1 /* SPDX-License-Identifier: (BSD-3-Clause OR GPL-2.0)
2 * Copyright(c) 2018-2019 Pensando Systems, Inc. All rights reserved.
5 #include <rte_malloc.h>
6 #include <rte_ethdev_driver.h>
9 #include "ionic_logs.h"
10 #include "ionic_lif.h"
11 #include "ionic_ethdev.h"
12 #include "ionic_rx_filter.h"
13 #include "ionic_rxtx.h"
15 static int ionic_lif_addr_add(struct ionic_lif *lif, const uint8_t *addr);
16 static int ionic_lif_addr_del(struct ionic_lif *lif, const uint8_t *addr);
19 ionic_qcq_enable(struct ionic_qcq *qcq)
21 struct ionic_queue *q = &qcq->q;
22 struct ionic_lif *lif = q->lif;
23 struct ionic_dev *idev = &lif->adapter->idev;
24 struct ionic_admin_ctx ctx = {
27 .opcode = IONIC_CMD_Q_CONTROL,
30 .oper = IONIC_Q_ENABLE,
34 if (qcq->flags & IONIC_QCQ_F_INTR) {
35 ionic_intr_mask(idev->intr_ctrl, qcq->intr.index,
36 IONIC_INTR_MASK_CLEAR);
39 return ionic_adminq_post_wait(lif, &ctx);
43 ionic_qcq_disable(struct ionic_qcq *qcq)
45 struct ionic_queue *q = &qcq->q;
46 struct ionic_lif *lif = q->lif;
47 struct ionic_dev *idev = &lif->adapter->idev;
48 struct ionic_admin_ctx ctx = {
51 .opcode = IONIC_CMD_Q_CONTROL,
54 .oper = IONIC_Q_DISABLE,
58 if (qcq->flags & IONIC_QCQ_F_INTR) {
59 ionic_intr_mask(idev->intr_ctrl, qcq->intr.index,
63 return ionic_adminq_post_wait(lif, &ctx);
67 ionic_lif_stop(struct ionic_lif *lif)
73 lif->state &= ~IONIC_LIF_F_UP;
75 for (i = 0; i < lif->nrxqcqs; i++) {
76 struct ionic_qcq *rxq = lif->rxqcqs[i];
77 if (rxq->flags & IONIC_QCQ_F_INITED)
78 (void)ionic_dev_rx_queue_stop(lif->eth_dev, i);
81 for (i = 0; i < lif->ntxqcqs; i++) {
82 struct ionic_qcq *txq = lif->txqcqs[i];
83 if (txq->flags & IONIC_QCQ_F_INITED)
84 (void)ionic_dev_tx_queue_stop(lif->eth_dev, i);
89 ionic_lif_reset(struct ionic_lif *lif)
91 struct ionic_dev *idev = &lif->adapter->idev;
96 ionic_dev_cmd_lif_reset(idev);
97 err = ionic_dev_cmd_wait_check(idev, IONIC_DEVCMD_TIMEOUT);
99 IONIC_PRINT(WARNING, "Failed to reset %s", lif->name);
103 ionic_lif_get_abs_stats(const struct ionic_lif *lif, struct rte_eth_stats *stats)
105 struct ionic_lif_stats *ls = &lif->info->stats;
107 uint32_t num_rx_q_counters = RTE_MIN(lif->nrxqcqs, (uint32_t)
108 RTE_ETHDEV_QUEUE_STAT_CNTRS);
109 uint32_t num_tx_q_counters = RTE_MIN(lif->ntxqcqs, (uint32_t)
110 RTE_ETHDEV_QUEUE_STAT_CNTRS);
112 memset(stats, 0, sizeof(*stats));
115 IONIC_PRINT(DEBUG, "Stats on port %u not yet initialized",
122 stats->ipackets = ls->rx_ucast_packets +
123 ls->rx_mcast_packets +
124 ls->rx_bcast_packets;
126 stats->ibytes = ls->rx_ucast_bytes +
130 for (i = 0; i < lif->nrxqcqs; i++) {
131 struct ionic_rx_stats *rx_stats = &lif->rxqcqs[i]->stats.rx;
133 rx_stats->no_cb_arg +
134 rx_stats->bad_cq_status +
140 ls->rx_ucast_drop_packets +
141 ls->rx_mcast_drop_packets +
142 ls->rx_bcast_drop_packets;
147 ls->rx_queue_disabled +
148 ls->rx_desc_fetch_error +
149 ls->rx_desc_data_error;
151 for (i = 0; i < num_rx_q_counters; i++) {
152 struct ionic_rx_stats *rx_stats = &lif->rxqcqs[i]->stats.rx;
153 stats->q_ipackets[i] = rx_stats->packets;
154 stats->q_ibytes[i] = rx_stats->bytes;
156 rx_stats->no_cb_arg +
157 rx_stats->bad_cq_status +
164 stats->opackets = ls->tx_ucast_packets +
165 ls->tx_mcast_packets +
166 ls->tx_bcast_packets;
168 stats->obytes = ls->tx_ucast_bytes +
172 for (i = 0; i < lif->ntxqcqs; i++) {
173 struct ionic_tx_stats *tx_stats = &lif->txqcqs[i]->stats.tx;
174 stats->oerrors += tx_stats->drop;
178 ls->tx_ucast_drop_packets +
179 ls->tx_mcast_drop_packets +
180 ls->tx_bcast_drop_packets;
184 ls->tx_queue_disabled +
185 ls->tx_desc_fetch_error +
186 ls->tx_desc_data_error;
188 for (i = 0; i < num_tx_q_counters; i++) {
189 struct ionic_tx_stats *tx_stats = &lif->txqcqs[i]->stats.tx;
190 stats->q_opackets[i] = tx_stats->packets;
191 stats->q_obytes[i] = tx_stats->bytes;
196 ionic_lif_get_stats(const struct ionic_lif *lif,
197 struct rte_eth_stats *stats)
199 ionic_lif_get_abs_stats(lif, stats);
201 stats->ipackets -= lif->stats_base.ipackets;
202 stats->opackets -= lif->stats_base.opackets;
203 stats->ibytes -= lif->stats_base.ibytes;
204 stats->obytes -= lif->stats_base.obytes;
205 stats->imissed -= lif->stats_base.imissed;
206 stats->ierrors -= lif->stats_base.ierrors;
207 stats->oerrors -= lif->stats_base.oerrors;
208 stats->rx_nombuf -= lif->stats_base.rx_nombuf;
212 ionic_lif_reset_stats(struct ionic_lif *lif)
216 for (i = 0; i < lif->nrxqcqs; i++) {
217 memset(&lif->rxqcqs[i]->stats.rx, 0,
218 sizeof(struct ionic_rx_stats));
219 memset(&lif->txqcqs[i]->stats.tx, 0,
220 sizeof(struct ionic_tx_stats));
223 ionic_lif_get_abs_stats(lif, &lif->stats_base);
227 ionic_lif_get_hw_stats(struct ionic_lif *lif, struct ionic_lif_stats *stats)
229 uint16_t i, count = sizeof(struct ionic_lif_stats) / sizeof(uint64_t);
230 uint64_t *stats64 = (uint64_t *)stats;
231 uint64_t *lif_stats64 = (uint64_t *)&lif->info->stats;
232 uint64_t *lif_stats64_base = (uint64_t *)&lif->lif_stats_base;
234 for (i = 0; i < count; i++)
235 stats64[i] = lif_stats64[i] - lif_stats64_base[i];
239 ionic_lif_reset_hw_stats(struct ionic_lif *lif)
241 uint16_t i, count = sizeof(struct ionic_lif_stats) / sizeof(uint64_t);
242 uint64_t *lif_stats64 = (uint64_t *)&lif->info->stats;
243 uint64_t *lif_stats64_base = (uint64_t *)&lif->lif_stats_base;
245 for (i = 0; i < count; i++)
246 lif_stats64_base[i] = lif_stats64[i];
250 ionic_lif_addr_add(struct ionic_lif *lif, const uint8_t *addr)
252 struct ionic_admin_ctx ctx = {
253 .pending_work = true,
254 .cmd.rx_filter_add = {
255 .opcode = IONIC_CMD_RX_FILTER_ADD,
256 .match = IONIC_RX_FILTER_MATCH_MAC,
261 memcpy(ctx.cmd.rx_filter_add.mac.addr, addr, RTE_ETHER_ADDR_LEN);
263 err = ionic_adminq_post_wait(lif, &ctx);
267 IONIC_PRINT(INFO, "rx_filter add (id %d)",
268 ctx.comp.rx_filter_add.filter_id);
270 return ionic_rx_filter_save(lif, 0, IONIC_RXQ_INDEX_ANY, &ctx);
274 ionic_lif_addr_del(struct ionic_lif *lif, const uint8_t *addr)
276 struct ionic_admin_ctx ctx = {
277 .pending_work = true,
278 .cmd.rx_filter_del = {
279 .opcode = IONIC_CMD_RX_FILTER_DEL,
282 struct ionic_rx_filter *f;
287 rte_spinlock_lock(&lif->rx_filters.lock);
289 f = ionic_rx_filter_by_addr(lif, addr);
291 rte_spinlock_unlock(&lif->rx_filters.lock);
295 ctx.cmd.rx_filter_del.filter_id = f->filter_id;
296 ionic_rx_filter_free(f);
298 rte_spinlock_unlock(&lif->rx_filters.lock);
300 err = ionic_adminq_post_wait(lif, &ctx);
304 IONIC_PRINT(INFO, "rx_filter del (id %d)",
305 ctx.cmd.rx_filter_del.filter_id);
311 ionic_dev_add_mac(struct rte_eth_dev *eth_dev,
312 struct rte_ether_addr *mac_addr,
313 uint32_t index __rte_unused, uint32_t pool __rte_unused)
315 struct ionic_lif *lif = IONIC_ETH_DEV_TO_LIF(eth_dev);
319 return ionic_lif_addr_add(lif, (const uint8_t *)mac_addr);
323 ionic_dev_remove_mac(struct rte_eth_dev *eth_dev, uint32_t index)
325 struct ionic_lif *lif = IONIC_ETH_DEV_TO_LIF(eth_dev);
326 struct ionic_adapter *adapter = lif->adapter;
327 struct rte_ether_addr *mac_addr;
331 if (index >= adapter->max_mac_addrs) {
333 "Index %u is above MAC filter limit %u",
334 index, adapter->max_mac_addrs);
338 mac_addr = ð_dev->data->mac_addrs[index];
340 if (!rte_is_valid_assigned_ether_addr(mac_addr))
343 ionic_lif_addr_del(lif, (const uint8_t *)mac_addr);
347 ionic_dev_set_mac(struct rte_eth_dev *eth_dev, struct rte_ether_addr *mac_addr)
349 struct ionic_lif *lif = IONIC_ETH_DEV_TO_LIF(eth_dev);
353 if (mac_addr == NULL) {
354 IONIC_PRINT(NOTICE, "New mac is null");
358 if (!rte_is_zero_ether_addr((struct rte_ether_addr *)lif->mac_addr)) {
359 IONIC_PRINT(INFO, "Deleting mac addr %pM",
361 ionic_lif_addr_del(lif, lif->mac_addr);
362 memset(lif->mac_addr, 0, RTE_ETHER_ADDR_LEN);
365 IONIC_PRINT(INFO, "Updating mac addr");
367 rte_ether_addr_copy(mac_addr, (struct rte_ether_addr *)lif->mac_addr);
369 return ionic_lif_addr_add(lif, (const uint8_t *)mac_addr);
373 ionic_vlan_rx_add_vid(struct ionic_lif *lif, uint16_t vid)
375 struct ionic_admin_ctx ctx = {
376 .pending_work = true,
377 .cmd.rx_filter_add = {
378 .opcode = IONIC_CMD_RX_FILTER_ADD,
379 .match = IONIC_RX_FILTER_MATCH_VLAN,
385 err = ionic_adminq_post_wait(lif, &ctx);
389 IONIC_PRINT(INFO, "rx_filter add VLAN %d (id %d)", vid,
390 ctx.comp.rx_filter_add.filter_id);
392 return ionic_rx_filter_save(lif, 0, IONIC_RXQ_INDEX_ANY, &ctx);
396 ionic_vlan_rx_kill_vid(struct ionic_lif *lif, uint16_t vid)
398 struct ionic_admin_ctx ctx = {
399 .pending_work = true,
400 .cmd.rx_filter_del = {
401 .opcode = IONIC_CMD_RX_FILTER_DEL,
404 struct ionic_rx_filter *f;
409 rte_spinlock_lock(&lif->rx_filters.lock);
411 f = ionic_rx_filter_by_vlan(lif, vid);
413 rte_spinlock_unlock(&lif->rx_filters.lock);
417 ctx.cmd.rx_filter_del.filter_id = f->filter_id;
418 ionic_rx_filter_free(f);
419 rte_spinlock_unlock(&lif->rx_filters.lock);
421 err = ionic_adminq_post_wait(lif, &ctx);
425 IONIC_PRINT(INFO, "rx_filter del VLAN %d (id %d)", vid,
426 ctx.cmd.rx_filter_del.filter_id);
432 ionic_dev_vlan_filter_set(struct rte_eth_dev *eth_dev, uint16_t vlan_id,
435 struct ionic_lif *lif = IONIC_ETH_DEV_TO_LIF(eth_dev);
439 err = ionic_vlan_rx_add_vid(lif, vlan_id);
441 err = ionic_vlan_rx_kill_vid(lif, vlan_id);
447 ionic_lif_rx_mode(struct ionic_lif *lif, uint32_t rx_mode)
449 struct ionic_admin_ctx ctx = {
450 .pending_work = true,
452 .opcode = IONIC_CMD_RX_MODE_SET,
458 if (rx_mode & IONIC_RX_MODE_F_UNICAST)
459 IONIC_PRINT(DEBUG, "rx_mode IONIC_RX_MODE_F_UNICAST");
460 if (rx_mode & IONIC_RX_MODE_F_MULTICAST)
461 IONIC_PRINT(DEBUG, "rx_mode IONIC_RX_MODE_F_MULTICAST");
462 if (rx_mode & IONIC_RX_MODE_F_BROADCAST)
463 IONIC_PRINT(DEBUG, "rx_mode IONIC_RX_MODE_F_BROADCAST");
464 if (rx_mode & IONIC_RX_MODE_F_PROMISC)
465 IONIC_PRINT(DEBUG, "rx_mode IONIC_RX_MODE_F_PROMISC");
466 if (rx_mode & IONIC_RX_MODE_F_ALLMULTI)
467 IONIC_PRINT(DEBUG, "rx_mode IONIC_RX_MODE_F_ALLMULTI");
469 err = ionic_adminq_post_wait(lif, &ctx);
471 IONIC_PRINT(ERR, "Failure setting RX mode");
475 ionic_set_rx_mode(struct ionic_lif *lif, uint32_t rx_mode)
477 if (lif->rx_mode != rx_mode) {
478 lif->rx_mode = rx_mode;
479 ionic_lif_rx_mode(lif, rx_mode);
484 ionic_dev_promiscuous_enable(struct rte_eth_dev *eth_dev)
486 struct ionic_lif *lif = IONIC_ETH_DEV_TO_LIF(eth_dev);
487 uint32_t rx_mode = lif->rx_mode;
491 rx_mode |= IONIC_RX_MODE_F_PROMISC;
493 ionic_set_rx_mode(lif, rx_mode);
499 ionic_dev_promiscuous_disable(struct rte_eth_dev *eth_dev)
501 struct ionic_lif *lif = IONIC_ETH_DEV_TO_LIF(eth_dev);
502 uint32_t rx_mode = lif->rx_mode;
504 rx_mode &= ~IONIC_RX_MODE_F_PROMISC;
506 ionic_set_rx_mode(lif, rx_mode);
512 ionic_dev_allmulticast_enable(struct rte_eth_dev *eth_dev)
514 struct ionic_lif *lif = IONIC_ETH_DEV_TO_LIF(eth_dev);
515 uint32_t rx_mode = lif->rx_mode;
517 rx_mode |= IONIC_RX_MODE_F_ALLMULTI;
519 ionic_set_rx_mode(lif, rx_mode);
525 ionic_dev_allmulticast_disable(struct rte_eth_dev *eth_dev)
527 struct ionic_lif *lif = IONIC_ETH_DEV_TO_LIF(eth_dev);
528 uint32_t rx_mode = lif->rx_mode;
530 rx_mode &= ~IONIC_RX_MODE_F_ALLMULTI;
532 ionic_set_rx_mode(lif, rx_mode);
538 ionic_lif_change_mtu(struct ionic_lif *lif, int new_mtu)
540 struct ionic_admin_ctx ctx = {
541 .pending_work = true,
543 .opcode = IONIC_CMD_LIF_SETATTR,
544 .attr = IONIC_LIF_ATTR_MTU,
550 err = ionic_adminq_post_wait(lif, &ctx);
558 ionic_intr_alloc(struct ionic_lif *lif, struct ionic_intr_info *intr)
560 struct ionic_adapter *adapter = lif->adapter;
561 struct ionic_dev *idev = &adapter->idev;
565 * Note: interrupt handler is called for index = 0 only
566 * (we use interrupts for the notifyq only anyway,
567 * which has index = 0)
570 for (index = 0; index < adapter->nintrs; index++)
571 if (!adapter->intrs[index])
574 if (index == adapter->nintrs)
577 adapter->intrs[index] = true;
579 ionic_intr_init(idev, intr, index);
585 ionic_intr_free(struct ionic_lif *lif, struct ionic_intr_info *intr)
587 if (intr->index != IONIC_INTR_INDEX_NOT_ASSIGNED)
588 lif->adapter->intrs[intr->index] = false;
592 ionic_qcq_alloc(struct ionic_lif *lif, uint8_t type,
594 const char *base, uint32_t flags,
597 uint32_t cq_desc_size,
598 uint32_t sg_desc_size,
599 struct ionic_qcq **qcq)
601 struct ionic_dev *idev = &lif->adapter->idev;
602 struct ionic_qcq *new;
603 uint32_t q_size, cq_size, sg_size, total_size;
604 void *q_base, *cq_base, *sg_base;
605 rte_iova_t q_base_pa = 0;
606 rte_iova_t cq_base_pa = 0;
607 rte_iova_t sg_base_pa = 0;
608 uint32_t socket_id = rte_socket_id();
613 q_size = num_descs * desc_size;
614 cq_size = num_descs * cq_desc_size;
615 sg_size = num_descs * sg_desc_size;
617 total_size = RTE_ALIGN(q_size, PAGE_SIZE) +
618 RTE_ALIGN(cq_size, PAGE_SIZE);
620 * Note: aligning q_size/cq_size is not enough due to cq_base address
621 * aligning as q_base could be not aligned to the page.
624 total_size += PAGE_SIZE;
626 if (flags & IONIC_QCQ_F_SG) {
627 total_size += RTE_ALIGN(sg_size, PAGE_SIZE);
628 total_size += PAGE_SIZE;
631 new = rte_zmalloc("ionic", sizeof(*new), 0);
633 IONIC_PRINT(ERR, "Cannot allocate queue structure");
640 new->q.info = rte_zmalloc("ionic", sizeof(*new->q.info) * num_descs, 0);
642 IONIC_PRINT(ERR, "Cannot allocate queue info");
648 err = ionic_q_init(lif, idev, &new->q, index, num_descs,
649 desc_size, sg_desc_size);
651 IONIC_PRINT(ERR, "Queue initialization failed");
655 if (flags & IONIC_QCQ_F_INTR) {
656 err = ionic_intr_alloc(lif, &new->intr);
660 ionic_intr_mask_assert(idev->intr_ctrl, new->intr.index,
661 IONIC_INTR_MASK_SET);
663 new->intr.index = IONIC_INTR_INDEX_NOT_ASSIGNED;
666 err = ionic_cq_init(lif, &new->cq, &new->intr,
667 num_descs, cq_desc_size);
669 IONIC_PRINT(ERR, "Completion queue initialization failed");
670 goto err_out_free_intr;
673 new->base_z = rte_eth_dma_zone_reserve(lif->eth_dev,
674 base /* name */, index /* queue_idx */,
675 total_size, IONIC_ALIGN, socket_id);
678 IONIC_PRINT(ERR, "Cannot reserve queue DMA memory");
680 goto err_out_free_intr;
683 new->base = new->base_z->addr;
684 new->base_pa = new->base_z->iova;
685 new->total_size = total_size;
688 q_base_pa = new->base_pa;
690 cq_base = (void *)RTE_ALIGN((uintptr_t)q_base + q_size, PAGE_SIZE);
691 cq_base_pa = RTE_ALIGN(q_base_pa + q_size, PAGE_SIZE);
693 if (flags & IONIC_QCQ_F_SG) {
694 sg_base = (void *)RTE_ALIGN((uintptr_t)cq_base + cq_size,
696 sg_base_pa = RTE_ALIGN(cq_base_pa + cq_size, PAGE_SIZE);
697 ionic_q_sg_map(&new->q, sg_base, sg_base_pa);
700 IONIC_PRINT(DEBUG, "Q-Base-PA = %#jx CQ-Base-PA = %#jx "
702 q_base_pa, cq_base_pa, sg_base_pa);
704 ionic_q_map(&new->q, q_base, q_base_pa);
705 ionic_cq_map(&new->cq, cq_base, cq_base_pa);
706 ionic_cq_bind(&new->cq, &new->q);
713 if (flags & IONIC_QCQ_F_INTR)
714 ionic_intr_free(lif, &new->intr);
720 ionic_qcq_free(struct ionic_qcq *qcq)
725 rte_memzone_free(qcq->base_z);
730 rte_free(qcq->q.info);
738 ionic_rx_qcq_alloc(struct ionic_lif *lif, uint32_t index, uint16_t nrxq_descs,
739 struct ionic_qcq **qcq)
744 flags = IONIC_QCQ_F_SG;
745 err = ionic_qcq_alloc(lif, IONIC_QTYPE_RXQ, index, "rx", flags,
747 sizeof(struct ionic_rxq_desc),
748 sizeof(struct ionic_rxq_comp),
749 sizeof(struct ionic_rxq_sg_desc),
750 &lif->rxqcqs[index]);
754 *qcq = lif->rxqcqs[index];
760 ionic_tx_qcq_alloc(struct ionic_lif *lif, uint32_t index, uint16_t ntxq_descs,
761 struct ionic_qcq **qcq)
766 flags = IONIC_QCQ_F_SG;
767 err = ionic_qcq_alloc(lif, IONIC_QTYPE_TXQ, index, "tx", flags,
769 sizeof(struct ionic_txq_desc),
770 sizeof(struct ionic_txq_comp),
771 sizeof(struct ionic_txq_sg_desc),
772 &lif->txqcqs[index]);
776 *qcq = lif->txqcqs[index];
782 ionic_admin_qcq_alloc(struct ionic_lif *lif)
788 err = ionic_qcq_alloc(lif, IONIC_QTYPE_ADMINQ, 0, "admin", flags,
790 sizeof(struct ionic_admin_cmd),
791 sizeof(struct ionic_admin_comp),
801 ionic_notify_qcq_alloc(struct ionic_lif *lif)
806 flags = IONIC_QCQ_F_NOTIFYQ | IONIC_QCQ_F_INTR;
808 err = ionic_qcq_alloc(lif, IONIC_QTYPE_NOTIFYQ, 0, "notify",
810 IONIC_NOTIFYQ_LENGTH,
811 sizeof(struct ionic_notifyq_cmd),
812 sizeof(union ionic_notifyq_comp),
822 ionic_bus_map_dbpage(struct ionic_adapter *adapter, int page_num)
824 char *vaddr = adapter->bars[IONIC_PCI_BAR_DBELL].vaddr;
826 if (adapter->num_bars <= IONIC_PCI_BAR_DBELL)
829 return (void *)&vaddr[page_num << PAGE_SHIFT];
833 ionic_lif_alloc(struct ionic_lif *lif)
835 struct ionic_adapter *adapter = lif->adapter;
836 uint32_t socket_id = rte_socket_id();
840 * lif->name was zeroed on allocation.
841 * Copy (sizeof() - 1) bytes to ensure that it is NULL terminated.
843 memcpy(lif->name, lif->eth_dev->data->name, sizeof(lif->name) - 1);
845 IONIC_PRINT(DEBUG, "LIF: %s", lif->name);
847 IONIC_PRINT(DEBUG, "Allocating Lif Info");
849 rte_spinlock_init(&lif->adminq_lock);
850 rte_spinlock_init(&lif->adminq_service_lock);
852 lif->kern_dbpage = ionic_bus_map_dbpage(adapter, 0);
853 if (!lif->kern_dbpage) {
854 IONIC_PRINT(ERR, "Cannot map dbpage, aborting");
858 lif->txqcqs = rte_zmalloc("ionic", sizeof(*lif->txqcqs) *
859 adapter->max_ntxqs_per_lif, 0);
862 IONIC_PRINT(ERR, "Cannot allocate tx queues array");
866 lif->rxqcqs = rte_zmalloc("ionic", sizeof(*lif->rxqcqs) *
867 adapter->max_nrxqs_per_lif, 0);
870 IONIC_PRINT(ERR, "Cannot allocate rx queues array");
874 IONIC_PRINT(DEBUG, "Allocating Notify Queue");
876 err = ionic_notify_qcq_alloc(lif);
878 IONIC_PRINT(ERR, "Cannot allocate notify queue");
882 IONIC_PRINT(DEBUG, "Allocating Admin Queue");
884 err = ionic_admin_qcq_alloc(lif);
886 IONIC_PRINT(ERR, "Cannot allocate admin queue");
890 IONIC_PRINT(DEBUG, "Allocating Lif Info");
892 lif->info_sz = RTE_ALIGN(sizeof(*lif->info), PAGE_SIZE);
894 lif->info_z = rte_eth_dma_zone_reserve(lif->eth_dev,
895 "lif_info", 0 /* queue_idx*/,
896 lif->info_sz, IONIC_ALIGN, socket_id);
898 IONIC_PRINT(ERR, "Cannot allocate lif info memory");
902 lif->info = lif->info_z->addr;
903 lif->info_pa = lif->info_z->iova;
909 ionic_lif_free(struct ionic_lif *lif)
911 if (lif->notifyqcq) {
912 ionic_qcq_free(lif->notifyqcq);
913 lif->notifyqcq = NULL;
917 ionic_qcq_free(lif->adminqcq);
918 lif->adminqcq = NULL;
922 rte_free(lif->txqcqs);
927 rte_free(lif->rxqcqs);
932 rte_memzone_free(lif->info_z);
938 ionic_lif_free_queues(struct ionic_lif *lif)
942 for (i = 0; i < lif->ntxqcqs; i++) {
943 ionic_dev_tx_queue_release(lif->eth_dev->data->tx_queues[i]);
944 lif->eth_dev->data->tx_queues[i] = NULL;
946 for (i = 0; i < lif->nrxqcqs; i++) {
947 ionic_dev_rx_queue_release(lif->eth_dev->data->rx_queues[i]);
948 lif->eth_dev->data->rx_queues[i] = NULL;
953 ionic_lif_rss_config(struct ionic_lif *lif,
954 const uint16_t types, const uint8_t *key, const uint32_t *indir)
956 struct ionic_admin_ctx ctx = {
957 .pending_work = true,
959 .opcode = IONIC_CMD_LIF_SETATTR,
960 .attr = IONIC_LIF_ATTR_RSS,
962 .rss.addr = lif->rss_ind_tbl_pa,
969 lif->rss_types = types;
972 memcpy(lif->rss_hash_key, key, IONIC_RSS_HASH_KEY_SIZE);
975 for (i = 0; i < lif->adapter->ident.lif.eth.rss_ind_tbl_sz; i++)
976 lif->rss_ind_tbl[i] = indir[i];
978 memcpy(ctx.cmd.lif_setattr.rss.key, lif->rss_hash_key,
979 IONIC_RSS_HASH_KEY_SIZE);
981 return ionic_adminq_post_wait(lif, &ctx);
985 ionic_lif_rss_setup(struct ionic_lif *lif)
987 static const uint8_t toeplitz_symmetric_key[] = {
988 0x6D, 0x5A, 0x6D, 0x5A, 0x6D, 0x5A, 0x6D, 0x5A,
989 0x6D, 0x5A, 0x6D, 0x5A, 0x6D, 0x5A, 0x6D, 0x5A,
990 0x6D, 0x5A, 0x6D, 0x5A, 0x6D, 0x5A, 0x6D, 0x5A,
991 0x6D, 0x5A, 0x6D, 0x5A, 0x6D, 0x5A, 0x6D, 0x5A,
992 0x6D, 0x5A, 0x6D, 0x5A, 0x6D, 0x5A, 0x6D, 0x5A,
995 uint16_t tbl_sz = lif->adapter->ident.lif.eth.rss_ind_tbl_sz;
999 if (!lif->rss_ind_tbl_z) {
1000 lif->rss_ind_tbl_z = rte_eth_dma_zone_reserve(lif->eth_dev,
1001 "rss_ind_tbl", 0 /* queue_idx */,
1002 sizeof(*lif->rss_ind_tbl) * tbl_sz,
1003 IONIC_ALIGN, rte_socket_id());
1004 if (!lif->rss_ind_tbl_z) {
1005 IONIC_PRINT(ERR, "OOM");
1009 lif->rss_ind_tbl = lif->rss_ind_tbl_z->addr;
1010 lif->rss_ind_tbl_pa = lif->rss_ind_tbl_z->iova;
1013 if (lif->rss_ind_tbl_nrxqcqs != lif->nrxqcqs) {
1014 lif->rss_ind_tbl_nrxqcqs = lif->nrxqcqs;
1016 /* Fill indirection table with 'default' values */
1017 for (i = 0; i < tbl_sz; i++)
1018 lif->rss_ind_tbl[i] = i % lif->nrxqcqs;
1021 return ionic_lif_rss_config(lif, IONIC_RSS_OFFLOAD_ALL,
1022 toeplitz_symmetric_key, NULL);
1026 ionic_lif_rss_teardown(struct ionic_lif *lif)
1028 if (!lif->rss_ind_tbl)
1031 if (lif->rss_ind_tbl_z) {
1032 /* Disable RSS on the NIC */
1033 ionic_lif_rss_config(lif, 0x0, NULL, NULL);
1035 lif->rss_ind_tbl = NULL;
1036 lif->rss_ind_tbl_pa = 0;
1037 rte_memzone_free(lif->rss_ind_tbl_z);
1038 lif->rss_ind_tbl_z = NULL;
1043 ionic_lif_qcq_deinit(struct ionic_lif *lif, struct ionic_qcq *qcq)
1045 struct ionic_dev *idev = &lif->adapter->idev;
1047 if (!(qcq->flags & IONIC_QCQ_F_INITED))
1050 if (qcq->flags & IONIC_QCQ_F_INTR)
1051 ionic_intr_mask(idev->intr_ctrl, qcq->intr.index,
1052 IONIC_INTR_MASK_SET);
1054 qcq->flags &= ~IONIC_QCQ_F_INITED;
1058 ionic_lif_txq_deinit(struct ionic_qcq *qcq)
1060 ionic_lif_qcq_deinit(qcq->lif, qcq);
1064 ionic_lif_rxq_deinit(struct ionic_qcq *qcq)
1066 ionic_lif_qcq_deinit(qcq->lif, qcq);
1070 ionic_adminq_service(struct ionic_cq *cq, uint32_t cq_desc_index,
1071 void *cb_arg __rte_unused)
1073 struct ionic_admin_comp *cq_desc_base = cq->base;
1074 struct ionic_admin_comp *cq_desc = &cq_desc_base[cq_desc_index];
1076 if (!color_match(cq_desc->color, cq->done_color))
1079 ionic_q_service(cq->bound_q, cq_desc_index, cq_desc->comp_index, NULL);
1084 /* This acts like ionic_napi */
1086 ionic_qcq_service(struct ionic_qcq *qcq, int budget, ionic_cq_cb cb,
1089 struct ionic_cq *cq = &qcq->cq;
1092 work_done = ionic_cq_service(cq, budget, cb, cb_arg);
1098 ionic_link_status_check(struct ionic_lif *lif)
1100 struct ionic_adapter *adapter = lif->adapter;
1103 lif->state &= ~IONIC_LIF_F_LINK_CHECK_NEEDED;
1108 link_up = (lif->info->status.link_status == IONIC_PORT_OPER_STATUS_UP);
1110 if ((link_up && adapter->link_up) ||
1111 (!link_up && !adapter->link_up))
1115 adapter->link_speed = lif->info->status.link_speed;
1116 IONIC_PRINT(DEBUG, "Link up - %d Gbps",
1117 adapter->link_speed);
1119 IONIC_PRINT(DEBUG, "Link down");
1122 adapter->link_up = link_up;
1123 ionic_dev_link_update(lif->eth_dev, 0);
1127 ionic_lif_handle_fw_down(struct ionic_lif *lif)
1129 if (lif->state & IONIC_LIF_F_FW_RESET)
1132 lif->state |= IONIC_LIF_F_FW_RESET;
1134 if (lif->state & IONIC_LIF_F_UP) {
1136 "Surprise FW stop, stopping %s\n", lif->name);
1137 ionic_lif_stop(lif);
1140 IONIC_PRINT(NOTICE, "FW down, %s stopped", lif->name);
1144 ionic_notifyq_cb(struct ionic_cq *cq, uint32_t cq_desc_index, void *cb_arg)
1146 union ionic_notifyq_comp *cq_desc_base = cq->base;
1147 union ionic_notifyq_comp *cq_desc = &cq_desc_base[cq_desc_index];
1148 struct ionic_lif *lif = cb_arg;
1150 IONIC_PRINT(DEBUG, "Notifyq callback eid = %jd ecode = %d",
1151 cq_desc->event.eid, cq_desc->event.ecode);
1153 /* Have we run out of new completions to process? */
1154 if (!(cq_desc->event.eid > lif->last_eid))
1157 lif->last_eid = cq_desc->event.eid;
1159 switch (cq_desc->event.ecode) {
1160 case IONIC_EVENT_LINK_CHANGE:
1162 "Notifyq IONIC_EVENT_LINK_CHANGE %s "
1163 "eid=%jd link_status=%d link_speed=%d",
1166 cq_desc->link_change.link_status,
1167 cq_desc->link_change.link_speed);
1169 lif->state |= IONIC_LIF_F_LINK_CHECK_NEEDED;
1172 case IONIC_EVENT_RESET:
1174 "Notifyq IONIC_EVENT_RESET %s "
1175 "eid=%jd, reset_code=%d state=%d",
1178 cq_desc->reset.reset_code,
1179 cq_desc->reset.state);
1180 ionic_lif_handle_fw_down(lif);
1184 IONIC_PRINT(WARNING, "Notifyq bad event ecode=%d eid=%jd",
1185 cq_desc->event.ecode, cq_desc->event.eid);
1193 ionic_notifyq_handler(struct ionic_lif *lif, int budget)
1195 struct ionic_dev *idev = &lif->adapter->idev;
1196 struct ionic_qcq *qcq = lif->notifyqcq;
1199 if (!(qcq->flags & IONIC_QCQ_F_INITED)) {
1200 IONIC_PRINT(DEBUG, "Notifyq not yet initialized");
1204 ionic_intr_mask(idev->intr_ctrl, qcq->intr.index,
1205 IONIC_INTR_MASK_SET);
1207 work_done = ionic_qcq_service(qcq, budget, ionic_notifyq_cb, lif);
1209 if (lif->state & IONIC_LIF_F_LINK_CHECK_NEEDED)
1210 ionic_link_status_check(lif);
1212 ionic_intr_credits(idev->intr_ctrl, qcq->intr.index,
1213 work_done, IONIC_INTR_CRED_RESET_COALESCE);
1215 ionic_intr_mask(idev->intr_ctrl, qcq->intr.index,
1216 IONIC_INTR_MASK_CLEAR);
1222 ionic_lif_adminq_init(struct ionic_lif *lif)
1224 struct ionic_dev *idev = &lif->adapter->idev;
1225 struct ionic_qcq *qcq = lif->adminqcq;
1226 struct ionic_queue *q = &qcq->q;
1227 struct ionic_q_init_comp comp;
1230 ionic_dev_cmd_adminq_init(idev, qcq, qcq->intr.index);
1231 err = ionic_dev_cmd_wait_check(idev, IONIC_DEVCMD_TIMEOUT);
1235 ionic_dev_cmd_comp(idev, &comp);
1237 q->hw_type = comp.hw_type;
1238 q->hw_index = comp.hw_index;
1239 q->db = ionic_db_map(lif, q);
1241 IONIC_PRINT(DEBUG, "adminq->hw_type %d", q->hw_type);
1242 IONIC_PRINT(DEBUG, "adminq->hw_index %d", q->hw_index);
1243 IONIC_PRINT(DEBUG, "adminq->db %p", q->db);
1245 if (qcq->flags & IONIC_QCQ_F_INTR)
1246 ionic_intr_mask(idev->intr_ctrl, qcq->intr.index,
1247 IONIC_INTR_MASK_CLEAR);
1249 qcq->flags |= IONIC_QCQ_F_INITED;
1255 ionic_lif_notifyq_init(struct ionic_lif *lif)
1257 struct ionic_dev *idev = &lif->adapter->idev;
1258 struct ionic_qcq *qcq = lif->notifyqcq;
1259 struct ionic_queue *q = &qcq->q;
1262 struct ionic_admin_ctx ctx = {
1263 .pending_work = true,
1265 .opcode = IONIC_CMD_Q_INIT,
1268 .flags = (IONIC_QINIT_F_IRQ | IONIC_QINIT_F_ENA),
1269 .intr_index = qcq->intr.index,
1270 .ring_size = rte_log2_u32(q->num_descs),
1271 .ring_base = q->base_pa,
1275 IONIC_PRINT(DEBUG, "notifyq_init.index %d",
1276 ctx.cmd.q_init.index);
1277 IONIC_PRINT(DEBUG, "notifyq_init.ring_base 0x%" PRIx64 "",
1278 ctx.cmd.q_init.ring_base);
1279 IONIC_PRINT(DEBUG, "notifyq_init.ring_size %d",
1280 ctx.cmd.q_init.ring_size);
1281 IONIC_PRINT(DEBUG, "notifyq_init.ver %u", ctx.cmd.q_init.ver);
1283 err = ionic_adminq_post_wait(lif, &ctx);
1287 q->hw_type = ctx.comp.q_init.hw_type;
1288 q->hw_index = ctx.comp.q_init.hw_index;
1291 IONIC_PRINT(DEBUG, "notifyq->hw_type %d", q->hw_type);
1292 IONIC_PRINT(DEBUG, "notifyq->hw_index %d", q->hw_index);
1293 IONIC_PRINT(DEBUG, "notifyq->db %p", q->db);
1295 if (qcq->flags & IONIC_QCQ_F_INTR)
1296 ionic_intr_mask(idev->intr_ctrl, qcq->intr.index,
1297 IONIC_INTR_MASK_CLEAR);
1299 qcq->flags |= IONIC_QCQ_F_INITED;
1305 ionic_lif_set_features(struct ionic_lif *lif)
1307 struct ionic_admin_ctx ctx = {
1308 .pending_work = true,
1309 .cmd.lif_setattr = {
1310 .opcode = IONIC_CMD_LIF_SETATTR,
1311 .attr = IONIC_LIF_ATTR_FEATURES,
1312 .features = lif->features,
1317 err = ionic_adminq_post_wait(lif, &ctx);
1321 lif->hw_features = (ctx.cmd.lif_setattr.features &
1322 ctx.comp.lif_setattr.features);
1324 if (lif->hw_features & IONIC_ETH_HW_VLAN_TX_TAG)
1325 IONIC_PRINT(DEBUG, "feature IONIC_ETH_HW_VLAN_TX_TAG");
1326 if (lif->hw_features & IONIC_ETH_HW_VLAN_RX_STRIP)
1327 IONIC_PRINT(DEBUG, "feature IONIC_ETH_HW_VLAN_RX_STRIP");
1328 if (lif->hw_features & IONIC_ETH_HW_VLAN_RX_FILTER)
1329 IONIC_PRINT(DEBUG, "feature IONIC_ETH_HW_VLAN_RX_FILTER");
1330 if (lif->hw_features & IONIC_ETH_HW_RX_HASH)
1331 IONIC_PRINT(DEBUG, "feature IONIC_ETH_HW_RX_HASH");
1332 if (lif->hw_features & IONIC_ETH_HW_TX_SG)
1333 IONIC_PRINT(DEBUG, "feature IONIC_ETH_HW_TX_SG");
1334 if (lif->hw_features & IONIC_ETH_HW_RX_SG)
1335 IONIC_PRINT(DEBUG, "feature IONIC_ETH_HW_RX_SG");
1336 if (lif->hw_features & IONIC_ETH_HW_TX_CSUM)
1337 IONIC_PRINT(DEBUG, "feature IONIC_ETH_HW_TX_CSUM");
1338 if (lif->hw_features & IONIC_ETH_HW_RX_CSUM)
1339 IONIC_PRINT(DEBUG, "feature IONIC_ETH_HW_RX_CSUM");
1340 if (lif->hw_features & IONIC_ETH_HW_TSO)
1341 IONIC_PRINT(DEBUG, "feature IONIC_ETH_HW_TSO");
1342 if (lif->hw_features & IONIC_ETH_HW_TSO_IPV6)
1343 IONIC_PRINT(DEBUG, "feature IONIC_ETH_HW_TSO_IPV6");
1344 if (lif->hw_features & IONIC_ETH_HW_TSO_ECN)
1345 IONIC_PRINT(DEBUG, "feature IONIC_ETH_HW_TSO_ECN");
1346 if (lif->hw_features & IONIC_ETH_HW_TSO_GRE)
1347 IONIC_PRINT(DEBUG, "feature IONIC_ETH_HW_TSO_GRE");
1348 if (lif->hw_features & IONIC_ETH_HW_TSO_GRE_CSUM)
1349 IONIC_PRINT(DEBUG, "feature IONIC_ETH_HW_TSO_GRE_CSUM");
1350 if (lif->hw_features & IONIC_ETH_HW_TSO_IPXIP4)
1351 IONIC_PRINT(DEBUG, "feature IONIC_ETH_HW_TSO_IPXIP4");
1352 if (lif->hw_features & IONIC_ETH_HW_TSO_IPXIP6)
1353 IONIC_PRINT(DEBUG, "feature IONIC_ETH_HW_TSO_IPXIP6");
1354 if (lif->hw_features & IONIC_ETH_HW_TSO_UDP)
1355 IONIC_PRINT(DEBUG, "feature IONIC_ETH_HW_TSO_UDP");
1356 if (lif->hw_features & IONIC_ETH_HW_TSO_UDP_CSUM)
1357 IONIC_PRINT(DEBUG, "feature IONIC_ETH_HW_TSO_UDP_CSUM");
1363 ionic_lif_txq_init(struct ionic_qcq *qcq)
1365 struct ionic_queue *q = &qcq->q;
1366 struct ionic_lif *lif = qcq->lif;
1367 struct ionic_cq *cq = &qcq->cq;
1368 struct ionic_admin_ctx ctx = {
1369 .pending_work = true,
1371 .opcode = IONIC_CMD_Q_INIT,
1374 .flags = IONIC_QINIT_F_SG,
1375 .intr_index = cq->bound_intr->index,
1376 .ring_size = rte_log2_u32(q->num_descs),
1377 .ring_base = q->base_pa,
1378 .cq_ring_base = cq->base_pa,
1379 .sg_ring_base = q->sg_base_pa,
1384 IONIC_PRINT(DEBUG, "txq_init.index %d", ctx.cmd.q_init.index);
1385 IONIC_PRINT(DEBUG, "txq_init.ring_base 0x%" PRIx64 "",
1386 ctx.cmd.q_init.ring_base);
1387 IONIC_PRINT(DEBUG, "txq_init.ring_size %d",
1388 ctx.cmd.q_init.ring_size);
1389 IONIC_PRINT(DEBUG, "txq_init.ver %u", ctx.cmd.q_init.ver);
1391 err = ionic_adminq_post_wait(qcq->lif, &ctx);
1395 q->hw_type = ctx.comp.q_init.hw_type;
1396 q->hw_index = ctx.comp.q_init.hw_index;
1397 q->db = ionic_db_map(lif, q);
1399 IONIC_PRINT(DEBUG, "txq->hw_type %d", q->hw_type);
1400 IONIC_PRINT(DEBUG, "txq->hw_index %d", q->hw_index);
1401 IONIC_PRINT(DEBUG, "txq->db %p", q->db);
1403 qcq->flags |= IONIC_QCQ_F_INITED;
1409 ionic_lif_rxq_init(struct ionic_qcq *qcq)
1411 struct ionic_queue *q = &qcq->q;
1412 struct ionic_lif *lif = qcq->lif;
1413 struct ionic_cq *cq = &qcq->cq;
1414 struct ionic_admin_ctx ctx = {
1415 .pending_work = true,
1417 .opcode = IONIC_CMD_Q_INIT,
1420 .flags = IONIC_QINIT_F_SG,
1421 .intr_index = cq->bound_intr->index,
1422 .ring_size = rte_log2_u32(q->num_descs),
1423 .ring_base = q->base_pa,
1424 .cq_ring_base = cq->base_pa,
1425 .sg_ring_base = q->sg_base_pa,
1430 IONIC_PRINT(DEBUG, "rxq_init.index %d", ctx.cmd.q_init.index);
1431 IONIC_PRINT(DEBUG, "rxq_init.ring_base 0x%" PRIx64 "",
1432 ctx.cmd.q_init.ring_base);
1433 IONIC_PRINT(DEBUG, "rxq_init.ring_size %d",
1434 ctx.cmd.q_init.ring_size);
1435 IONIC_PRINT(DEBUG, "rxq_init.ver %u", ctx.cmd.q_init.ver);
1437 err = ionic_adminq_post_wait(qcq->lif, &ctx);
1441 q->hw_type = ctx.comp.q_init.hw_type;
1442 q->hw_index = ctx.comp.q_init.hw_index;
1443 q->db = ionic_db_map(lif, q);
1445 qcq->flags |= IONIC_QCQ_F_INITED;
1447 IONIC_PRINT(DEBUG, "rxq->hw_type %d", q->hw_type);
1448 IONIC_PRINT(DEBUG, "rxq->hw_index %d", q->hw_index);
1449 IONIC_PRINT(DEBUG, "rxq->db %p", q->db);
1455 ionic_station_set(struct ionic_lif *lif)
1457 struct ionic_admin_ctx ctx = {
1458 .pending_work = true,
1459 .cmd.lif_getattr = {
1460 .opcode = IONIC_CMD_LIF_GETATTR,
1461 .attr = IONIC_LIF_ATTR_MAC,
1468 err = ionic_adminq_post_wait(lif, &ctx);
1472 if (!rte_is_zero_ether_addr((struct rte_ether_addr *)
1474 IONIC_PRINT(INFO, "deleting station MAC addr");
1476 ionic_lif_addr_del(lif, lif->mac_addr);
1479 memcpy(lif->mac_addr, ctx.comp.lif_getattr.mac, RTE_ETHER_ADDR_LEN);
1481 if (rte_is_zero_ether_addr((struct rte_ether_addr *)lif->mac_addr)) {
1482 IONIC_PRINT(NOTICE, "empty MAC addr (VF?)");
1486 IONIC_PRINT(DEBUG, "adding station MAC addr");
1488 ionic_lif_addr_add(lif, lif->mac_addr);
1494 ionic_lif_set_name(struct ionic_lif *lif)
1496 struct ionic_admin_ctx ctx = {
1497 .pending_work = true,
1498 .cmd.lif_setattr = {
1499 .opcode = IONIC_CMD_LIF_SETATTR,
1500 .attr = IONIC_LIF_ATTR_NAME,
1504 memcpy(ctx.cmd.lif_setattr.name, lif->name,
1505 sizeof(ctx.cmd.lif_setattr.name) - 1);
1507 ionic_adminq_post_wait(lif, &ctx);
1511 ionic_lif_init(struct ionic_lif *lif)
1513 struct ionic_dev *idev = &lif->adapter->idev;
1514 struct ionic_q_init_comp comp;
1517 memset(&lif->stats_base, 0, sizeof(lif->stats_base));
1519 ionic_dev_cmd_lif_init(idev, lif->info_pa);
1520 err = ionic_dev_cmd_wait_check(idev, IONIC_DEVCMD_TIMEOUT);
1521 ionic_dev_cmd_comp(idev, &comp);
1525 lif->hw_index = comp.hw_index;
1527 err = ionic_lif_adminq_init(lif);
1531 err = ionic_lif_notifyq_init(lif);
1533 goto err_out_adminq_deinit;
1536 IONIC_ETH_HW_VLAN_TX_TAG
1537 | IONIC_ETH_HW_VLAN_RX_STRIP
1538 | IONIC_ETH_HW_VLAN_RX_FILTER
1539 | IONIC_ETH_HW_RX_HASH
1540 | IONIC_ETH_HW_TX_SG
1541 | IONIC_ETH_HW_RX_SG
1542 | IONIC_ETH_HW_TX_CSUM
1543 | IONIC_ETH_HW_RX_CSUM
1545 | IONIC_ETH_HW_TSO_IPV6
1546 | IONIC_ETH_HW_TSO_ECN;
1548 err = ionic_lif_set_features(lif);
1550 goto err_out_notifyq_deinit;
1552 err = ionic_rx_filters_init(lif);
1554 goto err_out_notifyq_deinit;
1556 err = ionic_station_set(lif);
1558 goto err_out_rx_filter_deinit;
1560 ionic_lif_set_name(lif);
1562 lif->state |= IONIC_LIF_F_INITED;
1566 err_out_rx_filter_deinit:
1567 ionic_rx_filters_deinit(lif);
1569 err_out_notifyq_deinit:
1570 ionic_lif_qcq_deinit(lif, lif->notifyqcq);
1572 err_out_adminq_deinit:
1573 ionic_lif_qcq_deinit(lif, lif->adminqcq);
1579 ionic_lif_deinit(struct ionic_lif *lif)
1581 if (!(lif->state & IONIC_LIF_F_INITED))
1584 ionic_rx_filters_deinit(lif);
1585 ionic_lif_rss_teardown(lif);
1586 ionic_lif_qcq_deinit(lif, lif->notifyqcq);
1587 ionic_lif_qcq_deinit(lif, lif->adminqcq);
1589 lif->state &= ~IONIC_LIF_F_INITED;
1593 ionic_lif_configure(struct ionic_lif *lif)
1595 struct ionic_identity *ident = &lif->adapter->ident;
1596 uint32_t ntxqs_per_lif =
1597 ident->lif.eth.config.queue_count[IONIC_QTYPE_TXQ];
1598 uint32_t nrxqs_per_lif =
1599 ident->lif.eth.config.queue_count[IONIC_QTYPE_RXQ];
1600 uint32_t nrxqs = lif->eth_dev->data->nb_rx_queues;
1601 uint32_t ntxqs = lif->eth_dev->data->nb_tx_queues;
1603 lif->port_id = lif->eth_dev->data->port_id;
1605 IONIC_PRINT(DEBUG, "Configuring LIF on port %u",
1609 nrxqs_per_lif = RTE_MIN(nrxqs_per_lif, nrxqs);
1612 ntxqs_per_lif = RTE_MIN(ntxqs_per_lif, ntxqs);
1614 lif->nrxqcqs = nrxqs_per_lif;
1615 lif->ntxqcqs = ntxqs_per_lif;
1621 ionic_lif_start(struct ionic_lif *lif)
1627 err = ionic_lif_rss_setup(lif);
1631 if (!lif->rx_mode) {
1632 IONIC_PRINT(DEBUG, "Setting RX mode on %s",
1635 rx_mode = IONIC_RX_MODE_F_UNICAST;
1636 rx_mode |= IONIC_RX_MODE_F_MULTICAST;
1637 rx_mode |= IONIC_RX_MODE_F_BROADCAST;
1639 ionic_set_rx_mode(lif, rx_mode);
1642 IONIC_PRINT(DEBUG, "Starting %u RX queues and %u TX queues "
1644 lif->nrxqcqs, lif->ntxqcqs, lif->port_id);
1646 for (i = 0; i < lif->nrxqcqs; i++) {
1647 struct ionic_qcq *rxq = lif->rxqcqs[i];
1648 if (!(rxq->flags & IONIC_QCQ_F_DEFERRED)) {
1649 err = ionic_dev_rx_queue_start(lif->eth_dev, i);
1656 for (i = 0; i < lif->ntxqcqs; i++) {
1657 struct ionic_qcq *txq = lif->txqcqs[i];
1658 if (!(txq->flags & IONIC_QCQ_F_DEFERRED)) {
1659 err = ionic_dev_tx_queue_start(lif->eth_dev, i);
1666 /* Carrier ON here */
1667 lif->state |= IONIC_LIF_F_UP;
1669 ionic_link_status_check(lif);
1675 ionic_lif_identify(struct ionic_adapter *adapter)
1677 struct ionic_dev *idev = &adapter->idev;
1678 struct ionic_identity *ident = &adapter->ident;
1681 unsigned int lif_words = sizeof(ident->lif.words) /
1682 sizeof(ident->lif.words[0]);
1683 unsigned int cmd_words = sizeof(idev->dev_cmd->data) /
1684 sizeof(idev->dev_cmd->data[0]);
1685 unsigned int nwords;
1687 ionic_dev_cmd_lif_identify(idev, IONIC_LIF_TYPE_CLASSIC,
1688 IONIC_IDENTITY_VERSION_1);
1689 err = ionic_dev_cmd_wait_check(idev, IONIC_DEVCMD_TIMEOUT);
1693 nwords = RTE_MIN(lif_words, cmd_words);
1694 for (i = 0; i < nwords; i++)
1695 ident->lif.words[i] = ioread32(&idev->dev_cmd->data[i]);
1697 IONIC_PRINT(INFO, "capabilities 0x%" PRIx64 " ",
1698 ident->lif.capabilities);
1700 IONIC_PRINT(INFO, "eth.max_ucast_filters 0x%" PRIx32 " ",
1701 ident->lif.eth.max_ucast_filters);
1702 IONIC_PRINT(INFO, "eth.max_mcast_filters 0x%" PRIx32 " ",
1703 ident->lif.eth.max_mcast_filters);
1705 IONIC_PRINT(INFO, "eth.features 0x%" PRIx64 " ",
1706 ident->lif.eth.config.features);
1707 IONIC_PRINT(INFO, "eth.queue_count[IONIC_QTYPE_ADMINQ] 0x%" PRIx32 " ",
1708 ident->lif.eth.config.queue_count[IONIC_QTYPE_ADMINQ]);
1709 IONIC_PRINT(INFO, "eth.queue_count[IONIC_QTYPE_NOTIFYQ] 0x%" PRIx32 " ",
1710 ident->lif.eth.config.queue_count[IONIC_QTYPE_NOTIFYQ]);
1711 IONIC_PRINT(INFO, "eth.queue_count[IONIC_QTYPE_RXQ] 0x%" PRIx32 " ",
1712 ident->lif.eth.config.queue_count[IONIC_QTYPE_RXQ]);
1713 IONIC_PRINT(INFO, "eth.queue_count[IONIC_QTYPE_TXQ] 0x%" PRIx32 " ",
1714 ident->lif.eth.config.queue_count[IONIC_QTYPE_TXQ]);
1720 ionic_lifs_size(struct ionic_adapter *adapter)
1722 struct ionic_identity *ident = &adapter->ident;
1723 uint32_t nintrs, dev_nintrs = ident->dev.nintrs;
1725 adapter->max_ntxqs_per_lif =
1726 ident->lif.eth.config.queue_count[IONIC_QTYPE_TXQ];
1727 adapter->max_nrxqs_per_lif =
1728 ident->lif.eth.config.queue_count[IONIC_QTYPE_RXQ];
1730 nintrs = 1 /* notifyq */;
1732 if (nintrs > dev_nintrs) {
1734 "At most %d intr supported, minimum req'd is %u",
1735 dev_nintrs, nintrs);
1739 adapter->nintrs = nintrs;