/* Intel Ethernet Switch Host Interface Driver
 * Copyright(c) 2013 - 2014 Intel Corporation.
 *
 * This program is free software; you can redistribute it and/or modify it
 * under the terms and conditions of the GNU General Public License,
 * version 2, as published by the Free Software Foundation.
 *
 * This program is distributed in the hope 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.
 *
 * The full GNU General Public License is included in this distribution in
 * the file called "COPYING".
 *
 * Contact Information:
 * e1000-devel Mailing List <e1000-devel@lists.sourceforge.net>
 * Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
 */

#include "fm10k_common.h"

/**
 *  fm10k_get_bus_info_generic - Generic set PCI bus info
 *  @hw: pointer to hardware structure
 *
 *  Gets the PCI bus info (speed, width, type) then calls helper function to
 *  store this data within the fm10k_hw structure.
 **/
s32 fm10k_get_bus_info_generic(struct fm10k_hw *hw)
{
	u16 link_cap, link_status, device_cap, device_control;

	/* Get the maximum link width and speed from PCIe config space */
	link_cap = fm10k_read_pci_cfg_word(hw, FM10K_PCIE_LINK_CAP);

	switch (link_cap & FM10K_PCIE_LINK_WIDTH) {
	case FM10K_PCIE_LINK_WIDTH_1:
		hw->bus_caps.width = fm10k_bus_width_pcie_x1;
		break;
	case FM10K_PCIE_LINK_WIDTH_2:
		hw->bus_caps.width = fm10k_bus_width_pcie_x2;
		break;
	case FM10K_PCIE_LINK_WIDTH_4:
		hw->bus_caps.width = fm10k_bus_width_pcie_x4;
		break;
	case FM10K_PCIE_LINK_WIDTH_8:
		hw->bus_caps.width = fm10k_bus_width_pcie_x8;
		break;
	default:
		hw->bus_caps.width = fm10k_bus_width_unknown;
		break;
	}

	switch (link_cap & FM10K_PCIE_LINK_SPEED) {
	case FM10K_PCIE_LINK_SPEED_2500:
		hw->bus_caps.speed = fm10k_bus_speed_2500;
		break;
	case FM10K_PCIE_LINK_SPEED_5000:
		hw->bus_caps.speed = fm10k_bus_speed_5000;
		break;
	case FM10K_PCIE_LINK_SPEED_8000:
		hw->bus_caps.speed = fm10k_bus_speed_8000;
		break;
	default:
		hw->bus_caps.speed = fm10k_bus_speed_unknown;
		break;
	}

	/* Get the PCIe maximum payload size for the PCIe function */
	device_cap = fm10k_read_pci_cfg_word(hw, FM10K_PCIE_DEV_CAP);

	switch (device_cap & FM10K_PCIE_DEV_CAP_PAYLOAD) {
	case FM10K_PCIE_DEV_CAP_PAYLOAD_128:
		hw->bus_caps.payload = fm10k_bus_payload_128;
		break;
	case FM10K_PCIE_DEV_CAP_PAYLOAD_256:
		hw->bus_caps.payload = fm10k_bus_payload_256;
		break;
	case FM10K_PCIE_DEV_CAP_PAYLOAD_512:
		hw->bus_caps.payload = fm10k_bus_payload_512;
		break;
	default:
		hw->bus_caps.payload = fm10k_bus_payload_unknown;
		break;
	}

	/* Get the negotiated link width and speed from PCIe config space */
	link_status = fm10k_read_pci_cfg_word(hw, FM10K_PCIE_LINK_STATUS);

	switch (link_status & FM10K_PCIE_LINK_WIDTH) {
	case FM10K_PCIE_LINK_WIDTH_1:
		hw->bus.width = fm10k_bus_width_pcie_x1;
		break;
	case FM10K_PCIE_LINK_WIDTH_2:
		hw->bus.width = fm10k_bus_width_pcie_x2;
		break;
	case FM10K_PCIE_LINK_WIDTH_4:
		hw->bus.width = fm10k_bus_width_pcie_x4;
		break;
	case FM10K_PCIE_LINK_WIDTH_8:
		hw->bus.width = fm10k_bus_width_pcie_x8;
		break;
	default:
		hw->bus.width = fm10k_bus_width_unknown;
		break;
	}

	switch (link_status & FM10K_PCIE_LINK_SPEED) {
	case FM10K_PCIE_LINK_SPEED_2500:
		hw->bus.speed = fm10k_bus_speed_2500;
		break;
	case FM10K_PCIE_LINK_SPEED_5000:
		hw->bus.speed = fm10k_bus_speed_5000;
		break;
	case FM10K_PCIE_LINK_SPEED_8000:
		hw->bus.speed = fm10k_bus_speed_8000;
		break;
	default:
		hw->bus.speed = fm10k_bus_speed_unknown;
		break;
	}

	/* Get the negotiated PCIe maximum payload size for the PCIe function */
	device_control = fm10k_read_pci_cfg_word(hw, FM10K_PCIE_DEV_CTRL);

	switch (device_control & FM10K_PCIE_DEV_CTRL_PAYLOAD) {
	case FM10K_PCIE_DEV_CTRL_PAYLOAD_128:
		hw->bus.payload = fm10k_bus_payload_128;
		break;
	case FM10K_PCIE_DEV_CTRL_PAYLOAD_256:
		hw->bus.payload = fm10k_bus_payload_256;
		break;
	case FM10K_PCIE_DEV_CTRL_PAYLOAD_512:
		hw->bus.payload = fm10k_bus_payload_512;
		break;
	default:
		hw->bus.payload = fm10k_bus_payload_unknown;
		break;
	}

	return 0;
}

