aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/wireless/brcm80211
diff options
context:
space:
mode:
authorRoland Vossen <rvossen@broadcom.com>2011-10-21 10:16:27 -0400
committerJohn W. Linville <linville@tuxdriver.com>2011-11-08 15:54:20 -0500
commit2646c46d56792bdb370784d1cd6e696a7b3bbf67 (patch)
tree4a3b4b842a71590868486a00d39b01b09ec1559b /drivers/net/wireless/brcm80211
parentc6c44893c864429a7c6a4f7942dfb3ee182b4ad1 (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.c84
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
298static void brcms_ops_stop(struct ieee80211_hw *hw) 309static 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
303static int 335static int
304brcms_ops_add_interface(struct ieee80211_hw *hw, struct ieee80211_vif *vif) 336brcms_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
335static void 352static void
336brcms_ops_remove_interface(struct ieee80211_hw *hw, struct ieee80211_vif *vif) 353brcms_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
348static int brcms_ops_config(struct ieee80211_hw *hw, u32 changed) 357static 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*/
880static void brcms_remove(struct pci_dev *pdev) 889static 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