/*
 * Copyright (C) 2003 - 2009 NetXen, Inc.
 * All rights reserved.
 *
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public License
 * as published by the Free Software Foundation; either version 2
 * of the License, or (at your option) any later version.
 *
 * This program is distributed in the hope that 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.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place - Suite 330, Boston,
 * MA  02111-1307, USA.
 *
 * The full GNU General Public License is included in this distribution
 * in the file called LICENSE.
 *
 * Contact Information:
 *    info@netxen.com
 * NetXen Inc,
 * 18922 Forge Drive
 * Cupertino, CA 95014-0701
 *
 */

#include "netxen_nic.h"
#include "netxen_nic_hw.h"
#include "netxen_nic_phan_reg.h"

#include <net/ip.h>

#define MASK(n) ((1ULL<<(n))-1)
#define MN_WIN(addr) (((addr & 0x1fc0000) >> 1) | ((addr >> 25) & 0x3ff))
#define OCM_WIN(addr) (((addr & 0x1ff0000) >> 1) | ((addr >> 25) & 0x3ff))
#define MS_WIN(addr) (addr & 0x0ffc0000)

#define GET_MEM_OFFS_2M(addr) (addr & MASK(18))

#define CRB_BLK(off)	((off >> 20) & 0x3f)
#define CRB_SUBBLK(off)	((off >> 16) & 0xf)
#define CRB_WINDOW_2M	(0x130060)
#define CRB_HI(off)	((crb_hub_agt[CRB_BLK(off)] << 20) | ((off) & 0xf0000))
#define CRB_INDIRECT_2M	(0x1e0000UL)

#ifndef readq
static inline u64 readq(void __iomem *addr)
{
	return readl(addr) | (((u64) readl(addr + 4)) << 32LL);
}
#endif

#ifndef writeq
static inline void writeq(u64 val, void __iomem *addr)
{
	writel(((u32) (val)), (addr));
	writel(((u32) (val >> 32)), (addr + 4));
}
#endif

#define ADDR_IN_RANGE(addr, low, high)	\
	(((addr) < (high)) && ((addr) >= (low)))

#define PCI_OFFSET_FIRST_RANGE(adapter, off)    \
	((adapter)->ahw.pci_base0 + (off))
#define PCI_OFFSET_SECOND_RANGE(adapter, off)   \
	((adapter)->ahw.pci_base1 + (off) - SECOND_PAGE_GROUP_START)
#define PCI_OFFSET_THIRD_RANGE(adapter, off)    \
	((adapter)->ahw.pci_base2 + (off) - THIRD_PAGE_GROUP_START)

static void __iomem *pci_base_offset(struct netxen_adapter *adapter,
					    unsigned long off)
{
	if (ADDR_IN_RANGE(off, FIRST_PAGE_GROUP_START, FIRST_PAGE_GROUP_END))
		return PCI_OFFSET_FIRST_RANGE(adapter, off);

	if (ADDR_IN_RANGE(off, SECOND_PAGE_GROUP_START, SECOND_PAGE_GROUP_END))
		return PCI_OFFSET_SECOND_RANGE(adapter, off);

	if (ADDR_IN_RANGE(off, THIRD_PAGE_GROUP_START, THIRD_PAGE_GROUP_END))
		return PCI_OFFSET_THIRD_RANGE(adapter, off);

	return NULL;
}

#define CRB_WIN_LOCK_TIMEOUT 100000000
static crb_128M_2M_block_map_t
crb_128M_2M_map[64] __cacheline_aligned_in_smp = {
    {{{0, 0,         0,         0} } },		/* 0: PCI */
    {{{1, 0x0100000, 0x0102000, 0x120000},	/* 1: PCIE */
	  {1, 0x0110000, 0x0120000, 0x130000},
	  {1, 0x0120000, 0x0122000, 0x124000},
	  {1, 0x0130000, 0x0132000, 0x126000},
	  {1, 0x0140000, 0x0142000, 0x128000},
	  {1, 0x0150000, 0x0152000, 0x12a000},
	  {1, 0x0160000, 0x0170000, 0x110000},
	  {1, 0x0170000, 0x0172000, 0x12e000},
	  {0, 0x0000000, 0x0000000, 0x000000},
	  {0, 0x0000000, 0x0000000, 0x000000},
	  {0, 0x0000000, 0x0000000, 0x000000},
	  {0, 0x0000000, 0x0000000, 0x000000},
	  {0, 0x0000000, 0x0000000, 0x000000},
	  {0, 0x0000000, 0x0000000, 0x000000},
	  {1, 0x01e0000, 0x01e0800, 0x122000},
	  {0, 0x0000000, 0x0000000, 0x000000} } },
	{{{1, 0x0200000, 0x0210000, 0x180000} } },/* 2: MN */
    {{{0, 0,         0,         0} } },	    /* 3: */
    {{{1, 0x0400000, 0x0401000, 0x169000} } },/* 4: P2NR1 */
    {{{1, 0x0500000, 0x0510000, 0x140000} } },/* 5: SRE   */
    {{{1, 0x0600000, 0x0610000, 0x1c0000} } },/* 6: NIU   */
    {{{1, 0x0700000, 0x0704000, 0x1b8000} } },/* 7: QM    */
    {{{1, 0x0800000, 0x0802000, 0x170000},  /* 8: SQM0  */
      {0, 0x0000000, 0x0000000, 0x000000},
      {0, 0x0000000, 0x0000000, 0x000000},
      {0, 0x0000000, 0x0000000, 0x000000},
      {0, 0x0000000, 0x0000000, 0x000000},
      {0, 0x0000000, 0x0000000, 0x000000},
      {0, 0x0000000, 0x0000000, 0x000000},
      {0, 0x0000000, 0x0000000, 0x000000},
      {0, 0x0000000, 0x0000000, 0x000000},
      {0, 0x0000000, 0x0000000, 0x000000},
      {0, 0x0000000, 0x0000000, 0x000000},
      {0, 0x0000000, 0x0000000, 0x000000},
      {0, 0x0000000, 0x0000000, 0x000000},
      {0, 0x0000000, 0x0000000, 0x000000},
      {0, 0x0000000, 0x0000000, 0x000000},
      {1, 0x08f0000, 0x08f2000, 0x172000} } },
    {{{1, 0x0900000, 0x0902000, 0x174000},	/* 9: SQM1*/
      {0, 0x0000000, 0x0000000, 0x000000},
      {0, 0x0000000, 0x0000000, 0x000000},
      {0, 0x0000000, 0x0000000, 0x000000},
      {0, 0x0000000, 0x0000000, 0x000000},
      {0, 0x0000000, 0x0000000, 0x000000},
      {0, 0x0000000, 0x0000000, 0x000000},
      {0, 0x0000000, 0x0000000, 0x000000},
      {0, 0x0000000, 0x0000000, 0x000000},
      {0, 0x0000000, 0x0000000, 0x000000},
      {0, 0x0000000, 0x0000000, 0x000000},
      {0, 0x0000000, 0x0000000, 0x000000},
      {0, 0x0000000, 0x0000000, 0x000000},
      {0, 0x0000000, 0x0000000, 0x000000},
      {0, 0x0000000, 0x0000000, 0x000000},
      {1, 0x09f0000, 0x09f2000, 0x176000} } },
    {{{0, 0x0a00000, 0x0a02000, 0x178000},	/* 10: SQM2*/
      {0, 0x0000000, 0x0000000, 0x000000},
      {0, 0x0000000, 0x0000000, 0x000000},
      {0, 0x0000000, 0x0000000, 0x000000},
      {0, 0x0000000, 0x0000000, 0x000000},
      {0, 0x0000000, 0x0000000, 0x000000},
      {0, 0x0000000, 0x0000000, 0x000000},
      {0, 0x0000000, 0x0000000, 0x000000},
      {0, 0x0000000, 0x0000000, 0x000000},
      {0, 0x0000000, 0x0000000, 0x000000},
      {0, 0x0000000, 0x0000000, 0x000000},
      {0, 0x0000000, 0x0000000, 0x000000},
      {0, 0x0000000, 0x0000000, 0x000000},
      {0, 0x0000000, 0x0000000, 0x000000},
      {0, 0x0000000, 0x0000000, 0x000000},
      {1, 0x0af0000, 0x0af2000, 0x17a000} } },
    {{{0, 0x0b00000, 0x0b02000, 0x17c000},	/* 11: SQM3*/
      {0, 0x0000000, 0x0000000, 0x000000},
      {0, 0x0000000, 0x0000000, 0x000000},
      {0, 0x0000000, 0x0000000, 0x000000},
      {0, 0x0000000, 0x0000000, 0x000000},
      {0, 0x0000000, 0x0000000, 0x000000},
      {0, 0x0000000, 0x0000000, 0x000000},
      {0, 0x0000000, 0x0000000, 0x000000},
      {0, 0x0000000, 0x0000000, 0x000000},
      {0, 0x0000000, 0x0000000, 0x000000},
      {0, 0x0000000, 0x0000000, 0x000000},
      {0, 0x0000000, 0x0000000, 0x000000},
      {0, 0x0000000, 0x0000000, 0x000000},
      {0, 0x0000000, 0x0000000, 0x000000},
      {0, 0x0000000, 0x0000000, 0x000000},
      {1, 0x0bf0000, 0x0bf2000, 0x17e000} } },
	{{{1, 0x0c00000, 0x0c04000, 0x1d4000} } },/* 12: I2Q */
	{{{1, 0x0d00000, 0x0d04000, 0x1a4000} } },/* 13: TMR */
	{{{1, 0x0e00000, 0x0e04000, 0x1a0000} } },/* 14: ROMUSB */
	{{{1, 0x0f00000, 0x0f01000, 0x164000} } },/* 15: PEG4 */
	{{{0, 0x1000000, 0x1004000, 0x1a8000} } },/* 16: XDMA */
	{{{1, 0x1100000, 0x1101000, 0x160000} } },/* 17: PEG0 */
	{{{1, 0x1200000, 0x1201000, 0x161000} } },/* 18: PEG1 */
	{{{1, 0x1300000, 0x1301000, 0x162000} } },/* 19: PEG2 */
	{{{1, 0x1400000, 0x1401000, 0x163000} } },/* 20: PEG3 */
	{{{1, 0x1500000, 0x1501000, 0x165000} } },/* 21: P2ND */
	{{{1, 0x1600000, 0x1601000, 0x166000} } },/* 22: P2NI */
	{{{0, 0,         0,         0} } },	/* 23: */
	{{{0, 0,         0,         0} } },	/* 24: */
	{{{0, 0,         0,         0} } },	/* 25: */
	{{{0, 0,         0,         0} } },	/* 26: */
	{{{0, 0,         0,         0} } },	/* 27: */
	{{{0, 0,         0,         0} } },	/* 28: */
	{{{1, 0x1d00000, 0x1d10000, 0x190000} } },/* 29: MS */
    {{{1, 0x1e00000, 0x1e01000, 0x16a000} } },/* 30: P2NR2 */
    {{{1, 0x1f00000, 0x1f10000, 0x150000} } },/* 31: EPG */
	{{{0} } },				/* 32: PCI */
	{{{1, 0x2100000, 0x2102000, 0x120000},	/* 33: PCIE */
	  {1, 0x2110000, 0x2120000, 0x130000},
	  {1, 0x2120000, 0x2122000, 0x124000},
	  {1, 0x2130000, 0x2132000, 0x126000},
	  {1, 0x2140000, 0x2142000, 0x128000},
	  {1, 0x2150000, 0x2152000, 0x12a000},
	  {1, 0x2160000, 0x2170000, 0x110000},
	  {1, 0x2170000, 0x2172000, 0x12e000},
	  {0, 0x0000000, 0x0000000, 0x000000},
	  {0, 0x0000000, 0x0000000, 0x000000},
	  {0, 0x0000000, 0x0000000, 0x000000},
	  {0, 0x0000000, 0x0000000, 0x000000},
	  {0, 0x0000000, 0x0000000, 0x000000},
	  {0, 0x0000000, 0x0000000, 0x000000},
	  {0, 0x0000000, 0x0000000, 0x000000},
	  {0, 0x0000000, 0x0000000, 0x000000} } },
	{{{1, 0x2200000, 0x2204000, 0x1b0000} } },/* 34: CAM */
	{{{0} } },				/* 35: */
	{{{0} } },				/* 36: */
	{{{0} } },				/* 37: */
	{{{0} } },				/* 38: */
	{{{0} } },				/* 39: */
	{{{1, 0x2800000, 0x2804000, 0x1a4000} } },/* 40: TMR */
	{{{1, 0x2900000, 0x2901000, 0x16b000} } },/* 41: P2NR3 */
	{{{1, 0x2a00000, 0x2a00400, 0x1ac400} } },/* 42: RPMX1 */
	{{{1, 0x2b00000, 0x2b00400, 0x1ac800} } },/* 43: RPMX2 */
	{{{1, 0x2c00000, 0x2c00400, 0x1acc00} } },/* 44: RPMX3 */
	{{{1, 0x2d00000, 0x2d00400, 0x1ad000} } },/* 45: RPMX4 */
	{{{1, 0x2e00000, 0x2e00400, 0x1ad400} } },/* 46: RPMX5 */
	{{{1, 0x2f00000, 0x2f00400, 0x1ad800} } },/* 47: RPMX6 */
	{{{1, 0x3000000, 0x3000400, 0x1adc00} } },/* 48: RPMX7 */
	{{{0, 0x3100000, 0x3104000, 0x1a8000} } },/* 49: XDMA */
	{{{1, 0x3200000, 0x3204000, 0x1d4000} } },/* 50: I2Q */
	{{{1, 0x3300000, 0x3304000, 0x1a0000} } },/* 51: ROMUSB */
	{{{0} } },				/* 52: */
	{{{1, 0x3500000, 0x3500400, 0x1ac000} } },/* 53: RPMX0 */
	{{{1, 0x3600000, 0x3600400, 0x1ae000} } },/* 54: RPMX8 */
	{{{1, 0x3700000, 0x3700400, 0x1ae400} } },/* 55: RPMX9 */
	{{{1, 0x3800000, 0x3804000, 0x1d0000} } },/* 56: OCM0 */
	{{{1, 0x3900000, 0x3904000, 0x1b4000} } },/* 57: CRYPTO */
	{{{1, 0x3a00000, 0x3a04000, 0x1d8000} } },/* 58: SMB */
	{{{0} } },				/* 59: I2C0 */
	{{{0} } },				/* 60: I2C1 */
	{{{1, 0x3d00000, 0x3d04000, 0x1d8000} } },/* 61: LPC */
	{{{1, 0x3e00000, 0x3e01000, 0x167000} } },/* 62: P2NC */
	{{{1, 0x3f00000, 0x3f01000, 0x168000} } }	/* 63: P2NR0 */
};

