1669c8de6SAlfredo Cardigliano /* SPDX-License-Identifier: (BSD-3-Clause OR GPL-2.0)
2669c8de6SAlfredo Cardigliano * Copyright(c) 2018-2019 Pensando Systems, Inc. All rights reserved.
3669c8de6SAlfredo Cardigliano */
4669c8de6SAlfredo Cardigliano
5669c8de6SAlfredo Cardigliano #include <rte_malloc.h>
6df96fd0dSBruce Richardson #include <ethdev_driver.h>
7669c8de6SAlfredo Cardigliano
8669c8de6SAlfredo Cardigliano #include "ionic.h"
9669c8de6SAlfredo Cardigliano #include "ionic_logs.h"
10669c8de6SAlfredo Cardigliano #include "ionic_lif.h"
11669c8de6SAlfredo Cardigliano #include "ionic_ethdev.h"
1254fe083fSAlfredo Cardigliano #include "ionic_rx_filter.h"
13a27d9013SAlfredo Cardigliano #include "ionic_rxtx.h"
14669c8de6SAlfredo Cardigliano
15c5d15850SAndrew Boyer /* queuetype support level */
16c5d15850SAndrew Boyer static const uint8_t ionic_qtype_vers[IONIC_QTYPE_MAX] = {
17c5d15850SAndrew Boyer [IONIC_QTYPE_ADMINQ] = 0, /* 0 = Base version with CQ support */
18c5d15850SAndrew Boyer [IONIC_QTYPE_NOTIFYQ] = 0, /* 0 = Base version */
19c5d15850SAndrew Boyer [IONIC_QTYPE_RXQ] = 2, /* 0 = Base version with CQ+SG support
20c5d15850SAndrew Boyer * 1 = ... with EQ
21c5d15850SAndrew Boyer * 2 = ... with CMB
22c5d15850SAndrew Boyer */
23c5d15850SAndrew Boyer [IONIC_QTYPE_TXQ] = 3, /* 0 = Base version with CQ+SG support
24c5d15850SAndrew Boyer * 1 = ... with Tx SG version 1
25c5d15850SAndrew Boyer * 2 = ... with EQ
26c5d15850SAndrew Boyer * 3 = ... with CMB
27c5d15850SAndrew Boyer */
28c5d15850SAndrew Boyer };
29c5d15850SAndrew Boyer
30598f6726SAlfredo Cardigliano static int ionic_lif_addr_add(struct ionic_lif *lif, const uint8_t *addr);
31598f6726SAlfredo Cardigliano static int ionic_lif_addr_del(struct ionic_lif *lif, const uint8_t *addr);
32598f6726SAlfredo Cardigliano
3301a6c311SAlfredo Cardigliano int
ionic_qcq_enable(struct ionic_qcq * qcq)3401a6c311SAlfredo Cardigliano ionic_qcq_enable(struct ionic_qcq *qcq)
3501a6c311SAlfredo Cardigliano {
3601a6c311SAlfredo Cardigliano struct ionic_queue *q = &qcq->q;
374ad56b7aSAndrew Boyer struct ionic_lif *lif = qcq->lif;
3801a6c311SAlfredo Cardigliano struct ionic_admin_ctx ctx = {
3901a6c311SAlfredo Cardigliano .pending_work = true,
4001a6c311SAlfredo Cardigliano .cmd.q_control = {
4101a6c311SAlfredo Cardigliano .opcode = IONIC_CMD_Q_CONTROL,
4201a6c311SAlfredo Cardigliano .type = q->type,
4309f806e9SAndrew Boyer .index = rte_cpu_to_le_32(q->index),
4401a6c311SAlfredo Cardigliano .oper = IONIC_Q_ENABLE,
4501a6c311SAlfredo Cardigliano },
4601a6c311SAlfredo Cardigliano };
4701a6c311SAlfredo Cardigliano
4801a6c311SAlfredo Cardigliano return ionic_adminq_post_wait(lif, &ctx);
4901a6c311SAlfredo Cardigliano }
5001a6c311SAlfredo Cardigliano
5101a6c311SAlfredo Cardigliano int
ionic_qcq_disable(struct ionic_qcq * qcq)5201a6c311SAlfredo Cardigliano ionic_qcq_disable(struct ionic_qcq *qcq)
5301a6c311SAlfredo Cardigliano {
5401a6c311SAlfredo Cardigliano struct ionic_queue *q = &qcq->q;
554ad56b7aSAndrew Boyer struct ionic_lif *lif = qcq->lif;
5601a6c311SAlfredo Cardigliano struct ionic_admin_ctx ctx = {
5701a6c311SAlfredo Cardigliano .pending_work = true,
5801a6c311SAlfredo Cardigliano .cmd.q_control = {
5901a6c311SAlfredo Cardigliano .opcode = IONIC_CMD_Q_CONTROL,
6001a6c311SAlfredo Cardigliano .type = q->type,
6109f806e9SAndrew Boyer .index = rte_cpu_to_le_32(q->index),
6201a6c311SAlfredo Cardigliano .oper = IONIC_Q_DISABLE,
6301a6c311SAlfredo Cardigliano },
6401a6c311SAlfredo Cardigliano };
6501a6c311SAlfredo Cardigliano
6601a6c311SAlfredo Cardigliano return ionic_adminq_post_wait(lif, &ctx);
6701a6c311SAlfredo Cardigliano }
6801a6c311SAlfredo Cardigliano
69be63459eSAndrew Boyer void
ionic_lif_stop(struct ionic_lif * lif)70be63459eSAndrew Boyer ionic_lif_stop(struct ionic_lif *lif)
71598f6726SAlfredo Cardigliano {
72a0a99f21SAndrew Boyer uint32_t i;
73a0a99f21SAndrew Boyer
74be63459eSAndrew Boyer IONIC_PRINT_CALL();
75598f6726SAlfredo Cardigliano
76be63459eSAndrew Boyer lif->state &= ~IONIC_LIF_F_UP;
77a0a99f21SAndrew Boyer
78a0a99f21SAndrew Boyer for (i = 0; i < lif->nrxqcqs; i++) {
79be39f75cSAndrew Boyer struct ionic_rx_qcq *rxq = lif->rxqcqs[i];
80a0a99f21SAndrew Boyer if (rxq->flags & IONIC_QCQ_F_INITED)
81a0a99f21SAndrew Boyer (void)ionic_dev_rx_queue_stop(lif->eth_dev, i);
82a0a99f21SAndrew Boyer }
83a0a99f21SAndrew Boyer
84a0a99f21SAndrew Boyer for (i = 0; i < lif->ntxqcqs; i++) {
85be39f75cSAndrew Boyer struct ionic_tx_qcq *txq = lif->txqcqs[i];
86a0a99f21SAndrew Boyer if (txq->flags & IONIC_QCQ_F_INITED)
87a0a99f21SAndrew Boyer (void)ionic_dev_tx_queue_stop(lif->eth_dev, i);
88a0a99f21SAndrew Boyer }
89598f6726SAlfredo Cardigliano }
90598f6726SAlfredo Cardigliano
91598f6726SAlfredo Cardigliano void
ionic_lif_reset(struct ionic_lif * lif)92598f6726SAlfredo Cardigliano ionic_lif_reset(struct ionic_lif *lif)
93598f6726SAlfredo Cardigliano {
94598f6726SAlfredo Cardigliano struct ionic_dev *idev = &lif->adapter->idev;
9575f96902SAndrew Boyer int err;
96598f6726SAlfredo Cardigliano
97598f6726SAlfredo Cardigliano IONIC_PRINT_CALL();
98598f6726SAlfredo Cardigliano
9900b65da5SAndrew Boyer ionic_dev_cmd_lif_reset(idev);
10075f96902SAndrew Boyer err = ionic_dev_cmd_wait_check(idev, IONIC_DEVCMD_TIMEOUT);
10175f96902SAndrew Boyer if (err)
1024ae96cb8SAndrew Boyer IONIC_PRINT(WARNING, "Failed to reset %s", lif->name);
103598f6726SAlfredo Cardigliano }
104598f6726SAlfredo Cardigliano
1053cdfd905SAlfredo Cardigliano static void
ionic_lif_get_abs_stats(const struct ionic_lif * lif,struct rte_eth_stats * stats)1063cdfd905SAlfredo Cardigliano ionic_lif_get_abs_stats(const struct ionic_lif *lif, struct rte_eth_stats *stats)
1073cdfd905SAlfredo Cardigliano {
1083cdfd905SAlfredo Cardigliano struct ionic_lif_stats *ls = &lif->info->stats;
1093cdfd905SAlfredo Cardigliano uint32_t i;
1103cdfd905SAlfredo Cardigliano uint32_t num_rx_q_counters = RTE_MIN(lif->nrxqcqs, (uint32_t)
1113cdfd905SAlfredo Cardigliano RTE_ETHDEV_QUEUE_STAT_CNTRS);
1123cdfd905SAlfredo Cardigliano uint32_t num_tx_q_counters = RTE_MIN(lif->ntxqcqs, (uint32_t)
1133cdfd905SAlfredo Cardigliano RTE_ETHDEV_QUEUE_STAT_CNTRS);
1143cdfd905SAlfredo Cardigliano
1153cdfd905SAlfredo Cardigliano memset(stats, 0, sizeof(*stats));
1163cdfd905SAlfredo Cardigliano
1173cdfd905SAlfredo Cardigliano if (ls == NULL) {
1183cdfd905SAlfredo Cardigliano IONIC_PRINT(DEBUG, "Stats on port %u not yet initialized",
1193cdfd905SAlfredo Cardigliano lif->port_id);
1203cdfd905SAlfredo Cardigliano return;
1213cdfd905SAlfredo Cardigliano }
1223cdfd905SAlfredo Cardigliano
1233cdfd905SAlfredo Cardigliano /* RX */
1243cdfd905SAlfredo Cardigliano
1253cdfd905SAlfredo Cardigliano stats->ipackets = ls->rx_ucast_packets +
1263cdfd905SAlfredo Cardigliano ls->rx_mcast_packets +
1273cdfd905SAlfredo Cardigliano ls->rx_bcast_packets;
1283cdfd905SAlfredo Cardigliano
1293cdfd905SAlfredo Cardigliano stats->ibytes = ls->rx_ucast_bytes +
1303cdfd905SAlfredo Cardigliano ls->rx_mcast_bytes +
1313cdfd905SAlfredo Cardigliano ls->rx_bcast_bytes;
1323cdfd905SAlfredo Cardigliano
1333cdfd905SAlfredo Cardigliano for (i = 0; i < lif->nrxqcqs; i++) {
134be39f75cSAndrew Boyer struct ionic_rx_stats *rx_stats = &lif->rxqcqs[i]->stats;
1353cdfd905SAlfredo Cardigliano stats->imissed +=
1363cdfd905SAlfredo Cardigliano rx_stats->no_cb_arg +
1373cdfd905SAlfredo Cardigliano rx_stats->bad_cq_status +
1383cdfd905SAlfredo Cardigliano rx_stats->no_room +
1393cdfd905SAlfredo Cardigliano rx_stats->bad_len;
1403cdfd905SAlfredo Cardigliano }
1413cdfd905SAlfredo Cardigliano
1423cdfd905SAlfredo Cardigliano stats->imissed +=
1433cdfd905SAlfredo Cardigliano ls->rx_ucast_drop_packets +
1443cdfd905SAlfredo Cardigliano ls->rx_mcast_drop_packets +
1453cdfd905SAlfredo Cardigliano ls->rx_bcast_drop_packets;
1463cdfd905SAlfredo Cardigliano
1473cdfd905SAlfredo Cardigliano stats->imissed +=
1483cdfd905SAlfredo Cardigliano ls->rx_queue_empty +
1493cdfd905SAlfredo Cardigliano ls->rx_dma_error +
1503cdfd905SAlfredo Cardigliano ls->rx_queue_disabled +
1513cdfd905SAlfredo Cardigliano ls->rx_desc_fetch_error +
1523cdfd905SAlfredo Cardigliano ls->rx_desc_data_error;
1533cdfd905SAlfredo Cardigliano
1543cdfd905SAlfredo Cardigliano for (i = 0; i < num_rx_q_counters; i++) {
155be39f75cSAndrew Boyer struct ionic_rx_stats *rx_stats = &lif->rxqcqs[i]->stats;
1563cdfd905SAlfredo Cardigliano stats->q_ipackets[i] = rx_stats->packets;
1573cdfd905SAlfredo Cardigliano stats->q_ibytes[i] = rx_stats->bytes;
1583cdfd905SAlfredo Cardigliano stats->q_errors[i] =
1593cdfd905SAlfredo Cardigliano rx_stats->no_cb_arg +
1603cdfd905SAlfredo Cardigliano rx_stats->bad_cq_status +
1613cdfd905SAlfredo Cardigliano rx_stats->no_room +
1623cdfd905SAlfredo Cardigliano rx_stats->bad_len;
1633cdfd905SAlfredo Cardigliano }
1643cdfd905SAlfredo Cardigliano
1653cdfd905SAlfredo Cardigliano /* TX */
1663cdfd905SAlfredo Cardigliano
1673cdfd905SAlfredo Cardigliano stats->opackets = ls->tx_ucast_packets +
1683cdfd905SAlfredo Cardigliano ls->tx_mcast_packets +
1693cdfd905SAlfredo Cardigliano ls->tx_bcast_packets;
1703cdfd905SAlfredo Cardigliano
1713cdfd905SAlfredo Cardigliano stats->obytes = ls->tx_ucast_bytes +
1723cdfd905SAlfredo Cardigliano ls->tx_mcast_bytes +
1733cdfd905SAlfredo Cardigliano ls->tx_bcast_bytes;
1743cdfd905SAlfredo Cardigliano
1753cdfd905SAlfredo Cardigliano for (i = 0; i < lif->ntxqcqs; i++) {
176be39f75cSAndrew Boyer struct ionic_tx_stats *tx_stats = &lif->txqcqs[i]->stats;
1773cdfd905SAlfredo Cardigliano stats->oerrors += tx_stats->drop;
1783cdfd905SAlfredo Cardigliano }
1793cdfd905SAlfredo Cardigliano
1803cdfd905SAlfredo Cardigliano stats->oerrors +=
1813cdfd905SAlfredo Cardigliano ls->tx_ucast_drop_packets +
1823cdfd905SAlfredo Cardigliano ls->tx_mcast_drop_packets +
1833cdfd905SAlfredo Cardigliano ls->tx_bcast_drop_packets;
1843cdfd905SAlfredo Cardigliano
1853cdfd905SAlfredo Cardigliano stats->oerrors +=
1863cdfd905SAlfredo Cardigliano ls->tx_dma_error +
1873cdfd905SAlfredo Cardigliano ls->tx_queue_disabled +
1883cdfd905SAlfredo Cardigliano ls->tx_desc_fetch_error +
1893cdfd905SAlfredo Cardigliano ls->tx_desc_data_error;
1903cdfd905SAlfredo Cardigliano
1913cdfd905SAlfredo Cardigliano for (i = 0; i < num_tx_q_counters; i++) {
192be39f75cSAndrew Boyer struct ionic_tx_stats *tx_stats = &lif->txqcqs[i]->stats;
1933cdfd905SAlfredo Cardigliano stats->q_opackets[i] = tx_stats->packets;
1943cdfd905SAlfredo Cardigliano stats->q_obytes[i] = tx_stats->bytes;
1953cdfd905SAlfredo Cardigliano }
1963cdfd905SAlfredo Cardigliano }
1973cdfd905SAlfredo Cardigliano
1983cdfd905SAlfredo Cardigliano void
ionic_lif_get_stats(const struct ionic_lif * lif,struct rte_eth_stats * stats)1993cdfd905SAlfredo Cardigliano ionic_lif_get_stats(const struct ionic_lif *lif,
2003cdfd905SAlfredo Cardigliano struct rte_eth_stats *stats)
2013cdfd905SAlfredo Cardigliano {
2023cdfd905SAlfredo Cardigliano ionic_lif_get_abs_stats(lif, stats);
2033cdfd905SAlfredo Cardigliano
2043cdfd905SAlfredo Cardigliano stats->ipackets -= lif->stats_base.ipackets;
2053cdfd905SAlfredo Cardigliano stats->opackets -= lif->stats_base.opackets;
2063cdfd905SAlfredo Cardigliano stats->ibytes -= lif->stats_base.ibytes;
2073cdfd905SAlfredo Cardigliano stats->obytes -= lif->stats_base.obytes;
2083cdfd905SAlfredo Cardigliano stats->imissed -= lif->stats_base.imissed;
2093cdfd905SAlfredo Cardigliano stats->ierrors -= lif->stats_base.ierrors;
2103cdfd905SAlfredo Cardigliano stats->oerrors -= lif->stats_base.oerrors;
2113cdfd905SAlfredo Cardigliano stats->rx_nombuf -= lif->stats_base.rx_nombuf;
2123cdfd905SAlfredo Cardigliano }
2133cdfd905SAlfredo Cardigliano
2143cdfd905SAlfredo Cardigliano void
ionic_lif_reset_stats(struct ionic_lif * lif)2153cdfd905SAlfredo Cardigliano ionic_lif_reset_stats(struct ionic_lif *lif)
2163cdfd905SAlfredo Cardigliano {
2173cdfd905SAlfredo Cardigliano uint32_t i;
2183cdfd905SAlfredo Cardigliano
2193cdfd905SAlfredo Cardigliano for (i = 0; i < lif->nrxqcqs; i++) {
220be39f75cSAndrew Boyer memset(&lif->rxqcqs[i]->stats, 0,
2213cdfd905SAlfredo Cardigliano sizeof(struct ionic_rx_stats));
222be39f75cSAndrew Boyer memset(&lif->txqcqs[i]->stats, 0,
2233cdfd905SAlfredo Cardigliano sizeof(struct ionic_tx_stats));
2243cdfd905SAlfredo Cardigliano }
2253cdfd905SAlfredo Cardigliano
2263cdfd905SAlfredo Cardigliano ionic_lif_get_abs_stats(lif, &lif->stats_base);
2273cdfd905SAlfredo Cardigliano }
2283cdfd905SAlfredo Cardigliano
2293cdfd905SAlfredo Cardigliano void
ionic_lif_get_hw_stats(struct ionic_lif * lif,struct ionic_lif_stats * stats)2303cdfd905SAlfredo Cardigliano ionic_lif_get_hw_stats(struct ionic_lif *lif, struct ionic_lif_stats *stats)
2313cdfd905SAlfredo Cardigliano {
2323cdfd905SAlfredo Cardigliano uint16_t i, count = sizeof(struct ionic_lif_stats) / sizeof(uint64_t);
2333cdfd905SAlfredo Cardigliano uint64_t *stats64 = (uint64_t *)stats;
2343cdfd905SAlfredo Cardigliano uint64_t *lif_stats64 = (uint64_t *)&lif->info->stats;
2353cdfd905SAlfredo Cardigliano uint64_t *lif_stats64_base = (uint64_t *)&lif->lif_stats_base;
2363cdfd905SAlfredo Cardigliano
2373cdfd905SAlfredo Cardigliano for (i = 0; i < count; i++)
2383cdfd905SAlfredo Cardigliano stats64[i] = lif_stats64[i] - lif_stats64_base[i];
2393cdfd905SAlfredo Cardigliano }
2403cdfd905SAlfredo Cardigliano
2413cdfd905SAlfredo Cardigliano void
ionic_lif_reset_hw_stats(struct ionic_lif * lif)2423cdfd905SAlfredo Cardigliano ionic_lif_reset_hw_stats(struct ionic_lif *lif)
2433cdfd905SAlfredo Cardigliano {
2443cdfd905SAlfredo Cardigliano uint16_t i, count = sizeof(struct ionic_lif_stats) / sizeof(uint64_t);
2453cdfd905SAlfredo Cardigliano uint64_t *lif_stats64 = (uint64_t *)&lif->info->stats;
2463cdfd905SAlfredo Cardigliano uint64_t *lif_stats64_base = (uint64_t *)&lif->lif_stats_base;
2473cdfd905SAlfredo Cardigliano
2483cdfd905SAlfredo Cardigliano for (i = 0; i < count; i++)
2493cdfd905SAlfredo Cardigliano lif_stats64_base[i] = lif_stats64[i];
2503cdfd905SAlfredo Cardigliano }
2513cdfd905SAlfredo Cardigliano
252598f6726SAlfredo Cardigliano static int
ionic_lif_addr_add(struct ionic_lif * lif,const uint8_t * addr)25354fe083fSAlfredo Cardigliano ionic_lif_addr_add(struct ionic_lif *lif, const uint8_t *addr)
254598f6726SAlfredo Cardigliano {
25554fe083fSAlfredo Cardigliano struct ionic_admin_ctx ctx = {
25654fe083fSAlfredo Cardigliano .pending_work = true,
25754fe083fSAlfredo Cardigliano .cmd.rx_filter_add = {
25854fe083fSAlfredo Cardigliano .opcode = IONIC_CMD_RX_FILTER_ADD,
25909f806e9SAndrew Boyer .match = rte_cpu_to_le_16(IONIC_RX_FILTER_MATCH_MAC),
26054fe083fSAlfredo Cardigliano },
26154fe083fSAlfredo Cardigliano };
26254fe083fSAlfredo Cardigliano int err;
26354fe083fSAlfredo Cardigliano
26454fe083fSAlfredo Cardigliano memcpy(ctx.cmd.rx_filter_add.mac.addr, addr, RTE_ETHER_ADDR_LEN);
26554fe083fSAlfredo Cardigliano
26654fe083fSAlfredo Cardigliano err = ionic_adminq_post_wait(lif, &ctx);
26754fe083fSAlfredo Cardigliano if (err)
26854fe083fSAlfredo Cardigliano return err;
26954fe083fSAlfredo Cardigliano
27054fe083fSAlfredo Cardigliano IONIC_PRINT(INFO, "rx_filter add (id %d)",
27109f806e9SAndrew Boyer rte_le_to_cpu_32(ctx.comp.rx_filter_add.filter_id));
27254fe083fSAlfredo Cardigliano
27354fe083fSAlfredo Cardigliano return ionic_rx_filter_save(lif, 0, IONIC_RXQ_INDEX_ANY, &ctx);
27454fe083fSAlfredo Cardigliano }
27554fe083fSAlfredo Cardigliano
27654fe083fSAlfredo Cardigliano static int
ionic_lif_addr_del(struct ionic_lif * lif,const uint8_t * addr)27754fe083fSAlfredo Cardigliano ionic_lif_addr_del(struct ionic_lif *lif, const uint8_t *addr)
27854fe083fSAlfredo Cardigliano {
27954fe083fSAlfredo Cardigliano struct ionic_admin_ctx ctx = {
28054fe083fSAlfredo Cardigliano .pending_work = true,
28154fe083fSAlfredo Cardigliano .cmd.rx_filter_del = {
28254fe083fSAlfredo Cardigliano .opcode = IONIC_CMD_RX_FILTER_DEL,
28354fe083fSAlfredo Cardigliano },
28454fe083fSAlfredo Cardigliano };
28554fe083fSAlfredo Cardigliano struct ionic_rx_filter *f;
28654fe083fSAlfredo Cardigliano int err;
28754fe083fSAlfredo Cardigliano
28854fe083fSAlfredo Cardigliano IONIC_PRINT_CALL();
28954fe083fSAlfredo Cardigliano
29054fe083fSAlfredo Cardigliano rte_spinlock_lock(&lif->rx_filters.lock);
29154fe083fSAlfredo Cardigliano
29254fe083fSAlfredo Cardigliano f = ionic_rx_filter_by_addr(lif, addr);
29354fe083fSAlfredo Cardigliano if (!f) {
29454fe083fSAlfredo Cardigliano rte_spinlock_unlock(&lif->rx_filters.lock);
29554fe083fSAlfredo Cardigliano return -ENOENT;
29654fe083fSAlfredo Cardigliano }
29754fe083fSAlfredo Cardigliano
29809f806e9SAndrew Boyer ctx.cmd.rx_filter_del.filter_id = rte_cpu_to_le_32(f->filter_id);
29954fe083fSAlfredo Cardigliano ionic_rx_filter_free(f);
30054fe083fSAlfredo Cardigliano
30154fe083fSAlfredo Cardigliano rte_spinlock_unlock(&lif->rx_filters.lock);
30254fe083fSAlfredo Cardigliano
30354fe083fSAlfredo Cardigliano err = ionic_adminq_post_wait(lif, &ctx);
30454fe083fSAlfredo Cardigliano if (err)
30554fe083fSAlfredo Cardigliano return err;
30654fe083fSAlfredo Cardigliano
30754fe083fSAlfredo Cardigliano IONIC_PRINT(INFO, "rx_filter del (id %d)",
30809f806e9SAndrew Boyer rte_le_to_cpu_32(ctx.cmd.rx_filter_del.filter_id));
309598f6726SAlfredo Cardigliano
310598f6726SAlfredo Cardigliano return 0;
311598f6726SAlfredo Cardigliano }
312598f6726SAlfredo Cardigliano
31354fe083fSAlfredo Cardigliano int
ionic_dev_add_mac(struct rte_eth_dev * eth_dev,struct rte_ether_addr * mac_addr,uint32_t index __rte_unused,uint32_t pool __rte_unused)31454fe083fSAlfredo Cardigliano ionic_dev_add_mac(struct rte_eth_dev *eth_dev,
31554fe083fSAlfredo Cardigliano struct rte_ether_addr *mac_addr,
31654fe083fSAlfredo Cardigliano uint32_t index __rte_unused, uint32_t pool __rte_unused)
317598f6726SAlfredo Cardigliano {
31854fe083fSAlfredo Cardigliano struct ionic_lif *lif = IONIC_ETH_DEV_TO_LIF(eth_dev);
31954fe083fSAlfredo Cardigliano
32054fe083fSAlfredo Cardigliano IONIC_PRINT_CALL();
32154fe083fSAlfredo Cardigliano
32254fe083fSAlfredo Cardigliano return ionic_lif_addr_add(lif, (const uint8_t *)mac_addr);
32354fe083fSAlfredo Cardigliano }
32454fe083fSAlfredo Cardigliano
32554fe083fSAlfredo Cardigliano void
ionic_dev_remove_mac(struct rte_eth_dev * eth_dev,uint32_t index)32675f96902SAndrew Boyer ionic_dev_remove_mac(struct rte_eth_dev *eth_dev, uint32_t index)
32754fe083fSAlfredo Cardigliano {
32854fe083fSAlfredo Cardigliano struct ionic_lif *lif = IONIC_ETH_DEV_TO_LIF(eth_dev);
32954fe083fSAlfredo Cardigliano struct ionic_adapter *adapter = lif->adapter;
33075f96902SAndrew Boyer struct rte_ether_addr *mac_addr;
33154fe083fSAlfredo Cardigliano
33254fe083fSAlfredo Cardigliano IONIC_PRINT_CALL();
33354fe083fSAlfredo Cardigliano
33454fe083fSAlfredo Cardigliano if (index >= adapter->max_mac_addrs) {
33554fe083fSAlfredo Cardigliano IONIC_PRINT(WARNING,
33654fe083fSAlfredo Cardigliano "Index %u is above MAC filter limit %u",
33754fe083fSAlfredo Cardigliano index, adapter->max_mac_addrs);
33854fe083fSAlfredo Cardigliano return;
33954fe083fSAlfredo Cardigliano }
34054fe083fSAlfredo Cardigliano
34175f96902SAndrew Boyer mac_addr = ð_dev->data->mac_addrs[index];
34275f96902SAndrew Boyer
34375f96902SAndrew Boyer if (!rte_is_valid_assigned_ether_addr(mac_addr))
34454fe083fSAlfredo Cardigliano return;
34554fe083fSAlfredo Cardigliano
34675f96902SAndrew Boyer ionic_lif_addr_del(lif, (const uint8_t *)mac_addr);
34754fe083fSAlfredo Cardigliano }
34854fe083fSAlfredo Cardigliano
34954fe083fSAlfredo Cardigliano int
ionic_dev_set_mac(struct rte_eth_dev * eth_dev,struct rte_ether_addr * mac_addr)35054fe083fSAlfredo Cardigliano ionic_dev_set_mac(struct rte_eth_dev *eth_dev, struct rte_ether_addr *mac_addr)
35154fe083fSAlfredo Cardigliano {
35254fe083fSAlfredo Cardigliano struct ionic_lif *lif = IONIC_ETH_DEV_TO_LIF(eth_dev);
35354fe083fSAlfredo Cardigliano
35454fe083fSAlfredo Cardigliano IONIC_PRINT_CALL();
35554fe083fSAlfredo Cardigliano
35654fe083fSAlfredo Cardigliano if (mac_addr == NULL) {
35754fe083fSAlfredo Cardigliano IONIC_PRINT(NOTICE, "New mac is null");
35854fe083fSAlfredo Cardigliano return -1;
35954fe083fSAlfredo Cardigliano }
36054fe083fSAlfredo Cardigliano
36154fe083fSAlfredo Cardigliano if (!rte_is_zero_ether_addr((struct rte_ether_addr *)lif->mac_addr)) {
36254fe083fSAlfredo Cardigliano IONIC_PRINT(INFO, "Deleting mac addr %pM",
36354fe083fSAlfredo Cardigliano lif->mac_addr);
36454fe083fSAlfredo Cardigliano ionic_lif_addr_del(lif, lif->mac_addr);
36554fe083fSAlfredo Cardigliano memset(lif->mac_addr, 0, RTE_ETHER_ADDR_LEN);
36654fe083fSAlfredo Cardigliano }
36754fe083fSAlfredo Cardigliano
36854fe083fSAlfredo Cardigliano IONIC_PRINT(INFO, "Updating mac addr");
36954fe083fSAlfredo Cardigliano
37054fe083fSAlfredo Cardigliano rte_ether_addr_copy(mac_addr, (struct rte_ether_addr *)lif->mac_addr);
37154fe083fSAlfredo Cardigliano
37254fe083fSAlfredo Cardigliano return ionic_lif_addr_add(lif, (const uint8_t *)mac_addr);
37354fe083fSAlfredo Cardigliano }
37454fe083fSAlfredo Cardigliano
37554fe083fSAlfredo Cardigliano static int
ionic_vlan_rx_add_vid(struct ionic_lif * lif,uint16_t vid)37654fe083fSAlfredo Cardigliano ionic_vlan_rx_add_vid(struct ionic_lif *lif, uint16_t vid)
37754fe083fSAlfredo Cardigliano {
37854fe083fSAlfredo Cardigliano struct ionic_admin_ctx ctx = {
37954fe083fSAlfredo Cardigliano .pending_work = true,
38054fe083fSAlfredo Cardigliano .cmd.rx_filter_add = {
38154fe083fSAlfredo Cardigliano .opcode = IONIC_CMD_RX_FILTER_ADD,
38209f806e9SAndrew Boyer .match = rte_cpu_to_le_16(IONIC_RX_FILTER_MATCH_VLAN),
38309f806e9SAndrew Boyer .vlan.vlan = rte_cpu_to_le_16(vid),
38454fe083fSAlfredo Cardigliano },
38554fe083fSAlfredo Cardigliano };
38654fe083fSAlfredo Cardigliano int err;
38754fe083fSAlfredo Cardigliano
38854fe083fSAlfredo Cardigliano err = ionic_adminq_post_wait(lif, &ctx);
38954fe083fSAlfredo Cardigliano if (err)
39054fe083fSAlfredo Cardigliano return err;
39154fe083fSAlfredo Cardigliano
39254fe083fSAlfredo Cardigliano IONIC_PRINT(INFO, "rx_filter add VLAN %d (id %d)", vid,
39309f806e9SAndrew Boyer rte_le_to_cpu_32(ctx.comp.rx_filter_add.filter_id));
39454fe083fSAlfredo Cardigliano
39554fe083fSAlfredo Cardigliano return ionic_rx_filter_save(lif, 0, IONIC_RXQ_INDEX_ANY, &ctx);
39654fe083fSAlfredo Cardigliano }
39754fe083fSAlfredo Cardigliano
39854fe083fSAlfredo Cardigliano static int
ionic_vlan_rx_kill_vid(struct ionic_lif * lif,uint16_t vid)39954fe083fSAlfredo Cardigliano ionic_vlan_rx_kill_vid(struct ionic_lif *lif, uint16_t vid)
40054fe083fSAlfredo Cardigliano {
40154fe083fSAlfredo Cardigliano struct ionic_admin_ctx ctx = {
40254fe083fSAlfredo Cardigliano .pending_work = true,
40354fe083fSAlfredo Cardigliano .cmd.rx_filter_del = {
40454fe083fSAlfredo Cardigliano .opcode = IONIC_CMD_RX_FILTER_DEL,
40554fe083fSAlfredo Cardigliano },
40654fe083fSAlfredo Cardigliano };
40754fe083fSAlfredo Cardigliano struct ionic_rx_filter *f;
40854fe083fSAlfredo Cardigliano int err;
40954fe083fSAlfredo Cardigliano
41054fe083fSAlfredo Cardigliano IONIC_PRINT_CALL();
41154fe083fSAlfredo Cardigliano
41254fe083fSAlfredo Cardigliano rte_spinlock_lock(&lif->rx_filters.lock);
41354fe083fSAlfredo Cardigliano
41454fe083fSAlfredo Cardigliano f = ionic_rx_filter_by_vlan(lif, vid);
41554fe083fSAlfredo Cardigliano if (!f) {
41654fe083fSAlfredo Cardigliano rte_spinlock_unlock(&lif->rx_filters.lock);
41754fe083fSAlfredo Cardigliano return -ENOENT;
41854fe083fSAlfredo Cardigliano }
41954fe083fSAlfredo Cardigliano
42009f806e9SAndrew Boyer ctx.cmd.rx_filter_del.filter_id = rte_cpu_to_le_32(f->filter_id);
42154fe083fSAlfredo Cardigliano ionic_rx_filter_free(f);
42254fe083fSAlfredo Cardigliano rte_spinlock_unlock(&lif->rx_filters.lock);
42354fe083fSAlfredo Cardigliano
42454fe083fSAlfredo Cardigliano err = ionic_adminq_post_wait(lif, &ctx);
42554fe083fSAlfredo Cardigliano if (err)
42654fe083fSAlfredo Cardigliano return err;
42754fe083fSAlfredo Cardigliano
42854fe083fSAlfredo Cardigliano IONIC_PRINT(INFO, "rx_filter del VLAN %d (id %d)", vid,
42909f806e9SAndrew Boyer rte_le_to_cpu_32(ctx.cmd.rx_filter_del.filter_id));
430598f6726SAlfredo Cardigliano
431598f6726SAlfredo Cardigliano return 0;
432598f6726SAlfredo Cardigliano }
433598f6726SAlfredo Cardigliano
43454fe083fSAlfredo Cardigliano int
ionic_dev_vlan_filter_set(struct rte_eth_dev * eth_dev,uint16_t vlan_id,int on)43554fe083fSAlfredo Cardigliano ionic_dev_vlan_filter_set(struct rte_eth_dev *eth_dev, uint16_t vlan_id,
43654fe083fSAlfredo Cardigliano int on)
43754fe083fSAlfredo Cardigliano {
43854fe083fSAlfredo Cardigliano struct ionic_lif *lif = IONIC_ETH_DEV_TO_LIF(eth_dev);
43954fe083fSAlfredo Cardigliano int err;
44054fe083fSAlfredo Cardigliano
44154fe083fSAlfredo Cardigliano if (on)
44254fe083fSAlfredo Cardigliano err = ionic_vlan_rx_add_vid(lif, vlan_id);
44354fe083fSAlfredo Cardigliano else
44454fe083fSAlfredo Cardigliano err = ionic_vlan_rx_kill_vid(lif, vlan_id);
44554fe083fSAlfredo Cardigliano
44654fe083fSAlfredo Cardigliano return err;
44754fe083fSAlfredo Cardigliano }
44854fe083fSAlfredo Cardigliano
449598f6726SAlfredo Cardigliano static void
ionic_lif_rx_mode(struct ionic_lif * lif,uint32_t rx_mode)450598f6726SAlfredo Cardigliano ionic_lif_rx_mode(struct ionic_lif *lif, uint32_t rx_mode)
451598f6726SAlfredo Cardigliano {
452598f6726SAlfredo Cardigliano struct ionic_admin_ctx ctx = {
453598f6726SAlfredo Cardigliano .pending_work = true,
454598f6726SAlfredo Cardigliano .cmd.rx_mode_set = {
455598f6726SAlfredo Cardigliano .opcode = IONIC_CMD_RX_MODE_SET,
45609f806e9SAndrew Boyer .rx_mode = rte_cpu_to_le_16(rx_mode),
457598f6726SAlfredo Cardigliano },
458598f6726SAlfredo Cardigliano };
459598f6726SAlfredo Cardigliano int err;
460598f6726SAlfredo Cardigliano
461598f6726SAlfredo Cardigliano if (rx_mode & IONIC_RX_MODE_F_UNICAST)
462598f6726SAlfredo Cardigliano IONIC_PRINT(DEBUG, "rx_mode IONIC_RX_MODE_F_UNICAST");
463598f6726SAlfredo Cardigliano if (rx_mode & IONIC_RX_MODE_F_MULTICAST)
464598f6726SAlfredo Cardigliano IONIC_PRINT(DEBUG, "rx_mode IONIC_RX_MODE_F_MULTICAST");
465598f6726SAlfredo Cardigliano if (rx_mode & IONIC_RX_MODE_F_BROADCAST)
466598f6726SAlfredo Cardigliano IONIC_PRINT(DEBUG, "rx_mode IONIC_RX_MODE_F_BROADCAST");
467598f6726SAlfredo Cardigliano if (rx_mode & IONIC_RX_MODE_F_PROMISC)
468598f6726SAlfredo Cardigliano IONIC_PRINT(DEBUG, "rx_mode IONIC_RX_MODE_F_PROMISC");
469598f6726SAlfredo Cardigliano if (rx_mode & IONIC_RX_MODE_F_ALLMULTI)
470598f6726SAlfredo Cardigliano IONIC_PRINT(DEBUG, "rx_mode IONIC_RX_MODE_F_ALLMULTI");
471598f6726SAlfredo Cardigliano
472598f6726SAlfredo Cardigliano err = ionic_adminq_post_wait(lif, &ctx);
473598f6726SAlfredo Cardigliano if (err)
474598f6726SAlfredo Cardigliano IONIC_PRINT(ERR, "Failure setting RX mode");
475598f6726SAlfredo Cardigliano }
476598f6726SAlfredo Cardigliano
477598f6726SAlfredo Cardigliano static void
ionic_set_rx_mode(struct ionic_lif * lif,uint32_t rx_mode)478598f6726SAlfredo Cardigliano ionic_set_rx_mode(struct ionic_lif *lif, uint32_t rx_mode)
479598f6726SAlfredo Cardigliano {
480598f6726SAlfredo Cardigliano if (lif->rx_mode != rx_mode) {
481598f6726SAlfredo Cardigliano lif->rx_mode = rx_mode;
482598f6726SAlfredo Cardigliano ionic_lif_rx_mode(lif, rx_mode);
483598f6726SAlfredo Cardigliano }
484598f6726SAlfredo Cardigliano }
485598f6726SAlfredo Cardigliano
48654fe083fSAlfredo Cardigliano int
ionic_dev_promiscuous_enable(struct rte_eth_dev * eth_dev)48754fe083fSAlfredo Cardigliano ionic_dev_promiscuous_enable(struct rte_eth_dev *eth_dev)
48854fe083fSAlfredo Cardigliano {
48954fe083fSAlfredo Cardigliano struct ionic_lif *lif = IONIC_ETH_DEV_TO_LIF(eth_dev);
49054fe083fSAlfredo Cardigliano uint32_t rx_mode = lif->rx_mode;
49154fe083fSAlfredo Cardigliano
49254fe083fSAlfredo Cardigliano IONIC_PRINT_CALL();
49354fe083fSAlfredo Cardigliano
49454fe083fSAlfredo Cardigliano rx_mode |= IONIC_RX_MODE_F_PROMISC;
49554fe083fSAlfredo Cardigliano
49654fe083fSAlfredo Cardigliano ionic_set_rx_mode(lif, rx_mode);
49754fe083fSAlfredo Cardigliano
49854fe083fSAlfredo Cardigliano return 0;
49954fe083fSAlfredo Cardigliano }
50054fe083fSAlfredo Cardigliano
50154fe083fSAlfredo Cardigliano int
ionic_dev_promiscuous_disable(struct rte_eth_dev * eth_dev)50254fe083fSAlfredo Cardigliano ionic_dev_promiscuous_disable(struct rte_eth_dev *eth_dev)
50354fe083fSAlfredo Cardigliano {
50454fe083fSAlfredo Cardigliano struct ionic_lif *lif = IONIC_ETH_DEV_TO_LIF(eth_dev);
50554fe083fSAlfredo Cardigliano uint32_t rx_mode = lif->rx_mode;
50654fe083fSAlfredo Cardigliano
50754fe083fSAlfredo Cardigliano rx_mode &= ~IONIC_RX_MODE_F_PROMISC;
50854fe083fSAlfredo Cardigliano
50954fe083fSAlfredo Cardigliano ionic_set_rx_mode(lif, rx_mode);
51054fe083fSAlfredo Cardigliano
51154fe083fSAlfredo Cardigliano return 0;
51254fe083fSAlfredo Cardigliano }
51354fe083fSAlfredo Cardigliano
51454fe083fSAlfredo Cardigliano int
ionic_dev_allmulticast_enable(struct rte_eth_dev * eth_dev)51554fe083fSAlfredo Cardigliano ionic_dev_allmulticast_enable(struct rte_eth_dev *eth_dev)
51654fe083fSAlfredo Cardigliano {
51754fe083fSAlfredo Cardigliano struct ionic_lif *lif = IONIC_ETH_DEV_TO_LIF(eth_dev);
51854fe083fSAlfredo Cardigliano uint32_t rx_mode = lif->rx_mode;
51954fe083fSAlfredo Cardigliano
52054fe083fSAlfredo Cardigliano rx_mode |= IONIC_RX_MODE_F_ALLMULTI;
52154fe083fSAlfredo Cardigliano
52254fe083fSAlfredo Cardigliano ionic_set_rx_mode(lif, rx_mode);
52354fe083fSAlfredo Cardigliano
52454fe083fSAlfredo Cardigliano return 0;
52554fe083fSAlfredo Cardigliano }
52654fe083fSAlfredo Cardigliano
52754fe083fSAlfredo Cardigliano int
ionic_dev_allmulticast_disable(struct rte_eth_dev * eth_dev)52854fe083fSAlfredo Cardigliano ionic_dev_allmulticast_disable(struct rte_eth_dev *eth_dev)
52954fe083fSAlfredo Cardigliano {
53054fe083fSAlfredo Cardigliano struct ionic_lif *lif = IONIC_ETH_DEV_TO_LIF(eth_dev);
53154fe083fSAlfredo Cardigliano uint32_t rx_mode = lif->rx_mode;
53254fe083fSAlfredo Cardigliano
53354fe083fSAlfredo Cardigliano rx_mode &= ~IONIC_RX_MODE_F_ALLMULTI;
53454fe083fSAlfredo Cardigliano
53554fe083fSAlfredo Cardigliano ionic_set_rx_mode(lif, rx_mode);
53654fe083fSAlfredo Cardigliano
53754fe083fSAlfredo Cardigliano return 0;
53854fe083fSAlfredo Cardigliano }
539598f6726SAlfredo Cardigliano
540598f6726SAlfredo Cardigliano int
ionic_lif_change_mtu(struct ionic_lif * lif,int new_mtu)541598f6726SAlfredo Cardigliano ionic_lif_change_mtu(struct ionic_lif *lif, int new_mtu)
542598f6726SAlfredo Cardigliano {
543598f6726SAlfredo Cardigliano struct ionic_admin_ctx ctx = {
544598f6726SAlfredo Cardigliano .pending_work = true,
545598f6726SAlfredo Cardigliano .cmd.lif_setattr = {
546598f6726SAlfredo Cardigliano .opcode = IONIC_CMD_LIF_SETATTR,
547598f6726SAlfredo Cardigliano .attr = IONIC_LIF_ATTR_MTU,
54809f806e9SAndrew Boyer .mtu = rte_cpu_to_le_32(new_mtu),
549598f6726SAlfredo Cardigliano },
550598f6726SAlfredo Cardigliano };
551598f6726SAlfredo Cardigliano int err;
552598f6726SAlfredo Cardigliano
553598f6726SAlfredo Cardigliano err = ionic_adminq_post_wait(lif, &ctx);
554598f6726SAlfredo Cardigliano if (err)
555598f6726SAlfredo Cardigliano return err;
556598f6726SAlfredo Cardigliano
557598f6726SAlfredo Cardigliano return 0;
558598f6726SAlfredo Cardigliano }
559598f6726SAlfredo Cardigliano
560598f6726SAlfredo Cardigliano int
ionic_intr_alloc(struct ionic_lif * lif,struct ionic_intr_info * intr)56101a6c311SAlfredo Cardigliano ionic_intr_alloc(struct ionic_lif *lif, struct ionic_intr_info *intr)
56201a6c311SAlfredo Cardigliano {
56301a6c311SAlfredo Cardigliano struct ionic_adapter *adapter = lif->adapter;
56401a6c311SAlfredo Cardigliano struct ionic_dev *idev = &adapter->idev;
56501a6c311SAlfredo Cardigliano unsigned long index;
56601a6c311SAlfredo Cardigliano
56701a6c311SAlfredo Cardigliano /*
56801a6c311SAlfredo Cardigliano * Note: interrupt handler is called for index = 0 only
56901a6c311SAlfredo Cardigliano * (we use interrupts for the notifyq only anyway,
5704ae96cb8SAndrew Boyer * which has index = 0)
57101a6c311SAlfredo Cardigliano */
57201a6c311SAlfredo Cardigliano
57301a6c311SAlfredo Cardigliano for (index = 0; index < adapter->nintrs; index++)
57401a6c311SAlfredo Cardigliano if (!adapter->intrs[index])
57501a6c311SAlfredo Cardigliano break;
57601a6c311SAlfredo Cardigliano
57701a6c311SAlfredo Cardigliano if (index == adapter->nintrs)
57801a6c311SAlfredo Cardigliano return -ENOSPC;
57901a6c311SAlfredo Cardigliano
58001a6c311SAlfredo Cardigliano adapter->intrs[index] = true;
58101a6c311SAlfredo Cardigliano
58201a6c311SAlfredo Cardigliano ionic_intr_init(idev, intr, index);
58301a6c311SAlfredo Cardigliano
58401a6c311SAlfredo Cardigliano return 0;
58501a6c311SAlfredo Cardigliano }
58601a6c311SAlfredo Cardigliano
58701a6c311SAlfredo Cardigliano static int
ionic_qcq_alloc(struct ionic_lif * lif,uint8_t type,size_t struct_size,uint32_t socket_id,uint32_t index,const char * type_name,uint16_t flags,uint16_t num_descs,uint16_t desc_size,uint16_t cq_desc_size,uint16_t sg_desc_size,struct ionic_qcq ** qcq)5884ad56b7aSAndrew Boyer ionic_qcq_alloc(struct ionic_lif *lif,
5894ad56b7aSAndrew Boyer uint8_t type,
590be39f75cSAndrew Boyer size_t struct_size,
5918ec5ad7fSAndrew Boyer uint32_t socket_id,
59201a6c311SAlfredo Cardigliano uint32_t index,
5934ad56b7aSAndrew Boyer const char *type_name,
5944ad56b7aSAndrew Boyer uint16_t flags,
5954ad56b7aSAndrew Boyer uint16_t num_descs,
5964ad56b7aSAndrew Boyer uint16_t desc_size,
5974ad56b7aSAndrew Boyer uint16_t cq_desc_size,
5984ad56b7aSAndrew Boyer uint16_t sg_desc_size,
5991abf69fcSAndrew Boyer struct ionic_qcq **qcq)
60001a6c311SAlfredo Cardigliano {
60101a6c311SAlfredo Cardigliano struct ionic_qcq *new;
60201a6c311SAlfredo Cardigliano uint32_t q_size, cq_size, sg_size, total_size;
60301a6c311SAlfredo Cardigliano void *q_base, *cq_base, *sg_base;
60401a6c311SAlfredo Cardigliano rte_iova_t q_base_pa = 0;
60501a6c311SAlfredo Cardigliano rte_iova_t cq_base_pa = 0;
60601a6c311SAlfredo Cardigliano rte_iova_t sg_base_pa = 0;
60701a6c311SAlfredo Cardigliano int err;
60801a6c311SAlfredo Cardigliano
60901a6c311SAlfredo Cardigliano *qcq = NULL;
61001a6c311SAlfredo Cardigliano
61101a6c311SAlfredo Cardigliano q_size = num_descs * desc_size;
61201a6c311SAlfredo Cardigliano cq_size = num_descs * cq_desc_size;
61301a6c311SAlfredo Cardigliano sg_size = num_descs * sg_desc_size;
61401a6c311SAlfredo Cardigliano
615924e6b76SThomas Monjalon total_size = RTE_ALIGN(q_size, rte_mem_page_size()) +
616924e6b76SThomas Monjalon RTE_ALIGN(cq_size, rte_mem_page_size());
61701a6c311SAlfredo Cardigliano /*
61801a6c311SAlfredo Cardigliano * Note: aligning q_size/cq_size is not enough due to cq_base address
61901a6c311SAlfredo Cardigliano * aligning as q_base could be not aligned to the page.
620924e6b76SThomas Monjalon * Adding rte_mem_page_size().
62101a6c311SAlfredo Cardigliano */
622924e6b76SThomas Monjalon total_size += rte_mem_page_size();
62301a6c311SAlfredo Cardigliano
62401a6c311SAlfredo Cardigliano if (flags & IONIC_QCQ_F_SG) {
625924e6b76SThomas Monjalon total_size += RTE_ALIGN(sg_size, rte_mem_page_size());
626924e6b76SThomas Monjalon total_size += rte_mem_page_size();
62701a6c311SAlfredo Cardigliano }
62801a6c311SAlfredo Cardigliano
629be39f75cSAndrew Boyer new = rte_zmalloc("ionic", struct_size, 0);
63001a6c311SAlfredo Cardigliano if (!new) {
63101a6c311SAlfredo Cardigliano IONIC_PRINT(ERR, "Cannot allocate queue structure");
63201a6c311SAlfredo Cardigliano return -ENOMEM;
63301a6c311SAlfredo Cardigliano }
63401a6c311SAlfredo Cardigliano
63501a6c311SAlfredo Cardigliano new->lif = lif;
63601a6c311SAlfredo Cardigliano
637be39f75cSAndrew Boyer new->q.info = rte_calloc_socket("ionic",
638be39f75cSAndrew Boyer num_descs, sizeof(void *),
639924e6b76SThomas Monjalon rte_mem_page_size(), socket_id);
64001a6c311SAlfredo Cardigliano if (!new->q.info) {
64101a6c311SAlfredo Cardigliano IONIC_PRINT(ERR, "Cannot allocate queue info");
6424c8f8d57SAndrew Boyer err = -ENOMEM;
6434c8f8d57SAndrew Boyer goto err_out_free_qcq;
64401a6c311SAlfredo Cardigliano }
64501a6c311SAlfredo Cardigliano
64601a6c311SAlfredo Cardigliano new->q.type = type;
64701a6c311SAlfredo Cardigliano
6484ad56b7aSAndrew Boyer err = ionic_q_init(&new->q, index, num_descs);
64901a6c311SAlfredo Cardigliano if (err) {
65001a6c311SAlfredo Cardigliano IONIC_PRINT(ERR, "Queue initialization failed");
6514c8f8d57SAndrew Boyer goto err_out_free_info;
65201a6c311SAlfredo Cardigliano }
65301a6c311SAlfredo Cardigliano
6542aed9865SAndrew Boyer err = ionic_cq_init(&new->cq, num_descs);
65501a6c311SAlfredo Cardigliano if (err) {
65601a6c311SAlfredo Cardigliano IONIC_PRINT(ERR, "Completion queue initialization failed");
6574c8f8d57SAndrew Boyer goto err_out_free_info;
65801a6c311SAlfredo Cardigliano }
65901a6c311SAlfredo Cardigliano
66001a6c311SAlfredo Cardigliano new->base_z = rte_eth_dma_zone_reserve(lif->eth_dev,
6614ad56b7aSAndrew Boyer type_name, index /* queue_idx */,
66201a6c311SAlfredo Cardigliano total_size, IONIC_ALIGN, socket_id);
66301a6c311SAlfredo Cardigliano
66401a6c311SAlfredo Cardigliano if (!new->base_z) {
66501a6c311SAlfredo Cardigliano IONIC_PRINT(ERR, "Cannot reserve queue DMA memory");
66601a6c311SAlfredo Cardigliano err = -ENOMEM;
6674c8f8d57SAndrew Boyer goto err_out_free_info;
66801a6c311SAlfredo Cardigliano }
66901a6c311SAlfredo Cardigliano
67001a6c311SAlfredo Cardigliano new->base = new->base_z->addr;
67101a6c311SAlfredo Cardigliano new->base_pa = new->base_z->iova;
67201a6c311SAlfredo Cardigliano
67301a6c311SAlfredo Cardigliano q_base = new->base;
67401a6c311SAlfredo Cardigliano q_base_pa = new->base_pa;
67501a6c311SAlfredo Cardigliano
676924e6b76SThomas Monjalon cq_base = (void *)RTE_ALIGN((uintptr_t)q_base + q_size,
677924e6b76SThomas Monjalon rte_mem_page_size());
678924e6b76SThomas Monjalon cq_base_pa = RTE_ALIGN(q_base_pa + q_size,
679924e6b76SThomas Monjalon rte_mem_page_size());
68001a6c311SAlfredo Cardigliano
68101a6c311SAlfredo Cardigliano if (flags & IONIC_QCQ_F_SG) {
68201a6c311SAlfredo Cardigliano sg_base = (void *)RTE_ALIGN((uintptr_t)cq_base + cq_size,
683924e6b76SThomas Monjalon rte_mem_page_size());
684924e6b76SThomas Monjalon sg_base_pa = RTE_ALIGN(cq_base_pa + cq_size,
685924e6b76SThomas Monjalon rte_mem_page_size());
68601a6c311SAlfredo Cardigliano ionic_q_sg_map(&new->q, sg_base, sg_base_pa);
68701a6c311SAlfredo Cardigliano }
68801a6c311SAlfredo Cardigliano
6894ae96cb8SAndrew Boyer IONIC_PRINT(DEBUG, "Q-Base-PA = %#jx CQ-Base-PA = %#jx "
6904ae96cb8SAndrew Boyer "SG-base-PA = %#jx",
69101a6c311SAlfredo Cardigliano q_base_pa, cq_base_pa, sg_base_pa);
69201a6c311SAlfredo Cardigliano
69301a6c311SAlfredo Cardigliano ionic_q_map(&new->q, q_base, q_base_pa);
69401a6c311SAlfredo Cardigliano ionic_cq_map(&new->cq, cq_base, cq_base_pa);
69501a6c311SAlfredo Cardigliano
69601a6c311SAlfredo Cardigliano *qcq = new;
69701a6c311SAlfredo Cardigliano
69801a6c311SAlfredo Cardigliano return 0;
69901a6c311SAlfredo Cardigliano
7004c8f8d57SAndrew Boyer err_out_free_info:
7014c8f8d57SAndrew Boyer rte_free(new->q.info);
7024c8f8d57SAndrew Boyer err_out_free_qcq:
7034c8f8d57SAndrew Boyer rte_free(new);
70401a6c311SAlfredo Cardigliano
70501a6c311SAlfredo Cardigliano return err;
70601a6c311SAlfredo Cardigliano }
70701a6c311SAlfredo Cardigliano
70801a6c311SAlfredo Cardigliano void
ionic_qcq_free(struct ionic_qcq * qcq)70901a6c311SAlfredo Cardigliano ionic_qcq_free(struct ionic_qcq *qcq)
71001a6c311SAlfredo Cardigliano {
71101a6c311SAlfredo Cardigliano if (qcq->base_z) {
71201a6c311SAlfredo Cardigliano qcq->base = NULL;
71301a6c311SAlfredo Cardigliano qcq->base_pa = 0;
71401a6c311SAlfredo Cardigliano rte_memzone_free(qcq->base_z);
71501a6c311SAlfredo Cardigliano qcq->base_z = NULL;
71601a6c311SAlfredo Cardigliano }
71701a6c311SAlfredo Cardigliano
71801a6c311SAlfredo Cardigliano if (qcq->q.info) {
71901a6c311SAlfredo Cardigliano rte_free(qcq->q.info);
72001a6c311SAlfredo Cardigliano qcq->q.info = NULL;
72101a6c311SAlfredo Cardigliano }
72201a6c311SAlfredo Cardigliano
72301a6c311SAlfredo Cardigliano rte_free(qcq);
72401a6c311SAlfredo Cardigliano }
72501a6c311SAlfredo Cardigliano
726a27d9013SAlfredo Cardigliano int
ionic_rx_qcq_alloc(struct ionic_lif * lif,uint32_t socket_id,uint32_t index,uint16_t nrxq_descs,struct ionic_rx_qcq ** rxq_out)7278ec5ad7fSAndrew Boyer ionic_rx_qcq_alloc(struct ionic_lif *lif, uint32_t socket_id, uint32_t index,
728be39f75cSAndrew Boyer uint16_t nrxq_descs, struct ionic_rx_qcq **rxq_out)
729a27d9013SAlfredo Cardigliano {
730be39f75cSAndrew Boyer struct ionic_rx_qcq *rxq;
731be39f75cSAndrew Boyer uint16_t flags;
732be39f75cSAndrew Boyer int err;
733a27d9013SAlfredo Cardigliano
734a27d9013SAlfredo Cardigliano flags = IONIC_QCQ_F_SG;
7354ad56b7aSAndrew Boyer err = ionic_qcq_alloc(lif,
7364ad56b7aSAndrew Boyer IONIC_QTYPE_RXQ,
737be39f75cSAndrew Boyer sizeof(struct ionic_rx_qcq),
7388ec5ad7fSAndrew Boyer socket_id,
7394ad56b7aSAndrew Boyer index,
7404ad56b7aSAndrew Boyer "rx",
7414ad56b7aSAndrew Boyer flags,
742a27d9013SAlfredo Cardigliano nrxq_descs,
743a27d9013SAlfredo Cardigliano sizeof(struct ionic_rxq_desc),
744a27d9013SAlfredo Cardigliano sizeof(struct ionic_rxq_comp),
745a27d9013SAlfredo Cardigliano sizeof(struct ionic_rxq_sg_desc),
746be39f75cSAndrew Boyer (struct ionic_qcq **)&rxq);
747a27d9013SAlfredo Cardigliano if (err)
748a27d9013SAlfredo Cardigliano return err;
749a27d9013SAlfredo Cardigliano
750be39f75cSAndrew Boyer rxq->flags = flags;
751be39f75cSAndrew Boyer
752be39f75cSAndrew Boyer lif->rxqcqs[index] = rxq;
753be39f75cSAndrew Boyer *rxq_out = rxq;
754a27d9013SAlfredo Cardigliano
755a27d9013SAlfredo Cardigliano return 0;
756a27d9013SAlfredo Cardigliano }
757a27d9013SAlfredo Cardigliano
758a27d9013SAlfredo Cardigliano int
ionic_tx_qcq_alloc(struct ionic_lif * lif,uint32_t socket_id,uint32_t index,uint16_t ntxq_descs,struct ionic_tx_qcq ** txq_out)7598ec5ad7fSAndrew Boyer ionic_tx_qcq_alloc(struct ionic_lif *lif, uint32_t socket_id, uint32_t index,
760be39f75cSAndrew Boyer uint16_t ntxq_descs, struct ionic_tx_qcq **txq_out)
761a27d9013SAlfredo Cardigliano {
762be39f75cSAndrew Boyer struct ionic_tx_qcq *txq;
763e19eea1eSAndrew Boyer uint16_t flags, num_segs_fw;
764be39f75cSAndrew Boyer int err;
765a27d9013SAlfredo Cardigliano
766a27d9013SAlfredo Cardigliano flags = IONIC_QCQ_F_SG;
767e19eea1eSAndrew Boyer
768e19eea1eSAndrew Boyer num_segs_fw = IONIC_TX_MAX_SG_ELEMS_V1 + 1;
769e19eea1eSAndrew Boyer
7704ad56b7aSAndrew Boyer err = ionic_qcq_alloc(lif,
7714ad56b7aSAndrew Boyer IONIC_QTYPE_TXQ,
772be39f75cSAndrew Boyer sizeof(struct ionic_tx_qcq),
7738ec5ad7fSAndrew Boyer socket_id,
7744ad56b7aSAndrew Boyer index,
7754ad56b7aSAndrew Boyer "tx",
7764ad56b7aSAndrew Boyer flags,
777a27d9013SAlfredo Cardigliano ntxq_descs,
778a27d9013SAlfredo Cardigliano sizeof(struct ionic_txq_desc),
779a27d9013SAlfredo Cardigliano sizeof(struct ionic_txq_comp),
78056117636SAndrew Boyer sizeof(struct ionic_txq_sg_desc_v1),
781be39f75cSAndrew Boyer (struct ionic_qcq **)&txq);
782a27d9013SAlfredo Cardigliano if (err)
783a27d9013SAlfredo Cardigliano return err;
784a27d9013SAlfredo Cardigliano
785be39f75cSAndrew Boyer txq->flags = flags;
786e19eea1eSAndrew Boyer txq->num_segs_fw = num_segs_fw;
787be39f75cSAndrew Boyer
788be39f75cSAndrew Boyer lif->txqcqs[index] = txq;
789be39f75cSAndrew Boyer *txq_out = txq;
790a27d9013SAlfredo Cardigliano
791a27d9013SAlfredo Cardigliano return 0;
792a27d9013SAlfredo Cardigliano }
793a27d9013SAlfredo Cardigliano
79401a6c311SAlfredo Cardigliano static int
ionic_admin_qcq_alloc(struct ionic_lif * lif)79501a6c311SAlfredo Cardigliano ionic_admin_qcq_alloc(struct ionic_lif *lif)
79601a6c311SAlfredo Cardigliano {
797be39f75cSAndrew Boyer uint16_t flags = 0;
798be39f75cSAndrew Boyer int err;
79901a6c311SAlfredo Cardigliano
8004ad56b7aSAndrew Boyer err = ionic_qcq_alloc(lif,
8014ad56b7aSAndrew Boyer IONIC_QTYPE_ADMINQ,
802be39f75cSAndrew Boyer sizeof(struct ionic_admin_qcq),
8038ec5ad7fSAndrew Boyer rte_socket_id(),
8044ad56b7aSAndrew Boyer 0,
8054ad56b7aSAndrew Boyer "admin",
8064ad56b7aSAndrew Boyer flags,
80701a6c311SAlfredo Cardigliano IONIC_ADMINQ_LENGTH,
80801a6c311SAlfredo Cardigliano sizeof(struct ionic_admin_cmd),
80901a6c311SAlfredo Cardigliano sizeof(struct ionic_admin_comp),
81001a6c311SAlfredo Cardigliano 0,
811be39f75cSAndrew Boyer (struct ionic_qcq **)&lif->adminqcq);
81227b942c8SAlfredo Cardigliano if (err)
81327b942c8SAlfredo Cardigliano return err;
81401a6c311SAlfredo Cardigliano
81527b942c8SAlfredo Cardigliano return 0;
81627b942c8SAlfredo Cardigliano }
81727b942c8SAlfredo Cardigliano
81827b942c8SAlfredo Cardigliano static int
ionic_notify_qcq_alloc(struct ionic_lif * lif)81927b942c8SAlfredo Cardigliano ionic_notify_qcq_alloc(struct ionic_lif *lif)
82027b942c8SAlfredo Cardigliano {
821be39f75cSAndrew Boyer struct ionic_notify_qcq *nqcq;
8224c8f8d57SAndrew Boyer struct ionic_dev *idev = &lif->adapter->idev;
823be39f75cSAndrew Boyer uint16_t flags = 0;
824be39f75cSAndrew Boyer int err;
82527b942c8SAlfredo Cardigliano
8264ad56b7aSAndrew Boyer err = ionic_qcq_alloc(lif,
8274ad56b7aSAndrew Boyer IONIC_QTYPE_NOTIFYQ,
828be39f75cSAndrew Boyer sizeof(struct ionic_notify_qcq),
8298ec5ad7fSAndrew Boyer rte_socket_id(),
8304ad56b7aSAndrew Boyer 0,
8314ad56b7aSAndrew Boyer "notify",
83227b942c8SAlfredo Cardigliano flags,
83327b942c8SAlfredo Cardigliano IONIC_NOTIFYQ_LENGTH,
83427b942c8SAlfredo Cardigliano sizeof(struct ionic_notifyq_cmd),
83527b942c8SAlfredo Cardigliano sizeof(union ionic_notifyq_comp),
83627b942c8SAlfredo Cardigliano 0,
837be39f75cSAndrew Boyer (struct ionic_qcq **)&nqcq);
83801a6c311SAlfredo Cardigliano if (err)
83901a6c311SAlfredo Cardigliano return err;
84001a6c311SAlfredo Cardigliano
8414c8f8d57SAndrew Boyer err = ionic_intr_alloc(lif, &nqcq->intr);
8424c8f8d57SAndrew Boyer if (err) {
843be39f75cSAndrew Boyer ionic_qcq_free(&nqcq->qcq);
8444c8f8d57SAndrew Boyer return err;
8454c8f8d57SAndrew Boyer }
8464c8f8d57SAndrew Boyer
8474c8f8d57SAndrew Boyer ionic_intr_mask_assert(idev->intr_ctrl, nqcq->intr.index,
8484c8f8d57SAndrew Boyer IONIC_INTR_MASK_SET);
8494c8f8d57SAndrew Boyer
8504c8f8d57SAndrew Boyer lif->notifyqcq = nqcq;
8514c8f8d57SAndrew Boyer
85201a6c311SAlfredo Cardigliano return 0;
85301a6c311SAlfredo Cardigliano }
85401a6c311SAlfredo Cardigliano
855c67719e1SAlfredo Cardigliano static void *
ionic_bus_map_dbpage(struct ionic_adapter * adapter,int page_num)856c67719e1SAlfredo Cardigliano ionic_bus_map_dbpage(struct ionic_adapter *adapter, int page_num)
857c67719e1SAlfredo Cardigliano {
858c67719e1SAlfredo Cardigliano char *vaddr = adapter->bars[IONIC_PCI_BAR_DBELL].vaddr;
859c67719e1SAlfredo Cardigliano
860c67719e1SAlfredo Cardigliano if (adapter->num_bars <= IONIC_PCI_BAR_DBELL)
861c67719e1SAlfredo Cardigliano return NULL;
862c67719e1SAlfredo Cardigliano
863c67719e1SAlfredo Cardigliano return (void *)&vaddr[page_num << PAGE_SHIFT];
864c67719e1SAlfredo Cardigliano }
865c67719e1SAlfredo Cardigliano
866c5d15850SAndrew Boyer static void
ionic_lif_queue_identify(struct ionic_lif * lif)867c5d15850SAndrew Boyer ionic_lif_queue_identify(struct ionic_lif *lif)
868c5d15850SAndrew Boyer {
869c5d15850SAndrew Boyer struct ionic_adapter *adapter = lif->adapter;
870c5d15850SAndrew Boyer struct ionic_dev *idev = &adapter->idev;
871c5d15850SAndrew Boyer union ionic_q_identity *q_ident = &adapter->ident.txq;
872c5d15850SAndrew Boyer uint32_t q_words = RTE_DIM(q_ident->words);
873c5d15850SAndrew Boyer uint32_t cmd_words = RTE_DIM(idev->dev_cmd->data);
874c5d15850SAndrew Boyer uint32_t i, nwords, qtype;
875c5d15850SAndrew Boyer int err;
876c5d15850SAndrew Boyer
877c5d15850SAndrew Boyer for (qtype = 0; qtype < RTE_DIM(ionic_qtype_vers); qtype++) {
878c5d15850SAndrew Boyer struct ionic_qtype_info *qti = &lif->qtype_info[qtype];
879c5d15850SAndrew Boyer
880c5d15850SAndrew Boyer /* Filter out the types this driver knows about */
881c5d15850SAndrew Boyer switch (qtype) {
882c5d15850SAndrew Boyer case IONIC_QTYPE_ADMINQ:
883c5d15850SAndrew Boyer case IONIC_QTYPE_NOTIFYQ:
884c5d15850SAndrew Boyer case IONIC_QTYPE_RXQ:
885c5d15850SAndrew Boyer case IONIC_QTYPE_TXQ:
886c5d15850SAndrew Boyer break;
887c5d15850SAndrew Boyer default:
888c5d15850SAndrew Boyer continue;
889c5d15850SAndrew Boyer }
890c5d15850SAndrew Boyer
891c5d15850SAndrew Boyer memset(qti, 0, sizeof(*qti));
892c5d15850SAndrew Boyer
893c5d15850SAndrew Boyer ionic_dev_cmd_queue_identify(idev, IONIC_LIF_TYPE_CLASSIC,
894c5d15850SAndrew Boyer qtype, ionic_qtype_vers[qtype]);
895c5d15850SAndrew Boyer err = ionic_dev_cmd_wait_check(idev, IONIC_DEVCMD_TIMEOUT);
896c5d15850SAndrew Boyer if (err == -EINVAL) {
897c5d15850SAndrew Boyer IONIC_PRINT(ERR, "qtype %d not supported\n", qtype);
898c5d15850SAndrew Boyer continue;
899c5d15850SAndrew Boyer } else if (err == -EIO) {
900c5d15850SAndrew Boyer IONIC_PRINT(ERR, "q_ident failed, older FW\n");
901c5d15850SAndrew Boyer return;
902c5d15850SAndrew Boyer } else if (err) {
903c5d15850SAndrew Boyer IONIC_PRINT(ERR, "q_ident failed, qtype %d: %d\n",
904c5d15850SAndrew Boyer qtype, err);
905c5d15850SAndrew Boyer return;
906c5d15850SAndrew Boyer }
907c5d15850SAndrew Boyer
908c5d15850SAndrew Boyer nwords = RTE_MIN(q_words, cmd_words);
909c5d15850SAndrew Boyer for (i = 0; i < nwords; i++)
910c5d15850SAndrew Boyer q_ident->words[i] = ioread32(&idev->dev_cmd->data[i]);
911c5d15850SAndrew Boyer
912c5d15850SAndrew Boyer qti->version = q_ident->version;
913c5d15850SAndrew Boyer qti->supported = q_ident->supported;
914c5d15850SAndrew Boyer qti->features = rte_le_to_cpu_64(q_ident->features);
915c5d15850SAndrew Boyer qti->desc_sz = rte_le_to_cpu_16(q_ident->desc_sz);
916c5d15850SAndrew Boyer qti->comp_sz = rte_le_to_cpu_16(q_ident->comp_sz);
917c5d15850SAndrew Boyer qti->sg_desc_sz = rte_le_to_cpu_16(q_ident->sg_desc_sz);
918c5d15850SAndrew Boyer qti->max_sg_elems = rte_le_to_cpu_16(q_ident->max_sg_elems);
919c5d15850SAndrew Boyer qti->sg_desc_stride =
920c5d15850SAndrew Boyer rte_le_to_cpu_16(q_ident->sg_desc_stride);
921c5d15850SAndrew Boyer
922c5d15850SAndrew Boyer IONIC_PRINT(DEBUG, " qtype[%d].version = %d",
923c5d15850SAndrew Boyer qtype, qti->version);
924c5d15850SAndrew Boyer IONIC_PRINT(DEBUG, " qtype[%d].supported = %#x",
925c5d15850SAndrew Boyer qtype, qti->supported);
926c5d15850SAndrew Boyer IONIC_PRINT(DEBUG, " qtype[%d].features = %#jx",
927c5d15850SAndrew Boyer qtype, qti->features);
928c5d15850SAndrew Boyer IONIC_PRINT(DEBUG, " qtype[%d].desc_sz = %d",
929c5d15850SAndrew Boyer qtype, qti->desc_sz);
930c5d15850SAndrew Boyer IONIC_PRINT(DEBUG, " qtype[%d].comp_sz = %d",
931c5d15850SAndrew Boyer qtype, qti->comp_sz);
932c5d15850SAndrew Boyer IONIC_PRINT(DEBUG, " qtype[%d].sg_desc_sz = %d",
933c5d15850SAndrew Boyer qtype, qti->sg_desc_sz);
934c5d15850SAndrew Boyer IONIC_PRINT(DEBUG, " qtype[%d].max_sg_elems = %d",
935c5d15850SAndrew Boyer qtype, qti->max_sg_elems);
936c5d15850SAndrew Boyer IONIC_PRINT(DEBUG, " qtype[%d].sg_desc_stride = %d",
937c5d15850SAndrew Boyer qtype, qti->sg_desc_stride);
938c5d15850SAndrew Boyer }
939c5d15850SAndrew Boyer }
940c5d15850SAndrew Boyer
941669c8de6SAlfredo Cardigliano int
ionic_lif_alloc(struct ionic_lif * lif)942669c8de6SAlfredo Cardigliano ionic_lif_alloc(struct ionic_lif *lif)
943669c8de6SAlfredo Cardigliano {
944c67719e1SAlfredo Cardigliano struct ionic_adapter *adapter = lif->adapter;
945669c8de6SAlfredo Cardigliano uint32_t socket_id = rte_socket_id();
94601a6c311SAlfredo Cardigliano int err;
947669c8de6SAlfredo Cardigliano
9484ae96cb8SAndrew Boyer /*
9494ae96cb8SAndrew Boyer * lif->name was zeroed on allocation.
9504ae96cb8SAndrew Boyer * Copy (sizeof() - 1) bytes to ensure that it is NULL terminated.
9514ae96cb8SAndrew Boyer */
9524ae96cb8SAndrew Boyer memcpy(lif->name, lif->eth_dev->data->name, sizeof(lif->name) - 1);
9534ae96cb8SAndrew Boyer
9544ae96cb8SAndrew Boyer IONIC_PRINT(DEBUG, "LIF: %s", lif->name);
955669c8de6SAlfredo Cardigliano
956c5d15850SAndrew Boyer ionic_lif_queue_identify(lif);
957c5d15850SAndrew Boyer
95856117636SAndrew Boyer if (lif->qtype_info[IONIC_QTYPE_TXQ].version < 1) {
95956117636SAndrew Boyer IONIC_PRINT(ERR, "FW too old, please upgrade");
96056117636SAndrew Boyer return -ENXIO;
96156117636SAndrew Boyer }
96256117636SAndrew Boyer
963669c8de6SAlfredo Cardigliano IONIC_PRINT(DEBUG, "Allocating Lif Info");
964669c8de6SAlfredo Cardigliano
96501a6c311SAlfredo Cardigliano rte_spinlock_init(&lif->adminq_lock);
96601a6c311SAlfredo Cardigliano rte_spinlock_init(&lif->adminq_service_lock);
96701a6c311SAlfredo Cardigliano
96800b65da5SAndrew Boyer lif->kern_dbpage = ionic_bus_map_dbpage(adapter, 0);
969c67719e1SAlfredo Cardigliano if (!lif->kern_dbpage) {
970c67719e1SAlfredo Cardigliano IONIC_PRINT(ERR, "Cannot map dbpage, aborting");
971c67719e1SAlfredo Cardigliano return -ENOMEM;
972c67719e1SAlfredo Cardigliano }
973c67719e1SAlfredo Cardigliano
974a27d9013SAlfredo Cardigliano lif->txqcqs = rte_zmalloc("ionic", sizeof(*lif->txqcqs) *
975a27d9013SAlfredo Cardigliano adapter->max_ntxqs_per_lif, 0);
976a27d9013SAlfredo Cardigliano
977a27d9013SAlfredo Cardigliano if (!lif->txqcqs) {
978a27d9013SAlfredo Cardigliano IONIC_PRINT(ERR, "Cannot allocate tx queues array");
979a27d9013SAlfredo Cardigliano return -ENOMEM;
980a27d9013SAlfredo Cardigliano }
981a27d9013SAlfredo Cardigliano
982a27d9013SAlfredo Cardigliano lif->rxqcqs = rte_zmalloc("ionic", sizeof(*lif->rxqcqs) *
983a27d9013SAlfredo Cardigliano adapter->max_nrxqs_per_lif, 0);
984a27d9013SAlfredo Cardigliano
985a27d9013SAlfredo Cardigliano if (!lif->rxqcqs) {
986a27d9013SAlfredo Cardigliano IONIC_PRINT(ERR, "Cannot allocate rx queues array");
987a27d9013SAlfredo Cardigliano return -ENOMEM;
988a27d9013SAlfredo Cardigliano }
989a27d9013SAlfredo Cardigliano
99027b942c8SAlfredo Cardigliano IONIC_PRINT(DEBUG, "Allocating Notify Queue");
99127b942c8SAlfredo Cardigliano
99227b942c8SAlfredo Cardigliano err = ionic_notify_qcq_alloc(lif);
99327b942c8SAlfredo Cardigliano if (err) {
99427b942c8SAlfredo Cardigliano IONIC_PRINT(ERR, "Cannot allocate notify queue");
99527b942c8SAlfredo Cardigliano return err;
99627b942c8SAlfredo Cardigliano }
99727b942c8SAlfredo Cardigliano
99827b942c8SAlfredo Cardigliano IONIC_PRINT(DEBUG, "Allocating Admin Queue");
99927b942c8SAlfredo Cardigliano
100001a6c311SAlfredo Cardigliano err = ionic_admin_qcq_alloc(lif);
100101a6c311SAlfredo Cardigliano if (err) {
100201a6c311SAlfredo Cardigliano IONIC_PRINT(ERR, "Cannot allocate admin queue");
100301a6c311SAlfredo Cardigliano return err;
100401a6c311SAlfredo Cardigliano }
100501a6c311SAlfredo Cardigliano
100601a6c311SAlfredo Cardigliano IONIC_PRINT(DEBUG, "Allocating Lif Info");
100701a6c311SAlfredo Cardigliano
1008924e6b76SThomas Monjalon lif->info_sz = RTE_ALIGN(sizeof(*lif->info), rte_mem_page_size());
1009669c8de6SAlfredo Cardigliano
1010669c8de6SAlfredo Cardigliano lif->info_z = rte_eth_dma_zone_reserve(lif->eth_dev,
1011669c8de6SAlfredo Cardigliano "lif_info", 0 /* queue_idx*/,
1012669c8de6SAlfredo Cardigliano lif->info_sz, IONIC_ALIGN, socket_id);
1013669c8de6SAlfredo Cardigliano if (!lif->info_z) {
1014669c8de6SAlfredo Cardigliano IONIC_PRINT(ERR, "Cannot allocate lif info memory");
1015669c8de6SAlfredo Cardigliano return -ENOMEM;
1016669c8de6SAlfredo Cardigliano }
1017669c8de6SAlfredo Cardigliano
1018669c8de6SAlfredo Cardigliano lif->info = lif->info_z->addr;
1019669c8de6SAlfredo Cardigliano lif->info_pa = lif->info_z->iova;
1020669c8de6SAlfredo Cardigliano
1021669c8de6SAlfredo Cardigliano return 0;
1022669c8de6SAlfredo Cardigliano }
1023669c8de6SAlfredo Cardigliano
1024669c8de6SAlfredo Cardigliano void
ionic_lif_free(struct ionic_lif * lif)1025669c8de6SAlfredo Cardigliano ionic_lif_free(struct ionic_lif *lif)
1026669c8de6SAlfredo Cardigliano {
102727b942c8SAlfredo Cardigliano if (lif->notifyqcq) {
1028be39f75cSAndrew Boyer ionic_qcq_free(&lif->notifyqcq->qcq);
102927b942c8SAlfredo Cardigliano lif->notifyqcq = NULL;
103027b942c8SAlfredo Cardigliano }
103127b942c8SAlfredo Cardigliano
103201a6c311SAlfredo Cardigliano if (lif->adminqcq) {
1033be39f75cSAndrew Boyer ionic_qcq_free(&lif->adminqcq->qcq);
103401a6c311SAlfredo Cardigliano lif->adminqcq = NULL;
103501a6c311SAlfredo Cardigliano }
103601a6c311SAlfredo Cardigliano
1037a27d9013SAlfredo Cardigliano if (lif->txqcqs) {
1038a27d9013SAlfredo Cardigliano rte_free(lif->txqcqs);
1039a27d9013SAlfredo Cardigliano lif->txqcqs = NULL;
1040a27d9013SAlfredo Cardigliano }
1041a27d9013SAlfredo Cardigliano
1042a27d9013SAlfredo Cardigliano if (lif->rxqcqs) {
1043a27d9013SAlfredo Cardigliano rte_free(lif->rxqcqs);
1044a27d9013SAlfredo Cardigliano lif->rxqcqs = NULL;
1045a27d9013SAlfredo Cardigliano }
1046a27d9013SAlfredo Cardigliano
1047669c8de6SAlfredo Cardigliano if (lif->info) {
1048669c8de6SAlfredo Cardigliano rte_memzone_free(lif->info_z);
1049669c8de6SAlfredo Cardigliano lif->info = NULL;
1050669c8de6SAlfredo Cardigliano }
1051669c8de6SAlfredo Cardigliano }
1052669c8de6SAlfredo Cardigliano
1053175e4e7eSAndrew Boyer void
ionic_lif_free_queues(struct ionic_lif * lif)1054175e4e7eSAndrew Boyer ionic_lif_free_queues(struct ionic_lif *lif)
1055175e4e7eSAndrew Boyer {
1056175e4e7eSAndrew Boyer uint32_t i;
1057175e4e7eSAndrew Boyer
1058175e4e7eSAndrew Boyer for (i = 0; i < lif->ntxqcqs; i++) {
10597483341aSXueming Li ionic_dev_tx_queue_release(lif->eth_dev, i);
1060175e4e7eSAndrew Boyer lif->eth_dev->data->tx_queues[i] = NULL;
1061175e4e7eSAndrew Boyer }
1062175e4e7eSAndrew Boyer for (i = 0; i < lif->nrxqcqs; i++) {
10637483341aSXueming Li ionic_dev_rx_queue_release(lif->eth_dev, i);
1064175e4e7eSAndrew Boyer lif->eth_dev->data->rx_queues[i] = NULL;
1065175e4e7eSAndrew Boyer }
1066175e4e7eSAndrew Boyer }
1067175e4e7eSAndrew Boyer
106822e7171bSAlfredo Cardigliano int
ionic_lif_rss_config(struct ionic_lif * lif,const uint16_t types,const uint8_t * key,const uint32_t * indir)106922e7171bSAlfredo Cardigliano ionic_lif_rss_config(struct ionic_lif *lif,
107022e7171bSAlfredo Cardigliano const uint16_t types, const uint8_t *key, const uint32_t *indir)
107122e7171bSAlfredo Cardigliano {
107209f806e9SAndrew Boyer struct ionic_adapter *adapter = lif->adapter;
107322e7171bSAlfredo Cardigliano struct ionic_admin_ctx ctx = {
107422e7171bSAlfredo Cardigliano .pending_work = true,
107522e7171bSAlfredo Cardigliano .cmd.lif_setattr = {
107622e7171bSAlfredo Cardigliano .opcode = IONIC_CMD_LIF_SETATTR,
107722e7171bSAlfredo Cardigliano .attr = IONIC_LIF_ATTR_RSS,
107809f806e9SAndrew Boyer .rss.types = rte_cpu_to_le_16(types),
107909f806e9SAndrew Boyer .rss.addr = rte_cpu_to_le_64(lif->rss_ind_tbl_pa),
108022e7171bSAlfredo Cardigliano },
108122e7171bSAlfredo Cardigliano };
108222e7171bSAlfredo Cardigliano unsigned int i;
108309f806e9SAndrew Boyer uint16_t tbl_sz =
108409f806e9SAndrew Boyer rte_le_to_cpu_16(adapter->ident.lif.eth.rss_ind_tbl_sz);
108522e7171bSAlfredo Cardigliano
108622e7171bSAlfredo Cardigliano IONIC_PRINT_CALL();
108722e7171bSAlfredo Cardigliano
108822e7171bSAlfredo Cardigliano lif->rss_types = types;
108922e7171bSAlfredo Cardigliano
109022e7171bSAlfredo Cardigliano if (key)
109122e7171bSAlfredo Cardigliano memcpy(lif->rss_hash_key, key, IONIC_RSS_HASH_KEY_SIZE);
109222e7171bSAlfredo Cardigliano
109322e7171bSAlfredo Cardigliano if (indir)
109409f806e9SAndrew Boyer for (i = 0; i < tbl_sz; i++)
109522e7171bSAlfredo Cardigliano lif->rss_ind_tbl[i] = indir[i];
109622e7171bSAlfredo Cardigliano
109722e7171bSAlfredo Cardigliano memcpy(ctx.cmd.lif_setattr.rss.key, lif->rss_hash_key,
109822e7171bSAlfredo Cardigliano IONIC_RSS_HASH_KEY_SIZE);
109922e7171bSAlfredo Cardigliano
110022e7171bSAlfredo Cardigliano return ionic_adminq_post_wait(lif, &ctx);
110122e7171bSAlfredo Cardigliano }
110222e7171bSAlfredo Cardigliano
110322e7171bSAlfredo Cardigliano static int
ionic_lif_rss_setup(struct ionic_lif * lif)110422e7171bSAlfredo Cardigliano ionic_lif_rss_setup(struct ionic_lif *lif)
110522e7171bSAlfredo Cardigliano {
110609f806e9SAndrew Boyer struct ionic_adapter *adapter = lif->adapter;
110722e7171bSAlfredo Cardigliano static const uint8_t toeplitz_symmetric_key[] = {
110822e7171bSAlfredo Cardigliano 0x6D, 0x5A, 0x6D, 0x5A, 0x6D, 0x5A, 0x6D, 0x5A,
110922e7171bSAlfredo Cardigliano 0x6D, 0x5A, 0x6D, 0x5A, 0x6D, 0x5A, 0x6D, 0x5A,
111022e7171bSAlfredo Cardigliano 0x6D, 0x5A, 0x6D, 0x5A, 0x6D, 0x5A, 0x6D, 0x5A,
111122e7171bSAlfredo Cardigliano 0x6D, 0x5A, 0x6D, 0x5A, 0x6D, 0x5A, 0x6D, 0x5A,
111222e7171bSAlfredo Cardigliano 0x6D, 0x5A, 0x6D, 0x5A, 0x6D, 0x5A, 0x6D, 0x5A,
111322e7171bSAlfredo Cardigliano };
111422e7171bSAlfredo Cardigliano uint32_t i;
111509f806e9SAndrew Boyer uint16_t tbl_sz =
111609f806e9SAndrew Boyer rte_le_to_cpu_16(adapter->ident.lif.eth.rss_ind_tbl_sz);
111722e7171bSAlfredo Cardigliano
111822e7171bSAlfredo Cardigliano IONIC_PRINT_CALL();
111922e7171bSAlfredo Cardigliano
11203d845eddSAndrew Boyer if (!lif->rss_ind_tbl_z) {
112122e7171bSAlfredo Cardigliano lif->rss_ind_tbl_z = rte_eth_dma_zone_reserve(lif->eth_dev,
11223d845eddSAndrew Boyer "rss_ind_tbl", 0 /* queue_idx */,
11233d845eddSAndrew Boyer sizeof(*lif->rss_ind_tbl) * tbl_sz,
11243d845eddSAndrew Boyer IONIC_ALIGN, rte_socket_id());
112522e7171bSAlfredo Cardigliano if (!lif->rss_ind_tbl_z) {
112622e7171bSAlfredo Cardigliano IONIC_PRINT(ERR, "OOM");
112722e7171bSAlfredo Cardigliano return -ENOMEM;
112822e7171bSAlfredo Cardigliano }
112922e7171bSAlfredo Cardigliano
113022e7171bSAlfredo Cardigliano lif->rss_ind_tbl = lif->rss_ind_tbl_z->addr;
113122e7171bSAlfredo Cardigliano lif->rss_ind_tbl_pa = lif->rss_ind_tbl_z->iova;
11323d845eddSAndrew Boyer }
11333d845eddSAndrew Boyer
11343d845eddSAndrew Boyer if (lif->rss_ind_tbl_nrxqcqs != lif->nrxqcqs) {
11353d845eddSAndrew Boyer lif->rss_ind_tbl_nrxqcqs = lif->nrxqcqs;
113622e7171bSAlfredo Cardigliano
113722e7171bSAlfredo Cardigliano /* Fill indirection table with 'default' values */
11383d845eddSAndrew Boyer for (i = 0; i < tbl_sz; i++)
113922e7171bSAlfredo Cardigliano lif->rss_ind_tbl[i] = i % lif->nrxqcqs;
11403d845eddSAndrew Boyer }
114122e7171bSAlfredo Cardigliano
11423d845eddSAndrew Boyer return ionic_lif_rss_config(lif, IONIC_RSS_OFFLOAD_ALL,
114322e7171bSAlfredo Cardigliano toeplitz_symmetric_key, NULL);
114422e7171bSAlfredo Cardigliano }
114522e7171bSAlfredo Cardigliano
114622e7171bSAlfredo Cardigliano static void
ionic_lif_rss_teardown(struct ionic_lif * lif)114722e7171bSAlfredo Cardigliano ionic_lif_rss_teardown(struct ionic_lif *lif)
114822e7171bSAlfredo Cardigliano {
114922e7171bSAlfredo Cardigliano if (!lif->rss_ind_tbl)
115022e7171bSAlfredo Cardigliano return;
115122e7171bSAlfredo Cardigliano
115222e7171bSAlfredo Cardigliano if (lif->rss_ind_tbl_z) {
115322e7171bSAlfredo Cardigliano /* Disable RSS on the NIC */
115422e7171bSAlfredo Cardigliano ionic_lif_rss_config(lif, 0x0, NULL, NULL);
115522e7171bSAlfredo Cardigliano
115622e7171bSAlfredo Cardigliano lif->rss_ind_tbl = NULL;
115722e7171bSAlfredo Cardigliano lif->rss_ind_tbl_pa = 0;
115822e7171bSAlfredo Cardigliano rte_memzone_free(lif->rss_ind_tbl_z);
115922e7171bSAlfredo Cardigliano lif->rss_ind_tbl_z = NULL;
116022e7171bSAlfredo Cardigliano }
116122e7171bSAlfredo Cardigliano }
116222e7171bSAlfredo Cardigliano
1163be39f75cSAndrew Boyer void
ionic_lif_txq_deinit(struct ionic_tx_qcq * txq)1164be39f75cSAndrew Boyer ionic_lif_txq_deinit(struct ionic_tx_qcq *txq)
1165be39f75cSAndrew Boyer {
1166be39f75cSAndrew Boyer txq->flags &= ~IONIC_QCQ_F_INITED;
1167be39f75cSAndrew Boyer }
1168be39f75cSAndrew Boyer
1169be39f75cSAndrew Boyer void
ionic_lif_rxq_deinit(struct ionic_rx_qcq * rxq)1170be39f75cSAndrew Boyer ionic_lif_rxq_deinit(struct ionic_rx_qcq *rxq)
1171be39f75cSAndrew Boyer {
1172be39f75cSAndrew Boyer rxq->flags &= ~IONIC_QCQ_F_INITED;
1173be39f75cSAndrew Boyer }
1174be39f75cSAndrew Boyer
117501a6c311SAlfredo Cardigliano static void
ionic_lif_adminq_deinit(struct ionic_lif * lif)1176be39f75cSAndrew Boyer ionic_lif_adminq_deinit(struct ionic_lif *lif)
117701a6c311SAlfredo Cardigliano {
1178be39f75cSAndrew Boyer lif->adminqcq->flags &= ~IONIC_QCQ_F_INITED;
11794c8f8d57SAndrew Boyer }
11804c8f8d57SAndrew Boyer
11814c8f8d57SAndrew Boyer static void
ionic_lif_notifyq_deinit(struct ionic_lif * lif)11824c8f8d57SAndrew Boyer ionic_lif_notifyq_deinit(struct ionic_lif *lif)
11834c8f8d57SAndrew Boyer {
1184be39f75cSAndrew Boyer struct ionic_notify_qcq *nqcq = lif->notifyqcq;
11854c8f8d57SAndrew Boyer struct ionic_dev *idev = &lif->adapter->idev;
11864c8f8d57SAndrew Boyer
11874c8f8d57SAndrew Boyer if (!(nqcq->flags & IONIC_QCQ_F_INITED))
11884c8f8d57SAndrew Boyer return;
11894c8f8d57SAndrew Boyer
11904c8f8d57SAndrew Boyer ionic_intr_mask(idev->intr_ctrl, nqcq->intr.index,
11914c8f8d57SAndrew Boyer IONIC_INTR_MASK_SET);
11924c8f8d57SAndrew Boyer
11934c8f8d57SAndrew Boyer nqcq->flags &= ~IONIC_QCQ_F_INITED;
1194a27d9013SAlfredo Cardigliano }
1195a27d9013SAlfredo Cardigliano
119601a6c311SAlfredo Cardigliano /* This acts like ionic_napi */
119701a6c311SAlfredo Cardigliano int
ionic_qcq_service(struct ionic_qcq * qcq,int budget,ionic_cq_cb cb,void * cb_arg)119801a6c311SAlfredo Cardigliano ionic_qcq_service(struct ionic_qcq *qcq, int budget, ionic_cq_cb cb,
119901a6c311SAlfredo Cardigliano void *cb_arg)
120001a6c311SAlfredo Cardigliano {
120101a6c311SAlfredo Cardigliano struct ionic_cq *cq = &qcq->cq;
120201a6c311SAlfredo Cardigliano uint32_t work_done;
120301a6c311SAlfredo Cardigliano
120401a6c311SAlfredo Cardigliano work_done = ionic_cq_service(cq, budget, cb, cb_arg);
120501a6c311SAlfredo Cardigliano
120601a6c311SAlfredo Cardigliano return work_done;
120701a6c311SAlfredo Cardigliano }
120801a6c311SAlfredo Cardigliano
120927b942c8SAlfredo Cardigliano static void
ionic_link_status_check(struct ionic_lif * lif)121027b942c8SAlfredo Cardigliano ionic_link_status_check(struct ionic_lif *lif)
121127b942c8SAlfredo Cardigliano {
121227b942c8SAlfredo Cardigliano struct ionic_adapter *adapter = lif->adapter;
121327b942c8SAlfredo Cardigliano bool link_up;
121427b942c8SAlfredo Cardigliano
121527b942c8SAlfredo Cardigliano lif->state &= ~IONIC_LIF_F_LINK_CHECK_NEEDED;
121627b942c8SAlfredo Cardigliano
121727b942c8SAlfredo Cardigliano if (!lif->info)
121827b942c8SAlfredo Cardigliano return;
121927b942c8SAlfredo Cardigliano
122027b942c8SAlfredo Cardigliano link_up = (lif->info->status.link_status == IONIC_PORT_OPER_STATUS_UP);
122127b942c8SAlfredo Cardigliano
122227b942c8SAlfredo Cardigliano if ((link_up && adapter->link_up) ||
122327b942c8SAlfredo Cardigliano (!link_up && !adapter->link_up))
122427b942c8SAlfredo Cardigliano return;
122527b942c8SAlfredo Cardigliano
122627b942c8SAlfredo Cardigliano if (link_up) {
122709f806e9SAndrew Boyer adapter->link_speed =
122809f806e9SAndrew Boyer rte_le_to_cpu_32(lif->info->status.link_speed);
1229be63459eSAndrew Boyer IONIC_PRINT(DEBUG, "Link up - %d Gbps",
1230be63459eSAndrew Boyer adapter->link_speed);
123127b942c8SAlfredo Cardigliano } else {
123227b942c8SAlfredo Cardigliano IONIC_PRINT(DEBUG, "Link down");
123327b942c8SAlfredo Cardigliano }
123427b942c8SAlfredo Cardigliano
123527b942c8SAlfredo Cardigliano adapter->link_up = link_up;
1236be63459eSAndrew Boyer ionic_dev_link_update(lif->eth_dev, 0);
1237be63459eSAndrew Boyer }
1238be63459eSAndrew Boyer
1239be63459eSAndrew Boyer static void
ionic_lif_handle_fw_down(struct ionic_lif * lif)1240be63459eSAndrew Boyer ionic_lif_handle_fw_down(struct ionic_lif *lif)
1241be63459eSAndrew Boyer {
1242be63459eSAndrew Boyer if (lif->state & IONIC_LIF_F_FW_RESET)
1243be63459eSAndrew Boyer return;
1244be63459eSAndrew Boyer
1245be63459eSAndrew Boyer lif->state |= IONIC_LIF_F_FW_RESET;
1246be63459eSAndrew Boyer
1247be63459eSAndrew Boyer if (lif->state & IONIC_LIF_F_UP) {
1248be63459eSAndrew Boyer IONIC_PRINT(NOTICE,
1249be63459eSAndrew Boyer "Surprise FW stop, stopping %s\n", lif->name);
1250be63459eSAndrew Boyer ionic_lif_stop(lif);
1251be63459eSAndrew Boyer }
1252be63459eSAndrew Boyer
1253be63459eSAndrew Boyer IONIC_PRINT(NOTICE, "FW down, %s stopped", lif->name);
125427b942c8SAlfredo Cardigliano }
125527b942c8SAlfredo Cardigliano
125627b942c8SAlfredo Cardigliano static bool
ionic_notifyq_cb(struct ionic_cq * cq,uint16_t cq_desc_index,void * cb_arg)12574ad56b7aSAndrew Boyer ionic_notifyq_cb(struct ionic_cq *cq, uint16_t cq_desc_index, void *cb_arg)
125827b942c8SAlfredo Cardigliano {
125927b942c8SAlfredo Cardigliano union ionic_notifyq_comp *cq_desc_base = cq->base;
126027b942c8SAlfredo Cardigliano union ionic_notifyq_comp *cq_desc = &cq_desc_base[cq_desc_index];
126127b942c8SAlfredo Cardigliano struct ionic_lif *lif = cb_arg;
126227b942c8SAlfredo Cardigliano
126327b942c8SAlfredo Cardigliano IONIC_PRINT(DEBUG, "Notifyq callback eid = %jd ecode = %d",
126427b942c8SAlfredo Cardigliano cq_desc->event.eid, cq_desc->event.ecode);
126527b942c8SAlfredo Cardigliano
126627b942c8SAlfredo Cardigliano /* Have we run out of new completions to process? */
126727b942c8SAlfredo Cardigliano if (!(cq_desc->event.eid > lif->last_eid))
126827b942c8SAlfredo Cardigliano return false;
126927b942c8SAlfredo Cardigliano
127027b942c8SAlfredo Cardigliano lif->last_eid = cq_desc->event.eid;
127127b942c8SAlfredo Cardigliano
127227b942c8SAlfredo Cardigliano switch (cq_desc->event.ecode) {
127327b942c8SAlfredo Cardigliano case IONIC_EVENT_LINK_CHANGE:
127427b942c8SAlfredo Cardigliano IONIC_PRINT(DEBUG,
1275be63459eSAndrew Boyer "Notifyq IONIC_EVENT_LINK_CHANGE %s "
1276be63459eSAndrew Boyer "eid=%jd link_status=%d link_speed=%d",
1277be63459eSAndrew Boyer lif->name,
127827b942c8SAlfredo Cardigliano cq_desc->event.eid,
127927b942c8SAlfredo Cardigliano cq_desc->link_change.link_status,
128027b942c8SAlfredo Cardigliano cq_desc->link_change.link_speed);
128127b942c8SAlfredo Cardigliano
128227b942c8SAlfredo Cardigliano lif->state |= IONIC_LIF_F_LINK_CHECK_NEEDED;
128327b942c8SAlfredo Cardigliano break;
1284be63459eSAndrew Boyer
1285be63459eSAndrew Boyer case IONIC_EVENT_RESET:
1286be63459eSAndrew Boyer IONIC_PRINT(NOTICE,
1287be63459eSAndrew Boyer "Notifyq IONIC_EVENT_RESET %s "
1288be63459eSAndrew Boyer "eid=%jd, reset_code=%d state=%d",
1289be63459eSAndrew Boyer lif->name,
1290be63459eSAndrew Boyer cq_desc->event.eid,
1291be63459eSAndrew Boyer cq_desc->reset.reset_code,
1292be63459eSAndrew Boyer cq_desc->reset.state);
1293be63459eSAndrew Boyer ionic_lif_handle_fw_down(lif);
1294be63459eSAndrew Boyer break;
1295be63459eSAndrew Boyer
129627b942c8SAlfredo Cardigliano default:
129727b942c8SAlfredo Cardigliano IONIC_PRINT(WARNING, "Notifyq bad event ecode=%d eid=%jd",
129827b942c8SAlfredo Cardigliano cq_desc->event.ecode, cq_desc->event.eid);
129927b942c8SAlfredo Cardigliano break;
130027b942c8SAlfredo Cardigliano }
130127b942c8SAlfredo Cardigliano
130227b942c8SAlfredo Cardigliano return true;
130327b942c8SAlfredo Cardigliano }
130427b942c8SAlfredo Cardigliano
130527b942c8SAlfredo Cardigliano int
ionic_notifyq_handler(struct ionic_lif * lif,int budget)130627b942c8SAlfredo Cardigliano ionic_notifyq_handler(struct ionic_lif *lif, int budget)
130727b942c8SAlfredo Cardigliano {
130827b942c8SAlfredo Cardigliano struct ionic_dev *idev = &lif->adapter->idev;
1309be39f75cSAndrew Boyer struct ionic_notify_qcq *nqcq = lif->notifyqcq;
131027b942c8SAlfredo Cardigliano uint32_t work_done;
131127b942c8SAlfredo Cardigliano
1312be39f75cSAndrew Boyer if (!(nqcq->flags & IONIC_QCQ_F_INITED)) {
131327b942c8SAlfredo Cardigliano IONIC_PRINT(DEBUG, "Notifyq not yet initialized");
131427b942c8SAlfredo Cardigliano return -1;
131527b942c8SAlfredo Cardigliano }
131627b942c8SAlfredo Cardigliano
1317be39f75cSAndrew Boyer ionic_intr_mask(idev->intr_ctrl, nqcq->intr.index,
131827b942c8SAlfredo Cardigliano IONIC_INTR_MASK_SET);
131927b942c8SAlfredo Cardigliano
1320be39f75cSAndrew Boyer work_done = ionic_qcq_service(&nqcq->qcq, budget,
1321be39f75cSAndrew Boyer ionic_notifyq_cb, lif);
132227b942c8SAlfredo Cardigliano
132327b942c8SAlfredo Cardigliano if (lif->state & IONIC_LIF_F_LINK_CHECK_NEEDED)
132427b942c8SAlfredo Cardigliano ionic_link_status_check(lif);
132527b942c8SAlfredo Cardigliano
1326be39f75cSAndrew Boyer ionic_intr_credits(idev->intr_ctrl, nqcq->intr.index,
132727b942c8SAlfredo Cardigliano work_done, IONIC_INTR_CRED_RESET_COALESCE);
132827b942c8SAlfredo Cardigliano
1329be39f75cSAndrew Boyer ionic_intr_mask(idev->intr_ctrl, nqcq->intr.index,
133027b942c8SAlfredo Cardigliano IONIC_INTR_MASK_CLEAR);
133127b942c8SAlfredo Cardigliano
133227b942c8SAlfredo Cardigliano return 0;
133327b942c8SAlfredo Cardigliano }
133427b942c8SAlfredo Cardigliano
133501a6c311SAlfredo Cardigliano static int
ionic_lif_adminq_init(struct ionic_lif * lif)133601a6c311SAlfredo Cardigliano ionic_lif_adminq_init(struct ionic_lif *lif)
133701a6c311SAlfredo Cardigliano {
133801a6c311SAlfredo Cardigliano struct ionic_dev *idev = &lif->adapter->idev;
1339be39f75cSAndrew Boyer struct ionic_admin_qcq *aqcq = lif->adminqcq;
1340be39f75cSAndrew Boyer struct ionic_queue *q = &aqcq->qcq.q;
134101a6c311SAlfredo Cardigliano struct ionic_q_init_comp comp;
134201a6c311SAlfredo Cardigliano int err;
134301a6c311SAlfredo Cardigliano
1344be39f75cSAndrew Boyer ionic_dev_cmd_adminq_init(idev, &aqcq->qcq);
134501a6c311SAlfredo Cardigliano err = ionic_dev_cmd_wait_check(idev, IONIC_DEVCMD_TIMEOUT);
134601a6c311SAlfredo Cardigliano if (err)
134701a6c311SAlfredo Cardigliano return err;
134801a6c311SAlfredo Cardigliano
134901a6c311SAlfredo Cardigliano ionic_dev_cmd_comp(idev, &comp);
135001a6c311SAlfredo Cardigliano
135101a6c311SAlfredo Cardigliano q->hw_type = comp.hw_type;
135209f806e9SAndrew Boyer q->hw_index = rte_le_to_cpu_32(comp.hw_index);
135301a6c311SAlfredo Cardigliano q->db = ionic_db_map(lif, q);
135401a6c311SAlfredo Cardigliano
135501a6c311SAlfredo Cardigliano IONIC_PRINT(DEBUG, "adminq->hw_type %d", q->hw_type);
135601a6c311SAlfredo Cardigliano IONIC_PRINT(DEBUG, "adminq->hw_index %d", q->hw_index);
135701a6c311SAlfredo Cardigliano IONIC_PRINT(DEBUG, "adminq->db %p", q->db);
135801a6c311SAlfredo Cardigliano
1359be39f75cSAndrew Boyer aqcq->flags |= IONIC_QCQ_F_INITED;
136001a6c311SAlfredo Cardigliano
136101a6c311SAlfredo Cardigliano return 0;
136201a6c311SAlfredo Cardigliano }
136301a6c311SAlfredo Cardigliano
136427b942c8SAlfredo Cardigliano static int
ionic_lif_notifyq_init(struct ionic_lif * lif)136527b942c8SAlfredo Cardigliano ionic_lif_notifyq_init(struct ionic_lif *lif)
136627b942c8SAlfredo Cardigliano {
136727b942c8SAlfredo Cardigliano struct ionic_dev *idev = &lif->adapter->idev;
1368be39f75cSAndrew Boyer struct ionic_notify_qcq *nqcq = lif->notifyqcq;
1369be39f75cSAndrew Boyer struct ionic_queue *q = &nqcq->qcq.q;
137027b942c8SAlfredo Cardigliano int err;
137127b942c8SAlfredo Cardigliano
137227b942c8SAlfredo Cardigliano struct ionic_admin_ctx ctx = {
137327b942c8SAlfredo Cardigliano .pending_work = true,
137427b942c8SAlfredo Cardigliano .cmd.q_init = {
137527b942c8SAlfredo Cardigliano .opcode = IONIC_CMD_Q_INIT,
137627b942c8SAlfredo Cardigliano .type = q->type,
1377c5d15850SAndrew Boyer .ver = lif->qtype_info[q->type].version,
137809f806e9SAndrew Boyer .index = rte_cpu_to_le_32(q->index),
1379be39f75cSAndrew Boyer .intr_index = rte_cpu_to_le_16(nqcq->intr.index),
138009f806e9SAndrew Boyer .flags = rte_cpu_to_le_16(IONIC_QINIT_F_IRQ |
138109f806e9SAndrew Boyer IONIC_QINIT_F_ENA),
138227b942c8SAlfredo Cardigliano .ring_size = rte_log2_u32(q->num_descs),
138309f806e9SAndrew Boyer .ring_base = rte_cpu_to_le_64(q->base_pa),
138427b942c8SAlfredo Cardigliano }
138527b942c8SAlfredo Cardigliano };
138627b942c8SAlfredo Cardigliano
138709f806e9SAndrew Boyer IONIC_PRINT(DEBUG, "notifyq_init.index %d", q->index);
138809f806e9SAndrew Boyer IONIC_PRINT(DEBUG, "notifyq_init.ring_base 0x%" PRIx64 "", q->base_pa);
138927b942c8SAlfredo Cardigliano IONIC_PRINT(DEBUG, "notifyq_init.ring_size %d",
139027b942c8SAlfredo Cardigliano ctx.cmd.q_init.ring_size);
13914ae96cb8SAndrew Boyer IONIC_PRINT(DEBUG, "notifyq_init.ver %u", ctx.cmd.q_init.ver);
139227b942c8SAlfredo Cardigliano
139327b942c8SAlfredo Cardigliano err = ionic_adminq_post_wait(lif, &ctx);
139427b942c8SAlfredo Cardigliano if (err)
139527b942c8SAlfredo Cardigliano return err;
139627b942c8SAlfredo Cardigliano
139727b942c8SAlfredo Cardigliano q->hw_type = ctx.comp.q_init.hw_type;
139809f806e9SAndrew Boyer q->hw_index = rte_le_to_cpu_32(ctx.comp.q_init.hw_index);
139927b942c8SAlfredo Cardigliano q->db = NULL;
140027b942c8SAlfredo Cardigliano
140127b942c8SAlfredo Cardigliano IONIC_PRINT(DEBUG, "notifyq->hw_type %d", q->hw_type);
140227b942c8SAlfredo Cardigliano IONIC_PRINT(DEBUG, "notifyq->hw_index %d", q->hw_index);
140327b942c8SAlfredo Cardigliano IONIC_PRINT(DEBUG, "notifyq->db %p", q->db);
140427b942c8SAlfredo Cardigliano
1405be39f75cSAndrew Boyer ionic_intr_mask(idev->intr_ctrl, nqcq->intr.index,
140627b942c8SAlfredo Cardigliano IONIC_INTR_MASK_CLEAR);
140727b942c8SAlfredo Cardigliano
1408be39f75cSAndrew Boyer nqcq->flags |= IONIC_QCQ_F_INITED;
140927b942c8SAlfredo Cardigliano
141027b942c8SAlfredo Cardigliano return 0;
141127b942c8SAlfredo Cardigliano }
141227b942c8SAlfredo Cardigliano
1413669c8de6SAlfredo Cardigliano int
ionic_lif_set_features(struct ionic_lif * lif)1414598f6726SAlfredo Cardigliano ionic_lif_set_features(struct ionic_lif *lif)
1415598f6726SAlfredo Cardigliano {
1416598f6726SAlfredo Cardigliano struct ionic_admin_ctx ctx = {
1417598f6726SAlfredo Cardigliano .pending_work = true,
1418598f6726SAlfredo Cardigliano .cmd.lif_setattr = {
1419598f6726SAlfredo Cardigliano .opcode = IONIC_CMD_LIF_SETATTR,
1420598f6726SAlfredo Cardigliano .attr = IONIC_LIF_ATTR_FEATURES,
142109f806e9SAndrew Boyer .features = rte_cpu_to_le_64(lif->features),
1422598f6726SAlfredo Cardigliano },
1423598f6726SAlfredo Cardigliano };
1424598f6726SAlfredo Cardigliano int err;
1425598f6726SAlfredo Cardigliano
1426598f6726SAlfredo Cardigliano err = ionic_adminq_post_wait(lif, &ctx);
1427598f6726SAlfredo Cardigliano if (err)
1428598f6726SAlfredo Cardigliano return err;
1429598f6726SAlfredo Cardigliano
143009f806e9SAndrew Boyer lif->hw_features = rte_le_to_cpu_64(ctx.cmd.lif_setattr.features &
1431598f6726SAlfredo Cardigliano ctx.comp.lif_setattr.features);
1432598f6726SAlfredo Cardigliano
1433598f6726SAlfredo Cardigliano if (lif->hw_features & IONIC_ETH_HW_VLAN_TX_TAG)
1434598f6726SAlfredo Cardigliano IONIC_PRINT(DEBUG, "feature IONIC_ETH_HW_VLAN_TX_TAG");
1435598f6726SAlfredo Cardigliano if (lif->hw_features & IONIC_ETH_HW_VLAN_RX_STRIP)
1436598f6726SAlfredo Cardigliano IONIC_PRINT(DEBUG, "feature IONIC_ETH_HW_VLAN_RX_STRIP");
1437598f6726SAlfredo Cardigliano if (lif->hw_features & IONIC_ETH_HW_VLAN_RX_FILTER)
1438598f6726SAlfredo Cardigliano IONIC_PRINT(DEBUG, "feature IONIC_ETH_HW_VLAN_RX_FILTER");
1439598f6726SAlfredo Cardigliano if (lif->hw_features & IONIC_ETH_HW_RX_HASH)
1440598f6726SAlfredo Cardigliano IONIC_PRINT(DEBUG, "feature IONIC_ETH_HW_RX_HASH");
1441598f6726SAlfredo Cardigliano if (lif->hw_features & IONIC_ETH_HW_TX_SG)
1442598f6726SAlfredo Cardigliano IONIC_PRINT(DEBUG, "feature IONIC_ETH_HW_TX_SG");
1443598f6726SAlfredo Cardigliano if (lif->hw_features & IONIC_ETH_HW_RX_SG)
1444598f6726SAlfredo Cardigliano IONIC_PRINT(DEBUG, "feature IONIC_ETH_HW_RX_SG");
1445598f6726SAlfredo Cardigliano if (lif->hw_features & IONIC_ETH_HW_TX_CSUM)
1446598f6726SAlfredo Cardigliano IONIC_PRINT(DEBUG, "feature IONIC_ETH_HW_TX_CSUM");
1447598f6726SAlfredo Cardigliano if (lif->hw_features & IONIC_ETH_HW_RX_CSUM)
1448598f6726SAlfredo Cardigliano IONIC_PRINT(DEBUG, "feature IONIC_ETH_HW_RX_CSUM");
1449598f6726SAlfredo Cardigliano if (lif->hw_features & IONIC_ETH_HW_TSO)
1450598f6726SAlfredo Cardigliano IONIC_PRINT(DEBUG, "feature IONIC_ETH_HW_TSO");
1451598f6726SAlfredo Cardigliano if (lif->hw_features & IONIC_ETH_HW_TSO_IPV6)
1452598f6726SAlfredo Cardigliano IONIC_PRINT(DEBUG, "feature IONIC_ETH_HW_TSO_IPV6");
1453598f6726SAlfredo Cardigliano if (lif->hw_features & IONIC_ETH_HW_TSO_ECN)
1454598f6726SAlfredo Cardigliano IONIC_PRINT(DEBUG, "feature IONIC_ETH_HW_TSO_ECN");
1455598f6726SAlfredo Cardigliano if (lif->hw_features & IONIC_ETH_HW_TSO_GRE)
1456598f6726SAlfredo Cardigliano IONIC_PRINT(DEBUG, "feature IONIC_ETH_HW_TSO_GRE");
1457598f6726SAlfredo Cardigliano if (lif->hw_features & IONIC_ETH_HW_TSO_GRE_CSUM)
1458598f6726SAlfredo Cardigliano IONIC_PRINT(DEBUG, "feature IONIC_ETH_HW_TSO_GRE_CSUM");
1459598f6726SAlfredo Cardigliano if (lif->hw_features & IONIC_ETH_HW_TSO_IPXIP4)
1460598f6726SAlfredo Cardigliano IONIC_PRINT(DEBUG, "feature IONIC_ETH_HW_TSO_IPXIP4");
1461598f6726SAlfredo Cardigliano if (lif->hw_features & IONIC_ETH_HW_TSO_IPXIP6)
1462598f6726SAlfredo Cardigliano IONIC_PRINT(DEBUG, "feature IONIC_ETH_HW_TSO_IPXIP6");
1463598f6726SAlfredo Cardigliano if (lif->hw_features & IONIC_ETH_HW_TSO_UDP)
1464598f6726SAlfredo Cardigliano IONIC_PRINT(DEBUG, "feature IONIC_ETH_HW_TSO_UDP");
1465598f6726SAlfredo Cardigliano if (lif->hw_features & IONIC_ETH_HW_TSO_UDP_CSUM)
1466598f6726SAlfredo Cardigliano IONIC_PRINT(DEBUG, "feature IONIC_ETH_HW_TSO_UDP_CSUM");
1467598f6726SAlfredo Cardigliano
1468598f6726SAlfredo Cardigliano return 0;
1469598f6726SAlfredo Cardigliano }
1470598f6726SAlfredo Cardigliano
1471a27d9013SAlfredo Cardigliano int
ionic_lif_txq_init(struct ionic_tx_qcq * txq)1472be39f75cSAndrew Boyer ionic_lif_txq_init(struct ionic_tx_qcq *txq)
1473a27d9013SAlfredo Cardigliano {
1474be39f75cSAndrew Boyer struct ionic_qcq *qcq = &txq->qcq;
1475a27d9013SAlfredo Cardigliano struct ionic_queue *q = &qcq->q;
1476a27d9013SAlfredo Cardigliano struct ionic_lif *lif = qcq->lif;
1477a27d9013SAlfredo Cardigliano struct ionic_cq *cq = &qcq->cq;
1478a27d9013SAlfredo Cardigliano struct ionic_admin_ctx ctx = {
1479a27d9013SAlfredo Cardigliano .pending_work = true,
1480a27d9013SAlfredo Cardigliano .cmd.q_init = {
1481a27d9013SAlfredo Cardigliano .opcode = IONIC_CMD_Q_INIT,
1482a27d9013SAlfredo Cardigliano .type = q->type,
1483c5d15850SAndrew Boyer .ver = lif->qtype_info[q->type].version,
148409f806e9SAndrew Boyer .index = rte_cpu_to_le_32(q->index),
148509f806e9SAndrew Boyer .flags = rte_cpu_to_le_16(IONIC_QINIT_F_SG |
148609f806e9SAndrew Boyer IONIC_QINIT_F_ENA),
148709f806e9SAndrew Boyer .intr_index = rte_cpu_to_le_16(IONIC_INTR_NONE),
1488a27d9013SAlfredo Cardigliano .ring_size = rte_log2_u32(q->num_descs),
148909f806e9SAndrew Boyer .ring_base = rte_cpu_to_le_64(q->base_pa),
149009f806e9SAndrew Boyer .cq_ring_base = rte_cpu_to_le_64(cq->base_pa),
149109f806e9SAndrew Boyer .sg_ring_base = rte_cpu_to_le_64(q->sg_base_pa),
1492a27d9013SAlfredo Cardigliano },
1493a27d9013SAlfredo Cardigliano };
1494a27d9013SAlfredo Cardigliano int err;
1495a27d9013SAlfredo Cardigliano
149609f806e9SAndrew Boyer IONIC_PRINT(DEBUG, "txq_init.index %d", q->index);
149709f806e9SAndrew Boyer IONIC_PRINT(DEBUG, "txq_init.ring_base 0x%" PRIx64 "", q->base_pa);
1498a27d9013SAlfredo Cardigliano IONIC_PRINT(DEBUG, "txq_init.ring_size %d",
1499a27d9013SAlfredo Cardigliano ctx.cmd.q_init.ring_size);
15004ae96cb8SAndrew Boyer IONIC_PRINT(DEBUG, "txq_init.ver %u", ctx.cmd.q_init.ver);
1501a27d9013SAlfredo Cardigliano
1502be39f75cSAndrew Boyer err = ionic_adminq_post_wait(lif, &ctx);
1503a27d9013SAlfredo Cardigliano if (err)
1504a27d9013SAlfredo Cardigliano return err;
1505a27d9013SAlfredo Cardigliano
1506a27d9013SAlfredo Cardigliano q->hw_type = ctx.comp.q_init.hw_type;
150709f806e9SAndrew Boyer q->hw_index = rte_le_to_cpu_32(ctx.comp.q_init.hw_index);
1508a27d9013SAlfredo Cardigliano q->db = ionic_db_map(lif, q);
1509a27d9013SAlfredo Cardigliano
1510a27d9013SAlfredo Cardigliano IONIC_PRINT(DEBUG, "txq->hw_type %d", q->hw_type);
1511a27d9013SAlfredo Cardigliano IONIC_PRINT(DEBUG, "txq->hw_index %d", q->hw_index);
1512a27d9013SAlfredo Cardigliano IONIC_PRINT(DEBUG, "txq->db %p", q->db);
1513a27d9013SAlfredo Cardigliano
1514be39f75cSAndrew Boyer txq->flags |= IONIC_QCQ_F_INITED;
1515a27d9013SAlfredo Cardigliano
1516a27d9013SAlfredo Cardigliano return 0;
1517a27d9013SAlfredo Cardigliano }
1518a27d9013SAlfredo Cardigliano
1519a27d9013SAlfredo Cardigliano int
ionic_lif_rxq_init(struct ionic_rx_qcq * rxq)1520be39f75cSAndrew Boyer ionic_lif_rxq_init(struct ionic_rx_qcq *rxq)
1521a27d9013SAlfredo Cardigliano {
1522be39f75cSAndrew Boyer struct ionic_qcq *qcq = &rxq->qcq;
1523a27d9013SAlfredo Cardigliano struct ionic_queue *q = &qcq->q;
1524a27d9013SAlfredo Cardigliano struct ionic_lif *lif = qcq->lif;
1525a27d9013SAlfredo Cardigliano struct ionic_cq *cq = &qcq->cq;
1526a27d9013SAlfredo Cardigliano struct ionic_admin_ctx ctx = {
1527a27d9013SAlfredo Cardigliano .pending_work = true,
1528a27d9013SAlfredo Cardigliano .cmd.q_init = {
1529a27d9013SAlfredo Cardigliano .opcode = IONIC_CMD_Q_INIT,
1530a27d9013SAlfredo Cardigliano .type = q->type,
1531c5d15850SAndrew Boyer .ver = lif->qtype_info[q->type].version,
153209f806e9SAndrew Boyer .index = rte_cpu_to_le_32(q->index),
153309f806e9SAndrew Boyer .flags = rte_cpu_to_le_16(IONIC_QINIT_F_SG |
153409f806e9SAndrew Boyer IONIC_QINIT_F_ENA),
153509f806e9SAndrew Boyer .intr_index = rte_cpu_to_le_16(IONIC_INTR_NONE),
1536a27d9013SAlfredo Cardigliano .ring_size = rte_log2_u32(q->num_descs),
153709f806e9SAndrew Boyer .ring_base = rte_cpu_to_le_64(q->base_pa),
153809f806e9SAndrew Boyer .cq_ring_base = rte_cpu_to_le_64(cq->base_pa),
153909f806e9SAndrew Boyer .sg_ring_base = rte_cpu_to_le_64(q->sg_base_pa),
1540a27d9013SAlfredo Cardigliano },
1541a27d9013SAlfredo Cardigliano };
1542a27d9013SAlfredo Cardigliano int err;
1543a27d9013SAlfredo Cardigliano
154409f806e9SAndrew Boyer IONIC_PRINT(DEBUG, "rxq_init.index %d", q->index);
154509f806e9SAndrew Boyer IONIC_PRINT(DEBUG, "rxq_init.ring_base 0x%" PRIx64 "", q->base_pa);
1546a27d9013SAlfredo Cardigliano IONIC_PRINT(DEBUG, "rxq_init.ring_size %d",
1547a27d9013SAlfredo Cardigliano ctx.cmd.q_init.ring_size);
15484ae96cb8SAndrew Boyer IONIC_PRINT(DEBUG, "rxq_init.ver %u", ctx.cmd.q_init.ver);
1549a27d9013SAlfredo Cardigliano
1550be39f75cSAndrew Boyer err = ionic_adminq_post_wait(lif, &ctx);
1551a27d9013SAlfredo Cardigliano if (err)
1552a27d9013SAlfredo Cardigliano return err;
1553a27d9013SAlfredo Cardigliano
1554a27d9013SAlfredo Cardigliano q->hw_type = ctx.comp.q_init.hw_type;
155509f806e9SAndrew Boyer q->hw_index = rte_le_to_cpu_32(ctx.comp.q_init.hw_index);
1556a27d9013SAlfredo Cardigliano q->db = ionic_db_map(lif, q);
1557a27d9013SAlfredo Cardigliano
1558be39f75cSAndrew Boyer rxq->flags |= IONIC_QCQ_F_INITED;
1559a27d9013SAlfredo Cardigliano
1560a27d9013SAlfredo Cardigliano IONIC_PRINT(DEBUG, "rxq->hw_type %d", q->hw_type);
1561a27d9013SAlfredo Cardigliano IONIC_PRINT(DEBUG, "rxq->hw_index %d", q->hw_index);
1562a27d9013SAlfredo Cardigliano IONIC_PRINT(DEBUG, "rxq->db %p", q->db);
1563a27d9013SAlfredo Cardigliano
1564a27d9013SAlfredo Cardigliano return 0;
1565a27d9013SAlfredo Cardigliano }
1566a27d9013SAlfredo Cardigliano
1567598f6726SAlfredo Cardigliano static int
ionic_station_set(struct ionic_lif * lif)1568598f6726SAlfredo Cardigliano ionic_station_set(struct ionic_lif *lif)
1569598f6726SAlfredo Cardigliano {
1570598f6726SAlfredo Cardigliano struct ionic_admin_ctx ctx = {
1571598f6726SAlfredo Cardigliano .pending_work = true,
1572598f6726SAlfredo Cardigliano .cmd.lif_getattr = {
1573598f6726SAlfredo Cardigliano .opcode = IONIC_CMD_LIF_GETATTR,
1574598f6726SAlfredo Cardigliano .attr = IONIC_LIF_ATTR_MAC,
1575598f6726SAlfredo Cardigliano },
1576598f6726SAlfredo Cardigliano };
1577598f6726SAlfredo Cardigliano int err;
1578598f6726SAlfredo Cardigliano
1579598f6726SAlfredo Cardigliano IONIC_PRINT_CALL();
1580598f6726SAlfredo Cardigliano
1581598f6726SAlfredo Cardigliano err = ionic_adminq_post_wait(lif, &ctx);
1582598f6726SAlfredo Cardigliano if (err)
1583598f6726SAlfredo Cardigliano return err;
1584598f6726SAlfredo Cardigliano
1585598f6726SAlfredo Cardigliano memcpy(lif->mac_addr, ctx.comp.lif_getattr.mac, RTE_ETHER_ADDR_LEN);
1586598f6726SAlfredo Cardigliano
1587598f6726SAlfredo Cardigliano return 0;
1588598f6726SAlfredo Cardigliano }
1589598f6726SAlfredo Cardigliano
1590598f6726SAlfredo Cardigliano static void
ionic_lif_set_name(struct ionic_lif * lif)1591598f6726SAlfredo Cardigliano ionic_lif_set_name(struct ionic_lif *lif)
1592598f6726SAlfredo Cardigliano {
1593598f6726SAlfredo Cardigliano struct ionic_admin_ctx ctx = {
1594598f6726SAlfredo Cardigliano .pending_work = true,
1595598f6726SAlfredo Cardigliano .cmd.lif_setattr = {
1596598f6726SAlfredo Cardigliano .opcode = IONIC_CMD_LIF_SETATTR,
1597598f6726SAlfredo Cardigliano .attr = IONIC_LIF_ATTR_NAME,
1598598f6726SAlfredo Cardigliano },
1599598f6726SAlfredo Cardigliano };
1600598f6726SAlfredo Cardigliano
16014ae96cb8SAndrew Boyer memcpy(ctx.cmd.lif_setattr.name, lif->name,
16024ae96cb8SAndrew Boyer sizeof(ctx.cmd.lif_setattr.name) - 1);
1603598f6726SAlfredo Cardigliano
1604598f6726SAlfredo Cardigliano ionic_adminq_post_wait(lif, &ctx);
1605598f6726SAlfredo Cardigliano }
1606598f6726SAlfredo Cardigliano
1607598f6726SAlfredo Cardigliano int
ionic_lif_init(struct ionic_lif * lif)1608669c8de6SAlfredo Cardigliano ionic_lif_init(struct ionic_lif *lif)
1609669c8de6SAlfredo Cardigliano {
1610669c8de6SAlfredo Cardigliano struct ionic_dev *idev = &lif->adapter->idev;
1611656bfc9aSAndrew Boyer struct ionic_lif_init_comp comp;
1612669c8de6SAlfredo Cardigliano int err;
1613669c8de6SAlfredo Cardigliano
16143cdfd905SAlfredo Cardigliano memset(&lif->stats_base, 0, sizeof(lif->stats_base));
16153cdfd905SAlfredo Cardigliano
161600b65da5SAndrew Boyer ionic_dev_cmd_lif_init(idev, lif->info_pa);
1617669c8de6SAlfredo Cardigliano err = ionic_dev_cmd_wait_check(idev, IONIC_DEVCMD_TIMEOUT);
1618669c8de6SAlfredo Cardigliano if (err)
1619669c8de6SAlfredo Cardigliano return err;
1620669c8de6SAlfredo Cardigliano
1621656bfc9aSAndrew Boyer ionic_dev_cmd_comp(idev, &comp);
1622656bfc9aSAndrew Boyer
162309f806e9SAndrew Boyer lif->hw_index = rte_cpu_to_le_16(comp.hw_index);
1624669c8de6SAlfredo Cardigliano
162501a6c311SAlfredo Cardigliano err = ionic_lif_adminq_init(lif);
162601a6c311SAlfredo Cardigliano if (err)
162701a6c311SAlfredo Cardigliano return err;
162801a6c311SAlfredo Cardigliano
162927b942c8SAlfredo Cardigliano err = ionic_lif_notifyq_init(lif);
163027b942c8SAlfredo Cardigliano if (err)
163127b942c8SAlfredo Cardigliano goto err_out_adminq_deinit;
163227b942c8SAlfredo Cardigliano
163318a44465SAndrew Boyer /*
163418a44465SAndrew Boyer * Configure initial feature set
163518a44465SAndrew Boyer * This will be updated later by the dev_configure() step
163618a44465SAndrew Boyer */
163718a44465SAndrew Boyer lif->features = IONIC_ETH_HW_RX_HASH | IONIC_ETH_HW_VLAN_RX_FILTER;
1638598f6726SAlfredo Cardigliano
1639598f6726SAlfredo Cardigliano err = ionic_lif_set_features(lif);
1640598f6726SAlfredo Cardigliano if (err)
1641598f6726SAlfredo Cardigliano goto err_out_notifyq_deinit;
1642598f6726SAlfredo Cardigliano
164354fe083fSAlfredo Cardigliano err = ionic_rx_filters_init(lif);
1644598f6726SAlfredo Cardigliano if (err)
1645598f6726SAlfredo Cardigliano goto err_out_notifyq_deinit;
1646598f6726SAlfredo Cardigliano
164754fe083fSAlfredo Cardigliano err = ionic_station_set(lif);
164854fe083fSAlfredo Cardigliano if (err)
164954fe083fSAlfredo Cardigliano goto err_out_rx_filter_deinit;
165054fe083fSAlfredo Cardigliano
1651598f6726SAlfredo Cardigliano ionic_lif_set_name(lif);
1652598f6726SAlfredo Cardigliano
1653669c8de6SAlfredo Cardigliano lif->state |= IONIC_LIF_F_INITED;
1654669c8de6SAlfredo Cardigliano
1655669c8de6SAlfredo Cardigliano return 0;
165627b942c8SAlfredo Cardigliano
165754fe083fSAlfredo Cardigliano err_out_rx_filter_deinit:
165854fe083fSAlfredo Cardigliano ionic_rx_filters_deinit(lif);
165954fe083fSAlfredo Cardigliano
1660598f6726SAlfredo Cardigliano err_out_notifyq_deinit:
16614c8f8d57SAndrew Boyer ionic_lif_notifyq_deinit(lif);
1662598f6726SAlfredo Cardigliano
166327b942c8SAlfredo Cardigliano err_out_adminq_deinit:
1664be39f75cSAndrew Boyer ionic_lif_adminq_deinit(lif);
166527b942c8SAlfredo Cardigliano
166627b942c8SAlfredo Cardigliano return err;
1667669c8de6SAlfredo Cardigliano }
1668669c8de6SAlfredo Cardigliano
1669669c8de6SAlfredo Cardigliano void
ionic_lif_deinit(struct ionic_lif * lif)1670669c8de6SAlfredo Cardigliano ionic_lif_deinit(struct ionic_lif *lif)
1671669c8de6SAlfredo Cardigliano {
1672669c8de6SAlfredo Cardigliano if (!(lif->state & IONIC_LIF_F_INITED))
1673669c8de6SAlfredo Cardigliano return;
1674669c8de6SAlfredo Cardigliano
167554fe083fSAlfredo Cardigliano ionic_rx_filters_deinit(lif);
167622e7171bSAlfredo Cardigliano ionic_lif_rss_teardown(lif);
16774c8f8d57SAndrew Boyer ionic_lif_notifyq_deinit(lif);
1678be39f75cSAndrew Boyer ionic_lif_adminq_deinit(lif);
167901a6c311SAlfredo Cardigliano
1680669c8de6SAlfredo Cardigliano lif->state &= ~IONIC_LIF_F_INITED;
1681669c8de6SAlfredo Cardigliano }
1682669c8de6SAlfredo Cardigliano
168318a44465SAndrew Boyer void
ionic_lif_configure_vlan_offload(struct ionic_lif * lif,int mask)168418a44465SAndrew Boyer ionic_lif_configure_vlan_offload(struct ionic_lif *lif, int mask)
168518a44465SAndrew Boyer {
168618a44465SAndrew Boyer struct rte_eth_dev *eth_dev = lif->eth_dev;
168718a44465SAndrew Boyer struct rte_eth_rxmode *rxmode = ð_dev->data->dev_conf.rxmode;
168818a44465SAndrew Boyer
168918a44465SAndrew Boyer /*
169018a44465SAndrew Boyer * IONIC_ETH_HW_VLAN_RX_FILTER cannot be turned off, so
1691*295968d1SFerruh Yigit * set RTE_ETH_RX_OFFLOAD_VLAN_FILTER and ignore RTE_ETH_VLAN_FILTER_MASK
169218a44465SAndrew Boyer */
1693*295968d1SFerruh Yigit rxmode->offloads |= RTE_ETH_RX_OFFLOAD_VLAN_FILTER;
169418a44465SAndrew Boyer
1695*295968d1SFerruh Yigit if (mask & RTE_ETH_VLAN_STRIP_MASK) {
1696*295968d1SFerruh Yigit if (rxmode->offloads & RTE_ETH_RX_OFFLOAD_VLAN_STRIP)
169718a44465SAndrew Boyer lif->features |= IONIC_ETH_HW_VLAN_RX_STRIP;
169818a44465SAndrew Boyer else
169918a44465SAndrew Boyer lif->features &= ~IONIC_ETH_HW_VLAN_RX_STRIP;
170018a44465SAndrew Boyer }
170118a44465SAndrew Boyer }
170218a44465SAndrew Boyer
170318a44465SAndrew Boyer void
ionic_lif_configure(struct ionic_lif * lif)1704598f6726SAlfredo Cardigliano ionic_lif_configure(struct ionic_lif *lif)
1705598f6726SAlfredo Cardigliano {
170618a44465SAndrew Boyer struct rte_eth_rxmode *rxmode = &lif->eth_dev->data->dev_conf.rxmode;
170718a44465SAndrew Boyer struct rte_eth_txmode *txmode = &lif->eth_dev->data->dev_conf.txmode;
170822e7171bSAlfredo Cardigliano struct ionic_identity *ident = &lif->adapter->ident;
170909f806e9SAndrew Boyer union ionic_lif_config *cfg = &ident->lif.eth.config;
171022e7171bSAlfredo Cardigliano uint32_t ntxqs_per_lif =
171109f806e9SAndrew Boyer rte_le_to_cpu_32(cfg->queue_count[IONIC_QTYPE_TXQ]);
171222e7171bSAlfredo Cardigliano uint32_t nrxqs_per_lif =
171309f806e9SAndrew Boyer rte_le_to_cpu_32(cfg->queue_count[IONIC_QTYPE_RXQ]);
171422e7171bSAlfredo Cardigliano uint32_t nrxqs = lif->eth_dev->data->nb_rx_queues;
171522e7171bSAlfredo Cardigliano uint32_t ntxqs = lif->eth_dev->data->nb_tx_queues;
171622e7171bSAlfredo Cardigliano
1717598f6726SAlfredo Cardigliano lif->port_id = lif->eth_dev->data->port_id;
1718598f6726SAlfredo Cardigliano
171922e7171bSAlfredo Cardigliano IONIC_PRINT(DEBUG, "Configuring LIF on port %u",
172022e7171bSAlfredo Cardigliano lif->port_id);
172122e7171bSAlfredo Cardigliano
172222e7171bSAlfredo Cardigliano if (nrxqs > 0)
172322e7171bSAlfredo Cardigliano nrxqs_per_lif = RTE_MIN(nrxqs_per_lif, nrxqs);
172422e7171bSAlfredo Cardigliano
172522e7171bSAlfredo Cardigliano if (ntxqs > 0)
172622e7171bSAlfredo Cardigliano ntxqs_per_lif = RTE_MIN(ntxqs_per_lif, ntxqs);
172722e7171bSAlfredo Cardigliano
172822e7171bSAlfredo Cardigliano lif->nrxqcqs = nrxqs_per_lif;
172922e7171bSAlfredo Cardigliano lif->ntxqcqs = ntxqs_per_lif;
1730a27d9013SAlfredo Cardigliano
173118a44465SAndrew Boyer /* Update the LIF configuration based on the eth_dev */
173218a44465SAndrew Boyer
173318a44465SAndrew Boyer /*
173418a44465SAndrew Boyer * NB: While it is true that RSS_HASH is always enabled on ionic,
173518a44465SAndrew Boyer * setting this flag unconditionally causes problems in DTS.
1736*295968d1SFerruh Yigit * rxmode->offloads |= RTE_ETH_RX_OFFLOAD_RSS_HASH;
173718a44465SAndrew Boyer */
173818a44465SAndrew Boyer
173918a44465SAndrew Boyer /* RX per-port */
174018a44465SAndrew Boyer
1741*295968d1SFerruh Yigit if (rxmode->offloads & RTE_ETH_RX_OFFLOAD_IPV4_CKSUM ||
1742*295968d1SFerruh Yigit rxmode->offloads & RTE_ETH_RX_OFFLOAD_UDP_CKSUM ||
1743*295968d1SFerruh Yigit rxmode->offloads & RTE_ETH_RX_OFFLOAD_TCP_CKSUM)
174418a44465SAndrew Boyer lif->features |= IONIC_ETH_HW_RX_CSUM;
174518a44465SAndrew Boyer else
174618a44465SAndrew Boyer lif->features &= ~IONIC_ETH_HW_RX_CSUM;
174718a44465SAndrew Boyer
1748*295968d1SFerruh Yigit if (rxmode->offloads & RTE_ETH_RX_OFFLOAD_SCATTER) {
174918a44465SAndrew Boyer lif->features |= IONIC_ETH_HW_RX_SG;
175018a44465SAndrew Boyer lif->eth_dev->data->scattered_rx = 1;
175118a44465SAndrew Boyer } else {
175218a44465SAndrew Boyer lif->features &= ~IONIC_ETH_HW_RX_SG;
175318a44465SAndrew Boyer lif->eth_dev->data->scattered_rx = 0;
175418a44465SAndrew Boyer }
175518a44465SAndrew Boyer
175618a44465SAndrew Boyer /* Covers VLAN_STRIP */
1757*295968d1SFerruh Yigit ionic_lif_configure_vlan_offload(lif, RTE_ETH_VLAN_STRIP_MASK);
175818a44465SAndrew Boyer
175918a44465SAndrew Boyer /* TX per-port */
176018a44465SAndrew Boyer
1761*295968d1SFerruh Yigit if (txmode->offloads & RTE_ETH_TX_OFFLOAD_IPV4_CKSUM ||
1762*295968d1SFerruh Yigit txmode->offloads & RTE_ETH_TX_OFFLOAD_UDP_CKSUM ||
1763*295968d1SFerruh Yigit txmode->offloads & RTE_ETH_TX_OFFLOAD_TCP_CKSUM ||
1764*295968d1SFerruh Yigit txmode->offloads & RTE_ETH_TX_OFFLOAD_OUTER_IPV4_CKSUM ||
1765*295968d1SFerruh Yigit txmode->offloads & RTE_ETH_TX_OFFLOAD_OUTER_UDP_CKSUM)
176618a44465SAndrew Boyer lif->features |= IONIC_ETH_HW_TX_CSUM;
176718a44465SAndrew Boyer else
176818a44465SAndrew Boyer lif->features &= ~IONIC_ETH_HW_TX_CSUM;
176918a44465SAndrew Boyer
1770*295968d1SFerruh Yigit if (txmode->offloads & RTE_ETH_TX_OFFLOAD_VLAN_INSERT)
177118a44465SAndrew Boyer lif->features |= IONIC_ETH_HW_VLAN_TX_TAG;
177218a44465SAndrew Boyer else
177318a44465SAndrew Boyer lif->features &= ~IONIC_ETH_HW_VLAN_TX_TAG;
177418a44465SAndrew Boyer
1775*295968d1SFerruh Yigit if (txmode->offloads & RTE_ETH_TX_OFFLOAD_MULTI_SEGS)
177618a44465SAndrew Boyer lif->features |= IONIC_ETH_HW_TX_SG;
177718a44465SAndrew Boyer else
177818a44465SAndrew Boyer lif->features &= ~IONIC_ETH_HW_TX_SG;
177918a44465SAndrew Boyer
1780*295968d1SFerruh Yigit if (txmode->offloads & RTE_ETH_TX_OFFLOAD_TCP_TSO) {
178118a44465SAndrew Boyer lif->features |= IONIC_ETH_HW_TSO;
178218a44465SAndrew Boyer lif->features |= IONIC_ETH_HW_TSO_IPV6;
178318a44465SAndrew Boyer lif->features |= IONIC_ETH_HW_TSO_ECN;
178418a44465SAndrew Boyer } else {
178518a44465SAndrew Boyer lif->features &= ~IONIC_ETH_HW_TSO;
178618a44465SAndrew Boyer lif->features &= ~IONIC_ETH_HW_TSO_IPV6;
178718a44465SAndrew Boyer lif->features &= ~IONIC_ETH_HW_TSO_ECN;
178818a44465SAndrew Boyer }
1789598f6726SAlfredo Cardigliano }
1790598f6726SAlfredo Cardigliano
1791598f6726SAlfredo Cardigliano int
ionic_lif_start(struct ionic_lif * lif)1792598f6726SAlfredo Cardigliano ionic_lif_start(struct ionic_lif *lif)
1793598f6726SAlfredo Cardigliano {
17940578335aSAndrew Boyer uint32_t rx_mode;
1795a27d9013SAlfredo Cardigliano uint32_t i;
1796a27d9013SAlfredo Cardigliano int err;
1797598f6726SAlfredo Cardigliano
179822e7171bSAlfredo Cardigliano err = ionic_lif_rss_setup(lif);
179922e7171bSAlfredo Cardigliano if (err)
180022e7171bSAlfredo Cardigliano return err;
180122e7171bSAlfredo Cardigliano
18020578335aSAndrew Boyer if (!lif->rx_mode) {
18030578335aSAndrew Boyer IONIC_PRINT(DEBUG, "Setting RX mode on %s",
18040578335aSAndrew Boyer lif->name);
1805598f6726SAlfredo Cardigliano
18060578335aSAndrew Boyer rx_mode = IONIC_RX_MODE_F_UNICAST;
1807598f6726SAlfredo Cardigliano rx_mode |= IONIC_RX_MODE_F_MULTICAST;
1808598f6726SAlfredo Cardigliano rx_mode |= IONIC_RX_MODE_F_BROADCAST;
1809598f6726SAlfredo Cardigliano
1810598f6726SAlfredo Cardigliano ionic_set_rx_mode(lif, rx_mode);
18110578335aSAndrew Boyer }
1812598f6726SAlfredo Cardigliano
1813a27d9013SAlfredo Cardigliano IONIC_PRINT(DEBUG, "Starting %u RX queues and %u TX queues "
1814a27d9013SAlfredo Cardigliano "on port %u",
1815a27d9013SAlfredo Cardigliano lif->nrxqcqs, lif->ntxqcqs, lif->port_id);
1816a27d9013SAlfredo Cardigliano
1817a27d9013SAlfredo Cardigliano for (i = 0; i < lif->nrxqcqs; i++) {
1818be39f75cSAndrew Boyer struct ionic_rx_qcq *rxq = lif->rxqcqs[i];
181902eabf57SAndrew Boyer if (!(rxq->flags & IONIC_QCQ_F_DEFERRED)) {
1820a27d9013SAlfredo Cardigliano err = ionic_dev_rx_queue_start(lif->eth_dev, i);
1821a27d9013SAlfredo Cardigliano
1822a27d9013SAlfredo Cardigliano if (err)
1823a27d9013SAlfredo Cardigliano return err;
1824a27d9013SAlfredo Cardigliano }
1825a27d9013SAlfredo Cardigliano }
1826a27d9013SAlfredo Cardigliano
1827a27d9013SAlfredo Cardigliano for (i = 0; i < lif->ntxqcqs; i++) {
1828be39f75cSAndrew Boyer struct ionic_tx_qcq *txq = lif->txqcqs[i];
182902eabf57SAndrew Boyer if (!(txq->flags & IONIC_QCQ_F_DEFERRED)) {
1830a27d9013SAlfredo Cardigliano err = ionic_dev_tx_queue_start(lif->eth_dev, i);
1831a27d9013SAlfredo Cardigliano
1832a27d9013SAlfredo Cardigliano if (err)
1833a27d9013SAlfredo Cardigliano return err;
1834a27d9013SAlfredo Cardigliano }
1835a27d9013SAlfredo Cardigliano }
1836a27d9013SAlfredo Cardigliano
1837598f6726SAlfredo Cardigliano /* Carrier ON here */
1838be63459eSAndrew Boyer lif->state |= IONIC_LIF_F_UP;
1839be63459eSAndrew Boyer
1840be63459eSAndrew Boyer ionic_link_status_check(lif);
1841598f6726SAlfredo Cardigliano
1842598f6726SAlfredo Cardigliano return 0;
1843598f6726SAlfredo Cardigliano }
1844598f6726SAlfredo Cardigliano
1845598f6726SAlfredo Cardigliano int
ionic_lif_identify(struct ionic_adapter * adapter)1846669c8de6SAlfredo Cardigliano ionic_lif_identify(struct ionic_adapter *adapter)
1847669c8de6SAlfredo Cardigliano {
1848669c8de6SAlfredo Cardigliano struct ionic_dev *idev = &adapter->idev;
1849669c8de6SAlfredo Cardigliano struct ionic_identity *ident = &adapter->ident;
185009f806e9SAndrew Boyer union ionic_lif_config *cfg = &ident->lif.eth.config;
185176276d71SAndrew Boyer uint32_t lif_words = RTE_DIM(ident->lif.words);
185276276d71SAndrew Boyer uint32_t cmd_words = RTE_DIM(idev->dev_cmd->data);
185376276d71SAndrew Boyer uint32_t i, nwords;
1854669c8de6SAlfredo Cardigliano int err;
1855669c8de6SAlfredo Cardigliano
1856669c8de6SAlfredo Cardigliano ionic_dev_cmd_lif_identify(idev, IONIC_LIF_TYPE_CLASSIC,
1857669c8de6SAlfredo Cardigliano IONIC_IDENTITY_VERSION_1);
1858669c8de6SAlfredo Cardigliano err = ionic_dev_cmd_wait_check(idev, IONIC_DEVCMD_TIMEOUT);
1859669c8de6SAlfredo Cardigliano if (err)
1860669c8de6SAlfredo Cardigliano return (err);
1861669c8de6SAlfredo Cardigliano
1862669c8de6SAlfredo Cardigliano nwords = RTE_MIN(lif_words, cmd_words);
1863669c8de6SAlfredo Cardigliano for (i = 0; i < nwords; i++)
1864669c8de6SAlfredo Cardigliano ident->lif.words[i] = ioread32(&idev->dev_cmd->data[i]);
1865669c8de6SAlfredo Cardigliano
1866669c8de6SAlfredo Cardigliano IONIC_PRINT(INFO, "capabilities 0x%" PRIx64 " ",
186709f806e9SAndrew Boyer rte_le_to_cpu_64(ident->lif.capabilities));
1868669c8de6SAlfredo Cardigliano
1869669c8de6SAlfredo Cardigliano IONIC_PRINT(INFO, "eth.max_ucast_filters 0x%" PRIx32 " ",
187009f806e9SAndrew Boyer rte_le_to_cpu_32(ident->lif.eth.max_ucast_filters));
1871669c8de6SAlfredo Cardigliano IONIC_PRINT(INFO, "eth.max_mcast_filters 0x%" PRIx32 " ",
187209f806e9SAndrew Boyer rte_le_to_cpu_32(ident->lif.eth.max_mcast_filters));
1873669c8de6SAlfredo Cardigliano
1874669c8de6SAlfredo Cardigliano IONIC_PRINT(INFO, "eth.features 0x%" PRIx64 " ",
187509f806e9SAndrew Boyer rte_le_to_cpu_64(cfg->features));
1876669c8de6SAlfredo Cardigliano IONIC_PRINT(INFO, "eth.queue_count[IONIC_QTYPE_ADMINQ] 0x%" PRIx32 " ",
187709f806e9SAndrew Boyer rte_le_to_cpu_32(cfg->queue_count[IONIC_QTYPE_ADMINQ]));
1878669c8de6SAlfredo Cardigliano IONIC_PRINT(INFO, "eth.queue_count[IONIC_QTYPE_NOTIFYQ] 0x%" PRIx32 " ",
187909f806e9SAndrew Boyer rte_le_to_cpu_32(cfg->queue_count[IONIC_QTYPE_NOTIFYQ]));
1880669c8de6SAlfredo Cardigliano IONIC_PRINT(INFO, "eth.queue_count[IONIC_QTYPE_RXQ] 0x%" PRIx32 " ",
188109f806e9SAndrew Boyer rte_le_to_cpu_32(cfg->queue_count[IONIC_QTYPE_RXQ]));
1882669c8de6SAlfredo Cardigliano IONIC_PRINT(INFO, "eth.queue_count[IONIC_QTYPE_TXQ] 0x%" PRIx32 " ",
188309f806e9SAndrew Boyer rte_le_to_cpu_32(cfg->queue_count[IONIC_QTYPE_TXQ]));
1884669c8de6SAlfredo Cardigliano
1885669c8de6SAlfredo Cardigliano return 0;
1886669c8de6SAlfredo Cardigliano }
1887669c8de6SAlfredo Cardigliano
1888669c8de6SAlfredo Cardigliano int
ionic_lifs_size(struct ionic_adapter * adapter)1889669c8de6SAlfredo Cardigliano ionic_lifs_size(struct ionic_adapter *adapter)
1890669c8de6SAlfredo Cardigliano {
1891669c8de6SAlfredo Cardigliano struct ionic_identity *ident = &adapter->ident;
189209f806e9SAndrew Boyer union ionic_lif_config *cfg = &ident->lif.eth.config;
189309f806e9SAndrew Boyer uint32_t nintrs, dev_nintrs = rte_le_to_cpu_32(ident->dev.nintrs);
1894669c8de6SAlfredo Cardigliano
1895669c8de6SAlfredo Cardigliano adapter->max_ntxqs_per_lif =
189609f806e9SAndrew Boyer rte_le_to_cpu_32(cfg->queue_count[IONIC_QTYPE_TXQ]);
1897669c8de6SAlfredo Cardigliano adapter->max_nrxqs_per_lif =
189809f806e9SAndrew Boyer rte_le_to_cpu_32(cfg->queue_count[IONIC_QTYPE_RXQ]);
1899669c8de6SAlfredo Cardigliano
190000b65da5SAndrew Boyer nintrs = 1 /* notifyq */;
1901669c8de6SAlfredo Cardigliano
1902669c8de6SAlfredo Cardigliano if (nintrs > dev_nintrs) {
19034ae96cb8SAndrew Boyer IONIC_PRINT(ERR,
19044ae96cb8SAndrew Boyer "At most %d intr supported, minimum req'd is %u",
1905669c8de6SAlfredo Cardigliano dev_nintrs, nintrs);
1906669c8de6SAlfredo Cardigliano return -ENOSPC;
1907669c8de6SAlfredo Cardigliano }
1908669c8de6SAlfredo Cardigliano
1909669c8de6SAlfredo Cardigliano adapter->nintrs = nintrs;
1910669c8de6SAlfredo Cardigliano
1911669c8de6SAlfredo Cardigliano return 0;
1912669c8de6SAlfredo Cardigliano }
1913