( ( vnic->rq.cons % TXNIC_RQES ) * TXNIC_RQ_STRIDE ),
readq ( vnic->regs + TXNIC_QS_RBDR_HEAD(0) ),
readq ( vnic->regs + TXNIC_QS_RBDR_STATUS0(0) ) );
- DBGC ( vnic, "TXNIC %s CQ xxxxx(%05llx)/%05x(%05llx) %08llx:%08llx\n",
+ DBGC ( vnic, "TXNIC %s CQ xxxxx(%05llx)/%05zx(%05llx) %08llx:%08llx\n",
vnic->name, readq ( vnic->regs + TXNIC_QS_CQ_TAIL(0) ),
( ( vnic->cq.cons % TXNIC_CQES ) * TXNIC_CQ_STRIDE ),
readq ( vnic->regs + TXNIC_QS_CQ_HEAD(0) ),
* @ret rc Return status code
*/
static int txnic_send ( struct txnic *vnic, struct io_buffer *iobuf ) {
- struct txnic_sqe sqe;
+ struct txnic_sqe *sqe;
unsigned int sq_idx;
- size_t offset;
size_t len;
/* Get next send queue entry */
return -ENOBUFS;
}
sq_idx = ( vnic->sq.prod++ % TXNIC_SQES );
- offset = ( sq_idx * TXNIC_SQ_STRIDE );
+ sqe = &vnic->sq.sqe[sq_idx];
/* Populate send descriptor */
len = iob_len ( iobuf );
- memset ( &sqe, 0, sizeof ( sqe ) );
- sqe.hdr.total = cpu_to_le32 ( ( len >= ETH_ZLEN ) ? len : ETH_ZLEN );
- sqe.hdr.subdcnt = ( TXNIC_SQE_SUBDESCS - 1 );
- sqe.hdr.flags = TXNIC_SEND_HDR_FLAGS;
- sqe.gather.size = cpu_to_le16 ( len );
- sqe.gather.flags = TXNIC_SEND_GATHER_FLAGS;
- sqe.gather.addr = cpu_to_le64 ( virt_to_bus ( iobuf->data ) );
+ memset ( sqe, 0, sizeof ( *sqe ) );
+ sqe->hdr.total = cpu_to_le32 ( ( len >= ETH_ZLEN ) ? len : ETH_ZLEN );
+ sqe->hdr.subdcnt = ( TXNIC_SQE_SUBDESCS - 1 );
+ sqe->hdr.flags = TXNIC_SEND_HDR_FLAGS;
+ sqe->gather.size = cpu_to_le16 ( len );
+ sqe->gather.flags = TXNIC_SEND_GATHER_FLAGS;
+ sqe->gather.addr = cpu_to_le64 ( virt_to_bus ( iobuf->data ) );
DBGC2 ( vnic, "TXNIC %s SQE %#03x is [%08lx,%08lx)\n",
vnic->name, sq_idx, virt_to_bus ( iobuf->data ),
( virt_to_bus ( iobuf->data ) + len ) );
- /* Copy send descriptor to ring */
- copy_to_user ( vnic->sq.sqe, offset, &sqe, sizeof ( sqe ) );
-
/* Ring doorbell */
wmb();
writeq ( TXNIC_SQE_SUBDESCS, ( vnic->regs + TXNIC_QS_SQ_DOOR(0) ) );
*/
static void txnic_refill_rq ( struct txnic *vnic ) {
struct io_buffer *iobuf;
- struct txnic_rqe rqe;
+ struct txnic_rqe *rqe;
unsigned int rq_idx;
unsigned int rq_iobuf_idx;
unsigned int refilled = 0;
- size_t offset;
/* Refill ring */
while ( ( vnic->rq.prod - vnic->rq.cons ) < TXNIC_RQ_FILL ) {
/* Get next receive descriptor */
rq_idx = ( vnic->rq.prod++ % TXNIC_RQES );
- offset = ( rq_idx * TXNIC_RQ_STRIDE );
+ rqe = &vnic->rq.rqe[rq_idx];
/* Populate receive descriptor */
- rqe.rbdre.addr = cpu_to_le64 ( virt_to_bus ( iobuf->data ) );
+ rqe->rbdre.addr = cpu_to_le64 ( virt_to_bus ( iobuf->data ) );
DBGC2 ( vnic, "TXNIC %s RQE %#03x is [%08lx,%08lx)\n",
vnic->name, rq_idx, virt_to_bus ( iobuf->data ),
( virt_to_bus ( iobuf->data ) + TXNIC_RQE_SIZE ) );
- /* Copy receive descriptor to ring */
- copy_to_user ( vnic->rq.rqe, offset, &rqe, sizeof ( rqe ) );
+ /* Record number of refills for doorbell */
refilled++;
/* Record I/O buffer */
* @v vnic Virtual NIC
*/
static void txnic_poll_cq ( struct txnic *vnic ) {
- union txnic_cqe cqe;
+ union txnic_cqe *cqe;
uint64_t status;
- size_t offset;
unsigned int qcount;
unsigned int cq_idx;
unsigned int i;
/* Get completion queue entry */
cq_idx = ( vnic->cq.cons++ % TXNIC_CQES );
- offset = ( cq_idx * TXNIC_CQ_STRIDE );
- copy_from_user ( &cqe, vnic->cq.cqe, offset, sizeof ( cqe ) );
+ cqe = &vnic->cq.cqe[cq_idx];
/* Process completion queue entry */
- switch ( cqe.common.cqe_type ) {
+ switch ( cqe->common.cqe_type ) {
case TXNIC_CQE_TYPE_SEND:
- txnic_complete_sqe ( vnic, &cqe.send );
+ txnic_complete_sqe ( vnic, &cqe->send );
break;
case TXNIC_CQE_TYPE_RX:
- txnic_complete_rqe ( vnic, &cqe.rx );
+ txnic_complete_rqe ( vnic, &cqe->rx );
break;
default:
DBGC ( vnic, "TXNIC %s unknown completion type %d\n",
- vnic->name, cqe.common.cqe_type );
- DBGC_HDA ( vnic,
- ( virt_to_phys ( vnic->cq.cqe ) + offset ),
- &cqe, sizeof ( cqe ) );
+ vnic->name, cqe->common.cqe_type );
+ DBGC_HDA ( vnic, virt_to_phys ( cqe ), cqe,
+ sizeof ( *cqe ) );
break;
}
}
#include <stdint.h>
#include <ipxe/list.h>
#include <ipxe/netdevice.h>
-#include <ipxe/uaccess.h>
/******************************************************************************
*
/** Consumer counter */
unsigned int cons;
/** Send queue entries */
- userptr_t sqe;
+ struct txnic_sqe *sqe;
};
/******************************************************************************
/** Consumer counter */
unsigned int cons;
/** Receive queue entries */
- userptr_t rqe;
+ struct txnic_rqe *rqe;
/** I/O buffers */
struct io_buffer *iobuf[TXNIC_RQ_FILL];
};
struct txnic_cqe_send send;
/** Receive completion */
struct txnic_cqe_rx rx;
+ /** Padding */
+ uint8_t pad[512];
};
/** Number of completion queue entries
#define TXNIC_CQ_ALIGN 512
/** Completion queue stride */
-#define TXNIC_CQ_STRIDE 512
+#define TXNIC_CQ_STRIDE sizeof ( union txnic_cqe )
/** Completion queue size */
#define TXNIC_CQ_SIZE ( TXNIC_CQES * TXNIC_CQ_STRIDE )
/** Consumer counter */
unsigned int cons;
/** Completion queue entries */
- userptr_t cqe;
+ union txnic_cqe *cqe;
};
/******************************************************************************