* [PATCH v3 net-next 03/16] sfc_ef100: register accesses on EF100
From: Edward Cree @ 2020-07-16 13:00 UTC (permalink / raw)
To: linux-net-drivers, davem; +Cc: netdev
In-Reply-To: <7bb4f1f4-c67f-8c7b-86ba-7bf9f74ffc28@solarflare.com>
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
* Re: [PATCH v2 2/2] PCI: tegra: Remove PLL power supplies
From: Thierry Reding @ 2020-07-16 13:00 UTC (permalink / raw)
To: Lorenzo Pieralisi, Bjorn Helgaas, Rob Herring
Cc: Jon Hunter, linux-pci, linux-tegra
In-Reply-To: <20200623145528.1658337-2-thierry.reding@gmail.com>
[-- Attachment #1: Type: text/plain, Size: 2589 bytes --]
On Tue, Jun 23, 2020 at 04:55:28PM +0200, Thierry Reding wrote:
> From: Thierry Reding <treding@nvidia.com>
>
> The Tegra PCI controller driver doesn't need to control the PLL power
> supplies directly, but rather uses the pads provided by the XUSB pad
> controller, which in turn is responsible for supplying power to the
> PLLs.
>
> Signed-off-by: Thierry Reding <treding@nvidia.com>
> ---
> drivers/pci/controller/pci-tegra.c | 10 ++--------
> 1 file changed, 2 insertions(+), 8 deletions(-)
Hi Lorenzo,
do you have any comments on this? Can we get this into v5.9?
Thanks,
Thierry
> diff --git a/drivers/pci/controller/pci-tegra.c b/drivers/pci/controller/pci-tegra.c
> index 235b456698fc..f87a09d21eb0 100644
> --- a/drivers/pci/controller/pci-tegra.c
> +++ b/drivers/pci/controller/pci-tegra.c
> @@ -2025,7 +2025,7 @@ static int tegra_pcie_get_regulators(struct tegra_pcie *pcie, u32 lane_mask)
> pcie->supplies[i++].supply = "hvdd-pex";
> pcie->supplies[i++].supply = "vddio-pexctl-aud";
> } else if (of_device_is_compatible(np, "nvidia,tegra210-pcie")) {
> - pcie->num_supplies = 6;
> + pcie->num_supplies = 3;
>
> pcie->supplies = devm_kcalloc(pcie->dev, pcie->num_supplies,
> sizeof(*pcie->supplies),
> @@ -2033,14 +2033,11 @@ static int tegra_pcie_get_regulators(struct tegra_pcie *pcie, u32 lane_mask)
> if (!pcie->supplies)
> return -ENOMEM;
>
> - pcie->supplies[i++].supply = "avdd-pll-uerefe";
> pcie->supplies[i++].supply = "hvddio-pex";
> pcie->supplies[i++].supply = "dvddio-pex";
> - pcie->supplies[i++].supply = "dvdd-pex-pll";
> - pcie->supplies[i++].supply = "hvdd-pex-pll-e";
> pcie->supplies[i++].supply = "vddio-pex-ctl";
> } else if (of_device_is_compatible(np, "nvidia,tegra124-pcie")) {
> - pcie->num_supplies = 7;
> + pcie->num_supplies = 4;
>
> pcie->supplies = devm_kcalloc(dev, pcie->num_supplies,
> sizeof(*pcie->supplies),
> @@ -2050,11 +2047,8 @@ static int tegra_pcie_get_regulators(struct tegra_pcie *pcie, u32 lane_mask)
>
> pcie->supplies[i++].supply = "avddio-pex";
> pcie->supplies[i++].supply = "dvddio-pex";
> - pcie->supplies[i++].supply = "avdd-pex-pll";
> pcie->supplies[i++].supply = "hvdd-pex";
> - pcie->supplies[i++].supply = "hvdd-pex-pll-e";
> pcie->supplies[i++].supply = "vddio-pex-ctl";
> - pcie->supplies[i++].supply = "avdd-pll-erefe";
> } else if (of_device_is_compatible(np, "nvidia,tegra30-pcie")) {
> bool need_pexa = false, need_pexb = false;
>
> --
> 2.27.0
>
[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 833 bytes --]
^ permalink raw reply
* Re: [PATCH v2 2/2] PCI: tegra: Remove PLL power supplies
From: Thierry Reding @ 2020-07-16 13:00 UTC (permalink / raw)
To: Lorenzo Pieralisi, Bjorn Helgaas, Rob Herring
Cc: Jon Hunter, linux-pci-u79uwXL29TY76Z2rM5mHXA,
linux-tegra-u79uwXL29TY76Z2rM5mHXA
In-Reply-To: <20200623145528.1658337-2-thierry.reding-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
[-- Attachment #1: Type: text/plain, Size: 2647 bytes --]
On Tue, Jun 23, 2020 at 04:55:28PM +0200, Thierry Reding wrote:
> From: Thierry Reding <treding-DDmLM1+adcrQT0dZR+AlfA@public.gmane.org>
>
> The Tegra PCI controller driver doesn't need to control the PLL power
> supplies directly, but rather uses the pads provided by the XUSB pad
> controller, which in turn is responsible for supplying power to the
> PLLs.
>
> Signed-off-by: Thierry Reding <treding-DDmLM1+adcrQT0dZR+AlfA@public.gmane.org>
> ---
> drivers/pci/controller/pci-tegra.c | 10 ++--------
> 1 file changed, 2 insertions(+), 8 deletions(-)
Hi Lorenzo,
do you have any comments on this? Can we get this into v5.9?
Thanks,
Thierry
> diff --git a/drivers/pci/controller/pci-tegra.c b/drivers/pci/controller/pci-tegra.c
> index 235b456698fc..f87a09d21eb0 100644
> --- a/drivers/pci/controller/pci-tegra.c
> +++ b/drivers/pci/controller/pci-tegra.c
> @@ -2025,7 +2025,7 @@ static int tegra_pcie_get_regulators(struct tegra_pcie *pcie, u32 lane_mask)
> pcie->supplies[i++].supply = "hvdd-pex";
> pcie->supplies[i++].supply = "vddio-pexctl-aud";
> } else if (of_device_is_compatible(np, "nvidia,tegra210-pcie")) {
> - pcie->num_supplies = 6;
> + pcie->num_supplies = 3;
>
> pcie->supplies = devm_kcalloc(pcie->dev, pcie->num_supplies,
> sizeof(*pcie->supplies),
> @@ -2033,14 +2033,11 @@ static int tegra_pcie_get_regulators(struct tegra_pcie *pcie, u32 lane_mask)
> if (!pcie->supplies)
> return -ENOMEM;
>
> - pcie->supplies[i++].supply = "avdd-pll-uerefe";
> pcie->supplies[i++].supply = "hvddio-pex";
> pcie->supplies[i++].supply = "dvddio-pex";
> - pcie->supplies[i++].supply = "dvdd-pex-pll";
> - pcie->supplies[i++].supply = "hvdd-pex-pll-e";
> pcie->supplies[i++].supply = "vddio-pex-ctl";
> } else if (of_device_is_compatible(np, "nvidia,tegra124-pcie")) {
> - pcie->num_supplies = 7;
> + pcie->num_supplies = 4;
>
> pcie->supplies = devm_kcalloc(dev, pcie->num_supplies,
> sizeof(*pcie->supplies),
> @@ -2050,11 +2047,8 @@ static int tegra_pcie_get_regulators(struct tegra_pcie *pcie, u32 lane_mask)
>
> pcie->supplies[i++].supply = "avddio-pex";
> pcie->supplies[i++].supply = "dvddio-pex";
> - pcie->supplies[i++].supply = "avdd-pex-pll";
> pcie->supplies[i++].supply = "hvdd-pex";
> - pcie->supplies[i++].supply = "hvdd-pex-pll-e";
> pcie->supplies[i++].supply = "vddio-pex-ctl";
> - pcie->supplies[i++].supply = "avdd-pll-erefe";
> } else if (of_device_is_compatible(np, "nvidia,tegra30-pcie")) {
> bool need_pexa = false, need_pexb = false;
>
> --
> 2.27.0
>
[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 833 bytes --]
^ permalink raw reply
* [PATCH v3 net-next 02/16] sfc_ef100: add EF100 register definitions
From: Edward Cree @ 2020-07-16 13:00 UTC (permalink / raw)
To: linux-net-drivers, davem; +Cc: netdev
In-Reply-To: <7bb4f1f4-c67f-8c7b-86ba-7bf9f74ffc28@solarflare.com>
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
* [PATCH v3 net-next 01/16] sfc: remove efx_ethtool_nway_reset()
From: Edward Cree @ 2020-07-16 12:59 UTC (permalink / raw)
To: linux-net-drivers, davem; +Cc: netdev
In-Reply-To: <7bb4f1f4-c67f-8c7b-86ba-7bf9f74ffc28@solarflare.com>
An MDIO-based n-way restart does not make sense for any of the NICs
supported by this driver, nor for the coming EF100.
Unlike on Falcon (which was already split off into a separate driver),
the PHY on all of Siena, EF10 and EF100 is managed by MC firmware.
While Siena can talk to the PHY over MDIO, doing so for anything other
than debugging purposes (mdio_mii_ioctl) is likely to confuse the
firmware.
(According to the SFC firmware team, this support was originally added
to the Siena driver early in the development of that product, before
it was decided to have firmware manage the PHY.)
Signed-off-by: Edward Cree <ecree@solarflare.com>
---
drivers/net/ethernet/sfc/ethtool.c | 1 -
drivers/net/ethernet/sfc/ethtool_common.c | 8 --------
drivers/net/ethernet/sfc/ethtool_common.h | 1 -
3 files changed, 10 deletions(-)
diff --git a/drivers/net/ethernet/sfc/ethtool.c b/drivers/net/ethernet/sfc/ethtool.c
index 9828516bd82d..038c08d2d7aa 100644
--- a/drivers/net/ethernet/sfc/ethtool.c
+++ b/drivers/net/ethernet/sfc/ethtool.c
@@ -232,7 +232,6 @@ const struct ethtool_ops efx_ethtool_ops = {
.get_regs = efx_ethtool_get_regs,
.get_msglevel = efx_ethtool_get_msglevel,
.set_msglevel = efx_ethtool_set_msglevel,
- .nway_reset = efx_ethtool_nway_reset,
.get_link = ethtool_op_get_link,
.get_coalesce = efx_ethtool_get_coalesce,
.set_coalesce = efx_ethtool_set_coalesce,
diff --git a/drivers/net/ethernet/sfc/ethtool_common.c b/drivers/net/ethernet/sfc/ethtool_common.c
index e9a5a66529bf..fb06097b70d8 100644
--- a/drivers/net/ethernet/sfc/ethtool_common.c
+++ b/drivers/net/ethernet/sfc/ethtool_common.c
@@ -173,14 +173,6 @@ void efx_ethtool_self_test(struct net_device *net_dev,
test->flags |= ETH_TEST_FL_FAILED;
}
-/* Restart autonegotiation */
-int efx_ethtool_nway_reset(struct net_device *net_dev)
-{
- struct efx_nic *efx = netdev_priv(net_dev);
-
- return mdio45_nway_restart(&efx->mdio);
-}
-
void efx_ethtool_get_pauseparam(struct net_device *net_dev,
struct ethtool_pauseparam *pause)
{
diff --git a/drivers/net/ethernet/sfc/ethtool_common.h b/drivers/net/ethernet/sfc/ethtool_common.h
index 3f3aaa92fbb5..0c0ea9ac4d08 100644
--- a/drivers/net/ethernet/sfc/ethtool_common.h
+++ b/drivers/net/ethernet/sfc/ethtool_common.h
@@ -19,7 +19,6 @@ u32 efx_ethtool_get_msglevel(struct net_device *net_dev);
void efx_ethtool_set_msglevel(struct net_device *net_dev, u32 msg_enable);
void efx_ethtool_self_test(struct net_device *net_dev,
struct ethtool_test *test, u64 *data);
-int efx_ethtool_nway_reset(struct net_device *net_dev);
void efx_ethtool_get_pauseparam(struct net_device *net_dev,
struct ethtool_pauseparam *pause);
int efx_ethtool_set_pauseparam(struct net_device *net_dev,
^ permalink raw reply related
* Re: [PATCH v2 1/2] dt-bindings: pci: tegra: Remove PLL power supplies
From: Thierry Reding @ 2020-07-16 12:59 UTC (permalink / raw)
To: Lorenzo Pieralisi, Bjorn Helgaas, Rob Herring
Cc: Jon Hunter, linux-pci, linux-tegra
In-Reply-To: <20200623145528.1658337-1-thierry.reding@gmail.com>
[-- Attachment #1: Type: text/plain, Size: 2962 bytes --]
On Tue, Jun 23, 2020 at 04:55:27PM +0200, Thierry Reding wrote:
> From: Thierry Reding <treding@nvidia.com>
>
> The XUSB pad controller, which provides access to various USB, PCI and
> SATA pads (or PHYs), needs to bring up the PLLs associated with these
> pads. In order to properly do so, it needs to control the power supplied
> to these PLLs.
>
> Remove the PLL power supplies from the PCIe controller because it does
> not need direct access to them. Instead it will only use the configured
> pads provided by the XUSB pad controller.
>
> Signed-off-by: Thierry Reding <treding@nvidia.com>
> ---
> Hi Rob,
>
> I already made this change as part of the conversion series, but wanted
> to send this out as part of this subseries since it addresses a fairly
> long-standing issue that I'd like to clean up irrespective of the DT
> binding conversion. Since it looks like the conversion series will take
> a bit longer, I think it makes sense to send this out separately.
>
> Thierry
>
> .../devicetree/bindings/pci/nvidia,tegra20-pcie.txt | 12 ------------
> 1 file changed, 12 deletions(-)
Hi Rob, any feedback on this?
Thanks,
Thierry
> diff --git a/Documentation/devicetree/bindings/pci/nvidia,tegra20-pcie.txt b/Documentation/devicetree/bindings/pci/nvidia,tegra20-pcie.txt
> index 7939bca47861..d099f3476ccc 100644
> --- a/Documentation/devicetree/bindings/pci/nvidia,tegra20-pcie.txt
> +++ b/Documentation/devicetree/bindings/pci/nvidia,tegra20-pcie.txt
> @@ -112,28 +112,16 @@ Power supplies for Tegra124:
> - Required:
> - avddio-pex-supply: Power supply for analog PCIe logic. Must supply 1.05 V.
> - dvddio-pex-supply: Power supply for digital PCIe I/O. Must supply 1.05 V.
> - - avdd-pex-pll-supply: Power supply for dedicated (internal) PCIe PLL. Must
> - supply 1.05 V.
> - hvdd-pex-supply: High-voltage supply for PCIe I/O and PCIe output clocks.
> Must supply 3.3 V.
> - - hvdd-pex-pll-e-supply: High-voltage supply for PLLE (shared with USB3).
> - Must supply 3.3 V.
> - vddio-pex-ctl-supply: Power supply for PCIe control I/O partition. Must
> supply 2.8-3.3 V.
> - - avdd-pll-erefe-supply: Power supply for PLLE (shared with USB3). Must
> - supply 1.05 V.
>
> Power supplies for Tegra210:
> - Required:
> - - avdd-pll-uerefe-supply: Power supply for PLLE (shared with USB3). Must
> - supply 1.05 V.
> - hvddio-pex-supply: High-voltage supply for PCIe I/O and PCIe output
> clocks. Must supply 1.8 V.
> - dvddio-pex-supply: Power supply for digital PCIe I/O. Must supply 1.05 V.
> - - dvdd-pex-pll-supply: Power supply for dedicated (internal) PCIe PLL. Must
> - supply 1.05 V.
> - - hvdd-pex-pll-e-supply: High-voltage supply for PLLE (shared with USB3).
> - Must supply 3.3 V.
> - vddio-pex-ctl-supply: Power supply for PCIe control I/O partition. Must
> supply 1.8 V.
>
> --
> 2.27.0
>
[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 833 bytes --]
^ permalink raw reply
* Re: [PATCH v2 1/2] dt-bindings: pci: tegra: Remove PLL power supplies
From: Thierry Reding @ 2020-07-16 12:59 UTC (permalink / raw)
To: Lorenzo Pieralisi, Bjorn Helgaas, Rob Herring
Cc: Jon Hunter, linux-pci-u79uwXL29TY76Z2rM5mHXA,
linux-tegra-u79uwXL29TY76Z2rM5mHXA
In-Reply-To: <20200623145528.1658337-1-thierry.reding-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
[-- Attachment #1: Type: text/plain, Size: 3020 bytes --]
On Tue, Jun 23, 2020 at 04:55:27PM +0200, Thierry Reding wrote:
> From: Thierry Reding <treding-DDmLM1+adcrQT0dZR+AlfA@public.gmane.org>
>
> The XUSB pad controller, which provides access to various USB, PCI and
> SATA pads (or PHYs), needs to bring up the PLLs associated with these
> pads. In order to properly do so, it needs to control the power supplied
> to these PLLs.
>
> Remove the PLL power supplies from the PCIe controller because it does
> not need direct access to them. Instead it will only use the configured
> pads provided by the XUSB pad controller.
>
> Signed-off-by: Thierry Reding <treding-DDmLM1+adcrQT0dZR+AlfA@public.gmane.org>
> ---
> Hi Rob,
>
> I already made this change as part of the conversion series, but wanted
> to send this out as part of this subseries since it addresses a fairly
> long-standing issue that I'd like to clean up irrespective of the DT
> binding conversion. Since it looks like the conversion series will take
> a bit longer, I think it makes sense to send this out separately.
>
> Thierry
>
> .../devicetree/bindings/pci/nvidia,tegra20-pcie.txt | 12 ------------
> 1 file changed, 12 deletions(-)
Hi Rob, any feedback on this?
Thanks,
Thierry
> diff --git a/Documentation/devicetree/bindings/pci/nvidia,tegra20-pcie.txt b/Documentation/devicetree/bindings/pci/nvidia,tegra20-pcie.txt
> index 7939bca47861..d099f3476ccc 100644
> --- a/Documentation/devicetree/bindings/pci/nvidia,tegra20-pcie.txt
> +++ b/Documentation/devicetree/bindings/pci/nvidia,tegra20-pcie.txt
> @@ -112,28 +112,16 @@ Power supplies for Tegra124:
> - Required:
> - avddio-pex-supply: Power supply for analog PCIe logic. Must supply 1.05 V.
> - dvddio-pex-supply: Power supply for digital PCIe I/O. Must supply 1.05 V.
> - - avdd-pex-pll-supply: Power supply for dedicated (internal) PCIe PLL. Must
> - supply 1.05 V.
> - hvdd-pex-supply: High-voltage supply for PCIe I/O and PCIe output clocks.
> Must supply 3.3 V.
> - - hvdd-pex-pll-e-supply: High-voltage supply for PLLE (shared with USB3).
> - Must supply 3.3 V.
> - vddio-pex-ctl-supply: Power supply for PCIe control I/O partition. Must
> supply 2.8-3.3 V.
> - - avdd-pll-erefe-supply: Power supply for PLLE (shared with USB3). Must
> - supply 1.05 V.
>
> Power supplies for Tegra210:
> - Required:
> - - avdd-pll-uerefe-supply: Power supply for PLLE (shared with USB3). Must
> - supply 1.05 V.
> - hvddio-pex-supply: High-voltage supply for PCIe I/O and PCIe output
> clocks. Must supply 1.8 V.
> - dvddio-pex-supply: Power supply for digital PCIe I/O. Must supply 1.05 V.
> - - dvdd-pex-pll-supply: Power supply for dedicated (internal) PCIe PLL. Must
> - supply 1.05 V.
> - - hvdd-pex-pll-e-supply: High-voltage supply for PLLE (shared with USB3).
> - Must supply 3.3 V.
> - vddio-pex-ctl-supply: Power supply for PCIe control I/O partition. Must
> supply 1.8 V.
>
> --
> 2.27.0
>
[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 833 bytes --]
^ permalink raw reply
* Re: migration: broken snapshot saves appear on s390 when small fields in migration stream removed
From: Claudio Fontana @ 2020-07-16 12:58 UTC (permalink / raw)
To: Thomas Huth, Paolo Bonzini, Juan Quintela, Dr. David Alan Gilbert,
Kevin Wolf, Max Reitz
Cc: Jason J. Herne, Fam Zheng, Liang Yan, Peter Maydell,
Cornelia Huck, qemu-devel, Stefan Hajnoczi
In-Reply-To: <8ff7eeab-bef1-0957-a95c-72819680c431@suse.de>
Small update on this,
On 7/15/20 1:10 PM, Claudio Fontana wrote:
> Hi Thomas,
>
> On 7/14/20 4:35 PM, Thomas Huth wrote:
>> On 14/07/2020 16.29, Claudio Fontana wrote:
>>> Hello,
>>>
>>> I have some tiny progress in narrowing down this issue, possibly a qcow2 issue, still unclear,
>>> but involving Kevin Wolf and Max Reitz.
>>>
>>>
>>> The reproducer again:
>>>
>>>> --------------------------------------------cut-------------------------------------------
>>>> diff --git a/cpus.c b/cpus.c
>>>> index 41d1c5099f..443b88697a 100644
>>>> --- a/cpus.c
>>>> +++ b/cpus.c
>>>> @@ -643,7 +643,7 @@ static void qemu_account_warp_timer(void)
>>>>
>>>> static bool icount_state_needed(void *opaque)
>>>> {
>>>> - return use_icount;
>>>> + return 0;
>>>> }
>>>>
>>>> static bool warp_timer_state_needed(void *opaque)
>>>> --------------------------------------------cut-------------------------------------------
>>>
>>> This issue for now appears on s390 only:
>>>
>>> On s390 hardware, test 267 fails (both kvm and tcg) in the qcow2 backing file part, with broken migration stream data in the s390-skeys vmsave (old style).
>> [...]
>>> If someone has a good idea let me know - first attempts to reproduce on x86 failed, but maybe more work could lead to it.
>>
>
> small update: in the GOOD case (enough padding added) a qcow_merge() is triggered for the last write of 16202 bytes.
> In the BAD case (not enough padding added) a qcow_merge() is not triggered for the last write of 16201 bytes.
>
> Note: manually flushing with qemu_fflush in s390-skeys vmsave also works (maybe got lost in the noise).
>
>
>> Two questions:
>>
>> 1) Can you also reproduce the issue manually, without running iotest
>> 267? ... I tried, but so far I failed.
>
> Thanks for the suggestion, will try.
Currently trying to reproduce manually an environment similar to that of the test,
at the moment I am not able to reproduce the issue manually.
Not very familiar with s390,
I've been running with
export QEMU=/home/cfontana/qemu-build/s390x-softmmu/qemu-system-s390x
$QEMU -nographic -monitor stdio -nodefaults -no-shutdown FILENAME
where FILENAME is the qcow2 produced by the test.
let me know if you have a suggestion on how to setup up something simple properly.
>
>>
>> 2) Since all the information so far sounds like the problem could be
>> elsewhere in the code, and the skeys just catch it by accident ... have
>> you tried running with valgrind? Maybe it catches something useful?
>
> Nothing yet, but will fiddle with the options a bit more.
Only thing I have seen so far:
+==33321==
+==33321== Warning: client switching stacks? SP change: 0x1ffeffe5e8 --> 0x5d9cf60
+==33321== to suppress, use: --max-stackframe=137324009096 or greater
+==33321== Warning: client switching stacks? SP change: 0x5d9cd18 --> 0x1ffeffe5e8
+==33321== to suppress, use: --max-stackframe=137324009680 or greater
+==33321== Warning: client switching stacks? SP change: 0x1ffeffe8b8 --> 0x5d9ce58
+==33321== to suppress, use: --max-stackframe=137324010080 or greater
+==33321== further instances of this message will not be shown.
+==33321== Thread 4:
+==33321== Conditional jump or move depends on uninitialised value(s)
+==33321== at 0x3AEC70: process_queued_cpu_work (cpus-common.c:331)
+==33321== by 0x2753E1: qemu_wait_io_event_common (cpus.c:1213)
+==33321== by 0x2755CD: qemu_wait_io_event (cpus.c:1253)
+==33321== by 0x27596D: qemu_dummy_cpu_thread_fn (cpus.c:1337)
+==33321== by 0x725C87: qemu_thread_start (qemu-thread-posix.c:521)
+==33321== by 0x4D504E9: start_thread (in /lib64/libpthread-2.26.so)
+==33321== by 0x4E72BBD: ??? (in /lib64/libc-2.26.so)
+==33321==
+==33321== Conditional jump or move depends on uninitialised value(s)
+==33321== at 0x3AEC74: process_queued_cpu_work (cpus-common.c:331)
+==33321== by 0x2753E1: qemu_wait_io_event_common (cpus.c:1213)
+==33321== by 0x2755CD: qemu_wait_io_event (cpus.c:1253)
+==33321== by 0x27596D: qemu_dummy_cpu_thread_fn (cpus.c:1337)
+==33321== by 0x725C87: qemu_thread_start (qemu-thread-posix.c:521)
+==33321== by 0x4D504E9: start_thread (in /lib64/libpthread-2.26.so)
+==33321== by 0x4E72BBD: ??? (in /lib64/libc-2.26.so)
+==33321==
+==33321==
+==33321== HEAP SUMMARY:
+==33321== in use at exit: 2,138,442 bytes in 13,935 blocks
+==33321== total heap usage: 19,089 allocs, 5,154 frees, 5,187,670 bytes allocated
+==33321==
+==33321== LEAK SUMMARY:
+==33321== definitely lost: 0 bytes in 0 blocks
+==33321== indirectly lost: 0 bytes in 0 blocks
+==33321== possibly lost: 7,150 bytes in 111 blocks
+==33321== still reachable: 2,131,292 bytes in 13,824 blocks
+==33321== suppressed: 0 bytes in 0 blocks
+==33321== Rerun with --leak-check=full to see details of leaked memory
>
>>
>> Thomas
>>
>
> Ciao,
>
> Claudio
>
>
A more interesting update is what follows I think.
I was able to "fix" the problem shown by the reproducer:
@@ -643,7 +643,7 @@ static void qemu_account_warp_tim@@ -643,7 +643,7 @@ static void qemu_account_warp_timer(void)
static bool icount_state_needed(void *opaque)
{
- return use_icount;
+ return 0;
}
by just slowing down qcow2_co_pwritev_task_entry with some tight loops,
without changing any fields between runs (other than the reproducer icount field removal).
I tried to insert the same slowdown just in savevm.c at the end of save_snapshot, but that does not work, needs to be in the coroutine.
Thanks,
Claudio
^ permalink raw reply
* Re: [PATCH] arm64: tegra: Add the GPU on Tegra194
From: Jon Hunter @ 2020-07-16 12:59 UTC (permalink / raw)
To: Thierry Reding
Cc: linux-tegra-u79uwXL29TY76Z2rM5mHXA, Debarshi Dutta,
Terje Bergstrom,
linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r
In-Reply-To: <20200716120138.532906-1-thierry.reding-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
On 16/07/2020 13:01, Thierry Reding wrote:
> From: Thierry Reding <treding-DDmLM1+adcrQT0dZR+AlfA@public.gmane.org>
>
> The GPU found on NVIDIA Tegra194 SoCs is a Volta generation GPU called
> GV11B.
>
> Signed-off-by: Thierry Reding <treding-DDmLM1+adcrQT0dZR+AlfA@public.gmane.org>
> ---
> arch/arm64/boot/dts/nvidia/tegra194.dtsi | 33 ++++++++++++++++++++++++
> 1 file changed, 33 insertions(+)
>
> diff --git a/arch/arm64/boot/dts/nvidia/tegra194.dtsi b/arch/arm64/boot/dts/nvidia/tegra194.dtsi
> index 259e40469908..f559fe983ebe 100644
> --- a/arch/arm64/boot/dts/nvidia/tegra194.dtsi
> +++ b/arch/arm64/boot/dts/nvidia/tegra194.dtsi
> @@ -1395,6 +1395,39 @@ sor3: sor@15bc0000 {
> nvidia,interface = <3>;
> };
> };
> +
> + gpu@17000000 {
> + compatible = "nvidia,gv11b";
I think we also need to add the to binding doc.
> + reg = <0x17000000 0x10000000>,
> + <0x18000000 0x10000000>;
> + interrupts = <GIC_SPI 70 IRQ_TYPE_LEVEL_HIGH>,
> + <GIC_SPI 71 IRQ_TYPE_LEVEL_HIGH>;
> + interrupt-names = "stall", "nonstall";
> + clocks = <&bpmp TEGRA194_CLK_GPCCLK>,
> + <&bpmp TEGRA194_CLK_GPU_PWR>;
> + clock-names = "gpu", "pwr";
> + resets = <&bpmp TEGRA194_RESET_GPU>;
> + reset-names = "gpu";
> + status = "disabled";
> +
> + power-domains = <&bpmp TEGRA194_POWER_DOMAIN_GPU>;
> + interconnects = <&mc TEGRA194_MEMORY_CLIENT_NVL1R &emc>,
> + <&mc TEGRA194_MEMORY_CLIENT_NVL1RHP &emc>,
> + <&mc TEGRA194_MEMORY_CLIENT_NVL1W &emc>,
> + <&mc TEGRA194_MEMORY_CLIENT_NVL2R &emc>,
> + <&mc TEGRA194_MEMORY_CLIENT_NVL2RHP &emc>,
> + <&mc TEGRA194_MEMORY_CLIENT_NVL2W &emc>,
> + <&mc TEGRA194_MEMORY_CLIENT_NVL3R &emc>,
> + <&mc TEGRA194_MEMORY_CLIENT_NVL3RHP &emc>,
> + <&mc TEGRA194_MEMORY_CLIENT_NVL3W &emc>,
> + <&mc TEGRA194_MEMORY_CLIENT_NVL4R &emc>,
> + <&mc TEGRA194_MEMORY_CLIENT_NVL4RHP &emc>,
> + <&mc TEGRA194_MEMORY_CLIENT_NVL4W &emc>;
> + interconnect-names = "dma-mem", "read-0-hp", "write-0",
> + "read-1", "read-1-hp", "write-1",
> + "read-2", "read-2-hp", "write-2",
> + "read-3", "read-3-hp", "write-3";
> + };
> };
I also see that for gv11b we populate 'dma-coherent' and so we should
probably add this as well.
Cheers
Jon
--
nvpublic
^ permalink raw reply
* Re: [PATCH] imx219: selection compliance fixes
From: Laurent Pinchart @ 2020-07-16 12:59 UTC (permalink / raw)
To: Hans Verkuil
Cc: Jacopo Mondi, Linux Media Mailing List, Sowjanya Komatineni,
Sakari Ailus, Ricardo Ribalda Delgado, libcamera-devel
In-Reply-To: <5adade02-c863-1473-8c71-65f49be5e5b3@xs4all.nl>
Hi Hans,
On Thu, Jul 16, 2020 at 11:48:19AM +0200, Hans Verkuil wrote:
> On 15/07/2020 09:19, Jacopo Mondi wrote:
> > On Wed, Jul 15, 2020 at 02:49:38AM +0300, Laurent Pinchart wrote:
> >> On Tue, Jul 14, 2020 at 02:31:46PM +0200, Jacopo Mondi wrote:
> >>> On Thu, Jul 02, 2020 at 03:50:04PM +0200, Hans Verkuil wrote:
> >>>> The top/left crop coordinates were 0, 0 instead of 8, 8 in the
> >>>> supported_modes array. This was a mismatch with the default values,
> >>>> so this is corrected. Found with v4l2-compliance.
> >>>>
> >>>> Also add V4L2_SEL_TGT_CROP_BOUNDS support: CROP_DEFAULT and CROP_BOUNDS
> >>>> always go together. Found with v4l2-compliance.
> >>>
> >>> I actually introduced this with
> >>> e6d4ef7d58aa ("media: i2c: imx219: Implement get_selection")
> >>>
> >>>>
> >>>> Signed-off-by: Hans Verkuil <hverkuil-cisco@xs4all.nl>
> >>>> ---
> >>>> drivers/media/i2c/imx219.c | 17 +++++++++--------
> >>>> 1 file changed, 9 insertions(+), 8 deletions(-)
> >>>>
> >>>> diff --git a/drivers/media/i2c/imx219.c b/drivers/media/i2c/imx219.c
> >>>> index 0a546b8e466c..935e2a258ce5 100644
> >>>> --- a/drivers/media/i2c/imx219.c
> >>>> +++ b/drivers/media/i2c/imx219.c
> >>>> @@ -473,8 +473,8 @@ static const struct imx219_mode supported_modes[] = {
> >>>> .width = 3280,
> >>>> .height = 2464,
> >>>> .crop = {
> >>>> - .left = 0,
> >>>> - .top = 0,
> >>>> + .left = 8,
> >>>> + .top = 8,
> >>>
> >>> Mmmm, why this change ?
> >>> This values are used to report V4L2_SEL_TGT_CROP rectangle, which
> >>> according to the documentation is defined as
> >>> "Crop rectangle. Defines the cropped area."
> >>> (not a much extensive description :)
>
> Unless changed by calling S_SELECTION(TGT_CROP) the initial crop is equal
> to TGT_CROP_DEFAULT, and but TGT_CROP and TGT_CROP_DEFAULT shall be inside
> TGT_CROP_BOUNDS. CROP_BOUNDS may be larger than CROP_DEFAULT and describes
> the whole area from which you can crop. I.e. in the case of sensors you can
> set the crop rectangle to include optical blanks active pixels.
>
> In this driver the initial TGT_CROP rectangle as specified in supported_modes
> (aligned with the top-left pixel) was outside CROP_BOUNDS (centered) and also
> a mismatch with CROP_DEFAULT (also centered).
>
> >>> Clearly this is a faulty definition, and I know from experience how
> >>> hard is proving to define pixel array properties and in which extent
> >>> the documentation has to go:
> >>> https://lists.libcamera.org/pipermail/libcamera-devel/2020-June/009115.html
> >>>
> >>> My understanding is that target should report the current crop
> >>> rectangle, defined from the rectangle retrieved with the
> >>> V4L2_SEL_TGT_CROP_DEFAULT target, which, according documentation
> >>> reports the:
> >>> "Suggested cropping rectangle that covers the “whole picture”.
> >>> This includes only active pixels and excludes other non-active pixels such
> >>> as black pixels"
> >>>
> >>> The TGT_CROP_DEFAULT then reports the active pixel array portion, and
> >>> needs to be defined in respect to the TGT_NATIVE_SIZE, which reports
> >>> the dimensions of the whole pixel matrix, including non-active pixels,
> >>> optical blanks active and non-active pixels.
>
> The relationship between NATIVE_SIZE and CROP_BOUNDS is not properly defined,
> but I would expect that CROP_BOUNDS is inside the NATIVE_SIZE target rectangle.
>
> If NATIVE_SIZE is larger than BOUNDS, then I would expect that the additional
> margins are pixels that are invalid or otherwise useless.
>
> The hard rule though is that you can crop anywhere within the CROP_BOUNDS area.
>
> Historically CROP_BOUNDS originated with analog SDTV video capture where it was
> possible to capture more data than just the typical 720x576/480 PAL/NTSC active
> video area. Analog video was often overscanned, i.e. there was more video data
> outside the 'active' video area. That was how CRTs worked. So you could move the
> crop window around within the CROP_BOUNDS area, or just capture the full CROP_BOUNDS
> are. Although this was often poorly tested/implemented. The bttv driver is one of
> the few that could do this.
>
> This is actually simplified since you could do weird things with the horizontal
> sample rate as well, effectively changing the pixel aspect ratio, making things
> really complicated. It's analog video so while the video lines were discrete,
> horizontally you are just sampling a waveform, so you could sample at different
> rates if you wanted to. I doubt anyone ever used it since doing that would give
> you a huge headache :-)
>
> With digital video interfaces (HDMI, DVI, SDI, DP, etc.) that no longer applies and
> for those receivers the initial CROP/CROP_DEFAULT/CROP_BOUNDS rectangles are all
> the same, e.g. 1920x1080 for 1080p HDMI video.
>
> >>>
> >>> The TGT_CROP rectangle is hence defined from the CROP_DEFAULT one, and
> >>> if the 'whole active area' is selected, its top-left corner is placed
> >>> in position (0, 0) (what's the point of defining it in respect to an
> >>> area which cannot be read anyway ?)
> >>>
> >>> Unless TGT_CROP should be defined in respect to the NATIVE_SIZE
> >>> rectangle too, but that's not specified anywhere.
> >>>
> >>> Anyway, those selection targets badly apply to image sensors, are
> >>> ill-defined as the definition of active pixels, optical blank (active
> >>> and non-active) pixels is not provided anywhere, and it's not specified
> >>> anywhere what is the reference area for each of those rectangles, so I
> >>> might very well got them wrongly.
> >>
> >> My understanding is that both TGT_CROP_DEFAULT and TGT_CROP_BOUNDS are
> >> relative to TGT_NATIVE_SIZE. BOUNDS defines all the pixels that can be
> >
> > And what is TGT_CROP reference in your understanding ?
>
> That's the rectangle you are actually cropping. Initially CROP == CROP_DEFAULT
> and CROP shall always be inside CROP_BOUNDS. And CROP_BOUNDS shall be equal
> or larger than CROP_DEFAULT.
I think you've missed the point of Jacopo's question. He wasn't asking
if CROP needed to be inside CROP_BOUNDS, but what the reference was for
the left and top coordinates. That is, for all the crop rectangles, what
is the location of the (0,0) point ? Do they all refer to the same
location, or are they relative to each other ? This is not defined.
> >> captured, including optical black and invalid pixels, while DEFAULT
> >> defines the active area, excluding optical black and invalida pixels. To
> >> put it another way, DEFAULT is what the kernel recommends applications
> >> to use if they have no specific requirement and/or no specific knowledge
> >> about the sensor.
> >>
> >> I fully agree this is very under-documented, which also means that my
> >> understanding may be wrong :-)
> >
> > With some consensus on this interpretation I would be happy to update
> > the documentation. I already considered that, but the selection API
> > does not apply to image sensors only, and giving a description which
> > is about the pixel array properties might be not totally opportune as
> > it would rule out other devices like bridges or muxers.
>
> And m2m devices like codecs.
>
> >>>> .width = 3280,
> >>>> .height = 2464
> >>>> },
> >>>> @@ -489,8 +489,8 @@ static const struct imx219_mode supported_modes[] = {
> >>>> .width = 1920,
> >>>> .height = 1080,
> >>>> .crop = {
> >>>> - .left = 680,
> >>>> - .top = 692,
> >>>> + .left = 8 + 680,
> >>>> + .top = 8 + 692,
> >>>> .width = 1920,
> >>>> .height = 1080
> >>>> },
> >>>> @@ -505,8 +505,8 @@ static const struct imx219_mode supported_modes[] = {
> >>>> .width = 1640,
> >>>> .height = 1232,
> >>>> .crop = {
> >>>> - .left = 0,
> >>>> - .top = 0,
> >>>> + .left = 8,
> >>>> + .top = 8,
> >>>> .width = 3280,
> >>>> .height = 2464
> >>>> },
> >>>> @@ -521,8 +521,8 @@ static const struct imx219_mode supported_modes[] = {
> >>>> .width = 640,
> >>>> .height = 480,
> >>>> .crop = {
> >>>> - .left = 1000,
> >>>> - .top = 752,
> >>>> + .left = 8 + 1000,
> >>>> + .top = 8 + 752,
> >>>> .width = 1280,
> >>>> .height = 960
> >>>> },
> >>>> @@ -1014,6 +1014,7 @@ static int imx219_get_selection(struct v4l2_subdev *sd,
> >>>> return 0;
> >>>>
> >>>> case V4L2_SEL_TGT_CROP_DEFAULT:
> >>>> + case V4L2_SEL_TGT_CROP_BOUNDS:
> >>>
> >>> Still not getting what is the purpose of two targets if the "always
> >>> have to go together" :)
> >>>
> >>>> sel->r.top = IMX219_PIXEL_ARRAY_TOP;
> >>>> sel->r.left = IMX219_PIXEL_ARRAY_LEFT;
> >>>> sel->r.width = IMX219_PIXEL_ARRAY_WIDTH;
--
Regards,
Laurent Pinchart
^ permalink raw reply
* [RESEND PATCH v2 2/2] ARM: dts: colibri-imx7: add usb dual-role switch capability
From: Philippe Schenker @ 2020-07-16 12:58 UTC (permalink / raw)
To: devicetree, Shawn Guo, Ahmad Fatoum
Cc: Philippe Schenker, Fabio Estevam, NXP Linux Team,
Pengutronix Kernel Team, Rob Herring, Sascha Hauer,
linux-arm-kernel, linux-kernel
In-Reply-To: <20200716125831.796904-1-philippe.schenker@toradex.com>
Since the runtime-pm wakeup bug was fixed in
drivers/usb/chipidea/core.c usb dual-role host/device switching is
working. So make use of it.
Signed-off-by: Philippe Schenker <philippe.schenker@toradex.com>
---
arch/arm/boot/dts/imx7-colibri-eval-v3.dtsi | 9 +++++++++
arch/arm/boot/dts/imx7-colibri.dtsi | 4 ++--
2 files changed, 11 insertions(+), 2 deletions(-)
diff --git a/arch/arm/boot/dts/imx7-colibri-eval-v3.dtsi b/arch/arm/boot/dts/imx7-colibri-eval-v3.dtsi
index 97601375f264..db56a532a34a 100644
--- a/arch/arm/boot/dts/imx7-colibri-eval-v3.dtsi
+++ b/arch/arm/boot/dts/imx7-colibri-eval-v3.dtsi
@@ -20,6 +20,14 @@ clk16m: clk16m {
clock-frequency = <16000000>;
};
+ extcon_usbc_det: usbc_det {
+ compatible = "linux,extcon-usb-gpio";
+ id-gpio = <&gpio7 14 GPIO_ACTIVE_HIGH>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_usbc_det>;
+ };
+
+
gpio-keys {
compatible = "gpio-keys";
pinctrl-names = "default";
@@ -174,6 +182,7 @@ &uart3 {
};
&usbotg1 {
+ extcon = <0>, <&extcon_usbc_det>;
status = "okay";
};
diff --git a/arch/arm/boot/dts/imx7-colibri.dtsi b/arch/arm/boot/dts/imx7-colibri.dtsi
index e18e89dec879..caea90d2421f 100644
--- a/arch/arm/boot/dts/imx7-colibri.dtsi
+++ b/arch/arm/boot/dts/imx7-colibri.dtsi
@@ -457,7 +457,7 @@ &uart3 {
};
&usbotg1 {
- dr_mode = "host";
+ dr_mode = "otg";
};
&usdhc1 {
@@ -486,7 +486,7 @@ &usdhc3 {
&iomuxc {
pinctrl-names = "default";
pinctrl-0 = <&pinctrl_gpio1 &pinctrl_gpio2 &pinctrl_gpio3 &pinctrl_gpio4
- &pinctrl_gpio7 &pinctrl_usbc_det>;
+ &pinctrl_gpio7>;
pinctrl_gpio1: gpio1-grp {
fsl,pins = <
--
2.27.0
^ permalink raw reply related
* [RESEND PATCH v2 1/2] ARM: dts: colibri-imx6: add usb dual-role switch capability
From: Philippe Schenker @ 2020-07-16 12:58 UTC (permalink / raw)
To: devicetree, Shawn Guo, Ahmad Fatoum
Cc: Philippe Schenker, Fabio Estevam, NXP Linux Team,
Pengutronix Kernel Team, Rob Herring, Sascha Hauer,
linux-arm-kernel, linux-kernel
In-Reply-To: <20200716125831.796904-1-philippe.schenker@toradex.com>
Since the runtime-pm wakeup bug was fixed in
drivers/usb/chipidea/core.c usb dual-role host/device switching is
working. So make use of it.
Signed-off-by: Philippe Schenker <philippe.schenker@toradex.com>
---
arch/arm/boot/dts/imx6dl-colibri-eval-v3.dts | 8 ++++++++
arch/arm/boot/dts/imx6qdl-colibri.dtsi | 2 +-
2 files changed, 9 insertions(+), 1 deletion(-)
diff --git a/arch/arm/boot/dts/imx6dl-colibri-eval-v3.dts b/arch/arm/boot/dts/imx6dl-colibri-eval-v3.dts
index 65359aece950..c978b3f19a2d 100644
--- a/arch/arm/boot/dts/imx6dl-colibri-eval-v3.dts
+++ b/arch/arm/boot/dts/imx6dl-colibri-eval-v3.dts
@@ -45,6 +45,13 @@ clk16m: clock-16m {
clock-output-names = "clk16m";
};
+ extcon_usbc_det: usbc_det {
+ compatible = "linux,extcon-usb-gpio";
+ id-gpio = <&gpio7 12 GPIO_ACTIVE_HIGH>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_usbc_det>;
+ };
+
gpio-keys {
compatible = "gpio-keys";
pinctrl-names = "default";
@@ -220,6 +227,7 @@ &usbh1 {
};
&usbotg {
+ extcon = <0>, <&extcon_usbc_det>;
status = "okay";
};
diff --git a/arch/arm/boot/dts/imx6qdl-colibri.dtsi b/arch/arm/boot/dts/imx6qdl-colibri.dtsi
index 240b86d2eb71..34130f23ceaa 100644
--- a/arch/arm/boot/dts/imx6qdl-colibri.dtsi
+++ b/arch/arm/boot/dts/imx6qdl-colibri.dtsi
@@ -364,7 +364,7 @@ &uart3 {
&usbotg {
pinctrl-names = "default";
disable-over-current;
- dr_mode = "peripheral";
+ dr_mode = "otg";
status = "disabled";
};
--
2.27.0
^ permalink raw reply related
* [RESEND PATCH v2 0/2] Adding USB dual-role switching support for colibri-imx6/7 with extcon
From: Philippe Schenker @ 2020-07-16 12:58 UTC (permalink / raw)
To: devicetree, Shawn Guo, Ahmad Fatoum
Cc: Philippe Schenker, Fabio Estevam, NXP Linux Team,
Pengutronix Kernel Team, Rob Herring, Sascha Hauer,
linux-arm-kernel, linux-kernel
Hi Shawn,
This is a friendly reminder as I think the two patches in this patchset
got forgotten to pull back in.
Ahmad pointed out that extcon is legacy and I should better use the new
gpio-usb-b-connector compatible for that purpose. You removed those two
patches upon this recommendation.
In the meantime it turned out that I cannot use the new usb-connector
way of switching usb dual-role. This is due to Chipidea driver not
supporting it and Ahmad is fine using extcon for it.
I would be glad if you could pull those two patches back in.
Thanks,
Philippe
Philippe Schenker (2):
ARM: dts: colibri-imx6: add usb dual-role switch capability
ARM: dts: colibri-imx7: add usb dual-role switch capability
arch/arm/boot/dts/imx6dl-colibri-eval-v3.dts | 8 ++++++++
arch/arm/boot/dts/imx6qdl-colibri.dtsi | 2 +-
arch/arm/boot/dts/imx7-colibri-eval-v3.dtsi | 9 +++++++++
arch/arm/boot/dts/imx7-colibri.dtsi | 4 ++--
4 files changed, 20 insertions(+), 3 deletions(-)
--
2.27.0
^ permalink raw reply
* [PATCH v3 net-next 00/16] sfc_ef100: driver for EF100 family NICs, part 1
From: Edward Cree @ 2020-07-16 12:57 UTC (permalink / raw)
To: linux-net-drivers, davem; +Cc: netdev
EF100 is a new NIC architecture under development at Xilinx, based
partly on existing Solarflare technology. As many of the hardware
interfaces resemble EF10, the driver is implemented largely through
libraries of code from the 'sfc' driver, which previous patch series
"commonised" for this purpose.
The new driver is called 'sfc_ef100'.
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).
Changes from v2:
* remove MODULE_VERSION.
* call efx_destroy_reset_workqueue() from ef100_exit_module().
* correct uint32_ts to u32s. While I was at it, I fixed a bunch of
other style issues in the function-control-window code.
All in patch #4.
Changes from v1:
* kernel test robot spotted a link error when sfc_ef100 was built
without mdio. It turns out the thing we were trying to link to
was a bogus thing to do on anything but Falcon, so new patch #1
removes it from this driver.
* fix undeclared symbols in patch #4 by shuffling around prototypes
and #includes and adding 'static' where appropriate.
* fix uninitialised variable 'rc2' in patch #7.
Edward Cree (16):
sfc: remove efx_ethtool_nway_reset()
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/ef10.c | 1 +
drivers/net/ethernet/sfc/ef100.c | 577 ++++++++++++++++++
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 | 31 +
drivers/net/ethernet/sfc/ef100_rx.h | 19 +
drivers/net/ethernet/sfc/ef100_tx.c | 63 ++
drivers/net/ethernet/sfc/ef100_tx.h | 22 +
drivers/net/ethernet/sfc/efx.h | 1 -
drivers/net/ethernet/sfc/efx_common.c | 11 +-
drivers/net/ethernet/sfc/ethtool.c | 1 -
drivers/net/ethernet/sfc/ethtool_common.c | 8 -
drivers/net/ethernet/sfc/ethtool_common.h | 1 -
drivers/net/ethernet/sfc/io.h | 16 +-
drivers/net/ethernet/sfc/mcdi.h | 4 +-
drivers/net/ethernet/sfc/net_driver.h | 14 +-
drivers/net/ethernet/sfc/tx_common.h | 2 +
24 files changed, 2449 insertions(+), 20 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
* Re: [PATCH] opp: Increase parsed_static_opps on _of_add_opp_table_v1
From: Walter Lozano @ 2020-07-16 12:57 UTC (permalink / raw)
To: Viresh Kumar
Cc: linux-pm, kernel, Nishanth Menon, Stephen Boyd, Viresh Kumar,
linux-kernel
In-Reply-To: <20200716032259.l5ybqetpg74ybogh@vireshk-i7>
Hi Viresh,
On 16/7/20 00:22, Viresh Kumar wrote:
> On 15-07-20, 23:54, Walter Lozano wrote:
>> Currently, when using _of_add_opp_table_v2 parsed_static_opps is
>> increased and this value is used on _opp_remove_all_static to
>> check if there are static opps entries that need to be freed.
>> Unfortunately this does not happens when using _of_add_opp_table_v1,
>> which leads to warnings.
>>
>> This patch increases parsed_static_opps on _of_add_opp_table_v1 in a
>> similar way as in _of_add_opp_table_v2.
>>
>> Signed-off-by: Walter Lozano <walter.lozano@collabora.com>
>> ---
>>
>> drivers/opp/of.c | 2 ++
>> 1 file changed, 2 insertions(+)
>>
>> diff --git a/drivers/opp/of.c b/drivers/opp/of.c
>> index 9a5873591a40..b2bc82bf8b42 100644
>> --- a/drivers/opp/of.c
>> +++ b/drivers/opp/of.c
>> @@ -917,6 +917,8 @@ static int _of_add_opp_table_v1(struct device *dev, struct opp_table *opp_table)
>> nr -= 2;
>> }
>>
>> + opp_table->parsed_static_opps++;
>> +
>> return ret;
>> }
> Merged with this and added relevant Fixes and stable tags.
Thanks for apply the proper fix.
>
> diff --git a/drivers/opp/of.c b/drivers/opp/of.c
> index b2bc82bf8b42..314f306140a1 100644
> --- a/drivers/opp/of.c
> +++ b/drivers/opp/of.c
> @@ -902,6 +902,10 @@ static int _of_add_opp_table_v1(struct device *dev, struct opp_table *opp_table)
> return -EINVAL;
> }
>
> + mutex_lock(&opp_table->lock);
> + opp_table->parsed_static_opps = 1;
> + mutex_unlock(&opp_table->lock);
> +
> val = prop->value;
> while (nr) {
> unsigned long freq = be32_to_cpup(val++) * 1000;
> @@ -917,8 +921,6 @@ static int _of_add_opp_table_v1(struct device *dev, struct opp_table *opp_table)
> nr -= 2;
> }
>
> - opp_table->parsed_static_opps++;
> -
> return ret;
> }
>
^ permalink raw reply
* [PATCHv2 2/4] ARM: dts: omap: add channel to DSI panels
From: Sebastian Reichel @ 2020-07-16 12:57 UTC (permalink / raw)
To: Sebastian Reichel, Tomi Valkeinen, Sam Ravnborg, Tony Lindgren
Cc: Pavel Machek, Merlijn Wajer, Laurent Pinchart,
H. Nikolaus Schaller, Rob Herring, dri-devel, devicetree,
linux-omap, kernel, Sebastian Reichel
In-Reply-To: <20200716125733.83654-1-sebastian.reichel@collabora.com>
The standard binding for DSI requires that the channel number
of the panel is encoded in DT. This adds the channel number in
all OMAP3-5 boards in preparation for using common infrastructure.
Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Signed-off-by: Sebastian Reichel <sebastian.reichel@collabora.com>
---
arch/arm/boot/dts/motorola-mapphone-common.dtsi | 3 ++-
arch/arm/boot/dts/omap3-n950.dts | 3 ++-
arch/arm/boot/dts/omap3.dtsi | 3 +++
arch/arm/boot/dts/omap4-sdp.dts | 6 ++++--
arch/arm/boot/dts/omap4.dtsi | 6 ++++++
arch/arm/boot/dts/omap5.dtsi | 6 ++++++
6 files changed, 23 insertions(+), 4 deletions(-)
diff --git a/arch/arm/boot/dts/motorola-mapphone-common.dtsi b/arch/arm/boot/dts/motorola-mapphone-common.dtsi
index 06fbffa81636..4ffe461c3808 100644
--- a/arch/arm/boot/dts/motorola-mapphone-common.dtsi
+++ b/arch/arm/boot/dts/motorola-mapphone-common.dtsi
@@ -207,8 +207,9 @@ dsi1_out_ep: endpoint {
};
};
- lcd0: display {
+ lcd0: panel@0 {
compatible = "panel-dsi-cm";
+ reg = <0>;
label = "lcd0";
vddi-supply = <&lcd_regulator>;
reset-gpios = <&gpio4 5 GPIO_ACTIVE_HIGH>; /* gpio101 */
diff --git a/arch/arm/boot/dts/omap3-n950.dts b/arch/arm/boot/dts/omap3-n950.dts
index 31d47a1fad84..80cf4e1177da 100644
--- a/arch/arm/boot/dts/omap3-n950.dts
+++ b/arch/arm/boot/dts/omap3-n950.dts
@@ -225,8 +225,9 @@ dsi_out_ep: endpoint {
};
};
- lcd0: display {
+ lcd0: panel@0 {
compatible = "nokia,himalaya", "panel-dsi-cm";
+ reg = <0>;
label = "lcd0";
pinctrl-names = "default";
diff --git a/arch/arm/boot/dts/omap3.dtsi b/arch/arm/boot/dts/omap3.dtsi
index 1296d0643943..0ebbb6c11f04 100644
--- a/arch/arm/boot/dts/omap3.dtsi
+++ b/arch/arm/boot/dts/omap3.dtsi
@@ -898,6 +898,9 @@ dsi: encoder@4804fc00 {
ti,hwmods = "dss_dsi1";
clocks = <&dss1_alwon_fck>, <&dss2_alwon_fck>;
clock-names = "fck", "sys_clk";
+
+ #address-cells = <1>;
+ #size-cells = <0>;
};
rfbi: encoder@48050800 {
diff --git a/arch/arm/boot/dts/omap4-sdp.dts b/arch/arm/boot/dts/omap4-sdp.dts
index 91480ac1f328..8a8307517dab 100644
--- a/arch/arm/boot/dts/omap4-sdp.dts
+++ b/arch/arm/boot/dts/omap4-sdp.dts
@@ -662,8 +662,9 @@ dsi1_out_ep: endpoint {
};
};
- lcd0: display {
+ lcd0: panel@0 {
compatible = "tpo,taal", "panel-dsi-cm";
+ reg = <0>;
label = "lcd0";
reset-gpios = <&gpio4 6 GPIO_ACTIVE_HIGH>; /* 102 */
@@ -687,8 +688,9 @@ dsi2_out_ep: endpoint {
};
};
- lcd1: display {
+ lcd1: panel@0 {
compatible = "tpo,taal", "panel-dsi-cm";
+ reg = <0>;
label = "lcd1";
reset-gpios = <&gpio4 8 GPIO_ACTIVE_HIGH>; /* 104 */
diff --git a/arch/arm/boot/dts/omap4.dtsi b/arch/arm/boot/dts/omap4.dtsi
index 4400f5f8e099..c5b426616443 100644
--- a/arch/arm/boot/dts/omap4.dtsi
+++ b/arch/arm/boot/dts/omap4.dtsi
@@ -551,6 +551,9 @@ dsi1: encoder@0 {
clocks = <&l3_dss_clkctrl OMAP4_DSS_CORE_CLKCTRL 8>,
<&l3_dss_clkctrl OMAP4_DSS_CORE_CLKCTRL 10>;
clock-names = "fck", "sys_clk";
+
+ #address-cells = <1>;
+ #size-cells = <0>;
};
};
@@ -583,6 +586,9 @@ dsi2: encoder@0 {
clocks = <&l3_dss_clkctrl OMAP4_DSS_CORE_CLKCTRL 8>,
<&l3_dss_clkctrl OMAP4_DSS_CORE_CLKCTRL 10>;
clock-names = "fck", "sys_clk";
+
+ #address-cells = <1>;
+ #size-cells = <0>;
};
};
diff --git a/arch/arm/boot/dts/omap5.dtsi b/arch/arm/boot/dts/omap5.dtsi
index fb889c5b00c9..0855c0a4050f 100644
--- a/arch/arm/boot/dts/omap5.dtsi
+++ b/arch/arm/boot/dts/omap5.dtsi
@@ -491,6 +491,9 @@ dsi1: encoder@0 {
status = "disabled";
clocks = <&dss_clkctrl OMAP5_DSS_CORE_CLKCTRL 8>;
clock-names = "fck";
+
+ #address-cells = <1>;
+ #size-cells = <0>;
};
};
@@ -522,6 +525,9 @@ dsi2: encoder@0 {
status = "disabled";
clocks = <&dss_clkctrl OMAP5_DSS_CORE_CLKCTRL 8>;
clock-names = "fck";
+
+ #address-cells = <1>;
+ #size-cells = <0>;
};
};
--
2.27.0
^ permalink raw reply related
* [PATCHv2 1/4] dt-bindings: display: panel-dsi-cm: convert to YAML
From: Sebastian Reichel @ 2020-07-16 12:57 UTC (permalink / raw)
To: Sebastian Reichel, Tomi Valkeinen, Sam Ravnborg, Tony Lindgren
Cc: Pavel Machek, Merlijn Wajer, Laurent Pinchart,
H. Nikolaus Schaller, Rob Herring, dri-devel, devicetree,
linux-omap, kernel, Sebastian Reichel, Rob Herring
In-Reply-To: <20200716125733.83654-1-sebastian.reichel@collabora.com>
Convert panel-dsi-cm bindings to YAML and add
missing properties while at it.
Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Reviewed-by: Rob Herring <robh@kernel.org>
Signed-off-by: Sebastian Reichel <sebastian.reichel@collabora.com>
---
.../bindings/display/panel/panel-dsi-cm.txt | 29 -------
.../bindings/display/panel/panel-dsi-cm.yaml | 86 +++++++++++++++++++
2 files changed, 86 insertions(+), 29 deletions(-)
delete mode 100644 Documentation/devicetree/bindings/display/panel/panel-dsi-cm.txt
create mode 100644 Documentation/devicetree/bindings/display/panel/panel-dsi-cm.yaml
diff --git a/Documentation/devicetree/bindings/display/panel/panel-dsi-cm.txt b/Documentation/devicetree/bindings/display/panel/panel-dsi-cm.txt
deleted file mode 100644
index dce48eb9db57..000000000000
--- a/Documentation/devicetree/bindings/display/panel/panel-dsi-cm.txt
+++ /dev/null
@@ -1,29 +0,0 @@
-Generic MIPI DSI Command Mode Panel
-===================================
-
-Required properties:
-- compatible: "panel-dsi-cm"
-
-Optional properties:
-- label: a symbolic name for the panel
-- reset-gpios: panel reset gpio
-- te-gpios: panel TE gpio
-
-Required nodes:
-- Video port for DSI input
-
-Example
--------
-
-lcd0: display {
- compatible = "tpo,taal", "panel-dsi-cm";
- label = "lcd0";
-
- reset-gpios = <&gpio4 6 GPIO_ACTIVE_HIGH>;
-
- port {
- lcd0_in: endpoint {
- remote-endpoint = <&dsi1_out_ep>;
- };
- };
-};
diff --git a/Documentation/devicetree/bindings/display/panel/panel-dsi-cm.yaml b/Documentation/devicetree/bindings/display/panel/panel-dsi-cm.yaml
new file mode 100644
index 000000000000..d766c949c622
--- /dev/null
+++ b/Documentation/devicetree/bindings/display/panel/panel-dsi-cm.yaml
@@ -0,0 +1,86 @@
+# SPDX-License-Identifier: (GPL-2.0-only or BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/display/panel/panel-dsi-cm.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: DSI command mode panels
+
+maintainers:
+ - Tomi Valkeinen <tomi.valkeinen@ti.com>
+ - Sebastian Reichel <sre@kernel.org>
+
+description: |
+ This binding file is a collection of the DSI panels that
+ are usually driven in command mode. If no backlight is
+ referenced via the optional backlight property, the DSI
+ panel is assumed to have native backlight support.
+ The panel may use an OF graph binding for the association
+ to the display, or it may be a direct child node of the
+ display.
+
+allOf:
+ - $ref: panel-common.yaml#
+
+properties:
+
+ compatible:
+ items:
+ - enum:
+ - motorola,droid4-panel # Panel from Motorola Droid4 phone
+ - nokia,himalaya # Panel from Nokia N950 phone
+ - tpo,taal # Panel from OMAP4 SDP board
+ - const: panel-dsi-cm # Generic DSI command mode panel compatible fallback
+
+ reg:
+ maxItems: 1
+ description: DSI virtual channel
+
+ vddi-supply:
+ description:
+ Display panels require power to be supplied. While several panels need
+ more than one power supply with panel-specific constraints governing the
+ order and timings of the power supplies, in many cases a single power
+ supply is sufficient, either because the panel has a single power rail, or
+ because all its power rails can be driven by the same supply. In that case
+ the vddi-supply property specifies the supply powering the panel as a
+ phandle to a regulator.
+
+ vpnl-supply:
+ description:
+ When the display panel needs a second power supply, this property can be
+ used in addition to vddi-supply. Both supplies will be enabled at the
+ same time before the panel is being accessed.
+
+ width-mm: true
+ height-mm: true
+ label: true
+ rotation: true
+ panel-timing: true
+ port: true
+ reset-gpios: true
+ te-gpios: true
+ backlight: true
+
+additionalProperties: false
+
+required:
+ - compatible
+ - reg
+
+examples:
+ - |
+ #include <dt-bindings/gpio/gpio.h>
+
+ dsi-controller {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ panel@0 {
+ compatible = "tpo,taal", "panel-dsi-cm";
+ reg = <0>;
+ reset-gpios = <&gpio4 6 GPIO_ACTIVE_HIGH>;
+ };
+ };
+
+...
--
2.27.0
^ permalink raw reply related
* [PATCHv2 4/4] ARM: dts: omap4-droid4: add panel orientation
From: Sebastian Reichel @ 2020-07-16 12:57 UTC (permalink / raw)
To: Sebastian Reichel, Tomi Valkeinen, Sam Ravnborg, Tony Lindgren
Cc: Pavel Machek, Merlijn Wajer, Laurent Pinchart,
H. Nikolaus Schaller, Rob Herring, dri-devel, devicetree,
linux-omap, kernel, Sebastian Reichel
In-Reply-To: <20200716125733.83654-1-sebastian.reichel@collabora.com>
Add information about panel orientation, so that the
system boots into a properly rotated shell.
Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Signed-off-by: Sebastian Reichel <sebastian.reichel@collabora.com>
---
arch/arm/boot/dts/motorola-mapphone-common.dtsi | 1 +
1 file changed, 1 insertion(+)
diff --git a/arch/arm/boot/dts/motorola-mapphone-common.dtsi b/arch/arm/boot/dts/motorola-mapphone-common.dtsi
index 0e22fdfa42aa..e672e714fcbe 100644
--- a/arch/arm/boot/dts/motorola-mapphone-common.dtsi
+++ b/arch/arm/boot/dts/motorola-mapphone-common.dtsi
@@ -218,6 +218,7 @@ lcd0: panel@0 {
width-mm = <50>;
height-mm = <89>;
+ rotation = <90>;
panel-timing {
clock-frequency = <0>; /* Calculated by dsi */
--
2.27.0
^ permalink raw reply related
* [PATCHv2 0/4] Subject: panel-dsi-cm: update bindings
From: Sebastian Reichel @ 2020-07-16 12:57 UTC (permalink / raw)
To: Sebastian Reichel, Tomi Valkeinen, Sam Ravnborg, Tony Lindgren
Cc: Pavel Machek, Merlijn Wajer, Laurent Pinchart,
H. Nikolaus Schaller, Rob Herring, dri-devel, devicetree,
linux-omap, kernel, Sebastian Reichel
The cleanup series for omapdrm's DSI code got too big. Reviewing
this is not fun and the same goes for keeping track of the change
requests. Let's do the cleanup in smaller steps instead. This is
the first batch, which updates the binding (txt -> yaml) and
modifies the DT slightly.
Changes since PATCHv1 [0]:
PATCHv1..PATCHv2:
* Update binding as suggested by Sam
* Remove 'port' from required list
* Drop 'lanes' and 'port' from example ('lanes' is a port property
used by OMAP's DSI controller)
* Drop the label from example
* Add '...' at end of file
* Fix , in patch description from patch 2
* Apply Reviewed-by tags
[0] https://lore.kernel.org/dri-devel/20200629223315.118256-1-sebastian.reichel@collabora.com/
-- Sebastian
Sebastian Reichel (4):
dt-bindings: display: panel-dsi-cm: convert to YAML
ARM: dts: omap: add channel to DSI panels
ARM: dts: omap4-droid4: add panel compatible
ARM: dts: omap4-droid4: add panel orientation
.../bindings/display/panel/panel-dsi-cm.txt | 29 -------
.../bindings/display/panel/panel-dsi-cm.yaml | 86 +++++++++++++++++++
.../boot/dts/motorola-mapphone-common.dtsi | 6 +-
arch/arm/boot/dts/omap3-n950.dts | 3 +-
arch/arm/boot/dts/omap3.dtsi | 3 +
arch/arm/boot/dts/omap4-sdp.dts | 6 +-
arch/arm/boot/dts/omap4.dtsi | 6 ++
arch/arm/boot/dts/omap5.dtsi | 6 ++
8 files changed, 111 insertions(+), 34 deletions(-)
delete mode 100644 Documentation/devicetree/bindings/display/panel/panel-dsi-cm.txt
create mode 100644 Documentation/devicetree/bindings/display/panel/panel-dsi-cm.yaml
--
2.27.0
^ permalink raw reply
* [PATCHv2 3/4] ARM: dts: omap4-droid4: add panel compatible
From: Sebastian Reichel @ 2020-07-16 12:57 UTC (permalink / raw)
To: Sebastian Reichel, Tomi Valkeinen, Sam Ravnborg, Tony Lindgren
Cc: Pavel Machek, Merlijn Wajer, Laurent Pinchart,
H. Nikolaus Schaller, Rob Herring, dri-devel, devicetree,
linux-omap, kernel, Sebastian Reichel
In-Reply-To: <20200716125733.83654-1-sebastian.reichel@collabora.com>
Add Droid 4 specific compatible value in addition to the
generic one, so that we have the ability to add panel
specific quirks in the future.
Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Signed-off-by: Sebastian Reichel <sebastian.reichel@collabora.com>
---
arch/arm/boot/dts/motorola-mapphone-common.dtsi | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/arch/arm/boot/dts/motorola-mapphone-common.dtsi b/arch/arm/boot/dts/motorola-mapphone-common.dtsi
index 4ffe461c3808..0e22fdfa42aa 100644
--- a/arch/arm/boot/dts/motorola-mapphone-common.dtsi
+++ b/arch/arm/boot/dts/motorola-mapphone-common.dtsi
@@ -208,7 +208,7 @@ dsi1_out_ep: endpoint {
};
lcd0: panel@0 {
- compatible = "panel-dsi-cm";
+ compatible = "motorola,droid4-panel", "panel-dsi-cm";
reg = <0>;
label = "lcd0";
vddi-supply = <&lcd_regulator>;
--
2.27.0
^ permalink raw reply related
* [PATCH v2] net: dsa: microchip: call phy_remove_link_mode during probe
From: Helmut Grohne @ 2020-07-16 12:57 UTC (permalink / raw)
To: Andrew Lunn
Cc: Florian Fainelli, Heiner Kallweit, Russell King, David S. Miller,
Jakub Kicinski, netdev, Woojung Huh,
Microchip Linux Driver Support, Vivien Didelot, Tristram Ha
In-Reply-To: <20200715192722.GD1256692@lunn.ch>
When doing "ip link set dev ... up" for a ksz9477 backed link,
ksz9477_phy_setup is called and it calls phy_remove_link_mode to remove
1000baseT HDX. During phy_remove_link_mode, phy_advertise_supported is
called. Doing so reverts any previous change to advertised link modes
e.g. using a udevd .link file.
phy_remove_link_mode is not meant to be used while opening a link and
should be called during phy probe when the link is not yet available to
userspace.
Therefore move the phy_remove_link_mode calls into ksz9477_setup. This
is called during dsa_switch_register and thus comes after
ksz9477_switch_detect, which initializes dev->features.
Remove phy_setup from ksz_dev_ops as no users remain.
Link: https://lore.kernel.org/netdev/20200715192722.GD1256692@lunn.ch/
Fixes: 42fc6a4c613019 ("net: dsa: microchip: prepare PHY for proper advertisement")
Signed-off-by: Helmut Grohne <helmut.grohne@intenta.de>
---
drivers/net/dsa/microchip/ksz9477.c | 31 ++++++++++----------------
drivers/net/dsa/microchip/ksz_common.c | 2 --
drivers/net/dsa/microchip/ksz_common.h | 2 --
3 files changed, 12 insertions(+), 23 deletions(-)
changes since v1:
* Don't change phy_remove_link_mode. Instead, call it at the right
time. Thanks to Andrew Lunn for the detailed explanation.
Helmut
diff --git a/drivers/net/dsa/microchip/ksz9477.c b/drivers/net/dsa/microchip/ksz9477.c
index 8d15c3016024..d0023916e1e8 100644
--- a/drivers/net/dsa/microchip/ksz9477.c
+++ b/drivers/net/dsa/microchip/ksz9477.c
@@ -974,23 +974,6 @@ static void ksz9477_port_mirror_del(struct dsa_switch *ds, int port,
PORT_MIRROR_SNIFFER, false);
}
-static void ksz9477_phy_setup(struct ksz_device *dev, int port,
- struct phy_device *phy)
-{
- /* Only apply to port with PHY. */
- if (port >= dev->phy_port_cnt)
- return;
-
- /* The MAC actually cannot run in 1000 half-duplex mode. */
- phy_remove_link_mode(phy,
- ETHTOOL_LINK_MODE_1000baseT_Half_BIT);
-
- /* PHY does not support gigabit. */
- if (!(dev->features & GBIT_SUPPORT))
- phy_remove_link_mode(phy,
- ETHTOOL_LINK_MODE_1000baseT_Full_BIT);
-}
-
static bool ksz9477_get_gbit(struct ksz_device *dev, u8 data)
{
bool gbit;
@@ -1353,7 +1336,7 @@ static void ksz9477_config_cpu_port(struct dsa_switch *ds)
static int ksz9477_setup(struct dsa_switch *ds)
{
struct ksz_device *dev = ds->priv;
- int ret = 0;
+ int ret = 0, i;
dev->vlan_cache = devm_kcalloc(dev->dev, sizeof(struct vlan_table),
dev->num_vlans, GFP_KERNEL);
@@ -1391,6 +1374,17 @@ static int ksz9477_setup(struct dsa_switch *ds)
ksz_init_mib_timer(dev);
+ for (i = 0; i < dev->phy_port_cnt; ++i) {
+ /* The MAC actually cannot run in 1000 half-duplex mode. */
+ phy_remove_link_mode(&dev->ports[i].phydev,
+ ETHTOOL_LINK_MODE_1000baseT_Half_BIT);
+
+ /* PHY does not support gigabit. */
+ if (!(dev->features & GBIT_SUPPORT))
+ phy_remove_link_mode(&dev->ports[i].phydev,
+ ETHTOOL_LINK_MODE_1000baseT_Full_BIT);
+ }
+
return 0;
}
@@ -1603,7 +1597,6 @@ static const struct ksz_dev_ops ksz9477_dev_ops = {
.get_port_addr = ksz9477_get_port_addr,
.cfg_port_member = ksz9477_cfg_port_member,
.flush_dyn_mac_table = ksz9477_flush_dyn_mac_table,
- .phy_setup = ksz9477_phy_setup,
.port_setup = ksz9477_port_setup,
.r_mib_cnt = ksz9477_r_mib_cnt,
.r_mib_pkt = ksz9477_r_mib_pkt,
diff --git a/drivers/net/dsa/microchip/ksz_common.c b/drivers/net/dsa/microchip/ksz_common.c
index fd1d6676ae4f..7b6c0dce7536 100644
--- a/drivers/net/dsa/microchip/ksz_common.c
+++ b/drivers/net/dsa/microchip/ksz_common.c
@@ -358,8 +358,6 @@ int ksz_enable_port(struct dsa_switch *ds, int port, struct phy_device *phy)
/* setup slave port */
dev->dev_ops->port_setup(dev, port, false);
- if (dev->dev_ops->phy_setup)
- dev->dev_ops->phy_setup(dev, port, phy);
/* port_stp_state_set() will be called after to enable the port so
* there is no need to do anything.
diff --git a/drivers/net/dsa/microchip/ksz_common.h b/drivers/net/dsa/microchip/ksz_common.h
index f2c9bb68fd33..7d11dd32ec0d 100644
--- a/drivers/net/dsa/microchip/ksz_common.h
+++ b/drivers/net/dsa/microchip/ksz_common.h
@@ -119,8 +119,6 @@ struct ksz_dev_ops {
u32 (*get_port_addr)(int port, int offset);
void (*cfg_port_member)(struct ksz_device *dev, int port, u8 member);
void (*flush_dyn_mac_table)(struct ksz_device *dev, int port);
- void (*phy_setup)(struct ksz_device *dev, int port,
- struct phy_device *phy);
void (*port_cleanup)(struct ksz_device *dev, int port);
void (*port_setup)(struct ksz_device *dev, int port, bool cpu_port);
void (*r_phy)(struct ksz_device *dev, u16 phy, u16 reg, u16 *val);
--
2.20.1
^ permalink raw reply related
* Re: [PATCH v2] [RFC] dt-bindings: gpio: introduce hog properties with less ambiguity
From: Linus Walleij @ 2020-07-16 12:57 UTC (permalink / raw)
To: Uwe Kleine-König
Cc: Bartosz Golaszewski, Rob Herring, open list:GPIO SUBSYSTEM,
Sascha Hauer,
open list:OPEN FIRMWARE AND FLATTENED DEVICE TREE BINDINGS
In-Reply-To: <20200711045441.19464-1-u.kleine-koenig@pengutronix.de>
On Sat, Jul 11, 2020 at 6:54 AM Uwe Kleine-König
<u.kleine-koenig@pengutronix.de> wrote:
> For active low lines the semantic of output-low and output-high is hard
> to grasp because there is a double negation involved and so output-low
> is actually a request to drive the line high (aka inactive).
>
> So introduce output-inactive and output-active with the same semantic as
> output-low and output-high respectively have today, but with a more
> sensible name.
>
> Signed-off-by: Uwe Kleine-König <u.kleine-koenig@pengutronix.de>
> ---
> Hello,
>
> compared to (implicit) v1, changed to ..asserted from ...active as Linus
> Walleij suggested.
I'm fine to apply this but would prefer if I can apply it back-to-back
with a patch adding support to the kernel.
I know the bindings and the OS should be decoupled in theory
but ... feels better for me.
Yours,
Linus Walleij
^ permalink raw reply
* [f2fs-dev] [PATCH v3 1/1] f2fs: support zone capacity less than zone size
From: Aravind Ramesh @ 2020-07-16 12:56 UTC (permalink / raw)
To: jaegeuk, yuchao0, linux-fsdevel, linux-f2fs-devel, hch
Cc: niklas.cassel, Damien Le Moal, Aravind Ramesh, matias.bjorling
In-Reply-To: <20200716125656.3662-1-aravind.ramesh@wdc.com>
NVMe Zoned Namespace devices can have zone-capacity less than zone-size.
Zone-capacity indicates the maximum number of sectors that are usable in
a zone beginning from the first sector of the zone. This makes the sectors
sectors after the zone-capacity till zone-size to be unusable.
This patch set tracks zone-size and zone-capacity in zoned devices and
calculate the usable blocks per segment and usable segments per section.
If zone-capacity is less than zone-size mark only those segments which
start before zone-capacity as free segments. All segments at and beyond
zone-capacity are treated as permanently used segments. In cases where
zone-capacity does not align with segment size the last segment will start
before zone-capacity and end beyond the zone-capacity of the zone. For
such spanning segments only sectors within the zone-capacity are used.
During writes and GC manage the usable segments in a section and usable
blocks per segment. Segments which are beyond zone-capacity are never
allocated, and do not need to be garbage collected, only the segments
which are before zone-capacity needs to garbage collected.
For spanning segments based on the number of usable blocks in that
segment, write to blocks only up to zone-capacity.
Zone-capacity is device specific and cannot be configured by the user.
Since NVMe ZNS device zones are sequentially write only, a block device
with conventional zones or any normal block device is needed along with
the ZNS device for the metadata operations of F2fs.
A typical nvme-cli output of a zoned device shows zone start and capacity
and write pointer as below:
SLBA: 0x0 WP: 0x0 Cap: 0x18800 State: EMPTY Type: SEQWRITE_REQ
SLBA: 0x20000 WP: 0x20000 Cap: 0x18800 State: EMPTY Type: SEQWRITE_REQ
SLBA: 0x40000 WP: 0x40000 Cap: 0x18800 State: EMPTY Type: SEQWRITE_REQ
Here zone size is 64MB, capacity is 49MB, WP is at zone start as the zones
are in EMPTY state. For each zone, only zone start + 49MB is usable area,
any lba/sector after 49MB cannot be read or written to, the drive will fail
any attempts to read/write. So, the second zone starts at 64MB and is
usable till 113MB (64 + 49) and the range between 113 and 128MB is
again unusable. The next zone starts at 128MB, and so on.
Signed-off-by: Aravind Ramesh <aravind.ramesh@wdc.com>
Signed-off-by: Damien Le Moal <damien.lemoal@wdc.com>
Signed-off-by: Niklas Cassel <niklas.cassel@wdc.com>
---
Documentation/filesystems/f2fs.rst | 15 +++
fs/f2fs/f2fs.h | 5 +
fs/f2fs/gc.c | 25 +++--
fs/f2fs/gc.h | 44 +++++++-
fs/f2fs/segment.c | 156 ++++++++++++++++++++++++++---
fs/f2fs/segment.h | 26 +++--
fs/f2fs/super.c | 41 ++++++--
7 files changed, 275 insertions(+), 37 deletions(-)
diff --git a/Documentation/filesystems/f2fs.rst b/Documentation/filesystems/f2fs.rst
index 535021c46260..cec2167a31db 100644
--- a/Documentation/filesystems/f2fs.rst
+++ b/Documentation/filesystems/f2fs.rst
@@ -766,3 +766,18 @@ Compress metadata layout::
+-------------+-------------+----------+----------------------------+
| data length | data chksum | reserved | compressed data |
+-------------+-------------+----------+----------------------------+
+
+NVMe Zoned Namespace devices
+----------------------------
+
+- ZNS defines a per-zone capacity which can be equal or less than the
+ zone-size. Zone-capacity is the number of usable blocks in the zone.
+ F2fs checks if zone-capacity is less than zone-size, if it is, then any
+ segment which starts after the zone-capacity is marked as not-free in
+ the free segment bitmap at initial mount time. These segments are marked
+ as permanently used so they are not allocated for writes and
+ consequently are not needed to be garbage collected. In case the
+ zone-capacity is not aligned to default segment size(2MB), then a segment
+ can start before the zone-capacity and span across zone-capacity boundary.
+ Such spanning segments are also considered as usable segments. All blocks
+ past the zone-capacity are considered unusable in these segments.
diff --git a/fs/f2fs/f2fs.h b/fs/f2fs/f2fs.h
index e6e47618a357..73219e4e1ba4 100644
--- a/fs/f2fs/f2fs.h
+++ b/fs/f2fs/f2fs.h
@@ -1232,6 +1232,7 @@ struct f2fs_dev_info {
#ifdef CONFIG_BLK_DEV_ZONED
unsigned int nr_blkz; /* Total number of zones */
unsigned long *blkz_seq; /* Bitmap indicating sequential zones */
+ block_t *zone_capacity_blocks; /* Array of zone capacity in blks */
#endif
};
@@ -3395,6 +3396,10 @@ void f2fs_destroy_segment_manager_caches(void);
int f2fs_rw_hint_to_seg_type(enum rw_hint hint);
enum rw_hint f2fs_io_type_to_rw_hint(struct f2fs_sb_info *sbi,
enum page_type type, enum temp_type temp);
+unsigned int f2fs_usable_segs_in_sec(struct f2fs_sb_info *sbi,
+ unsigned int segno);
+unsigned int f2fs_usable_blks_in_seg(struct f2fs_sb_info *sbi,
+ unsigned int segno);
/*
* checkpoint.c
diff --git a/fs/f2fs/gc.c b/fs/f2fs/gc.c
index 9a40761445d3..429e7dae807d 100644
--- a/fs/f2fs/gc.c
+++ b/fs/f2fs/gc.c
@@ -266,13 +266,14 @@ static unsigned int get_cb_cost(struct f2fs_sb_info *sbi, unsigned int segno)
unsigned char age = 0;
unsigned char u;
unsigned int i;
+ unsigned int usable_segs_per_sec = f2fs_usable_segs_in_sec(sbi, segno);
- for (i = 0; i < sbi->segs_per_sec; i++)
+ for (i = 0; i < usable_segs_per_sec; i++)
mtime += get_seg_entry(sbi, start + i)->mtime;
vblocks = get_valid_blocks(sbi, segno, true);
- mtime = div_u64(mtime, sbi->segs_per_sec);
- vblocks = div_u64(vblocks, sbi->segs_per_sec);
+ mtime = div_u64(mtime, usable_segs_per_sec);
+ vblocks = div_u64(vblocks, usable_segs_per_sec);
u = (vblocks * 100) >> sbi->log_blocks_per_seg;
@@ -536,6 +537,7 @@ static int gc_node_segment(struct f2fs_sb_info *sbi,
int phase = 0;
bool fggc = (gc_type == FG_GC);
int submitted = 0;
+ unsigned int usable_blks_in_seg = f2fs_usable_blks_in_seg(sbi, segno);
start_addr = START_BLOCK(sbi, segno);
@@ -545,7 +547,7 @@ static int gc_node_segment(struct f2fs_sb_info *sbi,
if (fggc && phase == 2)
atomic_inc(&sbi->wb_sync_req[NODE]);
- for (off = 0; off < sbi->blocks_per_seg; off++, entry++) {
+ for (off = 0; off < usable_blks_in_seg; off++, entry++) {
nid_t nid = le32_to_cpu(entry->nid);
struct page *node_page;
struct node_info ni;
@@ -1033,13 +1035,14 @@ static int gc_data_segment(struct f2fs_sb_info *sbi, struct f2fs_summary *sum,
int off;
int phase = 0;
int submitted = 0;
+ unsigned int usable_blks_in_seg = f2fs_usable_blks_in_seg(sbi, segno);
start_addr = START_BLOCK(sbi, segno);
next_step:
entry = sum;
- for (off = 0; off < sbi->blocks_per_seg; off++, entry++) {
+ for (off = 0; off < usable_blks_in_seg; off++, entry++) {
struct page *data_page;
struct inode *inode;
struct node_info dni; /* dnode info for the data */
@@ -1204,6 +1207,15 @@ static int do_garbage_collect(struct f2fs_sb_info *sbi,
if (__is_large_section(sbi))
end_segno = rounddown(end_segno, sbi->segs_per_sec);
+ /*
+ * zone-capacity can be less than zone-size in zoned devices,
+ * resulting in less than expected usable segments in the zone,
+ * calculate the end segno in the zone which can be garbage collected
+ */
+ if (f2fs_sb_has_blkzoned(sbi))
+ end_segno -= sbi->segs_per_sec -
+ f2fs_usable_segs_in_sec(sbi, segno);
+
/* readahead multi ssa blocks those have contiguous address */
if (__is_large_section(sbi))
f2fs_ra_meta_pages(sbi, GET_SUM_BLOCK(sbi, segno),
@@ -1356,7 +1368,8 @@ int f2fs_gc(struct f2fs_sb_info *sbi, bool sync,
goto stop;
seg_freed = do_garbage_collect(sbi, segno, &gc_list, gc_type);
- if (gc_type == FG_GC && seg_freed == sbi->segs_per_sec)
+ if (gc_type == FG_GC &&
+ seg_freed == f2fs_usable_segs_in_sec(sbi, segno))
sec_freed++;
total_freed += seg_freed;
diff --git a/fs/f2fs/gc.h b/fs/f2fs/gc.h
index db3c61046aa4..ee5d7f30a1f8 100644
--- a/fs/f2fs/gc.h
+++ b/fs/f2fs/gc.h
@@ -44,13 +44,49 @@ struct gc_inode_list {
/*
* inline functions
*/
+
+/*
+ * On a Zoned device zone-capacity can be less than zone-size and if
+ * zone-capacity is not aligned to f2fs segment size(2MB), then the segment
+ * starting just before zone-capacity has some blocks spanning across the
+ * zone-capacity, these blocks are not usable.
+ * Such spanning segments can be in free list so calculate the sum of usable
+ * blocks in currently free segments including normal and spanning segments.
+ */
+static inline block_t free_segs_blk_count_zoned(struct f2fs_sb_info *sbi)
+{
+ block_t free_seg_blks = 0;
+ struct free_segmap_info *free_i = FREE_I(sbi);
+ int j;
+
+ spin_lock(&free_i->segmap_lock);
+ for (j = 0; j < MAIN_SEGS(sbi); j++)
+ if (!test_bit(j, free_i->free_segmap))
+ free_seg_blks += f2fs_usable_blks_in_seg(sbi, j);
+ spin_unlock(&free_i->segmap_lock);
+
+ return free_seg_blks;
+}
+
+static inline block_t free_segs_blk_count(struct f2fs_sb_info *sbi)
+{
+ if (f2fs_sb_has_blkzoned(sbi))
+ return free_segs_blk_count_zoned(sbi);
+
+ return free_segments(sbi) << sbi->log_blocks_per_seg;
+}
+
static inline block_t free_user_blocks(struct f2fs_sb_info *sbi)
{
- if (free_segments(sbi) < overprovision_segments(sbi))
+ block_t free_blks, ovp_blks;
+
+ free_blks = free_segs_blk_count(sbi);
+ ovp_blks = overprovision_segments(sbi) << sbi->log_blocks_per_seg;
+
+ if (free_blks < ovp_blks)
return 0;
- else
- return (free_segments(sbi) - overprovision_segments(sbi))
- << sbi->log_blocks_per_seg;
+
+ return free_blks - ovp_blks;
}
static inline block_t limit_invalid_user_blocks(struct f2fs_sb_info *sbi)
diff --git a/fs/f2fs/segment.c b/fs/f2fs/segment.c
index c35614d255e1..b36b4eb9e2a5 100644
--- a/fs/f2fs/segment.c
+++ b/fs/f2fs/segment.c
@@ -859,20 +859,22 @@ static void locate_dirty_segment(struct f2fs_sb_info *sbi, unsigned int segno)
{
struct dirty_seglist_info *dirty_i = DIRTY_I(sbi);
unsigned short valid_blocks, ckpt_valid_blocks;
+ unsigned int usable_blocks;
if (segno == NULL_SEGNO || IS_CURSEG(sbi, segno))
return;
+ usable_blocks = f2fs_usable_blks_in_seg(sbi, segno);
mutex_lock(&dirty_i->seglist_lock);
valid_blocks = get_valid_blocks(sbi, segno, false);
ckpt_valid_blocks = get_ckpt_valid_blocks(sbi, segno);
if (valid_blocks == 0 && (!is_sbi_flag_set(sbi, SBI_CP_DISABLED) ||
- ckpt_valid_blocks == sbi->blocks_per_seg)) {
+ ckpt_valid_blocks == usable_blocks)) {
__locate_dirty_segment(sbi, segno, PRE);
__remove_dirty_segment(sbi, segno, DIRTY);
- } else if (valid_blocks < sbi->blocks_per_seg) {
+ } else if (valid_blocks < usable_blocks) {
__locate_dirty_segment(sbi, segno, DIRTY);
} else {
/* Recovery routine with SSR needs this */
@@ -915,9 +917,11 @@ block_t f2fs_get_unusable_blocks(struct f2fs_sb_info *sbi)
for_each_set_bit(segno, dirty_i->dirty_segmap[DIRTY], MAIN_SEGS(sbi)) {
se = get_seg_entry(sbi, segno);
if (IS_NODESEG(se->type))
- holes[NODE] += sbi->blocks_per_seg - se->valid_blocks;
+ holes[NODE] += f2fs_usable_blks_in_seg(sbi, segno) -
+ se->valid_blocks;
else
- holes[DATA] += sbi->blocks_per_seg - se->valid_blocks;
+ holes[DATA] += f2fs_usable_blks_in_seg(sbi, segno) -
+ se->valid_blocks;
}
mutex_unlock(&dirty_i->seglist_lock);
@@ -2167,7 +2171,7 @@ static void update_sit_entry(struct f2fs_sb_info *sbi, block_t blkaddr, int del)
offset = GET_BLKOFF_FROM_SEG0(sbi, blkaddr);
f2fs_bug_on(sbi, (new_vblocks >> (sizeof(unsigned short) << 3) ||
- (new_vblocks > sbi->blocks_per_seg)));
+ (new_vblocks > f2fs_usable_blks_in_seg(sbi, segno))));
se->valid_blocks = new_vblocks;
se->mtime = get_mtime(sbi, false);
@@ -2933,9 +2937,9 @@ int f2fs_trim_fs(struct f2fs_sb_info *sbi, struct fstrim_range *range)
static bool __has_curseg_space(struct f2fs_sb_info *sbi, int type)
{
struct curseg_info *curseg = CURSEG_I(sbi, type);
- if (curseg->next_blkoff < sbi->blocks_per_seg)
- return true;
- return false;
+
+ return curseg->next_blkoff < f2fs_usable_blks_in_seg(sbi,
+ curseg->segno);
}
int f2fs_rw_hint_to_seg_type(enum rw_hint hint)
@@ -4294,9 +4298,12 @@ static void init_free_segmap(struct f2fs_sb_info *sbi)
{
unsigned int start;
int type;
+ struct seg_entry *sentry;
for (start = 0; start < MAIN_SEGS(sbi); start++) {
- struct seg_entry *sentry = get_seg_entry(sbi, start);
+ if (f2fs_usable_blks_in_seg(sbi, start) == 0)
+ continue;
+ sentry = get_seg_entry(sbi, start);
if (!sentry->valid_blocks)
__set_free(sbi, start);
else
@@ -4316,7 +4323,7 @@ static void init_dirty_segmap(struct f2fs_sb_info *sbi)
struct dirty_seglist_info *dirty_i = DIRTY_I(sbi);
struct free_segmap_info *free_i = FREE_I(sbi);
unsigned int segno = 0, offset = 0, secno;
- unsigned short valid_blocks;
+ unsigned short valid_blocks, usable_blks_in_seg;
unsigned short blks_per_sec = BLKS_PER_SEC(sbi);
while (1) {
@@ -4326,9 +4333,10 @@ static void init_dirty_segmap(struct f2fs_sb_info *sbi)
break;
offset = segno + 1;
valid_blocks = get_valid_blocks(sbi, segno, false);
- if (valid_blocks == sbi->blocks_per_seg || !valid_blocks)
+ usable_blks_in_seg = f2fs_usable_blks_in_seg(sbi, segno);
+ if (valid_blocks == usable_blks_in_seg || !valid_blocks)
continue;
- if (valid_blocks > sbi->blocks_per_seg) {
+ if (valid_blocks > usable_blks_in_seg) {
f2fs_bug_on(sbi, 1);
continue;
}
@@ -4678,6 +4686,101 @@ int f2fs_check_write_pointer(struct f2fs_sb_info *sbi)
return 0;
}
+
+static bool is_conv_zone(struct f2fs_sb_info *sbi, unsigned int zone_idx,
+ unsigned int dev_idx)
+{
+ if (!bdev_is_zoned(FDEV(dev_idx).bdev))
+ return true;
+ return !test_bit(zone_idx, FDEV(dev_idx).blkz_seq);
+}
+
+/* Return the zone index in the given device */
+static unsigned int get_zone_idx(struct f2fs_sb_info *sbi, unsigned int secno,
+ int dev_idx)
+{
+ block_t sec_start_blkaddr = START_BLOCK(sbi, GET_SEG_FROM_SEC(sbi, secno));
+
+ return (sec_start_blkaddr - FDEV(dev_idx).start_blk) >>
+ sbi->log_blocks_per_blkz;
+}
+
+/*
+ * Return the usable segments in a section based on the zone's
+ * corresponding zone capacity. Zone is equal to a section.
+ */
+static inline unsigned int f2fs_usable_zone_segs_in_sec(
+ struct f2fs_sb_info *sbi, unsigned int segno)
+{
+ unsigned int dev_idx, zone_idx, unusable_segs_in_sec;
+
+ dev_idx = f2fs_target_device_index(sbi, START_BLOCK(sbi, segno));
+ zone_idx = get_zone_idx(sbi, GET_SEC_FROM_SEG(sbi, segno), dev_idx);
+
+ /* Conventional zone's capacity is always equal to zone size */
+ if (is_conv_zone(sbi, zone_idx, dev_idx))
+ return sbi->segs_per_sec;
+
+ /*
+ * If the zone_capacity_blocks array is NULL, then zone capacity
+ * is equal to the zone size for all zones
+ */
+ if (!FDEV(dev_idx).zone_capacity_blocks)
+ return sbi->segs_per_sec;
+
+ /* Get the segment count beyond zone capacity block */
+ unusable_segs_in_sec = (sbi->blocks_per_blkz -
+ FDEV(dev_idx).zone_capacity_blocks[zone_idx]) >>
+ sbi->log_blocks_per_seg;
+ return sbi->segs_per_sec - unusable_segs_in_sec;
+}
+
+/*
+ * Return the number of usable blocks in a segment. The number of blocks
+ * returned is always equal to the number of blocks in a segment for
+ * segments fully contained within a sequential zone capacity or a
+ * conventional zone. For segments partially contained in a sequential
+ * zone capacity, the number of usable blocks up to the zone capacity
+ * is returned. 0 is returned in all other cases.
+ */
+static inline unsigned int f2fs_usable_zone_blks_in_seg(
+ struct f2fs_sb_info *sbi, unsigned int segno)
+{
+ block_t seg_start, sec_start_blkaddr, sec_cap_blkaddr;
+ unsigned int zone_idx, dev_idx, secno;
+
+ secno = GET_SEC_FROM_SEG(sbi, segno);
+ seg_start = START_BLOCK(sbi, segno);
+ dev_idx = f2fs_target_device_index(sbi, seg_start);
+ zone_idx = get_zone_idx(sbi, secno, dev_idx);
+
+ /*
+ * Conventional zone's capacity is always equal to zone size,
+ * so, blocks per segment is unchanged.
+ */
+ if (is_conv_zone(sbi, zone_idx, dev_idx))
+ return sbi->blocks_per_seg;
+
+ if (!FDEV(dev_idx).zone_capacity_blocks)
+ return sbi->blocks_per_seg;
+
+ sec_start_blkaddr = START_BLOCK(sbi, GET_SEG_FROM_SEC(sbi, secno));
+ sec_cap_blkaddr = sec_start_blkaddr +
+ FDEV(dev_idx).zone_capacity_blocks[zone_idx];
+
+ /*
+ * If segment starts before zone capacity and spans beyond
+ * zone capacity, then usable blocks are from seg start to
+ * zone capacity. If the segment starts after the zone capacity,
+ * then there are no usable blocks.
+ */
+ if (seg_start >= sec_cap_blkaddr)
+ return 0;
+ if (seg_start + sbi->blocks_per_seg > sec_cap_blkaddr)
+ return sec_cap_blkaddr - seg_start;
+
+ return sbi->blocks_per_seg;
+}
#else
int f2fs_fix_curseg_write_pointer(struct f2fs_sb_info *sbi)
{
@@ -4688,7 +4791,36 @@ int f2fs_check_write_pointer(struct f2fs_sb_info *sbi)
{
return 0;
}
+
+static inline unsigned int f2fs_usable_zone_blks_in_seg(struct f2fs_sb_info *sbi,
+ unsigned int segno)
+{
+ return 0;
+}
+
+static inline unsigned int f2fs_usable_zone_segs_in_sec(struct f2fs_sb_info *sbi,
+ unsigned int segno)
+{
+ return 0;
+}
#endif
+unsigned int f2fs_usable_blks_in_seg(struct f2fs_sb_info *sbi,
+ unsigned int segno)
+{
+ if (f2fs_sb_has_blkzoned(sbi))
+ return f2fs_usable_zone_blks_in_seg(sbi, segno);
+
+ return sbi->blocks_per_seg;
+}
+
+unsigned int f2fs_usable_segs_in_sec(struct f2fs_sb_info *sbi,
+ unsigned int segno)
+{
+ if (f2fs_sb_has_blkzoned(sbi))
+ return f2fs_usable_zone_segs_in_sec(sbi, segno);
+
+ return sbi->segs_per_sec;
+}
/*
* Update min, max modified time for cost-benefit GC algorithm
diff --git a/fs/f2fs/segment.h b/fs/f2fs/segment.h
index f261e3e6a69b..e1ca41fc3bfe 100644
--- a/fs/f2fs/segment.h
+++ b/fs/f2fs/segment.h
@@ -411,6 +411,7 @@ static inline void __set_free(struct f2fs_sb_info *sbi, unsigned int segno)
unsigned int secno = GET_SEC_FROM_SEG(sbi, segno);
unsigned int start_segno = GET_SEG_FROM_SEC(sbi, secno);
unsigned int next;
+ unsigned int usable_segs = f2fs_usable_segs_in_sec(sbi, segno);
spin_lock(&free_i->segmap_lock);
clear_bit(segno, free_i->free_segmap);
@@ -418,7 +419,7 @@ static inline void __set_free(struct f2fs_sb_info *sbi, unsigned int segno)
next = find_next_bit(free_i->free_segmap,
start_segno + sbi->segs_per_sec, start_segno);
- if (next >= start_segno + sbi->segs_per_sec) {
+ if (next >= start_segno + usable_segs) {
clear_bit(secno, free_i->free_secmap);
free_i->free_sections++;
}
@@ -444,6 +445,7 @@ static inline void __set_test_and_free(struct f2fs_sb_info *sbi,
unsigned int secno = GET_SEC_FROM_SEG(sbi, segno);
unsigned int start_segno = GET_SEG_FROM_SEC(sbi, secno);
unsigned int next;
+ unsigned int usable_segs = f2fs_usable_segs_in_sec(sbi, segno);
spin_lock(&free_i->segmap_lock);
if (test_and_clear_bit(segno, free_i->free_segmap)) {
@@ -453,7 +455,7 @@ static inline void __set_test_and_free(struct f2fs_sb_info *sbi,
goto skip_free;
next = find_next_bit(free_i->free_segmap,
start_segno + sbi->segs_per_sec, start_segno);
- if (next >= start_segno + sbi->segs_per_sec) {
+ if (next >= start_segno + usable_segs) {
if (test_and_clear_bit(secno, free_i->free_secmap))
free_i->free_sections++;
}
@@ -546,8 +548,8 @@ static inline bool has_curseg_enough_space(struct f2fs_sb_info *sbi)
/* check current node segment */
for (i = CURSEG_HOT_NODE; i <= CURSEG_COLD_NODE; i++) {
segno = CURSEG_I(sbi, i)->segno;
- left_blocks = sbi->blocks_per_seg -
- get_seg_entry(sbi, segno)->ckpt_valid_blocks;
+ left_blocks = f2fs_usable_blks_in_seg(sbi, segno) -
+ get_seg_entry(sbi, segno)->ckpt_valid_blocks;
if (node_blocks > left_blocks)
return false;
@@ -555,7 +557,7 @@ static inline bool has_curseg_enough_space(struct f2fs_sb_info *sbi)
/* check current data segment */
segno = CURSEG_I(sbi, CURSEG_HOT_DATA)->segno;
- left_blocks = sbi->blocks_per_seg -
+ left_blocks = f2fs_usable_blks_in_seg(sbi, segno) -
get_seg_entry(sbi, segno)->ckpt_valid_blocks;
if (dent_blocks > left_blocks)
return false;
@@ -677,21 +679,22 @@ static inline int check_block_count(struct f2fs_sb_info *sbi,
bool is_valid = test_bit_le(0, raw_sit->valid_map) ? true : false;
int valid_blocks = 0;
int cur_pos = 0, next_pos;
+ unsigned int usable_blks_per_seg = f2fs_usable_blks_in_seg(sbi, segno);
/* check bitmap with valid block count */
do {
if (is_valid) {
next_pos = find_next_zero_bit_le(&raw_sit->valid_map,
- sbi->blocks_per_seg,
+ usable_blks_per_seg,
cur_pos);
valid_blocks += next_pos - cur_pos;
} else
next_pos = find_next_bit_le(&raw_sit->valid_map,
- sbi->blocks_per_seg,
+ usable_blks_per_seg,
cur_pos);
cur_pos = next_pos;
is_valid = !is_valid;
- } while (cur_pos < sbi->blocks_per_seg);
+ } while (cur_pos < usable_blks_per_seg);
if (unlikely(GET_SIT_VBLOCKS(raw_sit) != valid_blocks)) {
f2fs_err(sbi, "Mismatch valid blocks %d vs. %d",
@@ -700,8 +703,13 @@ static inline int check_block_count(struct f2fs_sb_info *sbi,
return -EFSCORRUPTED;
}
+ if (usable_blks_per_seg < sbi->blocks_per_seg)
+ f2fs_bug_on(sbi, find_next_bit_le(&raw_sit->valid_map,
+ sbi->blocks_per_seg,
+ usable_blks_per_seg) != sbi->blocks_per_seg);
+
/* check segment usage, and check boundary of a given segment number */
- if (unlikely(GET_SIT_VBLOCKS(raw_sit) > sbi->blocks_per_seg
+ if (unlikely(GET_SIT_VBLOCKS(raw_sit) > usable_blks_per_seg
|| segno > TOTAL_SEGS(sbi) - 1)) {
f2fs_err(sbi, "Wrong valid blocks %d or segno %u",
GET_SIT_VBLOCKS(raw_sit), segno);
diff --git a/fs/f2fs/super.c b/fs/f2fs/super.c
index 80cb7cd358f8..7ced425dc102 100644
--- a/fs/f2fs/super.c
+++ b/fs/f2fs/super.c
@@ -1164,6 +1164,7 @@ static void destroy_device_list(struct f2fs_sb_info *sbi)
blkdev_put(FDEV(i).bdev, FMODE_EXCL);
#ifdef CONFIG_BLK_DEV_ZONED
kvfree(FDEV(i).blkz_seq);
+ kfree(FDEV(i).zone_capacity_blocks);
#endif
}
kvfree(sbi->devs);
@@ -3039,13 +3040,26 @@ static int init_percpu_info(struct f2fs_sb_info *sbi)
}
#ifdef CONFIG_BLK_DEV_ZONED
+
+struct f2fs_report_zones_args {
+ struct f2fs_dev_info *dev;
+ bool zone_cap_mismatch;
+};
+
static int f2fs_report_zone_cb(struct blk_zone *zone, unsigned int idx,
- void *data)
+ void *data)
{
- struct f2fs_dev_info *dev = data;
+ struct f2fs_report_zones_args *rz_args = data;
+
+ if (zone->type == BLK_ZONE_TYPE_CONVENTIONAL)
+ return 0;
+
+ set_bit(idx, rz_args->dev->blkz_seq);
+ rz_args->dev->zone_capacity_blocks[idx] = zone->capacity >>
+ F2FS_LOG_SECTORS_PER_BLOCK;
+ if (zone->len != zone->capacity && !rz_args->zone_cap_mismatch)
+ rz_args->zone_cap_mismatch = true;
- if (zone->type != BLK_ZONE_TYPE_CONVENTIONAL)
- set_bit(idx, dev->blkz_seq);
return 0;
}
@@ -3053,6 +3067,7 @@ static int init_blkz_info(struct f2fs_sb_info *sbi, int devi)
{
struct block_device *bdev = FDEV(devi).bdev;
sector_t nr_sectors = bdev->bd_part->nr_sects;
+ struct f2fs_report_zones_args rep_zone_arg;
int ret;
if (!f2fs_sb_has_blkzoned(sbi))
@@ -3078,12 +3093,26 @@ static int init_blkz_info(struct f2fs_sb_info *sbi, int devi)
if (!FDEV(devi).blkz_seq)
return -ENOMEM;
- /* Get block zones type */
+ /* Get block zones type and zone-capacity */
+ FDEV(devi).zone_capacity_blocks = f2fs_kzalloc(sbi,
+ FDEV(devi).nr_blkz * sizeof(block_t),
+ GFP_KERNEL);
+ if (!FDEV(devi).zone_capacity_blocks)
+ return -ENOMEM;
+
+ rep_zone_arg.dev = &FDEV(devi);
+ rep_zone_arg.zone_cap_mismatch = false;
+
ret = blkdev_report_zones(bdev, 0, BLK_ALL_ZONES, f2fs_report_zone_cb,
- &FDEV(devi));
+ &rep_zone_arg);
if (ret < 0)
return ret;
+ if (!rep_zone_arg.zone_cap_mismatch) {
+ kfree(FDEV(devi).zone_capacity_blocks);
+ FDEV(devi).zone_capacity_blocks = NULL;
+ }
+
return 0;
}
#endif
--
2.19.1
_______________________________________________
Linux-f2fs-devel mailing list
Linux-f2fs-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/linux-f2fs-devel
^ permalink raw reply related
* [f2fs-dev] [PATCH v3 0/1] f2fs: zns zone-capacity support
From: Aravind Ramesh @ 2020-07-16 12:56 UTC (permalink / raw)
To: jaegeuk, yuchao0, linux-fsdevel, linux-f2fs-devel, hch
Cc: niklas.cassel, Damien.LeMoal, Aravind Ramesh, matias.bjorling
NVM Express Zoned Namespace command set specification allows host software
to communicate with a NVM subsystem using zones. ZNS defines a host-managed
zoned block device model for NVMe devices. It divides the logical address
space of a namespace into zones. Each zone provides a LBA range that
shall be written sequentially. An explicit reset of zone is needed to write to
the zone again.
ZNS defines a per-zone capacity which can be equal or less than the
zone-size. Zone-capacity is the number of usable blocks in the zone.
This patchset implements support for ZNS devices with a zone-capacity
that is less that the device zone-size.
This patch checks if zone-capacity is less than zone-size, if it is,
then any segment which starts after the zone-capacity is marked as
not-free in the free segment bitmap at initial mount time. These segments
are marked as permanently used so they are not allocated for writes and
consequently not needed to be garbage collected. In case the zone-capacity
is not aligned to default segment size(2MB), then a segment can start
before the zone-capacity and span across zone-capacity boundary.
Such spanning segments are also considered as usable segments. It tracks
the usable blocks in a spanning segment, so that during writes and GC,
usable blocks in spanning segment is calculated to ensure writes/reads
do not cross the zone-capacity boundary.
This patch is based on the git tree
git://git.kernel.org/pub/scm/linux/kernel/git/jaegeuk/f2fs.git branch dev
and requires the below patch in order to build.
https://lore.kernel.org/linux-nvme/20200701063720.GA28954@lst.de/T/#m19e0197ae1837b7fe959b13fbc2a859b1f2abc1e
The above patch has been merged to the nvme-5.9 branch in the git tree:
git://git.infradead.org/nvme.git
Aravind Ramesh (1):
f2fs: support zone capacity less than zone size
Documentation/filesystems/f2fs.rst | 15 +++
fs/f2fs/f2fs.h | 5 +
fs/f2fs/gc.c | 25 +++--
fs/f2fs/gc.h | 44 +++++++-
fs/f2fs/segment.c | 156 ++++++++++++++++++++++++++---
fs/f2fs/segment.h | 26 +++--
fs/f2fs/super.c | 41 ++++++--
7 files changed, 275 insertions(+), 37 deletions(-)
--
2.19.1
_______________________________________________
Linux-f2fs-devel mailing list
Linux-f2fs-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/linux-f2fs-devel
^ permalink raw reply
* [PATCH v3 1/1] f2fs: support zone capacity less than zone size
From: Aravind Ramesh @ 2020-07-16 12:56 UTC (permalink / raw)
To: jaegeuk, yuchao0, linux-fsdevel, linux-f2fs-devel, hch
Cc: Damien.LeMoal, niklas.cassel, matias.bjorling, Aravind Ramesh,
Damien Le Moal
In-Reply-To: <20200716125656.3662-1-aravind.ramesh@wdc.com>
NVMe Zoned Namespace devices can have zone-capacity less than zone-size.
Zone-capacity indicates the maximum number of sectors that are usable in
a zone beginning from the first sector of the zone. This makes the sectors
sectors after the zone-capacity till zone-size to be unusable.
This patch set tracks zone-size and zone-capacity in zoned devices and
calculate the usable blocks per segment and usable segments per section.
If zone-capacity is less than zone-size mark only those segments which
start before zone-capacity as free segments. All segments at and beyond
zone-capacity are treated as permanently used segments. In cases where
zone-capacity does not align with segment size the last segment will start
before zone-capacity and end beyond the zone-capacity of the zone. For
such spanning segments only sectors within the zone-capacity are used.
During writes and GC manage the usable segments in a section and usable
blocks per segment. Segments which are beyond zone-capacity are never
allocated, and do not need to be garbage collected, only the segments
which are before zone-capacity needs to garbage collected.
For spanning segments based on the number of usable blocks in that
segment, write to blocks only up to zone-capacity.
Zone-capacity is device specific and cannot be configured by the user.
Since NVMe ZNS device zones are sequentially write only, a block device
with conventional zones or any normal block device is needed along with
the ZNS device for the metadata operations of F2fs.
A typical nvme-cli output of a zoned device shows zone start and capacity
and write pointer as below:
SLBA: 0x0 WP: 0x0 Cap: 0x18800 State: EMPTY Type: SEQWRITE_REQ
SLBA: 0x20000 WP: 0x20000 Cap: 0x18800 State: EMPTY Type: SEQWRITE_REQ
SLBA: 0x40000 WP: 0x40000 Cap: 0x18800 State: EMPTY Type: SEQWRITE_REQ
Here zone size is 64MB, capacity is 49MB, WP is at zone start as the zones
are in EMPTY state. For each zone, only zone start + 49MB is usable area,
any lba/sector after 49MB cannot be read or written to, the drive will fail
any attempts to read/write. So, the second zone starts at 64MB and is
usable till 113MB (64 + 49) and the range between 113 and 128MB is
again unusable. The next zone starts at 128MB, and so on.
Signed-off-by: Aravind Ramesh <aravind.ramesh@wdc.com>
Signed-off-by: Damien Le Moal <damien.lemoal@wdc.com>
Signed-off-by: Niklas Cassel <niklas.cassel@wdc.com>
---
Documentation/filesystems/f2fs.rst | 15 +++
fs/f2fs/f2fs.h | 5 +
fs/f2fs/gc.c | 25 +++--
fs/f2fs/gc.h | 44 +++++++-
fs/f2fs/segment.c | 156 ++++++++++++++++++++++++++---
fs/f2fs/segment.h | 26 +++--
fs/f2fs/super.c | 41 ++++++--
7 files changed, 275 insertions(+), 37 deletions(-)
diff --git a/Documentation/filesystems/f2fs.rst b/Documentation/filesystems/f2fs.rst
index 535021c46260..cec2167a31db 100644
--- a/Documentation/filesystems/f2fs.rst
+++ b/Documentation/filesystems/f2fs.rst
@@ -766,3 +766,18 @@ Compress metadata layout::
+-------------+-------------+----------+----------------------------+
| data length | data chksum | reserved | compressed data |
+-------------+-------------+----------+----------------------------+
+
+NVMe Zoned Namespace devices
+----------------------------
+
+- ZNS defines a per-zone capacity which can be equal or less than the
+ zone-size. Zone-capacity is the number of usable blocks in the zone.
+ F2fs checks if zone-capacity is less than zone-size, if it is, then any
+ segment which starts after the zone-capacity is marked as not-free in
+ the free segment bitmap at initial mount time. These segments are marked
+ as permanently used so they are not allocated for writes and
+ consequently are not needed to be garbage collected. In case the
+ zone-capacity is not aligned to default segment size(2MB), then a segment
+ can start before the zone-capacity and span across zone-capacity boundary.
+ Such spanning segments are also considered as usable segments. All blocks
+ past the zone-capacity are considered unusable in these segments.
diff --git a/fs/f2fs/f2fs.h b/fs/f2fs/f2fs.h
index e6e47618a357..73219e4e1ba4 100644
--- a/fs/f2fs/f2fs.h
+++ b/fs/f2fs/f2fs.h
@@ -1232,6 +1232,7 @@ struct f2fs_dev_info {
#ifdef CONFIG_BLK_DEV_ZONED
unsigned int nr_blkz; /* Total number of zones */
unsigned long *blkz_seq; /* Bitmap indicating sequential zones */
+ block_t *zone_capacity_blocks; /* Array of zone capacity in blks */
#endif
};
@@ -3395,6 +3396,10 @@ void f2fs_destroy_segment_manager_caches(void);
int f2fs_rw_hint_to_seg_type(enum rw_hint hint);
enum rw_hint f2fs_io_type_to_rw_hint(struct f2fs_sb_info *sbi,
enum page_type type, enum temp_type temp);
+unsigned int f2fs_usable_segs_in_sec(struct f2fs_sb_info *sbi,
+ unsigned int segno);
+unsigned int f2fs_usable_blks_in_seg(struct f2fs_sb_info *sbi,
+ unsigned int segno);
/*
* checkpoint.c
diff --git a/fs/f2fs/gc.c b/fs/f2fs/gc.c
index 9a40761445d3..429e7dae807d 100644
--- a/fs/f2fs/gc.c
+++ b/fs/f2fs/gc.c
@@ -266,13 +266,14 @@ static unsigned int get_cb_cost(struct f2fs_sb_info *sbi, unsigned int segno)
unsigned char age = 0;
unsigned char u;
unsigned int i;
+ unsigned int usable_segs_per_sec = f2fs_usable_segs_in_sec(sbi, segno);
- for (i = 0; i < sbi->segs_per_sec; i++)
+ for (i = 0; i < usable_segs_per_sec; i++)
mtime += get_seg_entry(sbi, start + i)->mtime;
vblocks = get_valid_blocks(sbi, segno, true);
- mtime = div_u64(mtime, sbi->segs_per_sec);
- vblocks = div_u64(vblocks, sbi->segs_per_sec);
+ mtime = div_u64(mtime, usable_segs_per_sec);
+ vblocks = div_u64(vblocks, usable_segs_per_sec);
u = (vblocks * 100) >> sbi->log_blocks_per_seg;
@@ -536,6 +537,7 @@ static int gc_node_segment(struct f2fs_sb_info *sbi,
int phase = 0;
bool fggc = (gc_type == FG_GC);
int submitted = 0;
+ unsigned int usable_blks_in_seg = f2fs_usable_blks_in_seg(sbi, segno);
start_addr = START_BLOCK(sbi, segno);
@@ -545,7 +547,7 @@ static int gc_node_segment(struct f2fs_sb_info *sbi,
if (fggc && phase == 2)
atomic_inc(&sbi->wb_sync_req[NODE]);
- for (off = 0; off < sbi->blocks_per_seg; off++, entry++) {
+ for (off = 0; off < usable_blks_in_seg; off++, entry++) {
nid_t nid = le32_to_cpu(entry->nid);
struct page *node_page;
struct node_info ni;
@@ -1033,13 +1035,14 @@ static int gc_data_segment(struct f2fs_sb_info *sbi, struct f2fs_summary *sum,
int off;
int phase = 0;
int submitted = 0;
+ unsigned int usable_blks_in_seg = f2fs_usable_blks_in_seg(sbi, segno);
start_addr = START_BLOCK(sbi, segno);
next_step:
entry = sum;
- for (off = 0; off < sbi->blocks_per_seg; off++, entry++) {
+ for (off = 0; off < usable_blks_in_seg; off++, entry++) {
struct page *data_page;
struct inode *inode;
struct node_info dni; /* dnode info for the data */
@@ -1204,6 +1207,15 @@ static int do_garbage_collect(struct f2fs_sb_info *sbi,
if (__is_large_section(sbi))
end_segno = rounddown(end_segno, sbi->segs_per_sec);
+ /*
+ * zone-capacity can be less than zone-size in zoned devices,
+ * resulting in less than expected usable segments in the zone,
+ * calculate the end segno in the zone which can be garbage collected
+ */
+ if (f2fs_sb_has_blkzoned(sbi))
+ end_segno -= sbi->segs_per_sec -
+ f2fs_usable_segs_in_sec(sbi, segno);
+
/* readahead multi ssa blocks those have contiguous address */
if (__is_large_section(sbi))
f2fs_ra_meta_pages(sbi, GET_SUM_BLOCK(sbi, segno),
@@ -1356,7 +1368,8 @@ int f2fs_gc(struct f2fs_sb_info *sbi, bool sync,
goto stop;
seg_freed = do_garbage_collect(sbi, segno, &gc_list, gc_type);
- if (gc_type == FG_GC && seg_freed == sbi->segs_per_sec)
+ if (gc_type == FG_GC &&
+ seg_freed == f2fs_usable_segs_in_sec(sbi, segno))
sec_freed++;
total_freed += seg_freed;
diff --git a/fs/f2fs/gc.h b/fs/f2fs/gc.h
index db3c61046aa4..ee5d7f30a1f8 100644
--- a/fs/f2fs/gc.h
+++ b/fs/f2fs/gc.h
@@ -44,13 +44,49 @@ struct gc_inode_list {
/*
* inline functions
*/
+
+/*
+ * On a Zoned device zone-capacity can be less than zone-size and if
+ * zone-capacity is not aligned to f2fs segment size(2MB), then the segment
+ * starting just before zone-capacity has some blocks spanning across the
+ * zone-capacity, these blocks are not usable.
+ * Such spanning segments can be in free list so calculate the sum of usable
+ * blocks in currently free segments including normal and spanning segments.
+ */
+static inline block_t free_segs_blk_count_zoned(struct f2fs_sb_info *sbi)
+{
+ block_t free_seg_blks = 0;
+ struct free_segmap_info *free_i = FREE_I(sbi);
+ int j;
+
+ spin_lock(&free_i->segmap_lock);
+ for (j = 0; j < MAIN_SEGS(sbi); j++)
+ if (!test_bit(j, free_i->free_segmap))
+ free_seg_blks += f2fs_usable_blks_in_seg(sbi, j);
+ spin_unlock(&free_i->segmap_lock);
+
+ return free_seg_blks;
+}
+
+static inline block_t free_segs_blk_count(struct f2fs_sb_info *sbi)
+{
+ if (f2fs_sb_has_blkzoned(sbi))
+ return free_segs_blk_count_zoned(sbi);
+
+ return free_segments(sbi) << sbi->log_blocks_per_seg;
+}
+
static inline block_t free_user_blocks(struct f2fs_sb_info *sbi)
{
- if (free_segments(sbi) < overprovision_segments(sbi))
+ block_t free_blks, ovp_blks;
+
+ free_blks = free_segs_blk_count(sbi);
+ ovp_blks = overprovision_segments(sbi) << sbi->log_blocks_per_seg;
+
+ if (free_blks < ovp_blks)
return 0;
- else
- return (free_segments(sbi) - overprovision_segments(sbi))
- << sbi->log_blocks_per_seg;
+
+ return free_blks - ovp_blks;
}
static inline block_t limit_invalid_user_blocks(struct f2fs_sb_info *sbi)
diff --git a/fs/f2fs/segment.c b/fs/f2fs/segment.c
index c35614d255e1..b36b4eb9e2a5 100644
--- a/fs/f2fs/segment.c
+++ b/fs/f2fs/segment.c
@@ -859,20 +859,22 @@ static void locate_dirty_segment(struct f2fs_sb_info *sbi, unsigned int segno)
{
struct dirty_seglist_info *dirty_i = DIRTY_I(sbi);
unsigned short valid_blocks, ckpt_valid_blocks;
+ unsigned int usable_blocks;
if (segno == NULL_SEGNO || IS_CURSEG(sbi, segno))
return;
+ usable_blocks = f2fs_usable_blks_in_seg(sbi, segno);
mutex_lock(&dirty_i->seglist_lock);
valid_blocks = get_valid_blocks(sbi, segno, false);
ckpt_valid_blocks = get_ckpt_valid_blocks(sbi, segno);
if (valid_blocks == 0 && (!is_sbi_flag_set(sbi, SBI_CP_DISABLED) ||
- ckpt_valid_blocks == sbi->blocks_per_seg)) {
+ ckpt_valid_blocks == usable_blocks)) {
__locate_dirty_segment(sbi, segno, PRE);
__remove_dirty_segment(sbi, segno, DIRTY);
- } else if (valid_blocks < sbi->blocks_per_seg) {
+ } else if (valid_blocks < usable_blocks) {
__locate_dirty_segment(sbi, segno, DIRTY);
} else {
/* Recovery routine with SSR needs this */
@@ -915,9 +917,11 @@ block_t f2fs_get_unusable_blocks(struct f2fs_sb_info *sbi)
for_each_set_bit(segno, dirty_i->dirty_segmap[DIRTY], MAIN_SEGS(sbi)) {
se = get_seg_entry(sbi, segno);
if (IS_NODESEG(se->type))
- holes[NODE] += sbi->blocks_per_seg - se->valid_blocks;
+ holes[NODE] += f2fs_usable_blks_in_seg(sbi, segno) -
+ se->valid_blocks;
else
- holes[DATA] += sbi->blocks_per_seg - se->valid_blocks;
+ holes[DATA] += f2fs_usable_blks_in_seg(sbi, segno) -
+ se->valid_blocks;
}
mutex_unlock(&dirty_i->seglist_lock);
@@ -2167,7 +2171,7 @@ static void update_sit_entry(struct f2fs_sb_info *sbi, block_t blkaddr, int del)
offset = GET_BLKOFF_FROM_SEG0(sbi, blkaddr);
f2fs_bug_on(sbi, (new_vblocks >> (sizeof(unsigned short) << 3) ||
- (new_vblocks > sbi->blocks_per_seg)));
+ (new_vblocks > f2fs_usable_blks_in_seg(sbi, segno))));
se->valid_blocks = new_vblocks;
se->mtime = get_mtime(sbi, false);
@@ -2933,9 +2937,9 @@ int f2fs_trim_fs(struct f2fs_sb_info *sbi, struct fstrim_range *range)
static bool __has_curseg_space(struct f2fs_sb_info *sbi, int type)
{
struct curseg_info *curseg = CURSEG_I(sbi, type);
- if (curseg->next_blkoff < sbi->blocks_per_seg)
- return true;
- return false;
+
+ return curseg->next_blkoff < f2fs_usable_blks_in_seg(sbi,
+ curseg->segno);
}
int f2fs_rw_hint_to_seg_type(enum rw_hint hint)
@@ -4294,9 +4298,12 @@ static void init_free_segmap(struct f2fs_sb_info *sbi)
{
unsigned int start;
int type;
+ struct seg_entry *sentry;
for (start = 0; start < MAIN_SEGS(sbi); start++) {
- struct seg_entry *sentry = get_seg_entry(sbi, start);
+ if (f2fs_usable_blks_in_seg(sbi, start) == 0)
+ continue;
+ sentry = get_seg_entry(sbi, start);
if (!sentry->valid_blocks)
__set_free(sbi, start);
else
@@ -4316,7 +4323,7 @@ static void init_dirty_segmap(struct f2fs_sb_info *sbi)
struct dirty_seglist_info *dirty_i = DIRTY_I(sbi);
struct free_segmap_info *free_i = FREE_I(sbi);
unsigned int segno = 0, offset = 0, secno;
- unsigned short valid_blocks;
+ unsigned short valid_blocks, usable_blks_in_seg;
unsigned short blks_per_sec = BLKS_PER_SEC(sbi);
while (1) {
@@ -4326,9 +4333,10 @@ static void init_dirty_segmap(struct f2fs_sb_info *sbi)
break;
offset = segno + 1;
valid_blocks = get_valid_blocks(sbi, segno, false);
- if (valid_blocks == sbi->blocks_per_seg || !valid_blocks)
+ usable_blks_in_seg = f2fs_usable_blks_in_seg(sbi, segno);
+ if (valid_blocks == usable_blks_in_seg || !valid_blocks)
continue;
- if (valid_blocks > sbi->blocks_per_seg) {
+ if (valid_blocks > usable_blks_in_seg) {
f2fs_bug_on(sbi, 1);
continue;
}
@@ -4678,6 +4686,101 @@ int f2fs_check_write_pointer(struct f2fs_sb_info *sbi)
return 0;
}
+
+static bool is_conv_zone(struct f2fs_sb_info *sbi, unsigned int zone_idx,
+ unsigned int dev_idx)
+{
+ if (!bdev_is_zoned(FDEV(dev_idx).bdev))
+ return true;
+ return !test_bit(zone_idx, FDEV(dev_idx).blkz_seq);
+}
+
+/* Return the zone index in the given device */
+static unsigned int get_zone_idx(struct f2fs_sb_info *sbi, unsigned int secno,
+ int dev_idx)
+{
+ block_t sec_start_blkaddr = START_BLOCK(sbi, GET_SEG_FROM_SEC(sbi, secno));
+
+ return (sec_start_blkaddr - FDEV(dev_idx).start_blk) >>
+ sbi->log_blocks_per_blkz;
+}
+
+/*
+ * Return the usable segments in a section based on the zone's
+ * corresponding zone capacity. Zone is equal to a section.
+ */
+static inline unsigned int f2fs_usable_zone_segs_in_sec(
+ struct f2fs_sb_info *sbi, unsigned int segno)
+{
+ unsigned int dev_idx, zone_idx, unusable_segs_in_sec;
+
+ dev_idx = f2fs_target_device_index(sbi, START_BLOCK(sbi, segno));
+ zone_idx = get_zone_idx(sbi, GET_SEC_FROM_SEG(sbi, segno), dev_idx);
+
+ /* Conventional zone's capacity is always equal to zone size */
+ if (is_conv_zone(sbi, zone_idx, dev_idx))
+ return sbi->segs_per_sec;
+
+ /*
+ * If the zone_capacity_blocks array is NULL, then zone capacity
+ * is equal to the zone size for all zones
+ */
+ if (!FDEV(dev_idx).zone_capacity_blocks)
+ return sbi->segs_per_sec;
+
+ /* Get the segment count beyond zone capacity block */
+ unusable_segs_in_sec = (sbi->blocks_per_blkz -
+ FDEV(dev_idx).zone_capacity_blocks[zone_idx]) >>
+ sbi->log_blocks_per_seg;
+ return sbi->segs_per_sec - unusable_segs_in_sec;
+}
+
+/*
+ * Return the number of usable blocks in a segment. The number of blocks
+ * returned is always equal to the number of blocks in a segment for
+ * segments fully contained within a sequential zone capacity or a
+ * conventional zone. For segments partially contained in a sequential
+ * zone capacity, the number of usable blocks up to the zone capacity
+ * is returned. 0 is returned in all other cases.
+ */
+static inline unsigned int f2fs_usable_zone_blks_in_seg(
+ struct f2fs_sb_info *sbi, unsigned int segno)
+{
+ block_t seg_start, sec_start_blkaddr, sec_cap_blkaddr;
+ unsigned int zone_idx, dev_idx, secno;
+
+ secno = GET_SEC_FROM_SEG(sbi, segno);
+ seg_start = START_BLOCK(sbi, segno);
+ dev_idx = f2fs_target_device_index(sbi, seg_start);
+ zone_idx = get_zone_idx(sbi, secno, dev_idx);
+
+ /*
+ * Conventional zone's capacity is always equal to zone size,
+ * so, blocks per segment is unchanged.
+ */
+ if (is_conv_zone(sbi, zone_idx, dev_idx))
+ return sbi->blocks_per_seg;
+
+ if (!FDEV(dev_idx).zone_capacity_blocks)
+ return sbi->blocks_per_seg;
+
+ sec_start_blkaddr = START_BLOCK(sbi, GET_SEG_FROM_SEC(sbi, secno));
+ sec_cap_blkaddr = sec_start_blkaddr +
+ FDEV(dev_idx).zone_capacity_blocks[zone_idx];
+
+ /*
+ * If segment starts before zone capacity and spans beyond
+ * zone capacity, then usable blocks are from seg start to
+ * zone capacity. If the segment starts after the zone capacity,
+ * then there are no usable blocks.
+ */
+ if (seg_start >= sec_cap_blkaddr)
+ return 0;
+ if (seg_start + sbi->blocks_per_seg > sec_cap_blkaddr)
+ return sec_cap_blkaddr - seg_start;
+
+ return sbi->blocks_per_seg;
+}
#else
int f2fs_fix_curseg_write_pointer(struct f2fs_sb_info *sbi)
{
@@ -4688,7 +4791,36 @@ int f2fs_check_write_pointer(struct f2fs_sb_info *sbi)
{
return 0;
}
+
+static inline unsigned int f2fs_usable_zone_blks_in_seg(struct f2fs_sb_info *sbi,
+ unsigned int segno)
+{
+ return 0;
+}
+
+static inline unsigned int f2fs_usable_zone_segs_in_sec(struct f2fs_sb_info *sbi,
+ unsigned int segno)
+{
+ return 0;
+}
#endif
+unsigned int f2fs_usable_blks_in_seg(struct f2fs_sb_info *sbi,
+ unsigned int segno)
+{
+ if (f2fs_sb_has_blkzoned(sbi))
+ return f2fs_usable_zone_blks_in_seg(sbi, segno);
+
+ return sbi->blocks_per_seg;
+}
+
+unsigned int f2fs_usable_segs_in_sec(struct f2fs_sb_info *sbi,
+ unsigned int segno)
+{
+ if (f2fs_sb_has_blkzoned(sbi))
+ return f2fs_usable_zone_segs_in_sec(sbi, segno);
+
+ return sbi->segs_per_sec;
+}
/*
* Update min, max modified time for cost-benefit GC algorithm
diff --git a/fs/f2fs/segment.h b/fs/f2fs/segment.h
index f261e3e6a69b..e1ca41fc3bfe 100644
--- a/fs/f2fs/segment.h
+++ b/fs/f2fs/segment.h
@@ -411,6 +411,7 @@ static inline void __set_free(struct f2fs_sb_info *sbi, unsigned int segno)
unsigned int secno = GET_SEC_FROM_SEG(sbi, segno);
unsigned int start_segno = GET_SEG_FROM_SEC(sbi, secno);
unsigned int next;
+ unsigned int usable_segs = f2fs_usable_segs_in_sec(sbi, segno);
spin_lock(&free_i->segmap_lock);
clear_bit(segno, free_i->free_segmap);
@@ -418,7 +419,7 @@ static inline void __set_free(struct f2fs_sb_info *sbi, unsigned int segno)
next = find_next_bit(free_i->free_segmap,
start_segno + sbi->segs_per_sec, start_segno);
- if (next >= start_segno + sbi->segs_per_sec) {
+ if (next >= start_segno + usable_segs) {
clear_bit(secno, free_i->free_secmap);
free_i->free_sections++;
}
@@ -444,6 +445,7 @@ static inline void __set_test_and_free(struct f2fs_sb_info *sbi,
unsigned int secno = GET_SEC_FROM_SEG(sbi, segno);
unsigned int start_segno = GET_SEG_FROM_SEC(sbi, secno);
unsigned int next;
+ unsigned int usable_segs = f2fs_usable_segs_in_sec(sbi, segno);
spin_lock(&free_i->segmap_lock);
if (test_and_clear_bit(segno, free_i->free_segmap)) {
@@ -453,7 +455,7 @@ static inline void __set_test_and_free(struct f2fs_sb_info *sbi,
goto skip_free;
next = find_next_bit(free_i->free_segmap,
start_segno + sbi->segs_per_sec, start_segno);
- if (next >= start_segno + sbi->segs_per_sec) {
+ if (next >= start_segno + usable_segs) {
if (test_and_clear_bit(secno, free_i->free_secmap))
free_i->free_sections++;
}
@@ -546,8 +548,8 @@ static inline bool has_curseg_enough_space(struct f2fs_sb_info *sbi)
/* check current node segment */
for (i = CURSEG_HOT_NODE; i <= CURSEG_COLD_NODE; i++) {
segno = CURSEG_I(sbi, i)->segno;
- left_blocks = sbi->blocks_per_seg -
- get_seg_entry(sbi, segno)->ckpt_valid_blocks;
+ left_blocks = f2fs_usable_blks_in_seg(sbi, segno) -
+ get_seg_entry(sbi, segno)->ckpt_valid_blocks;
if (node_blocks > left_blocks)
return false;
@@ -555,7 +557,7 @@ static inline bool has_curseg_enough_space(struct f2fs_sb_info *sbi)
/* check current data segment */
segno = CURSEG_I(sbi, CURSEG_HOT_DATA)->segno;
- left_blocks = sbi->blocks_per_seg -
+ left_blocks = f2fs_usable_blks_in_seg(sbi, segno) -
get_seg_entry(sbi, segno)->ckpt_valid_blocks;
if (dent_blocks > left_blocks)
return false;
@@ -677,21 +679,22 @@ static inline int check_block_count(struct f2fs_sb_info *sbi,
bool is_valid = test_bit_le(0, raw_sit->valid_map) ? true : false;
int valid_blocks = 0;
int cur_pos = 0, next_pos;
+ unsigned int usable_blks_per_seg = f2fs_usable_blks_in_seg(sbi, segno);
/* check bitmap with valid block count */
do {
if (is_valid) {
next_pos = find_next_zero_bit_le(&raw_sit->valid_map,
- sbi->blocks_per_seg,
+ usable_blks_per_seg,
cur_pos);
valid_blocks += next_pos - cur_pos;
} else
next_pos = find_next_bit_le(&raw_sit->valid_map,
- sbi->blocks_per_seg,
+ usable_blks_per_seg,
cur_pos);
cur_pos = next_pos;
is_valid = !is_valid;
- } while (cur_pos < sbi->blocks_per_seg);
+ } while (cur_pos < usable_blks_per_seg);
if (unlikely(GET_SIT_VBLOCKS(raw_sit) != valid_blocks)) {
f2fs_err(sbi, "Mismatch valid blocks %d vs. %d",
@@ -700,8 +703,13 @@ static inline int check_block_count(struct f2fs_sb_info *sbi,
return -EFSCORRUPTED;
}
+ if (usable_blks_per_seg < sbi->blocks_per_seg)
+ f2fs_bug_on(sbi, find_next_bit_le(&raw_sit->valid_map,
+ sbi->blocks_per_seg,
+ usable_blks_per_seg) != sbi->blocks_per_seg);
+
/* check segment usage, and check boundary of a given segment number */
- if (unlikely(GET_SIT_VBLOCKS(raw_sit) > sbi->blocks_per_seg
+ if (unlikely(GET_SIT_VBLOCKS(raw_sit) > usable_blks_per_seg
|| segno > TOTAL_SEGS(sbi) - 1)) {
f2fs_err(sbi, "Wrong valid blocks %d or segno %u",
GET_SIT_VBLOCKS(raw_sit), segno);
diff --git a/fs/f2fs/super.c b/fs/f2fs/super.c
index 80cb7cd358f8..7ced425dc102 100644
--- a/fs/f2fs/super.c
+++ b/fs/f2fs/super.c
@@ -1164,6 +1164,7 @@ static void destroy_device_list(struct f2fs_sb_info *sbi)
blkdev_put(FDEV(i).bdev, FMODE_EXCL);
#ifdef CONFIG_BLK_DEV_ZONED
kvfree(FDEV(i).blkz_seq);
+ kfree(FDEV(i).zone_capacity_blocks);
#endif
}
kvfree(sbi->devs);
@@ -3039,13 +3040,26 @@ static int init_percpu_info(struct f2fs_sb_info *sbi)
}
#ifdef CONFIG_BLK_DEV_ZONED
+
+struct f2fs_report_zones_args {
+ struct f2fs_dev_info *dev;
+ bool zone_cap_mismatch;
+};
+
static int f2fs_report_zone_cb(struct blk_zone *zone, unsigned int idx,
- void *data)
+ void *data)
{
- struct f2fs_dev_info *dev = data;
+ struct f2fs_report_zones_args *rz_args = data;
+
+ if (zone->type == BLK_ZONE_TYPE_CONVENTIONAL)
+ return 0;
+
+ set_bit(idx, rz_args->dev->blkz_seq);
+ rz_args->dev->zone_capacity_blocks[idx] = zone->capacity >>
+ F2FS_LOG_SECTORS_PER_BLOCK;
+ if (zone->len != zone->capacity && !rz_args->zone_cap_mismatch)
+ rz_args->zone_cap_mismatch = true;
- if (zone->type != BLK_ZONE_TYPE_CONVENTIONAL)
- set_bit(idx, dev->blkz_seq);
return 0;
}
@@ -3053,6 +3067,7 @@ static int init_blkz_info(struct f2fs_sb_info *sbi, int devi)
{
struct block_device *bdev = FDEV(devi).bdev;
sector_t nr_sectors = bdev->bd_part->nr_sects;
+ struct f2fs_report_zones_args rep_zone_arg;
int ret;
if (!f2fs_sb_has_blkzoned(sbi))
@@ -3078,12 +3093,26 @@ static int init_blkz_info(struct f2fs_sb_info *sbi, int devi)
if (!FDEV(devi).blkz_seq)
return -ENOMEM;
- /* Get block zones type */
+ /* Get block zones type and zone-capacity */
+ FDEV(devi).zone_capacity_blocks = f2fs_kzalloc(sbi,
+ FDEV(devi).nr_blkz * sizeof(block_t),
+ GFP_KERNEL);
+ if (!FDEV(devi).zone_capacity_blocks)
+ return -ENOMEM;
+
+ rep_zone_arg.dev = &FDEV(devi);
+ rep_zone_arg.zone_cap_mismatch = false;
+
ret = blkdev_report_zones(bdev, 0, BLK_ALL_ZONES, f2fs_report_zone_cb,
- &FDEV(devi));
+ &rep_zone_arg);
if (ret < 0)
return ret;
+ if (!rep_zone_arg.zone_cap_mismatch) {
+ kfree(FDEV(devi).zone_capacity_blocks);
+ FDEV(devi).zone_capacity_blocks = NULL;
+ }
+
return 0;
}
#endif
--
2.19.1
^ permalink raw reply related
page: next (older) | prev (newer) | latest
- recent:[subjects (threaded)|topics (new)|topics (active)]
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.