ethdev: make driver-only headers private
[dpdk.git] / drivers / net / ionic / ionic_lif.c
index 875c7e5..f3d55c0 100644 (file)
@@ -3,7 +3,7 @@
  */
 
 #include <rte_malloc.h>
-#include <rte_ethdev_driver.h>
+#include <ethdev_driver.h>
 
 #include "ionic.h"
 #include "ionic_logs.h"
@@ -25,7 +25,6 @@ ionic_qcq_enable(struct ionic_qcq *qcq)
                .pending_work = true,
                .cmd.q_control = {
                        .opcode = IONIC_CMD_Q_CONTROL,
-                       .lif_index = lif->index,
                        .type = q->type,
                        .index = q->index,
                        .oper = IONIC_Q_ENABLE,
@@ -50,7 +49,6 @@ ionic_qcq_disable(struct ionic_qcq *qcq)
                .pending_work = true,
                .cmd.q_control = {
                        .opcode = IONIC_CMD_Q_CONTROL,
-                       .lif_index = lif->index,
                        .type = q->type,
                        .index = q->index,
                        .oper = IONIC_Q_DISABLE,
@@ -65,12 +63,26 @@ ionic_qcq_disable(struct ionic_qcq *qcq)
        return ionic_adminq_post_wait(lif, &ctx);
 }
 
-int
-ionic_lif_stop(struct ionic_lif *lif __rte_unused)
+void
+ionic_lif_stop(struct ionic_lif *lif)
 {
-       /* Carrier OFF here */
+       uint32_t i;
 
-       return 0;
+       IONIC_PRINT_CALL();
+
+       lif->state &= ~IONIC_LIF_F_UP;
+
+       for (i = 0; i < lif->nrxqcqs; i++) {
+               struct ionic_qcq *rxq = lif->rxqcqs[i];
+               if (rxq->flags & IONIC_QCQ_F_INITED)
+                       (void)ionic_dev_rx_queue_stop(lif->eth_dev, i);
+       }
+
+       for (i = 0; i < lif->ntxqcqs; i++) {
+               struct ionic_qcq *txq = lif->txqcqs[i];
+               if (txq->flags & IONIC_QCQ_F_INITED)
+                       (void)ionic_dev_tx_queue_stop(lif->eth_dev, i);
+       }
 }
 
 void
@@ -81,7 +93,7 @@ ionic_lif_reset(struct ionic_lif *lif)
 
        IONIC_PRINT_CALL();
 
-       ionic_dev_cmd_lif_reset(idev, lif->index);
+       ionic_dev_cmd_lif_reset(idev);
        err = ionic_dev_cmd_wait_check(idev, IONIC_DEVCMD_TIMEOUT);
        if (err)
                IONIC_PRINT(WARNING, "Failed to reset %s", lif->name);
@@ -438,7 +450,6 @@ ionic_lif_rx_mode(struct ionic_lif *lif, uint32_t rx_mode)
                .pending_work = true,
                .cmd.rx_mode_set = {
                        .opcode = IONIC_CMD_RX_MODE_SET,
-                       .lif_index = lif->index,
                        .rx_mode = rx_mode,
                },
        };
@@ -530,7 +541,6 @@ ionic_lif_change_mtu(struct ionic_lif *lif, int new_mtu)
                .pending_work = true,
                .cmd.lif_setattr = {
                        .opcode = IONIC_CMD_LIF_SETATTR,
-                       .index = lif->index,
                        .attr = IONIC_LIF_ATTR_MTU,
                        .mtu = new_mtu,
                },
@@ -824,7 +834,6 @@ ionic_lif_alloc(struct ionic_lif *lif)
 {
        struct ionic_adapter *adapter = lif->adapter;
        uint32_t socket_id = rte_socket_id();
-       int dbpage_num;
        int err;
 
        /*
@@ -840,9 +849,7 @@ ionic_lif_alloc(struct ionic_lif *lif)
        rte_spinlock_init(&lif->adminq_lock);
        rte_spinlock_init(&lif->adminq_service_lock);
 
-       dbpage_num = ionic_db_page_num(lif, 0);
-
-       lif->kern_dbpage = ionic_bus_map_dbpage(adapter, dbpage_num);
+       lif->kern_dbpage = ionic_bus_map_dbpage(adapter, 0);
        if (!lif->kern_dbpage) {
                IONIC_PRINT(ERR, "Cannot map dbpage, aborting");
                return -ENOMEM;
@@ -927,6 +934,21 @@ ionic_lif_free(struct ionic_lif *lif)
        }
 }
 
+void
+ionic_lif_free_queues(struct ionic_lif *lif)
+{
+       uint32_t i;
+
+       for (i = 0; i < lif->ntxqcqs; i++) {
+               ionic_dev_tx_queue_release(lif->eth_dev->data->tx_queues[i]);
+               lif->eth_dev->data->tx_queues[i] = NULL;
+       }
+       for (i = 0; i < lif->nrxqcqs; i++) {
+               ionic_dev_rx_queue_release(lif->eth_dev->data->rx_queues[i]);
+               lif->eth_dev->data->rx_queues[i] = NULL;
+       }
+}
+
 int
 ionic_lif_rss_config(struct ionic_lif *lif,
                const uint16_t types, const uint8_t *key, const uint32_t *indir)
@@ -1090,14 +1112,32 @@ ionic_link_status_check(struct ionic_lif *lif)
                return;
 
        if (link_up) {
-               IONIC_PRINT(DEBUG, "Link up - %d Gbps",
-                       lif->info->status.link_speed);
                adapter->link_speed = lif->info->status.link_speed;
+               IONIC_PRINT(DEBUG, "Link up - %d Gbps",
+                       adapter->link_speed);
        } else {
                IONIC_PRINT(DEBUG, "Link down");
        }
 
        adapter->link_up = link_up;
+       ionic_dev_link_update(lif->eth_dev, 0);
+}
+
+static void
+ionic_lif_handle_fw_down(struct ionic_lif *lif)
+{
+       if (lif->state & IONIC_LIF_F_FW_RESET)
+               return;
+
+       lif->state |= IONIC_LIF_F_FW_RESET;
+
+       if (lif->state & IONIC_LIF_F_UP) {
+               IONIC_PRINT(NOTICE,
+                       "Surprise FW stop, stopping %s\n", lif->name);
+               ionic_lif_stop(lif);
+       }
+
+       IONIC_PRINT(NOTICE, "FW down, %s stopped", lif->name);
 }
 
 static bool
@@ -1119,14 +1159,27 @@ ionic_notifyq_cb(struct ionic_cq *cq, uint32_t cq_desc_index, void *cb_arg)
        switch (cq_desc->event.ecode) {
        case IONIC_EVENT_LINK_CHANGE:
                IONIC_PRINT(DEBUG,
-                       "Notifyq IONIC_EVENT_LINK_CHANGE eid=%jd link_status=%d link_speed=%d",
+                       "Notifyq IONIC_EVENT_LINK_CHANGE %s "
+                       "eid=%jd link_status=%d link_speed=%d",
+                       lif->name,
                        cq_desc->event.eid,
                        cq_desc->link_change.link_status,
                        cq_desc->link_change.link_speed);
 
                lif->state |= IONIC_LIF_F_LINK_CHECK_NEEDED;
+               break;
 
+       case IONIC_EVENT_RESET:
+               IONIC_PRINT(NOTICE,
+                       "Notifyq IONIC_EVENT_RESET %s "
+                       "eid=%jd, reset_code=%d state=%d",
+                       lif->name,
+                       cq_desc->event.eid,
+                       cq_desc->reset.reset_code,
+                       cq_desc->reset.state);
+               ionic_lif_handle_fw_down(lif);
                break;
+
        default:
                IONIC_PRINT(WARNING, "Notifyq bad event ecode=%d eid=%jd",
                        cq_desc->event.ecode, cq_desc->event.eid);
@@ -1174,7 +1227,7 @@ ionic_lif_adminq_init(struct ionic_lif *lif)
        struct ionic_q_init_comp comp;
        int err;
 
-       ionic_dev_cmd_adminq_init(idev, qcq, lif->index, qcq->intr.index);
+       ionic_dev_cmd_adminq_init(idev, qcq, qcq->intr.index);
        err = ionic_dev_cmd_wait_check(idev, IONIC_DEVCMD_TIMEOUT);
        if (err)
                return err;
@@ -1210,7 +1263,6 @@ ionic_lif_notifyq_init(struct ionic_lif *lif)
                .pending_work = true,
                .cmd.q_init = {
                        .opcode = IONIC_CMD_Q_INIT,
-                       .lif_index = lif->index,
                        .type = q->type,
                        .index = q->index,
                        .flags = (IONIC_QINIT_F_IRQ | IONIC_QINIT_F_ENA),
@@ -1256,7 +1308,6 @@ ionic_lif_set_features(struct ionic_lif *lif)
                .pending_work = true,
                .cmd.lif_setattr = {
                        .opcode = IONIC_CMD_LIF_SETATTR,
-                       .index = lif->index,
                        .attr = IONIC_LIF_ATTR_FEATURES,
                        .features = lif->features,
                },
@@ -1318,10 +1369,9 @@ ionic_lif_txq_init(struct ionic_qcq *qcq)
                .pending_work = true,
                .cmd.q_init = {
                        .opcode = IONIC_CMD_Q_INIT,
-                       .lif_index = lif->index,
                        .type = q->type,
                        .index = q->index,
-                       .flags = IONIC_QINIT_F_SG,
+                       .flags = IONIC_QINIT_F_SG | IONIC_QINIT_F_ENA,
                        .intr_index = cq->bound_intr->index,
                        .ring_size = rte_log2_u32(q->num_descs),
                        .ring_base = q->base_pa,
@@ -1365,10 +1415,9 @@ ionic_lif_rxq_init(struct ionic_qcq *qcq)
                .pending_work = true,
                .cmd.q_init = {
                        .opcode = IONIC_CMD_Q_INIT,
-                       .lif_index = lif->index,
                        .type = q->type,
                        .index = q->index,
-                       .flags = IONIC_QINIT_F_SG,
+                       .flags = IONIC_QINIT_F_SG | IONIC_QINIT_F_ENA,
                        .intr_index = cq->bound_intr->index,
                        .ring_size = rte_log2_u32(q->num_descs),
                        .ring_base = q->base_pa,
@@ -1409,7 +1458,6 @@ ionic_station_set(struct ionic_lif *lif)
                .pending_work = true,
                .cmd.lif_getattr = {
                        .opcode = IONIC_CMD_LIF_GETATTR,
-                       .index = lif->index,
                        .attr = IONIC_LIF_ATTR_MAC,
                },
        };
@@ -1421,24 +1469,8 @@ ionic_station_set(struct ionic_lif *lif)
        if (err)
                return err;
 
-       if (!rte_is_zero_ether_addr((struct rte_ether_addr *)
-                       lif->mac_addr)) {
-               IONIC_PRINT(INFO, "deleting station MAC addr");
-
-               ionic_lif_addr_del(lif, lif->mac_addr);
-       }
-
        memcpy(lif->mac_addr, ctx.comp.lif_getattr.mac, RTE_ETHER_ADDR_LEN);
 
-       if (rte_is_zero_ether_addr((struct rte_ether_addr *)lif->mac_addr)) {
-               IONIC_PRINT(NOTICE, "empty MAC addr (VF?)");
-               return 0;
-       }
-
-       IONIC_PRINT(DEBUG, "adding station MAC addr");
-
-       ionic_lif_addr_add(lif, lif->mac_addr);
-
        return 0;
 }
 
@@ -1449,7 +1481,6 @@ ionic_lif_set_name(struct ionic_lif *lif)
                .pending_work = true,
                .cmd.lif_setattr = {
                        .opcode = IONIC_CMD_LIF_SETATTR,
-                       .index = lif->index,
                        .attr = IONIC_LIF_ATTR_NAME,
                },
        };
@@ -1469,7 +1500,7 @@ ionic_lif_init(struct ionic_lif *lif)
 
        memset(&lif->stats_base, 0, sizeof(lif->stats_base));
 
-       ionic_dev_cmd_lif_init(idev, lif->index, lif->info_pa);
+       ionic_dev_cmd_lif_init(idev, lif->info_pa);
        err = ionic_dev_cmd_wait_check(idev, IONIC_DEVCMD_TIMEOUT);
        ionic_dev_cmd_comp(idev, &comp);
        if (err)
@@ -1485,18 +1516,11 @@ ionic_lif_init(struct ionic_lif *lif)
        if (err)
                goto err_out_adminq_deinit;
 
-       lif->features =
-                 IONIC_ETH_HW_VLAN_TX_TAG
-               | IONIC_ETH_HW_VLAN_RX_STRIP
-               | IONIC_ETH_HW_VLAN_RX_FILTER
-               | IONIC_ETH_HW_RX_HASH
-               | IONIC_ETH_HW_TX_SG
-               | IONIC_ETH_HW_RX_SG
-               | IONIC_ETH_HW_TX_CSUM
-               | IONIC_ETH_HW_RX_CSUM
-               | IONIC_ETH_HW_TSO
-               | IONIC_ETH_HW_TSO_IPV6
-               | IONIC_ETH_HW_TSO_ECN;
+       /*
+        * Configure initial feature set
+        * This will be updated later by the dev_configure() step
+        */
+       lif->features = IONIC_ETH_HW_RX_HASH | IONIC_ETH_HW_VLAN_RX_FILTER;
 
        err = ionic_lif_set_features(lif);
        if (err)
@@ -1542,9 +1566,31 @@ ionic_lif_deinit(struct ionic_lif *lif)
        lif->state &= ~IONIC_LIF_F_INITED;
 }
 
