X-Git-Url: http://git.droids-corp.org/?a=blobdiff_plain;f=lib%2Flibrte_pmd_e1000%2Figb_rxtx.c;h=41727e7651bcb8b9d68cfa444e371b996e344f8f;hb=08b563ffb19d8baf59dd84200f25bc85031d18a7;hp=74bfb1f45d1b2f1b05e07b8599a9f02a0f54160b;hpb=c6c79fa425f12fbb7ebb57b53bd83dd00deeaf3e;p=dpdk.git diff --git a/lib/librte_pmd_e1000/igb_rxtx.c b/lib/librte_pmd_e1000/igb_rxtx.c index 74bfb1f45d..41727e7651 100644 --- a/lib/librte_pmd_e1000/igb_rxtx.c +++ b/lib/librte_pmd_e1000/igb_rxtx.c @@ -73,20 +73,29 @@ #include "e1000/e1000_api.h" #include "e1000_ethdev.h" +#define IGB_RSS_OFFLOAD_ALL ( \ + ETH_RSS_IPV4 | \ + ETH_RSS_IPV4_TCP | \ + ETH_RSS_IPV6 | \ + ETH_RSS_IPV6_EX | \ + ETH_RSS_IPV6_TCP | \ + ETH_RSS_IPV6_TCP_EX | \ + ETH_RSS_IPV4_UDP | \ + ETH_RSS_IPV6_UDP | \ + ETH_RSS_IPV6_UDP_EX) + static inline struct rte_mbuf * rte_rxmbuf_alloc(struct rte_mempool *mp) { struct rte_mbuf *m; m = __rte_mbuf_raw_alloc(mp); - __rte_mbuf_sanity_check_raw(m, RTE_MBUF_PKT, 0); + __rte_mbuf_sanity_check_raw(m, 0); return (m); } #define RTE_MBUF_DATA_DMA_ADDR(mb) \ - (uint64_t) ((mb)->buf_physaddr + \ - (uint64_t) ((char *)((mb)->pkt.data) - \ - (char *)(mb)->buf_addr)) + (uint64_t) ((mb)->buf_physaddr + (mb)->data_off) #define RTE_MBUF_DATA_DMA_ADDR_DEFAULT(mb) \ (uint64_t) ((mb)->buf_physaddr + RTE_PKTMBUF_HEADROOM) @@ -142,13 +151,33 @@ enum igb_advctx_num { IGB_CTX_NUM = 2, /**< CTX_NUM */ }; +/** Offload features */ +union igb_vlan_macip { + uint32_t data; + struct { + uint16_t l2_l3_len; /**< 7bit L2 and 9b L3 lengths combined */ + uint16_t vlan_tci; + /**< VLAN Tag Control Identifier (CPU order). */ + } f; +}; + +/* + * Compare mask for vlan_macip_len.data, + * should be in sync with igb_vlan_macip.f layout. + * */ +#define TX_VLAN_CMP_MASK 0xFFFF0000 /**< VLAN length - 16-bits. */ +#define TX_MAC_LEN_CMP_MASK 0x0000FE00 /**< MAC length - 7-bits. */ +#define TX_IP_LEN_CMP_MASK 0x000001FF /**< IP length - 9-bits. */ +/** MAC+IP length. */ +#define TX_MACIP_LEN_CMP_MASK (TX_MAC_LEN_CMP_MASK | TX_IP_LEN_CMP_MASK) + /** * Strucutre to check if new context need be built */ struct igb_advctx_info { uint16_t flags; /**< ol_flags related to context build. */ uint32_t cmp_mask; /**< compare mask for vlan_macip_lens */ - union rte_vlan_macip vlan_macip_lens; /**< vlan, mac & ip length. */ + union igb_vlan_macip vlan_macip_lens; /**< vlan, mac & ip length. */ }; /** @@ -331,6 +360,7 @@ eth_igb_xmit_pkts(void *tx_queue, struct rte_mbuf **tx_pkts, volatile union e1000_adv_tx_desc *txd; struct rte_mbuf *tx_pkt; struct rte_mbuf *m_seg; + union igb_vlan_macip vlan_macip_lens; uint64_t buf_dma_addr; uint32_t olinfo_status; uint32_t cmd_type_len; @@ -344,7 +374,6 @@ eth_igb_xmit_pkts(void *tx_queue, struct rte_mbuf **tx_pkts, uint16_t tx_ol_req; uint32_t new_ctx = 0; uint32_t ctx = 0; - uint32_t vlan_macip_lens; txq = tx_queue; sw_ring = txq->sw_ring; @@ -354,7 +383,7 @@ eth_igb_xmit_pkts(void *tx_queue, struct rte_mbuf **tx_pkts, for (nb_tx = 0; nb_tx < nb_pkts; nb_tx++) { tx_pkt = *tx_pkts++; - pkt_len = tx_pkt->pkt.pkt_len; + pkt_len = tx_pkt->pkt_len; RTE_MBUF_PREFETCH_TO_FREE(txe->mbuf); @@ -366,16 +395,17 @@ eth_igb_xmit_pkts(void *tx_queue, struct rte_mbuf **tx_pkts, * for the packet, starting from the current position (tx_id) * in the ring. */ - tx_last = (uint16_t) (tx_id + tx_pkt->pkt.nb_segs - 1); + tx_last = (uint16_t) (tx_id + tx_pkt->nb_segs - 1); ol_flags = tx_pkt->ol_flags; - vlan_macip_lens = tx_pkt->pkt.vlan_macip.data; + vlan_macip_lens.f.vlan_tci = tx_pkt->vlan_tci; + vlan_macip_lens.f.l2_l3_len = tx_pkt->l2_l3_len; tx_ol_req = (uint16_t)(ol_flags & PKT_TX_OFFLOAD_MASK); /* If a Context Descriptor need be built . */ if (tx_ol_req) { ctx = what_advctx_update(txq, tx_ol_req, - vlan_macip_lens); + vlan_macip_lens.data); /* Only allocate context descriptor if required*/ new_ctx = (ctx == IGB_CTX_NUM); ctx = txq->ctx_curr; @@ -491,7 +521,7 @@ eth_igb_xmit_pkts(void *tx_queue, struct rte_mbuf **tx_pkts, } igbe_set_xmit_ctx(txq, ctx_txd, tx_ol_req, - vlan_macip_lens); + vlan_macip_lens.data); txe->last_id = tx_last; tx_id = txe->next_id; @@ -516,7 +546,7 @@ eth_igb_xmit_pkts(void *tx_queue, struct rte_mbuf **tx_pkts, /* * Set up transmit descriptor. */ - slen = (uint16_t) m_seg->pkt.data_len; + slen = (uint16_t) m_seg->data_len; buf_dma_addr = RTE_MBUF_DATA_DMA_ADDR(m_seg); txd->read.buffer_addr = rte_cpu_to_le_64(buf_dma_addr); @@ -527,7 +557,7 @@ eth_igb_xmit_pkts(void *tx_queue, struct rte_mbuf **tx_pkts, txe->last_id = tx_last; tx_id = txe->next_id; txe = txn; - m_seg = m_seg->pkt.next; + m_seg = m_seg->next; } while (m_seg != NULL); /* @@ -742,19 +772,18 @@ eth_igb_recv_pkts(void *rx_queue, struct rte_mbuf **rx_pkts, */ pkt_len = (uint16_t) (rte_le_to_cpu_16(rxd.wb.upper.length) - rxq->crc_len); - rxm->pkt.data = (char*) rxm->buf_addr + RTE_PKTMBUF_HEADROOM; - rte_packet_prefetch(rxm->pkt.data); - rxm->pkt.nb_segs = 1; - rxm->pkt.next = NULL; - rxm->pkt.pkt_len = pkt_len; - rxm->pkt.data_len = pkt_len; - rxm->pkt.in_port = rxq->port_id; - - rxm->pkt.hash.rss = rxd.wb.lower.hi_dword.rss; + rxm->data_off = RTE_PKTMBUF_HEADROOM; + rte_packet_prefetch((char *)rxm->buf_addr + rxm->data_off); + rxm->nb_segs = 1; + rxm->next = NULL; + rxm->pkt_len = pkt_len; + rxm->data_len = pkt_len; + rxm->port = rxq->port_id; + + rxm->hash.rss = rxd.wb.lower.hi_dword.rss; hlen_type_rss = rte_le_to_cpu_32(rxd.wb.lower.lo_dword.data); /* Only valid if PKT_RX_VLAN_PKT set in pkt_flags */ - rxm->pkt.vlan_macip.f.vlan_tci = - rte_le_to_cpu_16(rxd.wb.upper.vlan); + rxm->vlan_tci = rte_le_to_cpu_16(rxd.wb.upper.vlan); pkt_flags = rx_desc_hlen_type_rss_to_pkt_flags(hlen_type_rss); pkt_flags = (uint16_t)(pkt_flags | @@ -918,8 +947,8 @@ eth_igb_recv_scattered_pkts(void *rx_queue, struct rte_mbuf **rx_pkts, * Set data length & data buffer address of mbuf. */ data_len = rte_le_to_cpu_16(rxd.wb.upper.length); - rxm->pkt.data_len = data_len; - rxm->pkt.data = (char*) rxm->buf_addr + RTE_PKTMBUF_HEADROOM; + rxm->data_len = data_len; + rxm->data_off = RTE_PKTMBUF_HEADROOM; /* * If this is the first buffer of the received packet, @@ -931,12 +960,12 @@ eth_igb_recv_scattered_pkts(void *rx_queue, struct rte_mbuf **rx_pkts, */ if (first_seg == NULL) { first_seg = rxm; - first_seg->pkt.pkt_len = data_len; - first_seg->pkt.nb_segs = 1; + first_seg->pkt_len = data_len; + first_seg->nb_segs = 1; } else { - first_seg->pkt.pkt_len += data_len; - first_seg->pkt.nb_segs++; - last_seg->pkt.next = rxm; + first_seg->pkt_len += data_len; + first_seg->nb_segs++; + last_seg->next = rxm; } /* @@ -959,18 +988,18 @@ eth_igb_recv_scattered_pkts(void *rx_queue, struct rte_mbuf **rx_pkts, * mbuf, subtract the length of that CRC part from the * data length of the previous mbuf. */ - rxm->pkt.next = NULL; + rxm->next = NULL; if (unlikely(rxq->crc_len > 0)) { - first_seg->pkt.pkt_len -= ETHER_CRC_LEN; + first_seg->pkt_len -= ETHER_CRC_LEN; if (data_len <= ETHER_CRC_LEN) { rte_pktmbuf_free_seg(rxm); - first_seg->pkt.nb_segs--; - last_seg->pkt.data_len = (uint16_t) - (last_seg->pkt.data_len - + first_seg->nb_segs--; + last_seg->data_len = (uint16_t) + (last_seg->data_len - (ETHER_CRC_LEN - data_len)); - last_seg->pkt.next = NULL; + last_seg->next = NULL; } else - rxm->pkt.data_len = + rxm->data_len = (uint16_t) (data_len - ETHER_CRC_LEN); } @@ -983,15 +1012,14 @@ eth_igb_recv_scattered_pkts(void *rx_queue, struct rte_mbuf **rx_pkts, * - VLAN TCI, if any, * - error flags. */ - first_seg->pkt.in_port = rxq->port_id; - first_seg->pkt.hash.rss = rxd.wb.lower.hi_dword.rss; + first_seg->port = rxq->port_id; + first_seg->hash.rss = rxd.wb.lower.hi_dword.rss; /* * The vlan_tci field is only valid when PKT_RX_VLAN_PKT is * set in the pkt_flags field. */ - first_seg->pkt.vlan_macip.f.vlan_tci = - rte_le_to_cpu_16(rxd.wb.upper.vlan); + first_seg->vlan_tci = rte_le_to_cpu_16(rxd.wb.upper.vlan); hlen_type_rss = rte_le_to_cpu_32(rxd.wb.lower.lo_dword.data); pkt_flags = rx_desc_hlen_type_rss_to_pkt_flags(hlen_type_rss); pkt_flags = (uint16_t)(pkt_flags | @@ -1001,7 +1029,8 @@ eth_igb_recv_scattered_pkts(void *rx_queue, struct rte_mbuf **rx_pkts, first_seg->ol_flags = pkt_flags; /* Prefetch data of first segment, if configured to do so. */ - rte_packet_prefetch(first_seg->pkt.data); + rte_packet_prefetch((char *)first_seg->buf_addr + + first_seg->data_off); /* * Store the mbuf address into the next entry of the array @@ -1078,7 +1107,7 @@ ring_dma_zone_reserve(struct rte_eth_dev *dev, const char *ring_name, char z_name[RTE_MEMZONE_NAMESIZE]; const struct rte_memzone *mz; - rte_snprintf(z_name, sizeof(z_name), "%s_%s_%d_%d", + snprintf(z_name, sizeof(z_name), "%s_%s_%d_%d", dev->driver->pci_drv.name, ring_name, dev->data->port_id, queue_id); mz = rte_memzone_lookup(z_name); @@ -1212,8 +1241,10 @@ eth_igb_tx_queue_setup(struct rte_eth_dev *dev, "the TX WTHRESH value to 4, 8, or 16.\n"); /* Free memory prior to re-allocation if needed */ - if (dev->data->tx_queues[queue_idx] != NULL) + if (dev->data->tx_queues[queue_idx] != NULL) { igb_tx_queue_release(dev->data->tx_queues[queue_idx]); + dev->data->tx_queues[queue_idx] = NULL; + } /* First allocate the tx queue data structure */ txq = rte_zmalloc("ethdev TX queue", sizeof(struct igb_tx_queue), @@ -1524,7 +1555,7 @@ igb_hw_rss_hash_set(struct e1000_hw *hw, struct rte_eth_rss_conf *rss_conf) uint8_t *hash_key; uint32_t rss_key; uint32_t mrqc; - uint16_t rss_hf; + uint64_t rss_hf; uint16_t i; hash_key = rss_conf->rss_key; @@ -1569,7 +1600,7 @@ eth_igb_rss_hash_update(struct rte_eth_dev *dev, { struct e1000_hw *hw; uint32_t mrqc; - uint16_t rss_hf; + uint64_t rss_hf; hw = E1000_DEV_PRIVATE_TO_HW(dev->data->dev_private); @@ -1579,7 +1610,7 @@ eth_igb_rss_hash_update(struct rte_eth_dev *dev, * initialization time, or does not attempt to enable RSS, if RSS was * disabled at initialization time. */ - rss_hf = rss_conf->rss_hf; + rss_hf = rss_conf->rss_hf & IGB_RSS_OFFLOAD_ALL; mrqc = E1000_READ_REG(hw, E1000_MRQC); if (!(mrqc & E1000_MRQC_ENABLE_MASK)) { /* RSS disabled */ if (rss_hf != 0) /* Enable RSS */ @@ -1600,7 +1631,7 @@ int eth_igb_rss_hash_conf_get(struct rte_eth_dev *dev, uint8_t *hash_key; uint32_t rss_key; uint32_t mrqc; - uint16_t rss_hf; + uint64_t rss_hf; uint16_t i; hw = E1000_DEV_PRIVATE_TO_HW(dev->data->dev_private); @@ -1676,7 +1707,7 @@ igb_rss_configure(struct rte_eth_dev *dev) * the RSS hash of input packets. */ rss_conf = dev->data->dev_conf.rx_adv_conf.rss_conf; - if (rss_conf.rss_hf == 0) { + if ((rss_conf.rss_hf & IGB_RSS_OFFLOAD_ALL) == 0) { igb_rss_disable(dev); return; } @@ -1995,6 +2026,11 @@ eth_igb_rx_init(struct rte_eth_dev *dev) E1000_WRITE_REG(hw, E1000_RXDCTL(rxq->reg_idx), rxdctl); } + if (dev->data->dev_conf.rxmode.enable_scatter) { + dev->rx_pkt_burst = eth_igb_recv_scattered_pkts; + dev->data->scattered_rx = 1; + } + /* * Setup BSIZE field of RCTL register, if needed. * Buffer sizes >= 1024 are not [supposed to be] setup in the RCTL @@ -2264,6 +2300,11 @@ eth_igbvf_rx_init(struct rte_eth_dev *dev) E1000_WRITE_REG(hw, E1000_RXDCTL(i), rxdctl); } + if (dev->data->dev_conf.rxmode.enable_scatter) { + dev->rx_pkt_burst = eth_igb_recv_scattered_pkts; + dev->data->scattered_rx = 1; + } + /* * Setup the HW Rx Head and Tail Descriptor Pointers. * This needs to be done after enable.