Skip to content

Instantly share code, notes, and snippets.

@codedwrench
Last active October 1, 2020 14:47
Show Gist options
  • Save codedwrench/8d7916d63993574e1dd089a62dd523a9 to your computer and use it in GitHub Desktop.
Save codedwrench/8d7916d63993574e1dd089a62dd523a9 to your computer and use it in GitHub Desktop.
b43_fix_monitor_mode
diff --git a/drivers/net/wireless/broadcom/b43/main.c b/drivers/net/wireless/broadcom/b43/main.c
index a54dd4f7f..c2559adca 100644
--- a/drivers/net/wireless/broadcom/b43/main.c
+++ b/drivers/net/wireless/broadcom/b43/main.c
@@ -113,6 +113,10 @@ static int modparam_allhwsupport = !IS_ENABLED(CONFIG_BRCMSMAC);
module_param_named(allhwsupport, modparam_allhwsupport, int, 0444);
MODULE_PARM_DESC(allhwsupport, "Enable support for all hardware (even it if overlaps with the brcmsmac driver)");
+static int modparam_forcemonitor = 0;
+module_param_named(forcemonitor, modparam_forcemonitor, int, 0444);
+MODULE_PARM_DESC(forcemonitor, "Force monitor mode");
+
#ifdef CONFIG_B43_BCMA
static const struct bcma_device_id b43_bcma_tbl[] = {
BCMA_CORE(BCMA_MANUF_BCM, BCMA_CORE_80211, 0x11, BCMA_ANY_CLASS),
@@ -3116,6 +3120,8 @@ static void b43_adjust_opmode(struct b43_wldev *dev)
ctl |= B43_MACCTL_KEEP_BAD;
if (wl->filter_flags & FIF_PLCPFAIL)
ctl |= B43_MACCTL_KEEP_BADPLCP;
+ if (wl->filter_flags & FIF_PROMISC_IN_BSS)
+ ctl |= B43_MACCTL_PROMISC;
if (wl->filter_flags & FIF_BCN_PRBRESP_PROMISC)
ctl |= B43_MACCTL_BEACPROMISC;
@@ -4000,6 +4006,21 @@ static int b43_op_config(struct ieee80211_hw *hw, u32 changed)
b43_switch_channel(dev, phy->channel);
}
+ if (changed & IEEE80211_CONF_CHANGE_MONITOR) {
+ if (conf->flags & IEEE80211_CONF_MONITOR) {
+ printk("Monitor mode is enabled\n");
+ dev->wl->radiotap_enabled = true;
+ } else {
+ printk("Monitor mode is disabled\n");
+ dev->wl->radiotap_enabled = false;
+ }
+ }
+
+ if(modparam_forcemonitor) {
+ printk("Monitor mode forced\n");
+ dev->wl->radiotap_enabled = true;
+ }
+
if (changed & IEEE80211_CONF_CHANGE_RETRY_LIMITS)
b43_set_retry_limits(dev, conf->short_frame_max_tx_count,
conf->long_frame_max_tx_count);
@@ -4295,14 +4316,16 @@ static void b43_op_configure_filter(struct ieee80211_hw *hw,
FIF_PLCPFAIL |
FIF_CONTROL |
FIF_OTHER_BSS |
- FIF_BCN_PRBRESP_PROMISC;
+ FIF_BCN_PRBRESP_PROMISC |
+ FIF_PROMISC_IN_BSS;
changed &= FIF_ALLMULTI |
FIF_FCSFAIL |
FIF_PLCPFAIL |
FIF_CONTROL |
FIF_OTHER_BSS |
- FIF_BCN_PRBRESP_PROMISC;
+ FIF_BCN_PRBRESP_PROMISC |
+ FIF_PROMISC_IN_BSS;
wl->filter_flags = *fflags;
diff --git a/drivers/net/wireless/broadcom/b43/xmit.c b/drivers/net/wireless/broadcom/b43/xmit.c
index 7651b1bdb..e7d44cbdf 100644
--- a/drivers/net/wireless/broadcom/b43/xmit.c
+++ b/drivers/net/wireless/broadcom/b43/xmit.c
@@ -396,10 +396,16 @@ int b43_generate_txhdr(struct b43_wldev *dev,
rates = info->control.rates;
/* MAC control */
- if (!(info->flags & IEEE80211_TX_CTL_NO_ACK))
+ /* dev->wl->if_type returns IEEE80211_IF_TYPE_INVALID instead of
+ * IEEE80211_IF_TYPE_MNTR for monitor interfaces, as monitor mode
+ * is not considered "operating" by mac80211.
+ */
+ if (dev->wl->if_type != 5 && dev->wl->if_type != 0 &&
+ !(info->flags & IEEE80211_TX_CTL_NO_ACK))
mac_ctl |= B43_TXH_MAC_ACK;
/* use hardware sequence counter as the non-TID counter */
- if (info->flags & IEEE80211_TX_CTL_ASSIGN_SEQ)
+ if (dev->wl->if_type != 5 && dev->wl->if_type != 0 &&
+ info->flags & IEEE80211_TX_CTL_ASSIGN_SEQ)
mac_ctl |= B43_TXH_MAC_HWSEQ;
if (info->flags & IEEE80211_TX_CTL_FIRST_FRAGMENT)
mac_ctl |= B43_TXH_MAC_STMSDU;
@@ -749,7 +755,8 @@ void b43_rx(struct b43_wldev *dev, struct sk_buff *skb, const void *_rxhdr)
/* PLCP seems to be corrupted.
* Drop the frame, if we are not interested in corrupted frames. */
if (!(dev->wl->filter_flags & FIF_PLCPFAIL))
- goto drop;
+ if((!dev->wl->radiotap_enabled) && !(dev->wl->filter_flags & FIF_PROMISC_IN_BSS))
+ goto drop;
}
status.rate_idx = rate_idx;
status.antenna = !!(phystat0 & B43_RX_PHYST0_ANT);
@@ -800,6 +807,7 @@ void b43_rx(struct b43_wldev *dev, struct sk_buff *skb, const void *_rxhdr)
break;
default:
B43_WARN_ON(1);
+ if ((!dev->wl->radiotap_enabled) && !(dev->wl->filter_flags & FIF_PROMISC_IN_BSS))
goto drop;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment