Skip to content

Commit f16f5be

Browse files
brettcreeleydavem330
authored andcommitted
ionic: Query FW when getting VF info via ndo_get_vf_config
Currently when an administrator configures a VF via ndo_set_vf*, the driver will send the set command to FW and then update the cached value. The cached value is then used when reporting VF info via ndo_get_vf_config. A problem is that the VF info may have been updated between the last ndo_set_vf* and ndo_get_vf_info commands via some other method, i.e. a VF changes its MAC address (assuming it's allowed to do so) and since this is all managed by the FW, this new value won't be reflected in the PF's cache of values. To fix this, update the driver to always get the latest VF information by making use of the IONIC_CMD_VF_GETATTR dev command. The FW may not support getting all the attributes for IONIC_CMD_VF_GETATTR, so the driver will only update the cached VF config members if their associated IONIC_CMD_VF_GETATTR was successful. Otherwise the cached VF config members will remain the same as what was set in ndo_set_vf*. Fixes: fbb3980 ("ionic: support sr-iov operations") Signed-off-by: Brett Creeley <[email protected]> Signed-off-by: Shannon Nelson <[email protected]> Signed-off-by: David S. Miller <[email protected]>
1 parent b640b55 commit f16f5be

File tree

5 files changed

+148
-8
lines changed

5 files changed

+148
-8
lines changed

drivers/net/ethernet/pensando/ionic/ionic.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -92,4 +92,6 @@ int ionic_port_identify(struct ionic *ionic);
9292
int ionic_port_init(struct ionic *ionic);
9393
int ionic_port_reset(struct ionic *ionic);
9494

95+
const char *ionic_vf_attr_to_str(enum ionic_vf_attr attr);
96+
9597
#endif /* _IONIC_H_ */

drivers/net/ethernet/pensando/ionic/ionic_dev.c

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -472,6 +472,46 @@ int ionic_set_vf_config(struct ionic *ionic, int vf, u8 attr, u8 *data)
472472
return err;
473473
}
474474

475+
int ionic_dev_cmd_vf_getattr(struct ionic *ionic, int vf, u8 attr,
476+
struct ionic_vf_getattr_comp *comp)
477+
{
478+
union ionic_dev_cmd cmd = {
479+
.vf_getattr.opcode = IONIC_CMD_VF_GETATTR,
480+
.vf_getattr.attr = attr,
481+
.vf_getattr.vf_index = cpu_to_le16(vf),
482+
};
483+
int err;
484+
485+
if (vf >= ionic->num_vfs)
486+
return -EINVAL;
487+
488+
switch (attr) {
489+
case IONIC_VF_ATTR_SPOOFCHK:
490+
case IONIC_VF_ATTR_TRUST:
491+
case IONIC_VF_ATTR_LINKSTATE:
492+
case IONIC_VF_ATTR_MAC:
493+
case IONIC_VF_ATTR_VLAN:
494+
case IONIC_VF_ATTR_RATE:
495+
break;
496+
case IONIC_VF_ATTR_STATSADDR:
497+
default:
498+
return -EINVAL;
499+
}
500+
501+
mutex_lock(&ionic->dev_cmd_lock);
502+
ionic_dev_cmd_go(&ionic->idev, &cmd);
503+
err = ionic_dev_cmd_wait_nomsg(ionic, DEVCMD_TIMEOUT);
504+
memcpy_fromio(comp, &ionic->idev.dev_cmd_regs->comp.vf_getattr,
505+
sizeof(*comp));
506+
mutex_unlock(&ionic->dev_cmd_lock);
507+
508+
if (err && comp->status != IONIC_RC_ENOSUPP)
509+
ionic_dev_cmd_dev_err_print(ionic, cmd.vf_getattr.opcode,
510+
comp->status, err);
511+
512+
return err;
513+
}
514+
475515
/* LIF commands */
476516
void ionic_dev_cmd_queue_identify(struct ionic_dev *idev,
477517
u16 lif_type, u8 qtype, u8 qver)

