// SPDX-License-Identifier: GPL-2.0
/* Copyright (c) 2015 - 2022 Beijing WangXun Technology Co., Ltd. */

#include <linux/etherdevice.h>
#include <linux/if_ether.h>
#include <linux/string.h>
#include <linux/iopoll.h>
#include <linux/types.h>
#include <linux/pci.h>

#include "../libwx/wx_type.h"
#include "../libwx/wx_hw.h"
#include "txgbe_type.h"
#include "txgbe_hw.h"

/**
 *  txgbe_disable_sec_tx_path - Stops the transmit data path
 *  @wx: pointer to hardware structure
 *
 *  Stops the transmit data path and waits for the HW to internally empty
 *  the tx security block
 **/
int txgbe_disable_sec_tx_path(struct wx *wx)
{
	int val;

	wr32m(wx, WX_TSC_CTL, WX_TSC_CTL_TX_DIS, WX_TSC_CTL_TX_DIS);
	return read_poll_timeout(rd32, val, val & WX_TSC_ST_SECTX_RDY,
				 1000, 20000, false, wx, WX_TSC_ST);
}

/**
 *  txgbe_enable_sec_tx_path - Enables the transmit data path
 *  @wx: pointer to hardware structure
 *
 *  Enables the transmit data path.
 **/
void txgbe_enable_sec_tx_path(struct wx *wx)
{
	wr32m(wx, WX_TSC_CTL, WX_TSC_CTL_TX_DIS, 0);
	WX_WRITE_FLUSH(wx);
}

/**
 *  txgbe_init_thermal_sensor_thresh - Inits thermal sensor thresholds
 *  @wx: pointer to hardware structure
 *
 *  Inits the thermal sensor thresholds according to the NVM map
 *  and save off the threshold and location values into mac.thermal_sensor_data
 **/
static void txgbe_init_thermal_sensor_thresh(struct wx *wx)
{
	struct wx_thermal_sensor_data *data = &wx->mac.sensor;

	memset(data, 0, sizeof(struct wx_thermal_sensor_data));

	/* Only support thermal sensors attached to SP physical port 0 */
	if (wx->bus.func)
		return;

	wr32(wx, TXGBE_TS_CTL, TXGBE_TS_CTL_EVAL_MD);

	wr32(wx, WX_TS_INT_EN,
	     WX_TS_INT_EN_ALARM_INT_EN | WX_TS_INT_EN_DALARM_INT_EN);
	wr32(wx, WX_TS_EN, WX_TS_EN_ENA);

	data->alarm_thresh = 100;
	wr32(wx, WX_TS_ALARM_THRE, 677);
	data->dalarm_thresh = 90;
	wr32(wx, WX_TS_DALARM_THRE, 614);
}

/**
 *  txgbe_calc_eeprom_checksum - Calculates and returns the checksum
 *  @wx: pointer to hardware structure
 *  @checksum: pointer to cheksum
 *
 *  Returns a negative error code on error
 **/
static int txgbe_calc_eeprom_checksum(struct wx *wx, u16 *checksum)
{
	u16 *eeprom_ptrs = NULL;
	u16 *local_buffer;
	int status;
	u16 i;

	wx_init_eeprom_params(wx);

	eeprom_ptrs = kvmalloc_array(TXGBE_EEPROM_LAST_WORD, sizeof(u16),
				     GFP_KERNEL);
	if (!eeprom_ptrs)
		return -ENOMEM;
	/* Read pointer area */
	status = wx_read_ee_hostif_buffer(wx, 0, TXGBE_EEPROM_LAST_WORD, eeprom_ptrs);
	if (status != 0) {
		wx_err(wx, "Failed to read EEPROM image\n");
		kvfree(eeprom_ptrs);
		return status;
	}
	local_buffer = eeprom_ptrs;

	for (i = 0; i < TXGBE_EEPROM_LAST_WORD; i++)
		if (i != wx->eeprom.sw_region_offset + TXGBE_EEPROM_CHECKSUM)
			*checksum += local_buffer[i];

	if (eeprom_ptrs)
		kvfree(eeprom_ptrs);

	*checksum = TXGBE_EEPROM_SUM - *checksum;

	return 0;
}

/**
 *  txgbe_validate_eeprom_checksum - Validate EEPROM checksum
 *  @wx: pointer to hardware structure
 *  @checksum_val: calculated checksum
 *
 *  Performs checksum calculation and validates the EEPROM checksum.  If the
 *  caller does not need checksum_val, the value can be NULL.
 **/
int txgbe_validate_eeprom_checksum(struct wx *wx, u16 *checksum_val)
{
	u16 read_checksum = 0;
	u16 checksum;
	int status;

	/* Read the first word from the EEPROM. If this times out or fails, do
	 * not continue or we could be in for a very long wait while every
	 * EEPROM read fails
	 */
	status = wx_read_ee_hostif(wx, 0, &checksum);
	if (status) {
		wx_err(wx, "EEPROM read failed\n");
		return status;
	}

	checksum = 0;
	status = txgbe_calc_eeprom_checksum(wx, &checksum);
	if (status != 0)
		return status;

	status = wx_read_ee_hostif(wx, wx->eeprom.sw_region_offset +
				   TXGBE_EEPROM_CHECKSUM, &read_checksum);
	if (status != 0)
		return status;

	/* Verify read checksum from EEPROM is the same as
	 * calculated checksum
	 */
	if (read_checksum != checksum) {
		status = -EIO;
		wx_err(wx, "Invalid EEPROM checksum\n");
	}

	/* If the user cares, return the calculated checksum */
	if (checksum_val)
		*checksum_val = checksum;

	return status;
}

static void txgbe_reset_misc(struct wx *wx)
{
	wx_reset_misc(wx);
	txgbe_init_thermal_sensor_thresh(wx);
}

/**
 *  txgbe_reset_hw - Perform hardware reset
 *  @wx: pointer to wx structure
 *
 *  Resets the hardware by resetting the transmit and receive units, masks
 *  and clears all interrupts, perform a PHY reset, and perform a link (MAC)
 *  reset.
 **/
int txgbe_reset_hw(struct wx *wx)
{
	int status;

	/* Call adapter stop to disable tx/rx and clear interrupts */
	status = wx_stop_adapter(wx);
	if (status != 0)
		return status;

	if (wx->media_type != sp_media_copper) {
		u32 val;

		val = WX_MIS_RST_LAN_RST(wx->bus.func);
		wr32(wx, WX_MIS_RST, val | rd32(wx, WX_MIS_RST));
		WX_WRITE_FLUSH(wx);
		usleep_range(10, 100);
	}

	status = wx_check_flash_load(wx, TXGBE_SPI_ILDR_STATUS_LAN_SW_RST(wx->bus.func));
	if (status != 0)
		return status;

	txgbe_reset_misc(wx);

	wx_clear_hw_cntrs(wx);

	/* Store the permanent mac address */
	wx_get_mac_addr(wx, wx->mac.perm_addr);

	/* Store MAC address from RAR0, clear receive address registers, and
	 * clear the multicast table.  Also reset num_rar_entries to 128,
	 * since we modify this value when programming the SAN MAC address.
	 */
	wx->mac.num_rar_entries = TXGBE_SP_RAR_ENTRIES;
	wx_init_rx_addrs(wx);

	pci_set_master(wx->pdev);

	return 0;
}
