Minor cleanups of tdma protocol handling:
o break out version-related code to simplify rev'ing the protocol o add parameter validation macros so checks that appear multiple places are consistent (and easy to change) o add protocol version check when looking for a scan candidate o improve scan debug output format o rewrite beacon update handling to calculate a bitmask of changed values and pass that down through the driver callback so drivers can optimize work o do slot bounds check before use when parsing received beacons
This commit is contained in:
parent
2e5b83493d
commit
2bc3ce7732
@ -225,7 +225,7 @@ static void ath_tdma_bintvalsetup(struct ath_softc *sc,
|
|||||||
const struct ieee80211_tdma_state *tdma);
|
const struct ieee80211_tdma_state *tdma);
|
||||||
static void ath_tdma_config(struct ath_softc *sc, struct ieee80211vap *vap);
|
static void ath_tdma_config(struct ath_softc *sc, struct ieee80211vap *vap);
|
||||||
static void ath_tdma_update(struct ieee80211_node *ni,
|
static void ath_tdma_update(struct ieee80211_node *ni,
|
||||||
const struct ieee80211_tdma_param *tdma);
|
const struct ieee80211_tdma_param *tdma, int);
|
||||||
static void ath_tdma_beacon_send(struct ath_softc *sc,
|
static void ath_tdma_beacon_send(struct ath_softc *sc,
|
||||||
struct ieee80211vap *vap);
|
struct ieee80211vap *vap);
|
||||||
|
|
||||||
@ -7477,7 +7477,7 @@ ath_tdma_config(struct ath_softc *sc, struct ieee80211vap *vap)
|
|||||||
*/
|
*/
|
||||||
static void
|
static void
|
||||||
ath_tdma_update(struct ieee80211_node *ni,
|
ath_tdma_update(struct ieee80211_node *ni,
|
||||||
const struct ieee80211_tdma_param *tdma)
|
const struct ieee80211_tdma_param *tdma, int changed)
|
||||||
{
|
{
|
||||||
#define TSF_TO_TU(_h,_l) \
|
#define TSF_TO_TU(_h,_l) \
|
||||||
((((u_int32_t)(_h)) << 22) | (((u_int32_t)(_l)) >> 10))
|
((((u_int32_t)(_h)) << 22) | (((u_int32_t)(_l)) >> 10))
|
||||||
@ -7498,7 +7498,7 @@ ath_tdma_update(struct ieee80211_node *ni,
|
|||||||
/*
|
/*
|
||||||
* Check for and adopt configuration changes.
|
* Check for and adopt configuration changes.
|
||||||
*/
|
*/
|
||||||
if (isset(ATH_VAP(vap)->av_boff.bo_flags, IEEE80211_BEACON_TDMA)) {
|
if (changed != 0) {
|
||||||
const struct ieee80211_tdma_state *ts = vap->iv_tdma;
|
const struct ieee80211_tdma_state *ts = vap->iv_tdma;
|
||||||
|
|
||||||
ath_tdma_bintvalsetup(sc, ts);
|
ath_tdma_bintvalsetup(sc, ts);
|
||||||
|
@ -1077,15 +1077,27 @@ struct ieee80211_duration {
|
|||||||
#define ATH_FF_SNAP_ORGCODE_1 0x03
|
#define ATH_FF_SNAP_ORGCODE_1 0x03
|
||||||
#define ATH_FF_SNAP_ORGCODE_2 0x7f
|
#define ATH_FF_SNAP_ORGCODE_2 0x7f
|
||||||
|
|
||||||
|
/* NB: Atheros allocated the OUI for this purpose ~2005 but beware ... */
|
||||||
|
#define TDMA_OUI ATH_OUI
|
||||||
|
#define TDMA_OUI_TYPE 0x02
|
||||||
|
#define TDMA_VERSION_V2 2
|
||||||
|
#define TDMA_VERSION TDMA_VERSION_V2
|
||||||
|
|
||||||
|
/* NB: we only support 2 right now but protocol handles up to 8 */
|
||||||
|
#define TDMA_MAXSLOTS 2 /* max slots/sta's */
|
||||||
|
|
||||||
|
#define TDMA_PARAM_LEN_V2 sizeof(struct ieee80211_tdma_param)
|
||||||
|
|
||||||
struct ieee80211_tdma_param {
|
struct ieee80211_tdma_param {
|
||||||
u_int8_t tdma_id; /* IEEE80211_ELEMID_VENDOR */
|
u_int8_t tdma_id; /* IEEE80211_ELEMID_VENDOR */
|
||||||
u_int8_t tdma_len;
|
u_int8_t tdma_len;
|
||||||
u_int8_t tdma_oui[3]; /* 0x00, 0x03, 0x7f */
|
u_int8_t tdma_oui[3]; /* 0x00, 0x03, 0x7f */
|
||||||
u_int8_t tdma_type; /* OUI type */
|
u_int8_t tdma_type; /* OUI type */
|
||||||
u_int8_t tdma_subtype; /* OUI subtype */
|
u_int8_t tdma_subtype; /* OUI subtype */
|
||||||
|
#define TDMA_SUBTYPE_PARAM 0x01
|
||||||
u_int8_t tdma_version; /* spec revision */
|
u_int8_t tdma_version; /* spec revision */
|
||||||
u_int8_t tdma_slot; /* station slot # */
|
u_int8_t tdma_slot; /* station slot # [0..7] */
|
||||||
u_int8_t tdma_slotcnt; /* bss slot count */
|
u_int8_t tdma_slotcnt; /* bss slot count [1..8] */
|
||||||
u_int16_t tdma_slotlen; /* bss slot len (100us) */
|
u_int16_t tdma_slotlen; /* bss slot len (100us) */
|
||||||
u_int8_t tdma_bintval; /* beacon interval (superframes) */
|
u_int8_t tdma_bintval; /* beacon interval (superframes) */
|
||||||
u_int8_t tdma_inuse[1]; /* slot occupancy map */
|
u_int8_t tdma_inuse[1]; /* slot occupancy map */
|
||||||
@ -1093,10 +1105,14 @@ struct ieee80211_tdma_param {
|
|||||||
u_int8_t tdma_tstamp[8]; /* timestamp from last beacon */
|
u_int8_t tdma_tstamp[8]; /* timestamp from last beacon */
|
||||||
} __packed;
|
} __packed;
|
||||||
|
|
||||||
/* NB: Atheros allocated the OUI for this purpose ~3 years ago but beware ... */
|
#define TDMA_VERSION_VALID(_version) \
|
||||||
#define TDMA_OUI ATH_OUI
|
(TDMA_VERSION_V2 <= (_version) && (_version) <= TDMA_VERSION)
|
||||||
#define TDMA_OUI_TYPE 0x02
|
#define TDMA_SLOTCNT_VALID(_slotcnt) \
|
||||||
#define TDMA_SUBTYPE_PARAM 0x01
|
(2 <= (_slotcnt) && (_slotcnt) <= TDMA_MAXSLOTS)
|
||||||
#define TDMA_VERSION 2
|
/* XXX magic constants */
|
||||||
|
#define TDMA_SLOTLEN_VALID(_slotlen) \
|
||||||
|
(2*100 <= (_slotlen) && (unsigned)(_slotlen) <= 0xfffff)
|
||||||
|
/* XXX probably should set a max */
|
||||||
|
#define TDMA_BINTVAL_VALID(_bintval) (1 <= (_bintval))
|
||||||
|
|
||||||
#endif /* _NET80211_IEEE80211_H_ */
|
#endif /* _NET80211_IEEE80211_H_ */
|
||||||
|
@ -126,6 +126,7 @@ static void sta_flush_table(struct sta_table *);
|
|||||||
#define MATCH_TDMA_NOTMASTER 0x0800 /* not TDMA master */
|
#define MATCH_TDMA_NOTMASTER 0x0800 /* not TDMA master */
|
||||||
#define MATCH_TDMA_NOSLOT 0x1000 /* all TDMA slots occupied */
|
#define MATCH_TDMA_NOSLOT 0x1000 /* all TDMA slots occupied */
|
||||||
#define MATCH_TDMA_LOCAL 0x2000 /* local address */
|
#define MATCH_TDMA_LOCAL 0x2000 /* local address */
|
||||||
|
#define MATCH_TDMA_VERSION 0x4000 /* protocol version mismatch */
|
||||||
static int match_bss(struct ieee80211vap *,
|
static int match_bss(struct ieee80211vap *,
|
||||||
const struct ieee80211_scan_state *, struct sta_entry *, int);
|
const struct ieee80211_scan_state *, struct sta_entry *, int);
|
||||||
static void adhoc_age(struct ieee80211_scan_state *);
|
static void adhoc_age(struct ieee80211_scan_state *);
|
||||||
@ -970,9 +971,12 @@ match_bss(struct ieee80211vap *vap,
|
|||||||
if (vap->iv_caps & IEEE80211_C_TDMA) {
|
if (vap->iv_caps & IEEE80211_C_TDMA) {
|
||||||
const struct ieee80211_tdma_param *tdma =
|
const struct ieee80211_tdma_param *tdma =
|
||||||
(const struct ieee80211_tdma_param *)se->se_ies.tdma_ie;
|
(const struct ieee80211_tdma_param *)se->se_ies.tdma_ie;
|
||||||
|
const struct ieee80211_tdma_state *ts = vap->iv_tdma;
|
||||||
|
|
||||||
if (tdma == NULL)
|
if (tdma == NULL)
|
||||||
fail |= MATCH_TDMA_NOIE;
|
fail |= MATCH_TDMA_NOIE;
|
||||||
|
else if (tdma->tdma_version != ts->tdma_version)
|
||||||
|
fail |= MATCH_TDMA_VERSION;
|
||||||
else if (tdma->tdma_slot != 0)
|
else if (tdma->tdma_slot != 0)
|
||||||
fail |= MATCH_TDMA_NOTMASTER;
|
fail |= MATCH_TDMA_NOTMASTER;
|
||||||
else if (tdma_isfull(tdma))
|
else if (tdma_isfull(tdma))
|
||||||
@ -1062,9 +1066,10 @@ match_bss(struct ieee80211vap *vap,
|
|||||||
fail & MATCH_CC ? '$' :
|
fail & MATCH_CC ? '$' :
|
||||||
#ifdef IEEE80211_SUPPORT_TDMA
|
#ifdef IEEE80211_SUPPORT_TDMA
|
||||||
fail & MATCH_TDMA_NOIE ? '&' :
|
fail & MATCH_TDMA_NOIE ? '&' :
|
||||||
fail & MATCH_TDMA_NOTMASTER ? ':' :
|
fail & MATCH_TDMA_VERSION ? 'v' :
|
||||||
fail & MATCH_TDMA_NOSLOT ? '@' :
|
fail & MATCH_TDMA_NOTMASTER ? 's' :
|
||||||
fail & MATCH_TDMA_LOCAL ? '#' :
|
fail & MATCH_TDMA_NOSLOT ? 'f' :
|
||||||
|
fail & MATCH_TDMA_LOCAL ? 'l' :
|
||||||
#endif
|
#endif
|
||||||
fail ? '-' : '+', ether_sprintf(se->se_macaddr));
|
fail ? '-' : '+', ether_sprintf(se->se_macaddr));
|
||||||
printf(" %s%c", ether_sprintf(se->se_bssid),
|
printf(" %s%c", ether_sprintf(se->se_bssid),
|
||||||
@ -1076,8 +1081,7 @@ match_bss(struct ieee80211vap *vap,
|
|||||||
fail & MATCH_RATE ? '!' : ' ');
|
fail & MATCH_RATE ? '!' : ' ');
|
||||||
printf(" %4s%c",
|
printf(" %4s%c",
|
||||||
(se->se_capinfo & IEEE80211_CAPINFO_ESS) ? "ess" :
|
(se->se_capinfo & IEEE80211_CAPINFO_ESS) ? "ess" :
|
||||||
(se->se_capinfo & IEEE80211_CAPINFO_IBSS) ? "ibss" :
|
(se->se_capinfo & IEEE80211_CAPINFO_IBSS) ? "ibss" : "",
|
||||||
"????",
|
|
||||||
fail & MATCH_CAPINFO ? '!' : ' ');
|
fail & MATCH_CAPINFO ? '!' : ' ');
|
||||||
printf(" %3s%c ",
|
printf(" %3s%c ",
|
||||||
(se->se_capinfo & IEEE80211_CAPINFO_PRIVACY) ?
|
(se->se_capinfo & IEEE80211_CAPINFO_PRIVACY) ?
|
||||||
|
@ -142,6 +142,7 @@ ieee80211_tdma_vattach(struct ieee80211vap *vap)
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
/* NB: default configuration is passive so no beacons */
|
/* NB: default configuration is passive so no beacons */
|
||||||
|
ts->tdma_version = TDMA_VERSION;
|
||||||
ts->tdma_slotlen = TDMA_SLOTLEN_DEFAULT;
|
ts->tdma_slotlen = TDMA_SLOTLEN_DEFAULT;
|
||||||
ts->tdma_slotcnt = TDMA_SLOTCNT_DEFAULT;
|
ts->tdma_slotcnt = TDMA_SLOTCNT_DEFAULT;
|
||||||
ts->tdma_bintval = TDMA_BINTVAL_DEFAULT;
|
ts->tdma_bintval = TDMA_BINTVAL_DEFAULT;
|
||||||
@ -371,71 +372,90 @@ tdma_recv_mgmt(struct ieee80211_node *ni, struct mbuf *m0,
|
|||||||
* a TDMA information element. The sender's identity
|
* a TDMA information element. The sender's identity
|
||||||
* is provided so we can track who our peer is. If pickslot
|
* is provided so we can track who our peer is. If pickslot
|
||||||
* is non-zero we scan the slot allocation state in the ie
|
* is non-zero we scan the slot allocation state in the ie
|
||||||
* locate a free slot for our use.
|
* to locate a free slot for our use.
|
||||||
*/
|
*/
|
||||||
static int
|
static int
|
||||||
tdma_update(struct ieee80211vap *vap, const struct ieee80211_tdma_param *tdma,
|
tdma_update(struct ieee80211vap *vap, const struct ieee80211_tdma_param *tdma,
|
||||||
struct ieee80211_node *ni, int pickslot)
|
struct ieee80211_node *ni, int pickslot)
|
||||||
{
|
{
|
||||||
struct ieee80211_tdma_state *ts = vap->iv_tdma;
|
struct ieee80211_tdma_state *ts = vap->iv_tdma;
|
||||||
int slotlen, slotcnt, slot, bintval;
|
int slot, slotlen, update;
|
||||||
|
|
||||||
KASSERT(vap->iv_caps & IEEE80211_C_TDMA,
|
KASSERT(vap->iv_caps & IEEE80211_C_TDMA,
|
||||||
("not a tdma vap, caps 0x%x", vap->iv_caps));
|
("not a tdma vap, caps 0x%x", vap->iv_caps));
|
||||||
|
|
||||||
slotlen = le16toh(tdma->tdma_slotlen);
|
update = 0;
|
||||||
slotcnt = tdma->tdma_slotcnt;
|
if (tdma->tdma_slotcnt != ts->tdma_slotcnt) {
|
||||||
bintval = tdma->tdma_bintval;
|
if (!TDMA_SLOTCNT_VALID(tdma->tdma_slotcnt)) {
|
||||||
|
printf("%s: bad slot cnt %u\n",
|
||||||
/* XXX rate-limit printf's */
|
__func__, tdma->tdma_slotcnt);
|
||||||
if (!(2 <= slotcnt && slotcnt <= IEEE80211_TDMA_MAXSLOTS)) {
|
|
||||||
printf("%s: bogus slot cnt %u\n", __func__, slotcnt);
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
/* XXX magic constants */
|
update |= TDMA_UPDATE_SLOTCNT;
|
||||||
if (slotlen < 2 || slotlen > (0xfffff/100)) {
|
}
|
||||||
printf("%s: bogus slot len %u\n", __func__, slotlen);
|
slotlen = le16toh(tdma->tdma_slotlen) * 100;
|
||||||
|
if (slotlen != ts->tdma_slotlen) {
|
||||||
|
if (!TDMA_SLOTLEN_VALID(slotlen)) {
|
||||||
|
printf("%s: bad slot len %u\n",
|
||||||
|
__func__, slotlen);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
if (bintval < 1) {
|
update |= TDMA_UPDATE_SLOTLEN;
|
||||||
printf("%s: bogus beacon interval %u\n", __func__, bintval);
|
}
|
||||||
|
if (tdma->tdma_bintval != ts->tdma_bintval) {
|
||||||
|
if (!TDMA_BINTVAL_VALID(tdma->tdma_bintval)) {
|
||||||
|
printf("%s: bad beacon interval %u\n",
|
||||||
|
__func__, tdma->tdma_bintval);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
update |= TDMA_UPDATE_BINTVAL;
|
||||||
|
}
|
||||||
|
slot = ts->tdma_slot;
|
||||||
if (pickslot) {
|
if (pickslot) {
|
||||||
/*
|
/*
|
||||||
* Pick unoccupied slot. Note we never choose slot 0.
|
* Pick unoccupied slot. Note we never choose slot 0.
|
||||||
*/
|
*/
|
||||||
for (slot = slotcnt-1; slot > 0; slot--)
|
for (slot = tdma->tdma_slotcnt-1; slot > 0; slot--)
|
||||||
if (isclr(tdma->tdma_inuse, slot))
|
if (isclr(tdma->tdma_inuse, slot))
|
||||||
break;
|
break;
|
||||||
if (slot <= 0) {
|
if (slot <= 0) {
|
||||||
printf("%s: no free slot, slotcnt %u inuse: 0x%x\n",
|
printf("%s: no free slot, slotcnt %u inuse: 0x%x\n",
|
||||||
__func__, slotcnt, tdma->tdma_inuse[0]);
|
__func__, tdma->tdma_slotcnt,
|
||||||
|
tdma->tdma_inuse[0]);
|
||||||
/* XXX need to do something better */
|
/* XXX need to do something better */
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
} else
|
if (slot != ts->tdma_slot)
|
||||||
slot = ts->tdma_slot;
|
update |= TDMA_UPDATE_SLOT;
|
||||||
|
}
|
||||||
|
if (ni != ts->tdma_peer) {
|
||||||
|
/* update everything */
|
||||||
|
update = TDMA_UPDATE_SLOT
|
||||||
|
| TDMA_UPDATE_SLOTCNT
|
||||||
|
| TDMA_UPDATE_SLOTLEN
|
||||||
|
| TDMA_UPDATE_BINTVAL;
|
||||||
|
}
|
||||||
|
|
||||||
if (slotcnt != ts->tdma_slotcnt ||
|
if (update) {
|
||||||
100*slotlen != ts->tdma_slotlen ||
|
|
||||||
bintval != ts->tdma_bintval ||
|
|
||||||
slot != ts->tdma_slot ||
|
|
||||||
ts->tdma_peer != ni) {
|
|
||||||
/*
|
/*
|
||||||
* New/changed parameters; update runtime state.
|
* New/changed parameters; update runtime state.
|
||||||
*/
|
*/
|
||||||
/* XXX overwrites user parameters */
|
/* XXX overwrites user parameters */
|
||||||
ts->tdma_slotcnt = slotcnt;
|
if (update & TDMA_UPDATE_SLOTCNT)
|
||||||
ts->tdma_slotlen = 100*slotlen;
|
ts->tdma_slotcnt = tdma->tdma_slotcnt;
|
||||||
|
if (update & TDMA_UPDATE_SLOTLEN)
|
||||||
|
ts->tdma_slotlen = slotlen;
|
||||||
|
if (update & TDMA_UPDATE_SLOT)
|
||||||
ts->tdma_slot = slot;
|
ts->tdma_slot = slot;
|
||||||
ts->tdma_bintval = bintval;
|
if (update & TDMA_UPDATE_BINTVAL)
|
||||||
|
ts->tdma_bintval = tdma->tdma_bintval;
|
||||||
/* mark beacon to be updated before next xmit */
|
/* mark beacon to be updated before next xmit */
|
||||||
ieee80211_beacon_notify(vap, IEEE80211_BEACON_TDMA);
|
ieee80211_beacon_notify(vap, IEEE80211_BEACON_TDMA);
|
||||||
|
|
||||||
IEEE80211_DPRINTF(vap, IEEE80211_MSG_TDMA,
|
IEEE80211_DPRINTF(vap, IEEE80211_MSG_TDMA,
|
||||||
"%s: slot %u slotcnt %u slotlen %u us bintval %u\n",
|
"%s: slot %u slotcnt %u slotlen %u us bintval %u\n",
|
||||||
__func__, slot, slotcnt, 100*slotlen, tdma->tdma_bintval);
|
__func__, ts->tdma_slot, ts->tdma_slotcnt,
|
||||||
|
100*ts->tdma_slotlen, ts->tdma_bintval);
|
||||||
}
|
}
|
||||||
/*
|
/*
|
||||||
* Notify driver. Note we can be called before
|
* Notify driver. Note we can be called before
|
||||||
@ -445,7 +465,7 @@ tdma_update(struct ieee80211vap *vap, const struct ieee80211_tdma_param *tdma,
|
|||||||
* has been setup. The next beacon will dtrt.
|
* has been setup. The next beacon will dtrt.
|
||||||
*/
|
*/
|
||||||
if (vap->iv_state == IEEE80211_S_RUN)
|
if (vap->iv_state == IEEE80211_S_RUN)
|
||||||
vap->iv_ic->ic_tdma_update(ni, tdma);
|
vap->iv_ic->ic_tdma_update(ni, tdma, update);
|
||||||
/*
|
/*
|
||||||
* Dispatch join event on first beacon from new master.
|
* Dispatch join event on first beacon from new master.
|
||||||
*/
|
*/
|
||||||
@ -481,10 +501,23 @@ tdma_process_params(struct ieee80211_node *ni,
|
|||||||
wh, "tdma", "too short, len %u", len);
|
wh, "tdma", "too short, len %u", len);
|
||||||
return IEEE80211_REASON_IE_INVALID;
|
return IEEE80211_REASON_IE_INVALID;
|
||||||
}
|
}
|
||||||
if (tdma->tdma_version != TDMA_VERSION) {
|
if (tdma->tdma_version != ts->tdma_version) {
|
||||||
IEEE80211_DISCARD_IE(vap,
|
IEEE80211_DISCARD_IE(vap,
|
||||||
IEEE80211_MSG_ELEMID | IEEE80211_MSG_TDMA,
|
IEEE80211_MSG_ELEMID | IEEE80211_MSG_TDMA,
|
||||||
wh, "tdma", "bad version %u", tdma->tdma_version);
|
wh, "tdma", "bad version %u (ours %u)",
|
||||||
|
tdma->tdma_version, ts->tdma_version);
|
||||||
|
return IEEE80211_REASON_IE_INVALID;
|
||||||
|
}
|
||||||
|
/*
|
||||||
|
* NB: ideally we'd check against tdma_slotcnt, but that
|
||||||
|
* would require extra effort so do this easy check that
|
||||||
|
* covers the work below; more stringent checks are done
|
||||||
|
* before we make more extensive use of the ie contents.
|
||||||
|
*/
|
||||||
|
if (tdma->tdma_slot >= TDMA_MAXSLOTS) {
|
||||||
|
IEEE80211_DISCARD_IE(vap,
|
||||||
|
IEEE80211_MSG_ELEMID | IEEE80211_MSG_TDMA,
|
||||||
|
wh, "tdma", "invalid slot %u", tdma->tdma_slot);
|
||||||
return IEEE80211_REASON_IE_INVALID;
|
return IEEE80211_REASON_IE_INVALID;
|
||||||
}
|
}
|
||||||
/*
|
/*
|
||||||
@ -612,7 +645,7 @@ ieee80211_add_tdma(uint8_t *frm, struct ieee80211vap *vap)
|
|||||||
.tdma_subtype = TDMA_SUBTYPE_PARAM,
|
.tdma_subtype = TDMA_SUBTYPE_PARAM,
|
||||||
.tdma_version = TDMA_VERSION,
|
.tdma_version = TDMA_VERSION,
|
||||||
};
|
};
|
||||||
const struct ieee80211_tdma_state *tdma = vap->iv_tdma;
|
const struct ieee80211_tdma_state *ts = vap->iv_tdma;
|
||||||
uint16_t slotlen;
|
uint16_t slotlen;
|
||||||
|
|
||||||
KASSERT(vap->iv_caps & IEEE80211_C_TDMA,
|
KASSERT(vap->iv_caps & IEEE80211_C_TDMA,
|
||||||
@ -620,13 +653,13 @@ ieee80211_add_tdma(uint8_t *frm, struct ieee80211vap *vap)
|
|||||||
|
|
||||||
memcpy(frm, ¶m, sizeof(param));
|
memcpy(frm, ¶m, sizeof(param));
|
||||||
frm += __offsetof(struct ieee80211_tdma_param, tdma_slot);
|
frm += __offsetof(struct ieee80211_tdma_param, tdma_slot);
|
||||||
*frm++ = tdma->tdma_slot;
|
*frm++ = ts->tdma_slot;
|
||||||
*frm++ = tdma->tdma_slotcnt;
|
*frm++ = ts->tdma_slotcnt;
|
||||||
/* NB: convert units to fit in 16-bits */
|
/* NB: convert units to fit in 16-bits */
|
||||||
slotlen = tdma->tdma_slotlen / 100; /* 100us units */
|
slotlen = ts->tdma_slotlen / 100; /* 100us units */
|
||||||
ADDSHORT(frm, slotlen);
|
ADDSHORT(frm, slotlen);
|
||||||
*frm++ = tdma->tdma_bintval;
|
*frm++ = ts->tdma_bintval;
|
||||||
*frm++ = tdma->tdma_inuse[0];
|
*frm++ = ts->tdma_inuse[0];
|
||||||
frm += 10; /* pad+timestamp */
|
frm += 10; /* pad+timestamp */
|
||||||
return frm;
|
return frm;
|
||||||
#undef ADDSHORT
|
#undef ADDSHORT
|
||||||
@ -717,8 +750,7 @@ ieee80211_tdma_ioctl_set80211(struct ieee80211vap *vap,
|
|||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case IEEE80211_IOC_TDMA_SLOTCNT:
|
case IEEE80211_IOC_TDMA_SLOTCNT:
|
||||||
if (!(2 <= ireq->i_val &&
|
if (!TDMA_SLOTCNT_VALID(ireq->i_val))
|
||||||
ireq->i_val <= IEEE80211_TDMA_MAXSLOTS))
|
|
||||||
return EINVAL;
|
return EINVAL;
|
||||||
if (ireq->i_val != ts->tdma_slotcnt) {
|
if (ireq->i_val != ts->tdma_slotcnt) {
|
||||||
ts->tdma_slotcnt = ireq->i_val;
|
ts->tdma_slotcnt = ireq->i_val;
|
||||||
@ -732,7 +764,7 @@ ieee80211_tdma_ioctl_set80211(struct ieee80211vap *vap,
|
|||||||
* 0xfffff is the max duration for bursting
|
* 0xfffff is the max duration for bursting
|
||||||
* (implict by way of 16-bit data type for i_val)
|
* (implict by way of 16-bit data type for i_val)
|
||||||
*/
|
*/
|
||||||
if (ireq->i_val < 150)
|
if (!TDMA_SLOTLEN_VALID(ireq->i_val))
|
||||||
return EINVAL;
|
return EINVAL;
|
||||||
if (ireq->i_val != ts->tdma_slotlen) {
|
if (ireq->i_val != ts->tdma_slotlen) {
|
||||||
ts->tdma_slotlen = ireq->i_val;
|
ts->tdma_slotlen = ireq->i_val;
|
||||||
@ -740,7 +772,7 @@ ieee80211_tdma_ioctl_set80211(struct ieee80211vap *vap,
|
|||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case IEEE80211_IOC_TDMA_BINTERVAL:
|
case IEEE80211_IOC_TDMA_BINTERVAL:
|
||||||
if (ireq->i_val < 1)
|
if (!TDMA_BINTVAL_VALID(ireq->i_val))
|
||||||
return EINVAL;
|
return EINVAL;
|
||||||
if (ireq->i_val != ts->tdma_bintval) {
|
if (ireq->i_val != ts->tdma_bintval) {
|
||||||
ts->tdma_bintval = ireq->i_val;
|
ts->tdma_bintval = ireq->i_val;
|
||||||
|
@ -33,11 +33,11 @@
|
|||||||
*/
|
*/
|
||||||
struct ieee80211_tdma_state {
|
struct ieee80211_tdma_state {
|
||||||
u_int tdma_slotlen; /* bss slot length (us) */
|
u_int tdma_slotlen; /* bss slot length (us) */
|
||||||
|
uint8_t tdma_version; /* protocol version to use */
|
||||||
uint8_t tdma_slotcnt; /* bss slot count */
|
uint8_t tdma_slotcnt; /* bss slot count */
|
||||||
uint8_t tdma_bintval; /* beacon interval (slots) */
|
uint8_t tdma_bintval; /* beacon interval (slots) */
|
||||||
uint8_t tdma_slot; /* station slot # */
|
uint8_t tdma_slot; /* station slot # */
|
||||||
uint8_t tdma_inuse[1]; /* mask of slots in use */
|
uint8_t tdma_inuse[1]; /* mask of slots in use */
|
||||||
#define IEEE80211_TDMA_MAXSLOTS 8
|
|
||||||
void *tdma_peer; /* peer station cookie */
|
void *tdma_peer; /* peer station cookie */
|
||||||
uint8_t tdma_active[1]; /* mask of active slots */
|
uint8_t tdma_active[1]; /* mask of active slots */
|
||||||
int tdma_count; /* active/inuse countdown */
|
int tdma_count; /* active/inuse countdown */
|
||||||
@ -50,6 +50,11 @@ struct ieee80211_tdma_state {
|
|||||||
void (*tdma_opdetach)(struct ieee80211vap *);
|
void (*tdma_opdetach)(struct ieee80211vap *);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
#define TDMA_UPDATE_SLOT 0x0001 /* tdma_slot changed */
|
||||||
|
#define TDMA_UPDATE_SLOTCNT 0x0002 /* tdma_slotcnt changed */
|
||||||
|
#define TDMA_UPDATE_SLOTLEN 0x0004 /* tdma_slotlen changed */
|
||||||
|
#define TDMA_UPDATE_BINTVAL 0x0008 /* tdma_bintval changed */
|
||||||
|
|
||||||
void ieee80211_tdma_vattach(struct ieee80211vap *);
|
void ieee80211_tdma_vattach(struct ieee80211vap *);
|
||||||
|
|
||||||
int ieee80211_tdma_getslot(struct ieee80211vap *vap);
|
int ieee80211_tdma_getslot(struct ieee80211vap *vap);
|
||||||
|
@ -229,7 +229,7 @@ struct ieee80211com {
|
|||||||
void (*ic_newassoc)(struct ieee80211_node *, int);
|
void (*ic_newassoc)(struct ieee80211_node *, int);
|
||||||
/* TDMA update notification */
|
/* TDMA update notification */
|
||||||
void (*ic_tdma_update)(struct ieee80211_node *,
|
void (*ic_tdma_update)(struct ieee80211_node *,
|
||||||
const struct ieee80211_tdma_param *);
|
const struct ieee80211_tdma_param *, int);
|
||||||
/* node state management */
|
/* node state management */
|
||||||
struct ieee80211_node* (*ic_node_alloc)(struct ieee80211vap *,
|
struct ieee80211_node* (*ic_node_alloc)(struct ieee80211vap *,
|
||||||
const uint8_t [IEEE80211_ADDR_LEN]);
|
const uint8_t [IEEE80211_ADDR_LEN]);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user