diff options
| -rw-r--r-- | drivers/net/ethernet/sfc/ef10.c | 4 | ||||
| -rw-r--r-- | drivers/net/ethernet/sfc/ef100.c | 69 | ||||
| -rw-r--r-- | drivers/net/ethernet/sfc/ef100_ethtool.c | 2 | ||||
| -rw-r--r-- | drivers/net/ethernet/sfc/ef100_netdev.c | 130 | ||||
| -rw-r--r-- | drivers/net/ethernet/sfc/ef100_netdev.h | 4 | ||||
| -rw-r--r-- | drivers/net/ethernet/sfc/ef100_nic.c | 422 | ||||
| -rw-r--r-- | drivers/net/ethernet/sfc/ef100_nic.h | 10 | ||||
| -rw-r--r-- | drivers/net/ethernet/sfc/efx.c | 73 | ||||
| -rw-r--r-- | drivers/net/ethernet/sfc/efx_common.c | 77 | ||||
| -rw-r--r-- | drivers/net/ethernet/sfc/efx_common.h | 16 | ||||
| -rw-r--r-- | drivers/net/ethernet/sfc/ethtool.c | 22 | ||||
| -rw-r--r-- | drivers/net/ethernet/sfc/ethtool_common.c | 50 | ||||
| -rw-r--r-- | drivers/net/ethernet/sfc/mcdi.c | 15 | ||||
| -rw-r--r-- | drivers/net/ethernet/sfc/mcdi_port.c | 4 | ||||
| -rw-r--r-- | drivers/net/ethernet/sfc/net_driver.h | 69 | ||||
| -rw-r--r-- | drivers/net/ethernet/sfc/rx_common.c | 4 | ||||
| -rw-r--r-- | drivers/net/ethernet/sfc/sriov.c | 10 | ||||
| -rw-r--r-- | drivers/net/ethernet/sfc/tx.c | 4 |
18 files changed, 554 insertions, 431 deletions
diff --git a/drivers/net/ethernet/sfc/ef10.c b/drivers/net/ethernet/sfc/ef10.c index 186cb28c03bd..a99c3a6b912c 100644 --- a/drivers/net/ethernet/sfc/ef10.c +++ b/drivers/net/ethernet/sfc/ef10.c @@ -3874,7 +3874,7 @@ static int efx_ef10_udp_tnl_set_port(struct net_device *dev, unsigned int table, unsigned int entry, struct udp_tunnel_info *ti) { - struct efx_nic *efx = netdev_priv(dev); + struct efx_nic *efx = efx_netdev_priv(dev); struct efx_ef10_nic_data *nic_data; int efx_tunnel_type, rc; @@ -3934,7 +3934,7 @@ static int efx_ef10_udp_tnl_unset_port(struct net_device *dev, unsigned int table, unsigned int entry, struct udp_tunnel_info *ti) { - struct efx_nic *efx = netdev_priv(dev); + struct efx_nic *efx = efx_netdev_priv(dev); struct efx_ef10_nic_data *nic_data; int rc; diff --git a/drivers/net/ethernet/sfc/ef100.c b/drivers/net/ethernet/sfc/ef100.c index 173f0ecebc70..425017fbcb25 100644 --- a/drivers/net/ethernet/sfc/ef100.c +++ b/drivers/net/ethernet/sfc/ef100.c @@ -423,65 +423,58 @@ static int ef100_pci_find_func_ctrl_window(struct efx_nic *efx, */ static void ef100_pci_remove(struct pci_dev *pci_dev) { - struct efx_nic *efx; + struct efx_nic *efx = pci_get_drvdata(pci_dev); + struct efx_probe_data *probe_data; - efx = pci_get_drvdata(pci_dev); if (!efx) return; - rtnl_lock(); - dev_close(efx->net_dev); - rtnl_unlock(); - - /* Unregistering our netdev notifier triggers unbinding of TC indirect - * blocks, so we have to do it before PCI removal. - */ - unregister_netdevice_notifier(&efx->netdev_notifier); -#if defined(CONFIG_SFC_SRIOV) - if (!efx->type->is_vf) - efx_ef100_pci_sriov_disable(efx); -#endif + probe_data = container_of(efx, struct efx_probe_data, efx); + ef100_remove_netdev(probe_data); + ef100_remove(efx); efx_fini_io(efx); - netif_dbg(efx, drv, efx->net_dev, "shutdown successful\n"); - pci_set_drvdata(pci_dev, NULL); - efx_fini_struct(efx); - free_netdev(efx->net_dev); + pci_dbg(pci_dev, "shutdown successful\n"); pci_disable_pcie_error_reporting(pci_dev); + + pci_set_drvdata(pci_dev, NULL); + efx_fini_struct(efx); + kfree(probe_data); }; static int ef100_pci_probe(struct pci_dev *pci_dev, const struct pci_device_id *entry) { struct ef100_func_ctl_window fcw = { 0 }; - struct net_device *net_dev; + struct efx_probe_data *probe_data; struct efx_nic *efx; int rc; - /* Allocate and initialise a struct net_device and struct efx_nic */ - net_dev = alloc_etherdev_mq(sizeof(*efx), EFX_MAX_CORE_TX_QUEUES); - if (!net_dev) + /* Allocate probe data and struct efx_nic */ + probe_data = kzalloc(sizeof(*probe_data), GFP_KERNEL); + if (!probe_data) return -ENOMEM; - efx = netdev_priv(net_dev); + probe_data->pci_dev = pci_dev; + efx = &probe_data->efx; + efx->type = (const struct efx_nic_type *)entry->driver_data; + efx->pci_dev = pci_dev; pci_set_drvdata(pci_dev, efx); - SET_NETDEV_DEV(net_dev, &pci_dev->dev); - rc = efx_init_struct(efx, pci_dev, net_dev); + rc = efx_init_struct(efx, pci_dev); if (rc) goto fail; efx->vi_stride = EF100_DEFAULT_VI_STRIDE; - netif_info(efx, probe, efx->net_dev, - "Solarflare EF100 NIC detected\n"); + pci_info(pci_dev, "Solarflare EF100 NIC detected\n"); rc = ef100_pci_find_func_ctrl_window(efx, &fcw); if (rc) { - netif_err(efx, probe, efx->net_dev, - "Error looking for ef100 function control window, rc=%d\n", - rc); + pci_err(pci_dev, + "Error looking for ef100 function control window, rc=%d\n", + rc); goto fail; } @@ -493,8 +486,7 @@ static int ef100_pci_probe(struct pci_dev *pci_dev, } if (fcw.offset > pci_resource_len(efx->pci_dev, fcw.bar) - ESE_GZ_FCW_LEN) { - netif_err(efx, probe, efx->net_dev, - "Func control window overruns BAR\n"); + pci_err(pci_dev, "Func control window overruns BAR\n"); rc = -EIO; goto fail; } @@ -508,19 +500,16 @@ static int ef100_pci_probe(struct pci_dev *pci_dev, efx->reg_base = fcw.offset; - efx->netdev_notifier.notifier_call = ef100_netdev_event; - rc = register_netdevice_notifier(&efx->netdev_notifier); - if (rc) { - netif_err(efx, probe, efx->net_dev, - "Failed to register netdevice notifier, rc=%d\n", rc); + rc = efx->type->probe(efx); + if (rc) goto fail; - } - rc = efx->type->probe(efx); + efx->state = STATE_PROBED; + rc = ef100_probe_netdev(probe_data); if (rc) goto fail; - netif_dbg(efx, probe, efx->net_dev, "initialisation successful\n"); + pci_dbg(pci_dev, "initialisation successful\n"); return 0; diff --git a/drivers/net/ethernet/sfc/ef100_ethtool.c b/drivers/net/ethernet/sfc/ef100_ethtool.c index 5dba4125d953..702abbe59b76 100644 --- a/drivers/net/ethernet/sfc/ef100_ethtool.c +++ b/drivers/net/ethernet/sfc/ef100_ethtool.c @@ -26,7 +26,7 @@ ef100_ethtool_get_ringparam(struct net_device *net_dev, struct kernel_ethtool_ringparam *kernel_ring, struct netlink_ext_ack *extack) { - struct efx_nic *efx = netdev_priv(net_dev); + struct efx_nic *efx = efx_netdev_priv(net_dev); ring->rx_max_pending = EFX_EF100_MAX_DMAQ_SIZE; ring->tx_max_pending = EFX_EF100_MAX_DMAQ_SIZE; diff --git a/drivers/net/ethernet/sfc/ef100_netdev.c b/drivers/net/ethernet/sfc/ef100_netdev.c index 67fe44db6b61..060392ddd612 100644 --- a/drivers/net/ethernet/sfc/ef100_netdev.c +++ b/drivers/net/ethernet/sfc/ef100_netdev.c @@ -22,6 +22,7 @@ #include "ef100_regs.h" #include "mcdi_filters.h" #include "rx_common.h" +#include "ef100_sriov.h" static void ef100_update_name(struct efx_nic *efx) { @@ -79,7 +80,7 @@ static int ef100_remap_bar(struct efx_nic *efx, int max_vis) */ static int ef100_net_stop(struct net_device *net_dev) { - struct efx_nic *efx = netdev_priv(net_dev); + struct efx_nic *efx = efx_netdev_priv(net_dev); netif_dbg(efx, ifdown, efx->net_dev, "closing on CPU %d\n", raw_smp_processor_id()); @@ -96,13 +97,15 @@ static int ef100_net_stop(struct net_device *net_dev) efx_mcdi_free_vis(efx); efx_remove_interrupts(efx); + efx->state = STATE_NET_DOWN; + return 0; } /* Context: process, rtnl_lock() held. */ static int ef100_net_open(struct net_device *net_dev) { - struct efx_nic *efx = netdev_priv(net_dev); + struct efx_nic *efx = efx_netdev_priv(net_dev); unsigned int allocated_vis; int rc; @@ -172,6 +175,8 @@ static int ef100_net_open(struct net_device *net_dev) efx_link_status_changed(efx); mutex_unlock(&efx->mac_lock); + efx->state = STATE_NET_UP; + return 0; fail: @@ -189,7 +194,7 @@ fail: static netdev_tx_t ef100_hard_start_xmit(struct sk_buff *skb, struct net_device *net_dev) { - struct efx_nic *efx = netdev_priv(net_dev); + struct efx_nic *efx = efx_netdev_priv(net_dev); struct efx_tx_queue *tx_queue; struct efx_channel *channel; int rc; @@ -239,13 +244,14 @@ int ef100_netdev_event(struct notifier_block *this, struct efx_nic *efx = container_of(this, struct efx_nic, netdev_notifier); struct net_device *net_dev = netdev_notifier_info_to_dev(ptr); - if (netdev_priv(net_dev) == efx && event == NETDEV_CHANGENAME) + if (efx->net_dev == net_dev && + (event == NETDEV_CHANGENAME || event == NETDEV_REGISTER)) ef100_update_name(efx); return NOTIFY_DONE; } -int ef100_register_netdev(struct efx_nic *efx) +static int ef100_register_netdev(struct efx_nic *efx) { struct net_device *net_dev = efx->net_dev; int rc; @@ -271,7 +277,7 @@ int ef100_register_netdev(struct efx_nic *efx) /* Always start with carrier off; PHY events will detect the link */ netif_carrier_off(net_dev); - efx->state = STATE_READY; + efx->state = STATE_NET_DOWN; rtnl_unlock(); efx_init_mcdi_logging(efx); @@ -283,11 +289,119 @@ fail_locked: return rc; } -void ef100_unregister_netdev(struct efx_nic *efx) +static void ef100_unregister_netdev(struct efx_nic *efx) { if (efx_dev_registered(efx)) { efx_fini_mcdi_logging(efx); - efx->state = STATE_UNINIT; + efx->state = STATE_PROBED; unregister_netdev(efx->net_dev); } } + +void ef100_remove_netdev(struct efx_probe_data *probe_data) +{ + struct efx_nic *efx = &probe_data->efx; + + if (!efx->net_dev) + return; + + rtnl_lock(); + dev_close(efx->net_dev); + rtnl_unlock(); + + unregister_netdevice_notifier(&efx->netdev_notifier); +#if defined(CONFIG_SFC_SRIOV) + if (!efx->type->is_vf) + efx_ef100_pci_sriov_disable(efx); +#endif + + ef100_unregister_netdev(efx); + + down_write(&efx->filter_sem); + efx_mcdi_filter_table_remove(efx); + up_write(&efx->filter_sem); + efx_fini_channels(efx); + kfree(efx->phy_data); + efx->phy_data = NULL; + + free_netdev(efx->net_dev); + efx->net_dev = NULL; + efx->state = STATE_PROBED; +} + +int ef100_probe_netdev(struct efx_probe_data *probe_data) +{ + struct efx_nic *efx = &probe_data->efx; + struct efx_probe_data **probe_ptr; + struct net_device *net_dev; + int rc; + + if (efx->mcdi->fn_flags & + (1 << MC_CMD_DRV_ATTACH_EXT_OUT_FLAG_NO_ACTIVE_PORT)) { + pci_info(efx->pci_dev, "No network port on this PCI function"); + return 0; + } + + /* Allocate and initialise a struct net_device */ + net_dev = alloc_etherdev_mq(sizeof(probe_data), EFX_MAX_CORE_TX_QUEUES); + if (!net_dev) + return -ENOMEM; + probe_ptr = netdev_priv(net_dev); + *probe_ptr = probe_data; + efx->net_dev = net_dev; + SET_NETDEV_DEV(net_dev, &efx->pci_dev->dev); + + net_dev->features |= efx->type->offload_features; + net_dev->hw_features |= efx->type->offload_features; + net_dev->hw_enc_features |= efx->type->offload_features; + net_dev->vlan_features |= NETIF_F_HW_CSUM | NETIF_F_SG | + NETIF_F_HIGHDMA | NETIF_F_ALL_TSO; + netif_set_tso_max_segs(net_dev, + ESE_EF100_DP_GZ_TSO_MAX_HDR_NUM_SEGS_DEFAULT); + efx->mdio.dev = net_dev; + + rc = efx_ef100_init_datapath_caps(efx); + if (rc < 0) + goto fail; + + rc = ef100_phy_probe(efx); + if (rc) + goto fail; + + rc = efx_init_channels(efx); + if (rc) + goto fail; + + down_write(&efx->filter_sem); + rc = ef100_filter_table_probe(efx); + up_write(&efx->filter_sem); + if (rc) + goto fail; + + netdev_rss_key_fill(efx->rss_context.rx_hash_key, + sizeof(efx->rss_context.rx_hash_key)); + + /* Don't fail init if RSS setup doesn't work. */ + efx_mcdi_push_default_indir_table(efx, efx->n_rx_channels); + + rc = ef100_register_netdev(efx); + if (rc) + goto fail; + + if (!efx->type->is_vf) { + rc = ef100_probe_netdev_pf(efx); + if (rc) + goto fail; + } + + efx->netdev_notifier.notifier_call = ef100_netdev_event; + rc = register_netdevice_notifier(&efx->netdev_notifier); + if (rc) { + netif_err(efx, probe, efx->net_dev, + "Failed to register netdevice notifier, rc=%d\n", rc); + goto fail; + } + +fail: + return rc; +} diff --git a/drivers/net/ethernet/sfc/ef100_netdev.h b/drivers/net/ethernet/sfc/ef100_netdev.h index d40abb7cc086..38b032ba0953 100644 --- a/drivers/net/ethernet/sfc/ef100_netdev.h +++ b/drivers/net/ethernet/sfc/ef100_netdev.h @@ -13,5 +13,5 @@ int ef100_netdev_event(struct notifier_block *this, unsigned long event, void *ptr); -int ef100_register_netdev(struct efx_nic *efx); -void ef100_unregister_netdev(struct efx_nic *efx); +int ef100_probe_netdev(struct efx_probe_data *probe_data); +void ef100_remove_netdev(struct efx_probe_data *probe_data); diff --git a/drivers/net/ethernet/sfc/ef100_nic.c b/drivers/net/ethernet/sfc/ef100_nic.c index b2536d2c218a..f89e695cf8ac 100644 --- a/drivers/net/ethernet/sfc/ef100_nic.c +++ b/drivers/net/ethernet/sfc/ef100_nic.c @@ -148,7 +148,7 @@ static int ef100_get_mac_address(struct efx_nic *efx, u8 *mac_address) return 0; } -static int efx_ef100_init_datapath_caps(struct efx_nic *efx) +int efx_ef100_init_datapath_caps(struct efx_nic *efx) { MCDI_DECLARE_BUF(outbuf, MC_CMD_GET_CAPABILITIES_V7_OUT_LEN); struct ef100_nic_data *nic_data = efx->nic_data; @@ -327,7 +327,7 @@ static irqreturn_t ef100_msi_interrupt(int irq, void *dev_id) return IRQ_HANDLED; } -static int ef100_phy_probe(struct efx_nic *efx) +int ef100_phy_probe(struct efx_nic *efx) { struct efx_mcdi_phy_data *phy_data; int rc; @@ -365,7 +365,7 @@ static int ef100_phy_probe(struct efx_nic *efx) return 0; } -static int ef100_filter_table_probe(struct efx_nic *efx) +int ef100_filter_table_probe(struct efx_nic *efx) { return efx_mcdi_filter_table_probe(efx, true); } @@ -704,178 +704,6 @@ static unsigned int efx_ef100_recycle_ring_size(const struct efx_nic *efx) return 10 * EFX_RECYCLE_RING_SIZE_10G; } -/* NIC level access functions - */ -#define EF100_OFFLOAD_FEATURES (NETIF_F_HW_CSUM | NETIF_F_RXCSUM | \ - NETIF_F_HIGHDMA | NETIF_F_SG | NETIF_F_FRAGLIST | NETIF_F_NTUPLE | \ - NETIF_F_RXHASH | NETIF_F_RXFCS | NETIF_F_TSO_ECN | NETIF_F_RXALL | \ - NETIF_F_HW_VLAN_CTAG_TX) - -const struct efx_nic_type ef100_pf_nic_type = { - .revision = EFX_REV_EF100, - .is_vf = false, - .probe = ef100_probe_pf, - .offload_features = EF100_OFFLOAD_FEATURES, - .mcdi_max_ver = 2, - .mcdi_request = ef100_mcdi_request, - .mcdi_poll_response = ef100_mcdi_poll_response, - .mcdi_read_response = ef100_mcdi_read_response, - .mcdi_poll_reboot = ef100_mcdi_poll_reboot, - .mcdi_reboot_detected = ef100_mcdi_reboot_detected, - .irq_enable_master = efx_port_dummy_op_void, - .irq_test_generate = efx_ef100_irq_test_generate, - .irq_disable_non_ev = efx_port_dummy_op_void, - .push_irq_moderation = efx_channel_dummy_op_void, - .min_interrupt_mode = EFX_INT_MODE_MSIX, - .map_reset_reason = ef100_map_reset_reason, - .map_reset_flags = ef100_map_reset_flags, - .reset = ef100_reset, - - .check_caps = ef100_check_caps, - - .ev_probe = ef100_ev_probe, - .ev_init = ef100_ev_init, - .ev_fini = efx_mcdi_ev_fini, - .ev_remove = efx_mcdi_ev_remove, - .irq_handle_msi = ef100_msi_interrupt, - .ev_process = ef100_ev_process, - .ev_read_ack = ef100_ev_read_ack, - .ev_test_generate = efx_ef100_ev_test_generate, - .tx_probe = ef100_tx_probe, - .tx_init = ef100_tx_init, - .tx_write = ef100_tx_write, - .tx_enqueue = ef100_enqueue_skb, - .rx_probe = efx_mcdi_rx_probe, - .rx_init = efx_mcdi_rx_init, - .rx_remove = efx_mcdi_rx_remove, - .rx_write = ef100_rx_write, - .rx_packet = __ef100_rx_packet, - .rx_buf_hash_valid = ef100_rx_buf_hash_valid, - .fini_dmaq = efx_fini_dmaq, - .max_rx_ip_filters = EFX_MCDI_FILTER_TBL_ROWS, - .filter_table_probe = ef100_filter_table_up, - .filter_table_restore = efx_mcdi_filter_table_restore, - .filter_table_remove = ef100_filter_table_down, - .filter_insert = efx_mcdi_filter_insert, - .filter_remove_safe = efx_mcdi_filter_remove_safe, - .filter_get_safe = efx_mcdi_filter_get_safe, - .filter_clear_rx = efx_mcdi_filter_clear_rx, - .filter_count_rx_used = efx_mcdi_filter_count_rx_used, - .filter_get_rx_id_limit = efx_mcdi_filter_get_rx_id_limit, - .filter_get_rx_ids = efx_mcdi_filter_get_rx_ids, -#ifdef CONFIG_RFS_ACCEL - .filter_rfs_expire_one = efx_mcdi_filter_rfs_expire_one, -#endif - - .get_phys_port_id = efx_ef100_get_phys_port_id, - - .rx_prefix_size = ESE_GZ_RX_PKT_PREFIX_LEN, - .rx_hash_offset = ESF_GZ_RX_PREFIX_RSS_HASH_LBN / 8, - .rx_ts_offset = ESF_GZ_RX_PREFIX_PARTIAL_TSTAMP_LBN / 8, - .rx_hash_key_size = 40, - .rx_pull_rss_config = efx_mcdi_rx_pull_rss_config, - .rx_push_rss_config = efx_mcdi_pf_rx_push_rss_config, - .rx_push_rss_context_config = efx_mcdi_rx_push_rss_context_config, - .rx_pull_rss_context_config = efx_mcdi_rx_pull_rss_context_config, - .rx_restore_rss_contexts = efx_mcdi_rx_restore_rss_contexts, - .rx_recycle_ring_size = efx_ef100_recycle_ring_size, - - .reconfigure_mac = ef100_reconfigure_mac, - .reconfigure_port = efx_mcdi_port_reconfigure, - .test_nvram = efx_new_mcdi_nvram_test_all, - .describe_stats = ef100_describe_stats, - .start_stats = efx_mcdi_mac_start_stats, - .update_stats = ef100_update_stats, - .pull_stats = efx_mcdi_mac_pull_stats, - .stop_stats = efx_mcdi_mac_stop_stats, -#ifdef CONFIG_SFC_SRIOV - .sriov_configure = efx_ef100_sriov_configure, -#endif - - /* Per-type bar/size configuration not used on ef100. Location of - * registers is defined by extended capabilities. - */ - .mem_bar = NULL, - .mem_map_size = NULL, - -}; - -const struct efx_nic_type ef100_vf_nic_type = { - .revision = EFX_REV_EF100, - .is_vf = true, - .probe = ef100_probe_vf, - .offload_features = EF100_OFFLOAD_FEATURES, - .mcdi_max_ver = 2, - .mcdi_request = ef100_mcdi_request, - .mcdi_poll_response = ef100_mcdi_poll_response, - .mcdi_read_response = ef100_mcdi_read_response, - .mcdi_poll_reboot = ef100_mcdi_poll_reboot, - .mcdi_reboot_detected = ef100_mcdi_reboot_detected, - .irq_enable_master = efx_port_dummy_op_void, - .irq_test_generate = efx_ef100_irq_test_generate, - .irq_disable_non_ev = efx_port_dummy_op_void, - .push_irq_moderation = efx_channel_dummy_op_void, - .min_interrupt_mode = EFX_INT_MODE_MSIX, - .map_reset_reason = ef100_map_reset_reason, - .map_reset_flags = ef100_map_reset_flags, - .reset = ef100_reset, - .check_caps = ef100_check_caps, - .ev_probe = ef100_ev_probe, - .ev_init = ef100_ev_init, - .ev_fini = efx_mcdi_ev_fini, - .ev_remove = efx_mcdi_ev_remove, - .irq_handle_msi = ef100_msi_interrupt, - .ev_process = ef100_ev_process, - .ev_read_ack = ef100_ev_read_ack, - .ev_test_generate = efx_ef100_ev_test_generate, - .tx_probe = ef100_tx_probe, - .tx_init = ef100_tx_init, - .tx_write = ef100_tx_write, - .tx_enqueue = ef100_enqueue_skb, - .rx_probe = efx_mcdi_rx_probe, - .rx_init = efx_mcdi_rx_init, - .rx_remove = efx_mcdi_rx_remove, - .rx_write = ef100_rx_write, - .rx_packet = __ef100_rx_packet, - .rx_buf_hash_valid = ef100_rx_buf_hash_valid, - .fini_dmaq = efx_fini_dmaq, - .max_rx_ip_filters = EFX_MCDI_FILTER_TBL_ROWS, - .filter_table_probe = ef100_filter_table_up, - .filter_table_restore = efx_mcdi_filter_table_restore, - .filter_table_remove = ef100_filter_table_down, - .filter_insert = efx_mcdi_filter_insert, - .filter_remove_safe = efx_mcdi_filter_remove_safe, - .filter_get_safe = efx_mcdi_filter_get_safe, - .filter_clear_rx = efx_mcdi_filter_clear_rx, - .filter_count_rx_used = efx_mcdi_filter_count_rx_used, - .filter_get_rx_id_limit = efx_mcdi_filter_get_rx_id_limit, - .filter_get_rx_ids = efx_mcdi_filter_get_rx_ids, -#ifdef CONFIG_RFS_ACCEL - .filter_rfs_expire_one = efx_mcdi_filter_rfs_expire_one, -#endif - - .rx_prefix_size = ESE_GZ_RX_PKT_PREFIX_LEN, - .rx_hash_offset = ESF_GZ_RX_PREFIX_RSS_HASH_LBN / 8, - .rx_ts_offset = ESF_GZ_RX_PREFIX_PARTIAL_TSTAMP_LBN / 8, - .rx_hash_key_size = 40, - .rx_pull_rss_config = efx_mcdi_rx_pull_rss_config, - .rx_push_rss_config = efx_mcdi_pf_rx_push_rss_config, - .rx_restore_rss_contexts = efx_mcdi_rx_restore_rss_contexts, - .rx_recycle_ring_size = efx_ef100_recycle_ring_size, - - .reconfigure_mac = ef100_reconfigure_mac, - .test_nvram = efx_new_mcdi_nvram_test_all, - .describe_stats = ef100_describe_stats, - .start_stats = efx_mcdi_mac_start_stats, - .update_stats = ef100_update_stats, - .pull_stats = efx_mcdi_mac_pull_stats, - .stop_stats = efx_mcdi_mac_stop_stats, - - .mem_bar = NULL, - .mem_map_size = NULL, - -}; - static int compare_versions(const char *a, const char *b) { int a_major, a_minor, a_point, a_patch; @@ -1077,8 +905,7 @@ static int ef100_check_design_params(struct efx_nic *efx) efx_readd(efx, ®, ER_GZ_PARAMS_TLV_LEN); total_len = EFX_DWORD_FIELD(reg, EFX_DWORD_0); - netif_dbg(efx, probe, efx->net_dev, "%u bytes of design parameters\n", - total_len); + pci_dbg(efx->pci_dev, "%u bytes of design parameters\n", total_len); while (offset < total_len) { efx_readd(efx, ®, ER_GZ_PARAMS_TLV + offset); data = EFX_DWORD_FIELD(reg, EFX_DWORD_0); @@ -1117,7 +944,6 @@ out: static int ef100_probe_main(struct efx_nic *efx) { unsigned int bar_size = resource_size(&efx->pci_dev->resource[efx->mem_bar]); - struct net_device *net_dev = efx->net_dev; struct ef100_nic_data *nic_data; char fw_version[32]; int i, rc; @@ -1130,24 +956,18 @@ static int ef100_probe_main(struct efx_nic *efx) return -ENOMEM; efx->nic_data = nic_data; nic_data->efx = efx; - net_dev->features |= efx->type->offload_features; - net_dev->hw_features |= efx->type->offload_features; - net_dev->hw_enc_features |= efx->type->offload_features; - net_dev->vlan_features |= NETIF_F_HW_CSUM | NETIF_F_SG | - NETIF_F_HIGHDMA | NETIF_F_ALL_TSO; + efx->max_vis = EF100_MAX_VIS; /* Populate design-parameter defaults */ nic_data->tso_max_hdr_len = ESE_EF100_DP_GZ_TSO_MAX_HDR_LEN_DEFAULT; nic_data->tso_max_frames = ESE_EF100_DP_GZ_TSO_MAX_NUM_FRAMES_DEFAULT; nic_data->tso_max_payload_num_segs = ESE_EF100_DP_GZ_TSO_MAX_PAYLOAD_NUM_SEGS_DEFAULT; nic_data->tso_max_payload_len = ESE_EF100_DP_GZ_TSO_MAX_PAYLOAD_LEN_DEFAULT; - netif_set_tso_max_segs(net_dev, - ESE_EF100_DP_GZ_TSO_MAX_HDR_NUM_SEGS_DEFAULT); + /* Read design parameters */ rc = ef100_check_design_params(efx); if (rc) { - netif_err(efx, probe, efx->net_dev, - "Unsupported design parameters\n"); + pci_err(efx->pci_dev, "Unsupported design parameters\n"); goto fail; } @@ -1184,12 +1004,6 @@ static int ef100_probe_main(struct efx_nic *efx) /* Post-IO section. */ rc = efx_mcdi_init(efx); - if (!rc && efx->mcdi->fn_flags & - (1 << MC_CMD_DRV_ATTACH_EXT_OUT_FLAG_NO_ACTIVE_PORT)) { - netif_info(efx, probe, efx->net_dev, - "No network port on this PCI function"); - rc = -ENODEV; - } if (rc) goto fail; /* Reset (most) configuration for this function */ @@ -1205,67 +1019,37 @@ static int ef100_probe_main(struct efx_nic *efx) if (rc) goto fail; - rc = efx_ef100_init_datapath_caps(efx); - if (rc < 0) - goto fail; - - efx->max_vis = EF100_MAX_VIS; - rc = efx_mcdi_port_get_number(efx); if (rc < 0) goto fail; efx->port_num = rc; efx_mcdi_print_fwver(efx, fw_version, sizeof(fw_version)); - netif_dbg(efx, drv, efx->net_dev, "Firmware version %s\n", fw_version); + pci_dbg(efx->pci_dev, "Firmware version %s\n", fw_version); if (compare_versions(fw_version, "1.1.0.1000") < 0) { - netif_info(efx, drv, efx->net_dev, "Firmware uses old event descriptors\n"); + pci_info(efx->pci_dev, "Firmware uses old event descriptors\n"); rc = -EINVAL; goto fail; } if (efx_has_cap(efx, UNSOL_EV_CREDIT_SUPPORTED)) { - netif_info(efx, drv, efx->net_dev, "Firmware uses unsolicited-event credits\n"); + pci_info(efx->pci_dev, "Firmware uses unsolicited-event credits\n"); rc = -EINVAL; goto fail; } - rc = ef100_phy_probe(efx); - if (rc) - goto fail; - - down_write(&efx->filter_sem); - rc = ef100_filter_table_probe(efx); - up_write(&efx->filter_sem); - if (rc) - goto fail; - - netdev_rss_key_fill(efx->rss_context.rx_hash_key, - sizeof(efx->rss_context.rx_hash_key)); - - /* Don't fail init if RSS setup doesn't work. */ - efx_mcdi_push_default_indir_table(efx, efx->n_rx_channels); - - rc = ef100_register_netdev(efx); - if (rc) - goto fail; - return 0; fail: return rc; } -int ef100_probe_pf(struct efx_nic *efx) +int ef100_probe_netdev_pf(struct efx_nic *efx) { + struct ef100_nic_data *nic_data = efx->nic_data; struct net_device *net_dev = efx->net_dev; - struct ef100_nic_data *nic_data; - int rc = ef100_probe_main(efx); - - if (rc) - goto fail; + int rc; - nic_data = efx->nic_data; rc = ef100_get_mac_address(efx, net_dev->perm_addr); if (rc) goto fail; @@ -1288,14 +1072,6 @@ void ef100_remove(struct efx_nic *efx) { struct ef100_nic_data *nic_data = efx->nic_data; - ef100_unregister_netdev(efx); - - down_write(&efx->filter_sem); - efx_mcdi_filter_table_remove(efx); - up_write(&efx->filter_sem); - efx_fini_channels(efx); - kfree(efx->phy_data); - efx->phy_data = NULL; efx_mcdi_detach(efx); efx_mcdi_fini(efx); if (nic_data) @@ -1303,3 +1079,175 @@ void ef100_remove(struct efx_nic *efx) kfree(nic_data); efx->nic_data = NULL; } + +/* NIC level access functions + */ +#define EF100_OFFLOAD_FEATURES (NETIF_F_HW_CSUM | NETIF_F_RXCSUM | \ + NETIF_F_HIGHDMA | NETIF_F_SG | NETIF_F_FRAGLIST | NETIF_F_NTUPLE | \ + NETIF_F_RXHASH | NETIF_F_RXFCS | NETIF_F_TSO_ECN | NETIF_F_RXALL | \ + NETIF_F_HW_VLAN_CTAG_TX) + +const struct efx_nic_type ef100_pf_nic_type = { + .revision = EFX_REV_EF100, + .is_vf = false, + .probe = ef100_probe_main, + .offload_features = EF100_OFFLOAD_FEATURES, + .mcdi_max_ver = 2, + .mcdi_request = ef100_mcdi_request, + .mcdi_poll_response = ef100_mcdi_poll_response, + .mcdi_read_response = ef100_mcdi_read_response, + .mcdi_poll_reboot = ef100_mcdi_poll_reboot, + .mcdi_reboot_detected = ef100_mcdi_reboot_detected, + .irq_enable_master = efx_port_dummy_op_void, + .irq_test_generate = efx_ef100_irq_test_generate, + .irq_disable_non_ev = efx_port_dummy_op_void, + .push_irq_moderation = efx_channel_dummy_op_void, + .min_interrupt_mode = EFX_INT_MODE_MSIX, + .map_reset_reason = ef100_map_reset_reason, + .map_reset_flags = ef100_map_reset_flags, + .reset = ef100_reset, + + .check_caps = ef100_check_caps, + + .ev_probe = ef100_ev_probe, + .ev_init = ef100_ev_init, + .ev_fini = efx_mcdi_ev_fini, + .ev_remove = efx_mcdi_ev_remove, + .irq_handle_msi = ef100_msi_interrupt, + .ev_process = ef100_ev_process, + .ev_read_ack = ef100_ev_read_ack, + .ev_test_generate = efx_ef100_ev_test_generate, + .tx_probe = ef100_tx_probe, + .tx_init = ef100_tx_init, + .tx_write = ef100_tx_write, + .tx_enqueue = ef100_enqueue_skb, + .rx_probe = efx_mcdi_rx_probe, + .rx_init = efx_mcdi_rx_init, + .rx_remove = efx_mcdi_rx_remove, + .rx_write = ef100_rx_write, + .rx_packet = __ef100_rx_packet, + .rx_buf_hash_valid = ef100_rx_buf_hash_valid, + .fini_dmaq = efx_fini_dmaq, + .max_rx_ip_filters = EFX_MCDI_FILTER_TBL_ROWS, + .filter_table_probe = ef100_filter_table_up, + .filter_table_restore = efx_mcdi_filter_table_restore, + .filter_table_remove = ef100_filter_table_down, + .filter_insert = efx_mcdi_filter_insert, + .filter_remove_safe = efx_mcdi_filter_remove_safe, + .filter_get_safe = efx_mcdi_filter_get_safe, + .filter_clear_rx = efx_mcdi_filter_clear_rx, + .filter_count_rx_used = efx_mcdi_filter_count_rx_used, + .filter_get_rx_id_limit = efx_mcdi_filter_get_rx_id_limit, + .filter_get_rx_ids = efx_mcdi_filter_get_rx_ids, +#ifdef CONFIG_RFS_ACCEL + .filter_rfs_expire_one = efx_mcdi_filter_rfs_expire_one, +#endif + + .get_phys_port_id = efx_ef100_get_phys_port_id, + + .rx_prefix_size = ESE_GZ_RX_PKT_PREFIX_LEN, + .rx_hash_offset = ESF_GZ_RX_PREFIX_RSS_HASH_LBN / 8, + .rx_ts_offset = ESF_GZ_RX_PREFIX_PARTIAL_TSTAMP_LBN / 8, + .rx_hash_key_size = 40, + .rx_pull_rss_config = efx_mcdi_rx_pull_rss_config, + .rx_push_rss_config = efx_mcdi_pf_rx_push_rss_config, + .rx_push_rss_context_config = efx_mcdi_rx_push_rss_context_config, + .rx_pull_rss_context_config = efx_mcdi_rx_pull_rss_context_config, + .rx_restore_rss_contexts = efx_mcdi_rx_restore_rss_contexts, + .rx_recycle_ring_size = efx_ef100_recycle_ring_size, + + .reconfigure_mac = ef100_reconfigure_mac, + .reconfigure_port = efx_mcdi_port_reconfigure, + .test_nvram = efx_new_mcdi_nvram_test_all, + .describe_stats = ef100_describe_stats, + .start_stats = efx_mcdi_mac_start_stats, + .update_stats = ef100_update_stats, + .pull_stats = efx_mcdi_mac_pull_stats, + .stop_stats = efx_mcdi_mac_stop_stats, +#ifdef CONFIG_SFC_SRIOV + .sriov_configure = efx_ef100_sriov_configure, +#endif + + /* Per-type bar/size configuration not used on ef100. Location of + * registers is defined by extended capabilities. + */ + .mem_bar = NULL, + .mem_map_size = NULL, + +}; + +const struct efx_nic_type ef100_vf_nic_type = { + .revision = EFX_REV_EF100, + .is_vf = true, + .probe = ef100_probe_vf, + .offload_features = EF100_OFFLOAD_FEATURES, + .mcdi_max_ver = 2, + .mcdi_request = ef100_mcdi_request, + .mcdi_poll_response = ef100_mcdi_poll_response, + .mcdi_read_response = ef100_mcdi_read_response, + .mcdi_poll_reboot = ef100_mcdi_poll_reboot, + .mcdi_reboot_detected = ef100_mcdi_reboot_detected, + .irq_enable_master = efx_port_dummy_op_void, + .irq_test_generate = efx_ef100_irq_test_generate, + .irq_disable_non_ev = efx_port_dummy_op_void, + .push_irq_moderation = efx_channel_dummy_op_void, + .min_interrupt_mode = EFX_INT_MODE_MSIX, + .map_reset_reason = ef100_map_reset_reason, + .map_reset_flags = ef100_map_reset_flags, + .reset = ef100_reset, + .check_caps = ef100_check_caps, + .ev_probe = ef100_ev_probe, + .ev_init = ef100_ev_init, + .ev_fini = efx_mcdi_ev_fini, + .ev_remove = efx_mcdi_ev_remove, + .irq_handle_msi = ef100_msi_interrupt, + .ev_process = ef100_ev_process, + .ev_read_ack = ef100_ev_read_ack, + .ev_test_generate = efx_ef100_ev_test_generate, + .tx_probe = ef100_tx_probe, + .tx_init = ef100_tx_init, + .tx_write = ef100_tx_write, + .tx_enqueue = ef100_enqueue_skb, + .rx_probe = efx_mcdi_rx_probe, + .rx_init = efx_mcdi_rx_init, + .rx_remove = efx_mcdi_rx_remove, + .rx_write = ef100_rx_write, + .rx_packet = __ef100_rx_packet, + .rx_buf_hash_valid = ef100_rx_buf_hash_valid, + .fini_dmaq = efx_fini_dmaq, + .max_rx_ip_filters = EFX_MCDI_FILTER_TBL_ROWS, + .filter_table_probe = ef100_filter_table_up, + .filter_table_restore = efx_mcdi_filter_table_restore, + .filter_table_remove = ef100_filter_table_down, + .filter_insert = efx_mcdi_filter_insert, + .filter_remove_safe = efx_mcdi_filter_remove_safe, + .filter_get_safe = efx_mcdi_filter_get_safe, + .filter_clear_rx = efx_mcdi_filter_clear_rx, + .filter_count_rx_used = efx_mcdi_filter_count_rx_used, + .filter_get_rx_id_limit = efx_mcdi_filter_get_rx_id_limit, + .filter_get_rx_ids = efx_mcdi_filter_get_rx_ids, +#ifdef CONFIG_RFS_ACCEL + .filter_rfs_expire_one = efx_mcdi_filter_rfs_expire_one, +#endif + + .rx_prefix_size = ESE_GZ_RX_PKT_PREFIX_LEN, + .rx_hash_offset = ESF_GZ_RX_PREFIX_RSS_HASH_LBN / 8, + .rx_ts_offset = ESF_GZ_RX_PREFIX_PARTIAL_TSTAMP_LBN / 8, + .rx_hash_key_size = 40, + .rx_pull_rss_config = efx_mcdi_rx_pull_rss_config, + .rx_push_rss_config = efx_mcdi_pf_rx_push_rss_config, + .rx_restore_rss_contexts = efx_mcdi_rx_restore_rss_contexts, + .rx_recycle_ring_size = efx_ef100_recycle_ring_size, + + .reconfigure_mac = ef100_reconfigure_mac, + .test_nvram = efx_new_mcdi_nvram_test_all, + .describe_stats = ef100_describe_stats, + .start_stats = efx_mcdi_mac_start_stats, + .update_stats = ef100_update_stats, + .pull_stats = efx_mcdi_mac_pull_stats, + .stop_stats = efx_mcdi_mac_stop_stats, + + .mem_bar = NULL, + .mem_map_size = NULL, + +}; diff --git a/drivers/net/ethernet/sfc/ef100_nic.h b/drivers/net/ethernet/sfc/ef100_nic.h index e799688d5264..744dbbdb4adc 100644 --- a/drivers/net/ethernet/sfc/ef100_nic.h +++ b/drivers/net/ethernet/sfc/ef100_nic.h @@ -8,6 +8,8 @@ * under the terms of the GNU General Public License version 2 as published * by the Free Software Foundation, incorporated herein by reference. */ +#ifndef EFX_EF100_NIC_H +#define EFX_EF100_NIC_H #include "net_driver.h" #include "nic_common.h" @@ -15,7 +17,7 @@ extern const struct efx_nic_type ef100_pf_nic_type; extern const struct efx_nic_type ef100_vf_nic_type; -int ef100_probe_pf(struct efx_nic *efx); +int ef100_probe_netdev_pf(struct efx_nic *efx); int ef100_probe_vf(struct efx_nic *efx); void ef100_remove(struct efx_nic *efx); @@ -78,3 +80,9 @@ struct ef100_nic_data { #define efx_ef100_has_cap(caps, flag) \ (!!((caps) & BIT_ULL(MC_CMD_GET_CAPABILITIES_V4_OUT_ ## flag ## _LBN))) + +int efx_ef100_init_datapath_caps(struct efx_nic *efx); +int ef100_phy_probe(struct efx_nic *efx); +int ef100_filter_table_probe(struct efx_nic *efx); + +#endif /* EFX_EF100_NIC_H */ diff --git a/drivers/net/ethernet/sfc/efx.c b/drivers/net/ethernet/sfc/efx.c index 5a772354da83..153d68e29b8b 100644 --- a/drivers/net/ethernet/sfc/efx.c +++ b/drivers/net/ethernet/sfc/efx.c @@ -106,14 +106,6 @@ static int efx_xdp(struct net_device *dev, struct netdev_bpf *xdp); static int efx_xdp_xmit(struct net_device *dev, int n, struct xdp_frame **xdpfs, u32 flags); -#define EFX_ASSERT_RESET_SERIALISED(efx) \ - do { \ - if ((efx->state == STATE_READY) || \ - (efx->state == STATE_RECOVERY) || \ - (efx->state == STATE_DISABLED)) \ - ASSERT_RTNL(); \ - } while (0) - /************************************************************************** * * Port handling @@ -378,6 +370,8 @@ static int efx_probe_all(struct efx_nic *efx) if (rc) goto fail5; + efx->state = STATE_NET_DOWN; + return 0; fail5: @@ -498,7 +492,7 @@ void efx_get_irq_moderation(struct efx_nic *efx, unsigned int *tx_usecs, */ static int efx_ioctl(struct net_device *net_dev, struct ifreq *ifr, int cmd) { - struct efx_nic *efx = netdev_priv(net_dev); + struct efx_nic *efx = efx_netdev_priv(net_dev); struct mii_ioctl_data *data = if_mii(ifr); if (cmd == SIOCSHWTSTAMP) @@ -523,7 +517,7 @@ static int efx_ioctl(struct net_device *net_dev, struct ifreq *ifr, int cmd) /* Context: process, rtnl_lock() held. */ int efx_net_open(struct net_device *net_dev) { - struct efx_nic *efx = netdev_priv(net_dev); + struct efx_nic *efx = efx_netdev_priv(net_dev); int rc; netif_dbg(efx, ifup, efx->net_dev, "opening device on CPU %d\n", @@ -544,6 +538,9 @@ int efx_net_open(struct net_device *net_dev) efx_start_all(efx); if (efx->state == STATE_DISABLED || efx->reset_pending) netif_device_detach(efx->net_dev); + else + efx->state = STATE_NET_UP; + efx_selftest_async_start(efx); return 0; } @@ -554,7 +551,7 @@ int efx_net_open(struct net_device *net_dev) */ int efx_net_stop(struct net_device *net_dev) { - struct efx_nic *efx = netdev_priv(net_dev); + struct efx_nic *efx = efx_netdev_priv(net_dev); netif_dbg(efx, ifdown, efx->net_dev, "closing on CPU %d\n", raw_smp_processor_id()); @@ -567,7 +564,7 @@ int efx_net_stop(struct net_device *net_dev) static int efx_vlan_rx_add_vid(struct net_device *net_dev, __be16 proto, u16 vid) { - struct efx_nic *efx = netdev_priv(net_dev); + struct efx_nic *efx = efx_netdev_priv(net_dev); if (efx->type->vlan_rx_add_vid) return efx->type->vlan_rx_add_vid(efx, proto, vid); @@ -577,7 +574,7 @@ static int efx_vlan_rx_add_vid(struct net_device *net_dev, __be16 proto, u16 vid static int efx_vlan_rx_kill_vid(struct net_device *net_dev, __be16 proto, u16 vid) { - struct efx_nic *efx = netdev_priv(net_dev); + struct efx_nic *efx = efx_netdev_priv(net_dev); if (efx->type->vlan_rx_kill_vid) return efx->type->vlan_rx_kill_vid(efx, proto, vid); @@ -646,7 +643,7 @@ static int efx_xdp_setup_prog(struct efx_nic *efx, struct bpf_prog *prog) /* Context: process, rtnl_lock() held. */ static int efx_xdp(struct net_device *dev, struct netdev_bpf *xdp) { - struct efx_nic *efx = netdev_priv(dev); + struct efx_nic *efx = efx_netdev_priv(dev); switch (xdp->command) { case XDP_SETUP_PROG: @@ -659,7 +656,7 @@ static int efx_xdp(struct net_device *dev, struct netdev_bpf *xdp) static int efx_xdp_xmit(struct net_device *dev, int n, struct xdp_frame **xdpfs, u32 flags) { - struct efx_nic *efx = netdev_priv(dev); + struct efx_nic *efx = efx_netdev_priv(dev); if (!netif_running(dev)) return -EINVAL; @@ -681,7 +678,7 @@ static int efx_netdev_event(struct notifier_block *this, if ((net_dev->netdev_ops == &efx_netdev_ops) && event == NETDEV_CHANGENAME) - efx_update_name(netdev_priv(net_dev)); + efx_update_name(efx_netdev_priv(net_dev)); return NOTIFY_DONE; } @@ -720,8 +717,6 @@ static int efx_register_netdev(struct efx_nic *efx) * already requested. If so, the NIC is probably hosed so we * 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; @@ -748,6 +743,8 @@ static int efx_register_netdev(struct efx_nic *efx) efx_associate(efx); + efx->state = STATE_NET_DOWN; + rtnl_unlock(); rc = device_create_file(&efx->pci_dev->dev, &dev_attr_phy_type); @@ -777,7 +774,8 @@ static void efx_unregister_netdev(struct efx_nic *efx) if (!efx->net_dev) return; - BUG_ON(netdev_priv(efx->net_dev) != efx); + if (WARN_ON(efx_netdev_priv(efx->net_dev) != efx)) + return; if (efx_dev_registered(efx)) { strlcpy(efx->name, pci_name(efx->pci_dev), sizeof(efx->name)); @@ -845,7 +843,7 @@ static void efx_pci_remove_main(struct efx_nic *efx) /* Flush reset_work. It can no longer be scheduled since we * are not READY. */ - BUG_ON(efx->state == STATE_READY); + WARN_ON(efx_net_active(efx->state)); efx_flush_reset_workqueue(efx); efx_disable_interrupts(efx); @@ -863,6 +861,7 @@ static void efx_pci_remove_main(struct efx_nic *efx) */ static void efx_pci_remove(struct pci_dev *pci_dev) { + struct efx_probe_data *probe_data; struct efx_nic *efx; efx = pci_get_drvdata(pci_dev); @@ -887,10 +886,12 @@ static void efx_pci_remove(struct pci_dev *pci_dev) efx_pci_remove_main(efx); efx_fini_io(efx); - netif_dbg(efx, drv, efx->net_dev, "shutdown successful\n"); + pci_dbg(efx->pci_dev, "shutdown successful\n"); efx_fini_struct(efx); free_netdev(efx->net_dev); + probe_data = container_of(efx, struct efx_probe_data, efx); + kfree(probe_data); pci_disable_pcie_error_reporting(pci_dev); }; @@ -1044,24 +1045,34 @@ static int efx_pci_probe_post_io(struct efx_nic *efx) static int efx_pci_probe(struct pci_dev *pci_dev, const struct pci_device_id *entry) { + struct efx_probe_data *probe_data, **probe_ptr; struct net_device *net_dev; struct efx_nic *efx; int rc; - /* Allocate and initialise a struct net_device and struct efx_nic */ - net_dev = alloc_etherdev_mqs(sizeof(*efx), EFX_MAX_CORE_TX_QUEUES, - EFX_MAX_RX_QUEUES); + /* Allocate probe data and struct efx_nic */ + probe_data = kzalloc(sizeof(*probe_data), GFP_KERNEL); + if (!probe_data) + return -ENOMEM; + probe_data->pci_dev = pci_dev; + efx = &probe_data->efx; + + /* Allocate and initialise a struct net_device */ + net_dev = alloc_etherdev_mq(sizeof(probe_data), EFX_MAX_CORE_TX_QUEUES); if (!net_dev) return -ENOMEM; - efx = netdev_priv(net_dev); + probe_ptr = netdev_priv(net_dev); + *probe_ptr = probe_data; + efx->net_dev = net_dev; efx->type = (const struct efx_nic_type *) entry->driver_data; efx->fixed_features |= NETIF_F_HIGHDMA; pci_set_drvdata(pci_dev, efx); SET_NETDEV_DEV(net_dev, &pci_dev->dev); - rc = efx_init_struct(efx, pci_dev, net_dev); + rc = efx_init_struct(efx, pci_dev); if (rc) goto fail1; + efx->mdio.dev = net_dev; pci_info(pci_dev, "Solarflare NIC detected\n"); @@ -1150,13 +1161,13 @@ static int efx_pm_freeze(struct device *dev) rtnl_lock(); - if (efx->state != STATE_DISABLED) { - efx->state = STATE_UNINIT; - + if (efx_net_active(efx->state)) { efx_device_detach_sync(efx); efx_stop_all(efx); efx_disable_interrupts(efx); + + efx->state = efx_freeze(efx->state); } rtnl_unlock(); @@ -1171,7 +1182,7 @@ static int efx_pm_thaw(struct device *dev) rtnl_lock(); - if (efx->state != STATE_DISABLED) { + if (efx_frozen(efx->state)) { rc = efx_enable_interrupts(efx); if (rc) goto fail; @@ -1184,7 +1195,7 @@ static int efx_pm_thaw(struct device *dev) efx_device_attach_if_not_resetting(efx); - efx->state = STATE_READY; + efx->state = efx_thaw(efx->state); efx->type->resume_wol(efx); } diff --git a/drivers/net/ethernet/sfc/efx_common.c b/drivers/net/ethernet/sfc/efx_common.c index f6577e74d6e6..56eb717bb07a 100644 --- a/drivers/net/ethernet/sfc/efx_common.c +++ b/drivers/net/ethernet/sfc/efx_common.c @@ -167,7 +167,7 @@ static void efx_mac_work(struct work_struct *data) int efx_set_mac_address(struct net_device *net_dev, void *data) { - struct efx_nic *efx = netdev_priv(net_dev); + struct efx_nic *efx = efx_netdev_priv(net_dev); struct sockaddr *addr = data; u8 *new_addr = addr->sa_data; u8 old_addr[6]; @@ -202,7 +202,7 @@ int efx_set_mac_address(struct net_device *net_dev, void *data) /* Context: netif_addr_lock held, BHs disabled. */ void efx_set_rx_mode(struct net_device *net_dev) { - struct efx_nic *efx = netdev_priv(net_dev); + struct efx_nic *efx = efx_netdev_priv(net_dev); if (efx->port_enabled) queue_work(efx->workqueue, &efx->mac_work); @@ -211,7 +211,7 @@ void efx_set_rx_mode(struct net_device *net_dev) int efx_set_features(struct net_device *net_dev, netdev_features_t data) { - struct efx_nic *efx = netdev_priv(net_dev); + struct efx_nic *efx = efx_netdev_priv(net_dev); int rc; /* If disabling RX n-tuple filtering, clear existing filters */ @@ -285,7 +285,7 @@ unsigned int efx_xdp_max_mtu(struct efx_nic *efx) /* Context: process, rtnl_lock() held. */ int efx_change_mtu(struct net_device *net_dev, int new_mtu) { - struct efx_nic *efx = netdev_priv(net_dev); + struct efx_nic *efx = efx_netdev_priv(net_dev); int rc; rc = efx_check_disabled(efx); @@ -600,7 +600,7 @@ void efx_stop_all(struct efx_nic *efx) /* Context: process, dev_base_lock or RTNL held, non-blocking. */ void efx_net_stats(struct net_device *net_dev, struct rtnl_link_stats64 *stats) { - struct efx_nic *efx = netdev_priv(net_dev); + struct efx_nic *efx = efx_netdev_priv(net_dev); spin_lock_bh(&efx->stats_lock); efx_nic_update_stats_atomic(efx, NULL, stats); @@ -723,7 +723,7 @@ void efx_reset_down(struct efx_nic *efx, enum reset_type method) /* Context: netif_tx_lock held, BHs disabled. */ void efx_watchdog(struct net_device *net_dev, unsigned int txqueue) { - struct efx_nic *efx = netdev_priv(net_dev); + struct efx_nic *efx = efx_netdev_priv(net_dev); netif_err(efx, tx_err, efx->net_dev, "TX stuck with port_enabled=%d: resetting channels\n", @@ -898,7 +898,7 @@ static void efx_reset_work(struct work_struct *data) * have changed by now. Now that we have the RTNL lock, * it cannot change again. */ - if (efx->state == STATE_READY) + if (efx_net_active(efx->state)) (void)efx_reset(efx, method); rtnl_unlock(); @@ -908,7 +908,7 @@ void efx_schedule_reset(struct efx_nic *efx, enum reset_type type) { enum reset_type method; - if (efx->state == STATE_RECOVERY) { + if (efx_recovering(efx->state)) { netif_dbg(efx, drv, efx->net_dev, "recovering: skip scheduling %s reset\n", RESET_TYPE(type)); @@ -943,7 +943,7 @@ void efx_schedule_reset(struct efx_nic *efx, enum reset_type type) /* If we're not READY then just leave the flags set as the cue * to abort probing or reschedule the reset later. */ - if (READ_ONCE(efx->state) != STATE_READY) + if (!efx_net_active(READ_ONCE(efx->state))) return; /* efx_process_channel() will no longer read events once a @@ -978,8 +978,7 @@ void efx_port_dummy_op_void(struct efx_nic *efx) {} /* This zeroes out and then fills in the invariants in a struct * efx_nic (including all sub-structures). */ -int efx_init_struct(struct efx_nic *efx, - struct pci_dev *pci_dev, struct net_device *net_dev) +int efx_init_struct(struct efx_nic *efx, struct pci_dev *pci_dev) { int rc = -ENOMEM; @@ -998,7 +997,6 @@ int efx_init_struct(struct efx_nic *efx, efx->state = STATE_UNINIT; strlcpy(efx->name, pci_name(pci_dev), sizeof(efx->name)); - efx->net_dev = net_dev; efx->rx_prefix_size = efx->type->rx_prefix_size; efx->rx_ip_align = NET_IP_ALIGN ? (efx->rx_prefix_size + NET_IP_ALIGN) % 4 : 0; @@ -1023,7 +1021,6 @@ int efx_init_struct(struct efx_nic *efx, efx->rps_hash_table = kcalloc(EFX_ARFS_HASH_TABLE_SIZE, sizeof(*efx->rps_hash_table), GFP_KERNEL); #endif - efx->mdio.dev = net_dev; INIT_WORK(&efx->mac_work, efx_mac_work); init_waitqueue_head(&efx->flush_wq); @@ -1077,13 +1074,11 @@ int efx_init_io(struct efx_nic *efx, int bar, dma_addr_t dma_mask, int rc; efx->mem_bar = UINT_MAX; - - netif_dbg(efx, probe, efx->net_dev, "initialising I/O bar=%d\n", bar); + pci_dbg(pci_dev, "initialising I/O bar=%d\n", bar); rc = pci_enable_device(pci_dev); if (rc) { - netif_err(efx, probe, efx->net_dev, - "failed to enable PCI device\n"); + pci_err(pci_dev, "failed to enable PCI device\n"); goto fail1; } @@ -1091,42 +1086,40 @@ int efx_init_io(struct efx_nic *efx, int bar, dma_addr_t dma_mask, rc = dma_set_mask_and_coherent(&pci_dev->dev, dma_mask); if (rc) { - netif_err(efx, probe, efx->net_dev, - "could not find a suitable DMA mask\n"); + pci_err(efx->pci_dev, "could not find a suitable DMA mask\n"); goto fail2; } - netif_dbg(efx, probe, efx->net_dev, - "using DMA mask %llx\n", (unsigned long long)dma_mask); + pci_dbg(efx->pci_dev, "using DMA mask %llx\n", (unsigned long long)dma_mask); efx->membase_phys = pci_resource_start(efx->pci_dev, bar); if (!efx->membase_phys) { - netif_err(efx, probe, efx->net_dev, - "ERROR: No BAR%d mapping from the BIOS. " - "Try pci=realloc on the kernel command line\n", bar); + pci_err(efx->pci_dev, + "ERROR: No BAR%d mapping from the BIOS. Try pci=realloc on the kernel command line\n", + bar); rc = -ENODEV; goto fail3; } rc = pci_request_region(pci_dev, bar, "sfc"); if (rc) { - netif_err(efx, probe, efx->net_dev, - "request for memory BAR[%d] failed\n", bar); + pci_err(efx->pci_dev, + "request for memory BAR[%d] failed\n", bar); rc = -EIO; goto fail3; } efx->mem_bar = bar; efx->membase = ioremap(efx->membase_phys, mem_map_size); if (!efx->membase) { - netif_err(efx, probe, efx->net_dev, - "could not map memory BAR[%d] at %llx+%x\n", bar, - (unsigned long long)efx->membase_phys, mem_map_size); + pci_err(efx->pci_dev, + "could not map memory BAR[%d] at %llx+%x\n", bar, + (unsigned long long)efx->membase_phys, mem_map_size); rc = -ENOMEM; goto fail4; } - netif_dbg(efx, probe, efx->net_dev, - "memory BAR[%d] at %llx+%x (virtual %p)\n", bar, - (unsigned long long)efx->membase_phys, mem_map_size, - efx->membase); + pci_dbg(efx->pci_dev, + "memory BAR[%d] at %llx+%x (virtual %p)\n", bar, + (unsigned long long)efx->membase_phys, mem_map_size, + efx->membase); return 0; @@ -1142,7 +1135,7 @@ fail1: void efx_fini_io(struct efx_nic *efx) { - netif_dbg(efx, drv, efx->net_dev, "shutting down I/O\n"); + pci_dbg(efx->pci_dev, "shutting down I/O\n"); if (efx->membase) { iounmap(efx->membase); @@ -1217,13 +1210,15 @@ static pci_ers_result_t efx_io_error_detected(struct pci_dev *pdev, rtnl_lock(); if (efx->state != STATE_DISABLED) { - efx->state = STATE_RECOVERY; + efx->state = efx_recover(efx->state); efx->reset_pending = 0; efx_device_detach_sync(efx); - efx_stop_all(efx); - efx_disable_interrupts(efx); + if (efx_net_active(efx->state)) { + efx_stop_all(efx); + efx_disable_interrupts(efx); + } status = PCI_ERS_RESULT_NEED_RESET; } else { @@ -1271,7 +1266,7 @@ static void efx_io_resume(struct pci_dev *pdev) netif_err(efx, hw, efx->net_dev, "efx_reset failed after PCI error (%d)\n", rc); } else { - efx->state = STATE_READY; + efx->state = efx_recovered(efx->state); netif_dbg(efx, hw, efx->net_dev, "Done resetting and resuming IO after PCI error.\n"); } @@ -1357,7 +1352,7 @@ static bool efx_can_encap_offloads(struct efx_nic *efx, struct sk_buff *skb) netdev_features_t efx_features_check(struct sk_buff *skb, struct net_device *dev, netdev_features_t features) { - struct efx_nic *efx = netdev_priv(dev); + struct efx_nic *efx = efx_netdev_priv(dev); if (skb->encapsulation) { if (features & NETIF_F_GSO_MASK) @@ -1378,7 +1373,7 @@ netdev_features_t efx_features_check(struct sk_buff *skb, struct net_device *dev int efx_get_phys_port_id(struct net_device *net_dev, struct netdev_phys_item_id *ppid) { - struct efx_nic *efx = netdev_priv(net_dev); + struct efx_nic *efx = efx_netdev_priv(net_dev); if (efx->type->get_phys_port_id) return efx->type->get_phys_port_id(efx, ppid); @@ -1388,7 +1383,7 @@ int efx_get_phys_port_id(struct net_device *net_dev, int efx_get_phys_port_name(struct net_device *net_dev, char *name, size_t len) { - struct efx_nic *efx = netdev_priv(net_dev); + struct efx_nic *efx = efx_netdev_priv(net_dev); if (snprintf(name, len, "p%u", efx->port_num) >= len) return -EINVAL; diff --git a/drivers/net/ethernet/sfc/efx_common.h b/drivers/net/ethernet/sfc/efx_common.h index 65513fd0cf6c..93babc1a2678 100644 --- a/drivers/net/ethernet/sfc/efx_common.h +++ b/drivers/net/ethernet/sfc/efx_common.h @@ -14,8 +14,7 @@ int efx_init_io(struct efx_nic *efx, int bar, dma_addr_t dma_mask, unsigned int mem_map_size); void efx_fini_io(struct efx_nic *efx); -int efx_init_struct(struct efx_nic *efx, struct pci_dev *pci_dev, - struct net_device *net_dev); +int efx_init_struct(struct efx_nic *efx, struct pci_dev *pci_dev); void efx_fini_struct(struct efx_nic *efx); #define EFX_MAX_DMAQ_SIZE 4096UL @@ -43,12 +42,11 @@ void efx_start_monitor(struct efx_nic *efx); int __efx_reconfigure_port(struct efx_nic *efx); int efx_reconfigure_port(struct efx_nic *efx); -#define EFX_ASSERT_RESET_SERIALISED(efx) \ - do { \ - if ((efx->state == STATE_READY) || \ - (efx->state == STATE_RECOVERY) || \ - (efx->state == STATE_DISABLED)) \ - ASSERT_RTNL(); \ +#define EFX_ASSERT_RESET_SERIALISED(efx) \ + do { \ + if ((efx)->state != STATE_UNINIT && \ + (efx)->state != STATE_PROBED) \ + ASSERT_RTNL(); \ } while (0) int efx_try_recovery(struct efx_nic *efx); @@ -64,7 +62,7 @@ void efx_port_dummy_op_void(struct efx_nic *efx); static inline int efx_check_disabled(struct efx_nic *efx) { - if (efx->state == STATE_DISABLED || efx->state == STATE_RECOVERY) { + if (efx->state == STATE_DISABLED || efx_recovering(efx->state)) { netif_err(efx, drv, efx->net_dev, "device is disabled due to earlier errors\n"); return -EIO; diff --git a/drivers/net/ethernet/sfc/ethtool.c b/drivers/net/ethernet/sfc/ethtool.c index 48506373721a..364323599f7b 100644 --- a/drivers/net/ethernet/sfc/ethtool.c +++ b/drivers/net/ethernet/sfc/ethtool.c @@ -33,7 +33,7 @@ static int efx_ethtool_phys_id(struct net_device *net_dev, enum ethtool_phys_id_state state) { - struct efx_nic *efx = netdev_priv(net_dev); + struct efx_nic *efx = efx_netdev_priv(net_dev); enum efx_led_mode mode = EFX_LED_DEFAULT; switch (state) { @@ -55,13 +55,13 @@ static int efx_ethtool_phys_id(struct net_device *net_dev, static int efx_ethtool_get_regs_len(struct net_device *net_dev) { - return efx_nic_get_regs_len(netdev_priv(net_dev)); + return efx_nic_get_regs_len(efx_netdev_priv(net_dev)); } static void efx_ethtool_get_regs(struct net_device *net_dev, struct ethtool_regs *regs, void *buf) { - struct efx_nic *efx = netdev_priv(net_dev); + struct efx_nic *efx = efx_netdev_priv(net_dev); regs->version = efx->type->revision; efx_nic_get_regs(efx, buf); @@ -101,7 +101,7 @@ static int efx_ethtool_get_coalesce(struct net_device *net_dev, struct kernel_ethtool_coalesce *kernel_coal, struct netlink_ext_ack *extack) { - struct efx_nic *efx = netdev_priv(net_dev); + struct efx_nic *efx = efx_netdev_priv(net_dev); unsigned int tx_usecs, rx_usecs; bool rx_adaptive; @@ -121,7 +121,7 @@ static int efx_ethtool_set_coalesce(struct net_device *net_dev, struct kernel_ethtool_coalesce *kernel_coal, struct netlink_ext_ack *extack) { - struct efx_nic *efx = netdev_priv(net_dev); + struct efx_nic *efx = efx_netdev_priv(net_dev); struct efx_channel *channel; unsigned int tx_usecs, rx_usecs; bool adaptive, rx_may_override_tx; @@ -163,7 +163,7 @@ efx_ethtool_get_ringparam(struct net_device *net_dev, struct kernel_ethtool_ringparam *kernel_ring, struct netlink_ext_ack *extack) { - struct efx_nic *efx = netdev_priv(net_dev); + struct efx_nic *efx = efx_netdev_priv(net_dev); ring->rx_max_pending = EFX_MAX_DMAQ_SIZE; ring->tx_max_pending = EFX_TXQ_MAX_ENT(efx); @@ -177,7 +177,7 @@ efx_ethtool_set_ringparam(struct net_device *net_dev, struct kernel_ethtool_ringparam *kernel_ring, struct netlink_ext_ack *extack) { - struct efx_nic *efx = netdev_priv(net_dev); + struct efx_nic *efx = efx_netdev_priv(net_dev); u32 txq_entries; if (ring->rx_mini_pending || ring->rx_jumbo_pending || @@ -204,7 +204,7 @@ efx_ethtool_set_ringparam(struct net_device *net_dev, static void efx_ethtool_get_wol(struct net_device *net_dev, struct ethtool_wolinfo *wol) { - struct efx_nic *efx = netdev_priv(net_dev); + struct efx_nic *efx = efx_netdev_priv(net_dev); return efx->type->get_wol(efx, wol); } @@ -212,14 +212,14 @@ static void efx_ethtool_get_wol(struct net_device *net_dev, static int efx_ethtool_set_wol(struct net_device *net_dev, struct ethtool_wolinfo *wol) { - struct efx_nic *efx = netdev_priv(net_dev); + struct efx_nic *efx = efx_netdev_priv(net_dev); return efx->type->set_wol(efx, wol->wolopts); } static void efx_ethtool_get_fec_stats(struct net_device *net_dev, struct ethtool_fec_stats *fec_stats) { - struct efx_nic *efx = netdev_priv(net_dev); + struct efx_nic *efx = efx_netdev_priv(net_dev); if (efx->type->get_fec_stats) efx->type->get_fec_stats(efx, fec_stats); @@ -228,7 +228,7 @@ static void efx_ethtool_get_fec_stats(struct net_device *net_dev, static int efx_ethtool_get_ts_info(struct net_device *net_dev, struct ethtool_ts_info *ts_info) { - struct efx_nic *efx = netdev_priv(net_dev); + struct efx_nic *efx = efx_netdev_priv(net_dev); /* Software capabilities */ ts_info->so_timestamping = (SOF_TIMESTAMPING_RX_SOFTWARE | diff --git a/drivers/net/ethernet/sfc/ethtool_common.c b/drivers/net/ethernet/sfc/ethtool_common.c index bd552c7dffcb..58ad9d665805 100644 --- a/drivers/net/ethernet/sfc/ethtool_common.c +++ b/drivers/net/ethernet/sfc/ethtool_common.c @@ -103,7 +103,7 @@ static const struct efx_sw_stat_desc efx_sw_stat_desc[] = { void efx_ethtool_get_drvinfo(struct net_device *net_dev, struct ethtool_drvinfo *info) { - struct efx_nic *efx = netdev_priv(net_dev); + struct efx_nic *efx = efx_netdev_priv(net_dev); strlcpy(info->driver, KBUILD_MODNAME, sizeof(info->driver)); efx_mcdi_print_fwver(efx, info->fw_version, @@ -113,14 +113,14 @@ void efx_ethtool_get_drvinfo(struct net_device *net_dev, u32 efx_ethtool_get_msglevel(struct net_device *net_dev) { - struct efx_nic *efx = netdev_priv(net_dev); + struct efx_nic *efx = efx_netdev_priv(net_dev); return efx->msg_enable; } void efx_ethtool_set_msglevel(struct net_device *net_dev, u32 msg_enable) { - struct efx_nic *efx = netdev_priv(net_dev); + struct efx_nic *efx = efx_netdev_priv(net_dev); efx->msg_enable = msg_enable; } @@ -128,7 +128,7 @@ void efx_ethtool_set_msglevel(struct net_device *net_dev, u32 msg_enable) void efx_ethtool_self_test(struct net_device *net_dev, struct ethtool_test *test, u64 *data) { - struct efx_nic *efx = netdev_priv(net_dev); + struct efx_nic *efx = efx_netdev_priv(net_dev); struct efx_self_tests *efx_tests; bool already_up; int rc = -ENOMEM; @@ -137,7 +137,7 @@ void efx_ethtool_self_test(struct net_device *net_dev, if (!efx_tests) goto fail; - if (efx->state != STATE_READY) { + if (!efx_net_active(efx->state)) { rc = -EBUSY; goto out; } @@ -176,7 +176,7 @@ fail: void efx_ethtool_get_pauseparam(struct net_device *net_dev, struct ethtool_pauseparam *pause) { - struct efx_nic *efx = netdev_priv(net_dev); + struct efx_nic *efx = efx_netdev_priv(net_dev); pause->rx_pause = !!(efx->wanted_fc & EFX_FC_RX); pause->tx_pause = !!(efx->wanted_fc & EFX_FC_TX); @@ -186,7 +186,7 @@ void efx_ethtool_get_pauseparam(struct net_device *net_dev, int efx_ethtool_set_pauseparam(struct net_device *net_dev, struct ethtool_pauseparam *pause) { - struct efx_nic *efx = netdev_priv(net_dev); + struct efx_nic *efx = efx_netdev_priv(net_dev); u8 wanted_fc, old_fc; u32 old_adv; int rc = 0; @@ -441,7 +441,7 @@ static size_t efx_describe_per_queue_stats(struct efx_nic *efx, u8 *strings) int efx_ethtool_get_sset_count(struct net_device *net_dev, int string_set) { - struct efx_nic *efx = netdev_priv(net_dev); + struct efx_nic *efx = efx_netdev_priv(net_dev); switch (string_set) { case ETH_SS_STATS: @@ -459,7 +459,7 @@ int efx_ethtool_get_sset_count(struct net_device *net_dev, int string_set) void efx_ethtool_get_strings(struct net_device *net_dev, u32 string_set, u8 *strings) { - struct efx_nic *efx = netdev_priv(net_dev); + struct efx_nic *efx = efx_netdev_priv(net_dev); int i; switch (string_set) { @@ -487,7 +487,7 @@ void efx_ethtool_get_stats(struct net_device *net_dev, struct ethtool_stats *stats, u64 *data) { - struct efx_nic *efx = netdev_priv(net_dev); + struct efx_nic *efx = efx_netdev_priv(net_dev); const struct efx_sw_stat_desc *stat; struct efx_channel *channel; struct efx_tx_queue *tx_queue; @@ -561,7 +561,7 @@ void efx_ethtool_get_stats(struct net_device *net_dev, int efx_ethtool_get_link_ksettings(struct net_device *net_dev, struct ethtool_link_ksettings *cmd) { - struct efx_nic *efx = netdev_priv(net_dev); + struct efx_nic *efx = efx_netdev_priv(net_dev); struct efx_link_state *link_state = &efx->link_state; mutex_lock(&efx->mac_lock); @@ -584,7 +584,7 @@ int efx_ethtool_get_link_ksettings(struct net_device *net_dev, int efx_ethtool_set_link_ksettings(struct net_device *net_dev, const struct ethtool_link_ksettings *cmd) { - struct efx_nic *efx = netdev_priv(net_dev); + struct efx_nic *efx = efx_netdev_priv(net_dev); int rc; /* GMAC does not support 1000Mbps HD */ @@ -604,7 +604,7 @@ int efx_ethtool_set_link_ksettings(struct net_device *net_dev, int efx_ethtool_get_fecparam(struct net_device *net_dev, struct ethtool_fecparam *fecparam) { - struct efx_nic *efx = netdev_priv(net_dev); + struct efx_nic *efx = efx_netdev_priv(net_dev); int rc; mutex_lock(&efx->mac_lock); @@ -617,7 +617,7 @@ int efx_ethtool_get_fecparam(struct net_device *net_dev, int efx_ethtool_set_fecparam(struct net_device *net_dev, struct ethtool_fecparam *fecparam) { - struct efx_nic *efx = netdev_priv(net_dev); + struct efx_nic *efx = efx_netdev_priv(net_dev); int rc; mutex_lock(&efx->mac_lock); @@ -809,7 +809,7 @@ static int efx_ethtool_get_class_rule(struct efx_nic *efx, int efx_ethtool_get_rxnfc(struct net_device *net_dev, struct ethtool_rxnfc *info, u32 *rule_locs) { - struct efx_nic *efx = netdev_priv(net_dev); + struct efx_nic *efx = efx_netdev_priv(net_dev); u32 rss_context = 0; s32 rc = 0; @@ -1127,7 +1127,7 @@ static int efx_ethtool_set_class_rule(struct efx_nic *efx, int efx_ethtool_set_rxnfc(struct net_device *net_dev, struct ethtool_rxnfc *info) { - struct efx_nic *efx = netdev_priv(net_dev); + struct efx_nic *efx = efx_netdev_priv(net_dev); if (efx_filter_get_rx_id_limit(efx) == 0) return -EOPNOTSUPP; @@ -1148,7 +1148,7 @@ int efx_ethtool_set_rxnfc(struct net_device *net_dev, u32 efx_ethtool_get_rxfh_indir_size(struct net_device *net_dev) { - struct efx_nic *efx = netdev_priv(net_dev); + struct efx_nic *efx = efx_netdev_priv(net_dev); if (efx->n_rx_channels == 1) return 0; @@ -1157,7 +1157,7 @@ u32 efx_ethtool_get_rxfh_indir_size(struct net_device *net_dev) u32 efx_ethtool_get_rxfh_key_size(struct net_device *net_dev) { - struct efx_nic *efx = netdev_priv(net_dev); + struct efx_nic *efx = efx_netdev_priv(net_dev); return efx->type->rx_hash_key_size; } @@ -1165,7 +1165,7 @@ u32 efx_ethtool_get_rxfh_key_size(struct net_device *net_dev) int efx_ethtool_get_rxfh(struct net_device *net_dev, u32 *indir, u8 *key, u8 *hfunc) { - struct efx_nic *efx = netdev_priv(net_dev); + struct efx_nic *efx = efx_netdev_priv(net_dev); int rc; rc = efx->type->rx_pull_rss_config(efx); @@ -1186,7 +1186,7 @@ int efx_ethtool_get_rxfh(struct net_device *net_dev, u32 *indir, u8 *key, int efx_ethtool_set_rxfh(struct net_device *net_dev, const u32 *indir, const u8 *key, const u8 hfunc) { - struct efx_nic *efx = netdev_priv(net_dev); + struct efx_nic *efx = efx_netdev_priv(net_dev); /* Hash function is Toeplitz, cannot be changed */ if (hfunc != ETH_RSS_HASH_NO_CHANGE && hfunc != ETH_RSS_HASH_TOP) @@ -1205,7 +1205,7 @@ int efx_ethtool_set_rxfh(struct net_device *net_dev, const u32 *indir, int efx_ethtool_get_rxfh_context(struct net_device *net_dev, u32 *indir, u8 *key, u8 *hfunc, u32 rss_context) { - struct efx_nic *efx = netdev_priv(net_dev); + struct efx_nic *efx = efx_netdev_priv(net_dev); struct efx_rss_context *ctx; int rc = 0; @@ -1238,7 +1238,7 @@ int efx_ethtool_set_rxfh_context(struct net_device *net_dev, const u8 hfunc, u32 *rss_context, bool delete) { - struct efx_nic *efx = netdev_priv(net_dev); + struct efx_nic *efx = efx_netdev_priv(net_dev); struct efx_rss_context *ctx; bool allocated = false; int rc; @@ -1300,7 +1300,7 @@ out_unlock: int efx_ethtool_reset(struct net_device *net_dev, u32 *flags) { - struct efx_nic *efx = netdev_priv(net_dev); + struct efx_nic *efx = efx_netdev_priv(net_dev); int rc; rc = efx->type->map_reset_flags(flags); @@ -1314,7 +1314,7 @@ int efx_ethtool_get_module_eeprom(struct net_device *net_dev, struct ethtool_eeprom *ee, u8 *data) { - struct efx_nic *efx = netdev_priv(net_dev); + struct efx_nic *efx = efx_netdev_priv(net_dev); int ret; mutex_lock(&efx->mac_lock); @@ -1327,7 +1327,7 @@ int efx_ethtool_get_module_eeprom(struct net_device *net_dev, int efx_ethtool_get_module_info(struct net_device *net_dev, struct ethtool_modinfo *modinfo) { - struct efx_nic *efx = netdev_priv(net_dev); + struct efx_nic *efx = efx_netdev_priv(net_dev); int ret; mutex_lock(&efx->mac_lock); diff --git a/drivers/net/ethernet/sfc/mcdi.c b/drivers/net/ethernet/sfc/mcdi.c index a3425b6be3f7..3225fe64c397 100644 --- a/drivers/net/ethernet/sfc/mcdi.c +++ b/drivers/net/ethernet/sfc/mcdi.c @@ -99,14 +99,12 @@ int efx_mcdi_init(struct efx_nic *efx) */ rc = efx_mcdi_drv_attach(efx, true, &already_attached); if (rc) { - netif_err(efx, probe, efx->net_dev, - "Unable to register driver with MCPU\n"); + pci_err(efx->pci_dev, "Unable to register driver with MCPU\n"); goto fail2; } if (already_attached) /* Not a fatal error */ - netif_err(efx, probe, efx->net_dev, - "Host already registered with MCPU\n"); + pci_err(efx->pci_dev, "Host already registered with MCPU\n"); if (efx->mcdi->fn_flags & (1 << MC_CMD_DRV_ATTACH_EXT_OUT_FLAG_PRIMARY)) @@ -1447,7 +1445,7 @@ void efx_mcdi_print_fwver(struct efx_nic *efx, char *buf, size_t len) return; fail: - netif_err(efx, probe, efx->net_dev, "%s: failed rc=%d\n", __func__, rc); + pci_err(efx->pci_dev, "%s: failed rc=%d\n", __func__, rc); buf[0] = 0; } @@ -1471,8 +1469,9 @@ static int efx_mcdi_drv_attach(struct efx_nic *efx, bool driver_operating, * care what firmware we get. */ if (rc == -EPERM) { - netif_dbg(efx, probe, efx->net_dev, - "efx_mcdi_drv_attach with fw-variant setting failed EPERM, trying without it\n"); + pci_dbg(efx->pci_dev, + "%s with fw-variant setting failed EPERM, trying without it\n", + __func__); MCDI_SET_DWORD(inbuf, DRV_ATTACH_IN_FIRMWARE_ID, MC_CMD_FW_DONT_CARE); rc = efx_mcdi_rpc_quiet(efx, MC_CMD_DRV_ATTACH, inbuf, @@ -1514,7 +1513,7 @@ static int efx_mcdi_drv_attach(struct efx_nic *efx, bool driver_operating, return 0; fail: - netif_err(efx, probe, efx->net_dev, "%s: failed rc=%d\n", __func__, rc); + pci_err(efx->pci_dev, "%s: failed rc=%d\n", __func__, rc); return rc; } diff --git a/drivers/net/ethernet/sfc/mcdi_port.c b/drivers/net/ethernet/sfc/mcdi_port.c index 94c6a345c0b1..ad4694fa3dda 100644 --- a/drivers/net/ethernet/sfc/mcdi_port.c +++ b/drivers/net/ethernet/sfc/mcdi_port.c @@ -20,7 +20,7 @@ static int efx_mcdi_mdio_read(struct net_device *net_dev, int prtad, int devad, u16 addr) { - struct efx_nic *efx = netdev_priv(net_dev); + struct efx_nic *efx = efx_netdev_priv(net_dev); MCDI_DECLARE_BUF(inbuf, MC_CMD_MDIO_READ_IN_LEN); MCDI_DECLARE_BUF(outbuf, MC_CMD_MDIO_READ_OUT_LEN); size_t outlen; @@ -46,7 +46,7 @@ static int efx_mcdi_mdio_read(struct net_device *net_dev, static int efx_mcdi_mdio_write(struct net_device *net_dev, int prtad, int devad, u16 addr, u16 value) { - struct efx_nic *efx = netdev_priv(net_dev); + struct efx_nic *efx = efx_netdev_priv(net_dev); MCDI_DECLARE_BUF(inbuf, MC_CMD_MDIO_WRITE_IN_LEN); MCDI_DECLARE_BUF(outbuf, MC_CMD_MDIO_WRITE_OUT_LEN); size_t outlen; diff --git a/drivers/net/ethernet/sfc/net_driver.h b/drivers/net/ethernet/sfc/net_driver.h index 723bbeea5d0c..2228c88a7f31 100644 --- a/drivers/net/ethernet/sfc/net_driver.h +++ b/drivers/net/ethernet/sfc/net_driver.h @@ -622,12 +622,55 @@ enum efx_int_mode { #define EFX_INT_MODE_USE_MSI(x) (((x)->interrupt_mode) <= EFX_INT_MODE_MSI) enum nic_state { - STATE_UNINIT = 0, /* device being probed/removed or is frozen */ - STATE_READY = 1, /* hardware ready and netdev registered */ - STATE_DISABLED = 2, /* device disabled due to hardware errors */ - STATE_RECOVERY = 3, /* device recovering from PCI error */ + STATE_UNINIT = 0, /* device being probed/removed */ + STATE_PROBED, /* hardware probed */ + STATE_NET_DOWN, /* netdev registered */ + STATE_NET_UP, /* ready for traffic */ + STATE_DISABLED, /* device disabled due to hardware errors */ + + STATE_RECOVERY = 0x100,/* recovering from PCI error */ + STATE_FROZEN = 0x200, /* frozen by power management */ }; +static inline bool efx_net_active(enum nic_state state) +{ + return state == STATE_NET_DOWN || state == STATE_NET_UP; +} + +static inline bool efx_frozen(enum nic_state state) +{ + return state & STATE_FROZEN; +} + +static inline bool efx_recovering(enum nic_state state) +{ + return state & STATE_RECOVERY; +} + +static inline enum nic_state efx_freeze(enum nic_state state) +{ + WARN_ON(!efx_net_active(state)); + return state | STATE_FROZEN; +} + +static inline enum nic_state efx_thaw(enum nic_state state) +{ + WARN_ON(!efx_frozen(state)); + return state & ~STATE_FROZEN; +} + +static inline enum nic_state efx_recover(enum nic_state state) +{ + WARN_ON(!efx_net_active(state)); + return state | STATE_RECOVERY; +} + +static inline enum nic_state efx_recovered(enum nic_state state) +{ + WARN_ON(!efx_recovering(state)); + return state & ~STATE_RECOVERY; +} + /* Forward declaration */ struct efx_nic; @@ -1123,6 +1166,24 @@ struct efx_nic { atomic_t n_rx_noskb_drops; }; +/** + * struct efx_probe_data - State after hardware probe + * @pci_dev: The PCI device + * @efx: Efx NIC details + */ +struct efx_probe_data { + struct pci_dev *pci_dev; + struct efx_nic efx; +}; + +static inline struct efx_nic *efx_netdev_priv(struct net_device *dev) +{ + struct efx_probe_data **probe_ptr = netdev_priv(dev); + struct efx_probe_data *probe_data = *probe_ptr; + + return &probe_data->efx; +} + static inline int efx_dev_registered(struct efx_nic *efx) { return efx->net_dev->reg_state == NETREG_REGISTERED; diff --git a/drivers/net/ethernet/sfc/rx_common.c b/drivers/net/ethernet/sfc/rx_common.c index fa8b9aacca11..bd21d6ac778a 100644 --- a/drivers/net/ethernet/sfc/rx_common.c +++ b/drivers/net/ethernet/sfc/rx_common.c @@ -857,7 +857,7 @@ static void efx_filter_rfs_work(struct work_struct *data) { struct efx_async_filter_insertion *req = container_of(data, struct efx_async_filter_insertion, work); - struct efx_nic *efx = netdev_priv(req->net_dev); + struct efx_nic *efx = efx_netdev_priv(req->net_dev); struct efx_channel *channel = efx_get_channel(efx, req->rxq_index); int slot_idx = req - efx->rps_slot; struct efx_arfs_rule *rule; @@ -942,7 +942,7 @@ static void efx_filter_rfs_work(struct work_struct *data) int efx_filter_rfs(struct net_device *net_dev, const struct sk_buff *skb, u16 rxq_index, u32 flow_id) { - struct efx_nic *efx = netdev_priv(net_dev); + struct efx_nic *efx = efx_netdev_priv(net_dev); struct efx_async_filter_insertion *req; struct efx_arfs_rule *rule; struct flow_keys fk; diff --git a/drivers/net/ethernet/sfc/sriov.c b/drivers/net/ethernet/sfc/sriov.c index 3f241e6c881a..fc9f0189f285 100644 --- a/drivers/net/ethernet/sfc/sriov.c +++ b/drivers/net/ethernet/sfc/sriov.c @@ -10,7 +10,7 @@ int efx_sriov_set_vf_mac(struct net_device *net_dev, int vf_i, u8 *mac) { - struct efx_nic *efx = netdev_priv(net_dev); + struct efx_nic *efx = efx_netdev_priv(net_dev); if (efx->type->sriov_set_vf_mac) return efx->type->sriov_set_vf_mac(efx, vf_i, mac); @@ -21,7 +21,7 @@ int efx_sriov_set_vf_mac(struct net_device *net_dev, int vf_i, u8 *mac) int efx_sriov_set_vf_vlan(struct net_device *net_dev, int vf_i, u16 vlan, u8 qos, __be16 vlan_proto) { - struct efx_nic *efx = netdev_priv(net_dev); + struct efx_nic *efx = efx_netdev_priv(net_dev); if (efx->type->sriov_set_vf_vlan) { if ((vlan & ~VLAN_VID_MASK) || @@ -40,7 +40,7 @@ int efx_sriov_set_vf_vlan(struct net_device *net_dev, int vf_i, u16 vlan, int efx_sriov_set_vf_spoofchk(struct net_device *net_dev, int vf_i, bool spoofchk) { - struct efx_nic *efx = netdev_priv(net_dev); + struct efx_nic *efx = efx_netdev_priv(net_dev); if (efx->type->sriov_set_vf_spoofchk) return efx->type->sriov_set_vf_spoofchk(efx, vf_i, spoofchk); @@ -51,7 +51,7 @@ int efx_sriov_set_vf_spoofchk(struct net_device *net_dev, int vf_i, int efx_sriov_get_vf_config(struct net_device *net_dev, int vf_i, struct ifla_vf_info *ivi) { - struct efx_nic *efx = netdev_priv(net_dev); + struct efx_nic *efx = efx_netdev_priv(net_dev); if (efx->type->sriov_get_vf_config) return efx->type->sriov_get_vf_config(efx, vf_i, ivi); @@ -62,7 +62,7 @@ int efx_sriov_get_vf_config(struct net_device *net_dev, int vf_i, int efx_sriov_set_vf_link_state(struct net_device *net_dev, int vf_i, int link_state) { - struct efx_nic *efx = netdev_priv(net_dev); + struct efx_nic *efx = efx_netdev_priv(net_dev); if (efx->type->sriov_set_vf_link_state) return efx->type->sriov_set_vf_link_state(efx, vf_i, diff --git a/drivers/net/ethernet/sfc/tx.c b/drivers/net/ethernet/sfc/tx.c index 138bca611341..79cc0bb76321 100644 --- a/drivers/net/ethernet/sfc/tx.c +++ b/drivers/net/ethernet/sfc/tx.c @@ -512,7 +512,7 @@ unlock: netdev_tx_t efx_hard_start_xmit(struct sk_buff *skb, struct net_device *net_dev) { - struct efx_nic *efx = netdev_priv(net_dev); + struct efx_nic *efx = efx_netdev_priv(net_dev); struct efx_tx_queue *tx_queue; unsigned index, type; @@ -609,7 +609,7 @@ void efx_init_tx_queue_core_txq(struct efx_tx_queue *tx_queue) int efx_setup_tc(struct net_device *net_dev, enum tc_setup_type type, void *type_data) { - struct efx_nic *efx = netdev_priv(net_dev); + struct efx_nic *efx = efx_netdev_priv(net_dev); struct tc_mqprio_qopt *mqprio = type_data; unsigned tc, num_tc; |
