module_param_named(rss_cpus, efx_siena_rss_cpus, uint, 0444);
MODULE_PARM_DESC(rss_cpus, "Number of CPUs to use for Receive-Side Scaling");
/* *UseseparatechannelsforTXandRXevents * *Setthisto1touseseparatechannelsforTXandRX.Itallowsus *tocontrolinterruptaffinityseparatelyforTXandRX. * *ThisisonlyusedinMSI-Xinterruptmode
*/ bool efx_siena_separate_tx_channels;
module_param_named(efx_separate_tx_channels, efx_siena_separate_tx_channels, bool, 0444);
MODULE_PARM_DESC(efx_separate_tx_channels, "Use separate channels for TX and RX");
/* Initial interrupt moderation settings. They can be modified after *moduleloadwithethtool. * *ThedefaultforRXshouldstrikeabalancebetweenincreasingthe *round-triplatencyandreducingoverhead.
*/ staticunsignedint rx_irq_mod_usec = 60;
/* Initial interrupt moderation settings. They can be modified after *moduleloadwithethtool. * *Thisdefaultischosentoensurethata10Glinkdoesnotgoidle *whileaTXqueueisstoppedafterithasbecomefull.Aqueueis *restartedwhenitdropsbelowhalffull.Thetimethistakes(assuming *worstcase3descriptorsperpacketand1024descriptors)is *512/3*1.2=205usec.
*/ staticunsignedint tx_irq_mod_usec = 150;
#ifdef CONFIG_SFC_SIENA_SRIOV
rc = efx->type->vswitching_probe(efx); if (rc) /* not fatal; the PF will still work fine */
netif_warn(efx, probe, efx->net_dev, "failed to setup vswitching rc=%d;" " VFs may not function\n", rc); #endif
rc = efx_siena_probe_filters(efx); if (rc) {
netif_err(efx, probe, efx->net_dev, "failed to create filter tables\n"); goto fail4;
}
rc = efx_siena_probe_channels(efx); if (rc) goto fail5;
/* If channels are shared between RX and TX, so is IRQ *moderation.Otherwise,IRQmoderationisthesameforall *TXchannelsandisnotadaptive.
*/ if (efx->tx_channel_offset == 0) {
*tx_usecs = *rx_usecs;
} else { struct efx_channel *tx_channel;
if (efx->xdp_rxq_info_failed) {
netif_err(efx, drv, efx->net_dev, "Unable to bind XDP program due to previous failure of rxq_info\n"); return -EINVAL;
}
if (prog && efx->net_dev->mtu > efx_siena_xdp_max_mtu(efx)) {
netif_err(efx, drv, efx->net_dev, "Unable to configure XDP with MTU of %d (max: %d)\n",
efx->net_dev->mtu, efx_siena_xdp_max_mtu(efx)); return -EINVAL;
}
old_prog = rtnl_dereference(efx->xdp_prog);
rcu_assign_pointer(efx->xdp_prog, prog); /* Release the reference that was originally passed by the caller. */ if (old_prog)
bpf_prog_put(old_prog);
/* Enable resets to be scheduled and check whether any were *alreadyrequested.Ifso,theNICisprobablyhosedsowe *abort.
*/
efx->state = STATE_READY;
smp_mb(); /* ensure we change state before checking reset_pending */ if (efx->reset_pending) {
pci_err(efx->pci_dev, "aborting probe due to scheduled reset\n");
rc = -EIO; goto fail_locked;
}
rc = device_create_file(&efx->pci_dev->dev, &dev_attr_phy_type); if (rc) {
netif_err(efx, drv, efx->net_dev, "failed to init net dev attributes\n"); goto fail_registered;
}
efx_siena_init_mcdi_logging(efx);
return0;
fail_registered:
rtnl_lock();
efx_dissociate(efx);
unregister_netdevice(net_dev);
fail_locked:
efx->state = STATE_UNINIT;
rtnl_unlock();
netif_err(efx, drv, efx->net_dev, "could not register net dev\n"); return rc;
}
staticvoid efx_unregister_netdev(struct efx_nic *efx)
{ if (!efx->net_dev) return;
/* Main body of final NIC shutdown code *Thisiscalledonlyatmoduleunload(orhotplugremoval).
*/ staticvoid efx_pci_remove_main(struct efx_nic *efx)
{ /* Flush reset_work. It can no longer be scheduled since we *arenotREADY.
*/
BUG_ON(efx->state == STATE_READY);
efx_siena_flush_reset_workqueue(efx);
/* Final NIC shutdown *Thisiscalledonlyatmoduleunload(orhotplugremoval).APFcancall *thisonitsVFstoensuretheyareunboundfirst.
*/ staticvoid efx_pci_remove(struct pci_dev *pci_dev)
{ struct efx_nic *efx;
efx = pci_get_drvdata(pci_dev); if (!efx) return;
/* Mark the NIC as fini, then stop the interface */
rtnl_lock();
efx_dissociate(efx);
dev_close(efx->net_dev);
efx_siena_disable_interrupts(efx);
efx->state = STATE_UNINIT;
rtnl_unlock();
if (efx->type->sriov_fini)
efx->type->sriov_fini(efx);
/* NIC VPD information *Calledduringprobetodisplaythepartnumberofthe *installedNIC.
*/ staticvoid efx_probe_vpd_strings(struct efx_nic *efx)
{ struct pci_dev *dev = efx->pci_dev; unsignedint vpd_size, kw_len;
u8 *vpd_data; int start;
vpd_data = pci_vpd_alloc(dev, &vpd_size); if (IS_ERR(vpd_data)) {
pci_warn(dev, "Unable to read VPD\n"); return;
}
start = pci_vpd_find_ro_info_keyword(vpd_data, vpd_size,
PCI_VPD_RO_KEYWORD_PARTNO, &kw_len); if (start < 0)
pci_err(dev, "Part number not found or incomplete\n"); else
pci_info(dev, "Part Number : %.*s\n", kw_len, vpd_data + start);
start = pci_vpd_find_ro_info_keyword(vpd_data, vpd_size,
PCI_VPD_RO_KEYWORD_SERIALNO, &kw_len); if (start < 0)
pci_err(dev, "Serial number not found or incomplete\n"); else
efx->vpd_sn = kmemdup_nul(vpd_data + start, kw_len, GFP_KERNEL);
kfree(vpd_data);
}
/* Main body of NIC initialisation *Thisiscalledatmoduleload(orhotpluginsertion,theoretically).
*/ staticint efx_pci_probe_main(struct efx_nic *efx)
{ int rc;
/* Do start-of-day initialisation */
rc = efx_probe_all(efx); if (rc) goto fail1;
efx_siena_init_napi(efx);
down_write(&efx->filter_sem);
rc = efx->type->init(efx);
up_write(&efx->filter_sem); if (rc) {
pci_err(efx->pci_dev, "failed to initialise NIC\n"); goto fail3;
}
rc = efx_init_port(efx); if (rc) {
netif_err(efx, probe, efx->net_dev, "failed to initialise port\n"); goto fail4;
}
rc = efx_siena_init_interrupt(efx); if (rc) goto fail5;
efx_siena_set_interrupt_affinity(efx);
rc = efx_siena_enable_interrupts(efx); if (rc) goto fail6;
/* Disable receiving frames with bad FCS, by default. */
net_dev->features &= ~NETIF_F_RXALL;
/* Disable VLAN filtering by default. It may be enforced if *thefeatureisfixed(i.e.VLANfiltersarerequiredto *receiveVLANtaggedpacketsduetovPortrestrictions).
*/
net_dev->features &= ~NETIF_F_HW_VLAN_CTAG_FILTER;
net_dev->features |= efx->fixed_features;
if (!efx->type->is_vf)
efx_probe_vpd_strings(efx);
/* Set up basic I/O (BAR mappings etc) */
rc = efx_siena_init_io(efx, efx->type->mem_bar(efx),
efx->type->max_dma_mask,
efx->type->mem_map_size(efx)); if (rc) goto fail2;
rc = efx_pci_probe_post_io(efx); if (rc) { /* On failure, retry once immediately. *Ifweabortedprobeduetoascheduledreset,dismissit.
*/
efx->reset_pending = 0;
rc = efx_pci_probe_post_io(efx); if (rc) { /* On another failure, retry once more *aftera50-305msdelay.
*/ unsignedchar r;
/* efx_pci_sriov_configure returns the actual number of Virtual Functions *enabledonsuccess
*/ #ifdef CONFIG_SFC_SIENA_SRIOV staticint efx_pci_sriov_configure(struct pci_dev *dev, int num_vfs)
{ int rc; struct efx_nic *efx = pci_get_drvdata(dev);
if (efx->type->sriov_configure) {
rc = efx->type->sriov_configure(efx, num_vfs); if (rc) return rc; else return num_vfs;
} else return -EOPNOTSUPP;
} #endif
/* Used for both resume and restore */ staticint efx_pm_resume(struct device *dev)
{ struct pci_dev *pci_dev = to_pci_dev(dev); struct efx_nic *efx = pci_get_drvdata(pci_dev); int rc;
rc = pci_set_power_state(pci_dev, PCI_D0); if (rc) return rc;
pci_restore_state(pci_dev);
rc = pci_enable_device(pci_dev); if (rc) return rc;
pci_set_master(efx->pci_dev);
rc = efx->type->reset(efx, RESET_TYPE_ALL); if (rc) return rc;
down_write(&efx->filter_sem);
rc = efx->type->init(efx);
up_write(&efx->filter_sem); if (rc) return rc;
rc = efx_pm_thaw(dev); return rc;
}
staticint efx_pm_suspend(struct device *dev)
{ int rc;
efx_pm_freeze(dev);
rc = efx_pm_poweroff(dev); if (rc)
efx_pm_resume(dev); return rc;
}
MODULE_AUTHOR("Solarflare Communications and " "Michael Brown <mbrown@fensystems.co.uk>");
MODULE_DESCRIPTION("Solarflare Siena network driver");
MODULE_LICENSE("GPL");
MODULE_DEVICE_TABLE(pci, efx_pci_table);
Messung V0.5 in Prozent
¤ Dauer der Verarbeitung: 0.23 Sekunden
(vorverarbeitet am 2026-09-28)
¤
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.