From 20ad4fd56255b455beb677dc097eb108d15f1d63 Mon Sep 17 00:00:00 2001 From: Scott Ashcroft Date: Tue, 27 May 2008 11:15:02 +0300 Subject: rndis_wlan: use ARRAY_SIZE instead of sizeof when adding 11g rates While figuring out the TKIP problem I found a bug in the code which adds the 11g rates. It's using sizeof instead of ARRAY_SIZE to terminate the for loop. This makes it fall off the end of the rates array start into the frequency array instead. Running "iwlist rate" should show the problem as there will always be 32 rates with the last few being bogus. The following patch will fix it. Signed-off-by: Scott Ashcroft Signed-off-by: Jussi Kivilinna Signed-off-by: John W. Linville --- drivers/net/wireless/rndis_wlan.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/net/wireless/rndis_wlan.c') diff --git a/drivers/net/wireless/rndis_wlan.c b/drivers/net/wireless/rndis_wlan.c index d0b1fb15c70..ed310f84f28 100644 --- a/drivers/net/wireless/rndis_wlan.c +++ b/drivers/net/wireless/rndis_wlan.c @@ -1108,7 +1108,7 @@ static int rndis_iw_get_range(struct net_device *dev, /* fill in 802.11g rates */ if (has_80211g_rates) { num = range->num_bitrates; - for (i = 0; i < sizeof(rates_80211g); i++) { + for (i = 0; i < ARRAY_SIZE(rates_80211g); i++) { for (j = 0; j < num; j++) { if (range->bitrate[j] == rates_80211g[i] * 1000000) -- cgit v1.2.3 From 6010ce07a66cfed043879de31275f5b90b33c4fc Mon Sep 17 00:00:00 2001 From: Jussi Kivilinna Date: Mon, 2 Jun 2008 18:35:21 +0300 Subject: rndis_wlan: do link-down state change in worker thread rndis_wext_link_change() is called from within rndis_command() so it isn't very good place to do any work. Move to worker thread. Signed-off-by: Jussi Kivilinna Signed-off-by: John W. Linville --- drivers/net/wireless/rndis_wlan.c | 28 ++++++++++++++-------------- 1 file changed, 14 insertions(+), 14 deletions(-) (limited to 'drivers/net/wireless/rndis_wlan.c') diff --git a/drivers/net/wireless/rndis_wlan.c b/drivers/net/wireless/rndis_wlan.c index 3954897d067..aaeeec80397 100644 --- a/drivers/net/wireless/rndis_wlan.c +++ b/drivers/net/wireless/rndis_wlan.c @@ -310,8 +310,9 @@ enum wpa_key_mgmt { KEY_MGMT_802_1X, KEY_MGMT_PSK, KEY_MGMT_NONE, #define CAP_MODE_MASK 7 #define CAP_SUPPORT_TXPOWER 8 -#define WORK_CONNECTION_EVENT (1<<0) -#define WORK_SET_MULTICAST_LIST (1<<1) +#define WORK_LINK_UP (1<<0) +#define WORK_LINK_DOWN (1<<1) +#define WORK_SET_MULTICAST_LIST (1<<2) /* RNDIS device private data */ struct rndis_wext_private { @@ -2213,7 +2214,7 @@ static void rndis_wext_worker(struct work_struct *work) int assoc_size = sizeof(*info) + IW_CUSTOM_MAX + 32; int ret, offset; - if (test_and_clear_bit(WORK_CONNECTION_EVENT, &priv->work_pending)) { + if (test_and_clear_bit(WORK_LINK_UP, &priv->work_pending)) { info = kzalloc(assoc_size, GFP_KERNEL); if (!info) goto get_bssid; @@ -2251,6 +2252,13 @@ get_bssid: } } + if (test_and_clear_bit(WORK_LINK_DOWN, &priv->work_pending)) { + 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); + } + if (test_and_clear_bit(WORK_SET_MULTICAST_LIST, &priv->work_pending)) set_multicast_list(usbdev); } @@ -2267,18 +2275,10 @@ static void rndis_wext_set_multicast_list(struct net_device *dev) static void rndis_wext_link_change(struct usbnet *dev, int state) { struct rndis_wext_private *priv = get_rndis_wext_priv(dev); - union iwreq_data evt; - if (state) { - /* queue work to avoid recursive calls into rndis_command */ - set_bit(WORK_CONNECTION_EVENT, &priv->work_pending); - queue_work(priv->workqueue, &priv->work); - } else { - evt.data.flags = 0; - evt.data.length = 0; - memset(evt.ap_addr.sa_data, 0, ETH_ALEN); - wireless_send_event(dev->net, SIOCGIWAP, &evt, NULL); - } + /* queue work to avoid recursive calls into rndis_command */ + set_bit(state ? WORK_LINK_UP : WORK_LINK_DOWN, &priv->work_pending); + queue_work(priv->workqueue, &priv->work); } -- cgit v1.2.3 From 5331b96ce3a9f08d3a9e28386e193e8c78f8fdd1 Mon Sep 17 00:00:00 2001 From: Jussi Kivilinna Date: Mon, 2 Jun 2008 18:35:29 +0300 Subject: rndis_wlan: update carrier flag when link state changes Driver wasn't updating netif_carrier on link state changes but assumed link layer was always up. Signed-off-by: Jussi Kivilinna Signed-off-by: John W. Linville --- drivers/net/wireless/rndis_wlan.c | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'drivers/net/wireless/rndis_wlan.c') diff --git a/drivers/net/wireless/rndis_wlan.c b/drivers/net/wireless/rndis_wlan.c index aaeeec80397..c281c0b35ed 100644 --- a/drivers/net/wireless/rndis_wlan.c +++ b/drivers/net/wireless/rndis_wlan.c @@ -2215,6 +2215,8 @@ static void rndis_wext_worker(struct work_struct *work) 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; @@ -2253,6 +2255,8 @@ get_bssid: } if (test_and_clear_bit(WORK_LINK_DOWN, &priv->work_pending)) { + netif_carrier_off(usbdev->net); + evt.data.flags = 0; evt.data.length = 0; memset(evt.ap_addr.sa_data, 0, ETH_ALEN); @@ -2574,6 +2578,7 @@ static int rndis_wext_bind(struct usbnet *dev, struct usb_interface *intf) /* turn radio on */ priv->radio_on = 1; disassociate(dev, 1); + netif_carrier_off(dev->net); /* because rndis_command() sleeps we need to use workqueue */ priv->workqueue = create_singlethread_workqueue("rndis_wlan"); -- cgit v1.2.3 From a67edb9e31a328397516d2285269232e98c5f88b Mon Sep 17 00:00:00 2001 From: Jussi Kivilinna Date: Mon, 2 Jun 2008 18:35:36 +0300 Subject: rndis_wlan: check if set_multicast_list work is already scheduled Don't queue set_multicast_list work if WORK_SET_MULTICAST_LIST flag already set. Signed-off-by: Jussi Kivilinna Signed-off-by: John W. Linville --- drivers/net/wireless/rndis_wlan.c | 3 +++ 1 file changed, 3 insertions(+) (limited to 'drivers/net/wireless/rndis_wlan.c') diff --git a/drivers/net/wireless/rndis_wlan.c b/drivers/net/wireless/rndis_wlan.c index c281c0b35ed..ad46a0ba6e6 100644 --- a/drivers/net/wireless/rndis_wlan.c +++ b/drivers/net/wireless/rndis_wlan.c @@ -2272,6 +2272,9 @@ static void rndis_wext_set_multicast_list(struct net_device *dev) struct usbnet *usbdev = dev->priv; struct rndis_wext_private *priv = get_rndis_wext_priv(usbdev); + if (test_bit(WORK_SET_MULTICAST_LIST, &priv->work_pending)) + return; + set_bit(WORK_SET_MULTICAST_LIST, &priv->work_pending); queue_work(priv->workqueue, &priv->work); } -- cgit v1.2.3 From a19d7292dc7f1c7d8704a353f51c7f1529de953b Mon Sep 17 00:00:00 2001 From: Jussi Kivilinna Date: Mon, 2 Jun 2008 18:35:44 +0300 Subject: rndis_wlan: cleanup: rename and remove local pointers Mixed use of 'dev' and 'usbdev' for usbnet pointer can be confusing. So changing all 'usbnet *dev' to 'usbnet *usbdev'. Also remove 'net_device *net' pointer from 'rndis_wext_bind' as 'usbdev->net' were already used where needed. Signed-off-by: Jussi Kivilinna Signed-off-by: John W. Linville --- drivers/net/wireless/rndis_wlan.c | 74 +++++++++++++++++++-------------------- 1 file changed, 37 insertions(+), 37 deletions(-) (limited to 'drivers/net/wireless/rndis_wlan.c') diff --git a/drivers/net/wireless/rndis_wlan.c b/drivers/net/wireless/rndis_wlan.c index ad46a0ba6e6..8505d8bcb69 100644 --- a/drivers/net/wireless/rndis_wlan.c +++ b/drivers/net/wireless/rndis_wlan.c @@ -2279,9 +2279,9 @@ static void rndis_wext_set_multicast_list(struct net_device *dev) queue_work(priv->workqueue, &priv->work); } -static void rndis_wext_link_change(struct usbnet *dev, int state) +static void rndis_wext_link_change(struct usbnet *usbdev, int state) { - struct rndis_wext_private *priv = get_rndis_wext_priv(dev); + struct rndis_wext_private *priv = get_rndis_wext_priv(usbdev); /* queue work to avoid recursive calls into rndis_command */ set_bit(state ? WORK_LINK_UP : WORK_LINK_DOWN, &priv->work_pending); @@ -2289,7 +2289,7 @@ static void rndis_wext_link_change(struct usbnet *dev, int state) } -static int rndis_wext_get_caps(struct usbnet *dev) +static int rndis_wext_get_caps(struct usbnet *usbdev) { struct { __le32 num_items; @@ -2297,18 +2297,18 @@ static int rndis_wext_get_caps(struct usbnet *dev) } networks_supported; int len, retval, i, n; __le32 tx_power; - struct rndis_wext_private *priv = get_rndis_wext_priv(dev); + struct rndis_wext_private *priv = get_rndis_wext_priv(usbdev); /* determine if supports setting txpower */ len = sizeof(tx_power); - retval = rndis_query_oid(dev, OID_802_11_TX_POWER_LEVEL, &tx_power, - &len); + retval = rndis_query_oid(usbdev, OID_802_11_TX_POWER_LEVEL, &tx_power, + &len); if (retval == 0 && le32_to_cpu(tx_power) != 0xFF) priv->caps |= CAP_SUPPORT_TXPOWER; /* determine supported modes */ len = sizeof(networks_supported); - retval = rndis_query_oid(dev, OID_802_11_NETWORK_TYPES_SUPPORTED, + retval = rndis_query_oid(usbdev, OID_802_11_NETWORK_TYPES_SUPPORTED, &networks_supported, &len); if (retval >= 0) { n = le32_to_cpu(networks_supported.num_items); @@ -2447,9 +2447,9 @@ end: } -static int bcm4320_early_init(struct usbnet *dev) +static int bcm4320_early_init(struct usbnet *usbdev) { - struct rndis_wext_private *priv = get_rndis_wext_priv(dev); + struct rndis_wext_private *priv = get_rndis_wext_priv(usbdev); char buf[8]; /* Early initialization settings, setting these won't have effect @@ -2497,27 +2497,26 @@ static int bcm4320_early_init(struct usbnet *dev) else priv->param_workaround_interval = modparam_workaround_interval; - rndis_set_config_parameter_str(dev, "Country", priv->param_country); - rndis_set_config_parameter_str(dev, "FrameBursting", + rndis_set_config_parameter_str(usbdev, "Country", priv->param_country); + rndis_set_config_parameter_str(usbdev, "FrameBursting", priv->param_frameburst ? "1" : "0"); - rndis_set_config_parameter_str(dev, "Afterburner", + rndis_set_config_parameter_str(usbdev, "Afterburner", priv->param_afterburner ? "1" : "0"); sprintf(buf, "%d", priv->param_power_save); - rndis_set_config_parameter_str(dev, "PowerSaveMode", buf); + rndis_set_config_parameter_str(usbdev, "PowerSaveMode", buf); sprintf(buf, "%d", priv->param_power_output); - rndis_set_config_parameter_str(dev, "PwrOut", buf); + rndis_set_config_parameter_str(usbdev, "PwrOut", buf); sprintf(buf, "%d", priv->param_roamtrigger); - rndis_set_config_parameter_str(dev, "RoamTrigger", buf); + rndis_set_config_parameter_str(usbdev, "RoamTrigger", buf); sprintf(buf, "%d", priv->param_roamdelta); - rndis_set_config_parameter_str(dev, "RoamDelta", buf); + rndis_set_config_parameter_str(usbdev, "RoamDelta", buf); return 0; } -static int rndis_wext_bind(struct usbnet *dev, struct usb_interface *intf) +static int rndis_wext_bind(struct usbnet *usbdev, struct usb_interface *intf) { - struct net_device *net = dev->net; struct rndis_wext_private *priv; int retval, len; __le32 tmp; @@ -2530,18 +2529,18 @@ static int rndis_wext_bind(struct usbnet *dev, struct usb_interface *intf) /* These have to be initialized before calling generic_rndis_bind(). * Otherwise we'll be in big trouble in rndis_wext_early_init(). */ - dev->driver_priv = priv; + usbdev->driver_priv = priv; memset(priv, 0, sizeof(*priv)); memset(priv->name, 0, sizeof(priv->name)); strcpy(priv->name, "IEEE802.11"); - net->wireless_handlers = &rndis_iw_handlers; - priv->usbdev = dev; + usbdev->net->wireless_handlers = &rndis_iw_handlers; + priv->usbdev = usbdev; mutex_init(&priv->command_lock); spin_lock_init(&priv->stats_lock); /* try bind rndis_host */ - retval = generic_rndis_bind(dev, intf, FLAG_RNDIS_PHYM_WIRELESS); + retval = generic_rndis_bind(usbdev, intf, FLAG_RNDIS_PHYM_WIRELESS); if (retval < 0) goto fail; @@ -2552,20 +2551,21 @@ static int rndis_wext_bind(struct usbnet *dev, struct usb_interface *intf) * rndis_host wants to avoid all OID as much as possible * so do promisc/multicast handling in rndis_wext. */ - dev->net->set_multicast_list = rndis_wext_set_multicast_list; + usbdev->net->set_multicast_list = rndis_wext_set_multicast_list; tmp = RNDIS_PACKET_TYPE_DIRECTED | RNDIS_PACKET_TYPE_BROADCAST; - retval = rndis_set_oid(dev, OID_GEN_CURRENT_PACKET_FILTER, &tmp, + retval = rndis_set_oid(usbdev, OID_GEN_CURRENT_PACKET_FILTER, &tmp, sizeof(tmp)); len = sizeof(tmp); - retval = rndis_query_oid(dev, OID_802_3_MAXIMUM_LIST_SIZE, &tmp, &len); + retval = rndis_query_oid(usbdev, OID_802_3_MAXIMUM_LIST_SIZE, &tmp, + &len); priv->multicast_size = le32_to_cpu(tmp); if (retval < 0 || priv->multicast_size < 0) priv->multicast_size = 0; if (priv->multicast_size > 0) - dev->net->flags |= IFF_MULTICAST; + usbdev->net->flags |= IFF_MULTICAST; else - dev->net->flags &= ~IFF_MULTICAST; + usbdev->net->flags &= ~IFF_MULTICAST; priv->iwstats.qual.qual = 0; priv->iwstats.qual.level = 0; @@ -2575,13 +2575,13 @@ static int rndis_wext_bind(struct usbnet *dev, struct usb_interface *intf) | IW_QUAL_QUAL_INVALID | IW_QUAL_LEVEL_INVALID; - rndis_wext_get_caps(dev); - set_default_iw_params(dev); + rndis_wext_get_caps(usbdev); + set_default_iw_params(usbdev); /* turn radio on */ priv->radio_on = 1; - disassociate(dev, 1); - netif_carrier_off(dev->net); + disassociate(usbdev, 1); + netif_carrier_off(usbdev->net); /* because rndis_command() sleeps we need to use workqueue */ priv->workqueue = create_singlethread_workqueue("rndis_wlan"); @@ -2598,12 +2598,12 @@ fail: } -static void rndis_wext_unbind(struct usbnet *dev, struct usb_interface *intf) +static void rndis_wext_unbind(struct usbnet *usbdev, struct usb_interface *intf) { - struct rndis_wext_private *priv = get_rndis_wext_priv(dev); + struct rndis_wext_private *priv = get_rndis_wext_priv(usbdev); /* turn radio off */ - disassociate(dev, 0); + disassociate(usbdev, 0); cancel_delayed_work_sync(&priv->stats_work); cancel_work_sync(&priv->work); @@ -2614,13 +2614,13 @@ static void rndis_wext_unbind(struct usbnet *dev, struct usb_interface *intf) kfree(priv->wpa_ie); kfree(priv); - rndis_unbind(dev, intf); + rndis_unbind(usbdev, intf); } -static int rndis_wext_reset(struct usbnet *dev) +static int rndis_wext_reset(struct usbnet *usbdev) { - return deauthenticate(dev); + return deauthenticate(usbdev); } -- cgit v1.2.3 From bb8649d42989eddf9c7d128114c1adcffe9eef54 Mon Sep 17 00:00:00 2001 From: Jussi Kivilinna Date: Thu, 12 Jun 2008 20:19:01 +0300 Subject: rndis_wlan: use kzalloc to allocate private data rndis_wlan used kmalloc to allocate private data structure and leaving data uninitialized, but later assumed to be set zero. Signed-off-by: Jussi Kivilinna Signed-off-by: John W. Linville --- drivers/net/wireless/rndis_wlan.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) (limited to 'drivers/net/wireless/rndis_wlan.c') diff --git a/drivers/net/wireless/rndis_wlan.c b/drivers/net/wireless/rndis_wlan.c index 8505d8bcb69..6eb487dcc42 100644 --- a/drivers/net/wireless/rndis_wlan.c +++ b/drivers/net/wireless/rndis_wlan.c @@ -2522,7 +2522,7 @@ static int rndis_wext_bind(struct usbnet *usbdev, struct usb_interface *intf) __le32 tmp; /* allocate rndis private data */ - priv = kmalloc(sizeof(struct rndis_wext_private), GFP_KERNEL); + priv = kzalloc(sizeof(struct rndis_wext_private), GFP_KERNEL); if (!priv) return -ENOMEM; @@ -2530,8 +2530,6 @@ static int rndis_wext_bind(struct usbnet *usbdev, struct usb_interface *intf) * Otherwise we'll be in big trouble in rndis_wext_early_init(). */ usbdev->driver_priv = priv; - memset(priv, 0, sizeof(*priv)); - memset(priv->name, 0, sizeof(priv->name)); strcpy(priv->name, "IEEE802.11"); usbdev->net->wireless_handlers = &rndis_iw_handlers; priv->usbdev = usbdev; -- cgit v1.2.3 From 90d07349f8d754b89de8c61bdef9f95688900f30 Mon Sep 17 00:00:00 2001 From: Jussi Kivilinna Date: Thu, 12 Jun 2008 20:19:19 +0300 Subject: rndis_wlan: preallocate command buffer for set/get_oid Reduce amount of kmalloc/kfree calls in set/get_oid by preallocating command buffer. Signed-off-by: Jussi Kivilinna Signed-off-by: John W. Linville --- drivers/net/wireless/rndis_wlan.c | 47 +++++++++++++++++++++++++++------------ 1 file changed, 33 insertions(+), 14 deletions(-) (limited to 'drivers/net/wireless/rndis_wlan.c') diff --git a/drivers/net/wireless/rndis_wlan.c b/drivers/net/wireless/rndis_wlan.c index 6eb487dcc42..a0ad8e781dd 100644 --- a/drivers/net/wireless/rndis_wlan.c +++ b/drivers/net/wireless/rndis_wlan.c @@ -314,6 +314,8 @@ enum wpa_key_mgmt { KEY_MGMT_802_1X, KEY_MGMT_PSK, KEY_MGMT_NONE, #define WORK_LINK_DOWN (1<<1) #define WORK_SET_MULTICAST_LIST (1<<2) +#define COMMAND_BUFFER_SIZE (CONTROL_BUFFER_SIZE + sizeof(struct rndis_set)) + /* RNDIS device private data */ struct rndis_wext_private { char name[32]; @@ -362,6 +364,8 @@ struct rndis_wext_private { u8 *wpa_ie; int wpa_cipher_pair; int wpa_cipher_group; + + u8 command_buffer[COMMAND_BUFFER_SIZE]; }; @@ -428,18 +432,23 @@ static int rndis_query_oid(struct usbnet *dev, __le32 oid, void *data, int *len) buflen = *len + sizeof(*u.get); if (buflen < CONTROL_BUFFER_SIZE) buflen = CONTROL_BUFFER_SIZE; - u.buf = kmalloc(buflen, GFP_KERNEL); - if (!u.buf) - return -ENOMEM; + + if (buflen > COMMAND_BUFFER_SIZE) { + u.buf = kmalloc(buflen, GFP_KERNEL); + if (!u.buf) + return -ENOMEM; + } else { + u.buf = priv->command_buffer; + } + + mutex_lock(&priv->command_lock); + memset(u.get, 0, sizeof *u.get); u.get->msg_type = RNDIS_MSG_QUERY; u.get->msg_len = ccpu2(sizeof *u.get); u.get->oid = oid; - mutex_lock(&priv->command_lock); ret = rndis_command(dev, u.header); - mutex_unlock(&priv->command_lock); - if (ret == 0) { ret = le32_to_cpu(u.get_c->len); *len = (*len > ret) ? ret : *len; @@ -447,7 +456,10 @@ static int rndis_query_oid(struct usbnet *dev, __le32 oid, void *data, int *len) ret = rndis_error_status(u.get_c->status); } - kfree(u.buf); + mutex_unlock(&priv->command_lock); + + if (u.buf != priv->command_buffer) + kfree(u.buf); return ret; } @@ -466,9 +478,16 @@ static int rndis_set_oid(struct usbnet *dev, __le32 oid, void *data, int len) buflen = len + sizeof(*u.set); if (buflen < CONTROL_BUFFER_SIZE) buflen = CONTROL_BUFFER_SIZE; - u.buf = kmalloc(buflen, GFP_KERNEL); - if (!u.buf) - return -ENOMEM; + + if (buflen > COMMAND_BUFFER_SIZE) { + u.buf = kmalloc(buflen, GFP_KERNEL); + if (!u.buf) + return -ENOMEM; + } else { + u.buf = priv->command_buffer; + } + + mutex_lock(&priv->command_lock); memset(u.set, 0, sizeof *u.set); u.set->msg_type = RNDIS_MSG_SET; @@ -479,14 +498,14 @@ static int rndis_set_oid(struct usbnet *dev, __le32 oid, void *data, int len) u.set->handle = ccpu2(0); memcpy(u.buf + sizeof(*u.set), data, len); - mutex_lock(&priv->command_lock); ret = rndis_command(dev, u.header); - mutex_unlock(&priv->command_lock); - if (ret == 0) ret = rndis_error_status(u.set_c->status); - kfree(u.buf); + mutex_unlock(&priv->command_lock); + + if (u.buf != priv->command_buffer) + kfree(u.buf); return ret; } -- cgit v1.2.3 From 5720508d9ad9a82927875252b7a19ba2b45f11f8 Mon Sep 17 00:00:00 2001 From: "Robert P. J. Day" Date: Thu, 12 Jun 2008 15:34:42 -0400 Subject: rndis_wlan: Use kernel-supplied ARRAY_SIZE() macro. Signed-off-by: Robert P. J. Day Signed-off-by: John W. Linville --- drivers/net/wireless/rndis_wlan.c | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) (limited to 'drivers/net/wireless/rndis_wlan.c') diff --git a/drivers/net/wireless/rndis_wlan.c b/drivers/net/wireless/rndis_wlan.c index a0ad8e781dd..a36d2c85e26 100644 --- a/drivers/net/wireless/rndis_wlan.c +++ b/drivers/net/wireless/rndis_wlan.c @@ -640,8 +640,7 @@ static void dsconfig_to_freq(unsigned int dsconfig, struct iw_freq *freq) static int freq_to_dsconfig(struct iw_freq *freq, unsigned int *dsconfig) { if (freq->m < 1000 && freq->e == 0) { - if (freq->m >= 1 && - freq->m <= (sizeof(freq_chan) / sizeof(freq_chan[0]))) + if (freq->m >= 1 && freq->m <= ARRAY_SIZE(freq_chan)) *dsconfig = freq_chan[freq->m - 1] * 1000; else return -1; @@ -1179,10 +1178,9 @@ static int rndis_iw_get_range(struct net_device *dev, range->throughput = 11 * 1000 * 1000 / 2; } - range->num_channels = (sizeof(freq_chan)/sizeof(freq_chan[0])); + range->num_channels = ARRAY_SIZE(freq_chan); - for (i = 0; i < (sizeof(freq_chan)/sizeof(freq_chan[0])) && - i < IW_MAX_FREQUENCIES; i++) { + for (i = 0; i < ARRAY_SIZE(freq_chan) && i < IW_MAX_FREQUENCIES; i++) { range->freq[i].i = i + 1; range->freq[i].m = freq_chan[i] * 100000; range->freq[i].e = 1; -- cgit v1.2.3 From ccc580571cf0799d0460a085a7632b77753f083e Mon Sep 17 00:00:00 2001 From: "David S. Miller" Date: Mon, 16 Jun 2008 18:50:49 -0700 Subject: wext: Emit event stream entries correctly when compat. Three major portions to this change: 1) Add IW_EV_COMPAT_LCP_LEN, IW_EV_COMPAT_POINT_OFF, and IW_EV_COMPAT_POINT_LEN helper defines. 2) Delete iw_stream_check_add_*(), they are unused. 3) Add iw_request_info argument to iwe_stream_add_*(), and use it to size the event and pointer lengths correctly depending upon whether IW_REQUEST_FLAG_COMPAT is set or not. 4) The mechanical transformations to the drivers and wireless stack bits to get the iw_request_info passed down into the routines modified in #3. Also, explicit references to IW_EV_LCP_LEN are replaced with iwe_stream_lcp_len(info). With a lot of help and bug fixes from Masakazu Mokuno. Signed-off-by: David S. Miller --- drivers/net/wireless/rndis_wlan.c | 32 +++++++++++++++++--------------- 1 file changed, 17 insertions(+), 15 deletions(-) (limited to 'drivers/net/wireless/rndis_wlan.c') diff --git a/drivers/net/wireless/rndis_wlan.c b/drivers/net/wireless/rndis_wlan.c index a36d2c85e26..65c50025c88 100644 --- a/drivers/net/wireless/rndis_wlan.c +++ b/drivers/net/wireless/rndis_wlan.c @@ -1648,7 +1648,9 @@ static int rndis_iw_set_scan(struct net_device *dev, static char *rndis_translate_scan(struct net_device *dev, - char *cev, char *end_buf, struct ndis_80211_bssid_ex *bssid) + struct iw_request_info *info, char *cev, + char *end_buf, + struct ndis_80211_bssid_ex *bssid) { #ifdef DEBUG struct usbnet *usbdev = dev->priv; @@ -1667,14 +1669,14 @@ static char *rndis_translate_scan(struct net_device *dev, iwe.cmd = SIOCGIWAP; iwe.u.ap_addr.sa_family = ARPHRD_ETHER; memcpy(iwe.u.ap_addr.sa_data, bssid->mac, ETH_ALEN); - cev = iwe_stream_add_event(cev, end_buf, &iwe, IW_EV_ADDR_LEN); + cev = iwe_stream_add_event(info, cev, end_buf, &iwe, IW_EV_ADDR_LEN); devdbg(usbdev, "SSID(%d) %s", le32_to_cpu(bssid->ssid.length), bssid->ssid.essid); iwe.cmd = SIOCGIWESSID; iwe.u.essid.length = le32_to_cpu(bssid->ssid.length); iwe.u.essid.flags = 1; - cev = iwe_stream_add_point(cev, end_buf, &iwe, bssid->ssid.essid); + cev = iwe_stream_add_point(info, cev, end_buf, &iwe, bssid->ssid.essid); devdbg(usbdev, "MODE %d", le32_to_cpu(bssid->net_infra)); iwe.cmd = SIOCGIWMODE; @@ -1690,12 +1692,12 @@ static char *rndis_translate_scan(struct net_device *dev, iwe.u.mode = IW_MODE_AUTO; break; } - cev = iwe_stream_add_event(cev, end_buf, &iwe, IW_EV_UINT_LEN); + cev = iwe_stream_add_event(info, cev, end_buf, &iwe, IW_EV_UINT_LEN); devdbg(usbdev, "FREQ %d kHz", le32_to_cpu(bssid->config.ds_config)); iwe.cmd = SIOCGIWFREQ; dsconfig_to_freq(le32_to_cpu(bssid->config.ds_config), &iwe.u.freq); - cev = iwe_stream_add_event(cev, end_buf, &iwe, IW_EV_FREQ_LEN); + cev = iwe_stream_add_event(info, cev, end_buf, &iwe, IW_EV_FREQ_LEN); devdbg(usbdev, "QUAL %d", le32_to_cpu(bssid->rssi)); iwe.cmd = IWEVQUAL; @@ -1704,7 +1706,7 @@ static char *rndis_translate_scan(struct net_device *dev, iwe.u.qual.updated = IW_QUAL_QUAL_UPDATED | IW_QUAL_LEVEL_UPDATED | IW_QUAL_NOISE_INVALID; - cev = iwe_stream_add_event(cev, end_buf, &iwe, IW_EV_QUAL_LEN); + cev = iwe_stream_add_event(info, cev, end_buf, &iwe, IW_EV_QUAL_LEN); devdbg(usbdev, "ENCODE %d", le32_to_cpu(bssid->privacy)); iwe.cmd = SIOCGIWENCODE; @@ -1714,10 +1716,10 @@ static char *rndis_translate_scan(struct net_device *dev, else iwe.u.data.flags = IW_ENCODE_ENABLED | IW_ENCODE_NOKEY; - cev = iwe_stream_add_point(cev, end_buf, &iwe, NULL); + cev = iwe_stream_add_point(info, cev, end_buf, &iwe, NULL); devdbg(usbdev, "RATES:"); - current_val = cev + IW_EV_LCP_LEN; + current_val = cev + iwe_stream_lcp_len(info); iwe.cmd = SIOCGIWRATE; for (i = 0; i < sizeof(bssid->rates); i++) { if (bssid->rates[i] & 0x7f) { @@ -1725,13 +1727,13 @@ static char *rndis_translate_scan(struct net_device *dev, ((bssid->rates[i] & 0x7f) * 500000); devdbg(usbdev, " %d", iwe.u.bitrate.value); - current_val = iwe_stream_add_value(cev, + current_val = iwe_stream_add_value(info, cev, current_val, end_buf, &iwe, IW_EV_PARAM_LEN); } } - if ((current_val - cev) > IW_EV_LCP_LEN) + if ((current_val - cev) > iwe_stream_lcp_len(info)) cev = current_val; beacon = le32_to_cpu(bssid->config.beacon_period); @@ -1739,14 +1741,14 @@ static char *rndis_translate_scan(struct net_device *dev, iwe.cmd = IWEVCUSTOM; snprintf(sbuf, sizeof(sbuf), "bcn_int=%d", beacon); iwe.u.data.length = strlen(sbuf); - cev = iwe_stream_add_point(cev, end_buf, &iwe, sbuf); + cev = iwe_stream_add_point(info, cev, end_buf, &iwe, sbuf); atim = le32_to_cpu(bssid->config.atim_window); devdbg(usbdev, "ATIM %d", atim); iwe.cmd = IWEVCUSTOM; snprintf(sbuf, sizeof(sbuf), "atim=%u", atim); iwe.u.data.length = strlen(sbuf); - cev = iwe_stream_add_point(cev, end_buf, &iwe, sbuf); + cev = iwe_stream_add_point(info, cev, end_buf, &iwe, sbuf); ie = (void *)(bssid->ies + sizeof(struct ndis_80211_fixed_ies)); ie_len = min(bssid_len - (int)sizeof(*bssid), @@ -1760,7 +1762,7 @@ static char *rndis_translate_scan(struct net_device *dev, (ie->id == MFIE_TYPE_RSN) ? 2 : 1); iwe.cmd = IWEVGENIE; iwe.u.data.length = min(ie->len + 2, MAX_WPA_IE_LEN); - cev = iwe_stream_add_point(cev, end_buf, &iwe, + cev = iwe_stream_add_point(info, cev, end_buf, &iwe, (u8 *)ie); } @@ -1803,8 +1805,8 @@ static int rndis_iw_get_scan(struct net_device *dev, devdbg(usbdev, "SIOCGIWSCAN: %d BSSIDs found", count); while (count && ((void *)bssid + bssid_len) <= (buf + len)) { - cev = rndis_translate_scan(dev, cev, extra + IW_SCAN_MAX_DATA, - bssid); + cev = rndis_translate_scan(dev, info, cev, + extra + IW_SCAN_MAX_DATA, bssid); bssid = (void *)bssid + bssid_len; bssid_len = le32_to_cpu(bssid->length); count--; -- cgit v1.2.3 From 818727badc14ce57dc099a075b05505d50b7956e Mon Sep 17 00:00:00 2001 From: Jussi Kivilinna Date: Wed, 18 Jun 2008 15:40:12 +0300 Subject: rndis_host: pass buffer length to rndis_command Pass buffer length to rndis_command so that rndis_command can read full response buffer from device instead of max CONTROL_BUFFER_SIZE bytes. Signed-off-by: Jussi Kivilinna Signed-off-by: Jeff Garzik --- drivers/net/wireless/rndis_wlan.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers/net/wireless/rndis_wlan.c') diff --git a/drivers/net/wireless/rndis_wlan.c b/drivers/net/wireless/rndis_wlan.c index a36d2c85e26..f001f2afd05 100644 --- a/drivers/net/wireless/rndis_wlan.c +++ b/drivers/net/wireless/rndis_wlan.c @@ -448,7 +448,7 @@ static int rndis_query_oid(struct usbnet *dev, __le32 oid, void *data, int *len) u.get->msg_len = ccpu2(sizeof *u.get); u.get->oid = oid; - ret = rndis_command(dev, u.header); + ret = rndis_command(dev, u.header, buflen); if (ret == 0) { ret = le32_to_cpu(u.get_c->len); *len = (*len > ret) ? ret : *len; @@ -498,7 +498,7 @@ static int rndis_set_oid(struct usbnet *dev, __le32 oid, void *data, int len) u.set->handle = ccpu2(0); memcpy(u.buf + sizeof(*u.set), data, len); - ret = rndis_command(dev, u.header); + ret = rndis_command(dev, u.header, buflen); if (ret == 0) ret = rndis_error_status(u.set_c->status); -- cgit v1.2.3