// SPDX-License-Identifier: GPL-2.0
/* Copyright (c)  2018 Intel Corporation */

#include <linux/delay.h>

#include "igc_hw.h"
#include "igc_i225.h"
#include "igc_mac.h"
#include "igc_base.h"
#include "igc.h"

/**
 * igc_reset_hw_base - Reset hardware
 * @hw: pointer to the HW structure
 *
 * This resets the hardware into a known state.  This is a
 * function pointer entry point called by the api module.
 */
static s32 igc_reset_hw_base(struct igc_hw *hw)
{
	s32 ret_val;
	u32 ctrl;

	/* Prevent the PCI-E bus from sticking if there is no TLP connection
	 * on the last TLP read/write transaction when MAC is reset.
	 */
	ret_val = igc_disable_pcie_master(hw);
	if (ret_val)
		hw_dbg("PCI-E Master disable polling has failed\n");

	hw_dbg("Masking off all interrupts\n");
	wr32(IGC_IMC, 0xffffffff);

	wr32(IGC_RCTL, 0);
	wr32(IGC_TCTL, IGC_TCTL_PSP);
	wrfl();

	usleep_range(10000, 20000);

	ctrl = rd32(IGC_CTRL);

	hw_dbg("Issuing a global reset to MAC\n");
	wr32(IGC_CTRL, ctrl | IGC_CTRL_RST);

	ret_val = igc_get_auto_rd_done(hw);
	if (ret_val) {
		/* When auto config read does not complete, do not
		 * return with an error. This can happen in situations
		 * where there is no eeprom and prevents getting link.
		 */
		hw_dbg("Auto Read Done did not complete\n");
	}

	/* Clear any pending interrupt events. */
	wr32(IGC_IMC, 0xffffffff);
	rd32(IGC_ICR);

	return ret_val;
}

/**
 * igc_init_nvm_params_base - Init NVM func ptrs.
 * @hw: pointer to the HW structure
 */
static s32 igc_init_nvm_params_base(struct igc_hw *hw)
{
	struct igc_nvm_info *nvm = &hw->nvm;
	u32 eecd = rd32(IGC_EECD);
	u16 size;

	size = (u16)((eecd & IGC_EECD_SIZE_EX_MASK) >>
		     IGC_EECD_SIZE_EX_SHIFT);

	/* Added to a constant, "size" becomes the left-shift value
	 * for setting word_size.
	 */
	size += NVM_WORD_SIZE_BASE_SHIFT;

	/* Just in case size is out of range, cap it to the largest
	 * EEPROM size supported
	 */
	if (size > 15)
		size = 15;

	nvm->type = igc_nvm_eeprom_spi;
	nvm->word_size = BIT(size);
	nvm->opcode_bits = 8;
	nvm->delay_usec = 1;

	nvm->page_size = eecd & IGC_EECD_ADDR_BITS ? 32 : 8;
	nvm->address_bits = eecd & IGC_EECD_ADDR_BITS ?
			    16 : 8;

	if (nvm->word_size == BIT(15))
		nvm->page_size = 128;

	return 0;
}

/**
 * igc_setup_copper_link_base - Configure copper link settings
 * @hw: pointer to the HW structure
 *
 * Configures the link for auto-neg or forced speed and duplex.  Then we check
 * for link, once link is established calls to configure collision distance
 * and flow control are called.
 */
static s32 igc_setup_copper_link_base(struct igc_hw *hw)
{
	s32  ret_val = 0;
	u32 ctrl;

	ctrl = rd32(IGC_CTRL);
	ctrl |= IGC_CTRL_SLU;
	ctrl &= ~(IGC_CTRL_FRCSPD | IGC_CTRL_FRCDPX);
	wr32(IGC_CTRL, ctrl);

	ret_val = igc_setup_copper_link(hw);

	return ret_val;
}

/**
 * igc_init_mac_params_base - Init MAC func ptrs.
 * @hw: pointer to the HW structure
 */
static s32 igc_init_mac_params_base(struct igc_hw *hw)
{
	struct igc_dev_spec_base *dev_spec = &hw->dev_spec._base;
	struct igc_mac_info *mac = &hw->mac;

	/* Set mta register count */
	mac->mta_reg_count = 128;
	mac->rar_entry_count = IGC_RAR_ENTRIES;

	/* reset */
	mac->ops.reset_hw = igc_reset_hw_base;

	mac->ops.acquire_swfw_sync = igc_acquire_swfw_sync_i225;
	mac->ops.release_swfw_sync = igc_release_swfw_sync_i225;

	/* Allow a single clear of the SW semaphore on I225 */
	if (mac->type == igc_i225)
		dev_spec->clear_semaphore_once = true;

	/* physical interface link setup */
	mac->ops.setup_physical_interface = igc_setup_copper_link_base;

	return 0;
}

