Browse Source

qcacld-3.0: Add vdev pause bitmap (Set/Clear/Update/Get) API's

Currently, Host modify the vdev pause bitmap
directly which may be problematic in scenario
where this value update information need to
notify to other components.

Hence as a part of this fix, Add (set/clear/update) API's
for vdev pause bitmap modification.

Change-Id: I5c8d6576d27076f697463b42632962327306902f
CRs-Fixed: 2013376
Mukul Sharma 8 years ago
parent
commit
6411bb8535
5 changed files with 149 additions and 22 deletions
  1. 117 0
      core/wma/inc/wma.h
  2. 11 11
      core/wma/src/wma_data.c
  3. 8 9
      core/wma/src/wma_dev_if.c
  4. 12 0
      core/wma/src/wma_main.c
  5. 1 2
      core/wma/src/wma_mgmt.c

+ 117 - 0
core/wma/inc/wma.h

@@ -2377,4 +2377,121 @@ void wma_vdev_set_mlme_state(tp_wma_handle wma, uint8_t vdev_id,
 		wlan_objmgr_vdev_release_ref(vdev, WLAN_LEGACY_WMA_ID);
 	}
 }
+
+/**
+ * wma_update_vdev_pause_bitmap() - update vdev pause bitmap
+ * @vdev_id: the Id of the vdev to configure
+ * @value: value pause bitmap value
+ *
+ * Return: None
+ */
+static inline
+void wma_vdev_update_pause_bitmap(uint8_t vdev_id, uint16_t value)
+{
+	tp_wma_handle wma = (tp_wma_handle)cds_get_context(QDF_MODULE_ID_WMA);
+	struct wma_txrx_node *iface;
+
+	if (vdev_id > wma->max_bssid) {
+		WMA_LOGE("%s: Invalid vdev_id: %d", __func__, vdev_id);
+		return;
+	}
+
+	if (!wma) {
+		WMA_LOGE("%s: WMA context is invald!", __func__);
+		return;
+	}
+
+	iface = &wma->interfaces[vdev_id];
+	if (!iface || !iface->handle) {
+		WMA_LOGE("%s: Failed to get iface handle: %p",
+			 __func__, iface->handle);
+		return;
+	}
+
+	iface->pause_bitmap = value;
+}
+
+/**
+ * wma_vdev_get_pause_bitmap() - Get vdev pause bitmap
+ * @vdev_id: the Id of the vdev to configure
+ *
+ * Return: Vdev pause bitmap value else 0 on error
+ */
+static inline
+uint16_t wma_vdev_get_pause_bitmap(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 0;
+	}
+
+	iface = &wma->interfaces[vdev_id];
+	if (!iface || !iface->handle) {
+		WMA_LOGE("%s: Failed to get iface handle: %p",
+			 __func__, iface->handle);
+		return 0;
+	}
+
+	return iface->pause_bitmap;
+}
+
+/**
+ * wma_vdev_set_pause_bit() - Set a bit in vdev pause bitmap
+ * @vdev_id: the Id of the vdev to configure
+ * @bit_pos: set bit position in pause bitmap
+ *
+ * Return: None
+ */
+static inline
+void wma_vdev_set_pause_bit(uint8_t vdev_id, wmi_tx_pause_type bit_pos)
+{
+	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;
+	}
+
+	iface = &wma->interfaces[vdev_id];
+	if (!iface || !iface->handle) {
+		WMA_LOGE("%s: Failed to get iface handle: %p",
+			 __func__, iface->handle);
+		return;
+	}
+
+	iface->pause_bitmap |= (1 << bit_pos);
+}
+
+/**
+ * wma_vdev_clear_pause_bit() - Clear a bit from vdev pause bitmap
+ * @vdev_id: the Id of the vdev to configure
+ * @bit_pos: set bit position in pause bitmap
+ *
+ * Return: None
+ */
+static inline
+void wma_vdev_clear_pause_bit(uint8_t vdev_id, wmi_tx_pause_type bit_pos)
+{
+	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;
+	}
+
+	iface = &wma->interfaces[vdev_id];
+	if (!iface || !iface->handle) {
+		WMA_LOGE("%s: Failed to get iface handle: %p",
+			 __func__, iface->handle);
+		return;
+	}
+
+	iface->pause_bitmap &= ~(1 << bit_pos);
+}
+
 #endif

+ 11 - 11
core/wma/src/wma_data.c

@@ -1222,7 +1222,7 @@ void wma_set_linkstate(tp_wma_handle wma, tpLinkStateParams params)
 		cdp_fc_vdev_pause(soc,
 			wma->interfaces[vdev_id].handle,
 			OL_TXQ_PAUSE_REASON_VDEV_STOP);
