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

#include <linux/etherdevice.h>
#include <linux/netdevice.h>
#include <linux/if_ether.h>
#include <linux/if_vlan.h>
#include <linux/iopoll.h>
#include <linux/pci.h>

#include "wx_type.h"
#include "wx_lib.h"
#include "wx_hw.h"

static int wx_phy_read_reg_mdi(struct mii_bus *bus, int phy_addr, int devnum, int regnum)
{
	struct wx *wx = bus->priv;
	u32 command, val;
	int ret;

	/* setup and write the address cycle command */
	command = WX_MSCA_RA(regnum) |
		  WX_MSCA_PA(phy_addr) |
		  WX_MSCA_DA(devnum);
	wr32(wx, WX_MSCA, command);

	command = WX_MSCC_CMD(WX_MSCA_CMD_READ) | WX_MSCC_BUSY;
	if (wx->mac.type == wx_mac_em)
		command |= WX_MDIO_CLK(6);
	wr32(wx, WX_MSCC, command);

	/* wait to complete */
	ret = read_poll_timeout(rd32, val, !(val & WX_MSCC_BUSY), 1000,
				100000, false, wx, WX_MSCC);
	if (ret) {
		wx_err(wx, "Mdio read c22 command did not complete.\n");
		return ret;
	}

	return (u16)rd32(wx, WX_MSCC);
}

static int wx_phy_write_reg_mdi(struct mii_bus *bus, int phy_addr,
				int devnum, int regnum, u16 value)
{
	struct wx *wx = bus->priv;
	u32 command, val;
	int ret;

	/* setup and write the address cycle command */
	command = WX_MSCA_RA(regnum) |
		  WX_MSCA_PA(phy_addr) |
		  WX_MSCA_DA(devnum);
	wr32(wx, WX_MSCA, command);

	command = value | WX_MSCC_CMD(WX_MSCA_CMD_WRITE) | WX_MSCC_BUSY;
	if (wx->mac.type == wx_mac_em)
		command |= WX_MDIO_CLK(6);
	wr32(wx, WX_MSCC, command);

	/* wait to complete */
	ret = read_poll_timeout(rd32, val, !(val & WX_MSCC_BUSY), 1000,
				100000, false, wx, WX_MSCC);
	if (ret)
		wx_err(wx, "Mdio write c22 command did not complete.\n");

	return ret;
}

int wx_phy_read_reg_mdi_c22(struct mii_bus *bus, int phy_addr, int regnum)
{
	struct wx *wx = bus->priv;

	wr32(wx, WX_MDIO_CLAUSE_SELECT, 0xF);
	return wx_phy_read_reg_mdi(bus, phy_addr, 0, regnum);
}
EXPORT_SYMBOL(wx_phy_read_reg_mdi_c22);

int wx_phy_write_reg_mdi_c22(struct mii_bus *bus, int phy_addr, int regnum, u16 value)
{
	struct wx *wx = bus->priv;

	wr32(wx, WX_MDIO_CLAUSE_SELECT, 0xF);
	return wx_phy_write_reg_mdi(bus, phy_addr, 0, regnum, value);
}
EXPORT_SYMBOL(wx_phy_write_reg_mdi_c22);

int wx_phy_read_reg_mdi_c45(struct mii_bus *bus, int phy_addr, int devnum, int regnum)
{
	struct wx *wx = bus->priv;

	wr32(wx, WX_MDIO_CLAUSE_SELECT, 0);
	return wx_phy_read_reg_mdi(bus, phy_addr, devnum, regnum);
}
EXPORT_SYMBOL(wx_phy_read_reg_mdi_c45);

int wx_phy_write_reg_mdi_c45(struct mii_bus *bus, int phy_addr,
			     int devnum, int regnum, u16 value)
{
	struct wx *wx = bus->priv;

	wr32(wx, WX_MDIO_CLAUSE_SELECT, 0);
	return wx_phy_write_reg_mdi(bus, phy_addr, devnum, regnum, value);
}
EXPORT_SYMBOL(wx_phy_write_reg_mdi_c45);

static void wx_intr_disable(struct wx *wx, u64 qmask)
{
	u32 mask;

	mask = (qmask & U32_MAX);
	if (mask)
		wr32(wx, WX_PX_IMS(0), mask);

	if (wx->mac.type == wx_mac_sp) {
		mask = (qmask >> 32);
		if (mask)
			wr32(wx, WX_PX_IMS(1), mask);
	}
}

void wx_intr_enable(struct wx *wx, u64 qmask)
{
	u32 mask;

	mask = (qmask & U32_MAX);
	if (mask)
		wr32(wx, WX_PX_IMC(0), mask);
	if (wx->mac.type == wx_mac_sp) {
		mask = (qmask >> 32);
		if (mask)
			wr32(wx, WX_PX_IMC(1), mask);
	}
}
EXPORT_SYMBOL(wx_intr_enable);

/**
 * wx_irq_disable - Mask off interrupt generation on the NIC
 * @wx: board private structure
 **/
void wx_irq_disable(struct wx *wx)
{
	struct pci_dev *pdev = wx->pdev;

	wr32(wx, WX_PX_MISC_IEN, 0);
	wx_intr_disable(wx, WX_INTR_ALL);

	if (pdev->msix_enabled) {
		int vector;

		for (vector = 0; vector < wx->num_q_vectors; vector++)
			synchronize_irq(wx->msix_q_entries[vector].vector);

		synchronize_irq(wx->msix_entry->vector);
	} else {
		synchronize_irq(pdev->irq);
	}
}
EXPORT_SYMBOL(wx_irq_disable);

/* cmd_addr is used for some special command:
 * 1. to be sector address, when implemented erase sector command
 * 2. to be flash address when implemented read, write flash address
 */
static int wx_fmgr_cmd_op(struct wx *wx, u32 cmd, u32 cmd_addr)
{
	u32 cmd_val = 0, val = 0;

	cmd_val = WX_SPI_CMD_CMD(cmd) |
		  WX_SPI_CMD_CLK(WX_SPI_CLK_DIV) |
		  cmd_addr;
	wr32(wx, WX_SPI_CMD, cmd_val);

	return read_poll_timeout(rd32, val, (val & 0x1), 10, 100000,
				 false, wx, WX_SPI_STATUS);
}

static int wx_flash_read_dword(struct wx *wx, u32 addr, u32 *data)
{
	int ret = 0;

	ret = wx_fmgr_cmd_op(wx, WX_SPI_CMD_READ_DWORD, addr);
	if (ret < 0)
		return ret;

	*data = rd32(wx, WX_SPI_DATA);

	return ret;
}

int wx_check_flash_load(struct wx *hw, u32 check_bit)
{
	u32 reg = 0;
	int err = 0;

	/* if there's flash existing */
	if (!(rd32(hw, WX_SPI_STATUS) &
	      WX_SPI_STATUS_FLASH_BYPASS)) {
		/* wait hw load flash done */
		err = read_poll_timeout(rd32, reg, !(reg & check_bit), 20000, 2000000,
					false, hw, WX_SPI_ILDR_STATUS);
		if (err < 0)
			wx_err(hw, "Check flash load timeout.\n");
	}

	return err;
}
EXPORT_SYMBOL(wx_check_flash_load);

void wx_control_hw(struct wx *wx, bool drv)
{
	/* True : Let firmware know the driver has taken over
	 * False : Let firmware take over control of hw
	 */
	wr32m(wx, WX_CFG_PORT_CTL, WX_CFG_PORT_CTL_DRV_LOAD,
	      drv ? WX_CFG_PORT_CTL_DRV_LOAD : 0);
}
EXPORT_SYMBOL(wx_control_hw);

/**
 * wx_mng_present - returns 0 when management capability is present
 * @wx: pointer to hardware structure
 */
int wx_mng_present(struct wx *wx)
{
	u32 fwsm;

	fwsm = rd32(wx, WX_MIS_ST);
	if (fwsm & WX_MIS_ST_MNG_INIT_DN)
		return 0;
	else
		return -EACCES;
}
EXPORT_SYMBOL(wx_mng_present);

/* Software lock to be held while software semaphore is being accessed. */
static DEFINE_MUTEX(wx_sw_sync_lock);

/**
 *  wx_release_sw_sync - Release SW semaphore
 *  @wx: pointer to hardware structure
 *  @mask: Mask to specify which semaphore to release
 *
 *  Releases the SW semaphore for the specified
 *  function (CSR, PHY0, PHY1, EEPROM, Flash)
 **/
static void wx_release_sw_sync(struct wx *wx, u32 mask)
{
	mutex_lock(&wx_sw_sync_lock);
	wr32m(wx, WX_MNG_SWFW_SYNC, mask, 0);
	mutex_unlock(&wx_sw_sync_lock);
}

/**
 *  wx_acquire_sw_sync - Acquire SW semaphore
 *  @wx: pointer to hardware structure
 *  @mask: Mask to specify which semaphore to acquire
 *
 *  Acquires the SW semaphore for the specified
 *  function (CSR, PHY0, PHY1, EEPROM, Flash)
 **/
static int wx_acquire_sw_sync(struct wx *wx, u32 mask)
{
	u32 sem = 0;
	int ret = 0;

	mutex_lock(&wx_sw_sync_lock);
	ret = read_poll_timeout(rd32, sem, !(sem & mask),
				5000, 2000000, false, wx, WX_MNG_SWFW_SYNC);
	if (!ret) {
		sem |= mask;
		wr32(wx, WX_MNG_SWFW_SYNC, sem);
	} else {
		wx_err(wx, "SW Semaphore not granted: 0x%x.\n", sem);
	}
	mutex_unlock(&wx_sw_sync_lock);

	return ret;
}

/**
 *  wx_host_interface_command - Issue command to manageability block
 *  @wx: pointer to the HW structure
 *  @buffer: contains the command to write and where the return status will
 *   be placed
 *  @length: length of buffer, must be multiple of 4 bytes
 *  @timeout: time in ms to wait for command completion
 *  @return_data: read and return data from the buffer (true) or not (false)
 *   Needed because FW structures are big endian and decoding of
 *   these fields can be 8 bit or 16 bit based on command. Decoding
 *   is not easily understood without making a table of commands.
 *   So we will leave this up to the caller to read back the data
 *   in these cases.
 **/
