netdev.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH net-next 00/15] sfc_ef100: driver for EF100 family NICs, part 1
@ 2020-07-03 15:28 Edward Cree
  2020-07-03 15:30 ` [PATCH net-next 01/15] sfc_ef100: add EF100 register definitions Edward Cree
                   ` (14 more replies)
  0 siblings, 15 replies; 25+ messages in thread
From: Edward Cree @ 2020-07-03 15:28 UTC (permalink / raw)
  To: linux-net-drivers, davem; +Cc: netdev

In order to maintain bisectability while splitting into patches of a
 reasonable size, I had to do a certain amount of back-and-forth with
 stubs for things that the common code may try to call, mainly because
 we can't do them until we've set up MCDI, but we can't set up MCDI
 without probing the event queues, at which point a lot of the common
 machinery becomes reachable from event handlers.
Consequently, this first series doesn't get as far as actually sending
 and receiving packets.  I have a second series ready to follow it
 which implements the datapath (and a few other things like ethtool).

(Would folks prefer the whole thing submitted in one series?  It's 27
 patches in total.)

Edward Cree (15):
  sfc_ef100: add EF100 register definitions
  sfc_ef100: register accesses on EF100
  sfc_ef100: skeleton EF100 PF driver
  sfc_ef100: reset-handling stub
  sfc_ef100: PHY probe stub
  sfc_ef100: don't call efx_reset_down()/up() on EF100
  sfc_ef100: implement MCDI transport
  sfc_ef100: implement ndo_open/close and EVQ probing
  sfc_ef100: process events for MCDI completions
  sfc_ef100: read datapath caps, implement check_caps
  sfc_ef100: extend ef100_check_caps to cover datapath_caps3
  sfc_ef100: actually perform resets
  sfc_ef100: probe the PHY and configure the MAC
  sfc_ef100: read device MAC address at probe time
  sfc_ef100: implement ndo_get_phys_port_{id,name}

 drivers/net/ethernet/sfc/Kconfig         |  10 +
 drivers/net/ethernet/sfc/Makefile        |   8 +
 drivers/net/ethernet/sfc/ef100.c         | 583 +++++++++++++++++++
 drivers/net/ethernet/sfc/ef100_ethtool.c |  26 +
 drivers/net/ethernet/sfc/ef100_ethtool.h |  12 +
 drivers/net/ethernet/sfc/ef100_netdev.c  | 280 +++++++++
 drivers/net/ethernet/sfc/ef100_netdev.h  |  17 +
 drivers/net/ethernet/sfc/ef100_nic.c     | 620 ++++++++++++++++++++
 drivers/net/ethernet/sfc/ef100_nic.h     |  32 ++
 drivers/net/ethernet/sfc/ef100_regs.h    | 693 +++++++++++++++++++++++
 drivers/net/ethernet/sfc/ef100_rx.c      |  30 +
 drivers/net/ethernet/sfc/ef100_rx.h      |  19 +
 drivers/net/ethernet/sfc/ef100_tx.c      |  62 ++
 drivers/net/ethernet/sfc/ef100_tx.h      |  22 +
 drivers/net/ethernet/sfc/efx_common.c    |   9 +-
 drivers/net/ethernet/sfc/io.h            |  16 +-
 drivers/net/ethernet/sfc/mcdi.h          |   4 +-
 drivers/net/ethernet/sfc/net_driver.h    |  14 +-
 18 files changed, 2449 insertions(+), 8 deletions(-)
 create mode 100644 drivers/net/ethernet/sfc/ef100.c
 create mode 100644 drivers/net/ethernet/sfc/ef100_ethtool.c
 create mode 100644 drivers/net/ethernet/sfc/ef100_ethtool.h
 create mode 100644 drivers/net/ethernet/sfc/ef100_netdev.c
 create mode 100644 drivers/net/ethernet/sfc/ef100_netdev.h
 create mode 100644 drivers/net/ethernet/sfc/ef100_nic.c
 create mode 100644 drivers/net/ethernet/sfc/ef100_nic.h
 create mode 100644 drivers/net/ethernet/sfc/ef100_regs.h
 create mode 100644 drivers/net/ethernet/sfc/ef100_rx.c
 create mode 100644 drivers/net/ethernet/sfc/ef100_rx.h
 create mode 100644 drivers/net/ethernet/sfc/ef100_tx.c
 create mode 100644 drivers/net/ethernet/sfc/ef100_tx.h


^ permalink raw reply	[flat|nested] 25+ messages in thread

* [PATCH net-next 01/15] sfc_ef100: add EF100 register definitions
  2020-07-03 15:28 [PATCH net-next 00/15] sfc_ef100: driver for EF100 family NICs, part 1 Edward Cree
