diff options
author | Roland Vossen <rvossen@broadcom.com> | 2011-10-21 10:16:27 -0400 |
---|---|---|
committer | John W. Linville <linville@tuxdriver.com> | 2011-11-08 15:54:20 -0500 |
commit | 2646c46d56792bdb370784d1cd6e696a7b3bbf67 (patch) | |
tree | 4a3b4b842a71590868486a00d39b01b09ec1559b /drivers/net/wireless/brcm80211 | |
parent | c6c44893c864429a7c6a4f7942dfb3ee182b4ad1 (diff) |
brcm80211: smac: modified Mac80211 callback interface
Upon ops_start(), a Mac80211 driver should enable receive functionality to
support monitor mode. Also, upon ops_stop(), it should disable rx.
Driver did not follow this rule so code has been changed.
Reported-by: Johannes Berg <johannes@sipsolutions.net>
Reviewed-by: Alwin Beukers <alwin@broadcom.com>
Reviewed-by: Arend van Spriel <arend@broadcom.com>
Signed-off-by: Roland Vossen <rvossen@broadcom.com>
Signed-off-by: Arend van Spriel <arend@broadcom.com>
Signed-off-by: John W. Linville <linville@tuxdriver.com>
Diffstat (limited to 'drivers/net/wireless/brcm80211')
-rw-r--r-- | drivers/net/wireless/brcm80211/brcmsmac/mac80211_if.c | 84 |
1 files changed, 37 insertions, 47 deletions
diff --git a/drivers/net/wireless/brcm80211/brcmsmac/mac80211_if.c b/drivers/net/wireless/brcm80211/brcmsmac/mac80211_if.c index 915b74199911..f38ba17c2ebd 100644 --- a/drivers/net/wireless/brcm80211/brcmsmac/mac80211_if.c +++ b/drivers/net/wireless/brcm80211/brcmsmac/mac80211_if.c | |||
@@ -284,6 +284,7 @@ static int brcms_ops_start(struct ieee80211_hw *hw) | |||
284 | { | 284 | { |
285 | struct brcms_info *wl = hw->priv; | 285 | struct brcms_info *wl = hw->priv; |
286 | bool blocked; | 286 | bool blocked; |
287 | int err; | ||
287 | 288 | ||
288 | ieee80211_wake_queues(hw); | 289 | ieee80211_wake_queues(hw); |
289 | spin_lock_bh(&wl->lock); | 290 | spin_lock_bh(&wl->lock); |
@@ -292,20 +293,48 @@ static int brcms_ops_start(struct ieee80211_hw *hw) | |||
292 | if (!blocked) | 293 | if (!blocked) |
293 | wiphy_rfkill_stop_polling(wl->pub->ieee_hw->wiphy); | 294 | wiphy_rfkill_stop_polling(wl->pub->ieee_hw->wiphy); |
294 | 295 | ||
295 | return 0; | 296 | spin_lock_bh(&wl->lock); |
297 | if (!wl->pub->up) | ||
298 | err = brcms_up(wl); | ||
299 | else | ||
300 | err = -ENODEV; | ||
301 | spin_unlock_bh(&wl->lock); | ||
302 | |||
303 | if (err != 0) | ||
304 | wiphy_err(hw->wiphy, "%s: brcms_up() returned %d\n", __func__, | ||
305 | err); | ||
306 | return err; | ||
296 | } | 307 | } |
297 | 308 | ||
298 | static void brcms_ops_stop(struct ieee80211_hw *hw) | 309 | static void brcms_ops_stop(struct ieee80211_hw *hw) |
299 | { | 310 | { |
311 | struct brcms_info *wl = hw->priv; | ||
312 | int status; | ||
313 | |||
300 | ieee80211_stop_queues(hw); | 314 | ieee80211_stop_queues(hw); |
315 | |||
316 | if (wl->wlc == NULL) | ||
317 | return; | ||
318 | |||
319 | spin_lock_bh(&wl->lock); | ||
320 | status = brcms_c_chipmatch(wl->wlc->hw->vendorid, | ||
321 | wl->wlc->hw->deviceid); | ||
322 | spin_unlock_bh(&wl->lock); | ||
323 | if (!status) { | ||
324 | wiphy_err(wl->wiphy, | ||
325 | "wl: brcms_ops_stop: chipmatch failed\n"); | ||
326 | return; | ||
327 | } | ||
328 | |||
329 | /* put driver in down state */ | ||
330 | spin_lock_bh(&wl->lock); | ||
331 | brcms_down(wl); | ||
332 | spin_unlock_bh(&wl->lock); | ||
301 | } | 333 | } |
302 | 334 | ||
303 | static int | 335 | static int |
304 | brcms_ops_add_interface(struct ieee80211_hw *hw, struct ieee80211_vif *vif) | 336 | brcms_ops_add_interface(struct ieee80211_hw *hw, struct ieee80211_vif *vif) |
305 | { | 337 | { |
306 | struct brcms_info *wl; | ||
307 | int err; | ||
308 | |||
309 | /* Just STA for now */ | 338 | /* Just STA for now */ |
310 | if (vif->type != NL80211_IFTYPE_AP && | 339 | if (vif->type != NL80211_IFTYPE_AP && |
311 | vif->type != NL80211_IFTYPE_MESH_POINT && | 340 | vif->type != NL80211_IFTYPE_MESH_POINT && |
@@ -317,32 +346,12 @@ brcms_ops_add_interface(struct ieee80211_hw *hw, struct ieee80211_vif *vif) | |||
317 | return -EOPNOTSUPP; | 346 | return -EOPNOTSUPP; |
318 | } | 347 | } |
319 | 348 | ||
320 | wl = hw->priv; | 349 | return 0; |
321 | spin_lock_bh(&wl->lock); | ||
322 | if (!wl->pub->up) | ||
323 | err = brcms_up(wl); | ||
324 | else | ||
325 | err = -ENODEV; | ||
326 | spin_unlock_bh(&wl->lock); | ||
327 | |||
328 | if (err != 0) | ||
329 | wiphy_err(hw->wiphy, "%s: brcms_up() returned %d\n", __func__, | ||
330 | err); | ||
331 | |||
332 | return err; | ||
333 | } | 350 | } |
334 | 351 | ||
335 | static void | 352 | static void |
336 | brcms_ops_remove_interface(struct ieee80211_hw *hw, struct ieee80211_vif *vif) | 353 | brcms_ops_remove_interface(struct ieee80211_hw *hw, struct ieee80211_vif *vif) |
337 | { | 354 | { |
338 | struct brcms_info *wl; | ||
339 | |||
340 | wl = hw->priv; | ||
341 | |||
342 | /* put driver in down state */ | ||
343 | spin_lock_bh(&wl->lock); | ||
344 | brcms_down(wl); | ||
345 | spin_unlock_bh(&wl->lock); | ||
346 | } | 355 | } |
347 | 356 | ||
348 | static int brcms_ops_config(struct ieee80211_hw *hw, u32 changed) | 357 | static int brcms_ops_config(struct ieee80211_hw *hw, u32 changed) |
@@ -874,37 +883,18 @@ static void brcms_free(struct brcms_info *wl) | |||
874 | } | 883 | } |
875 | 884 | ||
876 | /* | 885 | /* |
877 | * called from both kernel as from this kernel module. | 886 | * called from both kernel as from this kernel module (error flow on attach) |
878 | * precondition: perimeter lock is not acquired. | 887 | * precondition: perimeter lock is not acquired. |
879 | */ | 888 | */ |
880 | static void brcms_remove(struct pci_dev *pdev) | 889 | static void brcms_remove(struct pci_dev *pdev) |
881 | { | 890 | { |
882 | struct brcms_info *wl; | 891 | struct ieee80211_hw *hw = pci_get_drvdata(pdev); |
883 | struct ieee80211_hw *hw; | 892 | struct brcms_info *wl = hw->priv; |
884 | int status; | ||
885 | |||
886 | hw = pci_get_drvdata(pdev); | ||
887 | wl = hw->priv; | ||
888 | if (!wl) { | ||
889 | pr_err("wl: brcms_remove: pci_get_drvdata failed\n"); | ||
890 | return; | ||
891 | } | ||
892 | 893 | ||
893 | spin_lock_bh(&wl->lock); | ||
894 | status = brcms_c_chipmatch(pdev->vendor, pdev->device); | ||
895 | spin_unlock_bh(&wl->lock); | ||
896 | if (!status) { | ||
897 | wiphy_err(wl->wiphy, "wl: brcms_remove: chipmatch " | ||
898 | "failed\n"); | ||
899 | return; | ||
900 | } | ||
901 | if (wl->wlc) { | 894 | if (wl->wlc) { |
902 | wiphy_rfkill_set_hw_state(wl->pub->ieee_hw->wiphy, false); | 895 | wiphy_rfkill_set_hw_state(wl->pub->ieee_hw->wiphy, false); |
903 | wiphy_rfkill_stop_polling(wl->pub->ieee_hw->wiphy); | 896 | wiphy_rfkill_stop_polling(wl->pub->ieee_hw->wiphy); |
904 | ieee80211_unregister_hw(hw); | 897 | ieee80211_unregister_hw(hw); |
905 | spin_lock_bh(&wl->lock); | ||
906 | brcms_down(wl); | ||
907 | spin_unlock_bh(&wl->lock); | ||
908 | } | 898 | } |
909 | pci_disable_device(pdev); | 899 | pci_disable_device(pdev); |
910 | 900 | ||