nl80211: Fix deauth/disassoc for AP mode SME-in-driver case
authorAarthi Thiruvengadam <athiruve@qca.qualcomm.com>
Thu, 15 Mar 2012 00:06:06 +0000 (14:06 -1000)
committerJouni Malinen <j@w1.fi>
Thu, 15 Mar 2012 00:06:06 +0000 (14:06 -1000)
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>

src/drivers/driver_nl80211.c

index 184b26f..74865f3 100644 (file)
@@ -2579,7 +2579,9 @@ 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_SET_KEYS_AFTER_ASSOC_DONE;
        drv->capa.flags |= WPA_DRIVER_FLAGS_EAPOL_TX_STATUS;
-       drv->capa.flags |= WPA_DRIVER_FLAGS_DEAUTH_TX_STATUS;
+
+       if (!info.device_ap_sme)
+               drv->capa.flags |= WPA_DRIVER_FLAGS_DEAUTH_TX_STATUS;
 
        drv->device_ap_sme = info.device_ap_sme;
        drv->poll_command_supported = info.poll_command_supported;
@@ -7399,8 +7401,12 @@ static int i802_sta_deauth(void *priv, const u8 *own_addr, const u8 *addr,
                           int reason)
 {
        struct i802_bss *bss = priv;
+       struct wpa_driver_nl80211_data *drv = bss->drv;
        struct ieee80211_mgmt mgmt;
 
+       if (drv->device_ap_sme)
+               return wpa_driver_nl80211_sta_remove(bss, addr);
+
        memset(&mgmt, 0, sizeof(mgmt));
        mgmt.frame_control = IEEE80211_FC(WLAN_FC_TYPE_MGMT,
                                          WLAN_FC_STYPE_DEAUTH);
@@ -7418,8 +7424,12 @@ static int i802_sta_disassoc(void *priv, const u8 *own_addr, const u8 *addr,
                             int reason)
 {
        struct i802_bss *bss = priv;
+       struct wpa_driver_nl80211_data *drv = bss->drv;
        struct ieee80211_mgmt mgmt;
 
+       if (drv->device_ap_sme)
+               return wpa_driver_nl80211_sta_remove(bss, addr);
+
        memset(&mgmt, 0, sizeof(mgmt));
        mgmt.frame_control = IEEE80211_FC(WLAN_FC_TYPE_MGMT,
                                          WLAN_FC_STYPE_DISASSOC);