Browse Source

qcacld-3.0: Add support for multiple queues per AC in TX

Add support for multiple queues per access category and
flow steering in TX.

Change-Id: I40385ab300fc2f7ef83a0f052b95e32a25accfb0
CRs-Fixed: 3059758
Yeshwanth Sriram Guntuka 3 years ago
parent
commit
21958305b5

+ 1 - 0
Kbuild

@@ -3671,6 +3671,7 @@ cppflags-$(CONFIG_ENABLE_HAL_REG_WR_HISTORY) += -DCONFIG_ENABLE_HAL_REG_WR_HISTO
 cppflags-$(CONFIG_DP_RX_DESC_COOKIE_INVALIDATE) += -DDP_RX_DESC_COOKIE_INVALIDATE
 cppflags-$(CONFIG_MON_ENABLE_DROP_FOR_MAC) += -DMON_ENABLE_DROP_FOR_MAC
 cppflags-$(CONFIG_LITHIUM) += -DDISABLE_MON_RING_MSI_CFG
+cppflags-$(CONFIG_TX_MULTIQ_PER_AC) += -DTX_MULTIQ_PER_AC
 cppflags-$(CONFIG_PCI_LINK_STATUS_SANITY) += -DPCI_LINK_STATUS_SANITY
 cppflags-$(CONFIG_DDP_MON_RSSI_IN_DBM) += -DDP_MON_RSSI_IN_DBM
 cppflags-$(CONFIG_SYSTEM_PM_CHECK) += -DSYSTEM_PM_CHECK

+ 23 - 3
core/hdd/inc/wlan_hdd_main.h

@@ -158,15 +158,26 @@ struct hdd_apf_context {
 };
 #endif /* FEATURE_WLAN_APF */
 
+#ifdef TX_MULTIQ_PER_AC
+#define TX_GET_QUEUE_IDX(ac, off) (((ac) * TX_QUEUES_PER_AC) + (off))
+#define TX_QUEUES_PER_AC 4
+#else
+#define TX_GET_QUEUE_IDX(ac, off) (ac)
+#define TX_QUEUES_PER_AC 1
+#endif
+
 /** Number of Tx Queues */
 #if defined(QCA_LL_TX_FLOW_CONTROL_V2) || \
 	defined(QCA_HL_NETDEV_FLOW_CONTROL) || \
 	defined(QCA_LL_PDEV_TX_FLOW_CONTROL)
-#define NUM_TX_QUEUES 5
+/* Only one HI_PRIO queue */
+#define NUM_TX_QUEUES (4 * TX_QUEUES_PER_AC + 1)
 #else
-#define NUM_TX_QUEUES 4
+#define NUM_TX_QUEUES (4 * TX_QUEUES_PER_AC)
 #endif
 
+#define NUM_RX_QUEUES 5
+
 /*
  * Number of DPTRACE records to dump when a cfg80211 disconnect with reason
  * WLAN_REASON_DEAUTH_LEAVING DEAUTH is received from user-space.
@@ -579,7 +590,16 @@ struct hdd_tx_rx_stats {
 		__u32    tx_orphaned;
 		__u32    tx_classified_ac[WLAN_MAX_AC];
 		__u32    tx_dropped_ac[WLAN_MAX_AC];
-
+#ifdef TX_MULTIQ_PER_AC
+		/* Neither valid socket nor skb->hash */
+		uint32_t inv_sk_and_skb_hash;
+		/* skb->hash already calculated */
+		uint32_t qselect_existing_skb_hash;
+		/* valid tx queue id in socket */
+		uint32_t qselect_sk_tx_map;
+		/* skb->hash calculated in select queue */
+		uint32_t qselect_skb_hash_calc;
+#endif
 		/* rx stats */
 		__u32 rx_packets;
 		__u32 rx_dropped;

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

@@ -1,5 +1,6 @@
 /*
  * Copyright (c) 2012-2021 The Linux Foundation. All rights reserved.
+ * Copyright (c) 2021 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
@@ -3893,11 +3894,11 @@ struct hdd_adapter *hdd_wlan_create_ap_dev(struct hdd_context *hdd_ctx,
 
 	hdd_debug("iface_name = %s", iface_name);
 
-	dev = alloc_netdev_mq(sizeof(struct hdd_adapter), iface_name,
+	dev = alloc_netdev_mqs(sizeof(struct hdd_adapter), iface_name,
 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 17, 0)) || defined(WITH_BACKPORTS)
-					  name_assign_type,
+			       name_assign_type,
 #endif
-					  ether_setup, NUM_TX_QUEUES);
+			       ether_setup, NUM_TX_QUEUES, NUM_RX_QUEUES);
 
 	if (!dev)
 		return NULL;

+ 2 - 2
core/hdd/src/wlan_hdd_main.c

@@ -5696,14 +5696,14 @@ hdd_alloc_station_adapter(struct hdd_context *hdd_ctx, tSirMacAddr mac_addr,
 	uint8_t latency_level;
 
 	/* cfg80211 initialization and registration */
