Lines Matching +full:channel +full:- +full:0
2 * DFS - Dynamic Frequency Selection
3 * Copyright (c) 2002-2013, Jouni Malinen <j@w1.fi>
4 * Copyright (c) 2013-2017, Qualcomm Atheros, Inc.
25 DFS_AVAILABLE, /* non-radar or radar-available */
26 DFS_NO_CAC_YET, /* radar-not-yet-available */
38 return (iface->drv_flags2 & WPA_DRIVER_FLAGS2_RADAR_BACKGROUND) && in dfs_use_radar_background()
39 iface->conf->enable_background_radar; in dfs_use_radar_background()
47 *seg1 = 0; in dfs_get_used_n_chans()
49 if (iface->conf->ieee80211n && iface->conf->secondary_channel) in dfs_get_used_n_chans()
52 if (iface->conf->ieee80211ac || iface->conf->ieee80211ax) { in dfs_get_used_n_chans()
53 switch (hostapd_get_oper_chwidth(iface->conf)) { in dfs_get_used_n_chans()
75 /* dfs_channel_available: select new channel according to type parameter */
80 /* Select only radar channel where CAC has not been in dfs_channel_available()
83 if ((chan->flag & HOSTAPD_CHAN_RADAR) && in dfs_channel_available()
84 (chan->flag & HOSTAPD_CHAN_DFS_MASK) == in dfs_channel_available()
87 return 0; in dfs_channel_available()
93 * channel for CSA, unless they are available for immediate use. in dfs_channel_available()
95 if (type == DFS_AVAILABLE && (chan->flag & HOSTAPD_CHAN_RADAR) && in dfs_channel_available()
96 ((chan->flag & HOSTAPD_CHAN_DFS_MASK) != in dfs_channel_available()
98 return 0; in dfs_channel_available()
100 if (chan->flag & HOSTAPD_CHAN_DISABLED) in dfs_channel_available()
101 return 0; in dfs_channel_available()
102 if ((chan->flag & HOSTAPD_CHAN_RADAR) && in dfs_channel_available()
103 ((chan->flag & HOSTAPD_CHAN_DFS_MASK) == in dfs_channel_available()
105 return 0; in dfs_channel_available()
113 * The tables contain first valid channel number based on channel width. in dfs_is_chan_allowed()
114 * We will also choose this first channel as the control one. in dfs_is_chan_allowed()
129 unsigned int i, allowed_no = 0; in dfs_is_chan_allowed()
149 for (i = 0; i < allowed_no; i++) { in dfs_is_chan_allowed()
150 if (chan->chan == allowed[i]) in dfs_is_chan_allowed()
154 return 0; in dfs_is_chan_allowed()
163 for (i = first_chan_idx; i < mode->num_channels; i++) { in dfs_get_chan_data()
164 if (mode->channels[i].freq == freq) in dfs_get_chan_data()
165 return &mode->channels[i]; in dfs_get_chan_data()
180 if (first_chan_idx + num_chans > mode->num_channels) { in dfs_chan_range_available()
183 return 0; in dfs_chan_range_available()
186 first_chan = &mode->channels[first_chan_idx]; in dfs_chan_range_available()
188 /* hostapd DFS implementation assumes the first channel as primary. in dfs_chan_range_available()
189 * If it's not allowed to use the first channel as primary, decline the in dfs_chan_range_available()
190 * whole channel range. */ in dfs_chan_range_available()
192 wpa_printf(MSG_DEBUG, "DFS: primary channel not allowed"); in dfs_chan_range_available()
193 return 0; in dfs_chan_range_available()
196 for (i = 0; i < num_chans; i++) { in dfs_chan_range_available()
197 chan = dfs_get_chan_data(mode, first_chan->freq + i * 20, in dfs_chan_range_available()
200 wpa_printf(MSG_DEBUG, "DFS: no channel data for %d", in dfs_chan_range_available()
201 first_chan->freq + i * 20); in dfs_chan_range_available()
202 return 0; in dfs_chan_range_available()
205 /* HT 40 MHz secondary channel availability checked only for in dfs_chan_range_available()
206 * primary channel */ in dfs_chan_range_available()
209 first_chan->freq + i * 20); in dfs_chan_range_available()
210 return 0; in dfs_chan_range_available()
214 wpa_printf(MSG_DEBUG, "DFS: channel not available %d", in dfs_chan_range_available()
215 first_chan->freq + i * 20); in dfs_chan_range_available()
216 return 0; in dfs_chan_range_available()
227 if (!iface->conf->acs_ch_list.num) in is_in_chanlist()
230 return freq_range_list_includes(&iface->conf->acs_ch_list, chan->chan); in is_in_chanlist()
237 * - hapd->secondary_channel
238 * - hapd->vht/he_oper_centr_freq_seg0_idx
239 * - hapd->vht/he_oper_centr_freq_seg1_idx
247 int i, channel_idx = 0, n_chans, n_chans1; in dfs_find_channel()
249 mode = iface->current_mode; in dfs_find_channel()
253 for (i = 0; i < mode->num_channels; i++) { in dfs_find_channel()
254 chan = &mode->channels[i]; in dfs_find_channel()
257 if (iface->conf->ieee80211n && in dfs_find_channel()
258 iface->conf->secondary_channel && in dfs_find_channel()
260 !(chan->allowed_bw & HOSTAPD_CHAN_WIDTH_40P))) { in dfs_find_channel()
262 "DFS: channel %d (%d) is incompatible", in dfs_find_channel()
263 chan->freq, chan->chan); in dfs_find_channel()
271 chan->freq, chan->chan); in dfs_find_channel()
277 "DFS: channel %d (%d) not in chanlist", in dfs_find_channel()
278 chan->freq, chan->chan); in dfs_find_channel()
282 if (chan->max_tx_power < iface->conf->min_tx_power) in dfs_find_channel()
285 if ((chan->flag & HOSTAPD_CHAN_INDOOR_ONLY) && in dfs_find_channel()
286 iface->conf->country[2] == 0x4f) in dfs_find_channel()
290 wpa_printf(MSG_DEBUG, "Selected channel %d (%d)", in dfs_find_channel()
291 chan->freq, chan->chan); in dfs_find_channel()
295 wpa_printf(MSG_DEBUG, "Adding channel %d (%d)", in dfs_find_channel()
296 chan->freq, chan->chan); in dfs_find_channel()
310 if (!iface->conf->ieee80211ac && !iface->conf->ieee80211ax) in dfs_adjust_center_freq()
316 *oper_centr_freq_seg1_idx = 0; in dfs_adjust_center_freq()
318 switch (hostapd_get_oper_chwidth(iface->conf)) { in dfs_adjust_center_freq()
321 *oper_centr_freq_seg0_idx = chan->chan + 2; in dfs_adjust_center_freq()
322 else if (secondary_channel == -1) in dfs_adjust_center_freq()
323 *oper_centr_freq_seg0_idx = chan->chan - 2; in dfs_adjust_center_freq()
325 *oper_centr_freq_seg0_idx = chan->chan; in dfs_adjust_center_freq()
328 *oper_centr_freq_seg0_idx = chan->chan + 6; in dfs_adjust_center_freq()
331 *oper_centr_freq_seg0_idx = chan->chan + 14; in dfs_adjust_center_freq()
334 *oper_centr_freq_seg0_idx = chan->chan + 6; in dfs_adjust_center_freq()
340 "DFS: Unsupported channel width configuration"); in dfs_adjust_center_freq()
341 *oper_centr_freq_seg0_idx = 0; in dfs_adjust_center_freq()
351 /* Return start channel idx we will use for mode->channels[idx] */
356 int channel_no = iface->conf->channel; in dfs_get_start_chan_idx()
357 int res = -1, i; in dfs_get_start_chan_idx()
358 int chan_seg1 = -1; in dfs_get_start_chan_idx()
360 *seg1_start = -1; in dfs_get_start_chan_idx()
362 /* HT40- */ in dfs_get_start_chan_idx()
363 if (iface->conf->ieee80211n && iface->conf->secondary_channel == -1) in dfs_get_start_chan_idx()
364 channel_no -= 4; in dfs_get_start_chan_idx()
367 if (iface->conf->ieee80211ac || iface->conf->ieee80211ax || in dfs_get_start_chan_idx()
368 iface->conf->ieee80211be) { in dfs_get_start_chan_idx()
369 switch (hostapd_get_oper_chwidth(iface->conf)) { in dfs_get_start_chan_idx()
374 iface->conf) - 6; in dfs_get_start_chan_idx()
378 iface->conf) - 14; in dfs_get_start_chan_idx()
382 iface->conf) - 6; in dfs_get_start_chan_idx()
384 iface->conf) - 6; in dfs_get_start_chan_idx()
388 iface->conf) - 30; in dfs_get_start_chan_idx()
393 channel_no = -1; in dfs_get_start_chan_idx()
399 mode = iface->current_mode; in dfs_get_start_chan_idx()
400 for (i = 0; i < mode->num_channels; i++) { in dfs_get_start_chan_idx()
401 chan = &mode->channels[i]; in dfs_get_start_chan_idx()
402 if (chan->chan == channel_no) { in dfs_get_start_chan_idx()
408 if (res != -1 && chan_seg1 > -1) { in dfs_get_start_chan_idx()
409 int found = 0; in dfs_get_start_chan_idx()
412 mode = iface->current_mode; in dfs_get_start_chan_idx()
413 for (i = 0; i < mode->num_channels; i++) { in dfs_get_start_chan_idx()
414 chan = &mode->channels[i]; in dfs_get_start_chan_idx()
415 if (chan->chan == chan_seg1) { in dfs_get_start_chan_idx()
422 res = -1; in dfs_get_start_chan_idx()
425 if (res == -1) { in dfs_get_start_chan_idx()
427 …"DFS chan_idx seems wrong; num-ch: %d ch-no: %d conf-ch-no: %d 11n: %d sec-ch: %d vht-oper-width: … in dfs_get_start_chan_idx()
428 mode->num_channels, channel_no, iface->conf->channel, in dfs_get_start_chan_idx()
429 iface->conf->ieee80211n, in dfs_get_start_chan_idx()
430 iface->conf->secondary_channel, in dfs_get_start_chan_idx()
431 hostapd_get_oper_chwidth(iface->conf)); in dfs_get_start_chan_idx()
433 for (i = 0; i < mode->num_channels; i++) { in dfs_get_start_chan_idx()
434 wpa_printf(MSG_DEBUG, "Available channel: %d", in dfs_get_start_chan_idx()
435 mode->channels[i].chan); in dfs_get_start_chan_idx()
443 /* At least one channel have radar flag */
447 struct hostapd_channel_data *channel; in dfs_check_chans_radar() local
449 int i, res = 0; in dfs_check_chans_radar()
451 mode = iface->current_mode; in dfs_check_chans_radar()
453 for (i = 0; i < n_chans; i++) { in dfs_check_chans_radar()
454 if (start_chan_idx + i >= mode->num_channels) in dfs_check_chans_radar()
456 channel = &mode->channels[start_chan_idx + i]; in dfs_check_chans_radar()
457 if (channel->flag & HOSTAPD_CHAN_RADAR) in dfs_check_chans_radar()
469 struct hostapd_channel_data *channel; in dfs_check_chans_available() local
473 mode = iface->current_mode; in dfs_check_chans_available()
475 for (i = 0; i < n_chans; i++) { in dfs_check_chans_available()
476 channel = &mode->channels[start_chan_idx + i]; in dfs_check_chans_available()
478 if (channel->flag & HOSTAPD_CHAN_DISABLED) in dfs_check_chans_available()
481 if (!(channel->flag & HOSTAPD_CHAN_RADAR)) in dfs_check_chans_available()
484 if ((channel->flag & HOSTAPD_CHAN_DFS_MASK) != in dfs_check_chans_available()
493 /* At least one channel unavailable */
498 struct hostapd_channel_data *channel; in dfs_check_chans_unavailable() local
500 int i, res = 0; in dfs_check_chans_unavailable()
502 mode = iface->current_mode; in dfs_check_chans_unavailable()
504 for (i = 0; i < n_chans; i++) { in dfs_check_chans_unavailable()
505 channel = &mode->channels[start_chan_idx + i]; in dfs_check_chans_unavailable()
506 if (channel->flag & HOSTAPD_CHAN_DISABLED) in dfs_check_chans_unavailable()
508 if ((channel->flag & HOSTAPD_CHAN_DFS_MASK) == in dfs_check_chans_unavailable()
529 int sec_chan_idx_80p80 = -1; in dfs_get_valid_channel()
533 wpa_printf(MSG_DEBUG, "DFS: Selecting random channel"); in dfs_get_valid_channel()
534 *secondary_channel = 0; in dfs_get_valid_channel()
535 *oper_centr_freq_seg0_idx = 0; in dfs_get_valid_channel()
536 *oper_centr_freq_seg1_idx = 0; in dfs_get_valid_channel()
538 if (iface->current_mode == NULL) in dfs_get_valid_channel()
541 mode = iface->current_mode; in dfs_get_valid_channel()
542 if (mode->mode != HOSTAPD_MODE_IEEE80211A) in dfs_get_valid_channel()
546 num_available_chandefs = dfs_find_channel(iface, NULL, 0, type); in dfs_get_valid_channel()
549 if (num_available_chandefs == 0) in dfs_get_valid_channel()
552 if (os_get_random((u8 *) &_rand, sizeof(_rand)) < 0) in dfs_get_valid_channel()
559 wpa_printf(MSG_DEBUG, "DFS: no random channel found"); in dfs_get_valid_channel()
562 wpa_printf(MSG_DEBUG, "DFS: got random channel %d (%d)", in dfs_get_valid_channel()
563 chan->freq, chan->chan); in dfs_get_valid_channel()
566 if (iface->conf->secondary_channel) in dfs_get_valid_channel()
569 *secondary_channel = 0; in dfs_get_valid_channel()
571 /* Get secondary channel for HT80P80 */ in dfs_get_valid_channel()
572 if (hostapd_get_oper_chwidth(iface->conf) == in dfs_get_valid_channel()
584 for (i = 0; i < num_available_chandefs - 1; i++) { in dfs_get_valid_channel()
585 /* start from chan_idx + 1, end when chan_idx - 1 */ in dfs_get_valid_channel()
588 if (chan2 && abs(chan2->chan - chan->chan) > 12) { in dfs_get_valid_channel()
590 sec_chan_idx_80p80 = chan2->chan; in dfs_get_valid_channel()
593 chan2->freq, chan2->chan); in dfs_get_valid_channel()
598 /* Check if we got a valid secondary channel which is not in dfs_get_valid_channel()
599 * adjacent to the first channel. in dfs_get_valid_channel()
601 if (sec_chan_idx_80p80 == -1) { in dfs_get_valid_channel()
620 struct hostapd_channel_data *channel; in dfs_set_valid_channel() local
621 u8 cf1 = 0, cf2 = 0; in dfs_set_valid_channel()
622 int sec = 0; in dfs_set_valid_channel()
624 channel = dfs_get_valid_channel(iface, &sec, &cf1, &cf2, in dfs_set_valid_channel()
627 if (!channel) { in dfs_set_valid_channel()
628 wpa_printf(MSG_ERROR, "could not get valid channel"); in dfs_set_valid_channel()
629 return -1; in dfs_set_valid_channel()
632 iface->freq = channel->freq; in dfs_set_valid_channel()
633 iface->conf->channel = channel->chan; in dfs_set_valid_channel()
634 iface->conf->secondary_channel = sec; in dfs_set_valid_channel()
635 hostapd_set_oper_centr_freq_seg0_idx(iface->conf, cf1); in dfs_set_valid_channel()
636 hostapd_set_oper_centr_freq_seg1_idx(iface->conf, cf2); in dfs_set_valid_channel()
638 return 0; in dfs_set_valid_channel()
648 mode = iface->current_mode; in set_dfs_state_freq()
650 return 0; in set_dfs_state_freq()
652 wpa_printf(MSG_DEBUG, "set_dfs_state 0x%X for %d MHz", state, freq); in set_dfs_state_freq()
653 for (i = 0; i < iface->current_mode->num_channels; i++) { in set_dfs_state_freq()
654 chan = &iface->current_mode->channels[i]; in set_dfs_state_freq()
655 if (chan->freq == freq) { in set_dfs_state_freq()
656 if (chan->flag & HOSTAPD_CHAN_RADAR) { in set_dfs_state_freq()
657 chan->flag &= ~HOSTAPD_CHAN_DFS_MASK; in set_dfs_state_freq()
658 chan->flag |= state; in set_dfs_state_freq()
659 return 1; /* Channel found */ in set_dfs_state_freq()
664 return 0; in set_dfs_state_freq()
675 int frequency2 = 0; in set_dfs_state()
676 int ret = 0; in set_dfs_state()
678 mode = iface->current_mode; in set_dfs_state()
680 return 0; in set_dfs_state()
682 if (mode->mode != HOSTAPD_MODE_IEEE80211A) { in set_dfs_state()
684 return 0; in set_dfs_state()
692 if (frequency == 0) in set_dfs_state()
697 frequency = cf1 - 10; in set_dfs_state()
701 frequency = cf1 - 30; in set_dfs_state()
705 frequency = cf1 - 30; in set_dfs_state()
706 frequency2 = cf2 - 30; in set_dfs_state()
710 frequency = cf1 - 70; in set_dfs_state()
720 for (i = 0; i < n_chans; i++) { in set_dfs_state()
742 int res = 0; in dfs_are_channels_overlapped()
745 mode = iface->current_mode; in dfs_are_channels_overlapped()
749 /* Check we are on DFS channel(s) */ in dfs_are_channels_overlapped()
751 return 0; in dfs_are_channels_overlapped()
758 if (frequency == 0) in dfs_are_channels_overlapped()
763 frequency = cf1 - 10; in dfs_are_channels_overlapped()
767 frequency = cf1 - 30; in dfs_are_channels_overlapped()
771 frequency = cf1 - 70; in dfs_are_channels_overlapped()
781 for (i = 0; i < n_chans; i++) { in dfs_are_channels_overlapped()
782 chan = &mode->channels[start_chan_idx + i]; in dfs_are_channels_overlapped()
783 if (!(chan->flag & HOSTAPD_CHAN_RADAR)) in dfs_are_channels_overlapped()
785 for (j = 0; j < radar_n_chans; j++) { in dfs_are_channels_overlapped()
787 chan->chan, radar_chan + j * 4); in dfs_are_channels_overlapped()
788 if (chan->chan == radar_chan + j * 4) in dfs_are_channels_overlapped()
802 struct hostapd_channel_data *channel; in dfs_get_cac_time() local
805 unsigned int cac_time_ms = 0; in dfs_get_cac_time()
807 mode = iface->current_mode; in dfs_get_cac_time()
809 for (i = 0; i < n_chans; i++) { in dfs_get_cac_time()
810 if (start_chan_idx + i >= mode->num_channels) in dfs_get_cac_time()
812 channel = &mode->channels[start_chan_idx + i]; in dfs_get_cac_time()
813 if (!(channel->flag & HOSTAPD_CHAN_RADAR)) in dfs_get_cac_time()
815 if (channel->dfs_cac_ms > cac_time_ms) in dfs_get_cac_time()
816 cac_time_ms = channel->dfs_cac_ms; in dfs_get_cac_time()
825 * 1 - continue channel/ap setup
826 * 0 - channel/ap setup will be continued after CAC
827 * -1 - hit critical error
832 int skip_radar = 0; in hostapd_handle_dfs()
834 if (is_6ghz_freq(iface->freq)) in hostapd_handle_dfs()
837 if (!iface->current_mode) { in hostapd_handle_dfs()
843 "DFS: No current_mode information - assume no need to perform DFS operations by hostapd"); in hostapd_handle_dfs()
847 iface->cac_started = 0; in hostapd_handle_dfs()
850 /* Get start (first) channel for current configuration */ in hostapd_handle_dfs()
853 if (start_chan_idx == -1) in hostapd_handle_dfs()
854 return -1; in hostapd_handle_dfs()
860 iface->dfs_cac_ms = dfs_get_cac_time(iface, start_chan_idx, in hostapd_handle_dfs()
882 wpa_printf(MSG_DEBUG, "DFS %d chans unavailable - choose other channel: %s", in hostapd_handle_dfs()
885 if (dfs_set_valid_channel(iface, skip_radar) < 0) { in hostapd_handle_dfs()
887 return 0; in hostapd_handle_dfs()
894 wpa_printf(MSG_DEBUG, "DFS start CAC on %d MHz%s", iface->freq, in hostapd_handle_dfs()
896 wpa_msg(iface->bss[0]->msg_ctx, MSG_INFO, DFS_EVENT_CAC_START in hostapd_handle_dfs()
898 iface->freq, in hostapd_handle_dfs()
899 iface->conf->channel, iface->conf->secondary_channel, in hostapd_handle_dfs()
900 hostapd_get_oper_chwidth(iface->conf), in hostapd_handle_dfs()
901 hostapd_get_oper_centr_freq_seg0_idx(iface->conf), in hostapd_handle_dfs()
902 hostapd_get_oper_centr_freq_seg1_idx(iface->conf), in hostapd_handle_dfs()
903 iface->dfs_cac_ms / 1000); in hostapd_handle_dfs()
906 iface, iface->conf->hw_mode, iface->freq, iface->conf->channel, in hostapd_handle_dfs()
907 iface->conf->ieee80211n, iface->conf->ieee80211ac, in hostapd_handle_dfs()
908 iface->conf->ieee80211ax, iface->conf->ieee80211be, in hostapd_handle_dfs()
909 iface->conf->secondary_channel, in hostapd_handle_dfs()
910 hostapd_get_oper_chwidth(iface->conf), in hostapd_handle_dfs()
911 hostapd_get_oper_centr_freq_seg0_idx(iface->conf), in hostapd_handle_dfs()
912 hostapd_get_oper_centr_freq_seg1_idx(iface->conf), in hostapd_handle_dfs()
917 return -1; in hostapd_handle_dfs()
922 iface->radar_background.channel = iface->conf->channel; in hostapd_handle_dfs()
923 iface->radar_background.secondary_channel = in hostapd_handle_dfs()
924 iface->conf->secondary_channel; in hostapd_handle_dfs()
925 iface->radar_background.freq = iface->freq; in hostapd_handle_dfs()
926 iface->radar_background.centr_freq_seg0_idx = in hostapd_handle_dfs()
927 hostapd_get_oper_centr_freq_seg0_idx(iface->conf); in hostapd_handle_dfs()
928 iface->radar_background.centr_freq_seg1_idx = in hostapd_handle_dfs()
929 hostapd_get_oper_centr_freq_seg1_idx(iface->conf); in hostapd_handle_dfs()
932 * Let's select a random channel according to the in hostapd_handle_dfs()
936 if (res < 0) in hostapd_handle_dfs()
939 iface->radar_background.temp_ch = 1; in hostapd_handle_dfs()
943 return 0; in hostapd_handle_dfs()
951 /* Get the start (first) channel for current configuration */ in hostapd_is_dfs_chan_available()
953 if (start_chan_idx < 0) in hostapd_is_dfs_chan_available()
954 return 0; in hostapd_is_dfs_chan_available()
965 int channel, int freq, in hostapd_dfs_request_channel_switch() argument
971 struct hostapd_hw_modes *cmode = iface->current_mode; in hostapd_dfs_request_channel_switch()
976 unsigned int num_err = 0; in hostapd_dfs_request_channel_switch()
978 wpa_printf(MSG_DEBUG, "DFS will switch to a new channel %d", channel); in hostapd_dfs_request_channel_switch()
979 wpa_msg(iface->bss[0]->msg_ctx, MSG_INFO, DFS_EVENT_NEW_CHANNEL in hostapd_dfs_request_channel_switch()
980 "freq=%d chan=%d sec_chan=%d", freq, channel, in hostapd_dfs_request_channel_switch()
983 new_vht_oper_chwidth = hostapd_get_oper_chwidth(iface->conf); in hostapd_dfs_request_channel_switch()
984 hostapd_set_oper_chwidth(iface->conf, current_vht_oper_chwidth); in hostapd_dfs_request_channel_switch()
987 os_memset(&csa_settings, 0, sizeof(csa_settings)); in hostapd_dfs_request_channel_switch()
990 csa_settings.link_id = -1; in hostapd_dfs_request_channel_switch()
992 if (iface->bss[0]->conf->mld_ap) in hostapd_dfs_request_channel_switch()
993 csa_settings.link_id = iface->bss[0]->mld_link_id; in hostapd_dfs_request_channel_switch()
996 if (iface->mconf) in hostapd_dfs_request_channel_switch()
1000 iface->conf->hw_mode, in hostapd_dfs_request_channel_switch()
1001 freq, channel, in hostapd_dfs_request_channel_switch()
1002 iface->conf->enable_edmg, in hostapd_dfs_request_channel_switch()
1003 iface->conf->edmg_channel, in hostapd_dfs_request_channel_switch()
1004 iface->conf->ieee80211n, in hostapd_dfs_request_channel_switch()
1005 iface->conf->ieee80211ac, in hostapd_dfs_request_channel_switch()
1006 iface->conf->ieee80211ax, in hostapd_dfs_request_channel_switch()
1007 iface->conf->ieee80211be, in hostapd_dfs_request_channel_switch()
1012 cmode->vht_capab, in hostapd_dfs_request_channel_switch()
1013 &cmode->he_capab[ieee80211_mode], in hostapd_dfs_request_channel_switch()
1014 &cmode->eht_capab[ieee80211_mode], in hostapd_dfs_request_channel_switch()
1015 hostapd_get_punct_bitmap(iface->bss[0])); in hostapd_dfs_request_channel_switch()
1024 for (i = 0; i < iface->num_bss; i++) { in hostapd_dfs_request_channel_switch()
1025 err = hostapd_switch_channel(iface->bss[i], &csa_settings); in hostapd_dfs_request_channel_switch()
1030 if (num_err == iface->num_bss) { in hostapd_dfs_request_channel_switch()
1032 "DFS failed to schedule CSA (%d) - trying fallback", in hostapd_dfs_request_channel_switch()
1034 iface->freq = freq; in hostapd_dfs_request_channel_switch()
1035 iface->conf->channel = channel; in hostapd_dfs_request_channel_switch()
1036 iface->conf->secondary_channel = secondary_channel; in hostapd_dfs_request_channel_switch()
1037 hostapd_set_oper_chwidth(iface->conf, new_vht_oper_chwidth); in hostapd_dfs_request_channel_switch()
1038 hostapd_set_oper_centr_freq_seg0_idx(iface->conf, in hostapd_dfs_request_channel_switch()
1040 hostapd_set_oper_centr_freq_seg1_idx(iface->conf, in hostapd_dfs_request_channel_switch()
1046 return 0; in hostapd_dfs_request_channel_switch()
1049 /* Channel configuration will be updated once CSA completes and in hostapd_dfs_request_channel_switch()
1051 wpa_printf(MSG_DEBUG, "DFS waiting channel switch event"); in hostapd_dfs_request_channel_switch()
1053 return 0; in hostapd_dfs_request_channel_switch()
1059 int sec = 0; in hostapd_dfs_update_background_chain()
1061 struct hostapd_channel_data *channel; in hostapd_dfs_update_background_chain() local
1062 u8 oper_centr_freq_seg0_idx = 0; in hostapd_dfs_update_background_chain()
1063 u8 oper_centr_freq_seg1_idx = 0; in hostapd_dfs_update_background_chain()
1066 * Allow selection of DFS channel in ETSI to comply with in hostapd_dfs_update_background_chain()
1069 if (iface->dfs_domain == HOSTAPD_DFS_REGION_ETSI) in hostapd_dfs_update_background_chain()
1072 channel = dfs_get_valid_channel(iface, &sec, &oper_centr_freq_seg0_idx, in hostapd_dfs_update_background_chain()
1075 if (!channel || in hostapd_dfs_update_background_chain()
1076 channel->chan == iface->conf->channel || in hostapd_dfs_update_background_chain()
1077 channel->chan == iface->radar_background.channel) in hostapd_dfs_update_background_chain()
1078 channel = dfs_downgrade_bandwidth(iface, &sec, in hostapd_dfs_update_background_chain()
1082 if (!channel || in hostapd_dfs_update_background_chain()
1083 hostapd_start_dfs_cac(iface, iface->conf->hw_mode, in hostapd_dfs_update_background_chain()
1084 channel->freq, channel->chan, in hostapd_dfs_update_background_chain()
1085 iface->conf->ieee80211n, in hostapd_dfs_update_background_chain()
1086 iface->conf->ieee80211ac, in hostapd_dfs_update_background_chain()
1087 iface->conf->ieee80211ax, in hostapd_dfs_update_background_chain()
1088 iface->conf->ieee80211be, in hostapd_dfs_update_background_chain()
1089 sec, hostapd_get_oper_chwidth(iface->conf), in hostapd_dfs_update_background_chain()
1093 iface->radar_background.channel = -1; in hostapd_dfs_update_background_chain()
1097 iface->radar_background.channel = channel->chan; in hostapd_dfs_update_background_chain()
1098 iface->radar_background.freq = channel->freq; in hostapd_dfs_update_background_chain()
1099 iface->radar_background.secondary_channel = sec; in hostapd_dfs_update_background_chain()
1100 iface->radar_background.centr_freq_seg0_idx = oper_centr_freq_seg0_idx; in hostapd_dfs_update_background_chain()
1101 iface->radar_background.centr_freq_seg1_idx = oper_centr_freq_seg1_idx; in hostapd_dfs_update_background_chain()
1105 __func__, channel->chan, channel->freq); in hostapd_dfs_update_background_chain()
1113 iface->radar_background.channel != -1 && in hostapd_dfs_is_background_event()
1114 iface->radar_background.freq == freq; in hostapd_dfs_is_background_event()
1121 u8 current_vht_oper_chwidth = hostapd_get_oper_chwidth(iface->conf); in hostapd_dfs_start_channel_switch_background()
1123 iface->conf->channel = iface->radar_background.channel; in hostapd_dfs_start_channel_switch_background()
1124 iface->freq = iface->radar_background.freq; in hostapd_dfs_start_channel_switch_background()
1125 iface->conf->secondary_channel = in hostapd_dfs_start_channel_switch_background()
1126 iface->radar_background.secondary_channel; in hostapd_dfs_start_channel_switch_background()
1128 iface->conf, iface->radar_background.centr_freq_seg0_idx); in hostapd_dfs_start_channel_switch_background()
1130 iface->conf, iface->radar_background.centr_freq_seg1_idx); in hostapd_dfs_start_channel_switch_background()
1135 iface, iface->conf->channel, iface->freq, in hostapd_dfs_start_channel_switch_background()
1136 iface->conf->secondary_channel, current_vht_oper_chwidth, in hostapd_dfs_start_channel_switch_background()
1137 hostapd_get_oper_centr_freq_seg0_idx(iface->conf), in hostapd_dfs_start_channel_switch_background()
1138 hostapd_get_oper_centr_freq_seg1_idx(iface->conf)); in hostapd_dfs_start_channel_switch_background()
1146 wpa_msg(iface->bss[0]->msg_ctx, MSG_INFO, DFS_EVENT_CAC_COMPLETED in hostapd_dfs_complete_cac()
1149 iface->radar_detected); in hostapd_dfs_complete_cac()
1153 if (iface->drv_flags & WPA_DRIVER_FLAGS_DFS_OFFLOAD) { in hostapd_dfs_complete_cac()
1155 * a radar was detected in this channel, interface setup in hostapd_dfs_complete_cac()
1158 * non-DFS channel in hostapd_dfs_complete_cac()
1160 * DFS channel. in hostapd_dfs_complete_cac()
1162 if (iface->state != HAPD_IFACE_ENABLED && in hostapd_dfs_complete_cac()
1163 !iface->radar_detected) in hostapd_dfs_complete_cac()
1164 hostapd_setup_interface_complete(iface, 0); in hostapd_dfs_complete_cac()
1166 iface->cac_started = 0; in hostapd_dfs_complete_cac()
1174 * channel. Perform CSA, move the main chain to the in hostapd_dfs_complete_cac()
1175 * selected channel and configure the background chain in hostapd_dfs_complete_cac()
1176 * to a new DFS channel. in hostapd_dfs_complete_cac()
1179 iface->radar_background.cac_started = 0; in hostapd_dfs_complete_cac()
1180 if (!iface->radar_background.temp_ch) in hostapd_dfs_complete_cac()
1181 return 0; in hostapd_dfs_complete_cac()
1183 iface->radar_background.temp_ch = 0; in hostapd_dfs_complete_cac()
1188 * Just mark the channel available when CAC completion in hostapd_dfs_complete_cac()
1192 * received during non-HAPD_IFACE_ENABLED state, make in hostapd_dfs_complete_cac()
1193 * sure the configured channel is available because this in hostapd_dfs_complete_cac()
1197 if (iface->state != HAPD_IFACE_ENABLED && in hostapd_dfs_complete_cac()
1199 hostapd_setup_interface_complete(iface, 0); in hostapd_dfs_complete_cac()
1200 iface->cac_started = 0; in hostapd_dfs_complete_cac()
1204 iface->radar_background.cac_started = 0; in hostapd_dfs_complete_cac()
1208 iface->radar_detected = false; in hostapd_dfs_complete_cac()
1209 return 0; in hostapd_dfs_complete_cac()
1217 wpa_msg(iface->bss[0]->msg_ctx, MSG_INFO, DFS_EVENT_PRE_CAC_EXPIRED in hostapd_dfs_pre_cac_expired()
1222 if (iface->drv_flags & WPA_DRIVER_FLAGS_DFS_OFFLOAD) in hostapd_dfs_pre_cac_expired()
1223 return 0; in hostapd_dfs_pre_cac_expired()
1228 return 0; in hostapd_dfs_pre_cac_expired()
1238 struct hostapd_channel_data *channel; in dfs_downgrade_bandwidth() local
1241 channel = dfs_get_valid_channel(iface, secondary_channel, in dfs_downgrade_bandwidth()
1245 if (channel) { in dfs_downgrade_bandwidth()
1246 wpa_printf(MSG_DEBUG, "DFS: Selected channel: %d", in dfs_downgrade_bandwidth()
1247 channel->chan); in dfs_downgrade_bandwidth()
1248 return channel; in dfs_downgrade_bandwidth()
1256 oper_chwidth = hostapd_get_oper_chwidth(iface->conf); in dfs_downgrade_bandwidth()
1260 hostapd_set_oper_chwidth(iface->conf, oper_chwidth - 1); in dfs_downgrade_bandwidth()
1273 struct hostapd_channel_data *channel; in hostapd_dfs_start_channel_switch_cac() local
1275 u8 oper_centr_freq_seg0_idx = 0; in hostapd_dfs_start_channel_switch_cac()
1276 u8 oper_centr_freq_seg1_idx = 0; in hostapd_dfs_start_channel_switch_cac()
1281 iface->cac_started = 0; in hostapd_dfs_start_channel_switch_cac()
1282 channel = dfs_get_valid_channel(iface, &secondary_channel, in hostapd_dfs_start_channel_switch_cac()
1287 if (!channel) { in hostapd_dfs_start_channel_switch_cac()
1288 channel = dfs_downgrade_bandwidth(iface, &secondary_channel, in hostapd_dfs_start_channel_switch_cac()
1292 if (!channel) { in hostapd_dfs_start_channel_switch_cac()
1293 wpa_printf(MSG_ERROR, "No valid channel available"); in hostapd_dfs_start_channel_switch_cac()
1298 wpa_printf(MSG_DEBUG, "DFS will switch to a new channel %d", in hostapd_dfs_start_channel_switch_cac()
1299 channel->chan); in hostapd_dfs_start_channel_switch_cac()
1300 wpa_msg(iface->bss[0]->msg_ctx, MSG_INFO, DFS_EVENT_NEW_CHANNEL in hostapd_dfs_start_channel_switch_cac()
1301 "freq=%d chan=%d sec_chan=%d", channel->freq, in hostapd_dfs_start_channel_switch_cac()
1302 channel->chan, secondary_channel); in hostapd_dfs_start_channel_switch_cac()
1304 iface->freq = channel->freq; in hostapd_dfs_start_channel_switch_cac()
1305 iface->conf->channel = channel->chan; in hostapd_dfs_start_channel_switch_cac()
1306 iface->conf->secondary_channel = secondary_channel; in hostapd_dfs_start_channel_switch_cac()
1307 hostapd_set_oper_centr_freq_seg0_idx(iface->conf, in hostapd_dfs_start_channel_switch_cac()
1309 hostapd_set_oper_centr_freq_seg1_idx(iface->conf, in hostapd_dfs_start_channel_switch_cac()
1311 err = 0; in hostapd_dfs_start_channel_switch_cac()
1323 return -1; /* Background radar chain not supported. */ in hostapd_dfs_background_start_channel_switch()
1327 __func__, iface->radar_background.cac_started ? "yes" : "no", in hostapd_dfs_background_start_channel_switch()
1332 return 0; in hostapd_dfs_background_start_channel_switch()
1337 * Just select a new random channel according to the in hostapd_dfs_background_start_channel_switch()
1341 return 0; in hostapd_dfs_background_start_channel_switch()
1345 * If background radar detection is supported and the radar channel in hostapd_dfs_background_start_channel_switch()
1349 if (iface->radar_background.channel == -1) in hostapd_dfs_background_start_channel_switch()
1350 return -1; /* Background radar chain not available. */ in hostapd_dfs_background_start_channel_switch()
1352 if (iface->radar_background.cac_started) { in hostapd_dfs_background_start_channel_switch()
1354 * Background channel not available yet. Perform CAC on the in hostapd_dfs_background_start_channel_switch()
1357 iface->radar_background.temp_ch = 1; in hostapd_dfs_background_start_channel_switch()
1358 return -1; in hostapd_dfs_background_start_channel_switch()
1367 struct hostapd_channel_data *channel; in hostapd_dfs_start_channel_switch() local
1372 u8 current_vht_oper_chwidth = hostapd_get_oper_chwidth(iface->conf); in hostapd_dfs_start_channel_switch()
1375 __func__, iface->cac_started ? "yes" : "no", in hostapd_dfs_start_channel_switch()
1380 return 0; in hostapd_dfs_start_channel_switch()
1383 if (iface->cac_started) in hostapd_dfs_start_channel_switch()
1387 * Allow selection of DFS channel in ETSI to comply with in hostapd_dfs_start_channel_switch()
1390 if (iface->dfs_domain == HOSTAPD_DFS_REGION_ETSI) in hostapd_dfs_start_channel_switch()
1393 /* Perform channel switch/CSA */ in hostapd_dfs_start_channel_switch()
1394 channel = dfs_get_valid_channel(iface, &secondary_channel, in hostapd_dfs_start_channel_switch()
1399 if (!channel) { in hostapd_dfs_start_channel_switch()
1401 * If there is no channel to switch immediately to, check if in hostapd_dfs_start_channel_switch()
1402 * there is another channel where we can switch even if it in hostapd_dfs_start_channel_switch()
1406 channel = dfs_downgrade_bandwidth(iface, &secondary_channel, in hostapd_dfs_start_channel_switch()
1410 if (!channel) { in hostapd_dfs_start_channel_switch()
1417 return 0; in hostapd_dfs_start_channel_switch()
1421 iface->freq = channel->freq; in hostapd_dfs_start_channel_switch()
1422 iface->conf->channel = channel->chan; in hostapd_dfs_start_channel_switch()
1423 iface->conf->secondary_channel = secondary_channel; in hostapd_dfs_start_channel_switch()
1425 iface->conf, oper_centr_freq_seg0_idx); in hostapd_dfs_start_channel_switch()
1427 iface->conf, oper_centr_freq_seg1_idx); in hostapd_dfs_start_channel_switch()
1431 return 0; in hostapd_dfs_start_channel_switch()
1435 return hostapd_dfs_request_channel_switch(iface, channel->chan, in hostapd_dfs_start_channel_switch()
1436 channel->freq, in hostapd_dfs_start_channel_switch()
1448 wpa_msg(iface->bss[0]->msg_ctx, MSG_INFO, DFS_EVENT_RADAR_DETECTED in hostapd_dfs_radar_detected()
1452 iface->radar_detected = true; in hostapd_dfs_radar_detected()
1455 if (iface->drv_flags & WPA_DRIVER_FLAGS_DFS_OFFLOAD) in hostapd_dfs_radar_detected()
1456 return 0; in hostapd_dfs_radar_detected()
1458 if (!iface->conf->ieee80211h) in hostapd_dfs_radar_detected()
1459 return 0; in hostapd_dfs_radar_detected()
1464 return 0; in hostapd_dfs_radar_detected()
1470 return 0; in hostapd_dfs_radar_detected()
1474 /* Radar detected while operating, switch the channel. */ in hostapd_dfs_radar_detected()
1478 return 0; in hostapd_dfs_radar_detected()
1486 wpa_msg(iface->bss[0]->msg_ctx, MSG_INFO, DFS_EVENT_NOP_FINISHED in hostapd_dfs_nop_finished()
1491 if (iface->drv_flags & WPA_DRIVER_FLAGS_DFS_OFFLOAD) in hostapd_dfs_nop_finished()
1492 return 0; in hostapd_dfs_nop_finished()
1498 if (iface->state == HAPD_IFACE_DFS && !iface->cac_started) { in hostapd_dfs_nop_finished()
1502 iface->radar_background.channel == -1) { in hostapd_dfs_nop_finished()
1507 return 0; in hostapd_dfs_nop_finished()
1515 if ((!(iface->drv_flags & WPA_DRIVER_FLAGS_DFS_OFFLOAD) && in hostapd_is_dfs_required()
1516 !iface->conf->ieee80211h) || in hostapd_is_dfs_required()
1517 !iface->current_mode || in hostapd_is_dfs_required()
1518 iface->current_mode->mode != HOSTAPD_MODE_IEEE80211A) in hostapd_is_dfs_required()
1519 return 0; in hostapd_is_dfs_required()
1521 /* Get start (first) channel for current configuration */ in hostapd_is_dfs_required()
1523 if (start_chan_idx == -1) in hostapd_is_dfs_required()
1524 return -1; in hostapd_is_dfs_required()
1533 if (start_chan_idx1 >= 0 && n_chans1 > 0) in hostapd_is_dfs_required()
1544 iface->radar_background.cac_started = 1; in hostapd_dfs_start_cac()
1548 * DFS channel. Clear it for this new CAC process. */ in hostapd_dfs_start_cac()
1550 iface->cac_started = 1; in hostapd_dfs_start_cac()
1555 iface->radar_detected = false; in hostapd_dfs_start_cac()
1556 if (iface->interfaces && iface->interfaces->count > 1) in hostapd_dfs_start_cac()
1560 iface->dfs_cac_ms = 60000; in hostapd_dfs_start_cac()
1561 wpa_msg(iface->bss[0]->msg_ctx, MSG_INFO, DFS_EVENT_CAC_START in hostapd_dfs_start_cac()
1564 freq, (freq - 5000) / 5, chan_offset, chan_width, cf1, cf2, in hostapd_dfs_start_cac()
1565 iface->dfs_cac_ms / 1000, in hostapd_dfs_start_cac()
1569 os_get_reltime(&iface->dfs_cac_start); in hostapd_dfs_start_cac()
1570 return 0; in hostapd_dfs_start_cac()
1576 * 2 - continue channel/AP setup for non-DFS channel
1577 * 1 - continue channel/AP setup for DFS channel
1578 * 0 - channel/AP setup will be continued after CAC
1579 * -1 - hit critical error
1585 wpa_printf(MSG_DEBUG, "%s: iface->cac_started: %d", in hostapd_handle_dfs_offload()
1586 __func__, iface->cac_started); in hostapd_handle_dfs_offload()
1590 * callback to continue AP/channel setup. Reset the CAC start flag and in hostapd_handle_dfs_offload()
1593 if (iface->cac_started) { in hostapd_handle_dfs_offload()
1594 wpa_printf(MSG_DEBUG, "%s: iface->cac_started: %d", in hostapd_handle_dfs_offload()
1595 __func__, iface->cac_started); in hostapd_handle_dfs_offload()
1596 iface->cac_started = 0; in hostapd_handle_dfs_offload()
1601 if (dfs_res > 0) { in hostapd_handle_dfs_offload()
1604 __func__, iface->freq, dfs_res); in hostapd_handle_dfs_offload()
1605 return 0; in hostapd_handle_dfs_offload()
1609 "%s: freq %d MHz does not require DFS. Continue channel/AP setup", in hostapd_handle_dfs_offload()
1610 __func__, iface->freq); in hostapd_handle_dfs_offload()
1619 struct hostapd_hw_modes *mode = iface->current_mode; in hostapd_is_dfs_overlap()
1621 int res = 0; in hostapd_is_dfs_overlap()
1624 if (!iface->conf->ieee80211h || !mode || in hostapd_is_dfs_overlap()
1625 mode->mode != HOSTAPD_MODE_IEEE80211A) in hostapd_is_dfs_overlap()
1626 return 0; in hostapd_is_dfs_overlap()
1646 return 0; in hostapd_is_dfs_overlap()
1649 for (i = 0; i < mode->num_channels; i++) { in hostapd_is_dfs_overlap()
1650 chan = &mode->channels[i]; in hostapd_is_dfs_overlap()
1652 if (!(chan->flag & HOSTAPD_CHAN_RADAR)) in hostapd_is_dfs_overlap()
1655 if ((chan->flag & HOSTAPD_CHAN_DFS_MASK) == in hostapd_is_dfs_overlap()
1659 if (center_freq - chan->freq < half_width && in hostapd_is_dfs_overlap()
1660 chan->freq - center_freq < half_width) in hostapd_is_dfs_overlap()
1665 center_freq - half_width, center_freq + half_width, in hostapd_is_dfs_overlap()