📄 wlan_11d.c
字号:
//
// Copyright (c) Microsoft Corporation. All rights reserved.
//
//
// Use of this sample source code is subject to the terms of the Microsoft
// license agreement under which you licensed this sample source code. If
// you did not accept the terms of the license agreement, you are not
// authorized to use this sample source code. For the terms of the license,
// please see the license agreement between you and Microsoft or, if applicable,
// see the LICENSE.RTF on your install media or the root of your tools installation.
// THE SAMPLE SOURCE CODE IS PROVIDED "AS IS", WITH NO WARRANTIES OR INDEMNITIES.
//
/** @file wlan_11d.c
* Copyright (c) Marvell Semiconductor, Inc.
*/
#include "precomp.h"
#ifdef ENABLE_802_11D
// Convert Region string to code integer
UCHAR region_2_code(CHAR *region)
{
int i, size;
CHAR country1[COUNTRY_CODE_LEN + 1];
CHAR country2[COUNTRY_CODE_LEN + 1];
DBGPRINT(DBG_ALLEN, ("region_2_code() \n"));
NdisMoveMemory (country1, region, COUNTRY_CODE_LEN);
country1[COUNTRY_CODE_LEN]='\0';
size = sizeof(region_code_mapping)/sizeof(region_code_mapping_t);
for (i=0; i<size; i++)
{
NdisMoveMemory (country2, region_code_mapping[i].region, COUNTRY_CODE_LEN);
country2[COUNTRY_CODE_LEN]='\0';
if ((country1[0]==country2[0] || country1[0]+0x20==country2[0] || country1[0]==country2[0]+0x20) &&
(country1[1]==country2[1] || country1[1]+0x20==country2[1] || country1[1]==country2[1]+0x20) &&
(country1[2]==country2[2] || country1[2]+0x20==country2[2] || country1[2]==country2[2]+0x20))
return (region_code_mapping[i].code);
}
return 0;
}
/*
// Convert interger code to region string
CHAR *code_2_region( UCHAR code )
{
int i;
int size = sizeof(region_code_mapping)/ sizeof(region_code_mapping_t);
for ( i=0; i< size; i++ )
{
if ( region_code_mapping[i].code == code )
return (region_code_mapping[i].region);
}
return NULL;
}
// Convert chan to frequency
ULONG chan_2_freq ( USHORT chan, UCHAR band)
{
CHANNEL_FREQ_POWER *cf;
UCHAR cnt;
int i;
if ( band == MRVDRV_802_11_BAND_A )
{
cf =channel_freq_power_UN_AJ;
cnt = sizeof(channel_freq_power_UN_AJ)/sizeof(CHANNEL_FREQ_POWER);
}
else
{
cf = channel_freq_power_UN_BG;
cnt = sizeof(channel_freq_power_UN_BG)/sizeof(CHANNEL_FREQ_POWER);
}
for ( i=0; i< cnt; i++ )
{
if ( chan == cf[i].Channel )
return cf[i].Freq;
}
return 0;
}
*/
VOID
ResetAllScanTypeAndPower(
PMRVDRV_ADAPTER Adapter
)
{
// int i;
DBGPRINT(DBG_ALLEN, ("ResetAllScanTypeAndPower() \n"));
if (Adapter->region_channel[0].Valid)
{
Adapter->region_channel[0].Region = 0;
NdisFillMemory(Adapter->region_channel[0].ScanType, MAX_PSCAN_CH_NUM, 0x00);
NdisFillMemory(Adapter->region_channel[0].TxPower, MAX_PSCAN_CH_NUM, TX_PWR_DEFAULT);
}
if (Adapter->region_channel[1].Valid)
{
Adapter->region_channel[1].Region = 0;
NdisFillMemory(Adapter->region_channel[1].ScanType, MAX_PSCAN_CH_NUM, 0x00);
NdisFillMemory(Adapter->region_channel[1].TxPower, MAX_PSCAN_CH_NUM, TX_PWR_DEFAULT);
}
}
VOID
UpdateScanTypeFromCountryIE(
PMRVDRV_ADAPTER Adapter,
UCHAR BssidListIndex // 0xff for all list entry
)
{
PBSS_DESCRIPTION_SET_ALL_FIELDS pBissidListDesc;
IEEEtypes_CountryInfoFullSet_t *pCountryIE;
CHANNEL_FREQ_POWER *pNewCFP_BG;
CHANNEL_FREQ_POWER *pNewCFP_A;
IEEEtypes_SubbandSet_t *pSubband;
int RemainLen;
int i, j, k, k1;
UCHAR CountryNum;
DBGPRINT(DBG_ALLEN, ("UpdateScanTypeFromCountryIE() \n"));
pBissidListDesc = Adapter->PSBssDescList;
if (BssidListIndex == 0xff)
{
for (i=0; Adapter->ulPSNumOfBSSIDs ; i++)
{
pCountryIE = &(pBissidListDesc[i].CountryInfo);
CountryNum = region_2_code( pCountryIE->CountryCode);
if (CountryNum != 0) // first conntry info
break;
}
}
else
{
pCountryIE = &(pBissidListDesc[BssidListIndex].CountryInfo);
CountryNum = region_2_code( pCountryIE->CountryCode);
}
if ((CountryNum != 0) &&
((CountryNum == 0x10) || (CountryNum == 0x30) || (CountryNum == 0x31) ||
(CountryNum == 0x32) || (CountryNum == 0x40)))
{
switch (CountryNum)
{
case 0x10: // "US ", "CA "
pNewCFP_BG = channel_freq_power_US_BG;
pNewCFP_A = channel_freq_power_A;
k = sizeof(channel_freq_power_US_BG)/sizeof(CHANNEL_FREQ_POWER);
k1 = sizeof(channel_freq_power_A)/sizeof(CHANNEL_FREQ_POWER);
break;
case 0x30: // "EU "
pNewCFP_BG = channel_freq_power_EU_BG;
pNewCFP_A = channel_freq_power_EU_A;
k = sizeof(channel_freq_power_EU_BG)/sizeof(CHANNEL_FREQ_POWER);
k1 = sizeof(channel_freq_power_EU_A)/sizeof(CHANNEL_FREQ_POWER);
break;
case 0x31: // "ES "
pNewCFP_BG = channel_freq_power_SPN_BG;
pNewCFP_A = channel_freq_power_A;
k = sizeof(channel_freq_power_SPN_BG)/sizeof(CHANNEL_FREQ_POWER);
k1 = sizeof(channel_freq_power_A)/sizeof(CHANNEL_FREQ_POWER);
break;
case 0x32: // "FR "
pNewCFP_BG = channel_freq_power_FR_BG;
pNewCFP_A = channel_freq_power_A;
k = sizeof(channel_freq_power_FR_BG)/sizeof(CHANNEL_FREQ_POWER);
k1 = sizeof(channel_freq_power_A)/sizeof(CHANNEL_FREQ_POWER);
break;
case 0x40: // "JP "
pNewCFP_BG = channel_freq_power_JPN_BG;
pNewCFP_A = channel_freq_power_JPN_A;
k = sizeof(channel_freq_power_JPN_BG)/sizeof(CHANNEL_FREQ_POWER);
k1 = sizeof(channel_freq_power_JPN_A)/sizeof(CHANNEL_FREQ_POWER);
break;
}
DBGPRINT(DBG_ALLEN, ("CountryNum = %d, k = %d, k1 = %d \n", CountryNum, k, k1));
if (Adapter->region_channel[0].Valid)
{
Adapter->region_channel[0].Region = CountryNum;
// set passive scan type to all channel
NdisFillMemory(Adapter->region_channel[0].ScanType, MAX_PSCAN_CH_NUM, 0x01);
for (i=0; i< Adapter->region_channel[0].NrCFP; i++)
{
for (j=0; j< k; j++)
{
if (Adapter->region_channel[0].CFP[i].Channel == pNewCFP_BG[j].Channel)
{
Adapter->region_channel[0].ScanType[i] = 0;
break;
}
}
}
RemainLen = pCountryIE->Len - COUNTRY_CODE_LEN;
pSubband = pCountryIE->Subband;
while (RemainLen)
{
for(j=0; j<pSubband->NoOfChan; j++)
{
for (i=0; i< Adapter->region_channel[0].NrCFP; i++)
{
if (Adapter->region_channel[0].CFP[i].Channel == pSubband->FirstChan + j)
{
Adapter->region_channel[0].TxPower[i] = pSubband->MaxTxPwr;
break;
}
}
}
RemainLen -= sizeof(IEEEtypes_SubbandSet_t);
if (RemainLen < sizeof(IEEEtypes_SubbandSet_t))
break;
pSubband += 1;
}
///HexDump(DBG_ALLEN, "region_channel[0]", (UCHAR *)&(Adapter->region_channel[0]),
/// sizeof(REGION_CHANNEL));
///HexDump(DBG_ALLEN, "Adapter->region_channel.CFP", (UCHAR *)(Adapter->region_channel[0].CFP),
/// sizeof(CHANNEL_FREQ_POWER)*k);
}
if (Adapter->region_channel[1].Valid)
{
Adapter->region_channel[1].Region = CountryNum;
// set passive scan type to all channel
NdisFillMemory(Adapter->region_channel[1].ScanType, MAX_PSCAN_CH_NUM, 0x01);
for (i=0; i< Adapter->region_channel[1].NrCFP; i++)
{
for (j=0; j< k1; j++)
{
if (Adapter->region_channel[1].CFP[i].Channel == pNewCFP_BG[j].Channel)
{ // set active sacn type to the channel
Adapter->region_channel[1].ScanType[i] = 0;
break;
}
}
}
RemainLen = pCountryIE->Len - COUNTRY_CODE_LEN;
pSubband = pCountryIE->Subband;
while (RemainLen)
{
for(j=0; j<pSubband->NoOfChan; j++)
{
for (i=0; i< Adapter->region_channel[1].NrCFP; i++)
{
if (Adapter->region_channel[1].CFP[i].Channel == pSubband->FirstChan + j)
{
Adapter->region_channel[1].TxPower[i] = pSubband->MaxTxPwr;
break;
}
}
}
RemainLen -= sizeof(IEEEtypes_SubbandSet_t);
if (RemainLen < sizeof(IEEEtypes_SubbandSet_t))
break;
pSubband += 1;
}
///HexDump(DBG_ALLEN, "region_channel[1]", (UCHAR *)&(Adapter->region_channel[1]),
/// sizeof(REGION_CHANNEL));
///HexDump(DBG_ALLEN, "Adapter->region_channel.CFP", (UCHAR *)(Adapter->region_channel[1].CFP),
/// sizeof(CHANNEL_FREQ_POWER)*k1);
}
}
return;
}
// Generate domaininfo CountryIE
VOID
GenerateDomainInfoFromCountryIE(
MrvlIEtypes_DomainParamSet_t *pDomainInfo,
IEEEtypes_CountryInfoFullSet_t *pCountryIE
)
{
DBGPRINT(DBG_ALLEN, ("GenerateDomainInfoFromCountryIE() \n"));
NdisMoveMemory (pDomainInfo->CountryCode, pCountryIE->CountryCode, COUNTRY_CODE_LEN);
pDomainInfo->Header.Len= (SHORT)pCountryIE->Len;
pDomainInfo->Header.Type = TLV_TYPE_DOMAIN;
NdisMoveMemory(pDomainInfo->Subband, pCountryIE->Subband, pCountryIE->Len);
return;
}
// Enable/Disable 11D via set SNMP OID to FW
VOID
Enable_11d(
PMRVDRV_ADAPTER Adapter,
BOOLEAN enable )
{
USHORT Cmdopt = 0;
if (enable)
Cmdopt = 1;
PrepareAndSendCommand(
Adapter,
HostCmd_CMD_802_11_SNMP_MIB,
0,
HostCmd_OPTION_USE_INT,
OID_802_11D_ENABLE,
HostCmd_PENDING_ON_NONE,
0,
FALSE,
NULL,
NULL,
NULL,
&Cmdopt);
return;
}
// Set DOMAIN INFO to FW
VOID
SetDomainInfo(
PMRVDRV_ADAPTER Adapter,
IEEEtypes_CountryInfoFullSet_t *pCountryIE)
{
PrepareAndSendCommand(
Adapter,
HostCmd_CMD_802_11D_DOMAIN_INFO,
HostCmd_ACT_SET,
HostCmd_OPTION_USE_INT,
0,
HostCmd_PENDING_ON_NONE,
0,
FALSE,
NULL,
NULL,
NULL,
(PVOID)pCountryIE
);
return;
}
#endif
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -