linux/drivers/staging/rtl8192e/dot11d.c
<<
>>
Prefs
   1/******************************************************************************
   2 * Copyright(c) 2008 - 2010 Realtek Corporation. All rights reserved.
   3 *
   4 * This program is distributed in the hope that it will be useful, but WITHOUT
   5 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
   6 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
   7 * more details.
   8 *
   9 * The full GNU General Public License is included in this distribution in the
  10 * file called LICENSE.
  11 *
  12 * Contact Information:
  13 * wlanfae <wlanfae@realtek.com>
  14 ******************************************************************************/
  15#include "dot11d.h"
  16
  17struct channel_list {
  18        u8      Channel[32];
  19        u8      Len;
  20};
  21
  22static struct channel_list ChannelPlan[] = {
  23        {{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 36, 40, 44, 48, 52, 56, 60, 64,
  24          149, 153, 157, 161, 165}, 24},
  25        {{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11}, 11},
  26        {{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 36, 40, 44, 48, 52, 56,
  27          60, 64}, 21},
  28        {{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13}, 13},
  29        {{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13}, 13},
  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, 36, 40, 44, 48, 52,
  33          56, 60, 64}, 22},
  34        {{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13}, 13},
  35        {{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 36, 40, 44, 48, 52,
  36          56, 60, 64}, 22},
  37        {{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 36, 40, 44, 48, 52,
  38         56, 60, 64}, 22},
  39        {{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14}, 14},
  40        {{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13}, 13},
  41        {{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 36, 40, 44, 48, 52,
  42          56, 60, 64}, 21}
  43};
  44
  45void dot11d_init(struct rtllib_device *ieee)
  46{
  47        struct rt_dot11d_info *pDot11dInfo = GET_DOT11D_INFO(ieee);
  48
  49        pDot11dInfo->bEnabled = false;
  50
  51        pDot11dInfo->State = DOT11D_STATE_NONE;
  52        pDot11dInfo->CountryIeLen = 0;
  53        memset(pDot11dInfo->channel_map, 0, MAX_CHANNEL_NUMBER+1);
  54        memset(pDot11dInfo->MaxTxPwrDbmList, 0xFF, MAX_CHANNEL_NUMBER + 1);
  55        RESET_CIE_WATCHDOG(ieee);
  56}
  57EXPORT_SYMBOL(dot11d_init);
  58
  59void Dot11d_Channelmap(u8 channel_plan, struct rtllib_device *ieee)
  60{
  61        int i, max_chan = 14, min_chan = 1;
  62
  63        ieee->bGlobalDomain = false;
  64
  65        if (ChannelPlan[channel_plan].Len != 0) {
  66                memset(GET_DOT11D_INFO(ieee)->channel_map, 0,
  67                       sizeof(GET_DOT11D_INFO(ieee)->channel_map));
  68                for (i = 0; i < ChannelPlan[channel_plan].Len; i++) {
  69                        if (ChannelPlan[channel_plan].Channel[i] < min_chan ||
  70                            ChannelPlan[channel_plan].Channel[i] > max_chan)
  71                                break;
  72                        GET_DOT11D_INFO(ieee)->channel_map[ChannelPlan
  73                                        [channel_plan].Channel[i]] = 1;
  74                }
  75        }
  76
  77        switch (channel_plan) {
  78        case COUNTRY_CODE_GLOBAL_DOMAIN:
  79                ieee->bGlobalDomain = true;
  80                for (i = 12; i <= 14; i++)
  81                        GET_DOT11D_INFO(ieee)->channel_map[i] = 2;
  82                ieee->IbssStartChnl = 10;
  83                ieee->ibss_maxjoin_chal = 11;
  84                break;
  85
  86        case COUNTRY_CODE_WORLD_WIDE_13:
  87                for (i = 12; i <= 13; i++)
  88                        GET_DOT11D_INFO(ieee)->channel_map[i] = 2;
  89                ieee->IbssStartChnl = 10;
  90                ieee->ibss_maxjoin_chal = 11;
  91                break;
  92
  93        default:
  94                ieee->IbssStartChnl = 1;
  95                ieee->ibss_maxjoin_chal = 14;
  96                break;
  97        }
  98}
  99EXPORT_SYMBOL(Dot11d_Channelmap);
 100
 101void Dot11d_Reset(struct rtllib_device *ieee)
 102{
 103        struct rt_dot11d_info *pDot11dInfo = GET_DOT11D_INFO(ieee);
 104        u32 i;
 105
 106        memset(pDot11dInfo->channel_map, 0, MAX_CHANNEL_NUMBER + 1);
 107        memset(pDot11dInfo->MaxTxPwrDbmList, 0xFF, MAX_CHANNEL_NUMBER + 1);
 108        for (i = 1; i <= 11; i++)
 109                (pDot11dInfo->channel_map)[i] = 1;
 110        for (i = 12; i <= 14; i++)
 111                (pDot11dInfo->channel_map)[i] = 2;
 112        pDot11dInfo->State = DOT11D_STATE_NONE;
 113        pDot11dInfo->CountryIeLen = 0;
 114        RESET_CIE_WATCHDOG(ieee);
 115}
 116
 117void Dot11d_UpdateCountryIe(struct rtllib_device *dev, u8 *pTaddr,
 118                            u16 CoutryIeLen, u8 *pCoutryIe)
 119{
 120        struct rt_dot11d_info *pDot11dInfo = GET_DOT11D_INFO(dev);
 121        u8 i, j, NumTriples, MaxChnlNum;
 122        struct chnl_txpow_triple *pTriple;
 123
 124        memset(pDot11dInfo->channel_map, 0, MAX_CHANNEL_NUMBER + 1);
 125        memset(pDot11dInfo->MaxTxPwrDbmList, 0xFF, MAX_CHANNEL_NUMBER + 1);
 126        MaxChnlNum = 0;
 127        NumTriples = (CoutryIeLen - 3) / 3;
 128        pTriple = (struct chnl_txpow_triple *)(pCoutryIe + 3);
 129        for (i = 0; i < NumTriples; i++) {
 130                if (MaxChnlNum >= pTriple->FirstChnl) {
 131                        netdev_info(dev->dev,
 132                                    "%s: Invalid country IE, skip it......1\n",
 133                                    __func__);
 134                        return;
 135                }
 136                if (MAX_CHANNEL_NUMBER < (pTriple->FirstChnl +
 137                    pTriple->NumChnls)) {
 138                        netdev_info(dev->dev,
 139                                    "%s: Invalid country IE, skip it......2\n",
 140                                    __func__);
 141                        return;
 142                }
 143
 144                for (j = 0; j < pTriple->NumChnls; j++) {
 145                        pDot11dInfo->channel_map[pTriple->FirstChnl + j] = 1;
 146                        pDot11dInfo->MaxTxPwrDbmList[pTriple->FirstChnl + j] =
 147                                                 pTriple->MaxTxPowerInDbm;
 148                        MaxChnlNum = pTriple->FirstChnl + j;
 149                }
 150
 151                pTriple = (struct chnl_txpow_triple *)((u8 *)pTriple + 3);
 152        }
 153
 154        UPDATE_CIE_SRC(dev, pTaddr);
 155
 156        pDot11dInfo->CountryIeLen = CoutryIeLen;
 157        memcpy(pDot11dInfo->CountryIeBuf, pCoutryIe, CoutryIeLen);
 158        pDot11dInfo->State = DOT11D_STATE_LEARNED;
 159}
 160
 161void DOT11D_ScanComplete(struct rtllib_device *dev)
 162{
 163        struct rt_dot11d_info *pDot11dInfo = GET_DOT11D_INFO(dev);
 164
 165        switch (pDot11dInfo->State) {
 166        case DOT11D_STATE_LEARNED:
 167                pDot11dInfo->State = DOT11D_STATE_DONE;
 168                break;
 169        case DOT11D_STATE_DONE:
 170                Dot11d_Reset(dev);
 171                break;
 172        case DOT11D_STATE_NONE:
 173                break;
 174        }
 175}
 176