int wx_host_interface_command(struct wx *wx, u32 *buffer,
			      u32 length, u32 timeout, bool return_data)
{
	u32 hdr_size = sizeof(struct wx_hic_hdr);
	u32 hicr, i, bi, buf[64] = {};
	int status = 0;
	u32 dword_len;
	u16 buf_len;

	if (length == 0 || length > WX_HI_MAX_BLOCK_BYTE_LENGTH) {
		wx_err(wx, "Buffer length failure buffersize=%d.\n", length);
		return -EINVAL;
	}

	status = wx_acquire_sw_sync(wx, WX_MNG_SWFW_SYNC_SW_MB);
	if (status != 0)
		return status;

	/* Calculate length in DWORDs. We must be DWORD aligned */
	if ((length % (sizeof(u32))) != 0) {
		wx_err(wx, "Buffer length failure, not aligned to dword");
		status = -EINVAL;
		goto rel_out;
	}

	dword_len = length >> 2;

	/* The device driver writes the relevant command block
	 * into the ram area.
	 */
	for (i = 0; i < dword_len; i++) {
		wr32a(wx, WX_MNG_MBOX, i, (__force u32)cpu_to_le32(buffer[i]));
		/* write flush */
		buf[i] = rd32a(wx, WX_MNG_MBOX, i);
	}
	/* Setting this bit tells the ARC that a new command is pending. */
	wr32m(wx, WX_MNG_MBOX_CTL,
	      WX_MNG_MBOX_CTL_SWRDY, WX_MNG_MBOX_CTL_SWRDY);

	status = read_poll_timeout(rd32, hicr, hicr & WX_MNG_MBOX_CTL_FWRDY, 1000,
				   timeout * 1000, false, wx, WX_MNG_MBOX_CTL);

	/* Check command completion */
	if (status) {
		wx_dbg(wx, "Command has failed with no status valid.\n");

		buf[0] = rd32(wx, WX_MNG_MBOX);
		if ((buffer[0] & 0xff) != (~buf[0] >> 24)) {
			status = -EINVAL;
			goto rel_out;
		}
		if ((buf[0] & 0xff0000) >> 16 == 0x80) {
			wx_dbg(wx, "It's unknown cmd.\n");
			status = -EINVAL;
			goto rel_out;
		}

		wx_dbg(wx, "write value:\n");
		for (i = 0; i < dword_len; i++)
			wx_dbg(wx, "%x ", buffer[i]);
		wx_dbg(wx, "read value:\n");
		for (i = 0; i < dword_len; i++)
			wx_dbg(wx, "%x ", buf[i]);
	}

	if (!return_data)
		goto rel_out;

	/* Calculate length in DWORDs */
	dword_len = hdr_size >> 2;

	/* first pull in the header so we know the buffer length */
	for (bi = 0; bi < dword_len; bi++) {
		buffer[bi] = rd32a(wx, WX_MNG_MBOX, bi);
		le32_to_cpus(&buffer[bi]);
	}

	/* If there is any thing in data position pull it in */
	buf_len = ((struct wx_hic_hdr *)buffer)->buf_len;
	if (buf_len == 0)
		goto rel_out;

	if (length < buf_len + hdr_size) {
		wx_err(wx, "Buffer not large enough for reply message.\n");
		status = -EFAULT;
		goto rel_out;
	}

	/* Calculate length in DWORDs, add 3 for odd lengths */
	dword_len = (buf_len + 3) >> 2;

	/* Pull in the rest of the buffer (bi is where we left off) */
	for (; bi <= dword_len; bi++) {
		buffer[bi] = rd32a(wx, WX_MNG_MBOX, bi);
		le32_to_cpus(&buffer[bi]);
	}

rel_out:
	wx_release_sw_sync(wx, WX_MNG_SWFW_SYNC_SW_MB);
	return status;
}
EXPORT_SYMBOL(wx_host_interface_command);

/**
 *  wx_read_ee_hostif_data - Read EEPROM word using a host interface cmd
 *  assuming that the semaphore is already obtained.
 *  @wx: pointer to hardware structure
 *  @offset: offset of  word in the EEPROM to read
 *  @data: word read from the EEPROM
 *
 *  Reads a 16 bit word from the EEPROM using the hostif.
 **/
static int wx_read_ee_hostif_data(struct wx *wx, u16 offset, u16 *data)
{
	struct wx_hic_read_shadow_ram buffer;
	int status;

	buffer.hdr.req.cmd = FW_READ_SHADOW_RAM_CMD;
	buffer.hdr.req.buf_lenh = 0;
	buffer.hdr.req.buf_lenl = FW_READ_SHADOW_RAM_LEN;
	buffer.hdr.req.checksum = FW_DEFAULT_CHECKSUM;

	/* convert offset from words to bytes */
	buffer.address = (__force u32)cpu_to_be32(offset * 2);
	/* one word */
	buffer.length = (__force u16)cpu_to_be16(sizeof(u16));

	status = wx_host_interface_command(wx, (u32 *)&buffer, sizeof(buffer),
					   WX_HI_COMMAND_TIMEOUT, false);

	if (status != 0)
		return status;

	*data = (u16)rd32a(wx, WX_MNG_MBOX, FW_NVM_DATA_OFFSET);

	return status;
}

/**
 *  wx_read_ee_hostif - Read EEPROM word using a host interface cmd
 *  @wx: pointer to hardware structure
 *  @offset: offset of  word in the EEPROM to read
 *  @data: word read from the EEPROM
 *
 *  Reads a 16 bit word from the EEPROM using the hostif.
 **/
int wx_read_ee_hostif(struct wx *wx, u16 offset, u16 *data)
{
	int status = 0;

	status = wx_acquire_sw_sync(wx, WX_MNG_SWFW_SYNC_SW_FLASH);
	if (status == 0) {
		status = wx_read_ee_hostif_data(wx, offset, data);
		wx_release_sw_sync(wx, WX_MNG_SWFW_SYNC_SW_FLASH);
	}

	return status;
}
EXPORT_SYMBOL(wx_read_ee_hostif);

/**
 *  wx_read_ee_hostif_buffer- Read EEPROM word(s) using hostif
 *  @wx: pointer to hardware structure
 *  @offset: offset of  word in the EEPROM to read
 *  @words: number of words
 *  @data: word(s) read from the EEPROM
 *
 *  Reads a 16 bit word(s) from the EEPROM using the hostif.
 **/
int wx_read_ee_hostif_buffer(struct wx *wx,
			     u16 offset, u16 words, u16 *data)
{
	struct wx_hic_read_shadow_ram buffer;
	u32 current_word = 0;
	u16 words_to_read;
	u32 value = 0;
	int status;
	u32 i;

	/* Take semaphore for the entire operation. */
	status = wx_acquire_sw_sync(wx, WX_MNG_SWFW_SYNC_SW_FLASH);
	if (status != 0)
		return status;

	while (words) {
		if (words > FW_MAX_READ_BUFFER_SIZE / 2)
			words_to_read = FW_MAX_READ_BUFFER_SIZE / 2;
		else
			words_to_read = words;

		buffer.hdr.req.cmd = FW_READ_SHADOW_RAM_CMD;
		buffer.hdr.req.buf_lenh = 0;
		buffer.hdr.req.buf_lenl = FW_READ_SHADOW_RAM_LEN;
		buffer.hdr.req.checksum = FW_DEFAULT_CHECKSUM;

		/* convert offset from words to bytes */
		buffer.address = (__force u32)cpu_to_be32((offset + current_word) * 2);
		buffer.length = (__force u16)cpu_to_be16(words_to_read * 2);

		status = wx_host_interface_command(wx, (u32 *)&buffer,
						   sizeof(buffer),
						   WX_HI_COMMAND_TIMEOUT,
						   false);

		if (status != 0) {
			wx_err(wx, "Host interface command failed\n");
			goto out;
		}

		for (i = 0; i < words_to_read; i++) {
			u32 reg = WX_MNG_MBOX + (FW_NVM_DATA_OFFSET << 2) + 2 * i;

			value = rd32(wx, reg);
			data[current_word] = (u16)(value & 0xffff);
			current_word++;
			i++;
			if (i < words_to_read) {
				value >>= 16;
				data[current_word] = (u16)(value & 0xffff);
				current_word++;
			}
		}
		words -= words_to_read;
	}

out:
	wx_release_sw_sync(wx, WX_MNG_SWFW_SYNC_SW_FLASH);
	return status;
}
EXPORT_SYMBOL(wx_read_ee_hostif_buffer);

/**
 *  wx_init_eeprom_params - Initialize EEPROM params
 *  @wx: pointer to hardware structure
 *
 *  Initializes the EEPROM parameters wx_eeprom_info within the
 *  wx_hw struct in order to set up EEPROM access.
 **/
void wx_init_eeprom_params(struct wx *wx)
{
	struct wx_eeprom_info *eeprom = &wx->eeprom;
	u16 eeprom_size;
	u16 data = 0x80;

	if (eeprom->type == wx_eeprom_uninitialized) {
		eeprom->semaphore_delay = 10;
		eeprom->type = wx_eeprom_none;

		if (!(rd32(wx, WX_SPI_STATUS) &
		      WX_SPI_STATUS_FLASH_BYPASS)) {
			eeprom->type = wx_flash;

			eeprom_size = 4096;
			eeprom->word_size = eeprom_size >> 1;

			wx_dbg(wx, "Eeprom params: type = %d, size = %d\n",
			       eeprom->type, eeprom->word_size);
		}
	}

	if (wx->mac.type == wx_mac_sp) {
		if (wx_read_ee_hostif(wx, WX_SW_REGION_PTR, &data)) {
			wx_err(wx, "NVM Read Error\n");
			return;
		}
		data = data >> 1;
	}

	eeprom->sw_region_offset = data;
}
EXPORT_SYMBOL(wx_init_eeprom_params);

/**
 *  wx_get_mac_addr - Generic get MAC address
 *  @wx: pointer to hardware structure
 *  @mac_addr: Adapter MAC address
 *
 *  Reads the adapter's MAC address from first Receive Address Register (RAR0)
 *  A reset of the adapter must be performed prior to calling this function
 *  in order for the MAC address to have been loaded from the EEPROM into RAR0
 **/
void wx_get_mac_addr(struct wx *wx, u8 *mac_addr)
{
	u32 rar_high;
	u32 rar_low;
	u16 i;

	wr32(wx, WX_PSR_MAC_SWC_IDX, 0);
	rar_high = rd32(wx, WX_PSR_MAC_SWC_AD_H);
	rar_low = rd32(wx, WX_PSR_MAC_SWC_AD_L);

	for (i = 0; i < 2; i++)
		mac_addr[i] = (u8)(rar_high >> (1 - i) * 8);

	for (i = 0; i < 4; i++)
		mac_addr[i + 2] = (u8)(rar_low >> (3 - i) * 8);
}
EXPORT_SYMBOL(wx_get_mac_addr);

/**
 *  wx_set_rar - Set Rx address register
 *  @wx: pointer to hardware structure
 *  @index: Receive address register to write
 *  @addr: Address to put into receive address register
 *  @pools: VMDq "set" or "pool" index
 *  @enable_addr: set flag that address is active
 *
 *  Puts an ethernet address into a receive address register.
 **/
static int wx_set_rar(struct wx *wx, u32 index, u8 *addr, u64 pools,
		      u32 enable_addr)
{
	u32 rar_entries = wx->mac.num_rar_entries;
	u32 rar_low, rar_high;

	/* Make sure we are using a valid rar index range */
	if (index >= rar_entries) {
		wx_err(wx, "RAR index %d is out of range.\n", index);
		return -EINVAL;
	}

	/* select the MAC address */
	wr32(wx, WX_PSR_MAC_SWC_IDX, index);

	/* setup VMDq pool mapping */
	wr32(wx, WX_PSR_MAC_SWC_VM_L, pools & 0xFFFFFFFF);
	if (wx->mac.type == wx_mac_sp)
		wr32(wx, WX_PSR_MAC_SWC_VM_H, pools >> 32);

	/* HW expects these in little endian so we reverse the byte
	 * order from network order (big endian) to little endian
	 *
	 * Some parts put the VMDq setting in the extra RAH bits,
	 * so save everything except the lower 16 bits that hold part
	 * of the address and the address valid bit.
	 */
	rar_low = ((u32)addr[5] |
		  ((u32)addr[4] << 8) |
		  ((u32)addr[3] << 16) |
		  ((u32)addr[2] << 24));
	rar_high = ((u32)addr[1] |
		   ((u32)addr[0] << 8));
	if (enable_addr != 0)
		rar_high |= WX_PSR_MAC_SWC_AD_H_AV;

	wr32(wx, WX_PSR_MAC_SWC_AD_L, rar_low);
	wr32m(wx, WX_PSR_MAC_SWC_AD_H,
	      (WX_PSR_MAC_SWC_AD_H_AD(U16_MAX) |
	       WX_PSR_MAC_SWC_AD_H_ADTYPE(1) |
	       WX_PSR_MAC_SWC_AD_H_AV),
	      rar_high);

	return 0;
}

