Search Linux Wireless

[PATCH v2 09/17] brcm80211: smac: modified Mac80211 callback interface

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



From: Roland Vossen <rvossen@xxxxxxxxxxxx>

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@xxxxxxxxxxxxxxxx>
Reviewed-by: Alwin Beukers <alwin@xxxxxxxxxxxx>
Reviewed-by: Arend van Spriel <arend@xxxxxxxxxxxx>
Signed-off-by: Roland Vossen <rvossen@xxxxxxxxxxxx>
Signed-off-by: Arend van Spriel <arend@xxxxxxxxxxxx>
---
 .../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 915b741..f38ba17 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)
 {
 	struct brcms_info *wl = hw->priv;
 	bool blocked;
+	int err;
 
 	ieee80211_wake_queues(hw);
 	spin_lock_bh(&wl->lock);
@@ -292,20 +293,48 @@ static int brcms_ops_start(struct ieee80211_hw *hw)
 	if (!blocked)
 		wiphy_rfkill_stop_polling(wl->pub->ieee_hw->wiphy);
 
-	return 0;
+	spin_lock_bh(&wl->lock);
+	if (!wl->pub->up)
+		err = brcms_up(wl);
+	else
+		err = -ENODEV;
+	spin_unlock_bh(&wl->lock);
+
+	if (err != 0)
+		wiphy_err(hw->wiphy, "%s: brcms_up() returned %d\n", __func__,
+			  err);
+	return err;
 }
 
 static void brcms_ops_stop(struct ieee80211_hw *hw)
 {
+	struct brcms_info *wl = hw->priv;
+	int status;
+
 	ieee80211_stop_queues(hw);
+
+	if (wl->wlc == NULL)
+		return;
+
+	spin_lock_bh(&wl->lock);
+	status = brcms_c_chipmatch(wl->wlc->hw->vendorid,
+				   wl->wlc->hw->deviceid);
+	spin_unlock_bh(&wl->lock);
+	if (!status) {
+		wiphy_err(wl->wiphy,
+			  "wl: brcms_ops_stop: chipmatch failed\n");
+		return;
+	}
+
+	/* put driver in down state */
+	spin_lock_bh(&wl->lock);
+	brcms_down(wl);
+	spin_unlock_bh(&wl->lock);
 }
 
 static int
 brcms_ops_add_interface(struct ieee80211_hw *hw, struct ieee80211_vif *vif)
 {
-	struct brcms_info *wl;
-	int err;
-
 	/* Just STA for now */
 	if (vif->type != NL80211_IFTYPE_AP &&
 	    vif->type != NL80211_IFTYPE_MESH_POINT &&
@@ -317,32 +346,12 @@ brcms_ops_add_interface(struct ieee80211_hw *hw, struct ieee80211_vif *vif)
 		return -EOPNOTSUPP;
 	}
 
-	wl = hw->priv;
-	spin_lock_bh(&wl->lock);
-	if (!wl->pub->up)
-		err = brcms_up(wl);
-	else
-		err = -ENODEV;
-	spin_unlock_bh(&wl->lock);
-
-	if (err != 0)
-		wiphy_err(hw->wiphy, "%s: brcms_up() returned %d\n", __func__,
-			  err);
-
-	return err;
+	return 0;
 }
 
 static void
 brcms_ops_remove_interface(struct ieee80211_hw *hw, struct ieee80211_vif *vif)
 {
-	struct brcms_info *wl;
-
-	wl = hw->priv;
-
-	/* put driver in down state */
-	spin_lock_bh(&wl->lock);
-	brcms_down(wl);
-	spin_unlock_bh(&wl->lock);
 }
 
 static int brcms_ops_config(struct ieee80211_hw *hw, u32 changed)
@@ -874,37 +883,18 @@ static void brcms_free(struct brcms_info *wl)
 }
 
 /*
-* called from both kernel as from this kernel module.
+* called from both kernel as from this kernel module (error flow on attach)
 * precondition: perimeter lock is not acquired.
 */
 static void brcms_remove(struct pci_dev *pdev)
 {
-	struct brcms_info *wl;
-	struct ieee80211_hw *hw;
-	int status;
-
-	hw = pci_get_drvdata(pdev);
-	wl = hw->priv;
-	if (!wl) {
-		pr_err("wl: brcms_remove: pci_get_drvdata failed\n");
-		return;
-	}
+	struct ieee80211_hw *hw = pci_get_drvdata(pdev);
+	struct brcms_info *wl = hw->priv;
 
-	spin_lock_bh(&wl->lock);
-	status = brcms_c_chipmatch(pdev->vendor, pdev->device);
-	spin_unlock_bh(&wl->lock);
-	if (!status) {
-		wiphy_err(wl->wiphy, "wl: brcms_remove: chipmatch "
-				     "failed\n");
-		return;
-	}
 	if (wl->wlc) {
 		wiphy_rfkill_set_hw_state(wl->pub->ieee_hw->wiphy, false);
 		wiphy_rfkill_stop_polling(wl->pub->ieee_hw->wiphy);
 		ieee80211_unregister_hw(hw);
-		spin_lock_bh(&wl->lock);
-		brcms_down(wl);
-		spin_unlock_bh(&wl->lock);
 	}
 	pci_disable_device(pdev);
 
-- 
1.7.4.1


--
To unsubscribe from this list: send the line "unsubscribe linux-wireless" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[Index of Archives]     [Linux Host AP]     [ATH6KL]     [Linux Bluetooth]     [Linux Netdev]     [Kernel Newbies]     [Linux Kernel]     [IDE]     [Security]     [Git]     [Netfilter]     [Bugtraq]     [Yosemite News]     [MIPS Linux]     [ARM Linux]     [Linux Security]     [Linux RAID]     [Linux ATA RAID]     [Samba]     [Device Mapper]
  Powered by Linux