return err;
 }
 
+int ionic_dev_cmd_vf_getattr(struct ionic *ionic, int vf, u8 attr,
+                            struct ionic_vf_getattr_comp *comp)
+{
+       union ionic_dev_cmd cmd = {
+               .vf_getattr.opcode = IONIC_CMD_VF_GETATTR,
+               .vf_getattr.attr = attr,
+               .vf_getattr.vf_index = cpu_to_le16(vf),
+       };
+       int err;
+
+       if (vf >= ionic->num_vfs)
+               return -EINVAL;
+
+       switch (attr) {
+       case IONIC_VF_ATTR_SPOOFCHK:
+       case IONIC_VF_ATTR_TRUST:
+       case IONIC_VF_ATTR_LINKSTATE:
+       case IONIC_VF_ATTR_MAC:
+       case IONIC_VF_ATTR_VLAN:
+       case IONIC_VF_ATTR_RATE:
+               break;
+       case IONIC_VF_ATTR_STATSADDR:
+       default:
+               return -EINVAL;
+       }
+
+       mutex_lock(&ionic->dev_cmd_lock);
+       ionic_dev_cmd_go(&ionic->idev, &cmd);
+       err = ionic_dev_cmd_wait_nomsg(ionic, DEVCMD_TIMEOUT);
+       memcpy_fromio(comp, &ionic->idev.dev_cmd_regs->comp.vf_getattr,
+                     sizeof(*comp));
+       mutex_unlock(&ionic->dev_cmd_lock);
+
+       if (err && comp->status != IONIC_RC_ENOSUPP)
+               ionic_dev_cmd_dev_err_print(ionic, cmd.vf_getattr.opcode,
+                                           comp->status, err);
+
+       return err;
+}
+
 /* LIF commands */
 void ionic_dev_cmd_queue_identify(struct ionic_dev *idev,
                                  u16 lif_type, u8 qtype, u8 qver)
 
        }
 }
 