/*
 * top 12 bits of crb internal address (hub, agent)
 */
static unsigned crb_hub_agt[64] =
{
	0,
	NETXEN_HW_CRB_HUB_AGT_ADR_PS,
	NETXEN_HW_CRB_HUB_AGT_ADR_MN,
	NETXEN_HW_CRB_HUB_AGT_ADR_MS,
	0,
	NETXEN_HW_CRB_HUB_AGT_ADR_SRE,
	NETXEN_HW_CRB_HUB_AGT_ADR_NIU,
	NETXEN_HW_CRB_HUB_AGT_ADR_QMN,
	NETXEN_HW_CRB_HUB_AGT_ADR_SQN0,
	NETXEN_HW_CRB_HUB_AGT_ADR_SQN1,
	NETXEN_HW_CRB_HUB_AGT_ADR_SQN2,
	NETXEN_HW_CRB_HUB_AGT_ADR_SQN3,
	NETXEN_HW_CRB_HUB_AGT_ADR_I2Q,
	NETXEN_HW_CRB_HUB_AGT_ADR_TIMR,
	NETXEN_HW_CRB_HUB_AGT_ADR_ROMUSB,
	NETXEN_HW_CRB_HUB_AGT_ADR_PGN4,
	NETXEN_HW_CRB_HUB_AGT_ADR_XDMA,
	NETXEN_HW_CRB_HUB_AGT_ADR_PGN0,
	NETXEN_HW_CRB_HUB_AGT_ADR_PGN1,
	NETXEN_HW_CRB_HUB_AGT_ADR_PGN2,
	NETXEN_HW_CRB_HUB_AGT_ADR_PGN3,
	NETXEN_HW_CRB_HUB_AGT_ADR_PGND,
	NETXEN_HW_CRB_HUB_AGT_ADR_PGNI,
	NETXEN_HW_CRB_HUB_AGT_ADR_PGS0,
	NETXEN_HW_CRB_HUB_AGT_ADR_PGS1,
	NETXEN_HW_CRB_HUB_AGT_ADR_PGS2,
	NETXEN_HW_CRB_HUB_AGT_ADR_PGS3,
	0,
	NETXEN_HW_CRB_HUB_AGT_ADR_PGSI,
	NETXEN_HW_CRB_HUB_AGT_ADR_SN,
	0,
	NETXEN_HW_CRB_HUB_AGT_ADR_EG,
	0,
	NETXEN_HW_CRB_HUB_AGT_ADR_PS,
	NETXEN_HW_CRB_HUB_AGT_ADR_CAM,
	0,
	0,
	0,
	0,
	0,
	NETXEN_HW_CRB_HUB_AGT_ADR_TIMR,
	0,
	NETXEN_HW_CRB_HUB_AGT_ADR_RPMX1,
	NETXEN_HW_CRB_HUB_AGT_ADR_RPMX2,
	NETXEN_HW_CRB_HUB_AGT_ADR_RPMX3,
	NETXEN_HW_CRB_HUB_AGT_ADR_RPMX4,
	NETXEN_HW_CRB_HUB_AGT_ADR_RPMX5,
	NETXEN_HW_CRB_HUB_AGT_ADR_RPMX6,
	NETXEN_HW_CRB_HUB_AGT_ADR_RPMX7,
	NETXEN_HW_CRB_HUB_AGT_ADR_XDMA,
	NETXEN_HW_CRB_HUB_AGT_ADR_I2Q,
	NETXEN_HW_CRB_HUB_AGT_ADR_ROMUSB,
	0,
	NETXEN_HW_CRB_HUB_AGT_ADR_RPMX0,
	NETXEN_HW_CRB_HUB_AGT_ADR_RPMX8,
	NETXEN_HW_CRB_HUB_AGT_ADR_RPMX9,
	NETXEN_HW_CRB_HUB_AGT_ADR_OCM0,
	0,
	NETXEN_HW_CRB_HUB_AGT_ADR_SMB,
	NETXEN_HW_CRB_HUB_AGT_ADR_I2C0,
	NETXEN_HW_CRB_HUB_AGT_ADR_I2C1,
	0,
	NETXEN_HW_CRB_HUB_AGT_ADR_PGNC,
	0,
};

/*  PCI Windowing for DDR regions.  */

#define NETXEN_WINDOW_ONE 	0x2000000 /*CRB Window: bit 25 of CRB address */

#define NETXEN_UNICAST_ADDR(port, index) \
	(NETXEN_UNICAST_ADDR_BASE+(port*32)+(index*8))
#define NETXEN_MCAST_ADDR(port, index) \
	(NETXEN_MULTICAST_ADDR_BASE+(port*0x80)+(index*8))
#define MAC_HI(addr) \
	((addr[2] << 16) | (addr[1] << 8) | (addr[0]))
#define MAC_LO(addr) \
	((addr[5] << 16) | (addr[4] << 8) | (addr[3]))

static int
netxen_nic_enable_mcast_filter(struct netxen_adapter *adapter)
{
	u32	val = 0;
	u16 port = adapter->physical_port;
	u8 *addr = adapter->netdev->dev_addr;

	if (adapter->mc_enabled)
		return 0;

	val = NXRD32(adapter, NETXEN_MAC_ADDR_CNTL_REG);
	val |= (1UL << (28+port));
	NXWR32(adapter, NETXEN_MAC_ADDR_CNTL_REG, val);

	/* add broadcast addr to filter */
	val = 0xffffff;
	NXWR32(adapter, NETXEN_UNICAST_ADDR(port, 0), val);
	NXWR32(adapter, NETXEN_UNICAST_ADDR(port, 0)+4, val);

	/* add station addr to filter */
	val = MAC_HI(addr);
	NXWR32(adapter, NETXEN_UNICAST_ADDR(port, 1), val);
	val = MAC_LO(addr);
	NXWR32(adapter, NETXEN_UNICAST_ADDR(port, 1)+4, val);

	adapter->mc_enabled = 1;
	return 0;
}

