Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit dd8fef0f authored by Prakash Manjunathappa's avatar Prakash Manjunathappa Committed by Madan Koyyalamudi
Browse files

qcacld-3.0: init/deinit tx_rx_histogram along with hdd_bus_bandwidth

hdd_txrx_hist histogram is accessed in hdd_pld_request_bus_bandwidth.
init/deinit tx_rx_histogram along with init/deinit of hdd_bus_bandwidth
Without this in FTM mode where hdd_txrx_hist memeber is accessed without
allocating memory for it. This results in uninitialized NULL dereference
assert

Change-Id: I3b8d80b71f4c37da4a0dafc4a7b91f8ca16bbab3
CRs-Fixed: 3110416
parent cc6aa888
Loading
Loading
Loading
Loading
+45 −29
Original line number Diff line number Diff line
@@ -3713,6 +3713,7 @@ static int hdd_update_country_code(struct hdd_context *hdd_ctx)
	return hdd_reg_set_country(hdd_ctx, country_code);
}
#ifdef WLAN_FEATURE_DP_BUS_BANDWIDTH
/**
 * wlan_hdd_init_tx_rx_histogram() - init tx/rx histogram stats
 * @hdd_ctx: hdd context
@@ -3743,6 +3744,7 @@ static void wlan_hdd_deinit_tx_rx_histogram(struct hdd_context *hdd_ctx)
	qdf_mem_free(hdd_ctx->hdd_txrx_hist);
	hdd_ctx->hdd_txrx_hist = NULL;
}
#endif /*WLAN_FEATURE_DP_BUS_BANDWIDTH*/
#ifdef WLAN_NS_OFFLOAD
/**
@@ -4199,8 +4201,6 @@ int hdd_wlan_start_modules(struct hdd_context *hdd_ctx, bool reinit)
		hdd_skip_acs_scan_timer_init(hdd_ctx);
		wlan_hdd_init_tx_rx_histogram(hdd_ctx);
		hdd_set_hif_init_phase(hif_ctx, false);
		hdd_hif_set_enable_detection(hif_ctx, true);
@@ -10727,12 +10727,17 @@ int hdd_bus_bandwidth_init(struct hdd_context *hdd_ctx)
{
	QDF_STATUS status;
	if (QDF_GLOBAL_FTM_MODE == hdd_get_conparam())
		return QDF_STATUS_SUCCESS;
	hdd_enter();
	qdf_spinlock_create(&hdd_ctx->bus_bw_lock);
	hdd_pm_qos_add_request(hdd_ctx);
	wlan_hdd_init_tx_rx_histogram(hdd_ctx);
	status = qdf_periodic_work_create(&hdd_ctx->bus_bw_work,
					  hdd_bus_bw_work_handler,
					  hdd_ctx);
@@ -10744,6 +10749,9 @@ int hdd_bus_bandwidth_init(struct hdd_context *hdd_ctx)
void hdd_bus_bandwidth_deinit(struct hdd_context *hdd_ctx)
{
	if (QDF_GLOBAL_FTM_MODE == hdd_get_conparam())
		return;
	hdd_enter();
	/* it is expecting the timer has been stopped or not started
@@ -10752,6 +10760,7 @@ 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);
	wlan_hdd_deinit_tx_rx_histogram(hdd_ctx);
	qdf_spinlock_destroy(&hdd_ctx->bus_bw_lock);
	hdd_pm_qos_remove_request(hdd_ctx);
@@ -10877,7 +10886,7 @@ void hdd_adapter_feature_update_work_deinit(struct hdd_adapter *adapter)
	hdd_exit();
}
static uint8_t *convert_level_to_string(uint32_t level)
static uint8_t *hdd_tp_level_to_str(uint32_t level)
{
	switch (level) {
	/* initialize the wlan sub system */
