summaryrefslogtreecommitdiffstats
path: root/src/drivers/net/phantom/phantom.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/drivers/net/phantom/phantom.c')
-rw-r--r--src/drivers/net/phantom/phantom.c987
1 files changed, 339 insertions, 648 deletions
diff --git a/src/drivers/net/phantom/phantom.c b/src/drivers/net/phantom/phantom.c
index 47bbcb9a..3b2fbfd3 100644
--- a/src/drivers/net/phantom/phantom.c
+++ b/src/drivers/net/phantom/phantom.c
@@ -42,11 +42,8 @@
*
*/
-/** Maximum time to wait for SPI lock */
-#define PHN_SPI_LOCK_TIMEOUT_MS 100
-
-/** Maximum time to wait for SPI command to be issued */
-#define PHN_SPI_CMD_TIMEOUT_MS 100
+/** Maximum number of ports */
+#define PHN_MAX_NUM_PORTS 4
/** Maximum time to wait for command PEG to initialise
*
@@ -110,10 +107,41 @@ struct phantom_descriptor_rings {
volatile uint32_t cmd_cons;
};
-/** A Phantom NIC port */
-struct phantom_nic_port {
- /** Phantom NIC containing this port */
- struct phantom_nic *phantom;
+/** 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;
@@ -148,76 +176,18 @@ struct phantom_nic_port {
struct io_buffer *cds_iobuf[PHN_NUM_CDS];
- /** Link state poll timer */
- unsigned long link_poll_timer;
-
-
/** Descriptor rings */
struct phantom_descriptor_rings *desc;
- /** Non-volatile settings */
- struct settings settings;
-};
-
-/** 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 DMA buffer area */
-union phantom_dma_buffer {
- /** Dummy area required for (read-only) self-tests */
- uint8_t dummy_dma[UNM_DUMMY_DMA_SIZE];
- /** RX context creation request and response buffers */
- struct phantom_create_rx_ctx_rqrsp create_rx_ctx;
- /** TX context creation request and response buffers */
- struct phantom_create_tx_ctx_rqrsp create_tx_ctx;
-};
-
-/** 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 );
-
- /** Number of ports */
- int num_ports;
- /** Per-port network devices */
- struct net_device *netdev[UNM_FLASH_NUM_PORTS];
-
- /** DMA buffers */
- union phantom_dma_buffer *dma_buf;
-
- /** Flash memory SPI bus */
- struct spi_bus spi_bus;
- /** Flash memory SPI device */
- struct spi_device flash;
/** Last known link state */
uint32_t link_state;
+ /** Link state poll timer */
+ unsigned long link_poll_timer;
+
+
+ /** Non-volatile settings */
+ struct settings settings;
};
/***************************************************************************
@@ -533,139 +503,6 @@ phantom_dmesg_all ( struct phantom_nic *phantom, unsigned int max_lines ) {
/***************************************************************************
*
- * SPI bus access (for flash memory)
- *
- */
-
-/**
- * Acquire Phantom SPI lock
- *
- * @v phantom Phantom NIC
- * @ret rc Return status code
- */
-static int phantom_spi_lock ( struct phantom_nic *phantom ) {
- unsigned int retries;
- uint32_t pcie_sem2_lock;
-
- for ( retries = 0 ; retries < PHN_SPI_LOCK_TIMEOUT_MS ; retries++ ) {
- pcie_sem2_lock = phantom_readl ( phantom, UNM_PCIE_SEM2_LOCK );
- if ( pcie_sem2_lock != 0 )
- return 0;
- mdelay ( 1 );
- }
-
- DBGC ( phantom, "Phantom %p timed out waiting for SPI lock\n",
- phantom );
- return -ETIMEDOUT;
-}
-
-/**
- * Wait for Phantom SPI command to complete
- *
- * @v phantom Phantom NIC
- * @ret rc Return status code
- */
-static int phantom_spi_wait ( struct phantom_nic *phantom ) {
- unsigned int retries;
- uint32_t glb_status;
-
- for ( retries = 0 ; retries < PHN_SPI_CMD_TIMEOUT_MS ; retries++ ) {
- glb_status = phantom_readl ( phantom, UNM_ROMUSB_GLB_STATUS );
- if ( glb_status & UNM_ROMUSB_GLB_STATUS_ROM_DONE )
- return 0;
- mdelay ( 1 );
- }
-
- DBGC ( phantom, "Phantom %p timed out waiting for SPI command\n",
- phantom );
- return -ETIMEDOUT;
-}
-
-/**
- * Release Phantom SPI lock
- *
- * @v phantom Phantom NIC
- */
-static void phantom_spi_unlock ( struct phantom_nic *phantom ) {
- phantom_readl ( phantom, UNM_PCIE_SEM2_UNLOCK );
-}
-
-/**
- * Read/write data via Phantom SPI bus
- *
- * @v bus SPI bus
- * @v device SPI device
- * @v command Command
- * @v address Address to read/write (<0 for no address)
- * @v data_out TX data buffer (or NULL)
- * @v data_in RX data buffer (or NULL)
- * @v len Length of data buffer(s)
- * @ret rc Return status code
- */
-static int phantom_spi_rw ( struct spi_bus *bus,
- struct spi_device *device,
- unsigned int command, int address,
- const void *data_out, void *data_in,
- size_t len ) {
- struct phantom_nic *phantom =
- container_of ( bus, struct phantom_nic, spi_bus );
- uint32_t data;
- int rc;
-
- DBGCP ( phantom, "Phantom %p SPI command %x at %x+%zx\n",
- phantom, command, address, len );
- if ( data_out )
- DBGCP_HDA ( phantom, address, data_out, len );
-
- /* We support only exactly 4-byte reads */
- if ( len != UNM_SPI_BLKSIZE ) {
- DBGC ( phantom, "Phantom %p invalid SPI length %zx\n",
- phantom, len );
- return -EINVAL;
- }
-
- /* Acquire SPI lock */
- if ( ( rc = phantom_spi_lock ( phantom ) ) != 0 )
- goto err_lock;
-
- /* Issue SPI command as per the PRM */
- if ( data_out ) {
- memcpy ( &data, data_out, sizeof ( data ) );
- phantom_writel ( phantom, data, UNM_ROMUSB_ROM_WDATA );
- }
- phantom_writel ( phantom, address, UNM_ROMUSB_ROM_ADDRESS );
- phantom_writel ( phantom, ( device->address_len / 8 ),
- UNM_ROMUSB_ROM_ABYTE_CNT );
- udelay ( 100 ); /* according to PRM */
- phantom_writel ( phantom, 0, UNM_ROMUSB_ROM_DUMMY_BYTE_CNT );
- phantom_writel ( phantom, command, UNM_ROMUSB_ROM_INSTR_OPCODE );
-
- /* Wait for SPI command to complete */
- if ( ( rc = phantom_spi_wait ( phantom ) ) != 0 )
- goto err_wait;
-
- /* Reset address byte count and dummy byte count, because the
- * PRM asks us to.
- */
- phantom_writel ( phantom, 0, UNM_ROMUSB_ROM_ABYTE_CNT );
- udelay ( 100 ); /* according to PRM */
- phantom_writel ( phantom, 0, UNM_ROMUSB_ROM_DUMMY_BYTE_CNT );
-
- /* Read data, if applicable */
- if ( data_in ) {
- data = phantom_readl ( phantom, UNM_ROMUSB_ROM_RDATA );
- memcpy ( data_in, &data, sizeof ( data ) );
- DBGCP_HDA ( phantom, address, data_in, len );
- }
-
- err_wait:
- phantom_spi_unlock ( phantom );
- err_lock:
- return rc;
-}
-
-/***************************************************************************
- *
* Firmware interface
*
*/
@@ -705,26 +542,24 @@ static int phantom_wait_for_cmd ( struct phantom_nic *phantom ) {
/**
* Issue command to firmware
*
- * @v phantom_port Phantom NIC port
+ * @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_port *phantom_port,
+static int phantom_issue_cmd ( struct phantom_nic *phantom,
uint32_t command, uint32_t arg1, uint32_t arg2,
uint32_t arg3 ) {
- struct phantom_nic *phantom = phantom_port->phantom;
uint32_t signature;
int rc;
/* Issue command */
- signature = NX_CDRP_SIGNATURE_MAKE ( phantom_port->port,
+ signature = NX_CDRP_SIGNATURE_MAKE ( phantom->port,
NXHAL_VERSION );
- DBGC2 ( phantom, "Phantom %p port %d issuing command %08lx (%08lx, "
- "%08lx, %08lx)\n", phantom, phantom_port->port,
- command, arg1, arg2, arg3 );
+ DBGC2 ( phantom, "Phantom %p issuing command %08lx (%08lx, %08lx, "
+ "%08lx)\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 );
@@ -745,36 +580,41 @@ static int phantom_issue_cmd ( struct phantom_nic_port *phantom_port,
/**
* Issue buffer-format command to firmware
*
- * @v phantom_port Phantom NIC port
+ * @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_port *phantom_port,
+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_port, command, ( physaddr >> 32 ),
+ return phantom_issue_cmd ( phantom, command, ( physaddr >> 32 ),
( physaddr & 0xffffffffUL ), len );
}
/**
* Create Phantom RX context
*
- * @v phantom_port Phantom NIC port
+ * @v phantom Phantom NIC
* @ret rc Return status code
*/
-static int phantom_create_rx_ctx ( struct phantom_nic_port *phantom_port ) {
- struct phantom_nic *phantom = phantom_port->phantom;
+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_dma ( sizeof ( *buf ), UNM_DMA_BUFFER_ALIGN );
+ if ( ! buf ) {
+ rc = -ENOMEM;
+ goto out;
+ }
+ memset ( buf, 0, sizeof ( *buf ) );
/* Prepare request */
- buf = &phantom->dma_buf->create_rx_ctx;
- memset ( buf, 0, sizeof ( *buf ) );
buf->hostrq.rx_ctx.host_rsp_dma_addr =
cpu_to_le64 ( virt_to_bus ( &buf->cardrsp ) );
buf->hostrq.rx_ctx.capabilities[0] =
@@ -789,197 +629,194 @@ static int phantom_create_rx_ctx ( struct phantom_nic_port *phantom_port ) {
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_port->desc->rds ) );
+ 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_port->desc->sds ) );
+ cpu_to_le64 ( virt_to_bus ( phantom->desc->sds ) );
buf->hostrq.sds.ring_size = cpu_to_le32 ( PHN_NUM_SDS );
- DBGC ( phantom, "Phantom %p port %d creating RX context\n",
- phantom, phantom_port->port );
+ 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_port,
+ if ( ( rc = phantom_issue_buf_cmd ( phantom,
NX_CDRP_CMD_CREATE_RX_CTX,
&buf->hostrq,
sizeof ( buf->hostrq ) ) ) != 0 ) {
- DBGC ( phantom, "Phantom %p port %d could not create RX "
- "context: %s\n",
- phantom, phantom_port->port, strerror ( rc ) );
+ 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 ) );
- return rc;
+ goto out;
}
/* Retrieve context parameters */
- phantom_port->rx_context_id =
+ phantom->rx_context_id =
le16_to_cpu ( buf->cardrsp.rx_ctx.context_id );
- phantom_port->rds_producer_crb =
+ phantom->rds_producer_crb =
( UNM_CAM_RAM +
le32_to_cpu ( buf->cardrsp.rds.host_producer_crb ));
- phantom_port->sds_consumer_crb =
+ phantom->sds_consumer_crb =
( UNM_CAM_RAM +
le32_to_cpu ( buf->cardrsp.sds.host_consumer_crb ));
- DBGC ( phantom, "Phantom %p port %d created RX context (id %04x, "
- "port phys %02x virt %02x)\n", phantom, phantom_port->port,
- phantom_port->rx_context_id, buf->cardrsp.rx_ctx.phys_port,
- buf->cardrsp.rx_ctx.virt_port );
+ 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 port %d RDS producer CRB is %08lx\n",
- phantom, phantom_port->port, phantom_port->rds_producer_crb );
- DBGC ( phantom, "Phantom %p port %d SDS consumer CRB is %08lx\n",
- phantom, phantom_port->port, phantom_port->sds_consumer_crb );
+ 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 );
- return 0;
+ out:
+ free_dma ( buf, sizeof ( *buf ) );
+ return rc;
}
/**
* Destroy Phantom RX context
*
- * @v phantom_port Phantom NIC port
+ * @v phantom Phantom NIC
* @ret rc Return status code
*/
-static void phantom_destroy_rx_ctx ( struct phantom_nic_port *phantom_port ) {
- struct phantom_nic *phantom = phantom_port->phantom;
+static void phantom_destroy_rx_ctx ( struct phantom_nic *phantom ) {
int rc;
- DBGC ( phantom, "Phantom %p port %d destroying RX context (id %04x)\n",
- phantom, phantom_port->port, phantom_port->rx_context_id );
+ DBGC ( phantom, "Phantom %p destroying RX context (id %04x)\n",
+ phantom, phantom->rx_context_id );
/* Issue request */
- if ( ( rc = phantom_issue_cmd ( phantom_port,
+ if ( ( rc = phantom_issue_cmd ( phantom,
NX_CDRP_CMD_DESTROY_RX_CTX,
- phantom_port->rx_context_id,
+ phantom->rx_context_id,
NX_DESTROY_CTX_RESET, 0 ) ) != 0 ) {
- DBGC ( phantom, "Phantom %p port %d could not destroy RX "
- "context: %s\n",
- phantom, phantom_port->port, strerror ( rc ) );
+ DBGC ( phantom, "Phantom %p could not destroy RX context: "
+ "%s\n", phantom, strerror ( rc ) );
/* We're probably screwed */
return;
}
/* Clear context parameters */
- phantom_port->rx_context_id = 0;
- phantom_port->rds_producer_crb = 0;
- phantom_port->sds_consumer_crb = 0;
+ phantom->rx_context_id = 0;
+ phantom->rds_producer_crb = 0;
+ phantom->sds_consumer_crb = 0;
/* Reset software counters */
- phantom_port->rds_producer_idx = 0;
- phantom_port->rds_consumer_idx = 0;
- phantom_port->sds_consumer_idx = 0;
+ phantom->rds_producer_idx = 0;
+ phantom->rds_consumer_idx = 0;
+ phantom->sds_consumer_idx = 0;
}
/**
* Create Phantom TX context
*
- * @v phantom_port Phantom NIC port
+ * @v phantom Phantom NIC
* @ret rc Return status code
*/
-static int phantom_create_tx_ctx ( struct phantom_nic_port *phantom_port ) {
- struct phantom_nic *phantom = phantom_port->phantom;
+static int phantom_create_tx_ctx ( struct phantom_nic *phantom ) {
struct phantom_create_tx_ctx_rqrsp *buf;
int rc;
- /* Prepare request */
- buf = &phantom->dma_buf->create_tx_ctx;
+ /* Allocate context creation buffer */
+ buf = malloc_dma ( 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_port->desc->cmd_cons ) );
- buf->hostrq.tx_ctx.dummy_dma_addr =
- cpu_to_le64 ( virt_to_bus ( phantom->dma_buf->dummy_dma ) );
+ 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_port->desc->cds ) );
+ 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 port %d creating TX context\n",
- phantom, phantom_port->port );
+ 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_port,
+ if ( ( rc = phantom_issue_buf_cmd ( phantom,
NX_CDRP_CMD_CREATE_TX_CTX,
&buf->hostrq,
sizeof ( buf->hostrq ) ) ) != 0 ) {
- DBGC ( phantom, "Phantom %p port %d could not create TX "
- "context: %s\n",
- phantom, phantom_port->port, strerror ( rc ) );
+ 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 ) );
- return rc;
+ goto out;
}
/* Retrieve context parameters */
- phantom_port->tx_context_id =
+ phantom->tx_context_id =
le16_to_cpu ( buf->cardrsp.tx_ctx.context_id );
- phantom_port->cds_producer_crb =
+ phantom->cds_producer_crb =
( UNM_CAM_RAM +
le32_to_cpu(buf->cardrsp.tx_ctx.cds_ring.host_producer_crb));
- DBGC ( phantom, "Phantom %p port %d created TX context (id %04x, "
- "port phys %02x virt %02x)\n", phantom, phantom_port->port,
- phantom_port->tx_context_id, buf->cardrsp.tx_ctx.phys_port,
- buf->cardrsp.tx_ctx.virt_port );
+ 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 port %d CDS producer CRB is %08lx\n",
- phantom, phantom_port->port, phantom_port->cds_producer_crb );
+ DBGC ( phantom, "Phantom %p CDS producer CRB is %08lx\n",
+ phantom, phantom->cds_producer_crb );
- return 0;
+ out:
+ free_dma ( buf, sizeof ( *buf ) );
+ return rc;
}
/**
* Destroy Phantom TX context
*
- * @v phantom_port Phantom NIC port
+ * @v phantom Phantom NIC
* @ret rc Return status code
*/
-static void phantom_destroy_tx_ctx ( struct phantom_nic_port *phantom_port ) {
- struct phantom_nic *phantom = phantom_port->phantom;
+static void phantom_destroy_tx_ctx ( struct phantom_nic *phantom ) {
int rc;
- DBGC ( phantom, "Phantom %p port %d destroying TX context (id %04x)\n",
- phantom, phantom_port->port, phantom_port->tx_context_id );
+ DBGC ( phantom, "Phantom %p destroying TX context (id %04x)\n",
+ phantom, phantom->tx_context_id );
/* Issue request */
- if ( ( rc = phantom_issue_cmd ( phantom_port,
+ if ( ( rc = phantom_issue_cmd ( phantom,
NX_CDRP_CMD_DESTROY_TX_CTX,
- phantom_port->tx_context_id,
+ phantom->tx_context_id,
NX_DESTROY_CTX_RESET, 0 ) ) != 0 ) {
- DBGC ( phantom, "Phantom %p port %d could not destroy TX "
- "context: %s\n",
- phantom, phantom_port->port, strerror ( rc ) );
+ DBGC ( phantom, "Phantom %p could not destroy TX context: "
+ "%s\n", phantom, strerror ( rc ) );
/* We're probably screwed */
return;
}
/* Clear context parameters */
- phantom_port->tx_context_id = 0;
- phantom_port->cds_producer_crb = 0;
+ phantom->tx_context_id = 0;
+ phantom->cds_producer_crb = 0;
/* Reset software counters */
- phantom_port->cds_producer_idx = 0;
- phantom_port->cds_consumer_idx = 0;
+ phantom->cds_producer_idx = 0;
+ phantom->cds_consumer_idx = 0;
}
/***************************************************************************
@@ -991,11 +828,10 @@ static void phantom_destroy_tx_ctx ( struct phantom_nic_port *phantom_port ) {
/**
* Allocate Phantom RX descriptor
*
- * @v phantom_port Phantom NIC port
+ * @v phantom Phantom NIC
* @ret index RX descriptor index, or negative error
*/
-static int phantom_alloc_rds ( struct phantom_nic_port *phantom_port ) {
- struct phantom_nic *phantom = phantom_port->phantom;
+static int phantom_alloc_rds ( struct phantom_nic *phantom ) {
unsigned int rds_producer_idx;
unsigned int next_rds_producer_idx;
@@ -1005,12 +841,11 @@ static int phantom_alloc_rds ( struct phantom_nic_port *phantom_port ) {
* guaranteed never to be an overestimate of the number of
* descriptors read by the hardware.
*/
- rds_producer_idx = phantom_port->rds_producer_idx;
+ rds_producer_idx = phantom->rds_producer_idx;
next_rds_producer_idx = ( ( rds_producer_idx + 1 ) % PHN_NUM_RDS );
- if ( next_rds_producer_idx == phantom_port->rds_consumer_idx ) {
- DBGC ( phantom, "Phantom %p port %d RDS ring full (index %d "
- "not consumed)\n", phantom, phantom_port->port,
- next_rds_producer_idx );
+ 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;
}
@@ -1020,41 +855,38 @@ static int phantom_alloc_rds ( struct phantom_nic_port *phantom_port ) {
/**
* Post Phantom RX descriptor
*
- * @v phantom_port Phantom NIC port
+ * @v phantom Phantom NIC
* @v rds RX descriptor
*/
-static void phantom_post_rds ( struct phantom_nic_port *phantom_port,
+static void phantom_post_rds ( struct phantom_nic *phantom,
struct phantom_rds *rds ) {
- struct phantom_nic *phantom = phantom_port->phantom;
unsigned int rds_producer_idx;
unsigned int next_rds_producer_idx;
struct phantom_rds *entry;
/* Copy descriptor to ring */
- rds_producer_idx = phantom_port->rds_producer_idx;
- entry = &phantom_port->desc->rds[rds_producer_idx];
+ rds_producer_idx = phantom->rds_producer_idx;
+ entry = &phantom->desc->rds[rds_producer_idx];
memcpy ( entry, rds, sizeof ( *entry ) );
- DBGC2 ( phantom, "Phantom %p port %d posting RDS %ld (slot %d):\n",
- phantom, phantom_port->port, NX_GET ( rds, handle ),
- rds_producer_idx );
+ 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_port->rds_producer_idx = next_rds_producer_idx;
+ phantom->rds_producer_idx = next_rds_producer_idx;
wmb();
- phantom_writel ( phantom, phantom_port->rds_producer_idx,
- phantom_port->rds_producer_crb );
+ phantom_writel ( phantom, phantom->rds_producer_idx,
+ phantom->rds_producer_crb );
}
/**
* Allocate Phantom TX descriptor
*
- * @v phantom_port Phantom NIC port
+ * @v phantom Phantom NIC
* @ret index TX descriptor index, or negative error
*/
-static int phantom_alloc_cds ( struct phantom_nic_port *phantom_port ) {
- struct phantom_nic *phantom = phantom_port->phantom;
+static int phantom_alloc_cds ( struct phantom_nic *phantom ) {
unsigned int cds_producer_idx;
unsigned int next_cds_producer_idx;
@@ -1062,12 +894,11 @@ static int phantom_alloc_cds ( struct phantom_nic_port *phantom_port ) {
* in strict order, so we just check for a collision against
* the consumer index.
*/
- cds_producer_idx = phantom_port->cds_producer_idx;
+ cds_producer_idx = phantom->cds_producer_idx;
next_cds_producer_idx = ( ( cds_producer_idx + 1 ) % PHN_NUM_CDS );
- if ( next_cds_producer_idx == phantom_port->cds_consumer_idx ) {
- DBGC ( phantom, "Phantom %p port %d CDS ring full (index %d "
- "not consumed)\n", phantom, phantom_port->port,
- next_cds_producer_idx );
+ 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;
}
@@ -1077,30 +908,29 @@ static int phantom_alloc_cds ( struct phantom_nic_port *phantom_port ) {
/**
* Post Phantom TX descriptor
*
- * @v phantom_port Phantom NIC port
+ * @v phantom Phantom NIC
* @v cds TX descriptor
*/
-static void phantom_post_cds ( struct phantom_nic_port *phantom_port,
+static void phantom_post_cds ( struct phantom_nic *phantom,
union phantom_cds *cds ) {
- struct phantom_nic *phantom = phantom_port->phantom;
unsigned int cds_producer_idx;
unsigned int next_cds_producer_idx;
union phantom_cds *entry;
/* Copy descriptor to ring */
- cds_producer_idx = phantom_port->cds_producer_idx;
- entry = &phantom_port->desc->cds[cds_producer_idx];
+ cds_producer_idx = phantom->cds_producer_idx;
+ entry = &phantom->desc->cds[cds_producer_idx];
memcpy ( entry, cds, sizeof ( *entry ) );
- DBGC2 ( phantom, "Phantom %p port %d posting CDS %d:\n",
- phantom, phantom_port->port, cds_producer_idx );
+ 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_port->cds_producer_idx = next_cds_producer_idx;
+ phantom->cds_producer_idx = next_cds_producer_idx;
wmb();
- phantom_writel ( phantom, phantom_port->cds_producer_idx,
- phantom_port->cds_producer_crb );
+ phantom_writel ( phantom, phantom->cds_producer_idx,
+ phantom->cds_producer_crb );
}
/***************************************************************************
@@ -1112,19 +942,19 @@ static void phantom_post_cds ( struct phantom_nic_port *phantom_port,
/**
* Add/remove MAC address
*
- * @v phantom_port Phantom NIC port
+ * @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_port *phantom_port,
+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_port );
+ index = phantom_alloc_cds ( phantom );
if ( index < 0 )
return index;
@@ -1134,7 +964,7 @@ static int phantom_update_macaddr ( struct phantom_nic_port *phantom_port,
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->port );
+ 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],
@@ -1145,7 +975,7 @@ static int phantom_update_macaddr ( struct phantom_nic_port *phantom_port,
nic_request.body.mac_request.mac_addr_5, ll_addr[5] );
/* Post descriptor */
- phantom_post_cds ( phantom_port, &cds );
+ phantom_post_cds ( phantom, &cds );
return 0;
}
@@ -1153,35 +983,33 @@ static int phantom_update_macaddr ( struct phantom_nic_port *phantom_port,
/**
* Add MAC address
*
- * @v phantom_port Phantom NIC port
+ * @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_port *phantom_port,
+static inline int phantom_add_macaddr ( struct phantom_nic *phantom,
const uint8_t *ll_addr ) {
- struct phantom_nic *phantom = phantom_port->phantom;
- DBGC ( phantom, "Phantom %p port %d adding MAC address %s\n",
- phantom, phantom_port->port, eth_ntoa ( ll_addr ) );
+ DBGC ( phantom, "Phantom %p adding MAC address %s\n",
+ phantom, eth_ntoa ( ll_addr ) );
- return phantom_update_macaddr ( phantom_port, ll_addr, UNM_MAC_ADD );
+ return phantom_update_macaddr ( phantom, ll_addr, UNM_MAC_ADD );
}
/**
* Remove MAC address
*
- * @v phantom_port Phantom NIC port
+ * @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_port *phantom_port,
+static inline int phantom_del_macaddr ( struct phantom_nic *phantom,
const uint8_t *ll_addr ) {
- struct phantom_nic *phantom = phantom_port->phantom;
- DBGC ( phantom, "Phantom %p port %d removing MAC address %s\n",
- phantom, phantom_port->port, eth_ntoa ( ll_addr ) );
+ DBGC ( phantom, "Phantom %p removing MAC address %s\n",
+ phantom, eth_ntoa ( ll_addr ) );
- return phantom_update_macaddr ( phantom_port, ll_addr, UNM_MAC_DEL );
+ return phantom_update_macaddr ( phantom, ll_addr, UNM_MAC_DEL );
}
/***************************************************************************
@@ -1193,14 +1021,12 @@ static inline int phantom_del_macaddr ( struct phantom_nic_port *phantom_port,
/**
* Poll link state
*
- * @v phantom Phantom NIC
+ * @v netdev Network device
*/
-static void phantom_poll_link_state ( struct phantom_nic *phantom ) {
- struct net_device *netdev;
- struct phantom_nic_port *phantom_port;
+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;
- int i;
/* Read link state */
xg_state_p3 = phantom_readl ( phantom, UNM_NIC_REG_XG_STATE_P3 );
@@ -1214,28 +1040,22 @@ static void phantom_poll_link_state ( struct phantom_nic *phantom ) {
phantom, xg_state_p3, phantom->link_state );
phantom->link_state = xg_state_p3;
- /* Indicate per-port link state to gPXE */
- for ( i = 0 ; i < phantom->num_ports ; i++ ) {
- netdev = phantom->netdev[i];
- phantom_port = netdev_priv ( netdev );
- link = UNM_NIC_REG_XG_STATE_P3_LINK ( phantom_port->port,
- phantom->link_state );
- switch ( link ) {
- case UNM_NIC_REG_XG_STATE_P3_LINK_UP:
- DBGC ( phantom, "Phantom %p port %d link is up\n",
- phantom, phantom_port->port );
- netdev_link_up ( netdev );
- break;
- case UNM_NIC_REG_XG_STATE_P3_LINK_DOWN:
- DBGC ( phantom, "Phantom %p port %d link is down\n",
- phantom, phantom_port->port );
- netdev_link_down ( netdev );
- break;
- default:
- DBGC ( phantom, "Phantom %p port %d bad link state "
- "%d\n", phantom, phantom_port->port, link );
- break;
- }
+ /* Indicate link state to gPXE */
+ 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;
}
}
@@ -1251,7 +1071,7 @@ static void phantom_poll_link_state ( struct phantom_nic *phantom ) {
* @v netdev Net device
*/
static void phantom_refill_rx_ring ( struct net_device *netdev ) {
- struct phantom_nic_port *phantom_port = netdev_priv ( netdev );
+ struct phantom_nic *phantom = netdev_priv ( netdev );
struct io_buffer *iobuf;
struct phantom_rds rds;
unsigned int handle;
@@ -1262,11 +1082,11 @@ static void phantom_refill_rx_ring ( struct net_device *netdev ) {
/* Skip this index if the descriptor has not yet been
* consumed.
*/
- if ( phantom_port->rds_iobuf[handle] != NULL )
+ if ( phantom->rds_iobuf[handle] != NULL )
continue;
/* Allocate descriptor ring entry */
- index = phantom_alloc_rds ( phantom_port );
+ index = phantom_alloc_rds ( phantom );
assert ( PHN_RDS_MAX_FILL < PHN_NUM_RDS );
assert ( index >= 0 ); /* Guaranteed by MAX_FILL < NUM_RDS ) */
@@ -1287,11 +1107,11 @@ static void phantom_refill_rx_ring ( struct net_device *netdev ) {
dma_addr, virt_to_bus ( iobuf->data ) );
/* Record I/O buffer */
- assert ( phantom_port->rds_iobuf[handle] == NULL );
- phantom_port->rds_iobuf[handle] = iobuf;
+ assert ( phantom->rds_iobuf[handle] == NULL );
+ phantom->rds_iobuf[handle] = iobuf;
/* Post descriptor */
- phantom_post_rds ( phantom_port, &rds );
+ phantom_post_rds ( phantom, &rds );
}
}
@@ -1302,24 +1122,24 @@ static void phantom_refill_rx_ring ( struct net_device *netdev ) {
* @ret rc Return status code
*/
static int phantom_open ( struct net_device *netdev ) {
- struct phantom_nic_port *phantom_port = netdev_priv ( netdev );
+ struct phantom_nic *phantom = netdev_priv ( netdev );
int rc;
/* Allocate and zero descriptor rings */
- phantom_port->desc = malloc_dma ( sizeof ( *(phantom_port->desc) ),
+ phantom->desc = malloc_dma ( sizeof ( *(phantom->desc) ),
UNM_DMA_BUFFER_ALIGN );
- if ( ! phantom_port->desc ) {
+ if ( ! phantom->desc ) {
rc = -ENOMEM;
goto err_alloc_desc;
}
- memset ( phantom_port->desc, 0, sizeof ( *(phantom_port->desc) ) );
+ memset ( phantom->desc, 0, sizeof ( *(phantom->desc) ) );
/* Create RX context */
- if ( ( rc = phantom_create_rx_ctx ( phantom_port ) ) != 0 )
+ if ( ( rc = phantom_create_rx_ctx ( phantom ) ) != 0 )
goto err_create_rx_ctx;
/* Create TX context */
- if ( ( rc = phantom_create_tx_ctx ( phantom_port ) ) != 0 )
+ if ( ( rc = phantom_create_tx_ctx ( phantom ) ) != 0 )
goto err_create_tx_ctx;
/* Fill the RX descriptor ring */
@@ -1333,26 +1153,26 @@ static int phantom_open ( struct net_device *netdev ) {
* packets (or, failing that, promiscuous mode), but the
* firmware doesn't currently support this.
*/
- if ( ( rc = phantom_add_macaddr ( phantom_port,
+ if ( ( rc = phantom_add_macaddr ( phantom,
netdev->ll_protocol->ll_broadcast ) ) != 0 )
goto err_add_macaddr_broadcast;
- if ( ( rc = phantom_add_macaddr ( phantom_port,
+ if ( ( rc = phantom_add_macaddr ( phantom,
netdev->ll_addr ) ) != 0 )
goto err_add_macaddr_unicast;
return 0;
- phantom_del_macaddr ( phantom_port, netdev->ll_addr );
+ phantom_del_macaddr ( phantom, netdev->ll_addr );
err_add_macaddr_unicast:
- phantom_del_macaddr ( phantom_port,
+ phantom_del_macaddr ( phantom,
netdev->ll_protocol->ll_broadcast );
err_add_macaddr_broadcast:
- phantom_destroy_tx_ctx ( phantom_port );
+ phantom_destroy_tx_ctx ( phantom );
err_create_tx_ctx:
- phantom_destroy_rx_ctx ( phantom_port );
+ phantom_destroy_rx_ctx ( phantom );
err_create_rx_ctx:
- free_dma ( phantom_port->desc, sizeof ( *(phantom_port->desc) ) );
- phantom_port->desc = NULL;
+ free_dma ( phantom->desc, sizeof ( *(phantom->desc) ) );
+ phantom->desc = NULL;
err_alloc_desc:
return rc;
}
@@ -1363,32 +1183,32 @@ static int phantom_open ( struct net_device *netdev ) {
* @v netdev Net device
*/
static void phantom_close ( struct net_device *netdev ) {
- struct phantom_nic_port *phantom_port = netdev_priv ( netdev );
+ struct phantom_nic *phantom = netdev_priv ( netdev );
struct io_buffer *iobuf;
unsigned int i;
/* Shut down the port */
- phantom_del_macaddr ( phantom_port, netdev->ll_addr );
- phantom_del_macaddr ( phantom_port,
+ phantom_del_macaddr ( phantom, netdev->ll_addr );
+ phantom_del_macaddr ( phantom,
netdev->ll_protocol->ll_broadcast );
- phantom_destroy_tx_ctx ( phantom_port );
- phantom_destroy_rx_ctx ( phantom_port );
- free_dma ( phantom_port->desc, sizeof ( *(phantom_port->desc) ) );
- phantom_port->desc = NULL;
+ phantom_destroy_tx_ctx ( phantom );
+ phantom_destroy_rx_ctx ( phantom );
+ free_dma ( phantom->desc, sizeof ( *(phantom->desc) ) );
+ phantom->desc = NULL;
/* Flush any uncompleted descriptors */
for ( i = 0 ; i < PHN_RDS_MAX_FILL ; i++ ) {
- iobuf = phantom_port->rds_iobuf[i];
+ iobuf = phantom->rds_iobuf[i];
if ( iobuf ) {
free_iob ( iobuf );
- phantom_port->rds_iobuf[i] = NULL;
+ phantom->rds_iobuf[i] = NULL;
}
}
for ( i = 0 ; i < PHN_NUM_CDS ; i++ ) {
- iobuf = phantom_port->cds_iobuf[i];
+ iobuf = phantom->cds_iobuf[i];
if ( iobuf ) {
netdev_tx_complete_err ( netdev, iobuf, -ECANCELED );
- phantom_port->cds_iobuf[i] = NULL;
+ phantom->cds_iobuf[i] = NULL;
}
}
}
@@ -1402,12 +1222,12 @@ static void phantom_close ( struct net_device *netdev ) {
*/
static int phantom_transmit ( struct net_device *netdev,
struct io_buffer *iobuf ) {
- struct phantom_nic_port *phantom_port = netdev_priv ( netdev );
+ struct phantom_nic *phantom = netdev_priv ( netdev );
union phantom_cds cds;
int index;
/* Get descriptor ring entry */
- index = phantom_alloc_cds ( phantom_port );
+ index = phantom_alloc_cds ( phantom );
if ( index < 0 )
return index;
@@ -1418,19 +1238,19 @@ static int phantom_transmit ( struct net_device *netdev,
tx.num_buffers, 1,
tx.length, iob_len ( iobuf ) );
NX_FILL_2 ( &cds, 2,
- tx.port, phantom_port->port,
- tx.context_id, phantom_port->port );
+ 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_port->cds_iobuf[index] == NULL );
- phantom_port->cds_iobuf[index] = iobuf;
+ assert ( phantom->cds_iobuf[index] == NULL );
+ phantom->cds_iobuf[index] = iobuf;
/* Post descriptor */
- phantom_post_cds ( phantom_port, &cds );
+ phantom_post_cds ( phantom, &cds );
return 0;
}
@@ -1441,8 +1261,7 @@ static int phantom_transmit ( struct net_device *netdev,
* @v netdev Network device
*/
static void phantom_poll ( struct net_device *netdev ) {
- struct phantom_nic_port *phantom_port = netdev_priv ( netdev );
- struct phantom_nic *phantom = phantom_port->phantom;
+ struct phantom_nic *phantom = netdev_priv ( netdev );
struct io_buffer *iobuf;
unsigned int cds_consumer_idx;
unsigned int raw_new_cds_consumer_idx;
@@ -1454,33 +1273,33 @@ static void phantom_poll ( struct net_device *netdev ) {
unsigned int sds_opcode;
/* Check for TX completions */
- cds_consumer_idx = phantom_port->cds_consumer_idx;
- raw_new_cds_consumer_idx = phantom_port->desc->cmd_cons;
+ 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 port %d CDS %d complete\n",
- phantom, phantom_port->port, 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_port->cds_iobuf[cds_consumer_idx] ) ) {
+ if ( ( iobuf = phantom->cds_iobuf[cds_consumer_idx] ) ) {
netdev_tx_complete ( netdev, iobuf );
- phantom_port->cds_iobuf[cds_consumer_idx] = NULL;
+ phantom->cds_iobuf[cds_consumer_idx] = NULL;
}
cds_consumer_idx = ( ( cds_consumer_idx + 1 ) % PHN_NUM_CDS );
- phantom_port->cds_consumer_idx = cds_consumer_idx;
+ phantom->cds_consumer_idx = cds_consumer_idx;
}
/* Check for received packets */
- rds_consumer_idx = phantom_port->rds_consumer_idx;
- sds_consumer_idx = phantom_port->sds_consumer_idx;
+ rds_consumer_idx = phantom->rds_consumer_idx;
+ sds_consumer_idx = phantom->sds_consumer_idx;
while ( 1 ) {
- sds = &phantom_port->desc->sds[sds_consumer_idx];
+ sds = &phantom->desc->sds[sds_consumer_idx];
if ( NX_GET ( sds, owner ) == 0 )
break;
- DBGC2 ( phantom, "Phantom %p port %d SDS %d status:\n",
- phantom, phantom_port->port, sds_consumer_idx );
+ 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 */
@@ -1492,24 +1311,23 @@ static void phantom_poll ( struct net_device *netdev ) {
* descriptor has been written.
*/
if ( NX_GET ( sds, total_length ) == 0 ) {
- DBGC ( phantom, "Phantom %p port %d SDS %d "
- "incomplete; deferring\n", phantom,
- phantom_port->port, sds_consumer_idx );
+ 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_port->rds_iobuf[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 port %d RDS %d "
- "complete\n",
- phantom, phantom_port->port, sds_handle );
+ DBGC2 ( phantom, "Phantom %p RDS %d complete\n",
+ phantom, sds_handle );
netdev_rx ( netdev, iobuf );
- phantom_port->rds_iobuf[sds_handle] = NULL;
+ phantom->rds_iobuf[sds_handle] = NULL;
/* Update RDS consumer counter. This is a
* lower bound for the number of descriptors
@@ -1520,13 +1338,12 @@ static void phantom_poll ( struct net_device *netdev ) {
*/
rds_consumer_idx =
( ( rds_consumer_idx + 1 ) % PHN_NUM_RDS );
- phantom_port->rds_consumer_idx = rds_consumer_idx;
+ phantom->rds_consumer_idx = rds_consumer_idx;
} else {
- DBGC ( phantom, "Phantom %p port %d unexpected SDS "
- "opcode %02x\n",
- phantom, phantom_port->port, sds_opcode );
+ DBGC ( phantom, "Phantom %p unexpected SDS opcode "
+ "%02x\n", phantom, sds_opcode );
DBGC_HDA ( phantom, virt_to_bus ( sds ),
sds, sizeof ( *sds ) );
}
@@ -1536,20 +1353,20 @@ static void phantom_poll ( struct net_device *netdev ) {
/* Update SDS consumer index */
sds_consumer_idx = ( ( sds_consumer_idx + 1 ) % PHN_NUM_SDS );
- phantom_port->sds_consumer_idx = sds_consumer_idx;
+ phantom->sds_consumer_idx = sds_consumer_idx;
wmb();
- phantom_writel ( phantom, phantom_port->sds_consumer_idx,
- phantom_port->sds_consumer_crb );
+ phantom_writel ( phantom, phantom->sds_consumer_idx,
+ phantom->sds_consumer_crb );
}
/* Refill the RX descriptor ring */
phantom_refill_rx_ring ( netdev );
/* Occasionally poll the link state */
- if ( phantom_port->link_poll_timer-- == 0 ) {
- phantom_poll_link_state ( phantom );
+ if ( phantom->link_poll_timer-- == 0 ) {
+ phantom_poll_link_state ( netdev );
/* Reset the link poll timer */
- phantom_port->link_poll_timer = PHN_LINK_POLL_FREQUENCY;
+ phantom->link_poll_timer = PHN_LINK_POLL_FREQUENCY;
}
}
@@ -1560,9 +1377,8 @@ static void phantom_poll ( struct net_device *netdev ) {
* @v enable Interrupts should be enabled
*/
static void phantom_irq ( struct net_device *netdev, int enable ) {
- struct phantom_nic_port *phantom_port = netdev_priv ( netdev );
- struct phantom_nic *phantom = phantom_port->phantom;
- static const unsigned long sw_int_mask_reg[UNM_FLASH_NUM_PORTS] = {
+ struct phantom_nic *phantom = netdev_priv ( netdev );
+ static const unsigned long sw_int_mask_reg[PHN_MAX_NUM_PORTS] = {
UNM_NIC_REG_SW_INT_MASK_0,
UNM_NIC_REG_SW_INT_MASK_1,
UNM_NIC_REG_SW_INT_MASK_2,
@@ -1571,7 +1387,7 @@ static void phantom_irq ( struct net_device *netdev, int enable ) {
phantom_writel ( phantom,
( enable ? 1 : 0 ),
- sw_int_mask_reg[phantom_port->port] );
+ sw_int_mask_reg[phantom->port] );
}
/** Phantom net device operations */
@@ -1845,9 +1661,8 @@ phantom_clp_setting ( struct phantom_nic *phantom, struct setting *setting ) {
static int phantom_store_setting ( struct settings *settings,
struct setting *setting,
const void *data, size_t len ) {
- struct phantom_nic_port *phantom_port =
- container_of ( settings, struct phantom_nic_port, settings );
- struct phantom_nic *phantom = phantom_port->phantom;
+ struct phantom_nic *phantom =
+ container_of ( settings, struct phantom_nic, settings );
unsigned int clp_setting;
int rc;
@@ -1857,7 +1672,7 @@ static int phantom_store_setting ( struct settings *settings,
return -ENOTSUP;
/* Store setting */
- if ( ( rc = phantom_clp_store ( phantom, phantom_port->port,
+ 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 ) );
@@ -1879,9 +1694,8 @@ static int phantom_store_setting ( struct settings *settings,
static int phantom_fetch_setting ( struct settings *settings,
struct setting *setting,
void *data, size_t len ) {
- struct phantom_nic_port *phantom_port =
- container_of ( settings, struct phantom_nic_port, settings );
- struct phantom_nic *phantom = phantom_port->phantom;
+ struct phantom_nic *phantom =
+ container_of ( settings, struct phantom_nic, settings );
unsigned int clp_setting;
int read_len;
int rc;
@@ -1892,7 +1706,7 @@ static int phantom_fetch_setting ( struct settings *settings,
return -ENOTSUP;
/* Fetch setting */
- if ( ( read_len = phantom_clp_fetch ( phantom, phantom_port->port,
+ 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\": "
@@ -1928,8 +1742,15 @@ static int phantom_map_crb ( struct phantom_nic *phantom,
bar0_start = pci_bar_start ( pci, PCI_BASE_ADDRESS_0 );
bar0_size = pci_bar_size ( pci, PCI_BASE_ADDRESS_0 );
- DBGC ( phantom, "Phantom %p BAR0 is %08lx+%lx\n",
- phantom, bar0_start, bar0_size );
+ DBGC ( phantom, "Phantom %p is PCI %02x:%02x.%x with BAR0 at "
+ "%08lx+%lx\n", phantom, pci->bus, PCI_SLOT ( pci->devfn ),
+ PCI_FUNC ( pci->devfn ), 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 ) :
@@ -1964,74 +1785,6 @@ static int phantom_map_crb ( struct phantom_nic *phantom,
}
/**
- * Read Phantom flash contents
- *
- * @v phantom Phantom NIC
- * @ret rc Return status code
- */
-static int phantom_read_flash ( struct phantom_nic *phantom ) {
- struct unm_board_info board_info;
- int rc;
-
- /* Initialise flash access */
- phantom->spi_bus.rw = phantom_spi_rw;
- phantom->flash.bus = &phantom->spi_bus;
- init_m25p32 ( &phantom->flash );
- /* Phantom doesn't support greater than 4-byte block sizes */
- phantom->flash.nvs.block_size = UNM_SPI_BLKSIZE;
-
- /* Read and verify board information */
- if ( ( rc = nvs_read ( &phantom->flash.nvs, UNM_BRDCFG_START,
- &board_info, sizeof ( board_info ) ) ) != 0 ) {
- DBGC ( phantom, "Phantom %p could not read board info: %s\n",
- phantom, strerror ( rc ) );
- return rc;
- }
- if ( board_info.magic != UNM_BDINFO_MAGIC ) {
- DBGC ( phantom, "Phantom %p has bad board info magic %lx\n",
- phantom, board_info.magic );
- DBGC_HD ( phantom, &board_info, sizeof ( board_info ) );
- return -EINVAL;
- }
- if ( board_info.header_version != UNM_BDINFO_VERSION ) {
- DBGC ( phantom, "Phantom %p has bad board info version %lx\n",
- phantom, board_info.header_version );
- DBGC_HD ( phantom, &board_info, sizeof ( board_info ) );
- return -EINVAL;
- }
-
- /* Identify board type and number of ports */
- switch ( board_info.board_type ) {
- case UNM_BRDTYPE_P3_4_GB:
- case UNM_BRDTYPE_P3_4_GB_MM:
- phantom->num_ports = 4;
- break;
- case UNM_BRDTYPE_P3_HMEZ:
- case UNM_BRDTYPE_P3_IMEZ:
- case UNM_BRDTYPE_P3_10G_CX4:
- case UNM_BRDTYPE_P3_10G_CX4_LP:
- case UNM_BRDTYPE_P3_10G_SFP_PLUS:
- case UNM_BRDTYPE_P3_XG_LOM:
- phantom->num_ports = 2;
- break;
- case UNM_BRDTYPE_P3_10000_BASE_T:
- case UNM_BRDTYPE_P3_10G_XFP:
- phantom->num_ports = 1;
- break;
- default:
- DBGC ( phantom, "Phantom %p unrecognised board type %#lx; "
- "assuming single-port\n",
- phantom, board_info.board_type );
- phantom->num_ports = 1;
- break;
- }
- DBGC ( phantom, "Phantom %p board type is %#lx (%d ports)\n",
- phantom, board_info.board_type, phantom->num_ports );
-
- return 0;
-}
-
-/**
* Halt all PEGs
*
* @v phantom Phantom NIC
@@ -2073,7 +1826,6 @@ static void phantom_unhalt_pegs ( struct phantom_nic *phantom ) {
static int phantom_init_cmdpeg ( struct phantom_nic *phantom ) {
uint32_t cold_boot;
uint32_t sw_reset;
- physaddr_t dummy_dma_phys;
unsigned int retries;
uint32_t cmdpeg_state;
uint32_t last_cmdpeg_state = 0;
@@ -2117,10 +1869,7 @@ static int phantom_init_cmdpeg ( struct phantom_nic *phantom ) {
UNM_CAM_RAM_WOL_PORT_MODE );
/* Pass dummy DMA area to card */
- dummy_dma_phys = virt_to_bus ( phantom->dma_buf->dummy_dma );
- DBGC ( phantom, "Phantom %p dummy DMA at %08lx\n",
- phantom, dummy_dma_phys );
- phantom_write_hilo ( phantom, dummy_dma_phys,
+ 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,
@@ -2160,12 +1909,11 @@ static int phantom_init_cmdpeg ( struct phantom_nic *phantom ) {
/**
* Read Phantom MAC address
*
- * @v phanton_port Phantom NIC port
+ * @v phanton_port Phantom NIC
* @v ll_addr Buffer to fill with MAC address
*/
-static void phantom_get_macaddr ( struct phantom_nic_port *phantom_port,
+static void phantom_get_macaddr ( struct phantom_nic *phantom,
uint8_t *ll_addr ) {
- struct phantom_nic *phantom = phantom_port->phantom;
union {
uint8_t mac_addr[2][ETH_ALEN];
uint32_t dwords[3];
@@ -2175,7 +1923,7 @@ static void phantom_get_macaddr ( struct phantom_nic_port *phantom_port,
/* Read the three dwords that include this MAC address and one other */
offset = ( UNM_CAM_RAM_MAC_ADDRS +
- ( 12 * ( phantom_port->port / 2 ) ) );
+ ( 12 * ( phantom->port / 2 ) ) );
for ( i = 0 ; i < 3 ; i++, offset += 4 ) {
u.dwords[i] = phantom_readl ( phantom, offset );
}
@@ -2183,10 +1931,10 @@ static void phantom_get_macaddr ( struct phantom_nic_port *phantom_port,
/* Copy out the relevant MAC address */
for ( i = 0 ; i < ETH_ALEN ; i++ ) {
ll_addr[ ETH_ALEN - i - 1 ] =
- u.mac_addr[ phantom_port->port & 1 ][i];
+ u.mac_addr[ phantom->port & 1 ][i];
}
- DBGC ( phantom, "Phantom %p port %d MAC address is %s\n",
- phantom, phantom_port->port, eth_ntoa ( ll_addr ) );
+ DBGC ( phantom, "Phantom %p MAC address is %s\n",
+ phantom, eth_ntoa ( ll_addr ) );
}
/**
@@ -2230,26 +1978,27 @@ static int phantom_init_rcvpeg ( struct phantom_nic *phantom ) {
*/
static int phantom_probe ( struct pci_device *pci,
const struct pci_device_id *id __unused ) {
- struct phantom_nic *phantom;
struct net_device *netdev;
- struct phantom_nic_port *phantom_port;
+ struct phantom_nic *phantom;
struct settings *parent_settings;
- int i;
int rc;
- /* Phantom NICs expose multiple PCI functions, used for
- * virtualisation. Ignore everything except function 0.
- */
- if ( PCI_FUNC ( pci->devfn ) != 0 )
- return -ENODEV;
-
/* Allocate Phantom device */
- phantom = zalloc ( sizeof ( *phantom ) );
- if ( ! phantom ) {
+ netdev = alloc_etherdev ( sizeof ( *phantom ) );
+ if ( ! netdev ) {
rc = -ENOMEM;
- goto err_alloc_phantom;
+ goto err_alloc_etherdev;
}
- pci_set_drvdata ( pci, phantom );
+ 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->devfn );
+ assert ( phantom->port < PHN_MAX_NUM_PORTS );
+ settings_init ( &phantom->settings,
+ &phantom_settings_operations,
+ &netdev->refcnt, "clp", PHN_CLP_TAG_MAGIC );
/* Fix up PCI device */
adjust_pci_device ( pci );
@@ -2258,110 +2007,62 @@ static int phantom_probe ( struct pci_device *pci,
if ( ( rc = phantom_map_crb ( phantom, pci ) ) != 0 )
goto err_map_crb;
- /* Read flash information */
- if ( ( rc = phantom_read_flash ( phantom ) ) != 0 )
- goto err_read_flash;
-
- /* Allocate net devices for each port */
- for ( i = 0 ; i < phantom->num_ports ; i++ ) {
- netdev = alloc_etherdev ( sizeof ( *phantom_port ) );
- if ( ! netdev ) {
- rc = -ENOMEM;
- goto err_alloc_etherdev;
- }
- phantom->netdev[i] = netdev;
- netdev_init ( netdev, &phantom_operations );
- phantom_port = netdev_priv ( netdev );
- netdev->dev = &pci->dev;
- phantom_port->phantom = phantom;
- phantom_port->port = i;
- settings_init ( &phantom_port->settings,
- &phantom_settings_operations,
- &netdev->refcnt, "clp", PHN_CLP_TAG_MAGIC );
- }
-
/* 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.
*/
- for ( i = 0 ; i < 8 ; i++ ) {
- uint32_t temp;
- pci->devfn = PCI_DEVFN ( PCI_SLOT ( pci->devfn ), i );
- pci_read_config_dword ( pci, 0xc8, &temp );
- pci_read_config_dword ( pci, 0xc8, &temp );
- pci_write_config_dword ( pci, 0xc8, 0xf1000 );
+ if ( PCI_FUNC ( pci->devfn ) == 0 ) {
+ unsigned int i;
+ for ( i = 0 ; i < 8 ; i++ ) {
+ uint32_t temp;
+ pci->devfn = PCI_DEVFN ( PCI_SLOT ( pci->devfn ), i );
+ pci_read_config_dword ( pci, 0xc8, &temp );
+ pci_read_config_dword ( pci, 0xc8, &temp );
+ pci_write_config_dword ( pci, 0xc8, 0xf1000 );
+ }
+ pci->devfn = PCI_DEVFN ( PCI_SLOT ( pci->devfn ), 0 );
}
- pci->devfn = PCI_DEVFN ( PCI_SLOT ( pci->devfn ), 0 );
- /* Allocate dummy DMA buffer and perform initial hardware handshake */
- phantom->dma_buf = malloc_dma ( sizeof ( *(phantom->dma_buf) ),
- UNM_DMA_BUFFER_ALIGN );
- if ( ! phantom->dma_buf )
- goto err_dma_buf;
+ /* Initialise the command PEG */
if ( ( rc = phantom_init_cmdpeg ( phantom ) ) != 0 )
goto err_init_cmdpeg;
- /* Initialise the receive firmware */
+ /* Initialise the receive PEG */
if ( ( rc = phantom_init_rcvpeg ( phantom ) ) != 0 )
goto err_init_rcvpeg;
/* Read MAC addresses */
- for ( i = 0 ; i < phantom->num_ports ; i++ ) {
- phantom_port = netdev_priv ( phantom->netdev[i] );
- phantom_get_macaddr ( phantom_port,
- phantom->netdev[i]->ll_addr );
- }
+ phantom_get_macaddr ( phantom, netdev->ll_addr );
/* Register network devices */
- for ( i = 0 ; i < phantom->num_ports ; i++ ) {
- if ( ( rc = register_netdev ( phantom->netdev[i] ) ) != 0 ) {
- DBGC ( phantom, "Phantom %p could not register port "
- "%d: %s\n", phantom, i, strerror ( rc ) );
- goto err_register_netdev;
- }
+ 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 */
- for ( i = 0 ; i < phantom->num_ports ; i++ ) {
- phantom_port = netdev_priv ( phantom->netdev[i] );
- parent_settings = netdev_settings ( phantom->netdev[i] );
- if ( ( rc = register_settings ( &phantom_port->settings,
- parent_settings ) ) != 0 ) {
- DBGC ( phantom, "Phantom %p could not register port "
- "%d settings: %s\n",
- phantom, i, strerror ( rc ) );
- goto err_register_settings;
- }
+ parent_settings = netdev_settings ( netdev );
+ if ( ( rc = register_settings ( &phantom->settings,
+ parent_settings ) ) != 0 ) {
+ DBGC ( phantom, "Phantom %p could not register settings: "
+ "%s\n", phantom, strerror ( rc ) );
+ goto err_register_settings;
}
return 0;
- i = ( phantom->num_ports - 1 );
+ unregister_settings ( &phantom->settings );
err_register_settings:
- for ( ; i >= 0 ; i-- ) {
- phantom_port = netdev_priv ( phantom->netdev[i] );
- unregister_settings ( &phantom_port->settings );
- }
- i = ( phantom->num_ports - 1 );
+ unregister_netdev ( netdev );
err_register_netdev:
- for ( ; i >= 0 ; i-- )
- unregister_netdev ( phantom->netdev[i] );
err_init_rcvpeg:
- phantom_halt_pegs ( phantom );
err_init_cmdpeg:
- free_dma ( phantom->dma_buf, sizeof ( *(phantom->dma_buf) ) );
- phantom->dma_buf = NULL;
- err_dma_buf:
- i = ( phantom->num_ports - 1 );
- err_alloc_etherdev:
- for ( ; i >= 0 ; i-- ) {
- netdev_nullify ( phantom->netdev[i] );
- netdev_put ( phantom->netdev[i] );
- }
- err_read_flash:
+ phantom_halt_pegs ( phantom );
err_map_crb:
- free ( phantom );
- err_alloc_phantom:
+ netdev_nullify ( netdev );
+ netdev_put ( netdev );
+ err_alloc_etherdev:
return rc;
}
@@ -2371,24 +2072,14 @@ static int phantom_probe ( struct pci_device *pci,
* @v pci PCI device
*/
static void phantom_remove ( struct pci_device *pci ) {
- struct phantom_nic *phantom = pci_get_drvdata ( pci );
- struct phantom_nic_port *phantom_port;
- int i;
+ struct net_device *netdev = pci_get_drvdata ( pci );
+ struct phantom_nic *phantom = netdev_priv ( netdev );
- for ( i = ( phantom->num_ports - 1 ) ; i >= 0 ; i-- ) {
- phantom_port = netdev_priv ( phantom->netdev[i] );
- unregister_settings ( &phantom_port->settings );
- }
- for ( i = ( phantom->num_ports - 1 ) ; i >= 0 ; i-- )
- unregister_netdev ( phantom->netdev[i] );
+ unregister_settings ( &phantom->settings );
+ unregister_netdev ( netdev );
phantom_halt_pegs ( phantom );
- free_dma ( phantom->dma_buf, sizeof ( *(phantom->dma_buf) ) );
- phantom->dma_buf = NULL;
- for ( i = ( phantom->num_ports - 1 ) ; i >= 0 ; i-- ) {
- netdev_nullify ( phantom->netdev[i] );
- netdev_put ( phantom->netdev[i] );
- }
- free ( phantom );
+ netdev_nullify ( netdev );
+ netdev_put ( netdev );
}
/** Phantom PCI IDs */