/**
 * igc_init_phy_params_base - Init PHY func ptrs.
 * @hw: pointer to the HW structure
 */
static s32 igc_init_phy_params_base(struct igc_hw *hw)
{
	struct igc_phy_info *phy = &hw->phy;
	s32 ret_val = 0;

	phy->autoneg_mask	= AUTONEG_ADVERTISE_SPEED_DEFAULT_2500;
	phy->reset_delay_us	= 100;

	/* set lan id */
	hw->bus.func = (rd32(IGC_STATUS) & IGC_STATUS_FUNC_MASK) >>
			IGC_STATUS_FUNC_SHIFT;

	/* Make sure the PHY is in a good state. Several people have reported
	 * firmware leaving the PHY's page select register set to something
	 * other than the default of zero, which causes the PHY ID read to
	 * access something other than the intended register.
	 */
	ret_val = hw->phy.ops.reset(hw);
	if (ret_val) {
		hw_dbg("Error resetting the PHY\n");
		goto out;
	}

	ret_val = igc_get_phy_id(hw);
	if (ret_val)
		return ret_val;

	igc_check_for_copper_link(hw);

out:
	return ret_val;
}

static s32 igc_get_invariants_base(struct igc_hw *hw)
{
	struct igc_mac_info *mac = &hw->mac;
	s32 ret_val = 0;

	switch (hw->device_id) {
	case IGC_DEV_ID_I225_LM:
	case IGC_DEV_ID_I225_V:
	case IGC_DEV_ID_I225_I:
	case IGC_DEV_ID_I220_V:
	case IGC_DEV_ID_I225_K:
	case IGC_DEV_ID_I225_K2:
	case IGC_DEV_ID_I226_K:
	case IGC_DEV_ID_I225_LMVP:
	case IGC_DEV_ID_I226_LMVP:
	case IGC_DEV_ID_I225_IT:
	case IGC_DEV_ID_I226_LM:
	case IGC_DEV_ID_I226_V:
	case IGC_DEV_ID_I226_IT:
	case IGC_DEV_ID_I221_V:
	case IGC_DEV_ID_I226_BLANK_NVM:
	case IGC_DEV_ID_I225_BLANK_NVM:
		mac->type = igc_i225;
		break;
	default:
		return -IGC_ERR_MAC_INIT;
	}

	hw->phy.media_type = igc_media_type_copper;

	/* mac initialization and operations */
	ret_val = igc_init_mac_params_base(hw);
	if (ret_val)
		goto out;

	/* NVM initialization */
	ret_val = igc_init_nvm_params_base(hw);
	switch (hw->mac.type) {
	case igc_i225:
		ret_val = igc_init_nvm_params_i225(hw);
		break;
	default:
		break;
	}

	/* setup PHY parameters */
	ret_val = igc_init_phy_params_base(hw);
	if (ret_val)
		goto out;

out:
	return ret_val;
}

/**
 * igc_acquire_phy_base - Acquire rights to access PHY
 * @hw: pointer to the HW structure
 *
 * Acquire access rights to the correct PHY.  This is a
 * function pointer entry point called by the api module.
 */
static s32 igc_acquire_phy_base(struct igc_hw *hw)
{
	u16 mask = IGC_SWFW_PHY0_SM;

	return hw->mac.ops.acquire_swfw_sync(hw, mask);
}

/**
 * igc_release_phy_base - Release rights to access PHY
 * @hw: pointer to the HW structure
 *
 * A wrapper to release access rights to the correct PHY.  This is a
 * function pointer entry point called by the api module.
 */
static void igc_release_phy_base(struct igc_hw *hw)
{
	u16 mask = IGC_SWFW_PHY0_SM;

	hw->mac.ops.release_swfw_sync(hw, mask);
}

/**
 * igc_init_hw_base - Initialize hardware
 * @hw: pointer to the HW structure
 *
 * This inits the hardware readying it for operation.
 */
static s32 igc_init_hw_base(struct igc_hw *hw)
{
	struct igc_mac_info *mac = &hw->mac;
	u16 i, rar_count = mac->rar_entry_count;
	s32 ret_val = 0;

	/* Setup the receive address */
	igc_init_rx_addrs(hw, rar_count);

	/* Zero out the Multicast HASH table */
	hw_dbg("Zeroing the MTA\n");
	for (i = 0; i < mac->mta_reg_count; i++)
		array_wr32(IGC_MTA, i, 0);

	/* Zero out the Unicast HASH table */
	hw_dbg("Zeroing the UTA\n");
	for (i = 0; i < mac->uta_reg_count; i++)
		array_wr32(IGC_UTA, i, 0);

	/* Setup link and flow control */
	ret_val = igc_setup_link(hw);

	/* Clear all of the statistics registers (clear on read).  It is
	 * important that we do this after we have tried to establish link
	 * because the symbol error count will increment wildly if there
	 * is no link.
	 */
	igc_clear_hw_cntrs_base(hw);

	return ret_val;
}

