~ubuntu-branches/ubuntu/trusty/linux-backports-modules-3.2.0/trusty

« back to all changes in this revision

Viewing changes to updates/cw-3.3/drivers/net/wireless/ath/ath6kl/main.c

  • Committer: Package Import Robot
  • Author(s): Leann Ogasawara
  • Date: 2012-02-15 08:42:08 UTC
  • Revision ID: package-import@ubuntu.com-20120215084208-2gcs2zosufz014pi
Tags: 3.2.0-18.1
* Open Precise LBM
* Add compat-wireless v3.3
* Consolidated amd64 server flavour into generic
* Remove lpia control file
* Update Vcs-Git to ubuntu-preicse-lbm

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
 * Copyright (c) 2004-2011 Atheros Communications Inc.
 
3
 *
 
4
 * Permission to use, copy, modify, and/or distribute this software for any
 
5
 * purpose with or without fee is hereby granted, provided that the above
 
6
 * copyright notice and this permission notice appear in all copies.
 
7
 *
 
8
 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
 
9
 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
 
10
 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
 
11
 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
 
12
 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
 
13
 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
 
14
 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
 
15
 */
 
16
 
 
17
#include "core.h"
 
18
#include "hif-ops.h"
 
19
#include "cfg80211.h"
 
20
#include "target.h"
 
21
#include "debug.h"
 
22
 
 
23
struct ath6kl_sta *ath6kl_find_sta(struct ath6kl_vif *vif, u8 *node_addr)
 
24
{
 
25
        struct ath6kl *ar = vif->ar;
 
26
        struct ath6kl_sta *conn = NULL;
 
27
        u8 i, max_conn;
 
28
 
 
29
        max_conn = (vif->nw_type == AP_NETWORK) ? AP_MAX_NUM_STA : 0;
 
30
 
 
31
        for (i = 0; i < max_conn; i++) {
 
32
                if (memcmp(node_addr, ar->sta_list[i].mac, ETH_ALEN) == 0) {
 
33
                        conn = &ar->sta_list[i];
 
34
                        break;
 
35
                }
 
36
        }
 
37
 
 
38
        return conn;
 
39
}
 
40
 
 
41
struct ath6kl_sta *ath6kl_find_sta_by_aid(struct ath6kl *ar, u8 aid)
 
42
{
 
43
        struct ath6kl_sta *conn = NULL;
 
44
        u8 ctr;
 
45
 
 
46
        for (ctr = 0; ctr < AP_MAX_NUM_STA; ctr++) {
 
47
                if (ar->sta_list[ctr].aid == aid) {
 
48
                        conn = &ar->sta_list[ctr];
 
49
                        break;
 
50
                }
 
51
        }
 
52
        return conn;
 
53
}
 
54
 
 
55
static void ath6kl_add_new_sta(struct ath6kl *ar, u8 *mac, u16 aid, u8 *wpaie,
 
56
                        u8 ielen, u8 keymgmt, u8 ucipher, u8 auth)
 
57
{
 
58
        struct ath6kl_sta *sta;
 
59
        u8 free_slot;
 
60
 
 
61
        free_slot = aid - 1;
 
62
 
 
63
        sta = &ar->sta_list[free_slot];
 
64
        memcpy(sta->mac, mac, ETH_ALEN);
 
65
        if (ielen <= ATH6KL_MAX_IE)
 
66
                memcpy(sta->wpa_ie, wpaie, ielen);
 
67
        sta->aid = aid;
 
68
        sta->keymgmt = keymgmt;
 
69
        sta->ucipher = ucipher;
 
70
        sta->auth = auth;
 
71
 
 
72
        ar->sta_list_index = ar->sta_list_index | (1 << free_slot);
 
73
        ar->ap_stats.sta[free_slot].aid = cpu_to_le32(aid);
 
74
}
 
75
 
 
76
static void ath6kl_sta_cleanup(struct ath6kl *ar, u8 i)
 
77
{
 
78
        struct ath6kl_sta *sta = &ar->sta_list[i];
 
79
 
 
80
        /* empty the queued pkts in the PS queue if any */
 
81
        spin_lock_bh(&sta->psq_lock);
 
82
        skb_queue_purge(&sta->psq);
 
83
        spin_unlock_bh(&sta->psq_lock);
 
84
 
 
85
        memset(&ar->ap_stats.sta[sta->aid - 1], 0,
 
86
               sizeof(struct wmi_per_sta_stat));
 
87
        memset(sta->mac, 0, ETH_ALEN);
 
88
        memset(sta->wpa_ie, 0, ATH6KL_MAX_IE);
 
89
        sta->aid = 0;
 
90
        sta->sta_flags = 0;
 
91
 
 
92
        ar->sta_list_index = ar->sta_list_index & ~(1 << i);
 
93
 
 
94
}
 
95
 
 
96
static u8 ath6kl_remove_sta(struct ath6kl *ar, u8 *mac, u16 reason)
 
97
{
 
98
        u8 i, removed = 0;
 
99
 
 
100
        if (is_zero_ether_addr(mac))
 
101
                return removed;
 
102
 
 
103
        if (is_broadcast_ether_addr(mac)) {
 
104
                ath6kl_dbg(ATH6KL_DBG_TRC, "deleting all station\n");
 
105
 
 
106
                for (i = 0; i < AP_MAX_NUM_STA; i++) {
 
107
                        if (!is_zero_ether_addr(ar->sta_list[i].mac)) {
 
108
                                ath6kl_sta_cleanup(ar, i);
 
109
                                removed = 1;
 
110
                        }
 
111
                }
 
112
        } else {
 
113
                for (i = 0; i < AP_MAX_NUM_STA; i++) {
 
114
                        if (memcmp(ar->sta_list[i].mac, mac, ETH_ALEN) == 0) {
 
115
                                ath6kl_dbg(ATH6KL_DBG_TRC,
 
116
                                           "deleting station %pM aid=%d reason=%d\n",
 
117
                                           mac, ar->sta_list[i].aid, reason);
 
118
                                ath6kl_sta_cleanup(ar, i);
 
119
                                removed = 1;
 
120
                                break;
 
121
                        }
 
122
                }
 
123
        }
 
124
 
 
125
        return removed;
 
126
}
 
127
 
 
128
enum htc_endpoint_id ath6kl_ac2_endpoint_id(void *devt, u8 ac)
 
129
{
 
130
        struct ath6kl *ar = devt;
 
131
        return ar->ac2ep_map[ac];
 
132
}
 
133
 
 
134
struct ath6kl_cookie *ath6kl_alloc_cookie(struct ath6kl *ar)
 
