1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17#include "ath9k.h"
18
19#define FUDGE 2
20
21
22
23
24
25
26int ath_beaconq_config(struct ath_softc *sc)
27{
28 struct ath_hw *ah = sc->sc_ah;
29 struct ath_common *common = ath9k_hw_common(ah);
30 struct ath9k_tx_queue_info qi, qi_be;
31 struct ath_txq *txq;
32
33 ath9k_hw_get_txq_props(ah, sc->beacon.beaconq, &qi);
34 if (sc->sc_ah->opmode == NL80211_IFTYPE_AP) {
35
36 qi.tqi_aifs = 1;
37 qi.tqi_cwmin = 0;
38 qi.tqi_cwmax = 0;
39 } else {
40
41 txq = sc->tx.txq_map[WME_AC_BE];
42 ath9k_hw_get_txq_props(ah, txq->axq_qnum, &qi_be);
43 qi.tqi_aifs = qi_be.tqi_aifs;
44 qi.tqi_cwmin = 4*qi_be.tqi_cwmin;
45 qi.tqi_cwmax = qi_be.tqi_cwmax;
46 }
47
48 if (!ath9k_hw_set_txq_props(ah, sc->beacon.beaconq, &qi)) {
49 ath_err(common,
50 "Unable to update h/w beacon queue parameters\n");
51 return 0;
52 } else {
53 ath9k_hw_resettxqueue(ah, sc->beacon.beaconq);
54 return 1;
55 }
56}
57
58
59
60
61
62
63static void ath_beacon_setup(struct ath_softc *sc, struct ath_vif *avp,
64 struct ath_buf *bf, int rateidx)
65{
66 struct sk_buff *skb = bf->bf_mpdu;
67 struct ath_hw *ah = sc->sc_ah;
68 struct ath_common *common = ath9k_hw_common(ah);
69 struct ath_desc *ds;
70 struct ath9k_11n_rate_series series[4];
71 int flags, antenna, ctsrate = 0, ctsduration = 0;
72 struct ieee80211_supported_band *sband;
73 u8 rate = 0;
74
75 ds = bf->bf_desc;
76 flags = ATH9K_TXDESC_NOACK;
77
78 ds->ds_link = 0;
79
80
81
82
83
84 antenna = ((sc->beacon.ast_be_xmit / sc->nbcnvifs) & 1 ? 2 : 1);
85
86 sband = &sc->sbands[common->hw->conf.channel->band];
87 rate = sband->bitrates[rateidx].hw_value;
88 if (sc->sc_flags & SC_OP_PREAMBLE_SHORT)
89 rate |= sband->bitrates[rateidx].hw_value_short;
90
91 ath9k_hw_set11n_txdesc(ah, ds, skb->len + FCS_LEN,
92 ATH9K_PKT_TYPE_BEACON,
93 MAX_RATE_POWER,
94 ATH9K_TXKEYIX_INVALID,
95 ATH9K_KEY_TYPE_CLEAR,
96 flags);
97
98
99 ath9k_hw_filltxdesc(ah, ds, roundup(skb->len, 4),
100 true, true, ds, bf->bf_buf_addr,
101 sc->beacon.beaconq);
102
103 memset(series, 0, sizeof(struct ath9k_11n_rate_series) * 4);
104 series[0].Tries = 1;
105 series[0].Rate = rate;
106 series[0].ChSel = ath_txchainmask_reduction(sc,
107 common->tx_chainmask, series[0].Rate);
108 series[0].RateFlags = (ctsrate) ? ATH9K_RATESERIES_RTS_CTS : 0;
109 ath9k_hw_set11n_ratescenario(ah, ds, ds, 0, ctsrate, ctsduration,
110 series, 4, 0);
111}
112
113static void ath_tx_cabq(struct ieee80211_hw *hw, struct sk_buff *skb)
114{
115 struct ath_wiphy *aphy = hw->priv;
116 struct ath_softc *sc = aphy->sc;
117 struct ath_common *common = ath9k_hw_common(sc->sc_ah);
118 struct ath_tx_control txctl;
119
120 memset(&txctl, 0, sizeof(struct ath_tx_control));
121 txctl.txq = sc->beacon.cabq;
122
123 ath_dbg(common, ATH_DBG_XMIT,
124 "transmitting CABQ packet, skb: %p\n", skb);
125
126 if (ath_tx_start(hw, skb, &txctl) != 0) {
127 ath_dbg(common, ATH_DBG_XMIT, "CABQ TX failed\n");
128 dev_kfree_skb_any(skb);
129 }
130}
131
132static struct ath_buf *ath_beacon_generate(struct ieee80211_hw *hw,
133 struct ieee80211_vif *vif)
134{
135 struct ath_wiphy *aphy = hw->priv;
136 struct ath_softc *sc = aphy->sc;
137 struct ath_common *common = ath9k_hw_common(sc->sc_ah);
138 struct ath_buf *bf;
139 struct ath_vif *avp;
140 struct sk_buff *skb;
141 struct ath_txq *cabq;
142 struct ieee80211_tx_info *info;
143 int cabq_depth;
144
145 if (aphy->state != ATH_WIPHY_ACTIVE)
146 return NULL;
147
148 avp = (void *)vif->drv_priv;
149 cabq = sc->beacon.cabq;
150
151 if (avp->av_bcbuf == NULL)
152 return NULL;
153
154
155
156 bf = avp->av_bcbuf;
157 skb = bf->bf_mpdu;
158 if (skb) {
159 dma_unmap_single(sc->dev, bf->bf_buf_addr,
160 skb->len, DMA_TO_DEVICE);
161 dev_kfree_skb_any(skb);
162 bf->bf_buf_addr = 0;
163 }
164
165
166
167 skb = ieee80211_beacon_get(hw, vif);
168 bf->bf_mpdu = skb;
169 if (skb == NULL)
170 return NULL;
171 ((struct ieee80211_mgmt *)skb->data)->u.beacon.timestamp =
172 avp->tsf_adjust;
173
174 info = IEEE80211_SKB_CB(skb);
175 if (info->flags & IEEE80211_TX_CTL_ASSIGN_SEQ) {
176
177
178
179
180 struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data;
181 sc->tx.seq_no += 0x10;
182 hdr->seq_ctrl &= cpu_to_le16(IEEE80211_SCTL_FRAG);
183 hdr->seq_ctrl |= cpu_to_le16(sc->tx.seq_no);
184 }
185
186 bf->bf_buf_addr = dma_map_single(sc->dev, skb->data,
187 skb->len, DMA_TO_DEVICE);
188 if (unlikely(dma_mapping_error(sc->dev, bf->bf_buf_addr))) {
189 dev_kfree_skb_any(skb);
190 bf->bf_mpdu = NULL;
191 bf->bf_buf_addr = 0;
192 ath_err(common, "dma_mapping_error on beaconing\n");
193 return NULL;
194 }
195
196 skb = ieee80211_get_buffered_bc(hw, vif);
197
198
199
200
201
202
203
204
205
206 spin_lock_bh(&cabq->axq_lock);
207 cabq_depth = cabq->axq_depth;
208 spin_unlock_bh(&cabq->axq_lock);
209
210 if (skb && cabq_depth) {
211 if (sc->nvifs > 1) {
212 ath_dbg(common, ATH_DBG_BEACON,
213 "Flushing previous cabq traffic\n");
214 ath_draintxq(sc, cabq, false);
215 }
216 }
217
218 ath_beacon_setup(sc, avp, bf, info->control.rates[0].idx);
219
220 while (skb) {
221 ath_tx_cabq(hw, skb);
222 skb = ieee80211_get_buffered_bc(hw, vif);
223 }
224
225 return bf;
226}
227
228int ath_beacon_alloc(struct ath_wiphy *aphy, struct ieee80211_vif *vif)
229{
230 struct ath_softc *sc = aphy->sc;
231 struct ath_common *common = ath9k_hw_common(sc->sc_ah);
232 struct ath_vif *avp;
233 struct ath_buf *bf;
234 struct sk_buff *skb;
235 __le64 tstamp;
236
237 avp = (void *)vif->drv_priv;
238
239
240 if (!avp->av_bcbuf) {
241
242
243 avp->av_bcbuf = list_first_entry(&sc->beacon.bbuf,
244 struct ath_buf, list);
245 list_del(&avp->av_bcbuf->list);
246
247 if (sc->sc_ah->opmode == NL80211_IFTYPE_AP ||
248 sc->sc_ah->opmode == NL80211_IFTYPE_ADHOC ||
249 sc->sc_ah->opmode == NL80211_IFTYPE_MESH_POINT) {
250 int slot;
251
252
253
254
255 avp->av_bslot = 0;
256 for (slot = 0; slot < ATH_BCBUF; slot++)
257 if (sc->beacon.bslot[slot] == NULL) {
258 avp->av_bslot = slot;
259
260
261 if (slot == 0 || !sc->beacon.bslot[slot-1])
262 break;
263 }
264 BUG_ON(sc->beacon.bslot[avp->av_bslot] != NULL);
265 sc->beacon.bslot[avp->av_bslot] = vif;
266 sc->beacon.bslot_aphy[avp->av_bslot] = aphy;
267 sc->nbcnvifs++;
268 }
269 }
270
271
272 bf = avp->av_bcbuf;
273 if (bf->bf_mpdu != NULL) {
274 skb = bf->bf_mpdu;
275 dma_unmap_single(sc->dev, bf->bf_buf_addr,
276 skb->len, DMA_TO_DEVICE);
277 dev_kfree_skb_any(skb);
278 bf->bf_mpdu = NULL;
279 bf->bf_buf_addr = 0;
280 }
281
282
283 skb = ieee80211_beacon_get(sc->hw, vif);
284 if (skb == NULL) {
285 ath_dbg(common, ATH_DBG_BEACON, "cannot get skb\n");
286 return -ENOMEM;
287 }
288
289 tstamp = ((struct ieee80211_mgmt *)skb->data)->u.beacon.timestamp;
290 sc->beacon.bc_tstamp = le64_to_cpu(tstamp);
291
292 if (avp->av_bslot > 0) {
293 u64 tsfadjust;
294 int intval;
295
296 intval = sc->beacon_interval ? : ATH_DEFAULT_BINTVAL;
297
298
299
300
301
302
303
304
305
306 tsfadjust = intval * avp->av_bslot / ATH_BCBUF;
307 avp->tsf_adjust = cpu_to_le64(TU_TO_USEC(tsfadjust));
308
309 ath_dbg(common, ATH_DBG_BEACON,
310 "stagger beacons, bslot %d intval %u tsfadjust %llu\n",
311 avp->av_bslot, intval, (unsigned long long)tsfadjust);
312
313 ((struct ieee80211_mgmt *)skb->data)->u.beacon.timestamp =
314 avp->tsf_adjust;
315 } else
316 avp->tsf_adjust = cpu_to_le64(0);
317
318 bf->bf_mpdu = skb;
319 bf->bf_buf_addr = dma_map_single(sc->dev, skb->data,
320 skb->len, DMA_TO_DEVICE);
321 if (unlikely(dma_mapping_error(sc->dev, bf->bf_buf_addr))) {
322 dev_kfree_skb_any(skb);
323 bf->bf_mpdu = NULL;
324 bf->bf_buf_addr = 0;
325 ath_err(common, "dma_mapping_error on beacon alloc\n");
326 return -ENOMEM;
327 }
328
329 return 0;
330}
331
332void ath_beacon_return(struct ath_softc *sc, struct ath_vif *avp)
333{
334 if (avp->av_bcbuf != NULL) {
335 struct ath_buf *bf;
336
337 if (avp->av_bslot != -1) {
338 sc->beacon.bslot[avp->av_bslot] = NULL;
339 sc->beacon.bslot_aphy[avp->av_bslot] = NULL;
340 sc->nbcnvifs--;
341 }
342
343 bf = avp->av_bcbuf;
344 if (bf->bf_mpdu != NULL) {
345 struct sk_buff *skb = bf->bf_mpdu;
346 dma_unmap_single(sc->dev, bf->bf_buf_addr,
347 skb->len, DMA_TO_DEVICE);
348 dev_kfree_skb_any(skb);
349 bf->bf_mpdu = NULL;
350 bf->bf_buf_addr = 0;
351 }
352 list_add_tail(&bf->list, &sc->beacon.bbuf);
353
354 avp->av_bcbuf = NULL;
355 }
356}
357
358void ath_beacon_tasklet(unsigned long data)
359{
360 struct ath_softc *sc = (struct ath_softc *)data;
361 struct ath_hw *ah = sc->sc_ah;
362 struct ath_common *common = ath9k_hw_common(ah);
363 struct ath_buf *bf = NULL;
364 struct ieee80211_vif *vif;
365 struct ath_wiphy *aphy;
366 int slot;
367 u32 bfaddr, bc = 0, tsftu;
368 u64 tsf;
369 u16 intval;
370
371
372
373
374
375
376
377
378 if (ath9k_hw_numtxpending(ah, sc->beacon.beaconq) != 0) {
379 sc->beacon.bmisscnt++;
380
381 if (sc->beacon.bmisscnt < BSTUCK_THRESH) {
382 ath_dbg(common, ATH_DBG_BSTUCK,
383 "missed %u consecutive beacons\n",
384 sc->beacon.bmisscnt);
385 ath9k_hw_bstuck_nfcal(ah);
386 } else if (sc->beacon.bmisscnt >= BSTUCK_THRESH) {
387 ath_dbg(common, ATH_DBG_BSTUCK,
388 "beacon is officially stuck\n");
389 sc->sc_flags |= SC_OP_TSF_RESET;
390 ath_reset(sc, true);
391 }
392
393 return;
394 }
395
396 if (sc->beacon.bmisscnt != 0) {
397 ath_dbg(common, ATH_DBG_BSTUCK,
398 "resume beacon xmit after %u misses\n",
399 sc->beacon.bmisscnt);
400 sc->beacon.bmisscnt = 0;
401 }
402
403
404
405
406
407
408
409 intval = sc->beacon_interval ? : ATH_DEFAULT_BINTVAL;
410
411 tsf = ath9k_hw_gettsf64(ah);
412 tsftu = TSF_TO_TU(tsf>>32, tsf);
413 slot = ((tsftu % intval) * ATH_BCBUF) / intval;
414
415
416
417
418
419
420
421 slot = ATH_BCBUF - slot - 1;
422 vif = sc->beacon.bslot[slot];
423 aphy = sc->beacon.bslot_aphy[slot];
424
425 ath_dbg(common, ATH_DBG_BEACON,
426 "slot %d [tsf %llu tsftu %u intval %u] vif %p\n",
427 slot, tsf, tsftu, intval, vif);
428
429 bfaddr = 0;
430 if (vif) {
431 bf = ath_beacon_generate(aphy->hw, vif);
432 if (bf != NULL) {
433 bfaddr = bf->bf_daddr;
434 bc = 1;
435 }
436 }
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454 if (sc->beacon.updateslot == UPDATE) {
455 sc->beacon.updateslot = COMMIT;
456 sc->beacon.slotupdate = slot;
457 } else if (sc->beacon.updateslot == COMMIT && sc->beacon.slotupdate == slot) {
458 ah->slottime = sc->beacon.slottime;
459 ath9k_hw_init_global_settings(ah);
460 sc->beacon.updateslot = OK;
461 }
462 if (bfaddr != 0) {
463
464
465
466
467
468 if (!ath9k_hw_stoptxdma(ah, sc->beacon.beaconq)) {
469 ath_err(common, "beacon queue %u did not stop?\n",
470 sc->beacon.beaconq);
471 }
472
473
474 ath9k_hw_puttxbuf(ah, sc->beacon.beaconq, bfaddr);
475 ath9k_hw_txstart(ah, sc->beacon.beaconq);
476
477 sc->beacon.ast_be_xmit += bc;
478 }
479}
480
481static void ath9k_beacon_init(struct ath_softc *sc,
482 u32 next_beacon,
483 u32 beacon_period)
484{
485 if (beacon_period & ATH9K_BEACON_RESET_TSF)
486 ath9k_ps_wakeup(sc);
487
488 ath9k_hw_beaconinit(sc->sc_ah, next_beacon, beacon_period);
489
490 if (beacon_period & ATH9K_BEACON_RESET_TSF)
491 ath9k_ps_restore(sc);
492}
493
494
495
496
497
498
499static void ath_beacon_config_ap(struct ath_softc *sc,
500 struct ath_beacon_config *conf)
501{
502 struct ath_hw *ah = sc->sc_ah;
503 u32 nexttbtt, intval;
504
505
506 intval = conf->beacon_interval & ATH9K_BEACON_PERIOD;
507 intval /= ATH_BCBUF;
508 nexttbtt = intval;
509
510 if (sc->sc_flags & SC_OP_TSF_RESET)
511 intval |= ATH9K_BEACON_RESET_TSF;
512
513
514
515
516
517 intval |= ATH9K_BEACON_ENA;
518 ah->imask |= ATH9K_INT_SWBA;
519 ath_beaconq_config(sc);
520
521
522
523 ath9k_hw_disable_interrupts(ah);
524 ath9k_beacon_init(sc, nexttbtt, intval);
525 sc->beacon.bmisscnt = 0;
526 ath9k_hw_set_interrupts(ah, ah->imask);
527
528
529
530
531 sc->sc_flags &= ~SC_OP_TSF_RESET;
532}
533
534
535
536
537
538
539
540
541
542static void ath_beacon_config_sta(struct ath_softc *sc,
543 struct ath_beacon_config *conf)
544{
545 struct ath_hw *ah = sc->sc_ah;
546 struct ath_common *common = ath9k_hw_common(ah);
547 struct ath9k_beacon_state bs;
548 int dtimperiod, dtimcount, sleepduration;
549 int cfpperiod, cfpcount;
550 u32 nexttbtt = 0, intval, tsftu;
551 u64 tsf;
552 int num_beacons, offset, dtim_dec_count, cfp_dec_count;
553
554
555 if (!common->curaid) {
556 ath_dbg(common, ATH_DBG_BEACON,
557 "STA is not yet associated..skipping beacon config\n");
558 return;
559 }
560
561 memset(&bs, 0, sizeof(bs));
562 intval = conf->beacon_interval & ATH9K_BEACON_PERIOD;
563
564
565
566
567
568 dtimperiod = conf->dtim_period;
569 dtimcount = conf->dtim_count;
570 if (dtimcount >= dtimperiod)
571 dtimcount = 0;
572 cfpperiod = 1;
573 cfpcount = 0;
574
575 sleepduration = conf->listen_interval * intval;
576
577
578
579
580
581 tsf = ath9k_hw_gettsf64(ah);
582 tsftu = TSF_TO_TU(tsf>>32, tsf) + FUDGE;
583
584 num_beacons = tsftu / intval + 1;
585 offset = tsftu % intval;
586 nexttbtt = tsftu - offset;
587 if (offset)
588 nexttbtt += intval;
589
590
591 dtim_dec_count = num_beacons % dtimperiod;
592
593 cfp_dec_count = (num_beacons / dtimperiod) % cfpperiod;
594 if (dtim_dec_count)
595 cfp_dec_count++;
596
597 dtimcount -= dtim_dec_count;
598 if (dtimcount < 0)
599 dtimcount += dtimperiod;
600
601 cfpcount -= cfp_dec_count;
602 if (cfpcount < 0)
603 cfpcount += cfpperiod;
604
605 bs.bs_intval = intval;
606 bs.bs_nexttbtt = nexttbtt;
607 bs.bs_dtimperiod = dtimperiod*intval;
608 bs.bs_nextdtim = bs.bs_nexttbtt + dtimcount*intval;
609 bs.bs_cfpperiod = cfpperiod*bs.bs_dtimperiod;
610 bs.bs_cfpnext = bs.bs_nextdtim + cfpcount*bs.bs_dtimperiod;
611 bs.bs_cfpmaxduration = 0;
612
613
614
615
616
617
618
619 if (sleepduration > intval) {
620 bs.bs_bmissthreshold = conf->listen_interval *
621 ATH_DEFAULT_BMISS_LIMIT / 2;
622 } else {
623 bs.bs_bmissthreshold = DIV_ROUND_UP(conf->bmiss_timeout, intval);
624 if (bs.bs_bmissthreshold > 15)
625 bs.bs_bmissthreshold = 15;
626 else if (bs.bs_bmissthreshold <= 0)
627 bs.bs_bmissthreshold = 1;
628 }
629
630
631
632
633
634
635
636
637
638
639 bs.bs_sleepduration = roundup(IEEE80211_MS_TO_TU(100), sleepduration);
640 if (bs.bs_sleepduration > bs.bs_dtimperiod)
641 bs.bs_sleepduration = bs.bs_dtimperiod;
642
643
644 bs.bs_tsfoor_threshold = ATH9K_TSFOOR_THRESHOLD;
645
646 ath_dbg(common, ATH_DBG_BEACON, "tsf: %llu tsftu: %u\n", tsf, tsftu);
647 ath_dbg(common, ATH_DBG_BEACON,
648 "bmiss: %u sleep: %u cfp-period: %u maxdur: %u next: %u\n",
649 bs.bs_bmissthreshold, bs.bs_sleepduration,
650 bs.bs_cfpperiod, bs.bs_cfpmaxduration, bs.bs_cfpnext);
651
652
653
654 ath9k_hw_disable_interrupts(ah);
655 ath9k_hw_set_sta_beacon_timers(ah, &bs);
656 ah->imask |= ATH9K_INT_BMISS;
657 ath9k_hw_set_interrupts(ah, ah->imask);
658}
659
660static void ath_beacon_config_adhoc(struct ath_softc *sc,
661 struct ath_beacon_config *conf)
662{
663 struct ath_hw *ah = sc->sc_ah;
664 struct ath_common *common = ath9k_hw_common(ah);
665 u64 tsf;
666 u32 tsftu, intval, nexttbtt;
667
668 intval = conf->beacon_interval & ATH9K_BEACON_PERIOD;
669
670
671
672
673 nexttbtt = TSF_TO_TU(sc->beacon.bc_tstamp >> 32, sc->beacon.bc_tstamp);
674 if (nexttbtt == 0)
675 nexttbtt = intval;
676 else if (intval)
677 nexttbtt = roundup(nexttbtt, intval);
678
679 tsf = ath9k_hw_gettsf64(ah);
680 tsftu = TSF_TO_TU((u32)(tsf>>32), (u32)tsf) + FUDGE;
681 do {
682 nexttbtt += intval;
683 } while (nexttbtt < tsftu);
684
685 ath_dbg(common, ATH_DBG_BEACON,
686 "IBSS nexttbtt %u intval %u (%u)\n",
687 nexttbtt, intval, conf->beacon_interval);
688
689
690
691
692
693
694 intval |= ATH9K_BEACON_ENA;
695 ah->imask |= ATH9K_INT_SWBA;
696
697 ath_beaconq_config(sc);
698
699
700
701 ath9k_hw_disable_interrupts(ah);
702 ath9k_beacon_init(sc, nexttbtt, intval);
703 sc->beacon.bmisscnt = 0;
704 ath9k_hw_set_interrupts(ah, ah->imask);
705}
706
707void ath_beacon_config(struct ath_softc *sc, struct ieee80211_vif *vif)
708{
709 struct ath_beacon_config *cur_conf = &sc->cur_beacon_conf;
710 struct ath_common *common = ath9k_hw_common(sc->sc_ah);
711 enum nl80211_iftype iftype;
712
713
714 if (vif) {
715 struct ieee80211_bss_conf *bss_conf = &vif->bss_conf;
716 iftype = vif->type;
717 cur_conf->beacon_interval = bss_conf->beacon_int;
718 cur_conf->dtim_period = bss_conf->dtim_period;
719 } else {
720 iftype = sc->sc_ah->opmode;
721 }
722
723 cur_conf->listen_interval = 1;
724 cur_conf->dtim_count = 1;
725 cur_conf->bmiss_timeout =
726 ATH_DEFAULT_BMISS_LIMIT * cur_conf->beacon_interval;
727
728
729
730
731
732
733
734 if (cur_conf->beacon_interval == 0)
735 cur_conf->beacon_interval = 100;
736
737
738
739
740
741 if (cur_conf->dtim_period == 0)
742 cur_conf->dtim_period = 1;
743
744 switch (iftype) {
745 case NL80211_IFTYPE_AP:
746 ath_beacon_config_ap(sc, cur_conf);
747 break;
748 case NL80211_IFTYPE_ADHOC:
749 case NL80211_IFTYPE_MESH_POINT:
750 ath_beacon_config_adhoc(sc, cur_conf);
751 break;
752 case NL80211_IFTYPE_STATION:
753 ath_beacon_config_sta(sc, cur_conf);
754 break;
755 default:
756 ath_dbg(common, ATH_DBG_CONFIG,
757 "Unsupported beaconing mode\n");
758 return;
759 }
760
761 sc->sc_flags |= SC_OP_BEACONS;
762}
763