Lines Matching +full:time +full:- +full:slot

1 /*-
2 * SPDX-License-Identifier: BSD-2-Clause
4 * Copyright (c) 2007-2009 Sam Leffler, Errno Consulting
5 * Copyright (c) 2007-2009 Intel Corporation
66 #define TDMA_SLOTCNT_DEFAULT 2 /* 2x (pt-to-pt) */
125 if (isclr(vap->iv_ic->ic_modecaps, mode)) in settxparms()
128 vap->iv_txparms[mode].ucastrate = rate; in settxparms()
129 vap->iv_txparms[mode].mcastrate = rate; in settxparms()
135 struct ieee80211_wme_state *wme = &ic->ic_wme; in setackpolicy()
139 wme->wme_chanParams.cap_wmeParams[ac].wmep_noackPolicy = noack; in setackpolicy()
140 wme->wme_wmeChanParams.cap_wmeParams[ac].wmep_noackPolicy = noack; in setackpolicy()
149 KASSERT(vap->iv_caps & IEEE80211_C_TDMA, in ieee80211_tdma_vattach()
150 ("not a tdma vap, caps 0x%x", vap->iv_caps)); in ieee80211_tdma_vattach()
158 vap->iv_caps &= ~IEEE80211_C_TDMA; in ieee80211_tdma_vattach()
162 ts->tdma_version = TDMA_VERSION; in ieee80211_tdma_vattach()
163 ts->tdma_slotlen = TDMA_SLOTLEN_DEFAULT; in ieee80211_tdma_vattach()
164 ts->tdma_slotcnt = TDMA_SLOTCNT_DEFAULT; in ieee80211_tdma_vattach()
165 ts->tdma_bintval = TDMA_BINTVAL_DEFAULT; in ieee80211_tdma_vattach()
166 ts->tdma_slot = 1; /* passive operation */ in ieee80211_tdma_vattach()
182 setackpolicy(vap->iv_ic, 1); /* disable ACK's */ in ieee80211_tdma_vattach()
184 ts->tdma_opdetach = vap->iv_opdetach; in ieee80211_tdma_vattach()
185 vap->iv_opdetach = tdma_vdetach; in ieee80211_tdma_vattach()
186 ts->tdma_newstate = vap->iv_newstate; in ieee80211_tdma_vattach()
187 vap->iv_newstate = tdma_newstate; in ieee80211_tdma_vattach()
188 vap->iv_bmiss = tdma_beacon_miss; in ieee80211_tdma_vattach()
189 ts->tdma_recv_mgmt = vap->iv_recv_mgmt; in ieee80211_tdma_vattach()
190 vap->iv_recv_mgmt = tdma_recv_mgmt; in ieee80211_tdma_vattach()
192 vap->iv_tdma = ts; in ieee80211_tdma_vattach()
198 struct ieee80211_tdma_state *ts = vap->iv_tdma; in tdma_vdetach()
204 ts->tdma_opdetach(vap); in tdma_vdetach()
205 IEEE80211_FREE(vap->iv_tdma, M_80211_VAP); in tdma_vdetach()
206 vap->iv_tdma = NULL; in tdma_vdetach()
208 setackpolicy(vap->iv_ic, 0); /* enable ACK's */ in tdma_vdetach()
214 struct ieee80211vap *vap = ni->ni_vap; in sta_leave()
216 if (ni != vap->iv_bss) in sta_leave()
226 struct ieee80211_tdma_state *ts = vap->iv_tdma; in tdma_newstate()
227 struct ieee80211com *ic = vap->iv_ic; in tdma_newstate()
233 ostate = vap->iv_state; in tdma_newstate()
234 IEEE80211_DPRINTF(vap, IEEE80211_MSG_STATE, "%s: %s -> %s (%d)\n", in tdma_newstate()
238 if (vap->iv_flags_ext & IEEE80211_FEXT_SWBMISS) in tdma_newstate()
239 callout_stop(&vap->iv_swbmiss); in tdma_newstate()
242 ts->tdma_slot != 0) { in tdma_newstate()
247 vap->iv_state = nstate; /* state transition */ in tdma_newstate()
251 ieee80211_iterate_nodes_vap(&ic->ic_sta, vap, in tdma_newstate()
254 if (vap->iv_flags_ext & IEEE80211_FEXT_SCANREQ) { in tdma_newstate()
256 vap->iv_scanreq_flags, in tdma_newstate()
257 vap->iv_scanreq_duration, in tdma_newstate()
258 vap->iv_scanreq_mindwell, in tdma_newstate()
259 vap->iv_scanreq_maxdwell, in tdma_newstate()
260 vap->iv_scanreq_nssid, vap->iv_scanreq_ssid); in tdma_newstate()
261 vap->iv_flags_ext &= ~IEEE80211_FEXT_SCANREQ; in tdma_newstate()
266 status = ts->tdma_newstate(vap, nstate, arg); in tdma_newstate()
270 (vap->iv_flags_ext & IEEE80211_FEXT_SWBMISS) && in tdma_newstate()
271 ts->tdma_slot != 0 && in tdma_newstate()
272 vap->iv_des_chan == IEEE80211_CHAN_ANYC) { in tdma_newstate()
280 vap->iv_swbmiss_period = IEEE80211_TU_TO_TICKS( in tdma_newstate()
281 2 * vap->iv_bmissthreshold * ts->tdma_bintval * in tdma_newstate()
282 ((ts->tdma_slotcnt * ts->tdma_slotlen) / 1024)); in tdma_newstate()
283 vap->iv_swbmiss_count = 0; in tdma_newstate()
284 callout_reset(&vap->iv_swbmiss, vap->iv_swbmiss_period, in tdma_newstate()
293 struct ieee80211_tdma_state *ts = vap->iv_tdma; in tdma_beacon_miss()
295 IEEE80211_LOCK_ASSERT(vap->iv_ic); in tdma_beacon_miss()
297 KASSERT((vap->iv_ic->ic_flags & IEEE80211_F_SCAN) == 0, ("scanning")); in tdma_beacon_miss()
298 KASSERT(vap->iv_state == IEEE80211_S_RUN, in tdma_beacon_miss()
299 ("wrong state %d", vap->iv_state)); in tdma_beacon_miss()
304 vap->iv_opmode, ieee80211_state_name[vap->iv_state]); in tdma_beacon_miss()
306 callout_stop(&vap->iv_swbmiss); in tdma_beacon_miss()
308 if (ts->tdma_peer != NULL) { /* XXX? can this be null? */ in tdma_beacon_miss()
309 ieee80211_notify_node_leave(vap->iv_bss); in tdma_beacon_miss()
310 ts->tdma_peer = NULL; in tdma_beacon_miss()
316 ieee80211_scan_assoc_fail(vap, vap->iv_bss->ni_macaddr, in tdma_beacon_miss()
320 ts->tdma_inuse = 0; /* clear slot usage */ in tdma_beacon_miss()
329 struct ieee80211com *ic = ni->ni_ic; in tdma_recv_mgmt()
330 struct ieee80211vap *vap = ni->ni_vap; in tdma_recv_mgmt()
331 struct ieee80211_tdma_state *ts = vap->iv_tdma; in tdma_recv_mgmt()
334 (ic->ic_flags & IEEE80211_F_SCAN) == 0) { in tdma_recv_mgmt()
338 /* XXX TODO: use rxstatus to determine off-channel beacons */ in tdma_recv_mgmt()
339 if (ieee80211_parse_beacon(ni, m0, ic->ic_curchan, &scan) != 0) in tdma_recv_mgmt()
351 vap->iv_stats.is_rx_mgtdiscard++; in tdma_recv_mgmt()
354 if (ni == vap->iv_bss && in tdma_recv_mgmt()
355 !IEEE80211_ADDR_EQ(wh->i_addr2, ni->ni_macaddr)) { in tdma_recv_mgmt()
369 if (IEEE80211_ADDR_EQ(wh->i_addr3, ni->ni_bssid)) { in tdma_recv_mgmt()
373 vap->iv_stats.is_rx_beacon++; in tdma_recv_mgmt()
380 memcpy(&ni->ni_tstamp.data, scan.tstamp, in tdma_recv_mgmt()
381 sizeof(ni->ni_tstamp.data)); in tdma_recv_mgmt()
385 vap->iv_swbmiss_count++; in tdma_recv_mgmt()
388 * the slot timing, reconfigure the bss, etc. in tdma_recv_mgmt()
398 ts->tdma_recv_mgmt(ni, m0, subtype, rxs, rssi, nf); in tdma_recv_mgmt()
405 * is non-zero we scan the slot allocation state in the ie
406 * to locate a free slot for our use.
412 struct ieee80211_tdma_state *ts = vap->iv_tdma; in tdma_update()
413 int slot, slotlen, update; in tdma_update() local
415 KASSERT(vap->iv_caps & IEEE80211_C_TDMA, in tdma_update()
416 ("not a tdma vap, caps 0x%x", vap->iv_caps)); in tdma_update()
419 if (tdma->tdma_slotcnt != ts->tdma_slotcnt) { in tdma_update()
420 if (!TDMA_SLOTCNT_VALID(tdma->tdma_slotcnt)) { in tdma_update()
421 if (ppsratecheck(&ts->tdma_lastprint, &ts->tdma_fails, 1)) in tdma_update()
422 printf("%s: bad slot cnt %u\n", in tdma_update()
423 __func__, tdma->tdma_slotcnt); in tdma_update()
428 slotlen = le16toh(tdma->tdma_slotlen) * 100; in tdma_update()
429 if (slotlen != ts->tdma_slotlen) { in tdma_update()
431 if (ppsratecheck(&ts->tdma_lastprint, &ts->tdma_fails, 1)) in tdma_update()
432 printf("%s: bad slot len %u\n", in tdma_update()
438 if (tdma->tdma_bintval != ts->tdma_bintval) { in tdma_update()
439 if (!TDMA_BINTVAL_VALID(tdma->tdma_bintval)) { in tdma_update()
440 if (ppsratecheck(&ts->tdma_lastprint, &ts->tdma_fails, 1)) in tdma_update()
442 __func__, tdma->tdma_bintval); in tdma_update()
447 slot = ts->tdma_slot; in tdma_update()
450 * Pick unoccupied slot. Note we never choose slot 0. in tdma_update()
452 for (slot = tdma->tdma_slotcnt-1; slot > 0; slot--) in tdma_update()
453 if (isclr(tdma->tdma_inuse, slot)) in tdma_update()
455 if (slot <= 0) { in tdma_update()
456 printf("%s: no free slot, slotcnt %u inuse: 0x%x\n", in tdma_update()
457 __func__, tdma->tdma_slotcnt, in tdma_update()
458 tdma->tdma_inuse[0]); in tdma_update()
462 if (slot != ts->tdma_slot) in tdma_update()
465 if (ni != ts->tdma_peer) { in tdma_update()
479 ts->tdma_slotcnt = tdma->tdma_slotcnt; in tdma_update()
481 ts->tdma_slotlen = slotlen; in tdma_update()
483 ts->tdma_slot = slot; in tdma_update()
485 ts->tdma_bintval = tdma->tdma_bintval; in tdma_update()
490 "%s: slot %u slotcnt %u slotlen %u us bintval %u\n", in tdma_update()
491 __func__, ts->tdma_slot, ts->tdma_slotcnt, in tdma_update()
492 ts->tdma_slotlen, ts->tdma_bintval); in tdma_update()
501 if (vap->iv_state == IEEE80211_S_RUN) in tdma_update()
502 vap->iv_ic->ic_tdma_update(ni, tdma, update); in tdma_update()
506 if (ts->tdma_peer != ni) { in tdma_update()
507 if (ts->tdma_peer != NULL) in tdma_update()
508 ieee80211_notify_node_leave(vap->iv_bss); in tdma_update()
511 ts->tdma_peer = ni; in tdma_update()
523 struct ieee80211vap *vap = ni->ni_vap; in tdma_process_params()
524 struct ieee80211_tdma_state *ts = vap->iv_tdma; in tdma_process_params()
529 KASSERT(vap->iv_caps & IEEE80211_C_TDMA, in tdma_process_params()
530 ("not a tdma vap, caps 0x%x", vap->iv_caps)); in tdma_process_params()
532 if (len < sizeof(*tdma) - 2) { in tdma_process_params()
538 if (tdma->tdma_version != ts->tdma_version) { in tdma_process_params()
542 tdma->tdma_version, ts->tdma_version); in tdma_process_params()
551 if (tdma->tdma_slot >= TDMA_MAXSLOTS) { in tdma_process_params()
554 wh, "tdma", "invalid slot %u", tdma->tdma_slot); in tdma_process_params()
561 if (vap->iv_state == IEEE80211_S_RUN) { in tdma_process_params()
562 if (tdma->tdma_slot != ts->tdma_slot && in tdma_process_params()
563 isclr(ts->tdma_inuse, tdma->tdma_slot)) { in tdma_process_params()
565 "discovered in slot %u", tdma->tdma_slot); in tdma_process_params()
566 setbit(ts->tdma_inuse, tdma->tdma_slot); in tdma_process_params()
568 if (ts->tdma_slot == 0) in tdma_process_params()
571 setbit(ts->tdma_active, tdma->tdma_slot); in tdma_process_params()
572 if (tdma->tdma_slot == ts->tdma_slot-1) { in tdma_process_params()
579 * trip time. We cannot do that here because in tdma_process_params()
584 } else if (tdma->tdma_slot == ts->tdma_slot+1) { in tdma_process_params()
587 uint32_t rstamp = (uint32_t) le64toh(rs->tsf); in tdma_process_params()
592 * roundtrip time. in tdma_process_params()
594 memcpy(&tstamp, tdma->tdma_tstamp, 8); in tdma_process_params()
597 rtt = rstamp - (le64toh(tstamp) & 0x7fff); in tdma_process_params()
606 } else if (tdma->tdma_slot == ts->tdma_slot && in tdma_process_params()
607 le64toh(ni->ni_tstamp.tsf) > vap->iv_bss->ni_tstamp.tsf) { in tdma_process_params()
609 * Station using the same slot as us and has in tdma_process_params()
615 "slot %u collision rxtsf %llu tsf %llu\n", in tdma_process_params()
616 tdma->tdma_slot, in tdma_process_params()
617 (unsigned long long) le64toh(ni->ni_tstamp.tsf), in tdma_process_params()
618 vap->iv_bss->ni_tstamp.tsf); in tdma_process_params()
619 setbit(ts->tdma_inuse, tdma->tdma_slot); in tdma_process_params()
630 struct ieee80211_tdma_state *ts = vap->iv_tdma; in ieee80211_tdma_getslot()
632 KASSERT(vap->iv_caps & IEEE80211_C_TDMA, in ieee80211_tdma_getslot()
633 ("not a tdma vap, caps 0x%x", vap->iv_caps)); in ieee80211_tdma_getslot()
634 return ts->tdma_slot; in ieee80211_tdma_getslot()
643 struct ieee80211vap *vap = ni->ni_vap; in ieee80211_parse_tdma()
645 if (vap->iv_caps & IEEE80211_C_TDMA) { in ieee80211_parse_tdma()
648 struct ieee80211_tdma_state *ts = vap->iv_tdma; in ieee80211_parse_tdma()
653 setbit(ts->tdma_inuse, tdma->tdma_slot); in ieee80211_parse_tdma()
661 if ((vap->iv_flags & IEEE80211_F_WME) && in ieee80211_parse_tdma()
662 ni->ni_ies.wme_ie != NULL) in ieee80211_parse_tdma()
663 ni->ni_flags |= IEEE80211_NODE_QOS; in ieee80211_parse_tdma()
681 .tdma_len = sizeof(struct ieee80211_tdma_param) - 2, in ieee80211_add_tdma()
687 const struct ieee80211_tdma_state *ts = vap->iv_tdma; in ieee80211_add_tdma()
690 KASSERT(vap->iv_caps & IEEE80211_C_TDMA, in ieee80211_add_tdma()
691 ("not a tdma vap, caps 0x%x", vap->iv_caps)); in ieee80211_add_tdma()
695 *frm++ = ts->tdma_slot; in ieee80211_add_tdma()
696 *frm++ = ts->tdma_slotcnt; in ieee80211_add_tdma()
697 /* NB: convert units to fit in 16-bits */ in ieee80211_add_tdma()
698 slotlen = ts->tdma_slotlen / 100; /* 100us units */ in ieee80211_add_tdma()
700 *frm++ = ts->tdma_bintval; in ieee80211_add_tdma()
701 *frm++ = ts->tdma_inuse[0]; in ieee80211_add_tdma()
715 struct ieee80211_tdma_state *ts = vap->iv_tdma; in ieee80211_tdma_update_beacon()
717 KASSERT(vap->iv_caps & IEEE80211_C_TDMA, in ieee80211_tdma_update_beacon()
718 ("not a tdma vap, caps 0x%x", vap->iv_caps)); in ieee80211_tdma_update_beacon()
720 if (isset(bo->bo_flags, IEEE80211_BEACON_TDMA)) { in ieee80211_tdma_update_beacon()
721 (void) ieee80211_add_tdma(bo->bo_tdma, vap); in ieee80211_tdma_update_beacon()
722 clrbit(bo->bo_flags, IEEE80211_BEACON_TDMA); in ieee80211_tdma_update_beacon()
724 if (ts->tdma_slot != 0) /* only on master */ in ieee80211_tdma_update_beacon()
726 if (ts->tdma_count <= 0) { in ieee80211_tdma_update_beacon()
728 * Time to update the mask of active/inuse stations. in ieee80211_tdma_update_beacon()
732 * a slot free for re-use. in ieee80211_tdma_update_beacon()
734 ts->tdma_inuse[0] = ts->tdma_active[0]; in ieee80211_tdma_update_beacon()
735 ts->tdma_active[0] = 0x01; in ieee80211_tdma_update_beacon()
736 /* update next time 'round */ in ieee80211_tdma_update_beacon()
738 setbit(bo->bo_flags, IEEE80211_BEACON_TDMA); in ieee80211_tdma_update_beacon()
740 ts->tdma_count = vap->iv_bmissthreshold-1; in ieee80211_tdma_update_beacon()
742 ts->tdma_count--; in ieee80211_tdma_update_beacon()
748 struct ieee80211_tdma_state *ts = vap->iv_tdma; in tdma_ioctl_get80211()
750 if ((vap->iv_caps & IEEE80211_C_TDMA) == 0) in tdma_ioctl_get80211()
753 switch (ireq->i_type) { in tdma_ioctl_get80211()
755 ireq->i_val = ts->tdma_slot; in tdma_ioctl_get80211()
758 ireq->i_val = ts->tdma_slotcnt; in tdma_ioctl_get80211()
761 ireq->i_val = ts->tdma_slotlen; in tdma_ioctl_get80211()
764 ireq->i_val = ts->tdma_bintval; in tdma_ioctl_get80211()
776 struct ieee80211_tdma_state *ts = vap->iv_tdma; in tdma_ioctl_set80211()
778 if ((vap->iv_caps & IEEE80211_C_TDMA) == 0) in tdma_ioctl_set80211()
781 switch (ireq->i_type) { in tdma_ioctl_set80211()
783 if (!(0 <= ireq->i_val && ireq->i_val <= ts->tdma_slotcnt)) in tdma_ioctl_set80211()
785 if (ireq->i_val != ts->tdma_slot) { in tdma_ioctl_set80211()
786 ts->tdma_slot = ireq->i_val; in tdma_ioctl_set80211()
791 if (!TDMA_SLOTCNT_VALID(ireq->i_val)) in tdma_ioctl_set80211()
793 if (ireq->i_val != ts->tdma_slotcnt) { in tdma_ioctl_set80211()
794 ts->tdma_slotcnt = ireq->i_val; in tdma_ioctl_set80211()
803 * (implict by way of 16-bit data type for i_val) in tdma_ioctl_set80211()
805 if (!TDMA_SLOTLEN_VALID(ireq->i_val)) in tdma_ioctl_set80211()
807 if (ireq->i_val != ts->tdma_slotlen) { in tdma_ioctl_set80211()
808 ts->tdma_slotlen = ireq->i_val; in tdma_ioctl_set80211()
813 if (!TDMA_BINTVAL_VALID(ireq->i_val)) in tdma_ioctl_set80211()
815 if (ireq->i_val != ts->tdma_bintval) { in tdma_ioctl_set80211()
816 ts->tdma_bintval = ireq->i_val; in tdma_ioctl_set80211()