135
{
 
136
        struct ath6kl_cookie *cookie;
 
137
 
 
138
        cookie = ar->cookie_list;
 
139
        if (cookie != NULL) {
 
140
                ar->cookie_list = cookie->arc_list_next;
 
141
                ar->cookie_count--;
 
142
        }
 
143
 
 
144
        return cookie;
 
145
}
 
146
 
 
147
void ath6kl_cookie_init(struct ath6kl *ar)
 
148
{
 
149
        u32 i;
 
150
 
 
151
        ar->cookie_list = NULL;
 
152
        ar->cookie_count = 0;
 
153
 
 
154
        memset(ar->cookie_mem, 0, sizeof(ar->cookie_mem));
 
155
 
 
156
        for (i = 0; i < MAX_COOKIE_NUM; i++)
 
157
                ath6kl_free_cookie(ar, &ar->cookie_mem[i]);
 
158
}
 
159
 
 
160
void ath6kl_cookie_cleanup(struct ath6kl *ar)
 
161
{
 
162
        ar->cookie_list = NULL;
 
163
        ar->cookie_count = 0;
 
164
}
 
165
 
 
166
void ath6kl_free_cookie(struct ath6kl *ar, struct ath6kl_cookie *cookie)
 
167
{
 
168
        /* Insert first */
 
169
 
 
170
        if (!ar || !cookie)
 
171
                return;
 
172
 
 
173
        cookie->arc_list_next = ar->cookie_list;
 
174
        ar->cookie_list = cookie;
 
175
        ar->cookie_count++;
 
176
}
 
177
 
 
178
/*
 
179
 * Read from the hardware through its diagnostic window. No cooperation
 
180
 * from the firmware is required for this.
 
181
 */
 
182
int ath6kl_diag_read32(struct ath6kl *ar, u32 address, u32 *value)
 
183
{
 
184
        int ret;
 
185
 
 
186
        ret = ath6kl_hif_diag_read32(ar, address, value);
 
187
        if (ret) {
 
188
                ath6kl_warn("failed to read32 through diagnose window: %d\n",
 
189
                            ret);
 
190
                return ret;
 
191
        }
 
192
 
 
193
        return 0;
 
194
}
 
195
 
 
196
/*
 
197
 * Write to the ATH6KL through its diagnostic window. No cooperation from
 
198
 * the Target is required for this.
 
199
 */
 
200
int ath6kl_diag_write32(struct ath6kl *ar, u32 address, __le32 value)
 
201
{
 
202
        int ret;
 
203
 
 
204
        ret = ath6kl_hif_diag_write32(ar, address, value);
 
205
 
 
206
        if (ret) {
 
207
                ath6kl_err("failed to write 0x%x during diagnose window to 0x%d\n",
 
208
                           address, value);
 
209
                return ret;
 
210
        }
 
211
 
 
212
        return 0;
 
213
}
 
214
 
 
215
int ath6kl_diag_read(struct ath6kl *ar, u32 address, void *data, u32 length)
 
216
{
 
217
        u32 count, *buf = data;
 
218
        int ret;
 
219
 
 
220
        if (WARN_ON(length % 4))
 
221
                return -EINVAL;
 
222
 
 
223
        for (count = 0; count < length / 4; count++, address += 4) {
 
224
                ret = ath6kl_diag_read32(ar, address, &buf[count]);
 
225
                if (ret)
 
226
                        return ret;
 
227
        }
 
228
 
 
229
        return 0;
 
230
}
 
231
 
 
232
int ath6kl_diag_write(struct ath6kl *ar, u32 address, void *data, u32 length)
 
233
{
 
234
        u32 count;
 
235
        __le32 *buf = data;
 
236
        int ret;
 
237
 
 
238
        if (WARN_ON(length % 4))
 
239
                return -EINVAL;
 
240
 
 
241
        for (count = 0; count < length / 4; count++, address += 4) {
 
242
                ret = ath6kl_diag_write32(ar, address, buf[count]);
 
243
                if (ret)
 
244
                        return ret;
 
245
        }
 
246
 
 
247
        return 0;
 
248
}
 
249
 
 
250
int ath6kl_read_fwlogs(struct ath6kl *ar)
 
251
{
 
252
        struct ath6kl_dbglog_hdr debug_hdr;
 
253
        struct ath6kl_dbglog_buf debug_buf;
 
254
        u32 address, length, dropped, firstbuf, debug_hdr_addr;
 
255
        int ret = 0, loop;
 
256
        u8 *buf;
 
257
 
 
258
        buf = kmalloc(ATH6KL_FWLOG_PAYLOAD_SIZE, GFP_KERNEL);
 
259
        if (!buf)
 
260
                return -ENOMEM;
 
261
 
 
262
        address = TARG_VTOP(ar->target_type,
 
263
                            ath6kl_get_hi_item_addr(ar,
 
264
                                                    HI_ITEM(hi_dbglog_hdr)));
 
265
 
 
266
        ret = ath6kl_diag_read32(ar, address, &debug_hdr_addr);
 
267
        if (ret)
 
268
                goto out;
 
269
 
 
270
        /* Get the contents of the ring buffer */
 
271
        if (debug_hdr_addr == 0) {
 
272
                ath6kl_warn("Invalid address for debug_hdr_addr\n");
 
273
                ret = -EINVAL;
 
274
                goto out;
 
275
        }
 
276
 
 
277
        address = TARG_VTOP(ar->target_type, debug_hdr_addr);
 
278
        ath6kl_diag_read(ar, address, &debug_hdr, sizeof(debug_hdr));
 
279
 
 
280
        address = TARG_VTOP(ar->target_type,
 
281
                            le32_to_cpu(debug_hdr.dbuf_addr));
 
282
        firstbuf = address;
 
283
        dropped = le32_to_cpu(debug_hdr.dropped);
 
284
        ath6kl_diag_read(ar, address, &debug_buf, sizeof(debug_buf));
 
285
 
 
286
        loop = 100;
 
287
 
 
288
        do {
 
289
                address = TARG_VTOP(ar->target_type,
 
290
                                    le32_to_cpu(debug_buf.buffer_addr));
 
291
                length = le32_to_cpu(debug_buf.length);
 
292
 
 
293
                if (length != 0 && (le32_to_cpu(debug_buf.length) <=
 
294
                                    le32_to_cpu(debug_buf.bufsize))) {
 
295
                        length = ALIGN(length, 4);
 
296
 
 
297
                        ret = ath6kl_diag_read(ar, address,
 
298
                                               buf, length);
 
299
                        if (ret)
 
300
                                goto out;
 
301
 
 
302
                        ath6kl_debug_fwlog_event(ar, buf, length);
 
303
                }
 
304
 
 
305
                address = TARG_VTOP(ar->target_type,
 
306
                                    le32_to_cpu(debug_buf.next));
 
307
                ath6kl_diag_read(ar, address, &debug_buf, sizeof(debug_buf));
 
308
                if (ret)
 
309
                        goto out;
 
310
 
 
311
                loop--;
 
312
 
 
313
                if (WARN_ON(loop == 0)) {
 
314
                        ret = -ETIMEDOUT;
 
315
                        goto out;
 
316
                }
 
317
        } while (address != firstbuf);
 
318
 
 
319
out:
 
320
        kfree(buf);
 
321
 
 
322
        return ret;
 
323
}
 
