diff options
author | sam <sam@FreeBSD.org> | 2008-09-21 23:59:14 +0000 |
---|---|---|
committer | sam <sam@FreeBSD.org> | 2008-09-21 23:59:14 +0000 |
commit | 7b36216c91f1e4ec39b40c68ee415df5c327919c (patch) | |
tree | 7bd20b90da680e15e9b19b05542ecd4a6abe71ad /sys/net80211 | |
parent | b823d18ca491ab2a0d4996a20a7368650e7d7715 (diff) | |
download | FreeBSD-src-7b36216c91f1e4ec39b40c68ee415df5c327919c.zip FreeBSD-src-7b36216c91f1e4ec39b40c68ee415df5c327919c.tar.gz |
MIMO power save support; still needs callbacks for notifying drivers
of dynamic state change in station mode.
Diffstat (limited to 'sys/net80211')
-rw-r--r-- | sys/net80211/ieee80211_ddb.c | 2 | ||||
-rw-r--r-- | sys/net80211/ieee80211_ht.c | 52 | ||||
-rw-r--r-- | sys/net80211/ieee80211_ioctl.c | 25 | ||||
-rw-r--r-- | sys/net80211/ieee80211_ioctl.h | 1 | ||||
-rw-r--r-- | sys/net80211/ieee80211_node.c | 4 | ||||
-rw-r--r-- | sys/net80211/ieee80211_node.h | 5 | ||||
-rw-r--r-- | sys/net80211/ieee80211_sta.c | 4 | ||||
-rw-r--r-- | sys/net80211/ieee80211_var.h | 1 |
8 files changed, 88 insertions, 6 deletions
diff --git a/sys/net80211/ieee80211_ddb.c b/sys/net80211/ieee80211_ddb.c index 9dcb7ed..2b49004 100644 --- a/sys/net80211/ieee80211_ddb.c +++ b/sys/net80211/ieee80211_ddb.c @@ -90,7 +90,7 @@ __FBSDID("$FreeBSD$"); #define IEEE80211_NODE_BITS \ "\20\1AUTH\2QOS\3ERP\5PWR_MGT\6AREF\7HT\10HTCOMPAT\11WPS\12TSN" \ - "\13AMPDU_RX\14AMPDU_TX" + "\13AMPDU_RX\14AMPDU_TX\15MIMO_PS\16MIMO_RTS" #define IEEE80211_ERP_BITS \ "\20\1NON_ERP_PRESENT\2USE_PROTECTION\3LONG_PREAMBLE" diff --git a/sys/net80211/ieee80211_ht.c b/sys/net80211/ieee80211_ht.c index 827336b..1f0ad17 100644 --- a/sys/net80211/ieee80211_ht.c +++ b/sys/net80211/ieee80211_ht.c @@ -1237,6 +1237,32 @@ htinfo_update_chw(struct ieee80211_node *ni, int htflags) } /* + * Update 11n MIMO PS state according to received htcap. + */ +static __inline int +htcap_update_mimo_ps(struct ieee80211_node *ni) +{ + uint16_t oflags = ni->ni_flags; + + switch (ni->ni_htcap & IEEE80211_HTCAP_SMPS) { + case IEEE80211_HTCAP_SMPS_DYNAMIC: + ni->ni_flags |= IEEE80211_NODE_MIMO_PS; + ni->ni_flags |= IEEE80211_NODE_MIMO_RTS; + break; + case IEEE80211_HTCAP_SMPS_ENA: + ni->ni_flags |= IEEE80211_NODE_MIMO_PS; + ni->ni_flags &= ~IEEE80211_NODE_MIMO_RTS; + break; + case IEEE80211_HTCAP_SMPS_OFF: + default: /* disable on rx of reserved value */ + ni->ni_flags &= ~IEEE80211_NODE_MIMO_PS; + ni->ni_flags &= ~IEEE80211_NODE_MIMO_RTS; + break; + } + return (oflags ^ ni->ni_flags); +} + +/* * Parse and update HT-related state extracted from * the HT cap and info ie's. */ @@ -1249,6 +1275,8 @@ ieee80211_ht_updateparams(struct ieee80211_node *ni, int htflags; ieee80211_parse_htcap(ni, htcapie); + if (vap->iv_htcaps & IEEE80211_HTCAP_SMPS) + htcap_update_mimo_ps(ni); if (htinfoie[0] == IEEE80211_ELEMID_VENDOR) htinfoie += 4; @@ -1279,6 +1307,8 @@ ieee80211_ht_updatehtcap(struct ieee80211_node *ni, const uint8_t *htcapie) int htflags; ieee80211_parse_htcap(ni, htcapie); + if (vap->iv_htcaps & IEEE80211_HTCAP_SMPS) + htcap_update_mimo_ps(ni); /* NB: honor operating mode constraint */ /* XXX 40 MHZ intolerant */ @@ -1660,11 +1690,29 @@ ieee80211_recv_action(struct ieee80211_node *ni, /* XXX notify on change */ } break; - case IEEE80211_ACTION_HT_MIMOPWRSAVE: + case IEEE80211_ACTION_HT_MIMOPWRSAVE: { + const struct ieee80211_action_ht_mimopowersave *mps = + (const struct ieee80211_action_ht_mimopowersave *) ia; + /* XXX check iv_htcaps */ + if (mps->am_control & IEEE80211_A_HT_MIMOPWRSAVE_ENA) + ni->ni_flags |= IEEE80211_NODE_MIMO_PS; + else + ni->ni_flags &= ~IEEE80211_NODE_MIMO_PS; + if (mps->am_control & IEEE80211_A_HT_MIMOPWRSAVE_MODE) + ni->ni_flags |= IEEE80211_NODE_MIMO_RTS; + else + ni->ni_flags &= ~IEEE80211_NODE_MIMO_RTS; + /* XXX notify on change */ IEEE80211_NOTE(vap, IEEE80211_MSG_ACTION | IEEE80211_MSG_11N, ni, - "%s: HT MIMO PS", __func__); + "%s: HT MIMO PS (%s%s)", __func__, + (ni->ni_flags & IEEE80211_NODE_MIMO_PS) ? + "on" : "off", + (ni->ni_flags & IEEE80211_NODE_MIMO_RTS) ? + "+rts" : "" + ); break; + } default: IEEE80211_NOTE(vap, IEEE80211_MSG_ACTION | IEEE80211_MSG_11N, ni, diff --git a/sys/net80211/ieee80211_ioctl.c b/sys/net80211/ieee80211_ioctl.c index 3d2697c..8bfcdb8 100644 --- a/sys/net80211/ieee80211_ioctl.c +++ b/sys/net80211/ieee80211_ioctl.c @@ -1068,6 +1068,18 @@ ieee80211_ioctl_get80211(struct ieee80211vap *vap, u_long cmd, case IEEE80211_IOC_STA_VLAN: error = ieee80211_ioctl_getstavlan(vap, ireq); break; + case IEEE80211_IOC_SMPS: + if (vap->iv_opmode == IEEE80211_M_STA && + vap->iv_state == IEEE80211_S_RUN) { + if (vap->iv_bss->ni_flags & IEEE80211_NODE_MIMO_RTS) + ireq->i_val = IEEE80211_HTCAP_SMPS_DYNAMIC; + else if (vap->iv_bss->ni_flags & IEEE80211_NODE_MIMO_PS) + ireq->i_val = IEEE80211_HTCAP_SMPS_ENA; + else + ireq->i_val = IEEE80211_HTCAP_SMPS_OFF; + } else + ireq->i_val = vap->iv_htcaps & IEEE80211_HTCAP_SMPS; + break; default: error = EINVAL; break; @@ -3068,6 +3080,19 @@ ieee80211_ioctl_set80211(struct ieee80211vap *vap, u_long cmd, struct ieee80211r case IEEE80211_IOC_STA_VLAN: error = ieee80211_ioctl_setstavlan(vap, ireq); break; + case IEEE80211_IOC_SMPS: + if ((ireq->i_val &~ IEEE80211_HTCAP_SMPS) != 0 || + ireq->i_val == 0x0008) /* value of 2 is reserved */ + return EINVAL; + if (ireq->i_val != IEEE80211_HTCAP_SMPS_OFF && + (vap->iv_htcaps & IEEE80211_HTC_SMPS) == 0) + return EOPNOTSUPP; + vap->iv_htcaps = (vap->iv_htcaps &~ IEEE80211_HTCAP_SMPS) | + ireq->i_val; + /* NB: if not operating in 11n this can wait */ + if (isvapht(vap)) + error = ERESTART; + break; default: error = EINVAL; break; diff --git a/sys/net80211/ieee80211_ioctl.h b/sys/net80211/ieee80211_ioctl.h index f5eef26..0efd180 100644 --- a/sys/net80211/ieee80211_ioctl.h +++ b/sys/net80211/ieee80211_ioctl.h @@ -609,6 +609,7 @@ struct ieee80211req { #define IEEE80211_IOC_ROAM 107 /* roaming params en masse */ #define IEEE80211_IOC_TXPARAMS 108 /* tx parameters */ #define IEEE80211_IOC_STA_VLAN 109 /* per-station vlan tag */ +#define IEEE80211_IOC_SMPS 110 /* MIMO power save */ /* * Parameters for controlling a scan requested with diff --git a/sys/net80211/ieee80211_node.c b/sys/net80211/ieee80211_node.c index eb607c6..790c383 100644 --- a/sys/net80211/ieee80211_node.c +++ b/sys/net80211/ieee80211_node.c @@ -2264,7 +2264,7 @@ ieee80211_node_join(struct ieee80211_node *ni, int resp) newassoc = 0; IEEE80211_NOTE(vap, IEEE80211_MSG_ASSOC | IEEE80211_MSG_DEBUG, ni, - "station associated at aid %d: %s preamble, %s slot time%s%s%s%s%s%s", + "station associated at aid %d: %s preamble, %s slot time%s%s%s%s%s%s%s", IEEE80211_NODE_AID(ni), ic->ic_flags & IEEE80211_F_SHPREAMBLE ? "short" : "long", ic->ic_flags & IEEE80211_F_SHSLOT ? "short" : "long", @@ -2273,6 +2273,8 @@ ieee80211_node_join(struct ieee80211_node *ni, int resp) ni->ni_flags & IEEE80211_NODE_HT ? (ni->ni_chw == 40 ? ", HT40" : ", HT20") : "", ni->ni_flags & IEEE80211_NODE_AMPDU ? " (+AMPDU)" : "", + ni->ni_flags & IEEE80211_NODE_MIMO_RTS ? " (+SMPS-DYN)" : + ni->ni_flags & IEEE80211_NODE_MIMO_PS ? " (+SMPS)" : "", IEEE80211_ATH_CAP(vap, ni, IEEE80211_NODE_FF) ? ", fast-frames" : "", IEEE80211_ATH_CAP(vap, ni, IEEE80211_NODE_TURBOP) ? diff --git a/sys/net80211/ieee80211_node.h b/sys/net80211/ieee80211_node.h index fb74736..1d104d1 100644 --- a/sys/net80211/ieee80211_node.h +++ b/sys/net80211/ieee80211_node.h @@ -112,6 +112,8 @@ struct ieee80211_node { #define IEEE80211_NODE_TSN 0x000200 /* TSN association */ #define IEEE80211_NODE_AMPDU_RX 0x000400 /* AMPDU rx enabled */ #define IEEE80211_NODE_AMPDU_TX 0x000800 /* AMPDU tx enabled */ +#define IEEE80211_NODE_MIMO_PS 0x001000 /* MIMO power save enabled */ +#define IEEE80211_NODE_MIMO_RTS 0x002000 /* send RTS in MIMO PS */ uint16_t ni_associd; /* association ID */ uint16_t ni_vlan; /* vlan tag */ uint16_t ni_txpower; /* current transmit power */ @@ -195,7 +197,8 @@ MALLOC_DECLARE(M_80211_NODE_IE); (IEEE80211_NODE_AMPDU_RX | IEEE80211_NODE_AMPDU_TX) #define IEEE80211_NODE_HT_ALL \ (IEEE80211_NODE_HT | IEEE80211_NODE_HTCOMPAT | \ - IEEE80211_NODE_AMPDU) + IEEE80211_NODE_AMPDU | IEEE80211_NODE_MIMO_PS | \ + IEEE80211_NODE_MIMO_RTS) #define IEEE80211_NODE_AID(ni) IEEE80211_AID(ni->ni_associd) diff --git a/sys/net80211/ieee80211_sta.c b/sys/net80211/ieee80211_sta.c index 3010965..232e67a 100644 --- a/sys/net80211/ieee80211_sta.c +++ b/sys/net80211/ieee80211_sta.c @@ -1538,7 +1538,7 @@ sta_recv_mgmt(struct ieee80211_node *ni, struct mbuf *m0, ic->ic_flags &= ~IEEE80211_F_USEPROT; IEEE80211_NOTE_MAC(vap, IEEE80211_MSG_ASSOC | IEEE80211_MSG_DEBUG, wh->i_addr2, - "%sassoc success at aid %d: %s preamble, %s slot time%s%s%s%s%s%s", + "%sassoc success at aid %d: %s preamble, %s slot time%s%s%s%s%s%s%s", ISREASSOC(subtype) ? "re" : "", IEEE80211_NODE_AID(ni), ic->ic_flags&IEEE80211_F_SHPREAMBLE ? "short" : "long", @@ -1548,6 +1548,8 @@ sta_recv_mgmt(struct ieee80211_node *ni, struct mbuf *m0, ni->ni_flags & IEEE80211_NODE_HT ? (ni->ni_chw == 40 ? ", HT40" : ", HT20") : "", ni->ni_flags & IEEE80211_NODE_AMPDU ? " (+AMPDU)" : "", + ni->ni_flags & IEEE80211_NODE_MIMO_RTS ? " (+SMPS-DYN)" : + ni->ni_flags & IEEE80211_NODE_MIMO_PS ? " (+SMPS)" : "", IEEE80211_ATH_CAP(vap, ni, IEEE80211_NODE_FF) ? ", fast-frames" : "", IEEE80211_ATH_CAP(vap, ni, IEEE80211_NODE_TURBOP) ? diff --git a/sys/net80211/ieee80211_var.h b/sys/net80211/ieee80211_var.h index 5334d1e..ab2cbe4 100644 --- a/sys/net80211/ieee80211_var.h +++ b/sys/net80211/ieee80211_var.h @@ -534,6 +534,7 @@ MALLOC_DECLARE(M_80211_VAP); #define IEEE80211_HTC_AMSDU 0x00020000 /* CAPABILITY: A-MSDU tx */ /* NB: HT40 is implied by IEEE80211_HTCAP_CHWIDTH40 */ #define IEEE80211_HTC_HT 0x00040000 /* CAPABILITY: HT operation */ +#define IEEE80211_HTC_SMPS 0x00080000 /* CAPABILITY: MIMO power save*/ void ieee80211_ifattach(struct ieee80211com *); void ieee80211_ifdetach(struct ieee80211com *); |