net: wireless: rockchip_wlan: add rtl8723cs support
[firefly-linux-kernel-4.4.55.git] / drivers / net / wireless / rockchip_wlan / rtl8723cs / hal / phydm / txbf / haltxbfinterface.c
1 /* ************************************************************
2  * Description:
3  *
4  * This file is for TXBF interface mechanism
5  *
6  * ************************************************************ */
7 #include "mp_precomp.h"
8 #include "../phydm_precomp.h"
9
10 #if (BEAMFORMING_SUPPORT == 1)
11 #if (DM_ODM_SUPPORT_TYPE == ODM_WIN)
12 void
13 beamforming_gid_paid(
14         struct _ADAPTER *adapter,
15         PRT_TCB         p_tcb
16 )
17 {
18         u8              idx = 0;
19         u8              RA[6] = {0};
20         u8              *p_header = GET_FRAME_OF_FIRST_FRAG(adapter, p_tcb);
21         HAL_DATA_TYPE                   *p_hal_data = GET_HAL_DATA(adapter);
22         struct PHY_DM_STRUCT                            *p_dm_odm = &p_hal_data->DM_OutSrc;
23         struct _RT_BEAMFORMING_INFO     *p_beam_info = &(p_dm_odm->beamforming_info);
24
25         if (adapter->HardwareType < HARDWARE_TYPE_RTL8192EE)
26                 return;
27         else if (IS_WIRELESS_MODE_N(adapter) == false)
28                 return;
29
30 #if (SUPPORT_MU_BF == 1)
31         if (p_tcb->tx_bf_pkt_type == RT_BF_PKT_TYPE_BROADCAST_NDPA) { /* MU NDPA */
32 #else
33         if (0) {
34 #endif
35                 /* Fill G_ID and P_AID */
36                 p_tcb->G_ID = 63;
37                 if (p_beam_info->first_mu_bfee_index < BEAMFORMEE_ENTRY_NUM) {
38                         p_tcb->P_AID = p_beam_info->beamformee_entry[p_beam_info->first_mu_bfee_index].p_aid;
39                         RT_DISP(FBEAM, FBEAM_FUN, ("[David]@%s End, G_ID=0x%X, P_AID=0x%X\n", __func__, p_tcb->G_ID, p_tcb->P_AID));
40                 }
41         } else {
42                 GET_80211_HDR_ADDRESS1(p_header, &RA);
43
44                 /* VHT SU PPDU carrying one or more group addressed MPDUs or */
45                 /* Transmitting a VHT NDP intended for multiple recipients */
46                 if (MacAddr_isBcst(RA) || MacAddr_isMulticast(RA)       || p_tcb->macId == MAC_ID_STATIC_FOR_BROADCAST_MULTICAST) {
47                         p_tcb->G_ID = 63;
48                         p_tcb->P_AID = 0;
49                 } else if (ACTING_AS_AP(adapter)) {
50                         u16     AID = (u16)(MacIdGetOwnerAssociatedClientAID(adapter, p_tcb->macId) & 0x1ff);           /*AID[0:8]*/
51
52                         /*RT_DISP(FBEAM, FBEAM_FUN, ("@%s  p_tcb->mac_id=0x%X, AID=0x%X\n", __func__, p_tcb->mac_id, AID));*/
53                         p_tcb->G_ID = 63;
54
55                         if (AID == 0)           /*A PPDU sent by an AP to a non associated STA*/
56                                 p_tcb->P_AID = 0;
57                         else {                          /*Sent by an AP and addressed to a STA associated with that AP*/
58                                 u16     BSSID = 0;
59                                 GET_80211_HDR_ADDRESS2(p_header, &RA);
60                                 BSSID = ((RA[5] & 0xf0) >> 4) ^ (RA[5] & 0xf);  /*BSSID[44:47] xor BSSID[40:43]*/
61                                 p_tcb->P_AID = (AID + BSSID * 32) & 0x1ff;              /*(dec(A) + dec(B)*32) mod 512*/
62                         }
63                 } else if (ACTING_AS_IBSS(adapter)) {
64                         p_tcb->G_ID = 63;
65                         /*P_AID for infrasturcture mode; MACID for ad-hoc mode. */
66                         p_tcb->P_AID = p_tcb->macId;
67                 } else if (MgntLinkStatusQuery(adapter)) {                              /*Addressed to AP*/
68                         p_tcb->G_ID = 0;
69                         GET_80211_HDR_ADDRESS1(p_header, &RA);
70                         p_tcb->P_AID =  RA[5];                                                  /*RA[39:47]*/
71                         p_tcb->P_AID = (p_tcb->P_AID << 1) | (RA[4] >> 7);
72                 } else {
73                         p_tcb->G_ID = 63;
74                         p_tcb->P_AID = 0;
75                 }
76                 /*RT_DISP(FBEAM, FBEAM_FUN, ("[David]@%s End, G_ID=0x%X, P_AID=0x%X\n", __func__, p_tcb->G_ID, p_tcb->P_AID));*/
77         }
78 }
79
80
81 enum rt_status
82 beamforming_get_report_frame(
83         struct _ADAPTER         *adapter,
84         PRT_RFD                 p_rfd,
85         POCTET_STRING   p_pdu_os
86 )
87 {
88         HAL_DATA_TYPE                           *p_hal_data = GET_HAL_DATA(adapter);
89         struct PHY_DM_STRUCT                                    *p_dm_odm = &p_hal_data->DM_OutSrc;
90         struct _RT_BEAMFORMEE_ENTRY             *p_beamform_entry = NULL;
91         u8                                              *p_mimo_ctrl_field, p_csi_report, p_csi_matrix;
92         u8                                              idx, nc, nr, CH_W;
93         u16                                             csi_matrix_len = 0;
94
95         ACT_PKT_TYPE                            pkt_type = ACT_PKT_TYPE_UNKNOWN;
96
97         /* Memory comparison to see if CSI report is the same with previous one */
98         p_beamform_entry = phydm_beamforming_get_bfee_entry_by_addr(p_dm_odm, Frame_Addr2(*p_pdu_os), &idx);
99
100         if (p_beamform_entry == NULL) {
101                 ODM_RT_TRACE(p_dm_odm, PHYDM_COMP_TXBF, ODM_DBG_LOUD, ("beamforming_get_report_frame: Cannot find entry by addr\n"));
102                 return RT_STATUS_FAILURE;
103         }
104
105         pkt_type = PacketGetActionFrameType(p_pdu_os);
106
107         /* -@ Modified by David */
108         if (pkt_type == ACT_PKT_VHT_COMPRESSED_BEAMFORMING) {
109                 p_mimo_ctrl_field = p_pdu_os->Octet + 26;
110                 nc = ((*p_mimo_ctrl_field) & 0x7) + 1;
111                 nr = (((*p_mimo_ctrl_field) & 0x38) >> 3) + 1;
112                 CH_W = (((*p_mimo_ctrl_field) & 0xC0) >> 6);
113                 /*p_csi_matrix = p_mimo_ctrl_field + 3 + nc;*/ /* 24+(1+1+3)+2  MAC header+(Category+ActionCode+MIMOControlField) +SNR(nc=2) */
114                 csi_matrix_len = p_pdu_os->Length  - 26 - 3 - nc;
115         } else if (pkt_type == ACT_PKT_HT_COMPRESSED_BEAMFORMING) {
116                 p_mimo_ctrl_field = p_pdu_os->Octet + 26;
117                 nc = ((*p_mimo_ctrl_field) & 0x3) + 1;
118                 nr = (((*p_mimo_ctrl_field) & 0xC) >> 2) + 1;
119                 CH_W = (((*p_mimo_ctrl_field) & 0x10) >> 4);
120                 /*p_csi_matrix = p_mimo_ctrl_field + 6 + nr;*/  /* 24+(1+1+6)+2  MAC header+(Category+ActionCode+MIMOControlField) +SNR(nc=2) */
121                 csi_matrix_len = p_pdu_os->Length  - 26 - 6 - nr;
122         } else
123                 return RT_STATUS_SUCCESS;
124
125         ODM_RT_TRACE(p_dm_odm, PHYDM_COMP_TXBF, ODM_DBG_LOUD, ("[%s] idx=%d, pkt type=%d, nc=%d, nr=%d, CH_W=%d\n", __func__, idx, pkt_type, nc, nr, CH_W));
126
127         return RT_STATUS_SUCCESS;
128 }
129
130
131 void
132 construct_ht_ndpa_packet(
133         struct _ADAPTER         *adapter,
134         u8                      *RA,
135         u8                      *buffer,
136         u32                     *p_length,
137         CHANNEL_WIDTH   BW
138 )
139 {
140         u16                                     duration = 0;
141         PMGNT_INFO                              p_mgnt_info = &(adapter->MgntInfo);
142         OCTET_STRING                    p_ndpa_frame, action_content;
143         u8                                      action_hdr[4] = {ACT_CAT_VENDOR, 0x00, 0xe0, 0x4c};
144
145         PlatformZeroMemory(buffer, 32);
146
147         SET_80211_HDR_FRAME_CONTROL(buffer, 0);
148
149         SET_80211_HDR_ORDER(buffer, 1);
150         SET_80211_HDR_TYPE_AND_SUBTYPE(buffer, Type_Action_No_Ack);
151
152         SET_80211_HDR_ADDRESS1(buffer, RA);
153         SET_80211_HDR_ADDRESS2(buffer, adapter->CurrentAddress);
154         SET_80211_HDR_ADDRESS3(buffer, p_mgnt_info->Bssid);
155
156         duration = 2 * a_SifsTime + 40;
157
158         if (BW == CHANNEL_WIDTH_40)
159                 duration += 87;
160         else
161                 duration += 180;
162
163         SET_80211_HDR_DURATION(buffer, duration);
164
165         /* HT control field */
166         SET_HT_CTRL_CSI_STEERING(buffer + sMacHdrLng, 3);
167         SET_HT_CTRL_NDP_ANNOUNCEMENT(buffer + sMacHdrLng, 1);
168
169         FillOctetString(p_ndpa_frame, buffer, sMacHdrLng + sHTCLng);
170
171         FillOctetString(action_content, action_hdr, 4);
172         PacketAppendData(&p_ndpa_frame, action_content);
173
174         *p_length = 32;
175 }
176
177
178
179
180 boolean
181 send_fw_ht_ndpa_packet(
182         void                    *p_dm_void,
183         u8                      *RA,
184         CHANNEL_WIDTH   BW
185 )
186 {
187         struct PHY_DM_STRUCT                            *p_dm_odm = (struct PHY_DM_STRUCT *)p_dm_void;
188         struct _ADAPTER                         *adapter = p_dm_odm->adapter;
189         PRT_TCB                         p_tcb;
190         PRT_TX_LOCAL_BUFFER     p_buf;
191         boolean                         ret = true;
192         u32                                     buf_len;
193         u8                                      *buf_addr;
194         u8                                      desc_len = 0, idx = 0, ndp_tx_rate;
195         struct _ADAPTER                         *p_def_adapter = GetDefaultAdapter(adapter);
196         struct _RT_BEAMFORMING_INFO     *p_beam_info = &p_dm_odm->beamforming_info;
197         HAL_DATA_TYPE                   *p_hal_data = GET_HAL_DATA(adapter);
198         struct _RT_BEAMFORMEE_ENTRY     *p_beamform_entry = phydm_beamforming_get_bfee_entry_by_addr(p_dm_odm, RA, &idx);
199
200         ODM_RT_TRACE(p_dm_odm, PHYDM_COMP_TXBF, ODM_DBG_LOUD, ("[%s] Start!\n", __func__));
201
202         if (p_beamform_entry == NULL)
203                 return false;
204
205         ndp_tx_rate = beamforming_get_htndp_tx_rate(p_dm_odm, p_beamform_entry->comp_steering_num_of_bfer);
206         ODM_RT_TRACE(p_dm_odm, PHYDM_COMP_TXBF, ODM_DBG_LOUD, ("[%s] ndp_tx_rate =%d\n", __func__, ndp_tx_rate));
207         PlatformAcquireSpinLock(adapter, RT_TX_SPINLOCK);
208
209         if (MgntGetFWBuffer(p_def_adapter, &p_tcb, &p_buf)) {
210 #if (DEV_BUS_TYPE != RT_PCI_INTERFACE)
211                 desc_len = adapter->HWDescHeadLength - p_hal_data->USBALLDummyLength;
212 #endif
213                 buf_addr = p_buf->Buffer.VirtualAddress + desc_len;
214
215                 construct_ht_ndpa_packet(
216                         adapter,
217                         RA,
218                         buf_addr,
219                         &buf_len,
220                         BW
221                 );
222
223                 p_tcb->PacketLength = buf_len + desc_len;
224
225                 p_tcb->bTxEnableSwCalcDur = true;
226
227                 p_tcb->BWOfPacket = BW;
228
229                 if (ACTING_AS_IBSS(adapter) || ACTING_AS_AP(adapter))
230                         p_tcb->G_ID = 63;
231
232                 p_tcb->P_AID = p_beamform_entry->p_aid;
233                 p_tcb->DataRate = ndp_tx_rate;  /*rate of NDP decide by nr*/
234
235                 adapter->HalFunc.CmdSendPacketHandler(adapter, p_tcb, p_buf, p_tcb->PacketLength, DESC_PACKET_TYPE_NORMAL, false);
236         } else
237                 ret = false;
238
239         PlatformReleaseSpinLock(adapter, RT_TX_SPINLOCK);
240
241         if (ret)
242                 RT_DISP_DATA(FBEAM, FBEAM_DATA, "", p_buf->Buffer.VirtualAddress, p_tcb->PacketLength);
243
244         return ret;
245 }
246
247
248 boolean
249 send_sw_ht_ndpa_packet(
250         void                    *p_dm_void,
251         u8                      *RA,
252         CHANNEL_WIDTH   BW
253 )
254 {
255         struct PHY_DM_STRUCT                            *p_dm_odm = (struct PHY_DM_STRUCT *)p_dm_void;
256         struct _ADAPTER                         *adapter = p_dm_odm->adapter;
257         PRT_TCB                                 p_tcb;
258         PRT_TX_LOCAL_BUFFER             p_buf;
259         boolean                                 ret = true;
260         u8                                      idx = 0, ndp_tx_rate = 0;
261         struct _RT_BEAMFORMING_INFO     *p_beam_info = &p_dm_odm->beamforming_info;
262         struct _RT_BEAMFORMEE_ENTRY     *p_beamform_entry = phydm_beamforming_get_bfee_entry_by_addr(p_dm_odm, RA, &idx);
263
264         ODM_RT_TRACE(p_dm_odm, PHYDM_COMP_TXBF, ODM_DBG_LOUD, ("[%s] Start!\n", __func__));
265
266         ndp_tx_rate = beamforming_get_htndp_tx_rate(p_dm_odm, p_beamform_entry->comp_steering_num_of_bfer);
267         ODM_RT_TRACE(p_dm_odm, PHYDM_COMP_TXBF, ODM_DBG_LOUD, ("[%s] ndp_tx_rate =%d\n", __func__, ndp_tx_rate));
268
269         PlatformAcquireSpinLock(adapter, RT_TX_SPINLOCK);
270
271         if (MgntGetBuffer(adapter, &p_tcb, &p_buf)) {
272                 construct_ht_ndpa_packet(
273                         adapter,
274                         RA,
275                         p_buf->Buffer.VirtualAddress,
276                         &p_tcb->PacketLength,
277                         BW
278                 );
279
280                 p_tcb->bTxEnableSwCalcDur = true;
281
282                 p_tcb->BWOfPacket = BW;
283
284                 MgntSendPacket(adapter, p_tcb, p_buf, p_tcb->PacketLength, NORMAL_QUEUE, ndp_tx_rate);
285         } else
286                 ret = false;
287
288         PlatformReleaseSpinLock(adapter, RT_TX_SPINLOCK);
289
290         if (ret)
291                 RT_DISP_DATA(FBEAM, FBEAM_DATA, "", p_buf->Buffer.VirtualAddress, p_tcb->PacketLength);
292
293         return ret;
294 }
295
296
297
298 void
299 construct_vht_ndpa_packet(
300         struct PHY_DM_STRUCT    *p_dm_odm,
301         u8                      *RA,
302         u16                     AID,
303         u8                      *buffer,
304         u32                     *p_length,
305         CHANNEL_WIDTH   BW
306 )
307 {
308         u16                                     duration = 0;
309         u8                                      sequence = 0;
310         u8                                      *p_ndpa_frame = buffer;
311         struct _RT_NDPA_STA_INFO                sta_info;
312         struct _ADAPTER                         *adapter = p_dm_odm->adapter;
313         u8      idx = 0;
314         struct _RT_BEAMFORMEE_ENTRY     *p_beamform_entry = phydm_beamforming_get_bfee_entry_by_addr(p_dm_odm, RA, &idx);
315         /* Frame control. */
316         SET_80211_HDR_FRAME_CONTROL(p_ndpa_frame, 0);
317         SET_80211_HDR_TYPE_AND_SUBTYPE(p_ndpa_frame, Type_NDPA);
318
319         SET_80211_HDR_ADDRESS1(p_ndpa_frame, RA);
320         SET_80211_HDR_ADDRESS2(p_ndpa_frame, p_beamform_entry->my_mac_addr);
321
322         duration = 2 * a_SifsTime + 44;
323
324         if (BW == CHANNEL_WIDTH_80)
325                 duration += 40;
326         else if (BW == CHANNEL_WIDTH_40)
327                 duration += 87;
328         else
329                 duration += 180;
330
331         SET_80211_HDR_DURATION(p_ndpa_frame, duration);
332
333         sequence = *(p_dm_odm->p_sounding_seq) << 2;
334         odm_move_memory(p_dm_odm, p_ndpa_frame + 16, &sequence, 1);
335
336         if (phydm_acting_determine(p_dm_odm, phydm_acting_as_ibss) || phydm_acting_determine(p_dm_odm, phydm_acting_as_ap) == false)
337                 AID = 0;
338
339         sta_info.aid = AID;
340         sta_info.feedback_type = 0;
341         sta_info.nc_index = 0;
342
343         odm_move_memory(p_dm_odm, p_ndpa_frame + 17, (u8 *)&sta_info, 2);
344
345         *p_length = 19;
346 }
347
348
349 boolean
350 send_fw_vht_ndpa_packet(
351         void                    *p_dm_void,
352         u8                      *RA,
353         u16                     AID,
354         CHANNEL_WIDTH   BW
355 )
356 {
357         struct PHY_DM_STRUCT                            *p_dm_odm = (struct PHY_DM_STRUCT *)p_dm_void;
358         struct _ADAPTER                         *adapter = p_dm_odm->adapter;
359         PRT_TCB                                 p_tcb;
360         PRT_TX_LOCAL_BUFFER             p_buf;
361         boolean                                 ret = true;
362         u32                                     buf_len;
363         u8                                      *buf_addr;
364         u8                                      desc_len = 0, idx = 0, ndp_tx_rate = 0;
365         struct _ADAPTER                         *p_def_adapter = GetDefaultAdapter(adapter);
366         struct _RT_BEAMFORMING_INFO     *p_beam_info = &p_dm_odm->beamforming_info;
367         HAL_DATA_TYPE                   *p_hal_data = GET_HAL_DATA(adapter);
368         struct _RT_BEAMFORMEE_ENTRY     *p_beamform_entry = phydm_beamforming_get_bfee_entry_by_addr(p_dm_odm, RA, &idx);
369
370         ODM_RT_TRACE(p_dm_odm, PHYDM_COMP_TXBF, ODM_DBG_LOUD, ("[%s] Start!\n", __func__));
371
372         if (p_beamform_entry == NULL)
373                 return false;
374
375         ndp_tx_rate = beamforming_get_vht_ndp_tx_rate(p_dm_odm, p_beamform_entry->comp_steering_num_of_bfer);
376         ODM_RT_TRACE(p_dm_odm, PHYDM_COMP_TXBF, ODM_DBG_LOUD, ("[%s] ndp_tx_rate =%d\n", __func__, ndp_tx_rate));
377
378         PlatformAcquireSpinLock(adapter, RT_TX_SPINLOCK);
379
380         if (MgntGetFWBuffer(p_def_adapter, &p_tcb, &p_buf)) {
381 #if (DEV_BUS_TYPE != RT_PCI_INTERFACE)
382                 desc_len = adapter->HWDescHeadLength - p_hal_data->USBALLDummyLength;
383 #endif
384                 buf_addr = p_buf->Buffer.VirtualAddress + desc_len;
385
386                 construct_vht_ndpa_packet(
387                         p_dm_odm,
388                         RA,
389                         AID,
390                         buf_addr,
391                         &buf_len,
392                         BW
393                 );
394
395                 p_tcb->PacketLength = buf_len + desc_len;
396
397                 p_tcb->bTxEnableSwCalcDur = true;
398
399                 p_tcb->BWOfPacket = BW;
400
401                 if (phydm_acting_determine(p_dm_odm, phydm_acting_as_ibss) || phydm_acting_determine(p_dm_odm, phydm_acting_as_ap))
402                         p_tcb->G_ID = 63;
403
404                 p_tcb->P_AID = p_beamform_entry->p_aid;
405                 p_tcb->DataRate = ndp_tx_rate;  /*decide by nr*/
406
407                 adapter->HalFunc.CmdSendPacketHandler(adapter, p_tcb, p_buf, p_tcb->PacketLength, DESC_PACKET_TYPE_NORMAL, false);
408         } else
409                 ret = false;
410
411         PlatformReleaseSpinLock(adapter, RT_TX_SPINLOCK);
412
413         ODM_RT_TRACE(p_dm_odm, PHYDM_COMP_TXBF, ODM_DBG_LOUD, ("[%s] End, ret=%d\n", __func__, ret));
414
415         if (ret)
416                 RT_DISP_DATA(FBEAM, FBEAM_DATA, "", p_buf->Buffer.VirtualAddress, p_tcb->PacketLength);
417
418         return ret;
419 }
420
421
422
423 boolean
424 send_sw_vht_ndpa_packet(
425         void                    *p_dm_void,
426         u8                      *RA,
427         u16                     AID,
428         CHANNEL_WIDTH   BW
429 )
430 {
431         struct PHY_DM_STRUCT                            *p_dm_odm = (struct PHY_DM_STRUCT *)p_dm_void;
432         struct _ADAPTER                         *adapter = p_dm_odm->adapter;
433         PRT_TCB                                 p_tcb;
434         PRT_TX_LOCAL_BUFFER             p_buf;
435         boolean                                 ret = true;
436         u8                                      idx = 0, ndp_tx_rate = 0;
437         struct _RT_BEAMFORMING_INFO     *p_beam_info = &(p_dm_odm->beamforming_info);
438         struct _RT_BEAMFORMEE_ENTRY     *p_beamform_entry = phydm_beamforming_get_bfee_entry_by_addr(p_dm_odm, RA, &idx);
439
440         ndp_tx_rate = beamforming_get_vht_ndp_tx_rate(p_dm_odm, p_beamform_entry->comp_steering_num_of_bfer);
441         ODM_RT_TRACE(p_dm_odm, PHYDM_COMP_TXBF, ODM_DBG_LOUD, ("[%s] ndp_tx_rate =%d\n", __func__, ndp_tx_rate));
442
443         PlatformAcquireSpinLock(adapter, RT_TX_SPINLOCK);
444
445         if (MgntGetBuffer(adapter, &p_tcb, &p_buf)) {
446                 construct_vht_ndpa_packet(
447                         p_dm_odm,
448                         RA,
449                         AID,
450                         p_buf->Buffer.VirtualAddress,
451                         &p_tcb->PacketLength,
452                         BW
453                 );
454
455                 p_tcb->bTxEnableSwCalcDur = true;
456                 p_tcb->BWOfPacket = BW;
457
458                 /*rate of NDP decide by nr*/
459                 MgntSendPacket(adapter, p_tcb, p_buf, p_tcb->PacketLength, NORMAL_QUEUE, ndp_tx_rate);
460         } else
461                 ret = false;
462
463         PlatformReleaseSpinLock(adapter, RT_TX_SPINLOCK);
464
465         if (ret)
466                 RT_DISP_DATA(FBEAM, FBEAM_DATA, "", p_buf->Buffer.VirtualAddress, p_tcb->PacketLength);
467
468         return ret;
469 }
470
471 #ifdef SUPPORT_MU_BF
472 #if (SUPPORT_MU_BF == 1)
473 /*
474  * Description: On VHT GID management frame by an MU beamformee.
475  *
476  * 2015.05.20. Created by tynli.
477  */
478 enum rt_status
479 beamforming_get_vht_gid_mgnt_frame(
480         struct _ADAPTER         *adapter,
481         PRT_RFD                 p_rfd,
482         POCTET_STRING   p_pdu_os
483 )
484 {
485         HAL_DATA_TYPE   *p_hal_data = GET_HAL_DATA(adapter);
486         struct PHY_DM_STRUCT            *p_dm_odm = &p_hal_data->DM_OutSrc;
487         enum rt_status          rt_status = RT_STATUS_SUCCESS;
488         u8                      *p_buffer = NULL;
489         u8                      *p_raddr = NULL;
490         u8                      mem_status[8] = {0}, user_pos[16] = {0};
491         u8                      idx;
492         struct _RT_BEAMFORMING_INFO     *p_beam_info = &(p_dm_odm->beamforming_info);
493         struct _RT_BEAMFORMER_ENTRY     *p_beamform_entry = &p_beam_info->beamformer_entry[p_beam_info->mu_ap_index];
494
495         ODM_RT_TRACE(p_dm_odm, PHYDM_COMP_TXBF, ODM_DBG_LOUD, ("[%s] On VHT GID mgnt frame!\n", __func__));
496
497         /* Check length*/
498         if (p_pdu_os->length < (FRAME_OFFSET_VHT_GID_MGNT_USER_POSITION_ARRAY + 16)) {
499                 ODM_RT_TRACE(p_dm_odm, PHYDM_COMP_TXBF, ODM_DBG_LOUD, ("beamforming_get_vht_gid_mgnt_frame(): Invalid length (%d)\n", p_pdu_os->length));
500                 return RT_STATUS_INVALID_LENGTH;
501         }
502
503         /* Check RA*/
504         p_raddr = (u8 *)(p_pdu_os->Octet) + 4;
505         if (!eq_mac_addr(p_raddr, adapter->CurrentAddress)) {
506                 ODM_RT_TRACE(p_dm_odm, PHYDM_COMP_TXBF, ODM_DBG_LOUD, ("beamforming_get_vht_gid_mgnt_frame(): Drop because of RA error.\n"));
507                 return RT_STATUS_PKT_DROP;
508         }
509
510         RT_DISP_DATA(FBEAM, FBEAM_DATA, "On VHT GID Mgnt Frame ==>:\n", p_pdu_os->Octet, p_pdu_os->length);
511
512         /*Parsing Membership status array*/
513         p_buffer = p_pdu_os->Octet + FRAME_OFFSET_VHT_GID_MGNT_MEMBERSHIP_STATUS_ARRAY;
514         for (idx = 0; idx < 8; idx++) {
515                 mem_status[idx] = GET_VHT_GID_MGNT_INFO_MEMBERSHIP_STATUS(p_buffer + idx);
516                 p_beamform_entry->gid_valid[idx] = GET_VHT_GID_MGNT_INFO_MEMBERSHIP_STATUS(p_buffer + idx);
517         }
518
519         RT_DISP_DATA(FBEAM, FBEAM_DATA, "mem_status: ", mem_status, 8);
520
521         /* Parsing User Position array*/
522         p_buffer = p_pdu_os->Octet + FRAME_OFFSET_VHT_GID_MGNT_USER_POSITION_ARRAY;
523         for (idx = 0; idx < 16; idx++) {
524                 user_pos[idx] = GET_VHT_GID_MGNT_INFO_USER_POSITION(p_buffer + idx);
525                 p_beamform_entry->user_position[idx] = GET_VHT_GID_MGNT_INFO_USER_POSITION(p_buffer + idx);
526         }
527
528         RT_DISP_DATA(FBEAM, FBEAM_DATA, "user_pos: ", user_pos, 16);
529
530         /* Group ID detail printed*/
531         {
532                 u8      i, j;
533                 u8      tmp_val;
534                 u16     tmp_val2;
535
536                 for (i = 0; i < 8; i++) {
537                         tmp_val = mem_status[i];
538                         tmp_val2 = ((user_pos[i * 2 + 1] << 8) & 0xFF00) + (user_pos[i * 2] & 0xFF);
539                         for (j = 0; j < 8; j++) {
540                                 if ((tmp_val >> j) & BIT(0)) {
541                                         ODM_RT_TRACE(p_dm_odm, PHYDM_COMP_TXBF, ODM_DBG_LOUD, ("Use Group ID (%d), User Position (%d)\n",
542                                                 (i * 8 + j), (tmp_val2 >> 2 * j) & 0x3));
543                                 }
544                         }
545                 }
546         }
547
548         /* Indicate GID frame to IHV service. */
549         {
550                 u8      indibuffer[24] = {0};
551                 u8      indioffset = 0;
552
553                 PlatformMoveMemory(indibuffer + indioffset, p_beamform_entry->gid_valid, 8);
554                 indioffset += 8;
555                 PlatformMoveMemory(indibuffer + indioffset, p_beamform_entry->user_position, 16);
556                 indioffset += 16;
557
558                 PlatformIndicateCustomStatus(
559                         adapter,
560                         RT_CUSTOM_EVENT_VHT_RECV_GID_MGNT_FRAME,
561                         RT_CUSTOM_INDI_TARGET_IHV,
562                         indibuffer,
563                         indioffset);
564         }
565
566         /* Config HW GID table */
567         hal_com_txbf_config_gtab(p_dm_odm);
568
569         return rt_status;
570 }
571
572 /*
573  * Description: Construct VHT Group ID (GID) management frame.
574  *
575  * 2015.05.20. Created by tynli.
576  */
577 void
578 construct_vht_gid_mgnt_frame(
579         struct PHY_DM_STRUCT            *p_dm_odm,
580         u8                      *RA,
581         struct _RT_BEAMFORMEE_ENTRY     *p_beamform_entry,
582         u8                      *buffer,
583         u32                     *p_length
584
585 )
586 {
587         struct _RT_BEAMFORMING_INFO     *p_beam_info = &(p_dm_odm->beamforming_info);
588         struct _ADAPTER                         *adapter = p_beam_info->source_adapter;
589         OCTET_STRING            os_ftm_frame, tmp;
590
591         FillOctetString(os_ftm_frame, buffer, 0);
592         *p_length = 0;
593
594         ConstructMaFrameHdr(
595                 adapter,
596                 RA,
597                 ACT_CAT_VHT,
598                 ACT_VHT_GROUPID_MANAGEMENT,
599                 &os_ftm_frame);
600
601         /* Membership status array*/
602         FillOctetString(tmp, p_beamform_entry->gid_valid, 8);
603         PacketAppendData(&os_ftm_frame, tmp);
604
605         /* User Position array*/
606         FillOctetString(tmp, p_beamform_entry->user_position, 16);
607         PacketAppendData(&os_ftm_frame, tmp);
608
609         *p_length = os_ftm_frame.length;
610
611         RT_DISP_DATA(FBEAM, FBEAM_DATA, "construct_vht_gid_mgnt_frame():\n", buffer, *p_length);
612 }
613
614 boolean
615 send_sw_vht_gid_mgnt_frame(
616         void                    *p_dm_void,
617         u8                      *RA,
618         u8                      idx
619 )
620 {
621         struct PHY_DM_STRUCT                            *p_dm_odm = (struct PHY_DM_STRUCT *)p_dm_void;
622         PRT_TCB                                 p_tcb;
623         PRT_TX_LOCAL_BUFFER             p_buf;
624         boolean                                 ret = true;
625         u8                                      data_rate = 0;
626         struct _RT_BEAMFORMING_INFO     *p_beam_info = &(p_dm_odm->beamforming_info);
627         struct _RT_BEAMFORMEE_ENTRY     *p_beamform_entry = &p_beam_info->beamformee_entry[idx];
628         struct _ADAPTER                         *adapter = p_beam_info->source_adapter;
629
630         ODM_RT_TRACE(p_dm_odm, PHYDM_COMP_TXBF, ODM_DBG_LOUD, ("[%s] Start!\n", __func__));
631
632         PlatformAcquireSpinLock(adapter, RT_TX_SPINLOCK);
633
634         if (MgntGetBuffer(adapter, &p_tcb, &p_buf)) {
635                 construct_vht_gid_mgnt_frame(
636                         p_dm_odm,
637                         RA,
638                         p_beamform_entry,
639                         p_buf->Buffer.VirtualAddress,
640                         &p_tcb->PacketLength
641                 );
642
643                 p_tcb->bw_of_packet = CHANNEL_WIDTH_20;
644                 data_rate = MGN_6M;
645                 MgntSendPacket(adapter, p_tcb, p_buf, p_tcb->PacketLength, NORMAL_QUEUE, data_rate);
646         } else
647                 ret = false;
648
649         PlatformReleaseSpinLock(adapter, RT_TX_SPINLOCK);
650
651         if (ret)
652                 RT_DISP_DATA(FBEAM, FBEAM_DATA, "", p_buf->Buffer.VirtualAddress, p_tcb->PacketLength);
653
654         return ret;
655 }
656
657
658 /*
659  * Description: Construct VHT beamforming report poll.
660  *
661  * 2015.05.20. Created by tynli.
662  */
663 void
664 construct_vht_bf_report_poll(
665         struct PHY_DM_STRUCT            *p_dm_odm,
666         u8                      *RA,
667         u8                      *buffer,
668         u32                     *p_length
669 )
670 {
671         struct _RT_BEAMFORMING_INFO     *p_beam_info = &(p_dm_odm->beamforming_info);
672         struct _ADAPTER                         *adapter = p_beam_info->source_adapter;
673         u8                      *p_bf_rpt_poll = buffer;
674
675         /* Frame control*/
676         SET_80211_HDR_FRAME_CONTROL(p_bf_rpt_poll, 0);
677         SET_80211_HDR_TYPE_AND_SUBTYPE(p_bf_rpt_poll, Type_Beamforming_Report_Poll);
678
679         /* duration*/
680         SET_80211_HDR_DURATION(p_bf_rpt_poll, 100);
681
682         /* RA*/
683         SET_VHT_BF_REPORT_POLL_RA(p_bf_rpt_poll, RA);
684
685         /* TA*/
686         SET_VHT_BF_REPORT_POLL_TA(p_bf_rpt_poll, adapter->CurrentAddress);
687
688         /* Feedback Segment Retransmission Bitmap*/
689         SET_VHT_BF_REPORT_POLL_FEEDBACK_SEG_RETRAN_BITMAP(p_bf_rpt_poll, 0xFF);
690
691         *p_length = 17;
692
693         RT_DISP_DATA(FBEAM, FBEAM_DATA, "construct_vht_bf_report_poll():\n", buffer, *p_length);
694
695 }
696
697 boolean
698 send_sw_vht_bf_report_poll(
699         void                    *p_dm_void,
700         u8                      *RA,
701         boolean                 is_final_poll
702 )
703 {
704         struct PHY_DM_STRUCT                            *p_dm_odm = (struct PHY_DM_STRUCT *)p_dm_void;
705         PRT_TCB                                 p_tcb;
706         PRT_TX_LOCAL_BUFFER             p_buf;
707         boolean                                 ret = true;
708         u8                                      idx = 0, data_rate = 0;
709         struct _RT_BEAMFORMING_INFO     *p_beam_info = &(p_dm_odm->beamforming_info);
710         struct _RT_BEAMFORMEE_ENTRY     *p_beamform_entry = phydm_beamforming_get_bfee_entry_by_addr(p_dm_odm, RA, &idx);
711         struct _ADAPTER                         *adapter = p_beam_info->source_adapter;
712
713         ODM_RT_TRACE(p_dm_odm, PHYDM_COMP_TXBF, ODM_DBG_LOUD, ("[%s] Start!\n", __func__));
714
715         PlatformAcquireSpinLock(adapter, RT_TX_SPINLOCK);
716
717         if (MgntGetBuffer(adapter, &p_tcb, &p_buf)) {
718                 construct_vht_bf_report_poll(
719                         p_dm_odm,
720                         RA,
721                         p_buf->Buffer.VirtualAddress,
722                         &p_tcb->PacketLength
723                 );
724
725                 p_tcb->bTxEnableSwCalcDur = true; /* <tynli_note> need?*/
726                 p_tcb->BWOfPacket = CHANNEL_WIDTH_20;
727
728                 if (is_final_poll)
729                         p_tcb->TxBFPktType = RT_BF_PKT_TYPE_FINAL_BF_REPORT_POLL;
730                 else
731                         p_tcb->TxBFPktType = RT_BF_PKT_TYPE_BF_REPORT_POLL;
732
733                 data_rate = MGN_6M;     /* Legacy OFDM rate*/
734                 MgntSendPacket(adapter, p_tcb, p_buf, p_tcb->PacketLength, NORMAL_QUEUE, data_rate);
735         } else
736                 ret = false;
737
738         PlatformReleaseSpinLock(adapter, RT_TX_SPINLOCK);
739
740         if (ret)
741                 RT_DISP_DATA(FBEAM, FBEAM_DATA, "send_sw_vht_bf_report_poll():\n", p_buf->Buffer.VirtualAddress, p_tcb->PacketLength);
742
743         return ret;
744
745 }
746
747
748 /*
749  * Description: Construct VHT MU NDPA packet.
750  *      <Note> We should combine this function with construct_vht_ndpa_packet() in the future.
751  *
752  * 2015.05.21. Created by tynli.
753  */
754 void
755 construct_vht_mu_ndpa_packet(
756         struct PHY_DM_STRUCT            *p_dm_odm,
757         CHANNEL_WIDTH   BW,
758         u8                      *buffer,
759         u32                     *p_length
760 )
761 {
762         struct _RT_BEAMFORMING_INFO     *p_beam_info = &(p_dm_odm->beamforming_info);
763         struct _ADAPTER                         *adapter = p_beam_info->source_adapter;
764         u16                                     duration = 0;
765         u8                                      sequence = 0;
766         u8                                      *p_ndpa_frame = buffer;
767         struct _RT_NDPA_STA_INFO                sta_info;
768         u8                                      idx;
769         u8                                      dest_addr[6] = {0};
770         struct _RT_BEAMFORMEE_ENTRY     *p_entry = NULL;
771
772         /* Fill the first MU BFee entry (STA1) MAC addr to destination address then
773              HW will change A1 to broadcast addr. 2015.05.28. Suggested by SD1 Chunchu. */
774         for (idx = 0; idx < BEAMFORMEE_ENTRY_NUM; idx++) {
775                 p_entry = &(p_beam_info->beamformee_entry[idx]);
776                 if (p_entry->is_mu_sta) {
777                         cp_mac_addr(dest_addr, p_entry->mac_addr);
778                         break;
779                 }
780         }
781         if (p_entry == NULL)
782                 return;
783
784         /* Frame control.*/
785         SET_80211_HDR_FRAME_CONTROL(p_ndpa_frame, 0);
786         SET_80211_HDR_TYPE_AND_SUBTYPE(p_ndpa_frame, Type_NDPA);
787
788         SET_80211_HDR_ADDRESS1(p_ndpa_frame, dest_addr);
789         SET_80211_HDR_ADDRESS2(p_ndpa_frame, p_entry->my_mac_addr);
790
791         /*--------------------------------------------*/
792         /* <Note> Need to modify "duration" to MU consideration. */
793         duration = 2 * a_SifsTime + 44;
794
795         if (BW == CHANNEL_WIDTH_80)
796                 duration += 40;
797         else if (BW == CHANNEL_WIDTH_40)
798                 duration += 87;
799         else
800                 duration += 180;
801         /*--------------------------------------------*/
802
803         SET_80211_HDR_DURATION(p_ndpa_frame, duration);
804
805         sequence = *(p_dm_odm->p_sounding_seq) << 2;
806         odm_move_memory(p_dm_odm, p_ndpa_frame + 16, &sequence, 1);
807
808         *p_length = 17;
809
810         /* Construct STA info. for multiple STAs*/
811         for (idx = 0; idx < BEAMFORMEE_ENTRY_NUM; idx++) {
812                 p_entry = &(p_beam_info->beamformee_entry[idx]);
813                 if (p_entry->is_mu_sta) {
814                         sta_info.aid = p_entry->AID;
815                         sta_info.feedback_type = 1; /* 1'b1: MU*/
816                         sta_info.nc_index = 0;
817
818                         ODM_RT_TRACE(p_dm_odm, PHYDM_COMP_TXBF, ODM_DBG_LOUD, ("[%s] Get beamformee_entry idx(%d), AID =%d\n", __func__, idx, p_entry->AID));
819
820                         odm_move_memory(p_dm_odm, p_ndpa_frame + (*p_length), (u8 *)&sta_info, 2);
821                         *p_length += 2;
822                 }
823         }
824
825 }
826
827 boolean
828 send_sw_vht_mu_ndpa_packet(
829         void                    *p_dm_void,
830         CHANNEL_WIDTH   BW
831 )
832 {
833         struct PHY_DM_STRUCT                            *p_dm_odm = (struct PHY_DM_STRUCT *)p_dm_void;
834         PRT_TCB                                 p_tcb;
835         PRT_TX_LOCAL_BUFFER             p_buf;
836         boolean                                 ret = true;
837         u8                                      ndp_tx_rate = 0;
838         struct _RT_BEAMFORMING_INFO     *p_beam_info = &(p_dm_odm->beamforming_info);
839         struct _ADAPTER                         *adapter = p_beam_info->source_adapter;
840
841         ndp_tx_rate = MGN_VHT2SS_MCS0;
842         ODM_RT_TRACE(p_dm_odm, PHYDM_COMP_TXBF, ODM_DBG_LOUD, ("[%s] ndp_tx_rate =%d\n", __func__, ndp_tx_rate));
843
844         PlatformAcquireSpinLock(adapter, RT_TX_SPINLOCK);
845
846         if (MgntGetBuffer(adapter, &p_tcb, &p_buf)) {
847                 construct_vht_mu_ndpa_packet(
848                         p_dm_odm,
849                         BW,
850                         p_buf->Buffer.VirtualAddress,
851                         &p_tcb->PacketLength
852                 );
853
854                 p_tcb->bTxEnableSwCalcDur = true;
855                 p_tcb->BWOfPacket = BW;
856                 p_tcb->TxBFPktType = RT_BF_PKT_TYPE_BROADCAST_NDPA;
857
858                 /*rate of NDP decide by nr*/
859                 MgntSendPacket(adapter, p_tcb, p_buf, p_tcb->PacketLength, NORMAL_QUEUE, ndp_tx_rate);
860         } else
861                 ret = false;
862
863         PlatformReleaseSpinLock(adapter, RT_TX_SPINLOCK);
864
865         if (ret)
866                 RT_DISP_DATA(FBEAM, FBEAM_DATA, "", p_buf->Buffer.VirtualAddress, p_tcb->PacketLength);
867
868         return ret;
869 }
870
871
872 void
873 dbg_construct_vht_mundpa_packet(
874         struct PHY_DM_STRUCT            *p_dm_odm,
875         CHANNEL_WIDTH   BW,
876         u8                      *buffer,
877         u32                     *p_length
878 )
879 {
880         struct _RT_BEAMFORMING_INFO     *p_beam_info = &(p_dm_odm->beamforming_info);
881         struct _ADAPTER                         *adapter = p_beam_info->source_adapter;
882         u16                                     duration = 0;
883         u8                                      sequence = 0;
884         u8                                      *p_ndpa_frame = buffer;
885         struct _RT_NDPA_STA_INFO                sta_info;
886         u8                                      idx;
887         u8                                      dest_addr[6] = {0};
888         struct _RT_BEAMFORMEE_ENTRY     *p_entry = NULL;
889
890         boolean is_STA1 = false;
891
892
893         /* Fill the first MU BFee entry (STA1) MAC addr to destination address then
894              HW will change A1 to broadcast addr. 2015.05.28. Suggested by SD1 Chunchu. */
895         for (idx = 0; idx < BEAMFORMEE_ENTRY_NUM; idx++) {
896                 p_entry = &(p_beam_info->beamformee_entry[idx]);
897                 if (p_entry->is_mu_sta) {
898                         if (is_STA1 == false) {
899                                 is_STA1 = true;
900                                 continue;
901                         } else {
902                                 cp_mac_addr(dest_addr, p_entry->mac_addr);
903                                 break;
904                         }
905                 }
906         }
907
908         /* Frame control.*/
909         SET_80211_HDR_FRAME_CONTROL(p_ndpa_frame, 0);
910         SET_80211_HDR_TYPE_AND_SUBTYPE(p_ndpa_frame, Type_NDPA);
911
912         SET_80211_HDR_ADDRESS1(p_ndpa_frame, dest_addr);
913         SET_80211_HDR_ADDRESS2(p_ndpa_frame, p_dm_odm->CurrentAddress);
914
915         /*--------------------------------------------*/
916         /* <Note> Need to modify "duration" to MU consideration. */
917         duration = 2 * a_SifsTime + 44;
918
919         if (BW == CHANNEL_WIDTH_80)
920                 duration += 40;
921         else if (BW == CHANNEL_WIDTH_40)
922                 duration += 87;
923         else
924                 duration += 180;
925         /*--------------------------------------------*/
926
927         SET_80211_HDR_DURATION(p_ndpa_frame, duration);
928
929         sequence = *(p_dm_odm->p_sounding_seq) << 2;
930         odm_move_memory(p_dm_odm, p_ndpa_frame + 16, &sequence, 1);
931
932         *p_length = 17;
933
934         /*STA2's STA Info*/
935         sta_info.aid = p_entry->aid;
936         sta_info.feedback_type = 1; /* 1'b1: MU */
937         sta_info.nc_index = 0;
938
939         ODM_RT_TRACE(p_dm_odm, PHYDM_COMP_TXBF, ODM_DBG_LOUD, ("[%s] Get beamformee_entry idx(%d), AID =%d\n", __func__, idx, p_entry->aid));
940
941         odm_move_memory(p_dm_odm, p_ndpa_frame + (*p_length), (u8 *)&sta_info, 2);
942         *p_length += 2;
943
944 }
945
946 boolean
947 dbg_send_sw_vht_mundpa_packet(
948         void                    *p_dm_void,
949         CHANNEL_WIDTH   BW
950 )
951 {
952         struct PHY_DM_STRUCT                            *p_dm_odm = (struct PHY_DM_STRUCT *)p_dm_void;
953         PRT_TCB                                 p_tcb;
954         PRT_TX_LOCAL_BUFFER             p_buf;
955         boolean                                 ret = true;
956         u8                                      ndp_tx_rate = 0;
957         struct _RT_BEAMFORMING_INFO     *p_beam_info = &(p_dm_odm->beamforming_info);
958         struct _ADAPTER                         *adapter = p_beam_info->source_adapter;
959
960         ndp_tx_rate = MGN_VHT2SS_MCS0;
961         ODM_RT_TRACE(p_dm_odm, PHYDM_COMP_TXBF, ODM_DBG_LOUD, ("[%s] ndp_tx_rate =%d\n", __func__, ndp_tx_rate));
962
963         PlatformAcquireSpinLock(adapter, RT_TX_SPINLOCK);
964
965         if (MgntGetBuffer(adapter, &p_tcb, &p_buf)) {
966                 dbg_construct_vht_mundpa_packet(
967                         p_dm_odm,
968                         BW,
969                         p_buf->Buffer.VirtualAddress,
970                         &p_tcb->PacketLength
971                 );
972
973                 p_tcb->bTxEnableSwCalcDur = true;
974                 p_tcb->BWOfPacket = BW;
975                 p_tcb->TxBFPktType = RT_BF_PKT_TYPE_UNICAST_NDPA;
976
977                 /*rate of NDP decide by nr*/
978                 MgntSendPacket(adapter, p_tcb, p_buf, p_tcb->PacketLength, NORMAL_QUEUE, ndp_tx_rate);
979         } else
980                 ret = false;
981
982         PlatformReleaseSpinLock(adapter, RT_TX_SPINLOCK);
983
984         if (ret)
985                 RT_DISP_DATA(FBEAM, FBEAM_DATA, "", p_buf->Buffer.VirtualAddress, p_tcb->PacketLength);
986
987         return ret;
988 }
989
990
991 #endif  /*#if (SUPPORT_MU_BF == 1)*/
992 #endif  /*#ifdef SUPPORT_MU_BF*/
993
994
995 #elif (DM_ODM_SUPPORT_TYPE == ODM_CE)
996
997 u32
998 beamforming_get_report_frame(
999         void                    *p_dm_void,
1000         union recv_frame *precv_frame
1001 )
1002 {
1003         struct PHY_DM_STRUCT                            *p_dm_odm = (struct PHY_DM_STRUCT *)p_dm_void;
1004         u32                                     ret = _SUCCESS;
1005         struct _RT_BEAMFORMEE_ENTRY     *p_beamform_entry = NULL;
1006         u8                                      *pframe = precv_frame->u.hdr.rx_data;
1007         u32                                     frame_len = precv_frame->u.hdr.len;
1008         u8                                      *TA;
1009         u8                                      idx, offset;
1010
1011
1012         /*Memory comparison to see if CSI report is the same with previous one*/
1013         TA = get_addr2_ptr(pframe);
1014         p_beamform_entry = phydm_beamforming_get_bfee_entry_by_addr(p_dm_odm, TA, &idx);
1015         if (p_beamform_entry->beamform_entry_cap & BEAMFORMER_CAP_VHT_SU)
1016                 offset = 31;            /*24+(1+1+3)+2  MAC header+(Category+ActionCode+MIMOControlField)+SNR(nc=2)*/
1017         else if (p_beamform_entry->beamform_entry_cap & BEAMFORMER_CAP_HT_EXPLICIT)
1018                 offset = 34;            /*24+(1+1+6)+2  MAC header+(Category+ActionCode+MIMOControlField)+SNR(nc=2)*/
1019         else
1020                 return ret;
1021
1022
1023         return ret;
1024 }
1025
1026
1027 boolean
1028 send_fw_ht_ndpa_packet(
1029         void                    *p_dm_void,
1030         u8                      *RA,
1031         CHANNEL_WIDTH   BW
1032 )
1033 {
1034         struct PHY_DM_STRUCT                            *p_dm_odm = (struct PHY_DM_STRUCT *)p_dm_void;
1035         struct _ADAPTER                         *adapter = p_dm_odm->adapter;
1036         struct xmit_frame               *pmgntframe;
1037         struct pkt_attrib               *pattrib;
1038         struct rtw_ieee80211_hdr        *pwlanhdr;
1039         struct xmit_priv                *pxmitpriv = &(adapter->xmitpriv);
1040         struct mlme_ext_priv    *pmlmeext = &adapter->mlmeextpriv;
1041         struct mlme_ext_info    *pmlmeinfo = &(pmlmeext->mlmext_info);
1042         u8      action_hdr[4] = {ACT_CAT_VENDOR, 0x00, 0xe0, 0x4c};
1043         u8      *pframe;
1044         u16     *fctrl;
1045         u16     duration = 0;
1046         u8      a_sifs_time = 0, ndp_tx_rate = 0, idx = 0;
1047         struct _RT_BEAMFORMING_INFO     *p_beam_info = &(p_dm_odm->beamforming_info);
1048         struct _RT_BEAMFORMEE_ENTRY     *p_beamform_entry = phydm_beamforming_get_bfee_entry_by_addr(p_dm_odm, RA, &idx);
1049
1050         pmgntframe = alloc_mgtxmitframe(pxmitpriv);
1051
1052         if (pmgntframe == NULL) {
1053                 ODM_RT_TRACE(p_dm_odm, PHYDM_COMP_TXBF, ODM_DBG_LOUD, ("%s, alloc mgnt frame fail\n", __func__));
1054                 return _FALSE;
1055         }
1056
1057         /* update attribute */
1058         pattrib = &pmgntframe->attrib;
1059         update_mgntframe_attrib(adapter, pattrib);
1060
1061         pattrib->qsel = QSLT_BEACON;
1062         ndp_tx_rate = beamforming_get_htndp_tx_rate(p_dm_odm, p_beamform_entry->comp_steering_num_of_bfer);
1063         ODM_RT_TRACE(p_dm_odm, PHYDM_COMP_TXBF, ODM_DBG_LOUD, ("[%s] ndp_tx_rate =%d\n", __func__, ndp_tx_rate));
1064         pattrib->rate = ndp_tx_rate;
1065         pattrib->bwmode = BW;
1066         pattrib->order = 1;
1067         pattrib->subtype = WIFI_ACTION_NOACK;
1068
1069         _rtw_memset(pmgntframe->buf_addr, 0, WLANHDR_OFFSET + TXDESC_OFFSET);
1070
1071         pframe = (u8 *)(pmgntframe->buf_addr) + TXDESC_OFFSET;
1072
1073         pwlanhdr = (struct rtw_ieee80211_hdr *)pframe;
1074
1075         fctrl = &pwlanhdr->frame_ctl;
1076         *(fctrl) = 0;
1077
1078         set_order_bit(pframe);
1079         set_frame_sub_type(pframe, WIFI_ACTION_NOACK);
1080
1081         _rtw_memcpy(pwlanhdr->addr1, RA, ETH_ALEN);
1082         _rtw_memcpy(pwlanhdr->addr2, p_beamform_entry->my_mac_addr, ETH_ALEN);
1083         _rtw_memcpy(pwlanhdr->addr3, get_my_bssid(&(pmlmeinfo->network)), ETH_ALEN);
1084
1085         if (pmlmeext->cur_wireless_mode == WIRELESS_11B)
1086                 a_sifs_time = 10;
1087         else
1088                 a_sifs_time = 16;
1089
1090         duration = 2 * a_sifs_time + 40;
1091
1092         if (BW == CHANNEL_WIDTH_40)
1093                 duration += 87;
1094         else
1095                 duration += 180;
1096
1097         set_duration(pframe, duration);
1098
1099         /* HT control field */
1100         SET_HT_CTRL_CSI_STEERING(pframe + 24, 3);
1101         SET_HT_CTRL_NDP_ANNOUNCEMENT(pframe + 24, 1);
1102
1103         _rtw_memcpy(pframe + 28, action_hdr, 4);
1104
1105         pattrib->pktlen = 32;
1106
1107         pattrib->last_txcmdsz = pattrib->pktlen;
1108
1109         dump_mgntframe(adapter, pmgntframe);
1110
1111         return _TRUE;
1112 }
1113
1114
1115 boolean
1116 send_sw_ht_ndpa_packet(
1117         void                    *p_dm_void,
1118         u8                      *RA,
1119         CHANNEL_WIDTH   BW
1120 )
1121 {
1122         struct PHY_DM_STRUCT                            *p_dm_odm = (struct PHY_DM_STRUCT *)p_dm_void;
1123         struct _ADAPTER                         *adapter = p_dm_odm->adapter;
1124         struct xmit_frame               *pmgntframe;
1125         struct pkt_attrib               *pattrib;
1126         struct rtw_ieee80211_hdr        *pwlanhdr;
1127         struct xmit_priv                *pxmitpriv = &(adapter->xmitpriv);
1128         struct mlme_ext_priv    *pmlmeext = &adapter->mlmeextpriv;
1129         struct mlme_ext_info    *pmlmeinfo = &(pmlmeext->mlmext_info);
1130         u8      action_hdr[4] = {ACT_CAT_VENDOR, 0x00, 0xe0, 0x4c};
1131         u8      *pframe;
1132         u16     *fctrl;
1133         u16     duration = 0;
1134         u8      a_sifs_time = 0, ndp_tx_rate = 0, idx = 0;
1135         struct _RT_BEAMFORMING_INFO     *p_beam_info = &(p_dm_odm->beamforming_info);
1136         struct _RT_BEAMFORMEE_ENTRY     *p_beamform_entry = phydm_beamforming_get_bfee_entry_by_addr(p_dm_odm, RA, &idx);
1137
1138         ndp_tx_rate = beamforming_get_htndp_tx_rate(p_dm_odm, p_beamform_entry->comp_steering_num_of_bfer);
1139
1140         pmgntframe = alloc_mgtxmitframe(pxmitpriv);
1141
1142         if (pmgntframe == NULL) {
1143                 ODM_RT_TRACE(p_dm_odm, PHYDM_COMP_TXBF, ODM_DBG_LOUD, ("%s, alloc mgnt frame fail\n", __func__));
1144                 return _FALSE;
1145         }
1146
1147         /*update attribute*/
1148         pattrib = &pmgntframe->attrib;
1149         update_mgntframe_attrib(adapter, pattrib);
1150         pattrib->qsel = QSLT_MGNT;
1151         pattrib->rate = ndp_tx_rate;
1152         pattrib->bwmode = BW;
1153         pattrib->order = 1;
1154         pattrib->subtype = WIFI_ACTION_NOACK;
1155
1156         _rtw_memset(pmgntframe->buf_addr, 0, WLANHDR_OFFSET + TXDESC_OFFSET);
1157
1158         pframe = (u8 *)(pmgntframe->buf_addr) + TXDESC_OFFSET;
1159
1160         pwlanhdr = (struct rtw_ieee80211_hdr *)pframe;
1161
1162         fctrl = &pwlanhdr->frame_ctl;
1163         *(fctrl) = 0;
1164
1165         set_order_bit(pframe);
1166         set_frame_sub_type(pframe, WIFI_ACTION_NOACK);
1167
1168         _rtw_memcpy(pwlanhdr->addr1, RA, ETH_ALEN);
1169         _rtw_memcpy(pwlanhdr->addr2, p_beamform_entry->my_mac_addr, ETH_ALEN);
1170         _rtw_memcpy(pwlanhdr->addr3, get_my_bssid(&(pmlmeinfo->network)), ETH_ALEN);
1171
1172         if (pmlmeext->cur_wireless_mode == WIRELESS_11B)
1173                 a_sifs_time = 10;
1174         else
1175                 a_sifs_time = 16;
1176
1177         duration = 2 * a_sifs_time + 40;
1178
1179         if (BW == CHANNEL_WIDTH_40)
1180                 duration += 87;
1181         else
1182                 duration += 180;
1183
1184         set_duration(pframe, duration);
1185
1186         /*HT control field*/
1187         SET_HT_CTRL_CSI_STEERING(pframe + 24, 3);
1188         SET_HT_CTRL_NDP_ANNOUNCEMENT(pframe + 24, 1);
1189
1190         _rtw_memcpy(pframe + 28, action_hdr, 4);
1191
1192         pattrib->pktlen = 32;
1193
1194         pattrib->last_txcmdsz = pattrib->pktlen;
1195
1196         dump_mgntframe(adapter, pmgntframe);
1197
1198         return _TRUE;
1199 }
1200
1201
1202 boolean
1203 send_fw_vht_ndpa_packet(
1204         void                    *p_dm_void,
1205         u8                      *RA,
1206         u16                     AID,
1207         CHANNEL_WIDTH   BW
1208 )
1209 {
1210         struct PHY_DM_STRUCT                            *p_dm_odm = (struct PHY_DM_STRUCT *)p_dm_void;
1211         struct _ADAPTER                         *adapter = p_dm_odm->adapter;
1212         struct xmit_frame               *pmgntframe;
1213         struct pkt_attrib               *pattrib;
1214         struct rtw_ieee80211_hdr        *pwlanhdr;
1215         struct xmit_priv                *pxmitpriv = &(adapter->xmitpriv);
1216         struct mlme_ext_priv    *pmlmeext = &adapter->mlmeextpriv;
1217         struct mlme_ext_info    *pmlmeinfo = &(pmlmeext->mlmext_info);
1218         struct mlme_priv                *pmlmepriv = &(adapter->mlmepriv);
1219         u8      *pframe;
1220         u16     *fctrl;
1221         u16     duration = 0;
1222         u8      sequence = 0, a_sifs_time = 0, ndp_tx_rate = 0, idx = 0;
1223         struct _RT_BEAMFORMING_INFO     *p_beam_info = &(p_dm_odm->beamforming_info);
1224         struct _RT_BEAMFORMEE_ENTRY     *p_beamform_entry = phydm_beamforming_get_bfee_entry_by_addr(p_dm_odm, RA, &idx);
1225         struct _RT_NDPA_STA_INFO        sta_info;
1226
1227         pmgntframe = alloc_mgtxmitframe(pxmitpriv);
1228
1229         if (pmgntframe == NULL) {
1230                 ODM_RT_TRACE(p_dm_odm, PHYDM_COMP_TXBF, ODM_DBG_LOUD, ("%s, alloc mgnt frame fail\n", __func__));
1231                 return _FALSE;
1232         }
1233
1234         /* update attribute */
1235         pattrib = &pmgntframe->attrib;
1236         _rtw_memcpy(pattrib->ra, RA, ETH_ALEN);
1237         update_mgntframe_attrib(adapter, pattrib);
1238
1239         pattrib->qsel = QSLT_BEACON;
1240         ndp_tx_rate = beamforming_get_vht_ndp_tx_rate(p_dm_odm, p_beamform_entry->comp_steering_num_of_bfer);
1241         ODM_RT_TRACE(p_dm_odm, PHYDM_COMP_TXBF, ODM_DBG_LOUD, ("[%s] ndp_tx_rate =%d\n", __func__, ndp_tx_rate));
1242         pattrib->rate = ndp_tx_rate;
1243         pattrib->bwmode = BW;
1244         pattrib->subtype = WIFI_NDPA;
1245
1246         _rtw_memset(pmgntframe->buf_addr, 0, WLANHDR_OFFSET + TXDESC_OFFSET);
1247
1248         pframe = (u8 *)(pmgntframe->buf_addr) + TXDESC_OFFSET;
1249
1250         pwlanhdr = (struct rtw_ieee80211_hdr *)pframe;
1251
1252         fctrl = &pwlanhdr->frame_ctl;
1253         *(fctrl) = 0;
1254
1255         set_frame_sub_type(pframe, WIFI_NDPA);
1256
1257         _rtw_memcpy(pwlanhdr->addr1, RA, ETH_ALEN);
1258         _rtw_memcpy(pwlanhdr->addr2, p_beamform_entry->my_mac_addr, ETH_ALEN);
1259
1260         if (is_supported_5g(pmlmeext->cur_wireless_mode) || is_supported_ht(pmlmeext->cur_wireless_mode))
1261                 a_sifs_time = 16;
1262         else
1263                 a_sifs_time = 10;
1264
1265         duration = 2 * a_sifs_time + 44;
1266
1267         if (BW == CHANNEL_WIDTH_80)
1268                 duration += 40;
1269         else if (BW == CHANNEL_WIDTH_40)
1270                 duration += 87;
1271         else
1272                 duration += 180;
1273
1274         set_duration(pframe, duration);
1275
1276         sequence = p_beam_info->sounding_sequence << 2;
1277         if (p_beam_info->sounding_sequence >= 0x3f)
1278                 p_beam_info->sounding_sequence = 0;
1279         else
1280                 p_beam_info->sounding_sequence++;
1281
1282         _rtw_memcpy(pframe + 16, &sequence, 1);
1283
1284         if (((pmlmeinfo->state & 0x03) == WIFI_FW_ADHOC_STATE) || ((pmlmeinfo->state & 0x03) == WIFI_FW_AP_STATE))
1285                 AID = 0;
1286
1287         sta_info.aid = AID;
1288         sta_info.feedback_type = 0;
1289         sta_info.nc_index = 0;
1290
1291         _rtw_memcpy(pframe + 17, (u8 *)&sta_info, 2);
1292
1293         pattrib->pktlen = 19;
1294
1295         pattrib->last_txcmdsz = pattrib->pktlen;
1296
1297         dump_mgntframe(adapter, pmgntframe);
1298
1299         return _TRUE;
1300 }
1301
1302
1303
1304 boolean
1305 send_sw_vht_ndpa_packet(
1306         void                    *p_dm_void,
1307         u8                      *RA,
1308         u16                     AID,
1309         CHANNEL_WIDTH   BW
1310 )
1311 {
1312         struct PHY_DM_STRUCT                            *p_dm_odm = (struct PHY_DM_STRUCT *)p_dm_void;
1313         struct _ADAPTER                         *adapter = p_dm_odm->adapter;
1314         struct xmit_frame               *pmgntframe;
1315         struct pkt_attrib               *pattrib;
1316         struct rtw_ieee80211_hdr        *pwlanhdr;
1317         struct xmit_priv                *pxmitpriv = &(adapter->xmitpriv);
1318         struct mlme_ext_priv    *pmlmeext = &adapter->mlmeextpriv;
1319         struct mlme_ext_info    *pmlmeinfo = &(pmlmeext->mlmext_info);
1320         struct mlme_priv                *pmlmepriv = &(adapter->mlmepriv);
1321         struct _RT_NDPA_STA_INFO        ndpa_sta_info;
1322         u8      ndp_tx_rate = 0, sequence = 0, a_sifs_time = 0, idx = 0;
1323         u8      *pframe;
1324         u16     *fctrl;
1325         u16     duration = 0;
1326         struct _RT_BEAMFORMING_INFO     *p_beam_info = &(p_dm_odm->beamforming_info);
1327         struct _RT_BEAMFORMEE_ENTRY     *p_beamform_entry = phydm_beamforming_get_bfee_entry_by_addr(p_dm_odm, RA, &idx);
1328
1329         ndp_tx_rate = beamforming_get_vht_ndp_tx_rate(p_dm_odm, p_beamform_entry->comp_steering_num_of_bfer);
1330         ODM_RT_TRACE(p_dm_odm, PHYDM_COMP_TXBF, ODM_DBG_LOUD, ("[%s] ndp_tx_rate =%d\n", __func__, ndp_tx_rate));
1331
1332         pmgntframe = alloc_mgtxmitframe(pxmitpriv);
1333
1334         if (pmgntframe == NULL) {
1335                 ODM_RT_TRACE(p_dm_odm, PHYDM_COMP_TXBF, ODM_DBG_LOUD, ("%s, alloc mgnt frame fail\n", __func__));
1336                 return _FALSE;
1337         }
1338
1339         /*update attribute*/
1340         pattrib = &pmgntframe->attrib;
1341         _rtw_memcpy(pattrib->ra, RA, ETH_ALEN);
1342         update_mgntframe_attrib(adapter, pattrib);
1343         pattrib->qsel = QSLT_MGNT;
1344         pattrib->rate = ndp_tx_rate;
1345         pattrib->bwmode = BW;
1346         pattrib->subtype = WIFI_NDPA;
1347
1348         _rtw_memset(pmgntframe->buf_addr, 0, WLANHDR_OFFSET + TXDESC_OFFSET);
1349
1350         pframe = (u8 *)(pmgntframe->buf_addr) + TXDESC_OFFSET;
1351
1352         pwlanhdr = (struct rtw_ieee80211_hdr *)pframe;
1353
1354         fctrl = &pwlanhdr->frame_ctl;
1355         *(fctrl) = 0;
1356
1357         set_frame_sub_type(pframe, WIFI_NDPA);
1358
1359         _rtw_memcpy(pwlanhdr->addr1, RA, ETH_ALEN);
1360         _rtw_memcpy(pwlanhdr->addr2, p_beamform_entry->my_mac_addr, ETH_ALEN);
1361
1362         if (is_supported_5g(pmlmeext->cur_wireless_mode) || is_supported_ht(pmlmeext->cur_wireless_mode))
1363                 a_sifs_time = 16;
1364         else
1365                 a_sifs_time = 10;
1366
1367         duration = 2 * a_sifs_time + 44;
1368
1369         if (BW == CHANNEL_WIDTH_80)
1370                 duration += 40;
1371         else if (BW == CHANNEL_WIDTH_40)
1372                 duration += 87;
1373         else
1374                 duration += 180;
1375
1376         set_duration(pframe, duration);
1377
1378         sequence = p_beam_info->sounding_sequence << 2;
1379         if (p_beam_info->sounding_sequence >= 0x3f)
1380                 p_beam_info->sounding_sequence = 0;
1381         else
1382                 p_beam_info->sounding_sequence++;
1383
1384         _rtw_memcpy(pframe + 16, &sequence, 1);
1385         if (((pmlmeinfo->state & 0x03) == WIFI_FW_ADHOC_STATE) || ((pmlmeinfo->state & 0x03) == WIFI_FW_AP_STATE))
1386                 AID = 0;
1387
1388         ndpa_sta_info.aid = AID;
1389         ndpa_sta_info.feedback_type = 0;
1390         ndpa_sta_info.nc_index = 0;
1391
1392         _rtw_memcpy(pframe + 17, (u8 *)&ndpa_sta_info, 2);
1393
1394         pattrib->pktlen = 19;
1395
1396         pattrib->last_txcmdsz = pattrib->pktlen;
1397
1398         dump_mgntframe(adapter, pmgntframe);
1399         ODM_RT_TRACE(p_dm_odm, PHYDM_COMP_TXBF, ODM_DBG_LOUD, ("[%s] [%d]\n", __func__, __LINE__));
1400
1401         return _TRUE;
1402 }
1403
1404
1405 #endif
1406
1407
1408 void
1409 beamforming_get_ndpa_frame(
1410         void                    *p_dm_void,
1411 #if (DM_ODM_SUPPORT_TYPE == ODM_WIN)
1412         OCTET_STRING    pdu_os
1413 #elif (DM_ODM_SUPPORT_TYPE == ODM_CE)
1414         union recv_frame *precv_frame
1415 #endif
1416 )
1417 {
1418         struct PHY_DM_STRUCT                                    *p_dm_odm = (struct PHY_DM_STRUCT *)p_dm_void;
1419         struct _ADAPTER                                 *adapter = p_dm_odm->adapter;
1420         u8                                              *TA ;
1421         u8                                              idx, sequence;
1422 #if (DM_ODM_SUPPORT_TYPE == ODM_WIN)
1423         u8                                              *p_ndpa_frame = pdu_os.Octet;
1424 #elif (DM_ODM_SUPPORT_TYPE == ODM_CE)
1425         u8                                              *p_ndpa_frame = precv_frame->u.hdr.rx_data;
1426 #endif
1427         struct _RT_BEAMFORMER_ENTRY             *p_beamformer_entry = NULL;             /*Modified By Jeffery @2014-10-29*/
1428
1429
1430 #if (DM_ODM_SUPPORT_TYPE == ODM_WIN)
1431         RT_DISP_DATA(FBEAM, FBEAM_DATA, "beamforming_get_ndpa_frame\n", pdu_os.Octet, pdu_os.Length);
1432         if (IsCtrlNDPA(p_ndpa_frame) == false)
1433 #elif (DM_ODM_SUPPORT_TYPE == ODM_CE)
1434         if (get_frame_sub_type(p_ndpa_frame) != WIFI_NDPA)
1435 #endif
1436                 return;
1437         else if (!(p_dm_odm->support_ic_type & (ODM_RTL8812 | ODM_RTL8821))) {
1438                 ODM_RT_TRACE(p_dm_odm, PHYDM_COMP_TXBF, ODM_DBG_LOUD, ("[%s] not 8812 or 8821A, return\n", __func__));
1439                 return;
1440         }
1441 #if (DM_ODM_SUPPORT_TYPE == ODM_WIN)
1442         TA = Frame_Addr2(pdu_os);
1443 #elif (DM_ODM_SUPPORT_TYPE == ODM_CE)
1444         TA = get_addr2_ptr(p_ndpa_frame);
1445 #endif
1446         /*Remove signaling TA. */
1447         TA[0] = TA[0] & 0xFE;
1448
1449         p_beamformer_entry = phydm_beamforming_get_bfer_entry_by_addr(p_dm_odm, TA, &idx);              /* Modified By Jeffery @2014-10-29 */
1450
1451         /*Break options for Clock Reset*/
1452         if (p_beamformer_entry == NULL)
1453                 return;
1454         else if (!(p_beamformer_entry->beamform_entry_cap & BEAMFORMEE_CAP_VHT_SU))
1455                 return;
1456         /*log_success: As long as 8812A receive NDPA and feedback CSI succeed once, clock reset is NO LONGER needed !2015-04-10, Jeffery*/
1457         /*clock_reset_times: While BFer entry always doesn't receive our CSI, clock will reset again and again.So clock_reset_times is limited to 5 times.2015-04-13, Jeffery*/
1458         else if ((p_beamformer_entry->log_success == 1) || (p_beamformer_entry->clock_reset_times == 5)) {
1459                 ODM_RT_TRACE(p_dm_odm, PHYDM_COMP_TXBF, ODM_DBG_LOUD, ("[%s] log_seq=%d, pre_log_seq=%d, log_retry_cnt=%d, log_success=%d, clock_reset_times=%d, clock reset is no longer needed.\n",
1460                         __func__, p_beamformer_entry->log_seq, p_beamformer_entry->pre_log_seq, p_beamformer_entry->log_retry_cnt, p_beamformer_entry->log_success, p_beamformer_entry->clock_reset_times));
1461
1462                 return;
1463         }
1464
1465         sequence = (p_ndpa_frame[16]) >> 2;
1466
1467         ODM_RT_TRACE(p_dm_odm, PHYDM_COMP_TXBF, ODM_DBG_LOUD, ("[%s] Start, sequence=%d, log_seq=%d, pre_log_seq=%d, log_retry_cnt=%d, clock_reset_times=%d, log_success=%d\n",
1468                 __func__, sequence, p_beamformer_entry->log_seq, p_beamformer_entry->pre_log_seq, p_beamformer_entry->log_retry_cnt, p_beamformer_entry->clock_reset_times, p_beamformer_entry->log_success));
1469
1470         if ((p_beamformer_entry->log_seq != 0) && (p_beamformer_entry->pre_log_seq != 0)) {
1471                 /*Success condition*/
1472                 if ((p_beamformer_entry->log_seq != sequence) && (p_beamformer_entry->pre_log_seq != p_beamformer_entry->log_seq)) {
1473                         /* break option for clcok reset, 2015-03-30, Jeffery */
1474                         p_beamformer_entry->log_retry_cnt = 0;
1475                         /*As long as 8812A receive NDPA and feedback CSI succeed once, clock reset is no longer needed.*/
1476                         /*That is, log_success is NOT needed to be reset to zero, 2015-04-13, Jeffery*/
1477                         p_beamformer_entry->log_success = 1;
1478
1479                 } else {/*Fail condition*/
1480
1481                         if (p_beamformer_entry->log_retry_cnt == 5) {
1482                                 p_beamformer_entry->clock_reset_times++;
1483                                 p_beamformer_entry->log_retry_cnt = 0;
1484
1485                                 ODM_RT_TRACE(p_dm_odm, PHYDM_COMP_TXBF, ODM_DBG_LOUD, ("[%s] Clock Reset!!! clock_reset_times=%d\n",
1486                                         __func__, p_beamformer_entry->clock_reset_times));
1487                                 hal_com_txbf_set(p_dm_odm, TXBF_SET_SOUNDING_CLK, NULL);
1488
1489                         } else
1490                                 p_beamformer_entry->log_retry_cnt++;
1491                 }
1492         }
1493
1494         /*Update log_seq & pre_log_seq*/
1495         p_beamformer_entry->pre_log_seq = p_beamformer_entry->log_seq;
1496         p_beamformer_entry->log_seq = sequence;
1497
1498 }
1499
1500
1501
1502 #endif