static int
netxen_nic_disable_mcast_filter(struct netxen_adapter *adapter)
{
	u32	val = 0;
	u16 port = adapter->physical_port;
	u8 *addr = adapter->netdev->dev_addr;

	if (!adapter->mc_enabled)
		return 0;

	val = NXRD32(adapter, NETXEN_MAC_ADDR_CNTL_REG);
	val &= ~(1UL << (28+port));
	NXWR32(adapter, NETXEN_MAC_ADDR_CNTL_REG, val);

	val = MAC_HI(addr);
	NXWR32(adapter, NETXEN_UNICAST_ADDR(port, 0), val);
	val = MAC_LO(addr);
	NXWR32(adapter, NETXEN_UNICAST_ADDR(port, 0)+4, val);

	NXWR32(adapter, NETXEN_UNICAST_ADDR(port, 1), 0);
	NXWR32(adapter, NETXEN_UNICAST_ADDR(port, 1)+4, 0);

	adapter->mc_enabled = 0;
	return 0;
}

static int
netxen_nic_set_mcast_addr(struct netxen_adapter *adapter,
		int index, u8 *addr)
{
	u32 hi = 0, lo = 0;
	u16 port = adapter->physical_port;

	lo = MAC_LO(addr);
	hi = MAC_HI(addr);

	NXWR32(adapter, NETXEN_MCAST_ADDR(port, index), hi);
	NXWR32(adapter, NETXEN_MCAST_ADDR(port, index)+4, lo);

	return 0;
}

void netxen_p2_nic_set_multi(struct net_device *netdev)
{
	struct netxen_adapter *adapter = netdev_priv(netdev);
	struct dev_mc_list *mc_ptr;
	u8 null_addr[6];
	int index = 0;

	memset(null_addr, 0, 6);

	if (netdev->flags & IFF_PROMISC) {

		adapter->set_promisc(adapter,
				NETXEN_NIU_PROMISC_MODE);

		/* Full promiscuous mode */
		netxen_nic_disable_mcast_filter(adapter);

		return;
	}

	if (netdev->mc_count == 0) {
		adapter->set_promisc(adapter,
				NETXEN_NIU_NON_PROMISC_MODE);
		netxen_nic_disable_mcast_filter(adapter);
		return;
	}

	adapter->set_promisc(adapter, NETXEN_NIU_ALLMULTI_MODE);
	if (netdev->flags & IFF_ALLMULTI ||
			netdev->mc_count > adapter->max_mc_count) {
		netxen_nic_disable_mcast_filter(adapter);
		return;
	}

	netxen_nic_enable_mcast_filter(adapter);

	for (mc_ptr = netdev->mc_list; mc_ptr; mc_ptr = mc_ptr->next, index++)
		netxen_nic_set_mcast_addr(adapter, index, mc_ptr->dmi_addr);

	if (index != netdev->mc_count)
		printk(KERN_WARNING "%s: %s multicast address count mismatch\n",
			netxen_nic_driver_name, netdev->name);

	/* Clear out remaining addresses */
	for (; index < adapter->max_mc_count; index++)
		netxen_nic_set_mcast_addr(adapter, index, null_addr);
}

static int
netxen_send_cmd_descs(struct netxen_adapter *adapter,
		struct cmd_desc_type0 *cmd_desc_arr, int nr_desc)
{
	u32 i, producer, consumer;
	struct netxen_cmd_buffer *pbuf;
	struct cmd_desc_type0 *cmd_desc;
	struct nx_host_tx_ring *tx_ring;

	i = 0;

	tx_ring = adapter->tx_ring;
	netif_tx_lock_bh(adapter->netdev);

	producer = tx_ring->producer;
	consumer = tx_ring->sw_consumer;

	if (nr_desc >= find_diff_among(producer, consumer, tx_ring->num_desc)) {
		netif_tx_unlock_bh(adapter->netdev);
		return -EBUSY;
	}

	do {
		cmd_desc = &cmd_desc_arr[i];

		pbuf = &tx_ring->cmd_buf_arr[producer];
		pbuf->skb = NULL;
		pbuf->frag_count = 0;

		memcpy(&tx_ring->desc_head[producer],
			&cmd_desc_arr[i], sizeof(struct cmd_desc_type0));

		producer = get_next_index(producer, tx_ring->num_desc);
		i++;

	} while (i != nr_desc);

	tx_ring->producer = producer;

	netxen_nic_update_cmd_producer(adapter, tx_ring);

	netif_tx_unlock_bh(adapter->netdev);

	return 0;
}

static int
nx_p3_sre_macaddr_change(struct netxen_adapter *adapter, u8 *addr, unsigned op)
{
	nx_nic_req_t req;
	nx_mac_req_t *mac_req;
	u64 word;

	memset(&req, 0, sizeof(nx_nic_req_t));
	req.qhdr = cpu_to_le64(NX_NIC_REQUEST << 23);

	word = NX_MAC_EVENT | ((u64)adapter->portnum << 16);
	req.req_hdr = cpu_to_le64(word);

	mac_req = (nx_mac_req_t *)&req.words[0];
	mac_req->op = op;
	memcpy(mac_req->mac_addr, addr, 6);

	return netxen_send_cmd_descs(adapter, (struct cmd_desc_type0 *)&req, 1);
}

static int nx_p3_nic_add_mac(struct netxen_adapter *adapter,
		u8 *addr, struct list_head *del_list)
{
	struct list_head *head;
	nx_mac_list_t *cur;

	/* look up if already exists */
	list_for_each(head, del_list) {
		cur = list_entry(head, nx_mac_list_t, list);

		if (memcmp(addr, cur->mac_addr, ETH_ALEN) == 0) {
			list_move_tail(head, &adapter->mac_list);
			return 0;
		}
	}

	cur = kzalloc(sizeof(nx_mac_list_t), GFP_ATOMIC);
	if (cur == NULL) {
		printk(KERN_ERR "%s: failed to add mac address filter\n",
				adapter->netdev->name);
		return -ENOMEM;
	}
	memcpy(cur->mac_addr, addr, ETH_ALEN);
	list_add_tail(&cur->list, &adapter->mac_list);
	return nx_p3_sre_macaddr_change(adapter,
				cur->mac_addr, NETXEN_MAC_ADD);
}

void netxen_p3_nic_set_multi(struct net_device *netdev)
{
	struct netxen_adapter *adapter = netdev_priv(netdev);
	struct dev_mc_list *mc_ptr;
	u8 bcast_addr[ETH_ALEN] = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff };
	u32 mode = VPORT_MISS_MODE_DROP;
	LIST_HEAD(del_list);
	struct list_head *head;
	nx_mac_list_t *cur;

	list_splice_tail_init(&adapter->mac_list, &del_list);

	nx_p3_nic_add_mac(adapter, netdev->dev_addr, &del_list);
	nx_p3_nic_add_mac(adapter, bcast_addr, &del_list);

	if (netdev->flags & IFF_PROMISC) {
		mode = VPORT_MISS_MODE_ACCEPT_ALL;
		goto send_fw_cmd;
	}

	if ((netdev->flags & IFF_ALLMULTI) ||
			(netdev->mc_count > adapter->max_mc_count)) {
		mode = VPORT_MISS_MODE_ACCEPT_MULTI;
		goto send_fw_cmd;
	}

	if (netdev->mc_count > 0) {
		for (mc_ptr = netdev->mc_list; mc_ptr;
		     mc_ptr = mc_ptr->next) {
			nx_p3_nic_add_mac(adapter, mc_ptr->dmi_addr, &del_list);
		}
	}

send_fw_cmd:
	adapter->set_promisc(adapter, mode);
	head = &del_list;
	while (!list_empty(head)) {
		cur = list_entry(head->next, nx_mac_list_t, list);

		nx_p3_sre_macaddr_change(adapter,
				cur->mac_addr, NETXEN_MAC_DEL);
		list_del(&cur->list);
		kfree(cur);
	}
}

int netxen_p3_nic_set_promisc(struct netxen_adapter *adapter, u32 mode)
{
	nx_nic_req_t req;
	u64 word;

	memset(&req, 0, sizeof(nx_nic_req_t));

	req.qhdr = cpu_to_le64(NX_HOST_REQUEST << 23);

	word = NX_NIC_H2C_OPCODE_PROXY_SET_VPORT_MISS_MODE |
			((u64)adapter->portnum << 16);
	req.req_hdr = cpu_to_le64(word);

	req.words[0] = cpu_to_le64(mode);

	return netxen_send_cmd_descs(adapter,
				(struct cmd_desc_type0 *)&req, 1);
}

void netxen_p3_free_mac_list(struct netxen_adapter *adapter)
{
	nx_mac_list_t *cur;
	struct list_head *head = &adapter->mac_list;

	while (!list_empty(head)) {
		cur = list_entry(head->next, nx_mac_list_t, list);
		nx_p3_sre_macaddr_change(adapter,
				cur->mac_addr, NETXEN_MAC_DEL);
		list_del(&cur->list);
		kfree(cur);
	}
}

int netxen_p3_nic_set_mac_addr(struct netxen_adapter *adapter, u8 *addr)
{
	/* assuming caller has already copied new addr to netdev */
	netxen_p3_nic_set_multi(adapter->netdev);
	return 0;
}

#define	NETXEN_CONFIG_INTR_COALESCE	3

/*
 * Send the interrupt coalescing parameter set by ethtool to the card.
 */
