Browse Source

qcacmn: Add support of extended service bitmap handling

Extended service bitmap is used by FW to indicate supported services
bitmap for services excedding the current limitation of 128. Add support
to save and use this bitmap to check services supported in FW. Also,
change exisiting services bitmap to be dynamic allocated buffer to
optimize the buffer used to save the bitmap.

Change-Id: I24a0321bc1a06ee3aedf1c6acbc379e907bbd464
CRs-Fixed: 2103617
Kiran Venkatappa 7 years ago
parent
commit
482bc5ecbc

+ 17 - 0
wmi/inc/wmi_unified_api.h

@@ -1150,9 +1150,26 @@ QDF_STATUS wmi_unified_init_cmd_send(void *wmi_hdl,
 
 bool wmi_service_enabled(void *wmi_hdl, uint32_t service_id);
 
+/**
+ * wmi_save_service_bitmap() - save service bitmap
+ * @wmi_handle: wmi handle
+ * @param evt_buf: pointer to event buffer
+ *
+ * Return: QDF_STATUS_SUCCESS on success and QDF_STATUS failure code
+ */
 QDF_STATUS wmi_save_service_bitmap(void *wmi_hdl, void *evt_buf,
 				   void *bitmap_buf);
 
+/**
+ * wmi_save_ext_service_bitmap() - save extended service bitmap
+ * @wmi_handle: wmi handle
+ * @param evt_buf: pointer to event buffer
+ *
+ * Return: QDF_STATUS_SUCCESS on success and QDF_STATUS failure code
+ */
+QDF_STATUS wmi_save_ext_service_bitmap(void *wmi_hdl, void *evt_buf,
+				   void *bitmap_buf);
+
 QDF_STATUS wmi_save_fw_version(void *wmi_hdl, void *evt_buf);
 
 QDF_STATUS wmi_get_target_cap_from_service_ready(void *wmi_hdl,

+ 1 - 0
wmi/inc/wmi_unified_param.h

@@ -5157,6 +5157,7 @@ typedef enum {
 	wmi_ext_tbttoffset_update_event_id,
 	wmi_11d_new_country_event_id,
 	wmi_get_arp_stats_req_id,
+	wmi_service_available_event_id,
 
 	wmi_events_max,
 } wmi_conv_event_id;

+ 6 - 5
wmi/inc/wmi_unified_priv.h

@@ -955,7 +955,9 @@ QDF_STATUS (*send_lteu_config_cmd)(wmi_unified_t wmi_handle,
 
 QDF_STATUS (*send_set_ps_mode_cmd)(wmi_unified_t wmi_handle,
 		       struct set_ps_mode_params *param);
-void (*save_service_bitmap)(wmi_unified_t wmi_handle,
+QDF_STATUS (*save_service_bitmap)(wmi_unified_t wmi_handle,
+		void *evt_buf,  void *bitmap_buf);
+QDF_STATUS (*save_ext_service_bitmap)(wmi_unified_t wmi_handle,
 		void *evt_buf,  void *bitmap_buf);
 bool (*is_service_enabled)(wmi_unified_t wmi_handle,
 	uint32_t service_id);
@@ -1452,8 +1454,6 @@ struct wmi_unified {
 	bool wmi_stopinprogress;
 	uint32_t *wmi_events;
 #ifndef CONFIG_MCL
-	/* WMI service bitmap recieved from target */
-	uint32_t *wmi_service_bitmap;
 	uint32_t *pdev_param;
 	uint32_t *vdev_param;
 	uint32_t *services;
@@ -1478,9 +1478,10 @@ struct wmi_soc {
 	uint16_t max_msg_len[WMI_MAX_RADIOS];
 	struct wmi_ops *ops;
 	uint32_t wmi_events[wmi_events_max];
-#ifndef CONFIG_MCL
 	/* WMI service bitmap recieved from target */
-	uint32_t wmi_service_bitmap[wmi_services_max];
+	uint32_t *wmi_service_bitmap;
+	uint32_t *wmi_ext_service_bitmap;
+#ifndef CONFIG_MCL
 	uint32_t pdev_param[wmi_pdev_param_max];
 	uint32_t vdev_param[wmi_vdev_param_max];
 	uint32_t services[wmi_services_max];

+ 11 - 2
wmi/src/wmi_unified.c

@@ -2573,8 +2573,6 @@ void wmi_interface_logging_init(struct wmi_unified *wmi_handle)
 static inline void wmi_target_params_init(struct wmi_soc *soc,
 				struct wmi_unified *wmi_handle)
 {
-	/* WMI service bitmap recieved from target */
-	wmi_handle->wmi_service_bitmap = soc->wmi_service_bitmap;
 	wmi_handle->pdev_param = soc->pdev_param;
 	wmi_handle->vdev_param = soc->vdev_param;
 	wmi_handle->services   = soc->services;
@@ -2783,6 +2781,17 @@ void wmi_unified_detach(struct wmi_unified *wmi_handle)
 		}
 	}
 	qdf_spinlock_destroy(&soc->ctx_lock);
+
+	if (soc->wmi_service_bitmap) {
+		qdf_mem_free(soc->wmi_service_bitmap);
+		soc->wmi_service_bitmap = NULL;
+	}
+
+	if (soc->wmi_ext_service_bitmap) {
+		qdf_mem_free(soc->wmi_ext_service_bitmap);
+		soc->wmi_ext_service_bitmap = NULL;
+	}
+
 	/* Decrease the ref count once refcount infra is present */
 	soc->wmi_psoc = NULL;
 	qdf_mem_free(soc);

+ 20 - 2
wmi/src/wmi_unified_api.c

@@ -4447,9 +4447,27 @@ QDF_STATUS wmi_save_service_bitmap(void *wmi_hdl, void *evt_buf,
 	struct wmi_unified *wmi_handle = (struct wmi_unified *) wmi_hdl;
 
 	if (wmi_handle->ops->save_service_bitmap) {
-		wmi_handle->ops->save_service_bitmap(wmi_handle, evt_buf,
+		return wmi_handle->ops->save_service_bitmap(wmi_handle, evt_buf,
 						     bitmap_buf);
-		return 0;
+	}
+	return QDF_STATUS_E_FAILURE;
+}
+
+/**
+ * wmi_save_ext_service_bitmap() - save extended service bitmap
+ * @wmi_handle: wmi handle
+ * @param evt_buf: pointer to event buffer
+ *
+ * Return: QDF_STATUS_SUCCESS on success and QDF_STATUS_E_FAILURE for failure
+ */
+QDF_STATUS wmi_save_ext_service_bitmap(void *wmi_hdl, void *evt_buf,
+				   void *bitmap_buf)
+{
+	struct wmi_unified *wmi_handle = (struct wmi_unified *) wmi_hdl;
+
+	if (wmi_handle->ops->save_ext_service_bitmap) {
+		return wmi_handle->ops->save_ext_service_bitmap(wmi_handle,
+				evt_buf, bitmap_buf);
 	}
 	return QDF_STATUS_E_FAILURE;
 }

+ 26 - 4
wmi/src/wmi_unified_non_tlv.c

@@ -5458,21 +5458,36 @@ static QDF_STATUS send_ext_resource_config_non_tlv(wmi_unified_t wmi_handle,
  * @param evt_buf: pointer to event buffer
  * @param bitmap_buf: bitmap buffer for converged legacy support
  *
- * Return: None
+ * Return: QDF_STATUS
  */
-static void save_service_bitmap_non_tlv(wmi_unified_t wmi_handle,
+static QDF_STATUS save_service_bitmap_non_tlv(wmi_unified_t wmi_handle,
 				 void *evt_buf, void *bitmap_buf)
 {
 	wmi_service_ready_event *ev;
+	struct wmi_soc *soc = wmi_handle->soc;
 
 	ev = (wmi_service_ready_event *) evt_buf;
 
-	qdf_mem_copy(wmi_handle->wmi_service_bitmap, ev->wmi_service_bitmap,
+	/* If it is already allocated, use that buffer. This can happen
+	 * during target stop/start scenarios where host allocation is skipped.
+	 */
+	if (!soc->wmi_service_bitmap) {
+		soc->wmi_service_bitmap =
+			qdf_mem_malloc(WMI_SERVICE_BM_SIZE * sizeof(uint32_t));
+		if (!soc->wmi_service_bitmap) {
+			WMI_LOGE("Failed memory alloc for service bitmap\n");
+			return QDF_STATUS_E_NOMEM;
+		}
+	}
+
+	qdf_mem_copy(soc->wmi_service_bitmap, ev->wmi_service_bitmap,
 				(WMI_SERVICE_BM_SIZE * sizeof(uint32_t)));
 
 	if (bitmap_buf)
 		qdf_mem_copy(bitmap_buf, ev->wmi_service_bitmap,
 				(WMI_SERVICE_BM_SIZE * sizeof(uint32_t)));
+
+	return QDF_STATUS_SUCCESS;
 }
 
 /**
@@ -5485,7 +5500,14 @@ static void save_service_bitmap_non_tlv(wmi_unified_t wmi_handle,
 static bool is_service_enabled_non_tlv(wmi_unified_t wmi_handle,
 				uint32_t service_id)
 {
-	return WMI_SERVICE_IS_ENABLED(wmi_handle->wmi_service_bitmap,
+	struct wmi_soc *soc = wmi_handle->soc;
+
+	if (!soc->wmi_service_bitmap) {
+		WMI_LOGE("WMI service bit map is not saved yet\n");
+		return false;
+	}
+
+	return WMI_SERVICE_IS_ENABLED(soc->wmi_service_bitmap,
 			service_id);
 }
 

+ 76 - 14
wmi/src/wmi_unified_tlv.c

@@ -15862,17 +15862,30 @@ static QDF_STATUS init_cmd_send_tlv(wmi_unified_t wmi_handle,
  * @param evt_buf: pointer to event buffer
  * @param bitmap_buf: bitmap buffer, for converged legacy support
  *
- * Return: None
+ * Return: QDF_STATUS
  */
-#ifndef CONFIG_MCL
 static
-void save_service_bitmap_tlv(wmi_unified_t wmi_handle, void *evt_buf,
+QDF_STATUS save_service_bitmap_tlv(wmi_unified_t wmi_handle, void *evt_buf,
 			     void *bitmap_buf)
 {
 	WMI_SERVICE_READY_EVENTID_param_tlvs *param_buf;
+	struct wmi_soc *soc = wmi_handle->soc;
+
 	param_buf = (WMI_SERVICE_READY_EVENTID_param_tlvs *) evt_buf;
 
-	qdf_mem_copy(wmi_handle->wmi_service_bitmap,
+	/* If it is already allocated, use that buffer. This can happen
+	 * during target stop/start scenarios where host allocation is skipped.
+	 */
+	if (!soc->wmi_service_bitmap) {
+		soc->wmi_service_bitmap =
+			qdf_mem_malloc(WMI_SERVICE_BM_SIZE * sizeof(uint32_t));
+		if (!soc->wmi_service_bitmap) {
+			WMI_LOGE("Failed memory allocation for service bitmap");
+			return QDF_STATUS_E_NOMEM;
+		}
+	}
+
+	qdf_mem_copy(soc->wmi_service_bitmap,
 			param_buf->wmi_service_bitmap,
 			(WMI_SERVICE_BM_SIZE * sizeof(uint32_t)));
 
@@ -15880,22 +15893,53 @@ void save_service_bitmap_tlv(wmi_unified_t wmi_handle, void *evt_buf,
 		qdf_mem_copy(bitmap_buf,
 			     param_buf->wmi_service_bitmap,
 			     (WMI_SERVICE_BM_SIZE * sizeof(uint32_t)));
+
+	return QDF_STATUS_SUCCESS;
 }
-#else
+
+/**
+ * save_ext_service_bitmap_tlv() - save extendend service bitmap
+ * @wmi_handle: wmi handle
+ * @param evt_buf: pointer to event buffer
+ * @param bitmap_buf: bitmap buffer, for converged legacy support
+ *
+ * Return: QDF_STATUS
+ */
 static
-void save_service_bitmap_tlv(wmi_unified_t wmi_handle, void *evt_buf,
+QDF_STATUS save_ext_service_bitmap_tlv(wmi_unified_t wmi_handle, void *evt_buf,
 			     void *bitmap_buf)
 {
-	WMI_SERVICE_READY_EVENTID_param_tlvs *param_buf;
-	param_buf = (WMI_SERVICE_READY_EVENTID_param_tlvs *) evt_buf;
+	WMI_SERVICE_AVAILABLE_EVENTID_param_tlvs *param_buf;
+	wmi_service_available_event_fixed_param *ev;
+	struct wmi_soc *soc = wmi_handle->soc;
+
+	param_buf = (WMI_SERVICE_AVAILABLE_EVENTID_param_tlvs *) evt_buf;
+
+	ev = param_buf->fixed_param;
+
+	/* If it is already allocated, use that buffer. This can happen
+	 * during target stop/start scenarios where host allocation is skipped.
+	 */
+	if (!soc->wmi_ext_service_bitmap) {
+		soc->wmi_ext_service_bitmap = qdf_mem_malloc(
+			WMI_SERVICE_SEGMENT_BM_SIZE32 * sizeof(uint32_t));
+		if (!soc->wmi_ext_service_bitmap) {
+			WMI_LOGE("Failed memory allocation for service bitmap");
+			return QDF_STATUS_E_NOMEM;
+		}
+	}
+
+	qdf_mem_copy(soc->wmi_ext_service_bitmap,
+			ev->wmi_service_segment_bitmap,
+			(WMI_SERVICE_SEGMENT_BM_SIZE32 * sizeof(uint32_t)));
 
 	if (bitmap_buf)
 		qdf_mem_copy(bitmap_buf,
-			     param_buf->wmi_service_bitmap,
-			     (WMI_SERVICE_BM_SIZE * sizeof(uint32_t)));
-}
-#endif
+			soc->wmi_ext_service_bitmap,
+			(WMI_SERVICE_SEGMENT_BM_SIZE32 * sizeof(uint32_t)));
 
+	return QDF_STATUS_SUCCESS;
+}
 /**
  * is_service_enabled_tlv() - Check if service enabled
  * @param wmi_handle: wmi handle
@@ -15907,8 +15951,23 @@ void save_service_bitmap_tlv(wmi_unified_t wmi_handle, void *evt_buf,
 static bool is_service_enabled_tlv(wmi_unified_t wmi_handle,
 		uint32_t service_id)
 {
-	return WMI_SERVICE_IS_ENABLED(wmi_handle->wmi_service_bitmap,
-						service_id);
+	struct wmi_soc *soc = wmi_handle->soc;
+
+	if (!soc->wmi_service_bitmap) {
+		WMI_LOGE("WMI service bit map is not saved yet\n");
+		return false;
+	}
+
+	/* if WMI_EXTENDED_SERVICE_AVAILABLE was received with extended bitmap,
+	 * use WMI_SERVICE_EXT_ENABLE to check the services.
+	 */
+	if (soc->wmi_ext_service_bitmap)
+		return WMI_SERVICE_EXT_IS_ENABLED(soc->wmi_service_bitmap,
+				soc->wmi_ext_service_bitmap,
+				service_id);
+
+	return WMI_SERVICE_IS_ENABLED(soc->wmi_service_bitmap,
+				service_id);
 }
 #else
 static bool is_service_enabled_tlv(wmi_unified_t wmi_handle,
@@ -19257,6 +19316,7 @@ struct wmi_ops tlv_ops =  {
 	.extract_hal_reg_cap = extract_hal_reg_cap_tlv,
 	.extract_host_mem_req = extract_host_mem_req_tlv,
 	.save_service_bitmap = save_service_bitmap_tlv,
+	.save_ext_service_bitmap = save_ext_service_bitmap_tlv,
 	.is_service_enabled = is_service_enabled_tlv,
 	.save_fw_version = save_fw_version_in_service_ready_tlv,
 	.ready_extract_init_status = ready_extract_init_status_tlv,
@@ -19596,6 +19656,8 @@ static void populate_tlv_events_id(uint32_t *event_ids)
 	event_ids[wmi_11d_new_country_event_id] = WMI_11D_NEW_COUNTRY_EVENTID;
 	event_ids[wmi_pdev_tpc_event_id] = WMI_PDEV_TPC_EVENTID;
 	event_ids[wmi_get_arp_stats_req_id] = WMI_VDEV_GET_ARP_STAT_EVENTID;
+	event_ids[wmi_service_available_event_id] =
+						WMI_SERVICE_AVAILABLE_EVENTID;
 }
 
 #ifndef CONFIG_MCL