/**
 *  wx_clear_rar - Remove Rx address register
 *  @wx: pointer to hardware structure
 *  @index: Receive address register to write
 *
 *  Clears an ethernet address from a receive address register.
 **/
static int wx_clear_rar(struct wx *wx, u32 index)
{
	u32 rar_entries = wx->mac.num_rar_entries;

	/* Make sure we are using a valid rar index range */
	if (index >= rar_entries) {
		wx_err(wx, "RAR index %d is out of range.\n", index);
		return -EINVAL;
	}

	/* Some parts put the VMDq setting in the extra RAH bits,
	 * so save everything except the lower 16 bits that hold part
	 * of the address and the address valid bit.
	 */
	wr32(wx, WX_PSR_MAC_SWC_IDX, index);

	wr32(wx, WX_PSR_MAC_SWC_VM_L, 0);
	wr32(wx, WX_PSR_MAC_SWC_VM_H, 0);

	wr32(wx, WX_PSR_MAC_SWC_AD_L, 0);
	wr32m(wx, WX_PSR_MAC_SWC_AD_H,
	      (WX_PSR_MAC_SWC_AD_H_AD(U16_MAX) |
	       WX_PSR_MAC_SWC_AD_H_ADTYPE(1) |
	       WX_PSR_MAC_SWC_AD_H_AV),
	      0);

	return 0;
}

/**
 *  wx_clear_vmdq - Disassociate a VMDq pool index from a rx address
 *  @wx: pointer to hardware struct
 *  @rar: receive address register index to disassociate
 *  @vmdq: VMDq pool index to remove from the rar
 **/
static int wx_clear_vmdq(struct wx *wx, u32 rar, u32 __maybe_unused vmdq)
{
	u32 rar_entries = wx->mac.num_rar_entries;
	u32 mpsar_lo, mpsar_hi;

	/* Make sure we are using a valid rar index range */
	if (rar >= rar_entries) {
		wx_err(wx, "RAR index %d is out of range.\n", rar);
		return -EINVAL;
	}

	wr32(wx, WX_PSR_MAC_SWC_IDX, rar);
	mpsar_lo = rd32(wx, WX_PSR_MAC_SWC_VM_L);
	mpsar_hi = rd32(wx, WX_PSR_MAC_SWC_VM_H);

	if (!mpsar_lo && !mpsar_hi)
		return 0;

	/* was that the last pool using this rar? */
	if (mpsar_lo == 0 && mpsar_hi == 0 && rar != 0)
		wx_clear_rar(wx, rar);

	return 0;
}

/**
 *  wx_init_uta_tables - Initialize the Unicast Table Array
 *  @wx: pointer to hardware structure
 **/
static void wx_init_uta_tables(struct wx *wx)
{
	int i;

	wx_dbg(wx, " Clearing UTA\n");

	for (i = 0; i < 128; i++)
		wr32(wx, WX_PSR_UC_TBL(i), 0);
}

/**
 *  wx_init_rx_addrs - Initializes receive address filters.
 *  @wx: pointer to hardware structure
 *
 *  Places the MAC address in receive address register 0 and clears the rest
 *  of the receive address registers. Clears the multicast table. Assumes
 *  the receiver is in reset when the routine is called.
 **/
void wx_init_rx_addrs(struct wx *wx)
{
	u32 rar_entries = wx->mac.num_rar_entries;
	u32 psrctl;
	int i;

	/* If the current mac address is valid, assume it is a software override
	 * to the permanent address.
	 * Otherwise, use the permanent address from the eeprom.
	 */
	if (!is_valid_ether_addr(wx->mac.addr)) {
		/* Get the MAC address from the RAR0 for later reference */
		wx_get_mac_addr(wx, wx->mac.addr);
		wx_dbg(wx, "Keeping Current RAR0 Addr = %pM\n", wx->mac.addr);
	} else {
		/* Setup the receive address. */
		wx_dbg(wx, "Overriding MAC Address in RAR[0]\n");
		wx_dbg(wx, "New MAC Addr = %pM\n", wx->mac.addr);

		wx_set_rar(wx, 0, wx->mac.addr, 0, WX_PSR_MAC_SWC_AD_H_AV);

		if (wx->mac.type == wx_mac_sp) {
			/* clear VMDq pool/queue selection for RAR 0 */
			wx_clear_vmdq(wx, 0, WX_CLEAR_VMDQ_ALL);
		}
	}

	/* Zero out the other receive addresses. */
	wx_dbg(wx, "Clearing RAR[1-%d]\n", rar_entries - 1);
	for (i = 1; i < rar_entries; i++) {
		wr32(wx, WX_PSR_MAC_SWC_IDX, i);
		wr32(wx, WX_PSR_MAC_SWC_AD_L, 0);
		wr32(wx, WX_PSR_MAC_SWC_AD_H, 0);
	}

	/* Clear the MTA */
	wx->addr_ctrl.mta_in_use = 0;
	psrctl = rd32(wx, WX_PSR_CTL);
	psrctl &= ~(WX_PSR_CTL_MO | WX_PSR_CTL_MFE);
	psrctl |= wx->mac.mc_filter_type << WX_PSR_CTL_MO_SHIFT;
	wr32(wx, WX_PSR_CTL, psrctl);
	wx_dbg(wx, " Clearing MTA\n");
	for (i = 0; i < wx->mac.mcft_size; i++)
		wr32(wx, WX_PSR_MC_TBL(i), 0);

	wx_init_uta_tables(wx);
}
EXPORT_SYMBOL(wx_init_rx_addrs);

static void wx_sync_mac_table(struct wx *wx)
{
	int i;

	for (i = 0; i < wx->mac.num_rar_entries; i++) {
		if (wx->mac_table[i].state & WX_MAC_STATE_MODIFIED) {
			if (wx->mac_table[i].state & WX_MAC_STATE_IN_USE) {
				wx_set_rar(wx, i,
					   wx->mac_table[i].addr,
					   wx->mac_table[i].pools,
					   WX_PSR_MAC_SWC_AD_H_AV);
			} else {
				wx_clear_rar(wx, i);
			}
			wx->mac_table[i].state &= ~(WX_MAC_STATE_MODIFIED);
		}
	}
}

/* this function destroys the first RAR entry */
void wx_mac_set_default_filter(struct wx *wx, u8 *addr)
{
	memcpy(&wx->mac_table[0].addr, addr, ETH_ALEN);
	wx->mac_table[0].pools = 1ULL;
	wx->mac_table[0].state = (WX_MAC_STATE_DEFAULT | WX_MAC_STATE_IN_USE);
	wx_set_rar(wx, 0, wx->mac_table[0].addr,
		   wx->mac_table[0].pools,
		   WX_PSR_MAC_SWC_AD_H_AV);
}
EXPORT_SYMBOL(wx_mac_set_default_filter);

void wx_flush_sw_mac_table(struct wx *wx)
{
	u32 i;

	for (i = 0; i < wx->mac.num_rar_entries; i++) {
		if (!(wx->mac_table[i].state & WX_MAC_STATE_IN_USE))
			continue;

		wx->mac_table[i].state |= WX_MAC_STATE_MODIFIED;
		wx->mac_table[i].state &= ~WX_MAC_STATE_IN_USE;
		memset(wx->mac_table[i].addr, 0, ETH_ALEN);
		wx->mac_table[i].pools = 0;
	}
	wx_sync_mac_table(wx);
}
EXPORT_SYMBOL(wx_flush_sw_mac_table);

static int wx_add_mac_filter(struct wx *wx, u8 *addr, u16 pool)
{
	u32 i;

	if (is_zero_ether_addr(addr))
		return -EINVAL;

	for (i = 0; i < wx->mac.num_rar_entries; i++) {
		if (wx->mac_table[i].state & WX_MAC_STATE_IN_USE) {
			if (ether_addr_equal(addr, wx->mac_table[i].addr)) {
				if (wx->mac_table[i].pools != (1ULL << pool)) {
					memcpy(wx->mac_table[i].addr, addr, ETH_ALEN);
					wx->mac_table[i].pools |= (1ULL << pool);
					wx_sync_mac_table(wx);
					return i;
				}
			}
		}

		if (wx->mac_table[i].state & WX_MAC_STATE_IN_USE)
			continue;
		wx->mac_table[i].state |= (WX_MAC_STATE_MODIFIED |
					   WX_MAC_STATE_IN_USE);
		memcpy(wx->mac_table[i].addr, addr, ETH_ALEN);
		wx->mac_table[i].pools |= (1ULL << pool);
		wx_sync_mac_table(wx);
		return i;
	}
	return -ENOMEM;
}

static int wx_del_mac_filter(struct wx *wx, u8 *addr, u16 pool)
{
	u32 i;

	if (is_zero_ether_addr(addr))
		return -EINVAL;

	/* search table for addr, if found, set to 0 and sync */
	for (i = 0; i < wx->mac.num_rar_entries; i++) {
		if (!ether_addr_equal(addr, wx->mac_table[i].addr))
			continue;

		wx->mac_table[i].state |= WX_MAC_STATE_MODIFIED;
		wx->mac_table[i].pools &= ~(1ULL << pool);
		if (!wx->mac_table[i].pools) {
			wx->mac_table[i].state &= ~WX_MAC_STATE_IN_USE;
			memset(wx->mac_table[i].addr, 0, ETH_ALEN);
		}
		wx_sync_mac_table(wx);
		return 0;
	}
	return -ENOMEM;
}

static int wx_available_rars(struct wx *wx)
{
	u32 i, count = 0;

	for (i = 0; i < wx->mac.num_rar_entries; i++) {
		if (wx->mac_table[i].state == 0)
			count++;
	}

	return count;
}

/**
 * wx_write_uc_addr_list - write unicast addresses to RAR table
 * @netdev: network interface device structure
 * @pool: index for mac table
 *
 * Writes unicast address list to the RAR table.
 * Returns: -ENOMEM on failure/insufficient address space
 *                0 on no addresses written
 *                X on writing X addresses to the RAR table
 **/
static int wx_write_uc_addr_list(struct net_device *netdev, int pool)
{
	struct wx *wx = netdev_priv(netdev);
	int count = 0;

	/* return ENOMEM indicating insufficient memory for addresses */
	if (netdev_uc_count(netdev) > wx_available_rars(wx))
		return -ENOMEM;

	if (!netdev_uc_empty(netdev)) {
		struct netdev_hw_addr *ha;

		netdev_for_each_uc_addr(ha, netdev) {
			wx_del_mac_filter(wx, ha->addr, pool);
			wx_add_mac_filter(wx, ha->addr, pool);
			count++;
		}
	}
	return count;
}

/**
 *  wx_mta_vector - Determines bit-vector in multicast table to set
 *  @wx: pointer to private structure
 *  @mc_addr: the multicast address
 *
 *  Extracts the 12 bits, from a multicast address, to determine which
 *  bit-vector to set in the multicast table. The hardware uses 12 bits, from
 *  incoming rx multicast addresses, to determine the bit-vector to check in
 *  the MTA. Which of the 4 combination, of 12-bits, the hardware uses is set
 *  by the MO field of the MCSTCTRL. The MO field is set during initialization
 *  to mc_filter_type.
 **/