static u16 fm10k_get_pcie_msix_count_generic(struct fm10k_hw *hw)
{
	u16 msix_count;

	/* read in value from MSI-X capability register */
	msix_count = fm10k_read_pci_cfg_word(hw, FM10K_PCI_MSIX_MSG_CTRL);
	msix_count &= FM10K_PCI_MSIX_MSG_CTRL_TBL_SZ_MASK;

	/* MSI-X count is zero-based in HW */
	msix_count++;

	if (msix_count > FM10K_MAX_MSIX_VECTORS)
		msix_count = FM10K_MAX_MSIX_VECTORS;

	return msix_count;
}

/**
 *  fm10k_get_invariants_generic - Inits constant values
 *  @hw: pointer to the hardware structure
 *
 *  Initialize the common invariants for the device.
 **/
s32 fm10k_get_invariants_generic(struct fm10k_hw *hw)
{
	struct fm10k_mac_info *mac = &hw->mac;

	/* initialize GLORT state to avoid any false hits */
	mac->dglort_map = FM10K_DGLORTMAP_NONE;

	/* record maximum number of MSI-X vectors */
	mac->max_msix_vectors = fm10k_get_pcie_msix_count_generic(hw);

	return 0;
}

/**
 *  fm10k_start_hw_generic - Prepare hardware for Tx/Rx
 *  @hw: pointer to hardware structure
 *
 *  This function sets the Tx ready flag to indicate that the Tx path has
 *  been initialized.
 **/
s32 fm10k_start_hw_generic(struct fm10k_hw *hw)
{
	/* set flag indicating we are beginning Tx */
	hw->mac.tx_ready = true;

	return 0;
}

/**
 *  fm10k_disable_queues_generic - Stop Tx/Rx queues
 *  @hw: pointer to hardware structure
 *  @q_cnt: number of queues to be disabled
 *
 **/
