struct rte_mempool *mb_pool;
uint16_t in_port;
+ uint8_t vlan_strip;
volatile unsigned long rx_pkts;
volatile unsigned long rx_bytes;
struct pkt_rx_queue *rx_queue;
struct pkt_tx_queue *tx_queue;
+ uint8_t vlan_strip;
};
static const char *valid_arguments[] = {
if (ppd->tp_status & TP_STATUS_VLAN_VALID) {
mbuf->vlan_tci = ppd->tp_vlan_tci;
mbuf->ol_flags |= (PKT_RX_VLAN | PKT_RX_VLAN_STRIPPED);
+
+ if (!pkt_q->vlan_strip && rte_vlan_insert(&mbuf))
+ PMD_LOG(ERR, "Failed to reinsert VLAN tag");
}
/* release incoming frame and advance ring buffer */
return num_rx;
}
+/*
+ * Check if there is an available frame in the ring
+ */
+static inline bool
+tx_ring_status_available(uint32_t tp_status)
+{
+ /*
+ * We eliminate the timestamp status from the packet status.
+ * This should only matter if timestamping is enabled on the socket,
+ * but there is a bug in the kernel which is fixed in newer releases.
+ *
+ * See the following kernel commit for reference:
+ * commit 171c3b151118a2fe0fc1e2a9d1b5a1570cfe82d2
+ * net: packetmmap: fix only tx timestamp on request
+ */
+ tp_status &= ~(TP_STATUS_TS_SOFTWARE | TP_STATUS_TS_RAW_HARDWARE);
+
+ return tp_status == TP_STATUS_AVAILABLE;
+}
+
/*
* Callback to handle sending packets through a real NIC.
*/
}
/* point at the next incoming frame */
- if ((ppd->tp_status != TP_STATUS_AVAILABLE) &&
- (poll(&pfd, 1, -1) < 0))
+ if (!tx_ring_status_available(ppd->tp_status) &&
+ poll(&pfd, 1, -1) < 0)
break;
/* copy the tx frame data */
static int
eth_dev_configure(struct rte_eth_dev *dev __rte_unused)
{
+ struct rte_eth_conf *dev_conf = &dev->data->dev_conf;
+ const struct rte_eth_rxmode *rxmode = &dev_conf->rxmode;
+ struct pmd_internals *internals = dev->data->dev_private;
+
+ internals->vlan_strip = !!(rxmode->offloads & DEV_RX_OFFLOAD_VLAN_STRIP);
return 0;
}
dev_info->min_rx_bufsize = 0;
dev_info->tx_offload_capa = DEV_TX_OFFLOAD_MULTI_SEGS |
DEV_TX_OFFLOAD_VLAN_INSERT;
+ dev_info->rx_offload_capa = DEV_RX_OFFLOAD_VLAN_STRIP;
return 0;
}
return 0;
}
-static void
-eth_queue_release(void *q __rte_unused)
-{
-}
-
static int
eth_link_update(struct rte_eth_dev *dev __rte_unused,
int wait_to_complete __rte_unused)
dev->data->rx_queues[rx_queue_id] = pkt_q;
pkt_q->in_port = dev->data->port_id;
+ pkt_q->vlan_strip = internals->vlan_strip;
return 0;
}
.promiscuous_disable = eth_dev_promiscuous_disable,
.rx_queue_setup = eth_rx_queue_setup,
.tx_queue_setup = eth_tx_queue_setup,
- .rx_queue_release = eth_queue_release,
- .tx_queue_release = eth_queue_release,
.link_update = eth_link_update,
.stats_get = eth_stats_get,
.stats_reset = eth_stats_reset,
goto error;
}
+ if (qdisc_bypass) {
#if defined(PACKET_QDISC_BYPASS)
- rc = setsockopt(qsockfd, SOL_PACKET, PACKET_QDISC_BYPASS,
- &qdisc_bypass, sizeof(qdisc_bypass));
- if (rc == -1) {
- PMD_LOG_ERRNO(ERR,
- "%s: could not set PACKET_QDISC_BYPASS on AF_PACKET socket for %s",
- name, pair->value);
- goto error;
- }
-#else
- RTE_SET_USED(qdisc_bypass);
+ rc = setsockopt(qsockfd, SOL_PACKET, PACKET_QDISC_BYPASS,
+ &qdisc_bypass, sizeof(qdisc_bypass));
+ if (rc == -1) {
+ PMD_LOG_ERRNO(ERR,
+ "%s: could not set PACKET_QDISC_BYPASS on AF_PACKET socket for %s",
+ name, pair->value);
+ goto error;
+ }
#endif
+ }
rc = setsockopt(qsockfd, SOL_PACKET, PACKET_RX_RING, req, sizeof(*req));
if (rc == -1) {