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"
13 static int ionic_lif_addr_add(struct ionic_lif *lif, const uint8_t *addr);
14 static int ionic_lif_addr_del(struct ionic_lif *lif, const uint8_t *addr);
17 ionic_qcq_enable(struct ionic_qcq *qcq)
19 struct ionic_queue *q = &qcq->q;
20 struct ionic_lif *lif = q->lif;
21 struct ionic_dev *idev = &lif->adapter->idev;
22 struct ionic_admin_ctx ctx = {
25 .opcode = IONIC_CMD_Q_CONTROL,
26 .lif_index = lif->index,
29 .oper = IONIC_Q_ENABLE,
33 if (qcq->flags & IONIC_QCQ_F_INTR) {
34 ionic_intr_mask(idev->intr_ctrl, qcq->intr.index,
35 IONIC_INTR_MASK_CLEAR);
38 return ionic_adminq_post_wait(lif, &ctx);
42 ionic_qcq_disable(struct ionic_qcq *qcq)
44 struct ionic_queue *q = &qcq->q;
45 struct ionic_lif *lif = q->lif;
46 struct ionic_dev *idev = &lif->adapter->idev;
47 struct ionic_admin_ctx ctx = {
50 .opcode = IONIC_CMD_Q_CONTROL,
51 .lif_index = lif->index,
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 __rte_unused)
69 /* Carrier OFF here */
75 ionic_lif_reset(struct ionic_lif *lif)
77 struct ionic_dev *idev = &lif->adapter->idev;
81 ionic_dev_cmd_lif_reset(idev, lif->index);
82 ionic_dev_cmd_wait_check(idev, IONIC_DEVCMD_TIMEOUT);
86 ionic_lif_addr_add(struct ionic_lif *lif __rte_unused,
87 const uint8_t *addr __rte_unused)
89 IONIC_PRINT(INFO, "%s: stubbed", __func__);
95 ionic_lif_addr_del(struct ionic_lif *lif __rte_unused,
96 const uint8_t *addr __rte_unused)
98 IONIC_PRINT(INFO, "%s: stubbed", __func__);
104 ionic_lif_rx_mode(struct ionic_lif *lif, uint32_t rx_mode)
106 struct ionic_admin_ctx ctx = {
107 .pending_work = true,
109 .opcode = IONIC_CMD_RX_MODE_SET,
110 .lif_index = lif->index,
116 if (rx_mode & IONIC_RX_MODE_F_UNICAST)
117 IONIC_PRINT(DEBUG, "rx_mode IONIC_RX_MODE_F_UNICAST");
118 if (rx_mode & IONIC_RX_MODE_F_MULTICAST)
119 IONIC_PRINT(DEBUG, "rx_mode IONIC_RX_MODE_F_MULTICAST");
120 if (rx_mode & IONIC_RX_MODE_F_BROADCAST)
121 IONIC_PRINT(DEBUG, "rx_mode IONIC_RX_MODE_F_BROADCAST");
122 if (rx_mode & IONIC_RX_MODE_F_PROMISC)
123 IONIC_PRINT(DEBUG, "rx_mode IONIC_RX_MODE_F_PROMISC");
124 if (rx_mode & IONIC_RX_MODE_F_ALLMULTI)
125 IONIC_PRINT(DEBUG, "rx_mode IONIC_RX_MODE_F_ALLMULTI");
127 err = ionic_adminq_post_wait(lif, &ctx);
129 IONIC_PRINT(ERR, "Failure setting RX mode");
133 ionic_set_rx_mode(struct ionic_lif *lif, uint32_t rx_mode)
135 if (lif->rx_mode != rx_mode) {
136 lif->rx_mode = rx_mode;
137 ionic_lif_rx_mode(lif, rx_mode);
143 ionic_lif_change_mtu(struct ionic_lif *lif, int new_mtu)
145 struct ionic_admin_ctx ctx = {
146 .pending_work = true,
148 .opcode = IONIC_CMD_LIF_SETATTR,
150 .attr = IONIC_LIF_ATTR_MTU,
156 err = ionic_adminq_post_wait(lif, &ctx);
166 ionic_intr_alloc(struct ionic_lif *lif, struct ionic_intr_info *intr)
168 struct ionic_adapter *adapter = lif->adapter;
169 struct ionic_dev *idev = &adapter->idev;
173 * Note: interrupt handler is called for index = 0 only
174 * (we use interrupts for the notifyq only anyway,
175 * which hash index = 0)
178 for (index = 0; index < adapter->nintrs; index++)
179 if (!adapter->intrs[index])
182 if (index == adapter->nintrs)
185 adapter->intrs[index] = true;
187 ionic_intr_init(idev, intr, index);
193 ionic_intr_free(struct ionic_lif *lif, struct ionic_intr_info *intr)
195 if (intr->index != IONIC_INTR_INDEX_NOT_ASSIGNED)
196 lif->adapter->intrs[intr->index] = false;
200 ionic_qcq_alloc(struct ionic_lif *lif, uint8_t type,
202 const char *base, uint32_t flags,
205 uint32_t cq_desc_size,
206 uint32_t sg_desc_size,
207 uint32_t pid, struct ionic_qcq **qcq)
209 struct ionic_dev *idev = &lif->adapter->idev;
210 struct ionic_qcq *new;
211 uint32_t q_size, cq_size, sg_size, total_size;
212 void *q_base, *cq_base, *sg_base;
213 rte_iova_t q_base_pa = 0;
214 rte_iova_t cq_base_pa = 0;
215 rte_iova_t sg_base_pa = 0;
216 uint32_t socket_id = rte_socket_id();
221 q_size = num_descs * desc_size;
222 cq_size = num_descs * cq_desc_size;
223 sg_size = num_descs * sg_desc_size;
225 total_size = RTE_ALIGN(q_size, PAGE_SIZE) +
226 RTE_ALIGN(cq_size, PAGE_SIZE);
228 * Note: aligning q_size/cq_size is not enough due to cq_base address
229 * aligning as q_base could be not aligned to the page.
232 total_size += PAGE_SIZE;
234 if (flags & IONIC_QCQ_F_SG) {
235 total_size += RTE_ALIGN(sg_size, PAGE_SIZE);
236 total_size += PAGE_SIZE;
239 new = rte_zmalloc("ionic", sizeof(*new), 0);
241 IONIC_PRINT(ERR, "Cannot allocate queue structure");
248 new->q.info = rte_zmalloc("ionic", sizeof(*new->q.info) * num_descs, 0);
250 IONIC_PRINT(ERR, "Cannot allocate queue info");
256 err = ionic_q_init(lif, idev, &new->q, index, num_descs,
257 desc_size, sg_desc_size, pid);
259 IONIC_PRINT(ERR, "Queue initialization failed");
263 if (flags & IONIC_QCQ_F_INTR) {
264 err = ionic_intr_alloc(lif, &new->intr);
268 ionic_intr_mask_assert(idev->intr_ctrl, new->intr.index,
269 IONIC_INTR_MASK_SET);
271 new->intr.index = IONIC_INTR_INDEX_NOT_ASSIGNED;
274 err = ionic_cq_init(lif, &new->cq, &new->intr,
275 num_descs, cq_desc_size);
277 IONIC_PRINT(ERR, "Completion queue initialization failed");
278 goto err_out_free_intr;
281 new->base_z = rte_eth_dma_zone_reserve(lif->eth_dev,
282 base /* name */, index /* queue_idx */,
283 total_size, IONIC_ALIGN, socket_id);
286 IONIC_PRINT(ERR, "Cannot reserve queue DMA memory");
288 goto err_out_free_intr;
291 new->base = new->base_z->addr;
292 new->base_pa = new->base_z->iova;
293 new->total_size = total_size;
296 q_base_pa = new->base_pa;
298 cq_base = (void *)RTE_ALIGN((uintptr_t)q_base + q_size, PAGE_SIZE);
299 cq_base_pa = RTE_ALIGN(q_base_pa + q_size, PAGE_SIZE);
301 if (flags & IONIC_QCQ_F_SG) {
302 sg_base = (void *)RTE_ALIGN((uintptr_t)cq_base + cq_size,
304 sg_base_pa = RTE_ALIGN(cq_base_pa + cq_size, PAGE_SIZE);
305 ionic_q_sg_map(&new->q, sg_base, sg_base_pa);
308 IONIC_PRINT(DEBUG, "Q-Base-PA = %ju CQ-Base-PA = %ju "
310 q_base_pa, cq_base_pa, sg_base_pa);
312 ionic_q_map(&new->q, q_base, q_base_pa);
313 ionic_cq_map(&new->cq, cq_base, cq_base_pa);
314 ionic_cq_bind(&new->cq, &new->q);
321 if (flags & IONIC_QCQ_F_INTR)
322 ionic_intr_free(lif, &new->intr);
328 ionic_qcq_free(struct ionic_qcq *qcq)
333 rte_memzone_free(qcq->base_z);
338 rte_free(qcq->q.info);
346 ionic_admin_qcq_alloc(struct ionic_lif *lif)
352 err = ionic_qcq_alloc(lif, IONIC_QTYPE_ADMINQ, 0, "admin", flags,
354 sizeof(struct ionic_admin_cmd),
355 sizeof(struct ionic_admin_comp),
357 lif->kern_pid, &lif->adminqcq);
365 ionic_notify_qcq_alloc(struct ionic_lif *lif)
370 flags = IONIC_QCQ_F_NOTIFYQ | IONIC_QCQ_F_INTR;
372 err = ionic_qcq_alloc(lif, IONIC_QTYPE_NOTIFYQ, 0, "notify",
374 IONIC_NOTIFYQ_LENGTH,
375 sizeof(struct ionic_notifyq_cmd),
376 sizeof(union ionic_notifyq_comp),
378 lif->kern_pid, &lif->notifyqcq);
386 ionic_bus_map_dbpage(struct ionic_adapter *adapter, int page_num)
388 char *vaddr = adapter->bars[IONIC_PCI_BAR_DBELL].vaddr;
390 if (adapter->num_bars <= IONIC_PCI_BAR_DBELL)
393 return (void *)&vaddr[page_num << PAGE_SHIFT];
397 ionic_lif_alloc(struct ionic_lif *lif)
399 struct ionic_adapter *adapter = lif->adapter;
400 uint32_t socket_id = rte_socket_id();
404 snprintf(lif->name, sizeof(lif->name), "lif%u", lif->index);
406 IONIC_PRINT(DEBUG, "Allocating Lif Info");
408 rte_spinlock_init(&lif->adminq_lock);
409 rte_spinlock_init(&lif->adminq_service_lock);
413 dbpage_num = ionic_db_page_num(lif, 0);
415 lif->kern_dbpage = ionic_bus_map_dbpage(adapter, dbpage_num);
416 if (!lif->kern_dbpage) {
417 IONIC_PRINT(ERR, "Cannot map dbpage, aborting");
421 IONIC_PRINT(DEBUG, "Allocating Notify Queue");
423 err = ionic_notify_qcq_alloc(lif);
425 IONIC_PRINT(ERR, "Cannot allocate notify queue");
429 IONIC_PRINT(DEBUG, "Allocating Admin Queue");
431 IONIC_PRINT(DEBUG, "Allocating Admin Queue");
433 err = ionic_admin_qcq_alloc(lif);
435 IONIC_PRINT(ERR, "Cannot allocate admin queue");
439 IONIC_PRINT(DEBUG, "Allocating Lif Info");
441 lif->info_sz = RTE_ALIGN(sizeof(*lif->info), PAGE_SIZE);
443 lif->info_z = rte_eth_dma_zone_reserve(lif->eth_dev,
444 "lif_info", 0 /* queue_idx*/,
445 lif->info_sz, IONIC_ALIGN, socket_id);
447 IONIC_PRINT(ERR, "Cannot allocate lif info memory");
451 lif->info = lif->info_z->addr;
452 lif->info_pa = lif->info_z->iova;
458 ionic_lif_free(struct ionic_lif *lif)
460 if (lif->notifyqcq) {
461 ionic_qcq_free(lif->notifyqcq);
462 lif->notifyqcq = NULL;
466 ionic_qcq_free(lif->adminqcq);
467 lif->adminqcq = NULL;
471 rte_memzone_free(lif->info_z);
477 ionic_lif_qcq_deinit(struct ionic_lif *lif, struct ionic_qcq *qcq)
479 struct ionic_dev *idev = &lif->adapter->idev;
481 if (!(qcq->flags & IONIC_QCQ_F_INITED))
484 if (qcq->flags & IONIC_QCQ_F_INTR)
485 ionic_intr_mask(idev->intr_ctrl, qcq->intr.index,
486 IONIC_INTR_MASK_SET);
488 qcq->flags &= ~IONIC_QCQ_F_INITED;
492 ionic_adminq_service(struct ionic_cq *cq, uint32_t cq_desc_index,
493 void *cb_arg __rte_unused)
495 struct ionic_admin_comp *cq_desc_base = cq->base;
496 struct ionic_admin_comp *cq_desc = &cq_desc_base[cq_desc_index];
498 if (!color_match(cq_desc->color, cq->done_color))
501 ionic_q_service(cq->bound_q, cq_desc_index, cq_desc->comp_index, NULL);
506 /* This acts like ionic_napi */
508 ionic_qcq_service(struct ionic_qcq *qcq, int budget, ionic_cq_cb cb,
511 struct ionic_cq *cq = &qcq->cq;
514 work_done = ionic_cq_service(cq, budget, cb, cb_arg);
520 ionic_link_status_check(struct ionic_lif *lif)
522 struct ionic_adapter *adapter = lif->adapter;
525 lif->state &= ~IONIC_LIF_F_LINK_CHECK_NEEDED;
530 link_up = (lif->info->status.link_status == IONIC_PORT_OPER_STATUS_UP);
532 if ((link_up && adapter->link_up) ||
533 (!link_up && !adapter->link_up))
537 IONIC_PRINT(DEBUG, "Link up - %d Gbps",
538 lif->info->status.link_speed);
539 adapter->link_speed = lif->info->status.link_speed;
541 IONIC_PRINT(DEBUG, "Link down");
544 adapter->link_up = link_up;
548 ionic_notifyq_cb(struct ionic_cq *cq, uint32_t cq_desc_index, void *cb_arg)
550 union ionic_notifyq_comp *cq_desc_base = cq->base;
551 union ionic_notifyq_comp *cq_desc = &cq_desc_base[cq_desc_index];
552 struct ionic_lif *lif = cb_arg;
554 IONIC_PRINT(DEBUG, "Notifyq callback eid = %jd ecode = %d",
555 cq_desc->event.eid, cq_desc->event.ecode);
557 /* Have we run out of new completions to process? */
558 if (!(cq_desc->event.eid > lif->last_eid))
561 lif->last_eid = cq_desc->event.eid;
563 switch (cq_desc->event.ecode) {
564 case IONIC_EVENT_LINK_CHANGE:
566 "Notifyq IONIC_EVENT_LINK_CHANGE eid=%jd link_status=%d link_speed=%d",
568 cq_desc->link_change.link_status,
569 cq_desc->link_change.link_speed);
571 lif->state |= IONIC_LIF_F_LINK_CHECK_NEEDED;
575 IONIC_PRINT(WARNING, "Notifyq bad event ecode=%d eid=%jd",
576 cq_desc->event.ecode, cq_desc->event.eid);
584 ionic_notifyq_handler(struct ionic_lif *lif, int budget)
586 struct ionic_dev *idev = &lif->adapter->idev;
587 struct ionic_qcq *qcq = lif->notifyqcq;
590 if (!(qcq->flags & IONIC_QCQ_F_INITED)) {
591 IONIC_PRINT(DEBUG, "Notifyq not yet initialized");
595 ionic_intr_mask(idev->intr_ctrl, qcq->intr.index,
596 IONIC_INTR_MASK_SET);
598 work_done = ionic_qcq_service(qcq, budget, ionic_notifyq_cb, lif);
600 if (lif->state & IONIC_LIF_F_LINK_CHECK_NEEDED)
601 ionic_link_status_check(lif);
603 ionic_intr_credits(idev->intr_ctrl, qcq->intr.index,
604 work_done, IONIC_INTR_CRED_RESET_COALESCE);
606 ionic_intr_mask(idev->intr_ctrl, qcq->intr.index,
607 IONIC_INTR_MASK_CLEAR);
613 ionic_lif_adminq_init(struct ionic_lif *lif)
615 struct ionic_dev *idev = &lif->adapter->idev;
616 struct ionic_qcq *qcq = lif->adminqcq;
617 struct ionic_queue *q = &qcq->q;
618 struct ionic_q_init_comp comp;
621 ionic_dev_cmd_adminq_init(idev, qcq, lif->index, qcq->intr.index);
622 err = ionic_dev_cmd_wait_check(idev, IONIC_DEVCMD_TIMEOUT);
626 ionic_dev_cmd_comp(idev, &comp);
628 q->hw_type = comp.hw_type;
629 q->hw_index = comp.hw_index;
630 q->db = ionic_db_map(lif, q);
632 IONIC_PRINT(DEBUG, "adminq->hw_type %d", q->hw_type);
633 IONIC_PRINT(DEBUG, "adminq->hw_index %d", q->hw_index);
634 IONIC_PRINT(DEBUG, "adminq->db %p", q->db);
636 if (qcq->flags & IONIC_QCQ_F_INTR)
637 ionic_intr_mask(idev->intr_ctrl, qcq->intr.index,
638 IONIC_INTR_MASK_CLEAR);
640 qcq->flags |= IONIC_QCQ_F_INITED;
646 ionic_lif_notifyq_init(struct ionic_lif *lif)
648 struct ionic_dev *idev = &lif->adapter->idev;
649 struct ionic_qcq *qcq = lif->notifyqcq;
650 struct ionic_queue *q = &qcq->q;
653 struct ionic_admin_ctx ctx = {
654 .pending_work = true,
656 .opcode = IONIC_CMD_Q_INIT,
657 .lif_index = lif->index,
660 .flags = (IONIC_QINIT_F_IRQ | IONIC_QINIT_F_ENA),
661 .intr_index = qcq->intr.index,
663 .ring_size = rte_log2_u32(q->num_descs),
664 .ring_base = q->base_pa,
668 IONIC_PRINT(DEBUG, "notifyq_init.pid %d", ctx.cmd.q_init.pid);
669 IONIC_PRINT(DEBUG, "notifyq_init.index %d",
670 ctx.cmd.q_init.index);
671 IONIC_PRINT(DEBUG, "notifyq_init.ring_base 0x%" PRIx64 "",
672 ctx.cmd.q_init.ring_base);
673 IONIC_PRINT(DEBUG, "notifyq_init.ring_size %d",
674 ctx.cmd.q_init.ring_size);
676 err = ionic_adminq_post_wait(lif, &ctx);
680 q->hw_type = ctx.comp.q_init.hw_type;
681 q->hw_index = ctx.comp.q_init.hw_index;
684 IONIC_PRINT(DEBUG, "notifyq->hw_type %d", q->hw_type);
685 IONIC_PRINT(DEBUG, "notifyq->hw_index %d", q->hw_index);
686 IONIC_PRINT(DEBUG, "notifyq->db %p", q->db);
688 if (qcq->flags & IONIC_QCQ_F_INTR)
689 ionic_intr_mask(idev->intr_ctrl, qcq->intr.index,
690 IONIC_INTR_MASK_CLEAR);
692 qcq->flags |= IONIC_QCQ_F_INITED;
698 ionic_lif_set_features(struct ionic_lif *lif)
700 struct ionic_admin_ctx ctx = {
701 .pending_work = true,
703 .opcode = IONIC_CMD_LIF_SETATTR,
705 .attr = IONIC_LIF_ATTR_FEATURES,
706 .features = lif->features,
711 err = ionic_adminq_post_wait(lif, &ctx);
715 lif->hw_features = (ctx.cmd.lif_setattr.features &
716 ctx.comp.lif_setattr.features);
718 if (lif->hw_features & IONIC_ETH_HW_VLAN_TX_TAG)
719 IONIC_PRINT(DEBUG, "feature IONIC_ETH_HW_VLAN_TX_TAG");
720 if (lif->hw_features & IONIC_ETH_HW_VLAN_RX_STRIP)
721 IONIC_PRINT(DEBUG, "feature IONIC_ETH_HW_VLAN_RX_STRIP");
722 if (lif->hw_features & IONIC_ETH_HW_VLAN_RX_FILTER)
723 IONIC_PRINT(DEBUG, "feature IONIC_ETH_HW_VLAN_RX_FILTER");
724 if (lif->hw_features & IONIC_ETH_HW_RX_HASH)
725 IONIC_PRINT(DEBUG, "feature IONIC_ETH_HW_RX_HASH");
726 if (lif->hw_features & IONIC_ETH_HW_TX_SG)
727 IONIC_PRINT(DEBUG, "feature IONIC_ETH_HW_TX_SG");
728 if (lif->hw_features & IONIC_ETH_HW_RX_SG)
729 IONIC_PRINT(DEBUG, "feature IONIC_ETH_HW_RX_SG");
730 if (lif->hw_features & IONIC_ETH_HW_TX_CSUM)
731 IONIC_PRINT(DEBUG, "feature IONIC_ETH_HW_TX_CSUM");
732 if (lif->hw_features & IONIC_ETH_HW_RX_CSUM)
733 IONIC_PRINT(DEBUG, "feature IONIC_ETH_HW_RX_CSUM");
734 if (lif->hw_features & IONIC_ETH_HW_TSO)
735 IONIC_PRINT(DEBUG, "feature IONIC_ETH_HW_TSO");
736 if (lif->hw_features & IONIC_ETH_HW_TSO_IPV6)
737 IONIC_PRINT(DEBUG, "feature IONIC_ETH_HW_TSO_IPV6");
738 if (lif->hw_features & IONIC_ETH_HW_TSO_ECN)
739 IONIC_PRINT(DEBUG, "feature IONIC_ETH_HW_TSO_ECN");
740 if (lif->hw_features & IONIC_ETH_HW_TSO_GRE)
741 IONIC_PRINT(DEBUG, "feature IONIC_ETH_HW_TSO_GRE");
742 if (lif->hw_features & IONIC_ETH_HW_TSO_GRE_CSUM)
743 IONIC_PRINT(DEBUG, "feature IONIC_ETH_HW_TSO_GRE_CSUM");
744 if (lif->hw_features & IONIC_ETH_HW_TSO_IPXIP4)
745 IONIC_PRINT(DEBUG, "feature IONIC_ETH_HW_TSO_IPXIP4");
746 if (lif->hw_features & IONIC_ETH_HW_TSO_IPXIP6)
747 IONIC_PRINT(DEBUG, "feature IONIC_ETH_HW_TSO_IPXIP6");
748 if (lif->hw_features & IONIC_ETH_HW_TSO_UDP)
749 IONIC_PRINT(DEBUG, "feature IONIC_ETH_HW_TSO_UDP");
750 if (lif->hw_features & IONIC_ETH_HW_TSO_UDP_CSUM)
751 IONIC_PRINT(DEBUG, "feature IONIC_ETH_HW_TSO_UDP_CSUM");
757 ionic_station_set(struct ionic_lif *lif)
759 struct ionic_admin_ctx ctx = {
760 .pending_work = true,
762 .opcode = IONIC_CMD_LIF_GETATTR,
764 .attr = IONIC_LIF_ATTR_MAC,
771 err = ionic_adminq_post_wait(lif, &ctx);
775 if (!rte_is_zero_ether_addr((struct rte_ether_addr *)
777 IONIC_PRINT(INFO, "deleting station MAC addr");
779 ionic_lif_addr_del(lif, lif->mac_addr);
782 memcpy(lif->mac_addr, ctx.comp.lif_getattr.mac, RTE_ETHER_ADDR_LEN);
784 if (rte_is_zero_ether_addr((struct rte_ether_addr *)lif->mac_addr)) {
785 IONIC_PRINT(NOTICE, "empty MAC addr (VF?)");
789 IONIC_PRINT(DEBUG, "adding station MAC addr");
791 ionic_lif_addr_add(lif, lif->mac_addr);
797 ionic_lif_set_name(struct ionic_lif *lif)
799 struct ionic_admin_ctx ctx = {
800 .pending_work = true,
802 .opcode = IONIC_CMD_LIF_SETATTR,
804 .attr = IONIC_LIF_ATTR_NAME,
808 snprintf(ctx.cmd.lif_setattr.name, sizeof(ctx.cmd.lif_setattr.name),
811 ionic_adminq_post_wait(lif, &ctx);
815 ionic_lif_init(struct ionic_lif *lif)
817 struct ionic_dev *idev = &lif->adapter->idev;
818 struct ionic_q_init_comp comp;
821 ionic_dev_cmd_lif_init(idev, lif->index, lif->info_pa);
822 err = ionic_dev_cmd_wait_check(idev, IONIC_DEVCMD_TIMEOUT);
823 ionic_dev_cmd_comp(idev, &comp);
827 lif->hw_index = comp.hw_index;
829 err = ionic_lif_adminq_init(lif);
833 err = ionic_lif_notifyq_init(lif);
835 goto err_out_adminq_deinit;
839 err = ionic_lif_set_features(lif);
841 goto err_out_notifyq_deinit;
843 err = ionic_station_set(lif);
845 goto err_out_notifyq_deinit;
847 ionic_lif_set_name(lif);
849 lif->state |= IONIC_LIF_F_INITED;
853 err_out_notifyq_deinit:
854 ionic_lif_qcq_deinit(lif, lif->notifyqcq);
856 err_out_adminq_deinit:
857 ionic_lif_qcq_deinit(lif, lif->adminqcq);
863 ionic_lif_deinit(struct ionic_lif *lif)
865 if (!(lif->state & IONIC_LIF_F_INITED))
868 ionic_lif_qcq_deinit(lif, lif->notifyqcq);
869 ionic_lif_qcq_deinit(lif, lif->adminqcq);
871 lif->state &= ~IONIC_LIF_F_INITED;
875 ionic_lif_configure(struct ionic_lif *lif)
877 lif->port_id = lif->eth_dev->data->port_id;
883 ionic_lif_start(struct ionic_lif *lif)
885 uint32_t rx_mode = 0;
887 IONIC_PRINT(DEBUG, "Setting RX mode on port %u",
890 rx_mode |= IONIC_RX_MODE_F_UNICAST;
891 rx_mode |= IONIC_RX_MODE_F_MULTICAST;
892 rx_mode |= IONIC_RX_MODE_F_BROADCAST;
894 lif->rx_mode = 0; /* set by ionic_set_rx_mode */
896 ionic_set_rx_mode(lif, rx_mode);
898 ionic_link_status_check(lif);
900 /* Carrier ON here */
906 ionic_lif_identify(struct ionic_adapter *adapter)
908 struct ionic_dev *idev = &adapter->idev;
909 struct ionic_identity *ident = &adapter->ident;
912 unsigned int lif_words = sizeof(ident->lif.words) /
913 sizeof(ident->lif.words[0]);
914 unsigned int cmd_words = sizeof(idev->dev_cmd->data) /
915 sizeof(idev->dev_cmd->data[0]);
918 ionic_dev_cmd_lif_identify(idev, IONIC_LIF_TYPE_CLASSIC,
919 IONIC_IDENTITY_VERSION_1);
920 err = ionic_dev_cmd_wait_check(idev, IONIC_DEVCMD_TIMEOUT);
924 nwords = RTE_MIN(lif_words, cmd_words);
925 for (i = 0; i < nwords; i++)
926 ident->lif.words[i] = ioread32(&idev->dev_cmd->data[i]);
928 IONIC_PRINT(INFO, "capabilities 0x%" PRIx64 " ",
929 ident->lif.capabilities);
931 IONIC_PRINT(INFO, "eth.max_ucast_filters 0x%" PRIx32 " ",
932 ident->lif.eth.max_ucast_filters);
933 IONIC_PRINT(INFO, "eth.max_mcast_filters 0x%" PRIx32 " ",
934 ident->lif.eth.max_mcast_filters);
936 IONIC_PRINT(INFO, "eth.features 0x%" PRIx64 " ",
937 ident->lif.eth.config.features);
938 IONIC_PRINT(INFO, "eth.queue_count[IONIC_QTYPE_ADMINQ] 0x%" PRIx32 " ",
939 ident->lif.eth.config.queue_count[IONIC_QTYPE_ADMINQ]);
940 IONIC_PRINT(INFO, "eth.queue_count[IONIC_QTYPE_NOTIFYQ] 0x%" PRIx32 " ",
941 ident->lif.eth.config.queue_count[IONIC_QTYPE_NOTIFYQ]);
942 IONIC_PRINT(INFO, "eth.queue_count[IONIC_QTYPE_RXQ] 0x%" PRIx32 " ",
943 ident->lif.eth.config.queue_count[IONIC_QTYPE_RXQ]);
944 IONIC_PRINT(INFO, "eth.queue_count[IONIC_QTYPE_TXQ] 0x%" PRIx32 " ",
945 ident->lif.eth.config.queue_count[IONIC_QTYPE_TXQ]);
951 ionic_lifs_size(struct ionic_adapter *adapter)
953 struct ionic_identity *ident = &adapter->ident;
954 uint32_t nlifs = ident->dev.nlifs;
955 uint32_t nintrs, dev_nintrs = ident->dev.nintrs;
957 adapter->max_ntxqs_per_lif =
958 ident->lif.eth.config.queue_count[IONIC_QTYPE_TXQ];
959 adapter->max_nrxqs_per_lif =
960 ident->lif.eth.config.queue_count[IONIC_QTYPE_RXQ];
962 nintrs = nlifs * 1 /* notifyq */;
964 if (nintrs > dev_nintrs) {
965 IONIC_PRINT(ERR, "At most %d intr queues supported, minimum required is %u",
970 adapter->nintrs = nintrs;