Browse Source

qcacld-3.0: fix ipa mcc scc event notification

Issue is under AP-AP MCC config, mcc event is not sent from wlan
to IPA driver. mcc mode is decided with the help of connection
table. But for AP mode, mcc mode is checked and updated before
connection table is updated by adding the SAP vdev entry.

Fix is to make ipa mcc mode check and notification when connection
table is updated. Since block is not allowed when conn table is
updated, a new work_struct mcc_work is introduced.

Change-Id: I935222e26bb3f6b31685f52b75084b034daccad2
CRs-Fixed: 2075876
jiad 7 years ago
parent
commit
bb47e130a0

+ 6 - 6
components/ipa/core/inc/wlan_ipa_core.h

@@ -439,15 +439,11 @@ void wlan_ipa_reg_send_to_nw_cb(struct wlan_ipa_priv *ipa_ctx, void *cb)
 /**
  * wlan_ipa_set_mcc_mode() - Set MCC mode
  * @ipa_ctx: IPA context
- * @mcc_mode: 0=MCC/1=SCC
+ * @mcc_mode: 1=MCC/0=SCC
  *
  * Return: void
  */
-static inline
-void wlan_ipa_set_mcc_mode(struct wlan_ipa_priv *ipa_ctx, bool mcc_mode)
-{
-	ipa_ctx->mcc_mode = mcc_mode;
-}
+void wlan_ipa_set_mcc_mode(struct wlan_ipa_priv *ipa_ctx, bool mcc_mode);
 
 /**
  * wlan_ipa_set_dfs_cac_tx() - Set DFS cac tx block
@@ -537,6 +533,10 @@ QDF_STATUS wlan_ipa_send_mcc_scc_msg(struct wlan_ipa_priv *ipa_ctx,
 {
 	return QDF_STATUS_SUCCESS;
 }
+
+static inline void wlan_ipa_mcc_work_handler(void *data)
+{
+}
 #endif
 
 /**

+ 1 - 0
components/ipa/core/inc/wlan_ipa_priv.h

@@ -631,6 +631,7 @@ struct wlan_ipa_priv {
 	uint8_t vdev_to_iface[WLAN_IPA_MAX_SESSION];
 	bool vdev_offload_enabled[WLAN_IPA_MAX_SESSION];
 	bool mcc_mode;
+	qdf_work_t mcc_work;
 	bool ap_intrabss_fwd;
 	bool dfs_cac_block_tx;
 #ifdef FEATURE_METERING

+ 59 - 35
components/ipa/core/src/wlan_ipa_core.c

@@ -2061,6 +2061,53 @@ static void wlan_ipa_teardown_sys_pipe(struct wlan_ipa_priv *ipa_ctx)
 	}
 }
 
+#ifndef QCA_LL_TX_FLOW_CONTROL_V2
+QDF_STATUS wlan_ipa_send_mcc_scc_msg(struct wlan_ipa_priv *ipa_ctx,
+				     bool mcc_mode)
+{
+	qdf_ipa_msg_meta_t meta;
+	qdf_ipa_wlan_msg_t *msg;
+	int ret;
+
+	if (!wlan_ipa_uc_sta_is_enabled(ipa_ctx->config))
+		return QDF_STATUS_SUCCESS;
+
+	/* Send SCC/MCC Switching event to IPA */
+	QDF_IPA_MSG_META_MSG_LEN(&meta) = sizeof(*msg);
+	msg = qdf_mem_malloc(QDF_IPA_MSG_META_MSG_LEN(&meta));
+	if (msg == NULL) {
+		ipa_err("msg allocation failed");
+		return QDF_STATUS_E_NOMEM;
+	}
+
+	if (mcc_mode)
+		QDF_IPA_SET_META_MSG_TYPE(&meta, QDF_SWITCH_TO_MCC);
+	else
+		QDF_IPA_SET_META_MSG_TYPE(&meta, QDF_SWITCH_TO_SCC);
+	WLAN_IPA_LOG(QDF_TRACE_LEVEL_DEBUG,
+		    "ipa_send_msg(Evt:%d)",
+		    QDF_IPA_MSG_META_MSG_TYPE(&meta));
+
+	ret = qdf_ipa_send_msg(&meta, msg, wlan_ipa_msg_free_fn);
+
+	if (ret) {
+		ipa_err("ipa_send_msg(Evt:%d) - fail=%d",
+			QDF_IPA_MSG_META_MSG_TYPE(&meta), ret);
+		qdf_mem_free(msg);
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	return QDF_STATUS_SUCCESS;
+}
+
+static void wlan_ipa_mcc_work_handler(void *data)
+{
+	struct wlan_ipa_priv *ipa_ctx = (struct wlan_ipa_priv *)data;
+
+	wlan_ipa_send_mcc_scc_msg(ipa_ctx, ipa_ctx->mcc_mode);
+}
+#endif
+
 /**
  * wlan_ipa_setup() - IPA initialization function
  * @ipa_ctx: IPA context
@@ -2134,6 +2181,9 @@ QDF_STATUS wlan_ipa_setup(struct wlan_ipa_priv *ipa_ctx,
 			ret = wlan_ipa_setup_sys_pipe(ipa_ctx);
 			if (ret)
 				goto fail_create_sys_pipe;
+
+			qdf_create_work(0, &ipa_ctx->mcc_work,
+					wlan_ipa_mcc_work_handler, ipa_ctx);
 		}
 
 		status = wlan_ipa_wdi_init(ipa_ctx);
@@ -2208,8 +2258,10 @@ QDF_STATUS wlan_ipa_cleanup(struct wlan_ipa_priv *ipa_ctx)
 		wlan_ipa_teardown_sys_pipe(ipa_ctx);
 
 	/* Teardown IPA sys_pipe for MCC */
