diff options
Diffstat (limited to 'src/drivers/net/intelxl.c')
| -rw-r--r-- | src/drivers/net/intelxl.c | 122 |
1 files changed, 72 insertions, 50 deletions
diff --git a/src/drivers/net/intelxl.c b/src/drivers/net/intelxl.c index c98ba265c..ac9e37c5a 100644 --- a/src/drivers/net/intelxl.c +++ b/src/drivers/net/intelxl.c @@ -34,7 +34,6 @@ FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL ); #include <ipxe/if_ether.h> #include <ipxe/vlan.h> #include <ipxe/iobuf.h> -#include <ipxe/malloc.h> #include <ipxe/pci.h> #include <ipxe/version.h> #include "intelxl.h" @@ -87,15 +86,16 @@ static int intelxl_reset ( struct intelxl_nic *intelxl ) { static int intelxl_fetch_mac ( struct intelxl_nic *intelxl, struct net_device *netdev ) { union intelxl_receive_address mac; - uint32_t prtgl_sal; + uint32_t prtpm_sal; + uint32_t prtpm_sah; uint32_t prtgl_sah; size_t mfs; /* Read NVM-loaded address */ - prtgl_sal = readl ( intelxl->regs + INTELXL_PRTGL_SAL ); - prtgl_sah = readl ( intelxl->regs + INTELXL_PRTGL_SAH ); - mac.reg.low = cpu_to_le32 ( prtgl_sal ); - mac.reg.high = cpu_to_le32 ( prtgl_sah ); + prtpm_sal = readl ( intelxl->regs + INTELXL_PRTPM_SAL ); + prtpm_sah = readl ( intelxl->regs + INTELXL_PRTPM_SAH ); + mac.reg.low = cpu_to_le32 ( prtpm_sal ); + mac.reg.high = cpu_to_le32 ( prtpm_sah ); /* Check that address is valid */ if ( ! is_valid_ether_addr ( mac.raw ) ) { @@ -110,6 +110,7 @@ static int intelxl_fetch_mac ( struct intelxl_nic *intelxl, memcpy ( netdev->hw_addr, mac.raw, ETH_ALEN ); /* Get maximum frame size */ + prtgl_sah = readl ( intelxl->regs + INTELXL_PRTGL_SAH ); mfs = INTELXL_PRTGL_SAH_MFS_GET ( prtgl_sah ); netdev->max_pkt_len = ( mfs - 4 /* CRC */ ); @@ -134,20 +135,36 @@ int intelxl_msix_enable ( struct intelxl_nic *intelxl, struct pci_device *pci ) { int rc; + /* Map dummy target location */ + if ( ( rc = dma_map ( intelxl->dma, &intelxl->msix.map, + virt_to_phys ( &intelxl->msix.msg ), + sizeof ( intelxl->msix.msg ), DMA_RX ) ) != 0 ) { + DBGC ( intelxl, "INTELXL %p could not map MSI-X target: %s\n", + intelxl, strerror ( rc ) ); + goto err_map; + } + /* Enable MSI-X capability */ - if ( ( rc = pci_msix_enable ( pci, &intelxl->msix ) ) != 0 ) { + if ( ( rc = pci_msix_enable ( pci, &intelxl->msix.cap ) ) != 0 ) { DBGC ( intelxl, "INTELXL %p could not enable MSI-X: %s\n", intelxl, strerror ( rc ) ); - return rc; + goto err_enable; } /* Configure interrupt zero to write to dummy location */ - pci_msix_map ( &intelxl->msix, 0, virt_to_bus ( &intelxl->msg ), 0 ); + pci_msix_map ( &intelxl->msix.cap, 0, + dma ( &intelxl->msix.map, &intelxl->msix.msg ), 0 ); /* Enable dummy interrupt zero */ - pci_msix_unmask ( &intelxl->msix, 0 ); + pci_msix_unmask ( &intelxl->msix.cap, 0 ); return 0; + + pci_msix_disable ( pci, &intelxl->msix.cap ); + err_enable: + dma_unmap ( &intelxl->msix.map ); + err_map: + return rc; } /** @@ -160,10 +177,13 @@ void intelxl_msix_disable ( struct intelxl_nic *intelxl, struct pci_device *pci ) { /* Disable dummy interrupt zero */ - pci_msix_mask ( &intelxl->msix, 0 ); + pci_msix_mask ( &intelxl->msix.cap, 0 ); /* Disable MSI-X capability */ - pci_msix_disable ( pci, &intelxl->msix ); + pci_msix_disable ( pci, &intelxl->msix.cap ); + + /* Unmap dummy target location */ + dma_unmap ( &intelxl->msix.map ); } /****************************************************************************** @@ -195,19 +215,19 @@ static int intelxl_alloc_admin ( struct intelxl_nic *intelxl, size_t len = ( sizeof ( admin->desc[0] ) * INTELXL_ADMIN_NUM_DESC ); /* Allocate admin queue */ - admin->buf = malloc_dma ( ( buf_len + len ), INTELXL_ALIGN ); + admin->buf = dma_alloc ( intelxl->dma, &admin->map, ( buf_len + len ), + INTELXL_ALIGN ); if ( ! admin->buf ) return -ENOMEM; admin->desc = ( ( ( void * ) admin->buf ) + buf_len ); - DBGC ( intelxl, "INTELXL %p A%cQ is at [%08llx,%08llx) buf " - "[%08llx,%08llx)\n", intelxl, + DBGC ( intelxl, "INTELXL %p A%cQ is at [%08lx,%08lx) buf " + "[%08lx,%08lx)\n", intelxl, ( ( admin == &intelxl->command ) ? 'T' : 'R' ), - ( ( unsigned long long ) virt_to_bus ( admin->desc ) ), - ( ( unsigned long long ) ( virt_to_bus ( admin->desc ) + len ) ), - ( ( unsigned long long ) virt_to_bus ( admin->buf ) ), - ( ( unsigned long long ) ( virt_to_bus ( admin->buf ) + - buf_len ) ) ); + virt_to_phys ( admin->desc ), + ( virt_to_phys ( admin->desc ) + len ), + virt_to_phys ( admin->buf ), + ( virt_to_phys ( admin->buf ) + buf_len ) ); return 0; } @@ -235,7 +255,7 @@ static void intelxl_enable_admin ( struct intelxl_nic *intelxl, admin->index = 0; /* Program queue address */ - address = virt_to_bus ( admin->desc ); + address = dma ( &admin->map, admin->desc ); writel ( ( address & 0xffffffffUL ), admin_regs + regs->bal ); if ( sizeof ( physaddr_t ) > sizeof ( uint32_t ) ) { writel ( ( ( ( uint64_t ) address ) >> 32 ), @@ -277,7 +297,7 @@ static void intelxl_free_admin ( struct intelxl_nic *intelxl __unused, size_t len = ( sizeof ( admin->desc[0] ) * INTELXL_ADMIN_NUM_DESC ); /* Free queue */ - free_dma ( admin->buf, ( buf_len + len ) ); + dma_free ( &admin->map, admin->buf, ( buf_len + len ) ); } /** @@ -330,7 +350,7 @@ static void intelxl_admin_event_init ( struct intelxl_nic *intelxl, /* Initialise descriptor */ evt = &admin->desc[ index % INTELXL_ADMIN_NUM_DESC ]; buf = &admin->buf[ index % INTELXL_ADMIN_NUM_DESC ]; - address = virt_to_bus ( buf ); + address = dma ( &admin->map, buf ); evt->flags = cpu_to_le16 ( INTELXL_ADMIN_FL_BUF ); evt->len = cpu_to_le16 ( sizeof ( *buf ) ); evt->params.buffer.high = cpu_to_le32 ( address >> 32 ); @@ -375,7 +395,7 @@ int intelxl_admin_command ( struct intelxl_nic *intelxl ) { /* Populate data buffer address if applicable */ if ( cmd->flags & cpu_to_le16 ( INTELXL_ADMIN_FL_BUF ) ) { - address = virt_to_bus ( buf ); + address = dma ( &admin->map, buf ); cmd->params.buffer.high = cpu_to_le32 ( address >> 32 ); cmd->params.buffer.low = cpu_to_le32 ( address & 0xffffffffUL ); } @@ -922,16 +942,15 @@ void intelxl_close_admin ( struct intelxl_nic *intelxl ) { */ int intelxl_alloc_ring ( struct intelxl_nic *intelxl, struct intelxl_ring *ring ) { - physaddr_t address; int rc; /* Allocate descriptor ring */ - ring->desc.raw = malloc_dma ( ring->len, INTELXL_ALIGN ); + ring->desc.raw = dma_alloc ( intelxl->dma, &ring->map, ring->len, + INTELXL_ALIGN ); if ( ! ring->desc.raw ) { rc = -ENOMEM; goto err_alloc; } - address = virt_to_bus ( ring->desc.raw ); /* Initialise descriptor ring */ memset ( ring->desc.raw, 0, ring->len ); @@ -943,14 +962,14 @@ int intelxl_alloc_ring ( struct intelxl_nic *intelxl, ring->prod = 0; ring->cons = 0; - DBGC ( intelxl, "INTELXL %p ring %06x is at [%08llx,%08llx)\n", + DBGC ( intelxl, "INTELXL %p ring %06x is at [%08lx,%08lx)\n", intelxl, ( ring->reg + ring->tail ), - ( ( unsigned long long ) address ), - ( ( unsigned long long ) address + ring->len ) ); + virt_to_phys ( ring->desc.raw ), + ( virt_to_phys ( ring->desc.raw ) + ring->len ) ); return 0; - free_dma ( ring->desc.raw, ring->len ); + dma_free ( &ring->map, ring->desc.raw, ring->len ); err_alloc: return rc; } @@ -965,7 +984,7 @@ void intelxl_free_ring ( struct intelxl_nic *intelxl __unused, struct intelxl_ring *ring ) { /* Free descriptor ring */ - free_dma ( ring->desc.raw, ring->len ); + dma_free ( &ring->map, ring->desc.raw, ring->len ); ring->desc.raw = NULL; } @@ -1241,7 +1260,7 @@ static int intelxl_create_ring ( struct intelxl_nic *intelxl, goto err_alloc; /* Program queue context */ - address = virt_to_bus ( ring->desc.raw ); + address = dma ( &ring->map, ring->desc.raw ); if ( ( rc = ring->context ( intelxl, address ) ) != 0 ) goto err_context; @@ -1289,14 +1308,13 @@ static void intelxl_refill_rx ( struct intelxl_nic *intelxl ) { struct io_buffer *iobuf; unsigned int rx_idx; unsigned int rx_tail; - physaddr_t address; unsigned int refilled = 0; /* Refill ring */ while ( ( intelxl->rx.prod - intelxl->rx.cons ) < INTELXL_RX_FILL ) { /* Allocate I/O buffer */ - iobuf = alloc_iob ( intelxl->mfs ); + iobuf = alloc_rx_iob ( intelxl->mfs, intelxl->dma ); if ( ! iobuf ) { /* Wait for next refill */ break; @@ -1307,17 +1325,16 @@ static void intelxl_refill_rx ( struct intelxl_nic *intelxl ) { rx = &intelxl->rx.desc.rx[rx_idx].data; /* Populate receive descriptor */ - address = virt_to_bus ( iobuf->data ); - rx->address = cpu_to_le64 ( address ); + rx->address = cpu_to_le64 ( iob_dma ( iobuf ) ); rx->flags = 0; /* Record I/O buffer */ assert ( intelxl->rx_iobuf[rx_idx] == NULL ); intelxl->rx_iobuf[rx_idx] = iobuf; - DBGC2 ( intelxl, "INTELXL %p RX %d is [%llx,%llx)\n", intelxl, - rx_idx, ( ( unsigned long long ) address ), - ( ( unsigned long long ) address + intelxl->mfs ) ); + DBGC2 ( intelxl, "INTELXL %p RX %d is [%08lx,%08lx)\n", + intelxl, rx_idx, virt_to_phys ( iobuf->data ), + ( virt_to_phys ( iobuf->data ) + intelxl->mfs ) ); refilled++; } @@ -1340,7 +1357,7 @@ void intelxl_empty_rx ( struct intelxl_nic *intelxl ) { /* Discard any unused receive buffers */ for ( i = 0 ; i < INTELXL_RX_NUM_DESC ; i++ ) { if ( intelxl->rx_iobuf[i] ) - free_iob ( intelxl->rx_iobuf[i] ); + free_rx_iob ( intelxl->rx_iobuf[i] ); intelxl->rx_iobuf[i] = NULL; } } @@ -1467,7 +1484,6 @@ int intelxl_transmit ( struct net_device *netdev, struct io_buffer *iobuf ) { struct intelxl_tx_data_descriptor *tx; unsigned int tx_idx; unsigned int tx_tail; - physaddr_t address; size_t len; /* Get next transmit descriptor */ @@ -1481,9 +1497,8 @@ int intelxl_transmit ( struct net_device *netdev, struct io_buffer *iobuf ) { tx = &intelxl->tx.desc.tx[tx_idx].data; /* Populate transmit descriptor */ - address = virt_to_bus ( iobuf->data ); len = iob_len ( iobuf ); - tx->address = cpu_to_le64 ( address ); + tx->address = cpu_to_le64 ( iob_dma ( iobuf ) ); tx->len = cpu_to_le32 ( INTELXL_TX_DATA_LEN ( len ) ); tx->flags = cpu_to_le32 ( INTELXL_TX_DATA_DTYP | INTELXL_TX_DATA_EOP | INTELXL_TX_DATA_RS | INTELXL_TX_DATA_JFDI ); @@ -1492,9 +1507,9 @@ int intelxl_transmit ( struct net_device *netdev, struct io_buffer *iobuf ) { /* Notify card that there are packets ready to transmit */ writel ( tx_tail, ( intelxl->regs + intelxl->tx.tail ) ); - DBGC2 ( intelxl, "INTELXL %p TX %d is [%llx,%llx)\n", intelxl, tx_idx, - ( ( unsigned long long ) address ), - ( ( unsigned long long ) address + len ) ); + DBGC2 ( intelxl, "INTELXL %p TX %d is [%08lx,%08lx)\n", + intelxl, tx_idx, virt_to_phys ( iobuf->data ), + ( virt_to_phys ( iobuf->data ) + len ) ); return 0; } @@ -1641,6 +1656,7 @@ static struct net_device_operations intelxl_operations = { static int intelxl_probe ( struct pci_device *pci ) { struct net_device *netdev; struct intelxl_nic *intelxl; + uint32_t pffunc_rid; uint32_t pfgen_portnum; uint32_t pflan_qalloc; int rc; @@ -1656,7 +1672,6 @@ static int intelxl_probe ( struct pci_device *pci ) { pci_set_drvdata ( pci, netdev ); netdev->dev = &pci->dev; memset ( intelxl, 0, sizeof ( *intelxl ) ); - intelxl->pf = PCI_FUNC ( pci->busdevfn ); intelxl->intr = INTELXL_PFINT_DYN_CTL0; intelxl_init_admin ( &intelxl->command, INTELXL_ADMIN_CMD, &intelxl_admin_offsets ); @@ -1673,17 +1688,24 @@ static int intelxl_probe ( struct pci_device *pci ) { adjust_pci_device ( pci ); /* Map registers */ - intelxl->regs = ioremap ( pci->membase, INTELXL_BAR_SIZE ); + intelxl->regs = pci_ioremap ( pci, pci->membase, INTELXL_BAR_SIZE ); if ( ! intelxl->regs ) { rc = -ENODEV; goto err_ioremap; } + /* Configure DMA */ + intelxl->dma = &pci->dma; + dma_set_mask_64bit ( intelxl->dma ); + netdev->dma = intelxl->dma; + /* Reset the NIC */ if ( ( rc = intelxl_reset ( intelxl ) ) != 0 ) goto err_reset; - /* Get port number and base queue number */ + /* Get function number, port number and base queue number */ + pffunc_rid = readl ( intelxl->regs + INTELXL_PFFUNC_RID ); + intelxl->pf = INTELXL_PFFUNC_RID_FUNC_NUM ( pffunc_rid ); pfgen_portnum = readl ( intelxl->regs + INTELXL_PFGEN_PORTNUM ); intelxl->port = INTELXL_PFGEN_PORTNUM_PORT_NUM ( pfgen_portnum ); pflan_qalloc = readl ( intelxl->regs + INTELXL_PFLAN_QALLOC ); |