324
 
 
325
/* FIXME: move to a better place, target.h? */
 
326
#define AR6003_RESET_CONTROL_ADDRESS 0x00004000
 
327
#define AR6004_RESET_CONTROL_ADDRESS 0x00004000
 
328
 
 
329
void ath6kl_reset_device(struct ath6kl *ar, u32 target_type,
 
330
                         bool wait_fot_compltn, bool cold_reset)
 
331
{
 
332
        int status = 0;
 
333
        u32 address;
 
334
        __le32 data;
 
335
 
 
336
        if (target_type != TARGET_TYPE_AR6003 &&
 
337
                target_type != TARGET_TYPE_AR6004)
 
338
                return;
 
339
 
 
340
        data = cold_reset ? cpu_to_le32(RESET_CONTROL_COLD_RST) :
 
341
                            cpu_to_le32(RESET_CONTROL_MBOX_RST);
 
342
 
 
343
        switch (target_type) {
 
344
        case TARGET_TYPE_AR6003:
 
345
                address = AR6003_RESET_CONTROL_ADDRESS;
 
346
                break;
 
347
        case TARGET_TYPE_AR6004:
 
348
                address = AR6004_RESET_CONTROL_ADDRESS;
 
349
                break;
 
350
        default:
 
351
                address = AR6003_RESET_CONTROL_ADDRESS;
 
352
                break;
 
353
        }
 
354
 
 
355
        status = ath6kl_diag_write32(ar, address, data);
 
356
 
 
357
        if (status)
 
358
                ath6kl_err("failed to reset target\n");
 
359
}
 
360
 
 
361
static void ath6kl_install_static_wep_keys(struct ath6kl_vif *vif)
 
362
{
 
363
        u8 index;
 
364
        u8 keyusage;
 
365
 
 
366
        for (index = WMI_MIN_KEY_INDEX; index <= WMI_MAX_KEY_INDEX; index++) {
 
367
                if (vif->wep_key_list[index].key_len) {
 
368
                        keyusage = GROUP_USAGE;
 
369
                        if (index == vif->def_txkey_index)
 
370
                                keyusage |= TX_USAGE;
 
371
 
 
372
                        ath6kl_wmi_addkey_cmd(vif->ar->wmi, vif->fw_vif_idx,
 
373
                                              index,
 
374
                                              WEP_CRYPT,
 
375
                                              keyusage,
 
376
                                              vif->wep_key_list[index].key_len,
 
377
                                              NULL, 0,
 
378
                                              vif->wep_key_list[index].key,
 
379
                                              KEY_OP_INIT_VAL, NULL,
 
380
                                              NO_SYNC_WMIFLAG);
 
381
                }
 
382
        }
 
383
}
 
384
 
 
385
void ath6kl_connect_ap_mode_bss(struct ath6kl_vif *vif, u16 channel)
 
386
{
 
387
        struct ath6kl *ar = vif->ar;
 
388
        struct ath6kl_req_key *ik;
 
389
        int res;
 
390
        u8 key_rsc[ATH6KL_KEY_SEQ_LEN];
 
391
 
 
392
        ik = &ar->ap_mode_bkey;
 
393
 
 
394
        ath6kl_dbg(ATH6KL_DBG_WLAN_CFG, "AP mode started on %u MHz\n", channel);
 
395
 
 
396
        switch (vif->auth_mode) {
 
397
        case NONE_AUTH:
 
398
                if (vif->prwise_crypto == WEP_CRYPT)
 
399
                        ath6kl_install_static_wep_keys(vif);
 
400
                if (!ik->valid || ik->key_type != WAPI_CRYPT)
 
401
                        break;
 
402
                /* for WAPI, we need to set the delayed group key, continue: */
 
403
        case WPA_PSK_AUTH:
 
404
        case WPA2_PSK_AUTH:
 
405
        case (WPA_PSK_AUTH | WPA2_PSK_AUTH):
 
406
                if (!ik->valid)
 
407
                        break;
 
408
 
 
409
                ath6kl_dbg(ATH6KL_DBG_WLAN_CFG, "Delayed addkey for "
 
410
                           "the initial group key for AP mode\n");
 
411
                memset(key_rsc, 0, sizeof(key_rsc));
 
412
                res = ath6kl_wmi_addkey_cmd(
 
413
                        ar->wmi, vif->fw_vif_idx, ik->key_index, ik->key_type,
 
414
                        GROUP_USAGE, ik->key_len, key_rsc, ATH6KL_KEY_SEQ_LEN,
 
415
                        ik->key,
 
416
                        KEY_OP_INIT_VAL, NULL, SYNC_BOTH_WMIFLAG);
 
417
                if (res) {
 
418
                        ath6kl_dbg(ATH6KL_DBG_WLAN_CFG, "Delayed "
 
419
                                   "addkey failed: %d\n", res);
 
420
                }
 
421
                break;
 
422
        }
 
423
 
 
424
        ath6kl_wmi_bssfilter_cmd(ar->wmi, vif->fw_vif_idx, NONE_BSS_FILTER, 0);
 
425
        set_bit(CONNECTED, &vif->flags);
 
426
        netif_carrier_on(vif->ndev);
 
427
}
 
428
 
 
429
void ath6kl_connect_ap_mode_sta(struct ath6kl_vif *vif, u16 aid, u8 *mac_addr,
 
430
                                u8 keymgmt, u8 ucipher, u8 auth,
 
431
                                u8 assoc_req_len, u8 *assoc_info)
 
