ath6kl: Fix inactivity timeout for AR6004
[cascardo/linux.git] / drivers / net / wireless / ath / ath6kl / init.c
1
2 /*
3  * Copyright (c) 2011 Atheros Communications Inc.
4  * Copyright (c) 2011-2012 Qualcomm Atheros, Inc.
5  *
6  * Permission to use, copy, modify, and/or distribute this software for any
7  * purpose with or without fee is hereby granted, provided that the above
8  * copyright notice and this permission notice appear in all copies.
9  *
10  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
11  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
12  * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
13  * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
14  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
15  * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
16  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
17  */
18
19 #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
20
21 #include <linux/moduleparam.h>
22 #include <linux/errno.h>
23 #include <linux/export.h>
24 #include <linux/of.h>
25 #include <linux/mmc/sdio_func.h>
26 #include <linux/vmalloc.h>
27
28 #include "core.h"
29 #include "cfg80211.h"
30 #include "target.h"
31 #include "debug.h"
32 #include "hif-ops.h"
33 #include "htc-ops.h"
34
35 static const struct ath6kl_hw hw_list[] = {
36         {
37                 .id                             = AR6003_HW_2_0_VERSION,
38                 .name                           = "ar6003 hw 2.0",
39                 .dataset_patch_addr             = 0x57e884,
40                 .app_load_addr                  = 0x543180,
41                 .board_ext_data_addr            = 0x57e500,
42                 .reserved_ram_size              = 6912,
43                 .refclk_hz                      = 26000000,
44                 .uarttx_pin                     = 8,
45                 .flags                          = 0,
46
47                 /* hw2.0 needs override address hardcoded */
48                 .app_start_override_addr        = 0x944C00,
49
50                 .fw = {
51                         .dir            = AR6003_HW_2_0_FW_DIR,
52                         .otp            = AR6003_HW_2_0_OTP_FILE,
53                         .fw             = AR6003_HW_2_0_FIRMWARE_FILE,
54                         .tcmd           = AR6003_HW_2_0_TCMD_FIRMWARE_FILE,
55                         .patch          = AR6003_HW_2_0_PATCH_FILE,
56                 },
57
58                 .fw_board               = AR6003_HW_2_0_BOARD_DATA_FILE,
59                 .fw_default_board       = AR6003_HW_2_0_DEFAULT_BOARD_DATA_FILE,
60         },
61         {
62                 .id                             = AR6003_HW_2_1_1_VERSION,
63                 .name                           = "ar6003 hw 2.1.1",
64                 .dataset_patch_addr             = 0x57ff74,
65                 .app_load_addr                  = 0x1234,
66                 .board_ext_data_addr            = 0x542330,
67                 .reserved_ram_size              = 512,
68                 .refclk_hz                      = 26000000,
69                 .uarttx_pin                     = 8,
70                 .testscript_addr                = 0x57ef74,
71                 .flags                          = 0,
72
73                 .fw = {
74                         .dir            = AR6003_HW_2_1_1_FW_DIR,
75                         .otp            = AR6003_HW_2_1_1_OTP_FILE,
76                         .fw             = AR6003_HW_2_1_1_FIRMWARE_FILE,
77                         .tcmd           = AR6003_HW_2_1_1_TCMD_FIRMWARE_FILE,
78                         .patch          = AR6003_HW_2_1_1_PATCH_FILE,
79                         .utf            = AR6003_HW_2_1_1_UTF_FIRMWARE_FILE,
80                         .testscript     = AR6003_HW_2_1_1_TESTSCRIPT_FILE,
81                 },
82
83                 .fw_board               = AR6003_HW_2_1_1_BOARD_DATA_FILE,
84                 .fw_default_board = AR6003_HW_2_1_1_DEFAULT_BOARD_DATA_FILE,
85         },
86         {
87                 .id                             = AR6004_HW_1_0_VERSION,
88                 .name                           = "ar6004 hw 1.0",
89                 .dataset_patch_addr             = 0x57e884,
90                 .app_load_addr                  = 0x1234,
91                 .board_ext_data_addr            = 0x437000,
92                 .reserved_ram_size              = 19456,
93                 .board_addr                     = 0x433900,
94                 .refclk_hz                      = 26000000,
95                 .uarttx_pin                     = 11,
96                 .flags                          = ATH6KL_HW_64BIT_RATES |
97                                                   ATH6KL_HW_AP_INACTIVITY_MINS,
98
99                 .fw = {
100                         .dir            = AR6004_HW_1_0_FW_DIR,
101                         .fw             = AR6004_HW_1_0_FIRMWARE_FILE,
102                 },
103
104                 .fw_board               = AR6004_HW_1_0_BOARD_DATA_FILE,
105                 .fw_default_board       = AR6004_HW_1_0_DEFAULT_BOARD_DATA_FILE,
106         },
107         {
108                 .id                             = AR6004_HW_1_1_VERSION,
109                 .name                           = "ar6004 hw 1.1",
110                 .dataset_patch_addr             = 0x57e884,
111                 .app_load_addr                  = 0x1234,
112                 .board_ext_data_addr            = 0x437000,
113                 .reserved_ram_size              = 11264,
114                 .board_addr                     = 0x43d400,
115                 .refclk_hz                      = 40000000,
116                 .uarttx_pin                     = 11,
117                 .flags                          = ATH6KL_HW_64BIT_RATES |
118                                                   ATH6KL_HW_AP_INACTIVITY_MINS,
119                 .fw = {
120                         .dir            = AR6004_HW_1_1_FW_DIR,
121                         .fw             = AR6004_HW_1_1_FIRMWARE_FILE,
122                 },
123
124                 .fw_board               = AR6004_HW_1_1_BOARD_DATA_FILE,
125                 .fw_default_board       = AR6004_HW_1_1_DEFAULT_BOARD_DATA_FILE,
126         },
127         {
128                 .id                             = AR6004_HW_1_2_VERSION,
129                 .name                           = "ar6004 hw 1.2",
130                 .dataset_patch_addr             = 0x436ecc,
131                 .app_load_addr                  = 0x1234,
132                 .board_ext_data_addr            = 0x437000,
133                 .reserved_ram_size              = 9216,
134                 .board_addr                     = 0x435c00,
135                 .refclk_hz                      = 40000000,
136                 .uarttx_pin                     = 11,
137                 .flags                          = ATH6KL_HW_64BIT_RATES |
138                                                   ATH6KL_HW_AP_INACTIVITY_MINS,
139
140                 .fw = {
141                         .dir            = AR6004_HW_1_2_FW_DIR,
142                         .fw             = AR6004_HW_1_2_FIRMWARE_FILE,
143                 },
144                 .fw_board               = AR6004_HW_1_2_BOARD_DATA_FILE,
145                 .fw_default_board       = AR6004_HW_1_2_DEFAULT_BOARD_DATA_FILE,
146         },
147         {
148                 .id                             = AR6004_HW_1_3_VERSION,
149                 .name                           = "ar6004 hw 1.3",
150                 .dataset_patch_addr             = 0x437860,
151                 .app_load_addr                  = 0x1234,
152                 .board_ext_data_addr            = 0x437000,
153                 .reserved_ram_size              = 7168,
154                 .board_addr                     = 0x436400,
155                 .refclk_hz                      = 40000000,
156                 .uarttx_pin                     = 11,
157                 .flags                          = ATH6KL_HW_64BIT_RATES |
158                                                   ATH6KL_HW_AP_INACTIVITY_MINS,
159
160                 .fw = {
161                         .dir            = AR6004_HW_1_3_FW_DIR,
162                         .fw             = AR6004_HW_1_3_FIRMWARE_FILE,
163                 },
164
165                 .fw_board               = AR6004_HW_1_3_BOARD_DATA_FILE,
166                 .fw_default_board       = AR6004_HW_1_3_DEFAULT_BOARD_DATA_FILE,
167         },
168 };
169
170 /*
171  * Include definitions here that can be used to tune the WLAN module
172  * behavior. Different customers can tune the behavior as per their needs,
173  * here.
174  */
175
176 /*
177  * This configuration item enable/disable keepalive support.
178  * Keepalive support: In the absence of any data traffic to AP, null
179  * frames will be sent to the AP at periodic interval, to keep the association
180  * active. This configuration item defines the periodic interval.
181  * Use value of zero to disable keepalive support
182  * Default: 60 seconds
183  */
184 #define WLAN_CONFIG_KEEP_ALIVE_INTERVAL 60
185
186 /*
187  * This configuration item sets the value of disconnect timeout
188  * Firmware delays sending the disconnec event to the host for this
189  * timeout after is gets disconnected from the current AP.
190  * If the firmware successly roams within the disconnect timeout
191  * it sends a new connect event
192  */
193 #define WLAN_CONFIG_DISCONNECT_TIMEOUT 10
194
195
196 #define ATH6KL_DATA_OFFSET    64
197 struct sk_buff *ath6kl_buf_alloc(int size)
198 {
199         struct sk_buff *skb;
200         u16 reserved;
201
202         /* Add chacheline space at front and back of buffer */
203         reserved = (2 * L1_CACHE_BYTES) + ATH6KL_DATA_OFFSET +
204                    sizeof(struct htc_packet) + ATH6KL_HTC_ALIGN_BYTES;
205         skb = dev_alloc_skb(size + reserved);
206
207         if (skb)
208                 skb_reserve(skb, reserved - L1_CACHE_BYTES);
209         return skb;
210 }
211
212 void ath6kl_init_profile_info(struct ath6kl_vif *vif)
213 {
214         vif->ssid_len = 0;
215         memset(vif->ssid, 0, sizeof(vif->ssid));
216
217         vif->dot11_auth_mode = OPEN_AUTH;
218         vif->auth_mode = NONE_AUTH;
219         vif->prwise_crypto = NONE_CRYPT;
220         vif->prwise_crypto_len = 0;
221         vif->grp_crypto = NONE_CRYPT;
222         vif->grp_crypto_len = 0;
223         memset(vif->wep_key_list, 0, sizeof(vif->wep_key_list));
224         memset(vif->req_bssid, 0, sizeof(vif->req_bssid));
225         memset(vif->bssid, 0, sizeof(vif->bssid));
226         vif->bss_ch = 0;
227 }
228
229 static int ath6kl_set_host_app_area(struct ath6kl *ar)
230 {
231         u32 address, data;
232         struct host_app_area host_app_area;
233
234         /* Fetch the address of the host_app_area_s
235          * instance in the host interest area */
236         address = ath6kl_get_hi_item_addr(ar, HI_ITEM(hi_app_host_interest));
237         address = TARG_VTOP(ar->target_type, address);
238
239         if (ath6kl_diag_read32(ar, address, &data))
240                 return -EIO;
241
242         address = TARG_VTOP(ar->target_type, data);
243         host_app_area.wmi_protocol_ver = cpu_to_le32(WMI_PROTOCOL_VERSION);
244         if (ath6kl_diag_write(ar, address, (u8 *) &host_app_area,
245                               sizeof(struct host_app_area)))
246                 return -EIO;
247
248         return 0;
249 }
250
251 static inline void set_ac2_ep_map(struct ath6kl *ar,
252                                   u8 ac,
253                                   enum htc_endpoint_id ep)
254 {
255         ar->ac2ep_map[ac] = ep;
256         ar->ep2ac_map[ep] = ac;
257 }
258
259 /* connect to a service */
260 static int ath6kl_connectservice(struct ath6kl *ar,
261                                  struct htc_service_connect_req  *con_req,
262                                  char *desc)
263 {
264         int status;
265         struct htc_service_connect_resp response;
266
267         memset(&response, 0, sizeof(response));
268
269         status = ath6kl_htc_conn_service(ar->htc_target, con_req, &response);
270         if (status) {
271                 ath6kl_err("failed to connect to %s service status:%d\n",
272                            desc, status);
273                 return status;
274         }
275
276         switch (con_req->svc_id) {
277         case WMI_CONTROL_SVC:
278                 if (test_bit(WMI_ENABLED, &ar->flag))
279                         ath6kl_wmi_set_control_ep(ar->wmi, response.endpoint);
280                 ar->ctrl_ep = response.endpoint;
281                 break;
282         case WMI_DATA_BE_SVC:
283                 set_ac2_ep_map(ar, WMM_AC_BE, response.endpoint);
284                 break;
285         case WMI_DATA_BK_SVC:
286                 set_ac2_ep_map(ar, WMM_AC_BK, response.endpoint);
287                 break;
288         case WMI_DATA_VI_SVC:
289                 set_ac2_ep_map(ar, WMM_AC_VI, response.endpoint);
290                 break;
291         case WMI_DATA_VO_SVC:
292                 set_ac2_ep_map(ar, WMM_AC_VO, response.endpoint);
293                 break;
294         default:
295                 ath6kl_err("service id is not mapped %d\n", con_req->svc_id);
296                 return -EINVAL;
297         }
298
299         return 0;
300 }
301
302 static int ath6kl_init_service_ep(struct ath6kl *ar)
303 {
304         struct htc_service_connect_req connect;
305
306         memset(&connect, 0, sizeof(connect));
307
308         /* these fields are the same for all service endpoints */
309         connect.ep_cb.tx_comp_multi = ath6kl_tx_complete;
310         connect.ep_cb.rx = ath6kl_rx;
311         connect.ep_cb.rx_refill = ath6kl_rx_refill;
312         connect.ep_cb.tx_full = ath6kl_tx_queue_full;
313
314         /*
315          * Set the max queue depth so that our ath6kl_tx_queue_full handler
316          * gets called.
317         */
318         connect.max_txq_depth = MAX_DEFAULT_SEND_QUEUE_DEPTH;
319         connect.ep_cb.rx_refill_thresh = ATH6KL_MAX_RX_BUFFERS / 4;
320         if (!connect.ep_cb.rx_refill_thresh)
321                 connect.ep_cb.rx_refill_thresh++;
322
323         /* connect to control service */
324         connect.svc_id = WMI_CONTROL_SVC;
325         if (ath6kl_connectservice(ar, &connect, "WMI CONTROL"))
326                 return -EIO;
327
328         connect.flags |= HTC_FLGS_TX_BNDL_PAD_EN;
329
330         /*
331          * Limit the HTC message size on the send path, although e can
332          * receive A-MSDU frames of 4K, we will only send ethernet-sized
333          * (802.3) frames on the send path.
334          */
335         connect.max_rxmsg_sz = WMI_MAX_TX_DATA_FRAME_LENGTH;
336
337         /*
338          * To reduce the amount of committed memory for larger A_MSDU
339          * frames, use the recv-alloc threshold mechanism for larger
340          * packets.
341          */
342         connect.ep_cb.rx_alloc_thresh = ATH6KL_BUFFER_SIZE;
343         connect.ep_cb.rx_allocthresh = ath6kl_alloc_amsdu_rxbuf;
344
345         /*
346          * For the remaining data services set the connection flag to
347          * reduce dribbling, if configured to do so.
348          */
349         connect.conn_flags |= HTC_CONN_FLGS_REDUCE_CRED_DRIB;
350         connect.conn_flags &= ~HTC_CONN_FLGS_THRESH_MASK;
351         connect.conn_flags |= HTC_CONN_FLGS_THRESH_LVL_HALF;
352
353         connect.svc_id = WMI_DATA_BE_SVC;
354
355         if (ath6kl_connectservice(ar, &connect, "WMI DATA BE"))
356                 return -EIO;
357
358         /* connect to back-ground map this to WMI LOW_PRI */
359         connect.svc_id = WMI_DATA_BK_SVC;
360         if (ath6kl_connectservice(ar, &connect, "WMI DATA BK"))
361                 return -EIO;
362
363         /* connect to Video service, map this to to HI PRI */
364         connect.svc_id = WMI_DATA_VI_SVC;
365         if (ath6kl_connectservice(ar, &connect, "WMI DATA VI"))
366                 return -EIO;
367
368         /*
369          * Connect to VO service, this is currently not mapped to a WMI
370          * priority stream due to historical reasons. WMI originally
371          * defined 3 priorities over 3 mailboxes We can change this when
372          * WMI is reworked so that priorities are not dependent on
373          * mailboxes.
374          */
375         connect.svc_id = WMI_DATA_VO_SVC;
376         if (ath6kl_connectservice(ar, &connect, "WMI DATA VO"))
377                 return -EIO;
378
379         return 0;
380 }
381
382 void ath6kl_init_control_info(struct ath6kl_vif *vif)
383 {
384         ath6kl_init_profile_info(vif);
385         vif->def_txkey_index = 0;
386         memset(vif->wep_key_list, 0, sizeof(vif->wep_key_list));
387         vif->ch_hint = 0;
388 }
389
390 /*
391  * Set HTC/Mbox operational parameters, this can only be called when the
392  * target is in the BMI phase.
393  */
394 static int ath6kl_set_htc_params(struct ath6kl *ar, u32 mbox_isr_yield_val,
395                                  u8 htc_ctrl_buf)
396 {
397         int status;
398         u32 blk_size;
399
400         blk_size = ar->mbox_info.block_size;
401
402         if (htc_ctrl_buf)
403                 blk_size |=  ((u32)htc_ctrl_buf) << 16;
404
405         /* set the host interest area for the block size */
406         status = ath6kl_bmi_write_hi32(ar, hi_mbox_io_block_sz, blk_size);
407         if (status) {
408                 ath6kl_err("bmi_write_memory for IO block size failed\n");
409                 goto out;
410         }
411
412         ath6kl_dbg(ATH6KL_DBG_TRC, "block size set: %d (target addr:0x%X)\n",
413                    blk_size,
414                    ath6kl_get_hi_item_addr(ar, HI_ITEM(hi_mbox_io_block_sz)));
415
416         if (mbox_isr_yield_val) {
417                 /* set the host interest area for the mbox ISR yield limit */
418                 status = ath6kl_bmi_write_hi32(ar, hi_mbox_isr_yield_limit,
419                                                mbox_isr_yield_val);
420                 if (status) {
421                         ath6kl_err("bmi_write_memory for yield limit failed\n");
422                         goto out;
423                 }
424         }
425
426 out:
427         return status;
428 }
429
430 static int ath6kl_target_config_wlan_params(struct ath6kl *ar, int idx)
431 {
432         int ret;
433
434         /*
435          * Configure the device for rx dot11 header rules. "0,0" are the
436          * default values. Required if checksum offload is needed. Set
437          * RxMetaVersion to 2.
438          */
439         ret = ath6kl_wmi_set_rx_frame_format_cmd(ar->wmi, idx,
440                                                  ar->rx_meta_ver, 0, 0);
441         if (ret) {
442                 ath6kl_err("unable to set the rx frame format: %d\n", ret);
443                 return ret;
444         }
445
446         if (ar->conf_flags & ATH6KL_CONF_IGNORE_PS_FAIL_EVT_IN_SCAN) {
447                 ret = ath6kl_wmi_pmparams_cmd(ar->wmi, idx, 0, 1, 0, 0, 1,
448                                               IGNORE_PS_FAIL_DURING_SCAN);
449                 if (ret) {
450                         ath6kl_err("unable to set power save fail event policy: %d\n",
451                                    ret);
452                         return ret;
453                 }
454         }
455
456         if (!(ar->conf_flags & ATH6KL_CONF_IGNORE_ERP_BARKER)) {
457                 ret = ath6kl_wmi_set_lpreamble_cmd(ar->wmi, idx, 0,
458                                                    WMI_FOLLOW_BARKER_IN_ERP);
459                 if (ret) {
460                         ath6kl_err("unable to set barker preamble policy: %d\n",
461                                    ret);
462                         return ret;
463                 }
464         }
465
466         ret = ath6kl_wmi_set_keepalive_cmd(ar->wmi, idx,
467                                            WLAN_CONFIG_KEEP_ALIVE_INTERVAL);
468         if (ret) {
469                 ath6kl_err("unable to set keep alive interval: %d\n", ret);
470                 return ret;
471         }
472
473         ret = ath6kl_wmi_disctimeout_cmd(ar->wmi, idx,
474                                          WLAN_CONFIG_DISCONNECT_TIMEOUT);
475         if (ret) {
476                 ath6kl_err("unable to set disconnect timeout: %d\n", ret);
477                 return ret;
478         }
479
480         if (!(ar->conf_flags & ATH6KL_CONF_ENABLE_TX_BURST)) {
481                 ret = ath6kl_wmi_set_wmm_txop(ar->wmi, idx, WMI_TXOP_DISABLED);
482                 if (ret) {
483                         ath6kl_err("unable to set txop bursting: %d\n", ret);
484                         return ret;
485                 }
486         }
487
488         if (ar->p2p && (ar->vif_max == 1 || idx)) {
489                 ret = ath6kl_wmi_info_req_cmd(ar->wmi, idx,
490                                               P2P_FLAG_CAPABILITIES_REQ |
491                                               P2P_FLAG_MACADDR_REQ |
492                                               P2P_FLAG_HMODEL_REQ);
493                 if (ret) {
494                         ath6kl_dbg(ATH6KL_DBG_TRC,
495                                    "failed to request P2P capabilities (%d) - assuming P2P not supported\n",
496                                    ret);
497                         ar->p2p = false;
498                 }
499         }
500
501         if (ar->p2p && (ar->vif_max == 1 || idx)) {
502                 /* Enable Probe Request reporting for P2P */
503                 ret = ath6kl_wmi_probe_report_req_cmd(ar->wmi, idx, true);
504                 if (ret) {
505                         ath6kl_dbg(ATH6KL_DBG_TRC,
506                                    "failed to enable Probe Request reporting (%d)\n",
507                                    ret);
508                 }
509         }
510
511         return ret;
512 }
513
514 int ath6kl_configure_target(struct ath6kl *ar)
515 {
516         u32 param, ram_reserved_size;
517         u8 fw_iftype, fw_mode = 0, fw_submode = 0;
518         int i, status;
519
520         param = !!(ar->conf_flags & ATH6KL_CONF_UART_DEBUG);
521         if (ath6kl_bmi_write_hi32(ar, hi_serial_enable, param)) {
522                 ath6kl_err("bmi_write_memory for uart debug failed\n");
523                 return -EIO;
524         }
525
526         /*
527          * Note: Even though the firmware interface type is
528          * chosen as BSS_STA for all three interfaces, can
529          * be configured to IBSS/AP as long as the fw submode
530          * remains normal mode (0 - AP, STA and IBSS). But
531          * due to an target assert in firmware only one interface is
532          * configured for now.
533          */
534         fw_iftype = HI_OPTION_FW_MODE_BSS_STA;
535
536         for (i = 0; i < ar->vif_max; i++)
537                 fw_mode |= fw_iftype << (i * HI_OPTION_FW_MODE_BITS);
538
539         /*
540          * Submodes when fw does not support dynamic interface
541          * switching:
542          *              vif[0] - AP/STA/IBSS
543          *              vif[1] - "P2P dev"/"P2P GO"/"P2P Client"
544          *              vif[2] - "P2P dev"/"P2P GO"/"P2P Client"
545          * Otherwise, All the interface are initialized to p2p dev.
546          */
547
548         if (test_bit(ATH6KL_FW_CAPABILITY_STA_P2PDEV_DUPLEX,
549                      ar->fw_capabilities)) {
550                 for (i = 0; i < ar->vif_max; i++)
551                         fw_submode |= HI_OPTION_FW_SUBMODE_P2PDEV <<
552                                 (i * HI_OPTION_FW_SUBMODE_BITS);
553         } else {
554                 for (i = 0; i < ar->max_norm_iface; i++)
555                         fw_submode |= HI_OPTION_FW_SUBMODE_NONE <<
556                                 (i * HI_OPTION_FW_SUBMODE_BITS);
557
558                 for (i = ar->max_norm_iface; i < ar->vif_max; i++)
559                         fw_submode |= HI_OPTION_FW_SUBMODE_P2PDEV <<
560                                 (i * HI_OPTION_FW_SUBMODE_BITS);
561
562                 if (ar->p2p && ar->vif_max == 1)
563                         fw_submode = HI_OPTION_FW_SUBMODE_P2PDEV;
564         }
565
566         if (ath6kl_bmi_write_hi32(ar, hi_app_host_interest,
567                                   HTC_PROTOCOL_VERSION) != 0) {
568                 ath6kl_err("bmi_write_memory for htc version failed\n");
569                 return -EIO;
570         }
571
572         /* set the firmware mode to STA/IBSS/AP */
573         param = 0;
574
575         if (ath6kl_bmi_read_hi32(ar, hi_option_flag, &param) != 0) {
576                 ath6kl_err("bmi_read_memory for setting fwmode failed\n");
577                 return -EIO;
578         }
579
580         param |= (ar->vif_max << HI_OPTION_NUM_DEV_SHIFT);
581         param |= fw_mode << HI_OPTION_FW_MODE_SHIFT;
582         param |= fw_submode << HI_OPTION_FW_SUBMODE_SHIFT;
583
584         param |= (0 << HI_OPTION_MAC_ADDR_METHOD_SHIFT);
585         param |= (0 << HI_OPTION_FW_BRIDGE_SHIFT);
586
587         if (ath6kl_bmi_write_hi32(ar, hi_option_flag, param) != 0) {
588                 ath6kl_err("bmi_write_memory for setting fwmode failed\n");
589                 return -EIO;
590         }
591
592         ath6kl_dbg(ATH6KL_DBG_TRC, "firmware mode set\n");
593
594         /*
595          * Hardcode the address use for the extended board data
596          * Ideally this should be pre-allocate by the OS at boot time
597          * But since it is a new feature and board data is loaded
598          * at init time, we have to workaround this from host.
599          * It is difficult to patch the firmware boot code,
600          * but possible in theory.
601          */
602
603         if (ar->target_type == TARGET_TYPE_AR6003) {
604                 param = ar->hw.board_ext_data_addr;
605                 ram_reserved_size = ar->hw.reserved_ram_size;
606
607                 if (ath6kl_bmi_write_hi32(ar, hi_board_ext_data, param) != 0) {
608                         ath6kl_err("bmi_write_memory for hi_board_ext_data failed\n");
609                         return -EIO;
610                 }
611
612                 if (ath6kl_bmi_write_hi32(ar, hi_end_ram_reserve_sz,
613                                           ram_reserved_size) != 0) {
614                         ath6kl_err("bmi_write_memory for hi_end_ram_reserve_sz failed\n");
615                         return -EIO;
616                 }
617         }
618
619         /* set the block size for the target */
620         if (ath6kl_set_htc_params(ar, MBOX_YIELD_LIMIT, 0))
621                 /* use default number of control buffers */
622                 return -EIO;
623
624         /* Configure GPIO AR600x UART */
625         status = ath6kl_bmi_write_hi32(ar, hi_dbg_uart_txpin,
626                                        ar->hw.uarttx_pin);
627         if (status)
628                 return status;
629
630         /* Configure target refclk_hz */
631         status = ath6kl_bmi_write_hi32(ar, hi_refclk_hz, ar->hw.refclk_hz);
632         if (status)
633                 return status;
634
635         return 0;
636 }
637
638 /* firmware upload */
639 static int ath6kl_get_fw(struct ath6kl *ar, const char *filename,
640                          u8 **fw, size_t *fw_len)
641 {
642         const struct firmware *fw_entry;
643         int ret;
644
645         ret = request_firmware(&fw_entry, filename, ar->dev);
646         if (ret)
647                 return ret;
648
649         *fw_len = fw_entry->size;
650         *fw = kmemdup(fw_entry->data, fw_entry->size, GFP_KERNEL);
651
652         if (*fw == NULL)
653                 ret = -ENOMEM;
654
655         release_firmware(fw_entry);
656
657         return ret;
658 }
659
660 #ifdef CONFIG_OF
661 /*
662  * Check the device tree for a board-id and use it to construct
663  * the pathname to the firmware file.  Used (for now) to find a
664  * fallback to the "bdata.bin" file--typically a symlink to the
665  * appropriate board-specific file.
666  */
667 static bool check_device_tree(struct ath6kl *ar)
668 {
669         static const char *board_id_prop = "atheros,board-id";
670         struct device_node *node;
671         char board_filename[64];
672         const char *board_id;
673         int ret;
674
675         for_each_compatible_node(node, NULL, "atheros,ath6kl") {
676                 board_id = of_get_property(node, board_id_prop, NULL);
677                 if (board_id == NULL) {
678                         ath6kl_warn("No \"%s\" property on %s node.\n",
679                                     board_id_prop, node->name);
680                         continue;
681                 }
682                 snprintf(board_filename, sizeof(board_filename),
683                          "%s/bdata.%s.bin", ar->hw.fw.dir, board_id);
684
685                 ret = ath6kl_get_fw(ar, board_filename, &ar->fw_board,
686                                     &ar->fw_board_len);
687                 if (ret) {
688                         ath6kl_err("Failed to get DT board file %s: %d\n",
689                                    board_filename, ret);
690                         continue;
691                 }
692                 return true;
693         }
694         return false;
695 }
696 #else
697 static bool check_device_tree(struct ath6kl *ar)
698 {
699         return false;
700 }
701 #endif /* CONFIG_OF */
702
703 static int ath6kl_fetch_board_file(struct ath6kl *ar)
704 {
705         const char *filename;
706         int ret;
707
708         if (ar->fw_board != NULL)
709                 return 0;
710
711         if (WARN_ON(ar->hw.fw_board == NULL))
712                 return -EINVAL;
713
714         filename = ar->hw.fw_board;
715
716         ret = ath6kl_get_fw(ar, filename, &ar->fw_board,
717                             &ar->fw_board_len);
718         if (ret == 0) {
719                 /* managed to get proper board file */
720                 return 0;
721         }
722
723         if (check_device_tree(ar)) {
724                 /* got board file from device tree */
725                 return 0;
726         }
727
728         /* there was no proper board file, try to use default instead */
729         ath6kl_warn("Failed to get board file %s (%d), trying to find default board file.\n",
730                     filename, ret);
731
732         filename = ar->hw.fw_default_board;
733
734         ret = ath6kl_get_fw(ar, filename, &ar->fw_board,
735                             &ar->fw_board_len);
736         if (ret) {
737                 ath6kl_err("Failed to get default board file %s: %d\n",
738                            filename, ret);
739                 return ret;
740         }
741
742         ath6kl_warn("WARNING! No proper board file was not found, instead using a default board file.\n");
743         ath6kl_warn("Most likely your hardware won't work as specified. Install correct board file!\n");
744
745         return 0;
746 }
747
748 static int ath6kl_fetch_otp_file(struct ath6kl *ar)
749 {
750         char filename[100];
751         int ret;
752
753         if (ar->fw_otp != NULL)
754                 return 0;
755
756         if (ar->hw.fw.otp == NULL) {
757                 ath6kl_dbg(ATH6KL_DBG_BOOT,
758                            "no OTP file configured for this hw\n");
759                 return 0;
760         }
761
762         snprintf(filename, sizeof(filename), "%s/%s",
763                  ar->hw.fw.dir, ar->hw.fw.otp);
764
765         ret = ath6kl_get_fw(ar, filename, &ar->fw_otp,
766                             &ar->fw_otp_len);
767         if (ret) {
768                 ath6kl_err("Failed to get OTP file %s: %d\n",
769                            filename, ret);
770                 return ret;
771         }
772
773         return 0;
774 }
775
776 static int ath6kl_fetch_testmode_file(struct ath6kl *ar)
777 {
778         char filename[100];
779         int ret;
780
781         if (ar->testmode == 0)
782                 return 0;
783
784         ath6kl_dbg(ATH6KL_DBG_BOOT, "testmode %d\n", ar->testmode);
785
786         if (ar->testmode == 2) {
787                 if (ar->hw.fw.utf == NULL) {
788                         ath6kl_warn("testmode 2 not supported\n");
789                         return -EOPNOTSUPP;
790                 }
791
792                 snprintf(filename, sizeof(filename), "%s/%s",
793                          ar->hw.fw.dir, ar->hw.fw.utf);
794         } else {
795                 if (ar->hw.fw.tcmd == NULL) {
796                         ath6kl_warn("testmode 1 not supported\n");
797                         return -EOPNOTSUPP;
798                 }
799
800                 snprintf(filename, sizeof(filename), "%s/%s",
801                          ar->hw.fw.dir, ar->hw.fw.tcmd);
802         }
803
804         set_bit(TESTMODE, &ar->flag);
805
806         ret = ath6kl_get_fw(ar, filename, &ar->fw, &ar->fw_len);
807         if (ret) {
808                 ath6kl_err("Failed to get testmode %d firmware file %s: %d\n",
809                            ar->testmode, filename, ret);
810                 return ret;
811         }
812
813         return 0;
814 }
815
816 static int ath6kl_fetch_fw_file(struct ath6kl *ar)
817 {
818         char filename[100];
819         int ret;
820
821         if (ar->fw != NULL)
822                 return 0;
823
824         /* FIXME: remove WARN_ON() as we won't support FW API 1 for long */
825         if (WARN_ON(ar->hw.fw.fw == NULL))
826                 return -EINVAL;
827
828         snprintf(filename, sizeof(filename), "%s/%s",
829                  ar->hw.fw.dir, ar->hw.fw.fw);
830
831         ret = ath6kl_get_fw(ar, filename, &ar->fw, &ar->fw_len);
832         if (ret) {
833                 ath6kl_err("Failed to get firmware file %s: %d\n",
834                            filename, ret);
835                 return ret;
836         }
837
838         return 0;
839 }
840
841 static int ath6kl_fetch_patch_file(struct ath6kl *ar)
842 {
843         char filename[100];
844         int ret;
845
846         if (ar->fw_patch != NULL)
847                 return 0;
848
849         if (ar->hw.fw.patch == NULL)
850                 return 0;
851
852         snprintf(filename, sizeof(filename), "%s/%s",
853                  ar->hw.fw.dir, ar->hw.fw.patch);
854
855         ret = ath6kl_get_fw(ar, filename, &ar->fw_patch,
856                             &ar->fw_patch_len);
857         if (ret) {
858                 ath6kl_err("Failed to get patch file %s: %d\n",
859                            filename, ret);
860                 return ret;
861         }
862
863         return 0;
864 }
865
866 static int ath6kl_fetch_testscript_file(struct ath6kl *ar)
867 {
868         char filename[100];
869         int ret;
870
871         if (ar->testmode != 2)
872                 return 0;
873
874         if (ar->fw_testscript != NULL)
875                 return 0;
876
877         if (ar->hw.fw.testscript == NULL)
878                 return 0;
879
880         snprintf(filename, sizeof(filename), "%s/%s",
881                  ar->hw.fw.dir, ar->hw.fw.testscript);
882
883         ret = ath6kl_get_fw(ar, filename, &ar->fw_testscript,
884                                 &ar->fw_testscript_len);
885         if (ret) {
886                 ath6kl_err("Failed to get testscript file %s: %d\n",
887                            filename, ret);
888                 return ret;
889         }
890
891         return 0;
892 }
893
894 static int ath6kl_fetch_fw_api1(struct ath6kl *ar)
895 {
896         int ret;
897
898         ret = ath6kl_fetch_otp_file(ar);
899         if (ret)
900                 return ret;
901
902         ret = ath6kl_fetch_fw_file(ar);
903         if (ret)
904                 return ret;
905
906         ret = ath6kl_fetch_patch_file(ar);
907         if (ret)
908                 return ret;
909
910         ret = ath6kl_fetch_testscript_file(ar);
911         if (ret)
912                 return ret;
913
914         return 0;
915 }
916
917 static int ath6kl_fetch_fw_apin(struct ath6kl *ar, const char *name)
918 {
919         size_t magic_len, len, ie_len;
920         const struct firmware *fw;
921         struct ath6kl_fw_ie *hdr;
922         char filename[100];
923         const u8 *data;
924         int ret, ie_id, i, index, bit;
925         __le32 *val;
926
927         snprintf(filename, sizeof(filename), "%s/%s", ar->hw.fw.dir, name);
928
929         ret = request_firmware(&fw, filename, ar->dev);
930         if (ret)
931                 return ret;
932
933         data = fw->data;
934         len = fw->size;
935
936         /* magic also includes the null byte, check that as well */
937         magic_len = strlen(ATH6KL_FIRMWARE_MAGIC) + 1;
938
939         if (len < magic_len) {
940                 ret = -EINVAL;
941                 goto out;
942         }
943
944         if (memcmp(data, ATH6KL_FIRMWARE_MAGIC, magic_len) != 0) {
945                 ret = -EINVAL;
946                 goto out;
947         }
948
949         len -= magic_len;
950         data += magic_len;
951
952         /* loop elements */
953         while (len > sizeof(struct ath6kl_fw_ie)) {
954                 /* hdr is unaligned! */
955                 hdr = (struct ath6kl_fw_ie *) data;
956
957                 ie_id = le32_to_cpup(&hdr->id);
958                 ie_len = le32_to_cpup(&hdr->len);
959
960                 len -= sizeof(*hdr);
961                 data += sizeof(*hdr);
962
963                 if (len < ie_len) {
964                         ret = -EINVAL;
965                         goto out;
966                 }
967
968                 switch (ie_id) {
969                 case ATH6KL_FW_IE_FW_VERSION:
970                         strlcpy(ar->wiphy->fw_version, data,
971                                 sizeof(ar->wiphy->fw_version));
972
973                         ath6kl_dbg(ATH6KL_DBG_BOOT,
974                                    "found fw version %s\n",
975                                     ar->wiphy->fw_version);
976                         break;
977                 case ATH6KL_FW_IE_OTP_IMAGE:
978                         ath6kl_dbg(ATH6KL_DBG_BOOT, "found otp image ie (%zd B)\n",
979                                    ie_len);
980
981                         ar->fw_otp = kmemdup(data, ie_len, GFP_KERNEL);
982
983                         if (ar->fw_otp == NULL) {
984                                 ret = -ENOMEM;
985                                 goto out;
986                         }
987
988                         ar->fw_otp_len = ie_len;
989                         break;
990                 case ATH6KL_FW_IE_FW_IMAGE:
991                         ath6kl_dbg(ATH6KL_DBG_BOOT, "found fw image ie (%zd B)\n",
992                                    ie_len);
993
994                         /* in testmode we already might have a fw file */
995                         if (ar->fw != NULL)
996                                 break;
997
998                         ar->fw = vmalloc(ie_len);
999
1000                         if (ar->fw == NULL) {
1001                                 ret = -ENOMEM;
1002                                 goto out;
1003                         }
1004
1005                         memcpy(ar->fw, data, ie_len);
1006                         ar->fw_len = ie_len;
1007                         break;
1008                 case ATH6KL_FW_IE_PATCH_IMAGE:
1009                         ath6kl_dbg(ATH6KL_DBG_BOOT, "found patch image ie (%zd B)\n",
1010                                    ie_len);
1011
1012                         ar->fw_patch = kmemdup(data, ie_len, GFP_KERNEL);
1013
1014                         if (ar->fw_patch == NULL) {
1015                                 ret = -ENOMEM;
1016                                 goto out;
1017                         }
1018
1019                         ar->fw_patch_len = ie_len;
1020                         break;
1021                 case ATH6KL_FW_IE_RESERVED_RAM_SIZE:
1022                         val = (__le32 *) data;
1023                         ar->hw.reserved_ram_size = le32_to_cpup(val);
1024
1025                         ath6kl_dbg(ATH6KL_DBG_BOOT,
1026                                    "found reserved ram size ie 0x%d\n",
1027                                    ar->hw.reserved_ram_size);
1028                         break;
1029                 case ATH6KL_FW_IE_CAPABILITIES:
1030                         ath6kl_dbg(ATH6KL_DBG_BOOT,
1031                                    "found firmware capabilities ie (%zd B)\n",
1032                                    ie_len);
1033
1034                         for (i = 0; i < ATH6KL_FW_CAPABILITY_MAX; i++) {
1035                                 index = i / 8;
1036                                 bit = i % 8;
1037
1038                                 if (index == ie_len)
1039                                         break;
1040
1041                                 if (data[index] & (1 << bit))
1042                                         __set_bit(i, ar->fw_capabilities);
1043                         }
1044
1045                         ath6kl_dbg_dump(ATH6KL_DBG_BOOT, "capabilities", "",
1046                                         ar->fw_capabilities,
1047                                         sizeof(ar->fw_capabilities));
1048                         break;
1049                 case ATH6KL_FW_IE_PATCH_ADDR:
1050                         if (ie_len != sizeof(*val))
1051                                 break;
1052
1053                         val = (__le32 *) data;
1054                         ar->hw.dataset_patch_addr = le32_to_cpup(val);
1055
1056                         ath6kl_dbg(ATH6KL_DBG_BOOT,
1057                                    "found patch address ie 0x%x\n",
1058                                    ar->hw.dataset_patch_addr);
1059                         break;
1060                 case ATH6KL_FW_IE_BOARD_ADDR:
1061                         if (ie_len != sizeof(*val))
1062                                 break;
1063
1064                         val = (__le32 *) data;
1065                         ar->hw.board_addr = le32_to_cpup(val);
1066
1067                         ath6kl_dbg(ATH6KL_DBG_BOOT,
1068                                    "found board address ie 0x%x\n",
1069                                    ar->hw.board_addr);
1070                         break;
1071                 case ATH6KL_FW_IE_VIF_MAX:
1072                         if (ie_len != sizeof(*val))
1073                                 break;
1074
1075                         val = (__le32 *) data;
1076                         ar->vif_max = min_t(unsigned int, le32_to_cpup(val),
1077                                             ATH6KL_VIF_MAX);
1078
1079                         if (ar->vif_max > 1 && !ar->p2p)
1080                                 ar->max_norm_iface = 2;
1081
1082                         ath6kl_dbg(ATH6KL_DBG_BOOT,
1083                                    "found vif max ie %d\n", ar->vif_max);
1084                         break;
1085                 default:
1086                         ath6kl_dbg(ATH6KL_DBG_BOOT, "Unknown fw ie: %u\n",
1087                                    le32_to_cpup(&hdr->id));
1088                         break;
1089                 }
1090
1091                 len -= ie_len;
1092                 data += ie_len;
1093         };
1094
1095         ret = 0;
1096 out:
1097         release_firmware(fw);
1098
1099         return ret;
1100 }
1101
1102 int ath6kl_init_fetch_firmwares(struct ath6kl *ar)
1103 {
1104         int ret;
1105
1106         ret = ath6kl_fetch_board_file(ar);
1107         if (ret)
1108                 return ret;
1109
1110         ret = ath6kl_fetch_testmode_file(ar);
1111         if (ret)
1112                 return ret;
1113
1114         ret = ath6kl_fetch_fw_apin(ar, ATH6KL_FW_API4_FILE);
1115         if (ret == 0) {
1116                 ar->fw_api = 4;
1117                 goto out;
1118         }
1119
1120         ret = ath6kl_fetch_fw_apin(ar, ATH6KL_FW_API3_FILE);
1121         if (ret == 0) {
1122                 ar->fw_api = 3;
1123                 goto out;
1124         }
1125
1126         ret = ath6kl_fetch_fw_apin(ar, ATH6KL_FW_API2_FILE);
1127         if (ret == 0) {
1128                 ar->fw_api = 2;
1129                 goto out;
1130         }
1131
1132         ret = ath6kl_fetch_fw_api1(ar);
1133         if (ret)
1134                 return ret;
1135
1136         ar->fw_api = 1;
1137
1138 out:
1139         ath6kl_dbg(ATH6KL_DBG_BOOT, "using fw api %d\n", ar->fw_api);
1140
1141         return 0;
1142 }
1143
1144 static int ath6kl_upload_board_file(struct ath6kl *ar)
1145 {
1146         u32 board_address, board_ext_address, param;
1147         u32 board_data_size, board_ext_data_size;
1148         int ret;
1149
1150         if (WARN_ON(ar->fw_board == NULL))
1151                 return -ENOENT;
1152
1153         /*
1154          * Determine where in Target RAM to write Board Data.
1155          * For AR6004, host determine Target RAM address for
1156          * writing board data.
1157          */
1158         if (ar->hw.board_addr != 0) {
1159                 board_address = ar->hw.board_addr;
1160                 ath6kl_bmi_write_hi32(ar, hi_board_data,
1161                                       board_address);
1162         } else {
1163                 ath6kl_bmi_read_hi32(ar, hi_board_data, &board_address);
1164         }
1165
1166         /* determine where in target ram to write extended board data */
1167         ath6kl_bmi_read_hi32(ar, hi_board_ext_data, &board_ext_address);
1168
1169         if (ar->target_type == TARGET_TYPE_AR6003 &&
1170             board_ext_address == 0) {
1171                 ath6kl_err("Failed to get board file target address.\n");
1172                 return -EINVAL;
1173         }
1174
1175         switch (ar->target_type) {
1176         case TARGET_TYPE_AR6003:
1177                 board_data_size = AR6003_BOARD_DATA_SZ;
1178                 board_ext_data_size = AR6003_BOARD_EXT_DATA_SZ;
1179                 if (ar->fw_board_len > (board_data_size + board_ext_data_size))
1180                         board_ext_data_size = AR6003_BOARD_EXT_DATA_SZ_V2;
1181                 break;
1182         case TARGET_TYPE_AR6004:
1183                 board_data_size = AR6004_BOARD_DATA_SZ;
1184                 board_ext_data_size = AR6004_BOARD_EXT_DATA_SZ;
1185                 break;
1186         default:
1187                 WARN_ON(1);
1188                 return -EINVAL;
1189                 break;
1190         }
1191
1192         if (board_ext_address &&
1193             ar->fw_board_len == (board_data_size + board_ext_data_size)) {
1194
1195                 /* write extended board data */
1196                 ath6kl_dbg(ATH6KL_DBG_BOOT,
1197                            "writing extended board data to 0x%x (%d B)\n",
1198                            board_ext_address, board_ext_data_size);
1199
1200                 ret = ath6kl_bmi_write(ar, board_ext_address,
1201                                        ar->fw_board + board_data_size,
1202                                        board_ext_data_size);
1203                 if (ret) {
1204                         ath6kl_err("Failed to write extended board data: %d\n",
1205                                    ret);
1206                         return ret;
1207                 }
1208
1209                 /* record that extended board data is initialized */
1210                 param = (board_ext_data_size << 16) | 1;
1211
1212                 ath6kl_bmi_write_hi32(ar, hi_board_ext_data_config, param);
1213         }
1214
1215         if (ar->fw_board_len < board_data_size) {
1216                 ath6kl_err("Too small board file: %zu\n", ar->fw_board_len);
1217                 ret = -EINVAL;
1218                 return ret;
1219         }
1220
1221         ath6kl_dbg(ATH6KL_DBG_BOOT, "writing board file to 0x%x (%d B)\n",
1222                    board_address, board_data_size);
1223
1224         ret = ath6kl_bmi_write(ar, board_address, ar->fw_board,
1225                                board_data_size);
1226
1227         if (ret) {
1228                 ath6kl_err("Board file bmi write failed: %d\n", ret);
1229                 return ret;
1230         }
1231
1232         /* record the fact that Board Data IS initialized */
1233         ath6kl_bmi_write_hi32(ar, hi_board_data_initialized, 1);
1234
1235         return ret;
1236 }
1237
1238 static int ath6kl_upload_otp(struct ath6kl *ar)
1239 {
1240         u32 address, param;
1241         bool from_hw = false;
1242         int ret;
1243
1244         if (ar->fw_otp == NULL)
1245                 return 0;
1246
1247         address = ar->hw.app_load_addr;
1248
1249         ath6kl_dbg(ATH6KL_DBG_BOOT, "writing otp to 0x%x (%zd B)\n", address,
1250                    ar->fw_otp_len);
1251
1252         ret = ath6kl_bmi_fast_download(ar, address, ar->fw_otp,
1253                                        ar->fw_otp_len);
1254         if (ret) {
1255                 ath6kl_err("Failed to upload OTP file: %d\n", ret);
1256                 return ret;
1257         }
1258
1259         /* read firmware start address */
1260         ret = ath6kl_bmi_read_hi32(ar, hi_app_start, &address);
1261
1262         if (ret) {
1263                 ath6kl_err("Failed to read hi_app_start: %d\n", ret);
1264                 return ret;
1265         }
1266
1267         if (ar->hw.app_start_override_addr == 0) {
1268                 ar->hw.app_start_override_addr = address;
1269                 from_hw = true;
1270         }
1271
1272         ath6kl_dbg(ATH6KL_DBG_BOOT, "app_start_override_addr%s 0x%x\n",
1273                    from_hw ? " (from hw)" : "",
1274                    ar->hw.app_start_override_addr);
1275
1276         /* execute the OTP code */
1277         ath6kl_dbg(ATH6KL_DBG_BOOT, "executing OTP at 0x%x\n",
1278                    ar->hw.app_start_override_addr);
1279         param = 0;
1280         ath6kl_bmi_execute(ar, ar->hw.app_start_override_addr, &param);
1281
1282         return ret;
1283 }
1284
1285 static int ath6kl_upload_firmware(struct ath6kl *ar)
1286 {
1287         u32 address;
1288         int ret;
1289
1290         if (WARN_ON(ar->fw == NULL))
1291                 return 0;
1292
1293         address = ar->hw.app_load_addr;
1294
1295         ath6kl_dbg(ATH6KL_DBG_BOOT, "writing firmware to 0x%x (%zd B)\n",
1296                    address, ar->fw_len);
1297
1298         ret = ath6kl_bmi_fast_download(ar, address, ar->fw, ar->fw_len);
1299
1300         if (ret) {
1301                 ath6kl_err("Failed to write firmware: %d\n", ret);
1302                 return ret;
1303         }
1304
1305         /*
1306          * Set starting address for firmware
1307          * Don't need to setup app_start override addr on AR6004
1308          */
1309         if (ar->target_type != TARGET_TYPE_AR6004) {
1310                 address = ar->hw.app_start_override_addr;
1311                 ath6kl_bmi_set_app_start(ar, address);
1312         }
1313         return ret;
1314 }
1315
1316 static int ath6kl_upload_patch(struct ath6kl *ar)
1317 {
1318         u32 address;
1319         int ret;
1320
1321         if (ar->fw_patch == NULL)
1322                 return 0;
1323
1324         address = ar->hw.dataset_patch_addr;
1325
1326         ath6kl_dbg(ATH6KL_DBG_BOOT, "writing patch to 0x%x (%zd B)\n",
1327                    address, ar->fw_patch_len);
1328
1329         ret = ath6kl_bmi_write(ar, address, ar->fw_patch, ar->fw_patch_len);
1330         if (ret) {
1331                 ath6kl_err("Failed to write patch file: %d\n", ret);
1332                 return ret;
1333         }
1334
1335         ath6kl_bmi_write_hi32(ar, hi_dset_list_head, address);
1336
1337         return 0;
1338 }
1339
1340 static int ath6kl_upload_testscript(struct ath6kl *ar)
1341 {
1342         u32 address;
1343         int ret;
1344
1345         if (ar->testmode != 2)
1346                 return 0;
1347
1348         if (ar->fw_testscript == NULL)
1349                 return 0;
1350
1351         address = ar->hw.testscript_addr;
1352
1353         ath6kl_dbg(ATH6KL_DBG_BOOT, "writing testscript to 0x%x (%zd B)\n",
1354                    address, ar->fw_testscript_len);
1355
1356         ret = ath6kl_bmi_write(ar, address, ar->fw_testscript,
1357                 ar->fw_testscript_len);
1358         if (ret) {
1359                 ath6kl_err("Failed to write testscript file: %d\n", ret);
1360                 return ret;
1361         }
1362
1363         ath6kl_bmi_write_hi32(ar, hi_ota_testscript, address);
1364         ath6kl_bmi_write_hi32(ar, hi_end_ram_reserve_sz, 4096);
1365         ath6kl_bmi_write_hi32(ar, hi_test_apps_related, 1);
1366
1367         return 0;
1368 }
1369
1370 static int ath6kl_init_upload(struct ath6kl *ar)
1371 {
1372         u32 param, options, sleep, address;
1373         int status = 0;
1374
1375         if (ar->target_type != TARGET_TYPE_AR6003 &&
1376             ar->target_type != TARGET_TYPE_AR6004)
1377                 return -EINVAL;
1378
1379         /* temporarily disable system sleep */
1380         address = MBOX_BASE_ADDRESS + LOCAL_SCRATCH_ADDRESS;
1381         status = ath6kl_bmi_reg_read(ar, address, &param);
1382         if (status)
1383                 return status;
1384
1385         options = param;
1386
1387         param |= ATH6KL_OPTION_SLEEP_DISABLE;
1388         status = ath6kl_bmi_reg_write(ar, address, param);
1389         if (status)
1390                 return status;
1391
1392         address = RTC_BASE_ADDRESS + SYSTEM_SLEEP_ADDRESS;
1393         status = ath6kl_bmi_reg_read(ar, address, &param);
1394         if (status)
1395                 return status;
1396
1397         sleep = param;
1398
1399         param |= SM(SYSTEM_SLEEP_DISABLE, 1);
1400         status = ath6kl_bmi_reg_write(ar, address, param);
1401         if (status)
1402                 return status;
1403
1404         ath6kl_dbg(ATH6KL_DBG_TRC, "old options: %d, old sleep: %d\n",
1405                    options, sleep);
1406
1407         /* program analog PLL register */
1408         /* no need to control 40/44MHz clock on AR6004 */
1409         if (ar->target_type != TARGET_TYPE_AR6004) {
1410                 status = ath6kl_bmi_reg_write(ar, ATH6KL_ANALOG_PLL_REGISTER,
1411                                               0xF9104001);
1412
1413                 if (status)
1414                         return status;
1415
1416                 /* Run at 80/88MHz by default */
1417                 param = SM(CPU_CLOCK_STANDARD, 1);
1418
1419                 address = RTC_BASE_ADDRESS + CPU_CLOCK_ADDRESS;
1420                 status = ath6kl_bmi_reg_write(ar, address, param);
1421                 if (status)
1422                         return status;
1423         }
1424
1425         param = 0;
1426         address = RTC_BASE_ADDRESS + LPO_CAL_ADDRESS;
1427         param = SM(LPO_CAL_ENABLE, 1);
1428         status = ath6kl_bmi_reg_write(ar, address, param);
1429         if (status)
1430                 return status;
1431
1432         /* WAR to avoid SDIO CRC err */
1433         if (ar->version.target_ver == AR6003_HW_2_0_VERSION ||
1434             ar->version.target_ver == AR6003_HW_2_1_1_VERSION) {
1435                 ath6kl_err("temporary war to avoid sdio crc error\n");
1436
1437                 param = 0x28;
1438                 address = GPIO_BASE_ADDRESS + GPIO_PIN9_ADDRESS;
1439                 status = ath6kl_bmi_reg_write(ar, address, param);
1440                 if (status)
1441                         return status;
1442
1443                 param = 0x20;
1444
1445                 address = GPIO_BASE_ADDRESS + GPIO_PIN10_ADDRESS;
1446                 status = ath6kl_bmi_reg_write(ar, address, param);
1447                 if (status)
1448                         return status;
1449
1450                 address = GPIO_BASE_ADDRESS + GPIO_PIN11_ADDRESS;
1451                 status = ath6kl_bmi_reg_write(ar, address, param);
1452                 if (status)
1453                         return status;
1454
1455                 address = GPIO_BASE_ADDRESS + GPIO_PIN12_ADDRESS;
1456                 status = ath6kl_bmi_reg_write(ar, address, param);
1457                 if (status)
1458                         return status;
1459
1460                 address = GPIO_BASE_ADDRESS + GPIO_PIN13_ADDRESS;
1461                 status = ath6kl_bmi_reg_write(ar, address, param);
1462                 if (status)
1463                         return status;
1464         }
1465
1466         /* write EEPROM data to Target RAM */
1467         status = ath6kl_upload_board_file(ar);
1468         if (status)
1469                 return status;
1470
1471         /* transfer One time Programmable data */
1472         status = ath6kl_upload_otp(ar);
1473         if (status)
1474                 return status;
1475
1476         /* Download Target firmware */
1477         status = ath6kl_upload_firmware(ar);
1478         if (status)
1479                 return status;
1480
1481         status = ath6kl_upload_patch(ar);
1482         if (status)
1483                 return status;
1484
1485         /* Download the test script */
1486         status = ath6kl_upload_testscript(ar);
1487         if (status)
1488                 return status;
1489
1490         /* Restore system sleep */
1491         address = RTC_BASE_ADDRESS + SYSTEM_SLEEP_ADDRESS;
1492         status = ath6kl_bmi_reg_write(ar, address, sleep);
1493         if (status)
1494                 return status;
1495
1496         address = MBOX_BASE_ADDRESS + LOCAL_SCRATCH_ADDRESS;
1497         param = options | 0x20;
1498         status = ath6kl_bmi_reg_write(ar, address, param);
1499         if (status)
1500                 return status;
1501
1502         return status;
1503 }
1504
1505 int ath6kl_init_hw_params(struct ath6kl *ar)
1506 {
1507         const struct ath6kl_hw *uninitialized_var(hw);
1508         int i;
1509
1510         for (i = 0; i < ARRAY_SIZE(hw_list); i++) {
1511                 hw = &hw_list[i];
1512
1513                 if (hw->id == ar->version.target_ver)
1514                         break;
1515         }
1516
1517         if (i == ARRAY_SIZE(hw_list)) {
1518                 ath6kl_err("Unsupported hardware version: 0x%x\n",
1519                            ar->version.target_ver);
1520                 return -EINVAL;
1521         }
1522
1523         ar->hw = *hw;
1524
1525         ath6kl_dbg(ATH6KL_DBG_BOOT,
1526                    "target_ver 0x%x target_type 0x%x dataset_patch 0x%x app_load_addr 0x%x\n",
1527                    ar->version.target_ver, ar->target_type,
1528                    ar->hw.dataset_patch_addr, ar->hw.app_load_addr);
1529         ath6kl_dbg(ATH6KL_DBG_BOOT,
1530                    "app_start_override_addr 0x%x board_ext_data_addr 0x%x reserved_ram_size 0x%x",
1531                    ar->hw.app_start_override_addr, ar->hw.board_ext_data_addr,
1532                    ar->hw.reserved_ram_size);
1533         ath6kl_dbg(ATH6KL_DBG_BOOT,
1534                    "refclk_hz %d uarttx_pin %d",
1535                    ar->hw.refclk_hz, ar->hw.uarttx_pin);
1536
1537         return 0;
1538 }
1539
1540 static const char *ath6kl_init_get_hif_name(enum ath6kl_hif_type type)
1541 {
1542         switch (type) {
1543         case ATH6KL_HIF_TYPE_SDIO:
1544                 return "sdio";
1545         case ATH6KL_HIF_TYPE_USB:
1546                 return "usb";
1547         }
1548
1549         return NULL;
1550 }
1551
1552 static int __ath6kl_init_hw_start(struct ath6kl *ar)
1553 {
1554         long timeleft;
1555         int ret, i;
1556
1557         ath6kl_dbg(ATH6KL_DBG_BOOT, "hw start\n");
1558
1559         ret = ath6kl_hif_power_on(ar);
1560         if (ret)
1561                 return ret;
1562
1563         ret = ath6kl_configure_target(ar);
1564         if (ret)
1565                 goto err_power_off;
1566
1567         ret = ath6kl_init_upload(ar);
1568         if (ret)
1569                 goto err_power_off;
1570
1571         /* Do we need to finish the BMI phase */
1572         /* FIXME: return error from ath6kl_bmi_done() */
1573         if (ath6kl_bmi_done(ar)) {
1574                 ret = -EIO;
1575                 goto err_power_off;
1576         }
1577
1578         /*
1579          * The reason we have to wait for the target here is that the
1580          * driver layer has to init BMI in order to set the host block
1581          * size.
1582          */
1583         if (ath6kl_htc_wait_target(ar->htc_target)) {
1584                 ret = -EIO;
1585                 goto err_power_off;
1586         }
1587
1588         if (ath6kl_init_service_ep(ar)) {
1589                 ret = -EIO;
1590                 goto err_cleanup_scatter;
1591         }
1592
1593         /* setup credit distribution */
1594         ath6kl_htc_credit_setup(ar->htc_target, &ar->credit_state_info);
1595
1596         /* start HTC */
1597         ret = ath6kl_htc_start(ar->htc_target);
1598         if (ret) {
1599                 /* FIXME: call this */
1600                 ath6kl_cookie_cleanup(ar);
1601                 goto err_cleanup_scatter;
1602         }
1603
1604         /* Wait for Wmi event to be ready */
1605         timeleft = wait_event_interruptible_timeout(ar->event_wq,
1606                                                     test_bit(WMI_READY,
1607                                                              &ar->flag),
1608                                                     WMI_TIMEOUT);
1609
1610         ath6kl_dbg(ATH6KL_DBG_BOOT, "firmware booted\n");
1611
1612
1613         if (test_and_clear_bit(FIRST_BOOT, &ar->flag)) {
1614                 ath6kl_info("%s %s fw %s api %d%s\n",
1615                             ar->hw.name,
1616                             ath6kl_init_get_hif_name(ar->hif_type),
1617                             ar->wiphy->fw_version,
1618                             ar->fw_api,
1619                             test_bit(TESTMODE, &ar->flag) ? " testmode" : "");
1620         }
1621
1622         if (ar->version.abi_ver != ATH6KL_ABI_VERSION) {
1623                 ath6kl_err("abi version mismatch: host(0x%x), target(0x%x)\n",
1624                            ATH6KL_ABI_VERSION, ar->version.abi_ver);
1625                 ret = -EIO;
1626                 goto err_htc_stop;
1627         }
1628
1629         if (!timeleft || signal_pending(current)) {
1630                 ath6kl_err("wmi is not ready or wait was interrupted\n");
1631                 ret = -EIO;
1632                 goto err_htc_stop;
1633         }
1634
1635         ath6kl_dbg(ATH6KL_DBG_TRC, "%s: wmi is ready\n", __func__);
1636
1637         /* communicate the wmi protocol verision to the target */
1638         /* FIXME: return error */
1639         if ((ath6kl_set_host_app_area(ar)) != 0)
1640                 ath6kl_err("unable to set the host app area\n");
1641
1642         for (i = 0; i < ar->vif_max; i++) {
1643                 ret = ath6kl_target_config_wlan_params(ar, i);
1644                 if (ret)
1645                         goto err_htc_stop;
1646         }
1647
1648         return 0;
1649
1650 err_htc_stop:
1651         ath6kl_htc_stop(ar->htc_target);
1652 err_cleanup_scatter:
1653         ath6kl_hif_cleanup_scatter(ar);
1654 err_power_off:
1655         ath6kl_hif_power_off(ar);
1656
1657         return ret;
1658 }
1659
1660 int ath6kl_init_hw_start(struct ath6kl *ar)
1661 {
1662         int err;
1663
1664         err = __ath6kl_init_hw_start(ar);
1665         if (err)
1666                 return err;
1667         ar->state = ATH6KL_STATE_ON;
1668         return 0;
1669 }
1670
1671 static int __ath6kl_init_hw_stop(struct ath6kl *ar)
1672 {
1673         int ret;
1674
1675         ath6kl_dbg(ATH6KL_DBG_BOOT, "hw stop\n");
1676
1677         ath6kl_htc_stop(ar->htc_target);
1678
1679         ath6kl_hif_stop(ar);
1680
1681         ath6kl_bmi_reset(ar);
1682
1683         ret = ath6kl_hif_power_off(ar);
1684         if (ret)
1685                 ath6kl_warn("failed to power off hif: %d\n", ret);
1686
1687         return 0;
1688 }
1689
1690 int ath6kl_init_hw_stop(struct ath6kl *ar)
1691 {
1692         int err;
1693
1694         err = __ath6kl_init_hw_stop(ar);
1695         if (err)
1696                 return err;
1697         ar->state = ATH6KL_STATE_OFF;
1698         return 0;
1699 }
1700
1701 void ath6kl_init_hw_restart(struct ath6kl *ar)
1702 {
1703         clear_bit(WMI_READY, &ar->flag);
1704
1705         ath6kl_cfg80211_stop_all(ar);
1706
1707         if (__ath6kl_init_hw_stop(ar)) {
1708                 ath6kl_dbg(ATH6KL_DBG_RECOVERY, "Failed to stop during fw error recovery\n");
1709                 return;
1710         }
1711
1712         if (__ath6kl_init_hw_start(ar)) {
1713                 ath6kl_dbg(ATH6KL_DBG_RECOVERY, "Failed to restart during fw error recovery\n");
1714                 return;
1715         }
1716 }
1717
1718 /* FIXME: move this to cfg80211.c and rename to ath6kl_cfg80211_vif_stop() */
1719 void ath6kl_cleanup_vif(struct ath6kl_vif *vif, bool wmi_ready)
1720 {
1721         static u8 bcast_mac[] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
1722         bool discon_issued;
1723
1724         netif_stop_queue(vif->ndev);
1725
1726         clear_bit(WLAN_ENABLED, &vif->flags);
1727
1728         if (wmi_ready) {
1729                 discon_issued = test_bit(CONNECTED, &vif->flags) ||
1730                                 test_bit(CONNECT_PEND, &vif->flags);
1731                 ath6kl_disconnect(vif);
1732                 del_timer(&vif->disconnect_timer);
1733
1734                 if (discon_issued)
1735                         ath6kl_disconnect_event(vif, DISCONNECT_CMD,
1736                                                 (vif->nw_type & AP_NETWORK) ?
1737                                                 bcast_mac : vif->bssid,
1738                                                 0, NULL, 0);
1739         }
1740
1741         if (vif->scan_req) {
1742                 cfg80211_scan_done(vif->scan_req, true);
1743                 vif->scan_req = NULL;
1744         }
1745
1746         /* need to clean up enhanced bmiss detection fw state */
1747         ath6kl_cfg80211_sta_bmiss_enhance(vif, false);
1748 }
1749
1750 void ath6kl_stop_txrx(struct ath6kl *ar)
1751 {
1752         struct ath6kl_vif *vif, *tmp_vif;
1753         int i;
1754
1755         set_bit(DESTROY_IN_PROGRESS, &ar->flag);
1756
1757         if (down_interruptible(&ar->sem)) {
1758                 ath6kl_err("down_interruptible failed\n");
1759                 return;
1760         }
1761
1762         for (i = 0; i < AP_MAX_NUM_STA; i++)
1763                 aggr_reset_state(ar->sta_list[i].aggr_conn);
1764
1765         spin_lock_bh(&ar->list_lock);
1766         list_for_each_entry_safe(vif, tmp_vif, &ar->vif_list, list) {
1767                 list_del(&vif->list);
1768                 spin_unlock_bh(&ar->list_lock);
1769                 ath6kl_cleanup_vif(vif, test_bit(WMI_READY, &ar->flag));
1770                 rtnl_lock();
1771                 ath6kl_cfg80211_vif_cleanup(vif);
1772                 rtnl_unlock();
1773                 spin_lock_bh(&ar->list_lock);
1774         }
1775         spin_unlock_bh(&ar->list_lock);
1776
1777         clear_bit(WMI_READY, &ar->flag);
1778
1779         /*
1780          * After wmi_shudown all WMI events will be dropped. We
1781          * need to cleanup the buffers allocated in AP mode and
1782          * give disconnect notification to stack, which usually
1783          * happens in the disconnect_event. Simulate the disconnect
1784          * event by calling the function directly. Sometimes
1785          * disconnect_event will be received when the debug logs
1786          * are collected.
1787          */
1788         ath6kl_wmi_shutdown(ar->wmi);
1789
1790         clear_bit(WMI_ENABLED, &ar->flag);
1791         if (ar->htc_target) {
1792                 ath6kl_dbg(ATH6KL_DBG_TRC, "%s: shut down htc\n", __func__);
1793                 ath6kl_htc_stop(ar->htc_target);
1794         }
1795
1796         /*
1797          * Try to reset the device if we can. The driver may have been
1798          * configure NOT to reset the target during a debug session.
1799          */
1800         ath6kl_dbg(ATH6KL_DBG_TRC,
1801                    "attempting to reset target on instance destroy\n");
1802         ath6kl_reset_device(ar, ar->target_type, true, true);
1803
1804         clear_bit(WLAN_ENABLED, &ar->flag);
1805
1806         up(&ar->sem);
1807 }
1808 EXPORT_SYMBOL(ath6kl_stop_txrx);