struct mlxsw_sp_vr *vr;
        struct list_head nexthop_group_node;
        struct mlxsw_sp_nexthop_group *nh_group;
+       bool offloaded;
 };
 
 struct mlxsw_sp_fib {
        mlxsw_sp_nexthop_group_destroy(mlxsw_sp, nh_grp);
 }
 
+static bool
+mlxsw_sp_fib_entry_should_offload(const struct mlxsw_sp_fib_entry *fib_entry)
+{
+       struct mlxsw_sp_nexthop_group *nh_group = fib_entry->nh_group;
+
+       switch (fib_entry->type) {
+       case MLXSW_SP_FIB_ENTRY_TYPE_REMOTE:
+               return !!nh_group->adj_index_valid;
+       case MLXSW_SP_FIB_ENTRY_TYPE_LOCAL:
+               return true;
+       default:
+               return false;
+       }
+}
+
+static void mlxsw_sp_fib_entry_offload_set(struct mlxsw_sp_fib_entry *fib_entry)
+{
+       fib_entry->offloaded = true;
+
+       switch (fib_entry->vr->proto) {
+       case MLXSW_SP_L3_PROTO_IPV4:
+               fib_info_offload_inc(fib_entry->nh_group->key.fi);
+               break;
+       case MLXSW_SP_L3_PROTO_IPV6:
+               WARN_ON_ONCE(1);
+       }
+}
+
+static void
+mlxsw_sp_fib_entry_offload_unset(struct mlxsw_sp_fib_entry *fib_entry)
+{
+       switch (fib_entry->vr->proto) {
+       case MLXSW_SP_L3_PROTO_IPV4:
+               fib_info_offload_dec(fib_entry->nh_group->key.fi);
+               break;
+       case MLXSW_SP_L3_PROTO_IPV6:
+               WARN_ON_ONCE(1);
+       }
+
+       fib_entry->offloaded = false;
+}
+
+static void
+mlxsw_sp_fib_entry_offload_refresh(struct mlxsw_sp_fib_entry *fib_entry,
+                                  enum mlxsw_reg_ralue_op op, int err)
+{
+       switch (op) {
+       case MLXSW_REG_RALUE_OP_WRITE_DELETE:
+               if (!fib_entry->offloaded)
+                       return;
+               return mlxsw_sp_fib_entry_offload_unset(fib_entry);
+       case MLXSW_REG_RALUE_OP_WRITE_WRITE:
+               if (err)
+                       return;
+               if (mlxsw_sp_fib_entry_should_offload(fib_entry) &&
+                   !fib_entry->offloaded)
+                       mlxsw_sp_fib_entry_offload_set(fib_entry);
+               else if (!mlxsw_sp_fib_entry_should_offload(fib_entry) &&
+                        fib_entry->offloaded)
+                       mlxsw_sp_fib_entry_offload_unset(fib_entry);
+               return;
+       default:
+               return;
+       }
+}
+
 static int mlxsw_sp_fib_entry_op4_remote(struct mlxsw_sp *mlxsw_sp,
                                         struct mlxsw_sp_fib_entry *fib_entry,
                                         enum mlxsw_reg_ralue_op op)
                                 struct mlxsw_sp_fib_entry *fib_entry,
                                 enum mlxsw_reg_ralue_op op)
 {
+       int err = -EINVAL;
+
        switch (fib_entry->vr->proto) {
        case MLXSW_SP_L3_PROTO_IPV4:
-               return mlxsw_sp_fib_entry_op4(mlxsw_sp, fib_entry, op);
+               err = mlxsw_sp_fib_entry_op4(mlxsw_sp, fib_entry, op);
+               break;
        case MLXSW_SP_L3_PROTO_IPV6:
-               return -EINVAL;
+               return err;
        }
-       return -EINVAL;
+       mlxsw_sp_fib_entry_offload_refresh(fib_entry, op, err);
+       return err;
 }
 
 static int mlxsw_sp_fib_entry_update(struct mlxsw_sp *mlxsw_sp,
 }
 
 static int
-mlxsw_sp_router_fib4_entry_init(struct mlxsw_sp *mlxsw_sp,
-                               const struct fib_entry_notifier_info *fen_info,
-                               struct mlxsw_sp_fib_entry *fib_entry)
+mlxsw_sp_fib4_entry_type_set(struct mlxsw_sp *mlxsw_sp,
+                            const struct fib_entry_notifier_info *fen_info,
+                            struct mlxsw_sp_fib_entry *fib_entry)
 {
        struct fib_info *fi = fen_info->fi;
        struct mlxsw_sp_rif *r = NULL;
                fib_entry->type = MLXSW_SP_FIB_ENTRY_TYPE_LOCAL;
        else
                fib_entry->type = MLXSW_SP_FIB_ENTRY_TYPE_REMOTE;
-       fib_info_offload_inc(fen_info->fi);
        return 0;
 }
 
-static void
-mlxsw_sp_router_fib4_entry_fini(struct mlxsw_sp *mlxsw_sp,
-                               struct mlxsw_sp_fib_entry *fib_entry)
-{
-       if (fib_entry->type != MLXSW_SP_FIB_ENTRY_TYPE_TRAP)
-               fib_info_offload_dec(fib_entry->nh_group->key.fi);
-}
-
 static struct mlxsw_sp_fib_entry *
 mlxsw_sp_fib_entry_get(struct mlxsw_sp *mlxsw_sp,
                       const struct fib_entry_notifier_info *fen_info)
        fib_entry->vr = vr;
        fib_entry->ref_count = 1;
 
-       err = mlxsw_sp_router_fib4_entry_init(mlxsw_sp, fen_info, fib_entry);
+       err = mlxsw_sp_fib4_entry_type_set(mlxsw_sp, fen_info, fib_entry);
        if (err)
-               goto err_fib4_entry_init;
+               goto err_fib4_entry_type_set;
 
        err = mlxsw_sp_nexthop_group_get(mlxsw_sp, fib_entry, fi);
        if (err)
        return fib_entry;
 
 err_nexthop_group_get:
-       mlxsw_sp_router_fib4_entry_fini(mlxsw_sp, fib_entry);
-err_fib4_entry_init:
+err_fib4_entry_type_set:
        mlxsw_sp_fib_entry_destroy(fib_entry);
 err_fib_entry_create:
        mlxsw_sp_vr_put(mlxsw_sp, vr);
 
        if (--fib_entry->ref_count == 0) {
                mlxsw_sp_nexthop_group_put(mlxsw_sp, fib_entry);
-               mlxsw_sp_router_fib4_entry_fini(mlxsw_sp, fib_entry);
                mlxsw_sp_fib_entry_destroy(fib_entry);
        }
        mlxsw_sp_vr_put(mlxsw_sp, vr);