net/ice: add memory allocation check in RSS init
[dpdk.git] / drivers / net / ice / ice_ethdev.c
index 7db8b35..84a0d8e 100644 (file)
@@ -71,18 +71,6 @@ static struct proto_xtr_ol_flag ice_proto_xtr_ol_flag_params[] = {
 #define ICE_COMMS_PKG_NAME                     "ICE COMMS Package"
 #define ICE_MAX_RES_DESC_NUM        1024
 
-int ice_logtype_init;
-int ice_logtype_driver;
-#ifdef RTE_LIBRTE_ICE_DEBUG_RX
-int ice_logtype_rx;
-#endif
-#ifdef RTE_LIBRTE_ICE_DEBUG_TX
-int ice_logtype_tx;
-#endif
-#ifdef RTE_LIBRTE_ICE_DEBUG_TX_FREE
-int ice_logtype_tx_free;
-#endif
-
 static int ice_dev_configure(struct rte_eth_dev *dev);
 static int ice_dev_start(struct rte_eth_dev *dev);
 static void ice_dev_stop(struct rte_eth_dev *dev);
@@ -2292,9 +2280,10 @@ ice_release_vsi(struct ice_vsi *vsi)
        struct ice_hw *hw;
        struct ice_vsi_ctx vsi_ctx;
        enum ice_status ret;
+       int error = 0;
 
        if (!vsi)
-               return 0;
+               return error;
 
        hw = ICE_VSI_TO_HW(vsi);
 
@@ -2307,12 +2296,13 @@ ice_release_vsi(struct ice_vsi *vsi)
        ret = ice_free_vsi(hw, vsi->idx, &vsi_ctx, false, NULL);
        if (ret != ICE_SUCCESS) {
                PMD_INIT_LOG(ERR, "Failed to free vsi by aq, %u", vsi->vsi_id);
-               rte_free(vsi);
-               return -1;
+               error = -1;
        }
 
+       rte_free(vsi->rss_lut);
+       rte_free(vsi->rss_key);
        rte_free(vsi);
-       return 0;
+       return error;
 }
 
 void
@@ -2533,6 +2523,166 @@ ice_rss_hash_set(struct ice_pf *pf, uint64_t rss_hf)
                        PMD_DRV_LOG(ERR, "%s SCTP_IPV6 rss flow fail %d",
                                    __func__, ret);
        }
