bool do_bond, roce_lag;
        int err;
 
-       if (!dev0 || !dev1)
+       if (!mlx5_lag_is_ready(ldev))
                return;
 
        spin_lock(&lag_lock);
         */
        is_in_lag = num_slaves == MLX5_MAX_PORTS && bond_status == 0x3;
 
+       if (!mlx5_lag_is_ready(ldev) && is_in_lag) {
+               NL_SET_ERR_MSG_MOD(info->info.extack,
+                                  "Can't activate LAG offload, PF is configured with more than 64 VFs");
+               return 0;
+       }
+
        /* Lag mode must be activebackup or hash. */
        mode_supported = tracker->tx_type == NETDEV_LAG_TX_TYPE_ACTIVEBACKUP ||
                         tracker->tx_type == NETDEV_LAG_TX_TYPE_HASH;
                return NOTIFY_DONE;
 
        ldev    = container_of(this, struct mlx5_lag, nb);
+
+       if (!mlx5_lag_is_ready(ldev) && event == NETDEV_CHANGELOWERSTATE)
+               return NOTIFY_DONE;
+
        tracker = ldev->tracker;
 
        switch (event) {
        kfree(ldev);
 }
 
-static void mlx5_lag_dev_add_pf(struct mlx5_lag *ldev,
-                               struct mlx5_core_dev *dev,
-                               struct net_device *netdev)
+static int mlx5_lag_dev_add_pf(struct mlx5_lag *ldev,
+                              struct mlx5_core_dev *dev,
+                              struct net_device *netdev)
 {
        unsigned int fn = PCI_FUNC(dev->pdev->devfn);
 
        if (fn >= MLX5_MAX_PORTS)
-               return;
+               return -EPERM;
 
        spin_lock(&lag_lock);
        ldev->pf[fn].dev    = dev;
        dev->priv.lag = ldev;
 
        spin_unlock(&lag_lock);
+
+       return fn;
 }
 
 static void mlx5_lag_dev_remove_pf(struct mlx5_lag *ldev,
 {
        struct mlx5_lag *ldev = NULL;
        struct mlx5_core_dev *tmp_dev;
-       int err;
+       int i, err;
 
-       if (!MLX5_CAP_GEN(dev, vport_group_manager) ||
-           !MLX5_CAP_GEN(dev, lag_master) ||
-           (MLX5_CAP_GEN(dev, num_lag_ports) != MLX5_MAX_PORTS))
+       if (!MLX5_CAP_GEN(dev, vport_group_manager))
                return;
 
        tmp_dev = mlx5_get_next_phys_dev(dev);
                }
        }
 
-       mlx5_lag_dev_add_pf(ldev, dev, netdev);
+       if (mlx5_lag_dev_add_pf(ldev, dev, netdev) < 0)
+               return;
+
+       for (i = 0; i < MLX5_MAX_PORTS; i++) {
+               tmp_dev = ldev->pf[i].dev;
+               if (!tmp_dev || !MLX5_CAP_GEN(tmp_dev, lag_master) ||
+                   MLX5_CAP_GEN(tmp_dev, num_lag_ports) != MLX5_MAX_PORTS)
+                       break;
+       }
+
+       if (i >= MLX5_MAX_PORTS)
+               ldev->flags |= MLX5_LAG_FLAG_READY;
 
        if (!ldev->nb.notifier_call) {
                ldev->nb.notifier_call = mlx5_lag_netdev_event;
 
        mlx5_lag_dev_remove_pf(ldev, dev);
 
+       ldev->flags &= ~MLX5_LAG_FLAG_READY;
+
        for (i = 0; i < MLX5_MAX_PORTS; i++)
                if (ldev->pf[i].dev)
                        break;
 
        MLX5_LAG_FLAG_ROCE   = 1 << 0,
        MLX5_LAG_FLAG_SRIOV  = 1 << 1,
        MLX5_LAG_FLAG_MULTIPATH = 1 << 2,
+       MLX5_LAG_FLAG_READY = 1 << 3,
 };
 
 #define MLX5_LAG_MODE_FLAGS (MLX5_LAG_FLAG_ROCE | MLX5_LAG_FLAG_SRIOV |\
        return !!(ldev->flags & MLX5_LAG_MODE_FLAGS);
 }
 
+static inline bool
+mlx5_lag_is_ready(struct mlx5_lag *ldev)
+{
+       return ldev->flags & MLX5_LAG_FLAG_READY;
+}
+
 void mlx5_modify_lag(struct mlx5_lag *ldev,
                     struct lag_tracker *tracker);
 int mlx5_activate_lag(struct mlx5_lag *ldev,