Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 2646c46d authored by Roland Vossen's avatar Roland Vossen Committed by John W. Linville
Browse files

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: default avatarJohannes Berg <johannes@sipsolutions.net>
Reviewed-by: default avatarAlwin Beukers <alwin@broadcom.com>
Reviewed-by: default avatarArend van Spriel <arend@broadcom.com>
Signed-off-by: default avatarRoland Vossen <rvossen@broadcom.com>
Signed-off-by: default avatarArend van Spriel <arend@broadcom.com>
Signed-off-by: default avatarJohn W. Linville <linville@tuxdriver.com>
parent c6c44893
Loading
Loading
Loading
Loading
+37 −47
Original line number Diff line number Diff line
@@ -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);