432
{
 
433
        struct ath6kl *ar = vif->ar;
 
434
        u8 *ies = NULL, *wpa_ie = NULL, *pos;
 
435
        size_t ies_len = 0;
 
436
        struct station_info sinfo;
 
437
 
 
438
        ath6kl_dbg(ATH6KL_DBG_TRC, "new station %pM aid=%d\n", mac_addr, aid);
 
439
 
 
440
        if (assoc_req_len > sizeof(struct ieee80211_hdr_3addr)) {
 
441
                struct ieee80211_mgmt *mgmt =
 
442
                        (struct ieee80211_mgmt *) assoc_info;
 
443
                if (ieee80211_is_assoc_req(mgmt->frame_control) &&
 
444
                    assoc_req_len >= sizeof(struct ieee80211_hdr_3addr) +
 
445
                    sizeof(mgmt->u.assoc_req)) {
 
446
                        ies = mgmt->u.assoc_req.variable;
 
447
                        ies_len = assoc_info + assoc_req_len - ies;
 
448
                } else if (ieee80211_is_reassoc_req(mgmt->frame_control) &&
 
449
                           assoc_req_len >= sizeof(struct ieee80211_hdr_3addr)
 
450
                           + sizeof(mgmt->u.reassoc_req)) {
 
451
                        ies = mgmt->u.reassoc_req.variable;
 
452
                        ies_len = assoc_info + assoc_req_len - ies;
 
453
                }
 
454
        }
 
455
 
 
456
        pos = ies;
 
457
        while (pos && pos + 1 < ies + ies_len) {
 
458
                if (pos + 2 + pos[1] > ies + ies_len)
 
459
                        break;
 
460
                if (pos[0] == WLAN_EID_RSN)
 
461
                        wpa_ie = pos; /* RSN IE */
 
462
                else if (pos[0] == WLAN_EID_VENDOR_SPECIFIC &&
 
463
                         pos[1] >= 4 &&
 
464
                         pos[2] == 0x00 && pos[3] == 0x50 && pos[4] == 0xf2) {
 
465
                        if (pos[5] == 0x01)
 
466
                                wpa_ie = pos; /* WPA IE */
 
467
                        else if (pos[5] == 0x04) {
 
468
                                wpa_ie = pos; /* WPS IE */
 
469
                                break; /* overrides WPA/RSN IE */
 
470
                        }
 
471
                } else if (pos[0] == 0x44 && wpa_ie == NULL) {
 
472
                        /*
 
473
                         * Note: WAPI Parameter Set IE re-uses Element ID that
 
474
                         * was officially allocated for BSS AC Access Delay. As
 
475
                         * such, we need to be a bit more careful on when
 
476
                         * parsing the frame. However, BSS AC Access Delay
 
477
                         * element is not supposed to be included in
 
478
                         * (Re)Association Request frames, so this should not
 
479
                         * cause problems.
 
480
                         */
 
481
                        wpa_ie = pos; /* WAPI IE */
 
482
                        break;
 
483
                }
 
484
                pos += 2 + pos[1];
 
485
        }
 
486
 
 
487
        ath6kl_add_new_sta(ar, mac_addr, aid, wpa_ie,
 
488
                           wpa_ie ? 2 + wpa_ie[1] : 0,
 
489
                           keymgmt, ucipher, auth);
 
490
 
 
491
        /* send event to application */
 
492
        memset(&sinfo, 0, sizeof(sinfo));
 
493
 
 
494
        /* TODO: sinfo.generation */
 
495
 
 
496
        sinfo.assoc_req_ies = ies;
 
497
        sinfo.assoc_req_ies_len = ies_len;
 
498
        sinfo.filled |= STATION_INFO_ASSOC_REQ_IES;
 
499
 
 
500
        cfg80211_new_sta(vif->ndev, mac_addr, &sinfo, GFP_KERNEL);
 
501
 
 
502
        netif_wake_queue(vif->ndev);
 
503
}
 
504
 
 
505
void disconnect_timer_handler(unsigned long ptr)
 
506
{
 
507
        struct net_device *dev = (struct net_device *)ptr;
 
508
        struct ath6kl_vif *vif = netdev_priv(dev);
 
509
 
 
510
        ath6kl_init_profile_info(vif);
 
511
        ath6kl_disconnect(vif);
 
512
}
 
513
 
 
514
void ath6kl_disconnect(struct ath6kl_vif *vif)
 
515
{
 
516
        if (test_bit(CONNECTED, &vif->flags) ||
 
517
            test_bit(CONNECT_PEND, &vif->flags)) {
 
518
                ath6kl_wmi_disconnect_cmd(vif->ar->wmi, vif->fw_vif_idx);
 
519
                /*
 
520
                 * Disconnect command is issued, clear the connect pending
 
521
                 * flag. The connected flag will be cleared in
 
522
                 * disconnect event notification.
 
523
                 */
 
524
                clear_bit(CONNECT_PEND, &vif->flags);
 
525
        }
 
526
}
 
527
 
 
528
/* WMI Event handlers */
 
529
 
 
530
void ath6kl_ready_event(void *devt, u8 *datap, u32 sw_ver, u32 abi_ver)
 
531
{
 
532
        struct ath6kl *ar = devt;
 
533
 
 
534
        memcpy(ar->mac_addr, datap, ETH_ALEN);
 
535
        ath6kl_dbg(ATH6KL_DBG_TRC, "%s: mac addr = %pM\n",
 
536
                   __func__, ar->mac_addr);
 
537
 
 
538
        ar->version.wlan_ver = sw_ver;
 
539
        ar->version.abi_ver = abi_ver;
 
540
 
 
541
        snprintf(ar->wiphy->fw_version,
 
542
                 sizeof(ar->wiphy->fw_version),
 
543
                 "%u.%u.%u.%u",
 
544
                 (ar->version.wlan_ver & 0xf0000000) >> 28,
 
545
                 (ar->version.wlan_ver & 0x0f000000) >> 24,
 
546
                 (ar->version.wlan_ver & 0x00ff0000) >> 16,
 
547
                 (ar->version.wlan_ver & 0x0000ffff));
 
548
 
 
549
        /* indicate to the waiting thread that the ready event was received */
 
550
        set_bit(WMI_READY, &ar->flag);
 
551
        wake_up(&ar->event_wq);
 
552
}
 
553
 
 
554
void ath6kl_scan_complete_evt(struct ath6kl_vif *vif, int status)
 
