OpenCores
URL https://opencores.org/ocsvn/test_project/test_project/trunk

Subversion Repositories test_project

[/] [test_project/] [trunk/] [linux_sd_driver/] [net/] [ieee80211/] [softmac/] [ieee80211softmac_module.c] - Blame information for rev 62

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 62 marcus.erl
/*
2
 * Contains some basic softmac functions along with module registration code etc.
3
 *
4
 * Copyright (c) 2005, 2006 Johannes Berg <johannes@sipsolutions.net>
5
 *                          Joseph Jezak <josejx@gentoo.org>
6
 *                          Larry Finger <Larry.Finger@lwfinger.net>
7
 *                          Danny van Dyk <kugelfang@gentoo.org>
8
 *                          Michael Buesch <mbuesch@freenet.de>
9
 *
10
 * This program is free software; you can redistribute it and/or modify it
11
 * under the terms of version 2 of the GNU General Public License as
12
 * published by the Free Software Foundation.
13
 *
14
 * This program is distributed in the hope that it will be useful, but WITHOUT
15
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
16
 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
17
 * more details.
18
 *
19
 * You should have received a copy of the GNU General Public License
20
 * along with this program; if not, write to the Free Software
21
 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301 USA
22
 *
23
 * The full GNU General Public License is included in this distribution in the
24
 * file called COPYING.
25
 */
26
 
27
#include "ieee80211softmac_priv.h"
28
#include <linux/sort.h>
29
#include <linux/etherdevice.h>
30
 
31
struct net_device *alloc_ieee80211softmac(int sizeof_priv)
32
{
33
        struct ieee80211softmac_device *softmac;
34
        struct net_device *dev;
35
 
36
        dev = alloc_ieee80211(sizeof(*softmac) + sizeof_priv);
37
        if (!dev)
38
                return NULL;
39
        softmac = ieee80211_priv(dev);
40
        softmac->wq = create_freezeable_workqueue("softmac");
41
        if (!softmac->wq) {
42
                free_ieee80211(dev);
43
                return NULL;
44
        }
45
 
46
        softmac->dev = dev;
47
        softmac->ieee = netdev_priv(dev);
48
        spin_lock_init(&softmac->lock);
49
 
50
        softmac->ieee->handle_auth = ieee80211softmac_auth_resp;
51
        softmac->ieee->handle_deauth = ieee80211softmac_deauth_resp;
52
        softmac->ieee->handle_assoc_response = ieee80211softmac_handle_assoc_response;
53
        softmac->ieee->handle_reassoc_request = ieee80211softmac_handle_reassoc_req;
54
        softmac->ieee->handle_disassoc = ieee80211softmac_handle_disassoc;
55
        softmac->ieee->handle_beacon = ieee80211softmac_handle_beacon;
56
        softmac->scaninfo = NULL;
57
 
58
        softmac->associnfo.scan_retry = IEEE80211SOFTMAC_ASSOC_SCAN_RETRY_LIMIT;
59
 
60
        /* TODO: initialise all the other callbacks in the ieee struct
61
         *       (once they're written)
62
         */
63
 
64
        INIT_LIST_HEAD(&softmac->auth_queue);
65
        INIT_LIST_HEAD(&softmac->network_list);
66
        INIT_LIST_HEAD(&softmac->events);
67
 
68
        mutex_init(&softmac->associnfo.mutex);
69
        INIT_DELAYED_WORK(&softmac->associnfo.work, ieee80211softmac_assoc_work);
70
        INIT_DELAYED_WORK(&softmac->associnfo.timeout, ieee80211softmac_assoc_timeout);
71
        softmac->start_scan = ieee80211softmac_start_scan_implementation;
72
        softmac->wait_for_scan = ieee80211softmac_wait_for_scan_implementation;
73
        softmac->stop_scan = ieee80211softmac_stop_scan_implementation;
74
 
75
        /* to start with, we can't send anything ... */
76
        netif_carrier_off(dev);
77
 
78
        return dev;
79
}
80
EXPORT_SYMBOL_GPL(alloc_ieee80211softmac);
81
 
