diff options
-rw-r--r-- | src/drivers/net/intel.c | 92 | ||||
-rw-r--r-- | src/drivers/net/intel.h | 70 | ||||
-rw-r--r-- | src/drivers/net/intelx.c | 6 |
3 files changed, 126 insertions, 42 deletions
diff --git a/src/drivers/net/intel.c b/src/drivers/net/intel.c index 4b0e4c0e..6309e9aa 100644 --- a/src/drivers/net/intel.c +++ b/src/drivers/net/intel.c @@ -349,6 +349,67 @@ static void intel_check_link ( struct net_device *netdev ) { /****************************************************************************** * + * Descriptors + * + ****************************************************************************** + */ + +/** + * Populate transmit descriptor + * + * @v tx Transmit descriptor + * @v addr Data buffer address + * @v len Length of data + */ +void intel_describe_tx ( struct intel_descriptor *tx, physaddr_t addr, + size_t len ) { + + /* Populate transmit descriptor */ + tx->address = cpu_to_le64 ( addr ); + tx->length = cpu_to_le16 ( len ); + tx->flags = 0; + tx->command = ( INTEL_DESC_CMD_RS | INTEL_DESC_CMD_IFCS | + INTEL_DESC_CMD_EOP ); + tx->status = 0; +} + +/** + * Populate advanced transmit descriptor + * + * @v tx Transmit descriptor + * @v addr Data buffer address + * @v len Length of data + */ +void intel_describe_tx_adv ( struct intel_descriptor *tx, physaddr_t addr, + size_t len ) { + + /* Populate advanced transmit descriptor */ + tx->address = cpu_to_le64 ( addr ); + tx->length = cpu_to_le16 ( len ); + tx->flags = INTEL_DESC_FL_DTYP_DATA; + tx->command = ( INTEL_DESC_CMD_DEXT | INTEL_DESC_CMD_RS | + INTEL_DESC_CMD_IFCS | INTEL_DESC_CMD_EOP ); + tx->status = cpu_to_le32 ( INTEL_DESC_STATUS_PAYLEN ( len ) ); +} + +/** + * Populate receive descriptor + * + * @v rx Receive descriptor + * @v addr Data buffer address + * @v len Length of data + */ +void intel_describe_rx ( struct intel_descriptor *rx, physaddr_t addr, + size_t len __unused ) { + + /* Populate transmit descriptor */ + rx->address = cpu_to_le64 ( addr ); + rx->length = 0; + rx->status = 0; +} + +/****************************************************************************** + * * Network device interface * ****************************************************************************** @@ -457,10 +518,7 @@ void intel_refill_rx ( struct intel_nic *intel ) { /* Populate receive descriptor */ address = virt_to_bus ( iobuf->data ); - rx->address = cpu_to_le64 ( address ); - rx->length = 0; - rx->status = 0; - rx->errors = 0; + intel->rx.describe ( rx, address, 0 ); /* Record I/O buffer */ assert ( intel->rx_iobuf[rx_idx] == NULL ); @@ -602,6 +660,7 @@ int intel_transmit ( struct net_device *netdev, struct io_buffer *iobuf ) { unsigned int tx_idx; unsigned int tx_tail; physaddr_t address; + size_t len; /* Get next transmit descriptor */ if ( ( intel->tx.prod - intel->tx.cons ) >= INTEL_TX_FILL ) { @@ -614,11 +673,8 @@ int intel_transmit ( struct net_device *netdev, struct io_buffer *iobuf ) { /* Populate transmit descriptor */ address = virt_to_bus ( iobuf->data ); - tx->address = cpu_to_le64 ( address ); - tx->length = cpu_to_le16 ( iob_len ( iobuf ) ); - tx->command = ( INTEL_DESC_CMD_RS | INTEL_DESC_CMD_IFCS | - INTEL_DESC_CMD_EOP ); - tx->status = 0; + len = iob_len ( iobuf ); + intel->tx.describe ( tx, address, len ); wmb(); /* Notify card that there are packets ready to transmit */ @@ -629,7 +685,7 @@ int intel_transmit ( struct net_device *netdev, struct io_buffer *iobuf ) { DBGC2 ( intel, "INTEL %p TX %d is [%llx,%llx)\n", intel, tx_idx, ( ( unsigned long long ) address ), - ( ( unsigned long long ) address + iob_len ( iobuf ) ) ); + ( ( unsigned long long ) address + len ) ); return 0; } @@ -652,7 +708,7 @@ void intel_poll_tx ( struct net_device *netdev ) { tx = &intel->tx.desc[tx_idx]; /* Stop if descriptor is still in use */ - if ( ! ( tx->status & INTEL_DESC_STATUS_DD ) ) + if ( ! ( tx->status & cpu_to_le32 ( INTEL_DESC_STATUS_DD ) ) ) return; DBGC2 ( intel, "INTEL %p TX %d complete\n", intel, tx_idx ); @@ -683,7 +739,7 @@ void intel_poll_rx ( struct net_device *netdev ) { rx = &intel->rx.desc[rx_idx]; /* Stop if descriptor is still in use */ - if ( ! ( rx->status & INTEL_DESC_STATUS_DD ) ) + if ( ! ( rx->status & cpu_to_le32 ( INTEL_DESC_STATUS_DD ) ) ) return; /* Populate I/O buffer */ @@ -693,10 +749,10 @@ void intel_poll_rx ( struct net_device *netdev ) { iob_put ( iobuf, len ); /* Hand off to network stack */ - if ( rx->errors ) { + if ( rx->status & cpu_to_le32 ( INTEL_DESC_STATUS_RXE ) ) { DBGC ( intel, "INTEL %p RX %d error (length %zd, " - "errors %02x)\n", - intel, rx_idx, len, rx->errors ); + "status %08x)\n", intel, rx_idx, len, + le32_to_cpu ( rx->status ) ); netdev_rx_err ( netdev, iobuf, -EIO ); } else { DBGC2 ( intel, "INTEL %p RX %d complete (length %zd)\n", @@ -811,8 +867,10 @@ static int intel_probe ( struct pci_device *pci ) { memset ( intel, 0, sizeof ( *intel ) ); intel->port = PCI_FUNC ( pci->busdevfn ); intel->flags = pci->id->driver_data; - intel_init_ring ( &intel->tx, INTEL_NUM_TX_DESC, INTEL_TD ); - intel_init_ring ( &intel->rx, INTEL_NUM_RX_DESC, INTEL_RD ); + intel_init_ring ( &intel->tx, INTEL_NUM_TX_DESC, INTEL_TD, + intel_describe_tx ); + intel_init_ring ( &intel->rx, INTEL_NUM_RX_DESC, INTEL_RD, + intel_describe_rx ); /* Fix up PCI device */ adjust_pci_device ( pci ); diff --git a/src/drivers/net/intel.h b/src/drivers/net/intel.h index 621ee2e7..2656cda5 100644 --- a/src/drivers/net/intel.h +++ b/src/drivers/net/intel.h @@ -22,33 +22,38 @@ struct intel_descriptor { uint64_t address; /** Length */ uint16_t length; - /** Reserved */ - uint8_t reserved_a; + /** Flags */ + uint8_t flags; /** Command */ uint8_t command; /** Status */ - uint8_t status; - /** Errors */ - uint8_t errors; - /** Reserved */ - uint16_t reserved_b; + uint32_t status; } __attribute__ (( packed )); -/** Packet descriptor command bits */ -enum intel_descriptor_command { - /** Report status */ - INTEL_DESC_CMD_RS = 0x08, - /** Insert frame checksum (CRC) */ - INTEL_DESC_CMD_IFCS = 0x02, - /** End of packet */ - INTEL_DESC_CMD_EOP = 0x01, -}; +/** Descriptor type */ +#define INTEL_DESC_FL_DTYP( dtyp ) ( (dtyp) << 4 ) +#define INTEL_DESC_FL_DTYP_DATA INTEL_DESC_FL_DTYP ( 0x03 ) -/** Packet descriptor status bits */ -enum intel_descriptor_status { - /** Descriptor done */ - INTEL_DESC_STATUS_DD = 0x01, -}; +/** Descriptor extension */ +#define INTEL_DESC_CMD_DEXT 0x20 + +/** Report status */ +#define INTEL_DESC_CMD_RS 0x08 + +/** Insert frame checksum (CRC) */ +#define INTEL_DESC_CMD_IFCS 0x02 + +/** End of packet */ +#define INTEL_DESC_CMD_EOP 0x01 + +/** Descriptor done */ +#define INTEL_DESC_STATUS_DD 0x00000001UL + +/** Receive error */ +#define INTEL_DESC_STATUS_RXE 0x00000100UL + +/** Payload length */ +#define INTEL_DESC_STATUS_PAYLEN( len ) ( (len) << 14 ) /** Device Control Register */ #define INTEL_CTRL 0x00000UL @@ -209,6 +214,15 @@ struct intel_ring { unsigned int reg; /** Length (in bytes) */ size_t len; + + /** Populate descriptor + * + * @v desc Descriptor + * @v addr Data buffer address + * @v len Length of data + */ + void ( * describe ) ( struct intel_descriptor *desc, physaddr_t addr, + size_t len ); }; /** @@ -217,12 +231,16 @@ struct intel_ring { * @v ring Descriptor ring * @v count Number of descriptors * @v reg Descriptor register block + * @v describe Method to populate descriptor */ static inline __attribute__ (( always_inline)) void -intel_init_ring ( struct intel_ring *ring, unsigned int count, - unsigned int reg ) { +intel_init_ring ( struct intel_ring *ring, unsigned int count, unsigned int reg, + void ( * describe ) ( struct intel_descriptor *desc, + physaddr_t addr, size_t len ) ) { + ring->len = ( count * sizeof ( ring->desc[0] ) ); ring->reg = reg; + ring->describe = describe; } /** An Intel network card */ @@ -278,6 +296,12 @@ static inline void intel_diag ( struct intel_nic *intel ) { readl ( intel->regs + intel->rx.reg + INTEL_xDT ) ); } +extern void intel_describe_tx ( struct intel_descriptor *tx, + physaddr_t addr, size_t len ); +extern void intel_describe_tx_adv ( struct intel_descriptor *tx, + physaddr_t addr, size_t len ); +extern void intel_describe_rx ( struct intel_descriptor *rx, + physaddr_t addr, size_t len ); extern int intel_create_ring ( struct intel_nic *intel, struct intel_ring *ring ); extern void intel_destroy_ring ( struct intel_nic *intel, diff --git a/src/drivers/net/intelx.c b/src/drivers/net/intelx.c index d2bb19b0..982b74f1 100644 --- a/src/drivers/net/intelx.c +++ b/src/drivers/net/intelx.c @@ -396,8 +396,10 @@ static int intelx_probe ( struct pci_device *pci ) { netdev->dev = &pci->dev; memset ( intel, 0, sizeof ( *intel ) ); intel->port = PCI_FUNC ( pci->busdevfn ); - intel_init_ring ( &intel->tx, INTEL_NUM_TX_DESC, INTELX_TD ); - intel_init_ring ( &intel->rx, INTEL_NUM_RX_DESC, INTELX_RD ); + intel_init_ring ( &intel->tx, INTEL_NUM_TX_DESC, INTELX_TD, + intel_describe_tx ); + intel_init_ring ( &intel->rx, INTEL_NUM_RX_DESC, INTELX_RD, + intel_describe_rx ); /* Fix up PCI device */ adjust_pci_device ( pci ); |