ethdev: add return value to stats get dev op
[dpdk.git] / drivers / net / dpaa2 / dpaa2_ethdev.c
index d5fa644..1ac607c 100644 (file)
 #include <mc/fsl_dpmng.h>
 #include "dpaa2_ethdev.h"
 
+struct rte_dpaa2_xstats_name_off {
+       char name[RTE_ETH_XSTATS_NAME_SIZE];
+       uint8_t page_id; /* dpni statistics page id */
+       uint8_t stats_id; /* stats id in the given page */
+};
+
+static const struct rte_dpaa2_xstats_name_off dpaa2_xstats_strings[] = {
+       {"ingress_multicast_frames", 0, 2},
+       {"ingress_multicast_bytes", 0, 3},
+       {"ingress_broadcast_frames", 0, 4},
+       {"ingress_broadcast_bytes", 0, 5},
+       {"egress_multicast_frames", 1, 2},
+       {"egress_multicast_bytes", 1, 3},
+       {"egress_broadcast_frames", 1, 4},
+       {"egress_broadcast_bytes", 1, 5},
+       {"ingress_filtered_frames", 2, 0},
+       {"ingress_discarded_frames", 2, 1},
+       {"ingress_nobuffer_discards", 2, 2},
+       {"egress_discarded_frames", 2, 3},
+       {"egress_confirmed_frames", 2, 4},
+};
+
 static struct rte_dpaa2_driver rte_dpaa2_pmd;
 static int dpaa2_dev_uninit(struct rte_eth_dev *eth_dev);
 static int dpaa2_dev_link_update(struct rte_eth_dev *dev,
@@ -160,6 +182,12 @@ dpaa2_vlan_offload_set(struct rte_eth_dev *dev, int mask)
                        RTE_LOG(ERR, PMD, "Unable to set vlan filter = %d\n",
                                ret);
        }
+
+       if (mask & ETH_VLAN_EXTEND_MASK) {
+               if (dev->data->dev_conf.rxmode.hw_vlan_extend)
+                       RTE_LOG(INFO, PMD,
+                               "VLAN extend offload not supported\n");
+       }
 }
 
 static int
@@ -306,8 +334,10 @@ fail:
 static int
 dpaa2_eth_dev_configure(struct rte_eth_dev *dev)
 {
-       struct rte_eth_dev_data *data = dev->data;
-       struct rte_eth_conf *eth_conf = &data->dev_conf;
+       struct dpaa2_dev_priv *priv = dev->data->dev_private;
+       struct fsl_mc_io *dpni = priv->hw;
+       struct rte_eth_conf *eth_conf = &dev->data->dev_conf;
+       int rx_ip_csum_offload = false;
        int ret;
 
        PMD_INIT_FUNC_TRACE();
@@ -326,18 +356,7 @@ dpaa2_eth_dev_configure(struct rte_eth_dev *dev)
                }
        }
 
-       /* Check for correct configuration */
-       if (eth_conf->rxmode.mq_mode != ETH_MQ_RX_RSS &&
-           data->nb_rx_queues > 1) {
-               PMD_INIT_LOG(ERR, "Distribution is not enabled, "
-                           "but Rx queues more than 1\n");
-               return -1;
-       }
-
        if (eth_conf->rxmode.mq_mode == ETH_MQ_RX_RSS) {
-               /* Return in case number of Rx queues is 1 */
-               if (data->nb_rx_queues == 1)
-                       return 0;
                ret = dpaa2_setup_flow_dist(dev,
                                eth_conf->rx_adv_conf.rss_conf.rss_hf);
                if (ret) {
@@ -347,6 +366,37 @@ dpaa2_eth_dev_configure(struct rte_eth_dev *dev)
                }
        }
 
