/*
 * Copyright (C) 2003 - 2006 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,
 * 3965 Freedom Circle, Fourth floor,
 * Santa Clara, CA 95054
 *
 *
 * Source file for NIC routines to access the Phantom hardware
 *
 */

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

/*  PCI Windowing for DDR regions.  */

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

#define NETXEN_FLASH_BASE	(BOOTLD_START)
#define NETXEN_PHANTOM_MEM_BASE	(NETXEN_FLASH_BASE)
#define NETXEN_MAX_MTU		8000
#define NETXEN_MIN_MTU		64
#define NETXEN_ETH_FCS_SIZE     4
#define NETXEN_ENET_HEADER_SIZE 14
#define NETXEN_WINDOW_ONE 	0x2000000	/*CRB Window: bit 25 of CRB address */
#define NETXEN_FIRMWARE_LEN 	((16 * 1024) / 4)
#define NETXEN_NIU_HDRSIZE	(0x1 << 6)
#define NETXEN_NIU_TLRSIZE	(0x1 << 5)

#define lower32(x)		((u32)((x) & 0xffffffff))
#define upper32(x)			\
	((u32)(((unsigned long long)(x) >> 32) & 0xffffffff))

#define NETXEN_NIC_ZERO_PAUSE_ADDR     0ULL
#define NETXEN_NIC_UNIT_PAUSE_ADDR     0x200ULL
#define NETXEN_NIC_EPG_PAUSE_ADDR1     0x2200010000c28001ULL
#define NETXEN_NIC_EPG_PAUSE_ADDR2     0x0100088866554433ULL

#define NETXEN_NIC_WINDOW_MARGIN 0x100000

unsigned long netxen_nic_pci_set_window(struct netxen_adapter *adapter,
					unsigned long long addr);
void netxen_free_hw_resources(struct netxen_adapter *adapter);

int netxen_nic_set_mac(struct net_device *netdev, void *p)
{
	struct netxen_port *port = netdev_priv(netdev);
	struct netxen_adapter *adapter = port->adapter;
	struct sockaddr *addr = p;

	if (netif_running(netdev))
		return -EBUSY;

	if (!is_valid_ether_addr(addr->sa_data))
		return -EADDRNOTAVAIL;

	DPRINTK(INFO, "valid ether addr\n");
	memcpy(netdev->dev_addr, addr->sa_data, netdev->addr_len);

	if (adapter->ops->macaddr_set)
		adapter->ops->macaddr_set(port, addr->sa_data);

	return 0;
}

/*
 * netxen_nic_set_multi - Multicast
 */
void netxen_nic_set_multi(struct net_device *netdev)
{
	struct netxen_port *port = netdev_priv(netdev);
	struct netxen_adapter *adapter = port->adapter;
	struct dev_mc_list *mc_ptr;
	__le32 netxen_mac_addr_cntl_data = 0;

	mc_ptr = netdev->mc_list;
	if (netdev->flags & IFF_PROMISC) {
		if (adapter->ops->set_promisc)
			adapter->ops->set_promisc(adapter,
						  port->portnum,
						  NETXEN_NIU_PROMISC_MODE);
	} else {
		if (adapter->ops->unset_promisc &&
		    adapter->ahw.boardcfg.board_type
		    != NETXEN_BRDTYPE_P2_SB31_10G_IMEZ)
			adapter->ops->unset_promisc(adapter,
						    port->portnum,
						    NETXEN_NIU_NON_PROMISC_MODE);
	}
	if (adapter->ahw.board_type == NETXEN_NIC_XGBE) {
		netxen_nic_mcr_set_mode_select(netxen_mac_addr_cntl_data, 0x03);
		netxen_nic_mcr_set_id_pool0(netxen_mac_addr_cntl_data, 0x00);
		netxen_nic_mcr_set_id_pool1(netxen_mac_addr_cntl_data, 0x00);
		netxen_nic_mcr_set_id_pool2(netxen_mac_addr_cntl_data, 0x00);
		netxen_nic_mcr_set_id_pool3(netxen_mac_addr_cntl_data, 0x00);
		netxen_nic_mcr_set_enable_xtnd0(netxen_mac_addr_cntl_data);
		netxen_nic_mcr_set_enable_xtnd1(netxen_mac_addr_cntl_data);
		netxen_nic_mcr_set_enable_xtnd2(netxen_mac_addr_cntl_data);
		netxen_nic_mcr_set_enable_xtnd3(netxen_mac_addr_cntl_data);
	} else {
		netxen_nic_mcr_set_mode_select(netxen_mac_addr_cntl_data, 0x00);
		netxen_nic_mcr_set_id_pool0(netxen_mac_addr_cntl_data, 0x00);
		netxen_nic_mcr_set_id_pool1(netxen_mac_addr_cntl_data, 0x01);
		netxen_nic_mcr_set_id_pool2(netxen_mac_addr_cntl_data, 0x02);
		netxen_nic_mcr_set_id_pool3(netxen_mac_addr_cntl_data, 0x03);
	}
	writel(netxen_mac_addr_cntl_data,
	       NETXEN_CRB_NORMALIZE(adapter, NETXEN_MAC_ADDR_CNTL_REG));
	if (adapter->ahw.board_type == NETXEN_NIC_XGBE) {
		writel(netxen_mac_addr_cntl_data,
		       NETXEN_CRB_NORMALIZE(adapter,
					    NETXEN_MULTICAST_ADDR_HI_0));
	} else {
		writel(netxen_mac_addr_cntl_data,
		       NETXEN_CRB_NORMALIZE(adapter,
					    NETXEN_MULTICAST_ADDR_HI_1));
	}
	netxen_mac_addr_cntl_data = 0;
	writel(netxen_mac_addr_cntl_data,
	       NETXEN_CRB_NORMALIZE(adapter, NETXEN_NIU_GB_DROP_WRONGADDR));
}

