ionic: update filter id after replay
authorShannon Nelson <snelson@pensando.io>
Mon, 20 Jul 2020 23:00:15 +0000 (16:00 -0700)
committerDavid S. Miller <davem@davemloft.net>
Tue, 21 Jul 2020 01:09:38 +0000 (18:09 -0700)
When we replay the rx filters after a fw-upgrade we get new
filter_id values from the FW, which we need to save and update
in our local filter list.  This allows us to delete the filters
with the correct filter_id when we're done.

Fixes: 7e4d47596b68 ("ionic: replay filters after fw upgrade")
Signed-off-by: Shannon Nelson <snelson@pensando.io>
Signed-off-by: David S. Miller <davem@davemloft.net>
drivers/net/ethernet/pensando/ionic/ionic_rx_filter.c

index fb9d828..cd0076f 100644 (file)
@@ -21,13 +21,16 @@ void ionic_rx_filter_free(struct ionic_lif *lif, struct ionic_rx_filter *f)
 void ionic_rx_filter_replay(struct ionic_lif *lif)
 {
        struct ionic_rx_filter_add_cmd *ac;
+       struct hlist_head new_id_list;
        struct ionic_admin_ctx ctx;
        struct ionic_rx_filter *f;
        struct hlist_head *head;
        struct hlist_node *tmp;
+       unsigned int key;
        unsigned int i;
        int err;
 
+       INIT_HLIST_HEAD(&new_id_list);
        ac = &ctx.cmd.rx_filter_add;
 
        for (i = 0; i < IONIC_RX_FILTER_HLISTS; i++) {
@@ -58,9 +61,30 @@ void ionic_rx_filter_replay(struct ionic_lif *lif)
                                                    ac->mac.addr);
                                        break;
                                }
+                               spin_lock_bh(&lif->rx_filters.lock);
+                               ionic_rx_filter_free(lif, f);
+                               spin_unlock_bh(&lif->rx_filters.lock);
+
+                               continue;
                        }
+
+                       /* remove from old id list, save new id in tmp list */
+                       spin_lock_bh(&lif->rx_filters.lock);
+                       hlist_del(&f->by_id);
+                       spin_unlock_bh(&lif->rx_filters.lock);
+                       f->filter_id = le32_to_cpu(ctx.comp.rx_filter_add.filter_id);
+                       hlist_add_head(&f->by_id, &new_id_list);
                }
        }
+
+       /* rebuild the by_id hash lists with the new filter ids */
+       spin_lock_bh(&lif->rx_filters.lock);
+       hlist_for_each_entry_safe(f, tmp, &new_id_list, by_id) {
+               key = f->filter_id & IONIC_RX_FILTER_HLISTS_MASK;
+               head = &lif->rx_filters.by_id[key];
+               hlist_add_head(&f->by_id, head);
+       }
+       spin_unlock_bh(&lif->rx_filters.lock);
 }
 
 int ionic_rx_filters_init(struct ionic_lif *lif)