/*
 * Copyright (C) 2008 Michael Brown <mbrown@fensystems.co.uk>.
 * Copyright (C) 2008 NetXen, Inc.
 *
 * 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 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., 51 Franklin Street, Fifth Floor, Boston, MA
 * 02110-1301, USA.
 *
 * You can also choose to distribute this program under the terms of
 * the Unmodified Binary Distribution Licence (as given in the file
 * COPYING.UBDL), provided that you have satisfied its requirements.
 */

FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );

#include <stdint.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <errno.h>
#include <assert.h>
#include <byteswap.h>
#include <ipxe/pci.h>
#include <ipxe/io.h>
#include <ipxe/malloc.h>
#include <ipxe/iobuf.h>
#include <ipxe/netdevice.h>
#include <ipxe/if_ether.h>
#include <ipxe/ethernet.h>
#include <ipxe/spi.h>
#include <ipxe/settings.h>
#include "phantom.h"

/**
 * @file
 *
 * NetXen Phantom NICs
 *
 */

/** Maximum number of ports */
#define PHN_MAX_NUM_PORTS 8

/** Maximum time to wait for command PEG to initialise
 *
 * BUGxxxx
 *
 * The command PEG will currently report initialisation complete only
 * when at least one PHY has detected a link (so that the global PHY
 * clock can be set to 10G/1G as appropriate).  This can take a very,
 * very long time.
 *
 * A future firmware revision should decouple PHY initialisation from
 * firmware initialisation, at which point the command PEG will report
 * initialisation complete much earlier, and this timeout can be
 * reduced.
 */
#define PHN_CMDPEG_INIT_TIMEOUT_SEC 50

/** Maximum time to wait for receive PEG to initialise */
#define PHN_RCVPEG_INIT_TIMEOUT_SEC 2

/** Maximum time to wait for firmware to accept a command */
#define PHN_ISSUE_CMD_TIMEOUT_MS 2000

/** Maximum time to wait for test memory */
#define PHN_TEST_MEM_TIMEOUT_MS 100

/** Maximum time to wait for CLP command to be issued */
#define PHN_CLP_CMD_TIMEOUT_MS 500

/** Link state poll frequency
 *
 * The link state will be checked once in every N calls to poll().
 */
#define PHN_LINK_POLL_FREQUENCY 4096

/** Number of RX descriptors */
#define PHN_NUM_RDS 32

/** RX maximum fill level.  Must be strictly less than PHN_NUM_RDS. */
#define PHN_RDS_MAX_FILL 16

/** RX buffer size */
#define PHN_RX_BUFSIZE ( 32 /* max LL padding added by card */ + \
			 ETH_FRAME_LEN )

/** Number of RX status descriptors */
#define PHN_NUM_SDS 32

/** Number of TX descriptors */
#define PHN_NUM_CDS 8

/** A Phantom descriptor ring set */
struct phantom_descriptor_rings {
	/** RX descriptors */
	struct phantom_rds rds[PHN_NUM_RDS];
	/** RX status descriptors */
	struct phantom_sds sds[PHN_NUM_SDS];
	/** TX descriptors */
	union phantom_cds cds[PHN_NUM_CDS];
	/** TX consumer index */
	volatile uint32_t cmd_cons;
};

/** RX context creation request and response buffers */
struct phantom_create_rx_ctx_rqrsp {
	struct {
		struct nx_hostrq_rx_ctx_s rx_ctx;
		struct nx_hostrq_rds_ring_s rds;
		struct nx_hostrq_sds_ring_s sds;
	} __unm_dma_aligned hostrq;
	struct {
		struct nx_cardrsp_rx_ctx_s rx_ctx;
		struct nx_cardrsp_rds_ring_s rds;
		struct nx_cardrsp_sds_ring_s sds;
	} __unm_dma_aligned cardrsp;
};

/** TX context creation request and response buffers */
struct phantom_create_tx_ctx_rqrsp {
	struct {
		struct nx_hostrq_tx_ctx_s tx_ctx;
	} __unm_dma_aligned hostrq;
	struct {
		struct nx_cardrsp_tx_ctx_s tx_ctx;
	} __unm_dma_aligned cardrsp;
};

/** A Phantom NIC */
struct phantom_nic {
	/** BAR 0 */
	void *bar0;
	/** Current CRB window */
	unsigned long crb_window;
	/** CRB window access method */
	unsigned long ( *crb_access ) ( struct phantom_nic *phantom,
					unsigned long reg );


	/** Port number */
	unsigned int port;


	/** RX context ID */
	uint16_t rx_context_id;
	/** RX descriptor producer CRB offset */
	unsigned long rds_producer_crb;
	/** RX status descriptor consumer CRB offset */
	unsigned long sds_consumer_crb;
	/** RX interrupt mask CRB offset */
	unsigned long sds_irq_mask_crb;
	/** RX interrupts enabled */
	unsigned int sds_irq_enabled;

	/** RX producer index */
	unsigned int rds_producer_idx;
	/** RX consumer index */
	unsigned int rds_consumer_idx;
	/** RX status consumer index */
	unsigned int sds_consumer_idx;
	/** RX I/O buffers */
	struct io_buffer *rds_iobuf[PHN_RDS_MAX_FILL];


	/** TX context ID */
	uint16_t tx_context_id;
	/** TX descriptor producer CRB offset */
	unsigned long cds_producer_crb;

	/** TX producer index */
	unsigned int cds_producer_idx;
	/** TX consumer index */
	unsigned int cds_consumer_idx;
	/** TX I/O buffers */
	struct io_buffer *cds_iobuf[PHN_NUM_CDS];


	/** Descriptor rings */
	struct phantom_descriptor_rings *desc;


	/** Last known link state */
	uint32_t link_state;
	/** Link state poll timer */
	unsigned long link_poll_timer;


	/** Non-volatile settings */
	struct settings settings;
};

/** Interrupt mask registers */
static const unsigned long phantom_irq_mask_reg[PHN_MAX_NUM_PORTS] = {
	UNM_PCIE_IRQ_MASK_F0,
	UNM_PCIE_IRQ_MASK_F1,
	UNM_PCIE_IRQ_MASK_F2,
	UNM_PCIE_IRQ_MASK_F3,
	UNM_PCIE_IRQ_MASK_F4,
	UNM_PCIE_IRQ_MASK_F5,
	UNM_PCIE_IRQ_MASK_F6,
	UNM_PCIE_IRQ_MASK_F7,
};

/** Interrupt status registers */
static const unsigned long phantom_irq_status_reg[PHN_MAX_NUM_PORTS] = {
	UNM_PCIE_IRQ_STATUS_F0,
	UNM_PCIE_IRQ_STATUS_F1,
	UNM_PCIE_IRQ_STATUS_F2,
	UNM_PCIE_IRQ_STATUS_F3,
	UNM_PCIE_IRQ_STATUS_F4,
	UNM_PCIE_IRQ_STATUS_F5,
	UNM_PCIE_IRQ_STATUS_F6,
	UNM_PCIE_IRQ_STATUS_F7,
};

/***************************************************************************
 *
 * CRB register access
 *
 */

/**
 * Prepare for access to CRB register via 128MB BAR
 *
 * @v phantom		Phantom NIC
 * @v reg		Register offset within abstract address space
 * @ret offset		Register offset within PCI BAR0
 */
static unsigned long phantom_crb_access_128m ( struct phantom_nic *phantom,
					       unsigned long reg ) {
	unsigned long offset = ( 0x6000000 + ( reg & 0x1ffffff ) );
	uint32_t window = ( reg & 0x2000000 );
	uint32_t verify_window;

	if ( phantom->crb_window != window ) {

		/* Write to the CRB window register */
		writel ( window, phantom->bar0 + UNM_128M_CRB_WINDOW );

		/* Ensure that the write has reached the card */
		verify_window = readl ( phantom->bar0 + UNM_128M_CRB_WINDOW );
		assert ( verify_window == window );

		/* Record new window */
		phantom->crb_window = window;
	}

	return offset;
}

/**
 * Prepare for access to CRB register via 32MB BAR
 *
 * @v phantom		Phantom NIC
 * @v reg		Register offset within abstract address space
 * @ret offset		Register offset within PCI BAR0
 */
static unsigned long phantom_crb_access_32m ( struct phantom_nic *phantom,
					      unsigned long reg ) {
	unsigned long offset = ( reg & 0x1ffffff );
	uint32_t window = ( reg & 0x2000000 );
	uint32_t verify_window;

	if ( phantom->crb_window != window ) {

		/* Write to the CRB window register */
		writel ( window, phantom->bar0 + UNM_32M_CRB_WINDOW );

		/* Ensure that the write has reached the card */
		verify_window = readl ( phantom->bar0 + UNM_32M_CRB_WINDOW );
		assert ( verify_window == window );

		/* Record new window */
		phantom->crb_window = window;
	}

	return offset;
}

/**
 * Prepare for access to CRB register via 2MB BAR
 *
 * @v phantom		Phantom NIC
 * @v reg		Register offset within abstract address space
 * @ret offset		Register offset within PCI BAR0
 */