555
{
 
556
        struct ath6kl *ar = vif->ar;
 
557
        bool aborted = false;
 
558
 
 
559
        if (status != WMI_SCAN_STATUS_SUCCESS)
 
560
                aborted = true;
 
561
 
 
562
        ath6kl_cfg80211_scan_complete_event(vif, aborted);
 
563
 
 
564
        if (!ar->usr_bss_filter) {
 
565
                clear_bit(CLEAR_BSSFILTER_ON_BEACON, &vif->flags);
 
566
                ath6kl_wmi_bssfilter_cmd(ar->wmi, vif->fw_vif_idx,
 
567
                                         NONE_BSS_FILTER, 0);
 
568
        }
 
569
 
 
570
        ath6kl_dbg(ATH6KL_DBG_WLAN_CFG, "scan complete: %d\n", status);
 
571
}
 
572
 
 
573
void ath6kl_connect_event(struct ath6kl_vif *vif, u16 channel, u8 *bssid,
 
574
                          u16 listen_int, u16 beacon_int,
 
575
                          enum network_type net_type, u8 beacon_ie_len,
 
576
                          u8 assoc_req_len, u8 assoc_resp_len,
 
577
                          u8 *assoc_info)
 
578
{
 
579
        struct ath6kl *ar = vif->ar;
 
580
 
 
581
        ath6kl_cfg80211_connect_event(vif, channel, bssid,
 
582
                                      listen_int, beacon_int,
 
583
                                      net_type, beacon_ie_len,
 
584
                                      assoc_req_len, assoc_resp_len,
 
585
                                      assoc_info);
 
586
 
 
587
        memcpy(vif->bssid, bssid, sizeof(vif->bssid));
 
588
        vif->bss_ch = channel;
 
589
 
 
590
        if ((vif->nw_type == INFRA_NETWORK))
 
591
                ath6kl_wmi_listeninterval_cmd(ar->wmi, vif->fw_vif_idx,
 
592
                                              ar->listen_intvl_t,
 
593
                                              ar->listen_intvl_b);
 
594
 
 
595
        netif_wake_queue(vif->ndev);
 
596
 
 
597
        /* Update connect & link status atomically */
 
598
        spin_lock_bh(&vif->if_lock);
 
599
        set_bit(CONNECTED, &vif->flags);
 
600
        clear_bit(CONNECT_PEND, &vif->flags);
 
601
        netif_carrier_on(vif->ndev);
 
602
        spin_unlock_bh(&vif->if_lock);
 
603
 
 
604
        aggr_reset_state(vif->aggr_cntxt);
 
605
        vif->reconnect_flag = 0;
 
606
 
 
607
        if ((vif->nw_type == ADHOC_NETWORK) && ar->ibss_ps_enable) {
 
608
                memset(ar->node_map, 0, sizeof(ar->node_map));
 
609
                ar->node_num = 0;
 
610
                ar->next_ep_id = ENDPOINT_2;
 
611
        }
 
612
 
 
613
        if (!ar->usr_bss_filter) {
 
614
                set_bit(CLEAR_BSSFILTER_ON_BEACON, &vif->flags);
 
615
                ath6kl_wmi_bssfilter_cmd(ar->wmi, vif->fw_vif_idx,
 
616
                                         CURRENT_BSS_FILTER, 0);
 
617
        }
 
618
}
 
619
 
 
620
void ath6kl_tkip_micerr_event(struct ath6kl_vif *vif, u8 keyid, bool ismcast)
 
621
{
 
622
        struct ath6kl_sta *sta;
 
623
        struct ath6kl *ar = vif->ar;
 
624
        u8 tsc[6];
 
625
 
 
626
        /*
 
627
         * For AP case, keyid will have aid of STA which sent pkt with
 
628
         * MIC error. Use this aid to get MAC & send it to hostapd.
 
629
         */
 
630
        if (vif->nw_type == AP_NETWORK) {
 
631
                sta = ath6kl_find_sta_by_aid(ar, (keyid >> 2));
 
632
                if (!sta)
 
633
                        return;
 
634
 
 
635
                ath6kl_dbg(ATH6KL_DBG_TRC,
 
636
                           "ap tkip mic error received from aid=%d\n", keyid);
 
637
 
 
638
                memset(tsc, 0, sizeof(tsc)); /* FIX: get correct TSC */
 
639
                cfg80211_michael_mic_failure(vif->ndev, sta->mac,
 
640
                                             NL80211_KEYTYPE_PAIRWISE, keyid,
 
641
                                             tsc, GFP_KERNEL);
 
642
        } else
 
643
                ath6kl_cfg80211_tkip_micerr_event(vif, keyid, ismcast);
 
644
 
 
645
}
 
646
 
 
647
static void ath6kl_update_target_stats(struct ath6kl_vif *vif, u8 *ptr, u32 len)
 
