diff options
author | David S. Miller <davem@davemloft.net> | 2017-12-18 13:07:50 -0500 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2017-12-18 13:07:50 -0500 |
commit | e7655085973bd33ee47bb12de663d31c81717404 (patch) | |
tree | c601877dc0955589847e3666fc362fa6d2acc7e3 | |
parent | 59436c9ee18d7faad0cd1875c9d8322668f98611 (diff) | |
parent | 0bc959a95e8c1ee0295d2b85538a2a32b7b87880 (diff) | |
download | linux-e7655085973bd33ee47bb12de663d31c81717404.tar.bz2 |
Merge branch 'sfc-Medford2'
Edward Cree says:
====================
sfc: Initial X2000-series (Medford2) support
Basic PCI-level changes to support X2000-series NICs.
Also fix unexpected-PTP-event log messages, since the timestamp format has
been changed in these NICs and that causes us to fail to probe PTP (but we
still get the PPS events).
====================
Signed-off-by: David S. Miller <davem@davemloft.net>
-rw-r--r-- | drivers/net/ethernet/sfc/ef10.c | 126 | ||||
-rw-r--r-- | drivers/net/ethernet/sfc/ef10_regs.h | 46 | ||||
-rw-r--r-- | drivers/net/ethernet/sfc/efx.c | 10 | ||||
-rw-r--r-- | drivers/net/ethernet/sfc/efx.h | 5 | ||||
-rw-r--r-- | drivers/net/ethernet/sfc/io.h | 19 | ||||
-rw-r--r-- | drivers/net/ethernet/sfc/mcdi.h | 3 | ||||
-rw-r--r-- | drivers/net/ethernet/sfc/net_driver.h | 7 | ||||
-rw-r--r-- | drivers/net/ethernet/sfc/ptp.c | 4 | ||||
-rw-r--r-- | drivers/net/ethernet/sfc/siena.c | 10 |
9 files changed, 162 insertions, 68 deletions
diff --git a/drivers/net/ethernet/sfc/ef10.c b/drivers/net/ethernet/sfc/ef10.c index e566dbb3343d..1f64c7f60943 100644 --- a/drivers/net/ethernet/sfc/ef10.c +++ b/drivers/net/ethernet/sfc/ef10.c @@ -160,11 +160,31 @@ static int efx_ef10_get_warm_boot_count(struct efx_nic *efx) EFX_DWORD_FIELD(reg, EFX_WORD_0) : -EIO; } +/* On all EF10s up to and including SFC9220 (Medford1), all PFs use BAR 0 for + * I/O space and BAR 2(&3) for memory. On SFC9250 (Medford2), there is no I/O + * bar; PFs use BAR 0/1 for memory. + */ +static unsigned int efx_ef10_pf_mem_bar(struct efx_nic *efx) +{ + switch (efx->pci_dev->device) { + case 0x0b03: /* SFC9250 PF */ + return 0; + default: + return 2; + } +} + +/* All VFs use BAR 0/1 for memory */ +static unsigned int efx_ef10_vf_mem_bar(struct efx_nic *efx) +{ + return 0; +} + static unsigned int efx_ef10_mem_map_size(struct efx_nic *efx) { int bar; - bar = efx->type->mem_bar; + bar = efx->type->mem_bar(efx); return resource_size(&efx->pci_dev->resource[bar]); } @@ -213,7 +233,7 @@ static int efx_ef10_get_vf_index(struct efx_nic *efx) static int efx_ef10_init_datapath_caps(struct efx_nic *efx) { - MCDI_DECLARE_BUF(outbuf, MC_CMD_GET_CAPABILITIES_V2_OUT_LEN); + MCDI_DECLARE_BUF(outbuf, MC_CMD_GET_CAPABILITIES_V3_OUT_LEN); struct efx_ef10_nic_data *nic_data = efx->nic_data; size_t outlen; int rc; @@ -257,6 +277,35 @@ static int efx_ef10_init_datapath_caps(struct efx_nic *efx) return -ENODEV; } + if (outlen >= MC_CMD_GET_CAPABILITIES_V3_OUT_LEN) { + u8 vi_window_mode = MCDI_BYTE(outbuf, + GET_CAPABILITIES_V3_OUT_VI_WINDOW_MODE); + + switch (vi_window_mode) { + case MC_CMD_GET_CAPABILITIES_V3_OUT_VI_WINDOW_MODE_8K: + efx->vi_stride = 8192; + break; + case MC_CMD_GET_CAPABILITIES_V3_OUT_VI_WINDOW_MODE_16K: + efx->vi_stride = 16384; + break; + case MC_CMD_GET_CAPABILITIES_V3_OUT_VI_WINDOW_MODE_64K: + efx->vi_stride = 65536; + break; + default: + netif_err(efx, probe, efx->net_dev, + "Unrecognised VI window mode %d\n", + vi_window_mode); + return -EIO; + } + netif_dbg(efx, probe, efx->net_dev, "vi_stride = %u\n", + efx->vi_stride); + } else { + /* keep default VI stride */ + netif_dbg(efx, probe, efx->net_dev, + "firmware did not report VI window mode, assuming vi_stride = %u\n", + efx->vi_stride); + } + return 0; } @@ -589,17 +638,6 @@ static int efx_ef10_probe(struct efx_nic *efx) struct efx_ef10_nic_data *nic_data; int i, rc; - /* We can have one VI for each 8K region. However, until we - * use TX option descriptors we need two TX queues per channel. - */ - efx->max_channels = min_t(unsigned int, - EFX_MAX_CHANNELS, - efx_ef10_mem_map_size(efx) / - (EFX_VI_PAGE_SIZE * EFX_TXQ_TYPES)); - efx->max_tx_channels = efx->max_channels; - if (WARN_ON(efx->max_channels == 0)) - return -EIO; - nic_data = kzalloc(sizeof(*nic_data), GFP_KERNEL); if (!nic_data) return -ENOMEM; @@ -671,6 +709,20 @@ static int efx_ef10_probe(struct efx_nic *efx) if (rc < 0) goto fail5; + /* We can have one VI for each vi_stride-byte region. + * However, until we use TX option descriptors we need two TX queues + * per channel. + */ + efx->max_channels = min_t(unsigned int, + EFX_MAX_CHANNELS, + efx_ef10_mem_map_size(efx) / + (efx->vi_stride * EFX_TXQ_TYPES)); + efx->max_tx_channels = efx->max_channels; + if (WARN_ON(efx->max_channels == 0)) { + rc = -EIO; + goto fail5; + } + efx->rx_packet_len_offset = ES_DZ_RX_PREFIX_PKTLEN_OFST - ES_DZ_RX_PREFIX_SIZE; @@ -695,7 +747,14 @@ static int efx_ef10_probe(struct efx_nic *efx) if (rc && rc != -EPERM) goto fail5; - efx_ptp_probe(efx, NULL); + rc = efx_ptp_probe(efx, NULL); + /* Failure to probe PTP is not fatal. + * In the case of EPERM, efx_ptp_probe will print its own message (in + * efx_ptp_get_attributes()), so we don't need to. + */ + if (rc && rc != -EPERM) + netif_warn(efx, drv, efx->net_dev, + "Failed to probe PTP, rc=%d\n", rc); #ifdef CONFIG_SFC_SRIOV if ((efx->pci_dev->physfn) && (!efx->pci_dev->is_physfn)) { @@ -907,7 +966,7 @@ static int efx_ef10_link_piobufs(struct efx_nic *efx) } else { tx_queue->piobuf = nic_data->pio_write_base + - index * EFX_VI_PAGE_SIZE + offset; + index * efx->vi_stride + offset; tx_queue->piobuf_offset = offset; netif_dbg(efx, probe, efx->net_dev, "linked VI %u to PIO buffer %u offset %x addr %p\n", @@ -1253,19 +1312,19 @@ static int efx_ef10_dimension_resources(struct efx_nic *efx) * for writing PIO buffers through. * * The UC mapping contains (channel_vis - 1) complete VIs and the - * first half of the next VI. Then the WC mapping begins with - * the second half of this last VI. + * first 4K of the next VI. Then the WC mapping begins with + * the remainder of this last VI. */ - uc_mem_map_size = PAGE_ALIGN((channel_vis - 1) * EFX_VI_PAGE_SIZE + + uc_mem_map_size = PAGE_ALIGN((channel_vis - 1) * efx->vi_stride + ER_DZ_TX_PIOBUF); if (nic_data->n_piobufs) { /* pio_write_vi_base rounds down to give the number of complete * VIs inside the UC mapping. */ - pio_write_vi_base = uc_mem_map_size / EFX_VI_PAGE_SIZE; + pio_write_vi_base = uc_mem_map_size / efx->vi_stride; wc_mem_map_size = (PAGE_ALIGN((pio_write_vi_base + nic_data->n_piobufs) * - EFX_VI_PAGE_SIZE) - + efx->vi_stride) - uc_mem_map_size); max_vis = pio_write_vi_base + nic_data->n_piobufs; } else { @@ -1337,7 +1396,7 @@ static int efx_ef10_dimension_resources(struct efx_nic *efx) nic_data->pio_write_vi_base = pio_write_vi_base; nic_data->pio_write_base = nic_data->wc_membase + - (pio_write_vi_base * EFX_VI_PAGE_SIZE + ER_DZ_TX_PIOBUF - + (pio_write_vi_base * efx->vi_stride + ER_DZ_TX_PIOBUF - uc_mem_map_size); rc = efx_ef10_link_piobufs(efx); @@ -1951,8 +2010,9 @@ static void efx_ef10_push_irq_moderation(struct efx_channel *channel) } else { unsigned int ticks = efx_usecs_to_ticks(efx, usecs); - EFX_POPULATE_DWORD_2(timer_cmd, ERF_DZ_TC_TIMER_MODE, mode, - ERF_DZ_TC_TIMER_VAL, ticks); + EFX_POPULATE_DWORD_3(timer_cmd, ERF_DZ_TC_TIMER_MODE, mode, + ERF_DZ_TC_TIMER_VAL, ticks, + ERF_FZ_TC_TMR_REL_VAL, ticks); efx_writed_page(efx, &timer_cmd, ER_DZ_EVQ_TMR, channel->channel); } @@ -3233,8 +3293,8 @@ static u16 efx_ef10_handle_rx_event_errors(struct efx_channel *channel, if (unlikely(rx_encap_hdr != ESE_EZ_ENCAP_HDR_VXLAN && ((rx_l3_class != ESE_DZ_L3_CLASS_IP4 && rx_l3_class != ESE_DZ_L3_CLASS_IP6) || - (rx_l4_class != ESE_DZ_L4_CLASS_TCP && - rx_l4_class != ESE_DZ_L4_CLASS_UDP)))) + (rx_l4_class != ESE_FZ_L4_CLASS_TCP && + rx_l4_class != ESE_FZ_L4_CLASS_UDP)))) netdev_WARN(efx->net_dev, "invalid class for RX_TCPUDP_CKSUM_ERR: event=" EFX_QWORD_FMT "\n", @@ -3271,8 +3331,8 @@ static u16 efx_ef10_handle_rx_event_errors(struct efx_channel *channel, EFX_QWORD_VAL(*event)); else if (unlikely((rx_l3_class != ESE_DZ_L3_CLASS_IP4 && rx_l3_class != ESE_DZ_L3_CLASS_IP6) || - (rx_l4_class != ESE_DZ_L4_CLASS_TCP && - rx_l4_class != ESE_DZ_L4_CLASS_UDP))) + (rx_l4_class != ESE_FZ_L4_CLASS_TCP && + rx_l4_class != ESE_FZ_L4_CLASS_UDP))) netdev_WARN(efx->net_dev, "invalid class for RX_TCP_UDP_INNER_CHKSUM_ERR: event=" EFX_QWORD_FMT "\n", @@ -3307,7 +3367,7 @@ static int efx_ef10_handle_rx_event(struct efx_channel *channel, next_ptr_lbits = EFX_QWORD_FIELD(*event, ESF_DZ_RX_DSC_PTR_LBITS); rx_queue_label = EFX_QWORD_FIELD(*event, ESF_DZ_RX_QLABEL); rx_l3_class = EFX_QWORD_FIELD(*event, ESF_DZ_RX_L3_CLASS); - rx_l4_class = EFX_QWORD_FIELD(*event, ESF_DZ_RX_L4_CLASS); + rx_l4_class = EFX_QWORD_FIELD(*event, ESF_FZ_RX_L4_CLASS); rx_cont = EFX_QWORD_FIELD(*event, ESF_DZ_RX_CONT); rx_encap_hdr = nic_data->datapath_caps & @@ -3385,8 +3445,8 @@ static int efx_ef10_handle_rx_event(struct efx_channel *channel, rx_l3_class, rx_l4_class, event); } else { - bool tcpudp = rx_l4_class == ESE_DZ_L4_CLASS_TCP || - rx_l4_class == ESE_DZ_L4_CLASS_UDP; + bool tcpudp = rx_l4_class == ESE_FZ_L4_CLASS_TCP || + rx_l4_class == ESE_FZ_L4_CLASS_UDP; switch (rx_encap_hdr) { case ESE_EZ_ENCAP_HDR_VXLAN: /* VxLAN or GENEVE */ @@ -3407,7 +3467,7 @@ static int efx_ef10_handle_rx_event(struct efx_channel *channel, } } - if (rx_l4_class == ESE_DZ_L4_CLASS_TCP) + if (rx_l4_class == ESE_FZ_L4_CLASS_TCP) flags |= EFX_RX_PKT_TCP; channel->irq_mod_score += 2 * n_packets; @@ -6392,7 +6452,7 @@ out_unlock: const struct efx_nic_type efx_hunt_a0_vf_nic_type = { .is_vf = true, - .mem_bar = EFX_MEM_VF_BAR, + .mem_bar = efx_ef10_vf_mem_bar, .mem_map_size = efx_ef10_mem_map_size, .probe = efx_ef10_probe_vf, .remove = efx_ef10_remove, @@ -6500,7 +6560,7 @@ const struct efx_nic_type efx_hunt_a0_vf_nic_type = { const struct efx_nic_type efx_hunt_a0_nic_type = { .is_vf = false, - .mem_bar = EFX_MEM_BAR, + .mem_bar = efx_ef10_pf_mem_bar, .mem_map_size = efx_ef10_mem_map_size, .probe = efx_ef10_probe_pf, .remove = efx_ef10_remove, diff --git a/drivers/net/ethernet/sfc/ef10_regs.h b/drivers/net/ethernet/sfc/ef10_regs.h index 2c4bf9476c37..6a56778cf06c 100644 --- a/drivers/net/ethernet/sfc/ef10_regs.h +++ b/drivers/net/ethernet/sfc/ef10_regs.h @@ -1,6 +1,6 @@ /**************************************************************************** * Driver for Solarflare network controllers and boards - * Copyright 2012-2015 Solarflare Communications Inc. + * Copyright 2012-2017 Solarflare Communications Inc. * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License version 2 as published @@ -79,6 +79,8 @@ #define ER_DZ_EVQ_TMR 0x00000420 #define ER_DZ_EVQ_TMR_STEP 8192 #define ER_DZ_EVQ_TMR_ROWS 2048 +#define ERF_FZ_TC_TMR_REL_VAL_LBN 16 +#define ERF_FZ_TC_TMR_REL_VAL_WIDTH 14 #define ERF_DZ_TC_TIMER_MODE_LBN 14 #define ERF_DZ_TC_TIMER_MODE_WIDTH 2 #define ERF_DZ_TC_TIMER_VAL_LBN 0 @@ -159,16 +161,24 @@ #define ESF_DZ_RX_EV_SOFT2_WIDTH 2 #define ESF_DZ_RX_DSC_PTR_LBITS_LBN 48 #define ESF_DZ_RX_DSC_PTR_LBITS_WIDTH 4 -#define ESF_DZ_RX_L4_CLASS_LBN 45 -#define ESF_DZ_RX_L4_CLASS_WIDTH 3 -#define ESE_DZ_L4_CLASS_RSVD7 7 -#define ESE_DZ_L4_CLASS_RSVD6 6 -#define ESE_DZ_L4_CLASS_RSVD5 5 -#define ESE_DZ_L4_CLASS_RSVD4 4 -#define ESE_DZ_L4_CLASS_RSVD3 3 -#define ESE_DZ_L4_CLASS_UDP 2 -#define ESE_DZ_L4_CLASS_TCP 1 -#define ESE_DZ_L4_CLASS_UNKNOWN 0 +#define ESF_DE_RX_L4_CLASS_LBN 45 +#define ESF_DE_RX_L4_CLASS_WIDTH 3 +#define ESE_DE_L4_CLASS_RSVD7 7 +#define ESE_DE_L4_CLASS_RSVD6 6 +#define ESE_DE_L4_CLASS_RSVD5 5 +#define ESE_DE_L4_CLASS_RSVD4 4 +#define ESE_DE_L4_CLASS_RSVD3 3 +#define ESE_DE_L4_CLASS_UDP 2 +#define ESE_DE_L4_CLASS_TCP 1 +#define ESE_DE_L4_CLASS_UNKNOWN 0 +#define ESF_FZ_RX_FASTPD_INDCTR_LBN 47 +#define ESF_FZ_RX_FASTPD_INDCTR_WIDTH 1 +#define ESF_FZ_RX_L4_CLASS_LBN 45 +#define ESF_FZ_RX_L4_CLASS_WIDTH 2 +#define ESE_FZ_L4_CLASS_RSVD3 3 +#define ESE_FZ_L4_CLASS_UDP 2 +#define ESE_FZ_L4_CLASS_TCP 1 +#define ESE_FZ_L4_CLASS_UNKNOWN 0 #define ESF_DZ_RX_L3_CLASS_LBN 42 #define ESF_DZ_RX_L3_CLASS_WIDTH 3 #define ESE_DZ_L3_CLASS_RSVD7 7 @@ -215,6 +225,8 @@ #define ESF_EZ_RX_ABORT_WIDTH 1 #define ESF_DZ_RX_ECC_ERR_LBN 29 #define ESF_DZ_RX_ECC_ERR_WIDTH 1 +#define ESF_DZ_RX_TRUNC_ERR_LBN 29 +#define ESF_DZ_RX_TRUNC_ERR_WIDTH 1 #define ESF_DZ_RX_CRC1_ERR_LBN 28 #define ESF_DZ_RX_CRC1_ERR_WIDTH 1 #define ESF_DZ_RX_CRC0_ERR_LBN 27 @@ -332,6 +344,8 @@ #define ESE_DZ_TX_OPTION_DESC_CRC_CSUM 0 #define ESF_DZ_TX_TSO_OPTION_TYPE_LBN 56 #define ESF_DZ_TX_TSO_OPTION_TYPE_WIDTH 4 +#define ESE_DZ_TX_TSO_OPTION_DESC_FATSO2B 3 +#define ESE_DZ_TX_TSO_OPTION_DESC_FATSO2A 2 #define ESE_DZ_TX_TSO_OPTION_DESC_ENCAP 1 #define ESE_DZ_TX_TSO_OPTION_DESC_NORMAL 0 #define ESF_DZ_TX_TSO_TCP_FLAGS_LBN 48 @@ -341,7 +355,7 @@ #define ESF_DZ_TX_TSO_TCP_SEQNO_LBN 0 #define ESF_DZ_TX_TSO_TCP_SEQNO_WIDTH 32 -/* TX_TSO_FATSO2A_DESC */ +/* TX_TSO_V2_DESC_A */ #define ESF_DZ_TX_DESC_IS_OPT_LBN 63 #define ESF_DZ_TX_DESC_IS_OPT_WIDTH 1 #define ESF_DZ_TX_OPTION_TYPE_LBN 60 @@ -360,8 +374,7 @@ #define ESF_DZ_TX_TSO_TCP_SEQNO_LBN 0 #define ESF_DZ_TX_TSO_TCP_SEQNO_WIDTH 32 - -/* TX_TSO_FATSO2B_DESC */ +/* TX_TSO_V2_DESC_B */ #define ESF_DZ_TX_DESC_IS_OPT_LBN 63 #define ESF_DZ_TX_DESC_IS_OPT_WIDTH 1 #define ESF_DZ_TX_OPTION_TYPE_LBN 60 @@ -375,11 +388,10 @@ #define ESE_DZ_TX_TSO_OPTION_DESC_FATSO2A 2 #define ESE_DZ_TX_TSO_OPTION_DESC_ENCAP 1 #define ESE_DZ_TX_TSO_OPTION_DESC_NORMAL 0 -#define ESF_DZ_TX_TSO_OUTER_IP_ID_LBN 0 -#define ESF_DZ_TX_TSO_OUTER_IP_ID_WIDTH 16 #define ESF_DZ_TX_TSO_TCP_MSS_LBN 32 #define ESF_DZ_TX_TSO_TCP_MSS_WIDTH 16 - +#define ESF_DZ_TX_TSO_OUTER_IPID_LBN 0 +#define ESF_DZ_TX_TSO_OUTER_IPID_WIDTH 16 /*************************************************************************/ diff --git a/drivers/net/ethernet/sfc/efx.c b/drivers/net/ethernet/sfc/efx.c index e3c492fcaff0..7bcbedce07a5 100644 --- a/drivers/net/ethernet/sfc/efx.c +++ b/drivers/net/ethernet/sfc/efx.c @@ -27,6 +27,7 @@ #include <net/udp_tunnel.h> #include "efx.h" #include "nic.h" +#include "io.h" #include "selftest.h" #include "sriov.h" @@ -1248,7 +1249,7 @@ static int efx_init_io(struct efx_nic *efx) netif_dbg(efx, probe, efx->net_dev, "initialising I/O\n"); - bar = efx->type->mem_bar; + bar = efx->type->mem_bar(efx); rc = pci_enable_device(pci_dev); if (rc) { @@ -1323,7 +1324,7 @@ static void efx_fini_io(struct efx_nic *efx) } if (efx->membase_phys) { - bar = efx->type->mem_bar; + bar = efx->type->mem_bar(efx); pci_release_region(efx->pci_dev, bar); efx->membase_phys = 0; } @@ -2909,6 +2910,10 @@ static const struct pci_device_id efx_pci_table[] = { .driver_data = (unsigned long) &efx_hunt_a0_nic_type}, {PCI_DEVICE(PCI_VENDOR_ID_SOLARFLARE, 0x1a03), /* SFC9220 VF */ .driver_data = (unsigned long) &efx_hunt_a0_vf_nic_type}, + {PCI_DEVICE(PCI_VENDOR_ID_SOLARFLARE, 0x0b03), /* SFC9250 PF */ + .driver_data = (unsigned long) &efx_hunt_a0_nic_type}, + {PCI_DEVICE(PCI_VENDOR_ID_SOLARFLARE, 0x1b03), /* SFC9250 VF */ + .driver_data = (unsigned long) &efx_hunt_a0_vf_nic_type}, {0} /* end of list */ }; @@ -2977,6 +2982,7 @@ static int efx_init_struct(struct efx_nic *efx, efx->rx_packet_ts_offset = efx->type->rx_ts_offset - efx->type->rx_prefix_size; spin_lock_init(&efx->stats_lock); + efx->vi_stride = EFX_DEFAULT_VI_STRIDE; mutex_init(&efx->mac_lock); efx->phy_op = &efx_dummy_phy_operations; efx->mdio.dev = net_dev; diff --git a/drivers/net/ethernet/sfc/efx.h b/drivers/net/ethernet/sfc/efx.h index 52c84b782901..16da3e9a6000 100644 --- a/drivers/net/ethernet/sfc/efx.h +++ b/drivers/net/ethernet/sfc/efx.h @@ -14,11 +14,6 @@ #include "net_driver.h" #include "filter.h" -/* All controllers use BAR 0 for I/O space and BAR 2(&3) for memory */ -/* All VFs use BAR 0/1 for memory */ -#define EFX_MEM_BAR 2 -#define EFX_MEM_VF_BAR 0 - int efx_net_open(struct net_device *net_dev); int efx_net_stop(struct net_device *net_dev); diff --git a/drivers/net/ethernet/sfc/io.h b/drivers/net/ethernet/sfc/io.h index afb94aa2c15e..89563170af52 100644 --- a/drivers/net/ethernet/sfc/io.h +++ b/drivers/net/ethernet/sfc/io.h @@ -222,18 +222,21 @@ static inline void efx_reado_table(struct efx_nic *efx, efx_oword_t *value, efx_reado(efx, value, reg + index * sizeof(efx_oword_t)); } -/* Page size used as step between per-VI registers */ -#define EFX_VI_PAGE_SIZE 0x2000 +/* default VI stride (step between per-VI registers) is 8K */ +#define EFX_DEFAULT_VI_STRIDE 0x2000 /* Calculate offset to page-mapped register */ -#define EFX_PAGED_REG(page, reg) \ - ((page) * EFX_VI_PAGE_SIZE + (reg)) +static inline unsigned int efx_paged_reg(struct efx_nic *efx, unsigned int page, + unsigned int reg) +{ + return page * efx->vi_stride + reg; +} /* Write the whole of RX_DESC_UPD or TX_DESC_UPD */ static inline void _efx_writeo_page(struct efx_nic *efx, efx_oword_t *value, unsigned int reg, unsigned int page) { - reg = EFX_PAGED_REG(page, reg); + reg = efx_paged_reg(efx, page, reg); netif_vdbg(efx, hw, efx->net_dev, "writing register %x with " EFX_OWORD_FMT "\n", reg, @@ -262,7 +265,7 @@ static inline void _efx_writed_page(struct efx_nic *efx, const efx_dword_t *value, unsigned int reg, unsigned int page) { - efx_writed(efx, value, EFX_PAGED_REG(page, reg)); + efx_writed(efx, value, efx_paged_reg(efx, page, reg)); } #define efx_writed_page(efx, value, reg, page) \ _efx_writed_page(efx, value, \ @@ -288,10 +291,10 @@ static inline void _efx_writed_page_locked(struct efx_nic *efx, if (page == 0) { spin_lock_irqsave(&efx->biu_lock, flags); - efx_writed(efx, value, EFX_PAGED_REG(page, reg)); + efx_writed(efx, value, efx_paged_reg(efx, page, reg)); spin_unlock_irqrestore(&efx->biu_lock, flags); } else { - efx_writed(efx, value, EFX_PAGED_REG(page, reg)); + efx_writed(efx, value, efx_paged_reg(efx, page, reg)); } } #define efx_writed_page_locked(efx, value, reg, page) \ diff --git a/drivers/net/ethernet/sfc/mcdi.h b/drivers/net/ethernet/sfc/mcdi.h index 154ef41d1927..ebd95972ae7b 100644 --- a/drivers/net/ethernet/sfc/mcdi.h +++ b/drivers/net/ethernet/sfc/mcdi.h @@ -208,6 +208,9 @@ void efx_mcdi_sensor_event(struct efx_nic *efx, efx_qword_t *ev); #define _MCDI_DWORD(_buf, _field) \ ((_buf) + (_MCDI_CHECK_ALIGN(MC_CMD_ ## _field ## _OFST, 4) >> 2)) +#define MCDI_BYTE(_buf, _field) \ + ((void)BUILD_BUG_ON_ZERO(MC_CMD_ ## _field ## _LEN != 1), \ + *MCDI_PTR(_buf, _field)) #define MCDI_WORD(_buf, _field) \ ((u16)BUILD_BUG_ON_ZERO(MC_CMD_ ## _field ## _LEN != 2) + \ le16_to_cpu(*(__force const __le16 *)MCDI_PTR(_buf, _field))) diff --git a/drivers/net/ethernet/sfc/net_driver.h b/drivers/net/ethernet/sfc/net_driver.h index c0537ea06c9a..6b8730a24513 100644 --- a/drivers/net/ethernet/sfc/net_driver.h +++ b/drivers/net/ethernet/sfc/net_driver.h @@ -708,6 +708,7 @@ struct vfdi_status; * @reset_work: Scheduled reset workitem * @membase_phys: Memory BAR value as physical address * @membase: Memory BAR value + * @vi_stride: step between per-VI registers / memory regions * @interrupt_mode: Interrupt mode * @timer_quantum_ns: Interrupt timer quantum, in nanoseconds * @timer_max_ns: Interrupt timer maximum value, in nanoseconds @@ -812,6 +813,7 @@ struct vfdi_status; * @vf_init_count: Number of VFs that have been fully initialised. * @vi_scale: log2 number of vnics per VF. * @ptp_data: PTP state data + * @ptp_warned: has this NIC seen and warned about unexpected PTP events? * @vpd_sn: Serial number read from VPD * @monitor_work: Hardware monitor workitem * @biu_lock: BIU (bus interface unit) lock @@ -842,6 +844,8 @@ struct efx_nic { resource_size_t membase_phys; void __iomem *membase; + unsigned int vi_stride; + enum efx_int_mode interrupt_mode; unsigned int timer_quantum_ns; unsigned int timer_max_ns; @@ -965,6 +969,7 @@ struct efx_nic { #endif struct efx_ptp_data *ptp_data; + bool ptp_warned; char *vpd_sn; @@ -1154,7 +1159,7 @@ struct efx_udp_tunnel { */ struct efx_nic_type { bool is_vf; - unsigned int mem_bar; + unsigned int (*mem_bar)(struct efx_nic *efx); unsigned int (*mem_map_size)(struct efx_nic *efx); int (*probe)(struct efx_nic *efx); void (*remove)(struct efx_nic *efx); diff --git a/drivers/net/ethernet/sfc/ptp.c b/drivers/net/ethernet/sfc/ptp.c index caa89bf7603e..3b37d7ded3c4 100644 --- a/drivers/net/ethernet/sfc/ptp.c +++ b/drivers/net/ethernet/sfc/ptp.c @@ -1662,9 +1662,11 @@ void efx_ptp_event(struct efx_nic *efx, efx_qword_t *ev) int code = EFX_QWORD_FIELD(*ev, MCDI_EVENT_CODE); if (!ptp) { - if (net_ratelimit()) + if (!efx->ptp_warned) { netif_warn(efx, drv, efx->net_dev, "Received PTP event but PTP not set up\n"); + efx->ptp_warned = true; + } return; } diff --git a/drivers/net/ethernet/sfc/siena.c b/drivers/net/ethernet/sfc/siena.c index a617f657eae3..22d49ebb347c 100644 --- a/drivers/net/ethernet/sfc/siena.c +++ b/drivers/net/ethernet/sfc/siena.c @@ -242,6 +242,14 @@ static int siena_dimension_resources(struct efx_nic *efx) return 0; } +/* On all Falcon-architecture NICs, PFs use BAR 0 for I/O space and BAR 2(&3) + * for memory. + */ +static unsigned int siena_mem_bar(struct efx_nic *efx) +{ + return 2; +} + static unsigned int siena_mem_map_size(struct efx_nic *efx) { return FR_CZ_MC_TREG_SMEM + @@ -950,7 +958,7 @@ fail: const struct efx_nic_type siena_a0_nic_type = { .is_vf = false, - .mem_bar = EFX_MEM_BAR, + .mem_bar = siena_mem_bar, .mem_map_size = siena_mem_map_size, .probe = siena_probe_nic, .remove = siena_remove_nic, |