diff --git a/dp/inc/cdp_txrx_mon.h b/dp/inc/cdp_txrx_mon.h index 1e0dbaa7d7..1bb7d3ed55 100644 --- a/dp/inc/cdp_txrx_mon.h +++ b/dp/inc/cdp_txrx_mon.h @@ -218,4 +218,31 @@ cdp_is_lite_mon_enabled(ol_txrx_soc_handle soc, return soc->ops->mon_ops->txrx_is_lite_mon_enabled(soc, pdev_id, dir); } #endif + +#ifdef QCA_RSSI_DB2DBM +/* + * cdp_set_params_rssi_dbm_conversion - Set the rssi dbm conversion params + * into dp_pdev structure + * @soc: soc txrx handler + * @params: cdp_rssi_db2dbm_param_dp pointer + * + */ +static inline QDF_STATUS +cdp_set_params_rssi_dbm_conversion(ol_txrx_soc_handle soc, + struct cdp_rssi_db2dbm_param_dp *params) +{ + if (!soc || !soc->ops) { + dp_cdp_debug("Invalid Instance:"); + QDF_BUG(0); + return QDF_STATUS_E_FAILURE; + } + + if (!soc->ops->mon_ops || + !soc->ops->mon_ops->txrx_set_mon_pdev_params_rssi_dbm_conv) + return QDF_STATUS_E_FAILURE; + + return soc->ops->mon_ops->txrx_set_mon_pdev_params_rssi_dbm_conv + (soc, params); +} +#endif #endif diff --git a/dp/inc/cdp_txrx_mon_struct.h b/dp/inc/cdp_txrx_mon_struct.h index 14a504a93c..a2ae40c9f2 100644 --- a/dp/inc/cdp_txrx_mon_struct.h +++ b/dp/inc/cdp_txrx_mon_struct.h @@ -106,6 +106,10 @@ enum cdp_lite_mon_direction { CDP_LITE_MON_DIRECTION_TX = 2, }; #endif +/* Same as MAX_20MHZ_SEGMENTS */ +#define CDP_MAX_20MHZ_SEGS 16 +/* Same as MAX_ANTENNA_EIGHT */ +#define CDP_MAX_NUM_ANTENNA 8 /* XXX not really a mode; there are really multiple PHY's */ enum cdp_mon_phymode { @@ -505,4 +509,62 @@ struct cdp_lite_mon_peer_info { uint8_t mac[CDP_LITE_MON_PEER_MAX][QDF_MAC_ADDR_SIZE]; }; #endif +/* channel operating width */ +enum cdp_channel_width { + CHAN_WIDTH_20 = 0, + CHAN_WIDTH_40, + CHAN_WIDTH_80, + CHAN_WIDTH_160, + CHAN_WIDTH_80P80, + CHAN_WIDTH_5, + CHAN_WIDTH_10, + CHAN_WIDTH_165, + CHAN_WIDTH_160P160, + CHAN_WIDTH_320, + + CHAN_WIDTH_MAX, +}; + +/* struct cdp_rssi_temp_off_param_dp + * @rssi_temp_offset: Temperature based rssi offset , send every 30 secs + */ + +struct cdp_rssi_temp_off_param_dp { + int32_t rssi_temp_offset; +}; + +/* + * struct cdp_rssi_dbm_conv_param_dp + * @curr_bw: Current bandwidth + * @curr_rx_chainmask: Current rx chainmask + * @xbar_config: 4 bytes, used for BB to RF Chain mapping + * @xlna_bypass_offset: Low noise amplifier bypass offset + * @xlna_bypass_threshold: Low noise amplifier bypass threshold + * @nfHwDbm: HW noise floor in dBm per chain, per 20MHz subband + */ +struct cdp_rssi_dbm_conv_param_dp { + uint32_t curr_bw; + uint32_t curr_rx_chainmask; + uint32_t xbar_config; + int32_t xlna_bypass_offset; + int32_t xlna_bypass_threshold; + int8_t nf_hw_dbm[CDP_MAX_NUM_ANTENNA][CDP_MAX_20MHZ_SEGS]; +}; + +/* + * struct cdp_rssi_db2dbm_param_dp + * @pdev_id: pdev_id + * @rssi_temp_off_present: to check temp offset values present or not + * @rssi_dbm_info_present: to check rssi dbm converstion parameters + * present or not + * @temp_off_param: cdp_rssi_temp_off_param_dp structure value + * @rssi_dbm_param: cdp_rssi_dbm_conv_param_dp staructure value + */ +struct cdp_rssi_db2dbm_param_dp { + uint32_t pdev_id; + bool rssi_temp_off_present; + bool rssi_dbm_info_present; + struct cdp_rssi_temp_off_param_dp temp_off_param; + struct cdp_rssi_dbm_conv_param_dp rssi_dbm_param; +}; #endif diff --git a/dp/inc/cdp_txrx_ops.h b/dp/inc/cdp_txrx_ops.h index 227b2d058c..dd8f272353 100644 --- a/dp/inc/cdp_txrx_ops.h +++ b/dp/inc/cdp_txrx_ops.h @@ -966,6 +966,10 @@ struct cdp_mon_ops { uint8_t pdev_id, uint8_t direction); #endif + /*To set RSSI dbm converstion params in monitor pdev */ + QDF_STATUS (*txrx_set_mon_pdev_params_rssi_dbm_conv) + (struct cdp_soc_t *soc, + struct cdp_rssi_db2dbm_param_dp *params); }; struct cdp_host_stats_ops { diff --git a/dp/wifi3.0/monitor/2.0/dp_mon_2.0.c b/dp/wifi3.0/monitor/2.0/dp_mon_2.0.c index eb64c30305..0a83eccf87 100644 --- a/dp/wifi3.0/monitor/2.0/dp_mon_2.0.c +++ b/dp/wifi3.0/monitor/2.0/dp_mon_2.0.c @@ -33,6 +33,15 @@ #include "dp_lite_mon.h" #endif +/* 40MHZ BW 2 20MHZ sub bands */ +#define SUB40BW 2 +/* 80MHZ BW 4 20MHZ sub bands */ +#define SUB80BW 4 +/* 160MHZ BW 8 20MHZ sub bands */ +#define SUB160BW 8 +/* 320MHZ BW 16 20MHZ sub bands */ +#define SUB320BW 16 + #if !defined(DISABLE_MON_CONFIG) /** @@ -1155,6 +1164,140 @@ QDF_STATUS dp_vdev_set_monitor_mode_rings_2_0(struct dp_pdev *pdev, } #endif +#ifdef QCA_RSSI_DB2DBM +/* + * dp_mon_compute_min_nf() - calculate the min nf value in the + * active chains 20MHZ subbands. + * computation: Need to calculate nfInDbm[][] to A_MIN(nfHwDbm[][]) + * considering row index as active chains and column + * index as 20MHZ subbands per chain. + * example: chain_mask = 0x07 (consider 3 active chains 0,1,2 index) + * BandWidth = 40MHZ (40MHZ includes two 20MHZ subbands so need to + * consider 0,1 index calculate min_nf value) + * + *@conv_params: cdp_rssi_dbm_conv_param_dp structure value + *@chain_idx: active chain index in nfHwdbm array + * + * Return: QDF_STATUS_SUCCESS if value set successfully + * QDF_STATUS_E_INVAL false if error + */ +static QDF_STATUS +dp_mon_compute_min_nf(struct cdp_rssi_dbm_conv_param_dp *conv_params, + int8_t *min_nf, int chain_idx) +{ + int j; + *min_nf = conv_params->nf_hw_dbm[chain_idx][0]; + + switch (conv_params->curr_bw) { + case CHAN_WIDTH_20: + case CHAN_WIDTH_5: + case CHAN_WIDTH_10: + break; + case CHAN_WIDTH_40: + for (j = 1; j < SUB40BW; j++) { + if (conv_params->nf_hw_dbm[chain_idx][j] < *min_nf) + *min_nf = conv_params->nf_hw_dbm[chain_idx][j]; + } + break; + case CHAN_WIDTH_80: + for (j = 1; j < SUB80BW; j++) { + if (conv_params->nf_hw_dbm[chain_idx][j] < *min_nf) + *min_nf = conv_params->nf_hw_dbm[chain_idx][j]; + } + break; + case CHAN_WIDTH_160: + case CHAN_WIDTH_80P80: + case CHAN_WIDTH_165: + for (j = 1; j < SUB160BW; j++) { + if (conv_params->nf_hw_dbm[chain_idx][j] < *min_nf) + *min_nf = conv_params->nf_hw_dbm[chain_idx][j]; + } + break; + case CHAN_WIDTH_160P160: + case CHAN_WIDTH_320: + for (j = 1; j < SUB320BW; j++) { + if (conv_params->nf_hw_dbm[chain_idx][j] < *min_nf) + *min_nf = conv_params->nf_hw_dbm[chain_idx][j]; + } + break; + default: + dp_cdp_err("Invalid bandwidth %u", conv_params->curr_bw); + return QDF_STATUS_E_INVAL; + } + return QDF_STATUS_SUCCESS; +} + +/* + * dp_mon_pdev_params_rssi_dbm_conv() --> to set rssi in dbm converstion + * params into monitor pdev. + *@cdp_soc: dp soc handle. + *@params: cdp_rssi_db2dbm_param_dp structure value. + * + * Return: QDF_STATUS_SUCCESS if value set successfully + * QDF_STATUS_E_INVAL false if error + */ +static QDF_STATUS +dp_mon_pdev_params_rssi_dbm_conv(struct cdp_soc_t *cdp_soc, + struct cdp_rssi_db2dbm_param_dp *params) +{ + struct cdp_rssi_db2dbm_param_dp *dp_rssi_params = params; + uint8_t pdev_id = params->pdev_id; + struct dp_soc *soc = (struct dp_soc *)cdp_soc; + struct dp_pdev *pdev = + dp_get_pdev_from_soc_pdev_id_wifi3(soc, pdev_id); + struct dp_mon_pdev *mon_pdev; + struct dp_mon_pdev_be *mon_pdev_be; + struct cdp_rssi_temp_off_param_dp temp_off_param; + struct cdp_rssi_dbm_conv_param_dp conv_params; + int8_t min_nf = 0; + int i; + + if (!soc->features.rssi_dbm_conv_support) { + dp_cdp_err("rssi dbm converstion support is false"); + return QDF_STATUS_E_INVAL; + } + if (!pdev || !pdev->monitor_pdev) { + dp_cdp_err("Invalid pdev_id %u", pdev_id); + return QDF_STATUS_E_FAILURE; + } + + mon_pdev = pdev->monitor_pdev; + mon_pdev_be = dp_get_be_mon_pdev_from_dp_mon_pdev(mon_pdev); + + if (dp_rssi_params->rssi_temp_off_present) { + temp_off_param = dp_rssi_params->temp_off_param; + mon_pdev_be->rssi_temp_offset = temp_off_param.rssi_temp_offset; + } + if (dp_rssi_params->rssi_dbm_info_present) { + conv_params = dp_rssi_params->rssi_dbm_param; + for (i = 0; i < CDP_MAX_NUM_ANTENNA; i++) { + if (conv_params.curr_rx_chainmask & (0x01 << i)) { + if (QDF_STATUS_E_INVAL == dp_mon_compute_min_nf + (&conv_params, &min_nf, i)) + return QDF_STATUS_E_INVAL; + } else { + continue; + } + } + mon_pdev_be->xlna_bypass_offset = + conv_params.xlna_bypass_offset; + mon_pdev_be->xlna_bypass_threshold = + conv_params.xlna_bypass_threshold; + mon_pdev_be->xbar_config = conv_params.xbar_config; + + mon_pdev_be->min_nf_dbm = min_nf; + } + return QDF_STATUS_SUCCESS; +} +#else +static inline QDF_STATUS +dp_mon_pdev_params_rssi_dbm_conv(struct cdp_soc_t *cdp_soc, + struct cdp_rssi_db2dbm_param_dp *params) +{ + return 0; +} +#endif + static void dp_mon_register_intr_ops_2_0(struct dp_soc *soc) { struct dp_mon_soc *mon_soc = soc->monitor_soc; @@ -1415,6 +1558,8 @@ struct cdp_mon_ops dp_ops_mon_2_0 = { .txrx_get_lite_mon_peer_config = dp_lite_mon_get_peer_config, .txrx_is_lite_mon_enabled = dp_lite_mon_is_enabled, #endif + .txrx_set_mon_pdev_params_rssi_dbm_conv = + dp_mon_pdev_params_rssi_dbm_conv, }; #ifdef QCA_MONITOR_OPS_PER_SOC_SUPPORT diff --git a/dp/wifi3.0/monitor/2.0/dp_mon_2.0.h b/dp/wifi3.0/monitor/2.0/dp_mon_2.0.h index eb18b9b3f6..43f697ceb9 100644 --- a/dp/wifi3.0/monitor/2.0/dp_mon_2.0.h +++ b/dp/wifi3.0/monitor/2.0/dp_mon_2.0.h @@ -116,6 +116,11 @@ struct dp_mon_desc_pool { * @rx_mon_queue_depth: RxMON queue depth * @desc_count: reaped status desc count * @status: reaped status buffer per ppdu + * @rssi_temp_offset: Temperature based rssi offset + * @xlna_bypass_offset: Low noise amplifier bypass offset + * @xlna_bypass_threshold: Low noise amplifier bypass threshold + * @xbar_config: 3 Bytes of xbar_config are used for RF to BB mapping + * @min_nf_dbm: min noise floor in active chains per channel */ struct dp_mon_pdev_be { struct dp_mon_pdev mon_pdev; @@ -138,6 +143,13 @@ struct dp_mon_pdev_be { #endif void *prev_rxmon_desc; uint32_t prev_rxmon_cookie; +#ifdef QCA_RSSI_DB2DBM + int32_t rssi_temp_offset; + int32_t xlna_bypass_offset; + int32_t xlna_bypass_threshold; + uint32_t xbar_config; + int8_t min_nf_dbm; +#endif }; /**