648
{
 
649
        struct wmi_target_stats *tgt_stats =
 
650
                (struct wmi_target_stats *) ptr;
 
651
        struct ath6kl *ar = vif->ar;
 
652
        struct target_stats *stats = &vif->target_stats;
 
653
        struct tkip_ccmp_stats *ccmp_stats;
 
654
        u8 ac;
 
655
 
 
656
        if (len < sizeof(*tgt_stats))
 
657
                return;
 
658
 
 
659
        ath6kl_dbg(ATH6KL_DBG_TRC, "updating target stats\n");
 
660
 
 
661
        stats->tx_pkt += le32_to_cpu(tgt_stats->stats.tx.pkt);
 
662
        stats->tx_byte += le32_to_cpu(tgt_stats->stats.tx.byte);
 
663
        stats->tx_ucast_pkt += le32_to_cpu(tgt_stats->stats.tx.ucast_pkt);
 
664
        stats->tx_ucast_byte += le32_to_cpu(tgt_stats->stats.tx.ucast_byte);
 
665
        stats->tx_mcast_pkt += le32_to_cpu(tgt_stats->stats.tx.mcast_pkt);
 
666
        stats->tx_mcast_byte += le32_to_cpu(tgt_stats->stats.tx.mcast_byte);
 
667
        stats->tx_bcast_pkt  += le32_to_cpu(tgt_stats->stats.tx.bcast_pkt);
 
668
        stats->tx_bcast_byte += le32_to_cpu(tgt_stats->stats.tx.bcast_byte);
 
669
        stats->tx_rts_success_cnt +=
 
670
                le32_to_cpu(tgt_stats->stats.tx.rts_success_cnt);
 
671
 
 
672
        for (ac = 0; ac < WMM_NUM_AC; ac++)
 
673
                stats->tx_pkt_per_ac[ac] +=
 
674
                        le32_to_cpu(tgt_stats->stats.tx.pkt_per_ac[ac]);
 
675
 
 
676
        stats->tx_err += le32_to_cpu(tgt_stats->stats.tx.err);
 
677
        stats->tx_fail_cnt += le32_to_cpu(tgt_stats->stats.tx.fail_cnt);
 
678
        stats->tx_retry_cnt += le32_to_cpu(tgt_stats->stats.tx.retry_cnt);
 
679
        stats->tx_mult_retry_cnt +=
 
680
                le32_to_cpu(tgt_stats->stats.tx.mult_retry_cnt);
 
681
        stats->tx_rts_fail_cnt +=
 
682
                le32_to_cpu(tgt_stats->stats.tx.rts_fail_cnt);
 
683
        stats->tx_ucast_rate =
 
684
            ath6kl_wmi_get_rate(a_sle32_to_cpu(tgt_stats->stats.tx.ucast_rate));
 
685
 
 
686
        stats->rx_pkt += le32_to_cpu(tgt_stats->stats.rx.pkt);
 
687
        stats->rx_byte += le32_to_cpu(tgt_stats->stats.rx.byte);
 
688
        stats->rx_ucast_pkt += le32_to_cpu(tgt_stats->stats.rx.ucast_pkt);
 
689
        stats->rx_ucast_byte += le32_to_cpu(tgt_stats->stats.rx.ucast_byte);
 
690
        stats->rx_mcast_pkt += le32_to_cpu(tgt_stats->stats.rx.mcast_pkt);
 
691
        stats->rx_mcast_byte += le32_to_cpu(tgt_stats->stats.rx.mcast_byte);
 
692
        stats->rx_bcast_pkt += le32_to_cpu(tgt_stats->stats.rx.bcast_pkt);
 
693
        stats->rx_bcast_byte += le32_to_cpu(tgt_stats->stats.rx.bcast_byte);
 
694
        stats->rx_frgment_pkt += le32_to_cpu(tgt_stats->stats.rx.frgment_pkt);
 
695
        stats->rx_err += le32_to_cpu(tgt_stats->stats.rx.err);
 
696
        stats->rx_crc_err += le32_to_cpu(tgt_stats->stats.rx.crc_err);
 
697
        stats->rx_key_cache_miss +=
 
698
                le32_to_cpu(tgt_stats->stats.rx.key_cache_miss);
 
699
        stats->rx_decrypt_err += le32_to_cpu(tgt_stats->stats.rx.decrypt_err);
 
700
        stats->rx_dupl_frame += le32_to_cpu(tgt_stats->stats.rx.dupl_frame);
 
701
        stats->rx_ucast_rate =
 
702
            ath6kl_wmi_get_rate(a_sle32_to_cpu(tgt_stats->stats.rx.ucast_rate));
 
703
 
 
704
        ccmp_stats = &tgt_stats->stats.tkip_ccmp_stats;
 
705
 
 
706
        stats->tkip_local_mic_fail +=
 
707
                le32_to_cpu(ccmp_stats->tkip_local_mic_fail);
 
708
        stats->tkip_cnter_measures_invoked +=
 
709
                le32_to_cpu(ccmp_stats->tkip_cnter_measures_invoked);
 
710
        stats->tkip_fmt_err += le32_to_cpu(ccmp_stats->tkip_fmt_err);
 
711
 
 
712
        stats->ccmp_fmt_err += le32_to_cpu(ccmp_stats->ccmp_fmt_err);
 
713
        stats->ccmp_replays += le32_to_cpu(ccmp_stats->ccmp_replays);
 
714
 
 
715
        stats->pwr_save_fail_cnt +=
 
716
                le32_to_cpu(tgt_stats->pm_stats.pwr_save_failure_cnt);
 
717
        stats->noise_floor_calib =
 
718
                a_sle32_to_cpu(tgt_stats->noise_floor_calib);
 
719
 
 
720
        stats->cs_bmiss_cnt +=
 
721
                le32_to_cpu(tgt_stats->cserv_stats.cs_bmiss_cnt);
 
722
        stats->cs_low_rssi_cnt +=
 
723
                le32_to_cpu(tgt_stats->cserv_stats.cs_low_rssi_cnt);
 
724
        stats->cs_connect_cnt +=
 
725
                le16_to_cpu(tgt_stats->cserv_stats.cs_connect_cnt);
 
726
        stats->cs_discon_cnt +=
 
727
                le16_to_cpu(tgt_stats->cserv_stats.cs_discon_cnt);
 
728
 
 
729
        stats->cs_ave_beacon_rssi =
 
730
                a_sle16_to_cpu(tgt_stats->cserv_stats.cs_ave_beacon_rssi);
 
731
 
 
732
        stats->cs_last_roam_msec =
 
733
                tgt_stats->cserv_stats.cs_last_roam_msec;
 
734
        stats->cs_snr = tgt_stats->cserv_stats.cs_snr;
 
735
        stats->cs_rssi = a_sle16_to_cpu(tgt_stats->cserv_stats.cs_rssi);
 
736
 
 
737
        stats->lq_val = le32_to_cpu(tgt_stats->lq_val);
 
738
 
 
739
        stats->wow_pkt_dropped +=
 
740
                le32_to_cpu(tgt_stats->wow_stats.wow_pkt_dropped);
 
741
        stats->wow_host_pkt_wakeups +=
 
742
                tgt_stats->wow_stats.wow_host_pkt_wakeups;
 
743
        stats->wow_host_evt_wakeups +=
 
744
                tgt_stats->wow_stats.wow_host_evt_wakeups;
 
745
        stats->wow_evt_discarded +=
 
746
                le16_to_cpu(tgt_stats->wow_stats.wow_evt_discarded);
 
747
 
 
748
        if (test_bit(STATS_UPDATE_PEND, &vif->flags)) {
 
749
                clear_bit(STATS_UPDATE_PEND, &vif->flags);
 
750
                wake_up(&ar->event_wq);
 
751
        }
 
752
}
 
753
 
 
754
static void ath6kl_add_le32(__le32 *var, __le32 val)
 
755
{
 
756
        *var = cpu_to_le32(le32_to_cpu(*var) + le32_to_cpu(val));
 
757
}
 
758
 
 
759
void ath6kl_tgt_stats_event(struct ath6kl_vif *vif, u8 *ptr, u32 len)
 
