blob: 21a95ffdfb865aa461e2eb5bb63b9b09f925b331 [file] [log] [blame]
/*
*************************************************************************
* Ralink Tech Inc.
* 5F., No.36, Taiyuan St., Jhubei City,
* Hsinchu County 302,
* Taiwan, R.O.C.
*
* (c) Copyright 2002-2007, Ralink Technology, Inc.
*
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. *
* *
* This program is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU General Public License for more details. *
* *
* You should have received a copy of the GNU General Public License *
* along with this program; if not, write to the *
* Free Software Foundation, Inc., *
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
* *
*************************************************************************
Module Name:
rtmp_init.c
Abstract:
Miniport generic portion header file
Revision History:
Who When What
-------- ---------- ----------------------------------------------
*/
#include "../rt_config.h"
u8 BIT8[] = { 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80 };
char *CipherName[] =
{ "none", "wep64", "wep128", "TKIP", "AES", "CKIP64", "CKIP128" };
/* */
/* BBP register initialization set */
/* */
struct rt_reg_pair BBPRegTable[] = {
{BBP_R65, 0x2C}, /* fix rssi issue */
{BBP_R66, 0x38}, /* Also set this default value to pAd->BbpTuning.R66CurrentValue at initial */
{BBP_R69, 0x12},
{BBP_R70, 0xa}, /* BBP_R70 will change to 0x8 in ApStartUp and LinkUp for rt2860C, otherwise value is 0xa */
{BBP_R73, 0x10},
{BBP_R81, 0x37},
{BBP_R82, 0x62},
{BBP_R83, 0x6A},
{BBP_R84, 0x99}, /* 0x19 is for rt2860E and after. This is for extension channel overlapping IOT. 0x99 is for rt2860D and before */
{BBP_R86, 0x00}, /* middle range issue, Rory @2008-01-28 */
{BBP_R91, 0x04}, /* middle range issue, Rory @2008-01-28 */
{BBP_R92, 0x00}, /* middle range issue, Rory @2008-01-28 */
{BBP_R103, 0x00}, /* near range high-power issue, requested from Gary @2008-0528 */
{BBP_R105, 0x05}, /* 0x05 is for rt2860E to turn on FEQ control. It is safe for rt2860D and before, because Bit 7:2 are reserved in rt2860D and before. */
{BBP_R106, 0x35}, /* for ShortGI throughput */
};
#define NUM_BBP_REG_PARMS (sizeof(BBPRegTable) / sizeof(struct rt_reg_pair))
/* */
/* ASIC register initialization sets */
/* */
struct rt_rtmp_reg_pair MACRegTable[] = {
#if defined(HW_BEACON_OFFSET) && (HW_BEACON_OFFSET == 0x200)
{BCN_OFFSET0, 0xf8f0e8e0}, /* 0x3800(e0), 0x3A00(e8), 0x3C00(f0), 0x3E00(f8), 512B for each beacon */
{BCN_OFFSET1, 0x6f77d0c8}, /* 0x3200(c8), 0x3400(d0), 0x1DC0(77), 0x1BC0(6f), 512B for each beacon */
#elif defined(HW_BEACON_OFFSET) && (HW_BEACON_OFFSET == 0x100)
{BCN_OFFSET0, 0xece8e4e0}, /* 0x3800, 0x3A00, 0x3C00, 0x3E00, 512B for each beacon */
{BCN_OFFSET1, 0xfcf8f4f0}, /* 0x3800, 0x3A00, 0x3C00, 0x3E00, 512B for each beacon */
#else
#error You must re-calculate new value for BCN_OFFSET0 & BCN_OFFSET1 in MACRegTable[]!
#endif /* HW_BEACON_OFFSET // */
{LEGACY_BASIC_RATE, 0x0000013f}, /* Basic rate set bitmap */
{HT_BASIC_RATE, 0x00008003}, /* Basic HT rate set , 20M, MCS=3, MM. Format is the same as in TXWI. */
{MAC_SYS_CTRL, 0x00}, /* 0x1004, , default Disable RX */
{RX_FILTR_CFG, 0x17f97}, /*0x1400 , RX filter control, */
{BKOFF_SLOT_CFG, 0x209}, /* default set short slot time, CC_DELAY_TIME should be 2 */
/*{TX_SW_CFG0, 0x40a06}, // Gary,2006-08-23 */
{TX_SW_CFG0, 0x0}, /* Gary,2008-05-21 for CWC test */
{TX_SW_CFG1, 0x80606}, /* Gary,2006-08-23 */
{TX_LINK_CFG, 0x1020}, /* Gary,2006-08-23 */
/*{TX_TIMEOUT_CFG, 0x00182090}, // CCK has some problem. So increase timieout value. 2006-10-09// MArvek RT */
{TX_TIMEOUT_CFG, 0x000a2090}, /* CCK has some problem. So increase timieout value. 2006-10-09// MArvek RT , Modify for 2860E ,2007-08-01 */
{MAX_LEN_CFG, MAX_AGGREGATION_SIZE | 0x00001000}, /* 0x3018, MAX frame length. Max PSDU = 16kbytes. */
{LED_CFG, 0x7f031e46}, /* Gary, 2006-08-23 */
{PBF_MAX_PCNT, 0x1F3FBF9F}, /*0x1F3f7f9f}, //Jan, 2006/04/20 */
{TX_RTY_CFG, 0x47d01f0f}, /* Jan, 2006/11/16, Set TxWI->ACK =0 in Probe Rsp Modify for 2860E ,2007-08-03 */
{AUTO_RSP_CFG, 0x00000013}, /* Initial Auto_Responder, because QA will turn off Auto-Responder */
{CCK_PROT_CFG, 0x05740003 /*0x01740003 */ }, /* Initial Auto_Responder, because QA will turn off Auto-Responder. And RTS threshold is enabled. */
{OFDM_PROT_CFG, 0x05740003 /*0x01740003 */ }, /* Initial Auto_Responder, because QA will turn off Auto-Responder. And RTS threshold is enabled. */
#ifdef RTMP_MAC_USB
{PBF_CFG, 0xf40006}, /* Only enable Queue 2 */
{MM40_PROT_CFG, 0x3F44084}, /* Initial Auto_Responder, because QA will turn off Auto-Responder */
{WPDMA_GLO_CFG, 0x00000030},
#endif /* RTMP_MAC_USB // */
{GF20_PROT_CFG, 0x01744004}, /* set 19:18 --> Short NAV for MIMO PS */
{GF40_PROT_CFG, 0x03F44084},
{MM20_PROT_CFG, 0x01744004},
#ifdef RTMP_MAC_PCI
{MM40_PROT_CFG, 0x03F54084},
#endif /* RTMP_MAC_PCI // */
{TXOP_CTRL_CFG, 0x0000583f, /*0x0000243f *//*0x000024bf */ }, /*Extension channel backoff. */
{TX_RTS_CFG, 0x00092b20},
{EXP_ACK_TIME, 0x002400ca}, /* default value */
{TXOP_HLDR_ET, 0x00000002},
/* Jerry comments 2008/01/16: we use SIFS = 10us in CCK defaultly, but it seems that 10us
is too small for INTEL 2200bg card, so in MBSS mode, the delta time between beacon0
and beacon1 is SIFS (10us), so if INTEL 2200bg card connects to BSS0, the ping
will always lost. So we change the SIFS of CCK from 10us to 16us. */
{XIFS_TIME_CFG, 0x33a41010},
{PWR_PIN_CFG, 0x00000003}, /* patch for 2880-E */
};
struct rt_rtmp_reg_pair STAMACRegTable[] = {
{WMM_AIFSN_CFG, 0x00002273},
{WMM_CWMIN_CFG, 0x00002344},
{WMM_CWMAX_CFG, 0x000034aa},
};
#define NUM_MAC_REG_PARMS (sizeof(MACRegTable) / sizeof(struct rt_rtmp_reg_pair))
#define NUM_STA_MAC_REG_PARMS (sizeof(STAMACRegTable) / sizeof(struct rt_rtmp_reg_pair))
/*
========================================================================
Routine Description:
Allocate struct rt_rtmp_adapter data block and do some initialization
Arguments:
Adapter Pointer to our adapter
Return Value:
NDIS_STATUS_SUCCESS
NDIS_STATUS_FAILURE
IRQL = PASSIVE_LEVEL
Note:
========================================================================
*/
int RTMPAllocAdapterBlock(void *handle,
struct rt_rtmp_adapter * * ppAdapter)
{
struct rt_rtmp_adapter *pAd;
int Status;
int index;
u8 *pBeaconBuf = NULL;
DBGPRINT(RT_DEBUG_TRACE, ("--> RTMPAllocAdapterBlock\n"));
*ppAdapter = NULL;
do {
/* Allocate struct rt_rtmp_adapter memory block */
pBeaconBuf = kmalloc(MAX_BEACON_SIZE, MEM_ALLOC_FLAG);
if (pBeaconBuf == NULL) {
Status = NDIS_STATUS_FAILURE;
DBGPRINT_ERR(("Failed to allocate memory - BeaconBuf!\n"));
break;
}
NdisZeroMemory(pBeaconBuf, MAX_BEACON_SIZE);
Status = AdapterBlockAllocateMemory(handle, (void **) & pAd);
if (Status != NDIS_STATUS_SUCCESS) {
DBGPRINT_ERR(("Failed to allocate memory - ADAPTER\n"));
break;
}
pAd->BeaconBuf = pBeaconBuf;
DBGPRINT(RT_DEBUG_OFF,
("=== pAd = %p, size = %d ===\n", pAd,
(u32)sizeof(struct rt_rtmp_adapter)));
/* Init spin locks */
NdisAllocateSpinLock(&pAd->MgmtRingLock);
#ifdef RTMP_MAC_PCI
NdisAllocateSpinLock(&pAd->RxRingLock);
#ifdef RT3090
NdisAllocateSpinLock(&pAd->McuCmdLock);
#endif /* RT3090 // */
#endif /* RTMP_MAC_PCI // */
for (index = 0; index < NUM_OF_TX_RING; index++) {
NdisAllocateSpinLock(&pAd->TxSwQueueLock[index]);
NdisAllocateSpinLock(&pAd->DeQueueLock[index]);
pAd->DeQueueRunning[index] = FALSE;
}
NdisAllocateSpinLock(&pAd->irq_lock);
} while (FALSE);
if ((Status != NDIS_STATUS_SUCCESS) && (pBeaconBuf))
kfree(pBeaconBuf);
*ppAdapter = pAd;
DBGPRINT_S(Status, ("<-- RTMPAllocAdapterBlock, Status=%x\n", Status));
return Status;
}
/*
========================================================================
Routine Description:
Read initial Tx power per MCS and BW from EEPROM
Arguments:
Adapter Pointer to our adapter
Return Value:
None
IRQL = PASSIVE_LEVEL
Note:
========================================================================
*/
void RTMPReadTxPwrPerRate(struct rt_rtmp_adapter *pAd)
{
unsigned long data, Adata, Gdata;
u16 i, value, value2;
int Apwrdelta, Gpwrdelta;
u8 t1, t2, t3, t4;
BOOLEAN bApwrdeltaMinus = TRUE, bGpwrdeltaMinus = TRUE;
/* */
/* Get power delta for 20MHz and 40MHz. */
/* */
DBGPRINT(RT_DEBUG_TRACE, ("Txpower per Rate\n"));
RT28xx_EEPROM_READ16(pAd, EEPROM_TXPOWER_DELTA, value2);
Apwrdelta = 0;
Gpwrdelta = 0;
if ((value2 & 0xff) != 0xff) {
if ((value2 & 0x80))
Gpwrdelta = (value2 & 0xf);
if ((value2 & 0x40))
bGpwrdeltaMinus = FALSE;
else
bGpwrdeltaMinus = TRUE;
}
if ((value2 & 0xff00) != 0xff00) {
if ((value2 & 0x8000))
Apwrdelta = ((value2 & 0xf00) >> 8);
if ((value2 & 0x4000))
bApwrdeltaMinus = FALSE;
else
bApwrdeltaMinus = TRUE;
}
DBGPRINT(RT_DEBUG_TRACE,
("Gpwrdelta = %x, Apwrdelta = %x .\n", Gpwrdelta, Apwrdelta));
/* */
/* Get Txpower per MCS for 20MHz in 2.4G. */
/* */
for (i = 0; i < 5; i++) {
RT28xx_EEPROM_READ16(pAd,
EEPROM_TXPOWER_BYRATE_20MHZ_2_4G + i * 4,
value);
data = value;
if (bApwrdeltaMinus == FALSE) {
t1 = (value & 0xf) + (Apwrdelta);
if (t1 > 0xf)
t1 = 0xf;
t2 = ((value & 0xf0) >> 4) + (Apwrdelta);
if (t2 > 0xf)
t2 = 0xf;
t3 = ((value & 0xf00) >> 8) + (Apwrdelta);
if (t3 > 0xf)
t3 = 0xf;
t4 = ((value & 0xf000) >> 12) + (Apwrdelta);
if (t4 > 0xf)
t4 = 0xf;
} else {
if ((value & 0xf) > Apwrdelta)
t1 = (value & 0xf) - (Apwrdelta);
else
t1 = 0;
if (((value & 0xf0) >> 4) > Apwrdelta)
t2 = ((value & 0xf0) >> 4) - (Apwrdelta);
else
t2 = 0;
if (((value & 0xf00) >> 8) > Apwrdelta)
t3 = ((value & 0xf00) >> 8) - (Apwrdelta);
else
t3 = 0;
if (((value & 0xf000) >> 12) > Apwrdelta)
t4 = ((value & 0xf000) >> 12) - (Apwrdelta);
else
t4 = 0;
}
Adata = t1 + (t2 << 4) + (t3 << 8) + (t4 << 12);
if (bGpwrdeltaMinus == FALSE) {
t1 = (value & 0xf) + (Gpwrdelta);
if (t1 > 0xf)
t1 = 0xf;
t2 = ((value & 0xf0) >> 4) + (Gpwrdelta);
if (t2 > 0xf)
t2 = 0xf;
t3 = ((value & 0xf00) >> 8) + (Gpwrdelta);
if (t3 > 0xf)
t3 = 0xf;
t4 = ((value & 0xf000) >> 12) + (Gpwrdelta);
if (t4 > 0xf)
t4 = 0xf;
} else {
if ((value & 0xf) > Gpwrdelta)
t1 = (value & 0xf) - (Gpwrdelta);
else
t1 = 0;
if (((value & 0xf0) >> 4) > Gpwrdelta)
t2 = ((value & 0xf0) >> 4) - (Gpwrdelta);
else
t2 = 0;
if (((value & 0xf00) >> 8) > Gpwrdelta)
t3 = ((value & 0xf00) >> 8) - (Gpwrdelta);
else
t3 = 0;
if (((value & 0xf000) >> 12) > Gpwrdelta)
t4 = ((value & 0xf000) >> 12) - (Gpwrdelta);
else
t4 = 0;
}
Gdata = t1 + (t2 << 4) + (t3 << 8) + (t4 << 12);
RT28xx_EEPROM_READ16(pAd,
EEPROM_TXPOWER_BYRATE_20MHZ_2_4G + i * 4 +
2, value);
if (bApwrdeltaMinus == FALSE) {
t1 = (value & 0xf) + (Apwrdelta);
if (t1 > 0xf)
t1 = 0xf;
t2 = ((value & 0xf0) >> 4) + (Apwrdelta);
if (t2 > 0xf)
t2 = 0xf;
t3 = ((value & 0xf00) >> 8) + (Apwrdelta);
if (t3 > 0xf)
t3 = 0xf;
t4 = ((value & 0xf000) >> 12) + (Apwrdelta);
if (t4 > 0xf)
t4 = 0xf;
} else {
if ((value & 0xf) > Apwrdelta)
t1 = (value & 0xf) - (Apwrdelta);
else
t1 = 0;
if (((value & 0xf0) >> 4) > Apwrdelta)
t2 = ((value & 0xf0) >> 4) - (Apwrdelta);
else
t2 = 0;
if (((value & 0xf00) >> 8) > Apwrdelta)
t3 = ((value & 0xf00) >> 8) - (Apwrdelta);
else
t3 = 0;
if (((value & 0xf000) >> 12) > Apwrdelta)
t4 = ((value & 0xf000) >> 12) - (Apwrdelta);
else
t4 = 0;
}
Adata |= ((t1 << 16) + (t2 << 20) + (t3 << 24) + (t4 << 28));
if (bGpwrdeltaMinus == FALSE) {
t1 = (value & 0xf) + (Gpwrdelta);
if (t1 > 0xf)
t1 = 0xf;
t2 = ((value & 0xf0) >> 4) + (Gpwrdelta);
if (t2 > 0xf)
t2 = 0xf;
t3 = ((value & 0xf00) >> 8) + (Gpwrdelta);
if (t3 > 0xf)
t3 = 0xf;
t4 = ((value & 0xf000) >> 12) + (Gpwrdelta);
if (t4 > 0xf)
t4 = 0xf;
} else {
if ((value & 0xf) > Gpwrdelta)
t1 = (value & 0xf) - (Gpwrdelta);
else
t1 = 0;
if (((value & 0xf0) >> 4) > Gpwrdelta)
t2 = ((value & 0xf0) >> 4) - (Gpwrdelta);
else
t2 = 0;
if (((value & 0xf00) >> 8) > Gpwrdelta)
t3 = ((value & 0xf00) >> 8) - (Gpwrdelta);
else
t3 = 0;
if (((value & 0xf000) >> 12) > Gpwrdelta)
t4 = ((value & 0xf000) >> 12) - (Gpwrdelta);
else
t4 = 0;
}
Gdata |= ((t1 << 16) + (t2 << 20) + (t3 << 24) + (t4 << 28));
data |= (value << 16);
/* For 20M/40M Power Delta issue */
pAd->Tx20MPwrCfgABand[i] = data;
pAd->Tx20MPwrCfgGBand[i] = data;
pAd->Tx40MPwrCfgABand[i] = Adata;
pAd->Tx40MPwrCfgGBand[i] = Gdata;
if (data != 0xffffffff)
RTMP_IO_WRITE32(pAd, TX_PWR_CFG_0 + i * 4, data);
DBGPRINT_RAW(RT_DEBUG_TRACE,
("20MHz BW, 2.4G band-%lx, Adata = %lx, Gdata = %lx \n",
data, Adata, Gdata));
}
}
/*
========================================================================
Routine Description:
Read initial channel power parameters from EEPROM
Arguments:
Adapter Pointer to our adapter
Return Value:
None
IRQL = PASSIVE_LEVEL
Note:
========================================================================
*/
void RTMPReadChannelPwr(struct rt_rtmp_adapter *pAd)
{
u8 i, choffset;
EEPROM_TX_PWR_STRUC Power;
EEPROM_TX_PWR_STRUC Power2;
/* Read Tx power value for all channels */
/* Value from 1 - 0x7f. Default value is 24. */
/* Power value : 2.4G 0x00 (0) ~ 0x1F (31) */
/* : 5.5G 0xF9 (-7) ~ 0x0F (15) */
/* 0. 11b/g, ch1 - ch 14 */
for (i = 0; i < 7; i++) {
RT28xx_EEPROM_READ16(pAd, EEPROM_G_TX_PWR_OFFSET + i * 2,
Power.word);
RT28xx_EEPROM_READ16(pAd, EEPROM_G_TX2_PWR_OFFSET + i * 2,
Power2.word);
pAd->TxPower[i * 2].Channel = i * 2 + 1;
pAd->TxPower[i * 2 + 1].Channel = i * 2 + 2;
if ((Power.field.Byte0 > 31) || (Power.field.Byte0 < 0))
pAd->TxPower[i * 2].Power = DEFAULT_RF_TX_POWER;
else
pAd->TxPower[i * 2].Power = Power.field.Byte0;
if ((Power.field.Byte1 > 31) || (Power.field.Byte1 < 0))
pAd->TxPower[i * 2 + 1].Power = DEFAULT_RF_TX_POWER;
else
pAd->TxPower[i * 2 + 1].Power = Power.field.Byte1;
if ((Power2.field.Byte0 > 31) || (Power2.field.Byte0 < 0))
pAd->TxPower[i * 2].Power2 = DEFAULT_RF_TX_POWER;
else
pAd->TxPower[i * 2].Power2 = Power2.field.Byte0;
if ((Power2.field.Byte1 > 31) || (Power2.field.Byte1 < 0))
pAd->TxPower[i * 2 + 1].Power2 = DEFAULT_RF_TX_POWER;
else
pAd->TxPower[i * 2 + 1].Power2 = Power2.field.Byte1;
}
/* 1. U-NII lower/middle band: 36, 38, 40; 44, 46, 48; 52, 54, 56; 60, 62, 64 (including central frequency in BW 40MHz) */
/* 1.1 Fill up channel */
choffset = 14;
for (i = 0; i < 4; i++) {
pAd->TxPower[3 * i + choffset + 0].Channel = 36 + i * 8 + 0;
pAd->TxPower[3 * i + choffset + 0].Power = DEFAULT_RF_TX_POWER;
pAd->TxPower[3 * i + choffset + 0].Power2 = DEFAULT_RF_TX_POWER;
pAd->TxPower[3 * i + choffset + 1].Channel = 36 + i * 8 + 2;
pAd->TxPower[3 * i + choffset + 1].Power = DEFAULT_RF_TX_POWER;
pAd->TxPower[3 * i + choffset + 1].Power2 = DEFAULT_RF_TX_POWER;
pAd->TxPower[3 * i + choffset + 2].Channel = 36 + i * 8 + 4;
pAd->TxPower[3 * i + choffset + 2].Power = DEFAULT_RF_TX_POWER;
pAd->TxPower[3 * i + choffset + 2].Power2 = DEFAULT_RF_TX_POWER;
}
/* 1.2 Fill up power */
for (i = 0; i < 6; i++) {
RT28xx_EEPROM_READ16(pAd, EEPROM_A_TX_PWR_OFFSET + i * 2,
Power.word);
RT28xx_EEPROM_READ16(pAd, EEPROM_A_TX2_PWR_OFFSET + i * 2,
Power2.word);
if ((Power.field.Byte0 < 16) && (Power.field.Byte0 >= -7))
pAd->TxPower[i * 2 + choffset + 0].Power =
Power.field.Byte0;
if ((Power.field.Byte1 < 16) && (Power.field.Byte1 >= -7))
pAd->TxPower[i * 2 + choffset + 1].Power =
Power.field.Byte1;
if ((Power2.field.Byte0 < 16) && (Power2.field.Byte0 >= -7))
pAd->TxPower[i * 2 + choffset + 0].Power2 =
Power2.field.Byte0;
if ((Power2.field.Byte1 < 16) && (Power2.field.Byte1 >= -7))
pAd->TxPower[i * 2 + choffset + 1].Power2 =
Power2.field.Byte1;
}
/* 2. HipperLAN 2 100, 102 ,104; 108, 110, 112; 116, 118, 120; 124, 126, 128; 132, 134, 136; 140 (including central frequency in BW 40MHz) */
/* 2.1 Fill up channel */
choffset = 14 + 12;
for (i = 0; i < 5; i++) {
pAd->TxPower[3 * i + choffset + 0].Channel = 100 + i * 8 + 0;
pAd->TxPower[3 * i + choffset + 0].Power = DEFAULT_RF_TX_POWER;
pAd->TxPower[3 * i + choffset + 0].Power2 = DEFAULT_RF_TX_POWER;
pAd->TxPower[3 * i + choffset + 1].Channel = 100 + i * 8 + 2;
pAd->TxPower[3 * i + choffset + 1].Power = DEFAULT_RF_TX_POWER;
pAd->TxPower[3 * i + choffset + 1].Power2 = DEFAULT_RF_TX_POWER;
pAd->TxPower[3 * i + choffset + 2].Channel = 100 + i * 8 + 4;
pAd->TxPower[3 * i + choffset + 2].Power = DEFAULT_RF_TX_POWER;
pAd->TxPower[3 * i + choffset + 2].Power2 = DEFAULT_RF_TX_POWER;
}
pAd->TxPower[3 * 5 + choffset + 0].Channel = 140;
pAd->TxPower[3 * 5 + choffset + 0].Power = DEFAULT_RF_TX_POWER;
pAd->TxPower[3 * 5 + choffset + 0].Power2 = DEFAULT_RF_TX_POWER;
/* 2.2 Fill up power */
for (i = 0; i < 8; i++) {
RT28xx_EEPROM_READ16(pAd,
EEPROM_A_TX_PWR_OFFSET + (choffset - 14) +
i * 2, Power.word);
RT28xx_EEPROM_READ16(pAd,
EEPROM_A_TX2_PWR_OFFSET + (choffset - 14) +
i * 2, Power2.word);
if ((Power.field.Byte0 < 16) && (Power.field.Byte0 >= -7))
pAd->TxPower[i * 2 + choffset + 0].Power =
Power.field.Byte0;
if ((Power.field.Byte1 < 16) && (Power.field.Byte1 >= -7))
pAd->TxPower[i * 2 + choffset + 1].Power =
Power.field.Byte1;
if ((Power2.field.Byte0 < 16) && (Power2.field.Byte0 >= -7))
pAd->TxPower[i * 2 + choffset + 0].Power2 =
Power2.field.Byte0;
if ((Power2.field.Byte1 < 16) && (Power2.field.Byte1 >= -7))
pAd->TxPower[i * 2 + choffset + 1].Power2 =
Power2.field.Byte1;
}
/* 3. U-NII upper band: 149, 151, 153; 157, 159, 161; 165, 167, 169; 171, 173 (including central frequency in BW 40MHz) */
/* 3.1 Fill up channel */
choffset = 14 + 12 + 16;
/*for (i = 0; i < 2; i++) */
for (i = 0; i < 3; i++) {
pAd->TxPower[3 * i + choffset + 0].Channel = 149 + i * 8 + 0;
pAd->TxPower[3 * i + choffset + 0].Power = DEFAULT_RF_TX_POWER;
pAd->TxPower[3 * i + choffset + 0].Power2 = DEFAULT_RF_TX_POWER;
pAd->TxPower[3 * i + choffset + 1].Channel = 149 + i * 8 + 2;
pAd->TxPower[3 * i + choffset + 1].Power = DEFAULT_RF_TX_POWER;
pAd->TxPower[3 * i + choffset + 1].Power2 = DEFAULT_RF_TX_POWER;
pAd->TxPower[3 * i + choffset + 2].Channel = 149 + i * 8 + 4;
pAd->TxPower[3 * i + choffset + 2].Power = DEFAULT_RF_TX_POWER;
pAd->TxPower[3 * i + choffset + 2].Power2 = DEFAULT_RF_TX_POWER;
}
pAd->TxPower[3 * 3 + choffset + 0].Channel = 171;
pAd->TxPower[3 * 3 + choffset + 0].Power = DEFAULT_RF_TX_POWER;
pAd->TxPower[3 * 3 + choffset + 0].Power2 = DEFAULT_RF_TX_POWER;
pAd->TxPower[3 * 3 + choffset + 1].Channel = 173;
pAd->TxPower[3 * 3 + choffset + 1].Power = DEFAULT_RF_TX_POWER;
pAd->TxPower[3 * 3 + choffset + 1].Power2 = DEFAULT_RF_TX_POWER;
/* 3.2 Fill up power */
/*for (i = 0; i < 4; i++) */
for (i = 0; i < 6; i++) {
RT28xx_EEPROM_READ16(pAd,
EEPROM_A_TX_PWR_OFFSET + (choffset - 14) +
i * 2, Power.word);
RT28xx_EEPROM_READ16(pAd,
EEPROM_A_TX2_PWR_OFFSET + (choffset - 14) +
i * 2, Power2.word);
if ((Power.field.Byte0 < 16) && (Power.field.Byte0 >= -7))
pAd->TxPower[i * 2 + choffset + 0].Power =
Power.field.Byte0;
if ((Power.field.Byte1 < 16) && (Power.field.Byte1 >= -7))
pAd->TxPower[i * 2 + choffset + 1].Power =
Power.field.Byte1;
if ((Power2.field.Byte0 < 16) && (Power2.field.Byte0 >= -7))
pAd->TxPower[i * 2 + choffset + 0].Power2 =
Power2.field.Byte0;
if ((Power2.field.Byte1 < 16) && (Power2.field.Byte1 >= -7))
pAd->TxPower[i * 2 + choffset + 1].Power2 =
Power2.field.Byte1;
}
/* 4. Print and Debug */
/*choffset = 14 + 12 + 16 + 7; */
choffset = 14 + 12 + 16 + 11;
}
/*
========================================================================
Routine Description:
Read the following from the registry
1. All the parameters
2. NetworkAddres
Arguments:
Adapter Pointer to our adapter
WrapperConfigurationContext For use by NdisOpenConfiguration
Return Value:
NDIS_STATUS_SUCCESS
NDIS_STATUS_FAILURE
NDIS_STATUS_RESOURCES
IRQL = PASSIVE_LEVEL
Note:
========================================================================
*/
int NICReadRegParameters(struct rt_rtmp_adapter *pAd,
void *WrapperConfigurationContext)
{
int Status = NDIS_STATUS_SUCCESS;
DBGPRINT_S(Status, ("<-- NICReadRegParameters, Status=%x\n", Status));
return Status;
}
/*
========================================================================
Routine Description:
Read initial parameters from EEPROM
Arguments:
Adapter Pointer to our adapter
Return Value:
None
IRQL = PASSIVE_LEVEL
Note:
========================================================================
*/
void NICReadEEPROMParameters(struct rt_rtmp_adapter *pAd, u8 *mac_addr)
{
u32 data = 0;
u16 i, value, value2;
u8 TmpPhy;
EEPROM_TX_PWR_STRUC Power;
EEPROM_VERSION_STRUC Version;
EEPROM_ANTENNA_STRUC Antenna;
EEPROM_NIC_CONFIG2_STRUC NicConfig2;
DBGPRINT(RT_DEBUG_TRACE, ("--> NICReadEEPROMParameters\n"));
if (pAd->chipOps.eeinit)
pAd->chipOps.eeinit(pAd);
/* Init EEPROM Address Number, before access EEPROM; if 93c46, EEPROMAddressNum=6, else if 93c66, EEPROMAddressNum=8 */
RTMP_IO_READ32(pAd, E2PROM_CSR, &data);
DBGPRINT(RT_DEBUG_TRACE, ("--> E2PROM_CSR = 0x%x\n", data));
if ((data & 0x30) == 0)
pAd->EEPROMAddressNum = 6; /* 93C46 */
else if ((data & 0x30) == 0x10)
pAd->EEPROMAddressNum = 8; /* 93C66 */
else
pAd->EEPROMAddressNum = 8; /* 93C86 */
DBGPRINT(RT_DEBUG_TRACE,
("--> EEPROMAddressNum = %d\n", pAd->EEPROMAddressNum));
/* RT2860 MAC no longer auto load MAC address from E2PROM. Driver has to intialize */
/* MAC address registers according to E2PROM setting */
if (mac_addr == NULL ||
strlen((char *)mac_addr) != 17 ||
mac_addr[2] != ':' || mac_addr[5] != ':' || mac_addr[8] != ':' ||
mac_addr[11] != ':' || mac_addr[14] != ':') {
u16 Addr01, Addr23, Addr45;
RT28xx_EEPROM_READ16(pAd, 0x04, Addr01);
RT28xx_EEPROM_READ16(pAd, 0x06, Addr23);
RT28xx_EEPROM_READ16(pAd, 0x08, Addr45);
pAd->PermanentAddress[0] = (u8)(Addr01 & 0xff);
pAd->PermanentAddress[1] = (u8)(Addr01 >> 8);
pAd->PermanentAddress[2] = (u8)(Addr23 & 0xff);
pAd->PermanentAddress[3] = (u8)(Addr23 >> 8);
pAd->PermanentAddress[4] = (u8)(Addr45 & 0xff);
pAd->PermanentAddress[5] = (u8)(Addr45 >> 8);
DBGPRINT(RT_DEBUG_TRACE,
("Initialize MAC Address from E2PROM \n"));
} else {
int j;
char *macptr;
macptr = (char *)mac_addr;
for (j = 0; j < MAC_ADDR_LEN; j++) {
AtoH(macptr, &pAd->PermanentAddress[j], 1);
macptr = macptr + 3;
}
DBGPRINT(RT_DEBUG_TRACE,
("Initialize MAC Address from module parameter \n"));
}
{
/*more conveninet to test mbssid, so ap's bssid &0xf1 */
if (pAd->PermanentAddress[0] == 0xff)
pAd->PermanentAddress[0] = RandomByte(pAd) & 0xf8;
/*if (pAd->PermanentAddress[5] == 0xff) */
/* pAd->PermanentAddress[5] = RandomByte(pAd)&0xf8; */
DBGPRINT_RAW(RT_DEBUG_TRACE,
("E2PROM MAC: =%02x:%02x:%02x:%02x:%02x:%02x\n",
pAd->PermanentAddress[0],
pAd->PermanentAddress[1],
pAd->PermanentAddress[2],
pAd->PermanentAddress[3],
pAd->PermanentAddress[4],
pAd->PermanentAddress[5]));
if (pAd->bLocalAdminMAC == FALSE) {
MAC_DW0_STRUC csr2;
MAC_DW1_STRUC csr3;
COPY_MAC_ADDR(pAd->CurrentAddress,
pAd->PermanentAddress);
csr2.field.Byte0 = pAd->CurrentAddress[0];
csr2.field.Byte1 = pAd->CurrentAddress[1];
csr2.field.Byte2 = pAd->CurrentAddress[2];
csr2.field.Byte3 = pAd->CurrentAddress[3];
RTMP_IO_WRITE32(pAd, MAC_ADDR_DW0, csr2.word);
csr3.word = 0;
csr3.field.Byte4 = pAd->CurrentAddress[4];
csr3.field.Byte5 = pAd->CurrentAddress[5];
csr3.field.U2MeMask = 0xff;
RTMP_IO_WRITE32(pAd, MAC_ADDR_DW1, csr3.word);
DBGPRINT_RAW(RT_DEBUG_TRACE,
("E2PROM MAC: =%02x:%02x:%02x:%02x:%02x:%02x\n",
PRINT_MAC(pAd->PermanentAddress)));
}
}
/* if not return early. cause fail at emulation. */
/* Init the channel number for TX channel power */
RTMPReadChannelPwr(pAd);
/* if E2PROM version mismatch with driver's expectation, then skip */
/* all subsequent E2RPOM retieval and set a system error bit to notify GUI */
RT28xx_EEPROM_READ16(pAd, EEPROM_VERSION_OFFSET, Version.word);
pAd->EepromVersion =
Version.field.Version + Version.field.FaeReleaseNumber * 256;
DBGPRINT(RT_DEBUG_TRACE,
("E2PROM: Version = %d, FAE release #%d\n",
Version.field.Version, Version.field.FaeReleaseNumber));
if (Version.field.Version > VALID_EEPROM_VERSION) {
DBGPRINT_ERR(("E2PROM: WRONG VERSION 0x%x, should be %d\n",
Version.field.Version, VALID_EEPROM_VERSION));
/*pAd->SystemErrorBitmap |= 0x00000001;
// hard-code default value when no proper E2PROM installed
pAd->bAutoTxAgcA = FALSE;
pAd->bAutoTxAgcG = FALSE;
// Default the channel power
for (i = 0; i < MAX_NUM_OF_CHANNELS; i++)
pAd->TxPower[i].Power = DEFAULT_RF_TX_POWER;
// Default the channel power
for (i = 0; i < MAX_NUM_OF_11JCHANNELS; i++)
pAd->TxPower11J[i].Power = DEFAULT_RF_TX_POWER;
for(i = 0; i < NUM_EEPROM_BBP_PARMS; i++)
pAd->EEPROMDefaultValue[i] = 0xffff;
return; */
}
/* Read BBP default value from EEPROM and store to array(EEPROMDefaultValue) in pAd */
RT28xx_EEPROM_READ16(pAd, EEPROM_NIC1_OFFSET, value);
pAd->EEPROMDefaultValue[0] = value;
RT28xx_EEPROM_READ16(pAd, EEPROM_NIC2_OFFSET, value);
pAd->EEPROMDefaultValue[1] = value;
RT28xx_EEPROM_READ16(pAd, 0x38, value); /* Country Region */
pAd->EEPROMDefaultValue[2] = value;
for (i = 0; i < 8; i++) {
RT28xx_EEPROM_READ16(pAd, EEPROM_BBP_BASE_OFFSET + i * 2,
value);
pAd->EEPROMDefaultValue[i + 3] = value;
}
/* We have to parse NIC configuration 0 at here. */
/* If TSSI did not have preloaded value, it should reset the TxAutoAgc to false */
/* Therefore, we have to read TxAutoAgc control beforehand. */
/* Read Tx AGC control bit */
Antenna.word = pAd->EEPROMDefaultValue[0];
if (Antenna.word == 0xFFFF) {
#ifdef RT30xx
if (IS_RT3090(pAd) || IS_RT3390(pAd)) {
Antenna.word = 0;
Antenna.field.RfIcType = RFIC_3020;
Antenna.field.TxPath = 1;
Antenna.field.RxPath = 1;
} else
#endif /* RT30xx // */
{
Antenna.word = 0;
Antenna.field.RfIcType = RFIC_2820;
Antenna.field.TxPath = 1;
Antenna.field.RxPath = 2;
DBGPRINT(RT_DEBUG_WARN,
("E2PROM error, hard code as 0x%04x\n",
Antenna.word));
}
}
/* Choose the desired Tx&Rx stream. */
if ((pAd->CommonCfg.TxStream == 0)
|| (pAd->CommonCfg.TxStream > Antenna.field.TxPath))
pAd->CommonCfg.TxStream = Antenna.field.TxPath;
if ((pAd->CommonCfg.RxStream == 0)
|| (pAd->CommonCfg.RxStream > Antenna.field.RxPath)) {
pAd->CommonCfg.RxStream = Antenna.field.RxPath;
if ((pAd->MACVersion < RALINK_2883_VERSION) &&
(pAd->CommonCfg.RxStream > 2)) {
/* only 2 Rx streams for RT2860 series */
pAd->CommonCfg.RxStream = 2;
}
}
/* 3*3 */
/* read value from EEPROM and set them to CSR174 ~ 177 in chain0 ~ chain2 */
/* yet implement */
for (i = 0; i < 3; i++) {
}
NicConfig2.word = pAd->EEPROMDefaultValue[1];
{
if ((NicConfig2.word & 0x00ff) == 0xff) {
NicConfig2.word &= 0xff00;
}
if ((NicConfig2.word >> 8) == 0xff) {
NicConfig2.word &= 0x00ff;
}
}
if (NicConfig2.field.DynamicTxAgcControl == 1)
pAd->bAutoTxAgcA = pAd->bAutoTxAgcG = TRUE;
else
pAd->bAutoTxAgcA = pAd->bAutoTxAgcG = FALSE;
DBGPRINT_RAW(RT_DEBUG_TRACE,
("NICReadEEPROMParameters: RxPath = %d, TxPath = %d\n",
Antenna.field.RxPath, Antenna.field.TxPath));
/* Save the antenna for future use */
pAd->Antenna.word = Antenna.word;
/* Set the RfICType here, then we can initialize RFIC related operation callbacks */
pAd->Mlme.RealRxPath = (u8)Antenna.field.RxPath;
pAd->RfIcType = (u8)Antenna.field.RfIcType;
#ifdef RTMP_RF_RW_SUPPORT
RtmpChipOpsRFHook(pAd);
#endif /* RTMP_RF_RW_SUPPORT // */
#ifdef RTMP_MAC_PCI
sprintf((char *)pAd->nickname, "RT2860STA");
#endif /* RTMP_MAC_PCI // */
/* */
/* Reset PhyMode if we don't support 802.11a */
/* Only RFIC_2850 & RFIC_2750 support 802.11a */
/* */
if ((Antenna.field.RfIcType != RFIC_2850)
&& (Antenna.field.RfIcType != RFIC_2750)
&& (Antenna.field.RfIcType != RFIC_3052)) {
if ((pAd->CommonCfg.PhyMode == PHY_11ABG_MIXED) ||
(pAd->CommonCfg.PhyMode == PHY_11A))
pAd->CommonCfg.PhyMode = PHY_11BG_MIXED;
else if ((pAd->CommonCfg.PhyMode == PHY_11ABGN_MIXED) ||
(pAd->CommonCfg.PhyMode == PHY_11AN_MIXED) ||
(pAd->CommonCfg.PhyMode == PHY_11AGN_MIXED) ||
(pAd->CommonCfg.PhyMode == PHY_11N_5G))
pAd->CommonCfg.PhyMode = PHY_11BGN_MIXED;
}
/* Read TSSI reference and TSSI boundary for temperature compensation. This is ugly */
/* 0. 11b/g */
{
/* these are tempature reference value (0x00 ~ 0xFE)
ex: 0x00 0x15 0x25 0x45 0x88 0xA0 0xB5 0xD0 0xF0
TssiPlusBoundaryG [4] [3] [2] [1] [0] (smaller) +
TssiMinusBoundaryG[0] [1] [2] [3] [4] (larger) */
RT28xx_EEPROM_READ16(pAd, 0x6E, Power.word);
pAd->TssiMinusBoundaryG[4] = Power.field.Byte0;
pAd->TssiMinusBoundaryG[3] = Power.field.Byte1;
RT28xx_EEPROM_READ16(pAd, 0x70, Power.word);
pAd->TssiMinusBoundaryG[2] = Power.field.Byte0;
pAd->TssiMinusBoundaryG[1] = Power.field.Byte1;
RT28xx_EEPROM_READ16(pAd, 0x72, Power.word);
pAd->TssiRefG = Power.field.Byte0; /* reference value [0] */
pAd->TssiPlusBoundaryG[1] = Power.field.Byte1;
RT28xx_EEPROM_READ16(pAd, 0x74, Power.word);
pAd->TssiPlusBoundaryG[2] = Power.field.Byte0;
pAd->TssiPlusBoundaryG[3] = Power.field.Byte1;
RT28xx_EEPROM_READ16(pAd, 0x76, Power.word);
pAd->TssiPlusBoundaryG[4] = Power.field.Byte0;
pAd->TxAgcStepG = Power.field.Byte1;
pAd->TxAgcCompensateG = 0;
pAd->TssiMinusBoundaryG[0] = pAd->TssiRefG;
pAd->TssiPlusBoundaryG[0] = pAd->TssiRefG;
/* Disable TxAgc if the based value is not right */
if (pAd->TssiRefG == 0xff)
pAd->bAutoTxAgcG = FALSE;
DBGPRINT(RT_DEBUG_TRACE,
("E2PROM: G Tssi[-4 .. +4] = %d %d %d %d - %d -%d %d %d %d, step=%d, tuning=%d\n",
pAd->TssiMinusBoundaryG[4],
pAd->TssiMinusBoundaryG[3],
pAd->TssiMinusBoundaryG[2],
pAd->TssiMinusBoundaryG[1], pAd->TssiRefG,
pAd->TssiPlusBoundaryG[1], pAd->TssiPlusBoundaryG[2],
pAd->TssiPlusBoundaryG[3], pAd->TssiPlusBoundaryG[4],
pAd->TxAgcStepG, pAd->bAutoTxAgcG));
}
/* 1. 11a */
{
RT28xx_EEPROM_READ16(pAd, 0xD4, Power.word);
pAd->TssiMinusBoundaryA[4] = Power.field.Byte0;
pAd->TssiMinusBoundaryA[3] = Power.field.Byte1;
RT28xx_EEPROM_READ16(pAd, 0xD6, Power.word);
pAd->TssiMinusBoundaryA[2] = Power.field.Byte0;
pAd->TssiMinusBoundaryA[1] = Power.field.Byte1;
RT28xx_EEPROM_READ16(pAd, 0xD8, Power.word);
pAd->TssiRefA = Power.field.Byte0;
pAd->TssiPlusBoundaryA[1] = Power.field.Byte1;
RT28xx_EEPROM_READ16(pAd, 0xDA, Power.word);
pAd->TssiPlusBoundaryA[2] = Power.field.Byte0;
pAd->TssiPlusBoundaryA[3] = Power.field.Byte1;
RT28xx_EEPROM_READ16(pAd, 0xDC, Power.word);
pAd->TssiPlusBoundaryA[4] = Power.field.Byte0;
pAd->TxAgcStepA = Power.field.Byte1;
pAd->TxAgcCompensateA = 0;
pAd->TssiMinusBoundaryA[0] = pAd->TssiRefA;
pAd->TssiPlusBoundaryA[0] = pAd->TssiRefA;
/* Disable TxAgc if the based value is not right */
if (pAd->TssiRefA == 0xff)
pAd->bAutoTxAgcA = FALSE;
DBGPRINT(RT_DEBUG_TRACE,
("E2PROM: A Tssi[-4 .. +4] = %d %d %d %d - %d -%d %d %d %d, step=%d, tuning=%d\n",
pAd->TssiMinusBoundaryA[4],
pAd->TssiMinusBoundaryA[3],
pAd->TssiMinusBoundaryA[2],
pAd->TssiMinusBoundaryA[1], pAd->TssiRefA,
pAd->TssiPlusBoundaryA[1], pAd->TssiPlusBoundaryA[2],
pAd->TssiPlusBoundaryA[3], pAd->TssiPlusBoundaryA[4],
pAd->TxAgcStepA, pAd->bAutoTxAgcA));
}
pAd->BbpRssiToDbmDelta = 0x0;
/* Read frequency offset setting for RF */
RT28xx_EEPROM_READ16(pAd, EEPROM_FREQ_OFFSET, value);
if ((value & 0x00FF) != 0x00FF)
pAd->RfFreqOffset = (unsigned long)(value & 0x00FF);
else
pAd->RfFreqOffset = 0;
DBGPRINT(RT_DEBUG_TRACE,
("E2PROM: RF FreqOffset=0x%lx \n", pAd->RfFreqOffset));
/*CountryRegion byte offset (38h) */
value = pAd->EEPROMDefaultValue[2] >> 8; /* 2.4G band */
value2 = pAd->EEPROMDefaultValue[2] & 0x00FF; /* 5G band */
if ((value <= REGION_MAXIMUM_BG_BAND)
&& (value2 <= REGION_MAXIMUM_A_BAND)) {
pAd->CommonCfg.CountryRegion = ((u8)value) | 0x80;
pAd->CommonCfg.CountryRegionForABand = ((u8)value2) | 0x80;
TmpPhy = pAd->CommonCfg.PhyMode;
pAd->CommonCfg.PhyMode = 0xff;
RTMPSetPhyMode(pAd, TmpPhy);
SetCommonHT(pAd);
}
/* */
/* Get RSSI Offset on EEPROM 0x9Ah & 0x9Ch. */
/* The valid value are (-10 ~ 10) */
/* */
RT28xx_EEPROM_READ16(pAd, EEPROM_RSSI_BG_OFFSET, value);
pAd->BGRssiOffset0 = value & 0x00ff;
pAd->BGRssiOffset1 = (value >> 8);
RT28xx_EEPROM_READ16(pAd, EEPROM_RSSI_BG_OFFSET + 2, value);
pAd->BGRssiOffset2 = value & 0x00ff;
pAd->ALNAGain1 = (value >> 8);
RT28xx_EEPROM_READ16(pAd, EEPROM_LNA_OFFSET, value);
pAd->BLNAGain = value & 0x00ff;
pAd->ALNAGain0 = (value >> 8);
/* Validate 11b/g RSSI_0 offset. */
if ((pAd->BGRssiOffset0 < -10) || (pAd->BGRssiOffset0 > 10))
pAd->BGRssiOffset0 = 0;
/* Validate 11b/g RSSI_1 offset. */
if ((pAd->BGRssiOffset1 < -10) || (pAd->BGRssiOffset1 > 10))
pAd->BGRssiOffset1 = 0;
/* Validate 11b/g RSSI_2 offset. */
if ((pAd->BGRssiOffset2 < -10) || (pAd->BGRssiOffset2 > 10))
pAd->BGRssiOffset2 = 0;
RT28xx_EEPROM_READ16(pAd, EEPROM_RSSI_A_OFFSET, value);
pAd->ARssiOffset0 = value & 0x00ff;
pAd->ARssiOffset1 = (value >> 8);
RT28xx_EEPROM_READ16(pAd, (EEPROM_RSSI_A_OFFSET + 2), value);
pAd->ARssiOffset2 = value & 0x00ff;
pAd->ALNAGain2 = (value >> 8);
if (((u8)pAd->ALNAGain1 == 0xFF) || (pAd->ALNAGain1 == 0x00))
pAd->ALNAGain1 = pAd->ALNAGain0;
if (((u8)pAd->ALNAGain2 == 0xFF) || (pAd->ALNAGain2 == 0x00))
pAd->ALNAGain2 = pAd->ALNAGain0;
/* Validate 11a RSSI_0 offset. */
if ((pAd->ARssiOffset0 < -10) || (pAd->ARssiOffset0 > 10))
pAd->ARssiOffset0 = 0;
/* Validate 11a RSSI_1 offset. */
if ((pAd->ARssiOffset1 < -10) || (pAd->ARssiOffset1 > 10))
pAd->ARssiOffset1 = 0;
/*Validate 11a RSSI_2 offset. */
if ((pAd->ARssiOffset2 < -10) || (pAd->ARssiOffset2 > 10))
pAd->ARssiOffset2 = 0;
#ifdef RT30xx
/* */
/* Get TX mixer gain setting */
/* 0xff are invalid value */
/* Note: RT30xX default value is 0x00 and will program to RF_R17 only when this value is not zero. */
/* RT359X default value is 0x02 */
/* */
if (IS_RT30xx(pAd) || IS_RT3572(pAd)) {
RT28xx_EEPROM_READ16(pAd, EEPROM_TXMIXER_GAIN_2_4G, value);
pAd->TxMixerGain24G = 0;
value &= 0x00ff;
if (value != 0xff) {
value &= 0x07;
pAd->TxMixerGain24G = (u8)value;
}
}
#endif /* RT30xx // */
/* */
/* Get LED Setting. */
/* */
RT28xx_EEPROM_READ16(pAd, 0x3a, value);
pAd->LedCntl.word = (value >> 8);
RT28xx_EEPROM_READ16(pAd, EEPROM_LED1_OFFSET, value);
pAd->Led1 = value;
RT28xx_EEPROM_READ16(pAd, EEPROM_LED2_OFFSET, value);
pAd->Led2 = value;
RT28xx_EEPROM_READ16(pAd, EEPROM_LED3_OFFSET, value);
pAd->Led3 = value;
RTMPReadTxPwrPerRate(pAd);
#ifdef RT30xx
#ifdef RTMP_EFUSE_SUPPORT
RtmpEfuseSupportCheck(pAd);
#endif /* RTMP_EFUSE_SUPPORT // */
#endif /* RT30xx // */
DBGPRINT(RT_DEBUG_TRACE, ("<-- NICReadEEPROMParameters\n"));
}
/*
========================================================================
Routine Description:
Set default value from EEPROM
Arguments:
Adapter Pointer to our adapter
Return Value:
None
IRQL = PASSIVE_LEVEL
Note:
========================================================================
*/
void NICInitAsicFromEEPROM(struct rt_rtmp_adapter *pAd)
{
u32 data = 0;
u8 BBPR1 = 0;
u16 i;
/* EEPROM_ANTENNA_STRUC Antenna; */
EEPROM_NIC_CONFIG2_STRUC NicConfig2;
u8 BBPR3 = 0;
DBGPRINT(RT_DEBUG_TRACE, ("--> NICInitAsicFromEEPROM\n"));
for (i = 3; i < NUM_EEPROM_BBP_PARMS; i++) {
u8 BbpRegIdx, BbpValue;
if ((pAd->EEPROMDefaultValue[i] != 0xFFFF)
&& (pAd->EEPROMDefaultValue[i] != 0)) {
BbpRegIdx = (u8)(pAd->EEPROMDefaultValue[i] >> 8);
BbpValue = (u8)(pAd->EEPROMDefaultValue[i] & 0xff);
RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BbpRegIdx, BbpValue);
}
}
NicConfig2.word = pAd->EEPROMDefaultValue[1];
{
if ((NicConfig2.word & 0x00ff) == 0xff) {
NicConfig2.word &= 0xff00;
}
if ((NicConfig2.word >> 8) == 0xff) {
NicConfig2.word &= 0x00ff;
}
}
/* Save the antenna for future use */
pAd->NicConfig2.word = NicConfig2.word;
#ifdef RT30xx
/* set default antenna as main */
if (pAd->RfIcType == RFIC_3020)
AsicSetRxAnt(pAd, pAd->RxAnt.Pair1PrimaryRxAnt);
#endif /* RT30xx // */
/* */
/* Send LED Setting to MCU. */
/* */
if (pAd->LedCntl.word == 0xFF) {
pAd->LedCntl.word = 0x01;
pAd->Led1 = 0x5555;
pAd->Led2 = 0x2221;
#ifdef RTMP_MAC_PCI
pAd->Led3 = 0xA9F8;
#endif /* RTMP_MAC_PCI // */
#ifdef RTMP_MAC_USB
pAd->Led3 = 0x5627;
#endif /* RTMP_MAC_USB // */
}
AsicSendCommandToMcu(pAd, 0x52, 0xff, (u8)pAd->Led1,
(u8)(pAd->Led1 >> 8));
AsicSendCommandToMcu(pAd, 0x53, 0xff, (u8)pAd->Led2,
(u8)(pAd->Led2 >> 8));
AsicSendCommandToMcu(pAd, 0x54, 0xff, (u8)pAd->Led3,
(u8)(pAd->Led3 >> 8));
AsicSendCommandToMcu(pAd, 0x51, 0xff, 0, pAd->LedCntl.field.Polarity);
pAd->LedIndicatorStrength = 0xFF;
RTMPSetSignalLED(pAd, -100); /* Force signal strength Led to be turned off, before link up */
{
/* Read Hardware controlled Radio state enable bit */
if (NicConfig2.field.HardwareRadioControl == 1) {
pAd->StaCfg.bHardwareRadio = TRUE;
/* Read GPIO pin2 as Hardware controlled radio state */
RTMP_IO_READ32(pAd, GPIO_CTRL_CFG, &data);
if ((data & 0x04) == 0) {
pAd->StaCfg.bHwRadio = FALSE;
pAd->StaCfg.bRadio = FALSE;
/* RTMP_IO_WRITE32(pAd, PWR_PIN_CFG, 0x00001818); */
RTMP_SET_FLAG(pAd, fRTMP_ADAPTER_RADIO_OFF);
}
} else
pAd->StaCfg.bHardwareRadio = FALSE;
if (pAd->StaCfg.bRadio == FALSE) {
RTMPSetLED(pAd, LED_RADIO_OFF);
} else {
RTMPSetLED(pAd, LED_RADIO_ON);
#ifdef RTMP_MAC_PCI
#ifdef RT3090
AsicSendCommandToMcu(pAd, 0x30, PowerRadioOffCID, 0xff,
0x02);
AsicCheckCommanOk(pAd, PowerRadioOffCID);
#endif /* RT3090 // */
#ifndef RT3090
AsicSendCommandToMcu(pAd, 0x30, 0xff, 0xff, 0x02);
#endif /* RT3090 // */
AsicSendCommandToMcu(pAd, 0x31, PowerWakeCID, 0x00,
0x00);
/* 2-1. wait command ok. */
AsicCheckCommanOk(pAd, PowerWakeCID);
#endif /* RTMP_MAC_PCI // */
}
}
#ifdef RTMP_MAC_PCI
#ifdef RT30xx
if (IS_RT3090(pAd) || IS_RT3572(pAd) || IS_RT3390(pAd)) {
struct rt_rtmp_chip_op *pChipOps = &pAd->chipOps;
if (pChipOps->AsicReverseRfFromSleepMode)
pChipOps->AsicReverseRfFromSleepMode(pAd);
}
/* 3090 MCU Wakeup command needs more time to be stable. */
/* Before stable, don't issue other MCU command to prevent from firmware error. */
if ((IS_RT3090(pAd) || IS_RT3572(pAd) || IS_RT3390(pAd))
&& IS_VERSION_AFTER_F(pAd)
&& (pAd->StaCfg.PSControl.field.rt30xxPowerMode == 3)
&& (pAd->StaCfg.PSControl.field.EnableNewPS == TRUE)) {
DBGPRINT(RT_DEBUG_TRACE, ("%s, release Mcu Lock\n", __func__));
RTMP_SEM_LOCK(&pAd->McuCmdLock);
pAd->brt30xxBanMcuCmd = FALSE;
RTMP_SEM_UNLOCK(&pAd->McuCmdLock);
}
#endif /* RT30xx // */
#endif /* RTMP_MAC_PCI // */
/* Turn off patching for cardbus controller */
if (NicConfig2.field.CardbusAcceleration == 1) {
/* pAd->bTest1 = TRUE; */
}
if (NicConfig2.field.DynamicTxAgcControl == 1)
pAd->bAutoTxAgcA = pAd->bAutoTxAgcG = TRUE;
else
pAd->bAutoTxAgcA = pAd->bAutoTxAgcG = FALSE;
/* */
/* Since BBP has been progamed, to make sure BBP setting will be */
/* upate inside of AsicAntennaSelect, so reset to UNKNOWN_BAND! */
/* */
pAd->CommonCfg.BandState = UNKNOWN_BAND;
RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R3, &BBPR3);
BBPR3 &= (~0x18);
if (pAd->Antenna.field.RxPath == 3) {
BBPR3 |= (0x10);
} else if (pAd->Antenna.field.RxPath == 2) {
BBPR3 |= (0x8);
} else if (pAd->Antenna.field.RxPath == 1) {
BBPR3 |= (0x0);
}
RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R3, BBPR3);
{
/* Handle the difference when 1T */
RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R1, &BBPR1);
if (pAd->Antenna.field.TxPath == 1) {
BBPR1 &= (~0x18);
}
RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R1, BBPR1);
DBGPRINT(RT_DEBUG_TRACE,
("Use Hw Radio Control Pin=%d; if used Pin=%d;\n",
pAd->CommonCfg.bHardwareRadio,
pAd->CommonCfg.bHardwareRadio));
}
#ifdef RTMP_MAC_USB
#ifdef RT30xx
/* update registers from EEPROM for RT3071 or later(3572/3592). */
if (IS_RT3090(pAd) || IS_RT3572(pAd) || IS_RT3390(pAd)) {
u8 RegIdx, RegValue;
u16 value;
/* after RT3071, write BBP from EEPROM 0xF0 to 0x102 */
for (i = 0xF0; i <= 0x102; i = i + 2) {
value = 0xFFFF;
RT28xx_EEPROM_READ16(pAd, i, value);
if ((value != 0xFFFF) && (value != 0)) {
RegIdx = (u8)(value >> 8);
RegValue = (u8)(value & 0xff);
RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, RegIdx,
RegValue);
DBGPRINT(RT_DEBUG_TRACE,
("Update BBP Registers from EEPROM(0x%0x), BBP(0x%x) = 0x%x\n",
i, RegIdx, RegValue));
}
}
/* after RT3071, write RF from EEPROM 0x104 to 0x116 */
for (i = 0x104; i <= 0x116; i = i + 2) {
value = 0xFFFF;
RT28xx_EEPROM_READ16(pAd, i, value);
if ((value != 0xFFFF) && (value != 0)) {
RegIdx = (u8)(value >> 8);
RegValue = (u8)(value & 0xff);
RT30xxWriteRFRegister(pAd, RegIdx, RegValue);
DBGPRINT(RT_DEBUG_TRACE,
("Update RF Registers from EEPROM0x%x), BBP(0x%x) = 0x%x\n",
i, RegIdx, RegValue));
}
}
}
#endif /* RT30xx // */
#endif /* RTMP_MAC_USB // */
DBGPRINT(RT_DEBUG_TRACE,
("TxPath = %d, RxPath = %d, RFIC=%d, Polar+LED mode=%x\n",
pAd->Antenna.field.TxPath, pAd->Antenna.field.RxPath,
pAd->RfIcType, pAd->LedCntl.word));
DBGPRINT(RT_DEBUG_TRACE, ("<-- NICInitAsicFromEEPROM\n"));
}
/*
========================================================================
Routine Description:
Initialize NIC hardware
Arguments:
Adapter Pointer to our adapter
Return Value:
None
IRQL = PASSIVE_LEVEL
Note:
========================================================================
*/
int NICInitializeAdapter(struct rt_rtmp_adapter *pAd, IN BOOLEAN bHardReset)
{
int Status = NDIS_STATUS_SUCCESS;
WPDMA_GLO_CFG_STRUC GloCfg;
#ifdef RTMP_MAC_PCI
u32 Value;
DELAY_INT_CFG_STRUC IntCfg;
#endif /* RTMP_MAC_PCI // */
/* INT_MASK_CSR_STRUC IntMask; */
unsigned long i = 0, j = 0;
AC_TXOP_CSR0_STRUC csr0;
DBGPRINT(RT_DEBUG_TRACE, ("--> NICInitializeAdapter\n"));
/* 3. Set DMA global configuration except TX_DMA_EN and RX_DMA_EN bits: */
retry:
i = 0;
do {
RTMP_IO_READ32(pAd, WPDMA_GLO_CFG, &GloCfg.word);
if ((GloCfg.field.TxDMABusy == 0)
&& (GloCfg.field.RxDMABusy == 0))
break;
RTMPusecDelay(1000);
i++;
} while (i < 100);
DBGPRINT(RT_DEBUG_TRACE,
("<== DMA offset 0x208 = 0x%x\n", GloCfg.word));
GloCfg.word &= 0xff0;
GloCfg.field.EnTXWriteBackDDONE = 1;
RTMP_IO_WRITE32(pAd, WPDMA_GLO_CFG, GloCfg.word);
/* Record HW Beacon offset */
pAd->BeaconOffset[0] = HW_BEACON_BASE0;
pAd->BeaconOffset[1] = HW_BEACON_BASE1;
pAd->BeaconOffset[2] = HW_BEACON_BASE2;
pAd->BeaconOffset[3] = HW_BEACON_BASE3;
pAd->BeaconOffset[4] = HW_BEACON_BASE4;
pAd->BeaconOffset[5] = HW_BEACON_BASE5;
pAd->BeaconOffset[6] = HW_BEACON_BASE6;
pAd->BeaconOffset[7] = HW_BEACON_BASE7;
/* */
/* write all shared Ring's base address into ASIC */
/* */
/* asic simulation sequence put this ahead before loading firmware. */
/* pbf hardware reset */
#ifdef RTMP_MAC_PCI
RTMP_IO_WRITE32(pAd, WPDMA_RST_IDX, 0x1003f); /* 0x10000 for reset rx, 0x3f resets all 6 tx rings. */
RTMP_IO_WRITE32(pAd, PBF_SYS_CTRL, 0xe1f);
RTMP_IO_WRITE32(pAd, PBF_SYS_CTRL, 0xe00);
#endif /* RTMP_MAC_PCI // */
/* Initialze ASIC for TX & Rx operation */
if (NICInitializeAsic(pAd, bHardReset) != NDIS_STATUS_SUCCESS) {
if (j++ == 0) {
NICLoadFirmware(pAd);
goto retry;
}
return NDIS_STATUS_FAILURE;
}
#ifdef RTMP_MAC_PCI
/* Write AC_BK base address register */
Value =
RTMP_GetPhysicalAddressLow(pAd->TxRing[QID_AC_BK].Cell[0].AllocPa);
RTMP_IO_WRITE32(pAd, TX_BASE_PTR1, Value);
DBGPRINT(RT_DEBUG_TRACE, ("--> TX_BASE_PTR1 : 0x%x\n", Value));
/* Write AC_BE base address register */
Value =
RTMP_GetPhysicalAddressLow(pAd->TxRing[QID_AC_BE].Cell[0].AllocPa);
RTMP_IO_WRITE32(pAd, TX_BASE_PTR0, Value);
DBGPRINT(RT_DEBUG_TRACE, ("--> TX_BASE_PTR0 : 0x%x\n", Value));
/* Write AC_VI base address register */
Value =
RTMP_GetPhysicalAddressLow(pAd->TxRing[QID_AC_VI].Cell[0].AllocPa);
RTMP_IO_WRITE32(pAd, TX_BASE_PTR2, Value);
DBGPRINT(RT_DEBUG_TRACE, ("--> TX_BASE_PTR2 : 0x%x\n", Value));
/* Write AC_VO base address register */
Value =
RTMP_GetPhysicalAddressLow(pAd->TxRing[QID_AC_VO].Cell[0].AllocPa);
RTMP_IO_WRITE32(pAd, TX_BASE_PTR3, Value);
DBGPRINT(RT_DEBUG_TRACE, ("--> TX_BASE_PTR3 : 0x%x\n", Value));
/* Write MGMT_BASE_CSR register */
Value = RTMP_GetPhysicalAddressLow(pAd->MgmtRing.Cell[0].AllocPa);
RTMP_IO_WRITE32(pAd, TX_BASE_PTR5, Value);
DBGPRINT(RT_DEBUG_TRACE, ("--> TX_BASE_PTR5 : 0x%x\n", Value));
/* Write RX_BASE_CSR register */
Value = RTMP_GetPhysicalAddressLow(pAd->RxRing.Cell[0].AllocPa);
RTMP_IO_WRITE32(pAd, RX_BASE_PTR, Value);
DBGPRINT(RT_DEBUG_TRACE, ("--> RX_BASE_PTR : 0x%x\n", Value));
/* Init RX Ring index pointer */
pAd->RxRing.RxSwReadIdx = 0;
pAd->RxRing.RxCpuIdx = RX_RING_SIZE - 1;
RTMP_IO_WRITE32(pAd, RX_CRX_IDX, pAd->RxRing.RxCpuIdx);
/* Init TX rings index pointer */
{
for (i = 0; i < NUM_OF_TX_RING; i++) {
pAd->TxRing[i].TxSwFreeIdx = 0;
pAd->TxRing[i].TxCpuIdx = 0;
RTMP_IO_WRITE32(pAd, (TX_CTX_IDX0 + i * 0x10),
pAd->TxRing[i].TxCpuIdx);
}
}
/* init MGMT ring index pointer */
pAd->MgmtRing.TxSwFreeIdx = 0;
pAd->MgmtRing.TxCpuIdx = 0;
RTMP_IO_WRITE32(pAd, TX_MGMTCTX_IDX, pAd->MgmtRing.TxCpuIdx);
/* */
/* set each Ring's SIZE into ASIC. Descriptor Size is fixed by design. */
/* */
/* Write TX_RING_CSR0 register */
Value = TX_RING_SIZE;
RTMP_IO_WRITE32(pAd, TX_MAX_CNT0, Value);
RTMP_IO_WRITE32(pAd, TX_MAX_CNT1, Value);
RTMP_IO_WRITE32(pAd, TX_MAX_CNT2, Value);
RTMP_IO_WRITE32(pAd, TX_MAX_CNT3, Value);
RTMP_IO_WRITE32(pAd, TX_MAX_CNT4, Value);
Value = MGMT_RING_SIZE;
RTMP_IO_WRITE32(pAd, TX_MGMTMAX_CNT, Value);
/* Write RX_RING_CSR register */
Value = RX_RING_SIZE;
RTMP_IO_WRITE32(pAd, RX_MAX_CNT, Value);
#endif /* RTMP_MAC_PCI // */
/* WMM parameter */
csr0.word = 0;
RTMP_IO_WRITE32(pAd, WMM_TXOP0_CFG, csr0.word);
if (pAd->CommonCfg.PhyMode == PHY_11B) {
csr0.field.Ac0Txop = 192; /* AC_VI: 192*32us ~= 6ms */
csr0.field.Ac1Txop = 96; /* AC_VO: 96*32us ~= 3ms */
} else {
csr0.field.Ac0Txop = 96; /* AC_VI: 96*32us ~= 3ms */
csr0.field.Ac1Txop = 48; /* AC_VO: 48*32us ~= 1.5ms */
}
RTMP_IO_WRITE32(pAd, WMM_TXOP1_CFG, csr0.word);
#ifdef RTMP_MAC_PCI
/* 3. Set DMA global configuration except TX_DMA_EN and RX_DMA_EN bits: */
i = 0;
do {
RTMP_IO_READ32(pAd, WPDMA_GLO_CFG, &GloCfg.word);
if ((GloCfg.field.TxDMABusy == 0)
&& (GloCfg.field.RxDMABusy == 0))
break;
RTMPusecDelay(1000);
i++;
} while (i < 100);
GloCfg.word &= 0xff0;
GloCfg.field.EnTXWriteBackDDONE = 1;
RTMP_IO_WRITE32(pAd, WPDMA_GLO_CFG, GloCfg.word);
IntCfg.word = 0;
RTMP_IO_WRITE32(pAd, DELAY_INT_CFG, IntCfg.word);
#endif /* RTMP_MAC_PCI // */
/* reset action */
/* Load firmware */
/* Status = NICLoadFirmware(pAd); */
DBGPRINT(RT_DEBUG_TRACE, ("<-- NICInitializeAdapter\n"));
return Status;
}
/*
========================================================================
Routine Description:
Initialize ASIC
Arguments:
Adapter Pointer to our adapter
Return Value:
None
IRQL = PASSIVE_LEVEL
Note:
========================================================================
*/
int NICInitializeAsic(struct rt_rtmp_adapter *pAd, IN BOOLEAN bHardReset)
{
unsigned long Index = 0;
u8 R0 = 0xff;
u32 MacCsr12 = 0, Counter = 0;
#ifdef RTMP_MAC_USB
u32 MacCsr0 = 0;
int Status;
u8 Value = 0xff;
#endif /* RTMP_MAC_USB // */
#ifdef RT30xx
u8 bbpreg = 0;
u8 RFValue = 0;
#endif /* RT30xx // */
u16 KeyIdx;
int i, apidx;
DBGPRINT(RT_DEBUG_TRACE, ("--> NICInitializeAsic\n"));
#ifdef RTMP_MAC_PCI
RTMP_IO_WRITE32(pAd, PWR_PIN_CFG, 0x3); /* To fix driver disable/enable hang issue when radio off */
if (bHardReset == TRUE) {
RTMP_IO_WRITE32(pAd, MAC_SYS_CTRL, 0x3);
} else
RTMP_IO_WRITE32(pAd, MAC_SYS_CTRL, 0x1);
RTMP_IO_WRITE32(pAd, MAC_SYS_CTRL, 0x0);
/* Initialize MAC register to default value */
for (Index = 0; Index < NUM_MAC_REG_PARMS; Index++) {
RTMP_IO_WRITE32(pAd, MACRegTable[Index].Register,
MACRegTable[Index].Value);
}
{
for (Index = 0; Index < NUM_STA_MAC_REG_PARMS; Index++) {
RTMP_IO_WRITE32(pAd, STAMACRegTable[Index].Register,
STAMACRegTable[Index].Value);
}
}
#endif /* RTMP_MAC_PCI // */
#ifdef RTMP_MAC_USB
/* */
/* Make sure MAC gets ready after NICLoadFirmware(). */
/* */
Index = 0;
/*To avoid hang-on issue when interface up in kernel 2.4, */
/*we use a local variable "MacCsr0" instead of using "pAd->MACVersion" directly. */
do {
RTMP_IO_READ32(pAd, MAC_CSR0, &MacCsr0);
if ((MacCsr0 != 0x00) && (MacCsr0 != 0xFFFFFFFF))
break;
RTMPusecDelay(10);
} while (Index++ < 100);
pAd->MACVersion = MacCsr0;
DBGPRINT(RT_DEBUG_TRACE,
("MAC_CSR0 [ Ver:Rev=0x%08x]\n", pAd->MACVersion));
/* turn on bit13 (set to zero) after rt2860D. This is to solve high-current issue. */
RTMP_IO_READ32(pAd, PBF_SYS_CTRL, &MacCsr12);
MacCsr12 &= (~0x2000);
RTMP_IO_WRITE32(pAd, PBF_SYS_CTRL, MacCsr12);
RTMP_IO_WRITE32(pAd, MAC_SYS_CTRL, 0x3);
RTMP_IO_WRITE32(pAd, USB_DMA_CFG, 0x0);
Status = RTUSBVenderReset(pAd);
RTMP_IO_WRITE32(pAd, MAC_SYS_CTRL, 0x0);
/* Initialize MAC register to default value */
for (Index = 0; Index < NUM_MAC_REG_PARMS; Index++) {
#ifdef RT30xx
if ((MACRegTable[Index].Register == TX_SW_CFG0)
&& (IS_RT3070(pAd) || IS_RT3071(pAd) || IS_RT3572(pAd)
|| IS_RT3090(pAd) || IS_RT3390(pAd))) {
MACRegTable[Index].Value = 0x00000400;
}
#endif /* RT30xx // */
RTMP_IO_WRITE32(pAd, (u16)MACRegTable[Index].Register,
MACRegTable[Index].Value);
}
{
for (Index = 0; Index < NUM_STA_MAC_REG_PARMS; Index++) {
RTMP_IO_WRITE32(pAd,
(u16)STAMACRegTable[Index].Register,
STAMACRegTable[Index].Value);
}
}
#endif /* RTMP_MAC_USB // */
#ifdef RT30xx
/* Initialize RT3070 serial MAC registers which is different from RT2870 serial */
if (IS_RT3090(pAd) || IS_RT3572(pAd) || IS_RT3390(pAd)) {
RTMP_IO_WRITE32(pAd, TX_SW_CFG1, 0);
/* RT3071 version E has fixed this issue */
if ((pAd->MACVersion & 0xffff) < 0x0211) {
if (pAd->NicConfig2.field.DACTestBit == 1) {
RTMP_IO_WRITE32(pAd, TX_SW_CFG2, 0x2C); /* To fix throughput drop drastically */
} else {
RTMP_IO_WRITE32(pAd, TX_SW_CFG2, 0x0F); /* To fix throughput drop drastically */
}
} else {
RTMP_IO_WRITE32(pAd, TX_SW_CFG2, 0x0);
}
} else if (IS_RT3070(pAd)) {
if (((pAd->MACVersion & 0xffff) < 0x0201)) {
RTMP_IO_WRITE32(pAd, TX_SW_CFG1, 0);
RTMP_IO_WRITE32(pAd, TX_SW_CFG2, 0x2C); /* To fix throughput drop drastically */
} else {
RTMP_IO_WRITE32(pAd, TX_SW_CFG2, 0);
}
}
#endif /* RT30xx // */
/* */
/* Before program BBP, we need to wait BBP/RF get wake up. */
/* */
Index = 0;
do {
RTMP_IO_READ32(pAd, MAC_STATUS_CFG, &MacCsr12);
if ((MacCsr12 & 0x03) == 0) /* if BB.RF is stable */
break;
DBGPRINT(RT_DEBUG_TRACE,
("Check MAC_STATUS_CFG = Busy = %x\n", MacCsr12));
RTMPusecDelay(1000);
} while (Index++ < 100);
/* The commands to firmware should be after these commands, these commands will init firmware */
/* PCI and USB are not the same because PCI driver needs to wait for PCI bus ready */
RTMP_IO_WRITE32(pAd, H2M_BBP_AGENT, 0); /* initialize BBP R/W access agent */
RTMP_IO_WRITE32(pAd, H2M_MAILBOX_CSR, 0);
#ifdef RT3090
/*2008/11/28:KH add to fix the dead rf frequency offset bug<-- */
AsicSendCommandToMcu(pAd, 0x72, 0, 0, 0);
/*2008/11/28:KH add to fix the dead rf frequency offset bug--> */
#endif /* RT3090 // */
RTMPusecDelay(1000);
/* Read BBP register, make sure BBP is up and running before write new data */
Index = 0;
do {
RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R0, &R0);
DBGPRINT(RT_DEBUG_TRACE, ("BBP version = %x\n", R0));
} while ((++Index < 20) && ((R0 == 0xff) || (R0 == 0x00)));
/*ASSERT(Index < 20); //this will cause BSOD on Check-build driver */
if ((R0 == 0xff) || (R0 == 0x00))
return NDIS_STATUS_FAILURE;
/* Initialize BBP register to default value */
for (Index = 0; Index < NUM_BBP_REG_PARMS; Index++) {
RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBPRegTable[Index].Register,
BBPRegTable[Index].Value);
}
#ifdef RTMP_MAC_PCI
/* TODO: shiang, check MACVersion, currently, rbus-based chip use this. */
if (pAd->MACVersion == 0x28720200) {
/*u8 value; */
unsigned long value2;
/*disable MLD by Bruce 20080704 */
/*BBP_IO_READ8_BY_REG_ID(pAd, BBP_R105, &value); */
/*BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R105, value | 4); */
/*Maximum PSDU length from 16K to 32K bytes */
RTMP_IO_READ32(pAd, MAX_LEN_CFG, &value2);
value2 &= ~(0x3 << 12);
value2 |= (0x2 << 12);
RTMP_IO_WRITE32(pAd, MAX_LEN_CFG, value2);
}
#endif /* RTMP_MAC_PCI // */
/* for rt2860E and after, init BBP_R84 with 0x19. This is for extension channel overlapping IOT. */
/* RT3090 should not program BBP R84 to 0x19, otherwise TX will block. */
/*3070/71/72,3090,3090A( are included in RT30xx),3572,3390 */
if (((pAd->MACVersion & 0xffff) != 0x0101)
&& !(IS_RT30xx(pAd) || IS_RT3572(pAd) || IS_RT3390(pAd)))
RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R84, 0x19);
#ifdef RT30xx
/* add by johnli, RF power sequence setup */
if (IS_RT30xx(pAd) || IS_RT3572(pAd) || IS_RT3390(pAd)) { /*update for RT3070/71/72/90/91/92,3572,3390. */
RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R79, 0x13);
RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R80, 0x05);
RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R81, 0x33);
}
if (IS_RT3090(pAd) || IS_RT3390(pAd)) /* RT309x, RT3071/72 */
{
/* enable DC filter */
if ((pAd->MACVersion & 0xffff) >= 0x0211) {
RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R103, 0xc0);
}
/* improve power consumption */
RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R138, &bbpreg);
if (pAd->Antenna.field.TxPath == 1) {
/* turn off tx DAC_1 */
bbpreg = (bbpreg | 0x20);
}
if (pAd->Antenna.field.RxPath == 1) {
/* turn off tx ADC_1 */
bbpreg &= (~0x2);
}
RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R138, bbpreg);
/* improve power consumption in RT3071 Ver.E */
if ((pAd->MACVersion & 0xffff) >= 0x0211) {
RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R31, &bbpreg);
bbpreg &= (~0x3);
RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R31, bbpreg);
}
} else if (IS_RT3070(pAd)) {
if ((pAd->MACVersion & 0xffff) >= 0x0201) {
/* enable DC filter */
RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R103, 0xc0);
/* improve power consumption in RT3070 Ver.F */
RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R31, &bbpreg);
bbpreg &= (~0x3);
RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R31, bbpreg);
}
/* TX_LO1_en, RF R17 register Bit 3 to 0 */
RT30xxReadRFRegister(pAd, RF_R17, &RFValue);
RFValue &= (~0x08);
/* to fix rx long range issue */
if (pAd->NicConfig2.field.ExternalLNAForG == 0) {
RFValue |= 0x20;
}
/* set RF_R17_bit[2:0] equal to EEPROM setting at 0x48h */
if (pAd->TxMixerGain24G >= 1) {
RFValue &= (~0x7); /* clean bit [2:0] */
RFValue |= pAd->TxMixerGain24G;
}
RT30xxWriteRFRegister(pAd, RF_R17, RFValue);
}
/* end johnli */
#endif /* RT30xx // */
if (pAd->MACVersion == 0x28600100) {
RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R69, 0x16);
RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R73, 0x12);
}
if (pAd->MACVersion >= RALINK_2880E_VERSION && pAd->MACVersion < RALINK_3070_VERSION) /* 3*3 */
{
/* enlarge MAX_LEN_CFG */
u32 csr;
RTMP_IO_READ32(pAd, MAX_LEN_CFG, &csr);
csr &= 0xFFF;
csr |= 0x2000;
RTMP_IO_WRITE32(pAd, MAX_LEN_CFG, csr);
}
#ifdef RTMP_MAC_USB
{
u8 MAC_Value[] =
{ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0, 0 };
/*Initialize WCID table */
Value = 0xff;
for (Index = 0; Index < 254; Index++) {
RTUSBMultiWrite(pAd,
(u16)(MAC_WCID_BASE + Index * 8),
MAC_Value, 8);
}
}
#endif /* RTMP_MAC_USB // */
/* Add radio off control */
{
if (pAd->StaCfg.bRadio == FALSE) {
/* RTMP_IO_WRITE32(pAd, PWR_PIN_CFG, 0x00001818); */
RTMP_SET_FLAG(pAd, fRTMP_ADAPTER_RADIO_OFF);
DBGPRINT(RT_DEBUG_TRACE, ("Set Radio Off\n"));
}
}
/* Clear raw counters */
RTMP_IO_READ32(pAd, RX_STA_CNT0, &Counter);
RTMP_IO_READ32(pAd, RX_STA_CNT1, &Counter);
RTMP_IO_READ32(pAd, RX_STA_CNT2, &Counter);
RTMP_IO_READ32(pAd, TX_STA_CNT0, &Counter);
RTMP_IO_READ32(pAd, TX_STA_CNT1, &Counter);
RTMP_IO_READ32(pAd, TX_STA_CNT2, &Counter);
/* ASIC will keep garbage value after boot */
/* Clear all shared key table when initial */
/* This routine can be ignored in radio-ON/OFF operation. */
if (bHardReset) {
for (KeyIdx = 0; KeyIdx < 4; KeyIdx++) {
RTMP_IO_WRITE32(pAd, SHARED_KEY_MODE_BASE + 4 * KeyIdx,
0);
}
/* Clear all pairwise key table when initial */
for (KeyIdx = 0; KeyIdx < 256; KeyIdx++) {
RTMP_IO_WRITE32(pAd,
MAC_WCID_ATTRIBUTE_BASE +
(KeyIdx * HW_WCID_ATTRI_SIZE), 1);
}
}
/* assert HOST ready bit */
/* RTMP_IO_WRITE32(pAd, MAC_CSR1, 0x0); // 2004-09-14 asked by Mark */
/* RTMP_IO_WRITE32(pAd, MAC_CSR1, 0x4); */
/* It isn't necessary to clear this space when not hard reset. */
if (bHardReset == TRUE) {
/* clear all on-chip BEACON frame space */
for (apidx = 0; apidx < HW_BEACON_MAX_COUNT; apidx++) {
for (i = 0; i < HW_BEACON_OFFSET >> 2; i += 4)
RTMP_IO_WRITE32(pAd,
pAd->BeaconOffset[apidx] + i,
0x00);
}
}
#ifdef RTMP_MAC_USB
AsicDisableSync(pAd);
/* Clear raw counters */
RTMP_IO_READ32(pAd, RX_STA_CNT0, &Counter);
RTMP_IO_READ32(pAd, RX_STA_CNT1, &Counter);
RTMP_IO_READ32(pAd, RX_STA_CNT2, &Counter);
RTMP_IO_READ32(pAd, TX_STA_CNT0, &Counter);
RTMP_IO_READ32(pAd, TX_STA_CNT1, &Counter);
RTMP_IO_READ32(pAd, TX_STA_CNT2, &Counter);
/* Default PCI clock cycle per ms is different as default setting, which is based on PCI. */
RTMP_IO_READ32(pAd, USB_CYC_CFG, &Counter);
Counter &= 0xffffff00;
Counter |= 0x000001e;
RTMP_IO_WRITE32(pAd, USB_CYC_CFG, Counter);
#endif /* RTMP_MAC_USB // */
{
/* for rt2860E and after, init TXOP_CTRL_CFG with 0x583f. This is for extension channel overlapping IOT. */
if ((pAd->MACVersion & 0xffff) != 0x0101)
RTMP_IO_WRITE32(pAd, TXOP_CTRL_CFG, 0x583f);
}
DBGPRINT(RT_DEBUG_TRACE, ("<-- NICInitializeAsic\n"));
return NDIS_STATUS_SUCCESS;
}
/*
========================================================================
Routine Description:
Reset NIC Asics
Arguments:
Adapter Pointer to our adapter
Return Value:
None
IRQL = PASSIVE_LEVEL
Note:
Reset NIC to initial state AS IS system boot up time.
========================================================================
*/
void NICIssueReset(struct rt_rtmp_adapter *pAd)
{
u32 Value = 0;
DBGPRINT(RT_DEBUG_TRACE, ("--> NICIssueReset\n"));
/* Abort Tx, prevent ASIC from writing to Host memory */
/*RTMP_IO_WRITE32(pAd, TX_CNTL_CSR, 0x001f0000); */
/* Disable Rx, register value supposed will remain after reset */
RTMP_IO_READ32(pAd, MAC_SYS_CTRL, &Value);
Value &= (0xfffffff3);
RTMP_IO_WRITE32(pAd, MAC_SYS_CTRL, Value);
/* Issue reset and clear from reset state */
RTMP_IO_WRITE32(pAd, MAC_SYS_CTRL, 0x03); /* 2004-09-17 change from 0x01 */
RTMP_IO_WRITE32(pAd, MAC_SYS_CTRL, 0x00);
DBGPRINT(RT_DEBUG_TRACE, ("<-- NICIssueReset\n"));
}
/*
========================================================================
Routine Description:
Check ASIC registers and find any reason the system might hang
Arguments:
Adapter Pointer to our adapter
Return Value:
None
IRQL = DISPATCH_LEVEL
========================================================================
*/
BOOLEAN NICCheckForHang(struct rt_rtmp_adapter *pAd)
{
return (FALSE);
}
void NICUpdateFifoStaCounters(struct rt_rtmp_adapter *pAd)
{
TX_STA_FIFO_STRUC StaFifo;
struct rt_mac_table_entry *pEntry;
u8 i = 0;
u8 pid = 0, wcid = 0;
char reTry;
u8 succMCS;
do {
RTMP_IO_READ32(pAd, TX_STA_FIFO, &StaFifo.word);
if (StaFifo.field.bValid == 0)
break;
wcid = (u8)StaFifo.field.wcid;
/* ignore NoACK and MGMT frame use 0xFF as WCID */
if ((StaFifo.field.TxAckRequired == 0)
|| (wcid >= MAX_LEN_OF_MAC_TABLE)) {
i++;
continue;
}
/* PID store Tx MCS Rate */
pid = (u8)StaFifo.field.PidType;
pEntry = &pAd->MacTab.Content[wcid];
pEntry->DebugFIFOCount++;
if (StaFifo.field.TxBF) /* 3*3 */
pEntry->TxBFCount++;
if (!StaFifo.field.TxSuccess) {
pEntry->FIFOCount++;
pEntry->OneSecTxFailCount++;
if (pEntry->FIFOCount >= 1) {
DBGPRINT(RT_DEBUG_TRACE, ("#"));
pEntry->NoBADataCountDown = 64;
if (pEntry->PsMode == PWR_ACTIVE) {
int tid;
for (tid = 0; tid < NUM_OF_TID; tid++) {
BAOriSessionTearDown(pAd,
pEntry->
Aid, tid,
FALSE,
FALSE);
}
/* Update the continuous transmission counter except PS mode */
pEntry->ContinueTxFailCnt++;
} else {
/* Clear the FIFOCount when sta in Power Save mode. Basically we assume */
/* this tx error happened due to sta just go to sleep. */
pEntry->FIFOCount = 0;
pEntry->ContinueTxFailCnt = 0;
}
/*pEntry->FIFOCount = 0; */
}
/*pEntry->bSendBAR = TRUE; */
} else {
if ((pEntry->PsMode != PWR_SAVE)
&& (pEntry->NoBADataCountDown > 0)) {
pEntry->NoBADataCountDown--;
if (pEntry->NoBADataCountDown == 0) {
DBGPRINT(RT_DEBUG_TRACE, ("@\n"));
}
}
pEntry->FIFOCount = 0;
pEntry->OneSecTxNoRetryOkCount++;
/* update NoDataIdleCount when sucessful send packet to STA. */
pEntry->NoDataIdleCount = 0;
pEntry->ContinueTxFailCnt = 0;
}
succMCS = StaFifo.field.SuccessRate & 0x7F;
reTry = pid - succMCS;
if (StaFifo.field.TxSuccess) {
pEntry->TXMCSExpected[pid]++;
if (pid == succMCS) {
pEntry->TXMCSSuccessful[pid]++;
} else {
pEntry->TXMCSAutoFallBack[pid][succMCS]++;
}
} else {
pEntry->TXMCSFailed[pid]++;
}
if (reTry > 0) {
if ((pid >= 12) && succMCS <= 7) {
reTry -= 4;
}
pEntry->OneSecTxRetryOkCount += reTry;
}
i++;
/* ASIC store 16 stack */
} while (i < (2 * TX_RING_SIZE));
}
/*
========================================================================
Routine Description:
Read statistical counters from hardware registers and record them
in software variables for later on query
Arguments:
pAd Pointer to our adapter
Return Value:
None
IRQL = DISPATCH_LEVEL
========================================================================
*/
void NICUpdateRawCounters(struct rt_rtmp_adapter *pAd)
{
u32 OldValue; /*, Value2; */
/*unsigned long PageSum, OneSecTransmitCount; */
/*unsigned long TxErrorRatio, Retry, Fail; */
RX_STA_CNT0_STRUC RxStaCnt0;
RX_STA_CNT1_STRUC RxStaCnt1;
RX_STA_CNT2_STRUC RxStaCnt2;
TX_STA_CNT0_STRUC TxStaCnt0;
TX_STA_CNT1_STRUC StaTx1;
TX_STA_CNT2_STRUC StaTx2;
TX_AGG_CNT_STRUC TxAggCnt;
TX_AGG_CNT0_STRUC TxAggCnt0;
TX_AGG_CNT1_STRUC TxAggCnt1;
TX_AGG_CNT2_STRUC TxAggCnt2;
TX_AGG_CNT3_STRUC TxAggCnt3;
TX_AGG_CNT4_STRUC TxAggCnt4;
TX_AGG_CNT5_STRUC TxAggCnt5;
TX_AGG_CNT6_STRUC TxAggCnt6;
TX_AGG_CNT7_STRUC TxAggCnt7;
struct rt_counter_ralink *pRalinkCounters;
pRalinkCounters = &pAd->RalinkCounters;
RTMP_IO_READ32(pAd, RX_STA_CNT0, &RxStaCnt0.word);
RTMP_IO_READ32(pAd, RX_STA_CNT2, &RxStaCnt2.word);
{
RTMP_IO_READ32(pAd, RX_STA_CNT1, &RxStaCnt1.word);
/* Update RX PLCP error counter */
pAd->PrivateInfo.PhyRxErrCnt += RxStaCnt1.field.PlcpErr;
/* Update False CCA counter */
pAd->RalinkCounters.OneSecFalseCCACnt +=
RxStaCnt1.field.FalseCca;
}
/* Update FCS counters */
OldValue = pAd->WlanCounters.FCSErrorCount.u.LowPart;
pAd->WlanCounters.FCSErrorCount.u.LowPart += (RxStaCnt0.field.CrcErr); /* >> 7); */
if (pAd->WlanCounters.FCSErrorCount.u.LowPart < OldValue)
pAd->WlanCounters.FCSErrorCount.u.HighPart++;
/* Add FCS error count to private counters */
pRalinkCounters->OneSecRxFcsErrCnt += RxStaCnt0.field.CrcErr;
OldValue = pRalinkCounters->RealFcsErrCount.u.LowPart;
pRalinkCounters->RealFcsErrCount.u.LowPart += RxStaCnt0.field.CrcErr;
if (pRalinkCounters->RealFcsErrCount.u.LowPart < OldValue)
pRalinkCounters->RealFcsErrCount.u.HighPart++;
/* Update Duplicate Rcv check */
pRalinkCounters->DuplicateRcv += RxStaCnt2.field.RxDupliCount;
pAd->WlanCounters.FrameDuplicateCount.u.LowPart +=
RxStaCnt2.field.RxDupliCount;
/* Update RX Overflow counter */
pAd->Counters8023.RxNoBuffer += (RxStaCnt2.field.RxFifoOverflowCount);
/*pAd->RalinkCounters.RxCount = 0; */
#ifdef RTMP_MAC_USB
if (pRalinkCounters->RxCount != pAd->watchDogRxCnt) {
pAd->watchDogRxCnt = pRalinkCounters->RxCount;
pAd->watchDogRxOverFlowCnt = 0;
} else {
if (RxStaCnt2.field.RxFifoOverflowCount)
pAd->watchDogRxOverFlowCnt++;
else
pAd->watchDogRxOverFlowCnt = 0;
}
#endif /* RTMP_MAC_USB // */
/*if (!OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_TX_RATE_SWITCH_ENABLED) || */
/* (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_TX_RATE_SWITCH_ENABLED) && (pAd->MacTab.Size != 1))) */
if (!pAd->bUpdateBcnCntDone) {
/* Update BEACON sent count */
RTMP_IO_READ32(pAd, TX_STA_CNT0, &TxStaCnt0.word);
RTMP_IO_READ32(pAd, TX_STA_CNT1, &StaTx1.word);
RTMP_IO_READ32(pAd, TX_STA_CNT2, &StaTx2.word);
pRalinkCounters->OneSecBeaconSentCnt +=
TxStaCnt0.field.TxBeaconCount;
pRalinkCounters->OneSecTxRetryOkCount +=
StaTx1.field.TxRetransmit;
pRalinkCounters->OneSecTxNoRetryOkCount +=
StaTx1.field.TxSuccess;
pRalinkCounters->OneSecTxFailCount +=
TxStaCnt0.field.TxFailCount;
pAd->WlanCounters.TransmittedFragmentCount.u.LowPart +=
StaTx1.field.TxSuccess;
pAd->WlanCounters.RetryCount.u.LowPart +=
StaTx1.field.TxRetransmit;
pAd->WlanCounters.FailedCount.u.LowPart +=
TxStaCnt0.field.TxFailCount;
}
/*if (pAd->bStaFifoTest == TRUE) */
{
RTMP_IO_READ32(pAd, TX_AGG_CNT, &TxAggCnt.word);
RTMP_IO_READ32(pAd, TX_AGG_CNT0, &TxAggCnt0.word);
RTMP_IO_READ32(pAd, TX_AGG_CNT1, &TxAggCnt1.word);
RTMP_IO_READ32(pAd, TX_AGG_CNT2, &TxAggCnt2.word);
RTMP_IO_READ32(pAd, TX_AGG_CNT3, &TxAggCnt3.word);
RTMP_IO_READ32(pAd, TX_AGG_CNT4, &TxAggCnt4.word);
RTMP_IO_READ32(pAd, TX_AGG_CNT5, &TxAggCnt5.word);
RTMP_IO_READ32(pAd, TX_AGG_CNT6, &TxAggCnt6.word);
RTMP_IO_READ32(pAd, TX_AGG_CNT7, &TxAggCnt7.word);
pRalinkCounters->TxAggCount += TxAggCnt.field.AggTxCount;
pRalinkCounters->TxNonAggCount += TxAggCnt.field.NonAggTxCount;
pRalinkCounters->TxAgg1MPDUCount +=
TxAggCnt0.field.AggSize1Count;
pRalinkCounters->TxAgg2MPDUCount +=
TxAggCnt0.field.AggSize2Count;
pRalinkCounters->TxAgg3MPDUCount +=
TxAggCnt1.field.AggSize3Count;
pRalinkCounters->TxAgg4MPDUCount +=
TxAggCnt1.field.AggSize4Count;
pRalinkCounters->TxAgg5MPDUCount +=
TxAggCnt2.field.AggSize5Count;
pRalinkCounters->TxAgg6MPDUCount +=
TxAggCnt2.field.AggSize6Count;
pRalinkCounters->TxAgg7MPDUCount +=
TxAggCnt3.field.AggSize7Count;
pRalinkCounters->TxAgg8MPDUCount +=
TxAggCnt3.field.AggSize8Count;
pRalinkCounters->TxAgg9MPDUCount +=
TxAggCnt4.field.AggSize9Count;
pRalinkCounters->TxAgg10MPDUCount +=
TxAggCnt4.field.AggSize10Count;
pRalinkCounters->TxAgg11MPDUCount +=
TxAggCnt5.field.AggSize11Count;
pRalinkCounters->TxAgg12MPDUCount +=
TxAggCnt5.field.AggSize12Count;
pRalinkCounters->TxAgg13MPDUCount +=
TxAggCnt6.field.AggSize13Count;
pRalinkCounters->TxAgg14MPDUCount +=
TxAggCnt6.field.AggSize14Count;
pRalinkCounters->TxAgg15MPDUCount +=
TxAggCnt7.field.AggSize15Count;
pRalinkCounters->TxAgg16MPDUCount +=
TxAggCnt7.field.AggSize16Count;
/* Calculate the transmitted A-MPDU count */
pRalinkCounters->TransmittedAMPDUCount.u.LowPart +=
TxAggCnt0.field.AggSize1Count;
pRalinkCounters->TransmittedAMPDUCount.u.LowPart +=
(TxAggCnt0.field.AggSize2Count / 2);
pRalinkCounters->TransmittedAMPDUCount.u.LowPart +=
(TxAggCnt1.field.AggSize3Count / 3);
pRalinkCounters->TransmittedAMPDUCount.u.LowPart +=
(TxAggCnt1.field.AggSize4Count / 4);
pRalinkCounters->TransmittedAMPDUCount.u.LowPart +=
(TxAggCnt2.field.AggSize5Count / 5);
pRalinkCounters->TransmittedAMPDUCount.u.LowPart +=
(TxAggCnt2.field.AggSize6Count / 6);
pRalinkCounters->TransmittedAMPDUCount.u.LowPart +=
(TxAggCnt3.field.AggSize7Count / 7);
pRalinkCounters->TransmittedAMPDUCount.u.LowPart +=
(TxAggCnt3.field.AggSize8Count / 8);
pRalinkCounters->TransmittedAMPDUCount.u.LowPart +=
(TxAggCnt4.field.AggSize9Count / 9);
pRalinkCounters->TransmittedAMPDUCount.u.LowPart +=
(TxAggCnt4.field.AggSize10Count / 10);
pRalinkCounters->TransmittedAMPDUCount.u.LowPart +=
(TxAggCnt5.field.AggSize11Count / 11);
pRalinkCounters->TransmittedAMPDUCount.u.LowPart +=
(TxAggCnt5.field.AggSize12Count / 12);
pRalinkCounters->TransmittedAMPDUCount.u.LowPart +=
(TxAggCnt6.field.AggSize13Count / 13);
pRalinkCounters->TransmittedAMPDUCount.u.LowPart +=
(TxAggCnt6.field.AggSize14Count / 14);
pRalinkCounters->TransmittedAMPDUCount.u.LowPart +=
(TxAggCnt7.field.AggSize15Count / 15);
pRalinkCounters->TransmittedAMPDUCount.u.LowPart +=
(TxAggCnt7.field.AggSize16Count / 16);
}
}
/*
========================================================================
Routine Description:
Reset NIC from error
Arguments:
Adapter Pointer to our adapter
Return Value:
None
IRQL = PASSIVE_LEVEL
Note:
Reset NIC from error state
========================================================================
*/
void NICResetFromError(struct rt_rtmp_adapter *pAd)
{
/* Reset BBP (according to alex, reset ASIC will force reset BBP */
/* Therefore, skip the reset BBP */
/* RTMP_IO_WRITE32(pAd, MAC_CSR1, 0x2); */
RTMP_IO_WRITE32(pAd, MAC_SYS_CTRL, 0x1);
/* Remove ASIC from reset state */
RTMP_IO_WRITE32(pAd, MAC_SYS_CTRL, 0x0);
NICInitializeAdapter(pAd, FALSE);
NICInitAsicFromEEPROM(pAd);
/* Switch to current channel, since during reset process, the connection should remains on. */
AsicSwitchChannel(pAd, pAd->CommonCfg.CentralChannel, FALSE);
AsicLockChannel(pAd, pAd->CommonCfg.CentralChannel);
}
int NICLoadFirmware(struct rt_rtmp_adapter *pAd)
{
int status = NDIS_STATUS_SUCCESS;
if (pAd->chipOps.loadFirmware)
status = pAd->chipOps.loadFirmware(pAd);
return status;
}
/*
========================================================================
Routine Description:
erase 8051 firmware image in MAC ASIC
Arguments:
Adapter Pointer to our adapter
IRQL = PASSIVE_LEVEL
========================================================================
*/
void NICEraseFirmware(struct rt_rtmp_adapter *pAd)
{
if (pAd->chipOps.eraseFirmware)
pAd->chipOps.eraseFirmware(pAd);
} /* End of NICEraseFirmware */
/*
========================================================================
Routine Description:
Load Tx rate switching parameters
Arguments:
Adapter Pointer to our adapter
Return Value:
NDIS_STATUS_SUCCESS firmware image load ok
NDIS_STATUS_FAILURE image not found
IRQL = PASSIVE_LEVEL
Rate Table Format:
1. (B0: Valid Item number) (B1:Initial item from zero)
2. Item Number(Dec) Mode(Hex) Current MCS(Dec) TrainUp(Dec) TrainDown(Dec)
========================================================================
*/
int NICLoadRateSwitchingParams(struct rt_rtmp_adapter *pAd)
{
return NDIS_STATUS_SUCCESS;
}
/*
========================================================================
Routine Description:
Compare two memory block
Arguments:
pSrc1 Pointer to first memory address
pSrc2 Pointer to second memory address
Return Value:
0: memory is equal
1: pSrc1 memory is larger
2: pSrc2 memory is larger
IRQL = DISPATCH_LEVEL
Note:
========================================================================
*/
unsigned long RTMPCompareMemory(void *pSrc1, void *pSrc2, unsigned long Length)
{
u8 *pMem1;
u8 *pMem2;
unsigned long Index = 0;
pMem1 = (u8 *)pSrc1;
pMem2 = (u8 *)pSrc2;
for (Index = 0; Index < Length; Index++) {
if (pMem1[Index] > pMem2[Index])
return (1);
else if (pMem1[Index] < pMem2[Index])
return (2);
}
/* Equal */
return (0);
}
/*
========================================================================
Routine Description:
Zero out memory block
Arguments:
pSrc1 Pointer to memory address
Length Size
Return Value:
None
IRQL = PASSIVE_LEVEL
IRQL = DISPATCH_LEVEL
Note:
========================================================================
*/
void RTMPZeroMemory(void *pSrc, unsigned long Length)
{
u8 *pMem;
unsigned long Index = 0;
pMem = (u8 *)pSrc;
for (Index = 0; Index < Length; Index++) {
pMem[Index] = 0x00;
}
}
/*
========================================================================
Routine Description:
Copy data from memory block 1 to memory block 2
Arguments:
pDest Pointer to destination memory address
pSrc Pointer to source memory address
Length Copy size
Return Value:
None
IRQL = PASSIVE_LEVEL
IRQL = DISPATCH_LEVEL
Note:
========================================================================
*/
void RTMPMoveMemory(void *pDest, void *pSrc, unsigned long Length)
{
u8 *pMem1;
u8 *pMem2;
u32 Index;
ASSERT((Length == 0) || (pDest && pSrc));
pMem1 = (u8 *)pDest;
pMem2 = (u8 *)pSrc;
for (Index = 0; Index < Length; Index++) {
pMem1[Index] = pMem2[Index];
}
}
/*
========================================================================
Routine Description:
Initialize port configuration structure
Arguments:
Adapter Pointer to our adapter
Return Value:
None
IRQL = PASSIVE_LEVEL
Note:
========================================================================
*/
void UserCfgInit(struct rt_rtmp_adapter *pAd)
{
u32 key_index, bss_index;
DBGPRINT(RT_DEBUG_TRACE, ("--> UserCfgInit\n"));
/* */
/* part I. intialize common configuration */
/* */
#ifdef RTMP_MAC_USB
pAd->BulkOutReq = 0;
pAd->BulkOutComplete = 0;
pAd->BulkOutCompleteOther = 0;
pAd->BulkOutCompleteCancel = 0;
pAd->BulkInReq = 0;
pAd->BulkInComplete = 0;
pAd->BulkInCompleteFail = 0;
/*pAd->QuickTimerP = 100; */
/*pAd->TurnAggrBulkInCount = 0; */
pAd->bUsbTxBulkAggre = 0;
/* init as unsed value to ensure driver will set to MCU once. */
pAd->LedIndicatorStrength = 0xFF;
pAd->CommonCfg.MaxPktOneTxBulk = 2;
pAd->CommonCfg.TxBulkFactor = 1;
pAd->CommonCfg.RxBulkFactor = 1;
pAd->CommonCfg.TxPower = 100; /*mW */
NdisZeroMemory(&pAd->CommonCfg.IOTestParm,
sizeof(pAd->CommonCfg.IOTestParm));
#endif /* RTMP_MAC_USB // */
for (key_index = 0; key_index < SHARE_KEY_NUM; key_index++) {
for (bss_index = 0; bss_index < MAX_MBSSID_NUM; bss_index++) {
pAd->SharedKey[bss_index][key_index].KeyLen = 0;
pAd->SharedKey[bss_index][key_index].CipherAlg =
CIPHER_NONE;
}
}
pAd->EepromAccess = FALSE;
pAd->Antenna.word = 0;
pAd->CommonCfg.BBPCurrentBW =