diff --git a/src/drivers/driver.h b/src/drivers/driver.h index 60304a181..f492f9fd1 100644 --- a/src/drivers/driver.h +++ b/src/drivers/driver.h @@ -1708,6 +1708,17 @@ struct wpa_driver_ops { * 802.11b-only devices. */ int (*disable_11b_rates)(void *priv, int disabled); + + /** + * deinit_ap - Deinitialize AP 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 AP mode related + * configuration and change the driver mode to station mode to allow + * normal station operations like scanning to be completed. + */ + int (*deinit_ap)(void *priv); }; diff --git a/src/drivers/driver_ndis.c b/src/drivers/driver_ndis.c index d36c0a9e3..29597a682 100644 --- a/src/drivers/driver_ndis.c +++ b/src/drivers/driver_ndis.c @@ -3271,5 +3271,6 @@ const struct wpa_driver_ops wpa_driver_ndis_ops = { NULL /* remain_on_channel */, NULL /* cancel_remain_on_channel */, NULL /* probe_req_report */, - NULL /* disable_11b_rates */ + NULL /* disable_11b_rates */, + NULL /* deinit_ap */ }; diff --git a/src/drivers/driver_nl80211.c b/src/drivers/driver_nl80211.c index a394e296d..ec2dad6d3 100644 --- a/src/drivers/driver_nl80211.c +++ b/src/drivers/driver_nl80211.c @@ -1959,6 +1959,9 @@ static int wpa_driver_nl80211_authenticate( drv->associated = 0; os_memset(drv->auth_bssid, 0, ETH_ALEN); + /* FIX: IBSS mode */ + if (drv->nlmode != NL80211_IFTYPE_STATION) + wpa_driver_nl80211_set_mode(priv, IEEE80211_MODE_INFRA); if (wpa_driver_nl80211_set_mode(drv, IEEE80211_MODE_INFRA) < 0) return -1; @@ -3632,6 +3635,9 @@ done: } else if (!ret && nlmode != NL80211_IFTYPE_AP) { /* Remove additional AP mode functionality */ nl80211_remove_monitor_interface(drv); +#ifndef HOSTAPD + drv->beacon_set = 0; +#endif /* HOSTAPD */ } if (ret) @@ -4629,6 +4635,16 @@ static int wpa_driver_nl80211_disable_11b_rates(void *priv, int disabled) } +static int wpa_driver_nl80211_deinit_ap(void *priv) +{ + struct wpa_driver_nl80211_data *drv = priv; + if (drv->nlmode != NL80211_IFTYPE_AP) + return -1; + wpa_driver_nl80211_del_beacon(drv); + return wpa_driver_nl80211_set_mode(drv, IEEE80211_MODE_INFRA); +} + + const struct wpa_driver_ops wpa_driver_nl80211_ops = { .name = "nl80211", .desc = "Linux nl80211/cfg80211", @@ -4684,4 +4700,5 @@ const struct wpa_driver_ops wpa_driver_nl80211_ops = { .alloc_interface_addr = wpa_driver_nl80211_alloc_interface_addr, .release_interface_addr = wpa_driver_nl80211_release_interface_addr, .disable_11b_rates = wpa_driver_nl80211_disable_11b_rates, + .deinit_ap = wpa_driver_nl80211_deinit_ap, }; diff --git a/wpa_supplicant/driver_i.h b/wpa_supplicant/driver_i.h index 5f3e1496b..203cbfca7 100644 --- a/wpa_supplicant/driver_i.h +++ b/wpa_supplicant/driver_i.h @@ -449,4 +449,11 @@ static inline int wpa_drv_disable_11b_rates(struct wpa_supplicant *wpa_s, return -1; } +static inline int wpa_drv_deinit_ap(struct wpa_supplicant *wpa_s) +{ + if (wpa_s->driver->deinit_ap) + return wpa_s->driver->deinit_ap(wpa_s->drv_priv); + return 0; +} + #endif /* DRIVER_I_H */