760
{
 
761
        struct wmi_ap_mode_stat *p = (struct wmi_ap_mode_stat *) ptr;
 
762
        struct ath6kl *ar = vif->ar;
 
763
        struct wmi_ap_mode_stat *ap = &ar->ap_stats;
 
764
        struct wmi_per_sta_stat *st_ap, *st_p;
 
765
        u8 ac;
 
766
 
 
767
        if (vif->nw_type == AP_NETWORK) {
 
768
                if (len < sizeof(*p))
 
769
                        return;
 
770
 
 
771
                for (ac = 0; ac < AP_MAX_NUM_STA; ac++) {
 
772
                        st_ap = &ap->sta[ac];
 
773
                        st_p = &p->sta[ac];
 
774
 
 
775
                        ath6kl_add_le32(&st_ap->tx_bytes, st_p->tx_bytes);
 
776
                        ath6kl_add_le32(&st_ap->tx_pkts, st_p->tx_pkts);
 
777
                        ath6kl_add_le32(&st_ap->tx_error, st_p->tx_error);
 
778
                        ath6kl_add_le32(&st_ap->tx_discard, st_p->tx_discard);
 
779
                        ath6kl_add_le32(&st_ap->rx_bytes, st_p->rx_bytes);
 
780
                        ath6kl_add_le32(&st_ap->rx_pkts, st_p->rx_pkts);
 
781
                        ath6kl_add_le32(&st_ap->rx_error, st_p->rx_error);
 
782
                        ath6kl_add_le32(&st_ap->rx_discard, st_p->rx_discard);
 
783
                }
 
784
 
 
785
        } else {
 
786
                ath6kl_update_target_stats(vif, ptr, len);
 
787
        }
 
788
}
 
789
 
 
790
void ath6kl_wakeup_event(void *dev)
 
791
{
 
792
        struct ath6kl *ar = (struct ath6kl *) dev;
 
793
 
 
794
        wake_up(&ar->event_wq);
 
795
}
 
796
 
 
797
void ath6kl_txpwr_rx_evt(void *devt, u8 tx_pwr)
 
798
{
 
799
        struct ath6kl *ar = (struct ath6kl *) devt;
 
800
 
 
801
        ar->tx_pwr = tx_pwr;
 
802
        wake_up(&ar->event_wq);
 
803
}
 
804
 
 
805
void ath6kl_pspoll_event(struct ath6kl_vif *vif, u8 aid)
 
806
{
 
807
        struct ath6kl_sta *conn;
 
808
        struct sk_buff *skb;
 
809
        bool psq_empty = false;
 
810
        struct ath6kl *ar = vif->ar;
 
811
 
 
812
        conn = ath6kl_find_sta_by_aid(ar, aid);
 
813
 
 
814
        if (!conn)
 
815
                return;
 
816
        /*
 
817
         * Send out a packet queued on ps queue. When the ps queue
 
818
         * becomes empty update the PVB for this station.
 
819
         */
 
820
        spin_lock_bh(&conn->psq_lock);
 
821
        psq_empty  = skb_queue_empty(&conn->psq);
 
822
        spin_unlock_bh(&conn->psq_lock);
 
823
 
 
824
        if (psq_empty)
 
825
                /* TODO: Send out a NULL data frame */
 
826
                return;
 
827
 
 
828
        spin_lock_bh(&conn->psq_lock);
 
829
        skb = skb_dequeue(&conn->psq);
 
830
        spin_unlock_bh(&conn->psq_lock);
 
831
 
 
832
        conn->sta_flags |= STA_PS_POLLED;
 
833
        ath6kl_data_tx(skb, vif->ndev);
 
834
        conn->sta_flags &= ~STA_PS_POLLED;
 
835
 
 
836
        spin_lock_bh(&conn->psq_lock);
 
837
        psq_empty  = skb_queue_empty(&conn->psq);
 
838
        spin_unlock_bh(&conn->psq_lock);
 
839
 
 
840
        if (psq_empty)
 
841
                ath6kl_wmi_set_pvb_cmd(ar->wmi, vif->fw_vif_idx, conn->aid, 0);
 
842
}
 
843
 
 
844
void ath6kl_dtimexpiry_event(struct ath6kl_vif *vif)
 
845
{
 
846
        bool mcastq_empty = false;
 
847
        struct sk_buff *skb;
 
848
        struct ath6kl *ar = vif->ar;
 
849
 
 
850
        /*
 
851
         * If there are no associated STAs, ignore the DTIM expiry event.
 
852
         * There can be potential race conditions where the last associated
 
853
         * STA may disconnect & before the host could clear the 'Indicate
 
854
         * DTIM' request to the firmware, the firmware would have just
 
855
         * indicated a DTIM expiry event. The race is between 'clear DTIM
 
856
         * expiry cmd' going from the host to the firmware & the DTIM
 
857
         * expiry event happening from the firmware to the host.
 
858
         */
 
859
        if (!ar->sta_list_index)
 
860
                return;
 
861
 
 
862
        spin_lock_bh(&ar->mcastpsq_lock);
 
863
        mcastq_empty = skb_queue_empty(&ar->mcastpsq);
 
864
        spin_unlock_bh(&ar->mcastpsq_lock);
 
865
 
 
866
        if (mcastq_empty)
 
867
                return;
 
868
 
 
869
        /* set the STA flag to dtim_expired for the frame to go out */
 
870
        set_bit(DTIM_EXPIRED, &vif->flags);
 
871
 
 
872
        spin_lock_bh(&ar->mcastpsq_lock);
 
873
        while ((skb = skb_dequeue(&ar->mcastpsq)) != NULL) {
 
874
                spin_unlock_bh(&ar->mcastpsq_lock);
 
875
 
 
876
                ath6kl_data_tx(skb, vif->ndev);
 
877
 
 
878
                spin_lock_bh(&ar->mcastpsq_lock);
 
879
        }
 
880
        spin_unlock_bh(&ar->mcastpsq_lock);
 
881
 
 
882
        clear_bit(DTIM_EXPIRED, &vif->flags);
 
883
 
 
884
        /* clear the LSB of the BitMapCtl field of the TIM IE */
 
885
        ath6kl_wmi_set_pvb_cmd(ar->wmi, vif->fw_vif_idx, MCAST_AID, 0);
 
886
}
 
887
 
 
888
void ath6kl_disconnect_event(struct ath6kl_vif *vif, u8 reason, u8 *bssid,
 
889
                             u8 assoc_resp_len, u8 *assoc_info,
 
890
                             u16 prot_reason_status)
 
