mwifiex: add multi-queue support
authorBing Zhao <bzhao@marvell.com>
Mon, 22 Oct 2012 23:44:53 +0000 (16:44 -0700)
committerGerrit <chrome-bot@google.com>
Fri, 2 Nov 2012 19:11:38 +0000 (12:11 -0700)
This patch adds support for multiple TX queues inside mwifiex
driver. Four different queues according to WMM access categories
are defined for each virtual interface. When a packet is
received from netdev for transmission, tx pending count for
particular queue is incremented and if tx pending count has
reached upper water-mark, this queue is stopped instead of
stopping all queues. Similarly when a packet is successfully
transmitted from device, tx pending count is decremented per
queue and if pending count falls below lower water-mark, queue
operations are again resumed. This ensures that not all
tranmission is blocked if traffic with particular TOS value
suddenly increases.

Also wake all queues when association/IBSS_join happens to
enable traffic on all queues.

Signed-off-by: Avinash Patil <patila@marvell.com>
Signed-off-by: Bing Zhao <bzhao@marvell.com>
BUG=chrome-os-partner:15536
TEST=pass pre-WiFi Cert. test case 5.2.30

Change-Id: I7b11c6f3f90943f09deaa7ef37b2975982bc02d3
Reviewed-on: https://gerrit.chromium.org/gerrit/36286
Reviewed-by: Paul Stewart <pstew@chromium.org>
Commit-Ready: Bing Zhao <bzhao@marvell.com>
Tested-by: Bing Zhao <bzhao@marvell.com>
12 files changed:
drivers/net/wireless/mwifiex/11n_aggr.c
drivers/net/wireless/mwifiex/cfg80211.c
drivers/net/wireless/mwifiex/debugfs.c
drivers/net/wireless/mwifiex/init.c
drivers/net/wireless/mwifiex/join.c
drivers/net/wireless/mwifiex/main.c
drivers/net/wireless/mwifiex/main.h
drivers/net/wireless/mwifiex/sta_event.c
drivers/net/wireless/mwifiex/sta_ioctl.c
drivers/net/wireless/mwifiex/txrx.c
drivers/net/wireless/mwifiex/wmm.c
drivers/net/wireless/mwifiex/wmm.h

index 3d10964..a82f5e7 100644 (file)
@@ -197,7 +197,7 @@ mwifiex_11n_aggregate_pkt(struct mwifiex_private *priv,
                                       ra_list_flags);
                mwifiex_11n_form_amsdu_pkt(skb_aggr, skb_src, &pad);
 
-               mwifiex_write_data_complete(adapter, skb_src, 0);
+               mwifiex_write_data_complete(adapter, skb_src, 0, 0);
 
                spin_lock_irqsave(&priv->wmm.ra_list_spinlock, ra_list_flags);
 
