/*
 * Copyright 2019 Advanced Micro Devices, Inc.
 *
 * Permission is hereby granted, free of charge, to any person obtaining a
 * copy of this software and associated documentation files (the "Software"),
 * to deal in the Software without restriction, including without limitation
 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
 * and/or sell copies of the Software, and to permit persons to whom the
 * Software is furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in
 * all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
 * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
 * OTHER DEALINGS IN THE SOFTWARE.
 *
 */
#include <linux/pci.h>

#include "amdgpu.h"
#include "amdgpu_i2c.h"
#include "smu_v11_0_i2c.h"
#include "atom.h"
#include "amdgpu_fru_eeprom.h"
#include "amdgpu_eeprom.h"

#define FRU_EEPROM_MADDR_6      0x60000
#define FRU_EEPROM_MADDR_8      0x80000
#define FRU_EEPROM_MADDR_INV    0xFFFFF

static bool is_fru_eeprom_supported(struct amdgpu_device *adev, u32 *fru_addr)
{
	/* Only server cards have the FRU EEPROM
	 * TODO: See if we can figure this out dynamically instead of
	 * having to parse VBIOS versions.
	 */
	struct atom_context *atom_ctx = adev->mode_info.atom_context;

	/* The i2c access is blocked on VF
	 * TODO: Need other way to get the info
	 * Also, FRU not valid for APU devices.
	 */
	if (amdgpu_sriov_vf(adev) || (adev->flags & AMD_IS_APU))
		return false;

	/* The default I2C EEPROM address of the FRU.
	 */
	if (fru_addr)
		*fru_addr = FRU_EEPROM_MADDR_8;

	/* VBIOS is of the format ###-DXXXYYYY-##. For SKU identification,
	 * we can use just the "DXXX" portion. If there were more models, we
	 * could convert the 3 characters to a hex integer and use a switch
	 * for ease/speed/readability. For now, 2 string comparisons are
	 * reasonable and not too expensive
	 */
	switch (amdgpu_ip_version(adev, MP1_HWIP, 0)) {
	case IP_VERSION(11, 0, 2):
		switch (adev->asic_type) {
		case CHIP_VEGA20:
			/* D161 and D163 are the VG20 server SKUs */
			if (atom_ctx && (strnstr(atom_ctx->vbios_pn, "D161",
						 sizeof(atom_ctx->vbios_pn)) ||
					 strnstr(atom_ctx->vbios_pn, "D163",
						 sizeof(atom_ctx->vbios_pn)))) {
				if (fru_addr)
					*fru_addr = FRU_EEPROM_MADDR_6;
				return true;
			} else {
				return false;
			}
		case CHIP_ARCTURUS:
		default:
			return false;
		}
	case IP_VERSION(11, 0, 7):
		if (atom_ctx && strnstr(atom_ctx->vbios_pn, "D603",
					sizeof(atom_ctx->vbios_pn))) {
			if (strnstr(atom_ctx->vbios_pn, "D603GLXE",
				    sizeof(atom_ctx->vbios_pn))) {
				return false;
			}

			if (fru_addr)
				*fru_addr = FRU_EEPROM_MADDR_6;
			return true;

		} else {
			return false;
		}
	case IP_VERSION(13, 0, 2):
		/* All Aldebaran SKUs have an FRU */
		if (atom_ctx && !strnstr(atom_ctx->vbios_pn, "D673",
					 sizeof(atom_ctx->vbios_pn)))
			if (fru_addr)
				*fru_addr = FRU_EEPROM_MADDR_6;
		return true;
	case IP_VERSION(13, 0, 6):
	case IP_VERSION(13, 0, 14):
			if (fru_addr)
				*fru_addr = FRU_EEPROM_MADDR_8;
			return true;
	case IP_VERSION(13, 0, 12):
	case IP_VERSION(15, 0, 8):
			if (fru_addr)
				*fru_addr = FRU_EEPROM_MADDR_INV;
			return true;
	default:
		return false;
	}
}

/*
 * IPMI FRU Product Info Area fields are TLV: one type/length byte
 * (low 6 bits = data length) followed by that many data bytes. These
 * helpers walk the cursor and copy a single field while bounding all
 * accesses to the actual buffer length read from the EEPROM.
 */
#define FRU_FIELD_LEN(p, a)	((p)[a] & 0x3F)

/* Advance cursor past the current TLV. Returns false if no more data. */
static bool fru_pia_advance(u32 *addr, const unsigned char *pia, int len)
{
	if (*addr >= (u32)len)
		return false;
	*addr += 1 + FRU_FIELD_LEN(pia, *addr);
	return true;
}

/*
 * Copy the current TLV's data into dst (NUL-terminated). Returns false if
 * the TLV header or data would read past the end of pia.
 */
static bool fru_pia_copy_field(char *dst, size_t dst_size,
			       const unsigned char *pia, u32 addr, int len)
{
	size_t fl;

	if (addr + 1 >= (u32)len)
		return false;

	fl = min3((size_t)FRU_FIELD_LEN(pia, addr),
			  dst_size - 1,
			  (size_t)(len - addr - 1));
	memcpy(dst, pia + addr + 1, fl);
	dst[fl] = '\0';
	return true;
}

int amdgpu_fru_get_product_info(struct amdgpu_device *adev)
{
	struct amdgpu_fru_info *fru_info;
	unsigned char buf[8], *pia;
	u32 addr, fru_addr;
	int size, len;
	u8 csum;

	if (!is_fru_eeprom_supported(adev, &fru_addr))
		return 0;

	/* FRU data avaialble, but no direct EEPROM access */
	if (fru_addr == FRU_EEPROM_MADDR_INV)
		return 0;

	if (!adev->fru_info) {
		adev->fru_info = kzalloc_obj(*adev->fru_info);
		if (!adev->fru_info)
			return -ENOMEM;
	}

	fru_info = adev->fru_info;
	/* For Arcturus-and-later, default value of serial_number is unique_id
	 * so convert it to a 16-digit HEX string for convenience and
	 * backwards-compatibility.
	 */
	sprintf(fru_info->serial, "%llx", adev->unique_id);

	/* If algo exists, it means that the i2c_adapter's initialized */
	if (!adev->pm.fru_eeprom_i2c_bus || !adev->pm.fru_eeprom_i2c_bus->algo) {
		dev_warn(adev->dev,
			 "Cannot access FRU, EEPROM accessor not initialized");
		return -ENODEV;
	}

	/* Read the IPMI Common header */
	len = amdgpu_eeprom_read(adev->pm.fru_eeprom_i2c_bus, fru_addr, buf,
				 sizeof(buf));
	if (len != 8) {
		dev_err(adev->dev, "Couldn't read the IPMI Common Header: %d",
			len);
		return len < 0 ? len : -EIO;
	}

	if (buf[0] != 1) {
		dev_err(adev->dev, "Bad IPMI Common Header version: 0x%02x",
			buf[0]);
		return -EIO;
	}

	for (csum = 0; len > 0; len--)
		csum += buf[len - 1];
	if (csum) {
		dev_err(adev->dev, "Bad IPMI Common Header checksum: 0x%02x",
			csum);
		return -EIO;
	}

	/* Get the offset to the Product Info Area (PIA). */
	addr = buf[4] * 8;
	if (!addr)
		return 0;

	/* Get the absolute address to the PIA. */
	addr += fru_addr;

	/* Read the header of the PIA. */
	len = amdgpu_eeprom_read(adev->pm.fru_eeprom_i2c_bus, addr, buf, 3);
	if (len != 3) {
		dev_err(adev->dev,
			"Couldn't read the Product Info Area header: %d", len);
		return len < 0 ? len : -EIO;
	}

	if (buf[0] != 1) {
		dev_err(adev->dev, "Bad IPMI Product Info Area version: 0x%02x",
			buf[0]);
		return -EIO;
	}

	size = buf[1] * 8;
	pia = kzalloc(size, GFP_KERNEL);
	if (!pia)
		return -ENOMEM;

	/* Read the whole PIA. */
	len = amdgpu_eeprom_read(adev->pm.fru_eeprom_i2c_bus, addr, pia, size);
	if (len != size) {
		kfree(pia);
		dev_err(adev->dev, "Couldn't read the Product Info Area: %d",
			len);
		return len < 0 ? len : -EIO;
	}

	for (csum = 0; size > 0; size--)
		csum += pia[size - 1];
	if (csum) {
		dev_err(adev->dev, "Bad Product Info Area checksum: 0x%02x",
			csum);
		kfree(pia);
		return -EIO;
	}

	/* Now extract useful information from the PIA.
	 *
	 * Read Manufacturer Name field whose length is [3].
	 */
	addr = 3;
	if (!fru_pia_copy_field(fru_info->manufacturer_name,
				sizeof(fru_info->manufacturer_name),
				pia, addr, len))
		goto Out;

	/* Read Product Name field. */
	if (!fru_pia_advance(&addr, pia, len) ||
	    !fru_pia_copy_field(fru_info->product_name,
				sizeof(fru_info->product_name),
				pia, addr, len))
		goto Out;

	/* Go to the Product Part/Model Number field. */
	if (!fru_pia_advance(&addr, pia, len) ||
	    !fru_pia_copy_field(fru_info->product_number,
				sizeof(fru_info->product_number),
				pia, addr, len))
		goto Out;

	/* Skip the Product Version field. */
	if (!fru_pia_advance(&addr, pia, len))
		goto Out;

	/* Read the Product Serial Number field. */
	if (!fru_pia_advance(&addr, pia, len) ||
	    !fru_pia_copy_field(fru_info->serial,
				sizeof(fru_info->serial),
				pia, addr, len))
		goto Out;

	/* Skip the Asset Tag field. */
	if (!fru_pia_advance(&addr, pia, len))
		goto Out;

	/* FRU File Id field. This could be 'null'. */
	if (!fru_pia_advance(&addr, pia, len) ||
	    !fru_pia_copy_field(fru_info->fru_id,
				sizeof(fru_info->fru_id),
				pia, addr, len))
		goto Out;

Out:
	kfree(pia);
	return 0;
}