@ 2020-07-03 15:30 ` Edward Cree
  2020-07-03 15:30 ` [PATCH net-next 02/15] sfc_ef100: register accesses on EF100 Edward Cree
                   ` (13 subsequent siblings)
  14 siblings, 0 replies; 25+ messages in thread
From: Edward Cree @ 2020-07-03 15:30 UTC (permalink / raw)
  To: linux-net-drivers, davem; +Cc: netdev

Signed-off-by: Edward Cree <ecree@solarflare.com>
---
 drivers/net/ethernet/sfc/ef100_regs.h | 693 ++++++++++++++++++++++++++
 1 file changed, 693 insertions(+)
 create mode 100644 drivers/net/ethernet/sfc/ef100_regs.h

diff --git a/drivers/net/ethernet/sfc/ef100_regs.h b/drivers/net/ethernet/sfc/ef100_regs.h
new file mode 100644
index 000000000000..710bbdb19885
--- /dev/null
+++ b/drivers/net/ethernet/sfc/ef100_regs.h
@@ -0,0 +1,693 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+/****************************************************************************
+ * Driver for Solarflare network controllers and boards
+ * Copyright 2018 Solarflare Communications Inc.
+ * Copyright 2019-2020 Xilinx 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
+ * by the Free Software Foundation, incorporated herein by reference.
+ */
+
+#ifndef EFX_EF100_REGS_H
+#define EFX_EF100_REGS_H
+
+/* EF100 hardware architecture definitions have a name prefix following
+ * the format:
+ *
+ *     E<type>_<min-rev><max-rev>_
+ *
+ * The following <type> strings are used:
+ *
+ *             MMIO register  Host memory structure
+ * -------------------------------------------------------------
+ * Address     R
+ * Bitfield    RF             SF
+ * Enumerator  FE             SE
+ *
+ * <min-rev> is the first revision to which the definition applies:
+ *
+ *     G: Riverhead
+ *
+ * If the definition has been changed or removed in later revisions
+ * then <max-rev> is the last revision to which the definition applies;
+ * otherwise it is "Z".
+ */
+
+/**************************************************************************
+ *
+ * EF100 registers and descriptors
+ *
+ **************************************************************************
+ */
+
+/* HW_REV_ID_REG: Hardware revision info register */
+#define	ER_GZ_HW_REV_ID 0x00000000
+
+/* NIC_REV_ID: SoftNIC revision info register */
+#define	ER_GZ_NIC_REV_ID 0x00000004
+
+/* NIC_MAGIC: Signature register that should contain a well-known value */
+#define	ER_GZ_NIC_MAGIC 0x00000008
+#define	ERF_GZ_NIC_MAGIC_LBN 0
+#define	ERF_GZ_NIC_MAGIC_WIDTH 32
+#define	EFE_GZ_NIC_MAGIC_EXPECTED 0xEF100FCB
+
+/* MC_SFT_STATUS: MC soft status */
+#define	ER_GZ_MC_SFT_STATUS 0x00000010
+#define	ER_GZ_MC_SFT_STATUS_STEP 4
+#define	ER_GZ_MC_SFT_STATUS_ROWS 2
+
+/* MC_DB_LWRD_REG: MC doorbell register, low word */
+#define	ER_GZ_MC_DB_LWRD 0x00000020
+
+/* MC_DB_HWRD_REG: MC doorbell register, high word */
+#define	ER_GZ_MC_DB_HWRD 0x00000024
+
+/* EVQ_INT_PRIME: Prime EVQ */
+#define	ER_GZ_EVQ_INT_PRIME 0x00000040
+#define	ERF_GZ_IDX_LBN 16
+#define	ERF_GZ_IDX_WIDTH 16
+#define	ERF_GZ_EVQ_ID_LBN 0
+#define	ERF_GZ_EVQ_ID_WIDTH 16
+
+/* INT_AGG_RING_PRIME: Prime interrupt aggregation ring. */
+#define	ER_GZ_INT_AGG_RING_PRIME 0x00000048
+/* defined as ERF_GZ_IDX_LBN 16; access=WO reset=0x0 */
+/* defined as ERF_GZ_IDX_WIDTH 16 */
+#define	ERF_GZ_RING_ID_LBN 0
+#define	ERF_GZ_RING_ID_WIDTH 16
+
+/* EVQ_TMR: EVQ timer control */
+#define	ER_GZ_EVQ_TMR 0x00000104
+#define	ER_GZ_EVQ_TMR_STEP 65536
+#define	ER_GZ_EVQ_TMR_ROWS 1024
+
+/* EVQ_UNSOL_CREDIT_GRANT_SEQ: Grant credits for unsolicited events. */
+#define	ER_GZ_EVQ_UNSOL_CREDIT_GRANT_SEQ 0x00000108
+#define	ER_GZ_EVQ_UNSOL_CREDIT_GRANT_SEQ_STEP 65536
+#define	ER_GZ_EVQ_UNSOL_CREDIT_GRANT_SEQ_ROWS 1024
+
+/* EVQ_DESC_CREDIT_GRANT_SEQ: Grant credits for descriptor proxy events. */
+#define	ER_GZ_EVQ_DESC_CREDIT_GRANT_SEQ 0x00000110
+#define	ER_GZ_EVQ_DESC_CREDIT_GRANT_SEQ_STEP 65536
+#define	ER_GZ_EVQ_DESC_CREDIT_GRANT_SEQ_ROWS 1024
+
+/* RX_RING_DOORBELL: Ring Rx doorbell. */
+#define	ER_GZ_RX_RING_DOORBELL 0x00000180
+#define	ER_GZ_RX_RING_DOORBELL_STEP 65536
+#define	ER_GZ_RX_RING_DOORBELL_ROWS 1024
+#define	ERF_GZ_RX_RING_PIDX_LBN 16
+#define	ERF_GZ_RX_RING_PIDX_WIDTH 16
+
+/* TX_RING_DOORBELL: Ring Tx doorbell. */
+#define	ER_GZ_TX_RING_DOORBELL 0x00000200
+#define	ER_GZ_TX_RING_DOORBELL_STEP 65536
+#define	ER_GZ_TX_RING_DOORBELL_ROWS 1024
+#define	ERF_GZ_TX_RING_PIDX_LBN 16
+#define	ERF_GZ_TX_RING_PIDX_WIDTH 16
+
+/* TX_DESC_PUSH: Tx ring descriptor push. Reserved for future use. */
+#define	ER_GZ_TX_DESC_PUSH 0x00000210
+#define	ER_GZ_TX_DESC_PUSH_STEP 65536
+#define	ER_GZ_TX_DESC_PUSH_ROWS 1024
+
+/* THE_TIME: NIC hardware time */
+#define	ER_GZ_THE_TIME 0x00000280
+#define	ER_GZ_THE_TIME_STEP 65536
+#define	ER_GZ_THE_TIME_ROWS 1024
+#define	ERF_GZ_THE_TIME_SECS_LBN 32
+#define	ERF_GZ_THE_TIME_SECS_WIDTH 32
+#define	ERF_GZ_THE_TIME_NANOS_LBN 2
+#define	ERF_GZ_THE_TIME_NANOS_WIDTH 30
+#define	ERF_GZ_THE_TIME_CLOCK_IN_SYNC_LBN 1
+#define	ERF_GZ_THE_TIME_CLOCK_IN_SYNC_WIDTH 1
+#define	ERF_GZ_THE_TIME_CLOCK_IS_SET_LBN 0
+#define	ERF_GZ_THE_TIME_CLOCK_IS_SET_WIDTH 1
+
+/* PARAMS_TLV_LEN: Size of design parameters area in bytes */
+#define	ER_GZ_PARAMS_TLV_LEN 0x00000c00
+#define	ER_GZ_PARAMS_TLV_LEN_STEP 65536
+#define	ER_GZ_PARAMS_TLV_LEN_ROWS 1024
+
+/* PARAMS_TLV: Design parameters */
+#define	ER_GZ_PARAMS_TLV 0x00000c04
+#define	ER_GZ_PARAMS_TLV_STEP 65536
+#define	ER_GZ_PARAMS_TLV_ROWS 1024
+
+/* EW_EMBEDDED_EVENT */
+#define	ESF_GZ_EV_256_EVENT_LBN 0
+#define	ESF_GZ_EV_256_EVENT_WIDTH 64
+#define	ESE_GZ_EW_EMBEDDED_EVENT_STRUCT_SIZE 64
+
+/* NMMU_PAGESZ_2M_ADDR */
+#define	ESF_GZ_NMMU_2M_PAGE_SIZE_ID_LBN 59
+#define	ESF_GZ_NMMU_2M_PAGE_SIZE_ID_WIDTH 5
+#define	ESE_GZ_NMMU_PAGE_SIZE_2M 9
+#define	ESF_GZ_NMMU_2M_PAGE_ID_LBN 21
+#define	ESF_GZ_NMMU_2M_PAGE_ID_WIDTH 38
+#define	ESF_GZ_NMMU_2M_PAGE_OFFSET_LBN 0
+#define	ESF_GZ_NMMU_2M_PAGE_OFFSET_WIDTH 21
+#define	ESE_GZ_NMMU_PAGESZ_2M_ADDR_STRUCT_SIZE 64
+
+/* PARAM_TLV */
+#define	ESF_GZ_TLV_VALUE_LBN 16
+#define	ESF_GZ_TLV_VALUE_WIDTH 8
+#define	ESE_GZ_TLV_VALUE_LENMIN 8
+#define	ESE_GZ_TLV_VALUE_LENMAX 2040
+#define	ESF_GZ_TLV_LEN_LBN 8
+#define	ESF_GZ_TLV_LEN_WIDTH 8
+#define	ESF_GZ_TLV_TYPE_LBN 0
+#define	ESF_GZ_TLV_TYPE_WIDTH 8
+#define	ESE_GZ_DP_NMMU_GROUP_SIZE 5
+#define	ESE_GZ_DP_EVQ_UNSOL_CREDIT_SEQ_BITS 4
+#define	ESE_GZ_DP_TX_EV_NUM_DESCS_BITS 3
+#define	ESE_GZ_DP_RX_EV_NUM_PACKETS_BITS 2
+#define	ESE_GZ_DP_PARTIAL_TSTAMP_SUB_NANO_BITS 1
+#define	ESE_GZ_DP_PAD 0
+#define	ESE_GZ_PARAM_TLV_STRUCT_SIZE 24
+
+/* PCI_EXPRESS_XCAP_HDR */
+#define	ESF_GZ_PCI_EXPRESS_XCAP_NEXT_LBN 20
+#define	ESF_GZ_PCI_EXPRESS_XCAP_NEXT_WIDTH 12
+#define	ESF_GZ_PCI_EXPRESS_XCAP_VER_LBN 16
+#define	ESF_GZ_PCI_EXPRESS_XCAP_VER_WIDTH 4
+#define	ESE_GZ_PCI_EXPRESS_XCAP_VER_VSEC 1
+#define	ESF_GZ_PCI_EXPRESS_XCAP_ID_LBN 0
+#define	ESF_GZ_PCI_EXPRESS_XCAP_ID_WIDTH 16
+#define	ESE_GZ_PCI_EXPRESS_XCAP_ID_VNDR 0xb
+#define	ESE_GZ_PCI_EXPRESS_XCAP_HDR_STRUCT_SIZE 32
+
+/* RHEAD_BASE_EVENT */
+#define	ESF_GZ_E_TYPE_LBN 60
+#define	ESF_GZ_E_TYPE_WIDTH 4
+#define	ESE_GZ_EF100_EV_DRIVER 5
+#define	ESE_GZ_EF100_EV_MCDI 4
+#define	ESE_GZ_EF100_EV_CONTROL 3
+#define	ESE_GZ_EF100_EV_TX_TIMESTAMP 2
+#define	ESE_GZ_EF100_EV_TX_COMPLETION 1
+#define	ESE_GZ_EF100_EV_RX_PKTS 0
+#define	ESF_GZ_EV_EVQ_PHASE_LBN 59
+#define	ESF_GZ_EV_EVQ_PHASE_WIDTH 1
+#define	ESE_GZ_RHEAD_BASE_EVENT_STRUCT_SIZE 64
+
+/* RHEAD_EW_EVENT */
+#define	ESF_GZ_EV_256_EV32_PHASE_LBN 255
+#define	ESF_GZ_EV_256_EV32_PHASE_WIDTH 1
+#define	ESF_GZ_EV_256_EV32_TYPE_LBN 251
+#define	ESF_GZ_EV_256_EV32_TYPE_WIDTH 4
+#define	ESE_GZ_EF100_EVEW_VIRTQ_DESC 2
+#define	ESE_GZ_EF100_EVEW_TXQ_DESC 1
+#define	ESE_GZ_EF100_EVEW_64BIT 0
+#define	ESE_GZ_RHEAD_EW_EVENT_STRUCT_SIZE 256
+
+/* RX_DESC */
+#define	ESF_GZ_RX_BUF_ADDR_LBN 0
+#define	ESF_GZ_RX_BUF_ADDR_WIDTH 64
+#define	ESE_GZ_RX_DESC_STRUCT_SIZE 64
+
+/* TXQ_DESC_PROXY_EVENT */
+#define	ESF_GZ_EV_TXQ_DP_VI_ID_LBN 128
+#define	ESF_GZ_EV_TXQ_DP_VI_ID_WIDTH 16
+#define	ESF_GZ_EV_TXQ_DP_TXQ_DESC_LBN 0
+#define	ESF_GZ_EV_TXQ_DP_TXQ_DESC_WIDTH 128
+#define	ESE_GZ_TXQ_DESC_PROXY_EVENT_STRUCT_SIZE 144
+
+/* TX_DESC_TYPE */
+#define	ESF_GZ_TX_DESC_TYPE_LBN 124
+#define	ESF_GZ_TX_DESC_TYPE_WIDTH 4
+#define	ESE_GZ_TX_DESC_TYPE_DESC2CMPT 7
+#define	ESE_GZ_TX_DESC_TYPE_MEM2MEM 4
+#define	ESE_GZ_TX_DESC_TYPE_SEG 3
+#define	ESE_GZ_TX_DESC_TYPE_TSO 2
+#define	ESE_GZ_TX_DESC_TYPE_PREFIX 1
+#define	ESE_GZ_TX_DESC_TYPE_SEND 0
+#define	ESE_GZ_TX_DESC_TYPE_STRUCT_SIZE 128
+
+/* VIRTQ_DESC_PROXY_EVENT */
+#define	ESF_GZ_EV_VQ_DP_AVAIL_ENTRY_LBN 144
+#define	ESF_GZ_EV_VQ_DP_AVAIL_ENTRY_WIDTH 16
+#define	ESF_GZ_EV_VQ_DP_VI_ID_LBN 128
+#define	ESF_GZ_EV_VQ_DP_VI_ID_WIDTH 16
+#define	ESF_GZ_EV_VQ_DP_VIRTQ_DESC_LBN 0
+#define	ESF_GZ_EV_VQ_DP_VIRTQ_DESC_WIDTH 128
+#define	ESE_GZ_VIRTQ_DESC_PROXY_EVENT_STRUCT_SIZE 160
+
+/* XIL_CFGBAR_TBL_ENTRY */
+#define	ESF_GZ_CFGBAR_CONT_CAP_OFF_HI_LBN 96
+#define	ESF_GZ_CFGBAR_CONT_CAP_OFF_HI_WIDTH 32
+#define	ESF_GZ_CFGBAR_CONT_CAP_OFFSET_LBN 68
+#define	ESF_GZ_CFGBAR_CONT_CAP_OFFSET_WIDTH 60
+#define	ESE_GZ_CONT_CAP_OFFSET_BYTES_SHIFT 4
+#define	ESF_GZ_CFGBAR_EF100_FUNC_CTL_WIN_OFF_LBN 67
+#define	ESF_GZ_CFGBAR_EF100_FUNC_CTL_WIN_OFF_WIDTH 29
+#define	ESE_GZ_EF100_FUNC_CTL_WIN_OFF_SHIFT 4
+#define	ESF_GZ_CFGBAR_CONT_CAP_OFF_LO_LBN 68
+#define	ESF_GZ_CFGBAR_CONT_CAP_OFF_LO_WIDTH 28
+#define	ESF_GZ_CFGBAR_CONT_CAP_RSV_LBN 67
+#define	ESF_GZ_CFGBAR_CONT_CAP_RSV_WIDTH 1
+#define	ESF_GZ_CFGBAR_EF100_BAR_LBN 64
+#define	ESF_GZ_CFGBAR_EF100_BAR_WIDTH 3
+#define	ESE_GZ_CFGBAR_EF100_BAR_NUM_INVALID 7
+#define	ESE_GZ_CFGBAR_EF100_BAR_NUM_EXPANSION_ROM 6
+#define	ESF_GZ_CFGBAR_CONT_CAP_BAR_LBN 64
+#define	ESF_GZ_CFGBAR_CONT_CAP_BAR_WIDTH 3
+#define	ESE_GZ_CFGBAR_CONT_CAP_BAR_NUM_INVALID 7
+#define	ESE_GZ_CFGBAR_CONT_CAP_BAR_NUM_EXPANSION_ROM 6
+#define	ESF_GZ_CFGBAR_ENTRY_SIZE_LBN 32
+#define	ESF_GZ_CFGBAR_ENTRY_SIZE_WIDTH 32
+#define	ESE_GZ_CFGBAR_ENTRY_SIZE_EF100 12
+#define	ESE_GZ_CFGBAR_ENTRY_HEADER_SIZE 8
+#define	ESF_GZ_CFGBAR_ENTRY_LAST_LBN 28
+#define	ESF_GZ_CFGBAR_ENTRY_LAST_WIDTH 1
+#define	ESF_GZ_CFGBAR_ENTRY_REV_LBN 20
+#define	ESF_GZ_CFGBAR_ENTRY_REV_WIDTH 8
+#define	ESE_GZ_CFGBAR_ENTRY_REV_EF100 0
+#define	ESF_GZ_CFGBAR_ENTRY_FORMAT_LBN 0
+#define	ESF_GZ_CFGBAR_ENTRY_FORMAT_WIDTH 20
+#define	ESE_GZ_CFGBAR_ENTRY_LAST 0xfffff
+#define	ESE_GZ_CFGBAR_ENTRY_CONT_CAP_ADDR 0xffffe
+#define	ESE_GZ_CFGBAR_ENTRY_EF100 0xef100
+#define	ESE_GZ_XIL_CFGBAR_TBL_ENTRY_STRUCT_SIZE 128
+
+/* XIL_CFGBAR_VSEC */
+#define	ESF_GZ_VSEC_TBL_OFF_HI_LBN 64
+#define	ESF_GZ_VSEC_TBL_OFF_HI_WIDTH 32
+#define	ESE_GZ_VSEC_TBL_OFF_HI_BYTES_SHIFT 32
+#define	ESF_GZ_VSEC_TBL_OFF_LO_LBN 36
+#define	ESF_GZ_VSEC_TBL_OFF_LO_WIDTH 28
+#define	ESE_GZ_VSEC_TBL_OFF_LO_BYTES_SHIFT 4
+#define	ESF_GZ_VSEC_TBL_BAR_LBN 32
+#define	ESF_GZ_VSEC_TBL_BAR_WIDTH 4
+#define	ESE_GZ_VSEC_BAR_NUM_INVALID 7
+#define	ESE_GZ_VSEC_BAR_NUM_EXPANSION_ROM 6
+#define	ESF_GZ_VSEC_LEN_LBN 20
+#define	ESF_GZ_VSEC_LEN_WIDTH 12
+#define	ESE_GZ_VSEC_LEN_HIGH_OFFT 16
+#define	ESE_GZ_VSEC_LEN_MIN 12
+#define	ESF_GZ_VSEC_VER_LBN 16
+#define	ESF_GZ_VSEC_VER_WIDTH 4
+#define	ESE_GZ_VSEC_VER_XIL_CFGBAR 0
+#define	ESF_GZ_VSEC_ID_LBN 0
+#define	ESF_GZ_VSEC_ID_WIDTH 16
+#define	ESE_GZ_XILINX_VSEC_ID 0x20
+#define	ESE_GZ_XIL_CFGBAR_VSEC_STRUCT_SIZE 96
+
+/* rh_egres_hclass */
+#define	ESF_GZ_RX_PREFIX_HCLASS_TUN_OUTER_L4_CSUM_LBN 15
+#define	ESF_GZ_RX_PREFIX_HCLASS_TUN_OUTER_L4_CSUM_WIDTH 1
+#define	ESF_GZ_RX_PREFIX_HCLASS_TUN_OUTER_L3_CLASS_LBN 13
+#define	ESF_GZ_RX_PREFIX_HCLASS_TUN_OUTER_L3_CLASS_WIDTH 2
+#define	ESF_GZ_RX_PREFIX_HCLASS_NT_OR_INNER_L4_CSUM_LBN 12
+#define	ESF_GZ_RX_PREFIX_HCLASS_NT_OR_INNER_L4_CSUM_WIDTH 1
+#define	ESF_GZ_RX_PREFIX_HCLASS_NT_OR_INNER_L4_CLASS_LBN 10
+#define	ESF_GZ_RX_PREFIX_HCLASS_NT_OR_INNER_L4_CLASS_WIDTH 2
+#define	ESF_GZ_RX_PREFIX_HCLASS_NT_OR_INNER_L3_CLASS_LBN 8
+#define	ESF_GZ_RX_PREFIX_HCLASS_NT_OR_INNER_L3_CLASS_WIDTH 2
+#define	ESF_GZ_RX_PREFIX_HCLASS_TUNNEL_CLASS_LBN 5
+#define	ESF_GZ_RX_PREFIX_HCLASS_TUNNEL_CLASS_WIDTH 3
+#define	ESF_GZ_RX_PREFIX_HCLASS_L2_N_VLAN_LBN 3
+#define	ESF_GZ_RX_PREFIX_HCLASS_L2_N_VLAN_WIDTH 2
+#define	ESF_GZ_RX_PREFIX_HCLASS_L2_CLASS_LBN 2
+#define	ESF_GZ_RX_PREFIX_HCLASS_L2_CLASS_WIDTH 1
+#define	ESF_GZ_RX_PREFIX_HCLASS_L2_STATUS_LBN 0
+#define	ESF_GZ_RX_PREFIX_HCLASS_L2_STATUS_WIDTH 2
+#define	ESE_GZ_RH_EGRES_HCLASS_STRUCT_SIZE 16
+
+/* sf_driver */
+#define	ESF_GZ_DRIVER_E_TYPE_LBN 60
+#define	ESF_GZ_DRIVER_E_TYPE_WIDTH 4
+#define	ESF_GZ_DRIVER_PHASE_LBN 59
+#define	ESF_GZ_DRIVER_PHASE_WIDTH 1
+#define	ESF_GZ_DRIVER_DATA_LBN 0
+#define	ESF_GZ_DRIVER_DATA_WIDTH 59
+#define	ESE_GZ_SF_DRIVER_STRUCT_SIZE 64
+
+/* sf_ev_rsvd */
+#define	ESF_GZ_EV_RSVD_TBD_NEXT_LBN 34
+#define	ESF_GZ_EV_RSVD_TBD_NEXT_WIDTH 3
+#define	ESF_GZ_EV_RSVD_EVENT_GEN_FLAGS_LBN 30
+#define	ESF_GZ_EV_RSVD_EVENT_GEN_FLAGS_WIDTH 4
+#define	ESF_GZ_EV_RSVD_SRC_QID_LBN 18
+#define	ESF_GZ_EV_RSVD_SRC_QID_WIDTH 12
+#define	ESF_GZ_EV_RSVD_SEQ_NUM_LBN 2
+#define	ESF_GZ_EV_RSVD_SEQ_NUM_WIDTH 16
+#define	ESF_GZ_EV_RSVD_TBD_LBN 0
+#define	ESF_GZ_EV_RSVD_TBD_WIDTH 2
+#define	ESE_GZ_SF_EV_RSVD_STRUCT_SIZE 37
+
+/* sf_flush_evnt */
+#define	ESF_GZ_EV_FLSH_E_TYPE_LBN 60
+#define	ESF_GZ_EV_FLSH_E_TYPE_WIDTH 4
+#define	ESF_GZ_EV_FLSH_PHASE_LBN 59
+#define	ESF_GZ_EV_FLSH_PHASE_WIDTH 1
+#define	ESF_GZ_EV_FLSH_SUB_TYPE_LBN 53
+#define	ESF_GZ_EV_FLSH_SUB_TYPE_WIDTH 6
+#define	ESF_GZ_EV_FLSH_RSVD_LBN 10
+#define	ESF_GZ_EV_FLSH_RSVD_WIDTH 43
+#define	ESF_GZ_EV_FLSH_LABEL_LBN 4
+#define	ESF_GZ_EV_FLSH_LABEL_WIDTH 6
+#define	ESF_GZ_EV_FLSH_FLUSH_TYPE_LBN 0
+#define	ESF_GZ_EV_FLSH_FLUSH_TYPE_WIDTH 4
+#define	ESE_GZ_SF_FLUSH_EVNT_STRUCT_SIZE 64
+
+/* sf_rx_pkts */
+#define	ESF_GZ_EV_RXPKTS_E_TYPE_LBN 60
+#define	ESF_GZ_EV_RXPKTS_E_TYPE_WIDTH 4
+#define	ESF_GZ_EV_RXPKTS_PHASE_LBN 59
+#define	ESF_GZ_EV_RXPKTS_PHASE_WIDTH 1
+#define	ESF_GZ_EV_RXPKTS_RSVD_LBN 22
+#define	ESF_GZ_EV_RXPKTS_RSVD_WIDTH 37
+#define	ESF_GZ_EV_RXPKTS_Q_LABEL_LBN 16
+#define	ESF_GZ_EV_RXPKTS_Q_LABEL_WIDTH 6
+#define	ESF_GZ_EV_RXPKTS_NUM_PKT_LBN 0
+#define	ESF_GZ_EV_RXPKTS_NUM_PKT_WIDTH 16
+#define	ESE_GZ_SF_RX_PKTS_STRUCT_SIZE 64
+
+/* sf_rx_prefix */
+#define	ESF_GZ_RX_PREFIX_VLAN_STRIP_TCI_LBN 160
+#define	ESF_GZ_RX_PREFIX_VLAN_STRIP_TCI_WIDTH 16
+#define	ESF_GZ_RX_PREFIX_CSUM_FRAME_LBN 144
+#define	ESF_GZ_RX_PREFIX_CSUM_FRAME_WIDTH 16
+#define	ESF_GZ_RX_PREFIX_INGRESS_VPORT_LBN 128
+#define	ESF_GZ_RX_PREFIX_INGRESS_VPORT_WIDTH 16
+#define	ESF_GZ_RX_PREFIX_USER_MARK_LBN 96
+#define	ESF_GZ_RX_PREFIX_USER_MARK_WIDTH 32
+#define	ESF_GZ_RX_PREFIX_RSS_HASH_LBN 64
+#define	ESF_GZ_RX_PREFIX_RSS_HASH_WIDTH 32
+#define	ESF_GZ_RX_PREFIX_PARTIAL_TSTAMP_LBN 32
+#define	ESF_GZ_RX_PREFIX_PARTIAL_TSTAMP_WIDTH 32
+#define	ESF_GZ_RX_PREFIX_CLASS_LBN 16
+#define	ESF_GZ_RX_PREFIX_CLASS_WIDTH 16
+#define	ESF_GZ_RX_PREFIX_USER_FLAG_LBN 15
+#define	ESF_GZ_RX_PREFIX_USER_FLAG_WIDTH 1
+#define	ESF_GZ_RX_PREFIX_RSS_HASH_VALID_LBN 14
+#define	ESF_GZ_RX_PREFIX_RSS_HASH_VALID_WIDTH 1
+#define	ESF_GZ_RX_PREFIX_LENGTH_LBN 0
+#define	ESF_GZ_RX_PREFIX_LENGTH_WIDTH 14
+#define	ESE_GZ_SF_RX_PREFIX_STRUCT_SIZE 176
+
+/* sf_rxtx_generic */
+#define	ESF_GZ_EV_BARRIER_LBN 167
+#define	ESF_GZ_EV_BARRIER_WIDTH 1
+#define	ESF_GZ_EV_RSVD_LBN 130
+#define	ESF_GZ_EV_RSVD_WIDTH 37
+#define	ESF_GZ_EV_DPRXY_LBN 129
+#define	ESF_GZ_EV_DPRXY_WIDTH 1
+#define	ESF_GZ_EV_VIRTIO_LBN 128
+#define	ESF_GZ_EV_VIRTIO_WIDTH 1
+#define	ESF_GZ_EV_COUNT_LBN 0
+#define	ESF_GZ_EV_COUNT_WIDTH 128
+#define	ESE_GZ_SF_RXTX_GENERIC_STRUCT_SIZE 168
+
+/* sf_ts_stamp */
+#define	ESF_GZ_EV_TS_E_TYPE_LBN 60
+#define	ESF_GZ_EV_TS_E_TYPE_WIDTH 4
+#define	ESF_GZ_EV_TS_PHASE_LBN 59
+#define	ESF_GZ_EV_TS_PHASE_WIDTH 1
+#define	ESF_GZ_EV_TS_RSVD_LBN 56
+#define	ESF_GZ_EV_TS_RSVD_WIDTH 3
+#define	ESF_GZ_EV_TS_STATUS_LBN 54
+#define	ESF_GZ_EV_TS_STATUS_WIDTH 2
+#define	ESF_GZ_EV_TS_Q_LABEL_LBN 48
+#define	ESF_GZ_EV_TS_Q_LABEL_WIDTH 6
+#define	ESF_GZ_EV_TS_DESC_ID_LBN 32
+#define	ESF_GZ_EV_TS_DESC_ID_WIDTH 16
+#define	ESF_GZ_EV_TS_PARTIAL_STAMP_LBN 0
+#define	ESF_GZ_EV_TS_PARTIAL_STAMP_WIDTH 32
+#define	ESE_GZ_SF_TS_STAMP_STRUCT_SIZE 64
+
+/* sf_tx_cmplt */
+#define	ESF_GZ_EV_TXCMPL_E_TYPE_LBN 60
+#define	ESF_GZ_EV_TXCMPL_E_TYPE_WIDTH 4
+#define	ESF_GZ_EV_TXCMPL_PHASE_LBN 59
+#define	ESF_GZ_EV_TXCMPL_PHASE_WIDTH 1
+#define	ESF_GZ_EV_TXCMPL_RSVD_LBN 22
+#define	ESF_GZ_EV_TXCMPL_RSVD_WIDTH 37
+#define	ESF_GZ_EV_TXCMPL_Q_LABEL_LBN 16
+#define	ESF_GZ_EV_TXCMPL_Q_LABEL_WIDTH 6
+#define	ESF_GZ_EV_TXCMPL_NUM_DESC_LBN 0
+#define	ESF_GZ_EV_TXCMPL_NUM_DESC_WIDTH 16
+#define	ESE_GZ_SF_TX_CMPLT_STRUCT_SIZE 64
+
+/* sf_tx_desc2cmpt_dsc_fmt */
+#define	ESF_GZ_D2C_TGT_VI_ID_LBN 108
+#define	ESF_GZ_D2C_TGT_VI_ID_WIDTH 16
+#define	ESF_GZ_D2C_CMPT2_LBN 107
+#define	ESF_GZ_D2C_CMPT2_WIDTH 1
+#define	ESF_GZ_D2C_ABS_VI_ID_LBN 106
+#define	ESF_GZ_D2C_ABS_VI_ID_WIDTH 1
+#define	ESF_GZ_D2C_ORDERED_LBN 105
+#define	ESF_GZ_D2C_ORDERED_WIDTH 1
+#define	ESF_GZ_D2C_SKIP_N_LBN 97
+#define	ESF_GZ_D2C_SKIP_N_WIDTH 8
+#define	ESF_GZ_D2C_RSVD_LBN 64
+#define	ESF_GZ_D2C_RSVD_WIDTH 33
+#define	ESF_GZ_D2C_COMPLETION_LBN 0
+#define	ESF_GZ_D2C_COMPLETION_WIDTH 64
+#define	ESE_GZ_SF_TX_DESC2CMPT_DSC_FMT_STRUCT_SIZE 124
+
+/* sf_tx_mem2mem_dsc_fmt */
+#define	ESF_GZ_M2M_ADDR_SPC_EN_LBN 123
+#define	ESF_GZ_M2M_ADDR_SPC_EN_WIDTH 1
+#define	ESF_GZ_M2M_TRANSLATE_ADDR_LBN 122
+#define	ESF_GZ_M2M_TRANSLATE_ADDR_WIDTH 1
+#define	ESF_GZ_M2M_RSVD_LBN 120
+#define	ESF_GZ_M2M_RSVD_WIDTH 2
+#define	ESF_GZ_M2M_ADDR_SPC_LBN 108
+#define	ESF_GZ_M2M_ADDR_SPC_WIDTH 12
+#define	ESF_GZ_M2M_ADDR_SPC_PASID_LBN 86
+#define	ESF_GZ_M2M_ADDR_SPC_PASID_WIDTH 22
+#define	ESF_GZ_M2M_ADDR_SPC_MODE_LBN 84
+#define	ESF_GZ_M2M_ADDR_SPC_MODE_WIDTH 2
+#define	ESF_GZ_M2M_LEN_MINUS_1_LBN 64
+#define	ESF_GZ_M2M_LEN_MINUS_1_WIDTH 20
+#define	ESF_GZ_M2M_ADDR_LBN 0
+#define	ESF_GZ_M2M_ADDR_WIDTH 64
+#define	ESE_GZ_SF_TX_MEM2MEM_DSC_FMT_STRUCT_SIZE 124
+
+/* sf_tx_ovr_dsc_fmt */
+#define	ESF_GZ_TX_PREFIX_MARK_EN_LBN 123
+#define	ESF_GZ_TX_PREFIX_MARK_EN_WIDTH 1
+#define	ESF_GZ_TX_PREFIX_INGRESS_MPORT_EN_LBN 122
+#define	ESF_GZ_TX_PREFIX_INGRESS_MPORT_EN_WIDTH 1
+#define	ESF_GZ_TX_PREFIX_INLINE_CAPSULE_META_LBN 121
+#define	ESF_GZ_TX_PREFIX_INLINE_CAPSULE_META_WIDTH 1
+#define	ESF_GZ_TX_PREFIX_EGRESS_MPORT_EN_LBN 120
+#define	ESF_GZ_TX_PREFIX_EGRESS_MPORT_EN_WIDTH 1
+#define	ESF_GZ_TX_PREFIX_RSRVD_LBN 64
+#define	ESF_GZ_TX_PREFIX_RSRVD_WIDTH 56
+#define	ESF_GZ_TX_PREFIX_EGRESS_MPORT_LBN 48
+#define	ESF_GZ_TX_PREFIX_EGRESS_MPORT_WIDTH 16
+#define	ESF_GZ_TX_PREFIX_INGRESS_MPORT_LBN 32
+#define	ESF_GZ_TX_PREFIX_INGRESS_MPORT_WIDTH 16
+#define	ESF_GZ_TX_PREFIX_MARK_LBN 0
+#define	ESF_GZ_TX_PREFIX_MARK_WIDTH 32
+#define	ESE_GZ_SF_TX_OVR_DSC_FMT_STRUCT_SIZE 124
+
+/* sf_tx_seg_dsc_fmt */
+#define	ESF_GZ_TX_SEG_ADDR_SPC_EN_LBN 123
+#define	ESF_GZ_TX_SEG_ADDR_SPC_EN_WIDTH 1
+#define	ESF_GZ_TX_SEG_TRANSLATE_ADDR_LBN 122
+#define	ESF_GZ_TX_SEG_TRANSLATE_ADDR_WIDTH 1
+#define	ESF_GZ_TX_SEG_RSVD2_LBN 120
+#define	ESF_GZ_TX_SEG_RSVD2_WIDTH 2
+#define	ESF_GZ_TX_SEG_ADDR_SPC_LBN 108
+#define	ESF_GZ_TX_SEG_ADDR_SPC_WIDTH 12
+#define	ESF_GZ_TX_SEG_ADDR_SPC_PASID_LBN 86
+#define	ESF_GZ_TX_SEG_ADDR_SPC_PASID_WIDTH 22
+#define	ESF_GZ_TX_SEG_ADDR_SPC_MODE_LBN 84
+#define	ESF_GZ_TX_SEG_ADDR_SPC_MODE_WIDTH 2
+#define	ESF_GZ_TX_SEG_RSVD_LBN 80
+#define	ESF_GZ_TX_SEG_RSVD_WIDTH 4
+#define	ESF_GZ_TX_SEG_LEN_LBN 64
+#define	ESF_GZ_TX_SEG_LEN_WIDTH 16
+#define	ESF_GZ_TX_SEG_ADDR_LBN 0
+#define	ESF_GZ_TX_SEG_ADDR_WIDTH 64
+#define	ESE_GZ_SF_TX_SEG_DSC_FMT_STRUCT_SIZE 124
+
+/* sf_tx_std_dsc_fmt */
+#define	ESF_GZ_TX_SEND_VLAN_INSERT_TCI_LBN 108
+#define	ESF_GZ_TX_SEND_VLAN_INSERT_TCI_WIDTH 16
+#define	ESF_GZ_TX_SEND_VLAN_INSERT_EN_LBN 107
+#define	ESF_GZ_TX_SEND_VLAN_INSERT_EN_WIDTH 1
+#define	ESF_GZ_TX_SEND_TSTAMP_REQ_LBN 106
+#define	ESF_GZ_TX_SEND_TSTAMP_REQ_WIDTH 1
+#define	ESF_GZ_TX_SEND_CSO_OUTER_L4_LBN 105
+#define	ESF_GZ_TX_SEND_CSO_OUTER_L4_WIDTH 1
+#define	ESF_GZ_TX_SEND_CSO_OUTER_L3_LBN 104
+#define	ESF_GZ_TX_SEND_CSO_OUTER_L3_WIDTH 1
+#define	ESF_GZ_TX_SEND_CSO_INNER_L3_LBN 101
+#define	ESF_GZ_TX_SEND_CSO_INNER_L3_WIDTH 3
+#define	ESF_GZ_TX_SEND_RSVD_LBN 99
+#define	ESF_GZ_TX_SEND_RSVD_WIDTH 2
+#define	ESF_GZ_TX_SEND_CSO_PARTIAL_EN_LBN 97
+#define	ESF_GZ_TX_SEND_CSO_PARTIAL_EN_WIDTH 2
+#define	ESF_GZ_TX_SEND_CSO_PARTIAL_CSUM_W_LBN 92
+#define	ESF_GZ_TX_SEND_CSO_PARTIAL_CSUM_W_WIDTH 5
+#define	ESF_GZ_TX_SEND_CSO_PARTIAL_START_W_LBN 83
+#define	ESF_GZ_TX_SEND_CSO_PARTIAL_START_W_WIDTH 9
+#define	ESF_GZ_TX_SEND_NUM_SEGS_LBN 78
+#define	ESF_GZ_TX_SEND_NUM_SEGS_WIDTH 5
+#define	ESF_GZ_TX_SEND_LEN_LBN 64
+#define	ESF_GZ_TX_SEND_LEN_WIDTH 14
+#define	ESF_GZ_TX_SEND_ADDR_LBN 0
+#define	ESF_GZ_TX_SEND_ADDR_WIDTH 64
+#define	ESE_GZ_SF_TX_STD_DSC_FMT_STRUCT_SIZE 124
+
+/* sf_tx_tso_dsc_fmt */
+#define	ESF_GZ_TX_TSO_VLAN_INSERT_TCI_LBN 108
+#define	ESF_GZ_TX_TSO_VLAN_INSERT_TCI_WIDTH 16
+#define	ESF_GZ_TX_TSO_VLAN_INSERT_EN_LBN 107
+#define	ESF_GZ_TX_TSO_VLAN_INSERT_EN_WIDTH 1
+#define	ESF_GZ_TX_TSO_TSTAMP_REQ_LBN 106
+#define	ESF_GZ_TX_TSO_TSTAMP_REQ_WIDTH 1
+#define	ESF_GZ_TX_TSO_CSO_OUTER_L4_LBN 105
+#define	ESF_GZ_TX_TSO_CSO_OUTER_L4_WIDTH 1
+#define	ESF_GZ_TX_TSO_CSO_OUTER_L3_LBN 104
+#define	ESF_GZ_TX_TSO_CSO_OUTER_L3_WIDTH 1
+#define	ESF_GZ_TX_TSO_CSO_INNER_L3_LBN 101
+#define	ESF_GZ_TX_TSO_CSO_INNER_L3_WIDTH 3
+#define	ESF_GZ_TX_TSO_RSVD_LBN 94
+#define	ESF_GZ_TX_TSO_RSVD_WIDTH 7
+#define	ESF_GZ_TX_TSO_CSO_INNER_L4_LBN 93
+#define	ESF_GZ_TX_TSO_CSO_INNER_L4_WIDTH 1
+#define	ESF_GZ_TX_TSO_INNER_L4_OFF_W_LBN 85
+#define	ESF_GZ_TX_TSO_INNER_L4_OFF_W_WIDTH 8
+#define	ESF_GZ_TX_TSO_INNER_L3_OFF_W_LBN 77
+#define	ESF_GZ_TX_TSO_INNER_L3_OFF_W_WIDTH 8
+#define	ESF_GZ_TX_TSO_OUTER_L4_OFF_W_LBN 69
+#define	ESF_GZ_TX_TSO_OUTER_L4_OFF_W_WIDTH 8
+#define	ESF_GZ_TX_TSO_OUTER_L3_OFF_W_LBN 64
+#define	ESF_GZ_TX_TSO_OUTER_L3_OFF_W_WIDTH 5
+#define	ESF_GZ_TX_TSO_PAYLOAD_LEN_LBN 42
+#define	ESF_GZ_TX_TSO_PAYLOAD_LEN_WIDTH 22
+#define	ESF_GZ_TX_TSO_HDR_LEN_W_LBN 34
+#define	ESF_GZ_TX_TSO_HDR_LEN_W_WIDTH 8
+#define	ESF_GZ_TX_TSO_ED_OUTER_UDP_LEN_LBN 33
+#define	ESF_GZ_TX_TSO_ED_OUTER_UDP_LEN_WIDTH 1
+#define	ESF_GZ_TX_TSO_ED_INNER_IP_LEN_LBN 32
+#define	ESF_GZ_TX_TSO_ED_INNER_IP_LEN_WIDTH 1
+#define	ESF_GZ_TX_TSO_ED_OUTER_IP_LEN_LBN 31
+#define	ESF_GZ_TX_TSO_ED_OUTER_IP_LEN_WIDTH 1
+#define	ESF_GZ_TX_TSO_ED_INNER_IP4_ID_LBN 29
+#define	ESF_GZ_TX_TSO_ED_INNER_IP4_ID_WIDTH 2
+#define	ESF_GZ_TX_TSO_ED_OUTER_IP4_ID_LBN 27
+#define	ESF_GZ_TX_TSO_ED_OUTER_IP4_ID_WIDTH 2
+#define	ESF_GZ_TX_TSO_PAYLOAD_NUM_SEGS_LBN 17
+#define	ESF_GZ_TX_TSO_PAYLOAD_NUM_SEGS_WIDTH 10
+#define	ESF_GZ_TX_TSO_HDR_NUM_SEGS_LBN 14
+#define	ESF_GZ_TX_TSO_HDR_NUM_SEGS_WIDTH 3
+#define	ESF_GZ_TX_TSO_MSS_LBN 0
+#define	ESF_GZ_TX_TSO_MSS_WIDTH 14
+#define	ESE_GZ_SF_TX_TSO_DSC_FMT_STRUCT_SIZE 124
+
+
+/* Enum DESIGN_PARAMS */
+#define	ESE_EF100_DP_GZ_RX_MAX_RUNT 17
+#define	ESE_EF100_DP_GZ_VI_STRIDES 16
+#define	ESE_EF100_DP_GZ_NMMU_PAGE_SIZES 15
+#define	ESE_EF100_DP_GZ_EVQ_TIMER_TICK_NANOS 14
+#define	ESE_EF100_DP_GZ_MEM2MEM_MAX_LEN 13
+#define	ESE_EF100_DP_GZ_COMPAT 12
+#define	ESE_EF100_DP_GZ_TSO_MAX_NUM_FRAMES 11
+#define	ESE_EF100_DP_GZ_TSO_MAX_PAYLOAD_NUM_SEGS 10
+#define	ESE_EF100_DP_GZ_TSO_MAX_PAYLOAD_LEN 9
+#define	ESE_EF100_DP_GZ_TXQ_SIZE_GRANULARITY 8
+#define	ESE_EF100_DP_GZ_RXQ_SIZE_GRANULARITY 7
+#define	ESE_EF100_DP_GZ_TSO_MAX_HDR_NUM_SEGS 6
+#define	ESE_EF100_DP_GZ_TSO_MAX_HDR_LEN 5
+#define	ESE_EF100_DP_GZ_RX_L4_CSUM_PROTOCOLS 4
+#define	ESE_EF100_DP_GZ_NMMU_GROUP_SIZE 3
+#define	ESE_EF100_DP_GZ_EVQ_UNSOL_CREDIT_SEQ_BITS 2
+#define	ESE_EF100_DP_GZ_PARTIAL_TSTAMP_SUB_NANO_BITS 1
+#define	ESE_EF100_DP_GZ_PAD 0
+
+/* Enum DESIGN_PARAM_DEFAULTS */
+#define	ESE_EF100_DP_GZ_TSO_MAX_PAYLOAD_LEN_DEFAULT 0x3fffff
+#define	ESE_EF100_DP_GZ_TSO_MAX_NUM_FRAMES_DEFAULT 8192
+#define	ESE_EF100_DP_GZ_MEM2MEM_MAX_LEN_DEFAULT 8192
+#define	ESE_EF100_DP_GZ_RX_L4_CSUM_PROTOCOLS_DEFAULT 0x1106
+#define	ESE_EF100_DP_GZ_TSO_MAX_PAYLOAD_NUM_SEGS_DEFAULT 0x3ff
+#define	ESE_EF100_DP_GZ_RX_MAX_RUNT_DEFAULT 640
+#define	ESE_EF100_DP_GZ_EVQ_TIMER_TICK_NANOS_DEFAULT 512
+#define	ESE_EF100_DP_GZ_NMMU_PAGE_SIZES_DEFAULT 512
+#define	ESE_EF100_DP_GZ_TSO_MAX_HDR_LEN_DEFAULT 192
+#define	ESE_EF100_DP_GZ_RXQ_SIZE_GRANULARITY_DEFAULT 64
+#define	ESE_EF100_DP_GZ_TXQ_SIZE_GRANULARITY_DEFAULT 64
+#define	ESE_EF100_DP_GZ_NMMU_GROUP_SIZE_DEFAULT 32
+#define	ESE_EF100_DP_GZ_VI_STRIDES_DEFAULT 16
+#define	ESE_EF100_DP_GZ_EVQ_UNSOL_CREDIT_SEQ_BITS_DEFAULT 7
+#define	ESE_EF100_DP_GZ_TSO_MAX_HDR_NUM_SEGS_DEFAULT 4
+#define	ESE_EF100_DP_GZ_PARTIAL_TSTAMP_SUB_NANO_BITS_DEFAULT 2
+#define	ESE_EF100_DP_GZ_COMPAT_DEFAULT 0
+
+/* Enum HOST_IF_CONSTANTS */
+#define	ESE_GZ_FCW_LEN 0x4C
+#define	ESE_GZ_RX_PKT_PREFIX_LEN 22
+
+/* Enum PCI_CONSTANTS */
+#define	ESE_GZ_PCI_BASE_CONFIG_SPACE_SIZE 256
+#define	ESE_GZ_PCI_EXPRESS_XCAP_HDR_SIZE 4
+
+/* Enum RH_HCLASS_L2_CLASS */
+#define	ESE_GZ_RH_HCLASS_L2_CLASS_E2_0123VLAN 1
+#define	ESE_GZ_RH_HCLASS_L2_CLASS_OTHER 0
+
+/* Enum RH_HCLASS_L2_STATUS */
+#define	ESE_GZ_RH_HCLASS_L2_STATUS_RESERVED 3
+#define	ESE_GZ_RH_HCLASS_L2_STATUS_FCS_ERR 2
+#define	ESE_GZ_RH_HCLASS_L2_STATUS_LEN_ERR 1
+#define	ESE_GZ_RH_HCLASS_L2_STATUS_OK 0
+
+/* Enum RH_HCLASS_L3_CLASS */
+#define	ESE_GZ_RH_HCLASS_L3_CLASS_OTHER 3
+#define	ESE_GZ_RH_HCLASS_L3_CLASS_IP6 2
+#define	ESE_GZ_RH_HCLASS_L3_CLASS_IP4BAD 1
+#define	ESE_GZ_RH_HCLASS_L3_CLASS_IP4GOOD 0
+
+/* Enum RH_HCLASS_L4_CLASS */
+#define	ESE_GZ_RH_HCLASS_L4_CLASS_OTHER 3
+#define	ESE_GZ_RH_HCLASS_L4_CLASS_FRAG 2
+#define	ESE_GZ_RH_HCLASS_L4_CLASS_UDP 1
+#define	ESE_GZ_RH_HCLASS_L4_CLASS_TCP 0
+
+/* Enum RH_HCLASS_L4_CSUM */
+#define	ESE_GZ_RH_HCLASS_L4_CSUM_GOOD 1
+#define	ESE_GZ_RH_HCLASS_L4_CSUM_BAD_OR_UNKNOWN 0
+
+/* Enum RH_HCLASS_TUNNEL_CLASS */
+#define	ESE_GZ_RH_HCLASS_TUNNEL_CLASS_RESERVED_7 7
+#define	ESE_GZ_RH_HCLASS_TUNNEL_CLASS_RESERVED_6 6
+#define	ESE_GZ_RH_HCLASS_TUNNEL_CLASS_RESERVED_5 5
+#define	ESE_GZ_RH_HCLASS_TUNNEL_CLASS_RESERVED_4 4
+#define	ESE_GZ_RH_HCLASS_TUNNEL_CLASS_GENEVE 3
+#define	ESE_GZ_RH_HCLASS_TUNNEL_CLASS_NVGRE 2
+#define	ESE_GZ_RH_HCLASS_TUNNEL_CLASS_VXLAN 1
+#define	ESE_GZ_RH_HCLASS_TUNNEL_CLASS_NONE 0
+
+/* Enum TX_DESC_CSO_PARTIAL_EN */
+#define	ESE_GZ_TX_DESC_CSO_PARTIAL_EN_TCP 2
+#define	ESE_GZ_TX_DESC_CSO_PARTIAL_EN_UDP 1
+#define	ESE_GZ_TX_DESC_CSO_PARTIAL_EN_OFF 0
+
+/* Enum TX_DESC_CS_INNER_L3 */
+#define	ESE_GZ_TX_DESC_CS_INNER_L3_GENEVE 3
+#define	ESE_GZ_TX_DESC_CS_INNER_L3_NVGRE 2
+#define	ESE_GZ_TX_DESC_CS_INNER_L3_VXLAN 1
+#define	ESE_GZ_TX_DESC_CS_INNER_L3_OFF 0
+
+/* Enum TX_DESC_IP4_ID */
+#define	ESE_GZ_TX_DESC_IP4_ID_INC_MOD16 2
+#define	ESE_GZ_TX_DESC_IP4_ID_INC_MOD15 1
+#define	ESE_GZ_TX_DESC_IP4_ID_NO_OP 0
+/**************************************************************************/
+
+#define	ESF_GZ_EV_DEBUG_EVENT_GEN_FLAGS_LBN 44
+#define	ESF_GZ_EV_DEBUG_EVENT_GEN_FLAGS_WIDTH 4
+#define	ESF_GZ_EV_DEBUG_SRC_QID_LBN 32
+#define	ESF_GZ_EV_DEBUG_SRC_QID_WIDTH 12
+#define	ESF_GZ_EV_DEBUG_SEQ_NUM_LBN 16
+#define	ESF_GZ_EV_DEBUG_SEQ_NUM_WIDTH 16
+
+#endif /* EFX_EF100_REGS_H */


^ permalink raw reply related	[flat|nested] 25+ messages in thread

* [PATCH net-next 02/15] sfc_ef100: register accesses on EF100
  2020-07-03 15:28 [PATCH net-next 00/15] sfc_ef100: driver for EF100 family NICs, part 1 Edward Cree
  2020-07-03 15:30 ` [PATCH net-next 01/15] sfc_ef100: add EF100 register definitions Edward Cree