s32 fm10k_disable_queues_generic(struct fm10k_hw *hw, u16 q_cnt)
{
	u32 reg;
	u16 i, time;

	/* clear tx_ready to prevent any false hits for reset */
	hw->mac.tx_ready = false;

	/* clear the enable bit for all rings */
	for (i = 0; i < q_cnt; i++) {
		reg = fm10k_read_reg(hw, FM10K_TXDCTL(i));
		fm10k_write_reg(hw, FM10K_TXDCTL(i),
				reg & ~FM10K_TXDCTL_ENABLE);
		reg = fm10k_read_reg(hw, FM10K_RXQCTL(i));
		fm10k_write_reg(hw, FM10K_RXQCTL(i),
				reg & ~FM10K_RXQCTL_ENABLE);
	}

	fm10k_write_flush(hw);
	udelay(1);

	/* loop through all queues to verify that they are all disabled */
	for (i = 0, time = FM10K_QUEUE_DISABLE_TIMEOUT; time;) {
		/* if we are at end of rings all rings are disabled */
		if (i == q_cnt)
			return 0;

		/* if queue enables cleared, then move to next ring pair */
		reg = fm10k_read_reg(hw, FM10K_TXDCTL(i));
		if (!~reg || !(reg & FM10K_TXDCTL_ENABLE)) {
			reg = fm10k_read_reg(hw, FM10K_RXQCTL(i));
			if (!~reg || !(reg & FM10K_RXQCTL_ENABLE)) {
				i++;
				continue;
			}
		}

		/* decrement time and wait 1 usec */
		time--;
		if (time)
			udelay(1);
	}

	return FM10K_ERR_REQUESTS_PENDING;
}

/**
 *  fm10k_stop_hw_generic - Stop Tx/Rx units
 *  @hw: pointer to hardware structure
 *
 **/
s32 fm10k_stop_hw_generic(struct fm10k_hw *hw)
{
	return fm10k_disable_queues_generic(hw, hw->mac.max_queues);
}

/**
 *  fm10k_read_hw_stats_32b - Reads value of 32-bit registers
 *  @hw: pointer to the hardware structure
 *  @addr: address of register containing a 32-bit value
 *
 *  Function reads the content of the register and returns the delta
 *  between the base and the current value.
 *  **/
u32 fm10k_read_hw_stats_32b(struct fm10k_hw *hw, u32 addr,
			    struct fm10k_hw_stat *stat)
{
	u32 delta = fm10k_read_reg(hw, addr) - stat->base_l;

	if (FM10K_REMOVED(hw->hw_addr))
		stat->base_h = 0;

	return delta;
}

/**
 *  fm10k_read_hw_stats_48b - Reads value of 48-bit registers
 *  @hw: pointer to the hardware structure
 *  @addr: address of register containing the lower 32-bit value
 *
 *  Function reads the content of 2 registers, combined to represent a 48-bit
 *  statistical value. Extra processing is required to handle overflowing.
 *  Finally, a delta value is returned representing the difference between the
 *  values stored in registers and values stored in the statistic counters.
 *  **/
static u64 fm10k_read_hw_stats_48b(struct fm10k_hw *hw, u32 addr,
				   struct fm10k_hw_stat *stat)
{
	u32 count_l;
	u32 count_h;
	u32 count_tmp;
	u64 delta;

	count_h = fm10k_read_reg(hw, addr + 1);

	/* Check for overflow */
	do {
		count_tmp = count_h;
		count_l = fm10k_read_reg(hw, addr);
		count_h = fm10k_read_reg(hw, addr + 1);
	} while (count_h != count_tmp);

	delta = ((u64)(count_h - stat->base_h) << 32) + count_l;
	delta -= stat->base_l;

	return delta & FM10K_48_BIT_MASK;
}

/**
 *  fm10k_update_hw_base_48b - Updates 48-bit statistic base value
 *  @stat: pointer to the hardware statistic structure
 *  @delta: value to be updated into the hardware statistic structure
 *
 *  Function receives a value and determines if an update is required based on
 *  a delta calculation. Only the base value will be updated.
 **/
