cxgb4: Delete all hash and TCAM filters before resource cleanup
authorVishal Kulkarni <vishal@chelsio.com>
Fri, 26 Apr 2019 08:28:48 +0000 (13:58 +0530)
committerDavid S. Miller <davem@davemloft.net>
Sun, 28 Apr 2019 02:25:37 +0000 (22:25 -0400)
During driver unload, hash/TCAM filter deletion doesn't wait for
completion.This patch deletes all the filters with completion before
clearing the resources.

Signed-off-by: Vishal Kulkarni <vishal@chelsio.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
drivers/net/ethernet/chelsio/cxgb4/cxgb4_filter.c
drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c

index 93ad4be..4107007 100644 (file)
@@ -524,8 +524,7 @@ static int del_filter_wr(struct adapter *adapter, int fidx)
                return -ENOMEM;
 
        fwr = __skb_put(skb, len);
-       t4_mk_filtdelwr(f->tid, fwr, (adapter->flags & CXGB4_SHUTTING_DOWN) ? -1
-                       : adapter->sge.fw_evtq.abs_id);
+       t4_mk_filtdelwr(f->tid, fwr, adapter->sge.fw_evtq.abs_id);
 
        /* Mark the filter as "pending" and ship off the Filter Work Request.
         * When we get the Work Request Reply we'll clear the pending status.
@@ -744,16 +743,40 @@ void clear_filter(struct adapter *adap, struct filter_entry *f)
 
 void clear_all_filters(struct adapter *adapter)
 {
+       struct net_device *dev = adapter->port[0];
        unsigned int i;
 
        if (adapter->tids.ftid_tab) {
                struct filter_entry *f = &adapter->tids.ftid_tab[0];
                unsigned int max_ftid = adapter->tids.nftids +
                                        adapter->tids.nsftids;
-
+               /* Clear all TCAM filters */
                for (i = 0; i < max_ftid; i++, f++)
                        if (f->valid || f->pending)
-                               clear_filter(adapter, f);
+                               cxgb4_del_filter(dev, i, &f->fs);
+       }
+
+       /* Clear all hash filters */
+       if (is_hashfilter(adapter) && adapter->tids.tid_tab) {
+               struct filter_entry *f;
+               unsigned int sb;
+
+               for (i = adapter->tids.hash_base;
+                    i <= adapter->tids.ntids; i++) {
+                       f = (struct filter_entry *)
+                               adapter->tids.tid_tab[i];
+
+                       if (f && (f->valid || f->pending))
+                               cxgb4_del_filter(dev, i, &f->fs);
+               }
+
+               sb = t4_read_reg(adapter, LE_DB_SRVR_START_INDEX_A);
+               for (i = 0; i < sb; i++) {
+                       f = (struct filter_entry *)adapter->tids.tid_tab[i];
+
+                       if (f && (f->valid || f->pending))
+                               cxgb4_del_filter(dev, i, &f->fs);
+               }
        }
 }
 
@@ -1568,9 +1591,8 @@ int cxgb4_del_filter(struct net_device *dev, int filter_id,
        struct filter_ctx ctx;
        int ret;
 
-       /* If we are shutting down the adapter do not wait for completion */
        if (netdev2adap(dev)->flags & CXGB4_SHUTTING_DOWN)
-               return __cxgb4_del_filter(dev, filter_id, fs, NULL);
+               return 0;
 
        init_completion(&ctx.completion);
 
index 3339f1f..7487852 100644 (file)
@@ -6024,6 +6024,11 @@ static void remove_one(struct pci_dev *pdev)
                return;
        }
 
+       /* If we allocated filters, free up state associated with any
+        * valid filters ...
+        */
+       clear_all_filters(adapter);
+
        adapter->flags |= CXGB4_SHUTTING_DOWN;
 
        if (adapter->pf == 4) {
@@ -6054,11 +6059,6 @@ static void remove_one(struct pci_dev *pdev)
                if (IS_REACHABLE(CONFIG_THERMAL))
                        cxgb4_thermal_remove(adapter);
 
-               /* If we allocated filters, free up state associated with any
-                * valid filters ...
-                */
-               clear_all_filters(adapter);
-
                if (adapter->flags & CXGB4_FULL_INIT_DONE)
                        cxgb_down(adapter);