static unsigned long phantom_crb_access_2m ( struct phantom_nic *phantom,
					     unsigned long reg ) {
	static const struct {
		uint8_t block;
		uint16_t window_hi;
	} reg_window_hi[] = {
		{ UNM_CRB_BLK_PCIE,	0x773 },
		{ UNM_CRB_BLK_CAM,	0x416 },
		{ UNM_CRB_BLK_ROMUSB,	0x421 },
		{ UNM_CRB_BLK_TEST,	0x295 },
		{ UNM_CRB_BLK_PEG_0,	0x340 },
		{ UNM_CRB_BLK_PEG_1,	0x341 },
		{ UNM_CRB_BLK_PEG_2,	0x342 },
		{ UNM_CRB_BLK_PEG_3,	0x343 },
		{ UNM_CRB_BLK_PEG_4,	0x34b },
	};
	unsigned int block = UNM_CRB_BLK ( reg );
	unsigned long offset = UNM_CRB_OFFSET ( reg );
	uint32_t window;
	uint32_t verify_window;
	unsigned int i;

	for ( i = 0 ; i < ( sizeof ( reg_window_hi ) /
			    sizeof ( reg_window_hi[0] ) ) ; i++ ) {

		if ( reg_window_hi[i].block != block )
			continue;

		window = ( ( reg_window_hi[i].window_hi << 20 ) |
			   ( offset & 0x000f0000 ) );

		if ( phantom->crb_window != window ) {

			/* Write to the CRB window register */
			writel ( window, phantom->bar0 + UNM_2M_CRB_WINDOW );

			/* Ensure that the write has reached the card */
			verify_window = readl ( phantom->bar0 +
						UNM_2M_CRB_WINDOW );
			assert ( verify_window == window );

			/* Record new window */
			phantom->crb_window = window;
		}

		return ( 0x1e0000 + ( offset & 0xffff ) );
	}

	assert ( 0 );
	return 0;
}

/**
 * Read from Phantom CRB register
 *
 * @v phantom		Phantom NIC
 * @v reg		Register offset within abstract address space
 * @ret	value		Register value
 */
static uint32_t phantom_readl ( struct phantom_nic *phantom,
				unsigned long reg ) {
	unsigned long offset;

	offset = phantom->crb_access ( phantom, reg );
	return readl ( phantom->bar0 + offset );
}

/**
 * Write to Phantom CRB register
 *
 * @v phantom		Phantom NIC
 * @v value		Register value
 * @v reg		Register offset within abstract address space
 */
static void phantom_writel ( struct phantom_nic *phantom, uint32_t value,
			     unsigned long reg ) {
	unsigned long offset;

	offset = phantom->crb_access ( phantom, reg );
	writel ( value, phantom->bar0 + offset );
}

/**
 * Write to Phantom CRB HI/LO register pair
 *
 * @v phantom		Phantom NIC
 * @v value		Register value
 * @v lo_offset		LO register offset within CRB
 * @v hi_offset		HI register offset within CRB
 */
static inline void phantom_write_hilo ( struct phantom_nic *phantom,
					uint64_t value,
					unsigned long lo_offset,
					unsigned long hi_offset ) {
	uint32_t lo = ( value & 0xffffffffUL );
	uint32_t hi = ( value >> 32 );

	phantom_writel ( phantom, lo, lo_offset );
	phantom_writel ( phantom, hi, hi_offset );
}

/***************************************************************************
 *
 * Firmware message buffer access (for debug)
 *
 */

/**
 * Read from Phantom test memory
 *
 * @v phantom		Phantom NIC
 * @v offset		Offset within test memory
 * @v buf		8-byte buffer to fill
 * @ret rc		Return status code
 */
static int phantom_read_test_mem_block ( struct phantom_nic *phantom,
					 unsigned long offset,
					 uint32_t buf[2] ) {
	unsigned int retries;
	uint32_t test_control;

	phantom_write_hilo ( phantom, offset, UNM_TEST_ADDR_LO,
			     UNM_TEST_ADDR_HI );
	phantom_writel ( phantom, UNM_TEST_CONTROL_ENABLE, UNM_TEST_CONTROL );
	phantom_writel ( phantom,
			 ( UNM_TEST_CONTROL_ENABLE | UNM_TEST_CONTROL_START ),
			 UNM_TEST_CONTROL );
	
	for ( retries = 0 ; retries < PHN_TEST_MEM_TIMEOUT_MS ; retries++ ) {
		test_control = phantom_readl ( phantom, UNM_TEST_CONTROL );
		if ( ( test_control & UNM_TEST_CONTROL_BUSY ) == 0 ) {
			buf[0] = phantom_readl ( phantom, UNM_TEST_RDDATA_LO );
			buf[1] = phantom_readl ( phantom, UNM_TEST_RDDATA_HI );
			return 0;
		}
		mdelay ( 1 );
	}

	DBGC ( phantom, "Phantom %p timed out waiting for test memory\n",
	       phantom );
	return -ETIMEDOUT;
}

/**
 * Read single byte from Phantom test memory
 *
 * @v phantom		Phantom NIC
 * @v offset		Offset within test memory
 * @ret byte		Byte read, or negative error
 */
static int phantom_read_test_mem ( struct phantom_nic *phantom,
				   unsigned long offset ) {
	static union {
		uint8_t bytes[8];
		uint32_t dwords[2];
	} cache;
	static unsigned long cache_offset = -1UL;
	unsigned long sub_offset;
	int rc;

	sub_offset = ( offset & ( sizeof ( cache ) - 1 ) );
	offset = ( offset & ~( sizeof ( cache ) - 1 ) );

	if ( cache_offset != offset ) {
		if ( ( rc = phantom_read_test_mem_block ( phantom, offset,
							  cache.dwords )) !=0 )
			return rc;
		cache_offset = offset;
	}

	return cache.bytes[sub_offset];
}

/**
 * Dump Phantom firmware dmesg log
 *
 * @v phantom		Phantom NIC
 * @v log		Log number
 * @v max_lines		Maximum number of lines to show, or -1 to show all
 * @ret rc		Return status code
 */
static int phantom_dmesg ( struct phantom_nic *phantom, unsigned int log,
			    unsigned int max_lines ) {
	uint32_t head;
	uint32_t tail;
	uint32_t sig;
	uint32_t offset;
	int byte;

	/* Optimise out for non-debug builds */
	if ( ! DBG_LOG )
		return 0;

	/* Locate log */
	head = phantom_readl ( phantom, UNM_CAM_RAM_DMESG_HEAD ( log ) );
	tail = phantom_readl ( phantom, UNM_CAM_RAM_DMESG_TAIL ( log ) );
	sig = phantom_readl ( phantom, UNM_CAM_RAM_DMESG_SIG ( log ) );
	DBGC ( phantom, "Phantom %p firmware dmesg buffer %d (%08x-%08x)\n",
	       phantom, log, head, tail );
	assert ( ( head & 0x07 ) == 0 );
	if ( sig != UNM_CAM_RAM_DMESG_SIG_MAGIC ) {
		DBGC ( phantom, "Warning: bad signature %08x (want %08lx)\n",
		       sig, UNM_CAM_RAM_DMESG_SIG_MAGIC );
	}

	/* Locate start of last (max_lines) lines */
	for ( offset = tail ; offset > head ; offset-- ) {
		if ( ( byte = phantom_read_test_mem ( phantom,
						      ( offset - 1 ) ) ) < 0 )
			return byte;
		if ( ( byte == '\n' ) && ( max_lines-- == 0 ) )
			break;
	}

	/* Print lines */
	for ( ; offset < tail ; offset++ ) {
		if ( ( byte = phantom_read_test_mem ( phantom, offset ) ) < 0 )
			return byte;
		DBG ( "%c", byte );
	}
	DBG ( "\n" );
	return 0;
}

/**
 * Dump Phantom firmware dmesg logs
 *
 * @v phantom		Phantom NIC
 * @v max_lines		Maximum number of lines to show, or -1 to show all
 */
static void __attribute__ (( unused ))
phantom_dmesg_all ( struct phantom_nic *phantom, unsigned int max_lines ) {
	unsigned int i;

	for ( i = 0 ; i < UNM_CAM_RAM_NUM_DMESG_BUFFERS ; i++ )
		phantom_dmesg ( phantom, i, max_lines );
}

/***************************************************************************
 *
 * Firmware interface
 *
 */

/**
 * Wait for firmware to accept command
 *
 * @v phantom		Phantom NIC
 * @ret rc		Return status code
 */
static int phantom_wait_for_cmd ( struct phantom_nic *phantom ) {
	unsigned int retries;
	uint32_t cdrp;

	for ( retries = 0 ; retries < PHN_ISSUE_CMD_TIMEOUT_MS ; retries++ ) {
		mdelay ( 1 );
		cdrp = phantom_readl ( phantom, UNM_NIC_REG_NX_CDRP );
		if ( NX_CDRP_IS_RSP ( cdrp ) ) {
			switch ( NX_CDRP_FORM_RSP ( cdrp ) ) {
			case NX_CDRP_RSP_OK:
				return 0;
			case NX_CDRP_RSP_FAIL:
				return -EIO;
			case NX_CDRP_RSP_TIMEOUT:
				return -ETIMEDOUT;
			default:
				return -EPROTO;
			}
		}
	}

	DBGC ( phantom, "Phantom %p timed out waiting for firmware to accept "
	       "command\n", phantom );
	return -ETIMEDOUT;
}

/**
 * Issue command to firmware
 *
 * @v phantom		Phantom NIC
 * @v command		Firmware command
 * @v arg1		Argument 1
 * @v arg2		Argument 2
 * @v arg3		Argument 3
 * @ret rc		Return status code
 */
static int phantom_issue_cmd ( struct phantom_nic *phantom,
			       uint32_t command, uint32_t arg1, uint32_t arg2,
			       uint32_t arg3 ) {
	uint32_t signature;
	int rc;

	/* Issue command */
	signature = NX_CDRP_SIGNATURE_MAKE ( phantom->port,
					     NXHAL_VERSION );
	DBGC2 ( phantom, "Phantom %p issuing command %08x (%08x, %08x, "
		"%08x)\n", phantom, command, arg1, arg2, arg3 );
	phantom_writel ( phantom, signature, UNM_NIC_REG_NX_SIGN );
	phantom_writel ( phantom, arg1, UNM_NIC_REG_NX_ARG1 );
	phantom_writel ( phantom, arg2, UNM_NIC_REG_NX_ARG2 );
	phantom_writel ( phantom, arg3, UNM_NIC_REG_NX_ARG3 );
	phantom_writel ( phantom, NX_CDRP_FORM_CMD ( command ),
			 UNM_NIC_REG_NX_CDRP );

	/* Wait for command to be accepted */
	if ( ( rc = phantom_wait_for_cmd ( phantom ) ) != 0 ) {
		DBGC ( phantom, "Phantom %p could not issue command: %s\n",
		       phantom, strerror ( rc ) );
		return rc;
	}

	return 0;
}