/*
 * netxen_nic_change_mtu - Change the Maximum Transfer Unit
 * @returns 0 on success, negative on failure
 */
int netxen_nic_change_mtu(struct net_device *netdev, int mtu)
{
	struct netxen_port *port = netdev_priv(netdev);
	struct netxen_adapter *adapter = port->adapter;
	int eff_mtu = mtu + NETXEN_ENET_HEADER_SIZE + NETXEN_ETH_FCS_SIZE;

	if ((eff_mtu > NETXEN_MAX_MTU) || (eff_mtu < NETXEN_MIN_MTU)) {
		printk(KERN_ERR "%s: %s %d is not supported.\n",
		       netxen_nic_driver_name, netdev->name, mtu);
		return -EINVAL;
	}

	if (adapter->ops->set_mtu)
		adapter->ops->set_mtu(port, mtu);
	netdev->mtu = mtu;

	return 0;
}

/*
 * check if the firmware has been downloaded and ready to run  and
 * setup the address for the descriptors in the adapter
 */
int netxen_nic_hw_resources(struct netxen_adapter *adapter)
{
	struct netxen_hardware_context *hw = &adapter->ahw;
	u32 state = 0;
	void *addr;
	void *pause_addr;
	int loops = 0, err = 0;
	int ctx, ring;
	u32 card_cmdring = 0;
	struct netxen_rcv_desc_crb *rcv_desc_crb = NULL;
	struct netxen_recv_context *recv_ctx;
	struct netxen_rcv_desc_ctx *rcv_desc;

	DPRINTK(INFO, "crb_base: %lx %lx", NETXEN_PCI_CRBSPACE,
		PCI_OFFSET_SECOND_RANGE(adapter, NETXEN_PCI_CRBSPACE));
	DPRINTK(INFO, "cam base: %lx %lx", NETXEN_CRB_CAM,
		pci_base_offset(adapter, NETXEN_CRB_CAM));
	DPRINTK(INFO, "cam RAM: %lx %lx", NETXEN_CAM_RAM_BASE,
		pci_base_offset(adapter, NETXEN_CAM_RAM_BASE));
	DPRINTK(INFO, "NIC base:%lx %lx\n", NIC_CRB_BASE_PORT1,
		pci_base_offset(adapter, NIC_CRB_BASE_PORT1));

	/* Window 1 call */
	card_cmdring = readl(NETXEN_CRB_NORMALIZE(adapter, CRB_CMDPEG_CMDRING));

	DPRINTK(INFO, "Command Peg sends 0x%x for cmdring base\n",
		card_cmdring);

	for (ctx = 0; ctx < MAX_RCV_CTX; ++ctx) {
		DPRINTK(INFO, "Command Peg ready..waiting for rcv peg\n");
		loops = 0;
		state = 0;
		/* Window 1 call */
		state = readl(NETXEN_CRB_NORMALIZE(adapter,
						   recv_crb_registers[ctx].
						   crb_rcvpeg_state));
		while (state != PHAN_PEG_RCV_INITIALIZED && loops < 20) {
			udelay(100);
			/* Window 1 call */
			state = readl(NETXEN_CRB_NORMALIZE(adapter,
							   recv_crb_registers
							   [ctx].
							   crb_rcvpeg_state));
			loops++;
		}
		if (loops >= 20) {
			printk(KERN_ERR "Rcv Peg initialization not complete:"
			       "%x.\n", state);
			err = -EIO;
			return err;
		}
	}
	DPRINTK(INFO, "Recieve Peg ready too. starting stuff\n");

	addr = netxen_alloc(adapter->ahw.pdev,
			    sizeof(struct cmd_desc_type0) *
			    adapter->max_tx_desc_count,
			    &hw->cmd_desc_phys_addr, &hw->cmd_desc_pdev);

	if (addr == NULL) {
		DPRINTK(ERR, "bad return from pci_alloc_consistent\n");
		return -ENOMEM;
	}

	pause_addr = netxen_alloc(adapter->ahw.pdev, 512,
				  (dma_addr_t *) & hw->pause_physaddr,
				  &hw->pause_pdev);
	if (pause_addr == NULL) {
		DPRINTK(1, ERR, "bad return from pci_alloc_consistent\n");
		return -ENOMEM;
	}

	hw->pauseaddr = (char *)pause_addr;
	{
		u64 *ptr = (u64 *) pause_addr;
		*ptr++ = NETXEN_NIC_ZERO_PAUSE_ADDR;
		*ptr++ = NETXEN_NIC_ZERO_PAUSE_ADDR;
		*ptr++ = NETXEN_NIC_UNIT_PAUSE_ADDR;
		*ptr++ = NETXEN_NIC_ZERO_PAUSE_ADDR;
		*ptr++ = NETXEN_NIC_EPG_PAUSE_ADDR1;
		*ptr++ = NETXEN_NIC_EPG_PAUSE_ADDR2;
	}

	hw->cmd_desc_head = (struct cmd_desc_type0 *)addr;

	for (ctx = 0; ctx < MAX_RCV_CTX; ++ctx) {
		recv_ctx = &adapter->recv_ctx[ctx];

		for (ring = 0; ring < NUM_RCV_DESC_RINGS; ring++) {
			rcv_desc = &recv_ctx->rcv_desc[ring];
			addr = netxen_alloc(adapter->ahw.pdev,
					    RCV_DESC_RINGSIZE,
					    &rcv_desc->phys_addr,
					    &rcv_desc->phys_pdev);
			if (addr == NULL) {
				DPRINTK(ERR, "bad return from "
					"pci_alloc_consistent\n");
				netxen_free_hw_resources(adapter);
				err = -ENOMEM;
				return err;
			}
			rcv_desc->desc_head = (struct rcv_desc *)addr;
		}

		addr = netxen_alloc(adapter->ahw.pdev,
				    STATUS_DESC_RINGSIZE,
				    &recv_ctx->
				    rcv_status_desc_phys_addr,
				    &recv_ctx->rcv_status_desc_pdev);
		if (addr == NULL) {
			DPRINTK(ERR, "bad return from"
				" pci_alloc_consistent\n");
			netxen_free_hw_resources(adapter);
			err = -ENOMEM;
			return err;
		}
		recv_ctx->rcv_status_desc_head = (struct status_desc *)addr;
		for (ring = 0; ring < NUM_RCV_DESC_RINGS; ring++) {
			rcv_desc = &recv_ctx->rcv_desc[ring];
			rcv_desc_crb =
			    &recv_crb_registers[ctx].rcv_desc_crb[ring];
			DPRINTK(INFO, "ring #%d crb global ring reg 0x%x\n",
				ring, rcv_desc_crb->crb_globalrcv_ring);
			/* Window = 1 */
			writel(lower32(rcv_desc->phys_addr),
			       NETXEN_CRB_NORMALIZE(adapter,
						    rcv_desc_crb->
						    crb_globalrcv_ring));
			DPRINTK(INFO, "GLOBAL_RCV_RING ctx %d, addr 0x%x"
				" val 0x%llx,"
				" virt %p\n", ctx,
				rcv_desc_crb->crb_globalrcv_ring,
				(unsigned long long)rcv_desc->phys_addr,
				+rcv_desc->desc_head);
		}

		/* Window = 1 */
		writel(lower32(recv_ctx->rcv_status_desc_phys_addr),
		       NETXEN_CRB_NORMALIZE(adapter,
					    recv_crb_registers[ctx].
					    crb_rcvstatus_ring));
		DPRINTK(INFO, "RCVSTATUS_RING, ctx %d, addr 0x%x,"
			" val 0x%x,virt%p\n",
			ctx,
			recv_crb_registers[ctx].crb_rcvstatus_ring,
			(unsigned long long)recv_ctx->rcv_status_desc_phys_addr,
			recv_ctx->rcv_status_desc_head);
	}
	/* Window = 1 */
	writel(lower32(hw->pause_physaddr),
	       NETXEN_CRB_NORMALIZE(adapter, CRB_PAUSE_ADDR_LO));
	writel(upper32(hw->pause_physaddr),
	       NETXEN_CRB_NORMALIZE(adapter, CRB_PAUSE_ADDR_HI));

	writel(lower32(hw->cmd_desc_phys_addr),
	       NETXEN_CRB_NORMALIZE(adapter, CRB_HOST_CMD_ADDR_LO));
	writel(upper32(hw->cmd_desc_phys_addr),
	       NETXEN_CRB_NORMALIZE(adapter, CRB_HOST_CMD_ADDR_HI));
	return err;
}

