forked from mirrors/linux
		
	ice: Refactor status flow for DDP load
Before this change, final state of the DDP pkg load process was dependent on many variables such as: ice_status, pkg version, ice_aq_err. The last one had be stored in hw->pkg_dwnld_status. It was impossible to conclude this state just from ice_status, that's why logging process of DDP pkg load in the caller was a little bit complicated. With this patch new status enum is introduced - ice_ddp_state. It covers all the possible final states of the loading process. What's tricky for ice_ddp_state is that not only ICE_DDP_PKG_SUCCESS(=0) means that load was successful. Actually three states mean that: - ICE_DDP_PKG_SUCCESS - ICE_DDP_PKG_SAME_VERSION_ALREADY_LOADED - ICE_DDP_PKG_COMPATIBLE_ALREADY_LOADED ice_is_init_pkg_successful can tell that information. One ddp_state should not be used outside of ice_init_pkg which is ICE_DDP_PKG_ALREADY_LOADED. It is more generic, it is used in ice_dwnld_cfg_bufs to see if pkg is already loaded. At this point we can't use one of the specific one (SAME_VERSION, COMPATIBLE, NOT_SUPPORTED) because we don't have information on the package currently loaded in HW (we are before calling ice_get_pkg_info). We can get rid of hw->pkg_dwnld_status because we are immediately mapping aq errors to ice_ddp_state in ice_dwnld_cfg_bufs. Other errors like ICE_ERR_NO_MEMORY, ICE_ERR_PARAM are mapped the generic ICE_DDP_PKG_ERR. Suggested-by: Jacob Keller <jacob.e.keller@intel.com> Signed-off-by: Wojciech Drewek <wojciech.drewek@intel.com> Tested-by: Tony Brelinski <tony.brelinski@intel.com> Signed-off-by: Tony Nguyen <anthony.l.nguyen@intel.com>
This commit is contained in:
		
							parent
							
								
									fabf480bf9
								
							
						
					
					
						commit
						247dd97d71
					
				
					 4 changed files with 272 additions and 182 deletions
				
			
		| 
						 | 
					@ -993,6 +993,22 @@ ice_update_pkg(struct ice_hw *hw, struct ice_buf *bufs, u32 count)
 | 
				
			||||||
	return status;
 | 
						return status;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static enum ice_ddp_state ice_map_aq_err_to_ddp_state(enum ice_aq_err aq_err)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						switch (aq_err) {
 | 
				
			||||||
 | 
						case ICE_AQ_RC_ENOSEC:
 | 
				
			||||||
 | 
						case ICE_AQ_RC_EBADSIG:
 | 
				
			||||||
 | 
							return ICE_DDP_PKG_FILE_SIGNATURE_INVALID;
 | 
				
			||||||
 | 
						case ICE_AQ_RC_ESVN:
 | 
				
			||||||
 | 
							return ICE_DDP_PKG_FILE_REVISION_TOO_LOW;
 | 
				
			||||||
 | 
						case ICE_AQ_RC_EBADMAN:
 | 
				
			||||||
 | 
						case ICE_AQ_RC_EBADBUF:
 | 
				
			||||||
 | 
							return ICE_DDP_PKG_LOAD_ERROR;
 | 
				
			||||||
 | 
						default:
 | 
				
			||||||
 | 
							return ICE_DDP_PKG_ERR;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/**
 | 
					/**
 | 
				
			||||||
 * ice_dwnld_cfg_bufs
 | 
					 * ice_dwnld_cfg_bufs
 | 
				
			||||||
 * @hw: pointer to the hardware structure
 | 
					 * @hw: pointer to the hardware structure
 | 
				
			||||||
| 
						 | 
					@ -1003,15 +1019,17 @@ ice_update_pkg(struct ice_hw *hw, struct ice_buf *bufs, u32 count)
 | 
				
			||||||
 * to the firmware. Metadata buffers are skipped, and the first metadata buffer
 | 
					 * to the firmware. Metadata buffers are skipped, and the first metadata buffer
 | 
				
			||||||
 * found indicates that the rest of the buffers are all metadata buffers.
 | 
					 * found indicates that the rest of the buffers are all metadata buffers.
 | 
				
			||||||
 */
 | 
					 */
 | 
				
			||||||
static enum ice_status
 | 
					static enum ice_ddp_state
 | 
				
			||||||
ice_dwnld_cfg_bufs(struct ice_hw *hw, struct ice_buf *bufs, u32 count)
 | 
					ice_dwnld_cfg_bufs(struct ice_hw *hw, struct ice_buf *bufs, u32 count)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
 | 
						enum ice_ddp_state state = ICE_DDP_PKG_SUCCESS;
 | 
				
			||||||
	enum ice_status status;
 | 
						enum ice_status status;
 | 
				
			||||||
	struct ice_buf_hdr *bh;
 | 
						struct ice_buf_hdr *bh;
 | 
				
			||||||
 | 
						enum ice_aq_err err;
 | 
				
			||||||
	u32 offset, info, i;
 | 
						u32 offset, info, i;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (!bufs || !count)
 | 
						if (!bufs || !count)
 | 
				
			||||||
		return ICE_ERR_PARAM;
 | 
							return ICE_DDP_PKG_ERR;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/* If the first buffer's first section has its metadata bit set
 | 
						/* If the first buffer's first section has its metadata bit set
 | 
				
			||||||
	 * then there are no buffers to be downloaded, and the operation is
 | 
						 * then there are no buffers to be downloaded, and the operation is
 | 
				
			||||||
| 
						 | 
					@ -1019,20 +1037,13 @@ ice_dwnld_cfg_bufs(struct ice_hw *hw, struct ice_buf *bufs, u32 count)
 | 
				
			||||||
	 */
 | 
						 */
 | 
				
			||||||
	bh = (struct ice_buf_hdr *)bufs;
 | 
						bh = (struct ice_buf_hdr *)bufs;
 | 
				
			||||||
	if (le32_to_cpu(bh->section_entry[0].type) & ICE_METADATA_BUF)
 | 
						if (le32_to_cpu(bh->section_entry[0].type) & ICE_METADATA_BUF)
 | 
				
			||||||
		return 0;
 | 
							return ICE_DDP_PKG_SUCCESS;
 | 
				
			||||||
 | 
					 | 
				
			||||||
	/* reset pkg_dwnld_status in case this function is called in the
 | 
					 | 
				
			||||||
	 * reset/rebuild flow
 | 
					 | 
				
			||||||
	 */
 | 
					 | 
				
			||||||
	hw->pkg_dwnld_status = ICE_AQ_RC_OK;
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
	status = ice_acquire_global_cfg_lock(hw, ICE_RES_WRITE);
 | 
						status = ice_acquire_global_cfg_lock(hw, ICE_RES_WRITE);
 | 
				
			||||||
	if (status) {
 | 
						if (status) {
 | 
				
			||||||
		if (status == ICE_ERR_AQ_NO_WORK)
 | 
							if (status == ICE_ERR_AQ_NO_WORK)
 | 
				
			||||||
			hw->pkg_dwnld_status = ICE_AQ_RC_EEXIST;
 | 
								return ICE_DDP_PKG_ALREADY_LOADED;
 | 
				
			||||||
		else
 | 
							return ice_map_aq_err_to_ddp_state(hw->adminq.sq_last_status);
 | 
				
			||||||
			hw->pkg_dwnld_status = hw->adminq.sq_last_status;
 | 
					 | 
				
			||||||
		return status;
 | 
					 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	for (i = 0; i < count; i++) {
 | 
						for (i = 0; i < count; i++) {
 | 
				
			||||||
| 
						 | 
					@ -1058,11 +1069,11 @@ ice_dwnld_cfg_bufs(struct ice_hw *hw, struct ice_buf *bufs, u32 count)
 | 
				
			||||||
					     &offset, &info, NULL);
 | 
										     &offset, &info, NULL);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		/* Save AQ status from download package */
 | 
							/* Save AQ status from download package */
 | 
				
			||||||
		hw->pkg_dwnld_status = hw->adminq.sq_last_status;
 | 
					 | 
				
			||||||
		if (status) {
 | 
							if (status) {
 | 
				
			||||||
			ice_debug(hw, ICE_DBG_PKG, "Pkg download failed: err %d off %d inf %d\n",
 | 
								ice_debug(hw, ICE_DBG_PKG, "Pkg download failed: err %d off %d inf %d\n",
 | 
				
			||||||
				  status, offset, info);
 | 
									  status, offset, info);
 | 
				
			||||||
 | 
								err = hw->adminq.sq_last_status;
 | 
				
			||||||
 | 
								state = ice_map_aq_err_to_ddp_state(err);
 | 
				
			||||||
			break;
 | 
								break;
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1072,7 +1083,7 @@ ice_dwnld_cfg_bufs(struct ice_hw *hw, struct ice_buf *bufs, u32 count)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	ice_release_global_cfg_lock(hw);
 | 
						ice_release_global_cfg_lock(hw);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	return status;
 | 
						return state;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/**
 | 
					/**
 | 
				
			||||||
| 
						 | 
					@ -1103,7 +1114,7 @@ ice_aq_get_pkg_info_list(struct ice_hw *hw,
 | 
				
			||||||
 *
 | 
					 *
 | 
				
			||||||
 * Handles the download of a complete package.
 | 
					 * Handles the download of a complete package.
 | 
				
			||||||
 */
 | 
					 */
 | 
				
			||||||
static enum ice_status
 | 
					static enum ice_ddp_state
 | 
				
			||||||
ice_download_pkg(struct ice_hw *hw, struct ice_seg *ice_seg)
 | 
					ice_download_pkg(struct ice_hw *hw, struct ice_seg *ice_seg)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	struct ice_buf_table *ice_buf_tbl;
 | 
						struct ice_buf_table *ice_buf_tbl;
 | 
				
			||||||
| 
						 | 
					@ -1134,13 +1145,13 @@ ice_download_pkg(struct ice_hw *hw, struct ice_seg *ice_seg)
 | 
				
			||||||
 *
 | 
					 *
 | 
				
			||||||
 * Saves off the package details into the HW structure.
 | 
					 * Saves off the package details into the HW structure.
 | 
				
			||||||
 */
 | 
					 */
 | 
				
			||||||
static enum ice_status
 | 
					static enum ice_ddp_state
 | 
				
			||||||
ice_init_pkg_info(struct ice_hw *hw, struct ice_pkg_hdr *pkg_hdr)
 | 
					ice_init_pkg_info(struct ice_hw *hw, struct ice_pkg_hdr *pkg_hdr)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	struct ice_generic_seg_hdr *seg_hdr;
 | 
						struct ice_generic_seg_hdr *seg_hdr;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (!pkg_hdr)
 | 
						if (!pkg_hdr)
 | 
				
			||||||
		return ICE_ERR_PARAM;
 | 
							return ICE_DDP_PKG_ERR;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	seg_hdr = ice_find_seg_in_pkg(hw, SEGMENT_TYPE_ICE, pkg_hdr);
 | 
						seg_hdr = ice_find_seg_in_pkg(hw, SEGMENT_TYPE_ICE, pkg_hdr);
 | 
				
			||||||
	if (seg_hdr) {
 | 
						if (seg_hdr) {
 | 
				
			||||||
| 
						 | 
					@ -1154,7 +1165,7 @@ ice_init_pkg_info(struct ice_hw *hw, struct ice_pkg_hdr *pkg_hdr)
 | 
				
			||||||
					    ICE_SID_METADATA);
 | 
										    ICE_SID_METADATA);
 | 
				
			||||||
		if (!meta) {
 | 
							if (!meta) {
 | 
				
			||||||
			ice_debug(hw, ICE_DBG_INIT, "Did not find ice metadata section in package\n");
 | 
								ice_debug(hw, ICE_DBG_INIT, "Did not find ice metadata section in package\n");
 | 
				
			||||||
			return ICE_ERR_CFG;
 | 
								return ICE_DDP_PKG_INVALID_FILE;
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		hw->pkg_ver = meta->ver;
 | 
							hw->pkg_ver = meta->ver;
 | 
				
			||||||
| 
						 | 
					@ -1176,10 +1187,10 @@ ice_init_pkg_info(struct ice_hw *hw, struct ice_pkg_hdr *pkg_hdr)
 | 
				
			||||||
			  seg_hdr->seg_id);
 | 
								  seg_hdr->seg_id);
 | 
				
			||||||
	} else {
 | 
						} else {
 | 
				
			||||||
		ice_debug(hw, ICE_DBG_INIT, "Did not find ice segment in driver package\n");
 | 
							ice_debug(hw, ICE_DBG_INIT, "Did not find ice segment in driver package\n");
 | 
				
			||||||
		return ICE_ERR_CFG;
 | 
							return ICE_DDP_PKG_INVALID_FILE;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	return 0;
 | 
						return ICE_DDP_PKG_SUCCESS;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/**
 | 
					/**
 | 
				
			||||||
| 
						 | 
					@ -1188,21 +1199,22 @@ ice_init_pkg_info(struct ice_hw *hw, struct ice_pkg_hdr *pkg_hdr)
 | 
				
			||||||
 *
 | 
					 *
 | 
				
			||||||
 * Store details of the package currently loaded in HW into the HW structure.
 | 
					 * Store details of the package currently loaded in HW into the HW structure.
 | 
				
			||||||
 */
 | 
					 */
 | 
				
			||||||
static enum ice_status ice_get_pkg_info(struct ice_hw *hw)
 | 
					static enum ice_ddp_state ice_get_pkg_info(struct ice_hw *hw)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
 | 
						enum ice_ddp_state state = ICE_DDP_PKG_SUCCESS;
 | 
				
			||||||
	struct ice_aqc_get_pkg_info_resp *pkg_info;
 | 
						struct ice_aqc_get_pkg_info_resp *pkg_info;
 | 
				
			||||||
	enum ice_status status;
 | 
					 | 
				
			||||||
	u16 size;
 | 
						u16 size;
 | 
				
			||||||
	u32 i;
 | 
						u32 i;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	size = struct_size(pkg_info, pkg_info, ICE_PKG_CNT);
 | 
						size = struct_size(pkg_info, pkg_info, ICE_PKG_CNT);
 | 
				
			||||||
	pkg_info = kzalloc(size, GFP_KERNEL);
 | 
						pkg_info = kzalloc(size, GFP_KERNEL);
 | 
				
			||||||
	if (!pkg_info)
 | 
						if (!pkg_info)
 | 
				
			||||||
		return ICE_ERR_NO_MEMORY;
 | 
							return ICE_DDP_PKG_ERR;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	status = ice_aq_get_pkg_info_list(hw, pkg_info, size, NULL);
 | 
						if (ice_aq_get_pkg_info_list(hw, pkg_info, size, NULL)) {
 | 
				
			||||||
	if (status)
 | 
							state = ICE_DDP_PKG_ERR;
 | 
				
			||||||
		goto init_pkg_free_alloc;
 | 
							goto init_pkg_free_alloc;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	for (i = 0; i < le32_to_cpu(pkg_info->count); i++) {
 | 
						for (i = 0; i < le32_to_cpu(pkg_info->count); i++) {
 | 
				
			||||||
#define ICE_PKG_FLAG_COUNT	4
 | 
					#define ICE_PKG_FLAG_COUNT	4
 | 
				
			||||||
| 
						 | 
					@ -1237,7 +1249,7 @@ static enum ice_status ice_get_pkg_info(struct ice_hw *hw)
 | 
				
			||||||
init_pkg_free_alloc:
 | 
					init_pkg_free_alloc:
 | 
				
			||||||
	kfree(pkg_info);
 | 
						kfree(pkg_info);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	return status;
 | 
						return state;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/**
 | 
					/**
 | 
				
			||||||
| 
						 | 
					@ -1248,28 +1260,28 @@ static enum ice_status ice_get_pkg_info(struct ice_hw *hw)
 | 
				
			||||||
 * Verifies various attributes of the package file, including length, format
 | 
					 * Verifies various attributes of the package file, including length, format
 | 
				
			||||||
 * version, and the requirement of at least one segment.
 | 
					 * version, and the requirement of at least one segment.
 | 
				
			||||||
 */
 | 
					 */
 | 
				
			||||||
static enum ice_status ice_verify_pkg(struct ice_pkg_hdr *pkg, u32 len)
 | 
					static enum ice_ddp_state ice_verify_pkg(struct ice_pkg_hdr *pkg, u32 len)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	u32 seg_count;
 | 
						u32 seg_count;
 | 
				
			||||||
	u32 i;
 | 
						u32 i;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (len < struct_size(pkg, seg_offset, 1))
 | 
						if (len < struct_size(pkg, seg_offset, 1))
 | 
				
			||||||
		return ICE_ERR_BUF_TOO_SHORT;
 | 
							return ICE_DDP_PKG_INVALID_FILE;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (pkg->pkg_format_ver.major != ICE_PKG_FMT_VER_MAJ ||
 | 
						if (pkg->pkg_format_ver.major != ICE_PKG_FMT_VER_MAJ ||
 | 
				
			||||||
	    pkg->pkg_format_ver.minor != ICE_PKG_FMT_VER_MNR ||
 | 
						    pkg->pkg_format_ver.minor != ICE_PKG_FMT_VER_MNR ||
 | 
				
			||||||
	    pkg->pkg_format_ver.update != ICE_PKG_FMT_VER_UPD ||
 | 
						    pkg->pkg_format_ver.update != ICE_PKG_FMT_VER_UPD ||
 | 
				
			||||||
	    pkg->pkg_format_ver.draft != ICE_PKG_FMT_VER_DFT)
 | 
						    pkg->pkg_format_ver.draft != ICE_PKG_FMT_VER_DFT)
 | 
				
			||||||
		return ICE_ERR_CFG;
 | 
							return ICE_DDP_PKG_INVALID_FILE;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/* pkg must have at least one segment */
 | 
						/* pkg must have at least one segment */
 | 
				
			||||||
	seg_count = le32_to_cpu(pkg->seg_count);
 | 
						seg_count = le32_to_cpu(pkg->seg_count);
 | 
				
			||||||
	if (seg_count < 1)
 | 
						if (seg_count < 1)
 | 
				
			||||||
		return ICE_ERR_CFG;
 | 
							return ICE_DDP_PKG_INVALID_FILE;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/* make sure segment array fits in package length */
 | 
						/* make sure segment array fits in package length */
 | 
				
			||||||
	if (len < struct_size(pkg, seg_offset, seg_count))
 | 
						if (len < struct_size(pkg, seg_offset, seg_count))
 | 
				
			||||||
		return ICE_ERR_BUF_TOO_SHORT;
 | 
							return ICE_DDP_PKG_INVALID_FILE;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/* all segments must fit within length */
 | 
						/* all segments must fit within length */
 | 
				
			||||||
	for (i = 0; i < seg_count; i++) {
 | 
						for (i = 0; i < seg_count; i++) {
 | 
				
			||||||
| 
						 | 
					@ -1278,16 +1290,16 @@ static enum ice_status ice_verify_pkg(struct ice_pkg_hdr *pkg, u32 len)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		/* segment header must fit */
 | 
							/* segment header must fit */
 | 
				
			||||||
		if (len < off + sizeof(*seg))
 | 
							if (len < off + sizeof(*seg))
 | 
				
			||||||
			return ICE_ERR_BUF_TOO_SHORT;
 | 
								return ICE_DDP_PKG_INVALID_FILE;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		seg = (struct ice_generic_seg_hdr *)((u8 *)pkg + off);
 | 
							seg = (struct ice_generic_seg_hdr *)((u8 *)pkg + off);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		/* segment body must fit */
 | 
							/* segment body must fit */
 | 
				
			||||||
		if (len < off + le32_to_cpu(seg->seg_size))
 | 
							if (len < off + le32_to_cpu(seg->seg_size))
 | 
				
			||||||
			return ICE_ERR_BUF_TOO_SHORT;
 | 
								return ICE_DDP_PKG_INVALID_FILE;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	return 0;
 | 
						return ICE_DDP_PKG_SUCCESS;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/**
 | 
					/**
 | 
				
			||||||
| 
						 | 
					@ -1331,13 +1343,18 @@ static void ice_init_pkg_regs(struct ice_hw *hw)
 | 
				
			||||||
 * version must match our ICE_PKG_SUPP_VER_MAJ and ICE_PKG_SUPP_VER_MNR
 | 
					 * version must match our ICE_PKG_SUPP_VER_MAJ and ICE_PKG_SUPP_VER_MNR
 | 
				
			||||||
 * definitions.
 | 
					 * definitions.
 | 
				
			||||||
 */
 | 
					 */
 | 
				
			||||||
static enum ice_status ice_chk_pkg_version(struct ice_pkg_ver *pkg_ver)
 | 
					static enum ice_ddp_state ice_chk_pkg_version(struct ice_pkg_ver *pkg_ver)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	if (pkg_ver->major != ICE_PKG_SUPP_VER_MAJ ||
 | 
						if (pkg_ver->major > ICE_PKG_SUPP_VER_MAJ ||
 | 
				
			||||||
	    pkg_ver->minor != ICE_PKG_SUPP_VER_MNR)
 | 
						    (pkg_ver->major == ICE_PKG_SUPP_VER_MAJ &&
 | 
				
			||||||
		return ICE_ERR_NOT_SUPPORTED;
 | 
						     pkg_ver->minor > ICE_PKG_SUPP_VER_MNR))
 | 
				
			||||||
 | 
							return ICE_DDP_PKG_FILE_VERSION_TOO_HIGH;
 | 
				
			||||||
 | 
						else if (pkg_ver->major < ICE_PKG_SUPP_VER_MAJ ||
 | 
				
			||||||
 | 
							 (pkg_ver->major == ICE_PKG_SUPP_VER_MAJ &&
 | 
				
			||||||
 | 
							  pkg_ver->minor < ICE_PKG_SUPP_VER_MNR))
 | 
				
			||||||
 | 
							return ICE_DDP_PKG_FILE_VERSION_TOO_LOW;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	return 0;
 | 
						return ICE_DDP_PKG_SUCCESS;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/**
 | 
					/**
 | 
				
			||||||
| 
						 | 
					@ -1348,20 +1365,20 @@ static enum ice_status ice_chk_pkg_version(struct ice_pkg_ver *pkg_ver)
 | 
				
			||||||
 *
 | 
					 *
 | 
				
			||||||
 * This function checks the package version compatibility with driver and NVM
 | 
					 * This function checks the package version compatibility with driver and NVM
 | 
				
			||||||
 */
 | 
					 */
 | 
				
			||||||
static enum ice_status
 | 
					static enum ice_ddp_state
 | 
				
			||||||
ice_chk_pkg_compat(struct ice_hw *hw, struct ice_pkg_hdr *ospkg,
 | 
					ice_chk_pkg_compat(struct ice_hw *hw, struct ice_pkg_hdr *ospkg,
 | 
				
			||||||
		   struct ice_seg **seg)
 | 
							   struct ice_seg **seg)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	struct ice_aqc_get_pkg_info_resp *pkg;
 | 
						struct ice_aqc_get_pkg_info_resp *pkg;
 | 
				
			||||||
	enum ice_status status;
 | 
						enum ice_ddp_state state;
 | 
				
			||||||
	u16 size;
 | 
						u16 size;
 | 
				
			||||||
	u32 i;
 | 
						u32 i;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/* Check package version compatibility */
 | 
						/* Check package version compatibility */
 | 
				
			||||||
	status = ice_chk_pkg_version(&hw->pkg_ver);
 | 
						state = ice_chk_pkg_version(&hw->pkg_ver);
 | 
				
			||||||
	if (status) {
 | 
						if (state) {
 | 
				
			||||||
		ice_debug(hw, ICE_DBG_INIT, "Package version check failed.\n");
 | 
							ice_debug(hw, ICE_DBG_INIT, "Package version check failed.\n");
 | 
				
			||||||
		return status;
 | 
							return state;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/* find ICE segment in given package */
 | 
						/* find ICE segment in given package */
 | 
				
			||||||
| 
						 | 
					@ -1369,18 +1386,19 @@ ice_chk_pkg_compat(struct ice_hw *hw, struct ice_pkg_hdr *ospkg,
 | 
				
			||||||
						     ospkg);
 | 
											     ospkg);
 | 
				
			||||||
	if (!*seg) {
 | 
						if (!*seg) {
 | 
				
			||||||
		ice_debug(hw, ICE_DBG_INIT, "no ice segment in package.\n");
 | 
							ice_debug(hw, ICE_DBG_INIT, "no ice segment in package.\n");
 | 
				
			||||||
		return ICE_ERR_CFG;
 | 
							return ICE_DDP_PKG_INVALID_FILE;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/* Check if FW is compatible with the OS package */
 | 
						/* Check if FW is compatible with the OS package */
 | 
				
			||||||
	size = struct_size(pkg, pkg_info, ICE_PKG_CNT);
 | 
						size = struct_size(pkg, pkg_info, ICE_PKG_CNT);
 | 
				
			||||||
	pkg = kzalloc(size, GFP_KERNEL);
 | 
						pkg = kzalloc(size, GFP_KERNEL);
 | 
				
			||||||
	if (!pkg)
 | 
						if (!pkg)
 | 
				
			||||||
		return ICE_ERR_NO_MEMORY;
 | 
							return ICE_DDP_PKG_ERR;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	status = ice_aq_get_pkg_info_list(hw, pkg, size, NULL);
 | 
						if (ice_aq_get_pkg_info_list(hw, pkg, size, NULL)) {
 | 
				
			||||||
	if (status)
 | 
							state = ICE_DDP_PKG_LOAD_ERROR;
 | 
				
			||||||
		goto fw_ddp_compat_free_alloc;
 | 
							goto fw_ddp_compat_free_alloc;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	for (i = 0; i < le32_to_cpu(pkg->count); i++) {
 | 
						for (i = 0; i < le32_to_cpu(pkg->count); i++) {
 | 
				
			||||||
		/* loop till we find the NVM package */
 | 
							/* loop till we find the NVM package */
 | 
				
			||||||
| 
						 | 
					@ -1390,7 +1408,7 @@ ice_chk_pkg_compat(struct ice_hw *hw, struct ice_pkg_hdr *ospkg,
 | 
				
			||||||
			pkg->pkg_info[i].ver.major ||
 | 
								pkg->pkg_info[i].ver.major ||
 | 
				
			||||||
		    (*seg)->hdr.seg_format_ver.minor >
 | 
							    (*seg)->hdr.seg_format_ver.minor >
 | 
				
			||||||
			pkg->pkg_info[i].ver.minor) {
 | 
								pkg->pkg_info[i].ver.minor) {
 | 
				
			||||||
			status = ICE_ERR_FW_DDP_MISMATCH;
 | 
								state = ICE_DDP_PKG_FW_MISMATCH;
 | 
				
			||||||
			ice_debug(hw, ICE_DBG_INIT, "OS package is not compatible with NVM.\n");
 | 
								ice_debug(hw, ICE_DBG_INIT, "OS package is not compatible with NVM.\n");
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
		/* done processing NVM package so break */
 | 
							/* done processing NVM package so break */
 | 
				
			||||||
| 
						 | 
					@ -1398,7 +1416,7 @@ ice_chk_pkg_compat(struct ice_hw *hw, struct ice_pkg_hdr *ospkg,
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
fw_ddp_compat_free_alloc:
 | 
					fw_ddp_compat_free_alloc:
 | 
				
			||||||
	kfree(pkg);
 | 
						kfree(pkg);
 | 
				
			||||||
	return status;
 | 
						return state;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/**
 | 
					/**
 | 
				
			||||||
| 
						 | 
					@ -1481,6 +1499,34 @@ static enum ice_status ice_get_prof_index_max(struct ice_hw *hw)
 | 
				
			||||||
	return 0;
 | 
						return 0;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * ice_get_ddp_pkg_state - get DDP pkg state after download
 | 
				
			||||||
 | 
					 * @hw: pointer to the HW struct
 | 
				
			||||||
 | 
					 * @already_loaded: indicates if pkg was already loaded onto the device
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					static enum ice_ddp_state
 | 
				
			||||||
 | 
					ice_get_ddp_pkg_state(struct ice_hw *hw, bool already_loaded)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						if (hw->pkg_ver.major == hw->active_pkg_ver.major &&
 | 
				
			||||||
 | 
						    hw->pkg_ver.minor == hw->active_pkg_ver.minor &&
 | 
				
			||||||
 | 
						    hw->pkg_ver.update == hw->active_pkg_ver.update &&
 | 
				
			||||||
 | 
						    hw->pkg_ver.draft == hw->active_pkg_ver.draft &&
 | 
				
			||||||
 | 
						    !memcmp(hw->pkg_name, hw->active_pkg_name, sizeof(hw->pkg_name))) {
 | 
				
			||||||
 | 
							if (already_loaded)
 | 
				
			||||||
 | 
								return ICE_DDP_PKG_SAME_VERSION_ALREADY_LOADED;
 | 
				
			||||||
 | 
							else
 | 
				
			||||||
 | 
								return ICE_DDP_PKG_SUCCESS;
 | 
				
			||||||
 | 
						} else if (hw->active_pkg_ver.major != ICE_PKG_SUPP_VER_MAJ ||
 | 
				
			||||||
 | 
							   hw->active_pkg_ver.minor != ICE_PKG_SUPP_VER_MNR) {
 | 
				
			||||||
 | 
							return ICE_DDP_PKG_ALREADY_LOADED_NOT_SUPPORTED;
 | 
				
			||||||
 | 
						} else if (hw->active_pkg_ver.major == ICE_PKG_SUPP_VER_MAJ &&
 | 
				
			||||||
 | 
							   hw->active_pkg_ver.minor == ICE_PKG_SUPP_VER_MNR) {
 | 
				
			||||||
 | 
							return ICE_DDP_PKG_COMPATIBLE_ALREADY_LOADED;
 | 
				
			||||||
 | 
						} else {
 | 
				
			||||||
 | 
							return ICE_DDP_PKG_ERR;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/**
 | 
					/**
 | 
				
			||||||
 * ice_init_pkg - initialize/download package
 | 
					 * ice_init_pkg - initialize/download package
 | 
				
			||||||
 * @hw: pointer to the hardware structure
 | 
					 * @hw: pointer to the hardware structure
 | 
				
			||||||
| 
						 | 
					@ -1506,53 +1552,54 @@ static enum ice_status ice_get_prof_index_max(struct ice_hw *hw)
 | 
				
			||||||
 * ice_copy_and_init_pkg() instead of directly calling ice_init_pkg() in this
 | 
					 * ice_copy_and_init_pkg() instead of directly calling ice_init_pkg() in this
 | 
				
			||||||
 * case.
 | 
					 * case.
 | 
				
			||||||
 */
 | 
					 */
 | 
				
			||||||
enum ice_status ice_init_pkg(struct ice_hw *hw, u8 *buf, u32 len)
 | 
					enum ice_ddp_state ice_init_pkg(struct ice_hw *hw, u8 *buf, u32 len)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
 | 
						bool already_loaded = false;
 | 
				
			||||||
 | 
						enum ice_ddp_state state;
 | 
				
			||||||
	struct ice_pkg_hdr *pkg;
 | 
						struct ice_pkg_hdr *pkg;
 | 
				
			||||||
	enum ice_status status;
 | 
					 | 
				
			||||||
	struct ice_seg *seg;
 | 
						struct ice_seg *seg;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (!buf || !len)
 | 
						if (!buf || !len)
 | 
				
			||||||
		return ICE_ERR_PARAM;
 | 
							return ICE_DDP_PKG_ERR;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	pkg = (struct ice_pkg_hdr *)buf;
 | 
						pkg = (struct ice_pkg_hdr *)buf;
 | 
				
			||||||
	status = ice_verify_pkg(pkg, len);
 | 
						state = ice_verify_pkg(pkg, len);
 | 
				
			||||||
	if (status) {
 | 
						if (state) {
 | 
				
			||||||
		ice_debug(hw, ICE_DBG_INIT, "failed to verify pkg (err: %d)\n",
 | 
							ice_debug(hw, ICE_DBG_INIT, "failed to verify pkg (err: %d)\n",
 | 
				
			||||||
			  status);
 | 
								  state);
 | 
				
			||||||
		return status;
 | 
							return state;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/* initialize package info */
 | 
						/* initialize package info */
 | 
				
			||||||
	status = ice_init_pkg_info(hw, pkg);
 | 
						state = ice_init_pkg_info(hw, pkg);
 | 
				
			||||||
	if (status)
 | 
						if (state)
 | 
				
			||||||
		return status;
 | 
							return state;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/* before downloading the package, check package version for
 | 
						/* before downloading the package, check package version for
 | 
				
			||||||
	 * compatibility with driver
 | 
						 * compatibility with driver
 | 
				
			||||||
	 */
 | 
						 */
 | 
				
			||||||
	status = ice_chk_pkg_compat(hw, pkg, &seg);
 | 
						state = ice_chk_pkg_compat(hw, pkg, &seg);
 | 
				
			||||||
	if (status)
 | 
						if (state)
 | 
				
			||||||
		return status;
 | 
							return state;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/* initialize package hints and then download package */
 | 
						/* initialize package hints and then download package */
 | 
				
			||||||
	ice_init_pkg_hints(hw, seg);
 | 
						ice_init_pkg_hints(hw, seg);
 | 
				
			||||||
	status = ice_download_pkg(hw, seg);
 | 
						state = ice_download_pkg(hw, seg);
 | 
				
			||||||
	if (status == ICE_ERR_AQ_NO_WORK) {
 | 
						if (state == ICE_DDP_PKG_ALREADY_LOADED) {
 | 
				
			||||||
		ice_debug(hw, ICE_DBG_INIT, "package previously loaded - no work.\n");
 | 
							ice_debug(hw, ICE_DBG_INIT, "package previously loaded - no work.\n");
 | 
				
			||||||
		status = 0;
 | 
							already_loaded = true;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/* Get information on the package currently loaded in HW, then make sure
 | 
						/* Get information on the package currently loaded in HW, then make sure
 | 
				
			||||||
	 * the driver is compatible with this version.
 | 
						 * the driver is compatible with this version.
 | 
				
			||||||
	 */
 | 
						 */
 | 
				
			||||||
	if (!status) {
 | 
						if (!state || state == ICE_DDP_PKG_ALREADY_LOADED) {
 | 
				
			||||||
		status = ice_get_pkg_info(hw);
 | 
							state = ice_get_pkg_info(hw);
 | 
				
			||||||
		if (!status)
 | 
							if (!state)
 | 
				
			||||||
			status = ice_chk_pkg_version(&hw->active_pkg_ver);
 | 
								state = ice_get_ddp_pkg_state(hw, already_loaded);
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (!status) {
 | 
						if (ice_is_init_pkg_successful(state)) {
 | 
				
			||||||
		hw->seg = seg;
 | 
							hw->seg = seg;
 | 
				
			||||||
		/* on successful package download update other required
 | 
							/* on successful package download update other required
 | 
				
			||||||
		 * registers to support the package and fill HW tables
 | 
							 * registers to support the package and fill HW tables
 | 
				
			||||||
| 
						 | 
					@ -1564,10 +1611,10 @@ enum ice_status ice_init_pkg(struct ice_hw *hw, u8 *buf, u32 len)
 | 
				
			||||||
		ice_get_prof_index_max(hw);
 | 
							ice_get_prof_index_max(hw);
 | 
				
			||||||
	} else {
 | 
						} else {
 | 
				
			||||||
		ice_debug(hw, ICE_DBG_INIT, "package load failed, %d\n",
 | 
							ice_debug(hw, ICE_DBG_INIT, "package load failed, %d\n",
 | 
				
			||||||
			  status);
 | 
								  state);
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	return status;
 | 
						return state;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/**
 | 
					/**
 | 
				
			||||||
| 
						 | 
					@ -1593,18 +1640,19 @@ enum ice_status ice_init_pkg(struct ice_hw *hw, u8 *buf, u32 len)
 | 
				
			||||||
 * package buffer, as the new copy will be managed by this function and
 | 
					 * package buffer, as the new copy will be managed by this function and
 | 
				
			||||||
 * related routines.
 | 
					 * related routines.
 | 
				
			||||||
 */
 | 
					 */
 | 
				
			||||||
enum ice_status ice_copy_and_init_pkg(struct ice_hw *hw, const u8 *buf, u32 len)
 | 
					enum ice_ddp_state
 | 
				
			||||||
 | 
					ice_copy_and_init_pkg(struct ice_hw *hw, const u8 *buf, u32 len)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	enum ice_status status;
 | 
						enum ice_ddp_state state;
 | 
				
			||||||
	u8 *buf_copy;
 | 
						u8 *buf_copy;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (!buf || !len)
 | 
						if (!buf || !len)
 | 
				
			||||||
		return ICE_ERR_PARAM;
 | 
							return ICE_DDP_PKG_ERR;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	buf_copy = devm_kmemdup(ice_hw_to_dev(hw), buf, len, GFP_KERNEL);
 | 
						buf_copy = devm_kmemdup(ice_hw_to_dev(hw), buf, len, GFP_KERNEL);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	status = ice_init_pkg(hw, buf_copy, len);
 | 
						state = ice_init_pkg(hw, buf_copy, len);
 | 
				
			||||||
	if (status) {
 | 
						if (!ice_is_init_pkg_successful(state)) {
 | 
				
			||||||
		/* Free the copy, since we failed to initialize the package */
 | 
							/* Free the copy, since we failed to initialize the package */
 | 
				
			||||||
		devm_kfree(ice_hw_to_dev(hw), buf_copy);
 | 
							devm_kfree(ice_hw_to_dev(hw), buf_copy);
 | 
				
			||||||
	} else {
 | 
						} else {
 | 
				
			||||||
| 
						 | 
					@ -1613,7 +1661,23 @@ enum ice_status ice_copy_and_init_pkg(struct ice_hw *hw, const u8 *buf, u32 len)
 | 
				
			||||||
		hw->pkg_size = len;
 | 
							hw->pkg_size = len;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	return status;
 | 
						return state;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * ice_is_init_pkg_successful - check if DDP init was successful
 | 
				
			||||||
 | 
					 * @state: state of the DDP pkg after download
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					bool ice_is_init_pkg_successful(enum ice_ddp_state state)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						switch (state) {
 | 
				
			||||||
 | 
						case ICE_DDP_PKG_SUCCESS:
 | 
				
			||||||
 | 
						case ICE_DDP_PKG_SAME_VERSION_ALREADY_LOADED:
 | 
				
			||||||
 | 
						case ICE_DDP_PKG_COMPATIBLE_ALREADY_LOADED:
 | 
				
			||||||
 | 
							return true;
 | 
				
			||||||
 | 
						default:
 | 
				
			||||||
 | 
							return false;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/**
 | 
					/**
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -18,6 +18,63 @@
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#define ICE_PKG_CNT 4
 | 
					#define ICE_PKG_CNT 4
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					enum ice_ddp_state {
 | 
				
			||||||
 | 
						/* Indicates that this call to ice_init_pkg
 | 
				
			||||||
 | 
						 * successfully loaded the requested DDP package
 | 
				
			||||||
 | 
						 */
 | 
				
			||||||
 | 
						ICE_DDP_PKG_SUCCESS			= 0,
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/* Generic error for already loaded errors, it is mapped later to
 | 
				
			||||||
 | 
						 * the more specific one (one of the next 3)
 | 
				
			||||||
 | 
						 */
 | 
				
			||||||
 | 
						ICE_DDP_PKG_ALREADY_LOADED			= -1,
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/* Indicates that a DDP package of the same version has already been
 | 
				
			||||||
 | 
						 * loaded onto the device by a previous call or by another PF
 | 
				
			||||||
 | 
						 */
 | 
				
			||||||
 | 
						ICE_DDP_PKG_SAME_VERSION_ALREADY_LOADED		= -2,
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/* The device has a DDP package that is not supported by the driver */
 | 
				
			||||||
 | 
						ICE_DDP_PKG_ALREADY_LOADED_NOT_SUPPORTED	= -3,
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/* The device has a compatible package
 | 
				
			||||||
 | 
						 * (but different from the request) already loaded
 | 
				
			||||||
 | 
						 */
 | 
				
			||||||
 | 
						ICE_DDP_PKG_COMPATIBLE_ALREADY_LOADED		= -4,
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/* The firmware loaded on the device is not compatible with
 | 
				
			||||||
 | 
						 * the DDP package loaded
 | 
				
			||||||
 | 
						 */
 | 
				
			||||||
 | 
						ICE_DDP_PKG_FW_MISMATCH				= -5,
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/* The DDP package file is invalid */
 | 
				
			||||||
 | 
						ICE_DDP_PKG_INVALID_FILE			= -6,
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/* The version of the DDP package provided is higher than
 | 
				
			||||||
 | 
						 * the driver supports
 | 
				
			||||||
 | 
						 */
 | 
				
			||||||
 | 
						ICE_DDP_PKG_FILE_VERSION_TOO_HIGH		= -7,
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/* The version of the DDP package provided is lower than the
 | 
				
			||||||
 | 
						 * driver supports
 | 
				
			||||||
 | 
						 */
 | 
				
			||||||
 | 
						ICE_DDP_PKG_FILE_VERSION_TOO_LOW		= -8,
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/* The signature of the DDP package file provided is invalid */
 | 
				
			||||||
 | 
						ICE_DDP_PKG_FILE_SIGNATURE_INVALID		= -9,
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/* The DDP package file security revision is too low and not
 | 
				
			||||||
 | 
						 * supported by firmware
 | 
				
			||||||
 | 
						 */
 | 
				
			||||||
 | 
						ICE_DDP_PKG_FILE_REVISION_TOO_LOW		= -10,
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/* An error occurred in firmware while loading the DDP package */
 | 
				
			||||||
 | 
						ICE_DDP_PKG_LOAD_ERROR				= -11,
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/* Other errors */
 | 
				
			||||||
 | 
						ICE_DDP_PKG_ERR					= -12
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
enum ice_status
 | 
					enum ice_status
 | 
				
			||||||
ice_acquire_change_lock(struct ice_hw *hw, enum ice_aq_res_access_type access);
 | 
					ice_acquire_change_lock(struct ice_hw *hw, enum ice_aq_res_access_type access);
 | 
				
			||||||
void ice_release_change_lock(struct ice_hw *hw);
 | 
					void ice_release_change_lock(struct ice_hw *hw);
 | 
				
			||||||
| 
						 | 
					@ -52,9 +109,10 @@ enum ice_status
 | 
				
			||||||
ice_add_prof_id_flow(struct ice_hw *hw, enum ice_block blk, u16 vsi, u64 hdl);
 | 
					ice_add_prof_id_flow(struct ice_hw *hw, enum ice_block blk, u16 vsi, u64 hdl);
 | 
				
			||||||
enum ice_status
 | 
					enum ice_status
 | 
				
			||||||
ice_rem_prof_id_flow(struct ice_hw *hw, enum ice_block blk, u16 vsi, u64 hdl);
 | 
					ice_rem_prof_id_flow(struct ice_hw *hw, enum ice_block blk, u16 vsi, u64 hdl);
 | 
				
			||||||
enum ice_status ice_init_pkg(struct ice_hw *hw, u8 *buff, u32 len);
 | 
					enum ice_ddp_state ice_init_pkg(struct ice_hw *hw, u8 *buff, u32 len);
 | 
				
			||||||
enum ice_status
 | 
					enum ice_ddp_state
 | 
				
			||||||
ice_copy_and_init_pkg(struct ice_hw *hw, const u8 *buf, u32 len);
 | 
					ice_copy_and_init_pkg(struct ice_hw *hw, const u8 *buf, u32 len);
 | 
				
			||||||
 | 
					bool ice_is_init_pkg_successful(enum ice_ddp_state state);
 | 
				
			||||||
enum ice_status ice_init_hw_tbls(struct ice_hw *hw);
 | 
					enum ice_status ice_init_hw_tbls(struct ice_hw *hw);
 | 
				
			||||||
void ice_free_seg(struct ice_hw *hw);
 | 
					void ice_free_seg(struct ice_hw *hw);
 | 
				
			||||||
void ice_fill_blk_tbls(struct ice_hw *hw);
 | 
					void ice_fill_blk_tbls(struct ice_hw *hw);
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -4082,50 +4082,40 @@ static void ice_set_safe_mode_vlan_cfg(struct ice_pf *pf)
 | 
				
			||||||
/**
 | 
					/**
 | 
				
			||||||
 * ice_log_pkg_init - log result of DDP package load
 | 
					 * ice_log_pkg_init - log result of DDP package load
 | 
				
			||||||
 * @hw: pointer to hardware info
 | 
					 * @hw: pointer to hardware info
 | 
				
			||||||
 * @status: status of package load
 | 
					 * @state: state of package load
 | 
				
			||||||
 */
 | 
					 */
 | 
				
			||||||
static void
 | 
					static void ice_log_pkg_init(struct ice_hw *hw, enum ice_ddp_state state)
 | 
				
			||||||
ice_log_pkg_init(struct ice_hw *hw, enum ice_status *status)
 | 
					 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	struct ice_pf *pf = (struct ice_pf *)hw->back;
 | 
						struct ice_pf *pf = hw->back;
 | 
				
			||||||
	struct device *dev = ice_pf_to_dev(pf);
 | 
						struct device *dev;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	switch (*status) {
 | 
						dev = ice_pf_to_dev(pf);
 | 
				
			||||||
	case ICE_SUCCESS:
 | 
					
 | 
				
			||||||
		/* The package download AdminQ command returned success because
 | 
						switch (state) {
 | 
				
			||||||
		 * this download succeeded or ICE_ERR_AQ_NO_WORK since there is
 | 
						case ICE_DDP_PKG_SUCCESS:
 | 
				
			||||||
		 * already a package loaded on the device.
 | 
					 | 
				
			||||||
		 */
 | 
					 | 
				
			||||||
		if (hw->pkg_ver.major == hw->active_pkg_ver.major &&
 | 
					 | 
				
			||||||
		    hw->pkg_ver.minor == hw->active_pkg_ver.minor &&
 | 
					 | 
				
			||||||
		    hw->pkg_ver.update == hw->active_pkg_ver.update &&
 | 
					 | 
				
			||||||
		    hw->pkg_ver.draft == hw->active_pkg_ver.draft &&
 | 
					 | 
				
			||||||
		    !memcmp(hw->pkg_name, hw->active_pkg_name,
 | 
					 | 
				
			||||||
			    sizeof(hw->pkg_name))) {
 | 
					 | 
				
			||||||
			if (hw->pkg_dwnld_status == ICE_AQ_RC_EEXIST)
 | 
					 | 
				
			||||||
				dev_info(dev, "DDP package already present on device: %s version %d.%d.%d.%d\n",
 | 
					 | 
				
			||||||
					 hw->active_pkg_name,
 | 
					 | 
				
			||||||
					 hw->active_pkg_ver.major,
 | 
					 | 
				
			||||||
					 hw->active_pkg_ver.minor,
 | 
					 | 
				
			||||||
					 hw->active_pkg_ver.update,
 | 
					 | 
				
			||||||
					 hw->active_pkg_ver.draft);
 | 
					 | 
				
			||||||
			else
 | 
					 | 
				
			||||||
		dev_info(dev, "The DDP package was successfully loaded: %s version %d.%d.%d.%d\n",
 | 
							dev_info(dev, "The DDP package was successfully loaded: %s version %d.%d.%d.%d\n",
 | 
				
			||||||
			 hw->active_pkg_name,
 | 
								 hw->active_pkg_name,
 | 
				
			||||||
			 hw->active_pkg_ver.major,
 | 
								 hw->active_pkg_ver.major,
 | 
				
			||||||
			 hw->active_pkg_ver.minor,
 | 
								 hw->active_pkg_ver.minor,
 | 
				
			||||||
			 hw->active_pkg_ver.update,
 | 
								 hw->active_pkg_ver.update,
 | 
				
			||||||
			 hw->active_pkg_ver.draft);
 | 
								 hw->active_pkg_ver.draft);
 | 
				
			||||||
		} else if (hw->active_pkg_ver.major != ICE_PKG_SUPP_VER_MAJ ||
 | 
							break;
 | 
				
			||||||
			   hw->active_pkg_ver.minor != ICE_PKG_SUPP_VER_MNR) {
 | 
						case ICE_DDP_PKG_SAME_VERSION_ALREADY_LOADED:
 | 
				
			||||||
 | 
							dev_info(dev, "DDP package already present on device: %s version %d.%d.%d.%d\n",
 | 
				
			||||||
 | 
								 hw->active_pkg_name,
 | 
				
			||||||
 | 
								 hw->active_pkg_ver.major,
 | 
				
			||||||
 | 
								 hw->active_pkg_ver.minor,
 | 
				
			||||||
 | 
								 hw->active_pkg_ver.update,
 | 
				
			||||||
 | 
								 hw->active_pkg_ver.draft);
 | 
				
			||||||
 | 
							break;
 | 
				
			||||||
 | 
						case ICE_DDP_PKG_ALREADY_LOADED_NOT_SUPPORTED:
 | 
				
			||||||
		dev_err(dev, "The device has a DDP package that is not supported by the driver.  The device has package '%s' version %d.%d.x.x.  The driver requires version %d.%d.x.x.  Entering Safe Mode.\n",
 | 
							dev_err(dev, "The device has a DDP package that is not supported by the driver.  The device has package '%s' version %d.%d.x.x.  The driver requires version %d.%d.x.x.  Entering Safe Mode.\n",
 | 
				
			||||||
			hw->active_pkg_name,
 | 
								hw->active_pkg_name,
 | 
				
			||||||
			hw->active_pkg_ver.major,
 | 
								hw->active_pkg_ver.major,
 | 
				
			||||||
			hw->active_pkg_ver.minor,
 | 
								hw->active_pkg_ver.minor,
 | 
				
			||||||
			ICE_PKG_SUPP_VER_MAJ, ICE_PKG_SUPP_VER_MNR);
 | 
								ICE_PKG_SUPP_VER_MAJ, ICE_PKG_SUPP_VER_MNR);
 | 
				
			||||||
			*status = ICE_ERR_NOT_SUPPORTED;
 | 
							break;
 | 
				
			||||||
		} else if (hw->active_pkg_ver.major == ICE_PKG_SUPP_VER_MAJ &&
 | 
						case ICE_DDP_PKG_COMPATIBLE_ALREADY_LOADED:
 | 
				
			||||||
			   hw->active_pkg_ver.minor == ICE_PKG_SUPP_VER_MNR) {
 | 
					 | 
				
			||||||
		dev_info(dev, "The driver could not load the DDP package file because a compatible DDP package is already present on the device.  The device has package '%s' version %d.%d.%d.%d.  The package file found by the driver: '%s' version %d.%d.%d.%d.\n",
 | 
							dev_info(dev, "The driver could not load the DDP package file because a compatible DDP package is already present on the device.  The device has package '%s' version %d.%d.%d.%d.  The package file found by the driver: '%s' version %d.%d.%d.%d.\n",
 | 
				
			||||||
			 hw->active_pkg_name,
 | 
								 hw->active_pkg_name,
 | 
				
			||||||
			 hw->active_pkg_ver.major,
 | 
								 hw->active_pkg_ver.major,
 | 
				
			||||||
| 
						 | 
					@ -4137,54 +4127,35 @@ ice_log_pkg_init(struct ice_hw *hw, enum ice_status *status)
 | 
				
			||||||
			 hw->pkg_ver.minor,
 | 
								 hw->pkg_ver.minor,
 | 
				
			||||||
			 hw->pkg_ver.update,
 | 
								 hw->pkg_ver.update,
 | 
				
			||||||
			 hw->pkg_ver.draft);
 | 
								 hw->pkg_ver.draft);
 | 
				
			||||||
		} else {
 | 
					 | 
				
			||||||
			dev_err(dev, "An unknown error occurred when loading the DDP package, please reboot the system.  If the problem persists, update the NVM.  Entering Safe Mode.\n");
 | 
					 | 
				
			||||||
			*status = ICE_ERR_NOT_SUPPORTED;
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
		break;
 | 
							break;
 | 
				
			||||||
	case ICE_ERR_FW_DDP_MISMATCH:
 | 
						case ICE_DDP_PKG_FW_MISMATCH:
 | 
				
			||||||
		dev_err(dev, "The firmware loaded on the device is not compatible with the DDP package.  Please update the device's NVM.  Entering safe mode.\n");
 | 
							dev_err(dev, "The firmware loaded on the device is not compatible with the DDP package.  Please update the device's NVM.  Entering safe mode.\n");
 | 
				
			||||||
		break;
 | 
							break;
 | 
				
			||||||
	case ICE_ERR_BUF_TOO_SHORT:
 | 
						case ICE_DDP_PKG_INVALID_FILE:
 | 
				
			||||||
	case ICE_ERR_CFG:
 | 
					 | 
				
			||||||
		dev_err(dev, "The DDP package file is invalid. Entering Safe Mode.\n");
 | 
							dev_err(dev, "The DDP package file is invalid. Entering Safe Mode.\n");
 | 
				
			||||||
		break;
 | 
							break;
 | 
				
			||||||
	case ICE_ERR_NOT_SUPPORTED:
 | 
						case ICE_DDP_PKG_FILE_VERSION_TOO_HIGH:
 | 
				
			||||||
		/* Package File version not supported */
 | 
					 | 
				
			||||||
		if (hw->pkg_ver.major > ICE_PKG_SUPP_VER_MAJ ||
 | 
					 | 
				
			||||||
		    (hw->pkg_ver.major == ICE_PKG_SUPP_VER_MAJ &&
 | 
					 | 
				
			||||||
		     hw->pkg_ver.minor > ICE_PKG_SUPP_VER_MNR))
 | 
					 | 
				
			||||||
		dev_err(dev, "The DDP package file version is higher than the driver supports.  Please use an updated driver.  Entering Safe Mode.\n");
 | 
							dev_err(dev, "The DDP package file version is higher than the driver supports.  Please use an updated driver.  Entering Safe Mode.\n");
 | 
				
			||||||
		else if (hw->pkg_ver.major < ICE_PKG_SUPP_VER_MAJ ||
 | 
							break;
 | 
				
			||||||
			 (hw->pkg_ver.major == ICE_PKG_SUPP_VER_MAJ &&
 | 
						case ICE_DDP_PKG_FILE_VERSION_TOO_LOW:
 | 
				
			||||||
			  hw->pkg_ver.minor < ICE_PKG_SUPP_VER_MNR))
 | 
					 | 
				
			||||||
		dev_err(dev, "The DDP package file version is lower than the driver supports.  The driver requires version %d.%d.x.x.  Please use an updated DDP Package file.  Entering Safe Mode.\n",
 | 
							dev_err(dev, "The DDP package file version is lower than the driver supports.  The driver requires version %d.%d.x.x.  Please use an updated DDP Package file.  Entering Safe Mode.\n",
 | 
				
			||||||
			ICE_PKG_SUPP_VER_MAJ, ICE_PKG_SUPP_VER_MNR);
 | 
								ICE_PKG_SUPP_VER_MAJ, ICE_PKG_SUPP_VER_MNR);
 | 
				
			||||||
		break;
 | 
							break;
 | 
				
			||||||
	case ICE_ERR_AQ_ERROR:
 | 
						case ICE_DDP_PKG_FILE_SIGNATURE_INVALID:
 | 
				
			||||||
		switch (hw->pkg_dwnld_status) {
 | 
					 | 
				
			||||||
		case ICE_AQ_RC_ENOSEC:
 | 
					 | 
				
			||||||
		case ICE_AQ_RC_EBADSIG:
 | 
					 | 
				
			||||||
		dev_err(dev, "The DDP package could not be loaded because its signature is not valid.  Please use a valid DDP Package.  Entering Safe Mode.\n");
 | 
							dev_err(dev, "The DDP package could not be loaded because its signature is not valid.  Please use a valid DDP Package.  Entering Safe Mode.\n");
 | 
				
			||||||
			return;
 | 
							break;
 | 
				
			||||||
		case ICE_AQ_RC_ESVN:
 | 
						case ICE_DDP_PKG_FILE_REVISION_TOO_LOW:
 | 
				
			||||||
		dev_err(dev, "The DDP Package could not be loaded because its security revision is too low.  Please use an updated DDP Package.  Entering Safe Mode.\n");
 | 
							dev_err(dev, "The DDP Package could not be loaded because its security revision is too low.  Please use an updated DDP Package.  Entering Safe Mode.\n");
 | 
				
			||||||
			return;
 | 
							break;
 | 
				
			||||||
		case ICE_AQ_RC_EBADMAN:
 | 
						case ICE_DDP_PKG_LOAD_ERROR:
 | 
				
			||||||
		case ICE_AQ_RC_EBADBUF:
 | 
					 | 
				
			||||||
		dev_err(dev, "An error occurred on the device while loading the DDP package.  The device will be reset.\n");
 | 
							dev_err(dev, "An error occurred on the device while loading the DDP package.  The device will be reset.\n");
 | 
				
			||||||
			/* poll for reset to complete */
 | 
								/* poll for reset to complete */
 | 
				
			||||||
			if (ice_check_reset(hw))
 | 
								if (ice_check_reset(hw))
 | 
				
			||||||
				dev_err(dev, "Error resetting device. Please reload the driver\n");
 | 
									dev_err(dev, "Error resetting device. Please reload the driver\n");
 | 
				
			||||||
			return;
 | 
					 | 
				
			||||||
		default:
 | 
					 | 
				
			||||||
		break;
 | 
							break;
 | 
				
			||||||
		}
 | 
						case ICE_DDP_PKG_ERR:
 | 
				
			||||||
		fallthrough;
 | 
					 | 
				
			||||||
	default:
 | 
						default:
 | 
				
			||||||
		dev_err(dev, "An unknown error (%d) occurred when loading the DDP package.  Entering Safe Mode.\n",
 | 
							dev_err(dev, "An unknown error occurred when loading the DDP package.  Entering Safe Mode.\n");
 | 
				
			||||||
			*status);
 | 
					 | 
				
			||||||
		break;
 | 
					 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -4199,24 +4170,24 @@ ice_log_pkg_init(struct ice_hw *hw, enum ice_status *status)
 | 
				
			||||||
static void
 | 
					static void
 | 
				
			||||||
ice_load_pkg(const struct firmware *firmware, struct ice_pf *pf)
 | 
					ice_load_pkg(const struct firmware *firmware, struct ice_pf *pf)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	enum ice_status status = ICE_ERR_PARAM;
 | 
						enum ice_ddp_state state = ICE_DDP_PKG_ERR;
 | 
				
			||||||
	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;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/* Load DDP Package */
 | 
						/* Load DDP Package */
 | 
				
			||||||
	if (firmware && !hw->pkg_copy) {
 | 
						if (firmware && !hw->pkg_copy) {
 | 
				
			||||||
		status = ice_copy_and_init_pkg(hw, firmware->data,
 | 
							state = ice_copy_and_init_pkg(hw, firmware->data,
 | 
				
			||||||
					      firmware->size);
 | 
										      firmware->size);
 | 
				
			||||||
		ice_log_pkg_init(hw, &status);
 | 
							ice_log_pkg_init(hw, state);
 | 
				
			||||||
	} else if (!firmware && hw->pkg_copy) {
 | 
						} else if (!firmware && hw->pkg_copy) {
 | 
				
			||||||
		/* Reload package during rebuild after CORER/GLOBR reset */
 | 
							/* Reload package during rebuild after CORER/GLOBR reset */
 | 
				
			||||||
		status = ice_init_pkg(hw, hw->pkg_copy, hw->pkg_size);
 | 
							state = ice_init_pkg(hw, hw->pkg_copy, hw->pkg_size);
 | 
				
			||||||
		ice_log_pkg_init(hw, &status);
 | 
							ice_log_pkg_init(hw, state);
 | 
				
			||||||
	} else {
 | 
						} else {
 | 
				
			||||||
		dev_err(dev, "The DDP package file failed to load. Entering Safe Mode.\n");
 | 
							dev_err(dev, "The DDP package file failed to load. Entering Safe Mode.\n");
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (status) {
 | 
						if (!ice_is_init_pkg_successful(state)) {
 | 
				
			||||||
		/* Safe Mode */
 | 
							/* Safe Mode */
 | 
				
			||||||
		clear_bit(ICE_FLAG_ADV_FEATURES, pf->flags);
 | 
							clear_bit(ICE_FLAG_ADV_FEATURES, pf->flags);
 | 
				
			||||||
		return;
 | 
							return;
 | 
				
			||||||
| 
						 | 
					@ -4539,7 +4510,6 @@ ice_probe(struct pci_dev *pdev, const struct pci_device_id __always_unused *ent)
 | 
				
			||||||
	 * true
 | 
						 * true
 | 
				
			||||||
	 */
 | 
						 */
 | 
				
			||||||
	if (ice_is_safe_mode(pf)) {
 | 
						if (ice_is_safe_mode(pf)) {
 | 
				
			||||||
		dev_err(dev, "Package download failed. Advanced features disabled - Device now in Safe Mode\n");
 | 
					 | 
				
			||||||
		/* we already got function/device capabilities but these don't
 | 
							/* we already got function/device capabilities but these don't
 | 
				
			||||||
		 * reflect what the driver needs to do in safe mode. Instead of
 | 
							 * reflect what the driver needs to do in safe mode. Instead of
 | 
				
			||||||
		 * adding conditional logic everywhere to ignore these
 | 
							 * adding conditional logic everywhere to ignore these
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -873,8 +873,6 @@ struct ice_hw {
 | 
				
			||||||
	u8 active_pkg_name[ICE_PKG_NAME_SIZE];
 | 
						u8 active_pkg_name[ICE_PKG_NAME_SIZE];
 | 
				
			||||||
	u8 active_pkg_in_nvm;
 | 
						u8 active_pkg_in_nvm;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	enum ice_aq_err pkg_dwnld_status;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	/* Driver's package ver - (from the Ice Metadata section) */
 | 
						/* Driver's package ver - (from the Ice Metadata section) */
 | 
				
			||||||
	struct ice_pkg_ver pkg_ver;
 | 
						struct ice_pkg_ver pkg_ver;
 | 
				
			||||||
	u8 pkg_name[ICE_PKG_NAME_SIZE];
 | 
						u8 pkg_name[ICE_PKG_NAME_SIZE];
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
		Reference in a new issue