static u32 wx_mta_vector(struct wx *wx, u8 *mc_addr)
{
	u32 vector = 0;

	switch (wx->mac.mc_filter_type) {
	case 0:   /* use bits [47:36] of the address */
		vector = ((mc_addr[4] >> 4) | (((u16)mc_addr[5]) << 4));
		break;
	case 1:   /* use bits [46:35] of the address */
		vector = ((mc_addr[4] >> 3) | (((u16)mc_addr[5]) << 5));
		break;
	case 2:   /* use bits [45:34] of the address */
		vector = ((mc_addr[4] >> 2) | (((u16)mc_addr[5]) << 6));
		break;
	case 3:   /* use bits [43:32] of the address */
		vector = ((mc_addr[4]) | (((u16)mc_addr[5]) << 8));
		break;
	default:  /* Invalid mc_filter_type */
		wx_err(wx, "MC filter type param set incorrectly\n");
		break;
	}

	/* vector can only be 12-bits or boundary will be exceeded */
	vector &= 0xFFF;
	return vector;
}

/**
 *  wx_set_mta - Set bit-vector in multicast table
 *  @wx: pointer to private structure
 *  @mc_addr: Multicast address
 *
 *  Sets the bit-vector in the multicast table.
 **/
static void wx_set_mta(struct wx *wx, u8 *mc_addr)
{
	u32 vector, vector_bit, vector_reg;

	wx->addr_ctrl.mta_in_use++;

	vector = wx_mta_vector(wx, mc_addr);
	wx_dbg(wx, " bit-vector = 0x%03X\n", vector);

	/* The MTA is a register array of 128 32-bit registers. It is treated
	 * like an array of 4096 bits.  We want to set bit
	 * BitArray[vector_value]. So we figure out what register the bit is
	 * in, read it, OR in the new bit, then write back the new value.  The
	 * register is determined by the upper 7 bits of the vector value and
	 * the bit within that register are determined by the lower 5 bits of
	 * the value.
	 */
	vector_reg = (vector >> 5) & 0x7F;
	vector_bit = vector & 0x1F;
	wx->mac.mta_shadow[vector_reg] |= (1 << vector_bit);
}

/**
 *  wx_update_mc_addr_list - Updates MAC list of multicast addresses
 *  @wx: pointer to private structure
 *  @netdev: pointer to net device structure
 *
 *  The given list replaces any existing list. Clears the MC addrs from receive
 *  address registers and the multicast table. Uses unused receive address
 *  registers for the first multicast addresses, and hashes the rest into the
 *  multicast table.
 **/
static void wx_update_mc_addr_list(struct wx *wx, struct net_device *netdev)
{
	struct netdev_hw_addr *ha;
	u32 i, psrctl;

	/* Set the new number of MC addresses that we are being requested to
	 * use.
	 */
	wx->addr_ctrl.num_mc_addrs = netdev_mc_count(netdev);
	wx->addr_ctrl.mta_in_use = 0;

	/* Clear mta_shadow */
	wx_dbg(wx, " Clearing MTA\n");
	memset(&wx->mac.mta_shadow, 0, sizeof(wx->mac.mta_shadow));

	/* Update mta_shadow */
	netdev_for_each_mc_addr(ha, netdev) {
		wx_dbg(wx, " Adding the multicast addresses:\n");
		wx_set_mta(wx, ha->addr);
	}

	/* Enable mta */
	for (i = 0; i < wx->mac.mcft_size; i++)
		wr32a(wx, WX_PSR_MC_TBL(0), i,
		      wx->mac.mta_shadow[i]);

	if (wx->addr_ctrl.mta_in_use > 0) {
		psrctl = rd32(wx, WX_PSR_CTL);
		psrctl &= ~(WX_PSR_CTL_MO | WX_PSR_CTL_MFE);
		psrctl |= WX_PSR_CTL_MFE |
			  (wx->mac.mc_filter_type << WX_PSR_CTL_MO_SHIFT);
		wr32(wx, WX_PSR_CTL, psrctl);
	}

	wx_dbg(wx, "Update mc addr list Complete\n");
}

/**
 * wx_write_mc_addr_list - write multicast addresses to MTA
 * @netdev: network interface device structure
 *
 * Writes multicast address list to the MTA hash table.
 * Returns: 0 on no addresses written
 *          X on writing X addresses to MTA
 **/
static int wx_write_mc_addr_list(struct net_device *netdev)
{
	struct wx *wx = netdev_priv(netdev);

	if (!netif_running(netdev))
		return 0;

	wx_update_mc_addr_list(wx, netdev);

	return netdev_mc_count(netdev);
}

/**
 * wx_set_mac - Change the Ethernet Address of the NIC
 * @netdev: network interface device structure
 * @p: pointer to an address structure
 *
 * Returns 0 on success, negative on failure
 **/
int wx_set_mac(struct net_device *netdev, void *p)
{
	struct wx *wx = netdev_priv(netdev);
	struct sockaddr *addr = p;
	int retval;

	retval = eth_prepare_mac_addr_change(netdev, addr);
	if (retval)
		return retval;

	wx_del_mac_filter(wx, wx->mac.addr, 0);
	eth_hw_addr_set(netdev, addr->sa_data);
	memcpy(wx->mac.addr, addr->sa_data, netdev->addr_len);

	wx_mac_set_default_filter(wx, wx->mac.addr);

	return 0;
}
EXPORT_SYMBOL(wx_set_mac);

void wx_disable_rx(struct wx *wx)
{
	u32 pfdtxgswc;
	u32 rxctrl;

	rxctrl = rd32(wx, WX_RDB_PB_CTL);
	if (rxctrl & WX_RDB_PB_CTL_RXEN) {
		pfdtxgswc = rd32(wx, WX_PSR_CTL);
		if (pfdtxgswc & WX_PSR_CTL_SW_EN) {
			pfdtxgswc &= ~WX_PSR_CTL_SW_EN;
			wr32(wx, WX_PSR_CTL, pfdtxgswc);
			wx->mac.set_lben = true;
		} else {
			wx->mac.set_lben = false;
		}
		rxctrl &= ~WX_RDB_PB_CTL_RXEN;
		wr32(wx, WX_RDB_PB_CTL, rxctrl);

		if (!(((wx->subsystem_device_id & WX_NCSI_MASK) == WX_NCSI_SUP) ||
		      ((wx->subsystem_device_id & WX_WOL_MASK) == WX_WOL_SUP))) {
			/* disable mac receiver */
			wr32m(wx, WX_MAC_RX_CFG,
			      WX_MAC_RX_CFG_RE, 0);
		}
	}
}
EXPORT_SYMBOL(wx_disable_rx);

static void wx_enable_rx(struct wx *wx)
{
	u32 psrctl;

	/* enable mac receiver */
	wr32m(wx, WX_MAC_RX_CFG,
	      WX_MAC_RX_CFG_RE, WX_MAC_RX_CFG_RE);

	wr32m(wx, WX_RDB_PB_CTL,
	      WX_RDB_PB_CTL_RXEN, WX_RDB_PB_CTL_RXEN);

	if (wx->mac.set_lben) {
		psrctl = rd32(wx, WX_PSR_CTL);
		psrctl |= WX_PSR_CTL_SW_EN;
		wr32(wx, WX_PSR_CTL, psrctl);
		wx->mac.set_lben = false;
	}
}

/**
 * wx_set_rxpba - Initialize Rx packet buffer
 * @wx: pointer to private structure
 **/
static void wx_set_rxpba(struct wx *wx)
{
	u32 rxpktsize, txpktsize, txpbthresh;

	rxpktsize = wx->mac.rx_pb_size << WX_RDB_PB_SZ_SHIFT;
	wr32(wx, WX_RDB_PB_SZ(0), rxpktsize);

	/* Only support an equally distributed Tx packet buffer strategy. */
	txpktsize = wx->mac.tx_pb_size;
	txpbthresh = (txpktsize / 1024) - WX_TXPKT_SIZE_MAX;
	wr32(wx, WX_TDB_PB_SZ(0), txpktsize);
	wr32(wx, WX_TDM_PB_THRE(0), txpbthresh);
}

#define WX_ETH_FRAMING 20

/**
 * wx_hpbthresh - calculate high water mark for flow control
 *
 * @wx: board private structure to calculate for
 **/
static int wx_hpbthresh(struct wx *wx)
{
	struct net_device *dev = wx->netdev;
	int link, tc, kb, marker;
	u32 dv_id, rx_pba;

	/* Calculate max LAN frame size */
	link = dev->mtu + ETH_HLEN + ETH_FCS_LEN + WX_ETH_FRAMING;
	tc = link;

	/* Calculate delay value for device */
	dv_id = WX_DV(link, tc);

	/* Delay value is calculated in bit times convert to KB */
	kb = WX_BT2KB(dv_id);
	rx_pba = rd32(wx, WX_RDB_PB_SZ(0)) >> WX_RDB_PB_SZ_SHIFT;

	marker = rx_pba - kb;

	/* It is possible that the packet buffer is not large enough
	 * to provide required headroom. In this case throw an error
	 * to user and a do the best we can.
	 */
	if (marker < 0) {
		dev_warn(&wx->pdev->dev,
			 "Packet Buffer can not provide enough headroom to support flow control. Decrease MTU or number of traffic classes\n");
		marker = tc + 1;
	}

	return marker;
}

/**
 * wx_lpbthresh - calculate low water mark for flow control
 *
 * @wx: board private structure to calculate for
 **/
static int wx_lpbthresh(struct wx *wx)
{
	struct net_device *dev = wx->netdev;
	u32 dv_id;
	int tc;

	/* Calculate max LAN frame size */
	tc = dev->mtu + ETH_HLEN + ETH_FCS_LEN;

	/* Calculate delay value for device */
	dv_id = WX_LOW_DV(tc);

	/* Delay value is calculated in bit times convert to KB */
	return WX_BT2KB(dv_id);
}

/**
 * wx_pbthresh_setup - calculate and setup high low water marks
 *
 * @wx: board private structure to calculate for
 **/
static void wx_pbthresh_setup(struct wx *wx)
{
	wx->fc.high_water = wx_hpbthresh(wx);
	wx->fc.low_water = wx_lpbthresh(wx);

	/* Low water marks must not be larger than high water marks */
	if (wx->fc.low_water > wx->fc.high_water)
		wx->fc.low_water = 0;
}

static void wx_configure_port(struct wx *wx)
{
	u32 value, i;

	value = WX_CFG_PORT_CTL_D_VLAN | WX_CFG_PORT_CTL_QINQ;
	wr32m(wx, WX_CFG_PORT_CTL,
	      WX_CFG_PORT_CTL_D_VLAN |
	      WX_CFG_PORT_CTL_QINQ,
	      value);

	wr32(wx, WX_CFG_TAG_TPID(0),
	     ETH_P_8021Q | ETH_P_8021AD << 16);
	wx->tpid[0] = ETH_P_8021Q;
	wx->tpid[1] = ETH_P_8021AD;
	for (i = 1; i < 4; i++)
		wr32(wx, WX_CFG_TAG_TPID(i),
		     ETH_P_8021Q | ETH_P_8021Q << 16);
	for (i = 2; i < 8; i++)
		wx->tpid[i] = ETH_P_8021Q;
}

/**
 *  wx_disable_sec_rx_path - Stops the receive data path
 *  @wx: pointer to private structure
 *
 *  Stops the receive data path and waits for the HW to internally empty
 *  the Rx security block
 **/