/**
 * Issue buffer-format command to firmware
 *
 * @v phantom		Phantom NIC
 * @v command		Firmware command
 * @v buffer		Buffer to pass to firmware
 * @v len		Length of buffer
 * @ret rc		Return status code
 */
static int phantom_issue_buf_cmd ( struct phantom_nic *phantom,
				   uint32_t command, void *buffer,
				   size_t len ) {
	uint64_t physaddr;

	physaddr = virt_to_bus ( buffer );
	return phantom_issue_cmd ( phantom, command, ( physaddr >> 32 ),
				   ( physaddr & 0xffffffffUL ), len );
}

/**
 * Create Phantom RX context
 *
 * @v phantom		Phantom NIC
 * @ret rc		Return status code
 */
static int phantom_create_rx_ctx ( struct phantom_nic *phantom ) {
	struct phantom_create_rx_ctx_rqrsp *buf;
	int rc;

	/* Allocate context creation buffer */
	buf = malloc_phys ( sizeof ( *buf ), UNM_DMA_BUFFER_ALIGN );
	if ( ! buf ) {
		rc = -ENOMEM;
		goto out;
	}
	memset ( buf, 0, sizeof ( *buf ) );
	
	/* Prepare request */
	buf->hostrq.rx_ctx.host_rsp_dma_addr =
		cpu_to_le64 ( virt_to_bus ( &buf->cardrsp ) );
	buf->hostrq.rx_ctx.capabilities[0] =
		cpu_to_le32 ( NX_CAP0_LEGACY_CONTEXT | NX_CAP0_LEGACY_MN );
	buf->hostrq.rx_ctx.host_int_crb_mode =
		cpu_to_le32 ( NX_HOST_INT_CRB_MODE_SHARED );
	buf->hostrq.rx_ctx.host_rds_crb_mode =
		cpu_to_le32 ( NX_HOST_RDS_CRB_MODE_UNIQUE );
	buf->hostrq.rx_ctx.rds_ring_offset = cpu_to_le32 ( 0 );
	buf->hostrq.rx_ctx.sds_ring_offset =
		cpu_to_le32 ( sizeof ( buf->hostrq.rds ) );
	buf->hostrq.rx_ctx.num_rds_rings = cpu_to_le16 ( 1 );
	buf->hostrq.rx_ctx.num_sds_rings = cpu_to_le16 ( 1 );
	buf->hostrq.rds.host_phys_addr =
		cpu_to_le64 ( virt_to_bus ( phantom->desc->rds ) );
	buf->hostrq.rds.buff_size = cpu_to_le64 ( PHN_RX_BUFSIZE );
	buf->hostrq.rds.ring_size = cpu_to_le32 ( PHN_NUM_RDS );
	buf->hostrq.rds.ring_kind = cpu_to_le32 ( NX_RDS_RING_TYPE_NORMAL );
	buf->hostrq.sds.host_phys_addr =
		cpu_to_le64 ( virt_to_bus ( phantom->desc->sds ) );
	buf->hostrq.sds.ring_size = cpu_to_le32 ( PHN_NUM_SDS );

	DBGC ( phantom, "Phantom %p creating RX context\n", phantom );
	DBGC2_HDA ( phantom, virt_to_bus ( &buf->hostrq ),
		    &buf->hostrq, sizeof ( buf->hostrq ) );

	/* Issue request */
	if ( ( rc = phantom_issue_buf_cmd ( phantom,
					    NX_CDRP_CMD_CREATE_RX_CTX,
					    &buf->hostrq,
					    sizeof ( buf->hostrq ) ) ) != 0 ) {
		DBGC ( phantom, "Phantom %p could not create RX context: "
		       "%s\n", phantom, strerror ( rc ) );
		DBGC ( phantom, "Request:\n" );
		DBGC_HDA ( phantom, virt_to_bus ( &buf->hostrq ),
			   &buf->hostrq, sizeof ( buf->hostrq ) );
		DBGC ( phantom, "Response:\n" );
		DBGC_HDA ( phantom, virt_to_bus ( &buf->cardrsp ),
			   &buf->cardrsp, sizeof ( buf->cardrsp ) );
		goto out;
	}

	/* Retrieve context parameters */
	phantom->rx_context_id =
		le16_to_cpu ( buf->cardrsp.rx_ctx.context_id );
	phantom->rds_producer_crb =
		( UNM_CAM_RAM +
		  le32_to_cpu ( buf->cardrsp.rds.host_producer_crb ) );
	phantom->sds_consumer_crb =
		( UNM_CAM_RAM +
		  le32_to_cpu ( buf->cardrsp.sds.host_consumer_crb ) );
	phantom->sds_irq_mask_crb =
		( UNM_CAM_RAM +
		  le32_to_cpu ( buf->cardrsp.sds.interrupt_crb ) );

	DBGC ( phantom, "Phantom %p created RX context (id %04x, port phys "
	       "%02x virt %02x)\n", phantom, phantom->rx_context_id,
	       buf->cardrsp.rx_ctx.phys_port, buf->cardrsp.rx_ctx.virt_port );
	DBGC2_HDA ( phantom, virt_to_bus ( &buf->cardrsp ),
		    &buf->cardrsp, sizeof ( buf->cardrsp ) );
	DBGC ( phantom, "Phantom %p RDS producer CRB is %08lx\n",
	       phantom, phantom->rds_producer_crb );
	DBGC ( phantom, "Phantom %p SDS consumer CRB is %08lx\n",
	       phantom, phantom->sds_consumer_crb );
	DBGC ( phantom, "Phantom %p SDS interrupt mask CRB is %08lx\n",
	       phantom, phantom->sds_irq_mask_crb );

 out:
	free_phys ( buf, sizeof ( *buf ) );
	return rc;
}

/**
 * Destroy Phantom RX context
 *
 * @v phantom		Phantom NIC
 * @ret rc		Return status code
 */
static void phantom_destroy_rx_ctx ( struct phantom_nic *phantom ) {
	int rc;
	
	DBGC ( phantom, "Phantom %p destroying RX context (id %04x)\n",
	       phantom, phantom->rx_context_id );

	/* Issue request */
	if ( ( rc = phantom_issue_cmd ( phantom,
					NX_CDRP_CMD_DESTROY_RX_CTX,
					phantom->rx_context_id,
					NX_DESTROY_CTX_RESET, 0 ) ) != 0 ) {
		DBGC ( phantom, "Phantom %p could not destroy RX context: "
		       "%s\n", phantom, strerror ( rc ) );
		/* We're probably screwed */
		return;
	}

	/* Clear context parameters */
	phantom->rx_context_id = 0;
	phantom->rds_producer_crb = 0;
	phantom->sds_consumer_crb = 0;

	/* Reset software counters */
	phantom->rds_producer_idx = 0;
	phantom->rds_consumer_idx = 0;
	phantom->sds_consumer_idx = 0;
}

/**
 * Create Phantom TX context
 *
 * @v phantom		Phantom NIC
 * @ret rc		Return status code
 */
static int phantom_create_tx_ctx ( struct phantom_nic *phantom ) {
	struct phantom_create_tx_ctx_rqrsp *buf;
	int rc;

	/* Allocate context creation buffer */
	buf = malloc_phys ( sizeof ( *buf ), UNM_DMA_BUFFER_ALIGN );
	if ( ! buf ) {
		rc = -ENOMEM;
		goto out;
	}
	memset ( buf, 0, sizeof ( *buf ) );

	/* Prepare request */
	buf->hostrq.tx_ctx.host_rsp_dma_addr =
		cpu_to_le64 ( virt_to_bus ( &buf->cardrsp ) );
	buf->hostrq.tx_ctx.cmd_cons_dma_addr =
		cpu_to_le64 ( virt_to_bus ( &phantom->desc->cmd_cons ) );
	buf->hostrq.tx_ctx.capabilities[0] =
		cpu_to_le32 ( NX_CAP0_LEGACY_CONTEXT | NX_CAP0_LEGACY_MN );
	buf->hostrq.tx_ctx.host_int_crb_mode =
		cpu_to_le32 ( NX_HOST_INT_CRB_MODE_SHARED );
	buf->hostrq.tx_ctx.cds_ring.host_phys_addr =
		cpu_to_le64 ( virt_to_bus ( phantom->desc->cds ) );
	buf->hostrq.tx_ctx.cds_ring.ring_size = cpu_to_le32 ( PHN_NUM_CDS );

	DBGC ( phantom, "Phantom %p creating TX context\n", phantom );
	DBGC2_HDA ( phantom, virt_to_bus ( &buf->hostrq ),
		    &buf->hostrq, sizeof ( buf->hostrq ) );

	/* Issue request */
	if ( ( rc = phantom_issue_buf_cmd ( phantom,
					    NX_CDRP_CMD_CREATE_TX_CTX,
					    &buf->hostrq,
					    sizeof ( buf->hostrq ) ) ) != 0 ) {
		DBGC ( phantom, "Phantom %p could not create TX context: "
		       "%s\n", phantom, strerror ( rc ) );
		DBGC ( phantom, "Request:\n" );
		DBGC_HDA ( phantom, virt_to_bus ( &buf->hostrq ),
			   &buf->hostrq, sizeof ( buf->hostrq ) );
		DBGC ( phantom, "Response:\n" );
		DBGC_HDA ( phantom, virt_to_bus ( &buf->cardrsp ),
			   &buf->cardrsp, sizeof ( buf->cardrsp ) );
		goto out;
	}

	/* Retrieve context parameters */
	phantom->tx_context_id =
		le16_to_cpu ( buf->cardrsp.tx_ctx.context_id );
	phantom->cds_producer_crb =
		( UNM_CAM_RAM +
		  le32_to_cpu(buf->cardrsp.tx_ctx.cds_ring.host_producer_crb));

	DBGC ( phantom, "Phantom %p created TX context (id %04x, port phys "
	       "%02x virt %02x)\n", phantom, phantom->tx_context_id,
	       buf->cardrsp.tx_ctx.phys_port, buf->cardrsp.tx_ctx.virt_port );
	DBGC2_HDA ( phantom, virt_to_bus ( &buf->cardrsp ),
		    &buf->cardrsp, sizeof ( buf->cardrsp ) );
	DBGC ( phantom, "Phantom %p CDS producer CRB is %08lx\n",
	       phantom, phantom->cds_producer_crb );

 out:
	free_phys ( buf, sizeof ( *buf ) );
	return rc;
}

