Quellcode durchsuchen

qcacld-3.0: Enable/Disable MC filter when connected

Multicast address filtering only makes sense if the interface is
connected and capable of receiving traffic. Avoid enabling/disabling
the multicast address filter list on an interface that is disconnected.

Change-Id: Id8aff136e920bb726b8c7dd539d477ff44f080d4
CRs-Fixed: 2282003
Dustin Brown vor 6 Jahren
Ursprung
Commit
0127a73a2d

+ 5 - 7
components/pmo/core/src/wlan_pmo_arp.c

@@ -64,14 +64,12 @@ static QDF_STATUS pmo_core_cache_arp_in_vdev_priv(
 	/* cache arp request */
 	qdf_spin_lock_bh(&vdev_ctx->pmo_vdev_lock);
 	qdf_mem_copy(&vdev_ctx->vdev_arp_req, request,
-		sizeof(vdev_ctx->vdev_arp_req));
+		     sizeof(vdev_ctx->vdev_arp_req));
 	qdf_spin_unlock_bh(&vdev_ctx->pmo_vdev_lock);
-	pmo_debug("arp offload ipv4 addr: %d.%d.%d.%d enable: %d",
-		request->host_ipv4_addr[0],
-		request->host_ipv4_addr[1],
-		request->host_ipv4_addr[2],
-		request->host_ipv4_addr[3],
-		request->enable);
+
+	pmo_debug("cached arp offload; addr:" QDF_IPV4_ADDR_STR ", enable:%d",
+		  QDF_IPV4_ADDR_ARRAY(request->host_ipv4_addr),
+		  request->enable);
 
 free_req:
 	qdf_mem_free(request);

+ 11 - 3
components/pmo/core/src/wlan_pmo_mc_addr_filtering.c

@@ -339,9 +339,6 @@ static QDF_STATUS pmo_core_mc_addr_flitering_sanity(
 		return QDF_STATUS_E_INVAL;
 	}
 
