net/vmxnet3: allow variable length Tx data ring
vmxnet3 driver supports transmit data ring viz. a set of fixed size buffers used by the driver to copy packet headers. Small packets that fit these buffers are copied into these buffers entirely. Currently this buffer size of fixed at 128 bytes. This patch extends transmit data ring implementation to allow variable length transmit data ring buffers. The length of the buffer is read from the emulation during initialization. Signed-off-by: Shrikrishna Khare <skhare@vmware.com> Acked-by: Yong Wang <yongwang@vmware.com> Acked-by: Jin Heo <heoj@vmware.com>
This commit is contained in:
parent
2d1c4b176e
commit
01fef6e3c1
@ -121,7 +121,8 @@ typedef enum {
|
||||
VMXNET3_CMD_GET_DID_HI,
|
||||
VMXNET3_CMD_GET_DEV_EXTRA_INFO,
|
||||
VMXNET3_CMD_GET_CONF_INTR,
|
||||
VMXNET3_CMD_GET_ADAPTIVE_RING_INFO
|
||||
VMXNET3_CMD_GET_ADAPTIVE_RING_INFO,
|
||||
VMXNET3_CMD_GET_TXDATA_DESC_SIZE
|
||||
} Vmxnet3_Cmd;
|
||||
|
||||
/* Adaptive Ring Info Flags */
|
||||
@ -403,12 +404,19 @@ typedef union Vmxnet3_GenericDesc {
|
||||
#define VMXNET3_RING_SIZE_ALIGN 32
|
||||
#define VMXNET3_RING_SIZE_MASK (VMXNET3_RING_SIZE_ALIGN - 1)
|
||||
|
||||
/* Tx Data Ring buffer size must be a multiple of 64 */
|
||||
#define VMXNET3_TXDATA_DESC_SIZE_ALIGN 64
|
||||
#define VMXNET3_TXDATA_DESC_SIZE_MASK (VMXNET3_TXDATA_DESC_SIZE_ALIGN - 1)
|
||||
|
||||
/* Max ring size */
|
||||
#define VMXNET3_TX_RING_MAX_SIZE 4096
|
||||
#define VMXNET3_TC_RING_MAX_SIZE 4096
|
||||
#define VMXNET3_RX_RING_MAX_SIZE 4096
|
||||
#define VMXNET3_RC_RING_MAX_SIZE 8192
|
||||
|
||||
#define VMXNET3_TXDATA_DESC_MIN_SIZE 128
|
||||
#define VMXNET3_TXDATA_DESC_MAX_SIZE 2048
|
||||
|
||||
/* a list of reasons for queue stop */
|
||||
|
||||
#define VMXNET3_ERR_NOEOP 0x80000000 /* cannot find the EOP desc of a pkt */
|
||||
@ -508,7 +516,9 @@ struct Vmxnet3_TxQueueConf {
|
||||
__le32 compRingSize; /* # of comp desc */
|
||||
__le32 ddLen; /* size of driver data */
|
||||
uint8 intrIdx;
|
||||
uint8 _pad[7];
|
||||
uint8 _pad[1];
|
||||
__le16 txDataRingDescSize;
|
||||
uint8 _pad2[4];
|
||||
}
|
||||
#include "vmware_pack_end.h"
|
||||
Vmxnet3_TxQueueConf;
|
||||
|
@ -224,6 +224,24 @@ vmxnet3_disable_intr(struct vmxnet3_hw *hw)
|
||||
VMXNET3_WRITE_BAR0_REG(hw, VMXNET3_REG_IMR + i * 8, 1);
|
||||
}
|
||||
|
||||
/*
|
||||
* Gets tx data ring descriptor size.
|
||||
*/
|
||||
static uint16_t
|
||||
eth_vmxnet3_txdata_get(struct vmxnet3_hw *hw)
|
||||
{
|
||||
uint16 txdata_desc_size;
|
||||
|
||||
VMXNET3_WRITE_BAR1_REG(hw, VMXNET3_REG_CMD,
|
||||
VMXNET3_CMD_GET_TXDATA_DESC_SIZE);
|
||||
txdata_desc_size = VMXNET3_READ_BAR1_REG(hw, VMXNET3_REG_CMD);
|
||||
|
||||
return (txdata_desc_size < VMXNET3_TXDATA_DESC_MIN_SIZE ||
|
||||
txdata_desc_size > VMXNET3_TXDATA_DESC_MAX_SIZE ||
|
||||
txdata_desc_size & VMXNET3_TXDATA_DESC_SIZE_MASK) ?
|
||||
sizeof(struct Vmxnet3_TxDataDesc) : txdata_desc_size;
|
||||
}
|
||||
|
||||
/*
|
||||
* It returns 0 on success.
|
||||
*/
|
||||
@ -320,6 +338,9 @@ eth_vmxnet3_dev_init(struct rte_eth_dev *eth_dev)
|
||||
/* allow untagged pkts */
|
||||
VMXNET3_SET_VFTABLE_ENTRY(hw->shadow_vfta, 0);
|
||||
|
||||
hw->txdata_desc_size = VMXNET3_VERSION_GE_3(hw) ?
|
||||
eth_vmxnet3_txdata_get(hw) : sizeof(struct Vmxnet3_TxDataDesc);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -511,6 +532,7 @@ vmxnet3_setup_driver_shared(struct rte_eth_dev *dev)
|
||||
tqd->conf.txRingSize = txq->cmd_ring.size;
|
||||
tqd->conf.compRingSize = txq->comp_ring.size;
|
||||
tqd->conf.dataRingSize = txq->data_ring.size;
|
||||
tqd->conf.txDataRingDescSize = txq->txdata_desc_size;
|
||||
tqd->conf.intrIdx = txq->comp_ring.intr_idx;
|
||||
tqd->status.stopped = TRUE;
|
||||
tqd->status.error = 0;
|
||||
|
@ -103,6 +103,8 @@ struct vmxnet3_hw {
|
||||
|
||||
uint8_t version;
|
||||
|
||||
uint16_t txdata_desc_size; /* tx data ring buffer size */
|
||||
|
||||
Vmxnet3_TxQueueDesc *tqd_start; /* start address of all tx queue desc */
|
||||
Vmxnet3_RxQueueDesc *rqd_start; /* start address of all rx queue desc */
|
||||
|
||||
|
@ -141,6 +141,7 @@ typedef struct vmxnet3_tx_queue {
|
||||
bool stopped;
|
||||
uint16_t queue_id; /**< Device TX queue index. */
|
||||
uint8_t port_id; /**< Device port identifier. */
|
||||
uint16_t txdata_desc_size;
|
||||
} vmxnet3_tx_queue_t;
|
||||
|
||||
struct vmxnet3_rxq_stats {
|
||||
|
@ -244,7 +244,7 @@ vmxnet3_dev_tx_queue_reset(void *txq)
|
||||
|
||||
size = sizeof(struct Vmxnet3_TxDesc) * ring->size;
|
||||
size += sizeof(struct Vmxnet3_TxCompDesc) * comp_ring->size;
|
||||
size += sizeof(struct Vmxnet3_TxDataDesc) * data_ring->size;
|
||||
size += tq->txdata_desc_size * data_ring->size;
|
||||
|
||||
memset(ring->base, 0, size);
|
||||
}
|
||||
@ -471,10 +471,13 @@ vmxnet3_xmit_pkts(void *tx_queue, struct rte_mbuf **tx_pkts,
|
||||
}
|
||||
|
||||
if (txm->nb_segs == 1 &&
|
||||
rte_pktmbuf_pkt_len(txm) <= VMXNET3_HDR_COPY_SIZE) {
|
||||
rte_pktmbuf_pkt_len(txm) <= txq->txdata_desc_size) {
|
||||
struct Vmxnet3_TxDataDesc *tdd;
|
||||
|
||||
tdd = txq->data_ring.base + txq->cmd_ring.next2fill;
|
||||
tdd = (struct Vmxnet3_TxDataDesc *)
|
||||
((uint8 *)txq->data_ring.base +
|
||||
txq->cmd_ring.next2fill *
|
||||
txq->txdata_desc_size);
|
||||
copy_size = rte_pktmbuf_pkt_len(txm);
|
||||
rte_memcpy(tdd->data, rte_pktmbuf_mtod(txm, char *), copy_size);
|
||||
}
|
||||
@ -491,12 +494,15 @@ vmxnet3_xmit_pkts(void *tx_queue, struct rte_mbuf **tx_pkts,
|
||||
* maximum size of mbuf segment size.
|
||||
*/
|
||||
gdesc = txq->cmd_ring.base + txq->cmd_ring.next2fill;
|
||||
if (copy_size)
|
||||
gdesc->txd.addr = rte_cpu_to_le_64(txq->data_ring.basePA +
|
||||
txq->cmd_ring.next2fill *
|
||||
sizeof(struct Vmxnet3_TxDataDesc));
|
||||
else
|
||||
if (copy_size) {
|
||||
uint64 offset = txq->cmd_ring.next2fill *
|
||||
txq->txdata_desc_size;
|
||||
gdesc->txd.addr =
|
||||
rte_cpu_to_le_64(txq->data_ring.basePA +
|
||||
offset);
|
||||
} else {
|
||||
gdesc->txd.addr = rte_mbuf_data_dma_addr(m_seg);
|
||||
}
|
||||
|
||||
gdesc->dword[2] = dw2 | m_seg->data_len;
|
||||
gdesc->dword[3] = 0;
|
||||
@ -932,6 +938,7 @@ vmxnet3_dev_tx_queue_setup(struct rte_eth_dev *dev,
|
||||
txq->hw = hw;
|
||||
txq->qid = queue_idx;
|
||||
txq->stopped = TRUE;
|
||||
txq->txdata_desc_size = hw->txdata_desc_size;
|
||||
|
||||
ring = &txq->cmd_ring;
|
||||
comp_ring = &txq->comp_ring;
|
||||
@ -961,7 +968,7 @@ vmxnet3_dev_tx_queue_setup(struct rte_eth_dev *dev,
|
||||
|
||||
size = sizeof(struct Vmxnet3_TxDesc) * ring->size;
|
||||
size += sizeof(struct Vmxnet3_TxCompDesc) * comp_ring->size;
|
||||
size += sizeof(struct Vmxnet3_TxDataDesc) * data_ring->size;
|
||||
size += txq->txdata_desc_size * data_ring->size;
|
||||
|
||||
mz = ring_dma_zone_reserve(dev, "txdesc", queue_idx, size, socket_id);
|
||||
if (mz == NULL) {
|
||||
|
Loading…
Reference in New Issue
Block a user