@@ -11026,30 +11035,25 @@ void wlan_hdd_display_tx_rx_histogram(struct hdd_context *hdd_ctx)
	hdd_nofl_debug("Total entries: %d Current index: %d",
		       NUM_TX_RX_HISTOGRAM, hdd_ctx->hdd_txrx_hist_idx);
	if (hdd_ctx->hdd_txrx_hist) {
		hdd_nofl_debug("[index][timestamp]: interval_rx, interval_tx, bus_bw_level, RX TP Level, TX TP Level, Rx:Tx pm_qos");
		for (i = 0; i < NUM_TX_RX_HISTOGRAM; i++) {
			struct hdd_tx_rx_histogram *hist;
			/* using hdd_log to avoid printing function name */
		if (hdd_ctx->hdd_txrx_hist[i].qtime > 0)
			hdd_nofl_debug("[%3d][%15llu]: %6llu, %6llu, %s, %s, %s, %s:%s",
				       i, hdd_ctx->hdd_txrx_hist[i].qtime,
				       hdd_ctx->hdd_txrx_hist[i].interval_rx,
				       hdd_ctx->hdd_txrx_hist[i].interval_tx,
				       convert_level_to_string(
					hdd_ctx->hdd_txrx_hist[i].
						next_vote_level),
				       convert_level_to_string(
					hdd_ctx->hdd_txrx_hist[i].
						next_rx_level),
				       convert_level_to_string(
					hdd_ctx->hdd_txrx_hist[i].
						next_tx_level),
				hdd_ctx->hdd_txrx_hist[i].is_rx_pm_qos_high ?
				"HIGH" : "LOW",
				hdd_ctx->hdd_txrx_hist[i].is_tx_pm_qos_high ?
				"HIGH" : "LOW");
			if (hdd_ctx->hdd_txrx_hist[i].qtime <= 0)
				continue;
			hist = &hdd_ctx->hdd_txrx_hist[i];
			hdd_nofl_debug("[%3d][%15llu]: %6llu, %6llu, %s, %s, %s, %s:%s",
				       i, hist->qtime, hist->interval_rx,
				       hist->interval_tx,
				       pld_bus_width_type_to_str(hist->next_vote_level),
				       hdd_tp_level_to_str(hist->next_rx_level),
				       hdd_tp_level_to_str(hist->next_tx_level),
				       hist->is_rx_pm_qos_high ? "HIGH" : "LOW",
				       hist->is_tx_pm_qos_high ? "HIGH" : "LOW");
		}
	}
}
@@ -11062,8 +11066,10 @@ void wlan_hdd_display_tx_rx_histogram(struct hdd_context *hdd_ctx)
void wlan_hdd_clear_tx_rx_histogram(struct hdd_context *hdd_ctx)
{
	hdd_ctx->hdd_txrx_hist_idx = 0;
	if (hdd_ctx->hdd_txrx_hist)
		qdf_mem_zero(hdd_ctx->hdd_txrx_hist,
		(sizeof(struct hdd_tx_rx_histogram) * NUM_TX_RX_HISTOGRAM));
			     (sizeof(struct hdd_tx_rx_histogram) *
			     NUM_TX_RX_HISTOGRAM));
}
/* length of the netif queue log needed per adapter */
@@ -14681,8 +14687,6 @@ int hdd_wlan_stop_modules(struct hdd_context *hdd_ctx, bool ftm_mode)
		if (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);
