diff options
author | David S. Miller <davem@davemloft.net> | 2012-01-29 16:11:26 -0500 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2012-01-29 16:11:26 -0500 |
commit | 30088a25e9c4dc1f8bd5c48b14a18633441b5481 (patch) | |
tree | 522124a1ec4b39d18f3af6c8f3a169f59aee9de9 | |
parent | c45a3dfb59c0f17bdbd294dd01efb2d7f99a32c7 (diff) | |
parent | db3395697cad6e9dff8d21249e0b59dc9bb83b48 (diff) |
Merge branch 'for-davem' of git://git.kernel.org/pub/scm/linux/kernel/git/bwh/sfc-next
30 files changed, 3108 insertions, 2137 deletions
diff --git a/drivers/net/ethernet/sfc/Kconfig b/drivers/net/ethernet/sfc/Kconfig index 5d18841f0f3..8d423544a7e 100644 --- a/drivers/net/ethernet/sfc/Kconfig +++ b/drivers/net/ethernet/sfc/Kconfig @@ -16,6 +16,13 @@ config SFC_MTD depends on SFC && MTD && !(SFC=y && MTD=m) default y ---help--- - This exposes the on-board flash memory as MTD devices (e.g. - /dev/mtd1). This makes it possible to upload new firmware - to the NIC. + This exposes the on-board flash and/or EEPROM as MTD devices + (e.g. /dev/mtd1). This is required to update the firmware or + the boot configuration under Linux. +config SFC_MCDI_MON + bool "Solarflare SFC9000-family hwmon support" + depends on SFC && HWMON && !(SFC=y && HWMON=m) + default y + ----help--- + This exposes the on-board firmware-managed sensors as a + hardware monitor device. diff --git a/drivers/net/ethernet/sfc/Makefile b/drivers/net/ethernet/sfc/Makefile index ab31c7124db..3fa2e25ccc4 100644 --- a/drivers/net/ethernet/sfc/Makefile +++ b/drivers/net/ethernet/sfc/Makefile @@ -2,7 +2,7 @@ sfc-y += efx.o nic.o falcon.o siena.o tx.o rx.o filter.o \ falcon_xmac.o mcdi_mac.o \ selftest.o ethtool.o qt202x_phy.o mdio_10g.o \ tenxpress.o txc43128_phy.o falcon_boards.o \ - mcdi.o mcdi_phy.o + mcdi.o mcdi_phy.o mcdi_mon.o sfc-$(CONFIG_SFC_MTD) += mtd.o obj-$(CONFIG_SFC) += sfc.o diff --git a/drivers/net/ethernet/sfc/bitfield.h b/drivers/net/ethernet/sfc/bitfield.h index 098ac2ad757..a2a9f40b90c 100644 --- a/drivers/net/ethernet/sfc/bitfield.h +++ b/drivers/net/ethernet/sfc/bitfield.h @@ -448,40 +448,40 @@ typedef union efx_oword { EFX_INSERT32(min, max, low, high, EFX_MASK32(high + 1 - low)) #define EFX_SET_OWORD64(oword, low, high, value) do { \ - (oword).u64[0] = (((oword).u64[0] \ + (oword).u64[0] = (((oword).u64[0] \ & ~EFX_INPLACE_MASK64(0, 63, low, high)) \ | EFX_INSERT64(0, 63, low, high, value)); \ - (oword).u64[1] = (((oword).u64[1] \ + (oword).u64[1] = (((oword).u64[1] \ & ~EFX_INPLACE_MASK64(64, 127, low, high)) \ | EFX_INSERT64(64, 127, low, high, value)); \ } while (0) #define EFX_SET_QWORD64(qword, low, high, value) do { \ - (qword).u64[0] = (((qword).u64[0] \ + (qword).u64[0] = (((qword).u64[0] \ & ~EFX_INPLACE_MASK64(0, 63, low, high)) \ | EFX_INSERT64(0, 63, low, high, value)); \ } while (0) #define EFX_SET_OWORD32(oword, low, high, value) do { \ - (oword).u32[0] = (((oword).u32[0] \ + (oword).u32[0] = (((oword).u32[0] \ & ~EFX_INPLACE_MASK32(0, 31, low, high)) \ | EFX_INSERT32(0, 31, low, high, value)); \ - (oword).u32[1] = (((oword).u32[1] \ + (oword).u32[1] = (((oword).u32[1] \ & ~EFX_INPLACE_MASK32(32, 63, low, high)) \ | EFX_INSERT32(32, 63, low, high, value)); \ - (oword).u32[2] = (((oword).u32[2] \ + (oword).u32[2] = (((oword).u32[2] \ & ~EFX_INPLACE_MASK32(64, 95, low, high)) \ | EFX_INSERT32(64, 95, low, high, value)); \ - (oword).u32[3] = (((oword).u32[3] \ + (oword).u32[3] = (((oword).u32[3] \ & ~EFX_INPLACE_MASK32(96, 127, low, high)) \ | EFX_INSERT32(96, 127, low, high, value)); \ } while (0) #define EFX_SET_QWORD32(qword, low, high, value) do { \ - (qword).u32[0] = (((qword).u32[0] \ + (qword).u32[0] = (((qword).u32[0] \ & ~EFX_INPLACE_MASK32(0, 31, low, high)) \ | EFX_INSERT32(0, 31, low, high, value)); \ - (qword).u32[1] = (((qword).u32[1] \ + (qword).u32[1] = (((qword).u32[1] \ & ~EFX_INPLACE_MASK32(32, 63, low, high)) \ | EFX_INSERT32(32, 63, low, high, value)); \ } while (0) diff --git a/drivers/net/ethernet/sfc/efx.c b/drivers/net/ethernet/sfc/efx.c index e43702f33b6..952d0bf7695 100644 --- a/drivers/net/ethernet/sfc/efx.c +++ b/drivers/net/ethernet/sfc/efx.c @@ -38,15 +38,15 @@ /* Loopback mode names (see LOOPBACK_MODE()) */ const unsigned int efx_loopback_mode_max = LOOPBACK_MAX; -const char *efx_loopback_mode_names[] = { +const char *const efx_loopback_mode_names[] = { [LOOPBACK_NONE] = "NONE", [LOOPBACK_DATA] = "DATAPATH", [LOOPBACK_GMAC] = "GMAC", [LOOPBACK_XGMII] = "XGMII", [LOOPBACK_XGXS] = "XGXS", - [LOOPBACK_XAUI] = "XAUI", - [LOOPBACK_GMII] = "GMII", - [LOOPBACK_SGMII] = "SGMII", + [LOOPBACK_XAUI] = "XAUI", + [LOOPBACK_GMII] = "GMII", + [LOOPBACK_SGMII] = "SGMII", [LOOPBACK_XGBR] = "XGBR", [LOOPBACK_XFI] = "XFI", [LOOPBACK_XAUI_FAR] = "XAUI_FAR", @@ -55,21 +55,21 @@ const char *efx_loopback_mode_names[] = { [LOOPBACK_XFI_FAR] = "XFI_FAR", [LOOPBACK_GPHY] = "GPHY", [LOOPBACK_PHYXS] = "PHYXS", - [LOOPBACK_PCS] = "PCS", - [LOOPBACK_PMAPMD] = "PMA/PMD", + [LOOPBACK_PCS] = "PCS", + [LOOPBACK_PMAPMD] = "PMA/PMD", [LOOPBACK_XPORT] = "XPORT", [LOOPBACK_XGMII_WS] = "XGMII_WS", - [LOOPBACK_XAUI_WS] = "XAUI_WS", + [LOOPBACK_XAUI_WS] = "XAUI_WS", [LOOPBACK_XAUI_WS_FAR] = "XAUI_WS_FAR", [LOOPBACK_XAUI_WS_NEAR] = "XAUI_WS_NEAR", - [LOOPBACK_GMII_WS] = "GMII_WS", + [LOOPBACK_GMII_WS] = "GMII_WS", [LOOPBACK_XFI_WS] = "XFI_WS", [LOOPBACK_XFI_WS_FAR] = "XFI_WS_FAR", - [LOOPBACK_PHYXS_WS] = "PHYXS_WS", + [LOOPBACK_PHYXS_WS] = "PHYXS_WS", }; const unsigned int efx_reset_type_max = RESET_TYPE_MAX; -const char *efx_reset_type_names[] = { +const char *const efx_reset_type_names[] = { [RESET_TYPE_INVISIBLE] = "INVISIBLE", [RESET_TYPE_ALL] = "ALL", [RESET_TYPE_WORLD] = "WORLD", @@ -122,15 +122,6 @@ static int napi_weight = 64; */ static unsigned int efx_monitor_interval = 1 * HZ; -/* This controls whether or not the driver will initialise devices - * with invalid MAC addresses stored in the EEPROM or flash. If true, - * such devices will be initialised with a random locally-generated - * MAC address. This allows for loading the sfc_mtd driver to - * reprogram the flash, even if the flash contents (including the MAC - * address) have previously been erased. - */ -static unsigned int allow_bad_hwaddr; - /* Initial interrupt moderation settings. They can be modified after * module load with ethtool. * @@ -162,7 +153,7 @@ static unsigned int interrupt_mode; * interrupt handling. * * Cards without MSI-X will only target one CPU via legacy or MSI interrupt. - * The default (0) means to assign an interrupt to each package (level II cache) + * The default (0) means to assign an interrupt to each core. */ static unsigned int rss_cpus; module_param(rss_cpus, uint, 0444); @@ -238,8 +229,7 @@ static int efx_process_channel(struct efx_channel *channel, int budget) /* Deliver last RX packet. */ if (channel->rx_pkt) { - __efx_rx_packet(channel, channel->rx_pkt, - channel->rx_pkt_csummed); + __efx_rx_packet(channel, channel->rx_pkt); channel->rx_pkt = NULL; } @@ -373,7 +363,7 @@ static int efx_probe_eventq(struct efx_channel *channel) struct efx_nic *efx = channel->efx; unsigned long entries; - netif_dbg(channel->efx, probe, channel->efx->net_dev, + netif_dbg(efx, probe, efx->net_dev, "chan %d create event queue\n", channel->channel); /* Build an event queue with room for one event per tx and rx buffer, @@ -807,16 +797,14 @@ void efx_link_status_changed(struct efx_nic *efx) } /* Status message for kernel log */ - if (link_state->up) { + if (link_state->up) netif_info(efx, link, efx->net_dev, "link up at %uMbps %s-duplex (MTU %d)%s\n", link_state->speed, link_state->fd ? "full" : "half", efx->net_dev->mtu, (efx->promiscuous ? " [PROMISC]" : "")); - } else { + else netif_info(efx, link, efx->net_dev, "link down\n"); - } - } void efx_link_set_advertising(struct efx_nic *efx, u32 advertising) @@ -863,11 +851,9 @@ int __efx_reconfigure_port(struct efx_nic *efx) WARN_ON(!mutex_is_locked(&efx->mac_lock)); - /* Serialise the promiscuous flag with efx_set_multicast_list. */ - if (efx_dev_registered(efx)) { - netif_addr_lock_bh(efx->net_dev); - netif_addr_unlock_bh(efx->net_dev); - } + /* Serialise the promiscuous flag with efx_set_rx_mode. */ + netif_addr_lock_bh(efx->net_dev); + netif_addr_unlock_bh(efx->net_dev); /* Disable PHY transmit in mac level loopbacks */ phy_mode = efx->phy_mode; @@ -907,16 +893,13 @@ static void efx_mac_work(struct work_struct *data) struct efx_nic *efx = container_of(data, struct efx_nic, mac_work); mutex_lock(&efx->mac_lock); - if (efx->port_enabled) { - efx->type->push_multicast_hash(efx); - efx->mac_op->reconfigure(efx); - } + if (efx->port_enabled) + efx->type->reconfigure_mac(efx); mutex_unlock(&efx->mac_lock); } static int efx_probe_port(struct efx_nic *efx) { - unsigned char *perm_addr; int rc; netif_dbg(efx, probe, efx->net_dev, "create port\n"); @@ -929,28 +912,10 @@ static int efx_probe_port(struct efx_nic *efx) if (rc) return rc; - /* Sanity check MAC address */ - perm_addr = efx->net_dev->perm_addr; - if (is_valid_ether_addr(perm_addr)) { - memcpy(efx->net_dev->dev_addr, perm_addr, ETH_ALEN); - } else { - netif_err(efx, probe, efx->net_dev, "invalid MAC address %pM\n", - perm_addr); - if (!allow_bad_hwaddr) { - rc = -EINVAL; - goto err; - } - random_ether_addr(efx->net_dev->dev_addr); - netif_info(efx, probe, efx->net_dev, - "using locally-generated MAC %pM\n", - efx->net_dev->dev_addr); - } + /* Initialise MAC address to permanent address */ + memcpy(efx->net_dev->dev_addr, efx->net_dev->perm_addr, ETH_ALEN); return 0; - - err: - efx->type->remove_port(efx); - return rc; } static int efx_init_port(struct efx_nic *efx) @@ -969,7 +934,7 @@ static int efx_init_port(struct efx_nic *efx) /* Reconfigure the MAC before creating dma queues (required for * Falcon/A1 where RX_INGR_EN/TX_DRAIN_EN isn't supported) */ - efx->mac_op->reconfigure(efx); + efx->type->reconfigure_mac(efx); /* Ensure the PHY advertises the correct flow control settings */ rc = efx->phy_op->reconfigure(efx); @@ -996,8 +961,7 @@ static void efx_start_port(struct efx_nic *efx) /* efx_mac_work() might have been scheduled after efx_stop_port(), * and then cancelled by efx_flush_all() */ - efx->type->push_multicast_hash(efx); - efx->mac_op->reconfigure(efx); + efx->type->reconfigure_mac(efx); mutex_unlock(&efx->mac_lock); } @@ -1012,10 +976,8 @@ static void efx_stop_port(struct efx_nic *efx) mutex_unlock(&efx->mac_lock); /* Serialise against efx_set_multicast_list() */ - if (efx_dev_registered(efx)) { - netif_addr_lock_bh(efx->net_dev); - netif_addr_unlock_bh(efx->net_dev); - } + netif_addr_lock_bh(efx->net_dev); + netif_addr_unlock_bh(efx->net_dev); } static void efx_fini_port(struct efx_nic *efx) @@ -1069,9 +1031,11 @@ static int efx_init_io(struct efx_nic *efx) * masks event though they reject 46 bit masks. */ while (dma_mask > 0x7fffffffUL) { - if (pci_dma_supported(pci_dev, dma_mask) && - ((rc = pci_set_dma_mask(pci_dev, dma_mask)) == 0)) - break; + if (pci_dma_supported(pci_dev, dma_mask)) { + rc = pci_set_dma_mask(pci_dev, dma_mask); + if (rc == 0) + break; + } dma_mask >>= 1; } if (rc) { @@ -1144,18 +1108,16 @@ static void efx_fini_io(struct efx_nic *efx) pci_disable_device(efx->pci_dev); } -/* Get number of channels wanted. Each channel will have its own IRQ, - * 1 RX queue and/or 2 TX queues. */ -static int efx_wanted_channels(void) +static int efx_wanted_parallelism(void) { - cpumask_var_t core_mask; + cpumask_var_t thread_mask; int count; int cpu; if (rss_cpus) return rss_cpus; - if (unlikely(!zalloc_cpumask_var(&core_mask, GFP_KERNEL))) { + if (unlikely(!zalloc_cpumask_var(&thread_mask, GFP_KERNEL))) { printk(KERN_WARNING "sfc: RSS disabled due to allocation failure\n"); return 1; @@ -1163,14 +1125,14 @@ static int efx_wanted_channels(void) count = 0; for_each_online_cpu(cpu) { - if (!cpumask_test_cpu(cpu, core_mask)) { + if (!cpumask_test_cpu(cpu, thread_mask)) { ++count; - cpumask_or(core_mask, core_mask, - topology_core_cpumask(cpu)); + cpumask_or(thread_mask, thread_mask, + topology_thread_cpumask(cpu)); } } - free_cpumask_var(core_mask); + free_cpumask_var(thread_mask); return count; } @@ -1209,7 +1171,7 @@ static int efx_probe_interrupts(struct efx_nic *efx) struct msix_entry xentries[EFX_MAX_CHANNELS]; int n_channels; - n_channels = efx_wanted_channels(); + n_channels = efx_wanted_parallelism(); if (separate_tx_channels) n_channels *= 2; n_channels = min(n_channels, max_channels); @@ -1425,14 +1387,14 @@ static void efx_start_all(struct efx_nic *efx) return; if ((efx->state != STATE_RUNNING) && (efx->state != STATE_INIT)) return; - if (efx_dev_registered(efx) && !netif_running(efx->net_dev)) + if (!netif_running(efx->net_dev)) return; /* Mark the port as enabled so port reconfigurations can start, then * restart the transmit interface early so the watchdog timer stops */ efx_start_port(efx); - if (efx_dev_registered(efx) && netif_device_present(efx->net_dev)) + if (netif_device_present(efx->net_dev)) netif_tx_wake_all_queues(efx->net_dev); efx_for_each_channel(channel, efx) @@ -1523,11 +1485,9 @@ static void efx_stop_all(struct efx_nic *efx) /* Stop the kernel transmit interface late, so the watchdog * timer isn't ticking over the flush */ - if (efx_dev_registered(efx)) { - netif_tx_stop_all_queues(efx->net_dev); - netif_tx_lock_bh(efx->net_dev); - netif_tx_unlock_bh(efx->net_dev); - } + netif_tx_stop_all_queues(efx->net_dev); + netif_tx_lock_bh(efx->net_dev); + netif_tx_unlock_bh(efx->net_dev); } static void efx_remove_all(struct efx_nic *efx) @@ -1544,13 +1504,13 @@ static void efx_remove_all(struct efx_nic *efx) * **************************************************************************/ -static unsigned int irq_mod_ticks(unsigned int usecs, unsigned int resolution) +static unsigned int irq_mod_ticks(unsigned int usecs, unsigned int quantum_ns) { if (usecs == 0) return 0; - if (usecs < resolution) + if (usecs * 1000 < quantum_ns) return 1; /* never round down to 0 */ - return usecs / resolution; + return usecs * 1000 / quantum_ns; } /* Set interrupt moderation parameters */ @@ -1559,14 +1519,20 @@ int efx_init_irq_moderation(struct efx_nic *efx, unsigned int tx_usecs, bool rx_may_override_tx) { struct efx_channel *channel; - unsigned tx_ticks = irq_mod_ticks(tx_usecs, EFX_IRQ_MOD_RESOLUTION); - unsigned rx_ticks = irq_mod_ticks(rx_usecs, EFX_IRQ_MOD_RESOLUTION); + unsigned int irq_mod_max = DIV_ROUND_UP(efx->type->timer_period_max * + efx->timer_quantum_ns, + 1000); + unsigned int tx_ticks; + unsigned int rx_ticks; EFX_ASSERT_RESET_SERIALISED(efx); - if (tx_ticks > EFX_IRQ_MOD_MAX || rx_ticks > EFX_IRQ_MOD_MAX) + if (tx_usecs > irq_mod_max || rx_usecs > irq_mod_max) return -EINVAL; + tx_ticks = irq_mod_ticks(tx_usecs, efx->timer_quantum_ns); + rx_ticks = irq_mod_ticks(rx_usecs, efx->timer_quantum_ns); + if (tx_ticks != rx_ticks && efx->tx_channel_offset == 0 && !rx_may_override_tx) { netif_err(efx, drv, efx->net_dev, "Channels are shared. " @@ -1589,8 +1555,14 @@ int efx_init_irq_moderation(struct efx_nic *efx, unsigned int tx_usecs, void efx_get_irq_moderation(struct efx_nic *efx, unsigned int *tx_usecs, unsigned int *rx_usecs, bool *rx_adaptive) { + /* We must round up when converting ticks to microseconds + * because we round down when converting the other way. + */ + *rx_adaptive = efx->irq_rx_adaptive; - *rx_usecs = efx->irq_rx_moderation * EFX_IRQ_MOD_RESOLUTION; + *rx_usecs = DIV_ROUND_UP(efx->irq_rx_moderation * + efx->timer_quantum_ns, + 1000); /* If channels are shared between RX and TX, so is IRQ * moderation. Otherwise, IRQ moderation is the same for all @@ -1599,9 +1571,10 @@ void efx_get_irq_moderation(struct efx_nic *efx, unsigned int *tx_usecs, if (efx->tx_channel_offset == 0) *tx_usecs = *rx_usecs; else - *tx_usecs = + *tx_usecs = DIV_ROUND_UP( efx->channel[efx->tx_channel_offset]->irq_moderation * - EFX_IRQ_MOD_RESOLUTION; + efx->timer_quantum_ns, + 1000); } /************************************************************************** @@ -1765,14 +1738,15 @@ static int efx_net_stop(struct net_device *net_dev) } /* Context: process, dev_base_lock or RTNL held, non-blocking. */ -static struct rtnl_link_stats64 *efx_net_stats(struct net_device *net_dev, struct rtnl_link_stats64 *stats) +static struct rtnl_link_stats64 *efx_net_stats(struct net_device *net_dev, + struct rtnl_link_stats64 *stats) { struct efx_nic *efx = netdev_priv(net_dev); struct efx_mac_stats *mac_stats = &efx->mac_stats; spin_lock_bh(&efx->stats_lock); + efx->type->update_stats(efx); - spin_unlock_bh(&efx->stats_lock); stats->rx_packets = mac_stats->rx_packets; stats->tx_packets = mac_stats->tx_packets; @@ -1796,6 +1770,8 @@ static struct rtnl_link_stats64 *efx_net_stats(struct net_device *net_dev, struc stats->tx_errors = (stats->tx_window_errors + mac_stats->tx_bad); + spin_unlock_bh(&efx->stats_lock); + return stats; } @@ -1816,7 +1792,6 @@ static void efx_watchdog(struct net_device *net_dev) static int efx_change_mtu(struct net_device *net_dev, int new_mtu) { struct efx_nic *efx = netdev_priv(net_dev); - int rc = 0; EFX_ASSERT_RESET_SERIALISED(efx); @@ -1833,13 +1808,13 @@ static int efx_change_mtu(struct net_device *net_dev, int new_mtu) /* Reconfigure the MAC before enabling the dma queues so that * the RX buffers don't overflow */ net_dev->mtu = new_mtu; - efx->mac_op->reconfigure(efx); + efx->type->reconfigure_mac(efx); mutex_unlock(&efx->mac_lock); efx_init_channels(efx); efx_start_all(efx); - return rc; + return 0; } static int efx_set_mac_address(struct net_device *net_dev, void *data) @@ -1861,14 +1836,14 @@ static int efx_set_mac_address(struct net_device *net_dev, void *data) /* Reconfigure the MAC */ mutex_lock(&efx->mac_lock); - efx->mac_op->reconfigure(efx); + efx->type->reconfigure_mac(efx); mutex_unlock(&efx->mac_lock); return 0; } /* Context: netif_addr_lock held, BHs disabled. */ -static void efx_set_multicast_list(struct net_device *net_dev) +static void efx_set_rx_mode(struct net_device *net_dev) { struct efx_nic *efx = netdev_priv(net_dev); struct netdev_hw_addr *ha; @@ -1922,7 +1897,7 @@ static const struct net_device_ops efx_netdev_ops = { .ndo_do_ioctl = efx_ioctl, .ndo_change_mtu = efx_change_mtu, .ndo_set_mac_address = efx_set_mac_address, - .ndo_set_rx_mode = efx_set_multicast_list, + .ndo_set_rx_mode = efx_set_rx_mode, .ndo_set_features = efx_set_features, #ifdef CONFIG_NET_POLL_CONTROLLER .ndo_poll_controller = efx_netpoll, @@ -1975,10 +1950,6 @@ static int efx_register_netdev(struct efx_nic *efx) net_dev->netdev_ops = &efx_netdev_ops; SET_ETHTOOL_OPS(net_dev, &efx_ethtool_ops); - /* Clear MAC statistics */ - efx->mac_op->update_stats(efx); - memset(&efx->mac_stats, 0, sizeof(efx->mac_stats)); - rtnl_lock(); rc = dev_alloc_name(net_dev, net_dev->name); @@ -1997,7 +1968,7 @@ static int efx_register_netdev(struct efx_nic *efx) } /* Always start with carrier off; PHY events will detect the link */ - netif_carrier_off(efx->net_dev); + netif_carrier_off(net_dev); rtnl_unlock(); @@ -2038,11 +2009,9 @@ static void efx_unregister_netdev(struct efx_nic *efx) efx_release_tx_buffers(tx_queue); } - if (efx_dev_registered(efx)) { - strlcpy(efx->name, pci_name(efx->pci_dev), sizeof(efx->name)); - device_remove_file(&efx->pci_dev->dev, &dev_attr_phy_type); - unregister_netdev(efx->net_dev); - } + strlcpy(efx->name, pci_name(efx->pci_dev), sizeof(efx->name)); + device_remove_file(&efx->pci_dev->dev, &dev_attr_phy_type); + unregister_netdev(efx->net_dev); } /************************************************************************** @@ -2095,7 +2064,7 @@ int efx_reset_up(struct efx_nic *efx, enum reset_type method, bool ok) "could not restore PHY settings\n"); } - efx->mac_op->reconfigure(efx); + efx->type->reconfigure_mac(efx); efx_init_channels(efx); efx_restore_filters(efx); @@ -2300,7 +2269,6 @@ static int efx_init_struct(struct efx_nic *efx, const struct efx_nic_type *type, efx->net_dev = net_dev; spin_lock_init(&efx->stats_lock); mutex_init(&efx->mac_lock); - efx->mac_op = type->default_mac_ops; efx->phy_op = &efx_dummy_phy_operations; efx->mdio.dev = net_dev; INIT_WORK(&efx->mac_work, efx_mac_work); @@ -2459,7 +2427,7 @@ static int efx_pci_probe_main(struct efx_nic *efx) /* NIC initialisation * * This is called at module load (or hotplug insertion, - * theoretically). It sets up PCI mappings, tests and resets the NIC, + * theoretically). It sets up PCI mappings, resets the NIC, * sets up and registers the network devices with the kernel and hooks * the interrupt service routine. It does not prepare the device for * transmission; this is left to the first time one of the network @@ -2658,7 +2626,7 @@ static int efx_pm_suspend(struct device *dev) return rc; } -static struct dev_pm_ops efx_pm_ops = { +static const struct dev_pm_ops efx_pm_ops = { .suspend = efx_pm_suspend, .resume = efx_pm_resume, .freeze = efx_pm_freeze, diff --git a/drivers/net/ethernet/sfc/efx.h b/drivers/net/ethernet/sfc/efx.h index a3541ac6ea0..7f546e2c39e 100644 --- a/drivers/net/ethernet/sfc/efx.h +++ b/drivers/net/ethernet/sfc/efx.h @@ -40,9 +40,9 @@ extern void efx_rx_strategy(struct efx_channel *channel); extern void efx_fast_push_rx_descriptors(struct efx_rx_queue *rx_queue); extern void efx_rx_slow_fill(unsigned long context); extern void __efx_rx_packet(struct efx_channel *channel, - struct efx_rx_buffer *rx_buf, bool checksummed); + struct efx_rx_buffer *rx_buf); extern void efx_rx_packet(struct efx_rx_queue *rx_queue, unsigned int index, - unsigned int len, bool checksummed, bool discard); + unsigned int len, u16 flags); extern void efx_schedule_slow_fill(struct efx_rx_queue *rx_queue); #define EFX_MAX_DMAQ_SIZE 4096UL @@ -145,6 +145,12 @@ static inline void efx_schedule_channel(struct efx_channel *channel) napi_schedule(&channel->napi_str); } +static inline void efx_schedule_channel_irq(struct efx_channel *channel) +{ + channel->last_irq_cpu = raw_smp_processor_id(); + efx_schedule_channel(channel); +} + extern void efx_link_status_changed(struct efx_nic *efx); extern void efx_link_set_advertising(struct efx_nic *efx, u32); extern void efx_link_set_wanted_fc(struct efx_nic *efx, u8); diff --git a/drivers/net/ethernet/sfc/ethtool.c b/drivers/net/ethernet/sfc/ethtool.c index 29b2ebfef19..f887f65e418 100644 --- a/drivers/net/ethernet/sfc/ethtool.c +++ b/drivers/net/ethernet/sfc/ethtool.c @@ -52,11 +52,6 @@ static u64 efx_get_uint_stat(void *field) return *(unsigned int *)field; } -static u64 efx_get_ulong_stat(void *field) -{ - return *(unsigned long *)field; -} - static u64 efx_get_u64_stat(void *field) { return *(u64 *) field; @@ -67,12 +62,8 @@ static u64 efx_get_atomic_stat(void *field) return atomic_read((atomic_t *) field); } -#define EFX_ETHTOOL_ULONG_MAC_STAT(field) \ - EFX_ETHTOOL_STAT(field, mac_stats, field, \ - unsigned long, efx_get_ulong_stat) - #define EFX_ETHTOOL_U64_MAC_STAT(field) \ - EFX_ETHTOOL_STAT(field, mac_stats, field, \ + EFX_ETHTOOL_STAT(field, mac_stats, field, \ u64, efx_get_u64_stat) #define EFX_ETHTOOL_UINT_NIC_STAT(name) \ @@ -91,36 +82,36 @@ static u64 efx_get_atomic_stat(void *field) EFX_ETHTOOL_STAT(tx_##field, tx_queue, field, \ unsigned int, efx_get_uint_stat) -static struct efx_ethtool_stat efx_ethtool_stats[] = { +static const struct efx_ethtool_stat efx_ethtool_stats[] = { EFX_ETHTOOL_U64_MAC_STAT(tx_bytes), EFX_ETHTOOL_U64_MAC_STAT(tx_good_bytes), EFX_ETHTOOL_U64_MAC_STAT(tx_bad_bytes), - EFX_ETHTOOL_ULONG_MAC_STAT(tx_packets), - EFX_ETHTOOL_ULONG_MAC_STAT(tx_bad), - EFX_ETHTOOL_ULONG_MAC_STAT(tx_pause), - EFX_ETHTOOL_ULONG_MAC_STAT(tx_control), - EFX_ETHTOOL_ULONG_MAC_STAT(tx_unicast), - EFX_ETHTOOL_ULONG_MAC_STAT(tx_multicast), - EFX_ETHTOOL_ULONG_MAC_STAT(tx_broadcast), - EFX_ETHTOOL_ULONG_MAC_STAT(tx_lt64), - EFX_ETHTOOL_ULONG_MAC_STAT(tx_64), - EFX_ETHTOOL_ULONG_MAC_STAT(tx_65_to_127), - EFX_ETHTOOL_ULONG_MAC_STAT(tx_128_to_255), - EFX_ETHTOOL_ULONG_MAC_STAT(tx_256_to_511), - EFX_ETHTOOL_ULONG_MAC_STAT(tx_512_to_1023), - EFX_ETHTOOL_ULONG_MAC_STAT(tx_1024_to_15xx), - EFX_ETHTOOL_ULONG_MAC_STAT(tx_15xx_to_jumbo), - EFX_ETHTOOL_ULONG_MAC_STAT(tx_gtjumbo), - EFX_ETHTOOL_ULONG_MAC_STAT(tx_collision), - EFX_ETHTOOL_ULONG_MAC_STAT(tx_single_collision), - EFX_ETHTOOL_ULONG_MAC_STAT(tx_multiple_collision), - EFX_ETHTOOL_ULONG_MAC_STAT(tx_excessive_collision), - EFX_ETHTOOL_ULONG_MAC_STAT(tx_deferred), - EFX_ETHTOOL_ULONG_MAC_STAT(tx_late_collision), - EFX_ETHTOOL_ULONG_MAC_STAT(tx_excessive_deferred), - EFX_ETHTOOL_ULONG_MAC_STAT(tx_non_tcpudp), - EFX_ETHTOOL_ULONG_MAC_STAT(tx_mac_src_error), - EFX_ETHTOOL_ULONG_MAC_STAT(tx_ip_src_error), + EFX_ETHTOOL_U64_MAC_STAT(tx_packets), + EFX_ETHTOOL_U64_MAC_STAT(tx_bad), + EFX_ETHTOOL_U64_MAC_STAT(tx_pause), + EFX_ETHTOOL_U64_MAC_STAT(tx_control), + EFX_ETHTOOL_U64_MAC_STAT(tx_unicast), + EFX_ETHTOOL_U64_MAC_STAT(tx_multicast), + EFX_ETHTOOL_U64_MAC_STAT(tx_broadcast), + EFX_ETHTOOL_U64_MAC_STAT(tx_lt64), + EFX_ETHTOOL_U64_MAC_STAT(tx_64), + EFX_ETHTOOL_U64_MAC_STAT(tx_65_to_127), + EFX_ETHTOOL_U64_MAC_STAT(tx_128_to_255), + EFX_ETHTOOL_U64_MAC_STAT(tx_256_to_511), + EFX_ETHTOOL_U64_MAC_STAT(tx_512_to_1023), + EFX_ETHTOOL_U64_MAC_STAT(tx_1024_to_15xx), + EFX_ETHTOOL_U64_MAC_STAT(tx_15xx_to_jumbo), + EFX_ETHTOOL_U64_MAC_STAT(tx_gtjumbo), + EFX_ETHTOOL_U64_MAC_STAT(tx_collision), + EFX_ETHTOOL_U64_MAC_STAT(tx_single_collision), + EFX_ETHTOOL_U64_MAC_STAT(tx_multiple_collision), + EFX_ETHTOOL_U64_MAC_STAT(tx_excessive_collision), + EFX_ETHTOOL_U64_MAC_STAT(tx_deferred), + EFX_ETHTOOL_U64_MAC_STAT(tx_late_collision), + EFX_ETHTOOL_U64_MAC_STAT(tx_excessive_deferred), + EFX_ETHTOOL_U64_MAC_STAT(tx_non_tcpudp), + EFX_ETHTOOL_U64_MAC_STAT(tx_mac_src_error), + EFX_ETHTOOL_U64_MAC_STAT(tx_ip_src_error), EFX_ETHTOOL_UINT_TXQ_STAT(tso_bursts), EFX_ETHTOOL_UINT_TXQ_STAT(tso_long_headers), EFX_ETHTOOL_UINT_TXQ_STAT(tso_packets), @@ -128,34 +119,34 @@ static struct efx_ethtool_stat efx_ethtool_stats[] = { EFX_ETHTOOL_U64_MAC_STAT(rx_bytes), EFX_ETHTOOL_U64_MAC_STAT(rx_good_bytes), EFX_ETHTOOL_U64_MAC_STAT(rx_bad_bytes), - EFX_ETHTOOL_ULONG_MAC_STAT(rx_packets), - EFX_ETHTOOL_ULONG_MAC_STAT(rx_good), - EFX_ETHTOOL_ULONG_MAC_STAT(rx_bad), - EFX_ETHTOOL_ULONG_MAC_STAT(rx_pause), - EFX_ETHTOOL_ULONG_MAC_STAT(rx_control), - EFX_ETHTOOL_ULONG_MAC_STAT(rx_unicast), - EFX_ETHTOOL_ULONG_MAC_STAT(rx_multicast), - EFX_ETHTOOL_ULONG_MAC_STAT(rx_broadcast), - EFX_ETHTOOL_ULONG_MAC_STAT(rx_lt64), - EFX_ETHTOOL_ULONG_MAC_STAT(rx_64), - EFX_ETHTOOL_ULONG_MAC_STAT(rx_65_to_127), - EFX_ETHTOOL_ULONG_MAC_STAT(rx_128_to_255), - EFX_ETHTOOL_ULONG_MAC_STAT(rx_256_to_511), - EFX_ETHTOOL_ULONG_MAC_STAT(rx_512_to_1023), - EFX_ETHTOOL_ULONG_MAC_STAT(rx_1024_to_15xx), - EFX_ETHTOOL_ULONG_MAC_STAT(rx_15xx_to_jumbo), - EFX_ETHTOOL_ULONG_MAC_STAT(rx_gtjumbo), - EFX_ETHTOOL_ULONG_MAC_STAT(rx_bad_lt64), - EFX_ETHTOOL_ULONG_MAC_STAT(rx_bad_64_to_15xx), - EFX_ETHTOOL_ULONG_MAC_STAT(rx_bad_15xx_to_jumbo), - EFX_ETHTOOL_ULONG_MAC_STAT(rx_bad_gtjumbo), - EFX_ETHTOOL_ULONG_MAC_STAT(rx_overflow), - EFX_ETHTOOL_ULONG_MAC_STAT(rx_missed), - EFX_ETHTOOL_ULONG_MAC_STAT(rx_false_carrier), - EFX_ETHTOOL_ULONG_MAC_STAT(rx_symbol_error), - EFX_ETHTOOL_ULONG_MAC_STAT(rx_align_error), - EFX_ETHTOOL_ULONG_MAC_STAT(rx_length_error), - EFX_ETHTOOL_ULONG_MAC_STAT(rx_internal_error), + EFX_ETHTOOL_U64_MAC_STAT(rx_packets), + EFX_ETHTOOL_U64_MAC_STAT(rx_good), + EFX_ETHTOOL_U64_MAC_STAT(rx_bad), + EFX_ETHTOOL_U64_MAC_ST |