Loading drivers/net/wireless/ath/wil6210/debugfs.c +23 −5 Original line number Diff line number Diff line /* * Copyright (c) 2012-2017 Qualcomm Atheros, Inc. * Copyright (c) 2018, The Linux Foundation. All rights reserved. * Copyright (c) 2018-2019, The Linux Foundation. All rights reserved. * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above Loading Loading @@ -280,6 +280,11 @@ static void wil_print_mbox_ring(struct seq_file *s, const char *prefix, wil_halp_vote(wil); if (wil_mem_access_lock(wil)) { wil_halp_unvote(wil); return; } wil_memcpy_fromio_32(&r, off, sizeof(r)); wil_mbox_ring_le2cpus(&r); /* Loading Loading @@ -345,6 +350,7 @@ static void wil_print_mbox_ring(struct seq_file *s, const char *prefix, } out: seq_puts(s, "}\n"); wil_mem_access_unlock(wil); wil_halp_unvote(wil); } Loading Loading @@ -633,6 +639,12 @@ static int wil_memread_debugfs_show(struct seq_file *s, void *data) if (ret < 0) return ret; ret = wil_mem_access_lock(wil); if (ret) { wil_pm_runtime_put(wil); return ret; } a = wmi_buffer(wil, cpu_to_le32(mem_addr)); if (a) Loading @@ -640,6 +652,8 @@ static int wil_memread_debugfs_show(struct seq_file *s, void *data) else seq_printf(s, "[0x%08x] = INVALID\n", mem_addr); wil_mem_access_unlock(wil); wil_pm_runtime_put(wil); return 0; Loading Loading @@ -669,10 +683,6 @@ static ssize_t wil_read_file_ioblob(struct file *file, char __user *user_buf, size_t unaligned_bytes, aligned_count, ret; int rc; if (test_bit(wil_status_suspending, wil_blob->wil->status) || test_bit(wil_status_suspended, wil_blob->wil->status)) return 0; if (pos < 0) return -EINVAL; Loading @@ -699,11 +709,19 @@ static ssize_t wil_read_file_ioblob(struct file *file, char __user *user_buf, return rc; } rc = wil_mem_access_lock(wil); if (rc) { kfree(buf); wil_pm_runtime_put(wil); return rc; } wil_memcpy_fromio_32(buf, (const void __iomem *) wil_blob->blob.data + aligned_pos, aligned_count); ret = copy_to_user(user_buf, buf + unaligned_bytes, count); wil_mem_access_unlock(wil); wil_pm_runtime_put(wil); kfree(buf); Loading drivers/net/wireless/ath/wil6210/main.c +32 −11 Original line number Diff line number Diff line /* * Copyright (c) 2012-2017 Qualcomm Atheros, Inc. * Copyright (c) 2018, The Linux Foundation. All rights reserved. * Copyright (c) 2018-2019, The Linux Foundation. All rights reserved. * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above Loading Loading @@ -184,6 +184,28 @@ void wil_memcpy_toio_32(volatile void __iomem *dst, const void *src, } } /* Device memory access is prohibited while reset or suspend. * wil_mem_access_lock protects accessing device memory in these cases */ int wil_mem_access_lock(struct wil6210_priv *wil) { if (!down_read_trylock(&wil->mem_lock)) return -EBUSY; if (test_bit(wil_status_suspending, wil->status) || test_bit(wil_status_suspended, wil->status)) { up_read(&wil->mem_lock); return -EBUSY; } return 0; } void wil_mem_access_unlock(struct wil6210_priv *wil) { up_read(&wil->mem_lock); } static void wil_ring_fini_tx(struct wil6210_priv *wil, int id) { struct wil_ring *ring = &wil->ring_tx[id]; Loading Loading @@ -707,6 +729,7 @@ int wil_priv_init(struct wil6210_priv *wil) spin_lock_init(&wil->wmi_ev_lock); spin_lock_init(&wil->net_queue_lock); init_waitqueue_head(&wil->wq); init_rwsem(&wil->mem_lock); wil->wmi_wq = create_singlethread_workqueue(WIL_NAME "_wmi"); if (!wil->wmi_wq) Loading Loading @@ -1639,15 +1662,6 @@ int wil_reset(struct wil6210_priv *wil, bool load_fw) } set_bit(wil_status_resetting, wil->status); if (test_bit(wil_status_collecting_dumps, wil->status)) { /* Device collects crash dump, cancel the reset. * following crash dump collection, reset would take place. */ wil_dbg_misc(wil, "reject reset while collecting crash dump\n"); rc = -EBUSY; goto out; } mutex_lock(&wil->vif_mutex); wil_abort_scan_all_vifs(wil, false); mutex_unlock(&wil->vif_mutex); Loading Loading @@ -1831,7 +1845,9 @@ int __wil_up(struct wil6210_priv *wil) WARN_ON(!mutex_is_locked(&wil->mutex)); down_write(&wil->mem_lock); rc = wil_reset(wil, true); up_write(&wil->mem_lock); if (rc) return rc; Loading Loading @@ -1903,6 +1919,7 @@ int wil_up(struct wil6210_priv *wil) int __wil_down(struct wil6210_priv *wil) { int rc; WARN_ON(!mutex_is_locked(&wil->mutex)); set_bit(wil_status_resetting, wil->status); Loading @@ -1923,7 +1940,11 @@ int __wil_down(struct wil6210_priv *wil) wil_abort_scan_all_vifs(wil, false); mutex_unlock(&wil->vif_mutex); return wil_reset(wil, false); down_write(&wil->mem_lock); rc = wil_reset(wil, false); up_write(&wil->mem_lock); return rc; } int wil_down(struct wil6210_priv *wil) Loading drivers/net/wireless/ath/wil6210/pm.c +18 −11 Original line number Diff line number Diff line /* * Copyright (c) 2014,2017 Qualcomm Atheros, Inc. * Copyright (c) 2018, The Linux Foundation. All rights reserved. * Copyright (c) 2018-2019, The Linux Foundation. All rights reserved. * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above Loading Loading @@ -195,14 +195,18 @@ static int wil_suspend_keep_radio_on(struct wil6210_priv *wil) wil_dbg_pm(wil, "suspend keep radio on\n"); /* Prevent handling of new tx and wmi commands */ set_bit(wil_status_suspending, wil->status); if (test_bit(wil_status_collecting_dumps, wil->status)) { /* Device collects crash dump, cancel the suspend */ wil_dbg_pm(wil, "reject suspend while collecting crash dump\n"); clear_bit(wil_status_suspending, wil->status); rc = down_write_trylock(&wil->mem_lock); if (!rc) { wil_err(wil, "device is busy. down_write_trylock failed, returned (0x%x)\n", rc); wil->suspend_stats.rejected_by_host++; return -EBUSY; } set_bit(wil_status_suspending, wil->status); up_write(&wil->mem_lock); wil_pm_stop_all_net_queues(wil); if (!wil_is_tx_idle(wil)) { Loading Loading @@ -311,15 +315,18 @@ static int wil_suspend_radio_off(struct wil6210_priv *wil) wil_dbg_pm(wil, "suspend radio off\n"); set_bit(wil_status_suspending, wil->status); if (test_bit(wil_status_collecting_dumps, wil->status)) { /* Device collects crash dump, cancel the suspend */ wil_dbg_pm(wil, "reject suspend while collecting crash dump\n"); clear_bit(wil_status_suspending, wil->status); rc = down_write_trylock(&wil->mem_lock); if (!rc) { wil_err(wil, "device is busy. down_write_trylock failed, returned (0x%x)\n", rc); wil->suspend_stats.rejected_by_host++; return -EBUSY; } set_bit(wil_status_suspending, wil->status); up_write(&wil->mem_lock); /* if netif up, hardware is alive, shut it down */ mutex_lock(&wil->vif_mutex); active_ifaces = wil_has_active_ifaces(wil, true, false); Loading drivers/net/wireless/ath/wil6210/wil6210.h +5 −2 Original line number Diff line number Diff line /* * Copyright (c) 2012-2017 Qualcomm Atheros, Inc. * Copyright (c) 2018, The Linux Foundation. All rights reserved. * Copyright (c) 2018-2019, The Linux Foundation. All rights reserved. * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above Loading Loading @@ -661,7 +661,6 @@ enum { /* for wil6210_priv.status */ wil_status_suspending, /* suspend in progress */ wil_status_suspended, /* suspend completed, device is suspended */ wil_status_resuming, /* resume in progress */ wil_status_collecting_dumps, /* crashdump collection in progress */ wil_status_last /* keep last */ }; Loading Loading @@ -997,6 +996,8 @@ struct wil6210_priv { struct wil_txrx_ops txrx_ops; struct mutex mutex; /* for wil6210_priv access in wil_{up|down} */ /* for synchronizing device memory access while reset or suspend */ struct rw_semaphore mem_lock; /* statistics */ atomic_t isr_count_rx, isr_count_tx; /* debugfs */ Loading Loading @@ -1200,6 +1201,8 @@ void wil_memcpy_fromio_32(void *dst, const volatile void __iomem *src, size_t count); void wil_memcpy_toio_32(volatile void __iomem *dst, const void *src, size_t count); int wil_mem_access_lock(struct wil6210_priv *wil); void wil_mem_access_unlock(struct wil6210_priv *wil); struct wil6210_vif * wil_vif_alloc(struct wil6210_priv *wil, const char *name, Loading drivers/net/wireless/ath/wil6210/wil_crash_dump.c +6 −12 Original line number Diff line number Diff line /* * Copyright (c) 2015,2017 Qualcomm Atheros, Inc. * Copyright (c) 2018, The Linux Foundation. All rights reserved. * Copyright (c) 2018-2019, The Linux Foundation. All rights reserved. * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above Loading Loading @@ -57,7 +57,7 @@ static int wil_fw_get_crash_dump_bounds(struct wil6210_priv *wil, int wil_fw_copy_crash_dump(struct wil6210_priv *wil, void *dest, u32 size) { int i; int i, rc; const struct fw_map *map; void *data; u32 host_min, dump_size, offset, len; Loading @@ -73,14 +73,9 @@ int wil_fw_copy_crash_dump(struct wil6210_priv *wil, void *dest, u32 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; } rc = wil_mem_access_lock(wil); if (rc) return rc; /* copy to crash dump area */ for (i = 0; i < ARRAY_SIZE(fw_mapping); i++) { Loading @@ -100,8 +95,7 @@ int wil_fw_copy_crash_dump(struct wil6210_priv *wil, void *dest, u32 size) wil_memcpy_fromio_32((void * __force)(dest + offset), (const void __iomem * __force)data, len); } clear_bit(wil_status_collecting_dumps, wil->status); wil_mem_access_unlock(wil); return 0; } Loading Loading
drivers/net/wireless/ath/wil6210/debugfs.c +23 −5 Original line number Diff line number Diff line /* * Copyright (c) 2012-2017 Qualcomm Atheros, Inc. * Copyright (c) 2018, The Linux Foundation. All rights reserved. * Copyright (c) 2018-2019, The Linux Foundation. All rights reserved. * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above Loading Loading @@ -280,6 +280,11 @@ static void wil_print_mbox_ring(struct seq_file *s, const char *prefix, wil_halp_vote(wil); if (wil_mem_access_lock(wil)) { wil_halp_unvote(wil); return; } wil_memcpy_fromio_32(&r, off, sizeof(r)); wil_mbox_ring_le2cpus(&r); /* Loading Loading @@ -345,6 +350,7 @@ static void wil_print_mbox_ring(struct seq_file *s, const char *prefix, } out: seq_puts(s, "}\n"); wil_mem_access_unlock(wil); wil_halp_unvote(wil); } Loading Loading @@ -633,6 +639,12 @@ static int wil_memread_debugfs_show(struct seq_file *s, void *data) if (ret < 0) return ret; ret = wil_mem_access_lock(wil); if (ret) { wil_pm_runtime_put(wil); return ret; } a = wmi_buffer(wil, cpu_to_le32(mem_addr)); if (a) Loading @@ -640,6 +652,8 @@ static int wil_memread_debugfs_show(struct seq_file *s, void *data) else seq_printf(s, "[0x%08x] = INVALID\n", mem_addr); wil_mem_access_unlock(wil); wil_pm_runtime_put(wil); return 0; Loading Loading @@ -669,10 +683,6 @@ static ssize_t wil_read_file_ioblob(struct file *file, char __user *user_buf, size_t unaligned_bytes, aligned_count, ret; int rc; if (test_bit(wil_status_suspending, wil_blob->wil->status) || test_bit(wil_status_suspended, wil_blob->wil->status)) return 0; if (pos < 0) return -EINVAL; Loading @@ -699,11 +709,19 @@ static ssize_t wil_read_file_ioblob(struct file *file, char __user *user_buf, return rc; } rc = wil_mem_access_lock(wil); if (rc) { kfree(buf); wil_pm_runtime_put(wil); return rc; } wil_memcpy_fromio_32(buf, (const void __iomem *) wil_blob->blob.data + aligned_pos, aligned_count); ret = copy_to_user(user_buf, buf + unaligned_bytes, count); wil_mem_access_unlock(wil); wil_pm_runtime_put(wil); kfree(buf); Loading
drivers/net/wireless/ath/wil6210/main.c +32 −11 Original line number Diff line number Diff line /* * Copyright (c) 2012-2017 Qualcomm Atheros, Inc. * Copyright (c) 2018, The Linux Foundation. All rights reserved. * Copyright (c) 2018-2019, The Linux Foundation. All rights reserved. * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above Loading Loading @@ -184,6 +184,28 @@ void wil_memcpy_toio_32(volatile void __iomem *dst, const void *src, } } /* Device memory access is prohibited while reset or suspend. * wil_mem_access_lock protects accessing device memory in these cases */ int wil_mem_access_lock(struct wil6210_priv *wil) { if (!down_read_trylock(&wil->mem_lock)) return -EBUSY; if (test_bit(wil_status_suspending, wil->status) || test_bit(wil_status_suspended, wil->status)) { up_read(&wil->mem_lock); return -EBUSY; } return 0; } void wil_mem_access_unlock(struct wil6210_priv *wil) { up_read(&wil->mem_lock); } static void wil_ring_fini_tx(struct wil6210_priv *wil, int id) { struct wil_ring *ring = &wil->ring_tx[id]; Loading Loading @@ -707,6 +729,7 @@ int wil_priv_init(struct wil6210_priv *wil) spin_lock_init(&wil->wmi_ev_lock); spin_lock_init(&wil->net_queue_lock); init_waitqueue_head(&wil->wq); init_rwsem(&wil->mem_lock); wil->wmi_wq = create_singlethread_workqueue(WIL_NAME "_wmi"); if (!wil->wmi_wq) Loading Loading @@ -1639,15 +1662,6 @@ int wil_reset(struct wil6210_priv *wil, bool load_fw) } set_bit(wil_status_resetting, wil->status); if (test_bit(wil_status_collecting_dumps, wil->status)) { /* Device collects crash dump, cancel the reset. * following crash dump collection, reset would take place. */ wil_dbg_misc(wil, "reject reset while collecting crash dump\n"); rc = -EBUSY; goto out; } mutex_lock(&wil->vif_mutex); wil_abort_scan_all_vifs(wil, false); mutex_unlock(&wil->vif_mutex); Loading Loading @@ -1831,7 +1845,9 @@ int __wil_up(struct wil6210_priv *wil) WARN_ON(!mutex_is_locked(&wil->mutex)); down_write(&wil->mem_lock); rc = wil_reset(wil, true); up_write(&wil->mem_lock); if (rc) return rc; Loading Loading @@ -1903,6 +1919,7 @@ int wil_up(struct wil6210_priv *wil) int __wil_down(struct wil6210_priv *wil) { int rc; WARN_ON(!mutex_is_locked(&wil->mutex)); set_bit(wil_status_resetting, wil->status); Loading @@ -1923,7 +1940,11 @@ int __wil_down(struct wil6210_priv *wil) wil_abort_scan_all_vifs(wil, false); mutex_unlock(&wil->vif_mutex); return wil_reset(wil, false); down_write(&wil->mem_lock); rc = wil_reset(wil, false); up_write(&wil->mem_lock); return rc; } int wil_down(struct wil6210_priv *wil) Loading
drivers/net/wireless/ath/wil6210/pm.c +18 −11 Original line number Diff line number Diff line /* * Copyright (c) 2014,2017 Qualcomm Atheros, Inc. * Copyright (c) 2018, The Linux Foundation. All rights reserved. * Copyright (c) 2018-2019, The Linux Foundation. All rights reserved. * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above Loading Loading @@ -195,14 +195,18 @@ static int wil_suspend_keep_radio_on(struct wil6210_priv *wil) wil_dbg_pm(wil, "suspend keep radio on\n"); /* Prevent handling of new tx and wmi commands */ set_bit(wil_status_suspending, wil->status); if (test_bit(wil_status_collecting_dumps, wil->status)) { /* Device collects crash dump, cancel the suspend */ wil_dbg_pm(wil, "reject suspend while collecting crash dump\n"); clear_bit(wil_status_suspending, wil->status); rc = down_write_trylock(&wil->mem_lock); if (!rc) { wil_err(wil, "device is busy. down_write_trylock failed, returned (0x%x)\n", rc); wil->suspend_stats.rejected_by_host++; return -EBUSY; } set_bit(wil_status_suspending, wil->status); up_write(&wil->mem_lock); wil_pm_stop_all_net_queues(wil); if (!wil_is_tx_idle(wil)) { Loading Loading @@ -311,15 +315,18 @@ static int wil_suspend_radio_off(struct wil6210_priv *wil) wil_dbg_pm(wil, "suspend radio off\n"); set_bit(wil_status_suspending, wil->status); if (test_bit(wil_status_collecting_dumps, wil->status)) { /* Device collects crash dump, cancel the suspend */ wil_dbg_pm(wil, "reject suspend while collecting crash dump\n"); clear_bit(wil_status_suspending, wil->status); rc = down_write_trylock(&wil->mem_lock); if (!rc) { wil_err(wil, "device is busy. down_write_trylock failed, returned (0x%x)\n", rc); wil->suspend_stats.rejected_by_host++; return -EBUSY; } set_bit(wil_status_suspending, wil->status); up_write(&wil->mem_lock); /* if netif up, hardware is alive, shut it down */ mutex_lock(&wil->vif_mutex); active_ifaces = wil_has_active_ifaces(wil, true, false); Loading
drivers/net/wireless/ath/wil6210/wil6210.h +5 −2 Original line number Diff line number Diff line /* * Copyright (c) 2012-2017 Qualcomm Atheros, Inc. * Copyright (c) 2018, The Linux Foundation. All rights reserved. * Copyright (c) 2018-2019, The Linux Foundation. All rights reserved. * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above Loading Loading @@ -661,7 +661,6 @@ enum { /* for wil6210_priv.status */ wil_status_suspending, /* suspend in progress */ wil_status_suspended, /* suspend completed, device is suspended */ wil_status_resuming, /* resume in progress */ wil_status_collecting_dumps, /* crashdump collection in progress */ wil_status_last /* keep last */ }; Loading Loading @@ -997,6 +996,8 @@ struct wil6210_priv { struct wil_txrx_ops txrx_ops; struct mutex mutex; /* for wil6210_priv access in wil_{up|down} */ /* for synchronizing device memory access while reset or suspend */ struct rw_semaphore mem_lock; /* statistics */ atomic_t isr_count_rx, isr_count_tx; /* debugfs */ Loading Loading @@ -1200,6 +1201,8 @@ void wil_memcpy_fromio_32(void *dst, const volatile void __iomem *src, size_t count); void wil_memcpy_toio_32(volatile void __iomem *dst, const void *src, size_t count); int wil_mem_access_lock(struct wil6210_priv *wil); void wil_mem_access_unlock(struct wil6210_priv *wil); struct wil6210_vif * wil_vif_alloc(struct wil6210_priv *wil, const char *name, Loading
drivers/net/wireless/ath/wil6210/wil_crash_dump.c +6 −12 Original line number Diff line number Diff line /* * Copyright (c) 2015,2017 Qualcomm Atheros, Inc. * Copyright (c) 2018, The Linux Foundation. All rights reserved. * Copyright (c) 2018-2019, The Linux Foundation. All rights reserved. * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above Loading Loading @@ -57,7 +57,7 @@ static int wil_fw_get_crash_dump_bounds(struct wil6210_priv *wil, int wil_fw_copy_crash_dump(struct wil6210_priv *wil, void *dest, u32 size) { int i; int i, rc; const struct fw_map *map; void *data; u32 host_min, dump_size, offset, len; Loading @@ -73,14 +73,9 @@ int wil_fw_copy_crash_dump(struct wil6210_priv *wil, void *dest, u32 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; } rc = wil_mem_access_lock(wil); if (rc) return rc; /* copy to crash dump area */ for (i = 0; i < ARRAY_SIZE(fw_mapping); i++) { Loading @@ -100,8 +95,7 @@ int wil_fw_copy_crash_dump(struct wil6210_priv *wil, void *dest, u32 size) wil_memcpy_fromio_32((void * __force)(dest + offset), (const void __iomem * __force)data, len); } clear_bit(wil_status_collecting_dumps, wil->status); wil_mem_access_unlock(wil); return 0; } Loading