@@ -16140,6 +16144,9 @@ bool hdd_is_any_adapter_connected(struct hdd_context *hdd_ctx)
#ifdef WLAN_FEATURE_DP_BUS_BANDWIDTH
static void __hdd_bus_bw_compute_timer_start(struct hdd_context *hdd_ctx)
{
	if (hdd_get_conparam() == QDF_GLOBAL_FTM_MODE)
		return;
	qdf_periodic_work_start(&hdd_ctx->bus_bw_work,
				hdd_ctx->config->bus_bw_compute_interval);
	hdd_ctx->bw_vote_time = qdf_get_log_timestamp();
@@ -16168,6 +16175,9 @@ static void __hdd_bus_bw_compute_timer_stop(struct hdd_context *hdd_ctx)
{
	bool is_any_adapter_conn = hdd_is_any_adapter_connected(hdd_ctx);
	if (hdd_get_conparam() == QDF_GLOBAL_FTM_MODE)
		return;
	if (!qdf_periodic_work_stop_sync(&hdd_ctx->bus_bw_work))
		goto exit;
@@ -16220,6 +16230,9 @@ void hdd_bus_bw_compute_prev_txrx_stats(struct hdd_adapter *adapter)
{
	struct hdd_context *hdd_ctx = WLAN_HDD_GET_CTX(adapter);
	if (hdd_get_conparam() == QDF_GLOBAL_FTM_MODE)
		return;
	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;
@@ -16235,6 +16248,9 @@ void hdd_bus_bw_compute_reset_prev_txrx_stats(struct hdd_adapter *adapter)
{
	struct hdd_context *hdd_ctx = WLAN_HDD_GET_CTX(adapter);
	if (hdd_get_conparam() == QDF_GLOBAL_FTM_MODE)
		return;
	qdf_spin_lock_bh(&hdd_ctx->bus_bw_lock);
	adapter->prev_tx_packets = 0;
	adapter->prev_rx_packets = 0;
+13 −0
Original line number Diff line number Diff line
@@ -78,6 +78,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_ULTRA_HIGH: vote for ultra high bus bandwidth
 * @PLD_BUS_WIDTH_LOW_LATENCY: vote for low latency bus bandwidth
 */
enum pld_bus_width_type {
@@ -87,9 +88,12 @@ enum pld_bus_width_type {
	PLD_BUS_WIDTH_MEDIUM,
	PLD_BUS_WIDTH_HIGH,
	PLD_BUS_WIDTH_VERY_HIGH,
	PLD_BUS_WIDTH_ULTRA_HIGH,
	PLD_BUS_WIDTH_MAX,
	PLD_BUS_WIDTH_LOW_LATENCY,
};


#define PLD_MAX_FILE_NAME NAME_MAX

/**
@@ -942,6 +946,15 @@ int pld_thermal_register(struct device *dev, unsigned long state, int mon_id);
 */
void pld_thermal_unregister(struct device *dev, int mon_id);

/**
 * pld_bus_width_type_to_str() - Helper function to convert PLD bandwidth level
 *				 to string
 * @level: PLD bus width level
 *
 * Return: String corresponding to input "level"
 */
const char *pld_bus_width_type_to_str(enum pld_bus_width_type level);

/**
 * pld_get_thermal_state() - Get the current thermal state from the PLD
 * @dev: The device structure
+26 −0
Original line number Diff line number Diff line
@@ -3154,6 +3154,32 @@ void pld_thermal_unregister(struct device *dev, int mon_id)
	}
}

const char *pld_bus_width_type_to_str(enum pld_bus_width_type level)
{
	switch (level) {
	/* initialize the wlan sub system */
	case PLD_BUS_WIDTH_NONE:
		return "NONE";
	case PLD_BUS_WIDTH_IDLE:
		return "IDLE";
	case PLD_BUS_WIDTH_LOW:
		return "LOW";
	case PLD_BUS_WIDTH_MEDIUM:
		return "MEDIUM";
	case PLD_BUS_WIDTH_HIGH:
		return "HIGH";
	case PLD_BUS_WIDTH_VERY_HIGH:
		return "VERY_HIGH";
	case PLD_BUS_WIDTH_LOW_LATENCY:
		return "LOW_LAT";
	default:
		if (level > PLD_BUS_WIDTH_ULTRA_HIGH)
			return "ULTRA_HIGH+";
		else
			return "INVAL";
	}
}

int pld_get_thermal_state(struct device *dev, unsigned long *thermal_state,
			  int mon_id)
{