MIMO power save support; still needs callbacks for notifying drivers
of dynamic state change in station mode.
This commit is contained in:
parent
fdabd982e7
commit
8c070d69c7
Notes:
svn2git
2020-12-20 02:59:44 +00:00
svn path=/head/; revision=183255
@ -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"
|
||||
|
@ -1236,6 +1236,32 @@ htinfo_update_chw(struct ieee80211_node *ni, int htflags)
|
||||
ni->ni_chw = IEEE80211_IS_CHAN_HT40(ni->ni_chan)? 40 : 20;
|
||||
}
|
||||
|
||||
/*
|
||||
* 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,
|
||||
|
@ -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;
|
||||
|
@ -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
|
||||
|
@ -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) ?
|
||||
|
@ -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)
|
||||
|
||||
|
@ -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) ?
|
||||
|
@ -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 *);
|
||||
|
Loading…
Reference in New Issue
Block a user