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