wifi: rtw89: read bss_conf corresponding to the link
authorZong-Zhe Yang <kevin_yang@realtek.com>
Mon, 16 Sep 2024 05:31:54 +0000 (13:31 +0800)
committerPing-Ke Shih <pkshih@realtek.com>
Tue, 24 Sep 2024 01:14:55 +0000 (09:14 +0800)
Tweak code to not always access vif->bss_conf directly. Instead,
according to link_id, read target bss_conf from vif->link_conf[].

For now, rtwvif_link->link_id keeps 0. When driver starts to
support MLO, the link_id will be assigned.

Signed-off-by: Zong-Zhe Yang <kevin_yang@realtek.com>
Signed-off-by: Ping-Ke Shih <pkshih@realtek.com>
Link: https://patch.msgid.link/20240916053158.47350-4-pkshih@realtek.com
14 files changed:
drivers/net/wireless/realtek/rtw89/cam.c
drivers/net/wireless/realtek/rtw89/chan.c
drivers/net/wireless/realtek/rtw89/coex.c
drivers/net/wireless/realtek/rtw89/core.c
drivers/net/wireless/realtek/rtw89/core.h
drivers/net/wireless/realtek/rtw89/fw.c
drivers/net/wireless/realtek/rtw89/fw.h
drivers/net/wireless/realtek/rtw89/mac.c
drivers/net/wireless/realtek/rtw89/mac80211.c
drivers/net/wireless/realtek/rtw89/phy.c
drivers/net/wireless/realtek/rtw89/ps.c
drivers/net/wireless/realtek/rtw89/ps.h
drivers/net/wireless/realtek/rtw89/regd.c
drivers/net/wireless/realtek/rtw89/wow.c

index 80deb0712b8348e59ddefdad1968bc1b14446ec7..757f7633b079bc3ad7ffd13060a89214083599e2 100644 (file)
@@ -655,17 +655,24 @@ int rtw89_cam_fill_bssid_cam_info(struct rtw89_dev *rtwdev,
                                  struct rtw89_vif_link *rtwvif_link,
                                  struct rtw89_sta_link *rtwsta_link, u8 *cmd)
 {
-       struct ieee80211_vif *vif = rtwvif_to_vif(rtwvif_link);
        struct rtw89_bssid_cam_entry *bssid_cam = rtw89_get_bssid_cam_of(rtwvif_link,
                                                                         rtwsta_link);
-       u8 bss_color = vif->bss_conf.he_bss_color.color;
+       struct ieee80211_bss_conf *bss_conf;
+       u8 bss_color;
        u8 bss_mask;
 
-       if (vif->bss_conf.nontransmitted)
+       rcu_read_lock();
+
+       bss_conf = rtw89_vif_rcu_dereference_link(rtwvif_link, false);
+       bss_color = bss_conf->he_bss_color.color;
+
+       if (bss_conf->nontransmitted)
                bss_mask = RTW89_BSSID_MATCH_5_BYTES;
        else
                bss_mask = RTW89_BSSID_MATCH_ALL;
 
+       rcu_read_unlock();
+
        FWCMD_SET_ADDR_BSSID_IDX(cmd, bssid_cam->bssid_cam_idx);
        FWCMD_SET_ADDR_BSSID_OFFSET(cmd, bssid_cam->offset);
        FWCMD_SET_ADDR_BSSID_LEN(cmd, bssid_cam->len);
index 2f14ac6687163b13c133ab322f89129c914b4d51..2968c299203b895f21533c603adbb8b13b228a6a 100644 (file)
@@ -564,8 +564,9 @@ static void rtw89_mcc_fill_role_policy(struct rtw89_dev *rtwdev,
 static void rtw89_mcc_fill_role_limit(struct rtw89_dev *rtwdev,
                                      struct rtw89_mcc_role *mcc_role)
 {
-       struct ieee80211_vif *vif = rtwvif_to_vif(mcc_role->rtwvif_link);
+       struct rtw89_vif_link *rtwvif_link = mcc_role->rtwvif_link;
        struct ieee80211_p2p_noa_desc *noa_desc;
+       struct ieee80211_bss_conf *bss_conf;
        u32 bcn_intvl_us = ieee80211_tu_to_usec(mcc_role->beacon_interval);
        u32 max_toa_us, max_tob_us, max_dur_us;
        u32 start_time, interval, duration;
@@ -576,13 +577,18 @@ static void rtw89_mcc_fill_role_limit(struct rtw89_dev *rtwdev,
        if (!mcc_role->is_go && !mcc_role->is_gc)
                return;
 
+       rcu_read_lock();
+
+       bss_conf = rtw89_vif_rcu_dereference_link(rtwvif_link, true);
+
        /* find the first periodic NoA */
        for (i = 0; i < RTW89_P2P_MAX_NOA_NUM; i++) {
-               noa_desc = &vif->bss_conf.p2p_noa_attr.desc[i];
+               noa_desc = &bss_conf->p2p_noa_attr.desc[i];
                if (noa_desc->count == 255)
                        goto fill;
        }
 
+       rcu_read_unlock();
        return;
 
 fill:
@@ -590,6 +596,8 @@ fill:
        interval = le32_to_cpu(noa_desc->interval);
        duration = le32_to_cpu(noa_desc->duration);
 
+       rcu_read_unlock();
+
        if (interval != bcn_intvl_us) {
                rtw89_debug(rtwdev, RTW89_DBG_CHAN,
                            "MCC role limit: mismatch interval: %d vs. %d\n",
@@ -635,12 +643,18 @@ static int rtw89_mcc_fill_role(struct rtw89_dev *rtwdev,
                               struct rtw89_vif_link *rtwvif_link,
                               struct rtw89_mcc_role *role)
 {
-       struct ieee80211_vif *vif = rtwvif_to_vif(rtwvif_link);
+       struct ieee80211_bss_conf *bss_conf;
        const struct rtw89_chan *chan;
 
        memset(role, 0, sizeof(*role));
        role->rtwvif_link = rtwvif_link;
-       role->beacon_interval = vif->bss_conf.beacon_int;
+
+       rcu_read_lock();
+
+       bss_conf = rtw89_vif_rcu_dereference_link(rtwvif_link, true);
+       role->beacon_interval = bss_conf->beacon_int;
+
+       rcu_read_unlock();
 
        if (!role->beacon_interval) {
                rtw89_warn(rtwdev,
index 174e79b73352fd04276268214ed30c4988053f3c..591c24df1825216f64dadc75119025b093299596 100644 (file)
@@ -7488,6 +7488,7 @@ void rtw89_btc_ntfy_role_info(struct rtw89_dev *rtwdev,
                                                       rtwvif_link->chanctx_idx);
        struct ieee80211_vif *vif = rtwvif_to_vif(rtwvif_link);
        struct ieee80211_sta *sta = rtwsta_to_sta(rtwsta_link);
+       struct ieee80211_bss_conf *bss_conf;
        struct rtw89_btc *btc = &rtwdev->btc;
        const struct rtw89_btc_ver *ver = btc->ver;
        struct rtw89_btc_wl_info *wl = &btc->cx.wl;
@@ -7495,6 +7496,10 @@ void rtw89_btc_ntfy_role_info(struct rtw89_dev *rtwdev,
        struct rtw89_btc_wl_link_info *wlinfo = NULL;
        u8 mode = 0, rlink_id, link_mode_ori, pta_req_mac_ori, wa_type;
 
+       rcu_read_lock();
+
+       bss_conf = rtw89_vif_rcu_dereference_link(rtwvif_link, false);
+
        rtw89_debug(rtwdev, RTW89_DBG_BTC, "[BTC], state=%d\n", state);
        rtw89_debug(rtwdev, RTW89_DBG_BTC,
                    "[BTC], role is STA=%d\n",
@@ -7506,7 +7511,7 @@ void rtw89_btc_ntfy_role_info(struct rtw89_dev *rtwdev,
                    state == BTC_ROLE_MSTS_STA_CONN_END);
        rtw89_debug(rtwdev, RTW89_DBG_BTC,
                    "[BTC], bcn_period=%d dtim_period=%d\n",
-                   vif->bss_conf.beacon_int, vif->bss_conf.dtim_period);
+                   bss_conf->beacon_int, bss_conf->dtim_period);
 
        if (rtwsta_link) {
                rtw89_debug(rtwdev, RTW89_DBG_BTC, "[BTC], STA mac_id=%d\n",
@@ -7527,8 +7532,10 @@ void rtw89_btc_ntfy_role_info(struct rtw89_dev *rtwdev,
                r.mode = mode;
        }
 
-       if (rtwvif_link->wifi_role >= RTW89_WIFI_ROLE_MLME_MAX)
+       if (rtwvif_link->wifi_role >= RTW89_WIFI_ROLE_MLME_MAX) {
+               rcu_read_unlock();
                return;
+       }
 
        rtw89_debug(rtwdev, RTW89_DBG_BTC,
                    "[BTC], wifi_role=%d\n", rtwvif_link->wifi_role);
@@ -7538,8 +7545,8 @@ void rtw89_btc_ntfy_role_info(struct rtw89_dev *rtwdev,
        r.pid = rtwvif_link->port;
        r.active = true;
        r.connected = MLME_LINKED;
-       r.bcn_period = vif->bss_conf.beacon_int;
-       r.dtim_period = vif->bss_conf.dtim_period;
+       r.bcn_period = bss_conf->beacon_int;
+       r.dtim_period = bss_conf->dtim_period;
        r.band = chan->band_type;
        r.ch = chan->channel;
        r.bw = chan->band_width;
@@ -7549,6 +7556,8 @@ void rtw89_btc_ntfy_role_info(struct rtw89_dev *rtwdev,
        r.chdef.chan = chan->primary_channel;
        ether_addr_copy(r.mac_addr, rtwvif_link->mac_addr);
 
+       rcu_read_unlock();
+
        if (rtwsta_link && vif->type == NL80211_IFTYPE_STATION)
                r.mac_id = rtwsta_link->mac_id;
 
index 2b6a8fe0e53b0d27193b8bc323fd54eb4e6f7e8c..f1db598c6004865a78b38611407cebea42082057 100644 (file)
@@ -571,7 +571,10 @@ static u16 rtw89_core_get_mgmt_rate(struct rtw89_dev *rtwdev,
        struct sk_buff *skb = tx_req->skb;
        struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(skb);
        struct ieee80211_vif *vif = tx_info->control.vif;
+       struct rtw89_vif_link *rtwvif_link = vif_to_rtwvif_safe(vif);
+       struct ieee80211_bss_conf *bss_conf;
        u16 lowest_rate;
+       u16 rate;
 
        if (tx_info->flags & IEEE80211_TX_CTL_NO_CCK_RATE ||
            (vif && vif->p2p))
@@ -581,10 +584,23 @@ static u16 rtw89_core_get_mgmt_rate(struct rtw89_dev *rtwdev,
        else
                lowest_rate = RTW89_HW_RATE_OFDM6;
 
-       if (!vif || !vif->bss_conf.basic_rates || !tx_req->sta)
+       if (!rtwvif_link)
                return lowest_rate;
 
-       return __ffs(vif->bss_conf.basic_rates) + lowest_rate;
+       rcu_read_lock();
+
+       bss_conf = rtw89_vif_rcu_dereference_link(rtwvif_link, false);
+       if (!bss_conf->basic_rates || !tx_req->sta) {
+               rate = lowest_rate;
+               goto out;
+       }
+
+       rate = __ffs(bss_conf->basic_rates) + lowest_rate;
+
+out:
+       rcu_read_unlock();
+
+       return rate;
 }
 
 static u8 rtw89_core_tx_get_mac_id(struct rtw89_dev *rtwdev,
@@ -1879,6 +1895,7 @@ struct rtw89_vif_rx_stats_iter_data {
 
 static void rtw89_stats_trigger_frame(struct rtw89_dev *rtwdev,
                                      struct ieee80211_vif *vif,
+                                     struct ieee80211_bss_conf *bss_conf,
                                      struct sk_buff *skb)
 {
        struct rtw89_vif_link *rtwvif_link = (struct rtw89_vif_link *)vif->drv_priv;
@@ -1886,7 +1903,7 @@ static void rtw89_stats_trigger_frame(struct rtw89_dev *rtwdev,
        u8 *pos, *end, type, tf_bw;
        u16 aid, tf_rua;
 
-       if (!ether_addr_equal(vif->bss_conf.bssid, tf->ta) ||
+       if (!ether_addr_equal(bss_conf->bssid, tf->ta) ||
            rtwvif_link->wifi_role != RTW89_WIFI_ROLE_STATION ||
            rtwvif_link->net_type == RTW89_NET_TYPE_NO_LINK)
                return;
@@ -2010,6 +2027,7 @@ static void rtw89_vif_rx_stats_iter(void *data, u8 *mac,
        struct sk_buff *skb = iter_data->skb;
        struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data;
        struct rtw89_rx_phy_ppdu *phy_ppdu = iter_data->phy_ppdu;
+       struct ieee80211_bss_conf *bss_conf;
        const u8 *bssid = iter_data->bssid;
 
        if (rtwdev->scanning &&
@@ -2017,16 +2035,19 @@ static void rtw89_vif_rx_stats_iter(void *data, u8 *mac,
             ieee80211_is_probe_resp(hdr->frame_control)))
                rtw89_core_cancel_6ghz_probe_tx(rtwdev, skb);
 
-       if (!vif->bss_conf.bssid)
-               return;
+       rcu_read_lock();
+
+       bss_conf = rtw89_vif_rcu_dereference_link(rtwvif_link, false);
+       if (!bss_conf->bssid)
+               goto out;
 
        if (ieee80211_is_trigger(hdr->frame_control)) {
-               rtw89_stats_trigger_frame(rtwdev, vif, skb);
-               return;
+               rtw89_stats_trigger_frame(rtwdev, vif, bss_conf, skb);
+               goto out;
        }
 
-       if (!ether_addr_equal(vif->bss_conf.bssid, bssid))
-               return;
+       if (!ether_addr_equal(bss_conf->bssid, bssid))
+               goto out;
 
        if (ieee80211_is_beacon(hdr->frame_control)) {
                if (vif->type == NL80211_IFTYPE_STATION &&
@@ -2037,13 +2058,16 @@ static void rtw89_vif_rx_stats_iter(void *data, u8 *mac,
                pkt_stat->beacon_nr++;
        }
 
-       if (!ether_addr_equal(vif->addr, hdr->addr1))
-               return;
+       if (!ether_addr_equal(bss_conf->addr, hdr->addr1))
+               goto out;
 
        if (desc_info->data_rate < RTW89_HW_RATE_NR)
                pkt_stat->rx_rate_cnt[desc_info->data_rate]++;
 
        rtw89_traffic_stats_accu(rtwdev, &rtwvif_link->stats, skb, false);
+
+out:
+       rcu_read_unlock();
 }
 
 static void rtw89_core_rx_stats(struct rtw89_dev *rtwdev,
@@ -3008,7 +3032,7 @@ static int rtw89_core_send_nullfunc(struct rtw89_dev *rtwdev,
                return 0;
 
        rcu_read_lock();
-       sta = ieee80211_find_sta(vif, vif->bss_conf.bssid);
+       sta = ieee80211_find_sta(vif, vif->cfg.ap_addr);
        if (!sta) {
                ret = -EINVAL;
                goto out;
@@ -3241,14 +3265,16 @@ static void rtw89_core_rfk_track(struct rtw89_dev *rtwdev)
        rtw89_chip_rfk_track(rtwdev);
 }
 
-void rtw89_core_update_p2p_ps(struct rtw89_dev *rtwdev, struct ieee80211_vif *vif)
+void rtw89_core_update_p2p_ps(struct rtw89_dev *rtwdev,
+                             struct rtw89_vif_link *rtwvif_link,
+                             struct ieee80211_bss_conf *bss_conf)
 {
        enum rtw89_entity_mode mode = rtw89_get_entity_mode(rtwdev);
 
        if (mode == RTW89_ENTITY_MODE_MCC)
                rtw89_queue_chanctx_change(rtwdev, RTW89_CHANCTX_P2P_PS_CHANGE);
        else
-               rtw89_process_p2p_ps(rtwdev, vif);
+               rtw89_process_p2p_ps(rtwdev, rtwvif_link, bss_conf);
 }
 
 void rtw89_traffic_stats_init(struct rtw89_dev *rtwdev,
@@ -3410,6 +3436,7 @@ int rtw89_core_release_sta_ba_entry(struct rtw89_dev *rtwdev,
 void rtw89_vif_type_mapping(struct ieee80211_vif *vif, bool assoc)
 {
        struct rtw89_vif_link *rtwvif_link = (struct rtw89_vif_link *)vif->drv_priv;
+       const struct ieee80211_bss_conf *bss_conf;
 
        switch (vif->type) {
        case NL80211_IFTYPE_STATION:
@@ -3445,7 +3472,11 @@ void rtw89_vif_type_mapping(struct ieee80211_vif *vif, bool assoc)
        case NL80211_IFTYPE_STATION:
                if (assoc) {
                        rtwvif_link->net_type = RTW89_NET_TYPE_INFRA;
-                       rtwvif_link->trigger = vif->bss_conf.he_support;
+
+                       rcu_read_lock();
+                       bss_conf = rtw89_vif_rcu_dereference_link(rtwvif_link, false);
+                       rtwvif_link->trigger = bss_conf->he_support;
+                       rcu_read_unlock();
                } else {
                        rtwvif_link->net_type = RTW89_NET_TYPE_NO_LINK;
                        rtwvif_link->trigger = false;
@@ -3656,12 +3687,17 @@ int rtw89_core_sta_assoc(struct rtw89_dev *rtwdev,
        rtw89_mac_bf_monitor_calc(rtwdev, sta, false);
 
        if (vif->type == NL80211_IFTYPE_STATION && !sta->tdls) {
-               struct ieee80211_bss_conf *bss_conf = &vif->bss_conf;
+               struct ieee80211_bss_conf *bss_conf;
+
+               rcu_read_lock();
 
+               bss_conf = rtw89_vif_rcu_dereference_link(rtwvif_link, true);
                if (bss_conf->he_support &&
                    !(bss_conf->he_oper.params & IEEE80211_HE_OPERATION_ER_SU_DISABLE))
                        rtwsta_link->er_cap = true;
 
+               rcu_read_unlock();
+
                rtw89_btc_ntfy_role_info(rtwdev, rtwvif_link, rtwsta_link,
                                         BTC_ROLE_MSTS_STA_CONN_END);
                rtw89_core_get_no_ul_ofdma_htc(rtwdev, &rtwsta_link->htc_template, chan);
@@ -4480,11 +4516,18 @@ void rtw89_core_scan_complete(struct rtw89_dev *rtwdev,
 {
        struct rtw89_vif_link *rtwvif_link =
                vif ? (struct rtw89_vif_link *)vif->drv_priv : NULL;
+       struct ieee80211_bss_conf *bss_conf;
 
        if (!rtwvif_link)
                return;
 
-       ether_addr_copy(rtwvif_link->mac_addr, vif->addr);
+       rcu_read_lock();
+
+       bss_conf = rtw89_vif_rcu_dereference_link(rtwvif_link, true);
+       ether_addr_copy(rtwvif_link->mac_addr, bss_conf->addr);
+
+       rcu_read_unlock();
+
        rtw89_fw_h2c_cam(rtwdev, rtwvif_link, NULL, NULL);
 
        rtw89_chip_rfk_scan(rtwdev, rtwvif_link, false);
@@ -4700,6 +4743,27 @@ int rtw89_chip_info_setup(struct rtw89_dev *rtwdev)
 }
 EXPORT_SYMBOL(rtw89_chip_info_setup);
 
+void rtw89_chip_cfg_txpwr_ul_tb_offset(struct rtw89_dev *rtwdev,
+                                      struct ieee80211_vif *vif)
+{
+       struct rtw89_vif_link *rtwvif_link = (struct rtw89_vif_link *)vif->drv_priv;
+       const struct rtw89_chip_info *chip = rtwdev->chip;
+       struct ieee80211_bss_conf *bss_conf;
+
+       rcu_read_lock();
+
+       bss_conf = rtw89_vif_rcu_dereference_link(rtwvif_link, false);
+       if (!bss_conf->he_support || !vif->cfg.assoc) {
+               rcu_read_unlock();
+               return;
+       }
+
+       rcu_read_unlock();
+
+       if (chip->ops->set_txpwr_ul_tb_offset)
+               chip->ops->set_txpwr_ul_tb_offset(rtwdev, 0, rtwvif_link->mac_idx);
+}
+
 static int rtw89_core_register_hw(struct rtw89_dev *rtwdev)
 {
        const struct rtw89_chip_info *chip = rtwdev->chip;
index aa0627ce4cd170b9d2e0d56e7b129661a6320a95..3de9fae1095924a83357cfa1d93adb7595309a28 100644 (file)
@@ -3461,6 +3461,8 @@ struct rtw89_p2p_noa_setter {
 };
 
 struct rtw89_vif_link {
+       unsigned int link_id;
+
        struct list_head list;
        struct rtw89_dev *rtwdev;
        struct rtw89_roc roc;
@@ -5995,6 +5997,36 @@ static inline struct rtw89_sta_link *sta_to_rtwsta_safe(struct ieee80211_sta *st
        return sta ? (struct rtw89_sta_link *)sta->drv_priv : NULL;
 }
 
+static inline struct ieee80211_bss_conf *
+__rtw89_vif_rcu_dereference_link(struct rtw89_vif_link *rtwvif_link, bool *nolink)
+{
+       struct ieee80211_vif *vif = rtwvif_to_vif(rtwvif_link);
+       struct ieee80211_bss_conf *bss_conf;
+
+       bss_conf = rcu_dereference(vif->link_conf[rtwvif_link->link_id]);
+       if (unlikely(!bss_conf)) {
+               *nolink = true;
+               return &vif->bss_conf;
+       }
+
+       *nolink = false;
+       return bss_conf;
+}
+
+#define rtw89_vif_rcu_dereference_link(rtwvif_link, assert)            \
+({                                                                     \
+       typeof(rtwvif_link) p = rtwvif_link;                            \
+       struct ieee80211_bss_conf *bss_conf;                            \
+       bool nolink;                                                    \
+                                                                       \
+       bss_conf = __rtw89_vif_rcu_dereference_link(p, &nolink);        \
+       if (unlikely(nolink) && (assert))                               \
+               rtw89_err(p->rtwdev,                                    \
+                         "%s: cannot find exact bss_conf for link_id %u\n",\
+                         __func__, p->link_id);                        \
+       bss_conf;                                                       \
+})
+
 static inline u8 rtw89_hw_to_rate_info_bw(enum rtw89_bandwidth hw_bw)
 {
        if (hw_bw == RTW89_CHANNEL_WIDTH_160)
@@ -6348,20 +6380,6 @@ static inline void rtw89_chip_cfg_txrx_path(struct rtw89_dev *rtwdev)
                chip->ops->cfg_txrx_path(rtwdev);
 }
 
-static inline
-void rtw89_chip_cfg_txpwr_ul_tb_offset(struct rtw89_dev *rtwdev,
-                                      struct ieee80211_vif *vif)
-{
-       struct rtw89_vif_link *rtwvif_link = (struct rtw89_vif_link *)vif->drv_priv;
-       const struct rtw89_chip_info *chip = rtwdev->chip;
-
-       if (!vif->bss_conf.he_support || !vif->cfg.assoc)
-               return;
-
-       if (chip->ops->set_txpwr_ul_tb_offset)
-               chip->ops->set_txpwr_ul_tb_offset(rtwdev, 0, rtwvif_link->mac_idx);
-}
-
 static inline void rtw89_chip_digital_pwr_comp(struct rtw89_dev *rtwdev,
                                               enum rtw89_phy_idx phy_idx)
 {
@@ -6654,6 +6672,8 @@ int rtw89_core_release_sta_ba_entry(struct rtw89_dev *rtwdev,
                                    u8 *cam_idx);
 void rtw89_vif_type_mapping(struct ieee80211_vif *vif, bool assoc);
 int rtw89_chip_info_setup(struct rtw89_dev *rtwdev);
+void rtw89_chip_cfg_txpwr_ul_tb_offset(struct rtw89_dev *rtwdev,
+                                      struct ieee80211_vif *vif);
 bool rtw89_ra_report_to_bitrate(struct rtw89_dev *rtwdev, u8 rpt_rate, u16 *bitrate);
 int rtw89_regd_setup(struct rtw89_dev *rtwdev);
 int rtw89_regd_init(struct rtw89_dev *rtwdev,
@@ -6676,7 +6696,9 @@ void rtw89_core_scan_complete(struct rtw89_dev *rtwdev,
                              struct ieee80211_vif *vif, bool hw_scan);
 int rtw89_reg_6ghz_recalc(struct rtw89_dev *rtwdev, struct rtw89_vif_link *rtwvif_link,
                          bool active);
-void rtw89_core_update_p2p_ps(struct rtw89_dev *rtwdev, struct ieee80211_vif *vif);
+void rtw89_core_update_p2p_ps(struct rtw89_dev *rtwdev,
+                             struct rtw89_vif_link *rtwvif_link,
+                             struct ieee80211_bss_conf *bss_conf);
 void rtw89_core_ntfy_btc_event(struct rtw89_dev *rtwdev, enum rtw89_btc_hmsg event);
 
 #endif
index 59325a6995e67be4a52d5df333b7c382ff99f3eb..b2129164a6e10d4ec0179ffde0440f622ea1df6a 100644 (file)
@@ -2209,11 +2209,10 @@ static struct sk_buff *rtw89_eapol_get(struct rtw89_dev *rtwdev,
 {
        static const u8 gtkbody[] = {0xAA, 0xAA, 0x03, 0x00, 0x00, 0x00, 0x88,
                                     0x8E, 0x01, 0x03, 0x00, 0x5F, 0x02, 0x03};
-       struct ieee80211_vif *vif = rtwvif_to_vif(rtwvif_link);
-       struct ieee80211_bss_conf *bss_conf = &vif->bss_conf;
        u8 sec_hdr_len = rtw89_wow_get_sec_hdr_len(rtwdev);
        struct rtw89_wow_param *rtw_wow = &rtwdev->wow;
        struct rtw89_eapol_2_of_2 *eapol_pkt;
+       struct ieee80211_bss_conf *bss_conf;
        struct ieee80211_hdr_3addr *hdr;
        struct sk_buff *skb;
        u8 key_des_ver;
@@ -2235,10 +2234,17 @@ static struct sk_buff *rtw89_eapol_get(struct rtw89_dev *rtwdev,
        hdr->frame_control = cpu_to_le16(IEEE80211_FTYPE_DATA |
                                         IEEE80211_FCTL_TODS |
                                         IEEE80211_FCTL_PROTECTED);
+
+       rcu_read_lock();
+
+       bss_conf = rtw89_vif_rcu_dereference_link(rtwvif_link, true);
+
        ether_addr_copy(hdr->addr1, bss_conf->bssid);
-       ether_addr_copy(hdr->addr2, vif->addr);
+       ether_addr_copy(hdr->addr2, bss_conf->addr);
        ether_addr_copy(hdr->addr3, bss_conf->bssid);
 
+       rcu_read_unlock();
+
        skb_put_zero(skb, sec_hdr_len);
 
        eapol_pkt = skb_put_zero(skb, sizeof(*eapol_pkt));
@@ -2251,9 +2257,8 @@ static struct sk_buff *rtw89_eapol_get(struct rtw89_dev *rtwdev,
 static struct sk_buff *rtw89_sa_query_get(struct rtw89_dev *rtwdev,
                                          struct rtw89_vif_link *rtwvif_link)
 {
-       struct ieee80211_vif *vif = rtwvif_to_vif(rtwvif_link);
-       struct ieee80211_bss_conf *bss_conf = &vif->bss_conf;
        u8 sec_hdr_len = rtw89_wow_get_sec_hdr_len(rtwdev);
+       struct ieee80211_bss_conf *bss_conf;
        struct ieee80211_hdr_3addr *hdr;
        struct rtw89_sa_query *sa_query;
        struct sk_buff *skb;
@@ -2266,10 +2271,17 @@ static struct sk_buff *rtw89_sa_query_get(struct rtw89_dev *rtwdev,
        hdr->frame_control = cpu_to_le16(IEEE80211_FTYPE_MGMT |
                                         IEEE80211_STYPE_ACTION |
                                         IEEE80211_FCTL_PROTECTED);
+
+       rcu_read_lock();
+
+       bss_conf = rtw89_vif_rcu_dereference_link(rtwvif_link, true);
+
        ether_addr_copy(hdr->addr1, bss_conf->bssid);
-       ether_addr_copy(hdr->addr2, vif->addr);
+       ether_addr_copy(hdr->addr2, bss_conf->addr);
        ether_addr_copy(hdr->addr3, bss_conf->bssid);
 
+       rcu_read_unlock();
+
        skb_put_zero(skb, sec_hdr_len);
 
        sa_query = skb_put_zero(skb, sizeof(*sa_query));
@@ -2555,13 +2567,14 @@ fail:
 }
 
 #define H2C_P2P_ACT_LEN 20
-int rtw89_fw_h2c_p2p_act(struct rtw89_dev *rtwdev, struct ieee80211_vif *vif,
+int rtw89_fw_h2c_p2p_act(struct rtw89_dev *rtwdev,
+                        struct rtw89_vif_link *rtwvif_link,
+                        struct ieee80211_bss_conf *bss_conf,
                         struct ieee80211_p2p_noa_desc *desc,
                         u8 act, u8 noa_id)
 {
-       struct rtw89_vif_link *rtwvif_link = (struct rtw89_vif_link *)vif->drv_priv;
        bool p2p_type_gc = rtwvif_link->wifi_role == RTW89_WIFI_ROLE_P2P_CLIENT;
-       u8 ctwindow_oppps = vif->bss_conf.p2p_noa_attr.oppps_ctwindow;
+       u8 ctwindow_oppps = bss_conf->p2p_noa_attr.oppps_ctwindow;
        struct sk_buff *skb;
        u8 *cmd;
        int ret;
@@ -2963,6 +2976,7 @@ int rtw89_fw_h2c_assoc_cmac_tbl_g7(struct rtw89_dev *rtwdev,
        const struct rtw89_chan *chan = rtw89_chan_get(rtwdev, rtwvif_link->chanctx_idx);
        u8 mac_id = rtwsta_link ? rtwsta_link->mac_id : rtwvif_link->mac_id;
        struct rtw89_h2c_cctlinfo_ud_g7 *h2c;
+       struct ieee80211_bss_conf *bss_conf;
        u8 pads[RTW89_PPE_BW_NUM];
        u32 len = sizeof(*h2c);
        struct sk_buff *skb;
@@ -2977,6 +2991,16 @@ int rtw89_fw_h2c_assoc_cmac_tbl_g7(struct rtw89_dev *rtwdev,
                        __get_sta_he_pkt_padding(rtwdev, sta, pads);
        }
 
+       skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, len);
+       if (!skb) {
+               rtw89_err(rtwdev, "failed to alloc skb for cmac g7\n");
+               return -ENOMEM;
+       }
+
+       rcu_read_lock();
+
+       bss_conf = rtw89_vif_rcu_dereference_link(rtwvif_link, true);
+
        if (vif->p2p)
                lowest_rate = RTW89_HW_RATE_OFDM6;
        else if (chan->band_type == RTW89_BAND_2G)
@@ -2984,11 +3008,6 @@ int rtw89_fw_h2c_assoc_cmac_tbl_g7(struct rtw89_dev *rtwdev,
        else
                lowest_rate = RTW89_HW_RATE_OFDM6;
 
-       skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, len);
-       if (!skb) {
-               rtw89_err(rtwdev, "failed to alloc skb for cmac g7\n");
-               return -ENOMEM;
-       }
        skb_put(skb, len);
        h2c = (struct rtw89_h2c_cctlinfo_ud_g7 *)skb->data;
 
@@ -3017,8 +3036,8 @@ int rtw89_fw_h2c_assoc_cmac_tbl_g7(struct rtw89_dev *rtwdev,
                h2c->m4 |= cpu_to_le32(CCTLINFO_G7_W4_DATA_DCM);
        }
 
-       if (vif->bss_conf.eht_support) {
-               u16 punct = vif->bss_conf.chanreq.oper.punctured;
+       if (bss_conf->eht_support) {
+               u16 punct = bss_conf->chanreq.oper.punctured;
 
                h2c->w4 |= le32_encode_bits(~punct,
                                            CCTLINFO_G7_W4_ACT_SUBCH_CBW);
@@ -3051,6 +3070,8 @@ int rtw89_fw_h2c_assoc_cmac_tbl_g7(struct rtw89_dev *rtwdev,
                h2c->m8 = cpu_to_le32(CCTLINFO_G7_W8_BSR_QUEUE_SIZE_FORMAT);
        }
 
+       rcu_read_unlock();
+
        rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C,
                              H2C_CAT_MAC, H2C_CL_MAC_FR_EXCHG,
                              H2C_FUNC_MAC_CCTLINFO_UD_G7, 0, 1,
@@ -3434,7 +3455,8 @@ rtw89_fw_get_sta_type(struct rtw89_dev *rtwdev, struct rtw89_vif_link *rtwvif_li
                      struct rtw89_sta_link *rtwsta_link)
 {
        struct ieee80211_sta *sta = rtwsta_to_sta_safe(rtwsta_link);
-       struct ieee80211_vif *vif = rtwvif_to_vif(rtwvif_link);
+       struct ieee80211_bss_conf *bss_conf;
+       enum rtw89_fw_sta_type type;
 
        if (!sta)
                goto by_vif;
@@ -3447,12 +3469,20 @@ rtw89_fw_get_sta_type(struct rtw89_dev *rtwdev, struct rtw89_vif_link *rtwvif_li
                return RTW89_FW_N_AC_STA;
 
 by_vif:
-       if (vif->bss_conf.eht_support)
-               return RTW89_FW_BE_STA;
-       else if (vif->bss_conf.he_support)
-               return RTW89_FW_AX_STA;
+       rcu_read_lock();
+
+       bss_conf = rtw89_vif_rcu_dereference_link(rtwvif_link, true);
+
+       if (bss_conf->eht_support)
+               type = RTW89_FW_BE_STA;
+       else if (bss_conf->he_support)
+               type = RTW89_FW_AX_STA;
        else
-               return RTW89_FW_N_AC_STA;
+               type = RTW89_FW_N_AC_STA;
+
+       rcu_read_unlock();
+
+       return type;
 }
 
 int rtw89_fw_h2c_join_info(struct rtw89_dev *rtwdev, struct rtw89_vif_link *rtwvif_link,
@@ -3742,7 +3772,7 @@ int rtw89_fw_h2c_set_bcn_fltr_cfg(struct rtw89_dev *rtwdev,
                                  bool connect)
 {
        struct rtw89_vif_link *rtwvif_link = vif_to_rtwvif_safe(vif);
-       struct ieee80211_bss_conf *bss_conf = vif ? &vif->bss_conf : NULL;
+       struct ieee80211_bss_conf *bss_conf;
        s32 thold = RTW89_DEFAULT_CQM_THOLD;
        u32 hyst = RTW89_DEFAULT_CQM_HYST;
        struct rtw89_h2c_bcnfltr *h2c;
@@ -3753,9 +3783,20 @@ int rtw89_fw_h2c_set_bcn_fltr_cfg(struct rtw89_dev *rtwdev,
        if (!RTW89_CHK_FW_FEATURE(BEACON_FILTER, &rtwdev->fw))
                return -EINVAL;
 
-       if (!rtwvif_link || !bss_conf || rtwvif_link->net_type != RTW89_NET_TYPE_INFRA)
+       if (!rtwvif_link || rtwvif_link->net_type != RTW89_NET_TYPE_INFRA)
                return -EINVAL;
 
+       rcu_read_lock();
+
+       bss_conf = rtw89_vif_rcu_dereference_link(rtwvif_link, false);
+
+       if (bss_conf->cqm_rssi_hyst)
+               hyst = bss_conf->cqm_rssi_hyst;
+       if (bss_conf->cqm_rssi_thold)
+               thold = bss_conf->cqm_rssi_thold;
+
+       rcu_read_unlock();
+
        skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, len);
        if (!skb) {
                rtw89_err(rtwdev, "failed to alloc skb for h2c bcn filter\n");
@@ -3765,11 +3806,6 @@ int rtw89_fw_h2c_set_bcn_fltr_cfg(struct rtw89_dev *rtwdev,
        skb_put(skb, len);
        h2c = (struct rtw89_h2c_bcnfltr *)skb->data;
 
-       if (bss_conf->cqm_rssi_hyst)
-               hyst = bss_conf->cqm_rssi_hyst;
-       if (bss_conf->cqm_rssi_thold)
-               thold = bss_conf->cqm_rssi_thold;
-
        h2c->w0 = le32_encode_bits(connect, RTW89_H2C_BCNFLTR_W0_MON_RSSI) |
                  le32_encode_bits(connect, RTW89_H2C_BCNFLTR_W0_MON_BCN) |
                  le32_encode_bits(connect, RTW89_H2C_BCNFLTR_W0_MON_EN) |
@@ -6565,7 +6601,7 @@ void rtw89_hw_scan_start(struct rtw89_dev *rtwdev, struct ieee80211_vif *vif,
                get_random_mask_addr(mac_addr, req->mac_addr,
                                     req->mac_addr_mask);
        else
-               ether_addr_copy(mac_addr, vif->addr);
+               ether_addr_copy(mac_addr, rtwvif_link->mac_addr);
        rtw89_core_scan_start(rtwdev, rtwvif_link, mac_addr, true);
 
        rx_fltr &= ~B_AX_A_BCN_CHK_EN;
index 7cce4e71a36a3e7dea403af4a2f128d950eeadaf..896993d24c5b732eb64fe49d6b858134c1da36e4 100644 (file)
@@ -4608,7 +4608,9 @@ int rtw89_pno_scan_add_chan_list_be(struct rtw89_dev *rtwdev,
 int rtw89_fw_h2c_trigger_cpu_exception(struct rtw89_dev *rtwdev);
 int rtw89_fw_h2c_pkt_drop(struct rtw89_dev *rtwdev,
                          const struct rtw89_pkt_drop_params *params);
-int rtw89_fw_h2c_p2p_act(struct rtw89_dev *rtwdev, struct ieee80211_vif *vif,
+int rtw89_fw_h2c_p2p_act(struct rtw89_dev *rtwdev,
+                        struct rtw89_vif_link *rtwvif_link,
+                        struct ieee80211_bss_conf *bss_conf,
                         struct ieee80211_p2p_noa_desc *desc,
                         u8 act, u8 noa_id);
 int rtw89_fw_h2c_tsf32_toggle(struct rtw89_dev *rtwdev,
index d6cd3ed1e7fc818826afb29182d81a86574cdc7b..d5097d3a3385fb64e5454b9b62b8f8ef67269ebf 100644 (file)
@@ -4141,10 +4141,11 @@ static void rtw89_mac_port_cfg_func_sw(struct rtw89_dev *rtwdev,
 {
        const struct rtw89_mac_gen_def *mac = rtwdev->chip->mac_def;
        const struct rtw89_port_reg *p = mac->port_base;
-       struct ieee80211_vif *vif = rtwvif_to_vif(rtwvif_link);
        const struct rtw89_chip_info *chip = rtwdev->chip;
+       struct ieee80211_bss_conf *bss_conf;
        bool need_backup = false;
        u32 backup_val;
+       u16 beacon_int;
 
        if (!rtw89_read32_port_mask(rtwdev, rtwvif_link, p->port_cfg, B_AX_PORT_FUNC_EN))
                return;
@@ -4168,7 +4169,14 @@ static void rtw89_mac_port_cfg_func_sw(struct rtw89_dev *rtwdev,
                                       B_AX_BCNERLY_MASK);
        }
 
-       msleep(vif->bss_conf.beacon_int + 1);
+       rcu_read_lock();
+
+       bss_conf = rtw89_vif_rcu_dereference_link(rtwvif_link, true);
+       beacon_int = bss_conf->beacon_int;
+
+       rcu_read_unlock();
+
+       msleep(beacon_int + 1);
        rtw89_write32_port_clr(rtwdev, rtwvif_link, p->port_cfg, B_AX_PORT_FUNC_EN |
                                                            B_AX_BRK_SETUP);
        rtw89_write32_port_set(rtwdev, rtwvif_link, p->port_cfg, B_AX_TSFTR_RST);
@@ -4301,8 +4309,18 @@ static void rtw89_mac_port_cfg_bcn_intv(struct rtw89_dev *rtwdev,
 {
        const struct rtw89_mac_gen_def *mac = rtwdev->chip->mac_def;
        const struct rtw89_port_reg *p = mac->port_base;
-       struct ieee80211_vif *vif = rtwvif_to_vif(rtwvif_link);
-       u16 bcn_int = vif->bss_conf.beacon_int ? vif->bss_conf.beacon_int : BCN_INTERVAL;
+       struct ieee80211_bss_conf *bss_conf;
+       u16 bcn_int;
+
+       rcu_read_lock();
+
+       bss_conf = rtw89_vif_rcu_dereference_link(rtwvif_link, true);
+       if (bss_conf->beacon_int)
+               bcn_int = bss_conf->beacon_int;
+       else
+               bcn_int = BCN_INTERVAL;
+
+       rcu_read_unlock();
 
        rtw89_write32_port_mask(rtwdev, rtwvif_link, p->bcn_space, B_AX_BCN_SPACE_MASK,
                                bcn_int);
@@ -4326,14 +4344,22 @@ static void rtw89_mac_port_cfg_hiq_dtim(struct rtw89_dev *rtwdev,
 {
        const struct rtw89_mac_gen_def *mac = rtwdev->chip->mac_def;
        const struct rtw89_port_reg *p = mac->port_base;
-       struct ieee80211_vif *vif = rtwvif_to_vif(rtwvif_link);
+       struct ieee80211_bss_conf *bss_conf;
+       u8 dtim_period;
        u32 addr;
 
+       rcu_read_lock();
+
+       bss_conf = rtw89_vif_rcu_dereference_link(rtwvif_link, true);
+       dtim_period = bss_conf->dtim_period;
+
+       rcu_read_unlock();
+
        addr = rtw89_mac_reg_by_idx(rtwdev, p->md_tsft, rtwvif_link->mac_idx);
        rtw89_write8_set(rtwdev, addr, B_AX_UPD_HGQMD | B_AX_UPD_TIMIE);
 
        rtw89_write16_port_mask(rtwdev, rtwvif_link, p->dtim_ctrl, B_AX_DTIM_NUM_MASK,
-                               vif->bss_conf.dtim_period);
+                               dtim_period);
 }
 
 static void rtw89_mac_port_cfg_bcn_setup_time(struct rtw89_dev *rtwdev,
@@ -4381,18 +4407,24 @@ static void rtw89_mac_port_cfg_bss_color(struct rtw89_dev *rtwdev,
 {
        const struct rtw89_mac_gen_def *mac = rtwdev->chip->mac_def;
        const struct rtw89_port_reg *p = mac->port_base;
-       struct ieee80211_vif *vif = rtwvif_to_vif(rtwvif_link);
        static const u32 masks[RTW89_PORT_NUM] = {
                B_AX_BSS_COLOB_AX_PORT_0_MASK, B_AX_BSS_COLOB_AX_PORT_1_MASK,
                B_AX_BSS_COLOB_AX_PORT_2_MASK, B_AX_BSS_COLOB_AX_PORT_3_MASK,
                B_AX_BSS_COLOB_AX_PORT_4_MASK,
        };
+       struct ieee80211_bss_conf *bss_conf;
        u8 port = rtwvif_link->port;
        u32 reg_base;
        u32 reg;
        u8 bss_color;
 
-       bss_color = vif->bss_conf.he_bss_color.color;
+       rcu_read_lock();
+
+       bss_conf = rtw89_vif_rcu_dereference_link(rtwvif_link, true);
+       bss_color = bss_conf->he_bss_color.color;
+
+       rcu_read_unlock();
+
        reg_base = port >= 4 ? p->bss_color + 4 : p->bss_color;
        reg = rtw89_mac_reg_by_idx(rtwdev, reg_base, rtwvif_link->mac_idx);
        rtw89_write32_mask(rtwdev, reg, masks[port], bss_color);
@@ -4670,16 +4702,28 @@ void rtw89_mac_set_he_obss_narrow_bw_ru(struct rtw89_dev *rtwdev,
        struct rtw89_vif_link *rtwvif_link = (struct rtw89_vif_link *)vif->drv_priv;
        const struct rtw89_mac_gen_def *mac = rtwdev->chip->mac_def;
        struct ieee80211_hw *hw = rtwdev->hw;
+       struct ieee80211_bss_conf *bss_conf;
+       struct cfg80211_chan_def oper;
        bool tolerated = true;
        u32 reg;
 
-       if (!vif->bss_conf.he_support || vif->type != NL80211_IFTYPE_STATION)
+       rcu_read_lock();
+
+       bss_conf = rtw89_vif_rcu_dereference_link(rtwvif_link, true);
+       if (!bss_conf->he_support || vif->type != NL80211_IFTYPE_STATION) {
+               rcu_read_unlock();
                return;
+       }
 
-       if (!(vif->bss_conf.chanreq.oper.chan->flags & IEEE80211_CHAN_RADAR))
+       oper = bss_conf->chanreq.oper;
+       if (!(oper.chan->flags & IEEE80211_CHAN_RADAR)) {
+               rcu_read_unlock();
                return;
+       }
+
+       rcu_read_unlock();
 
-       cfg80211_bss_iter(hw->wiphy, &vif->bss_conf.chanreq.oper,
+       cfg80211_bss_iter(hw->wiphy, &oper,
                          rtw89_mac_check_he_obss_narrow_bw_ru_iter,
                          &tolerated);
 
index 392a38fcf4618b91bf2e6357a0ff60edcd7acbc1..f04032a8a8ec4cc99e225c61c5a9f8702997c3a1 100644 (file)
@@ -111,6 +111,7 @@ static int rtw89_ops_add_interface(struct ieee80211_hw *hw,
 {
        struct rtw89_dev *rtwdev = hw->priv;
        struct rtw89_vif_link *rtwvif_link = (struct rtw89_vif_link *)vif->drv_priv;
+       struct ieee80211_bss_conf *bss_conf;
        int ret = 0;
 
        rtw89_debug(rtwdev, RTW89_DBG_STATE, "add vif %pM type %d, p2p %d\n",
@@ -151,7 +152,14 @@ static int rtw89_ops_add_interface(struct ieee80211_hw *hw,
        rtwvif_link->chanctx_assigned = false;
        rtwvif_link->hit_rule = 0;
        rtwvif_link->reg_6ghz_power = RTW89_REG_6GHZ_POWER_DFLT;
-       ether_addr_copy(rtwvif_link->mac_addr, vif->addr);
+
+       rcu_read_lock();
+
+       bss_conf = rtw89_vif_rcu_dereference_link(rtwvif_link, true);
+       ether_addr_copy(rtwvif_link->mac_addr, bss_conf->addr);
+
+       rcu_read_unlock();
+
        INIT_LIST_HEAD(&rtwvif_link->general_pkt_list);
 
        ret = rtw89_mac_add_vif(rtwdev, rtwvif_link);
@@ -314,13 +322,19 @@ static const u8 ac_to_fw_idx[IEEE80211_NUM_ACS] = {
 static u8 rtw89_aifsn_to_aifs(struct rtw89_dev *rtwdev,
                              struct rtw89_vif_link *rtwvif_link, u8 aifsn)
 {
-       struct ieee80211_vif *vif = rtwvif_to_vif(rtwvif_link);
        const struct rtw89_chan *chan = rtw89_chan_get(rtwdev,
                                                       rtwvif_link->chanctx_idx);
+       struct ieee80211_bss_conf *bss_conf;
        u8 slot_time;
        u8 sifs;
 
-       slot_time = vif->bss_conf.use_short_slot ? 9 : 20;
+       rcu_read_lock();
+
+       bss_conf = rtw89_vif_rcu_dereference_link(rtwvif_link, true);
+       slot_time = bss_conf->use_short_slot ? 9 : 20;
+
+       rcu_read_unlock();
+
        sifs = chan->band_type == RTW89_BAND_2G ? 10 : 16;
 
        return aifsn * slot_time + sifs;
@@ -486,7 +500,7 @@ static void rtw89_ops_link_info_changed(struct ieee80211_hw *hw,
                rtw89_mac_bf_set_gid_table(rtwdev, vif, conf);
 
        if (changed & BSS_CHANGED_P2P_PS)
-               rtw89_core_update_p2p_ps(rtwdev, vif);
+               rtw89_core_update_p2p_ps(rtwdev, rtwvif_link, conf);
 
        if (changed & BSS_CHANGED_CQM)
                rtw89_fw_h2c_set_bcn_fltr_cfg(rtwdev, vif, true);
@@ -516,7 +530,7 @@ static int rtw89_ops_start_ap(struct ieee80211_hw *hw,
        if (rtwdev->scanning)
                rtw89_hw_scan_abort(rtwdev, rtwdev->scan_info.scanning_vif);
 
-       ether_addr_copy(rtwvif_link->bssid, vif->bss_conf.bssid);
+       ether_addr_copy(rtwvif_link->bssid, link_conf->bssid);
        rtw89_cam_bssid_changed(rtwdev, rtwvif_link);
        rtw89_mac_port_update(rtwdev, rtwvif_link);
        rtw89_chip_h2c_assoc_cmac_tbl(rtwdev, vif, NULL);
index f056fdc6262b818bbb77db0e2e8989080ed4f0c2..2fec179aba1b865e9a06045b07d0b04c6ae33f80 100644 (file)
@@ -6145,15 +6145,24 @@ void rtw89_phy_dm_init(struct rtw89_dev *rtwdev)
 
 void rtw89_phy_set_bss_color(struct rtw89_dev *rtwdev, struct ieee80211_vif *vif)
 {
+       struct rtw89_vif_link *rtwvif_link = (struct rtw89_vif_link *)vif->drv_priv;
        const struct rtw89_chip_info *chip = rtwdev->chip;
        const struct rtw89_reg_def *bss_clr_vld = &chip->bss_clr_vld;
        enum rtw89_phy_idx phy_idx = RTW89_PHY_0;
+       struct ieee80211_bss_conf *bss_conf;
        u8 bss_color;
 
-       if (!vif->bss_conf.he_support || !vif->cfg.assoc)
+       rcu_read_lock();
+
+       bss_conf = rtw89_vif_rcu_dereference_link(rtwvif_link, true);
+       if (!bss_conf->he_support || !vif->cfg.assoc) {
+               rcu_read_unlock();
                return;
+       }
+
+       bss_color = bss_conf->he_bss_color.color;
 
-       bss_color = vif->bss_conf.he_bss_color.color;
+       rcu_read_unlock();
 
        rtw89_phy_write32_idx(rtwdev, bss_clr_vld->addr, bss_clr_vld->mask, 0x1,
                              phy_idx);
index 42a73bba7f5c1687677c35a69935cdb3e08ef5f9..ded0b73bd6783757439c70b682fae92ccfb5d3bf 100644 (file)
@@ -214,9 +214,9 @@ static void rtw89_tsf32_toggle(struct rtw89_dev *rtwdev,
 }
 
 static void rtw89_p2p_disable_all_noa(struct rtw89_dev *rtwdev,
-                                     struct ieee80211_vif *vif)
+                                     struct rtw89_vif_link *rtwvif_link,
+                                     struct ieee80211_bss_conf *bss_conf)
 {
-       struct rtw89_vif_link *rtwvif_link = (struct rtw89_vif_link *)vif->drv_priv;
        enum rtw89_p2pps_action act;
        u8 noa_id;
 
@@ -229,20 +229,21 @@ static void rtw89_p2p_disable_all_noa(struct rtw89_dev *rtwdev,
                else
                        act = RTW89_P2P_ACT_REMOVE;
                rtw89_tsf32_toggle(rtwdev, rtwvif_link, act);
-               rtw89_fw_h2c_p2p_act(rtwdev, vif, NULL, act, noa_id);
+               rtw89_fw_h2c_p2p_act(rtwdev, rtwvif_link, bss_conf,
+                                    NULL, act, noa_id);
        }
 }
 
 static void rtw89_p2p_update_noa(struct rtw89_dev *rtwdev,
-                                struct ieee80211_vif *vif)
+                                struct rtw89_vif_link *rtwvif_link,
+                                struct ieee80211_bss_conf *bss_conf)
 {
-       struct rtw89_vif_link *rtwvif_link = (struct rtw89_vif_link *)vif->drv_priv;
        struct ieee80211_p2p_noa_desc *desc;
        enum rtw89_p2pps_action act;
        u8 noa_id;
 
        for (noa_id = 0; noa_id < RTW89_P2P_MAX_NOA_NUM; noa_id++) {
-               desc = &vif->bss_conf.p2p_noa_attr.desc[noa_id];
+               desc = &bss_conf->p2p_noa_attr.desc[noa_id];
                if (!desc->count || !desc->duration)
                        break;
 
@@ -251,15 +252,18 @@ static void rtw89_p2p_update_noa(struct rtw89_dev *rtwdev,
                else
                        act = RTW89_P2P_ACT_UPDATE;
                rtw89_tsf32_toggle(rtwdev, rtwvif_link, act);
-               rtw89_fw_h2c_p2p_act(rtwdev, vif, desc, act, noa_id);
+               rtw89_fw_h2c_p2p_act(rtwdev, rtwvif_link, bss_conf,
+                                    desc, act, noa_id);
        }
        rtwvif_link->last_noa_nr = noa_id;
 }
 
-void rtw89_process_p2p_ps(struct rtw89_dev *rtwdev, struct ieee80211_vif *vif)
+void rtw89_process_p2p_ps(struct rtw89_dev *rtwdev,
+                         struct rtw89_vif_link *rtwvif_link,
+                         struct ieee80211_bss_conf *bss_conf)
 {
-       rtw89_p2p_disable_all_noa(rtwdev, vif);
-       rtw89_p2p_update_noa(rtwdev, vif);
+       rtw89_p2p_disable_all_noa(rtwdev, rtwvif_link, bss_conf);
+       rtw89_p2p_update_noa(rtwdev, rtwvif_link, bss_conf);
 }
 
 void rtw89_recalc_lps(struct rtw89_dev *rtwdev)
index d0be56ee16a29f916dc5dfaaaf8a709bef817fd6..cdd712966b09d9b32f2e0de20c7c1846645655a9 100644 (file)
@@ -14,7 +14,9 @@ void rtw89_leave_ps_mode(struct rtw89_dev *rtwdev);
 void rtw89_enter_ips(struct rtw89_dev *rtwdev);
 void rtw89_leave_ips(struct rtw89_dev *rtwdev);
 void rtw89_set_coex_ctrl_lps(struct rtw89_dev *rtwdev, bool btc_ctrl);
-void rtw89_process_p2p_ps(struct rtw89_dev *rtwdev, struct ieee80211_vif *vif);
+void rtw89_process_p2p_ps(struct rtw89_dev *rtwdev,
+                         struct rtw89_vif_link *rtwvif_link,
+                         struct ieee80211_bss_conf *bss_conf);
 void rtw89_recalc_lps(struct rtw89_dev *rtwdev);
 void rtw89_p2p_noa_renew(struct rtw89_vif_link *rtwvif_link);
 void rtw89_p2p_noa_append(struct rtw89_vif_link *rtwvif_link,
index 0fd8e132fdf07aa0a4be4a07928fbc35053310b3..aa5ae02443727bfb131fd66c3a607d1f255258e7 100644 (file)
@@ -834,16 +834,21 @@ static int rtw89_reg_6ghz_tpe_recalc(struct rtw89_dev *rtwdev,
                                     struct rtw89_vif_link *rtwvif_link, bool active,
                                     unsigned int *changed)
 {
-       struct ieee80211_vif *vif = rtwvif_to_vif(rtwvif_link);
-       struct ieee80211_bss_conf *bss_conf = &vif->bss_conf;
        struct rtw89_reg_6ghz_tpe *tpe = &rtwvif_link->reg_6ghz_tpe;
+       struct ieee80211_bss_conf *bss_conf;
 
        memset(tpe, 0, sizeof(*tpe));
 
        if (!active || rtwvif_link->reg_6ghz_power != RTW89_REG_6GHZ_POWER_STD)
                goto bottom;
 
+       rcu_read_lock();
+
+       bss_conf = rtw89_vif_rcu_dereference_link(rtwvif_link, true);
        rtw89_calculate_tpe(rtwdev, tpe, &bss_conf->tpe);
+
+       rcu_read_unlock();
+
        if (!tpe->valid)
                goto bottom;
 
@@ -911,10 +916,14 @@ static int rtw89_reg_6ghz_power_recalc(struct rtw89_dev *rtwdev,
                                       struct rtw89_vif_link *rtwvif_link, bool active,
                                       unsigned int *changed)
 {
-       struct ieee80211_vif *vif = rtwvif_to_vif(rtwvif_link);
+       struct ieee80211_bss_conf *bss_conf;
+
+       rcu_read_lock();
+
+       bss_conf = rtw89_vif_rcu_dereference_link(rtwvif_link, true);
 
        if (active) {
-               switch (vif->bss_conf.power_type) {
+               switch (bss_conf->power_type) {
                case IEEE80211_REG_VLP_AP:
                        rtwvif_link->reg_6ghz_power = RTW89_REG_6GHZ_POWER_VLP;
                        break;
@@ -932,6 +941,8 @@ static int rtw89_reg_6ghz_power_recalc(struct rtw89_dev *rtwdev,
                rtwvif_link->reg_6ghz_power = RTW89_REG_6GHZ_POWER_DFLT;
        }
 
+       rcu_read_unlock();
+
        *changed += __rtw89_reg_6ghz_power_recalc(rtwdev);
        return 0;
 }
index 5046fef55222dccc486497b58ffe2d7293d86bb4..17e2d5cbb1e6a771c0981d13394c605200265aba 100644 (file)
@@ -633,10 +633,12 @@ static struct ieee80211_key_conf *rtw89_wow_gtk_rekey(struct rtw89_dev *rtwdev,
 static void rtw89_wow_update_key_info(struct rtw89_dev *rtwdev, bool rx_ready)
 {
        struct ieee80211_vif *wow_vif = rtwdev->wow.wow_vif;
+       struct rtw89_vif_link *rtwvif_link = (struct rtw89_vif_link *)wow_vif->drv_priv;
        struct rtw89_wow_param *rtw_wow = &rtwdev->wow;
        struct rtw89_wow_aoac_report *aoac_rpt = &rtw_wow->aoac_rpt;
        struct rtw89_set_key_info_iter_data data = {.error = false,
                                                    .rx_ready = rx_ready};
+       struct ieee80211_bss_conf *bss_conf;
        struct ieee80211_key_conf *key;
 
        rcu_read_lock();
@@ -669,9 +671,15 @@ static void rtw89_wow_update_key_info(struct rtw89_dev *rtwdev, bool rx_ready)
                return;
 
        rtw89_rx_pn_set_pmf(rtwdev, key, aoac_rpt->igtk_ipn);
-       ieee80211_gtk_rekey_notify(wow_vif, wow_vif->bss_conf.bssid,
+
+       rcu_read_lock();
+
+       bss_conf = rtw89_vif_rcu_dereference_link(rtwvif_link, true);
+       ieee80211_gtk_rekey_notify(wow_vif, bss_conf->bssid,
                                   aoac_rpt->eapol_key_replay_count,
-                                  GFP_KERNEL);
+                                  GFP_ATOMIC);
+
+       rcu_read_unlock();
 }
 
 static void rtw89_wow_leave_deep_ps(struct rtw89_dev *rtwdev)