@ 2020-07-03 15:30 ` Edward Cree
  2020-07-03 15:31 ` [PATCH net-next 03/15] sfc_ef100: skeleton EF100 PF driver Edward Cree
                   ` (12 subsequent siblings)
  14 siblings, 0 replies; 25+ messages in thread
From: Edward Cree @ 2020-07-03 15:30 UTC (permalink / raw)
  To: linux-net-drivers, davem; +Cc: netdev

EF100 adds a few new valid addresses for efx_writed_page(), as well as
 a Function Control Window in the BAR whose location is variable.

Signed-off-by: Edward Cree <ecree@solarflare.com>
---
 drivers/net/ethernet/sfc/io.h         | 16 +++++++++++++---
 drivers/net/ethernet/sfc/net_driver.h |  2 ++
 2 files changed, 15 insertions(+), 3 deletions(-)

diff --git a/drivers/net/ethernet/sfc/io.h b/drivers/net/ethernet/sfc/io.h
index c3c011bc6a68..30439cc83a89 100644
--- a/drivers/net/ethernet/sfc/io.h
+++ b/drivers/net/ethernet/sfc/io.h
@@ -75,6 +75,11 @@
 #endif
 #endif
 
+static inline u32 efx_reg(struct efx_nic *efx, unsigned int reg)
+{
+	return efx->reg_base + reg;
+}
+
 #ifdef EFX_USE_QWORD_IO
 static inline void _efx_writeq(struct efx_nic *efx, __le64 value,
 				  unsigned int reg)
@@ -217,8 +222,11 @@ static inline void efx_reado_table(struct efx_nic *efx, efx_oword_t *value,
 	efx_reado(efx, value, reg + index * sizeof(efx_oword_t));
 }
 
-/* default VI stride (step between per-VI registers) is 8K */
-#define EFX_DEFAULT_VI_STRIDE 0x2000
+/* default VI stride (step between per-VI registers) is 8K on EF10 and
+ * 64K on EF100
+ */
+#define EFX_DEFAULT_VI_STRIDE		0x2000
+#define EF100_DEFAULT_VI_STRIDE		0x10000
 
 /* Calculate offset to page-mapped register */
 static inline unsigned int efx_paged_reg(struct efx_nic *efx, unsigned int page,
@@ -265,7 +273,9 @@ _efx_writed_page(struct efx_nic *efx, const efx_dword_t *value,
 #define efx_writed_page(efx, value, reg, page)				\
 	_efx_writed_page(efx, value,					\
 			 reg +						\
-			 BUILD_BUG_ON_ZERO((reg) != 0x400 &&		\
+			 BUILD_BUG_ON_ZERO((reg) != 0x180 &&		\
+					   (reg) != 0x200 &&		\
+					   (reg) != 0x400 &&		\
 					   (reg) != 0x420 &&		\
 					   (reg) != 0x830 &&		\
 					   (reg) != 0x83c &&		\
diff --git a/drivers/net/ethernet/sfc/net_driver.h b/drivers/net/ethernet/sfc/net_driver.h
index 0bf11ebb03cf..5b3b3a976114 100644
--- a/drivers/net/ethernet/sfc/net_driver.h
+++ b/drivers/net/ethernet/sfc/net_driver.h
@@ -966,6 +966,7 @@ struct efx_async_filter_insertion {
  * @xdp_rxq_info_failed: Have any of the rx queues failed to initialise their
  *      xdp_rxq_info structures?
  * @mem_bar: The BAR that is mapped into membase.
+ * @reg_base: Offset from the start of the bar to the function control window.
  * @monitor_work: Hardware monitor workitem
  * @biu_lock: BIU (bus interface unit) lock
  * @last_irq_cpu: Last CPU to handle a possible test interrupt.  This
@@ -1144,6 +1145,7 @@ struct efx_nic {
 	bool xdp_rxq_info_failed;
 
 	unsigned int mem_bar;
+	u32 reg_base;
 
 	/* The following fields may be written more often */
 


^ permalink raw reply related	[flat|nested] 25+ messages in thread

* [PATCH net-next 03/15] sfc_ef100: skeleton EF100 PF driver
  2020-07-03 15:28 [PATCH net-next 00/15] sfc_ef100: driver for EF100 family NICs, part 1 Edward Cree
  2020-07-03 15:30 ` [PATCH net-next 01/15] sfc_ef100: add EF100 register definitions Edward Cree
  2020-07-03 15:30 ` [PATCH net-next 02/15] sfc_ef100: register accesses on EF100 Edward Cree
@ 2020-07-03 15:31 ` Edward Cree
  2020-07-03 17:43   ` Jakub Kicinski
                     ` (4 more replies)
  2020-07-03 15:31 ` [PATCH net-next 04/15] sfc_ef100: reset-handling stub Edward Cree
                   ` (11 subsequent siblings)
  14 siblings, 5 replies; 25+ messages in thread
From: Edward Cree @ 2020-07-03 15:31 UTC (permalink / raw)
  To: linux-net-drivers, davem; +Cc: netdev

No TX or RX path, no MCDI, not even an ifup/down handler.
Besides stubs, the bulk of the patch deals with reading the Xilinx
 extended PCIe capability, which tells us where to find our BAR.

Signed-off-by: Edward Cree <ecree@solarflare.com>
---
 drivers/net/ethernet/sfc/Kconfig         |  10 +
 drivers/net/ethernet/sfc/Makefile        |   8 +
 drivers/net/ethernet/sfc/ef100.c         | 583 +++++++++++++++++++++++
 drivers/net/ethernet/sfc/ef100_ethtool.c |  26 +
 drivers/net/ethernet/sfc/ef100_ethtool.h |  12 +
 drivers/net/ethernet/sfc/ef100_netdev.c  | 135 ++++++
 drivers/net/ethernet/sfc/ef100_netdev.h  |  17 +
 drivers/net/ethernet/sfc/ef100_nic.c     | 177 +++++++
 drivers/net/ethernet/sfc/ef100_nic.h     |  26 +
 drivers/net/ethernet/sfc/ef100_rx.c      |  24 +
 drivers/net/ethernet/sfc/ef100_rx.h      |  17 +
 drivers/net/ethernet/sfc/ef100_tx.c      |  43 ++
 drivers/net/ethernet/sfc/ef100_tx.h      |  18 +
 drivers/net/ethernet/sfc/net_driver.h    |  12 +-
 14 files changed, 1107 insertions(+), 1 deletion(-)
 create mode 100644 drivers/net/ethernet/sfc/ef100.c
 create mode 100644 drivers/net/ethernet/sfc/ef100_ethtool.c
 create mode 100644 drivers/net/ethernet/sfc/ef100_ethtool.h
 create mode 100644 drivers/net/ethernet/sfc/ef100_netdev.c
 create mode 100644 drivers/net/ethernet/sfc/ef100_netdev.h
 create mode 100644 drivers/net/ethernet/sfc/ef100_nic.c
 create mode 100644 drivers/net/ethernet/sfc/ef100_nic.h
 create mode 100644 drivers/net/ethernet/sfc/ef100_rx.c
 create mode 100644 drivers/net/ethernet/sfc/ef100_rx.h
 create mode 100644 drivers/net/ethernet/sfc/ef100_tx.c
 create mode 100644 drivers/net/ethernet/sfc/ef100_tx.h

diff --git a/drivers/net/ethernet/sfc/Kconfig b/drivers/net/ethernet/sfc/Kconfig
index 81b0f7d3a025..2d37d1bc008c 100644
--- a/drivers/net/ethernet/sfc/Kconfig
+++ b/drivers/net/ethernet/sfc/Kconfig
@@ -28,6 +28,16 @@ config SFC
 
 	  To compile this driver as a module, choose M here.  The module
 	  will be called sfc.
+config SFC_EF100
+	tristate "Solarflare EF100 (Riverhead) support"
+	depends on PCI
+	default m
+	help
+          This driver supports 10/25/40/100-gigabit Ethernet cards based
+          on the Solarflare EF100 networking IP in Xilinx FPGAs.
+
+          To compile this driver as a module, choose M here. The module
+          will be called sfc_ef100.
 config SFC_MTD
 	bool "Solarflare SFC9000/SFC9100-family MTD support"
 	depends on SFC && MTD && !(SFC=y && MTD=m)
diff --git a/drivers/net/ethernet/sfc/Makefile b/drivers/net/ethernet/sfc/Makefile
index 87d093da22ca..90992a1c404d 100644
--- a/drivers/net/ethernet/sfc/Makefile
+++ b/drivers/net/ethernet/sfc/Makefile
@@ -10,4 +10,12 @@ sfc-$(CONFIG_SFC_SRIOV)	+= sriov.o siena_sriov.o ef10_sriov.o
 
 obj-$(CONFIG_SFC)	+= sfc.o
 
+sfc_ef100-y             += mcdi.o ef100.o efx_common.o efx_channels.o \
+                           ef100_nic.o nic.o ef100_netdev.o ef100_ethtool.o \
+                           ef100_rx.o rx_common.o ef100_tx.o tx_common.o \
+			   ethtool_common.o mcdi_port_common.o mcdi_functions.o \
+			   mcdi_filters.o selftest.o ptp.o
+
+obj-$(CONFIG_SFC_EF100) += sfc_ef100.o
+
 obj-$(CONFIG_SFC_FALCON) += falcon/
