2020-01-15 03:58:14

by Logan Gunthorpe

[permalink] [raw]
Subject: [PATCH v2 0/7] Switchtec Gen4 Support

Hi,

Here are the cleaned up version of the patches for Gen4 support in
switchtec. The end result is mostly the same, save some very minor
changes, but the organization into commits has been reworked per
Bjorn's feedback. This set is also rebased onto pci/switchtec.

A git branch is available here:

https://github.com/sbates130272/linux-p2pmem switchtec-next-v2

Thanks,

Logan

--

Kelvin Cao (2):
PCI/switchtec: Add gen4 support for the flash information interface
PCI/switchtec: Introduce gen4 variant IDS in the device ID table

Logan Gunthorpe (5):
PCI/switchtec: Rename generation specific constants
PCI/switchtec: Introduce Generation Variable
PCI/switchtec: Refactor ioctl_flash_part_info()
PCI/switchtec: Separate out gen3 register structures into unionse
PCI/switchtec: Add gen4 support for the system info registers

drivers/pci/quirks.c | 18 ++
drivers/pci/switch/switchtec.c | 334 +++++++++++++++++++++------
include/linux/switchtec.h | 148 ++++++++++--
include/uapi/linux/switchtec_ioctl.h | 13 +-
4 files changed, 424 insertions(+), 89 deletions(-)

--
2.20.1


2020-01-15 03:58:31

by Logan Gunthorpe

[permalink] [raw]
Subject: [PATCH v2 5/7] PCI/switchtec: Add gen4 support for the system info registers

Add the gen4 specific system info registers and ensure their usage is
guarded by a check on the device's generation.

Signed-off-by: Logan Gunthorpe <[email protected]>
---
drivers/pci/switch/switchtec.c | 5 ++++
include/linux/switchtec.h | 43 ++++++++++++++++++++++++++++++++++
2 files changed, 48 insertions(+)