/**
 * Destroy Phantom TX context
 *
 * @v phantom		Phantom NIC
 * @ret rc		Return status code
 */
static void phantom_destroy_tx_ctx ( struct phantom_nic *phantom ) {
	int rc;
	
	DBGC ( phantom, "Phantom %p destroying TX context (id %04x)\n",
	       phantom, phantom->tx_context_id );

	/* Issue request */
	if ( ( rc = phantom_issue_cmd ( phantom,
					NX_CDRP_CMD_DESTROY_TX_CTX,
					phantom->tx_context_id,
					NX_DESTROY_CTX_RESET, 0 ) ) != 0 ) {
		DBGC ( phantom, "Phantom %p could not destroy TX context: "
		       "%s\n", phantom, strerror ( rc ) );
		/* We're probably screwed */
		return;
	}

	/* Clear context parameters */
	phantom->tx_context_id = 0;
	phantom->cds_producer_crb = 0;

	/* Reset software counters */
	phantom->cds_producer_idx = 0;
	phantom->cds_consumer_idx = 0;
}

/***************************************************************************
 *
 * Descriptor ring management
 *
 */

/**
 * Allocate Phantom RX descriptor
 *
 * @v phantom		Phantom NIC
 * @ret index		RX descriptor index, or negative error
 */
static int phantom_alloc_rds ( struct phantom_nic *phantom ) {
	unsigned int rds_producer_idx;
	unsigned int next_rds_producer_idx;

	/* Check for space in the ring.  RX descriptors are consumed
	 * out of order, but they are *read* by the hardware in strict
	 * order.  We maintain a pessimistic consumer index, which is
	 * guaranteed never to be an overestimate of the number of
	 * descriptors read by the hardware.
	 */
	rds_producer_idx = phantom->rds_producer_idx;
	next_rds_producer_idx = ( ( rds_producer_idx + 1 ) % PHN_NUM_RDS );
	if ( next_rds_producer_idx == phantom->rds_consumer_idx ) {
		DBGC ( phantom, "Phantom %p RDS ring full (index %d not "
		       "consumed)\n", phantom, next_rds_producer_idx );
		return -ENOBUFS;
	}

	return rds_producer_idx;
}

/**
 * Post Phantom RX descriptor
 *
 * @v phantom		Phantom NIC
 * @v rds		RX descriptor
 */
static void phantom_post_rds ( struct phantom_nic *phantom,
			       struct phantom_rds *rds ) {
	unsigned int rds_producer_idx;
	unsigned int next_rds_producer_idx;
	struct phantom_rds *entry;

	/* Copy descriptor to ring */
	rds_producer_idx = phantom->rds_producer_idx;
	entry = &phantom->desc->rds[rds_producer_idx];
	memcpy ( entry, rds, sizeof ( *entry ) );
	DBGC2 ( phantom, "Phantom %p posting RDS %ld (slot %d):\n",
		phantom, NX_GET ( rds, handle ), rds_producer_idx );
	DBGC2_HDA ( phantom, virt_to_bus ( entry ), entry, sizeof ( *entry ) );

	/* Update producer index */
	next_rds_producer_idx = ( ( rds_producer_idx + 1 ) % PHN_NUM_RDS );
	phantom->rds_producer_idx = next_rds_producer_idx;
	wmb();
	phantom_writel ( phantom, phantom->rds_producer_idx,
			 phantom->rds_producer_crb );
}

/**
 * Allocate Phantom TX descriptor
 *
 * @v phantom		Phantom NIC
 * @ret index		TX descriptor index, or negative error
 */
static int phantom_alloc_cds ( struct phantom_nic *phantom ) {
	unsigned int cds_producer_idx;
	unsigned int next_cds_producer_idx;

	/* Check for space in the ring.  TX descriptors are consumed
	 * in strict order, so we just check for a collision against
	 * the consumer index.
	 */
	cds_producer_idx = phantom->cds_producer_idx;
	next_cds_producer_idx = ( ( cds_producer_idx + 1 ) % PHN_NUM_CDS );
	if ( next_cds_producer_idx == phantom->cds_consumer_idx ) {
		DBGC ( phantom, "Phantom %p CDS ring full (index %d not "
		       "consumed)\n", phantom, next_cds_producer_idx );
		return -ENOBUFS;
	}

	return cds_producer_idx;
}

/**
 * Post Phantom TX descriptor
 *
 * @v phantom		Phantom NIC
 * @v cds		TX descriptor
 */
static void phantom_post_cds ( struct phantom_nic *phantom,
			       union phantom_cds *cds ) {
	unsigned int cds_producer_idx;
	unsigned int next_cds_producer_idx;
	union phantom_cds *entry;

	/* Copy descriptor to ring */
	cds_producer_idx = phantom->cds_producer_idx;
	entry = &phantom->desc->cds[cds_producer_idx];
	memcpy ( entry, cds, sizeof ( *entry ) );
	DBGC2 ( phantom, "Phantom %p posting CDS %d:\n",
		phantom, cds_producer_idx );
	DBGC2_HDA ( phantom, virt_to_bus ( entry ), entry, sizeof ( *entry ) );

	/* Update producer index */
	next_cds_producer_idx = ( ( cds_producer_idx + 1 ) % PHN_NUM_CDS );
	phantom->cds_producer_idx = next_cds_producer_idx;
	wmb();
	phantom_writel ( phantom, phantom->cds_producer_idx,
			 phantom->cds_producer_crb );
}

/***************************************************************************
 *
 * MAC address management
 *
 */

/**
 * Add/remove MAC address
 *
 * @v phantom		Phantom NIC
 * @v ll_addr		MAC address to add or remove
 * @v opcode		MAC request opcode
 * @ret rc		Return status code
 */
static int phantom_update_macaddr ( struct phantom_nic *phantom,
				    const uint8_t *ll_addr,
				    unsigned int opcode ) {
	union phantom_cds cds;
	int index;

	/* Get descriptor ring entry */
	index = phantom_alloc_cds ( phantom );
	if ( index < 0 )
		return index;

	/* Fill descriptor ring entry */
	memset ( &cds, 0, sizeof ( cds ) );
	NX_FILL_1 ( &cds, 0,
		    nic_request.common.opcode, UNM_NIC_REQUEST );
	NX_FILL_2 ( &cds, 1,
		    nic_request.header.opcode, UNM_MAC_EVENT,
		    nic_request.header.context_id, phantom->port );
	NX_FILL_7 ( &cds, 2,
		    nic_request.body.mac_request.opcode, opcode,
		    nic_request.body.mac_request.mac_addr_0, ll_addr[0],
		    nic_request.body.mac_request.mac_addr_1, ll_addr[1],
		    nic_request.body.mac_request.mac_addr_2, ll_addr[2],
		    nic_request.body.mac_request.mac_addr_3, ll_addr[3],
		    nic_request.body.mac_request.mac_addr_4, ll_addr[4],
		    nic_request.body.mac_request.mac_addr_5, ll_addr[5] );

	/* Post descriptor */
	phantom_post_cds ( phantom, &cds );

	return 0;
}

/**
 * Add MAC address
 *
 * @v phantom		Phantom NIC
 * @v ll_addr		MAC address to add or remove
 * @ret rc		Return status code
 */
static inline int phantom_add_macaddr ( struct phantom_nic *phantom,
					const uint8_t *ll_addr ) {

	DBGC ( phantom, "Phantom %p adding MAC address %s\n",
	       phantom, eth_ntoa ( ll_addr ) );

	return phantom_update_macaddr ( phantom, ll_addr, UNM_MAC_ADD );
}

/**
 * Remove MAC address
 *
 * @v phantom		Phantom NIC
 * @v ll_addr		MAC address to add or remove
 * @ret rc		Return status code
 */
static inline int phantom_del_macaddr ( struct phantom_nic *phantom,
					const uint8_t *ll_addr ) {

	DBGC ( phantom, "Phantom %p removing MAC address %s\n",
	       phantom, eth_ntoa ( ll_addr ) );

	return phantom_update_macaddr ( phantom, ll_addr, UNM_MAC_DEL );
}

/***************************************************************************
 *
 * Link state detection
 *
 */

/**
 * Poll link state
 *
 * @v netdev		Network device
 */
static void phantom_poll_link_state ( struct net_device *netdev ) {
	struct phantom_nic *phantom = netdev_priv ( netdev );
	uint32_t xg_state_p3;
	unsigned int link;

	/* Read link state */
	xg_state_p3 = phantom_readl ( phantom, UNM_NIC_REG_XG_STATE_P3 );

	/* If there is no change, do nothing */
	if ( phantom->link_state == xg_state_p3 )
		return;

	/* Record new link state */
	DBGC ( phantom, "Phantom %p new link state %08x (was %08x)\n",
	       phantom, xg_state_p3, phantom->link_state );
	phantom->link_state = xg_state_p3;

	/* Indicate link state to iPXE */
	link = UNM_NIC_REG_XG_STATE_P3_LINK ( phantom->port,
					      phantom->link_state );
	switch ( link ) {
	case UNM_NIC_REG_XG_STATE_P3_LINK_UP:
		DBGC ( phantom, "Phantom %p link is up\n", phantom );
		netdev_link_up ( netdev );
		break;
	case UNM_NIC_REG_XG_STATE_P3_LINK_DOWN:
		DBGC ( phantom, "Phantom %p link is down\n", phantom );
		netdev_link_down ( netdev );
		break;
	default:
		DBGC ( phantom, "Phantom %p bad link state %d\n",
		       phantom, link );
		break;
	}
}

