VOID Phydm_NHMCounterStatisticsInit( IN PVOID pDM_VOID ) { PDM_ODM_T pDM_Odm = (PDM_ODM_T)pDM_VOID; if (pDM_Odm->SupportICType & ODM_IC_11N_SERIES) { /*PHY parameters initialize for n series*/ ODM_Write2Byte(pDM_Odm, ODM_REG_NHM_TIMER_11N + 2, 0xC350); /*0x894[31:16]=0x0xC350 Time duration for NHM unit: us, 0xc350=200ms*/ ODM_Write2Byte(pDM_Odm, ODM_REG_NHM_TH9_TH10_11N + 2, 0xffff); /*0x890[31:16]=0xffff th_9, th_10*/ ODM_Write4Byte(pDM_Odm, ODM_REG_NHM_TH3_TO_TH0_11N, 0xffffff50); /*0x898=0xffffff52 th_3, th_2, th_1, th_0*/ ODM_Write4Byte(pDM_Odm, ODM_REG_NHM_TH7_TO_TH4_11N, 0xffffffff); /*0x89c=0xffffffff th_7, th_6, th_5, th_4*/ ODM_SetBBReg(pDM_Odm, ODM_REG_FPGA0_IQK_11N, bMaskByte0, 0xff); /*0xe28[7:0]=0xff th_8*/ ODM_SetBBReg(pDM_Odm, ODM_REG_NHM_TH9_TH10_11N, BIT10 | BIT9 | BIT8, 0x1); /*0x890[10:8]=1 ignoreCCA ignore PHYTXON enable CCX*/ ODM_SetBBReg(pDM_Odm, ODM_REG_OFDM_FA_RSTC_11N, BIT7, 0x1); /*0xc0c[7]=1 max power among all RX ants*/ } #if (RTL8195A_SUPPORT == 0) else if (pDM_Odm->SupportICType & ODM_IC_11AC_SERIES) { /*PHY parameters initialize for ac series*/ ODM_Write2Byte(pDM_Odm, ODM_REG_NHM_TIMER_11AC + 2, 0xC350); /*0x990[31:16]=0xC350 Time duration for NHM unit: us, 0xc350=200ms*/ ODM_Write2Byte(pDM_Odm, ODM_REG_NHM_TH9_TH10_11AC + 2, 0xffff); /*0x994[31:16]=0xffff th_9, th_10*/ ODM_Write4Byte(pDM_Odm, ODM_REG_NHM_TH3_TO_TH0_11AC, 0xffffff50); /*0x998=0xffffff52 th_3, th_2, th_1, th_0*/ ODM_Write4Byte(pDM_Odm, ODM_REG_NHM_TH7_TO_TH4_11AC, 0xffffffff); /*0x99c=0xffffffff th_7, th_6, th_5, th_4*/ ODM_SetBBReg(pDM_Odm, ODM_REG_NHM_TH8_11AC, bMaskByte0, 0xff); /*0x9a0[7:0]=0xff th_8*/ ODM_SetBBReg(pDM_Odm, ODM_REG_NHM_TH9_TH10_11AC, BIT8 | BIT9 | BIT10, 0x1); /*0x994[10:8]=1 ignoreCCA ignore PHYTXON enable CCX*/ ODM_SetBBReg(pDM_Odm, ODM_REG_NHM_9E8_11AC, BIT0, 0x1); /*0x9e8[7]=1 max power among all RX ants*/ } #endif }
VOID HalTxbf8814A_Status( IN PVOID pDM_VOID, IN u1Byte Idx ) { PDM_ODM_T pDM_Odm = (PDM_ODM_T)pDM_VOID; u2Byte BeamCtrlVal, tmpVal; u4Byte BeamCtrlReg; PRT_BEAMFORMING_INFO pBeamformingInfo = &pDM_Odm->BeamformingInfo; RT_BEAMFORMEE_ENTRY BeamformEntry; if (Idx < BEAMFORMEE_ENTRY_NUM) BeamformEntry = pBeamformingInfo->BeamformeeEntry[Idx]; else return; if (phydm_actingDetermine(pDM_Odm, PhyDM_ACTING_AS_IBSS)) BeamCtrlVal = BeamformEntry.MacId; else BeamCtrlVal = BeamformEntry.P_AID; ODM_RT_TRACE(pDM_Odm, PHYDM_COMP_TXBF, ODM_DBG_LOUD, ("@%s, BeamformEntry.BeamformEntryState = %d", __func__, BeamformEntry.BeamformEntryState)); if (Idx == 0) BeamCtrlReg = REG_TXBF_CTRL_8814A; else { BeamCtrlReg = REG_TXBF_CTRL_8814A + 2; BeamCtrlVal |= BIT12 | BIT14 | BIT15; } if (BeamformEntry.BeamformEntryState == BEAMFORMING_ENTRY_STATE_PROGRESSED) { if (BeamformEntry.SoundBW == CHANNEL_WIDTH_20) BeamCtrlVal |= BIT9; else if (BeamformEntry.SoundBW == CHANNEL_WIDTH_40) BeamCtrlVal |= (BIT9 | BIT10); else if (BeamformEntry.SoundBW == CHANNEL_WIDTH_80) BeamCtrlVal |= (BIT9 | BIT10 | BIT11); } else { ODM_RT_TRACE(pDM_Odm, PHYDM_COMP_TXBF, ODM_DBG_LOUD, ("@%s, Don't apply Vmatrix", __func__)); BeamCtrlVal &= ~(BIT9 | BIT10 | BIT11); } ODM_Write2Byte(pDM_Odm, BeamCtrlReg, BeamCtrlVal); /*disable NDP packet use beamforming */ tmpVal = ODM_Read2Byte(pDM_Odm, REG_TXBF_CTRL_8814A); ODM_Write2Byte(pDM_Odm, REG_TXBF_CTRL_8814A, tmpVal | BIT15); }
VOID odm_NHMBBInit( IN PVOID pDM_VOID ) { PDM_ODM_T pDM_Odm = (PDM_ODM_T)pDM_VOID; pDM_Odm->adaptivity_flag = 0; pDM_Odm->tolerance_cnt = 3; pDM_Odm->NHMLastTxOkcnt = 0; pDM_Odm->NHMLastRxOkcnt = 0; pDM_Odm->NHMCurTxOkcnt = 0; pDM_Odm->NHMCurRxOkcnt = 0; if(pDM_Odm->SupportICType & ODM_IC_11AC_SERIES) { //PHY parameters initialize for ac series ODM_Write2Byte(pDM_Odm, ODM_REG_NHM_TIMER_11AC+2, 0x2710); //0x990[31:16]=0x2710 Time duration for NHM unit: 4us, 0x2710=40ms ODM_Write2Byte(pDM_Odm, ODM_REG_NHM_TH9_TH10_11AC+2, 0xffff); //0x994[31:16]=0xffff th_9, th_10 //ODM_Write4Byte(pDM_Odm, ODM_REG_NHM_TH3_TO_TH0_11AC, 0xffffff5c); //0x998=0xffffff5c th_3, th_2, th_1, th_0 ODM_Write4Byte(pDM_Odm, ODM_REG_NHM_TH3_TO_TH0_11AC, 0xffffff52); //0x998=0xffffff52 th_3, th_2, th_1, th_0 ODM_Write4Byte(pDM_Odm, ODM_REG_NHM_TH7_TO_TH4_11AC, 0xffffffff); //0x99c=0xffffffff th_7, th_6, th_5, th_4 ODM_SetBBReg(pDM_Odm, ODM_REG_NHM_TH8_11AC, bMaskByte0, 0xff); //0x9a0[7:0]=0xff th_8 ODM_SetBBReg(pDM_Odm, ODM_REG_NHM_TH9_TH10_11AC, BIT8|BIT9|BIT10, 7); //0x994[9:8]=3 enable CCX ODM_SetBBReg(pDM_Odm, ODM_REG_NHM_9E8_11AC, BIT0, 1); //0x9e8[7]=1 max power among all RX ants //panic_printk("RTL8812AU phy parameters init %s,%d\n", __FUNCTION__, __LINE__); } else if (pDM_Odm->SupportICType & ODM_IC_11N_SERIES) { //PHY parameters initialize for n series ODM_Write2Byte(pDM_Odm, ODM_REG_NHM_TIMER_11N+2, 0x2710); //0x894[31:16]=0x2710 Time duration for NHM unit: 4us, 0x2710=40ms //ODM_Write2Byte(pDM_Odm, ODM_REG_NHM_TIMER_11N+2, 0x4e20); //0x894[31:16]=0x4e20 Time duration for NHM unit: 4us, 0x4e20=80ms ODM_Write2Byte(pDM_Odm, ODM_REG_NHM_TH9_TH10_11N+2, 0xffff); //0x890[31:16]=0xffff th_9, th_10 //ODM_Write4Byte(pDM_Odm, ODM_REG_NHM_TH3_TO_TH0_11N, 0xffffff5c); //0x898=0xffffff5c th_3, th_2, th_1, th_0 ODM_Write4Byte(pDM_Odm, ODM_REG_NHM_TH3_TO_TH0_11N, 0xffffff52); //0x898=0xffffff52 th_3, th_2, th_1, th_0 ODM_Write4Byte(pDM_Odm, ODM_REG_NHM_TH7_TO_TH4_11N, 0xffffffff); //0x89c=0xffffffff th_7, th_6, th_5, th_4 ODM_SetBBReg(pDM_Odm, ODM_REG_FPGA0_IQK_11N, bMaskByte0, 0xff); //0xe28[7:0]=0xff th_8 ODM_SetBBReg(pDM_Odm, ODM_REG_NHM_TH9_TH10_11N, BIT10|BIT9|BIT8, 7); //0x890[9:8]=3 enable CCX ODM_SetBBReg(pDM_Odm, ODM_REG_OFDM_FA_RSTC_11N, BIT7, 1); //0xc0c[7]=1 max power among all RX ants } }
VOID HalTxbf8192E_Leave( IN PVOID pDM_VOID, IN u1Byte Idx ) { PDM_ODM_T pDM_Odm = (PDM_ODM_T)pDM_VOID; PRT_BEAMFORMING_INFO pBeamInfo = &pDM_Odm->BeamformingInfo; halTxbf8192E_RfMode(pDM_Odm, pBeamInfo); /* Clear P_AID of Beamformee * Clear MAC addresss of Beamformer * Clear Associated Bfmee Sel */ if (pBeamInfo->BeamformCap == BEAMFORMING_CAP_NONE) ODM_Write1Byte(pDM_Odm, REG_SND_PTCL_CTRL_8192E, 0xC8); if (Idx == 0) { ODM_Write2Byte(pDM_Odm, REG_TXBF_CTRL_8192E, 0); ODM_Write4Byte(pDM_Odm, REG_ASSOCIATED_BFMER0_INFO_8192E, 0); ODM_Write2Byte(pDM_Odm, REG_ASSOCIATED_BFMER0_INFO_8192E+4, 0); ODM_Write2Byte(pDM_Odm, REG_ASSOCIATED_BFMEE_SEL_8192E, 0); } else { ODM_Write2Byte(pDM_Odm, REG_TXBF_CTRL_8192E+2, ODM_Read1Byte(pDM_Odm, REG_TXBF_CTRL_8192E+2) & 0xF000); ODM_Write4Byte(pDM_Odm, REG_ASSOCIATED_BFMER1_INFO_8192E, 0); ODM_Write2Byte(pDM_Odm, REG_ASSOCIATED_BFMER1_INFO_8192E+4, 0); ODM_Write2Byte(pDM_Odm, REG_ASSOCIATED_BFMEE_SEL_8192E+2, ODM_Read2Byte(pDM_Odm, REG_ASSOCIATED_BFMEE_SEL_8192E+2) & 0x60); } ODM_RT_TRACE(pDM_Odm, PHYDM_COMP_TXBF, ODM_DBG_LOUD, ("[%s] Idx %d\n", __func__, Idx)); }
VOID HalTxbf8814A_Leave( IN PVOID pDM_VOID, IN u1Byte Idx ) { PDM_ODM_T pDM_Odm = (PDM_ODM_T)pDM_VOID; PRT_BEAMFORMING_INFO pBeamformingInfo = &pDM_Odm->BeamformingInfo; RT_BEAMFORMER_ENTRY BeamformerEntry; RT_BEAMFORMEE_ENTRY BeamformeeEntry; if (Idx < BEAMFORMER_ENTRY_NUM) { BeamformerEntry = pBeamformingInfo->BeamformerEntry[Idx]; BeamformeeEntry = pBeamformingInfo->BeamformeeEntry[Idx]; } else return; /*Clear P_AID of Beamformee*/ /*Clear MAC address of Beamformer*/ /*Clear Associated Bfmee Sel*/ if (BeamformerEntry.BeamformEntryCap == BEAMFORMING_CAP_NONE) { ODM_Write1Byte(pDM_Odm, REG_SND_PTCL_CTRL_8814A, 0xD8); if (Idx == 0) { ODM_Write4Byte(pDM_Odm, REG_ASSOCIATED_BFMER0_INFO_8814A, 0); ODM_Write2Byte(pDM_Odm, REG_ASSOCIATED_BFMER0_INFO_8814A + 4, 0); ODM_Write2Byte(pDM_Odm, REG_CSI_RPT_PARAM_BW20_8814A, 0); } else { ODM_Write4Byte(pDM_Odm, REG_ASSOCIATED_BFMER1_INFO_8814A, 0); ODM_Write2Byte(pDM_Odm, REG_ASSOCIATED_BFMER1_INFO_8814A + 4, 0); ODM_Write2Byte(pDM_Odm, REG_CSI_RPT_PARAM_BW20_8814A + 2, 0); } } if (BeamformeeEntry.BeamformEntryCap == BEAMFORMING_CAP_NONE) { halTxbf8814A_RfMode(pDM_Odm, pBeamformingInfo, Idx); if (Idx == 0) { ODM_Write2Byte(pDM_Odm, REG_TXBF_CTRL_8814A, 0x0); ODM_Write1Byte(pDM_Odm, REG_TXBF_CTRL_8814A + 3, ODM_Read1Byte(pDM_Odm, REG_TXBF_CTRL_8814A + 3) | BIT4 | BIT6 | BIT7); ODM_Write2Byte(pDM_Odm, REG_ASSOCIATED_BFMEE_SEL_8814A, 0); } else { ODM_Write2Byte(pDM_Odm, REG_TXBF_CTRL_8814A + 2, 0x0 | BIT14 | BIT15 | BIT12); ODM_Write2Byte(pDM_Odm, REG_ASSOCIATED_BFMEE_SEL_8814A + 2, ODM_Read2Byte(pDM_Odm, REG_ASSOCIATED_BFMEE_SEL_8814A + 2) & 0x60); } } }
VOID HalTxbf8821B_Status( IN PVOID pDM_VOID, IN u1Byte Idx ) { PDM_ODM_T pDM_Odm = (PDM_ODM_T)pDM_VOID; u2Byte BeamCtrlVal; u4Byte BeamCtrlReg; PRT_BEAMFORMING_INFO pBeamInfo = &pDM_Odm->BeamformingInfo; RT_BEAMFORMEE_ENTRY BeamformEntry = pBeamInfo->BeamformeeEntry[Idx]; if (phydm_actingDetermine(pDM_Odm, PhyDM_ACTING_AS_IBSS)) BeamCtrlVal = BeamformEntry.MacId; else BeamCtrlVal = BeamformEntry.P_AID; if (Idx == 0) BeamCtrlReg = REG_TXBF_CTRL_8821B; else { BeamCtrlReg = REG_TXBF_CTRL_8821B + 2; BeamCtrlVal |= BIT12 | BIT14 | BIT15; } if (BeamformEntry.BeamformEntryState == BEAMFORMING_ENTRY_STATE_PROGRESSED) { if (BeamformEntry.SoundBW == CHANNEL_WIDTH_20) BeamCtrlVal |= BIT9; else if (BeamformEntry.SoundBW == CHANNEL_WIDTH_40) BeamCtrlVal |= BIT10; else if (BeamformEntry.SoundBW == CHANNEL_WIDTH_80) BeamCtrlVal |= BIT11; } else BeamCtrlVal &= ~(BIT9 | BIT10 | BIT11); ODM_RT_TRACE(pDM_Odm, PHYDM_COMP_TXBF, ODM_DBG_LOUD, ("[%s] BeamCtrlVal = 0x%x!\n", __func__, BeamCtrlVal)); ODM_Write2Byte(pDM_Odm, BeamCtrlReg, BeamCtrlVal); }
VOID phydm_DataRate_8814A( IN PDM_ODM_T pDM_Odm, IN u1Byte macId, OUT pu4Byte data, IN u1Byte dataLen ) { u1Byte i = 0; u2Byte XReadDataAddr = 0; ODM_Write2Byte(pDM_Odm, REG_PKTBUF_DBG_CTRL_8814A, PHYDM_CTRL_INFO_PAGE); XReadDataAddr = PHYDM_MEMORY_MAP_BUF_READ + macId*32; /*Ctrl Info: 32Bytes for each macid(n)*/ if ((XReadDataAddr < PHYDM_MEMORY_MAP_BUF_READ) || (XReadDataAddr > 0x8FFF)) { ODM_RT_TRACE(pDM_Odm, PHYDM_COMP_TXBF, ODM_DBG_LOUD, ("XReadDataAddr(0x%x) is not correct!\n", XReadDataAddr)); return; } /* Read data */ for (i = 0; i < dataLen; i++) *(data+i) = ODM_Read2Byte(pDM_Odm, XReadDataAddr+i); }
VOID HalTxbf8192E_Enter( IN PVOID pDM_VOID, IN u1Byte BFerBFeeIdx ) { PDM_ODM_T pDM_Odm = (PDM_ODM_T)pDM_VOID; u1Byte i = 0; u1Byte BFerIdx = (BFerBFeeIdx & 0xF0) >> 4; u1Byte BFeeIdx = (BFerBFeeIdx & 0xF); u4Byte CSI_Param; PRT_BEAMFORMING_INFO pBeamformingInfo = &pDM_Odm->BeamformingInfo; RT_BEAMFORMEE_ENTRY BeamformeeEntry; RT_BEAMFORMER_ENTRY BeamformerEntry; u2Byte STAid = 0; ODM_RT_TRACE(pDM_Odm, PHYDM_COMP_TXBF, ODM_DBG_LOUD, ("[%s] Start!\n", __func__)); halTxbf8192E_RfMode(pDM_Odm, pBeamformingInfo); if (pDM_Odm->RFType == ODM_2T2R) ODM_Write4Byte(pDM_Odm, 0xd80, 0x00000000); /*Nc =2*/ if ((pBeamformingInfo->beamformer_su_cnt > 0) && (BFerIdx < BEAMFORMER_ENTRY_NUM)) { BeamformerEntry = pBeamformingInfo->BeamformerEntry[BFerIdx]; /*Sounding protocol control*/ ODM_Write1Byte(pDM_Odm, REG_SND_PTCL_CTRL_8192E, 0xCB); /*MAC address/Partial AID of Beamformer*/ if (BFerIdx == 0) { for (i = 0; i < 6 ; i++) ODM_Write1Byte(pDM_Odm, (REG_ASSOCIATED_BFMER0_INFO_8192E+i), BeamformerEntry.MacAddr[i]); } else { for (i = 0; i < 6 ; i++) ODM_Write1Byte(pDM_Odm, (REG_ASSOCIATED_BFMER1_INFO_8192E+i), BeamformerEntry.MacAddr[i]); } /*CSI report parameters of Beamformer Default use Nc = 2*/ CSI_Param = 0x03090309; ODM_Write4Byte(pDM_Odm, REG_CSI_RPT_PARAM_BW20_8192E, CSI_Param); ODM_Write4Byte(pDM_Odm, REG_CSI_RPT_PARAM_BW40_8192E, CSI_Param); ODM_Write4Byte(pDM_Odm, REG_CSI_RPT_PARAM_BW80_8192E, CSI_Param); /*Timeout value for MAC to leave NDP_RX_standby_state (60 us, Test chip) (80 us, MP chip)*/ ODM_Write1Byte(pDM_Odm, REG_SND_PTCL_CTRL_8192E+3, 0x50); } if ((pBeamformingInfo->beamformee_su_cnt > 0) && (BFeeIdx < BEAMFORMEE_ENTRY_NUM)) { BeamformeeEntry = pBeamformingInfo->BeamformeeEntry[BFeeIdx]; if (phydm_actingDetermine(pDM_Odm, PhyDM_ACTING_AS_IBSS)) STAid = BeamformeeEntry.MacId; else STAid = BeamformeeEntry.P_AID; ODM_RT_TRACE(pDM_Odm, PHYDM_COMP_TXBF, ODM_DBG_LOUD, ("[%s], STAid=0x%X\n", __func__, STAid)); /*P_AID of Beamformee & enable NDPA transmission & enable NDPA interrupt*/ if (BFeeIdx == 0) { ODM_Write2Byte(pDM_Odm, REG_TXBF_CTRL_8192E, STAid); ODM_Write1Byte(pDM_Odm, REG_TXBF_CTRL_8192E+3, ODM_Read1Byte(pDM_Odm, REG_TXBF_CTRL_8192E+3) | BIT4 | BIT6 | BIT7); } else ODM_Write2Byte(pDM_Odm, REG_TXBF_CTRL_8192E+2, STAid | BIT12 | BIT14 | BIT15); /*CSI report parameters of Beamformee*/ if (BFeeIdx == 0) { /*Get BIT24 & BIT25*/ u1Byte tmp = ODM_Read1Byte(pDM_Odm, REG_ASSOCIATED_BFMEE_SEL_8192E+3) & 0x3; ODM_Write1Byte(pDM_Odm, REG_ASSOCIATED_BFMEE_SEL_8192E+3, tmp | 0x60); ODM_Write2Byte(pDM_Odm, REG_ASSOCIATED_BFMEE_SEL_8192E, STAid | BIT9); } else { /*Set BIT25*/ ODM_Write2Byte(pDM_Odm, REG_ASSOCIATED_BFMEE_SEL_8192E+2, STAid | 0xE200); } phydm_Beamforming_Notify(pDM_Odm); } }
VOID HalTxbf8814A_Enter( IN PVOID pDM_VOID, IN u1Byte BFerBFeeIdx ) { PDM_ODM_T pDM_Odm = (PDM_ODM_T)pDM_VOID; u1Byte i = 0; u1Byte BFerIdx = (BFerBFeeIdx & 0xF0) >> 4; u1Byte BFeeIdx = (BFerBFeeIdx & 0xF); PRT_BEAMFORMING_INFO pBeamformingInfo = &pDM_Odm->BeamformingInfo; RT_BEAMFORMEE_ENTRY BeamformeeEntry; RT_BEAMFORMER_ENTRY BeamformerEntry; u2Byte STAid = 0, CSI_Param = 0; u1Byte Nc_index = 0, Nr_index = 0, grouping = 0, codebookinfo = 0, coefficientsize = 0; ODM_RT_TRACE(pDM_Odm, PHYDM_COMP_TXBF, ODM_DBG_LOUD, ("[%s] BFerIdx=%d, BFeeIdx=%d\n", __func__, BFerIdx, BFeeIdx)); ODM_SetMACReg(pDM_Odm, REG_SND_PTCL_CTRL_8814A, bMaskByte1 | bMaskByte2, 0x0202); if ((pBeamformingInfo->beamformer_su_cnt > 0) && (BFerIdx < BEAMFORMER_ENTRY_NUM)) { BeamformerEntry = pBeamformingInfo->BeamformerEntry[BFerIdx]; /*Sounding protocol control*/ ODM_Write1Byte(pDM_Odm, REG_SND_PTCL_CTRL_8814A, 0xDB); /*MAC address/Partial AID of Beamformer*/ if (BFerIdx == 0) { for (i = 0; i < 6 ; i++) ODM_Write1Byte(pDM_Odm, (REG_ASSOCIATED_BFMER0_INFO_8814A + i), BeamformerEntry.MacAddr[i]); } else { for (i = 0; i < 6 ; i++) ODM_Write1Byte(pDM_Odm, (REG_ASSOCIATED_BFMER1_INFO_8814A + i), BeamformerEntry.MacAddr[i]); } /*CSI report parameters of Beamformer*/ Nc_index = halTxbf8814A_GetNrx(pDM_Odm); /*for 8814A Nrx = 3(4 Ant), min=0(1 Ant)*/ Nr_index = BeamformerEntry.NumofSoundingDim; /*0x718[7] = 1 use Nsts, 0x718[7] = 0 use reg setting. as Bfee, we use Nsts, so Nr_index don't care*/ grouping = 0; /*for ac = 1, for n = 3*/ if (BeamformerEntry.BeamformEntryCap & BEAMFORMEE_CAP_VHT_SU) codebookinfo = 1; else if (BeamformerEntry.BeamformEntryCap & BEAMFORMEE_CAP_HT_EXPLICIT) codebookinfo = 3; coefficientsize = 3; CSI_Param = (u2Byte)((coefficientsize << 10) | (codebookinfo << 8) | (grouping << 6) | (Nr_index << 3) | (Nc_index)); if (BFerIdx == 0) ODM_Write2Byte(pDM_Odm, REG_CSI_RPT_PARAM_BW20_8814A, CSI_Param); else ODM_Write2Byte(pDM_Odm, REG_CSI_RPT_PARAM_BW20_8814A + 2, CSI_Param); /*ndp_rx_standby_timer, 8814 need > 0x56, suggest from Dvaid*/ ODM_Write1Byte(pDM_Odm, REG_SND_PTCL_CTRL_8814A + 3, 0x40); } if ((pBeamformingInfo->beamformee_su_cnt > 0) && (BFeeIdx < BEAMFORMEE_ENTRY_NUM)) { BeamformeeEntry = pBeamformingInfo->BeamformeeEntry[BFeeIdx]; halTxbf8814A_RfMode(pDM_Odm, pBeamformingInfo, BFeeIdx); if (phydm_actingDetermine(pDM_Odm, PhyDM_ACTING_AS_IBSS)) STAid = BeamformeeEntry.MacId; else STAid = BeamformeeEntry.P_AID; /*P_AID of Beamformee & enable NDPA transmission & enable NDPA interrupt*/ if (BFeeIdx == 0) { ODM_Write2Byte(pDM_Odm, REG_TXBF_CTRL_8814A, STAid); ODM_Write1Byte(pDM_Odm, REG_TXBF_CTRL_8814A + 3, ODM_Read1Byte(pDM_Odm, REG_TXBF_CTRL_8814A + 3) | BIT4 | BIT6 | BIT7); } else ODM_Write2Byte(pDM_Odm, REG_TXBF_CTRL_8814A + 2, STAid | BIT14 | BIT15 | BIT12); /*CSI report parameters of Beamformee*/ if (BFeeIdx == 0) { /*Get BIT24 & BIT25*/ u1Byte tmp = ODM_Read1Byte(pDM_Odm, REG_ASSOCIATED_BFMEE_SEL_8814A + 3) & 0x3; ODM_Write1Byte(pDM_Odm, REG_ASSOCIATED_BFMEE_SEL_8814A + 3, tmp | 0x60); ODM_Write2Byte(pDM_Odm, REG_ASSOCIATED_BFMEE_SEL_8814A, STAid | BIT9); } else ODM_Write2Byte(pDM_Odm, REG_ASSOCIATED_BFMEE_SEL_8814A + 2, STAid | 0xE200); /*Set BIT25*/ phydm_Beamforming_Notify(pDM_Odm); } }
VOID halTxbf8814A_DownloadNDPA( IN PVOID pDM_VOID, IN u1Byte Idx ) { PDM_ODM_T pDM_Odm = (PDM_ODM_T)pDM_VOID; u1Byte u1bTmp = 0, tmpReg422 = 0; u1Byte BcnValidReg = 0, count = 0, DLBcnCount = 0; u2Byte Head_Page = 0x7FE; BOOLEAN bSendBeacon = FALSE; u2Byte TxPageBndy = LAST_ENTRY_OF_TX_PKT_BUFFER_8814A; /*default reseved 1 page for the IC type which is undefined.*/ PRT_BEAMFORMING_INFO pBeamInfo = &pDM_Odm->BeamformingInfo; PRT_BEAMFORMEE_ENTRY pBeamEntry = pBeamInfo->BeamformeeEntry + Idx; PADAPTER Adapter = pDM_Odm->Adapter; #if (DM_ODM_SUPPORT_TYPE == ODM_WIN) *pDM_Odm->pbFwDwRsvdPageInProgress = TRUE; #endif ODM_RT_TRACE(pDM_Odm, PHYDM_COMP_TXBF, ODM_DBG_LOUD, ("[%s] Start!\n", __func__)); Adapter->HalFunc.GetHalDefVarHandler(Adapter, HAL_DEF_TX_PAGE_BOUNDARY, (pu2Byte)&TxPageBndy); /*Set REG_CR bit 8. DMA beacon by SW.*/ u1bTmp = ODM_Read1Byte(pDM_Odm, REG_CR_8814A + 1); ODM_Write1Byte(pDM_Odm, REG_CR_8814A + 1, (u1bTmp | BIT0)); /*Set FWHW_TXQ_CTRL 0x422[6]=0 to tell Hw the packet is not a real beacon frame.*/ tmpReg422 = ODM_Read1Byte(pDM_Odm, REG_FWHW_TXQ_CTRL_8814A + 2); ODM_Write1Byte(pDM_Odm, REG_FWHW_TXQ_CTRL_8814A + 2, tmpReg422 & (~BIT6)); if (tmpReg422 & BIT6) { ODM_RT_TRACE(pDM_Odm, PHYDM_COMP_TXBF, ODM_DBG_LOUD, ("%s: There is an Adapter is sending beacon.\n", __func__)); bSendBeacon = TRUE; } /*0x204[11:0] Beacon Head for TXDMA*/ ODM_Write2Byte(pDM_Odm, REG_FIFOPAGE_CTRL_2_8814A, Head_Page); do { /*Clear beacon valid check bit.*/ BcnValidReg = ODM_Read1Byte(pDM_Odm, REG_FIFOPAGE_CTRL_2_8814A + 1); ODM_Write1Byte(pDM_Odm, REG_FIFOPAGE_CTRL_2_8814A + 1, (BcnValidReg | BIT7)); /*download NDPA rsvd page.*/ if (pBeamEntry->BeamformEntryCap & BEAMFORMER_CAP_VHT_SU) Beamforming_SendVHTNDPAPacket(pDM_Odm, pBeamEntry->MacAddr, pBeamEntry->AID, pBeamEntry->SoundBW, BEACON_QUEUE); else Beamforming_SendHTNDPAPacket(pDM_Odm, pBeamEntry->MacAddr, pBeamEntry->SoundBW, BEACON_QUEUE); /*check rsvd page download OK.*/ BcnValidReg = ODM_Read1Byte(pDM_Odm, REG_FIFOPAGE_CTRL_2_8814A + 1); count = 0; while (!(BcnValidReg & BIT7) && count < 20) { count++; ODM_delay_ms(10); BcnValidReg = ODM_Read1Byte(pDM_Odm, REG_FIFOPAGE_CTRL_2_8814A + 2); } DLBcnCount++; } while (!(BcnValidReg & BIT7) && DLBcnCount < 5); if (!(BcnValidReg & BIT7)) ODM_RT_TRACE(pDM_Odm, PHYDM_COMP_TXBF, ODM_DBG_LOUD, ("%s Download RSVD page failed!\n", __func__)); /*0x204[11:0] Beacon Head for TXDMA*/ ODM_Write2Byte(pDM_Odm, REG_FIFOPAGE_CTRL_2_8814A, TxPageBndy); /*To make sure that if there exists an adapter which would like to send beacon.*/ /*If exists, the origianl value of 0x422[6] will be 1, we should check this to*/ /*prevent from setting 0x422[6] to 0 after download reserved page, or it will cause */ /*the beacon cannot be sent by HW.*/ /*2010.06.23. Added by tynli.*/ if (bSendBeacon) ODM_Write1Byte(pDM_Odm, REG_FWHW_TXQ_CTRL_8814A + 2, tmpReg422); /*Do not enable HW DMA BCN or it will cause Pcie interface hang by timing issue. 2011.11.24. by tynli.*/ /*Clear CR[8] or beacon packet will not be send to TxBuf anymore.*/ u1bTmp = ODM_Read1Byte(pDM_Odm, REG_CR_8814A + 1); ODM_Write1Byte(pDM_Odm, REG_CR_8814A + 1, (u1bTmp & (~BIT0))); pBeamEntry->BeamformEntryState = BEAMFORMING_ENTRY_STATE_PROGRESSED; #if (DM_ODM_SUPPORT_TYPE == ODM_WIN) *pDM_Odm->pbFwDwRsvdPageInProgress = FALSE; #endif }
VOID HalTxbf8821B_Leave( IN PVOID pDM_VOID, IN u1Byte Idx ) { PDM_ODM_T pDM_Odm = (PDM_ODM_T)pDM_VOID; PRT_BEAMFORMING_INFO pBeamformingInfo = &pDM_Odm->BeamformingInfo; RT_BEAMFORMER_ENTRY BeamformerEntry; RT_BEAMFORMEE_ENTRY BeamformeeEntry; if (Idx < BEAMFORMER_ENTRY_NUM) { BeamformerEntry = pBeamformingInfo->BeamformerEntry[Idx]; BeamformeeEntry = pBeamformingInfo->BeamformeeEntry[Idx]; } else return; ODM_RT_TRACE(pDM_Odm, PHYDM_COMP_TXBF, ODM_DBG_LOUD, ("[%s]Start!, IDx = %d\n", __func__, Idx)); /*Clear P_AID of Beamformee*/ /*Clear MAC address of Beamformer*/ /*Clear Associated Bfmee Sel*/ if (BeamformerEntry.BeamformEntryCap == BEAMFORMING_CAP_NONE) { ODM_Write1Byte(pDM_Odm, REG_SND_PTCL_CTRL_8821B, 0xC8); if (Idx == 0) { ODM_Write4Byte(pDM_Odm, REG_BFMER0_INFO_8812A, 0); ODM_Write2Byte(pDM_Odm, REG_BFMER0_INFO_8812A + 4, 0); ODM_Write2Byte(pDM_Odm, REG_CSI_RPT_PARAM_BW20_8821B, 0); ODM_Write2Byte(pDM_Odm, REG_CSI_RPT_PARAM_BW40_8821B, 0); ODM_Write2Byte(pDM_Odm, REG_CSI_RPT_PARAM_BW80_8821B, 0); } else { ODM_Write4Byte(pDM_Odm, REG_BFMER1_INFO_8812A, 0); ODM_Write2Byte(pDM_Odm, REG_BFMER1_INFO_8812A + 4, 0); ODM_Write2Byte(pDM_Odm, REG_CSI_RPT_PARAM_BW20_8821B, 0); ODM_Write2Byte(pDM_Odm, REG_CSI_RPT_PARAM_BW40_8821B, 0); ODM_Write2Byte(pDM_Odm, REG_CSI_RPT_PARAM_BW80_8821B, 0); } } if (BeamformeeEntry.BeamformEntryCap == BEAMFORMING_CAP_NONE) { halTxbf8821B_RfMode(pDM_Odm, pBeamformingInfo); if (Idx == 0) { ODM_Write2Byte(pDM_Odm, REG_TXBF_CTRL_8821B, 0x0); ODM_Write2Byte(pDM_Odm, REG_BFMEE_SEL_8812A, 0); } else { ODM_Write2Byte(pDM_Odm, REG_TXBF_CTRL_8821B + 2, ODM_Read2Byte(pDM_Odm, REG_TXBF_CTRL_8821B + 2) & 0xF000); ODM_Write2Byte(pDM_Odm, REG_BFMEE_SEL_8812A + 2, ODM_Read2Byte(pDM_Odm, REG_BFMEE_SEL_8812A + 2) & 0x60); } } }
VOID HalTxbf8821B_Enter( IN PVOID pDM_VOID, IN u1Byte BFerBFeeIdx ) { PDM_ODM_T pDM_Odm = (PDM_ODM_T)pDM_VOID; u1Byte i = 0; u1Byte BFerIdx = (BFerBFeeIdx & 0xF0) >> 4; u1Byte BFeeIdx = (BFerBFeeIdx & 0xF); u4Byte CSI_Param; PRT_BEAMFORMING_INFO pBeamformingInfo = &pDM_Odm->BeamformingInfo; RT_BEAMFORMEE_ENTRY BeamformeeEntry; RT_BEAMFORMER_ENTRY BeamformerEntry; u2Byte STAid = 0; ODM_RT_TRACE(pDM_Odm, PHYDM_COMP_TXBF, ODM_DBG_LOUD, ("[%s]Start!\n", __func__)); halTxbf8821B_RfMode(pDM_Odm, pBeamformingInfo); if (pDM_Odm->RFType == ODM_2T2R) ODM_SetBBReg(pDM_Odm, ODM_REG_CSI_CONTENT_VALUE, bMaskDWord, 0x00000000); /*Nc =2*/ else ODM_SetBBReg(pDM_Odm, ODM_REG_CSI_CONTENT_VALUE, bMaskDWord, 0x01081008); /*Nc =1*/ if ((pBeamformingInfo->beamformer_su_cnt > 0) && (BFerIdx < BEAMFORMER_ENTRY_NUM)) { BeamformerEntry = pBeamformingInfo->BeamformerEntry[BFerIdx]; /*Sounding protocol control*/ ODM_Write1Byte(pDM_Odm, REG_SND_PTCL_CTRL_8821B, 0xCB); /*MAC address/Partial AID of Beamformer*/ if (BFerIdx == 0) { for (i = 0; i < 6 ; i++) ODM_Write1Byte(pDM_Odm, (REG_BFMER0_INFO_8812A + i), BeamformerEntry.MacAddr[i]); /*CSI report use legacy ofdm so don't need to fill P_AID. */ /*PlatformEFIOWrite2Byte(Adapter, REG_BFMER0_INFO_8821B+6, BeamformEntry.P_AID); */ } else { for (i = 0; i < 6 ; i++) ODM_Write1Byte(pDM_Odm, (REG_BFMER1_INFO_8812A + i), BeamformerEntry.MacAddr[i]); /*CSI report use legacy ofdm so don't need to fill P_AID.*/ /*PlatformEFIOWrite2Byte(Adapter, REG_BFMER1_INFO_8821B+6, BeamformEntry.P_AID);*/ } /*CSI report parameters of Beamformee*/ if (BeamformerEntry.BeamformEntryCap & BEAMFORMEE_CAP_VHT_SU) { if (pDM_Odm->RFType == ODM_2T2R) CSI_Param = 0x01090109; else CSI_Param = 0x01080108; } else { if (pDM_Odm->RFType == ODM_2T2R) CSI_Param = 0x03090309; else CSI_Param = 0x03080308; } ODM_Write4Byte(pDM_Odm, REG_CSI_RPT_PARAM_BW20_8821B, CSI_Param); ODM_Write4Byte(pDM_Odm, REG_CSI_RPT_PARAM_BW40_8821B, CSI_Param); ODM_Write4Byte(pDM_Odm, REG_CSI_RPT_PARAM_BW80_8821B, CSI_Param); /*Timeout value for MAC to leave NDP_RX_standby_state (60 us, Test chip) (80 us, MP chip)*/ ODM_Write1Byte(pDM_Odm, REG_SND_PTCL_CTRL_8821B + 3, 0x50); } if ((pBeamformingInfo->beamformee_su_cnt > 0) && (BFeeIdx < BEAMFORMEE_ENTRY_NUM)) { BeamformeeEntry = pBeamformingInfo->BeamformeeEntry[BFeeIdx]; if (phydm_actingDetermine(pDM_Odm, PhyDM_ACTING_AS_IBSS)) STAid = BeamformeeEntry.MacId; else STAid = BeamformeeEntry.P_AID; /*P_AID of Beamformee & enable NDPA transmission & enable NDPA interrupt*/ if (BFeeIdx == 0) { ODM_Write2Byte(pDM_Odm, REG_TXBF_CTRL_8821B, STAid); ODM_Write1Byte(pDM_Odm, REG_TXBF_CTRL_8821B + 3, ODM_Read1Byte(pDM_Odm, REG_TXBF_CTRL_8821B + 3) | BIT4 | BIT6 | BIT7); } else ODM_Write2Byte(pDM_Odm, REG_TXBF_CTRL_8821B + 2, STAid | BIT12 | BIT14 | BIT15); /*CSI report parameters of Beamformee*/ if (BFeeIdx == 0) { /*Get BIT24 & BIT25*/ u1Byte tmp = ODM_Read1Byte(pDM_Odm, REG_BFMEE_SEL_8812A + 3) & 0x3; ODM_Write1Byte(pDM_Odm, REG_BFMEE_SEL_8812A + 3, tmp | 0x60); ODM_Write2Byte(pDM_Odm, REG_BFMEE_SEL_8812A, STAid | BIT9); } else { /*Set BIT25*/ ODM_Write2Byte(pDM_Odm, REG_BFMEE_SEL_8812A + 2, STAid | 0xE200); } phydm_Beamforming_Notify(pDM_Odm); } }