1 /* 2 * Copyright (c) 2012-2021 The Linux Foundation. All rights reserved. 3 * 4 * Permission to use, copy, modify, and/or distribute this software for 5 * any purpose with or without fee is hereby granted, provided that the 6 * above copyright notice and this permission notice appear in all 7 * copies. 8 * 9 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL 10 * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED 11 * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE 12 * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL 13 * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR 14 * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER 15 * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR 16 * PERFORMANCE OF THIS SOFTWARE. 17 */ 18 19 #include <wlan_dfs_public_struct.h> 20 #include <reg_services_public_struct.h> 21 22 /* Channel width definitions */ 23 /* 20MHz channel width */ 24 #define DFS_CH_WIDTH_20MHZ 0 25 26 /* 40MHz channel width */ 27 #define DFS_CH_WIDTH_40MHZ 1 28 29 /* 80MHz channel width */ 30 #define DFS_CH_WIDTH_80MHZ 2 31 32 /* 160MHz channel width */ 33 #define DFS_CH_WIDTH_160MHZ 3 34 35 /* 80+80 non-contiguous */ 36 #define DFS_CH_WIDTH_80P80MHZ 4 37 38 /* 5MHz channel width */ 39 #define DFS_CH_WIDTH_5MHZ 5 40 41 /* 10MHz channel width */ 42 #define DFS_CH_WIDTH_10MHZ 6 43 44 /* Invalid channel width */ 45 #define DFS_CH_WIDTH_INVALID 7 46 47 /* Max channel width */ 48 #define DFS_CH_WIDTH_MAX 8 49 50 /* Next 5GHz channel number */ 51 #define DFS_80_NUM_SUB_CHANNEL 4 52 53 /* Next 5GHz channel freq offset */ 54 #define DFS_80_NUM_SUB_CHANNEL_FREQ 20 55 56 /* Next 5GHz channel number */ 57 #define DFS_NEXT_5GHZ_CHANNEL 4 58 59 /* Next 5GHz channel number */ 60 #define DFS_NEXT_5GHZ_CHANNEL_FREQ_OFFSET 20 61 62 /* Number of 20MHz channels in bitmap */ 63 #define DFS_MAX_20M_SUB_CH 8 64 65 /* Frequency difference between 80+80 MHz */ 66 #define DFS_80P80M_FREQ_DIFF 40 67 68 #ifdef CONFIG_BAND_6GHZ 69 /* Number of 80MHz channels in 5GHz and 6GHz band */ 70 #define DFS_MAX_80MHZ_BANDS (7 + 14) 71 #else 72 /* Number of 80MHz channels in 5GHz band */ 73 #define DFS_MAX_80MHZ_BANDS 7 74 #endif 75 76 /* Start channel and center channel diff in 80Mhz */ 77 #define DFS_80MHZ_START_CENTER_CH_DIFF 6 78 79 /* Start channel and center channel freq diff in 80Mhz */ 80 #define DFS_80MHZ_START_CENTER_CH_FREQ_DIFF 30 81 82 /* Bitmap mask for 80MHz */ 83 #define DFS_80MHZ_MASK 0x0F 84 85 /* Bitmap mask for 40MHz lower */ 86 #define DFS_40MHZ_MASK_L 0x03 87 88 /* Bitmap mask for 40MHz higher */ 89 #define DFS_40MHZ_MASK_H 0x0C 90 91 /* Adjacent weather radar channel frequency */ 92 #define DFS_ADJACENT_WEATHER_RADAR_CHANNEL 5580 93 94 /* Adjacent weather radar channel number */ 95 #define DFS_ADJACENT_WEATHER_RADAR_CHANNEL_NUM 116 96 97 /* Max 2.4 GHz channel number */ 98 #define DFS_MAX_24GHZ_CHANNEL 14 99 100 /* Max 2.4 GHz channel frequency */ 101 #define DFS_MAX_24GHZ_CHANNEL_FREQ 2484 102 103 /* Adjacent weather radar channel frequency */ 104 #define DFS_ADJACENT_WEATHER_RADAR_CHANNEL_FREQ 5580 105 /* Max valid channel number */ 106 #define MAX_CHANNEL_NUM 184 107 108 #ifdef WLAN_ENABLE_CHNL_MATRIX_RESTRICTION 109 #define DFS_TX_LEAKAGE_THRES 310 110 #define DFS_TX_LEAKAGE_MAX 1000 111 #define DFS_TX_LEAKAGE_MIN 200 112 113 /* 114 * This define is used to block additional channels 115 * based on the new data gathered on auto platforms 116 * and to differentiate the leakage data among different 117 * platforms. 118 */ 119 120 #define DFS_TX_LEAKAGE_AUTO_MIN 210 121 #endif 122 123 #define DFS_IS_CHANNEL_WEATHER_RADAR(_f) (((_f) >= 5600) && ((_f) <= 5650)) 124 125 #ifdef CONFIG_CHAN_FREQ_API 126 #define DFS_IS_CHAN_JAPAN_INDOOR_FREQ(_ch)(((_ch) >= 5180) && ((_ch) <= 5320)) 127 #define DFS_IS_CHAN_JAPAN_OUTDOOR_FREQ(_ch)(((_ch) >= 5500) && ((_ch) <= 5720)) 128 #define DFS_IS_CHAN_JAPAN_W53_FREQ(_ch) (((_ch) >= 5260) && ((_ch) <= 5320)) 129 /* 130 * Spur or leakage transmissions is observed in Spruce HW in 131 * frequencies from 5260MHz to 5320MHz when one of the following 132 * conditions is true, 133 * i) The AP is transmitting in 52/56/60/64 in 80MHz mode and then the AP 134 * moves to the adjacent channel 36/44/48 in 80MHz mode and starts 135 * transmitting. 136 * ii) The AP is transmitting in 36/44/48/52/56/60/64 in 160MHz mode and then 137 * the AP moves to the adjacent channel 36/44/48 in 80MHz mode and starts 138 * transmitting. 139 * iii) The AP is transmitting in 52/56/60/64 in 20MHz or 40MHz mode and 140 * the AP moves to the adjacent channels 40/44/48 in 20MHz mode or 141 * 36/40/44/48 in 40MHz mode and starts transmitting. 142 * Hence, center frequencies from 5260MHz to 5320MHz in Spruce HW are called 143 * Spruce Spur 80MHz Frequencies and, center frequencies from 5180MHz and 144 * 5320MHz except 5200MHz are called Spruce Spur 160MHz Frequencies. 145 */ 146 /* Channels 52/56/60/64 in 80MHz */ 147 #define DFS_IS_CHAN_SPRUCE_SPUR_FREQ_80MHZ(_ch) \ 148 (((_ch) >= 5260) && ((_ch) <= 5320)) 149 /* 36/44/48/52/56/60/64 in 160MHz mode */ 150 #define DFS_IS_CHAN_SPRUCE_SPUR_FREQ_160MHZ(_ch) \ 151 (((_ch) >= 5180) && ((_ch) <= 5320) && ((_ch) != 5200)) 152 /* Avoid channels 36/44/48 */ 153 #define DFS_IS_SPRUCE_SPUR_AVOID_FREQS(_ch) \ 154 (((_ch) >= 5180) && ((_ch) <= 5240) && ((_ch) != 5200)) 155 156 /* Avoid channels 36/40/44/48 in HT40 mode and 40/44/48 in HT20 mode. */ 157 #define DFS_IS_CHAN_SPRUCE_SPUR_FREQ_20_40_MHZ(_ch) \ 158 (((_ch) >= 5200) && ((_ch) <= 5240)) 159 #endif 160 161 /** 162 * struct chan_bonding_info - for holding channel bonding bitmap 163 * @chan_map: channel map 164 * @rsvd: reserved 165 * @start_chan: start channel 166 * @start_chan_freq: start channel frequency in MHZ. 167 */ 168 struct chan_bonding_info { 169 uint8_t chan_map:4; 170 uint8_t rsvd:4; 171 uint8_t start_chan; 172 uint16_t start_chan_freq; 173 }; 174 175 /** 176 * struct chan_bonding_bitmap - bitmap structure which represent 177 * all 5GHZ channels. 178 * @chan_bonding_set: channel bonding bitmap 179 */ 180 struct chan_bonding_bitmap { 181 struct chan_bonding_info chan_bonding_set[DFS_MAX_80MHZ_BANDS]; 182 }; 183 184 #ifdef WLAN_ENABLE_CHNL_MATRIX_RESTRICTION 185 /** 186 * struct dfs_tx_leak_info - DFS leakage info 187 * @leak_chan: leak channel. 188 * @leak_lvl: tx leakage lvl. 189 */ 190 struct dfs_tx_leak_info { 191 uint8_t leak_chan; 192 uint16_t leak_chan_freq; 193 uint32_t leak_lvl; 194 }; 195 196 /** 197 * struct dfs_matrix_tx_leak_info - DFS leakage matrix info for dfs channel. 198 * @channel: channel to switch from 199 * @chan_matrix DFS leakage matrix info for given dfs channel. 200 */ 201 struct dfs_matrix_tx_leak_info { 202 uint8_t channel; 203 uint16_t channel_freq; 204 struct dfs_tx_leak_info chan_matrix[CHAN_ENUM_5720 - 205 CHAN_ENUM_5180 + 1]; 206 }; 207 #endif 208 209 /** 210 * dfs_mark_leaking_chan_for_freq() - to mark channel leaking in to nol 211 * @dfs: dfs handler. 212 * @ch_width: channel width 213 * @temp_chan_lst_sz: the target channel list size. 214 * @temp_freq_lst: the target frequency channel list 215 * 216 * This function removes the channels from temp channel list that 217 * (if selected as target channel) will cause leakage in one of 218 * the NOL channels 219 * 220 * Return: QDF_STATUS 221 */ 222 #ifdef CONFIG_CHAN_FREQ_API 223 QDF_STATUS dfs_mark_leaking_chan_for_freq(struct wlan_dfs *dfs, 224 enum phy_ch_width ch_width, 225 uint8_t temp_chan_lst_sz, 226 uint16_t *temp_freq_lst); 227 #endif 228 229 /** 230 * dfs_prepare_random_channel_for_freq() - This function picks a random channel 231 * from the list of available channels. 232 * @dfs: dfs handler. 233 * @chan_list: channel list. 234 * @ch_count: Number of channels in given list. 235 * @flags: DFS_RANDOM_CH_FLAG_* 236 * @chan_wd: input channel width, used same variable to return new ch width. 237 * @cur_chan: current channel. 238 * @dfs_region: DFS region. 239 * @acs_info: acs channel range information. 240 * 241 * Function used to find random channel selection from a given list. 242 * First this function removes channels based on flags and then uses final 243 * list to find channel based on requested bandwidth, if requested bandwidth 244 * not available, it chooses next lower bandwidth and try. 245 * 246 * Return: channel frequency, else zero. 247 */ 248 #ifdef CONFIG_CHAN_FREQ_API 249 uint16_t dfs_prepare_random_channel_for_freq(struct wlan_dfs *dfs, 250 struct dfs_channel *ch_list, 251 uint32_t chan_count, 252 uint32_t flags, 253 struct ch_params *chan_params, 254 uint8_t dfs_region, 255 struct dfs_acs_info *acs_info); 256 #endif 257