/*
 * Copyright(c) 2015, 2016 Intel Corporation.
 *
 * This file is provided under a dual BSD/GPLv2 license.  When using or
 * redistributing this file, you may do so under either license.
 *
 * GPL LICENSE SUMMARY
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of version 2 of the GNU General Public License as
 * published by the Free Software Foundation.
 *
 * This program is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * General Public License for more details.
 *
 * BSD LICENSE
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 *
 *  - Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 *  - Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in
 *    the documentation and/or other materials provided with the
 *    distribution.
 *  - Neither the name of Intel Corporation nor the names of its
 *    contributors may be used to endorse or promote products derived
 *    from this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 *
 */

#include <linux/firmware.h>

#include "hfi.h"
#include "efivar.h"
#include "eprom.h"

#define DEFAULT_PLATFORM_CONFIG_NAME "hfi1_platform.dat"

static int validate_scratch_checksum(struct hfi1_devdata *dd)
{
	u64 checksum = 0, temp_scratch = 0;
	int i, j, version;

	temp_scratch = read_csr(dd, ASIC_CFG_SCRATCH);
	version = (temp_scratch & BITMAP_VERSION_SMASK) >> BITMAP_VERSION_SHIFT;

	/* Prevent power on default of all zeroes from passing checksum */
	if (!version) {
		dd_dev_err(dd, "%s: Config bitmap uninitialized\n", __func__);
		dd_dev_err(dd,
			   "%s: Please update your BIOS to support active channels\n",
			   __func__);
		return 0;
	}

	/*
	 * ASIC scratch 0 only contains the checksum and bitmap version as
	 * fields of interest, both of which are handled separately from the
	 * loop below, so skip it
	 */
	checksum += version;
	for (i = 1; i < ASIC_NUM_SCRATCH; i++) {
		temp_scratch = read_csr(dd, ASIC_CFG_SCRATCH + (8 * i));
		for (j = sizeof(u64); j != 0; j -= 2) {
			checksum += (temp_scratch & 0xFFFF);
			temp_scratch >>= 16;
		}
	}

	while (checksum >> 16)
		checksum = (checksum & CHECKSUM_MASK) + (checksum >> 16);

	temp_scratch = read_csr(dd, ASIC_CFG_SCRATCH);
	temp_scratch &= CHECKSUM_SMASK;
	temp_scratch >>= CHECKSUM_SHIFT;

	if (checksum + temp_scratch == 0xFFFF)
		return 1;

	dd_dev_err(dd, "%s: Configuration bitmap corrupted\n", __func__);
	return 0;
}

static void save_platform_config_fields(struct hfi1_devdata *dd)
{
	struct hfi1_pportdata *ppd = dd->pport;
	u64 temp_scratch = 0, temp_dest = 0;

	temp_scratch = read_csr(dd, ASIC_CFG_SCRATCH_1);

	temp_dest = temp_scratch &
		    (dd->hfi1_id ? PORT1_PORT_TYPE_SMASK :
		     PORT0_PORT_TYPE_SMASK);
	ppd->port_type = temp_dest >>
			 (dd->hfi1_id ? PORT1_PORT_TYPE_SHIFT :
			  PORT0_PORT_TYPE_SHIFT);

	temp_dest = temp_scratch &
		    (dd->hfi1_id ? PORT1_LOCAL_ATTEN_SMASK :
		     PORT0_LOCAL_ATTEN_SMASK);
	ppd->local_atten = temp_dest >>
			   (dd->hfi1_id ? PORT1_LOCAL_ATTEN_SHIFT :
			    PORT0_LOCAL_ATTEN_SHIFT);

	temp_dest = temp_scratch &
		    (dd->hfi1_id ? PORT1_REMOTE_ATTEN_SMASK :
		     PORT0_REMOTE_ATTEN_SMASK);
	ppd->remote_atten = temp_dest >>
			    (dd->hfi1_id ? PORT1_REMOTE_ATTEN_SHIFT :
			     PORT0_REMOTE_ATTEN_SHIFT);

	temp_dest = temp_scratch &
		    (dd->hfi1_id ? PORT1_DEFAULT_ATTEN_SMASK :
		     PORT0_DEFAULT_ATTEN_SMASK);
	ppd->default_atten = temp_dest >>
			     (dd->hfi1_id ? PORT1_DEFAULT_ATTEN_SHIFT :
			      PORT0_DEFAULT_ATTEN_SHIFT);

	temp_scratch = read_csr(dd, dd->hfi1_id ? ASIC_CFG_SCRATCH_3 :
				ASIC_CFG_SCRATCH_2);

	ppd->tx_preset_eq = (temp_scratch & TX_EQ_SMASK) >> TX_EQ_SHIFT;
	ppd->tx_preset_noeq = (temp_scratch & TX_NO_EQ_SMASK) >> TX_NO_EQ_SHIFT;
	ppd->rx_preset = (temp_scratch & RX_SMASK) >> RX_SHIFT;

	ppd->max_power_class = (temp_scratch & QSFP_MAX_POWER_SMASK) >>
				QSFP_MAX_POWER_SHIFT;

	ppd->config_from_scratch = true;
}

void get_platform_config(struct hfi1_devdata *dd)
{
	int ret = 0;
	u8 *temp_platform_config = NULL;
	u32 esize;
	const struct firmware *platform_config_file = NULL;

	if (is_integrated(dd)) {
		if (validate_scratch_checksum(dd)) {
			save_platform_config_fields(dd);
			return;
		}
	} else {
		ret = eprom_read_platform_config(dd,
						 (void **)&temp_platform_config,
						 &esize);
		if (!ret) {
			/* success */
			dd->platform_config.data = temp_platform_config;
			dd->platform_config.size = esize;
			return;
		}
	}
	dd_dev_err(dd,
		   "%s: Failed to get platform config, falling back to sub-optimal default file\n",
		   __func__);

	ret = request_firmware(&platform_config_file,
			       DEFAULT_PLATFORM_CONFIG_NAME,
			       &dd->pcidev->dev);
	if (ret) {
		dd_dev_err(dd,
			   "%s: No default platform config file found\n",
			   __func__);
		return;
	}

	/*
	 * Allocate separate memory block to store data and free firmware
	 * structure. This allows free_platform_config to treat EPROM and
	 * fallback configs in the same manner.
	 */
	dd->platform_config.data = kmemdup(platform_config_file->data,
					   platform_config_file->size,
					   GFP_KERNEL);
	dd->platform_config.size = platform_config_file->size;
	release_firmware(platform_config_file);
}

void free_platform_config(struct hfi1_devdata *dd)
{
	/* Release memory allocated for eprom or fallback file read. */
	kfree(dd->platform_config.data);
	dd->platform_config.data = NULL;
}

void get_port_type(struct hfi1_pportdata *ppd)
{
	int ret;
	u32 temp;

	ret = get_platform_config_field(ppd->dd, PLATFORM_CONFIG_PORT_TABLE, 0,
					PORT_TABLE_PORT_TYPE, &temp,
					4);
	if (ret) {
		ppd->port_type = PORT_TYPE_UNKNOWN;
		return;
	}
	ppd->port_type = temp;
}

int set_qsfp_tx(struct hfi1_pportdata *ppd, int on)
{
	u8 tx_ctrl_byte = on ? 0x0 : 0xF;
	int ret = 0;

	ret = qsfp_write(ppd, ppd->dd->hfi1_id, QSFP_TX_CTRL_BYTE_OFFS,
			 &tx_ctrl_byte, 1);
	/* we expected 1, so consider 0 an error */
	if (ret == 0)
		ret = -EIO;
	else if (ret == 1)
		ret = 0;
	return ret;
}

static int qual_power(struct hfi1_pportdata *ppd)
{
	u32 cable_power_class = 0, power_class_max = 0;
	u8 *cache = ppd->qsfp_info.cache;
	int ret = 0;

	ret = get_platform_config_field(
		ppd->dd, PLATFORM_CONFIG_SYSTEM_TABLE, 0,
		SYSTEM_TABLE_QSFP_POWER_CLASS_MAX, &power_class_max, 4);
	if (ret)
		return ret;

	cable_power_class = get_qsfp_power_class(cache[QSFP_MOD_PWR_OFFS]);

	if (cable_power_class > power_class_max)
		ppd->offline_disabled_reason =
			HFI1_ODR_MASK(OPA_LINKDOWN_REASON_POWER_POLICY);

	if (ppd->offline_disabled_reason ==
			HFI1_ODR_MASK(OPA_LINKDOWN_REASON_POWER_POLICY)) {
		dd_dev_err(
			ppd->dd,
			"%s: Port disabled due to system power restrictions\n",
			__func__);
		ret = -EPERM;
	}
	return ret;
}

static int qual_bitrate(struct hfi1_pportdata *ppd)
{
	u16 lss = ppd->link_speed_supported, lse = ppd->link_speed_enabled;
	u8 *cache = ppd->qsfp_info.cache;

	if ((lss & OPA_LINK_SPEED_25G) && (lse & OPA_LINK_SPEED_25G) &&
	    cache[QSFP_NOM_BIT_RATE_250_OFFS] < 0x64)
		ppd->offline_disabled_reason =
			   HFI1_ODR_MASK(OPA_LINKDOWN_REASON_LINKSPEED_POLICY);

	if ((lss & OPA_LINK_SPEED_12_5G) && (lse & OPA_LINK_SPEED_12_5G) &&
	    cache[QSFP_NOM_BIT_RATE_100_OFFS] < 0x7D)
		ppd->offline_disabled_reason =
			   HFI1_ODR_MASK(OPA_LINKDOWN_REASON_LINKSPEED_POLICY);

	if (ppd->offline_disabled_reason ==
			HFI1_ODR_MASK(OPA_LINKDOWN_REASON_LINKSPEED_POLICY)) {
		dd_dev_err(
			ppd->dd,
			"%s: Cable failed bitrate check, disabling port\n",
			__func__);
		return -EPERM;
	}
	return 0;
}

static int set_qsfp_high_power(struct hfi1_pportdata *ppd)
{
	u8 cable_power_class = 0, power_ctrl_byte = 0;
	u8 *cache = ppd->qsfp_info.cache;
	int ret;

	cable_power_class = get_qsfp_power_class(cache[QSFP_MOD_PWR_OFFS]);

	if (cable_power_class > QSFP_POWER_CLASS_1) {
		power_ctrl_byte = cache[QSFP_PWR_CTRL_BYTE_OFFS];

		power_ctrl_byte |= 1;
		power_ctrl_byte &= ~(0x2);

		ret = qsfp_write(ppd, ppd->dd->hfi1_id,
				 QSFP_PWR_CTRL_BYTE_OFFS,
				 &power_ctrl_byte, 1);
		if (ret != 1)
			return -EIO;

		if (cable_power_class > QSFP_POWER_CLASS_4) {
			power_ctrl_byte |= (1 << 2);
			ret = qsfp_write(ppd, ppd->dd->hfi1_id,
					 QSFP_PWR_CTRL_BYTE_OFFS,
					 &power_ctrl_byte, 1);
			if (ret != 1)
				return -EIO;
		}

		/* SFF 8679 rev 1.7 LPMode Deassert time */
		msleep(300);
	}
	return 0;
}

static void apply_rx_cdr(struct hfi1_pportdata *ppd,
			 u32 rx_preset_index,
			 u8 *cdr_ctrl_byte)
{
	u32 rx_preset;
	u8 *cache = ppd->qsfp_info.cache;
	int cable_power_class;

	if (!((cache[QSFP_MOD_PWR_OFFS] & 0x4) &&
	      (cache[QSFP_CDR_INFO_OFFS] & 0x40)))
		return;

	/* RX CDR present, bypass supported */
	cable_power_class = get_qsfp_power_class(cache[QSFP_MOD_PWR_OFFS]);

	if (cable_power_class <= QSFP_POWER_CLASS_3) {
		/* Power class <= 3, ignore config & turn RX CDR on */
		*cdr_ctrl_byte |= 0xF;
		return;
	}

	get_platform_config_field(
		ppd->dd, PLATFORM_CONFIG_RX_PRESET_TABLE,
		rx_preset_index, RX_PRESET_TABLE_QSFP_RX_CDR_APPLY,
		&rx_preset, 4);

	if (!rx_preset) {
		dd_dev_info(
			ppd->dd,
			"%s: RX_CDR_APPLY is set to disabled\n",
			__func__);
		return;
	}
	get_platform_config_field(
		ppd->dd, PLATFORM_CONFIG_RX_PRESET_TABLE,
		rx_preset_index, RX_PRESET_TABLE_QSFP_RX_CDR,
		&rx_preset, 4);

	/* Expand cdr setting to all 4 lanes */
	rx_preset = (rx_preset | (rx_preset << 1) |
			(rx_preset << 2) | (rx_preset << 3));

	if (rx_preset) {
		*cdr_ctrl_byte |= rx_preset;
	} else {
		*cdr_ctrl_byte &= rx_preset;
		/* Preserve current TX CDR status */
		*cdr_ctrl_byte |= (cache[QSFP_CDR_CTRL_BYTE_OFFS] & 0xF0);
	}
}

static void apply_tx_cdr(struct hfi1_pportdata *ppd,
			 u32 tx_preset_index,
			 u8 *cdr_ctrl_byte)
{
	u32 tx_preset;
	u8 *cache = ppd->qsfp_info.cache;
	int cable_power_class;

	if (!((cache[QSFP_MOD_PWR_OFFS] & 0x8) &&
	      (cache[QSFP_CDR_INFO_OFFS] & 0x80)))
		return;

	/* TX CDR present, bypass supported */
	cable_power_class = get_qsfp_power_class(cache[QSFP_MOD_PWR_OFFS]);

	if (cable_power_class <= QSFP_POWER_CLASS_3) {
		/* Power class <= 3, ignore config & turn TX CDR on */
		*cdr_ctrl_byte |= 0xF0;
		return;
	}

	get_platform_config_field(
		ppd->dd,
		PLATFORM_CONFIG_TX_PRESET_TABLE, tx_preset_index,
		TX_PRESET_TABLE_QSFP_TX_CDR_APPLY, &tx_preset, 4);

	if (!tx_preset) {
		dd_dev_info(
			ppd->dd,
			"%s: TX_CDR_APPLY is set to disabled\n",
			__func__);
		return;
	}
	get_platform_config_field(
		ppd->dd,
		PLATFORM_CONFIG_TX_PRESET_TABLE,
		tx_preset_index,
		TX_PRESET_TABLE_QSFP_TX_CDR, &tx_preset, 4);

	/* Expand cdr setting to all 4 lanes */
	tx_preset = (tx_preset | (tx_preset << 1) |
			(tx_preset << 2) | (tx_preset << 3));

	if (tx_preset)
		*cdr_ctrl_byte |= (tx_preset << 4);
	else
		/* Preserve current/determined RX CDR status */
		*cdr_ctrl_byte &= ((tx_preset << 4) | 0xF);
}