/***************************************************************************
 *
 * Main driver body
 *
 */

/**
 * Refill descriptor ring
 *
 * @v netdev		Net device
 */
static void phantom_refill_rx_ring ( struct net_device *netdev ) {
	struct phantom_nic *phantom = netdev_priv ( netdev );
	struct io_buffer *iobuf;
	struct phantom_rds rds;
	unsigned int handle;
	int index;

	for ( handle = 0 ; handle < PHN_RDS_MAX_FILL ; handle++ ) {

		/* Skip this index if the descriptor has not yet been
		 * consumed.
		 */
		if ( phantom->rds_iobuf[handle] != NULL )
			continue;

		/* Allocate descriptor ring entry */
		index = phantom_alloc_rds ( phantom );
		assert ( PHN_RDS_MAX_FILL < PHN_NUM_RDS );
		assert ( index >= 0 ); /* Guaranteed by MAX_FILL < NUM_RDS ) */

		/* Try to allocate an I/O buffer */
		iobuf = alloc_iob ( PHN_RX_BUFSIZE );
		if ( ! iobuf ) {
			/* Failure is non-fatal; we will retry later */
			netdev_rx_err ( netdev, NULL, -ENOMEM );
			break;
		}

		/* Fill descriptor ring entry */
		memset ( &rds, 0, sizeof ( rds ) );
		NX_FILL_2 ( &rds, 0,
			    handle, handle,
			    length, iob_len ( iobuf ) );
		NX_FILL_1 ( &rds, 1,
			    dma_addr, virt_to_bus ( iobuf->data ) );

		/* Record I/O buffer */
		assert ( phantom->rds_iobuf[handle] == NULL );
		phantom->rds_iobuf[handle] = iobuf;

		/* Post descriptor */
		phantom_post_rds ( phantom, &rds );
	}
}

/**
 * Open NIC
 *
 * @v netdev		Net device
 * @ret rc		Return status code
 */
static int phantom_open ( struct net_device *netdev ) {
	struct phantom_nic *phantom = netdev_priv ( netdev );
	int rc;

	/* Allocate and zero descriptor rings */
	phantom->desc = malloc_phys ( sizeof ( *(phantom->desc) ),
				      UNM_DMA_BUFFER_ALIGN );
	if ( ! phantom->desc ) {
		rc = -ENOMEM;
		goto err_alloc_desc;
	}
	memset ( phantom->desc, 0, sizeof ( *(phantom->desc) ) );

	/* Create RX context */
	if ( ( rc = phantom_create_rx_ctx ( phantom ) ) != 0 )
		goto err_create_rx_ctx;

	/* Create TX context */
	if ( ( rc = phantom_create_tx_ctx ( phantom ) ) != 0 )
		goto err_create_tx_ctx;

	/* Fill the RX descriptor ring */
	phantom_refill_rx_ring ( netdev );

	/* Add MAC addresses
	 *
	 * BUG5583
	 *
	 * We would like to be able to enable receiving all multicast
	 * packets (or, failing that, promiscuous mode), but the
	 * firmware doesn't currently support this.
	 */
	if ( ( rc = phantom_add_macaddr ( phantom,
					  netdev->ll_broadcast ) ) != 0 )
		goto err_add_macaddr_broadcast;
	if ( ( rc = phantom_add_macaddr ( phantom,
					  netdev->ll_addr ) ) != 0 )
		goto err_add_macaddr_unicast;

	return 0;

	phantom_del_macaddr ( phantom, netdev->ll_addr );
 err_add_macaddr_unicast:
	phantom_del_macaddr ( phantom, netdev->ll_broadcast );
 err_add_macaddr_broadcast:
	phantom_destroy_tx_ctx ( phantom );
 err_create_tx_ctx:
	phantom_destroy_rx_ctx ( phantom );
 err_create_rx_ctx:
	free_phys ( phantom->desc, sizeof ( *(phantom->desc) ) );
	phantom->desc = NULL;
 err_alloc_desc:
	return rc;
}

/**
 * Close NIC
 *
 * @v netdev		Net device
 */
static void phantom_close ( struct net_device *netdev ) {
	struct phantom_nic *phantom = netdev_priv ( netdev );
	struct io_buffer *iobuf;
	unsigned int i;

	/* Shut down the port */
	phantom_del_macaddr ( phantom, netdev->ll_addr );
	phantom_del_macaddr ( phantom, netdev->ll_broadcast );
	phantom_destroy_tx_ctx ( phantom );
	phantom_destroy_rx_ctx ( phantom );
	free_phys ( phantom->desc, sizeof ( *(phantom->desc) ) );
	phantom->desc = NULL;

	/* Flush any uncompleted descriptors */
	for ( i = 0 ; i < PHN_RDS_MAX_FILL ; i++ ) {
		iobuf = phantom->rds_iobuf[i];
		if ( iobuf ) {
			free_iob ( iobuf );
			phantom->rds_iobuf[i] = NULL;
		}
	}
	for ( i = 0 ; i < PHN_NUM_CDS ; i++ ) {
		iobuf = phantom->cds_iobuf[i];
		if ( iobuf ) {
			netdev_tx_complete_err ( netdev, iobuf, -ECANCELED );
			phantom->cds_iobuf[i] = NULL;
		}
	}
}

/** 
 * Transmit packet
 *
 * @v netdev	Network device
 * @v iobuf	I/O buffer
 * @ret rc	Return status code
 */
static int phantom_transmit ( struct net_device *netdev,
			      struct io_buffer *iobuf ) {
	struct phantom_nic *phantom = netdev_priv ( netdev );
	union phantom_cds cds;
	int index;

	/* Get descriptor ring entry */
	index = phantom_alloc_cds ( phantom );
	if ( index < 0 )
		return index;

	/* Fill descriptor ring entry */
	memset ( &cds, 0, sizeof ( cds ) );
	NX_FILL_3 ( &cds, 0,
		    tx.opcode, UNM_TX_ETHER_PKT,
		    tx.num_buffers, 1,
		    tx.length, iob_len ( iobuf ) );
	NX_FILL_2 ( &cds, 2,
		    tx.port, phantom->port,
		    tx.context_id, phantom->port );
	NX_FILL_1 ( &cds, 4,
		    tx.buffer1_dma_addr, virt_to_bus ( iobuf->data ) );
	NX_FILL_1 ( &cds, 5,
		    tx.buffer1_length, iob_len ( iobuf ) );

	/* Record I/O buffer */
	assert ( phantom->cds_iobuf[index] == NULL );
	phantom->cds_iobuf[index] = iobuf;

	/* Post descriptor */
	phantom_post_cds ( phantom, &cds );

	return 0;
}

/**
 * Poll for received packets
 *
 * @v netdev	Network device
 */
static void phantom_poll ( struct net_device *netdev ) {
	struct phantom_nic *phantom = netdev_priv ( netdev );
	struct io_buffer *iobuf;
	unsigned int irq_vector;
	unsigned int irq_state;
	unsigned int cds_consumer_idx;
	unsigned int raw_new_cds_consumer_idx;
	unsigned int new_cds_consumer_idx;
	unsigned int rds_consumer_idx;
	unsigned int sds_consumer_idx;
	struct phantom_sds *sds;
	unsigned int sds_handle;
	unsigned int sds_opcode;

	/* Occasionally poll the link state */
	if ( phantom->link_poll_timer-- == 0 ) {
		phantom_poll_link_state ( netdev );
		/* Reset the link poll timer */
		phantom->link_poll_timer = PHN_LINK_POLL_FREQUENCY;
	}

	/* Check for interrupts */
	if ( phantom->sds_irq_enabled ) {

		/* Do nothing unless an interrupt is asserted */
		irq_vector = phantom_readl ( phantom, UNM_PCIE_IRQ_VECTOR );
		if ( ! ( irq_vector & UNM_PCIE_IRQ_VECTOR_BIT( phantom->port )))
			return;

		/* Do nothing unless interrupt state machine has stabilised */
		irq_state = phantom_readl ( phantom, UNM_PCIE_IRQ_STATE );
		if ( ! UNM_PCIE_IRQ_STATE_TRIGGERED ( irq_state ) )
			return;

		/* Acknowledge interrupt */
		phantom_writel ( phantom, UNM_PCIE_IRQ_STATUS_MAGIC,
				 phantom_irq_status_reg[phantom->port] );
		phantom_readl ( phantom, UNM_PCIE_IRQ_VECTOR );
	}

	/* Check for TX completions */
	cds_consumer_idx = phantom->cds_consumer_idx;
	raw_new_cds_consumer_idx = phantom->desc->cmd_cons;
	new_cds_consumer_idx = le32_to_cpu ( raw_new_cds_consumer_idx );
	while ( cds_consumer_idx != new_cds_consumer_idx ) {
		DBGC2 ( phantom, "Phantom %p CDS %d complete\n",
			phantom, cds_consumer_idx );
		/* Completions may be for commands other than TX, so
		 * there may not always be an associated I/O buffer.
		 */
		if ( ( iobuf = phantom->cds_iobuf[cds_consumer_idx] ) ) {
			netdev_tx_complete ( netdev, iobuf );
			phantom->cds_iobuf[cds_consumer_idx] = NULL;
		}
		cds_consumer_idx = ( ( cds_consumer_idx + 1 ) % PHN_NUM_CDS );
		phantom->cds_consumer_idx = cds_consumer_idx;
	}

	/* Check for received packets */
	rds_consumer_idx = phantom->rds_consumer_idx;
	sds_consumer_idx = phantom->sds_consumer_idx;
	while ( 1 ) {
		sds = &phantom->desc->sds[sds_consumer_idx];
		if ( NX_GET ( sds, owner ) == 0 )
			break;

		DBGC2 ( phantom, "Phantom %p SDS %d status:\n",
			phantom, sds_consumer_idx );
		DBGC2_HDA ( phantom, virt_to_bus ( sds ), sds, sizeof (*sds) );

		/* Check received opcode */
		sds_opcode = NX_GET ( sds, opcode );
		if ( ( sds_opcode == UNM_RXPKT_DESC ) ||
		     ( sds_opcode == UNM_SYN_OFFLOAD ) ) {

			/* Sanity check: ensure that all of the SDS
			 * descriptor has been written.
			 */
			if ( NX_GET ( sds, total_length ) == 0 ) {
				DBGC ( phantom, "Phantom %p SDS %d "
				       "incomplete; deferring\n",
				       phantom, sds_consumer_idx );
				/* Leave for next poll() */
				break;
			}

			/* Process received packet */
			sds_handle = NX_GET ( sds, handle );
			iobuf = phantom->rds_iobuf[sds_handle];
			assert ( iobuf != NULL );
			iob_put ( iobuf, NX_GET ( sds, total_length ) );
			iob_pull ( iobuf, NX_GET ( sds, pkt_offset ) );
			DBGC2 ( phantom, "Phantom %p RDS %d complete\n",
				phantom, sds_handle );
			netdev_rx ( netdev, iobuf );
			phantom->rds_iobuf[sds_handle] = NULL;

			/* Update RDS consumer counter.  This is a
			 * lower bound for the number of descriptors
			 * that have been read by the hardware, since
			 * the hardware must have read at least one
			 * descriptor for each completion that we
			 * receive.
			 */
			rds_consumer_idx =
				( ( rds_consumer_idx + 1 ) % PHN_NUM_RDS );
			phantom->rds_consumer_idx = rds_consumer_idx;

		} else {

			DBGC ( phantom, "Phantom %p unexpected SDS opcode "
			       "%02x\n", phantom, sds_opcode );
			DBGC_HDA ( phantom, virt_to_bus ( sds ),
				   sds, sizeof ( *sds ) );
		}
			
		/* Clear status descriptor */
		memset ( sds, 0, sizeof ( *sds ) );

		/* Update SDS consumer index */
		sds_consumer_idx = ( ( sds_consumer_idx + 1 ) % PHN_NUM_SDS );
		phantom->sds_consumer_idx = sds_consumer_idx;
		wmb();
		phantom_writel ( phantom, phantom->sds_consumer_idx,
				 phantom->sds_consumer_crb );
	}

	/* Refill the RX descriptor ring */
	phantom_refill_rx_ring ( netdev );
}

