[v3,2/4] raw/ifpga/base: update board information

Message ID 1655450375-10739-3-git-send-email-wei.huang@intel.com (mailing list archive)
State Accepted, archived
Delegated to: Thomas Monjalon
Headers
Series introduce PMCI driver |

Checks

Context Check Description
ci/checkpatch success coding style OK

Commit Message

Wei Huang June 17, 2022, 7:19 a.m. UTC
  N6000 ADP platform has different definition of board information,
they can be recognized after this patch.

Signed-off-by: Wei Huang <wei.huang@intel.com>
---
 drivers/raw/ifpga/base/ifpga_defines.h    | 101 +++++++++++++++----------
 drivers/raw/ifpga/base/ifpga_fme.c        | 121 ++++++++++++++++++++----------
 drivers/raw/ifpga/base/ifpga_fme_error.c  |   2 +
 drivers/raw/ifpga/base/ifpga_port_error.c |   2 +-
 drivers/raw/ifpga/base/opae_intel_max10.c |  45 +++++++++++
 drivers/raw/ifpga/base/opae_intel_max10.h |   3 +
 6 files changed, 194 insertions(+), 80 deletions(-)
  

Comments

Zhang, Tianfei June 17, 2022, 8:57 a.m. UTC | #1
> -----Original Message-----
> From: Huang, Wei <wei.huang@intel.com>
> Sent: Friday, June 17, 2022 3:20 PM
> To: dev@dpdk.org; thomas@monjalon.net; nipun.gupta@nxp.com;
> hemant.agrawal@nxp.com
> Cc: stable@dpdk.org; Xu, Rosen <rosen.xu@intel.com>; Zhang, Tianfei
> <tianfei.zhang@intel.com>; Zhang, Qi Z <qi.z.zhang@intel.com>; Huang, Wei
> <wei.huang@intel.com>
> Subject: [PATCH v3 2/4] raw/ifpga/base: update board information
> 
> N6000 ADP platform has different definition of board information, they can be
> recognized after this patch.
> 
> Signed-off-by: Wei Huang <wei.huang@intel.com>
> ---
>  drivers/raw/ifpga/base/ifpga_defines.h    | 101 +++++++++++++++----------
>  drivers/raw/ifpga/base/ifpga_fme.c        | 121 ++++++++++++++++++++----------
>  drivers/raw/ifpga/base/ifpga_fme_error.c  |   2 +
>  drivers/raw/ifpga/base/ifpga_port_error.c |   2 +-
>  drivers/raw/ifpga/base/opae_intel_max10.c |  45 +++++++++++
>  drivers/raw/ifpga/base/opae_intel_max10.h |   3 +
>  6 files changed, 194 insertions(+), 80 deletions(-)
> 
> diff --git a/drivers/raw/ifpga/base/ifpga_defines.h
> b/drivers/raw/ifpga/base/ifpga_defines.h
> index f84ed1d..7c8fa89 100644
> --- a/drivers/raw/ifpga/base/ifpga_defines.h
> +++ b/drivers/raw/ifpga/base/ifpga_defines.h
> @@ -268,6 +268,24 @@ struct feature_fme_bitstream_id {
>  	union {
>  		u64 csr;
>  		struct {
> +			u8 build_patch:8;
> +			u8 build_minor:8;
> +			u8 build_major:8;
> +			u8 fvl_bypass:1;
> +			u8 mac_lightweight:1;
> +			u8 disagregate:1;
> +			u8 lightweiht:1;
> +			u8 seu:1;
> +			u8 ptp:1;
> +			u8 reserve:2;
> +			u8 interface:4;
> +			u32 afu_revision:12;
> +			u8 patch:4;
> +			u8 minor:4;
> +			u8 major:4;
> +			u8 reserved:4;
> +		} v1;
> +		struct {
>  			u32 gitrepo_hash:32;	/* GIT repository hash */
>  			/*
>  			 * HSSI configuration identifier:
> @@ -276,7 +294,8 @@ struct feature_fme_bitstream_id {
>  			 * 2 - Ethernet
>  			 */
>  			u8  hssi_id:4;
> -			u16 rsvd1:12;		/* Reserved */
> +			u8  rsvd1:4;
> +			u8  fim_type:8;
>  			/* Bitstream version patch number */
>  			u8  bs_verpatch:4;
>  			/* Bitstream version minor number */ @@ -285,7
> +304,7 @@ struct feature_fme_bitstream_id {
>  			u8  bs_vermajor:4;
>  			/* Bitstream version debug number */
>  			u8  bs_verdebug:4;
> -		};
> +		} v2;
>  	};
>  };
> 
> @@ -1672,31 +1691,6 @@ struct bts_header {
> 
>  #define check_support(n) (n == 1 ? "support" : "no")
> 
> -/* bitstream id definition */
> -struct fme_bitstream_id {
> -	union {
> -		u64 id;
> -		struct {
> -			u8 build_patch:8;
> -			u8 build_minor:8;
> -			u8 build_major:8;
> -			u8 fvl_bypass:1;
> -			u8 mac_lightweight:1;
> -			u8 disagregate:1;
> -			u8 lightweiht:1;
> -			u8 seu:1;
> -			u8 ptp:1;
> -			u8 reserve:2;
> -			u8 interface:4;
> -			u32 afu_revision:12;
> -			u8 patch:4;
> -			u8 minor:4;
> -			u8 major:4;
> -			u8 reserved:4;
> -		};
> -	};
> -};
> -
>  enum board_interface {
>  	VC_8_10G = 0,
>  	VC_4_25G = 1,
> @@ -1705,10 +1699,30 @@ enum board_interface {
>  	VC_2_2_25G = 4,
>  };
> 
> +enum fim_type {
> +	BASE_ADP = 0,
> +	BASE_FDK,
> +	BASE_X16_ADP,
> +	BASE_X16_FDK,
> +	FIMA_10G_ADP,
> +	FIMA_25G_ADP,
> +	FIMA_100G_ADP,
> +	FIMB_ADP,
> +	FIMC_ADP
> +};
> +
> +enum hssi_id {
> +	NO_HSSI = 0,
> +	PCIE_RP,
> +	ETHER_NET
> +};
> +
>  enum pac_major {
>  	VISTA_CREEK = 0,
>  	RUSH_CREEK = 1,
>  	DARBY_CREEK = 2,
> +	LIGHTNING_CREEK = 3,
> +	ARROW_CREEK = 5,
>  };
> 
>  enum pac_minor {
> @@ -1720,23 +1734,30 @@ enum pac_minor {  struct opae_board_info {
>  	enum pac_major major;
>  	enum pac_minor minor;
> -	enum board_interface type;
> -
> -	/* PAC features */
> -	u8 fvl_bypass;
> -	u8 mac_lightweight;
> -	u8 disaggregate;
> -	u8 lightweight;
> -	u8 seu;
> -	u8 ptp;
> 
>  	u32 boot_page;
>  	u32 max10_version;
>  	u32 nios_fw_version;
> -	u32 nums_of_retimer;
> -	u32 ports_per_retimer;
> -	u32 nums_of_fvl;
> -	u32 ports_per_fvl;
> +
> +	union {
> +		struct {  /* N3000 specific */
> +			enum board_interface type;
> +			u8 fvl_bypass;
> +			u8 mac_lightweight;
> +			u8 disaggregate;
> +			u8 lightweight;
> +			u8 seu;
> +			u8 ptp;
> +			u32 nums_of_retimer;
> +			u32 ports_per_retimer;
> +			u32 nums_of_fvl;
> +			u32 ports_per_fvl;
> +		};
> +		struct {
> +			enum fim_type n6000_fim_type;
> +			enum hssi_id n6000_hssi_id;
> +		};
> +	};
>  };
> 
>  #pragma pack(pop)
> diff --git a/drivers/raw/ifpga/base/ifpga_fme.c
> b/drivers/raw/ifpga/base/ifpga_fme.c
> index 4d089d2..608a352 100644
> --- a/drivers/raw/ifpga/base/ifpga_fme.c
> +++ b/drivers/raw/ifpga/base/ifpga_fme.c
> @@ -790,19 +790,32 @@ struct ifpga_feature_ops fme_emif_ops = {
>  	.uinit = fme_emif_uinit,
>  };
> 
> -static const char *board_type_to_string(u32 type) -{
> -	switch (type) {
> -	case VC_8_10G:
> -		return "VC_8x10G";
> -	case VC_4_25G:
> -		return "VC_4x25G";
> -	case VC_2_1_25:
> -		return "VC_2x1x25G";
> -	case VC_4_25G_2_25G:
> -		return "VC_4x25G+2x25G";
> -	case VC_2_2_25G:
> -		return "VC_2x2x25G";
> +static const char *board_type_to_string(u32 board, u32 type) {
> +	if (board == VISTA_CREEK) {
> +		switch (type) {
> +		case VC_8_10G:
> +			return "8x10G";
> +		case VC_4_25G:
> +			return "4x25G";
> +		case VC_2_1_25:
> +			return "2x1x25G";
> +		case VC_4_25G_2_25G:
> +			return "4x25G+2x25G";
> +		case VC_2_2_25G:
> +			return "2x2x25G";
> +		break;
> +		}
> +	} else {
> +		switch (type) {
> +		case FIMA_10G_ADP:
> +			return "2x4x10G";
> +		case FIMA_25G_ADP:
> +			return "2x2x25G";
> +		case FIMA_100G_ADP:
> +			return "2x100G";
> +		break;
> +		}
>  	}
> 
>  	return "unknown";
> @@ -817,6 +830,12 @@ static const char *board_major_to_string(u32 major)
>  		return "RUSH_CREEK";
>  	case DARBY_CREEK:
>  		return "DARBY_CREEK";
> +	case LIGHTNING_CREEK:
> +		return "LIGHTNING_CREEK";
> +	case ARROW_CREEK:
> +		return "ARROW_CREEK";
> +	default:
> +		break;
>  	}
> 
>  	return "unknown";
> @@ -859,35 +878,56 @@ static int board_type_to_info(u32 type,
> 
>  static int fme_get_board_interface(struct ifpga_fme_hw *fme)  {
> -	struct fme_bitstream_id id;
> +	struct feature_fme_bitstream_id id;
>  	struct ifpga_hw *hw;
>  	u32 val;
> +	const char *type = NULL;
> +	int ret;
> 
>  	hw = fme->parent;
>  	if (!hw)
>  		return -ENODEV;
> 
> -	if (fme_hdr_get_bitstream_id(fme, &id.id))
> +	if (fme_hdr_get_bitstream_id(fme, &id.csr))
>  		return -EINVAL;
> 
> -	fme->board_info.major = id.major;
> -	fme->board_info.minor = id.minor;
> -	fme->board_info.type = id.interface;
> -	fme->board_info.fvl_bypass = id.fvl_bypass;
> -	fme->board_info.mac_lightweight = id.mac_lightweight;
> -	fme->board_info.lightweight = id.lightweiht;
> -	fme->board_info.disaggregate = id.disagregate;
> -	fme->board_info.seu = id.seu;
> -	fme->board_info.ptp = id.ptp;
> +	if (id.v1.major == ARROW_CREEK) {
> +		fme->board_info.major = id.v2.bs_vermajor;
> +		fme->board_info.minor = id.v2.bs_verminor;
> +		fme->board_info.n6000_fim_type = id.v2.fim_type;
> +		fme->board_info.n6000_hssi_id = id.v2.hssi_id;
> +		type = board_type_to_string(fme->board_info.major,
> +				fme->board_info.n6000_fim_type);
> +	} else {
> +		fme->board_info.major = id.v1.major;
> +		fme->board_info.minor = id.v1.minor;
> +		fme->board_info.type = id.v1.interface;
> +		fme->board_info.fvl_bypass = id.v1.fvl_bypass;
> +		fme->board_info.mac_lightweight = id.v1.mac_lightweight;
> +		fme->board_info.lightweight = id.v1.lightweiht;
> +		fme->board_info.disaggregate = id.v1.disagregate;
> +		fme->board_info.seu = id.v1.seu;
> +		fme->board_info.ptp = id.v1.ptp;
> +		type = board_type_to_string(fme->board_info.major,
> +				fme->board_info.type);
> +	}
> 
>  	dev_info(fme, "found: PCI dev: %02x:%02x:%x board: %s type: %s\n",
>  			hw->pci_data->bus,
>  			hw->pci_data->devid,
>  			hw->pci_data->function,
>  			board_major_to_string(fme->board_info.major),
> -			board_type_to_string(fme->board_info.type));
> +			type);
> 
> -	dev_info(fme, "support feature:\n"
> +	ret = max10_get_fpga_load_info(fme->max10_dev, &val);
> +	if (ret)
> +		return ret;
> +	fme->board_info.boot_page = val;
> +
> +	if (fme->board_info.major == VISTA_CREEK) {
> +		dev_info(dev, "FPGA loaded from %s Image\n",
> +			val ? "User" : "Factory");
> +		dev_info(fme, "support feature:\n"
>  			"fvl_bypass:%s\n"
>  			"mac_lightweight:%s\n"
>  			"lightweight:%s\n"
> @@ -901,26 +941,29 @@ static int fme_get_board_interface(struct
> ifpga_fme_hw *fme)
>  			check_support(fme->board_info.seu),
>  			check_support(fme->board_info.ptp));
> 
> +		if (board_type_to_info(fme->board_info.type, &fme-
> >board_info))
> +			return -EINVAL;
> 
> -	if (board_type_to_info(fme->board_info.type, &fme->board_info))
> -		return -EINVAL;
> -
> -	dev_info(fme, "get board info: nums_retimers %d ports_per_retimer %d
> nums_fvl %d ports_per_fvl %d\n",
> +		dev_info(fme, "get board info: nums_retimers %d "
> +			"ports_per_retimer %d nums_fvl %d "
> +			"ports_per_fvl %d\n",
>  			fme->board_info.nums_of_retimer,
>  			fme->board_info.ports_per_retimer,
>  			fme->board_info.nums_of_fvl,
>  			fme->board_info.ports_per_fvl);
> +	} else {
> +		dev_info(dev, "FPGA loaded from %s Image\n",
> +			val ? (val == 1 ? "User1" : "User2") : "Factory");
> +	}
> 
> -	if (max10_sys_read(fme->max10_dev, FPGA_PAGE_INFO, &val))
> -		return -EINVAL;
> -	fme->board_info.boot_page = val & 0x7;
> -
> -	if (max10_sys_read(fme->max10_dev, MAX10_BUILD_VER, &val))
> -		return -EINVAL;
> +	ret = max10_get_bmc_version(fme->max10_dev, &val);
> +	if (ret)
> +		return ret;
>  	fme->board_info.max10_version = val;
> 
> -	if (max10_sys_read(fme->max10_dev, NIOS2_FW_VERSION, &val))
> -		return -EINVAL;
> +	ret = max10_get_bmcfw_version(fme->max10_dev, &val);
> +	if (ret)
> +		return ret;
>  	fme->board_info.nios_fw_version = val;
> 
>  	dev_info(fme, "max10 version 0x%x, nios fw version 0x%x\n", @@ -
> 1023,7 +1066,7 @@ static int fme_spi_init(struct ifpga_feature *feature)
>  	opae_free(max10);
>  release_dev:
>  	altera_spi_release(spi_master);
> -	return ret;
> +	return -ENODEV;
>  }
> 
>  static void fme_spi_uinit(struct ifpga_feature *feature) diff --git
> a/drivers/raw/ifpga/base/ifpga_fme_error.c
> b/drivers/raw/ifpga/base/ifpga_fme_error.c
> index 5905eac..c5bed28 100644
> --- a/drivers/raw/ifpga/base/ifpga_fme_error.c
> +++ b/drivers/raw/ifpga/base/ifpga_fme_error.c
> @@ -224,6 +224,8 @@ static int fme_global_error_init(struct ifpga_feature
> *feature)  {
>  	struct ifpga_fme_hw *fme = feature->parent;
> 
> +	dev_info(NULL, "FME error_module Init.\n");
> +
>  	fme_error_enable(fme);
> 
>  	if (feature->ctx_num)
> diff --git a/drivers/raw/ifpga/base/ifpga_port_error.c
> b/drivers/raw/ifpga/base/ifpga_port_error.c
> index 189f762..6c8a7d7 100644
> --- a/drivers/raw/ifpga/base/ifpga_port_error.c
> +++ b/drivers/raw/ifpga/base/ifpga_port_error.c
> @@ -88,7 +88,7 @@ static int port_error_init(struct ifpga_feature *feature)  {
>  	struct ifpga_port_hw *port = feature->parent;
> 
> -	dev_info(NULL, "port error Init.\n");
> +	dev_info(NULL, "port error_module Init.\n");
> 
>  	spinlock_lock(&port->lock);
>  	port_err_mask(port, false);
> diff --git a/drivers/raw/ifpga/base/opae_intel_max10.c
> b/drivers/raw/ifpga/base/opae_intel_max10.c
> index 901a258..26f323c 100644
> --- a/drivers/raw/ifpga/base/opae_intel_max10.c
> +++ b/drivers/raw/ifpga/base/opae_intel_max10.c
> @@ -766,6 +766,51 @@ static int max10_staging_area_init(struct
> intel_max10_device *dev)
>  	return 0;
>  }
> 
> +int max10_get_fpga_load_info(struct intel_max10_device *dev, unsigned
> +int *val) {
> +	int ret;
> +	unsigned int value;
> +
> +	/* read FPGA loading information */
> +	ret = max10_sys_read(dev, dev->csr->fpga_page_info, &value);
> +	if (ret) {
> +		dev_err(dev, "fail to get FPGA loading info\n");
> +		return ret;
> +	}
> +
> +	if (dev->type == M10_N3000)
> +		*val = value & 0x7;
> +	else if (dev->type == M10_N6000) {
> +		if (!GET_FIELD(PMCI_FPGA_CONFIGURED, value))
> +			return -EINVAL;
> +		*val = GET_FIELD(PMCI_FPGA_BOOT_PAGE, value);
> +	}
> +
> +	return 0;
> +}
> +
> +int max10_get_bmc_version(struct intel_max10_device *dev, unsigned int
> +*val) {
> +	int ret;
> +
> +	ret = max10_sys_read(dev, dev->csr->build_version, val);
> +	if (ret)
> +		return ret;
> +
> +	return 0;
> +}
> +
> +int max10_get_bmcfw_version(struct intel_max10_device *dev, unsigned
> +int *val) {
> +	int ret;
> +
> +	ret = max10_sys_read(dev, dev->csr->fw_version, val);
> +	if (ret)
> +		return ret;
> +
> +	return 0;
> +}
> +
>  static const struct m10bmc_csr m10bmc_spi_csr = {
>  	.base = MAX10_SEC_BASE_ADDR,
>  	.build_version = MAX10_BUILD_VER,
> diff --git a/drivers/raw/ifpga/base/opae_intel_max10.h
> b/drivers/raw/ifpga/base/opae_intel_max10.h
> index 0d31196..6a1b122 100644
> --- a/drivers/raw/ifpga/base/opae_intel_max10.h
> +++ b/drivers/raw/ifpga/base/opae_intel_max10.h
> @@ -336,6 +336,9 @@ int max10_reg_write(struct intel_max10_device *dev,
>  	unsigned int offset, unsigned int val);  int max10_sys_update_bits(struct
> intel_max10_device *dev,
>  	unsigned int offset, unsigned int msk, unsigned int val);
> +int max10_get_bmcfw_version(struct intel_max10_device *dev, unsigned
> +int *val); int max10_get_bmc_version(struct intel_max10_device *dev,
> +unsigned int *val); int max10_get_fpga_load_info(struct
> +intel_max10_device *dev, unsigned int *val);
>  int intel_max10_device_init(struct intel_max10_device *dev);  int
> intel_max10_device_remove(struct intel_max10_device *dev);
> 
> --
> 1.8.3.1

It looks good for me.
Acked-by: Tianfei Zhang <tianfei.zhang@intel.com>
  
Xu, Rosen June 17, 2022, 2:42 p.m. UTC | #2
Hi,

> -----Original Message-----
> From: Huang, Wei <wei.huang@intel.com>
> Sent: Friday, June 17, 2022 15:20
> To: dev@dpdk.org; thomas@monjalon.net; nipun.gupta@nxp.com;
> hemant.agrawal@nxp.com
> Cc: stable@dpdk.org; Xu, Rosen <rosen.xu@intel.com>; Zhang, Tianfei
> <tianfei.zhang@intel.com>; Zhang, Qi Z <qi.z.zhang@intel.com>; Huang, Wei
> <wei.huang@intel.com>
> Subject: [PATCH v3 2/4] raw/ifpga/base: update board information
> 
> N6000 ADP platform has different definition of board information, they can
> be recognized after this patch.
> 
> Signed-off-by: Wei Huang <wei.huang@intel.com>
> ---
>  drivers/raw/ifpga/base/ifpga_defines.h    | 101 +++++++++++++++----------
>  drivers/raw/ifpga/base/ifpga_fme.c        | 121 ++++++++++++++++++++-----
> -----
>  drivers/raw/ifpga/base/ifpga_fme_error.c  |   2 +
>  drivers/raw/ifpga/base/ifpga_port_error.c |   2 +-
>  drivers/raw/ifpga/base/opae_intel_max10.c |  45 +++++++++++
>  drivers/raw/ifpga/base/opae_intel_max10.h |   3 +
>  6 files changed, 194 insertions(+), 80 deletions(-)
> 
> diff --git a/drivers/raw/ifpga/base/ifpga_defines.h
> b/drivers/raw/ifpga/base/ifpga_defines.h
> index f84ed1d..7c8fa89 100644
> --- a/drivers/raw/ifpga/base/ifpga_defines.h
> +++ b/drivers/raw/ifpga/base/ifpga_defines.h
> @@ -268,6 +268,24 @@ struct feature_fme_bitstream_id {
>  	union {
>  		u64 csr;
>  		struct {
> +			u8 build_patch:8;
> +			u8 build_minor:8;
> +			u8 build_major:8;
> +			u8 fvl_bypass:1;
> +			u8 mac_lightweight:1;
> +			u8 disagregate:1;
> +			u8 lightweiht:1;
> +			u8 seu:1;
> +			u8 ptp:1;
> +			u8 reserve:2;
> +			u8 interface:4;
> +			u32 afu_revision:12;
> +			u8 patch:4;
> +			u8 minor:4;
> +			u8 major:4;
> +			u8 reserved:4;
> +		} v1;
> +		struct {
>  			u32 gitrepo_hash:32;	/* GIT repository hash */
>  			/*
>  			 * HSSI configuration identifier:
> @@ -276,7 +294,8 @@ struct feature_fme_bitstream_id {
>  			 * 2 - Ethernet
>  			 */
>  			u8  hssi_id:4;
> -			u16 rsvd1:12;		/* Reserved */
> +			u8  rsvd1:4;
> +			u8  fim_type:8;
>  			/* Bitstream version patch number */
>  			u8  bs_verpatch:4;
>  			/* Bitstream version minor number */ @@ -285,7
> +304,7 @@ struct feature_fme_bitstream_id {
>  			u8  bs_vermajor:4;
>  			/* Bitstream version debug number */
>  			u8  bs_verdebug:4;
> -		};
> +		} v2;
>  	};
>  };
> 
> @@ -1672,31 +1691,6 @@ struct bts_header {
> 
>  #define check_support(n) (n == 1 ? "support" : "no")
> 
> -/* bitstream id definition */
> -struct fme_bitstream_id {
> -	union {
> -		u64 id;
> -		struct {
> -			u8 build_patch:8;
> -			u8 build_minor:8;
> -			u8 build_major:8;
> -			u8 fvl_bypass:1;
> -			u8 mac_lightweight:1;
> -			u8 disagregate:1;
> -			u8 lightweiht:1;
> -			u8 seu:1;
> -			u8 ptp:1;
> -			u8 reserve:2;
> -			u8 interface:4;
> -			u32 afu_revision:12;
> -			u8 patch:4;
> -			u8 minor:4;
> -			u8 major:4;
> -			u8 reserved:4;
> -		};
> -	};
> -};
> -
>  enum board_interface {
>  	VC_8_10G = 0,
>  	VC_4_25G = 1,
> @@ -1705,10 +1699,30 @@ enum board_interface {
>  	VC_2_2_25G = 4,
>  };
> 
> +enum fim_type {
> +	BASE_ADP = 0,
> +	BASE_FDK,
> +	BASE_X16_ADP,
> +	BASE_X16_FDK,
> +	FIMA_10G_ADP,
> +	FIMA_25G_ADP,
> +	FIMA_100G_ADP,
> +	FIMB_ADP,
> +	FIMC_ADP
> +};
> +
> +enum hssi_id {
> +	NO_HSSI = 0,
> +	PCIE_RP,
> +	ETHER_NET
> +};
> +
>  enum pac_major {
>  	VISTA_CREEK = 0,
>  	RUSH_CREEK = 1,
>  	DARBY_CREEK = 2,
> +	LIGHTNING_CREEK = 3,
> +	ARROW_CREEK = 5,
>  };
> 
>  enum pac_minor {
> @@ -1720,23 +1734,30 @@ enum pac_minor {  struct opae_board_info {
>  	enum pac_major major;
>  	enum pac_minor minor;
> -	enum board_interface type;
> -
> -	/* PAC features */
> -	u8 fvl_bypass;
> -	u8 mac_lightweight;
> -	u8 disaggregate;
> -	u8 lightweight;
> -	u8 seu;
> -	u8 ptp;
> 
>  	u32 boot_page;
>  	u32 max10_version;
>  	u32 nios_fw_version;
> -	u32 nums_of_retimer;
> -	u32 ports_per_retimer;
> -	u32 nums_of_fvl;
> -	u32 ports_per_fvl;
> +
> +	union {
> +		struct {  /* N3000 specific */
> +			enum board_interface type;
> +			u8 fvl_bypass;
> +			u8 mac_lightweight;
> +			u8 disaggregate;
> +			u8 lightweight;
> +			u8 seu;
> +			u8 ptp;
> +			u32 nums_of_retimer;
> +			u32 ports_per_retimer;
> +			u32 nums_of_fvl;
> +			u32 ports_per_fvl;
> +		};
> +		struct {
> +			enum fim_type n6000_fim_type;
> +			enum hssi_id n6000_hssi_id;
> +		};
> +	};
>  };
> 
>  #pragma pack(pop)
> diff --git a/drivers/raw/ifpga/base/ifpga_fme.c
> b/drivers/raw/ifpga/base/ifpga_fme.c
> index 4d089d2..608a352 100644
> --- a/drivers/raw/ifpga/base/ifpga_fme.c
> +++ b/drivers/raw/ifpga/base/ifpga_fme.c
> @@ -790,19 +790,32 @@ struct ifpga_feature_ops fme_emif_ops = {
>  	.uinit = fme_emif_uinit,
>  };
> 
> -static const char *board_type_to_string(u32 type) -{
> -	switch (type) {
> -	case VC_8_10G:
> -		return "VC_8x10G";
> -	case VC_4_25G:
> -		return "VC_4x25G";
> -	case VC_2_1_25:
> -		return "VC_2x1x25G";
> -	case VC_4_25G_2_25G:
> -		return "VC_4x25G+2x25G";
> -	case VC_2_2_25G:
> -		return "VC_2x2x25G";
> +static const char *board_type_to_string(u32 board, u32 type) {
> +	if (board == VISTA_CREEK) {
> +		switch (type) {
> +		case VC_8_10G:
> +			return "8x10G";
> +		case VC_4_25G:
> +			return "4x25G";
> +		case VC_2_1_25:
> +			return "2x1x25G";
> +		case VC_4_25G_2_25G:
> +			return "4x25G+2x25G";
> +		case VC_2_2_25G:
> +			return "2x2x25G";
> +		break;
> +		}
> +	} else {
> +		switch (type) {
> +		case FIMA_10G_ADP:
> +			return "2x4x10G";
> +		case FIMA_25G_ADP:
> +			return "2x2x25G";
> +		case FIMA_100G_ADP:
> +			return "2x100G";
> +		break;
> +		}
>  	}
> 
>  	return "unknown";
> @@ -817,6 +830,12 @@ static const char *board_major_to_string(u32 major)
>  		return "RUSH_CREEK";
>  	case DARBY_CREEK:
>  		return "DARBY_CREEK";
> +	case LIGHTNING_CREEK:
> +		return "LIGHTNING_CREEK";
> +	case ARROW_CREEK:
> +		return "ARROW_CREEK";
> +	default:
> +		break;
>  	}
> 
>  	return "unknown";
> @@ -859,35 +878,56 @@ static int board_type_to_info(u32 type,
> 
>  static int fme_get_board_interface(struct ifpga_fme_hw *fme)  {
> -	struct fme_bitstream_id id;
> +	struct feature_fme_bitstream_id id;
>  	struct ifpga_hw *hw;
>  	u32 val;
> +	const char *type = NULL;
> +	int ret;
> 
>  	hw = fme->parent;
>  	if (!hw)
>  		return -ENODEV;
> 
> -	if (fme_hdr_get_bitstream_id(fme, &id.id))
> +	if (fme_hdr_get_bitstream_id(fme, &id.csr))
>  		return -EINVAL;
> 
> -	fme->board_info.major = id.major;
> -	fme->board_info.minor = id.minor;
> -	fme->board_info.type = id.interface;
> -	fme->board_info.fvl_bypass = id.fvl_bypass;
> -	fme->board_info.mac_lightweight = id.mac_lightweight;
> -	fme->board_info.lightweight = id.lightweiht;
> -	fme->board_info.disaggregate = id.disagregate;
> -	fme->board_info.seu = id.seu;
> -	fme->board_info.ptp = id.ptp;
> +	if (id.v1.major == ARROW_CREEK) {
> +		fme->board_info.major = id.v2.bs_vermajor;
> +		fme->board_info.minor = id.v2.bs_verminor;
> +		fme->board_info.n6000_fim_type = id.v2.fim_type;
> +		fme->board_info.n6000_hssi_id = id.v2.hssi_id;
> +		type = board_type_to_string(fme->board_info.major,
> +				fme->board_info.n6000_fim_type);
> +	} else {
> +		fme->board_info.major = id.v1.major;
> +		fme->board_info.minor = id.v1.minor;
> +		fme->board_info.type = id.v1.interface;
> +		fme->board_info.fvl_bypass = id.v1.fvl_bypass;
> +		fme->board_info.mac_lightweight = id.v1.mac_lightweight;
> +		fme->board_info.lightweight = id.v1.lightweiht;
> +		fme->board_info.disaggregate = id.v1.disagregate;
> +		fme->board_info.seu = id.v1.seu;
> +		fme->board_info.ptp = id.v1.ptp;
> +		type = board_type_to_string(fme->board_info.major,
> +				fme->board_info.type);
> +	}
> 
>  	dev_info(fme, "found: PCI dev: %02x:%02x:%x board: %s
> type: %s\n",
>  			hw->pci_data->bus,
>  			hw->pci_data->devid,
>  			hw->pci_data->function,
>  			board_major_to_string(fme->board_info.major),
> -			board_type_to_string(fme->board_info.type));
> +			type);
> 
> -	dev_info(fme, "support feature:\n"
> +	ret = max10_get_fpga_load_info(fme->max10_dev, &val);
> +	if (ret)
> +		return ret;
> +	fme->board_info.boot_page = val;
> +
> +	if (fme->board_info.major == VISTA_CREEK) {
> +		dev_info(dev, "FPGA loaded from %s Image\n",
> +			val ? "User" : "Factory");
> +		dev_info(fme, "support feature:\n"
>  			"fvl_bypass:%s\n"
>  			"mac_lightweight:%s\n"
>  			"lightweight:%s\n"
> @@ -901,26 +941,29 @@ static int fme_get_board_interface(struct
> ifpga_fme_hw *fme)
>  			check_support(fme->board_info.seu),
>  			check_support(fme->board_info.ptp));
> 
> +		if (board_type_to_info(fme->board_info.type, &fme-
> >board_info))
> +			return -EINVAL;
> 
> -	if (board_type_to_info(fme->board_info.type, &fme->board_info))
> -		return -EINVAL;
> -
> -	dev_info(fme, "get board info: nums_retimers %d
> ports_per_retimer %d nums_fvl %d ports_per_fvl %d\n",
> +		dev_info(fme, "get board info: nums_retimers %d "
> +			"ports_per_retimer %d nums_fvl %d "
> +			"ports_per_fvl %d\n",
>  			fme->board_info.nums_of_retimer,
>  			fme->board_info.ports_per_retimer,
>  			fme->board_info.nums_of_fvl,
>  			fme->board_info.ports_per_fvl);
> +	} else {
> +		dev_info(dev, "FPGA loaded from %s Image\n",
> +			val ? (val == 1 ? "User1" : "User2") : "Factory");
> +	}
> 
> -	if (max10_sys_read(fme->max10_dev, FPGA_PAGE_INFO, &val))
> -		return -EINVAL;
> -	fme->board_info.boot_page = val & 0x7;
> -
> -	if (max10_sys_read(fme->max10_dev, MAX10_BUILD_VER, &val))
> -		return -EINVAL;
> +	ret = max10_get_bmc_version(fme->max10_dev, &val);
> +	if (ret)
> +		return ret;
>  	fme->board_info.max10_version = val;
> 
> -	if (max10_sys_read(fme->max10_dev, NIOS2_FW_VERSION, &val))
> -		return -EINVAL;
> +	ret = max10_get_bmcfw_version(fme->max10_dev, &val);
> +	if (ret)
> +		return ret;
>  	fme->board_info.nios_fw_version = val;
> 
>  	dev_info(fme, "max10 version 0x%x, nios fw version 0x%x\n", @@ -
> 1023,7 +1066,7 @@ static int fme_spi_init(struct ifpga_feature *feature)
>  	opae_free(max10);
>  release_dev:
>  	altera_spi_release(spi_master);
> -	return ret;
> +	return -ENODEV;
>  }
> 
>  static void fme_spi_uinit(struct ifpga_feature *feature) diff --git
> a/drivers/raw/ifpga/base/ifpga_fme_error.c
> b/drivers/raw/ifpga/base/ifpga_fme_error.c
> index 5905eac..c5bed28 100644
> --- a/drivers/raw/ifpga/base/ifpga_fme_error.c
> +++ b/drivers/raw/ifpga/base/ifpga_fme_error.c
> @@ -224,6 +224,8 @@ static int fme_global_error_init(struct ifpga_feature
> *feature)  {
>  	struct ifpga_fme_hw *fme = feature->parent;
> 
> +	dev_info(NULL, "FME error_module Init.\n");
> +
>  	fme_error_enable(fme);
> 
>  	if (feature->ctx_num)
> diff --git a/drivers/raw/ifpga/base/ifpga_port_error.c
> b/drivers/raw/ifpga/base/ifpga_port_error.c
> index 189f762..6c8a7d7 100644
> --- a/drivers/raw/ifpga/base/ifpga_port_error.c
> +++ b/drivers/raw/ifpga/base/ifpga_port_error.c
> @@ -88,7 +88,7 @@ static int port_error_init(struct ifpga_feature *feature)
> {
>  	struct ifpga_port_hw *port = feature->parent;
> 
> -	dev_info(NULL, "port error Init.\n");
> +	dev_info(NULL, "port error_module Init.\n");
> 
>  	spinlock_lock(&port->lock);
>  	port_err_mask(port, false);
> diff --git a/drivers/raw/ifpga/base/opae_intel_max10.c
> b/drivers/raw/ifpga/base/opae_intel_max10.c
> index 901a258..26f323c 100644
> --- a/drivers/raw/ifpga/base/opae_intel_max10.c
> +++ b/drivers/raw/ifpga/base/opae_intel_max10.c
> @@ -766,6 +766,51 @@ static int max10_staging_area_init(struct
> intel_max10_device *dev)
>  	return 0;
>  }
> 
> +int max10_get_fpga_load_info(struct intel_max10_device *dev, unsigned
> +int *val) {
> +	int ret;
> +	unsigned int value;
> +
> +	/* read FPGA loading information */
> +	ret = max10_sys_read(dev, dev->csr->fpga_page_info, &value);
> +	if (ret) {
> +		dev_err(dev, "fail to get FPGA loading info\n");
> +		return ret;
> +	}
> +
> +	if (dev->type == M10_N3000)
> +		*val = value & 0x7;
> +	else if (dev->type == M10_N6000) {
> +		if (!GET_FIELD(PMCI_FPGA_CONFIGURED, value))
> +			return -EINVAL;
> +		*val = GET_FIELD(PMCI_FPGA_BOOT_PAGE, value);
> +	}
> +
> +	return 0;
> +}
> +
> +int max10_get_bmc_version(struct intel_max10_device *dev, unsigned int
> +*val) {
> +	int ret;
> +
> +	ret = max10_sys_read(dev, dev->csr->build_version, val);
> +	if (ret)
> +		return ret;
> +
> +	return 0;
> +}
> +
> +int max10_get_bmcfw_version(struct intel_max10_device *dev, unsigned
> +int *val) {
> +	int ret;
> +
> +	ret = max10_sys_read(dev, dev->csr->fw_version, val);
> +	if (ret)
> +		return ret;
> +
> +	return 0;
> +}
> +
>  static const struct m10bmc_csr m10bmc_spi_csr = {
>  	.base = MAX10_SEC_BASE_ADDR,
>  	.build_version = MAX10_BUILD_VER,
> diff --git a/drivers/raw/ifpga/base/opae_intel_max10.h
> b/drivers/raw/ifpga/base/opae_intel_max10.h
> index 0d31196..6a1b122 100644
> --- a/drivers/raw/ifpga/base/opae_intel_max10.h
> +++ b/drivers/raw/ifpga/base/opae_intel_max10.h
> @@ -336,6 +336,9 @@ int max10_reg_write(struct intel_max10_device *dev,
>  	unsigned int offset, unsigned int val);  int
> max10_sys_update_bits(struct intel_max10_device *dev,
>  	unsigned int offset, unsigned int msk, unsigned int val);
> +int max10_get_bmcfw_version(struct intel_max10_device *dev, unsigned
> +int *val); int max10_get_bmc_version(struct intel_max10_device *dev,
> +unsigned int *val); int max10_get_fpga_load_info(struct
> +intel_max10_device *dev, unsigned int *val);
>  int intel_max10_device_init(struct intel_max10_device *dev);  int
> intel_max10_device_remove(struct intel_max10_device *dev);
> 
> --
> 1.8.3.1

Reviewed-by: Rosen Xu <rosen.xu@intel.com>
  

Patch

diff --git a/drivers/raw/ifpga/base/ifpga_defines.h b/drivers/raw/ifpga/base/ifpga_defines.h
index f84ed1d..7c8fa89 100644
--- a/drivers/raw/ifpga/base/ifpga_defines.h
+++ b/drivers/raw/ifpga/base/ifpga_defines.h
@@ -268,6 +268,24 @@  struct feature_fme_bitstream_id {
 	union {
 		u64 csr;
 		struct {
+			u8 build_patch:8;
+			u8 build_minor:8;
+			u8 build_major:8;
+			u8 fvl_bypass:1;
+			u8 mac_lightweight:1;
+			u8 disagregate:1;
+			u8 lightweiht:1;
+			u8 seu:1;
+			u8 ptp:1;
+			u8 reserve:2;
+			u8 interface:4;
+			u32 afu_revision:12;
+			u8 patch:4;
+			u8 minor:4;
+			u8 major:4;
+			u8 reserved:4;
+		} v1;
+		struct {
 			u32 gitrepo_hash:32;	/* GIT repository hash */
 			/*
 			 * HSSI configuration identifier:
@@ -276,7 +294,8 @@  struct feature_fme_bitstream_id {
 			 * 2 - Ethernet
 			 */
 			u8  hssi_id:4;
-			u16 rsvd1:12;		/* Reserved */
+			u8  rsvd1:4;
+			u8  fim_type:8;
 			/* Bitstream version patch number */
 			u8  bs_verpatch:4;
 			/* Bitstream version minor number */
@@ -285,7 +304,7 @@  struct feature_fme_bitstream_id {
 			u8  bs_vermajor:4;
 			/* Bitstream version debug number */
 			u8  bs_verdebug:4;
-		};
+		} v2;
 	};
 };
 
@@ -1672,31 +1691,6 @@  struct bts_header {
 
 #define check_support(n) (n == 1 ? "support" : "no")
 
-/* bitstream id definition */
-struct fme_bitstream_id {
-	union {
-		u64 id;
-		struct {
-			u8 build_patch:8;
-			u8 build_minor:8;
-			u8 build_major:8;
-			u8 fvl_bypass:1;
-			u8 mac_lightweight:1;
-			u8 disagregate:1;
-			u8 lightweiht:1;
-			u8 seu:1;
-			u8 ptp:1;
-			u8 reserve:2;
-			u8 interface:4;
-			u32 afu_revision:12;
-			u8 patch:4;
-			u8 minor:4;
-			u8 major:4;
-			u8 reserved:4;
-		};
-	};
-};
-
 enum board_interface {
 	VC_8_10G = 0,
 	VC_4_25G = 1,
@@ -1705,10 +1699,30 @@  enum board_interface {
 	VC_2_2_25G = 4,
 };
 
+enum fim_type {
+	BASE_ADP = 0,
+	BASE_FDK,
+	BASE_X16_ADP,
+	BASE_X16_FDK,
+	FIMA_10G_ADP,
+	FIMA_25G_ADP,
+	FIMA_100G_ADP,
+	FIMB_ADP,
+	FIMC_ADP
+};
+
+enum hssi_id {
+	NO_HSSI = 0,
+	PCIE_RP,
+	ETHER_NET
+};
+
 enum pac_major {
 	VISTA_CREEK = 0,
 	RUSH_CREEK = 1,
 	DARBY_CREEK = 2,
+	LIGHTNING_CREEK = 3,
+	ARROW_CREEK = 5,
 };
 
 enum pac_minor {
@@ -1720,23 +1734,30 @@  enum pac_minor {
 struct opae_board_info {
 	enum pac_major major;
 	enum pac_minor minor;
-	enum board_interface type;
-
-	/* PAC features */
-	u8 fvl_bypass;
-	u8 mac_lightweight;
-	u8 disaggregate;
-	u8 lightweight;
-	u8 seu;
-	u8 ptp;
 
 	u32 boot_page;
 	u32 max10_version;
 	u32 nios_fw_version;
-	u32 nums_of_retimer;
-	u32 ports_per_retimer;
-	u32 nums_of_fvl;
-	u32 ports_per_fvl;
+
+	union {
+		struct {  /* N3000 specific */
+			enum board_interface type;
+			u8 fvl_bypass;
+			u8 mac_lightweight;
+			u8 disaggregate;
+			u8 lightweight;
+			u8 seu;
+			u8 ptp;
+			u32 nums_of_retimer;
+			u32 ports_per_retimer;
+			u32 nums_of_fvl;
+			u32 ports_per_fvl;
+		};
+		struct {
+			enum fim_type n6000_fim_type;
+			enum hssi_id n6000_hssi_id;
+		};
+	};
 };
 
 #pragma pack(pop)
diff --git a/drivers/raw/ifpga/base/ifpga_fme.c b/drivers/raw/ifpga/base/ifpga_fme.c
index 4d089d2..608a352 100644
--- a/drivers/raw/ifpga/base/ifpga_fme.c
+++ b/drivers/raw/ifpga/base/ifpga_fme.c
@@ -790,19 +790,32 @@  struct ifpga_feature_ops fme_emif_ops = {
 	.uinit = fme_emif_uinit,
 };
 
-static const char *board_type_to_string(u32 type)
-{
-	switch (type) {
-	case VC_8_10G:
-		return "VC_8x10G";
-	case VC_4_25G:
-		return "VC_4x25G";
-	case VC_2_1_25:
-		return "VC_2x1x25G";
-	case VC_4_25G_2_25G:
-		return "VC_4x25G+2x25G";
-	case VC_2_2_25G:
-		return "VC_2x2x25G";
+static const char *board_type_to_string(u32 board, u32 type)
+{
+	if (board == VISTA_CREEK) {
+		switch (type) {
+		case VC_8_10G:
+			return "8x10G";
+		case VC_4_25G:
+			return "4x25G";
+		case VC_2_1_25:
+			return "2x1x25G";
+		case VC_4_25G_2_25G:
+			return "4x25G+2x25G";
+		case VC_2_2_25G:
+			return "2x2x25G";
+		break;
+		}
+	} else {
+		switch (type) {
+		case FIMA_10G_ADP:
+			return "2x4x10G";
+		case FIMA_25G_ADP:
+			return "2x2x25G";
+		case FIMA_100G_ADP:
+			return "2x100G";
+		break;
+		}
 	}
 
 	return "unknown";
@@ -817,6 +830,12 @@  static const char *board_major_to_string(u32 major)
 		return "RUSH_CREEK";
 	case DARBY_CREEK:
 		return "DARBY_CREEK";
+	case LIGHTNING_CREEK:
+		return "LIGHTNING_CREEK";
+	case ARROW_CREEK:
+		return "ARROW_CREEK";
+	default:
+		break;
 	}
 
 	return "unknown";
@@ -859,35 +878,56 @@  static int board_type_to_info(u32 type,
 
 static int fme_get_board_interface(struct ifpga_fme_hw *fme)
 {
-	struct fme_bitstream_id id;
+	struct feature_fme_bitstream_id id;
 	struct ifpga_hw *hw;
 	u32 val;
+	const char *type = NULL;
+	int ret;
 
 	hw = fme->parent;
 	if (!hw)
 		return -ENODEV;
 
-	if (fme_hdr_get_bitstream_id(fme, &id.id))
+	if (fme_hdr_get_bitstream_id(fme, &id.csr))
 		return -EINVAL;
 
-	fme->board_info.major = id.major;
-	fme->board_info.minor = id.minor;
-	fme->board_info.type = id.interface;
-	fme->board_info.fvl_bypass = id.fvl_bypass;
-	fme->board_info.mac_lightweight = id.mac_lightweight;
-	fme->board_info.lightweight = id.lightweiht;
-	fme->board_info.disaggregate = id.disagregate;
-	fme->board_info.seu = id.seu;
-	fme->board_info.ptp = id.ptp;
+	if (id.v1.major == ARROW_CREEK) {
+		fme->board_info.major = id.v2.bs_vermajor;
+		fme->board_info.minor = id.v2.bs_verminor;
+		fme->board_info.n6000_fim_type = id.v2.fim_type;
+		fme->board_info.n6000_hssi_id = id.v2.hssi_id;
+		type = board_type_to_string(fme->board_info.major,
+				fme->board_info.n6000_fim_type);
+	} else {
+		fme->board_info.major = id.v1.major;
+		fme->board_info.minor = id.v1.minor;
+		fme->board_info.type = id.v1.interface;
+		fme->board_info.fvl_bypass = id.v1.fvl_bypass;
+		fme->board_info.mac_lightweight = id.v1.mac_lightweight;
+		fme->board_info.lightweight = id.v1.lightweiht;
+		fme->board_info.disaggregate = id.v1.disagregate;
+		fme->board_info.seu = id.v1.seu;
+		fme->board_info.ptp = id.v1.ptp;
+		type = board_type_to_string(fme->board_info.major,
+				fme->board_info.type);
+	}
 
 	dev_info(fme, "found: PCI dev: %02x:%02x:%x board: %s type: %s\n",
 			hw->pci_data->bus,
 			hw->pci_data->devid,
 			hw->pci_data->function,
 			board_major_to_string(fme->board_info.major),
-			board_type_to_string(fme->board_info.type));
+			type);
 
-	dev_info(fme, "support feature:\n"
+	ret = max10_get_fpga_load_info(fme->max10_dev, &val);
+	if (ret)
+		return ret;
+	fme->board_info.boot_page = val;
+
+	if (fme->board_info.major == VISTA_CREEK) {
+		dev_info(dev, "FPGA loaded from %s Image\n",
+			val ? "User" : "Factory");
+		dev_info(fme, "support feature:\n"
 			"fvl_bypass:%s\n"
 			"mac_lightweight:%s\n"
 			"lightweight:%s\n"
@@ -901,26 +941,29 @@  static int fme_get_board_interface(struct ifpga_fme_hw *fme)
 			check_support(fme->board_info.seu),
 			check_support(fme->board_info.ptp));
 
+		if (board_type_to_info(fme->board_info.type, &fme->board_info))
+			return -EINVAL;
 
-	if (board_type_to_info(fme->board_info.type, &fme->board_info))
-		return -EINVAL;
-
-	dev_info(fme, "get board info: nums_retimers %d ports_per_retimer %d nums_fvl %d ports_per_fvl %d\n",
+		dev_info(fme, "get board info: nums_retimers %d "
+			"ports_per_retimer %d nums_fvl %d "
+			"ports_per_fvl %d\n",
 			fme->board_info.nums_of_retimer,
 			fme->board_info.ports_per_retimer,
 			fme->board_info.nums_of_fvl,
 			fme->board_info.ports_per_fvl);
+	} else {
+		dev_info(dev, "FPGA loaded from %s Image\n",
+			val ? (val == 1 ? "User1" : "User2") : "Factory");
+	}
 
-	if (max10_sys_read(fme->max10_dev, FPGA_PAGE_INFO, &val))
-		return -EINVAL;
-	fme->board_info.boot_page = val & 0x7;
-
-	if (max10_sys_read(fme->max10_dev, MAX10_BUILD_VER, &val))
-		return -EINVAL;
+	ret = max10_get_bmc_version(fme->max10_dev, &val);
+	if (ret)
+		return ret;
 	fme->board_info.max10_version = val;
 
-	if (max10_sys_read(fme->max10_dev, NIOS2_FW_VERSION, &val))
-		return -EINVAL;
+	ret = max10_get_bmcfw_version(fme->max10_dev, &val);
+	if (ret)
+		return ret;
 	fme->board_info.nios_fw_version = val;
 
 	dev_info(fme, "max10 version 0x%x, nios fw version 0x%x\n",
@@ -1023,7 +1066,7 @@  static int fme_spi_init(struct ifpga_feature *feature)
 	opae_free(max10);
 release_dev:
 	altera_spi_release(spi_master);
-	return ret;
+	return -ENODEV;
 }
 
 static void fme_spi_uinit(struct ifpga_feature *feature)
diff --git a/drivers/raw/ifpga/base/ifpga_fme_error.c b/drivers/raw/ifpga/base/ifpga_fme_error.c
index 5905eac..c5bed28 100644
--- a/drivers/raw/ifpga/base/ifpga_fme_error.c
+++ b/drivers/raw/ifpga/base/ifpga_fme_error.c
@@ -224,6 +224,8 @@  static int fme_global_error_init(struct ifpga_feature *feature)
 {
 	struct ifpga_fme_hw *fme = feature->parent;
 
+	dev_info(NULL, "FME error_module Init.\n");
+
 	fme_error_enable(fme);
 
 	if (feature->ctx_num)
diff --git a/drivers/raw/ifpga/base/ifpga_port_error.c b/drivers/raw/ifpga/base/ifpga_port_error.c
index 189f762..6c8a7d7 100644
--- a/drivers/raw/ifpga/base/ifpga_port_error.c
+++ b/drivers/raw/ifpga/base/ifpga_port_error.c
@@ -88,7 +88,7 @@  static int port_error_init(struct ifpga_feature *feature)
 {
 	struct ifpga_port_hw *port = feature->parent;
 
-	dev_info(NULL, "port error Init.\n");
+	dev_info(NULL, "port error_module Init.\n");
 
 	spinlock_lock(&port->lock);
 	port_err_mask(port, false);
diff --git a/drivers/raw/ifpga/base/opae_intel_max10.c b/drivers/raw/ifpga/base/opae_intel_max10.c
index 901a258..26f323c 100644
--- a/drivers/raw/ifpga/base/opae_intel_max10.c
+++ b/drivers/raw/ifpga/base/opae_intel_max10.c
@@ -766,6 +766,51 @@  static int max10_staging_area_init(struct intel_max10_device *dev)
 	return 0;
 }
 
+int max10_get_fpga_load_info(struct intel_max10_device *dev, unsigned int *val)
+{
+	int ret;
+	unsigned int value;
+
+	/* read FPGA loading information */
+	ret = max10_sys_read(dev, dev->csr->fpga_page_info, &value);
+	if (ret) {
+		dev_err(dev, "fail to get FPGA loading info\n");
+		return ret;
+	}
+
+	if (dev->type == M10_N3000)
+		*val = value & 0x7;
+	else if (dev->type == M10_N6000) {
+		if (!GET_FIELD(PMCI_FPGA_CONFIGURED, value))
+			return -EINVAL;
+		*val = GET_FIELD(PMCI_FPGA_BOOT_PAGE, value);
+	}
+
+	return 0;
+}
+
+int max10_get_bmc_version(struct intel_max10_device *dev, unsigned int *val)
+{
+	int ret;
+
+	ret = max10_sys_read(dev, dev->csr->build_version, val);
+	if (ret)
+		return ret;
+
+	return 0;
+}
+
+int max10_get_bmcfw_version(struct intel_max10_device *dev, unsigned int *val)
+{
+	int ret;
+
+	ret = max10_sys_read(dev, dev->csr->fw_version, val);
+	if (ret)
+		return ret;
+
+	return 0;
+}
+
 static const struct m10bmc_csr m10bmc_spi_csr = {
 	.base = MAX10_SEC_BASE_ADDR,
 	.build_version = MAX10_BUILD_VER,
diff --git a/drivers/raw/ifpga/base/opae_intel_max10.h b/drivers/raw/ifpga/base/opae_intel_max10.h
index 0d31196..6a1b122 100644
--- a/drivers/raw/ifpga/base/opae_intel_max10.h
+++ b/drivers/raw/ifpga/base/opae_intel_max10.h
@@ -336,6 +336,9 @@  int max10_reg_write(struct intel_max10_device *dev,
 	unsigned int offset, unsigned int val);
 int max10_sys_update_bits(struct intel_max10_device *dev,
 	unsigned int offset, unsigned int msk, unsigned int val);
+int max10_get_bmcfw_version(struct intel_max10_device *dev, unsigned int *val);
+int max10_get_bmc_version(struct intel_max10_device *dev, unsigned int *val);
+int max10_get_fpga_load_info(struct intel_max10_device *dev, unsigned int *val);
 int intel_max10_device_init(struct intel_max10_device *dev);
 int intel_max10_device_remove(struct intel_max10_device *dev);