void netxen_free_hw_resources(struct netxen_adapter *adapter)
{
	struct netxen_recv_context *recv_ctx;
	struct netxen_rcv_desc_ctx *rcv_desc;
	int ctx, ring;

	if (adapter->ahw.cmd_desc_head != NULL) {
		pci_free_consistent(adapter->ahw.cmd_desc_pdev,
				    sizeof(struct cmd_desc_type0) *
				    adapter->max_tx_desc_count,
				    adapter->ahw.cmd_desc_head,
				    adapter->ahw.cmd_desc_phys_addr);
		adapter->ahw.cmd_desc_head = NULL;
	}
	if (adapter->ahw.pauseaddr != NULL) {
		pci_free_consistent(adapter->ahw.pause_pdev, 512,
				    adapter->ahw.pauseaddr,
				    adapter->ahw.pause_physaddr);
		adapter->ahw.pauseaddr = NULL;
	}

	for (ctx = 0; ctx < MAX_RCV_CTX; ++ctx) {
		recv_ctx = &adapter->recv_ctx[ctx];
		for (ring = 0; ring < NUM_RCV_DESC_RINGS; ring++) {
			rcv_desc = &recv_ctx->rcv_desc[ring];

			if (rcv_desc->desc_head != NULL) {
				pci_free_consistent(rcv_desc->phys_pdev,
						    RCV_DESC_RINGSIZE,
						    rcv_desc->desc_head,
						    rcv_desc->phys_addr);
				rcv_desc->desc_head = NULL;
			}
		}

		if (recv_ctx->rcv_status_desc_head != NULL) {
			pci_free_consistent(recv_ctx->rcv_status_desc_pdev,
					    STATUS_DESC_RINGSIZE,
					    recv_ctx->rcv_status_desc_head,
					    recv_ctx->
					    rcv_status_desc_phys_addr);
			recv_ctx->rcv_status_desc_head = NULL;
		}
	}
}