@@ -250,7 +250,7 @@ mwifiex_11n_aggregate_pkt(struct mwifiex_private *priv,
                if (!mwifiex_is_ralist_valid(priv, pra_list, ptrindex)) {
                        spin_unlock_irqrestore(&priv->wmm.ra_list_spinlock,
                                               ra_list_flags);
-                       mwifiex_write_data_complete(adapter, skb_aggr, -1);
+                       mwifiex_write_data_complete(adapter, skb_aggr, 1, -1);
                        return -1;
                }
                if (GET_BSS_ROLE(priv) == MWIFIEX_BSS_ROLE_STA &&
@@ -276,13 +276,13 @@ mwifiex_11n_aggregate_pkt(struct mwifiex_private *priv,
                dev_err(adapter->dev, "%s: host_to_card failed: %#x\n",
                        __func__, ret);
                adapter->dbg.num_tx_host_to_card_failure++;
-               mwifiex_write_data_complete(adapter, skb_aggr, ret);
+               mwifiex_write_data_complete(adapter, skb_aggr, 1, ret);
                return 0;
        case -EINPROGRESS:
                adapter->data_sent = false;
                break;
        case 0:
-               mwifiex_write_data_complete(adapter, skb_aggr, ret);
+               mwifiex_write_data_complete(adapter, skb_aggr, 1, ret);
                break;
        default:
                break;
index e498dbf..531c96f 100644 (file)
@@ -1518,8 +1518,8 @@ struct net_device *mwifiex_add_virtual_intf(struct wiphy *wiphy,
                return ERR_PTR(-EINVAL);
        }
 
-       dev = alloc_netdev_mq(sizeof(struct mwifiex_private *), name,
-                             ether_setup, 1);
+       dev = alloc_netdev_mqs(sizeof(struct mwifiex_private *), name,
+                              ether_setup, IEEE80211_NUM_ACS, 1);
        if (!dev) {
                wiphy_err(wiphy, "no memory available for netdevice\n");
                priv->bss_mode = NL80211_IFTYPE_UNSPECIFIED;
@@ -1575,8 +1575,7 @@ int mwifiex_del_virtual_intf(struct wiphy *wiphy, struct net_device *dev)
        mwifiex_dev_debugfs_remove(priv);
 #endif
 
-       if (!netif_queue_stopped(priv->netdev))
-               netif_stop_queue(priv->netdev);
+       mwifiex_stop_net_dev_queue(priv->netdev, priv->adapter);
 
        if (netif_carrier_ok(priv->netdev))
                netif_carrier_off(priv->netdev);
index a870b58..46e34aa 100644 (file)
@@ -178,6 +178,7 @@ mwifiex_info_read(struct file *file, char __user *ubuf,
                (struct mwifiex_private *) file->private_data;
        struct net_device *netdev = priv->netdev;
        struct netdev_hw_addr *ha;
+       struct netdev_queue *txq;
        unsigned long page = get_zeroed_page(GFP_KERNEL);
        char *p = (char *) page, fmt[64];
        struct mwifiex_bss_info info;
@@ -229,8 +230,13 @@ mwifiex_info_read(struct file *file, char __user *ubuf,
        p += sprintf(p, "num_rx_pkts_err = %lu\n", priv->stats.rx_errors);
        p += sprintf(p, "carrier %s\n", ((netif_carrier_ok(priv->netdev))
                                         ? "on" : "off"));
-       p += sprintf(p, "tx queue %s\n", ((netif_queue_stopped(priv->netdev))
-                                         ? "stopped" : "started"));
+       p += sprintf(p, "tx queue");
+       for (i = 0; i < netdev->num_tx_queues; i++) {
+               txq = netdev_get_tx_queue(netdev, i);
+               p += sprintf(p, " %d:%s", i, netif_tx_queue_stopped(txq) ?
+                            "stopped" : "started");
+       }
+       p += sprintf(p, "\n");
 
        ret = simple_read_from_buffer(ubuf, count, ppos, (char *) page,
                                      (unsigned long) p - page);
index cf2c41e..a5c1b48 100644 (file)
@@ -388,9 +388,17 @@ void mwifiex_wake_up_net_dev_queue(struct net_device *netdev,
                                        struct mwifiex_adapter *adapter)
 {
        unsigned long dev_queue_flags;
+       unsigned int i;
 
        spin_lock_irqsave(&adapter->queue_lock, dev_queue_flags);
-       netif_tx_wake_all_queues(netdev);
+
+       for (i = 0; i < netdev->num_tx_queues; i++) {
+               struct netdev_queue *txq = netdev_get_tx_queue(netdev, i);
+
+               if (netif_tx_queue_stopped(txq))
+                       netif_tx_wake_queue(txq);
+       }
+
        spin_unlock_irqrestore(&adapter->queue_lock, dev_queue_flags);
 }
 
@@ -401,9 +409,17 @@ void mwifiex_stop_net_dev_queue(struct net_device *netdev,
                                        struct mwifiex_adapter *adapter)
 {
        unsigned long dev_queue_flags;
+       unsigned int i;
 
        spin_lock_irqsave(&adapter->queue_lock, dev_queue_flags);
-       netif_tx_stop_all_queues(netdev);
+
+       for (i = 0; i < netdev->num_tx_queues; i++) {
+               struct netdev_queue *txq = netdev_get_tx_queue(netdev, i);
+
+               if (!netif_tx_queue_stopped(txq))
+                       netif_tx_stop_queue(txq);
+       }
+
        spin_unlock_irqrestore(&adapter->queue_lock, dev_queue_flags);
 }
 
index 2e36541..a3c9250 100644 (file)
@@ -721,8 +721,7 @@ int mwifiex_ret_802_11_associate(struct mwifiex_private *priv,
 
        if (!netif_carrier_ok(priv->netdev))
                netif_carrier_on(priv->netdev);
-       if (netif_queue_stopped(priv->netdev))
-               netif_wake_queue(priv->netdev);
+       mwifiex_wake_up_net_dev_queue(priv->netdev, adapter);
 
        if (priv->sec_info.wpa_enabled || priv->sec_info.wpa2_enabled)
                priv->scan_block = true;
@@ -1238,8 +1237,7 @@ int mwifiex_ret_802_11_ad_hoc(struct mwifiex_private *priv,
 
        if (!netif_carrier_ok(priv->netdev))
                netif_carrier_on(priv->netdev);
-       if (netif_queue_stopped(priv->netdev))
-               netif_wake_queue(priv->netdev);
+       mwifiex_wake_up_net_dev_queue(priv->netdev, adapter);
 
        mwifiex_save_curr_bcn(priv);
 
index a59509b..34cd418 100644 (file)
@@ -386,49 +386,6 @@ static int mwifiex_init_hw_fw(struct mwifiex_adapter *adapter)
        return ret;
 }
 
-/*
- * This function fills a driver buffer.
- *
- * The function associates a given SKB with the provided driver buffer
- * and also updates some of the SKB parameters, including IP header,
- * priority and timestamp.
- */
-static void
-mwifiex_fill_buffer(struct sk_buff *skb)
-{
-       struct ethhdr *eth;
-       struct iphdr *iph;
-       struct timeval tv;
-       u8 tid = 0;
-
-       eth = (struct ethhdr *) skb->data;
-       switch (eth->h_proto) {
-       case __constant_htons(ETH_P_IP):
-               iph = ip_hdr(skb);
-               tid = IPTOS_PREC(iph->tos);
-               pr_debug("data: packet type ETH_P_IP: %04x, tid=%#x prio=%#x\n",
-                        eth->h_proto, tid, skb->priority);
-               break;
-       case __constant_htons(ETH_P_ARP):
-               pr_debug("data: ARP packet: %04x\n", eth->h_proto);
-       default:
-               break;
-       }
-/* Offset for TOS field in the IP header */
-#define IPTOS_OFFSET 5
-       tid = (tid >> IPTOS_OFFSET);
-       skb->priority = tid;
-       /* Record the current time the packet was queued; used to
-          determine the amount of time the packet was queued in
-          the driver before it was sent to the firmware.
-          The delay is then sent along with the packet to the
-          firmware for aggregate delay calculation for stats and
-          MSDU lifetime expiry.
-        */
-       do_gettimeofday(&tv);
-       skb->tstamp = timeval_to_ktime(tv);
-}
-
 /*
  * CFG802.11 network device handler for open.
  *
@@ -463,17 +420,23 @@ mwifiex_close(struct net_device *dev)
  */
 int mwifiex_queue_tx_pkt(struct mwifiex_private *priv, struct sk_buff *skb)
 {
-       mwifiex_wmm_add_buf_txqueue(priv, skb);
+       struct netdev_queue *txq;
+       int index = mwifiex_1d_to_wmm_queue[skb->priority];
+
+       if (atomic_inc_return(&priv->wmm_tx_pending[index]) >= MAX_TX_PENDING) {
+               txq = netdev_get_tx_queue(priv->netdev, index);
+               if (!netif_tx_queue_stopped(txq)) {
+                       netif_tx_stop_queue(txq);
+                       dev_dbg(priv->adapter->dev, "stop queue: %d\n", index);
+               }
+       }
+
        atomic_inc(&priv->adapter->tx_pending);
+       mwifiex_wmm_add_buf_txqueue(priv, skb);
 
        if (priv->adapter->scan_delay_cnt)
                atomic_set(&priv->adapter->is_tx_received, true);
 
-       if (atomic_read(&priv->adapter->tx_pending) >= MAX_TX_PENDING) {
-               mwifiex_set_trans_start(priv->netdev);
-               mwifiex_stop_net_dev_queue(priv->netdev, priv->adapter);
-       }
-
        queue_work(priv->adapter->workqueue, &priv->adapter->main_work);
 
        return 0;
@@ -488,6 +451,7 @@ mwifiex_hard_start_xmit(struct sk_buff *skb, struct net_device *dev)
        struct mwifiex_private *priv = mwifiex_netdev_get_priv(dev);
        struct sk_buff *new_skb;
        struct mwifiex_txinfo *tx_info;
+       struct timeval tv;
 
        dev_dbg(priv->adapter->dev, "data: %lu BSS(%d-%d): Data <= kernel\n",
                jiffies, priv->bss_type, priv->bss_num);
@@ -525,7 +489,16 @@ mwifiex_hard_start_xmit(struct sk_buff *skb, struct net_device *dev)
        tx_info = MWIFIEX_SKB_TXCB(skb);
        tx_info->bss_num = priv->bss_num;
        tx_info->bss_type = priv->bss_type;
-       mwifiex_fill_buffer(skb);
+
+       /* Record the current time the packet was queued; used to
+        * determine the amount of time the packet was queued in
+        * the driver before it was sent to the firmware.
+        * The delay is then sent along with the packet to the
+        * firmware for aggregate delay calculation for stats and
+        * MSDU lifetime expiry.
+        */
+       do_gettimeofday(&tv);
+       skb->tstamp = timeval_to_ktime(tv);
 
        mwifiex_queue_tx_pkt(priv, skb);
 
@@ -605,6 +578,13 @@ static struct net_device_stats *mwifiex_get_stats(struct net_device *dev)
        return &priv->stats;
 }
 
+static u16
+mwifiex_netdev_select_wmm_queue(struct net_device *dev, struct sk_buff *skb)
+{
+       skb->priority = cfg80211_classify8021d(skb);
+       return mwifiex_1d_to_wmm_queue[skb->priority];
+}
+
 /* Network device handlers */
 static const struct net_device_ops mwifiex_netdev_ops = {
        .ndo_open = mwifiex_open,
@@ -614,6 +594,7 @@ static const struct net_device_ops mwifiex_netdev_ops = {
        .ndo_tx_timeout = mwifiex_tx_timeout,
        .ndo_get_stats = mwifiex_get_stats,
        .ndo_set_rx_mode = mwifiex_set_multicast_list,
+       .ndo_select_queue = mwifiex_netdev_select_wmm_queue,
 };
 
 /*
@@ -806,9 +787,7 @@ int mwifiex_remove_card(struct mwifiex_adapter *adapter, struct semaphore *sem)
        for (i = 0; i < adapter->priv_num; i++) {
                priv = adapter->priv[i];
                if (priv && priv->netdev) {
-                       if (!netif_queue_stopped(priv->netdev))
-                               mwifiex_stop_net_dev_queue(priv->netdev,
-                                                          adapter);
+                       mwifiex_stop_net_dev_queue(priv->netdev, adapter);
                        if (netif_carrier_ok(priv->netdev))
                                netif_carrier_off(priv->netdev);
                }
index 008a292..9f98449 100644 (file)
@@ -421,6 +421,7 @@ struct mwifiex_private {
        u8 wmm_enabled;
        u8 wmm_qosinfo;
        struct mwifiex_wmm_desc wmm;
+       atomic_t wmm_tx_pending[IEEE80211_NUM_ACS];
        struct list_head tx_ba_stream_tbl_ptr;
        /* spin lock for tx_ba_stream_tbl_ptr queue */
        spinlock_t tx_ba_stream_tbl_lock;
@@ -738,7 +739,7 @@ int mwifiex_process_tx(struct mwifiex_private *priv, struct sk_buff *skb,
                       struct mwifiex_tx_param *tx_param);
 int mwifiex_send_null_packet(struct mwifiex_private *priv, u8 flags);
 int mwifiex_write_data_complete(struct mwifiex_adapter *adapter,
-                               struct sk_buff *skb, int status);
+                               struct sk_buff *skb, int aggr, int status);
 void mwifiex_clean_txrx(struct mwifiex_private *priv);
 u8 mwifiex_check_last_packet_indication(struct mwifiex_private *priv);
 void mwifiex_check_ps_cond(struct mwifiex_adapter *adapter);
index b4b584b..b9e4f17 100644 (file)
@@ -124,8 +124,7 @@ mwifiex_reset_connect_state(struct mwifiex_private *priv, u16 reason_code)
        }
        memset(priv->cfg_bssid, 0, ETH_ALEN);
 
-       if (!netif_queue_stopped(priv->netdev))
-               mwifiex_stop_net_dev_queue(priv->netdev, adapter);
+       mwifiex_stop_net_dev_queue(priv->netdev, adapter);
        if (netif_carrier_ok(priv->netdev))
                netif_carrier_off(priv->netdev);
 }
@@ -197,8 +196,7 @@ int mwifiex_process_sta_event(struct mwifiex_private *priv)
                dev_dbg(adapter->dev, "event: LINK_SENSED\n");
                if (!netif_carrier_ok(priv->netdev))
                        netif_carrier_on(priv->netdev);
-               if (netif_queue_stopped(priv->netdev))
-                       mwifiex_wake_up_net_dev_queue(priv->netdev, adapter);
+               mwifiex_wake_up_net_dev_queue(priv->netdev, adapter);
                break;
 
        case EVENT_DEAUTHENTICATED:
@@ -306,8 +304,7 @@ int mwifiex_process_sta_event(struct mwifiex_private *priv)
                dev_dbg(adapter->dev, "event: ADHOC_BCN_LOST\n");
                priv->adhoc_is_link_sensed = false;
                mwifiex_clean_txrx(priv);
-               if (!netif_queue_stopped(priv->netdev))
-                       mwifiex_stop_net_dev_queue(priv->netdev, adapter);
+               mwifiex_stop_net_dev_queue(priv->netdev, adapter);
                if (netif_carrier_ok(priv->netdev))
                        netif_carrier_off(priv->netdev);
                break;
index 4a6acd0..e2d2794 100644 (file)
@@ -287,8 +287,7 @@ int mwifiex_bss_start(struct mwifiex_private *priv, struct cfg80211_bss *bss,
                dev_dbg(adapter->dev, "info: SSID found in scan list ... "
                                      "associating...\n");
 
-               if (!netif_queue_stopped(priv->netdev))
-                       mwifiex_stop_net_dev_queue(priv->netdev, adapter);
+               mwifiex_stop_net_dev_queue(priv->netdev, adapter);
                if (netif_carrier_ok(priv->netdev))
                        netif_carrier_off(priv->netdev);
 
@@ -329,8 +328,7 @@ int mwifiex_bss_start(struct mwifiex_private *priv, struct cfg80211_bss *bss,
 
                ret = mwifiex_check_network_compatibility(priv, bss_desc);
 
-               if (!netif_queue_stopped(priv->netdev))
-                       mwifiex_stop_net_dev_queue(priv->netdev, adapter);
+               mwifiex_stop_net_dev_queue(priv->netdev, adapter);
                if (netif_carrier_ok(priv->netdev))
                        netif_carrier_off(priv->netdev);
 
index d2af8cb..9be25af 100644 (file)
@@ -97,13 +97,13 @@ int mwifiex_process_tx(struct mwifiex_private *priv, struct sk_buff *skb,
                dev_err(adapter->dev, "mwifiex_write_data_async failed: 0x%X\n",
                        ret);
                adapter->dbg.num_tx_host_to_card_failure++;
-               mwifiex_write_data_complete(adapter, skb, ret);
+               mwifiex_write_data_complete(adapter, skb, 0, ret);
                break;
        case -EINPROGRESS:
                adapter->data_sent = false;
                break;
        case 0:
-               mwifiex_write_data_complete(adapter, skb, ret);
+               mwifiex_write_data_complete(adapter, skb, 0, ret);
                break;
        default:
                break;
@@ -120,11 +120,12 @@ int mwifiex_process_tx(struct mwifiex_private *priv, struct sk_buff *skb,
  * wakes up stalled traffic queue if required, and then frees the buffer.
  */
 int mwifiex_write_data_complete(struct mwifiex_adapter *adapter,
-                               struct sk_buff *skb, int status)
+                               struct sk_buff *skb, int aggr, int status)
 {
-       struct mwifiex_private *priv, *tpriv;
+       struct mwifiex_private *priv;
        struct mwifiex_txinfo *tx_info;
-       int i;
+       struct netdev_queue *txq;
+       int index;
 
        if (!skb)
                return 0;
@@ -143,18 +144,18 @@ int mwifiex_write_data_complete(struct mwifiex_adapter *adapter,
                priv->stats.tx_errors++;
        }
 
-       if (atomic_dec_return(&adapter->tx_pending) >= LOW_TX_PENDING)
+       if (aggr)
+               /* For skb_aggr, do not wake up tx queue */
                goto done;
 
-       for (i = 0; i < adapter->priv_num; i++) {
+       atomic_dec(&adapter->tx_pending);
 
-               tpriv = adapter->priv[i];
-
-               if ((GET_BSS_ROLE(tpriv) == MWIFIEX_BSS_ROLE_STA) &&
-                   (tpriv->media_connected)) {
-                       if (netif_queue_stopped(tpriv->netdev))
-                               mwifiex_wake_up_net_dev_queue(tpriv->netdev,
-                                                             adapter);
+       index = mwifiex_1d_to_wmm_queue[skb->priority];
+       if (atomic_dec_return(&priv->wmm_tx_pending[index]) < LOW_TX_PENDING) {
+               txq = netdev_get_tx_queue(priv->netdev, index);
+               if (netif_tx_queue_stopped(txq)) {
+                       netif_tx_wake_queue(txq);
+                       dev_dbg(adapter->dev, "wake queue: %d\n", index);
                }
        }
 done:
index 1ac5f71..2d26bab 100644 (file)
@@ -444,7 +444,7 @@ mwifiex_wmm_del_pkts_in_ralist_node(struct mwifiex_private *priv,
        struct sk_buff *skb, *tmp;
 
        skb_queue_walk_safe(&ra_list->skb_head, skb, tmp)
-               mwifiex_write_data_complete(adapter, skb, -1);
+               mwifiex_write_data_complete(adapter, skb, 0, -1);
 }
 
 /*
@@ -611,7 +611,7 @@ mwifiex_wmm_add_buf_txqueue(struct mwifiex_private *priv,
 
        if (!priv->media_connected && !mwifiex_is_skb_mgmt_frame(skb)) {
                dev_dbg(adapter->dev, "data: drop packet in disconnect\n");
-               mwifiex_write_data_complete(adapter, skb, -1);
+               mwifiex_write_data_complete(adapter, skb, 0, -1);
                return;
        }
 
@@ -641,7 +641,7 @@ mwifiex_wmm_add_buf_txqueue(struct mwifiex_private *priv,
 
        if (!ra_list) {
                spin_unlock_irqrestore(&priv->wmm.ra_list_spinlock, flags);
-               mwifiex_write_data_complete(adapter, skb, -1);
+               mwifiex_write_data_complete(adapter, skb, 0, -1);
                return;
        }
 
@@ -1040,7 +1040,7 @@ mwifiex_send_single_packet(struct mwifiex_private *priv,
                if (!mwifiex_is_ralist_valid(priv, ptr, ptr_index)) {
                        spin_unlock_irqrestore(&priv->wmm.ra_list_spinlock,
                                               ra_list_flags);
-                       mwifiex_write_data_complete(adapter, skb, -1);
+                       mwifiex_write_data_complete(adapter, skb, 0, -1);
                        return;
                }
 
@@ -1136,7 +1136,7 @@ mwifiex_send_processed_packet(struct mwifiex_private *priv,
                if (!mwifiex_is_ralist_valid(priv, ptr, ptr_index)) {
                        spin_unlock_irqrestore(&priv->wmm.ra_list_spinlock,
                                               ra_list_flags);
-                       mwifiex_write_data_complete(adapter, skb, -1);
+                       mwifiex_write_data_complete(adapter, skb, 0, -1);
                        return;
                }
 
@@ -1150,7 +1150,7 @@ mwifiex_send_processed_packet(struct mwifiex_private *priv,
                adapter->data_sent = false;
                dev_err(adapter->dev, "host_to_card failed: %#x\n", ret);
                adapter->dbg.num_tx_host_to_card_failure++;
-               mwifiex_write_data_complete(adapter, skb, ret);
+               mwifiex_write_data_complete(adapter, skb, 0, ret);
                break;
        case -EINPROGRESS:
                adapter->data_sent = false;
index ec83995..b92f39d 100644 (file)
@@ -31,6 +31,8 @@ enum ieee_types_wmm_ecw_bitmasks {
        MWIFIEX_ECW_MAX = (BIT(4) | BIT(5) | BIT(6) | BIT(7)),
 };
 
+static const u16 mwifiex_1d_to_wmm_queue[8] = { 1, 0, 0, 1, 2, 2, 3, 3 };
+
 /*
  * This function retrieves the TID of the given RA list.
  */