net/ice: support new devices
[dpdk.git] / drivers / net / ice / base / ice_common.c
index fdde857..9d8f78f 100644 (file)
@@ -675,13 +675,14 @@ static void ice_get_itr_intrl_gran(struct ice_hw *hw)
 void ice_print_rollback_msg(struct ice_hw *hw)
 {
        char nvm_str[ICE_NVM_VER_LEN] = { 0 };
-       struct ice_nvm_info *nvm = &hw->nvm;
        struct ice_orom_info *orom;
+       struct ice_nvm_info *nvm;
 
-       orom = &nvm->orom;
+       orom = &hw->flash.orom;
+       nvm = &hw->flash.nvm;
 
        SNPRINTF(nvm_str, sizeof(nvm_str), "%x.%02x 0x%x %d.%d.%d",
-                nvm->major_ver, nvm->minor_ver, nvm->eetrack, orom->major,
+                nvm->major, nvm->minor, nvm->eetrack, orom->major,
                 orom->build, orom->patch);
        ice_warn(hw,
                 "Firmware rollback mode detected. Current version is NVM: %s, FW: %d.%d. Device may exhibit limited functionality. Refer to the Intel(R) Ethernet Adapters and Devices User Guide for details on firmware rollback mode\n",
@@ -760,8 +761,7 @@ enum ice_status ice_init_hw(struct ice_hw *hw)
        /* Query the allocated resources for Tx scheduler */
        status = ice_sched_query_res_alloc(hw);
        if (status) {
-               ice_debug(hw, ICE_DBG_SCHED,
-                         "Failed to get scheduler allocated resources\n");
+               ice_debug(hw, ICE_DBG_SCHED, "Failed to get scheduler allocated resources\n");
                goto err_unroll_alloc;
        }
        ice_sched_get_psm_clk_freq(hw);
@@ -770,7 +770,6 @@ enum ice_status ice_init_hw(struct ice_hw *hw)
        status = ice_sched_init_port(hw->port_info);
        if (status)
                goto err_unroll_sched;
-
        pcaps = (struct ice_aqc_get_phy_caps_data *)
                ice_malloc(hw, sizeof(*pcaps));
        if (!pcaps) {
@@ -783,7 +782,7 @@ enum ice_status ice_init_hw(struct ice_hw *hw)
                                     ICE_AQC_REPORT_TOPO_CAP, pcaps, NULL);
        ice_free(hw, pcaps);
        if (status)
-               goto err_unroll_sched;
+               ice_debug(hw, ICE_DBG_PHY, "Get PHY capabilities failed, continuing anyway\n");
 
        /* Initialize port_info struct with link information */
        status = ice_aq_get_link_info(hw->port_info, false, NULL, NULL);
@@ -898,8 +897,7 @@ enum ice_status ice_check_reset(struct ice_hw *hw)
        }
 
        if (cnt == grst_timeout) {
-               ice_debug(hw, ICE_DBG_INIT,
-                         "Global reset polling failed to complete.\n");
+               ice_debug(hw, ICE_DBG_INIT, "Global reset polling failed to complete.\n");
                return ICE_ERR_RESET_FAILED;
        }
 
@@ -917,16 +915,14 @@ enum ice_status ice_check_reset(struct ice_hw *hw)
        for (cnt = 0; cnt < ICE_PF_RESET_WAIT_COUNT; cnt++) {
                reg = rd32(hw, GLNVM_ULD) & uld_mask;
                if (reg == uld_mask) {
-                       ice_debug(hw, ICE_DBG_INIT,
-                                 "Global reset processes done. %d\n", cnt);
+                       ice_debug(hw, ICE_DBG_INIT, "Global reset processes done. %d\n", cnt);
                        break;
                }
                ice_msec_delay(10, true);
        }
 
        if (cnt == ICE_PF_RESET_WAIT_COUNT) {
-               ice_debug(hw, ICE_DBG_INIT,
-                         "Wait for Reset Done timed out. GLNVM_ULD = 0x%x\n",
+               ice_debug(hw, ICE_DBG_INIT, "Wait for Reset Done timed out. GLNVM_ULD = 0x%x\n",
                          reg);
                return ICE_ERR_RESET_FAILED;
        }
@@ -978,8 +974,7 @@ static enum ice_status ice_pf_reset(struct ice_hw *hw)
        }
 
        if (cnt == ICE_PF_RESET_WAIT_COUNT) {
-               ice_debug(hw, ICE_DBG_INIT,
-                         "PF reset polling failed to complete.\n");
+               ice_debug(hw, ICE_DBG_INIT, "PF reset polling failed to complete.\n");
                return ICE_ERR_RESET_FAILED;
        }
 
@@ -1626,8 +1621,7 @@ ice_acquire_res(struct ice_hw *hw, enum ice_aq_res_ids res,
                goto ice_acquire_res_exit;
 
        if (status)
-               ice_debug(hw, ICE_DBG_RES,
-                         "resource %d acquire type %d failed.\n", res, access);
+               ice_debug(hw, ICE_DBG_RES, "resource %d acquire type %d failed.\n", res, access);
 
        /* If necessary, poll until the current lock owner timeouts */
        timeout = time_left;
@@ -1650,11 +1644,9 @@ ice_acquire_res(struct ice_hw *hw, enum ice_aq_res_ids res,
 ice_acquire_res_exit:
        if (status == ICE_ERR_AQ_NO_WORK) {
                if (access == ICE_RES_WRITE)
-                       ice_debug(hw, ICE_DBG_RES,
-                                 "resource indicates no work to do.\n");
+                       ice_debug(hw, ICE_DBG_RES, "resource indicates no work to do.\n");
                else
-                       ice_debug(hw, ICE_DBG_RES,
-                                 "Warning: ICE_ERR_AQ_NO_WORK not expected\n");
+                       ice_debug(hw, ICE_DBG_RES, "Warning: ICE_ERR_AQ_NO_WORK not expected\n");
        }
        return status;
 }
@@ -1846,60 +1838,48 @@ ice_parse_common_caps(struct ice_hw *hw, struct ice_hw_common_caps *caps,
        switch (cap) {
        case ICE_AQC_CAPS_VALID_FUNCTIONS:
                caps->valid_functions = number;
-               ice_debug(hw, ICE_DBG_INIT,
-                         "%s: valid_functions (bitmap) = %d\n", prefix,
+               ice_debug(hw, ICE_DBG_INIT, "%s: valid_functions (bitmap) = %d\n", prefix,
                          caps->valid_functions);
                break;
        case ICE_AQC_CAPS_DCB:
                caps->dcb = (number == 1);
                caps->active_tc_bitmap = logical_id;
                caps->maxtc = phys_id;
-               ice_debug(hw, ICE_DBG_INIT,
-                         "%s: dcb = %d\n", prefix, caps->dcb);
-               ice_debug(hw, ICE_DBG_INIT,
-                         "%s: active_tc_bitmap = %d\n", prefix,
+               ice_debug(hw, ICE_DBG_INIT, "%s: dcb = %d\n", prefix, caps->dcb);
+               ice_debug(hw, ICE_DBG_INIT, "%s: active_tc_bitmap = %d\n", prefix,
                          caps->active_tc_bitmap);
-               ice_debug(hw, ICE_DBG_INIT,
-                         "%s: maxtc = %d\n", prefix, caps->maxtc);
+               ice_debug(hw, ICE_DBG_INIT, "%s: maxtc = %d\n", prefix, caps->maxtc);
                break;
        case ICE_AQC_CAPS_RSS:
                caps->rss_table_size = number;
                caps->rss_table_entry_width = logical_id;
-               ice_debug(hw, ICE_DBG_INIT,
-                         "%s: rss_table_size = %d\n", prefix,
+               ice_debug(hw, ICE_DBG_INIT, "%s: rss_table_size = %d\n", prefix,
                          caps->rss_table_size);
-               ice_debug(hw, ICE_DBG_INIT,
-                         "%s: rss_table_entry_width = %d\n", prefix,
+               ice_debug(hw, ICE_DBG_INIT, "%s: rss_table_entry_width = %d\n", prefix,
                          caps->rss_table_entry_width);
                break;
        case ICE_AQC_CAPS_RXQS:
                caps->num_rxq = number;
                caps->rxq_first_id = phys_id;
-               ice_debug(hw, ICE_DBG_INIT,
-                         "%s: num_rxq = %d\n", prefix,
+               ice_debug(hw, ICE_DBG_INIT, "%s: num_rxq = %d\n", prefix,
                          caps->num_rxq);
-               ice_debug(hw, ICE_DBG_INIT,
-                         "%s: rxq_first_id = %d\n", prefix,
+               ice_debug(hw, ICE_DBG_INIT, "%s: rxq_first_id = %d\n", prefix,
                          caps->rxq_first_id);
                break;
        case ICE_AQC_CAPS_TXQS:
                caps->num_txq = number;
                caps->txq_first_id = phys_id;
-               ice_debug(hw, ICE_DBG_INIT,
-                         "%s: num_txq = %d\n", prefix,
+               ice_debug(hw, ICE_DBG_INIT, "%s: num_txq = %d\n", prefix,
                          caps->num_txq);
-               ice_debug(hw, ICE_DBG_INIT,
-                         "%s: txq_first_id = %d\n", prefix,
+               ice_debug(hw, ICE_DBG_INIT, "%s: txq_first_id = %d\n", prefix,
                          caps->txq_first_id);
                break;
        case ICE_AQC_CAPS_MSIX:
                caps->num_msix_vectors = number;
                caps->msix_vector_first_id = phys_id;
-               ice_debug(hw, ICE_DBG_INIT,
-                         "%s: num_msix_vectors = %d\n", prefix,
+               ice_debug(hw, ICE_DBG_INIT, "%s: num_msix_vectors = %d\n", prefix,
                          caps->num_msix_vectors);
-               ice_debug(hw, ICE_DBG_INIT,
-                         "%s: msix_vector_first_id = %d\n", prefix,
+               ice_debug(hw, ICE_DBG_INIT, "%s: msix_vector_first_id = %d\n", prefix,
                          caps->msix_vector_first_id);
                break;
        case ICE_AQC_CAPS_MAX_MTU:
@@ -1933,8 +1913,7 @@ ice_recalc_port_limited_caps(struct ice_hw *hw, struct ice_hw_common_caps *caps)
        if (hw->dev_caps.num_funcs > 4) {
                /* Max 4 TCs per port */
                caps->maxtc = 4;
-               ice_debug(hw, ICE_DBG_INIT,
-                         "reducing maxtc to %d (based on #ports)\n",
+               ice_debug(hw, ICE_DBG_INIT, "reducing maxtc to %d (based on #ports)\n",
                          caps->maxtc);
        }
 }
@@ -1962,13 +1941,11 @@ ice_parse_vsi_func_caps(struct ice_hw *hw, struct ice_hw_func_caps *func_p,
  * ice_parse_fdir_func_caps - Parse ICE_AQC_CAPS_FD function caps
  * @hw: pointer to the HW struct
  * @func_p: pointer to function capabilities structure
- * @cap: pointer to the capability element to parse
  *
  * Extract function capabilities for ICE_AQC_CAPS_FD.
  */
 static void
-ice_parse_fdir_func_caps(struct ice_hw *hw, struct ice_hw_func_caps *func_p,
-                        struct ice_aqc_list_caps_elem *cap)
+ice_parse_fdir_func_caps(struct ice_hw *hw, struct ice_hw_func_caps *func_p)
 {
        u32 reg_val, val;
 
@@ -1983,11 +1960,9 @@ ice_parse_fdir_func_caps(struct ice_hw *hw, struct ice_hw_func_caps *func_p,
                GLQF_FD_SIZE_FD_BSIZE_S;
        func_p->fd_fltr_best_effort = val;
 
-       ice_debug(hw, ICE_DBG_INIT,
-                 "func caps: fd_fltr_guar = %d\n",
+       ice_debug(hw, ICE_DBG_INIT, "func caps: fd_fltr_guar = %d\n",
                  func_p->fd_fltr_guar);
-       ice_debug(hw, ICE_DBG_INIT,
-                 "func caps: fd_fltr_best_effort = %d\n",
+       ice_debug(hw, ICE_DBG_INIT, "func caps: fd_fltr_best_effort = %d\n",
                  func_p->fd_fltr_best_effort);
 }
 
@@ -2028,13 +2003,12 @@ ice_parse_func_caps(struct ice_hw *hw, struct ice_hw_func_caps *func_p,
                        ice_parse_vsi_func_caps(hw, func_p, &cap_resp[i]);
                        break;
                case ICE_AQC_CAPS_FD:
-                       ice_parse_fdir_func_caps(hw, func_p, &cap_resp[i]);
+                       ice_parse_fdir_func_caps(hw, func_p);
                        break;
                default:
                        /* Don't list common capabilities as unknown */
                        if (!found)
-                               ice_debug(hw, ICE_DBG_INIT,
-                                         "func caps: unknown capability[%d]: 0x%x\n",
+                               ice_debug(hw, ICE_DBG_INIT, "func caps: unknown capability[%d]: 0x%x\n",
                                          i, cap);
                        break;
                }
@@ -2108,7 +2082,7 @@ ice_parse_fdir_dev_caps(struct ice_hw *hw, struct ice_hw_dev_caps *dev_p,
  * @cap_count: the number of capabilities
  *
  * Helper device to parse device (0x000B) capabilities list. For
- * capabilities shared between device and device, this relies on
+ * capabilities shared between device and function, this relies on
  * ice_parse_common_caps.
  *
  * Loop through the list of provided capabilities and extract the relevant
@@ -2145,8 +2119,7 @@ ice_parse_dev_caps(struct ice_hw *hw, struct ice_hw_dev_caps *dev_p,
                default:
                        /* Don't list common capabilities as unknown */
                        if (!found)
-                               ice_debug(hw, ICE_DBG_INIT,
-                                         "dev caps: unknown capability[%d]: 0x%x\n",
+                               ice_debug(hw, ICE_DBG_INIT, "dev caps: unknown capability[%d]: 0x%x\n",
                                          i, cap);
                        break;
                }
@@ -2273,26 +2246,25 @@ void ice_set_safe_mode_caps(struct ice_hw *hw)
 {
        struct ice_hw_func_caps *func_caps = &hw->func_caps;
        struct ice_hw_dev_caps *dev_caps = &hw->dev_caps;
-       u32 valid_func, rxq_first_id, txq_first_id;
-       u32 msix_vector_first_id, max_mtu;
+       struct ice_hw_common_caps cached_caps;
        u32 num_funcs;
 
        /* cache some func_caps values that should be restored after memset */
-       valid_func = func_caps->common_cap.valid_functions;
-       txq_first_id = func_caps->common_cap.txq_first_id;
-       rxq_first_id = func_caps->common_cap.rxq_first_id;
-       msix_vector_first_id = func_caps->common_cap.msix_vector_first_id;
-       max_mtu = func_caps->common_cap.max_mtu;
+       cached_caps = func_caps->common_cap;
 
        /* unset func capabilities */
        memset(func_caps, 0, sizeof(*func_caps));
 
+#define ICE_RESTORE_FUNC_CAP(name) \
+       func_caps->common_cap.name = cached_caps.name
+
        /* restore cached values */
-       func_caps->common_cap.valid_functions = valid_func;
-       func_caps->common_cap.txq_first_id = txq_first_id;
-       func_caps->common_cap.rxq_first_id = rxq_first_id;
-       func_caps->common_cap.msix_vector_first_id = msix_vector_first_id;
-       func_caps->common_cap.max_mtu = max_mtu;
+       ICE_RESTORE_FUNC_CAP(valid_functions);
+       ICE_RESTORE_FUNC_CAP(txq_first_id);
+       ICE_RESTORE_FUNC_CAP(rxq_first_id);
+       ICE_RESTORE_FUNC_CAP(msix_vector_first_id);
+       ICE_RESTORE_FUNC_CAP(max_mtu);
+       ICE_RESTORE_FUNC_CAP(nvm_unified_update);
 
        /* one Tx and one Rx queue in safe mode */
        func_caps->common_cap.num_rxq = 1;
@@ -2303,22 +2275,22 @@ void ice_set_safe_mode_caps(struct ice_hw *hw)
        func_caps->guar_num_vsi = 1;
 
        /* cache some dev_caps values that should be restored after memset */
-       valid_func = dev_caps->common_cap.valid_functions;
-       txq_first_id = dev_caps->common_cap.txq_first_id;
-       rxq_first_id = dev_caps->common_cap.rxq_first_id;
-       msix_vector_first_id = dev_caps->common_cap.msix_vector_first_id;
-       max_mtu = dev_caps->common_cap.max_mtu;
+       cached_caps = dev_caps->common_cap;
        num_funcs = dev_caps->num_funcs;
 
        /* unset dev capabilities */
        memset(dev_caps, 0, sizeof(*dev_caps));
 
+#define ICE_RESTORE_DEV_CAP(name) \
+       dev_caps->common_cap.name = cached_caps.name
+
        /* restore cached values */
-       dev_caps->common_cap.valid_functions = valid_func;
-       dev_caps->common_cap.txq_first_id = txq_first_id;
-       dev_caps->common_cap.rxq_first_id = rxq_first_id;
-       dev_caps->common_cap.msix_vector_first_id = msix_vector_first_id;
-       dev_caps->common_cap.max_mtu = max_mtu;
+       ICE_RESTORE_DEV_CAP(valid_functions);
+       ICE_RESTORE_DEV_CAP(txq_first_id);
+       ICE_RESTORE_DEV_CAP(rxq_first_id);
+       ICE_RESTORE_DEV_CAP(msix_vector_first_id);
+       ICE_RESTORE_DEV_CAP(max_mtu);
+       ICE_RESTORE_DEV_CAP(nvm_unified_update);
        dev_caps->num_funcs = num_funcs;
 
        /* one Tx and one Rx queue per function in safe mode */
@@ -2598,8 +2570,7 @@ ice_aq_set_phy_cfg(struct ice_hw *hw, struct ice_port_info *pi,
 
        /* Ensure that only valid bits of cfg->caps can be turned on. */
        if (cfg->caps & ~ICE_AQ_PHY_ENA_VALID_MASK) {
-               ice_debug(hw, ICE_DBG_PHY,
-                         "Invalid bit is set in ice_aqc_set_phy_cfg_data->caps : 0x%x\n",
+               ice_debug(hw, ICE_DBG_PHY, "Invalid bit is set in ice_aqc_set_phy_cfg_data->caps : 0x%x\n",
                          cfg->caps);
 
                cfg->caps &= ICE_AQ_PHY_ENA_VALID_MASK;
@@ -3083,8 +3054,7 @@ enum ice_status ice_get_link_status(struct ice_port_info *pi, bool *link_up)
                status = ice_update_link_info(pi);
 
                if (status)
-                       ice_debug(pi->hw, ICE_DBG_LINK,
-                                 "get link status error, status = %d\n",
+                       ice_debug(pi->hw, ICE_DBG_LINK, "get link status error, status = %d\n",
                                  status);
        }
 
@@ -3879,8 +3849,7 @@ ice_set_ctx(struct ice_hw *hw, u8 *src_ctx, u8 *dest_ctx,
                 * of the endianness of the machine.
                 */
                if (ce_info[f].width > (ce_info[f].size_of * BITS_PER_BYTE)) {
-                       ice_debug(hw, ICE_DBG_QCTX,
-                                 "Field %d width of %d bits larger than size of %d byte(s) ... skipping write\n",
+                       ice_debug(hw, ICE_DBG_QCTX, "Field %d width of %d bits larger than size of %d byte(s) ... skipping write\n",
                                  f, ce_info[f].width, ce_info[f].size_of);
                        continue;
                }
@@ -4410,6 +4379,7 @@ static bool ice_is_main_vsi(struct ice_hw *hw, u16 vsi_handle)
 static enum ice_status
 ice_replay_pre_init(struct ice_hw *hw, struct ice_switch_info *sw)
 {
+       enum ice_status status;
        u8 i;
 
        /* Delete old entries from replay filter list head if there is any */
@@ -4423,6 +4393,10 @@ ice_replay_pre_init(struct ice_hw *hw, struct ice_switch_info *sw)
                                  &sw->recp_list[i].filt_replay_rules);
        ice_sched_replay_agg_vsi_preinit(hw);
 
+       status = ice_sched_replay_root_node_bw(hw->port_info);
+       if (status)
+               return status;
+
        return ice_sched_replay_tc_node_bw(hw->port_info);
 }
 
@@ -4657,10 +4631,6 @@ enum ice_fw_modes ice_get_fw_mode(struct ice_hw *hw)
  */
 bool ice_fw_supports_link_override(struct ice_hw *hw)
 {
-       /* Currently, only supported for E810 devices */
-       if (hw->mac_type != ICE_MAC_E810)
-               return false;
-
        if (hw->api_maj_ver == ICE_FW_API_LINK_OVERRIDE_MAJ) {
                if (hw->api_min_ver > ICE_FW_API_LINK_OVERRIDE_MIN)
                        return true;
@@ -4692,8 +4662,7 @@ ice_get_link_default_override(struct ice_link_default_override_tlv *ldo,
        status = ice_get_pfa_module_tlv(hw, &tlv, &tlv_len,
                                        ICE_SR_LINK_DEFAULT_OVERRIDE_PTR);
        if (status) {
-               ice_debug(hw, ICE_DBG_INIT,
-                         "Failed to read link override TLV.\n");
+               ice_debug(hw, ICE_DBG_INIT, "Failed to read link override TLV.\n");
                return status;
        }
 
@@ -4704,8 +4673,7 @@ ice_get_link_default_override(struct ice_link_default_override_tlv *ldo,
        /* link options first */
        status = ice_read_sr_word(hw, tlv_start, &buf);
        if (status) {
-               ice_debug(hw, ICE_DBG_INIT,
-                         "Failed to read override link options.\n");
+               ice_debug(hw, ICE_DBG_INIT, "Failed to read override link options.\n");
                return status;
        }
        ldo->options = buf & ICE_LINK_OVERRIDE_OPT_M;
@@ -4716,8 +4684,7 @@ ice_get_link_default_override(struct ice_link_default_override_tlv *ldo,
        offset = tlv_start + ICE_SR_PFA_LINK_OVERRIDE_FEC_OFFSET;
        status = ice_read_sr_word(hw, offset, &buf);
        if (status) {
-               ice_debug(hw, ICE_DBG_INIT,
-                         "Failed to read override phy config.\n");
+               ice_debug(hw, ICE_DBG_INIT, "Failed to read override phy config.\n");
                return status;
        }
        ldo->fec_options = buf & ICE_LINK_OVERRIDE_FEC_OPT_M;
@@ -4727,8 +4694,7 @@ ice_get_link_default_override(struct ice_link_default_override_tlv *ldo,
        for (i = 0; i < ICE_SR_PFA_LINK_OVERRIDE_PHY_WORDS; i++) {
                status = ice_read_sr_word(hw, (offset + i), &buf);
                if (status) {
-                       ice_debug(hw, ICE_DBG_INIT,
-                                 "Failed to read override link options.\n");
+                       ice_debug(hw, ICE_DBG_INIT, "Failed to read override link options.\n");
                        return status;
                }
                /* shift 16 bits at a time to fill 64 bits */
@@ -4741,8 +4707,7 @@ ice_get_link_default_override(struct ice_link_default_override_tlv *ldo,
        for (i = 0; i < ICE_SR_PFA_LINK_OVERRIDE_PHY_WORDS; i++) {
                status = ice_read_sr_word(hw, (offset + i), &buf);
                if (status) {
-                       ice_debug(hw, ICE_DBG_INIT,
-                                 "Failed to read override link options.\n");
+                       ice_debug(hw, ICE_DBG_INIT, "Failed to read override link options.\n");
                        return status;
                }
                /* shift 16 bits at a time to fill 64 bits */
@@ -4799,3 +4764,50 @@ ice_aq_set_lldp_mib(struct ice_hw *hw, u8 mib_type, void *buf, u16 buf_size,
 
        return ice_aq_send_cmd(hw, &desc, buf, buf_size, cd);
 }
+
+/**
+ * ice_fw_supports_lldp_fltr - check NVM version supports lldp_fltr_ctrl
+ * @hw: pointer to HW struct
+ */
+bool ice_fw_supports_lldp_fltr_ctrl(struct ice_hw *hw)
+{
+       if (hw->mac_type != ICE_MAC_E810)
+               return false;
+
+       if (hw->api_maj_ver == ICE_FW_API_LLDP_FLTR_MAJ) {
+               if (hw->api_min_ver > ICE_FW_API_LLDP_FLTR_MIN)
+                       return true;
+               if (hw->api_min_ver == ICE_FW_API_LLDP_FLTR_MIN &&
+                   hw->api_patch >= ICE_FW_API_LLDP_FLTR_PATCH)
+                       return true;
+       } else if (hw->api_maj_ver > ICE_FW_API_LLDP_FLTR_MAJ) {
+               return true;
+       }
+       return false;
+}
+
+/**
+ * ice_lldp_fltr_add_remove - add or remove a LLDP Rx switch filter
+ * @hw: pointer to HW struct
+ * @vsi_num: absolute HW index for VSI
+ * @add: boolean for if adding or removing a filter
+ */
+enum ice_status
+ice_lldp_fltr_add_remove(struct ice_hw *hw, u16 vsi_num, bool add)
+{
+       struct ice_aqc_lldp_filter_ctrl *cmd;
+       struct ice_aq_desc desc;
+
+       cmd = &desc.params.lldp_filter_ctrl;
+
+       ice_fill_dflt_direct_cmd_desc(&desc, ice_aqc_opc_lldp_filter_ctrl);
+
+       if (add)
+               cmd->cmd_flags = ICE_AQC_LLDP_FILTER_ACTION_ADD;
+       else
+               cmd->cmd_flags = ICE_AQC_LLDP_FILTER_ACTION_DELETE;
+
+       cmd->vsi_num = CPU_TO_LE16(vsi_num);
+
+       return ice_aq_send_cmd(hw, &desc, NULL, 0, NULL);
+}