/* ======================================================================== Routine Description: Caller ensures we has 802.11n support. Calls at setting HT from AP/STASetinformation Arguments: pAd - Pointer to our adapter phymode - ======================================================================== */ VOID RTMPSetIndividualHT( IN RTMP_ADAPTER *pAd, IN UCHAR apidx) { RT_PHY_INFO *pDesired_ht_phy = NULL; UCHAR TxStream = pAd->CommonCfg.TxStream; UCHAR DesiredMcs = MCS_AUTO; UCHAR encrypt_mode = Ndis802_11EncryptionDisabled; do { #ifdef CONFIG_AP_SUPPORT #ifdef APCLI_SUPPORT if (apidx >= MIN_NET_DEVICE_FOR_APCLI) { UCHAR idx = apidx - MIN_NET_DEVICE_FOR_APCLI; if (idx < MAX_APCLI_NUM) { pDesired_ht_phy = &pAd->ApCfg.ApCliTab[idx].DesiredHtPhyInfo; DesiredMcs = pAd->ApCfg.ApCliTab[idx].DesiredTransmitSetting.field.MCS; encrypt_mode = pAd->ApCfg.ApCliTab[idx].WepStatus; pAd->ApCfg.ApCliTab[idx].bAutoTxRateSwitch = (DesiredMcs == MCS_AUTO) ? TRUE : FALSE; break; } else { DBGPRINT(RT_DEBUG_ERROR, ("RTMPSetIndividualHT: invalid idx(%d)\n", idx)); return; } } #endif /* APCLI_SUPPORT */ IF_DEV_CONFIG_OPMODE_ON_AP(pAd) { #ifdef WDS_SUPPORT if (apidx >= MIN_NET_DEVICE_FOR_WDS) { UCHAR idx = apidx - MIN_NET_DEVICE_FOR_WDS; if (idx < MAX_WDS_ENTRY) { pDesired_ht_phy = &pAd->WdsTab.WdsEntry[idx].DesiredHtPhyInfo; DesiredMcs = pAd->WdsTab.WdsEntry[idx].DesiredTransmitSetting.field.MCS; /*encrypt_mode = pAd->WdsTab.WdsEntry[idx].WepStatus;*/ pAd->WdsTab.WdsEntry[idx].bAutoTxRateSwitch = (DesiredMcs == MCS_AUTO) ? TRUE : FALSE; break; } else { DBGPRINT(RT_DEBUG_ERROR, ("RTMPSetIndividualHT: invalid apidx(%d)\n", apidx)); return; } } #endif /* WDS_SUPPORT */ if ((apidx < pAd->ApCfg.BssidNum) && (apidx < MAX_MBSSID_NUM(pAd)) && (apidx < HW_BEACON_MAX_NUM)) { pDesired_ht_phy = &pAd->ApCfg.MBSSID[apidx].DesiredHtPhyInfo; DesiredMcs = pAd->ApCfg.MBSSID[apidx].DesiredTransmitSetting.field.MCS; encrypt_mode = pAd->ApCfg.MBSSID[apidx].WepStatus; pAd->ApCfg.MBSSID[apidx].bWmmCapable = TRUE; pAd->ApCfg.MBSSID[apidx].bAutoTxRateSwitch = (DesiredMcs == MCS_AUTO) ? TRUE : FALSE; break; } DBGPRINT(RT_DEBUG_ERROR, ("RTMPSetIndividualHT: invalid apidx(%d)\n", apidx)); return; } #endif /* CONFIG_AP_SUPPORT */ } while (FALSE); if (pDesired_ht_phy == NULL) { DBGPRINT(RT_DEBUG_ERROR, ("RTMPSetIndividualHT: invalid apidx(%d)\n", apidx)); return; } RTMPZeroMemory(pDesired_ht_phy, sizeof(RT_PHY_INFO)); DBGPRINT(RT_DEBUG_TRACE, ("RTMPSetIndividualHT : Desired MCS = %d\n", DesiredMcs)); /* Check the validity of MCS */ if ((TxStream == 1) && ((DesiredMcs >= MCS_8) && (DesiredMcs <= MCS_15))) { DBGPRINT(RT_DEBUG_WARN, ("RTMPSetIndividualHT: MCS(%d) is invalid in 1S, reset it as MCS_7\n", DesiredMcs)); DesiredMcs = MCS_7; } if ((pAd->CommonCfg.DesiredHtPhy.ChannelWidth == BW_20) && (DesiredMcs == MCS_32)) { DBGPRINT(RT_DEBUG_WARN, ("RTMPSetIndividualHT: MCS_32 is only supported in 40-MHz, reset it as MCS_0\n")); DesiredMcs = MCS_0; } /* WFA recommend to restrict the encryption type in 11n-HT mode. So, the WEP and TKIP are not allowed in HT rate. */ if (pAd->CommonCfg.HT_DisallowTKIP && IS_INVALID_HT_SECURITY(encrypt_mode)) { DBGPRINT(RT_DEBUG_WARN, ("%s : Use legacy rate in WEP/TKIP encryption mode (apidx=%d)\n", __FUNCTION__, apidx)); return; } if (pAd->CommonCfg.HT_Disable) { DBGPRINT(RT_DEBUG_TRACE, ("%s : HT is disabled\n", __FUNCTION__)); return; } pDesired_ht_phy->bHtEnable = TRUE; /* Decide desired Tx MCS*/ switch (TxStream) { case 1: if (DesiredMcs == MCS_AUTO) pDesired_ht_phy->MCSSet[0]= 0xff; else if (DesiredMcs <= MCS_7) pDesired_ht_phy->MCSSet[0]= 1<<DesiredMcs; break; case 2: if (DesiredMcs == MCS_AUTO) { pDesired_ht_phy->MCSSet[0]= 0xff; pDesired_ht_phy->MCSSet[1]= 0xff; } else if (DesiredMcs <= MCS_15) { ULONG mode; mode = DesiredMcs / 8; if (mode < 2) pDesired_ht_phy->MCSSet[mode] = (1 << (DesiredMcs - mode * 8)); } break; case 3: if (DesiredMcs == MCS_AUTO) { /* MCS0 ~ MCS23, 3 bytes */ pDesired_ht_phy->MCSSet[0]= 0xff; pDesired_ht_phy->MCSSet[1]= 0xff; pDesired_ht_phy->MCSSet[2]= 0xff; } else if (DesiredMcs <= MCS_23) { ULONG mode; mode = DesiredMcs / 8; if (mode < 3) pDesired_ht_phy->MCSSet[mode] = (1 << (DesiredMcs - mode * 8)); } break; } if(pAd->CommonCfg.DesiredHtPhy.ChannelWidth == BW_40) { if (DesiredMcs == MCS_AUTO || DesiredMcs == MCS_32) pDesired_ht_phy->MCSSet[4] = 0x1; } /* update HT Rate setting */ if (pAd->OpMode == OPMODE_STA) { MlmeUpdateHtTxRates(pAd, BSS0); } else MlmeUpdateHtTxRates(pAd, apidx); #ifdef DOT11_VHT_AC if (WMODE_CAP_AC(pAd->CommonCfg.PhyMode)) { pDesired_ht_phy->bVhtEnable = TRUE; rtmp_set_vht(pAd, pDesired_ht_phy); } #endif /* DOT11_VHT_AC */ }
/* ======================================================================== Routine Description: Caller ensures we has 802.11n support. Calls at setting HT from AP/STASetinformation Arguments: pAd - Pointer to our adapter phymode - ======================================================================== */ VOID RTMPSetIndividualHT(struct rtmp_adapter *pAd, u8 apidx) { RT_PHY_INFO *pDesired_ht_phy = NULL; u8 TxStream = pAd->CommonCfg.TxStream; u8 DesiredMcs = MCS_AUTO; u8 encrypt_mode = Ndis802_11EncryptionDisabled; struct rtmp_wifi_dev *wdev; do { #ifdef CONFIG_AP_SUPPORT IF_DEV_CONFIG_OPMODE_ON_AP(pAd) { if ((apidx < pAd->ApCfg.BssidNum) && (apidx < MAX_MBSSID_NUM(pAd)) && (apidx < HW_BEACON_MAX_NUM)) { wdev = &pAd->ApCfg.MBSSID[apidx].wdev; pDesired_ht_phy = &wdev->DesiredHtPhyInfo; DesiredMcs = wdev->DesiredTransmitSetting.field.MCS; #ifdef WFA_VHT_PF // TODO: Sigma, this code segment used to work around for Sigma Automation! if (WMODE_CAP_AC(pAd->CommonCfg.PhyMode) && (DesiredMcs != MCS_AUTO)) { DesiredMcs += ((TxStream - 1) << 4); pAd->ApCfg.MBSSID[apidx].DesiredTransmitSetting.field.FixedTxMode = FIXED_TXMODE_VHT; RT_CfgSetAutoFallBack(pAd, "0"); } else { RT_CfgSetAutoFallBack(pAd, "1"); } #endif /* WFA_VHT_PF */ encrypt_mode = wdev->WepStatus; pAd->ApCfg.MBSSID[apidx].wdev.bWmmCapable = true; wdev->bAutoTxRateSwitch = (DesiredMcs == MCS_AUTO) ? true : false; break; } DBGPRINT(RT_DEBUG_ERROR, ("RTMPSetIndividualHT: invalid apidx(%d)\n", apidx)); return; } #endif /* CONFIG_AP_SUPPORT */ #ifdef CONFIG_STA_SUPPORT IF_DEV_CONFIG_OPMODE_ON_STA(pAd) { wdev = &pAd->StaCfg.wdev; pDesired_ht_phy = &wdev->DesiredHtPhyInfo; DesiredMcs = wdev->DesiredTransmitSetting.field.MCS; encrypt_mode = wdev->WepStatus; break; } #endif /* CONFIG_STA_SUPPORT */ } while (false); if (pDesired_ht_phy == NULL) { DBGPRINT(RT_DEBUG_ERROR, ("RTMPSetIndividualHT: invalid apidx(%d)\n", apidx)); return; } RTMPZeroMemory(pDesired_ht_phy, sizeof(RT_PHY_INFO)); DBGPRINT(RT_DEBUG_TRACE, ("RTMPSetIndividualHT : Desired MCS = %d\n", DesiredMcs)); /* Check the validity of MCS */ if ((TxStream == 1) && ((DesiredMcs >= MCS_8) && (DesiredMcs <= MCS_15))) { DBGPRINT(RT_DEBUG_WARN, ("RTMPSetIndividualHT: MCS(%d) is invalid in 1S, reset it as MCS_7\n", DesiredMcs)); DesiredMcs = MCS_7; } if ((pAd->CommonCfg.DesiredHtPhy.ChannelWidth == BW_20) && (DesiredMcs == MCS_32)) { DBGPRINT(RT_DEBUG_WARN, ("RTMPSetIndividualHT: MCS_32 is only supported in 40-MHz, reset it as MCS_0\n")); DesiredMcs = MCS_0; } #ifdef CONFIG_STA_SUPPORT if ((pAd->OpMode == OPMODE_STA) && (pAd->StaCfg.BssType == BSS_INFRA) && (apidx == MIN_NET_DEVICE_FOR_MBSSID)) ; else #endif /* CONFIG_STA_SUPPORT */ /* WFA recommend to restrict the encryption type in 11n-HT mode. So, the WEP and TKIP are not allowed in HT rate. */ if (pAd->CommonCfg.HT_DisallowTKIP && IS_INVALID_HT_SECURITY(encrypt_mode)) { #ifdef CONFIG_STA_SUPPORT pAd->StaCfg.bAdhocN = false; #endif /* CONFIG_STA_SUPPORT */ DBGPRINT(RT_DEBUG_WARN, ("%s : Use legacy rate in WEP/TKIP encryption mode (apidx=%d)\n", __FUNCTION__, apidx)); return; } if (pAd->CommonCfg.HT_Disable) { #ifdef CONFIG_STA_SUPPORT pAd->StaCfg.bAdhocN = false; #endif /* CONFIG_STA_SUPPORT */ DBGPRINT(RT_DEBUG_TRACE, ("%s : HT is disabled\n", __FUNCTION__)); return; } pDesired_ht_phy->bHtEnable = true; /* Decide desired Tx MCS*/ switch (TxStream) { case 1: if (DesiredMcs == MCS_AUTO) pDesired_ht_phy->MCSSet[0]= 0xff; else if (DesiredMcs <= MCS_7) pDesired_ht_phy->MCSSet[0]= 1<<DesiredMcs; break; case 2: if (DesiredMcs == MCS_AUTO) { pDesired_ht_phy->MCSSet[0]= 0xff; pDesired_ht_phy->MCSSet[1]= 0xff; } else if (DesiredMcs <= MCS_15) { ULONG mode; mode = DesiredMcs / 8; if (mode < 2) pDesired_ht_phy->MCSSet[mode] = (1 << (DesiredMcs - mode * 8)); } break; case 3: if (DesiredMcs == MCS_AUTO) { /* MCS0 ~ MCS23, 3 bytes */ pDesired_ht_phy->MCSSet[0]= 0xff; pDesired_ht_phy->MCSSet[1]= 0xff; pDesired_ht_phy->MCSSet[2]= 0xff; } else if (DesiredMcs <= MCS_23) { ULONG mode; mode = DesiredMcs / 8; if (mode < 3) pDesired_ht_phy->MCSSet[mode] = (1 << (DesiredMcs - mode * 8)); } break; } if(pAd->CommonCfg.DesiredHtPhy.ChannelWidth == BW_40) { if (DesiredMcs == MCS_AUTO || DesiredMcs == MCS_32) pDesired_ht_phy->MCSSet[4] = 0x1; } /* update HT Rate setting */ if (pAd->OpMode == OPMODE_STA) { MlmeUpdateHtTxRates(pAd, BSS0); } else MlmeUpdateHtTxRates(pAd, apidx); if (WMODE_CAP_AC(pAd->CommonCfg.PhyMode)) { pDesired_ht_phy->bVhtEnable = true; rtmp_set_vht(pAd, pDesired_ht_phy); } }