brcmsmac: fix deadlock on missing firmware
authorEmil Goode <emilgoode@gmail.com>
Sun, 9 Mar 2014 20:06:51 +0000 (21:06 +0100)
committerJohn W. Linville <linville@tuxdriver.com>
Fri, 14 Mar 2014 18:49:15 +0000 (14:49 -0400)
commit8fc1e8c240aab968db658b2d8d079b4391207a36
treecf2d7891b9ab63be0663316ef1ea07048cdf7b64
parentabee4c8414a621795bc7d4302061209a0b5d04c1
brcmsmac: fix deadlock on missing firmware

When brcm80211 firmware is not installed networking hangs.
A deadlock happens because we call ieee80211_unregister_hw()
from the .start callback of struct ieee80211_ops. When .start
is called we are under rtnl lock and ieee80211_unregister_hw()
tries to take it again.

Function call stack:

dev_change_flags()
__dev_change_flags()
__dev_open()
ASSERT_RTNL() <-- Assert rtnl lock
ops->ndo_open()

.ndo_open = ieee80211_open,

ieee80211_open()
ieee80211_do_open()
drv_start()
local->ops->start()

.start = brcms_ops_start,

brcms_ops_start()
brcms_remove()
ieee80211_unregister_hw()
rtnl_lock() <-- Here we deadlock

Introduced by:
commit 25b5632fb35ca61b8ae3eee235edcdc2883f7a5e
("brcmsmac: request firmware in .start() callback")

This patch fixes the bug by removing the call to brcms_remove()
and moves the brcms_request_fw() call to the top of the .start
callback to not initiate anything unless firmware is installed.

Signed-off-by: Emil Goode <emilgoode@gmail.com>
Signed-off-by: John W. Linville <linville@tuxdriver.com>
drivers/net/wireless/brcm80211/brcmsmac/mac80211_if.c