Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0
0002 /******************************************************************************
0003  * Copyright(c) 2008 - 2010 Realtek Corporation. All rights reserved.
0004  *
0005  * Contact Information:
0006  * wlanfae <wlanfae@realtek.com>
0007  ******************************************************************************/
0008 #include "dot11d.h"
0009 
0010 struct channel_list {
0011     u8      channel[32];
0012     u8      len;
0013 };
0014 
0015 static struct channel_list channel_array[] = {
0016     {{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 36, 40, 44, 48, 52, 56, 60, 64,
0017       149, 153, 157, 161, 165}, 24},
0018     {{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11}, 11},
0019     {{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 36, 40, 44, 48, 52, 56,
0020       60, 64}, 21},
0021     {{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13}, 13},
0022     {{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13}, 13},
0023     {{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 36, 40, 44, 48, 52,
0024       56, 60, 64}, 22},
0025     {{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 36, 40, 44, 48, 52,
0026       56, 60, 64}, 22},
0027     {{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13}, 13},
0028     {{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 36, 40, 44, 48, 52,
0029       56, 60, 64}, 22},
0030     {{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 36, 40, 44, 48, 52,
0031      56, 60, 64}, 22},
0032     {{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14}, 14},
0033     {{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13}, 13},
0034     {{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 36, 40, 44, 48, 52,
0035       56, 60, 64}, 21}
0036 };
0037 
0038 void dot11d_init(struct rtllib_device *ieee)
0039 {
0040     struct rt_dot11d_info *dot11d_info = GET_DOT11D_INFO(ieee);
0041 
0042     dot11d_info->enabled = false;
0043 
0044     dot11d_info->state = DOT11D_STATE_NONE;
0045     dot11d_info->country_len = 0;
0046     memset(dot11d_info->channel_map, 0, MAX_CHANNEL_NUMBER + 1);
0047     memset(dot11d_info->max_tx_power_list, 0xFF, MAX_CHANNEL_NUMBER + 1);
0048     RESET_CIE_WATCHDOG(ieee);
0049 }
0050 EXPORT_SYMBOL(dot11d_init);
0051 
0052 void dot11d_channel_map(u8 channel_plan, struct rtllib_device *ieee)
0053 {
0054     int i, max_chan = 14, min_chan = 1;
0055 
0056     ieee->global_domain = false;
0057 
0058     if (channel_array[channel_plan].len != 0) {
0059         memset(GET_DOT11D_INFO(ieee)->channel_map, 0,
0060                sizeof(GET_DOT11D_INFO(ieee)->channel_map));
0061         for (i = 0; i < channel_array[channel_plan].len; i++) {
0062             if (channel_array[channel_plan].channel[i] < min_chan ||
0063                 channel_array[channel_plan].channel[i] > max_chan)
0064                 break;
0065             GET_DOT11D_INFO(ieee)->channel_map[channel_array
0066                     [channel_plan].channel[i]] = 1;
0067         }
0068     }
0069 
0070     switch (channel_plan) {
0071     case COUNTRY_CODE_GLOBAL_DOMAIN:
0072         ieee->global_domain = true;
0073         for (i = 12; i <= 14; i++)
0074             GET_DOT11D_INFO(ieee)->channel_map[i] = 2;
0075         ieee->bss_start_channel = 10;
0076         ieee->ibss_maxjoin_chal = 11;
0077         break;
0078 
0079     case COUNTRY_CODE_WORLD_WIDE_13:
0080         for (i = 12; i <= 13; i++)
0081             GET_DOT11D_INFO(ieee)->channel_map[i] = 2;
0082         ieee->bss_start_channel = 10;
0083         ieee->ibss_maxjoin_chal = 11;
0084         break;
0085 
0086     default:
0087         ieee->bss_start_channel = 1;
0088         ieee->ibss_maxjoin_chal = 14;
0089         break;
0090     }
0091 }
0092 EXPORT_SYMBOL(dot11d_channel_map);
0093 
0094 void dot11d_reset(struct rtllib_device *ieee)
0095 {
0096     struct rt_dot11d_info *dot11d_info = GET_DOT11D_INFO(ieee);
0097     u32 i;
0098 
0099     memset(dot11d_info->channel_map, 0, MAX_CHANNEL_NUMBER + 1);
0100     memset(dot11d_info->max_tx_power_list, 0xFF, MAX_CHANNEL_NUMBER + 1);
0101     for (i = 1; i <= 11; i++)
0102         (dot11d_info->channel_map)[i] = 1;
0103     for (i = 12; i <= 14; i++)
0104         (dot11d_info->channel_map)[i] = 2;
0105     dot11d_info->state = DOT11D_STATE_NONE;
0106     dot11d_info->country_len = 0;
0107     RESET_CIE_WATCHDOG(ieee);
0108 }
0109 
0110 void dot11d_update_country(struct rtllib_device *dev, u8 *address,
0111                u16 country_len, u8 *country)
0112 {
0113     struct rt_dot11d_info *dot11d_info = GET_DOT11D_INFO(dev);
0114     u8 i, j, number_of_triples, max_channel_number;
0115     struct chnl_txpow_triple *triple;
0116 
0117     memset(dot11d_info->channel_map, 0, MAX_CHANNEL_NUMBER + 1);
0118     memset(dot11d_info->max_tx_power_list, 0xFF, MAX_CHANNEL_NUMBER + 1);
0119     max_channel_number = 0;
0120     number_of_triples = (country_len - 3) / 3;
0121     triple = (struct chnl_txpow_triple *)(country + 3);
0122     for (i = 0; i < number_of_triples; i++) {
0123         if (max_channel_number >= triple->first_channel) {
0124             netdev_info(dev->dev,
0125                     "%s: Invalid country IE, skip it......1\n",
0126                     __func__);
0127             return;
0128         }
0129         if (MAX_CHANNEL_NUMBER < (triple->first_channel +
0130             triple->num_channels)) {
0131             netdev_info(dev->dev,
0132                     "%s: Invalid country IE, skip it......2\n",
0133                     __func__);
0134             return;
0135         }
0136 
0137         for (j = 0; j < triple->num_channels; j++) {
0138             dot11d_info->channel_map[triple->first_channel + j] = 1;
0139             dot11d_info->max_tx_power_list[triple->first_channel + j] =
0140                          triple->max_tx_power;
0141             max_channel_number = triple->first_channel + j;
0142         }
0143 
0144         triple = (struct chnl_txpow_triple *)((u8 *)triple + 3);
0145     }
0146 
0147     UPDATE_CIE_SRC(dev, address);
0148 
0149     dot11d_info->country_len = country_len;
0150     memcpy(dot11d_info->country_buffer, country, country_len);
0151     dot11d_info->state = DOT11D_STATE_LEARNED;
0152 }
0153 
0154 void dot11d_scan_complete(struct rtllib_device *dev)
0155 {
0156     struct rt_dot11d_info *dot11d_info = GET_DOT11D_INFO(dev);
0157 
0158     switch (dot11d_info->state) {
0159     case DOT11D_STATE_LEARNED:
0160         dot11d_info->state = DOT11D_STATE_DONE;
0161         break;
0162     case DOT11D_STATE_DONE:
0163         dot11d_reset(dev);
0164         break;
0165     case DOT11D_STATE_NONE:
0166         break;
0167     }
0168 }