1 /*
2  *************************************************************************
3  * Ralink Tech Inc.
4  * 5F., No.36, Taiyuan St., Jhubei City,
5  * Hsinchu County 302,
6  * Taiwan, R.O.C.
7  *
8  * (c) Copyright 2002-2007, Ralink Technology, Inc.
9  *
10  * This program is free software; you can redistribute it and/or modify  *
11  * it under the terms of the GNU General Public License as published by  *
12  * the Free Software Foundation; either version 2 of the License, or     *
13  * (at your option) any later version.                                   *
14  *                                                                       *
15  * This program is distributed in the hope that it will be useful,       *
16  * but WITHOUT ANY WARRANTY; without even the implied warranty of        *
17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
18  * GNU General Public License for more details.                          *
19  *                                                                       *
20  * You should have received a copy of the GNU General Public License     *
21  * along with this program; if not, write to the                         *
22  * Free Software Foundation, Inc.,                                       *
23  * 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
24  *                                                                       *
25  *************************************************************************
26 
27 	Module Name:
28 	rtmp_phy.h
29 
30 	Abstract:
31 	Ralink Wireless Chip PHY(BBP/RF) related definition & structures
32 
33 	Revision History:
34 	Who			When		  What
35 	--------	----------	  ----------------------------------------------
36 */
37 
38 #ifndef __RTMP_PHY_H__
39 #define __RTMP_PHY_H__
40 
41 /*
42 	RF sections
43 */
44 #define RF_R00			0
45 #define RF_R01			1
46 #define RF_R02			2
47 #define RF_R03			3
48 #define RF_R04			4
49 #define RF_R05			5
50 #define RF_R06			6
51 #define RF_R07			7
52 #define RF_R08			8
53 #define RF_R09			9
54 #define RF_R10			10
55 #define RF_R11			11
56 #define RF_R12			12
57 #define RF_R13			13
58 #define RF_R14			14
59 #define RF_R15			15
60 #define RF_R16			16
61 #define RF_R17			17
62 #define RF_R18			18
63 #define RF_R19			19
64 #define RF_R20			20
65 #define RF_R21			21
66 #define RF_R22			22
67 #define RF_R23			23
68 #define RF_R24			24
69 #define RF_R25			25
70 #define RF_R26			26
71 #define RF_R27			27
72 #define RF_R28			28
73 #define RF_R29			29
74 #define RF_R30			30
75 #define RF_R31			31
76 
77 /* value domain of pAd->RfIcType */
78 #define RFIC_2820                   1	/* 2.4G 2T3R */
79 #define RFIC_2850                   2	/* 2.4G/5G 2T3R */
80 #define RFIC_2720                   3	/* 2.4G 1T2R */
81 #define RFIC_2750                   4	/* 2.4G/5G 1T2R */
82 #define RFIC_3020                   5	/* 2.4G 1T1R */
83 #define RFIC_2020                   6	/* 2.4G B/G */
84 #define RFIC_3021                   7	/* 2.4G 1T2R */
85 #define RFIC_3022                   8	/* 2.4G 2T2R */
86 #define RFIC_3052                   9	/* 2.4G/5G 2T2R */
87 
88 /*
89 	BBP sections
90 */
91 #define BBP_R0			0	/* version */
92 #define BBP_R1			1	/* TSSI */
93 #define BBP_R2			2	/* TX configure */
94 #define BBP_R3			3
95 #define BBP_R4			4
96 #define BBP_R5			5
97 #define BBP_R6			6
98 #define BBP_R14			14	/* RX configure */
99 #define BBP_R16			16
100 #define BBP_R17			17	/* RX sensibility */
101 #define BBP_R18			18
102 #define BBP_R21			21
103 #define BBP_R22			22
104 #define BBP_R24			24
105 #define BBP_R25			25
106 #define BBP_R26			26
107 #define BBP_R27			27
108 #define BBP_R31			31
109 #define BBP_R49			49	/*TSSI */
110 #define BBP_R50			50
111 #define BBP_R51			51
112 #define BBP_R52			52
113 #define BBP_R55			55
114 #define BBP_R62			62	/* Rx SQ0 Threshold HIGH */
115 #define BBP_R63			63
116 #define BBP_R64			64
117 #define BBP_R65			65
118 #define BBP_R66			66
119 #define BBP_R67			67
120 #define BBP_R68			68
121 #define BBP_R69			69
122 #define BBP_R70			70	/* Rx AGC SQ CCK Xcorr threshold */
123 #define BBP_R73			73
124 #define BBP_R75			75
125 #define BBP_R77			77
126 #define BBP_R78			78
127 #define BBP_R79			79
128 #define BBP_R80			80
129 #define BBP_R81			81
130 #define BBP_R82			82
131 #define BBP_R83			83
132 #define BBP_R84			84
133 #define BBP_R86			86
134 #define BBP_R91			91
135 #define BBP_R92			92
136 #define BBP_R94			94	/* Tx Gain Control */
137 #define BBP_R103		103
138 #define BBP_R105		105
139 #define BBP_R106		106
140 #define BBP_R113		113
141 #define BBP_R114		114
142 #define BBP_R115		115
143 #define BBP_R116		116
144 #define BBP_R117		117
145 #define BBP_R118		118
146 #define BBP_R119		119
147 #define BBP_R120		120
148 #define BBP_R121		121
149 #define BBP_R122		122
150 #define BBP_R123		123
151 #ifdef RT30xx
152 #define BBP_R138		138	/* add by johnli, RF power sequence setup, ADC dynamic on/off control */
153 #endif /* RT30xx // */
154 
155 #define BBPR94_DEFAULT	0x06	/* Add 1 value will gain 1db */
156 
157 /* */
158 /* BBP & RF are using indirect access. Before write any value into it. */
159 /* We have to make sure there is no outstanding command pending via checking busy bit. */
160 /* */
161 #define MAX_BUSY_COUNT  100	/* Number of retry before failing access BBP & RF indirect register */
162 
163 /*#define PHY_TR_SWITCH_TIME          5  // usec */
164 
165 /*#define BBP_R17_LOW_SENSIBILITY     0x50 */
166 /*#define BBP_R17_MID_SENSIBILITY     0x41 */
167 /*#define BBP_R17_DYNAMIC_UP_BOUND    0x40 */
168 
169 #define RSSI_FOR_VERY_LOW_SENSIBILITY   -35
170 #define RSSI_FOR_LOW_SENSIBILITY		-58
171 #define RSSI_FOR_MID_LOW_SENSIBILITY	-80
172 #define RSSI_FOR_MID_SENSIBILITY		-90
173 
174 /*****************************************************************************
175 	RF register Read/Write marco definition
176  *****************************************************************************/
177 #ifdef RTMP_MAC_PCI
178 #define RTMP_RF_IO_WRITE32(_A, _V)                  \
179 {											\
180 	if ((_A)->bPCIclkOff == FALSE) {				\
181 		PHY_CSR4_STRUC  _value;                          \
182 		unsigned long           _busyCnt = 0;                    \
183 											\
184 		do {                                            \
185 			RTMP_IO_READ32((_A), RF_CSR_CFG0, &_value.word);  \
186 			if (_value.field.Busy == IDLE)               \
187 				break;                                  \
188 			_busyCnt++;                                  \
189 		} while (_busyCnt < MAX_BUSY_COUNT);			\
190 		if (_busyCnt < MAX_BUSY_COUNT) {			\
191 			RTMP_IO_WRITE32((_A), RF_CSR_CFG0, (_V));          \
192 		}                                               \
193 	}								\
194 }
195 #endif /* RTMP_MAC_PCI // */
196 #ifdef RTMP_MAC_USB
197 #define RTMP_RF_IO_WRITE32(_A, _V)                 RTUSBWriteRFRegister(_A, _V)
198 #endif /* RTMP_MAC_USB // */
199 
200 #ifdef RT30xx
201 #define RTMP_RF_IO_READ8_BY_REG_ID(_A, _I, _pV)    RT30xxReadRFRegister(_A, _I, _pV)
202 #define RTMP_RF_IO_WRITE8_BY_REG_ID(_A, _I, _V)    RT30xxWriteRFRegister(_A, _I, _V)
203 #endif /* RT30xx // */
204 
205 /*****************************************************************************
206 	BBP register Read/Write marco definitions.
207 	we read/write the bbp value by register's ID.
208 	Generate PER to test BA
209  *****************************************************************************/
210 #ifdef RTMP_MAC_PCI
211 /*
212 	basic marco for BBP read operation.
213 	_pAd: the data structure pointer of struct rt_rtmp_adapter
214 	_bbpID : the bbp register ID
215 	_pV: data pointer used to save the value of queried bbp register.
216 	_bViaMCU: if we need access the bbp via the MCU.
217 */
218 #define RTMP_BBP_IO_READ8(_pAd, _bbpID, _pV, _bViaMCU)			\
219 	do {								\
220 		BBP_CSR_CFG_STRUC  BbpCsr;				\
221 		int   _busyCnt, _secCnt, _regID;			\
222 									\
223 		_regID = ((_bViaMCU) == TRUE ? H2M_BBP_AGENT : BBP_CSR_CFG); \
224 		for (_busyCnt = 0; _busyCnt < MAX_BUSY_COUNT; _busyCnt++) { \
225 			RTMP_IO_READ32(_pAd, _regID, &BbpCsr.word);	\
226 			if (BbpCsr.field.Busy == BUSY)                  \
227 				continue;                               \
228 			BbpCsr.word = 0;                                \
229 			BbpCsr.field.fRead = 1;                         \
230 			BbpCsr.field.BBP_RW_MODE = 1;                   \
231 			BbpCsr.field.Busy = 1;                          \
232 			BbpCsr.field.RegNum = _bbpID;                   \
233 			RTMP_IO_WRITE32(_pAd, _regID, BbpCsr.word);     \
234 			if ((_bViaMCU) == TRUE) {			\
235 			    AsicSendCommandToMcu(_pAd, 0x80, 0xff, 0x0, 0x0); \
236 			    RTMPusecDelay(1000);	\
237 			}						\
238 			for (_secCnt = 0; _secCnt < MAX_BUSY_COUNT; _secCnt++) { \
239 				RTMP_IO_READ32(_pAd, _regID, &BbpCsr.word); \
240 				if (BbpCsr.field.Busy == IDLE)		\
241 					break;				\
242 			}						\
243 			if ((BbpCsr.field.Busy == IDLE) &&		\
244 				(BbpCsr.field.RegNum == _bbpID)) {	\
245 				*(_pV) = (u8)BbpCsr.field.Value;	\
246 				break;					\
247 			}						\
248 		}							\
249 		if (BbpCsr.field.Busy == BUSY) {			\
250 			DBGPRINT_ERR("BBP(viaMCU=%d) read R%d fail\n", (_bViaMCU), _bbpID);	\
251 			*(_pV) = (_pAd)->BbpWriteLatch[_bbpID];               \
252 			if ((_bViaMCU) == TRUE) {			\
253 				RTMP_IO_READ32(_pAd, _regID, &BbpCsr.word);				\
254 				BbpCsr.field.Busy = 0;                          \
255 				RTMP_IO_WRITE32(_pAd, _regID, BbpCsr.word);				\
256 			}				\
257 		}													\
258 	} while (0)
259 
260 /*
261 	This marco used for the BBP read operation which didn't need via MCU.
262 */
263 #define BBP_IO_READ8_BY_REG_ID(_A, _I, _pV)			\
264 	RTMP_BBP_IO_READ8((_A), (_I), (_pV), FALSE)
265 
266 /*
267 	This marco used for the BBP read operation which need via MCU.
268 	But for some chipset which didn't have mcu (e.g., RBUS based chipset), we
269 	will use this function too and didn't access the bbp register via the MCU.
270 */
271 /* Read BBP register by register's ID. Generate PER to test BA */
272 #define RTMP_BBP_IO_READ8_BY_REG_ID(_A, _I, _pV)						\
273 {																		\
274 	BBP_CSR_CFG_STRUC	BbpCsr;											\
275 	int					i, k;			\
276 	BOOLEAN					brc;			\
277 	BbpCsr.field.Busy = IDLE;			\
278 	if ((IS_RT3090((_A)) || IS_RT3572((_A)) || IS_RT3390((_A)))  \
279 		&& ((_A)->StaCfg.PSControl.field.rt30xxPowerMode == 3)	\
280 		&& ((_A)->StaCfg.PSControl.field.EnableNewPS == TRUE)	\
281 		&& ((_A)->bPCIclkOff == FALSE)	\
282 		&& ((_A)->brt30xxBanMcuCmd == FALSE)) {			\
283 		for (i = 0; i < MAX_BUSY_COUNT; i++) {			\
284 			RTMP_IO_READ32(_A, H2M_BBP_AGENT, &BbpCsr.word); \
285 			if (BbpCsr.field.Busy == BUSY) {		\
286 				continue;				\
287 			}						\
288 			BbpCsr.word = 0;				\
289 			BbpCsr.field.fRead = 1;				\
290 			BbpCsr.field.BBP_RW_MODE = 1;			\
291 			BbpCsr.field.Busy = 1;				\
292 			BbpCsr.field.RegNum = _I;			\
293 			RTMP_IO_WRITE32(_A, H2M_BBP_AGENT, BbpCsr.word); \
294 			brc = AsicSendCommandToMcu(_A, 0x80, 0xff, 0x0, 0x0); \
295 			if (brc == TRUE) {				\
296 				for (k = 0; k < MAX_BUSY_COUNT; k++) {	\
297 					RTMP_IO_READ32(_A, H2M_BBP_AGENT, &BbpCsr.word); \
298 					if (BbpCsr.field.Busy == IDLE)	\
299 						break;			\
300 				}					\
301 				if ((BbpCsr.field.Busy == IDLE) &&	\
302 					(BbpCsr.field.RegNum == _I)) {	\
303 					*(_pV) = (u8)BbpCsr.field.Value; \
304 					break;				\
305 				}					\
306 			} else {					\
307 				BbpCsr.field.Busy = 0;											\
308 				RTMP_IO_WRITE32(_A, H2M_BBP_AGENT, BbpCsr.word);				\
309 			}																\
310 		}																	\
311 	}	\
312 	else if (!((IS_RT3090((_A)) || IS_RT3572((_A)) || IS_RT3390((_A))) && ((_A)->StaCfg.PSControl.field.rt30xxPowerMode == 3)	\
313 		&& ((_A)->StaCfg.PSControl.field.EnableNewPS == TRUE))	\
314 		&& ((_A)->bPCIclkOff == FALSE)) {			\
315 		for (i = 0; i < MAX_BUSY_COUNT; i++) {			\
316 			RTMP_IO_READ32(_A, H2M_BBP_AGENT, &BbpCsr.word); \
317 			if (BbpCsr.field.Busy == BUSY) {		\
318 				continue;				\
319 			}						\
320 			BbpCsr.word = 0;				\
321 			BbpCsr.field.fRead = 1;				\
322 			BbpCsr.field.BBP_RW_MODE = 1;			\
323 			BbpCsr.field.Busy = 1;				\
324 			BbpCsr.field.RegNum = _I;			\
325 			RTMP_IO_WRITE32(_A, H2M_BBP_AGENT, BbpCsr.word); \
326 			AsicSendCommandToMcu(_A, 0x80, 0xff, 0x0, 0x0);	\
327 			for (k = 0; k < MAX_BUSY_COUNT; k++) {		\
328 				RTMP_IO_READ32(_A, H2M_BBP_AGENT, &BbpCsr.word); \
329 				if (BbpCsr.field.Busy == IDLE)		\
330 					break;				\
331 			}						\
332 			if ((BbpCsr.field.Busy == IDLE) &&		\
333 				(BbpCsr.field.RegNum == _I)) {		\
334 				*(_pV) = (u8)BbpCsr.field.Value;	\
335 				break;					\
336 			}						\
337 		}							\
338 	} else {							\
339 		DBGPRINT_ERR(" , brt30xxBanMcuCmd = %d, Read BBP %d \n", (_A)->brt30xxBanMcuCmd, (_I));	\
340 		*(_pV) = (_A)->BbpWriteLatch[_I];			\
341 	}								\
342 	if ((BbpCsr.field.Busy == BUSY) || ((_A)->bPCIclkOff == TRUE)) { \
343 		DBGPRINT_ERR("BBP read R%d=0x%x fail\n", _I, BbpCsr.word); \
344 		*(_pV) = (_A)->BbpWriteLatch[_I];			\
345 	}								\
346 }
347 
348 /*
349 	basic marco for BBP write operation.
350 	_pAd: the data structure pointer of struct rt_rtmp_adapter
351 	_bbpID : the bbp register ID
352 	_pV: data used to save the value of queried bbp register.
353 	_bViaMCU: if we need access the bbp via the MCU.
354 */
355 #define RTMP_BBP_IO_WRITE8(_pAd, _bbpID, _pV, _bViaMCU)			\
356 	do {								\
357 		BBP_CSR_CFG_STRUC  BbpCsr;                             \
358 		int             _busyCnt, _regID;			\
359 									\
360 		_regID = ((_bViaMCU) == TRUE ? H2M_BBP_AGENT : BBP_CSR_CFG);	\
361 		for (_busyCnt = 0; _busyCnt < MAX_BUSY_COUNT; _busyCnt++) { \
362 			RTMP_IO_READ32((_pAd), BBP_CSR_CFG, &BbpCsr.word);     \
363 			if (BbpCsr.field.Busy == BUSY)			\
364 				continue;				\
365 			BbpCsr.word = 0;				\
366 			BbpCsr.field.fRead = 0;				\
367 			BbpCsr.field.BBP_RW_MODE = 1;			\
368 			BbpCsr.field.Busy = 1;				\
369 			BbpCsr.field.Value = _pV;			\
370 			BbpCsr.field.RegNum = _bbpID;			\
371 			RTMP_IO_WRITE32((_pAd), BBP_CSR_CFG, BbpCsr.word); \
372 			if ((_bViaMCU) == TRUE) {			\
373 				AsicSendCommandToMcu(_pAd, 0x80, 0xff, 0x0, 0x0); \
374 				if ((_pAd)->OpMode == OPMODE_AP)	\
375 					RTMPusecDelay(1000);		\
376 			}						\
377 			(_pAd)->BbpWriteLatch[_bbpID] = _pV;		\
378 			break;						\
379 		}							\
380 		if (_busyCnt == MAX_BUSY_COUNT) {			\
381 			DBGPRINT_ERR("BBP write R%d fail\n", _bbpID);	\
382 			if ((_bViaMCU) == TRUE) {			\
383 				RTMP_IO_READ32(_pAd, H2M_BBP_AGENT, &BbpCsr.word);	\
384 				BbpCsr.field.Busy = 0;			\
385 				RTMP_IO_WRITE32(_pAd, H2M_BBP_AGENT, BbpCsr.word);	\
386 			}						\
387 		}							\
388 	} while (0)
389 
390 /*
391 	This marco used for the BBP write operation which didn't need via MCU.
392 */
393 #define BBP_IO_WRITE8_BY_REG_ID(_A, _I, _pV)			\
394 	RTMP_BBP_IO_WRITE8((_A), (_I), (_pV), FALSE)
395 
396 /*
397 	This marco used for the BBP write operation which need via MCU.
398 	But for some chipset which didn't have mcu (e.g., RBUS based chipset), we
399 	will use this function too and didn't access the bbp register via the MCU.
400 */
401 /* Write BBP register by register's ID & value */
402 #define RTMP_BBP_IO_WRITE8_BY_REG_ID(_A, _I, _V)			\
403 {									\
404 	BBP_CSR_CFG_STRUC	BbpCsr;					\
405 	int					BusyCnt = 0;		\
406 	BOOLEAN					brc;			\
407 	if (_I < MAX_NUM_OF_BBP_LATCH) {				\
408 		if ((IS_RT3090((_A)) || IS_RT3572((_A)) || IS_RT3390((_A))) \
409 			&& ((_A)->StaCfg.PSControl.field.rt30xxPowerMode == 3)	\
410 			&& ((_A)->StaCfg.PSControl.field.EnableNewPS == TRUE)	\
411 			&& ((_A)->bPCIclkOff == FALSE)	\
412 			&& ((_A)->brt30xxBanMcuCmd == FALSE)) {		\
413 			if (_A->AccessBBPFailCount > 20) {		\
414 				AsicResetBBPAgent(_A);			\
415 				_A->AccessBBPFailCount = 0;		\
416 			}						\
417 			for (BusyCnt = 0; BusyCnt < MAX_BUSY_COUNT; BusyCnt++) { \
418 				RTMP_IO_READ32(_A, H2M_BBP_AGENT, &BbpCsr.word);				\
419 				if (BbpCsr.field.Busy == BUSY)									\
420 					continue;													\
421 				BbpCsr.word = 0;												\
422 				BbpCsr.field.fRead = 0;											\
423 				BbpCsr.field.BBP_RW_MODE = 1;									\
424 				BbpCsr.field.Busy = 1;											\
425 				BbpCsr.field.Value = _V;										\
426 				BbpCsr.field.RegNum = _I;										\
427 				RTMP_IO_WRITE32(_A, H2M_BBP_AGENT, BbpCsr.word);				\
428 				brc = AsicSendCommandToMcu(_A, 0x80, 0xff, 0x0, 0x0);					\
429 				if (brc == TRUE) {			\
430 					(_A)->BbpWriteLatch[_I] = _V;									\
431 				} else {				\
432 					BbpCsr.field.Busy = 0;											\
433 					RTMP_IO_WRITE32(_A, H2M_BBP_AGENT, BbpCsr.word);				\
434 				}																\
435 				break;															\
436 			}																	\
437 		}																	\
438 		else if (!((IS_RT3090((_A)) || IS_RT3572((_A)) || IS_RT3390((_A))) \
439 			&& ((_A)->StaCfg.PSControl.field.rt30xxPowerMode == 3)	\
440 			&& ((_A)->StaCfg.PSControl.field.EnableNewPS == TRUE))	\
441 			&& ((_A)->bPCIclkOff == FALSE)) { 		\
442 			if (_A->AccessBBPFailCount > 20) {		\
443 				AsicResetBBPAgent(_A);			\
444 				_A->AccessBBPFailCount = 0;		\
445 			}						\
446 			for (BusyCnt = 0; BusyCnt < MAX_BUSY_COUNT; BusyCnt++) { \
447 				RTMP_IO_READ32(_A, H2M_BBP_AGENT, &BbpCsr.word);				\
448 				if (BbpCsr.field.Busy == BUSY)									\
449 					continue;													\
450 				BbpCsr.word = 0;												\
451 				BbpCsr.field.fRead = 0;											\
452 				BbpCsr.field.BBP_RW_MODE = 1;									\
453 				BbpCsr.field.Busy = 1;											\
454 				BbpCsr.field.Value = _V;										\
455 				BbpCsr.field.RegNum = _I;										\
456 				RTMP_IO_WRITE32(_A, H2M_BBP_AGENT, BbpCsr.word);				\
457 				AsicSendCommandToMcu(_A, 0x80, 0xff, 0x0, 0x0);					\
458 				(_A)->BbpWriteLatch[_I] = _V;									\
459 				break;															\
460 			}																	\
461 		} else {						\
462 			DBGPRINT_ERR("  brt30xxBanMcuCmd = %d. Write BBP %d \n",  (_A)->brt30xxBanMcuCmd, (_I));	\
463 		}																	\
464 		if ((BusyCnt == MAX_BUSY_COUNT) || ((_A)->bPCIclkOff == TRUE)) { \
465 			if (BusyCnt == MAX_BUSY_COUNT)				\
466 				(_A)->AccessBBPFailCount++;					\
467 			DBGPRINT_ERR("BBP write R%d=0x%x fail. BusyCnt= %d.bPCIclkOff = %d. \n", _I, BbpCsr.word, BusyCnt, (_A)->bPCIclkOff);	\
468 		}																	\
469 	} else {							\
470 		DBGPRINT_ERR("****** BBP_Write_Latch Buffer exceeds max boundary ****** \n");	\
471 	}																		\
472 }
473 #endif /* RTMP_MAC_PCI // */
474 
475 #ifdef RTMP_MAC_USB
476 #define RTMP_BBP_IO_READ8_BY_REG_ID(_A, _I, _pV)   RTUSBReadBBPRegister(_A, _I, _pV)
477 #define RTMP_BBP_IO_WRITE8_BY_REG_ID(_A, _I, _V)   RTUSBWriteBBPRegister(_A, _I, _V)
478 
479 #define BBP_IO_WRITE8_BY_REG_ID(_A, _I, _V)			RTUSBWriteBBPRegister(_A, _I, _V)
480 #define BBP_IO_READ8_BY_REG_ID(_A, _I, _pV)		RTUSBReadBBPRegister(_A, _I, _pV)
481 #endif /* RTMP_MAC_USB // */
482 
483 #ifdef RT30xx
484 #define RTMP_ASIC_MMPS_DISABLE(_pAd)							\
485 	do {															\
486 		u32 _macData; \
487 		u8 _bbpData = 0; \
488 		/* disable MMPS BBP control register */						\
489 		RTMP_BBP_IO_READ8_BY_REG_ID(_pAd, BBP_R3, &_bbpData);	\
490 		_bbpData &= ~(0x04);	/*bit 2*/								\
491 		RTMP_BBP_IO_WRITE8_BY_REG_ID(_pAd, BBP_R3, _bbpData);	\
492 																\
493 		/* disable MMPS MAC control register */						\
494 		RTMP_IO_READ32(_pAd, 0x1210, &_macData);				\
495 		_macData &= ~(0x09);	/*bit 0, 3*/							\
496 		RTMP_IO_WRITE32(_pAd, 0x1210, _macData);				\
497 	} while (0)
498 
499 #define RTMP_ASIC_MMPS_ENABLE(_pAd)							\
500 	do {															\
501 		u32 _macData; \
502 		u8 _bbpData = 0; \
503 		/* enable MMPS BBP control register */						\
504 		RTMP_BBP_IO_READ8_BY_REG_ID(_pAd, BBP_R3, &_bbpData);	\
505 		_bbpData |= (0x04);	/*bit 2*/								\
506 		RTMP_BBP_IO_WRITE8_BY_REG_ID(_pAd, BBP_R3, _bbpData);	\
507 																\
508 		/* enable MMPS MAC control register */						\
509 		RTMP_IO_READ32(_pAd, 0x1210, &_macData);				\
510 		_macData |= (0x09);	/*bit 0, 3*/							\
511 		RTMP_IO_WRITE32(_pAd, 0x1210, _macData);				\
512 	} while (0)
513 
514 #endif /* RT30xx // */
515 
516 #endif /* __RTMP_PHY_H__ // */
517