+
+       if (rss_hf & ETH_RSS_IPV4) {
+               ret = ice_add_rss_cfg(hw, vsi->idx, ICE_FLOW_HASH_IPV4,
+                               ICE_FLOW_SEG_HDR_GTPU_IP |
+                               ICE_FLOW_SEG_HDR_IPV4 |
+                               ICE_FLOW_SEG_HDR_IPV_OTHER, 0);
+               if (ret)
+                       PMD_DRV_LOG(ERR, "%s GTPU_IPV4 rss flow fail %d",
+                                   __func__, ret);
+
+               ret = ice_add_rss_cfg(hw, vsi->idx, ICE_FLOW_HASH_IPV4,
+                               ICE_FLOW_SEG_HDR_GTPU_EH |
+                               ICE_FLOW_SEG_HDR_IPV4 |
+                               ICE_FLOW_SEG_HDR_IPV_OTHER, 0);
+               if (ret)
+                       PMD_DRV_LOG(ERR, "%s GTPU_EH_IPV4 rss flow fail %d",
+                                   __func__, ret);
+
+               ret = ice_add_rss_cfg(hw, vsi->idx, ICE_FLOW_HASH_IPV4,
+                               ICE_FLOW_SEG_HDR_PPPOE |
+                               ICE_FLOW_SEG_HDR_IPV4 |
+                               ICE_FLOW_SEG_HDR_IPV_OTHER, 0);
+               if (ret)
+                       PMD_DRV_LOG(ERR, "%s PPPoE_IPV4 rss flow fail %d",
+                                   __func__, ret);
+       }
+
+       if (rss_hf & ETH_RSS_IPV6) {
+               ret = ice_add_rss_cfg(hw, vsi->idx, ICE_FLOW_HASH_IPV6,
+                               ICE_FLOW_SEG_HDR_GTPU_IP |
+                               ICE_FLOW_SEG_HDR_IPV6 |
+                               ICE_FLOW_SEG_HDR_IPV_OTHER, 0);
+               if (ret)
+                       PMD_DRV_LOG(ERR, "%s GTPU_IPV6 rss flow fail %d",
+                                   __func__, ret);
+
+               ret = ice_add_rss_cfg(hw, vsi->idx, ICE_FLOW_HASH_IPV6,
+                               ICE_FLOW_SEG_HDR_GTPU_EH |
+                               ICE_FLOW_SEG_HDR_IPV6 |
+                               ICE_FLOW_SEG_HDR_IPV_OTHER, 0);
+               if (ret)
+                       PMD_DRV_LOG(ERR, "%s GTPU_EH_IPV6 rss flow fail %d",
+                                   __func__, ret);
+
+               ret = ice_add_rss_cfg(hw, vsi->idx, ICE_FLOW_HASH_IPV6,
+                               ICE_FLOW_SEG_HDR_PPPOE |
+                               ICE_FLOW_SEG_HDR_IPV6 |
+                               ICE_FLOW_SEG_HDR_IPV_OTHER, 0);
+               if (ret)
+                       PMD_DRV_LOG(ERR, "%s PPPoE_IPV6 rss flow fail %d",
+                                   __func__, ret);
+       }
+
+       if (rss_hf & ETH_RSS_NONFRAG_IPV4_UDP) {
+               ret = ice_add_rss_cfg(hw, vsi->idx, ICE_HASH_UDP_IPV4,
+                               ICE_FLOW_SEG_HDR_GTPU_IP, 0);
+               if (ret)
+                       PMD_DRV_LOG(ERR, "%s GTPU_IPV4_UDP rss flow fail %d",
+                                   __func__, ret);
+
+               ret = ice_add_rss_cfg(hw, vsi->idx, ICE_HASH_UDP_IPV4,
+                               ICE_FLOW_SEG_HDR_GTPU_EH, 0);
+               if (ret)
+                       PMD_DRV_LOG(ERR, "%s GTPU_EH_IPV4_UDP rss flow fail %d",
+                                   __func__, ret);
+
+               ret = ice_add_rss_cfg(hw, vsi->idx, ICE_HASH_UDP_IPV4,
+                               ICE_FLOW_SEG_HDR_PPPOE, 0);
+               if (ret)
+                       PMD_DRV_LOG(ERR, "%s PPPoE_IPV4_UDP rss flow fail %d",
+                                   __func__, ret);
+       }
+
+       if (rss_hf & ETH_RSS_NONFRAG_IPV6_UDP) {
+               ret = ice_add_rss_cfg(hw, vsi->idx, ICE_HASH_UDP_IPV6,
+                               ICE_FLOW_SEG_HDR_GTPU_IP, 0);
+               if (ret)
+                       PMD_DRV_LOG(ERR, "%s GTPU_IPV6_UDP rss flow fail %d",
+                                   __func__, ret);
+
+               ret = ice_add_rss_cfg(hw, vsi->idx, ICE_HASH_UDP_IPV6,
+                               ICE_FLOW_SEG_HDR_GTPU_EH, 0);
+               if (ret)
+                       PMD_DRV_LOG(ERR, "%s GTPU_EH_IPV6_UDP rss flow fail %d",
+                                   __func__, ret);
+
+               ret = ice_add_rss_cfg(hw, vsi->idx, ICE_HASH_UDP_IPV6,
+                               ICE_FLOW_SEG_HDR_PPPOE, 0);
+               if (ret)
+                       PMD_DRV_LOG(ERR, "%s PPPoE_IPV6_UDP rss flow fail %d",
+                                   __func__, ret);
+       }
+
+       if (rss_hf & ETH_RSS_NONFRAG_IPV4_TCP) {
+               ret = ice_add_rss_cfg(hw, vsi->idx, ICE_HASH_TCP_IPV4,
+                               ICE_FLOW_SEG_HDR_GTPU_IP, 0);
+               if (ret)
+                       PMD_DRV_LOG(ERR, "%s GTPU_IPV4_TCP rss flow fail %d",
+                                   __func__, ret);
+
+               ret = ice_add_rss_cfg(hw, vsi->idx, ICE_HASH_TCP_IPV4,
+                               ICE_FLOW_SEG_HDR_GTPU_EH, 0);
+               if (ret)
+                       PMD_DRV_LOG(ERR, "%s GTPU_EH_IPV4_TCP rss flow fail %d",
+                                   __func__, ret);
+
+               ret = ice_add_rss_cfg(hw, vsi->idx, ICE_HASH_TCP_IPV4,
+                               ICE_FLOW_SEG_HDR_PPPOE, 0);
+               if (ret)
+                       PMD_DRV_LOG(ERR, "%s PPPoE_IPV4_TCP rss flow fail %d",
+                                   __func__, ret);
+       }
+
+       if (rss_hf & ETH_RSS_NONFRAG_IPV6_TCP) {
+               ret = ice_add_rss_cfg(hw, vsi->idx, ICE_HASH_TCP_IPV6,
+                               ICE_FLOW_SEG_HDR_GTPU_IP, 0);
+               if (ret)
+                       PMD_DRV_LOG(ERR, "%s GTPU_IPV6_TCP rss flow fail %d",
+                                   __func__, ret);
+
+               ret = ice_add_rss_cfg(hw, vsi->idx, ICE_HASH_TCP_IPV6,
+                               ICE_FLOW_SEG_HDR_GTPU_EH, 0);
+               if (ret)
+                       PMD_DRV_LOG(ERR, "%s GTPU_EH_IPV6_TCP rss flow fail %d",
+                                   __func__, ret);
+
+               ret = ice_add_rss_cfg(hw, vsi->idx, ICE_HASH_TCP_IPV6,
+                               ICE_FLOW_SEG_HDR_PPPOE, 0);
+               if (ret)
+                       PMD_DRV_LOG(ERR, "%s PPPoE_IPV6_TCP rss flow fail %d",
+                                   __func__, ret);
+       }
+
+       if (rss_hf & ETH_RSS_NONFRAG_IPV4_SCTP) {
+               ret = ice_add_rss_cfg(hw, vsi->idx, ICE_HASH_SCTP_IPV4,
+                               ICE_FLOW_SEG_HDR_GTPU_IP, 0);
+               if (ret)
+                       PMD_DRV_LOG(ERR, "%s GTPU_IPV4_SCTP rss flow fail %d",
+                                   __func__, ret);
+
+               ret = ice_add_rss_cfg(hw, vsi->idx, ICE_HASH_SCTP_IPV4,
+                               ICE_FLOW_SEG_HDR_GTPU_EH, 0);
+               if (ret)
+                       PMD_DRV_LOG(ERR, "%s GTPU_EH_IPV4_SCTP rss flow fail %d",
+                                   __func__, ret);
+       }
+
+       if (rss_hf & ETH_RSS_NONFRAG_IPV6_SCTP) {
+               ret = ice_add_rss_cfg(hw, vsi->idx, ICE_HASH_SCTP_IPV6,
+                               ICE_FLOW_SEG_HDR_GTPU_IP, 0);
+               if (ret)
+                       PMD_DRV_LOG(ERR, "%s GTPU_IPV6_SCTP rss flow fail %d",
+                                   __func__, ret);
+
+               ret = ice_add_rss_cfg(hw, vsi->idx, ICE_HASH_SCTP_IPV6,
+                               ICE_FLOW_SEG_HDR_GTPU_EH, 0);
+               if (ret)
+                       PMD_DRV_LOG(ERR, "%s GTPU_EH_IPV6_SCTP rss flow fail %d",
+                                   __func__, ret);
+       }
 }
 
 static int ice_init_rss(struct ice_pf *pf)
