Przeglądaj źródła

qcacld-3.0: Move TC based dynamic GRO logic to DP component

Move TC based dynamic GRO logic to DP component.

Change-Id: I3c6658e8f19a71e548c77ff6fd637148925008d7
CRs-Fixed: 3219451
Yeshwanth Sriram Guntuka 2 lat temu
rodzic
commit
6529648bf3

+ 3 - 2
components/dp/core/inc/wlan_dp_priv.h

@@ -321,7 +321,7 @@ struct wlan_dp_intf {
 	qdf_atomic_t num_active_task;
 	uint32_t sap_tx_block_mask;
 
-	uint8_t gro_disallowed[DP_MAX_RX_THREADS];
+	qdf_atomic_t gro_disallowed;
 	uint8_t gro_flushed[DP_MAX_RX_THREADS];
 
 	bool runtime_disable_rx_thread;
@@ -430,7 +430,8 @@ struct wlan_dp_psoc_context {
 	struct {
 		qdf_atomic_t rx_aggregation;
 		uint8_t gro_force_flush[DP_MAX_RX_THREADS];
-		bool force_gro_enable;
+		bool tc_based_dyn_gro;
+		uint32_t tc_ingress_prio;
 	}
 	dp_agg_param;
 

+ 45 - 0
components/dp/core/src/wlan_dp_bus_bandwidth.c

@@ -1650,6 +1650,48 @@ static void dp_pld_request_bus_bandwidth(struct wlan_dp_psoc_context *dp_ctx,
 	}
 }
 
+#ifdef WLAN_FEATURE_DYNAMIC_RX_AGGREGATION
+/**
+ * dp_rx_check_qdisc_for_intf() - Check if any ingress qdisc is configured
+ *  for given adapter
+ * @dp_intf: pointer to DP interface context
+ *
+ * The function checks if ingress qdisc is registered for a given
+ * net device.
+ *
+ * Return: None
+ */
+static void
+dp_rx_check_qdisc_for_intf(struct wlan_dp_intf *dp_intf)
+{
+	struct wlan_dp_psoc_callbacks *dp_ops;
+	QDF_STATUS status;
+
+	dp_ops = &dp_intf->dp_ctx->dp_ops;
+	status = dp_ops->dp_rx_check_qdisc_configured(dp_intf->dev,
+				 dp_intf->dp_ctx->dp_agg_param.tc_ingress_prio);
+	if (QDF_IS_STATUS_SUCCESS(status)) {
+		if (qdf_likely(qdf_atomic_read(&dp_intf->gro_disallowed)))
+			return;
+
+		dp_debug("ingress qdisc/filter configured disable GRO");
+		qdf_atomic_set(&dp_intf->gro_disallowed, 1);
+
+		return;
+	} else if (status == QDF_STATUS_E_NOSUPPORT) {
+		if (qdf_unlikely(qdf_atomic_read(&dp_intf->gro_disallowed))) {
+			dp_debug("ingress qdisc/filter removed enable GRO");
+			qdf_atomic_set(&dp_intf->gro_disallowed, 0);
+		}
+	}
+}
+#else
+static void
+dp_rx_check_qdisc_for_intf(struct wlan_dp_intf *dp_intf)
+{
+}
+#endif
+
 /**
  * __dp_bus_bw_work_handler() - Bus bandwidth work handler
  * @dp_ctx: handle to DP context
@@ -1709,6 +1751,9 @@ static void __dp_bus_bw_work_handler(struct wlan_dp_psoc_context *dp_ctx)
 			continue;
 		}
 
+		if (dp_ctx->dp_agg_param.tc_based_dyn_gro)
+			dp_rx_check_qdisc_for_intf(dp_intf);
+
 		tx_packets += DP_BW_GET_DIFF(
 			QDF_NET_DEV_STATS_TX_PKTS(&dp_intf->stats),
 			dp_intf->prev_tx_packets);

+ 22 - 58
components/dp/core/src/wlan_dp_txrx.c

@@ -961,11 +961,13 @@ static QDF_STATUS dp_gro_rx_bh_disable(struct wlan_dp_intf *dp_intf,
 	uint32_t rx_aggregation;
 	uint8_t rx_ctx_id = QDF_NBUF_CB_RX_CTX_ID(nbuf);
 	uint8_t low_tput_force_flush = 0;
+	int32_t gro_disallowed;
 
 	rx_aggregation = qdf_atomic_read(&dp_ctx->dp_agg_param.rx_aggregation);
+	gro_disallowed = qdf_atomic_read(&dp_intf->gro_disallowed);
 
 	if (dp_get_current_throughput_level(dp_ctx) == PLD_BUS_WIDTH_IDLE ||
-	    !rx_aggregation || dp_intf->gro_disallowed[rx_ctx_id]) {
+	    !rx_aggregation || gro_disallowed) {
 		status = dp_ctx->dp_ops.dp_rx_napi_gro_flush(napi_to_use, nbuf,
 						   &low_tput_force_flush);
 		if (!low_tput_force_flush)
@@ -973,7 +975,7 @@ static QDF_STATUS dp_gro_rx_bh_disable(struct wlan_dp_intf *dp_intf,
 					rx_gro_low_tput_flush++;
 		if (!rx_aggregation)
 			dp_ctx->dp_agg_param.gro_force_flush[rx_ctx_id] = 1;
-		if (dp_intf->gro_disallowed[rx_ctx_id])
+		if (gro_disallowed)
 			dp_intf->gro_flushed[rx_ctx_id] = 1;
 	} else {
 		status = dp_ctx->dp_ops.dp_rx_napi_gro_receive(napi_to_use,
@@ -1400,58 +1402,6 @@ void wlan_dp_set_fisa_disallowed_for_vdev(ol_txrx_soc_handle soc,
 #endif
 
 #ifdef WLAN_FEATURE_DYNAMIC_RX_AGGREGATION
-/**
- * dp_rx_check_qdisc_for_intf() - Check if any ingress qdisc is configured
- *  for given adapter
- * @dp_intf: pointer to DP interface context
- * @rx_ctx_id: Rx context id
- *
- * The function checks if ingress qdisc is registered for a given
- * net device.
- *
- * Return: None
- */
-static void
-dp_rx_check_qdisc_for_intf(struct wlan_dp_intf *dp_intf,
-			   uint8_t rx_ctx_id)
-{
-	ol_txrx_soc_handle soc = cds_get_context(QDF_MODULE_ID_SOC);
-	struct wlan_dp_psoc_callbacks *dp_ops;
-	QDF_STATUS status;
-
-	/*
-	 * Restrict the qdisc based dynamic GRO enable/disable to
-	 * standalone STA mode only. Reset the configuration for
-	 * any other device mode or concurrency.
-	 */
-	if (dp_intf->device_mode != QDF_STA_MODE ||
-	    (qdf_atomic_read(&dp_intf->dp_ctx->rx_skip_qdisc_chk_conc)))
-		goto reset_wl;
-
-	dp_ops = &dp_intf->dp_ctx->dp_ops;
-	status = dp_ops->dp_rx_check_qdisc_configured(dp_intf->dev,
-						      rx_ctx_id);
-	if (QDF_IS_STATUS_SUCCESS(status)) {
-		if (qdf_likely(dp_intf->gro_disallowed[rx_ctx_id]))
-			return;
-
-		dp_debug("ingress qdisc/filter configured disable GRO");
-		dp_intf->gro_disallowed[rx_ctx_id] = 1;
-		wlan_dp_set_fisa_disallowed_for_vdev(soc, dp_intf->intf_id,
-						     rx_ctx_id, 1);
-		return;
-	}
-
-reset_wl:
-	if (qdf_unlikely(dp_intf->gro_disallowed[rx_ctx_id])) {
-		dp_debug("ingress qdisc/filter removed enable GRO");
-		wlan_dp_set_fisa_disallowed_for_vdev(soc, dp_intf->intf_id,
-						     rx_ctx_id, 0);
-		dp_intf->gro_disallowed[rx_ctx_id] = 0;
-		dp_intf->gro_flushed[rx_ctx_id] = 0;
-	}
-}
-
 QDF_STATUS wlan_dp_rx_deliver_to_stack(struct wlan_dp_intf *dp_intf,
 				       qdf_nbuf_t nbuf)
 {
@@ -1461,15 +1411,29 @@ QDF_STATUS wlan_dp_rx_deliver_to_stack(struct wlan_dp_intf *dp_intf,
 	bool nbuf_receive_offload_ok = false;
 	enum dp_nbuf_push_type push_type;
 	uint8_t rx_ctx_id = QDF_NBUF_CB_RX_CTX_ID(nbuf);
-
-	if (!dp_ctx->dp_agg_param.force_gro_enable)
-		/* rx_ctx_id is already verified for out-of-range */
-		dp_rx_check_qdisc_for_intf(dp_intf, rx_ctx_id);
+	ol_txrx_soc_handle soc = cds_get_context(QDF_MODULE_ID_SOC);
+	int32_t gro_disallowed;
 
 	if (QDF_NBUF_CB_RX_TCP_PROTO(nbuf) &&
 	    !QDF_NBUF_CB_RX_PEER_CACHED_FRM(nbuf))
 		nbuf_receive_offload_ok = true;
 
+	gro_disallowed = qdf_atomic_read(&dp_intf->gro_disallowed);
+	if (gro_disallowed == 0 &&
+	    dp_intf->gro_flushed[rx_ctx_id] != 0) {
+		if (qdf_likely(soc))
+			wlan_dp_set_fisa_disallowed_for_vdev(soc,
+							     dp_intf->intf_id,
+							     rx_ctx_id, 0);
+		dp_intf->gro_flushed[rx_ctx_id] = 0;
+	} else if (gro_disallowed &&
+		   dp_intf->gro_flushed[rx_ctx_id] == 0) {
+		if (qdf_likely(soc))
+			wlan_dp_set_fisa_disallowed_for_vdev(soc,
+							     dp_intf->intf_id,
+							     rx_ctx_id, 1);
+	}
+
 	if (nbuf_receive_offload_ok && dp_ctx->receive_offload_cb &&
 	    !dp_ctx->dp_agg_param.gro_force_flush[rx_ctx_id] &&
 	    !dp_intf->gro_flushed[rx_ctx_id] &&

+ 1 - 1
components/dp/dispatcher/inc/wlan_dp_public_struct.h

@@ -618,7 +618,7 @@ struct wlan_dp_psoc_callbacks {
 	void (*dp_register_rx_offld_flush_cb)(enum dp_rx_offld_flush_cb type);
 
 	QDF_STATUS (*dp_rx_check_qdisc_configured)(qdf_netdev_t dev,
-						   uint8_t rx_ctx_id);
+						   uint32_t prio);
 
 	bool (*dp_is_gratuitous_arp_unsolicited_na)(qdf_nbuf_t nbuf);
 

+ 14 - 8
components/dp/dispatcher/inc/wlan_dp_ucfg_api.h

@@ -256,19 +256,16 @@ bool ucfg_dp_is_ol_enabled(struct wlan_objmgr_psoc *psoc);
 /**
  * ucfg_dp_rx_handle_concurrency() - Handle concurrency setting in DP
  * @psoc: PSOC mapped to DP context
- * @is_wifi3_0_target: true if it is wifi3.0 target
- * @is_concurrency: Is concurrency enabled/disabled
+ * @disable: true/false to disable/enable the Rx offload
  *
  * Return: None
  */
 void ucfg_dp_rx_handle_concurrency(struct wlan_objmgr_psoc *psoc,
-				   bool is_wifi3_0_target,
-				   bool is_concurrency);
+				   bool disable);
 #else
 static inline
 void ucfg_dp_rx_handle_concurrency(struct wlan_objmgr_psoc *psoc,
-				   bool is_wifi3_0_target,
-				   bool is_concurrency) { }
+				   bool disable) { }
 #endif
 
 /**
@@ -1124,13 +1121,13 @@ void ucfg_dp_set_rx_aggregation_val(struct wlan_objmgr_psoc *psoc,
 				    uint32_t value);
 
 /**
- * ucfg_dp_set_force_gro_enable() - Set force gro enable
+ * ucfg_dp_set_tc_based_dyn_gro() - Set tc based dynamic gro
  * @psoc: psoc handle
  * @value : value to be set
  *
  * Return: None
  */
-void ucfg_dp_set_force_gro_enable(struct wlan_objmgr_psoc *psoc, bool value);
+void ucfg_dp_set_tc_based_dyn_gro(struct wlan_objmgr_psoc *psoc, bool value);
 
 /**
  * ucfg_dp_runtime_disable_rx_thread() - Disable rx thread
@@ -1149,4 +1146,13 @@ void ucfg_dp_runtime_disable_rx_thread(struct wlan_objmgr_vdev *vdev,
  * Return: true if NAPI enabled
  */
 bool ucfg_dp_get_napi_enabled(struct wlan_objmgr_psoc *psoc);
+
+/**
+ * ucfg_dp_set_tc_ingress_prio() - Set tc ingress priority
+ * @psoc: psoc handle mapped to DP context
+ * @value: value to be set
+ *
+ * Return: None
+ */
+void ucfg_dp_set_tc_ingress_prio(struct wlan_objmgr_psoc *psoc, uint32_t value);
 #endif /* _WLAN_DP_UCFG_API_H_ */

+ 16 - 21
components/dp/dispatcher/src/wlan_dp_ucfg_api.c

@@ -91,6 +91,7 @@ ucfg_dp_create_intf(struct wlan_objmgr_psoc *psoc,
 	dp_nud_init_tracking(dp_intf);
 	dp_mic_init_work(dp_intf);
 	qdf_atomic_init(&dp_ctx->num_latency_critical_clients);
+	qdf_atomic_init(&dp_intf->gro_disallowed);
 
 	return QDF_STATUS_SUCCESS;
 }
@@ -678,8 +679,7 @@ bool ucfg_dp_is_ol_enabled(struct wlan_objmgr_psoc *psoc)
 
 #ifdef RECEIVE_OFFLOAD
 void ucfg_dp_rx_handle_concurrency(struct wlan_objmgr_psoc *psoc,
-				   bool is_wifi3_0_target,
-				   bool is_concurrency)
+				   bool disable)
 {
 	struct wlan_dp_psoc_context *dp_ctx;
 
@@ -689,23 +689,7 @@ void ucfg_dp_rx_handle_concurrency(struct wlan_objmgr_psoc *psoc,
 		return;
 	}
 
-	if (is_wifi3_0_target) {
-		/*
-		 * Donot disable rx offload on concurrency for lithium and
-		 * beryllium based targets
-		 */
-		if (is_concurrency)
-			qdf_atomic_set(&dp_ctx->rx_skip_qdisc_chk_conc, 1);
-		else
-			qdf_atomic_set(&dp_ctx->rx_skip_qdisc_chk_conc, 0);
-
-		return;
-	}
-
-	if (!dp_ctx->ol_enable)
-		return;
-
-	if (is_concurrency) {
+	if (disable) {
 		if (DP_BUS_BW_CFG(dp_ctx->dp_cfg.enable_tcp_delack)) {
 			struct wlan_rx_tp_data rx_tp_data;
 
@@ -2048,7 +2032,7 @@ void ucfg_dp_set_rx_aggregation_val(struct wlan_objmgr_psoc *psoc,
 	qdf_atomic_set(&dp_ctx->dp_agg_param.rx_aggregation, !!value);
 }
 
-void ucfg_dp_set_force_gro_enable(struct wlan_objmgr_psoc *psoc, bool value)
+void ucfg_dp_set_tc_based_dyn_gro(struct wlan_objmgr_psoc *psoc, bool value)
 {
 	struct wlan_dp_psoc_context *dp_ctx = dp_psoc_get_priv(psoc);
 
@@ -2056,7 +2040,7 @@ void ucfg_dp_set_force_gro_enable(struct wlan_objmgr_psoc *psoc, bool value)
 		dp_err("DP ctx is NULL");
 		return;
 	}
-	dp_ctx->dp_agg_param.force_gro_enable = value;
+	dp_ctx->dp_agg_param.tc_based_dyn_gro = value;
 }
 
 void ucfg_dp_runtime_disable_rx_thread(struct wlan_objmgr_vdev *vdev,
@@ -2081,3 +2065,14 @@ bool ucfg_dp_get_napi_enabled(struct wlan_objmgr_psoc *psoc)
 	}
 	return dp_ctx->napi_enable;
 }
+
+void ucfg_dp_set_tc_ingress_prio(struct wlan_objmgr_psoc *psoc, uint32_t value)
+{
+	struct wlan_dp_psoc_context *dp_ctx = dp_psoc_get_priv(psoc);
+
+	if (!dp_ctx) {
+		dp_err("DP ctx is NULL");
+		return;
+	}
+	dp_ctx->dp_agg_param.tc_ingress_prio = value;
+}

+ 6 - 2
components/target_if/dp/src/target_if_dp_comp.c

@@ -320,6 +320,7 @@ target_if_dp_send_dhcp_ind(uint16_t vdev_id,
 	struct wmi_unified *wmi_handle;
 	struct wlan_objmgr_psoc *psoc;
 	wmi_peer_set_param_cmd_fixed_param peer_set_param_fp = {0};
+	QDF_STATUS status;
 
 	psoc = wlan_objmgr_get_psoc_by_id(0, WLAN_PSOC_TARGET_IF_ID);
 	if (!psoc) {
@@ -345,8 +346,11 @@ target_if_dp_send_dhcp_ind(uint16_t vdev_id,
 	WMI_CHAR_ARRAY_TO_MAC_ADDR(dhcp_ind->peer_mac_addr.bytes,
 				   &peer_set_param_fp.peer_macaddr);
 
-	return wmi_unified_process_dhcp_ind(wmi_handle,
-						&peer_set_param_fp);
+	status = wmi_unified_process_dhcp_ind(wmi_handle,
+					      &peer_set_param_fp);
+	wlan_objmgr_psoc_release_ref(psoc, WLAN_PSOC_TARGET_IF_ID);
+
+	return status;
 }
 
 void target_if_dp_register_tx_ops(struct wlan_dp_psoc_sb_ops *sb_ops)

+ 14 - 0
os_if/dp/inc/os_if_dp.h

@@ -26,6 +26,20 @@
 #include "wlan_dp_public_struct.h"
 #include <wlan_cfg80211.h>
 
+#ifdef WLAN_FEATURE_DYNAMIC_RX_AGGREGATION
+/**
+ * enum qdisc_filter_status - QDISC filter status
+ * @QDISC_FILTER_RTNL_LOCK_FAIL: rtnl lock acquire failed
+ * @QDISC_FILTER_PRIO_MATCH: qdisc filter with priority match
+ * @QDISC_FILTER_PRIO_MISMATCH: no filter match with configured priority
+ */
+enum qdisc_filter_status {
+	QDISC_FILTER_RTNL_LOCK_FAIL,
+	QDISC_FILTER_PRIO_MATCH,
+	QDISC_FILTER_PRIO_MISMATCH,
+};
+#endif
+
 /**
  * osif_dp_classify_pkt() - classify packet
  * @skb - sk buff

+ 95 - 22
os_if/dp/src/os_if_dp_txrx.c

@@ -299,36 +299,94 @@ static void osif_dp_qdf_lro_flush(void *data)
 #endif
 
 #ifdef WLAN_FEATURE_DYNAMIC_RX_AGGREGATION
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(5, 4, 0))
+static enum qdisc_filter_status
+__osif_check_for_prio_filter_in_clsact_qdisc(struct tcf_block *block,
+					     uint32_t prio)
+{
+	struct tcf_chain *chain;
+	struct tcf_proto *tp;
+	struct tcf_proto *tp_next;
+	enum qdisc_filter_status ret = QDISC_FILTER_PRIO_MISMATCH;
+
+	if (!rtnl_trylock())
+		return QDISC_FILTER_RTNL_LOCK_FAIL;
+
+	mutex_lock(&block->lock);
+	list_for_each_entry(chain, &block->chain_list, list) {
+		mutex_lock(&chain->filter_chain_lock);
+		tp = tcf_chain_dereference(chain->filter_chain, chain);
+		while (tp) {
+			tp_next = rcu_dereference_protected(tp->next, 1);
+			if (tp->prio == (prio << 16)) {
+				ret = QDISC_FILTER_PRIO_MATCH;
+				break;
+			}
+			tp = tp_next;
+		}
+		mutex_unlock(&chain->filter_chain_lock);
+
+		if (ret == QDISC_FILTER_PRIO_MATCH)
+			break;
+	}
+	mutex_unlock(&block->lock);
+	rtnl_unlock();
+
+	return ret;
+}
+#else
+static enum qdisc_filter_status
+__osif_check_for_prio_filter_in_clsact_qdisc(struct tcf_block *block,
+					     uint32_t prio)
+{
+	struct tcf_chain *chain;
+	struct tcf_proto *tp;
+	enum qdisc_filter_status ret = QDISC_FILTER_PRIO_MISMATCH;
+
+	if (!rtnl_trylock())
+		return QDISC_FILTER_RTNL_LOCK_FAIL;
+
+	list_for_each_entry(chain, &block->chain_list, list) {
+		for (tp = rtnl_dereference(chain->filter_chain); tp;
+		     tp = rtnl_dereference(tp->next)) {
+			if (tp->prio == (prio << 16))
+				ret = QDISC_FILTER_PRIO_MATCH;
+		}
+	}
+	rtnl_unlock();
+
+	return ret;
+}
+#endif
+
 /**
- * osif_dp_is_chain_list_non_empty_for_clsact_qdisc() - Check if chain_list in
- *  ingress block is non-empty for a clsact qdisc.
+ * osif_check_for_prio_filter_in_clsact_qdisc() - Check if priority 3 filter
+ *  is configured in the ingress clsact qdisc
  * @qdisc: pointer to clsact qdisc
  *
- * Return: true if chain_list is not empty else false
+ * Return: qdisc filter status
  */
-static bool
-osif_dp_is_chain_list_non_empty_for_clsact_qdisc(struct Qdisc *qdisc)
+static enum qdisc_filter_status
+osif_check_for_prio_filter_in_clsact_qdisc(struct Qdisc *qdisc, uint32_t prio)
 {
 	const struct Qdisc_class_ops *cops;
 	struct tcf_block *ingress_block;
 
 	cops = qdisc->ops->cl_ops;
 	if (qdf_unlikely(!cops || !cops->tcf_block))
-		return false;
+		return QDISC_FILTER_PRIO_MISMATCH;
 
 	ingress_block = cops->tcf_block(qdisc, TC_H_MIN_INGRESS, NULL);
 	if (qdf_unlikely(!ingress_block))
-		return false;
+		return QDISC_FILTER_PRIO_MISMATCH;
 
-	if (list_empty(&ingress_block->chain_list))
-		return false;
-	else
-		return true;
+	return __osif_check_for_prio_filter_in_clsact_qdisc(ingress_block,
+							    prio);
 }
 
 /**
- * osif_dp_rx_check_qdisc_for_configured() - Check if any ingress qdisc configured
- *  for given adapter
+ * osif_dp_rx_check_qdisc_for_configured() - Check if any ingress qdisc
+ * configured for given adapter
  * @dp_intf: pointer to DP interface context
  * @rx_ctx_id: Rx context id
  *
@@ -338,11 +396,13 @@ osif_dp_is_chain_list_non_empty_for_clsact_qdisc(struct Qdisc *qdisc)
  * Return: None
  */
 static QDF_STATUS
-osif_dp_rx_check_qdisc_configured(qdf_netdev_t ndev, uint8_t rx_ctx_id)
+osif_dp_rx_check_qdisc_configured(qdf_netdev_t ndev, uint32_t prio)
 {
 	struct netdev_queue *ingress_q;
 	struct Qdisc *ingress_qdisc;
 	struct net_device *dev = (struct net_device *)ndev;
+	bool disable_gro = false;
+	enum qdisc_filter_status status;
 
 	if (!dev->ingress_queue)
 		goto reset_wl;
@@ -357,14 +417,27 @@ osif_dp_rx_check_qdisc_configured(qdf_netdev_t ndev, uint8_t rx_ctx_id)
 	if (qdf_unlikely(!ingress_qdisc))
 		goto reset;
 
-	if (!(qdf_str_eq(ingress_qdisc->ops->id, "ingress") ||
-	      (qdf_str_eq(ingress_qdisc->ops->id, "clsact") &&
-	       osif_dp_is_chain_list_non_empty_for_clsact_qdisc(ingress_qdisc))))
-		goto reset;
-
-	rcu_read_unlock();
+	if (qdf_str_eq(ingress_qdisc->ops->id, "ingress")) {
+		disable_gro = true;
+	} else if (qdf_str_eq(ingress_qdisc->ops->id, "clsact")) {
+		status = osif_check_for_prio_filter_in_clsact_qdisc(
+								  ingress_qdisc,
+								  prio);
+
+		if (status == QDISC_FILTER_RTNL_LOCK_FAIL) {
+			rcu_read_unlock();
+			return QDF_STATUS_E_AGAIN;
+		} else if (status == QDISC_FILTER_PRIO_MISMATCH) {
+			goto reset;
+		}
+
+		disable_gro = true;
+	}
 
-	return 0;
+	if (disable_gro) {
+		rcu_read_unlock();
+		return QDF_STATUS_SUCCESS;
+	}
 
 reset:
 	rcu_read_unlock();
@@ -375,7 +448,7 @@ reset_wl:
 
 #else
 static QDF_STATUS
-osif_dp_rx_check_qdisc_configured(qdf_netdev_t ndev, uint8_t rx_ctx_id)
+osif_dp_rx_check_qdisc_configured(qdf_netdev_t ndev, uint32_t prio)
 {
 	return QDF_STATUS_E_NOSUPPORT;
 }