* [PATCH] iw: fix output qualifier for unsigned values
From: Arnd Hannemann @ 2009-08-17 10:46 UTC (permalink / raw)
To: linux-wireless@vger.kernel.org
[-- Attachment #1: Type: text/plain, Size: 353 bytes --]
Hi,
with 0.9.16 a "iw wlan0 station dump" gives the following output:
Station XX:XX:XX:XX:XX:XX (on wlan0)
inactive time: 4 ms
rx bytes: -1611945626
rx packets: 7643414
tx bytes: 1527923993
tx packets: 4829428
signal: -63 dBm
tx bitrate: 54.0 MBit/s
Seems to be the output qualifier %d is used wrongly in some cases.
This patch fixes that.
[-- Attachment #2: iw_use_unsigned.patch --]
[-- Type: text/x-patch, Size: 1198 bytes --]
Signed-off-by: Arnd Hannemann <hannemann@nets.rwth-aachen.de>
diff -Naur iw-0.9.16.orig/station.c iw-0.9.16/station.c
--- iw-0.9.16.orig/station.c 2009-08-16 16:03:36.000000000 +0200
+++ iw-0.9.16/station.c 2009-08-17 12:31:58.119502558 +0200
@@ -80,19 +80,19 @@
printf("Station %s (on %s)", mac_addr, dev);
if (sinfo[NL80211_STA_INFO_INACTIVE_TIME])
- printf("\n\tinactive time:\t%d ms",
+ printf("\n\tinactive time:\t%u ms",
nla_get_u32(sinfo[NL80211_STA_INFO_INACTIVE_TIME]));
if (sinfo[NL80211_STA_INFO_RX_BYTES])
- printf("\n\trx bytes:\t%d",
+ printf("\n\trx bytes:\t%u",
nla_get_u32(sinfo[NL80211_STA_INFO_RX_BYTES]));
if (sinfo[NL80211_STA_INFO_RX_PACKETS])
- printf("\n\trx packets:\t%d",
+ printf("\n\trx packets:\t%u",
nla_get_u32(sinfo[NL80211_STA_INFO_RX_PACKETS]));
if (sinfo[NL80211_STA_INFO_TX_BYTES])
- printf("\n\ttx bytes:\t%d",
+ printf("\n\ttx bytes:\t%u",
nla_get_u32(sinfo[NL80211_STA_INFO_TX_BYTES]));
if (sinfo[NL80211_STA_INFO_TX_PACKETS])
- printf("\n\ttx packets:\t%d",
+ printf("\n\ttx packets:\t%u",
nla_get_u32(sinfo[NL80211_STA_INFO_TX_PACKETS]));
if (sinfo[NL80211_STA_INFO_SIGNAL])
printf("\n\tsignal: \t%d dBm",
^ permalink raw reply
* Re: [ANN] iw: v0.9.16
From: Johannes Berg @ 2009-08-17 10:39 UTC (permalink / raw)
To: drago01; +Cc: linux-wireless
In-Reply-To: <f6ca9fed0908170336u50df5a48v80fa34549fc08e87@mail.gmail.com>
[-- Attachment #1: Type: text/plain, Size: 980 bytes --]
On Mon, 2009-08-17 at 12:36 +0200, drago01 wrote:
> On Mon, Aug 17, 2009 at 5:10 AM, <wireless@sipsolutions.net> wrote:
> >
> > A new release of iw (v0.9.16) is available at:
> >
> > http://wireless.kernel.org/download/iw/iw-0.9.16.tar.bz2
> >
> > SHA1 sum: e224b6698802498569854b475ae532d41ddbd719
> >
> > Here is the short log of the changes included in this
> > release:
>
> It is indeed very short ;)
Yeah, must be a bug in the script...
The real shortlog would have been
0.9.16
Revert "magically set interface up for connect/join"
mark a key default if none is marked manually
add iw commands for setting fragmentation and rts threshold
iw: fix typos in MCS set parsing code
print out wmm aifsn
some wmm parameter improvements
fix typo
fix bug parsing ACI
show WMM parameters
iw: add beacon hint event parsing
add warning about screenscraping
add missing newline
add link command
magically set interface up for connect/join
johannes
[-- Attachment #2: This is a digitally signed message part --]
[-- Type: application/pgp-signature, Size: 801 bytes --]
^ permalink raw reply
* Re: [ANN] iw: v0.9.16
From: drago01 @ 2009-08-17 10:36 UTC (permalink / raw)
To: linux-wireless
In-Reply-To: <E1McscB-0004xM-M5@sipsolutions.net>
On Mon, Aug 17, 2009 at 5:10 AM, <wireless@sipsolutions.net> wrote:
>
> A new release of iw (v0.9.16) is available at:
>
> http://wireless.kernel.org/download/iw/iw-0.9.16.tar.bz2
>
> SHA1 sum: e224b6698802498569854b475ae532d41ddbd719
>
> Here is the short log of the changes included in this
> release:
It is indeed very short ;)
^ permalink raw reply
* [PATCH v2] cfg80211: fix deadlock
From: Johannes Berg @ 2009-08-17 10:25 UTC (permalink / raw)
To: John Linville; +Cc: linux-wireless, Christian Lamparter
In-Reply-To: <1250422358.17522.0.camel@johannes.local>
When removing an interface with nl80211, cfg80211 will
deadlock in the netdev notifier because we're already
holding rdev->mtx and try to acquire it again to verify
the scan has been done.
This bug was introduced by my patch
"cfg80211: check for and abort dangling scan requests".
To fix this, move the dangling scan request check into
wiphy_unregister(). This will not be able to catch all
cases right away, but if the scan problem happens with
a manual ifdown or so it will be possible to remedy it
by removing the module/device.
Additionally, add comments about the deadlock scenario.
Reported-by: Christian Lamparter <chunkeey@web.de>
Signed-off-by: Johannes Berg <johannes@sipsolutions.net>
---
v2: don't move flush_work under cfg80211_mutex locked section
net/wireless/core.c | 30 ++++++++++++++++++------------
1 file changed, 18 insertions(+), 12 deletions(-)
--- wireless-testing.orig/net/wireless/core.c 2009-08-16 13:35:51.000000000 +0200
+++ wireless-testing/net/wireless/core.c 2009-08-17 12:22:50.000000000 +0200
@@ -586,9 +586,14 @@ void wiphy_unregister(struct wiphy *wiph
* get to lock contention here if userspace issues a command
* that identified the hardware by wiphy index.
*/
- mutex_lock(&rdev->mtx);
- /* unlock again before freeing */
- mutex_unlock(&rdev->mtx);
+ cfg80211_lock_rdev(rdev);
+
+ if (WARN_ON(rdev->scan_req)) {
+ rdev->scan_req->aborted = true;
+ ___cfg80211_scan_done(rdev);
+ }
+
+ cfg80211_unlock_rdev(rdev);
cfg80211_debugfs_rdev_del(rdev);
@@ -605,7 +610,6 @@ void wiphy_unregister(struct wiphy *wiph
flush_work(&rdev->scan_done_wk);
cancel_work_sync(&rdev->conn_work);
- kfree(rdev->scan_req);
flush_work(&rdev->event_work);
}
EXPORT_SYMBOL(wiphy_unregister);
@@ -653,6 +657,11 @@ static int cfg80211_netdev_notifier_call
switch (state) {
case NETDEV_REGISTER:
+ /*
+ * NB: cannot take rdev->mtx here because this may be
+ * called within code protected by it when interfaces
+ * are added with nl80211.
+ */
mutex_init(&wdev->mtx);
INIT_LIST_HEAD(&wdev->event_list);
spin_lock_init(&wdev->event_lock);
@@ -730,13 +739,11 @@ static int cfg80211_netdev_notifier_call
#endif
break;
case NETDEV_UNREGISTER:
- cfg80211_lock_rdev(rdev);
-
- if (WARN_ON(rdev->scan_req && rdev->scan_req->dev == dev)) {
- rdev->scan_req->aborted = true;
- ___cfg80211_scan_done(rdev);
- }
-
+ /*
+ * NB: cannot take rdev->mtx here because this may be
+ * called within code protected by it when interfaces
+ * are removed with nl80211.
+ */
mutex_lock(&rdev->devlist_mtx);
/*
* It is possible to get NETDEV_UNREGISTER
@@ -755,7 +762,6 @@ static int cfg80211_netdev_notifier_call
#endif
}
mutex_unlock(&rdev->devlist_mtx);
- cfg80211_unlock_rdev(rdev);
break;
case NETDEV_PRE_UP:
if (!(wdev->wiphy->interface_modes & BIT(wdev->iftype)))
^ permalink raw reply
* Re: Multiple BSSID problem with hostapd
From: Christian Felsing @ 2009-08-17 10:25 UTC (permalink / raw)
To: linux-wireless
In-Reply-To: <20090817102354.GA19258@jm.kir.nu>
Works with development branch :-)
regards
Christian
Jouni Malinen schrieb:
> checking the current development branch (0.7.x) would be a good idea
> when advanced AP functionality is desired.
>
^ permalink raw reply
* Re: Multiple BSSID problem with hostapd
From: Jouni Malinen @ 2009-08-17 10:23 UTC (permalink / raw)
To: Christian Felsing; +Cc: linux-wireless
In-Reply-To: <4A75333D.9070100@taunusstein.net>
On Sun, Aug 02, 2009 at 08:33:33AM +0200, Christian Felsing wrote:
> After investigating source code following function caused my problem:
>
> static int i802_bss_add(void *priv, const char *ifname, const u8 *bssid)
> {
> int ifidx;
>
> /*
> * The kernel supports that when the low-level driver does,
> * but we currently don't because we need per-BSS data that
> * currently we can't handle easily.
> */
> return -1;
Some more investigation would show that this does not exist in the
hostapd development branch..
> Obviously hostapd does not support multiple SSIDs because that function
> returns always an error.
That is the case for hostapd 0.6.9. In any case, there are number of new
kernel features that may not be fully supported by the 0.6.x branch and
checking the current development branch (0.7.x) would be a good idea
when advanced AP functionality is desired.
--
Jouni Malinen PGP id EFC895FA
^ permalink raw reply
* [PATCH] cfg80211: report userspace SME connected event properly
From: Johannes Berg @ 2009-08-17 10:22 UTC (permalink / raw)
To: John Linville; +Cc: Zhu Yi, linux-wireless
Instead of hacking the event reporting into the
__cfg80211_connect_result() function which is also
invoked by others, set up things correctly and then
invoke that function, so that it can do more sanity
checking.
Also, it is currently not possible to get a ROAMED
event from the userspace SME anyway since we send
out a DISCONNECTED event when it disassociates and
then a new CONNECTED event on the next association.
Thanks to Zhu Yi for pointing out that the code is
somewhat convoluted and doesn't warn when it should.
Signed-off-by: Johannes Berg <johannes@sipsolutions.net>
---
net/wireless/mlme.c | 9 +++++++++
net/wireless/sme.c | 22 ++++++----------------
2 files changed, 15 insertions(+), 16 deletions(-)
--- wireless-testing.orig/net/wireless/mlme.c 2009-08-17 11:48:13.000000000 +0200
+++ wireless-testing/net/wireless/mlme.c 2009-08-17 12:17:54.000000000 +0200
@@ -96,6 +96,15 @@ void cfg80211_send_rx_assoc(struct net_d
WARN_ON(!bss);
}
+ if (!wdev->conn && wdev->sme_state == CFG80211_SME_IDLE) {
+ /*
+ * This is for the userspace SME, the CONNECTING
+ * state will be changed to CONNECTED by
+ * __cfg80211_connect_result() below.
+ */
+ wdev->sme_state = CFG80211_SME_CONNECTING;
+ }
+
/* this consumes one bss reference (unless bss is NULL) */
__cfg80211_connect_result(dev, mgmt->bssid, NULL, 0, ie, len - ieoffs,
status_code,
--- wireless-testing.orig/net/wireless/sme.c 2009-08-17 11:46:44.000000000 +0200
+++ wireless-testing/net/wireless/sme.c 2009-08-17 11:48:04.000000000 +0200
@@ -351,15 +351,13 @@ void __cfg80211_connect_result(struct ne
if (WARN_ON(wdev->iftype != NL80211_IFTYPE_STATION))
return;
- if (wdev->sme_state == CFG80211_SME_CONNECTED)
- nl80211_send_roamed(wiphy_to_dev(wdev->wiphy), dev,
+ if (WARN_ON(wdev->sme_state != CFG80211_SME_CONNECTING))
+ return;
+
+ nl80211_send_connect_result(wiphy_to_dev(wdev->wiphy), dev,
bssid, req_ie, req_ie_len,
- resp_ie, resp_ie_len, GFP_KERNEL);
- else
- nl80211_send_connect_result(wiphy_to_dev(wdev->wiphy), dev,
- bssid, req_ie, req_ie_len,
- resp_ie, resp_ie_len,
- status, GFP_KERNEL);
+ resp_ie, resp_ie_len,
+ status, GFP_KERNEL);
#ifdef CONFIG_WIRELESS_EXT
if (wextev) {
@@ -392,13 +390,6 @@ void __cfg80211_connect_result(struct ne
wdev->current_bss = NULL;
}
- if (status == WLAN_STATUS_SUCCESS &&
- wdev->sme_state == CFG80211_SME_IDLE)
- goto success;
-
- if (wdev->sme_state != CFG80211_SME_CONNECTING)
- return;
-
if (wdev->conn)
wdev->conn->state = CFG80211_CONN_IDLE;
@@ -412,7 +403,6 @@ void __cfg80211_connect_result(struct ne
return;
}
- success:
if (!bss)
bss = cfg80211_get_bss(wdev->wiphy, NULL, bssid,
wdev->ssid, wdev->ssid_len,
^ permalink raw reply
* question about ieee80211_tx.c (fwd)
From: Julia Lawall @ 2009-08-17 8:03 UTC (permalink / raw)
To: linux-wireless; +Cc: gregkh
The files ieee80211_tx.c in the directories
drivers/staging/rtl8192su/ieee80211 and drivers/staging/rtl8192e/ieee80211
both contain the following code in the function
ieee80211_query_protectionmode:
if (ieee->mode == IW_MODE_MASTER)
goto NO_PROTECTION;
Elsewhere in these files when there is a comparison against an IW_MODE
value, the field that is compared is iw_mode. Should that be the case
here as well?
thanks,
julia
^ permalink raw reply
* Re: [PATCH] cfg80211: set SME state machine correctly for roam event
From: Johannes Berg @ 2009-08-17 7:23 UTC (permalink / raw)
To: Zhu Yi; +Cc: linville@tuxdriver.com, linux-wireless@vger.kernel.org
In-Reply-To: <1250476527.9651.21.camel@debian>
[-- Attachment #1: Type: text/plain, Size: 1290 bytes --]
On Mon, 2009-08-17 at 10:35 +0800, Zhu Yi wrote:
> Yes, the iwmc3200wifi device sends special disconnect and reassoc events
> for roaming. But since we know we'll be reassociated shortly, we don't
> propagate this special disconnect event outside (to kernel SME and
> userspace). I agree we should use cfg80211_roamed() to indicate a real
> roam event. But sometimes the device reassociated to the same BSSID. Do
> you think the driver should simply ignore this event or still call
> cfg80211_connect_result() as well?
You probably can't just ignore it since it might require re-doing WPA
handshake, so I think I'd just send a "roamed to the same" event.
> Continue with the above case, in my current implementation, I call
> cfg80211_connect_result(). Then I find the SME enters a weird state
> (CFG80211_SME_CONNECTED while wdev->current_bss is NULL). So I think if
> we don't allow cfg80211_connect_result() to be called while
> CFG80211_SME_CONNECTED, let's put a big WARN_ON at the beginning of
> __cfg80211_connect_result(). The current code seems allow this case
> (i.e. send some roam event), thus I'm confused.
Ok, I'll take a look. There probably was a reason that's somewhat
related to the cfg80211 SME, but it must be possible to change.
johannes
[-- Attachment #2: This is a digitally signed message part --]
[-- Type: application/pgp-signature, Size: 801 bytes --]
^ permalink raw reply
* [PATCH V2] nl80211 connect API support
From: Zhu Yi @ 2009-08-17 6:04 UTC (permalink / raw)
To: j; +Cc: hostap, linux-wireless, Zhu Yi, Johannes Berg, Samuel Ortiz
nl80211 driver connect API support.
Cc: Johannes Berg <johannes@sipsolutions.net>
Cc: Samuel Ortiz <sameo@linux.intel.com>
Signed-off-by: Zhu Yi <yi.zhu@intel.com>
---
V2: Use auth/assoc as the default operations if they are supported.
diff --git a/src/common/ieee802_11_defs.h b/src/common/ieee802_11_defs.h
index b4c804e..e1bd487 100644
--- a/src/common/ieee802_11_defs.h
+++ b/src/common/ieee802_11_defs.h
@@ -679,4 +679,19 @@ enum {
#define VENDOR_HT_CAPAB_OUI_TYPE 0x33 /* 00-90-4c:0x33 */
+/* cipher suite selectors */
+#define WLAN_CIPHER_SUITE_USE_GROUP 0x000FAC00
+#define WLAN_CIPHER_SUITE_WEP40 0x000FAC01
+#define WLAN_CIPHER_SUITE_TKIP 0x000FAC02
+/* reserved: 0x000FAC03 */
+#define WLAN_CIPHER_SUITE_CCMP 0x000FAC04
+#define WLAN_CIPHER_SUITE_WEP104 0x000FAC05
+#define WLAN_CIPHER_SUITE_AES_CMAC 0x000FAC06
+
+/* AKM suite selectors */
+#define WLAN_AKM_SUITE_8021X 0x000FAC01
+#define WLAN_AKM_SUITE_PSK 0x000FAC02
+
+#define WLAN_MAX_KEY_LEN 32
+
#endif /* IEEE802_11_DEFS_H */
diff --git a/src/common/nl80211_copy.h b/src/common/nl80211_copy.h
index dbea93b..c019a16 100644
--- a/src/common/nl80211_copy.h
+++ b/src/common/nl80211_copy.h
@@ -310,6 +310,14 @@ enum nl80211_commands {
NL80211_CMD_JOIN_IBSS,
NL80211_CMD_LEAVE_IBSS,
+ NL80211_CMD_TESTMODE,
+
+ NL80211_CMD_CONNECT,
+ NL80211_CMD_ROAM,
+ NL80211_CMD_DISCONNECT,
+
+ NL80211_CMD_SET_WIPHY_NETNS,
+
/* add new commands above here */
/* used to define NL80211_CMD_MAX below */
@@ -619,6 +627,28 @@ enum nl80211_attrs {
NL80211_ATTR_CONTROL_PORT,
+ NL80211_ATTR_TESTDATA,
+
+ NL80211_ATTR_PRIVACY,
+
+ NL80211_ATTR_DISCONNECTED_BY_AP,
+ NL80211_ATTR_STATUS_CODE,
+
+ NL80211_ATTR_CIPHER_SUITES_PAIRWISE,
+ NL80211_ATTR_CIPHER_SUITE_GROUP,
+ NL80211_ATTR_WPA_VERSIONS,
+ NL80211_ATTR_AKM_SUITES,
+
+ NL80211_ATTR_REQ_IE,
+ NL80211_ATTR_RESP_IE,
+
+ NL80211_ATTR_PREV_BSSID,
+
+ NL80211_ATTR_KEY,
+ NL80211_ATTR_KEYS,
+
+ NL80211_ATTR_PID,
+
/* add attributes here, update the policy in nl80211.c */
__NL80211_ATTR_AFTER_LAST,
@@ -1224,4 +1254,39 @@ enum nl80211_mfp {
NL80211_MFP_REQUIRED,
};
+enum nl80211_wpa_versions {
+ NL80211_WPA_VERSION_1 = 1 << 0,
+ NL80211_WPA_VERSION_2 = 1 << 1,
+};
+
+/**
+ * enum nl80211_key_attributes - key attributes
+ * @__NL80211_KEY_INVALID: invalid
+ * @NL80211_KEY_DATA: (temporal) key data; for TKIP this consists of
+ * 16 bytes encryption key followed by 8 bytes each for TX and RX MIC
+ * keys
+ * @NL80211_KEY_IDX: key ID (u8, 0-3)
+ * @NL80211_KEY_CIPHER: key cipher suite (u32, as defined by IEEE 802.11
+ * section 7.3.2.25.1, e.g. 0x000FAC04)
+ * @NL80211_KEY_SEQ: transmit key sequence number (IV/PN) for TKIP and
+ * CCMP keys, each six bytes in little endian
+ * @NL80211_KEY_DEFAULT: flag indicating default key
+ * @NL80211_KEY_DEFAULT_MGMT: flag indicating default management key
+ * @__NL80211_KEY_AFTER_LAST: internal
+ * @NL80211_KEY_MAX: highest key attribute
+ */
+enum nl80211_key_attributes {
+ __NL80211_KEY_INVALID,
+ NL80211_KEY_DATA,
+ NL80211_KEY_IDX,
+ NL80211_KEY_CIPHER,
+ NL80211_KEY_SEQ,
+ NL80211_KEY_DEFAULT,
+ NL80211_KEY_DEFAULT_MGMT,
+
+ /* keep last */
+ __NL80211_KEY_AFTER_LAST,
+ NL80211_KEY_MAX = __NL80211_KEY_AFTER_LAST - 1
+};
+
#endif /* __LINUX_NL80211_H */
diff --git a/src/drivers/driver.h b/src/drivers/driver.h
index 2ae5b1a..fcb602b 100644
--- a/src/drivers/driver.h
+++ b/src/drivers/driver.h
@@ -441,9 +441,11 @@ struct wpa_driver_capa {
#define WPA_DRIVER_FLAGS_WIRED 0x00000010
/* Driver provides separate commands for authentication and association (SME in
* wpa_supplicant). */
-#define WPA_DRIVER_FLAGS_SME 0x00000020
+#define WPA_DRIVER_FLAGS_SME_AUTH 0x00000020
/* Driver supports AP mode */
#define WPA_DRIVER_FLAGS_AP 0x00000040
+/* Driver supports connect API */
+#define WPA_DRIVER_FLAGS_SME_CONNECT 0x00000080
unsigned int flags;
int max_scan_ssids;
@@ -1333,6 +1335,21 @@ struct wpa_driver_ops {
* Returns: 0 on success, -1 on failure
*/
int (*set_supp_port)(void *priv, int authorized);
+
+ /**
+ * connect - Request driver to connect
+ * @priv: private driver interface data
+ * @params: connect parameters
+ * Returns: 0 on success, -1 on failure
+ *
+ * This is an optional function that can be used with drivers that
+ * support connect (both authentication and association) API. If
+ * driver SME is not supported (both connect and authenticate are
+ * not implemented), associate() function is expected to take care
+ * of IEEE 802.11 authentication and association, too.
+ */
+ int (*connect)(void *priv, struct wpa_driver_associate_params *params);
+ int (*disconnect)(void *priv, u8 *addr, int reason_code);
};
/**
diff --git a/src/drivers/driver_nl80211.c b/src/drivers/driver_nl80211.c
index 9b2bf7c..c032ddc 100644
--- a/src/drivers/driver_nl80211.c
+++ b/src/drivers/driver_nl80211.c
@@ -739,6 +739,40 @@ static void mlme_event_assoc(struct wpa_driver_nl80211_data *drv,
wpa_supplicant_event(drv->ctx, EVENT_ASSOC, &event);
}
+static void mlme_event_connect(struct wpa_driver_nl80211_data *drv,
+ enum nl80211_commands cmd, struct nlattr *status,
+ struct nlattr *addr, struct nlattr *req_ie,
+ struct nlattr *resp_ie)
+{
+ union wpa_event_data event;
+
+ os_memset(&event, 0, sizeof(event));
+ if (cmd == NL80211_CMD_CONNECT &&
+ nla_get_u16(status) != WLAN_STATUS_SUCCESS) {
+ if (resp_ie) {
+ event.assoc_reject.resp_ies = nla_data(resp_ie);
+ event.assoc_reject.resp_ies_len = nla_len(resp_ie);
+ }
+ event.assoc_reject.status_code = nla_get_u16(status);
+ wpa_supplicant_event(drv->ctx, EVENT_ASSOC_REJECT, &event);
+ return;
+ }
+
+ drv->associated = 1;
+ if (addr)
+ os_memcpy(drv->bssid, nla_data(addr), ETH_ALEN);
+
+ if (req_ie) {
+ event.assoc_info.req_ies = nla_data(req_ie);
+ event.assoc_info.req_ies_len = nla_len(req_ie);
+ }
+ if (resp_ie) {
+ event.assoc_info.resp_ies = nla_data(resp_ie);
+ event.assoc_info.resp_ies_len = nla_len(resp_ie);
+ }
+
+ wpa_supplicant_event(drv->ctx, EVENT_ASSOC, &event);
+}
static void mlme_timeout_event(struct wpa_driver_nl80211_data *drv,
enum nl80211_commands cmd, struct nlattr *addr)
@@ -895,6 +929,17 @@ static int process_event(struct nl_msg *msg, void *arg)
mlme_event(drv, gnlh->cmd, tb[NL80211_ATTR_FRAME],
tb[NL80211_ATTR_MAC], tb[NL80211_ATTR_TIMED_OUT]);
break;
+ case NL80211_CMD_CONNECT:
+ case NL80211_CMD_ROAM:
+ mlme_event_connect(drv, gnlh->cmd, tb[NL80211_ATTR_STATUS_CODE],
+ tb[NL80211_ATTR_MAC],
+ tb[NL80211_ATTR_REQ_IE],
+ tb[NL80211_ATTR_RESP_IE]);
+ break;
+ case NL80211_CMD_DISCONNECT:
+ drv->associated = 0;
+ wpa_supplicant_event(drv->ctx, EVENT_DISASSOC, NULL);
+ break;
#endif /* HOSTAPD */
case NL80211_CMD_MICHAEL_MIC_FAILURE:
mlme_event_michael_mic_failure(drv, tb);
@@ -1003,6 +1048,8 @@ nla_put_failure:
struct wiphy_info_data {
int max_scan_ssids;
int ap_supported;
+ int auth_supported;
+ int connect_supported;
};
@@ -1031,6 +1078,19 @@ static int wiphy_info_handler(struct nl_msg *msg, void *arg)
}
}
+ if (tb[NL80211_ATTR_SUPPORTED_COMMANDS]) {
+ struct nlattr *nl_cmd;
+ int i;
+
+ nla_for_each_nested(nl_cmd,
+ tb[NL80211_ATTR_SUPPORTED_COMMANDS], i) {
+ if (nla_get_u32(nl_cmd) == NL80211_CMD_AUTHENTICATE)
+ info->auth_supported = 1;
+ if (nla_get_u32(nl_cmd) == NL80211_CMD_CONNECT)
+ info->connect_supported = 1;
+ }
+ }
+
return NL_SKIP;
}
@@ -1078,6 +1138,12 @@ static void wpa_driver_nl80211_capa(struct wpa_driver_nl80211_data *drv)
drv->capa.max_scan_ssids = info.max_scan_ssids;
if (info.ap_supported)
drv->capa.flags |= WPA_DRIVER_FLAGS_AP;
+
+ if (info.auth_supported)
+ drv->capa.flags |= WPA_DRIVER_FLAGS_SME_AUTH;
+
+ if (info.connect_supported)
+ drv->capa.flags |= WPA_DRIVER_FLAGS_SME_CONNECT;
}
#endif /* HOSTAPD */
@@ -1227,8 +1293,6 @@ static void * wpa_driver_nl80211_init(void *ctx, const char *ifname)
return NULL;
}
- drv->capa.flags |= WPA_DRIVER_FLAGS_SME;
-
drv->ioctl_sock = socket(PF_INET, SOCK_DGRAM, 0);
if (drv->ioctl_sock < 0) {
perror("socket(PF_INET,SOCK_DGRAM)");
@@ -1658,19 +1722,22 @@ static int nl_set_encr(int ifindex, struct wpa_driver_nl80211_data *drv,
case WPA_ALG_WEP:
if (key_len == 5)
NLA_PUT_U32(msg, NL80211_ATTR_KEY_CIPHER,
- 0x000FAC01);
+ WLAN_CIPHER_SUITE_WEP40);
else
NLA_PUT_U32(msg, NL80211_ATTR_KEY_CIPHER,
- 0x000FAC05);
+ WLAN_CIPHER_SUITE_WEP104);
break;
case WPA_ALG_TKIP:
- NLA_PUT_U32(msg, NL80211_ATTR_KEY_CIPHER, 0x000FAC02);
+ NLA_PUT_U32(msg, NL80211_ATTR_KEY_CIPHER,
+ WLAN_CIPHER_SUITE_TKIP);
break;
case WPA_ALG_CCMP:
- NLA_PUT_U32(msg, NL80211_ATTR_KEY_CIPHER, 0x000FAC04);
+ NLA_PUT_U32(msg, NL80211_ATTR_KEY_CIPHER,
+ WLAN_CIPHER_SUITE_CCMP);
break;
case WPA_ALG_IGTK:
- NLA_PUT_U32(msg, NL80211_ATTR_KEY_CIPHER, 0x000FAC06);
+ NLA_PUT_U32(msg, NL80211_ATTR_KEY_CIPHER,
+ WLAN_CIPHER_SUITE_AES_CMAC);
break;
default:
wpa_printf(MSG_ERROR, "%s: Unsupported encryption "
@@ -1737,6 +1804,60 @@ nla_put_failure:
#ifndef HOSTAPD
+static int nl80211_set_conn_keys(void *priv,
+ struct wpa_driver_associate_params *params,
+ struct nl_msg *msg)
+{
+ int i, privacy = 0;
+ struct nlattr *nl_keys, *nl_key;
+
+ for (i = 0; i < 4; i++) {
+ if (!params->wep_key[i])
+ continue;
+ privacy = 1;
+ break;
+ }
+ if (!privacy)
+ return 0;
+
+ NLA_PUT_FLAG(msg, NL80211_ATTR_PRIVACY);
+
+ nl_keys = nla_nest_start(msg, NL80211_ATTR_KEYS);
+ if (!nl_keys)
+ goto nla_put_failure;
+
+ for (i = 0; i < 4; i++) {
+ if (!params->wep_key[i])
+ continue;
+
+ nl_key = nla_nest_start(msg, i);
+ if (!nl_key)
+ goto nla_put_failure;
+
+ NLA_PUT(msg, NL80211_KEY_DATA, params->wep_key_len[i],
+ params->wep_key[i]);
+ if (params->wep_key_len[i] == 5)
+ NLA_PUT_U32(msg, NL80211_KEY_CIPHER,
+ WLAN_CIPHER_SUITE_WEP40);
+ else
+ NLA_PUT_U32(msg, NL80211_KEY_CIPHER,
+ WLAN_CIPHER_SUITE_WEP104);
+
+ NLA_PUT_U8(msg, NL80211_KEY_IDX, i);
+
+ if (i == params->wep_tx_keyidx)
+ NLA_PUT_FLAG(msg, NL80211_KEY_DEFAULT);
+
+ nla_nest_end(msg, nl_key);
+ }
+ nla_nest_end(msg, nl_keys);
+
+ return 0;
+
+nla_put_failure:
+ return -ENOBUFS;
+}
+
static int wpa_driver_nl80211_set_key(void *priv, wpa_alg alg,
const u8 *addr, int key_idx,
int set_tx, const u8 *seq,
@@ -1883,6 +2004,164 @@ nla_put_failure:
return ret;
}
+static int wpa_driver_nl80211_connect(
+ void *priv, struct wpa_driver_associate_params *params)
+{
+ struct wpa_driver_nl80211_data *drv = priv;
+ struct nl_msg *msg;
+ enum nl80211_auth_type type;
+ int ret = 0;
+
+ if (!(drv->capa.flags & WPA_DRIVER_FLAGS_SME_CONNECT))
+ return -EOPNOTSUPP;
+
+ msg = nlmsg_alloc();
+ if (!msg)
+ return -1;
+
+ wpa_printf(MSG_DEBUG, "nl80211: Connect (ifindex=%d)", drv->ifindex);
+ genlmsg_put(msg, 0, 0, genl_family_get_id(drv->nl80211), 0, 0,
+ NL80211_CMD_CONNECT, 0);
+
+ NLA_PUT_U32(msg, NL80211_ATTR_IFINDEX, drv->ifindex);
+ if (params->bssid) {
+ wpa_printf(MSG_DEBUG, " * bssid=" MACSTR,
+ MAC2STR(params->bssid));
+ NLA_PUT(msg, NL80211_ATTR_MAC, ETH_ALEN, params->bssid);
+ }
+ if (params->freq) {
+ wpa_printf(MSG_DEBUG, " * freq=%d", params->freq);
+ NLA_PUT_U32(msg, NL80211_ATTR_WIPHY_FREQ, params->freq);
+ }
+ if (params->ssid) {
+ wpa_hexdump_ascii(MSG_DEBUG, " * SSID",
+ params->ssid, params->ssid_len);
+ NLA_PUT(msg, NL80211_ATTR_SSID, params->ssid_len,
+ params->ssid);
+ if (params->ssid_len > sizeof(drv->ssid))
+ goto nla_put_failure;
+ os_memcpy(drv->ssid, params->ssid, params->ssid_len);
+ drv->ssid_len = params->ssid_len;
+ }
+ wpa_hexdump(MSG_DEBUG, " * IEs", params->wpa_ie, params->wpa_ie_len);
+ if (params->wpa_ie)
+ NLA_PUT(msg, NL80211_ATTR_IE, params->wpa_ie_len,
+ params->wpa_ie);
+
+ if (params->auth_alg & AUTH_ALG_OPEN_SYSTEM)
+ type = NL80211_AUTHTYPE_OPEN_SYSTEM;
+ else if (params->auth_alg & AUTH_ALG_SHARED_KEY)
+ type = NL80211_AUTHTYPE_SHARED_KEY;
+ else if (params->auth_alg & AUTH_ALG_LEAP)
+ type = NL80211_AUTHTYPE_NETWORK_EAP;
+ else if (params->auth_alg & AUTH_ALG_FT)
+ type = NL80211_AUTHTYPE_FT;
+ else
+ goto nla_put_failure;
+
+ wpa_printf(MSG_DEBUG, " * Auth Type %d", type);
+ NLA_PUT_U32(msg, NL80211_ATTR_AUTH_TYPE, type);
+
+ if (params->wpa_ie && params->wpa_ie_len) {
+ enum nl80211_wpa_versions ver;
+
+ if (params->wpa_ie[0] == WLAN_EID_RSN)
+ ver = NL80211_WPA_VERSION_2;
+ else
+ ver = NL80211_WPA_VERSION_1;
+
+ wpa_printf(MSG_DEBUG, " * WPA Version %d", ver);
+ NLA_PUT_U32(msg, NL80211_ATTR_WPA_VERSIONS, ver);
+ }
+
+ if (params->pairwise_suite != CIPHER_NONE) {
+ int cipher = IW_AUTH_CIPHER_NONE;
+
+ switch (params->pairwise_suite) {
+ case CIPHER_WEP40:
+ cipher = WLAN_CIPHER_SUITE_WEP40;
+ break;
+ case CIPHER_WEP104:
+ cipher = WLAN_CIPHER_SUITE_WEP104;
+ break;
+ case CIPHER_CCMP:
+ cipher = WLAN_CIPHER_SUITE_CCMP;
+ break;
+ case CIPHER_TKIP:
+ default:
+ cipher = WLAN_CIPHER_SUITE_TKIP;
+ break;
+ }
+ NLA_PUT_U32(msg, NL80211_ATTR_CIPHER_SUITES_PAIRWISE, cipher);
+ }
+
+ if (params->group_suite != CIPHER_NONE) {
+ int cipher = IW_AUTH_CIPHER_NONE;
+
+ switch (params->group_suite) {
+ case CIPHER_WEP40:
+ cipher = WLAN_CIPHER_SUITE_WEP40;
+ break;
+ case CIPHER_WEP104:
+ cipher = WLAN_CIPHER_SUITE_WEP104;
+ break;
+ case CIPHER_CCMP:
+ cipher = WLAN_CIPHER_SUITE_CCMP;
+ break;
+ case CIPHER_TKIP:
+ default:
+ cipher = WLAN_CIPHER_SUITE_TKIP;
+ break;
+ }
+ NLA_PUT_U32(msg, NL80211_ATTR_CIPHER_SUITE_GROUP, cipher);
+ }
+
+ if (params->key_mgmt_suite == KEY_MGMT_802_1X ||
+ params->key_mgmt_suite == KEY_MGMT_PSK) {
+ int mgmt = WLAN_AKM_SUITE_PSK;
+
+ switch (params->key_mgmt_suite) {
+ case KEY_MGMT_802_1X:
+ mgmt = WLAN_AKM_SUITE_8021X;
+ break;
+ case KEY_MGMT_PSK:
+ default:
+ mgmt = WLAN_AKM_SUITE_PSK;
+ break;
+ }
+ NLA_PUT_U32(msg, NL80211_ATTR_AKM_SUITES, mgmt);
+ }
+
+ ret = nl80211_set_conn_keys(drv, params, msg);
+ if (ret)
+ goto nla_put_failure;
+
+ ret = send_and_recv_msgs(drv, msg, NULL, NULL);
+ msg = NULL;
+ if (ret) {
+ wpa_printf(MSG_DEBUG, "nl80211: MLME connect failed: ret=%d "
+ "(%s)", ret, strerror(-ret));
+ goto nla_put_failure;
+ }
+ ret = 0;
+ wpa_printf(MSG_DEBUG, "nl80211: Connect request send successfully");
+
+nla_put_failure:
+ nlmsg_free(msg);
+ return ret;
+
+}
+
+static int wpa_driver_nl80211_disconnect(void *priv, u8 *addr, int reason_code)
+{
+ struct wpa_driver_nl80211_data *drv = priv;
+
+ wpa_printf(MSG_DEBUG, "%s", __func__);
+ drv->associated = 0;
+ return wpa_driver_nl80211_mlme(drv, addr, NL80211_CMD_DISCONNECT,
+ reason_code);
+}
+
#endif /* HOSTAPD */
@@ -4060,6 +4339,8 @@ const struct wpa_driver_ops wpa_driver_nl80211_ops = {
.get_capa = wpa_driver_nl80211_get_capa,
.set_operstate = wpa_driver_nl80211_set_operstate,
.set_supp_port = wpa_driver_nl80211_set_supp_port,
+ .connect = wpa_driver_nl80211_connect,
+ .disconnect = wpa_driver_nl80211_disconnect,
#endif /* HOSTAPD */
.set_country = wpa_driver_nl80211_set_country,
.set_mode = wpa_driver_nl80211_set_mode,
diff --git a/wpa_supplicant/driver_i.h b/wpa_supplicant/driver_i.h
index 4cb5372..e5a8ef4 100644
--- a/wpa_supplicant/driver_i.h
+++ b/wpa_supplicant/driver_i.h
@@ -448,4 +448,22 @@ static inline int wpa_drv_set_supp_port(struct wpa_supplicant *wpa_s,
return 0;
}
+static inline int wpa_drv_connect(struct wpa_supplicant *wpa_s,
+ struct wpa_driver_associate_params *params)
+{
+ if (wpa_s->driver->connect)
+ return wpa_s->driver->connect(wpa_s->drv_priv, params);
+
+ return -1;
+}
+
+static inline int wpa_drv_disconnect(struct wpa_supplicant *wpa_s, u8 *addr,
+ int reason_code)
+{
+ if (wpa_s->driver->disconnect)
+ return wpa_s->driver->disconnect(wpa_s->drv_priv, addr,
+ reason_code);
+ return -1;
+}
+
#endif /* DRIVER_I_H */
diff --git a/wpa_supplicant/sme.c b/wpa_supplicant/sme.c
index 0d729ef..426afd2 100644
--- a/wpa_supplicant/sme.c
+++ b/wpa_supplicant/sme.c
@@ -238,6 +238,175 @@ void sme_authenticate(struct wpa_supplicant *wpa_s,
*/
}
+void sme_connect(struct wpa_supplicant *wpa_s, struct wpa_scan_res *bss,
+ struct wpa_ssid *ssid)
+{
+ struct wpa_driver_associate_params params;
+ const u8 *ie;
+ int i;
+
+ if (bss == NULL) {
+ wpa_printf(MSG_ERROR, "SME: No scan result available for the "
+ "network");
+ return;
+ }
+
+ os_memset(¶ms, 0, sizeof(params));
+ wpa_s->reassociate = 0;
+
+ params.freq = bss->freq;
+ params.bssid = bss->bssid;
+ ie = wpa_scan_get_ie(bss, WLAN_EID_SSID);
+ if (ie == NULL) {
+ wpa_printf(MSG_ERROR, "SME: SSID not available for the BSS");
+ return;
+ }
+ params.ssid = ie + 2;
+ params.ssid_len = ie[1];
+
+ wpa_s->sme.freq = params.freq;
+ os_memcpy(wpa_s->sme.ssid, params.ssid, params.ssid_len);
+ wpa_s->sme.ssid_len = params.ssid_len;
+
+ params.auth_alg = AUTH_ALG_OPEN_SYSTEM;
+#ifdef IEEE8021X_EAPOL
+ if (ssid->key_mgmt & WPA_KEY_MGMT_IEEE8021X_NO_WPA) {
+ if (ssid->leap) {
+ if (ssid->non_leap == 0)
+ params.auth_alg = AUTH_ALG_LEAP;
+ else
+ params.auth_alg |= AUTH_ALG_LEAP;
+ }
+ }
+#endif /* IEEE8021X_EAPOL */
+ wpa_printf(MSG_DEBUG, "Automatic auth_alg selection: 0x%x",
+ params.auth_alg);
+ if (ssid->auth_alg) {
+ params.auth_alg = 0;
+ if (ssid->auth_alg & WPA_AUTH_ALG_OPEN)
+ params.auth_alg |= AUTH_ALG_OPEN_SYSTEM;
+ if (ssid->auth_alg & WPA_AUTH_ALG_SHARED)
+ params.auth_alg |= AUTH_ALG_SHARED_KEY;
+ if (ssid->auth_alg & WPA_AUTH_ALG_LEAP)
+ params.auth_alg |= AUTH_ALG_LEAP;
+ wpa_printf(MSG_DEBUG, "Overriding auth_alg selection: 0x%x",
+ params.auth_alg);
+ }
+
+ for (i = 0; i < NUM_WEP_KEYS; i++) {
+ if (ssid->wep_key_len[i])
+ params.wep_key[i] = ssid->wep_key[i];
+ params.wep_key_len[i] = ssid->wep_key_len[i];
+ }
+ params.wep_tx_keyidx = ssid->wep_tx_keyidx;
+
+ os_memset(wpa_s->bssid, 0, ETH_ALEN);
+ os_memcpy(wpa_s->pending_bssid, bss->bssid, ETH_ALEN);
+
+ if (bss && (wpa_scan_get_vendor_ie(bss, WPA_IE_VENDOR_TYPE) ||
+ wpa_scan_get_ie(bss, WLAN_EID_RSN)) &&
+ (ssid->key_mgmt & (WPA_KEY_MGMT_IEEE8021X | WPA_KEY_MGMT_PSK |
+ WPA_KEY_MGMT_FT_IEEE8021X |
+ WPA_KEY_MGMT_FT_PSK |
+ WPA_KEY_MGMT_IEEE8021X_SHA256 |
+ WPA_KEY_MGMT_PSK_SHA256))) {
+ int try_opportunistic;
+ try_opportunistic = ssid->proactive_key_caching &&
+ (ssid->proto & WPA_PROTO_RSN);
+ if (pmksa_cache_set_current(wpa_s->wpa, NULL, bss->bssid,
+ wpa_s->current_ssid,
+ try_opportunistic) == 0)
+ eapol_sm_notify_pmkid_attempt(wpa_s->eapol, 1);
+ wpa_s->sme.assoc_req_ie_len = sizeof(wpa_s->sme.assoc_req_ie);
+ if (wpa_supplicant_set_suites(wpa_s, bss, ssid,
+ wpa_s->sme.assoc_req_ie,
+ &wpa_s->sme.assoc_req_ie_len)) {
+ wpa_printf(MSG_WARNING, "SME: Failed to set WPA key "
+ "management and encryption suites");
+ return;
+ }
+ } else if (ssid->key_mgmt &
+ (WPA_KEY_MGMT_PSK | WPA_KEY_MGMT_IEEE8021X |
+ WPA_KEY_MGMT_WPA_NONE | WPA_KEY_MGMT_FT_PSK |
+ WPA_KEY_MGMT_FT_IEEE8021X | WPA_KEY_MGMT_PSK_SHA256 |
+ WPA_KEY_MGMT_IEEE8021X_SHA256)) {
+ wpa_s->sme.assoc_req_ie_len = sizeof(wpa_s->sme.assoc_req_ie);
+ if (wpa_supplicant_set_suites(wpa_s, NULL, ssid,
+ wpa_s->sme.assoc_req_ie,
+ &wpa_s->sme.assoc_req_ie_len)) {
+ wpa_printf(MSG_WARNING, "SME: Failed to set WPA key "
+ "management and encryption suites (no scan "
+ "results)");
+ return;
+ }
+#ifdef CONFIG_WPS
+ } else if (ssid->key_mgmt & WPA_KEY_MGMT_WPS) {
+ struct wpabuf *wps_ie;
+ wps_ie = wps_build_assoc_req_ie(wpas_wps_get_req_type(ssid));
+ if (wps_ie && wpabuf_len(wps_ie) <=
+ sizeof(wpa_s->sme.assoc_req_ie)) {
+ wpa_s->sme.assoc_req_ie_len = wpabuf_len(wps_ie);
+ os_memcpy(wpa_s->sme.assoc_req_ie, wpabuf_head(wps_ie),
+ wpa_s->sme.assoc_req_ie_len);
+ } else
+ wpa_s->sme.assoc_req_ie_len = 0;
+ wpabuf_free(wps_ie);
+ wpa_supplicant_set_non_wpa_policy(wpa_s, ssid);
+#endif /* CONFIG_WPS */
+ } else {
+ wpa_supplicant_set_non_wpa_policy(wpa_s, ssid);
+ wpa_s->sme.assoc_req_ie_len = 0;
+ }
+
+#ifdef CONFIG_IEEE80211W
+ switch (ssid->ieee80211w) {
+ case NO_IEEE80211W:
+ wpa_s->sme.mfp = NO_MGMT_FRAME_PROTECTION;
+ break;
+ case IEEE80211W_OPTIONAL:
+ wpa_s->sme.mfp = MGMT_FRAME_PROTECTION_OPTIONAL;
+ break;
+ case IEEE80211W_REQUIRED:
+ wpa_s->sme.mfp = MGMT_FRAME_PROTECTION_REQUIRED;
+ break;
+ }
+ if (ssid->ieee80211w != NO_IEEE80211W && bss) {
+ const u8 *rsn = wpa_scan_get_ie(bss, WLAN_EID_RSN);
+ struct wpa_ie_data _ie;
+ if (rsn && wpa_parse_wpa_ie(rsn, 2 + rsn[1], &_ie) == 0 &&
+ _ie.capabilities &
+ (WPA_CAPABILITY_MFPC | WPA_CAPABILITY_MFPR)) {
+ wpa_printf(MSG_DEBUG, "WPA: Selected AP supports MFP: "
+ "require MFP");
+ wpa_s->sme.mfp = MGMT_FRAME_PROTECTION_REQUIRED;
+ }
+ }
+#endif /* CONFIG_IEEE80211W */
+
+ wpa_supplicant_cancel_scan(wpa_s);
+
+ wpa_msg(wpa_s, MSG_INFO, "Trying to connect with " MACSTR
+ " (SSID='%s' freq=%d MHz)", MAC2STR(params.bssid),
+ wpa_ssid_txt(params.ssid, params.ssid_len), params.freq);
+
+ wpa_clear_keys(wpa_s, bss->bssid);
+ wpa_supplicant_set_state(wpa_s, WPA_ASSOCIATING);
+ wpa_s->current_ssid = ssid;
+ wpa_supplicant_rsn_supp_set_config(wpa_s, wpa_s->current_ssid);
+ wpa_supplicant_initiate_eapol(wpa_s);
+
+ params.key_mgmt_suite = key_mgmt2driver(wpa_s->key_mgmt);
+ params.wpa_ie = wpa_s->sme.assoc_req_ie;
+ params.wpa_ie_len = wpa_s->sme.assoc_req_ie_len;
+ params.pairwise_suite = cipher_suite2driver(wpa_s->pairwise_cipher);
+ params.group_suite = cipher_suite2driver(wpa_s->group_cipher);
+
+ if (wpa_drv_connect(wpa_s, ¶ms) < 0) {
+ wpa_msg(wpa_s, MSG_INFO, "Connect to the driver failed");
+ return;
+ }
+}
+
void sme_event_auth(struct wpa_supplicant *wpa_s, union wpa_event_data *data)
{
diff --git a/wpa_supplicant/sme.h b/wpa_supplicant/sme.h
index 2780041..fd5ea9c 100644
--- a/wpa_supplicant/sme.h
+++ b/wpa_supplicant/sme.h
@@ -19,6 +19,8 @@
void sme_authenticate(struct wpa_supplicant *wpa_s,
struct wpa_scan_res *bss, struct wpa_ssid *ssid);
+void sme_connect(struct wpa_supplicant *wpa_s, struct wpa_scan_res *bss,
+ struct wpa_ssid *ssid);
void sme_event_auth(struct wpa_supplicant *wpa_s, union wpa_event_data *data);
int sme_update_ft_ies(struct wpa_supplicant *wpa_s, const u8 *md,
const u8 *ies, size_t ies_len);
@@ -37,6 +39,12 @@ static inline void sme_authenticate(struct wpa_supplicant *wpa_s,
{
}
+static inline void sme_connect(struct wpa_supplicant *wpa_s,
+ struct wpa_scan_res *bss,
+ struct wpa_ssid *ssid)
+{
+}
+
static inline void sme_event_auth(struct wpa_supplicant *wpa_s,
union wpa_event_data *data)
{
diff --git a/wpa_supplicant/wpa_supplicant.c b/wpa_supplicant/wpa_supplicant.c
index f1f929a..4282b14 100644
--- a/wpa_supplicant/wpa_supplicant.c
+++ b/wpa_supplicant/wpa_supplicant.c
@@ -640,7 +640,7 @@ static void wpa_supplicant_reconfig(int sig, void *eloop_ctx,
}
-static wpa_cipher cipher_suite2driver(int cipher)
+wpa_cipher cipher_suite2driver(int cipher)
{
switch (cipher) {
case WPA_CIPHER_NONE:
@@ -658,7 +658,7 @@ static wpa_cipher cipher_suite2driver(int cipher)
}
-static wpa_key_mgmt key_mgmt2driver(int key_mgmt)
+wpa_key_mgmt key_mgmt2driver(int key_mgmt)
{
switch (key_mgmt) {
case WPA_KEY_MGMT_NONE:
@@ -965,11 +965,16 @@ void wpa_supplicant_associate(struct wpa_supplicant *wpa_s,
return;
}
- if (wpa_s->drv_flags & WPA_DRIVER_FLAGS_SME) {
+ if (wpa_s->drv_flags & WPA_DRIVER_FLAGS_SME_AUTH) {
sme_authenticate(wpa_s, bss, ssid);
return;
}
+ if (wpa_s->drv_flags & WPA_DRIVER_FLAGS_SME_CONNECT) {
+ sme_connect(wpa_s, bss, ssid);
+ return;
+ }
+
wpa_s->reassociate = 0;
if (bss) {
#ifdef CONFIG_IEEE80211R
@@ -1303,9 +1308,12 @@ void wpa_supplicant_deauthenticate(struct wpa_supplicant *wpa_s,
if (!is_zero_ether_addr(wpa_s->bssid)) {
if (wpa_s->drv_flags & WPA_DRIVER_FLAGS_USER_SPACE_MLME)
ieee80211_sta_deauthenticate(wpa_s, reason_code);
- else
+ else if (wpa_s->drv_flags & WPA_DRIVER_FLAGS_SME_AUTH)
wpa_drv_deauthenticate(wpa_s, wpa_s->bssid,
reason_code);
+ else if (wpa_s->drv_flags & WPA_DRIVER_FLAGS_SME_CONNECT)
+ wpa_drv_disconnect(wpa_s, wpa_s->bssid, reason_code);
+
addr = wpa_s->bssid;
}
wpa_clear_keys(wpa_s, addr);
diff --git a/wpa_supplicant/wpa_supplicant_i.h b/wpa_supplicant/wpa_supplicant_i.h
index 63984d8..13896d9 100644
--- a/wpa_supplicant/wpa_supplicant_i.h
+++ b/wpa_supplicant/wpa_supplicant_i.h
@@ -392,6 +392,8 @@ int wpa_supplicant_reload_configuration(struct wpa_supplicant *wpa_s);
const char * wpa_supplicant_state_txt(int state);
int wpa_supplicant_driver_init(struct wpa_supplicant *wpa_s);
+wpa_cipher cipher_suite2driver(int cipher);
+wpa_key_mgmt key_mgmt2driver(int key_mgmt);
int wpa_supplicant_set_suites(struct wpa_supplicant *wpa_s,
struct wpa_scan_res *bss,
struct wpa_ssid *ssid,
diff --git a/wpa_supplicant/wpas_glue.c b/wpa_supplicant/wpas_glue.c
index b1f8bf8..3cfcd32 100644
--- a/wpa_supplicant/wpas_glue.c
+++ b/wpa_supplicant/wpas_glue.c
@@ -478,7 +478,7 @@ static int wpa_supplicant_update_ft_ies(void *ctx, const u8 *md,
struct wpa_supplicant *wpa_s = ctx;
if (wpa_s->drv_flags & WPA_DRIVER_FLAGS_USER_SPACE_MLME)
return ieee80211_sta_update_ft_ies(wpa_s, md, ies, ies_len);
- if (wpa_s->drv_flags & WPA_DRIVER_FLAGS_SME)
+ if (wpa_s->drv_flags & WPA_DRIVER_FLAGS_SME_AUTH)
return sme_update_ft_ies(wpa_s, md, ies, ies_len);
return wpa_drv_update_ft_ies(wpa_s, md, ies, ies_len);
}
^ permalink raw reply related
* [ANN] iw: v0.9.16
From: wireless @ 2009-08-17 3:10 UTC (permalink / raw)
To: linux-wireless
A new release of iw (v0.9.16) is available at:
http://wireless.kernel.org/download/iw/iw-0.9.16.tar.bz2
SHA1 sum: e224b6698802498569854b475ae532d41ddbd719
Here is the short log of the changes included in this
release:
Johannes Berg - 0.9.16
^ permalink raw reply
* Re: [PATCH] cfg80211: set SME state machine correctly for roam event
From: Zhu Yi @ 2009-08-17 2:35 UTC (permalink / raw)
To: Johannes Berg; +Cc: linville@tuxdriver.com, linux-wireless@vger.kernel.org
In-Reply-To: <1250261645.24924.22.camel@johannes.local>
On Fri, 2009-08-14 at 22:54 +0800, Johannes Berg wrote:
> On Fri, 2009-08-14 at 11:58 +0800, Zhu Yi wrote:
>
> > The device notifies both when it begins to roam and after the new
> > association is made. Yes, I think I missed the cfg80211_roamed call for
> > the real roam event. But there is still a reassociation path that the
> > above situation could happen (__cfg80211_connect_result is called while
> > in CFG80211_SME_CONNECTED state). Or do you think we should suppress
> > reassoc event from driver?
>
> Would that be after a disconnect event?
>
> I think that after a DISCONNECTED event the device should go to sleep
> completely and wait for userspace instructions. Otherwise we end up
> having a weird situation _again_ where userspace has no idea what the
> device is doing. I suppose if the device just keeps trying you just have
> to tell it to stop after a bit if it doesn't find a new connections.
>
> Otherwise, if you're roaming, you still get a disconnect/reassoc or
> something like that? Those together should form a ROAMED event.
Yes, the iwmc3200wifi device sends special disconnect and reassoc events
for roaming. But since we know we'll be reassociated shortly, we don't
propagate this special disconnect event outside (to kernel SME and
userspace). I agree we should use cfg80211_roamed() to indicate a real
roam event. But sometimes the device reassociated to the same BSSID. Do
you think the driver should simply ignore this event or still call
cfg80211_connect_result() as well?
> > Actually, the code in __cfg80211_connect_result() has already handled
> > the (wdev->sme_state == CFG80211_SME_CONNECTED) case. The problem is
> > wdev->current_bss is set to NULL but leaves wdev->sme_state still as
> > CFG80211_SME_CONNECTED. So I think the patch is still valid, but needs a
> > better description.
>
> I don't think I understand?
>
> Why would you ever have a connect_result() while already connected?
Continue with the above case, in my current implementation, I call
cfg80211_connect_result(). Then I find the SME enters a weird state
(CFG80211_SME_CONNECTED while wdev->current_bss is NULL). So I think if
we don't allow cfg80211_connect_result() to be called while
CFG80211_SME_CONNECTED, let's put a big WARN_ON at the beginning of
__cfg80211_connect_result(). The current code seems allow this case
(i.e. send some roam event), thus I'm confused.
Thanks,
-yi
^ permalink raw reply
* Need rc6 posted to orbit-lab
From: Philip A. Prindeville @ 2009-08-16 21:13 UTC (permalink / raw)
To: Luis R. Rodriguez; +Cc: wireless
Can you please send out an announcement when rc6 hits orbit-lab?
Thanks.
^ permalink raw reply
* Re: [PATCH v2] b43: LP-PHY: Remove BROKEN from B43_PHY_LP
From: Michael Buesch @ 2009-08-16 18:28 UTC (permalink / raw)
To: Gábor Stefanik
Cc: John Linville, Larry Finger, Mark Huijgen, Broadcom Wireless,
linux-wireless
In-Reply-To: <4A884E71.6070202@gmail.com>
On Sunday 16 August 2009 20:22:41 Gábor Stefanik wrote:
> Larry has reported success getting scan data with an LP-PHY device,
> so it's probably time to release LP-PHY support for testing.
>
> Also disable 802.11a support for now, as 802.11a currently causes
> the driver to panic on startup (NULL pointer dereference).
>
> Signed-off-by: Gábor Stefanik <netrolller.3d@gmail.com>
ack
> ---
> V2:
> -Remove "VERY" from the warning in the symbol name.
> -Remove list of known devices.
> -Don't create a separate symbol for 5GHz, just disable it in the code.
>
> drivers/net/wireless/b43/Kconfig | 14 +++++++-------
> drivers/net/wireless/b43/main.c | 2 ++
> 2 files changed, 9 insertions(+), 7 deletions(-)
>
> diff --git a/drivers/net/wireless/b43/Kconfig b/drivers/net/wireless/b43/Kconfig
> index 67f564e..237b1aa 100644
> --- a/drivers/net/wireless/b43/Kconfig
> +++ b/drivers/net/wireless/b43/Kconfig
> @@ -80,16 +80,16 @@ config B43_NPHY
> SAY N.
>
> config B43_PHY_LP
> - bool "IEEE 802.11g LP-PHY support (BROKEN)"
> - depends on B43 && EXPERIMENTAL && BROKEN
> + bool "Support for low-power (LP-PHY) devices (EXPERIMENTAL)"
> + depends on B43 && EXPERIMENTAL
> ---help---
> Support for the LP-PHY.
> - The LP-PHY is an IEEE 802.11g based PHY built into some notebooks
> - and embedded devices.
> -
> - THIS IS BROKEN AND DOES NOT WORK YET.
> + The LP-PHY is a low-power PHY built into some notebooks
> + and embedded devices. It supports 802.11a/g
> + (802.11a support is optional, and currently disabled).
>
> - SAY N.
> + This is heavily experimental, and probably will not work for you.
> + Say N unless you want to help debug the driver.
>
> # This config option automatically enables b43 LEDS support,
> # if it's possible.
> diff --git a/drivers/net/wireless/b43/main.c b/drivers/net/wireless/b43/main.c
> index 99b41ce..c5bece0 100644
> --- a/drivers/net/wireless/b43/main.c
> +++ b/drivers/net/wireless/b43/main.c
> @@ -4514,7 +4514,9 @@ static int b43_wireless_core_attach(struct b43_wldev *dev)
> have_5ghz_phy = 1;
> break;
> case B43_PHYTYPE_LP: //FIXME not always!
> +#if 0 //FIXME enabling 5GHz causes a NULL pointer dereference
> have_5ghz_phy = 1;
> +#endif
> case B43_PHYTYPE_G:
> case B43_PHYTYPE_N:
> have_2ghz_phy = 1;
--
Greetings, Michael.
^ permalink raw reply
* [PATCH v2] b43: LP-PHY: Remove BROKEN from B43_PHY_LP
From: Gábor Stefanik @ 2009-08-16 18:22 UTC (permalink / raw)
To: John Linville, Michael Buesch, Larry Finger
Cc: Mark Huijgen, Broadcom Wireless, linux-wireless
Larry has reported success getting scan data with an LP-PHY device,
so it's probably time to release LP-PHY support for testing.
Also disable 802.11a support for now, as 802.11a currently causes
the driver to panic on startup (NULL pointer dereference).
Signed-off-by: Gábor Stefanik <netrolller.3d@gmail.com>
---
V2:
-Remove "VERY" from the warning in the symbol name.
-Remove list of known devices.
-Don't create a separate symbol for 5GHz, just disable it in the code.
drivers/net/wireless/b43/Kconfig | 14 +++++++-------
drivers/net/wireless/b43/main.c | 2 ++
2 files changed, 9 insertions(+), 7 deletions(-)
diff --git a/drivers/net/wireless/b43/Kconfig b/drivers/net/wireless/b43/Kconfig
index 67f564e..237b1aa 100644
--- a/drivers/net/wireless/b43/Kconfig
+++ b/drivers/net/wireless/b43/Kconfig
@@ -80,16 +80,16 @@ config B43_NPHY
SAY N.
config B43_PHY_LP
- bool "IEEE 802.11g LP-PHY support (BROKEN)"
- depends on B43 && EXPERIMENTAL && BROKEN
+ bool "Support for low-power (LP-PHY) devices (EXPERIMENTAL)"
+ depends on B43 && EXPERIMENTAL
---help---
Support for the LP-PHY.
- The LP-PHY is an IEEE 802.11g based PHY built into some notebooks
- and embedded devices.
-
- THIS IS BROKEN AND DOES NOT WORK YET.
+ The LP-PHY is a low-power PHY built into some notebooks
+ and embedded devices. It supports 802.11a/g
+ (802.11a support is optional, and currently disabled).
- SAY N.
+ This is heavily experimental, and probably will not work for you.
+ Say N unless you want to help debug the driver.
# This config option automatically enables b43 LEDS support,
# if it's possible.
diff --git a/drivers/net/wireless/b43/main.c b/drivers/net/wireless/b43/main.c
index 99b41ce..c5bece0 100644
--- a/drivers/net/wireless/b43/main.c
+++ b/drivers/net/wireless/b43/main.c
@@ -4514,7 +4514,9 @@ static int b43_wireless_core_attach(struct b43_wldev *dev)
have_5ghz_phy = 1;
break;
case B43_PHYTYPE_LP: //FIXME not always!
+#if 0 //FIXME enabling 5GHz causes a NULL pointer dereference
have_5ghz_phy = 1;
+#endif
case B43_PHYTYPE_G:
case B43_PHYTYPE_N:
have_2ghz_phy = 1;
--
1.6.2.4
^ permalink raw reply related
* Re: [PATCH] b43: LP-PHY: Update B2062 radio init with recent spec changes
From: Michael Buesch @ 2009-08-16 18:09 UTC (permalink / raw)
To: Gábor Stefanik
Cc: John Linville, Larry Finger, Mark Huijgen, Broadcom Wireless,
linux-wireless
In-Reply-To: <4A884B0D.5000808@gmail.com>
On Sunday 16 August 2009 20:08:13 Gábor Stefanik wrote:
> The spec for initializing the B2062 radio have changed recently,
> update the code to match the changes.
>
> Signed-off-by: Gábor Stefanik <netrolller.3d@gmail.com>
ack
> ---
> drivers/net/wireless/b43/phy_lp.c | 5 +++++
> 1 files changed, 5 insertions(+), 0 deletions(-)
>
> diff --git a/drivers/net/wireless/b43/phy_lp.c b/drivers/net/wireless/b43/phy_lp.c
> index 5a7b873..34b7910 100644
> --- a/drivers/net/wireless/b43/phy_lp.c
> +++ b/drivers/net/wireless/b43/phy_lp.c
> @@ -539,10 +539,15 @@ static void lpphy_2062_init(struct b43_wldev *dev)
> b43_radio_write(dev, B2062_N_TX_CTL3, 0);
> b43_radio_write(dev, B2062_N_TX_CTL4, 0);
> b43_radio_write(dev, B2062_N_TX_CTL5, 0);
> + b43_radio_write(dev, B2062_N_TX_CTL6, 0);
> b43_radio_write(dev, B2062_N_PDN_CTL0, 0x40);
> b43_radio_write(dev, B2062_N_PDN_CTL0, 0);
> b43_radio_write(dev, B2062_N_CALIB_TS, 0x10);
> b43_radio_write(dev, B2062_N_CALIB_TS, 0);
> + if (dev->phy.rev > 0) {
> + b43_radio_write(dev, B2062_S_BG_CTL1,
> + (b43_radio_read(dev, B2062_N_COMM2) >> 1) | 0x80);
> + }
> if (b43_current_band(dev->wl) == IEEE80211_BAND_2GHZ)
> b43_radio_set(dev, B2062_N_TSSI_CTL0, 0x1);
> else
--
Greetings, Michael.
^ permalink raw reply
* [PATCH] b43: LP-PHY: Update B2062 radio init with recent spec changes
From: Gábor Stefanik @ 2009-08-16 18:08 UTC (permalink / raw)
To: John Linville, Michael Buesch, Larry Finger
Cc: Mark Huijgen, Broadcom Wireless, linux-wireless
The spec for initializing the B2062 radio have changed recently,
update the code to match the changes.
Signed-off-by: Gábor Stefanik <netrolller.3d@gmail.com>
---
drivers/net/wireless/b43/phy_lp.c | 5 +++++
1 files changed, 5 insertions(+), 0 deletions(-)
diff --git a/drivers/net/wireless/b43/phy_lp.c b/drivers/net/wireless/b43/phy_lp.c
index 5a7b873..34b7910 100644
--- a/drivers/net/wireless/b43/phy_lp.c
+++ b/drivers/net/wireless/b43/phy_lp.c
@@ -539,10 +539,15 @@ static void lpphy_2062_init(struct b43_wldev *dev)
b43_radio_write(dev, B2062_N_TX_CTL3, 0);
b43_radio_write(dev, B2062_N_TX_CTL4, 0);
b43_radio_write(dev, B2062_N_TX_CTL5, 0);
+ b43_radio_write(dev, B2062_N_TX_CTL6, 0);
b43_radio_write(dev, B2062_N_PDN_CTL0, 0x40);
b43_radio_write(dev, B2062_N_PDN_CTL0, 0);
b43_radio_write(dev, B2062_N_CALIB_TS, 0x10);
b43_radio_write(dev, B2062_N_CALIB_TS, 0);
+ if (dev->phy.rev > 0) {
+ b43_radio_write(dev, B2062_S_BG_CTL1,
+ (b43_radio_read(dev, B2062_N_COMM2) >> 1) | 0x80);
+ }
if (b43_current_band(dev->wl) == IEEE80211_BAND_2GHZ)
b43_radio_set(dev, B2062_N_TSSI_CTL0, 0x1);
else
--
1.6.2.4
^ permalink raw reply related
* Re: [PATCH] b43: LP-PHY: Remove BROKEN from B43_PHY_LP
From: Michael Buesch @ 2009-08-16 17:50 UTC (permalink / raw)
To: Gábor Stefanik
Cc: John Linville, Larry Finger, Mark Huijgen, Broadcom Wireless,
linux-wireless
In-Reply-To: <4A88370B.5090506@gmail.com>
On Sunday 16 August 2009 18:42:51 Gábor Stefanik wrote:
> Larry has reported success getting scan data with an LP-PHY device,
> so it's probably time to release LP-PHY support for testing.
>
> Also add a temporary BROKEN Kconfig symbol to disable 5GHz support,
> as 5GHz currently causes the driver to panic (NULL pointer deref).
>
> Signed-off-by: Gábor Stefanik <netrolller.3d@gmail.com>
> ---
> drivers/net/wireless/b43/Kconfig | 25 +++++++++++++++++++------
> drivers/net/wireless/b43/main.c | 2 ++
> drivers/net/wireless/b43/phy_lp.c | 2 ++
> 3 files changed, 23 insertions(+), 6 deletions(-)
>
> diff --git a/drivers/net/wireless/b43/Kconfig b/drivers/net/wireless/b43/Kconfig
> index 67f564e..13414c9 100644
> --- a/drivers/net/wireless/b43/Kconfig
> +++ b/drivers/net/wireless/b43/Kconfig
> @@ -80,16 +80,29 @@ config B43_NPHY
> SAY N.
>
> config B43_PHY_LP
> - bool "IEEE 802.11g LP-PHY support (BROKEN)"
> - depends on B43 && EXPERIMENTAL && BROKEN
> + bool "Support for low-power (LP-PHY) devices (VERY EXPERIMENTAL)"
Very is a vague term. Just remove it.
> + depends on B43 && EXPERIMENTAL
> ---help---
> Support for the LP-PHY.
> - The LP-PHY is an IEEE 802.11g based PHY built into some notebooks
> - and embedded devices.
> + The LP-PHY is a low-power PHY built into some notebooks
> + and embedded devices. It supports 802.11a/g
> + (802.11a support is optional, and currently disabled).
>
> - THIS IS BROKEN AND DOES NOT WORK YET.
> + Known LP-PHY devices include the BCM4310, BCM4312 (PCI ID 0x4315),
> + BCM4325 (currently unsupported), BCM4326 & BCM4328 wireless cards
> + and the BCM5354 SoC.
It's pointless to list them here, as the list will always be obsolete and never be correct.
>
> - SAY N.
> + This is heavily experimental, and probably will not work for you.
> + Say N unless you want to help debug the driver.
> +
> +config B43_PHY_LP_5GHZ
> + bool "Enable 802.11a support for LP-PHYs (BROKEN)"
> + depends on B43_PHY_LP && BROKEN
> + ---help---
> + Enable the 5GHz band of LP-PHY devices. Currently, all it
> + does is cause the driver to panic on startup.
> +
> + Only select this if you are a developer working on this feature.
I don't think we should introduce another config option. Just hardcode
disable the 802.11a for LP-PHYs. There's no point in enabling an option
that crashes the kernel. And if you fix the crash, there's no point in
leaving it disabled.
> # This config option automatically enables b43 LEDS support,
> # if it's possible.
> diff --git a/drivers/net/wireless/b43/main.c b/drivers/net/wireless/b43/main.c
> index 99b41ce..0096d25 100644
> --- a/drivers/net/wireless/b43/main.c
> +++ b/drivers/net/wireless/b43/main.c
> @@ -4514,7 +4514,9 @@ static int b43_wireless_core_attach(struct b43_wldev *dev)
> have_5ghz_phy = 1;
> break;
> case B43_PHYTYPE_LP: //FIXME not always!
> +#ifdef CONFIG_B43_PHY_LP_5GHZ
> have_5ghz_phy = 1;
> +#endif
> case B43_PHYTYPE_G:
> case B43_PHYTYPE_N:
> have_2ghz_phy = 1;
> diff --git a/drivers/net/wireless/b43/phy_lp.c b/drivers/net/wireless/b43/phy_lp.c
> index 3889519..c902dd1 100644
> --- a/drivers/net/wireless/b43/phy_lp.c
> +++ b/drivers/net/wireless/b43/phy_lp.c
> @@ -43,7 +43,9 @@ static inline u16 channel2freq_lp(u8 channel)
>
> static unsigned int b43_lpphy_op_get_default_chan(struct b43_wldev *dev)
> {
> +#ifdef CONFIG_B43_PHY_LP_5GHZ
> if (b43_current_band(dev->wl) == IEEE80211_BAND_2GHZ)
> +#endif
> return 1;
> return 36;
> }
This is a completely pointless ifdef.
--
Greetings, Michael.
^ permalink raw reply
* [PATCH] b43: LP-PHY: Remove BROKEN from B43_PHY_LP
From: Gábor Stefanik @ 2009-08-16 16:42 UTC (permalink / raw)
To: John Linville, Michael Buesch, Larry Finger
Cc: Mark Huijgen, Broadcom Wireless, linux-wireless
Larry has reported success getting scan data with an LP-PHY device,
so it's probably time to release LP-PHY support for testing.
Also add a temporary BROKEN Kconfig symbol to disable 5GHz support,
as 5GHz currently causes the driver to panic (NULL pointer deref).
Signed-off-by: Gábor Stefanik <netrolller.3d@gmail.com>
---
drivers/net/wireless/b43/Kconfig | 25 +++++++++++++++++++------
drivers/net/wireless/b43/main.c | 2 ++
drivers/net/wireless/b43/phy_lp.c | 2 ++
3 files changed, 23 insertions(+), 6 deletions(-)
diff --git a/drivers/net/wireless/b43/Kconfig b/drivers/net/wireless/b43/Kconfig
index 67f564e..13414c9 100644
--- a/drivers/net/wireless/b43/Kconfig
+++ b/drivers/net/wireless/b43/Kconfig
@@ -80,16 +80,29 @@ config B43_NPHY
SAY N.
config B43_PHY_LP
- bool "IEEE 802.11g LP-PHY support (BROKEN)"
- depends on B43 && EXPERIMENTAL && BROKEN
+ bool "Support for low-power (LP-PHY) devices (VERY EXPERIMENTAL)"
+ depends on B43 && EXPERIMENTAL
---help---
Support for the LP-PHY.
- The LP-PHY is an IEEE 802.11g based PHY built into some notebooks
- and embedded devices.
+ The LP-PHY is a low-power PHY built into some notebooks
+ and embedded devices. It supports 802.11a/g
+ (802.11a support is optional, and currently disabled).
- THIS IS BROKEN AND DOES NOT WORK YET.
+ Known LP-PHY devices include the BCM4310, BCM4312 (PCI ID 0x4315),
+ BCM4325 (currently unsupported), BCM4326 & BCM4328 wireless cards
+ and the BCM5354 SoC.
- SAY N.
+ This is heavily experimental, and probably will not work for you.
+ Say N unless you want to help debug the driver.
+
+config B43_PHY_LP_5GHZ
+ bool "Enable 802.11a support for LP-PHYs (BROKEN)"
+ depends on B43_PHY_LP && BROKEN
+ ---help---
+ Enable the 5GHz band of LP-PHY devices. Currently, all it
+ does is cause the driver to panic on startup.
+
+ Only select this if you are a developer working on this feature.
# This config option automatically enables b43 LEDS support,
# if it's possible.
diff --git a/drivers/net/wireless/b43/main.c b/drivers/net/wireless/b43/main.c
index 99b41ce..0096d25 100644
--- a/drivers/net/wireless/b43/main.c
+++ b/drivers/net/wireless/b43/main.c
@@ -4514,7 +4514,9 @@ static int b43_wireless_core_attach(struct b43_wldev *dev)
have_5ghz_phy = 1;
break;
case B43_PHYTYPE_LP: //FIXME not always!
+#ifdef CONFIG_B43_PHY_LP_5GHZ
have_5ghz_phy = 1;
+#endif
case B43_PHYTYPE_G:
case B43_PHYTYPE_N:
have_2ghz_phy = 1;
diff --git a/drivers/net/wireless/b43/phy_lp.c b/drivers/net/wireless/b43/phy_lp.c
index 3889519..c902dd1 100644
--- a/drivers/net/wireless/b43/phy_lp.c
+++ b/drivers/net/wireless/b43/phy_lp.c
@@ -43,7 +43,9 @@ static inline u16 channel2freq_lp(u8 channel)
static unsigned int b43_lpphy_op_get_default_chan(struct b43_wldev *dev)
{
+#ifdef CONFIG_B43_PHY_LP_5GHZ
if (b43_current_band(dev->wl) == IEEE80211_BAND_2GHZ)
+#endif
return 1;
return 36;
}
--
1.6.2.4
^ permalink raw reply related
* [PATCH] b43: LP-PHY: Fix a bug in the B2062 channel tune path
From: Gábor Stefanik @ 2009-08-16 16:40 UTC (permalink / raw)
To: John Linville, Michael Buesch, Larry Finger
Cc: Mark Huijgen, Broadcom Wireless, linux-wireless
I missed the "+16" part of the instruction in the specs.
Signed-off-by: Gábor Stefanik <netrolller.3d@gmail.com>
---
drivers/net/wireless/b43/phy_lp.c | 2 +-
1 files changed, 1 insertions(+), 1 deletions(-)
diff --git a/drivers/net/wireless/b43/phy_lp.c b/drivers/net/wireless/b43/phy_lp.c
index 1de4a74..5a7b873 100644
--- a/drivers/net/wireless/b43/phy_lp.c
+++ b/drivers/net/wireless/b43/phy_lp.c
@@ -1952,7 +1952,7 @@ static int lpphy_b2062_tune(struct b43_wldev *dev,
b43_radio_write(dev, B2062_S_RFPLL_CTL29, tmp6 + ((2 * tmp7) / tmp4));
tmp8 = b43_phy_read(dev, B2062_S_RFPLL_CTL19);
tmp9 = ((2 * tmp3 * (tmp8 + 1)) + (3 * tmp1)) / (6 * tmp1);
- b43_radio_write(dev, B2062_S_RFPLL_CTL23, tmp9 >> 8);
+ b43_radio_write(dev, B2062_S_RFPLL_CTL23, (tmp9 >> 8) + 16);
b43_radio_write(dev, B2062_S_RFPLL_CTL24, tmp9 & 0xFF);
lpphy_b2062_vco_calib(dev);
--
1.6.2.4
^ permalink raw reply related
* Some success with LP PHY
From: Larry Finger @ 2009-08-16 16:05 UTC (permalink / raw)
To: Gábor Stefanik; +Cc: wireless, John Linville, Michael Buesch, Mark Huijgen
Gábor,
I can report some success. This morning, I got input from a 'sudo
iwlist scan' command. It does not show all the nearby APs, including
mine on channel 1, but I see a couple on channel 6, and one on 11.
I'm having a problem with 2062 channel tune routine. It gets the "PLL
charge pump out of range" error. To get anything to work, I had to
replace the error return with a printk that prints the channel. The
error happens for channels 1-6 and 9-11. Perhaps the fact that it is
OK for channels 7 and 8 is a clue. If so, I don't understand it yet.
Thanks for your efforts. It is exciting to see this device finally
coming to life.
Larry
^ permalink raw reply
* [PATCH v2] b43: LP-PHY: Update code for spec fixes, and fix a few typos
From: Gábor Stefanik @ 2009-08-16 16:05 UTC (permalink / raw)
To: John Linville, Michael Buesch, Larry Finger
Cc: Mark Huijgen, Broadcom Wireless, linux-wireless
A few typos have been discovered in both the specs and the code.
This patch fixes them.
Also use lpphy_op_switch_channel consistently, and make all users
of it print its return value for easier debugging.
Signed-off-by: Gábor Stefanik <netrolller.3d@gmail.com>
---
V2: Fix one more typo (this time a harmless one).
drivers/net/wireless/b43/phy_lp.c | 53 ++++++++++++++++++++++++------------
1 files changed, 35 insertions(+), 18 deletions(-)
diff --git a/drivers/net/wireless/b43/phy_lp.c b/drivers/net/wireless/b43/phy_lp.c
index d949cfa..1de4a74 100644
--- a/drivers/net/wireless/b43/phy_lp.c
+++ b/drivers/net/wireless/b43/phy_lp.c
@@ -554,7 +554,7 @@ static void lpphy_2062_init(struct b43_wldev *dev)
B43_WARN_ON(!(bus->chipco.capabilities & SSB_CHIPCO_CAP_PMU));
B43_WARN_ON(crystalfreq == 0);
- if (crystalfreq >= 30000000) {
+ if (crystalfreq <= 30000000) {
lpphy->pdiv = 1;
b43_radio_mask(dev, B2062_S_RFPLL_CTL1, 0xFFFB);
} else {
@@ -562,14 +562,16 @@ static void lpphy_2062_init(struct b43_wldev *dev)
b43_radio_set(dev, B2062_S_RFPLL_CTL1, 0x4);
}
- tmp = (800000000 * lpphy->pdiv + crystalfreq) /
- (32000000 * lpphy->pdiv);
- tmp = (tmp - 1) & 0xFF;
+ tmp = (((800000000 * lpphy->pdiv + crystalfreq) /
+ (2 * crystalfreq)) - 8) & 0xFF;
+ b43_radio_write(dev, B2062_S_RFPLL_CTL7, tmp);
+
+ tmp = (((100 * crystalfreq + 16000000 * lpphy->pdiv) /
+ (32000000 * lpphy->pdiv)) - 1) & 0xFF;
b43_radio_write(dev, B2062_S_RFPLL_CTL18, tmp);
- tmp = (2 * crystalfreq + 1000000 * lpphy->pdiv) /
- (2000000 * lpphy->pdiv);
- tmp = ((tmp & 0xFF) - 1) & 0xFFFF;
+ tmp = (((2 * crystalfreq + 1000000 * lpphy->pdiv) /
+ (2000000 * lpphy->pdiv)) - 1) & 0xFF;
b43_radio_write(dev, B2062_S_RFPLL_CTL19, tmp);
ref = (1000 * lpphy->pdiv + 2 * crystalfreq) / (2000 * lpphy->pdiv);
@@ -673,7 +675,7 @@ static void lpphy_radio_init(struct b43_wldev *dev)
b43_phy_mask(dev, B43_LPPHY_FOURWIRE_CTL, 0xFFFD);
udelay(1);
- if (dev->phy.rev < 2) {
+ if (dev->phy.radio_ver == 0x2062) {
lpphy_2062_init(dev);
} else {
lpphy_2063_init(dev);
@@ -690,11 +692,18 @@ struct lpphy_iq_est { u32 iq_prod, i_pwr, q_pwr; };
static void lpphy_set_rc_cap(struct b43_wldev *dev)
{
- u8 rc_cap = dev->phy.lp->rc_cap;
+ struct b43_phy_lp *lpphy = dev->phy.lp;
- b43_radio_write(dev, B2062_N_RXBB_CALIB2, max_t(u8, rc_cap-4, 0x80));
- b43_radio_write(dev, B2062_N_TX_CTL_A, ((rc_cap & 0x1F) >> 1) | 0x80);
- b43_radio_write(dev, B2062_S_RXG_CNT16, ((rc_cap & 0x1F) >> 2) | 0x80);
+ u8 rc_cap = (lpphy->rc_cap & 0x1F) >> 1;
+
+ if (dev->phy.rev == 1) //FIXME check channel 14!
+ rc_cap = max_t(u8, rc_cap + 5, 15);
+
+ b43_radio_write(dev, B2062_N_RXBB_CALIB2,
+ max_t(u8, lpphy->rc_cap - 4, 0x80));
+ b43_radio_write(dev, B2062_N_TX_CTL_A, rc_cap | 0x80);
+ b43_radio_write(dev, B2062_S_RXG_CNT16,
+ ((lpphy->rc_cap & 0x1F) >> 2) | 0x80);
}
static u8 lpphy_get_bb_mult(struct b43_wldev *dev)
@@ -1103,6 +1112,9 @@ static void lpphy_set_tx_power_control(struct b43_wldev *dev,
lpphy_write_tx_pctl_mode_to_hardware(dev);
}
+static int b43_lpphy_op_switch_channel(struct b43_wldev *dev,
+ unsigned int new_channel);
+
static void lpphy_rev0_1_rc_calib(struct b43_wldev *dev)
{
struct b43_phy_lp *lpphy = dev->phy.lp;
@@ -1120,11 +1132,16 @@ static void lpphy_rev0_1_rc_calib(struct b43_wldev *dev)
old_rf2_ovr, old_rf2_ovrval, old_phy_ctl;
enum b43_lpphy_txpctl_mode old_txpctl;
u32 normal_pwr, ideal_pwr, mean_sq_pwr, tmp = 0, mean_sq_pwr_min = 0;
- int loopback, i, j, inner_sum;
+ int loopback, i, j, inner_sum, err;
memset(&iq_est, 0, sizeof(iq_est));
- b43_switch_channel(dev, 7);
+ err = b43_lpphy_op_switch_channel(dev, 7);
+ if (err) {
+ b43dbg(dev->wl,
+ "RC calib: Failed to switch to channel 7, error = %d",
+ err);
+ }
old_txg_ovr = (b43_phy_read(dev, B43_LPPHY_AFE_CTL_OVR) >> 6) & 1;
old_bbmult = lpphy_get_bb_mult(dev);
if (old_txg_ovr)
@@ -1883,14 +1900,14 @@ static int lpphy_b2062_tune(struct b43_wldev *dev,
{
struct b43_phy_lp *lpphy = dev->phy.lp;
struct ssb_bus *bus = dev->dev->bus;
- static const struct b206x_channel *chandata = NULL;
+ const struct b206x_channel *chandata = NULL;
u32 crystal_freq = bus->chipco.pmu.crystalfreq * 1000;
u32 tmp1, tmp2, tmp3, tmp4, tmp5, tmp6, tmp7, tmp8, tmp9;
int i, err = 0;
- for (i = 0; i < ARRAY_SIZE(b2063_chantbl); i++) {
- if (b2063_chantbl[i].channel == channel) {
- chandata = &b2063_chantbl[i];
+ for (i = 0; i < ARRAY_SIZE(b2062_chantbl); i++) {
+ if (b2062_chantbl[i].channel == channel) {
+ chandata = &b2062_chantbl[i];
break;
}
}
--
1.6.2.4
^ permalink raw reply related
* Re: [PATCH] b43: LP-PHY: Update code for spec fixes, and fix a few typos
From: Larry Finger @ 2009-08-17 2:37 UTC (permalink / raw)
To: Gábor Stefanik
Cc: John Linville, Michael Buesch, Mark Huijgen, Broadcom Wireless,
linux-wireless
In-Reply-To: <4A88090D.3070107@gmail.com>
Gábor Stefanik wrote:
> A few typos have been discovered both in the specs in and our code.
> This patch fixes them.
>
> Also use lpphy_op_switch_channel consistently, and make all callers
> print its return value for easier debugging.
>
> Signed-off-by: Gábor Stefanik <netrolller.3d@gmail.com>
> ---
> I think using a forward declaration is justified in this case;
> as avoiding the forward decl would require moving around huge
> blocks of code, completely breaking any logical ordering.
>
> drivers/net/wireless/b43/phy_lp.c | 51
> ++++++++++++++++++++++++------------
> 1 files changed, 34 insertions(+), 17 deletions(-)
>
> diff --git a/drivers/net/wireless/b43/phy_lp.c
> b/drivers/net/wireless/b43/phy_lp.c
> index e4a040b..a51da6e 100644
> --- a/drivers/net/wireless/b43/phy_lp.c
> +++ b/drivers/net/wireless/b43/phy_lp.c
> @@ -552,7 +552,7 @@ static void lpphy_2062_init(struct b43_wldev *dev)
> B43_WARN_ON(!(bus->chipco.capabilities & SSB_CHIPCO_CAP_PMU));
> B43_WARN_ON(crystalfreq == 0);
>
> - if (crystalfreq >= 30000000) {
> + if (crystalfreq <= 30000000) {
> lpphy->pdiv = 1;
> b43_radio_mask(dev, B2062_S_RFPLL_CTL1, 0xFFFB);
> } else {
> @@ -560,14 +560,16 @@ static void lpphy_2062_init(struct b43_wldev *dev)
> b43_radio_set(dev, B2062_S_RFPLL_CTL1, 0x4);
> }
>
> - tmp = (800000000 * lpphy->pdiv + crystalfreq) /
> - (32000000 * lpphy->pdiv);
> - tmp = (tmp - 1) & 0xFF;
> + tmp = (((800000000 * lpphy->pdiv + crystalfreq) /
> + (2 * crystalfreq)) - 8) & 0xFF;
> + b43_radio_write(dev, B2062_S_RFPLL_CTL7, tmp);
> +
> + tmp = (((100 * crystalfreq + 16000000 * lpphy->pdiv) /
> + (32000000 * lpphy->pdiv)) - 1) & 0xFF;
> b43_radio_write(dev, B2062_S_RFPLL_CTL18, tmp);
>
> - tmp = (2 * crystalfreq + 1000000 * lpphy->pdiv) /
> - (2000000 * lpphy->pdiv);
> - tmp = ((tmp & 0xFF) - 1) & 0xFFFF;
> + tmp = (((2 * crystalfreq + 1000000 * lpphy->pdiv) /
> + (2000000 * lpphy->pdiv)) - 1) & 0xFF;
> b43_radio_write(dev, B2062_S_RFPLL_CTL19, tmp);
>
> ref = (1000 * lpphy->pdiv + 2 * crystalfreq) / (2000 * lpphy->pdiv);
> @@ -671,7 +673,7 @@ static void lpphy_radio_init(struct b43_wldev *dev)
> b43_phy_mask(dev, B43_LPPHY_FOURWIRE_CTL, 0xFFFD);
> udelay(1);
>
> - if (dev->phy.rev < 2) {
> + if (dev->phy.radio_ver == 0x2062) {
> lpphy_2062_init(dev);
> } else {
> lpphy_2063_init(dev);
> @@ -688,11 +690,18 @@ struct lpphy_iq_est { u32 iq_prod, i_pwr, q_pwr; };
>
> static void lpphy_set_rc_cap(struct b43_wldev *dev)
> {
> - u8 rc_cap = dev->phy.lp->rc_cap;
> + struct b43_phy_lp *lpphy = dev->phy.lp;
>
> - b43_radio_write(dev, B2062_N_RXBB_CALIB2, max_t(u8, rc_cap-4, 0x80));
> - b43_radio_write(dev, B2062_N_TX_CTL_A, ((rc_cap & 0x1F) >> 1) | 0x80);
> - b43_radio_write(dev, B2062_S_RXG_CNT16, ((rc_cap & 0x1F) >> 2) |
> 0x80);
> + u8 rc_cap = (lpphy->rc_cap & 0x1F) >> 1;
> +
> + if (dev->phy.rev == 1) //FIXME check channel 14!
> + rc_cap = max_t(u8, rc_cap + 5, 15);
> +
> + b43_radio_write(dev, B2062_N_RXBB_CALIB2,
> + max_t(u8, lpphy->rc_cap - 4, 0x80));
> + b43_radio_write(dev, B2062_N_TX_CTL_A, rc_cap | 0x80);
> + b43_radio_write(dev, B2062_S_RXG_CNT16,
> + ((lpphy->rc_cap & 0x1F) >> 2) | 0x80);
> }
>
> static u8 lpphy_get_bb_mult(struct b43_wldev *dev)
> @@ -1101,6 +1110,9 @@ static void lpphy_set_tx_power_control(struct
> b43_wldev *dev,
> lpphy_write_tx_pctl_mode_to_hardware(dev);
> }
>
> +static int b43_lpphy_op_switch_channel(struct b43_wldev *dev,
> + unsigned int new_channel);
> +
> static void lpphy_rev0_1_rc_calib(struct b43_wldev *dev)
> {
> struct b43_phy_lp *lpphy = dev->phy.lp;
> @@ -1118,11 +1130,16 @@ static void lpphy_rev0_1_rc_calib(struct
> b43_wldev *dev)
> old_rf2_ovr, old_rf2_ovrval, old_phy_ctl;
> enum b43_lpphy_txpctl_mode old_txpctl;
> u32 normal_pwr, ideal_pwr, mean_sq_pwr, tmp = 0, mean_sq_pwr_min = 0;
> - int loopback, i, j, inner_sum;
> + int loopback, i, j, inner_sum, err;
>
> memset(&iq_est, 0, sizeof(iq_est));
>
> - b43_switch_channel(dev, 7);
> + err = b43_lpphy_op_switch_channel(dev, 7);
> + if (err) {
> + b43dbg(dev->wl,
> + "RC calib: Failed to switch to channel 7, error = %d",
> + err);
> + }
> old_txg_ovr = (b43_phy_read(dev, B43_LPPHY_AFE_CTL_OVR) >> 6) & 1;
> old_bbmult = lpphy_get_bb_mult(dev);
> if (old_txg_ovr)
> @@ -1881,14 +1898,14 @@ static int lpphy_b2062_tune(struct b43_wldev *dev,
> {
> struct b43_phy_lp *lpphy = dev->phy.lp;
> struct ssb_bus *bus = dev->dev->bus;
> - static const struct b206x_channel *chandata = NULL;
> + const struct b206x_channel *chandata = NULL;
> u32 crystal_freq = bus->chipco.pmu.crystalfreq * 1000;
> u32 tmp1, tmp2, tmp3, tmp4, tmp5, tmp6, tmp7, tmp8, tmp9;
> int i, err = 0;
>
> - for (i = 0; i < ARRAY_SIZE(b2063_chantbl); i++) {
> + for (i = 0; i < ARRAY_SIZE(b2062_chantbl); i++) {
> if (b2063_chantbl[i].channel == channel) {
-----
This should also be b2062. As long as the two tables have the same
channel ordering, this way would work.
> - chandata = &b2063_chantbl[i];
> + chandata = &b2062_chantbl[i];
> break;
> }
> }
Larry
^ permalink raw reply
* Re: [PATCH] b43: LP-PHY: Fix a spec error in the B2062 channel switch routine
From: Michael Buesch @ 2009-08-16 13:43 UTC (permalink / raw)
To: Gábor Stefanik
Cc: John Linville, Larry Finger, Mark Huijgen, Broadcom Wireless,
linux-wireless
In-Reply-To: <4A880A78.9050205@gmail.com>
On Sunday 16 August 2009 15:32:40 Gábor Stefanik wrote:
> The channel switch routine had a whole instruction missing. Add it.
>
> Signed-off-by: Gábor Stefanik <netrolller.3d@gmail.com>
ack
> ---
> drivers/net/wireless/b43/phy_lp.c | 4 ++++
> 1 files changed, 4 insertions(+), 0 deletions(-)
>
> diff --git a/drivers/net/wireless/b43/phy_lp.c b/drivers/net/wireless/b43/phy_lp.c
> index a51da6e..3889519 100644
> --- a/drivers/net/wireless/b43/phy_lp.c
> +++ b/drivers/net/wireless/b43/phy_lp.c
> @@ -1939,6 +1939,10 @@ static int lpphy_b2062_tune(struct b43_wldev *dev,
> tmp5 = tmp7 * 0x100;
> tmp6 = tmp5 / tmp4;
> tmp7 = tmp5 % tmp4;
> + b43_radio_write(dev, B2062_S_RFPLL_CTL27, tmp6);
> + tmp5 = tmp7 * 0x100;
> + tmp6 = tmp5 / tmp4;
> + tmp7 = tmp5 % tmp4;
> b43_radio_write(dev, B2062_S_RFPLL_CTL28, tmp6);
> tmp5 = tmp7 * 0x100;
> tmp6 = tmp5 / tmp4;
--
Greetings, Michael.
^ permalink raw reply
* Re: [PATCH] b43: LP-PHY: Update code for spec fixes, and fix a few typos
From: Michael Buesch @ 2009-08-16 13:42 UTC (permalink / raw)
To: Gábor Stefanik
Cc: John Linville, Larry Finger, Mark Huijgen, Broadcom Wireless,
linux-wireless
In-Reply-To: <4A88090D.3070107@gmail.com>
On Sunday 16 August 2009 15:26:37 Gábor Stefanik wrote:
> A few typos have been discovered both in the specs in and our code.
> This patch fixes them.
>
> Also use lpphy_op_switch_channel consistently, and make all callers
> print its return value for easier debugging.
>
> Signed-off-by: Gábor Stefanik <netrolller.3d@gmail.com>
> ---
> I think using a forward declaration is justified in this case;
> as avoiding the forward decl would require moving around huge
> blocks of code, completely breaking any logical ordering.
I don't think so, but I'll ack this anyway.
--
Greetings, Michael.
^ permalink raw reply
page: next (older) | prev (newer) | latest
- recent:[subjects (threaded)|topics (new)|topics (active)]
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox