/***********************license start***************
 * Author: Cavium Networks
 *
 * Contact: support@caviumnetworks.com
 * This file is part of the OCTEON SDK
 *
 * Copyright (C) 2003-2018 Cavium, Inc.
 *
 * This file is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License, Version 2, as
 * published by the Free Software Foundation.
 *
 * This file is distributed in the hope that it will be useful, but
 * AS-IS and WITHOUT ANY WARRANTY; without even the implied warranty
 * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, TITLE, or
 * NONINFRINGEMENT.  See the GNU General Public License for more
 * details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this file; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
 * or visit http://www.gnu.org/licenses/.
 *
 * This file may also be available under a different license from Cavium.
 * Contact Cavium Networks for more information
 ***********************license end**************************************/

/*
 * Functions for SGMII initialization, configuration,
 * and monitoring.
 */

#include <asm/octeon/octeon.h>

#include <asm/octeon/cvmx-config.h>

#include <asm/octeon/cvmx-helper.h>
#include <asm/octeon/cvmx-helper-board.h>

#include <asm/octeon/cvmx-gmxx-defs.h>
#include <asm/octeon/cvmx-pcsx-defs.h>
#include <asm/octeon/cvmx-pcsxx-defs.h>

/**
 * Perform initialization required only once for an SGMII port.
 *
 * @interface: Interface to init
 * @index:     Index of prot on the interface
 *
 * Returns Zero on success, negative on failure
 */
static int __cvmx_helper_sgmii_hardware_init_one_time(int interface, int index)
{
	const uint64_t clock_mhz = cvmx_sysinfo_get()->cpu_clock_hz / 1000000;
	union cvmx_pcsx_miscx_ctl_reg pcs_misc_ctl_reg;
	union cvmx_pcsx_linkx_timer_count_reg pcsx_linkx_timer_count_reg;
	union cvmx_gmxx_prtx_cfg gmxx_prtx_cfg;

	/* Disable GMX */
	gmxx_prtx_cfg.u64 = cvmx_read_csr(CVMX_GMXX_PRTX_CFG(index, interface));
	gmxx_prtx_cfg.s.en = 0;
	cvmx_write_csr(CVMX_GMXX_PRTX_CFG(index, interface), gmxx_prtx_cfg.u64);

	/*
	 * Write PCS*_LINK*_TIMER_COUNT_REG[COUNT] with the
	 * appropriate value. 1000BASE-X specifies a 10ms
	 * interval. SGMII specifies a 1.6ms interval.
	 */
	pcs_misc_ctl_reg.u64 =
	    cvmx_read_csr(CVMX_PCSX_MISCX_CTL_REG(index, interface));
	pcsx_linkx_timer_count_reg.u64 =
	    cvmx_read_csr(CVMX_PCSX_LINKX_TIMER_COUNT_REG(index, interface));
	if (pcs_misc_ctl_reg.s.mode) {
		/* 1000BASE-X */
		pcsx_linkx_timer_count_reg.s.count =
		    (10000ull * clock_mhz) >> 10;
	} else {
		/* SGMII */
		pcsx_linkx_timer_count_reg.s.count =
		    (1600ull * clock_mhz) >> 10;
	}
	cvmx_write_csr(CVMX_PCSX_LINKX_TIMER_COUNT_REG(index, interface),
		       pcsx_linkx_timer_count_reg.u64);

	/*
	 * Write the advertisement register to be used as the
	 * tx_Config_Reg<D15:D0> of the autonegotiation.  In
	 * 1000BASE-X mode, tx_Config_Reg<D15:D0> is PCS*_AN*_ADV_REG.
	 * In SGMII PHY mode, tx_Config_Reg<D15:D0> is
	 * PCS*_SGM*_AN_ADV_REG.  In SGMII MAC mode,
	 * tx_Config_Reg<D15:D0> is the fixed value 0x4001, so this
	 * step can be skipped.
	 */
	if (pcs_misc_ctl_reg.s.mode) {
		/* 1000BASE-X */
		union cvmx_pcsx_anx_adv_reg pcsx_anx_adv_reg;
		pcsx_anx_adv_reg.u64 =
		    cvmx_read_csr(CVMX_PCSX_ANX_ADV_REG(index, interface));
		pcsx_anx_adv_reg.s.rem_flt = 0;
		pcsx_anx_adv_reg.s.pause = 3;
		pcsx_anx_adv_reg.s.hfd = 1;
		pcsx_anx_adv_reg.s.fd = 1;
		cvmx_write_csr(CVMX_PCSX_ANX_ADV_REG(index, interface),
			       pcsx_anx_adv_reg.u64);
	} else {
		union cvmx_pcsx_miscx_ctl_reg pcsx_miscx_ctl_reg;
		pcsx_miscx_ctl_reg.u64 =
		    cvmx_read_csr(CVMX_PCSX_MISCX_CTL_REG(index, interface));
		if (pcsx_miscx_ctl_reg.s.mac_phy) {
			/* PHY Mode */
			union cvmx_pcsx_sgmx_an_adv_reg pcsx_sgmx_an_adv_reg;
			pcsx_sgmx_an_adv_reg.u64 =
			    cvmx_read_csr(CVMX_PCSX_SGMX_AN_ADV_REG
					  (index, interface));
			pcsx_sgmx_an_adv_reg.s.link = 1;
			pcsx_sgmx_an_adv_reg.s.dup = 1;
			pcsx_sgmx_an_adv_reg.s.speed = 2;
			cvmx_write_csr(CVMX_PCSX_SGMX_AN_ADV_REG
				       (index, interface),
				       pcsx_sgmx_an_adv_reg.u64);
		} else {
			/* MAC Mode - Nothing to do */
		}
	}
	return 0;
}

/**
 * Initialize the SERTES link for the first time or after a loss
 * of link.
 *
 * @interface: Interface to init
 * @index:     Index of prot on the interface
 *
 * Returns Zero on success, negative on failure
 */
static int __cvmx_helper_sgmii_hardware_init_link(int interface, int index)
{
	union cvmx_pcsx_mrx_control_reg control_reg;

	/*
	 * Take PCS through a reset sequence.
	 * PCS*_MR*_CONTROL_REG[PWR_DN] should be cleared to zero.
	 * Write PCS*_MR*_CONTROL_REG[RESET]=1 (while not changing the
	 * value of the other PCS*_MR*_CONTROL_REG bits).  Read
	 * PCS*_MR*_CONTROL_REG[RESET] until it changes value to
	 * zero.
	 */
	control_reg.u64 =
	    cvmx_read_csr(CVMX_PCSX_MRX_CONTROL_REG(index, interface));
	if (cvmx_sysinfo_get()->board_type != CVMX_BOARD_TYPE_SIM) {
		control_reg.s.reset = 1;
		cvmx_write_csr(CVMX_PCSX_MRX_CONTROL_REG(index, interface),
			       control_reg.u64);
		if (CVMX_WAIT_FOR_FIELD64
		    (CVMX_PCSX_MRX_CONTROL_REG(index, interface),
		     union cvmx_pcsx_mrx_control_reg, reset, ==, 0, 10000)) {
			cvmx_dprintf("SGMII%d: Timeout waiting for port %d "
				     "to finish reset\n",
			     interface, index);
			return -1;
		}
	}

	/*
	 * Write PCS*_MR*_CONTROL_REG[RST_AN]=1 to ensure a fresh
	 * sgmii negotiation starts.
	 */
	control_reg.s.rst_an = 1;
	control_reg.s.an_en = 1;
	control_reg.s.pwr_dn = 0;
	cvmx_write_csr(CVMX_PCSX_MRX_CONTROL_REG(index, interface),
		       control_reg.u64);

	/*
	 * Wait for PCS*_MR*_STATUS_REG[AN_CPT] to be set, indicating
	 * that sgmii autonegotiation is complete. In MAC mode this
	 * isn't an ethernet link, but a link between Octeon and the
	 * PHY.
	 */
	if ((cvmx_sysinfo_get()->board_type != CVMX_BOARD_TYPE_SIM) &&
	    CVMX_WAIT_FOR_FIELD64(CVMX_PCSX_MRX_STATUS_REG(index, interface),
				  union cvmx_pcsx_mrx_status_reg, an_cpt, ==, 1,
				  10000)) {
		/* cvmx_dprintf("SGMII%d: Port %d link timeout\n", interface, index); */
		return -1;
	}
	return 0;
}

