/* PCI config space info */
err = wx_sw_init(wx); if (err < 0) return err;
/* mac type, phy type , oem type */
ngbe_init_type_code(wx);
/* Set common capability flags and settings */
wx->max_q_vectors = NGBE_MAX_MSIX_VECTORS;
err = wx_get_pcie_msix_counts(wx, &msix_count, NGBE_MAX_MSIX_VECTORS); if (err)
dev_err(&pdev->dev, "Do not support MSI-X\n");
wx->mac.max_msix_vectors = msix_count;
eicr = wx_misc_isb(wx, WX_ISB_VEC0); if (!eicr) { /* shared interrupt alert! * the interrupt that we masked before the EICR read.
*/ if (netif_running(wx->netdev))
ngbe_irq_enable(wx, true); return IRQ_NONE; /* Not our interrupt */
}
wx->isb_mem[WX_ISB_VEC0] = 0; if (!(pdev->msi_enabled))
wr32(wx, WX_PX_INTA, 1);
eicr_misc = wx_misc_isb(wx, WX_ISB_MISC); if (unlikely(eicr_misc & NGBE_PX_MISC_IC_TIMESYNC))
wx_ptp_check_pps_event(wx);
wx->isb_mem[WX_ISB_MISC] = 0; /* would disable interrupts here but it is auto disabled */
napi_schedule_irqoff(&q_vector->napi);
if (netif_running(wx->netdev))
ngbe_irq_enable(wx, false);
/* Due to hardware design, when num_vfs < 7, pf can use 0 for misc and 1 * for queue. But when num_vfs == 7, vector[1] is assigned to vf6. * Misc and queue should reuse interrupt vector[0].
*/ if (test_bit(WX_FLAG_IRQ_VECTOR_SHARED, wx->flags))
err = request_irq(wx->msix_entry->vector,
ngbe_misc_and_queue, 0, netdev->name, wx); else
err = request_irq(wx->msix_entry->vector,
ngbe_msix_misc, 0, netdev->name, wx);
if (err) {
wx_err(wx, "request_irq for msix_other failed: %d\n", err); goto free_queue_irqs;
}
/* Mark all the VFs as inactive */ for (i = 0; i < wx->num_vfs; i++)
wx->vfinfo[i].clear_to_send = 0;
wx->notify_down = true; /* ping all the active vfs to let them know we are going down */
wx_ping_all_vfs_with_link_status(wx, false);
wx->notify_down = false;
/* Disable all VFTE/VFRE TX/RX */
wx_disable_vf_rx_tx(wx);
}
/* disable all enabled rx queues */ for (i = 0; i < wx->num_rx_queues; i++) /* this call also flushes the previous write */
wx_disable_rx_queue(wx, wx->rx_ring[i]); /* disable receives */
wx_disable_rx(wx);
wx_napi_disable_all(wx);
netif_tx_stop_all_queues(netdev);
netif_tx_disable(netdev); if (wx->gpio_ctrl)
ngbe_sfp_modules_txrx_powerctl(wx, false);
wx_irq_disable(wx); /* disable transmits in the hardware now that interrupts are off */ for (i = 0; i < wx->num_tx_queues; i++) {
u8 reg_idx = wx->tx_ring[i]->reg_idx;
/* make sure to complete pre-operations */
smp_mb__before_atomic();
wx_napi_enable_all(wx); /* enable transmits */
netif_tx_start_all_queues(wx->netdev);
/* clear any pending interrupts, may auto mask */
rd32(wx, WX_PX_IC(0));
rd32(wx, WX_PX_MISC_IC);
ngbe_irq_enable(wx, true); if (wx->gpio_ctrl)
ngbe_sfp_modules_txrx_powerctl(wx, true);
phylink_start(wx->phylink); /* Set PF Reset Done bit so PF/VF Mail Ops can work */
wr32m(wx, WX_CFG_PORT_CTL,
WX_CFG_PORT_CTL_PFRSTD, WX_CFG_PORT_CTL_PFRSTD); if (wx->num_vfs)
wx_ping_all_vfs_with_link_status(wx, false);
}
/** * ngbe_open - Called when a network interface is made active * @netdev: network interface device structure * * Returns 0 on success, negative value on failure * * The open entry point is called when a network interface is made * active by the system (IFF_UP).
**/ staticint ngbe_open(struct net_device *netdev)
{ struct wx *wx = netdev_priv(netdev); int err;
wx_control_hw(wx, true);
err = wx_setup_resources(wx); if (err) return err;
wx_configure(wx);
err = ngbe_request_irq(wx); if (err) goto err_free_resources;
err = phylink_connect_phy(wx->phylink, wx->phydev); if (err) goto err_free_irq;
err = netif_set_real_num_tx_queues(netdev, wx->num_tx_queues); if (err) goto err_dis_phy;
err = netif_set_real_num_rx_queues(netdev, wx->num_rx_queues); if (err) goto err_dis_phy;
/** * ngbe_close - Disables a network interface * @netdev: network interface device structure * * Returns 0, this is not allowed to fail * * The close entry point is called when an interface is de-activated * by the OS. The hardware is still under the drivers control, but * needs to be disabled. A global MAC reset is issued to stop the * hardware, and all transmit and receive resources are freed.
**/ staticint ngbe_close(struct net_device *netdev)
{ struct wx *wx = netdev_priv(netdev);
/** * ngbe_setup_tc - routine to configure net_device for multiple traffic * classes. * * @dev: net device to configure * @tc: number of traffic classes to enable
*/ int ngbe_setup_tc(struct net_device *dev, u8 tc)
{ struct wx *wx = netdev_priv(dev);
/* Hardware has to reinitialize queues and interrupts to * match packet buffer alignment. Unfortunately, the * hardware is not flexible enough to do this dynamically.
*/ if (netif_running(dev))
ngbe_close(dev);
wx_clear_interrupt_scheme(wx);
if (tc)
netdev_set_num_tc(dev, tc); else
netdev_reset_tc(dev);
/* The emerald supports up to 8 VFs per pf, but physical * function also need one pool for basic networking.
*/
pci_sriov_set_totalvfs(pdev, NGBE_MAX_VFS_DRV_LIMIT);
wx->driver_name = ngbe_driver_name;
ngbe_set_ethtool_ops(netdev);
netdev->netdev_ops = &ngbe_netdev_ops;
netdev->features = NETIF_F_SG | NETIF_F_IP_CSUM |
NETIF_F_TSO | NETIF_F_TSO6 |
NETIF_F_RXHASH | NETIF_F_RXCSUM;
netdev->features |= NETIF_F_SCTP_CRC | NETIF_F_TSO_MANGLEID;
netdev->vlan_features |= netdev->features;
netdev->features |= NETIF_F_IPV6_CSUM | NETIF_F_VLAN_FEATURES; /* copy netdev features into list of user selectable features */
netdev->hw_features |= netdev->features | NETIF_F_RXALL;
netdev->hw_features |= NETIF_F_NTUPLE | NETIF_F_HW_TC;
netdev->features |= NETIF_F_HIGHDMA;
netdev->hw_features |= NETIF_F_GRO;
netdev->features |= NETIF_F_GRO;
wx->bd_number = func_nums; /* setup the private structure */
err = ngbe_sw_init(wx); if (err) goto err_pci_release_regions;
/* check if flash load is done after hw power up */
err = wx_check_flash_load(wx, NGBE_SPI_ILDR_STATUS_PERST); if (err) goto err_free_mac_table;
err = wx_check_flash_load(wx, NGBE_SPI_ILDR_STATUS_PWRRST); if (err) goto err_free_mac_table;
err = wx_mng_present(wx); if (err) {
dev_err(&pdev->dev, "Management capability is not present\n"); goto err_free_mac_table;
}
wx_init_eeprom_params(wx); if (wx->bus.func == 0 || e2rom_cksum_cap == 0) { /* make sure the EEPROM is ready */
err = ngbe_eeprom_chksum_hostif(wx); if (err) {
dev_err(&pdev->dev, "The EEPROM Checksum Is Not Valid\n");
err = -EIO; goto err_free_mac_table;
}
}
wx->wol = 0; if (wx->wol_hw_supported)
wx->wol = NGBE_PSR_WKUP_CTL_MAG;
/* Save off EEPROM version number and Option Rom version which * together make a unique identify for the eeprom
*/ if (saved_ver) {
etrack_id = saved_ver;
} else {
wx_read_ee_hostif(wx,
wx->eeprom.sw_region_offset + NGBE_EEPROM_VERSION_H,
&e2rom_ver);
etrack_id = e2rom_ver << 16;
wx_read_ee_hostif(wx,
wx->eeprom.sw_region_offset + NGBE_EEPROM_VERSION_L,
&e2rom_ver);
etrack_id |= e2rom_ver;
wr32(wx, NGBE_EEPROM_VERSION_STORE_REG, etrack_id);
}
snprintf(wx->eeprom_id, sizeof(wx->eeprom_id), "0x%08x", etrack_id);
/** * ngbe_remove - Device Removal Routine * @pdev: PCI device information struct * * ngbe_remove is called by the PCI subsystem to alert the driver * that it should release a PCI device. The could be caused by a * Hot-Plug event, or because the driver is going to be removed from * memory.
**/ staticvoid ngbe_remove(struct pci_dev *pdev)
{ struct wx *wx = pci_get_drvdata(pdev); struct net_device *netdev;
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.