summaryrefslogtreecommitdiff
path: root/freebsd/sys/net80211/ieee80211_sta.c
diff options
context:
space:
mode:
Diffstat (limited to 'freebsd/sys/net80211/ieee80211_sta.c')
-rw-r--r--freebsd/sys/net80211/ieee80211_sta.c45
1 files changed, 30 insertions, 15 deletions
diff --git a/freebsd/sys/net80211/ieee80211_sta.c b/freebsd/sys/net80211/ieee80211_sta.c
index f709d51e..c96eb0b5 100644
--- a/freebsd/sys/net80211/ieee80211_sta.c
+++ b/freebsd/sys/net80211/ieee80211_sta.c
@@ -436,7 +436,7 @@ sta_newstate(struct ieee80211vap *vap, enum ieee80211_state nstate, int arg)
goto invalid;
break;
case IEEE80211_S_SLEEP:
- ieee80211_sta_pwrsave(vap, 0);
+ ieee80211_sta_pwrsave(vap, 1);
break;
default:
invalid:
@@ -514,7 +514,6 @@ doprint(struct ieee80211vap *vap, int subtype)
static int
sta_input(struct ieee80211_node *ni, struct mbuf *m, int rssi, int nf)
{
-#define SEQ_LEQ(a,b) ((int)((a)-(b)) <= 0)
#define HAS_SEQ(type) ((type & 0x4) == 0)
struct ieee80211vap *vap = ni->ni_vap;
struct ieee80211com *ic = ni->ni_ic;
@@ -593,9 +592,7 @@ sta_input(struct ieee80211_node *ni, struct mbuf *m, int rssi, int nf)
TID_TO_WME_AC(tid) >= WME_AC_VI)
ic->ic_wme.wme_hipri_traffic++;
rxseq = le16toh(*(uint16_t *)wh->i_seq);
- if ((ni->ni_flags & IEEE80211_NODE_HT) == 0 &&
- (wh->i_fc[1] & IEEE80211_FC1_RETRY) &&
- SEQ_LEQ(rxseq, ni->ni_rxseqs[tid])) {
+ if (! ieee80211_check_rxseq(ni, wh)) {
/* duplicate, discard */
IEEE80211_DISCARD_MAC(vap, IEEE80211_MSG_INPUT,
bssid, "duplicate",
@@ -912,7 +909,6 @@ out:
m_freem(m);
}
return type;
-#undef SEQ_LEQ
}
static void
@@ -1546,7 +1542,7 @@ sta_recv_mgmt(struct ieee80211_node *ni, struct mbuf *m0,
htcap = frm;
} else if (ishtinfooui(frm)) {
if (htinfo == NULL)
- htcap = frm;
+ htinfo = frm;
}
}
/* XXX Atheros OUI support */
@@ -1720,21 +1716,35 @@ sta_recv_mgmt(struct ieee80211_node *ni, struct mbuf *m0,
}
case IEEE80211_FC0_SUBTYPE_ACTION:
- if (vap->iv_state == IEEE80211_S_RUN) {
- if (ieee80211_parse_action(ni, m0) == 0)
- ic->ic_recv_action(ni, wh, frm, efrm);
- } else
+ case IEEE80211_FC0_SUBTYPE_ACTION_NOACK:
+ if (!IEEE80211_ADDR_EQ(vap->iv_myaddr, wh->i_addr1) &&
+ !IEEE80211_IS_MULTICAST(wh->i_addr1)) {
+ IEEE80211_DISCARD(vap, IEEE80211_MSG_INPUT,
+ wh, NULL, "%s", "not for us");
vap->iv_stats.is_rx_mgtdiscard++;
+ } else if (vap->iv_state != IEEE80211_S_RUN) {
+ IEEE80211_DISCARD(vap, IEEE80211_MSG_INPUT,
+ wh, NULL, "wrong state %s",
+ ieee80211_state_name[vap->iv_state]);
+ vap->iv_stats.is_rx_mgtdiscard++;
+ } else {
+ if (ieee80211_parse_action(ni, m0) == 0)
+ (void)ic->ic_recv_action(ni, wh, frm, efrm);
+ }
break;
- case IEEE80211_FC0_SUBTYPE_PROBE_REQ:
case IEEE80211_FC0_SUBTYPE_ASSOC_REQ:
case IEEE80211_FC0_SUBTYPE_REASSOC_REQ:
+ case IEEE80211_FC0_SUBTYPE_PROBE_REQ:
+ case IEEE80211_FC0_SUBTYPE_ATIM:
+ IEEE80211_DISCARD(vap, IEEE80211_MSG_INPUT,
+ wh, NULL, "%s", "not handled");
vap->iv_stats.is_rx_mgtdiscard++;
- return;
+ break;
+
default:
IEEE80211_DISCARD(vap, IEEE80211_MSG_ANY,
- wh, "mgt", "subtype 0x%x not handled", subtype);
+ wh, "mgt", "subtype 0x%x not handled", subtype);
vap->iv_stats.is_rx_badsubtype++;
break;
}
@@ -1743,6 +1753,11 @@ sta_recv_mgmt(struct ieee80211_node *ni, struct mbuf *m0,
}
static void
-sta_recv_ctl(struct ieee80211_node *ni, struct mbuf *m0, int subtype)
+sta_recv_ctl(struct ieee80211_node *ni, struct mbuf *m, int subtype)
{
+ switch (subtype) {
+ case IEEE80211_FC0_SUBTYPE_BAR:
+ ieee80211_recv_bar(ni, m);
+ break;
+ }
}