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
158 #define BBPR94_DEFAULT 0x06 // Add 1 value will gain 1db
161 #ifdef MERGE_ARCH_TEAM
162 #define MAX_BBP_ID 200
163 #define MAX_BBP_MSG_SIZE 4096
166 // edit by johnli, RF power sequence setup, add BBP R138 for ADC dynamic on/off control
167 #define MAX_BBP_ID 138
170 #define MAX_BBP_ID 136
172 #define MAX_BBP_MSG_SIZE 2048
173 #endif // MERGE_ARCH_TEAM //
177 // BBP & RF are using indirect access. Before write any value into it.
178 // We have to make sure there is no outstanding command pending via checking busy bit.
180 #define MAX_BUSY_COUNT 100 // Number of retry before failing access BBP & RF indirect register
182 //#define PHY_TR_SWITCH_TIME 5 // usec
184 //#define BBP_R17_LOW_SENSIBILITY 0x50
185 //#define BBP_R17_MID_SENSIBILITY 0x41
186 //#define BBP_R17_DYNAMIC_UP_BOUND 0x40
188 #define RSSI_FOR_VERY_LOW_SENSIBILITY -35
189 #define RSSI_FOR_LOW_SENSIBILITY -58
190 #define RSSI_FOR_MID_LOW_SENSIBILITY -80
191 #define RSSI_FOR_MID_SENSIBILITY -90
193 /*****************************************************************************
194 RF register Read/Write marco definition
195 *****************************************************************************/
197 #define RTMP_RF_IO_WRITE32(_A, _V) \
199 if ((_A)->bPCIclkOff == FALSE) \
201 PHY_CSR4_STRUC _value; \
202 ULONG _busyCnt = 0; \
205 RTMP_IO_READ32((_A), RF_CSR_CFG0, &_value.word); \
206 if (_value.field.Busy == IDLE) \
209 }while (_busyCnt < MAX_BUSY_COUNT); \
210 if(_busyCnt < MAX_BUSY_COUNT) \
212 RTMP_IO_WRITE32((_A), RF_CSR_CFG0, (_V)); \
216 #endif // RTMP_MAC_PCI //
221 #define RTMP_RF_IO_READ8_BY_REG_ID(_A, _I, _pV) RT30xxReadRFRegister(_A, _I, _pV)
222 #define RTMP_RF_IO_WRITE8_BY_REG_ID(_A, _I, _V) RT30xxWriteRFRegister(_A, _I, _V)
226 /*****************************************************************************
227 BBP register Read/Write marco definitions.
228 we read/write the bbp value by register's ID.
229 Generate PER to test BA
230 *****************************************************************************/
233 basic marco for BBP read operation.
234 _pAd: the data structure pointer of RTMP_ADAPTER
235 _bbpID : the bbp register ID
236 _pV: data pointer used to save the value of queried bbp register.
237 _bViaMCU: if we need access the bbp via the MCU.
239 #define RTMP_BBP_IO_READ8(_pAd, _bbpID, _pV, _bViaMCU) \
241 BBP_CSR_CFG_STRUC BbpCsr; \
242 int _busyCnt, _secCnt, _regID; \
244 _regID = ((_bViaMCU) == TRUE ? H2M_BBP_AGENT : BBP_CSR_CFG); \
245 for (_busyCnt=0; _busyCnt<MAX_BUSY_COUNT; _busyCnt++) \
247 RTMP_IO_READ32(_pAd, _regID, &BbpCsr.word); \
248 if (BbpCsr.field.Busy == BUSY) \
251 BbpCsr.field.fRead = 1; \
252 BbpCsr.field.BBP_RW_MODE = 1; \
253 BbpCsr.field.Busy = 1; \
254 BbpCsr.field.RegNum = _bbpID; \
255 RTMP_IO_WRITE32(_pAd, _regID, BbpCsr.word); \
256 if ((_bViaMCU) == TRUE) \
258 AsicSendCommandToMcu(_pAd, 0x80, 0xff, 0x0, 0x0); \
259 RTMPusecDelay(1000); \
261 for (_secCnt=0; _secCnt<MAX_BUSY_COUNT; _secCnt++) \
263 RTMP_IO_READ32(_pAd, _regID, &BbpCsr.word); \
264 if (BbpCsr.field.Busy == IDLE) \
267 if ((BbpCsr.field.Busy == IDLE) && \
268 (BbpCsr.field.RegNum == _bbpID)) \
270 *(_pV) = (UCHAR)BbpCsr.field.Value; \
274 if (BbpCsr.field.Busy == BUSY) \
276 DBGPRINT_ERR(("BBP(viaMCU=%d) read R%d fail\n", (_bViaMCU), _bbpID)); \
277 *(_pV) = (_pAd)->BbpWriteLatch[_bbpID]; \
278 if ((_bViaMCU) == TRUE) \
280 RTMP_IO_READ32(_pAd, _regID, &BbpCsr.word); \
281 BbpCsr.field.Busy = 0; \
282 RTMP_IO_WRITE32(_pAd, _regID, BbpCsr.word); \
288 This marco used for the BBP read operation which didn't need via MCU.
290 #define BBP_IO_READ8_BY_REG_ID(_A, _I, _pV) \
291 RTMP_BBP_IO_READ8((_A), (_I), (_pV), FALSE)
294 This marco used for the BBP read operation which need via MCU.
295 But for some chipset which didn't have mcu (e.g., RBUS based chipset), we
296 will use this function too and didn't access the bbp register via the MCU.
298 #ifndef CONFIG_STA_SUPPORT
299 #define RTMP_BBP_IO_READ8_BY_REG_ID(_A, _I, _pV) \
301 if ((_A)->bPCIclkOff == FALSE) \
303 if ((_A)->infType == RTMP_DEV_INF_RBUS) \
304 RTMP_BBP_IO_READ8((_A), (_I), (_pV), FALSE); \
306 RTMP_BBP_IO_READ8((_A), (_I), (_pV), TRUE); \
309 #endif // CONFIG_STA_SUPPORT //
310 #ifdef CONFIG_STA_SUPPORT
311 // Read BBP register by register's ID. Generate PER to test BA
312 #define RTMP_BBP_IO_READ8_BY_REG_ID(_A, _I, _pV) \
314 BBP_CSR_CFG_STRUC BbpCsr; \
317 BbpCsr.field.Busy = IDLE; \
318 if ((IS_RT3090((_A)) || IS_RT3572((_A)) || IS_RT3390((_A))) && ((_A)->StaCfg.PSControl.field.rt30xxPowerMode == 3) \
319 && ((_A)->StaCfg.PSControl.field.EnableNewPS == TRUE) \
320 && ((_A)->bPCIclkOff == FALSE) \
321 && ((_A)->brt30xxBanMcuCmd == FALSE)) \
323 for (i=0; i<MAX_BUSY_COUNT; i++) \
325 RTMP_IO_READ32(_A, H2M_BBP_AGENT, &BbpCsr.word); \
326 if (BbpCsr.field.Busy == BUSY) \
331 BbpCsr.field.fRead = 1; \
332 BbpCsr.field.BBP_RW_MODE = 1; \
333 BbpCsr.field.Busy = 1; \
334 BbpCsr.field.RegNum = _I; \
335 RTMP_IO_WRITE32(_A, H2M_BBP_AGENT, BbpCsr.word); \
336 brc = AsicSendCommandToMcu(_A, 0x80, 0xff, 0x0, 0x0); \
339 for (k=0; k<MAX_BUSY_COUNT; k++) \
341 RTMP_IO_READ32(_A, H2M_BBP_AGENT, &BbpCsr.word); \
342 if (BbpCsr.field.Busy == IDLE) \
345 if ((BbpCsr.field.Busy == IDLE) && \
346 (BbpCsr.field.RegNum == _I)) \
348 *(_pV) = (UCHAR)BbpCsr.field.Value; \
354 BbpCsr.field.Busy = 0; \
355 RTMP_IO_WRITE32(_A, H2M_BBP_AGENT, BbpCsr.word); \
359 else if (!((IS_RT3090((_A)) || IS_RT3572((_A)) || IS_RT3390((_A))) && ((_A)->StaCfg.PSControl.field.rt30xxPowerMode == 3) \
360 && ((_A)->StaCfg.PSControl.field.EnableNewPS == TRUE)) \
361 && ((_A)->bPCIclkOff == FALSE)) \
363 for (i=0; i<MAX_BUSY_COUNT; i++) \
365 RTMP_IO_READ32(_A, H2M_BBP_AGENT, &BbpCsr.word); \
366 if (BbpCsr.field.Busy == BUSY) \
371 BbpCsr.field.fRead = 1; \
372 BbpCsr.field.BBP_RW_MODE = 1; \
373 BbpCsr.field.Busy = 1; \
374 BbpCsr.field.RegNum = _I; \
375 RTMP_IO_WRITE32(_A, H2M_BBP_AGENT, BbpCsr.word); \
376 AsicSendCommandToMcu(_A, 0x80, 0xff, 0x0, 0x0); \
377 for (k=0; k<MAX_BUSY_COUNT; k++) \
379 RTMP_IO_READ32(_A, H2M_BBP_AGENT, &BbpCsr.word); \
380 if (BbpCsr.field.Busy == IDLE) \
383 if ((BbpCsr.field.Busy == IDLE) && \
384 (BbpCsr.field.RegNum == _I)) \
386 *(_pV) = (UCHAR)BbpCsr.field.Value; \
393 DBGPRINT_ERR((" , brt30xxBanMcuCmd = %d, Read BBP %d \n", (_A)->brt30xxBanMcuCmd, (_I))); \
394 *(_pV) = (_A)->BbpWriteLatch[_I]; \
396 if ((BbpCsr.field.Busy == BUSY) || ((_A)->bPCIclkOff == TRUE)) \
398 DBGPRINT_ERR(("BBP read R%d=0x%x fail\n", _I, BbpCsr.word)); \
399 *(_pV) = (_A)->BbpWriteLatch[_I]; \
402 #endif // CONFIG_STA_SUPPORT //
405 basic marco for BBP write operation.
406 _pAd: the data structure pointer of RTMP_ADAPTER
407 _bbpID : the bbp register ID
408 _pV: data used to save the value of queried bbp register.
409 _bViaMCU: if we need access the bbp via the MCU.
411 #define RTMP_BBP_IO_WRITE8(_pAd, _bbpID, _pV, _bViaMCU) \
413 BBP_CSR_CFG_STRUC BbpCsr; \
414 int _busyCnt, _regID; \
416 _regID = ((_bViaMCU) == TRUE ? H2M_BBP_AGENT : BBP_CSR_CFG); \
417 for (_busyCnt=0; _busyCnt<MAX_BUSY_COUNT; _busyCnt++) \
419 RTMP_IO_READ32((_pAd), BBP_CSR_CFG, &BbpCsr.word); \
420 if (BbpCsr.field.Busy == BUSY) \
423 BbpCsr.field.fRead = 0; \
424 BbpCsr.field.BBP_RW_MODE = 1; \
425 BbpCsr.field.Busy = 1; \
426 BbpCsr.field.Value = _pV; \
427 BbpCsr.field.RegNum = _bbpID; \
428 RTMP_IO_WRITE32((_pAd), BBP_CSR_CFG, BbpCsr.word); \
429 if ((_bViaMCU) == TRUE) \
431 AsicSendCommandToMcu(_pAd, 0x80, 0xff, 0x0, 0x0); \
432 if ((_pAd)->OpMode == OPMODE_AP) \
433 RTMPusecDelay(1000); \
435 (_pAd)->BbpWriteLatch[_bbpID] = _pV; \
438 if (_busyCnt == MAX_BUSY_COUNT) \
440 DBGPRINT_ERR(("BBP write R%d fail\n", _bbpID)); \
441 if((_bViaMCU) == TRUE) \
443 RTMP_IO_READ32(_pAd, H2M_BBP_AGENT, &BbpCsr.word); \
444 BbpCsr.field.Busy = 0; \
445 RTMP_IO_WRITE32(_pAd, H2M_BBP_AGENT, BbpCsr.word); \
452 This marco used for the BBP write operation which didn't need via MCU.
454 #define BBP_IO_WRITE8_BY_REG_ID(_A, _I, _pV) \
455 RTMP_BBP_IO_WRITE8((_A), (_I), (_pV), FALSE)
458 This marco used for the BBP write operation which need via MCU.
459 But for some chipset which didn't have mcu (e.g., RBUS based chipset), we
460 will use this function too and didn't access the bbp register via the MCU.
462 #ifndef CONFIG_STA_SUPPORT
463 #define RTMP_BBP_IO_WRITE8_BY_REG_ID(_A, _I, _pV) \
465 if ((_A)->bPCIclkOff == FALSE) \
467 if ((_A)->infType == RTMP_DEV_INF_RBUS) \
468 RTMP_BBP_IO_WRITE8((_A), (_I), (_pV), FALSE); \
470 RTMP_BBP_IO_WRITE8((_A), (_I), (_pV), TRUE); \
473 #endif // CONFIG_STA_SUPPORT //
474 #ifdef CONFIG_STA_SUPPORT
475 // Write BBP register by register's ID & value
476 #define RTMP_BBP_IO_WRITE8_BY_REG_ID(_A, _I, _V) \
478 BBP_CSR_CFG_STRUC BbpCsr; \
481 if (_I < MAX_NUM_OF_BBP_LATCH) \
483 if ((IS_RT3090((_A)) || IS_RT3572((_A)) || IS_RT3390((_A))) && ((_A)->StaCfg.PSControl.field.rt30xxPowerMode == 3) \
484 && ((_A)->StaCfg.PSControl.field.EnableNewPS == TRUE) \
485 && ((_A)->bPCIclkOff == FALSE) \
486 && ((_A)->brt30xxBanMcuCmd == FALSE)) \
488 if (_A->AccessBBPFailCount > 20) \
490 AsicResetBBPAgent(_A); \
491 _A->AccessBBPFailCount = 0; \
493 for (BusyCnt=0; BusyCnt<MAX_BUSY_COUNT; BusyCnt++) \
495 RTMP_IO_READ32(_A, H2M_BBP_AGENT, &BbpCsr.word); \
496 if (BbpCsr.field.Busy == BUSY) \
499 BbpCsr.field.fRead = 0; \
500 BbpCsr.field.BBP_RW_MODE = 1; \
501 BbpCsr.field.Busy = 1; \
502 BbpCsr.field.Value = _V; \
503 BbpCsr.field.RegNum = _I; \
504 RTMP_IO_WRITE32(_A, H2M_BBP_AGENT, BbpCsr.word); \
505 brc = AsicSendCommandToMcu(_A, 0x80, 0xff, 0x0, 0x0); \
508 (_A)->BbpWriteLatch[_I] = _V; \
512 BbpCsr.field.Busy = 0; \
513 RTMP_IO_WRITE32(_A, H2M_BBP_AGENT, BbpCsr.word); \
518 else if (!((IS_RT3090((_A)) || IS_RT3572((_A)) || IS_RT3390((_A))) && ((_A)->StaCfg.PSControl.field.rt30xxPowerMode == 3) \
519 && ((_A)->StaCfg.PSControl.field.EnableNewPS == TRUE)) \
520 && ((_A)->bPCIclkOff == FALSE)) \
522 if (_A->AccessBBPFailCount > 20) \
524 AsicResetBBPAgent(_A); \
525 _A->AccessBBPFailCount = 0; \
527 for (BusyCnt=0; BusyCnt<MAX_BUSY_COUNT; BusyCnt++) \
529 RTMP_IO_READ32(_A, H2M_BBP_AGENT, &BbpCsr.word); \
530 if (BbpCsr.field.Busy == BUSY) \
533 BbpCsr.field.fRead = 0; \
534 BbpCsr.field.BBP_RW_MODE = 1; \
535 BbpCsr.field.Busy = 1; \
536 BbpCsr.field.Value = _V; \
537 BbpCsr.field.RegNum = _I; \
538 RTMP_IO_WRITE32(_A, H2M_BBP_AGENT, BbpCsr.word); \
539 AsicSendCommandToMcu(_A, 0x80, 0xff, 0x0, 0x0); \
540 (_A)->BbpWriteLatch[_I] = _V; \
546 DBGPRINT_ERR((" brt30xxBanMcuCmd = %d. Write BBP %d \n", (_A)->brt30xxBanMcuCmd, (_I))); \
548 if ((BusyCnt == MAX_BUSY_COUNT) || ((_A)->bPCIclkOff == TRUE)) \
550 if (BusyCnt == MAX_BUSY_COUNT) \
551 (_A)->AccessBBPFailCount++; \
552 DBGPRINT_ERR(("BBP write R%d=0x%x fail. BusyCnt= %d.bPCIclkOff = %d. \n", _I, BbpCsr.word, BusyCnt, (_A)->bPCIclkOff )); \
557 DBGPRINT_ERR(("****** BBP_Write_Latch Buffer exceeds max boundry ****** \n")); \
560 #endif // CONFIG_STA_SUPPORT //
561 #endif // RTMP_MAC_PCI //
566 //Need to collect each ant's rssi concurrently
567 //rssi1 is report to pair2 Ant and rss2 is reprot to pair1 Ant when 4 Ant
568 #define COLLECT_RX_ANTENNA_AVERAGE_RSSI(_pAd, _rssi1, _rssi2) \
572 if (_pAd->RxAnt.EvaluatePeriod == 0) \
574 UsedAnt = _pAd->RxAnt.Pair1PrimaryRxAnt; \
575 AvgRssi = _pAd->RxAnt.Pair1AvgRssi[UsedAnt]; \
577 AvgRssi = AvgRssi - (AvgRssi >> 3) + _rssi1; \
579 AvgRssi = _rssi1 << 3; \
580 _pAd->RxAnt.Pair1AvgRssi[UsedAnt] = AvgRssi; \
584 UsedAnt = _pAd->RxAnt.Pair1SecondaryRxAnt; \
585 AvgRssi = _pAd->RxAnt.Pair1AvgRssi[UsedAnt]; \
586 if ((AvgRssi < 0) && (_pAd->RxAnt.FirstPktArrivedWhenEvaluate)) \
587 AvgRssi = AvgRssi - (AvgRssi >> 3) + _rssi1; \
590 _pAd->RxAnt.FirstPktArrivedWhenEvaluate = TRUE; \
591 AvgRssi = _rssi1 << 3; \
593 _pAd->RxAnt.Pair1AvgRssi[UsedAnt] = AvgRssi; \
594 _pAd->RxAnt.RcvPktNumWhenEvaluate++; \
598 #define RTMP_ASIC_MMPS_DISABLE(_pAd) \
602 /* disable MMPS BBP control register */ \
603 RTMP_BBP_IO_READ8_BY_REG_ID(_pAd, BBP_R3, &_bbpData); \
604 _bbpData &= ~(0x04); /*bit 2*/ \
605 RTMP_BBP_IO_WRITE8_BY_REG_ID(_pAd, BBP_R3, _bbpData); \
607 /* disable MMPS MAC control register */ \
608 RTMP_IO_READ32(_pAd, 0x1210, &_macData); \
609 _macData &= ~(0x09); /*bit 0, 3*/ \
610 RTMP_IO_WRITE32(_pAd, 0x1210, _macData); \
614 #define RTMP_ASIC_MMPS_ENABLE(_pAd) \
618 /* enable MMPS BBP control register */ \
619 RTMP_BBP_IO_READ8_BY_REG_ID(_pAd, BBP_R3, &_bbpData); \
620 _bbpData |= (0x04); /*bit 2*/ \
621 RTMP_BBP_IO_WRITE8_BY_REG_ID(_pAd, BBP_R3, _bbpData); \
623 /* enable MMPS MAC control register */ \
624 RTMP_IO_READ32(_pAd, 0x1210, &_macData); \
625 _macData |= (0x09); /*bit 0, 3*/ \
626 RTMP_IO_WRITE32(_pAd, 0x1210, _macData); \
631 #endif // __RTMP_PHY_H__ //