/**
 * Enable/disable interrupts
 *
 * @v netdev	Network device
 * @v enable	Interrupts should be enabled
 */
static void phantom_irq ( struct net_device *netdev, int enable ) {
	struct phantom_nic *phantom = netdev_priv ( netdev );

	phantom_writel ( phantom, ( enable ? 1 : 0 ),
			 phantom->sds_irq_mask_crb );
	phantom_writel ( phantom, UNM_PCIE_IRQ_MASK_MAGIC,
			 phantom_irq_mask_reg[phantom->port] );
	phantom->sds_irq_enabled = enable;
}

/** Phantom net device operations */
static struct net_device_operations phantom_operations = {
	.open		= phantom_open,
	.close		= phantom_close,
	.transmit	= phantom_transmit,
	.poll		= phantom_poll,
	.irq		= phantom_irq,
};

/***************************************************************************
 *
 * CLP settings
 *
 */

/** Phantom CLP settings scope */
static const struct settings_scope phantom_settings_scope;

/** Phantom CLP data
 *
 */
union phantom_clp_data {
	/** Data bytes
	 *
	 * This field is right-aligned; if only N bytes are present
	 * then bytes[0]..bytes[7-N] should be zero, and the data
	 * should be in bytes[7-N+1] to bytes[7];
	 */
	uint8_t bytes[8];
	/** Dwords for the CLP interface */
	struct {
		/** High dword, in network byte order */
		uint32_t hi;
		/** Low dword, in network byte order */
		uint32_t lo;
	} dwords;
};
#define PHN_CLP_BLKSIZE ( sizeof ( union phantom_clp_data ) )

/**
 * Wait for Phantom CLP command to complete
 *
 * @v phantom		Phantom NIC
 * @ret rc		Return status code
 */
static int phantom_clp_wait ( struct phantom_nic *phantom ) {
	unsigned int retries;
	uint32_t status;

	for ( retries = 0 ; retries < PHN_CLP_CMD_TIMEOUT_MS ; retries++ ) {
		status = phantom_readl ( phantom, UNM_CAM_RAM_CLP_STATUS );
		if ( status & UNM_CAM_RAM_CLP_STATUS_DONE )
			return 0;
		mdelay ( 1 );
	}

	DBGC ( phantom, "Phantom %p timed out waiting for CLP command\n",
	       phantom );
	return -ETIMEDOUT;
}

/**
 * Issue Phantom CLP command
 *
 * @v phantom		Phantom NIC
 * @v port		Virtual port number
 * @v opcode		Opcode
 * @v data_in		Data in, or NULL
 * @v data_out		Data out, or NULL
 * @v offset		Offset within data
 * @v len		Data buffer length
 * @ret len		Total transfer length (for reads), or negative error
 */
static int phantom_clp_cmd ( struct phantom_nic *phantom, unsigned int port,
			     unsigned int opcode, const void *data_in,
			     void *data_out, size_t offset, size_t len ) {
	union phantom_clp_data data;
	unsigned int index = ( offset / sizeof ( data ) );
	unsigned int last = 0;
	size_t in_frag_len;
	uint8_t *in_frag;
	uint32_t command;
	uint32_t status;
	size_t read_len;
	unsigned int error;
	size_t out_frag_len;
	uint8_t *out_frag;
	int rc;

	/* Sanity checks */
	assert ( ( offset % sizeof ( data ) ) == 0 );
	if ( len > 255 ) {
		DBGC ( phantom, "Phantom %p invalid CLP length %zd\n",
		       phantom, len );
		return -EINVAL;
	}

	/* Check that CLP interface is ready */
	if ( ( rc = phantom_clp_wait ( phantom ) ) != 0 )
		return rc;

	/* Copy data in */
	memset ( &data, 0, sizeof ( data ) );
	if ( data_in ) {
		assert ( offset < len );
		in_frag_len = ( len - offset );
		if ( in_frag_len > sizeof ( data ) ) {
			in_frag_len = sizeof ( data );
		} else {
			last = 1;
		}
		in_frag = &data.bytes[ sizeof ( data ) - in_frag_len ];
		memcpy ( in_frag, ( data_in + offset ), in_frag_len );
		phantom_writel ( phantom, be32_to_cpu ( data.dwords.lo ),
				 UNM_CAM_RAM_CLP_DATA_LO );
		phantom_writel ( phantom, be32_to_cpu ( data.dwords.hi ),
				 UNM_CAM_RAM_CLP_DATA_HI );
	}

	/* Issue CLP command */
	command = ( ( index << 24 ) | ( ( data_in ? len : 0 ) << 16 ) |
		    ( port << 8 ) | ( last << 7 ) | ( opcode << 0 ) );
	phantom_writel ( phantom, command, UNM_CAM_RAM_CLP_COMMAND );
	mb();
	phantom_writel ( phantom, UNM_CAM_RAM_CLP_STATUS_START,
			 UNM_CAM_RAM_CLP_STATUS );

	/* Wait for command to complete */
	if ( ( rc = phantom_clp_wait ( phantom ) ) != 0 )
		return rc;

	/* Get command status */
	status = phantom_readl ( phantom, UNM_CAM_RAM_CLP_STATUS );
	read_len = ( ( status >> 16 ) & 0xff );
	error = ( ( status >> 8 ) & 0xff );
	if ( error ) {
		DBGC ( phantom, "Phantom %p CLP command error %02x\n",
		       phantom, error );
		return -EIO;
	}

	/* Copy data out */
	if ( data_out ) {
		data.dwords.lo = cpu_to_be32 ( phantom_readl ( phantom,
						  UNM_CAM_RAM_CLP_DATA_LO ) );
		data.dwords.hi = cpu_to_be32 ( phantom_readl ( phantom,
						  UNM_CAM_RAM_CLP_DATA_HI ) );
		out_frag_len = ( read_len - offset );
		if ( out_frag_len > sizeof ( data ) )
			out_frag_len = sizeof ( data );
		out_frag = &data.bytes[ sizeof ( data ) - out_frag_len ];
		if ( out_frag_len > ( len - offset ) )
			out_frag_len = ( len - offset );
		memcpy ( ( data_out + offset ), out_frag, out_frag_len );
	}

	return read_len;
}

/**
 * Store Phantom CLP setting
 *
 * @v phantom		Phantom NIC
 * @v port		Virtual port number
 * @v setting		Setting number
 * @v data		Data buffer
 * @v len		Length of data buffer
 * @ret rc		Return status code
 */
static int phantom_clp_store ( struct phantom_nic *phantom, unsigned int port,
			       unsigned int setting, const void *data,
			       size_t len ) {
	unsigned int opcode = setting;
	size_t offset;
	int rc;

	for ( offset = 0 ; offset < len ; offset += PHN_CLP_BLKSIZE ) {
		if ( ( rc = phantom_clp_cmd ( phantom, port, opcode, data,
					      NULL, offset, len ) ) < 0 )
			return rc;
	}
	return 0;
}

/**
 * Fetch Phantom CLP setting
 *
 * @v phantom		Phantom NIC
 * @v port		Virtual port number
 * @v setting		Setting number
 * @v data		Data buffer
 * @v len		Length of data buffer
 * @ret len		Length of setting, or negative error
 */
static int phantom_clp_fetch ( struct phantom_nic *phantom, unsigned int port,
			       unsigned int setting, void *data, size_t len ) {
	unsigned int opcode = ( setting + 1 );
	size_t offset = 0;
	int read_len;

	while ( 1 ) {
		read_len = phantom_clp_cmd ( phantom, port, opcode, NULL,
					     data, offset, len );
		if ( read_len < 0 )
			return read_len;
		offset += PHN_CLP_BLKSIZE;
		if ( offset >= ( unsigned ) read_len )
			break;
		if ( offset >= len )
			break;
	}
	return read_len;
}