/**
 * Configure an SGMII link to the specified speed after the SERTES
 * link is up.
 *
 * @interface: Interface to init
 * @index:     Index of prot on the interface
 * @link_info: Link state to configure
 *
 * Returns Zero on success, negative on failure
 */
static int __cvmx_helper_sgmii_hardware_init_link_speed(int interface,
							int index,
							union cvmx_helper_link_info
							link_info)
{
	int is_enabled;
	union cvmx_gmxx_prtx_cfg gmxx_prtx_cfg;
	union cvmx_pcsx_miscx_ctl_reg pcsx_miscx_ctl_reg;

	/* Disable GMX before we make any changes. Remember the enable state */
	gmxx_prtx_cfg.u64 = cvmx_read_csr(CVMX_GMXX_PRTX_CFG(index, interface));
	is_enabled = gmxx_prtx_cfg.s.en;
	gmxx_prtx_cfg.s.en = 0;
	cvmx_write_csr(CVMX_GMXX_PRTX_CFG(index, interface), gmxx_prtx_cfg.u64);

	/* Wait for GMX to be idle */
	if (CVMX_WAIT_FOR_FIELD64
	    (CVMX_GMXX_PRTX_CFG(index, interface), union cvmx_gmxx_prtx_cfg,
	     rx_idle, ==, 1, 10000)
	    || CVMX_WAIT_FOR_FIELD64(CVMX_GMXX_PRTX_CFG(index, interface),
				     union cvmx_gmxx_prtx_cfg, tx_idle, ==, 1,
				     10000)) {
		cvmx_dprintf
		    ("SGMII%d: Timeout waiting for port %d to be idle\n",
		     interface, index);
		return -1;
	}

	/* Read GMX CFG again to make sure the disable completed */
	gmxx_prtx_cfg.u64 = cvmx_read_csr(CVMX_GMXX_PRTX_CFG(index, interface));

	/*
	 * Get the misc control for PCS. We will need to set the
	 * duplication amount.
	 */
	pcsx_miscx_ctl_reg.u64 =
	    cvmx_read_csr(CVMX_PCSX_MISCX_CTL_REG(index, interface));

	/*
	 * Use GMXENO to force the link down if the status we get says
	 * it should be down.
	 */
	pcsx_miscx_ctl_reg.s.gmxeno = !link_info.s.link_up;

	/* Only change the duplex setting if the link is up */
	if (link_info.s.link_up)
		gmxx_prtx_cfg.s.duplex = link_info.s.full_duplex;

	/* Do speed based setting for GMX */
	switch (link_info.s.speed) {
	case 10:
		gmxx_prtx_cfg.s.speed = 0;
		gmxx_prtx_cfg.s.speed_msb = 1;
		gmxx_prtx_cfg.s.slottime = 0;
		/* Setting from GMX-603 */
		pcsx_miscx_ctl_reg.s.samp_pt = 25;
		cvmx_write_csr(CVMX_GMXX_TXX_SLOT(index, interface), 64);
		cvmx_write_csr(CVMX_GMXX_TXX_BURST(index, interface), 0);
		break;
	case 100:
		gmxx_prtx_cfg.s.speed = 0;
		gmxx_prtx_cfg.s.speed_msb = 0;
		gmxx_prtx_cfg.s.slottime = 0;
		pcsx_miscx_ctl_reg.s.samp_pt = 0x5;
		cvmx_write_csr(CVMX_GMXX_TXX_SLOT(index, interface), 64);
		cvmx_write_csr(CVMX_GMXX_TXX_BURST(index, interface), 0);
		break;
	case 1000:
		gmxx_prtx_cfg.s.speed = 1;
		gmxx_prtx_cfg.s.speed_msb = 0;
		gmxx_prtx_cfg.s.slottime = 1;
		pcsx_miscx_ctl_reg.s.samp_pt = 1;
		cvmx_write_csr(CVMX_GMXX_TXX_SLOT(index, interface), 512);
		cvmx_write_csr(CVMX_GMXX_TXX_BURST(index, interface), 8192);
		break;
	default:
		break;
	}

	/* Write the new misc control for PCS */
	cvmx_write_csr(CVMX_PCSX_MISCX_CTL_REG(index, interface),
		       pcsx_miscx_ctl_reg.u64);

	/* Write the new GMX settings with the port still disabled */
	cvmx_write_csr(CVMX_GMXX_PRTX_CFG(index, interface), gmxx_prtx_cfg.u64);

	/* Read GMX CFG again to make sure the config completed */
	gmxx_prtx_cfg.u64 = cvmx_read_csr(CVMX_GMXX_PRTX_CFG(index, interface));

	/* Restore the enabled / disabled state */
	gmxx_prtx_cfg.s.en = is_enabled;
	cvmx_write_csr(CVMX_GMXX_PRTX_CFG(index, interface), gmxx_prtx_cfg.u64);

	return 0;
}

