Commit a1ffafb0 authored by Brett Creeley's avatar Brett Creeley Committed by Tony Nguyen

ice: Support configuring the device to Double VLAN Mode

In order to support configuring the device in Double VLAN Mode (DVM),
the DDP and FW have to support DVM. If both support DVM, the PF that
downloads the package needs to update the default recipes, set the
VLAN mode, and update boost TCAM entries.

To support updating the default recipes in DVM, add support for
updating an existing switch recipe's lkup_idx and mask. This is done
by first calling the get recipe AQ (0x0292) with the desired recipe
ID. Then, if that is successful update one of the lookup indices
(lkup_idx) and its associated mask if the mask is valid otherwise
the already existing mask will be used.

The VLAN mode of the device has to be configured while the global
configuration lock is held while downloading the DDP, specifically after
the DDP has been downloaded. If supported, the device will default to
DVM.
Co-developed-by: default avatarDan Nowlin <dan.nowlin@intel.com>
Signed-off-by: default avatarDan Nowlin <dan.nowlin@intel.com>
Signed-off-by: default avatarBrett Creeley <brett.creeley@intel.com>
Tested-by: default avatarGurucharan G <gurucharanx.g@intel.com>
Signed-off-by: default avatarTony Nguyen <anthony.l.nguyen@intel.com>
parent cc71de8f
...@@ -23,6 +23,7 @@ ice-y := ice_main.o \ ...@@ -23,6 +23,7 @@ ice-y := ice_main.o \
ice_vsi_vlan_lib.o \ ice_vsi_vlan_lib.o \
ice_fdir.o \ ice_fdir.o \
ice_ethtool_fdir.o \ ice_ethtool_fdir.o \
ice_vlan_mode.o \
ice_flex_pipe.o \ ice_flex_pipe.o \
ice_flow.o \ ice_flow.o \
ice_idc.o \ ice_idc.o \
......
...@@ -226,6 +226,15 @@ struct ice_aqc_get_sw_cfg_resp_elem { ...@@ -226,6 +226,15 @@ struct ice_aqc_get_sw_cfg_resp_elem {
#define ICE_AQC_GET_SW_CONF_RESP_IS_VF BIT(15) #define ICE_AQC_GET_SW_CONF_RESP_IS_VF BIT(15)
}; };
/* Set Port parameters, (direct, 0x0203) */
struct ice_aqc_set_port_params {
__le16 cmd_flags;
#define ICE_AQC_SET_P_PARAMS_DOUBLE_VLAN_ENA BIT(2)
__le16 bad_frame_vsi;
__le16 swid;
u8 reserved[10];
};
/* These resource type defines are used for all switch resource /* These resource type defines are used for all switch resource
* commands where a resource type is required, such as: * commands where a resource type is required, such as:
* Get Resource Allocation command (indirect 0x0204) * Get Resource Allocation command (indirect 0x0204)
...@@ -283,6 +292,40 @@ struct ice_aqc_alloc_free_res_elem { ...@@ -283,6 +292,40 @@ struct ice_aqc_alloc_free_res_elem {
struct ice_aqc_res_elem elem[]; struct ice_aqc_res_elem elem[];
}; };
/* Request buffer for Set VLAN Mode AQ command (indirect 0x020C) */
struct ice_aqc_set_vlan_mode {
u8 reserved;
u8 l2tag_prio_tagging;
#define ICE_AQ_VLAN_PRIO_TAG_S 0
#define ICE_AQ_VLAN_PRIO_TAG_M (0x7 << ICE_AQ_VLAN_PRIO_TAG_S)
#define ICE_AQ_VLAN_PRIO_TAG_NOT_SUPPORTED 0x0
#define ICE_AQ_VLAN_PRIO_TAG_STAG 0x1
#define ICE_AQ_VLAN_PRIO_TAG_OUTER_CTAG 0x2
#define ICE_AQ_VLAN_PRIO_TAG_OUTER_VLAN 0x3
#define ICE_AQ_VLAN_PRIO_TAG_INNER_CTAG 0x4
#define ICE_AQ_VLAN_PRIO_TAG_MAX 0x4
#define ICE_AQ_VLAN_PRIO_TAG_ERROR 0x7
u8 l2tag_reserved[64];
u8 rdma_packet;
#define ICE_AQ_VLAN_RDMA_TAG_S 0
#define ICE_AQ_VLAN_RDMA_TAG_M (0x3F << ICE_AQ_VLAN_RDMA_TAG_S)
#define ICE_AQ_SVM_VLAN_RDMA_PKT_FLAG_SETTING 0x10
#define ICE_AQ_DVM_VLAN_RDMA_PKT_FLAG_SETTING 0x1A
u8 rdma_reserved[2];
u8 mng_vlan_prot_id;
#define ICE_AQ_VLAN_MNG_PROTOCOL_ID_OUTER 0x10
#define ICE_AQ_VLAN_MNG_PROTOCOL_ID_INNER 0x11
u8 prot_id_reserved[30];
};
/* Response buffer for Get VLAN Mode AQ command (indirect 0x020D) */
struct ice_aqc_get_vlan_mode {
u8 vlan_mode;
#define ICE_AQ_VLAN_MODE_DVM_ENA BIT(0)
u8 l2tag_prio_tagging;
u8 reserved[98];
};
/* Add VSI (indirect 0x0210) /* Add VSI (indirect 0x0210)
* Update VSI (indirect 0x0211) * Update VSI (indirect 0x0211)
* Get VSI (indirect 0x0212) * Get VSI (indirect 0x0212)
...@@ -494,9 +537,13 @@ struct ice_aqc_add_get_recipe { ...@@ -494,9 +537,13 @@ struct ice_aqc_add_get_recipe {
struct ice_aqc_recipe_content { struct ice_aqc_recipe_content {
u8 rid; u8 rid;
#define ICE_AQ_RECIPE_ID_S 0
#define ICE_AQ_RECIPE_ID_M (0x3F << ICE_AQ_RECIPE_ID_S)
#define ICE_AQ_RECIPE_ID_IS_ROOT BIT(7) #define ICE_AQ_RECIPE_ID_IS_ROOT BIT(7)
#define ICE_AQ_SW_ID_LKUP_IDX 0 #define ICE_AQ_SW_ID_LKUP_IDX 0
u8 lkup_indx[5]; u8 lkup_indx[5];
#define ICE_AQ_RECIPE_LKUP_DATA_S 0
#define ICE_AQ_RECIPE_LKUP_DATA_M (0x3F << ICE_AQ_RECIPE_LKUP_DATA_S)
#define ICE_AQ_RECIPE_LKUP_IGNORE BIT(7) #define ICE_AQ_RECIPE_LKUP_IGNORE BIT(7)
#define ICE_AQ_SW_ID_LKUP_MASK 0x00FF #define ICE_AQ_SW_ID_LKUP_MASK 0x00FF
__le16 mask[5]; __le16 mask[5];
...@@ -507,15 +554,25 @@ struct ice_aqc_recipe_content { ...@@ -507,15 +554,25 @@ struct ice_aqc_recipe_content {
u8 rsvd0[3]; u8 rsvd0[3];
u8 act_ctrl_join_priority; u8 act_ctrl_join_priority;
u8 act_ctrl_fwd_priority; u8 act_ctrl_fwd_priority;
#define ICE_AQ_RECIPE_FWD_PRIORITY_S 0
#define ICE_AQ_RECIPE_FWD_PRIORITY_M (0xF << ICE_AQ_RECIPE_FWD_PRIORITY_S)
u8 act_ctrl; u8 act_ctrl;
#define ICE_AQ_RECIPE_ACT_NEED_PASS_L2 BIT(0)
#define ICE_AQ_RECIPE_ACT_ALLOW_PASS_L2 BIT(1)
#define ICE_AQ_RECIPE_ACT_INV_ACT BIT(2) #define ICE_AQ_RECIPE_ACT_INV_ACT BIT(2)
#define ICE_AQ_RECIPE_ACT_PRUNE_INDX_S 4
#define ICE_AQ_RECIPE_ACT_PRUNE_INDX_M (0x3 << ICE_AQ_RECIPE_ACT_PRUNE_INDX_S)
u8 rsvd1; u8 rsvd1;
__le32 dflt_act; __le32 dflt_act;
#define ICE_AQ_RECIPE_DFLT_ACT_S 0
#define ICE_AQ_RECIPE_DFLT_ACT_M (0x7FFFF << ICE_AQ_RECIPE_DFLT_ACT_S)
#define ICE_AQ_RECIPE_DFLT_ACT_VALID BIT(31)
}; };
struct ice_aqc_recipe_data_elem { struct ice_aqc_recipe_data_elem {
u8 recipe_indx; u8 recipe_indx;
u8 resp_bits; u8 resp_bits;
#define ICE_AQ_RECIPE_WAS_UPDATED BIT(0)
u8 rsvd0[2]; u8 rsvd0[2];
u8 recipe_bitmap[8]; u8 recipe_bitmap[8];
u8 rsvd1[4]; u8 rsvd1[4];
...@@ -1888,7 +1945,7 @@ struct ice_aqc_get_clear_fw_log { ...@@ -1888,7 +1945,7 @@ struct ice_aqc_get_clear_fw_log {
}; };
/* Download Package (indirect 0x0C40) */ /* Download Package (indirect 0x0C40) */
/* Also used for Update Package (indirect 0x0C42) */ /* Also used for Update Package (indirect 0x0C41 and 0x0C42) */
struct ice_aqc_download_pkg { struct ice_aqc_download_pkg {
u8 flags; u8 flags;
#define ICE_AQC_DOWNLOAD_PKG_LAST_BUF 0x01 #define ICE_AQC_DOWNLOAD_PKG_LAST_BUF 0x01
...@@ -2014,6 +2071,7 @@ struct ice_aq_desc { ...@@ -2014,6 +2071,7 @@ struct ice_aq_desc {
struct ice_aqc_sff_eeprom read_write_sff_param; struct ice_aqc_sff_eeprom read_write_sff_param;
struct ice_aqc_set_port_id_led set_port_id_led; struct ice_aqc_set_port_id_led set_port_id_led;
struct ice_aqc_get_sw_cfg get_sw_conf; struct ice_aqc_get_sw_cfg get_sw_conf;
struct ice_aqc_set_port_params set_port_params;
struct ice_aqc_sw_rules sw_rules; struct ice_aqc_sw_rules sw_rules;
struct ice_aqc_add_get_recipe add_get_recipe; struct ice_aqc_add_get_recipe add_get_recipe;
struct ice_aqc_recipe_to_profile recipe_to_profile; struct ice_aqc_recipe_to_profile recipe_to_profile;
...@@ -2115,10 +2173,13 @@ enum ice_adminq_opc { ...@@ -2115,10 +2173,13 @@ enum ice_adminq_opc {
/* internal switch commands */ /* internal switch commands */
ice_aqc_opc_get_sw_cfg = 0x0200, ice_aqc_opc_get_sw_cfg = 0x0200,
ice_aqc_opc_set_port_params = 0x0203,
/* Alloc/Free/Get Resources */ /* Alloc/Free/Get Resources */
ice_aqc_opc_alloc_res = 0x0208, ice_aqc_opc_alloc_res = 0x0208,
ice_aqc_opc_free_res = 0x0209, ice_aqc_opc_free_res = 0x0209,
ice_aqc_opc_set_vlan_mode_parameters = 0x020C,
ice_aqc_opc_get_vlan_mode_parameters = 0x020D,
/* VSI commands */ /* VSI commands */
ice_aqc_opc_add_vsi = 0x0210, ice_aqc_opc_add_vsi = 0x0210,
...@@ -2209,6 +2270,7 @@ enum ice_adminq_opc { ...@@ -2209,6 +2270,7 @@ enum ice_adminq_opc {
/* package commands */ /* package commands */
ice_aqc_opc_download_pkg = 0x0C40, ice_aqc_opc_download_pkg = 0x0C40,
ice_aqc_opc_upload_section = 0x0C41,
ice_aqc_opc_update_pkg = 0x0C42, ice_aqc_opc_update_pkg = 0x0C42,
ice_aqc_opc_get_pkg_info_list = 0x0C43, ice_aqc_opc_get_pkg_info_list = 0x0C43,
......
...@@ -1518,16 +1518,27 @@ ice_aq_send_cmd(struct ice_hw *hw, struct ice_aq_desc *desc, void *buf, ...@@ -1518,16 +1518,27 @@ ice_aq_send_cmd(struct ice_hw *hw, struct ice_aq_desc *desc, void *buf,
/* When a package download is in process (i.e. when the firmware's /* When a package download is in process (i.e. when the firmware's
* Global Configuration Lock resource is held), only the Download * Global Configuration Lock resource is held), only the Download
* Package, Get Version, Get Package Info List and Release Resource * Package, Get Version, Get Package Info List, Upload Section,
* (with resource ID set to Global Config Lock) AdminQ commands are * Update Package, Set Port Parameters, Get/Set VLAN Mode Parameters,
* allowed; all others must block until the package download completes * Add Recipe, Set Recipes to Profile Association, Get Recipe, and Get
* and the Global Config Lock is released. See also * Recipes to Profile Association, and Release Resource (with resource
* ice_acquire_global_cfg_lock(). * ID set to Global Config Lock) AdminQ commands are allowed; all others
* must block until the package download completes and the Global Config
* Lock is released. See also ice_acquire_global_cfg_lock().
*/ */
switch (le16_to_cpu(desc->opcode)) { switch (le16_to_cpu(desc->opcode)) {
case ice_aqc_opc_download_pkg: case ice_aqc_opc_download_pkg:
case ice_aqc_opc_get_pkg_info_list: case ice_aqc_opc_get_pkg_info_list:
case ice_aqc_opc_get_ver: case ice_aqc_opc_get_ver:
case ice_aqc_opc_upload_section:
case ice_aqc_opc_update_pkg:
case ice_aqc_opc_set_port_params:
case ice_aqc_opc_get_vlan_mode_parameters:
case ice_aqc_opc_set_vlan_mode_parameters:
case ice_aqc_opc_add_recipe:
case ice_aqc_opc_recipe_to_profile:
case ice_aqc_opc_get_recipe:
case ice_aqc_opc_get_recipe_to_profile:
break; break;
case ice_aqc_opc_release_res: case ice_aqc_opc_release_res:
if (le16_to_cpu(cmd->res_id) == ICE_AQC_RES_ID_GLBL_LOCK) if (le16_to_cpu(cmd->res_id) == ICE_AQC_RES_ID_GLBL_LOCK)
...@@ -2736,6 +2747,34 @@ void ice_clear_pxe_mode(struct ice_hw *hw) ...@@ -2736,6 +2747,34 @@ void ice_clear_pxe_mode(struct ice_hw *hw)
ice_aq_clear_pxe_mode(hw); ice_aq_clear_pxe_mode(hw);
} }
/**
* ice_aq_set_port_params - set physical port parameters.
* @pi: pointer to the port info struct
* @double_vlan: if set double VLAN is enabled
* @cd: pointer to command details structure or NULL
*
* Set Physical port parameters (0x0203)
*/
int
ice_aq_set_port_params(struct ice_port_info *pi, bool double_vlan,
struct ice_sq_cd *cd)
{
struct ice_aqc_set_port_params *cmd;
struct ice_hw *hw = pi->hw;
struct ice_aq_desc desc;
u16 cmd_flags = 0;
cmd = &desc.params.set_port_params;
ice_fill_dflt_direct_cmd_desc(&desc, ice_aqc_opc_set_port_params);
if (double_vlan)
cmd_flags |= ICE_AQC_SET_P_PARAMS_DOUBLE_VLAN_ENA;
cmd->cmd_flags = cpu_to_le16(cmd_flags);
return ice_aq_send_cmd(hw, &desc, NULL, 0, cd);
}
/** /**
* ice_get_link_speed_based_on_phy_type - returns link speed * ice_get_link_speed_based_on_phy_type - returns link speed
* @phy_type_low: lower part of phy_type * @phy_type_low: lower part of phy_type
......
...@@ -85,6 +85,9 @@ int ...@@ -85,6 +85,9 @@ int
ice_aq_send_driver_ver(struct ice_hw *hw, struct ice_driver_ver *dv, ice_aq_send_driver_ver(struct ice_hw *hw, struct ice_driver_ver *dv,
struct ice_sq_cd *cd); struct ice_sq_cd *cd);
int int
ice_aq_set_port_params(struct ice_port_info *pi, bool double_vlan,
struct ice_sq_cd *cd);
int
ice_aq_get_phy_caps(struct ice_port_info *pi, bool qual_mods, u8 report_mode, ice_aq_get_phy_caps(struct ice_port_info *pi, bool qual_mods, u8 report_mode,
struct ice_aqc_get_phy_caps_data *caps, struct ice_aqc_get_phy_caps_data *caps,
struct ice_sq_cd *cd); struct ice_sq_cd *cd);
......
...@@ -89,6 +89,12 @@ ice_init_prof_result_bm(struct ice_hw *hw); ...@@ -89,6 +89,12 @@ ice_init_prof_result_bm(struct ice_hw *hw);
int int
ice_get_sw_fv_list(struct ice_hw *hw, u8 *prot_ids, u16 ids_cnt, ice_get_sw_fv_list(struct ice_hw *hw, u8 *prot_ids, u16 ids_cnt,
unsigned long *bm, struct list_head *fv_list); unsigned long *bm, struct list_head *fv_list);
int
ice_pkg_buf_unreserve_section(struct ice_buf_build *bld, u16 count);
u16 ice_pkg_buf_get_free_space(struct ice_buf_build *bld);
int
ice_aq_upload_section(struct ice_hw *hw, struct ice_buf_hdr *pkg_buf,
u16 buf_size, struct ice_sq_cd *cd);
bool bool
ice_get_open_tunnel_port(struct ice_hw *hw, u16 *port, ice_get_open_tunnel_port(struct ice_hw *hw, u16 *port,
enum ice_tunnel_type type); enum ice_tunnel_type type);
...@@ -96,6 +102,7 @@ int ice_udp_tunnel_set_port(struct net_device *netdev, unsigned int table, ...@@ -96,6 +102,7 @@ int ice_udp_tunnel_set_port(struct net_device *netdev, unsigned int table,
unsigned int idx, struct udp_tunnel_info *ti); unsigned int idx, struct udp_tunnel_info *ti);
int ice_udp_tunnel_unset_port(struct net_device *netdev, unsigned int table, int ice_udp_tunnel_unset_port(struct net_device *netdev, unsigned int table,
unsigned int idx, struct udp_tunnel_info *ti); unsigned int idx, struct udp_tunnel_info *ti);
int ice_set_dvm_boost_entries(struct ice_hw *hw);
/* Rx parser PTYPE functions */ /* Rx parser PTYPE functions */
bool ice_hw_ptype_ena(struct ice_hw *hw, u16 ptype); bool ice_hw_ptype_ena(struct ice_hw *hw, u16 ptype);
...@@ -119,4 +126,10 @@ void ice_fill_blk_tbls(struct ice_hw *hw); ...@@ -119,4 +126,10 @@ void ice_fill_blk_tbls(struct ice_hw *hw);
void ice_clear_hw_tbls(struct ice_hw *hw); void ice_clear_hw_tbls(struct ice_hw *hw);
void ice_free_hw_tbls(struct ice_hw *hw); void ice_free_hw_tbls(struct ice_hw *hw);
int ice_rem_prof(struct ice_hw *hw, enum ice_block blk, u64 id); int ice_rem_prof(struct ice_hw *hw, enum ice_block blk, u64 id);
struct ice_buf_build *
ice_pkg_buf_alloc_single_section(struct ice_hw *hw, u32 type, u16 size,
void **section);
struct ice_buf *ice_pkg_buf(struct ice_buf_build *bld);
void ice_pkg_buf_free(struct ice_hw *hw, struct ice_buf_build *bld);
#endif /* _ICE_FLEX_PIPE_H_ */ #endif /* _ICE_FLEX_PIPE_H_ */
...@@ -162,6 +162,7 @@ struct ice_meta_sect { ...@@ -162,6 +162,7 @@ struct ice_meta_sect {
#define ICE_SID_RXPARSER_MARKER_PTYPE 55 #define ICE_SID_RXPARSER_MARKER_PTYPE 55
#define ICE_SID_RXPARSER_BOOST_TCAM 56 #define ICE_SID_RXPARSER_BOOST_TCAM 56
#define ICE_SID_RXPARSER_METADATA_INIT 58
#define ICE_SID_TXPARSER_BOOST_TCAM 66 #define ICE_SID_TXPARSER_BOOST_TCAM 66
#define ICE_SID_XLT0_PE 80 #define ICE_SID_XLT0_PE 80
...@@ -442,6 +443,19 @@ struct ice_tunnel_table { ...@@ -442,6 +443,19 @@ struct ice_tunnel_table {
u16 valid_count[__TNL_TYPE_CNT]; u16 valid_count[__TNL_TYPE_CNT];
}; };
struct ice_dvm_entry {
u16 boost_addr;
u16 enable;
struct ice_boost_tcam_entry *boost_entry;
};
#define ICE_DVM_MAX_ENTRIES 48
struct ice_dvm_table {
struct ice_dvm_entry tbl[ICE_DVM_MAX_ENTRIES];
u16 count;
};
struct ice_pkg_es { struct ice_pkg_es {
__le16 count; __le16 count;
__le16 offset; __le16 offset;
...@@ -662,4 +676,30 @@ enum ice_prof_type { ...@@ -662,4 +676,30 @@ enum ice_prof_type {
ICE_PROF_TUN_ALL = 0x6, ICE_PROF_TUN_ALL = 0x6,
ICE_PROF_ALL = 0xFF, ICE_PROF_ALL = 0xFF,
}; };
/* Number of bits/bytes contained in meta init entry. Note, this should be a
* multiple of 32 bits.
*/
#define ICE_META_INIT_BITS 192
#define ICE_META_INIT_DW_CNT (ICE_META_INIT_BITS / (sizeof(__le32) * \
BITS_PER_BYTE))
/* The meta init Flag field starts at this bit */
#define ICE_META_FLAGS_ST 123
/* The entry and bit to check for Double VLAN Mode (DVM) support */
#define ICE_META_VLAN_MODE_ENTRY 0
#define ICE_META_FLAG_VLAN_MODE 60
#define ICE_META_VLAN_MODE_BIT (ICE_META_FLAGS_ST + \
ICE_META_FLAG_VLAN_MODE)
struct ice_meta_init_entry {
__le32 bm[ICE_META_INIT_DW_CNT];
};
struct ice_meta_init_section {
__le16 count;
__le16 offset;
struct ice_meta_init_entry entry;
};
#endif /* _ICE_FLEX_TYPE_H_ */ #endif /* _ICE_FLEX_TYPE_H_ */
...@@ -3547,12 +3547,17 @@ static int ice_tc_indir_block_register(struct ice_vsi *vsi) ...@@ -3547,12 +3547,17 @@ static int ice_tc_indir_block_register(struct ice_vsi *vsi)
static int ice_setup_pf_sw(struct ice_pf *pf) static int ice_setup_pf_sw(struct ice_pf *pf)
{ {
struct device *dev = ice_pf_to_dev(pf); struct device *dev = ice_pf_to_dev(pf);
bool dvm = ice_is_dvm_ena(&pf->hw);
struct ice_vsi *vsi; struct ice_vsi *vsi;
int status; int status;
if (ice_is_reset_in_progress(pf->state)) if (ice_is_reset_in_progress(pf->state))
return -EBUSY; return -EBUSY;
status = ice_aq_set_port_params(pf->hw.port_info, dvm, NULL);
if (status)
return -EIO;
vsi = ice_pf_vsi_setup(pf, pf->hw.port_info); vsi = ice_pf_vsi_setup(pf, pf->hw.port_info);
if (!vsi) if (!vsi)
return -ENOMEM; return -ENOMEM;
...@@ -6634,6 +6639,7 @@ static void ice_rebuild(struct ice_pf *pf, enum ice_reset_req reset_type) ...@@ -6634,6 +6639,7 @@ static void ice_rebuild(struct ice_pf *pf, enum ice_reset_req reset_type)
{ {
struct device *dev = ice_pf_to_dev(pf); struct device *dev = ice_pf_to_dev(pf);
struct ice_hw *hw = &pf->hw; struct ice_hw *hw = &pf->hw;
bool dvm;
int err; int err;
if (test_bit(ICE_DOWN, pf->state)) if (test_bit(ICE_DOWN, pf->state))
...@@ -6697,6 +6703,12 @@ static void ice_rebuild(struct ice_pf *pf, enum ice_reset_req reset_type) ...@@ -6697,6 +6703,12 @@ static void ice_rebuild(struct ice_pf *pf, enum ice_reset_req reset_type)
goto err_init_ctrlq; goto err_init_ctrlq;
} }
dvm = ice_is_dvm_ena(hw);
err = ice_aq_set_port_params(pf->hw.port_info, dvm, NULL);
if (err)
goto err_init_ctrlq;
err = ice_sched_init_port(hw->port_info); err = ice_sched_init_port(hw->port_info);
if (err) if (err)
goto err_sched_init_port; goto err_sched_init_port;
......
...@@ -3,6 +3,7 @@ ...@@ -3,6 +3,7 @@
#include "ice_vsi_vlan_ops.h" #include "ice_vsi_vlan_ops.h"
#include "ice_vsi_vlan_lib.h" #include "ice_vsi_vlan_lib.h"
#include "ice_vlan_mode.h"
#include "ice.h" #include "ice.h"
#include "ice_pf_vsi_vlan_ops.h" #include "ice_pf_vsi_vlan_ops.h"
......
...@@ -1096,6 +1096,64 @@ ice_aq_get_recipe(struct ice_hw *hw, ...@@ -1096,6 +1096,64 @@ ice_aq_get_recipe(struct ice_hw *hw,
return status; return status;
} }
/**
* ice_update_recipe_lkup_idx - update a default recipe based on the lkup_idx
* @hw: pointer to the HW struct
* @params: parameters used to update the default recipe
*
* This function only supports updating default recipes and it only supports
* updating a single recipe based on the lkup_idx at a time.
*
* This is done as a read-modify-write operation. First, get the current recipe
* contents based on the recipe's ID. Then modify the field vector index and
* mask if it's valid at the lkup_idx. Finally, use the add recipe AQ to update
* the pre-existing recipe with the modifications.
*/
int
ice_update_recipe_lkup_idx(struct ice_hw *hw,
struct ice_update_recipe_lkup_idx_params *params)
{
struct ice_aqc_recipe_data_elem *rcp_list;
u16 num_recps = ICE_MAX_NUM_RECIPES;
int status;
rcp_list = kcalloc(num_recps, sizeof(*rcp_list), GFP_KERNEL);
if (!rcp_list)
return -ENOMEM;
/* read current recipe list from firmware */
rcp_list->recipe_indx = params->rid;
status = ice_aq_get_recipe(hw, rcp_list, &num_recps, params->rid, NULL);
if (status) {
ice_debug(hw, ICE_DBG_SW, "Failed to get recipe %d, status %d\n",
params->rid, status);
goto error_out;
}
/* only modify existing recipe's lkup_idx and mask if valid, while
* leaving all other fields the same, then update the recipe firmware
*/
rcp_list->content.lkup_indx[params->lkup_idx] = params->fv_idx;
if (params->mask_valid)
rcp_list->content.mask[params->lkup_idx] =
cpu_to_le16(params->mask);
if (params->ignore_valid)
rcp_list->content.lkup_indx[params->lkup_idx] |=
ICE_AQ_RECIPE_LKUP_IGNORE;
status = ice_aq_add_recipe(hw, &rcp_list[0], 1, NULL);
if (status)
ice_debug(hw, ICE_DBG_SW, "Failed to update recipe %d lkup_idx %d fv_idx %d mask %d mask_valid %s, status %d\n",
params->rid, params->lkup_idx, params->fv_idx,
params->mask, params->mask_valid ? "true" : "false",
status);
error_out:
kfree(rcp_list);
return status;
}
/** /**
* ice_aq_map_recipe_to_profile - Map recipe to packet profile * ice_aq_map_recipe_to_profile - Map recipe to packet profile
* @hw: pointer to the HW struct * @hw: pointer to the HW struct
...@@ -3872,6 +3930,23 @@ ice_find_recp(struct ice_hw *hw, struct ice_prot_lkup_ext *lkup_exts, ...@@ -3872,6 +3930,23 @@ ice_find_recp(struct ice_hw *hw, struct ice_prot_lkup_ext *lkup_exts,
return ICE_MAX_NUM_RECIPES; return ICE_MAX_NUM_RECIPES;
} }
/**
* ice_change_proto_id_to_dvm - change proto id in prot_id_tbl
*
* As protocol id for outer vlan is different in dvm and svm, if dvm is
* supported protocol array record for outer vlan has to be modified to
* reflect the value proper for DVM.
*/
void ice_change_proto_id_to_dvm(void)
{
u8 i;
for (i = 0; i < ARRAY_SIZE(ice_prot_id_tbl); i++)
if (ice_prot_id_tbl[i].type == ICE_VLAN_OFOS &&
ice_prot_id_tbl[i].protocol_id != ICE_VLAN_OF_HW)
ice_prot_id_tbl[i].protocol_id = ICE_VLAN_OF_HW;
}
/** /**
* ice_prot_type_to_id - get protocol ID from protocol type * ice_prot_type_to_id - get protocol ID from protocol type
* @type: protocol type * @type: protocol type
......
...@@ -118,6 +118,15 @@ struct ice_fltr_info { ...@@ -118,6 +118,15 @@ struct ice_fltr_info {
u8 lan_en; /* Indicate if packet can be forwarded to the uplink */ u8 lan_en; /* Indicate if packet can be forwarded to the uplink */
}; };
struct ice_update_recipe_lkup_idx_params {
u16 rid;
u16 fv_idx;
bool ignore_valid;
u16 mask;
bool mask_valid;
u8 lkup_idx;
};
struct ice_adv_lkup_elem { struct ice_adv_lkup_elem {
enum ice_protocol_type type; enum ice_protocol_type type;
union ice_prot_hdr h_u; /* Header values */ union ice_prot_hdr h_u; /* Header values */
...@@ -360,4 +369,8 @@ void ice_rm_all_sw_replay_rule_info(struct ice_hw *hw); ...@@ -360,4 +369,8 @@ void ice_rm_all_sw_replay_rule_info(struct ice_hw *hw);
int int
ice_aq_sw_rules(struct ice_hw *hw, void *rule_list, u16 rule_list_sz, ice_aq_sw_rules(struct ice_hw *hw, void *rule_list, u16 rule_list_sz,
u8 num_rules, enum ice_adminq_opc opc, struct ice_sq_cd *cd); u8 num_rules, enum ice_adminq_opc opc, struct ice_sq_cd *cd);
int
ice_update_recipe_lkup_idx(struct ice_hw *hw,
struct ice_update_recipe_lkup_idx_params *params);
void ice_change_proto_id_to_dvm(void);
#endif /* _ICE_SWITCH_H_ */ #endif /* _ICE_SWITCH_H_ */
...@@ -15,6 +15,7 @@ ...@@ -15,6 +15,7 @@
#include "ice_flex_type.h" #include "ice_flex_type.h"
#include "ice_protocol_type.h" #include "ice_protocol_type.h"
#include "ice_sbq_cmd.h" #include "ice_sbq_cmd.h"
#include "ice_vlan_mode.h"
static inline bool ice_is_tc_ena(unsigned long bitmap, u8 tc) static inline bool ice_is_tc_ena(unsigned long bitmap, u8 tc)
{ {
...@@ -54,6 +55,11 @@ static inline u32 ice_round_to_num(u32 N, u32 R) ...@@ -54,6 +55,11 @@ static inline u32 ice_round_to_num(u32 N, u32 R)
#define ICE_DBG_AQ_DESC BIT_ULL(25) #define ICE_DBG_AQ_DESC BIT_ULL(25)
#define ICE_DBG_AQ_DESC_BUF BIT_ULL(26) #define ICE_DBG_AQ_DESC_BUF BIT_ULL(26)
#define ICE_DBG_AQ_CMD BIT_ULL(27) #define ICE_DBG_AQ_CMD BIT_ULL(27)
#define ICE_DBG_AQ (ICE_DBG_AQ_MSG | \
ICE_DBG_AQ_DESC | \
ICE_DBG_AQ_DESC_BUF | \
ICE_DBG_AQ_CMD)
#define ICE_DBG_USER BIT_ULL(31) #define ICE_DBG_USER BIT_ULL(31)
enum ice_aq_res_ids { enum ice_aq_res_ids {
...@@ -920,6 +926,9 @@ struct ice_hw { ...@@ -920,6 +926,9 @@ struct ice_hw {
struct udp_tunnel_nic_shared udp_tunnel_shared; struct udp_tunnel_nic_shared udp_tunnel_shared;
struct udp_tunnel_nic_info udp_tunnel_nic; struct udp_tunnel_nic_info udp_tunnel_nic;
/* dvm boost update information */
struct ice_dvm_table dvm_upd;
/* HW block tables */ /* HW block tables */
struct ice_blk_info blk[ICE_BLK_COUNT]; struct ice_blk_info blk[ICE_BLK_COUNT];
struct mutex fl_profs_locks[ICE_BLK_COUNT]; /* lock fltr profiles */ struct mutex fl_profs_locks[ICE_BLK_COUNT]; /* lock fltr profiles */
...@@ -943,6 +952,7 @@ struct ice_hw { ...@@ -943,6 +952,7 @@ struct ice_hw {
struct list_head rss_list_head; struct list_head rss_list_head;
struct ice_mbx_snapshot mbx_snapshot; struct ice_mbx_snapshot mbx_snapshot;
DECLARE_BITMAP(hw_ptype, ICE_FLOW_PTYPE_MAX); DECLARE_BITMAP(hw_ptype, ICE_FLOW_PTYPE_MAX);
u8 dvm_ena;
u16 io_expander_handle; u16 io_expander_handle;
}; };
......
...@@ -3,6 +3,7 @@ ...@@ -3,6 +3,7 @@
#include "ice_vsi_vlan_ops.h" #include "ice_vsi_vlan_ops.h"
#include "ice_vsi_vlan_lib.h" #include "ice_vsi_vlan_lib.h"
#include "ice_vlan_mode.h"
#include "ice.h" #include "ice.h"
#include "ice_vf_vsi_vlan_ops.h" #include "ice_vf_vsi_vlan_ops.h"
#include "ice_virtchnl_pf.h" #include "ice_virtchnl_pf.h"
......
This diff is collapsed.
/* SPDX-License-Identifier: GPL-2.0 */
/* Copyright (C) 2019-2021, Intel Corporation. */
#ifndef _ICE_VLAN_MODE_H_
#define _ICE_VLAN_MODE_H_
struct ice_hw;
bool ice_is_dvm_ena(struct ice_hw *hw);
int ice_set_vlan_mode(struct ice_hw *hw);
void ice_post_pkg_dwnld_vlan_mode_cfg(struct ice_hw *hw);
#endif /* _ICE_VLAN_MODE_H */
...@@ -39,20 +39,20 @@ static bool validate_vlan(struct ice_vsi *vsi, struct ice_vlan *vlan) ...@@ -39,20 +39,20 @@ static bool validate_vlan(struct ice_vsi *vsi, struct ice_vlan *vlan)
*/ */
int ice_vsi_add_vlan(struct ice_vsi *vsi, struct ice_vlan *vlan) int ice_vsi_add_vlan(struct ice_vsi *vsi, struct ice_vlan *vlan)
{ {
int err = 0; int err;
if (!validate_vlan(vsi, vlan)) if (!validate_vlan(vsi, vlan))
return -EINVAL; return -EINVAL;
if (!ice_fltr_add_vlan(vsi, vlan)) { err = ice_fltr_add_vlan(vsi, vlan);
vsi->num_vlan++; if (err && err != -EEXIST) {
} else { dev_err(ice_pf_to_dev(vsi->back), "Failure Adding VLAN %d on VSI %i, status %d\n",
err = -ENODEV; vlan->vid, vsi->vsi_num, err);
dev_err(ice_pf_to_dev(vsi->back), "Failure Adding VLAN %d on VSI %i\n", return err;
vlan->vid, vsi->vsi_num);
} }
return err; vsi->num_vlan++;
return 0;
} }
/** /**
...@@ -72,16 +72,13 @@ int ice_vsi_del_vlan(struct ice_vsi *vsi, struct ice_vlan *vlan) ...@@ -72,16 +72,13 @@ int ice_vsi_del_vlan(struct ice_vsi *vsi, struct ice_vlan *vlan)
dev = ice_pf_to_dev(pf); dev = ice_pf_to_dev(pf);
err = ice_fltr_remove_vlan(vsi, vlan); err = ice_fltr_remove_vlan(vsi, vlan);
if (!err) { if (!err)
vsi->num_vlan--; vsi->num_vlan--;
} else if (err == -ENOENT) { else if (err == -ENOENT || err == -EBUSY)
dev_dbg(dev, "Failed to remove VLAN %d on VSI %i, it does not exist\n",
vlan->vid, vsi->vsi_num);
err = 0; err = 0;
} else { else
dev_err(dev, "Error removing VLAN %d on VSI %i error: %d\n", dev_err(dev, "Error removing VLAN %d on VSI %i error: %d\n",
vlan->vid, vsi->vsi_num, err); vlan->vid, vsi->vsi_num, err);
}
return err; return err;
} }
......
...@@ -23,11 +23,6 @@ struct ice_vsi_vlan_ops { ...@@ -23,11 +23,6 @@ struct ice_vsi_vlan_ops {
int (*set_port_vlan)(struct ice_vsi *vsi, struct ice_vlan *vlan); int (*set_port_vlan)(struct ice_vsi *vsi, struct ice_vlan *vlan);
}; };
static inline bool ice_is_dvm_ena(struct ice_hw __always_unused *hw)
{
return false;
}
void ice_vsi_init_vlan_ops(struct ice_vsi *vsi); void ice_vsi_init_vlan_ops(struct ice_vsi *vsi);
struct ice_vsi_vlan_ops *ice_get_compat_vsi_vlan_ops(struct ice_vsi *vsi); struct ice_vsi_vlan_ops *ice_get_compat_vsi_vlan_ops(struct ice_vsi *vsi);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment