RE: [RFC/PATCH 6/13] d80211: remove obsolete stuff

2006-03-21 Thread Simon Barber
Yes, fully agreed - and the hardware's pre-beacon interrupt would cause
the beacon function to create a beacon frame and put it into the queue
(dev_queue_xmit on the master device). The beacon frame would the be
passed to the hardware through the normal run_queue that follows.

Simon 

-Original Message-
From: Jouni Malinen 
Sent: Wednesday, March 15, 2006 4:48 PM
To: Simon Barber
Cc: Jiri Benc; netdev@vger.kernel.org
Subject: Re: [RFC/PATCH 6/13] d80211: remove obsolete stuff

On Wed, Mar 15, 2006 at 04:41:56PM -0800, Simon Barber wrote:
> The more natural way for beacons to flow from the 80211.o to the low 
> level driver would be for beacons to be passed down just like any 
> other
> 802.11 frame is passed down - rather than having a special case for 
> beacons and buffered MC data, where they are pulled. I would suggest 
> making the qdisc aware of beacons, and then there is no special 
> interface for passing beacons down - they are passed down just like 
> other frames, with a special queue ID reserved for beacons and 
> buffered multicast.
> 
> This would simplify the 80211.o/low level interface.

Sure, but it would also require good synchronization for sending the
beacons just before they are needed for transmission.. If the wlan
hardware implementation provides support for interrupts that request
beacons at proper times, being able to use them for this is quite
convenient.

-- 
Jouni MalinenPGP id EFC895FA
-
To unsubscribe from this list: send the line "unsubscribe netdev" in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [RFC/PATCH 6/13] d80211: remove obsolete stuff

2006-03-16 Thread Jouni Malinen
On Thu, Mar 16, 2006 at 05:45:48PM +0100, Jiri Benc wrote:
> On Wed, 15 Mar 2006 16:36:16 -0800, Jouni Malinen wrote:

> See the patch below. Is it viable?

I'll test this with our low-level driver.

> > This and similar change for ieee80211_get_buffered_bc() add more
> > requirements for the low-level driver. It used to be enough to just know
> > that the low-level code should ask for up to N beacon frames. However,
> > with this change, the low-level driver would need to maintain a list of
> > ifindexes for the virtual interfaces. This is somewhat against the
> > original design of hiding all the virtual interfaces from low-level
> > code.
> 
> I like the approach, but I'm afraid it's not generic enough. The new
> code should cover all possibilities (even such hypothetical case as a
> card capable of multiple APs in its firmware with host-buffering of
> frames for STAs in PS mode).

Your proposed change does not cover at least one case..

> In a typical case of only-one-AP capable card the code will be nearly
> the same. In your case it indeed means one extra list.

Agreed.

> Yes, I wanted to add ifindex into ieee80211_if_conf but apparently
> forgot to. See patch below.

OK. I'll test this.

> This patch fixes some problems in interface configuration.
> 
> - Pass interface ID to add_interface and remove_interface callbacks. This ID
>   is used by a driver when calling ieee80211_beacon_get and
>   ieee80211_get_buffered_bc functions.

There is one more corner case that I did not remember yesterday: Atheros
XR. It is using two BSSIDs and two different beacons per network
interface (or at least our implementation of it is doing this; in
theory, it could be possible to do this with two interfaces and
bridging, but it gets somewhat complex for couple of cases)..

With the current d80211 implementation, this can be handled by just
multiplying bss_count with two. With per-ifindex call, this is more
difficult. One option would be to modify the interface to return more
than one skb in this case.. This might actually be useful way to handle
all indexes if the beacons are to be sent at the same time. However, if
beacons are to be sent at different times for different BSSes, it may be
easier to just maintain the current mechanism (one call per virtual AP)
and allow XR to return two beacon frames.

-- 
Jouni MalinenPGP id EFC895FA
-
To unsubscribe from this list: send the line "unsubscribe netdev" in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [RFC/PATCH 6/13] d80211: remove obsolete stuff

