brcm80211: smac: mute transmit on ops_start
authorRoland Vossen <rvossen@broadcom.com>
Fri, 21 Oct 2011 14:16:28 +0000 (16:16 +0200)
committerJohn W. Linville <linville@tuxdriver.com>
Tue, 8 Nov 2011 20:54:21 +0000 (15:54 -0500)
Monitor mode functionality (not functional yet) requires transmit to be
muted after ops_start() is called, transmit is unmuted when the first
interface is added.

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>
drivers/net/wireless/brcm80211/brcmsmac/mac80211_if.c
drivers/net/wireless/brcm80211/brcmsmac/mac80211_if.h
drivers/net/wireless/brcm80211/brcmsmac/main.c
drivers/net/wireless/brcm80211/brcmsmac/pub.h

index f38ba17c2ebda0c3c9a95824edba6762ff7a46fe..824c608d8541afdc49f4972b852ab7a7206e3113 100644 (file)
@@ -294,6 +294,9 @@ static int brcms_ops_start(struct ieee80211_hw *hw)
                wiphy_rfkill_stop_polling(wl->pub->ieee_hw->wiphy);
 
        spin_lock_bh(&wl->lock);
+       /* avoid acknowledging frames before a non-monitor device is added */
+       wl->mute_tx = true;
+
        if (!wl->pub->up)
                err = brcms_up(wl);
        else
@@ -335,6 +338,8 @@ static void brcms_ops_stop(struct ieee80211_hw *hw)
 static int
 brcms_ops_add_interface(struct ieee80211_hw *hw, struct ieee80211_vif *vif)
 {
+       struct brcms_info *wl = hw->priv;
+
        /* Just STA for now */
        if (vif->type != NL80211_IFTYPE_AP &&
            vif->type != NL80211_IFTYPE_MESH_POINT &&
@@ -346,6 +351,9 @@ brcms_ops_add_interface(struct ieee80211_hw *hw, struct ieee80211_vif *vif)
                return -EOPNOTSUPP;
        }
 
+       wl->mute_tx = false;
+       brcms_c_mute(wl->wlc, false);
+
        return 0;
 }
 
@@ -1303,8 +1311,7 @@ void brcms_init(struct brcms_info *wl)
 {
        BCMMSG(wl->pub->ieee_hw->wiphy, "wl%d\n", wl->pub->unit);
        brcms_reset(wl);
-
-       brcms_c_init(wl->wlc);
+       brcms_c_init(wl->wlc, wl->mute_tx);
 }
 
 /*
index 5c279c0a898c762448d4a38844eeb88887c2087e..6242f188b717d4e6c7a1cf3d7f30043a00fc1c29 100644 (file)
@@ -80,6 +80,7 @@ struct brcms_info {
        struct brcms_firmware fw;
        struct wiphy *wiphy;
        struct brcms_ucode ucode;
+       bool mute_tx;
 };
 
 /* misc callbacks */
index cc74205708eda44191c8104faa6201707c9a8a0f..3f8a6c7d7a2366f3427af13ddad19f128357ef74 100644 (file)
@@ -2396,6 +2396,7 @@ void brcms_c_intrsrestore(struct brcms_c_info *wlc, u32 macintmask)
        W_REG(&wlc_hw->regs->macintmask, wlc->macintmask);
 }
 
+/* assumes that the d11 MAC is enabled */
 static void brcms_b_tx_fifo_suspend(struct brcms_hardware *wlc_hw,
                                    uint tx_fifo)
 {
@@ -2487,6 +2488,12 @@ static void brcms_b_mute(struct brcms_hardware *wlc_hw, bool mute_tx)
                brcms_c_ucode_mute_override_clear(wlc_hw);
 }
 
+void
+brcms_c_mute(struct brcms_c_info *wlc, bool mute_tx)
+{
+       brcms_b_mute(wlc->hw, mute_tx);
+}
+
 /*
  * Read and clear macintmask and macintstatus and intstatus registers.
  * This routine should be called with interrupts off
@@ -8253,11 +8260,10 @@ bool brcms_c_dpc(struct brcms_c_info *wlc, bool bounded)
        return wlc->macintstatus != 0;
 }
 
-void brcms_c_init(struct brcms_c_info *wlc)
+void brcms_c_init(struct brcms_c_info *wlc, bool mute_tx)
 {
        struct d11regs __iomem *regs;
        u16 chanspec;
-       bool mute_tx = false;
 
        BCMMSG(wlc->wiphy, "wl%d\n", wlc->pub->unit);
 
index 97b9cce630819f231ff399692ac54d267de09c9d..022523a5a5321b26e0b17f824d7b3f023d1951ad 100644 (file)
@@ -540,7 +540,7 @@ extern int brcms_c_up(struct brcms_c_info *wlc);
 extern uint brcms_c_down(struct brcms_c_info *wlc);
 
 extern bool brcms_c_chipmatch(u16 vendor, u16 device);
-extern void brcms_c_init(struct brcms_c_info *wlc);
+extern void brcms_c_init(struct brcms_c_info *wlc, bool mute_tx);
 extern void brcms_c_reset(struct brcms_c_info *wlc);
 
 extern void brcms_c_intrson(struct brcms_c_info *wlc);
@@ -597,5 +597,6 @@ extern void brcms_c_set_beacon_listen_interval(struct brcms_c_info *wlc,
 extern int brcms_c_set_tx_power(struct brcms_c_info *wlc, int txpwr);
 extern int brcms_c_get_tx_power(struct brcms_c_info *wlc);
 extern bool brcms_c_check_radio_disabled(struct brcms_c_info *wlc);
+extern void brcms_c_mute(struct brcms_c_info *wlc, bool on);
 
 #endif                         /* _BRCM_PUB_H_ */