+       if (eth_conf->rxmode.hw_ip_checksum)
+               rx_ip_csum_offload = true;
+
+       ret = dpni_set_offload(dpni, CMD_PRI_LOW, priv->token,
+                              DPNI_OFF_RX_L3_CSUM, rx_ip_csum_offload);
+       if (ret) {
+               PMD_INIT_LOG(ERR, "Error to set RX l3 csum:Error = %d\n", ret);
+               return ret;
+       }
+
+       ret = dpni_set_offload(dpni, CMD_PRI_LOW, priv->token,
+                              DPNI_OFF_RX_L4_CSUM, rx_ip_csum_offload);
+       if (ret) {
+               PMD_INIT_LOG(ERR, "Error to get RX l4 csum:Error = %d\n", ret);
+               return ret;
+       }
+
+       ret = dpni_set_offload(dpni, CMD_PRI_LOW, priv->token,
+                              DPNI_OFF_TX_L3_CSUM, true);
+       if (ret) {
+               PMD_INIT_LOG(ERR, "Error to set TX l3 csum:Error = %d\n", ret);
+               return ret;
+       }
+
+       ret = dpni_set_offload(dpni, CMD_PRI_LOW, priv->token,
+                              DPNI_OFF_TX_L4_CSUM, true);
+       if (ret) {
+               PMD_INIT_LOG(ERR, "Error to get TX l4 csum:Error = %d\n", ret);
+               return ret;
+       }
+
        /* update the current status */
        dpaa2_dev_link_update(dev, 0);
 
@@ -376,8 +426,8 @@ dpaa2_dev_rx_queue_setup(struct rte_eth_dev *dev,
 
        PMD_INIT_FUNC_TRACE();
 
-       PMD_INIT_LOG(DEBUG, "dev =%p, queue =%d, pool = %p, conf =%p",
-                    dev, rx_queue_id, mb_pool, rx_conf);
+       PMD_DRV_LOG(DEBUG, "dev =%p, queue =%d, pool = %p, conf =%p",
+                   dev, rx_queue_id, mb_pool, rx_conf);
 
        if (!priv->bp_list || priv->bp_list->mp != mb_pool) {
                bpid = mempool_to_bpid(mb_pool);
@@ -426,8 +476,8 @@ dpaa2_dev_rx_queue_setup(struct rte_eth_dev *dev,
                taildrop.threshold = CONG_THRESHOLD_RX_Q;
                taildrop.units = DPNI_CONGESTION_UNIT_BYTES;
                taildrop.oal = CONG_RX_OAL;
-               PMD_INIT_LOG(DEBUG, "Enabling Early Drop on queue = %d",
-                            rx_queue_id);
+               PMD_DRV_LOG(DEBUG, "Enabling Early Drop on queue = %d",
+                           rx_queue_id);
                ret = dpni_set_taildrop(dpni, CMD_PRI_LOW, priv->token,
                                        DPNI_CP_QUEUE, DPNI_QUEUE_RX,
                                        dpaa2_q->tc_index, flow_id, &taildrop);
@@ -690,34 +740,6 @@ dpaa2_dev_start(struct rte_eth_dev *dev)
                dpaa2_q->fqid = qid.fqid;
        }
 
-       ret = dpni_set_offload(dpni, CMD_PRI_LOW, priv->token,
-                              DPNI_OFF_RX_L3_CSUM, true);
-       if (ret) {
-               PMD_INIT_LOG(ERR, "Error to set RX l3 csum:Error = %d\n", ret);
-               return ret;
-       }
-
-       ret = dpni_set_offload(dpni, CMD_PRI_LOW, priv->token,
-                              DPNI_OFF_RX_L4_CSUM, true);
-       if (ret) {
-               PMD_INIT_LOG(ERR, "Error to get RX l4 csum:Error = %d\n", ret);
-               return ret;
-       }
-
-       ret = dpni_set_offload(dpni, CMD_PRI_LOW, priv->token,
-                              DPNI_OFF_TX_L3_CSUM, true);
-       if (ret) {
-               PMD_INIT_LOG(ERR, "Error to set TX l3 csum:Error = %d\n", ret);
-               return ret;
-       }
-
-       ret = dpni_set_offload(dpni, CMD_PRI_LOW, priv->token,
-                              DPNI_OFF_TX_L4_CSUM, true);
-       if (ret) {
-               PMD_INIT_LOG(ERR, "Error to get TX l4 csum:Error = %d\n", ret);
-               return ret;
-       }
-
        /*checksum errors, send them to normal path and set it in annotation */
        err_cfg.errors = DPNI_ERROR_L3CE | DPNI_ERROR_L4CE;
 
@@ -961,7 +983,7 @@ dpaa2_dev_mtu_set(struct rte_eth_dev *dev, uint16_t mtu)
                PMD_DRV_LOG(ERR, "setting the max frame length failed");
                return -1;
        }
-       PMD_DRV_LOG(INFO, "MTU is configured %d for the device\n", mtu);
+       PMD_DRV_LOG(INFO, "MTU is configured %d for the device", mtu);
        return 0;
 }
 
