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

Commit 423e8de3 authored by Rakesh Pillai's avatar Rakesh Pillai Committed by snandini
Browse files

qcacld-3.0: Validate adapter before netdev features update

Currently a high priority workqueue is scheduled for
enabling the network queue and updating the netdev features
after a successful connection. The adapter validity is not
verified when the workqueue is scheduled, which can lead to
unexpected behaviour.

Validate the adapter in the workqueue before updating
any netdev features.

Change-Id: I29a4dc20993d14c00aef6a4fe502439ae4e14afe
CRs-Fixed: 2776009
parent 40adffa4
Loading
Loading
Loading
Loading
+7 −0
Original line number Diff line number Diff line
@@ -1643,7 +1643,14 @@ 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
+32 −10
Original line number Diff line number Diff line
@@ -9577,21 +9577,29 @@ void hdd_bus_bandwidth_deinit(struct hdd_context *hdd_ctx)
 *				       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)
{
	struct hdd_context *hdd_ctx = WLAN_HDD_GET_CTX(adapter);

	if (hdd_validate_adapter(adapter)) {
		hdd_adapter_ops_record_event(hdd_ctx, WLAN_HDD_ADAPTER_OPS_WORK_SCHED,
					     WLAN_INVALID_VDEV_ID);
		hdd_err("netdev features update request for invalid 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_adapter_ops_record_event(hdd_ctx, WLAN_HDD_ADAPTER_OPS_WORK_SCHED,
				     adapter->vdev_id);

	hdd_netdev_update_features(adapter);

@@ -9609,10 +9617,25 @@ __hdd_adapter_param_update_work(struct hdd_adapter *adapter)
 */
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;
@@ -9687,7 +9710,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