-		wma->interfaces[vdev_id].pause_bitmap |= (1 << PAUSE_TYPE_HOST);
+		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__);
@@ -1259,11 +1259,11 @@ void wma_unpause_vdev(tp_wma_handle wma)
 
 #if defined(QCA_LL_LEGACY_TX_FLOW_CONTROL) || defined(QCA_LL_TX_FLOW_CONTROL_V2)
 		/* When host resume, by default, unpause all active vdev */
-		if (wma->interfaces[vdev_id].pause_bitmap) {
+		if (wma_vdev_get_pause_bitmap(vdev_id)) {
 			cdp_fc_vdev_unpause(cds_get_context(QDF_MODULE_ID_SOC),
 			     wma->interfaces[vdev_id].handle,
 			     0xffffffff);
-			wma->interfaces[vdev_id].pause_bitmap = 0;
+			wma_vdev_update_pause_bitmap(vdev_id, 0);
 		}
 #endif /* QCA_LL_LEGACY_TX_FLOW_CONTROL */
 
@@ -1650,20 +1650,20 @@ int wma_mcc_vdev_tx_pause_evt_handler(void *handle, uint8_t *event,
 				 * Now only support per-dev pause so it is not
 				 * necessary to pause a paused queue again.
 				 */
-				if (!wma->interfaces[vdev_id].pause_bitmap)
+				if (!wma_vdev_get_pause_bitmap(vdev_id))
 					cdp_fc_vdev_pause(soc,
 						wma->
 						interfaces[vdev_id].handle,
 						OL_TXQ_PAUSE_REASON_FW);
-				wma->interfaces[vdev_id].pause_bitmap |=
-					(1 << wmi_event->pause_type);
+				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->interfaces[vdev_id].pause_bitmap) {
-					wma->interfaces[vdev_id].pause_bitmap &=
-						~(1 << wmi_event->pause_type);
+				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) {
@@ -1682,7 +1682,7 @@ int wma_mcc_vdev_tx_pause_evt_handler(void *handle, uint8_t *event,
 
 			WMA_LOGD
 				("vdev_id %d, pause_map 0x%x, pause type %d, action %d",
-				vdev_id, wma->interfaces[vdev_id].pause_bitmap,
+				vdev_id, wma_vdev_get_pause_bitmap(vdev_id),
 				wmi_event->pause_type, wmi_event->action);
 		}
 		/* Test Next VDEV */
@@ -2998,7 +2998,7 @@ void wma_tx_abort(uint8_t vdev_id)
 		return;
 	}
 	WMA_LOGI("%s: vdevid %d bssid %pM", __func__, vdev_id, iface->bssid);
-	iface->pause_bitmap |= (1 << PAUSE_TYPE_HOST);
+	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);

+ 8 - 9
core/wma/src/wma_dev_if.c

@@ -911,7 +911,7 @@ int wma_vdev_start_resp_handler(void *handle, uint8_t *cmd_param_info,
 		cdp_fc_vdev_unpause(cds_get_context(QDF_MODULE_ID_SOC),
 				iface->handle,
 				OL_TXQ_PAUSE_REASON_VDEV_STOP);
-		iface->pause_bitmap &= ~(1 << PAUSE_TYPE_HOST);
+		wma_vdev_clear_pause_bit(resp_event->vdev_id, PAUSE_TYPE_HOST);
 	}
 
 	req_msg = wma_find_vdev_req(wma, resp_event->vdev_id,
@@ -1527,7 +1527,7 @@ int wma_vdev_stop_resp_handler(void *handle, uint8_t *cmd_param_info,
 			 __func__, resp_event->vdev_id);
 		cdp_fc_vdev_unpause(soc, iface->handle,
 				     OL_TXQ_PAUSE_REASON_VDEV_STOP);
-		iface->pause_bitmap &= ~(1 << PAUSE_TYPE_HOST);
+		wma_vdev_clear_pause_bit(resp_event->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);
@@ -1640,7 +1640,7 @@ struct cdp_vdev *wma_vdev_attach(tp_wma_handle wma_handle,
 					self_sta_req->self_mac_addr,
 					self_sta_req->session_id,
 					txrx_vdev_type);
-	wma_handle->interfaces[self_sta_req->session_id].pause_bitmap = 0;
+	wma_vdev_update_pause_bitmap(self_sta_req->session_id, 0);
 
 	WMA_LOGD("vdev_id %hu, txrx_vdev_handle = %p", self_sta_req->session_id,
 		 txrx_vdev_handle);
@@ -2112,7 +2112,7 @@ QDF_STATUS wma_vdev_start(tp_wma_handle wma,
 		cdp_fc_vdev_unpause(cds_get_context(QDF_MODULE_ID_SOC),
 			wma->interfaces[params.vdev_id].handle,
 			0xffffffff);
-		wma->interfaces[params.vdev_id].pause_bitmap = 0;
+		wma_vdev_update_pause_bitmap(params.vdev_id, 0);
 	}
 
 	return wma_send_vdev_start_to_fw(wma, &params);
@@ -2607,7 +2607,7 @@ void wma_vdev_resp_timer(void *data)
 			 __func__, tgt_req->vdev_id);
 		cdp_fc_vdev_unpause(soc, iface->handle,
 				     OL_TXQ_PAUSE_REASON_VDEV_STOP);
-		iface->pause_bitmap &= ~(1 << PAUSE_TYPE_HOST);
+		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);
@@ -4452,14 +4452,14 @@ void wma_delete_bss_ho_fail(tp_wma_handle wma, tpDeleteBssParams params)
 		 __func__, params->smesessionId);
 	cdp_fc_vdev_pause(soc, iface->handle,
 			   OL_TXQ_PAUSE_REASON_VDEV_STOP);
-	iface->pause_bitmap |= (1 << PAUSE_TYPE_HOST);
+	wma_vdev_set_pause_bit(params->smesessionId, PAUSE_TYPE_HOST);
 
 	cdp_fc_vdev_flush(soc, iface->handle);
 	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);
-	iface->pause_bitmap &= ~(1 << PAUSE_TYPE_HOST);
+	wma_vdev_clear_pause_bit(params->smesessionId, 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);
@@ -4602,11 +4602,10 @@ void wma_delete_bss(tp_wma_handle wma, tpDeleteBssParams params)
 
 	WMA_LOGD("%s, vdev_id: %d, pausing tx_ll_queue for VDEV_STOP (del_bss)",
 		 __func__, params->smesessionId);
-	iface->pause_bitmap |= (1 << PAUSE_TYPE_HOST);
+	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);
-	iface->pause_bitmap |= (1 << PAUSE_TYPE_HOST);
 
 	if (wma_send_vdev_stop_to_fw(wma, params->smesessionId)) {
 		WMA_LOGP("%s: %d Failed to send vdev stop", __func__, __LINE__);

+ 12 - 0
core/wma/src/wma_main.c

@@ -86,6 +86,7 @@
 #include "wlan_global_lmac_if_api.h"
 #include "target_if_pmo.h"
 #include "wma_he.h"
+#include "wlan_pmo_obj_mgmt_api.h"
 
 #include <cdp_txrx_handle.h>
 #define WMA_LOG_COMPLETION_TIMER 10000 /* 10 seconds */
@@ -2533,6 +2534,11 @@ QDF_STATUS wma_open(struct wlan_objmgr_psoc *psoc, void *cds_context,
 	wma_ndp_register_all_event_handlers(wma_handle);
 
 	wma_register_debug_callback();
+	/* 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);
 
 	return QDF_STATUS_SUCCESS;
 
@@ -3634,6 +3640,12 @@ QDF_STATUS wma_close(void *cds_ctx)
 	target_if_close();
 	wma_target_if_close(wma_handle);
 
+	pmo_unregister_pause_bitmap_notifier(wma_handle->psoc,
+		wma_vdev_update_pause_bitmap);
+	pmo_unregister_get_pause_bitmap(wma_handle->psoc,
+		wma_vdev_get_pause_bitmap);
+
+
 	WMA_LOGD("%s: Exit", __func__);
 	return QDF_STATUS_SUCCESS;
 }

+ 1 - 2
core/wma/src/wma_mgmt.c

@@ -2935,8 +2935,7 @@ void wma_hidden_ssid_vdev_restart(tp_wma_handle wma_handle,
 		wma_handle->
 		interfaces[pReq->sessionId].handle,
 		OL_TXQ_PAUSE_REASON_VDEV_STOP);
-	wma_handle->interfaces[pReq->sessionId].pause_bitmap |=
-							(1 << PAUSE_TYPE_HOST);
+	wma_vdev_set_pause_bit(pReq->sessionId, PAUSE_TYPE_HOST);
 	if (wma_send_vdev_stop_to_fw(wma_handle, pReq->sessionId)) {
 		WMA_LOGE("%s: %d Failed to send vdev stop", __func__, __LINE__);
 		qdf_atomic_set(&intr[pReq->sessionId].vdev_restart_params.