@@ -59,12 +59,12 @@ struct scan_state {
59
59
#define ISCAN_DISCARD 0x0002 /* discard rx'd frames */
60
60
#define ISCAN_CANCEL 0x0004 /* cancel current scan */
61
61
#define ISCAN_ABORT 0x0008 /* end the scan immediately */
62
+ #define ISCAN_RUNNING 0x0010 /* scan was started */
62
63
unsigned long ss_chanmindwell ; /* min dwell on curchan */
63
64
unsigned long ss_scanend ; /* time scan must stop */
64
65
u_int ss_duration ; /* duration for next scan */
65
- struct task ss_scan_task ; /* scan execution */
66
- struct cv ss_scan_cv ; /* scan signal */
67
- struct callout ss_scan_timer ; /* scan timer */
66
+ struct task ss_scan_start ; /* scan start */
67
+ struct timeout_task ss_scan_curchan ; /* scan execution */
68
68
};
69
69
#define SCAN_PRIVATE (ss ) ((struct scan_state *) ss)
70
70
@@ -99,7 +99,8 @@ struct scan_state {
99
99
static void scan_curchan (struct ieee80211_scan_state * , unsigned long );
100
100
static void scan_mindwell (struct ieee80211_scan_state * );
101
101
static void scan_signal (void * );
102
- static void scan_task (void * , int );
102
+ static void scan_start (void * , int );
103
+ static void scan_curchan_task (void * , int );
103
104
static void scan_end (struct ieee80211_scan_state * , int );
104
105
static void scan_done (struct ieee80211_scan_state * , int );
105
106
@@ -115,8 +116,9 @@ ieee80211_swscan_detach(struct ieee80211com *ic)
115
116
SCAN_PRIVATE (ss )-> ss_iflags |= ISCAN_ABORT ;
116
117
scan_signal (ss );
117
118
IEEE80211_UNLOCK (ic );
118
- ieee80211_draintask (ic , & SCAN_PRIVATE (ss )-> ss_scan_task );
119
- callout_drain (& SCAN_PRIVATE (ss )-> ss_scan_timer );
119
+ ieee80211_draintask (ic , & SCAN_PRIVATE (ss )-> ss_scan_start );
120
+ taskqueue_drain_timeout (ic -> ic_tq ,
121
+ & SCAN_PRIVATE (ss )-> ss_scan_curchan );
120
122
KASSERT ((ic -> ic_flags & IEEE80211_F_SCAN ) == 0 ,
121
123
("scan still running" ));
122
124
@@ -238,7 +240,7 @@ ieee80211_swscan_start_scan_locked(const struct ieee80211_scanner *scan,
238
240
ic -> ic_flags |= IEEE80211_F_SCAN ;
239
241
240
242
/* Start scan task */
241
- ieee80211_runtask (ic , & SCAN_PRIVATE (ss )-> ss_scan_task );
243
+ ieee80211_runtask (ic , & SCAN_PRIVATE (ss )-> ss_scan_start );
242
244
}
243
245
return 1 ;
244
246
} else {
@@ -413,7 +415,8 @@ ieee80211_swscan_bg_scan(const struct ieee80211_scanner *scan,
413
415
ss -> ss_maxdwell = duration ;
414
416
ic -> ic_flags |= IEEE80211_F_SCAN ;
415
417
ic -> ic_flags_ext |= IEEE80211_FEXT_BGSCAN ;
416
- ieee80211_runtask (ic , & SCAN_PRIVATE (ss )-> ss_scan_task );
418
+ ieee80211_runtask (ic ,
419
+ & SCAN_PRIVATE (ss )-> ss_scan_start );
417
420
} else {
418
421
/* XXX msg+stat */
419
422
}
@@ -560,18 +563,25 @@ scan_curchan(struct ieee80211_scan_state *ss, unsigned long maxdwell)
560
563
IEEE80211_LOCK (vap -> iv_ic );
561
564
if (ss -> ss_flags & IEEE80211_SCAN_ACTIVE )
562
565
ieee80211_probe_curchan (vap , 0 );
563
- callout_reset ( & SCAN_PRIVATE ( ss ) -> ss_scan_timer ,
564
- maxdwell , scan_signal , ss );
566
+ taskqueue_enqueue_timeout ( vap -> iv_ic -> ic_tq ,
567
+ & SCAN_PRIVATE ( ss ) -> ss_scan_curchan , maxdwell );
565
568
IEEE80211_UNLOCK (vap -> iv_ic );
566
569
}
567
570
568
571
static void
569
572
scan_signal (void * arg )
570
573
{
571
574
struct ieee80211_scan_state * ss = (struct ieee80211_scan_state * ) arg ;
575
+ struct scan_state * ss_priv = SCAN_PRIVATE (ss );
576
+ struct timeout_task * scan_task = & ss_priv -> ss_scan_curchan ;
577
+ struct ieee80211com * ic = ss -> ss_ic ;
578
+
579
+ IEEE80211_LOCK_ASSERT (ic );
572
580
573
- IEEE80211_LOCK_ASSERT (ss -> ss_ic );
574
- cv_signal (& SCAN_PRIVATE (ss )-> ss_scan_cv );
581
+ if (ss_priv -> ss_iflags & ISCAN_RUNNING ) {
582
+ if (taskqueue_cancel_timeout (ic -> ic_tq , scan_task , NULL ) == 0 )
583
+ taskqueue_enqueue_timeout (ic -> ic_tq , scan_task , 0 );
584
+ }
575
585
}
F438
576
586
577
587
/*
@@ -591,16 +601,13 @@ scan_mindwell(struct ieee80211_scan_state *ss)
591
601
}
592
602
593
603
static void
594
- scan_task (void * arg , int pending )
604
+ scan_start (void * arg , int pending )
595
605
{
596
606
#define ISCAN_REP (ISCAN_MINDWELL | ISCAN_DISCARD)
597
607
struct ieee80211_scan_state * ss = (struct ieee80211_scan_state * ) arg ;
598
608
struct scan_state * ss_priv = SCAN_PRIVATE (ss );
599
609
struct ieee80211vap * vap = ss -> ss_vap ;
600
610
struct ieee80211com * ic = ss -> ss_ic ;
601
- struct ieee80211_channel * chan ;
602
- unsigned long maxdwell ;
603
- int scandone = 0 ;
604
611
605
612
IEEE80211_LOCK (ic );
606
613
if (vap == NULL || (ic -> ic_flags & IEEE80211_F_SCAN ) == 0 ||
@@ -627,8 +634,8 @@ scan_task(void *arg, int pending)
627
634
* to go out.
628
635
* XXX Should use M_TXCB mechanism to eliminate this.
629
636
*/
630
- cv_timedwait ( & ss_priv -> ss_scan_cv ,
631
- IEEE80211_LOCK_OBJ ( ic ) , msecs_to_ticks (1 ));
637
+ mtx_sleep ( vap , IEEE80211_LOCK_OBJ ( ic ), PCATCH ,
638
+ "sta_ps" , msecs_to_ticks (1 ));
632
639
if (ss_priv -> ss_iflags & ISCAN_ABORT ) {
633
640
scan_done (ss , 0 );
634
641
return ;
@@ -641,90 +648,102 @@ scan_task(void *arg, int pending)
641
648
/* XXX scan state can change! Re-validate scan state! */
642
649
643
650
IEEE80211_UNLOCK (ic );
651
+
644
652
ic -> ic_scan_start (ic ); /* notify driver */
645
- IEEE80211_LOCK (ic );
646
653
647
- for (;;) {
654
+ scan_curchan_task (ss , 0 );
655
+ }
648
656
649
- scandone = (ss -> ss_next >= ss -> ss_last ) ||
650
- (ss_priv -> ss_iflags & ISCAN_CANCEL ) != 0 ;
657
+ static void
658
+ scan_curchan_task (void * arg , int pending )
659
+ {
660
+ struct ieee80211_scan_state * ss = arg ;
661
+ struct scan_state * ss_priv = SCAN_PRIVATE (ss );
662
+ struct ieee80211vap * vap = ss -> ss_vap ;
663
+ struct ieee80211com * ic = ss -> ss_ic ;
664
+ struct ieee80211_channel * chan ;
665
+ unsigned long maxdwell ;
666
+ int scandone ;
651
667
652
- IEEE80211_DPRINTF ( vap , IEEE80211_MSG_SCAN ,
653
- "%s: loop start; scandone=%d\n" ,
654
- __func__ ,
655
- scandone ) ;
668
+ IEEE80211_LOCK ( ic );
669
+ end :
670
+ scandone = ( ss -> ss_next >= ss -> ss_last ) ||
671
+ ( ss_priv -> ss_iflags & ISCAN_CANCEL ) != 0 ;
656
672
657
- if (scandone || (ss -> ss_flags & IEEE80211_SCAN_GOTPICK ) ||
658
- (ss_priv -> ss_iflags & ISCAN_ABORT ) ||
659
- time_after (ticks + ss -> ss_mindwell , ss_priv -> ss_scanend )) {
660
- scan_end (ss , scandone );
661
- return ;
662
- }
673
+ IEEE80211_DPRINTF (vap , IEEE80211_MSG_SCAN ,
674
+ "%s: loop start; scandone=%d\n" ,
675
+ __func__ ,
676
+ scandone );
663
677
664
- chan = ss -> ss_chans [ss -> ss_next ++ ];
678
+ if (scandone || (ss -> ss_flags & IEEE80211_SCAN_GOTPICK ) ||
679
+ (ss_priv -> ss_iflags & ISCAN_ABORT ) ||
680
+ time_after (ticks + ss -> ss_mindwell , ss_priv -> ss_scanend )) {
681
+ ss_priv -> ss_iflags &= ~ISCAN_RUNNING ;
682
+ scan_end (ss , scandone );
683
+ return ;
684
+ } else
685
+ ss_priv -> ss_iflags |= ISCAN_RUNNING ;
665
686
666
- /*
667
- * Watch for truncation due to the scan end time.
668
- */
669
- if (time_after (ticks + ss -> ss_maxdwell , ss_priv -> ss_scanend ))
670
- maxdwell = ss_priv -> ss_scanend - ticks ;
671
- else
672
- maxdwell = ss -> ss_maxdwell ;
687
+ chan = ss -> ss_chans [ss -> ss_next ++ ];
673
688
674
- IEEE80211_DPRINTF (vap , IEEE80211_MSG_SCAN ,
675
- "%s: chan %3d%c -> %3d%c [%s, dwell min %lums max %lums]\n" ,
676
- __func__ ,
677
- ieee80211_chan2ieee (ic , ic -> ic_curchan ),
678
- ieee80211_channel_type_char (ic -> ic_curchan ),
679
- ieee80211_chan2ieee (ic , chan ),
680
- ieee80211_channel_type_char (chan ),
681
- (ss -> ss_flags & IEEE80211_SCAN_ACTIVE ) &&
682
- (chan -> ic_flags & IEEE80211_CHAN_PASSIVE ) == 0 ?
683
- "active" : "passive" ,
684
- ticks_to_msecs (ss -> ss_mindwell ), ticks_to_msecs (maxdwell ));
689
+ /*
690
+ * Watch for truncation due to the scan end time.
691
+ */
692
+ if (time_after (ticks + ss -> ss_maxdwell , ss_priv -> ss_scanend ))
693
+ maxdwell = ss_priv -> ss_scanend - ticks ;
694
+ else
695
+ maxdwell = ss -> ss_maxdwell ;
685
696
686
- /*
687
- * Potentially change channel and phy mode.
688
- */
689
- ic -> ic_curchan = chan ;
690
- ic -> ic_rt = ieee80211_get_ratetable (chan );
691
- IEEE80211_UNLOCK (ic );
692
- /*
693
- * Perform the channel change and scan unlocked so the driver
694
- * may sleep. Once set_channel returns the hardware has
695
- * completed the channel change.
696
- */
697
- ic -> ic_set_channel (ic );
698
- ieee80211_radiotap_chan_change (ic );
697
+ IEEE80211_DPRINTF (vap , IEEE80211_MSG_SCAN ,
698
+ "%s: chan %3d%c -> %3d%c [%s, dwell min %lums max %lums]\n" ,
699
+ __func__ ,
700
+ ieee80211_chan2ieee (ic , ic -> ic_curchan ),
701
+ ieee80211_channel_type_char (ic -> ic_curchan ),
702
+ ieee80211_chan2ieee (ic , chan ),
703
+ ieee80211_channel_type_char (chan ),
704
+ (ss -> ss_flags & IEEE80211_SCAN_ACTIVE ) &&
705
+ (chan -> ic_flags & IEEE80211_CHAN_PASSIVE ) == 0 ?
706
+ "active" : "passive" ,
707
+ ticks_to_msecs (ss -> ss_mindwell ), ticks_to_msecs (maxdwell ));
699
708
700
- /*
701
- * Scan curchan. Drivers for "intelligent hardware"
702
- * override ic_scan_curchan to tell the device to do
703
- * the work. Otherwise we manage the work outselves;
704
- * sending a probe request (as needed), and arming the
705
- * timeout to switch channels after maxdwell ticks.
706
- *
707
- * scan_curchan should only pause for the time required to
708
- * prepare/initiate the hardware for the scan (if at all), the
709
- * below condvar is used to sleep for the channels dwell time
710
- * and allows it to be signalled for abort.
711
- */
712
- ic -> ic_scan_curchan (ss , maxdwell );
713
- IEEE80211_LOCK (ic );
709
+ /*
710
+ * Potentially change channel and phy mode.
711
+ */
712
+ ic -> ic_curchan = chan ;
713
+ ic -> ic_rt = ieee80211_get_ratetable (chan );
714
+ IEEE80211_UNLOCK (ic );
715
+ /*
716
+ * Perform the channel change and scan unlocked so the driver
717
+ * may sleep. Once set_channel returns the hardware has
718
+ * completed the channel change.
719
+ */
720
+ ic -> ic_set_channel (ic );
721
+ ieee80211_radiotap_chan_change (ic );
722
+
723
+ /*
724
+ * Scan curchan. Drivers for "intelligent hardware"
725
+ * override ic_scan_curchan to tell the device to do
726
+ * the work. Otherwise we manage the work ourselves;
727
+ * sending a probe request (as needed), and arming the
728
+ * timeout to switch channels after maxdwell ticks.
729
+ *
730
+ * scan_curchan should only pause for the time required to
731
+ * prepare/initiate the hardware for the scan (if at all).
732
+ */
<
F438
/code>
733
+ ic -> ic_scan_curchan (ss , maxdwell );
734
+ IEEE80211_LOCK (ic );
714
735
715
- /* XXX scan state can change! Re-validate scan state! */
736
+ /* XXX scan state can change! Re-validate scan state! */
716
737
717
- ss_priv -> ss_chanmindwell = ticks + ss -> ss_mindwell ;
718
- /* clear mindwell lock and initial channel change flush */
719
- ss_priv -> ss_iflags &= ~ISCAN_REP ;
738
+ ss_priv -> ss_chanmindwell = ticks + ss -> ss_mindwell ;
739
+ /* clear mindwell lock and initial channel change flush */
740
+ ss_priv -> ss_iflags &= ~ISCAN_REP ;
720
741
721
- if (ss_priv -> ss_iflags & (ISCAN_CANCEL |ISCAN_ABORT ))
722
- continue ;
742
+ if (ss_priv -> ss_iflags & (ISCAN_CANCEL |ISCAN_ABORT ))
743
+ goto end ;
723
744
724
- IEEE80211_DPRINTF (vap , IEEE80211_MSG_SCAN , "%s: waiting\n" , __func__ );
725
- /* Wait to be signalled to scan the next channel */
726
- cv_wait (& ss_priv -> ss_scan_cv , IEEE80211_LOCK_OBJ (ic ));
727
- }
745
+ IEEE80211_DPRINTF (vap , IEEE80211_MSG_SCAN , "%s: waiting\n" , __func__ );
746
+ IEEE80211_UNLOCK (ic );
728
747
}
729
748
730
749
static void
@@ -803,7 +822,7 @@ scan_end(struct ieee80211_scan_state *ss, int scandone)
803
822
vap -> iv_stats .is_scan_passive ++ ;
804
823
805
824
ss -> ss_ops -> scan_restart (ss , vap ); /* XXX? */
806
- ieee80211_runtask (ic , & ss_priv -> ss_scan_task );
825
+ ieee80211_runtask (ic , & ss_priv -> ss_scan_start );
807
826
IEEE80211_UNLOCK (ic );
808
827
return ;
809
828
}
@@ -960,9 +979,9 @@ ieee80211_swscan_attach(struct ieee80211com *ic)
960
979
ic -> ic_scan = NULL ;
961
980
return ;
962
981
}
963
- callout_init_mtx (& ss -> ss_scan_timer , IEEE80211_LOCK_OBJ ( ic ), 0 );
964
- cv_init ( & ss -> ss_scan_cv , "scan" );
965
- TASK_INIT ( & ss -> ss_scan_task , 0 , scan_task , ss );
982
+ TASK_INIT (& ss -> ss_scan_start , 0 , scan_start , ss );
983
+ TIMEOUT_TASK_INIT ( ic -> ic_tq , & ss -> ss_scan_curchan , 0 ,
984
+ scan_curchan_task , ss );
966
985
967
986
ic -> ic_scan = & ss -> base ;
968
987
ss -> base .ss_ic = ic ;
0 commit comments