diff --git a/src/drivers/driver.h b/src/drivers/driver.h index 3c7ebe863..329f89a25 100644 --- a/src/drivers/driver.h +++ b/src/drivers/driver.h @@ -2018,6 +2018,16 @@ struct wpa_driver_ops { */ int (*deinit_ap)(void *priv); + /** + * deinit_p2p_cli - Deinitialize P2P client mode + * @priv: Private driver interface data + * Returns: 0 on success, -1 on failure (or if not supported) + * + * This optional function can be used to disable P2P client mode. It + * can be used to change the interface type back to station mode. + */ + int (*deinit_p2p_cli)(void *priv); + /** * suspend - Notification on system suspend/hibernate event * @priv: Private driver interface data diff --git a/src/drivers/driver_nl80211.c b/src/drivers/driver_nl80211.c index 512893327..6f456779b 100644 --- a/src/drivers/driver_nl80211.c +++ b/src/drivers/driver_nl80211.c @@ -8303,6 +8303,16 @@ static int wpa_driver_nl80211_deinit_ap(void *priv) } +static int wpa_driver_nl80211_deinit_p2p_cli(void *priv) +{ + struct i802_bss *bss = priv; + struct wpa_driver_nl80211_data *drv = bss->drv; + if (drv->nlmode != NL80211_IFTYPE_P2P_CLIENT) + return -1; + return wpa_driver_nl80211_set_mode(priv, NL80211_IFTYPE_STATION); +} + + static void wpa_driver_nl80211_resume(void *priv) { struct i802_bss *bss = priv; @@ -9028,6 +9038,7 @@ const struct wpa_driver_ops wpa_driver_nl80211_ops = { wpa_driver_nl80211_cancel_remain_on_channel, .probe_req_report = wpa_driver_nl80211_probe_req_report, .deinit_ap = wpa_driver_nl80211_deinit_ap, + .deinit_p2p_cli = wpa_driver_nl80211_deinit_p2p_cli, .resume = wpa_driver_nl80211_resume, .send_ft_action = nl80211_send_ft_action, .signal_monitor = nl80211_signal_monitor, diff --git a/wpa_supplicant/driver_i.h b/wpa_supplicant/driver_i.h index 5b1054052..e1e921d2a 100644 --- a/wpa_supplicant/driver_i.h +++ b/wpa_supplicant/driver_i.h @@ -427,6 +427,13 @@ static inline int wpa_drv_deinit_ap(struct wpa_supplicant *wpa_s) return 0; } +static inline int wpa_drv_deinit_p2p_cli(struct wpa_supplicant *wpa_s) +{ + if (wpa_s->driver->deinit_p2p_cli) + return wpa_s->driver->deinit_p2p_cli(wpa_s->drv_priv); + return 0; +} + static inline void wpa_drv_suspend(struct wpa_supplicant *wpa_s) { if (wpa_s->driver->suspend) diff --git a/wpa_supplicant/p2p_supplicant.c b/wpa_supplicant/p2p_supplicant.c index ebd248671..413d0b277 100644 --- a/wpa_supplicant/p2p_supplicant.c +++ b/wpa_supplicant/p2p_supplicant.c @@ -311,7 +311,10 @@ static void wpas_p2p_group_delete(struct wpa_supplicant *wpa_s) wpa_printf(MSG_DEBUG, "P2P: Temporary group network not " "found"); } - wpa_supplicant_ap_deinit(wpa_s); + if (wpa_s->ap_iface) + wpa_supplicant_ap_deinit(wpa_s); + else + wpa_drv_deinit_p2p_cli(wpa_s); }