int netxen_config_intr_coalesce(struct netxen_adapter *adapter)
{
	nx_nic_req_t req;
	u64 word;
	int rv;

	memset(&req, 0, sizeof(nx_nic_req_t));

	req.qhdr = cpu_to_le64(NX_NIC_REQUEST << 23);

	word = NETXEN_CONFIG_INTR_COALESCE | ((u64)adapter->portnum << 16);
	req.req_hdr = cpu_to_le64(word);

	memcpy(&req.words[0], &adapter->coal, sizeof(adapter->coal));

	rv = netxen_send_cmd_descs(adapter, (struct cmd_desc_type0 *)&req, 1);
	if (rv != 0) {
		printk(KERN_ERR "ERROR. Could not send "
			"interrupt coalescing parameters\n");
	}

	return rv;
}

#define RSS_HASHTYPE_IP_TCP	0x3

int netxen_config_rss(struct netxen_adapter *adapter, int enable)
{
	nx_nic_req_t req;
	u64 word;
	int i, rv;

	u64 key[] = { 0xbeac01fa6a42b73bULL, 0x8030f20c77cb2da3ULL,
			0xae7b30b4d0ca2bcbULL, 0x43a38fb04167253dULL,
			0x255b0ec26d5a56daULL };


	memset(&req, 0, sizeof(nx_nic_req_t));
	req.qhdr = cpu_to_le64(NX_HOST_REQUEST << 23);

	word = NX_NIC_H2C_OPCODE_CONFIG_RSS | ((u64)adapter->portnum << 16);
	req.req_hdr = cpu_to_le64(word);

	/*
	 * RSS request:
	 * bits 3-0: hash_method
	 *      5-4: hash_type_ipv4
	 *	7-6: hash_type_ipv6
	 *	  8: enable
	 *        9: use indirection table
	 *    47-10: reserved
	 *    63-48: indirection table mask
	 */
	word =  ((u64)(RSS_HASHTYPE_IP_TCP & 0x3) << 4) |
		((u64)(RSS_HASHTYPE_IP_TCP & 0x3) << 6) |
		((u64)(enable & 0x1) << 8) |
		((0x7ULL) << 48);
	req.words[0] = cpu_to_le64(word);
	for (i = 0; i < 5; i++)
		req.words[i+1] = cpu_to_le64(key[i]);


	rv = netxen_send_cmd_descs(adapter, (struct cmd_desc_type0 *)&req, 1);
	if (rv != 0) {
		printk(KERN_ERR "%s: could not configure RSS\n",
				adapter->netdev->name);
	}

	return rv;
}

int netxen_linkevent_request(struct netxen_adapter *adapter, int enable)
{
	nx_nic_req_t req;
	u64 word;
	int rv;

	memset(&req, 0, sizeof(nx_nic_req_t));
	req.qhdr = cpu_to_le64(NX_HOST_REQUEST << 23);

	word = NX_NIC_H2C_OPCODE_GET_LINKEVENT | ((u64)adapter->portnum << 16);
	req.req_hdr = cpu_to_le64(word);
	req.words[0] = cpu_to_le64(enable | (enable << 8));

	rv = netxen_send_cmd_descs(adapter, (struct cmd_desc_type0 *)&req, 1);
	if (rv != 0) {
		printk(KERN_ERR "%s: could not configure link notification\n",
				adapter->netdev->name);
	}

	return rv;
}

/*
 * netxen_nic_change_mtu - Change the Maximum Transfer Unit
 * @returns 0 on success, negative on failure
 */

#define MTU_FUDGE_FACTOR	100

int netxen_nic_change_mtu(struct net_device *netdev, int mtu)
{
	struct netxen_adapter *adapter = netdev_priv(netdev);
	int max_mtu;
	int rc = 0;

	if (NX_IS_REVISION_P3(adapter->ahw.revision_id))
		max_mtu = P3_MAX_MTU;
	else
		max_mtu = P2_MAX_MTU;

	if (mtu > max_mtu) {
		printk(KERN_ERR "%s: mtu > %d bytes unsupported\n",
				netdev->name, max_mtu);
		return -EINVAL;
	}

	if (adapter->set_mtu)
		rc = adapter->set_mtu(adapter, mtu);

	if (!rc)
		netdev->mtu = mtu;

	return rc;
}

static int netxen_get_flash_block(struct netxen_adapter *adapter, int base,
				  int size, __le32 * buf)
{
	int i, v, addr;
	__le32 *ptr32;

	addr = base;
	ptr32 = buf;
	for (i = 0; i < size / sizeof(u32); i++) {
		if (netxen_rom_fast_read(adapter, addr, &v) == -1)
			return -1;
		*ptr32 = cpu_to_le32(v);
		ptr32++;
		addr += sizeof(u32);
	}
	if ((char *)buf + size > (char *)ptr32) {
		__le32 local;
		if (netxen_rom_fast_read(adapter, addr, &v) == -1)
			return -1;
		local = cpu_to_le32(v);
		memcpy(ptr32, &local, (char *)buf + size - (char *)ptr32);
	}

	return 0;
}

int netxen_get_flash_mac_addr(struct netxen_adapter *adapter, __le64 *mac)
{
	__le32 *pmac = (__le32 *) mac;
	u32 offset;

	offset = NETXEN_USER_START +
		offsetof(struct netxen_new_user_info, mac_addr) +
		adapter->portnum * sizeof(u64);

	if (netxen_get_flash_block(adapter, offset, sizeof(u64), pmac) == -1)
		return -1;

	if (*mac == cpu_to_le64(~0ULL)) {

		offset = NETXEN_USER_START_OLD +
			offsetof(struct netxen_user_old_info, mac_addr) +
			adapter->portnum * sizeof(u64);

		if (netxen_get_flash_block(adapter,
					offset, sizeof(u64), pmac) == -1)
			return -1;

		if (*mac == cpu_to_le64(~0ULL))
			return -1;
	}
	return 0;
}

int netxen_p3_get_mac_addr(struct netxen_adapter *adapter, __le64 *mac)
{
	uint32_t crbaddr, mac_hi, mac_lo;
	int pci_func = adapter->ahw.pci_func;

	crbaddr = CRB_MAC_BLOCK_START +
		(4 * ((pci_func/2) * 3)) + (4 * (pci_func & 1));

	mac_lo = NXRD32(adapter, crbaddr);
	mac_hi = NXRD32(adapter, crbaddr+4);

	if (pci_func & 1)
		*mac = le64_to_cpu((mac_lo >> 16) | ((u64)mac_hi << 16));
	else
		*mac = le64_to_cpu((u64)mac_lo | ((u64)mac_hi << 32));

	return 0;
}

#define CRB_WIN_LOCK_TIMEOUT 100000000

static int crb_win_lock(struct netxen_adapter *adapter)
{
	int done = 0, timeout = 0;

	while (!done) {
		/* acquire semaphore3 from PCI HW block */
		done = NXRD32(adapter, NETXEN_PCIE_REG(PCIE_SEM7_LOCK));
		if (done == 1)
			break;
		if (timeout >= CRB_WIN_LOCK_TIMEOUT)
			return -1;
		timeout++;
		udelay(1);
	}
	NXWR32(adapter, NETXEN_CRB_WIN_LOCK_ID, adapter->portnum);
	return 0;
}

static void crb_win_unlock(struct netxen_adapter *adapter)
{
	int val;

	val = NXRD32(adapter, NETXEN_PCIE_REG(PCIE_SEM7_UNLOCK));
}

/*
 * Changes the CRB window to the specified window.
 */
void
netxen_nic_pci_change_crbwindow_128M(struct netxen_adapter *adapter, u32 wndw)
{
	void __iomem *offset;
	u32 tmp;
	int count = 0;
	uint8_t func = adapter->ahw.pci_func;

	if (adapter->curr_window == wndw)
		return;
	/*
	 * Move the CRB window.
	 * We need to write to the "direct access" region of PCI
	 * to avoid a race condition where the window register has
	 * not been successfully written across CRB before the target
	 * register address is received by PCI. The direct region bypasses
	 * the CRB bus.
	 */
	offset = PCI_OFFSET_SECOND_RANGE(adapter,
			NETXEN_PCIX_PH_REG(PCIE_CRB_WINDOW_REG(func)));

	if (wndw & 0x1)
		wndw = NETXEN_WINDOW_ONE;

	writel(wndw, offset);

	/* MUST make sure window is set before we forge on... */
	while ((tmp = readl(offset)) != wndw) {
		printk(KERN_WARNING "%s: %s WARNING: CRB window value not "
		       "registered properly: 0x%08x.\n",
		       netxen_nic_driver_name, __func__, tmp);
		mdelay(1);
		if (count >= 10)
			break;
		count++;
	}

	if (wndw == NETXEN_WINDOW_ONE)
		adapter->curr_window = 1;
	else
		adapter->curr_window = 0;
}

/*
 * Return -1 if off is not valid,
 *	 1 if window access is needed. 'off' is set to offset from
 *	   CRB space in 128M pci map
 *	 0 if no window access is needed. 'off' is set to 2M addr
 * In: 'off' is offset from base in 128M pci map
 */
static int
netxen_nic_pci_get_crb_addr_2M(struct netxen_adapter *adapter, ulong *off)
{
	crb_128M_2M_sub_block_map_t *m;


	if (*off >= NETXEN_CRB_MAX)
		return -1;

	if (*off >= NETXEN_PCI_CAMQM && (*off < NETXEN_PCI_CAMQM_2M_END)) {
		*off = (*off - NETXEN_PCI_CAMQM) + NETXEN_PCI_CAMQM_2M_BASE +
			(ulong)adapter->ahw.pci_base0;
		return 0;
	}

	if (*off < NETXEN_PCI_CRBSPACE)
		return -1;

	*off -= NETXEN_PCI_CRBSPACE;

	/*
	 * Try direct map
	 */
	m = &crb_128M_2M_map[CRB_BLK(*off)].sub_block[CRB_SUBBLK(*off)];

	if (m->valid && (m->start_128M <= *off) && (m->end_128M > *off)) {
		*off = *off + m->start_2M - m->start_128M +
			(ulong)adapter->ahw.pci_base0;
		return 0;
	}

	/*
	 * Not in direct map, use crb window
	 */
	return 1;
}

/*
 * In: 'off' is offset from CRB space in 128M pci map
 * Out: 'off' is 2M pci map addr
 * side effect: lock crb window
 */
static void
netxen_nic_pci_set_crbwindow_2M(struct netxen_adapter *adapter, ulong *off)
{
	u32 win_read;

	adapter->crb_win = CRB_HI(*off);
	writel(adapter->crb_win, (adapter->ahw.pci_base0 + CRB_WINDOW_2M));
	/*
	 * Read back value to make sure write has gone through before trying
	 * to use it.
	 */
	win_read = readl(adapter->ahw.pci_base0 + CRB_WINDOW_2M);
	if (win_read != adapter->crb_win) {
		printk(KERN_ERR "%s: Written crbwin (0x%x) != "
				"Read crbwin (0x%x), off=0x%lx\n",
				__func__, adapter->crb_win, win_read, *off);
	}
	*off = (*off & MASK(16)) + CRB_INDIRECT_2M +
		(ulong)adapter->ahw.pci_base0;
}

int
netxen_nic_hw_write_wx_128M(struct netxen_adapter *adapter, ulong off, u32 data)
{
	void __iomem *addr;

	if (ADDR_IN_WINDOW1(off)) {
		addr = NETXEN_CRB_NORMALIZE(adapter, off);
	} else {		/* Window 0 */
		addr = pci_base_offset(adapter, off);
		netxen_nic_pci_change_crbwindow_128M(adapter, 0);
	}

	if (!addr) {
		netxen_nic_pci_change_crbwindow_128M(adapter, 1);
		return 1;
	}

	writel(data, addr);

	if (!ADDR_IN_WINDOW1(off))
		netxen_nic_pci_change_crbwindow_128M(adapter, 1);

	return 0;
}

u32
netxen_nic_hw_read_wx_128M(struct netxen_adapter *adapter, ulong off)
{
	void __iomem *addr;
	u32 data;

	if (ADDR_IN_WINDOW1(off)) {	/* Window 1 */
		addr = NETXEN_CRB_NORMALIZE(adapter, off);
	} else {		/* Window 0 */
		addr = pci_base_offset(adapter, off);
		netxen_nic_pci_change_crbwindow_128M(adapter, 0);
	}

	if (!addr) {
		netxen_nic_pci_change_crbwindow_128M(adapter, 1);
		return 1;
	}

	data = readl(addr);

	if (!ADDR_IN_WINDOW1(off))
		netxen_nic_pci_change_crbwindow_128M(adapter, 1);

	return data;
}

int
netxen_nic_hw_write_wx_2M(struct netxen_adapter *adapter, ulong off, u32 data)
{
	unsigned long flags = 0;
	int rv;

	rv = netxen_nic_pci_get_crb_addr_2M(adapter, &off);

	if (rv == -1) {
		printk(KERN_ERR "%s: invalid offset: 0x%016lx\n",
				__func__, off);
		dump_stack();
		return -1;
	}

	if (rv == 1) {
		write_lock_irqsave(&adapter->adapter_lock, flags);
		crb_win_lock(adapter);
		netxen_nic_pci_set_crbwindow_2M(adapter, &off);
		writel(data, (void __iomem *)off);
		crb_win_unlock(adapter);
		write_unlock_irqrestore(&adapter->adapter_lock, flags);
	} else
		writel(data, (void __iomem *)off);


	return 0;
}

u32
netxen_nic_hw_read_wx_2M(struct netxen_adapter *adapter, ulong off)
{
	unsigned long flags = 0;
	int rv;
	u32 data;

	rv = netxen_nic_pci_get_crb_addr_2M(adapter, &off);

	if (rv == -1) {
		printk(KERN_ERR "%s: invalid offset: 0x%016lx\n",
				__func__, off);
		dump_stack();
		return -1;
	}

	if (rv == 1) {
		write_lock_irqsave(&adapter->adapter_lock, flags);
		crb_win_lock(adapter);
		netxen_nic_pci_set_crbwindow_2M(adapter, &off);
		data = readl((void __iomem *)off);
		crb_win_unlock(adapter);
		write_unlock_irqrestore(&adapter->adapter_lock, flags);
	} else
		data = readl((void __iomem *)off);

	return data;
}

/*
 * check memory access boundary.
 * used by test agent. support ddr access only for now
 */
static unsigned long
netxen_nic_pci_mem_bound_check(struct netxen_adapter *adapter,
		unsigned long long addr, int size)
{
	if (!ADDR_IN_RANGE(addr,
			NETXEN_ADDR_DDR_NET, NETXEN_ADDR_DDR_NET_MAX) ||
		!ADDR_IN_RANGE(addr+size-1,
			NETXEN_ADDR_DDR_NET, NETXEN_ADDR_DDR_NET_MAX) ||
		((size != 1) && (size != 2) && (size != 4) && (size != 8))) {
		return 0;
	}

	return 1;
}

static int netxen_pci_set_window_warning_count;

unsigned long
netxen_nic_pci_set_window_128M(struct netxen_adapter *adapter,
		unsigned long long addr)
{
	void __iomem *offset;
	int window;
	unsigned long long	qdr_max;
	uint8_t func = adapter->ahw.pci_func;

	if (NX_IS_REVISION_P2(adapter->ahw.revision_id)) {
		qdr_max = NETXEN_ADDR_QDR_NET_MAX_P2;
	} else {
		qdr_max = NETXEN_ADDR_QDR_NET_MAX_P3;
	}

	if (ADDR_IN_RANGE(addr, NETXEN_ADDR_DDR_NET, NETXEN_ADDR_DDR_NET_MAX)) {
		/* DDR network side */
		addr -= NETXEN_ADDR_DDR_NET;
		window = (addr >> 25) & 0x3ff;
		if (adapter->ahw.ddr_mn_window != window) {
			adapter->ahw.ddr_mn_window = window;
			offset = PCI_OFFSET_SECOND_RANGE(adapter,
				NETXEN_PCIX_PH_REG(PCIE_MN_WINDOW_REG(func)));
			writel(window, offset);
			/* MUST make sure window is set before we forge on... */
			readl(offset);
		}
		addr -= (window * NETXEN_WINDOW_ONE);
		addr += NETXEN_PCI_DDR_NET;
	} else if (ADDR_IN_RANGE(addr, NETXEN_ADDR_OCM0, NETXEN_ADDR_OCM0_MAX)) {
		addr -= NETXEN_ADDR_OCM0;
		addr += NETXEN_PCI_OCM0;
	} else if (ADDR_IN_RANGE(addr, NETXEN_ADDR_OCM1, NETXEN_ADDR_OCM1_MAX)) {
		addr -= NETXEN_ADDR_OCM1;
		addr += NETXEN_PCI_OCM1;
	} else if (ADDR_IN_RANGE(addr, NETXEN_ADDR_QDR_NET, qdr_max)) {
		/* QDR network side */
		addr -= NETXEN_ADDR_QDR_NET;
		window = (addr >> 22) & 0x3f;
		if (adapter->ahw.qdr_sn_window != window) {
			adapter->ahw.qdr_sn_window = window;
			offset = PCI_OFFSET_SECOND_RANGE(adapter,
				NETXEN_PCIX_PH_REG(PCIE_SN_WINDOW_REG(func)));
			writel((window << 22), offset);
			/* MUST make sure window is set before we forge on... */
			readl(offset);
		}
		addr -= (window * 0x400000);
		addr += NETXEN_PCI_QDR_NET;
	} else {
		/*
		 * peg gdb frequently accesses memory that doesn't exist,
		 * this limits the chit chat so debugging isn't slowed down.
		 */
		if ((netxen_pci_set_window_warning_count++ < 8)
		    || (netxen_pci_set_window_warning_count % 64 == 0))
			printk("%s: Warning:netxen_nic_pci_set_window()"
			       " Unknown address range!\n",
			       netxen_nic_driver_name);
		addr = -1UL;
	}
	return addr;
}

/*
 * Note : only 32-bit writes!
 */
int netxen_nic_pci_write_immediate_128M(struct netxen_adapter *adapter,
		u64 off, u32 data)
{
	writel(data, (void __iomem *)(PCI_OFFSET_SECOND_RANGE(adapter, off)));
	return 0;
}

u32 netxen_nic_pci_read_immediate_128M(struct netxen_adapter *adapter, u64 off)
{
	return readl((void __iomem *)(pci_base_offset(adapter, off)));
}

unsigned long
netxen_nic_pci_set_window_2M(struct netxen_adapter *adapter,
		unsigned long long addr)
{
	int window;
	u32 win_read;

	if (ADDR_IN_RANGE(addr, NETXEN_ADDR_DDR_NET, NETXEN_ADDR_DDR_NET_MAX)) {
		/* DDR network side */
		window = MN_WIN(addr);
		adapter->ahw.ddr_mn_window = window;
		NXWR32(adapter, adapter->ahw.mn_win_crb | NETXEN_PCI_CRBSPACE,
				window);
		win_read = NXRD32(adapter,
				adapter->ahw.mn_win_crb | NETXEN_PCI_CRBSPACE);
		if ((win_read << 17) != window) {
			printk(KERN_INFO "Written MNwin (0x%x) != "
				"Read MNwin (0x%x)\n", window, win_read);
		}
		addr = GET_MEM_OFFS_2M(addr) + NETXEN_PCI_DDR_NET;
	} else if (ADDR_IN_RANGE(addr,
				NETXEN_ADDR_OCM0, NETXEN_ADDR_OCM0_MAX)) {
		if ((addr & 0x00ff800) == 0xff800) {
			printk("%s: QM access not handled.\n", __func__);
			addr = -1UL;
		}

		window = OCM_WIN(addr);
		adapter->ahw.ddr_mn_window = window;
		NXWR32(adapter, adapter->ahw.mn_win_crb | NETXEN_PCI_CRBSPACE,
				window);
		win_read = NXRD32(adapter,
				adapter->ahw.mn_win_crb | NETXEN_PCI_CRBSPACE);
		if ((win_read >> 7) != window) {
			printk(KERN_INFO "%s: Written OCMwin (0x%x) != "
					"Read OCMwin (0x%x)\n",
					__func__, window, win_read);
		}
		addr = GET_MEM_OFFS_2M(addr) + NETXEN_PCI_OCM0_2M;

	} else if (ADDR_IN_RANGE(addr,
			NETXEN_ADDR_QDR_NET, NETXEN_ADDR_QDR_NET_MAX_P3)) {
		/* QDR network side */
		window = MS_WIN(addr);
		adapter->ahw.qdr_sn_window = window;
		NXWR32(adapter, adapter->ahw.ms_win_crb | NETXEN_PCI_CRBSPACE,
				window);
		win_read = NXRD32(adapter,
				adapter->ahw.ms_win_crb | NETXEN_PCI_CRBSPACE);
		if (win_read != window) {
			printk(KERN_INFO "%s: Written MSwin (0x%x) != "
					"Read MSwin (0x%x)\n",
					__func__, window, win_read);
		}
		addr = GET_MEM_OFFS_2M(addr) + NETXEN_PCI_QDR_NET;

	} else {
		/*
		 * peg gdb frequently accesses memory that doesn't exist,
		 * this limits the chit chat so debugging isn't slowed down.
		 */
		if ((netxen_pci_set_window_warning_count++ < 8)
			|| (netxen_pci_set_window_warning_count%64 == 0)) {
			printk("%s: Warning:%s Unknown address range!\n",
					__func__, netxen_nic_driver_name);
}
		addr = -1UL;
	}
	return addr;
}

static int netxen_nic_pci_is_same_window(struct netxen_adapter *adapter,
				      unsigned long long addr)
{
	int window;
	unsigned long long qdr_max;

	if (NX_IS_REVISION_P2(adapter->ahw.revision_id))
		qdr_max = NETXEN_ADDR_QDR_NET_MAX_P2;
	else
		qdr_max = NETXEN_ADDR_QDR_NET_MAX_P3;

	if (ADDR_IN_RANGE(addr,
			NETXEN_ADDR_DDR_NET, NETXEN_ADDR_DDR_NET_MAX)) {
		/* DDR network side */
		BUG();	/* MN access can not come here */
	} else if (ADDR_IN_RANGE(addr,
			NETXEN_ADDR_OCM0, NETXEN_ADDR_OCM0_MAX)) {
		return 1;
	} else if (ADDR_IN_RANGE(addr,
				NETXEN_ADDR_OCM1, NETXEN_ADDR_OCM1_MAX)) {
		return 1;
	} else if (ADDR_IN_RANGE(addr, NETXEN_ADDR_QDR_NET, qdr_max)) {
		/* QDR network side */
		window = ((addr - NETXEN_ADDR_QDR_NET) >> 22) & 0x3f;
		if (adapter->ahw.qdr_sn_window == window)
			return 1;
	}

	return 0;
}

static int netxen_nic_pci_mem_read_direct(struct netxen_adapter *adapter,
			u64 off, void *data, int size)
{
	unsigned long flags;
	void __iomem *addr, *mem_ptr = NULL;
	int ret = 0;
	u64 start;
	unsigned long mem_base;
	unsigned long mem_page;

	write_lock_irqsave(&adapter->adapter_lock, flags);

	/*
	 * If attempting to access unknown address or straddle hw windows,
	 * do not access.
	 */
	start = adapter->pci_set_window(adapter, off);
	if ((start == -1UL) ||
		(netxen_nic_pci_is_same_window(adapter, off+size-1) == 0)) {
		write_unlock_irqrestore(&adapter->adapter_lock, flags);
		printk(KERN_ERR "%s out of bound pci memory access. "
			"offset is 0x%llx\n", netxen_nic_driver_name,
			(unsigned long long)off);
		return -1;
	}

	addr = pci_base_offset(adapter, start);
	if (!addr) {
		write_unlock_irqrestore(&adapter->adapter_lock, flags);
		mem_base = pci_resource_start(adapter->pdev, 0);
		mem_page = start & PAGE_MASK;
		/* Map two pages whenever user tries to access addresses in two
		consecutive pages.
		*/
		if (mem_page != ((start + size - 1) & PAGE_MASK))
			mem_ptr = ioremap(mem_base + mem_page, PAGE_SIZE * 2);
		else
			mem_ptr = ioremap(mem_base + mem_page, PAGE_SIZE);
		if (mem_ptr == NULL) {
			*(uint8_t  *)data = 0;
			return -1;
		}
		addr = mem_ptr;
		addr += start & (PAGE_SIZE - 1);
		write_lock_irqsave(&adapter->adapter_lock, flags);
	}

	switch (size) {
	case 1:
		*(uint8_t  *)data = readb(addr);
		break;
	case 2:
		*(uint16_t *)data = readw(addr);
		break;
	case 4:
		*(uint32_t *)data = readl(addr);
		break;
	case 8:
		*(uint64_t *)data = readq(addr);
		break;
	default:
		ret = -1;
		break;
	}
	write_unlock_irqrestore(&adapter->adapter_lock, flags);

	if (mem_ptr)
		iounmap(mem_ptr);
	return ret;
}

static int
netxen_nic_pci_mem_write_direct(struct netxen_adapter *adapter, u64 off,
		void *data, int size)
{
	unsigned long flags;
	void __iomem *addr, *mem_ptr = NULL;
	int ret = 0;
	u64 start;
	unsigned long mem_base;
	unsigned long mem_page;

	write_lock_irqsave(&adapter->adapter_lock, flags);

	/*
	 * If attempting to access unknown address or straddle hw windows,
	 * do not access.
	 */
	start = adapter->pci_set_window(adapter, off);
	if ((start == -1UL) ||
		(netxen_nic_pci_is_same_window(adapter, off+size-1) == 0)) {
		write_unlock_irqrestore(&adapter->adapter_lock, flags);
		printk(KERN_ERR "%s out of bound pci memory access. "
			"offset is 0x%llx\n", netxen_nic_driver_name,
			(unsigned long long)off);
		return -1;
	}

	addr = pci_base_offset(adapter, start);
	if (!addr) {
		write_unlock_irqrestore(&adapter->adapter_lock, flags);
		mem_base = pci_resource_start(adapter->pdev, 0);
		mem_page = start & PAGE_MASK;
		/* Map two pages whenever user tries to access addresses in two
		 * consecutive pages.
		 */
		if (mem_page != ((start + size - 1) & PAGE_MASK))
			mem_ptr = ioremap(mem_base + mem_page, PAGE_SIZE*2);
		else
			mem_ptr = ioremap(mem_base + mem_page, PAGE_SIZE);
		if (mem_ptr == NULL)
			return -1;
		addr = mem_ptr;
		addr += start & (PAGE_SIZE - 1);
		write_lock_irqsave(&adapter->adapter_lock, flags);
	}

	switch (size) {
	case 1:
		writeb(*(uint8_t *)data, addr);
		break;
	case 2:
		writew(*(uint16_t *)data, addr);
		break;
	case 4:
		writel(*(uint32_t *)data, addr);
		break;
	case 8:
		writeq(*(uint64_t *)data, addr);
		break;
	default:
		ret = -1;
		break;
	}
	write_unlock_irqrestore(&adapter->adapter_lock, flags);
	if (mem_ptr)
		iounmap(mem_ptr);
	return ret;
}

#define MAX_CTL_CHECK   1000

int
netxen_nic_pci_mem_write_128M(struct netxen_adapter *adapter,
		u64 off, void *data, int size)
{
	unsigned long   flags;
	int	     i, j, ret = 0, loop, sz[2], off0;
	uint32_t      temp;
	uint64_t      off8, tmpw, word[2] = {0, 0};
	void __iomem *mem_crb;

	/*
	 * If not MN, go check for MS or invalid.
	 */
	if (netxen_nic_pci_mem_bound_check(adapter, off, size) == 0)
		return netxen_nic_pci_mem_write_direct(adapter,
				off, data, size);

	off8 = off & 0xfffffff8;
	off0 = off & 0x7;
	sz[0] = (size < (8 - off0)) ? size : (8 - off0);
	sz[1] = size - sz[0];
	loop = ((off0 + size - 1) >> 3) + 1;
	mem_crb = pci_base_offset(adapter, NETXEN_CRB_DDR_NET);

	if ((size != 8) || (off0 != 0))  {
		for (i = 0; i < loop; i++) {
			if (adapter->pci_mem_read(adapter,
				off8 + (i << 3), &word[i], 8))
				return -1;
		}
	}

	switch (size) {
	case 1:
		tmpw = *((uint8_t *)data);
		break;
	case 2:
		tmpw = *((uint16_t *)data);
		break;
	case 4:
		tmpw = *((uint32_t *)data);
		break;
	case 8:
	default:
		tmpw = *((uint64_t *)data);
		break;
	}
	word[0] &= ~((~(~0ULL << (sz[0] * 8))) << (off0 * 8));
	word[0] |= tmpw << (off0 * 8);

	if (loop == 2) {
		word[1] &= ~(~0ULL << (sz[1] * 8));
		word[1] |= tmpw >> (sz[0] * 8);
	}

	write_lock_irqsave(&adapter->adapter_lock, flags);
	netxen_nic_pci_change_crbwindow_128M(adapter, 0);

	for (i = 0; i < loop; i++) {
		writel((uint32_t)(off8 + (i << 3)),
			(mem_crb+MIU_TEST_AGT_ADDR_LO));
		writel(0,
			(mem_crb+MIU_TEST_AGT_ADDR_HI));
		writel(word[i] & 0xffffffff,
			(mem_crb+MIU_TEST_AGT_WRDATA_LO));
		writel((word[i] >> 32) & 0xffffffff,
			(mem_crb+MIU_TEST_AGT_WRDATA_HI));
		writel(MIU_TA_CTL_ENABLE|MIU_TA_CTL_WRITE,
			(mem_crb+MIU_TEST_AGT_CTRL));
		writel(MIU_TA_CTL_START|MIU_TA_CTL_ENABLE|MIU_TA_CTL_WRITE,
			(mem_crb+MIU_TEST_AGT_CTRL));

		for (j = 0; j < MAX_CTL_CHECK; j++) {
			temp = readl(
			     (mem_crb+MIU_TEST_AGT_CTRL));
			if ((temp & MIU_TA_CTL_BUSY) == 0)
				break;
		}

		if (j >= MAX_CTL_CHECK) {
			if (printk_ratelimit())
				dev_err(&adapter->pdev->dev,
					"failed to write through agent\n");
			ret = -1;
			break;
		}
	}

	netxen_nic_pci_change_crbwindow_128M(adapter, 1);
	write_unlock_irqrestore(&adapter->adapter_lock, flags);
	return ret;
}

int
netxen_nic_pci_mem_read_128M(struct netxen_adapter *adapter,
		u64 off, void *data, int size)
{
	unsigned long   flags;
	int	     i, j = 0, k, start, end, loop, sz[2], off0[2];
	uint32_t      temp;
	uint64_t      off8, val, word[2] = {0, 0};
	void __iomem *mem_crb;


	/*
	 * If not MN, go check for MS or invalid.
	 */
	if (netxen_nic_pci_mem_bound_check(adapter, off, size) == 0)
		return netxen_nic_pci_mem_read_direct(adapter, off, data, size);

	off8 = off & 0xfffffff8;
	off0[0] = off & 0x7;
	off0[1] = 0;
	sz[0] = (size < (8 - off0[0])) ? size : (8 - off0[0]);
	sz[1] = size - sz[0];
	loop = ((off0[0] + size - 1) >> 3) + 1;
	mem_crb = pci_base_offset(adapter, NETXEN_CRB_DDR_NET);

	write_lock_irqsave(&adapter->adapter_lock, flags);
	netxen_nic_pci_change_crbwindow_128M(adapter, 0);

	for (i = 0; i < loop; i++) {
		writel((uint32_t)(off8 + (i << 3)),
			(mem_crb+MIU_TEST_AGT_ADDR_LO));
		writel(0,
			(mem_crb+MIU_TEST_AGT_ADDR_HI));
		writel(MIU_TA_CTL_ENABLE,
			(mem_crb+MIU_TEST_AGT_CTRL));
		writel(MIU_TA_CTL_START|MIU_TA_CTL_ENABLE,
			(mem_crb+MIU_TEST_AGT_CTRL));

		for (j = 0; j < MAX_CTL_CHECK; j++) {
			temp = readl(
			      (mem_crb+MIU_TEST_AGT_CTRL));
			if ((temp & MIU_TA_CTL_BUSY) == 0)
				break;
		}

		if (j >= MAX_CTL_CHECK) {
			if (printk_ratelimit())
				dev_err(&adapter->pdev->dev,
					"failed to read through agent\n");
			break;
		}

		start = off0[i] >> 2;
		end   = (off0[i] + sz[i] - 1) >> 2;
		for (k = start; k <= end; k++) {
			word[i] |= ((uint64_t) readl(
				    (mem_crb +
				    MIU_TEST_AGT_RDDATA(k))) << (32*k));
		}
	}

	netxen_nic_pci_change_crbwindow_128M(adapter, 1);
	write_unlock_irqrestore(&adapter->adapter_lock, flags);

	if (j >= MAX_CTL_CHECK)
		return -1;

	if (sz[0] == 8) {
		val = word[0];
	} else {
		val = ((word[0] >> (off0[0] * 8)) & (~(~0ULL << (sz[0] * 8)))) |
			((word[1] & (~(~0ULL << (sz[1] * 8)))) << (sz[0] * 8));
	}

	switch (size) {
	case 1:
		*(uint8_t  *)data = val;
		break;
	case 2:
		*(uint16_t *)data = val;
		break;
	case 4:
		*(uint32_t *)data = val;
		break;
	case 8:
		*(uint64_t *)data = val;
		break;
	}
	return 0;
}

int
netxen_nic_pci_mem_write_2M(struct netxen_adapter *adapter,
		u64 off, void *data, int size)
{
	int i, j, ret = 0, loop, sz[2], off0;
	uint32_t temp;
	uint64_t off8, mem_crb, tmpw, word[2] = {0, 0};

	/*
	 * If not MN, go check for MS or invalid.
	 */
	if (off >= NETXEN_ADDR_QDR_NET && off <= NETXEN_ADDR_QDR_NET_MAX_P3)
		mem_crb = NETXEN_CRB_QDR_NET;
	else {
		mem_crb = NETXEN_CRB_DDR_NET;
		if (netxen_nic_pci_mem_bound_check(adapter, off, size) == 0)
			return netxen_nic_pci_mem_write_direct(adapter,
					off, data, size);
	}

	off8 = off & 0xfffffff8;
	off0 = off & 0x7;
	sz[0] = (size < (8 - off0)) ? size : (8 - off0);
	sz[1] = size - sz[0];
	loop = ((off0 + size - 1) >> 3) + 1;

	if ((size != 8) || (off0 != 0)) {
		for (i = 0; i < loop; i++) {
			if (adapter->pci_mem_read(adapter, off8 + (i << 3),
						&word[i], 8))
				return -1;
		}
	}

	switch (size) {
	case 1:
		tmpw = *((uint8_t *)data);
		break;
	case 2:
		tmpw = *((uint16_t *)data);
		break;
	case 4:
		tmpw = *((uint32_t *)data);
		break;
	case 8:
	default:
		tmpw = *((uint64_t *)data);
	break;
	}

	word[0] &= ~((~(~0ULL << (sz[0] * 8))) << (off0 * 8));
	word[0] |= tmpw << (off0 * 8);

	if (loop == 2) {
		word[1] &= ~(~0ULL << (sz[1] * 8));
		word[1] |= tmpw >> (sz[0] * 8);
	}

	/*
	 * don't lock here - write_wx gets the lock if each time
	 * write_lock_irqsave(&adapter->adapter_lock, flags);
	 * netxen_nic_pci_change_crbwindow_128M(adapter, 0);
	 */

	for (i = 0; i < loop; i++) {
		temp = off8 + (i << 3);
		NXWR32(adapter, mem_crb+MIU_TEST_AGT_ADDR_LO, temp);
		temp = 0;
		NXWR32(adapter, mem_crb+MIU_TEST_AGT_ADDR_HI, temp);
		temp = word[i] & 0xffffffff;
		NXWR32(adapter, mem_crb+MIU_TEST_AGT_WRDATA_LO, temp);
		temp = (word[i] >> 32) & 0xffffffff;
		NXWR32(adapter, mem_crb+MIU_TEST_AGT_WRDATA_HI, temp);
		temp = MIU_TA_CTL_ENABLE | MIU_TA_CTL_WRITE;
		NXWR32(adapter, mem_crb+MIU_TEST_AGT_CTRL, temp);
		temp = MIU_TA_CTL_START | MIU_TA_CTL_ENABLE | MIU_TA_CTL_WRITE;
		NXWR32(adapter, mem_crb+MIU_TEST_AGT_CTRL, temp);

		for (j = 0; j < MAX_CTL_CHECK; j++) {
			temp = NXRD32(adapter, mem_crb + MIU_TEST_AGT_CTRL);
			if ((temp & MIU_TA_CTL_BUSY) == 0)
				break;
		}

		if (j >= MAX_CTL_CHECK) {
			if (printk_ratelimit())
				dev_err(&adapter->pdev->dev,
					"failed to write through agent\n");
			ret = -1;
			break;
		}
	}

	/*
	 * netxen_nic_pci_change_crbwindow_128M(adapter, 1);
	 * write_unlock_irqrestore(&adapter->adapter_lock, flags);
	 */
	return ret;
}

int
netxen_nic_pci_mem_read_2M(struct netxen_adapter *adapter,
		u64 off, void *data, int size)
{
	int i, j = 0, k, start, end, loop, sz[2], off0[2];
	uint32_t      temp;
	uint64_t      off8, val, mem_crb, word[2] = {0, 0};

	/*
	 * If not MN, go check for MS or invalid.
	 */

	if (off >= NETXEN_ADDR_QDR_NET && off <= NETXEN_ADDR_QDR_NET_MAX_P3)
		mem_crb = NETXEN_CRB_QDR_NET;
	else {
		mem_crb = NETXEN_CRB_DDR_NET;
		if (netxen_nic_pci_mem_bound_check(adapter, off, size) == 0)
			return netxen_nic_pci_mem_read_direct(adapter,
					off, data, size);
	}

	off8 = off & 0xfffffff8;
	off0[0] = off & 0x7;
	off0[1] = 0;
	sz[0] = (size < (8 - off0[0])) ? size : (8 - off0[0]);
	sz[1] = size - sz[0];
	loop = ((off0[0] + size - 1) >> 3) + 1;

	/*
	 * don't lock here - write_wx gets the lock if each time
	 * write_lock_irqsave(&adapter->adapter_lock, flags);
	 * netxen_nic_pci_change_crbwindow_128M(adapter, 0);
	 */

	for (i = 0; i < loop; i++) {
		temp = off8 + (i << 3);
		NXWR32(adapter, mem_crb + MIU_TEST_AGT_ADDR_LO, temp);
		temp = 0;
		NXWR32(adapter, mem_crb + MIU_TEST_AGT_ADDR_HI, temp);
		temp = MIU_TA_CTL_ENABLE;
		NXWR32(adapter, mem_crb + MIU_TEST_AGT_CTRL, temp);
		temp = MIU_TA_CTL_START | MIU_TA_CTL_ENABLE;
		NXWR32(adapter, mem_crb + MIU_TEST_AGT_CTRL, temp);

		for (j = 0; j < MAX_CTL_CHECK; j++) {
			temp = NXRD32(adapter, mem_crb + MIU_TEST_AGT_CTRL);
			if ((temp & MIU_TA_CTL_BUSY) == 0)
				break;
		}

		if (j >= MAX_CTL_CHECK) {
			if (printk_ratelimit())
				dev_err(&adapter->pdev->dev,
					"failed to read through agent\n");
			break;
		}

		start = off0[i] >> 2;
		end   = (off0[i] + sz[i] - 1) >> 2;
		for (k = start; k <= end; k++) {
			temp = NXRD32(adapter,
				mem_crb + MIU_TEST_AGT_RDDATA(k));
			word[i] |= ((uint64_t)temp << (32 * k));
		}
	}

	/*
	 * netxen_nic_pci_change_crbwindow_128M(adapter, 1);
	 * write_unlock_irqrestore(&adapter->adapter_lock, flags);
	 */

	if (j >= MAX_CTL_CHECK)
		return -1;

	if (sz[0] == 8) {
		val = word[0];
	} else {
		val = ((word[0] >> (off0[0] * 8)) & (~(~0ULL << (sz[0] * 8)))) |
		((word[1] & (~(~0ULL << (sz[1] * 8)))) << (sz[0] * 8));
	}

	switch (size) {
	case 1:
		*(uint8_t  *)data = val;
		break;
	case 2:
		*(uint16_t *)data = val;
		break;
	case 4:
		*(uint32_t *)data = val;
		break;
	case 8:
		*(uint64_t *)data = val;
		break;
	}
	return 0;
}

