+ /* Uninit TM configuration */
+ ice_tm_conf_uninit(dev);
+
+ if (ad->devargs.pps_out_ena) {
+ ICE_WRITE_REG(hw, GLTSYN_AUX_OUT(pin_idx, timer), 0);
+ ICE_WRITE_REG(hw, GLTSYN_CLKO(pin_idx, timer), 0);
+ ICE_WRITE_REG(hw, GLTSYN_TGT_L(pin_idx, timer), 0);
+ ICE_WRITE_REG(hw, GLTSYN_TGT_H(pin_idx, timer), 0);
+
+ val = GLGEN_GPIO_CTL_PIN_DIR_M;
+ ICE_WRITE_REG(hw, GLGEN_GPIO_CTL(pin_idx), val);
+ }
+
+ /* disable uio intr before callback unregister */
+ rte_intr_disable(intr_handle);
+
+ /* unregister callback func from eal lib */
+ rte_intr_callback_unregister(intr_handle,
+ ice_interrupt_handler, dev);
+
+ return ret;
+}
+
+static int
+ice_dev_uninit(struct rte_eth_dev *dev)
+{
+ ice_dev_close(dev);
+
+ return 0;
+}
+
+static bool
+is_hash_cfg_valid(struct ice_rss_hash_cfg *cfg)
+{
+ return (cfg->hash_flds != 0 && cfg->addl_hdrs != 0) ? true : false;
+}
+
+static void
+hash_cfg_reset(struct ice_rss_hash_cfg *cfg)
+{
+ cfg->hash_flds = 0;
+ cfg->addl_hdrs = 0;
+ cfg->symm = 0;
+ cfg->hdr_type = ICE_RSS_OUTER_HEADERS;
+}
+
+static int
+ice_hash_moveout(struct ice_pf *pf, struct ice_rss_hash_cfg *cfg)
+{
+ enum ice_status status = ICE_SUCCESS;
+ struct ice_hw *hw = ICE_PF_TO_HW(pf);
+ struct ice_vsi *vsi = pf->main_vsi;
+
+ if (!is_hash_cfg_valid(cfg))
+ return -ENOENT;
+
+ status = ice_rem_rss_cfg(hw, vsi->idx, cfg);
+ if (status && status != ICE_ERR_DOES_NOT_EXIST) {
+ PMD_DRV_LOG(ERR,
+ "ice_rem_rss_cfg failed for VSI:%d, error:%d\n",
+ vsi->idx, status);
+ return -EBUSY;
+ }
+
+ return 0;
+}
+
+static int
+ice_hash_moveback(struct ice_pf *pf, struct ice_rss_hash_cfg *cfg)
+{
+ enum ice_status status = ICE_SUCCESS;
+ struct ice_hw *hw = ICE_PF_TO_HW(pf);
+ struct ice_vsi *vsi = pf->main_vsi;
+
+ if (!is_hash_cfg_valid(cfg))
+ return -ENOENT;
+
+ status = ice_add_rss_cfg(hw, vsi->idx, cfg);
+ if (status) {
+ PMD_DRV_LOG(ERR,
+ "ice_add_rss_cfg failed for VSI:%d, error:%d\n",
+ vsi->idx, status);
+ return -EBUSY;
+ }
+
+ return 0;
+}
+
+static int
+ice_hash_remove(struct ice_pf *pf, struct ice_rss_hash_cfg *cfg)
+{
+ int ret;
+
+ ret = ice_hash_moveout(pf, cfg);
+ if (ret && (ret != -ENOENT))
+ return ret;
+
+ hash_cfg_reset(cfg);
+
+ return 0;
+}
+
+static int
+ice_add_rss_cfg_pre_gtpu(struct ice_pf *pf, struct ice_hash_gtpu_ctx *ctx,
+ u8 ctx_idx)
+{
+ int ret;
+
+ switch (ctx_idx) {
+ case ICE_HASH_GTPU_CTX_EH_IP:
+ ret = ice_hash_remove(pf,
+ &ctx->ctx[ICE_HASH_GTPU_CTX_EH_IP_UDP]);
+ if (ret && (ret != -ENOENT))
+ return ret;
+
+ ret = ice_hash_remove(pf,
+ &ctx->ctx[ICE_HASH_GTPU_CTX_EH_IP_TCP]);
+ if (ret && (ret != -ENOENT))
+ return ret;
+
+ ret = ice_hash_remove(pf,
+ &ctx->ctx[ICE_HASH_GTPU_CTX_UP_IP]);
+ if (ret && (ret != -ENOENT))
+ return ret;
+
+ ret = ice_hash_remove(pf,
+ &ctx->ctx[ICE_HASH_GTPU_CTX_UP_IP_UDP]);
+ if (ret && (ret != -ENOENT))
+ return ret;
+
+ ret = ice_hash_remove(pf,
+ &ctx->ctx[ICE_HASH_GTPU_CTX_UP_IP_TCP]);
+ if (ret && (ret != -ENOENT))
+ return ret;
+
+ ret = ice_hash_remove(pf,
+ &ctx->ctx[ICE_HASH_GTPU_CTX_DW_IP]);
+ if (ret && (ret != -ENOENT))
+ return ret;
+
+ ret = ice_hash_remove(pf,
+ &ctx->ctx[ICE_HASH_GTPU_CTX_DW_IP_UDP]);
+ if (ret && (ret != -ENOENT))
+ return ret;
+
+ ret = ice_hash_remove(pf,
+ &ctx->ctx[ICE_HASH_GTPU_CTX_DW_IP_TCP]);
+ if (ret && (ret != -ENOENT))
+ return ret;
+
+ break;
+ case ICE_HASH_GTPU_CTX_EH_IP_UDP:
+ ret = ice_hash_remove(pf,
+ &ctx->ctx[ICE_HASH_GTPU_CTX_UP_IP_UDP]);
+ if (ret && (ret != -ENOENT))
+ return ret;
+
+ ret = ice_hash_remove(pf,
+ &ctx->ctx[ICE_HASH_GTPU_CTX_DW_IP_UDP]);
+ if (ret && (ret != -ENOENT))
+ return ret;
+
+ ret = ice_hash_moveout(pf,
+ &ctx->ctx[ICE_HASH_GTPU_CTX_UP_IP]);
+ if (ret && (ret != -ENOENT))
+ return ret;
+
+ ret = ice_hash_moveout(pf,
+ &ctx->ctx[ICE_HASH_GTPU_CTX_UP_IP_TCP]);
+ if (ret && (ret != -ENOENT))
+ return ret;
+
+ ret = ice_hash_moveout(pf,
+ &ctx->ctx[ICE_HASH_GTPU_CTX_DW_IP]);
+ if (ret && (ret != -ENOENT))
+ return ret;
+
+ ret = ice_hash_moveout(pf,
+ &ctx->ctx[ICE_HASH_GTPU_CTX_DW_IP_TCP]);
+ if (ret && (ret != -ENOENT))
+ return ret;
+
+ break;
+ case ICE_HASH_GTPU_CTX_EH_IP_TCP:
+ ret = ice_hash_remove(pf,
+ &ctx->ctx[ICE_HASH_GTPU_CTX_UP_IP_TCP]);
+ if (ret && (ret != -ENOENT))
+ return ret;
+
+ ret = ice_hash_remove(pf,
+ &ctx->ctx[ICE_HASH_GTPU_CTX_DW_IP_TCP]);
+ if (ret && (ret != -ENOENT))
+ return ret;
+
+ ret = ice_hash_moveout(pf,
+ &ctx->ctx[ICE_HASH_GTPU_CTX_UP_IP]);
+ if (ret && (ret != -ENOENT))
+ return ret;
+
+ ret = ice_hash_moveout(pf,
+ &ctx->ctx[ICE_HASH_GTPU_CTX_UP_IP_UDP]);
+ if (ret && (ret != -ENOENT))
+ return ret;
+
+ ret = ice_hash_moveout(pf,
+ &ctx->ctx[ICE_HASH_GTPU_CTX_DW_IP]);
+ if (ret && (ret != -ENOENT))
+ return ret;
+
+ ret = ice_hash_moveout(pf,
+ &ctx->ctx[ICE_HASH_GTPU_CTX_DW_IP_UDP]);
+ if (ret && (ret != -ENOENT))
+ return ret;
+
+ break;
+ case ICE_HASH_GTPU_CTX_UP_IP:
+ ret = ice_hash_remove(pf,
+ &ctx->ctx[ICE_HASH_GTPU_CTX_UP_IP_UDP]);
+ if (ret && (ret != -ENOENT))
+ return ret;
+
+ ret = ice_hash_remove(pf,
+ &ctx->ctx[ICE_HASH_GTPU_CTX_UP_IP_TCP]);
+ if (ret && (ret != -ENOENT))
+ return ret;
+
+ ret = ice_hash_moveout(pf,
+ &ctx->ctx[ICE_HASH_GTPU_CTX_EH_IP]);
+ if (ret && (ret != -ENOENT))
+ return ret;
+
+ ret = ice_hash_moveout(pf,
+ &ctx->ctx[ICE_HASH_GTPU_CTX_EH_IP_UDP]);
+ if (ret && (ret != -ENOENT))
+ return ret;
+
+ ret = ice_hash_moveout(pf,
+ &ctx->ctx[ICE_HASH_GTPU_CTX_EH_IP_TCP]);
+ if (ret && (ret != -ENOENT))
+ return ret;
+
+ break;
+ case ICE_HASH_GTPU_CTX_UP_IP_UDP:
+ case ICE_HASH_GTPU_CTX_UP_IP_TCP:
+ ret = ice_hash_moveout(pf,
+ &ctx->ctx[ICE_HASH_GTPU_CTX_EH_IP]);
+ if (ret && (ret != -ENOENT))
+ return ret;
+
+ ret = ice_hash_moveout(pf,
+ &ctx->ctx[ICE_HASH_GTPU_CTX_EH_IP_UDP]);
+ if (ret && (ret != -ENOENT))
+ return ret;
+
+ ret = ice_hash_moveout(pf,
+ &ctx->ctx[ICE_HASH_GTPU_CTX_EH_IP_TCP]);
+ if (ret && (ret != -ENOENT))
+ return ret;
+
+ break;
+ case ICE_HASH_GTPU_CTX_DW_IP:
+ ret = ice_hash_remove(pf,
+ &ctx->ctx[ICE_HASH_GTPU_CTX_DW_IP_UDP]);
+ if (ret && (ret != -ENOENT))
+ return ret;
+
+ ret = ice_hash_remove(pf,
+ &ctx->ctx[ICE_HASH_GTPU_CTX_DW_IP_TCP]);
+ if (ret && (ret != -ENOENT))
+ return ret;
+
+ ret = ice_hash_moveout(pf,
+ &ctx->ctx[ICE_HASH_GTPU_CTX_EH_IP]);
+ if (ret && (ret != -ENOENT))
+ return ret;
+
+ ret = ice_hash_moveout(pf,
+ &ctx->ctx[ICE_HASH_GTPU_CTX_EH_IP_UDP]);
+ if (ret && (ret != -ENOENT))
+ return ret;
+
+ ret = ice_hash_moveout(pf,
+ &ctx->ctx[ICE_HASH_GTPU_CTX_EH_IP_TCP]);
+ if (ret && (ret != -ENOENT))
+ return ret;
+
+ break;
+ case ICE_HASH_GTPU_CTX_DW_IP_UDP:
+ case ICE_HASH_GTPU_CTX_DW_IP_TCP:
+ ret = ice_hash_moveout(pf,
+ &ctx->ctx[ICE_HASH_GTPU_CTX_EH_IP]);
+ if (ret && (ret != -ENOENT))
+ return ret;
+
+ ret = ice_hash_moveout(pf,
+ &ctx->ctx[ICE_HASH_GTPU_CTX_EH_IP_UDP]);
+ if (ret && (ret != -ENOENT))
+ return ret;
+
+ ret = ice_hash_moveout(pf,
+ &ctx->ctx[ICE_HASH_GTPU_CTX_EH_IP_TCP]);
+ if (ret && (ret != -ENOENT))
+ return ret;
+
+ break;
+ default:
+ break;
+ }
+
+ return 0;
+}
+
+static u8 calc_gtpu_ctx_idx(uint32_t hdr)
+{
+ u8 eh_idx, ip_idx;
+
+ if (hdr & ICE_FLOW_SEG_HDR_GTPU_EH)
+ eh_idx = 0;
+ else if (hdr & ICE_FLOW_SEG_HDR_GTPU_UP)
+ eh_idx = 1;
+ else if (hdr & ICE_FLOW_SEG_HDR_GTPU_DWN)
+ eh_idx = 2;
+ else
+ return ICE_HASH_GTPU_CTX_MAX;
+
+ ip_idx = 0;
+ if (hdr & ICE_FLOW_SEG_HDR_UDP)
+ ip_idx = 1;
+ else if (hdr & ICE_FLOW_SEG_HDR_TCP)
+ ip_idx = 2;
+
+ if (hdr & (ICE_FLOW_SEG_HDR_IPV4 | ICE_FLOW_SEG_HDR_IPV6))
+ return eh_idx * 3 + ip_idx;
+ else
+ return ICE_HASH_GTPU_CTX_MAX;
+}
+
+static int
+ice_add_rss_cfg_pre(struct ice_pf *pf, uint32_t hdr)
+{
+ u8 gtpu_ctx_idx = calc_gtpu_ctx_idx(hdr);
+
+ if (hdr & ICE_FLOW_SEG_HDR_IPV4)
+ return ice_add_rss_cfg_pre_gtpu(pf, &pf->hash_ctx.gtpu4,
+ gtpu_ctx_idx);
+ else if (hdr & ICE_FLOW_SEG_HDR_IPV6)
+ return ice_add_rss_cfg_pre_gtpu(pf, &pf->hash_ctx.gtpu6,
+ gtpu_ctx_idx);
+
+ return 0;
+}
+
+static int
+ice_add_rss_cfg_post_gtpu(struct ice_pf *pf, struct ice_hash_gtpu_ctx *ctx,
+ u8 ctx_idx, struct ice_rss_hash_cfg *cfg)
+{
+ int ret;
+
+ if (ctx_idx < ICE_HASH_GTPU_CTX_MAX)
+ ctx->ctx[ctx_idx] = *cfg;
+
+ switch (ctx_idx) {
+ case ICE_HASH_GTPU_CTX_EH_IP:
+ break;
+ case ICE_HASH_GTPU_CTX_EH_IP_UDP:
+ ret = ice_hash_moveback(pf,
+ &ctx->ctx[ICE_HASH_GTPU_CTX_UP_IP]);
+ if (ret && (ret != -ENOENT))
+ return ret;
+
+ ret = ice_hash_moveback(pf,
+ &ctx->ctx[ICE_HASH_GTPU_CTX_UP_IP_TCP]);
+ if (ret && (ret != -ENOENT))
+ return ret;
+
+ ret = ice_hash_moveback(pf,
+ &ctx->ctx[ICE_HASH_GTPU_CTX_DW_IP]);
+ if (ret && (ret != -ENOENT))
+ return ret;
+
+ ret = ice_hash_moveback(pf,
+ &ctx->ctx[ICE_HASH_GTPU_CTX_DW_IP_TCP]);
+ if (ret && (ret != -ENOENT))
+ return ret;
+
+ break;
+ case ICE_HASH_GTPU_CTX_EH_IP_TCP:
+ ret = ice_hash_moveback(pf,
+ &ctx->ctx[ICE_HASH_GTPU_CTX_UP_IP]);
+ if (ret && (ret != -ENOENT))
+ return ret;
+
+ ret = ice_hash_moveback(pf,
+ &ctx->ctx[ICE_HASH_GTPU_CTX_UP_IP_UDP]);
+ if (ret && (ret != -ENOENT))
+ return ret;
+
+ ret = ice_hash_moveback(pf,
+ &ctx->ctx[ICE_HASH_GTPU_CTX_DW_IP]);
+ if (ret && (ret != -ENOENT))
+ return ret;
+
+ ret = ice_hash_moveback(pf,
+ &ctx->ctx[ICE_HASH_GTPU_CTX_DW_IP_UDP]);
+ if (ret && (ret != -ENOENT))
+ return ret;
+
+ break;
+ case ICE_HASH_GTPU_CTX_UP_IP:
+ case ICE_HASH_GTPU_CTX_UP_IP_UDP:
+ case ICE_HASH_GTPU_CTX_UP_IP_TCP:
+ case ICE_HASH_GTPU_CTX_DW_IP:
+ case ICE_HASH_GTPU_CTX_DW_IP_UDP:
+ case ICE_HASH_GTPU_CTX_DW_IP_TCP:
+ ret = ice_hash_moveback(pf,
+ &ctx->ctx[ICE_HASH_GTPU_CTX_EH_IP]);
+ if (ret && (ret != -ENOENT))
+ return ret;
+
+ ret = ice_hash_moveback(pf,
+ &ctx->ctx[ICE_HASH_GTPU_CTX_EH_IP_UDP]);
+ if (ret && (ret != -ENOENT))
+ return ret;
+
+ ret = ice_hash_moveback(pf,
+ &ctx->ctx[ICE_HASH_GTPU_CTX_EH_IP_TCP]);
+ if (ret && (ret != -ENOENT))
+ return ret;
+
+ break;
+ default:
+ break;
+ }
+
+ return 0;
+}
+
+static int
+ice_add_rss_cfg_post(struct ice_pf *pf, struct ice_rss_hash_cfg *cfg)
+{
+ u8 gtpu_ctx_idx = calc_gtpu_ctx_idx(cfg->addl_hdrs);
+
+ if (cfg->addl_hdrs & ICE_FLOW_SEG_HDR_IPV4)
+ return ice_add_rss_cfg_post_gtpu(pf, &pf->hash_ctx.gtpu4,
+ gtpu_ctx_idx, cfg);
+ else if (cfg->addl_hdrs & ICE_FLOW_SEG_HDR_IPV6)
+ return ice_add_rss_cfg_post_gtpu(pf, &pf->hash_ctx.gtpu6,
+ gtpu_ctx_idx, cfg);
+
+ return 0;
+}
+
+static void
+ice_rem_rss_cfg_post(struct ice_pf *pf, uint32_t hdr)
+{
+ u8 gtpu_ctx_idx = calc_gtpu_ctx_idx(hdr);
+
+ if (gtpu_ctx_idx >= ICE_HASH_GTPU_CTX_MAX)
+ return;
+
+ if (hdr & ICE_FLOW_SEG_HDR_IPV4)
+ hash_cfg_reset(&pf->hash_ctx.gtpu4.ctx[gtpu_ctx_idx]);
+ else if (hdr & ICE_FLOW_SEG_HDR_IPV6)
+ hash_cfg_reset(&pf->hash_ctx.gtpu6.ctx[gtpu_ctx_idx]);
+}
+
+int
+ice_rem_rss_cfg_wrap(struct ice_pf *pf, uint16_t vsi_id,
+ struct ice_rss_hash_cfg *cfg)
+{
+ struct ice_hw *hw = ICE_PF_TO_HW(pf);
+ int ret;