diff --git a/drivers/net/ethernet/sfc/ef100.c b/drivers/net/ethernet/sfc/ef100.c
new file mode 100644
index 000000000000..a2a816f691ee
--- /dev/null
+++ b/drivers/net/ethernet/sfc/ef100.c
@@ -0,0 +1,583 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/****************************************************************************
+ * Driver for Solarflare network controllers and boards
+ * Copyright 2005-2018 Solarflare Communications Inc.
+ * Copyright 2019-2020 Xilinx 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
+ * by the Free Software Foundation, incorporated herein by reference.
+ */
+
+#include "net_driver.h"
+#include <linux/module.h>
+#include <linux/aer.h>
+#include "efx_common.h"
+#include "efx_channels.h"
+#include "io.h"
+#include "ef100_nic.h"
+#include "ef100_netdev.h"
+#include "ef100_regs.h"
+
+#define EFX_EF100_PCI_DEFAULT_BAR	2
+
+/* Number of bytes at start of vendor specified extended capability that indicate
+ * that the capability is vendor specified. i.e. offset from value returned by
+ * pci_find_next_ext_capability() to beginning of vendor specified capability
+ * header.
+ */
+#define PCI_EXT_CAP_HDR_LENGTH  4
+
+/* Expected size of a Xilinx continuation address table entry. */
+#define ESE_GZ_CFGBAR_CONT_CAP_MIN_LENGTH      16
+
+struct ef100_func_ctl_window {
+	bool valid;
+	unsigned int bar;
+	u64 offset;
+};
+
+static int ef100_pci_walk_xilinx_table(struct efx_nic *efx, u64 offset,
+				       struct ef100_func_ctl_window *result);
+
+/* Number of bytes to offset when reading bit position x with dword accessors. */
+#define ROUND_DOWN_TO_DWORD(x) (((x) & (~31)) >> 3)
+
+#define EXTRACT_BITS(x, lbn, width) \
+	((x) >> ((lbn) & 31)) & ((1ull << (width)) - 1)
+
+static u32 _ef100_pci_get_bar_bits_with_width(struct efx_nic *efx,
+					      int structure_start,
+					      int lbn, int width)
+{
+	efx_dword_t dword;
+
+	efx_readd(efx, &dword, structure_start + ROUND_DOWN_TO_DWORD(lbn));
+
+	return EXTRACT_BITS(le32_to_cpu(dword.u32[0]), lbn, width);
+}
+
+#define ef100_pci_get_bar_bits(efx, entry_location, bitdef) \
+	_ef100_pci_get_bar_bits_with_width(efx, entry_location, \
+		bitdef ## _LBN, bitdef ## _WIDTH)
+
+static int ef100_pci_parse_ef100_entry(struct efx_nic *efx, int entry_location,
+				       struct ef100_func_ctl_window *result)
+{
+	u32 bar = ef100_pci_get_bar_bits(efx, entry_location,
+					 ESF_GZ_CFGBAR_EF100_BAR);
+	u64 offset = ef100_pci_get_bar_bits(efx, entry_location,
+					    ESF_GZ_CFGBAR_EF100_FUNC_CTL_WIN_OFF) << ESE_GZ_EF100_FUNC_CTL_WIN_OFF_SHIFT;
+
+	netif_dbg(efx, probe, efx->net_dev,
+		  "Found EF100 function control window bar=%d offset=0x%llx\n",
+		  bar, offset);
+
+	if (result->valid) {
+		netif_err(efx, probe, efx->net_dev,
+			  "Duplicated EF100 table entry.\n");
+		return -EINVAL;
+	}
+
+	if ((bar == ESE_GZ_CFGBAR_EF100_BAR_NUM_EXPANSION_ROM) ||
+	    (bar == ESE_GZ_CFGBAR_EF100_BAR_NUM_INVALID)) {
+		netif_err(efx, probe, efx->net_dev,
+			  "Bad BAR value of %d in Xilinx capabilities EF100 entry.\n",
+			  bar);
+		return -EINVAL;
+	}
+
+	result->bar = bar;
+	result->offset = offset;
+	result->valid = true;
+	return 0;
+}
+
+static bool ef100_pci_does_bar_overflow(struct efx_nic *efx, int bar,
+					u64 next_entry)
+{
+	return next_entry + ESE_GZ_CFGBAR_ENTRY_HEADER_SIZE >
+		pci_resource_len(efx->pci_dev, bar);
+}
+
+/* Parse a Xilinx capabilities table entry describing a continuation to a new
+ * sub-table.
+ */
+static int ef100_pci_parse_continue_entry(struct efx_nic *efx, int entry_location,
+					  struct ef100_func_ctl_window *result)
+{
+	unsigned int previous_bar;
+	efx_oword_t entry;
+	u64 offset;
+	int rc = 0;
+	u32 bar;
+
+	efx_reado(efx, &entry, entry_location);
+
+	bar = EFX_OWORD_FIELD32(entry, ESF_GZ_CFGBAR_CONT_CAP_BAR);
+
+	offset = EFX_OWORD_FIELD64(entry, ESF_GZ_CFGBAR_CONT_CAP_OFFSET) <<
+		ESE_GZ_CONT_CAP_OFFSET_BYTES_SHIFT;
+
+	previous_bar = efx->mem_bar;
+
+	if ((bar == ESE_GZ_VSEC_BAR_NUM_EXPANSION_ROM) ||
+	    (bar == ESE_GZ_VSEC_BAR_NUM_INVALID)) {
+		netif_err(efx, probe, efx->net_dev,
+			  "Bad BAR value of %d in Xilinx capabilities sub-table.\n",
+			  bar);
+		return -EINVAL;
+	}
+
+	if (bar != previous_bar) {
+		efx_fini_io(efx);
+
+		if (ef100_pci_does_bar_overflow(efx, bar, offset)) {
+			netif_err(efx, probe, efx->net_dev,
+				  "Xilinx table will overrun BAR[%d] offset=0x%llx\n",
+				  bar, offset);
+			return -EINVAL;
+		}
+
+		/* Temporarily map new BAR. */
+		rc = efx_init_io(efx, bar,
+				 DMA_BIT_MASK(ESF_GZ_TX_SEND_ADDR_WIDTH),
+				 pci_resource_len(efx->pci_dev, bar));
+		if (rc) {
+			netif_err(efx, probe, efx->net_dev,
+				  "Mapping new BAR for Xilinx table failed, rc=%d\n", rc);
+			return rc;
+		}
+	}
+
+	rc = ef100_pci_walk_xilinx_table(efx, offset, result);
+	if (rc)
+		return rc;
+
+	if (bar != previous_bar) {
+		efx_fini_io(efx);
+
+		/* Put old BAR back. */
+		rc = efx_init_io(efx, previous_bar,
+				 DMA_BIT_MASK(ESF_GZ_TX_SEND_ADDR_WIDTH),
+				 pci_resource_len(efx->pci_dev, previous_bar));
+		if (rc) {
+			netif_err(efx, probe, efx->net_dev,
+				  "Putting old BAR back failed, rc=%d\n", rc);
+			return rc;
+		}
+	}
+
+	return 0;
+}
+
+/* Iterate over the Xilinx capabilities table in the currently mapped BAR and
+ * call ef100_pci_parse_ef100_entry() on any EF100 entries and
+ * ef100_pci_parse_continue_entry() on any table continuations.
+ */
+static int ef100_pci_walk_xilinx_table(struct efx_nic *efx, u64 offset,
+				       struct ef100_func_ctl_window *result)
+{
+	u64 current_entry = offset;
+	int rc = 0;
+
+	while (true) {
+		u32 id = ef100_pci_get_bar_bits(efx, current_entry,
+						ESF_GZ_CFGBAR_ENTRY_FORMAT);
+		u32 last = ef100_pci_get_bar_bits(efx, current_entry,
+						  ESF_GZ_CFGBAR_ENTRY_LAST);
+		u32 rev = ef100_pci_get_bar_bits(efx, current_entry,
+						 ESF_GZ_CFGBAR_ENTRY_REV);
+		u32 entry_size;
+
+		if (id == ESE_GZ_CFGBAR_ENTRY_LAST)
+			return 0;
+
+		entry_size = ef100_pci_get_bar_bits(efx, current_entry,
+						    ESF_GZ_CFGBAR_ENTRY_SIZE);
+
+		netif_dbg(efx, probe, efx->net_dev,
+			  "Seen Xilinx table entry 0x%x size 0x%x at 0x%llx in BAR[%d]\n",
+			  id, entry_size, current_entry, efx->mem_bar);
+
+		if (entry_size < sizeof(uint32_t) * 2) {
+			netif_err(efx, probe, efx->net_dev,
+				  "Xilinx table entry too short len=0x%x\n", entry_size);
+			return -EINVAL;
+		}
+
+		switch (id) {
+		case ESE_GZ_CFGBAR_ENTRY_EF100:
+			if ((rev != ESE_GZ_CFGBAR_ENTRY_REV_EF100) ||
+			    (entry_size < ESE_GZ_CFGBAR_ENTRY_SIZE_EF100)) {
+				netif_err(efx, probe, efx->net_dev,
+					  "Bad length or rev for EF100 entry in Xilinx capabilities table. entry_size=%d rev=%d.\n",
+					  entry_size, rev);
+				return -EINVAL;
+			}
+
+			rc = ef100_pci_parse_ef100_entry(efx, current_entry,
+							 result);
+			if (rc)
+				return rc;
+			break;
+		case ESE_GZ_CFGBAR_ENTRY_CONT_CAP_ADDR:
+			if ((rev != 0) || (entry_size < ESE_GZ_CFGBAR_CONT_CAP_MIN_LENGTH)) {
+				netif_err(efx, probe, efx->net_dev,
+					  "Bad length or rev for continue entry in Xilinx capabilities table. entry_size=%d rev=%d.\n",
+					  entry_size, rev);
+				return -EINVAL;
+			}
+
+			rc = ef100_pci_parse_continue_entry(efx, current_entry, result);
+			if (rc)
+				return rc;
+			break;
+		default:
+			/* Ignore unknown table entries. */
+			break;
+		}
+
+		if (last)
+			return 0;
+
+		current_entry += entry_size;
+
+		if (ef100_pci_does_bar_overflow(efx, efx->mem_bar, current_entry)) {
+			netif_err(efx, probe, efx->net_dev,
+				  "Xilinx table overrun at position=0x%llx.\n",
+				  current_entry);
+			return -EINVAL;
+		}
+	}
+}
+
+static int _ef100_pci_get_config_bits_with_width(struct efx_nic *efx,
+						 int structure_start, int lbn,
+						 int width, u32 *result)
+{
+	int rc, pos = structure_start + ROUND_DOWN_TO_DWORD(lbn);
+	u32 temp;
+
+	rc = pci_read_config_dword(efx->pci_dev, pos, &temp);
+	if (rc) {
+		netif_err(efx, probe, efx->net_dev,
+			  "Failed to read PCI config dword at %d\n",
+			  pos);
+		return rc;
+	}
+
+	*result = EXTRACT_BITS(temp, lbn, width);
+
+	return 0;
+}
+
+#define ef100_pci_get_config_bits(efx, entry_location, bitdef, result) \
+	_ef100_pci_get_config_bits_with_width(efx, entry_location,  \
+		bitdef ## _LBN, bitdef ## _WIDTH, result)
+
+/* Call ef100_pci_walk_xilinx_table() for the Xilinx capabilities table pointed
+ * to by this PCI_EXT_CAP_ID_VNDR.
+ */
+static int ef100_pci_parse_xilinx_cap(struct efx_nic *efx, int vndr_cap,
+				      bool has_offset_hi,
+				      struct ef100_func_ctl_window *result)
+{
+	u32 offset_high = 0;
+	u32 offset_lo = 0;
+	u64 offset = 0;
+	u32 bar = 0;
+	int rc = 0;
+
+	rc = ef100_pci_get_config_bits(efx, vndr_cap, ESF_GZ_VSEC_TBL_BAR, &bar);
+	if (rc) {
+		netif_err(efx, probe, efx->net_dev,
+			  "Failed to read ESF_GZ_VSEC_TBL_BAR, rc=%d\n",
+			  rc);
+		return rc;
+	}
+
+	if ((bar == ESE_GZ_CFGBAR_CONT_CAP_BAR_NUM_EXPANSION_ROM) ||
+	    (bar == ESE_GZ_CFGBAR_CONT_CAP_BAR_NUM_INVALID)) {
+		netif_err(efx, probe, efx->net_dev,
+			  "Bad BAR value of %d in Xilinx capabilities sub-table.\n",
+			  bar);
+		return -EINVAL;
+	}
+
+	rc = ef100_pci_get_config_bits(efx, vndr_cap, ESF_GZ_VSEC_TBL_OFF_LO, &offset_lo);
+	if (rc) {
+		netif_err(efx, probe, efx->net_dev,
+			  "Failed to read ESF_GZ_VSEC_TBL_OFF_LO, rc=%d\n",
+			  rc);
+		return rc;
+	}
+
+	/* Get optional extension to 64bit offset. */
+	if (has_offset_hi) {
+		rc = ef100_pci_get_config_bits(efx, vndr_cap, ESF_GZ_VSEC_TBL_OFF_HI, &offset_high);
+		if (rc) {
+			netif_err(efx, probe, efx->net_dev,
+				  "Failed to read ESF_GZ_VSEC_TBL_OFF_HI, rc=%d\n",
+				  rc);
+			return rc;
+		}
+	}
+
+	offset = (((u64)offset_lo) << ESE_GZ_VSEC_TBL_OFF_LO_BYTES_SHIFT) |
+		 (((u64)offset_high) << ESE_GZ_VSEC_TBL_OFF_HI_BYTES_SHIFT);
+
+	if (offset > pci_resource_len(efx->pci_dev, bar) - sizeof(uint32_t) * 2) {
+		netif_err(efx, probe, efx->net_dev,
+			  "Xilinx table will overrun BAR[%d] offset=0x%llx\n",
+			  bar, offset);
+		return -EINVAL;
+	}
+
+	/* Temporarily map BAR. */
+	rc = efx_init_io(efx, bar,
+			 DMA_BIT_MASK(ESF_GZ_TX_SEND_ADDR_WIDTH),
+			 pci_resource_len(efx->pci_dev, bar));
+	if (rc) {
+		netif_err(efx, probe, efx->net_dev,
+			  "efx_init_io failed, rc=%d\n", rc);
+		return rc;
+	}
+
+	rc = ef100_pci_walk_xilinx_table(efx, offset, result);
+
+	/* Unmap temporarily mapped BAR. */
+	efx_fini_io(efx);
+	return rc;
+}
+
+/* Call ef100_pci_parse_ef100_entry() for each Xilinx PCI_EXT_CAP_ID_VNDR
+ * capability.
+ */
+static int ef100_pci_find_func_ctrl_window(struct efx_nic *efx,
+					   struct ef100_func_ctl_window *result)
+{
+	int num_xilinx_caps = 0;
+	int cap = 0;
+
+	result->valid = false;
+
+	while ((cap = pci_find_next_ext_capability(efx->pci_dev, cap, PCI_EXT_CAP_ID_VNDR)) != 0) {
+		int vndr_cap = cap + PCI_EXT_CAP_HDR_LENGTH;
+		u32 vsec_ver = 0;
+		u32 vsec_len = 0;
+		u32 vsec_id = 0;
+		int rc = 0;
+
+		num_xilinx_caps++;
+
+		rc = ef100_pci_get_config_bits(efx, vndr_cap, ESF_GZ_VSEC_ID,
+					       &vsec_id);
+		if (rc) {
+			netif_err(efx, probe, efx->net_dev,
+				  "Failed to read ESF_GZ_VSEC_ID, rc=%d\n",
+				  rc);
+			return rc;
+		}
+
+		rc = ef100_pci_get_config_bits(efx, vndr_cap, ESF_GZ_VSEC_VER,
+					       &vsec_ver);
+		if (rc) {
+			netif_err(efx, probe, efx->net_dev,
+				  "Failed to read ESF_GZ_VSEC_VER, rc=%d\n",
+				  rc);
+			return rc;
+		}
+
+		/* Get length of whole capability - i.e. starting at cap */
+		rc = ef100_pci_get_config_bits(efx, vndr_cap, ESF_GZ_VSEC_LEN,
+					       &vsec_len);
+		if (rc) {
+			netif_err(efx, probe, efx->net_dev,
+				  "Failed to read ESF_GZ_VSEC_LEN, rc=%d\n",
+				  rc);
+			return rc;
+		}
+
+		if ((vsec_id == ESE_GZ_XILINX_VSEC_ID) &&
+		    (vsec_ver == ESE_GZ_VSEC_VER_XIL_CFGBAR) &&
+		    (vsec_len >= ESE_GZ_VSEC_LEN_MIN)) {
+			bool has_offset_hi = (vsec_len >= ESE_GZ_VSEC_LEN_HIGH_OFFT);
+
+			rc = ef100_pci_parse_xilinx_cap(efx, vndr_cap,
+							has_offset_hi, result);
+			if (rc)
+				return rc;
+		}
+	}
+
+	if (num_xilinx_caps && !result->valid) {
+		netif_err(efx, probe, efx->net_dev,
+			  "Seen %d Xilinx tables, but no EF100 entry.\n",
+			  num_xilinx_caps);
+		return -EINVAL;
+	}
+
+	return 0;
+}
+
+/* Final NIC shutdown
+ * This is called only at module unload (or hotplug removal).  A PF can call
+ * this on its VFs to ensure they are unbound first.
+ */
+static void ef100_pci_remove(struct pci_dev *pci_dev)
+{
+	struct efx_nic *efx;
+
+	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);
+	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_disable_pcie_error_reporting(pci_dev);
+};
+
+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_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)
+		return -ENOMEM;
+	efx = netdev_priv(net_dev);
+	efx->type = (const struct efx_nic_type *)entry->driver_data;
+
+	pci_set_drvdata(pci_dev, efx);
+	SET_NETDEV_DEV(net_dev, &pci_dev->dev);
+	rc = efx_init_struct(efx, pci_dev, net_dev);
+	if (rc)
+		goto fail;
+
+	efx->vi_stride = EF100_DEFAULT_VI_STRIDE;
+	netif_info(efx, probe, efx->net_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);
+		goto fail;
+	}
+
+	if (!fcw.valid) {
+		/* Extended capability not found - use defaults. */
+		fcw.bar = EFX_EF100_PCI_DEFAULT_BAR;
+		fcw.offset = 0;
+		fcw.valid = true;
+	}
+
+	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");
+		goto fail;
+	}
+
+	/* Set up basic I/O (BAR mappings etc) */
+	rc = efx_init_io(efx, fcw.bar,
+			 DMA_BIT_MASK(ESF_GZ_TX_SEND_ADDR_WIDTH),
+			 pci_resource_len(efx->pci_dev, fcw.bar));
+	if (rc)
+		goto fail;
+
+	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);
+		goto fail;
+	}
+
+	rc = efx->type->probe(efx);
+	if (rc)
+		goto fail;
+
+	netif_dbg(efx, probe, efx->net_dev, "initialisation successful\n");
+
+	return 0;
+
+fail:
+	ef100_pci_remove(pci_dev);
+	return rc;
+}
+
+/* PCI device ID table */
+static const struct pci_device_id ef100_pci_table[] = {
+	{PCI_DEVICE(PCI_VENDOR_ID_XILINX, 0x0100),  /* Riverhead PF */
+		.driver_data = (unsigned long) &ef100_pf_nic_type },
+	{0}                     /* end of list */
+};
+
+static struct pci_driver ef100_pci_driver = {
+	.name           = KBUILD_MODNAME,
+	.id_table       = ef100_pci_table,
+	.probe          = ef100_pci_probe,
+	.remove         = ef100_pci_remove,
+	.err_handler    = &efx_err_handlers,
+};
+
+static int __init ef100_init_module(void)
+{
+	int rc;
+
+	pr_info("Solarflare EF100 NET driver v" EFX_DRIVER_VERSION "\n");
+
+	rc = efx_create_reset_workqueue();
+	if (rc)
+		goto err_reset;
+
+	rc = pci_register_driver(&ef100_pci_driver);
+	if (rc < 0) {
+		pr_err("pci_register_driver failed, rc=%d\n", rc);
+		goto err_pci;
+	}
+
+	return 0;
+
+err_pci:
+	efx_destroy_reset_workqueue();
+err_reset:
+	return rc;
+}
+
+static void __exit ef100_exit_module(void)
+{
+	pr_info("Solarflare EF100 NET driver unloading\n");
+
+	pci_unregister_driver(&ef100_pci_driver);
+}
+
+module_init(ef100_init_module);
+module_exit(ef100_exit_module);
+
+MODULE_DESCRIPTION("Solarflare EF100 network driver");
+MODULE_LICENSE("GPL");
+MODULE_DEVICE_TABLE(pci, ef100_pci_table);
+MODULE_VERSION(EFX_DRIVER_VERSION);
diff --git a/drivers/net/ethernet/sfc/ef100_ethtool.c b/drivers/net/ethernet/sfc/ef100_ethtool.c
new file mode 100644
index 000000000000..af3f385b828b
--- /dev/null
+++ b/drivers/net/ethernet/sfc/ef100_ethtool.c
@@ -0,0 +1,26 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/****************************************************************************
+ * Driver for Solarflare network controllers and boards
+ * Copyright 2018 Solarflare Communications Inc.
+ * Copyright 2019-2020 Xilinx 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
+ * by the Free Software Foundation, incorporated herein by reference.
+ */
+#include <linux/module.h>
+#include <linux/netdevice.h>
+#include "net_driver.h"
+#include "efx.h"
+#include "mcdi_port_common.h"
+#include "ethtool_common.h"
+#include "ef100_ethtool.h"
+#include "mcdi_functions.h"
+
+const char *efx_driver_name = KBUILD_MODNAME;
+
+/*	Ethtool options available
+ */
+const struct ethtool_ops ef100_ethtool_ops = {
+	.get_drvinfo		= efx_ethtool_get_drvinfo,
+};
diff --git a/drivers/net/ethernet/sfc/ef100_ethtool.h b/drivers/net/ethernet/sfc/ef100_ethtool.h
new file mode 100644
index 000000000000..6efda72dfc6c
--- /dev/null
+++ b/drivers/net/ethernet/sfc/ef100_ethtool.h
@@ -0,0 +1,12 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+/****************************************************************************
+ * Driver for Solarflare network controllers and boards
+ * Copyright 2018 Solarflare Communications Inc.
+ * Copyright 2019-2020 Xilinx 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
+ * by the Free Software Foundation, incorporated herein by reference.
+ */
+
+extern const struct ethtool_ops ef100_ethtool_ops;
diff --git a/drivers/net/ethernet/sfc/ef100_netdev.c b/drivers/net/ethernet/sfc/ef100_netdev.c
new file mode 100644
index 000000000000..356938104cb2
--- /dev/null
+++ b/drivers/net/ethernet/sfc/ef100_netdev.c
@@ -0,0 +1,135 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/****************************************************************************
+ * Driver for Solarflare network controllers and boards
+ * Copyright 2018 Solarflare Communications Inc.
+ * Copyright 2019-2020 Xilinx 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
+ * by the Free Software Foundation, incorporated herein by reference.
+ */
+#include "net_driver.h"
+#include "mcdi_port_common.h"
+#include "mcdi_functions.h"
+#include "efx_common.h"
+#include "efx_channels.h"
+#include "tx_common.h"
+#include "ef100_netdev.h"
+#include "ef100_ethtool.h"
+#include "efx_common.h"
+#include "nic_common.h"
+#include "ef100_nic.h"
+#include "ef100_tx.h"
+#include "ef100_regs.h"
+#include "mcdi_filters.h"
+#include "rx_common.h"
+
+/* In EF10 this was a module parameter.  Since EF100 is a new module, we
+ * don't have to be compatible with the old module parameters, so we can
+ * get rid of it.
+ */
+bool efx_separate_tx_channels = false;
+
+static void ef100_update_name(struct efx_nic *efx)
+{
+	strcpy(efx->name, efx->net_dev->name);
+}
+
+/* Initiate a packet transmission.  We use one channel per CPU
+ * (sharing when we have more CPUs than channels).
+ *
+ * Context: non-blocking.
+ * Note that returning anything other than NETDEV_TX_OK will cause the
+ * OS to free the skb.
+ */
+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_tx_queue *tx_queue;
+	struct efx_channel *channel;
+	int rc;
+
+	channel = efx_get_tx_channel(efx, skb_get_queue_mapping(skb));
+	netif_vdbg(efx, tx_queued, efx->net_dev,
+		   "%s len %d data %d channel %d\n", __func__,
+		   skb->len, skb->data_len, channel->channel);
+	if (!efx->n_channels || !efx->n_tx_channels || !channel) {
+		netif_stop_queue(net_dev);
+		goto err;
+	}
+
+	tx_queue = &channel->tx_queue[0];
+	rc = efx_enqueue_skb(tx_queue, skb);
+	if (rc == 0)
+		return NETDEV_TX_OK;
+
+err:
+	net_dev->stats.tx_dropped++;
+	return NETDEV_TX_OK;
+}
+
+static const struct net_device_ops ef100_netdev_ops = {
+	.ndo_start_xmit         = ef100_hard_start_xmit,
+};
+
+/*	Netdev registration
+ */
+int ef100_netdev_event(struct notifier_block *this,
+		       unsigned long event, void *ptr)
+{
+	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)
+		ef100_update_name(efx);
+
+	return NOTIFY_DONE;
+}
+
+int ef100_register_netdev(struct efx_nic *efx)
+{
+	struct net_device *net_dev = efx->net_dev;
+	int rc;
+
+	net_dev->watchdog_timeo = 5 * HZ;
+	net_dev->irq = efx->pci_dev->irq;
+	net_dev->netdev_ops = &ef100_netdev_ops;
+	net_dev->min_mtu = EFX_MIN_MTU;
+	net_dev->max_mtu = EFX_MAX_MTU;
+	net_dev->ethtool_ops = &ef100_ethtool_ops;
+
+	rtnl_lock();
+
+	rc = dev_alloc_name(net_dev, net_dev->name);
+	if (rc < 0)
+		goto fail_locked;
+	ef100_update_name(efx);
+
+	rc = register_netdevice(net_dev);
+	if (rc)
+		goto fail_locked;
+
+	/* Always start with carrier off; PHY events will detect the link */
+	netif_carrier_off(net_dev);
+
+	efx->state = STATE_READY;
+	rtnl_unlock();
+	efx_init_mcdi_logging(efx);
+
+	return 0;
+
+fail_locked:
+	rtnl_unlock();
+	netif_err(efx, drv, efx->net_dev, "could not register net dev\n");
+	return rc;
+}
+
+void ef100_unregister_netdev(struct efx_nic *efx)
+{
+	if (efx_dev_registered(efx)) {
+		efx_fini_mcdi_logging(efx);
+		efx->state = STATE_UNINIT;
+		unregister_netdev(efx->net_dev);
+	}
+}
diff --git a/drivers/net/ethernet/sfc/ef100_netdev.h b/drivers/net/ethernet/sfc/ef100_netdev.h
new file mode 100644
index 000000000000..d40abb7cc086
--- /dev/null
+++ b/drivers/net/ethernet/sfc/ef100_netdev.h
@@ -0,0 +1,17 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+/****************************************************************************
+ * Driver for Solarflare network controllers and boards
+ * Copyright 2018 Solarflare Communications Inc.
+ * Copyright 2019-2020 Xilinx 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
+ * by the Free Software Foundation, incorporated herein by reference.
+ */
+
+#include <linux/netdevice.h>
+
+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);
diff --git a/drivers/net/ethernet/sfc/ef100_nic.c b/drivers/net/ethernet/sfc/ef100_nic.c
new file mode 100644
index 000000000000..20b6f4bb35ad
--- /dev/null
+++ b/drivers/net/ethernet/sfc/ef100_nic.c
@@ -0,0 +1,177 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/****************************************************************************
+ * Driver for Solarflare network controllers and boards
+ * Copyright 2018 Solarflare Communications Inc.
+ * Copyright 2019-2020 Xilinx 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
+ * by the Free Software Foundation, incorporated herein by reference.
+ */
+
+#include "ef100_nic.h"
+#include "efx_common.h"
+#include "efx_channels.h"
+#include "io.h"
+#include "selftest.h"
+#include "ef100_regs.h"
+#include "mcdi.h"
+#include "mcdi_pcol.h"
+#include "mcdi_port_common.h"
+#include "mcdi_functions.h"
+#include "mcdi_filters.h"
+#include "ef100_rx.h"
+#include "ef100_tx.h"
+#include "ef100_netdev.h"
+
+#define EF100_MAX_VIS 4096
+
+/*	MCDI
+ */
+static int ef100_get_warm_boot_count(struct efx_nic *efx)
+{
+	efx_dword_t reg;
+
+	efx_readd(efx, &reg, efx_reg(efx, ER_GZ_MC_SFT_STATUS));
+
+	if (EFX_DWORD_FIELD(reg, EFX_DWORD_0) == 0xffffffff) {
+		netif_err(efx, hw, efx->net_dev, "Hardware unavailable\n");
+		efx->state = STATE_DISABLED;
+		return -ENETDOWN;
+	} else {
+		return EFX_DWORD_FIELD(reg, EFX_WORD_1) == 0xb007 ?
+			EFX_DWORD_FIELD(reg, EFX_WORD_0) : -EIO;
+	}
+}
+
+/*	Event handling
+ */
+static int ef100_ev_probe(struct efx_channel *channel)
+{
+	/* Allocate an extra descriptor for the QMDA status completion entry */
+	return efx_nic_alloc_buffer(channel->efx, &channel->eventq.buf,
+				    (channel->eventq_mask + 2) *
+				    sizeof(efx_qword_t),
+				    GFP_KERNEL);
+}
+
+/* efx_mcdi_process_event() may call this */
+void efx_mcdi_sensor_event(struct efx_nic *efx, efx_qword_t *ev) {}
+
+static irqreturn_t ef100_msi_interrupt(int irq, void *dev_id)
+{
+	struct efx_msi_context *context = dev_id;
+	struct efx_nic *efx = context->efx;
+
+	netif_vdbg(efx, intr, efx->net_dev,
+		   "IRQ %d on CPU %d\n", irq, raw_smp_processor_id());
+
+	if (likely(READ_ONCE(efx->irq_soft_enabled))) {
+		/* Note test interrupts */
+		if (context->index == efx->irq_level)
+			efx->last_irq_cpu = raw_smp_processor_id();
+
+		/* Schedule processing of the channel */
+		efx_schedule_channel_irq(efx->channel[context->index]);
+	}
+
+	return IRQ_HANDLED;
+}
+
+/*	NIC level access functions
+ */
+const struct efx_nic_type ef100_pf_nic_type = {
+	.revision = EFX_REV_EF100,
+	.is_vf = false,
+	.probe = ef100_probe_pf,
+	.mcdi_max_ver = 2,
+	.irq_enable_master = efx_port_dummy_op_void,
+	.irq_disable_non_ev = efx_port_dummy_op_void,
+	.push_irq_moderation = efx_channel_dummy_op_void,
+	.min_interrupt_mode = EFX_INT_MODE_MSIX,
+
+	.ev_probe = ef100_ev_probe,
+	.irq_handle_msi = ef100_msi_interrupt,
+
+	/* Per-type bar/size configuration not used on ef100. Location of
+	 * registers is defined by extended capabilities.
+	 */
+	.mem_bar = NULL,
+	.mem_map_size = NULL,
+
+};
+
+/*	NIC probe and remove
+ */
+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;
+	int i, rc;
+
+	if (WARN_ON(bar_size == 0))
+		return -EIO;
+
+	nic_data = kzalloc(sizeof(*nic_data), GFP_KERNEL);
+	if (!nic_data)
+		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;
+
+	/* Get the MC's warm boot count.  In case it's rebooting right
+	 * now, be prepared to retry.
+	 */
+	i = 0;
+	for (;;) {
+		rc = ef100_get_warm_boot_count(efx);
+		if (rc >= 0)
+			break;
+		if (++i == 5)
+			goto fail;
+		ssleep(1);
+	}
+	nic_data->warm_boot_count = rc;
+
+	/* In case we're recovering from a crash (kexec), we want to
+	 * cancel any outstanding request by the previous user of this
+	 * function.  We send a special message using the least
+	 * significant bits of the 'high' (doorbell) register.
+	 */
+	_efx_writed(efx, cpu_to_le32(1), efx_reg(efx, ER_GZ_MC_DB_HWRD));
+
+	/* Post-IO section. */
+
+	efx->max_vis = EF100_MAX_VIS;
+
+	rc = efx_init_channels(efx);
+	if (rc)
+		goto fail;
+
+	rc = ef100_register_netdev(efx);
+	if (rc)
+		goto fail;
+
+	return 0;
+fail:
+	return rc;
+}
+
+int ef100_probe_pf(struct efx_nic *efx)
+{
+	return ef100_probe_main(efx);
+}
+
+void ef100_remove(struct efx_nic *efx)
+{
+	struct ef100_nic_data *nic_data = efx->nic_data;
+
+	ef100_unregister_netdev(efx);
+	efx_fini_channels(efx);
+	kfree(efx->phy_data);
+	efx->phy_data = NULL;
+	kfree(nic_data);
+	efx->nic_data = NULL;
+}
diff --git a/drivers/net/ethernet/sfc/ef100_nic.h b/drivers/net/ethernet/sfc/ef100_nic.h
new file mode 100644
index 000000000000..643111aebba5
--- /dev/null
+++ b/drivers/net/ethernet/sfc/ef100_nic.h
@@ -0,0 +1,26 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+/****************************************************************************
+ * Driver for Solarflare network controllers and boards
+ * Copyright 2018 Solarflare Communications Inc.
+ * Copyright 2019-2020 Xilinx 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
+ * by the Free Software Foundation, incorporated herein by reference.
+ */
+
+#include "net_driver.h"
+#include "nic_common.h"
+
+extern const struct efx_nic_type ef100_pf_nic_type;
+
+int ef100_probe_pf(struct efx_nic *efx);
+void ef100_remove(struct efx_nic *efx);
+
+struct ef100_nic_data {
+	struct efx_nic *efx;
+	u16 warm_boot_count;
+};
+
+#define efx_ef100_has_cap(caps, flag) \
+	(!!((caps) & BIT_ULL(MC_CMD_GET_CAPABILITIES_V4_OUT_ ## flag ## _LBN)))
diff --git a/drivers/net/ethernet/sfc/ef100_rx.c b/drivers/net/ethernet/sfc/ef100_rx.c
new file mode 100644
index 000000000000..f06aa302e9c9
--- /dev/null
+++ b/drivers/net/ethernet/sfc/ef100_rx.c
@@ -0,0 +1,24 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/****************************************************************************
+ * Driver for Solarflare network controllers and boards
+ * Copyright 2005-2019 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
+ * by the Free Software Foundation, incorporated herein by reference.
+ */
+
+#include "net_driver.h"
+#include "ef100_rx.h"
+#include "rx_common.h"
+
+void __efx_rx_packet(struct efx_channel *channel)
+{
+	/* Stub.  No RX path yet.  Discard the buffer. */
+	struct efx_rx_buffer *rx_buf = efx_rx_buffer(&channel->rx_queue,
+						     channel->rx_pkt_index);
+	struct efx_rx_queue *rx_queue = efx_channel_get_rx_queue(channel);
+
+	efx_free_rx_buffers(rx_queue, rx_buf, 1);
+	channel->rx_pkt_n_frags = 0;
+}
diff --git a/drivers/net/ethernet/sfc/ef100_rx.h b/drivers/net/ethernet/sfc/ef100_rx.h
new file mode 100644
index 000000000000..9de9c2ab9014
--- /dev/null
+++ b/drivers/net/ethernet/sfc/ef100_rx.h
@@ -0,0 +1,17 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+/****************************************************************************
+ * Driver for Solarflare network controllers and boards
+ * Copyright 2019 Solarflare Communications Inc.
+ * Copyright 2019-2020 Xilinx 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
+ * by the Free Software Foundation, incorporated herein by reference.
+ */
+
+#ifndef EFX_EF100_RX_H
+#define EFX_EF100_RX_H
+
+#include "net_driver.h"
+
+#endif
diff --git a/drivers/net/ethernet/sfc/ef100_tx.c b/drivers/net/ethernet/sfc/ef100_tx.c
new file mode 100644
index 000000000000..0272f99b3115
--- /dev/null
+++ b/drivers/net/ethernet/sfc/ef100_tx.c
@@ -0,0 +1,43 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/****************************************************************************
+ * Driver for Solarflare network controllers and boards
+ * Copyright 2018 Solarflare Communications Inc.
+ * Copyright 2019-2020 Xilinx 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
+ * by the Free Software Foundation, incorporated herein by reference.
+ */
+
+#include "net_driver.h"
+#include "tx_common.h"
+#include "ef100_tx.h"
+
+int efx_enqueue_skb_tso(struct efx_tx_queue *tx_queue, struct sk_buff *skb,
+			bool *data_mapped)
+{
+	/* This should never be called; it's just a stub callback for some
+	 * infrastructure that's shared with the EF10 driver
+	 * (tx_queue->handle_tso, only called from tx.c which isn't linked
+	 * into sfc_ef100.ko).
+	 */
+	WARN_ON_ONCE(1);
+	return -EOPNOTSUPP;
+}
+
+/* Add a socket buffer to a TX queue
+ *
+ * You must hold netif_tx_lock() to call this function.
+ *
+ * Returns 0 on success, error code otherwise. In case of an error this
+ * function will free the SKB.
+ */
+int efx_enqueue_skb(struct efx_tx_queue *tx_queue, struct sk_buff *skb)
+{
+	/* Stub.  No TX path yet. */
+	struct efx_nic *efx = tx_queue->efx;
+
+	netif_stop_queue(efx->net_dev);
+	dev_kfree_skb_any(skb);
+	return -ENODEV;
+}
diff --git a/drivers/net/ethernet/sfc/ef100_tx.h b/drivers/net/ethernet/sfc/ef100_tx.h
new file mode 100644
index 000000000000..dedfed5d3e53
--- /dev/null
+++ b/drivers/net/ethernet/sfc/ef100_tx.h
@@ -0,0 +1,18 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+/****************************************************************************
+ * Driver for Solarflare network controllers and boards
+ * Copyright 2019 Solarflare Communications Inc.
+ * Copyright 2019-2020 Xilinx 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
+ * by the Free Software Foundation, incorporated herein by reference.
+ */
+
+#ifndef EFX_EF100_TX_H
+#define EFX_EF100_TX_H
+
+#include "net_driver.h"
+
+int efx_enqueue_skb(struct efx_tx_queue *tx_queue, struct sk_buff *skb);
+#endif
diff --git a/drivers/net/ethernet/sfc/net_driver.h b/drivers/net/ethernet/sfc/net_driver.h
index 5b3b3a976114..bf78c2faf999 100644
--- a/drivers/net/ethernet/sfc/net_driver.h
+++ b/drivers/net/ethernet/sfc/net_driver.h
@@ -38,7 +38,7 @@
  *
  **************************************************************************/
 
-#define EFX_DRIVER_VERSION	"4.1"
+#define EFX_DRIVER_VERSION	"4.2"
 
 #ifdef DEBUG
 #define EFX_WARN_ON_ONCE_PARANOID(x) WARN_ON_ONCE(x)
@@ -965,6 +965,7 @@ struct efx_async_filter_insertion {
  * @vpd_sn: Serial number read from VPD
  * @xdp_rxq_info_failed: Have any of the rx queues failed to initialise their
  *      xdp_rxq_info structures?
+ * @netdev_notifier: Netdevice notifier.
  * @mem_bar: The BAR that is mapped into membase.
  * @reg_base: Offset from the start of the bar to the function control window.
  * @monitor_work: Hardware monitor workitem
@@ -1144,6 +1145,8 @@ struct efx_nic {
 	char *vpd_sn;
 	bool xdp_rxq_info_failed;
 
+	struct notifier_block netdev_notifier;
+
 	unsigned int mem_bar;
 	u32 reg_base;
 
@@ -1532,6 +1535,13 @@ efx_get_channel(struct efx_nic *efx, unsigned index)
 	     _channel = _channel->channel ?				\
 		     (_efx)->channel[_channel->channel - 1] : NULL)
 
+static inline struct efx_channel *
+efx_get_tx_channel(struct efx_nic *efx, unsigned int index)
+{
+	EFX_WARN_ON_ONCE_PARANOID(index >= efx->n_tx_channels);
+	return efx->channel[efx->tx_channel_offset + index];
+}
+
 static inline struct efx_tx_queue *
 efx_get_tx_queue(struct efx_nic *efx, unsigned index, unsigned type)
 {



^ permalink raw reply related	[flat|nested] 25+ messages in thread

* [PATCH net-next 04/15] sfc_ef100: reset-handling stub
  2020-07-03 15:28 [PATCH net-next 00/15] sfc_ef100: driver for EF100 family NICs, part 1 Edward Cree
                   ` (2 preceding siblings ...)
  2020-07-03 15:31 ` [PATCH net-next 03/15] sfc_ef100: skeleton EF100 PF driver Edward Cree
@ 2020-07-03 15:31 ` Edward Cree
  2020-07-03 15:32 ` [PATCH net-next 05/15] sfc_ef100: PHY probe stub Edward Cree
                   ` (10 subsequent siblings)
  14 siblings, 0 replies; 25+ messages in thread
From: Edward Cree @ 2020-07-03 15:31 UTC (permalink / raw)
  To: linux-net-drivers, davem; +Cc: netdev

We don't actually do the efx_mcdi_reset() because we don't have MCDI yet.

Signed-off-by: Edward Cree <ecree@solarflare.com>
---
 drivers/net/ethernet/sfc/ef100_nic.c | 50 ++++++++++++++++++++++++++++
 1 file changed, 50 insertions(+)

diff --git a/drivers/net/ethernet/sfc/ef100_nic.c b/drivers/net/ethernet/sfc/ef100_nic.c
index 20b6f4bb35ad..772cde009472 100644
--- a/drivers/net/ethernet/sfc/ef100_nic.c
+++ b/drivers/net/ethernet/sfc/ef100_nic.c
@@ -26,6 +26,8 @@
 
 #define EF100_MAX_VIS 4096
 
+#define EF100_RESET_PORT ((ETH_RESET_MAC | ETH_RESET_PHY) << ETH_RESET_SHARED_SHIFT)
+
 /*	MCDI
  */
 static int ef100_get_warm_boot_count(struct efx_nic *efx)
@@ -78,6 +80,51 @@ static irqreturn_t ef100_msi_interrupt(int irq, void *dev_id)
 	return IRQ_HANDLED;
 }
 
+/*	Other
+ */
+
+static enum reset_type ef100_map_reset_reason(enum reset_type reason)
+{
+	if (reason == RESET_TYPE_TX_WATCHDOG)
+		return reason;
+	return RESET_TYPE_DISABLE;
+}
+
+static int ef100_map_reset_flags(u32 *flags)
+{
+	/* Only perform a RESET_TYPE_ALL because we don't support MC_REBOOTs */
+	if ((*flags & EF100_RESET_PORT)) {
+		*flags &= ~EF100_RESET_PORT;
+		return RESET_TYPE_ALL;
+	}
+	if (*flags & ETH_RESET_MGMT) {
+		*flags &= ~ETH_RESET_MGMT;
+		return RESET_TYPE_DISABLE;
+	}
+
+	return -EINVAL;
+}
+
+static int ef100_reset(struct efx_nic *efx, enum reset_type reset_type)
+{
+	int rc;
+
+	dev_close(efx->net_dev);
+
+	if (reset_type == RESET_TYPE_TX_WATCHDOG) {
+		netif_device_attach(efx->net_dev);
+		__clear_bit(reset_type, &efx->reset_pending);
+		rc = dev_open(efx->net_dev, NULL);
+	} else if (reset_type == RESET_TYPE_ALL) {
+		netif_device_attach(efx->net_dev);
+
+		rc = dev_open(efx->net_dev, NULL);
+	} else {
+		rc = 1;	/* Leave the device closed */
+	}
+	return rc;
+}
+
 /*	NIC level access functions
  */
 const struct efx_nic_type ef100_pf_nic_type = {
@@ -89,6 +136,9 @@ const struct efx_nic_type ef100_pf_nic_type = {
 	.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,
 
 	.ev_probe = ef100_ev_probe,
 	.irq_handle_msi = ef100_msi_interrupt,


^ permalink raw reply related	[flat|nested] 25+ messages in thread

* [PATCH net-next 05/15] sfc_ef100: PHY probe stub
  2020-07-03 15:28 [PATCH net-next 00/15] sfc_ef100: driver for EF100 family NICs, part 1 Edward Cree
                   ` (3 preceding siblings ...)
  2020-07-03 15:31 ` [PATCH net-next 04/15] sfc_ef100: reset-handling stub Edward Cree
@ 2020-07-03 15:32 ` Edward Cree
  2020-07-03 15:32 ` [PATCH net-next 06/15] sfc_ef100: don't call efx_reset_down()/up() on EF100 Edward Cree
                   ` (9 subsequent siblings)
  14 siblings, 0 replies; 25+ messages in thread
From: Edward Cree @ 2020-07-03 15:32 UTC (permalink / raw)
  To: linux-net-drivers, davem; +Cc: netdev

We can't actually do the MCDI to probe it fully until we have working
 MCDI, which comes later, but we need efx->phy_data to be allocated so
 that when we get MCDI events the link-state change handler doesn't
 NULL-dereference.

Signed-off-by: Edward Cree <ecree@solarflare.com>
---
 drivers/net/ethernet/sfc/ef100_nic.c | 14 ++++++++++++++
 1 file changed, 14 insertions(+)

diff --git a/drivers/net/ethernet/sfc/ef100_nic.c b/drivers/net/ethernet/sfc/ef100_nic.c
index 772cde009472..27e00b003039 100644
--- a/drivers/net/ethernet/sfc/ef100_nic.c
+++ b/drivers/net/ethernet/sfc/ef100_nic.c
@@ -80,6 +80,16 @@ static irqreturn_t ef100_msi_interrupt(int irq, void *dev_id)
 	return IRQ_HANDLED;
 }
 
+static int ef100_phy_probe(struct efx_nic *efx)
+{
+	/* stub: allocate the phy_data */
+	efx->phy_data = kzalloc(sizeof(struct efx_mcdi_phy_data), GFP_KERNEL);
+	if (!efx->phy_data)
+		return -ENOMEM;
+
+	return 0;
+}
+
 /*	Other
  */
 
@@ -196,6 +206,10 @@ static int ef100_probe_main(struct efx_nic *efx)
 
 	efx->max_vis = EF100_MAX_VIS;
 
+	rc = ef100_phy_probe(efx);
+	if (rc)
+		goto fail;
+
 	rc = efx_init_channels(efx);
 	if (rc)
 		goto fail;


^ permalink raw reply related	[flat|nested] 25+ messages in thread

* [PATCH net-next 06/15] sfc_ef100: don't call efx_reset_down()/up() on EF100
  2020-07-03 15:28 [PATCH net-next 00/15] sfc_ef100: driver for EF100 family NICs, part 1 Edward Cree
                   ` (4 preceding siblings ...)
  2020-07-03 15:32 ` [PATCH net-next 05/15] sfc_ef100: PHY probe stub Edward Cree
@ 2020-07-03 15:32 ` Edward Cree
  2020-07-04  2:15   ` kernel test robot
  2020-07-03 15:33 ` [PATCH net-next 07/15] sfc_ef100: implement MCDI transport Edward Cree
                   ` (8 subsequent siblings)
  14 siblings, 1 reply; 25+ messages in thread
From: Edward Cree @ 2020-07-03 15:32 UTC (permalink / raw)
  To: linux-net-drivers, davem; +Cc: netdev

We handle everything ourselves in ef100_reset(), rather than relying on
 the generic down/up routines.

Signed-off-by: Edward Cree <ecree@solarflare.com>
---
 drivers/net/ethernet/sfc/efx_common.c | 9 +++++++--
 1 file changed, 7 insertions(+), 2 deletions(-)

diff --git a/drivers/net/ethernet/sfc/efx_common.c b/drivers/net/ethernet/sfc/efx_common.c
index 5667694c6514..1bccd1f2cfa6 100644
--- a/drivers/net/ethernet/sfc/efx_common.c
+++ b/drivers/net/ethernet/sfc/efx_common.c
@@ -821,7 +821,11 @@ int efx_reset(struct efx_nic *efx, enum reset_type method)
 		   RESET_TYPE(method));
 
 	efx_device_detach_sync(efx);
-	efx_reset_down(efx, method);
+	/* efx_reset_down() grabs locks that prevent recovery on EF100.
+	 * EF100 reset is handled in the efx_nic_type callback below.
+	 */
+	if (efx_nic_rev(efx) != EFX_REV_EF100)
+		efx_reset_down(efx, method);
 
 	rc = efx->type->reset(efx, method);
 	if (rc) {
@@ -849,7 +853,8 @@ int efx_reset(struct efx_nic *efx, enum reset_type method)
 	disabled = rc ||
 		method == RESET_TYPE_DISABLE ||
 		method == RESET_TYPE_RECOVER_OR_DISABLE;
-	rc2 = efx_reset_up(efx, method, !disabled);
+	if (efx_nic_rev(efx) != EFX_REV_EF100)
+		rc2 = efx_reset_up(efx, method, !disabled);
 	if (rc2) {
 		disabled = true;
 		if (!rc)


^ permalink raw reply related	[flat|nested] 25+ messages in thread

* [PATCH net-next 07/15] sfc_ef100: implement MCDI transport
  2020-07-03 15:28 [PATCH net-next 00/15] sfc_ef100: driver for EF100 family NICs, part 1 Edward Cree
                   ` (5 preceding siblings ...)
  2020-07-03 15:32 ` [PATCH net-next 06/15] sfc_ef100: don't call efx_reset_down()/up() on EF100 Edward Cree
@ 2020-07-03 15:33 ` Edward Cree
  2020-07-03 15:33 ` [PATCH net-next 08/15] sfc_ef100: implement ndo_open/close and EVQ probing Edward Cree
                   ` (7 subsequent siblings)
  14 siblings, 0 replies; 25+ messages in thread
From: Edward Cree @ 2020-07-03 15:33 UTC (permalink / raw)
  To: linux-net-drivers, davem; +Cc: netdev

Signed-off-by: Edward Cree <ecree@solarflare.com>
---
 drivers/net/ethernet/sfc/ef100_nic.c | 106 +++++++++++++++++++++++++++
 drivers/net/ethernet/sfc/ef100_nic.h |   1 +
 2 files changed, 107 insertions(+)

diff --git a/drivers/net/ethernet/sfc/ef100_nic.c b/drivers/net/ethernet/sfc/ef100_nic.c
index 27e00b003039..57e56a3f9b14 100644
--- a/drivers/net/ethernet/sfc/ef100_nic.c
+++ b/drivers/net/ethernet/sfc/ef100_nic.c
@@ -25,11 +25,23 @@
 #include "ef100_netdev.h"
 
 #define EF100_MAX_VIS 4096
+#define EF100_NUM_MCDI_BUFFERS	1
+#define MCDI_BUF_LEN (8 + MCDI_CTL_SDU_LEN_MAX)
 
 #define EF100_RESET_PORT ((ETH_RESET_MAC | ETH_RESET_PHY) << ETH_RESET_SHARED_SHIFT)
 
 /*	MCDI
  */
+static u8 *ef100_mcdi_buf(struct efx_nic *efx, u8 bufid, dma_addr_t *dma_addr)
+{
+	struct ef100_nic_data *nic_data = efx->nic_data;
+
+	if (dma_addr)
+		*dma_addr = nic_data->mcdi_buf.dma_addr +
+			    bufid * ALIGN(MCDI_BUF_LEN, 256);
+	return nic_data->mcdi_buf.addr + bufid * ALIGN(MCDI_BUF_LEN, 256);
+}
+
 static int ef100_get_warm_boot_count(struct efx_nic *efx)
 {
 	efx_dword_t reg;
@@ -46,6 +58,72 @@ static int ef100_get_warm_boot_count(struct efx_nic *efx)
 	}
 }
 
+static void ef100_mcdi_request(struct efx_nic *efx,
+			       const efx_dword_t *hdr, size_t hdr_len,
+			       const efx_dword_t *sdu, size_t sdu_len)
+{
+	dma_addr_t dma_addr;
+	u8 *pdu = ef100_mcdi_buf(efx, 0, &dma_addr);
+
+	memcpy(pdu, hdr, hdr_len);
+	memcpy(pdu + hdr_len, sdu, sdu_len);
+	wmb();
+
+	/* The hardware provides 'low' and 'high' (doorbell) registers
+	 * for passing the 64-bit address of an MCDI request to
+	 * firmware.  However the dwords are swapped by firmware.  The
+	 * least significant bits of the doorbell are then 0 for all
+	 * MCDI requests due to alignment.
+	 */
+	_efx_writed(efx, cpu_to_le32((u64)dma_addr >> 32),  efx_reg(efx, ER_GZ_MC_DB_LWRD));
+	_efx_writed(efx, cpu_to_le32((u32)dma_addr),  efx_reg(efx, ER_GZ_MC_DB_HWRD));
+}
+
+static bool ef100_mcdi_poll_response(struct efx_nic *efx)
+{
+	const efx_dword_t hdr =
+		*(const efx_dword_t *)(ef100_mcdi_buf(efx, 0, NULL));
+
+	rmb();
+	return EFX_DWORD_FIELD(hdr, MCDI_HEADER_RESPONSE);
+}
+
+static void ef100_mcdi_read_response(struct efx_nic *efx,
+				     efx_dword_t *outbuf, size_t offset,
+				     size_t outlen)
+{
+	const u8 *pdu = ef100_mcdi_buf(efx, 0, NULL);
+
+	memcpy(outbuf, pdu + offset, outlen);
+}
+
+static int ef100_mcdi_poll_reboot(struct efx_nic *efx)
+{
+	struct ef100_nic_data *nic_data = efx->nic_data;
+	int rc;
+
+	rc = ef100_get_warm_boot_count(efx);
+	if (rc < 0) {
+		/* The firmware is presumably in the process of
+		 * rebooting.  However, we are supposed to report each
+		 * reboot just once, so we must only do that once we
+		 * can read and store the updated warm boot count.
+		 */
+		return 0;
+	}
+
+	if (rc == nic_data->warm_boot_count)
+		return 0;
+
+	nic_data->warm_boot_count = rc;
+
+	return -EIO;
+}
+
+static void ef100_mcdi_reboot_detected(struct efx_nic *efx)
+{
+}
+
 /*	Event handling
  */
 static int ef100_ev_probe(struct efx_channel *channel)
@@ -142,6 +220,11 @@ const struct efx_nic_type ef100_pf_nic_type = {
 	.is_vf = false,
 	.probe = ef100_probe_pf,
 	.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_disable_non_ev = efx_port_dummy_op_void,
 	.push_irq_moderation = efx_channel_dummy_op_void,
@@ -181,6 +264,15 @@ static int ef100_probe_main(struct efx_nic *efx)
 	net_dev->features |= efx->type->offload_features;
 	net_dev->hw_features |= efx->type->offload_features;
 
+	/* we assume later that we can copy from this buffer in dwords */
+	BUILD_BUG_ON(MCDI_CTL_SDU_LEN_MAX_V2 % 4);
+
+	/* MCDI buffers must be 256 byte aligned. */
+	rc = efx_nic_alloc_buffer(efx, &nic_data->mcdi_buf, MCDI_BUF_LEN,
+				  GFP_KERNEL);
+	if (rc)
+		goto fail;
+
 	/* Get the MC's warm boot count.  In case it's rebooting right
 	 * now, be prepared to retry.
 	 */
@@ -204,6 +296,16 @@ 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;
+
 	efx->max_vis = EF100_MAX_VIS;
 
 	rc = ef100_phy_probe(efx);
@@ -236,6 +338,10 @@ void ef100_remove(struct efx_nic *efx)
 	efx_fini_channels(efx);
 	kfree(efx->phy_data);
 	efx->phy_data = NULL;
+	efx_mcdi_detach(efx);
+	efx_mcdi_fini(efx);
+	if (nic_data)
+		efx_nic_free_buffer(efx, &nic_data->mcdi_buf);
 	kfree(nic_data);
 	efx->nic_data = NULL;
 }
diff --git a/drivers/net/ethernet/sfc/ef100_nic.h b/drivers/net/ethernet/sfc/ef100_nic.h
index 643111aebba5..a4290d183879 100644
--- a/drivers/net/ethernet/sfc/ef100_nic.h
+++ b/drivers/net/ethernet/sfc/ef100_nic.h
@@ -19,6 +19,7 @@ void ef100_remove(struct efx_nic *efx);
 
 struct ef100_nic_data {
 	struct efx_nic *efx;
+	struct efx_buffer mcdi_buf;
 	u16 warm_boot_count;
 };
 


^ permalink raw reply related	[flat|nested] 25+ messages in thread

* [PATCH net-next 08/15] sfc_ef100: implement ndo_open/close and EVQ probing
  2020-07-03 15:28 [PATCH net-next 00/15] sfc_ef100: driver for EF100 family NICs, part 1 Edward Cree
                   ` (6 preceding siblings ...)
  2020-07-03 15:33 ` [PATCH net-next 07/15] sfc_ef100: implement MCDI transport Edward Cree
@ 2020-07-03 15:33 ` Edward Cree
  2020-07-03 15:34 ` [PATCH net-next 09/15] sfc_ef100: process events for MCDI completions Edward Cree
                   ` (6 subsequent siblings)
  14 siblings, 0 replies; 25+ messages in thread
From: Edward Cree @ 2020-07-03 15:33 UTC (permalink / raw)
  To: linux-net-drivers, davem; +Cc: netdev

Channels are probed, but actual event handling is still stubbed out.

Stub implementation of check_caps is needed because ptp.c will call into
 it from efx_ptp_use_mac_tx_timestamps() to decide if it wants TXQs.

Signed-off-by: Edward Cree <ecree@solarflare.com>
---
 drivers/net/ethernet/sfc/ef100_netdev.c | 143 ++++++++++++++++++++++++
 drivers/net/ethernet/sfc/ef100_nic.c    |  49 ++++++++
 drivers/net/ethernet/sfc/ef100_nic.h    |   1 +
 drivers/net/ethernet/sfc/ef100_rx.c     |   6 +
 drivers/net/ethernet/sfc/ef100_rx.h     |   2 +
 drivers/net/ethernet/sfc/ef100_tx.c     |  19 ++++
 drivers/net/ethernet/sfc/ef100_tx.h     |   4 +
 7 files changed, 224 insertions(+)

diff --git a/drivers/net/ethernet/sfc/ef100_netdev.c b/drivers/net/ethernet/sfc/ef100_netdev.c
index 356938104cb2..3e4e7241d9a8 100644
--- a/drivers/net/ethernet/sfc/ef100_netdev.c
+++ b/drivers/net/ethernet/sfc/ef100_netdev.c
@@ -35,6 +35,147 @@ static void ef100_update_name(struct efx_nic *efx)
 	strcpy(efx->name, efx->net_dev->name);
 }
 
+static int ef100_alloc_vis(struct efx_nic *efx, unsigned int *allocated_vis)
+{
+	/* EF100 uses a single TXQ per channel, as all checksum offloading
+	 * is configured in the TX descriptor, and there is no TX Pacer for
+	 * HIGHPRI queues.
+	 */
+	unsigned int tx_vis = efx->n_tx_channels + efx->n_extra_tx_channels;
+	unsigned int rx_vis = efx->n_rx_channels;
+	unsigned int min_vis, max_vis;
+
+	EFX_WARN_ON_PARANOID(efx->tx_queues_per_channel != 1);
+
+	tx_vis += efx->n_xdp_channels * efx->xdp_tx_per_channel;
+
+	max_vis = max(rx_vis, tx_vis);
+	/* Currently don't handle resource starvation and only accept
+	 * our maximum needs and no less.
+	 */
+	min_vis = max_vis;
+
+	return efx_mcdi_alloc_vis(efx, min_vis, max_vis,
+				  NULL, allocated_vis);
+}
+
+static int ef100_remap_bar(struct efx_nic *efx, int max_vis)
+{
+	unsigned int uc_mem_map_size;
+	void __iomem *membase;
+
+	efx->max_vis = max_vis;
+	uc_mem_map_size = PAGE_ALIGN(max_vis * efx->vi_stride);
+
+	/* Extend the original UC mapping of the memory BAR */
+	membase = ioremap(efx->membase_phys, uc_mem_map_size);
+	if (!membase) {
+		netif_err(efx, probe, efx->net_dev,
+			  "could not extend memory BAR to %x\n",
+			  uc_mem_map_size);
+		return -ENOMEM;
+	}
+	iounmap(efx->membase);
+	efx->membase = membase;
+	return 0;
+}
+
+/* Context: process, rtnl_lock() held.
+ * Note that the kernel will ignore our return code; this method
+ * should really be a void.
+ */
+static int ef100_net_stop(struct net_device *net_dev)
+{
+	struct efx_nic *efx = netdev_priv(net_dev);
+
+	netif_dbg(efx, ifdown, efx->net_dev, "closing on CPU %d\n",
+		  raw_smp_processor_id());
+
+	netif_stop_queue(net_dev);
+	efx_stop_all(efx);
+	efx_disable_interrupts(efx);
+	efx_clear_interrupt_affinity(efx);
+	efx_nic_fini_interrupt(efx);
+	efx_fini_napi(efx);
+	efx_remove_channels(efx);
+	efx_mcdi_free_vis(efx);
+	efx_remove_interrupts(efx);
+
+	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);
+	unsigned int allocated_vis;
+	int rc;
+
+	ef100_update_name(efx);
+	netif_dbg(efx, ifup, net_dev, "opening device on CPU %d\n",
+		  raw_smp_processor_id());
+
+	rc = efx_check_disabled(efx);
+	if (rc)
+		goto fail;
+
+	rc = efx_probe_interrupts(efx);
+	if (rc)
+		goto fail;
+
+	rc = efx_set_channels(efx);
+	if (rc)
+		goto fail;
+
+	rc = efx_mcdi_free_vis(efx);
+	if (rc)
+		goto fail;
+
+	rc = ef100_alloc_vis(efx, &allocated_vis);
+	if (rc)
+		goto fail;
+
+	rc = efx_probe_channels(efx);
+	if (rc)
+		return rc;
+
+	rc = ef100_remap_bar(efx, allocated_vis);
+	if (rc)
+		goto fail;
+
+	efx_init_napi(efx);
+
+	rc = efx_nic_init_interrupt(efx);
+	if (rc)
+		goto fail;
+	efx_set_interrupt_affinity(efx);
+
+	rc = efx_enable_interrupts(efx);
+	if (rc)
+		goto fail;
+
+	/* in case the MC rebooted while we were stopped, consume the change
+	 * to the warm reboot count
+	 */
+	(void) efx_mcdi_poll_reboot(efx);
+
+	efx_start_all(efx);
+
+	/* Link state detection is normally event-driven; we have
+	 * to poll now because we could have missed a change
+	 */
+	mutex_lock(&efx->mac_lock);
+	if (efx_mcdi_phy_poll(efx))
+		efx_link_status_changed(efx);
+	mutex_unlock(&efx->mac_lock);
+
+	return 0;
+
+fail:
+	ef100_net_stop(net_dev);
+	return rc;
+}
+
 /* Initiate a packet transmission.  We use one channel per CPU
  * (sharing when we have more CPUs than channels).
  *
@@ -70,6 +211,8 @@ netdev_tx_t ef100_hard_start_xmit(struct sk_buff *skb,
 }
 
 static const struct net_device_ops ef100_netdev_ops = {
+	.ndo_open               = ef100_net_open,
+	.ndo_stop               = ef100_net_stop,
 	.ndo_start_xmit         = ef100_hard_start_xmit,
 };
 
diff --git a/drivers/net/ethernet/sfc/ef100_nic.c b/drivers/net/ethernet/sfc/ef100_nic.c
index 57e56a3f9b14..f62f3be1238b 100644
--- a/drivers/net/ethernet/sfc/ef100_nic.c
+++ b/drivers/net/ethernet/sfc/ef100_nic.c
@@ -135,9 +135,37 @@ static int ef100_ev_probe(struct efx_channel *channel)
 				    GFP_KERNEL);
 }
 
+static int ef100_ev_init(struct efx_channel *channel)
+{
+	struct ef100_nic_data *nic_data = channel->efx->nic_data;
+
+	/* initial phase is 0 */
+	clear_bit(channel->channel, nic_data->evq_phases);
+
+	return efx_mcdi_ev_init(channel, false, false);
+}
+
+static void ef100_ev_read_ack(struct efx_channel *channel)
+{
+	efx_dword_t evq_prime;
+
+	EFX_POPULATE_DWORD_2(evq_prime,
+			     ERF_GZ_EVQ_ID, channel->channel,
+			     ERF_GZ_IDX, channel->eventq_read_ptr &
+					 channel->eventq_mask);
+
+	efx_writed(channel->efx, &evq_prime,
+		   efx_reg(channel->efx, ER_GZ_EVQ_INT_PRIME));
+}
+
 /* efx_mcdi_process_event() may call this */
 void efx_mcdi_sensor_event(struct efx_nic *efx, efx_qword_t *ev) {}
 
+static int ef100_ev_process(struct efx_channel *channel, int quota)
+{
+	return 0;
+}
+
 static irqreturn_t ef100_msi_interrupt(int irq, void *dev_id)
 {
 	struct efx_msi_context *context = dev_id;
@@ -213,6 +241,13 @@ static int ef100_reset(struct efx_nic *efx, enum reset_type reset_type)
 	return rc;
 }
 
+static unsigned int ef100_check_caps(const struct efx_nic *efx,
+				     u8 flag, u32 offset)
+{
+	/* stub */
+	return 0;
+}
+
 /*	NIC level access functions
  */
 const struct efx_nic_type ef100_pf_nic_type = {
@@ -233,8 +268,22 @@ const struct efx_nic_type ef100_pf_nic_type = {
 	.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,
+	.tx_probe = ef100_tx_probe,
+	.tx_init = ef100_tx_init,
+	.tx_write = ef100_tx_write,
+	.rx_probe = efx_mcdi_rx_probe,
+	.rx_init = efx_mcdi_rx_init,
+	.rx_remove = efx_mcdi_rx_remove,
+	.rx_write = ef100_rx_write,
 
 	/* Per-type bar/size configuration not used on ef100. Location of
 	 * registers is defined by extended capabilities.
diff --git a/drivers/net/ethernet/sfc/ef100_nic.h b/drivers/net/ethernet/sfc/ef100_nic.h
index a4290d183879..5d376e2d98a7 100644
--- a/drivers/net/ethernet/sfc/ef100_nic.h
+++ b/drivers/net/ethernet/sfc/ef100_nic.h
@@ -21,6 +21,7 @@ struct ef100_nic_data {
 	struct efx_nic *efx;
 	struct efx_buffer mcdi_buf;
 	u16 warm_boot_count;
+	DECLARE_BITMAP(evq_phases, EFX_MAX_CHANNELS);
 };
 
 #define efx_ef100_has_cap(caps, flag) \
diff --git a/drivers/net/ethernet/sfc/ef100_rx.c b/drivers/net/ethernet/sfc/ef100_rx.c
index f06aa302e9c9..75d0e32a5871 100644
--- a/drivers/net/ethernet/sfc/ef100_rx.c
+++ b/drivers/net/ethernet/sfc/ef100_rx.c
@@ -22,3 +22,9 @@ void __efx_rx_packet(struct efx_channel *channel)
 	efx_free_rx_buffers(rx_queue, rx_buf, 1);
 	channel->rx_pkt_n_frags = 0;
 }
+
+/* RX stubs */
+
+void ef100_rx_write(struct efx_rx_queue *rx_queue)
+{
+}
diff --git a/drivers/net/ethernet/sfc/ef100_rx.h b/drivers/net/ethernet/sfc/ef100_rx.h
index 9de9c2ab9014..22222e2769fa 100644
--- a/drivers/net/ethernet/sfc/ef100_rx.h
+++ b/drivers/net/ethernet/sfc/ef100_rx.h
@@ -14,4 +14,6 @@
 
 #include "net_driver.h"
 
+void ef100_rx_write(struct efx_rx_queue *rx_queue);
+
 #endif
diff --git a/drivers/net/ethernet/sfc/ef100_tx.c b/drivers/net/ethernet/sfc/ef100_tx.c
index 0272f99b3115..daf5069e5d34 100644
--- a/drivers/net/ethernet/sfc/ef100_tx.c
+++ b/drivers/net/ethernet/sfc/ef100_tx.c
@@ -13,6 +13,25 @@
 #include "tx_common.h"
 #include "ef100_tx.h"
 
+/* TX queue stubs */
+int ef100_tx_probe(struct efx_tx_queue *tx_queue)
+{
+	return 0;
+}
+
+void ef100_tx_init(struct efx_tx_queue *tx_queue)
+{
+	/* must be the inverse of lookup in efx_get_tx_channel */
+	tx_queue->core_txq =
+		netdev_get_tx_queue(tx_queue->efx->net_dev,
+				    tx_queue->channel->channel -
+				    tx_queue->efx->tx_channel_offset);
+}
+
+void ef100_tx_write(struct efx_tx_queue *tx_queue)
+{
+}
+
 int efx_enqueue_skb_tso(struct efx_tx_queue *tx_queue, struct sk_buff *skb,
 			bool *data_mapped)
 {
diff --git a/drivers/net/ethernet/sfc/ef100_tx.h b/drivers/net/ethernet/sfc/ef100_tx.h
index dedfed5d3e53..9514edc4fb7f 100644
--- a/drivers/net/ethernet/sfc/ef100_tx.h
+++ b/drivers/net/ethernet/sfc/ef100_tx.h
@@ -14,5 +14,9 @@
 
 #include "net_driver.h"
 
+int ef100_tx_probe(struct efx_tx_queue *tx_queue);
+void ef100_tx_init(struct efx_tx_queue *tx_queue);
+void ef100_tx_write(struct efx_tx_queue *tx_queue);
+
 int efx_enqueue_skb(struct efx_tx_queue *tx_queue, struct sk_buff *skb);
 #endif


^ permalink raw reply related	[flat|nested] 25+ messages in thread

* [PATCH net-next 09/15] sfc_ef100: process events for MCDI completions
  2020-07-03 15:28 [PATCH net-next 00/15] sfc_ef100: driver for EF100 family NICs, part 1 Edward Cree
                   ` (7 preceding siblings ...)
  2020-07-03 15:33 ` [PATCH net-next 08/15] sfc_ef100: implement ndo_open/close and EVQ probing Edward Cree
@ 2020-07-03 15:34 ` Edward Cree
  2020-07-03 15:34 ` [PATCH net-next 10/15] sfc_ef100: read datapath caps, implement check_caps Edward Cree
                   ` (5 subsequent siblings)
  14 siblings, 0 replies; 25+ messages in thread
From: Edward Cree @ 2020-07-03 15:34 UTC (permalink / raw)
  To: linux-net-drivers, davem; +Cc: netdev

Currently RX and TX-completion events are unhandled, as neither the RX
 nor the TX path has been implemented yet.

Signed-off-by: Edward Cree <ecree@solarflare.com>
---
 drivers/net/ethernet/sfc/ef100_nic.c | 57 +++++++++++++++++++++++++++-
 1 file changed, 56 insertions(+), 1 deletion(-)

diff --git a/drivers/net/ethernet/sfc/ef100_nic.c b/drivers/net/ethernet/sfc/ef100_nic.c
index f62f3be1238b..d415d25e532a 100644
--- a/drivers/net/ethernet/sfc/ef100_nic.c
+++ b/drivers/net/ethernet/sfc/ef100_nic.c
@@ -163,7 +163,62 @@ void efx_mcdi_sensor_event(struct efx_nic *efx, efx_qword_t *ev) {}
 
 static int ef100_ev_process(struct efx_channel *channel, int quota)
 {
-	return 0;
+	struct efx_nic *efx = channel->efx;
+	struct ef100_nic_data *nic_data;
+	bool evq_phase, old_evq_phase;
+	unsigned int read_ptr;
+	efx_qword_t *p_event;
+	int spent = 0;
+	bool ev_phase;
+	int ev_type;
+
+	if (unlikely(!channel->enabled))
+		return 0;
+
+	nic_data = efx->nic_data;
+	evq_phase = test_bit(channel->channel, nic_data->evq_phases);
+	old_evq_phase = evq_phase;
+	read_ptr = channel->eventq_read_ptr;
+	BUILD_BUG_ON(ESF_GZ_EV_RXPKTS_PHASE_LBN != ESF_GZ_EV_TXCMPL_PHASE_LBN);
+
+	while (spent < quota) {
+		p_event = efx_event(channel, read_ptr);
+
+		ev_phase = !!EFX_QWORD_FIELD(*p_event, ESF_GZ_EV_RXPKTS_PHASE);
+		if (ev_phase != evq_phase)
+			break;
+
+		netif_vdbg(efx, drv, efx->net_dev,
+			   "processing event on %d " EFX_QWORD_FMT "\n",
+			   channel->channel, EFX_QWORD_VAL(*p_event));
+
+		ev_type = EFX_QWORD_FIELD(*p_event, ESF_GZ_E_TYPE);
+
+		switch (ev_type) {
+		case ESE_GZ_EF100_EV_MCDI:
+			efx_mcdi_process_event(channel, p_event);
+			break;
+		case ESE_GZ_EF100_EV_DRIVER:
+			netif_info(efx, drv, efx->net_dev,
+				   "Driver initiated event " EFX_QWORD_FMT "\n",
+				   EFX_QWORD_VAL(*p_event));
+			break;
+		default:
+			netif_info(efx, drv, efx->net_dev,
+				   "Unhandled event " EFX_QWORD_FMT "\n",
+				   EFX_QWORD_VAL(*p_event));
+		}
+
+		++read_ptr;
+		if ((read_ptr & channel->eventq_mask) == 0)
+			evq_phase = !evq_phase;
+	}
+
+	channel->eventq_read_ptr = read_ptr;
+	if (evq_phase != old_evq_phase)
+		change_bit(channel->channel, nic_data->evq_phases);
+
+	return spent;
 }
 
 static irqreturn_t ef100_msi_interrupt(int irq, void *dev_id)


^ permalink raw reply related	[flat|nested] 25+ messages in thread

* [PATCH net-next 10/15] sfc_ef100: read datapath caps, implement check_caps
  2020-07-03 15:28 [PATCH net-next 00/15] sfc_ef100: driver for EF100 family NICs, part 1 Edward Cree
                   ` (8 preceding siblings ...)
  2020-07-03 15:34 ` [PATCH net-next 09/15] sfc_ef100: process events for MCDI completions Edward Cree
@ 2020-07-03 15:34 ` Edward Cree
  2020-07-03 15:35 ` [PATCH net-next 11/15] sfc_ef100: extend ef100_check_caps to cover datapath_caps3 Edward Cree
                   ` (4 subsequent siblings)
  14 siblings, 0 replies; 25+ messages in thread
From: Edward Cree @ 2020-07-03 15:34 UTC (permalink / raw)
  To: linux-net-drivers, davem; +Cc: netdev

Signed-off-by: Edward Cree <ecree@solarflare.com>
---
 drivers/net/ethernet/sfc/ef100_nic.c | 58 +++++++++++++++++++++++++++-
 drivers/net/ethernet/sfc/ef100_nic.h |  2 +
 2 files changed, 58 insertions(+), 2 deletions(-)

diff --git a/drivers/net/ethernet/sfc/ef100_nic.c b/drivers/net/ethernet/sfc/ef100_nic.c
index d415d25e532a..06e9ae58f1c6 100644
--- a/drivers/net/ethernet/sfc/ef100_nic.c
+++ b/drivers/net/ethernet/sfc/ef100_nic.c
@@ -124,6 +124,49 @@ static void ef100_mcdi_reboot_detected(struct efx_nic *efx)
 {
 }
 
+/*	MCDI calls
+ */
+static int efx_ef100_init_datapath_caps(struct efx_nic *efx)
+{
+	MCDI_DECLARE_BUF(outbuf, MC_CMD_GET_CAPABILITIES_V4_OUT_LEN);
+	struct ef100_nic_data *nic_data = efx->nic_data;
+	u8 vi_window_mode;
+	size_t outlen;
+	int rc;
+
+	BUILD_BUG_ON(MC_CMD_GET_CAPABILITIES_IN_LEN != 0);
+
+	rc = efx_mcdi_rpc(efx, MC_CMD_GET_CAPABILITIES, NULL, 0,
+			  outbuf, sizeof(outbuf), &outlen);
+	if (rc)
+		return rc;
+	if (outlen < MC_CMD_GET_CAPABILITIES_V4_OUT_LEN) {
+		netif_err(efx, drv, efx->net_dev,
+			  "unable to read datapath firmware capabilities\n");
+		return -EIO;
+	}
+
+	nic_data->datapath_caps = MCDI_DWORD(outbuf,
+					     GET_CAPABILITIES_OUT_FLAGS1);
+	nic_data->datapath_caps2 = MCDI_DWORD(outbuf,
+					      GET_CAPABILITIES_V2_OUT_FLAGS2);
+
+	vi_window_mode = MCDI_BYTE(outbuf,
+				   GET_CAPABILITIES_V3_OUT_VI_WINDOW_MODE);
+	rc = efx_mcdi_window_mode_to_stride(efx, vi_window_mode);
+	if (rc)
+		return rc;
+
+	if (efx_ef100_has_cap(nic_data->datapath_caps2, TX_TSO_V3))
+		efx->net_dev->features |= NETIF_F_TSO | NETIF_F_TSO6;
+	efx->num_mac_stats = MCDI_WORD(outbuf,
+				       GET_CAPABILITIES_V4_OUT_MAC_STATS_NUM_STATS);
+	netif_dbg(efx, probe, efx->net_dev,
+		  "firmware reports num_mac_stats = %u\n",
+		  efx->num_mac_stats);
+	return 0;
+}
+
 /*	Event handling
  */
 static int ef100_ev_probe(struct efx_channel *channel)
@@ -299,8 +342,16 @@ static int ef100_reset(struct efx_nic *efx, enum reset_type reset_type)
 static unsigned int ef100_check_caps(const struct efx_nic *efx,
 				     u8 flag, u32 offset)
 {
-	/* stub */
-	return 0;
+	const struct ef100_nic_data *nic_data = efx->nic_data;
+
+	switch (offset) {
+	case MC_CMD_GET_CAPABILITIES_V8_OUT_FLAGS1_OFST:
+		return nic_data->datapath_caps & BIT_ULL(flag);
+	case MC_CMD_GET_CAPABILITIES_V8_OUT_FLAGS2_OFST:
+		return nic_data->datapath_caps2 & BIT_ULL(flag);
+	default:
+		return 0;
+	}
 }
 
 /*	NIC level access functions
@@ -409,6 +460,9 @@ 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;
 
diff --git a/drivers/net/ethernet/sfc/ef100_nic.h b/drivers/net/ethernet/sfc/ef100_nic.h
index 5d376e2d98a7..392611cc33b5 100644
--- a/drivers/net/ethernet/sfc/ef100_nic.h
+++ b/drivers/net/ethernet/sfc/ef100_nic.h
@@ -20,6 +20,8 @@ void ef100_remove(struct efx_nic *efx);
 struct ef100_nic_data {
 	struct efx_nic *efx;
 	struct efx_buffer mcdi_buf;
+	u32 datapath_caps;
+	u32 datapath_caps2;
 	u16 warm_boot_count;
 	DECLARE_BITMAP(evq_phases, EFX_MAX_CHANNELS);
 };


^ permalink raw reply related	[flat|nested] 25+ messages in thread

* [PATCH net-next 11/15] sfc_ef100: extend ef100_check_caps to cover datapath_caps3
  2020-07-03 15:28 [PATCH net-next 00/15] sfc_ef100: driver for EF100 family NICs, part 1 Edward Cree
                   ` (9 preceding siblings ...)
  2020-07-03 15:34 ` [PATCH net-next 10/15] sfc_ef100: read datapath caps, implement check_caps Edward Cree
@ 2020-07-03 15:35 ` Edward Cree
  2020-07-03 15:35 ` [PATCH net-next 12/15] sfc_ef100: actually perform resets Edward Cree
                   ` (3 subsequent siblings)
  14 siblings, 0 replies; 25+ messages in thread
From: Edward Cree @ 2020-07-03 15:35 UTC (permalink / raw)
  To: linux-net-drivers, davem; +Cc: netdev

MC_CMD_GET_CAPABILITIES now has a third word of flags; extend the
 efx_has_cap() machinery to cover it.

Signed-off-by: Edward Cree <ecree@solarflare.com>
---
 drivers/net/ethernet/sfc/ef100_nic.c | 9 ++++++++-
 drivers/net/ethernet/sfc/ef100_nic.h | 1 +
 drivers/net/ethernet/sfc/mcdi.h      | 4 ++--
 3 files changed, 11 insertions(+), 3 deletions(-)

diff --git a/drivers/net/ethernet/sfc/ef100_nic.c b/drivers/net/ethernet/sfc/ef100_nic.c
index 06e9ae58f1c6..fe7a5c4bc291 100644
--- a/drivers/net/ethernet/sfc/ef100_nic.c
+++ b/drivers/net/ethernet/sfc/ef100_nic.c
@@ -128,7 +128,7 @@ static void ef100_mcdi_reboot_detected(struct efx_nic *efx)
  */
 static int efx_ef100_init_datapath_caps(struct efx_nic *efx)
 {
-	MCDI_DECLARE_BUF(outbuf, MC_CMD_GET_CAPABILITIES_V4_OUT_LEN);
+	MCDI_DECLARE_BUF(outbuf, MC_CMD_GET_CAPABILITIES_V7_OUT_LEN);
 	struct ef100_nic_data *nic_data = efx->nic_data;
 	u8 vi_window_mode;
 	size_t outlen;
@@ -150,6 +150,11 @@ static int efx_ef100_init_datapath_caps(struct efx_nic *efx)
 					     GET_CAPABILITIES_OUT_FLAGS1);
 	nic_data->datapath_caps2 = MCDI_DWORD(outbuf,
 					      GET_CAPABILITIES_V2_OUT_FLAGS2);
+	if (outlen < MC_CMD_GET_CAPABILITIES_V7_OUT_LEN)
+		nic_data->datapath_caps3 = 0;
+	else
+		nic_data->datapath_caps3 = MCDI_DWORD(outbuf,
+						      GET_CAPABILITIES_V7_OUT_FLAGS3);
 
 	vi_window_mode = MCDI_BYTE(outbuf,
 				   GET_CAPABILITIES_V3_OUT_VI_WINDOW_MODE);
@@ -349,6 +354,8 @@ static unsigned int ef100_check_caps(const struct efx_nic *efx,
 		return nic_data->datapath_caps & BIT_ULL(flag);
 	case MC_CMD_GET_CAPABILITIES_V8_OUT_FLAGS2_OFST:
 		return nic_data->datapath_caps2 & BIT_ULL(flag);
+	case MC_CMD_GET_CAPABILITIES_V8_OUT_FLAGS3_OFST:
+		return nic_data->datapath_caps3 & BIT_ULL(flag);
 	default:
 		return 0;
 	}
diff --git a/drivers/net/ethernet/sfc/ef100_nic.h b/drivers/net/ethernet/sfc/ef100_nic.h
index 392611cc33b5..7744ec85bec6 100644
--- a/drivers/net/ethernet/sfc/ef100_nic.h
+++ b/drivers/net/ethernet/sfc/ef100_nic.h
@@ -22,6 +22,7 @@ struct ef100_nic_data {
 	struct efx_buffer mcdi_buf;
 	u32 datapath_caps;
 	u32 datapath_caps2;
+	u32 datapath_caps3;
 	u16 warm_boot_count;
 	DECLARE_BITMAP(evq_phases, EFX_MAX_CHANNELS);
 };
diff --git a/drivers/net/ethernet/sfc/mcdi.h b/drivers/net/ethernet/sfc/mcdi.h
index e053adfe82b0..658cf345420d 100644
--- a/drivers/net/ethernet/sfc/mcdi.h
+++ b/drivers/net/ethernet/sfc/mcdi.h
@@ -327,10 +327,10 @@ void efx_mcdi_sensor_event(struct efx_nic *efx, efx_qword_t *ev);
 	EFX_QWORD_FIELD(_ev, MCDI_EVENT_ ## _field)
 
 #define MCDI_CAPABILITY(field)						\
-	MC_CMD_GET_CAPABILITIES_V4_OUT_ ## field ## _LBN
+	MC_CMD_GET_CAPABILITIES_V8_OUT_ ## field ## _LBN
 
 #define MCDI_CAPABILITY_OFST(field) \
-	MC_CMD_GET_CAPABILITIES_V4_OUT_ ## field ## _OFST
+	MC_CMD_GET_CAPABILITIES_V8_OUT_ ## field ## _OFST
 
 #define efx_has_cap(efx, field) \
 	efx->type->check_caps(efx, \


^ permalink raw reply related	[flat|nested] 25+ messages in thread

* [PATCH net-next 12/15] sfc_ef100: actually perform resets
  2020-07-03 15:28 [PATCH net-next 00/15] sfc_ef100: driver for EF100 family NICs, part 1 Edward Cree
                   ` (10 preceding siblings ...)
  2020-07-03 15:35 ` [PATCH net-next 11/15] sfc_ef100: extend ef100_check_caps to cover datapath_caps3 Edward Cree
@ 2020-07-03 15:35 ` Edward Cree
  2020-07-03 15:35 ` [PATCH net-next 13/15] sfc_ef100: probe the PHY and configure the MAC Edward Cree
                   ` (2 subsequent siblings)
  14 siblings, 0 replies; 25+ messages in thread
From: Edward Cree @ 2020-07-03 15:35 UTC (permalink / raw)
  To: linux-net-drivers, davem; +Cc: netdev

In ef100_reset(), make the MCDI call to do the reset.
Also, do a reset at start-of-day during probe, to put the function in
 a clean state.

Signed-off-by: Edward Cree <ecree@solarflare.com>
---
 drivers/net/ethernet/sfc/ef100_nic.c | 9 +++++++++
 1 file changed, 9 insertions(+)

diff --git a/drivers/net/ethernet/sfc/ef100_nic.c b/drivers/net/ethernet/sfc/ef100_nic.c
index fe7a5c4bc291..f449960e5b02 100644
--- a/drivers/net/ethernet/sfc/ef100_nic.c
+++ b/drivers/net/ethernet/sfc/ef100_nic.c
@@ -335,6 +335,10 @@ static int ef100_reset(struct efx_nic *efx, enum reset_type reset_type)
 		__clear_bit(reset_type, &efx->reset_pending);
 		rc = dev_open(efx->net_dev, NULL);
 	} else if (reset_type == RESET_TYPE_ALL) {
+		rc = efx_mcdi_reset(efx, reset_type);
+		if (rc)
+			return rc;
+
 		netif_device_attach(efx->net_dev);
 
 		rc = dev_open(efx->net_dev, NULL);
@@ -467,6 +471,11 @@ static int ef100_probe_main(struct efx_nic *efx)
 	}
 	if (rc)
 		goto fail;
+	/* Reset (most) configuration for this function */
+	rc = efx_mcdi_reset(efx, RESET_TYPE_ALL);
+	if (rc)
+		goto fail;
+
 	rc = efx_ef100_init_datapath_caps(efx);
 	if (rc < 0)
 		goto fail;


^ permalink raw reply related	[flat|nested] 25+ messages in thread

* [PATCH net-next 13/15] sfc_ef100: probe the PHY and configure the MAC
  2020-07-03 15:28 [PATCH net-next 00/15] sfc_ef100: driver for EF100 family NICs, part 1 Edward Cree
                   ` (11 preceding siblings ...)
  2020-07-03 15:35 ` [PATCH net-next 12/15] sfc_ef100: actually perform resets Edward Cree
@ 2020-07-03 15:35 ` Edward Cree
  2020-07-03 15:36 ` [PATCH net-next 14/15] sfc_ef100: read device MAC address at probe time Edward Cree
  2020-07-03 15:36 ` [PATCH net-next 15/15] sfc_ef100: implement ndo_get_phys_port_{id,name} Edward Cree
  14 siblings, 0 replies; 25+ messages in thread
From: Edward Cree @ 2020-07-03 15:35 UTC (permalink / raw)
  To: linux-net-drivers, davem; +Cc: netdev

Signed-off-by: Edward Cree <ecree@solarflare.com>
---
 drivers/net/ethernet/sfc/ef100_nic.c | 42 +++++++++++++++++++++++++++-
 1 file changed, 41 insertions(+), 1 deletion(-)

diff --git a/drivers/net/ethernet/sfc/ef100_nic.c b/drivers/net/ethernet/sfc/ef100_nic.c
index f449960e5b02..aced682a7b08 100644
--- a/drivers/net/ethernet/sfc/ef100_nic.c
+++ b/drivers/net/ethernet/sfc/ef100_nic.c
@@ -291,16 +291,54 @@ static irqreturn_t ef100_msi_interrupt(int irq, void *dev_id)
 
 static int ef100_phy_probe(struct efx_nic *efx)
 {
-	/* stub: allocate the phy_data */
+	struct efx_mcdi_phy_data *phy_data;
+	int rc;
+
+	/* Probe for the PHY */
 	efx->phy_data = kzalloc(sizeof(struct efx_mcdi_phy_data), GFP_KERNEL);
 	if (!efx->phy_data)
 		return -ENOMEM;
 
+	rc = efx_mcdi_get_phy_cfg(efx, efx->phy_data);
+	if (rc)
+		return rc;
+
+	/* Populate driver and ethtool settings */
+	phy_data = efx->phy_data;
+	mcdi_to_ethtool_linkset(phy_data->media, phy_data->supported_cap,
+				efx->link_advertising);
+	efx->fec_config = mcdi_fec_caps_to_ethtool(phy_data->supported_cap,
+						   false);
+
+	/* Default to Autonegotiated flow control if the PHY supports it */
+	efx->wanted_fc = EFX_FC_RX | EFX_FC_TX;
+	if (phy_data->supported_cap & (1 << MC_CMD_PHY_CAP_AN_LBN))
+		efx->wanted_fc |= EFX_FC_AUTO;
+	efx_link_set_wanted_fc(efx, efx->wanted_fc);
+
+	/* Push settings to the PHY. Failure is not fatal, the user can try to
+	 * fix it using ethtool.
+	 */
+	rc = efx_mcdi_port_reconfigure(efx);
+	if (rc && rc != -EPERM)
+		netif_warn(efx, drv, efx->net_dev,
+			   "could not initialise PHY settings\n");
+
 	return 0;
 }
 
 /*	Other
  */
+static int ef100_reconfigure_mac(struct efx_nic *efx, bool mtu_only)
+{
+	WARN_ON(!mutex_is_locked(&efx->mac_lock));
+
+	efx_mcdi_filter_sync_rx_mode(efx);
+
+	if (mtu_only && efx_has_cap(efx, SET_MAC_ENHANCED))
+		return efx_mcdi_set_mtu(efx);
+	return efx_mcdi_set_mac(efx);
+}
 
 static enum reset_type ef100_map_reset_reason(enum reset_type reason)
 {
@@ -402,6 +440,8 @@ const struct efx_nic_type ef100_pf_nic_type = {
 	.rx_remove = efx_mcdi_rx_remove,
 	.rx_write = ef100_rx_write,
 
+	.reconfigure_mac = ef100_reconfigure_mac,
+
 	/* Per-type bar/size configuration not used on ef100. Location of
 	 * registers is defined by extended capabilities.
 	 */


^ permalink raw reply related	[flat|nested] 25+ messages in thread

* [PATCH net-next 14/15] sfc_ef100: read device MAC address at probe time
  2020-07-03 15:28 [PATCH net-next 00/15] sfc_ef100: driver for EF100 family NICs, part 1 Edward Cree
                   ` (12 preceding siblings ...)
  2020-07-03 15:35 ` [PATCH net-next 13/15] sfc_ef100: probe the PHY and configure the MAC Edward Cree
@ 2020-07-03 15:36 ` Edward Cree
  2020-07-03 15:36 ` [PATCH net-next 15/15] sfc_ef100: implement ndo_get_phys_port_{id,name} Edward Cree
  14 siblings, 0 replies; 25+ messages in thread
From: Edward Cree @ 2020-07-03 15:36 UTC (permalink / raw)
  To: linux-net-drivers, davem; +Cc: netdev

Signed-off-by: Edward Cree <ecree@solarflare.com>
---
 drivers/net/ethernet/sfc/ef100_nic.c | 40 +++++++++++++++++++++++++++-
 drivers/net/ethernet/sfc/ef100_nic.h |  1 +
 2 files changed, 40 insertions(+), 1 deletion(-)

diff --git a/drivers/net/ethernet/sfc/ef100_nic.c b/drivers/net/ethernet/sfc/ef100_nic.c
index aced682a7b08..7c914b2f71c5 100644
--- a/drivers/net/ethernet/sfc/ef100_nic.c
+++ b/drivers/net/ethernet/sfc/ef100_nic.c
@@ -126,6 +126,26 @@ static void ef100_mcdi_reboot_detected(struct efx_nic *efx)
 
 /*	MCDI calls
  */
+static int ef100_get_mac_address(struct efx_nic *efx, u8 *mac_address)
+{
+	MCDI_DECLARE_BUF(outbuf, MC_CMD_GET_MAC_ADDRESSES_OUT_LEN);
+	size_t outlen;
+	int rc;
+
+	BUILD_BUG_ON(MC_CMD_GET_MAC_ADDRESSES_IN_LEN != 0);
+
+	rc = efx_mcdi_rpc(efx, MC_CMD_GET_MAC_ADDRESSES, NULL, 0,
+			  outbuf, sizeof(outbuf), &outlen);
+	if (rc)
+		return rc;
+	if (outlen < MC_CMD_GET_MAC_ADDRESSES_OUT_LEN)
+		return -EIO;
+
+	ether_addr_copy(mac_address,
+			MCDI_PTR(outbuf, GET_MAC_ADDRESSES_OUT_MAC_ADDR_BASE));
+	return 0;
+}
+
 static int efx_ef100_init_datapath_caps(struct efx_nic *efx)
 {
 	MCDI_DECLARE_BUF(outbuf, MC_CMD_GET_CAPABILITIES_V7_OUT_LEN);
@@ -541,7 +561,25 @@ static int ef100_probe_main(struct efx_nic *efx)
 
 int ef100_probe_pf(struct efx_nic *efx)
 {
-	return ef100_probe_main(efx);
+	struct net_device *net_dev = efx->net_dev;
+	struct ef100_nic_data *nic_data;
+	int rc = ef100_probe_main(efx);
+
+	if (rc)
+		goto fail;
+
+	nic_data = efx->nic_data;
+	rc = ef100_get_mac_address(efx, net_dev->perm_addr);
+	if (rc)
+		goto fail;
+	/* Assign MAC address */
+	memcpy(net_dev->dev_addr, net_dev->perm_addr, ETH_ALEN);
+	memcpy(nic_data->port_id, net_dev->perm_addr, ETH_ALEN);
+
+	return 0;
+
+fail:
+	return rc;
 }
 
 void ef100_remove(struct efx_nic *efx)
diff --git a/drivers/net/ethernet/sfc/ef100_nic.h b/drivers/net/ethernet/sfc/ef100_nic.h
index 7744ec85bec6..6367bbb2c9b3 100644
--- a/drivers/net/ethernet/sfc/ef100_nic.h
+++ b/drivers/net/ethernet/sfc/ef100_nic.h
@@ -24,6 +24,7 @@ struct ef100_nic_data {
 	u32 datapath_caps2;
 	u32 datapath_caps3;
 	u16 warm_boot_count;
+	u8 port_id[ETH_ALEN];
 	DECLARE_BITMAP(evq_phases, EFX_MAX_CHANNELS);
 };
 


^ permalink raw reply related	[flat|nested] 25+ messages in thread

* [PATCH net-next 15/15] sfc_ef100: implement ndo_get_phys_port_{id,name}
  2020-07-03 15:28 [PATCH net-next 00/15] sfc_ef100: driver for EF100 family NICs, part 1 Edward Cree
                   ` (13 preceding siblings ...)
  2020-07-03 15:36 ` [PATCH net-next 14/15] sfc_ef100: read device MAC address at probe time Edward Cree
@ 2020-07-03 15:36 ` Edward Cree
  14 siblings, 0 replies; 25+ messages in thread
From: Edward Cree @ 2020-07-03 15:36 UTC (permalink / raw)
  To: linux-net-drivers, davem; +Cc: netdev

Signed-off-by: Edward Cree <ecree@solarflare.com>
---
 drivers/net/ethernet/sfc/ef100_netdev.c |  2 ++
 drivers/net/ethernet/sfc/ef100_nic.c    | 21 +++++++++++++++++++++
 2 files changed, 23 insertions(+)

diff --git a/drivers/net/ethernet/sfc/ef100_netdev.c b/drivers/net/ethernet/sfc/ef100_netdev.c
index 3e4e7241d9a8..66e6c1159c0f 100644
--- a/drivers/net/ethernet/sfc/ef100_netdev.c
+++ b/drivers/net/ethernet/sfc/ef100_netdev.c
@@ -214,6 +214,8 @@ static const struct net_device_ops ef100_netdev_ops = {
 	.ndo_open               = ef100_net_open,
 	.ndo_stop               = ef100_net_stop,
 	.ndo_start_xmit         = ef100_hard_start_xmit,
+	.ndo_get_phys_port_id   = efx_get_phys_port_id,
+	.ndo_get_phys_port_name = efx_get_phys_port_name,
 };
 
 /*	Netdev registration
diff --git a/drivers/net/ethernet/sfc/ef100_nic.c b/drivers/net/ethernet/sfc/ef100_nic.c
index 7c914b2f71c5..de7c428c63bb 100644
--- a/drivers/net/ethernet/sfc/ef100_nic.c
+++ b/drivers/net/ethernet/sfc/ef100_nic.c
@@ -406,6 +406,20 @@ static int ef100_reset(struct efx_nic *efx, enum reset_type reset_type)
 	return rc;
 }
 
+static int efx_ef100_get_phys_port_id(struct efx_nic *efx,
+				      struct netdev_phys_item_id *ppid)
+{
+	struct ef100_nic_data *nic_data = efx->nic_data;
+
+	if (!is_valid_ether_addr(nic_data->port_id))
+		return -EOPNOTSUPP;
+
+	ppid->id_len = ETH_ALEN;
+	memcpy(ppid->id, nic_data->port_id, ppid->id_len);
+
+	return 0;
+}
+
 static unsigned int ef100_check_caps(const struct efx_nic *efx,
 				     u8 flag, u32 offset)
 {
@@ -460,6 +474,8 @@ const struct efx_nic_type ef100_pf_nic_type = {
 	.rx_remove = efx_mcdi_rx_remove,
 	.rx_write = ef100_rx_write,
 
+	.get_phys_port_id = efx_ef100_get_phys_port_id,
+
 	.reconfigure_mac = ef100_reconfigure_mac,
 
 	/* Per-type bar/size configuration not used on ef100. Location of
@@ -542,6 +558,11 @@ static int ef100_probe_main(struct efx_nic *efx)
 
 	efx->max_vis = EF100_MAX_VIS;
 
+	rc = efx_mcdi_port_get_number(efx);
+	if (rc < 0)
+		goto fail;
+	efx->port_num = rc;
+
 	rc = ef100_phy_probe(efx);
 	if (rc)
 		goto fail;

^ permalink raw reply related	[flat|nested] 25+ messages in thread

* Re: [PATCH net-next 03/15] sfc_ef100: skeleton EF100 PF driver
  2020-07-03 15:31 ` [PATCH net-next 03/15] sfc_ef100: skeleton EF100 PF driver Edward Cree
@ 2020-07-03 17:43   ` Jakub Kicinski
  2020-07-03 17:46   ` kernel test robot
                     ` (3 subsequent siblings)
  4 siblings, 0 replies; 25+ messages in thread
From: Jakub Kicinski @ 2020-07-03 17:43 UTC (permalink / raw)
  To: Edward Cree; +Cc: linux-net-drivers, davem, netdev

On Fri, 3 Jul 2020 16:31:33 +0100 Edward Cree wrote:
> No TX or RX path, no MCDI, not even an ifup/down handler.
> Besides stubs, the bulk of the patch deals with reading the Xilinx
>  extended PCIe capability, which tells us where to find our BAR.
> 
> Signed-off-by: Edward Cree <ecree@solarflare.com>

Warnings:

drivers/net/ethernet/sfc/ef100_netdev.c:31:6: warning: symbol 'efx_separate_tx_channels' was not declared. Should it be static?
drivers/net/ethernet/sfc/ef100_netdev.c:45:13: warning: symbol 'ef100_hard_start_xmit' was not declared. Should it be static?
28a27,41
drivers/net/ethernet/sfc/ef100_rx.c:15:6: warning: symbol '__efx_rx_packet' was not declared. Should it be static?
drivers/net/ethernet/sfc/ef100_tx.c:16:5: warning: symbol 'efx_enqueue_skb_tso' was not declared. Should it be static?
drivers/net/ethernet/sfc/ef100_netdev.c:45:13: warning: no previous prototype for ‘ef100_hard_start_xmit’ [-Wmissing-prototypes]
   45 | netdev_tx_t ef100_hard_start_xmit(struct sk_buff *skb,
      |             ^~~~~~~~~~~~~~~~~~~~~
drivers/net/ethernet/sfc/ef100_rx.c:15:6: warning: no previous prototype for ‘__efx_rx_packet’ [-Wmissing-prototypes]
   15 | void __efx_rx_packet(struct efx_channel *channel)
      |      ^~~~~~~~~~~~~~~
drivers/net/ethernet/sfc/ef100_tx.c:16:5: warning: no previous prototype for ‘efx_enqueue_skb_tso’ [-Wmissing-prototypes]
   16 | int efx_enqueue_skb_tso(struct efx_tx_queue *tx_queue, struct sk_buff *skb,
      |     ^~~~~~~~~~~~~~~~~~~

^ permalink raw reply	[flat|nested] 25+ messages in thread

* Re: [PATCH net-next 03/15] sfc_ef100: skeleton EF100 PF driver
  2020-07-03 15:31 ` [PATCH net-next 03/15] sfc_ef100: skeleton EF100 PF driver Edward Cree
  2020-07-03 17:43   ` Jakub Kicinski
@ 2020-07-03 17:46   ` kernel test robot
  2020-07-08 19:16     ` Edward Cree
  2020-07-03 17:46   ` [RFC PATCH] sfc_ef100: ef100_hard_start_xmit() can be static kernel test robot
                     ` (2 subsequent siblings)
  4 siblings, 1 reply; 25+ messages in thread
From: kernel test robot @ 2020-07-03 17:46 UTC (permalink / raw)
  To: Edward Cree, linux-net-drivers, davem; +Cc: kbuild-all, netdev

[-- Attachment #1: Type: text/plain, Size: 10187 bytes --]

Hi Edward,

I love your patch! Perhaps something to improve:

[auto build test WARNING on net-next/master]

url:    https://github.com/0day-ci/linux/commits/Edward-Cree/sfc_ef100-driver-for-EF100-family-NICs-part-1/20200703-233750
base:   https://git.kernel.org/pub/scm/linux/kernel/git/davem/net-next.git 8c8278a5b1a81e099ba883d8a0f9e3df9bdb1a74
config: i386-randconfig-s002-20200702 (attached as .config)
compiler: gcc-9 (Debian 9.3.0-14) 9.3.0
reproduce:
        # apt-get install sparse
        # sparse version: v0.6.2-3-gfa153962-dirty
        # save the attached .config to linux build tree
        make W=1 C=1 CF='-fdiagnostic-prefix -D__CHECK_ENDIAN__' ARCH=i386 

If you fix the issue, kindly add following tag as appropriate
Reported-by: kernel test robot <lkp@intel.com>

All warnings (new ones prefixed by >>):

   In file included from include/linux/skbuff.h:31,
                    from include/linux/if_ether.h:19,
                    from include/uapi/linux/ethtool.h:19,
                    from include/linux/ethtool.h:18,
                    from include/linux/netdevice.h:37,
                    from drivers/net/ethernet/sfc/net_driver.h:13,
                    from drivers/net/ethernet/sfc/ef100.c:12:
   drivers/net/ethernet/sfc/ef100.c: In function 'ef100_pci_parse_continue_entry':
>> include/linux/dma-mapping.h:139:25: warning: conversion from 'long long unsigned int' to 'dma_addr_t' {aka 'unsigned int'} changes value from '18446744073709551615' to '4294967295' [-Woverflow]
     139 | #define DMA_BIT_MASK(n) (((n) == 64) ? ~0ULL : ((1ULL<<(n))-1))
         |                         ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
>> drivers/net/ethernet/sfc/ef100.c:144:6: note: in expansion of macro 'DMA_BIT_MASK'
     144 |      DMA_BIT_MASK(ESF_GZ_TX_SEND_ADDR_WIDTH),
         |      ^~~~~~~~~~~~
>> include/linux/dma-mapping.h:139:25: warning: conversion from 'long long unsigned int' to 'dma_addr_t' {aka 'unsigned int'} changes value from '18446744073709551615' to '4294967295' [-Woverflow]
     139 | #define DMA_BIT_MASK(n) (((n) == 64) ? ~0ULL : ((1ULL<<(n))-1))
         |                         ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
   drivers/net/ethernet/sfc/ef100.c:162:6: note: in expansion of macro 'DMA_BIT_MASK'
     162 |      DMA_BIT_MASK(ESF_GZ_TX_SEND_ADDR_WIDTH),
         |      ^~~~~~~~~~~~
   drivers/net/ethernet/sfc/ef100.c: In function 'ef100_pci_parse_xilinx_cap':
>> include/linux/dma-mapping.h:139:25: warning: conversion from 'long long unsigned int' to 'dma_addr_t' {aka 'unsigned int'} changes value from '18446744073709551615' to '4294967295' [-Woverflow]
     139 | #define DMA_BIT_MASK(n) (((n) == 64) ? ~0ULL : ((1ULL<<(n))-1))
         |                         ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
   drivers/net/ethernet/sfc/ef100.c:339:5: note: in expansion of macro 'DMA_BIT_MASK'
     339 |     DMA_BIT_MASK(ESF_GZ_TX_SEND_ADDR_WIDTH),
         |     ^~~~~~~~~~~~
   drivers/net/ethernet/sfc/ef100.c: In function 'ef100_pci_probe':
>> include/linux/dma-mapping.h:139:25: warning: conversion from 'long long unsigned int' to 'dma_addr_t' {aka 'unsigned int'} changes value from '18446744073709551615' to '4294967295' [-Woverflow]
     139 | #define DMA_BIT_MASK(n) (((n) == 64) ? ~0ULL : ((1ULL<<(n))-1))
         |                         ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
   drivers/net/ethernet/sfc/ef100.c:503:5: note: in expansion of macro 'DMA_BIT_MASK'
     503 |     DMA_BIT_MASK(ESF_GZ_TX_SEND_ADDR_WIDTH),
         |     ^~~~~~~~~~~~
--
>> drivers/net/ethernet/sfc/ef100_netdev.c:45:13: warning: no previous prototype for 'ef100_hard_start_xmit' [-Wmissing-prototypes]
      45 | netdev_tx_t ef100_hard_start_xmit(struct sk_buff *skb,
         |             ^~~~~~~~~~~~~~~~~~~~~
--
>> drivers/net/ethernet/sfc/ef100_rx.c:15:6: warning: no previous prototype for '__efx_rx_packet' [-Wmissing-prototypes]
      15 | void __efx_rx_packet(struct efx_channel *channel)
         |      ^~~~~~~~~~~~~~~
--
>> drivers/net/ethernet/sfc/ef100_tx.c:16:5: warning: no previous prototype for 'efx_enqueue_skb_tso' [-Wmissing-prototypes]
      16 | int efx_enqueue_skb_tso(struct efx_tx_queue *tx_queue, struct sk_buff *skb,
         |     ^~~~~~~~~~~~~~~~~~~

sparse warnings: (new ones prefixed by >>)

>> drivers/net/ethernet/sfc/ef100_netdev.c:45:13: sparse: sparse: symbol 'ef100_hard_start_xmit' was not declared. Should it be static?

Please review and possibly fold the followup patch.

vim +/DMA_BIT_MASK +144 drivers/net/ethernet/sfc/ef100.c

  > 12	#include "net_driver.h"
    13	#include <linux/module.h>
    14	#include <linux/aer.h>
    15	#include "efx_common.h"
    16	#include "efx_channels.h"
    17	#include "io.h"
    18	#include "ef100_nic.h"
    19	#include "ef100_netdev.h"
    20	#include "ef100_regs.h"
    21	
    22	#define EFX_EF100_PCI_DEFAULT_BAR	2
    23	
    24	/* Number of bytes at start of vendor specified extended capability that indicate
    25	 * that the capability is vendor specified. i.e. offset from value returned by
    26	 * pci_find_next_ext_capability() to beginning of vendor specified capability
    27	 * header.
    28	 */
    29	#define PCI_EXT_CAP_HDR_LENGTH  4
    30	
    31	/* Expected size of a Xilinx continuation address table entry. */
    32	#define ESE_GZ_CFGBAR_CONT_CAP_MIN_LENGTH      16
    33	
    34	struct ef100_func_ctl_window {
    35		bool valid;
    36		unsigned int bar;
    37		u64 offset;
    38	};
    39	
    40	static int ef100_pci_walk_xilinx_table(struct efx_nic *efx, u64 offset,
    41					       struct ef100_func_ctl_window *result);
    42	
    43	/* Number of bytes to offset when reading bit position x with dword accessors. */
    44	#define ROUND_DOWN_TO_DWORD(x) (((x) & (~31)) >> 3)
    45	
    46	#define EXTRACT_BITS(x, lbn, width) \
    47		((x) >> ((lbn) & 31)) & ((1ull << (width)) - 1)
    48	
    49	static u32 _ef100_pci_get_bar_bits_with_width(struct efx_nic *efx,
    50						      int structure_start,
    51						      int lbn, int width)
    52	{
    53		efx_dword_t dword;
    54	
    55		efx_readd(efx, &dword, structure_start + ROUND_DOWN_TO_DWORD(lbn));
    56	
    57		return EXTRACT_BITS(le32_to_cpu(dword.u32[0]), lbn, width);
    58	}
    59	
    60	#define ef100_pci_get_bar_bits(efx, entry_location, bitdef) \
    61		_ef100_pci_get_bar_bits_with_width(efx, entry_location, \
    62			bitdef ## _LBN, bitdef ## _WIDTH)
    63	
    64	static int ef100_pci_parse_ef100_entry(struct efx_nic *efx, int entry_location,
    65					       struct ef100_func_ctl_window *result)
    66	{
    67		u32 bar = ef100_pci_get_bar_bits(efx, entry_location,
    68						 ESF_GZ_CFGBAR_EF100_BAR);
    69		u64 offset = ef100_pci_get_bar_bits(efx, entry_location,
    70						    ESF_GZ_CFGBAR_EF100_FUNC_CTL_WIN_OFF) << ESE_GZ_EF100_FUNC_CTL_WIN_OFF_SHIFT;
    71	
    72		netif_dbg(efx, probe, efx->net_dev,
    73			  "Found EF100 function control window bar=%d offset=0x%llx\n",
    74			  bar, offset);
    75	
    76		if (result->valid) {
    77			netif_err(efx, probe, efx->net_dev,
    78				  "Duplicated EF100 table entry.\n");
    79			return -EINVAL;
    80		}
    81	
    82		if ((bar == ESE_GZ_CFGBAR_EF100_BAR_NUM_EXPANSION_ROM) ||
    83		    (bar == ESE_GZ_CFGBAR_EF100_BAR_NUM_INVALID)) {
    84			netif_err(efx, probe, efx->net_dev,
    85				  "Bad BAR value of %d in Xilinx capabilities EF100 entry.\n",
    86				  bar);
    87			return -EINVAL;
    88		}
    89	
    90		result->bar = bar;
    91		result->offset = offset;
    92		result->valid = true;
    93		return 0;
    94	}
    95	
    96	static bool ef100_pci_does_bar_overflow(struct efx_nic *efx, int bar,
    97						u64 next_entry)
    98	{
    99		return next_entry + ESE_GZ_CFGBAR_ENTRY_HEADER_SIZE >
   100			pci_resource_len(efx->pci_dev, bar);
   101	}
   102	
   103	/* Parse a Xilinx capabilities table entry describing a continuation to a new
   104	 * sub-table.
   105	 */
   106	static int ef100_pci_parse_continue_entry(struct efx_nic *efx, int entry_location,
   107						  struct ef100_func_ctl_window *result)
   108	{
   109		unsigned int previous_bar;
   110		efx_oword_t entry;
   111		u64 offset;
   112		int rc = 0;
   113		u32 bar;
   114	
   115		efx_reado(efx, &entry, entry_location);
   116	
   117		bar = EFX_OWORD_FIELD32(entry, ESF_GZ_CFGBAR_CONT_CAP_BAR);
   118	
   119		offset = EFX_OWORD_FIELD64(entry, ESF_GZ_CFGBAR_CONT_CAP_OFFSET) <<
   120			ESE_GZ_CONT_CAP_OFFSET_BYTES_SHIFT;
   121	
   122		previous_bar = efx->mem_bar;
   123	
   124		if ((bar == ESE_GZ_VSEC_BAR_NUM_EXPANSION_ROM) ||
   125		    (bar == ESE_GZ_VSEC_BAR_NUM_INVALID)) {
   126			netif_err(efx, probe, efx->net_dev,
   127				  "Bad BAR value of %d in Xilinx capabilities sub-table.\n",
   128				  bar);
   129			return -EINVAL;
   130		}
   131	
   132		if (bar != previous_bar) {
   133			efx_fini_io(efx);
   134	
   135			if (ef100_pci_does_bar_overflow(efx, bar, offset)) {
   136				netif_err(efx, probe, efx->net_dev,
   137					  "Xilinx table will overrun BAR[%d] offset=0x%llx\n",
   138					  bar, offset);
   139				return -EINVAL;
   140			}
   141	
   142			/* Temporarily map new BAR. */
   143			rc = efx_init_io(efx, bar,
 > 144					 DMA_BIT_MASK(ESF_GZ_TX_SEND_ADDR_WIDTH),
   145					 pci_resource_len(efx->pci_dev, bar));
   146			if (rc) {
   147				netif_err(efx, probe, efx->net_dev,
   148					  "Mapping new BAR for Xilinx table failed, rc=%d\n", rc);
   149				return rc;
   150			}
   151		}
   152	
   153		rc = ef100_pci_walk_xilinx_table(efx, offset, result);
   154		if (rc)
   155			return rc;
   156	
   157		if (bar != previous_bar) {
   158			efx_fini_io(efx);
   159	
   160			/* Put old BAR back. */
   161			rc = efx_init_io(efx, previous_bar,
   162					 DMA_BIT_MASK(ESF_GZ_TX_SEND_ADDR_WIDTH),
   163					 pci_resource_len(efx->pci_dev, previous_bar));
   164			if (rc) {
   165				netif_err(efx, probe, efx->net_dev,
   166					  "Putting old BAR back failed, rc=%d\n", rc);
   167				return rc;
   168			}
   169		}
   170	
   171		return 0;
   172	}
   173	

---
0-DAY CI Kernel Test Service, Intel Corporation
https://lists.01.org/hyperkitty/list/kbuild-all@lists.01.org

[-- Attachment #2: .config.gz --]
[-- Type: application/gzip, Size: 34942 bytes --]

^ permalink raw reply	[flat|nested] 25+ messages in thread

* [RFC PATCH] sfc_ef100: ef100_hard_start_xmit() can be static
  2020-07-03 15:31 ` [PATCH net-next 03/15] sfc_ef100: skeleton EF100 PF driver Edward Cree
  2020-07-03 17:43   ` Jakub Kicinski
  2020-07-03 17:46   ` kernel test robot
@ 2020-07-03 17:46   ` kernel test robot
  2020-07-03 19:41   ` [PATCH net-next 03/15] sfc_ef100: skeleton EF100 PF driver kernel test robot
  2020-07-04  4:16   ` kernel test robot
  4 siblings, 0 replies; 25+ messages in thread
From: kernel test robot @ 2020-07-03 17:46 UTC (permalink / raw)
  To: Edward Cree, linux-net-drivers, davem; +Cc: kbuild-all, netdev


Signed-off-by: kernel test robot <lkp@intel.com>
---
 ef100_netdev.c |    4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/net/ethernet/sfc/ef100_netdev.c b/drivers/net/ethernet/sfc/ef100_netdev.c
index 356938104cb27..8e23ffed3f0ec 100644
--- a/drivers/net/ethernet/sfc/ef100_netdev.c
+++ b/drivers/net/ethernet/sfc/ef100_netdev.c
@@ -42,8 +42,8 @@ static void ef100_update_name(struct efx_nic *efx)
  * Note that returning anything other than NETDEV_TX_OK will cause the
  * OS to free the skb.
  */
-netdev_tx_t ef100_hard_start_xmit(struct sk_buff *skb,
-				  struct net_device *net_dev)
+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_tx_queue *tx_queue;

^ permalink raw reply related	[flat|nested] 25+ messages in thread

* Re: [PATCH net-next 03/15] sfc_ef100: skeleton EF100 PF driver
  2020-07-03 15:31 ` [PATCH net-next 03/15] sfc_ef100: skeleton EF100 PF driver Edward Cree
                     ` (2 preceding siblings ...)
  2020-07-03 17:46   ` [RFC PATCH] sfc_ef100: ef100_hard_start_xmit() can be static kernel test robot
@ 2020-07-03 19:41   ` kernel test robot
  2020-07-04  4:16   ` kernel test robot
  4 siblings, 0 replies; 25+ messages in thread
From: kernel test robot @ 2020-07-03 19:41 UTC (permalink / raw)
  To: Edward Cree, linux-net-drivers, davem; +Cc: kbuild-all, netdev

[-- Attachment #1: Type: text/plain, Size: 1135 bytes --]

Hi Edward,

I love your patch! Yet something to improve:

[auto build test ERROR on net-next/master]

url:    https://github.com/0day-ci/linux/commits/Edward-Cree/sfc_ef100-driver-for-EF100-family-NICs-part-1/20200703-233750
base:   https://git.kernel.org/pub/scm/linux/kernel/git/davem/net-next.git 8c8278a5b1a81e099ba883d8a0f9e3df9bdb1a74
config: parisc-generic-64bit_defconfig (attached as .config)
compiler: hppa64-linux-gcc (GCC) 9.3.0
reproduce (this is a W=1 build):
        wget https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross
        chmod +x ~/bin/make.cross
        # save the attached .config to linux build tree
        COMPILER_INSTALL_PATH=$HOME/0day COMPILER=gcc-9.3.0 make.cross ARCH=parisc 

If you fix the issue, kindly add following tag as appropriate
Reported-by: kernel test robot <lkp@intel.com>

All errors (new ones prefixed by >>, old ones prefixed by <<):

>> ERROR: modpost: "mdio45_nway_restart" [drivers/net/ethernet/sfc/sfc_ef100.ko] undefined!

---
0-DAY CI Kernel Test Service, Intel Corporation
https://lists.01.org/hyperkitty/list/kbuild-all@lists.01.org

[-- Attachment #2: .config.gz --]
[-- Type: application/gzip, Size: 20280 bytes --]

^ permalink raw reply	[flat|nested] 25+ messages in thread

* Re: [PATCH net-next 06/15] sfc_ef100: don't call efx_reset_down()/up() on EF100
  2020-07-03 15:32 ` [PATCH net-next 06/15] sfc_ef100: don't call efx_reset_down()/up() on EF100 Edward Cree
@ 2020-07-04  2:15   ` kernel test robot
  0 siblings, 0 replies; 25+ messages in thread
From: kernel test robot @ 2020-07-04  2:15 UTC (permalink / raw)
  To: Edward Cree, linux-net-drivers, davem
  Cc: kbuild-all, clang-built-linux, netdev

[-- Attachment #1: Type: text/plain, Size: 4367 bytes --]

Hi Edward,

I love your patch! Perhaps something to improve:

[auto build test WARNING on net-next/master]

url:    https://github.com/0day-ci/linux/commits/Edward-Cree/sfc_ef100-driver-for-EF100-family-NICs-part-1/20200703-233750
base:   https://git.kernel.org/pub/scm/linux/kernel/git/davem/net-next.git 8c8278a5b1a81e099ba883d8a0f9e3df9bdb1a74
config: x86_64-allyesconfig (attached as .config)
compiler: clang version 11.0.0 (https://github.com/llvm/llvm-project ca464639a1c9dd3944eb055ffd2796e8c2e7639f)
reproduce (this is a W=1 build):
        wget https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross
        chmod +x ~/bin/make.cross
        # install x86_64 cross compiling tool for clang build
        # apt-get install binutils-x86-64-linux-gnu
        # save the attached .config to linux build tree
        COMPILER_INSTALL_PATH=$HOME/0day COMPILER=clang make.cross ARCH=x86_64 

If you fix the issue, kindly add following tag as appropriate
Reported-by: kernel test robot <lkp@intel.com>

All warnings (new ones prefixed by >>):

>> drivers/net/ethernet/sfc/efx_common.c:856:6: warning: variable 'rc2' is used uninitialized whenever 'if' condition is false [-Wsometimes-uninitialized]
           if (efx_nic_rev(efx) != EFX_REV_EF100)
               ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
   drivers/net/ethernet/sfc/efx_common.c:858:6: note: uninitialized use occurs here
           if (rc2) {
               ^~~
   drivers/net/ethernet/sfc/efx_common.c:856:2: note: remove the 'if' if its condition is always true
           if (efx_nic_rev(efx) != EFX_REV_EF100)
           ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
   drivers/net/ethernet/sfc/efx_common.c:818:13: note: initialize the variable 'rc2' to silence this warning
           int rc, rc2;
                      ^
                       = 0
   1 warning generated.

vim +856 drivers/net/ethernet/sfc/efx_common.c

   809	
   810	/* Reset the NIC using the specified method.  Note that the reset may
   811	 * fail, in which case the card will be left in an unusable state.
   812	 *
   813	 * Caller must hold the rtnl_lock.
   814	 */
   815	int efx_reset(struct efx_nic *efx, enum reset_type method)
   816	{
   817		bool disabled;
   818		int rc, rc2;
   819	
   820		netif_info(efx, drv, efx->net_dev, "resetting (%s)\n",
   821			   RESET_TYPE(method));
   822	
   823		efx_device_detach_sync(efx);
   824		/* efx_reset_down() grabs locks that prevent recovery on EF100.
   825		 * EF100 reset is handled in the efx_nic_type callback below.
   826		 */
   827		if (efx_nic_rev(efx) != EFX_REV_EF100)
   828			efx_reset_down(efx, method);
   829	
   830		rc = efx->type->reset(efx, method);
   831		if (rc) {
   832			netif_err(efx, drv, efx->net_dev, "failed to reset hardware\n");
   833			goto out;
   834		}
   835	
   836		/* Clear flags for the scopes we covered.  We assume the NIC and
   837		 * driver are now quiescent so that there is no race here.
   838		 */
   839		if (method < RESET_TYPE_MAX_METHOD)
   840			efx->reset_pending &= -(1 << (method + 1));
   841		else /* it doesn't fit into the well-ordered scope hierarchy */
   842			__clear_bit(method, &efx->reset_pending);
   843	
   844		/* Reinitialise bus-mastering, which may have been turned off before
   845		 * the reset was scheduled. This is still appropriate, even in the
   846		 * RESET_TYPE_DISABLE since this driver generally assumes the hardware
   847		 * can respond to requests.
   848		 */
   849		pci_set_master(efx->pci_dev);
   850	
   851	out:
   852		/* Leave device stopped if necessary */
   853		disabled = rc ||
   854			method == RESET_TYPE_DISABLE ||
   855			method == RESET_TYPE_RECOVER_OR_DISABLE;
 > 856		if (efx_nic_rev(efx) != EFX_REV_EF100)
   857			rc2 = efx_reset_up(efx, method, !disabled);
   858		if (rc2) {
   859			disabled = true;
   860			if (!rc)
   861				rc = rc2;
   862		}
   863	
   864		if (disabled) {
   865			dev_close(efx->net_dev);
   866			netif_err(efx, drv, efx->net_dev, "has been disabled\n");
   867			efx->state = STATE_DISABLED;
   868		} else {
   869			netif_dbg(efx, drv, efx->net_dev, "reset complete\n");
   870			efx_device_attach_if_not_resetting(efx);
   871		}
   872		return rc;
   873	}
   874	

---
0-DAY CI Kernel Test Service, Intel Corporation
https://lists.01.org/hyperkitty/list/kbuild-all@lists.01.org

[-- Attachment #2: .config.gz --]
[-- Type: application/gzip, Size: 75323 bytes --]

^ permalink raw reply	[flat|nested] 25+ messages in thread

* Re: [PATCH net-next 03/15] sfc_ef100: skeleton EF100 PF driver
  2020-07-03 15:31 ` [PATCH net-next 03/15] sfc_ef100: skeleton EF100 PF driver Edward Cree
                     ` (3 preceding siblings ...)
  2020-07-03 19:41   ` [PATCH net-next 03/15] sfc_ef100: skeleton EF100 PF driver kernel test robot
@ 2020-07-04  4:16   ` kernel test robot
  2020-07-07 18:34     ` Edward Cree
  4 siblings, 1 reply; 25+ messages in thread
From: kernel test robot @ 2020-07-04  4:16 UTC (permalink / raw)
  To: Edward Cree, linux-net-drivers, davem; +Cc: kbuild-all, netdev

[-- Attachment #1: Type: text/plain, Size: 7775 bytes --]

Hi Edward,

I love your patch! Perhaps something to improve:

[auto build test WARNING on net-next/master]

url:    https://github.com/0day-ci/linux/commits/Edward-Cree/sfc_ef100-driver-for-EF100-family-NICs-part-1/20200703-233750
base:   https://git.kernel.org/pub/scm/linux/kernel/git/davem/net-next.git 8c8278a5b1a81e099ba883d8a0f9e3df9bdb1a74
config: m68k-randconfig-c003-20200701 (attached as .config)
compiler: m68k-linux-gcc (GCC) 9.3.0

If you fix the issue, kindly add following tag as appropriate
Reported-by: kernel test robot <lkp@intel.com>


coccinelle warnings: (new ones prefixed by >>)

>> drivers/net/ethernet/sfc/ptp.c:1442:1-4: alloc with no test, possible model on line 1457

vim +1442 drivers/net/ethernet/sfc/ptp.c

5d0dab01175bff0 Ben Hutchings   2013-10-16  1434  
ac36baf817c39fc Ben Hutchings   2013-10-15  1435  /* Initialise PTP state. */
ac36baf817c39fc Ben Hutchings   2013-10-15  1436  int efx_ptp_probe(struct efx_nic *efx, struct efx_channel *channel)
7c236c43b838221 Stuart Hodgson  2012-09-03  1437  {
7c236c43b838221 Stuart Hodgson  2012-09-03  1438  	struct efx_ptp_data *ptp;
7c236c43b838221 Stuart Hodgson  2012-09-03  1439  	int rc = 0;
7c236c43b838221 Stuart Hodgson  2012-09-03  1440  	unsigned int pos;
7c236c43b838221 Stuart Hodgson  2012-09-03  1441  
7c236c43b838221 Stuart Hodgson  2012-09-03 @1442  	ptp = kzalloc(sizeof(struct efx_ptp_data), GFP_KERNEL);
7c236c43b838221 Stuart Hodgson  2012-09-03  1443  	efx->ptp_data = ptp;
7c236c43b838221 Stuart Hodgson  2012-09-03  1444  	if (!efx->ptp_data)
7c236c43b838221 Stuart Hodgson  2012-09-03  1445  		return -ENOMEM;
7c236c43b838221 Stuart Hodgson  2012-09-03  1446  
ac36baf817c39fc Ben Hutchings   2013-10-15  1447  	ptp->efx = efx;
ac36baf817c39fc Ben Hutchings   2013-10-15  1448  	ptp->channel = channel;
bd9a265db26cdbf Jon Cooper      2013-11-18  1449  	ptp->rx_ts_inline = efx_nic_rev(efx) >= EFX_REV_HUNT_A0;
ac36baf817c39fc Ben Hutchings   2013-10-15  1450  
0d19a540beb7849 Ben Hutchings   2012-09-18  1451  	rc = efx_nic_alloc_buffer(efx, &ptp->start, sizeof(int), GFP_KERNEL);
7c236c43b838221 Stuart Hodgson  2012-09-03  1452  	if (rc != 0)
7c236c43b838221 Stuart Hodgson  2012-09-03  1453  		goto fail1;
7c236c43b838221 Stuart Hodgson  2012-09-03  1454  
7c236c43b838221 Stuart Hodgson  2012-09-03  1455  	skb_queue_head_init(&ptp->rxq);
7c236c43b838221 Stuart Hodgson  2012-09-03  1456  	skb_queue_head_init(&ptp->txq);
7c236c43b838221 Stuart Hodgson  2012-09-03 @1457  	ptp->workwq = create_singlethread_workqueue("sfc_ptp");
7c236c43b838221 Stuart Hodgson  2012-09-03  1458  	if (!ptp->workwq) {
7c236c43b838221 Stuart Hodgson  2012-09-03  1459  		rc = -ENOMEM;
7c236c43b838221 Stuart Hodgson  2012-09-03  1460  		goto fail2;
7c236c43b838221 Stuart Hodgson  2012-09-03  1461  	}
7c236c43b838221 Stuart Hodgson  2012-09-03  1462  
2935e3c38228ad9 Edward Cree     2018-01-25  1463  	if (efx_ptp_use_mac_tx_timestamps(efx)) {
23418dc131464ff Martin Habets   2018-01-25  1464  		ptp->xmit_skb = efx_ptp_xmit_skb_queue;
2935e3c38228ad9 Edward Cree     2018-01-25  1465  		/* Request sync events on this channel. */
2935e3c38228ad9 Edward Cree     2018-01-25  1466  		channel->sync_events_state = SYNC_EVENTS_QUIESCENT;
2935e3c38228ad9 Edward Cree     2018-01-25  1467  	} else {
23418dc131464ff Martin Habets   2018-01-25  1468  		ptp->xmit_skb = efx_ptp_xmit_skb_mc;
2935e3c38228ad9 Edward Cree     2018-01-25  1469  	}
23418dc131464ff Martin Habets   2018-01-25  1470  
7c236c43b838221 Stuart Hodgson  2012-09-03  1471  	INIT_WORK(&ptp->work, efx_ptp_worker);
7c236c43b838221 Stuart Hodgson  2012-09-03  1472  	ptp->config.flags = 0;
7c236c43b838221 Stuart Hodgson  2012-09-03  1473  	ptp->config.tx_type = HWTSTAMP_TX_OFF;
7c236c43b838221 Stuart Hodgson  2012-09-03  1474  	ptp->config.rx_filter = HWTSTAMP_FILTER_NONE;
7c236c43b838221 Stuart Hodgson  2012-09-03  1475  	INIT_LIST_HEAD(&ptp->evt_list);
7c236c43b838221 Stuart Hodgson  2012-09-03  1476  	INIT_LIST_HEAD(&ptp->evt_free_list);
7c236c43b838221 Stuart Hodgson  2012-09-03  1477  	spin_lock_init(&ptp->evt_lock);
7c236c43b838221 Stuart Hodgson  2012-09-03  1478  	for (pos = 0; pos < MAX_RECEIVE_EVENTS; pos++)
7c236c43b838221 Stuart Hodgson  2012-09-03  1479  		list_add(&ptp->rx_evts[pos].link, &ptp->evt_free_list);
7c236c43b838221 Stuart Hodgson  2012-09-03  1480  
a6f73460b592404 Laurence Evans  2013-12-04  1481  	/* Get the NIC PTP attributes and set up time conversions */
a6f73460b592404 Laurence Evans  2013-12-04  1482  	rc = efx_ptp_get_attributes(efx);
a6f73460b592404 Laurence Evans  2013-12-04  1483  	if (rc < 0)
a6f73460b592404 Laurence Evans  2013-12-04  1484  		goto fail3;
a6f73460b592404 Laurence Evans  2013-12-04  1485  
a6f73460b592404 Laurence Evans  2013-12-04  1486  	/* Get the timestamp corrections */
a6f73460b592404 Laurence Evans  2013-12-04  1487  	rc = efx_ptp_get_timestamp_corrections(efx);
a6f73460b592404 Laurence Evans  2013-12-04  1488  	if (rc < 0)
a6f73460b592404 Laurence Evans  2013-12-04  1489  		goto fail3;
a6f73460b592404 Laurence Evans  2013-12-04  1490  
9aecda95d0a2865 Ben Hutchings   2013-12-05  1491  	if (efx->mcdi->fn_flags &
9aecda95d0a2865 Ben Hutchings   2013-12-05  1492  	    (1 << MC_CMD_DRV_ATTACH_EXT_OUT_FLAG_PRIMARY)) {
5d0dab01175bff0 Ben Hutchings   2013-10-16  1493  		ptp->phc_clock_info = efx_phc_clock_info;
1ef761582c07444 Richard Cochran 2012-09-22  1494  		ptp->phc_clock = ptp_clock_register(&ptp->phc_clock_info,
1ef761582c07444 Richard Cochran 2012-09-22  1495  						    &efx->pci_dev->dev);
155d940a78fd076 Wei Yongjun     2013-05-07  1496  		if (IS_ERR(ptp->phc_clock)) {
155d940a78fd076 Wei Yongjun     2013-05-07  1497  			rc = PTR_ERR(ptp->phc_clock);
7c236c43b838221 Stuart Hodgson  2012-09-03  1498  			goto fail3;
efee95f42b5ddde Nicolas Pitre   2016-09-20  1499  		} else if (ptp->phc_clock) {
7c236c43b838221 Stuart Hodgson  2012-09-03  1500  			INIT_WORK(&ptp->pps_work, efx_ptp_pps_worker);
7c236c43b838221 Stuart Hodgson  2012-09-03  1501  			ptp->pps_workwq = create_singlethread_workqueue("sfc_pps");
7c236c43b838221 Stuart Hodgson  2012-09-03  1502  			if (!ptp->pps_workwq) {
7c236c43b838221 Stuart Hodgson  2012-09-03  1503  				rc = -ENOMEM;
7c236c43b838221 Stuart Hodgson  2012-09-03  1504  				goto fail4;
7c236c43b838221 Stuart Hodgson  2012-09-03  1505  			}
9aecda95d0a2865 Ben Hutchings   2013-12-05  1506  		}
efee95f42b5ddde Nicolas Pitre   2016-09-20  1507  	}
7c236c43b838221 Stuart Hodgson  2012-09-03  1508  	ptp->nic_ts_enabled = false;
7c236c43b838221 Stuart Hodgson  2012-09-03  1509  
7c236c43b838221 Stuart Hodgson  2012-09-03  1510  	return 0;
7c236c43b838221 Stuart Hodgson  2012-09-03  1511  fail4:
7c236c43b838221 Stuart Hodgson  2012-09-03  1512  	ptp_clock_unregister(efx->ptp_data->phc_clock);
7c236c43b838221 Stuart Hodgson  2012-09-03  1513  
7c236c43b838221 Stuart Hodgson  2012-09-03  1514  fail3:
7c236c43b838221 Stuart Hodgson  2012-09-03  1515  	destroy_workqueue(efx->ptp_data->workwq);
7c236c43b838221 Stuart Hodgson  2012-09-03  1516  
7c236c43b838221 Stuart Hodgson  2012-09-03  1517  fail2:
7c236c43b838221 Stuart Hodgson  2012-09-03  1518  	efx_nic_free_buffer(efx, &ptp->start);
7c236c43b838221 Stuart Hodgson  2012-09-03  1519  
7c236c43b838221 Stuart Hodgson  2012-09-03  1520  fail1:
7c236c43b838221 Stuart Hodgson  2012-09-03  1521  	kfree(efx->ptp_data);
7c236c43b838221 Stuart Hodgson  2012-09-03  1522  	efx->ptp_data = NULL;
7c236c43b838221 Stuart Hodgson  2012-09-03  1523  
7c236c43b838221 Stuart Hodgson  2012-09-03  1524  	return rc;
7c236c43b838221 Stuart Hodgson  2012-09-03  1525  }
7c236c43b838221 Stuart Hodgson  2012-09-03  1526  

---
0-DAY CI Kernel Test Service, Intel Corporation
https://lists.01.org/hyperkitty/list/kbuild-all@lists.01.org

[-- Attachment #2: .config.gz --]
[-- Type: application/gzip, Size: 28439 bytes --]

^ permalink raw reply	[flat|nested] 25+ messages in thread

* Re: [PATCH net-next 03/15] sfc_ef100: skeleton EF100 PF driver
  2020-07-04  4:16   ` kernel test robot
@ 2020-07-07 18:34     ` Edward Cree
  2020-07-08  3:15       ` [kbuild-all] " Xia, Hui
  0 siblings, 1 reply; 25+ messages in thread
From: Edward Cree @ 2020-07-07 18:34 UTC (permalink / raw)
  To: kernel test robot, linux-net-drivers, davem; +Cc: kbuild-all, netdev

On 04/07/2020 05:16, kernel test robot wrote:
>>> drivers/net/ethernet/sfc/ptp.c:1442:1-4: alloc with no test, possible model on line 1457
This one's a false positive, see below:
> vim +1442 drivers/net/ethernet/sfc/ptp.c
>
> 5d0dab01175bff0 Ben Hutchings   2013-10-16  1434  
> ac36baf817c39fc Ben Hutchings   2013-10-15  1435  /* Initialise PTP state. */
> ac36baf817c39fc Ben Hutchings   2013-10-15  1436  int efx_ptp_probe(struct efx_nic *efx, struct efx_channel *channel)
> 7c236c43b838221 Stuart Hodgson  2012-09-03  1437  {
> 7c236c43b838221 Stuart Hodgson  2012-09-03  1438  	struct efx_ptp_data *ptp;
> 7c236c43b838221 Stuart Hodgson  2012-09-03  1439  	int rc = 0;
> 7c236c43b838221 Stuart Hodgson  2012-09-03  1440  	unsigned int pos;
> 7c236c43b838221 Stuart Hodgson  2012-09-03  1441  
> 7c236c43b838221 Stuart Hodgson  2012-09-03 @1442  	ptp = kzalloc(sizeof(struct efx_ptp_data), GFP_KERNEL);
We allocate ptp...
> 7c236c43b838221 Stuart Hodgson  2012-09-03  1443  	efx->ptp_data = ptp;
... assign it to efx->ptp_data...
> 7c236c43b838221 Stuart Hodgson  2012-09-03  1444  	if (!efx->ptp_data)
> 7c236c43b838221 Stuart Hodgson  2012-09-03  1445  		return -ENOMEM;
... which we then test.

So by here...
> 7c236c43b838221 Stuart Hodgson  2012-09-03 @1457  	ptp->workwq = create_singlethread_workqueue("sfc_ptp");
... we know ptp is non-NULL.

-ed

^ permalink raw reply	[flat|nested] 25+ messages in thread

* RE: [kbuild-all] Re: [PATCH net-next 03/15] sfc_ef100: skeleton EF100 PF driver
  2020-07-07 18:34     ` Edward Cree
@ 2020-07-08  3:15       ` Xia, Hui
  0 siblings, 0 replies; 25+ messages in thread
From: Xia, Hui @ 2020-07-08  3:15 UTC (permalink / raw)
  To: Edward Cree, lkp, linux-net-drivers, davem; +Cc: kbuild-all, netdev



>-----Original Message-----
>From: Edward Cree <ecree@solarflare.com>
>Sent: 2020年7月8日 2:35
>To: lkp <lkp@intel.com>; linux-net-drivers@solarflare.com;
>davem@davemloft.net
>Cc: kbuild-all@lists.01.org; netdev@vger.kernel.org
>Subject: [kbuild-all] Re: [PATCH net-next 03/15] sfc_ef100: skeleton EF100 PF
>driver
>
>On 04/07/2020 05:16, kernel test robot wrote:
>>>> drivers/net/ethernet/sfc/ptp.c:1442:1-4: alloc with no test,
>>>> possible model on line 1457
>This one's a false positive, see below:
Sorry for inconvenient. Please ignore this warning.
We will double check for this type of warning. Thanks.

>> vim +1442 drivers/net/ethernet/sfc/ptp.c
>>
>> 5d0dab01175bff0 Ben Hutchings   2013-10-16  1434
>> ac36baf817c39fc Ben Hutchings   2013-10-15  1435  /* Initialise PTP state. */
>> ac36baf817c39fc Ben Hutchings   2013-10-15  1436  int efx_ptp_probe(struct
>efx_nic *efx, struct efx_channel *channel)
>> 7c236c43b838221 Stuart Hodgson  2012-09-03  1437  {
>> 7c236c43b838221 Stuart Hodgson  2012-09-03  1438  	struct efx_ptp_data
>*ptp;
>> 7c236c43b838221 Stuart Hodgson  2012-09-03  1439  	int rc = 0;
>> 7c236c43b838221 Stuart Hodgson  2012-09-03  1440  	unsigned int pos;
>> 7c236c43b838221 Stuart Hodgson  2012-09-03  1441
>> 7c236c43b838221 Stuart Hodgson  2012-09-03 @1442  	ptp =
>kzalloc(sizeof(struct efx_ptp_data), GFP_KERNEL);
>We allocate ptp...
>> 7c236c43b838221 Stuart Hodgson  2012-09-03  1443  	efx->ptp_data = ptp;
>... assign it to efx->ptp_data...
>> 7c236c43b838221 Stuart Hodgson  2012-09-03  1444  	if (!efx->ptp_data)
>> 7c236c43b838221 Stuart Hodgson  2012-09-03  1445  		return -
>ENOMEM;
>... which we then test.
>
>So by here...
>> 7c236c43b838221 Stuart Hodgson  2012-09-03 @1457  	ptp->workwq =
>create_singlethread_workqueue("sfc_ptp");
>... we know ptp is non-NULL.
>
>-ed
>_______________________________________________
>kbuild-all mailing list -- kbuild-all@lists.01.org To unsubscribe send an email to
>kbuild-all-leave@lists.01.org

^ permalink raw reply	[flat|nested] 25+ messages in thread

* Re: [PATCH net-next 03/15] sfc_ef100: skeleton EF100 PF driver
  2020-07-03 17:46   ` kernel test robot
@ 2020-07-08 19:16     ` Edward Cree
  0 siblings, 0 replies; 25+ messages in thread
From: Edward Cree @ 2020-07-08 19:16 UTC (permalink / raw)
  To: kernel test robot, linux-net-drivers, davem; +Cc: kbuild-all, netdev

On 03/07/2020 18:46, kernel test robot wrote:
>    In file included from include/linux/skbuff.h:31,
>                     from include/linux/if_ether.h:19,
>                     from include/uapi/linux/ethtool.h:19,
>                     from include/linux/ethtool.h:18,
>                     from include/linux/netdevice.h:37,
>                     from drivers/net/ethernet/sfc/net_driver.h:13,
>                     from drivers/net/ethernet/sfc/ef100.c:12:
>    drivers/net/ethernet/sfc/ef100.c: In function 'ef100_pci_parse_continue_entry':
>>> include/linux/dma-mapping.h:139:25: warning: conversion from 'long long unsigned int' to 'dma_addr_t' {aka 'unsigned int'} changes value from '18446744073709551615' to '4294967295' [-Woverflow]
>      139 | #define DMA_BIT_MASK(n) (((n) == 64) ? ~0ULL : ((1ULL<<(n))-1))
>          |                         ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
>>> drivers/net/ethernet/sfc/ef100.c:144:6: note: in expansion of macro 'DMA_BIT_MASK'
>      144 |      DMA_BIT_MASK(ESF_GZ_TX_SEND_ADDR_WIDTH),
>          |      ^~~~~~~~~~~~
I think this is spurious?  DMA_BIT_MASK() looks likeit's intended to
 return a dma_addr_t, and the conversion does the right thing (truncate
 to 32 bits), so maybe all that's needed is some suitable annotation to
 make the compiler happy.  Would casting explicitly to dma_addr_t do it?

-ed

^ permalink raw reply	[flat|nested] 25+ messages in thread

end of thread, other threads:[~2020-07-08 19:16 UTC | newest]

Thread overview: 25+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2020-07-03 15:28 [PATCH net-next 00/15] sfc_ef100: driver for EF100 family NICs, part 1 Edward Cree
2020-07-03 15:30 ` [PATCH net-next 01/15] sfc_ef100: add EF100 register definitions Edward Cree
2020-07-03 15:30 ` [PATCH net-next 02/15] sfc_ef100: register accesses on EF100 Edward Cree
2020-07-03 15:31 ` [PATCH net-next 03/15] sfc_ef100: skeleton EF100 PF driver Edward Cree
2020-07-03 17:43   ` Jakub Kicinski
2020-07-03 17:46   ` kernel test robot
2020-07-08 19:16     ` Edward Cree
2020-07-03 17:46   ` [RFC PATCH] sfc_ef100: ef100_hard_start_xmit() can be static kernel test robot
2020-07-03 19:41   ` [PATCH net-next 03/15] sfc_ef100: skeleton EF100 PF driver kernel test robot
2020-07-04  4:16   ` kernel test robot
2020-07-07 18:34     ` Edward Cree
2020-07-08  3:15       ` [kbuild-all] " Xia, Hui
2020-07-03 15:31 ` [PATCH net-next 04/15] sfc_ef100: reset-handling stub Edward Cree
2020-07-03 15:32 ` [PATCH net-next 05/15] sfc_ef100: PHY probe stub Edward Cree
2020-07-03 15:32 ` [PATCH net-next 06/15] sfc_ef100: don't call efx_reset_down()/up() on EF100 Edward Cree
2020-07-04  2:15   ` kernel test robot
2020-07-03 15:33 ` [PATCH net-next 07/15] sfc_ef100: implement MCDI transport Edward Cree
2020-07-03 15:33 ` [PATCH net-next 08/15] sfc_ef100: implement ndo_open/close and EVQ probing Edward Cree
2020-07-03 15:34 ` [PATCH net-next 09/15] sfc_ef100: process events for MCDI completions Edward Cree
2020-07-03 15:34 ` [PATCH net-next 10/15] sfc_ef100: read datapath caps, implement check_caps Edward Cree
2020-07-03 15:35 ` [PATCH net-next 11/15] sfc_ef100: extend ef100_check_caps to cover datapath_caps3 Edward Cree
2020-07-03 15:35 ` [PATCH net-next 12/15] sfc_ef100: actually perform resets Edward Cree
2020-07-03 15:35 ` [PATCH net-next 13/15] sfc_ef100: probe the PHY and configure the MAC Edward Cree
2020-07-03 15:36 ` [PATCH net-next 14/15] sfc_ef100: read device MAC address at probe time Edward Cree
2020-07-03 15:36 ` [PATCH net-next 15/15] sfc_ef100: implement ndo_get_phys_port_{id,name} Edward Cree

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).