- 19 5月, 2017 12 次提交
-
-
由 Brian Norris 提交于
These are already handled by mwifiex_shutdown_sw() and mwifiex_reinit_sw(). Ideally, we'll kill the flag entirely eventually, as I suspect it breeds race conditions. Signed-off-by: NBrian Norris <briannorris@chromium.org> Signed-off-by: NKalle Valo <kvalo@codeaurora.org>
-
由 Brian Norris 提交于
Signed-off-by: NBrian Norris <briannorris@chromium.org> Signed-off-by: NKalle Valo <kvalo@codeaurora.org>
-
由 Brian Norris 提交于
These pointers are retrieved via container_of(). There's no way they are NULL. Signed-off-by: NBrian Norris <briannorris@chromium.org> Signed-off-by: NKalle Valo <kvalo@codeaurora.org>
-
由 Brian Norris 提交于
We're using 'adapter' right before calling this. Stop being unnecessarily paranoid. Signed-off-by: NBrian Norris <briannorris@chromium.org> Signed-off-by: NKalle Valo <kvalo@codeaurora.org>
-
由 Brian Norris 提交于
If mwifiex_shutdown_drv() is racing with another mwifiex_shutdown_drv(), we *really* have problems. Kill the lock. Signed-off-by: NBrian Norris <briannorris@chromium.org> Signed-off-by: NKalle Valo <kvalo@codeaurora.org>
-
由 Brian Norris 提交于
When removing or resetting an mwifiex device, we don't remember to free the saved beacon buffer. Use the (somewhat misleadingly-named) mwifiex_free_priv() helper to handle this. Noticed by kmemleak during tests: echo 1 > /sys/bus/pci/devices/.../reset unreferenced object 0xffffffc09d034a00 (size 256): ... backtrace: [<ffffffc0003cdce4>] create_object+0x228/0x3c4 [<ffffffc000c0b9d8>] kmemleak_alloc+0x54/0x88 [<ffffffc0003c0848>] __kmalloc+0x1cc/0x2dc [<ffffffbffc1500c4>] mwifiex_save_curr_bcn+0x80/0x308 [mwifiex] [<ffffffbffc1516b8>] mwifiex_ret_802_11_associate+0x4ec/0x5fc [mwifiex] [<ffffffbffc15da90>] mwifiex_process_sta_cmdresp+0xaf8/0x1fa4 [mwifiex] [<ffffffbffc1411e0>] mwifiex_process_cmdresp+0x40c/0x510 [mwifiex] [<ffffffbffc13b8f4>] mwifiex_main_process+0x4a4/0xb00 [mwifiex] [<ffffffbffc13bf84>] mwifiex_main_work_queue+0x34/0x40 [mwifiex] Signed-off-by: NBrian Norris <briannorris@chromium.org> Signed-off-by: NKalle Valo <kvalo@codeaurora.org>
-
由 Brian Norris 提交于
mwifiex_exec_next_cmd() seems to have a classic TOCTOU race, where we drop the list lock in between retrieving the next command and deleting it from the list. This potentially leaves room for someone else to also retrieve / steal this node from the list (e.g., mwifiex_cancel_all_pending_cmd()). Let's keep holding the lock while we do our 'ps_state' sanity checks. There should be no harm in continuing to hold this lock for a bit more. Noticed only by code inspection. Signed-off-by: NBrian Norris <briannorris@chromium.org> Signed-off-by: NKalle Valo <kvalo@codeaurora.org>
-
由 Douglas Anderson 提交于
The mwifiex_11n_delba() function walked the rx_reorder_tbl_ptr without holding the lock, which was an obvious violation. Grab the lock. NOTE: we hold the lock while calling mwifiex_send_delba(). There's also several callers in 11n_rxreorder.c that hold the lock and the comments in the struct sound just like very other list/lock pair -- as if the lock should definitely be help for all operations like this. Signed-off-by: NDouglas Anderson <dianders@chromium.org> Signed-off-by: NBrian Norris <briannorris@chromium.org> Signed-off-by: NKalle Valo <kvalo@codeaurora.org>
-
由 Douglas Anderson 提交于
Just like in the previous patch ("mwifiex: Don't release tx_ba_stream_tbl_lock while iterating"), in mwifiex_cancel_all_pending_cmd() we were itearting over a list protected by a spinlock. Again, it is not safe to release the spinlock while iterating. Don't do it. Luckily in this case there should be no need to release the spinlock. This is evidenced by: 1. The only function called while the spinlock was released was mwifiex_recycle_cmd_node() 2. Aside from atomic functions (which are safe to call), the only function called by mwifiex_recycle_cmd_node() was mwifiex_insert_cmd_to_free_q(). 3. It can be seen in mwifiex_cancel_pending_scan_cmd() that it's OK to call mwifiex_insert_cmd_to_free_q() while holding a different spinlock (scan_pending_q_lock), so in general holding a spinlock should be OK. 4. It doesn't appear that mwifiex_insert_cmd_to_free_q() has any interaction with the cmd_pending_q_lock No known bugs are fixed with this change, but as with other similar changes this could fix random list corruption. Signed-off-by: NDouglas Anderson <dianders@chromium.org> Signed-off-by: NBrian Norris <briannorris@chromium.org> Signed-off-by: NKalle Valo <kvalo@codeaurora.org>
-
由 Douglas Anderson 提交于
Despite the macro list_for_each_entry_safe() having the word "safe" in the name, it's still not actually safe to release the list spinlock while iterating over the list. The "safe" in the macro name actually only means that it's safe to delete the current entry while iterating over the list. Releasing the spinlock while iterating over the list means that someone else could come in and adjust the list while we don't have the spinlock. If they do that it can totally mix up our iteration and fully corrupt the list. Later iterating over a corrupted list while holding a spinlock and having IRQs off can cause all sorts of hard to debug problems. As evidenced by the other call to mwifiex_11n_delete_tx_ba_stream_tbl_entry() in mwifiex_11n_delete_all_tx_ba_stream_tbl(), it's actually safe to skip the spinlock release. Let's do that. No known problems are fixed by this patch, but it could fix all sorts of weird problems and it should be very safe. Signed-off-by: NDouglas Anderson <dianders@chromium.org> Signed-off-by: NBrian Norris <briannorris@chromium.org> Signed-off-by: NKalle Valo <kvalo@codeaurora.org>
-
由 Brian Norris 提交于
If we fail to add an interface in mwifiex_add_virtual_intf(), we might hit a BUG_ON() in the networking code, because we didn't tear things down properly. Among the problems: (a) when failing to allocate workqueues, we fail to unregister the netdev before calling free_netdev() (b) even if we do try to unregister the netdev, we're still holding the rtnl lock, so the device never properly unregistered; we'll be at state NETREG_UNREGISTERING, and then hit free_netdev()'s: BUG_ON(dev->reg_state != NETREG_UNREGISTERED); (c) we're allocating some dependent resources (e.g., DFS workqueues) after we've registered the interface; this may or may not cause problems, but it's good practice to allocate these before registering (d) we're not even trying to unwind anything when mwifiex_send_cmd() or mwifiex_sta_init_cmd() fail To fix these issues, let's: * add a stacked set of error handling labels, to keep error handling consistent and properly ordered (resolving (a) and (d)) * move the workqueue allocations before the registration (to resolve (c); also resolves (b) by avoiding error cases where we have to unregister) [Incidentally, it's pretty easy to interrupt the alloc_workqueue() in, e.g., the following: iw phy phy0 interface add mlan0 type station by sending it SIGTERM.] This bugfix covers commits like commit 7d652034 ("mwifiex: channel switch support for mwifiex"), but parts of this bug exist all the way back to the introduction of dynamic interface handling in commit 93a1df48 ("mwifiex: add cfg80211 handlers add/del_virtual_intf"). Cc: <stable@vger.kernel.org> Signed-off-by: NBrian Norris <briannorris@chromium.org> Signed-off-by: NKalle Valo <kvalo@codeaurora.org>
-
由 Brian Norris 提交于
This code was duplicated as part of the PCIe FLR code added to this driver. Let's de-duplicate it to: * make things easier to read (mwifiex_pcie_free_buffers() now has a corresponding mwifiex_pcie_alloc_buffers()) * reduce likelihood of bugs * make error logging equally verbose * save lines of code! Also drop some of the commentary that isn't really needed. Signed-off-by: NBrian Norris <briannorris@chromium.org> Signed-off-by: NKalle Valo <kvalo@codeaurora.org>
-
- 18 5月, 2017 3 次提交
-
-
由 Brian Norris 提交于
Similar to the SDIO driver, we should implement this so that we will automatically reset the device whenever there's a command timeout or similar. Signed-off-by: NBrian Norris <briannorris@chromium.org> Reviewed-by: NDmitry Torokhov <dmitry.torokhov@gmail.com> Signed-off-by: NKalle Valo <kvalo@codeaurora.org>
-
由 Brian Norris 提交于
The non-atomic test + set is a little awkward here, and it technically means we might double-schedule work unnecessarily. AFAICT, this is not really a problem, since the extra "work" will be a no-op (the flag(s) will be cleared by then), but it's still an anti-pattern. Rewrite this to use the atomic test_and_set_bit() helper instead. Signed-off-by: NBrian Norris <briannorris@chromium.org> Reviewed-by: NDmitry Torokhov <dmitry.torokhov@gmail.com> Signed-off-by: NKalle Valo <kvalo@codeaurora.org>
-
由 Xinming Hu 提交于
P2p client act as a station, data will be queued by DA instead of RA. This patch pass the sanity check, so that p2p client share the same data path with infrastruction station mode. Signed-off-by: NXinming Hu <huxm@marvell.com> Signed-off-by: NCathy Luo <cluo@marvell.com> Signed-off-by: NKalle Valo <kvalo@codeaurora.org>
-
- 28 4月, 2017 3 次提交
-
-
由 Arend Van Spriel 提交于
Have proper request id filled in the SCHED_SCAN_RESULTS and SCHED_SCAN_STOPPED notifications toward user-space by having the driver provide it through the api. Reviewed-by: NHante Meuleman <hante.meuleman@broadcom.com> Reviewed-by: NPieter-Paul Giesberts <pieter-paul.giesberts@broadcom.com> Reviewed-by: NFranky Lin <franky.lin@broadcom.com> Signed-off-by: NArend van Spriel <arend.vanspriel@broadcom.com> Signed-off-by: NJohannes Berg <johannes.berg@intel.com>
-
由 Johannes Berg 提交于
We currently use a lot of flags that are mutually incompatible, separate this out into actual encoding and bandwidth enum values. Much of this again done with spatch, with manual post-editing, mostly to add the switch statements and get rid of the conversions. @@ expression status; @@ -status->enc_flags |= RX_ENC_FLAG_80MHZ +status->bw = RATE_INFO_BW_80 @@ expression status; @@ -status->enc_flags |= RX_ENC_FLAG_40MHZ +status->bw = RATE_INFO_BW_40 @@ expression status; @@ -status->enc_flags |= RX_ENC_FLAG_20MHZ +status->bw = RATE_INFO_BW_20 @@ expression status; @@ -status->enc_flags |= RX_ENC_FLAG_160MHZ +status->bw = RATE_INFO_BW_160 @@ expression status; @@ -status->enc_flags |= RX_ENC_FLAG_5MHZ +status->bw = RATE_INFO_BW_5 @@ expression status; @@ -status->enc_flags |= RX_ENC_FLAG_10MHZ +status->bw = RATE_INFO_BW_10 @@ expression status; @@ -status->enc_flags |= RX_ENC_FLAG_VHT +status->encoding = RX_ENC_VHT @@ expression status; @@ -status->enc_flags |= RX_ENC_FLAG_HT +status->encoding = RX_ENC_HT @@ expression status; @@ -status.enc_flags |= RX_ENC_FLAG_VHT +status.encoding = RX_ENC_VHT @@ expression status; @@ -status.enc_flags |= RX_ENC_FLAG_HT +status.encoding = RX_ENC_HT @@ expression status; @@ -(status->enc_flags & RX_ENC_FLAG_HT) +(status->encoding == RX_ENC_HT) @@ expression status; @@ -(status->enc_flags & RX_ENC_FLAG_VHT) +(status->encoding == RX_ENC_VHT) @@ expression status; @@ -(status->enc_flags & RX_ENC_FLAG_5MHZ) +(status->bw == RATE_INFO_BW_5) @@ expression status; @@ -(status->enc_flags & RX_ENC_FLAG_10MHZ) +(status->bw == RATE_INFO_BW_10) @@ expression status; @@ -(status->enc_flags & RX_ENC_FLAG_40MHZ) +(status->bw == RATE_INFO_BW_40) @@ expression status; @@ -(status->enc_flags & RX_ENC_FLAG_80MHZ) +(status->bw == RATE_INFO_BW_80) @@ expression status; @@ -(status->enc_flags & RX_ENC_FLAG_160MHZ) +(status->bw == RATE_INFO_BW_160) Signed-off-by: NJohannes Berg <johannes.berg@intel.com>
-
由 Johannes Berg 提交于
In preparation for adding support for HE rates, clean up the driver report encoding for rate/bandwidth reporting on RX frames. Much of this patch was done with the following spatch: @@ expression status; @@ -status->flag & (RX_FLAG_HT | RX_FLAG_VHT) +status->enc_flags & (RX_ENC_FLAG_HT | RX_ENC_FLAG_VHT) @@ assignment operator op; expression status; @@ -status->flag op RX_FLAG_SHORTPRE +status->enc_flags op RX_ENC_FLAG_SHORTPRE @@ expression status; @@ -status->flag & RX_FLAG_SHORTPRE +status->enc_flags & RX_ENC_FLAG_SHORTPRE @@ assignment operator op; expression status; @@ -status->flag op RX_FLAG_HT +status->enc_flags op RX_ENC_FLAG_HT @@ expression status; @@ -status->flag & RX_FLAG_HT +status->enc_flags & RX_ENC_FLAG_HT @@ assignment operator op; expression status; @@ -status->flag op RX_FLAG_40MHZ +status->enc_flags op RX_ENC_FLAG_40MHZ @@ expression status; @@ -status->flag & RX_FLAG_40MHZ +status->enc_flags & RX_ENC_FLAG_40MHZ @@ assignment operator op; expression status; @@ -status->flag op RX_FLAG_SHORT_GI +status->enc_flags op RX_ENC_FLAG_SHORT_GI @@ expression status; @@ -status->flag & RX_FLAG_SHORT_GI +status->enc_flags & RX_ENC_FLAG_SHORT_GI @@ assignment operator op; expression status; @@ -status->flag op RX_FLAG_HT_GF +status->enc_flags op RX_ENC_FLAG_HT_GF @@ expression status; @@ -status->flag & RX_FLAG_HT_GF +status->enc_flags & RX_ENC_FLAG_HT_GF @@ assignment operator op; expression status; @@ -status->flag op RX_FLAG_VHT +status->enc_flags op RX_ENC_FLAG_VHT @@ expression status; @@ -status->flag & RX_FLAG_VHT +status->enc_flags & RX_ENC_FLAG_VHT @@ assignment operator op; expression status; @@ -status->flag op RX_FLAG_STBC_MASK +status->enc_flags op RX_ENC_FLAG_STBC_MASK @@ expression status; @@ -status->flag & RX_FLAG_STBC_MASK +status->enc_flags & RX_ENC_FLAG_STBC_MASK @@ assignment operator op; expression status; @@ -status->flag op RX_FLAG_LDPC +status->enc_flags op RX_ENC_FLAG_LDPC @@ expression status; @@ -status->flag & RX_FLAG_LDPC +status->enc_flags & RX_ENC_FLAG_LDPC @@ assignment operator op; expression status; @@ -status->flag op RX_FLAG_10MHZ +status->enc_flags op RX_ENC_FLAG_10MHZ @@ expression status; @@ -status->flag & RX_FLAG_10MHZ +status->enc_flags & RX_ENC_FLAG_10MHZ @@ assignment operator op; expression status; @@ -status->flag op RX_FLAG_5MHZ +status->enc_flags op RX_ENC_FLAG_5MHZ @@ expression status; @@ -status->flag & RX_FLAG_5MHZ +status->enc_flags & RX_ENC_FLAG_5MHZ @@ assignment operator op; expression status; @@ -status->vht_flag op RX_VHT_FLAG_80MHZ +status->enc_flags op RX_ENC_FLAG_80MHZ @@ expression status; @@ -status->vht_flag & RX_VHT_FLAG_80MHZ +status->enc_flags & RX_ENC_FLAG_80MHZ @@ assignment operator op; expression status; @@ -status->vht_flag op RX_VHT_FLAG_160MHZ +status->enc_flags op RX_ENC_FLAG_160MHZ @@ expression status; @@ -status->vht_flag & RX_VHT_FLAG_160MHZ +status->enc_flags & RX_ENC_FLAG_160MHZ @@ assignment operator op; expression status; @@ -status->vht_flag op RX_VHT_FLAG_BF +status->enc_flags op RX_ENC_FLAG_BF @@ expression status; @@ -status->vht_flag & RX_VHT_FLAG_BF +status->enc_flags & RX_ENC_FLAG_BF @@ assignment operator op; expression status, STBC; @@ -status->flag op STBC << RX_FLAG_STBC_SHIFT +status->enc_flags op STBC << RX_ENC_FLAG_STBC_SHIFT @@ assignment operator op; expression status; @@ -status.flag op RX_FLAG_SHORTPRE +status.enc_flags op RX_ENC_FLAG_SHORTPRE @@ expression status; @@ -status.flag & RX_FLAG_SHORTPRE +status.enc_flags & RX_ENC_FLAG_SHORTPRE @@ assignment operator op; expression status; @@ -status.flag op RX_FLAG_HT +status.enc_flags op RX_ENC_FLAG_HT @@ expression status; @@ -status.flag & RX_FLAG_HT +status.enc_flags & RX_ENC_FLAG_HT @@ assignment operator op; expression status; @@ -status.flag op RX_FLAG_40MHZ +status.enc_flags op RX_ENC_FLAG_40MHZ @@ expression status; @@ -status.flag & RX_FLAG_40MHZ +status.enc_flags & RX_ENC_FLAG_40MHZ @@ assignment operator op; expression status; @@ -status.flag op RX_FLAG_SHORT_GI +status.enc_flags op RX_ENC_FLAG_SHORT_GI @@ expression status; @@ -status.flag & RX_FLAG_SHORT_GI +status.enc_flags & RX_ENC_FLAG_SHORT_GI @@ assignment operator op; expression status; @@ -status.flag op RX_FLAG_HT_GF +status.enc_flags op RX_ENC_FLAG_HT_GF @@ expression status; @@ -status.flag & RX_FLAG_HT_GF +status.enc_flags & RX_ENC_FLAG_HT_GF @@ assignment operator op; expression status; @@ -status.flag op RX_FLAG_VHT +status.enc_flags op RX_ENC_FLAG_VHT @@ expression status; @@ -status.flag & RX_FLAG_VHT +status.enc_flags & RX_ENC_FLAG_VHT @@ assignment operator op; expression status; @@ -status.flag op RX_FLAG_STBC_MASK +status.enc_flags op RX_ENC_FLAG_STBC_MASK @@ expression status; @@ -status.flag & RX_FLAG_STBC_MASK +status.enc_flags & RX_ENC_FLAG_STBC_MASK @@ assignment operator op; expression status; @@ -status.flag op RX_FLAG_LDPC +status.enc_flags op RX_ENC_FLAG_LDPC @@ expression status; @@ -status.flag & RX_FLAG_LDPC +status.enc_flags & RX_ENC_FLAG_LDPC @@ assignment operator op; expression status; @@ -status.flag op RX_FLAG_10MHZ +status.enc_flags op RX_ENC_FLAG_10MHZ @@ expression status; @@ -status.flag & RX_FLAG_10MHZ +status.enc_flags & RX_ENC_FLAG_10MHZ @@ assignment operator op; expression status; @@ -status.flag op RX_FLAG_5MHZ +status.enc_flags op RX_ENC_FLAG_5MHZ @@ expression status; @@ -status.flag & RX_FLAG_5MHZ +status.enc_flags & RX_ENC_FLAG_5MHZ @@ assignment operator op; expression status; @@ -status.vht_flag op RX_VHT_FLAG_80MHZ +status.enc_flags op RX_ENC_FLAG_80MHZ @@ expression status; @@ -status.vht_flag & RX_VHT_FLAG_80MHZ +status.enc_flags & RX_ENC_FLAG_80MHZ @@ assignment operator op; expression status; @@ -status.vht_flag op RX_VHT_FLAG_160MHZ +status.enc_flags op RX_ENC_FLAG_160MHZ @@ expression status; @@ -status.vht_flag & RX_VHT_FLAG_160MHZ +status.enc_flags & RX_ENC_FLAG_160MHZ @@ assignment operator op; expression status; @@ -status.vht_flag op RX_VHT_FLAG_BF +status.enc_flags op RX_ENC_FLAG_BF @@ expression status; @@ -status.vht_flag & RX_VHT_FLAG_BF +status.enc_flags & RX_ENC_FLAG_BF @@ assignment operator op; expression status, STBC; @@ -status.flag op STBC << RX_FLAG_STBC_SHIFT +status.enc_flags op STBC << RX_ENC_FLAG_STBC_SHIFT @@ @@ -RX_FLAG_STBC_SHIFT +RX_ENC_FLAG_STBC_SHIFT Signed-off-by: NJohannes Berg <johannes.berg@intel.com>
-
- 27 4月, 2017 2 次提交
-
-
由 Arend Van Spriel 提交于
For multiple scheduled scan support the driver needs to know which scheduled scan request is being stopped. Pass the request id in the .sched_scan_stop() callback. Reviewed-by: NHante Meuleman <hante.meuleman@broadcom.com> Reviewed-by: NPieter-Paul Giesberts <pieter-paul.giesberts@broadcom.com> Reviewed-by: NFranky Lin <franky.lin@broadcom.com> Signed-off-by: NArend van Spriel <arend.vanspriel@broadcom.com> Signed-off-by: NJohannes Berg <johannes.berg@intel.com>
-
由 Arend Van Spriel 提交于
This patch implements the idea to have multiple scheduled scan requests running concurrently. It mainly illustrates how to deal with the incoming request from user-space in terms of backward compatibility. In order to use multiple scheduled scans user-space needs to provide a flag attribute NL80211_ATTR_SCHED_SCAN_MULTI to indicate support. If not the request is treated as a legacy scan. Drivers currently supporting scheduled scan are now indicating they support a single scheduled scan request. This obsoletes WIPHY_FLAG_SUPPORTS_SCHED_SCAN. Reviewed-by: NHante Meuleman <hante.meuleman@broadcom.com> Reviewed-by: NPieter-Paul Giesberts <pieter-paul.giesberts@broadcom.com> Reviewed-by: NFranky Lin <franky.lin@broadcom.com> Signed-off-by: NArend van Spriel <arend.vanspriel@broadcom.com> [clean up netlink destroy path to avoid allocations, code cleanups] Signed-off-by: NJohannes Berg <johannes.berg@intel.com>
-
- 26 4月, 2017 1 次提交
-
-
由 Pan Bian 提交于
Function alloc_workqueue() will return a NULL pointer if there is no enough memory, and its return value should be validated before using. However, in function if_spi_probe(), its return value is not checked. This may result in a NULL dereference bug. This patch fixes the bug. Signed-off-by: NPan Bian <bianpan2016@163.com> Signed-off-by: NKalle Valo <kvalo@codeaurora.org>
-
- 20 4月, 2017 9 次提交
-
-
由 Brian Norris 提交于
'chan_stats' is (re)allocated in _mwifiex_fw_dpc() -> mwifiex_init_channel_scan_gap(), which is called whenever the device is initialized -- at probe or at reset. But we only free it in we completely unregister the adapter, meaning we leak a copy of it during every reset. Let's free it in the shutdown / removal paths instead (and in the error-handling path), to avoid the leak. Ideally, we can eventually unify much of mwifiex_shutdown_sw() and mwifiex_remove_card() (way too much copy-and-paste) to reduce the burden on bugfixes like this. But that's work for tomorrow. Signed-off-by: NBrian Norris <briannorris@chromium.org> Signed-off-by: NKalle Valo <kvalo@codeaurora.org>
-
由 Brian Norris 提交于
When we shut down the device (i.e., during 'reset'), we cancel any outstanding work, but we don't clear any work-related flags. This can cause problems if, e.g., we begin to queue a new firmware dump or card reset while the other one is in progress. That might leave work_flags with a stale value, and we might begin one of these *after* we've completely reset the device. That doesn't make sense, because all firmware context will have been lost by then. This fixes some forms of cascading failures, where I: (a) force a firmware dump (cat /sys/kernel/debug/mwifiex/mlan0/device_dump) (b) run a Wifi scan in parallel (iw mlan0 scan) (c) the scan times out due to (a) hogging the interface (d) the command timeout triggers another firmware dump and a reset [*] (e) the 2nd firmware dump flag persists across the reset (f) as soon as the interface comes back up, we trigger the pending firmware dump (g) subsequent commands time out again, while we are processing the firmware dump; return to (d) [*] Note that automatic card_reset() support is not yet implemented for the mwifiex PCIe driver, so we won't hit *exactly* this behavior yet. But we can see similarly-confusing behaviors today. Signed-off-by: NBrian Norris <briannorris@chromium.org> Signed-off-by: NKalle Valo <kvalo@codeaurora.org>
-
由 Brian Norris 提交于
If we reset because of a command timeout, we should reset this flag. Otherwise, we might erroneously think the next command after reset is timing out, and trigger another reset. The above behavior effectively neuters the automatic card_reset() behavior, as it means we will never recover from a command timeout properly (and in fact, we might enter an infinite loop: timeout -> reset -> (fake) timeout -> reset -> ... This fixes a bug introduced with introduction of PCIe function level reset support, but it was carried into the SDIO driver when it was converted to use the same codepaths. And this is currently mostly a problem only in the SDIO driver, because it's the only one with automatic card_reset() support (e.g., on command timeout). But it will be a problem for PCIe too, as I'm working on supporting automatic card_reset() for PCIe. Fixes: c742e623 ("mwifiex: sdio card reset enhancement") Fixes: 4c5dae59 ("mwifiex: add PCIe function level reset support") Signed-off-by: NBrian Norris <briannorris@chromium.org> Signed-off-by: NKalle Valo <kvalo@codeaurora.org>
-
由 Brian Norris 提交于
Command buffers (skb's) are allocated by the main driver, and freed upon the last use. That last use is often in mwifiex_free_cmd_buffer(). In the meantime, if the command buffer gets used by the PCI driver, we map it as DMA-able, and store the mapping information in the 'cb' memory. However, if a command was in-flight when resetting the device (and therefore was still mapped), we don't get a chance to unmap this memory until after the core has cleaned up its command handling. Let's keep a refcount within the PCI driver, so we ensure the memory only gets freed after we've finished unmapping it. Noticed by KASAN when forcing a reset via: echo 1 > /sys/bus/pci/.../reset The same code path can presumably be exercised in remove() and shutdown(). [ 205.390377] mwifiex_pcie 0000:01:00.0: info: shutdown mwifiex... [ 205.400393] ================================================================== [ 205.407719] BUG: KASAN: use-after-free in mwifiex_unmap_pci_memory.isra.14+0x4c/0x100 [mwifiex_pcie] at addr ffffffc0ad471b28 [ 205.419040] Read of size 16 by task bash/1913 [ 205.423421] ============================================================================= [ 205.431625] BUG skbuff_head_cache (Tainted: G B ): kasan: bad access detected [ 205.439815] ----------------------------------------------------------------------------- [ 205.439815] [ 205.449534] INFO: Allocated in __build_skb+0x48/0x114 age=1311 cpu=4 pid=1913 [ 205.456709] alloc_debug_processing+0x124/0x178 [ 205.461282] ___slab_alloc.constprop.58+0x528/0x608 [ 205.466196] __slab_alloc.isra.54.constprop.57+0x44/0x54 [ 205.471542] kmem_cache_alloc+0xcc/0x278 [ 205.475497] __build_skb+0x48/0x114 [ 205.479019] __netdev_alloc_skb+0xe0/0x170 [ 205.483244] mwifiex_alloc_cmd_buffer+0x68/0xdc [mwifiex] [ 205.488759] mwifiex_init_fw+0x40/0x6cc [mwifiex] [ 205.493584] _mwifiex_fw_dpc+0x158/0x520 [mwifiex] [ 205.498491] mwifiex_reinit_sw+0x2c4/0x398 [mwifiex] [ 205.503510] mwifiex_pcie_reset_notify+0x114/0x15c [mwifiex_pcie] [ 205.509643] pci_reset_notify+0x5c/0x6c [ 205.513519] pci_reset_function+0x6c/0x7c [ 205.517567] reset_store+0x68/0x98 [ 205.521003] dev_attr_store+0x54/0x60 [ 205.524705] sysfs_kf_write+0x9c/0xb0 [ 205.528413] INFO: Freed in __kfree_skb+0xb0/0xbc age=131 cpu=4 pid=1913 [ 205.535064] free_debug_processing+0x264/0x370 [ 205.539550] __slab_free+0x84/0x40c [ 205.543075] kmem_cache_free+0x1c8/0x2a0 [ 205.547030] __kfree_skb+0xb0/0xbc [ 205.550465] consume_skb+0x164/0x178 [ 205.554079] __dev_kfree_skb_any+0x58/0x64 [ 205.558304] mwifiex_free_cmd_buffer+0xa0/0x158 [mwifiex] [ 205.563817] mwifiex_shutdown_drv+0x578/0x5c4 [mwifiex] [ 205.569164] mwifiex_shutdown_sw+0x178/0x310 [mwifiex] [ 205.574353] mwifiex_pcie_reset_notify+0xd4/0x15c [mwifiex_pcie] [ 205.580398] pci_reset_notify+0x5c/0x6c [ 205.584274] pci_dev_save_and_disable+0x24/0x6c [ 205.588837] pci_reset_function+0x30/0x7c [ 205.592885] reset_store+0x68/0x98 [ 205.596324] dev_attr_store+0x54/0x60 [ 205.600017] sysfs_kf_write+0x9c/0xb0 ... [ 205.800488] Call trace: [ 205.802980] [<ffffffc00020a69c>] dump_backtrace+0x0/0x190 [ 205.808415] [<ffffffc00020a96c>] show_stack+0x20/0x28 [ 205.813506] [<ffffffc0005d020c>] dump_stack+0xa4/0xcc [ 205.818598] [<ffffffc0003be44c>] print_trailer+0x158/0x168 [ 205.824120] [<ffffffc0003be5f0>] object_err+0x4c/0x5c [ 205.829210] [<ffffffc0003c45bc>] kasan_report+0x334/0x500 [ 205.834641] [<ffffffc0003c3994>] check_memory_region+0x20/0x14c [ 205.840593] [<ffffffc0003c3b14>] __asan_loadN+0x14/0x1c [ 205.845879] [<ffffffbffc46171c>] mwifiex_unmap_pci_memory.isra.14+0x4c/0x100 [mwifiex_pcie] [ 205.854282] [<ffffffbffc461864>] mwifiex_pcie_delete_cmdrsp_buf+0x94/0xa8 [mwifiex_pcie] [ 205.862421] [<ffffffbffc462028>] mwifiex_pcie_free_buffers+0x11c/0x158 [mwifiex_pcie] [ 205.870302] [<ffffffbffc4620d4>] mwifiex_pcie_down_dev+0x70/0x80 [mwifiex_pcie] [ 205.877736] [<ffffffbffc1397a8>] mwifiex_shutdown_sw+0x190/0x310 [mwifiex] [ 205.884658] [<ffffffbffc4606b4>] mwifiex_pcie_reset_notify+0xd4/0x15c [mwifiex_pcie] [ 205.892446] [<ffffffc000635f54>] pci_reset_notify+0x5c/0x6c [ 205.898048] [<ffffffc00063a044>] pci_dev_save_and_disable+0x24/0x6c [ 205.904350] [<ffffffc00063cf0c>] pci_reset_function+0x30/0x7c [ 205.910134] [<ffffffc000641118>] reset_store+0x68/0x98 [ 205.915312] [<ffffffc000771588>] dev_attr_store+0x54/0x60 [ 205.920750] [<ffffffc00046f53c>] sysfs_kf_write+0x9c/0xb0 [ 205.926182] [<ffffffc00046dfb0>] kernfs_fop_write+0x184/0x1f8 [ 205.931963] [<ffffffc0003d64f4>] __vfs_write+0x6c/0x17c [ 205.937221] [<ffffffc0003d7164>] vfs_write+0xf0/0x1c4 [ 205.942310] [<ffffffc0003d7da0>] SyS_write+0x78/0xd8 [ 205.947312] [<ffffffc000204634>] el0_svc_naked+0x24/0x28 ... [ 205.998268] ================================================================== This bug has been around in different forms for a while. It was sort of noticed in commit 955ab095 ("mwifiex: Do not kfree cmd buf while unregistering PCIe"), but it just fixed the double-free, without acknowledging the potential for use-after-free. Fixes: fc331460 ("mwifiex: use pci_alloc/free_consistent APIs for PCIe") Cc: <stable@vger.kernel.org> Signed-off-by: NBrian Norris <briannorris@chromium.org> Signed-off-by: NKalle Valo <kvalo@codeaurora.org>
-
由 Xinming Hu 提交于
A separate wifi-only firmware was download during pcie function level reset. It is in fact the tail part of wifi/bt combo firmware. Per Brian's and Dmitry's suggestion, this patch extract the wifi part from combo firmware. After that, the mrvl/pcie8997_wlan_v4.bin image in linux-firmware repo is redundant (though I guess we keep it around to support older kernels). Signed-off-by: NXinming Hu <huxm@marvell.com> Signed-off-by: NGanapathi Bhat <gbhat@marvell.com> Signed-off-by: NCathy Luo <cluo@marvell.com> Signed-off-by: NBrian Norris <briannorris@chromium.org> Signed-off-by: NKalle Valo <kvalo@codeaurora.org>
-
由 Xinming Hu 提交于
This patch correct pcie scratch register name, to keep the same with chipset side definition. Signed-off-by: NXinming Hu <huxm@marvell.com> Signed-off-by: NKalle Valo <kvalo@codeaurora.org>
-
由 Xinming Hu 提交于
mwifiex_dbg will do nothing before adapter->dev get assigned. several logs lost in this case. it can be avoided by fall back to pr_info. Signed-off-by: NXinming Hu <huxm@marvell.com> Reviewed-by: NBrian Norris <briannorris@chromium.org> Reviewed-by: NDmitry Torokhov <dtor@chromium.org> Signed-off-by: NKalle Valo <kvalo@codeaurora.org>
-
由 Xinming Hu 提交于
If wakeup interrupt handler is called, we know that the wakeup interrupt number is valid, there is no need to check it. Signed-off-by: NXinming Hu <huxm@marvell.com> Signed-off-by: NCathy Luo <cluo@marvell.com> Reviewed-by: NDmitry Torokhov <dtor@chromium.org> Reviewed-by: NBrian Norris <briannorris@chromium.org> Signed-off-by: NKalle Valo <kvalo@codeaurora.org>
-
由 Brian Norris 提交于
nl80211 provides the NL80211_SCAN_FLAG_RANDOM_ADDR for every scan request that should be randomized; the absence of such a flag means we should not randomize. However, mwifiex was stashing the latest randomization request and *always* using it for future scans, even those that didn't set the flag. Let's zero out the randomization info whenever we get a scan request without NL80211_SCAN_FLAG_RANDOM_ADDR. I'd prefer to remove priv->random_mac entirely (and plumb the randomization MAC properly through the call sequence), but the spaghetti is a little difficult to unravel here for me. Fixes: c2a8f0ff ("mwifiex: support random MAC address for scanning") Cc: <stable@vger.kernel.org> # 4.9+ Signed-off-by: NBrian Norris <briannorris@chromium.org> Signed-off-by: NKalle Valo <kvalo@codeaurora.org>
-
- 14 4月, 2017 1 次提交
-
-
由 Johannes Berg 提交于
Pass the new extended ACK reporting struct to all of the generic netlink parsing functions. For now, pass NULL in almost all callers (except for some in the core.) Signed-off-by: NJohannes Berg <johannes.berg@intel.com> Signed-off-by: NDavid S. Miller <davem@davemloft.net>
-
- 13 4月, 2017 2 次提交
-
-
由 Ganapathi Bhat 提交于
We have to use start port, for TX/RX of single packet, instead of current aggregating port. This will fix SDIO CMD53(TX/RX) returning -ETIMEDOUT and halting the data path. Fixes: 0cb52aac ("mwifiex: do not set multiport flag for tx/rx single packet") Signed-off-by: NGanapathi Bhat <gbhat@marvell.com> Signed-off-by: NKalle Valo <kvalo@codeaurora.org>
-
由 Johannes Berg 提交于
Instead passing both flags, which can be NULL, and vif_params, which are never NULL, move the flags into the vif_params and use BIT(0), which is invalid from userspace, to indicate that the flags were changed. While updating all drivers, fix a small bug in wil6210 where it was setting the flags to 0 instead of leaving them unchanged. Signed-off-by: NJohannes Berg <johannes.berg@intel.com>
-
- 05 4月, 2017 6 次提交
-
-
When IEEE80211_CHAN_RADAR is set by cfg80211, passive scan must be performed. In mwifiex,active scan is performed even though flag is set from cfg80211. mwifiex_reg_apply_radar_flags() function added in this patch correctly uses radar flag. Signed-off-by: NKarthik Ananthapadmanabha <karthida@marvell.com> Signed-off-by: NAmitkumar Karwar <akarwar@marvell.com> Signed-off-by: NGanapathi Bhat <gbhat@marvell.com> Signed-off-by: NKalle Valo <kvalo@codeaurora.org>
-
In mwifiex,IEs such as supported channels, supported operating classes 20/40 BSS COexistence are missing and also extra QOS capabilities IE is added during TDLS discovery response, TDLS setup request and TDLS setupresponse. This patch adds require IEs and also removes extra IE. Signed-off-by: NKarthik Ananthapadmanabha <karthida@marvell.com> Signed-off-by: NGanapathi Bhat <gbhat@marvell.com> Signed-off-by: NKalle Valo <kvalo@codeaurora.org>
-
由 Brian Norris 提交于
When resetting the device, we take a synchronous firmware-loading code path, which borrows a lot from the asynchronous path used at probe time. We don't catch errors correctly though, which means that in the PCIe driver, we may try to dereference the 'adapter' struct after mwifiex_fw_dpc() has freed it. See this (erronous) print in mwifiex_pcie_reset_notify(): mwifiex_dbg(adapter, INFO, "%s, successful\n", __func__); Let's instead refactor the synchronous (or "!req_fw_nowait") path so that we propagate errors and handle them properly. This fixes a use-after-free issue in the PCIe driver, as well as a misleading debug message ("successful"). It looks like the SDIO driver doesn't have these problems, since it doesn't do anything after mwifiex_reinit_sw(). Fixes: 4c5dae59 ("mwifiex: add PCIe function level reset support") Signed-off-by: NBrian Norris <briannorris@chromium.org> Signed-off-by: NKalle Valo <kvalo@codeaurora.org>
-
由 Brian Norris 提交于
If we fail to reinit the FW when resetting the device (in the synchronous version of mwifiex_init_hw_fw() -> mwifiex_fw_dpc()), mwifiex_fw_dpc() will tear down the interface and free up the adapter. But we don't actually check for all failure cases of mwifiex_fw_dpc(), so some of them fall through and dereference adapter->fw_done with a freed adapter, causing a use-after-free bug. In any case, mwifiex_fw_dpc() will always signal FW completion -- in the error OR success case -- so at best, this was repeat work. Let's not do it. Signed-off-by: NBrian Norris <briannorris@chromium.org> Signed-off-by: NKalle Valo <kvalo@codeaurora.org>
-
由 Amitkumar Karwar 提交于
Chip goes into low power state when this feature is enabled. This was already enabled for SDIO and PCIe interface based chipsets. Signed-off-by: NAmitkumar Karwar <akarwar@marvell.com> Signed-off-by: NKalle Valo <kvalo@codeaurora.org>
-
由 Ganapathi Bhat 提交于
USB firmware added support for sending command response/event through interrupt endpoint, to enhance RX throughput. Added corresponding changes required to support this feature. This change takes care of backward compatibility with older firmware. Signed-off-by: NGanapathi Bhat <gbhat@marvell.com> Signed-off-by: NKalle Valo <kvalo@codeaurora.org>
-
- 21 3月, 2017 1 次提交
-
-
由 Brian Norris 提交于
We observed a SHUTDOWN command timeout during reboot stress test due to a corner case firmware bug. It can lead to either a use-after-free + OOPS (on either the adapter structure, or the 'card' structure) or an abort (where, e.g., the PCI device is "disabled" before we're done dumping the FW). We can avoid this by canceling/flushing the FW dump work: (a) after we've terminated all other work queues (e.g., for processing commands which could time out) (b) after we've disabled all interrupts (which could also queue more work for us) (c) after we've unregistered the netdev and wiphy structures (and implicitly, and debugfs entries which could manually trigger FW dumps) (d) before we've actually disabled the device (e.g., pci_device_disable()) Altogether, this means no card->work will be scheduled if we sync at a point that satisfies the above. This can be done at the beginning of the .cleanup_if() callback. Signed-off-by: NBrian Norris <briannorris@chromium.org> Signed-off-by: NKalle Valo <kvalo@codeaurora.org>
-