2 *************************************************************************
4 * 5F., No.36, Taiyuan St., Jhubei City,
8 * (c) Copyright 2002-2007, Ralink Technology, Inc.
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. *
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. *
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. *
25 *************************************************************************
31 Ralink Wireless Chip PHY(BBP/RF) related definition & structures
35 -------- ---------- ----------------------------------------------
38 #ifndef __RTMP_PHY_H__
39 #define __RTMP_PHY_H__
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 */
91 #define BBP_R0 0 /* version */
92 #define BBP_R1 1 /* TSSI */
93 #define BBP_R2 2 /* TX configure */
98 #define BBP_R14 14 /* RX configure */
100 #define BBP_R17 17 /* RX sensibility */
109 #define BBP_R49 49 /*TSSI */
114 #define BBP_R62 62 /* Rx SQ0 Threshold HIGH */
122 #define BBP_R70 70 /* Rx AGC SQ CCK Xcorr threshold */
136 #define BBP_R94 94 /* Tx Gain Control */
152 #define BBP_R138 138 /* add by johnli, RF power sequence setup, ADC dynamic on/off control */
153 #endif /* RT30xx // */
155 #define BBPR94_DEFAULT 0x06 /* Add 1 value will gain 1db */
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. */
161 #define MAX_BUSY_COUNT 100 /* Number of retry before failing access BBP & RF indirect register */
163 /*#define PHY_TR_SWITCH_TIME 5 // usec */
165 /*#define BBP_R17_LOW_SENSIBILITY 0x50 */
166 /*#define BBP_R17_MID_SENSIBILITY 0x41 */
167 /*#define BBP_R17_DYNAMIC_UP_BOUND 0x40 */
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
174 /*****************************************************************************
175 RF register Read/Write marco definition
176 *****************************************************************************/
178 #define RTMP_RF_IO_WRITE32(_A, _V) \
180 if ((_A)->bPCIclkOff == FALSE) { \
181 PHY_CSR4_STRUC _value; \
182 unsigned long _busyCnt = 0; \
185 RTMP_IO_READ32((_A), RF_CSR_CFG0, &_value.word); \
186 if (_value.field.Busy == IDLE) \
189 } while (_busyCnt < MAX_BUSY_COUNT); \
190 if (_busyCnt < MAX_BUSY_COUNT) { \
191 RTMP_IO_WRITE32((_A), RF_CSR_CFG0, (_V)); \
195 #endif /* RTMP_MAC_PCI // */
197 #define RTMP_RF_IO_WRITE32(_A, _V) RTUSBWriteRFRegister(_A, _V)
198 #endif /* RTMP_MAC_USB // */
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 // */
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 *****************************************************************************/
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.
218 #define RTMP_BBP_IO_READ8(_pAd, _bbpID, _pV, _bViaMCU) \
220 BBP_CSR_CFG_STRUC BbpCsr; \
221 int _busyCnt, _secCnt, _regID; \
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) \
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); \
238 for (_secCnt = 0; _secCnt < MAX_BUSY_COUNT; _secCnt++) { \
239 RTMP_IO_READ32(_pAd, _regID, &BbpCsr.word); \
240 if (BbpCsr.field.Busy == IDLE) \
243 if ((BbpCsr.field.Busy == IDLE) && \
244 (BbpCsr.field.RegNum == _bbpID)) { \
245 *(_pV) = (u8)BbpCsr.field.Value; \
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); \
261 This marco used for the BBP read operation which didn't need via MCU.
263 #define BBP_IO_READ8_BY_REG_ID(_A, _I, _pV) \
264 RTMP_BBP_IO_READ8((_A), (_I), (_pV), FALSE)
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.
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) \
274 BBP_CSR_CFG_STRUC BbpCsr; \
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) { \
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); \
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) \
301 if ((BbpCsr.field.Busy == IDLE) && \
302 (BbpCsr.field.RegNum == _I)) { \
303 *(_pV) = (u8)BbpCsr.field.Value; \
307 BbpCsr.field.Busy = 0; \
308 RTMP_IO_WRITE32(_A, H2M_BBP_AGENT, BbpCsr.word); \
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) { \
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) \
332 if ((BbpCsr.field.Busy == IDLE) && \
333 (BbpCsr.field.RegNum == _I)) { \
334 *(_pV) = (u8)BbpCsr.field.Value; \
339 DBGPRINT_ERR(" , brt30xxBanMcuCmd = %d, Read BBP %d \n", (_A)->brt30xxBanMcuCmd, (_I)); \
340 *(_pV) = (_A)->BbpWriteLatch[_I]; \
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]; \
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.
355 #define RTMP_BBP_IO_WRITE8(_pAd, _bbpID, _pV, _bViaMCU) \
357 BBP_CSR_CFG_STRUC BbpCsr; \
358 int _busyCnt, _regID; \
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) \
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); \
377 (_pAd)->BbpWriteLatch[_bbpID] = _pV; \
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); \
391 This marco used for the BBP write operation which didn't need via MCU.
393 #define BBP_IO_WRITE8_BY_REG_ID(_A, _I, _pV) \
394 RTMP_BBP_IO_WRITE8((_A), (_I), (_pV), FALSE)
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.
401 /* Write BBP register by register's ID & value */
402 #define RTMP_BBP_IO_WRITE8_BY_REG_ID(_A, _I, _V) \
404 BBP_CSR_CFG_STRUC BbpCsr; \
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; \
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) \
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); \
430 (_A)->BbpWriteLatch[_I] = _V; \
432 BbpCsr.field.Busy = 0; \
433 RTMP_IO_WRITE32(_A, H2M_BBP_AGENT, BbpCsr.word); \
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; \
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) \
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; \
462 DBGPRINT_ERR(" brt30xxBanMcuCmd = %d. Write BBP %d \n", (_A)->brt30xxBanMcuCmd, (_I)); \
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); \
470 DBGPRINT_ERR("****** BBP_Write_Latch Buffer exceeds max boundary ****** \n"); \
473 #endif /* RTMP_MAC_PCI // */
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)
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 // */
484 #define RTMP_ASIC_MMPS_DISABLE(_pAd) \
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); \
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); \
499 #define RTMP_ASIC_MMPS_ENABLE(_pAd) \
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); \
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); \
514 #endif /* RT30xx // */
516 #endif /* __RTMP_PHY_H__ // */