dot11d.c (5135B)
1// SPDX-License-Identifier: GPL-2.0 2/****************************************************************************** 3 * Copyright(c) 2008 - 2010 Realtek Corporation. All rights reserved. 4 * 5 * Contact Information: 6 * wlanfae <wlanfae@realtek.com> 7 ******************************************************************************/ 8#include "dot11d.h" 9 10struct channel_list { 11 u8 channel[32]; 12 u8 len; 13}; 14 15static struct channel_list channel_array[] = { 16 {{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 36, 40, 44, 48, 52, 56, 60, 64, 17 149, 153, 157, 161, 165}, 24}, 18 {{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11}, 11}, 19 {{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 36, 40, 44, 48, 52, 56, 20 60, 64}, 21}, 21 {{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13}, 13}, 22 {{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13}, 13}, 23 {{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 36, 40, 44, 48, 52, 24 56, 60, 64}, 22}, 25 {{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 36, 40, 44, 48, 52, 26 56, 60, 64}, 22}, 27 {{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13}, 13}, 28 {{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 36, 40, 44, 48, 52, 29 56, 60, 64}, 22}, 30 {{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 36, 40, 44, 48, 52, 31 56, 60, 64}, 22}, 32 {{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14}, 14}, 33 {{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13}, 13}, 34 {{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 36, 40, 44, 48, 52, 35 56, 60, 64}, 21} 36}; 37 38void dot11d_init(struct rtllib_device *ieee) 39{ 40 struct rt_dot11d_info *dot11d_info = GET_DOT11D_INFO(ieee); 41 42 dot11d_info->enabled = false; 43 44 dot11d_info->state = DOT11D_STATE_NONE; 45 dot11d_info->country_len = 0; 46 memset(dot11d_info->channel_map, 0, MAX_CHANNEL_NUMBER + 1); 47 memset(dot11d_info->max_tx_power_list, 0xFF, MAX_CHANNEL_NUMBER + 1); 48 RESET_CIE_WATCHDOG(ieee); 49} 50EXPORT_SYMBOL(dot11d_init); 51 52void dot11d_channel_map(u8 channel_plan, struct rtllib_device *ieee) 53{ 54 int i, max_chan = 14, min_chan = 1; 55 56 ieee->global_domain = false; 57 58 if (channel_array[channel_plan].len != 0) { 59 memset(GET_DOT11D_INFO(ieee)->channel_map, 0, 60 sizeof(GET_DOT11D_INFO(ieee)->channel_map)); 61 for (i = 0; i < channel_array[channel_plan].len; i++) { 62 if (channel_array[channel_plan].channel[i] < min_chan || 63 channel_array[channel_plan].channel[i] > max_chan) 64 break; 65 GET_DOT11D_INFO(ieee)->channel_map[channel_array 66 [channel_plan].channel[i]] = 1; 67 } 68 } 69 70 switch (channel_plan) { 71 case COUNTRY_CODE_GLOBAL_DOMAIN: 72 ieee->global_domain = true; 73 for (i = 12; i <= 14; i++) 74 GET_DOT11D_INFO(ieee)->channel_map[i] = 2; 75 ieee->bss_start_channel = 10; 76 ieee->ibss_maxjoin_chal = 11; 77 break; 78 79 case COUNTRY_CODE_WORLD_WIDE_13: 80 for (i = 12; i <= 13; i++) 81 GET_DOT11D_INFO(ieee)->channel_map[i] = 2; 82 ieee->bss_start_channel = 10; 83 ieee->ibss_maxjoin_chal = 11; 84 break; 85 86 default: 87 ieee->bss_start_channel = 1; 88 ieee->ibss_maxjoin_chal = 14; 89 break; 90 } 91} 92EXPORT_SYMBOL(dot11d_channel_map); 93 94void dot11d_reset(struct rtllib_device *ieee) 95{ 96 struct rt_dot11d_info *dot11d_info = GET_DOT11D_INFO(ieee); 97 u32 i; 98 99 memset(dot11d_info->channel_map, 0, MAX_CHANNEL_NUMBER + 1); 100 memset(dot11d_info->max_tx_power_list, 0xFF, MAX_CHANNEL_NUMBER + 1); 101 for (i = 1; i <= 11; i++) 102 (dot11d_info->channel_map)[i] = 1; 103 for (i = 12; i <= 14; i++) 104 (dot11d_info->channel_map)[i] = 2; 105 dot11d_info->state = DOT11D_STATE_NONE; 106 dot11d_info->country_len = 0; 107 RESET_CIE_WATCHDOG(ieee); 108} 109 110void dot11d_update_country(struct rtllib_device *dev, u8 *address, 111 u16 country_len, u8 *country) 112{ 113 struct rt_dot11d_info *dot11d_info = GET_DOT11D_INFO(dev); 114 u8 i, j, number_of_triples, max_channel_number; 115 struct chnl_txpow_triple *triple; 116 117 memset(dot11d_info->channel_map, 0, MAX_CHANNEL_NUMBER + 1); 118 memset(dot11d_info->max_tx_power_list, 0xFF, MAX_CHANNEL_NUMBER + 1); 119 max_channel_number = 0; 120 number_of_triples = (country_len - 3) / 3; 121 triple = (struct chnl_txpow_triple *)(country + 3); 122 for (i = 0; i < number_of_triples; i++) { 123 if (max_channel_number >= triple->first_channel) { 124 netdev_info(dev->dev, 125 "%s: Invalid country IE, skip it......1\n", 126 __func__); 127 return; 128 } 129 if (MAX_CHANNEL_NUMBER < (triple->first_channel + 130 triple->num_channels)) { 131 netdev_info(dev->dev, 132 "%s: Invalid country IE, skip it......2\n", 133 __func__); 134 return; 135 } 136 137 for (j = 0; j < triple->num_channels; j++) { 138 dot11d_info->channel_map[triple->first_channel + j] = 1; 139 dot11d_info->max_tx_power_list[triple->first_channel + j] = 140 triple->max_tx_power; 141 max_channel_number = triple->first_channel + j; 142 } 143 144 triple = (struct chnl_txpow_triple *)((u8 *)triple + 3); 145 } 146 147 UPDATE_CIE_SRC(dev, address); 148 149 dot11d_info->country_len = country_len; 150 memcpy(dot11d_info->country_buffer, country, country_len); 151 dot11d_info->state = DOT11D_STATE_LEARNED; 152} 153 154void dot11d_scan_complete(struct rtllib_device *dev) 155{ 156 struct rt_dot11d_info *dot11d_info = GET_DOT11D_INFO(dev); 157 158 switch (dot11d_info->state) { 159 case DOT11D_STATE_LEARNED: 160 dot11d_info->state = DOT11D_STATE_DONE; 161 break; 162 case DOT11D_STATE_DONE: 163 dot11d_reset(dev); 164 break; 165 case DOT11D_STATE_NONE: 166 break; 167 } 168}