net: wireless: rockchip_wlan: add rtl8723cs support
[firefly-linux-kernel-4.4.55.git] / drivers / net / wireless / rockchip_wlan / rtl8723cs / hal / phydm / txbf / haltxbfjaguar.c
1 /* ************************************************************
2  * Description:
3  *
4  * This file is for 8812/8821/8811 TXBF mechanism
5  *
6  * ************************************************************ */
7 #include "mp_precomp.h"
8 #include "../phydm_precomp.h"
9
10 #if (BEAMFORMING_SUPPORT == 1)
11 #if ((RTL8812A_SUPPORT == 1) || (RTL8821A_SUPPORT == 1))
12 void
13 hal_txbf_8812a_set_ndpa_rate(
14         void                    *p_dm_void,
15         u8      BW,
16         u8      rate
17 )
18 {
19         struct PHY_DM_STRUCT    *p_dm_odm = (struct PHY_DM_STRUCT *)p_dm_void;
20
21         odm_write_1byte(p_dm_odm, REG_NDPA_OPT_CTRL_8812A, (rate << 2 | BW));
22
23 }
24
25 void
26 hal_txbf_jaguar_rf_mode(
27         void                    *p_dm_void,
28         struct _RT_BEAMFORMING_INFO     *p_beam_info
29 )
30 {
31         struct PHY_DM_STRUCT    *p_dm_odm = (struct PHY_DM_STRUCT *)p_dm_void;
32
33         if (p_dm_odm->rf_type == ODM_1T1R)
34                 return;
35
36         ODM_RT_TRACE(p_dm_odm, PHYDM_COMP_TXBF, ODM_DBG_LOUD, ("[%s] set TxIQGen\n", __func__));
37
38         odm_set_rf_reg(p_dm_odm, ODM_RF_PATH_A, 0xef, 0x80000, 0x1);    /*RF mode table write enable*/
39         odm_set_rf_reg(p_dm_odm, ODM_RF_PATH_B, 0xef, 0x80000, 0x1);    /*RF mode table write enable*/
40
41         if (p_beam_info->beamformee_su_cnt > 0) {
42                 /* Paath_A */
43                 odm_set_rf_reg(p_dm_odm, ODM_RF_PATH_A, 0x30, 0x78000, 0x3);            /*Select RX mode*/
44                 odm_set_rf_reg(p_dm_odm, ODM_RF_PATH_A, 0x31, 0xfffff, 0x3F7FF);        /*Set Table data*/
45                 odm_set_rf_reg(p_dm_odm, ODM_RF_PATH_A, 0x32, 0xfffff, 0xE26BF);        /*Enable TXIQGEN in RX mode*/
46                 /* Path_B */
47                 odm_set_rf_reg(p_dm_odm, ODM_RF_PATH_B, 0x30, 0x78000, 0x3);            /*Select RX mode*/
48                 odm_set_rf_reg(p_dm_odm, ODM_RF_PATH_B, 0x31, 0xfffff, 0x3F7FF);        /*Set Table data*/
49                 odm_set_rf_reg(p_dm_odm, ODM_RF_PATH_B, 0x32, 0xfffff, 0xE26BF);        /*Enable TXIQGEN in RX mode*/
50         } else {
51                 /* Paath_A */
52                 odm_set_rf_reg(p_dm_odm, ODM_RF_PATH_A, 0x30, 0x78000, 0x3);            /*Select RX mode*/
53                 odm_set_rf_reg(p_dm_odm, ODM_RF_PATH_A, 0x31, 0xfffff, 0x3F7FF);        /*Set Table data*/
54                 odm_set_rf_reg(p_dm_odm, ODM_RF_PATH_A, 0x32, 0xfffff, 0xC26BF);        /*Disable TXIQGEN in RX mode*/
55                 /* Path_B */
56                 odm_set_rf_reg(p_dm_odm, ODM_RF_PATH_B, 0x30, 0x78000, 0x3);            /*Select RX mode*/
57                 odm_set_rf_reg(p_dm_odm, ODM_RF_PATH_B, 0x31, 0xfffff, 0x3F7FF);        /*Set Table data*/
58                 odm_set_rf_reg(p_dm_odm, ODM_RF_PATH_B, 0x32, 0xfffff, 0xC26BF);        /*Disable TXIQGEN in RX mode*/
59         }
60
61         odm_set_rf_reg(p_dm_odm, ODM_RF_PATH_A, 0xef, 0x80000, 0x0);    /*RF mode table write disable*/
62         odm_set_rf_reg(p_dm_odm, ODM_RF_PATH_B, 0xef, 0x80000, 0x0);    /*RF mode table write disable*/
63
64         if (p_beam_info->beamformee_su_cnt > 0)
65                 odm_set_bb_reg(p_dm_odm, 0x80c, MASKBYTE1, 0x33);
66         else
67                 odm_set_bb_reg(p_dm_odm, 0x80c, MASKBYTE1, 0x11);
68 }
69
70
71 void
72 hal_txbf_jaguar_download_ndpa(
73         void                    *p_dm_void,
74         u8                              idx
75 )
76 {
77         struct PHY_DM_STRUCT    *p_dm_odm = (struct PHY_DM_STRUCT *)p_dm_void;
78         u8                      u1b_tmp = 0, tmp_reg422 = 0, head_page;
79         u8                      bcn_valid_reg = 0, count = 0, dl_bcn_count = 0;
80         boolean                 is_send_beacon = false;
81         u8                      tx_page_bndy = LAST_ENTRY_OF_TX_PKT_BUFFER_8812;        /*default reseved 1 page for the IC type which is undefined.*/
82         struct _RT_BEAMFORMING_INFO     *p_beam_info = &p_dm_odm->beamforming_info;
83         struct _RT_BEAMFORMEE_ENTRY     *p_beam_entry = p_beam_info->beamformee_entry + idx;
84         struct _ADAPTER         *adapter = p_dm_odm->adapter;
85 #if (DM_ODM_SUPPORT_TYPE == ODM_WIN)
86         *p_dm_odm->p_is_fw_dw_rsvd_page_in_progress = true;
87 #endif
88         ODM_RT_TRACE(p_dm_odm, PHYDM_COMP_TXBF, ODM_DBG_LOUD, ("[%s] Start!\n", __func__));
89
90         if (idx == 0)
91                 head_page = 0xFE;
92         else
93                 head_page = 0xFE;
94
95         phydm_get_hal_def_var_handler_interface(p_dm_odm, HAL_DEF_TX_PAGE_BOUNDARY, (u8 *)&tx_page_bndy);
96
97         /*Set REG_CR bit 8. DMA beacon by SW.*/
98         u1b_tmp = odm_read_1byte(p_dm_odm, REG_CR_8812A + 1);
99         odm_write_1byte(p_dm_odm,  REG_CR_8812A + 1, (u1b_tmp | BIT(0)));
100
101
102         /*Set FWHW_TXQ_CTRL 0x422[6]=0 to tell Hw the packet is not a real beacon frame.*/
103         tmp_reg422 = odm_read_1byte(p_dm_odm, REG_FWHW_TXQ_CTRL_8812A + 2);
104         odm_write_1byte(p_dm_odm, REG_FWHW_TXQ_CTRL_8812A + 2,  tmp_reg422 & (~BIT(6)));
105
106         if (tmp_reg422 & BIT(6)) {
107                 ODM_RT_TRACE(p_dm_odm, PHYDM_COMP_TXBF, ODM_DBG_LOUD, ("SetBeamformDownloadNDPA_8812(): There is an adapter is sending beacon.\n"));
108                 is_send_beacon = true;
109         }
110
111         /*TDECTRL[15:8] 0x209[7:0] = 0xF6       Beacon Head for TXDMA*/
112         odm_write_1byte(p_dm_odm, REG_TDECTRL_8812A + 1, head_page);
113
114         do {
115                 /*Clear beacon valid check bit.*/
116                 bcn_valid_reg = odm_read_1byte(p_dm_odm, REG_TDECTRL_8812A + 2);
117                 odm_write_1byte(p_dm_odm, REG_TDECTRL_8812A + 2, (bcn_valid_reg | BIT(0)));
118
119                 /*download NDPA rsvd page.*/
120                 if (p_beam_entry->beamform_entry_cap & BEAMFORMER_CAP_VHT_SU)
121                         beamforming_send_vht_ndpa_packet(p_dm_odm, p_beam_entry->mac_addr, p_beam_entry->aid, p_beam_entry->sound_bw, BEACON_QUEUE);
122                 else
123                         beamforming_send_ht_ndpa_packet(p_dm_odm, p_beam_entry->mac_addr, p_beam_entry->sound_bw, BEACON_QUEUE);
124
125                 /*check rsvd page download OK.*/
126                 bcn_valid_reg = odm_read_1byte(p_dm_odm, REG_TDECTRL_8812A + 2);
127                 count = 0;
128                 while (!(bcn_valid_reg & BIT(0)) && count < 20) {
129                         count++;
130                         ODM_delay_ms(10);
131                         bcn_valid_reg = odm_read_1byte(p_dm_odm, REG_TDECTRL_8812A + 2);
132                 }
133                 dl_bcn_count++;
134         } while (!(bcn_valid_reg & BIT(0)) && dl_bcn_count < 5);
135
136         if (!(bcn_valid_reg & BIT(0)))
137                 ODM_RT_TRACE(p_dm_odm, PHYDM_COMP_TXBF, ODM_DBG_LOUD, ("%s Download RSVD page failed!\n", __func__));
138
139         /*TDECTRL[15:8] 0x209[7:0] = 0xF6       Beacon Head for TXDMA*/
140         odm_write_1byte(p_dm_odm, REG_TDECTRL_8812A + 1, tx_page_bndy);
141
142         /*To make sure that if there exists an adapter which would like to send beacon.*/
143         /*If exists, the origianl value of 0x422[6] will be 1, we should check this to*/
144         /*prevent from setting 0x422[6] to 0 after download reserved page, or it will cause*/
145         /*the beacon cannot be sent by HW.*/
146         /*2010.06.23. Added by tynli.*/
147         if (is_send_beacon)
148                 odm_write_1byte(p_dm_odm, REG_FWHW_TXQ_CTRL_8812A + 2, tmp_reg422);
149
150         /*Do not enable HW DMA BCN or it will cause Pcie interface hang by timing issue. 2011.11.24. by tynli.*/
151         /*Clear CR[8] or beacon packet will not be send to TxBuf anymore.*/
152         u1b_tmp = odm_read_1byte(p_dm_odm, REG_CR_8812A + 1);
153         odm_write_1byte(p_dm_odm, REG_CR_8812A + 1, (u1b_tmp & (~BIT(0))));
154
155         p_beam_entry->beamform_entry_state = BEAMFORMING_ENTRY_STATE_PROGRESSED;
156 #if (DM_ODM_SUPPORT_TYPE == ODM_WIN)
157         *p_dm_odm->p_is_fw_dw_rsvd_page_in_progress = false;
158 #endif
159 }
160
161
162 void
163 hal_txbf_jaguar_fw_txbf_cmd(
164         void                    *p_dm_void
165 )
166 {
167         struct PHY_DM_STRUCT    *p_dm_odm = (struct PHY_DM_STRUCT *)p_dm_void;
168         u8      idx, period0 = 0, period1 = 0;
169         u8      PageNum0 = 0xFF, PageNum1 = 0xFF;
170         u8      u1_tx_bf_parm[3] = {0};
171         struct _RT_BEAMFORMING_INFO     *p_beam_info = &p_dm_odm->beamforming_info;
172
173         for (idx = 0; idx < BEAMFORMEE_ENTRY_NUM; idx++) {
174                 /*Modified by David*/
175                 if (p_beam_info->beamformee_entry[idx].is_used && p_beam_info->beamformee_entry[idx].beamform_entry_state == BEAMFORMING_ENTRY_STATE_PROGRESSED) {
176                         if (idx == 0) {
177                                 if (p_beam_info->beamformee_entry[idx].is_sound)
178                                         PageNum0 = 0xFE;
179                                 else
180                                         PageNum0 = 0xFF; /*stop sounding*/
181                                 period0 = (u8)(p_beam_info->beamformee_entry[idx].sound_period);
182                         } else if (idx == 1) {
183                                 if (p_beam_info->beamformee_entry[idx].is_sound)
184                                         PageNum1 = 0xFE;
185                                 else
186                                         PageNum1 = 0xFF; /*stop sounding*/
187                                 period1 = (u8)(p_beam_info->beamformee_entry[idx].sound_period);
188                         }
189                 }
190         }
191
192         u1_tx_bf_parm[0] = PageNum0;
193         u1_tx_bf_parm[1] = PageNum1;
194         u1_tx_bf_parm[2] = (period1 << 4) | period0;
195         odm_fill_h2c_cmd(p_dm_odm, PHYDM_H2C_TXBF, 3, u1_tx_bf_parm);
196
197         ODM_RT_TRACE(p_dm_odm, PHYDM_COMP_TXBF, ODM_DBG_LOUD,
198                 ("[%s] PageNum0 = %d period0 = %d, PageNum1 = %d period1 %d\n", __func__, PageNum0, period0, PageNum1, period1));
199 }
200
201
202 void
203 hal_txbf_jaguar_enter(
204         void                    *p_dm_void,
205         u8                              bfer_bfee_idx
206 )
207 {
208         struct PHY_DM_STRUCT    *p_dm_odm = (struct PHY_DM_STRUCT *)p_dm_void;
209         u8                                      i = 0;
210         u8                                      bfer_idx = (bfer_bfee_idx & 0xF0) >> 4;
211         u8                                      bfee_idx = (bfer_bfee_idx & 0xF);
212         u32                                     csi_param;
213         struct _RT_BEAMFORMING_INFO     *p_beamforming_info = &p_dm_odm->beamforming_info;
214         struct _RT_BEAMFORMEE_ENTRY     beamformee_entry;
215         struct _RT_BEAMFORMER_ENTRY     beamformer_entry;
216         u16                                     sta_id = 0;
217
218         ODM_RT_TRACE(p_dm_odm, PHYDM_COMP_TXBF, ODM_DBG_LOUD, ("[%s]Start!\n", __func__));
219
220         hal_txbf_jaguar_rf_mode(p_dm_odm, p_beamforming_info);
221
222         if (p_dm_odm->rf_type == ODM_2T2R)
223                 odm_set_bb_reg(p_dm_odm, ODM_REG_CSI_CONTENT_VALUE, MASKDWORD, 0x00000000);     /*nc =2*/
224         else
225                 odm_set_bb_reg(p_dm_odm, ODM_REG_CSI_CONTENT_VALUE, MASKDWORD, 0x01081008);     /*nc =1*/
226
227         if ((p_beamforming_info->beamformer_su_cnt > 0) && (bfer_idx < BEAMFORMER_ENTRY_NUM)) {
228                 beamformer_entry = p_beamforming_info->beamformer_entry[bfer_idx];
229
230                 /*Sounding protocol control*/
231                 odm_write_1byte(p_dm_odm, REG_SND_PTCL_CTRL_8812A, 0xCB);
232
233                 /*MAC address/Partial AID of Beamformer*/
234                 if (bfer_idx == 0) {
235                         for (i = 0; i < 6 ; i++)
236                                 odm_write_1byte(p_dm_odm, (REG_BFMER0_INFO_8812A + i), beamformer_entry.mac_addr[i]);
237                         /*CSI report use legacy ofdm so don't need to fill P_AID. */
238                         /*platform_efio_write_2byte(adapter, REG_BFMER0_INFO_8812A+6, beamform_entry.P_AID); */
239                 } else {
240                         for (i = 0; i < 6 ; i++)
241                                 odm_write_1byte(p_dm_odm, (REG_BFMER1_INFO_8812A + i), beamformer_entry.mac_addr[i]);
242                         /*CSI report use legacy ofdm so don't need to fill P_AID.*/
243                         /*platform_efio_write_2byte(adapter, REG_BFMER1_INFO_8812A+6, beamform_entry.P_AID);*/
244                 }
245
246                 /*CSI report parameters of Beamformee*/
247                 if (beamformer_entry.beamform_entry_cap & BEAMFORMEE_CAP_VHT_SU) {
248                         if (p_dm_odm->rf_type == ODM_2T2R)
249                                 csi_param = 0x01090109;
250                         else
251                                 csi_param = 0x01080108;
252                 } else {
253                         if (p_dm_odm->rf_type == ODM_2T2R)
254                                 csi_param = 0x03090309;
255                         else
256                                 csi_param = 0x03080308;
257                 }
258
259                 odm_write_4byte(p_dm_odm, REG_CSI_RPT_PARAM_BW20_8812A, csi_param);
260                 odm_write_4byte(p_dm_odm, REG_CSI_RPT_PARAM_BW40_8812A, csi_param);
261                 odm_write_4byte(p_dm_odm, REG_CSI_RPT_PARAM_BW80_8812A, csi_param);
262
263                 /*Timeout value for MAC to leave NDP_RX_standby_state (60 us, Test chip) (80 us,  MP chip)*/
264                 odm_write_1byte(p_dm_odm, REG_SND_PTCL_CTRL_8812A + 3, 0x50);
265         }
266
267
268         if ((p_beamforming_info->beamformee_su_cnt > 0) && (bfee_idx < BEAMFORMEE_ENTRY_NUM)) {
269                 beamformee_entry = p_beamforming_info->beamformee_entry[bfee_idx];
270
271                 if (phydm_acting_determine(p_dm_odm, phydm_acting_as_ibss))
272                         sta_id = beamformee_entry.mac_id;
273                 else
274                         sta_id = beamformee_entry.p_aid;
275
276                 /*P_AID of Beamformee & enable NDPA transmission & enable NDPA interrupt*/
277                 if (bfee_idx == 0) {
278                         odm_write_2byte(p_dm_odm, REG_TXBF_CTRL_8812A, sta_id);
279                         odm_write_1byte(p_dm_odm, REG_TXBF_CTRL_8812A + 3, odm_read_1byte(p_dm_odm, REG_TXBF_CTRL_8812A + 3) | BIT(4) | BIT(6) | BIT(7));
280                 } else
281                         odm_write_2byte(p_dm_odm, REG_TXBF_CTRL_8812A + 2, sta_id | BIT(12) | BIT(14) | BIT(15));
282
283                 /*CSI report parameters of Beamformee*/
284                 if (bfee_idx == 0) {
285                         /*Get BIT24 & BIT25*/
286                         u8      tmp = odm_read_1byte(p_dm_odm, REG_BFMEE_SEL_8812A + 3) & 0x3;
287
288                         odm_write_1byte(p_dm_odm, REG_BFMEE_SEL_8812A + 3, tmp | 0x60);
289                         odm_write_2byte(p_dm_odm, REG_BFMEE_SEL_8812A, sta_id | BIT(9));
290                 } else {
291                         /*Set BIT25*/
292                         odm_write_2byte(p_dm_odm, REG_BFMEE_SEL_8812A + 2, sta_id | 0xE200);
293                 }
294                 phydm_beamforming_notify(p_dm_odm);
295         }
296 }
297
298
299 void
300 hal_txbf_jaguar_leave(
301         void                    *p_dm_void,
302         u8                              idx
303 )
304 {
305         struct PHY_DM_STRUCT    *p_dm_odm = (struct PHY_DM_STRUCT *)p_dm_void;
306         struct _RT_BEAMFORMING_INFO     *p_beamforming_info = &p_dm_odm->beamforming_info;
307         struct _RT_BEAMFORMER_ENTRY     beamformer_entry;
308         struct _RT_BEAMFORMEE_ENTRY     beamformee_entry;
309
310         if (idx < BEAMFORMER_ENTRY_NUM) {
311                 beamformer_entry = p_beamforming_info->beamformer_entry[idx];
312                 beamformee_entry = p_beamforming_info->beamformee_entry[idx];
313         } else
314                 return;
315
316         ODM_RT_TRACE(p_dm_odm, PHYDM_COMP_TXBF, ODM_DBG_LOUD, ("[%s]Start!, IDx = %d\n", __func__, idx));
317
318         /*Clear P_AID of Beamformee*/
319         /*Clear MAC address of Beamformer*/
320         /*Clear Associated Bfmee Sel*/
321
322         if (beamformer_entry.beamform_entry_cap == BEAMFORMING_CAP_NONE) {
323                 odm_write_1byte(p_dm_odm, REG_SND_PTCL_CTRL_8812A, 0xC8);
324                 if (idx == 0) {
325                         odm_write_4byte(p_dm_odm, REG_BFMER0_INFO_8812A, 0);
326                         odm_write_2byte(p_dm_odm, REG_BFMER0_INFO_8812A + 4, 0);
327                         odm_write_2byte(p_dm_odm, REG_CSI_RPT_PARAM_BW20_8812A, 0);
328                         odm_write_2byte(p_dm_odm, REG_CSI_RPT_PARAM_BW40_8812A, 0);
329                         odm_write_2byte(p_dm_odm, REG_CSI_RPT_PARAM_BW80_8812A, 0);
330                 } else {
331                         odm_write_4byte(p_dm_odm, REG_BFMER1_INFO_8812A, 0);
332                         odm_write_2byte(p_dm_odm, REG_BFMER1_INFO_8812A + 4, 0);
333                         odm_write_2byte(p_dm_odm, REG_CSI_RPT_PARAM_BW20_8812A, 0);
334                         odm_write_2byte(p_dm_odm, REG_CSI_RPT_PARAM_BW40_8812A, 0);
335                         odm_write_2byte(p_dm_odm, REG_CSI_RPT_PARAM_BW80_8812A, 0);
336                 }
337         }
338
339         if (beamformee_entry.beamform_entry_cap == BEAMFORMING_CAP_NONE) {
340                 hal_txbf_jaguar_rf_mode(p_dm_odm, p_beamforming_info);
341                 if (idx == 0) {
342                         odm_write_2byte(p_dm_odm, REG_TXBF_CTRL_8812A, 0x0);
343                         odm_write_2byte(p_dm_odm, REG_BFMEE_SEL_8812A, 0);
344                 } else {
345                         odm_write_2byte(p_dm_odm, REG_TXBF_CTRL_8812A + 2, odm_read_2byte(p_dm_odm, REG_TXBF_CTRL_8812A + 2) & 0xF000);
346                         odm_write_2byte(p_dm_odm, REG_BFMEE_SEL_8812A + 2, odm_read_2byte(p_dm_odm, REG_BFMEE_SEL_8812A + 2) & 0x60);
347                 }
348         }
349
350 }
351
352
353 void
354 hal_txbf_jaguar_status(
355         void                    *p_dm_void,
356         u8                              idx
357 )
358 {
359         struct PHY_DM_STRUCT    *p_dm_odm = (struct PHY_DM_STRUCT *)p_dm_void;
360         u16                                     beam_ctrl_val;
361         u32                                     beam_ctrl_reg;
362         struct _RT_BEAMFORMING_INFO     *p_beam_info = &p_dm_odm->beamforming_info;
363         struct _RT_BEAMFORMEE_ENTRY     beamform_entry = p_beam_info->beamformee_entry[idx];
364
365         if (phydm_acting_determine(p_dm_odm, phydm_acting_as_ibss))
366                 beam_ctrl_val = beamform_entry.mac_id;
367         else
368                 beam_ctrl_val = beamform_entry.p_aid;
369
370         if (idx == 0)
371                 beam_ctrl_reg = REG_TXBF_CTRL_8812A;
372         else {
373                 beam_ctrl_reg = REG_TXBF_CTRL_8812A + 2;
374                 beam_ctrl_val |= BIT(12) | BIT(14) | BIT(15);
375         }
376
377         if ((beamform_entry.beamform_entry_state == BEAMFORMING_ENTRY_STATE_PROGRESSED) && (p_beam_info->apply_v_matrix == true)) {
378                 if (beamform_entry.sound_bw == CHANNEL_WIDTH_20)
379                         beam_ctrl_val |= BIT(9);
380                 else if (beamform_entry.sound_bw == CHANNEL_WIDTH_40)
381                         beam_ctrl_val |= (BIT(9) | BIT(10));
382                 else if (beamform_entry.sound_bw == CHANNEL_WIDTH_80)
383                         beam_ctrl_val |= (BIT(9) | BIT(10) | BIT(11));
384         } else
385                 beam_ctrl_val &= ~(BIT(9) | BIT(10) | BIT(11));
386
387         ODM_RT_TRACE(p_dm_odm, PHYDM_COMP_TXBF, ODM_DBG_LOUD, ("[%s] beam_ctrl_val = 0x%x!\n", __func__, beam_ctrl_val));
388
389         odm_write_2byte(p_dm_odm, beam_ctrl_reg, beam_ctrl_val);
390 }
391
392
393
394 void
395 hal_txbf_jaguar_fw_txbf(
396         void                    *p_dm_void,
397         u8                              idx
398 )
399 {
400         struct PHY_DM_STRUCT    *p_dm_odm = (struct PHY_DM_STRUCT *)p_dm_void;
401         struct _RT_BEAMFORMING_INFO     *p_beam_info = &p_dm_odm->beamforming_info;
402         struct _RT_BEAMFORMEE_ENTRY     *p_beam_entry = p_beam_info->beamformee_entry + idx;
403
404         ODM_RT_TRACE(p_dm_odm, PHYDM_COMP_TXBF, ODM_DBG_LOUD, ("[%s] Start!\n", __func__));
405
406         if (p_beam_entry->beamform_entry_state == BEAMFORMING_ENTRY_STATE_PROGRESSING)
407                 hal_txbf_jaguar_download_ndpa(p_dm_odm, idx);
408
409         hal_txbf_jaguar_fw_txbf_cmd(p_dm_odm);
410 }
411
412
413 void
414 hal_txbf_jaguar_patch(
415         void                    *p_dm_void,
416         u8                              operation
417 )
418 {
419         struct PHY_DM_STRUCT    *p_dm_odm = (struct PHY_DM_STRUCT *)p_dm_void;
420         struct _RT_BEAMFORMING_INFO     *p_beam_info = &p_dm_odm->beamforming_info;
421
422         ODM_RT_TRACE(p_dm_odm, PHYDM_COMP_TXBF, ODM_DBG_LOUD, ("[%s] Start!\n", __func__));
423
424         if (p_beam_info->beamform_cap == BEAMFORMING_CAP_NONE)
425                 return;
426 #if (DM_ODM_SUPPORT_TYPE == ODM_WIN)
427         if (operation == SCAN_OPT_BACKUP_BAND0)
428                 odm_write_1byte(p_dm_odm, REG_SND_PTCL_CTRL_8812A, 0xC8);
429         else if (operation == SCAN_OPT_RESTORE)
430                 odm_write_1byte(p_dm_odm, REG_SND_PTCL_CTRL_8812A, 0xCB);
431 #endif
432 }
433
434 void
435 hal_txbf_jaguar_clk_8812a(
436         void                    *p_dm_void
437 )
438 {
439         struct PHY_DM_STRUCT    *p_dm_odm = (struct PHY_DM_STRUCT *)p_dm_void;
440         u16     u2btmp;
441         u8      count = 0, u1btmp;
442         struct _ADAPTER *adapter = p_dm_odm->adapter;
443
444         ODM_RT_TRACE(p_dm_odm, PHYDM_COMP_TXBF, ODM_DBG_LOUD, ("[%s] Start!\n", __func__));
445
446         if (*(p_dm_odm->p_is_scan_in_process)) {
447                 ODM_RT_TRACE(p_dm_odm, PHYDM_COMP_TXBF, ODM_DBG_LOUD, ("[%s] return by Scan\n", __func__));
448                 return;
449         }
450 #if DEV_BUS_TYPE == RT_PCI_INTERFACE
451         /*Stop PCIe TxDMA*/
452         odm_write_1byte(p_dm_odm, REG_PCIE_CTRL_REG_8812A + 1, 0xFE);
453 #endif
454
455         /*Stop Usb TxDMA*/
456 #if (DM_ODM_SUPPORT_TYPE == ODM_WIN)
457         RT_DISABLE_FUNC(adapter, DF_TX_BIT);
458         PlatformReturnAllPendingTxPackets(adapter);
459 #else
460         rtw_write_port_cancel(adapter);
461 #endif
462
463         /*Wait TXFF empty*/
464         for (count = 0; count < 100; count++) {
465                 u2btmp = odm_read_2byte(p_dm_odm, REG_TXPKT_EMPTY_8812A);
466                 u2btmp = u2btmp & 0xfff;
467                 if (u2btmp != 0xfff) {
468                         ODM_delay_ms(10);
469                         continue;
470                 } else
471                         break;
472         }
473
474         /*TX pause*/
475         odm_write_1byte(p_dm_odm, REG_TXPAUSE_8812A, 0xFF);
476
477         /*Wait TX state Machine OK*/
478         for (count = 0; count < 100; count++) {
479                 if (odm_read_4byte(p_dm_odm, REG_SCH_TXCMD_8812A) != 0)
480                         continue;
481                 else
482                         break;
483         }
484
485
486         /*Stop RX DMA path*/
487         u1btmp = odm_read_1byte(p_dm_odm, REG_RXDMA_CONTROL_8812A);
488         odm_write_1byte(p_dm_odm, REG_RXDMA_CONTROL_8812A, u1btmp | BIT(2));
489
490         for (count = 0; count < 100; count++) {
491                 u1btmp = odm_read_1byte(p_dm_odm, REG_RXDMA_CONTROL_8812A);
492                 if (u1btmp & BIT(1))
493                         break;
494                 else
495                         ODM_delay_ms(10);
496         }
497
498         /*Disable clock*/
499         odm_write_1byte(p_dm_odm, REG_SYS_CLKR_8812A + 1, 0xf0);
500         /*Disable 320M*/
501         odm_write_1byte(p_dm_odm, REG_AFE_PLL_CTRL_8812A + 3, 0x8);
502         /*Enable 320M*/
503         odm_write_1byte(p_dm_odm, REG_AFE_PLL_CTRL_8812A + 3, 0xa);
504         /*Enable clock*/
505         odm_write_1byte(p_dm_odm, REG_SYS_CLKR_8812A + 1, 0xfc);
506
507
508         /*Release Tx pause*/
509         odm_write_1byte(p_dm_odm, REG_TXPAUSE_8812A, 0);
510
511         /*Enable RX DMA path*/
512         u1btmp = odm_read_1byte(p_dm_odm, REG_RXDMA_CONTROL_8812A);
513         odm_write_1byte(p_dm_odm, REG_RXDMA_CONTROL_8812A, u1btmp & (~BIT(2)));
514 #if DEV_BUS_TYPE == RT_PCI_INTERFACE
515         /*Enable PCIe TxDMA*/
516         odm_write_1byte(p_dm_odm, REG_PCIE_CTRL_REG_8812A + 1, 0);
517 #endif
518         /*Start Usb TxDMA*/
519         RT_ENABLE_FUNC(adapter, DF_TX_BIT);
520 }
521
522 #endif
523
524
525
526 #endif