wifi: rtw89: add skeleton of mac80211 chanctx ops support
authorZong-Zhe Yang <kevin_yang@realtek.com>
Tue, 9 Aug 2022 10:49:50 +0000 (18:49 +0800)
committerKalle Valo <kvalo@kernel.org>
Fri, 2 Sep 2022 08:29:02 +0000 (11:29 +0300)
Support mac80211 chanctx series ops. Still, currently support
single channel. Based on this premise, things should be similar
to before. So, we haven't dealt with relationship between vif
and chanctx in depth. Instead, we leave both ::assign_vif()
and ::unassign_vif() as noops for now.

Signed-off-by: Zong-Zhe Yang <kevin_yang@realtek.com>
Signed-off-by: Ping-Ke Shih <pkshih@realtek.com>
Signed-off-by: Kalle Valo <kvalo@kernel.org>
Link: https://lore.kernel.org/r/20220809104952.61355-12-pkshih@realtek.com
drivers/net/wireless/realtek/rtw89/chan.c
drivers/net/wireless/realtek/rtw89/chan.h
drivers/net/wireless/realtek/rtw89/core.c
drivers/net/wireless/realtek/rtw89/core.h
drivers/net/wireless/realtek/rtw89/mac80211.c

index 02d31f751d3e7281827d76698b0bc19993613cde..cccbd9c8c59b8230cdf29253d77cbe07e31b5fc7 100644 (file)
@@ -179,3 +179,56 @@ enum rtw89_entity_mode rtw89_entity_recalc(struct rtw89_dev *rtwdev)
        rtw89_set_entity_mode(rtwdev, mode);
        return mode;
 }
+
+int rtw89_chanctx_ops_add(struct rtw89_dev *rtwdev,
+                         struct ieee80211_chanctx_conf *ctx)
+{
+       struct rtw89_hal *hal = &rtwdev->hal;
+       struct rtw89_chanctx_cfg *cfg = (struct rtw89_chanctx_cfg *)ctx->drv_priv;
+       u8 idx;
+
+       idx = find_first_zero_bit(hal->entity_map, NUM_OF_RTW89_SUB_ENTITY);
+       if (idx > RTW89_SUB_ENTITY_0)
+               return -ENOENT;
+
+       rtw89_config_entity_chandef(rtwdev, idx, &ctx->def);
+       rtw89_set_channel(rtwdev);
+       cfg->idx = idx;
+       return 0;
+}
+
+void rtw89_chanctx_ops_remove(struct rtw89_dev *rtwdev,
+                             struct ieee80211_chanctx_conf *ctx)
+{
+       struct rtw89_hal *hal = &rtwdev->hal;
+       struct rtw89_chanctx_cfg *cfg = (struct rtw89_chanctx_cfg *)ctx->drv_priv;
+
+       clear_bit(cfg->idx, hal->entity_map);
+       rtw89_set_channel(rtwdev);
+}
+
+void rtw89_chanctx_ops_change(struct rtw89_dev *rtwdev,
+                             struct ieee80211_chanctx_conf *ctx,
+                             u32 changed)
+{
+       struct rtw89_chanctx_cfg *cfg = (struct rtw89_chanctx_cfg *)ctx->drv_priv;
+       u8 idx = cfg->idx;
+
+       if (changed & IEEE80211_CHANCTX_CHANGE_WIDTH) {
+               rtw89_config_entity_chandef(rtwdev, idx, &ctx->def);
+               rtw89_set_channel(rtwdev);
+       }
+}
+
+int rtw89_chanctx_ops_assign_vif(struct rtw89_dev *rtwdev,
+                                struct rtw89_vif *rtwvif,
+                                struct ieee80211_chanctx_conf *ctx)
+{
+       return 0;
+}
+
+void rtw89_chanctx_ops_unassign_vif(struct rtw89_dev *rtwdev,
+                                   struct rtw89_vif *rtwvif,
+                                   struct ieee80211_chanctx_conf *ctx)
+{
+}
index 6b2b5cc0d798b42e0b2051ceaf1f60526b506f46..ecbd4503bead9bbc8f205749ea2b714f51ed497b 100644 (file)
@@ -47,5 +47,18 @@ void rtw89_config_entity_chandef(struct rtw89_dev *rtwdev,
                                 const struct cfg80211_chan_def *chandef);
 void rtw89_entity_init(struct rtw89_dev *rtwdev);
 enum rtw89_entity_mode rtw89_entity_recalc(struct rtw89_dev *rtwdev);
+int rtw89_chanctx_ops_add(struct rtw89_dev *rtwdev,
+                         struct ieee80211_chanctx_conf *ctx);
+void rtw89_chanctx_ops_remove(struct rtw89_dev *rtwdev,
+                             struct ieee80211_chanctx_conf *ctx);
+void rtw89_chanctx_ops_change(struct rtw89_dev *rtwdev,
+                             struct ieee80211_chanctx_conf *ctx,
+                             u32 changed);
+int rtw89_chanctx_ops_assign_vif(struct rtw89_dev *rtwdev,
+                                struct rtw89_vif *rtwvif,
+                                struct ieee80211_chanctx_conf *ctx);
+void rtw89_chanctx_ops_unassign_vif(struct rtw89_dev *rtwdev,
+                                   struct rtw89_vif *rtwvif,
+                                   struct ieee80211_chanctx_conf *ctx);
 
 #endif
