0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018
0019 #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
0020
0021 #include <linux/moduleparam.h>
0022 #include <linux/errno.h>
0023 #include <linux/export.h>
0024 #include <linux/of.h>
0025 #include <linux/mmc/sdio_func.h>
0026 #include <linux/vmalloc.h>
0027
0028 #include "core.h"
0029 #include "cfg80211.h"
0030 #include "target.h"
0031 #include "debug.h"
0032 #include "hif-ops.h"
0033 #include "htc-ops.h"
0034
0035 static const struct ath6kl_hw hw_list[] = {
0036 {
0037 .id = AR6003_HW_2_0_VERSION,
0038 .name = "ar6003 hw 2.0",
0039 .dataset_patch_addr = 0x57e884,
0040 .app_load_addr = 0x543180,
0041 .board_ext_data_addr = 0x57e500,
0042 .reserved_ram_size = 6912,
0043 .refclk_hz = 26000000,
0044 .uarttx_pin = 8,
0045 .flags = ATH6KL_HW_SDIO_CRC_ERROR_WAR,
0046
0047
0048 .app_start_override_addr = 0x944C00,
0049
0050 .fw = {
0051 .dir = AR6003_HW_2_0_FW_DIR,
0052 .otp = AR6003_HW_2_0_OTP_FILE,
0053 .fw = AR6003_HW_2_0_FIRMWARE_FILE,
0054 .tcmd = AR6003_HW_2_0_TCMD_FIRMWARE_FILE,
0055 .patch = AR6003_HW_2_0_PATCH_FILE,
0056 },
0057
0058 .fw_board = AR6003_HW_2_0_BOARD_DATA_FILE,
0059 .fw_default_board = AR6003_HW_2_0_DEFAULT_BOARD_DATA_FILE,
0060 },
0061 {
0062 .id = AR6003_HW_2_1_1_VERSION,
0063 .name = "ar6003 hw 2.1.1",
0064 .dataset_patch_addr = 0x57ff74,
0065 .app_load_addr = 0x1234,
0066 .board_ext_data_addr = 0x542330,
0067 .reserved_ram_size = 512,
0068 .refclk_hz = 26000000,
0069 .uarttx_pin = 8,
0070 .testscript_addr = 0x57ef74,
0071 .flags = ATH6KL_HW_SDIO_CRC_ERROR_WAR,
0072
0073 .fw = {
0074 .dir = AR6003_HW_2_1_1_FW_DIR,
0075 .otp = AR6003_HW_2_1_1_OTP_FILE,
0076 .fw = AR6003_HW_2_1_1_FIRMWARE_FILE,
0077 .tcmd = AR6003_HW_2_1_1_TCMD_FIRMWARE_FILE,
0078 .patch = AR6003_HW_2_1_1_PATCH_FILE,
0079 .utf = AR6003_HW_2_1_1_UTF_FIRMWARE_FILE,
0080 .testscript = AR6003_HW_2_1_1_TESTSCRIPT_FILE,
0081 },
0082
0083 .fw_board = AR6003_HW_2_1_1_BOARD_DATA_FILE,
0084 .fw_default_board = AR6003_HW_2_1_1_DEFAULT_BOARD_DATA_FILE,
0085 },
0086 {
0087 .id = AR6004_HW_1_0_VERSION,
0088 .name = "ar6004 hw 1.0",
0089 .dataset_patch_addr = 0x57e884,
0090 .app_load_addr = 0x1234,
0091 .board_ext_data_addr = 0x437000,
0092 .reserved_ram_size = 19456,
0093 .board_addr = 0x433900,
0094 .refclk_hz = 26000000,
0095 .uarttx_pin = 11,
0096 .flags = 0,
0097
0098 .fw = {
0099 .dir = AR6004_HW_1_0_FW_DIR,
0100 .fw = AR6004_HW_1_0_FIRMWARE_FILE,
0101 },
0102
0103 .fw_board = AR6004_HW_1_0_BOARD_DATA_FILE,
0104 .fw_default_board = AR6004_HW_1_0_DEFAULT_BOARD_DATA_FILE,
0105 },
0106 {
0107 .id = AR6004_HW_1_1_VERSION,
0108 .name = "ar6004 hw 1.1",
0109 .dataset_patch_addr = 0x57e884,
0110 .app_load_addr = 0x1234,
0111 .board_ext_data_addr = 0x437000,
0112 .reserved_ram_size = 11264,
0113 .board_addr = 0x43d400,
0114 .refclk_hz = 40000000,
0115 .uarttx_pin = 11,
0116 .flags = 0,
0117 .fw = {
0118 .dir = AR6004_HW_1_1_FW_DIR,
0119 .fw = AR6004_HW_1_1_FIRMWARE_FILE,
0120 },
0121
0122 .fw_board = AR6004_HW_1_1_BOARD_DATA_FILE,
0123 .fw_default_board = AR6004_HW_1_1_DEFAULT_BOARD_DATA_FILE,
0124 },
0125 {
0126 .id = AR6004_HW_1_2_VERSION,
0127 .name = "ar6004 hw 1.2",
0128 .dataset_patch_addr = 0x436ecc,
0129 .app_load_addr = 0x1234,
0130 .board_ext_data_addr = 0x437000,
0131 .reserved_ram_size = 9216,
0132 .board_addr = 0x435c00,
0133 .refclk_hz = 40000000,
0134 .uarttx_pin = 11,
0135 .flags = 0,
0136
0137 .fw = {
0138 .dir = AR6004_HW_1_2_FW_DIR,
0139 .fw = AR6004_HW_1_2_FIRMWARE_FILE,
0140 },
0141 .fw_board = AR6004_HW_1_2_BOARD_DATA_FILE,
0142 .fw_default_board = AR6004_HW_1_2_DEFAULT_BOARD_DATA_FILE,
0143 },
0144 {
0145 .id = AR6004_HW_1_3_VERSION,
0146 .name = "ar6004 hw 1.3",
0147 .dataset_patch_addr = 0x437860,
0148 .app_load_addr = 0x1234,
0149 .board_ext_data_addr = 0x437000,
0150 .reserved_ram_size = 7168,
0151 .board_addr = 0x436400,
0152 .refclk_hz = 0,
0153 .uarttx_pin = 11,
0154 .flags = 0,
0155
0156 .fw = {
0157 .dir = AR6004_HW_1_3_FW_DIR,
0158 .fw = AR6004_HW_1_3_FIRMWARE_FILE,
0159 .tcmd = AR6004_HW_1_3_TCMD_FIRMWARE_FILE,
0160 .utf = AR6004_HW_1_3_UTF_FIRMWARE_FILE,
0161 .testscript = AR6004_HW_1_3_TESTSCRIPT_FILE,
0162 },
0163
0164 .fw_board = AR6004_HW_1_3_BOARD_DATA_FILE,
0165 .fw_default_board = AR6004_HW_1_3_DEFAULT_BOARD_DATA_FILE,
0166 },
0167 {
0168 .id = AR6004_HW_3_0_VERSION,
0169 .name = "ar6004 hw 3.0",
0170 .dataset_patch_addr = 0,
0171 .app_load_addr = 0x1234,
0172 .board_ext_data_addr = 0,
0173 .reserved_ram_size = 7168,
0174 .board_addr = 0x436400,
0175 .testscript_addr = 0,
0176 .uarttx_pin = 11,
0177 .flags = 0,
0178
0179 .fw = {
0180 .dir = AR6004_HW_3_0_FW_DIR,
0181 .fw = AR6004_HW_3_0_FIRMWARE_FILE,
0182 .tcmd = AR6004_HW_3_0_TCMD_FIRMWARE_FILE,
0183 .utf = AR6004_HW_3_0_UTF_FIRMWARE_FILE,
0184 .testscript = AR6004_HW_3_0_TESTSCRIPT_FILE,
0185 },
0186
0187 .fw_board = AR6004_HW_3_0_BOARD_DATA_FILE,
0188 .fw_default_board = AR6004_HW_3_0_DEFAULT_BOARD_DATA_FILE,
0189 },
0190 };
0191
0192
0193
0194
0195
0196
0197
0198
0199
0200
0201
0202
0203
0204
0205
0206 #define WLAN_CONFIG_KEEP_ALIVE_INTERVAL 60
0207
0208
0209
0210
0211
0212
0213
0214
0215 #define WLAN_CONFIG_DISCONNECT_TIMEOUT 10
0216
0217
0218 #define ATH6KL_DATA_OFFSET 64
0219 struct sk_buff *ath6kl_buf_alloc(int size)
0220 {
0221 struct sk_buff *skb;
0222 u16 reserved;
0223
0224
0225 reserved = roundup((2 * L1_CACHE_BYTES) + ATH6KL_DATA_OFFSET +
0226 sizeof(struct htc_packet) + ATH6KL_HTC_ALIGN_BYTES, 4);
0227 skb = dev_alloc_skb(size + reserved);
0228
0229 if (skb)
0230 skb_reserve(skb, reserved - L1_CACHE_BYTES);
0231 return skb;
0232 }
0233
0234 void ath6kl_init_profile_info(struct ath6kl_vif *vif)
0235 {
0236 vif->ssid_len = 0;
0237 memset(vif->ssid, 0, sizeof(vif->ssid));
0238
0239 vif->dot11_auth_mode = OPEN_AUTH;
0240 vif->auth_mode = NONE_AUTH;
0241 vif->prwise_crypto = NONE_CRYPT;
0242 vif->prwise_crypto_len = 0;
0243 vif->grp_crypto = NONE_CRYPT;
0244 vif->grp_crypto_len = 0;
0245 memset(vif->wep_key_list, 0, sizeof(vif->wep_key_list));
0246 memset(vif->req_bssid, 0, sizeof(vif->req_bssid));
0247 memset(vif->bssid, 0, sizeof(vif->bssid));
0248 vif->bss_ch = 0;
0249 }
0250
0251 static int ath6kl_set_host_app_area(struct ath6kl *ar)
0252 {
0253 u32 address, data;
0254 struct host_app_area host_app_area;
0255
0256
0257
0258 address = ath6kl_get_hi_item_addr(ar, HI_ITEM(hi_app_host_interest));
0259 address = TARG_VTOP(ar->target_type, address);
0260
0261 if (ath6kl_diag_read32(ar, address, &data))
0262 return -EIO;
0263
0264 address = TARG_VTOP(ar->target_type, data);
0265 host_app_area.wmi_protocol_ver = cpu_to_le32(WMI_PROTOCOL_VERSION);
0266 if (ath6kl_diag_write(ar, address, (u8 *) &host_app_area,
0267 sizeof(struct host_app_area)))
0268 return -EIO;
0269
0270 return 0;
0271 }
0272
0273 static inline void set_ac2_ep_map(struct ath6kl *ar,
0274 u8 ac,
0275 enum htc_endpoint_id ep)
0276 {
0277 ar->ac2ep_map[ac] = ep;
0278 ar->ep2ac_map[ep] = ac;
0279 }
0280
0281
0282 static int ath6kl_connectservice(struct ath6kl *ar,
0283 struct htc_service_connect_req *con_req,
0284 char *desc)
0285 {
0286 int status;
0287 struct htc_service_connect_resp response;
0288
0289 memset(&response, 0, sizeof(response));
0290
0291 status = ath6kl_htc_conn_service(ar->htc_target, con_req, &response);
0292 if (status) {
0293 ath6kl_err("failed to connect to %s service status:%d\n",
0294 desc, status);
0295 return status;
0296 }
0297
0298 switch (con_req->svc_id) {
0299 case WMI_CONTROL_SVC:
0300 if (test_bit(WMI_ENABLED, &ar->flag))
0301 ath6kl_wmi_set_control_ep(ar->wmi, response.endpoint);
0302 ar->ctrl_ep = response.endpoint;
0303 break;
0304 case WMI_DATA_BE_SVC:
0305 set_ac2_ep_map(ar, WMM_AC_BE, response.endpoint);
0306 break;
0307 case WMI_DATA_BK_SVC:
0308 set_ac2_ep_map(ar, WMM_AC_BK, response.endpoint);
0309 break;
0310 case WMI_DATA_VI_SVC:
0311 set_ac2_ep_map(ar, WMM_AC_VI, response.endpoint);
0312 break;
0313 case WMI_DATA_VO_SVC:
0314 set_ac2_ep_map(ar, WMM_AC_VO, response.endpoint);
0315 break;
0316 default:
0317 ath6kl_err("service id is not mapped %d\n", con_req->svc_id);
0318 return -EINVAL;
0319 }
0320
0321 return 0;
0322 }
0323
0324 static int ath6kl_init_service_ep(struct ath6kl *ar)
0325 {
0326 struct htc_service_connect_req connect;
0327
0328 memset(&connect, 0, sizeof(connect));
0329
0330
0331 connect.ep_cb.tx_comp_multi = ath6kl_tx_complete;
0332 connect.ep_cb.rx = ath6kl_rx;
0333 connect.ep_cb.rx_refill = ath6kl_rx_refill;
0334 connect.ep_cb.tx_full = ath6kl_tx_queue_full;
0335
0336
0337
0338
0339
0340 connect.max_txq_depth = MAX_DEFAULT_SEND_QUEUE_DEPTH;
0341 connect.ep_cb.rx_refill_thresh = ATH6KL_MAX_RX_BUFFERS / 4;
0342 if (!connect.ep_cb.rx_refill_thresh)
0343 connect.ep_cb.rx_refill_thresh++;
0344
0345
0346 connect.svc_id = WMI_CONTROL_SVC;
0347 if (ath6kl_connectservice(ar, &connect, "WMI CONTROL"))
0348 return -EIO;
0349
0350 connect.flags |= HTC_FLGS_TX_BNDL_PAD_EN;
0351
0352
0353
0354
0355
0356
0357 connect.max_rxmsg_sz = WMI_MAX_TX_DATA_FRAME_LENGTH;
0358
0359
0360
0361
0362
0363
0364 connect.ep_cb.rx_alloc_thresh = ATH6KL_BUFFER_SIZE;
0365 connect.ep_cb.rx_allocthresh = ath6kl_alloc_amsdu_rxbuf;
0366
0367
0368
0369
0370
0371 connect.conn_flags |= HTC_CONN_FLGS_REDUCE_CRED_DRIB;
0372 connect.conn_flags &= ~HTC_CONN_FLGS_THRESH_MASK;
0373 connect.conn_flags |= HTC_CONN_FLGS_THRESH_LVL_HALF;
0374
0375 connect.svc_id = WMI_DATA_BE_SVC;
0376
0377 if (ath6kl_connectservice(ar, &connect, "WMI DATA BE"))
0378 return -EIO;
0379
0380
0381 connect.svc_id = WMI_DATA_BK_SVC;
0382 if (ath6kl_connectservice(ar, &connect, "WMI DATA BK"))
0383 return -EIO;
0384
0385
0386 connect.svc_id = WMI_DATA_VI_SVC;
0387 if (ath6kl_connectservice(ar, &connect, "WMI DATA VI"))
0388 return -EIO;
0389
0390
0391
0392
0393
0394
0395
0396
0397 connect.svc_id = WMI_DATA_VO_SVC;
0398 if (ath6kl_connectservice(ar, &connect, "WMI DATA VO"))
0399 return -EIO;
0400
0401 return 0;
0402 }
0403
0404 void ath6kl_init_control_info(struct ath6kl_vif *vif)
0405 {
0406 ath6kl_init_profile_info(vif);
0407 vif->def_txkey_index = 0;
0408 memset(vif->wep_key_list, 0, sizeof(vif->wep_key_list));
0409 vif->ch_hint = 0;
0410 }
0411
0412
0413
0414
0415
0416 static int ath6kl_set_htc_params(struct ath6kl *ar, u32 mbox_isr_yield_val,
0417 u8 htc_ctrl_buf)
0418 {
0419 int status;
0420 u32 blk_size;
0421
0422 blk_size = ar->mbox_info.block_size;
0423
0424 if (htc_ctrl_buf)
0425 blk_size |= ((u32)htc_ctrl_buf) << 16;
0426
0427
0428 status = ath6kl_bmi_write_hi32(ar, hi_mbox_io_block_sz, blk_size);
0429 if (status) {
0430 ath6kl_err("bmi_write_memory for IO block size failed\n");
0431 goto out;
0432 }
0433
0434 ath6kl_dbg(ATH6KL_DBG_TRC, "block size set: %d (target addr:0x%X)\n",
0435 blk_size,
0436 ath6kl_get_hi_item_addr(ar, HI_ITEM(hi_mbox_io_block_sz)));
0437
0438 if (mbox_isr_yield_val) {
0439
0440 status = ath6kl_bmi_write_hi32(ar, hi_mbox_isr_yield_limit,
0441 mbox_isr_yield_val);
0442 if (status) {
0443 ath6kl_err("bmi_write_memory for yield limit failed\n");
0444 goto out;
0445 }
0446 }
0447
0448 out:
0449 return status;
0450 }
0451
0452 static int ath6kl_target_config_wlan_params(struct ath6kl *ar, int idx)
0453 {
0454 int ret;
0455
0456
0457
0458
0459
0460
0461 ret = ath6kl_wmi_set_rx_frame_format_cmd(ar->wmi, idx,
0462 ar->rx_meta_ver, 0, 0);
0463 if (ret) {
0464 ath6kl_err("unable to set the rx frame format: %d\n", ret);
0465 return ret;
0466 }
0467
0468 if (ar->conf_flags & ATH6KL_CONF_IGNORE_PS_FAIL_EVT_IN_SCAN) {
0469 ret = ath6kl_wmi_pmparams_cmd(ar->wmi, idx, 0, 1, 0, 0, 1,
0470 IGNORE_PS_FAIL_DURING_SCAN);
0471 if (ret) {
0472 ath6kl_err("unable to set power save fail event policy: %d\n",
0473 ret);
0474 return ret;
0475 }
0476 }
0477
0478 if (!(ar->conf_flags & ATH6KL_CONF_IGNORE_ERP_BARKER)) {
0479 ret = ath6kl_wmi_set_lpreamble_cmd(ar->wmi, idx, 0,
0480 WMI_FOLLOW_BARKER_IN_ERP);
0481 if (ret) {
0482 ath6kl_err("unable to set barker preamble policy: %d\n",
0483 ret);
0484 return ret;
0485 }
0486 }
0487
0488 ret = ath6kl_wmi_set_keepalive_cmd(ar->wmi, idx,
0489 WLAN_CONFIG_KEEP_ALIVE_INTERVAL);
0490 if (ret) {
0491 ath6kl_err("unable to set keep alive interval: %d\n", ret);
0492 return ret;
0493 }
0494
0495 ret = ath6kl_wmi_disctimeout_cmd(ar->wmi, idx,
0496 WLAN_CONFIG_DISCONNECT_TIMEOUT);
0497 if (ret) {
0498 ath6kl_err("unable to set disconnect timeout: %d\n", ret);
0499 return ret;
0500 }
0501
0502 if (!(ar->conf_flags & ATH6KL_CONF_ENABLE_TX_BURST)) {
0503 ret = ath6kl_wmi_set_wmm_txop(ar->wmi, idx, WMI_TXOP_DISABLED);
0504 if (ret) {
0505 ath6kl_err("unable to set txop bursting: %d\n", ret);
0506 return ret;
0507 }
0508 }
0509
0510 if (ar->p2p && (ar->vif_max == 1 || idx)) {
0511 ret = ath6kl_wmi_info_req_cmd(ar->wmi, idx,
0512 P2P_FLAG_CAPABILITIES_REQ |
0513 P2P_FLAG_MACADDR_REQ |
0514 P2P_FLAG_HMODEL_REQ);
0515 if (ret) {
0516 ath6kl_dbg(ATH6KL_DBG_TRC,
0517 "failed to request P2P capabilities (%d) - assuming P2P not supported\n",
0518 ret);
0519 ar->p2p = false;
0520 }
0521 }
0522
0523 if (ar->p2p && (ar->vif_max == 1 || idx)) {
0524
0525 ret = ath6kl_wmi_probe_report_req_cmd(ar->wmi, idx, true);
0526 if (ret) {
0527 ath6kl_dbg(ATH6KL_DBG_TRC,
0528 "failed to enable Probe Request reporting (%d)\n",
0529 ret);
0530 }
0531 }
0532
0533 return ret;
0534 }
0535
0536 int ath6kl_configure_target(struct ath6kl *ar)
0537 {
0538 u32 param, ram_reserved_size;
0539 u8 fw_iftype, fw_mode = 0, fw_submode = 0;
0540 int i, status;
0541
0542 param = !!(ar->conf_flags & ATH6KL_CONF_UART_DEBUG);
0543 if (ath6kl_bmi_write_hi32(ar, hi_serial_enable, param)) {
0544 ath6kl_err("bmi_write_memory for uart debug failed\n");
0545 return -EIO;
0546 }
0547
0548
0549
0550
0551
0552
0553
0554
0555
0556 fw_iftype = HI_OPTION_FW_MODE_BSS_STA;
0557
0558 for (i = 0; i < ar->vif_max; i++)
0559 fw_mode |= fw_iftype << (i * HI_OPTION_FW_MODE_BITS);
0560
0561
0562
0563
0564
0565
0566
0567
0568
0569
0570 if (test_bit(ATH6KL_FW_CAPABILITY_STA_P2PDEV_DUPLEX,
0571 ar->fw_capabilities)) {
0572 for (i = 0; i < ar->vif_max; i++)
0573 fw_submode |= HI_OPTION_FW_SUBMODE_P2PDEV <<
0574 (i * HI_OPTION_FW_SUBMODE_BITS);
0575 } else {
0576 for (i = 0; i < ar->max_norm_iface; i++)
0577 fw_submode |= HI_OPTION_FW_SUBMODE_NONE <<
0578 (i * HI_OPTION_FW_SUBMODE_BITS);
0579
0580 for (i = ar->max_norm_iface; i < ar->vif_max; i++)
0581 fw_submode |= HI_OPTION_FW_SUBMODE_P2PDEV <<
0582 (i * HI_OPTION_FW_SUBMODE_BITS);
0583
0584 if (ar->p2p && ar->vif_max == 1)
0585 fw_submode = HI_OPTION_FW_SUBMODE_P2PDEV;
0586 }
0587
0588 if (ath6kl_bmi_write_hi32(ar, hi_app_host_interest,
0589 HTC_PROTOCOL_VERSION) != 0) {
0590 ath6kl_err("bmi_write_memory for htc version failed\n");
0591 return -EIO;
0592 }
0593
0594
0595 param = 0;
0596
0597 if (ath6kl_bmi_read_hi32(ar, hi_option_flag, ¶m) != 0) {
0598 ath6kl_err("bmi_read_memory for setting fwmode failed\n");
0599 return -EIO;
0600 }
0601
0602 param |= (ar->vif_max << HI_OPTION_NUM_DEV_SHIFT);
0603 param |= fw_mode << HI_OPTION_FW_MODE_SHIFT;
0604 param |= fw_submode << HI_OPTION_FW_SUBMODE_SHIFT;
0605
0606 param |= (0 << HI_OPTION_MAC_ADDR_METHOD_SHIFT);
0607 param |= (0 << HI_OPTION_FW_BRIDGE_SHIFT);
0608
0609 if (ath6kl_bmi_write_hi32(ar, hi_option_flag, param) != 0) {
0610 ath6kl_err("bmi_write_memory for setting fwmode failed\n");
0611 return -EIO;
0612 }
0613
0614 ath6kl_dbg(ATH6KL_DBG_TRC, "firmware mode set\n");
0615
0616
0617
0618
0619
0620
0621
0622
0623
0624
0625 if ((ar->target_type == TARGET_TYPE_AR6003) ||
0626 (ar->version.target_ver == AR6004_HW_1_3_VERSION) ||
0627 (ar->version.target_ver == AR6004_HW_3_0_VERSION)) {
0628 param = ar->hw.board_ext_data_addr;
0629 ram_reserved_size = ar->hw.reserved_ram_size;
0630
0631 if (ath6kl_bmi_write_hi32(ar, hi_board_ext_data, param) != 0) {
0632 ath6kl_err("bmi_write_memory for hi_board_ext_data failed\n");
0633 return -EIO;
0634 }
0635
0636 if (ath6kl_bmi_write_hi32(ar, hi_end_ram_reserve_sz,
0637 ram_reserved_size) != 0) {
0638 ath6kl_err("bmi_write_memory for hi_end_ram_reserve_sz failed\n");
0639 return -EIO;
0640 }
0641 }
0642
0643
0644 if (ath6kl_set_htc_params(ar, MBOX_YIELD_LIMIT, 0))
0645
0646 return -EIO;
0647
0648
0649 status = ath6kl_bmi_write_hi32(ar, hi_dbg_uart_txpin,
0650 ar->hw.uarttx_pin);
0651 if (status)
0652 return status;
0653
0654
0655 if (ar->conf_flags & ATH6KL_CONF_UART_DEBUG) {
0656 status = ath6kl_bmi_write_hi32(ar, hi_desired_baud_rate,
0657 ar->hw.uarttx_rate);
0658 if (status)
0659 return status;
0660 }
0661
0662
0663 if (ar->hw.refclk_hz != 0) {
0664 status = ath6kl_bmi_write_hi32(ar, hi_refclk_hz,
0665 ar->hw.refclk_hz);
0666 if (status)
0667 return status;
0668 }
0669
0670 return 0;
0671 }
0672
0673
0674 static int ath6kl_get_fw(struct ath6kl *ar, const char *filename,
0675 u8 **fw, size_t *fw_len)
0676 {
0677 const struct firmware *fw_entry;
0678 int ret;
0679
0680 ret = request_firmware(&fw_entry, filename, ar->dev);
0681 if (ret)
0682 return ret;
0683
0684 *fw_len = fw_entry->size;
0685 *fw = kmemdup(fw_entry->data, fw_entry->size, GFP_KERNEL);
0686
0687 if (*fw == NULL)
0688 ret = -ENOMEM;
0689
0690 release_firmware(fw_entry);
0691
0692 return ret;
0693 }
0694
0695 #ifdef CONFIG_OF
0696
0697
0698
0699
0700
0701
0702 static bool check_device_tree(struct ath6kl *ar)
0703 {
0704 static const char *board_id_prop = "atheros,board-id";
0705 struct device_node *node;
0706 char board_filename[64];
0707 const char *board_id;
0708 int ret;
0709
0710 for_each_compatible_node(node, NULL, "atheros,ath6kl") {
0711 board_id = of_get_property(node, board_id_prop, NULL);
0712 if (board_id == NULL) {
0713 ath6kl_warn("No \"%s\" property on %pOFn node.\n",
0714 board_id_prop, node);
0715 continue;
0716 }
0717 snprintf(board_filename, sizeof(board_filename),
0718 "%s/bdata.%s.bin", ar->hw.fw.dir, board_id);
0719
0720 ret = ath6kl_get_fw(ar, board_filename, &ar->fw_board,
0721 &ar->fw_board_len);
0722 if (ret) {
0723 ath6kl_err("Failed to get DT board file %s: %d\n",
0724 board_filename, ret);
0725 continue;
0726 }
0727 of_node_put(node);
0728 return true;
0729 }
0730 return false;
0731 }
0732 #else
0733 static bool check_device_tree(struct ath6kl *ar)
0734 {
0735 return false;
0736 }
0737 #endif
0738
0739 static int ath6kl_fetch_board_file(struct ath6kl *ar)
0740 {
0741 const char *filename;
0742 int ret;
0743
0744 if (ar->fw_board != NULL)
0745 return 0;
0746
0747 if (WARN_ON(ar->hw.fw_board == NULL))
0748 return -EINVAL;
0749
0750 filename = ar->hw.fw_board;
0751
0752 ret = ath6kl_get_fw(ar, filename, &ar->fw_board,
0753 &ar->fw_board_len);
0754 if (ret == 0) {
0755
0756 return 0;
0757 }
0758
0759 if (check_device_tree(ar)) {
0760
0761 return 0;
0762 }
0763
0764
0765 ath6kl_warn("Failed to get board file %s (%d), trying to find default board file.\n",
0766 filename, ret);
0767
0768 filename = ar->hw.fw_default_board;
0769
0770 ret = ath6kl_get_fw(ar, filename, &ar->fw_board,
0771 &ar->fw_board_len);
0772 if (ret) {
0773 ath6kl_err("Failed to get default board file %s: %d\n",
0774 filename, ret);
0775 return ret;
0776 }
0777
0778 ath6kl_warn("WARNING! No proper board file was not found, instead using a default board file.\n");
0779 ath6kl_warn("Most likely your hardware won't work as specified. Install correct board file!\n");
0780
0781 return 0;
0782 }
0783
0784 static int ath6kl_fetch_otp_file(struct ath6kl *ar)
0785 {
0786 char filename[100];
0787 int ret;
0788
0789 if (ar->fw_otp != NULL)
0790 return 0;
0791
0792 if (ar->hw.fw.otp == NULL) {
0793 ath6kl_dbg(ATH6KL_DBG_BOOT,
0794 "no OTP file configured for this hw\n");
0795 return 0;
0796 }
0797
0798 snprintf(filename, sizeof(filename), "%s/%s",
0799 ar->hw.fw.dir, ar->hw.fw.otp);
0800
0801 ret = ath6kl_get_fw(ar, filename, &ar->fw_otp,
0802 &ar->fw_otp_len);
0803 if (ret) {
0804 ath6kl_err("Failed to get OTP file %s: %d\n",
0805 filename, ret);
0806 return ret;
0807 }
0808
0809 return 0;
0810 }
0811
0812 static int ath6kl_fetch_testmode_file(struct ath6kl *ar)
0813 {
0814 char filename[100];
0815 int ret;
0816
0817 if (ar->testmode == 0)
0818 return 0;
0819
0820 ath6kl_dbg(ATH6KL_DBG_BOOT, "testmode %d\n", ar->testmode);
0821
0822 if (ar->testmode == 2) {
0823 if (ar->hw.fw.utf == NULL) {
0824 ath6kl_warn("testmode 2 not supported\n");
0825 return -EOPNOTSUPP;
0826 }
0827
0828 snprintf(filename, sizeof(filename), "%s/%s",
0829 ar->hw.fw.dir, ar->hw.fw.utf);
0830 } else {
0831 if (ar->hw.fw.tcmd == NULL) {
0832 ath6kl_warn("testmode 1 not supported\n");
0833 return -EOPNOTSUPP;
0834 }
0835
0836 snprintf(filename, sizeof(filename), "%s/%s",
0837 ar->hw.fw.dir, ar->hw.fw.tcmd);
0838 }
0839
0840 set_bit(TESTMODE, &ar->flag);
0841
0842 ret = ath6kl_get_fw(ar, filename, &ar->fw, &ar->fw_len);
0843 if (ret) {
0844 ath6kl_err("Failed to get testmode %d firmware file %s: %d\n",
0845 ar->testmode, filename, ret);
0846 return ret;
0847 }
0848
0849 return 0;
0850 }
0851
0852 static int ath6kl_fetch_fw_file(struct ath6kl *ar)
0853 {
0854 char filename[100];
0855 int ret;
0856
0857 if (ar->fw != NULL)
0858 return 0;
0859
0860
0861 if (WARN_ON(ar->hw.fw.fw == NULL))
0862 return -EINVAL;
0863
0864 snprintf(filename, sizeof(filename), "%s/%s",
0865 ar->hw.fw.dir, ar->hw.fw.fw);
0866
0867 ret = ath6kl_get_fw(ar, filename, &ar->fw, &ar->fw_len);
0868 if (ret) {
0869 ath6kl_err("Failed to get firmware file %s: %d\n",
0870 filename, ret);
0871 return ret;
0872 }
0873
0874 return 0;
0875 }
0876
0877 static int ath6kl_fetch_patch_file(struct ath6kl *ar)
0878 {
0879 char filename[100];
0880 int ret;
0881
0882 if (ar->fw_patch != NULL)
0883 return 0;
0884
0885 if (ar->hw.fw.patch == NULL)
0886 return 0;
0887
0888 snprintf(filename, sizeof(filename), "%s/%s",
0889 ar->hw.fw.dir, ar->hw.fw.patch);
0890
0891 ret = ath6kl_get_fw(ar, filename, &ar->fw_patch,
0892 &ar->fw_patch_len);
0893 if (ret) {
0894 ath6kl_err("Failed to get patch file %s: %d\n",
0895 filename, ret);
0896 return ret;
0897 }
0898
0899 return 0;
0900 }
0901
0902 static int ath6kl_fetch_testscript_file(struct ath6kl *ar)
0903 {
0904 char filename[100];
0905 int ret;
0906
0907 if (ar->testmode != 2)
0908 return 0;
0909
0910 if (ar->fw_testscript != NULL)
0911 return 0;
0912
0913 if (ar->hw.fw.testscript == NULL)
0914 return 0;
0915
0916 snprintf(filename, sizeof(filename), "%s/%s",
0917 ar->hw.fw.dir, ar->hw.fw.testscript);
0918
0919 ret = ath6kl_get_fw(ar, filename, &ar->fw_testscript,
0920 &ar->fw_testscript_len);
0921 if (ret) {
0922 ath6kl_err("Failed to get testscript file %s: %d\n",
0923 filename, ret);
0924 return ret;
0925 }
0926
0927 return 0;
0928 }
0929
0930 static int ath6kl_fetch_fw_api1(struct ath6kl *ar)
0931 {
0932 int ret;
0933
0934 ret = ath6kl_fetch_otp_file(ar);
0935 if (ret)
0936 return ret;
0937
0938 ret = ath6kl_fetch_fw_file(ar);
0939 if (ret)
0940 return ret;
0941
0942 ret = ath6kl_fetch_patch_file(ar);
0943 if (ret)
0944 return ret;
0945
0946 ret = ath6kl_fetch_testscript_file(ar);
0947 if (ret)
0948 return ret;
0949
0950 return 0;
0951 }
0952
0953 static int ath6kl_fetch_fw_apin(struct ath6kl *ar, const char *name)
0954 {
0955 size_t magic_len, len, ie_len;
0956 const struct firmware *fw;
0957 struct ath6kl_fw_ie *hdr;
0958 char filename[100];
0959 const u8 *data;
0960 int ret, ie_id, i, index, bit;
0961 __le32 *val;
0962
0963 snprintf(filename, sizeof(filename), "%s/%s", ar->hw.fw.dir, name);
0964
0965 ret = request_firmware(&fw, filename, ar->dev);
0966 if (ret) {
0967 ath6kl_err("Failed request firmware, rv: %d\n", ret);
0968 return ret;
0969 }
0970
0971 data = fw->data;
0972 len = fw->size;
0973
0974
0975 magic_len = strlen(ATH6KL_FIRMWARE_MAGIC) + 1;
0976
0977 if (len < magic_len) {
0978 ath6kl_err("Magic length is invalid, len: %zd magic_len: %zd\n",
0979 len, magic_len);
0980 ret = -EINVAL;
0981 goto out;
0982 }
0983
0984 if (memcmp(data, ATH6KL_FIRMWARE_MAGIC, magic_len) != 0) {
0985 ath6kl_err("Magic is invalid, magic_len: %zd\n",
0986 magic_len);
0987 ret = -EINVAL;
0988 goto out;
0989 }
0990
0991 len -= magic_len;
0992 data += magic_len;
0993
0994
0995 while (len > sizeof(struct ath6kl_fw_ie)) {
0996
0997 hdr = (struct ath6kl_fw_ie *) data;
0998
0999 ie_id = le32_to_cpup(&hdr->id);
1000 ie_len = le32_to_cpup(&hdr->len);
1001
1002 len -= sizeof(*hdr);
1003 data += sizeof(*hdr);
1004
1005 ath6kl_dbg(ATH6KL_DBG_BOOT, "ie-id: %d len: %zd (0x%zx)\n",
1006 ie_id, ie_len, ie_len);
1007
1008 if (len < ie_len) {
1009 ath6kl_err("IE len is invalid, len: %zd ie_len: %zd ie-id: %d\n",
1010 len, ie_len, ie_id);
1011 ret = -EINVAL;
1012 goto out;
1013 }
1014
1015 switch (ie_id) {
1016 case ATH6KL_FW_IE_FW_VERSION:
1017 strlcpy(ar->wiphy->fw_version, data,
1018 min(sizeof(ar->wiphy->fw_version), ie_len+1));
1019
1020 ath6kl_dbg(ATH6KL_DBG_BOOT,
1021 "found fw version %s\n",
1022 ar->wiphy->fw_version);
1023 break;
1024 case ATH6KL_FW_IE_OTP_IMAGE:
1025 ath6kl_dbg(ATH6KL_DBG_BOOT, "found otp image ie (%zd B)\n",
1026 ie_len);
1027
1028 ar->fw_otp = kmemdup(data, ie_len, GFP_KERNEL);
1029
1030 if (ar->fw_otp == NULL) {
1031 ath6kl_err("fw_otp cannot be allocated\n");
1032 ret = -ENOMEM;
1033 goto out;
1034 }
1035
1036 ar->fw_otp_len = ie_len;
1037 break;
1038 case ATH6KL_FW_IE_FW_IMAGE:
1039 ath6kl_dbg(ATH6KL_DBG_BOOT, "found fw image ie (%zd B)\n",
1040 ie_len);
1041
1042
1043 if (ar->fw != NULL)
1044 break;
1045
1046 ar->fw = vmalloc(ie_len);
1047
1048 if (ar->fw == NULL) {
1049 ath6kl_err("fw storage cannot be allocated, len: %zd\n", ie_len);
1050 ret = -ENOMEM;
1051 goto out;
1052 }
1053
1054 memcpy(ar->fw, data, ie_len);
1055 ar->fw_len = ie_len;
1056 break;
1057 case ATH6KL_FW_IE_PATCH_IMAGE:
1058 ath6kl_dbg(ATH6KL_DBG_BOOT, "found patch image ie (%zd B)\n",
1059 ie_len);
1060
1061 ar->fw_patch = kmemdup(data, ie_len, GFP_KERNEL);
1062
1063 if (ar->fw_patch == NULL) {
1064 ath6kl_err("fw_patch storage cannot be allocated, len: %zd\n", ie_len);
1065 ret = -ENOMEM;
1066 goto out;
1067 }
1068
1069 ar->fw_patch_len = ie_len;
1070 break;
1071 case ATH6KL_FW_IE_RESERVED_RAM_SIZE:
1072 val = (__le32 *) data;
1073 ar->hw.reserved_ram_size = le32_to_cpup(val);
1074
1075 ath6kl_dbg(ATH6KL_DBG_BOOT,
1076 "found reserved ram size ie %d\n",
1077 ar->hw.reserved_ram_size);
1078 break;
1079 case ATH6KL_FW_IE_CAPABILITIES:
1080 ath6kl_dbg(ATH6KL_DBG_BOOT,
1081 "found firmware capabilities ie (%zd B)\n",
1082 ie_len);
1083
1084 for (i = 0; i < ATH6KL_FW_CAPABILITY_MAX; i++) {
1085 index = i / 8;
1086 bit = i % 8;
1087
1088 if (index == ie_len)
1089 break;
1090
1091 if (data[index] & (1 << bit))
1092 __set_bit(i, ar->fw_capabilities);
1093 }
1094
1095 ath6kl_dbg_dump(ATH6KL_DBG_BOOT, "capabilities", "",
1096 ar->fw_capabilities,
1097 sizeof(ar->fw_capabilities));
1098 break;
1099 case ATH6KL_FW_IE_PATCH_ADDR:
1100 if (ie_len != sizeof(*val))
1101 break;
1102
1103 val = (__le32 *) data;
1104 ar->hw.dataset_patch_addr = le32_to_cpup(val);
1105
1106 ath6kl_dbg(ATH6KL_DBG_BOOT,
1107 "found patch address ie 0x%x\n",
1108 ar->hw.dataset_patch_addr);
1109 break;
1110 case ATH6KL_FW_IE_BOARD_ADDR:
1111 if (ie_len != sizeof(*val))
1112 break;
1113
1114 val = (__le32 *) data;
1115 ar->hw.board_addr = le32_to_cpup(val);
1116
1117 ath6kl_dbg(ATH6KL_DBG_BOOT,
1118 "found board address ie 0x%x\n",
1119 ar->hw.board_addr);
1120 break;
1121 case ATH6KL_FW_IE_VIF_MAX:
1122 if (ie_len != sizeof(*val))
1123 break;
1124
1125 val = (__le32 *) data;
1126 ar->vif_max = min_t(unsigned int, le32_to_cpup(val),
1127 ATH6KL_VIF_MAX);
1128
1129 if (ar->vif_max > 1 && !ar->p2p)
1130 ar->max_norm_iface = 2;
1131
1132 ath6kl_dbg(ATH6KL_DBG_BOOT,
1133 "found vif max ie %d\n", ar->vif_max);
1134 break;
1135 default:
1136 ath6kl_dbg(ATH6KL_DBG_BOOT, "Unknown fw ie: %u\n",
1137 le32_to_cpup(&hdr->id));
1138 break;
1139 }
1140
1141 len -= ie_len;
1142 data += ie_len;
1143 }
1144
1145 ret = 0;
1146 out:
1147 release_firmware(fw);
1148
1149 return ret;
1150 }
1151
1152 int ath6kl_init_fetch_firmwares(struct ath6kl *ar)
1153 {
1154 int ret;
1155
1156 ret = ath6kl_fetch_board_file(ar);
1157 if (ret)
1158 return ret;
1159
1160 ret = ath6kl_fetch_testmode_file(ar);
1161 if (ret)
1162 return ret;
1163
1164 ret = ath6kl_fetch_fw_apin(ar, ATH6KL_FW_API5_FILE);
1165 if (ret == 0) {
1166 ar->fw_api = 5;
1167 goto out;
1168 }
1169
1170 ret = ath6kl_fetch_fw_apin(ar, ATH6KL_FW_API4_FILE);
1171 if (ret == 0) {
1172 ar->fw_api = 4;
1173 goto out;
1174 }
1175
1176 ret = ath6kl_fetch_fw_apin(ar, ATH6KL_FW_API3_FILE);
1177 if (ret == 0) {
1178 ar->fw_api = 3;
1179 goto out;
1180 }
1181
1182 ret = ath6kl_fetch_fw_apin(ar, ATH6KL_FW_API2_FILE);
1183 if (ret == 0) {
1184 ar->fw_api = 2;
1185 goto out;
1186 }
1187
1188 ret = ath6kl_fetch_fw_api1(ar);
1189 if (ret)
1190 return ret;
1191
1192 ar->fw_api = 1;
1193
1194 out:
1195 ath6kl_dbg(ATH6KL_DBG_BOOT, "using fw api %d\n", ar->fw_api);
1196
1197 return 0;
1198 }
1199
1200 static int ath6kl_upload_board_file(struct ath6kl *ar)
1201 {
1202 u32 board_address, board_ext_address, param;
1203 u32 board_data_size, board_ext_data_size;
1204 int ret;
1205
1206 if (WARN_ON(ar->fw_board == NULL))
1207 return -ENOENT;
1208
1209
1210
1211
1212
1213
1214 if (ar->hw.board_addr != 0) {
1215 board_address = ar->hw.board_addr;
1216 ath6kl_bmi_write_hi32(ar, hi_board_data,
1217 board_address);
1218 } else {
1219 ret = ath6kl_bmi_read_hi32(ar, hi_board_data, &board_address);
1220 if (ret) {
1221 ath6kl_err("Failed to get board file target address.\n");
1222 return ret;
1223 }
1224 }
1225
1226
1227 ret = ath6kl_bmi_read_hi32(ar, hi_board_ext_data, &board_ext_address);
1228 if (ret) {
1229 ath6kl_err("Failed to get extended board file target address.\n");
1230 return ret;
1231 }
1232
1233 if (ar->target_type == TARGET_TYPE_AR6003 &&
1234 board_ext_address == 0) {
1235 ath6kl_err("Failed to get board file target address.\n");
1236 return -EINVAL;
1237 }
1238
1239 switch (ar->target_type) {
1240 case TARGET_TYPE_AR6003:
1241 board_data_size = AR6003_BOARD_DATA_SZ;
1242 board_ext_data_size = AR6003_BOARD_EXT_DATA_SZ;
1243 if (ar->fw_board_len > (board_data_size + board_ext_data_size))
1244 board_ext_data_size = AR6003_BOARD_EXT_DATA_SZ_V2;
1245 break;
1246 case TARGET_TYPE_AR6004:
1247 board_data_size = AR6004_BOARD_DATA_SZ;
1248 board_ext_data_size = AR6004_BOARD_EXT_DATA_SZ;
1249 break;
1250 default:
1251 WARN_ON(1);
1252 return -EINVAL;
1253 }
1254
1255 if (board_ext_address &&
1256 ar->fw_board_len == (board_data_size + board_ext_data_size)) {
1257
1258 ath6kl_dbg(ATH6KL_DBG_BOOT,
1259 "writing extended board data to 0x%x (%d B)\n",
1260 board_ext_address, board_ext_data_size);
1261
1262 ret = ath6kl_bmi_write(ar, board_ext_address,
1263 ar->fw_board + board_data_size,
1264 board_ext_data_size);
1265 if (ret) {
1266 ath6kl_err("Failed to write extended board data: %d\n",
1267 ret);
1268 return ret;
1269 }
1270
1271
1272 param = (board_ext_data_size << 16) | 1;
1273
1274 ath6kl_bmi_write_hi32(ar, hi_board_ext_data_config, param);
1275 }
1276
1277 if (ar->fw_board_len < board_data_size) {
1278 ath6kl_err("Too small board file: %zu\n", ar->fw_board_len);
1279 ret = -EINVAL;
1280 return ret;
1281 }
1282
1283 ath6kl_dbg(ATH6KL_DBG_BOOT, "writing board file to 0x%x (%d B)\n",
1284 board_address, board_data_size);
1285
1286 ret = ath6kl_bmi_write(ar, board_address, ar->fw_board,
1287 board_data_size);
1288
1289 if (ret) {
1290 ath6kl_err("Board file bmi write failed: %d\n", ret);
1291 return ret;
1292 }
1293
1294
1295 if ((ar->version.target_ver == AR6004_HW_1_3_VERSION) ||
1296 (ar->version.target_ver == AR6004_HW_3_0_VERSION))
1297 param = board_data_size;
1298 else
1299 param = 1;
1300
1301 ath6kl_bmi_write_hi32(ar, hi_board_data_initialized, param);
1302
1303 return ret;
1304 }
1305
1306 static int ath6kl_upload_otp(struct ath6kl *ar)
1307 {
1308 u32 address, param;
1309 bool from_hw = false;
1310 int ret;
1311
1312 if (ar->fw_otp == NULL)
1313 return 0;
1314
1315 address = ar->hw.app_load_addr;
1316
1317 ath6kl_dbg(ATH6KL_DBG_BOOT, "writing otp to 0x%x (%zd B)\n", address,
1318 ar->fw_otp_len);
1319
1320 ret = ath6kl_bmi_fast_download(ar, address, ar->fw_otp,
1321 ar->fw_otp_len);
1322 if (ret) {
1323 ath6kl_err("Failed to upload OTP file: %d\n", ret);
1324 return ret;
1325 }
1326
1327
1328 ret = ath6kl_bmi_read_hi32(ar, hi_app_start, &address);
1329
1330 if (ret) {
1331 ath6kl_err("Failed to read hi_app_start: %d\n", ret);
1332 return ret;
1333 }
1334
1335 if (ar->hw.app_start_override_addr == 0) {
1336 ar->hw.app_start_override_addr = address;
1337 from_hw = true;
1338 }
1339
1340 ath6kl_dbg(ATH6KL_DBG_BOOT, "app_start_override_addr%s 0x%x\n",
1341 from_hw ? " (from hw)" : "",
1342 ar->hw.app_start_override_addr);
1343
1344
1345 ath6kl_dbg(ATH6KL_DBG_BOOT, "executing OTP at 0x%x\n",
1346 ar->hw.app_start_override_addr);
1347 param = 0;
1348 ath6kl_bmi_execute(ar, ar->hw.app_start_override_addr, ¶m);
1349
1350 return ret;
1351 }
1352
1353 static int ath6kl_upload_firmware(struct ath6kl *ar)
1354 {
1355 u32 address;
1356 int ret;
1357
1358 if (WARN_ON(ar->fw == NULL))
1359 return 0;
1360
1361 address = ar->hw.app_load_addr;
1362
1363 ath6kl_dbg(ATH6KL_DBG_BOOT, "writing firmware to 0x%x (%zd B)\n",
1364 address, ar->fw_len);
1365
1366 ret = ath6kl_bmi_fast_download(ar, address, ar->fw, ar->fw_len);
1367
1368 if (ret) {
1369 ath6kl_err("Failed to write firmware: %d\n", ret);
1370 return ret;
1371 }
1372
1373
1374
1375
1376
1377 if (ar->target_type != TARGET_TYPE_AR6004) {
1378 address = ar->hw.app_start_override_addr;
1379 ath6kl_bmi_set_app_start(ar, address);
1380 }
1381 return ret;
1382 }
1383
1384 static int ath6kl_upload_patch(struct ath6kl *ar)
1385 {
1386 u32 address;
1387 int ret;
1388
1389 if (ar->fw_patch == NULL)
1390 return 0;
1391
1392 address = ar->hw.dataset_patch_addr;
1393
1394 ath6kl_dbg(ATH6KL_DBG_BOOT, "writing patch to 0x%x (%zd B)\n",
1395 address, ar->fw_patch_len);
1396
1397 ret = ath6kl_bmi_write(ar, address, ar->fw_patch, ar->fw_patch_len);
1398 if (ret) {
1399 ath6kl_err("Failed to write patch file: %d\n", ret);
1400 return ret;
1401 }
1402
1403 ath6kl_bmi_write_hi32(ar, hi_dset_list_head, address);
1404
1405 return 0;
1406 }
1407
1408 static int ath6kl_upload_testscript(struct ath6kl *ar)
1409 {
1410 u32 address;
1411 int ret;
1412
1413 if (ar->testmode != 2)
1414 return 0;
1415
1416 if (ar->fw_testscript == NULL)
1417 return 0;
1418
1419 address = ar->hw.testscript_addr;
1420
1421 ath6kl_dbg(ATH6KL_DBG_BOOT, "writing testscript to 0x%x (%zd B)\n",
1422 address, ar->fw_testscript_len);
1423
1424 ret = ath6kl_bmi_write(ar, address, ar->fw_testscript,
1425 ar->fw_testscript_len);
1426 if (ret) {
1427 ath6kl_err("Failed to write testscript file: %d\n", ret);
1428 return ret;
1429 }
1430
1431 ath6kl_bmi_write_hi32(ar, hi_ota_testscript, address);
1432
1433 if ((ar->version.target_ver != AR6004_HW_1_3_VERSION) &&
1434 (ar->version.target_ver != AR6004_HW_3_0_VERSION))
1435 ath6kl_bmi_write_hi32(ar, hi_end_ram_reserve_sz, 4096);
1436
1437 ath6kl_bmi_write_hi32(ar, hi_test_apps_related, 1);
1438
1439 return 0;
1440 }
1441
1442 static int ath6kl_init_upload(struct ath6kl *ar)
1443 {
1444 u32 param, options, sleep, address;
1445 int status = 0;
1446
1447 if (ar->target_type != TARGET_TYPE_AR6003 &&
1448 ar->target_type != TARGET_TYPE_AR6004)
1449 return -EINVAL;
1450
1451
1452 address = MBOX_BASE_ADDRESS + LOCAL_SCRATCH_ADDRESS;
1453 status = ath6kl_bmi_reg_read(ar, address, ¶m);
1454 if (status)
1455 return status;
1456
1457 options = param;
1458
1459 param |= ATH6KL_OPTION_SLEEP_DISABLE;
1460 status = ath6kl_bmi_reg_write(ar, address, param);
1461 if (status)
1462 return status;
1463
1464 address = RTC_BASE_ADDRESS + SYSTEM_SLEEP_ADDRESS;
1465 status = ath6kl_bmi_reg_read(ar, address, ¶m);
1466 if (status)
1467 return status;
1468
1469 sleep = param;
1470
1471 param |= SM(SYSTEM_SLEEP_DISABLE, 1);
1472 status = ath6kl_bmi_reg_write(ar, address, param);
1473 if (status)
1474 return status;
1475
1476 ath6kl_dbg(ATH6KL_DBG_TRC, "old options: %d, old sleep: %d\n",
1477 options, sleep);
1478
1479
1480
1481 if (ar->target_type != TARGET_TYPE_AR6004) {
1482 status = ath6kl_bmi_reg_write(ar, ATH6KL_ANALOG_PLL_REGISTER,
1483 0xF9104001);
1484
1485 if (status)
1486 return status;
1487
1488
1489 param = SM(CPU_CLOCK_STANDARD, 1);
1490
1491 address = RTC_BASE_ADDRESS + CPU_CLOCK_ADDRESS;
1492 status = ath6kl_bmi_reg_write(ar, address, param);
1493 if (status)
1494 return status;
1495 }
1496
1497 param = 0;
1498 address = RTC_BASE_ADDRESS + LPO_CAL_ADDRESS;
1499 param = SM(LPO_CAL_ENABLE, 1);
1500 status = ath6kl_bmi_reg_write(ar, address, param);
1501 if (status)
1502 return status;
1503
1504
1505 if (ar->hw.flags & ATH6KL_HW_SDIO_CRC_ERROR_WAR) {
1506 ath6kl_err("temporary war to avoid sdio crc error\n");
1507
1508 param = 0x28;
1509 address = GPIO_BASE_ADDRESS + GPIO_PIN9_ADDRESS;
1510 status = ath6kl_bmi_reg_write(ar, address, param);
1511 if (status)
1512 return status;
1513
1514 param = 0x20;
1515
1516 address = GPIO_BASE_ADDRESS + GPIO_PIN10_ADDRESS;
1517 status = ath6kl_bmi_reg_write(ar, address, param);
1518 if (status)
1519 return status;
1520
1521 address = GPIO_BASE_ADDRESS + GPIO_PIN11_ADDRESS;
1522 status = ath6kl_bmi_reg_write(ar, address, param);
1523 if (status)
1524 return status;
1525
1526 address = GPIO_BASE_ADDRESS + GPIO_PIN12_ADDRESS;
1527 status = ath6kl_bmi_reg_write(ar, address, param);
1528 if (status)
1529 return status;
1530
1531 address = GPIO_BASE_ADDRESS + GPIO_PIN13_ADDRESS;
1532 status = ath6kl_bmi_reg_write(ar, address, param);
1533 if (status)
1534 return status;
1535 }
1536
1537
1538 status = ath6kl_upload_board_file(ar);
1539 if (status)
1540 return status;
1541
1542
1543 status = ath6kl_upload_otp(ar);
1544 if (status)
1545 return status;
1546
1547
1548 status = ath6kl_upload_firmware(ar);
1549 if (status)
1550 return status;
1551
1552 status = ath6kl_upload_patch(ar);
1553 if (status)
1554 return status;
1555
1556
1557 status = ath6kl_upload_testscript(ar);
1558 if (status)
1559 return status;
1560
1561
1562 address = RTC_BASE_ADDRESS + SYSTEM_SLEEP_ADDRESS;
1563 status = ath6kl_bmi_reg_write(ar, address, sleep);
1564 if (status)
1565 return status;
1566
1567 address = MBOX_BASE_ADDRESS + LOCAL_SCRATCH_ADDRESS;
1568 param = options | 0x20;
1569 status = ath6kl_bmi_reg_write(ar, address, param);
1570 if (status)
1571 return status;
1572
1573 return status;
1574 }
1575
1576 int ath6kl_init_hw_params(struct ath6kl *ar)
1577 {
1578 const struct ath6kl_hw *hw;
1579 int i;
1580
1581 for (i = 0; i < ARRAY_SIZE(hw_list); i++) {
1582 hw = &hw_list[i];
1583
1584 if (hw->id == ar->version.target_ver)
1585 break;
1586 }
1587
1588 if (i == ARRAY_SIZE(hw_list)) {
1589 ath6kl_err("Unsupported hardware version: 0x%x\n",
1590 ar->version.target_ver);
1591 return -EINVAL;
1592 }
1593
1594 ar->hw = *hw;
1595
1596 ath6kl_dbg(ATH6KL_DBG_BOOT,
1597 "target_ver 0x%x target_type 0x%x dataset_patch 0x%x app_load_addr 0x%x\n",
1598 ar->version.target_ver, ar->target_type,
1599 ar->hw.dataset_patch_addr, ar->hw.app_load_addr);
1600 ath6kl_dbg(ATH6KL_DBG_BOOT,
1601 "app_start_override_addr 0x%x board_ext_data_addr 0x%x reserved_ram_size 0x%x",
1602 ar->hw.app_start_override_addr, ar->hw.board_ext_data_addr,
1603 ar->hw.reserved_ram_size);
1604 ath6kl_dbg(ATH6KL_DBG_BOOT,
1605 "refclk_hz %d uarttx_pin %d",
1606 ar->hw.refclk_hz, ar->hw.uarttx_pin);
1607
1608 return 0;
1609 }
1610
1611 static const char *ath6kl_init_get_hif_name(enum ath6kl_hif_type type)
1612 {
1613 switch (type) {
1614 case ATH6KL_HIF_TYPE_SDIO:
1615 return "sdio";
1616 case ATH6KL_HIF_TYPE_USB:
1617 return "usb";
1618 }
1619
1620 return NULL;
1621 }
1622
1623
1624 static const struct fw_capa_str_map {
1625 int id;
1626 const char *name;
1627 } fw_capa_map[] = {
1628 { ATH6KL_FW_CAPABILITY_HOST_P2P, "host-p2p" },
1629 { ATH6KL_FW_CAPABILITY_SCHED_SCAN, "sched-scan" },
1630 { ATH6KL_FW_CAPABILITY_STA_P2PDEV_DUPLEX, "sta-p2pdev-duplex" },
1631 { ATH6KL_FW_CAPABILITY_INACTIVITY_TIMEOUT, "inactivity-timeout" },
1632 { ATH6KL_FW_CAPABILITY_RSN_CAP_OVERRIDE, "rsn-cap-override" },
1633 { ATH6KL_FW_CAPABILITY_WOW_MULTICAST_FILTER, "wow-mc-filter" },
1634 { ATH6KL_FW_CAPABILITY_BMISS_ENHANCE, "bmiss-enhance" },
1635 { ATH6KL_FW_CAPABILITY_SCHED_SCAN_MATCH_LIST, "sscan-match-list" },
1636 { ATH6KL_FW_CAPABILITY_RSSI_SCAN_THOLD, "rssi-scan-thold" },
1637 { ATH6KL_FW_CAPABILITY_CUSTOM_MAC_ADDR, "custom-mac-addr" },
1638 { ATH6KL_FW_CAPABILITY_TX_ERR_NOTIFY, "tx-err-notify" },
1639 { ATH6KL_FW_CAPABILITY_REGDOMAIN, "regdomain" },
1640 { ATH6KL_FW_CAPABILITY_SCHED_SCAN_V2, "sched-scan-v2" },
1641 { ATH6KL_FW_CAPABILITY_HEART_BEAT_POLL, "hb-poll" },
1642 { ATH6KL_FW_CAPABILITY_64BIT_RATES, "64bit-rates" },
1643 { ATH6KL_FW_CAPABILITY_AP_INACTIVITY_MINS, "ap-inactivity-mins" },
1644 { ATH6KL_FW_CAPABILITY_MAP_LP_ENDPOINT, "map-lp-endpoint" },
1645 { ATH6KL_FW_CAPABILITY_RATETABLE_MCS15, "ratetable-mcs15" },
1646 { ATH6KL_FW_CAPABILITY_NO_IP_CHECKSUM, "no-ip-checksum" },
1647 };
1648
1649 static const char *ath6kl_init_get_fw_capa_name(unsigned int id)
1650 {
1651 int i;
1652
1653 for (i = 0; i < ARRAY_SIZE(fw_capa_map); i++) {
1654 if (fw_capa_map[i].id == id)
1655 return fw_capa_map[i].name;
1656 }
1657
1658 return "<unknown>";
1659 }
1660
1661 static void ath6kl_init_get_fwcaps(struct ath6kl *ar, char *buf, size_t buf_len)
1662 {
1663 u8 *data = (u8 *) ar->fw_capabilities;
1664 size_t trunc_len, len = 0;
1665 int i, index, bit;
1666 char *trunc = "...";
1667
1668 for (i = 0; i < ATH6KL_FW_CAPABILITY_MAX; i++) {
1669 index = i / 8;
1670 bit = i % 8;
1671
1672 if (index >= sizeof(ar->fw_capabilities) * 4)
1673 break;
1674
1675 if (buf_len - len < 4) {
1676 ath6kl_warn("firmware capability buffer too small!\n");
1677
1678
1679 trunc_len = strlen(trunc) + 1;
1680 strncpy(buf + buf_len - trunc_len, trunc, trunc_len);
1681
1682 return;
1683 }
1684
1685 if (data[index] & (1 << bit)) {
1686 len += scnprintf(buf + len, buf_len - len, "%s,",
1687 ath6kl_init_get_fw_capa_name(i));
1688 }
1689 }
1690
1691
1692 if (len > 0)
1693 len--;
1694
1695 buf[len] = '\0';
1696 }
1697
1698 static int ath6kl_init_hw_reset(struct ath6kl *ar)
1699 {
1700 ath6kl_dbg(ATH6KL_DBG_BOOT, "cold resetting the device");
1701
1702 return ath6kl_diag_write32(ar, RESET_CONTROL_ADDRESS,
1703 cpu_to_le32(RESET_CONTROL_COLD_RST));
1704 }
1705
1706 static int __ath6kl_init_hw_start(struct ath6kl *ar)
1707 {
1708 long timeleft;
1709 int ret, i;
1710 char buf[200];
1711
1712 ath6kl_dbg(ATH6KL_DBG_BOOT, "hw start\n");
1713
1714 ret = ath6kl_hif_power_on(ar);
1715 if (ret)
1716 return ret;
1717
1718 ret = ath6kl_configure_target(ar);
1719 if (ret)
1720 goto err_power_off;
1721
1722 ret = ath6kl_init_upload(ar);
1723 if (ret)
1724 goto err_power_off;
1725
1726
1727 ret = ath6kl_bmi_done(ar);
1728 if (ret)
1729 goto err_power_off;
1730
1731
1732
1733
1734
1735
1736 ret = ath6kl_htc_wait_target(ar->htc_target);
1737
1738 if (ret == -ETIMEDOUT) {
1739
1740
1741
1742
1743
1744
1745 ath6kl_warn("htc wait target timed out, resetting device\n");
1746 ath6kl_init_hw_reset(ar);
1747 goto err_power_off;
1748 } else if (ret) {
1749 ath6kl_err("htc wait target failed: %d\n", ret);
1750 goto err_power_off;
1751 }
1752
1753 ret = ath6kl_init_service_ep(ar);
1754 if (ret) {
1755 ath6kl_err("Endpoint service initialization failed: %d\n", ret);
1756 goto err_cleanup_scatter;
1757 }
1758
1759
1760 ath6kl_htc_credit_setup(ar->htc_target, &ar->credit_state_info);
1761
1762
1763 ret = ath6kl_htc_start(ar->htc_target);
1764 if (ret) {
1765
1766 ath6kl_cookie_cleanup(ar);
1767 goto err_cleanup_scatter;
1768 }
1769
1770
1771 timeleft = wait_event_interruptible_timeout(ar->event_wq,
1772 test_bit(WMI_READY,
1773 &ar->flag),
1774 WMI_TIMEOUT);
1775 if (timeleft <= 0) {
1776 clear_bit(WMI_READY, &ar->flag);
1777 ath6kl_err("wmi is not ready or wait was interrupted: %ld\n",
1778 timeleft);
1779 ret = -EIO;
1780 goto err_htc_stop;
1781 }
1782
1783 ath6kl_dbg(ATH6KL_DBG_BOOT, "firmware booted\n");
1784
1785 if (test_and_clear_bit(FIRST_BOOT, &ar->flag)) {
1786 ath6kl_info("%s %s fw %s api %d%s\n",
1787 ar->hw.name,
1788 ath6kl_init_get_hif_name(ar->hif_type),
1789 ar->wiphy->fw_version,
1790 ar->fw_api,
1791 test_bit(TESTMODE, &ar->flag) ? " testmode" : "");
1792 ath6kl_init_get_fwcaps(ar, buf, sizeof(buf));
1793 ath6kl_info("firmware supports: %s\n", buf);
1794 }
1795
1796 if (ar->version.abi_ver != ATH6KL_ABI_VERSION) {
1797 ath6kl_err("abi version mismatch: host(0x%x), target(0x%x)\n",
1798 ATH6KL_ABI_VERSION, ar->version.abi_ver);
1799 ret = -EIO;
1800 goto err_htc_stop;
1801 }
1802
1803 ath6kl_dbg(ATH6KL_DBG_TRC, "%s: wmi is ready\n", __func__);
1804
1805
1806
1807 if ((ath6kl_set_host_app_area(ar)) != 0)
1808 ath6kl_err("unable to set the host app area\n");
1809
1810 for (i = 0; i < ar->vif_max; i++) {
1811 ret = ath6kl_target_config_wlan_params(ar, i);
1812 if (ret)
1813 goto err_htc_stop;
1814 }
1815
1816 return 0;
1817
1818 err_htc_stop:
1819 ath6kl_htc_stop(ar->htc_target);
1820 err_cleanup_scatter:
1821 ath6kl_hif_cleanup_scatter(ar);
1822 err_power_off:
1823 ath6kl_hif_power_off(ar);
1824
1825 return ret;
1826 }
1827
1828 int ath6kl_init_hw_start(struct ath6kl *ar)
1829 {
1830 int err;
1831
1832 err = __ath6kl_init_hw_start(ar);
1833 if (err)
1834 return err;
1835 ar->state = ATH6KL_STATE_ON;
1836 return 0;
1837 }
1838
1839 static int __ath6kl_init_hw_stop(struct ath6kl *ar)
1840 {
1841 int ret;
1842
1843 ath6kl_dbg(ATH6KL_DBG_BOOT, "hw stop\n");
1844
1845 ath6kl_htc_stop(ar->htc_target);
1846
1847 ath6kl_hif_stop(ar);
1848
1849 ath6kl_bmi_reset(ar);
1850
1851 ret = ath6kl_hif_power_off(ar);
1852 if (ret)
1853 ath6kl_warn("failed to power off hif: %d\n", ret);
1854
1855 return 0;
1856 }
1857
1858 int ath6kl_init_hw_stop(struct ath6kl *ar)
1859 {
1860 int err;
1861
1862 err = __ath6kl_init_hw_stop(ar);
1863 if (err)
1864 return err;
1865 ar->state = ATH6KL_STATE_OFF;
1866 return 0;
1867 }
1868
1869 void ath6kl_init_hw_restart(struct ath6kl *ar)
1870 {
1871 clear_bit(WMI_READY, &ar->flag);
1872
1873 ath6kl_cfg80211_stop_all(ar);
1874
1875 if (__ath6kl_init_hw_stop(ar)) {
1876 ath6kl_dbg(ATH6KL_DBG_RECOVERY, "Failed to stop during fw error recovery\n");
1877 return;
1878 }
1879
1880 if (__ath6kl_init_hw_start(ar)) {
1881 ath6kl_dbg(ATH6KL_DBG_RECOVERY, "Failed to restart during fw error recovery\n");
1882 return;
1883 }
1884 }
1885
1886 void ath6kl_stop_txrx(struct ath6kl *ar)
1887 {
1888 struct ath6kl_vif *vif, *tmp_vif;
1889 int i;
1890
1891 set_bit(DESTROY_IN_PROGRESS, &ar->flag);
1892
1893 if (down_interruptible(&ar->sem)) {
1894 ath6kl_err("down_interruptible failed\n");
1895 return;
1896 }
1897
1898 for (i = 0; i < AP_MAX_NUM_STA; i++)
1899 aggr_reset_state(ar->sta_list[i].aggr_conn);
1900
1901 spin_lock_bh(&ar->list_lock);
1902 list_for_each_entry_safe(vif, tmp_vif, &ar->vif_list, list) {
1903 list_del(&vif->list);
1904 spin_unlock_bh(&ar->list_lock);
1905 ath6kl_cfg80211_vif_stop(vif, test_bit(WMI_READY, &ar->flag));
1906 rtnl_lock();
1907 wiphy_lock(ar->wiphy);
1908 ath6kl_cfg80211_vif_cleanup(vif);
1909 wiphy_unlock(ar->wiphy);
1910 rtnl_unlock();
1911 spin_lock_bh(&ar->list_lock);
1912 }
1913 spin_unlock_bh(&ar->list_lock);
1914
1915 clear_bit(WMI_READY, &ar->flag);
1916
1917 if (ar->fw_recovery.enable)
1918 del_timer_sync(&ar->fw_recovery.hb_timer);
1919
1920
1921
1922
1923
1924
1925
1926
1927
1928
1929 ath6kl_wmi_shutdown(ar->wmi);
1930
1931 clear_bit(WMI_ENABLED, &ar->flag);
1932 if (ar->htc_target) {
1933 ath6kl_dbg(ATH6KL_DBG_TRC, "%s: shut down htc\n", __func__);
1934 ath6kl_htc_stop(ar->htc_target);
1935 }
1936
1937
1938
1939
1940
1941 ath6kl_init_hw_reset(ar);
1942
1943 up(&ar->sem);
1944 }
1945 EXPORT_SYMBOL(ath6kl_stop_txrx);