*/
 void cxgb4_remove_tid(struct tid_info *t, unsigned int chan, unsigned int tid)
 {
-       void *old;
        struct sk_buff *skb;
        struct adapter *adap = container_of(t, struct adapter, tids);
 
-       old = t->tid_tab[tid];
+       WARN_ON(tid >= t->ntids);
+
+       if (t->tid_tab[tid]) {
+               t->tid_tab[tid] = NULL;
+               if (t->hash_base && (tid >= t->hash_base))
+                       atomic_dec(&t->hash_tids_in_use);
+               else
+                       atomic_dec(&t->tids_in_use);
+       }
+
        skb = alloc_skb(sizeof(struct cpl_tid_release), GFP_ATOMIC);
        if (likely(skb)) {
-               t->tid_tab[tid] = NULL;
                mk_tid_release(skb, chan, tid);
                t4_ofld_send(adap, skb);
        } else
                cxgb4_queue_tid_release(t, chan, tid);
-       if (old)
-               atomic_dec(&t->tids_in_use);
 }
 EXPORT_SYMBOL(cxgb4_remove_tid);
 
        t->afree = NULL;
        t->atids_in_use = 0;
        atomic_set(&t->tids_in_use, 0);
+       atomic_set(&t->hash_tids_in_use, 0);
 
        /* Setup the free list for atid_tab and clear the stid bitmap. */
        if (natids) {
                adapter->params.offload = 0;
        }
 
+       if (is_offload(adapter)) {
+               if (t4_read_reg(adapter, LE_DB_CONFIG_A) & HASHEN_F) {
+                       u32 hash_base, hash_reg;
+
+                       if (chip <= CHELSIO_T5) {
+                               hash_reg = LE_DB_TID_HASHBASE_A;
+                               hash_base = t4_read_reg(adapter, hash_reg);
+                               adapter->tids.hash_base = hash_base / 4;
+                       } else {
+                               hash_reg = T6_LE_DB_HASH_TID_BASE_A;
+                               hash_base = t4_read_reg(adapter, hash_reg);
+                               adapter->tids.hash_base = hash_base;
+                       }
+               }
+       }
+
        /* See what interrupts we'll be using */
        if (msi > 1 && enable_msix(adapter) == 0)
                adapter->flags |= USING_MSIX;
 
        unsigned long *stid_bmap;
        unsigned int nstids;
        unsigned int stid_base;
+       unsigned int hash_base;
 
        union aopen_entry *atid_tab;
        unsigned int natids;
        spinlock_t stid_lock;
        unsigned int stids_in_use;
 
+       /* TIDs in the TCAM */
        atomic_t tids_in_use;
+       /* TIDs in the HASH */
+       atomic_t hash_tids_in_use;
 };
 
 static inline void *lookup_tid(const struct tid_info *t, unsigned int tid)
                                    unsigned int tid)
 {
        t->tid_tab[tid] = data;
-       atomic_inc(&t->tids_in_use);
+       if (t->hash_base && (tid >= t->hash_base))
+               atomic_inc(&t->hash_tids_in_use);
+       else
+               atomic_inc(&t->tids_in_use);
 }
 
 int cxgb4_alloc_atid(struct tid_info *t, void *data);