ethdev: change promiscuous callbacks to return status
[dpdk.git] / drivers / net / qede / qede_ethdev.c
index 308588c..4f324a6 100644 (file)
@@ -125,6 +125,8 @@ static const struct rte_qede_xstats_name_off qede_xstats_strings[] = {
                offsetof(struct ecore_eth_stats_common, mftag_filter_discards)},
        {"rx_mac_filter_discards",
                offsetof(struct ecore_eth_stats_common, mac_filter_discards)},
+       {"rx_gft_filter_drop",
+               offsetof(struct ecore_eth_stats_common, gft_filter_drop)},
        {"rx_hw_buffer_truncates",
                offsetof(struct ecore_eth_stats_common, brb_truncates)},
        {"rx_hw_buffer_discards",
@@ -1244,7 +1246,7 @@ static const struct rte_eth_desc_lim qede_tx_desc_lim = {
        .nb_mtu_seg_max = ETH_TX_MAX_BDS_PER_NON_LSO_PACKET
 };
 
-static void
+static int
 qede_dev_info_get(struct rte_eth_dev *eth_dev,
                  struct rte_eth_dev_info *dev_info)
 {
@@ -1328,6 +1330,8 @@ qede_dev_info_get(struct rte_eth_dev *eth_dev,
        if (link.adv_speed & NVM_CFG1_PORT_DRV_SPEED_CAPABILITY_MASK_BB_100G)
                speed_cap |= ETH_LINK_SPEED_100G;
        dev_info->speed_capa = speed_cap;
+
+       return 0;
 }
 
 /* return 0 means link status changed, -1 means not changed */
@@ -1376,33 +1380,39 @@ qede_link_update(struct rte_eth_dev *eth_dev, __rte_unused int wait_to_complete)
        return rte_eth_linkstatus_set(eth_dev, &link);
 }
 
-static void qede_promiscuous_enable(struct rte_eth_dev *eth_dev)
+static int qede_promiscuous_enable(struct rte_eth_dev *eth_dev)
 {
        struct qede_dev *qdev = eth_dev->data->dev_private;
        struct ecore_dev *edev = &qdev->edev;
        enum qed_filter_rx_mode_type type = QED_FILTER_RX_MODE_TYPE_PROMISC;
+       enum _ecore_status_t ecore_status;
 
        PMD_INIT_FUNC_TRACE(edev);
 
        if (rte_eth_allmulticast_get(eth_dev->data->port_id) == 1)
                type |= QED_FILTER_RX_MODE_TYPE_MULTI_PROMISC;
 
-       qed_configure_filter_rx_mode(eth_dev, type);
+       ecore_status = qed_configure_filter_rx_mode(eth_dev, type);
+
+       return ecore_status >= ECORE_SUCCESS ? 0 : -EAGAIN;
 }
 
-static void qede_promiscuous_disable(struct rte_eth_dev *eth_dev)
+static int qede_promiscuous_disable(struct rte_eth_dev *eth_dev)
 {
        struct qede_dev *qdev = eth_dev->data->dev_private;
        struct ecore_dev *edev = &qdev->edev;
+       enum _ecore_status_t ecore_status;
 
        PMD_INIT_FUNC_TRACE(edev);
 
        if (rte_eth_allmulticast_get(eth_dev->data->port_id) == 1)
-               qed_configure_filter_rx_mode(eth_dev,
+               ecore_status = qed_configure_filter_rx_mode(eth_dev,
                                QED_FILTER_RX_MODE_TYPE_MULTI_PROMISC);
        else
-               qed_configure_filter_rx_mode(eth_dev,
+               ecore_status = qed_configure_filter_rx_mode(eth_dev,
                                QED_FILTER_RX_MODE_TYPE_REGULAR);
+
+       return ecore_status >= ECORE_SUCCESS ? 0 : -EAGAIN;
 }
 
 static void qede_poll_sp_sb_cb(void *param)
@@ -1477,7 +1487,7 @@ qede_get_stats(struct rte_eth_dev *eth_dev, struct rte_eth_stats *eth_stats)
        struct qede_dev *qdev = eth_dev->data->dev_private;
        struct ecore_dev *edev = &qdev->edev;
        struct ecore_eth_stats stats;
-       unsigned int i = 0, j = 0, qid;
+       unsigned int i = 0, j = 0, qid, idx, hw_fn;
        unsigned int rxq_stat_cntrs, txq_stat_cntrs;
        struct qede_tx_queue *txq;
 
@@ -1525,32 +1535,47 @@ qede_get_stats(struct rte_eth_dev *eth_dev, struct rte_eth_stats *eth_stats)
                       " appropriately and retry.\n");
 
        for (qid = 0; qid < eth_dev->data->nb_rx_queues; qid++) {
-               eth_stats->q_ipackets[i] =
-                       *(uint64_t *)(
-                               ((char *)(qdev->fp_array[qid].rxq)) +
-                               offsetof(struct qede_rx_queue,
-                               rcv_pkts));
-               eth_stats->q_errors[i] =
-                       *(uint64_t *)(
-                               ((char *)(qdev->fp_array[qid].rxq)) +
-                               offsetof(struct qede_rx_queue,
-                               rx_hw_errors)) +
-                       *(uint64_t *)(
-                               ((char *)(qdev->fp_array[qid].rxq)) +
-                               offsetof(struct qede_rx_queue,
-                               rx_alloc_errors));
+               eth_stats->q_ipackets[i] = 0;
+               eth_stats->q_errors[i] = 0;
+
+               for_each_hwfn(edev, hw_fn) {
+                       idx = qid * edev->num_hwfns + hw_fn;
+
+                       eth_stats->q_ipackets[i] +=
+                               *(uint64_t *)
+                                       (((char *)(qdev->fp_array[idx].rxq)) +
+                                        offsetof(struct qede_rx_queue,
+                                        rcv_pkts));
+                       eth_stats->q_errors[i] +=
+                               *(uint64_t *)
+                                       (((char *)(qdev->fp_array[idx].rxq)) +
+                                        offsetof(struct qede_rx_queue,
+                                        rx_hw_errors)) +
+                               *(uint64_t *)
+                                       (((char *)(qdev->fp_array[idx].rxq)) +
+                                        offsetof(struct qede_rx_queue,
+                                        rx_alloc_errors));
+               }
+
                i++;
                if (i == rxq_stat_cntrs)
                        break;
        }
 
        for (qid = 0; qid < eth_dev->data->nb_tx_queues; qid++) {
-               txq = qdev->fp_array[qid].txq;
-               eth_stats->q_opackets[j] =
-                       *((uint64_t *)(uintptr_t)
-                               (((uint64_t)(uintptr_t)(txq)) +
-                                offsetof(struct qede_tx_queue,
-                                         xmit_pkts)));
+               eth_stats->q_opackets[j] = 0;
+
+               for_each_hwfn(edev, hw_fn) {
+                       idx = qid * edev->num_hwfns + hw_fn;
+
+                       txq = qdev->fp_array[idx].txq;
+                       eth_stats->q_opackets[j] +=
+                               *((uint64_t *)(uintptr_t)
+                                       (((uint64_t)(uintptr_t)(txq)) +
+                                        offsetof(struct qede_tx_queue,
+                                                 xmit_pkts)));
+               }
+
                j++;
                if (j == txq_stat_cntrs)
                        break;
@@ -1583,42 +1608,43 @@ qede_get_xstats_names(struct rte_eth_dev *dev,
        struct qede_dev *qdev = dev->data->dev_private;
        struct ecore_dev *edev = &qdev->edev;
        const unsigned int stat_cnt = qede_get_xstats_count(qdev);
-       unsigned int i, qid, stat_idx = 0;
-       unsigned int rxq_stat_cntrs;
+       unsigned int i, qid, hw_fn, stat_idx = 0;
+
+       if (xstats_names == NULL)
+               return stat_cnt;
 
-       if (xstats_names != NULL) {
-               for (i = 0; i < RTE_DIM(qede_xstats_strings); i++) {
+       for (i = 0; i < RTE_DIM(qede_xstats_strings); i++) {
+               strlcpy(xstats_names[stat_idx].name,
+                       qede_xstats_strings[i].name,
+                       sizeof(xstats_names[stat_idx].name));
+               stat_idx++;
+       }
+
+       if (ECORE_IS_BB(edev)) {
+               for (i = 0; i < RTE_DIM(qede_bb_xstats_strings); i++) {
                        strlcpy(xstats_names[stat_idx].name,
-                               qede_xstats_strings[i].name,
+                               qede_bb_xstats_strings[i].name,
                                sizeof(xstats_names[stat_idx].name));
                        stat_idx++;
                }
-
-               if (ECORE_IS_BB(edev)) {
-                       for (i = 0; i < RTE_DIM(qede_bb_xstats_strings); i++) {
-                               strlcpy(xstats_names[stat_idx].name,
-                                       qede_bb_xstats_strings[i].name,
-                                       sizeof(xstats_names[stat_idx].name));
-                               stat_idx++;
-                       }
-               } else {
-                       for (i = 0; i < RTE_DIM(qede_ah_xstats_strings); i++) {
-                               strlcpy(xstats_names[stat_idx].name,
-                                       qede_ah_xstats_strings[i].name,
-                                       sizeof(xstats_names[stat_idx].name));
-                               stat_idx++;
-                       }
+       } else {
+               for (i = 0; i < RTE_DIM(qede_ah_xstats_strings); i++) {
+                       strlcpy(xstats_names[stat_idx].name,
+                               qede_ah_xstats_strings[i].name,
+                               sizeof(xstats_names[stat_idx].name));
+                       stat_idx++;
                }
+       }
 
-               rxq_stat_cntrs = RTE_MIN(QEDE_RSS_COUNT(dev),
-                                        RTE_ETHDEV_QUEUE_STAT_CNTRS);
-               for (qid = 0; qid < rxq_stat_cntrs; qid++) {
+       for (qid = 0; qid < QEDE_RSS_COUNT(dev); qid++) {
+               for_each_hwfn(edev, hw_fn) {
                        for (i = 0; i < RTE_DIM(qede_rxq_xstats_strings); i++) {
                                snprintf(xstats_names[stat_idx].name,
-                                       sizeof(xstats_names[stat_idx].name),
-                                       "%.4s%d%s",
-                                       qede_rxq_xstats_strings[i].name, qid,
-                                       qede_rxq_xstats_strings[i].name + 4);
+                                        RTE_ETH_XSTATS_NAME_SIZE,
+                                        "%.4s%d.%d%s",
+                                        qede_rxq_xstats_strings[i].name,
+                                        hw_fn, qid,
+                                        qede_rxq_xstats_strings[i].name + 4);
                                stat_idx++;
                        }
                }
@@ -1635,8 +1661,7 @@ qede_get_xstats(struct rte_eth_dev *dev, struct rte_eth_xstat *xstats,
        struct ecore_dev *edev = &qdev->edev;
        struct ecore_eth_stats stats;
        const unsigned int num = qede_get_xstats_count(qdev);
-       unsigned int i, qid, stat_idx = 0;
-       unsigned int rxq_stat_cntrs;
+       unsigned int i, qid, hw_fn, fpidx, stat_idx = 0;
 
        if (n < num)
                return num;
@@ -1668,15 +1693,17 @@ qede_get_xstats(struct rte_eth_dev *dev, struct rte_eth_xstat *xstats,
                }
        }
 
-       rxq_stat_cntrs = RTE_MIN(QEDE_RSS_COUNT(dev),
-                                RTE_ETHDEV_QUEUE_STAT_CNTRS);
-       for (qid = 0; qid < rxq_stat_cntrs; qid++) {
-               for (i = 0; i < RTE_DIM(qede_rxq_xstats_strings); i++) {
-                       xstats[stat_idx].value = *(uint64_t *)
-                               (((char *)(qdev->fp_array[qid].rxq)) +
-                                qede_rxq_xstats_strings[i].offset);
-                       xstats[stat_idx].id = stat_idx;
-                       stat_idx++;
+       for (qid = 0; qid < dev->data->nb_rx_queues; qid++) {
+               for_each_hwfn(edev, hw_fn) {
+                       for (i = 0; i < RTE_DIM(qede_rxq_xstats_strings); i++) {
+                               fpidx = qid * edev->num_hwfns + hw_fn;
+                               xstats[stat_idx].value = *(uint64_t *)
+                                       (((char *)(qdev->fp_array[fpidx].rxq)) +
+                                        qede_rxq_xstats_strings[i].offset);
+                               xstats[stat_idx].id = stat_idx;
+                               stat_idx++;
+                       }
+
                }
        }
 
@@ -1962,8 +1989,7 @@ int qede_rss_hash_update(struct rte_eth_dev *eth_dev,
        uint32_t *key = (uint32_t *)rss_conf->rss_key;
        uint64_t hf = rss_conf->rss_hf;
        uint8_t len = rss_conf->rss_key_len;
-       uint8_t idx;
-       uint8_t i;
+       uint8_t idx, i, j, fpidx;
        int rc;
 
        memset(&vport_update_params, 0, sizeof(vport_update_params));
@@ -1997,14 +2023,18 @@ int qede_rss_hash_update(struct rte_eth_dev *eth_dev,
        /* tbl_size has to be set with capabilities */
        rss_params.rss_table_size_log = 7;
        vport_update_params.vport_id = 0;
-       /* pass the L2 handles instead of qids */
-       for (i = 0 ; i < ECORE_RSS_IND_TABLE_SIZE ; i++) {
-               idx = i % QEDE_RSS_COUNT(eth_dev);
-               rss_params.rss_ind_table[i] = qdev->fp_array[idx].rxq->handle;
-       }
-       vport_update_params.rss_params = &rss_params;
 
        for_each_hwfn(edev, i) {
+               /* pass the L2 handles instead of qids */
+               for (j = 0 ; j < ECORE_RSS_IND_TABLE_SIZE ; j++) {
+                       idx = j % QEDE_RSS_COUNT(eth_dev);
+                       fpidx = idx * edev->num_hwfns + i;
+                       rss_params.rss_ind_table[j] =
+                               qdev->fp_array[fpidx].rxq->handle;
+               }
+
+               vport_update_params.rss_params = &rss_params;
+
                p_hwfn = &edev->hwfns[i];
                vport_update_params.opaque_fid = p_hwfn->hw_info.opaque_fid;
                rc = ecore_sp_vport_update(p_hwfn, &vport_update_params,
@@ -2056,61 +2086,6 @@ static int qede_rss_hash_conf_get(struct rte_eth_dev *eth_dev,
        return 0;
 }
 
-static bool qede_update_rss_parm_cmt(struct ecore_dev *edev,
-                                   struct ecore_rss_params *rss)
-{
-       int i, fn;
-       bool rss_mode = 1; /* enable */
-       struct ecore_queue_cid *cid;
-       struct ecore_rss_params *t_rss;
-
-       /* In regular scenario, we'd simply need to take input handlers.
-        * But in CMT, we'd have to split the handlers according to the
-        * engine they were configured on. We'd then have to understand
-        * whether RSS is really required, since 2-queues on CMT doesn't
-        * require RSS.
-        */
-
-       /* CMT should be round-robin */
-       for (i = 0; i < ECORE_RSS_IND_TABLE_SIZE; i++) {
-               cid = rss->rss_ind_table[i];
-
-               if (cid->p_owner == ECORE_LEADING_HWFN(edev))
-                       t_rss = &rss[0];
-               else
-                       t_rss = &rss[1];
-
-               t_rss->rss_ind_table[i / edev->num_hwfns] = cid;
-       }
-
-       t_rss = &rss[1];
-       t_rss->update_rss_ind_table = 1;
-       t_rss->rss_table_size_log = 7;
-       t_rss->update_rss_config = 1;
-
-       /* Make sure RSS is actually required */
-       for_each_hwfn(edev, fn) {
-               for (i = 1; i < ECORE_RSS_IND_TABLE_SIZE / edev->num_hwfns;
-                    i++) {
-                       if (rss[fn].rss_ind_table[i] !=
-                           rss[fn].rss_ind_table[0])
-                               break;
-               }
-
-               if (i == ECORE_RSS_IND_TABLE_SIZE / edev->num_hwfns) {
-                       DP_INFO(edev,
-                               "CMT - 1 queue per-hwfn; Disabling RSS\n");
-                       rss_mode = 0;
-                       goto out;
-               }
-       }
-
-out:
-       t_rss->rss_enable = rss_mode;
-
-       return rss_mode;
-}
-
 int qede_rss_reta_update(struct rte_eth_dev *eth_dev,
                         struct rte_eth_rss_reta_entry64 *reta_conf,
                         uint16_t reta_size)
@@ -2119,8 +2094,8 @@ int qede_rss_reta_update(struct rte_eth_dev *eth_dev,
        struct ecore_dev *edev = QEDE_INIT_EDEV(qdev);
        struct ecore_sp_vport_update_params vport_update_params;
        struct ecore_rss_params *params;
+       uint16_t i, j, idx, fid, shift;
        struct ecore_hwfn *p_hwfn;
-       uint16_t i, idx, shift;
        uint8_t entry;
        int rc = 0;
 
@@ -2131,40 +2106,36 @@ int qede_rss_reta_update(struct rte_eth_dev *eth_dev,
        }
 
        memset(&vport_update_params, 0, sizeof(vport_update_params));
-       params = rte_zmalloc("qede_rss", sizeof(*params) * edev->num_hwfns,
-                            RTE_CACHE_LINE_SIZE);
+       params = rte_zmalloc("qede_rss", sizeof(*params), RTE_CACHE_LINE_SIZE);
        if (params == NULL) {
                DP_ERR(edev, "failed to allocate memory\n");
                return -ENOMEM;
        }
 
-       for (i = 0; i < reta_size; i++) {
-               idx = i / RTE_RETA_GROUP_SIZE;
-               shift = i % RTE_RETA_GROUP_SIZE;
-               if (reta_conf[idx].mask & (1ULL << shift)) {
-                       entry = reta_conf[idx].reta[shift];
-                       /* Pass rxq handles to ecore */
-                       params->rss_ind_table[i] =
-                                       qdev->fp_array[entry].rxq->handle;
-                       /* Update the local copy for RETA query command */
-                       qdev->rss_ind_table[i] = entry;
-               }
-       }
-
        params->update_rss_ind_table = 1;
        params->rss_table_size_log = 7;
        params->update_rss_config = 1;
 
-       /* Fix up RETA for CMT mode device */
-       if (ECORE_IS_CMT(edev))
-               qdev->rss_enable = qede_update_rss_parm_cmt(edev,
-                                                           params);
        vport_update_params.vport_id = 0;
        /* Use the current value of rss_enable */
        params->rss_enable = qdev->rss_enable;
        vport_update_params.rss_params = params;
 
        for_each_hwfn(edev, i) {
+               for (j = 0; j < reta_size; j++) {
+                       idx = j / RTE_RETA_GROUP_SIZE;
+                       shift = j % RTE_RETA_GROUP_SIZE;
+                       if (reta_conf[idx].mask & (1ULL << shift)) {
+                               entry = reta_conf[idx].reta[shift];
+                               fid = entry * edev->num_hwfns + i;
+                               /* Pass rxq handles to ecore */
+                               params->rss_ind_table[j] =
+                                               qdev->fp_array[fid].rxq->handle;
+                               /* Update the local copy for RETA query cmd */
+                               qdev->rss_ind_table[j] = entry;
+                       }
+               }
+
                p_hwfn = &edev->hwfns[i];
                vport_update_params.opaque_fid = p_hwfn->hw_info.opaque_fid;
                rc = ecore_sp_vport_update(p_hwfn, &vport_update_params,
@@ -2222,7 +2193,11 @@ static int qede_set_mtu(struct rte_eth_dev *dev, uint16_t mtu)
        int i, rc;
 
        PMD_INIT_FUNC_TRACE(edev);
-       qede_dev_info_get(dev, &dev_info);
+       rc = qede_dev_info_get(dev, &dev_info);
+       if (rc != 0) {
+               DP_ERR(edev, "Error during getting ethernet device info\n");
+               return rc;
+       }
        max_rx_pkt_len = mtu + QEDE_MAX_ETHER_HDR_LEN;
        frame_size = max_rx_pkt_len;
        if (mtu < RTE_ETHER_MIN_MTU || frame_size > dev_info.max_rx_pktlen) {