-	if (wlan_ipa_uc_sta_is_enabled(ipa_ctx->config))
+	if (wlan_ipa_uc_sta_is_enabled(ipa_ctx->config)) {
 		wlan_ipa_teardown_sys_pipe(ipa_ctx);
+		qdf_cancel_work(&ipa_ctx->mcc_work);
+	}
 
 	wlan_ipa_wdi_destroy_rm(ipa_ctx);
 
@@ -2253,45 +2305,17 @@ struct wlan_ipa_iface_context
 	return NULL;
 }
 
-#ifndef QCA_LL_TX_FLOW_CONTROL_V2
-QDF_STATUS wlan_ipa_send_mcc_scc_msg(struct wlan_ipa_priv *ipa_ctx,
-				     bool mcc_mode)
+void wlan_ipa_set_mcc_mode(struct wlan_ipa_priv *ipa_ctx, bool mcc_mode)
 {
-	qdf_ipa_msg_meta_t meta;
-	qdf_ipa_wlan_msg_t *msg;
-	int ret;
-
 	if (!wlan_ipa_uc_sta_is_enabled(ipa_ctx->config))
-		return QDF_STATUS_SUCCESS;
-
-	/* Send SCC/MCC Switching event to IPA */
-	QDF_IPA_MSG_META_MSG_LEN(&meta) = sizeof(*msg);
-	msg = qdf_mem_malloc(QDF_IPA_MSG_META_MSG_LEN(&meta));
-	if (msg == NULL) {
-		ipa_err("msg allocation failed");
-		return QDF_STATUS_E_NOMEM;
-	}
-
-	if (mcc_mode)
-		QDF_IPA_SET_META_MSG_TYPE(&meta, QDF_SWITCH_TO_MCC);
-	else
-		QDF_IPA_SET_META_MSG_TYPE(&meta, QDF_SWITCH_TO_SCC);
-	WLAN_IPA_LOG(QDF_TRACE_LEVEL_DEBUG,
-		    "ipa_send_msg(Evt:%d)",
-		    QDF_IPA_MSG_META_MSG_TYPE(&meta));
-
-	ret = qdf_ipa_send_msg(&meta, msg, wlan_ipa_msg_free_fn);
+		return;
 
-	if (ret) {
-		ipa_err("ipa_send_msg(Evt:%d) - fail=%d",
-			QDF_IPA_MSG_META_MSG_TYPE(&meta), ret);
-		qdf_mem_free(msg);
-		return QDF_STATUS_E_FAILURE;
-	}
+	if (ipa_ctx->mcc_mode == mcc_mode)
+		return;
 
-	return QDF_STATUS_SUCCESS;
+	ipa_ctx->mcc_mode = mcc_mode;
+	qdf_sched_work(0, &ipa_ctx->mcc_work);
 }
-#endif
 
 /**
  * wlan_ipa_uc_loaded_handler() - Process IPA uC loaded indication

+ 14 - 0
core/hdd/inc/wlan_hdd_ipa.h

@@ -61,6 +61,16 @@ void hdd_ipa_send_skb_to_network(qdf_nbuf_t skb, qdf_netdev_t dev);
  */
 void hdd_ipa_set_tx_flow_info(void);
 