-	if (!pmo_core_is_vdev_connected(vdev))
-		return QDF_STATUS_E_INVAL;
-
 	return QDF_STATUS_SUCCESS;
 }
 QDF_STATUS pmo_core_cache_mc_addr_list(
@@ -380,6 +377,7 @@ QDF_STATUS pmo_core_cache_mc_addr_list(
 		  mc_list_config->vdev_id, mc_list_config->psoc);
 
 	status = pmo_core_cache_mc_addr_list_in_vdev_priv(mc_list_config, vdev);
+
 dec_ref:
 	pmo_vdev_put_ref(vdev);
 out:
@@ -516,6 +514,11 @@ QDF_STATUS pmo_core_enable_mc_addr_filtering_in_fwr(
 	if (status != QDF_STATUS_SUCCESS)
 		goto put_vdev;
 
+	if (!pmo_core_is_vdev_connected(vdev)) {
+		status = QDF_STATUS_E_INVAL;
+		goto put_vdev;
+	}
+
 	pmo_debug("enable mclist trigger: %d", trigger);
 	status = pmo_core_handle_enable_mc_list_trigger(vdev, trigger);
 
@@ -613,6 +616,11 @@ QDF_STATUS pmo_core_disable_mc_addr_filtering_in_fwr(
 	if (status != QDF_STATUS_SUCCESS)
 		goto put_ref;
 
+	if (!pmo_core_is_vdev_connected(vdev)) {
+		status = QDF_STATUS_E_INVAL;
+		goto put_ref;
+	}
+
 	pmo_debug("disable mclist trigger: %d", trigger);
 
 	status = pmo_core_handle_disable_mc_list_trigger(vdev, trigger);

+ 8 - 0
core/hdd/inc/wlan_hdd_assoc.h

@@ -233,6 +233,14 @@ bool hdd_is_fils_connection(struct hdd_adapter *adapter);
  */
 bool hdd_conn_is_connected(struct hdd_station_ctx *sta_ctx);
 
+/**
+ * hdd_adapter_is_connected_sta() - check if @adapter is a connected station
+ * @adapter: the adapter to check
+ *
+ * Return: true if @adapter is a connected station
+ */
+bool hdd_adapter_is_connected_sta(struct hdd_adapter *adapter);
+
 /**
  * hdd_conn_get_connected_band() - get current connection radio band
  * @sta_ctx:    pointer to global HDD Station context

+ 24 - 33
core/hdd/src/wlan_hdd_assoc.c

@@ -268,56 +268,47 @@ void hdd_conn_set_connection_state(struct hdd_adapter *adapter,
  */
 static inline bool
 hdd_conn_get_connection_state(struct hdd_station_ctx *sta_ctx,
-			      eConnectionState *pConnState)
+			      eConnectionState *out_state)
 {
-	bool connected = false;
-	eConnectionState connState;
+	eConnectionState state = sta_ctx->conn_info.connState;
 
-	/* get the connection state. */
-	connState = sta_ctx->conn_info.connState;
+	if (out_state)
+		*out_state = state;
 
-	if (eConnectionState_Associated == connState ||
-	    eConnectionState_IbssConnected == connState ||
-	    eConnectionState_IbssDisconnected == connState) {
-		connected = true;
+	switch (state) {
+	case eConnectionState_Associated:
+	case eConnectionState_IbssConnected:
+	case eConnectionState_IbssDisconnected:
+	case eConnectionState_NdiConnected:
+		return true;
+	default:
+		return false;
 	}
-
-	if (pConnState)
-		*pConnState = connState;
-
-	return connected;
 }
 
-/**
- * hdd_is_connecting() - Function to check connection progress
- * @hdd_sta_ctx:    pointer to global HDD Station context
- *
- * Return: true if connecting, false otherwise
- */
 bool hdd_is_connecting(struct hdd_station_ctx *hdd_sta_ctx)
 {
 	return hdd_sta_ctx->conn_info.connState ==
 		eConnectionState_Connecting;
 }
 
-/**
- * hdd_conn_is_connected() - Function to check connection status
- * @sta_ctx:    pointer to global HDD Station context
- *
- * Return: false if any errors encountered, true otherwise
- */
 bool hdd_conn_is_connected(struct hdd_station_ctx *sta_ctx)
 {
 	return hdd_conn_get_connection_state(sta_ctx, NULL);
 }
 
-/**
- * hdd_conn_get_connected_band() - get current connection radio band
- * @sta_ctx:    pointer to global HDD Station context
- *
- * Return: BAND_2G or BAND_5G based on current AP connection
- *	BAND_ALL if not connected
- */
+bool hdd_adapter_is_connected_sta(struct hdd_adapter *adapter)
+{
+	switch (adapter->device_mode) {
+	case QDF_STA_MODE:
+	case QDF_P2P_CLIENT_MODE:
+	case QDF_NDI_MODE:
+		return hdd_conn_is_connected(&adapter->session.station);
+	default:
+		return false;
+	}
+}
+
 enum band_info hdd_conn_get_connected_band(struct hdd_station_ctx *sta_ctx)
 {
 	uint8_t staChannel = 0;

+ 40 - 27
core/hdd/src/wlan_hdd_power.c

@@ -878,13 +878,13 @@ void hdd_enable_arp_offload(struct hdd_adapter *adapter,
 
 	status = pmo_ucfg_cache_arp_offload_req(arp_req);
 	if (QDF_IS_STATUS_ERROR(status)) {
-		hdd_err("failed to cache arp offload request");
+		hdd_err("failed to cache arp offload req; status:%d", status);
 		goto free_req;
 	}
 
 	status = pmo_ucfg_enable_arp_offload_in_fwr(adapter->hdd_vdev, trigger);
 	if (QDF_IS_STATUS_ERROR(status)) {
-		hdd_err("failed to configure arp offload in firmware");
+		hdd_err("failed arp offload config in fw; status:%d", status);
 		goto free_req;
 	}
 
@@ -921,40 +921,48 @@ out:
 }
 
 void hdd_enable_mc_addr_filtering(struct hdd_adapter *adapter,
-		enum pmo_offload_trigger trigger)
+				  enum pmo_offload_trigger trigger)
 {
 	struct hdd_context *hdd_ctx = WLAN_HDD_GET_CTX(adapter);
 	QDF_STATUS status;
-	struct wlan_objmgr_psoc *psoc = hdd_ctx->hdd_psoc;
 
 	hdd_enter();
+
 	if (wlan_hdd_validate_context(hdd_ctx))
 		goto out;
 
-	status = pmo_ucfg_enable_mc_addr_filtering_in_fwr(psoc,
-				adapter->session_id, trigger);
+	if (!hdd_adapter_is_connected_sta(adapter))
+		goto out;
+
+	status = pmo_ucfg_enable_mc_addr_filtering_in_fwr(hdd_ctx->hdd_psoc,
+							  adapter->session_id,
+							  trigger);
 	if (QDF_IS_STATUS_ERROR(status))
-		hdd_info("failed to enable mc list status %d", status);
+		hdd_err("failed to enable mc list; status:%d", status);
+
 out:
 	hdd_exit();
-
 }
 
 void hdd_disable_mc_addr_filtering(struct hdd_adapter *adapter,
-		enum pmo_offload_trigger trigger)
+				   enum pmo_offload_trigger trigger)
 {
 	struct hdd_context *hdd_ctx = WLAN_HDD_GET_CTX(adapter);
-	QDF_STATUS status = QDF_STATUS_SUCCESS;
-	struct wlan_objmgr_psoc *psoc = hdd_ctx->hdd_psoc;
+	QDF_STATUS status;
 
 	hdd_enter();
+
 	if (wlan_hdd_validate_context(hdd_ctx))
 		goto out;
 
-	status = pmo_ucfg_disable_mc_addr_filtering_in_fwr(psoc,
-				adapter->session_id, trigger);
-	if (status != QDF_STATUS_SUCCESS)
-		hdd_info("failed to disable mc list status %d", status);
+	if (!hdd_adapter_is_connected_sta(adapter))
+		goto out;
+
+	status = pmo_ucfg_disable_mc_addr_filtering_in_fwr(hdd_ctx->hdd_psoc,
+							   adapter->session_id,
+							   trigger);
+	if (QDF_IS_STATUS_ERROR(status))
+		hdd_err("failed to disable mc list; status:%d", status);
 
 out:
 	hdd_exit();
@@ -972,23 +980,28 @@ int hdd_cache_mc_addr_list(struct pmo_mc_addr_list_params *mc_list_config)
 }
 
 void hdd_disable_and_flush_mc_addr_list(struct hdd_adapter *adapter,
-	enum pmo_offload_trigger trigger)
+					enum pmo_offload_trigger trigger)
 {
 	struct hdd_context *hdd_ctx = WLAN_HDD_GET_CTX(adapter);
-	struct wlan_objmgr_psoc *psoc = hdd_ctx->hdd_psoc;
-	QDF_STATUS status = QDF_STATUS_SUCCESS;
+	QDF_STATUS status;
 
 	hdd_enter();
-	/* disable mc list first */
-	status = pmo_ucfg_disable_mc_addr_filtering_in_fwr(psoc,
-			adapter->session_id, trigger);
-	if (status != QDF_STATUS_SUCCESS)
-		hdd_info("fail to disable mc list");
 
-	/* flush mc list */
-	status = pmo_ucfg_flush_mc_addr_list(psoc, adapter->session_id);
-	if (status != QDF_STATUS_SUCCESS)
-		hdd_info("fail to flush mc list status %d", status);
+	if (!hdd_adapter_is_connected_sta(adapter))
+		goto flush_mc_list;
+
+	/* disable mc list first because the mc list is cached in PMO */
+	status = pmo_ucfg_disable_mc_addr_filtering_in_fwr(hdd_ctx->hdd_psoc,
+							   adapter->session_id,
+							   trigger);
+	if (QDF_IS_STATUS_ERROR(status))
+		hdd_err("failed to disable mc list; status:%d", status);
+
+flush_mc_list:
+	status = pmo_ucfg_flush_mc_addr_list(hdd_ctx->hdd_psoc,
+					     adapter->session_id);
+	if (QDF_IS_STATUS_ERROR(status))
+		hdd_err("failed to flush mc list; status:%d", status);
 
 	hdd_exit();