1 // SPDX-License-Identifier: GPL-2.0
2 /* Copyright(c) 2007 - 2011 Realtek Corporation. */
3
4 #define _RTW_MP_C_
5
6 #include "../include/drv_types.h"
7 #include "../include/odm_precomp.h"
8 #include "../include/rtl8188e_hal.h"
9
read_bbreg(struct adapter * padapter,u32 addr,u32 bitmask)10 u32 read_bbreg(struct adapter *padapter, u32 addr, u32 bitmask)
11 {
12 return rtw_hal_read_bbreg(padapter, addr, bitmask);
13 }
14
write_bbreg(struct adapter * padapter,u32 addr,u32 bitmask,u32 val)15 void write_bbreg(struct adapter *padapter, u32 addr, u32 bitmask, u32 val)
16 {
17 rtw_hal_write_bbreg(padapter, addr, bitmask, val);
18 }
19
_read_rfreg(struct adapter * padapter,u8 rfpath,u32 addr,u32 bitmask)20 u32 _read_rfreg(struct adapter *padapter, u8 rfpath, u32 addr, u32 bitmask)
21 {
22 return rtw_hal_read_rfreg(padapter, (enum rf_radio_path)rfpath, addr, bitmask);
23 }
24
_write_rfreg(struct adapter * padapter,u8 rfpath,u32 addr,u32 bitmask,u32 val)25 void _write_rfreg(struct adapter *padapter, u8 rfpath, u32 addr, u32 bitmask, u32 val)
26 {
27 rtw_hal_write_rfreg(padapter, (enum rf_radio_path)rfpath, addr, bitmask, val);
28 }
29
read_rfreg(struct adapter * padapter,u8 rfpath,u32 addr)30 u32 read_rfreg(struct adapter *padapter, u8 rfpath, u32 addr)
31 {
32 return _read_rfreg(padapter, (enum rf_radio_path)rfpath, addr, bRFRegOffsetMask);
33 }
34
write_rfreg(struct adapter * padapter,u8 rfpath,u32 addr,u32 val)35 void write_rfreg(struct adapter *padapter, u8 rfpath, u32 addr, u32 val)
36 {
37 _write_rfreg(padapter, (enum rf_radio_path)rfpath, addr, bRFRegOffsetMask, val);
38 }
39
_init_mp_priv_(struct mp_priv * pmp_priv)40 static void _init_mp_priv_(struct mp_priv *pmp_priv)
41 {
42 struct wlan_bssid_ex *pnetwork;
43
44 memset(pmp_priv, 0, sizeof(struct mp_priv));
45
46 pmp_priv->mode = MP_OFF;
47
48 pmp_priv->channel = 1;
49 pmp_priv->bandwidth = HT_CHANNEL_WIDTH_20;
50 pmp_priv->prime_channel_offset = HAL_PRIME_CHNL_OFFSET_DONT_CARE;
51 pmp_priv->rateidx = MPT_RATE_1M;
52 pmp_priv->txpoweridx = 0x2A;
53
54 pmp_priv->antenna_tx = ANTENNA_A;
55 pmp_priv->antenna_rx = ANTENNA_AB;
56
57 pmp_priv->check_mp_pkt = 0;
58
59 pmp_priv->tx_pktcount = 0;
60
61 pmp_priv->rx_pktcount = 0;
62 pmp_priv->rx_crcerrpktcount = 0;
63
64 pmp_priv->network_macaddr[0] = 0x00;
65 pmp_priv->network_macaddr[1] = 0xE0;
66 pmp_priv->network_macaddr[2] = 0x4C;
67 pmp_priv->network_macaddr[3] = 0x87;
68 pmp_priv->network_macaddr[4] = 0x66;
69 pmp_priv->network_macaddr[5] = 0x55;
70
71 pnetwork = &pmp_priv->mp_network.network;
72 memcpy(pnetwork->MacAddress, pmp_priv->network_macaddr, ETH_ALEN);
73
74 pnetwork->Ssid.SsidLength = 8;
75 memcpy(pnetwork->Ssid.Ssid, "mp_871x", pnetwork->Ssid.SsidLength);
76 }
77
mp_init_xmit_attrib(struct mp_tx * pmptx,struct adapter * padapter)78 static void mp_init_xmit_attrib(struct mp_tx *pmptx, struct adapter *padapter)
79 {
80 struct pkt_attrib *pattrib;
81 struct tx_desc *desc;
82
83 /* init xmitframe attribute */
84 pattrib = &pmptx->attrib;
85 memset(pattrib, 0, sizeof(struct pkt_attrib));
86 desc = &pmptx->desc;
87 memset(desc, 0, TXDESC_SIZE);
88
89 pattrib->ether_type = 0x8712;
90 memset(pattrib->dst, 0xFF, ETH_ALEN);
91 pattrib->ack_policy = 0;
92 pattrib->hdrlen = WLAN_HDR_A3_LEN;
93 pattrib->subtype = WIFI_DATA;
94 pattrib->priority = 0;
95 pattrib->qsel = pattrib->priority;
96 pattrib->nr_frags = 1;
97 pattrib->encrypt = 0;
98 pattrib->bswenc = false;
99 pattrib->qos_en = false;
100 }
101
init_mp_priv(struct adapter * padapter)102 s32 init_mp_priv(struct adapter *padapter)
103 {
104 struct mp_priv *pmppriv = &padapter->mppriv;
105
106 _init_mp_priv_(pmppriv);
107 pmppriv->papdater = padapter;
108
109 pmppriv->tx.stop = 1;
110 mp_init_xmit_attrib(&pmppriv->tx, padapter);
111
112 switch (padapter->registrypriv.rf_config) {
113 case RF_1T1R:
114 pmppriv->antenna_tx = ANTENNA_A;
115 pmppriv->antenna_rx = ANTENNA_A;
116 break;
117 case RF_1T2R:
118 default:
119 pmppriv->antenna_tx = ANTENNA_A;
120 pmppriv->antenna_rx = ANTENNA_AB;
121 break;
122 case RF_2T2R:
123 case RF_2T2R_GREEN:
124 pmppriv->antenna_tx = ANTENNA_AB;
125 pmppriv->antenna_rx = ANTENNA_AB;
126 break;
127 case RF_2T4R:
128 pmppriv->antenna_tx = ANTENNA_AB;
129 pmppriv->antenna_rx = ANTENNA_ABCD;
130 break;
131 }
132
133 return _SUCCESS;
134 }
135
free_mp_priv(struct mp_priv * pmp_priv)136 void free_mp_priv(struct mp_priv *pmp_priv)
137 {
138 kfree(pmp_priv->pallocated_mp_xmitframe_buf);
139 pmp_priv->pallocated_mp_xmitframe_buf = NULL;
140 pmp_priv->pmp_xmtframe_buf = NULL;
141 }
142
143 #define PHY_IQCalibrate(a, b) PHY_IQCalibrate_8188E(a, b)
144 #define PHY_LCCalibrate(a) PHY_LCCalibrate_8188E(a)
145 #define PHY_SetRFPathSwitch(a, b) PHY_SetRFPathSwitch_8188E(a, b)
146
MPT_InitializeAdapter(struct adapter * pAdapter,u8 Channel)147 s32 MPT_InitializeAdapter(struct adapter *pAdapter, u8 Channel)
148 {
149 struct hal_data_8188e *pHalData = GET_HAL_DATA(pAdapter);
150 s32 rtStatus = _SUCCESS;
151 struct mpt_context *pMptCtx = &pAdapter->mppriv.MptCtx;
152 struct mlme_priv *pmlmepriv = &pAdapter->mlmepriv;
153
154 /* HW Initialization for 8190 MPT. */
155 /* SW Initialization for 8190 MP. */
156 pMptCtx->bMptDrvUnload = false;
157 pMptCtx->bMassProdTest = false;
158 pMptCtx->bMptIndexEven = true; /* default gain index is -6.0db */
159 pMptCtx->h2cReqNum = 0x0;
160 /* Init mpt event. */
161 /* init for BT MP */
162
163 pMptCtx->bMptWorkItemInProgress = false;
164 pMptCtx->CurrMptAct = NULL;
165 /* */
166
167 /* Don't accept any packets */
168 rtw_write32(pAdapter, REG_RCR, 0);
169
170 PHY_IQCalibrate(pAdapter, false);
171 dm_CheckTXPowerTracking(&pHalData->odmpriv); /* trigger thermal meter */
172 PHY_LCCalibrate(pAdapter);
173
174 pMptCtx->backup0xc50 = (u8)PHY_QueryBBReg(pAdapter, rOFDM0_XAAGCCore1, bMaskByte0);
175 pMptCtx->backup0xc58 = (u8)PHY_QueryBBReg(pAdapter, rOFDM0_XBAGCCore1, bMaskByte0);
176 pMptCtx->backup0xc30 = (u8)PHY_QueryBBReg(pAdapter, rOFDM0_RxDetector1, bMaskByte0);
177 pMptCtx->backup0x52_RF_A = (u8)PHY_QueryRFReg(pAdapter, RF_PATH_A, RF_0x52, 0x000F0);
178 pMptCtx->backup0x52_RF_B = (u8)PHY_QueryRFReg(pAdapter, RF_PATH_A, RF_0x52, 0x000F0);
179
180 /* set ant to wifi side in mp mode */
181 rtw_write16(pAdapter, 0x870, 0x300);
182 rtw_write16(pAdapter, 0x860, 0x110);
183
184 if (pAdapter->registrypriv.mp_mode == 1)
185 pmlmepriv->fw_state = WIFI_MP_STATE;
186
187 return rtStatus;
188 }
189
190 /*-----------------------------------------------------------------------------
191 * Function: MPT_DeInitAdapter()
192 *
193 * Overview: Extra DeInitialization for Mass Production Test.
194 *
195 * Input: struct adapter * pAdapter
196 *
197 * Output: NONE
198 *
199 * Return: NONE
200 *
201 * Revised History:
202 * When Who Remark
203 * 05/08/2007 MHC Create Version 0.
204 * 05/18/2007 MHC Add normal driver MPHalt code.
205 *
206 *---------------------------------------------------------------------------*/
MPT_DeInitAdapter(struct adapter * pAdapter)207 void MPT_DeInitAdapter(struct adapter *pAdapter)
208 {
209 struct mpt_context *pMptCtx = &pAdapter->mppriv.MptCtx;
210
211 pMptCtx->bMptDrvUnload = true;
212 }
213
mpt_ProStartTest(struct adapter * padapter)214 static u8 mpt_ProStartTest(struct adapter *padapter)
215 {
216 struct mpt_context *pMptCtx = &padapter->mppriv.MptCtx;
217
218 pMptCtx->bMassProdTest = true;
219 pMptCtx->bStartContTx = false;
220 pMptCtx->bCckContTx = false;
221 pMptCtx->bOfdmContTx = false;
222 pMptCtx->bSingleCarrier = false;
223 pMptCtx->bCarrierSuppression = false;
224 pMptCtx->bSingleTone = false;
225
226 return _SUCCESS;
227 }
228
229 /*
230 * General use
231 */
SetPowerTracking(struct adapter * padapter,u8 enable)232 s32 SetPowerTracking(struct adapter *padapter, u8 enable)
233 {
234 Hal_SetPowerTracking(padapter, enable);
235 return 0;
236 }
237
GetPowerTracking(struct adapter * padapter,u8 * enable)238 void GetPowerTracking(struct adapter *padapter, u8 *enable)
239 {
240 Hal_GetPowerTracking(padapter, enable);
241 }
242
disable_dm(struct adapter * padapter)243 static void disable_dm(struct adapter *padapter)
244 {
245 u8 v8;
246
247 /* 3 1. disable firmware dynamic mechanism */
248 /* disable Power Training, Rate Adaptive */
249 v8 = rtw_read8(padapter, REG_BCN_CTRL);
250 v8 &= ~EN_BCN_FUNCTION;
251 rtw_write8(padapter, REG_BCN_CTRL, v8);
252
253 /* 3 2. disable driver dynamic mechanism */
254 /* disable Dynamic Initial Gain */
255 /* disable High Power */
256 /* disable Power Tracking */
257 Switch_DM_Func(padapter, DYNAMIC_FUNC_DISABLE, false);
258
259 /* enable APK, LCK and IQK but disable power tracking */
260 Switch_DM_Func(padapter, DYNAMIC_RF_CALIBRATION, true);
261 }
262
263 /* This function initializes the DUT to the MP test mode */
mp_start_test(struct adapter * padapter)264 s32 mp_start_test(struct adapter *padapter)
265 {
266 struct wlan_bssid_ex bssid;
267 struct sta_info *psta;
268 u32 length;
269 u8 val8;
270 s32 res = _SUCCESS;
271 struct mp_priv *pmppriv = &padapter->mppriv;
272 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
273 struct wlan_network *tgt_network = &pmlmepriv->cur_network;
274
275 padapter->registrypriv.mp_mode = 1;
276 pmppriv->bSetTxPower = 0; /* for manually set tx power */
277
278 /* 3 disable dynamic mechanism */
279 disable_dm(padapter);
280
281 /* 3 0. update mp_priv */
282
283 if (padapter->registrypriv.rf_config == RF_819X_MAX_TYPE) {
284 switch (GET_RF_TYPE(padapter)) {
285 case RF_1T1R:
286 pmppriv->antenna_tx = ANTENNA_A;
287 pmppriv->antenna_rx = ANTENNA_A;
288 break;
289 case RF_1T2R:
290 default:
291 pmppriv->antenna_tx = ANTENNA_A;
292 pmppriv->antenna_rx = ANTENNA_AB;
293 break;
294 case RF_2T2R:
295 case RF_2T2R_GREEN:
296 pmppriv->antenna_tx = ANTENNA_AB;
297 pmppriv->antenna_rx = ANTENNA_AB;
298 break;
299 case RF_2T4R:
300 pmppriv->antenna_tx = ANTENNA_AB;
301 pmppriv->antenna_rx = ANTENNA_ABCD;
302 break;
303 }
304 }
305
306 mpt_ProStartTest(padapter);
307
308 /* 3 1. initialize a new struct wlan_bssid_ex */
309 /* memset(&bssid, 0, sizeof(struct wlan_bssid_ex)); */
310 memcpy(bssid.MacAddress, pmppriv->network_macaddr, ETH_ALEN);
311 bssid.Ssid.SsidLength = strlen("mp_pseudo_adhoc");
312 memcpy(bssid.Ssid.Ssid, (u8 *)"mp_pseudo_adhoc", bssid.Ssid.SsidLength);
313 bssid.InfrastructureMode = Ndis802_11IBSS;
314 bssid.NetworkTypeInUse = Ndis802_11DS;
315 bssid.IELength = 0;
316
317 length = get_wlan_bssid_ex_sz(&bssid);
318 if (length % 4)
319 bssid.Length = ((length >> 2) + 1) << 2; /* round up to multiple of 4 bytes. */
320 else
321 bssid.Length = length;
322
323 spin_lock_bh(&pmlmepriv->lock);
324
325 if (check_fwstate(pmlmepriv, WIFI_MP_STATE))
326 goto end_of_mp_start_test;
327
328 /* init mp_start_test status */
329 if (check_fwstate(pmlmepriv, _FW_LINKED)) {
330 rtw_disassoc_cmd(padapter, 500, true);
331 rtw_indicate_disconnect(padapter);
332 rtw_free_assoc_resources(padapter, 1);
333 }
334 pmppriv->prev_fw_state = get_fwstate(pmlmepriv);
335 if (padapter->registrypriv.mp_mode == 1)
336 pmlmepriv->fw_state = WIFI_MP_STATE;
337 set_fwstate(pmlmepriv, _FW_UNDER_LINKING);
338
339 /* 3 2. create a new psta for mp driver */
340 /* clear psta in the cur_network, if any */
341 psta = rtw_get_stainfo(&padapter->stapriv, tgt_network->network.MacAddress);
342 if (psta)
343 rtw_free_stainfo(padapter, psta);
344
345 psta = rtw_alloc_stainfo(&padapter->stapriv, bssid.MacAddress);
346 if (!psta) {
347 pmlmepriv->fw_state = pmppriv->prev_fw_state;
348 res = _FAIL;
349 goto end_of_mp_start_test;
350 }
351
352 /* 3 3. join psudo AdHoc */
353 tgt_network->join_res = 1;
354 tgt_network->aid = 1;
355 psta->aid = 1;
356 memcpy(&tgt_network->network, &bssid, length);
357
358 rtw_indicate_connect(padapter);
359 _clr_fwstate_(pmlmepriv, _FW_UNDER_LINKING);
360
361 end_of_mp_start_test:
362
363 spin_unlock_bh(&pmlmepriv->lock);
364
365 if (res == _SUCCESS) {
366 /* set MSR to WIFI_FW_ADHOC_STATE */
367 val8 = rtw_read8(padapter, MSR) & 0xFC; /* 0x0102 */
368 val8 |= WIFI_FW_ADHOC_STATE;
369 rtw_write8(padapter, MSR, val8); /* Link in ad hoc network */
370 }
371 return res;
372 }
373 /* */
374 /* This function change the DUT from the MP test mode into normal mode */
mp_stop_test(struct adapter * padapter)375 void mp_stop_test(struct adapter *padapter)
376 {
377 struct mp_priv *pmppriv = &padapter->mppriv;
378 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
379 struct wlan_network *tgt_network = &pmlmepriv->cur_network;
380 struct sta_info *psta;
381
382 if (pmppriv->mode == MP_ON) {
383 pmppriv->bSetTxPower = 0;
384 spin_lock_bh(&pmlmepriv->lock);
385 if (!check_fwstate(pmlmepriv, WIFI_MP_STATE))
386 goto end_of_mp_stop_test;
387
388 /* 3 1. disconnect psudo AdHoc */
389 rtw_indicate_disconnect(padapter);
390
391 /* 3 2. clear psta used in mp test mode. */
392 psta = rtw_get_stainfo(&padapter->stapriv, tgt_network->network.MacAddress);
393 if (psta)
394 rtw_free_stainfo(padapter, psta);
395
396 /* 3 3. return to normal state (default:station mode) */
397 pmlmepriv->fw_state = pmppriv->prev_fw_state; /* WIFI_STATION_STATE; */
398
399 /* flush the cur_network */
400 memset(tgt_network, 0, sizeof(struct wlan_network));
401
402 _clr_fwstate_(pmlmepriv, WIFI_MP_STATE);
403
404 end_of_mp_stop_test:
405
406 spin_unlock_bh(&pmlmepriv->lock);
407 }
408 }
409
410 /*---------------------------hal\rtl8192c\MPT_HelperFunc.c---------------------------*/
411 /*
412 * SetChannel
413 * Description
414 * Use H2C command to change channel,
415 * not only modify rf register, but also other setting need to be done.
416 */
SetChannel(struct adapter * pAdapter)417 void SetChannel(struct adapter *pAdapter)
418 {
419 Hal_SetChannel(pAdapter);
420 }
421
422 /*
423 * Notice
424 * Switch bandwitdth may change center frequency(channel)
425 */
SetBandwidth(struct adapter * pAdapter)426 void SetBandwidth(struct adapter *pAdapter)
427 {
428 Hal_SetBandwidth(pAdapter);
429 }
430
SetAntenna(struct adapter * pAdapter)431 void SetAntenna(struct adapter *pAdapter)
432 {
433 Hal_SetAntenna(pAdapter);
434 }
435
SetAntennaPathPower(struct adapter * pAdapter)436 void SetAntennaPathPower(struct adapter *pAdapter)
437 {
438 Hal_SetAntennaPathPower(pAdapter);
439 }
440
SetTxPower(struct adapter * pAdapter)441 void SetTxPower(struct adapter *pAdapter)
442 {
443 Hal_SetTxPower(pAdapter);
444 }
445
SetDataRate(struct adapter * pAdapter)446 void SetDataRate(struct adapter *pAdapter)
447 {
448 Hal_SetDataRate(pAdapter);
449 }
450
MP_PHY_SetRFPathSwitch(struct adapter * pAdapter,bool bMain)451 void MP_PHY_SetRFPathSwitch(struct adapter *pAdapter, bool bMain)
452 {
453 PHY_SetRFPathSwitch(pAdapter, bMain);
454 }
455
SetThermalMeter(struct adapter * pAdapter,u8 target_ther)456 s32 SetThermalMeter(struct adapter *pAdapter, u8 target_ther)
457 {
458 return Hal_SetThermalMeter(pAdapter, target_ther);
459 }
460
GetThermalMeter(struct adapter * pAdapter,u8 * value)461 void GetThermalMeter(struct adapter *pAdapter, u8 *value)
462 {
463 Hal_GetThermalMeter(pAdapter, value);
464 }
465
SetSingleCarrierTx(struct adapter * pAdapter,u8 bStart)466 void SetSingleCarrierTx(struct adapter *pAdapter, u8 bStart)
467 {
468 PhySetTxPowerLevel(pAdapter);
469 Hal_SetSingleCarrierTx(pAdapter, bStart);
470 }
471
SetSingleToneTx(struct adapter * pAdapter,u8 bStart)472 void SetSingleToneTx(struct adapter *pAdapter, u8 bStart)
473 {
474 PhySetTxPowerLevel(pAdapter);
475 Hal_SetSingleToneTx(pAdapter, bStart);
476 }
477
SetCarrierSuppressionTx(struct adapter * pAdapter,u8 bStart)478 void SetCarrierSuppressionTx(struct adapter *pAdapter, u8 bStart)
479 {
480 PhySetTxPowerLevel(pAdapter);
481 Hal_SetCarrierSuppressionTx(pAdapter, bStart);
482 }
483
SetContinuousTx(struct adapter * pAdapter,u8 bStart)484 void SetContinuousTx(struct adapter *pAdapter, u8 bStart)
485 {
486 PhySetTxPowerLevel(pAdapter);
487 Hal_SetContinuousTx(pAdapter, bStart);
488 }
489
PhySetTxPowerLevel(struct adapter * pAdapter)490 void PhySetTxPowerLevel(struct adapter *pAdapter)
491 {
492 struct mp_priv *pmp_priv = &pAdapter->mppriv;
493
494 if (pmp_priv->bSetTxPower == 0) /* for NO manually set power index */
495 PHY_SetTxPowerLevel8188E(pAdapter, pmp_priv->channel);
496 }
497
498 /* */
dump_mpframe(struct adapter * padapter,struct xmit_frame * pmpframe)499 static void dump_mpframe(struct adapter *padapter, struct xmit_frame *pmpframe)
500 {
501 rtw_hal_mgnt_xmit(padapter, pmpframe);
502 }
503
alloc_mp_xmitframe(struct xmit_priv * pxmitpriv)504 static struct xmit_frame *alloc_mp_xmitframe(struct xmit_priv *pxmitpriv)
505 {
506 struct xmit_frame *pmpframe;
507 struct xmit_buf *pxmitbuf;
508
509 pmpframe = rtw_alloc_xmitframe(pxmitpriv);
510 if (!pmpframe)
511 return NULL;
512
513 pxmitbuf = rtw_alloc_xmitbuf(pxmitpriv);
514 if (!pxmitbuf) {
515 rtw_free_xmitframe(pxmitpriv, pmpframe);
516 return NULL;
517 }
518
519 pmpframe->frame_tag = MP_FRAMETAG;
520
521 pmpframe->pxmitbuf = pxmitbuf;
522
523 pmpframe->buf_addr = pxmitbuf->pbuf;
524
525 pxmitbuf->priv_data = pmpframe;
526
527 return pmpframe;
528 }
529
mp_xmit_packet_thread(void * context)530 static int mp_xmit_packet_thread(void *context)
531 {
532 struct xmit_frame *pxmitframe;
533 struct mp_tx *pmptx;
534 struct mp_priv *pmp_priv;
535 struct xmit_priv *pxmitpriv;
536 struct adapter *padapter;
537
538 pmp_priv = (struct mp_priv *)context;
539 pmptx = &pmp_priv->tx;
540 padapter = pmp_priv->papdater;
541 pxmitpriv = &padapter->xmitpriv;
542
543 thread_enter("RTW_MP_THREAD");
544
545 /* DBG_88E("%s:pkTx Start\n", __func__); */
546 while (1) {
547 pxmitframe = alloc_mp_xmitframe(pxmitpriv);
548 if (!pxmitframe) {
549 if (pmptx->stop ||
550 padapter->bSurpriseRemoved ||
551 padapter->bDriverStopped) {
552 goto exit;
553 } else {
554 msleep(1);
555 continue;
556 }
557 }
558
559 memcpy((u8 *)(pxmitframe->buf_addr + TXDESC_OFFSET), pmptx->buf, pmptx->write_size);
560 memcpy(&pxmitframe->attrib, &pmptx->attrib, sizeof(struct pkt_attrib));
561
562 dump_mpframe(padapter, pxmitframe);
563
564 pmptx->sended++;
565 pmp_priv->tx_pktcount++;
566
567 if (pmptx->stop ||
568 padapter->bSurpriseRemoved ||
569 padapter->bDriverStopped)
570 goto exit;
571 if ((pmptx->count != 0) &&
572 (pmptx->count == pmptx->sended))
573 goto exit;
574
575 flush_signals_thread();
576 }
577
578 exit:
579 kfree(pmptx->pallocated_buf);
580 pmptx->pallocated_buf = NULL;
581 pmptx->stop = 1;
582
583 thread_exit();
584 }
585
fill_txdesc_for_mp(struct adapter * padapter,struct tx_desc * ptxdesc)586 void fill_txdesc_for_mp(struct adapter *padapter, struct tx_desc *ptxdesc)
587 {
588 struct mp_priv *pmp_priv = &padapter->mppriv;
589 memcpy(ptxdesc, &pmp_priv->tx.desc, TXDESC_SIZE);
590 }
591
SetPacketTx(struct adapter * padapter)592 void SetPacketTx(struct adapter *padapter)
593 {
594 u8 *ptr, *pkt_start, *pkt_end;
595 u32 pkt_size;
596 struct tx_desc *desc;
597 struct rtw_ieee80211_hdr *hdr;
598 u8 payload;
599 bool bmcast;
600 struct pkt_attrib *pattrib;
601 struct mp_priv *pmp_priv;
602
603 pmp_priv = &padapter->mppriv;
604 if (pmp_priv->tx.stop)
605 return;
606 pmp_priv->tx.sended = 0;
607 pmp_priv->tx.stop = 0;
608 pmp_priv->tx_pktcount = 0;
609
610 /* 3 1. update_attrib() */
611 pattrib = &pmp_priv->tx.attrib;
612 memcpy(pattrib->src, padapter->eeprompriv.mac_addr, ETH_ALEN);
613 memcpy(pattrib->ta, pattrib->src, ETH_ALEN);
614 memcpy(pattrib->ra, pattrib->dst, ETH_ALEN);
615 bmcast = is_multicast_ether_addr(pattrib->ra);
616 if (bmcast) {
617 pattrib->mac_id = 1;
618 pattrib->psta = rtw_get_bcmc_stainfo(padapter);
619 } else {
620 pattrib->mac_id = 0;
621 pattrib->psta = rtw_get_stainfo(&padapter->stapriv, get_bssid(&padapter->mlmepriv));
622 }
623
624 pattrib->last_txcmdsz = pattrib->hdrlen + pattrib->pktlen;
625
626 /* 3 2. allocate xmit buffer */
627 pkt_size = pattrib->last_txcmdsz;
628
629 kfree(pmp_priv->tx.pallocated_buf);
630 pmp_priv->tx.write_size = pkt_size;
631 pmp_priv->tx.buf_size = pkt_size + XMITBUF_ALIGN_SZ;
632 pmp_priv->tx.pallocated_buf = kzalloc(pmp_priv->tx.buf_size, GFP_KERNEL);
633 if (!pmp_priv->tx.pallocated_buf) {
634 DBG_88E("%s: malloc(%d) fail!!\n", __func__, pmp_priv->tx.buf_size);
635 return;
636 }
637 pmp_priv->tx.buf = (u8 *)N_BYTE_ALIGMENT((size_t)(pmp_priv->tx.pallocated_buf), XMITBUF_ALIGN_SZ);
638 ptr = pmp_priv->tx.buf;
639
640 desc = &pmp_priv->tx.desc;
641 memset(desc, 0, TXDESC_SIZE);
642 pkt_start = ptr;
643 pkt_end = pkt_start + pkt_size;
644
645 /* 3 3. init TX descriptor */
646 /* offset 0 */
647 desc->txdw0 |= cpu_to_le32(OWN | FSG | LSG);
648 desc->txdw0 |= cpu_to_le32(pkt_size & 0x0000FFFF); /* packet size */
649 desc->txdw0 |= cpu_to_le32(((TXDESC_SIZE + OFFSET_SZ) << OFFSET_SHT) & 0x00FF0000); /* 32 bytes for TX Desc */
650 if (bmcast)
651 desc->txdw0 |= cpu_to_le32(BMC); /* broadcast packet */
652
653 desc->txdw1 |= cpu_to_le32((0x01 << 26) & 0xff000000);
654 /* offset 4 */
655 desc->txdw1 |= cpu_to_le32((pattrib->mac_id) & 0x3F); /* CAM_ID(MAC_ID) */
656 desc->txdw1 |= cpu_to_le32((pattrib->qsel << QSEL_SHT) & 0x00001F00); /* Queue Select, TID */
657
658 desc->txdw1 |= cpu_to_le32((pattrib->raid << RATE_ID_SHT) & 0x000F0000); /* Rate Adaptive ID */
659 /* offset 8 */
660 /* offset 12 */
661
662 desc->txdw3 |= cpu_to_le32((pattrib->seqnum << 16) & 0x0fff0000);
663
664 /* offset 16 */
665 desc->txdw4 |= cpu_to_le32(HW_SSN);
666 desc->txdw4 |= cpu_to_le32(USERATE);
667 desc->txdw4 |= cpu_to_le32(DISDATAFB);
668
669 if (pmp_priv->preamble) {
670 if (pmp_priv->rateidx <= MPT_RATE_54M)
671 desc->txdw4 |= cpu_to_le32(DATA_SHORT); /* CCK Short Preamble */
672 }
673 if (pmp_priv->bandwidth == HT_CHANNEL_WIDTH_40)
674 desc->txdw4 |= cpu_to_le32(DATA_BW);
675
676 /* offset 20 */
677 desc->txdw5 |= cpu_to_le32(pmp_priv->rateidx & 0x0000001F);
678
679 if (pmp_priv->preamble) {
680 if (pmp_priv->rateidx > MPT_RATE_54M)
681 desc->txdw5 |= cpu_to_le32(SGI); /* MCS Short Guard Interval */
682 }
683 desc->txdw5 |= cpu_to_le32(RTY_LMT_EN); /* retry limit enable */
684 desc->txdw5 |= cpu_to_le32(0x00180000); /* DATA/RTS Rate Fallback Limit */
685
686 /* 3 4. make wlan header, make_wlanhdr() */
687 hdr = (struct rtw_ieee80211_hdr *)pkt_start;
688 SetFrameSubType(&hdr->frame_ctl, pattrib->subtype);
689 memcpy(hdr->addr1, pattrib->dst, ETH_ALEN); /* DA */
690 memcpy(hdr->addr2, pattrib->src, ETH_ALEN); /* SA */
691 memcpy(hdr->addr3, get_bssid(&padapter->mlmepriv), ETH_ALEN); /* RA, BSSID */
692
693 /* 3 5. make payload */
694 ptr = pkt_start + pattrib->hdrlen;
695
696 switch (pmp_priv->tx.payload) {
697 case 0:
698 payload = 0x00;
699 break;
700 case 1:
701 payload = 0x5a;
702 break;
703 case 2:
704 payload = 0xa5;
705 break;
706 case 3:
707 payload = 0xff;
708 break;
709 default:
710 payload = 0x00;
711 break;
712 }
713
714 memset(ptr, payload, pkt_end - ptr);
715
716 /* 3 6. start thread */
717 pmp_priv->tx.PktTxThread = kthread_run(mp_xmit_packet_thread, pmp_priv, "RTW_MP_THREAD");
718 if (IS_ERR(pmp_priv->tx.PktTxThread))
719 DBG_88E("Create PktTx Thread Fail !!!!!\n");
720 }
721
SetPacketRx(struct adapter * pAdapter,u8 bStartRx)722 void SetPacketRx(struct adapter *pAdapter, u8 bStartRx)
723 {
724 struct hal_data_8188e *pHalData = GET_HAL_DATA(pAdapter);
725
726 if (bStartRx) {
727 /* Accept CRC error and destination address */
728 pHalData->ReceiveConfig = AAP | APM | AM | AB | APP_ICV |
729 AMF | ADF | APP_FCS | HTC_LOC_CTRL |
730 APP_MIC | APP_PHYSTS;
731
732 pHalData->ReceiveConfig |= (RCR_ACRC32 | RCR_AAP);
733
734 rtw_write32(pAdapter, REG_RCR, pHalData->ReceiveConfig);
735
736 /* Accept all data frames */
737 rtw_write16(pAdapter, REG_RXFLTMAP2, 0xFFFF);
738 } else {
739 rtw_write32(pAdapter, REG_RCR, 0);
740 }
741 }
742
ResetPhyRxPktCount(struct adapter * pAdapter)743 void ResetPhyRxPktCount(struct adapter *pAdapter)
744 {
745 u32 i, phyrx_set = 0;
746
747 for (i = 0; i <= 0xF; i++) {
748 phyrx_set = 0;
749 phyrx_set |= _RXERR_RPT_SEL(i); /* select */
750 phyrx_set |= RXERR_RPT_RST; /* set counter to zero */
751 rtw_write32(pAdapter, REG_RXERR_RPT, phyrx_set);
752 }
753 }
754
GetPhyRxPktCounts(struct adapter * pAdapter,u32 selbit)755 static u32 GetPhyRxPktCounts(struct adapter *pAdapter, u32 selbit)
756 {
757 /* selection */
758 u32 phyrx_set = 0, count = 0;
759
760 phyrx_set = _RXERR_RPT_SEL(selbit & 0xF);
761 rtw_write32(pAdapter, REG_RXERR_RPT, phyrx_set);
762
763 /* Read packet count */
764 count = rtw_read32(pAdapter, REG_RXERR_RPT) & RXERR_COUNTER_MASK;
765
766 return count;
767 }
768
GetPhyRxPktReceived(struct adapter * pAdapter)769 u32 GetPhyRxPktReceived(struct adapter *pAdapter)
770 {
771 u32 OFDM_cnt = 0, CCK_cnt = 0, HT_cnt = 0;
772
773 OFDM_cnt = GetPhyRxPktCounts(pAdapter, RXERR_TYPE_OFDM_MPDU_OK);
774 CCK_cnt = GetPhyRxPktCounts(pAdapter, RXERR_TYPE_CCK_MPDU_OK);
775 HT_cnt = GetPhyRxPktCounts(pAdapter, RXERR_TYPE_HT_MPDU_OK);
776
777 return OFDM_cnt + CCK_cnt + HT_cnt;
778 }
779
GetPhyRxPktCRC32Error(struct adapter * pAdapter)780 u32 GetPhyRxPktCRC32Error(struct adapter *pAdapter)
781 {
782 u32 OFDM_cnt = 0, CCK_cnt = 0, HT_cnt = 0;
783
784 OFDM_cnt = GetPhyRxPktCounts(pAdapter, RXERR_TYPE_OFDM_MPDU_FAIL);
785 CCK_cnt = GetPhyRxPktCounts(pAdapter, RXERR_TYPE_CCK_MPDU_FAIL);
786 HT_cnt = GetPhyRxPktCounts(pAdapter, RXERR_TYPE_HT_MPDU_FAIL);
787
788 return OFDM_cnt + CCK_cnt + HT_cnt;
789 }
790
791 /* reg 0x808[9:0]: FFT data x */
792 /* reg 0x808[22]: 0 --> 1 to get 1 FFT data y */
793 /* reg 0x8B4[15:0]: FFT data y report */
rtw_GetPSDData(struct adapter * pAdapter,u32 point)794 static u32 rtw_GetPSDData(struct adapter *pAdapter, u32 point)
795 {
796 int psd_val;
797
798 psd_val = rtw_read32(pAdapter, 0x808);
799 psd_val &= 0xFFBFFC00;
800 psd_val |= point;
801
802 rtw_write32(pAdapter, 0x808, psd_val);
803 mdelay(1);
804 psd_val |= 0x00400000;
805
806 rtw_write32(pAdapter, 0x808, psd_val);
807 mdelay(1);
808 psd_val = rtw_read32(pAdapter, 0x8B4);
809
810 psd_val &= 0x0000FFFF;
811
812 return psd_val;
813 }
814
815 /*
816 *pts start_point_min stop_point_max
817 * 128 64 64 + 128 = 192
818 * 256 128 128 + 256 = 384
819 * 512 256 256 + 512 = 768
820 * 1024 512 512 + 1024 = 1536
821 */
mp_query_psd(struct adapter * pAdapter,u8 * data)822 u32 mp_query_psd(struct adapter *pAdapter, u8 *data)
823 {
824 u32 i, psd_pts = 0, psd_start = 0, psd_stop = 0;
825 u32 psd_data = 0;
826
827 if (!netif_running(pAdapter->pnetdev))
828 return 0;
829
830 if (!check_fwstate(&pAdapter->mlmepriv, WIFI_MP_STATE))
831 return 0;
832
833 if (strlen(data) == 0) { /* default value */
834 psd_pts = 128;
835 psd_start = 64;
836 psd_stop = 128;
837 } else {
838 sscanf(data, "pts =%d, start =%d, stop =%d", &psd_pts, &psd_start, &psd_stop);
839 }
840
841 memset(data, '\0', sizeof(*data));
842
843 i = psd_start;
844 while (i < psd_stop) {
845 if (i >= psd_pts) {
846 psd_data = rtw_GetPSDData(pAdapter, i - psd_pts);
847 } else {
848 psd_data = rtw_GetPSDData(pAdapter, i);
849 }
850 sprintf(data + strlen(data), "%x ", psd_data);
851 i++;
852 }
853
854 msleep(100);
855 return strlen(data) + 1;
856 }
857
_rtw_mp_xmit_priv(struct xmit_priv * pxmitpriv)858 void _rtw_mp_xmit_priv(struct xmit_priv *pxmitpriv)
859 {
860 int i, res;
861 struct adapter *padapter = pxmitpriv->adapter;
862 struct xmit_buf *pxmitbuf = (struct xmit_buf *)pxmitpriv->pxmitbuf;
863 u32 max_xmit_extbuf_size = MAX_XMIT_EXTBUF_SZ;
864 u32 num_xmit_extbuf = NR_XMIT_EXTBUFF;
865
866 if (padapter->registrypriv.mp_mode == 0) {
867 max_xmit_extbuf_size = MAX_XMIT_EXTBUF_SZ;
868 num_xmit_extbuf = NR_XMIT_EXTBUFF;
869 } else {
870 max_xmit_extbuf_size = 6000;
871 num_xmit_extbuf = 8;
872 }
873
874 pxmitbuf = (struct xmit_buf *)pxmitpriv->pxmit_extbuf;
875 for (i = 0; i < num_xmit_extbuf; i++) {
876 rtw_os_xmit_resource_free(padapter, pxmitbuf, (max_xmit_extbuf_size + XMITBUF_ALIGN_SZ));
877
878 pxmitbuf++;
879 }
880
881 vfree(pxmitpriv->pallocated_xmit_extbuf);
882
883 if (padapter->registrypriv.mp_mode == 0) {
884 max_xmit_extbuf_size = 6000;
885 num_xmit_extbuf = 8;
886 } else {
887 max_xmit_extbuf_size = MAX_XMIT_EXTBUF_SZ;
888 num_xmit_extbuf = NR_XMIT_EXTBUFF;
889 }
890
891 /* Init xmit extension buff */
892 _rtw_init_queue(&pxmitpriv->free_xmit_extbuf_queue);
893
894 pxmitpriv->pallocated_xmit_extbuf = vzalloc(num_xmit_extbuf * sizeof(struct xmit_buf) + 4);
895
896 if (!pxmitpriv->pallocated_xmit_extbuf) {
897 res = _FAIL;
898 goto exit;
899 }
900
901 pxmitpriv->pxmit_extbuf = (u8 *)N_BYTE_ALIGMENT((size_t)(pxmitpriv->pallocated_xmit_extbuf), 4);
902
903 pxmitbuf = (struct xmit_buf *)pxmitpriv->pxmit_extbuf;
904
905 for (i = 0; i < num_xmit_extbuf; i++) {
906 INIT_LIST_HEAD(&pxmitbuf->list);
907
908 pxmitbuf->priv_data = NULL;
909 pxmitbuf->padapter = padapter;
910 pxmitbuf->ext_tag = true;
911
912 res = rtw_os_xmit_resource_alloc(padapter, pxmitbuf, max_xmit_extbuf_size + XMITBUF_ALIGN_SZ);
913 if (res == _FAIL) {
914 res = _FAIL;
915 goto exit;
916 }
917
918 list_add_tail(&pxmitbuf->list, &pxmitpriv->free_xmit_extbuf_queue.queue);
919 pxmitbuf++;
920 }
921
922 pxmitpriv->free_xmit_extbuf_cnt = num_xmit_extbuf;
923
924 exit:
925 ;
926 }
927
Hal_ProSetCrystalCap(struct adapter * pAdapter,u32 CrystalCapVal)928 void Hal_ProSetCrystalCap(struct adapter *pAdapter, u32 CrystalCapVal)
929 {
930 CrystalCapVal = CrystalCapVal & 0x3F;
931
932 // write 0x24[16:11] = 0x24[22:17] = CrystalCap
933 PHY_SetBBReg(pAdapter, REG_AFE_XTAL_CTRL, 0x7FF800,
934 (CrystalCapVal | (CrystalCapVal << 6)));
935 }
936