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[] = {
};
static struct rte_eth_link pmd_link = {
- .link_speed = ETH_SPEED_NUM_10G,
- .link_duplex = ETH_LINK_FULL_DUPLEX,
- .link_status = ETH_LINK_DOWN,
- .link_autoneg = ETH_LINK_FIXED,
+ .link_speed = RTE_ETH_SPEED_NUM_10G,
+ .link_duplex = RTE_ETH_LINK_FULL_DUPLEX,
+ .link_status = RTE_ETH_LINK_DOWN,
+ .link_autoneg = RTE_ETH_LINK_FIXED,
};
RTE_LOG_REGISTER_DEFAULT(af_packet_logtype, NOTICE);
/* check for vlan info */
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);
+ mbuf->ol_flags |= (RTE_MBUF_F_RX_VLAN | RTE_MBUF_F_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.
*/
}
/* insert vlan info if necessary */
- if (mbuf->ol_flags & PKT_TX_VLAN_PKT) {
+ if (mbuf->ol_flags & RTE_MBUF_F_TX_VLAN) {
if (rte_vlan_insert(&mbuf)) {
rte_pktmbuf_free(mbuf);
continue;
}
/* 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)) {
+ if (poll(&pfd, 1, -1) < 0)
+ break;
+
+ /* poll() can return POLLERR if the interface is down */
+ if (pfd.revents & POLLERR)
+ break;
+ }
+
+ /*
+ * poll() will almost always return POLLOUT, even if there
+ * are no extra buffers available
+ *
+ * This happens, because packet_poll() calls datagram_poll()
+ * which checks the space left in the socket buffer and,
+ * in the case of packet_mmap, the default socket buffer length
+ * doesn't match the requested size for the tx_ring.
+ * As such, there is almost always space left in socket buffer,
+ * which doesn't seem to be correlated to the requested size
+ * for the tx_ring in packet_mmap.
+ *
+ * This results in poll() returning POLLOUT.
+ */
+ if (!tx_ring_status_available(ppd->tp_status))
break;
/* copy the tx frame data */
static int
eth_dev_start(struct rte_eth_dev *dev)
{
- dev->data->dev_link.link_status = ETH_LINK_UP;
+ dev->data->dev_link.link_status = RTE_ETH_LINK_UP;
return 0;
}
internals->tx_queue[i].sockfd = -1;
}
- dev->data->dev_link.link_status = ETH_LINK_DOWN;
+ dev->data->dev_link.link_status = RTE_ETH_LINK_DOWN;
return 0;
}
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 & RTE_ETH_RX_OFFLOAD_VLAN_STRIP);
return 0;
}
dev_info->if_index = internals->if_index;
dev_info->max_mac_addrs = 1;
- dev_info->max_rx_pktlen = (uint32_t)ETH_FRAME_LEN;
+ dev_info->max_rx_pktlen = RTE_ETHER_MAX_LEN;
dev_info->max_rx_queues = (uint16_t)internals->nb_queues;
dev_info->max_tx_queues = (uint16_t)internals->nb_queues;
dev_info->min_rx_bufsize = 0;
- dev_info->tx_offload_capa = DEV_TX_OFFLOAD_MULTI_SEGS |
- DEV_TX_OFFLOAD_VLAN_INSERT;
+ dev_info->tx_offload_capa = RTE_ETH_TX_OFFLOAD_MULTI_SEGS |
+ RTE_ETH_TX_OFFLOAD_VLAN_INSERT;
+ dev_info->rx_offload_capa = RTE_ETH_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,