📄 zd1211.c
字号:
}
//================================================================
// Housekeeping Every 0.5 s
//================================================================
void zd1211_TxCalibration(struct zd1205_private *macp)
{
static u32 loop = 0;
static u16 TrackingLoop = 0;
static u32 accumulate = 0;
u8 setpoint;
u16 channel;
u32 average = 0;
u32 tmpvalue;
static u16 TrackingCnt = 0;
static u32 accumulate_OFDM = 0;
static u16 TrackingCnt_OFDM = 0;
u8 PreTxOFDMType = cTX_CCK;
loop++;
#if fTX_PWR_CTRL
if ((loop % 64) == 0){
if (macp->bTraceSetPoint){
LockPhyReg(&dot11Obj);
if (TrackingLoop == TRACKING_NUM) {
TrackingLoop = 0;
if (TrackingCnt && PURE_A_MODE != macp->cardSetting.MacMode ){
average = (u32) (accumulate / TrackingCnt);
channel = dot11Obj.Channel;
setpoint = macp->EepSetPoint[channel-1];
if (macp->EnableTxPwrCtrl) {
if (average < (u32) (setpoint - cPWR_CTRL_GUARD))
zd1205_IncreaseTxPower(macp, cTX_CCK);
else if (average > setpoint)
zd1205_DecreaseTxPower(macp, cTX_CCK);
}
accumulate = 0;
TrackingCnt = 0;
}
if (TrackingCnt_OFDM){
average = (u32) (accumulate_OFDM / TrackingCnt_OFDM);
channel = dot11Obj.Channel;
if(PURE_A_MODE != macp->cardSetting.MacMode) {
setpoint = macp->SetPointOFDM[macp->TxOFDMType - cTX_OFDM][channel - 1];
}
else if (PURE_A_MODE == macp->cardSetting.MacMode) {
u8 UselessInt;//Only for store return Integration value that we don't need
int ret;
ret = a_OSC_get_cal_int(
channel,
macp->cardSetting.LastSentTxRate ,
&UselessInt, &setpoint);
if(0 != ret) printk("a_OSC_get_cal_int can't found the channel\n");
}
//printk("Enter TrackingCnt_OFDM(CH:%d)(SET:%d)(avg:%d)\n",channel,setpoint,average);
if (macp->EnableTxPwrCtrl){
if (average < (u32) (setpoint - cPWR_CTRL_GUARD))
zd1205_IncreaseTxPower(macp, cTX_OFDM);
else if (average > setpoint)
zd1205_DecreaseTxPower(macp, cTX_OFDM);
}
accumulate_OFDM = 0;
TrackingCnt_OFDM = 0;
}
}
else {
TrackingLoop ++;
tmpvalue = zd_readl(rLED_CTRL);
if (tmpvalue & BIT_0){ // Continuous Tx
if (tmpvalue & BIT_2){ // Tx OFDM
macp->TxPwrOFDM ++;
macp->TxOFDMCnt = cTX_SENT_LEN + 1;
tmpvalue = zd_readl(ZD1205_CR132);
tmpvalue &= 0xFF;
macp->TxOFDMType = cTX_OFDM;
if (tmpvalue == 0xC)
macp->TxOFDMType = cTX_54M;
else if (tmpvalue == 0x8)
macp->TxOFDMType = cTX_48M;
}
else
macp->TxPwrCCK ++; // Tx CCK
}
if (macp->TxPwrCCK){ // New sent after last read
tmpvalue = zd_readl(ZD1205_CR58);
tmpvalue &= 0xFF;
accumulate += tmpvalue;
TrackingCnt ++;
macp->TxPwrCCK = 0;
}
if (macp->TxPwrOFDM){
if (macp->TxOFDMCnt > cTX_SENT_LEN){ // make sure Tx by HMAC (for UMAC)
tmpvalue = zd_readl(ZD1205_CR57);
tmpvalue &= 0xFF;
accumulate_OFDM += tmpvalue;
TrackingCnt_OFDM ++;
PreTxOFDMType = macp->TxOFDMType;
}
else {
if (PreTxOFDMType != macp->TxOFDMType) {
accumulate_OFDM = 0;
TrackingCnt_OFDM = 0;
}
}
macp->TxPwrOFDM = 0;
}
}
UnLockPhyReg(&dot11Obj);
}
}
#endif
}
//================================================================
// Housekeeping Every 1s
//================================================================
void zd1211_CheckWithIPC(struct zd1205_private *macp)
{
static u32 loop = 0;
u8 BssType = macp->cardSetting.BssType;
loop++;
if ((loop % 10) == 0){
// bypass the weak signal in BSS and AP mode
if ( (macp->bAssoc) &&
(macp->PHYTestRssi <= 0x18) &&
((BssType == INDEPENDENT_BSS) ||
(BssType == PSEUDO_IBSS)) ){
if (!macp->CR138Flag){
LockPhyReg(&dot11Obj);
zd_writel(0xa8, ZD1205_CR138);
UnLockPhyReg(&dot11Obj);
macp->CR138Flag = 1;
}
}
else if (macp->CR138Flag){
LockPhyReg(&dot11Obj);
zd_writel(0x28, ZD1205_CR138);
UnLockPhyReg(&dot11Obj);
macp->CR138Flag = 0;
}
#if 0
// solve the throughput problem when communicate with the IPC card
if ( ((macp->rxDataPerSec + macp->txDataPerSec) > 50000) &&
(macp->RF_Mode == RFMD_RF) &&
(BssType != PSEUDO_IBSS) &&
(macp->IPCFlag != 4) ){
if ( (macp->rxDataPerSec > 3*macp->txDataPerSec) &&
(macp->PHYTestRssi <= 0x24) ){
if ((!macp->IPCFlag) || (macp->IPCFlag!=1)){
LockPhyReg(&dot11Obj);
zd_writel(0x0a, ZD1205_CR87);
zd_writel(0x04, ZD1205_CR89);
UnLockPhyReg(&dot11Obj);
macp->AdapterMaxRate = 8; // MAX = 24M
macp->IPCFlag = 1;
}
}
else if ( 3*macp->rxDataPerSec < macp->txDataPerSec ){
if ((!macp->IPCFlag) || (macp->IPCFlag != 3)){
LockPhyReg(&dot11Obj);
zd_writel(0x2A, ZD1205_CR87);
zd_writel(0x24, ZD1205_CR89);
UnLockPhyReg(&dot11Obj);
macp->AdapterMaxRate = 0x0B; // MAX = 54M
macp->IPCFlag = 3;
}
}
else
{
if ((!macp->IPCFlag) || (macp->IPCFlag != 2)){
LockPhyReg(&dot11Obj);
zd_writel(0x10, ZD1205_CR87);
zd_writel(0x0C, ZD1205_CR89);
UnLockPhyReg(&dot11Obj);
macp->AdapterMaxRate = 9; // MAX = 36M
macp->IPCFlag = 2;
}
}
}
else if ((macp->RF_Mode == RFMD_RF) &&
(BssType == PSEUDO_IBSS) &&
(macp->IPCFlag != 4)){
if ((!macp->IPCFlag) || (macp->IPCFlag != 3)){
LockPhyReg(&dot11Obj);
zd_writel(0x2A, ZD1205_CR87);
zd_writel(0x24, ZD1205_CR89);
UnLockPhyReg(&dot11Obj);
macp->AdapterMaxRate = 0x0B; // MAX = 54M
macp->IPCFlag = 3;
}
}
else if ((macp->RF_Mode == RFMD_RF) &&
(macp->IPCFlag != 4) ){
if ( (!macp->IPCFlag) || (macp->IPCFlag != 2)){
LockPhyReg(&dot11Obj);
zd_writel(0x10, ZD1205_CR87);
zd_writel(0x0C, ZD1205_CR89);
UnLockPhyReg(&dot11Obj);
macp->AdapterMaxRate = 9; // MAX = 36M
macp->IPCFlag = 2;
}
}
macp->rxDataPerSec = 0;
macp->txDataPerSec = 0;
#endif
if (macp->LinkLEDn == LED2)
iLED_OFF(macp, LED1);
if (!macp->bAssoc){
macp->LinkTimer ++;
if ((macp->LinkTimer == 1) && (macp->LinkLED_OnDur != 0)){
iLED_ON(macp, macp->LinkLEDn);
}
if (macp->LinkTimer == (macp->LinkLED_OnDur + 1)){
iLED_OFF(macp, macp->LinkLEDn);
}
if (macp->LinkTimer >= (macp->LinkLED_OnDur + macp->LinkLED_OffDur))
macp->LinkTimer = 0;
}
#if 0
if (dot11Obj.PhyTest & BIT_8){
u32 tmpvalue;
LockPhyReg(&dot11Obj);
tmpvalue = zd_readl(ZD1205_CR122);
if ((tmpvalue & 0xFF) != 0xFF)
zd_writel(0xFF, ZD1205_CR122);
else
zd_writel(0x00, ZD1205_CR122);
UnLockPhyReg(&dot11Obj);
}
#endif
}// end of (loop % 10)
}
// Switch to another antenna
void zd1211_SwitchAntenna(struct zd1205_private *macp)
{
u32 tmpvalue;
LockPhyReg(&dot11Obj);
tmpvalue = zd_readl(ZD1205_CR10);
tmpvalue ^= BIT_1;
zd_writel(tmpvalue, ZD1205_CR10);
tmpvalue = zd_readl(ZD1205_CR9);
tmpvalue ^= BIT_2;
zd_writel(tmpvalue, ZD1205_CR9);
UnLockPhyReg(&dot11Obj);
}
//-----------------------------------------------------------------------------
#if fPROG_FLASH
// 1:Intel Flash; 0: MXIC, Winbond, AMD, Atmel...
#define cFLASH_MXIC 0
#define cFLASH_INTEL 1
u16 zd1211_SetHighAddr(struct zd1205_private *macp, u16 high_addr)
{
u16 tmp_cr203;
u16 WriteAddr[cMAX_MULTI_WRITE_REG_NUM];
u16 WriteData[cMAX_MULTI_WRITE_REG_NUM];
u16 WriteIndex = 0;
tmp_cr203 = ((high_addr << 1) & ~mMASK(2)) + (high_addr & mBIT(0));
if (macp->FlashType == cFLASH_INTEL){
mFILL_WRITE_REGISTER(rLED_CTRL, 0);
if (mTEST_BIT(high_addr, 7))
mFILL_WRITE_REGISTER(rLED_CTRL, LED2);
}
mFILL_WRITE_REGISTER(ZD1205_CR203, tmp_cr203);
zd1211_WriteMultiRegister(WriteAddr, WriteData, WriteIndex, true);
return tmp_cr203;
}
/* abs_addr: in word */
u16 zd1211_SetAbsAddr(struct zd1205_private *macp, u32 abs_addr, u16 *get_cr203)
{
static u16 pre_high_addr = 0, pre_cr203 = 0;
u16 high_addr;
high_addr = (u16) (abs_addr >> 14);
if (pre_high_addr != high_addr){
pre_cr203 = zd1211_SetHighAddr(macp, high_addr);
pre_high_addr = high_addr;
}
if (get_cr203 != NULL)
*get_cr203 = pre_cr203;
return ((u16) (abs_addr & mMASK(14)));
}
void zd1211_FlashCmdWrite(struct zd1205_private *macp, u8 Cmd)
{
u32 tmpvalue;
u16 WriteAddr[cMAX_MULTI_WRITE_REG_NUM];
u16 WriteData[cMAX_MULTI_WRITE_REG_NUM];
u16 WriteIndex = 0;
tmpvalue = zd1211_readl(ZD1205_CR203, true);
if (macp->FlashType == cFLASH_MXIC){
mFLASH_WRITE_EVEN_ADDR(0xAAA, 0xAA, tmpvalue);
mFLASH_WRITE_ODD_ADDR(0x555, 0x55, tmpvalue);
mFLASH_WRITE_EVEN_ADDR(0xAAA, Cmd, tmpvalue);
}
else
mFLASH_WRITE_EVEN_ADDR(0, Cmd, tmpvalue);
zd1211_WriteMultiRegister(WriteAddr, WriteData, WriteIndex, false);
}
void zd1211_FlashResetCmd(struct zd1205_private *macp)
{
if (macp->FlashType == cFLASH_MXIC)
zd1211_writel(0, 0xF0, false);
else
zd1211_FlashCmdWrite(macp, 0xFF);
}
void zd1211_InitHighAddr(struct zd1205_private *macp)
{
u16 WriteAddr[cMAX_MULTI_WRITE_REG_NUM];
u16 WriteData[cMAX_MULTI_WRITE_REG_NUM];
u16 WriteIndex = 0;
mFILL_WRITE_REGISTER(UMAC_WAIT_STATE, 0x022); // 25ns * 2
mFILL_WRITE_REGISTER(ZD1205_CR11 + (u16) (macp->USBCSRAddress), 0x15);
// Use AntSel to control VPEN for Intel Flash
mFILL_WRITE_REGISTER(ZD1205_CR10 + (u16) (macp->USBCSRAddress), 0x82);
mFILL_WRITE_REGISTER(ZD1205_CR9 + (u16) (macp->USBCSRAddress), 0x24);
mFILL_WRITE_REGISTER(ZD1205_CR204 + (u16) (macp->USBCSRAddress), 0x7C);
mFILL_WRITE_REGISTER(ZD1205_CR203 + (u16) (macp->USBCSRAddress), 0);
zd1211_WriteMultiRegister(WriteAddr, WriteData, WriteIndex, false);
if (macp->FlashType == 0xFF){
u32 tmpvalue;
macp->FlashType = cFLASH_INTEL;
zd1211_FlashCmdWrite(macp, 0x90); // Read Chip ID
tmpvalue = zd1211_readl(0, false);
if ((tmpvalue & 0xFFFF) != 0x8989) // Intel Manufacture Code
macp->FlashType = cFLASH_MXIC;
}
zd1211_SetAbsAddr(macp, 0, NULL);
zd1211_FlashResetCmd(macp);
}
/* Top: 8k byte / sector ==> 0 - 0x1000 (word address) */
/* ==> sec0 address = 0; sec1 address = 0x1000 ... */
void zd1211_FlashSecErase(struct zd1205_private *macp, u16 Sec0)
{
u32 tmpvalue;
u16 WriteAddr[cMAX_MULTI_WRITE_REG_NUM];
u16 WriteData[cMAX_MULTI_WRITE_REG_NUM];
u16 WriteIndex = 0;
LockPhyReg(&dot11Obj);
tmpvalue = zd1211_readl(ZD1205_CR203, true);
if (macp->FlashType == cFLASH_MXIC){
zd1211_FlashCmdWrite(macp, 0x80);
mFLASH_WRITE_EVEN_ADDR(0xAAA, 0xAA, tmpvalue);
mFLASH_WRITE_ODD_ADDR(0x555, 0x55, tmpvalue);
mFLASH_WRITE_EVEN_ADDR(Sec0 << 1, 0x30, tmpvalue);
}
else
{
mFLASH_SET_EVEN_ADDR(tmpvalue);
mFILL_WRITE_REGISTER(Sec0, 0x20);
mFILL_WRITE_REGISTER(Sec0, 0xD0);
}
zd1211_WriteMultiRegister(WriteAddr, WriteData, WriteIndex, false);
UnLockPhyReg(&dot11Obj);
}
void zd1211_EraseFlash(struct zd1205_private *macp)
{
u32 ii;
u32 tmpvalue;
u16 low_addr, jj;
macp->bDisableTx = 1;
//USB_StopTxEP(Adapter);
LockPhyReg(&dot11Obj);
macp->bAllowAccessRegister = 0;
zd1211_InitHighAddr(macp);
if (macp->FlashType == cFLASH_MXIC)
{
zd1211_FlashCmdWrite(macp, 0x80);
zd1211_FlashCmdWrite(macp, 0x10);
}
else {
for (ii = 0; ii < 0x400000L; ii += 0x10000L){
low_addr = zd1211_SetAbsAddr(macp, ii, NULL);
zd1211_FlashSecErase(macp, low_addr);
for (jj = 0; jj < 100; jj ++){
tmpvalue = zd1211_readl(0, false);
if (tmpvalue & 0x8000)
break;
mdelay(10); // Sleep 10ms
}
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -