* [PATCH 2/8] rndis_wlan: get bssid scan list before new scan
2009-08-28 9:58 [PATCH 1/8] rndis_wlan: ignore OID_802_11_ADD_KEY triggered media connect indications Jussi Kivilinna
@ 2009-08-28 9:58 ` Jussi Kivilinna
2009-08-28 9:59 ` [PATCH 3/8] rndis_wlan: resize bssid list if too small Jussi Kivilinna
` (5 subsequent siblings)
6 siblings, 0 replies; 8+ messages in thread
From: Jussi Kivilinna @ 2009-08-28 9:58 UTC (permalink / raw)
To: linux-wireless; +Cc: John W. Linville
OID_802_11_BSSID_LIST_SCAN clears device's bssid list, so retrieve
current bssid list from device before issuing new scan.
Signed-off-by: Jussi Kivilinna <jussi.kivilinna@mbnet.fi>
---
drivers/net/wireless/rndis_wlan.c | 6 ++++++
1 files changed, 6 insertions(+), 0 deletions(-)
diff --git a/drivers/net/wireless/rndis_wlan.c b/drivers/net/wireless/rndis_wlan.c
index 612c2c7..3779621 100644
--- a/drivers/net/wireless/rndis_wlan.c
+++ b/drivers/net/wireless/rndis_wlan.c
@@ -926,6 +926,7 @@ static int freq_to_dsconfig(struct iw_freq *freq, unsigned int *dsconfig)
* common functions
*/
static void restore_keys(struct usbnet *usbdev);
+static int rndis_check_bssid_list(struct usbnet *usbdev);
static int get_essid(struct usbnet *usbdev, struct ndis_80211_ssid *ssid)
{
@@ -1616,6 +1617,11 @@ static int rndis_scan(struct wiphy *wiphy, struct net_device *dev,
devdbg(usbdev, "cfg80211.scan");
+ /* Get current bssid list from device before new scan, as new scan
+ * clears internal bssid list.
+ */
+ rndis_check_bssid_list(usbdev);
+
if (!request)
return -EINVAL;
^ permalink raw reply related [flat|nested] 8+ messages in thread* [PATCH 3/8] rndis_wlan: resize bssid list if too small
2009-08-28 9:58 [PATCH 1/8] rndis_wlan: ignore OID_802_11_ADD_KEY triggered media connect indications Jussi Kivilinna
2009-08-28 9:58 ` [PATCH 2/8] rndis_wlan: get bssid scan list before new scan Jussi Kivilinna
@ 2009-08-28 9:59 ` Jussi Kivilinna
2009-08-28 9:59 ` [PATCH 4/8] rndis_wlan: increase scan timer delay Jussi Kivilinna
` (4 subsequent siblings)
6 siblings, 0 replies; 8+ messages in thread
From: Jussi Kivilinna @ 2009-08-28 9:59 UTC (permalink / raw)
To: linux-wireless; +Cc: John W. Linville
Buffer used for bssid list might be too small. Change rndis_query_oid()
to return required buffer length to caller and make rndis_check_bssid_list()
resize buffer when needed.
Signed-off-by: Jussi Kivilinna <jussi.kivilinna@mbnet.fi>
---
drivers/net/wireless/rndis_wlan.c | 17 +++++++++++++++--
1 files changed, 15 insertions(+), 2 deletions(-)
diff --git a/drivers/net/wireless/rndis_wlan.c b/drivers/net/wireless/rndis_wlan.c
index 3779621..2309ad2 100644
--- a/drivers/net/wireless/rndis_wlan.c
+++ b/drivers/net/wireless/rndis_wlan.c
@@ -676,7 +676,8 @@ static int rndis_query_oid(struct usbnet *dev, __le32 oid, void *data, int *len)
if (ret == 0) {
ret = le32_to_cpu(u.get_c->len);
- *len = (*len > ret) ? ret : *len;
+ if (ret > *len)
+ *len = ret;
memcpy(data, u.buf + le32_to_cpu(u.get_c->offset) + 8, *len);
ret = rndis_error_status(u.get_c->status);
@@ -1656,6 +1657,9 @@ static struct cfg80211_bss *rndis_bss_info_update(struct usbnet *usbdev,
int ie_len, bssid_len;
u8 *ie;
+ devdbg(usbdev, " found bssid: '%.32s' [%pM]", bssid->ssid.essid,
+ bssid->mac);
+
/* parse bssid structure */
bssid_len = le32_to_cpu(bssid->length);
@@ -1695,10 +1699,12 @@ static int rndis_check_bssid_list(struct usbnet *usbdev)
struct ndis_80211_bssid_list_ex *bssid_list;
struct ndis_80211_bssid_ex *bssid;
int ret = -EINVAL, len, count, bssid_len;
+ bool resized = false;
devdbg(usbdev, "check_bssid_list");
len = CONTROL_BUFFER_SIZE;
+resize_buf:
buf = kmalloc(len, GFP_KERNEL);
if (!buf) {
ret = -ENOMEM;
@@ -1709,11 +1715,18 @@ static int rndis_check_bssid_list(struct usbnet *usbdev)
if (ret != 0)
goto out;
+ if (!resized && len > CONTROL_BUFFER_SIZE) {
+ resized = true;
+ kfree(buf);
+ goto resize_buf;
+ }
+
bssid_list = buf;
bssid = bssid_list->bssid;
bssid_len = le32_to_cpu(bssid->length);
count = le32_to_cpu(bssid_list->num_items);
- devdbg(usbdev, "check_bssid_list: %d BSSIDs found", count);
+ devdbg(usbdev, "check_bssid_list: %d BSSIDs found (buflen: %d)", count,
+ len);
while (count && ((void *)bssid + bssid_len) <= (buf + len)) {
rndis_bss_info_update(usbdev, bssid);
^ permalink raw reply related [flat|nested] 8+ messages in thread* [PATCH 4/8] rndis_wlan: increase scan timer delay
2009-08-28 9:58 [PATCH 1/8] rndis_wlan: ignore OID_802_11_ADD_KEY triggered media connect indications Jussi Kivilinna
2009-08-28 9:58 ` [PATCH 2/8] rndis_wlan: get bssid scan list before new scan Jussi Kivilinna
2009-08-28 9:59 ` [PATCH 3/8] rndis_wlan: resize bssid list if too small Jussi Kivilinna
@ 2009-08-28 9:59 ` Jussi Kivilinna
2009-08-28 9:59 ` [PATCH 5/8] rndis_wlan: move link up/down work to separate functions Jussi Kivilinna
` (3 subsequent siblings)
6 siblings, 0 replies; 8+ messages in thread
From: Jussi Kivilinna @ 2009-08-28 9:59 UTC (permalink / raw)
To: linux-wireless; +Cc: John W. Linville
Increase scan delay from 1 sec to 6 sec. Spec says that scan by
OID_802_11_BSSID_LIST_SCAN completes in 6 seconds.
Before rfkill patch too short delay was not problem as device was
always active (radio on) and performing background scanning.
Signed-off-by: Jussi Kivilinna <jussi.kivilinna@mbnet.fi>
---
drivers/net/wireless/rndis_wlan.c | 2 +-
1 files changed, 1 insertions(+), 1 deletions(-)
diff --git a/drivers/net/wireless/rndis_wlan.c b/drivers/net/wireless/rndis_wlan.c
index 2309ad2..cb362b0 100644
--- a/drivers/net/wireless/rndis_wlan.c
+++ b/drivers/net/wireless/rndis_wlan.c
@@ -1607,7 +1607,7 @@ static int rndis_get_tx_power(struct wiphy *wiphy, int *dbm)
}
-#define SCAN_DELAY_JIFFIES (HZ)
+#define SCAN_DELAY_JIFFIES (6 * HZ)
static int rndis_scan(struct wiphy *wiphy, struct net_device *dev,
struct cfg80211_scan_request *request)
{
^ permalink raw reply related [flat|nested] 8+ messages in thread* [PATCH 5/8] rndis_wlan: move link up/down work to separate functions
2009-08-28 9:58 [PATCH 1/8] rndis_wlan: ignore OID_802_11_ADD_KEY triggered media connect indications Jussi Kivilinna
` (2 preceding siblings ...)
2009-08-28 9:59 ` [PATCH 4/8] rndis_wlan: increase scan timer delay Jussi Kivilinna
@ 2009-08-28 9:59 ` Jussi Kivilinna
2009-08-28 9:59 ` [PATCH 6/8] rndis_wlan: use is_zero_ether_addr() and is_broadcast_ether_addr() Jussi Kivilinna
` (2 subsequent siblings)
6 siblings, 0 replies; 8+ messages in thread
From: Jussi Kivilinna @ 2009-08-28 9:59 UTC (permalink / raw)
To: linux-wireless; +Cc: John W. Linville
Move link up/down work to separate functions and use local array
for allocating memory for info structure instead of kzmalloc.
Signed-off-by: Jussi Kivilinna <jussi.kivilinna@mbnet.fi>
---
drivers/net/wireless/rndis_wlan.c | 101 ++++++++++++++++++++-----------------
1 files changed, 55 insertions(+), 46 deletions(-)
diff --git a/drivers/net/wireless/rndis_wlan.c b/drivers/net/wireless/rndis_wlan.c
index cb362b0..dc3083b 100644
--- a/drivers/net/wireless/rndis_wlan.c
+++ b/drivers/net/wireless/rndis_wlan.c
@@ -2319,68 +2319,77 @@ static const struct iw_handler_def rndis_iw_handlers = {
};
-static void rndis_wlan_worker(struct work_struct *work)
+static void rndis_wlan_do_link_up_work(struct usbnet *usbdev)
{
- struct rndis_wlan_private *priv =
- container_of(work, struct rndis_wlan_private, work);
- struct usbnet *usbdev = priv->usbdev;
- union iwreq_data evt;
- unsigned char bssid[ETH_ALEN];
struct ndis_80211_assoc_info *info;
- int assoc_size = sizeof(*info) + IW_CUSTOM_MAX + 32;
+ union iwreq_data evt;
+ u8 assoc_buf[sizeof(*info) + IW_CUSTOM_MAX + 32];
+ u8 bssid[ETH_ALEN];
int ret, offset;
- if (test_and_clear_bit(WORK_LINK_UP, &priv->work_pending)) {
- netif_carrier_on(usbdev->net);
-
- info = kzalloc(assoc_size, GFP_KERNEL);
- if (!info)
- goto get_bssid;
-
- /* Get association info IEs from device and send them back to
- * userspace. */
- ret = get_association_info(usbdev, info, assoc_size);
- if (!ret) {
- evt.data.length = le32_to_cpu(info->req_ie_length);
- if (evt.data.length > 0) {
- offset = le32_to_cpu(info->offset_req_ies);
- wireless_send_event(usbdev->net,
- IWEVASSOCREQIE, &evt,
- (char *)info + offset);
- }
-
- evt.data.length = le32_to_cpu(info->resp_ie_length);
- if (evt.data.length > 0) {
- offset = le32_to_cpu(info->offset_resp_ies);
- wireless_send_event(usbdev->net,
- IWEVASSOCRESPIE, &evt,
- (char *)info + offset);
- }
+ memset(assoc_buf, 0, sizeof(assoc_buf));
+ info = (void *)assoc_buf;
+
+ netif_carrier_on(usbdev->net);
+
+ /* Get association info IEs from device and send them back to
+ * userspace. */
+ ret = get_association_info(usbdev, info, sizeof(assoc_buf));
+ if (!ret) {
+ evt.data.length = le32_to_cpu(info->req_ie_length);
+ if (evt.data.length > 0) {
+ offset = le32_to_cpu(info->offset_req_ies);
+ wireless_send_event(usbdev->net,
+ IWEVASSOCREQIE, &evt,
+ (char *)info + offset);
}
- kfree(info);
-
-get_bssid:
- ret = get_bssid(usbdev, bssid);
- if (!ret) {
- evt.data.flags = 0;
- evt.data.length = 0;
- memcpy(evt.ap_addr.sa_data, bssid, ETH_ALEN);
- wireless_send_event(usbdev->net, SIOCGIWAP, &evt, NULL);
+ evt.data.length = le32_to_cpu(info->resp_ie_length);
+ if (evt.data.length > 0) {
+ offset = le32_to_cpu(info->offset_resp_ies);
+ wireless_send_event(usbdev->net,
+ IWEVASSOCRESPIE, &evt,
+ (char *)info + offset);
}
usbnet_resume_rx(usbdev);
}
- if (test_and_clear_bit(WORK_LINK_DOWN, &priv->work_pending)) {
- netif_carrier_off(usbdev->net);
-
+ ret = get_bssid(usbdev, bssid);
+ if (!ret) {
evt.data.flags = 0;
evt.data.length = 0;
- memset(evt.ap_addr.sa_data, 0, ETH_ALEN);
+ memcpy(evt.ap_addr.sa_data, bssid, ETH_ALEN);
wireless_send_event(usbdev->net, SIOCGIWAP, &evt, NULL);
}
+ usbnet_resume_rx(usbdev);
+}
+
+static void rndis_wlan_do_link_down_work(struct usbnet *usbdev)
+{
+ union iwreq_data evt;
+
+ netif_carrier_off(usbdev->net);
+
+ evt.data.flags = 0;
+ evt.data.length = 0;
+ memset(evt.ap_addr.sa_data, 0, ETH_ALEN);
+ wireless_send_event(usbdev->net, SIOCGIWAP, &evt, NULL);
+}
+
+static void rndis_wlan_worker(struct work_struct *work)
+{
+ struct rndis_wlan_private *priv =
+ container_of(work, struct rndis_wlan_private, work);
+ struct usbnet *usbdev = priv->usbdev;
+
+ if (test_and_clear_bit(WORK_LINK_UP, &priv->work_pending))
+ rndis_wlan_do_link_up_work(usbdev);
+
+ if (test_and_clear_bit(WORK_LINK_DOWN, &priv->work_pending))
+ rndis_wlan_do_link_down_work(usbdev);
+
if (test_and_clear_bit(WORK_SET_MULTICAST_LIST, &priv->work_pending))
set_multicast_list(usbdev);
}
^ permalink raw reply related [flat|nested] 8+ messages in thread* [PATCH 6/8] rndis_wlan: use is_zero_ether_addr() and is_broadcast_ether_addr()
2009-08-28 9:58 [PATCH 1/8] rndis_wlan: ignore OID_802_11_ADD_KEY triggered media connect indications Jussi Kivilinna
` (3 preceding siblings ...)
2009-08-28 9:59 ` [PATCH 5/8] rndis_wlan: move link up/down work to separate functions Jussi Kivilinna
@ 2009-08-28 9:59 ` Jussi Kivilinna
2009-08-28 9:59 ` [PATCH 7/8] rndis_wlan: set ieee80211_ptr->iftype in rndis_change_virtual_intf Jussi Kivilinna
2009-08-28 9:59 ` [PATCH 8/8] rndis_wlan: enable infrastructure before setting random essid Jussi Kivilinna
6 siblings, 0 replies; 8+ messages in thread
From: Jussi Kivilinna @ 2009-08-28 9:59 UTC (permalink / raw)
To: linux-wireless; +Cc: John W. Linville
Use is_zero_ether_addr() and is_broadcast_ether_addr() instead of
memcmp against ffff_bssid/zero_bssid.
Signed-off-by: Jussi Kivilinna <jussi.kivilinna@mbnet.fi>
---
drivers/net/wireless/rndis_wlan.c | 17 ++++++-----------
1 files changed, 6 insertions(+), 11 deletions(-)
diff --git a/drivers/net/wireless/rndis_wlan.c b/drivers/net/wireless/rndis_wlan.c
index dc3083b..c28fde5 100644
--- a/drivers/net/wireless/rndis_wlan.c
+++ b/drivers/net/wireless/rndis_wlan.c
@@ -514,11 +514,6 @@ static struct cfg80211_ops rndis_config_ops = {
static void *rndis_wiphy_privid = &rndis_wiphy_privid;
-static const unsigned char zero_bssid[ETH_ALEN] = {0,};
-static const unsigned char ffff_bssid[ETH_ALEN] = { 0xff, 0xff, 0xff,
- 0xff, 0xff, 0xff };
-
-
static struct rndis_wlan_private *get_rndis_wlan_priv(struct usbnet *dev)
{
return (struct rndis_wlan_private *)dev->driver_priv;
@@ -995,7 +990,7 @@ static int is_associated(struct usbnet *usbdev)
ret = get_bssid(usbdev, bssid);
- return(ret == 0 && memcmp(bssid, zero_bssid, ETH_ALEN) != 0);
+ return (ret == 0 && !is_zero_ether_addr(bssid));
}
@@ -1293,8 +1288,8 @@ static int add_wpa_key(struct usbnet *usbdev, const u8 *key, int key_len,
devdbg(usbdev, "add_wpa_key: recv seq flag without buffer");
return -EINVAL;
}
- is_addr_ok = addr && memcmp(addr, zero_bssid, ETH_ALEN) != 0 &&
- memcmp(addr, ffff_bssid, ETH_ALEN) != 0;
+ is_addr_ok = addr && !is_zero_ether_addr(addr) &&
+ !is_broadcast_ether_addr(addr);
if ((flags & NDIS_80211_ADDKEY_PAIRWISE_KEY) && !is_addr_ok) {
devdbg(usbdev, "add_wpa_key: pairwise but bssid invalid (%pM)",
addr);
@@ -1379,8 +1374,8 @@ static int restore_key(struct usbnet *usbdev, int key_idx)
/*if (priv->encr_tx_key_index == key_idx)
flags |= NDIS_80211_ADDKEY_TRANSMIT_KEY;*/
- if (memcmp(key.bssid, zero_bssid, ETH_ALEN) != 0 &&
- memcmp(key.bssid, ffff_bssid, ETH_ALEN) != 0)
+ if (!is_zero_ether_addr(key.bssid) &&
+ !is_broadcast_ether_addr(key.bssid))
flags |= NDIS_80211_ADDKEY_PAIRWISE_KEY;
return add_wpa_key(usbdev, key.material, key.len, key_idx,
@@ -1430,7 +1425,7 @@ static int remove_key(struct usbnet *usbdev, int index, u8 bssid[ETH_ALEN])
remove_key.index = cpu_to_le32(index);
if (bssid) {
/* pairwise key */
- if (memcmp(bssid, ffff_bssid, ETH_ALEN) != 0)
+ if (!is_broadcast_ether_addr(bssid))
remove_key.index |=
NDIS_80211_ADDKEY_PAIRWISE_KEY;
memcpy(remove_key.bssid, bssid,
^ permalink raw reply related [flat|nested] 8+ messages in thread* [PATCH 7/8] rndis_wlan: set ieee80211_ptr->iftype in rndis_change_virtual_intf
2009-08-28 9:58 [PATCH 1/8] rndis_wlan: ignore OID_802_11_ADD_KEY triggered media connect indications Jussi Kivilinna
` (4 preceding siblings ...)
2009-08-28 9:59 ` [PATCH 6/8] rndis_wlan: use is_zero_ether_addr() and is_broadcast_ether_addr() Jussi Kivilinna
@ 2009-08-28 9:59 ` Jussi Kivilinna
2009-08-28 9:59 ` [PATCH 8/8] rndis_wlan: enable infrastructure before setting random essid Jussi Kivilinna
6 siblings, 0 replies; 8+ messages in thread
From: Jussi Kivilinna @ 2009-08-28 9:59 UTC (permalink / raw)
To: linux-wireless; +Cc: John W. Linville
Signed-off-by: Jussi Kivilinna <jussi.kivilinna@mbnet.fi>
---
drivers/net/wireless/rndis_wlan.c | 5 ++++-
1 files changed, 4 insertions(+), 1 deletions(-)
diff --git a/drivers/net/wireless/rndis_wlan.c b/drivers/net/wireless/rndis_wlan.c
index c28fde5..d117620 100644
--- a/drivers/net/wireless/rndis_wlan.c
+++ b/drivers/net/wireless/rndis_wlan.c
@@ -1526,7 +1526,8 @@ static int rndis_change_virtual_intf(struct wiphy *wiphy,
enum nl80211_iftype type, u32 *flags,
struct vif_params *params)
{
- struct usbnet *usbdev = netdev_priv(dev);
+ struct rndis_wlan_private *priv = wiphy_priv(wiphy);
+ struct usbnet *usbdev = priv->usbdev;
int mode;
switch (type) {
@@ -1540,6 +1541,8 @@ static int rndis_change_virtual_intf(struct wiphy *wiphy,
return -EINVAL;
}
+ priv->wdev.iftype = type;
+
return set_infra_mode(usbdev, mode);
}
^ permalink raw reply related [flat|nested] 8+ messages in thread* [PATCH 8/8] rndis_wlan: enable infrastructure before setting random essid
2009-08-28 9:58 [PATCH 1/8] rndis_wlan: ignore OID_802_11_ADD_KEY triggered media connect indications Jussi Kivilinna
` (5 preceding siblings ...)
2009-08-28 9:59 ` [PATCH 7/8] rndis_wlan: set ieee80211_ptr->iftype in rndis_change_virtual_intf Jussi Kivilinna
@ 2009-08-28 9:59 ` Jussi Kivilinna
6 siblings, 0 replies; 8+ messages in thread
From: Jussi Kivilinna @ 2009-08-28 9:59 UTC (permalink / raw)
To: linux-wireless; +Cc: John W. Linville
Random essid must be set to turn on radio when not connected. If device is
in ad-hoc mode, this results 'media connect' indications with the random
essid which should be ignored.
Signed-off-by: Jussi Kivilinna <jussi.kivilinna@mbnet.fi>
---
drivers/net/wireless/rndis_wlan.c | 6 ++++++
1 files changed, 6 insertions(+), 0 deletions(-)
diff --git a/drivers/net/wireless/rndis_wlan.c b/drivers/net/wireless/rndis_wlan.c
index d117620..c5a674d 100644
--- a/drivers/net/wireless/rndis_wlan.c
+++ b/drivers/net/wireless/rndis_wlan.c
@@ -921,6 +921,7 @@ static int freq_to_dsconfig(struct iw_freq *freq, unsigned int *dsconfig)
/*
* common functions
*/
+static int set_infra_mode(struct usbnet *usbdev, int mode);
static void restore_keys(struct usbnet *usbdev);
static int rndis_check_bssid_list(struct usbnet *usbdev);
@@ -1014,6 +1015,11 @@ static int disassociate(struct usbnet *usbdev, int reset_ssid)
/* disassociate causes radio to be turned off; if reset_ssid
* is given, set random ssid to enable radio */
if (reset_ssid) {
+ /* Set device to infrastructure mode so we don't get ad-hoc
+ * 'media connect' indications with the random ssid.
+ */
+ set_infra_mode(usbdev, NDIS_80211_INFRA_INFRA);
+
ssid.length = cpu_to_le32(sizeof(ssid.essid));
get_random_bytes(&ssid.essid[2], sizeof(ssid.essid)-2);
ssid.essid[0] = 0x1;
^ permalink raw reply related [flat|nested] 8+ messages in thread