index dea4280039e6aa77a8d200626fa80d6e80c16fe1..885ef1525868a641db0acca4f36a8b98918322e3 100644 (file)
@@ -3114,6 +3114,7 @@ static int rtw89_core_register_hw(struct rtw89_dev *rtwdev)
        hw->vif_data_size = sizeof(struct rtw89_vif);
        hw->sta_data_size = sizeof(struct rtw89_sta);
        hw->txq_data_size = sizeof(struct rtw89_txq);
+       hw->chanctx_data_size = sizeof(struct rtw89_chanctx_cfg);
 
        SET_IEEE80211_PERM_ADDR(hw, efuse->addr);
 
index 96af628d8d46e60333670cfb00ba2aed9c0604f3..26f1fc9561e04991c0c3a9e15d31ae1630a7343b 100644 (file)
@@ -2623,6 +2623,10 @@ struct rtw89_sar_info {
        };
 };
 
+struct rtw89_chanctx_cfg {
+       enum rtw89_sub_entity_idx idx;
+};
+
 enum rtw89_entity_mode {
        RTW89_ENTITY_MODE_SCC,
 };
index 5da50b2c4abfc588fa61e2e3cff98d83f660b90f..668370cf8158a4d8ae3b4fb6238795b0bb9950b9 100644 (file)
@@ -777,6 +777,69 @@ static void rtw89_ops_sta_rc_update(struct ieee80211_hw *hw,
        rtw89_phy_ra_updata_sta(rtwdev, sta, changed);
 }
 
+static int rtw89_ops_add_chanctx(struct ieee80211_hw *hw,
+                                struct ieee80211_chanctx_conf *ctx)
+{
+       struct rtw89_dev *rtwdev = hw->priv;
+       int ret;
+
+       mutex_lock(&rtwdev->mutex);
+       ret = rtw89_chanctx_ops_add(rtwdev, ctx);
+       mutex_unlock(&rtwdev->mutex);
+
+       return ret;
+}
+
+static void rtw89_ops_remove_chanctx(struct ieee80211_hw *hw,
+                                    struct ieee80211_chanctx_conf *ctx)
+{
+       struct rtw89_dev *rtwdev = hw->priv;
+
+       mutex_lock(&rtwdev->mutex);
+       rtw89_chanctx_ops_remove(rtwdev, ctx);
+       mutex_unlock(&rtwdev->mutex);
+}
+
+static void rtw89_ops_change_chanctx(struct ieee80211_hw *hw,
+                                    struct ieee80211_chanctx_conf *ctx,
+                                    u32 changed)
+{
+       struct rtw89_dev *rtwdev = hw->priv;
+
+       mutex_lock(&rtwdev->mutex);
+       rtw89_chanctx_ops_change(rtwdev, ctx, changed);
+       mutex_unlock(&rtwdev->mutex);
+}
+
+static int rtw89_ops_assign_vif_chanctx(struct ieee80211_hw *hw,
+                                       struct ieee80211_vif *vif,
+                                       struct ieee80211_bss_conf *link_conf,
+                                       struct ieee80211_chanctx_conf *ctx)
+{
+       struct rtw89_dev *rtwdev = hw->priv;
+       struct rtw89_vif *rtwvif = (struct rtw89_vif *)vif->drv_priv;
+       int ret;
+
+       mutex_lock(&rtwdev->mutex);
+       ret = rtw89_chanctx_ops_assign_vif(rtwdev, rtwvif, ctx);
+       mutex_unlock(&rtwdev->mutex);
+
+       return ret;
+}
+
+static void rtw89_ops_unassign_vif_chanctx(struct ieee80211_hw *hw,
+                                          struct ieee80211_vif *vif,
+                                          struct ieee80211_bss_conf *link_conf,
+                                          struct ieee80211_chanctx_conf *ctx)
+{
+       struct rtw89_dev *rtwdev = hw->priv;
+       struct rtw89_vif *rtwvif = (struct rtw89_vif *)vif->drv_priv;
+
+       mutex_lock(&rtwdev->mutex);
+       rtw89_chanctx_ops_unassign_vif(rtwdev, rtwvif, ctx);
+       mutex_unlock(&rtwdev->mutex);
+}
+
 const struct ieee80211_ops rtw89_ops = {
        .tx                     = rtw89_ops_tx,
        .wake_tx_queue          = rtw89_ops_wake_tx_queue,
@@ -805,6 +868,11 @@ const struct ieee80211_ops rtw89_ops = {
        .reconfig_complete      = rtw89_ops_reconfig_complete,
        .hw_scan                = rtw89_ops_hw_scan,
        .cancel_hw_scan         = rtw89_ops_cancel_hw_scan,
+       .add_chanctx            = rtw89_ops_add_chanctx,
+       .remove_chanctx         = rtw89_ops_remove_chanctx,
+       .change_chanctx         = rtw89_ops_change_chanctx,
+       .assign_vif_chanctx     = rtw89_ops_assign_vif_chanctx,
+       .unassign_vif_chanctx   = rtw89_ops_unassign_vif_chanctx,
        .set_sar_specs          = rtw89_ops_set_sar_specs,
        .sta_rc_update          = rtw89_ops_sta_rc_update,
 };