4 * Copyright(c) 2013-2015 Intel Corporation. All rights reserved.
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
11 * * Redistributions of source code must retain the above copyright
12 * notice, this list of conditions and the following disclaimer.
13 * * Redistributions in binary form must reproduce the above copyright
14 * notice, this list of conditions and the following disclaimer in
15 * the documentation and/or other materials provided with the
17 * * Neither the name of Intel Corporation nor the names of its
18 * contributors may be used to endorse or promote products derived
19 * from this software without specific prior written permission.
21 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
22 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
23 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
24 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
25 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
26 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
27 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
28 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
29 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
30 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
31 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
34 #include <rte_ethdev.h>
35 #include <rte_malloc.h>
36 #include <rte_memzone.h>
37 #include <rte_string_fns.h>
39 #include <rte_spinlock.h>
42 #include "base/fm10k_api.h"
44 #define FM10K_RX_BUFF_ALIGN 512
45 /* Default delay to acquire mailbox lock */
46 #define FM10K_MBXLOCK_DELAY_US 20
48 /* Number of chars per uint32 type */
49 #define CHARS_PER_UINT32 (sizeof(uint32_t))
50 #define BIT_MASK_PER_UINT32 ((1 << CHARS_PER_UINT32) - 1)
53 fm10k_mbx_initlock(struct fm10k_hw *hw)
55 rte_spinlock_init(FM10K_DEV_PRIVATE_TO_MBXLOCK(hw->back));
59 fm10k_mbx_lock(struct fm10k_hw *hw)
61 while (!rte_spinlock_trylock(FM10K_DEV_PRIVATE_TO_MBXLOCK(hw->back)))
62 rte_delay_us(FM10K_MBXLOCK_DELAY_US);
66 fm10k_mbx_unlock(struct fm10k_hw *hw)
68 rte_spinlock_unlock(FM10K_DEV_PRIVATE_TO_MBXLOCK(hw->back));
72 * reset queue to initial state, allocate software buffers used when starting
75 * return -ENOMEM if buffers cannot be allocated
76 * return -EINVAL if buffers do not satisfy alignment condition
79 rx_queue_reset(struct fm10k_rx_queue *q)
83 PMD_INIT_FUNC_TRACE();
85 diag = rte_mempool_get_bulk(q->mp, (void **)q->sw_ring, q->nb_desc);
89 for (i = 0; i < q->nb_desc; ++i) {
90 fm10k_pktmbuf_reset(q->sw_ring[i], q->port_id);
91 if (!fm10k_addr_alignment_valid(q->sw_ring[i])) {
92 rte_mempool_put_bulk(q->mp, (void **)q->sw_ring,
96 dma_addr = MBUF_DMA_ADDR_DEFAULT(q->sw_ring[i]);
97 q->hw_ring[i].q.pkt_addr = dma_addr;
98 q->hw_ring[i].q.hdr_addr = dma_addr;
103 q->next_trigger = q->alloc_thresh - 1;
104 FM10K_PCI_REG_WRITE(q->tail_ptr, q->nb_desc - 1);
109 * clean queue, descriptor rings, free software buffers used when stopping
113 rx_queue_clean(struct fm10k_rx_queue *q)
115 union fm10k_rx_desc zero = {.q = {0, 0, 0, 0} };
117 PMD_INIT_FUNC_TRACE();
119 /* zero descriptor rings */
120 for (i = 0; i < q->nb_desc; ++i)
121 q->hw_ring[i] = zero;
123 /* free software buffers */
124 for (i = 0; i < q->nb_desc; ++i) {
126 rte_pktmbuf_free_seg(q->sw_ring[i]);
127 q->sw_ring[i] = NULL;
133 * free all queue memory used when releasing the queue (i.e. configure)
136 rx_queue_free(struct fm10k_rx_queue *q)
138 PMD_INIT_FUNC_TRACE();
140 PMD_INIT_LOG(DEBUG, "Freeing rx queue %p", q);
143 rte_free(q->sw_ring);
149 * disable RX queue, wait unitl HW finished necessary flush operation
152 rx_queue_disable(struct fm10k_hw *hw, uint16_t qnum)
156 reg = FM10K_READ_REG(hw, FM10K_RXQCTL(qnum));
157 FM10K_WRITE_REG(hw, FM10K_RXQCTL(qnum),
158 reg & ~FM10K_RXQCTL_ENABLE);
160 /* Wait 100us at most */
161 for (i = 0; i < FM10K_QUEUE_DISABLE_TIMEOUT; i++) {
163 reg = FM10K_READ_REG(hw, FM10K_RXQCTL(i));
164 if (!(reg & FM10K_RXQCTL_ENABLE))
168 if (i == FM10K_QUEUE_DISABLE_TIMEOUT)
175 * reset queue to initial state, allocate software buffers used when starting
179 tx_queue_reset(struct fm10k_tx_queue *q)
181 PMD_INIT_FUNC_TRACE();
185 q->nb_free = q->nb_desc - 1;
186 q->free_trigger = q->nb_free - q->free_thresh;
187 fifo_reset(&q->rs_tracker, (q->nb_desc + 1) / q->rs_thresh);
188 FM10K_PCI_REG_WRITE(q->tail_ptr, 0);
192 * clean queue, descriptor rings, free software buffers used when stopping
196 tx_queue_clean(struct fm10k_tx_queue *q)
198 struct fm10k_tx_desc zero = {0, 0, 0, 0, 0, 0};
200 PMD_INIT_FUNC_TRACE();
202 /* zero descriptor rings */
203 for (i = 0; i < q->nb_desc; ++i)
204 q->hw_ring[i] = zero;
206 /* free software buffers */
207 for (i = 0; i < q->nb_desc; ++i) {
209 rte_pktmbuf_free_seg(q->sw_ring[i]);
210 q->sw_ring[i] = NULL;
216 * free all queue memory used when releasing the queue (i.e. configure)
219 tx_queue_free(struct fm10k_tx_queue *q)
221 PMD_INIT_FUNC_TRACE();
223 PMD_INIT_LOG(DEBUG, "Freeing tx queue %p", q);
225 if (q->rs_tracker.list)
226 rte_free(q->rs_tracker.list);
228 rte_free(q->sw_ring);
234 * disable TX queue, wait unitl HW finished necessary flush operation
237 tx_queue_disable(struct fm10k_hw *hw, uint16_t qnum)
241 reg = FM10K_READ_REG(hw, FM10K_TXDCTL(qnum));
242 FM10K_WRITE_REG(hw, FM10K_TXDCTL(qnum),
243 reg & ~FM10K_TXDCTL_ENABLE);
245 /* Wait 100us at most */
246 for (i = 0; i < FM10K_QUEUE_DISABLE_TIMEOUT; i++) {
248 reg = FM10K_READ_REG(hw, FM10K_TXDCTL(i));
249 if (!(reg & FM10K_TXDCTL_ENABLE))
253 if (i == FM10K_QUEUE_DISABLE_TIMEOUT)
260 fm10k_dev_configure(struct rte_eth_dev *dev)
262 PMD_INIT_FUNC_TRACE();
264 if (dev->data->dev_conf.rxmode.hw_strip_crc == 0)
265 PMD_INIT_LOG(WARNING, "fm10k always strip CRC");
271 fm10k_dev_rx_queue_start(struct rte_eth_dev *dev, uint16_t rx_queue_id)
273 struct fm10k_hw *hw = FM10K_DEV_PRIVATE_TO_HW(dev->data->dev_private);
276 struct fm10k_rx_queue *rxq;
278 PMD_INIT_FUNC_TRACE();
280 if (rx_queue_id < dev->data->nb_rx_queues) {
281 rxq = dev->data->rx_queues[rx_queue_id];
282 err = rx_queue_reset(rxq);
283 if (err == -ENOMEM) {
284 PMD_INIT_LOG(ERR, "Failed to alloc memory : %d", err);
286 } else if (err == -EINVAL) {
287 PMD_INIT_LOG(ERR, "Invalid buffer address alignment :"
292 /* Setup the HW Rx Head and Tail Descriptor Pointers
293 * Note: this must be done AFTER the queue is enabled on real
294 * hardware, but BEFORE the queue is enabled when using the
295 * emulation platform. Do it in both places for now and remove
296 * this comment and the following two register writes when the
297 * emulation platform is no longer being used.
299 FM10K_WRITE_REG(hw, FM10K_RDH(rx_queue_id), 0);
300 FM10K_WRITE_REG(hw, FM10K_RDT(rx_queue_id), rxq->nb_desc - 1);
302 /* Set PF ownership flag for PF devices */
303 reg = FM10K_READ_REG(hw, FM10K_RXQCTL(rx_queue_id));
304 if (hw->mac.type == fm10k_mac_pf)
305 reg |= FM10K_RXQCTL_PF;
306 reg |= FM10K_RXQCTL_ENABLE;
307 /* enable RX queue */
308 FM10K_WRITE_REG(hw, FM10K_RXQCTL(rx_queue_id), reg);
309 FM10K_WRITE_FLUSH(hw);
311 /* Setup the HW Rx Head and Tail Descriptor Pointers
312 * Note: this must be done AFTER the queue is enabled
314 FM10K_WRITE_REG(hw, FM10K_RDH(rx_queue_id), 0);
315 FM10K_WRITE_REG(hw, FM10K_RDT(rx_queue_id), rxq->nb_desc - 1);
322 fm10k_dev_rx_queue_stop(struct rte_eth_dev *dev, uint16_t rx_queue_id)
324 struct fm10k_hw *hw = FM10K_DEV_PRIVATE_TO_HW(dev->data->dev_private);
326 PMD_INIT_FUNC_TRACE();
328 if (rx_queue_id < dev->data->nb_rx_queues) {
329 /* Disable RX queue */
330 rx_queue_disable(hw, rx_queue_id);
332 /* Free mbuf and clean HW ring */
333 rx_queue_clean(dev->data->rx_queues[rx_queue_id]);
340 fm10k_dev_tx_queue_start(struct rte_eth_dev *dev, uint16_t tx_queue_id)
342 struct fm10k_hw *hw = FM10K_DEV_PRIVATE_TO_HW(dev->data->dev_private);
343 /** @todo - this should be defined in the shared code */
344 #define FM10K_TXDCTL_WRITE_BACK_MIN_DELAY 0x00010000
345 uint32_t txdctl = FM10K_TXDCTL_WRITE_BACK_MIN_DELAY;
348 PMD_INIT_FUNC_TRACE();
350 if (tx_queue_id < dev->data->nb_tx_queues) {
351 tx_queue_reset(dev->data->tx_queues[tx_queue_id]);
353 /* reset head and tail pointers */
354 FM10K_WRITE_REG(hw, FM10K_TDH(tx_queue_id), 0);
355 FM10K_WRITE_REG(hw, FM10K_TDT(tx_queue_id), 0);
357 /* enable TX queue */
358 FM10K_WRITE_REG(hw, FM10K_TXDCTL(tx_queue_id),
359 FM10K_TXDCTL_ENABLE | txdctl);
360 FM10K_WRITE_FLUSH(hw);
368 fm10k_dev_tx_queue_stop(struct rte_eth_dev *dev, uint16_t tx_queue_id)
370 struct fm10k_hw *hw = FM10K_DEV_PRIVATE_TO_HW(dev->data->dev_private);
372 PMD_INIT_FUNC_TRACE();
374 if (tx_queue_id < dev->data->nb_tx_queues) {
375 tx_queue_disable(hw, tx_queue_id);
376 tx_queue_clean(dev->data->tx_queues[tx_queue_id]);
383 fm10k_link_update(struct rte_eth_dev *dev,
384 __rte_unused int wait_to_complete)
386 PMD_INIT_FUNC_TRACE();
388 /* The host-interface link is always up. The speed is ~50Gbps per Gen3
389 * x8 PCIe interface. For now, we leave the speed undefined since there
390 * is no 50Gbps Ethernet. */
391 dev->data->dev_link.link_speed = 0;
392 dev->data->dev_link.link_duplex = ETH_LINK_FULL_DUPLEX;
393 dev->data->dev_link.link_status = 1;
399 fm10k_stats_get(struct rte_eth_dev *dev, struct rte_eth_stats *stats)
401 uint64_t ipackets, opackets, ibytes, obytes;
402 struct fm10k_hw *hw =
403 FM10K_DEV_PRIVATE_TO_HW(dev->data->dev_private);
404 struct fm10k_hw_stats *hw_stats =
405 FM10K_DEV_PRIVATE_TO_STATS(dev->data->dev_private);
408 PMD_INIT_FUNC_TRACE();
410 fm10k_update_hw_stats(hw, hw_stats);
412 ipackets = opackets = ibytes = obytes = 0;
413 for (i = 0; (i < RTE_ETHDEV_QUEUE_STAT_CNTRS) &&
414 (i < FM10K_MAX_QUEUES_PF); ++i) {
415 stats->q_ipackets[i] = hw_stats->q[i].rx_packets.count;
416 stats->q_opackets[i] = hw_stats->q[i].tx_packets.count;
417 stats->q_ibytes[i] = hw_stats->q[i].rx_bytes.count;
418 stats->q_obytes[i] = hw_stats->q[i].tx_bytes.count;
419 ipackets += stats->q_ipackets[i];
420 opackets += stats->q_opackets[i];
421 ibytes += stats->q_ibytes[i];
422 obytes += stats->q_obytes[i];
424 stats->ipackets = ipackets;
425 stats->opackets = opackets;
426 stats->ibytes = ibytes;
427 stats->obytes = obytes;
431 fm10k_stats_reset(struct rte_eth_dev *dev)
433 struct fm10k_hw *hw = FM10K_DEV_PRIVATE_TO_HW(dev->data->dev_private);
434 struct fm10k_hw_stats *hw_stats =
435 FM10K_DEV_PRIVATE_TO_STATS(dev->data->dev_private);
437 PMD_INIT_FUNC_TRACE();
439 memset(hw_stats, 0, sizeof(*hw_stats));
440 fm10k_rebind_hw_stats(hw, hw_stats);
444 fm10k_dev_infos_get(struct rte_eth_dev *dev,
445 struct rte_eth_dev_info *dev_info)
447 struct fm10k_hw *hw = FM10K_DEV_PRIVATE_TO_HW(dev->data->dev_private);
449 PMD_INIT_FUNC_TRACE();
451 dev_info->min_rx_bufsize = FM10K_MIN_RX_BUF_SIZE;
452 dev_info->max_rx_pktlen = FM10K_MAX_PKT_SIZE;
453 dev_info->max_rx_queues = hw->mac.max_queues;
454 dev_info->max_tx_queues = hw->mac.max_queues;
455 dev_info->max_mac_addrs = 1;
456 dev_info->max_hash_mac_addrs = 0;
457 dev_info->max_vfs = FM10K_MAX_VF_NUM;
458 dev_info->max_vmdq_pools = ETH_64_POOLS;
459 dev_info->rx_offload_capa =
460 DEV_RX_OFFLOAD_IPV4_CKSUM |
461 DEV_RX_OFFLOAD_UDP_CKSUM |
462 DEV_RX_OFFLOAD_TCP_CKSUM;
463 dev_info->tx_offload_capa = 0;
464 dev_info->reta_size = FM10K_MAX_RSS_INDICES;
466 dev_info->default_rxconf = (struct rte_eth_rxconf) {
468 .pthresh = FM10K_DEFAULT_RX_PTHRESH,
469 .hthresh = FM10K_DEFAULT_RX_HTHRESH,
470 .wthresh = FM10K_DEFAULT_RX_WTHRESH,
472 .rx_free_thresh = FM10K_RX_FREE_THRESH_DEFAULT(0),
476 dev_info->default_txconf = (struct rte_eth_txconf) {
478 .pthresh = FM10K_DEFAULT_TX_PTHRESH,
479 .hthresh = FM10K_DEFAULT_TX_HTHRESH,
480 .wthresh = FM10K_DEFAULT_TX_WTHRESH,
482 .tx_free_thresh = FM10K_TX_FREE_THRESH_DEFAULT(0),
483 .tx_rs_thresh = FM10K_TX_RS_THRESH_DEFAULT(0),
484 .txq_flags = ETH_TXQ_FLAGS_NOMULTSEGS |
485 ETH_TXQ_FLAGS_NOOFFLOADS,
491 check_nb_desc(uint16_t min, uint16_t max, uint16_t mult, uint16_t request)
493 if ((request < min) || (request > max) || ((request % mult) != 0))
500 * Create a memzone for hardware descriptor rings. Malloc cannot be used since
501 * the physical address is required. If the memzone is already created, then
502 * this function returns a pointer to the existing memzone.
504 static inline const struct rte_memzone *
505 allocate_hw_ring(const char *driver_name, const char *ring_name,
506 uint8_t port_id, uint16_t queue_id, int socket_id,
507 uint32_t size, uint32_t align)
509 char name[RTE_MEMZONE_NAMESIZE];
510 const struct rte_memzone *mz;
512 snprintf(name, sizeof(name), "%s_%s_%d_%d_%d",
513 driver_name, ring_name, port_id, queue_id, socket_id);
515 /* return the memzone if it already exists */
516 mz = rte_memzone_lookup(name);
520 #ifdef RTE_LIBRTE_XEN_DOM0
521 return rte_memzone_reserve_bounded(name, size, socket_id, 0, align,
524 return rte_memzone_reserve_aligned(name, size, socket_id, 0, align);
529 check_thresh(uint16_t min, uint16_t max, uint16_t div, uint16_t request)
531 if ((request < min) || (request > max) || ((div % request) != 0))
538 handle_rxconf(struct fm10k_rx_queue *q, const struct rte_eth_rxconf *conf)
540 uint16_t rx_free_thresh;
542 if (conf->rx_free_thresh == 0)
543 rx_free_thresh = FM10K_RX_FREE_THRESH_DEFAULT(q);
545 rx_free_thresh = conf->rx_free_thresh;
547 /* make sure the requested threshold satisfies the constraints */
548 if (check_thresh(FM10K_RX_FREE_THRESH_MIN(q),
549 FM10K_RX_FREE_THRESH_MAX(q),
550 FM10K_RX_FREE_THRESH_DIV(q),
552 PMD_INIT_LOG(ERR, "rx_free_thresh (%u) must be "
553 "less than or equal to %u, "
554 "greater than or equal to %u, "
555 "and a divisor of %u",
556 rx_free_thresh, FM10K_RX_FREE_THRESH_MAX(q),
557 FM10K_RX_FREE_THRESH_MIN(q),
558 FM10K_RX_FREE_THRESH_DIV(q));
562 q->alloc_thresh = rx_free_thresh;
563 q->drop_en = conf->rx_drop_en;
564 q->rx_deferred_start = conf->rx_deferred_start;
570 * Hardware requires specific alignment for Rx packet buffers. At
571 * least one of the following two conditions must be satisfied.
572 * 1. Address is 512B aligned
573 * 2. Address is 8B aligned and buffer does not cross 4K boundary.
575 * As such, the driver may need to adjust the DMA address within the
576 * buffer by up to 512B. The mempool element size is checked here
577 * to make sure a maximally sized Ethernet frame can still be wholly
578 * contained within the buffer after 512B alignment.
580 * return 1 if the element size is valid, otherwise return 0.
583 mempool_element_size_valid(struct rte_mempool *mp)
587 /* elt_size includes mbuf header and headroom */
588 min_size = mp->elt_size - sizeof(struct rte_mbuf) -
589 RTE_PKTMBUF_HEADROOM;
591 /* account for up to 512B of alignment */
592 min_size -= FM10K_RX_BUFF_ALIGN;
594 /* sanity check for overflow */
595 if (min_size > mp->elt_size)
598 if (min_size < ETHER_MAX_VLAN_FRAME_LEN)
606 fm10k_rx_queue_setup(struct rte_eth_dev *dev, uint16_t queue_id,
607 uint16_t nb_desc, unsigned int socket_id,
608 const struct rte_eth_rxconf *conf, struct rte_mempool *mp)
610 struct fm10k_hw *hw = FM10K_DEV_PRIVATE_TO_HW(dev->data->dev_private);
611 struct fm10k_rx_queue *q;
612 const struct rte_memzone *mz;
614 PMD_INIT_FUNC_TRACE();
616 /* make sure the mempool element size can account for alignment. */
617 if (!mempool_element_size_valid(mp)) {
618 PMD_INIT_LOG(ERR, "Error : Mempool element size is too small");
622 /* make sure a valid number of descriptors have been requested */
623 if (check_nb_desc(FM10K_MIN_RX_DESC, FM10K_MAX_RX_DESC,
624 FM10K_MULT_RX_DESC, nb_desc)) {
625 PMD_INIT_LOG(ERR, "Number of Rx descriptors (%u) must be "
626 "less than or equal to %"PRIu32", "
627 "greater than or equal to %u, "
628 "and a multiple of %u",
629 nb_desc, (uint32_t)FM10K_MAX_RX_DESC, FM10K_MIN_RX_DESC,
635 * if this queue existed already, free the associated memory. The
636 * queue cannot be reused in case we need to allocate memory on
637 * different socket than was previously used.
639 if (dev->data->rx_queues[queue_id] != NULL) {
640 rx_queue_free(dev->data->rx_queues[queue_id]);
641 dev->data->rx_queues[queue_id] = NULL;
644 /* allocate memory for the queue structure */
645 q = rte_zmalloc_socket("fm10k", sizeof(*q), RTE_CACHE_LINE_SIZE,
648 PMD_INIT_LOG(ERR, "Cannot allocate queue structure");
654 q->nb_desc = nb_desc;
655 q->port_id = dev->data->port_id;
656 q->queue_id = queue_id;
657 q->tail_ptr = (volatile uint32_t *)
658 &((uint32_t *)hw->hw_addr)[FM10K_RDT(queue_id)];
659 if (handle_rxconf(q, conf))
662 /* allocate memory for the software ring */
663 q->sw_ring = rte_zmalloc_socket("fm10k sw ring",
664 nb_desc * sizeof(struct rte_mbuf *),
665 RTE_CACHE_LINE_SIZE, socket_id);
666 if (q->sw_ring == NULL) {
667 PMD_INIT_LOG(ERR, "Cannot allocate software ring");
673 * allocate memory for the hardware descriptor ring. A memzone large
674 * enough to hold the maximum ring size is requested to allow for
675 * resizing in later calls to the queue setup function.
677 mz = allocate_hw_ring(dev->driver->pci_drv.name, "rx_ring",
678 dev->data->port_id, queue_id, socket_id,
679 FM10K_MAX_RX_RING_SZ, FM10K_ALIGN_RX_DESC);
681 PMD_INIT_LOG(ERR, "Cannot allocate hardware ring");
682 rte_free(q->sw_ring);
686 q->hw_ring = mz->addr;
687 q->hw_ring_phys_addr = mz->phys_addr;
689 dev->data->rx_queues[queue_id] = q;
694 fm10k_rx_queue_release(void *queue)
696 PMD_INIT_FUNC_TRACE();
698 rx_queue_free(queue);
702 handle_txconf(struct fm10k_tx_queue *q, const struct rte_eth_txconf *conf)
704 uint16_t tx_free_thresh;
705 uint16_t tx_rs_thresh;
707 /* constraint MACROs require that tx_free_thresh is configured
708 * before tx_rs_thresh */
709 if (conf->tx_free_thresh == 0)
710 tx_free_thresh = FM10K_TX_FREE_THRESH_DEFAULT(q);
712 tx_free_thresh = conf->tx_free_thresh;
714 /* make sure the requested threshold satisfies the constraints */
715 if (check_thresh(FM10K_TX_FREE_THRESH_MIN(q),
716 FM10K_TX_FREE_THRESH_MAX(q),
717 FM10K_TX_FREE_THRESH_DIV(q),
719 PMD_INIT_LOG(ERR, "tx_free_thresh (%u) must be "
720 "less than or equal to %u, "
721 "greater than or equal to %u, "
722 "and a divisor of %u",
723 tx_free_thresh, FM10K_TX_FREE_THRESH_MAX(q),
724 FM10K_TX_FREE_THRESH_MIN(q),
725 FM10K_TX_FREE_THRESH_DIV(q));
729 q->free_thresh = tx_free_thresh;
731 if (conf->tx_rs_thresh == 0)
732 tx_rs_thresh = FM10K_TX_RS_THRESH_DEFAULT(q);
734 tx_rs_thresh = conf->tx_rs_thresh;
736 q->tx_deferred_start = conf->tx_deferred_start;
738 /* make sure the requested threshold satisfies the constraints */
739 if (check_thresh(FM10K_TX_RS_THRESH_MIN(q),
740 FM10K_TX_RS_THRESH_MAX(q),
741 FM10K_TX_RS_THRESH_DIV(q),
743 PMD_INIT_LOG(ERR, "tx_rs_thresh (%u) must be "
744 "less than or equal to %u, "
745 "greater than or equal to %u, "
746 "and a divisor of %u",
747 tx_rs_thresh, FM10K_TX_RS_THRESH_MAX(q),
748 FM10K_TX_RS_THRESH_MIN(q),
749 FM10K_TX_RS_THRESH_DIV(q));
753 q->rs_thresh = tx_rs_thresh;
759 fm10k_tx_queue_setup(struct rte_eth_dev *dev, uint16_t queue_id,
760 uint16_t nb_desc, unsigned int socket_id,
761 const struct rte_eth_txconf *conf)
763 struct fm10k_hw *hw = FM10K_DEV_PRIVATE_TO_HW(dev->data->dev_private);
764 struct fm10k_tx_queue *q;
765 const struct rte_memzone *mz;
767 PMD_INIT_FUNC_TRACE();
769 /* make sure a valid number of descriptors have been requested */
770 if (check_nb_desc(FM10K_MIN_TX_DESC, FM10K_MAX_TX_DESC,
771 FM10K_MULT_TX_DESC, nb_desc)) {
772 PMD_INIT_LOG(ERR, "Number of Tx descriptors (%u) must be "
773 "less than or equal to %"PRIu32", "
774 "greater than or equal to %u, "
775 "and a multiple of %u",
776 nb_desc, (uint32_t)FM10K_MAX_TX_DESC, FM10K_MIN_TX_DESC,
782 * if this queue existed already, free the associated memory. The
783 * queue cannot be reused in case we need to allocate memory on
784 * different socket than was previously used.
786 if (dev->data->tx_queues[queue_id] != NULL) {
787 tx_queue_free(dev->data->tx_queues[queue_id]);
788 dev->data->tx_queues[queue_id] = NULL;
791 /* allocate memory for the queue structure */
792 q = rte_zmalloc_socket("fm10k", sizeof(*q), RTE_CACHE_LINE_SIZE,
795 PMD_INIT_LOG(ERR, "Cannot allocate queue structure");
800 q->nb_desc = nb_desc;
801 q->port_id = dev->data->port_id;
802 q->queue_id = queue_id;
803 q->tail_ptr = (volatile uint32_t *)
804 &((uint32_t *)hw->hw_addr)[FM10K_TDT(queue_id)];
805 if (handle_txconf(q, conf))
808 /* allocate memory for the software ring */
809 q->sw_ring = rte_zmalloc_socket("fm10k sw ring",
810 nb_desc * sizeof(struct rte_mbuf *),
811 RTE_CACHE_LINE_SIZE, socket_id);
812 if (q->sw_ring == NULL) {
813 PMD_INIT_LOG(ERR, "Cannot allocate software ring");
819 * allocate memory for the hardware descriptor ring. A memzone large
820 * enough to hold the maximum ring size is requested to allow for
821 * resizing in later calls to the queue setup function.
823 mz = allocate_hw_ring(dev->driver->pci_drv.name, "tx_ring",
824 dev->data->port_id, queue_id, socket_id,
825 FM10K_MAX_TX_RING_SZ, FM10K_ALIGN_TX_DESC);
827 PMD_INIT_LOG(ERR, "Cannot allocate hardware ring");
828 rte_free(q->sw_ring);
832 q->hw_ring = mz->addr;
833 q->hw_ring_phys_addr = mz->phys_addr;
836 * allocate memory for the RS bit tracker. Enough slots to hold the
837 * descriptor index for each RS bit needing to be set are required.
839 q->rs_tracker.list = rte_zmalloc_socket("fm10k rs tracker",
840 ((nb_desc + 1) / q->rs_thresh) *
842 RTE_CACHE_LINE_SIZE, socket_id);
843 if (q->rs_tracker.list == NULL) {
844 PMD_INIT_LOG(ERR, "Cannot allocate RS bit tracker");
845 rte_free(q->sw_ring);
850 dev->data->tx_queues[queue_id] = q;
855 fm10k_tx_queue_release(void *queue)
857 PMD_INIT_FUNC_TRACE();
859 tx_queue_free(queue);
863 fm10k_reta_update(struct rte_eth_dev *dev,
864 struct rte_eth_rss_reta_entry64 *reta_conf,
867 struct fm10k_hw *hw = FM10K_DEV_PRIVATE_TO_HW(dev->data->dev_private);
868 uint16_t i, j, idx, shift;
872 PMD_INIT_FUNC_TRACE();
874 if (reta_size > FM10K_MAX_RSS_INDICES) {
875 PMD_INIT_LOG(ERR, "The size of hash lookup table configured "
876 "(%d) doesn't match the number hardware can supported "
877 "(%d)", reta_size, FM10K_MAX_RSS_INDICES);
882 * Update Redirection Table RETA[n], n=0..31. The redirection table has
883 * 128-entries in 32 registers
885 for (i = 0; i < FM10K_MAX_RSS_INDICES; i += CHARS_PER_UINT32) {
886 idx = i / RTE_RETA_GROUP_SIZE;
887 shift = i % RTE_RETA_GROUP_SIZE;
888 mask = (uint8_t)((reta_conf[idx].mask >> shift) &
889 BIT_MASK_PER_UINT32);
894 if (mask != BIT_MASK_PER_UINT32)
895 reta = FM10K_READ_REG(hw, FM10K_RETA(0, i >> 2));
897 for (j = 0; j < CHARS_PER_UINT32; j++) {
898 if (mask & (0x1 << j)) {
900 reta &= ~(UINT8_MAX << CHAR_BIT * j);
901 reta |= reta_conf[idx].reta[shift + j] <<
905 FM10K_WRITE_REG(hw, FM10K_RETA(0, i >> 2), reta);
912 fm10k_reta_query(struct rte_eth_dev *dev,
913 struct rte_eth_rss_reta_entry64 *reta_conf,
916 struct fm10k_hw *hw = FM10K_DEV_PRIVATE_TO_HW(dev->data->dev_private);
917 uint16_t i, j, idx, shift;
921 PMD_INIT_FUNC_TRACE();
923 if (reta_size < FM10K_MAX_RSS_INDICES) {
924 PMD_INIT_LOG(ERR, "The size of hash lookup table configured "
925 "(%d) doesn't match the number hardware can supported "
926 "(%d)", reta_size, FM10K_MAX_RSS_INDICES);
931 * Read Redirection Table RETA[n], n=0..31. The redirection table has
932 * 128-entries in 32 registers
934 for (i = 0; i < FM10K_MAX_RSS_INDICES; i += CHARS_PER_UINT32) {
935 idx = i / RTE_RETA_GROUP_SIZE;
936 shift = i % RTE_RETA_GROUP_SIZE;
937 mask = (uint8_t)((reta_conf[idx].mask >> shift) &
938 BIT_MASK_PER_UINT32);
942 reta = FM10K_READ_REG(hw, FM10K_RETA(0, i >> 2));
943 for (j = 0; j < CHARS_PER_UINT32; j++) {
944 if (mask & (0x1 << j))
945 reta_conf[idx].reta[shift + j] = ((reta >>
946 CHAR_BIT * j) & UINT8_MAX);
953 /* Mailbox message handler in VF */
954 static const struct fm10k_msg_data fm10k_msgdata_vf[] = {
955 FM10K_TLV_MSG_TEST_HANDLER(fm10k_tlv_msg_test),
956 FM10K_VF_MSG_MAC_VLAN_HANDLER(fm10k_msg_mac_vlan_vf),
957 FM10K_VF_MSG_LPORT_STATE_HANDLER(fm10k_msg_lport_state_vf),
958 FM10K_TLV_MSG_ERROR_HANDLER(fm10k_tlv_msg_error),
961 /* Mailbox message handler in PF */
962 static const struct fm10k_msg_data fm10k_msgdata_pf[] = {
963 FM10K_PF_MSG_ERR_HANDLER(XCAST_MODES, fm10k_msg_err_pf),
964 FM10K_PF_MSG_ERR_HANDLER(UPDATE_MAC_FWD_RULE, fm10k_msg_err_pf),
965 FM10K_PF_MSG_LPORT_MAP_HANDLER(fm10k_msg_lport_map_pf),
966 FM10K_PF_MSG_ERR_HANDLER(LPORT_CREATE, fm10k_msg_err_pf),
967 FM10K_PF_MSG_ERR_HANDLER(LPORT_DELETE, fm10k_msg_err_pf),
968 FM10K_PF_MSG_UPDATE_PVID_HANDLER(fm10k_msg_update_pvid_pf),
969 FM10K_TLV_MSG_ERROR_HANDLER(fm10k_tlv_msg_error),
973 fm10k_setup_mbx_service(struct fm10k_hw *hw)
977 /* Initialize mailbox lock */
978 fm10k_mbx_initlock(hw);
980 /* Replace default message handler with new ones */
981 if (hw->mac.type == fm10k_mac_pf)
982 err = hw->mbx.ops.register_handlers(&hw->mbx, fm10k_msgdata_pf);
984 err = hw->mbx.ops.register_handlers(&hw->mbx, fm10k_msgdata_vf);
987 PMD_INIT_LOG(ERR, "Failed to register mailbox handler.err:%d",
991 /* Connect to SM for PF device or PF for VF device */
992 return hw->mbx.ops.connect(hw, &hw->mbx);
995 static struct eth_dev_ops fm10k_eth_dev_ops = {
996 .dev_configure = fm10k_dev_configure,
997 .stats_get = fm10k_stats_get,
998 .stats_reset = fm10k_stats_reset,
999 .link_update = fm10k_link_update,
1000 .dev_infos_get = fm10k_dev_infos_get,
1001 .rx_queue_start = fm10k_dev_rx_queue_start,
1002 .rx_queue_stop = fm10k_dev_rx_queue_stop,
1003 .tx_queue_start = fm10k_dev_tx_queue_start,
1004 .tx_queue_stop = fm10k_dev_tx_queue_stop,
1005 .rx_queue_setup = fm10k_rx_queue_setup,
1006 .rx_queue_release = fm10k_rx_queue_release,
1007 .tx_queue_setup = fm10k_tx_queue_setup,
1008 .tx_queue_release = fm10k_tx_queue_release,
1009 .reta_update = fm10k_reta_update,
1010 .reta_query = fm10k_reta_query,
1014 eth_fm10k_dev_init(__rte_unused struct eth_driver *eth_drv,
1015 struct rte_eth_dev *dev)
1017 struct fm10k_hw *hw = FM10K_DEV_PRIVATE_TO_HW(dev->data->dev_private);
1020 PMD_INIT_FUNC_TRACE();
1022 dev->dev_ops = &fm10k_eth_dev_ops;
1024 /* only initialize in the primary process */
1025 if (rte_eal_process_type() != RTE_PROC_PRIMARY)
1028 /* Vendor and Device ID need to be set before init of shared code */
1029 memset(hw, 0, sizeof(*hw));
1030 hw->device_id = dev->pci_dev->id.device_id;
1031 hw->vendor_id = dev->pci_dev->id.vendor_id;
1032 hw->subsystem_device_id = dev->pci_dev->id.subsystem_device_id;
1033 hw->subsystem_vendor_id = dev->pci_dev->id.subsystem_vendor_id;
1034 hw->revision_id = 0;
1035 hw->hw_addr = (void *)dev->pci_dev->mem_resource[0].addr;
1036 if (hw->hw_addr == NULL) {
1037 PMD_INIT_LOG(ERR, "Bad mem resource."
1038 " Try to blacklist unused devices.");
1042 /* Store fm10k_adapter pointer */
1043 hw->back = dev->data->dev_private;
1045 /* Initialize the shared code */
1046 diag = fm10k_init_shared_code(hw);
1047 if (diag != FM10K_SUCCESS) {
1048 PMD_INIT_LOG(ERR, "Shared code init failed: %d", diag);
1053 * Inialize bus info. Normally we would call fm10k_get_bus_info(), but
1054 * there is no way to get link status without reading BAR4. Until this
1055 * works, assume we have maximum bandwidth.
1056 * @todo - fix bus info
1058 hw->bus_caps.speed = fm10k_bus_speed_8000;
1059 hw->bus_caps.width = fm10k_bus_width_pcie_x8;
1060 hw->bus_caps.payload = fm10k_bus_payload_512;
1061 hw->bus.speed = fm10k_bus_speed_8000;
1062 hw->bus.width = fm10k_bus_width_pcie_x8;
1063 hw->bus.payload = fm10k_bus_payload_256;
1065 /* Initialize the hw */
1066 diag = fm10k_init_hw(hw);
1067 if (diag != FM10K_SUCCESS) {
1068 PMD_INIT_LOG(ERR, "Hardware init failed: %d", diag);
1072 /* Initialize MAC address(es) */
1073 dev->data->mac_addrs = rte_zmalloc("fm10k", ETHER_ADDR_LEN, 0);
1074 if (dev->data->mac_addrs == NULL) {
1075 PMD_INIT_LOG(ERR, "Cannot allocate memory for MAC addresses");
1079 diag = fm10k_read_mac_addr(hw);
1080 if (diag != FM10K_SUCCESS) {
1082 * TODO: remove special handling on VF. Need shared code to
1085 if (hw->mac.type == fm10k_mac_pf) {
1086 PMD_INIT_LOG(ERR, "Read MAC addr failed: %d", diag);
1089 /* Generate a random addr */
1090 eth_random_addr(hw->mac.addr);
1091 memcpy(hw->mac.perm_addr, hw->mac.addr, ETH_ALEN);
1095 ether_addr_copy((const struct ether_addr *)hw->mac.addr,
1096 &dev->data->mac_addrs[0]);
1098 /* Reset the hw statistics */
1099 fm10k_stats_reset(dev);
1102 diag = fm10k_reset_hw(hw);
1103 if (diag != FM10K_SUCCESS) {
1104 PMD_INIT_LOG(ERR, "Hardware reset failed: %d", diag);
1108 /* Setup mailbox service */
1109 diag = fm10k_setup_mbx_service(hw);
1110 if (diag != FM10K_SUCCESS) {
1111 PMD_INIT_LOG(ERR, "Failed to setup mailbox: %d", diag);
1116 * Below function will trigger operations on mailbox, acquire lock to
1117 * avoid race condition from interrupt handler. Operations on mailbox
1118 * FIFO will trigger interrupt to PF/SM, in which interrupt handler
1119 * will handle and generate an interrupt to our side. Then, FIFO in
1120 * mailbox will be touched.
1123 /* Enable port first */
1124 hw->mac.ops.update_lport_state(hw, 0, 0, 1);
1126 /* Update default vlan */
1127 hw->mac.ops.update_vlan(hw, hw->mac.default_vid, 0, true);
1130 * Add default mac/vlan filter. glort is assigned by SM for PF, while is
1131 * unused for VF. PF will assign correct glort for VF.
1133 hw->mac.ops.update_uc_addr(hw, hw->mac.dglort_map, hw->mac.addr,
1134 hw->mac.default_vid, 1, 0);
1136 /* Set unicast mode by default. App can change to other mode in other
1139 hw->mac.ops.update_xcast_mode(hw, hw->mac.dglort_map,
1140 FM10K_XCAST_MODE_MULTI);
1142 fm10k_mbx_unlock(hw);
1148 * The set of PCI devices this driver supports. This driver will enable both PF
1149 * and SRIOV-VF devices.
1151 static struct rte_pci_id pci_id_fm10k_map[] = {
1152 #define RTE_PCI_DEV_ID_DECL_FM10K(vend, dev) { RTE_PCI_DEVICE(vend, dev) },
1153 #include "rte_pci_dev_ids.h"
1154 { .vendor_id = 0, /* sentinel */ },
1157 static struct eth_driver rte_pmd_fm10k = {
1159 .name = "rte_pmd_fm10k",
1160 .id_table = pci_id_fm10k_map,
1161 .drv_flags = RTE_PCI_DRV_NEED_MAPPING,
1163 .eth_dev_init = eth_fm10k_dev_init,
1164 .dev_private_size = sizeof(struct fm10k_adapter),
1168 * Driver initialization routine.
1169 * Invoked once at EAL init time.
1170 * Register itself as the [Poll Mode] Driver of PCI FM10K devices.
1173 rte_pmd_fm10k_init(__rte_unused const char *name,
1174 __rte_unused const char *params)
1176 PMD_INIT_FUNC_TRACE();
1177 rte_eth_driver_register(&rte_pmd_fm10k);
1181 static struct rte_driver rte_fm10k_driver = {
1183 .init = rte_pmd_fm10k_init,
1186 PMD_REGISTER_DRIVER(rte_fm10k_driver);