kfree(mlxsw_sp->trap);
 }
 
+static int mlxsw_sp_lag_pgt_init(struct mlxsw_sp *mlxsw_sp)
+{
+       char sgcr_pl[MLXSW_REG_SGCR_LEN];
+       u16 max_lag;
+       int err;
+
+       if (mlxsw_core_lag_mode(mlxsw_sp->core) !=
+           MLXSW_CMD_MBOX_CONFIG_PROFILE_LAG_MODE_SW)
+               return 0;
+
+       err = mlxsw_core_max_lag(mlxsw_sp->core, &max_lag);
+       if (err)
+               return err;
+
+       /* In DDD mode, which we by default use, each LAG entry is 8 PGT
+        * entries. The LAG table address needs to be 8-aligned, but that ought
+        * to be the case, since the LAG table is allocated first.
+        */
+       err = mlxsw_sp_pgt_mid_alloc_range(mlxsw_sp, &mlxsw_sp->lag_pgt_base,
+                                          max_lag * 8);
+       if (err)
+               return err;
+       if (WARN_ON_ONCE(mlxsw_sp->lag_pgt_base % 8)) {
+               err = -EINVAL;
+               goto err_mid_alloc_range;
+       }
+
+       mlxsw_reg_sgcr_pack(sgcr_pl, mlxsw_sp->lag_pgt_base);
+       err = mlxsw_reg_write(mlxsw_sp->core, MLXSW_REG(sgcr), sgcr_pl);
+       if (err)
+               goto err_mid_alloc_range;
+
+       return 0;
+
+err_mid_alloc_range:
+       mlxsw_sp_pgt_mid_free_range(mlxsw_sp, mlxsw_sp->lag_pgt_base,
+                                   max_lag * 8);
+       return err;
+}
+
+static void mlxsw_sp_lag_pgt_fini(struct mlxsw_sp *mlxsw_sp)
+{
+       u16 max_lag;
+       int err;
+
+       if (mlxsw_core_lag_mode(mlxsw_sp->core) !=
+           MLXSW_CMD_MBOX_CONFIG_PROFILE_LAG_MODE_SW)
+               return;
+
+       err = mlxsw_core_max_lag(mlxsw_sp->core, &max_lag);
+       if (err)
+               return;
+
+       mlxsw_sp_pgt_mid_free_range(mlxsw_sp, mlxsw_sp->lag_pgt_base,
+                                   max_lag * 8);
+}
+
 #define MLXSW_SP_LAG_SEED_INIT 0xcafecafe
 
 static int mlxsw_sp_lag_init(struct mlxsw_sp *mlxsw_sp)
        if (!MLXSW_CORE_RES_VALID(mlxsw_sp->core, MAX_LAG_MEMBERS))
                return -EIO;
 
+       err = mlxsw_sp_lag_pgt_init(mlxsw_sp);
+       if (err)
+               return err;
+
        mlxsw_sp->lags = kcalloc(max_lag, sizeof(struct mlxsw_sp_upper),
                                 GFP_KERNEL);
-       if (!mlxsw_sp->lags)
-               return -ENOMEM;
+       if (!mlxsw_sp->lags) {
+               err = -ENOMEM;
+               goto err_kcalloc;
+       }
 
        return 0;
+
+err_kcalloc:
+       mlxsw_sp_lag_pgt_fini(mlxsw_sp);
+       return err;
 }
 
 static void mlxsw_sp_lag_fini(struct mlxsw_sp *mlxsw_sp)
 {
+       mlxsw_sp_lag_pgt_fini(mlxsw_sp);
        kfree(mlxsw_sp->lags);
 }
 
                goto err_pgt_init;
        }
 
+       /* Initialize before FIDs so that the LAG table is at the start of PGT
+        * and 8-aligned without overallocation.
+        */
+       err = mlxsw_sp_lag_init(mlxsw_sp);
+       if (err) {
+               dev_err(mlxsw_sp->bus_info->dev, "Failed to initialize LAG\n");
+               goto err_lag_init;
+       }
+
        err = mlxsw_sp_fids_init(mlxsw_sp);
        if (err) {
                dev_err(mlxsw_sp->bus_info->dev, "Failed to initialize FIDs\n");
                goto err_buffers_init;
        }
 
-       err = mlxsw_sp_lag_init(mlxsw_sp);
-       if (err) {
-               dev_err(mlxsw_sp->bus_info->dev, "Failed to initialize LAG\n");
-               goto err_lag_init;
-       }
-
        /* Initialize SPAN before router and switchdev, so that those components
         * can call mlxsw_sp_span_respin().
         */
 err_switchdev_init:
        mlxsw_sp_span_fini(mlxsw_sp);
 err_span_init:
-       mlxsw_sp_lag_fini(mlxsw_sp);
-err_lag_init:
        mlxsw_sp_buffers_fini(mlxsw_sp);
 err_buffers_init:
        mlxsw_sp_devlink_traps_fini(mlxsw_sp);
 err_policers_init:
        mlxsw_sp_fids_fini(mlxsw_sp);
 err_fids_init:
+       mlxsw_sp_lag_fini(mlxsw_sp);
+err_lag_init:
        mlxsw_sp_pgt_fini(mlxsw_sp);
 err_pgt_init:
        mlxsw_sp_kvdl_fini(mlxsw_sp);
        mlxsw_sp_counter_pool_fini(mlxsw_sp);
        mlxsw_sp_switchdev_fini(mlxsw_sp);
        mlxsw_sp_span_fini(mlxsw_sp);
-       mlxsw_sp_lag_fini(mlxsw_sp);
        mlxsw_sp_buffers_fini(mlxsw_sp);
        mlxsw_sp_devlink_traps_fini(mlxsw_sp);
        mlxsw_sp_traps_fini(mlxsw_sp);
        mlxsw_sp_policers_fini(mlxsw_sp);
        mlxsw_sp_fids_fini(mlxsw_sp);
+       mlxsw_sp_lag_fini(mlxsw_sp);
        mlxsw_sp_pgt_fini(mlxsw_sp);
        mlxsw_sp_kvdl_fini(mlxsw_sp);
        mlxsw_sp_parsing_fini(mlxsw_sp);