aboutsummaryrefslogtreecommitdiffstats
path: root/src/plugins/dev_octeon
diff options
context:
space:
mode:
Diffstat (limited to 'src/plugins/dev_octeon')
-rw-r--r--src/plugins/dev_octeon/init.c25
-rw-r--r--src/plugins/dev_octeon/octeon.h19
-rw-r--r--src/plugins/dev_octeon/port.c89
-rw-r--r--src/plugins/dev_octeon/queue.c14
-rw-r--r--src/plugins/dev_octeon/rx_node.c14
-rw-r--r--src/plugins/dev_octeon/tx_node.c122
6 files changed, 218 insertions, 65 deletions
diff --git a/src/plugins/dev_octeon/init.c b/src/plugins/dev_octeon/init.c
index 47be8a8f9a4..97a11e0d0d7 100644
--- a/src/plugins/dev_octeon/init.c
+++ b/src/plugins/dev_octeon/init.c
@@ -51,7 +51,9 @@ static struct
}
_ (0xa063, RVU_PF, "Marvell Octeon Resource Virtualization Unit PF"),
- _ (0xa0f8, RVU_VF, "Marvell Octeon Resource Virtualization Unit VF"),
+ _ (0xa064, RVU_VF, "Marvell Octeon Resource Virtualization Unit VF"),
+ _ (0xa0f8, LBK_VF, "Marvell Octeon Loopback Unit VF"),
+ _ (0xa0f7, SDP_VF, "Marvell Octeon System DPI Packet Interface Unit VF"),
_ (0xa0f3, CPT_VF, "Marvell Octeon Cryptographic Accelerator Unit VF"),
#undef _
};
@@ -113,7 +115,7 @@ oct_init_nix (vlib_main_t *vm, vnet_dev_t *dev)
if ((rrv = roc_nix_dev_init (cd->nix)))
return cnx_return_roc_err (dev, rrv, "roc_nix_dev_init");
- if (roc_nix_npc_mac_addr_get (cd->nix, mac_addr))
+ if ((rrv = roc_nix_npc_mac_addr_get (cd->nix, mac_addr)))
return cnx_return_roc_err (dev, rrv, "roc_nix_npc_mac_addr_get");
vnet_dev_port_add_args_t port_add_args = {
@@ -239,12 +241,19 @@ oct_init (vlib_main_t *vm, vnet_dev_t *dev)
strncpy ((char *) cd->plt_pci_dev.name, dev->device_id,
sizeof (cd->plt_pci_dev.name) - 1);
- if (cd->type == OCT_DEVICE_TYPE_RVU_PF || cd->type == OCT_DEVICE_TYPE_RVU_VF)
- return oct_init_nix (vm, dev);
- else if (cd->type == OCT_DEVICE_TYPE_CPT_VF)
- return oct_init_cpt (vm, dev);
- else
- return VNET_DEV_ERR_UNSUPPORTED_DEVICE;
+ switch (cd->type)
+ {
+ case OCT_DEVICE_TYPE_RVU_PF:
+ case OCT_DEVICE_TYPE_RVU_VF:
+ case OCT_DEVICE_TYPE_SDP_VF:
+ return oct_init_nix (vm, dev);
+
+ case OCT_DEVICE_TYPE_CPT_VF:
+ return oct_init_cpt (vm, dev);
+
+ default:
+ return VNET_DEV_ERR_UNSUPPORTED_DEVICE;
+ }
return 0;
}
diff --git a/src/plugins/dev_octeon/octeon.h b/src/plugins/dev_octeon/octeon.h
index fd8a92c7b3d..e43cde0a35f 100644
--- a/src/plugins/dev_octeon/octeon.h
+++ b/src/plugins/dev_octeon/octeon.h
@@ -15,11 +15,15 @@
#include <base/roc_api.h>
#include <dev_octeon/hw_defs.h>
+#define OCT_BATCH_ALLOC_IOVA0_MASK 0xFFFFFFFFFFFFFF80
+
typedef enum
{
OCT_DEVICE_TYPE_UNKNOWN = 0,
OCT_DEVICE_TYPE_RVU_PF,
OCT_DEVICE_TYPE_RVU_VF,
+ OCT_DEVICE_TYPE_LBK_VF,
+ OCT_DEVICE_TYPE_SDP_VF,
OCT_DEVICE_TYPE_CPT_VF,
} __clib_packed oct_device_type_t;
@@ -72,13 +76,15 @@ typedef struct
typedef struct
{
CLIB_ALIGN_MARK (cl, 128);
- union
- {
- struct npa_batch_alloc_status_s status;
- u64 iova[16];
- };
+ u64 iova[16];
} oct_npa_batch_alloc_cl128_t;
+typedef union
+{
+ struct npa_batch_alloc_status_s status;
+ u64 as_u64;
+} oct_npa_batch_alloc_status_t;
+
STATIC_ASSERT_SIZEOF (oct_npa_batch_alloc_cl128_t, 128);
typedef struct
@@ -157,7 +163,8 @@ vnet_dev_rv_t oct_flow_query (vlib_main_t *, vnet_dev_port_t *, u32, uword,
_ (AURA_BATCH_ALLOC_ISSUE_FAIL, aura_batch_alloc_issue_fail, ERROR, \
"aura batch alloc issue failed") \
_ (AURA_BATCH_ALLOC_NOT_READY, aura_batch_alloc_not_ready, ERROR, \
- "aura batch alloc not ready")
+ "aura batch alloc not ready") \
+ _ (MTU_EXCEEDED, mtu_exceeded, ERROR, "mtu exceeded")
typedef enum
{
diff --git a/src/plugins/dev_octeon/port.c b/src/plugins/dev_octeon/port.c
index 00ad8b9c477..98a4c28b37d 100644
--- a/src/plugins/dev_octeon/port.c
+++ b/src/plugins/dev_octeon/port.c
@@ -284,8 +284,11 @@ oct_txq_stop (vlib_main_t *vm, vnet_dev_tx_queue_t *txq)
for (n = ctq->ba_num_cl, cl = ctq->ba_buffer + ctq->ba_first_cl; n;
cl++, n--)
{
- if (cl->status.ccode != 0)
- for (u32 i = 0; i < cl->status.count; i++)
+ oct_npa_batch_alloc_status_t st;
+
+ st.as_u64 = __atomic_load_n (cl->iova, __ATOMIC_ACQUIRE);
+ if (st.status.ccode != ALLOC_CCODE_INVAL)
+ for (u32 i = 0; i < st.status.count; i++)
{
vlib_buffer_t *b = (vlib_buffer_t *) (cl->iova[i] + off);
vlib_buffer_free_one (vm, vlib_get_buffer_index (vm, b));
@@ -376,6 +379,82 @@ oct_port_stop (vlib_main_t *vm, vnet_dev_port_t *port)
}
vnet_dev_rv_t
+oct_validate_config_promisc_mode (vnet_dev_port_t *port, int enable)
+{
+ vnet_dev_t *dev = port->dev;
+ oct_device_t *cd = vnet_dev_get_data (dev);
+ struct roc_nix *nix = cd->nix;
+
+ if (roc_nix_is_vf_or_sdp (nix))
+ return VNET_DEV_ERR_UNSUPPORTED_DEVICE;
+
+ return VNET_DEV_OK;
+}
+
+vnet_dev_rv_t
+oct_op_config_promisc_mode (vlib_main_t *vm, vnet_dev_port_t *port, int enable)
+{
+ vnet_dev_t *dev = port->dev;
+ oct_device_t *cd = vnet_dev_get_data (dev);
+ struct roc_nix *nix = cd->nix;
+ int rv;
+
+ rv = roc_nix_npc_promisc_ena_dis (nix, enable);
+ if (rv)
+ {
+ return oct_roc_err (dev, rv, "roc_nix_npc_promisc_ena_dis failed");
+ }
+
+ rv = roc_nix_mac_promisc_mode_enable (nix, enable);
+ if (rv)
+ {
+ return oct_roc_err (dev, rv,
+ "roc_nix_mac_promisc_mode_enable(%s) failed",
+ enable ? "true" : "false");
+ }
+
+ return VNET_DEV_OK;
+}
+
+static vnet_dev_rv_t
+oct_port_add_del_eth_addr (vlib_main_t *vm, vnet_dev_port_t *port,
+ vnet_dev_hw_addr_t *addr, int is_add,
+ int is_primary)
+{
+ vnet_dev_t *dev = port->dev;
+ oct_device_t *cd = vnet_dev_get_data (dev);
+ struct roc_nix *nix = cd->nix;
+ vnet_dev_rv_t rv = VNET_DEV_OK;
+
+ i32 rrv;
+
+ if (is_primary)
+ {
+ if (is_add)
+ {
+ /* Update mac address at NPC */
+ rrv = roc_nix_npc_mac_addr_set (nix, (u8 *) addr);
+ if (rrv)
+ rv = oct_roc_err (dev, rrv, "roc_nix_npc_mac_addr_set() failed");
+
+ /* Update mac address at CGX for PFs only */
+ if (!roc_nix_is_vf_or_sdp (nix))
+ {
+ rrv = roc_nix_mac_addr_set (nix, (u8 *) addr);
+ if (rrv)
+ {
+ /* Rollback to previous mac address */
+ roc_nix_npc_mac_addr_set (nix,
+ (u8 *) &port->primary_hw_addr);
+ rv = oct_roc_err (dev, rrv, "roc_nix_mac_addr_set() failed");
+ }
+ }
+ }
+ }
+ return rv;
+}
+
+vnet_dev_rv_t
oct_port_cfg_change_validate (vlib_main_t *vm, vnet_dev_port_t *port,
vnet_dev_port_cfg_change_req_t *req)
{
@@ -389,6 +468,8 @@ oct_port_cfg_change_validate (vlib_main_t *vm, vnet_dev_port_t *port,
break;
case VNET_DEV_PORT_CFG_PROMISC_MODE:
+ rv = oct_validate_config_promisc_mode (port, req->promisc);
+ break;
case VNET_DEV_PORT_CFG_CHANGE_PRIMARY_HW_ADDR:
case VNET_DEV_PORT_CFG_ADD_SECONDARY_HW_ADDR:
case VNET_DEV_PORT_CFG_REMOVE_SECONDARY_HW_ADDR:
@@ -418,9 +499,13 @@ oct_port_cfg_change (vlib_main_t *vm, vnet_dev_port_t *port,
switch (req->type)
{
case VNET_DEV_PORT_CFG_PROMISC_MODE:
+ rv = oct_op_config_promisc_mode (vm, port, req->promisc);
break;
case VNET_DEV_PORT_CFG_CHANGE_PRIMARY_HW_ADDR:
+ rv = oct_port_add_del_eth_addr (vm, port, &req->addr,
+ /* is_add */ 1,
+ /* is_primary */ 1);
break;
case VNET_DEV_PORT_CFG_ADD_SECONDARY_HW_ADDR:
diff --git a/src/plugins/dev_octeon/queue.c b/src/plugins/dev_octeon/queue.c
index 9378fc3b7c7..d6ae794fb8d 100644
--- a/src/plugins/dev_octeon/queue.c
+++ b/src/plugins/dev_octeon/queue.c
@@ -57,12 +57,20 @@ oct_tx_queue_alloc (vlib_main_t *vm, vnet_dev_tx_queue_t *txq)
oct_txq_t *ctq = vnet_dev_get_tx_queue_data (txq);
vnet_dev_port_t *port = txq->port;
vnet_dev_t *dev = port->dev;
+ u32 sz = sizeof (void *) * ROC_CN10K_NPA_BATCH_ALLOC_MAX_PTRS;
+ vnet_dev_rv_t rv;
log_debug (dev, "tx_queue_alloc: queue %u alocated", txq->queue_id);
- return vnet_dev_dma_mem_alloc (
- vm, dev, sizeof (void *) * ROC_CN10K_NPA_BATCH_ALLOC_MAX_PTRS, 128,
- (void **) &ctq->ba_buffer);
+ rv = vnet_dev_dma_mem_alloc (vm, dev, sz, 128, (void **) &ctq->ba_buffer);
+
+ if (rv != VNET_DEV_OK)
+ return rv;
+
+ clib_memset_u64 (ctq->ba_buffer, OCT_BATCH_ALLOC_IOVA0_MASK,
+ ROC_CN10K_NPA_BATCH_ALLOC_MAX_PTRS);
+
+ return rv;
}
void
diff --git a/src/plugins/dev_octeon/rx_node.c b/src/plugins/dev_octeon/rx_node.c
index 5f7e5a8469b..997f1356199 100644
--- a/src/plugins/dev_octeon/rx_node.c
+++ b/src/plugins/dev_octeon/rx_node.c
@@ -217,7 +217,8 @@ oct_rxq_refill (vlib_main_t *vm, vnet_dev_rx_queue_t *rxq, u16 n_refill)
while (n_lines >= batch_max_lines)
{
- n_alloc = vlib_buffer_alloc (vm, buffer_indices, batch_max_bufs);
+ n_alloc =
+ vlib_buffer_alloc_from_pool (vm, buffer_indices, batch_max_bufs, bpi);
if (PREDICT_FALSE (n_alloc < batch_max_bufs))
goto alloc_fail;
oct_rxq_refill_batch (vm, lmt_id, addr, lines, buffer_indices, w0,
@@ -313,7 +314,7 @@ oct_rx_node_inline (vlib_main_t *vm, vlib_node_runtime_t *node,
n_desc = (status.tail - head) & cq_mask;
if (n_desc == 0)
- return 0;
+ goto refill;
vlib_get_new_next_frame (vm, node, ctx->next_index, ctx->to_next,
ctx->n_left_to_next);
@@ -365,14 +366,15 @@ oct_rx_node_inline (vlib_main_t *vm, vlib_node_runtime_t *node,
vlib_put_next_frame (vm, node, ctx->next_index, ctx->n_left_to_next);
- n_enq = crq->n_enq - ctx->n_segs;
- n_enq += oct_rxq_refill (vm, rxq, rxq->size - n_enq);
- crq->n_enq = n_enq;
-
vlib_increment_combined_counter (
vnm->interface_main.combined_sw_if_counters + VNET_INTERFACE_COUNTER_RX,
thr_idx, ctx->hw_if_index, ctx->n_rx_pkts, ctx->n_rx_bytes);
+refill:
+ n_enq = crq->n_enq - ctx->n_segs;
+ n_enq += oct_rxq_refill (vm, rxq, rxq->size - n_enq);
+ crq->n_enq = n_enq;
+
return ctx->n_rx_pkts;
}
diff --git a/src/plugins/dev_octeon/tx_node.c b/src/plugins/dev_octeon/tx_node.c
index 5deaa82a0c1..a2e4b07de8a 100644
--- a/src/plugins/dev_octeon/tx_node.c
+++ b/src/plugins/dev_octeon/tx_node.c
@@ -22,8 +22,11 @@ typedef struct
u32 n_tx_bytes;
u32 n_drop;
vlib_buffer_t *drop[VLIB_FRAME_SIZE];
+ u32 n_exd_mtu;
+ vlib_buffer_t *exd_mtu[VLIB_FRAME_SIZE];
u32 batch_alloc_not_ready;
u32 batch_alloc_issue_fail;
+ int max_pkt_len;
u16 lmt_id;
u64 lmt_ioaddr;
lmt_line_t *lmt_lines;
@@ -46,9 +49,12 @@ oct_batch_free (vlib_main_t *vm, oct_tx_ctx_t *ctx, vnet_dev_tx_queue_t *txq)
for (cl = ctq->ba_buffer + ctq->ba_first_cl; num_cl > 0; num_cl--, cl++)
{
- u8 count;
- if (cl->status.ccode == ALLOC_CCODE_INVAL)
+ oct_npa_batch_alloc_status_t st;
+
+ if ((st.as_u64 = __atomic_load_n (cl->iova, __ATOMIC_RELAXED)) ==
+ OCT_BATCH_ALLOC_IOVA0_MASK + ALLOC_CCODE_INVAL)
{
+ cl_not_ready:
ctx->batch_alloc_not_ready++;
n_freed = bi - (u32 *) ctq->ba_buffer;
if (n_freed > 0)
@@ -63,11 +69,15 @@ oct_batch_free (vlib_main_t *vm, oct_tx_ctx_t *ctx, vnet_dev_tx_queue_t *txq)
return 0;
}
- count = cl->status.count;
+ if (st.status.count > 8 &&
+ __atomic_load_n (cl->iova + 8, __ATOMIC_RELAXED) ==
+ OCT_BATCH_ALLOC_IOVA0_MASK)
+ goto cl_not_ready;
+
#if (CLIB_DEBUG > 0)
- cl->status.count = cl->status.ccode = 0;
+ cl->iova[0] &= OCT_BATCH_ALLOC_IOVA0_MASK;
#endif
- if (PREDICT_TRUE (count == 16))
+ if (PREDICT_TRUE (st.status.count == 16))
{
/* optimize for likely case where cacheline is full */
vlib_get_buffer_indices_with_offset (vm, (void **) cl, bi, 16,
@@ -76,9 +86,9 @@ oct_batch_free (vlib_main_t *vm, oct_tx_ctx_t *ctx, vnet_dev_tx_queue_t *txq)
}
else
{
- vlib_get_buffer_indices_with_offset (vm, (void **) cl, bi, count,
- off);
- bi += count;
+ vlib_get_buffer_indices_with_offset (vm, (void **) cl, bi,
+ st.status.count, off);
+ bi += st.status.count;
}
}
@@ -89,7 +99,8 @@ oct_batch_free (vlib_main_t *vm, oct_tx_ctx_t *ctx, vnet_dev_tx_queue_t *txq)
/* clear status bits in each cacheline */
n = cl - ctq->ba_buffer;
for (u32 i = 0; i < n; i++)
- ctq->ba_buffer[i].iova[0] = 0;
+ ctq->ba_buffer[i].iova[0] = ctq->ba_buffer[i].iova[8] =
+ OCT_BATCH_ALLOC_IOVA0_MASK;
ctq->ba_num_cl = ctq->ba_first_cl = 0;
}
@@ -125,7 +136,8 @@ oct_batch_free (vlib_main_t *vm, oct_tx_ctx_t *ctx, vnet_dev_tx_queue_t *txq)
static_always_inline u8
oct_tx_enq1 (vlib_main_t *vm, oct_tx_ctx_t *ctx, vlib_buffer_t *b,
- lmt_line_t *line, u32 flags, int simple, int trace)
+ lmt_line_t *line, u32 flags, int simple, int trace, u32 *n,
+ u8 *dpl)
{
u8 n_dwords = 2;
u32 total_len = 0;
@@ -140,6 +152,12 @@ oct_tx_enq1 (vlib_main_t *vm, oct_tx_ctx_t *ctx, vlib_buffer_t *b,
},
};
+ if (PREDICT_FALSE (vlib_buffer_length_in_chain (vm, b) > ctx->max_pkt_len))
+ {
+ ctx->exd_mtu[ctx->n_exd_mtu++] = b;
+ return 0;
+ }
+
if (!simple && flags & VLIB_BUFFER_NEXT_PRESENT)
{
u8 n_tail_segs = 0;
@@ -151,7 +169,7 @@ oct_tx_enq1 (vlib_main_t *vm, oct_tx_ctx_t *ctx, vlib_buffer_t *b,
tail_segs[n_tail_segs++] = t;
if (n_tail_segs > 5)
{
- ctx->drop[ctx->n_drop++] = t;
+ ctx->drop[ctx->n_drop++] = b;
return 0;
}
}
@@ -223,6 +241,9 @@ oct_tx_enq1 (vlib_main_t *vm, oct_tx_ctx_t *ctx, vlib_buffer_t *b,
for (u32 i = 0; i < n_dwords; i++)
line->dwords[i] = d.as_u128[i];
+ *dpl = n_dwords;
+ *n = *n + 1;
+
return n_dwords;
}
@@ -232,7 +253,7 @@ oct_tx_enq16 (vlib_main_t *vm, oct_tx_ctx_t *ctx, vnet_dev_tx_queue_t *txq,
{
u8 dwords_per_line[16], *dpl = dwords_per_line;
u64 lmt_arg, ioaddr, n_lines;
- u32 n_left, or_flags_16 = 0;
+ u32 n_left, or_flags_16 = 0, n = 0;
const u32 not_simple_flags =
VLIB_BUFFER_NEXT_PRESENT | VNET_BUFFER_F_OFFLOAD;
lmt_line_t *l = ctx->lmt_lines;
@@ -240,7 +261,7 @@ oct_tx_enq16 (vlib_main_t *vm, oct_tx_ctx_t *ctx, vnet_dev_tx_queue_t *txq,
/* Data Store Memory Barrier - outer shareable domain */
asm volatile("dmb oshst" ::: "memory");
- for (n_left = n_pkts; n_left >= 8; n_left -= 8, b += 8, l += 8)
+ for (n_left = n_pkts; n_left >= 8; n_left -= 8, b += 8)
{
u32 f0, f1, f2, f3, f4, f5, f6, f7, or_f = 0;
vlib_prefetch_buffer_header (b[8], LOAD);
@@ -261,48 +282,54 @@ oct_tx_enq16 (vlib_main_t *vm, oct_tx_ctx_t *ctx, vnet_dev_tx_queue_t *txq,
if ((or_f & not_simple_flags) == 0)
{
int simple = 1;
- oct_tx_enq1 (vm, ctx, b[0], l, f0, simple, trace);
- oct_tx_enq1 (vm, ctx, b[1], l + 1, f1, simple, trace);
+ oct_tx_enq1 (vm, ctx, b[0], l, f0, simple, trace, &n, &dpl[n]);
+ oct_tx_enq1 (vm, ctx, b[1], l + n, f1, simple, trace, &n, &dpl[n]);
vlib_prefetch_buffer_header (b[13], LOAD);
- oct_tx_enq1 (vm, ctx, b[2], l + 2, f2, simple, trace);
- oct_tx_enq1 (vm, ctx, b[3], l + 3, f3, simple, trace);
+ oct_tx_enq1 (vm, ctx, b[2], l + n, f2, simple, trace, &n, &dpl[n]);
+ oct_tx_enq1 (vm, ctx, b[3], l + n, f3, simple, trace, &n, &dpl[n]);
vlib_prefetch_buffer_header (b[14], LOAD);
- oct_tx_enq1 (vm, ctx, b[4], l + 4, f4, simple, trace);
- oct_tx_enq1 (vm, ctx, b[5], l + 5, f5, simple, trace);
+ oct_tx_enq1 (vm, ctx, b[4], l + n, f4, simple, trace, &n, &dpl[n]);
+ oct_tx_enq1 (vm, ctx, b[5], l + n, f5, simple, trace, &n, &dpl[n]);
vlib_prefetch_buffer_header (b[15], LOAD);
- oct_tx_enq1 (vm, ctx, b[6], l + 6, f6, simple, trace);
- oct_tx_enq1 (vm, ctx, b[7], l + 7, f7, simple, trace);
- dpl[0] = dpl[1] = dpl[2] = dpl[3] = 2;
- dpl[4] = dpl[5] = dpl[6] = dpl[7] = 2;
+ oct_tx_enq1 (vm, ctx, b[6], l + n, f6, simple, trace, &n, &dpl[n]);
+ oct_tx_enq1 (vm, ctx, b[7], l + n, f7, simple, trace, &n, &dpl[n]);
}
else
{
int simple = 0;
- dpl[0] = oct_tx_enq1 (vm, ctx, b[0], l, f0, simple, trace);
- dpl[1] = oct_tx_enq1 (vm, ctx, b[1], l + 1, f1, simple, trace);
+ oct_tx_enq1 (vm, ctx, b[0], l, f0, simple, trace, &n, &dpl[n]);
+ oct_tx_enq1 (vm, ctx, b[1], l + n, f1, simple, trace, &n, &dpl[n]);
vlib_prefetch_buffer_header (b[13], LOAD);
- dpl[2] = oct_tx_enq1 (vm, ctx, b[2], l + 2, f2, simple, trace);
- dpl[3] = oct_tx_enq1 (vm, ctx, b[3], l + 3, f3, simple, trace);
+ oct_tx_enq1 (vm, ctx, b[2], l + n, f2, simple, trace, &n, &dpl[n]);
+ oct_tx_enq1 (vm, ctx, b[3], l + n, f3, simple, trace, &n, &dpl[n]);
vlib_prefetch_buffer_header (b[14], LOAD);
- dpl[4] = oct_tx_enq1 (vm, ctx, b[4], l + 4, f4, simple, trace);
- dpl[5] = oct_tx_enq1 (vm, ctx, b[5], l + 5, f5, simple, trace);
+ oct_tx_enq1 (vm, ctx, b[4], l + n, f4, simple, trace, &n, &dpl[n]);
+ oct_tx_enq1 (vm, ctx, b[5], l + n, f5, simple, trace, &n, &dpl[n]);
vlib_prefetch_buffer_header (b[15], LOAD);
- dpl[6] = oct_tx_enq1 (vm, ctx, b[6], l + 6, f6, simple, trace);
- dpl[7] = oct_tx_enq1 (vm, ctx, b[7], l + 7, f7, simple, trace);
+ oct_tx_enq1 (vm, ctx, b[6], l + n, f6, simple, trace, &n, &dpl[n]);
+ oct_tx_enq1 (vm, ctx, b[7], l + n, f7, simple, trace, &n, &dpl[n]);
}
- dpl += 8;
+ dpl += n;
+ l += n;
+ n = 0;
}
- for (; n_left > 0; n_left -= 1, b += 1, l += 1)
+ for (; n_left > 0; n_left -= 1, b += 1)
{
u32 f0 = b[0]->flags;
- dpl++[0] = oct_tx_enq1 (vm, ctx, b[0], l, f0, 0, trace);
+ oct_tx_enq1 (vm, ctx, b[0], l, f0, 0, trace, &n, &dpl[n]);
or_flags_16 |= f0;
+ dpl += n;
+ l += n;
+ n = 0;
}
lmt_arg = ctx->lmt_id;
ioaddr = ctx->lmt_ioaddr;
- n_lines = n_pkts;
+ n_lines = dpl - dwords_per_line;
+
+ if (PREDICT_FALSE (!n_lines))
+ return n_pkts;
if (PREDICT_FALSE (or_flags_16 & VLIB_BUFFER_NEXT_PRESENT))
{
@@ -342,6 +369,8 @@ VNET_DEV_NODE_FN (oct_tx_node)
vnet_dev_tx_node_runtime_t *rt = vnet_dev_get_tx_node_runtime (node);
vnet_dev_tx_queue_t *txq = rt->tx_queue;
oct_txq_t *ctq = vnet_dev_get_tx_queue_data (txq);
+ vnet_dev_t *dev = txq->port->dev;
+ oct_device_t *cd = vnet_dev_get_data (dev);
u32 node_index = node->node_index;
u32 *from = vlib_frame_vector_args (frame);
u32 n, n_enq, n_left, n_pkts = frame->n_vectors;
@@ -355,6 +384,7 @@ VNET_DEV_NODE_FN (oct_tx_node)
.sq = ctq->sq.qid,
.sizem1 = 1,
},
+ .max_pkt_len = roc_nix_max_pkt_len (cd->nix),
.lmt_id = lmt_id,
.lmt_ioaddr = ctq->io_addr,
.lmt_lines = ctq->lmt_addr + (lmt_id << ROC_LMT_LINE_SIZE_LOG2),
@@ -388,21 +418,25 @@ VNET_DEV_NODE_FN (oct_tx_node)
n += oct_tx_enq16 (vm, &ctx, txq, b, n_left, /* trace */ 0);
}
- ctq->n_enq = n_enq + n;
+ ctq->n_enq = n_enq + n - ctx.n_drop - ctx.n_exd_mtu;
if (n < n_pkts)
{
- n = n_pkts - n;
- vlib_buffer_free (vm, from + n, n);
+ u32 n_free = n_pkts - n;
+ vlib_buffer_free (vm, from + n, n_free);
vlib_error_count (vm, node->node_index, OCT_TX_NODE_CTR_NO_FREE_SLOTS,
- n);
- n_pkts -= ctx.n_drop;
+ n_free);
+ n_pkts -= n_free;
}
if (ctx.n_drop)
vlib_error_count (vm, node->node_index, OCT_TX_NODE_CTR_CHAIN_TOO_LONG,
ctx.n_drop);
+ if (PREDICT_FALSE (ctx.n_exd_mtu))
+ vlib_error_count (vm, node->node_index, OCT_TX_NODE_CTR_MTU_EXCEEDED,
+ ctx.n_exd_mtu);
+
if (ctx.batch_alloc_not_ready)
vlib_error_count (vm, node_index,
OCT_TX_NODE_CTR_AURA_BATCH_ALLOC_NOT_READY,
@@ -423,5 +457,13 @@ VNET_DEV_NODE_FN (oct_tx_node)
n_pkts -= ctx.n_drop;
}
+ if (PREDICT_FALSE (ctx.n_exd_mtu))
+ {
+ u32 bi[VLIB_FRAME_SIZE];
+ vlib_get_buffer_indices (vm, ctx.exd_mtu, bi, ctx.n_exd_mtu);
+ vlib_buffer_free (vm, bi, ctx.n_exd_mtu);
+ n_pkts -= ctx.n_exd_mtu;
+ }
+
return n_pkts;
}