drivers/net/ethernet/pensando/ionic/ionic_dev.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -319,6 +319,8 @@ void ionic_dev_cmd_port_fec(struct ionic_dev *idev, u8 fec_type);
319319
void ionic_dev_cmd_port_pause(struct ionic_dev *idev, u8 pause_type);
320320

321321
int ionic_set_vf_config(struct ionic *ionic, int vf, u8 attr, u8 *data);
322+
int ionic_dev_cmd_vf_getattr(struct ionic *ionic, int vf, u8 attr,
323+
struct ionic_vf_getattr_comp *comp);
322324
void ionic_dev_cmd_queue_identify(struct ionic_dev *idev,
323325
u16 lif_type, u8 qtype, u8 qver);
324326
void ionic_dev_cmd_lif_identify(struct ionic_dev *idev, u8 type, u8 ver);

drivers/net/ethernet/pensando/ionic/ionic_lif.c

Lines changed: 82 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -2157,6 +2157,76 @@ static int ionic_eth_ioctl(struct net_device *netdev, struct ifreq *ifr, int cmd
21572157
}
21582158
}
21592159

2160+
static int ionic_update_cached_vf_config(struct ionic *ionic, int vf)
2161+
{
2162+
struct ionic_vf_getattr_comp comp = { 0 };
2163+
int err;
2164+
u8 attr;
2165+
2166+
attr = IONIC_VF_ATTR_VLAN;
2167+
err = ionic_dev_cmd_vf_getattr(ionic, vf, attr, &comp);
2168+
if (err && comp.status != IONIC_RC_ENOSUPP)
2169+
goto err_out;
2170+
if (!err)
2171+
ionic->vfs[vf].vlanid = comp.vlanid;
2172+
2173+
attr = IONIC_VF_ATTR_SPOOFCHK;
2174+
err = ionic_dev_cmd_vf_getattr(ionic, vf, attr, &comp);
2175+
if (err && comp.status != IONIC_RC_ENOSUPP)
2176+
goto err_out;
2177+
if (!err)
2178+
ionic->vfs[vf].spoofchk = comp.spoofchk;
2179+
2180+
attr = IONIC_VF_ATTR_LINKSTATE;
2181+
err = ionic_dev_cmd_vf_getattr(ionic, vf, attr, &comp);
2182+
if (err && comp.status != IONIC_RC_ENOSUPP)
2183+
goto err_out;
2184+
if (!err) {
2185+
switch (comp.linkstate) {
2186+
case IONIC_VF_LINK_STATUS_UP:
2187+
ionic->vfs[vf].linkstate = IFLA_VF_LINK_STATE_ENABLE;
2188+
break;
2189+
case IONIC_VF_LINK_STATUS_DOWN:
2190+
ionic->vfs[vf].linkstate = IFLA_VF_LINK_STATE_DISABLE;
2191+
break;
2192+
case IONIC_VF_LINK_STATUS_AUTO:
2193+
ionic->vfs[vf].linkstate = IFLA_VF_LINK_STATE_AUTO;
2194+
break;
2195+
default:
2196+
dev_warn(ionic->dev, "Unexpected link state %u\n", comp.linkstate);
2197+
break;
2198+
}
2199+
}
2200+
2201+
attr = IONIC_VF_ATTR_RATE;
2202+
err = ionic_dev_cmd_vf_getattr(ionic, vf, attr, &comp);
2203+
if (err && comp.status != IONIC_RC_ENOSUPP)
2204+
goto err_out;
2205+
if (!err)
2206+
ionic->vfs[vf].maxrate = comp.maxrate;
2207+
2208+
attr = IONIC_VF_ATTR_TRUST;
2209+
err = ionic_dev_cmd_vf_getattr(ionic, vf, attr, &comp);
2210+
if (err && comp.status != IONIC_RC_ENOSUPP)
2211+
goto err_out;
2212+
if (!err)
2213+
ionic->vfs[vf].trusted = comp.trust;
2214+
2215+
attr = IONIC_VF_ATTR_MAC;
2216+
err = ionic_dev_cmd_vf_getattr(ionic, vf, attr, &comp);
2217+
if (err && comp.status != IONIC_RC_ENOSUPP)
2218+
goto err_out;
2219+
if (!err)
2220+
ether_addr_copy(ionic->vfs[vf].macaddr, comp.macaddr);
2221+
2222+
err_out:
2223+
if (err)
2224+
dev_err(ionic->dev, "Failed to get %s for VF %d\n",
2225+
ionic_vf_attr_to_str(attr), vf);
2226+
2227+
return err;
2228+
}
2229+
21602230
static int ionic_get_vf_config(struct net_device *netdev,
21612231
int vf, struct ifla_vf_info *ivf)
21622232
{
@@ -2172,14 +2242,18 @@ static int ionic_get_vf_config(struct net_device *netdev,
21722242
if (vf >= pci_num_vf(ionic->pdev) || !ionic->vfs) {
21732243
ret = -EINVAL;
21742244
} else {
2175-
ivf->vf = vf;
2176-
ivf->vlan = le16_to_cpu(ionic->vfs[vf].vlanid);
2177-
ivf->qos = 0;
2178-
ivf->spoofchk = ionic->vfs[vf].spoofchk;
2179-
ivf->linkstate = ionic->vfs[vf].linkstate;
2180-
ivf->max_tx_rate = le32_to_cpu(ionic->vfs[vf].maxrate);
2181-
ivf->trusted = ionic->vfs[vf].trusted;
2182-
ether_addr_copy(ivf->mac, ionic->vfs[vf].macaddr);
2245+
ivf->vf = vf;
2246+
ivf->qos = 0;
2247+
2248+
ret = ionic_update_cached_vf_config(ionic, vf);
2249+
if (!ret) {
2250+
ivf->vlan = le16_to_cpu(ionic->vfs[vf].vlanid);
2251+
ivf->spoofchk = ionic->vfs[vf].spoofchk;
2252+
ivf->linkstate = ionic->vfs[vf].linkstate;
2253+
ivf->max_tx_rate = le32_to_cpu(ionic->vfs[vf].maxrate);
2254+
ivf->trusted = ionic->vfs[vf].trusted;
2255+
ether_addr_copy(ivf->mac, ionic->vfs[vf].macaddr);
2256+
}
21832257
}
21842258

21852259
up_read(&ionic->vf_op_lock);

drivers/net/ethernet/pensando/ionic/ionic_main.c

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -188,6 +188,28 @@ static const char *ionic_opcode_to_str(enum ionic_cmd_opcode opcode)
188188
}
189189
}
190190

191+
const char *ionic_vf_attr_to_str(enum ionic_vf_attr attr)
192+
{
193+
switch (attr) {
194+
case IONIC_VF_ATTR_SPOOFCHK:
195+
return "IONIC_VF_ATTR_SPOOFCHK";
196+
case IONIC_VF_ATTR_TRUST:
197+
return "IONIC_VF_ATTR_TRUST";
198+
case IONIC_VF_ATTR_LINKSTATE:
199+
return "IONIC_VF_ATTR_LINKSTATE";
200+
case IONIC_VF_ATTR_MAC:
201+
return "IONIC_VF_ATTR_MAC";
202+
case IONIC_VF_ATTR_VLAN:
203+
return "IONIC_VF_ATTR_VLAN";
204+
case IONIC_VF_ATTR_RATE:
205+
return "IONIC_VF_ATTR_RATE";
206+
case IONIC_VF_ATTR_STATSADDR:
207+
return "IONIC_VF_ATTR_STATSADDR";
208+
default:
209+
return "IONIC_VF_ATTR_UNKNOWN";
210+
}
211+
}
212+
191213
static void ionic_adminq_flush(struct ionic_lif *lif)
192214
{
193215
struct ionic_desc_info *desc_info;

0 commit comments

Comments
 (0)