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__
79 // value domain of pAd->RfIcType
80 #define RFIC_2820 1 // 2.4G 2T3R
81 #define RFIC_2850 2 // 2.4G/5G 2T3R
82 #define RFIC_2720 3 // 2.4G 1T2R
83 #define RFIC_2750 4 // 2.4G/5G 1T2R
84 #define RFIC_3020 5 // 2.4G 1T1R
85 #define RFIC_2020 6 // 2.4G B/G
86 #define RFIC_3021 7 // 2.4G 1T2R
87 #define RFIC_3022 8 // 2.4G 2T2R
88 #define RFIC_3052 9 // 2.4G/5G 2T2R
93 #define BBP_R0 0 // version
94 #define BBP_R1 1 // TSSI
95 #define BBP_R2 2 // TX configure
100 #define BBP_R14 14 // RX configure
102 #define BBP_R17 17 // RX sensibility
111 #define BBP_R49 49 //TSSI
116 #define BBP_R62 62 // Rx SQ0 Threshold HIGH
124 #define BBP_R70 70 // Rx AGC SQ CCK Xcorr threshold
138 #define BBP_R94 94 // Tx Gain Control
154 #define BBP_R138 138 // add by johnli, RF power sequence setup, ADC dynamic on/off control
157 #define BBPR94_DEFAULT 0x06 // Add 1 value will gain 1db
160 // BBP & RF are using indirect access. Before write any value into it.
161 // We have to make sure there is no outstanding command pending via checking busy bit.
163 #define MAX_BUSY_COUNT 100 // Number of retry before failing access BBP & RF indirect register
165 //#define PHY_TR_SWITCH_TIME 5 // usec
167 //#define BBP_R17_LOW_SENSIBILITY 0x50
168 //#define BBP_R17_MID_SENSIBILITY 0x41
169 //#define BBP_R17_DYNAMIC_UP_BOUND 0x40
171 #define RSSI_FOR_VERY_LOW_SENSIBILITY -35
172 #define RSSI_FOR_LOW_SENSIBILITY -58
173 #define RSSI_FOR_MID_LOW_SENSIBILITY -80
174 #define RSSI_FOR_MID_SENSIBILITY -90
176 /*****************************************************************************
177 RF register Read/Write marco definition
178 *****************************************************************************/
180 #define RTMP_RF_IO_WRITE32(_A, _V) \
182 if ((_A)->bPCIclkOff == FALSE) \
184 PHY_CSR4_STRUC _value; \
185 ULONG _busyCnt = 0; \
188 RTMP_IO_READ32((_A), RF_CSR_CFG0, &_value.word); \
189 if (_value.field.Busy == IDLE) \
192 }while (_busyCnt < MAX_BUSY_COUNT); \
193 if(_busyCnt < MAX_BUSY_COUNT) \
195 RTMP_IO_WRITE32((_A), RF_CSR_CFG0, (_V)); \
199 #endif // RTMP_MAC_PCI //
201 #define RTMP_RF_IO_WRITE32(_A, _V) RTUSBWriteRFRegister(_A, _V)
202 #endif // RTMP_MAC_USB //
205 #define RTMP_RF_IO_READ8_BY_REG_ID(_A, _I, _pV) RT30xxReadRFRegister(_A, _I, _pV)
206 #define RTMP_RF_IO_WRITE8_BY_REG_ID(_A, _I, _V) RT30xxWriteRFRegister(_A, _I, _V)
209 /*****************************************************************************
210 BBP register Read/Write marco definitions.
211 we read/write the bbp value by register's ID.
212 Generate PER to test BA
213 *****************************************************************************/
216 basic marco for BBP read operation.
217 _pAd: the data structure pointer of RTMP_ADAPTER
218 _bbpID : the bbp register ID
219 _pV: data pointer used to save the value of queried bbp register.
220 _bViaMCU: if we need access the bbp via the MCU.
222 #define RTMP_BBP_IO_READ8(_pAd, _bbpID, _pV, _bViaMCU) \
224 BBP_CSR_CFG_STRUC BbpCsr; \
225 int _busyCnt, _secCnt, _regID; \
227 _regID = ((_bViaMCU) == TRUE ? H2M_BBP_AGENT : BBP_CSR_CFG); \
228 for (_busyCnt=0; _busyCnt<MAX_BUSY_COUNT; _busyCnt++) \
230 RTMP_IO_READ32(_pAd, _regID, &BbpCsr.word); \
231 if (BbpCsr.field.Busy == BUSY) \
234 BbpCsr.field.fRead = 1; \
235 BbpCsr.field.BBP_RW_MODE = 1; \
236 BbpCsr.field.Busy = 1; \
237 BbpCsr.field.RegNum = _bbpID; \
238 RTMP_IO_WRITE32(_pAd, _regID, BbpCsr.word); \
239 if ((_bViaMCU) == TRUE) \
241 AsicSendCommandToMcu(_pAd, 0x80, 0xff, 0x0, 0x0); \
242 RTMPusecDelay(1000); \
244 for (_secCnt=0; _secCnt<MAX_BUSY_COUNT; _secCnt++) \
246 RTMP_IO_READ32(_pAd, _regID, &BbpCsr.word); \
247 if (BbpCsr.field.Busy == IDLE) \
250 if ((BbpCsr.field.Busy == IDLE) && \
251 (BbpCsr.field.RegNum == _bbpID)) \
253 *(_pV) = (UCHAR)BbpCsr.field.Value; \
257 if (BbpCsr.field.Busy == BUSY) \
259 DBGPRINT_ERR(("BBP(viaMCU=%d) read R%d fail\n", (_bViaMCU), _bbpID)); \
260 *(_pV) = (_pAd)->BbpWriteLatch[_bbpID]; \
261 if ((_bViaMCU) == TRUE) \
263 RTMP_IO_READ32(_pAd, _regID, &BbpCsr.word); \
264 BbpCsr.field.Busy = 0; \
265 RTMP_IO_WRITE32(_pAd, _regID, BbpCsr.word); \
271 This marco used for the BBP read operation which didn't need via MCU.
273 #define BBP_IO_READ8_BY_REG_ID(_A, _I, _pV) \
274 RTMP_BBP_IO_READ8((_A), (_I), (_pV), FALSE)
277 This marco used for the BBP read operation which need via MCU.
278 But for some chipset which didn't have mcu (e.g., RBUS based chipset), we
279 will use this function too and didn't access the bbp register via the MCU.
282 #define RTMP_BBP_IO_READ8_BY_REG_ID(_A, _I, _pV) \
284 if ((_A)->bPCIclkOff == FALSE) \
286 if ((_A)->infType == RTMP_DEV_INF_RBUS) \
287 RTMP_BBP_IO_READ8((_A), (_I), (_pV), FALSE); \
289 RTMP_BBP_IO_READ8((_A), (_I), (_pV), TRUE); \
293 // Read BBP register by register's ID. Generate PER to test BA
294 #define RTMP_BBP_IO_READ8_BY_REG_ID(_A, _I, _pV) \
296 BBP_CSR_CFG_STRUC BbpCsr; \
299 BbpCsr.field.Busy = IDLE; \
300 if ((IS_RT3090((_A)) || IS_RT3572((_A)) || IS_RT3390((_A))) && ((_A)->StaCfg.PSControl.field.rt30xxPowerMode == 3) \
301 && ((_A)->StaCfg.PSControl.field.EnableNewPS == TRUE) \
302 && ((_A)->bPCIclkOff == FALSE) \
303 && ((_A)->brt30xxBanMcuCmd == FALSE)) \
305 for (i=0; i<MAX_BUSY_COUNT; i++) \
307 RTMP_IO_READ32(_A, H2M_BBP_AGENT, &BbpCsr.word); \
308 if (BbpCsr.field.Busy == BUSY) \
313 BbpCsr.field.fRead = 1; \
314 BbpCsr.field.BBP_RW_MODE = 1; \
315 BbpCsr.field.Busy = 1; \
316 BbpCsr.field.RegNum = _I; \
317 RTMP_IO_WRITE32(_A, H2M_BBP_AGENT, BbpCsr.word); \
318 brc = AsicSendCommandToMcu(_A, 0x80, 0xff, 0x0, 0x0); \
321 for (k=0; k<MAX_BUSY_COUNT; k++) \
323 RTMP_IO_READ32(_A, H2M_BBP_AGENT, &BbpCsr.word); \
324 if (BbpCsr.field.Busy == IDLE) \
327 if ((BbpCsr.field.Busy == IDLE) && \
328 (BbpCsr.field.RegNum == _I)) \
330 *(_pV) = (UCHAR)BbpCsr.field.Value; \
336 BbpCsr.field.Busy = 0; \
337 RTMP_IO_WRITE32(_A, H2M_BBP_AGENT, BbpCsr.word); \
341 else if (!((IS_RT3090((_A)) || IS_RT3572((_A)) || IS_RT3390((_A))) && ((_A)->StaCfg.PSControl.field.rt30xxPowerMode == 3) \
342 && ((_A)->StaCfg.PSControl.field.EnableNewPS == TRUE)) \
343 && ((_A)->bPCIclkOff == FALSE)) \
345 for (i=0; i<MAX_BUSY_COUNT; i++) \
347 RTMP_IO_READ32(_A, H2M_BBP_AGENT, &BbpCsr.word); \
348 if (BbpCsr.field.Busy == BUSY) \
353 BbpCsr.field.fRead = 1; \
354 BbpCsr.field.BBP_RW_MODE = 1; \
355 BbpCsr.field.Busy = 1; \
356 BbpCsr.field.RegNum = _I; \
357 RTMP_IO_WRITE32(_A, H2M_BBP_AGENT, BbpCsr.word); \
358 AsicSendCommandToMcu(_A, 0x80, 0xff, 0x0, 0x0); \
359 for (k=0; k<MAX_BUSY_COUNT; k++) \
361 RTMP_IO_READ32(_A, H2M_BBP_AGENT, &BbpCsr.word); \
362 if (BbpCsr.field.Busy == IDLE) \
365 if ((BbpCsr.field.Busy == IDLE) && \
366 (BbpCsr.field.RegNum == _I)) \
368 *(_pV) = (UCHAR)BbpCsr.field.Value; \
375 DBGPRINT_ERR((" , brt30xxBanMcuCmd = %d, Read BBP %d \n", (_A)->brt30xxBanMcuCmd, (_I))); \
376 *(_pV) = (_A)->BbpWriteLatch[_I]; \
378 if ((BbpCsr.field.Busy == BUSY) || ((_A)->bPCIclkOff == TRUE)) \
380 DBGPRINT_ERR(("BBP read R%d=0x%x fail\n", _I, BbpCsr.word)); \
381 *(_pV) = (_A)->BbpWriteLatch[_I]; \
387 basic marco for BBP write operation.
388 _pAd: the data structure pointer of RTMP_ADAPTER
389 _bbpID : the bbp register ID
390 _pV: data used to save the value of queried bbp register.
391 _bViaMCU: if we need access the bbp via the MCU.
393 #define RTMP_BBP_IO_WRITE8(_pAd, _bbpID, _pV, _bViaMCU) \
395 BBP_CSR_CFG_STRUC BbpCsr; \
396 int _busyCnt, _regID; \
398 _regID = ((_bViaMCU) == TRUE ? H2M_BBP_AGENT : BBP_CSR_CFG); \
399 for (_busyCnt=0; _busyCnt<MAX_BUSY_COUNT; _busyCnt++) \
401 RTMP_IO_READ32((_pAd), BBP_CSR_CFG, &BbpCsr.word); \
402 if (BbpCsr.field.Busy == BUSY) \
405 BbpCsr.field.fRead = 0; \
406 BbpCsr.field.BBP_RW_MODE = 1; \
407 BbpCsr.field.Busy = 1; \
408 BbpCsr.field.Value = _pV; \
409 BbpCsr.field.RegNum = _bbpID; \
410 RTMP_IO_WRITE32((_pAd), BBP_CSR_CFG, BbpCsr.word); \
411 if ((_bViaMCU) == TRUE) \
413 AsicSendCommandToMcu(_pAd, 0x80, 0xff, 0x0, 0x0); \
414 if ((_pAd)->OpMode == OPMODE_AP) \
415 RTMPusecDelay(1000); \
417 (_pAd)->BbpWriteLatch[_bbpID] = _pV; \
420 if (_busyCnt == MAX_BUSY_COUNT) \
422 DBGPRINT_ERR(("BBP write R%d fail\n", _bbpID)); \
423 if((_bViaMCU) == TRUE) \
425 RTMP_IO_READ32(_pAd, H2M_BBP_AGENT, &BbpCsr.word); \
426 BbpCsr.field.Busy = 0; \
427 RTMP_IO_WRITE32(_pAd, H2M_BBP_AGENT, BbpCsr.word); \
434 This marco used for the BBP write operation which didn't need via MCU.
436 #define BBP_IO_WRITE8_BY_REG_ID(_A, _I, _pV) \
437 RTMP_BBP_IO_WRITE8((_A), (_I), (_pV), FALSE)
440 This marco used for the BBP write operation which need via MCU.
441 But for some chipset which didn't have mcu (e.g., RBUS based chipset), we
442 will use this function too and didn't access the bbp register via the MCU.
445 #define RTMP_BBP_IO_WRITE8_BY_REG_ID(_A, _I, _pV) \
447 if ((_A)->bPCIclkOff == FALSE) \
449 if ((_A)->infType == RTMP_DEV_INF_RBUS) \
450 RTMP_BBP_IO_WRITE8((_A), (_I), (_pV), FALSE); \
452 RTMP_BBP_IO_WRITE8((_A), (_I), (_pV), TRUE); \
456 // Write BBP register by register's ID & value
457 #define RTMP_BBP_IO_WRITE8_BY_REG_ID(_A, _I, _V) \
459 BBP_CSR_CFG_STRUC BbpCsr; \
462 if (_I < MAX_NUM_OF_BBP_LATCH) \
464 if ((IS_RT3090((_A)) || IS_RT3572((_A)) || IS_RT3390((_A))) && ((_A)->StaCfg.PSControl.field.rt30xxPowerMode == 3) \
465 && ((_A)->StaCfg.PSControl.field.EnableNewPS == TRUE) \
466 && ((_A)->bPCIclkOff == FALSE) \
467 && ((_A)->brt30xxBanMcuCmd == FALSE)) \
469 if (_A->AccessBBPFailCount > 20) \
471 AsicResetBBPAgent(_A); \
472 _A->AccessBBPFailCount = 0; \
474 for (BusyCnt=0; BusyCnt<MAX_BUSY_COUNT; BusyCnt++) \
476 RTMP_IO_READ32(_A, H2M_BBP_AGENT, &BbpCsr.word); \
477 if (BbpCsr.field.Busy == BUSY) \
480 BbpCsr.field.fRead = 0; \
481 BbpCsr.field.BBP_RW_MODE = 1; \
482 BbpCsr.field.Busy = 1; \
483 BbpCsr.field.Value = _V; \
484 BbpCsr.field.RegNum = _I; \
485 RTMP_IO_WRITE32(_A, H2M_BBP_AGENT, BbpCsr.word); \
486 brc = AsicSendCommandToMcu(_A, 0x80, 0xff, 0x0, 0x0); \
489 (_A)->BbpWriteLatch[_I] = _V; \
493 BbpCsr.field.Busy = 0; \
494 RTMP_IO_WRITE32(_A, H2M_BBP_AGENT, BbpCsr.word); \
499 else if (!((IS_RT3090((_A)) || IS_RT3572((_A)) || IS_RT3390((_A))) && ((_A)->StaCfg.PSControl.field.rt30xxPowerMode == 3) \
500 && ((_A)->StaCfg.PSControl.field.EnableNewPS == TRUE)) \
501 && ((_A)->bPCIclkOff == FALSE)) \
503 if (_A->AccessBBPFailCount > 20) \
505 AsicResetBBPAgent(_A); \
506 _A->AccessBBPFailCount = 0; \
508 for (BusyCnt=0; BusyCnt<MAX_BUSY_COUNT; BusyCnt++) \
510 RTMP_IO_READ32(_A, H2M_BBP_AGENT, &BbpCsr.word); \
511 if (BbpCsr.field.Busy == BUSY) \
514 BbpCsr.field.fRead = 0; \
515 BbpCsr.field.BBP_RW_MODE = 1; \
516 BbpCsr.field.Busy = 1; \
517 BbpCsr.field.Value = _V; \
518 BbpCsr.field.RegNum = _I; \
519 RTMP_IO_WRITE32(_A, H2M_BBP_AGENT, BbpCsr.word); \
520 AsicSendCommandToMcu(_A, 0x80, 0xff, 0x0, 0x0); \
521 (_A)->BbpWriteLatch[_I] = _V; \
527 DBGPRINT_ERR((" brt30xxBanMcuCmd = %d. Write BBP %d \n", (_A)->brt30xxBanMcuCmd, (_I))); \
529 if ((BusyCnt == MAX_BUSY_COUNT) || ((_A)->bPCIclkOff == TRUE)) \
531 if (BusyCnt == MAX_BUSY_COUNT) \
532 (_A)->AccessBBPFailCount++; \
533 DBGPRINT_ERR(("BBP write R%d=0x%x fail. BusyCnt= %d.bPCIclkOff = %d. \n", _I, BbpCsr.word, BusyCnt, (_A)->bPCIclkOff )); \
538 DBGPRINT_ERR(("****** BBP_Write_Latch Buffer exceeds max boundry ****** \n")); \
543 #endif // RTMP_MAC_PCI //
545 #define RTMP_BBP_IO_READ8_BY_REG_ID(_A, _I, _pV) RTUSBReadBBPRegister(_A, _I, _pV)
546 #define RTMP_BBP_IO_WRITE8_BY_REG_ID(_A, _I, _V) RTUSBWriteBBPRegister(_A, _I, _V)
548 #define BBP_IO_WRITE8_BY_REG_ID(_A, _I, _V) RTUSBWriteBBPRegister(_A, _I, _V)
549 #define BBP_IO_READ8_BY_REG_ID(_A, _I, _pV) RTUSBReadBBPRegister(_A, _I, _pV)
550 #endif // RTMP_MAC_USB //
553 #define RTMP_ASIC_MMPS_DISABLE(_pAd) \
556 UCHAR _bbpData = 0; \
557 /* disable MMPS BBP control register */ \
558 RTMP_BBP_IO_READ8_BY_REG_ID(_pAd, BBP_R3, &_bbpData); \
559 _bbpData &= ~(0x04); /*bit 2*/ \
560 RTMP_BBP_IO_WRITE8_BY_REG_ID(_pAd, BBP_R3, _bbpData); \
562 /* disable MMPS MAC control register */ \
563 RTMP_IO_READ32(_pAd, 0x1210, &_macData); \
564 _macData &= ~(0x09); /*bit 0, 3*/ \
565 RTMP_IO_WRITE32(_pAd, 0x1210, _macData); \
569 #define RTMP_ASIC_MMPS_ENABLE(_pAd) \
572 UCHAR _bbpData = 0; \
573 /* enable MMPS BBP control register */ \
574 RTMP_BBP_IO_READ8_BY_REG_ID(_pAd, BBP_R3, &_bbpData); \
575 _bbpData |= (0x04); /*bit 2*/ \
576 RTMP_BBP_IO_WRITE8_BY_REG_ID(_pAd, BBP_R3, _bbpData); \
578 /* enable MMPS MAC control register */ \
579 RTMP_IO_READ32(_pAd, 0x1210, &_macData); \
580 _macData |= (0x09); /*bit 0, 3*/ \
581 RTMP_IO_WRITE32(_pAd, 0x1210, _macData); \
586 #endif // __RTMP_PHY_H__ //