📄 wlan_11d.c
字号:
LEAVE();
return WLAN_STATUS_SUCCESS;
}
static int wlan_channel_known_11d ( u8 chan,
parsed_region_chan_11d_t *parsed_region_chan)
/*Check if chan txpwr is learned from AP/IBSS*/
{
chan_power_11d_t *chanPwr = parsed_region_chan->chanPwr;
u8 NoOfChan = parsed_region_chan->NoOfChan;
int i =0;
ENTER();
HEXDUMP( "11D:parsed_region_chan:", (char *)chanPwr,
sizeof(chan_power_11d_t)*NoOfChan );
for( i=0; i<NoOfChan; i++ ) {
if ( chan == chanPwr[i].chan ) {
PRINTK("11D: Found Chan:%d\n", chan );
LEAVE();
return 1;
}
}
PRINTK("11D: Not Find Chan:%d\n", chan );
LEAVE();
return 0;
}
u8 wlan_get_scan_type_11d( u8 chan,
parsed_region_chan_11d_t *parsed_region_chan)
/* calsulate the scan typefor channels
1. Active scan for all chan in parsed_region_chan(learned form AP/IBSS)
2. Passive scan for all other channels
*/
{
u8 scan_type = HostCmd_SCAN_TYPE_PASSIVE;
ENTER();
if ( wlan_channel_known_11d( chan, parsed_region_chan) ) {
PRINTK("11D: Found and do Active Scan\n");
scan_type = HostCmd_SCAN_TYPE_ACTIVE;
}
else {
PRINTK("11D: Not Find and do Passive Scan\n");
}
LEAVE();
return scan_type;
}
state_11d_t wlan_get_state_11d( wlan_private *priv )
/* Get if 11D is enabled?*/
{
wlan_adapter *Adapter = priv->adapter;
wlan_802_11d_state_t *state = &Adapter->State11D;
return (state->Enable11D);
}
void wlan_init_11d( wlan_private *priv)
{
wlan_adapter *Adapter = priv->adapter;
wlan_802_11d_state_t *state = &Adapter->State11D;
state->Enable11D = DISABLE_11D;
memset( &(priv->adapter->parsed_region_chan), 0,
sizeof(parsed_region_chan_11d_t) );
return;
}
int wlan_enable_11d( wlan_private * priv, state_11d_t flag )
/* Enable/Disable 11D via set SNMP OID to FW*/
{
wlan_adapter *Adapter = priv->adapter;
wlan_802_11d_state_t *state = &Adapter->State11D;
int ret;
state_11d_t enable = flag;
ENTER();
state->Enable11D = flag;
/* send cmd to FW to enable/disable 11D fucntion in FW */
ret = PrepareAndSendCommand(priv, HostCmd_CMD_802_11_SNMP_MIB,
0, HostCmd_OPTION_USE_INT, OID_802_11D_ENABLE,
HostCmd_PENDING_ON_SET_OID, &enable );
if (ret) {
PRINTK2("11D: Fail to enable 11D \n");
}
LEAVE();
return WLAN_STATUS_SUCCESS;
}
int wlan_set_domain_info_11d( wlan_private * priv )
/* Set DOMAIN INFO to FW*/
{
int ret;
if( !wlan_get_state_11d( priv) ) {
PRINTK2("11D: dnld domain Info with 11d disabled\n");
return WLAN_STATUS_SUCCESS;
}
ret = PrepareAndSendCommand(priv, HostCmd_CMD_802_11D_DOMAIN_INFO,
HostCmd_ACT_GEN_SET, HostCmd_OPTION_USE_INT,
0, HostCmd_PENDING_ON_NONE, NULL);
if (ret) {
PRINTK2("11D: Fail to dnld domain Info\n");
}
LEAVE();
return ret;
}
int wlan_set_universaltable(wlan_private *priv, u8 band)
/* Setup scan channels when disconnected */
{
wlan_adapter *Adapter = priv->adapter;
int size = sizeof(CHANNEL_FREQ_POWER);
int i = 0;
ENTER();
memset(Adapter->universal_channel, 0, sizeof(Adapter->universal_channel));
#ifdef MULTI_BANDS
if (band & (BAND_B | BAND_G))
#endif
{
Adapter->universal_channel[i].NrCFP =
sizeof(channel_freq_power_UN_BG) / size;
PRINTK2("11D: BG-band NrCFP=%d\n",
Adapter->universal_channel[i].NrCFP );
Adapter->universal_channel[i].CFP =
channel_freq_power_UN_BG;
Adapter->universal_channel[i].Valid = TRUE;
Adapter->universal_channel[i].Region = UNIVERSAL_REGION_CODE;
#ifdef MULTI_BANDS
Adapter->universal_channel[i].Band =
(band & BAND_G) ? BAND_G : BAND_B;
#else
Adapter->universal_channel[i].Band = band;
#endif
i++;
}
#ifdef MULTI_BANDS
if (band & BAND_A) {
Adapter->universal_channel[i].NrCFP =
sizeof(channel_freq_power_UN_AJ) / size;
PRINTK2("11D: AJ-band NrCFP=%d\n",
Adapter->universal_channel[i].NrCFP );
Adapter->universal_channel[i].CFP =
channel_freq_power_UN_AJ;
Adapter->universal_channel[i].Valid = TRUE;
Adapter->universal_channel[i].Region = UNIVERSAL_REGION_CODE;
Adapter->universal_channel[i].Band = BAND_A;
i++;
}
#endif
LEAVE();
return 0;
}
int wlan_cmd_802_11d_domain_info(wlan_private * priv,
HostCmd_DS_COMMAND * cmd, u16 cmdno, u16 CmdOption)
/*Domain Info command: CMD_802_11D_DOMAIN_INFO*/
{
HostCmd_DS_802_11D_DOMAIN_INFO *pDomainInfo = &cmd->params.domaininfo;
MrvlIEtypes_DomainParamSet_t *domain = &pDomainInfo->Domain;
wlan_adapter *Adapter = priv->adapter;
unsigned int NoOfSubband = Adapter->DomainReg.NoOfSubband;
ENTER();
PRINTK2("NoOfSubband=%x\n", NoOfSubband );
cmd->Command = wlan_cpu_to_le16(cmdno);
pDomainInfo->Action = wlan_cpu_to_le16(CmdOption);
if ( CmdOption == HostCmd_ACT_GET ) {
cmd->Size = wlan_cpu_to_le16(sizeof( pDomainInfo->Action ) + S_DS_GEN);
HEXDUMP("11D: 802_11D_DOMAIN_INFO:", (u8 *)cmd, (int)(cmd->Size) );
LEAVE();
return 0;
}
domain->Header.Type = wlan_cpu_to_le16(TLV_TYPE_DOMAIN); /*0007*/
memcpy( domain->CountryCode, Adapter->DomainReg.CountryCode,
sizeof(domain->CountryCode) );
domain->Header.Len =
wlan_cpu_to_le16(NoOfSubband * sizeof(IEEEtypes_SubbandSet_t) +
sizeof(domain->CountryCode));
if ( NoOfSubband ) {
memcpy( domain->Subband, Adapter->DomainReg.Subband,
NoOfSubband * sizeof(IEEEtypes_SubbandSet_t) );
cmd->Size = wlan_cpu_to_le16(sizeof(pDomainInfo->Action)+
domain->Header.Len +
sizeof(MrvlIEtypesHeader_t) + S_DS_GEN);
}
else {
cmd->Size = wlan_cpu_to_le16(sizeof(pDomainInfo->Action) + S_DS_GEN);
}
HEXDUMP("11D:802_11D_DOMAIN_INFO:", (u8 *)cmd, (int)(cmd->Size) );
LEAVE();
return 0;
}
int wlan_cmd_enable_11d( wlan_private *priv, struct iwreq *wrq )
/*private cmd: enable/disable 11D*/
{
int data = *((int *)wrq->u.data.pointer);
wlan_adapter *Adapter = priv->adapter;
ENTER();
if ( wrq->u.data.length == 0 ) {
return -EINVAL;
}
PRINTK2("Enable 11D: %s\n", (data==1)?"Enable":"Disable");
switch ( data ) {
case CMD_ENABLED:
wlan_enable_11d(priv, ENABLE_11D );
break;
case CMD_DISABLED:
wlan_enable_11d( priv, DISABLE_11D );
break;
default:
break;
}
data = (Adapter->State11D.Enable11D==ENABLE_11D)?CMD_ENABLED:CMD_DISABLED;
copy_to_user(wrq->u.data.pointer, &data, sizeof(int) );
wrq->u.data.length = 1;
LEAVE();
return WLAN_STATUS_SUCCESS;
}
int wlan_ret_802_11d_domain_info(wlan_private * priv,
HostCmd_DS_COMMAND * resp)
/*Domain Info response process*/
{
HostCmd_DS_802_11D_DOMAIN_INFO_RSP
*domaininfo = &resp->params.domaininforesp;
MrvlIEtypes_DomainParamSet_t
*domain = &domaininfo->Domain;
u16 Action = wlan_le16_to_cpu(domaininfo->Action);
int ret=0;
int NoOfSubband = 0;
ENTER();
HEXDUMP( "11D DOMAIN Info Rsp Data:", (u8 *)resp,
(int)wlan_le16_to_cpu(resp->Size) );
NoOfSubband = ( domain->Header.Len - 3 ) / sizeof(IEEEtypes_SubbandSet_t);
/* countrycode 3 bytes */
PRINTK2("11D Domain Info Resp: NoOfSubband=%d\n", NoOfSubband);
if (NoOfSubband > MRVDRV_MAX_SUBBAND_802_11D ) {
PRINTK2("Invalid Numrer of Subband returned!!\n");
return -1;
}
switch (Action) {
case HostCmd_ACT_SET: /*Proc Set Action */
break;
case HostCmd_ACT_GET:
break;
default:
PRINTK2("Invalid Action:%d\n", domaininfo->Action );
ret = -1;
break;
}
LEAVE();
return ret;
}
int wlan_parse_dnld_countryinfo_11d( wlan_private *priv )
/*parse countryinfo from AP and download country info to FW*/
{
int ret;
wlan_adapter * Adapter = priv->adapter;
ENTER();
if( wlan_get_state_11d( priv) == ENABLE_11D ) {
memset( &Adapter->parsed_region_chan, 0, sizeof(parsed_region_chan_11d_t) );
ret = wlan_parse_domain_info_11d(
&(Adapter->BSSIDList[Adapter->ulAttemptedBSSIDIndex].CountryInfo),
#ifdef MULTI_BANDS
Adapter->CurBssParams.band,
#else
0,
#endif
&Adapter->parsed_region_chan
);
if( ret == WLAN_STATUS_FAILURE ) {
PRINTK2("11D: Err Parse domain_info from AP..\n");
LEAVE();
return ret;
}
memset( &Adapter->DomainReg,0, sizeof(wlan_802_11d_domain_reg_t) );
wlan_generate_domain_info_11d(
&Adapter->parsed_region_chan,
&Adapter->DomainReg
);
ret = wlan_set_domain_info_11d( priv );
if ( ret ) {
PRINTK2("11D: Err set domainInfo to FW\n");
LEAVE();
return ret;
}
}
LEAVE();
return WLAN_STATUS_SUCCESS;
}
int wlan_create_dnld_countryinfo_11d( wlan_private *priv )
/*generate from user specified regioncode and download to FW*/
{
int ret;
wlan_adapter * Adapter = priv->adapter;
REGION_CHANNEL *region_chan;
int j;
ENTER();
PRINTK2("11D:CurBssParams.Band[%d]\n", Adapter->CurBssParams.band);
if( wlan_get_state_11d(priv) == ENABLE_11D ) {
/* update parsed_region_chan_11; dnld domaininf to FW */
for (j = 0; j < sizeof(Adapter->region_channel) /
sizeof(Adapter->region_channel[0]); j++ ) {
region_chan = &Adapter->region_channel[j];
PRINTK2("11D:[%d] region_chan->Band[%d]\n",j, region_chan->Band);
if(!region_chan || !region_chan->Valid || !region_chan->CFP)
continue;
#ifdef MULTI_BANDS
switch (region_chan->Band) {
case BAND_A:
switch (Adapter->CurBssParams.band) {
case BAND_A:
break;
default:
continue;
}
break;
case BAND_B:
case BAND_G:
switch (Adapter->CurBssParams.band) {
case BAND_B:
case BAND_G:
break;
default:
continue;
}
break;
default:
continue;
}
#else
if (region_chan->Band != Adapter->CurBssParams.band )
continue;
#endif
break;
}
if (j >= sizeof(Adapter->region_channel)/
sizeof(Adapter->region_channel[0]) ) {
PRINTK2("11D:region_chan not found. Band[%d]\n",
Adapter->CurBssParams.band);
LEAVE();
return WLAN_STATUS_FAILURE;
}
memset( &Adapter->parsed_region_chan, 0, sizeof(parsed_region_chan_11d_t) );
wlan_generate_parsed_region_chan_11d(
region_chan,
&Adapter->parsed_region_chan
);
memset( &Adapter->DomainReg,0, sizeof(wlan_802_11d_domain_reg_t) );
wlan_generate_domain_info_11d(
&Adapter->parsed_region_chan,
&Adapter->DomainReg
);
ret = wlan_set_domain_info_11d( priv );
if ( ret ) {
PRINTK2("11D: Err set domainInfo to FW\n");
LEAVE();
return ret;
}
}
LEAVE();
return WLAN_STATUS_SUCCESS;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -