* Verifies various attributes of the package file, including length, format
  * version, and the requirement of at least one segment.
  */
-static enum ice_ddp_state ice_verify_pkg(struct ice_pkg_hdr *pkg, u32 len)
+static enum ice_ddp_state ice_verify_pkg(const struct ice_pkg_hdr *pkg, u32 len)
 {
        u32 seg_count;
        u32 i;
        /* all segments must fit within length */
        for (i = 0; i < seg_count; i++) {
                u32 off = le32_to_cpu(pkg->seg_offset[i]);
-               struct ice_generic_seg_hdr *seg;
+               const struct ice_generic_seg_hdr *seg;
 
                /* segment header must fit */
                if (len < off + sizeof(*seg))
                        return ICE_DDP_PKG_INVALID_FILE;
 
-               seg = (struct ice_generic_seg_hdr *)((u8 *)pkg + off);
+               seg = (void *)pkg + off;
 
                /* segment body must fit */
                if (len < off + le32_to_cpu(seg->seg_size))
  *
  * This helper function validates a buffer's header.
  */
-static struct ice_buf_hdr *ice_pkg_val_buf(struct ice_buf *buf)
+static const struct ice_buf_hdr *ice_pkg_val_buf(const struct ice_buf *buf)
 {
-       struct ice_buf_hdr *hdr;
+       const struct ice_buf_hdr *hdr;
        u16 section_count;
        u16 data_end;
 
-       hdr = (struct ice_buf_hdr *)buf->buf;
+       hdr = (const struct ice_buf_hdr *)buf->buf;
        /* verify data */
        section_count = le16_to_cpu(hdr->section_count);
        if (section_count < ICE_MIN_S_COUNT || section_count > ICE_MAX_S_COUNT)
  * unexpected value has been detected (for example an invalid section count or
  * an invalid buffer end value).
  */
-static struct ice_buf_hdr *ice_pkg_enum_buf(struct ice_seg *ice_seg,
-                                           struct ice_pkg_enum *state)
+static const struct ice_buf_hdr *ice_pkg_enum_buf(struct ice_seg *ice_seg,
+                                                 struct ice_pkg_enum *state)
 {
        if (ice_seg) {
                state->buf_table = ice_find_buf_table(ice_seg);
  * success it returns a pointer to the segment header, otherwise it will
  * return NULL.
  */
-static struct ice_generic_seg_hdr *
+static const struct ice_generic_seg_hdr *
 ice_find_seg_in_pkg(struct ice_hw *hw, u32 seg_type,
-                   struct ice_pkg_hdr *pkg_hdr)
+                   const struct ice_pkg_hdr *pkg_hdr)
 {
        u32 i;
 
 
        /* Search all package segments for the requested segment type */
        for (i = 0; i < le32_to_cpu(pkg_hdr->seg_count); i++) {
-               struct ice_generic_seg_hdr *seg;
+               const struct ice_generic_seg_hdr *seg;
 
-               seg = (struct ice_generic_seg_hdr
-                              *)((u8 *)pkg_hdr +
-                                 le32_to_cpu(pkg_hdr->seg_offset[i]));
+               seg = (void *)pkg_hdr + le32_to_cpu(pkg_hdr->seg_offset[i]);
 
                if (le32_to_cpu(seg->seg_type) == seg_type)
                        return seg;
  *
  * Return: zero when update was successful, negative values otherwise.
  */
-int ice_cfg_tx_topo(struct ice_hw *hw, u8 *buf, u32 len)
+int ice_cfg_tx_topo(struct ice_hw *hw, const void *buf, u32 len)
 {
-       u8 *current_topo, *new_topo = NULL;
-       struct ice_run_time_cfg_seg *seg;
-       struct ice_buf_hdr *section;
-       struct ice_pkg_hdr *pkg_hdr;
+       u8 *new_topo = NULL, *topo __free(kfree) = NULL;
+       const struct ice_run_time_cfg_seg *seg;
+       const struct ice_buf_hdr *section;
+       const struct ice_pkg_hdr *pkg_hdr;
        enum ice_ddp_state state;
        u16 offset, size = 0;
        u32 reg = 0;
                return -EOPNOTSUPP;
        }
 
-       current_topo = kzalloc(ICE_AQ_MAX_BUF_LEN, GFP_KERNEL);
-       if (!current_topo)
+       topo = kzalloc(ICE_AQ_MAX_BUF_LEN, GFP_KERNEL);
+       if (!topo)
                return -ENOMEM;
 
-       /* Get the current Tx topology */
-       status = ice_get_set_tx_topo(hw, current_topo, ICE_AQ_MAX_BUF_LEN, NULL,
-                                    &flags, false);
-
-       kfree(current_topo);
+       /* Get the current Tx topology flags */
+       status = ice_get_set_tx_topo(hw, topo, ICE_AQ_MAX_BUF_LEN, NULL, &flags,
+                                    false);
 
        if (status) {
                ice_debug(hw, ICE_DBG_INIT, "Get current topology is failed\n");
                goto update_topo;
        }
 
-       pkg_hdr = (struct ice_pkg_hdr *)buf;
+       pkg_hdr = (const struct ice_pkg_hdr *)buf;
        state = ice_verify_pkg(pkg_hdr, len);
        if (state) {
                ice_debug(hw, ICE_DBG_INIT, "Failed to verify pkg (err: %d)\n",
        }
 
        /* Find runtime configuration segment */
-       seg = (struct ice_run_time_cfg_seg *)
+       seg = (const struct ice_run_time_cfg_seg *)
              ice_find_seg_in_pkg(hw, SEGMENT_TYPE_ICE_RUN_TIME_CFG, pkg_hdr);
        if (!seg) {
                ice_debug(hw, ICE_DBG_INIT, "5 layer topology segment is missing\n");
                return -EIO;
        }
 
-       /* Get the new topology buffer */
-       new_topo = ((u8 *)section) + offset;
+       /* Get the new topology buffer, reuse current topo copy mem */
+       static_assert(ICE_PKG_BUF_SIZE == ICE_AQ_MAX_BUF_LEN);
+       new_topo = topo;
+       memcpy(new_topo, (u8 *)section + offset, size);
 
 update_topo:
        /* Acquire global lock to make sure that set topology issued