891
{
 
892
        struct ath6kl *ar = vif->ar;
 
893
 
 
894
        if (vif->nw_type == AP_NETWORK) {
 
895
                if (!ath6kl_remove_sta(ar, bssid, prot_reason_status))
 
896
                        return;
 
897
 
 
898
                /* if no more associated STAs, empty the mcast PS q */
 
899
                if (ar->sta_list_index == 0) {
 
900
                        spin_lock_bh(&ar->mcastpsq_lock);
 
901
                        skb_queue_purge(&ar->mcastpsq);
 
902
                        spin_unlock_bh(&ar->mcastpsq_lock);
 
903
 
 
904
                        /* clear the LSB of the TIM IE's BitMapCtl field */
 
905
                        if (test_bit(WMI_READY, &ar->flag))
 
906
                                ath6kl_wmi_set_pvb_cmd(ar->wmi, vif->fw_vif_idx,
 
907
                                                       MCAST_AID, 0);
 
908
                }
 
909
 
 
910
                if (!is_broadcast_ether_addr(bssid)) {
 
911
                        /* send event to application */
 
912
                        cfg80211_del_sta(vif->ndev, bssid, GFP_KERNEL);
 
913
                }
 
914
 
 
915
                if (memcmp(vif->ndev->dev_addr, bssid, ETH_ALEN) == 0) {
 
916
                        memset(vif->wep_key_list, 0, sizeof(vif->wep_key_list));
 
917
                        clear_bit(CONNECTED, &vif->flags);
 
918
                }
 
919
                return;
 
920
        }
 
921
 
 
922
        ath6kl_cfg80211_disconnect_event(vif, reason, bssid,
 
923
                                       assoc_resp_len, assoc_info,
 
924
                                       prot_reason_status);
 
925
 
 
926
        aggr_reset_state(vif->aggr_cntxt);
 
927
 
 
928
        del_timer(&vif->disconnect_timer);
 
929
 
 
930
        ath6kl_dbg(ATH6KL_DBG_WLAN_CFG, "disconnect reason is %d\n", reason);
 
931
 
 
932
        /*
 
933
         * If the event is due to disconnect cmd from the host, only they
 
934
         * the target would stop trying to connect. Under any other
 
935
         * condition, target would keep trying to connect.
 
936
         */
 
937
        if (reason == DISCONNECT_CMD) {
 
938
                if (!ar->usr_bss_filter && test_bit(WMI_READY, &ar->flag))
 
939
                        ath6kl_wmi_bssfilter_cmd(ar->wmi, vif->fw_vif_idx,
 
940
                                                 NONE_BSS_FILTER, 0);
 
941
        } else {
 
942
                set_bit(CONNECT_PEND, &vif->flags);
 
943
                if (((reason == ASSOC_FAILED) &&
 
944
                    (prot_reason_status == 0x11)) ||
 
945
                    ((reason == ASSOC_FAILED) && (prot_reason_status == 0x0)
 
946
                     && (vif->reconnect_flag == 1))) {
 
947
                        set_bit(CONNECTED, &vif->flags);
 
948
                        return;
 
949
                }
 
950
        }
 
951
 
 
952
        /* update connect & link status atomically */
 
953
        spin_lock_bh(&vif->if_lock);
 
954
        clear_bit(CONNECTED, &vif->flags);
 
955
        netif_carrier_off(vif->ndev);
 
956
        spin_unlock_bh(&vif->if_lock);
 
957
 
 
958
        if ((reason != CSERV_DISCONNECT) || (vif->reconnect_flag != 1))
 
959
                vif->reconnect_flag = 0;
 
960
 
 
961
        if (reason != CSERV_DISCONNECT)
 
962
                ar->user_key_ctrl = 0;
 
963
 
 
964
        netif_stop_queue(vif->ndev);
 
965
        memset(vif->bssid, 0, sizeof(vif->bssid));
 
966
        vif->bss_ch = 0;
 
967
 
 
968
        ath6kl_tx_data_cleanup(ar);
 
969
}
 
970
 
 
971
struct ath6kl_vif *ath6kl_vif_first(struct ath6kl *ar)
 
972
{
 
973
        struct ath6kl_vif *vif;
 
974
 
 
975
        spin_lock_bh(&ar->list_lock);
 
976
        if (list_empty(&ar->vif_list)) {
 
977
                spin_unlock_bh(&ar->list_lock);
 
978
                return NULL;
 
979
        }
 
980
 
 
981
        vif = list_first_entry(&ar->vif_list, struct ath6kl_vif, list);
 
982
 
 
983
        spin_unlock_bh(&ar->list_lock);
 
984
 
 
985
        return vif;
 
986
}
 
987
 
 
988
static int ath6kl_open(struct net_device *dev)
 
989
{
 
990
        struct ath6kl_vif *vif = netdev_priv(dev);
 
991
 
 
992
        set_bit(WLAN_ENABLED, &vif->flags);
 
993
 
 
994
        if (test_bit(CONNECTED, &vif->flags)) {
 
995
                netif_carrier_on(dev);
 
996
                netif_wake_queue(dev);
 
997
        } else
 
998
                netif_carrier_off(dev);
 
999
 
 
1000
        return 0;
 
1001
}
 
1002
 
 
1003
static int ath6kl_close(struct net_device *dev)
 
1004
{
 
1005
        struct ath6kl_vif *vif = netdev_priv(dev);
 
1006
 
 
1007
        netif_stop_queue(dev);
 
1008
 
 
1009
        ath6kl_cfg80211_stop(vif);
 
1010
 
 
1011
        clear_bit(WLAN_ENABLED, &vif->flags);
 
1012
 
 
1013
        return 0;
 
1014
}
 
1015
 
 
1016
static struct net_device_stats *ath6kl_get_stats(struct net_device *dev)
 
1017
{
 
1018
        struct ath6kl_vif *vif = netdev_priv(dev);
 
1019
 
 
1020
        return &vif->net_stats;
 
1021
}
 
1022
 
 
1023
static struct net_device_ops ath6kl_netdev_ops = {
 
1024
        .ndo_open               = ath6kl_open,
 
1025
        .ndo_stop               = ath6kl_close,
 
1026
        .ndo_start_xmit         = ath6kl_data_tx,
 
1027
        .ndo_get_stats          = ath6kl_get_stats,
 
1028
};
 
1029
 
 
1030
void init_netdev(struct net_device *dev)
 
1031
{
 
1032
        netdev_attach_ops(dev, &ath6kl_netdev_ops);
 
1033
        dev->destructor = free_netdev;
 
1034
        dev->watchdog_timeo = ATH6KL_TX_TIMEOUT;
 
1035
 
 
1036
        dev->needed_headroom = ETH_HLEN;
 
1037
        dev->needed_headroom += sizeof(struct ath6kl_llc_snap_hdr) +
 
1038
                                sizeof(struct wmi_data_hdr) + HTC_HDR_LENGTH
 
1039
                                + WMI_MAX_TX_META_SZ + ATH6KL_HTC_ALIGN_BYTES;
 
1040
 
 
1041
        return;
 
1042
}