static void apply_cdr_settings(
		struct hfi1_pportdata *ppd, u32 rx_preset_index,
		u32 tx_preset_index)
{
	u8 *cache = ppd->qsfp_info.cache;
	u8 cdr_ctrl_byte = cache[QSFP_CDR_CTRL_BYTE_OFFS];

	apply_rx_cdr(ppd, rx_preset_index, &cdr_ctrl_byte);

	apply_tx_cdr(ppd, tx_preset_index, &cdr_ctrl_byte);

	qsfp_write(ppd, ppd->dd->hfi1_id, QSFP_CDR_CTRL_BYTE_OFFS,
		   &cdr_ctrl_byte, 1);
}

static void apply_tx_eq_auto(struct hfi1_pportdata *ppd)
{
	u8 *cache = ppd->qsfp_info.cache;
	u8 tx_eq;

	if (!(cache[QSFP_EQ_INFO_OFFS] & 0x8))
		return;
	/* Disable adaptive TX EQ if present */
	tx_eq = cache[(128 * 3) + 241];
	tx_eq &= 0xF0;
	qsfp_write(ppd, ppd->dd->hfi1_id, (256 * 3) + 241, &tx_eq, 1);
}

static void apply_tx_eq_prog(struct hfi1_pportdata *ppd, u32 tx_preset_index)
{
	u8 *cache = ppd->qsfp_info.cache;
	u32 tx_preset;
	u8 tx_eq;

	if (!(cache[QSFP_EQ_INFO_OFFS] & 0x4))
		return;

	get_platform_config_field(
		ppd->dd, PLATFORM_CONFIG_TX_PRESET_TABLE,
		tx_preset_index, TX_PRESET_TABLE_QSFP_TX_EQ_APPLY,
		&tx_preset, 4);
	if (!tx_preset) {
		dd_dev_info(
			ppd->dd,
			"%s: TX_EQ_APPLY is set to disabled\n",
			__func__);
		return;
	}
	get_platform_config_field(
			ppd->dd, PLATFORM_CONFIG_TX_PRESET_TABLE,
			tx_preset_index, TX_PRESET_TABLE_QSFP_TX_EQ,
			&tx_preset, 4);

	if (((cache[(128 * 3) + 224] & 0xF0) >> 4) < tx_preset) {
		dd_dev_info(
			ppd->dd,
			"%s: TX EQ %x unsupported\n",
			__func__, tx_preset);

		dd_dev_info(
			ppd->dd,
			"%s: Applying EQ %x\n",
			__func__, cache[608] & 0xF0);

		tx_preset = (cache[608] & 0xF0) >> 4;
	}

	tx_eq = tx_preset | (tx_preset << 4);
	qsfp_write(ppd, ppd->dd->hfi1_id, (256 * 3) + 234, &tx_eq, 1);
	qsfp_write(ppd, ppd->dd->hfi1_id, (256 * 3) + 235, &tx_eq, 1);
}

static void apply_rx_eq_emp(struct hfi1_pportdata *ppd, u32 rx_preset_index)
{
	u32 rx_preset;
	u8 rx_eq, *cache = ppd->qsfp_info.cache;

	if (!(cache[QSFP_EQ_INFO_OFFS] & 0x2))
		return;
	get_platform_config_field(
			ppd->dd, PLATFORM_CONFIG_RX_PRESET_TABLE,
			rx_preset_index, RX_PRESET_TABLE_QSFP_RX_EMP_APPLY,
			&rx_preset, 4);

	if (!rx_preset) {
		dd_dev_info(
			ppd->dd,
			"%s: RX_EMP_APPLY is set to disabled\n",
			__func__);
		return;
	}
	get_platform_config_field(
		ppd->dd, PLATFORM_CONFIG_RX_PRESET_TABLE,
		rx_preset_index, RX_PRESET_TABLE_QSFP_RX_EMP,
		&rx_preset, 4);

	if ((cache[(128 * 3) + 224] & 0xF) < rx_preset) {
		dd_dev_info(
			ppd->dd,
			"%s: Requested RX EMP %x\n",
			__func__, rx_preset);

		dd_dev_info(
			ppd->dd,
			"%s: Applying supported EMP %x\n",
			__func__, cache[608] & 0xF);

		rx_preset = cache[608] & 0xF;
	}

	rx_eq = rx_preset | (rx_preset << 4);

	qsfp_write(ppd, ppd->dd->hfi1_id, (256 * 3) + 236, &rx_eq, 1);
	qsfp_write(ppd, ppd->dd->hfi1_id, (256 * 3) + 237, &rx_eq, 1);
}

static void apply_eq_settings(struct hfi1_pportdata *ppd,
			      u32 rx_preset_index, u32 tx_preset_index)
{
	u8 *cache = ppd->qsfp_info.cache;

	/* no point going on w/o a page 3 */
	if (cache[2] & 4) {
		dd_dev_info(ppd->dd,
			    "%s: Upper page 03 not present\n",
			    __func__);
		return;
	}

	apply_tx_eq_auto(ppd);

	apply_tx_eq_prog(ppd, tx_preset_index);

	apply_rx_eq_emp(ppd, rx_preset_index);
}