void netxen_tso_check(struct netxen_adapter *adapter,
		      struct cmd_desc_type0 *desc, struct sk_buff *skb)
{
	if (desc->mss) {
		desc->total_hdr_length = sizeof(struct ethhdr) +
		    ((skb->nh.iph)->ihl * sizeof(u32)) +
		    ((skb->h.th)->doff * sizeof(u32));
		desc->opcode = TX_TCP_LSO;
	} else if (skb->ip_summed == CHECKSUM_COMPLETE) {
		if (skb->nh.iph->protocol == IPPROTO_TCP) {
			desc->opcode = TX_TCP_PKT;
		} else if (skb->nh.iph->protocol == IPPROTO_UDP) {
			desc->opcode = TX_UDP_PKT;
		} else {
			return;
		}
	}
	adapter->stats.xmitcsummed++;
	CMD_DESC_TCP_HDR_OFFSET_WRT(desc, skb->h.raw - skb->data);
	desc->length_tcp_hdr = cpu_to_le32(desc->length_tcp_hdr);
	desc->ip_hdr_offset = skb->nh.raw - skb->data;
}

int netxen_is_flash_supported(struct netxen_adapter *adapter)
{
	const int locs[] = { 0, 0x4, 0x100, 0x4000, 0x4128 };
	int addr, val01, val02, i, j;

	/* if the flash size less than 4Mb, make huge war cry and die */
	for (j = 1; j < 4; j++) {
		addr = j * NETXEN_NIC_WINDOW_MARGIN;
		for (i = 0; i < (sizeof(locs) / sizeof(locs[0])); i++) {
			if (netxen_rom_fast_read(adapter, locs[i], &val01) == 0
			    && netxen_rom_fast_read(adapter, (addr + locs[i]),
						    &val02) == 0) {
				if (val01 == val02)
					return -1;
			} else
				return -1;
		}
	}

	return 0;
}

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

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

		if (netxen_rom_fast_read(adapter, addr, &local) == -1)
			return -1;
		memcpy(ptr32, &local, (char *)buf + size - (char *)ptr32);
	}

	return 0;
}

