ionic: replay VF attributes after fw crash recovery
authorShannon Nelson <snelson@pensando.io>
Wed, 26 Oct 2022 14:37:40 +0000 (07:37 -0700)
committerJakub Kicinski <kuba@kernel.org>
Fri, 28 Oct 2022 03:34:12 +0000 (20:34 -0700)
The VF attributes that the user has set into the FW through
the PF can be lost over a FW crash recovery.  Much like we
already replay the PF mac/vlan filters, we now add a replay
in the recovery path to be sure the FW has the up-to-date
VF configurations.

Signed-off-by: Shannon Nelson <snelson@pensando.io>
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
drivers/net/ethernet/pensando/ionic/ionic_lif.c

index 19d4848..865ee58 100644 (file)
@@ -2562,6 +2562,74 @@ static int ionic_set_vf_link_state(struct net_device *netdev, int vf, int set)
        return ret;
 }
 
+static void ionic_vf_attr_replay(struct ionic_lif *lif)
+{
+       struct ionic_vf_setattr_cmd vfc = { };
+       struct ionic *ionic = lif->ionic;
+       struct ionic_vf *v;
+       int i;
+
+       if (!ionic->vfs)
+               return;
+
+       down_read(&ionic->vf_op_lock);
+
+       for (i = 0; i < ionic->num_vfs; i++) {
+               v = &ionic->vfs[i];
+
+               if (v->stats_pa) {
+                       vfc.attr = IONIC_VF_ATTR_STATSADDR;
+                       vfc.stats_pa = cpu_to_le64(v->stats_pa);
+                       ionic_set_vf_config(ionic, i, &vfc);
+                       vfc.stats_pa = 0;
+               }
+
+               if (!is_zero_ether_addr(v->macaddr)) {
+                       vfc.attr = IONIC_VF_ATTR_MAC;
+                       ether_addr_copy(vfc.macaddr, v->macaddr);
+                       ionic_set_vf_config(ionic, i, &vfc);
+                       eth_zero_addr(vfc.macaddr);
+               }
+
+               if (v->vlanid) {
+                       vfc.attr = IONIC_VF_ATTR_VLAN;
+                       vfc.vlanid = v->vlanid;
+                       ionic_set_vf_config(ionic, i, &vfc);
+                       vfc.vlanid = 0;
+               }
+
+               if (v->maxrate) {
+                       vfc.attr = IONIC_VF_ATTR_RATE;
+                       vfc.maxrate = v->maxrate;
+                       ionic_set_vf_config(ionic, i, &vfc);
+                       vfc.maxrate = 0;
+               }
+
+               if (v->spoofchk) {
+                       vfc.attr = IONIC_VF_ATTR_SPOOFCHK;
+                       vfc.spoofchk = v->spoofchk;
+                       ionic_set_vf_config(ionic, i, &vfc);
+                       vfc.spoofchk = 0;
+               }
+
+               if (v->trusted) {
+                       vfc.attr = IONIC_VF_ATTR_TRUST;
+                       vfc.trust = v->trusted;
+                       ionic_set_vf_config(ionic, i, &vfc);
+                       vfc.trust = 0;
+               }
+
+               if (v->linkstate) {
+                       vfc.attr = IONIC_VF_ATTR_LINKSTATE;
+                       vfc.linkstate = v->linkstate;
+                       ionic_set_vf_config(ionic, i, &vfc);
+                       vfc.linkstate = 0;
+               }
+       }
+
+       up_read(&ionic->vf_op_lock);
+}
+
 static const struct net_device_ops ionic_netdev_ops = {
        .ndo_open               = ionic_open,
        .ndo_stop               = ionic_stop,
@@ -3042,6 +3110,8 @@ static void ionic_lif_handle_fw_up(struct ionic_lif *lif)
        if (err)
                goto err_qcqs_free;
 
+       ionic_vf_attr_replay(lif);
+
        if (lif->registered)
                ionic_lif_set_netdev_info(lif);