static void apply_rx_amplitude_settings(
		struct hfi1_pportdata *ppd, u32 rx_preset_index,
		u32 tx_preset_index)
{
	u32 rx_preset;
	u8 rx_amp = 0, i = 0, preferred = 0, *cache = ppd->qsfp_info.cache;

	/* no point going on w/o a page 3 */
	if (cache[2] & 4) {
		dd_dev_info(ppd->dd,
			    "%s: Upper page 03 not present\n",
			    __func__);
		return;
	}
	if (!(cache[QSFP_EQ_INFO_OFFS] & 0x1)) {
		dd_dev_info(ppd->dd,
			    "%s: RX_AMP_APPLY is set to disabled\n",
			    __func__);
		return;
	}

	get_platform_config_field(ppd->dd,
				  PLATFORM_CONFIG_RX_PRESET_TABLE,
				  rx_preset_index,
				  RX_PRESET_TABLE_QSFP_RX_AMP_APPLY,
				  &rx_preset, 4);

	if (!rx_preset) {
		dd_dev_info(ppd->dd,
			    "%s: RX_AMP_APPLY is set to disabled\n",
			    __func__);
		return;
	}
	get_platform_config_field(ppd->dd,
				  PLATFORM_CONFIG_RX_PRESET_TABLE,
				  rx_preset_index,
				  RX_PRESET_TABLE_QSFP_RX_AMP,
				  &rx_preset, 4);

	dd_dev_info(ppd->dd,
		    "%s: Requested RX AMP %x\n",
		    __func__,
		    rx_preset);

	for (i = 0; i < 4; i++) {
		if (cache[(128 * 3) + 225] & (1 << i)) {
			preferred = i;
			if (preferred == rx_preset)
				break;
		}
	}

	/*
	 * Verify that preferred RX amplitude is not just a
	 * fall through of the default
	 */
	if (!preferred && !(cache[(128 * 3) + 225] & 0x1)) {
		dd_dev_info(ppd->dd, "No supported RX AMP, not applying\n");
		return;
	}

	dd_dev_info(ppd->dd,
		    "%s: Applying RX AMP %x\n", __func__, preferred);

	rx_amp = preferred | (preferred << 4);
	qsfp_write(ppd, ppd->dd->hfi1_id, (256 * 3) + 238, &rx_amp, 1);
	qsfp_write(ppd, ppd->dd->hfi1_id, (256 * 3) + 239, &rx_amp, 1);
}

#define OPA_INVALID_INDEX 0xFFF

static void apply_tx_lanes(struct hfi1_pportdata *ppd, u8 field_id,
			   u32 config_data, const char *message)
{
	u8 i;
	int ret;

	for (i = 0; i < 4; i++) {
		ret = load_8051_config(ppd->dd, field_id, i, config_data);
		if (ret != HCMD_SUCCESS) {
			dd_dev_err(
				ppd->dd,
				"%s: %s for lane %u failed\n",
				message, __func__, i);
		}
	}
}

/*
 * Return a special SerDes setting for low power AOC cables.  The power class
 * threshold and setting being used were all found by empirical testing.
 *
 * Summary of the logic:
 *
 * if (QSFP and QSFP_TYPE == AOC and QSFP_POWER_CLASS < 4)
 *     return 0xe
 * return 0; // leave at default
 */
static u8 aoc_low_power_setting(struct hfi1_pportdata *ppd)
{
	u8 *cache = ppd->qsfp_info.cache;
	int power_class;

	/* QSFP only */
	if (ppd->port_type != PORT_TYPE_QSFP)
		return 0; /* leave at default */

	/* active optical cables only */
	switch ((cache[QSFP_MOD_TECH_OFFS] & 0xF0) >> 4) {
	case 0x0 ... 0x9: fallthrough;
	case 0xC: fallthrough;
	case 0xE:
		/* active AOC */
		power_class = get_qsfp_power_class(cache[QSFP_MOD_PWR_OFFS]);
		if (power_class < QSFP_POWER_CLASS_4)
			return 0xe;
	}
	return 0; /* leave at default */
}