int netxen_get_flash_mac_addr(struct netxen_adapter *adapter, u64 mac[])
{
	u32 *pmac = (u32 *) & mac[0];

	if (netxen_get_flash_block(adapter,
				   USER_START +
				   offsetof(struct netxen_new_user_info,
					    mac_addr),
				   FLASH_NUM_PORTS * sizeof(u64), pmac) == -1) {
		return -1;
	}
	if (*mac == ~0ULL) {
		if (netxen_get_flash_block(adapter,
					   USER_START_OLD +
					   offsetof(struct netxen_user_old_info,
						    mac_addr),
					   FLASH_NUM_PORTS * sizeof(u64),
					   pmac) == -1)
			return -1;
		if (*mac == ~0ULL)
			return -1;
	}
	return 0;
}

/*
 * Changes the CRB window to the specified window.
 */
void netxen_nic_pci_change_crbwindow(struct netxen_adapter *adapter, u32 wndw)
{
	void __iomem *offset;
	u32 tmp;
	int count = 0;

	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(PCIX_CRB_WINDOW));

	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, __FUNCTION__, tmp);
		mdelay(1);
		if (count >= 10)
			break;
		count++;
	}

	adapter->curr_window = wndw;
}

void netxen_load_firmware(struct netxen_adapter *adapter)
{
	int i;
	long data, size = 0;
	long flashaddr = NETXEN_FLASH_BASE, memaddr = NETXEN_PHANTOM_MEM_BASE;
	u64 off;
	void __iomem *addr;

	size = NETXEN_FIRMWARE_LEN;
	writel(1, NETXEN_CRB_NORMALIZE(adapter, NETXEN_ROMUSB_GLB_CAS_RST));

	for (i = 0; i < size; i++) {
		if (netxen_rom_fast_read(adapter, flashaddr, (int *)&data) != 0) {
			DPRINTK(ERR,
				"Error in netxen_rom_fast_read(). Will skip"
				"loading flash image\n");
			return;
		}
		off = netxen_nic_pci_set_window(adapter, memaddr);
		addr = pci_base_offset(adapter, off);
		writel(data, addr);
		flashaddr += 4;
		memaddr += 4;
	}
	udelay(100);
	/* make sure Casper is powered on */
	writel(0x3fff,
	       NETXEN_CRB_NORMALIZE(adapter, NETXEN_ROMUSB_GLB_CHIP_CLK_CTRL));
	writel(0, NETXEN_CRB_NORMALIZE(adapter, NETXEN_ROMUSB_GLB_CAS_RST));

	udelay(100);
}

int
netxen_nic_hw_write_wx(struct netxen_adapter *adapter, u64 off, void *data,
		       int len)
{
	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(adapter, 0);
	}

	DPRINTK(INFO, "writing to base %lx offset %llx addr %p"
		" data %llx len %d\n",
		pci_base(adapter, off), off, addr,
		*(unsigned long long *)data, len);
	if (!addr) {
		netxen_nic_pci_change_crbwindow(adapter, 1);
		return 1;
	}

	switch (len) {
	case 1:
		writeb(*(u8 *) data, addr);
		break;
	case 2:
		writew(*(u16 *) data, addr);
		break;
	case 4:
		writel(*(u32 *) data, addr);
		break;
	case 8:
		writeq(*(u64 *) data, addr);
		break;
	default:
		DPRINTK(INFO,
			"writing data %lx to offset %llx, num words=%d\n",
			*(unsigned long *)data, off, (len >> 3));

		netxen_nic_hw_block_write64((u64 __iomem *) data, addr,
					    (len >> 3));
		break;
	}
	if (!ADDR_IN_WINDOW1(off))
		netxen_nic_pci_change_crbwindow(adapter, 1);

	return 0;
}

