summaryrefslogtreecommitdiff
path: root/drivers/pci
diff options
context:
space:
mode:
authorKelvin Cao <kelvin.cao@microchip.com>2020-01-14 20:56:47 -0700
committerBjorn Helgaas <bhelgaas@google.com>2020-01-15 11:00:39 -0600
commit4efa1d2e36976d7b26f2e67f4c838330fbc91299 (patch)
tree4caab5002d4299e8ed65bcda5de6d65804893801 /drivers/pci
parenta3321ca394082f403b447646d81c18ff6b39f4a6 (diff)
PCI/switchtec: Add Gen4 flash information interface support
Add the new flash_info registers struct and the implementation of ioctl_flash_part_info() for the new Gen4 hardware. [logang@deltatee.com: rewrote commit message] Link: https://lore.kernel.org/r/20200115035648.2578-7-logang@deltatee.com Signed-off-by: Kelvin Cao <kelvin.cao@microchip.com> Signed-off-by: Logan Gunthorpe <logang@deltatee.com> Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
Diffstat (limited to 'drivers/pci')
-rw-r--r--drivers/pci/switch/switchtec.c111
1 files changed, 111 insertions, 0 deletions
diff --git a/drivers/pci/switch/switchtec.c b/drivers/pci/switch/switchtec.c
index b09c3f53a552..af85d232d200 100644
--- a/drivers/pci/switch/switchtec.c
+++ b/drivers/pci/switch/switchtec.c
@@ -600,6 +600,9 @@ static int ioctl_flash_info(struct switchtec_dev *stdev,
if (stdev->gen == SWITCHTEC_GEN3) {
info.flash_length = ioread32(&fi->gen3.flash_length);
info.num_partitions = SWITCHTEC_NUM_PARTITIONS_GEN3;
+ } else if (stdev->gen == SWITCHTEC_GEN4) {
+ info.flash_length = ioread32(&fi->gen4.flash_length);
+ info.num_partitions = SWITCHTEC_NUM_PARTITIONS_GEN4;
} else {
return -ENOTSUPP;
}
@@ -687,6 +690,110 @@ static int flash_part_info_gen3(struct switchtec_dev *stdev,
return 0;
}
+static int flash_part_info_gen4(struct switchtec_dev *stdev,
+ struct switchtec_ioctl_flash_part_info *info)
+{
+ struct flash_info_regs_gen4 __iomem *fi = &stdev->mmio_flash_info->gen4;
+ struct sys_info_regs_gen4 __iomem *si = &stdev->mmio_sys_info->gen4;
+ struct active_partition_info_gen4 __iomem *af = &fi->active_flag;
+
+ switch (info->flash_partition) {
+ case SWITCHTEC_IOCTL_PART_MAP_0:
+ set_fw_info_part(info, &fi->map0);
+ break;
+ case SWITCHTEC_IOCTL_PART_MAP_1:
+ set_fw_info_part(info, &fi->map1);
+ break;
+ case SWITCHTEC_IOCTL_PART_KEY_0:
+ set_fw_info_part(info, &fi->key0);
+ if (ioread8(&af->key) == SWITCHTEC_GEN4_KEY0_ACTIVE)
+ info->active |= SWITCHTEC_IOCTL_PART_ACTIVE;
+ if (ioread16(&si->key_running) == SWITCHTEC_GEN4_KEY0_RUNNING)
+ info->active |= SWITCHTEC_IOCTL_PART_RUNNING;
+ break;
+ case SWITCHTEC_IOCTL_PART_KEY_1:
+ set_fw_info_part(info, &fi->key1);
+ if (ioread8(&af->key) == SWITCHTEC_GEN4_KEY1_ACTIVE)
+ info->active |= SWITCHTEC_IOCTL_PART_ACTIVE;
+ if (ioread16(&si->key_running) == SWITCHTEC_GEN4_KEY1_RUNNING)
+ info->active |= SWITCHTEC_IOCTL_PART_RUNNING;
+ break;
+ case SWITCHTEC_IOCTL_PART_BL2_0:
+ set_fw_info_part(info, &fi->bl2_0);
+ if (ioread8(&af->bl2) == SWITCHTEC_GEN4_BL2_0_ACTIVE)
+ info->active |= SWITCHTEC_IOCTL_PART_ACTIVE;
+ if (ioread16(&si->bl2_running) == SWITCHTEC_GEN4_BL2_0_RUNNING)
+ info->active |= SWITCHTEC_IOCTL_PART_RUNNING;
+ break;
+ case SWITCHTEC_IOCTL_PART_BL2_1:
+ set_fw_info_part(info, &fi->bl2_1);
+ if (ioread8(&af->bl2) == SWITCHTEC_GEN4_BL2_1_ACTIVE)
+ info->active |= SWITCHTEC_IOCTL_PART_ACTIVE;
+ if (ioread16(&si->bl2_running) == SWITCHTEC_GEN4_BL2_1_RUNNING)
+ info->active |= SWITCHTEC_IOCTL_PART_RUNNING;
+ break;
+ case SWITCHTEC_IOCTL_PART_CFG0:
+ set_fw_info_part(info, &fi->cfg0);
+ if (ioread8(&af->cfg) == SWITCHTEC_GEN4_CFG0_ACTIVE)
+ info->active |= SWITCHTEC_IOCTL_PART_ACTIVE;
+ if (ioread16(&si->cfg_running) == SWITCHTEC_GEN4_CFG0_RUNNING)
+ info->active |= SWITCHTEC_IOCTL_PART_RUNNING;
+ break;
+ case SWITCHTEC_IOCTL_PART_CFG1:
+ set_fw_info_part(info, &fi->cfg1);
+ if (ioread8(&af->cfg) == SWITCHTEC_GEN4_CFG1_ACTIVE)
+ info->active |= SWITCHTEC_IOCTL_PART_ACTIVE;
+ if (ioread16(&si->cfg_running) == SWITCHTEC_GEN4_CFG1_RUNNING)
+ info->active |= SWITCHTEC_IOCTL_PART_RUNNING;
+ break;
+ case SWITCHTEC_IOCTL_PART_IMG0:
+ set_fw_info_part(info, &fi->img0);
+ if (ioread8(&af->img) == SWITCHTEC_GEN4_IMG0_ACTIVE)
+ info->active |= SWITCHTEC_IOCTL_PART_ACTIVE;
+ if (ioread16(&si->img_running) == SWITCHTEC_GEN4_IMG0_RUNNING)
+ info->active |= SWITCHTEC_IOCTL_PART_RUNNING;
+ break;
+ case SWITCHTEC_IOCTL_PART_IMG1:
+ set_fw_info_part(info, &fi->img1);
+ if (ioread8(&af->img) == SWITCHTEC_GEN4_IMG1_ACTIVE)
+ info->active |= SWITCHTEC_IOCTL_PART_ACTIVE;
+ if (ioread16(&si->img_running) == SWITCHTEC_GEN4_IMG1_RUNNING)
+ info->active |= SWITCHTEC_IOCTL_PART_RUNNING;
+ break;
+ case SWITCHTEC_IOCTL_PART_NVLOG:
+ set_fw_info_part(info, &fi->nvlog);
+ break;
+ case SWITCHTEC_IOCTL_PART_VENDOR0:
+ set_fw_info_part(info, &fi->vendor[0]);
+ break;
+ case SWITCHTEC_IOCTL_PART_VENDOR1:
+ set_fw_info_part(info, &fi->vendor[1]);
+ break;
+ case SWITCHTEC_IOCTL_PART_VENDOR2:
+ set_fw_info_part(info, &fi->vendor[2]);
+ break;
+ case SWITCHTEC_IOCTL_PART_VENDOR3:
+ set_fw_info_part(info, &fi->vendor[3]);
+ break;
+ case SWITCHTEC_IOCTL_PART_VENDOR4:
+ set_fw_info_part(info, &fi->vendor[4]);
+ break;
+ case SWITCHTEC_IOCTL_PART_VENDOR5:
+ set_fw_info_part(info, &fi->vendor[5]);
+ break;
+ case SWITCHTEC_IOCTL_PART_VENDOR6:
+ set_fw_info_part(info, &fi->vendor[6]);
+ break;
+ case SWITCHTEC_IOCTL_PART_VENDOR7:
+ set_fw_info_part(info, &fi->vendor[7]);
+ break;
+ default:
+ return -EINVAL;
+ }
+
+ return 0;
+}
+
static int ioctl_flash_part_info(struct switchtec_dev *stdev,
struct switchtec_ioctl_flash_part_info __user *uinfo)
{
@@ -700,6 +807,10 @@ static int ioctl_flash_part_info(struct switchtec_dev *stdev,
ret = flash_part_info_gen3(stdev, &info);
if (ret)
return ret;
+ } else if (stdev->gen == SWITCHTEC_GEN4) {
+ ret = flash_part_info_gen4(stdev, &info);
+ if (ret)
+ return ret;
} else {
return -ENOTSUPP;
}