static void apply_tunings(
		struct hfi1_pportdata *ppd, u32 tx_preset_index,
		u8 tuning_method, u32 total_atten, u8 limiting_active)
{
	int ret = 0;
	u32 config_data = 0, tx_preset = 0;
	u8 precur = 0, attn = 0, postcur = 0, external_device_config = 0;
	u8 *cache = ppd->qsfp_info.cache;

	/* Pass tuning method to 8051 */
	read_8051_config(ppd->dd, LINK_TUNING_PARAMETERS, GENERAL_CONFIG,
			 &config_data);
	config_data &= ~(0xff << TUNING_METHOD_SHIFT);
	config_data |= ((u32)tuning_method << TUNING_METHOD_SHIFT);
	ret = load_8051_config(ppd->dd, LINK_TUNING_PARAMETERS, GENERAL_CONFIG,
			       config_data);
	if (ret != HCMD_SUCCESS)
		dd_dev_err(ppd->dd, "%s: Failed to set tuning method\n",
			   __func__);

	/* Set same channel loss for both TX and RX */
	config_data = 0 | (total_atten << 16) | (total_atten << 24);
	apply_tx_lanes(ppd, CHANNEL_LOSS_SETTINGS, config_data,
		       "Setting channel loss");

	/* Inform 8051 of cable capabilities */
	if (ppd->qsfp_info.cache_valid) {
		external_device_config =
			((cache[QSFP_MOD_PWR_OFFS] & 0x4) << 3) |
			((cache[QSFP_MOD_PWR_OFFS] & 0x8) << 2) |
			((cache[QSFP_EQ_INFO_OFFS] & 0x2) << 1) |
			(cache[QSFP_EQ_INFO_OFFS] & 0x4);
		ret = read_8051_config(ppd->dd, DC_HOST_COMM_SETTINGS,
				       GENERAL_CONFIG, &config_data);
		/* Clear, then set the external device config field */
		config_data &= ~(u32)0xFF;
		config_data |= external_device_config;
		ret = load_8051_config(ppd->dd, DC_HOST_COMM_SETTINGS,
				       GENERAL_CONFIG, config_data);
		if (ret != HCMD_SUCCESS)
			dd_dev_err(ppd->dd,
				   "%s: Failed set ext device config params\n",
				   __func__);
	}

	if (tx_preset_index == OPA_INVALID_INDEX) {
		if (ppd->port_type == PORT_TYPE_QSFP && limiting_active)
			dd_dev_err(ppd->dd, "%s: Invalid Tx preset index\n",
				   __func__);
		return;
	}

	/* Following for limiting active channels only */
	get_platform_config_field(
		ppd->dd, PLATFORM_CONFIG_TX_PRESET_TABLE, tx_preset_index,
		TX_PRESET_TABLE_PRECUR, &tx_preset, 4);
	precur = tx_preset;

	get_platform_config_field(
		ppd->dd, PLATFORM_CONFIG_TX_PRESET_TABLE,
		tx_preset_index, TX_PRESET_TABLE_ATTN, &tx_preset, 4);
	attn = tx_preset;

	get_platform_config_field(
		ppd->dd, PLATFORM_CONFIG_TX_PRESET_TABLE,
		tx_preset_index, TX_PRESET_TABLE_POSTCUR, &tx_preset, 4);
	postcur = tx_preset;

	/*
	 * NOTES:
	 * o The aoc_low_power_setting is applied to all lanes even
	 *   though only lane 0's value is examined by the firmware.
	 * o A lingering low power setting after a cable swap does
	 *   not occur.  On cable unplug the 8051 is reset and
	 *   restarted on cable insert.  This resets all settings to
	 *   their default, erasing any previous low power setting.
	 */
	config_data = precur | (attn << 8) | (postcur << 16) |
			(aoc_low_power_setting(ppd) << 24);

	apply_tx_lanes(ppd, TX_EQ_SETTINGS, config_data,
		       "Applying TX settings");
}

/* Must be holding the QSFP i2c resource */
static int tune_active_qsfp(struct hfi1_pportdata *ppd, u32 *ptr_tx_preset,
			    u32 *ptr_rx_preset, u32 *ptr_total_atten)
{
	int ret;
	u16 lss = ppd->link_speed_supported, lse = ppd->link_speed_enabled;
	u8 *cache = ppd->qsfp_info.cache;

	ppd->qsfp_info.limiting_active = 1;

	ret = set_qsfp_tx(ppd, 0);
	if (ret)
		return ret;

	ret = qual_power(ppd);
	if (ret)
		return ret;

	ret = qual_bitrate(ppd);
	if (ret)
		return ret;

	/*
	 * We'll change the QSFP memory contents from here on out, thus we set a
	 * flag here to remind ourselves to reset the QSFP module. This prevents
	 * reuse of stale settings established in our previous pass through.
	 */
	if (ppd->qsfp_info.reset_needed) {
		ret = reset_qsfp(ppd);
		if (ret)
			return ret;
		refresh_qsfp_cache(ppd, &ppd->qsfp_info);
	} else {
		ppd->qsfp_info.reset_needed = 1;
	}

	ret = set_qsfp_high_power(ppd);
	if (ret)
		return ret;

	if (cache[QSFP_EQ_INFO_OFFS] & 0x4) {
		ret = get_platform_config_field(
			ppd->dd,
			PLATFORM_CONFIG_PORT_TABLE, 0,
			PORT_TABLE_TX_PRESET_IDX_ACTIVE_EQ,
			ptr_tx_preset, 4);
		if (ret) {
			*ptr_tx_preset = OPA_INVALID_INDEX;
			return ret;
		}
	} else {
		ret = get_platform_config_field(
			ppd->dd,
			PLATFORM_CONFIG_PORT_TABLE, 0,
			PORT_TABLE_TX_PRESET_IDX_ACTIVE_NO_EQ,
			ptr_tx_preset, 4);
		if (ret) {
			*ptr_tx_preset = OPA_INVALID_INDEX;
			return ret;
		}
	}

	ret = get_platform_config_field(
		ppd->dd, PLATFORM_CONFIG_PORT_TABLE, 0,
		PORT_TABLE_RX_PRESET_IDX, ptr_rx_preset, 4);
	if (ret) {
		*ptr_rx_preset = OPA_INVALID_INDEX;
		return ret;
	}

	if ((lss & OPA_LINK_SPEED_25G) && (lse & OPA_LINK_SPEED_25G))
		get_platform_config_field(
			ppd->dd, PLATFORM_CONFIG_PORT_TABLE, 0,
			PORT_TABLE_LOCAL_ATTEN_25G, ptr_total_atten, 4);
	else if ((lss & OPA_LINK_SPEED_12_5G) && (lse & OPA_LINK_SPEED_12_5G))
		get_platform_config_field(
			ppd->dd, PLATFORM_CONFIG_PORT_TABLE, 0,
			PORT_TABLE_LOCAL_ATTEN_12G, ptr_total_atten, 4);

	apply_cdr_settings(ppd, *ptr_rx_preset, *ptr_tx_preset);

	apply_eq_settings(ppd, *ptr_rx_preset, *ptr_tx_preset);

	apply_rx_amplitude_settings(ppd, *ptr_rx_preset, *ptr_tx_preset);

	ret = set_qsfp_tx(ppd, 1);

	return ret;
}