static void fm10k_update_hw_base_48b(struct fm10k_hw_stat *stat, u64 delta)
{
	if (!delta)
		return;

	/* update lower 32 bits */
	delta += stat->base_l;
	stat->base_l = (u32)delta;

	/* update upper 32 bits */
	stat->base_h += (u32)(delta >> 32);
}

/**
 *  fm10k_update_hw_stats_tx_q - Updates TX queue statistics counters
 *  @hw: pointer to the hardware structure
 *  @q: pointer to the ring of hardware statistics queue
 *  @idx: index pointing to the start of the ring iteration
 *
 *  Function updates the TX queue statistics counters that are related to the
 *  hardware.
 **/
static void fm10k_update_hw_stats_tx_q(struct fm10k_hw *hw,
				       struct fm10k_hw_stats_q *q,
				       u32 idx)
{
	u32 id_tx, id_tx_prev, tx_packets;
	u64 tx_bytes = 0;

	/* Retrieve TX Owner Data */
	id_tx = fm10k_read_reg(hw, FM10K_TXQCTL(idx));

	/* Process TX Ring */
	do {
		tx_packets = fm10k_read_hw_stats_32b(hw, FM10K_QPTC(idx),
						     &q->tx_packets);

		if (tx_packets)
			tx_bytes = fm10k_read_hw_stats_48b(hw,
							   FM10K_QBTC_L(idx),
							   &q->tx_bytes);

		/* Re-Check Owner Data */
		id_tx_prev = id_tx;
		id_tx = fm10k_read_reg(hw, FM10K_TXQCTL(idx));
	} while ((id_tx ^ id_tx_prev) & FM10K_TXQCTL_ID_MASK);

	/* drop non-ID bits and set VALID ID bit */
	id_tx &= FM10K_TXQCTL_ID_MASK;
	id_tx |= FM10K_STAT_VALID;

	/* update packet counts */
	if (q->tx_stats_idx == id_tx) {
		q->tx_packets.count += tx_packets;
		q->tx_bytes.count += tx_bytes;
	}

	/* update bases and record ID */
	fm10k_update_hw_base_32b(&q->tx_packets, tx_packets);
	fm10k_update_hw_base_48b(&q->tx_bytes, tx_bytes);

	q->tx_stats_idx = id_tx;
}

/**
 *  fm10k_update_hw_stats_rx_q - Updates RX queue statistics counters
 *  @hw: pointer to the hardware structure
 *  @q: pointer to the ring of hardware statistics queue
 *  @idx: index pointing to the start of the ring iteration
 *
 *  Function updates the RX queue statistics counters that are related to the
 *  hardware.
 **/
static void fm10k_update_hw_stats_rx_q(struct fm10k_hw *hw,
				       struct fm10k_hw_stats_q *q,
				       u32 idx)
{
	u32 id_rx, id_rx_prev, rx_packets, rx_drops;
	u64 rx_bytes = 0;

	/* Retrieve RX Owner Data */
	id_rx = fm10k_read_reg(hw, FM10K_RXQCTL(idx));

	/* Process RX Ring */
	do {
		rx_drops = fm10k_read_hw_stats_32b(hw, FM10K_QPRDC(idx),
						   &q->rx_drops);

		rx_packets = fm10k_read_hw_stats_32b(hw, FM10K_QPRC(idx),
						     &q->rx_packets);

		if (rx_packets)
			rx_bytes = fm10k_read_hw_stats_48b(hw,
							   FM10K_QBRC_L(idx),
							   &q->rx_bytes);

		/* Re-Check Owner Data */
		id_rx_prev = id_rx;
		id_rx = fm10k_read_reg(hw, FM10K_RXQCTL(idx));
	} while ((id_rx ^ id_rx_prev) & FM10K_RXQCTL_ID_MASK);

	/* drop non-ID bits and set VALID ID bit */
	id_rx &= FM10K_RXQCTL_ID_MASK;
	id_rx |= FM10K_STAT_VALID;

	/* update packet counts */
	if (q->rx_stats_idx == id_rx) {
		q->rx_drops.count += rx_drops;
		q->rx_packets.count += rx_packets;
		q->rx_bytes.count += rx_bytes;
	}

	/* update bases and record ID */
	fm10k_update_hw_base_32b(&q->rx_drops, rx_drops);
	fm10k_update_hw_base_32b(&q->rx_packets, rx_packets);
	fm10k_update_hw_base_48b(&q->rx_bytes, rx_bytes);

	q->rx_stats_idx = id_rx;
}

