diff options
Diffstat (limited to 'freebsd/sys/net80211/ieee80211_sta.c')
-rw-r--r-- | freebsd/sys/net80211/ieee80211_sta.c | 45 |
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; + } } |