static int tune_qsfp(struct hfi1_pportdata *ppd,
		     u32 *ptr_tx_preset, u32 *ptr_rx_preset,
		     u8 *ptr_tuning_method, u32 *ptr_total_atten)
{
	u32 cable_atten = 0, remote_atten = 0, platform_atten = 0;
	u16 lss = ppd->link_speed_supported, lse = ppd->link_speed_enabled;
	int ret = 0;
	u8 *cache = ppd->qsfp_info.cache;

	switch ((cache[QSFP_MOD_TECH_OFFS] & 0xF0) >> 4) {
	case 0xA ... 0xB:
		ret = get_platform_config_field(
			ppd->dd,
			PLATFORM_CONFIG_PORT_TABLE, 0,
			PORT_TABLE_LOCAL_ATTEN_25G,
			&platform_atten, 4);
		if (ret)
			return ret;

		if ((lss & OPA_LINK_SPEED_25G) && (lse & OPA_LINK_SPEED_25G))
			cable_atten = cache[QSFP_CU_ATTEN_12G_OFFS];
		else if ((lss & OPA_LINK_SPEED_12_5G) &&
			 (lse & OPA_LINK_SPEED_12_5G))
			cable_atten = cache[QSFP_CU_ATTEN_7G_OFFS];

		/* Fallback to configured attenuation if cable memory is bad */
		if (cable_atten == 0 || cable_atten > 36) {
			ret = get_platform_config_field(
				ppd->dd,
				PLATFORM_CONFIG_SYSTEM_TABLE, 0,
				SYSTEM_TABLE_QSFP_ATTENUATION_DEFAULT_25G,
				&cable_atten, 4);
			if (ret)
				return ret;
		}

		ret = get_platform_config_field(
			ppd->dd, PLATFORM_CONFIG_PORT_TABLE, 0,
			PORT_TABLE_REMOTE_ATTEN_25G, &remote_atten, 4);
		if (ret)
			return ret;

		*ptr_total_atten = platform_atten + cable_atten + remote_atten;

		*ptr_tuning_method = OPA_PASSIVE_TUNING;
		break;
	case 0x0 ... 0x9: fallthrough;
	case 0xC: fallthrough;
	case 0xE:
		ret = tune_active_qsfp(ppd, ptr_tx_preset, ptr_rx_preset,
				       ptr_total_atten);
		if (ret)
			return ret;

		*ptr_tuning_method = OPA_ACTIVE_TUNING;
		break;
	case 0xD: fallthrough;
	case 0xF:
	default:
		dd_dev_warn(ppd->dd, "%s: Unknown/unsupported cable\n",
			    __func__);
		break;
	}
	return ret;
}

/*
 * This function communicates its success or failure via ppd->driver_link_ready
 * Thus, it depends on its association with start_link(...) which checks
 * driver_link_ready before proceeding with the link negotiation and
 * initialization process.
 */
void tune_serdes(struct hfi1_pportdata *ppd)
{
	int ret = 0;
	u32 total_atten = 0;
	u32 remote_atten = 0, platform_atten = 0;
	u32 rx_preset_index, tx_preset_index;
	u8 tuning_method = 0, limiting_active = 0;
	struct hfi1_devdata *dd = ppd->dd;

	rx_preset_index = OPA_INVALID_INDEX;
	tx_preset_index = OPA_INVALID_INDEX;

	/* the link defaults to enabled */
	ppd->link_enabled = 1;
	/* the driver link ready state defaults to not ready */
	ppd->driver_link_ready = 0;
	ppd->offline_disabled_reason = HFI1_ODR_MASK(OPA_LINKDOWN_REASON_NONE);

	/* Skip the tuning for testing (loopback != none) and simulations */
	if (loopback != LOOPBACK_NONE ||
	    ppd->dd->icode == ICODE_FUNCTIONAL_SIMULATOR) {
		ppd->driver_link_ready = 1;

		if (qsfp_mod_present(ppd)) {
			ret = acquire_chip_resource(ppd->dd,
						    qsfp_resource(ppd->dd),
						    QSFP_WAIT);
			if (ret) {
				dd_dev_err(ppd->dd, "%s: hfi%d: cannot lock i2c chain\n",
					   __func__, (int)ppd->dd->hfi1_id);
				goto bail;
			}

			refresh_qsfp_cache(ppd, &ppd->qsfp_info);
			release_chip_resource(ppd->dd, qsfp_resource(ppd->dd));
		}

		return;
	}

	switch (ppd->port_type) {
	case PORT_TYPE_DISCONNECTED:
		ppd->offline_disabled_reason =
			HFI1_ODR_MASK(OPA_LINKDOWN_REASON_DISCONNECTED);
		dd_dev_warn(dd, "%s: Port disconnected, disabling port\n",
			    __func__);
		goto bail;
	case PORT_TYPE_FIXED:
		/* platform_atten, remote_atten pre-zeroed to catch error */
		get_platform_config_field(
			ppd->dd, PLATFORM_CONFIG_PORT_TABLE, 0,
			PORT_TABLE_LOCAL_ATTEN_25G, &platform_atten, 4);

		get_platform_config_field(
			ppd->dd, PLATFORM_CONFIG_PORT_TABLE, 0,
			PORT_TABLE_REMOTE_ATTEN_25G, &remote_atten, 4);

		total_atten = platform_atten + remote_atten;

		tuning_method = OPA_PASSIVE_TUNING;
		break;
	case PORT_TYPE_VARIABLE:
		if (qsfp_mod_present(ppd)) {
			/*
			 * platform_atten, remote_atten pre-zeroed to
			 * catch error
			 */
			get_platform_config_field(
				ppd->dd, PLATFORM_CONFIG_PORT_TABLE, 0,
				PORT_TABLE_LOCAL_ATTEN_25G,
				&platform_atten, 4);

			get_platform_config_field(
				ppd->dd, PLATFORM_CONFIG_PORT_TABLE, 0,
				PORT_TABLE_REMOTE_ATTEN_25G,
				&remote_atten, 4);

			total_atten = platform_atten + remote_atten;

			tuning_method = OPA_PASSIVE_TUNING;
		} else {
			ppd->offline_disabled_reason =
			     HFI1_ODR_MASK(OPA_LINKDOWN_REASON_CHASSIS_CONFIG);
			goto bail;
		}
		break;
	case PORT_TYPE_QSFP:
		if (qsfp_mod_present(ppd)) {
			ret = acquire_chip_resource(ppd->dd,
						    qsfp_resource(ppd->dd),
						    QSFP_WAIT);
			if (ret) {
				dd_dev_err(ppd->dd, "%s: hfi%d: cannot lock i2c chain\n",
					   __func__, (int)ppd->dd->hfi1_id);
				goto bail;
			}
			refresh_qsfp_cache(ppd, &ppd->qsfp_info);

			if (ppd->qsfp_info.cache_valid) {
				ret = tune_qsfp(ppd,
						&tx_preset_index,
						&rx_preset_index,
						&tuning_method,
						&total_atten);

				/*
				 * We may have modified the QSFP memory, so
				 * update the cache to reflect the changes
				 */
				refresh_qsfp_cache(ppd, &ppd->qsfp_info);
				limiting_active =
						ppd->qsfp_info.limiting_active;
			} else {
				dd_dev_err(dd,
					   "%s: Reading QSFP memory failed\n",
					   __func__);
				ret = -EINVAL; /* a fail indication */
			}
			release_chip_resource(ppd->dd, qsfp_resource(ppd->dd));
			if (ret)
				goto bail;
		} else {
			ppd->offline_disabled_reason =
			   HFI1_ODR_MASK(
				OPA_LINKDOWN_REASON_LOCAL_MEDIA_NOT_INSTALLED);
			goto bail;
		}
		break;
	default:
		dd_dev_warn(ppd->dd, "%s: Unknown port type\n", __func__);
		ppd->port_type = PORT_TYPE_UNKNOWN;
		tuning_method = OPA_UNKNOWN_TUNING;
		total_atten = 0;
		limiting_active = 0;
		tx_preset_index = OPA_INVALID_INDEX;
		break;
	}

	if (ppd->offline_disabled_reason ==
			HFI1_ODR_MASK(OPA_LINKDOWN_REASON_NONE))
		apply_tunings(ppd, tx_preset_index, tuning_method,
			      total_atten, limiting_active);

	if (!ret)
		ppd->driver_link_ready = 1;

	return;
bail:
	ppd->driver_link_ready = 0;
}