int
netxen_nic_hw_read_wx(struct netxen_adapter *adapter, u64 off, void *data,
		      int len)
{
	void __iomem *addr;

	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(adapter, 0);
	}

	DPRINTK(INFO, "reading from base %lx offset %llx addr %p\n",
		pci_base(adapter, off), off, addr);
	if (!addr) {
		netxen_nic_pci_change_crbwindow(adapter, 1);
		return 1;
	}
	switch (len) {
	case 1:
		*(u8 *) data = readb(addr);
		break;
	case 2:
		*(u16 *) data = readw(addr);
		break;
	case 4:
		*(u32 *) data = readl(addr);
		break;
	case 8:
		*(u64 *) data = readq(addr);
		break;
	default:
		netxen_nic_hw_block_read64((u64 __iomem *) data, addr,
					   (len >> 3));
		break;
	}
	DPRINTK(INFO, "read %lx\n", *(unsigned long *)data);

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

	return 0;
}

void netxen_nic_reg_write(struct netxen_adapter *adapter, u64 off, u32 val)
{				/* Only for window 1 */
	void __iomem *addr;

	addr = NETXEN_CRB_NORMALIZE(adapter, off);
	DPRINTK(INFO, "writing to base %lx offset %llx addr %p data %x\n",
		pci_base(adapter, off), off, addr);
	writel(val, addr);

}

int netxen_nic_reg_read(struct netxen_adapter *adapter, u64 off)
{				/* Only for window 1 */
	void __iomem *addr;
	int val;

	addr = NETXEN_CRB_NORMALIZE(adapter, off);
	DPRINTK(INFO, "reading from base %lx offset %llx addr %p\n",
		adapter->ahw.pci_base, off, addr);
	val = readl(addr);
	writel(val, addr);

	return val;
}

/* Change the window to 0, write and change back to window 1. */
void netxen_nic_write_w0(struct netxen_adapter *adapter, u32 index, u32 value)
{
	void __iomem *addr;

	netxen_nic_pci_change_crbwindow(adapter, 0);
	addr = (void __iomem *)(pci_base_offset(adapter, index));
	writel(value, addr);
	netxen_nic_pci_change_crbwindow(adapter, 1);
}

/* Change the window to 0, read and change back to window 1. */
void netxen_nic_read_w0(struct netxen_adapter *adapter, u32 index, u32 * value)
{
	void __iomem *addr;

	addr = (void __iomem *)(pci_base_offset(adapter, index));

	netxen_nic_pci_change_crbwindow(adapter, 0);
	*value = readl(addr);
	netxen_nic_pci_change_crbwindow(adapter, 1);
}

int netxen_pci_set_window_warning_count = 0;

unsigned long
netxen_nic_pci_set_window(struct netxen_adapter *adapter,
			  unsigned long long addr)
{
	static int ddr_mn_window = -1;
	static int qdr_sn_window = -1;
	int window;

	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 (ddr_mn_window != window) {
			ddr_mn_window = window;
			writel(window, PCI_OFFSET_SECOND_RANGE(adapter,
							       NETXEN_PCIX_PH_REG
							       (PCIX_MN_WINDOW)));
			/* MUST make sure window is set before we forge on... */
			readl(PCI_OFFSET_SECOND_RANGE(adapter,
						      NETXEN_PCIX_PH_REG
						      (PCIX_MN_WINDOW)));
		}
		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, NETXEN_ADDR_QDR_NET_MAX)) {
		/* QDR network side */
		addr -= NETXEN_ADDR_QDR_NET;
		window = (addr >> 22) & 0x3f;
		if (qdr_sn_window != window) {
			qdr_sn_window = window;
			writel((window << 22),
			       PCI_OFFSET_SECOND_RANGE(adapter,
						       NETXEN_PCIX_PH_REG
						       (PCIX_SN_WINDOW)));
			/* MUST make sure window is set before we forge on... */
			readl(PCI_OFFSET_SECOND_RANGE(adapter,
						      NETXEN_PCIX_PH_REG
						      (PCIX_SN_WINDOW)));
		}
		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);

	}
	return addr;
}