@@ -2557,13 +2707,24 @@ static int ice_init_rss(struct ice_pf *pf)
                return 0;
        }
 
-       if (!vsi->rss_key)
+       if (!vsi->rss_key) {
                vsi->rss_key = rte_zmalloc(NULL,
                                           vsi->rss_key_size, 0);
-       if (!vsi->rss_lut)
+               if (vsi->rss_key == NULL) {
+                       PMD_DRV_LOG(ERR, "Failed to allocate memory for rss_key");
+                       return -ENOMEM;
+               }
+       }
+       if (!vsi->rss_lut) {
                vsi->rss_lut = rte_zmalloc(NULL,
                                           vsi->rss_lut_size, 0);
-
+               if (vsi->rss_lut == NULL) {
+                       PMD_DRV_LOG(ERR, "Failed to allocate memory for rss_key");
+                       rte_free(vsi->rss_key);
+                       vsi->rss_key = NULL;
+                       return -ENOMEM;
+               }
+       }
        /* configure RSS key */
        if (!rss_conf->rss_key) {
                /* Calculate the default hash key */
@@ -2577,7 +2738,7 @@ static int ice_init_rss(struct ice_pf *pf)
        rte_memcpy(key.standard_rss_key, vsi->rss_key, vsi->rss_key_size);
        ret = ice_aq_set_rss_key(hw, vsi->idx, &key);
        if (ret)
-               return -EINVAL;
+               goto out;
 
        /* init RSS LUT table */
        for (i = 0; i < vsi->rss_lut_size; i++)
@@ -2587,7 +2748,7 @@ static int ice_init_rss(struct ice_pf *pf)
                                 ICE_AQC_GSET_RSS_LUT_TABLE_TYPE_PF,
                                 vsi->rss_lut, vsi->rss_lut_size);
        if (ret)