/*
 * Note : only 32-bit writes!
 */
int netxen_nic_pci_write_immediate_2M(struct netxen_adapter *adapter,
		u64 off, u32 data)
{
	NXWR32(adapter, off, data);

	return 0;
}

u32 netxen_nic_pci_read_immediate_2M(struct netxen_adapter *adapter, u64 off)
{
	return NXRD32(adapter, off);
}

int netxen_nic_get_board_info(struct netxen_adapter *adapter)
{
	int offset, board_type, magic, header_version;
	struct pci_dev *pdev = adapter->pdev;

	offset = NETXEN_BRDCFG_START +
		offsetof(struct netxen_board_info, magic);
	if (netxen_rom_fast_read(adapter, offset, &magic))
		return -EIO;

	offset = NETXEN_BRDCFG_START +
		offsetof(struct netxen_board_info, header_version);
	if (netxen_rom_fast_read(adapter, offset, &header_version))
		return -EIO;

	if (magic != NETXEN_BDINFO_MAGIC ||
			header_version != NETXEN_BDINFO_VERSION) {
		dev_err(&pdev->dev,
			"invalid board config, magic=%08x, version=%08x\n",
			magic, header_version);
		return -EIO;
	}

	offset = NETXEN_BRDCFG_START +
		offsetof(struct netxen_board_info, board_type);
	if (netxen_rom_fast_read(adapter, offset, &board_type))
		return -EIO;

	adapter->ahw.board_type = board_type;

	if (board_type == NETXEN_BRDTYPE_P3_4_GB_MM) {
		u32 gpio = NXRD32(adapter, NETXEN_ROMUSB_GLB_PAD_GPIO_I);
		if ((gpio & 0x8000) == 0)
			board_type = NETXEN_BRDTYPE_P3_10G_TP;
	}

	switch (board_type) {
	case NETXEN_BRDTYPE_P2_SB35_4G:
		adapter->ahw.port_type = NETXEN_NIC_GBE;
		break;
	case NETXEN_BRDTYPE_P2_SB31_10G:
	case NETXEN_BRDTYPE_P2_SB31_10G_IMEZ:
	case NETXEN_BRDTYPE_P2_SB31_10G_HMEZ:
	case NETXEN_BRDTYPE_P2_SB31_10G_CX4:
	case NETXEN_BRDTYPE_P3_HMEZ:
	case NETXEN_BRDTYPE_P3_XG_LOM:
	case NETXEN_BRDTYPE_P3_10G_CX4:
	case NETXEN_BRDTYPE_P3_10G_CX4_LP:
	case NETXEN_BRDTYPE_P3_IMEZ:
	case NETXEN_BRDTYPE_P3_10G_SFP_PLUS:
	case NETXEN_BRDTYPE_P3_10G_SFP_CT:
	case NETXEN_BRDTYPE_P3_10G_SFP_QT:
	case NETXEN_BRDTYPE_P3_10G_XFP:
	case NETXEN_BRDTYPE_P3_10000_BASE_T:
		adapter->ahw.port_type = NETXEN_NIC_XGBE;
		break;
	case NETXEN_BRDTYPE_P1_BD:
	case NETXEN_BRDTYPE_P1_SB:
	case NETXEN_BRDTYPE_P1_SMAX:
	case NETXEN_BRDTYPE_P1_SOCK:
	case NETXEN_BRDTYPE_P3_REF_QG:
	case NETXEN_BRDTYPE_P3_4_GB:
	case NETXEN_BRDTYPE_P3_4_GB_MM:
		adapter->ahw.port_type = NETXEN_NIC_GBE;
		break;
	case NETXEN_BRDTYPE_P3_10G_TP:
		adapter->ahw.port_type = (adapter->portnum < 2) ?
			NETXEN_NIC_XGBE : NETXEN_NIC_GBE;
		break;
	default:
		dev_err(&pdev->dev, "unknown board type %x\n", board_type);
		adapter->ahw.port_type = NETXEN_NIC_XGBE;
		break;
	}

	return 0;
}

/* NIU access sections */

int netxen_nic_set_mtu_gb(struct netxen_adapter *adapter, int new_mtu)
{
	new_mtu += MTU_FUDGE_FACTOR;
	NXWR32(adapter, NETXEN_NIU_GB_MAX_FRAME_SIZE(adapter->physical_port),
		new_mtu);
	return 0;
}

int netxen_nic_set_mtu_xgb(struct netxen_adapter *adapter, int new_mtu)
{
	new_mtu += MTU_FUDGE_FACTOR;
	if (adapter->physical_port == 0)
		NXWR32(adapter, NETXEN_NIU_XGE_MAX_FRAME_SIZE, new_mtu);
	else
		NXWR32(adapter, NETXEN_NIU_XG1_MAX_FRAME_SIZE, new_mtu);
	return 0;
}

void netxen_nic_set_link_parameters(struct netxen_adapter *adapter)
{
	__u32 status;
	__u32 autoneg;
	__u32 port_mode;

	if (!netif_carrier_ok(adapter->netdev)) {
		adapter->link_speed   = 0;
		adapter->link_duplex  = -1;
		adapter->link_autoneg = AUTONEG_ENABLE;
		return;
	}

	if (adapter->ahw.port_type == NETXEN_NIC_GBE) {
		port_mode = NXRD32(adapter, NETXEN_PORT_MODE_ADDR);
		if (port_mode == NETXEN_PORT_MODE_802_3_AP) {
			adapter->link_speed   = SPEED_1000;
			adapter->link_duplex  = DUPLEX_FULL;
			adapter->link_autoneg = AUTONEG_DISABLE;
			return;
		}

		if (adapter->phy_read
		    && adapter->phy_read(adapter,
			     NETXEN_NIU_GB_MII_MGMT_ADDR_PHY_STATUS,
			     &status) == 0) {
			if (netxen_get_phy_link(status)) {
				switch (netxen_get_phy_speed(status)) {
				case 0:
					adapter->link_speed = SPEED_10;
					break;
				case 1:
					adapter->link_speed = SPEED_100;
					break;
				case 2:
					adapter->link_speed = SPEED_1000;
					break;
				default:
					adapter->link_speed = 0;
					break;
				}
				switch (netxen_get_phy_duplex(status)) {
				case 0:
					adapter->link_duplex = DUPLEX_HALF;
					break;
				case 1:
					adapter->link_duplex = DUPLEX_FULL;
					break;
				default:
					adapter->link_duplex = -1;
					break;
				}
				if (adapter->phy_read
				    && adapter->phy_read(adapter,
					     NETXEN_NIU_GB_MII_MGMT_ADDR_AUTONEG,
					     &autoneg) != 0)
					adapter->link_autoneg = autoneg;
			} else
				goto link_down;
		} else {
		      link_down:
			adapter->link_speed = 0;
			adapter->link_duplex = -1;
		}
	}
}

void netxen_nic_get_firmware_info(struct netxen_adapter *adapter)
{
	u32 fw_major, fw_minor, fw_build;
	char brd_name[NETXEN_MAX_SHORT_NAME];
	char serial_num[32];
	int i, addr, val;
	int *ptr32;
	struct pci_dev *pdev = adapter->pdev;

	adapter->driver_mismatch = 0;

	ptr32 = (int *)&serial_num;
	addr = NETXEN_USER_START +
	       offsetof(struct netxen_new_user_info, serial_num);
	for (i = 0; i < 8; i++) {
		if (netxen_rom_fast_read(adapter, addr, &val) == -1) {
			dev_err(&pdev->dev, "error reading board info\n");
			adapter->driver_mismatch = 1;
			return;
		}
		ptr32[i] = cpu_to_le32(val);
		addr += sizeof(u32);
	}

	fw_major = NXRD32(adapter, NETXEN_FW_VERSION_MAJOR);
	fw_minor = NXRD32(adapter, NETXEN_FW_VERSION_MINOR);
	fw_build = NXRD32(adapter, NETXEN_FW_VERSION_SUB);

	adapter->fw_major = fw_major;
	adapter->fw_version = NETXEN_VERSION_CODE(fw_major, fw_minor, fw_build);

	if (adapter->portnum == 0) {
		get_brd_name_by_type(adapter->ahw.board_type, brd_name);

		printk(KERN_INFO "NetXen %s Board S/N %s  Chip rev 0x%x\n",
				brd_name, serial_num, adapter->ahw.revision_id);
	}

	if (adapter->fw_version < NETXEN_VERSION_CODE(3, 4, 216)) {
		adapter->driver_mismatch = 1;
		dev_warn(&pdev->dev, "firmware version %d.%d.%d unsupported\n",
				fw_major, fw_minor, fw_build);
		return;
	}

	dev_info(&pdev->dev, "firmware version %d.%d.%d\n",
			fw_major, fw_minor, fw_build);

	if (NX_IS_REVISION_P3(adapter->ahw.revision_id)) {
		i = NXRD32(adapter, NETXEN_SRE_MISC);
		adapter->ahw.cut_through = (i & 0x8000) ? 1 : 0;
		dev_info(&pdev->dev, "firmware running in %s mode\n",
		adapter->ahw.cut_through ? "cut-through" : "legacy");
	}
}

int
netxen_nic_wol_supported(struct netxen_adapter *adapter)
{
	u32 wol_cfg;

	if (NX_IS_REVISION_P2(adapter->ahw.revision_id))
		return 0;

	wol_cfg = NXRD32(adapter, NETXEN_WOL_CONFIG_NV);
	if (wol_cfg & (1UL << adapter->portnum)) {
		wol_cfg = NXRD32(adapter, NETXEN_WOL_CONFIG);
		if (wol_cfg & (1 << adapter->portnum))
			return 1;
	}

	return 0;
}