static int wx_disable_sec_rx_path(struct wx *wx)
{
	u32 secrx;

	wr32m(wx, WX_RSC_CTL,
	      WX_RSC_CTL_RX_DIS, WX_RSC_CTL_RX_DIS);

	return read_poll_timeout(rd32, secrx, secrx & WX_RSC_ST_RSEC_RDY,
				 1000, 40000, false, wx, WX_RSC_ST);
}

/**
 *  wx_enable_sec_rx_path - Enables the receive data path
 *  @wx: pointer to private structure
 *
 *  Enables the receive data path.
 **/
static void wx_enable_sec_rx_path(struct wx *wx)
{
	wr32m(wx, WX_RSC_CTL, WX_RSC_CTL_RX_DIS, 0);
	WX_WRITE_FLUSH(wx);
}

static void wx_vlan_strip_control(struct wx *wx, bool enable)
{
	int i, j;

	for (i = 0; i < wx->num_rx_queues; i++) {
		struct wx_ring *ring = wx->rx_ring[i];

		j = ring->reg_idx;
		wr32m(wx, WX_PX_RR_CFG(j), WX_PX_RR_CFG_VLAN,
		      enable ? WX_PX_RR_CFG_VLAN : 0);
	}
}

void wx_set_rx_mode(struct net_device *netdev)
{
	struct wx *wx = netdev_priv(netdev);
	netdev_features_t features;
	u32 fctrl, vmolr, vlnctrl;
	int count;

	features = netdev->features;

	/* Check for Promiscuous and All Multicast modes */
	fctrl = rd32(wx, WX_PSR_CTL);
	fctrl &= ~(WX_PSR_CTL_UPE | WX_PSR_CTL_MPE);
	vmolr = rd32(wx, WX_PSR_VM_L2CTL(0));
	vmolr &= ~(WX_PSR_VM_L2CTL_UPE |
		   WX_PSR_VM_L2CTL_MPE |
		   WX_PSR_VM_L2CTL_ROPE |
		   WX_PSR_VM_L2CTL_ROMPE);
	vlnctrl = rd32(wx, WX_PSR_VLAN_CTL);
	vlnctrl &= ~(WX_PSR_VLAN_CTL_VFE | WX_PSR_VLAN_CTL_CFIEN);

	/* set all bits that we expect to always be set */
	fctrl |= WX_PSR_CTL_BAM | WX_PSR_CTL_MFE;
	vmolr |= WX_PSR_VM_L2CTL_BAM |
		 WX_PSR_VM_L2CTL_AUPE |
		 WX_PSR_VM_L2CTL_VACC;
	vlnctrl |= WX_PSR_VLAN_CTL_VFE;

	wx->addr_ctrl.user_set_promisc = false;
	if (netdev->flags & IFF_PROMISC) {
		wx->addr_ctrl.user_set_promisc = true;
		fctrl |= WX_PSR_CTL_UPE | WX_PSR_CTL_MPE;
		/* pf don't want packets routing to vf, so clear UPE */
		vmolr |= WX_PSR_VM_L2CTL_MPE;
		vlnctrl &= ~WX_PSR_VLAN_CTL_VFE;
	}

	if (netdev->flags & IFF_ALLMULTI) {
		fctrl |= WX_PSR_CTL_MPE;
		vmolr |= WX_PSR_VM_L2CTL_MPE;
	}

	if (netdev->features & NETIF_F_RXALL) {
		vmolr |= (WX_PSR_VM_L2CTL_UPE | WX_PSR_VM_L2CTL_MPE);
		vlnctrl &= ~WX_PSR_VLAN_CTL_VFE;
		/* receive bad packets */
		wr32m(wx, WX_RSC_CTL,
		      WX_RSC_CTL_SAVE_MAC_ERR,
		      WX_RSC_CTL_SAVE_MAC_ERR);
	} else {
		vmolr |= WX_PSR_VM_L2CTL_ROPE | WX_PSR_VM_L2CTL_ROMPE;
	}

	/* Write addresses to available RAR registers, if there is not
	 * sufficient space to store all the addresses then enable
	 * unicast promiscuous mode
	 */
	count = wx_write_uc_addr_list(netdev, 0);
	if (count < 0) {
		vmolr &= ~WX_PSR_VM_L2CTL_ROPE;
		vmolr |= WX_PSR_VM_L2CTL_UPE;
	}

	/* Write addresses to the MTA, if the attempt fails
	 * then we should just turn on promiscuous mode so
	 * that we can at least receive multicast traffic
	 */
	count = wx_write_mc_addr_list(netdev);
	if (count < 0) {
		vmolr &= ~WX_PSR_VM_L2CTL_ROMPE;
		vmolr |= WX_PSR_VM_L2CTL_MPE;
	}

	wr32(wx, WX_PSR_VLAN_CTL, vlnctrl);
	wr32(wx, WX_PSR_CTL, fctrl);
	wr32(wx, WX_PSR_VM_L2CTL(0), vmolr);

	if ((features & NETIF_F_HW_VLAN_CTAG_RX) &&
	    (features & NETIF_F_HW_VLAN_STAG_RX))
		wx_vlan_strip_control(wx, true);
	else
		wx_vlan_strip_control(wx, false);

}
EXPORT_SYMBOL(wx_set_rx_mode);

static void wx_set_rx_buffer_len(struct wx *wx)
{
	struct net_device *netdev = wx->netdev;
	u32 mhadd, max_frame;

	max_frame = netdev->mtu + ETH_HLEN + ETH_FCS_LEN + VLAN_HLEN;
	/* adjust max frame to be at least the size of a standard frame */
	if (max_frame < (ETH_FRAME_LEN + ETH_FCS_LEN))
		max_frame = (ETH_FRAME_LEN + ETH_FCS_LEN);

	mhadd = rd32(wx, WX_PSR_MAX_SZ);
	if (max_frame != mhadd)
		wr32(wx, WX_PSR_MAX_SZ, max_frame);
}

/**
 * wx_change_mtu - Change the Maximum Transfer Unit
 * @netdev: network interface device structure
 * @new_mtu: new value for maximum frame size
 *
 * Returns 0 on success, negative on failure
 **/
int wx_change_mtu(struct net_device *netdev, int new_mtu)
{
	struct wx *wx = netdev_priv(netdev);

	netdev->mtu = new_mtu;
	wx_set_rx_buffer_len(wx);

	return 0;
}
EXPORT_SYMBOL(wx_change_mtu);

/* Disable the specified rx queue */
void wx_disable_rx_queue(struct wx *wx, struct wx_ring *ring)
{
	u8 reg_idx = ring->reg_idx;
	u32 rxdctl;
	int ret;

	/* write value back with RRCFG.EN bit cleared */
	wr32m(wx, WX_PX_RR_CFG(reg_idx),
	      WX_PX_RR_CFG_RR_EN, 0);

	/* the hardware may take up to 100us to really disable the rx queue */
	ret = read_poll_timeout(rd32, rxdctl, !(rxdctl & WX_PX_RR_CFG_RR_EN),
				10, 100, true, wx, WX_PX_RR_CFG(reg_idx));

	if (ret == -ETIMEDOUT) {
		/* Just for information */
		wx_err(wx,
		       "RRCFG.EN on Rx queue %d not cleared within the polling period\n",
		       reg_idx);
	}
}
EXPORT_SYMBOL(wx_disable_rx_queue);

static void wx_enable_rx_queue(struct wx *wx, struct wx_ring *ring)
{
	u8 reg_idx = ring->reg_idx;
	u32 rxdctl;
	int ret;

	ret = read_poll_timeout(rd32, rxdctl, rxdctl & WX_PX_RR_CFG_RR_EN,
				1000, 10000, true, wx, WX_PX_RR_CFG(reg_idx));

	if (ret == -ETIMEDOUT) {
		/* Just for information */
		wx_err(wx,
		       "RRCFG.EN on Rx queue %d not set within the polling period\n",
		       reg_idx);
	}
}

static void wx_configure_srrctl(struct wx *wx,
				struct wx_ring *rx_ring)
{
	u16 reg_idx = rx_ring->reg_idx;
	u32 srrctl;

	srrctl = rd32(wx, WX_PX_RR_CFG(reg_idx));
	srrctl &= ~(WX_PX_RR_CFG_RR_HDR_SZ |
		    WX_PX_RR_CFG_RR_BUF_SZ |
		    WX_PX_RR_CFG_SPLIT_MODE);
	/* configure header buffer length, needed for RSC */
	srrctl |= WX_RXBUFFER_256 << WX_PX_RR_CFG_BHDRSIZE_SHIFT;

	/* configure the packet buffer length */
	srrctl |= WX_RX_BUFSZ >> WX_PX_RR_CFG_BSIZEPKT_SHIFT;

	wr32(wx, WX_PX_RR_CFG(reg_idx), srrctl);
}

static void wx_configure_tx_ring(struct wx *wx,
				 struct wx_ring *ring)
{
	u32 txdctl = WX_PX_TR_CFG_ENABLE;
	u8 reg_idx = ring->reg_idx;
	u64 tdba = ring->dma;
	int ret;

	/* disable queue to avoid issues while updating state */
	wr32(wx, WX_PX_TR_CFG(reg_idx), WX_PX_TR_CFG_SWFLSH);
	WX_WRITE_FLUSH(wx);

	wr32(wx, WX_PX_TR_BAL(reg_idx), tdba & DMA_BIT_MASK(32));
	wr32(wx, WX_PX_TR_BAH(reg_idx), upper_32_bits(tdba));

	/* reset head and tail pointers */
	wr32(wx, WX_PX_TR_RP(reg_idx), 0);
	wr32(wx, WX_PX_TR_WP(reg_idx), 0);
	ring->tail = wx->hw_addr + WX_PX_TR_WP(reg_idx);

	if (ring->count < WX_MAX_TXD)
		txdctl |= ring->count / 128 << WX_PX_TR_CFG_TR_SIZE_SHIFT;
	txdctl |= 0x20 << WX_PX_TR_CFG_WTHRESH_SHIFT;

	/* reinitialize tx_buffer_info */
	memset(ring->tx_buffer_info, 0,
	       sizeof(struct wx_tx_buffer) * ring->count);

	/* enable queue */
	wr32(wx, WX_PX_TR_CFG(reg_idx), txdctl);

	/* poll to verify queue is enabled */
	ret = read_poll_timeout(rd32, txdctl, txdctl & WX_PX_TR_CFG_ENABLE,
				1000, 10000, true, wx, WX_PX_TR_CFG(reg_idx));
	if (ret == -ETIMEDOUT)
		wx_err(wx, "Could not enable Tx Queue %d\n", reg_idx);
}

static void wx_configure_rx_ring(struct wx *wx,
				 struct wx_ring *ring)
{
	u16 reg_idx = ring->reg_idx;
	union wx_rx_desc *rx_desc;
	u64 rdba = ring->dma;
	u32 rxdctl;

	/* disable queue to avoid issues while updating state */
	rxdctl = rd32(wx, WX_PX_RR_CFG(reg_idx));
	wx_disable_rx_queue(wx, ring);

	wr32(wx, WX_PX_RR_BAL(reg_idx), rdba & DMA_BIT_MASK(32));
	wr32(wx, WX_PX_RR_BAH(reg_idx), upper_32_bits(rdba));

