net: wireless: rockchip_wlan: add rtl8188fu support
[firefly-linux-kernel-4.4.55.git] / drivers / net / wireless / rockchip_wlan / rtl8188fu / hal / phydm / txbf / haltxbfjaguar.c
diff --git a/drivers/net/wireless/rockchip_wlan/rtl8188fu/hal/phydm/txbf/haltxbfjaguar.c b/drivers/net/wireless/rockchip_wlan/rtl8188fu/hal/phydm/txbf/haltxbfjaguar.c
new file mode 100644 (file)
index 0000000..2f18aa9
--- /dev/null
@@ -0,0 +1,527 @@
+//============================================================\r
+// Description:\r
+//\r
+// This file is for 8812/8821/8811 TXBF mechanism\r
+//\r
+//============================================================\r
+#include "mp_precomp.h"\r
+#include "../phydm_precomp.h"\r
+\r
+#if (BEAMFORMING_SUPPORT == 1)\r
+#if ((RTL8812A_SUPPORT == 1) || (RTL8821A_SUPPORT == 1))\r
+VOID\r
+HalTxbf8812A_setNDPArate(\r
+       IN PVOID                        pDM_VOID,\r
+       IN u1Byte       BW,\r
+       IN u1Byte       Rate\r
+)\r
+{\r
+       PDM_ODM_T       pDM_Odm = (PDM_ODM_T)pDM_VOID;\r
+       \r
+       ODM_Write1Byte(pDM_Odm, REG_NDPA_OPT_CTRL_8812A,  (Rate << 2 | BW));    \r
+\r
+}\r
+\r
+VOID\r
+halTxbfJaguar_RfMode(\r
+       IN PVOID                        pDM_VOID,\r
+       IN PRT_BEAMFORMING_INFO pBeamInfo\r
+)\r
+{\r
+       PDM_ODM_T       pDM_Odm = (PDM_ODM_T)pDM_VOID;\r
+       \r
+       if (pDM_Odm->RFType == ODM_1T1R)\r
+               return;\r
+\r
+       ODM_RT_TRACE(pDM_Odm, PHYDM_COMP_TXBF, ODM_DBG_LOUD, ("[%s] set TxIQGen\n", __func__));\r
+\r
+       ODM_SetRFReg(pDM_Odm, ODM_RF_PATH_A, RF_WeLut_Jaguar, 0x80000, 0x1);    /*RF Mode table write enable*/\r
+       ODM_SetRFReg(pDM_Odm, ODM_RF_PATH_B, RF_WeLut_Jaguar, 0x80000, 0x1);    /*RF Mode table write enable*/\r
+\r
+       if (pBeamInfo->beamformee_su_cnt > 0) {\r
+               // Paath_A\r
+               ODM_SetRFReg(pDM_Odm, ODM_RF_PATH_A, RF_ModeTableAddr, 0x78000, 0x3);           /*Select RX mode*/\r
+               ODM_SetRFReg(pDM_Odm, ODM_RF_PATH_A, RF_ModeTableData0, 0xfffff, 0x3F7FF);      /*Set Table data*/\r
+               ODM_SetRFReg(pDM_Odm, ODM_RF_PATH_A, RF_ModeTableData1, 0xfffff, 0xE26BF);      /*Enable TXIQGEN in RX mode*/\r
+               // Path_B\r
+               ODM_SetRFReg(pDM_Odm, ODM_RF_PATH_B, RF_ModeTableAddr, 0x78000, 0x3);           /*Select RX mode*/\r
+               ODM_SetRFReg(pDM_Odm, ODM_RF_PATH_B, RF_ModeTableData0, 0xfffff, 0x3F7FF);      /*Set Table data*/\r
+               ODM_SetRFReg(pDM_Odm, ODM_RF_PATH_B, RF_ModeTableData1, 0xfffff, 0xE26BF);      /*Enable TXIQGEN in RX mode*/\r
+       } else {\r
+               // Paath_A\r
+               ODM_SetRFReg(pDM_Odm, ODM_RF_PATH_A, RF_ModeTableAddr, 0x78000, 0x3);           /*Select RX mode*/\r
+               ODM_SetRFReg(pDM_Odm, ODM_RF_PATH_A, RF_ModeTableData0, 0xfffff, 0x3F7FF);      /*Set Table data*/\r
+               ODM_SetRFReg(pDM_Odm, ODM_RF_PATH_A, RF_ModeTableData1, 0xfffff, 0xC26BF);      /*Disable TXIQGEN in RX mode*/\r
+               // Path_B\r
+               ODM_SetRFReg(pDM_Odm, ODM_RF_PATH_B, RF_ModeTableAddr, 0x78000, 0x3);           /*Select RX mode*/\r
+               ODM_SetRFReg(pDM_Odm, ODM_RF_PATH_B, RF_ModeTableData0, 0xfffff, 0x3F7FF);      /*Set Table data*/\r
+               ODM_SetRFReg(pDM_Odm, ODM_RF_PATH_B, RF_ModeTableData1, 0xfffff, 0xC26BF);      /*Disable TXIQGEN in RX mode*/\r
+       }\r
+\r
+       ODM_SetRFReg(pDM_Odm, ODM_RF_PATH_A, RF_WeLut_Jaguar, 0x80000, 0x0);    /*RF Mode table write disable*/\r
+       ODM_SetRFReg(pDM_Odm, ODM_RF_PATH_B, RF_WeLut_Jaguar, 0x80000, 0x0);    /*RF Mode table write disable*/\r
+\r
+       if (pBeamInfo->beamformee_su_cnt > 0)\r
+               ODM_SetBBReg(pDM_Odm, rTxPath_Jaguar, bMaskByte1, 0x33);\r
+       else\r
+               ODM_SetBBReg(pDM_Odm, rTxPath_Jaguar, bMaskByte1, 0x11);\r
+}\r
+\r
+\r
+VOID\r
+halTxbfJaguar_DownloadNDPA(\r
+       IN PVOID                        pDM_VOID,\r
+       IN      u1Byte                          Idx\r
+)\r
+{\r
+       PDM_ODM_T       pDM_Odm = (PDM_ODM_T)pDM_VOID;\r
+       u1Byte                  u1bTmp = 0, tmpReg422 = 0, Head_Page;\r
+       u1Byte                  BcnValidReg = 0, count = 0, DLBcnCount = 0;\r
+       BOOLEAN                 bSendBeacon = FALSE;\r
+       u1Byte                  TxPageBndy = LAST_ENTRY_OF_TX_PKT_BUFFER_8812;  /*default reseved 1 page for the IC type which is undefined.*/\r
+       PRT_BEAMFORMING_INFO    pBeamInfo = &pDM_Odm->BeamformingInfo;\r
+       PRT_BEAMFORMEE_ENTRY    pBeamEntry = pBeamInfo->BeamformeeEntry + Idx;\r
+       PADAPTER                Adapter = pDM_Odm->Adapter;\r
+#if (DM_ODM_SUPPORT_TYPE == ODM_WIN)\r
+       *pDM_Odm->pbFwDwRsvdPageInProgress = TRUE;\r
+#endif\r
+       ODM_RT_TRACE(pDM_Odm, PHYDM_COMP_TXBF, ODM_DBG_LOUD, ("[%s] Start!\n", __func__));\r
+\r
+       if (Idx == 0)\r
+               Head_Page = 0xFE;\r
+       else\r
+               Head_Page = 0xFE;\r
+\r
+       Adapter->HalFunc.GetHalDefVarHandler(Adapter, HAL_DEF_TX_PAGE_BOUNDARY, (pu1Byte)&TxPageBndy);\r
+\r
+       /*Set REG_CR bit 8. DMA beacon by SW.*/\r
+       u1bTmp = ODM_Read1Byte(pDM_Odm, REG_CR_8812A + 1);\r
+       ODM_Write1Byte(pDM_Odm,  REG_CR_8812A + 1, (u1bTmp | BIT0));\r
+\r
+\r
+       /*Set FWHW_TXQ_CTRL 0x422[6]=0 to tell Hw the packet is not a real beacon frame.*/\r
+       tmpReg422 = ODM_Read1Byte(pDM_Odm, REG_FWHW_TXQ_CTRL_8812A + 2);\r
+       ODM_Write1Byte(pDM_Odm, REG_FWHW_TXQ_CTRL_8812A + 2,  tmpReg422 & (~BIT6));\r
+\r
+       if (tmpReg422 & BIT6) {\r
+               ODM_RT_TRACE(pDM_Odm, PHYDM_COMP_TXBF, ODM_DBG_LOUD, ("SetBeamformDownloadNDPA_8812(): There is an Adapter is sending beacon.\n"));\r
+               bSendBeacon = TRUE;\r
+       }\r
+\r
+       /*TDECTRL[15:8] 0x209[7:0] = 0xF6       Beacon Head for TXDMA*/\r
+       ODM_Write1Byte(pDM_Odm, REG_TDECTRL_8812A + 1, Head_Page);\r
+\r
+       do {\r
+               /*Clear beacon valid check bit.*/\r
+               BcnValidReg = ODM_Read1Byte(pDM_Odm, REG_TDECTRL_8812A + 2);\r
+               ODM_Write1Byte(pDM_Odm, REG_TDECTRL_8812A + 2, (BcnValidReg | BIT0));\r
+\r
+               /*download NDPA rsvd page.*/\r
+               if (pBeamEntry->BeamformEntryCap & BEAMFORMER_CAP_VHT_SU)\r
+                       Beamforming_SendVHTNDPAPacket(pDM_Odm, pBeamEntry->MacAddr, pBeamEntry->AID, pBeamEntry->SoundBW, BEACON_QUEUE);\r
+               else\r
+                       Beamforming_SendHTNDPAPacket(pDM_Odm, pBeamEntry->MacAddr, pBeamEntry->SoundBW, BEACON_QUEUE);\r
+\r
+               /*check rsvd page download OK.*/\r
+               BcnValidReg = ODM_Read1Byte(pDM_Odm, REG_TDECTRL_8812A + 2);\r
+               count = 0;\r
+               while (!(BcnValidReg & BIT0) && count < 20) {\r
+                       count++;\r
+                       ODM_delay_ms(10);\r
+                       BcnValidReg = ODM_Read1Byte(pDM_Odm, REG_TDECTRL_8812A + 2);\r
+               }\r
+               DLBcnCount++;\r
+       } while (!(BcnValidReg & BIT0) && DLBcnCount < 5);\r
+\r
+       if (!(BcnValidReg & BIT0))\r
+               ODM_RT_TRACE(pDM_Odm, PHYDM_COMP_TXBF, ODM_DBG_LOUD, ("%s Download RSVD page failed!\n", __func__));\r
+\r
+       /*TDECTRL[15:8] 0x209[7:0] = 0xF6       Beacon Head for TXDMA*/\r
+       ODM_Write1Byte(pDM_Odm, REG_TDECTRL_8812A + 1, TxPageBndy);\r
+\r
+       /*To make sure that if there exists an adapter which would like to send beacon.*/\r
+       /*If exists, the origianl value of 0x422[6] will be 1, we should check this to*/\r
+       /*prevent from setting 0x422[6] to 0 after download reserved page, or it will cause*/\r
+       /*the beacon cannot be sent by HW.*/\r
+       /*2010.06.23. Added by tynli.*/\r
+       if (bSendBeacon)\r
+               ODM_Write1Byte(pDM_Odm, REG_FWHW_TXQ_CTRL_8812A + 2, tmpReg422);\r
+\r
+       /*Do not enable HW DMA BCN or it will cause Pcie interface hang by timing issue. 2011.11.24. by tynli.*/\r
+       /*Clear CR[8] or beacon packet will not be send to TxBuf anymore.*/\r
+       u1bTmp = ODM_Read1Byte(pDM_Odm, REG_CR_8812A + 1);\r
+       ODM_Write1Byte(pDM_Odm, REG_CR_8812A + 1, (u1bTmp & (~BIT0)));\r
+\r
+       pBeamEntry->BeamformEntryState = BEAMFORMING_ENTRY_STATE_PROGRESSED;\r
+#if (DM_ODM_SUPPORT_TYPE == ODM_WIN)\r
+       *pDM_Odm->pbFwDwRsvdPageInProgress = FALSE;\r
+#endif\r
+}\r
+\r
+\r
+VOID\r
+halTxbfJaguar_FwTxBFCmd(\r
+       IN PVOID                        pDM_VOID\r
+)\r
+{\r
+       PDM_ODM_T       pDM_Odm = (PDM_ODM_T)pDM_VOID;\r
+       u1Byte  Idx, Period0 = 0, Period1 = 0;\r
+       u1Byte  PageNum0 = 0xFF, PageNum1 = 0xFF;\r
+       u1Byte  u1TxBFParm[3] = {0};\r
+       PRT_BEAMFORMING_INFO    pBeamInfo = &pDM_Odm->BeamformingInfo;\r
+\r
+       for (Idx = 0; Idx < BEAMFORMEE_ENTRY_NUM; Idx++) {\r
+               /*Modified by David*/\r
+               if (pBeamInfo->BeamformeeEntry[Idx].bUsed && pBeamInfo->BeamformeeEntry[Idx].BeamformEntryState == BEAMFORMING_ENTRY_STATE_PROGRESSED) {\r
+                       if (Idx == 0) {\r
+                               if (pBeamInfo->BeamformeeEntry[Idx].bSound)\r
+                                       PageNum0 = 0xFE;\r
+                               else\r
+                                       PageNum0 = 0xFF; /*stop sounding*/\r
+                               Period0 = (u1Byte)(pBeamInfo->BeamformeeEntry[Idx].SoundPeriod);\r
+                       } else if (Idx == 1) {\r
+                               if (pBeamInfo->BeamformeeEntry[Idx].bSound)\r
+                                       PageNum1 = 0xFE;\r
+                               else\r
+                                       PageNum1 = 0xFF; /*stop sounding*/\r
+                               Period1 = (u1Byte)(pBeamInfo->BeamformeeEntry[Idx].SoundPeriod);\r
+                       }\r
+               }\r
+       }\r
+\r
+       u1TxBFParm[0] = PageNum0;\r
+       u1TxBFParm[1] = PageNum1;\r
+       u1TxBFParm[2] = (Period1 << 4) | Period0;\r
+       ODM_FillH2CCmd(pDM_Odm, PHYDM_H2C_TXBF, 3, u1TxBFParm);\r
+\r
+       ODM_RT_TRACE(pDM_Odm, PHYDM_COMP_TXBF, ODM_DBG_LOUD, \r
+               ("[%s] PageNum0 = %d Period0 = %d, PageNum1 = %d Period1 %d\n", __func__, PageNum0, Period0, PageNum1, Period1));\r
+}\r
+\r
+\r
+VOID\r
+HalTxbfJaguar_Enter(\r
+       IN PVOID                        pDM_VOID,\r
+       IN u1Byte                               BFerBFeeIdx\r
+)\r
+{\r
+       PDM_ODM_T       pDM_Odm = (PDM_ODM_T)pDM_VOID;\r
+       u1Byte                                  i = 0;\r
+       u1Byte                                  BFerIdx = (BFerBFeeIdx & 0xF0) >> 4;\r
+       u1Byte                                  BFeeIdx = (BFerBFeeIdx & 0xF);\r
+       u4Byte                                  CSI_Param;\r
+       PRT_BEAMFORMING_INFO    pBeamformingInfo = &pDM_Odm->BeamformingInfo;\r
+       RT_BEAMFORMEE_ENTRY     BeamformeeEntry;\r
+       RT_BEAMFORMER_ENTRY     BeamformerEntry;\r
+       u2Byte                                  STAid = 0;\r
+\r
+       ODM_RT_TRACE(pDM_Odm, PHYDM_COMP_TXBF, ODM_DBG_LOUD, ("[%s]Start!\n", __func__));\r
+\r
+       halTxbfJaguar_RfMode(pDM_Odm, pBeamformingInfo);\r
+\r
+       if (pDM_Odm->RFType == ODM_2T2R)\r
+               ODM_SetBBReg(pDM_Odm, ODM_REG_CSI_CONTENT_VALUE, bMaskDWord, 0x00000000);       /*Nc =2*/\r
+       else\r
+               ODM_SetBBReg(pDM_Odm, ODM_REG_CSI_CONTENT_VALUE, bMaskDWord, 0x01081008);       /*Nc =1*/\r
+\r
+       if ((pBeamformingInfo->beamformer_su_cnt > 0) && (BFerIdx < BEAMFORMER_ENTRY_NUM)) {\r
+               BeamformerEntry = pBeamformingInfo->BeamformerEntry[BFerIdx];\r
+\r
+               /*Sounding protocol control*/\r
+               ODM_Write1Byte(pDM_Odm, REG_SND_PTCL_CTRL_8812A, 0xCB);\r
+\r
+               /*MAC address/Partial AID of Beamformer*/\r
+               if (BFerIdx == 0) {\r
+                       for (i = 0; i < 6 ; i++)\r
+                               ODM_Write1Byte(pDM_Odm, (REG_BFMER0_INFO_8812A + i), BeamformerEntry.MacAddr[i]);\r
+                       /*CSI report use legacy ofdm so don't need to fill P_AID. */\r
+                       /*PlatformEFIOWrite2Byte(Adapter, REG_BFMER0_INFO_8812A+6, BeamformEntry.P_AID); */\r
+               } else {\r
+                       for (i = 0; i < 6 ; i++)\r
+                               ODM_Write1Byte(pDM_Odm, (REG_BFMER1_INFO_8812A + i), BeamformerEntry.MacAddr[i]);\r
+                       /*CSI report use legacy ofdm so don't need to fill P_AID.*/\r
+                       /*PlatformEFIOWrite2Byte(Adapter, REG_BFMER1_INFO_8812A+6, BeamformEntry.P_AID);*/\r
+               }\r
+\r
+               /*CSI report parameters of Beamformee*/\r
+               if (BeamformerEntry.BeamformEntryCap & BEAMFORMEE_CAP_VHT_SU) {\r
+                       if (pDM_Odm->RFType == ODM_2T2R)\r
+                               CSI_Param = 0x01090109;\r
+                       else\r
+                               CSI_Param = 0x01080108;\r
+               } else {\r
+                       if (pDM_Odm->RFType == ODM_2T2R)\r
+                               CSI_Param = 0x03090309;\r
+                       else\r
+                               CSI_Param = 0x03080308;\r
+               }\r
+\r
+               ODM_Write4Byte(pDM_Odm, REG_CSI_RPT_PARAM_BW20_8812A, CSI_Param);\r
+               ODM_Write4Byte(pDM_Odm, REG_CSI_RPT_PARAM_BW40_8812A, CSI_Param);\r
+               ODM_Write4Byte(pDM_Odm, REG_CSI_RPT_PARAM_BW80_8812A, CSI_Param);\r
+\r
+               /*Timeout value for MAC to leave NDP_RX_standby_state (60 us, Test chip) (80 us,  MP chip)*/\r
+               ODM_Write1Byte(pDM_Odm, REG_SND_PTCL_CTRL_8812A + 3, 0x50);\r
+       }\r
+\r
+\r
+       if ((pBeamformingInfo->beamformee_su_cnt > 0) && (BFeeIdx < BEAMFORMEE_ENTRY_NUM)) {\r
+               BeamformeeEntry = pBeamformingInfo->BeamformeeEntry[BFeeIdx];\r
+\r
+               if (phydm_actingDetermine(pDM_Odm, PhyDM_ACTING_AS_IBSS))\r
+                       STAid = BeamformeeEntry.MacId;\r
+               else\r
+                       STAid = BeamformeeEntry.P_AID;\r
+\r
+               /*P_AID of Beamformee & enable NDPA transmission & enable NDPA interrupt*/\r
+               if (BFeeIdx == 0) {\r
+                       ODM_Write2Byte(pDM_Odm, REG_TXBF_CTRL_8812A, STAid);\r
+                       ODM_Write1Byte(pDM_Odm, REG_TXBF_CTRL_8812A + 3, ODM_Read1Byte(pDM_Odm, REG_TXBF_CTRL_8812A + 3) | BIT4 | BIT6 | BIT7);\r
+               } else\r
+                       ODM_Write2Byte(pDM_Odm, REG_TXBF_CTRL_8812A + 2, STAid | BIT12 | BIT14 | BIT15);\r
+\r
+               /*CSI report parameters of Beamformee*/\r
+               if (BFeeIdx == 0) {\r
+                       /*Get BIT24 & BIT25*/\r
+                       u1Byte  tmp = ODM_Read1Byte(pDM_Odm, REG_BFMEE_SEL_8812A + 3) & 0x3;\r
+\r
+                       ODM_Write1Byte(pDM_Odm, REG_BFMEE_SEL_8812A + 3, tmp | 0x60);\r
+                       ODM_Write2Byte(pDM_Odm, REG_BFMEE_SEL_8812A, STAid | BIT9);\r
+               } else {\r
+                       /*Set BIT25*/\r
+                       ODM_Write2Byte(pDM_Odm, REG_BFMEE_SEL_8812A + 2, STAid | 0xE200);\r
+               }\r
+                       phydm_Beamforming_Notify(pDM_Odm);\r
+       }\r
+}\r
+\r
+\r
+VOID\r
+HalTxbfJaguar_Leave(\r
+       IN PVOID                        pDM_VOID,\r
+       IN u1Byte                               Idx\r
+)\r
+{\r
+       PDM_ODM_T       pDM_Odm = (PDM_ODM_T)pDM_VOID;\r
+       PRT_BEAMFORMING_INFO    pBeamformingInfo = &pDM_Odm->BeamformingInfo;\r
+       RT_BEAMFORMER_ENTRY     BeamformerEntry;\r
+       RT_BEAMFORMEE_ENTRY     BeamformeeEntry;\r
+       \r
+       if (Idx < BEAMFORMER_ENTRY_NUM) {\r
+               BeamformerEntry = pBeamformingInfo->BeamformerEntry[Idx];\r
+               BeamformeeEntry = pBeamformingInfo->BeamformeeEntry[Idx];\r
+       } else\r
+               return;\r
+\r
+       ODM_RT_TRACE(pDM_Odm, PHYDM_COMP_TXBF, ODM_DBG_LOUD, ("[%s]Start!, IDx = %d\n", __func__, Idx));\r
+\r
+       /*Clear P_AID of Beamformee*/\r
+       /*Clear MAC address of Beamformer*/\r
+       /*Clear Associated Bfmee Sel*/\r
+       \r
+       if (BeamformerEntry.BeamformEntryCap == BEAMFORMING_CAP_NONE) {\r
+               ODM_Write1Byte(pDM_Odm, REG_SND_PTCL_CTRL_8812A, 0xC8);\r
+               if (Idx == 0) {\r
+                       ODM_Write4Byte(pDM_Odm, REG_BFMER0_INFO_8812A, 0);\r
+                       ODM_Write2Byte(pDM_Odm, REG_BFMER0_INFO_8812A + 4, 0);\r
+                       ODM_Write2Byte(pDM_Odm, REG_CSI_RPT_PARAM_BW20_8812A, 0);\r
+                       ODM_Write2Byte(pDM_Odm, REG_CSI_RPT_PARAM_BW40_8812A, 0);\r
+                       ODM_Write2Byte(pDM_Odm, REG_CSI_RPT_PARAM_BW80_8812A, 0);\r
+               } else {\r
+                       ODM_Write4Byte(pDM_Odm, REG_BFMER1_INFO_8812A, 0);\r
+                       ODM_Write2Byte(pDM_Odm, REG_BFMER1_INFO_8812A + 4, 0);\r
+                       ODM_Write2Byte(pDM_Odm, REG_CSI_RPT_PARAM_BW20_8812A, 0);\r
+                       ODM_Write2Byte(pDM_Odm, REG_CSI_RPT_PARAM_BW40_8812A, 0);\r
+                       ODM_Write2Byte(pDM_Odm, REG_CSI_RPT_PARAM_BW80_8812A, 0);\r
+               }\r
+       }\r
+\r
+       if (BeamformeeEntry.BeamformEntryCap == BEAMFORMING_CAP_NONE) {\r
+               halTxbfJaguar_RfMode(pDM_Odm, pBeamformingInfo);\r
+               if (Idx == 0) {\r
+                       ODM_Write2Byte(pDM_Odm, REG_TXBF_CTRL_8812A, 0x0);\r
+                       ODM_Write2Byte(pDM_Odm, REG_BFMEE_SEL_8812A, 0);\r
+               } else {\r
+                       ODM_Write2Byte(pDM_Odm, REG_TXBF_CTRL_8812A + 2, ODM_Read2Byte(pDM_Odm, REG_TXBF_CTRL_8812A + 2) & 0xF000);\r
+                       ODM_Write2Byte(pDM_Odm, REG_BFMEE_SEL_8812A + 2, ODM_Read2Byte(pDM_Odm, REG_BFMEE_SEL_8812A + 2) & 0x60);\r
+               }\r
+       }\r
+       \r
+}\r
+\r
+\r
+VOID\r
+HalTxbfJaguar_Status(\r
+       IN PVOID                        pDM_VOID,\r
+       IN u1Byte                               Idx\r
+)\r
+{\r
+       PDM_ODM_T       pDM_Odm = (PDM_ODM_T)pDM_VOID;\r
+       u2Byte                                  BeamCtrlVal;\r
+       u4Byte                                  BeamCtrlReg;\r
+       PRT_BEAMFORMING_INFO    pBeamInfo = &pDM_Odm->BeamformingInfo;\r
+       RT_BEAMFORMEE_ENTRY     BeamformEntry = pBeamInfo->BeamformeeEntry[Idx];\r
+\r
+       if (phydm_actingDetermine(pDM_Odm, PhyDM_ACTING_AS_IBSS))\r
+               BeamCtrlVal = BeamformEntry.MacId;\r
+       else\r
+               BeamCtrlVal = BeamformEntry.P_AID;\r
+\r
+       if (Idx == 0)\r
+               BeamCtrlReg = REG_TXBF_CTRL_8812A;\r
+       else {\r
+               BeamCtrlReg = REG_TXBF_CTRL_8812A + 2;\r
+               BeamCtrlVal |= BIT12 | BIT14 | BIT15;\r
+       }\r
+\r
+       if (BeamformEntry.BeamformEntryState == BEAMFORMING_ENTRY_STATE_PROGRESSED) {\r
+               if (BeamformEntry.SoundBW == CHANNEL_WIDTH_20)\r
+                       BeamCtrlVal |= BIT9;\r
+               else if (BeamformEntry.SoundBW == CHANNEL_WIDTH_40)\r
+                       BeamCtrlVal |= (BIT9 | BIT10);\r
+               else if (BeamformEntry.SoundBW == CHANNEL_WIDTH_80)\r
+                       BeamCtrlVal |= (BIT9 | BIT10 | BIT11);\r
+       } else\r
+               BeamCtrlVal &= ~(BIT9 | BIT10 | BIT11);\r
+\r
+       ODM_RT_TRACE(pDM_Odm, PHYDM_COMP_TXBF, ODM_DBG_LOUD, ("[%s] BeamCtrlVal = 0x%x!\n", __func__, BeamCtrlVal));\r
+\r
+       ODM_Write2Byte(pDM_Odm, BeamCtrlReg, BeamCtrlVal);\r
+}\r
+\r
+\r
+\r
+VOID\r
+HalTxbfJaguar_FwTxBF(\r
+       IN PVOID                        pDM_VOID,\r
+       IN      u1Byte                          Idx\r
+)\r
+{\r
+       PDM_ODM_T       pDM_Odm = (PDM_ODM_T)pDM_VOID;\r
+       PRT_BEAMFORMING_INFO    pBeamInfo = &pDM_Odm->BeamformingInfo;\r
+       PRT_BEAMFORMEE_ENTRY    pBeamEntry = pBeamInfo->BeamformeeEntry + Idx;\r
+\r
+       ODM_RT_TRACE(pDM_Odm, PHYDM_COMP_TXBF, ODM_DBG_LOUD, ("[%s] Start!\n", __func__));\r
+\r
+       if (pBeamEntry->BeamformEntryState == BEAMFORMING_ENTRY_STATE_PROGRESSING)\r
+               halTxbfJaguar_DownloadNDPA(pDM_Odm, Idx);\r
+\r
+       halTxbfJaguar_FwTxBFCmd(pDM_Odm);\r
+}\r
+\r
+\r
+VOID\r
+HalTxbfJaguar_Patch(\r
+       IN PVOID                        pDM_VOID,\r
+       IN      u1Byte                          Operation\r
+)\r
+{\r
+       PDM_ODM_T       pDM_Odm = (PDM_ODM_T)pDM_VOID;\r
+       PRT_BEAMFORMING_INFO    pBeamInfo = &pDM_Odm->BeamformingInfo;\r
+\r
+       ODM_RT_TRACE(pDM_Odm, PHYDM_COMP_TXBF, ODM_DBG_LOUD, ("[%s] Start!\n", __func__));\r
+\r
+       if (pBeamInfo->BeamformCap == BEAMFORMING_CAP_NONE)\r
+               return;\r
+#if (DM_ODM_SUPPORT_TYPE == ODM_WIN)\r
+       if (Operation == SCAN_OPT_BACKUP_BAND0)\r
+               ODM_Write1Byte(pDM_Odm, REG_SND_PTCL_CTRL_8812A, 0xC8);\r
+       else if (Operation == SCAN_OPT_RESTORE)\r
+               ODM_Write1Byte(pDM_Odm, REG_SND_PTCL_CTRL_8812A, 0xCB);\r
+#endif\r
+}\r
+\r
+VOID\r
+HalTxbfJaguar_Clk_8812A(\r
+       IN PVOID                        pDM_VOID\r
+)\r
+{\r
+       PDM_ODM_T       pDM_Odm = (PDM_ODM_T)pDM_VOID;\r
+       u2Byte  u2btmp;\r
+       u1Byte  Count = 0, u1btmp;\r
+       PADAPTER        Adapter = pDM_Odm->Adapter;\r
+       \r
+       ODM_RT_TRACE(pDM_Odm, PHYDM_COMP_TXBF, ODM_DBG_LOUD, ("[%s] Start!\n", __func__));\r
+\r
+       if (*(pDM_Odm->pbScanInProcess)) {\r
+               ODM_RT_TRACE(pDM_Odm, PHYDM_COMP_TXBF, ODM_DBG_LOUD, ("[%s] return by Scan\n", __func__));\r
+               return;\r
+       }\r
+#if DEV_BUS_TYPE == RT_PCI_INTERFACE   \r
+       /*Stop PCIe TxDMA*/\r
+       ODM_Write1Byte(pDM_Odm, REG_PCIE_CTRL_REG_8812A + 1, 0xFE);\r
+#endif\r
+\r
+       /*Stop Usb TxDMA*/\r
+#if (DM_ODM_SUPPORT_TYPE == ODM_WIN)\r
+       RT_DISABLE_FUNC(Adapter, DF_TX_BIT);\r
+       PlatformReturnAllPendingTxPackets(Adapter);\r
+#else\r
+       rtw_write_port_cancel(Adapter);\r
+#endif\r
+\r
+       /*Wait TXFF empty*/\r
+       for (Count = 0; Count < 100; Count++) {\r
+               u2btmp = ODM_Read2Byte(pDM_Odm, REG_TXPKT_EMPTY_8812A);\r
+               u2btmp = u2btmp & 0xfff;\r
+               if (u2btmp != 0xfff) {\r
+                       ODM_delay_ms(10);\r
+                       continue;\r
+               } else\r
+                       break;\r
+       }\r
+\r
+       /*TX pause*/\r
+       ODM_Write1Byte(pDM_Odm, REG_TXPAUSE_8812A, 0xFF);\r
+\r
+       /*Wait TX State Machine OK*/\r
+       for (Count = 0; Count < 100; Count++) {\r
+               if (ODM_Read4Byte(pDM_Odm, REG_SCH_TXCMD_8812A) != 0)\r
+                       continue;\r
+               else\r
+                       break;\r
+       }\r
+\r
+\r
+       /*Stop RX DMA path*/\r
+       u1btmp = ODM_Read1Byte(pDM_Odm, REG_RXDMA_CONTROL_8812A);\r
+       ODM_Write1Byte(pDM_Odm, REG_RXDMA_CONTROL_8812A, u1btmp | BIT2);\r
+\r
+       for (Count = 0; Count < 100; Count++) {\r
+               u1btmp = ODM_Read1Byte(pDM_Odm, REG_RXDMA_CONTROL_8812A);\r
+               if (u1btmp & BIT1)\r
+                       break;\r
+               else\r
+                       ODM_delay_ms(10);\r
+       }\r
+\r
+       /*Disable clock*/\r
+       ODM_Write1Byte(pDM_Odm, REG_SYS_CLKR_8812A + 1, 0xf0);\r
+       /*Disable 320M*/\r
+       ODM_Write1Byte(pDM_Odm, REG_AFE_PLL_CTRL_8812A + 3, 0x8);\r
+       /*Enable 320M*/\r
+       ODM_Write1Byte(pDM_Odm, REG_AFE_PLL_CTRL_8812A + 3, 0xa);\r
+       /*Enable clock*/\r
+       ODM_Write1Byte(pDM_Odm, REG_SYS_CLKR_8812A + 1, 0xfc);\r
+\r
+\r
+       /*Release Tx pause*/\r
+       ODM_Write1Byte(pDM_Odm, REG_TXPAUSE_8812A, 0);\r
+\r
+       /*Enable RX DMA path*/\r
+       u1btmp = ODM_Read1Byte(pDM_Odm, REG_RXDMA_CONTROL_8812A);\r
+       ODM_Write1Byte(pDM_Odm, REG_RXDMA_CONTROL_8812A, u1btmp & (~BIT2));\r
+#if DEV_BUS_TYPE == RT_PCI_INTERFACE\r
+       /*Enable PCIe TxDMA*/\r
+       ODM_Write1Byte(pDM_Odm, REG_PCIE_CTRL_REG_8812A + 1, 0);\r
+#endif\r
+       /*Start Usb TxDMA*/\r
+       RT_ENABLE_FUNC(Adapter, DF_TX_BIT);\r
+}\r
+\r
+#endif\r
+\r
+\r
+\r
+#endif\r
+\r