Prechádzať zdrojové kódy

qcacld-3.0: Add enhanced multicast enable/disable APIs

Currently, a hard-coded enhanced multicast filter configuration is being
sent to firmware. Instead, create a set of enable/disable APIs, and
configure enhanced multicast filter based on advertised firmware
capability.

Change-Id: I488b4a921612e1081266be8831be098d755375f9
CRs-Fixed: 2078615
Dustin Brown 7 rokov pred
rodič
commit
8d8d9fe485

+ 16 - 0
components/pmo/core/inc/wlan_pmo_mc_addr_filtering.h

@@ -66,6 +66,22 @@ QDF_STATUS pmo_core_cache_mc_addr_list(
 QDF_STATUS pmo_core_flush_mc_addr_list(struct wlan_objmgr_psoc *psoc,
 	uint8_t vdev_id);
 
+/**
+ * pmo_core_enhance_mc_filter_enable() - enable enhanced multicast filtering
+ * @vdev: the vdev to enable enhanced multicast filtering for
+ *
+ * Return: QDF_STATUS
+ */
+QDF_STATUS pmo_core_enhanced_mc_filter_enable(struct wlan_objmgr_vdev *vdev);
+
+/**
+ * pmo_core_enhance_mc_filter_disable() - disable enhanced multicast filtering
+ * @vdev: the vdev to disable enhanced multicast filtering for
+ *
+ * Return: QDF_STATUS
+ */
+QDF_STATUS pmo_core_enhanced_mc_filter_disable(struct wlan_objmgr_vdev *vdev);
+
 /**
  * pmo_core_enable_mc_addr_filtering_in_fwr(): Enable cached mc add list in fwr
  * @psoc: objmgr psoc handle

+ 2 - 8
components/pmo/core/inc/wlan_pmo_objmgr.h

@@ -60,7 +60,6 @@ pmo_vdev_get_id(struct wlan_objmgr_vdev *vdev)
 	uint8_t vdev_id;
 
 	vdev_id = wlan_vdev_get_id(vdev);
-
 	QDF_BUG(vdev_id < WLAN_UMAC_PSOC_MAX_VDEVS);
 
 	return vdev_id;
@@ -122,10 +121,9 @@ pmo_psoc_get_vdev(struct wlan_objmgr_psoc *psoc, uint8_t vdev_id)
 {
 	struct wlan_objmgr_vdev *vdev;
 
-	if (vdev_id >= WLAN_UMAC_PSOC_MAX_VDEVS) {
-		QDF_BUG(0);
+	QDF_BUG(vdev_id < WLAN_UMAC_PSOC_MAX_VDEVS);
+	if (vdev_id >= WLAN_UMAC_PSOC_MAX_VDEVS)
 		return NULL;
-	}
 
 	wlan_psoc_obj_lock(psoc);
 	vdev = psoc->soc_objmgr.wlan_vdev_list[vdev_id];
@@ -140,7 +138,6 @@ pmo_psoc_get_priv(struct wlan_objmgr_psoc *psoc)
 	struct pmo_psoc_priv_obj *psoc_priv;
 
 	psoc_priv = pmo_psoc_get_priv_nolock(psoc);
-
 	QDF_BUG(psoc_priv);
 
 	return psoc_priv;
@@ -154,7 +151,6 @@ pmo_pdev_get_psoc(struct wlan_objmgr_pdev *pdev)
 	struct wlan_objmgr_psoc *psoc;
 
 	psoc = wlan_pdev_get_psoc(pdev);
-
 	QDF_BUG(psoc);
 
 	return psoc;
@@ -174,7 +170,6 @@ pmo_vdev_get_priv(struct wlan_objmgr_vdev *vdev)
 	struct pmo_vdev_priv_obj *vdev_priv;
 
 	vdev_priv = pmo_vdev_get_priv_nolock(vdev);
-
 	QDF_BUG(vdev_priv);
 
 	return vdev_priv;
@@ -186,7 +181,6 @@ pmo_vdev_get_pdev(struct wlan_objmgr_vdev *vdev)
 	struct wlan_objmgr_pdev *pdev;
 
 	pdev = wlan_vdev_get_pdev(vdev);
-
 	QDF_BUG(pdev);
 
 	return pdev;

+ 72 - 73
components/pmo/core/src/wlan_pmo_mc_addr_filtering.c

@@ -102,40 +102,55 @@ static QDF_STATUS pmo_core_flush_mc_addr_list_from_vdev_priv(
 	return QDF_STATUS_SUCCESS;
 }
 
+QDF_STATUS pmo_core_enhanced_mc_filter_enable(struct wlan_objmgr_vdev *vdev)
+{
+	QDF_STATUS status;
+
+	PMO_ENTER();
+
+	status = pmo_vdev_get_ref(vdev);
+	if (QDF_IS_STATUS_ERROR(status))
+		goto exit_with_status;
+
+	pmo_tgt_send_enhance_multicast_offload_req(vdev, true);
+
+	pmo_vdev_put_ref(vdev);
+
+exit_with_status:
+	PMO_EXIT();
+
+	return status;
+}
+
+QDF_STATUS pmo_core_enhanced_mc_filter_disable(struct wlan_objmgr_vdev *vdev)
+{
+	QDF_STATUS status;
+
+	PMO_ENTER();
+
+	status = pmo_vdev_get_ref(vdev);
+	if (QDF_IS_STATUS_ERROR(status))
+		goto exit_with_status;
+
+	pmo_tgt_send_enhance_multicast_offload_req(vdev, false);
+
+	pmo_vdev_put_ref(vdev);
+
+exit_with_status:
+	PMO_EXIT();
+
+	return status;
+}
+
 QDF_STATUS pmo_core_set_mc_filter_req(struct wlan_objmgr_vdev *vdev,
 	struct pmo_mc_addr_list *mc_list)
 {
-	uint8_t vdev_id;
 	int i;
 
 	PMO_ENTER();
 
-	vdev_id = pmo_vdev_get_id(vdev);
-	/*
-	 * Configure enhance multicast offload feature for filtering out
-	 * multicast IP data packets transmitted using unicast MAC address
-	 */
-
-	/*
-	* TODO
-	{//(WMI_SERVICE_IS_ENABLED(wma_handle->wmi_service_bitmap,
-		//WMI_SERVICE_ENHANCED_MCAST_FILTER)) {
-	*/
-	if (1) {
-		pmo_info("FW supports enhance multicast offload");
-		pmo_tgt_send_enhance_multicast_offload_req(vdev, vdev_id,
-			false);
-	} else {
-		pmo_info("FW does not support enhance multicast offload");
-	}
-
-	/*
-	 * set mc_param->action to clear MCList and reset
-	 * to configure the MCList in FW
-	 */
 	for (i = 0; i < mc_list->mc_cnt; i++) {
-		pmo_tgt_set_mc_filter_req(vdev,
-					mc_list->mc_addr[i]);
+		pmo_tgt_set_mc_filter_req(vdev, mc_list->mc_addr[i]);
 	}
 
 	PMO_EXIT();
@@ -146,35 +161,10 @@ QDF_STATUS pmo_core_set_mc_filter_req(struct wlan_objmgr_vdev *vdev,
 QDF_STATUS pmo_core_clear_mc_filter_req(struct wlan_objmgr_vdev *vdev,
 	struct pmo_mc_addr_list *mc_list)
 {
-	uint8_t vdev_id;
 	int i;
 
 	PMO_ENTER();
 
-	vdev_id = pmo_vdev_get_id(vdev);
-
-	/*
-	 * Configure enhance multicast offload feature for filtering out
-	 * multicast IP data packets transmitted using unicast MAC address
-	 */
-
-	/*
-	* TODO
-	{//(WMI_SERVICE_IS_ENABLED(wma_handle->wmi_service_bitmap,
-		//WMI_SERVICE_ENHANCED_MCAST_FILTER)) {
-	*/
-	if (1) {
-		pmo_info("FW supports enhance multicast offload");
-		pmo_tgt_send_enhance_multicast_offload_req(vdev, vdev_id,
-			true);
-	} else {
-		pmo_info("FW does not support enhance multicast offload");
-	}
-
-	/*
-	 * set mcbc_param->action to clear MCList and reset
-	 * to configure the MCList in FW
-	 */
 	for (i = 0; i < mc_list->mc_cnt; i++) {
 		pmo_tgt_clear_mc_filter_req(vdev, mc_list->mc_addr[i]);
 	}
@@ -439,46 +429,51 @@ static QDF_STATUS pmo_core_handle_enable_mc_list_trigger(
 {
 	struct pmo_vdev_priv_obj *vdev_ctx;
 	QDF_STATUS status;
-	struct pmo_mc_addr_list *op_mc_list_req = NULL;
+	struct pmo_mc_addr_list *op_mc_list_req;
+
+	PMO_ENTER();
 
 	vdev_ctx = pmo_vdev_get_priv(vdev);
 
 	op_mc_list_req = qdf_mem_malloc(sizeof(*op_mc_list_req));
 	if (!op_mc_list_req) {
 		pmo_err("op_mc_list_req is NULL");
-		status = QDF_STATUS_E_NULL_VALUE;
-		goto out;
+		status = QDF_STATUS_E_NOMEM;
+		goto exit_with_status;
 	}
 
 	switch (trigger) {
 	case pmo_mc_list_change_notify:
 		if (!vdev_ctx->pmo_psoc_ctx->psoc_cfg.active_mode_offload) {
 			pmo_info("active offload is disabled, skip in mode: %d",
-				trigger);
+				 trigger);
 			status = QDF_STATUS_E_INVAL;
-			goto out;
+			goto free_req;
 		}
 		status = pmo_core_do_enable_mc_addr_list(vdev, vdev_ctx,
-				op_mc_list_req);
+							 op_mc_list_req);
 		break;
 	case pmo_apps_suspend:
 		if (vdev_ctx->pmo_psoc_ctx->psoc_cfg.active_mode_offload) {
 			pmo_info("active offload is enabled, skip in mode: %d",
 				trigger);
 			status = QDF_STATUS_E_INVAL;
-			goto out;
+			goto free_req;
 		}
 		status = pmo_core_do_enable_mc_addr_list(vdev, vdev_ctx,
-				op_mc_list_req);
+							 op_mc_list_req);
 		break;
 	default:
 		status = QDF_STATUS_E_INVAL;
 		pmo_err("invalid pmo trigger for enable mc list");
 		break;
 	}
-out:
-	if (op_mc_list_req)
-		qdf_mem_free(op_mc_list_req);
+
+free_req:
+	qdf_mem_free(op_mc_list_req);
+
+exit_with_status:
+	PMO_EXIT();
 
 	return status;
 }
@@ -492,32 +487,36 @@ QDF_STATUS pmo_core_enable_mc_addr_filtering_in_fwr(
 	struct wlan_objmgr_vdev *vdev;
 
 	PMO_ENTER();
-	if (!psoc) {
-		pmo_err("psoc is NULL");
-		status = QDF_STATUS_E_NULL_VALUE;
-		goto out;
-	}
+
+	status = pmo_psoc_get_ref(psoc);
+	if (QDF_IS_STATUS_ERROR(status))
+		goto exit_with_status;
 
 	vdev = pmo_psoc_get_vdev(psoc, vdev_id);
 	if (!vdev) {
 		pmo_err("vdev is NULL");
-		status = QDF_STATUS_E_NULL_VALUE;
-		goto out;
+		status = QDF_STATUS_E_INVAL;
+		goto put_psoc;
 	}
 
 	status = pmo_vdev_get_ref(vdev);
 	if (QDF_IS_STATUS_ERROR(status))
-		goto out;
+		goto put_psoc;
 
 	status = pmo_core_mc_addr_flitering_sanity(vdev);
 	if (status != QDF_STATUS_SUCCESS)
-		goto dec_ref;
+		goto put_vdev;
 
 	pmo_info("enable mclist trigger: %d", trigger);
 	status = pmo_core_handle_enable_mc_list_trigger(vdev, trigger);
-dec_ref:
+
+put_vdev:
 	pmo_vdev_put_ref(vdev);
-out:
+
+put_psoc:
+	pmo_psoc_put_ref(psoc);
+
+exit_with_status:
 	PMO_EXIT();
 
 	return status;

+ 1 - 3
components/pmo/dispatcher/inc/wlan_pmo_tgt_api.h

@@ -172,15 +172,13 @@ QDF_STATUS pmo_tgt_clear_mc_filter_req(struct wlan_objmgr_vdev *vdev,
 
 /**
  * pmo_tgt_send_enhance_multicast_offload_req() - send enhance mc offload req
- * @wma_handle: wma handle
- * @vdev_id: vdev id
+ * @vdev: the vdev to configure
  * @action: enable or disable enhance multicast offload
  *
  * Return: QDF_STATUS_SUCCESS on success else error code
  */
 QDF_STATUS pmo_tgt_send_enhance_multicast_offload_req(
 		struct wlan_objmgr_vdev *vdev,
-		uint8_t vdev_id,
 		uint8_t action);
 
 /**

+ 25 - 0
components/pmo/dispatcher/inc/wlan_pmo_ucfg_api.h

@@ -25,6 +25,7 @@
 #include "wlan_pmo_arp_public_struct.h"
 #include "wlan_pmo_ns_public_struct.h"
 #include "wlan_pmo_gtk_public_struct.h"
+#include "wlan_pmo_mc_addr_filtering.h"
 #include "wlan_pmo_mc_addr_filtering_public_struct.h"
 #include "wlan_pmo_wow_public_struct.h"
 #include "wlan_pmo_common_public_struct.h"
@@ -228,6 +229,30 @@ QDF_STATUS pmo_ucfg_cache_mc_addr_list(
 QDF_STATUS pmo_ucfg_flush_mc_addr_list(struct wlan_objmgr_psoc *psoc,
 	uint8_t vdev_id);
 
+/**
+ * pmo_ucfg_enhance_mc_filter_enable() - enable enhanced multicast filtering
+ * @vdev: the vdev to enable enhanced multicast filtering for
+ *
+ * Return: QDF_STATUS
+ */
+static inline QDF_STATUS
+pmo_ucfg_enhanced_mc_filter_enable(struct wlan_objmgr_vdev *vdev)
+{
+	return pmo_core_enhanced_mc_filter_enable(vdev);
+}
+
+/**
+ * pmo_ucfg_enhance_mc_filter_disable() - disable enhanced multicast filtering
+ * @vdev: the vdev to disable enhanced multicast filtering for
+ *
+ * Return: QDF_STATUS
+ */
+static inline QDF_STATUS
+pmo_ucfg_enhanced_mc_filter_disable(struct wlan_objmgr_vdev *vdev)
+{
+	return pmo_core_enhanced_mc_filter_disable(vdev);
+}
+
 /**
  * pmo_ucfg_enable_mc_addr_filtering_in_fwr(): Enable cached mc add list in fwr
  * @psoc: objmgr psoc handle

+ 2 - 3
components/pmo/dispatcher/src/wlan_pmo_tgt_static_config.c

@@ -25,9 +25,8 @@
 #include "wlan_pmo_main.h"
 
 QDF_STATUS pmo_tgt_send_enhance_multicast_offload_req(
-		struct wlan_objmgr_vdev *vdev,
-		uint8_t vdev_id,
-		uint8_t action)
+	struct wlan_objmgr_vdev *vdev,
+	uint8_t action)
 {
 	QDF_STATUS status;
 	struct wlan_objmgr_psoc *psoc;

+ 10 - 0
core/hdd/src/wlan_hdd_main.c

@@ -3028,7 +3028,17 @@ int hdd_vdev_ready(hdd_adapter_t *adapter)
 	QDF_STATUS status;
 
 	status = pmo_vdev_ready(adapter->hdd_vdev);
+	if (QDF_IS_STATUS_ERROR(status))
+		return qdf_status_to_os_return(status);
+
 	status = ucfg_reg_11d_vdev_created_update(adapter->hdd_vdev);
+	if (QDF_IS_STATUS_ERROR(status))
+		return qdf_status_to_os_return(status);
+
+	if (wma_capability_enhanced_mcast_filter())
+		status = pmo_ucfg_enhanced_mc_filter_enable(adapter->hdd_vdev);
+	else
+		status = pmo_ucfg_enhanced_mc_filter_disable(adapter->hdd_vdev);
 
 	return qdf_status_to_os_return(status);
 }

+ 1 - 0
core/wma/inc/wma_api.h

@@ -223,6 +223,7 @@ static inline QDF_STATUS wma_register_ndp_cb(QDF_STATUS (*pe_ndp_event_handler)
 
 bool wma_is_csa_offload_enabled(void);
 bool wma_is_p2p_lo_capable(void);
+bool wma_capability_enhanced_mcast_filter(void);
 QDF_STATUS wma_p2p_lo_start(struct sir_p2p_lo_start *params);
 QDF_STATUS wma_p2p_lo_stop(u_int32_t vdev_id);
 QDF_STATUS wma_get_wakelock_stats(struct sir_wake_lock_stats *wake_lock_stats);

+ 6 - 12
core/wma/src/wma_utils.c

@@ -4228,21 +4228,15 @@ wma_config_debug_module_cmd(wmi_unified_t wmi_handle, A_UINT32 param,
  */
 bool wma_is_p2p_lo_capable(void)
 {
-	tp_wma_handle wma;
-
-	wma = cds_get_context(QDF_MODULE_ID_WMA);
-	if (!wma) {
-		WMA_LOGE("%s: Invalid WMA handle", __func__);
-		return false;
-	}
-
-	if (WMI_SERVICE_IS_ENABLED(wma->wmi_service_bitmap,
-			WMI_SERVICE_P2P_LISTEN_OFFLOAD_SUPPORT))
-		return true;
+	return wma_is_service_enabled(WMI_SERVICE_P2P_LISTEN_OFFLOAD_SUPPORT);
+}
 
-	return false;
+bool wma_capability_enhanced_mcast_filter(void)
+{
+	return wma_is_service_enabled(WMI_SERVICE_ENHANCED_MCAST_FILTER);
 }
 
+
 bool wma_is_vdev_up(uint8_t vdev_id)
 {
 	struct wlan_objmgr_vdev *vdev;