static int
 ath10k_mac_op_assign_vif_chanctx(struct ieee80211_hw *hw,
                                 struct ieee80211_vif *vif,
-                                unsigned int link_id,
+                                struct ieee80211_bss_conf *link_conf,
                                 struct ieee80211_chanctx_conf *ctx)
 {
        struct ath10k *ar = hw->priv;
 static void
 ath10k_mac_op_unassign_vif_chanctx(struct ieee80211_hw *hw,
                                   struct ieee80211_vif *vif,
-                                  unsigned int link_id,
+                                  struct ieee80211_bss_conf *link_conf,
                                   struct ieee80211_chanctx_conf *ctx)
 {
        struct ath10k *ar = hw->priv;
 
 static int
 ath11k_mac_op_assign_vif_chanctx(struct ieee80211_hw *hw,
                                 struct ieee80211_vif *vif,
-                                unsigned int link_id,
+                                struct ieee80211_bss_conf *link_conf,
                                 struct ieee80211_chanctx_conf *ctx)
 {
        struct ath11k *ar = hw->priv;
 static void
 ath11k_mac_op_unassign_vif_chanctx(struct ieee80211_hw *hw,
                                   struct ieee80211_vif *vif,
-                                  unsigned int link_id,
+                                  struct ieee80211_bss_conf *link_conf,
                                   struct ieee80211_chanctx_conf *ctx)
 {
        struct ath11k *ar = hw->priv;
 
 
 static int ath9k_assign_vif_chanctx(struct ieee80211_hw *hw,
                                    struct ieee80211_vif *vif,
-                                   unsigned int link_id,
+                                   struct ieee80211_bss_conf *link_conf,
                                    struct ieee80211_chanctx_conf *conf)
 {
        struct ath_softc *sc = hw->priv;
 
 static void ath9k_unassign_vif_chanctx(struct ieee80211_hw *hw,
                                       struct ieee80211_vif *vif,
-                                      unsigned int link_id,
+                                      struct ieee80211_bss_conf *link_conf,
                                       struct ieee80211_chanctx_conf *conf)
 {
        struct ath_softc *sc = hw->priv;
 
 }
 static int iwl_mvm_assign_vif_chanctx(struct ieee80211_hw *hw,
                                      struct ieee80211_vif *vif,
-                                     unsigned int link_id,
+                                     struct ieee80211_bss_conf *link_conf,
                                      struct ieee80211_chanctx_conf *ctx)
 {
        struct iwl_mvm *mvm = IWL_MAC80211_GET_MVM(hw);
 
 static void iwl_mvm_unassign_vif_chanctx(struct ieee80211_hw *hw,
                                         struct ieee80211_vif *vif,
-                                        unsigned int link_id,
+                                        struct ieee80211_bss_conf *link_conf,
                                         struct ieee80211_chanctx_conf *ctx)
 {
        struct iwl_mvm *mvm = IWL_MAC80211_GET_MVM(hw);
 
 
 static int mac80211_hwsim_assign_vif_chanctx(struct ieee80211_hw *hw,
                                             struct ieee80211_vif *vif,
-                                            unsigned int link_id,
+                                            struct ieee80211_bss_conf *link_conf,
                                             struct ieee80211_chanctx_conf *ctx)
 {
        hwsim_check_magic(vif);
 
 static void mac80211_hwsim_unassign_vif_chanctx(struct ieee80211_hw *hw,
                                                struct ieee80211_vif *vif,
-                                               unsigned int link_id,
+                                               struct ieee80211_bss_conf *link_conf,
                                                struct ieee80211_chanctx_conf *ctx)
 {
        hwsim_check_magic(vif);
 
 }
 
 int wfx_assign_vif_chanctx(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
-                          unsigned int link_id,
+                          struct ieee80211_bss_conf *link_conf,
                           struct ieee80211_chanctx_conf *conf)
 {
        struct wfx_vif *wvif = (struct wfx_vif *)vif->drv_priv;
 }
 
 void wfx_unassign_vif_chanctx(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
-                             unsigned int link_id,
+                             struct ieee80211_bss_conf *link_conf,
                              struct ieee80211_chanctx_conf *conf)
 {
        struct wfx_vif *wvif = (struct wfx_vif *)vif->drv_priv;
 
 void wfx_remove_chanctx(struct ieee80211_hw *hw, struct ieee80211_chanctx_conf *conf);
 void wfx_change_chanctx(struct ieee80211_hw *hw, struct ieee80211_chanctx_conf *conf, u32 changed);
 int wfx_assign_vif_chanctx(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
-                          unsigned int link_id,
+                          struct ieee80211_bss_conf *link_conf,
                           struct ieee80211_chanctx_conf *conf);
 void wfx_unassign_vif_chanctx(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
-                             unsigned int link_id,
+                             struct ieee80211_bss_conf *link_conf,
                              struct ieee80211_chanctx_conf *conf);
 
 /* Hardware API Callbacks */
 
 
 static int wlcore_op_assign_vif_chanctx(struct ieee80211_hw *hw,
                                        struct ieee80211_vif *vif,
-                                       unsigned int link_id,
+                                       struct ieee80211_bss_conf *link_conf,
                                        struct ieee80211_chanctx_conf *ctx)
 {
        struct wl1271 *wl = hw->priv;
 
 static void wlcore_op_unassign_vif_chanctx(struct ieee80211_hw *hw,
                                           struct ieee80211_vif *vif,
-                                          unsigned int link_id,
+                                          struct ieee80211_bss_conf *link_conf,
                                           struct ieee80211_chanctx_conf *ctx)
 {
        struct wl1271 *wl = hw->priv;
 
  * done.
  *
  * @vif: the vif that should be switched from old_ctx to new_ctx
- * @link_id: the link ID that's switching
+ * @link_conf: the link conf that's switching
  * @old_ctx: the old context to which the vif was assigned
  * @new_ctx: the new context to which the vif must be assigned
  */
 struct ieee80211_vif_chanctx_switch {
        struct ieee80211_vif *vif;
-       unsigned int link_id;
+       struct ieee80211_bss_conf *link_conf;
        struct ieee80211_chanctx_conf *old_ctx;
        struct ieee80211_chanctx_conf *new_ctx;
 };
                               u32 changed);
        int (*assign_vif_chanctx)(struct ieee80211_hw *hw,
                                  struct ieee80211_vif *vif,
-                                 unsigned int link_id,
+                                 struct ieee80211_bss_conf *link_conf,
                                  struct ieee80211_chanctx_conf *ctx);
        void (*unassign_vif_chanctx)(struct ieee80211_hw *hw,
                                     struct ieee80211_vif *vif,
-                                    unsigned int link_id,
+                                    struct ieee80211_bss_conf *link_conf,
                                     struct ieee80211_chanctx_conf *ctx);
        int (*switch_vif_chanctx)(struct ieee80211_hw *hw,
                                  struct ieee80211_vif_chanctx_switch *vifs,
 
                                         struct ieee80211_chanctx *new_ctx)
 {
        struct ieee80211_sub_if_data *sdata = link->sdata;
-       unsigned int link_id = link->link_id;
        struct ieee80211_local *local = sdata->local;
        struct ieee80211_chanctx_conf *conf;
        struct ieee80211_chanctx *curr_ctx = NULL;
        if (conf) {
                curr_ctx = container_of(conf, struct ieee80211_chanctx, conf);
 
-               drv_unassign_vif_chanctx(local, sdata, link_id, curr_ctx);
+               drv_unassign_vif_chanctx(local, sdata, link->conf, curr_ctx);
                conf = NULL;
                list_del(&link->assigned_chanctx_list);
        }
 
        if (new_ctx) {
-               ret = drv_assign_vif_chanctx(local, sdata, link_id, new_ctx);
+               ret = drv_assign_vif_chanctx(local, sdata, link->conf, new_ctx);
                if (ret)
                        goto out;
 
        vif_chsw[0].vif = &sdata->vif;
        vif_chsw[0].old_ctx = &old_ctx->conf;
        vif_chsw[0].new_ctx = &new_ctx->conf;
-       vif_chsw[0].link_id = link->link_id;
+       vif_chsw[0].link_conf = link->conf;
 
        list_del(&link->reserved_chanctx_list);
        link->reserved_chanctx = NULL;
                        vif_chsw[i].vif = &link->sdata->vif;
                        vif_chsw[i].old_ctx = &old_ctx->conf;
                        vif_chsw[i].new_ctx = &ctx->conf;
-                       vif_chsw[i].link_id = link->link_id;
+                       vif_chsw[i].link_conf = link->conf;
 
                        i++;
                }
 
        trace_drv_return_void(local);
 }
 
+static inline void drv_verify_link_exists(struct ieee80211_sub_if_data *sdata,
+                                         struct ieee80211_bss_conf *link_conf)
+{
+       /* deflink always exists, so need to check only for other links */
+       if (sdata->deflink.conf != link_conf)
+               sdata_assert_lock(sdata);
+}
+
 static inline int drv_assign_vif_chanctx(struct ieee80211_local *local,
                                         struct ieee80211_sub_if_data *sdata,
-                                        unsigned int link_id,
+                                        struct ieee80211_bss_conf *link_conf,
                                         struct ieee80211_chanctx *ctx)
 {
        int ret = 0;
 
+       drv_verify_link_exists(sdata, link_conf);
        if (!check_sdata_in_driver(sdata))
                return -EIO;
 
-       trace_drv_assign_vif_chanctx(local, sdata, link_id, ctx);
+       trace_drv_assign_vif_chanctx(local, sdata, link_conf, ctx);
        if (local->ops->assign_vif_chanctx) {
                WARN_ON_ONCE(!ctx->driver_present);
                ret = local->ops->assign_vif_chanctx(&local->hw,
                                                     &sdata->vif,
-                                                    link_id,
+                                                    link_conf,
                                                     &ctx->conf);
        }
        trace_drv_return_int(local, ret);
 
 static inline void drv_unassign_vif_chanctx(struct ieee80211_local *local,
                                            struct ieee80211_sub_if_data *sdata,
-                                           unsigned int link_id,
+                                           struct ieee80211_bss_conf *link_conf,
                                            struct ieee80211_chanctx *ctx)
 {
        might_sleep();
 
+       drv_verify_link_exists(sdata, link_conf);
        if (!check_sdata_in_driver(sdata))
                return;
 
-       trace_drv_unassign_vif_chanctx(local, sdata, link_id, ctx);
+       trace_drv_unassign_vif_chanctx(local, sdata, link_conf, ctx);
        if (local->ops->unassign_vif_chanctx) {
                WARN_ON_ONCE(!ctx->driver_present);
                local->ops->unassign_vif_chanctx(&local->hw,
                                                 &sdata->vif,
-                                                link_id,
+                                                link_conf,
                                                 &ctx->conf);
        }
        trace_drv_return_void(local);
        int ret = 0;
 
        /* make sure link_conf is protected */
-       sdata_assert_lock(sdata);
+       drv_verify_link_exists(sdata, link_conf);
 
        might_sleep();
 
                               struct ieee80211_bss_conf *link_conf)
 {
        /* make sure link_conf is protected */
-       sdata_assert_lock(sdata);
+       drv_verify_link_exists(sdata, link_conf);
 
        if (!check_sdata_in_driver(sdata))
                return;
 
 
                                SWITCH_ENTRY_ASSIGN(vif.vif_type, vif->type);
                                SWITCH_ENTRY_ASSIGN(vif.p2p, vif->p2p);
-                               SWITCH_ENTRY_ASSIGN(link_id, link_id);
+                               SWITCH_ENTRY_ASSIGN(link_id, link_conf->link_id);
                                strncpy(local_vifs[i].vif.vif_name,
                                        sdata->name,
                                        sizeof(local_vifs[i].vif.vif_name));
 DECLARE_EVENT_CLASS(local_sdata_chanctx,
        TP_PROTO(struct ieee80211_local *local,
                 struct ieee80211_sub_if_data *sdata,
-                unsigned int link_id,
+                struct ieee80211_bss_conf *link_conf,
                 struct ieee80211_chanctx *ctx),
 
-       TP_ARGS(local, sdata, link_id, ctx),
+       TP_ARGS(local, sdata, link_conf, ctx),
 
        TP_STRUCT__entry(
                LOCAL_ENTRY
                LOCAL_ASSIGN;
                VIF_ASSIGN;
                CHANCTX_ASSIGN;
-               __entry->link_id = link_id;
+               __entry->link_id = link_conf->link_id;
        ),
 
        TP_printk(
 DEFINE_EVENT(local_sdata_chanctx, drv_assign_vif_chanctx,
        TP_PROTO(struct ieee80211_local *local,
                 struct ieee80211_sub_if_data *sdata,
-                unsigned int link_id,
+                struct ieee80211_bss_conf *link_conf,
                 struct ieee80211_chanctx *ctx),
-       TP_ARGS(local, sdata, link_id, ctx)
+       TP_ARGS(local, sdata, link_conf, ctx)
 );
 
 DEFINE_EVENT(local_sdata_chanctx, drv_unassign_vif_chanctx,
        TP_PROTO(struct ieee80211_local *local,
                 struct ieee80211_sub_if_data *sdata,
-                unsigned int link_id,
+                struct ieee80211_bss_conf *link_conf,
                 struct ieee80211_chanctx *ctx),
-       TP_ARGS(local, sdata, link_id, ctx)
+       TP_ARGS(local, sdata, link_conf, ctx)
 );
 
 TRACE_EVENT(drv_start_ap,
 
                                         lockdep_is_held(&local->chanctx_mtx));
        if (conf) {
                ctx = container_of(conf, struct ieee80211_chanctx, conf);
-               drv_assign_vif_chanctx(local, sdata, link->link_id, ctx);
+               drv_assign_vif_chanctx(local, sdata, link->conf, ctx);
        }
        mutex_unlock(&local->chanctx_mtx);
 }