/**
 * Bring up the SGMII interface to be ready for packet I/O but
 * leave I/O disabled using the GMX override. This function
 * follows the bringup documented in 10.6.3 of the manual.
 *
 * @interface: Interface to bringup
 * @num_ports: Number of ports on the interface
 *
 * Returns Zero on success, negative on failure
 */
static int __cvmx_helper_sgmii_hardware_init(int interface, int num_ports)
{
	int index;

	__cvmx_helper_setup_gmx(interface, num_ports);

	for (index = 0; index < num_ports; index++) {
		int ipd_port = cvmx_helper_get_ipd_port(interface, index);
		__cvmx_helper_sgmii_hardware_init_one_time(interface, index);
		/* Linux kernel driver will call ....link_set with the
		 * proper link state. In the simulator there is no
		 * link state polling and hence it is set from
		 * here.
		 */
		if (cvmx_sysinfo_get()->board_type == CVMX_BOARD_TYPE_SIM)
			__cvmx_helper_sgmii_link_set(ipd_port,
				       __cvmx_helper_sgmii_link_get(ipd_port));
	}

	return 0;
}

int __cvmx_helper_sgmii_enumerate(int interface)
{
	return 4;
}
/**
 * Probe a SGMII interface and determine the number of ports
 * connected to it. The SGMII interface should still be down after
 * this call.
 *
 * @interface: Interface to probe
 *
 * Returns Number of ports on the interface. Zero to disable.
 */
int __cvmx_helper_sgmii_probe(int interface)
{
	union cvmx_gmxx_inf_mode mode;

	/*
	 * Due to errata GMX-700 on CN56XXp1.x and CN52XXp1.x, the
	 * interface needs to be enabled before IPD otherwise per port
	 * backpressure may not work properly
	 */
	mode.u64 = cvmx_read_csr(CVMX_GMXX_INF_MODE(interface));
	mode.s.en = 1;
	cvmx_write_csr(CVMX_GMXX_INF_MODE(interface), mode.u64);
	return __cvmx_helper_sgmii_enumerate(interface);
}

/**
 * Bringup and enable a SGMII interface. After this call packet
 * I/O should be fully functional. This is called with IPD
 * enabled but PKO disabled.
 *
 * @interface: Interface to bring up
 *
 * Returns Zero on success, negative on failure
 */
int __cvmx_helper_sgmii_enable(int interface)
{
	int num_ports = cvmx_helper_ports_on_interface(interface);
	int index;

	__cvmx_helper_sgmii_hardware_init(interface, num_ports);

	for (index = 0; index < num_ports; index++) {
		union cvmx_gmxx_prtx_cfg gmxx_prtx_cfg;
		gmxx_prtx_cfg.u64 =
		    cvmx_read_csr(CVMX_GMXX_PRTX_CFG(index, interface));
		gmxx_prtx_cfg.s.en = 1;
		cvmx_write_csr(CVMX_GMXX_PRTX_CFG(index, interface),
			       gmxx_prtx_cfg.u64);
		__cvmx_interrupt_pcsx_intx_en_reg_enable(index, interface);
	}
	__cvmx_interrupt_pcsxx_int_en_reg_enable(interface);
	__cvmx_interrupt_gmxx_enable(interface);
	return 0;
}

/**
 * Return the link state of an IPD/PKO port as returned by
 * auto negotiation. The result of this function may not match
 * Octeon's link config if auto negotiation has changed since
 * the last call to cvmx_helper_link_set().
 *
 * @ipd_port: IPD/PKO port to query
 *
 * Returns Link state
 */
union cvmx_helper_link_info __cvmx_helper_sgmii_link_get(int ipd_port)
{
	union cvmx_helper_link_info result;
	union cvmx_pcsx_miscx_ctl_reg pcs_misc_ctl_reg;
	int interface = cvmx_helper_get_interface_num(ipd_port);
	int index = cvmx_helper_get_interface_index_num(ipd_port);
	union cvmx_pcsx_mrx_control_reg pcsx_mrx_control_reg;

	result.u64 = 0;

	if (cvmx_sysinfo_get()->board_type == CVMX_BOARD_TYPE_SIM) {
		/* The simulator gives you a simulated 1Gbps full duplex link */
		result.s.link_up = 1;
		result.s.full_duplex = 1;
		result.s.speed = 1000;
		return result;
	}

	pcsx_mrx_control_reg.u64 =
	    cvmx_read_csr(CVMX_PCSX_MRX_CONTROL_REG(index, interface));
	if (pcsx_mrx_control_reg.s.loopbck1) {
		/* Force 1Gbps full duplex link for internal loopback */
		result.s.link_up = 1;
		result.s.full_duplex = 1;
		result.s.speed = 1000;
		return result;
	}

	pcs_misc_ctl_reg.u64 =
	    cvmx_read_csr(CVMX_PCSX_MISCX_CTL_REG(index, interface));
	if (pcs_misc_ctl_reg.s.mode) {
		/* 1000BASE-X */
		/* FIXME */
	} else {
		union cvmx_pcsx_miscx_ctl_reg pcsx_miscx_ctl_reg;
		pcsx_miscx_ctl_reg.u64 =
		    cvmx_read_csr(CVMX_PCSX_MISCX_CTL_REG(index, interface));
		if (pcsx_miscx_ctl_reg.s.mac_phy) {
			/* PHY Mode */
			union cvmx_pcsx_mrx_status_reg pcsx_mrx_status_reg;
			union cvmx_pcsx_anx_results_reg pcsx_anx_results_reg;

			/*
			 * Don't bother continuing if the SERTES low
			 * level link is down
			 */
			pcsx_mrx_status_reg.u64 =
			    cvmx_read_csr(CVMX_PCSX_MRX_STATUS_REG
					  (index, interface));
			if (pcsx_mrx_status_reg.s.lnk_st == 0) {
				if (__cvmx_helper_sgmii_hardware_init_link
				    (interface, index) != 0)
					return result;
			}

			/* Read the autoneg results */
			pcsx_anx_results_reg.u64 =
			    cvmx_read_csr(CVMX_PCSX_ANX_RESULTS_REG
					  (index, interface));
			if (pcsx_anx_results_reg.s.an_cpt) {
				/*
				 * Auto negotiation is complete. Set
				 * status accordingly.
				 */
				result.s.full_duplex =
				    pcsx_anx_results_reg.s.dup;
				result.s.link_up =
				    pcsx_anx_results_reg.s.link_ok;
				switch (pcsx_anx_results_reg.s.spd) {
				case 0:
					result.s.speed = 10;
					break;
				case 1:
					result.s.speed = 100;
					break;
				case 2:
					result.s.speed = 1000;
					break;
				default:
					result.s.speed = 0;
					result.s.link_up = 0;
					break;
				}
			} else {
				/*
				 * Auto negotiation isn't
				 * complete. Return link down.
				 */
				result.s.speed = 0;
				result.s.link_up = 0;
			}
		} else {	/* MAC Mode */

			result = __cvmx_helper_board_link_get(ipd_port);
		}
	}
	return result;
}

/**
 * Configure an IPD/PKO port for the specified link state. This
 * function does not influence auto negotiation at the PHY level.
 * The passed link state must always match the link state returned
 * by cvmx_helper_link_get().
 *
 * @ipd_port:  IPD/PKO port to configure
 * @link_info: The new link state
 *
 * Returns Zero on success, negative on failure
 */
int __cvmx_helper_sgmii_link_set(int ipd_port,
				 union cvmx_helper_link_info link_info)
{
	int interface = cvmx_helper_get_interface_num(ipd_port);
	int index = cvmx_helper_get_interface_index_num(ipd_port);
	__cvmx_helper_sgmii_hardware_init_link(interface, index);
	return __cvmx_helper_sgmii_hardware_init_link_speed(interface, index,
							    link_info);
}