82
/* Clears the pending work queue items, stops all scans, etc. */
83
void
84
ieee80211softmac_clear_pending_work(struct ieee80211softmac_device *sm)
85
{
86
        unsigned long flags;
87
        struct ieee80211softmac_event *eventptr, *eventtmp;
88
        struct ieee80211softmac_auth_queue_item *authptr, *authtmp;
89
        struct ieee80211softmac_network *netptr, *nettmp;
90
 
91
        ieee80211softmac_stop_scan(sm);
92
        ieee80211softmac_wait_for_scan(sm);
93
 
94
        spin_lock_irqsave(&sm->lock, flags);
95
        sm->running = 0;
96
 
97
        /* Free all pending assoc work items */
98
        cancel_delayed_work(&sm->associnfo.work);
99
 
100
        /* Free all pending scan work items */
101
        if(sm->scaninfo != NULL)
102
                cancel_delayed_work(&sm->scaninfo->softmac_scan);
103
 
104
        /* Free all pending auth work items */
105
        list_for_each_entry(authptr, &sm->auth_queue, list)
106
                cancel_delayed_work(&authptr->work);
107
 
108
        /* delete all pending event calls and work items */
109
        list_for_each_entry_safe(eventptr, eventtmp, &sm->events, list)
110
                cancel_delayed_work(&eventptr->work);
111
 
112
        spin_unlock_irqrestore(&sm->lock, flags);
113
        flush_workqueue(sm->wq);
114
 
115
        /* now we should be save and no longer need locking... */
116
        spin_lock_irqsave(&sm->lock, flags);
117
        /* Free all pending auth work items */
118
        list_for_each_entry_safe(authptr, authtmp, &sm->auth_queue, list) {
119
                list_del(&authptr->list);
120
                kfree(authptr);
121
        }
122
 
123
        /* delete all pending event calls and work items */
124
        list_for_each_entry_safe(eventptr, eventtmp, &sm->events, list) {
125
                list_del(&eventptr->list);
126
                kfree(eventptr);
127
        }
128
 
129
        /* Free all networks */
130
        list_for_each_entry_safe(netptr, nettmp, &sm->network_list, list) {
131
                ieee80211softmac_del_network_locked(sm, netptr);
132
                if(netptr->challenge != NULL)
133
                        kfree(netptr->challenge);
134
                kfree(netptr);
135
        }
136
 
137
        spin_unlock_irqrestore(&sm->lock, flags);
138
}
139
EXPORT_SYMBOL_GPL(ieee80211softmac_clear_pending_work);
140
 
141
void free_ieee80211softmac(struct net_device *dev)
142
{
143
        struct ieee80211softmac_device *sm = ieee80211_priv(dev);
144
        ieee80211softmac_clear_pending_work(sm);
145
        kfree(sm->scaninfo);
146
        kfree(sm->wpa.IE);
147
        destroy_workqueue(sm->wq);
148
        free_ieee80211(dev);
149
}
150
EXPORT_SYMBOL_GPL(free_ieee80211softmac);
151
 
152
static void ieee80211softmac_start_check_rates(struct ieee80211softmac_device *mac)
153
{
154
        struct ieee80211softmac_ratesinfo *ri = &mac->ratesinfo;
155
        /* I took out the sorting check, we're seperating by modulation now. */
156
        if (ri->count)
157
                return;
158
        /* otherwise assume we hav'em all! */
159
        if (mac->ieee->modulation & IEEE80211_CCK_MODULATION) {
160
                ri->rates[ri->count++] = IEEE80211_CCK_RATE_1MB;
161
                ri->rates[ri->count++] = IEEE80211_CCK_RATE_2MB;
162
                ri->rates[ri->count++] = IEEE80211_CCK_RATE_5MB;
163
                ri->rates[ri->count++] = IEEE80211_CCK_RATE_11MB;
164
        }
165
        if (mac->ieee->modulation & IEEE80211_OFDM_MODULATION) {
166
                ri->rates[ri->count++] = IEEE80211_OFDM_RATE_6MB;
167
                ri->rates[ri->count++] = IEEE80211_OFDM_RATE_9MB;
168
                ri->rates[ri->count++] = IEEE80211_OFDM_RATE_12MB;
169
                ri->rates[ri->count++] = IEEE80211_OFDM_RATE_18MB;
170
                ri->rates[ri->count++] = IEEE80211_OFDM_RATE_24MB;
171
                ri->rates[ri->count++] = IEEE80211_OFDM_RATE_36MB;
172
                ri->rates[ri->count++] = IEEE80211_OFDM_RATE_48MB;
173
                ri->rates[ri->count++] = IEEE80211_OFDM_RATE_54MB;
174
        }
175
}
176
 