-int
+void
+ionic_lif_configure_vlan_offload(struct ionic_lif *lif, int mask)
+{
+       struct rte_eth_dev *eth_dev = lif->eth_dev;
+       struct rte_eth_rxmode *rxmode = &eth_dev->data->dev_conf.rxmode;
+
+       /*
+        * IONIC_ETH_HW_VLAN_RX_FILTER cannot be turned off, so
+        * set DEV_RX_OFFLOAD_VLAN_FILTER and ignore ETH_VLAN_FILTER_MASK
+        */
+       rxmode->offloads |= DEV_RX_OFFLOAD_VLAN_FILTER;
+
+       if (mask & ETH_VLAN_STRIP_MASK) {
+               if (rxmode->offloads & DEV_RX_OFFLOAD_VLAN_STRIP)
+                       lif->features |= IONIC_ETH_HW_VLAN_RX_STRIP;
+               else
+                       lif->features &= ~IONIC_ETH_HW_VLAN_RX_STRIP;
+       }
+}
+
+void
 ionic_lif_configure(struct ionic_lif *lif)
 {
+       struct rte_eth_rxmode *rxmode = &lif->eth_dev->data->dev_conf.rxmode;
+       struct rte_eth_txmode *txmode = &lif->eth_dev->data->dev_conf.txmode;
        struct ionic_identity *ident = &lif->adapter->ident;
        uint32_t ntxqs_per_lif =
                ident->lif.eth.config.queue_count[IONIC_QTYPE_TXQ];
@@ -1567,7 +1613,64 @@ ionic_lif_configure(struct ionic_lif *lif)
        lif->nrxqcqs = nrxqs_per_lif;
        lif->ntxqcqs = ntxqs_per_lif;
 
-       return 0;
+       /* Update the LIF configuration based on the eth_dev */
+
+       /*
+        * NB: While it is true that RSS_HASH is always enabled on ionic,
+        *     setting this flag unconditionally causes problems in DTS.
+        * rxmode->offloads |= DEV_RX_OFFLOAD_RSS_HASH;
+        */
+
+       /* RX per-port */
+
+       if (rxmode->offloads & DEV_RX_OFFLOAD_IPV4_CKSUM ||
+           rxmode->offloads & DEV_RX_OFFLOAD_UDP_CKSUM ||
+           rxmode->offloads & DEV_RX_OFFLOAD_TCP_CKSUM)
+               lif->features |= IONIC_ETH_HW_RX_CSUM;
+       else
+               lif->features &= ~IONIC_ETH_HW_RX_CSUM;
+
+       if (rxmode->offloads & DEV_RX_OFFLOAD_SCATTER) {
+               lif->features |= IONIC_ETH_HW_RX_SG;
+               lif->eth_dev->data->scattered_rx = 1;
+       } else {
+               lif->features &= ~IONIC_ETH_HW_RX_SG;
+               lif->eth_dev->data->scattered_rx = 0;
+       }
+
+       /* Covers VLAN_STRIP */
+       ionic_lif_configure_vlan_offload(lif, ETH_VLAN_STRIP_MASK);
+
+       /* TX per-port */
+
+       if (txmode->offloads & DEV_TX_OFFLOAD_IPV4_CKSUM ||
+           txmode->offloads & DEV_TX_OFFLOAD_UDP_CKSUM ||
+           txmode->offloads & DEV_TX_OFFLOAD_TCP_CKSUM ||
+           txmode->offloads & DEV_TX_OFFLOAD_OUTER_IPV4_CKSUM ||
+           txmode->offloads & DEV_TX_OFFLOAD_OUTER_UDP_CKSUM)
+               lif->features |= IONIC_ETH_HW_TX_CSUM;
+       else
+               lif->features &= ~IONIC_ETH_HW_TX_CSUM;
+
+       if (txmode->offloads & DEV_TX_OFFLOAD_VLAN_INSERT)
+               lif->features |= IONIC_ETH_HW_VLAN_TX_TAG;
+       else
+               lif->features &= ~IONIC_ETH_HW_VLAN_TX_TAG;
+
+       if (txmode->offloads & DEV_TX_OFFLOAD_MULTI_SEGS)
+               lif->features |= IONIC_ETH_HW_TX_SG;
+       else
+               lif->features &= ~IONIC_ETH_HW_TX_SG;
+
+       if (txmode->offloads & DEV_TX_OFFLOAD_TCP_TSO) {
+               lif->features |= IONIC_ETH_HW_TSO;
+               lif->features |= IONIC_ETH_HW_TSO_IPV6;
+               lif->features |= IONIC_ETH_HW_TSO_ECN;
+       } else {
+               lif->features &= ~IONIC_ETH_HW_TSO;
+               lif->features &= ~IONIC_ETH_HW_TSO_IPV6;
+               lif->features &= ~IONIC_ETH_HW_TSO_ECN;
+       }
 }
 
 int
@@ -1616,9 +1719,10 @@ ionic_lif_start(struct ionic_lif *lif)
                }
        }
 
-       ionic_link_status_check(lif);
-
        /* Carrier ON here */
+       lif->state |= IONIC_LIF_F_UP;
+
+       ionic_link_status_check(lif);
 
        return 0;
 }
@@ -1672,7 +1776,6 @@ int
 ionic_lifs_size(struct ionic_adapter *adapter)
 {
        struct ionic_identity *ident = &adapter->ident;
-       uint32_t nlifs = ident->dev.nlifs;
        uint32_t nintrs, dev_nintrs = ident->dev.nintrs;
 
        adapter->max_ntxqs_per_lif =
@@ -1680,7 +1783,7 @@ ionic_lifs_size(struct ionic_adapter *adapter)
        adapter->max_nrxqs_per_lif =
                ident->lif.eth.config.queue_count[IONIC_QTYPE_RXQ];
 
-       nintrs = nlifs * 1 /* notifyq */;
+       nintrs = 1 /* notifyq */;
 
        if (nintrs > dev_nintrs) {
                IONIC_PRINT(ERR,