static VOID ChipBBPAdjust(RTMP_ADAPTER *pAd) { UCHAR rf_bw, ext_ch; UCHAR bbp_val; #ifdef DOT11_N_SUPPORT if (get_ht_cent_ch(pAd, &rf_bw, &ext_ch) == FALSE) #endif /* DOT11_N_SUPPORT */ { rf_bw = BW_20; ext_ch = EXTCHA_NONE; pAd->CommonCfg.CentralChannel = pAd->CommonCfg.Channel; } rtmp_bbp_set_bw(pAd, rf_bw); /* TX/RX : control channel setting */ rtmp_mac_set_ctrlch(pAd, ext_ch); rtmp_bbp_set_ctrlch(pAd, ext_ch); /* request by Gary 20070208 for middle and long range G Band*/ #ifdef DOT11_N_SUPPORT if (rf_bw == BW_40) bbp_val = (pAd->CommonCfg.Channel > 14) ? 0x48 : 0x38; else #endif /* DOT11_N_SUPPORT */ bbp_val = (pAd->CommonCfg.Channel > 14) ? 0x40 : 0x38; rtmp_bbp_set_agc(pAd, bbp_val, RX_CHAIN_ALL); if (pAd->MACVersion == 0x28600100) { #ifdef RT28xx RT28xx_ch_tunning(pAd, BW_40); #endif /* RT28xx */ } else { RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R69, 0x12); RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R70, 0x0A); RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R73, 0x10); } DBGPRINT(RT_DEBUG_TRACE, ("%s(): BW_%s, ChannelWidth=%d, Channel=%d, ExtChanOffset=%d(%d) \n", __FUNCTION__, (rf_bw == BW_40 ? "40" : "20"), pAd->CommonCfg.HtCapability.HtCapInfo.ChannelWidth, pAd->CommonCfg.Channel, pAd->CommonCfg.RegTransmitSetting.field.EXTCHA, pAd->CommonCfg.AddHTInfo.AddHtInfo.ExtChanOffset)); /* request by Gary 20070208 for middle and long range A Band*/ if (pAd->CommonCfg.Channel > 14) bbp_val = 0x1D; else bbp_val = 0x2D; RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R62, 0x2D); RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R63, 0x2D); RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R64, 0x2D); /*RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R86, 0x2D);*/ }
INT dev_adjust_radio(RTMP_ADAPTER *pAd) { struct hw_setting *hw_cfg = &pAd->hw_cfg, new_cfg; NdisZeroMemory(&new_cfg, sizeof(struct hw_setting)); /* For all wdev, find the maximum inter-set */ if (hw_cfg->bbp_bw != new_cfg.bbp_bw) { rtmp_bbp_set_bw(pAd, new_cfg.bbp_bw); hw_cfg->bbp_bw = new_cfg.bbp_bw; } if (hw_cfg->cent_ch != new_cfg.cent_ch) { UCHAR ext_ch = EXTCHA_NONE; rtmp_bbp_set_ctrlch(pAd, ext_ch); rtmp_mac_set_ctrlch(pAd, ext_ch); } return TRUE; }
/*======================================================================== Routine Description: AsicSetChannel -- switch channel , bandwidth and 40MHz above/below setting Arguments: ch : Channel number, if 'bw' is BW_40, 'ch' is Center channel [1~14] bw : Bandwidth [BW_20, BW40] ext_ch: 11n bandwidth setting [EXTCHA_NONE, EXTCHA_ABOVE, EXTCHA_BELOW] if 'bw'=BW_20, 'ext_ch' should be EXTCHA_NONE or EXTCHA_ABOVE, these two options have the same effect for BW_20. if 'bw'=BW_20, 'ext_ch' should not be EXTCHA_BELOW Return Value: 0 is success Note: ========================================================================*/ INT AsicSetChannel(UCHAR ch, UCHAR bw, UCHAR ext_ch) { BOOLEAN bScan = FALSE; rtmp_bbp_set_bw(bw); /* Tx/RX : control channel setting */ /*set band as 40MHz above or Below*/ rtmp_bbp_set_ctrlch(ext_ch); rtmp_mac_set_ctrlch(ext_ch); /* Let BBP register at 20MHz to do scan */ AsicSwitchChannel(ch, bScan); return 0; }
/* ======================================================================== Routine Description: Caller ensures we has 802.11n support. Calls at setting HT from AP/STASetinformation Arguments: pAd - Pointer to our adapter phymode - ======================================================================== */ VOID RTMPSetHT( IN RTMP_ADAPTER *pAd, IN OID_SET_HT_PHYMODE *pHTPhyMode) { UCHAR RxStream = pAd->CommonCfg.RxStream; #ifdef CONFIG_AP_SUPPORT int apidx; #endif /* CONFIG_AP_SUPPORT */ int bw; RT_HT_CAPABILITY *rt_ht_cap = &pAd->CommonCfg.DesiredHtPhy; HT_CAPABILITY_IE *ht_cap= &pAd->CommonCfg.HtCapability; #ifdef CONFIG_AP_SUPPORT /* sanity check for extention channel */ if (CHAN_PropertyCheck(pAd, pAd->CommonCfg.Channel, CHANNEL_NO_FAT_BELOW | CHANNEL_NO_FAT_ABOVE) == TRUE) { /* only 20MHz is allowed */ pHTPhyMode->BW = 0; } else if (pHTPhyMode->ExtOffset == EXTCHA_BELOW) { /* extension channel below this channel is not allowed */ if (CHAN_PropertyCheck(pAd, pAd->CommonCfg.Channel, CHANNEL_NO_FAT_BELOW) == TRUE) { pHTPhyMode->ExtOffset = EXTCHA_ABOVE; } } else if (pHTPhyMode->ExtOffset == EXTCHA_ABOVE) { /* extension channel above this channel is not allowed */ if (CHAN_PropertyCheck(pAd, pAd->CommonCfg.Channel, CHANNEL_NO_FAT_ABOVE) == TRUE) { pHTPhyMode->ExtOffset = EXTCHA_BELOW; } } #endif /* CONFIG_AP_SUPPORT */ DBGPRINT(RT_DEBUG_TRACE, ("RTMPSetHT : HT_mode(%d), ExtOffset(%d), MCS(%d), BW(%d), STBC(%d), SHORTGI(%d)\n", pHTPhyMode->HtMode, pHTPhyMode->ExtOffset, pHTPhyMode->MCS, pHTPhyMode->BW, pHTPhyMode->STBC, pHTPhyMode->SHORTGI)); /* Don't zero supportedHyPhy structure.*/ RTMPZeroMemory(ht_cap, sizeof(HT_CAPABILITY_IE)); RTMPZeroMemory(&pAd->CommonCfg.AddHTInfo, sizeof(pAd->CommonCfg.AddHTInfo)); RTMPZeroMemory(&pAd->CommonCfg.NewExtChanOffset, sizeof(pAd->CommonCfg.NewExtChanOffset)); RTMPZeroMemory(rt_ht_cap, sizeof(RT_HT_CAPABILITY)); if (pAd->CommonCfg.bRdg) { ht_cap->ExtHtCapInfo.PlusHTC = 1; ht_cap->ExtHtCapInfo.RDGSupport = 1; } else { ht_cap->ExtHtCapInfo.PlusHTC = 0; ht_cap->ExtHtCapInfo.RDGSupport = 0; } if (RxStream == 1) { ht_cap->HtCapParm.MaxRAmpduFactor = 2; rt_ht_cap->MaxRAmpduFactor = 2; } else { ht_cap->HtCapParm.MaxRAmpduFactor = 3; rt_ht_cap->MaxRAmpduFactor = 3; } DBGPRINT(RT_DEBUG_TRACE, ("RTMPSetHT : RxBAWinLimit = %d\n", pAd->CommonCfg.BACapability.field.RxBAWinLimit)); /* Mimo power save, A-MSDU size, */ rt_ht_cap->AmsduEnable = (USHORT)pAd->CommonCfg.BACapability.field.AmsduEnable; rt_ht_cap->AmsduSize = (UCHAR)pAd->CommonCfg.BACapability.field.AmsduSize; rt_ht_cap->MimoPs = (UCHAR)pAd->CommonCfg.BACapability.field.MMPSmode; rt_ht_cap->MpduDensity = (UCHAR)pAd->CommonCfg.BACapability.field.MpduDensity; ht_cap->HtCapInfo.AMsduSize = (USHORT)pAd->CommonCfg.BACapability.field.AmsduSize; ht_cap->HtCapInfo.MimoPs = (USHORT)pAd->CommonCfg.BACapability.field.MMPSmode; ht_cap->HtCapParm.MpduDensity = (UCHAR)pAd->CommonCfg.BACapability.field.MpduDensity; DBGPRINT(RT_DEBUG_TRACE, ("RTMPSetHT : AMsduSize = %d, MimoPs = %d, MpduDensity = %d, MaxRAmpduFactor = %d\n", rt_ht_cap->AmsduSize, rt_ht_cap->MimoPs, rt_ht_cap->MpduDensity, rt_ht_cap->MaxRAmpduFactor)); if(pHTPhyMode->HtMode == HTMODE_GF) { ht_cap->HtCapInfo.GF = 1; rt_ht_cap->GF = 1; } else rt_ht_cap->GF = 0; /* Decide Rx MCSSet*/ switch (RxStream) { case 3: ht_cap->MCSSet[2] = 0xff; case 2: ht_cap->MCSSet[1] = 0xff; case 1: default: ht_cap->MCSSet[0] = 0xff; break; } if (pAd->CommonCfg.bForty_Mhz_Intolerant && (pHTPhyMode->BW == BW_40)) { pHTPhyMode->BW = BW_20; ht_cap->HtCapInfo.Forty_Mhz_Intolerant = 1; } // TODO: shiang-6590, how about the "bw" when channel 14 for JP region??? bw = BW_20; if(pHTPhyMode->BW == BW_40) { ht_cap->MCSSet[4] = 0x1; /* MCS 32*/ ht_cap->HtCapInfo.ChannelWidth = 1; if (pAd->CommonCfg.Channel <= 14) ht_cap->HtCapInfo.CCKmodein40 = 1; rt_ht_cap->ChannelWidth = 1; pAd->CommonCfg.AddHTInfo.AddHtInfo.RecomWidth = 1; pAd->CommonCfg.AddHTInfo.AddHtInfo.ExtChanOffset = (pHTPhyMode->ExtOffset == EXTCHA_BELOW)? (EXTCHA_BELOW): EXTCHA_ABOVE; /* Set Regsiter for extension channel position.*/ rtmp_mac_set_ctrlch(pAd, pHTPhyMode->ExtOffset); /* Turn on BBP 40MHz mode now only as AP . */ /* Sta can turn on BBP 40MHz after connection with 40MHz AP. Sta only broadcast 40MHz capability before connection.*/ if ((pAd->OpMode == OPMODE_AP) || INFRA_ON(pAd) || ADHOC_ON(pAd) ) { rtmp_bbp_set_ctrlch(pAd, pHTPhyMode->ExtOffset); #ifdef GREENAP_SUPPORT if (pAd->ApCfg.bGreenAPActive == 1) bw = BW_20; else #endif /* GREENAP_SUPPORT */ bw = BW_40; } } else { ht_cap->HtCapInfo.ChannelWidth = 0; rt_ht_cap->ChannelWidth = 0; pAd->CommonCfg.AddHTInfo.AddHtInfo.RecomWidth = 0; pAd->CommonCfg.AddHTInfo.AddHtInfo.ExtChanOffset = EXTCHA_NONE; pAd->CommonCfg.CentralChannel = pAd->CommonCfg.Channel; /* Turn on BBP 20MHz mode by request here.*/ bw = BW_20; } #ifdef DOT11_VHT_AC if (pHTPhyMode->BW == BW_40 && pAd->CommonCfg.vht_bw == VHT_BW_80 && pAd->CommonCfg.vht_cent_ch) bw = BW_80; #endif /* DOT11_VHT_AC */ rtmp_bbp_set_bw(pAd, bw); if(pHTPhyMode->STBC == STBC_USE) { if (pAd->Antenna.field.TxPath >= 2) { ht_cap->HtCapInfo.TxSTBC = 1; rt_ht_cap->TxSTBC = 1; } else { ht_cap->HtCapInfo.TxSTBC = 0; rt_ht_cap->TxSTBC = 0; } /* RxSTBC 0: not support, 1: support for 1SS 2: support for 1SS, 2SS 3: support for 1SS, 2SS, 3SS */ if (pAd->Antenna.field.RxPath >= 1) { ht_cap->HtCapInfo.RxSTBC = 1; rt_ht_cap->RxSTBC = 1; } else { ht_cap->HtCapInfo.RxSTBC = 0; rt_ht_cap->RxSTBC = 0; } } else { rt_ht_cap->TxSTBC = 0; rt_ht_cap->RxSTBC = 0; } if(pHTPhyMode->SHORTGI == GI_400) { ht_cap->HtCapInfo.ShortGIfor20 = 1; ht_cap->HtCapInfo.ShortGIfor40 = 1; rt_ht_cap->ShortGIfor20 = 1; rt_ht_cap->ShortGIfor40 = 1; } else { ht_cap->HtCapInfo.ShortGIfor20 = 0; ht_cap->HtCapInfo.ShortGIfor40 = 0; rt_ht_cap->ShortGIfor20 = 0; rt_ht_cap->ShortGIfor40 = 0; } /* We support link adaptation for unsolicit MCS feedback, set to 2.*/ pAd->CommonCfg.AddHTInfo.ControlChan = pAd->CommonCfg.Channel; /* 1, the extension channel above the control channel. */ /* EDCA parameters used for AP's own transmission*/ if (pAd->CommonCfg.APEdcaParm.bValid == FALSE) { pAd->CommonCfg.APEdcaParm.bValid = TRUE; pAd->CommonCfg.APEdcaParm.Aifsn[0] = 3; pAd->CommonCfg.APEdcaParm.Aifsn[1] = 7; pAd->CommonCfg.APEdcaParm.Aifsn[2] = 1; pAd->CommonCfg.APEdcaParm.Aifsn[3] = 1; pAd->CommonCfg.APEdcaParm.Cwmin[0] = 4; pAd->CommonCfg.APEdcaParm.Cwmin[1] = 4; pAd->CommonCfg.APEdcaParm.Cwmin[2] = 3; pAd->CommonCfg.APEdcaParm.Cwmin[3] = 2; pAd->CommonCfg.APEdcaParm.Cwmax[0] = 6; pAd->CommonCfg.APEdcaParm.Cwmax[1] = 10; pAd->CommonCfg.APEdcaParm.Cwmax[2] = 4; pAd->CommonCfg.APEdcaParm.Cwmax[3] = 3; pAd->CommonCfg.APEdcaParm.Txop[0] = 0; pAd->CommonCfg.APEdcaParm.Txop[1] = 0; pAd->CommonCfg.APEdcaParm.Txop[2] = 94; pAd->CommonCfg.APEdcaParm.Txop[3] = 47; } AsicSetEdcaParm(pAd, &pAd->CommonCfg.APEdcaParm); #ifdef TXBF_SUPPORT if (pAd->chipCap.FlgHwTxBfCap) { /* Set ETxBF */ setETxBFCap(pAd, &ht_cap->TxBFCap); /* Check ITxBF */ pAd->CommonCfg.RegTransmitSetting.field.ITxBfEn &= rtmp_chk_itxbf_calibration(pAd); /* Apply to ASIC */ rtmp_asic_set_bf(pAd); } #endif /* TXBF_SUPPORT */ #ifdef CONFIG_AP_SUPPORT IF_DEV_CONFIG_OPMODE_ON_AP(pAd) { for (apidx = 0; apidx < pAd->ApCfg.BssidNum; apidx++) RTMPSetIndividualHT(pAd, apidx); #ifdef WDS_SUPPORT for (apidx = 0; apidx < MAX_WDS_ENTRY; apidx++) RTMPSetIndividualHT(pAd, apidx + MIN_NET_DEVICE_FOR_WDS); #endif /* WDS_SUPPORT */ #ifdef APCLI_SUPPORT for (apidx = 0; apidx < MAX_APCLI_NUM; apidx++) RTMPSetIndividualHT(pAd, apidx + MIN_NET_DEVICE_FOR_APCLI); #endif /* APCLI_SUPPORT */ } #endif /* CONFIG_AP_SUPPORT */ }