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"
14 ionic_qcq_enable(struct ionic_qcq *qcq)
16 struct ionic_queue *q = &qcq->q;
17 struct ionic_lif *lif = q->lif;
18 struct ionic_dev *idev = &lif->adapter->idev;
19 struct ionic_admin_ctx ctx = {
22 .opcode = IONIC_CMD_Q_CONTROL,
23 .lif_index = lif->index,
26 .oper = IONIC_Q_ENABLE,
30 if (qcq->flags & IONIC_QCQ_F_INTR) {
31 ionic_intr_mask(idev->intr_ctrl, qcq->intr.index,
32 IONIC_INTR_MASK_CLEAR);
35 return ionic_adminq_post_wait(lif, &ctx);
39 ionic_qcq_disable(struct ionic_qcq *qcq)
41 struct ionic_queue *q = &qcq->q;
42 struct ionic_lif *lif = q->lif;
43 struct ionic_dev *idev = &lif->adapter->idev;
44 struct ionic_admin_ctx ctx = {
47 .opcode = IONIC_CMD_Q_CONTROL,
48 .lif_index = lif->index,
51 .oper = IONIC_Q_DISABLE,
55 if (qcq->flags & IONIC_QCQ_F_INTR) {
56 ionic_intr_mask(idev->intr_ctrl, qcq->intr.index,
60 return ionic_adminq_post_wait(lif, &ctx);
64 ionic_intr_alloc(struct ionic_lif *lif, struct ionic_intr_info *intr)
66 struct ionic_adapter *adapter = lif->adapter;
67 struct ionic_dev *idev = &adapter->idev;
71 * Note: interrupt handler is called for index = 0 only
72 * (we use interrupts for the notifyq only anyway,
73 * which hash index = 0)
76 for (index = 0; index < adapter->nintrs; index++)
77 if (!adapter->intrs[index])
80 if (index == adapter->nintrs)
83 adapter->intrs[index] = true;
85 ionic_intr_init(idev, intr, index);
91 ionic_intr_free(struct ionic_lif *lif, struct ionic_intr_info *intr)
93 if (intr->index != IONIC_INTR_INDEX_NOT_ASSIGNED)
94 lif->adapter->intrs[intr->index] = false;
98 ionic_qcq_alloc(struct ionic_lif *lif, uint8_t type,
100 const char *base, uint32_t flags,
103 uint32_t cq_desc_size,
104 uint32_t sg_desc_size,
105 uint32_t pid, struct ionic_qcq **qcq)
107 struct ionic_dev *idev = &lif->adapter->idev;
108 struct ionic_qcq *new;
109 uint32_t q_size, cq_size, sg_size, total_size;
110 void *q_base, *cq_base, *sg_base;
111 rte_iova_t q_base_pa = 0;
112 rte_iova_t cq_base_pa = 0;
113 rte_iova_t sg_base_pa = 0;
114 uint32_t socket_id = rte_socket_id();
119 q_size = num_descs * desc_size;
120 cq_size = num_descs * cq_desc_size;
121 sg_size = num_descs * sg_desc_size;
123 total_size = RTE_ALIGN(q_size, PAGE_SIZE) +
124 RTE_ALIGN(cq_size, PAGE_SIZE);
126 * Note: aligning q_size/cq_size is not enough due to cq_base address
127 * aligning as q_base could be not aligned to the page.
130 total_size += PAGE_SIZE;
132 if (flags & IONIC_QCQ_F_SG) {
133 total_size += RTE_ALIGN(sg_size, PAGE_SIZE);
134 total_size += PAGE_SIZE;
137 new = rte_zmalloc("ionic", sizeof(*new), 0);
139 IONIC_PRINT(ERR, "Cannot allocate queue structure");
146 new->q.info = rte_zmalloc("ionic", sizeof(*new->q.info) * num_descs, 0);
148 IONIC_PRINT(ERR, "Cannot allocate queue info");
154 err = ionic_q_init(lif, idev, &new->q, index, num_descs,
155 desc_size, sg_desc_size, pid);
157 IONIC_PRINT(ERR, "Queue initialization failed");
161 if (flags & IONIC_QCQ_F_INTR) {
162 err = ionic_intr_alloc(lif, &new->intr);
166 ionic_intr_mask_assert(idev->intr_ctrl, new->intr.index,
167 IONIC_INTR_MASK_SET);
169 new->intr.index = IONIC_INTR_INDEX_NOT_ASSIGNED;
172 err = ionic_cq_init(lif, &new->cq, &new->intr,
173 num_descs, cq_desc_size);
175 IONIC_PRINT(ERR, "Completion queue initialization failed");
176 goto err_out_free_intr;
179 new->base_z = rte_eth_dma_zone_reserve(lif->eth_dev,
180 base /* name */, index /* queue_idx */,
181 total_size, IONIC_ALIGN, socket_id);
184 IONIC_PRINT(ERR, "Cannot reserve queue DMA memory");
186 goto err_out_free_intr;
189 new->base = new->base_z->addr;
190 new->base_pa = new->base_z->iova;
191 new->total_size = total_size;
194 q_base_pa = new->base_pa;
196 cq_base = (void *)RTE_ALIGN((uintptr_t)q_base + q_size, PAGE_SIZE);
197 cq_base_pa = RTE_ALIGN(q_base_pa + q_size, PAGE_SIZE);
199 if (flags & IONIC_QCQ_F_SG) {
200 sg_base = (void *)RTE_ALIGN((uintptr_t)cq_base + cq_size,
202 sg_base_pa = RTE_ALIGN(cq_base_pa + cq_size, PAGE_SIZE);
203 ionic_q_sg_map(&new->q, sg_base, sg_base_pa);
206 IONIC_PRINT(DEBUG, "Q-Base-PA = %ju CQ-Base-PA = %ju "
208 q_base_pa, cq_base_pa, sg_base_pa);
210 ionic_q_map(&new->q, q_base, q_base_pa);
211 ionic_cq_map(&new->cq, cq_base, cq_base_pa);
212 ionic_cq_bind(&new->cq, &new->q);
219 if (flags & IONIC_QCQ_F_INTR)
220 ionic_intr_free(lif, &new->intr);
226 ionic_qcq_free(struct ionic_qcq *qcq)
231 rte_memzone_free(qcq->base_z);
236 rte_free(qcq->q.info);
244 ionic_admin_qcq_alloc(struct ionic_lif *lif)
250 err = ionic_qcq_alloc(lif, IONIC_QTYPE_ADMINQ, 0, "admin", flags,
252 sizeof(struct ionic_admin_cmd),
253 sizeof(struct ionic_admin_comp),
255 lif->kern_pid, &lif->adminqcq);
264 ionic_bus_map_dbpage(struct ionic_adapter *adapter, int page_num)
266 char *vaddr = adapter->bars[IONIC_PCI_BAR_DBELL].vaddr;
268 if (adapter->num_bars <= IONIC_PCI_BAR_DBELL)
271 return (void *)&vaddr[page_num << PAGE_SHIFT];
275 ionic_lif_alloc(struct ionic_lif *lif)
277 struct ionic_adapter *adapter = lif->adapter;
278 uint32_t socket_id = rte_socket_id();
282 snprintf(lif->name, sizeof(lif->name), "lif%u", lif->index);
284 IONIC_PRINT(DEBUG, "Allocating Lif Info");
286 rte_spinlock_init(&lif->adminq_lock);
287 rte_spinlock_init(&lif->adminq_service_lock);
291 dbpage_num = ionic_db_page_num(lif, 0);
293 lif->kern_dbpage = ionic_bus_map_dbpage(adapter, dbpage_num);
294 if (!lif->kern_dbpage) {
295 IONIC_PRINT(ERR, "Cannot map dbpage, aborting");
299 IONIC_PRINT(DEBUG, "Allocating Admin Queue");
301 err = ionic_admin_qcq_alloc(lif);
303 IONIC_PRINT(ERR, "Cannot allocate admin queue");
307 IONIC_PRINT(DEBUG, "Allocating Lif Info");
309 lif->info_sz = RTE_ALIGN(sizeof(*lif->info), PAGE_SIZE);
311 lif->info_z = rte_eth_dma_zone_reserve(lif->eth_dev,
312 "lif_info", 0 /* queue_idx*/,
313 lif->info_sz, IONIC_ALIGN, socket_id);
315 IONIC_PRINT(ERR, "Cannot allocate lif info memory");
319 lif->info = lif->info_z->addr;
320 lif->info_pa = lif->info_z->iova;
326 ionic_lif_free(struct ionic_lif *lif)
329 ionic_qcq_free(lif->adminqcq);
330 lif->adminqcq = NULL;
334 rte_memzone_free(lif->info_z);
340 ionic_lif_qcq_deinit(struct ionic_lif *lif, struct ionic_qcq *qcq)
342 struct ionic_dev *idev = &lif->adapter->idev;
344 if (!(qcq->flags & IONIC_QCQ_F_INITED))
347 if (qcq->flags & IONIC_QCQ_F_INTR)
348 ionic_intr_mask(idev->intr_ctrl, qcq->intr.index,
349 IONIC_INTR_MASK_SET);
351 qcq->flags &= ~IONIC_QCQ_F_INITED;
355 ionic_adminq_service(struct ionic_cq *cq, uint32_t cq_desc_index,
356 void *cb_arg __rte_unused)
358 struct ionic_admin_comp *cq_desc_base = cq->base;
359 struct ionic_admin_comp *cq_desc = &cq_desc_base[cq_desc_index];
361 if (!color_match(cq_desc->color, cq->done_color))
364 ionic_q_service(cq->bound_q, cq_desc_index, cq_desc->comp_index, NULL);
369 /* This acts like ionic_napi */
371 ionic_qcq_service(struct ionic_qcq *qcq, int budget, ionic_cq_cb cb,
374 struct ionic_cq *cq = &qcq->cq;
377 work_done = ionic_cq_service(cq, budget, cb, cb_arg);
383 ionic_lif_adminq_init(struct ionic_lif *lif)
385 struct ionic_dev *idev = &lif->adapter->idev;
386 struct ionic_qcq *qcq = lif->adminqcq;
387 struct ionic_queue *q = &qcq->q;
388 struct ionic_q_init_comp comp;
391 ionic_dev_cmd_adminq_init(idev, qcq, lif->index, qcq->intr.index);
392 err = ionic_dev_cmd_wait_check(idev, IONIC_DEVCMD_TIMEOUT);
396 ionic_dev_cmd_comp(idev, &comp);
398 q->hw_type = comp.hw_type;
399 q->hw_index = comp.hw_index;
400 q->db = ionic_db_map(lif, q);
402 IONIC_PRINT(DEBUG, "adminq->hw_type %d", q->hw_type);
403 IONIC_PRINT(DEBUG, "adminq->hw_index %d", q->hw_index);
404 IONIC_PRINT(DEBUG, "adminq->db %p", q->db);
406 if (qcq->flags & IONIC_QCQ_F_INTR)
407 ionic_intr_mask(idev->intr_ctrl, qcq->intr.index,
408 IONIC_INTR_MASK_CLEAR);
410 qcq->flags |= IONIC_QCQ_F_INITED;
416 ionic_lif_init(struct ionic_lif *lif)
418 struct ionic_dev *idev = &lif->adapter->idev;
419 struct ionic_q_init_comp comp;
422 ionic_dev_cmd_lif_init(idev, lif->index, lif->info_pa);
423 err = ionic_dev_cmd_wait_check(idev, IONIC_DEVCMD_TIMEOUT);
424 ionic_dev_cmd_comp(idev, &comp);
428 lif->hw_index = comp.hw_index;
430 err = ionic_lif_adminq_init(lif);
434 lif->state |= IONIC_LIF_F_INITED;
440 ionic_lif_deinit(struct ionic_lif *lif)
442 if (!(lif->state & IONIC_LIF_F_INITED))
445 ionic_lif_qcq_deinit(lif, lif->adminqcq);
447 lif->state &= ~IONIC_LIF_F_INITED;
451 ionic_lif_identify(struct ionic_adapter *adapter)
453 struct ionic_dev *idev = &adapter->idev;
454 struct ionic_identity *ident = &adapter->ident;
457 unsigned int lif_words = sizeof(ident->lif.words) /
458 sizeof(ident->lif.words[0]);
459 unsigned int cmd_words = sizeof(idev->dev_cmd->data) /
460 sizeof(idev->dev_cmd->data[0]);
463 ionic_dev_cmd_lif_identify(idev, IONIC_LIF_TYPE_CLASSIC,
464 IONIC_IDENTITY_VERSION_1);
465 err = ionic_dev_cmd_wait_check(idev, IONIC_DEVCMD_TIMEOUT);
469 nwords = RTE_MIN(lif_words, cmd_words);
470 for (i = 0; i < nwords; i++)
471 ident->lif.words[i] = ioread32(&idev->dev_cmd->data[i]);
473 IONIC_PRINT(INFO, "capabilities 0x%" PRIx64 " ",
474 ident->lif.capabilities);
476 IONIC_PRINT(INFO, "eth.max_ucast_filters 0x%" PRIx32 " ",
477 ident->lif.eth.max_ucast_filters);
478 IONIC_PRINT(INFO, "eth.max_mcast_filters 0x%" PRIx32 " ",
479 ident->lif.eth.max_mcast_filters);
481 IONIC_PRINT(INFO, "eth.features 0x%" PRIx64 " ",
482 ident->lif.eth.config.features);
483 IONIC_PRINT(INFO, "eth.queue_count[IONIC_QTYPE_ADMINQ] 0x%" PRIx32 " ",
484 ident->lif.eth.config.queue_count[IONIC_QTYPE_ADMINQ]);
485 IONIC_PRINT(INFO, "eth.queue_count[IONIC_QTYPE_NOTIFYQ] 0x%" PRIx32 " ",
486 ident->lif.eth.config.queue_count[IONIC_QTYPE_NOTIFYQ]);
487 IONIC_PRINT(INFO, "eth.queue_count[IONIC_QTYPE_RXQ] 0x%" PRIx32 " ",
488 ident->lif.eth.config.queue_count[IONIC_QTYPE_RXQ]);
489 IONIC_PRINT(INFO, "eth.queue_count[IONIC_QTYPE_TXQ] 0x%" PRIx32 " ",
490 ident->lif.eth.config.queue_count[IONIC_QTYPE_TXQ]);
496 ionic_lifs_size(struct ionic_adapter *adapter)
498 struct ionic_identity *ident = &adapter->ident;
499 uint32_t nlifs = ident->dev.nlifs;
500 uint32_t nintrs, dev_nintrs = ident->dev.nintrs;
502 adapter->max_ntxqs_per_lif =
503 ident->lif.eth.config.queue_count[IONIC_QTYPE_TXQ];
504 adapter->max_nrxqs_per_lif =
505 ident->lif.eth.config.queue_count[IONIC_QTYPE_RXQ];
507 nintrs = nlifs * 1 /* notifyq */;
509 if (nintrs > dev_nintrs) {
510 IONIC_PRINT(ERR, "At most %d intr queues supported, minimum required is %u",
515 adapter->nintrs = nintrs;