• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /******************************************************************************
2  *
3  * Copyright(c) 2007 - 2017 Realtek Corporation.
4  *
5  * This program is free software; you can redistribute it and/or modify it
6  * under the terms of version 2 of the GNU General Public License as
7  * published by the Free Software Foundation.
8  *
9  * This program is distributed in the hope that it will be useful, but WITHOUT
10  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11  * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
12  * more details.
13  *
14  *****************************************************************************/
15 
16 
17 #include <drv_types.h>
18 #include <rtw_bt_mp.h>
19 
20 #if defined(CONFIG_RTL8723B)
21 	#include <rtl8723b_hal.h>
22 #endif
23 
24 #if defined(CONFIG_RTL8723B) || defined(CONFIG_RTL8821A)
MPh2c_timeout_handle(void * FunctionContext)25 void MPh2c_timeout_handle(void *FunctionContext)
26 {
27 	PADAPTER pAdapter;
28 	PMPT_CONTEXT pMptCtx;
29 
30 
31 	RTW_INFO("[MPT], MPh2c_timeout_handle\n");
32 
33 	pAdapter = (PADAPTER)FunctionContext;
34 	pMptCtx = &pAdapter->mppriv.mpt_ctx;
35 
36 	pMptCtx->bMPh2c_timeout = _TRUE;
37 
38 	if ((_FALSE == pMptCtx->MptH2cRspEvent)
39 	    || ((_TRUE == pMptCtx->MptH2cRspEvent)
40 		&& (_FALSE == pMptCtx->MptBtC2hEvent)))
41 		_rtw_up_sema(&pMptCtx->MPh2c_Sema);
42 }
43 
WaitC2Hevent(PADAPTER pAdapter,u8 * C2H_event,u32 delay_time)44 u32 WaitC2Hevent(PADAPTER pAdapter, u8 *C2H_event, u32 delay_time)
45 {
46 	PMPT_CONTEXT		pMptCtx = &(pAdapter->mppriv.mpt_ctx);
47 	pMptCtx->bMPh2c_timeout = _FALSE;
48 
49 	if (pAdapter->registrypriv.mp_mode == 0) {
50 		RTW_INFO("[MPT], Error!! WaitC2Hevent mp_mode == 0!!\n");
51 		return _FALSE;
52 	}
53 
54 	_set_timer(&pMptCtx->MPh2c_timeout_timer, delay_time);
55 
56 	_rtw_down_sema(&pMptCtx->MPh2c_Sema);
57 
58 	if (pMptCtx->bMPh2c_timeout == _TRUE) {
59 		*C2H_event = _FALSE;
60 
61 		return _FALSE;
62 	}
63 
64 	/* for safty, cancel timer here again */
65 	_cancel_timer_ex(&pMptCtx->MPh2c_timeout_timer);
66 
67 	return _TRUE;
68 }
69 
70 BT_CTRL_STATUS
mptbt_CheckC2hFrame(PADAPTER Adapter,PBT_H2C pH2c,PBT_EXT_C2H pExtC2h)71 mptbt_CheckC2hFrame(
72 	PADAPTER		Adapter,
73 	PBT_H2C			pH2c,
74 	PBT_EXT_C2H		pExtC2h
75 )
76 {
77 	BT_CTRL_STATUS	c2hStatus = BT_STATUS_C2H_SUCCESS;
78 
79 	/* RTW_INFO("[MPT], MPT rsp C2H hex: %x %x %x  %x %x %x\n"), pExtC2h , pExtC2h+1 ,pExtC2h+2 ,pExtC2h+3 ,pExtC2h+4 ,pExtC2h+5); */
80 
81 	RTW_INFO("[MPT], statusCode = 0x%x\n", pExtC2h->statusCode);
82 	RTW_INFO("[MPT], retLen = %d\n", pExtC2h->retLen);
83 	RTW_INFO("[MPT], opCodeVer : req/rsp=%d/%d\n", pH2c->opCodeVer, pExtC2h->opCodeVer);
84 	RTW_INFO("[MPT], reqNum : req/rsp=%d/%d\n", pH2c->reqNum, pExtC2h->reqNum);
85 	if (pExtC2h->reqNum != pH2c->reqNum) {
86 		c2hStatus = BT_STATUS_C2H_REQNUM_MISMATCH;
87 		RTW_INFO("[MPT], Error!! C2H reqNum Mismatch!!\n");
88 	} else if (pExtC2h->opCodeVer != pH2c->opCodeVer) {
89 		c2hStatus = BT_STATUS_OPCODE_L_VERSION_MISMATCH;
90 		RTW_INFO("[MPT], Error!! OPCode version L mismatch!!\n");
91 	}
92 
93 	return c2hStatus;
94 }
95 
96 BT_CTRL_STATUS
mptbt_SendH2c(PADAPTER Adapter,PBT_H2C pH2c,u16 h2cCmdLen)97 mptbt_SendH2c(
98 	PADAPTER	Adapter,
99 	PBT_H2C	pH2c,
100 	u16		h2cCmdLen
101 )
102 {
103 	/* KIRQL				OldIrql = KeGetCurrentIrql(); */
104 	BT_CTRL_STATUS	h2cStatus = BT_STATUS_H2C_SUCCESS;
105 	PMPT_CONTEXT		pMptCtx = &(Adapter->mppriv.mpt_ctx);
106 	u8				i;
107 
108 	RTW_INFO("[MPT], mptbt_SendH2c()=========>\n");
109 
110 	/* PlatformResetEvent(&pMptCtx->MptH2cRspEvent); */
111 	/* PlatformResetEvent(&pMptCtx->MptBtC2hEvent); */
112 
113 	/*	if(OldIrql == PASSIVE_LEVEL)
114 	 *	{ */
115 	/* RTPRINT_DATA(FMPBT, FMPBT_H2C_CONTENT, ("[MPT], MPT H2C hex:\n"), pH2c, h2cCmdLen); */
116 
117 	for (i = 0; i < BT_H2C_MAX_RETRY; i++) {
118 		RTW_INFO("[MPT], Send H2C command to wifi!!!\n");
119 
120 		pMptCtx->MptH2cRspEvent = _FALSE;
121 		pMptCtx->MptBtC2hEvent = _FALSE;
122 
123 #if defined(CONFIG_RTL8723B)
124 		rtl8723b_set_FwBtMpOper_cmd(Adapter, pH2c->opCode, pH2c->opCodeVer, pH2c->reqNum, pH2c->buf);
125 #endif
126 		pMptCtx->h2cReqNum++;
127 		pMptCtx->h2cReqNum %= 16;
128 
129 		if (WaitC2Hevent(Adapter, &pMptCtx->MptH2cRspEvent, 100)) {
130 			RTW_INFO("[MPT], Received WiFi MptH2cRspEvent!!!\n");
131 			if (WaitC2Hevent(Adapter, &pMptCtx->MptBtC2hEvent, 400)) {
132 				RTW_INFO("[MPT], Received MptBtC2hEvent!!!\n");
133 				break;
134 			} else {
135 				RTW_INFO("[MPT], Error!!BT MptBtC2hEvent timeout!!\n");
136 				h2cStatus = BT_STATUS_H2C_BT_NO_RSP;
137 			}
138 		} else {
139 			RTW_INFO("[MPT], Error!!WiFi  MptH2cRspEvent timeout!!\n");
140 			h2cStatus = BT_STATUS_H2C_TIMTOUT;
141 		}
142 	}
143 	/*	}
144 	 *	else
145 	 *	{
146 	 * 		RT_ASSERT(FALSE, ("[MPT],  mptbt_SendH2c() can only run under PASSIVE_LEVEL!!\n"));
147 	 *		h2cStatus = BT_STATUS_WRONG_LEVEL;
148 	 *	} */
149 
150 	RTW_INFO("[MPT], mptbt_SendH2c()<=========\n");
151 	return h2cStatus;
152 }
153 
154 
155 
156 BT_CTRL_STATUS
mptbt_CheckBtRspStatus(PADAPTER Adapter,PBT_EXT_C2H pExtC2h)157 mptbt_CheckBtRspStatus(
158 	PADAPTER			Adapter,
159 	PBT_EXT_C2H			pExtC2h
160 )
161 {
162 	BT_CTRL_STATUS	retStatus = BT_OP_STATUS_SUCCESS;
163 
164 	switch (pExtC2h->statusCode) {
165 	case BT_OP_STATUS_SUCCESS:
166 		retStatus = BT_STATUS_BT_OP_SUCCESS;
167 		RTW_INFO("[MPT], BT status : BT_STATUS_SUCCESS\n");
168 		break;
169 	case BT_OP_STATUS_VERSION_MISMATCH:
170 		retStatus = BT_STATUS_OPCODE_L_VERSION_MISMATCH;
171 		RTW_INFO("[MPT], BT status : BT_STATUS_OPCODE_L_VERSION_MISMATCH\n");
172 		break;
173 	case BT_OP_STATUS_UNKNOWN_OPCODE:
174 		retStatus = BT_STATUS_UNKNOWN_OPCODE_L;
175 		RTW_INFO("[MPT], BT status : BT_STATUS_UNKNOWN_OPCODE_L\n");
176 		break;
177 	case BT_OP_STATUS_ERROR_PARAMETER:
178 		retStatus = BT_STATUS_PARAMETER_FORMAT_ERROR_L;
179 		RTW_INFO("[MPT], BT status : BT_STATUS_PARAMETER_FORMAT_ERROR_L\n");
180 		break;
181 	default:
182 		retStatus = BT_STATUS_UNKNOWN_STATUS_L;
183 		RTW_INFO("[MPT], BT status : BT_STATUS_UNKNOWN_STATUS_L\n");
184 		break;
185 	}
186 
187 	return retStatus;
188 }
189 
190 
191 
192 BT_CTRL_STATUS
mptbt_BtFwOpCodeProcess(PADAPTER Adapter,u8 btFwOpCode,u8 opCodeVer,u8 * pH2cPar,u8 h2cParaLen)193 mptbt_BtFwOpCodeProcess(
194 	PADAPTER		Adapter,
195 	u8			btFwOpCode,
196 	u8			opCodeVer,
197 	u8			*pH2cPar,
198 	u8			h2cParaLen
199 )
200 {
201 	u8				H2C_Parameter[6] = {0};
202 	PBT_H2C				pH2c = (PBT_H2C)&H2C_Parameter[0];
203 	PMPT_CONTEXT		pMptCtx = &(Adapter->mppriv.mpt_ctx);
204 	PBT_EXT_C2H			pExtC2h = (PBT_EXT_C2H)&pMptCtx->c2hBuf[0];
205 	u16				paraLen = 0, i;
206 	BT_CTRL_STATUS	h2cStatus = BT_STATUS_H2C_SUCCESS, c2hStatus = BT_STATUS_C2H_SUCCESS;
207 	BT_CTRL_STATUS	retStatus = BT_STATUS_H2C_BT_NO_RSP;
208 
209 	if (Adapter->registrypriv.mp_mode == 0) {
210 		RTW_INFO("[MPT], Error!! mptbt_BtFwOpCodeProces mp_mode == 0!!\n");
211 		return _FALSE;
212 	}
213 
214 	pH2c->opCode = btFwOpCode;
215 	pH2c->opCodeVer = opCodeVer;
216 	pH2c->reqNum = pMptCtx->h2cReqNum;
217 	/* PlatformMoveMemory(&pH2c->buf[0], pH2cPar, h2cParaLen); */
218 	/* _rtw_memcpy(&pH2c->buf[0], pH2cPar, h2cParaLen); */
219 	_rtw_memcpy(pH2c->buf, pH2cPar, h2cParaLen);
220 
221 	RTW_INFO("[MPT], pH2c->opCode=%d\n", pH2c->opCode);
222 	RTW_INFO("[MPT], pH2c->opCodeVer=%d\n", pH2c->opCodeVer);
223 	RTW_INFO("[MPT], pH2c->reqNum=%d\n", pH2c->reqNum);
224 	RTW_INFO("[MPT], h2c parameter length=%d\n", h2cParaLen);
225 	for (i = 0; i < h2cParaLen; i++)
226 		RTW_INFO("[MPT], parameter[%d]=0x%02x\n", i, pH2c->buf[i]);
227 
228 	h2cStatus = mptbt_SendH2c(Adapter, pH2c, h2cParaLen + 2);
229 	if (BT_STATUS_H2C_SUCCESS == h2cStatus) {
230 		/* if reach here, it means H2C get the correct c2h response, */
231 		c2hStatus = mptbt_CheckC2hFrame(Adapter, pH2c, pExtC2h);
232 		if (BT_STATUS_C2H_SUCCESS == c2hStatus)
233 			retStatus = mptbt_CheckBtRspStatus(Adapter, pExtC2h);
234 		else {
235 			RTW_INFO("[MPT], Error!! C2H failed for pH2c->opCode=%d\n", pH2c->opCode);
236 			/* check c2h status error, return error status code to upper layer. */
237 			retStatus = c2hStatus;
238 		}
239 	} else {
240 		RTW_INFO("[MPT], Error!! H2C failed for pH2c->opCode=%d\n", pH2c->opCode);
241 		/* check h2c status error, return error status code to upper layer. */
242 		retStatus = h2cStatus;
243 	}
244 
245 	return retStatus;
246 }
247 
248 
249 
250 
251 u16
mptbt_BtReady(PADAPTER Adapter,PBT_REQ_CMD pBtReq,PBT_RSP_CMD pBtRsp)252 mptbt_BtReady(
253 	PADAPTER		Adapter,
254 	PBT_REQ_CMD	pBtReq,
255 	PBT_RSP_CMD	pBtRsp
256 )
257 {
258 	u8				h2cParaBuf[6] = {0};
259 	u8				h2cParaLen = 0;
260 	u16				paraLen = 0;
261 	u8				retStatus = BT_STATUS_BT_OP_SUCCESS;
262 	u8				btOpcode;
263 	u8				btOpcodeVer = 0;
264 	PMPT_CONTEXT		pMptCtx = &(Adapter->mppriv.mpt_ctx);
265 	PBT_EXT_C2H			pExtC2h = (PBT_EXT_C2H)&pMptCtx->c2hBuf[0];
266 	u8				i;
267 	u8				btFwVer = 0, bdAddr[6] = {0};
268 	u16				btRealFwVer = 0;
269 	u16				*pu2Tmp = NULL;
270 
271 	/*  */
272 	/* check upper layer parameters */
273 	/*  */
274 
275 	/* 1. check upper layer opcode version */
276 	if (pBtReq->opCodeVer != 1) {
277 		RTW_INFO("[MPT], Error!! Upper OP code version not match!!!\n");
278 		pBtRsp->status = BT_STATUS_OPCODE_U_VERSION_MISMATCH;
279 		return paraLen;
280 	}
281 
282 	pBtRsp->pParamStart[0] = MP_BT_NOT_READY;
283 	paraLen = 10;
284 	/*  */
285 	/* execute lower layer opcodes */
286 	/*  */
287 
288 	/* Get BT FW version */
289 	/* fill h2c parameters */
290 	btOpcode = BT_LO_OP_GET_BT_VERSION;
291 	/* execute h2c and check respond c2h from bt fw is correct or not */
292 	retStatus = mptbt_BtFwOpCodeProcess(Adapter, btOpcode, btOpcodeVer, &h2cParaBuf[0], h2cParaLen);
293 	/* ckeck bt return status. */
294 	if (BT_STATUS_BT_OP_SUCCESS != retStatus) {
295 		pBtRsp->status = ((btOpcode << 8) | retStatus);
296 		RTW_INFO("[MPT], Error!! status code=0x%x\n", pBtRsp->status);
297 		return paraLen;
298 	} else {
299 		pu2Tmp = (u16 *)&pExtC2h->buf[0];
300 		btRealFwVer = *pu2Tmp;
301 		btFwVer = pExtC2h->buf[1];
302 		RTW_INFO("[MPT], btRealFwVer=0x%x, btFwVer=0x%x\n", btRealFwVer, btFwVer);
303 	}
304 
305 	/* Get BD Address */
306 	/* fill h2c parameters */
307 	btOpcode = BT_LO_OP_GET_BD_ADDR_L;
308 	/* execute h2c and check respond c2h from bt fw is correct or not */
309 	retStatus = mptbt_BtFwOpCodeProcess(Adapter, btOpcode, btOpcodeVer, &h2cParaBuf[0], h2cParaLen);
310 	/* ckeck bt return status. */
311 	if (BT_STATUS_BT_OP_SUCCESS != retStatus) {
312 		pBtRsp->status = ((btOpcode << 8) | retStatus);
313 		RTW_INFO("[MPT], Error!! status code=0x%x\n", pBtRsp->status);
314 		return paraLen;
315 	} else {
316 		bdAddr[5] = pExtC2h->buf[0];
317 		bdAddr[4] = pExtC2h->buf[1];
318 		bdAddr[3] = pExtC2h->buf[2];
319 	}
320 
321 	/* fill h2c parameters */
322 	btOpcode = BT_LO_OP_GET_BD_ADDR_H;
323 	/* execute h2c and check respond c2h from bt fw is correct or not */
324 	retStatus = mptbt_BtFwOpCodeProcess(Adapter, btOpcode, btOpcodeVer, &h2cParaBuf[0], h2cParaLen);
325 	/* ckeck bt return status. */
326 	if (BT_STATUS_BT_OP_SUCCESS != retStatus) {
327 		pBtRsp->status = ((btOpcode << 8) | retStatus);
328 		RTW_INFO("[MPT], Error!! status code=0x%x\n", pBtRsp->status);
329 		return paraLen;
330 	} else {
331 		bdAddr[2] = pExtC2h->buf[0];
332 		bdAddr[1] = pExtC2h->buf[1];
333 		bdAddr[0] = pExtC2h->buf[2];
334 	}
335 	RTW_INFO("[MPT], Local BDAddr:");
336 	for (i = 0; i < 6; i++)
337 		RTW_INFO(" 0x%x ", bdAddr[i]);
338 	pBtRsp->status = BT_STATUS_SUCCESS;
339 	pBtRsp->pParamStart[0] = MP_BT_READY;
340 	pu2Tmp = (u16 *)&pBtRsp->pParamStart[1];
341 	*pu2Tmp = btRealFwVer;
342 	pBtRsp->pParamStart[3] = btFwVer;
343 	for (i = 0; i < 6; i++)
344 		pBtRsp->pParamStart[4 + i] = bdAddr[5 - i];
345 
346 	return paraLen;
347 }
348 
mptbt_close_WiFiRF(PADAPTER Adapter)349 void mptbt_close_WiFiRF(PADAPTER Adapter)
350 {
351 	phy_set_bb_reg(Adapter, 0x824, 0xF, 0x0);
352 	phy_set_bb_reg(Adapter, 0x824, 0x700000, 0x0);
353 	phy_set_rf_reg(Adapter, RF_PATH_A, 0x0, 0xF0000, 0x0);
354 }
355 
mptbt_open_WiFiRF(PADAPTER Adapter)356 void mptbt_open_WiFiRF(PADAPTER	Adapter)
357 {
358 	phy_set_bb_reg(Adapter, 0x824, 0x700000, 0x3);
359 	phy_set_bb_reg(Adapter, 0x824, 0xF, 0x2);
360 	phy_set_rf_reg(Adapter, RF_PATH_A, 0x0, 0xF0000, 0x3);
361 }
362 
mptbt_switch_RF(PADAPTER Adapter,u8 Enter)363 u32 mptbt_switch_RF(PADAPTER	Adapter, u8	Enter)
364 {
365 	u16	tmp_2byte = 0;
366 
367 	/* Enter test mode */
368 	if (Enter) {
369 		/* 1>. close WiFi RF */
370 		mptbt_close_WiFiRF(Adapter);
371 
372 		/* 2>. change ant switch to BT */
373 		tmp_2byte = rtw_read16(Adapter, 0x860);
374 		tmp_2byte = tmp_2byte | BIT(9);
375 		tmp_2byte = tmp_2byte & (~BIT(8));
376 		rtw_write16(Adapter, 0x860, tmp_2byte);
377 		rtw_write16(Adapter, 0x870, 0x300);
378 	} else {
379 		/* 1>. Open WiFi RF */
380 		mptbt_open_WiFiRF(Adapter);
381 
382 		/* 2>. change ant switch back */
383 		tmp_2byte = rtw_read16(Adapter, 0x860);
384 		tmp_2byte = tmp_2byte | BIT(8);
385 		tmp_2byte = tmp_2byte & (~BIT(9));
386 		rtw_write16(Adapter, 0x860, tmp_2byte);
387 		rtw_write16(Adapter, 0x870, 0x300);
388 	}
389 
390 	return 0;
391 }
392 
393 u16
mptbt_BtSetMode(PADAPTER Adapter,PBT_REQ_CMD pBtReq,PBT_RSP_CMD pBtRsp)394 mptbt_BtSetMode(
395 	PADAPTER		Adapter,
396 	PBT_REQ_CMD	pBtReq,
397 	PBT_RSP_CMD	pBtRsp
398 )
399 {
400 	u8				h2cParaBuf[6] = {0};
401 	u8				h2cParaLen = 0;
402 	u16				paraLen = 0;
403 	u8				retStatus = BT_STATUS_BT_OP_SUCCESS;
404 	u8				btOpcode;
405 	u8				btOpcodeVer = 0;
406 	u8				btModeToSet = 0;
407 
408 	/*  */
409 	/* check upper layer parameters */
410 	/*  */
411 	/* 1. check upper layer opcode version */
412 	if (pBtReq->opCodeVer != 1) {
413 		RTW_INFO("[MPT], Error!! Upper OP code version not match!!!\n");
414 		pBtRsp->status = BT_STATUS_OPCODE_U_VERSION_MISMATCH;
415 		return paraLen;
416 	}
417 	/* 2. check upper layer parameter length */
418 	if (1 == pBtReq->paraLength) {
419 		btModeToSet = pBtReq->pParamStart[0];
420 		RTW_INFO("[MPT], BtTestMode=%d\n", btModeToSet);
421 	} else {
422 		RTW_INFO("[MPT], Error!! wrong parameter length=%d (should be 1)\n", pBtReq->paraLength);
423 		pBtRsp->status = BT_STATUS_PARAMETER_FORMAT_ERROR_U;
424 		return paraLen;
425 	}
426 
427 	/*  */
428 	/* execute lower layer opcodes */
429 	/*  */
430 
431 	/* 1. fill h2c parameters	 */
432 	/* check bt mode */
433 	btOpcode = BT_LO_OP_SET_BT_MODE;
434 	if (btModeToSet >= MP_BT_MODE_MAX) {
435 		pBtRsp->status = BT_STATUS_PARAMETER_OUT_OF_RANGE_U;
436 		return paraLen;
437 	} else {
438 		mptbt_switch_RF(Adapter, 1);
439 
440 		h2cParaBuf[0] = btModeToSet;
441 		h2cParaLen = 1;
442 		/* 2. execute h2c and check respond c2h from bt fw is correct or not */
443 		retStatus = mptbt_BtFwOpCodeProcess(Adapter, btOpcode, btOpcodeVer, &h2cParaBuf[0], h2cParaLen);
444 	}
445 
446 	/* 3. construct respond status code and data. */
447 	if (BT_STATUS_BT_OP_SUCCESS == retStatus)
448 		pBtRsp->status = BT_STATUS_SUCCESS;
449 	else {
450 		pBtRsp->status = ((btOpcode << 8) | retStatus);
451 		RTW_INFO("[MPT], Error!! status code=0x%x\n", pBtRsp->status);
452 	}
453 
454 	return paraLen;
455 }
456 
457 
458 void
MPTBT_FwC2hBtMpCtrl(PADAPTER Adapter,u8 * tmpBuf,u8 length)459 MPTBT_FwC2hBtMpCtrl(
460 	PADAPTER	Adapter,
461 	u8		*tmpBuf,
462 	u8		length
463 )
464 {
465 	u32 i;
466 	PMPT_CONTEXT	pMptCtx = &(Adapter->mppriv.mpt_ctx);
467 	PBT_EXT_C2H pExtC2h = (PBT_EXT_C2H)tmpBuf;
468 
469 	if (GET_HAL_DATA(Adapter)->bBTFWReady == _FALSE || Adapter->registrypriv.mp_mode == 0) {
470 		/* RTW_INFO("Ignore C2H BT MP Info since not in MP mode\n"); */
471 		return;
472 	}
473 	if (length > 32 || length < 3) {
474 		RTW_INFO("\n [MPT], pExtC2h->buf hex: length=%d > 32 || < 3\n", length);
475 		return;
476 	}
477 
478 	/* cancel_timeout for h2c handle */
479 	_cancel_timer_ex(&pMptCtx->MPh2c_timeout_timer);
480 
481 	for (i = 0; i < length; i++)
482 		RTW_INFO("[MPT], %s, buf[%d]=0x%02x ", __FUNCTION__, i, tmpBuf[i]);
483 	RTW_INFO("[MPT], pExtC2h->extendId=0x%x\n", pExtC2h->extendId);
484 
485 	switch (pExtC2h->extendId) {
486 	case EXT_C2H_WIFI_FW_ACTIVE_RSP:
487 		RTW_INFO("[MPT], EXT_C2H_WIFI_FW_ACTIVE_RSP\n");
488 #if 0
489 		RTW_INFO("[MPT], pExtC2h->buf hex:\n");
490 		for (i = 0; i < (length - 3); i++)
491 			RTW_INFO(" 0x%x ", pExtC2h->buf[i]);
492 #endif
493 		if ((_FALSE == pMptCtx->bMPh2c_timeout)
494 		    && (_FALSE == pMptCtx->MptH2cRspEvent)) {
495 			pMptCtx->MptH2cRspEvent = _TRUE;
496 			_rtw_up_sema(&pMptCtx->MPh2c_Sema);
497 		}
498 		break;
499 
500 	case EXT_C2H_TRIG_BY_BT_FW:
501 		RTW_INFO("[MPT], EXT_C2H_TRIG_BY_BT_FW\n");
502 		_rtw_memcpy(&pMptCtx->c2hBuf[0], tmpBuf, length);
503 		RTW_INFO("[MPT], pExtC2h->statusCode=0x%x\n", pExtC2h->statusCode);
504 		RTW_INFO("[MPT], pExtC2h->retLen=0x%x\n", pExtC2h->retLen);
505 		RTW_INFO("[MPT], pExtC2h->opCodeVer=0x%x\n", pExtC2h->opCodeVer);
506 		RTW_INFO("[MPT], pExtC2h->reqNum=0x%x\n", pExtC2h->reqNum);
507 		for (i = 0; i < (length - 3); i++)
508 			RTW_INFO("[MPT], pExtC2h->buf[%d]=0x%02x\n", i, pExtC2h->buf[i]);
509 
510 		if ((_FALSE == pMptCtx->bMPh2c_timeout)
511 		    && (_TRUE == pMptCtx->MptH2cRspEvent)
512 		    && (_FALSE == pMptCtx->MptBtC2hEvent)) {
513 			pMptCtx->MptBtC2hEvent = _TRUE;
514 			_rtw_up_sema(&pMptCtx->MPh2c_Sema);
515 		}
516 		break;
517 
518 	default:
519 		RTW_INFO("[MPT], EXT_C2H Target not found,pExtC2h->extendId =%d ,pExtC2h->reqNum=%d\n", pExtC2h->extendId, pExtC2h->reqNum);
520 		break;
521 	}
522 
523 
524 
525 }
526 
527 
528 u16
mptbt_BtGetGeneral(PADAPTER Adapter,PBT_REQ_CMD pBtReq,PBT_RSP_CMD pBtRsp)529 mptbt_BtGetGeneral(
530 		PADAPTER		Adapter,
531 		PBT_REQ_CMD	pBtReq,
532 		PBT_RSP_CMD	pBtRsp
533 )
534 {
535 	PMPT_CONTEXT		pMptCtx = &(Adapter->mppriv.mpt_ctx);
536 	PBT_EXT_C2H		pExtC2h = (PBT_EXT_C2H)&pMptCtx->c2hBuf[0];
537 	u8				h2cParaBuf[6] = {0};
538 	u8				h2cParaLen = 0;
539 	u16				paraLen = 0;
540 	u8				retStatus = BT_STATUS_BT_OP_SUCCESS;
541 	u8				btOpcode, bdAddr[6] = {0};
542 	u8				btOpcodeVer = 0;
543 	u8				getType = 0, i;
544 	u16				getParaLen = 0, validParaLen = 0;
545 	u8				regType = 0, reportType = 0;
546 	u32				regAddr = 0, regValue = 0;
547 	u32 				*pu4Tmp;
548 	u16 				*pu2Tmp;
549 	u8 				*pu1Tmp;
550 
551 	/*  */
552 	/* check upper layer parameters */
553 	/*  */
554 
555 	/* check upper layer opcode version */
556 	if (pBtReq->opCodeVer != 1) {
557 		RTW_INFO("[MPT], Error!! Upper OP code version not match!!!\n");
558 		pBtRsp->status = BT_STATUS_OPCODE_U_VERSION_MISMATCH;
559 		return paraLen;
560 	}
561 	/* check upper layer parameter length */
562 	if (pBtReq->paraLength < 1) {
563 		RTW_INFO("[MPT], Error!! wrong parameter length=%d (should larger than 1)\n", pBtReq->paraLength);
564 		pBtRsp->status = BT_STATUS_PARAMETER_FORMAT_ERROR_U;
565 		return paraLen;
566 	}
567 	getParaLen = pBtReq->paraLength - 1;
568 	getType = pBtReq->pParamStart[0];
569 
570 	RTW_INFO("[MPT], getType=%d, getParaLen=%d\n", getType, getParaLen);
571 
572 	/* check parameter first */
573 	switch (getType) {
574 	case BT_GGET_REG:
575 		RTW_INFO("[MPT], [BT_GGET_REG]\n");
576 		validParaLen = 5;
577 		if (getParaLen == validParaLen) {
578 			btOpcode = BT_LO_OP_READ_REG;
579 			regType = pBtReq->pParamStart[1];
580 			pu4Tmp = (u32 *)&pBtReq->pParamStart[2];
581 			regAddr = *pu4Tmp;
582 			RTW_INFO("[MPT], BT_GGET_REG regType=0x%02x, regAddr=0x%08x!!\n",
583 				 regType, regAddr);
584 			if (regType >= BT_REG_MAX) {
585 				pBtRsp->status = (btOpcode << 8) | BT_STATUS_PARAMETER_OUT_OF_RANGE_U;
586 				return paraLen;
587 			} else {
588 				if (((BT_REG_RF == regType) && (regAddr > 0x7f)) ||
589 				    ((BT_REG_MODEM == regType) && (regAddr > 0x1ff)) ||
590 				    ((BT_REG_BLUEWIZE == regType) && (regAddr > 0xfff)) ||
591 				    ((BT_REG_VENDOR == regType) && (regAddr > 0xfff)) ||
592 				    ((BT_REG_LE == regType) && (regAddr > 0xfff))) {
593 					pBtRsp->status = (btOpcode << 8) | BT_STATUS_PARAMETER_OUT_OF_RANGE_U;
594 					return paraLen;
595 				}
596 			}
597 		}
598 		break;
599 	case BT_GGET_STATUS:
600 		RTW_INFO("[MPT], [BT_GGET_STATUS]\n");
601 		validParaLen = 0;
602 		break;
603 	case BT_GGET_REPORT:
604 		RTW_INFO("[MPT], [BT_GGET_REPORT]\n");
605 		validParaLen = 1;
606 		if (getParaLen == validParaLen) {
607 			reportType = pBtReq->pParamStart[1];
608 			RTW_INFO("[MPT], BT_GGET_REPORT reportType=0x%x!!\n", reportType);
609 			if (reportType >= BT_REPORT_MAX) {
610 				pBtRsp->status = BT_STATUS_PARAMETER_OUT_OF_RANGE_U;
611 				return paraLen;
612 			}
613 		}
614 		break;
615 	default: {
616 		RTW_INFO("[MPT], Error!! getType=%d, out of range\n", getType);
617 		pBtRsp->status = BT_STATUS_PARAMETER_OUT_OF_RANGE_U;
618 		return paraLen;
619 	}
620 	break;
621 	}
622 	if (getParaLen != validParaLen) {
623 		RTW_INFO("[MPT], Error!! wrong parameter length=%d for BT_GET_GEN_CMD cmd id=0x%x, paraLen should=0x%x\n",
624 			 getParaLen, getType, validParaLen);
625 		pBtRsp->status = BT_STATUS_PARAMETER_FORMAT_ERROR_U;
626 		return paraLen;
627 	}
628 
629 	/*  */
630 	/* execute lower layer opcodes */
631 	/*  */
632 	if (BT_GGET_REG == getType) {
633 		/* fill h2c parameters */
634 		/* here we should write reg value first then write the address, adviced by Austin */
635 		btOpcode = BT_LO_OP_READ_REG;
636 		h2cParaBuf[0] = regType;
637 		h2cParaBuf[1] = pBtReq->pParamStart[2];
638 		h2cParaBuf[2] = pBtReq->pParamStart[3];
639 		h2cParaLen = 3;
640 		/* execute h2c and check respond c2h from bt fw is correct or not */
641 		retStatus = mptbt_BtFwOpCodeProcess(Adapter, btOpcode, btOpcodeVer, &h2cParaBuf[0], h2cParaLen);
642 		/* construct respond status code and data. */
643 		if (BT_STATUS_BT_OP_SUCCESS != retStatus) {
644 			pBtRsp->status = ((btOpcode << 8) | retStatus);
645 			RTW_INFO("[MPT], Error!! status code=0x%x\n", pBtRsp->status);
646 			return paraLen;
647 		}
648 
649 		pu2Tmp = (u16 *)&pExtC2h->buf[0];
650 		regValue = *pu2Tmp;
651 		RTW_INFO("[MPT], read reg regType=0x%02x, regAddr=0x%08x, regValue=0x%04x\n",
652 			 regType, regAddr, regValue);
653 
654 		pu4Tmp = (u32 *)&pBtRsp->pParamStart[0];
655 		*pu4Tmp = regValue;
656 		paraLen = 4;
657 	} else if (BT_GGET_STATUS == getType) {
658 		btOpcode = BT_LO_OP_GET_BT_STATUS;
659 		h2cParaLen = 0;
660 		/* execute h2c and check respond c2h from bt fw is correct or not */
661 		retStatus = mptbt_BtFwOpCodeProcess(Adapter, btOpcode, btOpcodeVer, &h2cParaBuf[0], h2cParaLen);
662 		/* construct respond status code and data. */
663 		if (BT_STATUS_BT_OP_SUCCESS != retStatus) {
664 			pBtRsp->status = ((btOpcode << 8) | retStatus);
665 			RTW_INFO("[MPT], Error!! status code=0x%x\n", pBtRsp->status);
666 			return paraLen;
667 		}
668 
669 		pBtRsp->pParamStart[0] = pExtC2h->buf[0];
670 		pBtRsp->pParamStart[1] = pExtC2h->buf[1];
671 		RTW_INFO("[MPT], read bt status, testMode=0x%x, testStatus=0x%x\n",
672 			 pBtRsp->pParamStart[0], pBtRsp->pParamStart[1]);
673 		paraLen = 2;
674 	} else if (BT_GGET_REPORT == getType) {
675 		switch (reportType) {
676 		case BT_REPORT_RX_PACKET_CNT: {
677 			RTW_INFO("[MPT], [Rx Packet Counts]\n");
678 			btOpcode = BT_LO_OP_GET_RX_PKT_CNT_L;
679 			h2cParaLen = 0;
680 			/* execute h2c and check respond c2h from bt fw is correct or not */
681 			retStatus = mptbt_BtFwOpCodeProcess(Adapter, btOpcode, btOpcodeVer, &h2cParaBuf[0], h2cParaLen);
682 			/* construct respond status code and data. */
683 			if (BT_STATUS_BT_OP_SUCCESS != retStatus) {
684 				pBtRsp->status = ((btOpcode << 8) | retStatus);
685 				RTW_INFO("[MPT], Error!! status code=0x%x\n", pBtRsp->status);
686 				return paraLen;
687 			}
688 			pBtRsp->pParamStart[0] = pExtC2h->buf[0];
689 			pBtRsp->pParamStart[1] = pExtC2h->buf[1];
690 
691 			btOpcode = BT_LO_OP_GET_RX_PKT_CNT_H;
692 			h2cParaLen = 0;
693 			/* execute h2c and check respond c2h from bt fw is correct or not */
694 			retStatus = mptbt_BtFwOpCodeProcess(Adapter, btOpcode, btOpcodeVer, &h2cParaBuf[0], h2cParaLen);
695 			/* construct respond status code and data. */
696 			if (BT_STATUS_BT_OP_SUCCESS != retStatus) {
697 				pBtRsp->status = ((btOpcode << 8) | retStatus);
698 				RTW_INFO("[MPT], Error!! status code=0x%x\n", pBtRsp->status);
699 				return paraLen;
700 			}
701 			pBtRsp->pParamStart[2] = pExtC2h->buf[0];
702 			pBtRsp->pParamStart[3] = pExtC2h->buf[1];
703 			paraLen = 4;
704 		}
705 		break;
706 		case BT_REPORT_RX_ERROR_BITS: {
707 			RTW_INFO("[MPT], [Rx Error Bits]\n");
708 			btOpcode = BT_LO_OP_GET_RX_ERROR_BITS_L;
709 			h2cParaLen = 0;
710 			/* execute h2c and check respond c2h from bt fw is correct or not */
711 			retStatus = mptbt_BtFwOpCodeProcess(Adapter, btOpcode, btOpcodeVer, &h2cParaBuf[0], h2cParaLen);
712 			/* construct respond status code and data. */
713 			if (BT_STATUS_BT_OP_SUCCESS != retStatus) {
714 				pBtRsp->status = ((btOpcode << 8) | retStatus);
715 				RTW_INFO("[MPT], Error!! status code=0x%x\n", pBtRsp->status);
716 				return paraLen;
717 			}
718 			pBtRsp->pParamStart[0] = pExtC2h->buf[0];
719 			pBtRsp->pParamStart[1] = pExtC2h->buf[1];
720 
721 			btOpcode = BT_LO_OP_GET_RX_ERROR_BITS_H;
722 			h2cParaLen = 0;
723 			/* execute h2c and check respond c2h from bt fw is correct or not */
724 			retStatus = mptbt_BtFwOpCodeProcess(Adapter, btOpcode, btOpcodeVer, &h2cParaBuf[0], h2cParaLen);
725 			/* construct respond status code and data. */
726 			if (BT_STATUS_BT_OP_SUCCESS != retStatus) {
727 				pBtRsp->status = ((btOpcode << 8) | retStatus);
728 				RTW_INFO("[MPT], Error!! status code=0x%x\n", pBtRsp->status);
729 				return paraLen;
730 			}
731 			pBtRsp->pParamStart[2] = pExtC2h->buf[0];
732 			pBtRsp->pParamStart[3] = pExtC2h->buf[1];
733 			paraLen = 4;
734 		}
735 		break;
736 		case BT_REPORT_RSSI: {
737 			RTW_INFO("[MPT], [RSSI]\n");
738 			btOpcode = BT_LO_OP_GET_RSSI;
739 			h2cParaLen = 0;
740 			/* execute h2c and check respond c2h from bt fw is correct or not */
741 			retStatus = mptbt_BtFwOpCodeProcess(Adapter, btOpcode, btOpcodeVer, &h2cParaBuf[0], h2cParaLen);
742 			/* construct respond status code and data. */
743 			if (BT_STATUS_BT_OP_SUCCESS != retStatus) {
744 				pBtRsp->status = ((btOpcode << 8) | retStatus);
745 				RTW_INFO("[MPT], Error!! status code=0x%x\n", pBtRsp->status);
746 				return paraLen;
747 			}
748 			pBtRsp->pParamStart[0] = pExtC2h->buf[0];
749 			pBtRsp->pParamStart[1] = pExtC2h->buf[1];
750 			paraLen = 2;
751 		}
752 		break;
753 		case BT_REPORT_CFO_HDR_QUALITY: {
754 			RTW_INFO("[MPT], [CFO & Header Quality]\n");
755 			btOpcode = BT_LO_OP_GET_CFO_HDR_QUALITY_L;
756 			h2cParaLen = 0;
757 			/* execute h2c and check respond c2h from bt fw is correct or not */
758 			retStatus = mptbt_BtFwOpCodeProcess(Adapter, btOpcode, btOpcodeVer, &h2cParaBuf[0], h2cParaLen);
759 			/* construct respond status code and data. */
760 			if (BT_STATUS_BT_OP_SUCCESS != retStatus) {
761 				pBtRsp->status = ((btOpcode << 8) | retStatus);
762 				RTW_INFO("[MPT], Error!! status code=0x%x\n", pBtRsp->status);
763 				return paraLen;
764 			}
765 			pBtRsp->pParamStart[0] = pExtC2h->buf[0];
766 			pBtRsp->pParamStart[1] = pExtC2h->buf[1];
767 
768 			btOpcode = BT_LO_OP_GET_CFO_HDR_QUALITY_H;
769 			h2cParaLen = 0;
770 			/* execute h2c and check respond c2h from bt fw is correct or not */
771 			retStatus = mptbt_BtFwOpCodeProcess(Adapter, btOpcode, btOpcodeVer, &h2cParaBuf[0], h2cParaLen);
772 			/* construct respond status code and data. */
773 			if (BT_STATUS_BT_OP_SUCCESS != retStatus) {
774 				pBtRsp->status = ((btOpcode << 8) | retStatus);
775 				RTW_INFO("[MPT], Error!! status code=0x%x\n", pBtRsp->status);
776 				return paraLen;
777 			}
778 			pBtRsp->pParamStart[2] = pExtC2h->buf[0];
779 			pBtRsp->pParamStart[3] = pExtC2h->buf[1];
780 			paraLen = 4;
781 		}
782 		break;
783 		case BT_REPORT_CONNECT_TARGET_BD_ADDR: {
784 			RTW_INFO("[MPT], [Connected Target BD ADDR]\n");
785 			btOpcode = BT_LO_OP_GET_TARGET_BD_ADDR_L;
786 			h2cParaLen = 0;
787 			/* execute h2c and check respond c2h from bt fw is correct or not */
788 			retStatus = mptbt_BtFwOpCodeProcess(Adapter, btOpcode, btOpcodeVer, &h2cParaBuf[0], h2cParaLen);
789 			/* construct respond status code and data. */
790 			if (BT_STATUS_BT_OP_SUCCESS != retStatus) {
791 				pBtRsp->status = ((btOpcode << 8) | retStatus);
792 				RTW_INFO("[MPT], Error!! status code=0x%x\n", pBtRsp->status);
793 				return paraLen;
794 			}
795 			bdAddr[5] = pExtC2h->buf[0];
796 			bdAddr[4] = pExtC2h->buf[1];
797 			bdAddr[3] = pExtC2h->buf[2];
798 
799 			btOpcode = BT_LO_OP_GET_TARGET_BD_ADDR_H;
800 			h2cParaLen = 0;
801 			/* execute h2c and check respond c2h from bt fw is correct or not */
802 			retStatus = mptbt_BtFwOpCodeProcess(Adapter, btOpcode, btOpcodeVer, &h2cParaBuf[0], h2cParaLen);
803 			/* construct respond status code and data. */
804 			if (BT_STATUS_BT_OP_SUCCESS != retStatus) {
805 				pBtRsp->status = ((btOpcode << 8) | retStatus);
806 				RTW_INFO("[MPT], Error!! status code=0x%x\n", pBtRsp->status);
807 				return paraLen;
808 			}
809 			bdAddr[2] = pExtC2h->buf[0];
810 			bdAddr[1] = pExtC2h->buf[1];
811 			bdAddr[0] = pExtC2h->buf[2];
812 
813 			RTW_INFO("[MPT], Connected Target BDAddr:%s", bdAddr);
814 			for (i = 0; i < 6; i++)
815 				pBtRsp->pParamStart[i] = bdAddr[5 - i];
816 			paraLen = 6;
817 		}
818 		break;
819 		default:
820 			pBtRsp->status = BT_STATUS_PARAMETER_OUT_OF_RANGE_U;
821 			return paraLen;
822 			break;
823 		}
824 	}
825 
826 	pBtRsp->status = BT_STATUS_SUCCESS;
827 	return paraLen;
828 }
829 
830 
831 
832 u16
mptbt_BtSetGeneral(PADAPTER Adapter,PBT_REQ_CMD pBtReq,PBT_RSP_CMD pBtRsp)833 mptbt_BtSetGeneral(
834 		PADAPTER		Adapter,
835 		PBT_REQ_CMD	pBtReq,
836 		PBT_RSP_CMD	pBtRsp
837 )
838 {
839 	u8				h2cParaBuf[6] = {0};
840 	u8				h2cParaLen = 0;
841 	u16				paraLen = 0;
842 	u8				retStatus = BT_STATUS_BT_OP_SUCCESS;
843 	u8				btOpcode;
844 	u8				btOpcodeVer = 0;
845 	u8				setType = 0;
846 	u16				setParaLen = 0, validParaLen = 0;
847 	u8				regType = 0, bdAddr[6] = {0}, calVal = 0;
848 	u32				regAddr = 0, regValue = 0;
849 	u32 				*pu4Tmp;
850 	u16 				*pu2Tmp;
851 	u8 				*pu1Tmp;
852 
853 	/*  */
854 	/* check upper layer parameters */
855 	/*  */
856 
857 	/* check upper layer opcode version */
858 	if (pBtReq->opCodeVer != 1) {
859 		RTW_INFO("[MPT], Error!! Upper OP code version not match!!!\n");
860 		pBtRsp->status = BT_STATUS_OPCODE_U_VERSION_MISMATCH;
861 		return paraLen;
862 	}
863 	/* check upper layer parameter length */
864 	if (pBtReq->paraLength < 1) {
865 		RTW_INFO("[MPT], Error!! wrong parameter length=%d (should larger than 1)\n", pBtReq->paraLength);
866 		pBtRsp->status = BT_STATUS_PARAMETER_FORMAT_ERROR_U;
867 		return paraLen;
868 	}
869 	setParaLen = pBtReq->paraLength - 1;
870 	setType = pBtReq->pParamStart[0];
871 
872 	RTW_INFO("[MPT], setType=%d, setParaLen=%d\n", setType, setParaLen);
873 
874 	/* check parameter first */
875 	switch (setType) {
876 	case BT_GSET_REG:
877 		RTW_INFO("[MPT], [BT_GSET_REG]\n");
878 		validParaLen = 9;
879 		if (setParaLen == validParaLen) {
880 			btOpcode = BT_LO_OP_WRITE_REG_VALUE;
881 			regType = pBtReq->pParamStart[1];
882 			pu4Tmp = (u32 *)&pBtReq->pParamStart[2];
883 			regAddr = *pu4Tmp;
884 			pu4Tmp = (u32 *)&pBtReq->pParamStart[6];
885 			regValue = *pu4Tmp;
886 			RTW_INFO("[MPT], BT_GSET_REG regType=0x%x, regAddr=0x%x, regValue=0x%x!!\n",
887 				 regType, regAddr, regValue);
888 			if (regType >= BT_REG_MAX) {
889 				pBtRsp->status = (btOpcode << 8) | BT_STATUS_PARAMETER_OUT_OF_RANGE_U;
890 				return paraLen;
891 			} else {
892 				if (((BT_REG_RF == regType) && (regAddr > 0x7f)) ||
893 				    ((BT_REG_MODEM == regType) && (regAddr > 0x1ff)) ||
894 				    ((BT_REG_BLUEWIZE == regType) && (regAddr > 0xfff)) ||
895 				    ((BT_REG_VENDOR == regType) && (regAddr > 0xfff)) ||
896 				    ((BT_REG_LE == regType) && (regAddr > 0xfff))) {
897 					pBtRsp->status = (btOpcode << 8) | BT_STATUS_PARAMETER_OUT_OF_RANGE_U;
898 					return paraLen;
899 				}
900 			}
901 		}
902 		break;
903 	case BT_GSET_RESET:
904 		RTW_INFO("[MPT], [BT_GSET_RESET]\n");
905 		validParaLen = 0;
906 		break;
907 	case BT_GSET_TARGET_BD_ADDR:
908 		RTW_INFO("[MPT], [BT_GSET_TARGET_BD_ADDR]\n");
909 		validParaLen = 6;
910 		if (setParaLen == validParaLen) {
911 			btOpcode = BT_LO_OP_SET_TARGET_BD_ADDR_H;
912 			if ((pBtReq->pParamStart[1] == 0) &&
913 			    (pBtReq->pParamStart[2] == 0) &&
914 			    (pBtReq->pParamStart[3] == 0) &&
915 			    (pBtReq->pParamStart[4] == 0) &&
916 			    (pBtReq->pParamStart[5] == 0) &&
917 			    (pBtReq->pParamStart[6] == 0)) {
918 				RTW_INFO("[MPT], Error!! targetBDAddr=all zero\n");
919 				pBtRsp->status = (btOpcode << 8) | BT_STATUS_PARAMETER_OUT_OF_RANGE_U;
920 				return paraLen;
921 			}
922 			if ((pBtReq->pParamStart[1] == 0xff) &&
923 			    (pBtReq->pParamStart[2] == 0xff) &&
924 			    (pBtReq->pParamStart[3] == 0xff) &&
925 			    (pBtReq->pParamStart[4] == 0xff) &&
926 			    (pBtReq->pParamStart[5] == 0xff) &&
927 			    (pBtReq->pParamStart[6] == 0xff)) {
928 				RTW_INFO("[MPT], Error!! targetBDAddr=all 0xf\n");
929 				pBtRsp->status = (btOpcode << 8) | BT_STATUS_PARAMETER_OUT_OF_RANGE_U;
930 				return paraLen;
931 			}
932 			bdAddr[0] = pBtReq->pParamStart[6];
933 			bdAddr[1] = pBtReq->pParamStart[5];
934 			bdAddr[2] = pBtReq->pParamStart[4];
935 			bdAddr[3] = pBtReq->pParamStart[3];
936 			bdAddr[4] = pBtReq->pParamStart[2];
937 			bdAddr[5] = pBtReq->pParamStart[1];
938 			RTW_INFO("[MPT], target BDAddr:%x,%x,%x,%x,%x,%x\n",
939 				bdAddr[0], bdAddr[1], bdAddr[2], bdAddr[3], bdAddr[4], bdAddr[5]);
940 		}
941 		break;
942 	case BT_GSET_TX_PWR_FINETUNE:
943 		RTW_INFO("[MPT], [BT_GSET_TX_PWR_FINETUNE]\n");
944 		validParaLen = 1;
945 		if (setParaLen == validParaLen) {
946 			btOpcode = BT_LO_OP_SET_TX_POWER_CALIBRATION;
947 			calVal = pBtReq->pParamStart[1];
948 			if ((calVal < 1) || (calVal > 9)) {
949 				pBtRsp->status = (btOpcode << 8) | BT_STATUS_PARAMETER_OUT_OF_RANGE_U;
950 				return paraLen;
951 			}
952 			RTW_INFO("[MPT], calVal=%d\n", calVal);
953 		}
954 		break;
955 	case BT_SET_TRACKING_INTERVAL:
956 		RTW_INFO("[MPT], [BT_SET_TRACKING_INTERVAL] setParaLen =%d\n", setParaLen);
957 
958 		validParaLen = 1;
959 		if (setParaLen == validParaLen)
960 			calVal = pBtReq->pParamStart[1];
961 		break;
962 	case BT_SET_THERMAL_METER:
963 		RTW_INFO("[MPT], [BT_SET_THERMAL_METER] setParaLen =%d\n", setParaLen);
964 		validParaLen = 1;
965 		if (setParaLen == validParaLen)
966 			calVal = pBtReq->pParamStart[1];
967 		break;
968 	case BT_ENABLE_CFO_TRACKING:
969 		RTW_INFO("[MPT], [BT_ENABLE_CFO_TRACKING] setParaLen =%d\n", setParaLen);
970 		validParaLen = 1;
971 		if (setParaLen == validParaLen)
972 			calVal = pBtReq->pParamStart[1];
973 		break;
974 	case BT_GSET_UPDATE_BT_PATCH:
975 
976 		break;
977 	default: {
978 		RTW_INFO("[MPT], Error!! setType=%d, out of range\n", setType);
979 		pBtRsp->status = BT_STATUS_PARAMETER_OUT_OF_RANGE_U;
980 		return paraLen;
981 	}
982 	break;
983 	}
984 	if (setParaLen != validParaLen) {
985 		RTW_INFO("[MPT], Error!! wrong parameter length=%d for BT_SET_GEN_CMD cmd id=0x%x, paraLen should=0x%x\n",
986 			 setParaLen, setType, validParaLen);
987 		pBtRsp->status = BT_STATUS_PARAMETER_FORMAT_ERROR_U;
988 		return paraLen;
989 	}
990 
991 	/*  */
992 	/* execute lower layer opcodes */
993 	/*  */
994 	if (BT_GSET_REG == setType) {
995 		/* fill h2c parameters */
996 		/* here we should write reg value first then write the address, adviced by Austin */
997 		btOpcode = BT_LO_OP_WRITE_REG_VALUE;
998 		h2cParaBuf[0] = pBtReq->pParamStart[6];
999 		h2cParaBuf[1] = pBtReq->pParamStart[7];
1000 		h2cParaBuf[2] = pBtReq->pParamStart[8];
1001 		h2cParaLen = 3;
1002 		/* execute h2c and check respond c2h from bt fw is correct or not */
1003 		retStatus = mptbt_BtFwOpCodeProcess(Adapter, btOpcode, btOpcodeVer, &h2cParaBuf[0], h2cParaLen);
1004 		/* construct respond status code and data. */
1005 		if (BT_STATUS_BT_OP_SUCCESS != retStatus) {
1006 			pBtRsp->status = ((btOpcode << 8) | retStatus);
1007 			RTW_INFO("[MPT], Error!! status code=0x%x\n", pBtRsp->status);
1008 			return paraLen;
1009 		}
1010 
1011 		/* write reg address */
1012 		btOpcode = BT_LO_OP_WRITE_REG_ADDR;
1013 		h2cParaBuf[0] = regType;
1014 		h2cParaBuf[1] = pBtReq->pParamStart[2];
1015 		h2cParaBuf[2] = pBtReq->pParamStart[3];
1016 		h2cParaLen = 3;
1017 		/* execute h2c and check respond c2h from bt fw is correct or not */
1018 		retStatus = mptbt_BtFwOpCodeProcess(Adapter, btOpcode, btOpcodeVer, &h2cParaBuf[0], h2cParaLen);
1019 		/* construct respond status code and data. */
1020 		if (BT_STATUS_BT_OP_SUCCESS != retStatus) {
1021 			pBtRsp->status = ((btOpcode << 8) | retStatus);
1022 			RTW_INFO("[MPT], Error!! status code=0x%x\n", pBtRsp->status);
1023 			return paraLen;
1024 		}
1025 	} else if (BT_GSET_RESET == setType) {
1026 		btOpcode = BT_LO_OP_RESET;
1027 		h2cParaLen = 0;
1028 		/* execute h2c and check respond c2h from bt fw is correct or not */
1029 		retStatus = mptbt_BtFwOpCodeProcess(Adapter, btOpcode, btOpcodeVer, &h2cParaBuf[0], h2cParaLen);
1030 		/* construct respond status code and data. */
1031 		if (BT_STATUS_BT_OP_SUCCESS != retStatus) {
1032 			pBtRsp->status = ((btOpcode << 8) | retStatus);
1033 			RTW_INFO("[MPT], Error!! status code=0x%x\n", pBtRsp->status);
1034 			return paraLen;
1035 		}
1036 	} else if (BT_GSET_TARGET_BD_ADDR == setType) {
1037 		/* fill h2c parameters */
1038 		btOpcode = BT_LO_OP_SET_TARGET_BD_ADDR_L;
1039 		h2cParaBuf[0] = pBtReq->pParamStart[1];
1040 		h2cParaBuf[1] = pBtReq->pParamStart[2];
1041 		h2cParaBuf[2] = pBtReq->pParamStart[3];
1042 		h2cParaLen = 3;
1043 		retStatus = mptbt_BtFwOpCodeProcess(Adapter, btOpcode, btOpcodeVer, &h2cParaBuf[0], h2cParaLen);
1044 		/* ckeck bt return status. */
1045 		if (BT_STATUS_BT_OP_SUCCESS != retStatus) {
1046 			pBtRsp->status = ((btOpcode << 8) | retStatus);
1047 			RTW_INFO("[MPT], Error!! status code=0x%x\n", pBtRsp->status);
1048 			return paraLen;
1049 		}
1050 
1051 		btOpcode = BT_LO_OP_SET_TARGET_BD_ADDR_H;
1052 		h2cParaBuf[0] = pBtReq->pParamStart[4];
1053 		h2cParaBuf[1] = pBtReq->pParamStart[5];
1054 		h2cParaBuf[2] = pBtReq->pParamStart[6];
1055 		h2cParaLen = 3;
1056 		retStatus = mptbt_BtFwOpCodeProcess(Adapter, btOpcode, btOpcodeVer, &h2cParaBuf[0], h2cParaLen);
1057 		/* ckeck bt return status. */
1058 		if (BT_STATUS_BT_OP_SUCCESS != retStatus) {
1059 			pBtRsp->status = ((btOpcode << 8) | retStatus);
1060 			RTW_INFO("[MPT], Error!! status code=0x%x\n", pBtRsp->status);
1061 			return paraLen;
1062 		}
1063 	} else if (BT_GSET_TX_PWR_FINETUNE == setType) {
1064 		/* fill h2c parameters */
1065 		btOpcode = BT_LO_OP_SET_TX_POWER_CALIBRATION;
1066 		h2cParaBuf[0] = calVal;
1067 		h2cParaLen = 1;
1068 		retStatus = mptbt_BtFwOpCodeProcess(Adapter, btOpcode, btOpcodeVer, &h2cParaBuf[0], h2cParaLen);
1069 		/* ckeck bt return status. */
1070 		if (BT_STATUS_BT_OP_SUCCESS != retStatus) {
1071 			pBtRsp->status = ((btOpcode << 8) | retStatus);
1072 			RTW_INFO("[MPT], Error!! status code=0x%x\n", pBtRsp->status);
1073 			return paraLen;
1074 		}
1075 	} else if (BT_SET_TRACKING_INTERVAL == setType) {
1076 		/*	BT_LO_OP_SET_TRACKING_INTERVAL								= 0x22, */
1077 		/*	BT_LO_OP_SET_THERMAL_METER									= 0x23, */
1078 		/*	BT_LO_OP_ENABLE_CFO_TRACKING									= 0x24, */
1079 		btOpcode = BT_LO_OP_SET_TRACKING_INTERVAL;
1080 		h2cParaBuf[0] = calVal;
1081 		h2cParaLen = 1;
1082 		retStatus = mptbt_BtFwOpCodeProcess(Adapter, btOpcode, btOpcodeVer, &h2cParaBuf[0], h2cParaLen);
1083 		/* ckeck bt return status. */
1084 		if (BT_STATUS_BT_OP_SUCCESS != retStatus) {
1085 			pBtRsp->status = ((btOpcode << 8) | retStatus);
1086 			RTW_INFO("[MPT], Error!! status code=0x%x\n", pBtRsp->status);
1087 			return paraLen;
1088 		}
1089 	} else if (BT_SET_THERMAL_METER == setType) {
1090 		btOpcode = BT_LO_OP_SET_THERMAL_METER;
1091 		h2cParaBuf[0] = calVal;
1092 		h2cParaLen = 1;
1093 		retStatus = mptbt_BtFwOpCodeProcess(Adapter, btOpcode, btOpcodeVer, &h2cParaBuf[0], h2cParaLen);
1094 		/* ckeck bt return status. */
1095 		if (BT_STATUS_BT_OP_SUCCESS != retStatus) {
1096 			pBtRsp->status = ((btOpcode << 8) | retStatus);
1097 			RTW_INFO("[MPT], Error!! status code=0x%x\n", pBtRsp->status);
1098 			return paraLen;
1099 		}
1100 	} else if (BT_ENABLE_CFO_TRACKING == setType) {
1101 		btOpcode = BT_LO_OP_ENABLE_CFO_TRACKING;
1102 		h2cParaBuf[0] = calVal;
1103 		h2cParaLen = 1;
1104 		retStatus = mptbt_BtFwOpCodeProcess(Adapter, btOpcode, btOpcodeVer, &h2cParaBuf[0], h2cParaLen);
1105 		/* ckeck bt return status. */
1106 		if (BT_STATUS_BT_OP_SUCCESS != retStatus) {
1107 			pBtRsp->status = ((btOpcode << 8) | retStatus);
1108 			RTW_INFO("[MPT], Error!! status code=0x%x\n", pBtRsp->status);
1109 			return paraLen;
1110 		}
1111 	}
1112 
1113 	pBtRsp->status = BT_STATUS_SUCCESS;
1114 	return paraLen;
1115 }
1116 
1117 
1118 
1119 u16
mptbt_BtSetTxRxPars(PADAPTER Adapter,PBT_REQ_CMD pBtReq,PBT_RSP_CMD pBtRsp)1120 mptbt_BtSetTxRxPars(
1121 		PADAPTER		Adapter,
1122 		PBT_REQ_CMD	pBtReq,
1123 		PBT_RSP_CMD	pBtRsp
1124 )
1125 {
1126 	u8				h2cParaBuf[6] = {0};
1127 	u8				h2cParaLen = 0;
1128 	u16				paraLen = 0;
1129 	u8				retStatus = BT_STATUS_BT_OP_SUCCESS;
1130 	u8				btOpcode;
1131 	u8				btOpcodeVer = 0;
1132 	PBT_TXRX_PARAMETERS pTxRxPars = (PBT_TXRX_PARAMETERS)&pBtReq->pParamStart[0];
1133 	u16				lenTxRx = sizeof(BT_TXRX_PARAMETERS);
1134 	u8				i;
1135 	u8				bdAddr[6] = {0};
1136 
1137 	/*  */
1138 	/* check upper layer parameters */
1139 	/*  */
1140 
1141 	/* 1. check upper layer opcode version */
1142 	if (pBtReq->opCodeVer != 1) {
1143 		RTW_INFO("[MPT], Error!! Upper OP code version not match!!!\n");
1144 		pBtRsp->status = BT_STATUS_OPCODE_U_VERSION_MISMATCH;
1145 		return paraLen;
1146 	}
1147 	/* 2. check upper layer parameter length */
1148 	if (pBtReq->paraLength == sizeof(BT_TXRX_PARAMETERS)) {
1149 		RTW_INFO("[MPT], pTxRxPars->txrxChannel=0x%x\n", pTxRxPars->txrxChannel);
1150 		RTW_INFO("[MPT], pTxRxPars->txrxTxPktCnt=0x%8x\n", pTxRxPars->txrxTxPktCnt);
1151 		RTW_INFO("[MPT], pTxRxPars->txrxTxPktInterval=0x%x\n", pTxRxPars->txrxTxPktInterval);
1152 		RTW_INFO("[MPT], pTxRxPars->txrxPayloadType=0x%x\n", pTxRxPars->txrxPayloadType);
1153 		RTW_INFO("[MPT], pTxRxPars->txrxPktType=0x%x\n", pTxRxPars->txrxPktType);
1154 		RTW_INFO("[MPT], pTxRxPars->txrxPayloadLen=0x%x\n", pTxRxPars->txrxPayloadLen);
1155 		RTW_INFO("[MPT], pTxRxPars->txrxPktHeader=0x%x\n", pTxRxPars->txrxPktHeader);
1156 		RTW_INFO("[MPT], pTxRxPars->txrxWhitenCoeff=0x%x\n", pTxRxPars->txrxWhitenCoeff);
1157 		bdAddr[0] = pTxRxPars->txrxBdaddr[5];
1158 		bdAddr[1] = pTxRxPars->txrxBdaddr[4];
1159 		bdAddr[2] = pTxRxPars->txrxBdaddr[3];
1160 		bdAddr[3] = pTxRxPars->txrxBdaddr[2];
1161 		bdAddr[4] = pTxRxPars->txrxBdaddr[1];
1162 		bdAddr[5] = pTxRxPars->txrxBdaddr[0];
1163 		RTW_INFO("[MPT], pTxRxPars->txrxBdaddr: %s", &bdAddr[0]);
1164 		RTW_INFO("[MPT], pTxRxPars->txrxTxGainIndex=0x%x\n", pTxRxPars->txrxTxGainIndex);
1165 	} else {
1166 		RTW_INFO("[MPT], Error!! pBtReq->paraLength=%d, correct Len=%d\n", pBtReq->paraLength, lenTxRx);
1167 		pBtRsp->status = BT_STATUS_PARAMETER_FORMAT_ERROR_U;
1168 		return paraLen;
1169 	}
1170 
1171 	/*  */
1172 	/* execute lower layer opcodes */
1173 	/*  */
1174 
1175 	/* fill h2c parameters */
1176 	btOpcode = BT_LO_OP_SET_PKT_HEADER;
1177 	if (pTxRxPars->txrxPktHeader > 0x3ffff) {
1178 		RTW_INFO("[MPT], Error!! pTxRxPars->txrxPktHeader=0x%x is out of range, (should be between 0x0~0x3ffff)\n", pTxRxPars->txrxPktHeader);
1179 		pBtRsp->status = (btOpcode << 8) | BT_STATUS_PARAMETER_OUT_OF_RANGE_U;
1180 		return paraLen;
1181 	} else {
1182 		h2cParaBuf[0] = (u8)(pTxRxPars->txrxPktHeader & 0xff);
1183 		h2cParaBuf[1] = (u8)((pTxRxPars->txrxPktHeader & 0xff00) >> 8);
1184 		h2cParaBuf[2] = (u8)((pTxRxPars->txrxPktHeader & 0xff0000) >> 16);
1185 		h2cParaLen = 3;
1186 		retStatus = mptbt_BtFwOpCodeProcess(Adapter, btOpcode, btOpcodeVer, &h2cParaBuf[0], h2cParaLen);
1187 	}
1188 
1189 	/* ckeck bt return status. */
1190 	if (BT_STATUS_BT_OP_SUCCESS != retStatus) {
1191 		pBtRsp->status = ((btOpcode << 8) | retStatus);
1192 		RTW_INFO("[MPT], Error!! status code=0x%x\n", pBtRsp->status);
1193 		return paraLen;
1194 	}
1195 
1196 	/* fill h2c parameters */
1197 	btOpcode = BT_LO_OP_SET_PKT_TYPE_LEN;
1198 	{
1199 		u16	payloadLenLimit = 0;
1200 		switch (pTxRxPars->txrxPktType) {
1201 		case MP_BT_PKT_DH1:
1202 			payloadLenLimit = 27 * 8;
1203 			break;
1204 		case MP_BT_PKT_DH3:
1205 			payloadLenLimit = 183 * 8;
1206 			break;
1207 		case MP_BT_PKT_DH5:
1208 			payloadLenLimit = 339 * 8;
1209 			break;
1210 		case MP_BT_PKT_2DH1:
1211 			payloadLenLimit = 54 * 8;
1212 			break;
1213 		case MP_BT_PKT_2DH3:
1214 			payloadLenLimit = 367 * 8;
1215 			break;
1216 		case MP_BT_PKT_2DH5:
1217 			payloadLenLimit = 679 * 8;
1218 			break;
1219 		case MP_BT_PKT_3DH1:
1220 			payloadLenLimit = 83 * 8;
1221 			break;
1222 		case MP_BT_PKT_3DH3:
1223 			payloadLenLimit = 552 * 8;
1224 			break;
1225 		case MP_BT_PKT_3DH5:
1226 			payloadLenLimit = 1021 * 8;
1227 			break;
1228 		case MP_BT_PKT_LE:
1229 			payloadLenLimit = 39 * 8;
1230 			break;
1231 		default: {
1232 			RTW_INFO("[MPT], Error!! Unknown pTxRxPars->txrxPktType=0x%x\n", pTxRxPars->txrxPktType);
1233 			pBtRsp->status = (btOpcode << 8) | BT_STATUS_PARAMETER_OUT_OF_RANGE_U;
1234 			return paraLen;
1235 		}
1236 		break;
1237 		}
1238 
1239 		if (pTxRxPars->txrxPayloadLen > payloadLenLimit) {
1240 			RTW_INFO("[MPT], Error!! pTxRxPars->txrxPayloadLen=0x%x, (should smaller than %d)\n",
1241 				 pTxRxPars->txrxPayloadLen, payloadLenLimit);
1242 			pBtRsp->status = (btOpcode << 8) | BT_STATUS_PARAMETER_OUT_OF_RANGE_U;
1243 			return paraLen;
1244 		}
1245 
1246 		h2cParaBuf[0] = pTxRxPars->txrxPktType;
1247 		h2cParaBuf[1] = (u8)((pTxRxPars->txrxPayloadLen & 0xff));
1248 		h2cParaBuf[2] = (u8)((pTxRxPars->txrxPayloadLen & 0xff00) >> 8);
1249 		h2cParaLen = 3;
1250 		retStatus = mptbt_BtFwOpCodeProcess(Adapter, btOpcode, btOpcodeVer, &h2cParaBuf[0], h2cParaLen);
1251 	}
1252 
1253 	/* ckeck bt return status. */
1254 	if (BT_STATUS_BT_OP_SUCCESS != retStatus) {
1255 		pBtRsp->status = ((btOpcode << 8) | retStatus);
1256 		RTW_INFO("[MPT], Error!! status code=0x%x\n", pBtRsp->status);
1257 		return paraLen;
1258 	}
1259 
1260 	/* fill h2c parameters */
1261 	btOpcode = BT_LO_OP_SET_PKT_CNT_L_PL_TYPE;
1262 	if (pTxRxPars->txrxPayloadType > MP_BT_PAYLOAD_MAX) {
1263 		RTW_INFO("[MPT], Error!! pTxRxPars->txrxPayloadType=0x%x, (should be between 0~4)\n", pTxRxPars->txrxPayloadType);
1264 		pBtRsp->status = (btOpcode << 8) | BT_STATUS_PARAMETER_OUT_OF_RANGE_U;
1265 		return paraLen;
1266 	} else {
1267 		h2cParaBuf[0] = (u8)((pTxRxPars->txrxTxPktCnt & 0xff));
1268 		h2cParaBuf[1] = (u8)((pTxRxPars->txrxTxPktCnt & 0xff00) >> 8);
1269 		h2cParaBuf[2] = pTxRxPars->txrxPayloadType;
1270 		h2cParaLen = 3;
1271 		retStatus = mptbt_BtFwOpCodeProcess(Adapter, btOpcode, btOpcodeVer, &h2cParaBuf[0], h2cParaLen);
1272 	}
1273 
1274 	/* ckeck bt return status. */
1275 	if (BT_STATUS_BT_OP_SUCCESS != retStatus) {
1276 		pBtRsp->status = ((btOpcode << 8) | retStatus);
1277 		RTW_INFO("[MPT], Error!! status code=0x%x\n", pBtRsp->status);
1278 		return paraLen;
1279 	}
1280 
1281 	/* fill h2c parameters */
1282 	btOpcode = BT_LO_OP_SET_PKT_CNT_H_PKT_INTV;
1283 	if (pTxRxPars->txrxTxPktInterval > 15) {
1284 		RTW_INFO("[MPT], Error!! pTxRxPars->txrxTxPktInterval=0x%x, (should be between 0~15)\n", pTxRxPars->txrxTxPktInterval);
1285 		pBtRsp->status = (btOpcode << 8) | BT_STATUS_PARAMETER_OUT_OF_RANGE_U;
1286 		return paraLen;
1287 	} else {
1288 		h2cParaBuf[0] = (u8)((pTxRxPars->txrxTxPktCnt & 0xff0000) >> 16);
1289 		h2cParaBuf[1] = (u8)((pTxRxPars->txrxTxPktCnt & 0xff000000) >> 24);
1290 		h2cParaBuf[2] = pTxRxPars->txrxTxPktInterval;
1291 		h2cParaLen = 3;
1292 		retStatus = mptbt_BtFwOpCodeProcess(Adapter, btOpcode, btOpcodeVer, &h2cParaBuf[0], h2cParaLen);
1293 	}
1294 
1295 	/* ckeck bt return status. */
1296 	if (BT_STATUS_BT_OP_SUCCESS != retStatus) {
1297 		pBtRsp->status = ((btOpcode << 8) | retStatus);
1298 		RTW_INFO("[MPT], Error!! status code=0x%x\n", pBtRsp->status);
1299 		return paraLen;
1300 	}
1301 
1302 	/* fill h2c parameters */
1303 	btOpcode = BT_LO_OP_SET_WHITENCOEFF;
1304 	{
1305 		h2cParaBuf[0] = pTxRxPars->txrxWhitenCoeff;
1306 		h2cParaLen = 1;
1307 		retStatus = mptbt_BtFwOpCodeProcess(Adapter, btOpcode, btOpcodeVer, &h2cParaBuf[0], h2cParaLen);
1308 	}
1309 
1310 	/* ckeck bt return status. */
1311 	if (BT_STATUS_BT_OP_SUCCESS != retStatus) {
1312 		pBtRsp->status = ((btOpcode << 8) | retStatus);
1313 		RTW_INFO("[MPT], Error!! status code=0x%x\n", pBtRsp->status);
1314 		return paraLen;
1315 	}
1316 
1317 
1318 	/* fill h2c parameters */
1319 	btOpcode = BT_LO_OP_SET_CHNL_TX_GAIN;
1320 	if ((pTxRxPars->txrxChannel > 78) ||
1321 	    (pTxRxPars->txrxTxGainIndex > 7)) {
1322 		RTW_INFO("[MPT], Error!! pTxRxPars->txrxChannel=0x%x, (should be between 0~78)\n", pTxRxPars->txrxChannel);
1323 		RTW_INFO("[MPT], Error!! pTxRxPars->txrxTxGainIndex=0x%x, (should be between 0~7)\n", pTxRxPars->txrxTxGainIndex);
1324 		pBtRsp->status = (btOpcode << 8) | BT_STATUS_PARAMETER_OUT_OF_RANGE_U;
1325 		return paraLen;
1326 	} else {
1327 		h2cParaBuf[0] = pTxRxPars->txrxChannel;
1328 		h2cParaBuf[1] = pTxRxPars->txrxTxGainIndex;
1329 		h2cParaLen = 2;
1330 		retStatus = mptbt_BtFwOpCodeProcess(Adapter, btOpcode, btOpcodeVer, &h2cParaBuf[0], h2cParaLen);
1331 	}
1332 
1333 	/* ckeck bt return status. */
1334 	if (BT_STATUS_BT_OP_SUCCESS != retStatus) {
1335 		pBtRsp->status = ((btOpcode << 8) | retStatus);
1336 		RTW_INFO("[MPT], Error!! status code=0x%x\n", pBtRsp->status);
1337 		return paraLen;
1338 	}
1339 
1340 	/* fill h2c parameters */
1341 	btOpcode = BT_LO_OP_SET_BD_ADDR_L;
1342 	if ((pTxRxPars->txrxBdaddr[0] == 0) &&
1343 	    (pTxRxPars->txrxBdaddr[1] == 0) &&
1344 	    (pTxRxPars->txrxBdaddr[2] == 0) &&
1345 	    (pTxRxPars->txrxBdaddr[3] == 0) &&
1346 	    (pTxRxPars->txrxBdaddr[4] == 0) &&
1347 	    (pTxRxPars->txrxBdaddr[5] == 0)) {
1348 		RTW_INFO("[MPT], Error!! pTxRxPars->txrxBdaddr=all zero\n");
1349 		pBtRsp->status = (btOpcode << 8) | BT_STATUS_PARAMETER_OUT_OF_RANGE_U;
1350 		return paraLen;
1351 	}
1352 	if ((pTxRxPars->txrxBdaddr[0] == 0xff) &&
1353 	    (pTxRxPars->txrxBdaddr[1] == 0xff) &&
1354 	    (pTxRxPars->txrxBdaddr[2] == 0xff) &&
1355 	    (pTxRxPars->txrxBdaddr[3] == 0xff) &&
1356 	    (pTxRxPars->txrxBdaddr[4] == 0xff) &&
1357 	    (pTxRxPars->txrxBdaddr[5] == 0xff)) {
1358 		RTW_INFO("[MPT], Error!! pTxRxPars->txrxBdaddr=all 0xf\n");
1359 		pBtRsp->status = (btOpcode << 8) | BT_STATUS_PARAMETER_OUT_OF_RANGE_U;
1360 		return paraLen;
1361 	}
1362 
1363 	{
1364 		h2cParaBuf[0] = pTxRxPars->txrxBdaddr[0];
1365 		h2cParaBuf[1] = pTxRxPars->txrxBdaddr[1];
1366 		h2cParaBuf[2] = pTxRxPars->txrxBdaddr[2];
1367 		h2cParaLen = 3;
1368 		retStatus = mptbt_BtFwOpCodeProcess(Adapter, btOpcode, btOpcodeVer, &h2cParaBuf[0], h2cParaLen);
1369 	}
1370 	/* ckeck bt return status. */
1371 	if (BT_STATUS_BT_OP_SUCCESS != retStatus) {
1372 		pBtRsp->status = ((btOpcode << 8) | retStatus);
1373 		RTW_INFO("[MPT], Error!! status code=0x%x\n", pBtRsp->status);
1374 		return paraLen;
1375 	}
1376 
1377 	btOpcode = BT_LO_OP_SET_BD_ADDR_H;
1378 	{
1379 		h2cParaBuf[0] = pTxRxPars->txrxBdaddr[3];
1380 		h2cParaBuf[1] = pTxRxPars->txrxBdaddr[4];
1381 		h2cParaBuf[2] = pTxRxPars->txrxBdaddr[5];
1382 		h2cParaLen = 3;
1383 		retStatus = mptbt_BtFwOpCodeProcess(Adapter, btOpcode, btOpcodeVer, &h2cParaBuf[0], h2cParaLen);
1384 	}
1385 	/* ckeck bt return status. */
1386 	if (BT_STATUS_BT_OP_SUCCESS != retStatus) {
1387 		pBtRsp->status = ((btOpcode << 8) | retStatus);
1388 		RTW_INFO("[MPT], Error!! status code=0x%x\n", pBtRsp->status);
1389 		return paraLen;
1390 	}
1391 
1392 	pBtRsp->status = BT_STATUS_SUCCESS;
1393 	return paraLen;
1394 }
1395 
1396 
1397 
1398 u16
mptbt_BtTestCtrl(PADAPTER Adapter,PBT_REQ_CMD pBtReq,PBT_RSP_CMD pBtRsp)1399 mptbt_BtTestCtrl(
1400 		PADAPTER		Adapter,
1401 		PBT_REQ_CMD	pBtReq,
1402 		PBT_RSP_CMD	pBtRsp
1403 )
1404 {
1405 	u8				h2cParaBuf[6] = {0};
1406 	u8				h2cParaLen = 0;
1407 	u16				paraLen = 0;
1408 	u8				retStatus = BT_STATUS_BT_OP_SUCCESS;
1409 	u8				btOpcode;
1410 	u8				btOpcodeVer = 0;
1411 	u8				testCtrl = 0;
1412 
1413 	/*  */
1414 	/* check upper layer parameters */
1415 	/*  */
1416 
1417 	/* 1. check upper layer opcode version */
1418 	if (pBtReq->opCodeVer != 1) {
1419 		RTW_INFO("[MPT], Error!! Upper OP code version not match!!!\n");
1420 		pBtRsp->status = BT_STATUS_OPCODE_U_VERSION_MISMATCH;
1421 		return paraLen;
1422 	}
1423 	/* 2. check upper layer parameter length */
1424 	if (1 == pBtReq->paraLength) {
1425 		testCtrl = pBtReq->pParamStart[0];
1426 		RTW_INFO("[MPT], testCtrl=%d\n", testCtrl);
1427 	} else {
1428 		RTW_INFO("[MPT], Error!! wrong parameter length=%d (should be 1)\n", pBtReq->paraLength);
1429 		pBtRsp->status = BT_STATUS_PARAMETER_FORMAT_ERROR_U;
1430 		return paraLen;
1431 	}
1432 
1433 	/*  */
1434 	/* execute lower layer opcodes */
1435 	/*  */
1436 
1437 	/* 1. fill h2c parameters	 */
1438 	/* check bt mode */
1439 	btOpcode = BT_LO_OP_TEST_CTRL;
1440 	if (testCtrl >= MP_BT_TEST_MAX) {
1441 		RTW_INFO("[MPT], Error!! testCtrl=0x%x, (should be between smaller or equal to 0x%x)\n",
1442 			 testCtrl, MP_BT_TEST_MAX - 1);
1443 		pBtRsp->status = BT_STATUS_PARAMETER_OUT_OF_RANGE_U;
1444 		return paraLen;
1445 	} else {
1446 		h2cParaBuf[0] = testCtrl;
1447 		h2cParaLen = 1;
1448 		retStatus = mptbt_BtFwOpCodeProcess(Adapter, btOpcode, btOpcodeVer, &h2cParaBuf[0], h2cParaLen);
1449 	}
1450 
1451 	/* 3. construct respond status code and data. */
1452 	if (BT_STATUS_BT_OP_SUCCESS != retStatus) {
1453 		pBtRsp->status = ((btOpcode << 8) | retStatus);
1454 		RTW_INFO("[MPT], Error!! status code=0x%x\n", pBtRsp->status);
1455 		return paraLen;
1456 	}
1457 
1458 	pBtRsp->status = BT_STATUS_SUCCESS;
1459 	return paraLen;
1460 }
1461 
1462 
1463 u16
mptbt_TestBT(PADAPTER Adapter,PBT_REQ_CMD pBtReq,PBT_RSP_CMD pBtRsp)1464 mptbt_TestBT(
1465 		PADAPTER		Adapter,
1466 		PBT_REQ_CMD	pBtReq,
1467 		PBT_RSP_CMD	pBtRsp
1468 )
1469 {
1470 
1471 	u8				h2cParaBuf[6] = {0};
1472 	u8				h2cParaLen = 0;
1473 	u16				paraLen = 0;
1474 	u8				retStatus = BT_STATUS_BT_OP_SUCCESS;
1475 	u8				btOpcode;
1476 	u8				btOpcodeVer = 0;
1477 	u8				testCtrl = 0;
1478 
1479 	/* 1. fill h2c parameters	 */
1480 	btOpcode =  0x11;
1481 	h2cParaBuf[0] = 0x11;
1482 	h2cParaBuf[1] = 0x0;
1483 	h2cParaBuf[2] = 0x0;
1484 	h2cParaBuf[3] = 0x0;
1485 	h2cParaBuf[4] = 0x0;
1486 	h2cParaLen = 1;
1487 	/*	retStatus = mptbt_BtFwOpCodeProcess(Adapter, btOpcode, btOpcodeVer, &h2cParaBuf[0], h2cParaLen); */
1488 	retStatus = mptbt_BtFwOpCodeProcess(Adapter, btOpcode, btOpcodeVer, h2cParaBuf, h2cParaLen);
1489 
1490 
1491 	/* 3. construct respond status code and data. */
1492 	if (BT_STATUS_BT_OP_SUCCESS != retStatus) {
1493 		pBtRsp->status = ((btOpcode << 8) | retStatus);
1494 		RTW_INFO("[MPT], Error!! status code=0x%x\n", pBtRsp->status);
1495 		return paraLen;
1496 	}
1497 
1498 	pBtRsp->status = BT_STATUS_SUCCESS;
1499 	return paraLen;
1500 }
1501 
1502 void
mptbt_BtControlProcess(PADAPTER Adapter,void * pInBuf)1503 mptbt_BtControlProcess(
1504 	PADAPTER	Adapter,
1505 	void			*pInBuf
1506 )
1507 {
1508 	u8			H2C_Parameter[6] = {0};
1509 	PBT_H2C		pH2c = (PBT_H2C)&H2C_Parameter[0];
1510 	PMPT_CONTEXT	pMptCtx = &(Adapter->mppriv.mpt_ctx);
1511 	PBT_REQ_CMD	pBtReq = (PBT_REQ_CMD)pInBuf;
1512 	PBT_RSP_CMD	pBtRsp;
1513 	u8			i;
1514 
1515 
1516 	RTW_INFO("[MPT], mptbt_BtControlProcess()=========>\n");
1517 
1518 	RTW_INFO("[MPT], input opCodeVer=%d\n", pBtReq->opCodeVer);
1519 	RTW_INFO("[MPT], input OpCode=%d\n", pBtReq->OpCode);
1520 	RTW_INFO("[MPT], paraLength=%d\n", pBtReq->paraLength);
1521 	if (pBtReq->paraLength) {
1522 		/* RTW_INFO("[MPT], parameters(hex):0x%x %d\n",&pBtReq->pParamStart[0], pBtReq->paraLength); */
1523 	}
1524 
1525 	_rtw_memset((void *)pMptCtx->mptOutBuf, 0, 100);
1526 	pMptCtx->mptOutLen = 4; /* length of (BT_RSP_CMD.status+BT_RSP_CMD.paraLength) */
1527 
1528 	pBtRsp = (PBT_RSP_CMD)pMptCtx->mptOutBuf;
1529 	pBtRsp->status = BT_STATUS_SUCCESS;
1530 	pBtRsp->paraLength = 0x0;
1531 
1532 	/* The following we should maintain the User OP codes sent by upper layer */
1533 	switch (pBtReq->OpCode) {
1534 	case BT_UP_OP_BT_READY:
1535 		RTW_INFO("[MPT], OPcode : [BT_READY]\n");
1536 		pBtRsp->paraLength = mptbt_BtReady(Adapter, pBtReq, pBtRsp);
1537 		break;
1538 	case BT_UP_OP_BT_SET_MODE:
1539 		RTW_INFO("[MPT], OPcode : [BT_SET_MODE]\n");
1540 		pBtRsp->paraLength = mptbt_BtSetMode(Adapter, pBtReq, pBtRsp);
1541 		break;
1542 	case BT_UP_OP_BT_SET_TX_RX_PARAMETER:
1543 		RTW_INFO("[MPT], OPcode : [BT_SET_TXRX_PARAMETER]\n");
1544 		pBtRsp->paraLength = mptbt_BtSetTxRxPars(Adapter, pBtReq, pBtRsp);
1545 		break;
1546 	case BT_UP_OP_BT_SET_GENERAL:
1547 		RTW_INFO("[MPT], OPcode : [BT_SET_GENERAL]\n");
1548 		pBtRsp->paraLength = mptbt_BtSetGeneral(Adapter, pBtReq, pBtRsp);
1549 		break;
1550 	case BT_UP_OP_BT_GET_GENERAL:
1551 		RTW_INFO("[MPT], OPcode : [BT_GET_GENERAL]\n");
1552 		pBtRsp->paraLength = mptbt_BtGetGeneral(Adapter, pBtReq, pBtRsp);
1553 		break;
1554 	case BT_UP_OP_BT_TEST_CTRL:
1555 		RTW_INFO("[MPT], OPcode : [BT_TEST_CTRL]\n");
1556 		pBtRsp->paraLength = mptbt_BtTestCtrl(Adapter, pBtReq, pBtRsp);
1557 		break;
1558 	case BT_UP_OP_TEST_BT:
1559 		RTW_INFO("[MPT], OPcode : [TEST_BT]\n");
1560 		pBtRsp->paraLength = mptbt_TestBT(Adapter, pBtReq, pBtRsp);
1561 		break;
1562 	default:
1563 		RTW_INFO("[MPT], Error!! OPcode : UNDEFINED!!!!\n");
1564 		pBtRsp->status = BT_STATUS_UNKNOWN_OPCODE_U;
1565 		pBtRsp->paraLength = 0x0;
1566 		break;
1567 	}
1568 
1569 	pMptCtx->mptOutLen += pBtRsp->paraLength;
1570 
1571 	RTW_INFO("[MPT], pMptCtx->mptOutLen=%d, pBtRsp->paraLength=%d\n", pMptCtx->mptOutLen, pBtRsp->paraLength);
1572 	RTW_INFO("[MPT], mptbt_BtControlProcess()<=========\n");
1573 }
1574 
1575 #endif
1576