	if (ring->count == WX_MAX_RXD)
		rxdctl |= 0 << WX_PX_RR_CFG_RR_SIZE_SHIFT;
	else
		rxdctl |= (ring->count / 128) << WX_PX_RR_CFG_RR_SIZE_SHIFT;

	rxdctl |= 0x1 << WX_PX_RR_CFG_RR_THER_SHIFT;
	wr32(wx, WX_PX_RR_CFG(reg_idx), rxdctl);

	/* reset head and tail pointers */
	wr32(wx, WX_PX_RR_RP(reg_idx), 0);
	wr32(wx, WX_PX_RR_WP(reg_idx), 0);
	ring->tail = wx->hw_addr + WX_PX_RR_WP(reg_idx);

	wx_configure_srrctl(wx, ring);

	/* initialize rx_buffer_info */
	memset(ring->rx_buffer_info, 0,
	       sizeof(struct wx_rx_buffer) * ring->count);

	/* initialize Rx descriptor 0 */
	rx_desc = WX_RX_DESC(ring, 0);
	rx_desc->wb.upper.length = 0;

	/* enable receive descriptor ring */
	wr32m(wx, WX_PX_RR_CFG(reg_idx),
	      WX_PX_RR_CFG_RR_EN, WX_PX_RR_CFG_RR_EN);

	wx_enable_rx_queue(wx, ring);
	wx_alloc_rx_buffers(ring, wx_desc_unused(ring));
}

/**
 * wx_configure_tx - Configure Transmit Unit after Reset
 * @wx: pointer to private structure
 *
 * Configure the Tx unit of the MAC after a reset.
 **/
static void wx_configure_tx(struct wx *wx)
{
	u32 i;

	/* TDM_CTL.TE must be before Tx queues are enabled */
	wr32m(wx, WX_TDM_CTL,
	      WX_TDM_CTL_TE, WX_TDM_CTL_TE);

	/* Setup the HW Tx Head and Tail descriptor pointers */
	for (i = 0; i < wx->num_tx_queues; i++)
		wx_configure_tx_ring(wx, wx->tx_ring[i]);

	wr32m(wx, WX_TSC_BUF_AE, WX_TSC_BUF_AE_THR, 0x10);

	if (wx->mac.type == wx_mac_em)
		wr32m(wx, WX_TSC_CTL, WX_TSC_CTL_TX_DIS | WX_TSC_CTL_TSEC_DIS, 0x1);

	/* enable mac transmitter */
	wr32m(wx, WX_MAC_TX_CFG,
	      WX_MAC_TX_CFG_TE, WX_MAC_TX_CFG_TE);
}

static void wx_restore_vlan(struct wx *wx)
{
	u16 vid = 1;

	wx_vlan_rx_add_vid(wx->netdev, htons(ETH_P_8021Q), 0);

	for_each_set_bit_from(vid, wx->active_vlans, VLAN_N_VID)
		wx_vlan_rx_add_vid(wx->netdev, htons(ETH_P_8021Q), vid);
}

static void wx_store_reta(struct wx *wx)
{
	u8 *indir_tbl = wx->rss_indir_tbl;
	u32 reta = 0;
	u32 i;

	/* Fill out the redirection table as follows:
	 *  - 8 bit wide entries containing 4 bit RSS index
	 */
	for (i = 0; i < WX_MAX_RETA_ENTRIES; i++) {
		reta |= indir_tbl[i] << (i & 0x3) * 8;
		if ((i & 3) == 3) {
			wr32(wx, WX_RDB_RSSTBL(i >> 2), reta);
			reta = 0;
		}
	}
}

static void wx_setup_reta(struct wx *wx)
{
	u16 rss_i = wx->ring_feature[RING_F_RSS].indices;
	u32 random_key_size = WX_RSS_KEY_SIZE / 4;
	u32 i, j;

	/* Fill out hash function seeds */
	for (i = 0; i < random_key_size; i++)
		wr32(wx, WX_RDB_RSSRK(i), wx->rss_key[i]);

	/* Fill out redirection table */
	memset(wx->rss_indir_tbl, 0, sizeof(wx->rss_indir_tbl));

	for (i = 0, j = 0; i < WX_MAX_RETA_ENTRIES; i++, j++) {
		if (j == rss_i)
			j = 0;

		wx->rss_indir_tbl[i] = j;
	}

	wx_store_reta(wx);
}

static void wx_setup_mrqc(struct wx *wx)
{
	u32 rss_field = 0;

	/* Disable indicating checksum in descriptor, enables RSS hash */
	wr32m(wx, WX_PSR_CTL, WX_PSR_CTL_PCSD, WX_PSR_CTL_PCSD);

	/* Perform hash on these packet types */
	rss_field = WX_RDB_RA_CTL_RSS_IPV4 |
		    WX_RDB_RA_CTL_RSS_IPV4_TCP |
		    WX_RDB_RA_CTL_RSS_IPV4_UDP |
		    WX_RDB_RA_CTL_RSS_IPV6 |
		    WX_RDB_RA_CTL_RSS_IPV6_TCP |
		    WX_RDB_RA_CTL_RSS_IPV6_UDP;

	netdev_rss_key_fill(wx->rss_key, sizeof(wx->rss_key));

	wx_setup_reta(wx);

	if (wx->rss_enabled)
		rss_field |= WX_RDB_RA_CTL_RSS_EN;

	wr32(wx, WX_RDB_RA_CTL, rss_field);
}

/**
 * wx_configure_rx - Configure Receive Unit after Reset
 * @wx: pointer to private structure
 *
 * Configure the Rx unit of the MAC after a reset.
 **/
void wx_configure_rx(struct wx *wx)
{
	u32 psrtype, i;
	int ret;

	wx_disable_rx(wx);

	psrtype = WX_RDB_PL_CFG_L4HDR |
		  WX_RDB_PL_CFG_L3HDR |
		  WX_RDB_PL_CFG_L2HDR |
		  WX_RDB_PL_CFG_TUN_TUNHDR;
	wr32(wx, WX_RDB_PL_CFG(0), psrtype);

	/* enable hw crc stripping */
	wr32m(wx, WX_RSC_CTL, WX_RSC_CTL_CRC_STRIP, WX_RSC_CTL_CRC_STRIP);

	if (wx->mac.type == wx_mac_sp) {
		u32 psrctl;

		/* RSC Setup */
		psrctl = rd32(wx, WX_PSR_CTL);
		psrctl |= WX_PSR_CTL_RSC_ACK; /* Disable RSC for ACK packets */
		psrctl |= WX_PSR_CTL_RSC_DIS;
		wr32(wx, WX_PSR_CTL, psrctl);
	}

	wx_setup_mrqc(wx);

	/* set_rx_buffer_len must be called before ring initialization */
	wx_set_rx_buffer_len(wx);

	/* Setup the HW Rx Head and Tail Descriptor Pointers and
	 * the Base and Length of the Rx Descriptor Ring
	 */
	for (i = 0; i < wx->num_rx_queues; i++)
		wx_configure_rx_ring(wx, wx->rx_ring[i]);

	/* Enable all receives, disable security engine prior to block traffic */
	ret = wx_disable_sec_rx_path(wx);
	if (ret < 0)
		wx_err(wx, "The register status is abnormal, please check device.");

	wx_enable_rx(wx);
	wx_enable_sec_rx_path(wx);
}
EXPORT_SYMBOL(wx_configure_rx);

static void wx_configure_isb(struct wx *wx)
{
	/* set ISB Address */
	wr32(wx, WX_PX_ISB_ADDR_L, wx->isb_dma & DMA_BIT_MASK(32));
	if (IS_ENABLED(CONFIG_ARCH_DMA_ADDR_T_64BIT))
		wr32(wx, WX_PX_ISB_ADDR_H, upper_32_bits(wx->isb_dma));
}

void wx_configure(struct wx *wx)
{
	wx_set_rxpba(wx);
	wx_pbthresh_setup(wx);
	wx_configure_port(wx);

	wx_set_rx_mode(wx->netdev);
	wx_restore_vlan(wx);
	wx_enable_sec_rx_path(wx);

	wx_configure_tx(wx);
	wx_configure_rx(wx);
	wx_configure_isb(wx);
}
EXPORT_SYMBOL(wx_configure);

/**
 *  wx_disable_pcie_master - Disable PCI-express master access
 *  @wx: pointer to hardware structure
 *
 *  Disables PCI-Express master access and verifies there are no pending
 *  requests.
 **/
int wx_disable_pcie_master(struct wx *wx)
{
	int status = 0;
	u32 val;

	/* Always set this bit to ensure any future transactions are blocked */
	pci_clear_master(wx->pdev);

	/* Exit if master requests are blocked */
	if (!(rd32(wx, WX_PX_TRANSACTION_PENDING)))
		return 0;

	/* Poll for master request bit to clear */
	status = read_poll_timeout(rd32, val, !val, 100, WX_PCI_MASTER_DISABLE_TIMEOUT,
				   false, wx, WX_PX_TRANSACTION_PENDING);
	if (status < 0)
		wx_err(wx, "PCIe transaction pending bit did not clear.\n");

	return status;
}
EXPORT_SYMBOL(wx_disable_pcie_master);

/**
 *  wx_stop_adapter - Generic stop Tx/Rx units
 *  @wx: pointer to hardware structure
 *
 *  Sets the adapter_stopped flag within wx_hw struct. Clears interrupts,
 *  disables transmit and receive units. The adapter_stopped flag is used by
 *  the shared code and drivers to determine if the adapter is in a stopped
 *  state and should not touch the hardware.
 **/
int wx_stop_adapter(struct wx *wx)
{
	u16 i;

	/* Set the adapter_stopped flag so other driver functions stop touching
	 * the hardware
	 */
	wx->adapter_stopped = true;

	/* Disable the receive unit */
	wx_disable_rx(wx);

	/* Set interrupt mask to stop interrupts from being generated */
	wx_intr_disable(wx, WX_INTR_ALL);

	/* Clear any pending interrupts, flush previous writes */
	wr32(wx, WX_PX_MISC_IC, 0xffffffff);
	wr32(wx, WX_BME_CTL, 0x3);

	/* Disable the transmit unit.  Each queue must be disabled. */
	for (i = 0; i < wx->mac.max_tx_queues; i++) {
		wr32m(wx, WX_PX_TR_CFG(i),
		      WX_PX_TR_CFG_SWFLSH | WX_PX_TR_CFG_ENABLE,
		      WX_PX_TR_CFG_SWFLSH);
	}

	/* Disable the receive unit by stopping each queue */
	for (i = 0; i < wx->mac.max_rx_queues; i++) {
		wr32m(wx, WX_PX_RR_CFG(i),
		      WX_PX_RR_CFG_RR_EN, 0);
	}

	/* flush all queues disables */
	WX_WRITE_FLUSH(wx);

	/* Prevent the PCI-E bus from hanging by disabling PCI-E master
	 * access and verify no pending requests
	 */
	return wx_disable_pcie_master(wx);
}
EXPORT_SYMBOL(wx_stop_adapter);

