diff --git a/drivers/net/wireless/realtek/rtw89/core.c b/drivers/net/wireless/realtek/rtw89/core.c index 8d2cce450241..79d3182fce5a 100644 --- a/drivers/net/wireless/realtek/rtw89/core.c +++ b/drivers/net/wireless/realtek/rtw89/core.c @@ -3224,7 +3224,10 @@ static int rtw89_core_register_hw(struct rtw89_dev *rtwdev) ieee80211_hw_set(hw, SUPPORTS_MULTI_BSSID); hw->wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION) | - BIT(NL80211_IFTYPE_AP); + BIT(NL80211_IFTYPE_AP) | + BIT(NL80211_IFTYPE_P2P_CLIENT) | + BIT(NL80211_IFTYPE_P2P_GO); + hw->wiphy->available_antennas_tx = BIT(rtwdev->chip->rf_path_num) - 1; hw->wiphy->available_antennas_rx = BIT(rtwdev->chip->rf_path_num) - 1; diff --git a/drivers/net/wireless/realtek/rtw89/debug.h b/drivers/net/wireless/realtek/rtw89/debug.h index 6176152dbf6b..ee243aadde87 100644 --- a/drivers/net/wireless/realtek/rtw89/debug.h +++ b/drivers/net/wireless/realtek/rtw89/debug.h @@ -25,6 +25,7 @@ enum rtw89_debug_mask { RTW89_DBG_BF = BIT(14), RTW89_DBG_HW_SCAN = BIT(15), RTW89_DBG_SAR = BIT(16), + RTW89_DBG_STATE = BIT(17), RTW89_DBG_UNEXP = BIT(31), }; diff --git a/drivers/net/wireless/realtek/rtw89/mac80211.c b/drivers/net/wireless/realtek/rtw89/mac80211.c index e82be57f291c..f9cd98d49615 100644 --- a/drivers/net/wireless/realtek/rtw89/mac80211.c +++ b/drivers/net/wireless/realtek/rtw89/mac80211.c @@ -109,6 +109,9 @@ static int rtw89_ops_add_interface(struct ieee80211_hw *hw, struct rtw89_vif *rtwvif = (struct rtw89_vif *)vif->drv_priv; int ret = 0; + rtw89_debug(rtwdev, RTW89_DBG_STATE, "add vif %pM type %d, p2p %d\n", + vif->addr, vif->type, vif->p2p); + mutex_lock(&rtwdev->mutex); rtwvif->rtwdev = rtwdev; list_add_tail(&rtwvif->list, &rtwdev->rtwvifs_list); @@ -151,6 +154,9 @@ static void rtw89_ops_remove_interface(struct ieee80211_hw *hw, struct rtw89_dev *rtwdev = hw->priv; struct rtw89_vif *rtwvif = (struct rtw89_vif *)vif->drv_priv; + rtw89_debug(rtwdev, RTW89_DBG_STATE, "remove vif %pM type %d p2p %d\n", + vif->addr, vif->type, vif->p2p); + cancel_work_sync(&rtwvif->update_beacon_work); mutex_lock(&rtwdev->mutex); @@ -162,6 +168,23 @@ static void rtw89_ops_remove_interface(struct ieee80211_hw *hw, mutex_unlock(&rtwdev->mutex); } +static int rtw89_ops_change_interface(struct ieee80211_hw *hw, + struct ieee80211_vif *vif, + enum nl80211_iftype type, bool p2p) +{ + struct rtw89_dev *rtwdev = hw->priv; + + rtw89_debug(rtwdev, RTW89_DBG_STATE, "change vif %pM (%d)->(%d), p2p (%d)->(%d)\n", + vif->addr, vif->type, type, vif->p2p, p2p); + + rtw89_ops_remove_interface(hw, vif); + + vif->type = type; + vif->p2p = p2p; + + return rtw89_ops_add_interface(hw, vif); +} + static void rtw89_ops_configure_filter(struct ieee80211_hw *hw, unsigned int changed_flags, unsigned int *new_flags, @@ -896,6 +919,7 @@ const struct ieee80211_ops rtw89_ops = { .stop = rtw89_ops_stop, .config = rtw89_ops_config, .add_interface = rtw89_ops_add_interface, + .change_interface = rtw89_ops_change_interface, .remove_interface = rtw89_ops_remove_interface, .configure_filter = rtw89_ops_configure_filter, .bss_info_changed = rtw89_ops_bss_info_changed,