diff --git a/drivers/pci/switch/switchtec.c b/drivers/pci/switch/switchtec.c
index 3bdec509f948..0062225db50f 100644
--- a/drivers/pci/switch/switchtec.c
+++ b/drivers/pci/switch/switchtec.c
@@ -321,6 +321,9 @@ static ssize_t field ## _show(struct device *dev, \
if (stdev->gen == SWITCHTEC_GEN3) \
return io_string_show(buf, &si->gen3.field, \
sizeof(si->gen3.field)); \
+ else if (stdev->gen == SWITCHTEC_GEN4) \
+ return io_string_show(buf, &si->gen4.field, \
+ sizeof(si->gen4.field)); \
else \
return -ENOTSUPP; \
} \
@@ -1435,6 +1438,8 @@ static int switchtec_init_pci(struct switchtec_dev *stdev,

if (stdev->gen == SWITCHTEC_GEN3)
part_id = &stdev->mmio_sys_info->gen3.partition_id;
+ else if (stdev->gen == SWITCHTEC_GEN4)
+ part_id = &stdev->mmio_sys_info->gen4.partition_id;
else
return -ENOTSUPP;

diff --git a/include/linux/switchtec.h b/include/linux/switchtec.h
index 73817d02db1e..ea217af5260e 100644
--- a/include/linux/switchtec.h
+++ b/include/linux/switchtec.h
@@ -39,6 +39,7 @@ enum {

enum switchtec_gen {
SWITCHTEC_GEN3,
+ SWITCHTEC_GEN4,
};

struct mrpc_regs {
@@ -130,12 +131,54 @@ struct sys_info_regs_gen3 {
u8 component_revision;
} __packed;

+struct sys_info_regs_gen4 {
+ u16 gas_layout_ver;
+ u8 evlist_ver;
+ u8 reserved1;
+ u16 mgmt_cmd_set_ver;
+ u16 fabric_cmd_set_ver;
+ u32 reserved2[2];
+ u8 mrpc_uart_ver;
+ u8 mrpc_twi_ver;
+ u8 mrpc_eth_ver;
+ u8 mrpc_inband_ver;
+ u32 reserved3[7];
+ u32 fw_update_tmo;
+ u32 xml_version_cfg;
+ u32 xml_version_img;
+ u32 partition_id;
+ u16 bl2_running;
+ u16 cfg_running;
+ u16 img_running;
+ u16 key_running;
+ u32 reserved4[43];
+ u32 vendor_seeprom_twi;
+ u32 vendor_table_revision;
+ u32 vendor_specific_info[2];
+ u16 p2p_vendor_id;
+ u16 p2p_device_id;
+ u8 p2p_revision_id;
+ u8 reserved5[3];
+ u32 p2p_class_id;
+ u16 subsystem_vendor_id;
+ u16 subsystem_id;
+ u32 p2p_serial_number[2];
+ u8 mac_addr[6];
+ u8 reserved6[2];
+ u32 reserved7[3];
+ char vendor_id[8];
+ char product_id[24];
+ char product_revision[2];
+ u16 reserved8;
+} __packed;
+
struct sys_info_regs {
u32 device_id;
u32 device_version;
u32 firmware_version;
union {
struct sys_info_regs_gen3 gen3;
+ struct sys_info_regs_gen4 gen4;
};
} __packed;

--
2.20.1

2020-01-15 03:59:40

by Logan Gunthorpe

[permalink] [raw]
Subject: [PATCH v2 1/7] PCI/switchtec: Rename generation specific constants

Gen4 hardware will have different values for the SWITCHTEC_X_RUNNING
and SWITCHTEC_IOCTL_NUM_PARTITIONS, so rename them with GEN3 in their
name.

No functional changes intended.

Signed-off-by: Logan Gunthorpe <[email protected]>
---
drivers/pci/switch/switchtec.c | 10 +++++-----
include/linux/switchtec.h | 8 ++++----
include/uapi/linux/switchtec_ioctl.h | 5 ++++-
3 files changed, 13 insertions(+), 10 deletions(-)

diff --git a/drivers/pci/switch/switchtec.c b/drivers/pci/switch/switchtec.c
index 11f83caf6576..c5c957ce8499 100644
--- a/drivers/pci/switch/switchtec.c
+++ b/drivers/pci/switch/switchtec.c
@@ -575,7 +575,7 @@ static int ioctl_flash_info(struct switchtec_dev *stdev,
struct flash_info_regs __iomem *fi = stdev->mmio_flash_info;

info.flash_length = ioread32(&fi->flash_length);
- info.num_partitions = SWITCHTEC_IOCTL_NUM_PARTITIONS;
+ info.num_partitions = SWITCHTEC_NUM_PARTITIONS_GEN3;

if (copy_to_user(uinfo, &info, sizeof(info)))
return -EFAULT;
@@ -605,25 +605,25 @@ static int ioctl_flash_part_info(struct switchtec_dev *stdev,
case SWITCHTEC_IOCTL_PART_CFG0:
active_addr = ioread32(&fi->active_cfg);
set_fw_info_part(&info, &fi->cfg0);
- if (ioread16(&si->cfg_running) == SWITCHTEC_CFG0_RUNNING)
+ if (ioread16(&si->cfg_running) == SWITCHTEC_GEN3_CFG0_RUNNING)
info.active |= SWITCHTEC_IOCTL_PART_RUNNING;
break;
case SWITCHTEC_IOCTL_PART_CFG1:
active_addr = ioread32(&fi->active_cfg);
set_fw_info_part(&info, &fi->cfg1);
- if (ioread16(&si->cfg_running) == SWITCHTEC_CFG1_RUNNING)
+ if (ioread16(&si->cfg_running) == SWITCHTEC_GEN3_CFG1_RUNNING)
info.active |= SWITCHTEC_IOCTL_PART_RUNNING;
break;
case SWITCHTEC_IOCTL_PART_IMG0:
active_addr = ioread32(&fi->active_img);
set_fw_info_part(&info, &fi->img0);
- if (ioread16(&si->img_running) == SWITCHTEC_IMG0_RUNNING)
+ if (ioread16(&si->img_running) == SWITCHTEC_GEN3_IMG0_RUNNING)
info.active |= SWITCHTEC_IOCTL_PART_RUNNING;
break;
case SWITCHTEC_IOCTL_PART_IMG1:
active_addr = ioread32(&fi->active_img);
set_fw_info_part(&info, &fi->img1);
- if (ioread16(&si->img_running) == SWITCHTEC_IMG1_RUNNING)
+ if (ioread16(&si->img_running) == SWITCHTEC_GEN3_IMG1_RUNNING)
info.active |= SWITCHTEC_IOCTL_PART_RUNNING;
break;
case SWITCHTEC_IOCTL_PART_NVLOG:
diff --git a/include/linux/switchtec.h b/include/linux/switchtec.h
index 8ec992c88a34..07b0ddabd48b 100644
--- a/include/linux/switchtec.h
+++ b/include/linux/switchtec.h
@@ -103,10 +103,10 @@ struct sw_event_regs {
} __packed;

enum {
- SWITCHTEC_CFG0_RUNNING = 0x04,
- SWITCHTEC_CFG1_RUNNING = 0x05,
- SWITCHTEC_IMG0_RUNNING = 0x03,
- SWITCHTEC_IMG1_RUNNING = 0x07,
+ SWITCHTEC_GEN3_CFG0_RUNNING = 0x04,
+ SWITCHTEC_GEN3_CFG1_RUNNING = 0x05,
+ SWITCHTEC_GEN3_IMG0_RUNNING = 0x03,
+ SWITCHTEC_GEN3_IMG1_RUNNING = 0x07,
};

struct sys_info_regs {
diff --git a/include/uapi/linux/switchtec_ioctl.h b/include/uapi/linux/switchtec_ioctl.h
index e8db938985ca..4d09cfa2e9e6 100644
--- a/include/uapi/linux/switchtec_ioctl.h
+++ b/include/uapi/linux/switchtec_ioctl.h
@@ -32,7 +32,10 @@
#define SWITCHTEC_IOCTL_PART_VENDOR5 10
#define SWITCHTEC_IOCTL_PART_VENDOR6 11
#define SWITCHTEC_IOCTL_PART_VENDOR7 12
-#define SWITCHTEC_IOCTL_NUM_PARTITIONS 13
+#define SWITCHTEC_NUM_PARTITIONS_GEN3 13
+
+/* obsolete: for compatibility with old userspace software */
+#define SWITCHTEC_IOCTL_NUM_PARTITIONS SWITCHTEC_NUM_PARTITIONS_GEN3

struct switchtec_ioctl_flash_info {
__u64 flash_length;
--
2.20.1

2020-01-15 03:59:42

by Logan Gunthorpe

[permalink] [raw]
Subject: [PATCH v2 3/7] PCI/switchtec: Refactor ioctl_flash_part_info()

Refactor ioctl_flash_part_info() into a gen3 specific function seeing the
registers for flash partition information have changed significantly
in Gen4 and will require a completely different implementation.

No functional changes intended.

Co-developed-by: Kelvin Cao <[email protected]>
Signed-off-by: Kelvin Cao <[email protected]>
Signed-off-by: Logan Gunthorpe <[email protected]>
---
drivers/pci/switch/switchtec.c | 68 +++++++++++++++++++++-------------
1 file changed, 42 insertions(+), 26 deletions(-)

diff --git a/drivers/pci/switch/switchtec.c b/drivers/pci/switch/switchtec.c
index 0abc8bc8b03e..fe0b7d96c36a 100644
--- a/drivers/pci/switch/switchtec.c
+++ b/drivers/pci/switch/switchtec.c
@@ -612,75 +612,91 @@ static void set_fw_info_part(struct switchtec_ioctl_flash_part_info *info,
info->length = ioread32(&pi->length);
}

-static int ioctl_flash_part_info(struct switchtec_dev *stdev,
- struct switchtec_ioctl_flash_part_info __user *uinfo)
+static int flash_part_info_gen3(struct switchtec_dev *stdev,
+ struct switchtec_ioctl_flash_part_info *info)
{
- struct switchtec_ioctl_flash_part_info info = {0};
struct flash_info_regs __iomem *fi = stdev->mmio_flash_info;
struct sys_info_regs __iomem *si = stdev->mmio_sys_info;
u32 active_addr = -1;

- if (copy_from_user(&info, uinfo, sizeof(info)))
- return -EFAULT;
-
- switch (info.flash_partition) {
+ switch (info->flash_partition) {
case SWITCHTEC_IOCTL_PART_CFG0:
active_addr = ioread32(&fi->active_cfg);
- set_fw_info_part(&info, &fi->cfg0);
+ set_fw_info_part(info, &fi->cfg0);
if (ioread16(&si->cfg_running) == SWITCHTEC_GEN3_CFG0_RUNNING)
- info.active |= SWITCHTEC_IOCTL_PART_RUNNING;
+ info->active |= SWITCHTEC_IOCTL_PART_RUNNING;
break;
case SWITCHTEC_IOCTL_PART_CFG1:
active_addr = ioread32(&fi->active_cfg);
- set_fw_info_part(&info, &fi->cfg1);
+ set_fw_info_part(info, &fi->cfg1);
if (ioread16(&si->cfg_running) == SWITCHTEC_GEN3_CFG1_RUNNING)
- info.active |= SWITCHTEC_IOCTL_PART_RUNNING;
+ info->active |= SWITCHTEC_IOCTL_PART_RUNNING;
break;
case SWITCHTEC_IOCTL_PART_IMG0:
active_addr = ioread32(&fi->active_img);
- set_fw_info_part(&info, &fi->img0);
+ set_fw_info_part(info, &fi->img0);
if (ioread16(&si->img_running) == SWITCHTEC_GEN3_IMG0_RUNNING)
- info.active |= SWITCHTEC_IOCTL_PART_RUNNING;
+ info->active |= SWITCHTEC_IOCTL_PART_RUNNING;
break;
case SWITCHTEC_IOCTL_PART_IMG1:
active_addr = ioread32(&fi->active_img);
- set_fw_info_part(&info, &fi->img1);
+ set_fw_info_part(info, &fi->img1);
if (ioread16(&si->img_running) == SWITCHTEC_GEN3_IMG1_RUNNING)
- info.active |= SWITCHTEC_IOCTL_PART_RUNNING;
+ info->active |= SWITCHTEC_IOCTL_PART_RUNNING;
break;
case SWITCHTEC_IOCTL_PART_NVLOG:
- set_fw_info_part(&info, &fi->nvlog);
+ set_fw_info_part(info, &fi->nvlog);
break;
case SWITCHTEC_IOCTL_PART_VENDOR0:
- set_fw_info_part(&info, &fi->vendor[0]);
+ set_fw_info_part(info, &fi->vendor[0]);
break;
case SWITCHTEC_IOCTL_PART_VENDOR1:
- set_fw_info_part(&info, &fi->vendor[1]);
+ set_fw_info_part(info, &fi->vendor[1]);
break;
case SWITCHTEC_IOCTL_PART_VENDOR2:
- set_fw_info_part(&info, &fi->vendor[2]);
+ set_fw_info_part(info, &fi->vendor[2]);
break;
case SWITCHTEC_IOCTL_PART_VENDOR3:
- set_fw_info_part(&info, &fi->vendor[3]);
+ set_fw_info_part(info, &fi->vendor[3]);
break;
case SWITCHTEC_IOCTL_PART_VENDOR4:
- set_fw_info_part(&info, &fi->vendor[4]);
+ set_fw_info_part(info, &fi->vendor[4]);
break;
case SWITCHTEC_IOCTL_PART_VENDOR5:
- set_fw_info_part(&info, &fi->vendor[5]);
+ set_fw_info_part(info, &fi->vendor[5]);
break;
case SWITCHTEC_IOCTL_PART_VENDOR6:
- set_fw_info_part(&info, &fi->vendor[6]);
+ set_fw_info_part(info, &fi->vendor[6]);
break;
case SWITCHTEC_IOCTL_PART_VENDOR7:
- set_fw_info_part(&info, &fi->vendor[7]);
+ set_fw_info_part(info, &fi->vendor[7]);
break;
default:
return -EINVAL;
}

- if (info.address == active_addr)
- info.active |= SWITCHTEC_IOCTL_PART_ACTIVE;
+ if (info->address == active_addr)
+ info->active |= SWITCHTEC_IOCTL_PART_ACTIVE;
+
+ return 0;
+}
+
+static int ioctl_flash_part_info(struct switchtec_dev *stdev,
+ struct switchtec_ioctl_flash_part_info __user *uinfo)
+{
+ int ret;
+ struct switchtec_ioctl_flash_part_info info = {0};
+
+ if (copy_from_user(&info, uinfo, sizeof(info)))
+ return -EFAULT;
+
+ if (stdev->gen == SWITCHTEC_GEN3) {
+ ret = flash_part_info_gen3(stdev, &info);
+ if (ret)
+ return ret;
+ } else {
+ return -ENOTSUPP;
+ }

if (copy_to_user(uinfo, &info, sizeof(info)))
return -EFAULT;
--
2.20.1

2020-01-15 17:04:45

by Bjorn Helgaas

[permalink] [raw]
Subject: Re: [PATCH v2 0/7] Switchtec Gen4 Support

On Tue, Jan 14, 2020 at 08:56:41PM -0700, Logan Gunthorpe wrote:
> Hi,
>
> Here are the cleaned up version of the patches for Gen4 support in
> switchtec. The end result is mostly the same, save some very minor
> changes, but the organization into commits has been reworked per
> Bjorn's feedback. This set is also rebased onto pci/switchtec.

Beautiful. Applied to pci/switchtec, thank you very much!

> Kelvin Cao (2):
> PCI/switchtec: Add gen4 support for the flash information interface
> PCI/switchtec: Introduce gen4 variant IDS in the device ID table
>
> Logan Gunthorpe (5):
> PCI/switchtec: Rename generation specific constants
> PCI/switchtec: Introduce Generation Variable
> PCI/switchtec: Refactor ioctl_flash_part_info()
> PCI/switchtec: Separate out gen3 register structures into unionse
> PCI/switchtec: Add gen4 support for the system info registers
>
> drivers/pci/quirks.c | 18 ++
> drivers/pci/switch/switchtec.c | 334 +++++++++++++++++++++------
> include/linux/switchtec.h | 148 ++++++++++--
> include/uapi/linux/switchtec_ioctl.h | 13 +-
> 4 files changed, 424 insertions(+), 89 deletions(-)
>
> --
> 2.20.1