int netxen_nic_get_board_info(struct netxen_adapter *adapter)
{
	int rv = 0;
	int addr = BRDCFG_START;
	struct netxen_board_info *boardinfo;
	int index;
	u32 *ptr32;

	boardinfo = &adapter->ahw.boardcfg;
	ptr32 = (u32 *) boardinfo;

	for (index = 0; index < sizeof(struct netxen_board_info) / sizeof(u32);
	     index++) {
		if (netxen_rom_fast_read(adapter, addr, ptr32) == -1) {
			return -EIO;
		}
		ptr32++;
		addr += sizeof(u32);
	}
	if (boardinfo->magic != NETXEN_BDINFO_MAGIC) {
		printk("%s: ERROR reading %s board config."
		       " Read %x, expected %x\n", netxen_nic_driver_name,
		       netxen_nic_driver_name,
		       boardinfo->magic, NETXEN_BDINFO_MAGIC);
		rv = -1;
	}
	if (boardinfo->header_version != NETXEN_BDINFO_VERSION) {
		printk("%s: Unknown board config version."
		       " Read %x, expected %x\n", netxen_nic_driver_name,
		       boardinfo->header_version, NETXEN_BDINFO_VERSION);
		rv = -1;
	}

	DPRINTK(INFO, "Discovered board type:0x%x  ", boardinfo->board_type);
	switch ((netxen_brdtype_t) boardinfo->board_type) {
	case NETXEN_BRDTYPE_P2_SB35_4G:
		adapter->ahw.board_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:
		adapter->ahw.board_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:
		adapter->ahw.board_type = NETXEN_NIC_GBE;
		break;
	default:
		printk("%s: Unknown(%x)\n", netxen_nic_driver_name,
		       boardinfo->board_type);
		break;
	}

	return rv;
}

/* NIU access sections */

int netxen_nic_set_mtu_gb(struct netxen_port *port, int new_mtu)
{
	struct netxen_adapter *adapter = port->adapter;
	netxen_nic_write_w0(adapter,
			    NETXEN_NIU_GB_MAX_FRAME_SIZE(port->portnum),
			    new_mtu);
	return 0;
}

int netxen_nic_set_mtu_xgb(struct netxen_port *port, int new_mtu)
{
	struct netxen_adapter *adapter = port->adapter;
	new_mtu += NETXEN_NIU_HDRSIZE + NETXEN_NIU_TLRSIZE;
	netxen_nic_write_w0(adapter, NETXEN_NIU_XGE_MAX_FRAME_SIZE, new_mtu);
	return 0;
}

void netxen_nic_init_niu_gb(struct netxen_adapter *adapter)
{
	int portno;
	for (portno = 0; portno < NETXEN_NIU_MAX_GBE_PORTS; portno++)
		netxen_niu_gbe_init_port(adapter, portno);
}

void netxen_nic_stop_all_ports(struct netxen_adapter *adapter)
{
	int port_nr;
	struct netxen_port *port;

	for (port_nr = 0; port_nr < adapter->ahw.max_ports; port_nr++) {
		port = adapter->port[port_nr];
		if (adapter->ops->stop_port)
			adapter->ops->stop_port(adapter, port->portnum);
	}
}

void
netxen_crb_writelit_adapter(struct netxen_adapter *adapter, unsigned long off,
			    int data)
{
	void __iomem *addr;

	if (ADDR_IN_WINDOW1(off)) {
		writel(data, NETXEN_CRB_NORMALIZE(adapter, off));
	} else {
		netxen_nic_pci_change_crbwindow(adapter, 0);
		addr = (void __iomem *)(pci_base_offset(adapter, off));
		writel(data, addr);
		netxen_nic_pci_change_crbwindow(adapter, 1);
	}
}

