qcacld-3.0: Do RX packet aggregation for every 16th packet

Do RX packet aggregation for every 16th packet except the ICMP packets,
if the platform is not SMP platform. This change will contribute to improve
standalone SAP/STA RX TPUT when IPA uC offload is enabled by reducing
CPU utilization.

And this change is progagated from CLD2.0 driver with below commits:

bfaad0cb3b0f77d1940eb1d782bd8d125c557bbc
5d960eac83008cad60ff3e7abe1bbebb00b53cf6
c7d2405d7e8e4ba3a5eecbbaa177f4895036a4eb

Change-Id: I256e65ec2399b9b24eec4ccca7fdd662e326838f
CRs-Fixed: 2075793
diff --git a/core/hdd/src/wlan_hdd_ipa.c b/core/hdd/src/wlan_hdd_ipa.c
index 78d7aa8..e513a06 100644
--- a/core/hdd/src/wlan_hdd_ipa.c
+++ b/core/hdd/src/wlan_hdd_ipa.c
@@ -91,6 +91,8 @@
 
 #define HDD_IPA_MAX_PENDING_EVENT_COUNT    20
 
+#define IPA_WLAN_RX_SOFTIRQ_THRESH 16
+
 enum hdd_ipa_uc_op_code {
 	HDD_IPA_UC_OPCODE_TX_SUSPEND = 0,
 	HDD_IPA_UC_OPCODE_TX_RESUME = 1,
@@ -4076,6 +4078,40 @@
 			    "RM CONS resource delete failed %d", ret);
 }
 
+#ifdef QCA_CONFIG_SMP
+static int hdd_ipa_aggregated_rx_ind(qdf_nbuf_t skb)
+{
+	return netif_rx_ni(skb);
+}
+#else
+static int hdd_ipa_aggregated_rx_ind(qdf_nbuf_t skb)
+{
+	struct iphdr *ip_h;
+	static atomic_t softirq_mitigation_cntr =
+		ATOMIC_INIT(IPA_WLAN_RX_SOFTIRQ_THRESH);
+	int result;
+
+	ip_h = (struct iphdr *)(skb->data);
+	if ((skb->protocol == htons(ETH_P_IP)) &&
+		(ip_h->protocol == IPPROTO_ICMP)) {
+		result = netif_rx_ni(skb);
+	} else {
+		/* Call netif_rx_ni for every IPA_WLAN_RX_SOFTIRQ_THRESH packets
+		 * to avoid excessive softirq's.
+		 */
+		if (atomic_dec_and_test(&softirq_mitigation_cntr)) {
+			result = netif_rx_ni(skb);
+			atomic_set(&softirq_mitigation_cntr,
+					IPA_WLAN_RX_SOFTIRQ_THRESH);
+		} else {
+			result = netif_rx(skb);
+		}
+	}
+
+	return result;
+}
+#endif
+
 /**
  * hdd_ipa_send_skb_to_network() - Send skb to kernel
  * @skb: network buffer
@@ -4089,6 +4125,7 @@
 static void hdd_ipa_send_skb_to_network(qdf_nbuf_t skb,
 	hdd_adapter_t *adapter)
 {
+	int result;
 	struct hdd_ipa_priv *hdd_ipa = ghdd_ipa;
 	unsigned int cpu_index;
 
@@ -4114,7 +4151,8 @@
 	cpu_index = wlan_hdd_get_cpu();
 
 	++adapter->hdd_stats.hddTxRxStats.rxPackets[cpu_index];
-	if (netif_rx_ni(skb) == NET_RX_SUCCESS)
+	result = hdd_ipa_aggregated_rx_ind(skb);
+	if (result == NET_RX_SUCCESS)
 		++adapter->hdd_stats.hddTxRxStats.rxDelivered[cpu_index];
 	else
 		++adapter->hdd_stats.hddTxRxStats.rxRefused[cpu_index];