-	dev = alloc_netdev_mq(sizeof(*adapter), name,
+	dev = alloc_netdev_mqs(sizeof(*adapter), name,
 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 17, 0)) || defined(WITH_BACKPORTS)
 			      name_assign_type,
 #endif
 			      ((cds_get_conparam() == QDF_GLOBAL_MONITOR_MODE ||
 			       wlan_hdd_is_session_type_monitor(session_type)) ?
 			       hdd_mon_mode_ether_setup : ether_setup),
-			      NUM_TX_QUEUES);
+			      NUM_TX_QUEUES, NUM_RX_QUEUES);
 
 	if (!dev) {
 		hdd_err("Failed to allocate new net_device '%s'", name);

+ 34 - 1
core/hdd/src/wlan_hdd_stats.c

@@ -6708,6 +6708,37 @@ int wlan_hdd_get_temperature(struct hdd_adapter *adapter, int *temperature)
 	return 0;
 }
 
+#ifdef TX_MULTIQ_PER_AC
+static inline
+void wlan_hdd_display_tx_multiq_stats(struct hdd_tx_rx_stats *stats)
+{
+	uint32_t total_inv_sk_and_skb_hash = 0;
+	uint32_t total_qselect_existing_skb_hash = 0;
+	uint32_t total_qselect_sk_tx_map = 0;
+	uint32_t total_qselect_skb_hash = 0;
+	uint8_t i;
+
+	for (i = 0; i < NUM_CPUS; i++) {
+		total_inv_sk_and_skb_hash +=
+					  stats->per_cpu[i].inv_sk_and_skb_hash;
+		total_qselect_existing_skb_hash +=
+				    stats->per_cpu[i].qselect_existing_skb_hash;
+		total_qselect_sk_tx_map += stats->per_cpu[i].qselect_sk_tx_map;
+		total_qselect_skb_hash +=
+					stats->per_cpu[i].qselect_skb_hash_calc;
+	}
+
+	hdd_debug("TX_MULTIQ: INV %u skb_hash %u sk_tx_map %u skb_hash_calc %u",
+		  total_inv_sk_and_skb_hash, total_qselect_existing_skb_hash,
+		  total_qselect_sk_tx_map, total_qselect_skb_hash);
+}
+#else
+static inline
+void wlan_hdd_display_tx_multiq_stats(struct hdd_tx_rx_stats *stats)
+{
+}
+#endif
+
 void wlan_hdd_display_txrx_stats(struct hdd_context *ctx)
 {
 	struct hdd_adapter *adapter = NULL, *next_adapter = NULL;
@@ -6731,7 +6762,7 @@ void wlan_hdd_display_txrx_stats(struct hdd_context *ctx)
 		total_tx_orphaned = 0;
 		stats = &adapter->hdd_stats.tx_rx_stats;
 
-		if (adapter->vdev_id == INVAL_VDEV_ID) {
+		if (adapter->vdev_id == WLAN_INVALID_VDEV_ID) {
 			hdd_adapter_dev_put_debug(adapter, dbgid);
 			continue;
 		}
@@ -6764,6 +6795,8 @@ void wlan_hdd_display_txrx_stats(struct hdd_context *ctx)
 			  total_tx_pkt, total_tx_dropped,
 			  total_tx_orphaned);
 
+		wlan_hdd_display_tx_multiq_stats(stats);
+
 		for (i = 0; i < NUM_CPUS; i++) {
 			if (stats->per_cpu[i].rx_packets == 0)
 				continue;

+ 106 - 18
core/hdd/src/wlan_hdd_tx_rx.c

@@ -75,6 +75,57 @@
 #include "wlan_hdd_object_manager.h"
 #include "wlan_hdd_mlo.h"
 
+#ifdef TX_MULTIQ_PER_AC
+#if defined(QCA_LL_TX_FLOW_CONTROL_V2) || defined(QCA_LL_PDEV_TX_FLOW_CONTROL)
+/*
+ * Mapping Linux AC interpretation to SME AC.
+ * Host has 4 queues per access category (4 AC) and 1 high priority queue.
+ * 16 flow-controlled queues for regular traffic and one non-flow
+ * controlled queue for high priority control traffic(EOPOL, DHCP).
+ * The seventeenth queue is mapped to AC_VO to allow for proper prioritization.
+ */
+const uint8_t hdd_qdisc_ac_to_tl_ac[] = {
+	SME_AC_VO,
+	SME_AC_VO,
+	SME_AC_VO,
+	SME_AC_VO,
+	SME_AC_VI,
+	SME_AC_VI,
+	SME_AC_VI,
+	SME_AC_VI,
+	SME_AC_BE,
+	SME_AC_BE,
+	SME_AC_BE,
+	SME_AC_BE,
+	SME_AC_BK,
+	SME_AC_BK,
+	SME_AC_BK,
+	SME_AC_BK,
+	SME_AC_VO,
+};
+
+#else
+const uint8_t hdd_qdisc_ac_to_tl_ac[] = {
+	SME_AC_VO,
+	SME_AC_VO,
+	SME_AC_VO,
+	SME_AC_VO,
+	SME_AC_VI,
+	SME_AC_VI,
+	SME_AC_VI,
+	SME_AC_VI,
+	SME_AC_BE,
+	SME_AC_BE,
+	SME_AC_BE,
+	SME_AC_BE,
+	SME_AC_BK,
+	SME_AC_BK,
+	SME_AC_BK,
+	SME_AC_BK,
+};
+
+#endif
+#else
 #if defined(QCA_LL_TX_FLOW_CONTROL_V2) || defined(QCA_LL_PDEV_TX_FLOW_CONTROL)
 /*
  * Mapping Linux AC interpretation to SME AC.
@@ -98,6 +149,7 @@ const uint8_t hdd_qdisc_ac_to_tl_ac[] = {
 	SME_AC_BK,
 };
 
+#endif
 #endif
 
 #ifdef QCA_HL_NETDEV_FLOW_CONTROL
@@ -2943,10 +2995,18 @@ wlan_hdd_update_queue_history_state(struct net_device *dev,
  */
 static inline void wlan_hdd_stop_non_priority_queue(struct hdd_adapter *adapter)
 {
-	netif_stop_subqueue(adapter->dev, HDD_LINUX_AC_VO);
-	netif_stop_subqueue(adapter->dev, HDD_LINUX_AC_VI);
-	netif_stop_subqueue(adapter->dev, HDD_LINUX_AC_BE);
-	netif_stop_subqueue(adapter->dev, HDD_LINUX_AC_BK);
+	uint8_t i;
+
+	for (i = 0; i < TX_QUEUES_PER_AC; i++) {
+		netif_stop_subqueue(adapter->dev,
+				    TX_GET_QUEUE_IDX(HDD_LINUX_AC_VO, i));
+		netif_stop_subqueue(adapter->dev,
+				    TX_GET_QUEUE_IDX(HDD_LINUX_AC_VI, i));
+		netif_stop_subqueue(adapter->dev,
+				    TX_GET_QUEUE_IDX(HDD_LINUX_AC_BE, i));
+		netif_stop_subqueue(adapter->dev,
+				    TX_GET_QUEUE_IDX(HDD_LINUX_AC_BK, i));
+	}
 }
 
 /**
@@ -2957,10 +3017,36 @@ static inline void wlan_hdd_stop_non_priority_queue(struct hdd_adapter *adapter)
  */
 static inline void wlan_hdd_wake_non_priority_queue(struct hdd_adapter *adapter)
 {
-	netif_wake_subqueue(adapter->dev, HDD_LINUX_AC_VO);
-	netif_wake_subqueue(adapter->dev, HDD_LINUX_AC_VI);
-	netif_wake_subqueue(adapter->dev, HDD_LINUX_AC_BE);
-	netif_wake_subqueue(adapter->dev, HDD_LINUX_AC_BK);
+	uint8_t i;
+
+	for (i = 0; i < TX_QUEUES_PER_AC; i++) {
+		netif_wake_subqueue(adapter->dev,
+				    TX_GET_QUEUE_IDX(HDD_LINUX_AC_VO, i));
+		netif_wake_subqueue(adapter->dev,
+				    TX_GET_QUEUE_IDX(HDD_LINUX_AC_VI, i));
+		netif_wake_subqueue(adapter->dev,
+				    TX_GET_QUEUE_IDX(HDD_LINUX_AC_BE, i));
+		netif_wake_subqueue(adapter->dev,
+				    TX_GET_QUEUE_IDX(HDD_LINUX_AC_BK, i));
+	}
+}
+
+static inline
+void hdd_wake_queues_for_ac(struct net_device *dev, enum hdd_wmm_linuxac ac)
+{
+	uint8_t i;
+
+	for (i = 0; i < TX_QUEUES_PER_AC; i++)
+		netif_wake_subqueue(dev, TX_GET_QUEUE_IDX(ac, i));
+}
+
+static inline
+void hdd_stop_queues_for_ac(struct net_device *dev, enum hdd_wmm_linuxac ac)
+{
+	uint8_t i;
+
+	for (i = 0; i < TX_QUEUES_PER_AC; i++)
+		netif_stop_subqueue(dev, TX_GET_QUEUE_IDX(ac, i));
 }
 
 /**
@@ -3027,14 +3113,16 @@ void wlan_hdd_netif_queue_control(struct hdd_adapter *adapter,
 		spin_lock_bh(&adapter->pause_map_lock);
 		temp_map = adapter->pause_map;
 		adapter->pause_map &= ~(1 << reason);
-		netif_wake_subqueue(adapter->dev, HDD_LINUX_AC_HI_PRIO);
+		netif_wake_subqueue(adapter->dev,
+				    HDD_LINUX_AC_HI_PRIO * TX_QUEUES_PER_AC);
 		wlan_hdd_update_pause_time(adapter, temp_map);
 		spin_unlock_bh(&adapter->pause_map_lock);
 		break;
 
 	case WLAN_NETIF_PRIORITY_QUEUE_OFF:
 		spin_lock_bh(&adapter->pause_map_lock);
-		netif_stop_subqueue(adapter->dev, HDD_LINUX_AC_HI_PRIO);
+		netif_stop_subqueue(adapter->dev,
+				    HDD_LINUX_AC_HI_PRIO * TX_QUEUES_PER_AC);
 		wlan_hdd_update_txq_timestamp(adapter->dev);
 		wlan_hdd_update_unpause_time(adapter);
 		adapter->pause_map |= (1 << reason);
@@ -3043,8 +3131,8 @@ void wlan_hdd_netif_queue_control(struct hdd_adapter *adapter,
 
 	case WLAN_NETIF_BE_BK_QUEUE_OFF:
 		spin_lock_bh(&adapter->pause_map_lock);
-		netif_stop_subqueue(adapter->dev, HDD_LINUX_AC_BK);
-		netif_stop_subqueue(adapter->dev, HDD_LINUX_AC_BE);
+		hdd_stop_queues_for_ac(adapter->dev, HDD_LINUX_AC_BK);
+		hdd_stop_queues_for_ac(adapter->dev, HDD_LINUX_AC_BE);
 		wlan_hdd_update_txq_timestamp(adapter->dev);
 		wlan_hdd_update_unpause_time(adapter);
 		adapter->pause_map |= (1 << reason);
@@ -3053,7 +3141,7 @@ void wlan_hdd_netif_queue_control(struct hdd_adapter *adapter,
 
 	case WLAN_NETIF_VI_QUEUE_OFF:
 		spin_lock_bh(&adapter->pause_map_lock);
-		netif_stop_subqueue(adapter->dev, HDD_LINUX_AC_VI);
+		hdd_stop_queues_for_ac(adapter->dev, HDD_LINUX_AC_VI);
 		wlan_hdd_update_txq_timestamp(adapter->dev);
 		wlan_hdd_update_unpause_time(adapter);
 		adapter->pause_map |= (1 << reason);
@@ -3064,14 +3152,14 @@ void wlan_hdd_netif_queue_control(struct hdd_adapter *adapter,
 		spin_lock_bh(&adapter->pause_map_lock);
 		temp_map = adapter->pause_map;
 		adapter->pause_map &= ~(1 << reason);
-		netif_wake_subqueue(adapter->dev, HDD_LINUX_AC_VI);
+		hdd_wake_queues_for_ac(adapter->dev, HDD_LINUX_AC_VI);
 		wlan_hdd_update_pause_time(adapter, temp_map);
 		spin_unlock_bh(&adapter->pause_map_lock);
 		break;
 
 	case WLAN_NETIF_VO_QUEUE_OFF:
 		spin_lock_bh(&adapter->pause_map_lock);
-		netif_stop_subqueue(adapter->dev, HDD_LINUX_AC_VO);
+		hdd_stop_queues_for_ac(adapter->dev, HDD_LINUX_AC_VO);
 		wlan_hdd_update_txq_timestamp(adapter->dev);
 		wlan_hdd_update_unpause_time(adapter);
 		adapter->pause_map |= (1 << reason);
@@ -3082,7 +3170,7 @@ void wlan_hdd_netif_queue_control(struct hdd_adapter *adapter,
 		spin_lock_bh(&adapter->pause_map_lock);
 		temp_map = adapter->pause_map;
 		adapter->pause_map &= ~(1 << reason);
-		netif_wake_subqueue(adapter->dev, HDD_LINUX_AC_VO);
+		hdd_wake_queues_for_ac(adapter->dev, HDD_LINUX_AC_VO);
 		wlan_hdd_update_pause_time(adapter, temp_map);
 		spin_unlock_bh(&adapter->pause_map_lock);
 		break;
@@ -3264,7 +3352,7 @@ void hdd_send_rps_ind(struct hdd_adapter *adapter)
 	}
 
 	hdd_ctxt = WLAN_HDD_GET_CTX(adapter);
-	rps_data.num_queues = NUM_TX_QUEUES;
+	rps_data.num_queues = NUM_RX_QUEUES;
 
 	hdd_debug("cpu_map_list '%s'", hdd_ctxt->config->cpu_map_list);
 
@@ -3332,7 +3420,7 @@ void hdd_send_rps_disable_ind(struct hdd_adapter *adapter)
 	}
 
 	hdd_ctxt = WLAN_HDD_GET_CTX(adapter);
-	rps_data.num_queues = NUM_TX_QUEUES;
+	rps_data.num_queues = NUM_RX_QUEUES;
 
 	hdd_info("Set cpu_map_list 0");
 

+ 92 - 24
core/hdd/src/wlan_hdd_wmm.c

@@ -141,13 +141,21 @@ config_tspec_policy[QCA_WLAN_VENDOR_ATTR_CONFIG_TSPEC_MAX + 1] = {
 #ifdef QCA_LL_TX_FLOW_CONTROL_V2
 void wlan_hdd_process_peer_unauthorised_pause(struct hdd_adapter *adapter)
 {
-	/* Enable HI_PRIO queue */
-	netif_stop_subqueue(adapter->dev, HDD_LINUX_AC_VO);
-	netif_stop_subqueue(adapter->dev, HDD_LINUX_AC_VI);
-	netif_stop_subqueue(adapter->dev, HDD_LINUX_AC_BE);
-	netif_stop_subqueue(adapter->dev, HDD_LINUX_AC_BK);
-	netif_wake_subqueue(adapter->dev, HDD_LINUX_AC_HI_PRIO);
-
+	uint8_t i;
+
+	netif_wake_subqueue(adapter->dev,
+			    HDD_LINUX_AC_HI_PRIO * TX_QUEUES_PER_AC);
+
+	for (i = 0; i < TX_QUEUES_PER_AC; i++) {
+		netif_stop_subqueue(adapter->dev,
+				    TX_GET_QUEUE_IDX(HDD_LINUX_AC_VO, i));
+		netif_stop_subqueue(adapter->dev,
+				    TX_GET_QUEUE_IDX(HDD_LINUX_AC_VI, i));
+		netif_stop_subqueue(adapter->dev,
+				    TX_GET_QUEUE_IDX(HDD_LINUX_AC_BE, i));
+		netif_stop_subqueue(adapter->dev,
+				    TX_GET_QUEUE_IDX(HDD_LINUX_AC_BK, i));
+	}
 }
 #else
 void wlan_hdd_process_peer_unauthorised_pause(struct hdd_adapter *adapter)
@@ -1928,6 +1936,69 @@ void hdd_wmm_classify_pkt(struct hdd_adapter *adapter,
 #endif /* HDD_WMM_DEBUG */
 }
 
+#ifdef TX_MULTIQ_PER_AC
+/**
+ * hdd_get_tx_queue_for_ac() - Get the netdev tx queue index
+ *  based on access category
+ * @adapter: adapter upon which the packet is being transmitted
+ * @skb: pointer to network buffer
+ * @ac: access category
+ *
+ * Return: tx queue index
+ */
+static
+uint16_t hdd_get_tx_queue_for_ac(struct hdd_adapter *adapter,
+				 struct sk_buff *skb, uint16_t ac)
+{
+	struct sock *sk = skb->sk;
+	int new_index;
+	int cpu = smp_processor_id();
+	struct hdd_tx_rx_stats *stats = &adapter->hdd_stats.tx_rx_stats;
+
+	if (qdf_unlikely(ac == HDD_LINUX_AC_HI_PRIO))
+		return TX_GET_QUEUE_IDX(HDD_LINUX_AC_HI_PRIO, 0);
+
+	if (!sk) {
+		/*
+		 * Neither valid socket nor skb_hash so default to the
+		 * first queue for the access category.
+		 */
+		if (qdf_unlikely(!skb->sw_hash && !skb->l4_hash)) {
+			++stats->per_cpu[cpu].inv_sk_and_skb_hash;
+
+			return TX_GET_QUEUE_IDX(ac, 0);
+		}
+		++stats->per_cpu[cpu].qselect_existing_skb_hash;
+
+		return TX_GET_QUEUE_IDX(ac,
+					reciprocal_scale(skb->hash,
+							 TX_QUEUES_PER_AC));
+	}
+
+	if (sk->sk_tx_queue_mapping != NO_QUEUE_MAPPING &&
+	    sk->sk_tx_queue_mapping < NUM_TX_QUEUES) {
+		++stats->per_cpu[cpu].qselect_sk_tx_map;
+		return sk->sk_tx_queue_mapping;
+	}
+
+	++stats->per_cpu[cpu].qselect_skb_hash_calc;
+	new_index = TX_GET_QUEUE_IDX(ac,
+				     reciprocal_scale(skb_get_hash(skb),
+						      TX_QUEUES_PER_AC));
+
+	if (sk_fullsock(sk) && rcu_access_pointer(sk->sk_dst_cache))
+		sk_tx_queue_set(sk, new_index);
+
+	return new_index;
+}
+#else
+static inline
+uint16_t hdd_get_tx_queue_for_ac(struct hdd_adapter *adapter,
+				 struct sk_buff *skb, uint16_t ac) {
+	return ac;
+}
+#endif
+
 /**
  * __hdd_get_queue_index() - get queue index
  * @up: user priority
@@ -1989,33 +2060,30 @@ static uint16_t hdd_wmm_select_queue(struct net_device *dev,
 	status = wlan_hdd_validate_context(hdd_ctx);
 	if (status != 0) {
 		skb->priority = SME_QOS_WMM_UP_BE;
-		return HDD_LINUX_AC_BE;
+		return TX_GET_QUEUE_IDX(HDD_LINUX_AC_BE, 0);
 	}
 
 	/* Get the user priority from IP header */
 	hdd_wmm_classify_pkt(adapter, skb, &up, &is_crtical);
-	spin_lock_bh(&adapter->pause_map_lock);
-	if ((adapter->pause_map & (1 <<  WLAN_DATA_FLOW_CONTROL)) &&
-	   !(adapter->pause_map & (1 <<  WLAN_DATA_FLOW_CONTROL_PRIORITY))) {
-		if (qdf_nbuf_is_ipv4_arp_pkt(skb))
+
+	if (qdf_nbuf_is_ipv4_arp_pkt(skb)) {
+		is_crtical = true;
+	} else if (qdf_nbuf_is_icmpv6_pkt(skb)) {
+		proto_subtype = qdf_nbuf_get_icmpv6_subtype(skb);
+		switch (proto_subtype) {
+		case QDF_PROTO_ICMPV6_NA:
+		case QDF_PROTO_ICMPV6_NS:
 			is_crtical = true;
-		else if (qdf_nbuf_is_icmpv6_pkt(skb)) {
-			proto_subtype = qdf_nbuf_get_icmpv6_subtype(skb);
-			switch (proto_subtype) {
-			case QDF_PROTO_ICMPV6_NA:
-			case QDF_PROTO_ICMPV6_NS:
-				is_crtical = true;
-				break;
-			default:
-				break;
-			}
+			break;
+		default:
+			break;
 		}
 	}
-	spin_unlock_bh(&adapter->pause_map_lock);
+
 	skb->priority = up;
 	index = hdd_get_queue_index(skb->priority, is_crtical);
 
-	return index;
+	return hdd_get_tx_queue_for_ac(adapter, skb, index);
 }
 
 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(5, 4, 0))