Update to new version 0.8.22 from BRCM
- Based on 0c01d65 : Ignore TX status for Data frames from not associated
STA
Change-Id: I2776ff8e292593f407bf5b9177640c512e06bf0d
Signed-off-by: Dmitry Shmidt <dimitrysh@google.com>
diff --git a/src/drivers/driver_nl80211.c b/src/drivers/driver_nl80211.c
index a00f703..9ef4e8b 100644
--- a/src/drivers/driver_nl80211.c
+++ b/src/drivers/driver_nl80211.c
@@ -1,19 +1,13 @@
/*
* Driver interaction with Linux nl80211/cfg80211
- * Copyright (c) 2002-2010, Jouni Malinen <j@w1.fi>
+ * Copyright (c) 2002-2012, Jouni Malinen <j@w1.fi>
* Copyright (c) 2003-2004, Instant802 Networks, Inc.
* Copyright (c) 2005-2006, Devicescape Software, Inc.
* Copyright (c) 2007, Johannes Berg <johannes@sipsolutions.net>
* Copyright (c) 2009-2010, Atheros Communications
*
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- *
- * Alternatively, this software may be distributed under the terms of BSD
- * license.
- *
- * See README and COPYING for more details.
+ * This software may be distributed under the terms of the BSD license.
+ * See README for more details.
*/
#include "includes.h"
@@ -43,9 +37,7 @@
#include "radiotap_iter.h"
#include "rfkill.h"
#include "driver.h"
-#if defined(ANDROID_P2P) && !defined(HOSTAPD)
-#include "wpa_supplicant_i.h"
-#endif
+
#ifndef SO_WIFI_STATUS
# if defined(__sparc__)
# define SO_WIFI_STATUS 0x0025
@@ -622,7 +614,7 @@
{
struct nl80211_wiphy_data *w = eloop_ctx;
- wpa_printf(MSG_DEBUG, "nl80211: Beacon event message available");
+ wpa_printf(MSG_EXCESSIVE, "nl80211: Beacon event message available");
nl_recvmsgs(handle, w->nl_cb);
}
@@ -1076,9 +1068,6 @@
const struct ieee80211_mgmt *mgmt;
union wpa_event_data event;
u16 status;
-#ifdef ANDROID_P2P
- struct wpa_supplicant *wpa_s = drv->ctx;
-#endif
mgmt = (const struct ieee80211_mgmt *) frame;
#if (defined (CONFIG_AP) || defined (HOSTAPD) ) && defined (ANDROID_P2P)
@@ -1186,7 +1175,8 @@
static void mlme_event_disconnect(struct wpa_driver_nl80211_data *drv,
- struct nlattr *reason, struct nlattr *addr)
+ struct nlattr *reason, struct nlattr *addr,
+ struct nlattr *by_ap)
{
union wpa_event_data data;
@@ -1204,6 +1194,7 @@
os_memset(&data, 0, sizeof(data));
if (reason)
data.disassoc_info.reason_code = nla_get_u16(reason);
+ data.disassoc_info.locally_generated = by_ap == NULL;
wpa_supplicant_event(drv->ctx, EVENT_DISASSOC, &data);
}
@@ -1352,6 +1343,9 @@
reason_code = le_to_host16(mgmt->u.deauth.reason_code);
if (type == EVENT_DISASSOC) {
+ event.disassoc_info.locally_generated =
+ !os_memcmp(mgmt->sa, drv->first_bss.addr, ETH_ALEN);
+
#ifdef ANDROID_P2P
if (drv->nlmode == NL80211_IFTYPE_AP ||
drv->nlmode == NL80211_IFTYPE_P2P_GO) {
@@ -1366,11 +1360,14 @@
mgmt->u.disassoc.variable;
}
} else {
+ event.deauth_info.locally_generated =
+ !os_memcmp(mgmt->sa, drv->first_bss.addr, ETH_ALEN);
+
#ifdef ANDROID_P2P
- if (drv->nlmode == NL80211_IFTYPE_AP ||
- drv->nlmode == NL80211_IFTYPE_P2P_GO) {
- event.deauth_info.addr = mgmt->sa;
- } else
+ if (drv->nlmode == NL80211_IFTYPE_AP ||
+ drv->nlmode == NL80211_IFTYPE_P2P_GO) {
+ event.deauth_info.addr = mgmt->sa;
+ } else
#endif
event.deauth_info.addr = bssid;
event.deauth_info.reason_code = reason_code;
@@ -2138,7 +2135,8 @@
break;
case NL80211_CMD_DISCONNECT:
mlme_event_disconnect(drv, tb[NL80211_ATTR_REASON_CODE],
- tb[NL80211_ATTR_MAC]);
+ tb[NL80211_ATTR_MAC],
+ tb[NL80211_ATTR_DISCONNECTED_BY_AP]);
break;
case NL80211_CMD_MICHAEL_MIC_FAILURE:
mlme_event_michael_mic_failure(drv, tb);
@@ -5175,24 +5173,32 @@
static int wpa_driver_nl80211_send_frame(struct i802_bss *bss,
const void *data, size_t len,
- int encrypt, int noack)
+ int encrypt, int noack,
+ unsigned int freq, int no_cck,
+ int offchanok, unsigned int wait_time)
{
struct wpa_driver_nl80211_data *drv = bss->drv;
u64 cookie;
+ if (freq == 0)
+ freq = bss->freq;
+
if (drv->use_monitor)
return wpa_driver_nl80211_send_mntr(drv, data, len,
encrypt, noack);
- return nl80211_send_frame_cmd(bss, bss->freq, 0, data, len,
- &cookie, 0, noack, 0);
+ return nl80211_send_frame_cmd(bss, freq, wait_time, data, len,
+ &cookie, no_cck, noack, offchanok);
}
-static int wpa_driver_nl80211_send_mlme(void *priv, const u8 *data,
- size_t data_len, int noack)
+static int wpa_driver_nl80211_send_mlme_freq(struct i802_bss *bss,
+ const u8 *data,
+ size_t data_len, int noack,
+ unsigned int freq, int no_cck,
+ int offchanok,
+ unsigned int wait_time)
{
- struct i802_bss *bss = priv;
struct wpa_driver_nl80211_data *drv = bss->drv;
struct ieee80211_mgmt *mgmt;
int encrypt = 1;
@@ -5209,21 +5215,28 @@
* but it works due to the single-threaded nature
* of wpa_supplicant.
*/
- return nl80211_send_frame_cmd(bss, drv->last_mgmt_freq, 0,
+ if (freq == 0)
+ freq = drv->last_mgmt_freq;
+ return nl80211_send_frame_cmd(bss, freq, 0,
data, data_len, NULL, 1, noack,
1);
}
#ifdef ANDROID_P2P
- if (is_ap_interface(drv->nlmode)) {
- return nl80211_send_frame_cmd(bss, bss->freq, 0,
+ if (freq == 0)
+ freq = bss->freq;
+ if ( is_ap_interface(drv->nlmode)) {
+ return nl80211_send_frame_cmd(bss, freq, 0,
data, data_len, &drv->send_action_cookie, 0, noack, 1);
}
#else
if (drv->device_ap_sme && is_ap_interface(drv->nlmode)) {
- return nl80211_send_frame_cmd(bss, bss->freq, 0,
- data, data_len, NULL,
- 0, noack, 0);
+ if (freq == 0)
+ freq = bss->freq;
+ return nl80211_send_frame_cmd(bss, freq, 0,
+ data, data_len,
+ &drv->send_action_cookie,
+ no_cck, noack, offchanok);
}
#endif
if (WLAN_FC_GET_TYPE(fc) == WLAN_FC_TYPE_MGMT &&
@@ -5241,7 +5254,17 @@
}
return wpa_driver_nl80211_send_frame(bss, data, data_len, encrypt,
- noack);
+ noack, freq, no_cck, offchanok,
+ wait_time);
+}
+
+
+static int wpa_driver_nl80211_send_mlme(void *priv, const u8 *data,
+ size_t data_len, int noack)
+{
+ struct i802_bss *bss = priv;
+ return wpa_driver_nl80211_send_mlme_freq(bss, data, data_len, noack,
+ 0, 0, 0, 0);
}
@@ -6303,7 +6326,8 @@
pos += 2;
memcpy(pos, data, data_len);
- res = wpa_driver_nl80211_send_frame(bss, (u8 *) hdr, len, encrypt, 0);
+ res = wpa_driver_nl80211_send_frame(bss, (u8 *) hdr, len, encrypt, 0,
+ 0, 0, 0, 0);
if (res < 0) {
wpa_printf(MSG_ERROR, "i802_send_eapol - packet len: %lu - "
"failed: %d (%s)",
@@ -6468,6 +6492,20 @@
if (ret)
goto nla_put_failure;
+ if (params->bssid && params->fixed_bssid) {
+ wpa_printf(MSG_DEBUG, " * BSSID=" MACSTR,
+ MAC2STR(params->bssid));
+ NLA_PUT(msg, NL80211_ATTR_MAC, ETH_ALEN, params->bssid);
+ }
+
+ if (params->key_mgmt_suite == KEY_MGMT_802_1X ||
+ params->key_mgmt_suite == KEY_MGMT_PSK ||
+ params->key_mgmt_suite == KEY_MGMT_802_1X_SHA256 ||
+ params->key_mgmt_suite == KEY_MGMT_PSK_SHA256) {
+ wpa_printf(MSG_DEBUG, " * control port");
+ NLA_PUT_FLAG(msg, NL80211_ATTR_CONTROL_PORT);
+ }
+
if (params->wpa_ie) {
wpa_hexdump(MSG_DEBUG,
" * Extra IEs for Beacon/Probe Response frames",
@@ -6689,6 +6727,16 @@
NLA_PUT_U32(msg, NL80211_ATTR_AKM_SUITES, mgmt);
}
+ if (params->disable_ht)
+ NLA_PUT_FLAG(msg, NL80211_ATTR_DISABLE_HT);
+
+ if (params->htcaps && params->htcaps_mask) {
+ int sz = sizeof(struct ieee80211_ht_capabilities);
+ NLA_PUT(msg, NL80211_ATTR_HT_CAPABILITY, sz, params->htcaps);
+ NLA_PUT(msg, NL80211_ATTR_HT_CAPABILITY_MASK, sz,
+ params->htcaps_mask);
+ }
+
ret = nl80211_set_conn_keys(params, msg);
if (ret)
goto nla_put_failure;
@@ -6836,6 +6884,16 @@
params->prev_bssid);
}
+ if (params->disable_ht)
+ NLA_PUT_FLAG(msg, NL80211_ATTR_DISABLE_HT);
+
+ if (params->htcaps && params->htcaps_mask) {
+ int sz = sizeof(struct ieee80211_ht_capabilities);
+ NLA_PUT(msg, NL80211_ATTR_HT_CAPABILITY, sz, params->htcaps);
+ NLA_PUT(msg, NL80211_ATTR_HT_CAPABILITY_MASK, sz,
+ params->htcaps_mask);
+ }
+
if (params->p2p)
wpa_printf(MSG_DEBUG, " * P2P group");
@@ -7849,10 +7907,15 @@
new_bss->ifindex = ifidx;
new_bss->drv = drv;
new_bss->next = drv->first_bss.next;
+ new_bss->freq = drv->first_bss.freq;
drv->first_bss.next = new_bss;
if (drv_priv)
*drv_priv = new_bss;
nl80211_init_bss(new_bss);
+
+ /* Subscribe management frames for this WPA_IF_AP_BSS */
+ if (nl80211_setup_ap(new_bss))
+ return -1;
}
#endif /* HOSTAPD */
@@ -7904,6 +7967,8 @@
for (tbss = &drv->first_bss; tbss; tbss = tbss->next) {
if (tbss->next == bss) {
tbss->next = bss->next;
+ /* Unsubscribe management frames */
+ nl80211_teardown_ap(bss);
nl80211_destroy_bss(bss);
os_free(bss);
bss = NULL;
@@ -7956,7 +8021,7 @@
if (wait)
NLA_PUT_U32(msg, NL80211_ATTR_DURATION, wait);
#endif
- if (offchanok)
+ if (offchanok && (drv->capa.flags & WPA_DRIVER_FLAGS_OFFCHANNEL_TX))
NLA_PUT_FLAG(msg, NL80211_ATTR_OFFCHANNEL_TX_OK);
if (no_cck)
NLA_PUT_FLAG(msg, NL80211_ATTR_TX_NO_CCK_RATE);
@@ -8001,7 +8066,8 @@
struct ieee80211_hdr *hdr;
wpa_printf(MSG_DEBUG, "nl80211: Send Action frame (ifindex=%d, "
- "wait=%d ms no_cck=%d)", drv->ifindex, wait_time, no_cck);
+ "freq=%u MHz wait=%d ms no_cck=%d)",
+ drv->ifindex, freq, wait_time, no_cck);
buf = os_zalloc(24 + data_len);
if (buf == NULL)
@@ -8015,8 +8081,10 @@
os_memcpy(hdr->addr3, bssid, ETH_ALEN);
if (is_ap_interface(drv->nlmode))
- ret = wpa_driver_nl80211_send_mlme(priv, buf, 24 + data_len,
- 0);
+ ret = wpa_driver_nl80211_send_mlme_freq(priv, buf,
+ 24 + data_len,
+ 0, freq, no_cck, 1,
+ wait_time);
else
ret = nl80211_send_frame_cmd(bss, freq, wait_time, buf,
24 + data_len,
@@ -8451,7 +8519,8 @@
int encrypt)
{
struct i802_bss *bss = priv;
- return wpa_driver_nl80211_send_frame(bss, data, data_len, encrypt, 0);
+ return wpa_driver_nl80211_send_frame(bss, data, data_len, encrypt, 0,
+ 0, 0, 0, 0);
}
@@ -8743,7 +8812,11 @@
"opp_ps=%d ctwindow=%d)", legacy_ps, opp_ps, ctwindow);
if (opp_ps != -1 || ctwindow != -1)
+#ifdef ANDROID_P2P
+ wpa_driver_set_p2p_ps(priv, legacy_ps, opp_ps, ctwindow);
+#else
return -1; /* Not yet supported */
+#endif
if (legacy_ps == -1)
return 0;
@@ -9046,9 +9119,7 @@
.flush_pmkid = nl80211_flush_pmkid,
.set_rekey_info = nl80211_set_rekey_info,
.poll_client = nl80211_poll_client,
-#ifndef ANDROID_P2P
.set_p2p_powersave = nl80211_set_p2p_powersave,
-#endif
#ifdef CONFIG_TDLS
.send_tdls_mgmt = nl80211_send_tdls_mgmt,
.tdls_oper = nl80211_tdls_oper,
@@ -9056,7 +9127,6 @@
#ifdef ANDROID_P2P
.set_noa = wpa_driver_set_p2p_noa,
.get_noa = wpa_driver_get_p2p_noa,
- .set_p2p_powersave = wpa_driver_set_p2p_ps,
.set_ap_wps_ie = wpa_driver_set_ap_wps_p2p_ie,
#endif
#ifdef ANDROID