1 /******************************************************************************
\r
3 * Copyright(c) 2007 - 2011 Realtek Corporation. All rights reserved.
\r
5 * This program is free software; you can redistribute it and/or modify it
\r
6 * under the terms of version 2 of the GNU General Public License as
\r
7 * published by the Free Software Foundation.
\r
9 * This program is distributed in the hope that it will be useful, but WITHOUT
\r
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
\r
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
\r
14 * You should have received a copy of the GNU General Public License along with
\r
15 * this program; if not, write to the Free Software Foundation, Inc.,
\r
16 * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
\r
19 ******************************************************************************/
\r
20 #define _RTW_BEAMFORMING_C_
\r
22 #include <drv_types.h>
\r
23 #include <hal_data.h>
\r
25 #ifdef CONFIG_BEAMFORMING
\r
27 #if (BEAMFORMING_SUPPORT == 0) /*for diver defined beamforming*/
\r
28 struct beamforming_entry *beamforming_get_entry_by_addr(struct mlme_priv *pmlmepriv, u8* ra,u8* idx)
\r
31 struct beamforming_info *pBeamInfo = GET_BEAMFORM_INFO(pmlmepriv);
\r
33 for(i = 0; i < BEAMFORMING_ENTRY_NUM; i++)
\r
35 if( pBeamInfo->beamforming_entry[i].bUsed &&
\r
36 (_rtw_memcmp(ra,pBeamInfo->beamforming_entry[i].mac_addr, ETH_ALEN)))
\r
39 return &(pBeamInfo->beamforming_entry[i]);
\r
46 BEAMFORMING_CAP beamforming_get_entry_beam_cap_by_mac_id(PVOID pmlmepriv ,u8 mac_id)
\r
49 struct beamforming_info *pBeamInfo = GET_BEAMFORM_INFO((struct mlme_priv *)pmlmepriv);
\r
50 BEAMFORMING_CAP BeamformEntryCap = BEAMFORMING_CAP_NONE;
\r
52 for(i = 0; i < BEAMFORMING_ENTRY_NUM; i++)
\r
54 if( pBeamInfo->beamforming_entry[i].bUsed &&
\r
55 (mac_id == pBeamInfo->beamforming_entry[i].mac_id))
\r
57 BeamformEntryCap = pBeamInfo->beamforming_entry[i].beamforming_entry_cap;
\r
58 i = BEAMFORMING_ENTRY_NUM;
\r
62 return BeamformEntryCap;
\r
65 struct beamforming_entry *beamforming_get_free_entry(struct mlme_priv *pmlmepriv, u8* idx)
\r
68 struct beamforming_info *pBeamInfo = GET_BEAMFORM_INFO(pmlmepriv);
\r
70 for(i = 0; i < BEAMFORMING_ENTRY_NUM; i++)
\r
72 if(pBeamInfo->beamforming_entry[i].bUsed == _FALSE)
\r
75 return &(pBeamInfo->beamforming_entry[i]);
\r
82 struct beamforming_entry *beamforming_add_entry(PADAPTER adapter, u8* ra, u16 aid,
\r
83 u16 mac_id, CHANNEL_WIDTH bw, BEAMFORMING_CAP beamfrom_cap, u8* idx)
\r
85 struct mlme_priv *pmlmepriv = &(adapter->mlmepriv);
\r
86 struct beamforming_entry *pEntry = beamforming_get_free_entry(pmlmepriv, idx);
\r
90 pEntry->bUsed = _TRUE;
\r
92 pEntry->mac_id = mac_id;
\r
93 pEntry->sound_bw = bw;
\r
94 if (check_fwstate(pmlmepriv, WIFI_AP_STATE))
\r
96 u16 BSSID = ((*(adapter_mac_addr(adapter) + 5) & 0xf0) >> 4) ^
\r
97 (*(adapter_mac_addr(adapter) + 5) & 0xf); /* BSSID[44:47] xor BSSID[40:43] */
\r
98 pEntry->p_aid = (aid + BSSID * 32) & 0x1ff; // (dec(A) + dec(B)*32) mod 512
\r
101 else if (check_fwstate(pmlmepriv, WIFI_ADHOC_STATE) || check_fwstate(pmlmepriv, WIFI_ADHOC_MASTER_STATE))
\r
108 pEntry->p_aid = ra[5]; // BSSID[39:47]
\r
109 pEntry->p_aid = (pEntry->p_aid << 1) | (ra[4] >> 7 );
\r
112 _rtw_memcpy(pEntry->mac_addr, ra, ETH_ALEN);
\r
113 pEntry->bSound = _FALSE;
\r
115 //3 TODO SW/FW sound period
\r
116 pEntry->sound_period = 200;
\r
117 pEntry->beamforming_entry_cap = beamfrom_cap;
\r
118 pEntry->beamforming_entry_state = BEAMFORMING_ENTRY_STATE_UNINITIALIZE;
\r
121 pEntry->PreLogSeq = 0; /*Modified by Jeffery @2015-04-13*/
\r
122 pEntry->LogSeq = 0; /*Modified by Jeffery @2014-10-29*/
\r
123 pEntry->LogRetryCnt = 0; /*Modified by Jeffery @2014-10-29*/
\r
124 pEntry->LogSuccess = 0; /*LogSuccess is NOT needed to be accumulated, so LogSuccessCnt->LogSuccess, 2015-04-13, Jeffery*/
\r
125 pEntry->ClockResetTimes = 0; /*Modified by Jeffery @2015-04-13*/
\r
126 pEntry->LogStatusFailCnt = 0;
\r
134 BOOLEAN beamforming_remove_entry(struct mlme_priv *pmlmepriv, u8* ra, u8* idx)
\r
136 struct beamforming_entry *pEntry = beamforming_get_entry_by_addr(pmlmepriv, ra, idx);
\r
140 pEntry->bUsed = _FALSE;
\r
141 pEntry->beamforming_entry_cap = BEAMFORMING_CAP_NONE;
\r
142 pEntry->beamforming_entry_state = BEAMFORMING_ENTRY_STATE_UNINITIALIZE;
\r
149 /* Used for BeamformingStart_V1 */
\r
150 void beamforming_dym_ndpa_rate(PADAPTER adapter)
\r
152 u16 NDPARate = MGN_6M;
\r
153 PHAL_DATA_TYPE pHalData = GET_HAL_DATA(adapter);
\r
155 if(pHalData->MinUndecoratedPWDBForDM > 30) // link RSSI > 30%
\r
156 NDPARate = MGN_24M;
\r
160 //BW = CHANNEL_WIDTH_20;
\r
161 NDPARate = NDPARate << 8;
\r
162 rtw_hal_set_hwreg(adapter, HW_VAR_SOUNDING_RATE, (u8 *)&NDPARate);
\r
165 void beamforming_dym_period(PADAPTER Adapter)
\r
168 BOOLEAN bChangePeriod = _FALSE;
\r
169 u16 SoundPeriod_SW, SoundPeriod_FW;
\r
170 PHAL_DATA_TYPE pHalData = GET_HAL_DATA(Adapter);
\r
171 struct dvobj_priv *pdvobjpriv = adapter_to_dvobj(Adapter);
\r
172 struct beamforming_entry *pBeamformEntry;
\r
173 struct beamforming_info *pBeamInfo = GET_BEAMFORM_INFO(( &Adapter->mlmepriv));
\r
174 struct sounding_info *pSoundInfo = &(pBeamInfo->sounding_info);
\r
176 //3 TODO per-client throughput caculation.
\r
178 if(pdvobjpriv->traffic_stat.cur_tx_tp + pdvobjpriv->traffic_stat.cur_rx_tp > 2)
\r
180 SoundPeriod_SW = 32*20;
\r
181 SoundPeriod_FW = 2;
\r
185 SoundPeriod_SW = 32*2000;
\r
186 SoundPeriod_FW = 200;
\r
189 for(Idx = 0; Idx < BEAMFORMING_ENTRY_NUM; Idx++)
\r
191 pBeamformEntry = pBeamInfo->beamforming_entry+Idx;
\r
192 if(pBeamformEntry->bDefaultCSI)
\r
194 SoundPeriod_SW = 32*2000;
\r
195 SoundPeriod_FW = 200;
\r
198 if(pBeamformEntry->beamforming_entry_cap & (BEAMFORMER_CAP_HT_EXPLICIT |BEAMFORMER_CAP_VHT_SU))
\r
200 if(pSoundInfo->sound_mode == SOUNDING_FW_VHT_TIMER || pSoundInfo->sound_mode == SOUNDING_FW_HT_TIMER)
\r
202 if(pBeamformEntry->sound_period != SoundPeriod_FW)
\r
204 pBeamformEntry->sound_period = SoundPeriod_FW;
\r
205 bChangePeriod = _TRUE; // Only FW sounding need to send H2C packet to change sound period.
\r
208 else if(pBeamformEntry->sound_period != SoundPeriod_SW)
\r
210 pBeamformEntry->sound_period = SoundPeriod_SW;
\r
216 rtw_hal_set_hwreg(Adapter, HW_VAR_SOUNDING_FW_NDPA, (u8 *)&Idx);
\r
219 BOOLEAN issue_ht_sw_ndpa_packet(PADAPTER Adapter, u8 *ra, CHANNEL_WIDTH bw, u8 qidx)
\r
221 struct xmit_frame *pmgntframe;
\r
222 struct pkt_attrib *pattrib;
\r
223 struct rtw_ieee80211_hdr *pwlanhdr;
\r
224 struct xmit_priv *pxmitpriv = &(Adapter->xmitpriv);
\r
225 struct mlme_ext_priv *pmlmeext = &Adapter->mlmeextpriv;
\r
226 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
\r
227 u8 ActionHdr[4] = {ACT_CAT_VENDOR, 0x00, 0xe0, 0x4c};
\r
234 DBG_871X("%s: issue_ht_sw_ndpa_packet!\n", __func__);
\r
236 NDPTxRate = MGN_MCS8;
\r
237 DBG_871X("%s: NDPTxRate =%d\n", __func__, NDPTxRate);
\r
238 pmgntframe = alloc_mgtxmitframe(pxmitpriv);
\r
240 if (pmgntframe == NULL)
\r
243 /*update attribute*/
\r
244 pattrib = &pmgntframe->attrib;
\r
245 update_mgntframe_attrib(Adapter, pattrib);
\r
246 pattrib->qsel = QSLT_MGNT;
\r
247 pattrib->rate = NDPTxRate;
\r
248 pattrib->bwmode = bw;
\r
249 pattrib->order = 1;
\r
250 pattrib->subtype = WIFI_ACTION_NOACK;
\r
252 _rtw_memset(pmgntframe->buf_addr, 0, WLANHDR_OFFSET + TXDESC_OFFSET);
\r
254 pframe = (u8 *)(pmgntframe->buf_addr) + TXDESC_OFFSET;
\r
256 pwlanhdr = (struct rtw_ieee80211_hdr *)pframe;
\r
258 fctrl = &pwlanhdr->frame_ctl;
\r
261 SetOrderBit(pframe);
\r
262 SetFrameSubType(pframe, WIFI_ACTION_NOACK);
\r
264 _rtw_memcpy(pwlanhdr->addr1, ra, ETH_ALEN);
\r
265 _rtw_memcpy(pwlanhdr->addr2, adapter_mac_addr(Adapter), ETH_ALEN);
\r
266 _rtw_memcpy(pwlanhdr->addr3, get_my_bssid(&(pmlmeinfo->network)), ETH_ALEN);
\r
268 if (pmlmeext->cur_wireless_mode == WIRELESS_11B)
\r
273 duration = 2*aSifsTime + 40;
\r
275 if (bw == CHANNEL_WIDTH_40)
\r
280 SetDuration(pframe, duration);
\r
282 /*HT control field*/
\r
283 SET_HT_CTRL_CSI_STEERING(pframe+24, 3);
\r
284 SET_HT_CTRL_NDP_ANNOUNCEMENT(pframe+24, 1);
\r
286 _rtw_memcpy(pframe+28, ActionHdr, 4);
\r
288 pattrib->pktlen = 32;
\r
290 pattrib->last_txcmdsz = pattrib->pktlen;
\r
292 dump_mgntframe(Adapter, pmgntframe);
\r
298 BOOLEAN issue_ht_ndpa_packet(PADAPTER Adapter, u8 *ra, CHANNEL_WIDTH bw, u8 qidx)
\r
300 struct xmit_frame *pmgntframe;
\r
301 struct pkt_attrib *pattrib;
\r
302 struct rtw_ieee80211_hdr *pwlanhdr;
\r
303 struct xmit_priv *pxmitpriv = &(Adapter->xmitpriv);
\r
304 struct mlme_ext_priv *pmlmeext = &Adapter->mlmeextpriv;
\r
305 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
\r
306 u8 ActionHdr[4] = {ACT_CAT_VENDOR, 0x00, 0xe0, 0x4c};
\r
312 pmgntframe = alloc_mgtxmitframe(pxmitpriv);
\r
314 if (pmgntframe == NULL)
\r
317 /*update attribute*/
\r
318 pattrib = &pmgntframe->attrib;
\r
319 update_mgntframe_attrib(Adapter, pattrib);
\r
321 if (qidx == BCN_QUEUE_INX)
\r
322 pattrib->qsel = QSLT_BEACON;
\r
323 pattrib->rate = MGN_MCS8;
\r
324 pattrib->bwmode = bw;
\r
325 pattrib->order = 1;
\r
326 pattrib->subtype = WIFI_ACTION_NOACK;
\r
328 _rtw_memset(pmgntframe->buf_addr, 0, WLANHDR_OFFSET + TXDESC_OFFSET);
\r
330 pframe = (u8 *)(pmgntframe->buf_addr) + TXDESC_OFFSET;
\r
332 pwlanhdr = (struct rtw_ieee80211_hdr*)pframe;
\r
334 fctrl = &pwlanhdr->frame_ctl;
\r
337 SetOrderBit(pframe);
\r
338 SetFrameSubType(pframe, WIFI_ACTION_NOACK);
\r
340 _rtw_memcpy(pwlanhdr->addr1, ra, ETH_ALEN);
\r
341 _rtw_memcpy(pwlanhdr->addr2, adapter_mac_addr(Adapter), ETH_ALEN);
\r
342 _rtw_memcpy(pwlanhdr->addr3, get_my_bssid(&(pmlmeinfo->network)), ETH_ALEN);
\r
344 if( pmlmeext->cur_wireless_mode == WIRELESS_11B)
\r
349 duration = 2*aSifsTime + 40;
\r
351 if(bw == CHANNEL_WIDTH_40)
\r
356 SetDuration(pframe, duration);
\r
359 SET_HT_CTRL_CSI_STEERING(pframe+24, 3);
\r
360 SET_HT_CTRL_NDP_ANNOUNCEMENT(pframe+24, 1);
\r
362 _rtw_memcpy(pframe+28, ActionHdr, 4);
\r
364 pattrib->pktlen = 32;
\r
366 pattrib->last_txcmdsz = pattrib->pktlen;
\r
368 dump_mgntframe(Adapter, pmgntframe);
\r
373 BOOLEAN beamforming_send_ht_ndpa_packet(PADAPTER Adapter, u8 *ra, CHANNEL_WIDTH bw, u8 qidx)
\r
375 return issue_ht_ndpa_packet(Adapter, ra, bw, qidx);
\r
377 BOOLEAN issue_vht_sw_ndpa_packet(PADAPTER Adapter, u8 *ra, u16 aid, CHANNEL_WIDTH bw, u8 qidx)
\r
379 struct xmit_frame *pmgntframe;
\r
380 struct pkt_attrib *pattrib;
\r
381 struct rtw_ieee80211_hdr *pwlanhdr;
\r
382 struct xmit_priv *pxmitpriv = &(Adapter->xmitpriv);
\r
383 struct mlme_ext_priv *pmlmeext = &Adapter->mlmeextpriv;
\r
384 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
\r
385 struct mlme_priv *pmlmepriv = &(Adapter->mlmepriv);
\r
386 struct beamforming_info *pBeamInfo = GET_BEAMFORM_INFO(pmlmepriv);
\r
387 struct rtw_ndpa_sta_info sta_info;
\r
393 u8 sequence = 0, aSifsTime = 0;
\r
395 DBG_871X("%s: issue_vht_sw_ndpa_packet!\n", __func__);
\r
398 NDPTxRate = MGN_VHT2SS_MCS0;
\r
399 DBG_871X("%s: NDPTxRate =%d\n", __func__, NDPTxRate);
\r
400 pmgntframe = alloc_mgtxmitframe(pxmitpriv);
\r
402 if (pmgntframe == NULL) {
\r
403 DBG_871X("%s, alloc mgnt frame fail\n", __func__);
\r
407 /*update attribute*/
\r
408 pattrib = &pmgntframe->attrib;
\r
409 update_mgntframe_attrib(Adapter, pattrib);
\r
410 pattrib->qsel = QSLT_MGNT;
\r
411 pattrib->rate = NDPTxRate;
\r
412 pattrib->bwmode = bw;
\r
413 pattrib->subtype = WIFI_NDPA;
\r
415 _rtw_memset(pmgntframe->buf_addr, 0, WLANHDR_OFFSET + TXDESC_OFFSET);
\r
417 pframe = (u8 *)(pmgntframe->buf_addr) + TXDESC_OFFSET;
\r
419 pwlanhdr = (struct rtw_ieee80211_hdr *)pframe;
\r
421 fctrl = &pwlanhdr->frame_ctl;
\r
424 SetFrameSubType(pframe, WIFI_NDPA);
\r
426 _rtw_memcpy(pwlanhdr->addr1, ra, ETH_ALEN);
\r
427 _rtw_memcpy(pwlanhdr->addr2, adapter_mac_addr(Adapter), ETH_ALEN);
\r
429 if (IsSupported5G(pmlmeext->cur_wireless_mode) || IsSupportedHT(pmlmeext->cur_wireless_mode))
\r
434 duration = 2*aSifsTime + 44;
\r
436 if (bw == CHANNEL_WIDTH_80)
\r
438 else if (bw == CHANNEL_WIDTH_40)
\r
443 SetDuration(pframe, duration);
\r
445 sequence = pBeamInfo->sounding_sequence << 2;
\r
446 if (pBeamInfo->sounding_sequence >= 0x3f)
\r
447 pBeamInfo->sounding_sequence = 0;
\r
449 pBeamInfo->sounding_sequence++;
\r
451 _rtw_memcpy(pframe+16, &sequence, 1);
\r
452 if (((pmlmeinfo->state&0x03) == WIFI_FW_ADHOC_STATE) || ((pmlmeinfo->state&0x03) == WIFI_FW_AP_STATE))
\r
455 sta_info.aid = aid;
\r
456 sta_info.feedback_type = 0;
\r
457 sta_info.nc_index = 0;
\r
459 _rtw_memcpy(pframe+17, (u8 *)&sta_info, 2);
\r
461 pattrib->pktlen = 19;
\r
463 pattrib->last_txcmdsz = pattrib->pktlen;
\r
465 dump_mgntframe(Adapter, pmgntframe);
\r
471 BOOLEAN issue_vht_ndpa_packet(PADAPTER Adapter, u8 *ra, u16 aid, CHANNEL_WIDTH bw, u8 qidx)
\r
473 struct xmit_frame *pmgntframe;
\r
474 struct pkt_attrib *pattrib;
\r
475 struct rtw_ieee80211_hdr *pwlanhdr;
\r
476 struct xmit_priv *pxmitpriv = &(Adapter->xmitpriv);
\r
477 struct mlme_ext_priv *pmlmeext = &Adapter->mlmeextpriv;
\r
478 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
\r
479 struct mlme_priv *pmlmepriv = &(Adapter->mlmepriv);
\r
480 struct beamforming_info *pBeamInfo = GET_BEAMFORM_INFO(pmlmepriv);
\r
481 struct rtw_ndpa_sta_info sta_info;
\r
485 u8 sequence = 0, aSifsTime = 0;
\r
487 if ((pmgntframe = alloc_mgtxmitframe(pxmitpriv)) == NULL)
\r
490 /*update attribute*/
\r
491 pattrib = &pmgntframe->attrib;
\r
492 update_mgntframe_attrib(Adapter, pattrib);
\r
494 if (qidx == BCN_QUEUE_INX)
\r
495 pattrib->qsel = QSLT_BEACON;
\r
496 pattrib->rate = MGN_VHT2SS_MCS0;
\r
497 pattrib->bwmode = bw;
\r
498 pattrib->subtype = WIFI_NDPA;
\r
500 _rtw_memset(pmgntframe->buf_addr, 0, WLANHDR_OFFSET + TXDESC_OFFSET);
\r
502 pframe = (u8 *)(pmgntframe->buf_addr) + TXDESC_OFFSET;
\r
504 pwlanhdr = (struct rtw_ieee80211_hdr*)pframe;
\r
506 fctrl = &pwlanhdr->frame_ctl;
\r
509 SetFrameSubType(pframe, WIFI_NDPA);
\r
511 _rtw_memcpy(pwlanhdr->addr1, ra, ETH_ALEN);
\r
512 _rtw_memcpy(pwlanhdr->addr2, adapter_mac_addr(Adapter), ETH_ALEN);
\r
514 if (IsSupported5G(pmlmeext->cur_wireless_mode) || IsSupportedHT(pmlmeext->cur_wireless_mode))
\r
519 duration = 2*aSifsTime + 44;
\r
521 if(bw == CHANNEL_WIDTH_80)
\r
523 else if(bw == CHANNEL_WIDTH_40)
\r
528 SetDuration(pframe, duration);
\r
530 sequence = pBeamInfo->sounding_sequence<< 2;
\r
531 if (pBeamInfo->sounding_sequence >= 0x3f)
\r
532 pBeamInfo->sounding_sequence = 0;
\r
534 pBeamInfo->sounding_sequence++;
\r
536 _rtw_memcpy(pframe+16, &sequence,1);
\r
538 if(((pmlmeinfo->state&0x03) == WIFI_FW_ADHOC_STATE) || ((pmlmeinfo->state&0x03) == WIFI_FW_AP_STATE))
\r
541 sta_info.aid = aid;
\r
542 sta_info.feedback_type = 0;
\r
543 sta_info.nc_index= 0;
\r
545 _rtw_memcpy(pframe+17, (u8 *)&sta_info, 2);
\r
547 pattrib->pktlen = 19;
\r
549 pattrib->last_txcmdsz = pattrib->pktlen;
\r
551 dump_mgntframe(Adapter, pmgntframe);
\r
556 BOOLEAN beamforming_send_vht_ndpa_packet(PADAPTER Adapter, u8 *ra, u16 aid, CHANNEL_WIDTH bw, u8 qidx)
\r
558 return issue_vht_ndpa_packet(Adapter, ra, aid, bw, qidx);
\r
561 BOOLEAN beamfomring_bSounding(struct beamforming_info *pBeamInfo)
\r
563 BOOLEAN bSounding = _FALSE;
\r
565 if(( beamforming_get_beamform_cap(pBeamInfo) & BEAMFORMER_CAP) == 0)
\r
566 bSounding = _FALSE;
\r
573 u8 beamforming_sounding_idx(struct beamforming_info *pBeamInfo)
\r
578 for(i = 0; i < BEAMFORMING_ENTRY_NUM; i++)
\r
580 if (pBeamInfo->beamforming_entry[i].bUsed &&
\r
581 (_FALSE == pBeamInfo->beamforming_entry[i].bSound))
\r
591 SOUNDING_MODE beamforming_sounding_mode(struct beamforming_info *pBeamInfo, u8 idx)
\r
593 struct beamforming_entry BeamEntry = pBeamInfo->beamforming_entry[idx];
\r
594 SOUNDING_MODE mode;
\r
596 if(BeamEntry.beamforming_entry_cap & BEAMFORMER_CAP_VHT_SU)
\r
598 mode = SOUNDING_FW_VHT_TIMER;
\r
600 else if(BeamEntry.beamforming_entry_cap & BEAMFORMER_CAP_HT_EXPLICIT)
\r
602 mode = SOUNDING_FW_HT_TIMER;
\r
606 mode = SOUNDING_STOP_All_TIMER;
\r
612 u16 beamforming_sounding_time(struct beamforming_info *pBeamInfo, SOUNDING_MODE mode, u8 idx)
\r
614 u16 sounding_time = 0xffff;
\r
615 struct beamforming_entry BeamEntry = pBeamInfo->beamforming_entry[idx];
\r
617 sounding_time = BeamEntry.sound_period;
\r
619 return sounding_time;
\r
622 CHANNEL_WIDTH beamforming_sounding_bw(struct beamforming_info *pBeamInfo, SOUNDING_MODE mode, u8 idx)
\r
624 CHANNEL_WIDTH sounding_bw = CHANNEL_WIDTH_20;
\r
625 struct beamforming_entry BeamEntry = pBeamInfo->beamforming_entry[idx];
\r
627 sounding_bw = BeamEntry.sound_bw;
\r
629 return sounding_bw;
\r
632 BOOLEAN beamforming_select_beam_entry(struct beamforming_info *pBeamInfo)
\r
634 struct sounding_info *pSoundInfo = &(pBeamInfo->sounding_info);
\r
636 pSoundInfo->sound_idx = beamforming_sounding_idx(pBeamInfo);
\r
638 if(pSoundInfo->sound_idx < BEAMFORMING_ENTRY_NUM)
\r
639 pSoundInfo->sound_mode = beamforming_sounding_mode(pBeamInfo, pSoundInfo->sound_idx);
\r
641 pSoundInfo->sound_mode = SOUNDING_STOP_All_TIMER;
\r
643 if(SOUNDING_STOP_All_TIMER == pSoundInfo->sound_mode)
\r
649 pSoundInfo->sound_bw = beamforming_sounding_bw(pBeamInfo, pSoundInfo->sound_mode, pSoundInfo->sound_idx );
\r
650 pSoundInfo->sound_period = beamforming_sounding_time(pBeamInfo, pSoundInfo->sound_mode, pSoundInfo->sound_idx );
\r
655 BOOLEAN beamforming_start_fw(PADAPTER adapter, u8 idx)
\r
658 struct beamforming_entry *pEntry;
\r
659 BOOLEAN ret = _TRUE;
\r
660 struct mlme_priv *pmlmepriv = &(adapter->mlmepriv);
\r
661 struct beamforming_info *pBeamInfo = GET_BEAMFORM_INFO(pmlmepriv);
\r
663 pEntry = &(pBeamInfo->beamforming_entry[idx]);
\r
664 if(pEntry->bUsed == _FALSE)
\r
666 DBG_871X("Skip Beamforming, no entry for Idx =%d\n", idx);
\r
670 pEntry->beamforming_entry_state = BEAMFORMING_ENTRY_STATE_PROGRESSING;
\r
671 pEntry->bSound = _TRUE;
\r
672 rtw_hal_set_hwreg(adapter, HW_VAR_SOUNDING_FW_NDPA, (u8 *)&idx);
\r
677 void beamforming_end_fw(PADAPTER adapter)
\r
681 rtw_hal_set_hwreg(adapter, HW_VAR_SOUNDING_FW_NDPA, (u8 *)&idx);
\r
683 DBG_871X("%s\n", __FUNCTION__);
\r
686 BOOLEAN beamforming_start_period(PADAPTER adapter)
\r
688 BOOLEAN ret = _TRUE;
\r
689 struct mlme_priv *pmlmepriv = &(adapter->mlmepriv);
\r
690 struct beamforming_info *pBeamInfo = GET_BEAMFORM_INFO(pmlmepriv);
\r
691 struct sounding_info *pSoundInfo = &(pBeamInfo->sounding_info);
\r
693 beamforming_dym_ndpa_rate(adapter);
\r
695 beamforming_select_beam_entry(pBeamInfo);
\r
697 if(pSoundInfo->sound_mode == SOUNDING_FW_VHT_TIMER || pSoundInfo->sound_mode == SOUNDING_FW_HT_TIMER)
\r
699 ret = beamforming_start_fw(adapter, pSoundInfo->sound_idx);
\r
706 DBG_871X("%s Idx %d Mode %d BW %d Period %d\n", __FUNCTION__,
\r
707 pSoundInfo->sound_idx, pSoundInfo->sound_mode, pSoundInfo->sound_bw, pSoundInfo->sound_period);
\r
712 void beamforming_end_period(PADAPTER adapter)
\r
715 struct beamforming_entry *pBeamformEntry;
\r
716 struct mlme_priv *pmlmepriv = &(adapter->mlmepriv);
\r
717 struct beamforming_info *pBeamInfo = GET_BEAMFORM_INFO(pmlmepriv);
\r
718 struct sounding_info *pSoundInfo = &(pBeamInfo->sounding_info);
\r
721 if(pSoundInfo->sound_mode == SOUNDING_FW_VHT_TIMER || pSoundInfo->sound_mode == SOUNDING_FW_HT_TIMER)
\r
723 beamforming_end_fw(adapter);
\r
727 void beamforming_notify(PADAPTER adapter)
\r
729 BOOLEAN bSounding = _FALSE;
\r
730 struct beamforming_info *pBeamInfo = GET_BEAMFORM_INFO(&(adapter->mlmepriv));
\r
732 bSounding = beamfomring_bSounding(pBeamInfo);
\r
734 if(pBeamInfo->beamforming_state == BEAMFORMING_STATE_IDLE)
\r
738 if(beamforming_start_period(adapter) == _TRUE)
\r
739 pBeamInfo->beamforming_state = BEAMFORMING_STATE_START;
\r
742 else if(pBeamInfo->beamforming_state == BEAMFORMING_STATE_START)
\r
746 if(beamforming_start_period(adapter) == _FALSE)
\r
747 pBeamInfo->beamforming_state = BEAMFORMING_STATE_END;
\r
751 beamforming_end_period(adapter);
\r
752 pBeamInfo->beamforming_state = BEAMFORMING_STATE_END;
\r
755 else if(pBeamInfo->beamforming_state == BEAMFORMING_STATE_END)
\r
759 if(beamforming_start_period(adapter) == _TRUE)
\r
760 pBeamInfo->beamforming_state = BEAMFORMING_STATE_START;
\r
765 DBG_871X("%s BeamformState %d\n", __FUNCTION__, pBeamInfo->beamforming_state);
\r
768 DBG_871X("%s BeamformState %d bSounding %d\n", __FUNCTION__, pBeamInfo->beamforming_state, bSounding);
\r
771 BOOLEAN beamforming_init_entry(PADAPTER adapter, struct sta_info *psta, u8* idx)
\r
773 struct mlme_priv *pmlmepriv = &(adapter->mlmepriv);
\r
774 struct ht_priv *phtpriv = &(pmlmepriv->htpriv);
\r
775 #ifdef CONFIG_80211AC_VHT
\r
776 struct vht_priv *pvhtpriv = &(pmlmepriv->vhtpriv);
\r
778 struct mlme_ext_priv *pmlmeext = &(adapter->mlmeextpriv);
\r
779 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
\r
780 struct beamforming_entry *pBeamformEntry = NULL;
\r
784 CHANNEL_WIDTH bw = CHANNEL_WIDTH_20;
\r
785 BEAMFORMING_CAP beamform_cap = BEAMFORMING_CAP_NONE;
\r
787 // The current setting does not support Beaforming
\r
788 if (0 == phtpriv->beamform_cap
\r
789 #ifdef CONFIG_80211AC_VHT
\r
790 && 0 == pvhtpriv->beamform_cap
\r
793 DBG_871X("The configuration disabled Beamforming! Skip...\n");
\r
799 mac_id = psta->mac_id;
\r
800 wireless_mode = psta->wireless_mode;
\r
801 bw = psta->bw_mode;
\r
803 if (IsSupportedHT(wireless_mode) || IsSupportedVHT(wireless_mode)) {
\r
807 cur_beamform = psta->htpriv.beamform_cap;
\r
809 // We are Beamformee because the STA is Beamformer
\r
810 if(TEST_FLAG(cur_beamform, BEAMFORMING_HT_BEAMFORMER_ENABLE))
\r
811 beamform_cap =(BEAMFORMING_CAP)(beamform_cap |BEAMFORMEE_CAP_HT_EXPLICIT);
\r
813 // We are Beamformer because the STA is Beamformee
\r
814 if(TEST_FLAG(cur_beamform, BEAMFORMING_HT_BEAMFORMEE_ENABLE))
\r
815 beamform_cap =(BEAMFORMING_CAP)(beamform_cap | BEAMFORMER_CAP_HT_EXPLICIT);
\r
816 #ifdef CONFIG_80211AC_VHT
\r
817 if (IsSupportedVHT(wireless_mode)) {
\r
819 cur_beamform = psta->vhtpriv.beamform_cap;
\r
821 // We are Beamformee because the STA is Beamformer
\r
822 if(TEST_FLAG(cur_beamform, BEAMFORMING_VHT_BEAMFORMER_ENABLE))
\r
823 beamform_cap =(BEAMFORMING_CAP)(beamform_cap |BEAMFORMEE_CAP_VHT_SU);
\r
824 // We are Beamformer because the STA is Beamformee
\r
825 if(TEST_FLAG(cur_beamform, BEAMFORMING_VHT_BEAMFORMEE_ENABLE))
\r
826 beamform_cap =(BEAMFORMING_CAP)(beamform_cap |BEAMFORMER_CAP_VHT_SU);
\r
828 #endif //CONFIG_80211AC_VHT
\r
830 if(beamform_cap == BEAMFORMING_CAP_NONE)
\r
833 DBG_871X("Beamforming Config Capability = 0x%02X\n", beamform_cap);
\r
835 pBeamformEntry = beamforming_get_entry_by_addr(pmlmepriv, ra, idx);
\r
836 if (pBeamformEntry == NULL) {
\r
837 pBeamformEntry = beamforming_add_entry(adapter, ra, aid, mac_id, bw, beamform_cap, idx);
\r
838 if(pBeamformEntry == NULL)
\r
841 pBeamformEntry->beamforming_entry_state = BEAMFORMING_ENTRY_STATE_INITIALIZEING;
\r
843 // Entry has been created. If entry is initialing or progressing then errors occur.
\r
844 if (pBeamformEntry->beamforming_entry_state != BEAMFORMING_ENTRY_STATE_INITIALIZED &&
\r
845 pBeamformEntry->beamforming_entry_state != BEAMFORMING_ENTRY_STATE_PROGRESSED) {
\r
846 DBG_871X("Error State of Beamforming");
\r
849 pBeamformEntry->beamforming_entry_state = BEAMFORMING_ENTRY_STATE_INITIALIZEING;
\r
853 pBeamformEntry->beamforming_entry_state = BEAMFORMING_ENTRY_STATE_INITIALIZED;
\r
854 psta->txbf_paid = pBeamformEntry->p_aid;
\r
855 psta->txbf_gid = pBeamformEntry->g_id;
\r
857 DBG_871X("%s Idx %d\n", __FUNCTION__, *idx);
\r
865 void beamforming_deinit_entry(PADAPTER adapter, u8* ra)
\r
868 struct mlme_priv *pmlmepriv = &(adapter->mlmepriv);
\r
870 if(beamforming_remove_entry(pmlmepriv, ra, &idx) == _TRUE)
\r
872 rtw_hal_set_hwreg(adapter, HW_VAR_SOUNDING_LEAVE, (u8 *)&idx);
\r
875 DBG_871X("%s Idx %d\n", __FUNCTION__, idx);
\r
878 void beamforming_reset(PADAPTER adapter)
\r
881 struct mlme_priv *pmlmepriv = &(adapter->mlmepriv);
\r
882 struct beamforming_info *pBeamInfo = GET_BEAMFORM_INFO(pmlmepriv);
\r
884 for(idx = 0; idx < BEAMFORMING_ENTRY_NUM; idx++)
\r
886 if(pBeamInfo->beamforming_entry[idx].bUsed == _TRUE)
\r
888 pBeamInfo->beamforming_entry[idx].bUsed = _FALSE;
\r
889 pBeamInfo->beamforming_entry[idx].beamforming_entry_cap = BEAMFORMING_CAP_NONE;
\r
890 pBeamInfo->beamforming_entry[idx].beamforming_entry_state= BEAMFORMING_ENTRY_STATE_UNINITIALIZE;
\r
891 rtw_hal_set_hwreg(adapter, HW_VAR_SOUNDING_LEAVE, (u8 *)&idx);
\r
895 DBG_871X("%s\n", __FUNCTION__);
\r
898 void beamforming_sounding_fail(PADAPTER Adapter)
\r
900 struct mlme_priv *pmlmepriv = &(Adapter->mlmepriv);
\r
901 struct beamforming_info *pBeamInfo = GET_BEAMFORM_INFO(pmlmepriv);
\r
902 struct beamforming_entry *pEntry = &(pBeamInfo->beamforming_entry[pBeamInfo->beamforming_cur_idx]);
\r
904 pEntry->bSound = _FALSE;
\r
905 rtw_hal_set_hwreg(Adapter, HW_VAR_SOUNDING_FW_NDPA, (u8 *)&pBeamInfo->beamforming_cur_idx);
\r
906 beamforming_deinit_entry(Adapter, pEntry->mac_addr);
\r
909 void beamforming_check_sounding_success(PADAPTER Adapter,BOOLEAN status)
\r
911 struct mlme_priv *pmlmepriv = &(Adapter->mlmepriv);
\r
912 struct beamforming_info *pBeamInfo = GET_BEAMFORM_INFO(pmlmepriv);
\r
913 struct beamforming_entry *pEntry = &(pBeamInfo->beamforming_entry[pBeamInfo->beamforming_cur_idx]);
\r
917 pEntry->LogStatusFailCnt = 0;
\r
921 pEntry->LogStatusFailCnt++;
\r
922 DBG_871X("%s LogStatusFailCnt %d\n", __FUNCTION__, pEntry->LogStatusFailCnt);
\r
924 if(pEntry->LogStatusFailCnt > 20)
\r
926 DBG_871X("%s LogStatusFailCnt > 20, Stop SOUNDING\n", __FUNCTION__);
\r
927 //pEntry->bSound = _FALSE;
\r
928 //rtw_hal_set_hwreg(Adapter, HW_VAR_SOUNDING_FW_NDPA, (u8 *)&pBeamInfo->beamforming_cur_idx);
\r
929 //beamforming_deinit_entry(Adapter, pEntry->mac_addr);
\r
930 beamforming_wk_cmd(Adapter, BEAMFORMING_CTRL_SOUNDING_FAIL, NULL, 0, 1);
\r
934 void beamforming_enter(PADAPTER adapter, PVOID psta)
\r
938 if(beamforming_init_entry(adapter, (struct sta_info *)psta, &idx))
\r
939 rtw_hal_set_hwreg(adapter, HW_VAR_SOUNDING_ENTER, (u8 *)&idx);
\r
941 //DBG_871X("%s Idx %d\n", __FUNCTION__, idx);
\r
944 void beamforming_leave(PADAPTER adapter,u8* ra)
\r
947 beamforming_reset(adapter);
\r
949 beamforming_deinit_entry(adapter, ra);
\r
951 beamforming_notify(adapter);
\r
954 BEAMFORMING_CAP beamforming_get_beamform_cap(struct beamforming_info *pBeamInfo)
\r
957 BOOLEAN bSelfBeamformer = _FALSE;
\r
958 BOOLEAN bSelfBeamformee = _FALSE;
\r
959 struct beamforming_entry beamforming_entry;
\r
960 BEAMFORMING_CAP beamform_cap = BEAMFORMING_CAP_NONE;
\r
962 for(i = 0; i < BEAMFORMING_ENTRY_NUM; i++)
\r
964 beamforming_entry = pBeamInfo->beamforming_entry[i];
\r
966 if(beamforming_entry.bUsed)
\r
968 if( (beamforming_entry.beamforming_entry_cap & BEAMFORMEE_CAP_VHT_SU) ||
\r
969 (beamforming_entry.beamforming_entry_cap & BEAMFORMEE_CAP_HT_EXPLICIT))
\r
970 bSelfBeamformee = _TRUE;
\r
971 if( (beamforming_entry.beamforming_entry_cap & BEAMFORMER_CAP_VHT_SU) ||
\r
972 (beamforming_entry.beamforming_entry_cap & BEAMFORMER_CAP_HT_EXPLICIT))
\r
973 bSelfBeamformer = _TRUE;
\r
976 if(bSelfBeamformer && bSelfBeamformee)
\r
977 i = BEAMFORMING_ENTRY_NUM;
\r
980 if(bSelfBeamformer)
\r
981 beamform_cap |= BEAMFORMER_CAP;
\r
982 if(bSelfBeamformee)
\r
983 beamform_cap |= BEAMFORMEE_CAP;
\r
985 return beamform_cap;
\r
988 void beamforming_watchdog(PADAPTER Adapter)
\r
990 struct beamforming_info *pBeamInfo = GET_BEAMFORM_INFO(( &(Adapter->mlmepriv)));
\r
992 if(pBeamInfo->beamforming_state != BEAMFORMING_STATE_START)
\r
995 beamforming_dym_period(Adapter);
\r
996 beamforming_dym_ndpa_rate(Adapter);
\r
998 #endif/* #if (BEAMFORMING_SUPPORT ==0) - for diver defined beamforming*/
\r
1000 u32 beamforming_get_report_frame(PADAPTER Adapter, union recv_frame *precv_frame)
\r
1002 u32 ret = _SUCCESS;
\r
1003 #if (BEAMFORMING_SUPPORT == 1)
\r
1004 PHAL_DATA_TYPE pHalData = GET_HAL_DATA(Adapter);
\r
1005 PDM_ODM_T pDM_Odm = &(pHalData->odmpriv);
\r
1007 ret = Beamforming_GetReportFrame(pDM_Odm, precv_frame);
\r
1009 #else /*(BEAMFORMING_SUPPORT == 0)- for drv beamfoming*/
\r
1010 struct beamforming_entry *pBeamformEntry = NULL;
\r
1011 struct mlme_priv *pmlmepriv = &(Adapter->mlmepriv);
\r
1012 u8 *pframe = precv_frame->u.hdr.rx_data;
\r
1013 u32 frame_len = precv_frame->u.hdr.len;
\r
1017 /*DBG_871X("beamforming_get_report_frame\n");*/
\r
1019 /*Memory comparison to see if CSI report is the same with previous one*/
\r
1020 ta = GetAddr2Ptr(pframe);
\r
1021 pBeamformEntry = beamforming_get_entry_by_addr(pmlmepriv, ta, &idx);
\r
1022 if (pBeamformEntry->beamforming_entry_cap & BEAMFORMER_CAP_VHT_SU)
\r
1023 offset = 31; /*24+(1+1+3)+2 MAC header+(Category+ActionCode+MIMOControlField)+SNR(Nc=2)*/
\r
1024 else if (pBeamformEntry->beamforming_entry_cap & BEAMFORMER_CAP_HT_EXPLICIT)
\r
1025 offset = 34; /*24+(1+1+6)+2 MAC header+(Category+ActionCode+MIMOControlField)+SNR(Nc=2)*/
\r
1029 /*DBG_871X("%s MacId %d offset=%d\n", __FUNCTION__, pBeamformEntry->mac_id, offset);*/
\r
1031 if (_rtw_memcmp(pBeamformEntry->PreCsiReport + offset, pframe+offset, frame_len-offset) == _FALSE)
\r
1032 pBeamformEntry->DefaultCsiCnt = 0;
\r
1034 pBeamformEntry->DefaultCsiCnt++;
\r
1036 _rtw_memcpy(&pBeamformEntry->PreCsiReport, pframe, frame_len);
\r
1038 pBeamformEntry->bDefaultCSI = _FALSE;
\r
1040 if (pBeamformEntry->DefaultCsiCnt > 20)
\r
1041 pBeamformEntry->bDefaultCSI = _TRUE;
\r
1043 pBeamformEntry->bDefaultCSI = _FALSE;
\r
1048 void beamforming_get_ndpa_frame(PADAPTER Adapter, union recv_frame *precv_frame)
\r
1050 #if (BEAMFORMING_SUPPORT == 1)
\r
1051 PHAL_DATA_TYPE pHalData = GET_HAL_DATA(Adapter);
\r
1052 PDM_ODM_T pDM_Odm = &(pHalData->odmpriv);
\r
1054 Beamforming_GetNDPAFrame(pDM_Odm, precv_frame);
\r
1056 #else /*(BEAMFORMING_SUPPORT == 0)- for drv beamfoming*/
\r
1059 u8 *pframe = precv_frame->u.hdr.rx_data;
\r
1060 struct mlme_priv *pmlmepriv = &(Adapter->mlmepriv);
\r
1061 struct beamforming_entry *pBeamformEntry = NULL;
\r
1063 /*DBG_871X("beamforming_get_ndpa_frame\n");*/
\r
1065 if (IS_HARDWARE_TYPE_8812(Adapter) == _FALSE)
\r
1067 else if (GetFrameSubType(pframe) != WIFI_NDPA)
\r
1070 ta = GetAddr2Ptr(pframe);
\r
1071 /*Remove signaling TA. */
\r
1072 ta[0] = ta[0] & 0xFE;
\r
1074 pBeamformEntry = beamforming_get_entry_by_addr(pmlmepriv, ta, &idx);
\r
1076 if (pBeamformEntry == NULL)
\r
1078 else if (!(pBeamformEntry->beamforming_entry_cap & BEAMFORMEE_CAP_VHT_SU))
\r
1080 /*LogSuccess: As long as 8812A receive NDPA and feedback CSI succeed once, clock reset is NO LONGER needed !2015-04-10, Jeffery*/
\r
1081 /*ClockResetTimes: While BFer entry always doesn't receive our CSI, clock will reset again and again.So ClockResetTimes is limited to 5 times.2015-04-13, Jeffery*/
\r
1082 else if ((pBeamformEntry->LogSuccess == 1) || (pBeamformEntry->ClockResetTimes == 5)) {
\r
1083 DBG_871X("[%s] LogSeq=%d, PreLogSeq=%d\n", __func__, pBeamformEntry->LogSeq, pBeamformEntry->PreLogSeq);
\r
1087 Sequence = (pframe[16]) >> 2;
\r
1088 DBG_871X("[%s] Start, Sequence=%d, LogSeq=%d, PreLogSeq=%d, LogRetryCnt=%d, ClockResetTimes=%d, LogSuccess=%d\n",
\r
1089 __func__, Sequence, pBeamformEntry->LogSeq, pBeamformEntry->PreLogSeq, pBeamformEntry->LogRetryCnt, pBeamformEntry->ClockResetTimes, pBeamformEntry->LogSuccess);
\r
1091 if ((pBeamformEntry->LogSeq != 0) && (pBeamformEntry->PreLogSeq != 0)) {
\r
1092 /*Success condition*/
\r
1093 if ((pBeamformEntry->LogSeq != Sequence) && (pBeamformEntry->PreLogSeq != pBeamformEntry->LogSeq)) {
\r
1094 /* break option for clcok reset, 2015-03-30, Jeffery */
\r
1095 pBeamformEntry->LogRetryCnt = 0;
\r
1096 /*As long as 8812A receive NDPA and feedback CSI succeed once, clock reset is no longer needed.*/
\r
1097 /*That is, LogSuccess is NOT needed to be reset to zero, 2015-04-13, Jeffery*/
\r
1098 pBeamformEntry->LogSuccess = 1;
\r
1100 } else {/*Fail condition*/
\r
1102 if (pBeamformEntry->LogRetryCnt == 5) {
\r
1103 pBeamformEntry->ClockResetTimes++;
\r
1104 pBeamformEntry->LogRetryCnt = 0;
\r
1106 DBG_871X("[%s] Clock Reset!!! ClockResetTimes=%d\n", __func__, pBeamformEntry->ClockResetTimes);
\r
1107 beamforming_wk_cmd(Adapter, BEAMFORMING_CTRL_SOUNDING_CLK, NULL, 0, 1);
\r
1110 pBeamformEntry->LogRetryCnt++;
\r
1114 /*Update LogSeq & PreLogSeq*/
\r
1115 pBeamformEntry->PreLogSeq = pBeamformEntry->LogSeq;
\r
1116 pBeamformEntry->LogSeq = Sequence;
\r
1125 void beamforming_wk_hdl(_adapter *padapter, u8 type, u8 *pbuf)
\r
1127 PHAL_DATA_TYPE pHalData = GET_HAL_DATA(padapter);
\r
1128 PDM_ODM_T pDM_Odm = &(pHalData->odmpriv);
\r
1131 #if (BEAMFORMING_SUPPORT == 1) /*(BEAMFORMING_SUPPORT == 1)- for PHYDM beamfoming*/
\r
1133 case BEAMFORMING_CTRL_ENTER:
\r
1135 struct sta_info *psta = (PVOID)pbuf;
\r
1136 u16 staIdx = psta->mac_id;
\r
1138 Beamforming_Enter(pDM_Odm, staIdx);
\r
1141 case BEAMFORMING_CTRL_LEAVE:
\r
1142 Beamforming_Leave(pDM_Odm, pbuf);
\r
1148 #else /*(BEAMFORMING_SUPPORT == 0)- for drv beamfoming*/
\r
1150 case BEAMFORMING_CTRL_ENTER:
\r
1151 beamforming_enter(padapter, (PVOID)pbuf);
\r
1154 case BEAMFORMING_CTRL_LEAVE:
\r
1155 beamforming_leave(padapter, pbuf);
\r
1158 case BEAMFORMING_CTRL_SOUNDING_FAIL:
\r
1159 beamforming_sounding_fail(padapter);
\r
1162 case BEAMFORMING_CTRL_SOUNDING_CLK:
\r
1163 rtw_hal_set_hwreg(padapter, HW_VAR_SOUNDING_CLK, NULL);
\r
1173 u8 beamforming_wk_cmd(_adapter*padapter, s32 type, u8 *pbuf, s32 size, u8 enqueue)
\r
1175 struct cmd_obj *ph2c;
\r
1176 struct drvextra_cmd_parm *pdrvextra_cmd_parm;
\r
1177 struct cmd_priv *pcmdpriv = &padapter->cmdpriv;
\r
1178 u8 res = _SUCCESS;
\r
1186 ph2c = (struct cmd_obj*)rtw_zmalloc(sizeof(struct cmd_obj));
\r
1192 pdrvextra_cmd_parm = (struct drvextra_cmd_parm*)rtw_zmalloc(sizeof(struct drvextra_cmd_parm));
\r
1193 if(pdrvextra_cmd_parm==NULL){
\r
1194 rtw_mfree((unsigned char *)ph2c, sizeof(struct cmd_obj));
\r
1199 if (pbuf != NULL) {
\r
1200 wk_buf = rtw_zmalloc(size);
\r
1202 rtw_mfree((u8 *)ph2c, sizeof(struct cmd_obj));
\r
1203 rtw_mfree((u8 *)pdrvextra_cmd_parm, sizeof(struct drvextra_cmd_parm));
\r
1208 _rtw_memcpy(wk_buf, pbuf, size);
\r
1214 pdrvextra_cmd_parm->ec_id = BEAMFORMING_WK_CID;
\r
1215 pdrvextra_cmd_parm->type = type;
\r
1216 pdrvextra_cmd_parm->size = size;
\r
1217 pdrvextra_cmd_parm->pbuf = wk_buf;
\r
1219 init_h2fwcmd_w_parm_no_rsp(ph2c, pdrvextra_cmd_parm, GEN_CMD_CODE(_Set_Drv_Extra));
\r
1221 res = rtw_enqueue_cmd(pcmdpriv, ph2c);
\r
1225 beamforming_wk_hdl(padapter, type, pbuf);
\r
1235 void update_attrib_txbf_info(_adapter *padapter, struct pkt_attrib *pattrib, struct sta_info *psta)
\r
1238 pattrib->txbf_g_id = psta->txbf_gid;
\r
1239 pattrib->txbf_p_aid = psta->txbf_paid;
\r