177
int ieee80211softmac_ratesinfo_rate_supported(struct ieee80211softmac_ratesinfo *ri, u8 rate)
178
{
179
        int search;
180
        u8 search_rate;
181
 
182
        for (search = 0; search < ri->count; search++) {
183
                search_rate = ri->rates[search];
184
                search_rate &= ~IEEE80211_BASIC_RATE_MASK;
185
                if (rate == search_rate)
186
                        return 1;
187
        }
188
 
189
        return 0;
190
}
191
 
192
u8 ieee80211softmac_highest_supported_rate(struct ieee80211softmac_device *mac,
193
        struct ieee80211softmac_ratesinfo *ri, int basic_only)
194
{
195
        u8 user_rate = mac->txrates.user_rate;
196
        int i;
197
 
198
        if (ri->count == 0)
199
                return IEEE80211_CCK_RATE_1MB;
200
 
201
        for (i = ri->count - 1; i >= 0; i--) {
202
                u8 rate = ri->rates[i];
203
                if (basic_only && !(rate & IEEE80211_BASIC_RATE_MASK))
204
                        continue;
205
                rate &= ~IEEE80211_BASIC_RATE_MASK;
206
                if (rate > user_rate)
207
                        continue;
208
                if (ieee80211softmac_ratesinfo_rate_supported(&mac->ratesinfo, rate))
209
                        return rate;
210
        }
211
 
212
        /* If we haven't found a suitable rate by now, just trust the user */
213
        return user_rate;
214
}
215
EXPORT_SYMBOL_GPL(ieee80211softmac_highest_supported_rate);
216
 
217
void ieee80211softmac_process_erp(struct ieee80211softmac_device *mac,
218
        u8 erp_value)
219
{
220
        int use_protection;
221
        int short_preamble;
222
        u32 changes = 0;
223
 
224
        /* Barker preamble mode */
225
        short_preamble = ((erp_value & WLAN_ERP_BARKER_PREAMBLE) == 0
226
                          && mac->associnfo.short_preamble_available) ? 1 : 0;
227
 
228
        /* Protection needed? */
229
        use_protection = (erp_value & WLAN_ERP_USE_PROTECTION) != 0;
230
 
231
        if (mac->bssinfo.short_preamble != short_preamble) {
232
                changes |= IEEE80211SOFTMAC_BSSINFOCHG_SHORT_PREAMBLE;
233
                mac->bssinfo.short_preamble = short_preamble;
234
        }
235
 
236
        if (mac->bssinfo.use_protection != use_protection) {
237
                changes |= IEEE80211SOFTMAC_BSSINFOCHG_PROTECTION;
238
                mac->bssinfo.use_protection = use_protection;
239
        }
240
 
241
        if (mac->bssinfo_change && changes)
242
                mac->bssinfo_change(mac->dev, changes);
243
}
244
 
245
void ieee80211softmac_recalc_txrates(struct ieee80211softmac_device *mac)
246
{
247
        struct ieee80211softmac_txrates *txrates = &mac->txrates;
248
        u32 change = 0;
249
 
250
        change |= IEEE80211SOFTMAC_TXRATECHG_DEFAULT;
251
        txrates->default_rate = ieee80211softmac_highest_supported_rate(mac, &mac->bssinfo.supported_rates, 0);
252
 
253
        change |= IEEE80211SOFTMAC_TXRATECHG_DEFAULT_FBACK;
254
        txrates->default_fallback = lower_rate(mac, txrates->default_rate);
255
 
256
        change |= IEEE80211SOFTMAC_TXRATECHG_MCAST;
257
        txrates->mcast_rate = ieee80211softmac_highest_supported_rate(mac, &mac->bssinfo.supported_rates, 1);
258
 
259
        if (mac->txrates_change)
260
                mac->txrates_change(mac->dev, change);
261
 
262
}
263
 
264
void ieee80211softmac_init_bss(struct ieee80211softmac_device *mac)
265
{
266
        struct ieee80211_device *ieee = mac->ieee;
267
        u32 change = 0;
268
        struct ieee80211softmac_txrates *txrates = &mac->txrates;
269
        struct ieee80211softmac_bss_info *bssinfo = &mac->bssinfo;
270
 
271
        /* TODO: We need some kind of state machine to lower the default rates
272
         *       if we loose too many packets.
273
         */
274
        /* Change the default txrate to the highest possible value.
275
         * The txrate machine will lower it, if it is too high.
276
         */
277
        if (ieee->modulation & IEEE80211_OFDM_MODULATION)
278
                txrates->user_rate = IEEE80211_OFDM_RATE_24MB;
279
        else
280
                txrates->user_rate = IEEE80211_CCK_RATE_11MB;
281
 
282
        txrates->default_rate = IEEE80211_CCK_RATE_1MB;
283
        change |= IEEE80211SOFTMAC_TXRATECHG_DEFAULT;
284
 
285
        txrates->default_fallback = IEEE80211_CCK_RATE_1MB;
286
        change |= IEEE80211SOFTMAC_TXRATECHG_DEFAULT_FBACK;
287
 
288
        txrates->mcast_rate = IEEE80211_CCK_RATE_1MB;
289
        change |= IEEE80211SOFTMAC_TXRATECHG_MCAST;
290
 
291
        txrates->mgt_mcast_rate = IEEE80211_CCK_RATE_1MB;
292
        change |= IEEE80211SOFTMAC_TXRATECHG_MGT_MCAST;
293
 
294
        if (mac->txrates_change)
295
                mac->txrates_change(mac->dev, change);
296
 
297
        change = 0;
298
 
299
        bssinfo->supported_rates.count = 0;
300
        memset(bssinfo->supported_rates.rates, 0,
301
                sizeof(bssinfo->supported_rates.rates));
302
        change |= IEEE80211SOFTMAC_BSSINFOCHG_RATES;
303
 
304
        bssinfo->short_preamble = 0;
305
        change |= IEEE80211SOFTMAC_BSSINFOCHG_SHORT_PREAMBLE;
306
 
307
        bssinfo->use_protection = 0;
308
        change |= IEEE80211SOFTMAC_BSSINFOCHG_PROTECTION;
309
 
310
        if (mac->bssinfo_change)
311
                mac->bssinfo_change(mac->dev, change);
312
 
313
        mac->running = 1;
314
}
315
 
316
void ieee80211softmac_start(struct net_device *dev)
317
{
318
        struct ieee80211softmac_device *mac = ieee80211_priv(dev);
319
 
320
        ieee80211softmac_start_check_rates(mac);
321
        ieee80211softmac_init_bss(mac);
322
}
323
EXPORT_SYMBOL_GPL(ieee80211softmac_start);
324
 
325
void ieee80211softmac_stop(struct net_device *dev)
326
{
327
        struct ieee80211softmac_device *mac = ieee80211_priv(dev);
328
 
329
        ieee80211softmac_clear_pending_work(mac);
330
}
331
EXPORT_SYMBOL_GPL(ieee80211softmac_stop);
332
 
333
void ieee80211softmac_set_rates(struct net_device *dev, u8 count, u8 *rates)
334
{
335
        struct ieee80211softmac_device *mac = ieee80211_priv(dev);
336
        unsigned long flags;
337
 
338
        spin_lock_irqsave(&mac->lock, flags);
339
        memcpy(mac->ratesinfo.rates, rates, count);
340
        mac->ratesinfo.count = count;
341
        spin_unlock_irqrestore(&mac->lock, flags);
342
}
343
EXPORT_SYMBOL_GPL(ieee80211softmac_set_rates);
344
 
345
static u8 raise_rate(struct ieee80211softmac_device *mac, u8 rate)
346
{
347
        int i;
348
        struct ieee80211softmac_ratesinfo *ri = &mac->ratesinfo;
349
 
350
        for (i=0; i<ri->count-1; i++) {
351
                if (ri->rates[i] == rate)
352
                        return ri->rates[i+1];
353
        }
354
        /* I guess we can't go any higher... */
355
        return ri->rates[ri->count];
356
}
357
 
358
u8 ieee80211softmac_lower_rate_delta(struct ieee80211softmac_device *mac, u8 rate, int delta)
359
{
360
        int i;
361
        struct ieee80211softmac_ratesinfo *ri = &mac->ratesinfo;
362
 
363
        for (i=delta; i<ri->count; i++) {
364
                if (ri->rates[i] == rate)
365
                        return ri->rates[i-delta];
366
        }
367
        /* I guess we can't go any lower... */
368
        return ri->rates[0];
369
}
370
 
371
static void ieee80211softmac_add_txrates_badness(struct ieee80211softmac_device *mac,
372
                                                 int amount)
