brcm80211: smac: added support for mac80211 filter flags
Added support for handling FIF_PROMISC_IN_BSS, FIF_FCSFAIL, FIF_CONTROL, FIF_OTHER_BSS and FIF_PSPOLL. Reviewed-by: Pieter-Paul Giesberts <pieterpg@broadcom.com> Reviewed-by: Arend van Spriel <arend@broadcom.com> Signed-off-by: Alwin Beukers <alwin@broadcom.com> Signed-off-by: Franky Lin <frankyl@broadcom.com> Signed-off-by: John W. Linville <linville@tuxdriver.com>
This commit is contained in:
Родитель
8906c43cb1
Коммит
be667669ec
|
@ -40,10 +40,10 @@
|
||||||
#define MAC_FILTERS (FIF_PROMISC_IN_BSS | \
|
#define MAC_FILTERS (FIF_PROMISC_IN_BSS | \
|
||||||
FIF_ALLMULTI | \
|
FIF_ALLMULTI | \
|
||||||
FIF_FCSFAIL | \
|
FIF_FCSFAIL | \
|
||||||
FIF_PLCPFAIL | \
|
|
||||||
FIF_CONTROL | \
|
FIF_CONTROL | \
|
||||||
FIF_OTHER_BSS | \
|
FIF_OTHER_BSS | \
|
||||||
FIF_BCN_PRBRESP_PROMISC)
|
FIF_BCN_PRBRESP_PROMISC | \
|
||||||
|
FIF_PSPOLL)
|
||||||
|
|
||||||
#define CHAN2GHZ(channel, freqency, chflags) { \
|
#define CHAN2GHZ(channel, freqency, chflags) { \
|
||||||
.band = IEEE80211_BAND_2GHZ, \
|
.band = IEEE80211_BAND_2GHZ, \
|
||||||
|
@ -373,7 +373,7 @@ static int brcms_ops_config(struct ieee80211_hw *hw, u32 changed)
|
||||||
conf->listen_interval);
|
conf->listen_interval);
|
||||||
}
|
}
|
||||||
if (changed & IEEE80211_CONF_CHANGE_MONITOR)
|
if (changed & IEEE80211_CONF_CHANGE_MONITOR)
|
||||||
wiphy_err(wiphy, "%s: change monitor mode: %s (implement)\n",
|
wiphy_dbg(wiphy, "%s: change monitor mode: %s\n",
|
||||||
__func__, conf->flags & IEEE80211_CONF_MONITOR ?
|
__func__, conf->flags & IEEE80211_CONF_MONITOR ?
|
||||||
"true" : "false");
|
"true" : "false");
|
||||||
if (changed & IEEE80211_CONF_CHANGE_PS)
|
if (changed & IEEE80211_CONF_CHANGE_PS)
|
||||||
|
@ -550,29 +550,25 @@ brcms_ops_configure_filter(struct ieee80211_hw *hw,
|
||||||
|
|
||||||
changed_flags &= MAC_FILTERS;
|
changed_flags &= MAC_FILTERS;
|
||||||
*total_flags &= MAC_FILTERS;
|
*total_flags &= MAC_FILTERS;
|
||||||
|
|
||||||
if (changed_flags & FIF_PROMISC_IN_BSS)
|
if (changed_flags & FIF_PROMISC_IN_BSS)
|
||||||
wiphy_err(wiphy, "FIF_PROMISC_IN_BSS\n");
|
wiphy_dbg(wiphy, "FIF_PROMISC_IN_BSS\n");
|
||||||
if (changed_flags & FIF_ALLMULTI)
|
if (changed_flags & FIF_ALLMULTI)
|
||||||
wiphy_err(wiphy, "FIF_ALLMULTI\n");
|
wiphy_dbg(wiphy, "FIF_ALLMULTI\n");
|
||||||
if (changed_flags & FIF_FCSFAIL)
|
if (changed_flags & FIF_FCSFAIL)
|
||||||
wiphy_err(wiphy, "FIF_FCSFAIL\n");
|
wiphy_dbg(wiphy, "FIF_FCSFAIL\n");
|
||||||
if (changed_flags & FIF_PLCPFAIL)
|
|
||||||
wiphy_err(wiphy, "FIF_PLCPFAIL\n");
|
|
||||||
if (changed_flags & FIF_CONTROL)
|
if (changed_flags & FIF_CONTROL)
|
||||||
wiphy_err(wiphy, "FIF_CONTROL\n");
|
wiphy_dbg(wiphy, "FIF_CONTROL\n");
|
||||||
if (changed_flags & FIF_OTHER_BSS)
|
if (changed_flags & FIF_OTHER_BSS)
|
||||||
wiphy_err(wiphy, "FIF_OTHER_BSS\n");
|
wiphy_dbg(wiphy, "FIF_OTHER_BSS\n");
|
||||||
if (changed_flags & FIF_BCN_PRBRESP_PROMISC) {
|
if (changed_flags & FIF_PSPOLL)
|
||||||
|
wiphy_dbg(wiphy, "FIF_PSPOLL\n");
|
||||||
|
if (changed_flags & FIF_BCN_PRBRESP_PROMISC)
|
||||||
|
wiphy_dbg(wiphy, "FIF_BCN_PRBRESP_PROMISC\n");
|
||||||
|
|
||||||
spin_lock_bh(&wl->lock);
|
spin_lock_bh(&wl->lock);
|
||||||
if (*total_flags & FIF_BCN_PRBRESP_PROMISC) {
|
brcms_c_mac_promisc(wl->wlc, *total_flags);
|
||||||
wl->pub->mac80211_state |= MAC80211_PROMISC_BCNS;
|
|
||||||
brcms_c_mac_bcn_promisc_change(wl->wlc, 1);
|
|
||||||
} else {
|
|
||||||
brcms_c_mac_bcn_promisc_change(wl->wlc, 0);
|
|
||||||
wl->pub->mac80211_state &= ~MAC80211_PROMISC_BCNS;
|
|
||||||
}
|
|
||||||
spin_unlock_bh(&wl->lock);
|
spin_unlock_bh(&wl->lock);
|
||||||
}
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -3062,7 +3062,7 @@ static bool brcms_c_ps_allowed(struct brcms_c_info *wlc)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
/* disallow PS when one of these meets when not scanning */
|
/* disallow PS when one of these meets when not scanning */
|
||||||
if (wlc->monitor)
|
if (wlc->filter_flags & FIF_PROMISC_IN_BSS)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
if (cfg->associated) {
|
if (cfg->associated) {
|
||||||
|
@ -3582,31 +3582,33 @@ static void brcms_c_bandinit_ordered(struct brcms_c_info *wlc,
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Set or clear maccontrol bits MCTL_PROMISC, MCTL_BCNS_PROMISC and
|
* Set or clear filtering related maccontrol bits based on
|
||||||
* MCTL_KEEPCONTROL
|
* specified filter flags
|
||||||
*/
|
*/
|
||||||
static void brcms_c_mac_promisc(struct brcms_c_info *wlc)
|
void brcms_c_mac_promisc(struct brcms_c_info *wlc, uint filter_flags)
|
||||||
{
|
{
|
||||||
u32 promisc_bits = 0;
|
u32 promisc_bits = 0;
|
||||||
|
|
||||||
if (wlc->bcnmisc_monitor)
|
wlc->filter_flags = filter_flags;
|
||||||
|
|
||||||
|
if (filter_flags & (FIF_PROMISC_IN_BSS | FIF_OTHER_BSS))
|
||||||
|
promisc_bits |= MCTL_PROMISC;
|
||||||
|
|
||||||
|
if (filter_flags & FIF_BCN_PRBRESP_PROMISC)
|
||||||
promisc_bits |= MCTL_BCNS_PROMISC;
|
promisc_bits |= MCTL_BCNS_PROMISC;
|
||||||
|
|
||||||
if (wlc->monitor)
|
if (filter_flags & FIF_FCSFAIL)
|
||||||
promisc_bits |=
|
promisc_bits |= MCTL_KEEPBADFCS;
|
||||||
MCTL_PROMISC | MCTL_BCNS_PROMISC | MCTL_KEEPCONTROL;
|
|
||||||
|
if (filter_flags & (FIF_CONTROL | FIF_PSPOLL))
|
||||||
|
promisc_bits |= MCTL_KEEPCONTROL;
|
||||||
|
|
||||||
brcms_b_mctrl(wlc->hw,
|
brcms_b_mctrl(wlc->hw,
|
||||||
MCTL_PROMISC | MCTL_BCNS_PROMISC | MCTL_KEEPCONTROL,
|
MCTL_PROMISC | MCTL_BCNS_PROMISC |
|
||||||
|
MCTL_KEEPCONTROL | MCTL_KEEPBADFCS,
|
||||||
promisc_bits);
|
promisc_bits);
|
||||||
}
|
}
|
||||||
|
|
||||||
void brcms_c_mac_bcn_promisc_change(struct brcms_c_info *wlc, bool promisc)
|
|
||||||
{
|
|
||||||
wlc->bcnmisc_monitor = promisc;
|
|
||||||
brcms_c_mac_promisc(wlc);
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* ucode, hwmac update
|
* ucode, hwmac update
|
||||||
* Channel dependent updates for ucode and hw
|
* Channel dependent updates for ucode and hw
|
||||||
|
@ -3634,9 +3636,6 @@ static void brcms_c_ucode_mac_upd(struct brcms_c_info *wlc)
|
||||||
} else {
|
} else {
|
||||||
/* disable an active IBSS if we are not on the home channel */
|
/* disable an active IBSS if we are not on the home channel */
|
||||||
}
|
}
|
||||||
|
|
||||||
/* update the various promisc bits */
|
|
||||||
brcms_c_mac_promisc(wlc);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void brcms_c_write_rate_shm(struct brcms_c_info *wlc, u8 rate,
|
static void brcms_c_write_rate_shm(struct brcms_c_info *wlc, u8 rate,
|
||||||
|
@ -8072,14 +8071,8 @@ static void brcms_c_recv(struct brcms_c_info *wlc, struct sk_buff *p)
|
||||||
len = p->len;
|
len = p->len;
|
||||||
|
|
||||||
if (rxh->RxStatus1 & RXS_FCSERR) {
|
if (rxh->RxStatus1 & RXS_FCSERR) {
|
||||||
if (wlc->pub->mac80211_state & MAC80211_PROMISC_BCNS) {
|
if (!(wlc->filter_flags & FIF_FCSFAIL))
|
||||||
wiphy_err(wlc->wiphy, "FCSERR while scanning******* -"
|
|
||||||
" tossing\n");
|
|
||||||
goto toss;
|
goto toss;
|
||||||
} else {
|
|
||||||
wiphy_err(wlc->wiphy, "RCSERR!!!\n");
|
|
||||||
goto toss;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* check received pkt has at least frame control field */
|
/* check received pkt has at least frame control field */
|
||||||
|
|
|
@ -519,8 +519,7 @@ struct brcms_c_info {
|
||||||
struct brcms_timer *radio_timer;
|
struct brcms_timer *radio_timer;
|
||||||
|
|
||||||
/* promiscuous */
|
/* promiscuous */
|
||||||
bool monitor;
|
uint filter_flags;
|
||||||
bool bcnmisc_monitor;
|
|
||||||
|
|
||||||
/* driver feature */
|
/* driver feature */
|
||||||
bool _rifs;
|
bool _rifs;
|
||||||
|
@ -658,8 +657,7 @@ extern void brcms_c_print_txdesc(struct d11txh *txh);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
extern int brcms_c_set_gmode(struct brcms_c_info *wlc, u8 gmode, bool config);
|
extern int brcms_c_set_gmode(struct brcms_c_info *wlc, u8 gmode, bool config);
|
||||||
extern void brcms_c_mac_bcn_promisc_change(struct brcms_c_info *wlc,
|
extern void brcms_c_mac_promisc(struct brcms_c_info *wlc, uint filter_flags);
|
||||||
bool promisc);
|
|
||||||
extern void brcms_c_send_q(struct brcms_c_info *wlc);
|
extern void brcms_c_send_q(struct brcms_c_info *wlc);
|
||||||
extern int brcms_c_prep_pdu(struct brcms_c_info *wlc, struct sk_buff *pdu,
|
extern int brcms_c_prep_pdu(struct brcms_c_info *wlc, struct sk_buff *pdu,
|
||||||
uint *fifo);
|
uint *fifo);
|
||||||
|
|
Загрузка…
Ссылка в новой задаче