X-Git-Url: http://git.droids-corp.org/?a=blobdiff_plain;f=drivers%2Fnet%2Faf_packet%2Frte_eth_af_packet.c;h=a077376dc0fbf69f964cdd9f00b1a85753344112;hb=63abf8d292252193db075e3264cceb3f6817ed79;hp=cb1c39b027d5c04de0b519e46b3b06ceb40e0f47;hpb=62024eb8275696bead35b38a6062a2513f1f7c58;p=dpdk.git diff --git a/drivers/net/af_packet/rte_eth_af_packet.c b/drivers/net/af_packet/rte_eth_af_packet.c index cb1c39b027..a077376dc0 100644 --- a/drivers/net/af_packet/rte_eth_af_packet.c +++ b/drivers/net/af_packet/rte_eth_af_packet.c @@ -8,8 +8,8 @@ #include #include -#include -#include +#include +#include #include #include #include @@ -48,6 +48,7 @@ struct pkt_rx_queue { struct rte_mempool *mb_pool; uint16_t in_port; + uint8_t vlan_strip; volatile unsigned long rx_pkts; volatile unsigned long rx_bytes; @@ -78,6 +79,7 @@ struct pmd_internals { struct pkt_rx_queue *rx_queue; struct pkt_tx_queue *tx_queue; + uint8_t vlan_strip; }; static const char *valid_arguments[] = { @@ -97,7 +99,7 @@ static struct rte_eth_link pmd_link = { .link_autoneg = ETH_LINK_FIXED, }; -RTE_LOG_REGISTER(af_packet_logtype, pmd.net.packet, NOTICE); +RTE_LOG_REGISTER_DEFAULT(af_packet_logtype, NOTICE); #define PMD_LOG(level, fmt, args...) \ rte_log(RTE_LOG_ ## level, af_packet_logtype, \ @@ -148,6 +150,9 @@ eth_af_packet_rx(void *queue, struct rte_mbuf **bufs, uint16_t nb_pkts) 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 */ @@ -167,6 +172,26 @@ eth_af_packet_rx(void *queue, struct rte_mbuf **bufs, uint16_t nb_pkts) 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. */ @@ -212,8 +237,8 @@ eth_af_packet_tx(void *queue, struct rte_mbuf **bufs, uint16_t nb_pkts) } /* 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 */ @@ -302,6 +327,11 @@ eth_dev_stop(struct rte_eth_dev *dev) 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; } @@ -318,6 +348,7 @@ eth_dev_info(struct rte_eth_dev *dev, struct rte_eth_dev_info *dev_info) 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; } @@ -407,11 +438,6 @@ eth_dev_close(struct rte_eth_dev *dev) 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) @@ -448,6 +474,7 @@ eth_rx_queue_setup(struct rte_eth_dev *dev, 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; } @@ -574,8 +601,6 @@ static const struct eth_dev_ops ops = { .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, @@ -748,18 +773,18 @@ rte_pmd_init_internals(struct rte_vdev_device *dev, 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) { @@ -860,6 +885,7 @@ rte_pmd_init_internals(struct rte_vdev_device *dev, data->nb_tx_queues = (uint16_t)nb_queues; data->dev_link = pmd_link; data->mac_addrs = &(*internals)->eth_addr; + data->dev_flags |= RTE_ETH_DEV_AUTOFILL_QUEUE_XSTATS; (*eth_dev)->dev_ops = &ops;