19 #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
22 #include <linux/errno.h>
23 #include <linux/export.h>
35 static const struct ath6kl_hw hw_list[] = {
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,
48 .app_start_override_addr = 0x944C00,
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,
70 .testscript_addr = 0x57ef74,
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,
108 .name =
"ar6004 hw 1.1",
109 .dataset_patch_addr = 0x57e884,
110 .app_load_addr = 0x1234,
111 .board_ext_data_addr = 0x437000,
112 .reserved_ram_size = 11264,
113 .board_addr = 0x43d400,
114 .refclk_hz = 40000000,
128 .name =
"ar6004 hw 1.2",
129 .dataset_patch_addr = 0x436ecc,
130 .app_load_addr = 0x1234,
131 .board_ext_data_addr = 0x437000,
132 .reserved_ram_size = 9216,
133 .board_addr = 0x435c00,
134 .refclk_hz = 40000000,
161 #define WLAN_CONFIG_KEEP_ALIVE_INTERVAL 60
170 #define WLAN_CONFIG_DISCONNECT_TIMEOUT 10
173 #define ATH6KL_DATA_OFFSET 64
182 skb = dev_alloc_skb(size + reserved);
206 static int ath6kl_set_host_app_area(
struct ath6kl *
ar)
213 address = ath6kl_get_hi_item_addr(ar,
HI_ITEM(hi_app_host_interest));
228 static inline void set_ac2_ep_map(
struct ath6kl *ar,
237 static int ath6kl_connectservice(
struct ath6kl *ar,
248 ath6kl_err(
"failed to connect to %s service status:%d\n",
253 switch (con_req->
svc_id) {
279 static int ath6kl_init_service_ep(
struct ath6kl *ar)
283 memset(&connect, 0,
sizeof(connect));
297 if (!connect.ep_cb.rx_refill_thresh)
298 connect.ep_cb.rx_refill_thresh++;
302 if (ath6kl_connectservice(ar, &connect,
"WMI CONTROL"))
332 if (ath6kl_connectservice(ar, &connect,
"WMI DATA BE"))
337 if (ath6kl_connectservice(ar, &connect,
"WMI DATA BK"))
342 if (ath6kl_connectservice(ar, &connect,
"WMI DATA VI"))
353 if (ath6kl_connectservice(ar, &connect,
"WMI DATA VO"))
371 static int ath6kl_set_htc_params(
struct ath6kl *ar,
u32 mbox_isr_yield_val,
380 blk_size |= ((
u32)htc_ctrl_buf) << 16;
385 ath6kl_err(
"bmi_write_memory for IO block size failed\n");
389 ath6kl_dbg(
ATH6KL_DBG_TRC,
"block size set: %d (target addr:0x%X)\n",
391 ath6kl_get_hi_item_addr(ar,
HI_ITEM(hi_mbox_io_block_sz)));
393 if (mbox_isr_yield_val) {
398 ath6kl_err(
"bmi_write_memory for yield limit failed\n");
407 static int ath6kl_target_config_wlan_params(
struct ath6kl *ar,
int idx)
419 ath6kl_err(
"unable to set the rx frame format: %d\n", ret);
427 ath6kl_err(
"unable to set power save fail event policy: %d\n",
437 ath6kl_err(
"unable to set barker preamble policy: %d\n",
446 ath6kl_err(
"unable to set keep alive interval: %d\n", ret);
453 ath6kl_err(
"unable to set disconnect timeout: %d\n", ret);
460 ath6kl_err(
"unable to set txop bursting: %d\n", ret);
472 "failed to request P2P capabilities (%d) - assuming P2P not supported\n",
483 "failed to enable Probe Request reporting (%d)\n",
494 u8 fw_iftype, fw_mode = 0, fw_submode = 0;
499 ath6kl_err(
"bmi_write_memory for uart debug failed\n");
513 for (i = 0; i < ar->
vif_max; i++)
527 for (i = 0; i < ar->
vif_max; i++)
545 ath6kl_err(
"bmi_write_memory for htc version failed\n");
553 ath6kl_err(
"bmi_read_memory for setting fwmode failed\n");
565 ath6kl_err(
"bmi_write_memory for setting fwmode failed\n");
581 param = ar->
hw.board_ext_data_addr;
582 ram_reserved_size = ar->
hw.reserved_ram_size;
585 ath6kl_err(
"bmi_write_memory for hi_board_ext_data failed\n");
590 ram_reserved_size) != 0) {
591 ath6kl_err(
"bmi_write_memory for hi_end_ram_reserve_sz failed\n");
617 u8 **
fw,
size_t *fw_len)
626 *fw_len = fw_entry->
size;
644 static bool check_device_tree(
struct ath6kl *ar)
646 static const char *board_id_prop =
"atheros,board-id";
648 char board_filename[64];
652 for_each_compatible_node(node,
NULL,
"atheros,ath6kl") {
654 if (board_id ==
NULL) {
656 board_id_prop, node->
name);
659 snprintf(board_filename,
sizeof(board_filename),
660 "%s/bdata.%s.bin", ar->
hw.fw.dir, board_id);
662 ret = ath6kl_get_fw(ar, board_filename, &ar->
fw_board,
665 ath6kl_err(
"Failed to get DT board file %s: %d\n",
666 board_filename, ret);
674 static bool check_device_tree(
struct ath6kl *ar)
680 static int ath6kl_fetch_board_file(
struct ath6kl *ar)
691 filename = ar->
hw.fw_board;
693 ret = ath6kl_get_fw(ar, filename, &ar->
fw_board,
700 if (check_device_tree(ar)) {
706 ath6kl_warn(
"Failed to get board file %s (%d), trying to find default board file.\n",
709 filename = ar->
hw.fw_default_board;
711 ret = ath6kl_get_fw(ar, filename, &ar->
fw_board,
714 ath6kl_err(
"Failed to get default board file %s: %d\n",
719 ath6kl_warn(
"WARNING! No proper board file was not found, instead using a default board file.\n");
720 ath6kl_warn(
"Most likely your hardware won't work as specified. Install correct board file!\n");
725 static int ath6kl_fetch_otp_file(
struct ath6kl *ar)
733 if (ar->
hw.fw.otp ==
NULL) {
735 "no OTP file configured for this hw\n");
739 snprintf(filename,
sizeof(filename),
"%s/%s",
740 ar->
hw.fw.dir, ar->
hw.fw.otp);
742 ret = ath6kl_get_fw(ar, filename, &ar->
fw_otp,
753 static int ath6kl_fetch_testmode_file(
struct ath6kl *ar)
764 if (ar->
hw.fw.utf ==
NULL) {
769 snprintf(filename,
sizeof(filename),
"%s/%s",
770 ar->
hw.fw.dir, ar->
hw.fw.utf);
772 if (ar->
hw.fw.tcmd ==
NULL) {
777 snprintf(filename,
sizeof(filename),
"%s/%s",
778 ar->
hw.fw.dir, ar->
hw.fw.tcmd);
783 ret = ath6kl_get_fw(ar, filename, &ar->
fw, &ar->
fw_len);
785 ath6kl_err(
"Failed to get testmode %d firmware file %s: %d\n",
793 static int ath6kl_fetch_fw_file(
struct ath6kl *ar)
805 snprintf(filename,
sizeof(filename),
"%s/%s",
806 ar->
hw.fw.dir, ar->
hw.fw.fw);
808 ret = ath6kl_get_fw(ar, filename, &ar->
fw, &ar->
fw_len);
810 ath6kl_err(
"Failed to get firmware file %s: %d\n",
818 static int ath6kl_fetch_patch_file(
struct ath6kl *ar)
826 if (ar->
hw.fw.patch ==
NULL)
829 snprintf(filename,
sizeof(filename),
"%s/%s",
830 ar->
hw.fw.dir, ar->
hw.fw.patch);
832 ret = ath6kl_get_fw(ar, filename, &ar->
fw_patch,
835 ath6kl_err(
"Failed to get patch file %s: %d\n",
843 static int ath6kl_fetch_testscript_file(
struct ath6kl *ar)
854 if (ar->
hw.fw.testscript ==
NULL)
857 snprintf(filename,
sizeof(filename),
"%s/%s",
858 ar->
hw.fw.dir, ar->
hw.fw.testscript);
863 ath6kl_err(
"Failed to get testscript file %s: %d\n",
871 static int ath6kl_fetch_fw_api1(
struct ath6kl *ar)
875 ret = ath6kl_fetch_otp_file(ar);
879 ret = ath6kl_fetch_fw_file(ar);
883 ret = ath6kl_fetch_patch_file(ar);
887 ret = ath6kl_fetch_testscript_file(ar);
894 static int ath6kl_fetch_fw_apin(
struct ath6kl *ar,
const char *
name)
904 snprintf(filename,
sizeof(filename),
"%s/%s", ar->
hw.fw.dir, name);
916 if (len < magic_len) {
938 data +=
sizeof(*hdr);
948 sizeof(ar->
wiphy->fw_version));
951 "found fw version %s\n",
952 ar->
wiphy->fw_version);
1003 "found reserved ram size ie 0x%d\n",
1004 ar->
hw.reserved_ram_size);
1008 "found firmware capabilities ie (%zd B)\n",
1015 if (index == ie_len)
1018 if (data[index] & (1 << bit))
1027 if (ie_len !=
sizeof(*val))
1034 "found patch address ie 0x%x\n",
1035 ar->
hw.dataset_patch_addr);
1038 if (ie_len !=
sizeof(*val))
1045 "found board address ie 0x%x\n",
1049 if (ie_len !=
sizeof(*val))
1060 "found vif max ie %d\n", ar->
vif_max);
1083 ret = ath6kl_fetch_board_file(ar);
1087 ret = ath6kl_fetch_testmode_file(ar);
1103 ret = ath6kl_fetch_fw_api1(ar);
1115 static int ath6kl_upload_board_file(
struct ath6kl *ar)
1117 u32 board_address, board_ext_address,
param;
1118 u32 board_data_size, board_ext_data_size;
1129 if (ar->
hw.board_addr != 0) {
1130 board_address = ar->
hw.board_addr;
1141 board_ext_address == 0) {
1142 ath6kl_err(
"Failed to get board file target address.\n");
1150 if (ar->
fw_board_len > (board_data_size + board_ext_data_size))
1163 if (board_ext_address &&
1164 ar->
fw_board_len == (board_data_size + board_ext_data_size)) {
1168 "writing extended board data to 0x%x (%d B)\n",
1169 board_ext_address, board_ext_data_size);
1173 board_ext_data_size);
1175 ath6kl_err(
"Failed to write extended board data: %d\n",
1181 param = (board_ext_data_size << 16) | 1;
1193 board_address, board_data_size);
1199 ath6kl_err(
"Board file bmi write failed: %d\n", ret);
1209 static int ath6kl_upload_otp(
struct ath6kl *ar)
1212 bool from_hw =
false;
1218 address = ar->
hw.app_load_addr;
1226 ath6kl_err(
"Failed to upload OTP file: %d\n", ret);
1234 ath6kl_err(
"Failed to read hi_app_start: %d\n", ret);
1238 if (ar->
hw.app_start_override_addr == 0) {
1239 ar->
hw.app_start_override_addr =
address;
1244 from_hw ?
" (from hw)" :
"",
1245 ar->
hw.app_start_override_addr);
1249 ar->
hw.app_start_override_addr);
1256 static int ath6kl_upload_firmware(
struct ath6kl *ar)
1264 address = ar->
hw.app_load_addr;
1272 ath6kl_err(
"Failed to write firmware: %d\n", ret);
1281 address = ar->
hw.app_start_override_addr;
1287 static int ath6kl_upload_patch(
struct ath6kl *ar)
1295 address = ar->
hw.dataset_patch_addr;
1302 ath6kl_err(
"Failed to write patch file: %d\n", ret);
1311 static int ath6kl_upload_testscript(
struct ath6kl *ar)
1322 address = ar->
hw.testscript_addr;
1330 ath6kl_err(
"Failed to write testscript file: %d\n", ret);
1341 static int ath6kl_init_upload(
struct ath6kl *ar)
1406 ath6kl_err(
"temporary war to avoid sdio crc error\n");
1438 status = ath6kl_upload_board_file(ar);
1443 status = ath6kl_upload_otp(ar);
1448 status = ath6kl_upload_firmware(ar);
1452 status = ath6kl_upload_patch(ar);
1457 status = ath6kl_upload_testscript(ar);
1468 param = options | 0x20;
1489 ath6kl_err(
"Unsupported hardware version: 0x%x\n",
1497 "target_ver 0x%x target_type 0x%x dataset_patch 0x%x app_load_addr 0x%x\n",
1499 ar->
hw.dataset_patch_addr, ar->
hw.app_load_addr);
1501 "app_start_override_addr 0x%x board_ext_data_addr 0x%x reserved_ram_size 0x%x",
1502 ar->
hw.app_start_override_addr, ar->
hw.board_ext_data_addr,
1503 ar->
hw.reserved_ram_size);
1505 "refclk_hz %d uarttx_pin %d",
1506 ar->
hw.refclk_hz, ar->
hw.uarttx_pin);
1530 ret = ath6kl_hif_power_on(ar);
1538 ret = ath6kl_init_upload(ar);
1554 if (ath6kl_htc_wait_target(ar->
htc_target)) {
1559 if (ath6kl_init_service_ep(ar)) {
1561 goto err_cleanup_scatter;
1572 goto err_cleanup_scatter;
1587 ath6kl_init_get_hif_name(ar->
hif_type),
1588 ar->
wiphy->fw_version,
1594 ath6kl_err(
"abi version mismatch: host(0x%x), target(0x%x)\n",
1600 if (!timeleft || signal_pending(
current)) {
1601 ath6kl_err(
"wmi is not ready or wait was interrupted\n");
1610 if ((ath6kl_set_host_app_area(ar)) != 0)
1611 ath6kl_err(
"unable to set the host app area\n");
1613 for (i = 0; i < ar->
vif_max; i++) {
1614 ret = ath6kl_target_config_wlan_params(ar, i);
1625 err_cleanup_scatter:
1626 ath6kl_hif_cleanup_scatter(ar);
1628 ath6kl_hif_power_off(ar);
1641 ath6kl_hif_stop(ar);
1645 ret = ath6kl_hif_power_off(ar);
1647 ath6kl_warn(
"failed to power off hif: %d\n", ret);
1657 static u8 bcast_mac[] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
1660 netif_stop_queue(vif->
ndev);
1673 bcast_mac : vif->
bssid,
1737 "attempting to reset target on instance destroy\n");