Blame tools/libboard/board_vc/board_vc.c

Packit 534379
// Copyright(c) 2019-2020, Intel Corporation
Packit 534379
//
Packit 534379
// Redistribution  and  use  in source  and  binary  forms,  with  or  without
Packit 534379
// modification, are permitted provided that the following conditions are met:
Packit 534379
//
Packit 534379
// * Redistributions of  source code  must retain the  above copyright notice,
Packit 534379
//   this list of conditions and the following disclaimer.
Packit 534379
// * Redistributions in binary form must reproduce the above copyright notice,
Packit 534379
//   this list of conditions and the following disclaimer in the documentation
Packit 534379
//   and/or other materials provided with the distribution.
Packit 534379
// * Neither the name  of Intel Corporation  nor the names of its contributors
Packit 534379
//   may be used to  endorse or promote  products derived  from this  software
Packit 534379
//   without specific prior written permission.
Packit 534379
//
Packit 534379
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
Packit 534379
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING,  BUT NOT LIMITED TO,  THE
Packit 534379
// IMPLIED WARRANTIES OF  MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
Packit 534379
// ARE DISCLAIMED.  IN NO EVENT  SHALL THE COPYRIGHT OWNER  OR CONTRIBUTORS BE
Packit 534379
// LIABLE  FOR  ANY  DIRECT,  INDIRECT,  INCIDENTAL,  SPECIAL,  EXEMPLARY,  OR
Packit 534379
// CONSEQUENTIAL  DAMAGES  (INCLUDING,  BUT  NOT LIMITED  TO,  PROCUREMENT  OF
Packit 534379
// SUBSTITUTE GOODS OR SERVICES;  LOSS OF USE,  DATA, OR PROFITS;  OR BUSINESS
Packit 534379
// INTERRUPTION)  HOWEVER CAUSED  AND ON ANY THEORY  OF LIABILITY,  WHETHER IN
Packit 534379
// CONTRACT,  STRICT LIABILITY,  OR TORT  (INCLUDING NEGLIGENCE  OR OTHERWISE)
Packit 534379
// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,  EVEN IF ADVISED OF THE
Packit 534379
// POSSIBILITY OF SUCH DAMAGE.
Packit 534379
Packit 534379
#include <glob.h>
Packit 534379
#include <stdio.h>
Packit 534379
#include <errno.h>
Packit 534379
#include <string.h>
Packit 534379
#include <unistd.h>
Packit 534379
#include <fcntl.h>
Packit 534379
#include <sys/types.h>
Packit 534379
#include <sys/stat.h>
Packit 534379
#include <net/ethernet.h>
Packit 534379
#include <opae/properties.h>
Packit 534379
#include <opae/utils.h>
Packit 534379
#include <opae/fpga.h>
Packit 534379
#include <sys/ioctl.h>
Packit 534379
Packit 534379
#include "board_vc.h"
Packit 534379
Packit 534379
// sysfs paths
Packit 534379
#define SYSFS_BMCFW_VER                     "spi-altera.*.auto/spi_master/spi*/spi*.*/bmcfw_flash_ctrl/bmcfw_version"
Packit 534379
#define SYSFS_MAX10_VER                     "spi-altera.*.auto/spi_master/spi*/spi*.*/max10_version"
Packit 534379
#define SYSFS_PCB_INFO                      "spi-altera.*.auto/spi_master/spi*/spi*.*/pcb_info"
Packit 534379
#define SYSFS_PKVL_POLL_MODE                "spi-altera.*.auto/spi_master/spi*/spi*.*/pkvl/polling_mode"
Packit 534379
#define SYSFS_PKVL_STATUS                   "spi-altera.*.auto/spi_master/spi*/spi*.*/pkvl/status"
Packit 534379
#define SYSFS_BS_ID                         "bitstream_id"
Packit 534379
#define SYSFS_PHY_GROUP_INFO                "pac_n3000_net*/misc/eth_group*.*"
Packit 534379
#define SYSFS_PHY_GROUP_INFO_DEV            "pac_n3000_net*/misc/eth_group*/dev"
Packit 534379
#define SYSFS_EEPROM                        "*i2c*/i2c*/*/eeprom"
Packit 534379
#define SYSFS_NVMEM                         "*i2c*/i2c*/*/nvmem"
Packit 534379
#define SYSFS_PKVL_A_VER                    "spi-altera.*.auto/spi_master/spi*/spi*.*/pkvl/pkvl_a_version"
Packit 534379
#define SYSFS_PKVL_B_VER                    "spi-altera.*.auto/spi_master/spi*/spi*.*/pkvl/pkvl_b_version"
Packit 534379
Packit 534379
// driver ioctl id
Packit 534379
#define FPGA_PHY_GROUP_GET_INFO               0xB702
Packit 534379
Packit 534379
#define FPGA_BSID_SIZE                        32
Packit 534379
Packit 534379
// fpga phy group mode
Packit 534379
#define FPGA_PHYGROUP_MODE_4_25G              1
Packit 534379
#define FPGA_PHYGROUP_MODE_6_25G              3
Packit 534379
#define FPGA_PHYGROUP_MODE_2_2_25G            4
Packit 534379
Packit 534379
// Read BMC firmware version
Packit 534379
fpga_result read_bmcfw_version(fpga_token token, char *bmcfw_ver, size_t len)
Packit 534379
{
Packit 534379
	fpga_result res                = FPGA_OK;
Packit 534379
	fpga_result resval             = FPGA_OK;
Packit 534379
	uint32_t size                  = 0;
Packit 534379
	char buf[FPGA_VAR_BUF_LEN]     = { 0 };
Packit 534379
	fpga_object bmcfw_object;
Packit 534379
Packit 534379
	if (bmcfw_ver == NULL) {
Packit 534379
		FPGA_ERR("Invalid Input parameters");
Packit 534379
		return FPGA_INVALID_PARAM;
Packit 534379
	}
Packit 534379
Packit 534379
	res = fpgaTokenGetObject(token, SYSFS_BMCFW_VER, &bmcfw_object, FPGA_OBJECT_GLOB);
Packit 534379
	if (res != FPGA_OK) {
Packit 534379
		OPAE_MSG("Failed to get token object");
Packit 534379
		return res;
Packit 534379
	}
Packit 534379
Packit 534379
	res = fpgaObjectGetSize(bmcfw_object, &size, 0);
Packit 534379
	if (res != FPGA_OK) {
Packit 534379
		OPAE_ERR("Failed to read object size ");
Packit 534379
		resval = res;
Packit 534379
		goto out_destroy;
Packit 534379
	}
Packit 534379
Packit 534379
	// Return error if object size bigger then buffer size
Packit 534379
	if (size > FPGA_VAR_BUF_LEN) {
Packit 534379
		FPGA_ERR("object size bigger then buffer size");
Packit 534379
		resval = FPGA_EXCEPTION;
Packit 534379
		goto out_destroy;
Packit 534379
	}
Packit 534379
Packit 534379
	res = fpgaObjectRead(bmcfw_object, (uint8_t *)buf, 0, size, 0);
Packit 534379
	if (res != FPGA_OK) {
Packit 534379
		OPAE_ERR("Failed to read object ");
Packit 534379
		resval = res;
Packit 534379
		goto out_destroy;
Packit 534379
	}
Packit 534379
Packit 534379
	res = parse_fw_ver(buf, bmcfw_ver, len);
Packit 534379
	if (res != FPGA_OK) {
Packit 534379
		OPAE_ERR("Failed to parse version ");
Packit 534379
		resval = res;
Packit 534379
		goto out_destroy;
Packit 534379
	}
Packit 534379
Packit 534379
Packit 534379
out_destroy:
Packit 534379
	res = fpgaDestroyObject(&bmcfw_object);
Packit 534379
	if (res != FPGA_OK) {
Packit 534379
		OPAE_ERR("Failed to destroy object");
Packit 534379
	}
Packit 534379
Packit 534379
	return resval;
Packit 534379
}
Packit 534379
Packit 534379
fpga_result parse_fw_ver(char *buf, char *fw_ver, size_t len)
Packit 534379
{
Packit 534379
	uint8_t rev                = 0;
Packit 534379
	uint32_t var               = 0;
Packit 534379
	fpga_result res            = FPGA_OK;
Packit 534379
	int retval                 = 0;
Packit 534379
Packit 534379
	if (buf == NULL ||
Packit 534379
		fw_ver == NULL) {
Packit 534379
		FPGA_ERR("Invalid Input parameters");
Packit 534379
		return FPGA_INVALID_PARAM;
Packit 534379
	}
Packit 534379
Packit 534379
Packit 534379
	/* BMC FW version format reading
Packit 534379
	NIOS II Firmware Build 0x0 32 RW[23:0] 24 hFFFFFF Build version of NIOS II Firmware
Packit 534379
	NIOS FW is up e.g. 1.0.1 for first release
Packit 534379
	[31:24] 8hFF Firmware Support Revision - ASCII code
Packit 534379
	0xFF is the default value without NIOS FW, will be changed after NIOS FW is up
Packit 534379
	0x41(A)-For RevA
Packit 534379
	0x42(B)-For RevB
Packit 534379
	0x43(C)-For RevC
Packit 534379
	0x44(D)-For RevD
Packit 534379
	*/
Packit 534379
Packit 534379
	errno = 0;
Packit 534379
	var = strtoul(buf, NULL, 16);
Packit 534379
	if (var == 0  &&
Packit 534379
		errno != 0) {
Packit 534379
		OPAE_ERR("Failed to covert buffer to integer: %s", strerror(errno));
Packit 534379
		return FPGA_EXCEPTION;
Packit 534379
	}
Packit 534379
Packit 534379
	rev = (var >> 24) & 0xff;
Packit 534379
	if ((rev >= 'A') && (rev <= 'Z')) {// range from 'A' to 'Z'
Packit 534379
		retval = snprintf(fw_ver, len, "%c.%u.%u.%u", (char)rev, (var >> 16) & 0xff, (var >> 8) & 0xff, var & 0xff);
Packit 534379
		if (retval < 0) {
Packit 534379
			FPGA_ERR("error in formatting version");
Packit 534379
			return FPGA_EXCEPTION;
Packit 534379
		}
Packit 534379
	} else {
Packit 534379
		OPAE_ERR("Invalid firmware version");
Packit 534379
		res = FPGA_EXCEPTION;
Packit 534379
	}
Packit 534379
Packit 534379
	return res;
Packit 534379
}
Packit 534379
Packit 534379
// Read MAX10 firmware version
Packit 534379
fpga_result read_max10fw_version(fpga_token token, char *max10fw_ver, size_t len)
Packit 534379
{
Packit 534379
	fpga_result res                      = FPGA_OK;
Packit 534379
	fpga_result resval                   = FPGA_OK;
Packit 534379
	uint32_t size                        = 0;
Packit 534379
	char buf[FPGA_VAR_BUF_LEN]           = { 0 };
Packit 534379
	fpga_object max10fw_object;
Packit 534379
Packit 534379
	if (max10fw_ver == NULL) {
Packit 534379
		FPGA_ERR("Invalid input parameters");
Packit 534379
		return FPGA_INVALID_PARAM;
Packit 534379
	}
Packit 534379
Packit 534379
	res = fpgaTokenGetObject(token, SYSFS_MAX10_VER, &max10fw_object, FPGA_OBJECT_GLOB);
Packit 534379
	if (res != FPGA_OK) {
Packit 534379
		OPAE_MSG("Failed to get token object");
Packit 534379
		return res;
Packit 534379
	}
Packit 534379
Packit 534379
	res = fpgaObjectGetSize(max10fw_object, &size, 0);
Packit 534379
	if (res != FPGA_OK) {
Packit 534379
		OPAE_ERR("Failed to get object size ");
Packit 534379
		resval = res;
Packit 534379
		goto out_destroy;
Packit 534379
	}
Packit 534379
Packit 534379
	// Return error if object size bigger then buffer size
Packit 534379
	if (size > FPGA_VAR_BUF_LEN) {
Packit 534379
		FPGA_ERR("object size bigger then buffer size");
Packit 534379
		resval = FPGA_EXCEPTION;
Packit 534379
		goto out_destroy;
Packit 534379
	}
Packit 534379
Packit 534379
	res = fpgaObjectRead(max10fw_object, (uint8_t *)buf, 0, size, 0);
Packit 534379
	if (res != FPGA_OK) {
Packit 534379
		OPAE_ERR("Failed to read object ");
Packit 534379
		resval = res;
Packit 534379
		goto out_destroy;
Packit 534379
	}
Packit 534379
Packit 534379
	res = parse_fw_ver(buf, max10fw_ver, len);
Packit 534379
	if (res != FPGA_OK) {
Packit 534379
		OPAE_ERR("Failed to parse version ");
Packit 534379
		resval = res;
Packit 534379
		goto out_destroy;
Packit 534379
	}
Packit 534379
Packit 534379
out_destroy:
Packit 534379
	res = fpgaDestroyObject(&max10fw_object);
Packit 534379
	if (res != FPGA_OK) {
Packit 534379
		OPAE_ERR("Failed to destroy object");
Packit 534379
	}
Packit 534379
Packit 534379
	return resval;
Packit 534379
}
Packit 534379
Packit 534379
// Read PCB information
Packit 534379
fpga_result read_pcb_info(fpga_token token, char *pcb_info, size_t len)
Packit 534379
{
Packit 534379
	fpga_result res                = FPGA_OK;
Packit 534379
	fpga_result resval             = FPGA_OK;
Packit 534379
	uint32_t size                  = 0;
Packit 534379
	fpga_object pcb_object;
Packit 534379
Packit 534379
	if (pcb_info == NULL) {
Packit 534379
		FPGA_ERR("Invalid input parameters");
Packit 534379
		return FPGA_INVALID_PARAM;
Packit 534379
	}
Packit 534379
Packit 534379
	res = fpgaTokenGetObject(token, SYSFS_PCB_INFO, &pcb_object, FPGA_OBJECT_GLOB);
Packit 534379
	if (res != FPGA_OK) {
Packit 534379
		OPAE_MSG("Failed to get token Object");
Packit 534379
		return res;
Packit 534379
	}
Packit 534379
Packit 534379
	res = fpgaObjectGetSize(pcb_object, &size, 0);
Packit 534379
	if (res != FPGA_OK) {
Packit 534379
		OPAE_ERR("Failed to read object size");
Packit 534379
		resval = res;
Packit 534379
		goto out_destroy;
Packit 534379
	}
Packit 534379
Packit 534379
	// Return error if object size bigger then pcb info length
Packit 534379
	if (size > len) {
Packit 534379
		FPGA_ERR("object size bigger then pcb info size");
Packit 534379
		resval = FPGA_EXCEPTION;
Packit 534379
		goto out_destroy;
Packit 534379
	}
Packit 534379
Packit 534379
	res = fpgaObjectRead(pcb_object, (uint8_t *)pcb_info, 0, size, 0);
Packit 534379
	if (res != FPGA_OK) {
Packit 534379
		OPAE_ERR("Failed to read object ");
Packit 534379
		resval = res;
Packit 534379
	}
Packit 534379
Packit 534379
out_destroy:
Packit 534379
	res = fpgaDestroyObject(&pcb_object);
Packit 534379
	if (res != FPGA_OK) {
Packit 534379
		OPAE_ERR("Failed to destroy object");
Packit 534379
	}
Packit 534379
Packit 534379
	return resval;
Packit 534379
}
Packit 534379
Packit 534379
Packit 534379
// Read PKVL information
Packit 534379
fpga_result read_pkvl_info(fpga_token token,
Packit 534379
			   fpga_pkvl_info *pkvl_info,
Packit 534379
			   int *fpga_mode)
Packit 534379
{
Packit 534379
	fpga_result res                    = FPGA_OK;
Packit 534379
	fpga_result resval                 = FPGA_OK;
Packit 534379
	uint64_t bs_id                     = 0;
Packit 534379
	uint64_t poll_mode                 = 0;
Packit 534379
	uint64_t status                    = 0;
Packit 534379
	fpga_object poll_mode_object;
Packit 534379
	fpga_object status_object;
Packit 534379
	fpga_object bsid_object;
Packit 534379
Packit 534379
	if (pkvl_info == NULL ||
Packit 534379
		fpga_mode == NULL) {
Packit 534379
		FPGA_ERR("Invalid Input parameters");
Packit 534379
		return FPGA_INVALID_PARAM;
Packit 534379
	}
Packit 534379
Packit 534379
	res = fpgaTokenGetObject(token, SYSFS_BS_ID, &bsid_object, FPGA_OBJECT_GLOB);
Packit 534379
	if (res != FPGA_OK) {
Packit 534379
		OPAE_ERR("Failed to get token object");
Packit 534379
		return res;
Packit 534379
	}
Packit 534379
Packit 534379
	res = fpgaTokenGetObject(token, SYSFS_PKVL_POLL_MODE, &poll_mode_object, FPGA_OBJECT_GLOB);
Packit 534379
	if (res != FPGA_OK) {
Packit 534379
		OPAE_ERR("Failed to get token object");
Packit 534379
		resval = res;
Packit 534379
		goto out_destroy_bsid;
Packit 534379
	}
Packit 534379
Packit 534379
	res = fpgaTokenGetObject(token, SYSFS_PKVL_STATUS, &status_object, FPGA_OBJECT_GLOB);
Packit 534379
	if (res != FPGA_OK) {
Packit 534379
		OPAE_ERR("Failed to get token object");
Packit 534379
		resval = res;
Packit 534379
		goto out_destroy_poll;
Packit 534379
	}
Packit 534379
Packit 534379
	res = fpgaObjectRead64(bsid_object, &bs_id, 0);
Packit 534379
	if (res != FPGA_OK) {
Packit 534379
		OPAE_ERR("Failed to read object ");
Packit 534379
		resval = res;
Packit 534379
		goto out_destroy_status;
Packit 534379
	}
Packit 534379
Packit 534379
	*fpga_mode = (bs_id >> FPGA_BSID_SIZE) & 0xf;
Packit 534379
Packit 534379
	res = fpgaObjectRead64(poll_mode_object, &poll_mode, 0);
Packit 534379
	if (res != FPGA_OK) {
Packit 534379
		OPAE_ERR("Failed to read object ");
Packit 534379
		resval = res;
Packit 534379
		goto out_destroy_status;
Packit 534379
	}
Packit 534379
Packit 534379
	res = fpgaObjectRead64(status_object, &status, 0);
Packit 534379
	if (res != FPGA_OK) {
Packit 534379
		OPAE_ERR("Failed to read object ");
Packit 534379
		resval = res;
Packit 534379
		goto out_destroy_status;
Packit 534379
	}
Packit 534379
Packit 534379
	pkvl_info->polling_mode = (uint32_t)poll_mode;
Packit 534379
	pkvl_info->status = (uint32_t)status;
Packit 534379
Packit 534379
out_destroy_status:
Packit 534379
	res = fpgaDestroyObject(&status_object);
Packit 534379
	if (res != FPGA_OK) {
Packit 534379
		OPAE_ERR("Failed to destroy object");
Packit 534379
	}
Packit 534379
Packit 534379
out_destroy_poll:
Packit 534379
	res = fpgaDestroyObject(&poll_mode_object);
Packit 534379
	if (res != FPGA_OK) {
Packit 534379
		OPAE_ERR("Failed to destroy object");
Packit 534379
	}
Packit 534379
Packit 534379
out_destroy_bsid:
Packit 534379
	res = fpgaDestroyObject(&bsid_object);
Packit 534379
	if (res != FPGA_OK) {
Packit 534379
		OPAE_ERR("Failed to destroy object");
Packit 534379
	}
Packit 534379
Packit 534379
	return resval;
Packit 534379
}
Packit 534379
Packit 534379
// Read PHY group information
Packit 534379
fpga_result read_phy_group_info(fpga_token token,
Packit 534379
				fpga_phy_group_info *group_info,
Packit 534379
				uint32_t *group_num)
Packit 534379
{
Packit 534379
	fpga_result res = FPGA_OK;
Packit 534379
	fpga_result resval = FPGA_OK;
Packit 534379
	char path[SYSFS_MAX_SIZE] = { 0, };
Packit 534379
	char cdevid[CDEV_ID_SIZE] = { 0, };
Packit 534379
	size_t i = 0;
Packit 534379
	uint32_t group_dev_count = 0;
Packit 534379
	uint32_t obj_size = 0;
Packit 534379
	fpga_object dev_obj;
Packit 534379
	fpga_object group_object;
Packit 534379
	fpga_object group_dev_object;
Packit 534379
Packit 534379
Packit 534379
	if (group_num == NULL) {
Packit 534379
		FPGA_ERR("Invalid Input parameters");
Packit 534379
		return FPGA_INVALID_PARAM;
Packit 534379
	}
Packit 534379
Packit 534379
	res = fpgaTokenGetObject(token, SYSFS_PHY_GROUP_INFO,
Packit 534379
		&group_object, FPGA_OBJECT_GLOB);
Packit 534379
	if (res != FPGA_OK) {
Packit 534379
		OPAE_ERR("Failed to get token object");
Packit 534379
		return FPGA_NOT_FOUND;
Packit 534379
	}
Packit 534379
Packit 534379
	res = fpgaTokenGetObject(token, SYSFS_PHY_GROUP_INFO_DEV,
Packit 534379
		&group_dev_object, FPGA_OBJECT_GLOB);
Packit 534379
	if (res != FPGA_OK) {
Packit 534379
		OPAE_ERR("Failed to get token object");
Packit 534379
		resval = res;
Packit 534379
		goto out_destroy_group;
Packit 534379
	}
Packit 534379
Packit 534379
	res = fpgaObjectGetSize(group_dev_object, &group_dev_count, FPGA_OBJECT_GLOB);
Packit 534379
	if (res != FPGA_OK) {
Packit 534379
		OPAE_ERR("Failed to get object size");
Packit 534379
		resval = res;
Packit 534379
		goto out_destroy_group_dev;
Packit 534379
	}
Packit 534379
Packit 534379
	// Return number of group.
Packit 534379
	if (group_info == NULL) {
Packit 534379
		*group_num = group_dev_count;
Packit 534379
		resval = FPGA_OK;
Packit 534379
		goto out_destroy_group_dev;
Packit 534379
	}
Packit 534379
Packit 534379
	// Return error if group device count bigger then group info array size
Packit 534379
	if (group_dev_count > *group_num) {
Packit 534379
		FPGA_ERR("group device count bigger then group info array size");
Packit 534379
		resval = FPGA_EXCEPTION;
Packit 534379
		goto out_destroy_group_dev;
Packit 534379
	}
Packit 534379
Packit 534379
	for (i = 0; i < group_dev_count; i++) {
Packit 534379
Packit 534379
		res = fpgaObjectGetObjectAt(group_dev_object, i, &dev_obj);
Packit 534379
		if (res != FPGA_OK) {
Packit 534379
			OPAE_ERR("Failed to get device node object from group device object");
Packit 534379
			resval = res;
Packit 534379
			continue;
Packit 534379
		}
Packit 534379
Packit 534379
		res = fpgaObjectGetSize(dev_obj, &obj_size, 0);
Packit 534379
		if (res != FPGA_OK) {
Packit 534379
			OPAE_ERR("Failed to get object size");
Packit 534379
			resval = res;
Packit 534379
			res = fpgaDestroyObject(&dev_obj);
Packit 534379
			if (res != FPGA_OK) {
Packit 534379
				OPAE_ERR("Failed to destroy object");
Packit 534379
			}
Packit 534379
			continue;
Packit 534379
		}
Packit 534379
Packit 534379
Packit 534379
		if (obj_size > CDEV_ID_SIZE) {
Packit 534379
			OPAE_ERR("Device node obj size size bigger then buffer ");
Packit 534379
			resval = FPGA_EXCEPTION;
Packit 534379
			res = fpgaDestroyObject(&dev_obj);
Packit 534379
			if (res != FPGA_OK) {
Packit 534379
				OPAE_ERR("Failed to destroy object");
Packit 534379
			}
Packit 534379
			continue;
Packit 534379
		}
Packit 534379
Packit 534379
		res = fpgaObjectRead(dev_obj, (uint8_t *)cdevid, 0, obj_size, 0);
Packit 534379
		if (res != FPGA_OK) {
Packit 534379
			OPAE_ERR("Failed to read device node");
Packit 534379
			resval = res;
Packit 534379
			res = fpgaDestroyObject(&dev_obj);
Packit 534379
			if (res != FPGA_OK) {
Packit 534379
				OPAE_ERR("Failed to destroy object");
Packit 534379
			}
Packit 534379
			continue;
Packit 534379
		}
Packit 534379
Packit 534379
Packit 534379
		res = fpgaDestroyObject(&dev_obj);
Packit 534379
		if (res != FPGA_OK) {
Packit 534379
			resval = res;
Packit 534379
			OPAE_ERR("Failed to destroy object");
Packit 534379
		}
Packit 534379
Packit 534379
		// append null char
Packit 534379
		cdevid[obj_size - 1] = '\0';
Packit 534379
		strncpy(path, "/dev/char/", 11);
Packit 534379
		strncat(path, cdevid, sizeof(path) - obj_size - 1);
Packit 534379
Packit 534379
		res = get_phy_info(path, &group_info[i]);
Packit 534379
		if (res != FPGA_OK) {
Packit 534379
			OPAE_ERR("Failed to get phy group info");
Packit 534379
			resval = res;
Packit 534379
		}
Packit 534379
Packit 534379
	} // end for loop
Packit 534379
Packit 534379
out_destroy_group_dev:
Packit 534379
	res = fpgaDestroyObject(&group_dev_object);
Packit 534379
	if (res != FPGA_OK) {
Packit 534379
		OPAE_ERR("Failed to destroy object");
Packit 534379
	}
Packit 534379
Packit 534379
out_destroy_group:
Packit 534379
	res = fpgaDestroyObject(&group_object);
Packit 534379
	if (res != FPGA_OK) {
Packit 534379
		OPAE_ERR("Failed to destroy object");
Packit 534379
	}
Packit 534379
Packit 534379
	return resval;
Packit 534379
Packit 534379
}
Packit 534379
Packit 534379
// get pyh group information
Packit 534379
fpga_result get_phy_info(char *dev_path, fpga_phy_group_info *info)
Packit 534379
{
Packit 534379
	fpga_result res = FPGA_OK;
Packit 534379
	int fd          = 0;
Packit 534379
Packit 534379
	if (dev_path == NULL ||
Packit 534379
		info == NULL) {
Packit 534379
		FPGA_ERR("Invalid Input parameters");
Packit 534379
		return FPGA_INVALID_PARAM;
Packit 534379
	}
Packit 534379
Packit 534379
	fd = open(dev_path, O_RDWR);
Packit 534379
	if (fd < 0) {
Packit 534379
		OPAE_ERR("Open %s failed\n", dev_path);
Packit 534379
		return FPGA_INVALID_PARAM;
Packit 534379
	}
Packit 534379
Packit 534379
	memset(info, 0, sizeof(fpga_phy_group_info));
Packit 534379
	info->argsz = sizeof(fpga_phy_group_info);
Packit 534379
Packit 534379
	if (0 != ioctl(fd, FPGA_PHY_GROUP_GET_INFO, info)) {
Packit 534379
		OPAE_ERR("ioctl  FPGA_PHY_GROUP_GET_INFO error\n");
Packit 534379
	}
Packit 534379
Packit 534379
	close(fd);
Packit 534379
Packit 534379
	return res;
Packit 534379
}
Packit 534379
Packit 534379
// Read mac information
Packit 534379
fpga_result read_mac_info(fpga_token token, unsigned char *mac_info, size_t len)
Packit 534379
{
Packit 534379
	fpga_result res                 = FPGA_OK;
Packit 534379
	fpga_result resval              = FPGA_OK;
Packit 534379
	unsigned char buf[8]            = {0};
Packit 534379
	fpga_object mac_object;
Packit 534379
Packit 534379
	if (!token || !mac_info || !len) {
Packit 534379
		FPGA_ERR("Invalid Input parameters");
Packit 534379
		return FPGA_INVALID_PARAM;
Packit 534379
	}
Packit 534379
Packit 534379
	res = fpgaTokenGetObject(token, SYSFS_EEPROM, &mac_object, FPGA_OBJECT_GLOB);
Packit 534379
	if (res != FPGA_OK) {
Packit 534379
		OPAE_ERR("Failed to get token object");
Packit 534379
		return res;
Packit 534379
	}
Packit 534379
Packit 534379
	res = fpgaObjectRead(mac_object, (uint8_t *)buf, 0, sizeof(buf), 0);
Packit 534379
	if (res != FPGA_OK) {
Packit 534379
		OPAE_ERR("Failed to read object ");
Packit 534379
		resval = res;
Packit 534379
		goto out_destroy_mac;
Packit 534379
	}
Packit 534379
Packit 534379
	memcpy(mac_info, buf, len);
Packit 534379
Packit 534379
out_destroy_mac:
Packit 534379
	res = fpgaDestroyObject(&mac_object);
Packit 534379
	if (res != FPGA_OK) {
Packit 534379
		OPAE_ERR("Failed to destroy object");
Packit 534379
	}
Packit 534379
Packit 534379
	return resval;
Packit 534379
}
Packit 534379
Packit 534379
// Read pkvl versoin
Packit 534379
fpga_result print_pkvl_version(fpga_token token)
Packit 534379
{
Packit 534379
	fpga_result res                     = FPGA_OK;
Packit 534379
	fpga_result resval                  = FPGA_OK;
Packit 534379
	char ver_a_buf[FPGA_VAR_BUF_LEN]    = { 0 };
Packit 534379
	char ver_b_buf[FPGA_VAR_BUF_LEN]    = { 0 };
Packit 534379
	uint32_t size                       = 0;
Packit 534379
	fpga_object pkvl_a_object;
Packit 534379
	fpga_object pkvl_b_object;
Packit 534379
Packit 534379
Packit 534379
	res = fpgaTokenGetObject(token, SYSFS_PKVL_A_VER, &pkvl_a_object, FPGA_OBJECT_GLOB);
Packit 534379
	if (res != FPGA_OK) {
Packit 534379
		OPAE_MSG("Failed to get token object");
Packit 534379
		return res;
Packit 534379
	}
Packit 534379
Packit 534379
	res = fpgaTokenGetObject(token, SYSFS_PKVL_B_VER, &pkvl_b_object, FPGA_OBJECT_GLOB);
Packit 534379
	if (res != FPGA_OK) {
Packit 534379
		OPAE_MSG("Failed to get token object");
Packit 534379
		resval = res;
Packit 534379
		goto out_destroy_obj_a;
Packit 534379
	}
Packit 534379
Packit 534379
	res = fpgaObjectGetSize(pkvl_a_object, &size, FPGA_OBJECT_GLOB);
Packit 534379
	if (res != FPGA_OK) {
Packit 534379
		OPAE_ERR("Failed to get object size");
Packit 534379
		resval = res;
Packit 534379
		goto out_destroy_obj_b;
Packit 534379
	}
Packit 534379
Packit 534379
	if (size > FPGA_VAR_BUF_LEN) {
Packit 534379
		OPAE_ERR("pkvl A version buffer bigger then version buffer");
Packit 534379
		resval = FPGA_EXCEPTION;
Packit 534379
		goto out_destroy_obj_b;
Packit 534379
	}
Packit 534379
Packit 534379
	res = fpgaObjectRead(pkvl_a_object, (uint8_t *)ver_a_buf, 0, size, 0);
Packit 534379
	if (res != FPGA_OK) {
Packit 534379
		OPAE_ERR("Failed to read object ");
Packit 534379
		resval = res;
Packit 534379
		goto out_destroy_obj_b;
Packit 534379
	}
Packit 534379
Packit 534379
	res = fpgaObjectGetSize(pkvl_b_object, &size, FPGA_OBJECT_GLOB);
Packit 534379
	if (res != FPGA_OK) {
Packit 534379
		OPAE_ERR("Failed to get object size");
Packit 534379
		resval = res;
Packit 534379
		goto out_destroy_obj_b;
Packit 534379
	}
Packit 534379
Packit 534379
	if (size > FPGA_VAR_BUF_LEN) {
Packit 534379
		OPAE_ERR("pkvl B version buffer bigger then version buffer");
Packit 534379
		resval = FPGA_EXCEPTION;
Packit 534379
		goto out_destroy_obj_b;
Packit 534379
	}
Packit 534379
Packit 534379
Packit 534379
	res = fpgaObjectRead(pkvl_b_object, (uint8_t *)ver_b_buf, 0, size, 0);
Packit 534379
	if (res != FPGA_OK) {
Packit 534379
		OPAE_ERR("Failed to read object ");
Packit 534379
		resval = res;
Packit 534379
		goto out_destroy_obj_b;
Packit 534379
	}
Packit 534379
Packit 534379
	printf("%-32s : %s", "Retimer A Version", ver_a_buf);
Packit 534379
	printf("%-32s : %s", "Retimer B Version", ver_b_buf);
Packit 534379
Packit 534379
out_destroy_obj_b:
Packit 534379
	res = fpgaDestroyObject(&pkvl_b_object);
Packit 534379
	if (res != FPGA_OK) {
Packit 534379
		OPAE_ERR("Failed to destroy object");
Packit 534379
	}
Packit 534379
Packit 534379
out_destroy_obj_a:
Packit 534379
	res = fpgaDestroyObject(&pkvl_a_object);
Packit 534379
	if (res != FPGA_OK) {
Packit 534379
		OPAE_ERR("Failed to destroy object");
Packit 534379
	}
Packit 534379
Packit 534379
	return resval;
Packit 534379
}
Packit 534379
Packit 534379
// print mac information
Packit 534379
fpga_result print_mac_info(fpga_token token)
Packit 534379
{
Packit 534379
	fpga_result res                  = FPGA_OK;
Packit 534379
	unsigned char buf[MAC_BUF_SIZE]  = { 0 };
Packit 534379
	int i                            = 0;
Packit 534379
	int n                            = 0;
Packit 534379
	pkvl_mac mac;
Packit 534379
Packit 534379
	res = read_mac_info(token, buf, MAC_BUF_SIZE);
Packit 534379
	if (res != FPGA_OK) {
Packit 534379
		OPAE_ERR("Failed to read mac information");
Packit 534379
		return res;
Packit 534379
	}
Packit 534379
Packit 534379
	n = (int)buf[6];
Packit 534379
	printf("%-32s : %d\n", "Number of MACs", n);
Packit 534379
	mac.byte[0] = buf[5];
Packit 534379
	mac.byte[1] = buf[4];
Packit 534379
	mac.byte[2] = buf[3];
Packit 534379
	mac.byte[3] = 0;
Packit 534379
	for (i = 0; i < n; ++i) {
Packit 534379
		printf("%s %-20d : %02X:%02X:%02X:%02X:%02X:%02X\n",
Packit 534379
			"MAC address", i, buf[0], buf[1], buf[2],
Packit 534379
			mac.byte[2], mac.byte[1], mac.byte[0]);
Packit 534379
		mac.dword += 1;
Packit 534379
	}
Packit 534379
Packit 534379
	return res;
Packit 534379
}
Packit 534379
Packit 534379
// print board information
Packit 534379
fpga_result print_board_info(fpga_token token)
Packit 534379
{
Packit 534379
	fpga_result res                      = FPGA_OK;
Packit 534379
	char bmc_ver[FPGA_VAR_BUF_LEN]       = { 0 };
Packit 534379
	char max10_ver[FPGA_VAR_BUF_LEN]     = { 0 };
Packit 534379
	char pcb_ver[FPGA_VAR_BUF_LEN]       = { 0 };
Packit 534379
Packit 534379
	res = read_bmcfw_version(token, bmc_ver, FPGA_VAR_BUF_LEN);
Packit 534379
	if (res != FPGA_OK) {
Packit 534379
		OPAE_MSG("Failed to read bmc version");
Packit 534379
	}
Packit 534379
Packit 534379
	res = read_max10fw_version(token, max10_ver, FPGA_VAR_BUF_LEN);
Packit 534379
	if (res != FPGA_OK) {
Packit 534379
		OPAE_MSG("Failed to read max10 version");
Packit 534379
	}
Packit 534379
Packit 534379
	res = read_pcb_info(token, pcb_ver, FPGA_VAR_BUF_LEN);
Packit 534379
	if (res != FPGA_OK) {
Packit 534379
		OPAE_MSG("Failed to read pcb version");
Packit 534379
	}
Packit 534379
Packit 534379
	printf("Board Management Controller, MAX10 NIOS FW version: %s \n", bmc_ver);
Packit 534379
	printf("Board Management Controller, MAX10 Build version: %s \n", max10_ver);
Packit 534379
	printf("PCB version: %s \n", pcb_ver);;
Packit 534379
Packit 534379
	return res;
Packit 534379
}
Packit 534379
Packit 534379
// print phy group information
Packit 534379
fpga_result print_phy_info(fpga_token token)
Packit 534379
{
Packit 534379
	fpga_result res                            = FPGA_OK;
Packit 534379
	fpga_phy_group_info *phy_info_array        = NULL;
Packit 534379
	uint32_t group_num                         = 0;
Packit 534379
	int fpga_mode                              = 0;
Packit 534379
	uint32_t i                                 = 0;
Packit 534379
	int j                                      = 0;
Packit 534379
	char mode[VER_BUF_SIZE]                    = { 0 };
Packit 534379
	fpga_pkvl_info pkvl_info;
Packit 534379
Packit 534379
Packit 534379
	res = read_phy_group_info(token, NULL, &group_num);
Packit 534379
	if (res != FPGA_OK) {
Packit 534379
		OPAE_ERR("Failed to read phy group count");
Packit 534379
		return res;
Packit 534379
	}
Packit 534379
Packit 534379
	phy_info_array = calloc(sizeof(fpga_phy_group_info), group_num);
Packit 534379
	if (phy_info_array == NULL) {
Packit 534379
		OPAE_ERR(" Failed to allocate memory");
Packit 534379
		return FPGA_NO_MEMORY;
Packit 534379
	}
Packit 534379
Packit 534379
Packit 534379
	res = read_phy_group_info(token, phy_info_array, &group_num);
Packit 534379
	if (res != FPGA_OK) {
Packit 534379
		OPAE_ERR("Failed to read phy group array");
Packit 534379
		goto out_free;
Packit 534379
	}
Packit 534379
Packit 534379
	res = read_pkvl_info(token, &pkvl_info, &fpga_mode);
Packit 534379
	if (res != FPGA_OK) {
Packit 534379
		OPAE_ERR("Failed to read pkvl info");
Packit 534379
		goto out_free;
Packit 534379
	}
Packit 534379
Packit 534379
Packit 534379
	for (i = 0; i < group_num; i++) {
Packit 534379
Packit 534379
		printf("//****** PHY GROUP %d ******//\n", i);
Packit 534379
		printf("%-32s : %s\n", "Direction",
Packit 534379
			phy_info_array[i].group_id == 0 ? "Line side" : "Fortville side");
Packit 534379
		printf("%-32s : %d Gbps\n", "Speed", phy_info_array[i].speed);
Packit 534379
		printf("%-32s : %d\n", "Number of PHYs", phy_info_array[i].phy_num);
Packit 534379
	}
Packit 534379
Packit 534379
Packit 534379
	int mask = 0;
Packit 534379
	if (phy_info_array[0].speed == 10) {
Packit 534379
		mask = 0xff;
Packit 534379
Packit 534379
	} else if (phy_info_array[0].speed == 25) {
Packit 534379
Packit 534379
Packit 534379
		if (phy_info_array[0].phy_num == 4) {
Packit 534379
			switch (fpga_mode) {
Packit 534379
			case FPGA_PHYGROUP_MODE_4_25G: /* 4x25g */
Packit 534379
				/* FALLTHROUGH */
Packit 534379
			case FPGA_PHYGROUP_MODE_6_25G: /* 6x25g */
Packit 534379
				mask = 0xf;
Packit 534379
				break;
Packit 534379
Packit 534379
			case FPGA_PHYGROUP_MODE_2_2_25G: /* 2x2x25g */
Packit 534379
				mask = 0x33;
Packit 534379
				break;
Packit 534379
Packit 534379
			default:
Packit 534379
				mask = 0xff;
Packit 534379
				break;
Packit 534379
			}
Packit 534379
		} else {
Packit 534379
			/* 2*1*25g */
Packit 534379
			mask = 0x11;
Packit 534379
		}
Packit 534379
Packit 534379
	}
Packit 534379
Packit 534379
	printf("//****** Intel C827 Retimer ******//\n");
Packit 534379
Packit 534379
	strncpy(mode, phy_info_array[0].speed == 25 ? "25G" : "10G", 4);
Packit 534379
	for (i = 0, j = 0; i < MAX_PORTS; i++) {
Packit 534379
		if (mask&(1 << i)) {
Packit 534379
			printf("Port%-2d%-26s : %s\n", j, mode, pkvl_info.status&(1 << i) ? "Up" : "Down");
Packit 534379
			j++;
Packit 534379
		}
Packit 534379
	}
Packit 534379
Packit 534379
	res = print_pkvl_version(token);
Packit 534379
	if (res != FPGA_OK) {
Packit 534379
		OPAE_MSG("Failed to read pkvl version");
Packit 534379
		goto out_free;
Packit 534379
	}
Packit 534379
Packit 534379
out_free:
Packit 534379
	if (phy_info_array)
Packit 534379
		free(phy_info_array);
Packit 534379
Packit 534379
	return res;
Packit 534379
Packit 534379
}