+static int ionic_update_cached_vf_config(struct ionic *ionic, int vf)
+{
+       struct ionic_vf_getattr_comp comp = { 0 };
+       int err;
+       u8 attr;
+
+       attr = IONIC_VF_ATTR_VLAN;
+       err = ionic_dev_cmd_vf_getattr(ionic, vf, attr, &comp);
+       if (err && comp.status != IONIC_RC_ENOSUPP)
+               goto err_out;
+       if (!err)
+               ionic->vfs[vf].vlanid = comp.vlanid;
+
+       attr = IONIC_VF_ATTR_SPOOFCHK;
+       err = ionic_dev_cmd_vf_getattr(ionic, vf, attr, &comp);
+       if (err && comp.status != IONIC_RC_ENOSUPP)
+               goto err_out;
+       if (!err)
+               ionic->vfs[vf].spoofchk = comp.spoofchk;
+
+       attr = IONIC_VF_ATTR_LINKSTATE;
+       err = ionic_dev_cmd_vf_getattr(ionic, vf, attr, &comp);
+       if (err && comp.status != IONIC_RC_ENOSUPP)
+               goto err_out;
+       if (!err) {
+               switch (comp.linkstate) {
+               case IONIC_VF_LINK_STATUS_UP:
+                       ionic->vfs[vf].linkstate = IFLA_VF_LINK_STATE_ENABLE;
+                       break;
+               case IONIC_VF_LINK_STATUS_DOWN:
+                       ionic->vfs[vf].linkstate = IFLA_VF_LINK_STATE_DISABLE;
+                       break;
+               case IONIC_VF_LINK_STATUS_AUTO:
+                       ionic->vfs[vf].linkstate = IFLA_VF_LINK_STATE_AUTO;
+                       break;
+               default:
+                       dev_warn(ionic->dev, "Unexpected link state %u\n", comp.linkstate);
+                       break;
+               }
+       }
+
+       attr = IONIC_VF_ATTR_RATE;
+       err = ionic_dev_cmd_vf_getattr(ionic, vf, attr, &comp);
+       if (err && comp.status != IONIC_RC_ENOSUPP)
+               goto err_out;
+       if (!err)
+               ionic->vfs[vf].maxrate = comp.maxrate;
+
+       attr = IONIC_VF_ATTR_TRUST;
+       err = ionic_dev_cmd_vf_getattr(ionic, vf, attr, &comp);
+       if (err && comp.status != IONIC_RC_ENOSUPP)
+               goto err_out;
+       if (!err)
+               ionic->vfs[vf].trusted = comp.trust;
+
+       attr = IONIC_VF_ATTR_MAC;
+       err = ionic_dev_cmd_vf_getattr(ionic, vf, attr, &comp);
+       if (err && comp.status != IONIC_RC_ENOSUPP)
+               goto err_out;
+       if (!err)
+               ether_addr_copy(ionic->vfs[vf].macaddr, comp.macaddr);
+
+err_out:
+       if (err)
+               dev_err(ionic->dev, "Failed to get %s for VF %d\n",
+                       ionic_vf_attr_to_str(attr), vf);
+
+       return err;
+}
+
 static int ionic_get_vf_config(struct net_device *netdev,
                               int vf, struct ifla_vf_info *ivf)
 {
        if (vf >= pci_num_vf(ionic->pdev) || !ionic->vfs) {
                ret = -EINVAL;
        } else {
-               ivf->vf           = vf;
-               ivf->vlan         = le16_to_cpu(ionic->vfs[vf].vlanid);
-               ivf->qos          = 0;
-               ivf->spoofchk     = ionic->vfs[vf].spoofchk;
-               ivf->linkstate    = ionic->vfs[vf].linkstate;
-               ivf->max_tx_rate  = le32_to_cpu(ionic->vfs[vf].maxrate);
-               ivf->trusted      = ionic->vfs[vf].trusted;
-               ether_addr_copy(ivf->mac, ionic->vfs[vf].macaddr);
+               ivf->vf = vf;
+               ivf->qos = 0;
+
+               ret = ionic_update_cached_vf_config(ionic, vf);
+               if (!ret) {
+                       ivf->vlan         = le16_to_cpu(ionic->vfs[vf].vlanid);
+                       ivf->spoofchk     = ionic->vfs[vf].spoofchk;
+                       ivf->linkstate    = ionic->vfs[vf].linkstate;
+                       ivf->max_tx_rate  = le32_to_cpu(ionic->vfs[vf].maxrate);
+                       ivf->trusted      = ionic->vfs[vf].trusted;
+                       ether_addr_copy(ivf->mac, ionic->vfs[vf].macaddr);
+               }
        }
 
        up_read(&ionic->vf_op_lock);
 
        }
 }
 
+const char *ionic_vf_attr_to_str(enum ionic_vf_attr attr)
+{
+       switch (attr) {
+       case IONIC_VF_ATTR_SPOOFCHK:
+               return "IONIC_VF_ATTR_SPOOFCHK";
+       case IONIC_VF_ATTR_TRUST:
+               return "IONIC_VF_ATTR_TRUST";
+       case IONIC_VF_ATTR_LINKSTATE:
+               return "IONIC_VF_ATTR_LINKSTATE";
+       case IONIC_VF_ATTR_MAC:
+               return "IONIC_VF_ATTR_MAC";
+       case IONIC_VF_ATTR_VLAN:
+               return "IONIC_VF_ATTR_VLAN";
+       case IONIC_VF_ATTR_RATE:
+               return "IONIC_VF_ATTR_RATE";
+       case IONIC_VF_ATTR_STATSADDR:
+               return "IONIC_VF_ATTR_STATSADDR";
+       default:
+               return "IONIC_VF_ATTR_UNKNOWN";
+       }
+}
+
 static void ionic_adminq_flush(struct ionic_lif *lif)
 {
        struct ionic_desc_info *desc_info;