--- zzzz-none-000/linux-4.4.60/drivers/net/wireless/ath/wil6210/wil_crash_dump.c 2017-04-08 07:53:53.000000000 +0000 +++ wasp-540e-714/linux-4.4.60/drivers/net/wireless/ath/wil6210/wil_crash_dump.c 2019-07-03 09:21:34.000000000 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015 Qualcomm Atheros, Inc. + * Copyright (c) 2015,2017 Qualcomm Atheros, Inc. * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above @@ -36,6 +36,9 @@ for (i = 1; i < ARRAY_SIZE(fw_mapping); i++) { map = &fw_mapping[i]; + if (!map->fw) + continue; + if (map->host < host_min) host_min = map->host; @@ -51,8 +54,7 @@ return 0; } -static int wil_fw_copy_crash_dump(struct wil6210_priv *wil, void *dest, - u32 size) +int wil_fw_copy_crash_dump(struct wil6210_priv *wil, void *dest, u32 size) { int i; const struct fw_map *map; @@ -60,13 +62,22 @@ u32 host_min, dump_size, offset, len; if (wil_fw_get_crash_dump_bounds(wil, &dump_size, &host_min)) { - wil_err(wil, "%s: fail to obtain crash dump size\n", __func__); + wil_err(wil, "fail to obtain crash dump size\n"); return -EINVAL; } if (dump_size > size) { - wil_err(wil, "%s: not enough space for dump. Need %d have %d\n", - __func__, dump_size, size); + wil_err(wil, "not enough space for dump. Need %d have %d\n", + dump_size, size); + return -EINVAL; + } + + set_bit(wil_status_collecting_dumps, wil->status); + if (test_bit(wil_status_suspending, wil->status) || + test_bit(wil_status_suspended, wil->status) || + test_bit(wil_status_resetting, wil->status)) { + wil_err(wil, "cannot collect fw dump during suspend/reset\n"); + clear_bit(wil_status_collecting_dumps, wil->status); return -EINVAL; } @@ -74,17 +85,23 @@ for (i = 0; i < ARRAY_SIZE(fw_mapping); i++) { map = &fw_mapping[i]; + if (!map->fw) + continue; + data = (void * __force)wil->csr + HOSTADDR(map->host); len = map->to - map->from; offset = map->host - host_min; - wil_dbg_misc(wil, "%s() - dump %s, size %d, offset %d\n", - __func__, fw_mapping[i].name, len, offset); + wil_dbg_misc(wil, + "fw_copy_crash_dump: - dump %s, size %d, offset %d\n", + fw_mapping[i].name, len, offset); wil_memcpy_fromio_32((void * __force)(dest + offset), (const void __iomem * __force)data, len); } + clear_bit(wil_status_collecting_dumps, wil->status); + return 0; } @@ -94,7 +111,7 @@ u32 fw_dump_size; if (wil_fw_get_crash_dump_bounds(wil, &fw_dump_size, NULL)) { - wil_err(wil, "%s: fail to get fw dump size\n", __func__); + wil_err(wil, "fail to get fw dump size\n"); return; } @@ -110,6 +127,5 @@ * after 5 min */ dev_coredumpv(wil_to_dev(wil), fw_dump_data, fw_dump_size, GFP_KERNEL); - wil_info(wil, "%s: fw core dumped, size %d bytes\n", __func__, - fw_dump_size); + wil_info(wil, "fw core dumped, size %d bytes\n", fw_dump_size); }