2006-03-16 Thread Jiri Benc
On Wed, 15 Mar 2006 16:36:16 -0800, Jouni Malinen wrote:
> In theory, the low-level driver can determine the needed mask itself.
> However, it would need to be somehow notified of allowed BSSID values.
> By removing this entry, this information would need to fetched from
> somewhere else before interfaces are added.
> 
> Most hardware implementations have storage for a single MAC address in
> EEPROM (or something similar) and in some cases, no addresses are stored
> with the card and some external store is needed for this. We have been
> using this mechanism of passing the information from user space to avoid
> problems in figuring out board specific mechanisms for storing extra
> data. Do you have any ideas on what would be the best of getting this
> information configured after this change?

See the patch below. Is it viable?

> This and similar change for ieee80211_get_buffered_bc() add more
> requirements for the low-level driver. It used to be enough to just know
> that the low-level code should ask for up to N beacon frames. However,
> with this change, the low-level driver would need to maintain a list of
> ifindexes for the virtual interfaces. This is somewhat against the
> original design of hiding all the virtual interfaces from low-level
> code.

I like the approach, but I'm afraid it's not generic enough. The new
code should cover all possibilities (even such hypothetical case as a
card capable of multiple APs in its firmware with host-buffering of
frames for STAs in PS mode).

In a typical case of only-one-AP capable card the code will be nearly
the same. In your case it indeed means one extra list.

> I think the ifindex values could be made available from add/remove
> interface calls that you added. Was that what you had in mind or is
> there another mechanism for getting the needed ifindexes down?

Yes, I wanted to add ifindex into ieee80211_if_conf but apparently
forgot to. See patch below.

>8

This patch fixes some problems in interface configuration.

- Pass interface ID to add_interface and remove_interface callbacks. This ID
  is used by a driver when calling ieee80211_beacon_get and
  ieee80211_get_buffered_bc functions.
- New configuration callback, config_interface, is introduced.
- Allow BSSID to be set per-interface.

Signed-off-by: Jiri Benc <[EMAIL PROTECTED]>

Index: dscape/include/net/d80211.h
===
--- dscape.orig/include/net/d80211.h2006-03-06 16:23:57.0 +0100
+++ dscape/include/net/d80211.h 2006-03-16 16:10:08.0 +0100
@@ -286,8 +286,6 @@ struct ieee80211_conf {
 
int atheros_xr;
 
-   u8 client_bssid[ETH_ALEN];
-
/* Following five fields are used for IEEE 802.11H */
unsigned int radar_detect;
unsigned int spect_mgmt;
@@ -310,11 +308,18 @@ struct ieee80211_conf {
 #define IEEE80211_SUB_IF_TYPE_WDS  0x5A580211
 #define IEEE80211_SUB_IF_TYPE_VLAN 0x00080211
 
-struct ieee80211_if_conf {
+struct ieee80211_if_init_conf {
+   int if_id;  /* not valid for monitor interface */
int type;
void *mac_addr;
 };
 
+struct ieee80211_if_conf {
+   int type;   /* just for convenience; doesn't change during
+* the live of the interface */
+   u8 *bssid;
+};
+
 typedef enum { ALG_NONE, ALG_WEP, ALG_TKIP, ALG_CCMP, ALG_NULL }
 ieee80211_key_alg;
 
@@ -476,17 +481,22 @@ struct ieee80211_hw {
 * of open() and add_interface() handler has to be non-NULL. If
 * add_interface() is NULL, one STA interface is permitted only. */
int (*add_interface)(struct net_device *dev,
-struct ieee80211_if_conf *conf);
+struct ieee80211_if_init_conf *conf);
 
/* Notify a driver that interface is going down. The stop() handler
 * is called prior to this if this is a last interface. */
void (*remove_interface)(struct net_device *dev,
-struct ieee80211_if_conf *conf);
+struct ieee80211_if_init_conf *conf);
 
/* Handler for configuration requests. IEEE 802.11 code calls this
 * function to change hardware configuration, e.g., channel. */
int (*config)(struct net_device *dev, struct ieee80211_conf *conf);
 
+   /* Handler for configuration requests related to interfaces (e.g.
+* BSSID). */
+   int (*config_interface)(struct net_device *dev, int if_id,
+   struct ieee80211_if_conf *conf);
+
/* ieee80211 drivers should use this and not the function in
 * net_device. dev->flags, dev->mc_count and dev->mc_list must not
 * be used; use passed parameters and ieee80211_get_mc_list_item
@@ -674,7 +684,7 @@ void ieee80211_tx_status_irqsafe(struct 
  * low-level is responsible for calling this function before beacon data is
  * needed (e.g., based on hardware interrup

Re: [RFC/PATCH 6/13] d80211: remove obsolete stuff

2006-03-15 Thread Jouni Malinen
On Wed, Mar 15, 2006 at 04:41:56PM -0800, Simon Barber wrote:
> The more natural way for beacons to flow from the 80211.o to the low
> level driver would be for beacons to be passed down just like any other
> 802.11 frame is passed down - rather than having a special case for
> beacons and buffered MC data, where they are pulled. I would suggest
> making the qdisc aware of beacons, and then there is no special
> interface for passing beacons down - they are passed down just like
> other frames, with a special queue ID reserved for beacons and buffered
> multicast.
> 
> This would simplify the 80211.o/low level interface.

Sure, but it would also require good synchronization for sending the
beacons just before they are needed for transmission.. If the wlan
hardware implementation provides support for interrupts that request
beacons at proper times, being able to use them for this is quite
convenient.

-- 
Jouni MalinenPGP id EFC895FA
-
To unsubscribe from this list: send the line "unsubscribe netdev" in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html


RE: [RFC/PATCH 6/13] d80211: remove obsolete stuff

2006-03-15 Thread Simon Barber
The more natural way for beacons to flow from the 80211.o to the low
level driver would be for beacons to be passed down just like any other
802.11 frame is passed down - rather than having a special case for
beacons and buffered MC data, where they are pulled. I would suggest
making the qdisc aware of beacons, and then there is no special
interface for passing beacons down - they are passed down just like
other frames, with a special queue ID reserved for beacons and buffered
multicast.

This would simplify the 80211.o/low level interface.

Simon

-Original Message-
From: [EMAIL PROTECTED] [mailto:[EMAIL PROTECTED]
On Behalf Of Jouni Malinen
Sent: Wednesday, March 15, 2006 4:36 PM
To: Jiri Benc
Cc: netdev@vger.kernel.org
Subject: Re: [RFC/PATCH 6/13] d80211: remove obsolete stuff

On Mon, Mar 06, 2006 at 04:44:26PM +0100, Jiri Benc wrote:

> Because any number of interfaces may be added, bss_devs and sta_devs 
> arrays cannot be fixed-size arrays. We can make them linked lists, but

> they are needed for optimalization only (and even that is questionable

> with subsequent patches). Let's remove them; we will probably want 
> something similar later to speed up packet receiving, but let's not 
> bother ourselves now.

> @@ -277,9 +277,6 @@ struct ieee80211_conf {
>  int antenna_def;
>  int antenna_mode;
>  
> - u8 bssid_mask[ETH_ALEN];/* ff:ff:ff:ff:ff:ff = 1 BSSID
*/
> - int bss_count;

In theory, the low-level driver can determine the needed mask itself.
However, it would need to be somehow notified of allowed BSSID values.
By removing this entry, this information would need to fetched from
somewhere else before interfaces are added.

Most hardware implementations have storage for a single MAC address in
EEPROM (or something similar) and in some cases, no addresses are stored
with the card and some external store is needed for this. We have been
using this mechanism of passing the information from user space to avoid
problems in figuring out board specific mechanisms for storing extra
data. Do you have any ideas on what would be the best of getting this
information configured after this change?

> --- dscape.orig/net/d80211/ieee80211.c2006-03-06
14:10:18.0 +0100
> +++ dscape/net/d80211/ieee80211.c 2006-03-06 14:10:22.0
+0100
> @@ -1569,17 +1569,14 @@ struct sk_buff * ieee80211_beacon_get(st
>   u8 *b_head, *b_tail;
>   int bh_len, bt_len;
>  
> - spin_lock_bh(&local->sub_if_lock);
> - if (bss_idx < 0 || bss_idx >= local->bss_dev_count)
> - bdev = NULL;
> - else {
> - bdev = local->bss_devs[bss_idx];
> + bdev = dev_get_by_index(bss_idx);

This and similar change for ieee80211_get_buffered_bc() add more
requirements for the low-level driver. It used to be enough to just know
that the low-level code should ask for up to N beacon frames. However,
with this change, the low-level driver would need to maintain a list of
ifindexes for the virtual interfaces. This is somewhat against the
original design of hiding all the virtual interfaces from low-level
code.

I think the ifindex values could be made available from add/remove
interface calls that you added. Was that what you had in mind or is
there another mechanism for getting the needed ifindexes down? I need to
understand this bit better in order to be able to modify the low-level
driver to handle this kind of change. At the moment, this change does
not look very good to me because of the extra requirement added for the
low-level code as far as virtual interfaces are concerned.

-- 
Jouni MalinenPGP id EFC895FA
-
To unsubscribe from this list: send the line "unsubscribe netdev" in the
body of a message to [EMAIL PROTECTED] More majordomo info at
http://vger.kernel.org/majordomo-info.html
-
To unsubscribe from this list: send the line "unsubscribe netdev" in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [RFC/PATCH 6/13] d80211: remove obsolete stuff

2006-03-15 Thread Jouni Malinen
On Mon, Mar 06, 2006 at 04:44:26PM +0100, Jiri Benc wrote:

> Because any number of interfaces may be added, bss_devs and sta_devs arrays
> cannot be fixed-size arrays. We can make them linked lists, but they are
> needed for optimalization only (and even that is questionable with
> subsequent patches). Let's remove them; we will probably want something
> similar later to speed up packet receiving, but let's not bother ourselves
> now.

> @@ -277,9 +277,6 @@ struct ieee80211_conf {
>  int antenna_def;
>  int antenna_mode;
>  
> - u8 bssid_mask[ETH_ALEN];/* ff:ff:ff:ff:ff:ff = 1 BSSID */
> - int bss_count;

In theory, the low-level driver can determine the needed mask itself.
However, it would need to be somehow notified of allowed BSSID values.
By removing this entry, this information would need to fetched from
somewhere else before interfaces are added.

Most hardware implementations have storage for a single MAC address in
EEPROM (or something similar) and in some cases, no addresses are stored
with the card and some external store is needed for this. We have been
using this mechanism of passing the information from user space to avoid
problems in figuring out board specific mechanisms for storing extra
data. Do you have any ideas on what would be the best of getting this
information configured after this change?

> --- dscape.orig/net/d80211/ieee80211.c2006-03-06 14:10:18.0 
> +0100
> +++ dscape/net/d80211/ieee80211.c 2006-03-06 14:10:22.0 +0100
> @@ -1569,17 +1569,14 @@ struct sk_buff * ieee80211_beacon_get(st
>   u8 *b_head, *b_tail;
>   int bh_len, bt_len;
>  
> - spin_lock_bh(&local->sub_if_lock);
> - if (bss_idx < 0 || bss_idx >= local->bss_dev_count)
> - bdev = NULL;
> - else {
> - bdev = local->bss_devs[bss_idx];
> + bdev = dev_get_by_index(bss_idx);

This and similar change for ieee80211_get_buffered_bc() add more
requirements for the low-level driver. It used to be enough to just know
that the low-level code should ask for up to N beacon frames. However,
with this change, the low-level driver would need to maintain a list of
ifindexes for the virtual interfaces. This is somewhat against the
original design of hiding all the virtual interfaces from low-level
code.

I think the ifindex values could be made available from add/remove
interface calls that you added. Was that what you had in mind or is
there another mechanism for getting the needed ifindexes down? I need to
understand this bit better in order to be able to modify the low-level
driver to handle this kind of change. At the moment, this change does
not look very good to me because of the extra requirement added for the
low-level code as far as virtual interfaces are concerned.

-- 
Jouni MalinenPGP id EFC895FA
-
To unsubscribe from this list: send the line "unsubscribe netdev" in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [RFC/PATCH 6/13] d80211: remove obsolete stuff

2006-03-06 Thread Jouni Malinen
On Mon, Mar 06, 2006 at 08:07:26PM +0100, Jiri Benc wrote:
> On Mon, 6 Mar 2006 10:49:46 -0800, Jouni Malinen wrote:
> > The reason for this optimization was in even high-end CPUs starting to
> > run out of resources when running one radio with 2007 "virtual STAs",

> Yes, I'm aware of that. But I'm afraid that hard-wired need for STA
> interfaces to have incremental MAC addresses is not acceptable - and
> this fact alone means degrading of performance in case of 2000+ STAs.

Since this is not needed for most normal use cases, this is probably
fine. However, being able to test with large number of STAs is very
useful test case for AP functionality (number of APs crash if you try to
associate that many STAs..) and performance. One approach could be to
add a hash table for address to netdev mapping. If that is not easily
doable, a (hopefully) small patch could of course be maintained
separately, but I would prefer to see this operation mode as something
that is supported in the stack by default.

-- 
Jouni MalinenPGP id EFC895FA
-
To unsubscribe from this list: send the line "unsubscribe netdev" in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [RFC/PATCH 6/13] d80211: remove obsolete stuff

2006-03-06 Thread Jiri Benc
On Mon, 6 Mar 2006 10:49:46 -0800, Jouni Malinen wrote:
> The reason for this optimization was in even high-end CPUs starting to
> run out of resources when running one radio with 2007 "virtual STAs",
> i.e., when testing AP capabilities.. In other words, unless some of your
> other patches improved netdev lookup, more work is likely needed here to
> allow such a test mode to be used.

Yes, I'm aware of that. But I'm afraid that hard-wired need for STA
interfaces to have incremental MAC addresses is not acceptable - and
this fact alone means degrading of performance in case of 2000+ STAs.

-- 
Jiri Benc
SUSE Labs
-
To unsubscribe from this list: send the line "unsubscribe netdev" in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [RFC/PATCH 6/13] d80211: remove obsolete stuff

2006-03-06 Thread Jouni Malinen
On Mon, Mar 06, 2006 at 04:44:26PM +0100, Jiri Benc wrote:

> Because any number of interfaces may be added, bss_devs and sta_devs arrays
> cannot be fixed-size arrays. We can make them linked lists, but they are
> needed for optimalization only (and even that is questionable with
> subsequent patches). Let's remove them; we will probably want something
> similar later to speed up packet receiving, but let's not bother ourselves
> now.

The reason for this optimization was in even high-end CPUs starting to
run out of resources when running one radio with 2007 "virtual STAs",
i.e., when testing AP capabilities.. In other words, unless some of your
other patches improved netdev lookup, more work is likely needed here to
allow such a test mode to be used.

With 2000 netdevs, there were other performance issues, at least with
Linux 2.4.x. If I remember correctly, it took close to half an hour to
just add and remove those netdevs.. ;-) Anyway, after the netdevs were
up, these optimizations were enough to keep CPU load reasonable in a
test case that sent data packets through all the STAs. I have not tested
this with 2.6 kernels, so the area of adding/deleting netdevs may have
already been improved.

-- 
Jouni MalinenPGP id EFC895FA
-
To unsubscribe from this list: send the line "unsubscribe netdev" in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[RFC/PATCH 6/13] d80211: remove obsolete stuff

2006-03-06 Thread Jiri Benc
Because any number of interfaces may be added, bss_devs and sta_devs arrays
cannot be fixed-size arrays. We can make them linked lists, but they are
needed for optimalization only (and even that is questionable with
subsequent patches). Let's remove them; we will probably want something
similar later to speed up packet receiving, but let's not bother ourselves
now.

Also, ieee80211_addr_inc is removed. Choosing of MAC address of a new STA
should be matter of userspace. It's responsibility of the stack not to allow
two STAs with the same MAC address to be up - this feature is introduced in
one of subsequent patches.

Signed-off-by: Jiri Benc <[EMAIL PROTECTED]>

Index: dscape/include/net/d80211.h
===
--- dscape.orig/include/net/d80211.h2006-03-06 14:10:18.0 +0100
+++ dscape/include/net/d80211.h 2006-03-06 14:10:22.0 +0100
@@ -277,9 +277,6 @@ struct ieee80211_conf {
 int antenna_def;
 int antenna_mode;
 
-   u8 bssid_mask[ETH_ALEN];/* ff:ff:ff:ff:ff:ff = 1 BSSID */
-   int bss_count;
-
int atheros_super_ag_compression;
int atheros_super_ag_fast_frame;
int atheros_super_ag_burst;
Index: dscape/net/d80211/ieee80211.c
===
--- dscape.orig/net/d80211/ieee80211.c  2006-03-06 14:10:18.0 +0100
+++ dscape/net/d80211/ieee80211.c   2006-03-06 14:10:22.0 +0100
@@ -1569,17 +1569,14 @@ struct sk_buff * ieee80211_beacon_get(st
u8 *b_head, *b_tail;
int bh_len, bt_len;
 
-   spin_lock_bh(&local->sub_if_lock);
-   if (bss_idx < 0 || bss_idx >= local->bss_dev_count)
-   bdev = NULL;
-   else {
-   bdev = local->bss_devs[bss_idx];
+   bdev = dev_get_by_index(bss_idx);
+   if (bdev) {
sdata = IEEE80211_DEV_TO_SUB_IF(bdev);
ap = &sdata->u.ap;
+   dev_put(bdev);
}
-   spin_unlock_bh(&local->sub_if_lock);
 
-   if (bdev == NULL || ap == NULL || ap->beacon_head == NULL) {
+   if (ap == NULL || ap->beacon_head == NULL) {
 #ifdef CONFIG_D80211_VERBOSE_DEBUG
if (net_ratelimit())
printk(KERN_DEBUG "no beacon data avail for idx=%d "
@@ -1646,19 +1643,15 @@ ieee80211_get_buffered_bc(struct net_dev
ieee80211_txrx_result res = TXRX_DROP;
struct net_device *bdev;
struct ieee80211_sub_if_data *sdata;
-   struct ieee80211_if_ap *bss;
+   struct ieee80211_if_ap *bss = NULL;
 
-   spin_lock_bh(&local->sub_if_lock);
-   if (bss_idx < 0 || bss_idx >= local->bss_dev_count) {
-   bdev = NULL;
-   bss = NULL;
-   } else {
-   bdev = local->bss_devs[bss_idx];
+   bdev = dev_get_by_index(bss_idx);
+   if (bdev) {
sdata = IEEE80211_DEV_TO_SUB_IF(bdev);
bss = &sdata->u.ap;
+   dev_put(bdev);
}
-   spin_unlock_bh(&local->sub_if_lock);
-   if (bdev == NULL || bss == NULL || bss->beacon_head == NULL)
+   if (bss == NULL || bss->beacon_head == NULL)
return NULL;
 
if (bss->dtim_count != 0)
@@ -1911,14 +1904,14 @@ ieee80211_get_wds_dev(struct ieee80211_l
 static struct net_device * ieee80211_own_bssid(struct ieee80211_local *local,
   u8 *addr)
 {
-   int i;
struct net_device *dev = NULL;
+   struct ieee80211_sub_if_data *sdata;
 
spin_lock_bh(&local->sub_if_lock);
-   for (i = 0; i < local->bss_dev_count; i++) {
-   if ((memcmp(local->bss_devs[i]->dev_addr, addr, ETH_ALEN) == 0)
-   ) {
-   dev = local->bss_devs[i];
+   list_for_each_entry(sdata, &local->sub_if_list, list) {
+   if (sdata->type == IEEE80211_SUB_IF_TYPE_AP &&
+   memcmp(addr, sdata->dev->dev_addr, ETH_ALEN) == 0) {
+   dev = sdata->dev;
break;
}
}
@@ -1934,31 +1927,9 @@ static struct net_device * ieee80211_sta
 {
struct list_head *ptr;
int multicast;
-   u8 *own_addr = local->mdev->dev_addr;
 
multicast = a1[0] & 0x01;
 
-   /* Try O(1) lookup for a common case of only one AP being used. */
-   if (own_addr[0] == a1[0] && own_addr[1] == a1[1] &&
-   own_addr[2] == a1[2]) {
-   int index = (((int) a1[3] << 16) | ((int) a1[4] << 8) | a1[5])
-   - (((int) own_addr[3] << 16) |
-  ((int) own_addr[4] << 8) | own_addr[5]);
-   if (index >= 0 && index < local->conf.bss_count &&
-   local->sta_devs[index]) {
-   struct net_device *dev = local->sta_devs[index];
-   struct ieee80211_sub_if_data *sdata;
-   sdata = IEEE80211_DEV_TO_SUB_IF(dev);
-