/**
 * DOC: product_name
 *
 * The amdgpu driver provides a sysfs API for reporting the product name
 * for the device
 * The file product_name is used for this and returns the product name
 * as returned from the FRU.
 * NOTE: This is only available for certain server cards
 */

static ssize_t amdgpu_fru_product_name_show(struct device *dev,
					    struct device_attribute *attr,
					    char *buf)
{
	struct drm_device *ddev = dev_get_drvdata(dev);
	struct amdgpu_device *adev = drm_to_adev(ddev);

	return sysfs_emit(buf, "%s\n", adev->fru_info->product_name);
}

static DEVICE_ATTR(product_name, 0444, amdgpu_fru_product_name_show, NULL);

/**
 * DOC: product_number
 *
 * The amdgpu driver provides a sysfs API for reporting the part number
 * for the device
 * The file product_number is used for this and returns the part number
 * as returned from the FRU.
 * NOTE: This is only available for certain server cards
 */

static ssize_t amdgpu_fru_product_number_show(struct device *dev,
					      struct device_attribute *attr,
					      char *buf)
{
	struct drm_device *ddev = dev_get_drvdata(dev);
	struct amdgpu_device *adev = drm_to_adev(ddev);

	return sysfs_emit(buf, "%s\n", adev->fru_info->product_number);
}

static DEVICE_ATTR(product_number, 0444, amdgpu_fru_product_number_show, NULL);

/**
 * DOC: serial_number
 *
 * The amdgpu driver provides a sysfs API for reporting the serial number
 * for the device
 * The file serial_number is used for this and returns the serial number
 * as returned from the FRU.
 * NOTE: This is only available for certain server cards
 */

static ssize_t amdgpu_fru_serial_number_show(struct device *dev,
					     struct device_attribute *attr,
					     char *buf)
{
	struct drm_device *ddev = dev_get_drvdata(dev);
	struct amdgpu_device *adev = drm_to_adev(ddev);

	return sysfs_emit(buf, "%s\n", adev->fru_info->serial);
}

static DEVICE_ATTR(serial_number, 0444, amdgpu_fru_serial_number_show, NULL);

/**
 * DOC: fru_id
 *
 * The amdgpu driver provides a sysfs API for reporting FRU File Id
 * for the device.
 * The file fru_id is used for this and returns the File Id value
 * as returned from the FRU.
 * NOTE: This is only available for certain server cards
 */

static ssize_t amdgpu_fru_id_show(struct device *dev,
				  struct device_attribute *attr, char *buf)
{
	struct drm_device *ddev = dev_get_drvdata(dev);
	struct amdgpu_device *adev = drm_to_adev(ddev);

	return sysfs_emit(buf, "%s\n", adev->fru_info->fru_id);
}

static DEVICE_ATTR(fru_id, 0444, amdgpu_fru_id_show, NULL);

/**
 * DOC: manufacturer
 *
 * The amdgpu driver provides a sysfs API for reporting manufacturer name from
 * FRU information.
 * The file manufacturer returns the value as returned from the FRU.
 * NOTE: This is only available for certain server cards
 */

static ssize_t amdgpu_fru_manufacturer_name_show(struct device *dev,
						 struct device_attribute *attr,
						 char *buf)
{
	struct drm_device *ddev = dev_get_drvdata(dev);
	struct amdgpu_device *adev = drm_to_adev(ddev);

	return sysfs_emit(buf, "%s\n", adev->fru_info->manufacturer_name);
}

static DEVICE_ATTR(manufacturer, 0444, amdgpu_fru_manufacturer_name_show, NULL);

static const struct attribute *amdgpu_fru_attributes[] = {
	&dev_attr_product_name.attr,
	&dev_attr_product_number.attr,
	&dev_attr_serial_number.attr,
	&dev_attr_fru_id.attr,
	&dev_attr_manufacturer.attr,
	NULL
};

int amdgpu_fru_sysfs_init(struct amdgpu_device *adev)
{
	if (!is_fru_eeprom_supported(adev, NULL) || !adev->fru_info)
		return 0;

	return sysfs_create_files(&adev->dev->kobj, amdgpu_fru_attributes);
}

void amdgpu_fru_sysfs_fini(struct amdgpu_device *adev)
{
	if (!adev->fru_info)
		return;

	sysfs_remove_files(&adev->dev->kobj, amdgpu_fru_attributes);
}