void netxen_nic_set_link_parameters(struct netxen_port *port)
{
	struct netxen_adapter *adapter = port->adapter;
	__le32 status;
	u16 autoneg;
	__le32 mode;

	netxen_nic_read_w0(adapter, NETXEN_NIU_MODE, &mode);
	if (netxen_get_niu_enable_ge(mode)) {	/* Gb 10/100/1000 Mbps mode */
		if (adapter->ops->phy_read
		    && adapter->ops->
		    phy_read(adapter, port->portnum,
			     NETXEN_NIU_GB_MII_MGMT_ADDR_PHY_STATUS,
			     &status) == 0) {
			if (netxen_get_phy_link(status)) {
				switch (netxen_get_phy_speed(status)) {
				case 0:
					port->link_speed = SPEED_10;
					break;
				case 1:
					port->link_speed = SPEED_100;
					break;
				case 2:
					port->link_speed = SPEED_1000;
					break;
				default:
					port->link_speed = -1;
					break;
				}
				switch (netxen_get_phy_duplex(status)) {
				case 0:
					port->link_duplex = DUPLEX_HALF;
					break;
				case 1:
					port->link_duplex = DUPLEX_FULL;
					break;
				default:
					port->link_duplex = -1;
					break;
				}
				if (adapter->ops->phy_read
				    && adapter->ops->
				    phy_read(adapter, port->portnum,
					     NETXEN_NIU_GB_MII_MGMT_ADDR_AUTONEG,
					     (__le32 *) & autoneg) != 0)
					port->link_autoneg = autoneg;
			} else
				goto link_down;
		} else {
		      link_down:
			port->link_speed = -1;
			port->link_duplex = -1;
		}
	}
}

void netxen_nic_flash_print(struct netxen_adapter *adapter)
{
	int valid = 1;
	u32 fw_major = 0;
	u32 fw_minor = 0;
	u32 fw_build = 0;
	char brd_name[NETXEN_MAX_SHORT_NAME];
	struct netxen_new_user_info user_info;
	int i, addr = USER_START;
	u32 *ptr32;

	struct netxen_board_info *board_info = &(adapter->ahw.boardcfg);
	if (board_info->magic != NETXEN_BDINFO_MAGIC) {
		printk
		    ("NetXen Unknown board config, Read 0x%x expected as 0x%x\n",
		     board_info->magic, NETXEN_BDINFO_MAGIC);
		valid = 0;
	}
	if (board_info->header_version != NETXEN_BDINFO_VERSION) {
		printk("NetXen Unknown board config version."
		       " Read %x, expected %x\n",
		       board_info->header_version, NETXEN_BDINFO_VERSION);
		valid = 0;
	}
	if (valid) {
		ptr32 = (u32 *) & user_info;
		for (i = 0;
		     i < sizeof(struct netxen_new_user_info) / sizeof(u32);
		     i++) {
			if (netxen_rom_fast_read(adapter, addr, ptr32) == -1) {
				printk("%s: ERROR reading %s board userarea.\n",
				       netxen_nic_driver_name,
				       netxen_nic_driver_name);
				return;
			}
			ptr32++;
			addr += sizeof(u32);
		}
		get_brd_name_by_type(board_info->board_type, brd_name);

		printk("NetXen %s Board S/N %s  Chip id 0x%x\n",
		       brd_name, user_info.serial_num, board_info->chip_id);

		printk("NetXen %s Board #%d, Chip id 0x%x\n",
		       board_info->board_type == 0x0b ? "XGB" : "GBE",
		       board_info->board_num, board_info->chip_id);
		fw_major = readl(NETXEN_CRB_NORMALIZE(adapter,
						      NETXEN_FW_VERSION_MAJOR));
		fw_minor = readl(NETXEN_CRB_NORMALIZE(adapter,
						      NETXEN_FW_VERSION_MINOR));
		fw_build =
		    readl(NETXEN_CRB_NORMALIZE(adapter, NETXEN_FW_VERSION_SUB));

		printk("NetXen Firmware version %d.%d.%d\n", fw_major, fw_minor,
		       fw_build);
	}
	if (fw_major != _NETXEN_NIC_LINUX_MAJOR) {
		printk(KERN_ERR "The mismatch in driver version and firmware "
		       "version major number\n"
		       "Driver version major number = %d \t"
		       "Firmware version major number = %d \n",
		       _NETXEN_NIC_LINUX_MAJOR, fw_major);
		adapter->driver_mismatch = 1;
	}
	if (fw_minor != _NETXEN_NIC_LINUX_MINOR) {
		printk(KERN_ERR "The mismatch in driver version and firmware "
		       "version minor number\n"
		       "Driver version minor number = %d \t"
		       "Firmware version minor number = %d \n",
		       _NETXEN_NIC_LINUX_MINOR, fw_minor);
		adapter->driver_mismatch = 1;
	}
	if (adapter->driver_mismatch)
		printk(KERN_INFO "Use the driver with version no %d.%d.xxx\n",
		       fw_major, fw_minor);
}

int netxen_crb_read_val(struct netxen_adapter *adapter, unsigned long off)
{
	int data;
	netxen_nic_hw_read_wx(adapter, off, &data, 4);
	return data;
}
