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