if (adapter->xdp_prog) {
e_warn(probe, "SRIOV is not supported with XDP\n"); return -EINVAL;
}
/* Enable VMDq flag so device will be set in VM mode */
adapter->flags |= IXGBE_FLAG_SRIOV_ENABLED |
IXGBE_FLAG_VMDQ_ENABLED;
/* Allocate memory for per VF control structures */
adapter->vfinfo = kcalloc(num_vfs, sizeof(struct vf_data_storage),
GFP_KERNEL); if (!adapter->vfinfo) return -ENOMEM;
/* Disable RSC when in SR-IOV mode */
adapter->flags2 &= ~(IXGBE_FLAG2_RSC_CAPABLE |
IXGBE_FLAG2_RSC_ENABLED);
for (i = 0; i < num_vfs; i++) { /* enable spoof checking for all VFs */
adapter->vfinfo[i].spoofchk_enabled = true;
adapter->vfinfo[i].link_enable = true;
/* We support VF RSS querying only for 82599 and x540 *devicesatthemoment.ThesedevicesshareRSS *indirectiontableandRSShashkeywithPFtherefore *wewanttodisablethequeryingbydefault.
*/
adapter->vfinfo[i].rss_query_enabled = false;
/* Untrust all VFs */
adapter->vfinfo[i].trusted = false;
/* set the default xcast mode */
adapter->vfinfo[i].xcast_mode = IXGBEVF_XCAST_MODE_NONE;
}
e_info(probe, "SR-IOV enabled with %d VFs\n", num_vfs); return0;
}
vfdev = pci_get_device(vendor, vf_id, NULL); for (; vfdev; vfdev = pci_get_device(vendor, vf_id, vfdev)) { if (!vfdev->is_virtfn) continue; if (vfdev->physfn != pdev) continue; if (vf >= adapter->num_vfs) continue;
pci_dev_get(vfdev);
adapter->vfinfo[vf].vfdev = vfdev;
++vf;
}
}
/* Note this function is called when the user wants to enable SR-IOV *VFsusingthenowdeprecatedmoduleparameter
*/ void ixgbe_enable_sriov(struct ixgbe_adapter *adapter, unsignedint max_vfs)
{ int pre_existing_vfs = 0; unsignedint num_vfs;
pre_existing_vfs = pci_num_vf(adapter->pdev); if (!pre_existing_vfs && !max_vfs) return;
/* If there are pre-existing VFs then we have to force *useofthatmany-overrideanymoduleparametervalue. *ThismayresultfromtheuserunloadingthePFdriver *whileVFswereassignedtoguestVMsorbecausetheVFs *havebeencreatedviathenewPCISR-IOVsysfsinterface.
*/ if (pre_existing_vfs) {
num_vfs = pre_existing_vfs;
dev_warn(&adapter->pdev->dev, "Virtual Functions already enabled for this device - Please reload all VF drivers to avoid spoofed packet errors\n");
} else { int err; /* *The82599supportsupto64VFsperphysicalfunction *butthisimplementationlimitsallocationto63sothat *basicnetworkingresourcesarestillavailabletothe *physicalfunction.Iftheuserrequestsgreaterthan *63VFsthenitisanerror-resettodefaultofzero.
*/
num_vfs = min_t(unsignedint, max_vfs, IXGBE_MAX_VFS_DRV_LIMIT);
err = pci_enable_sriov(adapter->pdev, num_vfs); if (err) {
e_err(probe, "Failed to enable PCI sriov: %d\n", err); return;
}
}
if (!__ixgbe_enable_sriov(adapter, num_vfs)) {
ixgbe_get_vfs(adapter); return;
}
/* If we have gotten to this point then there is no memory available *tomanagetheVFdevices-printmessageandbail.
*/
e_err(probe, "Unable to allocate memory for VF Data Storage - " "SRIOV disabled\n");
ixgbe_disable_sriov(adapter);
}
spin_lock_irqsave(&adapter->vfs_lock, flags); /* set num VFs to 0 to prevent access to vfinfo */
adapter->num_vfs = 0;
spin_unlock_irqrestore(&adapter->vfs_lock, flags);
/* put the reference to all of the vf devices */ for (vf = 0; vf < num_vfs; ++vf) { struct pci_dev *vfdev = adapter->vfinfo[vf].vfdev;
if (!vfdev) continue;
adapter->vfinfo[vf].vfdev = NULL;
pci_dev_put(vfdev);
}
/* free VF control structures */
kfree(adapter->vfinfo);
adapter->vfinfo = NULL;
/* free macvlan list */
kfree(adapter->mv_list);
adapter->mv_list = NULL;
/* if SR-IOV is already disabled then there is nothing to do */ if (!(adapter->flags & IXGBE_FLAG_SRIOV_ENABLED)) return0;
if (hw->mac.ops.disable_mdd)
hw->mac.ops.disable_mdd(hw);
#ifdef CONFIG_PCI_IOV /* *IfourVFsareassignedwecannotshutdownSR-IOV *withoutcausingissues,sojustleavethehardware *availablebutdisabled
*/ if (pci_vfs_assigned(adapter->pdev)) {
e_dev_warn("Unloading driver while VFs are assigned - VFs will not be deallocated\n"); return -EPERM;
} /* disable iov and allow time for transactions to clear */
pci_disable_sriov(adapter->pdev); #endif
/* Disable VMDq flag so device will be set in VM mode */ if (bitmap_weight(adapter->fwd_bitmask, adapter->num_rx_pools) == 1) {
adapter->flags &= ~IXGBE_FLAG_VMDQ_ENABLED;
adapter->flags &= ~IXGBE_FLAG_SRIOV_ENABLED;
rss = min_t(int, ixgbe_max_rss_indices(adapter),
num_online_cpus());
} else {
rss = min_t(int, IXGBE_MAX_L2A_QUEUES, num_online_cpus());
}
/* While the SR-IOV capability structure reports total VFs to be 64, *welimittheactualnumberallocatedasbelowbasedontwofactors. *Num_TCsMAX_VFs *163 *<=431 *>415 *First,wereservesometransmit/receiveresourcesforthePF. *Second,VMDQalsousesthesamepoolsthatSR-IOVdoes.Weneedto *accountforthis,sothatwedon'taccidentallyallocatemoreVFs *thanwehaveavailablepools.ThePCIbusdriveralreadychecksfor *othervaluesoutofrange.
*/
num_tc = adapter->hw_tcs;
num_rx_pools = bitmap_weight(adapter->fwd_bitmask,
adapter->num_rx_pools);
limit = (num_tc > 4) ? IXGBE_MAX_VFS_8TC :
(num_tc > 1) ? IXGBE_MAX_VFS_4TC : IXGBE_MAX_VFS_1TC;
if (num_vfs > (limit - num_rx_pools)) {
e_dev_err("Currently configured with %d TCs, and %d offloaded macvlans. Creating more than %d VFs is not allowed\n",
num_tc, num_rx_pools - 1, limit - num_rx_pools); return -EPERM;
}
err = __ixgbe_enable_sriov(adapter, num_vfs); if (err) return err;
for (i = 0; i < num_vfs; i++)
ixgbe_vf_configuration(dev, (i | 0x10000000));
/* reset before enabling SRIOV to avoid mailbox issues */
ixgbe_sriov_reinit(adapter);
err = pci_enable_sriov(dev, num_vfs); if (err) {
e_dev_warn("Failed to enable PCI sriov: %d\n", err); return err;
}
ixgbe_get_vfs(adapter);
/* Only reinit if no error and state changed */ #ifdef CONFIG_PCI_IOV if (!err && (current_flags != adapter->flags ||
prev_num_vf != pci_num_vf(dev)))
ixgbe_sriov_reinit(adapter); #endif
return err;
}
int ixgbe_pci_sriov_configure(struct pci_dev *dev, int num_vfs)
{ if (num_vfs == 0) return ixgbe_pci_sriov_disable(dev); else return ixgbe_pci_sriov_enable(dev, num_vfs);
}
/* Restore any VF macvlans */
ixgbe_full_sync_mac_table(adapter);
} #endif
staticint ixgbe_set_vf_vlan(struct ixgbe_adapter *adapter, int add, int vid,
u32 vf)
{ struct ixgbe_hw *hw = &adapter->hw; int err;
/* If VLAN overlaps with one the PF is currently monitoring make *surethatweareabletoallocateaVLVFentry.Thismaybe *redundantbutitguaranteesPFwillmaintainvisibilityto *theVLAN.
*/ if (add && test_bit(vid, adapter->active_vlans)) {
err = hw->mac.ops.set_vfta(hw, vid, VMDQ_P(0), true, false); if (err) return err;
}
/* If we failed to add the VF VLAN or we are removing the VF VLAN *wemayneedtodropthePFpoolbitinordertoallowustofree *uptheVLVFresources.
*/ if (test_bit(vid, adapter->active_vlans) ||
(adapter->flags2 & IXGBE_FLAG2_VLAN_PROMISC))
ixgbe_update_pf_promisc_vlvf(adapter, vid);
#ifdef CONFIG_FCOE if (dev->fcoe_mtu)
pf_max_frame = max_t(int, pf_max_frame,
IXGBE_FCOE_JUMBO_FRAME_SIZE);
#endif/* CONFIG_FCOE */ switch (adapter->vfinfo[vf].vf_api) { case ixgbe_mbox_api_11: case ixgbe_mbox_api_12: case ixgbe_mbox_api_13: case ixgbe_mbox_api_14: case ixgbe_mbox_api_16: case ixgbe_mbox_api_17: /* Version 1.1 supports jumbo frames on VFs if PF has *jumboframesenabledwhichmeanslegacyVFsare *disabled
*/ if (pf_max_frame > ETH_FRAME_LEN) break;
fallthrough; default: /* If the PF or VF are running w/ jumbo frames enabled *weneedtoshutdowntheVFRxpathaswecannot *supportjumboframesonlegacyVFs
*/ if ((pf_max_frame > ETH_FRAME_LEN) ||
(max_frame > (ETH_FRAME_LEN + ETH_FCS_LEN)))
err = -EINVAL; break;
}
for (i = vf * q_per_pool; i < ((vf + 1) * q_per_pool); i++) {
u32 reg;
/* flush previous write */
IXGBE_WRITE_FLUSH(hw);
/* indicate to hardware that we want to set drop enable */
reg = IXGBE_QDE_WRITE | qde;
reg |= i << IXGBE_QDE_IDX_SHIFT;
IXGBE_WRITE_REG(hw, IXGBE_QDE, reg);
}
}
/* The 82599 cannot support a mix of jumbo and non-jumbo PF/VFs. *Formoreinfotakealookatixgbe_set_vf_lpe
*/ if (adapter->hw.mac.type == ixgbe_mac_82599EB) { struct net_device *dev = adapter->netdev; int pf_max_frame = dev->mtu + ETH_HLEN;
if (!is_valid_ether_addr(new_mac)) {
e_warn(drv, "VF %d attempted to set invalid mac\n", vf); return -1;
}
if (adapter->vfinfo[vf].pf_set_mac && !adapter->vfinfo[vf].trusted &&
!ether_addr_equal(adapter->vfinfo[vf].vf_mac_addresses, new_mac)) {
e_warn(drv, "VF %d attempted to override administratively set MAC address\n" "Reload the VF driver to resume operations\n",
vf); return -1;
}
staticint ixgbe_set_vf_macvlan_msg(struct ixgbe_adapter *adapter,
u32 *msgbuf, u32 vf)
{
u8 *new_mac = ((u8 *)(&msgbuf[1])); int index = FIELD_GET(IXGBE_VT_MSGINFO_MASK, msgbuf[0]); int err;
if (adapter->vfinfo[vf].pf_set_mac && !adapter->vfinfo[vf].trusted &&
index > 0) {
e_warn(drv, "VF %d requested MACVLAN filter but is administratively denied\n",
vf); return -1;
}
/* An non-zero index indicates the VF is setting a filter */ if (index) { if (!is_valid_ether_addr(new_mac)) {
e_warn(drv, "VF %d attempted to set invalid mac\n", vf); return -1;
}
err = ixgbe_set_vf_macvlan(adapter, vf, index, new_mac); if (err == -ENOSPC)
e_warn(drv, "VF %d has requested a MACVLAN filter but there is no space for it\n",
vf);
return err < 0;
}
staticint ixgbe_negotiate_vf_api(struct ixgbe_adapter *adapter,
u32 *msgbuf, u32 vf)
{ int api = msgbuf[1];
switch (api) { case ixgbe_mbox_api_10: case ixgbe_mbox_api_11: case ixgbe_mbox_api_12: case ixgbe_mbox_api_13: case ixgbe_mbox_api_14: case ixgbe_mbox_api_16: case ixgbe_mbox_api_17:
adapter->vfinfo[vf].vf_api = api; return0; default: break;
}
e_dbg(drv, "VF %d requested unsupported api version %u\n", vf, api);
/* verify the PF is supporting the correct APIs */ switch (adapter->vfinfo[vf].vf_api) { case ixgbe_mbox_api_20: case ixgbe_mbox_api_11: case ixgbe_mbox_api_12: case ixgbe_mbox_api_13: case ixgbe_mbox_api_14: case ixgbe_mbox_api_16: case ixgbe_mbox_api_17: break; default: return -1;
}
/* only allow 1 Tx queue for bandwidth limiting */
msgbuf[IXGBE_VF_TX_QUEUES] = __ALIGN_MASK(1, ~vmdq->mask);
msgbuf[IXGBE_VF_RX_QUEUES] = __ALIGN_MASK(1, ~vmdq->mask);
/* if TCs > 1 determine which TC belongs to default user priority */ if (num_tcs > 1)
default_tc = netdev_get_prio_tc_map(dev, adapter->default_up);
/* notify VF of need for VLAN tag stripping, and correct queue */ if (num_tcs)
msgbuf[IXGBE_VF_TRANS_VLAN] = num_tcs; elseif (adapter->vfinfo[vf].pf_vlan || adapter->vfinfo[vf].pf_qos)
msgbuf[IXGBE_VF_TRANS_VLAN] = 1; else
msgbuf[IXGBE_VF_TRANS_VLAN] = 0;
/* notify VF of default queue */
msgbuf[IXGBE_VF_DEF_QUEUE] = default_tc;
/* Check if operation is permitted */ if (!adapter->vfinfo[vf].rss_query_enabled) return -EPERM;
/* verify the PF is supporting the correct API */ switch (adapter->vfinfo[vf].vf_api) { case ixgbe_mbox_api_17: case ixgbe_mbox_api_16: case ixgbe_mbox_api_14: case ixgbe_mbox_api_13: case ixgbe_mbox_api_12: break; default: return -EOPNOTSUPP;
}
/* This mailbox command is supported (required) only for 82599 and x540 *VFswhichsupportupto4RSSqueues.Thereforewewillcompressthe *RETAbysavingonly2bitsfromeachentry.Thiswaywewillbeable *totransferthewholeRETAinasinglemailboxoperation.
*/ for (i = 0; i < reta_size / 16; i++) {
out_buf[i] = 0; for (j = 0; j < 16; j++)
out_buf[i] |= (u32)(reta[16 * i + j] & 0x3) << (2 * j);
}
/* Check if the operation is permitted */ if (!adapter->vfinfo[vf].rss_query_enabled) return -EPERM;
/* verify the PF is supporting the correct API */ switch (adapter->vfinfo[vf].vf_api) { case ixgbe_mbox_api_17: case ixgbe_mbox_api_16: case ixgbe_mbox_api_14: case ixgbe_mbox_api_13: case ixgbe_mbox_api_12: break; default: return -EOPNOTSUPP;
}
/* verify the PF is supporting the correct APIs */ switch (adapter->vfinfo[vf].vf_api) { case ixgbe_mbox_api_12: /* promisc introduced in 1.3 version */ if (xcast_mode == IXGBEVF_XCAST_MODE_PROMISC) return -EOPNOTSUPP;
fallthrough; case ixgbe_mbox_api_13: case ixgbe_mbox_api_14: case ixgbe_mbox_api_16: case ixgbe_mbox_api_17: break; default: return -EOPNOTSUPP;
}
/* verify the PF is supporting the correct API */ switch (adapter->vfinfo[vf].vf_api) { case ixgbe_mbox_api_12: case ixgbe_mbox_api_13: case ixgbe_mbox_api_14: case ixgbe_mbox_api_16: case ixgbe_mbox_api_17: break; default: return -EOPNOTSUPP;
}
switch (adapter->vfinfo[vf].vf_api) { case ixgbe_mbox_api_16: case ixgbe_mbox_api_17: if (hw->mac.type != ixgbe_mac_e610) return -EOPNOTSUPP; break; default: return -EOPNOTSUPP;
} /* Simply provide stored values as watchdog & link status events take *careofitsfreshness.
*/
msgbuf[1] = adapter->link_speed;
msgbuf[2] = adapter->link_up;
for (i = 0 ; i < adapter->num_vfs; i++)
ixgbe_set_vf_link_state(adapter, i,
adapter->vfinfo[i].link_state);
}
int ixgbe_ndo_set_vf_mac(struct net_device *netdev, int vf, u8 *mac)
{ struct ixgbe_adapter *adapter = ixgbe_from_netdev(netdev); int retval;
if (vf >= adapter->num_vfs) return -EINVAL;
if (is_valid_ether_addr(mac)) {
dev_info(&adapter->pdev->dev, "setting MAC %pM on VF %d\n",
mac, vf);
dev_info(&adapter->pdev->dev, "Reload the VF driver to make this change effective.");
if (test_bit(__IXGBE_DOWN, &adapter->state)) {
dev_warn(&adapter->pdev->dev, "The VF MAC address has been set, but the PF device is not up.\n");
dev_warn(&adapter->pdev->dev, "Bring the PF device up before attempting to use the VF device.\n");
}
} else {
dev_warn(&adapter->pdev->dev, "The VF MAC address was NOT set due to invalid or duplicate MAC address.\n");
}
} elseif (is_zero_ether_addr(mac)) { unsignedchar *vf_mac_addr =
adapter->vfinfo[vf].vf_mac_addresses;
/* nothing to do */ if (is_zero_ether_addr(vf_mac_addr)) return0;
dev_info(&adapter->pdev->dev, "removing MAC on VF %d\n", vf);
retval = ixgbe_del_mac_filter(adapter, vf_mac_addr, vf); if (retval >= 0) {
adapter->vfinfo[vf].pf_set_mac = false;
memcpy(vf_mac_addr, mac, ETH_ALEN);
} else {
dev_warn(&adapter->pdev->dev, "Could NOT remove the VF MAC address.\n");
}
} else {
retval = -EINVAL;
}
return retval;
}
staticint ixgbe_enable_port_vlan(struct ixgbe_adapter *adapter, int vf,
u16 vlan, u8 qos)
{ struct ixgbe_hw *hw = &adapter->hw; int err;
err = ixgbe_set_vf_vlan(adapter, true, vlan, vf); if (err) goto out;
/* enable hide vlan on X550 */ if (hw->mac.type >= ixgbe_mac_X550)
ixgbe_write_qde(adapter, vf, IXGBE_QDE_ENABLE |
IXGBE_QDE_HIDE_VLAN);
adapter->vfinfo[vf].pf_vlan = vlan;
adapter->vfinfo[vf].pf_qos = qos;
dev_info(&adapter->pdev->dev, "Setting VLAN %d, QOS 0x%x on VF %d\n", vlan, qos, vf); if (test_bit(__IXGBE_DOWN, &adapter->state)) {
dev_warn(&adapter->pdev->dev, "The VF VLAN has been set, but the PF device is not up.\n");
dev_warn(&adapter->pdev->dev, "Bring the PF device up before attempting to use the VF device.\n");
}
out: return err;
}
staticint ixgbe_disable_port_vlan(struct ixgbe_adapter *adapter, int vf)
{ struct ixgbe_hw *hw = &adapter->hw; int err;
void ixgbe_check_vf_rate_limit(struct ixgbe_adapter *adapter)
{ int i;
/* VF Tx rate limit was not set */ if (!adapter->vf_rate_link_speed) return;
if (ixgbe_link_mbps(adapter) != adapter->vf_rate_link_speed) {
adapter->vf_rate_link_speed = 0;
dev_info(&adapter->pdev->dev, "Link speed has been changed. VF Transmit rate is disabled\n");
}
for (i = 0; i < adapter->num_vfs; i++) { if (!adapter->vf_rate_link_speed)
adapter->vfinfo[i].tx_rate = 0;
ixgbe_set_vf_rate_limit(adapter, i);
}
}
int ixgbe_ndo_set_vf_bw(struct net_device *netdev, int vf, int min_tx_rate, int max_tx_rate)
{ struct ixgbe_adapter *adapter = ixgbe_from_netdev(netdev); int link_speed;
/* verify VF is active */ if (vf >= adapter->num_vfs) return -EINVAL;
/* verify link is up */ if (!adapter->link_up) return -EINVAL;
/* verify we are linked at 10Gbps */
link_speed = ixgbe_link_mbps(adapter); if (link_speed != 10000) return -EINVAL;
if (min_tx_rate) return -EINVAL;
/* rate limit cannot be less than 10Mbs or greater than link speed */ if (max_tx_rate && ((max_tx_rate <= 10) || (max_tx_rate > link_speed))) return -EINVAL;
/* store values */
adapter->vf_rate_link_speed = link_speed;
adapter->vfinfo[vf].tx_rate = max_tx_rate;
/* Ensure LLDP and FC is set for Ethertype Antispoofing if we will be *callingset_ethertype_anti_spoofingforeachVFinloopbelow
*/ if (hw->mac.ops.set_ethertype_anti_spoofing) {
IXGBE_WRITE_REG(hw, IXGBE_ETQF(IXGBE_ETQF_FILTER_LLDP),
(IXGBE_ETQF_FILTER_EN |
IXGBE_ETQF_TX_ANTISPOOF |
ETH_P_LLDP));
/** *ixgbe_ndo_set_vf_link_state-Setlinkstate *@netdev:networkinterfacedevicestructure *@vf:VFidentifier *@state:requiredlinkstate * *SetthelinkstateofaspecifiedVF,regardlessofphysicallinkstate
**/ int ixgbe_ndo_set_vf_link_state(struct net_device *netdev, int vf, int state)
{ struct ixgbe_adapter *adapter = ixgbe_from_netdev(netdev); int ret = 0;
if (vf < 0 || vf >= adapter->num_vfs) {
dev_err(&adapter->pdev->dev, "NDO set VF link - invalid VF identifier %d\n", vf); return -EINVAL;
}
switch (state) { case IFLA_VF_LINK_STATE_ENABLE:
dev_info(&adapter->pdev->dev, "NDO set VF %d link state %d - not supported\n",
vf, state); break; case IFLA_VF_LINK_STATE_DISABLE:
dev_info(&adapter->pdev->dev, "NDO set VF %d link state disable\n", vf);
ixgbe_set_vf_link_state(adapter, vf, state); break; case IFLA_VF_LINK_STATE_AUTO:
dev_info(&adapter->pdev->dev, "NDO set VF %d link state auto\n", vf);
ixgbe_set_vf_link_state(adapter, vf, state); break; default:
dev_err(&adapter->pdev->dev, "NDO set VF %d - invalid link state %d\n", vf, state);
ret = -EINVAL;
}
return ret;
}
int ixgbe_ndo_set_vf_rss_query_en(struct net_device *netdev, int vf, bool setting)
{ struct ixgbe_adapter *adapter = ixgbe_from_netdev(netdev);
/* This operation is currently supported only for 82599 and x540 *devices.
*/ if (adapter->hw.mac.type < ixgbe_mac_82599EB ||
adapter->hw.mac.type >= ixgbe_mac_X550) return -EOPNOTSUPP;
if (vf >= adapter->num_vfs) return -EINVAL;
adapter->vfinfo[vf].rss_query_enabled = setting;
return0;
}
int ixgbe_ndo_set_vf_trust(struct net_device *netdev, int vf, bool setting)
{ struct ixgbe_adapter *adapter = ixgbe_from_netdev(netdev);
if (vf >= adapter->num_vfs) return -EINVAL;
/* nothing to do */ if (adapter->vfinfo[vf].trusted == setting) return0;
adapter->vfinfo[vf].trusted = setting;
/* reset VF to reconfigure features */
adapter->vfinfo[vf].clear_to_send = false;
ixgbe_ping_vf(adapter, vf);
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.