ath6kl: Fix buffer alignment for scatter-gather I/O
[pandora-kernel.git] / drivers / net / wireless / ath / ath6kl / init.c
1
2 /*
3  * Copyright (c) 2011 Atheros Communications Inc.
4  *
5  * Permission to use, copy, modify, and/or distribute this software for any
6  * purpose with or without fee is hereby granted, provided that the above
7  * copyright notice and this permission notice appear in all copies.
8  *
9  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
10  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
11  * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
12  * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
13  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
14  * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
15  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
16  */
17
18 #include <linux/mmc/sdio_func.h>
19 #include "core.h"
20 #include "cfg80211.h"
21 #include "target.h"
22 #include "debug.h"
23 #include "hif-ops.h"
24
25 unsigned int debug_mask;
26
27 module_param(debug_mask, uint, 0644);
28
29 /*
30  * Include definitions here that can be used to tune the WLAN module
31  * behavior. Different customers can tune the behavior as per their needs,
32  * here.
33  */
34
35 /*
36  * This configuration item enable/disable keepalive support.
37  * Keepalive support: In the absence of any data traffic to AP, null
38  * frames will be sent to the AP at periodic interval, to keep the association
39  * active. This configuration item defines the periodic interval.
40  * Use value of zero to disable keepalive support
41  * Default: 60 seconds
42  */
43 #define WLAN_CONFIG_KEEP_ALIVE_INTERVAL 60
44
45 /*
46  * This configuration item sets the value of disconnect timeout
47  * Firmware delays sending the disconnec event to the host for this
48  * timeout after is gets disconnected from the current AP.
49  * If the firmware successly roams within the disconnect timeout
50  * it sends a new connect event
51  */
52 #define WLAN_CONFIG_DISCONNECT_TIMEOUT 10
53
54 #define CONFIG_AR600x_DEBUG_UART_TX_PIN 8
55
56 enum addr_type {
57         DATASET_PATCH_ADDR,
58         APP_LOAD_ADDR,
59         APP_START_OVERRIDE_ADDR,
60 };
61
62 #define ATH6KL_DATA_OFFSET    64
63 struct sk_buff *ath6kl_buf_alloc(int size)
64 {
65         struct sk_buff *skb;
66         u16 reserved;
67
68         /* Add chacheline space at front and back of buffer */
69         reserved = (2 * L1_CACHE_BYTES) + ATH6KL_DATA_OFFSET +
70                    sizeof(struct htc_packet) + ATH6KL_HTC_ALIGN_BYTES;
71         skb = dev_alloc_skb(size + reserved);
72
73         if (skb)
74                 skb_reserve(skb, reserved - L1_CACHE_BYTES);
75         return skb;
76 }
77
78 void ath6kl_init_profile_info(struct ath6kl *ar)
79 {
80         ar->ssid_len = 0;
81         memset(ar->ssid, 0, sizeof(ar->ssid));
82
83         ar->dot11_auth_mode = OPEN_AUTH;
84         ar->auth_mode = NONE_AUTH;
85         ar->prwise_crypto = NONE_CRYPT;
86         ar->prwise_crypto_len = 0;
87         ar->grp_crypto = NONE_CRYPT;
88         ar->grp_crpto_len = 0;
89         memset(ar->wep_key_list, 0, sizeof(ar->wep_key_list));
90         memset(ar->req_bssid, 0, sizeof(ar->req_bssid));
91         memset(ar->bssid, 0, sizeof(ar->bssid));
92         ar->bss_ch = 0;
93         ar->nw_type = ar->next_mode = INFRA_NETWORK;
94 }
95
96 static u8 ath6kl_get_fw_iftype(struct ath6kl *ar)
97 {
98         switch (ar->nw_type) {
99         case INFRA_NETWORK:
100                 return HI_OPTION_FW_MODE_BSS_STA;
101         case ADHOC_NETWORK:
102                 return HI_OPTION_FW_MODE_IBSS;
103         case AP_NETWORK:
104                 return HI_OPTION_FW_MODE_AP;
105         default:
106                 ath6kl_err("Unsupported interface type :%d\n", ar->nw_type);
107                 return 0xff;
108         }
109 }
110
111 static inline u32 ath6kl_get_hi_item_addr(struct ath6kl *ar,
112                                           u32 item_offset)
113 {
114         u32 addr = 0;
115
116         if (ar->target_type == TARGET_TYPE_AR6003)
117                 addr = ATH6KL_AR6003_HI_START_ADDR + item_offset;
118         else if (ar->target_type == TARGET_TYPE_AR6004)
119                 addr = ATH6KL_AR6004_HI_START_ADDR + item_offset;
120
121         return addr;
122 }
123
124 static int ath6kl_set_host_app_area(struct ath6kl *ar)
125 {
126         u32 address, data;
127         struct host_app_area host_app_area;
128
129         /* Fetch the address of the host_app_area_s
130          * instance in the host interest area */
131         address = ath6kl_get_hi_item_addr(ar, HI_ITEM(hi_app_host_interest));
132         address = TARG_VTOP(ar->target_type, address);
133
134         if (ath6kl_read_reg_diag(ar, &address, &data))
135                 return -EIO;
136
137         address = TARG_VTOP(ar->target_type, data);
138         host_app_area.wmi_protocol_ver = WMI_PROTOCOL_VERSION;
139         if (ath6kl_access_datadiag(ar, address,
140                                 (u8 *)&host_app_area,
141                                 sizeof(struct host_app_area), false))
142                 return -EIO;
143
144         return 0;
145 }
146
147 static inline void set_ac2_ep_map(struct ath6kl *ar,
148                                   u8 ac,
149                                   enum htc_endpoint_id ep)
150 {
151         ar->ac2ep_map[ac] = ep;
152         ar->ep2ac_map[ep] = ac;
153 }
154
155 /* connect to a service */
156 static int ath6kl_connectservice(struct ath6kl *ar,
157                                  struct htc_service_connect_req  *con_req,
158                                  char *desc)
159 {
160         int status;
161         struct htc_service_connect_resp response;
162
163         memset(&response, 0, sizeof(response));
164
165         status = ath6kl_htc_conn_service(ar->htc_target, con_req, &response);
166         if (status) {
167                 ath6kl_err("failed to connect to %s service status:%d\n",
168                            desc, status);
169                 return status;
170         }
171
172         switch (con_req->svc_id) {
173         case WMI_CONTROL_SVC:
174                 if (test_bit(WMI_ENABLED, &ar->flag))
175                         ath6kl_wmi_set_control_ep(ar->wmi, response.endpoint);
176                 ar->ctrl_ep = response.endpoint;
177                 break;
178         case WMI_DATA_BE_SVC:
179                 set_ac2_ep_map(ar, WMM_AC_BE, response.endpoint);
180                 break;
181         case WMI_DATA_BK_SVC:
182                 set_ac2_ep_map(ar, WMM_AC_BK, response.endpoint);
183                 break;
184         case WMI_DATA_VI_SVC:
185                 set_ac2_ep_map(ar, WMM_AC_VI, response.endpoint);
186                 break;
187         case WMI_DATA_VO_SVC:
188                 set_ac2_ep_map(ar, WMM_AC_VO, response.endpoint);
189                 break;
190         default:
191                 ath6kl_err("service id is not mapped %d\n", con_req->svc_id);
192                 return -EINVAL;
193         }
194
195         return 0;
196 }
197
198 static int ath6kl_init_service_ep(struct ath6kl *ar)
199 {
200         struct htc_service_connect_req connect;
201
202         memset(&connect, 0, sizeof(connect));
203
204         /* these fields are the same for all service endpoints */
205         connect.ep_cb.rx = ath6kl_rx;
206         connect.ep_cb.rx_refill = ath6kl_rx_refill;
207         connect.ep_cb.tx_full = ath6kl_tx_queue_full;
208
209         /*
210          * Set the max queue depth so that our ath6kl_tx_queue_full handler
211          * gets called.
212         */
213         connect.max_txq_depth = MAX_DEFAULT_SEND_QUEUE_DEPTH;
214         connect.ep_cb.rx_refill_thresh = ATH6KL_MAX_RX_BUFFERS / 4;
215         if (!connect.ep_cb.rx_refill_thresh)
216                 connect.ep_cb.rx_refill_thresh++;
217
218         /* connect to control service */
219         connect.svc_id = WMI_CONTROL_SVC;
220         if (ath6kl_connectservice(ar, &connect, "WMI CONTROL"))
221                 return -EIO;
222
223         connect.flags |= HTC_FLGS_TX_BNDL_PAD_EN;
224
225         /*
226          * Limit the HTC message size on the send path, although e can
227          * receive A-MSDU frames of 4K, we will only send ethernet-sized
228          * (802.3) frames on the send path.
229          */
230         connect.max_rxmsg_sz = WMI_MAX_TX_DATA_FRAME_LENGTH;
231
232         /*
233          * To reduce the amount of committed memory for larger A_MSDU
234          * frames, use the recv-alloc threshold mechanism for larger
235          * packets.
236          */
237         connect.ep_cb.rx_alloc_thresh = ATH6KL_BUFFER_SIZE;
238         connect.ep_cb.rx_allocthresh = ath6kl_alloc_amsdu_rxbuf;
239
240         /*
241          * For the remaining data services set the connection flag to
242          * reduce dribbling, if configured to do so.
243          */
244         connect.conn_flags |= HTC_CONN_FLGS_REDUCE_CRED_DRIB;
245         connect.conn_flags &= ~HTC_CONN_FLGS_THRESH_MASK;
246         connect.conn_flags |= HTC_CONN_FLGS_THRESH_LVL_HALF;
247
248         connect.svc_id = WMI_DATA_BE_SVC;
249
250         if (ath6kl_connectservice(ar, &connect, "WMI DATA BE"))
251                 return -EIO;
252
253         /* connect to back-ground map this to WMI LOW_PRI */
254         connect.svc_id = WMI_DATA_BK_SVC;
255         if (ath6kl_connectservice(ar, &connect, "WMI DATA BK"))
256                 return -EIO;
257
258         /* connect to Video service, map this to to HI PRI */
259         connect.svc_id = WMI_DATA_VI_SVC;
260         if (ath6kl_connectservice(ar, &connect, "WMI DATA VI"))
261                 return -EIO;
262
263         /*
264          * Connect to VO service, this is currently not mapped to a WMI
265          * priority stream due to historical reasons. WMI originally
266          * defined 3 priorities over 3 mailboxes We can change this when
267          * WMI is reworked so that priorities are not dependent on
268          * mailboxes.
269          */
270         connect.svc_id = WMI_DATA_VO_SVC;
271         if (ath6kl_connectservice(ar, &connect, "WMI DATA VO"))
272                 return -EIO;
273
274         return 0;
275 }
276
277 static void ath6kl_init_control_info(struct ath6kl *ar)
278 {
279         u8 ctr;
280
281         clear_bit(WMI_ENABLED, &ar->flag);
282         ath6kl_init_profile_info(ar);
283         ar->def_txkey_index = 0;
284         memset(ar->wep_key_list, 0, sizeof(ar->wep_key_list));
285         ar->ch_hint = 0;
286         ar->listen_intvl_t = A_DEFAULT_LISTEN_INTERVAL;
287         ar->listen_intvl_b = 0;
288         ar->tx_pwr = 0;
289         clear_bit(SKIP_SCAN, &ar->flag);
290         set_bit(WMM_ENABLED, &ar->flag);
291         ar->intra_bss = 1;
292         memset(&ar->sc_params, 0, sizeof(ar->sc_params));
293         ar->sc_params.short_scan_ratio = WMI_SHORTSCANRATIO_DEFAULT;
294         ar->sc_params.scan_ctrl_flags = DEFAULT_SCAN_CTRL_FLAGS;
295
296         memset((u8 *)ar->sta_list, 0,
297                AP_MAX_NUM_STA * sizeof(struct ath6kl_sta));
298
299         spin_lock_init(&ar->mcastpsq_lock);
300
301         /* Init the PS queues */
302         for (ctr = 0; ctr < AP_MAX_NUM_STA; ctr++) {
303                 spin_lock_init(&ar->sta_list[ctr].psq_lock);
304                 skb_queue_head_init(&ar->sta_list[ctr].psq);
305         }
306
307         skb_queue_head_init(&ar->mcastpsq);
308
309         memcpy(ar->ap_country_code, DEF_AP_COUNTRY_CODE, 3);
310 }
311
312 /*
313  * Set HTC/Mbox operational parameters, this can only be called when the
314  * target is in the BMI phase.
315  */
316 static int ath6kl_set_htc_params(struct ath6kl *ar, u32 mbox_isr_yield_val,
317                                  u8 htc_ctrl_buf)
318 {
319         int status;
320         u32 blk_size;
321
322         blk_size = ar->mbox_info.block_size;
323
324         if (htc_ctrl_buf)
325                 blk_size |=  ((u32)htc_ctrl_buf) << 16;
326
327         /* set the host interest area for the block size */
328         status = ath6kl_bmi_write(ar,
329                         ath6kl_get_hi_item_addr(ar,
330                         HI_ITEM(hi_mbox_io_block_sz)),
331                         (u8 *)&blk_size,
332                         4);
333         if (status) {
334                 ath6kl_err("bmi_write_memory for IO block size failed\n");
335                 goto out;
336         }
337
338         ath6kl_dbg(ATH6KL_DBG_TRC, "block size set: %d (target addr:0x%X)\n",
339                    blk_size,
340                    ath6kl_get_hi_item_addr(ar, HI_ITEM(hi_mbox_io_block_sz)));
341
342         if (mbox_isr_yield_val) {
343                 /* set the host interest area for the mbox ISR yield limit */
344                 status = ath6kl_bmi_write(ar,
345                                 ath6kl_get_hi_item_addr(ar,
346                                 HI_ITEM(hi_mbox_isr_yield_limit)),
347                                 (u8 *)&mbox_isr_yield_val,
348                                 4);
349                 if (status) {
350                         ath6kl_err("bmi_write_memory for yield limit failed\n");
351                         goto out;
352                 }
353         }
354
355 out:
356         return status;
357 }
358
359 #define REG_DUMP_COUNT_AR6003   60
360 #define REGISTER_DUMP_LEN_MAX   60
361
362 static void ath6kl_dump_target_assert_info(struct ath6kl *ar)
363 {
364         u32 address;
365         u32 regdump_loc = 0;
366         int status;
367         u32 regdump_val[REGISTER_DUMP_LEN_MAX];
368         u32 i;
369
370         if (ar->target_type != TARGET_TYPE_AR6003)
371                 return;
372
373         /* the reg dump pointer is copied to the host interest area */
374         address = ath6kl_get_hi_item_addr(ar, HI_ITEM(hi_failure_state));
375         address = TARG_VTOP(ar->target_type, address);
376
377         /* read RAM location through diagnostic window */
378         status = ath6kl_read_reg_diag(ar, &address, &regdump_loc);
379
380         if (status || !regdump_loc) {
381                 ath6kl_err("failed to get ptr to register dump area\n");
382                 return;
383         }
384
385         ath6kl_dbg(ATH6KL_DBG_TRC, "location of register dump data: 0x%X\n",
386                 regdump_loc);
387         regdump_loc = TARG_VTOP(ar->target_type, regdump_loc);
388
389         /* fetch register dump data */
390         status = ath6kl_access_datadiag(ar,
391                                         regdump_loc,
392                                         (u8 *)&regdump_val[0],
393                                         REG_DUMP_COUNT_AR6003 * (sizeof(u32)),
394                                         true);
395
396         if (status) {
397                 ath6kl_err("failed to get register dump\n");
398                 return;
399         }
400         ath6kl_dbg(ATH6KL_DBG_TRC, "Register Dump:\n");
401
402         for (i = 0; i < REG_DUMP_COUNT_AR6003; i++)
403                 ath6kl_dbg(ATH6KL_DBG_TRC, " %d :  0x%8.8X\n",
404                            i, regdump_val[i]);
405
406 }
407
408 void ath6kl_target_failure(struct ath6kl *ar)
409 {
410         ath6kl_err("target asserted\n");
411
412         /* try dumping target assertion information (if any) */
413         ath6kl_dump_target_assert_info(ar);
414
415 }
416
417 static int ath6kl_target_config_wlan_params(struct ath6kl *ar)
418 {
419         int status = 0;
420
421         /*
422          * Configure the device for rx dot11 header rules. "0,0" are the
423          * default values. Required if checksum offload is needed. Set
424          * RxMetaVersion to 2.
425          */
426         if (ath6kl_wmi_set_rx_frame_format_cmd(ar->wmi,
427                                                ar->rx_meta_ver, 0, 0)) {
428                 ath6kl_err("unable to set the rx frame format\n");
429                 status = -EIO;
430         }
431
432         if (ar->conf_flags & ATH6KL_CONF_IGNORE_PS_FAIL_EVT_IN_SCAN)
433                 if ((ath6kl_wmi_pmparams_cmd(ar->wmi, 0, 1, 0, 0, 1,
434                      IGNORE_POWER_SAVE_FAIL_EVENT_DURING_SCAN)) != 0) {
435                         ath6kl_err("unable to set power save fail event policy\n");
436                         status = -EIO;
437                 }
438
439         if (!(ar->conf_flags & ATH6KL_CONF_IGNORE_ERP_BARKER))
440                 if ((ath6kl_wmi_set_lpreamble_cmd(ar->wmi, 0,
441                      WMI_DONOT_IGNORE_BARKER_IN_ERP)) != 0) {
442                         ath6kl_err("unable to set barker preamble policy\n");
443                         status = -EIO;
444                 }
445
446         if (ath6kl_wmi_set_keepalive_cmd(ar->wmi,
447                         WLAN_CONFIG_KEEP_ALIVE_INTERVAL)) {
448                 ath6kl_err("unable to set keep alive interval\n");
449                 status = -EIO;
450         }
451
452         if (ath6kl_wmi_disctimeout_cmd(ar->wmi,
453                         WLAN_CONFIG_DISCONNECT_TIMEOUT)) {
454                 ath6kl_err("unable to set disconnect timeout\n");
455                 status = -EIO;
456         }
457
458         if (!(ar->conf_flags & ATH6KL_CONF_ENABLE_TX_BURST))
459                 if (ath6kl_wmi_set_wmm_txop(ar->wmi, WMI_TXOP_DISABLED)) {
460                         ath6kl_err("unable to set txop bursting\n");
461                         status = -EIO;
462                 }
463
464         return status;
465 }
466
467 int ath6kl_configure_target(struct ath6kl *ar)
468 {
469         u32 param, ram_reserved_size;
470         u8 fw_iftype;
471
472         fw_iftype = ath6kl_get_fw_iftype(ar);
473         if (fw_iftype == 0xff)
474                 return -EINVAL;
475
476         /* Tell target which HTC version it is used*/
477         param = HTC_PROTOCOL_VERSION;
478         if (ath6kl_bmi_write(ar,
479                              ath6kl_get_hi_item_addr(ar,
480                              HI_ITEM(hi_app_host_interest)),
481                              (u8 *)&param, 4) != 0) {
482                 ath6kl_err("bmi_write_memory for htc version failed\n");
483                 return -EIO;
484         }
485
486         /* set the firmware mode to STA/IBSS/AP */
487         param = 0;
488
489         if (ath6kl_bmi_read(ar,
490                             ath6kl_get_hi_item_addr(ar,
491                             HI_ITEM(hi_option_flag)),
492                             (u8 *)&param, 4) != 0) {
493                 ath6kl_err("bmi_read_memory for setting fwmode failed\n");
494                 return -EIO;
495         }
496
497         param |= (1 << HI_OPTION_NUM_DEV_SHIFT);
498         param |= (fw_iftype << HI_OPTION_FW_MODE_SHIFT);
499         param |= (0 << HI_OPTION_MAC_ADDR_METHOD_SHIFT);
500         param |= (0 << HI_OPTION_FW_BRIDGE_SHIFT);
501
502         if (ath6kl_bmi_write(ar,
503                              ath6kl_get_hi_item_addr(ar,
504                              HI_ITEM(hi_option_flag)),
505                              (u8 *)&param,
506                              4) != 0) {
507                 ath6kl_err("bmi_write_memory for setting fwmode failed\n");
508                 return -EIO;
509         }
510
511         ath6kl_dbg(ATH6KL_DBG_TRC, "firmware mode set\n");
512
513         /*
514          * Hardcode the address use for the extended board data
515          * Ideally this should be pre-allocate by the OS at boot time
516          * But since it is a new feature and board data is loaded
517          * at init time, we have to workaround this from host.
518          * It is difficult to patch the firmware boot code,
519          * but possible in theory.
520          */
521
522         if (ar->target_type == TARGET_TYPE_AR6003 ||
523             ar->target_type == TARGET_TYPE_AR6004) {
524                 if (ar->version.target_ver == AR6003_REV2_VERSION) {
525                         param = AR6003_REV2_BOARD_EXT_DATA_ADDRESS;
526                         ram_reserved_size =  AR6003_REV2_RAM_RESERVE_SIZE;
527                 } else if (ar->version.target_ver == AR6004_REV1_VERSION) {
528                         param = AR6004_REV1_BOARD_EXT_DATA_ADDRESS;
529                         ram_reserved_size =  AR6004_REV1_RAM_RESERVE_SIZE;
530                 } else {
531                         param = AR6003_REV3_BOARD_EXT_DATA_ADDRESS;
532                         ram_reserved_size =  AR6003_REV3_RAM_RESERVE_SIZE;
533                 }
534
535                 if (ath6kl_bmi_write(ar,
536                                      ath6kl_get_hi_item_addr(ar,
537                                      HI_ITEM(hi_board_ext_data)),
538                                      (u8 *)&param, 4) != 0) {
539                         ath6kl_err("bmi_write_memory for hi_board_ext_data failed\n");
540                         return -EIO;
541                 }
542                 if (ath6kl_bmi_write(ar,
543                                      ath6kl_get_hi_item_addr(ar,
544                                      HI_ITEM(hi_end_ram_reserve_sz)),
545                                      (u8 *)&ram_reserved_size, 4) != 0) {
546                         ath6kl_err("bmi_write_memory for hi_end_ram_reserve_sz failed\n");
547                         return -EIO;
548                 }
549         }
550
551         /* set the block size for the target */
552         if (ath6kl_set_htc_params(ar, MBOX_YIELD_LIMIT, 0))
553                 /* use default number of control buffers */
554                 return -EIO;
555
556         return 0;
557 }
558
559 struct ath6kl *ath6kl_core_alloc(struct device *sdev)
560 {
561         struct net_device *dev;
562         struct ath6kl *ar;
563         struct wireless_dev *wdev;
564
565         wdev = ath6kl_cfg80211_init(sdev);
566         if (!wdev) {
567                 ath6kl_err("ath6kl_cfg80211_init failed\n");
568                 return NULL;
569         }
570
571         ar = wdev_priv(wdev);
572         ar->dev = sdev;
573         ar->wdev = wdev;
574         wdev->iftype = NL80211_IFTYPE_STATION;
575
576         dev = alloc_netdev(0, "wlan%d", ether_setup);
577         if (!dev) {
578                 ath6kl_err("no memory for network device instance\n");
579                 ath6kl_cfg80211_deinit(ar);
580                 return NULL;
581         }
582
583         dev->ieee80211_ptr = wdev;
584         SET_NETDEV_DEV(dev, wiphy_dev(wdev->wiphy));
585         wdev->netdev = dev;
586         ar->sme_state = SME_DISCONNECTED;
587         ar->auto_auth_stage = AUTH_IDLE;
588
589         init_netdev(dev);
590
591         ar->net_dev = dev;
592         set_bit(WLAN_ENABLED, &ar->flag);
593
594         ar->wlan_pwr_state = WLAN_POWER_STATE_ON;
595
596         spin_lock_init(&ar->lock);
597
598         ath6kl_init_control_info(ar);
599         init_waitqueue_head(&ar->event_wq);
600         sema_init(&ar->sem, 1);
601         clear_bit(DESTROY_IN_PROGRESS, &ar->flag);
602
603         INIT_LIST_HEAD(&ar->amsdu_rx_buffer_queue);
604
605         setup_timer(&ar->disconnect_timer, disconnect_timer_handler,
606                     (unsigned long) dev);
607
608         return ar;
609 }
610
611 int ath6kl_unavail_ev(struct ath6kl *ar)
612 {
613         ath6kl_destroy(ar->net_dev, 1);
614
615         return 0;
616 }
617
618 /* firmware upload */
619 static u32 ath6kl_get_load_address(u32 target_ver, enum addr_type type)
620 {
621         WARN_ON(target_ver != AR6003_REV2_VERSION &&
622                 target_ver != AR6003_REV3_VERSION &&
623                 target_ver != AR6004_REV1_VERSION);
624
625         switch (type) {
626         case DATASET_PATCH_ADDR:
627                 return (target_ver == AR6003_REV2_VERSION) ?
628                         AR6003_REV2_DATASET_PATCH_ADDRESS :
629                         AR6003_REV3_DATASET_PATCH_ADDRESS;
630         case APP_LOAD_ADDR:
631                 return (target_ver == AR6003_REV2_VERSION) ?
632                         AR6003_REV2_APP_LOAD_ADDRESS :
633                         0x1234;
634         case APP_START_OVERRIDE_ADDR:
635                 return (target_ver == AR6003_REV2_VERSION) ?
636                         AR6003_REV2_APP_START_OVERRIDE :
637                         AR6003_REV3_APP_START_OVERRIDE;
638         default:
639                 return 0;
640         }
641 }
642
643 static int ath6kl_get_fw(struct ath6kl *ar, const char *filename,
644                          u8 **fw, size_t *fw_len)
645 {
646         const struct firmware *fw_entry;
647         int ret;
648
649         ret = request_firmware(&fw_entry, filename, ar->dev);
650         if (ret)
651                 return ret;
652
653         *fw_len = fw_entry->size;
654         *fw = kmemdup(fw_entry->data, fw_entry->size, GFP_KERNEL);
655
656         if (*fw == NULL)
657                 ret = -ENOMEM;
658
659         release_firmware(fw_entry);
660
661         return ret;
662 }
663
664 static int ath6kl_fetch_board_file(struct ath6kl *ar)
665 {
666         const char *filename;
667         int ret;
668
669         switch (ar->version.target_ver) {
670         case AR6003_REV2_VERSION:
671                 filename = AR6003_REV2_BOARD_DATA_FILE;
672                 break;
673         case AR6004_REV1_VERSION:
674                 filename = AR6004_REV1_BOARD_DATA_FILE;
675                 break;
676         default:
677                 filename = AR6003_REV3_BOARD_DATA_FILE;
678                 break;
679         }
680
681         ret = ath6kl_get_fw(ar, filename, &ar->fw_board,
682                             &ar->fw_board_len);
683         if (ret == 0) {
684                 /* managed to get proper board file */
685                 return 0;
686         }
687
688         /* there was no proper board file, try to use default instead */
689         ath6kl_warn("Failed to get board file %s (%d), trying to find default board file.\n",
690                     filename, ret);
691
692         switch (ar->version.target_ver) {
693         case AR6003_REV2_VERSION:
694                 filename = AR6003_REV2_DEFAULT_BOARD_DATA_FILE;
695                 break;
696         case AR6004_REV1_VERSION:
697                 filename = AR6004_REV1_DEFAULT_BOARD_DATA_FILE;
698                 break;
699         default:
700                 filename = AR6003_REV3_DEFAULT_BOARD_DATA_FILE;
701                 break;
702         }
703
704         ret = ath6kl_get_fw(ar, filename, &ar->fw_board,
705                             &ar->fw_board_len);
706         if (ret) {
707                 ath6kl_err("Failed to get default board file %s: %d\n",
708                            filename, ret);
709                 return ret;
710         }
711
712         ath6kl_warn("WARNING! No proper board file was not found, instead using a default board file.\n");
713         ath6kl_warn("Most likely your hardware won't work as specified. Install correct board file!\n");
714
715         return 0;
716 }
717
718
719 static int ath6kl_upload_board_file(struct ath6kl *ar)
720 {
721         u32 board_address, board_ext_address, param;
722         u32 board_data_size, board_ext_data_size;
723         int ret;
724
725         if (ar->fw_board == NULL) {
726                 ret = ath6kl_fetch_board_file(ar);
727                 if (ret)
728                         return ret;
729         }
730
731         /*
732          * Determine where in Target RAM to write Board Data.
733          * For AR6004, host determine Target RAM address for
734          * writing board data.
735          */
736         if (ar->target_type == TARGET_TYPE_AR6004) {
737                 board_address = AR6004_REV1_BOARD_DATA_ADDRESS;
738                 ath6kl_bmi_write(ar,
739                                 ath6kl_get_hi_item_addr(ar,
740                                 HI_ITEM(hi_board_data)),
741                                 (u8 *) &board_address, 4);
742         } else {
743                 ath6kl_bmi_read(ar,
744                                 ath6kl_get_hi_item_addr(ar,
745                                 HI_ITEM(hi_board_data)),
746                                 (u8 *) &board_address, 4);
747         }
748
749         ath6kl_dbg(ATH6KL_DBG_TRC, "board data download addr: 0x%x\n",
750                    board_address);
751
752         /* determine where in target ram to write extended board data */
753         ath6kl_bmi_read(ar,
754                         ath6kl_get_hi_item_addr(ar,
755                         HI_ITEM(hi_board_ext_data)),
756                         (u8 *) &board_ext_address, 4);
757
758         ath6kl_dbg(ATH6KL_DBG_TRC, "board file download addr: 0x%x\n",
759                    board_ext_address);
760
761         if (board_ext_address == 0) {
762                 ath6kl_err("Failed to get board file target address.\n");
763                 return -EINVAL;
764         }
765
766         switch (ar->target_type) {
767         case TARGET_TYPE_AR6003:
768                 board_data_size = AR6003_BOARD_DATA_SZ;
769                 board_ext_data_size = AR6003_BOARD_EXT_DATA_SZ;
770                 break;
771         case TARGET_TYPE_AR6004:
772                 board_data_size = AR6004_BOARD_DATA_SZ;
773                 board_ext_data_size = AR6004_BOARD_EXT_DATA_SZ;
774                 break;
775         default:
776                 WARN_ON(1);
777                 return -EINVAL;
778                 break;
779         }
780
781         if (ar->fw_board_len == (board_data_size +
782                                  board_ext_data_size)) {
783
784                 /* write extended board data */
785                 ret = ath6kl_bmi_write(ar, board_ext_address,
786                                        ar->fw_board + board_data_size,
787                                        board_ext_data_size);
788                 if (ret) {
789                         ath6kl_err("Failed to write extended board data: %d\n",
790                                    ret);
791                         return ret;
792                 }
793
794                 /* record that extended board data is initialized */
795                 param = (board_ext_data_size << 16) | 1;
796
797                 ath6kl_bmi_write(ar,
798                                  ath6kl_get_hi_item_addr(ar,
799                                  HI_ITEM(hi_board_ext_data_config)),
800                                  (unsigned char *) &param, 4);
801         }
802
803         if (ar->fw_board_len < board_data_size) {
804                 ath6kl_err("Too small board file: %zu\n", ar->fw_board_len);
805                 ret = -EINVAL;
806                 return ret;
807         }
808
809         ret = ath6kl_bmi_write(ar, board_address, ar->fw_board,
810                                board_data_size);
811
812         if (ret) {
813                 ath6kl_err("Board file bmi write failed: %d\n", ret);
814                 return ret;
815         }
816
817         /* record the fact that Board Data IS initialized */
818         param = 1;
819         ath6kl_bmi_write(ar,
820                          ath6kl_get_hi_item_addr(ar,
821                          HI_ITEM(hi_board_data_initialized)),
822                          (u8 *)&param, 4);
823
824         return ret;
825 }
826
827 static int ath6kl_upload_otp(struct ath6kl *ar)
828 {
829         const char *filename;
830         u32 address, param;
831         int ret;
832
833         switch (ar->version.target_ver) {
834         case AR6003_REV2_VERSION:
835                 filename = AR6003_REV2_OTP_FILE;
836                 break;
837         case AR6004_REV1_VERSION:
838                 ath6kl_dbg(ATH6KL_DBG_TRC, "AR6004 doesn't need OTP file\n");
839                 return 0;
840                 break;
841         default:
842                 filename = AR6003_REV3_OTP_FILE;
843                 break;
844         }
845
846         if (ar->fw_otp == NULL) {
847                 ret = ath6kl_get_fw(ar, filename, &ar->fw_otp,
848                                     &ar->fw_otp_len);
849                 if (ret) {
850                         ath6kl_err("Failed to get OTP file %s: %d\n",
851                                    filename, ret);
852                         return ret;
853                 }
854         }
855
856         address = ath6kl_get_load_address(ar->version.target_ver,
857                                           APP_LOAD_ADDR);
858
859         ret = ath6kl_bmi_fast_download(ar, address, ar->fw_otp,
860                                        ar->fw_otp_len);
861         if (ret) {
862                 ath6kl_err("Failed to upload OTP file: %d\n", ret);
863                 return ret;
864         }
865
866         /* execute the OTP code */
867         param = 0;
868         address = ath6kl_get_load_address(ar->version.target_ver,
869                                           APP_START_OVERRIDE_ADDR);
870         ath6kl_bmi_execute(ar, address, &param);
871
872         return ret;
873 }
874
875 static int ath6kl_upload_firmware(struct ath6kl *ar)
876 {
877         const char *filename;
878         u32 address;
879         int ret;
880
881         switch (ar->version.target_ver) {
882         case AR6003_REV2_VERSION:
883                 filename = AR6003_REV2_FIRMWARE_FILE;
884                 break;
885         case AR6004_REV1_VERSION:
886                 filename = AR6004_REV1_FIRMWARE_FILE;
887                 break;
888         default:
889                 filename = AR6003_REV3_FIRMWARE_FILE;
890                 break;
891         }
892
893         if (ar->fw == NULL) {
894                 ret = ath6kl_get_fw(ar, filename, &ar->fw, &ar->fw_len);
895                 if (ret) {
896                         ath6kl_err("Failed to get firmware file %s: %d\n",
897                                    filename, ret);
898                         return ret;
899                 }
900         }
901
902         address = ath6kl_get_load_address(ar->version.target_ver,
903                                           APP_LOAD_ADDR);
904
905         ret = ath6kl_bmi_fast_download(ar, address, ar->fw, ar->fw_len);
906
907         if (ret) {
908                 ath6kl_err("Failed to write firmware: %d\n", ret);
909                 return ret;
910         }
911
912         /*
913          * Set starting address for firmware
914          * Don't need to setup app_start override addr on AR6004
915          */
916         if (ar->target_type != TARGET_TYPE_AR6004) {
917                 address = ath6kl_get_load_address(ar->version.target_ver,
918                                                   APP_START_OVERRIDE_ADDR);
919                 ath6kl_bmi_set_app_start(ar, address);
920         }
921         return ret;
922 }
923
924 static int ath6kl_upload_patch(struct ath6kl *ar)
925 {
926         const char *filename;
927         u32 address, param;
928         int ret;
929
930         switch (ar->version.target_ver) {
931         case AR6003_REV2_VERSION:
932                 filename = AR6003_REV2_PATCH_FILE;
933                 break;
934         case AR6004_REV1_VERSION:
935                 /* FIXME: implement for AR6004 */
936                 return 0;
937                 break;
938         default:
939                 filename = AR6003_REV3_PATCH_FILE;
940                 break;
941         }
942
943         if (ar->fw_patch == NULL) {
944                 ret = ath6kl_get_fw(ar, filename, &ar->fw_patch,
945                                     &ar->fw_patch_len);
946                 if (ret) {
947                         ath6kl_err("Failed to get patch file %s: %d\n",
948                                    filename, ret);
949                         return ret;
950                 }
951         }
952
953         address = ath6kl_get_load_address(ar->version.target_ver,
954                                           DATASET_PATCH_ADDR);
955
956         ret = ath6kl_bmi_write(ar, address, ar->fw_patch, ar->fw_patch_len);
957         if (ret) {
958                 ath6kl_err("Failed to write patch file: %d\n", ret);
959                 return ret;
960         }
961
962         param = address;
963         ath6kl_bmi_write(ar,
964                          ath6kl_get_hi_item_addr(ar,
965                          HI_ITEM(hi_dset_list_head)),
966                          (unsigned char *) &param, 4);
967
968         return 0;
969 }
970
971 static int ath6kl_init_upload(struct ath6kl *ar)
972 {
973         u32 param, options, sleep, address;
974         int status = 0;
975
976         if (ar->target_type != TARGET_TYPE_AR6003 &&
977                 ar->target_type != TARGET_TYPE_AR6004)
978                 return -EINVAL;
979
980         /* temporarily disable system sleep */
981         address = MBOX_BASE_ADDRESS + LOCAL_SCRATCH_ADDRESS;
982         status = ath6kl_bmi_reg_read(ar, address, &param);
983         if (status)
984                 return status;
985
986         options = param;
987
988         param |= ATH6KL_OPTION_SLEEP_DISABLE;
989         status = ath6kl_bmi_reg_write(ar, address, param);
990         if (status)
991                 return status;
992
993         address = RTC_BASE_ADDRESS + SYSTEM_SLEEP_ADDRESS;
994         status = ath6kl_bmi_reg_read(ar, address, &param);
995         if (status)
996                 return status;
997
998         sleep = param;
999
1000         param |= SM(SYSTEM_SLEEP_DISABLE, 1);
1001         status = ath6kl_bmi_reg_write(ar, address, param);
1002         if (status)
1003                 return status;
1004
1005         ath6kl_dbg(ATH6KL_DBG_TRC, "old options: %d, old sleep: %d\n",
1006                    options, sleep);
1007
1008         /* program analog PLL register */
1009         /* no need to control 40/44MHz clock on AR6004 */
1010         if (ar->target_type != TARGET_TYPE_AR6004) {
1011                 status = ath6kl_bmi_reg_write(ar, ATH6KL_ANALOG_PLL_REGISTER,
1012                                               0xF9104001);
1013
1014                 if (status)
1015                         return status;
1016
1017                 /* Run at 80/88MHz by default */
1018                 param = SM(CPU_CLOCK_STANDARD, 1);
1019
1020                 address = RTC_BASE_ADDRESS + CPU_CLOCK_ADDRESS;
1021                 status = ath6kl_bmi_reg_write(ar, address, param);
1022                 if (status)
1023                         return status;
1024         }
1025
1026         param = 0;
1027         address = RTC_BASE_ADDRESS + LPO_CAL_ADDRESS;
1028         param = SM(LPO_CAL_ENABLE, 1);
1029         status = ath6kl_bmi_reg_write(ar, address, param);
1030         if (status)
1031                 return status;
1032
1033         /* WAR to avoid SDIO CRC err */
1034         if (ar->version.target_ver == AR6003_REV2_VERSION) {
1035                 ath6kl_err("temporary war to avoid sdio crc error\n");
1036
1037                 param = 0x20;
1038
1039                 address = GPIO_BASE_ADDRESS + GPIO_PIN10_ADDRESS;
1040                 status = ath6kl_bmi_reg_write(ar, address, param);
1041                 if (status)
1042                         return status;
1043
1044                 address = GPIO_BASE_ADDRESS + GPIO_PIN11_ADDRESS;
1045                 status = ath6kl_bmi_reg_write(ar, address, param);
1046                 if (status)
1047                         return status;
1048
1049                 address = GPIO_BASE_ADDRESS + GPIO_PIN12_ADDRESS;
1050                 status = ath6kl_bmi_reg_write(ar, address, param);
1051                 if (status)
1052                         return status;
1053
1054                 address = GPIO_BASE_ADDRESS + GPIO_PIN13_ADDRESS;
1055                 status = ath6kl_bmi_reg_write(ar, address, param);
1056                 if (status)
1057                         return status;
1058         }
1059
1060         /* write EEPROM data to Target RAM */
1061         status = ath6kl_upload_board_file(ar);
1062         if (status)
1063                 return status;
1064
1065         /* transfer One time Programmable data */
1066         status = ath6kl_upload_otp(ar);
1067         if (status)
1068                 return status;
1069
1070         /* Download Target firmware */
1071         status = ath6kl_upload_firmware(ar);
1072         if (status)
1073                 return status;
1074
1075         status = ath6kl_upload_patch(ar);
1076         if (status)
1077                 return status;
1078
1079         /* Restore system sleep */
1080         address = RTC_BASE_ADDRESS + SYSTEM_SLEEP_ADDRESS;
1081         status = ath6kl_bmi_reg_write(ar, address, sleep);
1082         if (status)
1083                 return status;
1084
1085         address = MBOX_BASE_ADDRESS + LOCAL_SCRATCH_ADDRESS;
1086         param = options | 0x20;
1087         status = ath6kl_bmi_reg_write(ar, address, param);
1088         if (status)
1089                 return status;
1090
1091         /* Configure GPIO AR6003 UART */
1092         param = CONFIG_AR600x_DEBUG_UART_TX_PIN;
1093         status = ath6kl_bmi_write(ar,
1094                                   ath6kl_get_hi_item_addr(ar,
1095                                   HI_ITEM(hi_dbg_uart_txpin)),
1096                                   (u8 *)&param, 4);
1097
1098         return status;
1099 }
1100
1101 static int ath6kl_init(struct net_device *dev)
1102 {
1103         struct ath6kl *ar = ath6kl_priv(dev);
1104         int status = 0;
1105         s32 timeleft;
1106
1107         if (!ar)
1108                 return -EIO;
1109
1110         /* Do we need to finish the BMI phase */
1111         if (ath6kl_bmi_done(ar)) {
1112                 status = -EIO;
1113                 goto ath6kl_init_done;
1114         }
1115
1116         /* Indicate that WMI is enabled (although not ready yet) */
1117         set_bit(WMI_ENABLED, &ar->flag);
1118         ar->wmi = ath6kl_wmi_init(ar);
1119         if (!ar->wmi) {
1120                 ath6kl_err("failed to initialize wmi\n");
1121                 status = -EIO;
1122                 goto ath6kl_init_done;
1123         }
1124
1125         ath6kl_dbg(ATH6KL_DBG_TRC, "%s: got wmi @ 0x%p.\n", __func__, ar->wmi);
1126
1127         wlan_node_table_init(&ar->scan_table);
1128
1129         /*
1130          * The reason we have to wait for the target here is that the
1131          * driver layer has to init BMI in order to set the host block
1132          * size.
1133          */
1134         if (ath6kl_htc_wait_target(ar->htc_target)) {
1135                 status = -EIO;
1136                 goto err_node_cleanup;
1137         }
1138
1139         if (ath6kl_init_service_ep(ar)) {
1140                 status = -EIO;
1141                 goto err_cleanup_scatter;
1142         }
1143
1144         /* setup access class priority mappings */
1145         ar->ac_stream_pri_map[WMM_AC_BK] = 0; /* lowest  */
1146         ar->ac_stream_pri_map[WMM_AC_BE] = 1;
1147         ar->ac_stream_pri_map[WMM_AC_VI] = 2;
1148         ar->ac_stream_pri_map[WMM_AC_VO] = 3; /* highest */
1149
1150         /* give our connected endpoints some buffers */
1151         ath6kl_rx_refill(ar->htc_target, ar->ctrl_ep);
1152         ath6kl_rx_refill(ar->htc_target, ar->ac2ep_map[WMM_AC_BE]);
1153
1154         /* allocate some buffers that handle larger AMSDU frames */
1155         ath6kl_refill_amsdu_rxbufs(ar, ATH6KL_MAX_AMSDU_RX_BUFFERS);
1156
1157         /* setup credit distribution */
1158         ath6k_setup_credit_dist(ar->htc_target, &ar->credit_state_info);
1159
1160         ath6kl_cookie_init(ar);
1161
1162         /* start HTC */
1163         status = ath6kl_htc_start(ar->htc_target);
1164
1165         if (status) {
1166                 ath6kl_cookie_cleanup(ar);
1167                 goto err_rxbuf_cleanup;
1168         }
1169
1170         /* Wait for Wmi event to be ready */
1171         timeleft = wait_event_interruptible_timeout(ar->event_wq,
1172                                                     test_bit(WMI_READY,
1173                                                              &ar->flag),
1174                                                     WMI_TIMEOUT);
1175
1176         if (ar->version.abi_ver != ATH6KL_ABI_VERSION) {
1177                 ath6kl_err("abi version mismatch: host(0x%x), target(0x%x)\n",
1178                            ATH6KL_ABI_VERSION, ar->version.abi_ver);
1179                 status = -EIO;
1180                 goto err_htc_stop;
1181         }
1182
1183         if (!timeleft || signal_pending(current)) {
1184                 ath6kl_err("wmi is not ready or wait was interrupted\n");
1185                 status = -EIO;
1186                 goto err_htc_stop;
1187         }
1188
1189         ath6kl_dbg(ATH6KL_DBG_TRC, "%s: wmi is ready\n", __func__);
1190
1191         /* communicate the wmi protocol verision to the target */
1192         if ((ath6kl_set_host_app_area(ar)) != 0)
1193                 ath6kl_err("unable to set the host app area\n");
1194
1195         ar->conf_flags = ATH6KL_CONF_IGNORE_ERP_BARKER |
1196                          ATH6KL_CONF_ENABLE_11N | ATH6KL_CONF_ENABLE_TX_BURST;
1197
1198         status = ath6kl_target_config_wlan_params(ar);
1199         if (!status)
1200                 goto ath6kl_init_done;
1201
1202 err_htc_stop:
1203         ath6kl_htc_stop(ar->htc_target);
1204 err_rxbuf_cleanup:
1205         ath6kl_htc_flush_rx_buf(ar->htc_target);
1206         ath6kl_cleanup_amsdu_rxbufs(ar);
1207 err_cleanup_scatter:
1208         ath6kl_hif_cleanup_scatter(ar);
1209 err_node_cleanup:
1210         wlan_node_table_cleanup(&ar->scan_table);
1211         ath6kl_wmi_shutdown(ar->wmi);
1212         clear_bit(WMI_ENABLED, &ar->flag);
1213         ar->wmi = NULL;
1214
1215 ath6kl_init_done:
1216         return status;
1217 }
1218
1219 int ath6kl_core_init(struct ath6kl *ar)
1220 {
1221         int ret = 0;
1222         struct ath6kl_bmi_target_info targ_info;
1223
1224         ar->ath6kl_wq = create_singlethread_workqueue("ath6kl");
1225         if (!ar->ath6kl_wq)
1226                 return -ENOMEM;
1227
1228         ret = ath6kl_bmi_init(ar);
1229         if (ret)
1230                 goto err_wq;
1231
1232         ret = ath6kl_bmi_get_target_info(ar, &targ_info);
1233         if (ret)
1234                 goto err_bmi_cleanup;
1235
1236         ar->version.target_ver = le32_to_cpu(targ_info.version);
1237         ar->target_type = le32_to_cpu(targ_info.type);
1238         ar->wdev->wiphy->hw_version = le32_to_cpu(targ_info.version);
1239
1240         ret = ath6kl_configure_target(ar);
1241         if (ret)
1242                 goto err_bmi_cleanup;
1243
1244         ar->htc_target = ath6kl_htc_create(ar);
1245
1246         if (!ar->htc_target) {
1247                 ret = -ENOMEM;
1248                 goto err_bmi_cleanup;
1249         }
1250
1251         ar->aggr_cntxt = aggr_init(ar->net_dev);
1252         if (!ar->aggr_cntxt) {
1253                 ath6kl_err("failed to initialize aggr\n");
1254                 ret = -ENOMEM;
1255                 goto err_htc_cleanup;
1256         }
1257
1258         ret = ath6kl_init_upload(ar);
1259         if (ret)
1260                 goto err_htc_cleanup;
1261
1262         ret = ath6kl_init(ar->net_dev);
1263         if (ret)
1264                 goto err_htc_cleanup;
1265
1266         /* This runs the init function if registered */
1267         ret = register_netdev(ar->net_dev);
1268         if (ret) {
1269                 ath6kl_err("register_netdev failed\n");
1270                 ath6kl_destroy(ar->net_dev, 0);
1271                 return ret;
1272         }
1273
1274         set_bit(NETDEV_REGISTERED, &ar->flag);
1275
1276         ath6kl_dbg(ATH6KL_DBG_TRC, "%s: name=%s dev=0x%p, ar=0x%p\n",
1277                         __func__, ar->net_dev->name, ar->net_dev, ar);
1278
1279         return ret;
1280
1281 err_htc_cleanup:
1282         ath6kl_htc_cleanup(ar->htc_target);
1283 err_bmi_cleanup:
1284         ath6kl_bmi_cleanup(ar);
1285 err_wq:
1286         destroy_workqueue(ar->ath6kl_wq);
1287         return ret;
1288 }
1289
1290 void ath6kl_stop_txrx(struct ath6kl *ar)
1291 {
1292         struct net_device *ndev = ar->net_dev;
1293
1294         if (!ndev)
1295                 return;
1296
1297         set_bit(DESTROY_IN_PROGRESS, &ar->flag);
1298
1299         if (down_interruptible(&ar->sem)) {
1300                 ath6kl_err("down_interruptible failed\n");
1301                 return;
1302         }
1303
1304         if (ar->wlan_pwr_state != WLAN_POWER_STATE_CUT_PWR)
1305                 ath6kl_stop_endpoint(ndev, false, true);
1306
1307         clear_bit(WLAN_ENABLED, &ar->flag);
1308 }
1309
1310 /*
1311  * We need to differentiate between the surprise and planned removal of the
1312  * device because of the following consideration:
1313  *
1314  * - In case of surprise removal, the hcd already frees up the pending
1315  *   for the device and hence there is no need to unregister the function
1316  *   driver inorder to get these requests. For planned removal, the function
1317  *   driver has to explicitly unregister itself to have the hcd return all the
1318  *   pending requests before the data structures for the devices are freed up.
1319  *   Note that as per the current implementation, the function driver will
1320  *   end up releasing all the devices since there is no API to selectively
1321  *   release a particular device.
1322  *
1323  * - Certain commands issued to the target can be skipped for surprise
1324  *   removal since they will anyway not go through.
1325  */
1326 void ath6kl_destroy(struct net_device *dev, unsigned int unregister)
1327 {
1328         struct ath6kl *ar;
1329
1330         if (!dev || !ath6kl_priv(dev)) {
1331                 ath6kl_err("failed to get device structure\n");
1332                 return;
1333         }
1334
1335         ar = ath6kl_priv(dev);
1336
1337         destroy_workqueue(ar->ath6kl_wq);
1338
1339         if (ar->htc_target)
1340                 ath6kl_htc_cleanup(ar->htc_target);
1341
1342         aggr_module_destroy(ar->aggr_cntxt);
1343
1344         ath6kl_cookie_cleanup(ar);
1345
1346         ath6kl_cleanup_amsdu_rxbufs(ar);
1347
1348         ath6kl_bmi_cleanup(ar);
1349
1350         if (unregister && test_bit(NETDEV_REGISTERED, &ar->flag)) {
1351                 unregister_netdev(dev);
1352                 clear_bit(NETDEV_REGISTERED, &ar->flag);
1353         }
1354
1355         free_netdev(dev);
1356
1357         wlan_node_table_cleanup(&ar->scan_table);
1358
1359         kfree(ar->fw_board);
1360         kfree(ar->fw_otp);
1361         kfree(ar->fw);
1362         kfree(ar->fw_patch);
1363
1364         ath6kl_cfg80211_deinit(ar);
1365 }