@@ -1039,7 +1061,7 @@ dpaa2_dev_set_mac_addr(struct rte_eth_dev *dev,
                        "error: Setting the MAC ADDR failed %d\n", ret);
 }
 static
-void dpaa2_dev_stats_get(struct rte_eth_dev *dev,
+int dpaa2_dev_stats_get(struct rte_eth_dev *dev,
                         struct rte_eth_stats *stats)
 {
        struct dpaa2_dev_priv *priv = dev->data->dev_private;
@@ -1054,12 +1076,12 @@ void dpaa2_dev_stats_get(struct rte_eth_dev *dev,
 
        if (!dpni) {
                RTE_LOG(ERR, PMD, "dpni is NULL\n");
-               return;
+               return -EINVAL;
        }
 
        if (!stats) {
                RTE_LOG(ERR, PMD, "stats is NULL\n");
-               return;
+               return -EINVAL;
        }
 
        /*Get Counters from page_0*/
@@ -1094,15 +1116,158 @@ void dpaa2_dev_stats_get(struct rte_eth_dev *dev,
        stats->oerrors = value.page_2.egress_discarded_frames;
        stats->imissed = value.page_2.ingress_nobuffer_discards;
 
-       return;
+       return 0;
 
 err:
        RTE_LOG(ERR, PMD, "Operation not completed:Error Code = %d\n", retcode);
-       return;
+       return retcode;
 };
 
-static
-void dpaa2_dev_stats_reset(struct rte_eth_dev *dev)
+static int
+dpaa2_dev_xstats_get(struct rte_eth_dev *dev, struct rte_eth_xstat *xstats,
+                    unsigned int n)
+{
+       struct dpaa2_dev_priv *priv = dev->data->dev_private;
+       struct fsl_mc_io *dpni = (struct fsl_mc_io *)priv->hw;
+       int32_t  retcode;
+       union dpni_statistics value[3] = {};
+       unsigned int i = 0, num = RTE_DIM(dpaa2_xstats_strings);
+
+       if (xstats == NULL)
+               return 0;
+
+       if (n < num)
+               return num;
+
+       /* Get Counters from page_0*/
+       retcode = dpni_get_statistics(dpni, CMD_PRI_LOW, priv->token,
+                                     0, 0, &value[0]);
+       if (retcode)
+               goto err;
+
+       /* Get Counters from page_1*/
+       retcode = dpni_get_statistics(dpni, CMD_PRI_LOW, priv->token,
+                                     1, 0, &value[1]);
+       if (retcode)
+               goto err;
+
+       /* Get Counters from page_2*/
+       retcode = dpni_get_statistics(dpni, CMD_PRI_LOW, priv->token,
+                                     2, 0, &value[2]);
+       if (retcode)
+               goto err;
+
+       for (i = 0; i < num; i++) {
+               xstats[i].id = i;
+               xstats[i].value = value[dpaa2_xstats_strings[i].page_id].
+                       raw.counter[dpaa2_xstats_strings[i].stats_id];
+       }
+       return i;
+err:
+       RTE_LOG(ERR, PMD, "Error in obtaining extended stats (%d)\n", retcode);
+       return retcode;
+}
+
+static int
+dpaa2_xstats_get_names(__rte_unused struct rte_eth_dev *dev,
+                      struct rte_eth_xstat_name *xstats_names,
+                      __rte_unused unsigned int limit)
+{
+       unsigned int i, stat_cnt = RTE_DIM(dpaa2_xstats_strings);
+
+       if (xstats_names != NULL)
+               for (i = 0; i < stat_cnt; i++)
+                       snprintf(xstats_names[i].name,
+                                sizeof(xstats_names[i].name),
+                                "%s",
+                                dpaa2_xstats_strings[i].name);
+
+       return stat_cnt;
+}
+
+static int
+dpaa2_xstats_get_by_id(struct rte_eth_dev *dev, const uint64_t *ids,
+                      uint64_t *values, unsigned int n)
+{
+       unsigned int i, stat_cnt = RTE_DIM(dpaa2_xstats_strings);
+       uint64_t values_copy[stat_cnt];
+
+       if (!ids) {
+               struct dpaa2_dev_priv *priv = dev->data->dev_private;
+               struct fsl_mc_io *dpni = (struct fsl_mc_io *)priv->hw;
+               int32_t  retcode;
+               union dpni_statistics value[3] = {};
+
+               if (n < stat_cnt)
+                       return stat_cnt;
+
+               if (!values)
+                       return 0;
+
+               /* Get Counters from page_0*/
+               retcode = dpni_get_statistics(dpni, CMD_PRI_LOW, priv->token,
+                                             0, 0, &value[0]);
+               if (retcode)
+                       return 0;
+
+               /* Get Counters from page_1*/
+               retcode = dpni_get_statistics(dpni, CMD_PRI_LOW, priv->token,
+                                             1, 0, &value[1]);
+               if (retcode)
+                       return 0;
+
+               /* Get Counters from page_2*/
+               retcode = dpni_get_statistics(dpni, CMD_PRI_LOW, priv->token,
+                                             2, 0, &value[2]);
+               if (retcode)
+                       return 0;
+
+               for (i = 0; i < stat_cnt; i++) {
+                       values[i] = value[dpaa2_xstats_strings[i].page_id].
+                               raw.counter[dpaa2_xstats_strings[i].stats_id];
+               }
+               return stat_cnt;
+       }
+
+       dpaa2_xstats_get_by_id(dev, NULL, values_copy, stat_cnt);
+
+       for (i = 0; i < n; i++) {
+               if (ids[i] >= stat_cnt) {
+                       PMD_INIT_LOG(ERR, "id value isn't valid");
+                       return -1;
+               }
+               values[i] = values_copy[ids[i]];
+       }
+       return n;
+}
+
+static int
+dpaa2_xstats_get_names_by_id(
+       struct rte_eth_dev *dev,
+       struct rte_eth_xstat_name *xstats_names,
+       const uint64_t *ids,
+       unsigned int limit)
+{
+       unsigned int i, stat_cnt = RTE_DIM(dpaa2_xstats_strings);
+       struct rte_eth_xstat_name xstats_names_copy[stat_cnt];
+
+       if (!ids)
+               return dpaa2_xstats_get_names(dev, xstats_names, limit);
+
+       dpaa2_xstats_get_names(dev, xstats_names_copy, limit);
+
+       for (i = 0; i < limit; i++) {
+               if (ids[i] >= stat_cnt) {
+                       PMD_INIT_LOG(ERR, "id value isn't valid");
+                       return -1;
+               }
+               strcpy(xstats_names[i].name, xstats_names_copy[ids[i]].name);
+       }
+       return limit;
+}
+
+static void
+dpaa2_dev_stats_reset(struct rte_eth_dev *dev)
 {
        struct dpaa2_dev_priv *priv = dev->data->dev_private;
        struct fsl_mc_io *dpni = (struct fsl_mc_io *)priv->hw;
@@ -1429,6 +1594,46 @@ dpaa2_flow_ctrl_set(struct rte_eth_dev *dev, struct rte_eth_fc_conf *fc_conf)
        return ret;
 }
 
+static int
+dpaa2_dev_rss_hash_update(struct rte_eth_dev *dev,
+                         struct rte_eth_rss_conf *rss_conf)
+{
+       struct rte_eth_dev_data *data = dev->data;
+       struct rte_eth_conf *eth_conf = &data->dev_conf;
+       int ret;
+
+       PMD_INIT_FUNC_TRACE();
+
+       if (rss_conf->rss_hf) {
+               ret = dpaa2_setup_flow_dist(dev, rss_conf->rss_hf);
+               if (ret) {
+                       PMD_INIT_LOG(ERR, "unable to set flow dist");
+                       return ret;
+               }
+       } else {
+               ret = dpaa2_remove_flow_dist(dev, 0);
+               if (ret) {
+                       PMD_INIT_LOG(ERR, "unable to remove flow dist");
+                       return ret;
+               }
+       }
+       eth_conf->rx_adv_conf.rss_conf.rss_hf = rss_conf->rss_hf;
+       return 0;
+}
+
+static int
+dpaa2_dev_rss_hash_conf_get(struct rte_eth_dev *dev,
+                           struct rte_eth_rss_conf *rss_conf)
+{
+       struct rte_eth_dev_data *data = dev->data;
+       struct rte_eth_conf *eth_conf = &data->dev_conf;
+
+       /* dpaa2 does not support rss_key, so length should be 0*/
+       rss_conf->rss_key_len = 0;
+       rss_conf->rss_hf = eth_conf->rx_adv_conf.rss_conf.rss_hf;
+       return 0;
+}
+
 static struct eth_dev_ops dpaa2_ethdev_ops = {
        .dev_configure    = dpaa2_eth_dev_configure,
        .dev_start            = dpaa2_dev_start,
@@ -1442,7 +1647,12 @@ static struct eth_dev_ops dpaa2_ethdev_ops = {
        .dev_set_link_down    = dpaa2_dev_set_link_down,
        .link_update       = dpaa2_dev_link_update,
        .stats_get             = dpaa2_dev_stats_get,
+       .xstats_get            = dpaa2_dev_xstats_get,
+       .xstats_get_by_id     = dpaa2_xstats_get_by_id,
+       .xstats_get_names_by_id = dpaa2_xstats_get_names_by_id,
+       .xstats_get_names      = dpaa2_xstats_get_names,
        .stats_reset       = dpaa2_dev_stats_reset,
+       .xstats_reset         = dpaa2_dev_stats_reset,
        .fw_version_get    = dpaa2_fw_version_get,
        .dev_infos_get     = dpaa2_dev_info_get,
        .dev_supported_ptypes_get = dpaa2_supported_ptypes_get,
@@ -1458,6 +1668,8 @@ static struct eth_dev_ops dpaa2_ethdev_ops = {
        .mac_addr_add         = dpaa2_dev_add_mac_addr,
        .mac_addr_remove      = dpaa2_dev_remove_mac_addr,
        .mac_addr_set         = dpaa2_dev_set_mac_addr,
+       .rss_hash_update      = dpaa2_dev_rss_hash_update,
+       .rss_hash_conf_get    = dpaa2_dev_rss_hash_conf_get,
 };
 
 static int
@@ -1526,7 +1738,7 @@ dpaa2_dev_init(struct rte_eth_dev *eth_dev)
        priv->nb_tx_queues = attr.num_tx_tcs;
 
        PMD_DRV_LOG(DEBUG, "RX-TC= %d, nb_rx_queues= %d, nb_tx_queues=%d",
-                   priv->num_tc, priv->nb_rx_queues, priv->nb_tx_queues);
+                   priv->num_rx_tc, priv->nb_rx_queues, priv->nb_tx_queues);
 
        priv->hw = dpni_dev;
        priv->hw_id = hw_id;
@@ -1593,6 +1805,7 @@ dpaa2_dev_init(struct rte_eth_dev *eth_dev)
        eth_dev->tx_pkt_burst = dpaa2_dev_tx;
        rte_fslmc_vfio_dmamap();
 
+       RTE_LOG(INFO, PMD, "%s: netdev created\n", eth_dev->data->name);
        return 0;
 init_err:
        dpaa2_dev_uninit(eth_dev);
@@ -1653,6 +1866,7 @@ dpaa2_dev_uninit(struct rte_eth_dev *eth_dev)
        eth_dev->rx_pkt_burst = NULL;
        eth_dev->tx_pkt_burst = NULL;
 
+       RTE_LOG(INFO, PMD, "%s: netdev created\n", eth_dev->data->name);
        return 0;
 }