diff --git a/os_if/linux/scan/inc/wlan_cfg80211_scan.h b/os_if/linux/scan/inc/wlan_cfg80211_scan.h index a4004277f511..1634303d16de 100644 --- a/os_if/linux/scan/inc/wlan_cfg80211_scan.h +++ b/os_if/linux/scan/inc/wlan_cfg80211_scan.h @@ -138,7 +138,7 @@ struct scan_params { * @frame_len: frame length * @rssi: signal strength in mBm (100*dBm) * @boottime_ns: timestamp (CLOCK_BOOTTIME) when the information was received. - * @per_chain_snr: per chain snr received + * @per_chain_rssi: per chain rssi received */ struct wlan_cfg80211_inform_bss { struct ieee80211_channel *chan; @@ -146,7 +146,7 @@ struct wlan_cfg80211_inform_bss { size_t frame_len; int rssi; uint64_t boottime_ns; - uint8_t per_chain_snr[WLAN_MGMT_TXRX_HOST_MAX_ANTENNA]; + uint8_t per_chain_rssi[WLAN_MGMT_TXRX_HOST_MAX_ANTENNA]; }; diff --git a/os_if/linux/scan/src/wlan_cfg80211_scan.c b/os_if/linux/scan/src/wlan_cfg80211_scan.c index 86d8f18c229e..584a7f7528e3 100644 --- a/os_if/linux/scan/src/wlan_cfg80211_scan.c +++ b/os_if/linux/scan/src/wlan_cfg80211_scan.c @@ -1648,12 +1648,10 @@ static void wlan_fill_per_chain_rssi(struct cfg80211_inform_bss *data, return; } for (i = 0; i < WLAN_MGMT_TXRX_HOST_MAX_ANTENNA; i++) { - if (!bss->per_chain_snr[i] || - (bss->per_chain_snr[i] == WLAN_INVALID_PER_CHAIN_RSSI)) + if (!bss->per_chain_rssi[i] || + (bss->per_chain_rssi[i] == WLAN_INVALID_PER_CHAIN_RSSI)) continue; - /* Add noise margin to SNR to convert it to RSSI */ - data->chain_signal[i] = bss->per_chain_snr[i] + - WLAN_NOISE_FLOOR_DBM_DEFAULT; + data->chain_signal[i] = bss->per_chain_rssi[i]; data->chains |= BIT(i); } } @@ -1760,7 +1758,7 @@ void wlan_cfg80211_inform_bss_frame(struct wlan_objmgr_pdev *pdev, bss_data.boottime_ns = scan_params->boottime_ns; - qdf_mem_copy(bss_data.per_chain_snr, scan_params->per_chain_snr, + qdf_mem_copy(bss_data.per_chain_rssi, scan_params->per_chain_rssi, WLAN_MGMT_TXRX_HOST_MAX_ANTENNA); cfg80211_debug("BSSID: %pM Channel:%d RSSI:%d", bss_data.mgmt->bssid, diff --git a/target_if/cp_stats/src/target_if_mc_cp_stats.c b/target_if/cp_stats/src/target_if_mc_cp_stats.c index d3c229bd8f40..d3e620bff867 100644 --- a/target_if/cp_stats/src/target_if_mc_cp_stats.c +++ b/target_if/cp_stats/src/target_if_mc_cp_stats.c @@ -33,11 +33,7 @@ #include #include #include - -#define TGT_INVALID_SNR (0) -#define TGT_NOISE_FLOOR_DBM (-96) -#define TGT_MAX_SNR (TGT_NOISE_FLOOR_DBM * (-1)) -#define TGT_IS_VALID_SNR(x) ((x) >= 0 && (x) < TGT_MAX_SNR) +#include "../../../umac/cmn_services/utils/inc/wlan_utility.h" static void target_if_cp_stats_free_stats_event(struct stats_event *ev) { @@ -99,6 +95,7 @@ static QDF_STATUS target_if_cp_stats_extract_peer_stats( uint32_t i; QDF_STATUS status; wmi_host_peer_stats peer_stats; + bool db2dbm_enabled; ev->num_peer_stats = stats_param->num_peer_stats; if (!ev->num_peer_stats) @@ -111,6 +108,8 @@ static QDF_STATUS target_if_cp_stats_extract_peer_stats( return QDF_STATUS_E_NOMEM; } + db2dbm_enabled = wmi_service_enabled(wmi_hdl, + wmi_service_hw_db2dbm_support); for (i = 0; i < ev->num_peer_stats; i++) { status = wmi_extract_peer_stats(wmi_hdl, data, i, &peer_stats); if (QDF_IS_STATUS_ERROR(status)) { @@ -121,8 +120,11 @@ static QDF_STATUS target_if_cp_stats_extract_peer_stats( ev->peer_stats[i].peer_macaddr); ev->peer_stats[i].tx_rate = peer_stats.peer_tx_rate; ev->peer_stats[i].rx_rate = peer_stats.peer_rx_rate; - ev->peer_stats[i].peer_rssi = peer_stats.peer_rssi + - TGT_NOISE_FLOOR_DBM; + if (db2dbm_enabled) + ev->peer_stats[i].peer_rssi = peer_stats.peer_rssi; + else + ev->peer_stats[i].peer_rssi = peer_stats.peer_rssi + + TGT_NOISE_FLOOR_DBM; } return QDF_STATUS_SUCCESS; @@ -164,6 +166,7 @@ static QDF_STATUS target_if_cp_stats_extract_vdev_summary_stats( QDF_STATUS status; int32_t bcn_snr, dat_snr; wmi_host_vdev_stats vdev_stats; + bool db2dbm_enabled; ev->num_summary_stats = stats_param->num_vdev_stats; if (!ev->num_summary_stats) @@ -177,6 +180,8 @@ static QDF_STATUS target_if_cp_stats_extract_vdev_summary_stats( return QDF_STATUS_E_NOMEM; } + db2dbm_enabled = wmi_service_enabled(wmi_hdl, + wmi_service_hw_db2dbm_support); for (i = 0; i < ev->num_summary_stats; i++) { status = wmi_extract_vdev_stats(wmi_hdl, data, i, &vdev_stats); if (QDF_IS_STATUS_ERROR(status)) @@ -208,18 +213,11 @@ static QDF_STATUS target_if_cp_stats_extract_vdev_summary_stats( ev->vdev_summary_stats[i].stats.rts_fail_cnt = vdev_stats.rts_fail_cnt; /* Update SNR and RSSI in SummaryStats */ - if (TGT_IS_VALID_SNR(bcn_snr)) { - ev->vdev_summary_stats[i].stats.snr = bcn_snr; - ev->vdev_summary_stats[i].stats.rssi = - bcn_snr + TGT_NOISE_FLOOR_DBM; - } else if (TGT_IS_VALID_SNR(dat_snr)) { - ev->vdev_summary_stats[i].stats.snr = dat_snr; - ev->vdev_summary_stats[i].stats.rssi = - dat_snr + TGT_NOISE_FLOOR_DBM; - } else { - ev->vdev_summary_stats[i].stats.snr = TGT_INVALID_SNR; - ev->vdev_summary_stats[i].stats.rssi = 0; - } + wlan_util_stats_get_rssi(db2dbm_enabled, bcn_snr, dat_snr, + &ev->vdev_summary_stats[i].stats.rssi); + ev->vdev_summary_stats[i].stats.snr = + ev->vdev_summary_stats[i].stats.rssi - + TGT_NOISE_FLOOR_DBM; } return QDF_STATUS_SUCCESS; @@ -235,6 +233,7 @@ static QDF_STATUS target_if_cp_stats_extract_vdev_chain_rssi_stats( QDF_STATUS status; int32_t bcn_snr, dat_snr; struct wmi_host_per_chain_rssi_stats rssi_stats; + bool db2dbm_enabled; ev->num_chain_rssi_stats = stats_param->num_rssi_stats; if (!ev->num_chain_rssi_stats) @@ -246,7 +245,8 @@ static QDF_STATUS target_if_cp_stats_extract_vdev_chain_rssi_stats( cp_stats_err("malloc failed"); return QDF_STATUS_E_NOMEM; } - + db2dbm_enabled = wmi_service_enabled(wmi_hdl, + wmi_service_hw_db2dbm_support); for (i = 0; i < ev->num_chain_rssi_stats; i++) { status = wmi_extract_per_chain_rssi_stats(wmi_hdl, data, i, &rssi_stats); @@ -258,27 +258,15 @@ static QDF_STATUS target_if_cp_stats_extract_vdev_chain_rssi_stats( bcn_snr = rssi_stats.rssi_avg_beacon[j]; cp_stats_err("Chain %d SNR bcn: %d data: %d", j, bcn_snr, dat_snr); - if (TGT_IS_VALID_SNR(bcn_snr)) - ev->vdev_chain_rssi[i].chain_rssi[j] = bcn_snr; - else if (TGT_IS_VALID_SNR(dat_snr)) - ev->vdev_chain_rssi[i].chain_rssi[j] = dat_snr; - else - /* - * Firmware sends invalid snr till it sees - * Beacon/Data after connection since after - * vdev up fw resets the snr to invalid. In this - * duartion Host will return an invalid rssi - * value. - */ - ev->vdev_chain_rssi[i].chain_rssi[j] = - TGT_INVALID_SNR; /* * Get the absolute rssi value from the current rssi * value the snr value is hardcoded into 0 in the * qcacld-new/CORE stack */ - ev->vdev_chain_rssi[i].chain_rssi[j] += - TGT_NOISE_FLOOR_DBM; + wlan_util_stats_get_rssi(db2dbm_enabled, bcn_snr, + dat_snr, + &ev->vdev_chain_rssi[i]. + chain_rssi[j]); } } diff --git a/target_if/init_deinit/src/init_cmd_api.c b/target_if/init_deinit/src/init_cmd_api.c index b621415c5d30..a5c148e110d2 100644 --- a/target_if/init_deinit/src/init_cmd_api.c +++ b/target_if/init_deinit/src/init_cmd_api.c @@ -495,4 +495,7 @@ void init_deinit_prepare_send_init_cmd( /* Set Max scans allowed */ target_if_scan_set_max_active_scans(psoc, WLAN_MAX_ACTIVE_SCANS_ALLOWED); + + if (wmi_service_enabled(wmi_handle, wmi_service_hw_db2dbm_support)) + wlan_psoc_nif_fw_ext_cap_set(psoc, WLAN_SOC_CEXT_HW_DB2DBM); } diff --git a/umac/cmn_services/mgmt_txrx/dispatcher/inc/wlan_mgmt_txrx_utils_api.h b/umac/cmn_services/mgmt_txrx/dispatcher/inc/wlan_mgmt_txrx_utils_api.h index 5c4ad35eeefc..ede92737137c 100644 --- a/umac/cmn_services/mgmt_txrx/dispatcher/inc/wlan_mgmt_txrx_utils_api.h +++ b/umac/cmn_services/mgmt_txrx/dispatcher/inc/wlan_mgmt_txrx_utils_api.h @@ -652,7 +652,8 @@ enum mgmt_frame_type { }; #define WLAN_MGMT_TXRX_HOST_MAX_ANTENNA 4 -#define WLAN_INVALID_PER_CHAIN_RSSI 0x80 +#define WLAN_INVALID_PER_CHAIN_RSSI 0xFF +#define WLAN_INVALID_PER_CHAIN_SNR 0x80 #define WLAN_NOISE_FLOOR_DBM_DEFAULT -96 /** * struct mgmt_rx_event_params - host mgmt header params diff --git a/umac/cmn_services/obj_mgr/inc/wlan_objmgr_psoc_obj.h b/umac/cmn_services/obj_mgr/inc/wlan_objmgr_psoc_obj.h index 58271b1b795a..c4ee836b8bc5 100644 --- a/umac/cmn_services/obj_mgr/inc/wlan_objmgr_psoc_obj.h +++ b/umac/cmn_services/obj_mgr/inc/wlan_objmgr_psoc_obj.h @@ -125,6 +125,8 @@ #define WLAN_SOC_CEXT_TWT_REQUESTER 0x00002000 /* TWT Responder capable */ #define WLAN_SOC_CEXT_TWT_RESPONDER 0x00004000 + /* HW DB2DBM CAPABLE */ +#define WLAN_SOC_CEXT_HW_DB2DBM 0x00008000 /* feature_flags */ /* CONF: ATH FF enabled */ diff --git a/umac/cmn_services/utils/inc/wlan_utility.h b/umac/cmn_services/utils/inc/wlan_utility.h index f1b1e7587958..f936f26ef95b 100644 --- a/umac/cmn_services/utils/inc/wlan_utility.h +++ b/umac/cmn_services/utils/inc/wlan_utility.h @@ -28,6 +28,12 @@ #include #include +#define TGT_INVALID_SNR (0) +#define TGT_MAX_SNR (TGT_NOISE_FLOOR_DBM * (-1)) +#define TGT_NOISE_FLOOR_DBM (-96) +#define TGT_IS_VALID_SNR(x) ((x) >= 0 && (x) < TGT_MAX_SNR) +#define TGT_IS_VALID_RSSI(x) ((x) != 0xFF) + /** * struct wlan_find_vdev_filter - find vdev filter object. this can be extended * @ifname: interface name of vdev @@ -261,4 +267,22 @@ QDF_STATUS wlan_pdev_chan_change_pending_vdevs(struct wlan_objmgr_pdev *pdev, */ QDF_STATUS wlan_chan_eq(struct wlan_channel *chan1, struct wlan_channel *chan2); +/** + * wlan_util_stats_get_rssi() - API to get rssi in dbm + * @db2dbm_enabled: If db2dbm capability is enabled + * @bcn_snr: beacon snr + * @dat_snr: data snr + * @rssi: rssi + * + * This function gets the rssi based on db2dbm support. If this feature is + * present in hw then it means firmware directly sends rssi and no converstion + * is required. If this capablity is not present then host needs to convert + * snr to rssi + * + * Return: None + */ +void +wlan_util_stats_get_rssi(bool db2dbm_enabled, int32_t bcn_snr, int32_t dat_snr, + int8_t *rssi); + #endif /* _WLAN_UTILITY_H_ */ diff --git a/umac/cmn_services/utils/src/wlan_utility.c b/umac/cmn_services/utils/src/wlan_utility.c index 643f24bef4f2..24aff8cc767f 100644 --- a/umac/cmn_services/utils/src/wlan_utility.c +++ b/umac/cmn_services/utils/src/wlan_utility.c @@ -463,3 +463,29 @@ QDF_STATUS wlan_util_pdev_vdevs_deschan_match(struct wlan_objmgr_pdev *pdev, return QDF_STATUS_E_FAILURE; } #endif + +void +wlan_util_stats_get_rssi(bool db2dbm_enabled, int32_t bcn_snr, int32_t dat_snr, + int8_t *rssi) +{ + uint32_t snr; + + if (db2dbm_enabled) { + if (TGT_IS_VALID_RSSI(bcn_snr)) + *rssi = bcn_snr; + else if (TGT_IS_VALID_RSSI(dat_snr)) + *rssi = dat_snr; + else + *rssi = TGT_NOISE_FLOOR_DBM; + } else { + if (TGT_IS_VALID_SNR(bcn_snr)) + snr = bcn_snr; + else if (TGT_IS_VALID_SNR(dat_snr)) + snr = dat_snr; + else + snr = TGT_INVALID_SNR; + + /* Get the absolute rssi value from the current rssi value */ + *rssi = snr + TGT_NOISE_FLOOR_DBM; + } +} diff --git a/umac/cp_stats/dispatcher/inc/wlan_cp_stats_mc_defs.h b/umac/cp_stats/dispatcher/inc/wlan_cp_stats_mc_defs.h index 85353959dcd5..9556a4134de5 100644 --- a/umac/cp_stats/dispatcher/inc/wlan_cp_stats_mc_defs.h +++ b/umac/cp_stats/dispatcher/inc/wlan_cp_stats_mc_defs.h @@ -204,7 +204,7 @@ struct pdev_mc_cp_stats { */ struct summary_stats { uint32_t snr; - uint32_t rssi; + int8_t rssi; uint32_t retry_cnt[4]; uint32_t multiple_retry_cnt[4]; uint32_t tx_frm_cnt[4]; @@ -244,7 +244,7 @@ struct vdev_mc_cp_stats { struct peer_mc_cp_stats { uint32_t tx_rate; uint32_t rx_rate; - uint32_t peer_rssi; + int8_t peer_rssi; uint8_t peer_macaddr[WLAN_MACADDR_LEN]; }; diff --git a/umac/scan/dispatcher/inc/wlan_scan_public_structs.h b/umac/scan/dispatcher/inc/wlan_scan_public_structs.h index 1f5d2461487c..76742444a768 100644 --- a/umac/scan/dispatcher/inc/wlan_scan_public_structs.h +++ b/umac/scan/dispatcher/inc/wlan_scan_public_structs.h @@ -296,7 +296,7 @@ struct security_info { * @tsf_delta: TSF delta * @bss_score: bss score calculated on basis of RSSI/caps etc. * @neg_sec_info: negotiated security info - * @per_chain_snr: per chain SNR value received. + * @per_chain_rssi: per chain RSSI value received. * boottime_ns: boottime in ns. * @rrm_parent_tsf: RRM parent tsf * @mlme_info: Mlme info, this will be updated by MLME for the scan entry @@ -334,7 +334,7 @@ struct scan_cache_entry { uint32_t tsf_delta; uint32_t bss_score; struct security_info neg_sec_info; - uint8_t per_chain_snr[WLAN_MGMT_TXRX_HOST_MAX_ANTENNA]; + uint8_t per_chain_rssi[WLAN_MGMT_TXRX_HOST_MAX_ANTENNA]; uint64_t boottime_ns; uint32_t rrm_parent_tsf; struct element_info alt_wcn_ie; diff --git a/umac/scan/dispatcher/src/wlan_scan_utils_api.c b/umac/scan/dispatcher/src/wlan_scan_utils_api.c index d99dd1f1f428..b3b0152a06bd 100644 --- a/umac/scan/dispatcher/src/wlan_scan_utils_api.c +++ b/umac/scan/dispatcher/src/wlan_scan_utils_api.c @@ -985,6 +985,7 @@ util_scan_gen_scan_entry(struct wlan_objmgr_pdev *pdev, struct scan_cache_entry *scan_entry; struct qbss_load_ie *qbss_load; struct scan_cache_node *scan_node; + uint8_t i; scan_entry = qdf_mem_malloc_atomic(sizeof(*scan_entry)); if (!scan_entry) { @@ -1020,9 +1021,22 @@ util_scan_gen_scan_entry(struct wlan_objmgr_pdev *pdev, scan_entry->tsf_delta = rx_param->tsf_delta; /* Copy per chain rssi to scan entry */ - qdf_mem_copy(scan_entry->per_chain_snr, rx_param->rssi_ctl, + qdf_mem_copy(scan_entry->per_chain_rssi, rx_param->rssi_ctl, WLAN_MGMT_TXRX_HOST_MAX_ANTENNA); + if (!wlan_psoc_nif_fw_ext_cap_get(wlan_pdev_get_psoc(pdev), + WLAN_SOC_CEXT_HW_DB2DBM)) { + for (i = 0; i < WLAN_MGMT_TXRX_HOST_MAX_ANTENNA; i++) { + if (scan_entry->per_chain_rssi[i] != + WLAN_INVALID_PER_CHAIN_SNR) + scan_entry->per_chain_rssi[i] += + WLAN_NOISE_FLOOR_DBM_DEFAULT; + else + scan_entry->per_chain_rssi[i] = + WLAN_INVALID_PER_CHAIN_RSSI; + } + } + /* store jiffies */ scan_entry->rrm_parent_tsf = (uint32_t)qdf_system_ticks(); diff --git a/wmi/inc/wmi_unified_param.h b/wmi/inc/wmi_unified_param.h index e8da090a3b91..f29e3da75007 100644 --- a/wmi/inc/wmi_unified_param.h +++ b/wmi/inc/wmi_unified_param.h @@ -4569,7 +4569,7 @@ struct wmi_host_per_chain_rssi_stats { */ typedef struct { wmi_host_mac_addr peer_macaddr; - uint32_t peer_rssi; + int8_t peer_rssi; uint32_t peer_rssi_seq_num; uint32_t peer_tx_rate; uint32_t peer_rx_rate; @@ -5274,6 +5274,7 @@ typedef enum { wmi_service_nan_sap_support, wmi_service_ndi_sap_support, wmi_service_nan_disable_support, + wmi_service_hw_db2dbm_support, wmi_services_max, } wmi_conv_service_ids; #define WMI_SERVICE_UNAVAILABLE 0xFFFF diff --git a/wmi/src/wmi_unified_tlv.c b/wmi/src/wmi_unified_tlv.c index 8352c770aeba..024a730498d9 100644 --- a/wmi/src/wmi_unified_tlv.c +++ b/wmi/src/wmi_unified_tlv.c @@ -11974,6 +11974,8 @@ static void populate_tlv_service(uint32_t *wmi_service) wmi_service[wmi_service_ndi_sap_support] = WMI_SERVICE_NDI_SAP_SUPPORT; wmi_service[wmi_service_nan_disable_support] = WMI_SERVICE_NAN_DISABLE_SUPPORT; + wmi_service[wmi_service_hw_db2dbm_support] = + WMI_SERVICE_HW_DB2DBM_CONVERSION_SUPPORT; } #ifndef CONFIG_MCL