void ieee80211_mlme_join_infra_continue(struct ieee80211vap *vap, int32_t status) { struct ieee80211com *ic = vap->iv_ic; struct ieee80211_node *ni; struct ieee80211_mlme_priv *mlme_priv = vap->iv_mlme_priv; u_int32_t join_timeout_ms; if (mlme_priv->im_request_type != MLME_REQ_JOIN_INFRA) { IEEE80211_DPRINTF(vap, IEEE80211_MSG_MLME, "%s : im_request_type != JOIN_INFRA\n", __func__); return; } if (status != EOK) { mlme_priv->im_request_type = MLME_REQ_NONE; IEEE80211_DELIVER_EVENT_MLME_JOIN_COMPLETE_INFRA(vap, IEEE80211_STATUS_UNSPECIFIED); return; } /* iv_bss is valid only after ieee80211_sta_join */ ni = vap->iv_bss; IEEE80211_DPRINTF(vap, IEEE80211_MSG_MLME, "%s ni=%02X:%02X:%02X:%02X:%02X:%02X\n", __func__, ni->ni_macaddr[0], ni->ni_macaddr[1], ni->ni_macaddr[2], ni->ni_macaddr[3], ni->ni_macaddr[4], ni->ni_macaddr[5]); /* Update erp info */ if (ni->ni_erp & IEEE80211_ERP_USE_PROTECTION) ic->ic_flags |= IEEE80211_F_USEPROT; else ic->ic_flags &= ~IEEE80211_F_USEPROT; ic->ic_update_protmode(ic); if(ni->ni_erp & IEEE80211_ERP_LONG_PREAMBLE) ic->ic_flags |= IEEE80211_F_USEBARKER; else ic->ic_flags &= (~IEEE80211_F_USEBARKER); /* Update slot time info */ ieee80211_set_shortslottime(ic, IEEE80211_IS_CHAN_A(vap->iv_bsschan) || IEEE80211_IS_CHAN_11NA(vap->iv_bsschan) || (ni->ni_capinfo & IEEE80211_CAPINFO_SHORT_SLOTTIME)); /* Put underlying H/W to JOIN state */ ieee80211_vap_join(vap); #ifdef ATH_SUPPORT_TxBF ieee80211_init_txbf(ic, ni); #endif /* Send a direct probe to increase the odds of receiving a probe response */ ieee80211_send_probereq(ni, ic->ic_myaddr, ni->ni_bssid, ni->ni_bssid, ni->ni_essid, ni->ni_esslen, vap->iv_opt_ie.ie, vap->iv_opt_ie.length); /* Set the timeout timer for Join Failure case. */ join_timeout_ms = IEEE80211_TU_TO_MS(mlme_priv->im_timeout * ni->ni_intval); IEEE80211_DPRINTF(vap, IEEE80211_MSG_MLME, "%s: Setting Join Timeout timer for %d ms\n", __func__, join_timeout_ms); OS_SET_TIMER(&mlme_priv->im_timeout_timer, join_timeout_ms); /* Set the appropriate filtering function and wait for Join Beacon */ MLME_WAIT_FOR_BSS_JOIN(mlme_priv); }
/* * Save an outbound packet for a node in power-save sleep state. * The new packet is placed on the node's saved queue, and the TIM * is changed, if necessary. */ int ieee80211_pwrsave(struct ieee80211_node *ni, struct mbuf *m) { struct ieee80211_psq *psq = &ni->ni_psq; struct ieee80211vap *vap = ni->ni_vap; struct ieee80211com *ic = ni->ni_ic; struct ieee80211_psq_head *qhead; int qlen, age; IEEE80211_PSQ_LOCK(psq); if (psq->psq_len >= psq->psq_maxlen) { psq->psq_drops++; IEEE80211_PSQ_UNLOCK(psq); IEEE80211_NOTE(vap, IEEE80211_MSG_ANY, ni, "pwr save q overflow, drops %d (size %d)", psq->psq_drops, psq->psq_len); #ifdef IEEE80211_DEBUG if (ieee80211_msg_dumppkts(vap)) ieee80211_dump_pkt(ni->ni_ic, mtod(m, caddr_t), m->m_len, -1, -1); #endif psq_mfree(m); return ENOSPC; } /* * Tag the frame with it's expiry time and insert it in * the appropriate queue. The aging interval is 4 times * the listen interval specified by the station. Frames * that sit around too long are reclaimed using this * information. */ /* TU -> secs. XXX handle overflow? */ age = IEEE80211_TU_TO_MS((ni->ni_intval * ic->ic_bintval) << 2) / 1000; /* * Encapsulated frames go on the high priority queue, * other stuff goes on the low priority queue. We use * this to order frames returned out of the driver * ahead of frames we collect in ieee80211_start. */ if (m->m_flags & M_ENCAP) qhead = &psq->psq_head[0]; else qhead = &psq->psq_head[1]; if (qhead->tail == NULL) { struct mbuf *mh; qhead->head = m; /* * Take care to adjust age when inserting the first * frame of a queue and the other queue already has * frames. We need to preserve the age difference * relationship so ieee80211_node_psq_age works. */ if (qhead == &psq->psq_head[1]) { mh = psq->psq_head[0].head; if (mh != NULL) age-= M_AGE_GET(mh); } else { mh = psq->psq_head[1].head; if (mh != NULL) { int nage = M_AGE_GET(mh) - age; /* XXX is clamping to zero good 'nuf? */ M_AGE_SET(mh, nage < 0 ? 0 : nage); } } } else { qhead->tail->m_nextpkt = m; age -= M_AGE_GET(qhead->head); } KASSERT(age >= 0, ("age %d", age)); M_AGE_SET(m, age); m->m_nextpkt = NULL; qhead->tail = m; qhead->len++; qlen = ++(psq->psq_len); IEEE80211_PSQ_UNLOCK(psq); IEEE80211_NOTE(vap, IEEE80211_MSG_POWER, ni, "save frame with age %d, %u now queued", age, qlen); if (qlen == 1 && vap->iv_set_tim != NULL) vap->iv_set_tim(ni, 1); return 0; }