/** A Phantom CLP setting */
struct phantom_clp_setting {
	/** iPXE setting */
	const struct setting *setting;
	/** Setting number */
	unsigned int clp_setting;
};

/** Phantom CLP settings */
static struct phantom_clp_setting clp_settings[] = {
	{ &mac_setting, 0x01 },
};

/**
 * Find Phantom CLP setting
 *
 * @v setting		iPXE setting
 * @v clp_setting	Setting number, or 0 if not found
 */
static unsigned int
phantom_clp_setting ( struct phantom_nic *phantom,
		      const struct setting *setting ) {
	struct phantom_clp_setting *clp_setting;
	unsigned int i;

	/* Search the list of explicitly-defined settings */
	for ( i = 0 ; i < ( sizeof ( clp_settings ) /
			    sizeof ( clp_settings[0] ) ) ; i++ ) {
		clp_setting = &clp_settings[i];
		if ( setting_cmp ( setting, clp_setting->setting ) == 0 )
			return clp_setting->clp_setting;
	}

	/* Allow for use of numbered settings */
	if ( setting->scope == &phantom_settings_scope )
		return setting->tag;

	DBGC2 ( phantom, "Phantom %p has no \"%s\" setting\n",
		phantom, setting->name );

	return 0;
}

/**
 * Check applicability of Phantom CLP setting
 *
 * @v settings		Settings block
 * @v setting		Setting
 * @ret applies		Setting applies within this settings block
 */
static int phantom_setting_applies ( struct settings *settings,
				     const struct setting *setting ) {
	struct phantom_nic *phantom =
		container_of ( settings, struct phantom_nic, settings );
	unsigned int clp_setting;

	/* Find Phantom setting equivalent to iPXE setting */
	clp_setting = phantom_clp_setting ( phantom, setting );
	return ( clp_setting != 0 );
}

/**
 * Store Phantom CLP setting
 *
 * @v settings		Settings block
 * @v setting		Setting to store
 * @v data		Setting data, or NULL to clear setting
 * @v len		Length of setting data
 * @ret rc		Return status code
 */
static int phantom_store_setting ( struct settings *settings,
				   const struct setting *setting,
				   const void *data, size_t len ) {
	struct phantom_nic *phantom =
		container_of ( settings, struct phantom_nic, settings );
	unsigned int clp_setting;
	int rc;

	/* Find Phantom setting equivalent to iPXE setting */
	clp_setting = phantom_clp_setting ( phantom, setting );
	assert ( clp_setting != 0 );

	/* Store setting */
	if ( ( rc = phantom_clp_store ( phantom, phantom->port,
					clp_setting, data, len ) ) != 0 ) {
		DBGC ( phantom, "Phantom %p could not store setting \"%s\": "
		       "%s\n", phantom, setting->name, strerror ( rc ) );
		return rc;
	}

	return 0;
}

/**
 * Fetch Phantom CLP setting
 *
 * @v settings		Settings block
 * @v setting		Setting to fetch
 * @v data		Buffer to fill with setting data
 * @v len		Length of buffer
 * @ret len		Length of setting data, or negative error
 */
static int phantom_fetch_setting ( struct settings *settings,
				   struct setting *setting,
				   void *data, size_t len ) {
	struct phantom_nic *phantom =
		container_of ( settings, struct phantom_nic, settings );
	unsigned int clp_setting;
	int read_len;
	int rc;

	/* Find Phantom setting equivalent to iPXE setting */
	clp_setting = phantom_clp_setting ( phantom, setting );
	assert ( clp_setting != 0 );

	/* Fetch setting */
	if ( ( read_len = phantom_clp_fetch ( phantom, phantom->port,
					      clp_setting, data, len ) ) < 0 ){
		rc = read_len;
		DBGC ( phantom, "Phantom %p could not fetch setting \"%s\": "
		       "%s\n", phantom, setting->name, strerror ( rc ) );
		return rc;
	}

	return read_len;
}

/** Phantom CLP settings operations */
static struct settings_operations phantom_settings_operations = {
	.applies	= phantom_setting_applies,
	.store		= phantom_store_setting,
	.fetch		= phantom_fetch_setting,
};

/***************************************************************************
 *
 * Initialisation
 *
 */

/**
 * Map Phantom CRB window
 *
 * @v phantom		Phantom NIC
 * @ret rc		Return status code
 */
static int phantom_map_crb ( struct phantom_nic *phantom,
			     struct pci_device *pci ) {
	unsigned long bar0_start;
	unsigned long bar0_size;

	bar0_start = pci_bar_start ( pci, PCI_BASE_ADDRESS_0 );
	bar0_size = pci_bar_size ( pci, PCI_BASE_ADDRESS_0 );
	DBGC ( phantom, "Phantom %p is " PCI_FMT " with BAR0 at %08lx+%lx\n",
	       phantom, PCI_ARGS ( pci ), bar0_start, bar0_size );

	if ( ! bar0_start ) {
		DBGC ( phantom, "Phantom %p BAR not assigned; ignoring\n",
		       phantom );
		return -EINVAL;
	}

	switch ( bar0_size ) {
	case ( 128 * 1024 * 1024 ) :
		DBGC ( phantom, "Phantom %p has 128MB BAR\n", phantom );
		phantom->crb_access = phantom_crb_access_128m;
		break;
	case ( 32 * 1024 * 1024 ) :
		DBGC ( phantom, "Phantom %p has 32MB BAR\n", phantom );
		phantom->crb_access = phantom_crb_access_32m;
		break;
	case ( 2 * 1024 * 1024 ) :
		DBGC ( phantom, "Phantom %p has 2MB BAR\n", phantom );
		phantom->crb_access = phantom_crb_access_2m;
		break;
	default:
		DBGC ( phantom, "Phantom %p has bad BAR size\n", phantom );
		return -EINVAL;
	}

	phantom->bar0 = pci_ioremap ( pci, bar0_start, bar0_size );
	if ( ! phantom->bar0 ) {
		DBGC ( phantom, "Phantom %p could not map BAR0\n", phantom );
		return -EIO;
	}

	/* Mark current CRB window as invalid, so that the first
	 * read/write will set the current window.
	 */
	phantom->crb_window = -1UL;

	return 0;
}

/**
 * Unhalt all PEGs
 *
 * @v phantom		Phantom NIC
 */
static void phantom_unhalt_pegs ( struct phantom_nic *phantom ) {
	uint32_t halt_status;

	halt_status = phantom_readl ( phantom, UNM_PEG_0_HALT_STATUS );
	phantom_writel ( phantom, halt_status, UNM_PEG_0_HALT_STATUS );
	halt_status = phantom_readl ( phantom, UNM_PEG_1_HALT_STATUS );
	phantom_writel ( phantom, halt_status, UNM_PEG_1_HALT_STATUS );
	halt_status = phantom_readl ( phantom, UNM_PEG_2_HALT_STATUS );
	phantom_writel ( phantom, halt_status, UNM_PEG_2_HALT_STATUS );
	halt_status = phantom_readl ( phantom, UNM_PEG_3_HALT_STATUS );
	phantom_writel ( phantom, halt_status, UNM_PEG_3_HALT_STATUS );
	halt_status = phantom_readl ( phantom, UNM_PEG_4_HALT_STATUS );
	phantom_writel ( phantom, halt_status, UNM_PEG_4_HALT_STATUS );
}

/**
 * Initialise the Phantom command PEG
 *
 * @v phantom		Phantom NIC
 * @ret rc		Return status code
 */
static int phantom_init_cmdpeg ( struct phantom_nic *phantom ) {
	uint32_t cold_boot;
	uint32_t sw_reset;
	unsigned int retries;
	uint32_t cmdpeg_state;
	uint32_t last_cmdpeg_state = 0;

	/* Check for a previous initialisation.  This could have
	 * happened if, for example, the BIOS used the UNDI API to
	 * drive the NIC prior to a full PXE boot.
	 */
	cmdpeg_state = phantom_readl ( phantom, UNM_NIC_REG_CMDPEG_STATE );
	if ( cmdpeg_state == UNM_NIC_REG_CMDPEG_STATE_INITIALIZE_ACK ) {
		DBGC ( phantom, "Phantom %p command PEG already initialized\n",
		       phantom );
		/* Unhalt the PEGs.  Previous firmware (e.g. BOFM) may
		 * have halted the PEGs to prevent internal bus
		 * collisions when the BIOS re-reads the expansion ROM.
		 */
		phantom_unhalt_pegs ( phantom );
		return 0;
	}

	/* If this was a cold boot, check that the hardware came up ok */
	cold_boot = phantom_readl ( phantom, UNM_CAM_RAM_COLD_BOOT );
	if ( cold_boot == UNM_CAM_RAM_COLD_BOOT_MAGIC ) {
		DBGC ( phantom, "Phantom %p coming up from cold boot\n",
		       phantom );
		sw_reset = phantom_readl ( phantom, UNM_ROMUSB_GLB_SW_RESET );
		if ( sw_reset != UNM_ROMUSB_GLB_SW_RESET_MAGIC ) {
			DBGC ( phantom, "Phantom %p reset failed: %08x\n",
			       phantom, sw_reset );
			return -EIO;
		}
	} else {
		DBGC ( phantom, "Phantom %p coming up from warm boot "
		       "(%08x)\n", phantom, cold_boot );
	}
	/* Clear cold-boot flag */
	phantom_writel ( phantom, 0, UNM_CAM_RAM_COLD_BOOT );

	/* Set port modes */
	phantom_writel ( phantom, UNM_CAM_RAM_PORT_MODE_AUTO_NEG_1G,
			 UNM_CAM_RAM_WOL_PORT_MODE );

	/* Pass dummy DMA area to card */
	phantom_write_hilo ( phantom, 0,
			     UNM_NIC_REG_DUMMY_BUF_ADDR_LO,
			     UNM_NIC_REG_DUMMY_BUF_ADDR_HI );
	phantom_writel ( phantom, UNM_NIC_REG_DUMMY_BUF_INIT,
			 UNM_NIC_REG_DUMMY_BUF );

	/* Tell the hardware that tuning is complete */
	phantom_writel ( phantom, UNM_ROMUSB_GLB_PEGTUNE_DONE_MAGIC,
			 UNM_ROMUSB_GLB_PEGTUNE_DONE );

	/* Wait for command PEG to finish initialising */
	DBGC ( phantom, "Phantom %p initialising command PEG (will take up to "
	       "%d seconds)...\n", phantom, PHN_CMDPEG_INIT_TIMEOUT_SEC );
	for ( retries = 0; retries < PHN_CMDPEG_INIT_TIMEOUT_SEC; retries++ ) {
		cmdpeg_state = phantom_readl ( phantom,
					       UNM_NIC_REG_CMDPEG_STATE );
		if ( cmdpeg_state != last_cmdpeg_state ) {
			DBGC ( phantom, "Phantom %p command PEG state is "
			       "%08x after %d seconds...\n",
			       phantom, cmdpeg_state, retries );
			last_cmdpeg_state = cmdpeg_state;
		}
		if ( cmdpeg_state == UNM_NIC_REG_CMDPEG_STATE_INITIALIZED ) {
			/* Acknowledge the PEG initialisation */
			phantom_writel ( phantom,
				       UNM_NIC_REG_CMDPEG_STATE_INITIALIZE_ACK,
				       UNM_NIC_REG_CMDPEG_STATE );
			return 0;
		}
		mdelay ( 1000 );
	}

	DBGC ( phantom, "Phantom %p timed out waiting for command PEG to "
	       "initialise (status %08x)\n", phantom, cmdpeg_state );
	return -ETIMEDOUT;
}

/**
 * Read Phantom MAC address
 *
 * @v phanton_port	Phantom NIC
 * @v hw_addr		Buffer to fill with MAC address
 */
static void phantom_get_macaddr ( struct phantom_nic *phantom,
				  uint8_t *hw_addr ) {
	union {
		uint8_t mac_addr[2][ETH_ALEN];
		uint32_t dwords[3];
	} u;
	unsigned long offset;
	int i;

	/* Read the three dwords that include this MAC address and one other */
	offset = ( UNM_CAM_RAM_MAC_ADDRS +
		   ( 12 * ( phantom->port / 2 ) ) );
	for ( i = 0 ; i < 3 ; i++, offset += 4 ) {
		u.dwords[i] = phantom_readl ( phantom, offset );
	}

	/* Copy out the relevant MAC address */
	for ( i = 0 ; i < ETH_ALEN ; i++ ) {
		hw_addr[ ETH_ALEN - i - 1 ] =
			u.mac_addr[ phantom->port & 1 ][i];
	}
	DBGC ( phantom, "Phantom %p MAC address is %s\n",
	       phantom, eth_ntoa ( hw_addr ) );
}

/**
 * Check Phantom is enabled for boot
 *
 * @v phanton_port	Phantom NIC
 * @ret rc		Return status code
 *
 * This is something of an ugly hack to accommodate an OEM
 * requirement.  The NIC has only one expansion ROM BAR, rather than
 * one per port.  To allow individual ports to be selectively
 * enabled/disabled for PXE boot (as required), we must therefore
 * leave the expansion ROM always enabled, and place the per-port
 * enable/disable logic within the iPXE driver.
 */
static int phantom_check_boot_enable ( struct phantom_nic *phantom ) {
	unsigned long boot_enable;

	boot_enable = phantom_readl ( phantom, UNM_CAM_RAM_BOOT_ENABLE );
	if ( ! ( boot_enable & ( 1 << phantom->port ) ) ) {
		DBGC ( phantom, "Phantom %p PXE boot is disabled\n",
		       phantom );
		return -ENOTSUP;
	}

	return 0;
}

/**
 * Initialise Phantom receive PEG
 *
 * @v phantom		Phantom NIC
 * @ret rc		Return status code
 */
static int phantom_init_rcvpeg ( struct phantom_nic *phantom ) {
	unsigned int retries;
	uint32_t rcvpeg_state;
	uint32_t last_rcvpeg_state = 0;

	DBGC ( phantom, "Phantom %p initialising receive PEG (will take up to "
	       "%d seconds)...\n", phantom, PHN_RCVPEG_INIT_TIMEOUT_SEC );
	for ( retries = 0; retries < PHN_RCVPEG_INIT_TIMEOUT_SEC; retries++ ) {
		rcvpeg_state = phantom_readl ( phantom,
					       UNM_NIC_REG_RCVPEG_STATE );
		if ( rcvpeg_state != last_rcvpeg_state ) {
			DBGC ( phantom, "Phantom %p receive PEG state is "
			       "%08x after %d seconds...\n",
			       phantom, rcvpeg_state, retries );
			last_rcvpeg_state = rcvpeg_state;
		}
		if ( rcvpeg_state == UNM_NIC_REG_RCVPEG_STATE_INITIALIZED )
			return 0;
		mdelay ( 1000 );
	}

	DBGC ( phantom, "Phantom %p timed out waiting for receive PEG to "
	       "initialise (status %08x)\n", phantom, rcvpeg_state );
	return -ETIMEDOUT;
}

/**
 * Probe PCI device
 *
 * @v pci		PCI device
 * @v id		PCI ID
 * @ret rc		Return status code
 */
static int phantom_probe ( struct pci_device *pci ) {
	struct net_device *netdev;
	struct phantom_nic *phantom;
	struct settings *parent_settings;
	unsigned int busdevfn;
	int rc;

	/* Allocate Phantom device */
	netdev = alloc_etherdev ( sizeof ( *phantom ) );
	if ( ! netdev ) {
		rc = -ENOMEM;
		goto err_alloc_etherdev;
	}
	netdev_init ( netdev, &phantom_operations );
	phantom = netdev_priv ( netdev );
	pci_set_drvdata ( pci, netdev );
	netdev->dev = &pci->dev;
	memset ( phantom, 0, sizeof ( *phantom ) );
	phantom->port = PCI_FUNC ( pci->busdevfn );
	assert ( phantom->port < PHN_MAX_NUM_PORTS );
	settings_init ( &phantom->settings,
			&phantom_settings_operations,
			&netdev->refcnt, &phantom_settings_scope );

	/* Fix up PCI device */
	adjust_pci_device ( pci );

	/* Map CRB */
	if ( ( rc = phantom_map_crb ( phantom, pci ) ) != 0 )
		goto err_map_crb;

	/* BUG5945 - need to hack PCI config space on P3 B1 silicon.
	 * B2 will have this fixed; remove this hack when B1 is no
	 * longer in use.
	 */
	busdevfn = pci->busdevfn;
	if ( PCI_FUNC ( busdevfn ) == 0 ) {
		unsigned int i;
		for ( i = 0 ; i < 8 ; i++ ) {
			uint32_t temp;
			pci->busdevfn =
				PCI_BUSDEVFN ( PCI_SEG ( busdevfn ),
					       PCI_BUS ( busdevfn ),
					       PCI_SLOT ( busdevfn ), i );
			pci_read_config_dword ( pci, 0xc8, &temp );
			pci_read_config_dword ( pci, 0xc8, &temp );
			pci_write_config_dword ( pci, 0xc8, 0xf1000 );
		}
		pci->busdevfn = busdevfn;
	}

	/* Initialise the command PEG */
	if ( ( rc = phantom_init_cmdpeg ( phantom ) ) != 0 )
		goto err_init_cmdpeg;

	/* Initialise the receive PEG */
	if ( ( rc = phantom_init_rcvpeg ( phantom ) ) != 0 )
		goto err_init_rcvpeg;

	/* Read MAC addresses */
	phantom_get_macaddr ( phantom, netdev->hw_addr );

	/* Skip if boot disabled on NIC */
	if ( ( rc = phantom_check_boot_enable ( phantom ) ) != 0 )
		goto err_check_boot_enable;

	/* Register network devices */
	if ( ( rc = register_netdev ( netdev ) ) != 0 ) {
		DBGC ( phantom, "Phantom %p could not register net device: "
		       "%s\n", phantom, strerror ( rc ) );
		goto err_register_netdev;
	}

	/* Register settings blocks */
	parent_settings = netdev_settings ( netdev );
	if ( ( rc = register_settings ( &phantom->settings,
					parent_settings, "clp" ) ) != 0 ) {
		DBGC ( phantom, "Phantom %p could not register settings: "
		       "%s\n", phantom, strerror ( rc ) );
		goto err_register_settings;
	}

	return 0;

	unregister_settings ( &phantom->settings );
 err_register_settings:
	unregister_netdev ( netdev );
 err_register_netdev:
 err_check_boot_enable:
 err_init_rcvpeg:
 err_init_cmdpeg:
 err_map_crb:
	netdev_nullify ( netdev );
	netdev_put ( netdev );
 err_alloc_etherdev:
	return rc;
}

/**
 * Remove PCI device
 *
 * @v pci		PCI device
 */
static void phantom_remove ( struct pci_device *pci ) {
	struct net_device *netdev = pci_get_drvdata ( pci );
	struct phantom_nic *phantom = netdev_priv ( netdev );

	unregister_settings ( &phantom->settings );
	unregister_netdev ( netdev );
	netdev_nullify ( netdev );
	netdev_put ( netdev );
}

/** Phantom PCI IDs */
static struct pci_device_id phantom_nics[] = {
	PCI_ROM ( 0x4040, 0x0100, "nx", "NX", 0 ),
};

/** Phantom PCI driver */
struct pci_driver phantom_driver __pci_driver = {
	.ids = phantom_nics,
	.id_count = ( sizeof ( phantom_nics ) / sizeof ( phantom_nics[0] ) ),
	.probe = phantom_probe,
	.remove = phantom_remove,
};