+/**
+ * hdd_ipa_set_mcc_mode() - To set mcc mode if IPA is enabled
+ * @mcc_mode: mcc mode
+ *
+ * This routine is called to set mcc mode if IPA is enabled
+ *
+ * Return: None
+ */
+void hdd_ipa_set_mcc_mode(bool mcc_mode);
+
 #else
 static inline
 void hdd_ipa_send_skb_to_network(qdf_nbuf_t skb, qdf_netdev_t dev)
@@ -71,5 +81,9 @@ static inline void hdd_ipa_set_tx_flow_info(void)
 {
 }
 
+static inline void hdd_ipa_set_mcc_mode(bool mcc_mode)
+{
+}
+
 #endif
 #endif /* HDD_IPA_H__ */

+ 0 - 2
core/hdd/src/wlan_hdd_assoc.c

@@ -1485,8 +1485,6 @@ static void hdd_send_association_event(struct net_device *dev,
 #endif
 	}
 	hdd_ipa_set_tx_flow_info();
-	/* Send SCC/MCC Switching event to IPA */
-	ucfg_ipa_send_mcc_scc_msg(hdd_ctx->hdd_pdev, hdd_ctx->mcc_mode);
 
 	msg = NULL;
 	/* During the WLAN uninitialization,supplicant is stopped before the

+ 0 - 4
core/hdd/src/wlan_hdd_hostapd.c

@@ -1784,8 +1784,6 @@ QDF_STATUS hdd_hostapd_sap_event_cb(tpSap_Event pSapEvent,
 		we_event = IWEVCUSTOM;
 		we_custom_event_generic = we_custom_start_event;
 		hdd_ipa_set_tx_flow_info();
-		/* Send SCC/MCC Switching event to IPA */
-		ucfg_ipa_send_mcc_scc_msg(hdd_ctx->hdd_pdev, hdd_ctx->mcc_mode);
 
 		if (policy_mgr_is_hw_mode_change_after_vdev_up(
 			hdd_ctx->hdd_psoc)) {
@@ -2553,8 +2551,6 @@ stopbss:
 			qdf_event_set(&hostapd_state->qdf_stop_bss_event);
 
 		hdd_ipa_set_tx_flow_info();
-		/* Send SCC/MCC Switching event to IPA */
-		ucfg_ipa_send_mcc_scc_msg(hdd_ctx->hdd_pdev, hdd_ctx->mcc_mode);
 	}
 	return QDF_STATUS_SUCCESS;
 }

+ 13 - 3
core/hdd/src/wlan_hdd_ipa.c

@@ -320,9 +320,6 @@ void hdd_ipa_set_tx_flow_info(void)
 		targetChannel = 0;
 #endif /* QCA_LL_LEGACY_TX_FLOW_CONTROL */
 	}
-
-	hdd_ctx->mcc_mode = policy_mgr_current_concurrency_is_mcc(psoc);
-	ucfg_ipa_set_mcc_mode(hdd_ctx->hdd_pdev, hdd_ctx->mcc_mode);
 }
 
 #ifdef QCA_CONFIG_SMP
@@ -404,3 +401,16 @@ void hdd_ipa_send_skb_to_network(qdf_nbuf_t skb, qdf_netdev_t dev)
 	else
 		++adapter->hdd_stats.tx_rx_stats.rx_refused[cpu_index];
 }
+
+void hdd_ipa_set_mcc_mode(bool mcc_mode)
+{
+	struct hdd_context *hdd_ctx;
+
+	hdd_ctx = cds_get_context(QDF_MODULE_ID_HDD);
+	if (!hdd_ctx) {
+		hdd_err("HDD context is NULL");
+		return;
+	}
+
+	ucfg_ipa_set_mcc_mode(hdd_ctx->hdd_pdev, mcc_mode);
+}

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

@@ -10041,6 +10041,7 @@ int hdd_configure_cds(struct hdd_context *hdd_ctx, struct hdd_adapter *adapter)
 
 	dp_cbs.hdd_disable_lro_in_concurrency = hdd_disable_lro_in_concurrency;
 	dp_cbs.hdd_set_rx_mode_rps_cb = hdd_set_rx_mode_rps;
+	dp_cbs.hdd_ipa_set_mcc_mode_cb = hdd_ipa_set_mcc_mode;
 	status = policy_mgr_register_dp_cb(hdd_ctx->hdd_psoc, &dp_cbs);
 	if (!QDF_IS_STATUS_SUCCESS(status)) {
 		hdd_debug("Failed to register DP cb with Policy Manager");