1051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidt/* 2051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidt * DFS - Dynamic Frequency Selection 3051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidt * Copyright (c) 2002-2013, Jouni Malinen <j@w1.fi> 4051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidt * Copyright (c) 2013, Qualcomm Atheros, Inc. 5051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidt * 6051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidt * This software may be distributed under the terms of the BSD license. 7051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidt * See README for more details. 8051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidt */ 9051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidt 10051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidt#include "utils/includes.h" 11051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidt 12051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidt#include "utils/common.h" 13051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidt#include "common/ieee802_11_defs.h" 14cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt#include "common/wpa_ctrl.h" 15051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidt#include "hostapd.h" 16051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidt#include "ap_drv_ops.h" 17051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidt#include "drivers/driver.h" 18051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidt#include "dfs.h" 19051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidt 20051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidt 21a7b06faf528d1765cc2712cc9a31ad45d7c3110bDmitry Shmidtstatic int dfs_get_used_n_chans(struct hostapd_iface *iface, int *seg1) 22051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidt{ 23051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidt int n_chans = 1; 24051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidt 25a7b06faf528d1765cc2712cc9a31ad45d7c3110bDmitry Shmidt *seg1 = 0; 26a7b06faf528d1765cc2712cc9a31ad45d7c3110bDmitry Shmidt 27cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt if (iface->conf->ieee80211n && iface->conf->secondary_channel) 28051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidt n_chans = 2; 29051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidt 30cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt if (iface->conf->ieee80211ac) { 31cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt switch (iface->conf->vht_oper_chwidth) { 32051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidt case VHT_CHANWIDTH_USE_HT: 33051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidt break; 34051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidt case VHT_CHANWIDTH_80MHZ: 35051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidt n_chans = 4; 36051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidt break; 37051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidt case VHT_CHANWIDTH_160MHZ: 38051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidt n_chans = 8; 39051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidt break; 40a7b06faf528d1765cc2712cc9a31ad45d7c3110bDmitry Shmidt case VHT_CHANWIDTH_80P80MHZ: 41a7b06faf528d1765cc2712cc9a31ad45d7c3110bDmitry Shmidt n_chans = 4; 42a7b06faf528d1765cc2712cc9a31ad45d7c3110bDmitry Shmidt *seg1 = 4; 43a7b06faf528d1765cc2712cc9a31ad45d7c3110bDmitry Shmidt break; 44051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidt default: 45051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidt break; 46051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidt } 47051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidt } 48051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidt 49051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidt return n_chans; 50051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidt} 51051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidt 52051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidt 5304f534e89ed127da4077485376f24debc50d80d5Dmitry Shmidtstatic int dfs_channel_available(struct hostapd_channel_data *chan, 5404f534e89ed127da4077485376f24debc50d80d5Dmitry Shmidt int skip_radar) 55051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidt{ 5604f534e89ed127da4077485376f24debc50d80d5Dmitry Shmidt /* 5704f534e89ed127da4077485376f24debc50d80d5Dmitry Shmidt * When radar detection happens, CSA is performed. However, there's no 5804f534e89ed127da4077485376f24debc50d80d5Dmitry Shmidt * time for CAC, so radar channels must be skipped when finding a new 599866086a955d00e237cc8df3722e7dff75c02532Dmitry Shmidt * channel for CSA, unless they are available for immediate use. 6004f534e89ed127da4077485376f24debc50d80d5Dmitry Shmidt */ 619866086a955d00e237cc8df3722e7dff75c02532Dmitry Shmidt if (skip_radar && (chan->flag & HOSTAPD_CHAN_RADAR) && 629866086a955d00e237cc8df3722e7dff75c02532Dmitry Shmidt ((chan->flag & HOSTAPD_CHAN_DFS_MASK) != 639866086a955d00e237cc8df3722e7dff75c02532Dmitry Shmidt HOSTAPD_CHAN_DFS_AVAILABLE)) 6404f534e89ed127da4077485376f24debc50d80d5Dmitry Shmidt return 0; 6504f534e89ed127da4077485376f24debc50d80d5Dmitry Shmidt 66051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidt if (chan->flag & HOSTAPD_CHAN_DISABLED) 67051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidt return 0; 68051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidt if ((chan->flag & HOSTAPD_CHAN_RADAR) && 69051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidt ((chan->flag & HOSTAPD_CHAN_DFS_MASK) == 70051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidt HOSTAPD_CHAN_DFS_UNAVAILABLE)) 71051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidt return 0; 72051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidt return 1; 73051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidt} 74051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidt 75051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidt 7668d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidtstatic int dfs_is_chan_allowed(struct hostapd_channel_data *chan, int n_chans) 77051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidt{ 7868d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt /* 7968d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt * The tables contain first valid channel number based on channel width. 8068d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt * We will also choose this first channel as the control one. 8168d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt */ 8268d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt int allowed_40[] = { 36, 44, 52, 60, 100, 108, 116, 124, 132, 149, 157, 8368d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt 184, 192 }; 8468d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt /* 8568d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt * VHT80, valid channels based on center frequency: 8668d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt * 42, 58, 106, 122, 138, 155 8768d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt */ 8868d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt int allowed_80[] = { 36, 52, 100, 116, 132, 149 }; 89f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt /* 90f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt * VHT160 valid channels based on center frequency: 91f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt * 50, 114 92f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt */ 93f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt int allowed_160[] = { 36, 100 }; 9468d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt int *allowed = allowed_40; 9568d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt unsigned int i, allowed_no = 0; 9668d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt 9768d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt switch (n_chans) { 9868d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt case 2: 9968d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt allowed = allowed_40; 10068d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt allowed_no = ARRAY_SIZE(allowed_40); 10168d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt break; 10268d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt case 4: 10368d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt allowed = allowed_80; 10468d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt allowed_no = ARRAY_SIZE(allowed_80); 10568d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt break; 106f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt case 8: 107f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt allowed = allowed_160; 108f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt allowed_no = ARRAY_SIZE(allowed_160); 109f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt break; 11068d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt default: 11168d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt wpa_printf(MSG_DEBUG, "Unknown width for %d channels", n_chans); 11268d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt break; 11368d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt } 114051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidt 11568d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt for (i = 0; i < allowed_no; i++) { 116051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidt if (chan->chan == allowed[i]) 117051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidt return 1; 118051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidt } 119051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidt 120051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidt return 0; 121051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidt} 122051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidt 123051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidt 124cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidtstatic int dfs_chan_range_available(struct hostapd_hw_modes *mode, 12504f534e89ed127da4077485376f24debc50d80d5Dmitry Shmidt int first_chan_idx, int num_chans, 12604f534e89ed127da4077485376f24debc50d80d5Dmitry Shmidt int skip_radar) 127cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt{ 128cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt struct hostapd_channel_data *first_chan, *chan; 129cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt int i; 130cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt 131cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt if (first_chan_idx + num_chans >= mode->num_channels) 132cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt return 0; 133cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt 134cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt first_chan = &mode->channels[first_chan_idx]; 135cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt 136cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt for (i = 0; i < num_chans; i++) { 137cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt chan = &mode->channels[first_chan_idx + i]; 138cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt 139cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt if (first_chan->freq + i * 20 != chan->freq) 140cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt return 0; 141cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt 14204f534e89ed127da4077485376f24debc50d80d5Dmitry Shmidt if (!dfs_channel_available(chan, skip_radar)) 143cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt return 0; 144cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt } 145cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt 146cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt return 1; 147cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt} 148cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt 149cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt 1509866086a955d00e237cc8df3722e7dff75c02532Dmitry Shmidtstatic int is_in_chanlist(struct hostapd_iface *iface, 1519866086a955d00e237cc8df3722e7dff75c02532Dmitry Shmidt struct hostapd_channel_data *chan) 1529866086a955d00e237cc8df3722e7dff75c02532Dmitry Shmidt{ 1539866086a955d00e237cc8df3722e7dff75c02532Dmitry Shmidt int *entry; 1549866086a955d00e237cc8df3722e7dff75c02532Dmitry Shmidt 1559866086a955d00e237cc8df3722e7dff75c02532Dmitry Shmidt if (!iface->conf->chanlist) 1569866086a955d00e237cc8df3722e7dff75c02532Dmitry Shmidt return 1; 1579866086a955d00e237cc8df3722e7dff75c02532Dmitry Shmidt 1589866086a955d00e237cc8df3722e7dff75c02532Dmitry Shmidt for (entry = iface->conf->chanlist; *entry != -1; entry++) { 1599866086a955d00e237cc8df3722e7dff75c02532Dmitry Shmidt if (*entry == chan->chan) 1609866086a955d00e237cc8df3722e7dff75c02532Dmitry Shmidt return 1; 1619866086a955d00e237cc8df3722e7dff75c02532Dmitry Shmidt } 1629866086a955d00e237cc8df3722e7dff75c02532Dmitry Shmidt return 0; 1639866086a955d00e237cc8df3722e7dff75c02532Dmitry Shmidt} 1649866086a955d00e237cc8df3722e7dff75c02532Dmitry Shmidt 1659866086a955d00e237cc8df3722e7dff75c02532Dmitry Shmidt 166cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt/* 167