Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit ad2e6515 authored by Yeshwanth Sriram Guntuka's avatar Yeshwanth Sriram Guntuka Committed by Madan Koyyalamudi
Browse files

qcacld-3.0: Dynamically control rx aggregation based on ingress filter

Add support to dynamically control rx aggregation based
on clsact ingress filter addition or deletion. Disable
GRO/FISA when the filter is configured and enable GRO/FISA
back when there is no filter configured.

Change-Id: I462f62edf0acd191b57f40800118567edb2ac82d
CRs-Fixed: 2952276
parent a782a1e2
Loading
Loading
Loading
Loading
+60 −15
Original line number Diff line number Diff line
/*
 * Copyright (c) 2012-2020 The Linux Foundation. All rights reserved.
 * Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved.
 *
 * Permission to use, copy, modify, and/or distribute this software for
 * any purpose with or without fee is hereby granted, provided that the
@@ -2093,6 +2094,55 @@ void hdd_set_fisa_disallowed_for_vdev(ol_txrx_soc_handle soc, uint8_t vdev_id,
#endif

#ifdef WLAN_FEATURE_DYNAMIC_RX_AGGREGATION
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 19, 0))
/**
 * hdd_is_chain_list_non_empty_for_clsact_qdisc() - Check if chain_list in
 *  ingress block is non-empty for a clsact qdisc.
 * @qdisc: pointer to clsact qdisc
 *
 * Return: true if chain_list is not empty else false
 */
static bool
hdd_is_chain_list_non_empty_for_clsact_qdisc(struct Qdisc *qdisc)
{
	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;

	ingress_block = cops->tcf_block(qdisc, TC_H_MIN_INGRESS, NULL);
	if (qdf_unlikely(!ingress_block))
		return false;

	if (list_empty(&ingress_block->chain_list))
		return false;
	else
		return true;
}
#else
static bool
hdd_is_chain_list_non_empty_for_clsact_qdisc(struct Qdisc *qdisc)
{
	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;

	ingress_block = cops->tcf_block(qdisc, TC_H_MIN_INGRESS);
	if (qdf_unlikely(!ingress_block))
		return false;

	if (list_empty(&ingress_block->chain_list))
		return false;
	else
		return true;
}
#endif

/**
 * hdd_rx_check_qdisc_for_adapter() - Check if any ingress qdisc is configured
 *  for given adapter
@@ -2110,39 +2160,34 @@ hdd_rx_check_qdisc_for_adapter(struct hdd_adapter *adapter, uint8_t rx_ctx_id)
	ol_txrx_soc_handle soc = cds_get_context(QDF_MODULE_ID_SOC);
	struct netdev_queue *ingress_q;
	struct Qdisc *ingress_qdisc;
	bool is_qdisc_ingress = false;

	if (qdf_unlikely(!soc))
		return;

	/*
	 * This additional ingress_queue NULL check is to avoid
	 * doing RCU lock/unlock in the common scenario where
	 * ingress_queue is not configured by default
	 */
	if (qdf_likely(!adapter->dev->ingress_queue))
	if (!adapter->dev->ingress_queue)
		goto reset_wl;

	rcu_read_lock();
	ingress_q = rcu_dereference(adapter->dev->ingress_queue);

	ingress_q = rcu_dereference(adapter->dev->ingress_queue);
	if (qdf_unlikely(!ingress_q))
		goto reset;

	ingress_qdisc = rcu_dereference(ingress_q->qdisc);
	if (!ingress_qdisc)
	if (qdf_unlikely(!ingress_qdisc))
		goto reset;

	is_qdisc_ingress = qdf_str_eq(ingress_qdisc->ops->id, "ingress");
	if (!is_qdisc_ingress)
	if (!(qdf_str_eq(ingress_qdisc->ops->id, "ingress") ||
	      (qdf_str_eq(ingress_qdisc->ops->id, "clsact") &&
	       hdd_is_chain_list_non_empty_for_clsact_qdisc(ingress_qdisc))))
		goto reset;

	rcu_read_unlock();

	if (adapter->gro_disallowed[rx_ctx_id])
	if (qdf_likely(adapter->gro_disallowed[rx_ctx_id]))
		return;

	hdd_debug("ingress qdisc configured disable GRO");
	hdd_debug("ingress qdisc/filter configured disable GRO");
	adapter->gro_disallowed[rx_ctx_id] = 1;
	hdd_set_fisa_disallowed_for_vdev(soc, adapter->vdev_id, rx_ctx_id, 1);

@@ -2152,8 +2197,8 @@ hdd_rx_check_qdisc_for_adapter(struct hdd_adapter *adapter, uint8_t rx_ctx_id)
	rcu_read_unlock();

reset_wl:
	if (adapter->gro_disallowed[rx_ctx_id]) {
		hdd_debug("ingress qdisc removed enable GRO");
	if (qdf_unlikely(adapter->gro_disallowed[rx_ctx_id])) {
		hdd_debug("ingress qdisc/filter removed enable GRO");
		hdd_set_fisa_disallowed_for_vdev(soc, adapter->vdev_id,
						 rx_ctx_id, 0);
		adapter->gro_disallowed[rx_ctx_id] = 0;