-               return -EINVAL;
+               goto out;
 
        /* Enable registers for symmetric_toeplitz function. */
        reg = ICE_READ_REG(hw, VSIQF_HASH_CTL(vsi->vsi_id));
@@ -2599,6 +2760,12 @@ static int ice_init_rss(struct ice_pf *pf)
        ice_rss_hash_set(pf, rss_conf->rss_hf);
 
        return 0;
+out:
+       rte_free(vsi->rss_key);
+       vsi->rss_key = NULL;
+       rte_free(vsi->rss_lut);
+       vsi->rss_lut = NULL;
+       return -EINVAL;
 }
 
 static int
@@ -3991,8 +4158,7 @@ ice_get_eeprom_length(struct rte_eth_dev *dev)
 {
        struct ice_hw *hw = ICE_DEV_PRIVATE_TO_HW(dev->data->dev_private);
 
-       /* Convert word count to byte count */
-       return hw->nvm.sr_words << 1;
+       return hw->nvm.flash_size;
 }
 
 static int
@@ -4000,26 +4166,24 @@ ice_get_eeprom(struct rte_eth_dev *dev,
               struct rte_dev_eeprom_info *eeprom)
 {
        struct ice_hw *hw = ICE_DEV_PRIVATE_TO_HW(dev->data->dev_private);
-       uint16_t *data = eeprom->data;
-       uint16_t first_word, last_word, nwords;
        enum ice_status status = ICE_SUCCESS;
+       uint8_t *data = eeprom->data;
 
-       first_word = eeprom->offset >> 1;
-       last_word = (eeprom->offset + eeprom->length - 1) >> 1;
-       nwords = last_word - first_word + 1;
+       eeprom->magic = hw->vendor_id | (hw->device_id << 16);
 
-       if (first_word >= hw->nvm.sr_words ||
-           last_word >= hw->nvm.sr_words) {
-               PMD_DRV_LOG(ERR, "Requested EEPROM bytes out of range.");
-               return -EINVAL;
+       status = ice_acquire_nvm(hw, ICE_RES_READ);
+       if (status) {
+               PMD_DRV_LOG(ERR, "acquire nvm failed.");
+               return -EIO;
        }
 
-       eeprom->magic = hw->vendor_id | (hw->device_id << 16);
+       status = ice_read_flat_nvm(hw, eeprom->offset, &eeprom->length,
+                                  data, false);
+
+       ice_release_nvm(hw);
 
-       status = ice_read_sr_buf(hw, first_word, &nwords, data);
        if (status) {
                PMD_DRV_LOG(ERR, "EEPROM read failed.");
-               eeprom->length = sizeof(uint16_t) * nwords;
                return -EIO;
        }
 
@@ -4095,6 +4259,13 @@ ice_update_vsi_stats(struct ice_vsi *vsi)
        ice_stat_update_40(hw, GLV_BPRCH(idx), GLV_BPRCL(idx),
                           vsi->offset_loaded, &oes->rx_broadcast,
                           &nes->rx_broadcast);
+       /* enlarge the limitation when rx_bytes overflowed */
+       if (vsi->offset_loaded) {
+               if (ICE_RXTX_BYTES_LOW(vsi->old_rx_bytes) > nes->rx_bytes)
+                       nes->rx_bytes += (uint64_t)1 << ICE_40_BIT_WIDTH;
+               nes->rx_bytes += ICE_RXTX_BYTES_HIGH(vsi->old_rx_bytes);
+       }
+       vsi->old_rx_bytes = nes->rx_bytes;
        /* exclude CRC bytes */
        nes->rx_bytes -= (nes->rx_unicast + nes->rx_multicast +
                          nes->rx_broadcast) * RTE_ETHER_CRC_LEN;
@@ -4121,6 +4292,13 @@ ice_update_vsi_stats(struct ice_vsi *vsi)
        /* GLV_TDPC not supported */
        ice_stat_update_32(hw, GLV_TEPC(idx), vsi->offset_loaded,
                           &oes->tx_errors, &nes->tx_errors);
+       /* enlarge the limitation when tx_bytes overflowed */
+       if (vsi->offset_loaded) {
+               if (ICE_RXTX_BYTES_LOW(vsi->old_tx_bytes) > nes->tx_bytes)
+                       nes->tx_bytes += (uint64_t)1 << ICE_40_BIT_WIDTH;
+               nes->tx_bytes += ICE_RXTX_BYTES_HIGH(vsi->old_tx_bytes);
+       }
+       vsi->old_tx_bytes = nes->tx_bytes;
        vsi->offset_loaded = true;
 
        PMD_DRV_LOG(DEBUG, "************** VSI[%u] stats start **************",
@@ -4168,6 +4346,13 @@ ice_read_stats_registers(struct ice_pf *pf, struct ice_hw *hw)
        ice_stat_update_32(hw, PRTRPB_RDPC,
                           pf->offset_loaded, &os->eth.rx_discards,
                           &ns->eth.rx_discards);
+       /* enlarge the limitation when rx_bytes overflowed */
+       if (pf->offset_loaded) {
+               if (ICE_RXTX_BYTES_LOW(pf->old_rx_bytes) > ns->eth.rx_bytes)
+                       ns->eth.rx_bytes += (uint64_t)1 << ICE_40_BIT_WIDTH;
+               ns->eth.rx_bytes += ICE_RXTX_BYTES_HIGH(pf->old_rx_bytes);
+       }
+       pf->old_rx_bytes = ns->eth.rx_bytes;
 
        /* Workaround: CRC size should not be included in byte statistics,
         * so subtract RTE_ETHER_CRC_LEN from the byte counter for each rx
@@ -4198,6 +4383,13 @@ ice_read_stats_registers(struct ice_pf *pf, struct ice_hw *hw)
                           GLPRT_BPTCL(hw->port_info->lport),
                           pf->offset_loaded, &os->eth.tx_broadcast,
                           &ns->eth.tx_broadcast);
+       /* enlarge the limitation when tx_bytes overflowed */
+       if (pf->offset_loaded) {
+               if (ICE_RXTX_BYTES_LOW(pf->old_tx_bytes) > ns->eth.tx_bytes)
+                       ns->eth.tx_bytes += (uint64_t)1 << ICE_40_BIT_WIDTH;
+               ns->eth.tx_bytes += ICE_RXTX_BYTES_HIGH(pf->old_tx_bytes);
+       }
+       pf->old_tx_bytes = ns->eth.tx_bytes;
        ns->eth.tx_bytes -= (ns->eth.tx_unicast + ns->eth.tx_multicast +
                             ns->eth.tx_broadcast) * RTE_ETHER_CRC_LEN;
 
@@ -4611,30 +4803,14 @@ RTE_PMD_REGISTER_PARAM_STRING(net_ice,
                              ICE_PIPELINE_MODE_SUPPORT_ARG "=<0|1>"
                              ICE_FLOW_MARK_SUPPORT_ARG "=<0|1>");
 
-RTE_INIT(ice_init_log)
-{
-       ice_logtype_init = rte_log_register("pmd.net.ice.init");
-       if (ice_logtype_init >= 0)
-               rte_log_set_level(ice_logtype_init, RTE_LOG_NOTICE);
-       ice_logtype_driver = rte_log_register("pmd.net.ice.driver");
-       if (ice_logtype_driver >= 0)
-               rte_log_set_level(ice_logtype_driver, RTE_LOG_NOTICE);
-
+RTE_LOG_REGISTER(ice_logtype_init, pmd.net.ice.init, NOTICE);
+RTE_LOG_REGISTER(ice_logtype_driver, pmd.net.ice.driver, NOTICE);
 #ifdef RTE_LIBRTE_ICE_DEBUG_RX
-       ice_logtype_rx = rte_log_register("pmd.net.ice.rx");
-       if (ice_logtype_rx >= 0)
-               rte_log_set_level(ice_logtype_rx, RTE_LOG_DEBUG);
+RTE_LOG_REGISTER(ice_logtype_rx, pmd.net.ice.rx, DEBUG);
 #endif
-
 #ifdef RTE_LIBRTE_ICE_DEBUG_TX
-       ice_logtype_tx = rte_log_register("pmd.net.ice.tx");
-       if (ice_logtype_tx >= 0)
-               rte_log_set_level(ice_logtype_tx, RTE_LOG_DEBUG);
+RTE_LOG_REGISTER(ice_logtype_tx, pmd.net.ice.tx, DEBUG);
 #endif
-
 #ifdef RTE_LIBRTE_ICE_DEBUG_TX_FREE
-       ice_logtype_tx_free = rte_log_register("pmd.net.ice.tx_free");
-       if (ice_logtype_tx_free >= 0)
-               rte_log_set_level(ice_logtype_tx_free, RTE_LOG_DEBUG);
+RTE_LOG_REGISTER(ice_logtype_tx_free, pmd.net.ice.tx_free, DEBUG);
 #endif
-}