void wx_reset_misc(struct wx *wx)
{
	int i;

	/* receive packets that size > 2048 */
	wr32m(wx, WX_MAC_RX_CFG, WX_MAC_RX_CFG_JE, WX_MAC_RX_CFG_JE);

	/* clear counters on read */
	wr32m(wx, WX_MMC_CONTROL,
	      WX_MMC_CONTROL_RSTONRD, WX_MMC_CONTROL_RSTONRD);

	wr32m(wx, WX_MAC_RX_FLOW_CTRL,
	      WX_MAC_RX_FLOW_CTRL_RFE, WX_MAC_RX_FLOW_CTRL_RFE);

	wr32(wx, WX_MAC_PKT_FLT, WX_MAC_PKT_FLT_PR);

	wr32m(wx, WX_MIS_RST_ST,
	      WX_MIS_RST_ST_RST_INIT, 0x1E00);

	/* errata 4: initialize mng flex tbl and wakeup flex tbl*/
	wr32(wx, WX_PSR_MNG_FLEX_SEL, 0);
	for (i = 0; i < 16; i++) {
		wr32(wx, WX_PSR_MNG_FLEX_DW_L(i), 0);
		wr32(wx, WX_PSR_MNG_FLEX_DW_H(i), 0);
		wr32(wx, WX_PSR_MNG_FLEX_MSK(i), 0);
	}
	wr32(wx, WX_PSR_LAN_FLEX_SEL, 0);
	for (i = 0; i < 16; i++) {
		wr32(wx, WX_PSR_LAN_FLEX_DW_L(i), 0);
		wr32(wx, WX_PSR_LAN_FLEX_DW_H(i), 0);
		wr32(wx, WX_PSR_LAN_FLEX_MSK(i), 0);
	}

	/* set pause frame dst mac addr */
	wr32(wx, WX_RDB_PFCMACDAL, 0xC2000001);
	wr32(wx, WX_RDB_PFCMACDAH, 0x0180);
}
EXPORT_SYMBOL(wx_reset_misc);

/**
 *  wx_get_pcie_msix_counts - Gets MSI-X vector count
 *  @wx: pointer to hardware structure
 *  @msix_count: number of MSI interrupts that can be obtained
 *  @max_msix_count: number of MSI interrupts that mac need
 *
 *  Read PCIe configuration space, and get the MSI-X vector count from
 *  the capabilities table.
 **/
int wx_get_pcie_msix_counts(struct wx *wx, u16 *msix_count, u16 max_msix_count)
{
	struct pci_dev *pdev = wx->pdev;
	struct device *dev = &pdev->dev;
	int pos;

	*msix_count = 1;
	pos = pci_find_capability(pdev, PCI_CAP_ID_MSIX);
	if (!pos) {
		dev_err(dev, "Unable to find MSI-X Capabilities\n");
		return -EINVAL;
	}
	pci_read_config_word(pdev,
			     pos + PCI_MSIX_FLAGS,
			     msix_count);
	*msix_count &= WX_PCIE_MSIX_TBL_SZ_MASK;
	/* MSI-X count is zero-based in HW */
	*msix_count += 1;

	if (*msix_count > max_msix_count)
		*msix_count = max_msix_count;

	return 0;
}
EXPORT_SYMBOL(wx_get_pcie_msix_counts);

/**
 * wx_init_rss_key - Initialize wx RSS key
 * @wx: device handle
 *
 * Allocates and initializes the RSS key if it is not allocated.
 **/
static int wx_init_rss_key(struct wx *wx)
{
	u32 *rss_key;

	if (!wx->rss_key) {
		rss_key = kzalloc(WX_RSS_KEY_SIZE, GFP_KERNEL);
		if (unlikely(!rss_key))
			return -ENOMEM;

		netdev_rss_key_fill(rss_key, WX_RSS_KEY_SIZE);
		wx->rss_key = rss_key;
	}

	return 0;
}

int wx_sw_init(struct wx *wx)
{
	struct pci_dev *pdev = wx->pdev;
	u32 ssid = 0;
	int err = 0;

	wx->vendor_id = pdev->vendor;
	wx->device_id = pdev->device;
	wx->revision_id = pdev->revision;
	wx->oem_svid = pdev->subsystem_vendor;
	wx->oem_ssid = pdev->subsystem_device;
	wx->bus.device = PCI_SLOT(pdev->devfn);
	wx->bus.func = PCI_FUNC(pdev->devfn);

	if (wx->oem_svid == PCI_VENDOR_ID_WANGXUN) {
		wx->subsystem_vendor_id = pdev->subsystem_vendor;
		wx->subsystem_device_id = pdev->subsystem_device;
	} else {
		err = wx_flash_read_dword(wx, 0xfffdc, &ssid);
		if (err < 0) {
			wx_err(wx, "read of internal subsystem device id failed\n");
			return err;
		}

		wx->subsystem_device_id = swab16((u16)ssid);
	}

	err = wx_init_rss_key(wx);
	if (err < 0) {
		wx_err(wx, "rss key allocation failed\n");
		return err;
	}

	wx->mac_table = kcalloc(wx->mac.num_rar_entries,
				sizeof(struct wx_mac_addr),
				GFP_KERNEL);
	if (!wx->mac_table) {
		wx_err(wx, "mac_table allocation failed\n");
		kfree(wx->rss_key);
		return -ENOMEM;
	}

	return 0;
}
EXPORT_SYMBOL(wx_sw_init);

/**
 *  wx_find_vlvf_slot - find the vlanid or the first empty slot
 *  @wx: pointer to hardware structure
 *  @vlan: VLAN id to write to VLAN filter
 *
 *  return the VLVF index where this VLAN id should be placed
 *
 **/
static int wx_find_vlvf_slot(struct wx *wx, u32 vlan)
{
	u32 bits = 0, first_empty_slot = 0;
	int regindex;

	/* short cut the special case */
	if (vlan == 0)
		return 0;

	/* Search for the vlan id in the VLVF entries. Save off the first empty
	 * slot found along the way
	 */
	for (regindex = 1; regindex < WX_PSR_VLAN_SWC_ENTRIES; regindex++) {
		wr32(wx, WX_PSR_VLAN_SWC_IDX, regindex);
		bits = rd32(wx, WX_PSR_VLAN_SWC);
		if (!bits && !(first_empty_slot))
			first_empty_slot = regindex;
		else if ((bits & 0x0FFF) == vlan)
			break;
	}

	if (regindex >= WX_PSR_VLAN_SWC_ENTRIES) {
		if (first_empty_slot)
			regindex = first_empty_slot;
		else
			regindex = -ENOMEM;
	}

	return regindex;
}

/**
 *  wx_set_vlvf - Set VLAN Pool Filter
 *  @wx: pointer to hardware structure
 *  @vlan: VLAN id to write to VLAN filter
 *  @vind: VMDq output index that maps queue to VLAN id in VFVFB
 *  @vlan_on: boolean flag to turn on/off VLAN in VFVF
 *  @vfta_changed: pointer to boolean flag which indicates whether VFTA
 *                 should be changed
 *
 *  Turn on/off specified bit in VLVF table.
 **/
static int wx_set_vlvf(struct wx *wx, u32 vlan, u32 vind, bool vlan_on,
		       bool *vfta_changed)
{
	int vlvf_index;
	u32 vt, bits;

	/* If VT Mode is set
	 *   Either vlan_on
	 *     make sure the vlan is in VLVF
	 *     set the vind bit in the matching VLVFB
	 *   Or !vlan_on
	 *     clear the pool bit and possibly the vind
	 */
	vt = rd32(wx, WX_CFG_PORT_CTL);
	if (!(vt & WX_CFG_PORT_CTL_NUM_VT_MASK))
		return 0;

	vlvf_index = wx_find_vlvf_slot(wx, vlan);
	if (vlvf_index < 0)
		return vlvf_index;

	wr32(wx, WX_PSR_VLAN_SWC_IDX, vlvf_index);
	if (vlan_on) {
		/* set the pool bit */
		if (vind < 32) {
			bits = rd32(wx, WX_PSR_VLAN_SWC_VM_L);
			bits |= (1 << vind);
			wr32(wx, WX_PSR_VLAN_SWC_VM_L, bits);
		} else {
			bits = rd32(wx, WX_PSR_VLAN_SWC_VM_H);
			bits |= (1 << (vind - 32));
			wr32(wx, WX_PSR_VLAN_SWC_VM_H, bits);
		}
	} else {
		/* clear the pool bit */
		if (vind < 32) {
			bits = rd32(wx, WX_PSR_VLAN_SWC_VM_L);
			bits &= ~(1 << vind);
			wr32(wx, WX_PSR_VLAN_SWC_VM_L, bits);
			bits |= rd32(wx, WX_PSR_VLAN_SWC_VM_H);
		} else {
			bits = rd32(wx, WX_PSR_VLAN_SWC_VM_H);
			bits &= ~(1 << (vind - 32));
			wr32(wx, WX_PSR_VLAN_SWC_VM_H, bits);
			bits |= rd32(wx, WX_PSR_VLAN_SWC_VM_L);
		}
	}

	if (bits) {
		wr32(wx, WX_PSR_VLAN_SWC, (WX_PSR_VLAN_SWC_VIEN | vlan));
		if (!vlan_on && vfta_changed)
			*vfta_changed = false;
	} else {
		wr32(wx, WX_PSR_VLAN_SWC, 0);
	}

	return 0;
}

/**
 *  wx_set_vfta - Set VLAN filter table
 *  @wx: pointer to hardware structure
 *  @vlan: VLAN id to write to VLAN filter
 *  @vind: VMDq output index that maps queue to VLAN id in VFVFB
 *  @vlan_on: boolean flag to turn on/off VLAN in VFVF
 *
 *  Turn on/off specified VLAN in the VLAN filter table.
 **/
static int wx_set_vfta(struct wx *wx, u32 vlan, u32 vind, bool vlan_on)
{
	u32 bitindex, vfta, targetbit;
	bool vfta_changed = false;
	int regindex, ret;

	/* this is a 2 part operation - first the VFTA, then the
	 * VLVF and VLVFB if VT Mode is set
	 * We don't write the VFTA until we know the VLVF part succeeded.
	 */

	/* Part 1
	 * The VFTA is a bitstring made up of 128 32-bit registers
	 * that enable the particular VLAN id, much like the MTA:
	 *    bits[11-5]: which register
	 *    bits[4-0]:  which bit in the register
	 */
	regindex = (vlan >> 5) & 0x7F;
	bitindex = vlan & 0x1F;
	targetbit = (1 << bitindex);
	/* errata 5 */
	vfta = wx->mac.vft_shadow[regindex];
	if (vlan_on) {
		if (!(vfta & targetbit)) {
			vfta |= targetbit;
			vfta_changed = true;
		}
	} else {
		if ((vfta & targetbit)) {
			vfta &= ~targetbit;
			vfta_changed = true;
		}
	}
	/* Part 2
	 * Call wx_set_vlvf to set VLVFB and VLVF
	 */
	ret = wx_set_vlvf(wx, vlan, vind, vlan_on, &vfta_changed);
	if (ret != 0)
		return ret;

	if (vfta_changed)
		wr32(wx, WX_PSR_VLAN_TBL(regindex), vfta);
	wx->mac.vft_shadow[regindex] = vfta;

	return 0;
}

/**
 *  wx_clear_vfta - Clear VLAN filter table
 *  @wx: pointer to hardware structure
 *
 *  Clears the VLAN filer table, and the VMDq index associated with the filter
 **/
static void wx_clear_vfta(struct wx *wx)
{
	u32 offset;

	for (offset = 0; offset < wx->mac.vft_size; offset++) {
		wr32(wx, WX_PSR_VLAN_TBL(offset), 0);
		wx->mac.vft_shadow[offset] = 0;
	}

	for (offset = 0; offset < WX_PSR_VLAN_SWC_ENTRIES; offset++) {
		wr32(wx, WX_PSR_VLAN_SWC_IDX, offset);
		wr32(wx, WX_PSR_VLAN_SWC, 0);
		wr32(wx, WX_PSR_VLAN_SWC_VM_L, 0);
		wr32(wx, WX_PSR_VLAN_SWC_VM_H, 0);
	}
}

