nl80211: Fix deauth/disassoc for AP mode SME-in-driver case

When the driver (or firmware) implements AP mode SME, the use of raw
management frame TX functions is not working properly at the moment. As
an initial step, convert these AP mode operations to use
NL80211_CMD_DEL_STATION and do not claim that driver provides TX status
for deauth/disassoc frames. While this does not address all use cases
(e.g., reason code is not specified in the command), this fixes number
of issues where the station does not get disconnected properly.

Signed-hostap: Jouni Malinen <jouni@qca.qualcomm.com>
This commit is contained in:
Aarthi Thiruvengadam 2012-03-14 14:06:06 -10:00 committed by Jouni Malinen
parent 7d39d9c9cc
commit e1bd4e1934

View File

@ -2579,6 +2579,8 @@ static int wpa_driver_nl80211_capa(struct wpa_driver_nl80211_data *drv)
drv->capa.flags |= WPA_DRIVER_FLAGS_SANE_ERROR_CODES; drv->capa.flags |= WPA_DRIVER_FLAGS_SANE_ERROR_CODES;
drv->capa.flags |= WPA_DRIVER_FLAGS_SET_KEYS_AFTER_ASSOC_DONE; drv->capa.flags |= WPA_DRIVER_FLAGS_SET_KEYS_AFTER_ASSOC_DONE;
drv->capa.flags |= WPA_DRIVER_FLAGS_EAPOL_TX_STATUS; drv->capa.flags |= WPA_DRIVER_FLAGS_EAPOL_TX_STATUS;
if (!info.device_ap_sme)
drv->capa.flags |= WPA_DRIVER_FLAGS_DEAUTH_TX_STATUS; drv->capa.flags |= WPA_DRIVER_FLAGS_DEAUTH_TX_STATUS;
drv->device_ap_sme = info.device_ap_sme; drv->device_ap_sme = info.device_ap_sme;
@ -7399,8 +7401,12 @@ static int i802_sta_deauth(void *priv, const u8 *own_addr, const u8 *addr,
int reason) int reason)
{ {
struct i802_bss *bss = priv; struct i802_bss *bss = priv;
struct wpa_driver_nl80211_data *drv = bss->drv;
struct ieee80211_mgmt mgmt; struct ieee80211_mgmt mgmt;
if (drv->device_ap_sme)
return wpa_driver_nl80211_sta_remove(bss, addr);
memset(&mgmt, 0, sizeof(mgmt)); memset(&mgmt, 0, sizeof(mgmt));
mgmt.frame_control = IEEE80211_FC(WLAN_FC_TYPE_MGMT, mgmt.frame_control = IEEE80211_FC(WLAN_FC_TYPE_MGMT,
WLAN_FC_STYPE_DEAUTH); WLAN_FC_STYPE_DEAUTH);
@ -7418,8 +7424,12 @@ static int i802_sta_disassoc(void *priv, const u8 *own_addr, const u8 *addr,
int reason) int reason)
{ {
struct i802_bss *bss = priv; struct i802_bss *bss = priv;
struct wpa_driver_nl80211_data *drv = bss->drv;
struct ieee80211_mgmt mgmt; struct ieee80211_mgmt mgmt;
if (drv->device_ap_sme)
return wpa_driver_nl80211_sta_remove(bss, addr);
memset(&mgmt, 0, sizeof(mgmt)); memset(&mgmt, 0, sizeof(mgmt));
mgmt.frame_control = IEEE80211_FC(WLAN_FC_TYPE_MGMT, mgmt.frame_control = IEEE80211_FC(WLAN_FC_TYPE_MGMT,
WLAN_FC_STYPE_DISASSOC); WLAN_FC_STYPE_DISASSOC);