/**
 * igc_power_down_phy_copper_base - Remove link during PHY power down
 * @hw: pointer to the HW structure
 *
 * In the case of a PHY power down to save power, or to turn off link during a
 * driver unload, or wake on lan is not enabled, remove the link.
 */
void igc_power_down_phy_copper_base(struct igc_hw *hw)
{
	/* If the management interface is not enabled, then power down */
	if (!(igc_enable_mng_pass_thru(hw) || igc_check_reset_block(hw)))
		igc_power_down_phy_copper(hw);
}

/**
 * igc_rx_fifo_flush_base - Clean rx fifo after Rx enable
 * @hw: pointer to the HW structure
 *
 * After Rx enable, if manageability is enabled then there is likely some
 * bad data at the start of the fifo and possibly in the DMA fifo.  This
 * function clears the fifos and flushes any packets that came in as rx was
 * being enabled.
 */
void igc_rx_fifo_flush_base(struct igc_hw *hw)
{
	u32 rctl, rlpml, rxdctl[4], rfctl, temp_rctl, rx_enabled;
	int i, ms_wait;

	/* disable IPv6 options as per hardware errata */
	rfctl = rd32(IGC_RFCTL);
	rfctl |= IGC_RFCTL_IPV6_EX_DIS;
	wr32(IGC_RFCTL, rfctl);

	if (!(rd32(IGC_MANC) & IGC_MANC_RCV_TCO_EN))
		return;

	/* Disable all Rx queues */
	for (i = 0; i < 4; i++) {
		rxdctl[i] = rd32(IGC_RXDCTL(i));
		wr32(IGC_RXDCTL(i),
		     rxdctl[i] & ~IGC_RXDCTL_QUEUE_ENABLE);
	}
	/* Poll all queues to verify they have shut down */
	for (ms_wait = 0; ms_wait < 10; ms_wait++) {
		usleep_range(1000, 2000);
		rx_enabled = 0;
		for (i = 0; i < 4; i++)
			rx_enabled |= rd32(IGC_RXDCTL(i));
		if (!(rx_enabled & IGC_RXDCTL_QUEUE_ENABLE))
			break;
	}

	if (ms_wait == 10)
		hw_dbg("Queue disable timed out after 10ms\n");

	/* Clear RLPML, RCTL.SBP, RFCTL.LEF, and set RCTL.LPE so that all
	 * incoming packets are rejected.  Set enable and wait 2ms so that
	 * any packet that was coming in as RCTL.EN was set is flushed
	 */
	wr32(IGC_RFCTL, rfctl & ~IGC_RFCTL_LEF);

	rlpml = rd32(IGC_RLPML);
	wr32(IGC_RLPML, 0);

	rctl = rd32(IGC_RCTL);
	temp_rctl = rctl & ~(IGC_RCTL_EN | IGC_RCTL_SBP);
	temp_rctl |= IGC_RCTL_LPE;

	wr32(IGC_RCTL, temp_rctl);
	wr32(IGC_RCTL, temp_rctl | IGC_RCTL_EN);
	wrfl();
	usleep_range(2000, 3000);

	/* Enable Rx queues that were previously enabled and restore our
	 * previous state
	 */
	for (i = 0; i < 4; i++)
		wr32(IGC_RXDCTL(i), rxdctl[i]);
	wr32(IGC_RCTL, rctl);
	wrfl();

	wr32(IGC_RLPML, rlpml);
	wr32(IGC_RFCTL, rfctl);

	/* Flush receive errors generated by workaround */
	rd32(IGC_ROC);
	rd32(IGC_RNBC);
	rd32(IGC_MPC);
}

static struct igc_mac_operations igc_mac_ops_base = {
	.init_hw		= igc_init_hw_base,
	.check_for_link		= igc_check_for_copper_link,
	.rar_set		= igc_rar_set,
	.read_mac_addr		= igc_read_mac_addr,
	.get_speed_and_duplex	= igc_get_speed_and_duplex_copper,
};

static const struct igc_phy_operations igc_phy_ops_base = {
	.acquire		= igc_acquire_phy_base,
	.release		= igc_release_phy_base,
	.reset			= igc_phy_hw_reset,
	.read_reg		= igc_read_phy_reg_gpy,
	.write_reg		= igc_write_phy_reg_gpy,
};

const struct igc_info igc_base_info = {
	.get_invariants		= igc_get_invariants_base,
	.mac_ops		= &igc_mac_ops_base,
	.phy_ops		= &igc_phy_ops_base,
};