int wx_vlan_rx_add_vid(struct net_device *netdev,
		       __be16 proto, u16 vid)
{
	struct wx *wx = netdev_priv(netdev);

	/* add VID to filter table */
	wx_set_vfta(wx, vid, VMDQ_P(0), true);
	set_bit(vid, wx->active_vlans);

	return 0;
}
EXPORT_SYMBOL(wx_vlan_rx_add_vid);

int wx_vlan_rx_kill_vid(struct net_device *netdev, __be16 proto, u16 vid)
{
	struct wx *wx = netdev_priv(netdev);

	/* remove VID from filter table */
	if (vid)
		wx_set_vfta(wx, vid, VMDQ_P(0), false);
	clear_bit(vid, wx->active_vlans);

	return 0;
}
EXPORT_SYMBOL(wx_vlan_rx_kill_vid);

static void wx_enable_rx_drop(struct wx *wx, struct wx_ring *ring)
{
	u16 reg_idx = ring->reg_idx;
	u32 srrctl;

	srrctl = rd32(wx, WX_PX_RR_CFG(reg_idx));
	srrctl |= WX_PX_RR_CFG_DROP_EN;

	wr32(wx, WX_PX_RR_CFG(reg_idx), srrctl);
}

static void wx_disable_rx_drop(struct wx *wx, struct wx_ring *ring)
{
	u16 reg_idx = ring->reg_idx;
	u32 srrctl;

	srrctl = rd32(wx, WX_PX_RR_CFG(reg_idx));
	srrctl &= ~WX_PX_RR_CFG_DROP_EN;

	wr32(wx, WX_PX_RR_CFG(reg_idx), srrctl);
}

int wx_fc_enable(struct wx *wx, bool tx_pause, bool rx_pause)
{
	u16 pause_time = WX_DEFAULT_FCPAUSE;
	u32 mflcn_reg, fccfg_reg, reg;
	u32 fcrtl, fcrth;
	int i;

	/* Low water mark of zero causes XOFF floods */
	if (tx_pause && wx->fc.high_water) {
		if (!wx->fc.low_water || wx->fc.low_water >= wx->fc.high_water) {
			wx_err(wx, "Invalid water mark configuration\n");
			return -EINVAL;
		}
	}

	/* Disable any previous flow control settings */
	mflcn_reg = rd32(wx, WX_MAC_RX_FLOW_CTRL);
	mflcn_reg &= ~WX_MAC_RX_FLOW_CTRL_RFE;

	fccfg_reg = rd32(wx, WX_RDB_RFCC);
	fccfg_reg &= ~WX_RDB_RFCC_RFCE_802_3X;

	if (rx_pause)
		mflcn_reg |= WX_MAC_RX_FLOW_CTRL_RFE;
	if (tx_pause)
		fccfg_reg |= WX_RDB_RFCC_RFCE_802_3X;

	/* Set 802.3x based flow control settings. */
	wr32(wx, WX_MAC_RX_FLOW_CTRL, mflcn_reg);
	wr32(wx, WX_RDB_RFCC, fccfg_reg);

	/* Set up and enable Rx high/low water mark thresholds, enable XON. */
	if (tx_pause && wx->fc.high_water) {
		fcrtl = (wx->fc.low_water << 10) | WX_RDB_RFCL_XONE;
		wr32(wx, WX_RDB_RFCL, fcrtl);
		fcrth = (wx->fc.high_water << 10) | WX_RDB_RFCH_XOFFE;
	} else {
		wr32(wx, WX_RDB_RFCL, 0);
		/* In order to prevent Tx hangs when the internal Tx
		 * switch is enabled we must set the high water mark
		 * to the Rx packet buffer size - 24KB.  This allows
		 * the Tx switch to function even under heavy Rx
		 * workloads.
		 */
		fcrth = rd32(wx, WX_RDB_PB_SZ(0)) - 24576;
	}

	wr32(wx, WX_RDB_RFCH, fcrth);

	/* Configure pause time */
	reg = pause_time * 0x00010001;
	wr32(wx, WX_RDB_RFCV, reg);

	/* Configure flow control refresh threshold value */
	wr32(wx, WX_RDB_RFCRT, pause_time / 2);

	/*  We should set the drop enable bit if:
	 *  Number of Rx queues > 1 and flow control is disabled
	 *
	 *  This allows us to avoid head of line blocking for security
	 *  and performance reasons.
	 */
	if (wx->num_rx_queues > 1 && !tx_pause) {
		for (i = 0; i < wx->num_rx_queues; i++)
			wx_enable_rx_drop(wx, wx->rx_ring[i]);
	} else {
		for (i = 0; i < wx->num_rx_queues; i++)
			wx_disable_rx_drop(wx, wx->rx_ring[i]);
	}

	return 0;
}
EXPORT_SYMBOL(wx_fc_enable);

/**
 * wx_update_stats - Update the board statistics counters.
 * @wx: board private structure
 **/
void wx_update_stats(struct wx *wx)
{
	struct wx_hw_stats *hwstats = &wx->stats;

	u64 non_eop_descs = 0, alloc_rx_buff_failed = 0;
	u64 hw_csum_rx_good = 0, hw_csum_rx_error = 0;
	u64 restart_queue = 0, tx_busy = 0;
	u32 i;

	/* gather some stats to the wx struct that are per queue */
	for (i = 0; i < wx->num_rx_queues; i++) {
		struct wx_ring *rx_ring = wx->rx_ring[i];

		non_eop_descs += rx_ring->rx_stats.non_eop_descs;
		alloc_rx_buff_failed += rx_ring->rx_stats.alloc_rx_buff_failed;
		hw_csum_rx_good += rx_ring->rx_stats.csum_good_cnt;
		hw_csum_rx_error += rx_ring->rx_stats.csum_err;
	}
	wx->non_eop_descs = non_eop_descs;
	wx->alloc_rx_buff_failed = alloc_rx_buff_failed;
	wx->hw_csum_rx_error = hw_csum_rx_error;
	wx->hw_csum_rx_good = hw_csum_rx_good;

	for (i = 0; i < wx->num_tx_queues; i++) {
		struct wx_ring *tx_ring = wx->tx_ring[i];

		restart_queue += tx_ring->tx_stats.restart_queue;
		tx_busy += tx_ring->tx_stats.tx_busy;
	}
	wx->restart_queue = restart_queue;
	wx->tx_busy = tx_busy;

	hwstats->gprc += rd32(wx, WX_RDM_PKT_CNT);
	hwstats->gptc += rd32(wx, WX_TDM_PKT_CNT);
	hwstats->gorc += rd64(wx, WX_RDM_BYTE_CNT_LSB);
	hwstats->gotc += rd64(wx, WX_TDM_BYTE_CNT_LSB);
	hwstats->tpr += rd64(wx, WX_RX_FRAME_CNT_GOOD_BAD_L);
	hwstats->tpt += rd64(wx, WX_TX_FRAME_CNT_GOOD_BAD_L);
	hwstats->crcerrs += rd64(wx, WX_RX_CRC_ERROR_FRAMES_L);
	hwstats->rlec += rd64(wx, WX_RX_LEN_ERROR_FRAMES_L);
	hwstats->bprc += rd64(wx, WX_RX_BC_FRAMES_GOOD_L);
	hwstats->bptc += rd64(wx, WX_TX_BC_FRAMES_GOOD_L);
	hwstats->mprc += rd64(wx, WX_RX_MC_FRAMES_GOOD_L);
	hwstats->mptc += rd64(wx, WX_TX_MC_FRAMES_GOOD_L);
	hwstats->roc += rd32(wx, WX_RX_OVERSIZE_FRAMES_GOOD);
	hwstats->ruc += rd32(wx, WX_RX_UNDERSIZE_FRAMES_GOOD);
	hwstats->lxonoffrxc += rd32(wx, WX_MAC_LXONOFFRXC);
	hwstats->lxontxc += rd32(wx, WX_RDB_LXONTXC);
	hwstats->lxofftxc += rd32(wx, WX_RDB_LXOFFTXC);
	hwstats->o2bgptc += rd32(wx, WX_TDM_OS2BMC_CNT);
	hwstats->b2ospc += rd32(wx, WX_MNG_BMC2OS_CNT);
	hwstats->o2bspc += rd32(wx, WX_MNG_OS2BMC_CNT);
	hwstats->b2ogprc += rd32(wx, WX_RDM_BMC2OS_CNT);
	hwstats->rdmdrop += rd32(wx, WX_RDM_DRP_PKT);

	for (i = 0; i < wx->mac.max_rx_queues; i++)
		hwstats->qmprc += rd32(wx, WX_PX_MPRC(i));
}
EXPORT_SYMBOL(wx_update_stats);

/**
 *  wx_clear_hw_cntrs - Generic clear hardware counters
 *  @wx: board private structure
 *
 *  Clears all hardware statistics counters by reading them from the hardware
 *  Statistics counters are clear on read.
 **/
void wx_clear_hw_cntrs(struct wx *wx)
{
	u16 i = 0;

	for (i = 0; i < wx->mac.max_rx_queues; i++)
		wr32(wx, WX_PX_MPRC(i), 0);

	rd32(wx, WX_RDM_PKT_CNT);
	rd32(wx, WX_TDM_PKT_CNT);
	rd64(wx, WX_RDM_BYTE_CNT_LSB);
	rd32(wx, WX_TDM_BYTE_CNT_LSB);
	rd32(wx, WX_RDM_DRP_PKT);
	rd32(wx, WX_RX_UNDERSIZE_FRAMES_GOOD);
	rd32(wx, WX_RX_OVERSIZE_FRAMES_GOOD);
	rd64(wx, WX_RX_FRAME_CNT_GOOD_BAD_L);
	rd64(wx, WX_TX_FRAME_CNT_GOOD_BAD_L);
	rd64(wx, WX_RX_MC_FRAMES_GOOD_L);
	rd64(wx, WX_TX_MC_FRAMES_GOOD_L);
	rd64(wx, WX_RX_BC_FRAMES_GOOD_L);
	rd64(wx, WX_TX_BC_FRAMES_GOOD_L);
	rd64(wx, WX_RX_CRC_ERROR_FRAMES_L);
	rd64(wx, WX_RX_LEN_ERROR_FRAMES_L);
	rd32(wx, WX_RDB_LXONTXC);
	rd32(wx, WX_RDB_LXOFFTXC);
	rd32(wx, WX_MAC_LXONOFFRXC);
}
EXPORT_SYMBOL(wx_clear_hw_cntrs);

/**
 *  wx_start_hw - Prepare hardware for Tx/Rx
 *  @wx: pointer to hardware structure
 *
 *  Starts the hardware using the generic start_hw function
 *  and the generation start_hw function.
 *  Then performs revision-specific operations, if any.
 **/
void wx_start_hw(struct wx *wx)
{
	int i;

	/* Clear the VLAN filter table */
	wx_clear_vfta(wx);
	WX_WRITE_FLUSH(wx);
	/* Clear the rate limiters */
	for (i = 0; i < wx->mac.max_tx_queues; i++) {
		wr32(wx, WX_TDM_RP_IDX, i);
		wr32(wx, WX_TDM_RP_RATE, 0);
	}
}
EXPORT_SYMBOL(wx_start_hw);

MODULE_LICENSE("GPL");