373
{
374
        u8 default_rate = mac->txrates.default_rate;
375
        u8 default_fallback = mac->txrates.default_fallback;
376
        u32 changes = 0;
377
 
378
        //TODO: This is highly experimental code.
379
        //      Maybe the dynamic rate selection does not work
380
        //      and it has to be removed again.
381
 
382
printk("badness %d\n", mac->txrate_badness);
383
        mac->txrate_badness += amount;
384
        if (mac->txrate_badness <= -1000) {
385
                /* Very small badness. Try a faster bitrate. */
386
                default_rate = raise_rate(mac, default_rate);
387
                changes |= IEEE80211SOFTMAC_TXRATECHG_DEFAULT;
388
                default_fallback = get_fallback_rate(mac, default_rate);
389
                changes |= IEEE80211SOFTMAC_TXRATECHG_DEFAULT_FBACK;
390
                mac->txrate_badness = 0;
391
printk("Bitrate raised to %u\n", default_rate);
392
        } else if (mac->txrate_badness >= 10000) {
393
                /* Very high badness. Try a slower bitrate. */
394
                default_rate = lower_rate(mac, default_rate);
395
                changes |= IEEE80211SOFTMAC_TXRATECHG_DEFAULT;
396
                default_fallback = get_fallback_rate(mac, default_rate);
397
                changes |= IEEE80211SOFTMAC_TXRATECHG_DEFAULT_FBACK;
398
                mac->txrate_badness = 0;
399
printk("Bitrate lowered to %u\n", default_rate);
400
        }
401
 
402
        mac->txrates.default_rate = default_rate;
403
        mac->txrates.default_fallback = default_fallback;
404
 
405
        if (changes && mac->txrates_change)
406
                mac->txrates_change(mac->dev, changes);
407
}
408
 
409
void ieee80211softmac_fragment_lost(struct net_device *dev,
410
                                    u16 wl_seq)
411
{
412
        struct ieee80211softmac_device *mac = ieee80211_priv(dev);
413
        unsigned long flags;
414
 
415
        spin_lock_irqsave(&mac->lock, flags);
416
        ieee80211softmac_add_txrates_badness(mac, 1000);
417
        //TODO
418
 
419
        spin_unlock_irqrestore(&mac->lock, flags);
420
}
421
EXPORT_SYMBOL_GPL(ieee80211softmac_fragment_lost);
422
 
423
static int rate_cmp(const void *a_, const void *b_) {
424
        u8 *a, *b;
425
        a = (u8*)a_;
426
        b = (u8*)b_;
427
        return ((*a & ~IEEE80211_BASIC_RATE_MASK) - (*b & ~IEEE80211_BASIC_RATE_MASK));
428
}
429
 
430
/* Allocate a softmac network struct and fill it from a network */
431
struct ieee80211softmac_network *
432
ieee80211softmac_create_network(struct ieee80211softmac_device *mac,
433
        struct ieee80211_network *net)
434
{
435
        struct ieee80211softmac_network *softnet;
436
        softnet = kzalloc(sizeof(struct ieee80211softmac_network), GFP_ATOMIC);
437
        if(softnet == NULL)
438
                return NULL;
439
        memcpy(softnet->bssid, net->bssid, ETH_ALEN);
440
        softnet->channel = net->channel;
441
        softnet->essid.len = net->ssid_len;
442
        memcpy(softnet->essid.data, net->ssid, softnet->essid.len);
443
 
444
        /* copy rates over */
445
        softnet->supported_rates.count = net->rates_len;
446
        memcpy(&softnet->supported_rates.rates[0], net->rates, net->rates_len);
447
        memcpy(&softnet->supported_rates.rates[softnet->supported_rates.count], net->rates_ex, net->rates_ex_len);
448
        softnet->supported_rates.count += net->rates_ex_len;
449
        sort(softnet->supported_rates.rates, softnet->supported_rates.count, sizeof(softnet->supported_rates.rates[0]), rate_cmp, NULL);
450
 
451
        /* we save the ERP value because it is needed at association time, and
452
         * many AP's do not include an ERP IE in the association response. */
453
        softnet->erp_value = net->erp_value;
454
 
455
        softnet->capabilities = net->capability;
456
        return softnet;
457
}
458
 
459
 
460
/* Add a network to the list, while locked */
461
void
462
ieee80211softmac_add_network_locked(struct ieee80211softmac_device *mac,
463
        struct ieee80211softmac_network *add_net)