/**
 *  fm10k_update_hw_stats_q - Updates queue statistics counters
 *  @hw: pointer to the hardware structure
 *  @q: pointer to the ring of hardware statistics queue
 *  @idx: index pointing to the start of the ring iteration
 *  @count: number of queues to iterate over
 *
 *  Function updates the queue statistics counters that are related to the
 *  hardware.
 **/
void fm10k_update_hw_stats_q(struct fm10k_hw *hw, struct fm10k_hw_stats_q *q,
			     u32 idx, u32 count)
{
	u32 i;

	for (i = 0; i < count; i++, idx++, q++) {
		fm10k_update_hw_stats_tx_q(hw, q, idx);
		fm10k_update_hw_stats_rx_q(hw, q, idx);
	}
}

/**
 *  fm10k_unbind_hw_stats_q - Unbind the queue counters from their queues
 *  @hw: pointer to the hardware structure
 *  @q: pointer to the ring of hardware statistics queue
 *  @idx: index pointing to the start of the ring iteration
 *  @count: number of queues to iterate over
 *
 *  Function invalidates the index values for the queues so any updates that
 *  may have happened are ignored and the base for the queue stats is reset.
 **/
void fm10k_unbind_hw_stats_q(struct fm10k_hw_stats_q *q, u32 idx, u32 count)
{
	u32 i;

	for (i = 0; i < count; i++, idx++, q++) {
		q->rx_stats_idx = 0;
		q->tx_stats_idx = 0;
	}
}

/**
 *  fm10k_get_host_state_generic - Returns the state of the host
 *  @hw: pointer to hardware structure
 *  @host_ready: pointer to boolean value that will record host state
 *
 *  This function will check the health of the mailbox and Tx queue 0
 *  in order to determine if we should report that the link is up or not.
 **/
s32 fm10k_get_host_state_generic(struct fm10k_hw *hw, bool *host_ready)
{
	struct fm10k_mbx_info *mbx = &hw->mbx;
	struct fm10k_mac_info *mac = &hw->mac;
	s32 ret_val = 0;
	u32 txdctl = fm10k_read_reg(hw, FM10K_TXDCTL(0));

	/* process upstream mailbox in case interrupts were disabled */
	mbx->ops.process(hw, mbx);

	/* If Tx is no longer enabled link should come down */
	if (!(~txdctl) || !(txdctl & FM10K_TXDCTL_ENABLE))
		mac->get_host_state = true;

	/* exit if not checking for link, or link cannot be changed */
	if (!mac->get_host_state || !(~txdctl))
		goto out;

	/* if we somehow dropped the Tx enable we should reset */
	if (hw->mac.tx_ready && !(txdctl & FM10K_TXDCTL_ENABLE)) {
		ret_val = FM10K_ERR_RESET_REQUESTED;
		goto out;
	}

	/* if Mailbox timed out we should request reset */
	if (!mbx->timeout) {
		ret_val = FM10K_ERR_RESET_REQUESTED;
		goto out;
	}

	/* verify Mailbox is still valid */
	if (!mbx->ops.tx_ready(mbx, FM10K_VFMBX_MSG_MTU))
		goto out;

	/* interface cannot receive traffic without logical ports */
	if (mac->dglort_map == FM10K_DGLORTMAP_NONE)
		goto out;

	/* if we passed all the tests above then the switch is ready and we no
	 * longer need to check for link
	 */
	mac->get_host_state = false;

out:
	*host_ready = !mac->get_host_state;
	return ret_val;
}
