本文整理汇总了C++中IEEE80211_NOTE函数的典型用法代码示例。如果您正苦于以下问题:C++ IEEE80211_NOTE函数的具体用法?C++ IEEE80211_NOTE怎么用?C++ IEEE80211_NOTE使用的例子?那么恭喜您, 这里精选的函数代码示例或许可以为您提供帮助。
在下文中一共展示了IEEE80211_NOTE函数的15个代码示例,这些例子默认根据受欢迎程度排序。您可以为喜欢或者感觉有用的代码点赞,您的评价将有助于系统推荐出更棒的C++代码示例。
示例1: ieee80211_node_saveq_age
/*
* Age frames on the power save queue. The aging interval is
* 4 times the listen interval specified by the station. This
* number is factored into the age calculations when the frame
* is placed on the queue. We store ages as time differences
* so we can check and/or adjust only the head of the list.
* If a frame's age exceeds the threshold then discard it.
* The number of frames discarded is returned so the caller
* can check if it needs to adjust the tim.
*/
int
ieee80211_node_saveq_age(struct ieee80211_node *ni)
{
int discard = 0;
struct node_powersave_queue *dataq,*mgtq;
struct ieee80211vap *vap=ni->ni_vap;
dataq = IEEE80211_NODE_SAVEQ_DATAQ(ni);
mgtq = IEEE80211_NODE_SAVEQ_MGMTQ(ni);
/* XXX racey but good 'nuf? */
if ((IEEE80211_NODE_SAVEQ_QLEN(dataq) != 0) ||
(IEEE80211_NODE_SAVEQ_QLEN(mgtq) != 0)) {
wbuf_t wbuf;
IEEE80211_NODE_SAVEQ_LOCK(dataq);
while (IEEE80211_NODE_SAVEQ_POLL(dataq, wbuf) != NULL &&
wbuf_get_age(wbuf) < IEEE80211_INACT_WAIT) {
struct ieee80211_tx_status ts;
ts.ts_flags = IEEE80211_TX_ERROR;
IEEE80211_NOTE(vap, IEEE80211_MSG_POWER, ni,
"discard frame, age %u \n", wbuf_get_age(wbuf));
IEEE80211_NODE_SAVEQ_DEQUEUE(dataq, wbuf);
ieee80211_release_wbuf(ni,wbuf, &ts);
discard++;
}
if (wbuf != NULL)
wbuf_set_age(wbuf, wbuf_get_age(wbuf) - IEEE80211_INACT_WAIT);
IEEE80211_NODE_SAVEQ_UNLOCK(dataq);
IEEE80211_NODE_SAVEQ_LOCK(mgtq);
while (IEEE80211_NODE_SAVEQ_POLL(mgtq, wbuf) != NULL &&
wbuf_get_age(wbuf) < IEEE80211_INACT_WAIT) {
struct ieee80211_tx_status ts;
ts.ts_flags = IEEE80211_TX_ERROR;
IEEE80211_NOTE(vap, IEEE80211_MSG_POWER, ni,
"discard mgt frame, age %u \n", wbuf_get_age(wbuf));
IEEE80211_NODE_SAVEQ_DEQUEUE(mgtq, wbuf);
ieee80211_release_wbuf(ni,wbuf, &ts);
discard++;
}
if (wbuf != NULL)
wbuf_set_age(wbuf, wbuf_get_age(wbuf) - IEEE80211_INACT_WAIT);
IEEE80211_NODE_SAVEQ_UNLOCK(mgtq);
IEEE80211_NOTE(vap, IEEE80211_MSG_POWER, ni,
"discard %u frames for age \n", discard);
IEEE80211_NODE_STAT_ADD(ni, ps_discard, discard);
}
if ((IEEE80211_NODE_SAVEQ_QLEN(dataq) == 0) &&
(IEEE80211_NODE_SAVEQ_QLEN(mgtq) == 0)) {
if (vap->iv_set_tim != NULL)
vap->iv_set_tim(ni, 0);
}
return discard;
}
示例2: amrr_update
static int
amrr_update(struct ieee80211_amrr *amrr, struct ieee80211_amrr_node *amn,
struct ieee80211_node *ni)
{
int rix = amn->amn_rix;
KASSERT(is_enough(amn), ("txcnt %d", amn->amn_txcnt));
if (is_success(amn)) {
amn->amn_success++;
if (amn->amn_success >= amn->amn_success_threshold &&
rix + 1 < ni->ni_rates.rs_nrates) {
amn->amn_recovery = 1;
amn->amn_success = 0;
rix++;
IEEE80211_NOTE(ni->ni_vap, IEEE80211_MSG_RATECTL, ni,
"AMRR increasing rate %d (txcnt=%d retrycnt=%d)",
ni->ni_rates.rs_rates[rix] & IEEE80211_RATE_VAL,
amn->amn_txcnt, amn->amn_retrycnt);
} else {
amn->amn_recovery = 0;
}
} else if (is_failure(amn)) {
amn->amn_success = 0;
if (rix > 0) {
if (amn->amn_recovery) {
amn->amn_success_threshold *= 2;
if (amn->amn_success_threshold >
amrr->amrr_max_success_threshold)
amn->amn_success_threshold =
amrr->amrr_max_success_threshold;
} else {
amn->amn_success_threshold =
amrr->amrr_min_success_threshold;
}
rix--;
IEEE80211_NOTE(ni->ni_vap, IEEE80211_MSG_RATECTL, ni,
"AMRR decreasing rate %d (txcnt=%d retrycnt=%d)",
ni->ni_rates.rs_rates[rix] & IEEE80211_RATE_VAL,
amn->amn_txcnt, amn->amn_retrycnt);
}
amn->amn_recovery = 0;
}
/* reset counters */
amn->amn_txcnt = 0;
amn->amn_retrycnt = 0;
return rix;
}
示例3: hwmp_peerdown
static void
hwmp_peerdown(struct ieee80211_node *ni)
{
struct ieee80211vap *vap = ni->ni_vap;
struct ieee80211_mesh_state *ms = vap->iv_mesh;
struct ieee80211_meshperr_ie perr;
struct ieee80211_mesh_route *rt;
struct ieee80211_hwmp_route *hr;
rt = ieee80211_mesh_rt_find(vap, ni->ni_macaddr);
if (rt == NULL)
return;
hr = IEEE80211_MESH_ROUTE_PRIV(rt, struct ieee80211_hwmp_route);
IEEE80211_NOTE(vap, IEEE80211_MSG_HWMP, ni,
"%s", "delete route entry");
perr.perr_ttl = ms->ms_ttl;
perr.perr_ndests = 1;
PERR_DFLAGS(0) = 0;
if (hr->hr_seq == 0)
PERR_DFLAGS(0) |= IEEE80211_MESHPERR_DFLAGS_USN;
PERR_DFLAGS(0) |= IEEE80211_MESHPERR_DFLAGS_RC;
IEEE80211_ADDR_COPY(PERR_DADDR(0), rt->rt_dest);
PERR_DSEQ(0) = hr->hr_seq;
PERR_DRCODE(0) = IEEE80211_REASON_MESH_PERR_DEST_UNREACH;
/* NB: flush everything passing through peer */
ieee80211_mesh_rt_flush_peer(vap, ni->ni_macaddr);
hwmp_send_perr(vap->iv_bss, vap->iv_myaddr, broadcastaddr, &perr);
}
示例4: amrr_node_init
static void
amrr_node_init(struct ieee80211_node *ni)
{
const struct ieee80211_rateset *rs = &ni->ni_rates;
struct ieee80211vap *vap = ni->ni_vap;
struct ieee80211_amrr *amrr = vap->iv_rs;
struct ieee80211_amrr_node *amn;
if (ni->ni_rctls == NULL) {
ni->ni_rctls = amn = malloc(sizeof(struct ieee80211_amrr_node),
M_80211_RATECTL, M_NOWAIT|M_ZERO);
if (amn == NULL) {
if_printf(vap->iv_ifp, "couldn't alloc per-node ratectl "
"structure\n");
return;
}
} else
amn = ni->ni_rctls;
amn->amn_amrr = amrr;
amn->amn_success = 0;
amn->amn_recovery = 0;
amn->amn_txcnt = amn->amn_retrycnt = 0;
amn->amn_success_threshold = amrr->amrr_min_success_threshold;
/* pick initial rate */
for (amn->amn_rix = rs->rs_nrates - 1;
amn->amn_rix > 0 && (rs->rs_rates[amn->amn_rix] & IEEE80211_RATE_VAL) > 72;
amn->amn_rix--)
;
ni->ni_txrate = rs->rs_rates[amn->amn_rix] & IEEE80211_RATE_VAL;
amn->amn_ticks = ticks;
IEEE80211_NOTE(ni->ni_vap, IEEE80211_MSG_RATECTL, ni,
"AMRR initial rate %d", ni->ni_txrate);
}
示例5: ieee80211_sta_pwrsave
/*
* Handle power-save state change in station mode.
*/
void
ieee80211_sta_pwrsave(struct ieee80211vap *vap, int enable)
{
struct ieee80211_node *ni = vap->iv_bss;
if (!((enable != 0) ^ ((ni->ni_flags & IEEE80211_NODE_PWR_MGT) != 0)))
return;
IEEE80211_NOTE(vap, IEEE80211_MSG_POWER, ni,
"sta power save mode %s", enable ? "on" : "off");
if (!enable) {
ni->ni_flags &= ~IEEE80211_NODE_PWR_MGT;
ieee80211_send_nulldata(ieee80211_ref_node(ni));
/*
* Flush any queued frames; we can do this immediately
* because we know they'll be queued behind the null
* data frame we send the ap.
* XXX can we use a data frame to take us out of ps?
*/
if (ni->ni_psq.psq_len != 0)
pwrsave_flushq(ni);
} else {
ni->ni_flags |= IEEE80211_NODE_PWR_MGT;
ieee80211_send_nulldata(ieee80211_ref_node(ni));
}
}
示例6: ieee80211_crypto_decap
/*
* Validate and strip privacy headers (and trailer) for a
* received frame that has the Protected Frame bit set.
*/
struct ieee80211_key *
ieee80211_crypto_decap(struct ieee80211_node *ni, struct sk_buff *skb, int hdrlen)
{
#define IEEE80211_WEP_HDRLEN (IEEE80211_WEP_IVLEN + IEEE80211_WEP_KIDLEN)
#define IEEE80211_WEP_MINLEN \
(sizeof(struct ieee80211_frame) + \
IEEE80211_WEP_HDRLEN + IEEE80211_WEP_CRCLEN)
struct ieee80211vap *vap = ni->ni_vap;
struct ieee80211_key *k;
struct ieee80211_frame *wh;
const struct ieee80211_cipher *cip;
const u_int8_t *ivp;
u_int8_t keyid;
/* NB: this minimum size data frame could be bigger */
if (skb->len < IEEE80211_WEP_MINLEN) {
IEEE80211_NOTE(vap, IEEE80211_MSG_ANY, ni,
"%s: WEP data frame too short, len %u",
__func__, skb->len);
vap->iv_stats.is_rx_tooshort++; /* XXX need unique stat? */
return NULL;
}
/*
* Locate the key. If unicast and there is no unicast
* key then we fall back to the key id in the header.
* This assumes unicast keys are only configured when
* the key id in the header is meaningless (typically 0).
*/
wh = (struct ieee80211_frame *) skb->data;
ivp = skb->data + hdrlen;
keyid = ivp[IEEE80211_WEP_IVLEN];
if (IEEE80211_IS_MULTICAST(wh->i_addr1) ||
ni->ni_ucastkey.wk_cipher == &ieee80211_cipher_none)
k = &vap->iv_nw_keys[keyid >> 6];
else
示例7: amrr_node_init
static void
amrr_node_init(struct ieee80211_node *ni)
{
const struct ieee80211_rateset *rs = NULL;
struct ieee80211vap *vap = ni->ni_vap;
struct ieee80211_amrr *amrr = vap->iv_rs;
struct ieee80211_amrr_node *amn;
uint8_t rate;
if (ni->ni_rctls == NULL) {
ni->ni_rctls = amn = malloc(sizeof(struct ieee80211_amrr_node),
M_80211_RATECTL, M_NOWAIT|M_ZERO);
if (amn == NULL) {
if_printf(vap->iv_ifp, "couldn't alloc per-node ratectl "
"structure\n");
return;
}
} else
amn = ni->ni_rctls;
amn->amn_amrr = amrr;
amn->amn_success = 0;
amn->amn_recovery = 0;
amn->amn_txcnt = amn->amn_retrycnt = 0;
amn->amn_success_threshold = amrr->amrr_min_success_threshold;
rs = ieee80211_ratectl_get_rateset(ni);
/* Initial rate - lowest */
rate = rs->rs_rates[0];
/* XXX clear the basic rate flag if it's not 11n */
if (! ieee80211_ratectl_node_is11n(ni))
rate &= IEEE80211_RATE_VAL;
/* pick initial rate from the rateset - HT or otherwise */
for (amn->amn_rix = rs->rs_nrates - 1; amn->amn_rix > 0;
amn->amn_rix--) {
/* legacy - anything < 36mbit, stop searching */
/* 11n - stop at MCS4 / MCS12 / MCS28 */
if (ieee80211_ratectl_node_is11n(ni) &&
(rs->rs_rates[amn->amn_rix] & 0x7) < 4)
break;
else if ((rs->rs_rates[amn->amn_rix] & IEEE80211_RATE_VAL) <= 72)
break;
rate = rs->rs_rates[amn->amn_rix] & IEEE80211_RATE_VAL;
}
/* if the rate is an 11n rate, ensure the MCS bit is set */
if (ieee80211_ratectl_node_is11n(ni))
rate |= IEEE80211_RATE_MCS;
/* Assign initial rate from the rateset */
ni->ni_txrate = rate;
amn->amn_ticks = ticks;
IEEE80211_NOTE(ni->ni_vap, IEEE80211_MSG_RATECTL, ni,
"%s: AMRR: nrates=%d, initial rate %d",
__func__, rs->rs_nrates, rate);
}
示例8: hwmp_rootmode_rann_callout
/*
* Send a Root Annoucement (RANN) to find all the nodes on the mesh. We are
* called when the vap is configured as a HWMP RANN root node.
*/
static void
hwmp_rootmode_rann_callout(void *arg)
{
struct ieee80211vap *vap = (struct ieee80211vap *)arg;
struct ieee80211_hwmp_state *hs;
struct ieee80211_mesh_state *ms;
struct ieee80211_meshrann_ie rann;
wlan_serialize_enter();
hs = vap->iv_hwmp;
ms = vap->iv_mesh;
IEEE80211_NOTE(vap, IEEE80211_MSG_HWMP, vap->iv_bss,
"%s", "send broadcast RANN");
rann.rann_flags = 0;
if (ms->ms_flags & IEEE80211_MESHFLAGS_PORTAL)
rann.rann_flags |= IEEE80211_MESHRANN_FLAGS_PR;
rann.rann_hopcount = 0;
rann.rann_ttl = ms->ms_ttl;
IEEE80211_ADDR_COPY(rann.rann_addr, vap->iv_myaddr);
rann.rann_seq = ++hs->hs_seq;
rann.rann_metric = IEEE80211_MESHLMETRIC_INITIALVAL;
vap->iv_stats.is_hwmp_rootrann++;
hwmp_send_rann(vap->iv_bss, vap->iv_myaddr, broadcastaddr, &rann);
hwmp_rootmode_setup(vap);
wlan_serialize_exit();
}
示例9: hwmp_rootmode_cb
static void
hwmp_rootmode_cb(void *arg)
{
struct ieee80211vap *vap = (struct ieee80211vap *)arg;
struct ieee80211_hwmp_state *hs = vap->iv_hwmp;
struct ieee80211_mesh_state *ms = vap->iv_mesh;
struct ieee80211_meshpreq_ie preq;
IEEE80211_NOTE(vap, IEEE80211_MSG_HWMP, vap->iv_bss,
"%s", "send broadcast PREQ");
preq.preq_flags = IEEE80211_MESHPREQ_FLAGS_AM;
if (ms->ms_flags & IEEE80211_MESHFLAGS_PORTAL)
preq.preq_flags |= IEEE80211_MESHPREQ_FLAGS_PR;
if (hs->hs_rootmode == IEEE80211_HWMP_ROOTMODE_PROACTIVE)
preq.preq_flags |= IEEE80211_MESHPREQ_FLAGS_PP;
preq.preq_hopcount = 0;
preq.preq_ttl = ms->ms_ttl;
preq.preq_id = ++hs->hs_preqid;
IEEE80211_ADDR_COPY(preq.preq_origaddr, vap->iv_myaddr);
preq.preq_origseq = ++hs->hs_seq;
preq.preq_lifetime = ticks_to_msecs(ieee80211_hwmp_roottimeout);
preq.preq_metric = IEEE80211_MESHLMETRIC_INITIALVAL;
preq.preq_tcount = 1;
IEEE80211_ADDR_COPY(PREQ_TADDR(0), broadcastaddr);
PREQ_TFLAGS(0) = IEEE80211_MESHPREQ_TFLAGS_TO |
IEEE80211_MESHPREQ_TFLAGS_RF;
PREQ_TSEQ(0) = 0;
vap->iv_stats.is_hwmp_rootreqs++;
hwmp_send_preq(vap->iv_bss, vap->iv_myaddr, broadcastaddr, &preq);
hwmp_rootmode_setup(vap);
}
示例10: ieee80211_node_saveq_cleanup
/*
* Handle station leaving bss.
*/
void
ieee80211_node_saveq_cleanup(struct ieee80211_node *ni)
{
struct ieee80211vap *vap = ni->ni_vap;
/* vap is already deleted */
if (vap == NULL) return;
if (vap->iv_opmode == IEEE80211_M_HOSTAP) {
ieee80211_mlme_node_leave(ni);
}
else {
ieee80211node_clear_flag(ni, IEEE80211_NODE_PWR_MGT);
#if NOT_YET
if (ieee80211node_has_flag(ni, IEEE80211_NODE_UAPSD_TRIG)) {
ieee80211node_clear_flag(ni, IEEE80211_NODE_UAPSD_TRIG);
IEEE80211_UAPSD_LOCK(ni->ni_ic);
ni->ni_ic->ic_uapsdmaxtriggers--;
IEEE80211_UAPSD_UNLOCK(ni->ni_ic);
}
#endif
}
if ((ieee80211_node_saveq_drain(ni) != 0) && (vap->iv_set_tim != NULL))
vap->iv_set_tim(ni, 0);
IEEE80211_NOTE(vap, IEEE80211_MSG_POWER, ni,
"%s %u sta's in ps mode \n", __func__,vap->iv_ps_sta);
}
示例11: pwrsave_flushq
/*
* Move frames from the ps q to the vap's send queue
* and/or the driver's send queue; and kick the start
* method for each, as appropriate. Note we're careful
* to preserve packet ordering here.
*/
static void
pwrsave_flushq(struct ieee80211_node *ni)
{
struct ieee80211_psq *psq = &ni->ni_psq;
struct ieee80211com *ic = ni->ni_ic;
struct ieee80211vap *vap = ni->ni_vap;
struct ieee80211_psq_head *qhead;
struct mbuf *parent_q = NULL, *ifp_q = NULL;
struct mbuf *m;
IEEE80211_NOTE(vap, IEEE80211_MSG_POWER, ni,
"flush ps queue, %u packets queued", psq->psq_len);
IEEE80211_PSQ_LOCK(psq);
qhead = &psq->psq_head[0]; /* 802.11 frames */
if (qhead->head != NULL) {
/* XXX could dispatch through vap and check M_ENCAP */
/* XXX need different driver interface */
/* XXX bypasses q max and OACTIVE */
parent_q = qhead->head;
qhead->head = qhead->tail = NULL;
qhead->len = 0;
}
qhead = &psq->psq_head[1]; /* 802.3 frames */
if (qhead->head != NULL) {
/* XXX need different driver interface */
/* XXX bypasses q max and OACTIVE */
ifp_q = qhead->head;
qhead->head = qhead->tail = NULL;
qhead->len = 0;
}
psq->psq_len = 0;
IEEE80211_PSQ_UNLOCK(psq);
/* NB: do this outside the psq lock */
/* XXX packets might get reordered if parent is OACTIVE */
/* parent frames, should be encapsulated */
while (parent_q != NULL) {
m = parent_q;
parent_q = m->m_nextpkt;
m->m_nextpkt = NULL;
/* must be encapsulated */
KASSERT((m->m_flags & M_ENCAP),
("%s: parentq with non-M_ENCAP frame!\n",
__func__));
(void) ieee80211_parent_xmitpkt(ic, m);
}
/* VAP frames, aren't encapsulated */
while (ifp_q != NULL) {
m = ifp_q;
ifp_q = m->m_nextpkt;
m->m_nextpkt = NULL;
KASSERT((!(m->m_flags & M_ENCAP)),
("%s: vapq with M_ENCAP frame!\n", __func__));
(void) ieee80211_vap_xmitpkt(vap, m);
}
}
示例12: ieee80211_node_psq_age
/*
* Age frames on the power save queue. The aging interval is
* 4 times the listen interval specified by the station. This
* number is factored into the age calculations when the frame
* is placed on the queue. We store ages as time differences
* so we can check and/or adjust only the head of the list.
* If a frame's age exceeds the threshold then discard it.
* The number of frames discarded is returned so the caller
* can check if it needs to adjust the tim.
*/
int
ieee80211_node_psq_age(struct ieee80211_node *ni)
{
struct ieee80211_psq *psq = &ni->ni_psq;
int discard = 0;
if (psq->psq_len != 0) {
#ifdef IEEE80211_DEBUG
struct ieee80211vap *vap = ni->ni_vap;
#endif
struct ieee80211_psq_head *qhead;
struct mbuf *m;
IEEE80211_PSQ_LOCK(psq);
qhead = &psq->psq_head[0];
again:
while ((m = qhead->head) != NULL &&
M_AGE_GET(m) < IEEE80211_INACT_WAIT) {
IEEE80211_NOTE(vap, IEEE80211_MSG_POWER, ni,
"discard frame, age %u", M_AGE_GET(m));
if ((qhead->head = m->m_nextpkt) == NULL)
qhead->tail = NULL;
KASSERT(qhead->len > 0, ("qhead len %d", qhead->len));
qhead->len--;
KASSERT(psq->psq_len > 0, ("psq len %d", psq->psq_len));
psq->psq_len--;
psq_mfree(m);
discard++;
}
if (qhead == &psq->psq_head[0]) { /* Algol-68 style for loop */
qhead = &psq->psq_head[1];
goto again;
}
if (m != NULL)
M_AGE_SUB(m, IEEE80211_INACT_WAIT);
IEEE80211_PSQ_UNLOCK(psq);
IEEE80211_NOTE(vap, IEEE80211_MSG_POWER, ni,
"discard %u frames for age", discard);
IEEE80211_NODE_STAT_ADD(ni, ps_discard, discard);
}
return discard;
}
示例13: ieee80211_notify_node_auth
void
ieee80211_notify_node_auth(struct ieee80211_node *ni)
{
struct ieee80211vap *vap = ni->ni_vap;
struct ifnet *ifp = vap->iv_ifp;
IEEE80211_NOTE(vap, IEEE80211_MSG_NODE, ni, "%s", "node auth");
notify_macaddr(ifp, RTM_IEEE80211_AUTH, ni->ni_macaddr);
}
示例14: ieee80211_node_saveq_handle_ps_frames
static void ieee80211_node_saveq_handle_ps_frames(struct ieee80211_node *ni, wbuf_t wbuf, u_int8_t frame_type)
{
struct node_powersave_queue *mgtq;
wbuf_t tmpwbuf;
mgtq = IEEE80211_NODE_SAVEQ_MGMTQ(ni);
if (wbuf_is_pwrsaveframe(wbuf)) {
/* ps frame (null (or) pspoll frame) */
++mgtq->nsq_num_ps_frames;
} else {
/* non ps frame*/
if (mgtq->nsq_num_ps_frames) {
struct ieee80211_tx_status ts;
struct node_powersave_queue *tmpq, temp_q;
tmpq = &temp_q;
IEEE80211_NODE_SAVEQ_INIT(tmpq);
/*
* go through the mgt queue and dump the frames with PS=1(pspoll,null).
* accummulate the remaining frames into temp queue.
*/
for (;;) {
IEEE80211_NODE_SAVEQ_DEQUEUE(mgtq, tmpwbuf);
if (tmpwbuf == NULL) {
break;
}
if (wbuf_is_pwrsaveframe(tmpwbuf)) {
IEEE80211_NOTE(ni->ni_vap, IEEE80211_MSG_ANY, ni,
"%s pwr save q: complete the PS frame with error \n", __func__);
ts.ts_flags = IEEE80211_TX_ERROR;
ieee80211_release_wbuf(ni,tmpwbuf, &ts);
} else {
IEEE80211_NODE_SAVEQ_ADD(tmpq,tmpwbuf);
}
}
mgtq->nsq_num_ps_frames = 0;
/*
* move all the frames from temp queue to mgmt queue.
*/
for (;;) {
IEEE80211_NODE_SAVEQ_DEQUEUE(tmpq, tmpwbuf);
if (tmpwbuf == NULL) {
break;
}
IEEE80211_NODE_SAVEQ_ADD(mgtq, tmpwbuf);
}
}
}
}
示例15: ieee80211_node_pwrsave
/*
* Handle station power-save state change.
*/
void
ieee80211_node_pwrsave(struct ieee80211_node *ni, int enable)
{
struct ieee80211vap *vap = ni->ni_vap;
int update;
update = 0;
if (enable) {
if ((ni->ni_flags & IEEE80211_NODE_PWR_MGT) == 0) {
vap->iv_ps_sta++;
update = 1;
}
ni->ni_flags |= IEEE80211_NODE_PWR_MGT;
IEEE80211_NOTE(vap, IEEE80211_MSG_POWER, ni,
"power save mode on, %u sta's in ps mode", vap->iv_ps_sta);
if (update)
vap->iv_update_ps(vap, vap->iv_ps_sta);
} else {
if (ni->ni_flags & IEEE80211_NODE_PWR_MGT) {
vap->iv_ps_sta--;
update = 1;
}
ni->ni_flags &= ~IEEE80211_NODE_PWR_MGT;
IEEE80211_NOTE(vap, IEEE80211_MSG_POWER, ni,
"power save mode off, %u sta's in ps mode", vap->iv_ps_sta);
/* NB: order here is intentional so TIM is clear before flush */
if (vap->iv_set_tim != NULL)
vap->iv_set_tim(ni, 0);
if (update) {
/* NB if no sta's in ps, driver should flush mc q */
vap->iv_update_ps(vap, vap->iv_ps_sta);
}
if (ni->ni_psq.psq_len != 0)
pwrsave_flushq(ni);
}
}