464
{
465
        struct ieee80211softmac_network *softmac_net;
466
 
467
        list_for_each_entry(softmac_net, &mac->network_list, list) {
468
                if(!memcmp(softmac_net->bssid, add_net->bssid, ETH_ALEN))
469
                        return;
470
        }
471
        list_add(&(add_net->list), &mac->network_list);
472
}
473
 
474
/* Add a network to the list, with locking */
475
void
476
ieee80211softmac_add_network(struct ieee80211softmac_device *mac,
477
        struct ieee80211softmac_network *add_net)
478
{
479
        unsigned long flags;
480
        spin_lock_irqsave(&mac->lock, flags);
481
        ieee80211softmac_add_network_locked(mac, add_net);
482
        spin_unlock_irqrestore(&mac->lock, flags);
483
}
484
 
485
 
486
/* Delete a network from the list, while locked*/
487
void
488
ieee80211softmac_del_network_locked(struct ieee80211softmac_device *mac,
489
        struct ieee80211softmac_network *del_net)
490
{
491
        list_del(&(del_net->list));
492
}
493
 
494
/* Delete a network from the list with locking */
495
void
496
ieee80211softmac_del_network(struct ieee80211softmac_device *mac,
497
        struct ieee80211softmac_network *del_net)
498
{
499
        unsigned long flags;
500
        spin_lock_irqsave(&mac->lock, flags);
501
        ieee80211softmac_del_network_locked(mac, del_net);
502
        spin_unlock_irqrestore(&mac->lock, flags);
503
}
504
 
505
/* Get a network from the list by MAC while locked */
506
struct ieee80211softmac_network *
507
ieee80211softmac_get_network_by_bssid_locked(struct ieee80211softmac_device *mac,
508
        u8 *bssid)
509
{
510
        struct ieee80211softmac_network *softmac_net;
511
 
512
        list_for_each_entry(softmac_net, &mac->network_list, list) {
513
                if(!memcmp(softmac_net->bssid, bssid, ETH_ALEN))
514
                        return softmac_net;
515
        }
516
        return NULL;
517
}
518
 
519
/* Get a network from the list by BSSID with locking */
520
struct ieee80211softmac_network *
521
ieee80211softmac_get_network_by_bssid(struct ieee80211softmac_device *mac,
522
        u8 *bssid)
523
{
524
        unsigned long flags;
525
        struct ieee80211softmac_network *softmac_net;
526
 
527
        spin_lock_irqsave(&mac->lock, flags);
528
        softmac_net = ieee80211softmac_get_network_by_bssid_locked(mac, bssid);
529
        spin_unlock_irqrestore(&mac->lock, flags);
530
        return softmac_net;
531
}
532
 
533
/* Get a network from the list by ESSID while locked */
534
struct ieee80211softmac_network *
535
ieee80211softmac_get_network_by_essid_locked(struct ieee80211softmac_device *mac,
536
        struct ieee80211softmac_essid *essid)
537
{
538
        struct ieee80211softmac_network *softmac_net;
539
 
540
        list_for_each_entry(softmac_net, &mac->network_list, list) {
541
                if (softmac_net->essid.len == essid->len &&
542
                        !memcmp(softmac_net->essid.data, essid->data, essid->len))
543
                        return softmac_net;
544
        }
545
        return NULL;
546
}
547
 
548
/* Get a network from the list by ESSID with locking */
549
struct ieee80211softmac_network *
550
ieee80211softmac_get_network_by_essid(struct ieee80211softmac_device *mac,
551
        struct ieee80211softmac_essid *essid)
552
{
553
        unsigned long flags;
554
        struct ieee80211softmac_network *softmac_net = NULL;
555
 
556
        spin_lock_irqsave(&mac->lock, flags);
557
        softmac_net = ieee80211softmac_get_network_by_essid_locked(mac, essid);
558
        spin_unlock_irqrestore(&mac->lock, flags);
559
        return softmac_net;
560
}
561
 
562
MODULE_LICENSE("GPL");
563
MODULE_AUTHOR("Johannes Berg");
564
MODULE_AUTHOR("Joseph Jezak");
565
MODULE_AUTHOR("Larry Finger");
566
MODULE_AUTHOR("Danny van Dyk");
567
MODULE_AUTHOR("Michael Buesch");
568
MODULE_DESCRIPTION("802.11 software MAC");

powered by: WebSVN 2.1.0

© copyright 1999-2025 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.