/* * Description: Write a Byte to BASEBAND, by embedded programming * * Parameters: * In: * dwIoBase - I/O base address * byBBAddr - address of register in Baseband * byData - data to write * Out: * none * * Return Value: true if succeeded; false if failed. * */ bool BBbWriteEmbedded(struct vnt_private *priv, unsigned char byBBAddr, unsigned char byData) { void __iomem *dwIoBase = priv->PortOffset; unsigned short ww; unsigned char byValue; /* BB reg offset */ VNSvOutPortB(dwIoBase + MAC_REG_BBREGADR, byBBAddr); /* set BB data */ VNSvOutPortB(dwIoBase + MAC_REG_BBREGDATA, byData); /* turn on BBREGCTL_REGW */ MACvRegBitsOn(dwIoBase, MAC_REG_BBREGCTL, BBREGCTL_REGW); /* W_MAX_TIMEOUT is the timeout period */ for (ww = 0; ww < W_MAX_TIMEOUT; ww++) { VNSvInPortB(dwIoBase + MAC_REG_BBREGCTL, &byValue); if (byValue & BBREGCTL_DONE) break; } if (ww == W_MAX_TIMEOUT) { DBG_PORT80(0x31); pr_debug(" DBG_PORT80(0x31)\n"); return false; } return true; }
/* Need to Pull PLLON low when writing channel registers through * 3-wire interface */ static bool s_bAL7230SelectChannel(struct vnt_private *priv, unsigned char byChannel) { void __iomem *iobase = priv->PortOffset; bool ret; ret = true; /* PLLON Off */ MACvWordRegBitsOff(iobase, MAC_REG_SOFTPWRCTL, SOFTPWRCTL_SWPE3); ret &= IFRFbWriteEmbedded(priv, dwAL7230ChannelTable0[byChannel - 1]); ret &= IFRFbWriteEmbedded(priv, dwAL7230ChannelTable1[byChannel - 1]); ret &= IFRFbWriteEmbedded(priv, dwAL7230ChannelTable2[byChannel - 1]); /* PLLOn On */ MACvWordRegBitsOn(iobase, MAC_REG_SOFTPWRCTL, SOFTPWRCTL_SWPE3); /* Set Channel[7] = 0 to tell H/W channel is changing now. */ VNSvOutPortB(iobase + MAC_REG_CHANNEL, (byChannel & 0x7F)); MACvTimer0MicroSDelay(priv, SWITCH_CHANNEL_DELAY_AL7230); /* Set Channel[7] = 1 to tell H/W channel change is done. */ VNSvOutPortB(iobase + MAC_REG_CHANNEL, (byChannel | 0x80)); return ret; }
/* * Description: Auto Load EEPROM to MAC register * * Parameters: * In: * dwIoBase - I/O base address * Out: * none * * Return Value: true if success; otherwise false * */ bool SROMbAutoLoad(unsigned long dwIoBase) { unsigned char byWait; int ii; unsigned char byOrg; VNSvInPortB(dwIoBase + MAC_REG_I2MCFG, &byOrg); /* turn on hardware retry */ VNSvOutPortB(dwIoBase + MAC_REG_I2MCFG, (byOrg | I2MCFG_NORETRY)); MACvRegBitsOn(dwIoBase, MAC_REG_I2MCSR, I2MCSR_AUTOLD); /* ii = Rom Address */ for (ii = 0; ii < EEP_MAX_CONTEXT_SIZE; ii++) { MACvTimer0MicroSDelay(dwIoBase, CB_EEPROM_READBYTE_WAIT); VNSvInPortB(dwIoBase + MAC_REG_I2MCSR, &byWait); if ( !(byWait & I2MCSR_AUTOLD)) break; } VNSvOutPortB(dwIoBase + MAC_REG_I2MCFG, byOrg); if (ii == EEP_MAX_CONTEXT_SIZE) return false; return true; }
/* * Description: Read a byte from EEPROM, by MAC I2C * * Parameters: * In: * dwIoBase - I/O base address * byContntOffset - address of EEPROM * Out: * none * * Return Value: data read * */ BYTE SROMbyReadEmbedded(DWORD_PTR dwIoBase, BYTE byContntOffset) { WORD wDelay, wNoACK; BYTE byWait; BYTE byData; BYTE byOrg; byData = 0xFF; VNSvInPortB(dwIoBase + MAC_REG_I2MCFG, &byOrg); // turn off hardware retry for getting NACK VNSvOutPortB(dwIoBase + MAC_REG_I2MCFG, (byOrg & (~I2MCFG_NORETRY))); for (wNoACK = 0; wNoACK < W_MAX_I2CRETRY; wNoACK++) { VNSvOutPortB(dwIoBase + MAC_REG_I2MTGID, EEP_I2C_DEV_ID); VNSvOutPortB(dwIoBase + MAC_REG_I2MTGAD, byContntOffset); // issue read command VNSvOutPortB(dwIoBase + MAC_REG_I2MCSR, I2MCSR_EEMR); // wait DONE be set for (wDelay = 0; wDelay < W_MAX_TIMEOUT; wDelay++) { VNSvInPortB(dwIoBase + MAC_REG_I2MCSR, &byWait); if (byWait & (I2MCSR_DONE | I2MCSR_NACK)) break; PCAvDelayByIO(CB_DELAY_LOOP_WAIT); } if ((wDelay < W_MAX_TIMEOUT) && ( !(byWait & I2MCSR_NACK))) { break; } } VNSvInPortB(dwIoBase + MAC_REG_I2MDIPT, &byData); VNSvOutPortB(dwIoBase + MAC_REG_I2MCFG, byOrg); return byData; }
/* * Description: Auto Load EEPROM to MAC register * * Parameters: * In: * dwIoBase - I/O base address * Out: * none * * Return Value: TRUE if success; otherwise FALSE * */ BOOL SROMbAutoLoad (DWORD_PTR dwIoBase) { BYTE byWait; int ii; BYTE byOrg; VNSvInPortB(dwIoBase + MAC_REG_I2MCFG, &byOrg); // turn on hardware retry VNSvOutPortB(dwIoBase + MAC_REG_I2MCFG, (byOrg | I2MCFG_NORETRY)); MACvRegBitsOn(dwIoBase, MAC_REG_I2MCSR, I2MCSR_AUTOLD); // ii = Rom Address for (ii = 0; ii < EEP_MAX_CONTEXT_SIZE; ii++) { MACvTimer0MicroSDelay(dwIoBase, CB_EEPROM_READBYTE_WAIT); VNSvInPortB(dwIoBase + MAC_REG_I2MCSR, &byWait); if ( !(byWait & I2MCSR_AUTOLD)) break; } VNSvOutPortB(dwIoBase + MAC_REG_I2MCFG, byOrg); if (ii == EEP_MAX_CONTEXT_SIZE) return FALSE; return TRUE; }
/* * Description: Reset this hash index into multicast address register * bit * * Parameters: * */ VOID GMACvResetMultiAddrByHash(DWORD dwIoBase, BYTE byHashIdx) { UINT uByteIdx; BYTE byBitMask; BYTE byOrgValue; BYTE byOrgCAMCR, byData; /* modify CAMCR to select MAR regs */ VNSvInPortB(dwIoBase + MAC_REG_CAMCR, &byOrgCAMCR); byData = (BYTE)(byOrgCAMCR & ~(CAMCR_PS1|CAMCR_PS0)); VNSvOutPortB(dwIoBase + MAC_REG_CAMCR, byData); /* calculate byte position */ uByteIdx = byHashIdx / 8; DBG_ASSERT(uByteIdx < 8); /* calculate bit position */ byBitMask = 1; byBitMask <<= (byHashIdx % 8); /* turn off the bit */ byOrgValue = GMACbyReadMultiAddr(dwIoBase, uByteIdx); GMACvWriteMultiAddr(dwIoBase, uByteIdx, (BYTE)(byOrgValue & (~byBitMask))); /* restore to original CAMCR */ VNSvOutPortB(dwIoBase + MAC_REG_CAMCR, byOrgCAMCR); }
/* * Description: Read a byte from EEPROM, by MAC I2C * * Parameters: * In: * dwIoBase - I/O base address * byContntOffset - address of EEPROM * Out: * none * * Return Value: data read * */ unsigned char SROMbyReadEmbedded(unsigned long dwIoBase, unsigned char byContntOffset) { unsigned short wDelay, wNoACK; unsigned char byWait; unsigned char byData; unsigned char byOrg; byData = 0xFF; VNSvInPortB(dwIoBase + MAC_REG_I2MCFG, &byOrg); /* turn off hardware retry for getting NACK */ VNSvOutPortB(dwIoBase + MAC_REG_I2MCFG, (byOrg & (~I2MCFG_NORETRY))); for (wNoACK = 0; wNoACK < W_MAX_I2CRETRY; wNoACK++) { VNSvOutPortB(dwIoBase + MAC_REG_I2MTGID, EEP_I2C_DEV_ID); VNSvOutPortB(dwIoBase + MAC_REG_I2MTGAD, byContntOffset); /* issue read command */ VNSvOutPortB(dwIoBase + MAC_REG_I2MCSR, I2MCSR_EEMR); /* wait DONE be set */ for (wDelay = 0; wDelay < W_MAX_TIMEOUT; wDelay++) { VNSvInPortB(dwIoBase + MAC_REG_I2MCSR, &byWait); if (byWait & (I2MCSR_DONE | I2MCSR_NACK)) break; PCAvDelayByIO(CB_DELAY_LOOP_WAIT); } if ((wDelay < W_MAX_TIMEOUT) && ( !(byWait & I2MCSR_NACK))) { break; } } VNSvInPortB(dwIoBase + MAC_REG_I2MDIPT, &byData); VNSvOutPortB(dwIoBase + MAC_REG_I2MCFG, byOrg); return byData; }
VOID GMACvGetVCAM(DWORD dwIoBase, BYTE byAddress, PWORD pwData) { BYTE byOrgCAMCR, byData; /* modify CAMCR to select CAM DATA regs */ VNSvInPortB(dwIoBase + MAC_REG_CAMCR, &byOrgCAMCR); byData = (BYTE)((byOrgCAMCR | CAMCR_PS1) & ~CAMCR_PS0); VNSvOutPortB(dwIoBase + MAC_REG_CAMCR, byData); /* enable/select VCAM */ VNSvOutPortB(dwIoBase + MAC_REG_CAMADDR, (BYTE)(CAMADDR_CAMEN | CAMADDR_VCAMSL | byAddress)); /* issue read command */ MACvRegBitsOn(dwIoBase, MAC_REG_CAMCR, CAMCR_CAMRD); /* Wait for CAMRD self clear */ while (TRUE) { if (GMACbIsRegBitsOff(dwIoBase, MAC_REG_CAMCR, CAMCR_CAMRD)) break; } /* read VID CAM data */ VNSvInPortW(dwIoBase + MAC_REG_CAM, pwData); /* disable CAMEN */ VNSvOutPortB(dwIoBase + MAC_REG_CAMADDR, 0); /* restore to original CAMCR */ VNSvOutPortB(dwIoBase + MAC_REG_CAMCR, byOrgCAMCR); }
/* * Description: * Restore MAC registers from context buffer * * Parameters: * In: * dwIoBase - Base Address for MAC * pbyCxtBuf - Context buffer * Out: * none * * Return Value: none * */ void MACvRestoreContext(void __iomem *dwIoBase, unsigned char *pbyCxtBuf) { int ii; MACvSelectPage1(dwIoBase); // restore page1 for (ii = 0; ii < MAC_MAX_CONTEXT_SIZE_PAGE1; ii++) VNSvOutPortB((dwIoBase + ii), *(pbyCxtBuf + MAC_MAX_CONTEXT_SIZE_PAGE0 + ii)); MACvSelectPage0(dwIoBase); // restore RCR,TCR,IMR... for (ii = MAC_REG_RCR; ii < MAC_REG_ISR; ii++) VNSvOutPortB(dwIoBase + ii, *(pbyCxtBuf + ii)); // restore MAC Config. for (ii = MAC_REG_LRT; ii < MAC_REG_PAGE1SEL; ii++) VNSvOutPortB(dwIoBase + ii, *(pbyCxtBuf + ii)); VNSvOutPortB(dwIoBase + MAC_REG_CFG, *(pbyCxtBuf + MAC_REG_CFG)); // restore PS Config. for (ii = MAC_REG_PSCFG; ii < MAC_REG_BBREGCTL; ii++) VNSvOutPortB(dwIoBase + ii, *(pbyCxtBuf + ii)); // restore CURR_RX_DESC_ADDR, CURR_TX_DESC_ADDR VNSvOutPortD(dwIoBase + MAC_REG_TXDMAPTR0, *(unsigned long *)(pbyCxtBuf + MAC_REG_TXDMAPTR0)); VNSvOutPortD(dwIoBase + MAC_REG_AC0DMAPTR, *(unsigned long *)(pbyCxtBuf + MAC_REG_AC0DMAPTR)); VNSvOutPortD(dwIoBase + MAC_REG_BCNDMAPTR, *(unsigned long *)(pbyCxtBuf + MAC_REG_BCNDMAPTR)); VNSvOutPortD(dwIoBase + MAC_REG_RXDMAPTR0, *(unsigned long *)(pbyCxtBuf + MAC_REG_RXDMAPTR0)); VNSvOutPortD(dwIoBase + MAC_REG_RXDMAPTR1, *(unsigned long *)(pbyCxtBuf + MAC_REG_RXDMAPTR1)); }
VOID GMACvSetMCAM(DWORD dwIoBase, BYTE byAddress, PBYTE pbyData) { BYTE byOrgCAMCR, byData; /* DWORD dwData; */ /* modify CAMCR to select CAM DATA regs */ VNSvInPortB(dwIoBase + MAC_REG_CAMCR, &byOrgCAMCR); byData = (BYTE)((byOrgCAMCR | CAMCR_PS1) & ~CAMCR_PS0); VNSvOutPortB(dwIoBase + MAC_REG_CAMCR, byData); /* enable/select MCAM */ VNSvOutPortB(dwIoBase + MAC_REG_CAMADDR, (BYTE)(CAMADDR_CAMEN | byAddress)); /* set MCAM Data */ VNSvOutPortD(dwIoBase + MAC_REG_CAM, *(PDWORD)pbyData); /* VNSvInPortD(dwIoBase + MAC_REG_CAM, &dwData); */ VNSvOutPortW(dwIoBase + MAC_REG_CAM + 4, *(PWORD)(pbyData + 4)); /* VNSvInPortW(dwIoBase + MAC_REG_CAM + 4, (PWORD)(&dwData)); */ /* issue write command */ MACvRegBitsOn(dwIoBase, MAC_REG_CAMCR, CAMCR_CAMWR); /* Wait for CAMWR self clear */ while (TRUE) { if (GMACbIsRegBitsOff(dwIoBase, MAC_REG_CAMCR, CAMCR_CAMWR)) break; } /* disable CAMEN */ VNSvOutPortB(dwIoBase + MAC_REG_CAMADDR, 0); /* restore to original CAMCR */ VNSvOutPortB(dwIoBase + MAC_REG_CAMCR, byOrgCAMCR); }
VOID GMACvTimer0MiniSDelay(DWORD dwIoBase, BYTE byRevId, UINT udelay) { BYTE byData; /* Disable Timer0 Interrupt */ MACvRegBitsOff(dwIoBase, MAC_REG_IMR + 2, (BYTE)(ISR_TMR0I >> 16)); /* Set resolution to mini second */ MACvRegBitsOff(dwIoBase, MAC_REG_CHIPGCR, CHIPGCR_TM0US); /* set delay time to udelay, unit is mini-second */ VNSvOutPortW(dwIoBase + MAC_REG_SOFT_TIMER0, (WORD)udelay); /* enable timer0 */ VNSvOutPortB(dwIoBase + MAC_REG_CR1_SET, CR1_TM0EN); /* wait for TM0EN self clear */ while (TRUE) { if (GMACbIsRegBitsOff(dwIoBase, MAC_REG_CR1_SET, CR1_TM0EN)) { /* clear TMR0I */ VNSvInPortB(dwIoBase + MAC_REG_ISR + 2, &byData); VNSvOutPortB(dwIoBase + MAC_REG_ISR + 2, byData); break; } } /* Enable Timer0 Interrupt */ MACvRegBitsOn(dwIoBase, MAC_REG_IMR + 2, (BYTE)(ISR_TMR0I >> 16)); }
/* * NOTE.... * first, disable MIICR_MAUTO, then * set MII reg offset to BMSR == 0x01 * must set offset before re-enable MIICR_MAUTO */ VOID GMACvEnableMiiAutoPoll(DWORD dwIoBase) { WORD ww; BYTE byData; VNSvOutPortB(dwIoBase + MAC_REG_MIICR, 0); /* polling once before MAUTO is turned on */ VNSvOutPortB(dwIoBase + MAC_REG_MIIADR, MIIADR_SWMPL); /* as soon as MIIDL is on, polling is really completed */ for (ww = 0; ww < W_MAX_TIMEOUT; ww++) { udelay(1000); VNSvInPortB(dwIoBase + MAC_REG_MIISR, &byData); if (BITbIsBitOn(byData, MIISR_MIIDL)) break; } /* Turn on MAUTO */ VNSvOutPortB(dwIoBase + MAC_REG_MIICR, MIICR_MAUTO); /* as soon as MIIDL is off, MAUTO is really started */ for (ww = 0; ww < W_MAX_TIMEOUT; ww++) { VNSvInPortB(dwIoBase + MAC_REG_MIISR, &byData); if (BITbIsBitOff(byData, MIISR_MIIDL)) break; } }
/** * set_channel() - Set NIC media channel * * @pDeviceHandler: The adapter to be set * @uConnectionChannel: Channel to be set * * Return Value: true if succeeded; false if failed. * */ bool set_channel(struct vnt_private *priv, struct ieee80211_channel *ch) { bool ret = true; if (priv->byCurrentCh == ch->hw_value) return ret; /* Set VGA to max sensitivity */ if (priv->bUpdateBBVGA && priv->byBBVGACurrent != priv->abyBBVGA[0]) { priv->byBBVGACurrent = priv->abyBBVGA[0]; BBvSetVGAGainOffset(priv, priv->byBBVGACurrent); } /* clear NAV */ MACvRegBitsOn(priv->PortOffset, MAC_REG_MACCR, MACCR_CLRNAV); /* TX_PE will reserve 3 us for MAX2829 A mode only, it is for better TX throughput */ if (priv->byRFType == RF_AIROHA7230) RFbAL7230SelectChannelPostProcess(priv, priv->byCurrentCh, ch->hw_value); priv->byCurrentCh = ch->hw_value; ret &= RFbSelectChannel(priv, priv->byRFType, ch->hw_value); /* Init Synthesizer Table */ if (priv->bEnablePSMode) RFvWriteWakeProgSyn(priv, priv->byRFType, ch->hw_value); BBvSoftwareReset(priv); if (priv->byLocalID > REV_ID_VT3253_B1) { unsigned long flags; spin_lock_irqsave(&priv->lock, flags); /* set HW default power register */ MACvSelectPage1(priv->PortOffset); RFbSetPower(priv, RATE_1M, priv->byCurrentCh); VNSvOutPortB(priv->PortOffset + MAC_REG_PWRCCK, priv->byCurPwr); RFbSetPower(priv, RATE_6M, priv->byCurrentCh); VNSvOutPortB(priv->PortOffset + MAC_REG_PWROFDM, priv->byCurPwr); MACvSelectPage0(priv->PortOffset); spin_unlock_irqrestore(&priv->lock, flags); } if (priv->byBBType == BB_TYPE_11B) RFbSetPower(priv, RATE_1M, priv->byCurrentCh); else RFbSetPower(priv, RATE_6M, priv->byCurrentCh); return ret; }
VOID GMACvSetPacketFilter(DWORD dwIoBase, WORD wFilterType) { BYTE byOldRCR; BYTE byNewRCR = 0; BYTE byOrgCAMCR, byData; /* modify CAMCR to select MAR regs */ VNSvInPortB(dwIoBase + MAC_REG_CAMCR, &byOrgCAMCR); byData = (BYTE)(byOrgCAMCR & ~(CAMCR_PS1|CAMCR_PS0)); VNSvOutPortB(dwIoBase + MAC_REG_CAMCR, byData); /* if only in DIRECTED mode, multicast-address will set to zero, */ /* but if other mode exist (e.g. PROMISCUOUS), multicast-address */ /* will be open */ if (BITbIsBitOn(wFilterType, PKT_TYPE_DIRECTED)) { /* set multicast address to accept none */ VNSvOutPortD(dwIoBase + MAC_REG_MAR, 0L); /* PCAvDelayByIO(1); */ VNSvOutPortD(dwIoBase + MAC_REG_MAR + sizeof(DWORD), 0L); /* PCAvDelayByIO(1); */ } if (BITbIsAnyBitsOn(wFilterType, PKT_TYPE_PROMISCUOUS | PKT_TYPE_ALL_MULTICAST)) { /* set multicast address to accept all */ VNSvOutPortD(dwIoBase + MAC_REG_MAR, 0xFFFFFFFFL); /* PCAvDelayByIO(1); */ VNSvOutPortD(dwIoBase + MAC_REG_MAR + sizeof(DWORD), 0xFFFFFFFFL); /* PCAvDelayByIO(1); */ } /* restore to original CAMCR */ VNSvOutPortB(dwIoBase + MAC_REG_CAMCR, byOrgCAMCR); if (BITbIsBitOn(wFilterType, PKT_TYPE_PROMISCUOUS)) byNewRCR |= (RCR_PROM | RCR_AM | RCR_AB); if (BITbIsAnyBitsOn(wFilterType, PKT_TYPE_MULTICAST | PKT_TYPE_ALL_MULTICAST)) byNewRCR |= RCR_AM; if (BITbIsBitOn(wFilterType, PKT_TYPE_BROADCAST)) byNewRCR |= RCR_AB; if (BITbIsBitOn(wFilterType, PKT_TYPE_RUNT)) byNewRCR |= RCR_AR; if (BITbIsBitOn(wFilterType, PKT_TYPE_ERROR)) byNewRCR |= RCR_SEP; VNSvInPortB(dwIoBase + MAC_REG_RCR, &byOldRCR); if (byNewRCR != (byOldRCR & 0x1F)) { /* Modify the Receive Command Register */ byNewRCR |= (BYTE)(byOldRCR & 0xE0); VNSvOutPortB(dwIoBase + MAC_REG_RCR, byNewRCR); } }
int vnt_beacon_enable(struct vnt_private *priv, struct ieee80211_vif *vif, struct ieee80211_bss_conf *conf) { VNSvOutPortB(priv->PortOffset + MAC_REG_TFTCTL, TFTCTL_TSFCNTRST); VNSvOutPortB(priv->PortOffset + MAC_REG_TFTCTL, TFTCTL_TSFCNTREN); CARDvSetFirstNextTBTT(priv, conf->beacon_int); CARDbSetBeaconPeriod(priv, conf->beacon_int); return vnt_beacon_make(priv, vif); }
VOID GMACvTimer0MicroSDelay(DWORD dwIoBase, BYTE byRevId, UINT udelay) { BYTE byData; /* Notice!!! */ /* Disable Timer0 Interrupt */ MACvRegBitsOff(dwIoBase, MAC_REG_IMR + 2, (BYTE)(ISR_TMR0I >> 16)); /* Set resolution to micro second */ MACvRegBitsOn(dwIoBase, MAC_REG_CHIPGCR, CHIPGCR_TM0US); /* set delay time to udelay, unit is micro-second */ VNSvOutPortW(dwIoBase + MAC_REG_SOFT_TIMER0, (WORD)udelay); /* enable timer0 */ VNSvOutPortB(dwIoBase + MAC_REG_CR1_SET, CR1_TM0EN); /* wait for TM0EN self clear */ while (TRUE) { /* Method 1 -> OK, and safe */ if (GMACbIsRegBitsOff(dwIoBase, MAC_REG_CR1_SET, CR1_TM0EN)) { /* clear TMR0I */ VNSvInPortB(dwIoBase + MAC_REG_ISR + 2, &byData); VNSvOutPortB(dwIoBase + MAC_REG_ISR + 2, byData); break; } /* // Method 2 -> OK, but not safe VNSvInPortB(dwIoBase + MAC_REG_ISR + 2, &byData); if (BITbIsBitOn(byData, (BYTE)(ISR_TMR0I >> 16))) { VNSvOutPortB(dwIoBase + MAC_REG_ISR + 2, byData); break; } */ /* // Method 3 -> OK, but not safe if (MACbIsRegBitsOn(dwIoBase, MAC_REG_ISR + 2, (BYTE)(ISR_TMR0I >> 16))) { // clear TMR0I VNSvOutPortB(dwIoBase + MAC_REG_ISR + 2, (BYTE)(ISR_TMR0I >> 16)); break; } */ } /* Notice !!! */ /* Enable Timer0 Interrupt */ MACvRegBitsOn(dwIoBase, MAC_REG_IMR + 2, (BYTE)(ISR_TMR0I >> 16)); }
/* * Description: AIROHA IFRF chip init function * * Parameters: * In: * dwIoBase - I/O base address * Out: * none * * Return Value: TRUE if succeeded; FALSE if failed. * */ BOOL RFbAL2230Init (DWORD_PTR dwIoBase) { int ii; BOOL bResult; bResult = TRUE; //3-wire control for normal mode VNSvOutPortB(dwIoBase + MAC_REG_SOFTPWRCTL, 0); MACvWordRegBitsOn(dwIoBase, MAC_REG_SOFTPWRCTL, (SOFTPWRCTL_SWPECTI | SOFTPWRCTL_TXPEINV)); //2008-8-21 chester <add> // PLL Off MACvWordRegBitsOff(dwIoBase, MAC_REG_SOFTPWRCTL, SOFTPWRCTL_SWPE3); //patch abnormal AL2230 frequency output //2008-8-21 chester <add> IFRFbWriteEmbeded(dwIoBase, (0x07168700+(BY_AL2230_REG_LEN<<3)+IFREGCTL_REGW)); for (ii = 0; ii < CB_AL2230_INIT_SEQ; ii++) bResult &= IFRFbWriteEmbeded(dwIoBase, dwAL2230InitTable[ii]); //2008-8-21 chester <add> MACvTimer0MicroSDelay(dwIoBase, 30); //delay 30 us // PLL On MACvWordRegBitsOn(dwIoBase, MAC_REG_SOFTPWRCTL, SOFTPWRCTL_SWPE3); MACvTimer0MicroSDelay(dwIoBase, 150);//150us bResult &= IFRFbWriteEmbeded(dwIoBase, (0x00d80f00+(BY_AL2230_REG_LEN<<3)+IFREGCTL_REGW)); MACvTimer0MicroSDelay(dwIoBase, 30);//30us bResult &= IFRFbWriteEmbeded(dwIoBase, (0x00780f00+(BY_AL2230_REG_LEN<<3)+IFREGCTL_REGW)); MACvTimer0MicroSDelay(dwIoBase, 30);//30us bResult &= IFRFbWriteEmbeded(dwIoBase, dwAL2230InitTable[CB_AL2230_INIT_SEQ-1]); MACvWordRegBitsOn(dwIoBase, MAC_REG_SOFTPWRCTL, (SOFTPWRCTL_SWPE3 | SOFTPWRCTL_SWPE2 | SOFTPWRCTL_SWPECTI | SOFTPWRCTL_TXPEINV)); //3-wire control for power saving mode VNSvOutPortB(dwIoBase + MAC_REG_PSPWRSIG, (PSSIG_WPE3 | PSSIG_WPE2)); //1100 0000 return bResult; }
/* * Description: * Initialize MAC * * Parameters: * In: * dwIoBase - Base Address for MAC * Out: * none * * Return Value: none * */ void MACvInitialize(void __iomem *dwIoBase) { /* clear sticky bits */ MACvClearStckDS(dwIoBase); /* disable force PME-enable */ VNSvOutPortB(dwIoBase + MAC_REG_PMC1, PME_OVR); /* only 3253 A */ /* do reset */ MACbSoftwareReset(dwIoBase); /* reset TSF counter */ VNSvOutPortB(dwIoBase + MAC_REG_TFTCTL, TFTCTL_TSFCNTRST); /* enable TSF counter */ VNSvOutPortB(dwIoBase + MAC_REG_TFTCTL, TFTCTL_TSFCNTREN); }
/* * Description: * Initialize MAC * * Parameters: * In: * dwIoBase - Base Address for MAC * Out: * none * * Return Value: none * */ void MACvInitialize(void __iomem *dwIoBase) { // clear sticky bits MACvClearStckDS(dwIoBase); // disable force PME-enable VNSvOutPortB(dwIoBase + MAC_REG_PMC1, PME_OVR); // only 3253 A // do reset MACbSoftwareReset(dwIoBase); // reset TSF counter VNSvOutPortB(dwIoBase + MAC_REG_TFTCTL, TFTCTL_TSFCNTRST); // enable TSF counter VNSvOutPortB(dwIoBase + MAC_REG_TFTCTL, TFTCTL_TSFCNTREN); }
BOOL RFbAL2230SelectChannel (DWORD_PTR dwIoBase, BYTE byChannel) { BOOL bResult; bResult = TRUE; bResult &= IFRFbWriteEmbeded (dwIoBase, dwAL2230ChannelTable0[byChannel-1]); bResult &= IFRFbWriteEmbeded (dwIoBase, dwAL2230ChannelTable1[byChannel-1]); // Set Channel[7] = 0 to tell H/W channel is changing now. VNSvOutPortB(dwIoBase + MAC_REG_CHANNEL, (byChannel & 0x7F)); MACvTimer0MicroSDelay(dwIoBase, SWITCH_CHANNEL_DELAY_AL2230); // Set Channel[7] = 1 to tell H/W channel change is done. VNSvOutPortB(dwIoBase + MAC_REG_CHANNEL, (byChannel | 0x80)); return bResult; }
bool RFbAL2230SelectChannel (unsigned long dwIoBase, unsigned char byChannel) { bool bResult; bResult = true; bResult &= IFRFbWriteEmbeded (dwIoBase, dwAL2230ChannelTable0[byChannel-1]); bResult &= IFRFbWriteEmbeded (dwIoBase, dwAL2230ChannelTable1[byChannel-1]); // Set Channel[7] = 0 to tell H/W channel is changing now. VNSvOutPortB(dwIoBase + MAC_REG_CHANNEL, (byChannel & 0x7F)); MACvTimer0MicroSDelay(dwIoBase, SWITCH_CHANNEL_DELAY_AL2230); // Set Channel[7] = 1 to tell H/W channel change is done. VNSvOutPortB(dwIoBase + MAC_REG_CHANNEL, (byChannel | 0x80)); return bResult; }
/* * Description: AIROHA IFRF chip init function * * Parameters: * In: * iobase - I/O base address * Out: * none * * Return Value: true if succeeded; false if failed. * */ static bool s_bAL7230Init(struct vnt_private *priv) { void __iomem *iobase = priv->PortOffset; int ii; bool ret; ret = true; /* 3-wire control for normal mode */ VNSvOutPortB(iobase + MAC_REG_SOFTPWRCTL, 0); MACvWordRegBitsOn(iobase, MAC_REG_SOFTPWRCTL, (SOFTPWRCTL_SWPECTI | SOFTPWRCTL_TXPEINV)); BBvPowerSaveModeOFF(priv); /* RobertYu:20050106, have DC value for Calibration */ for (ii = 0; ii < CB_AL7230_INIT_SEQ; ii++) ret &= IFRFbWriteEmbedded(priv, dwAL7230InitTable[ii]); /* PLL On */ MACvWordRegBitsOn(iobase, MAC_REG_SOFTPWRCTL, SOFTPWRCTL_SWPE3); /* Calibration */ MACvTimer0MicroSDelay(priv, 150);/* 150us */ /* TXDCOC:active, RCK:disable */ ret &= IFRFbWriteEmbedded(priv, (0x9ABA8F00 + (BY_AL7230_REG_LEN << 3) + IFREGCTL_REGW)); MACvTimer0MicroSDelay(priv, 30);/* 30us */ /* TXDCOC:disable, RCK:active */ ret &= IFRFbWriteEmbedded(priv, (0x3ABA8F00 + (BY_AL7230_REG_LEN << 3) + IFREGCTL_REGW)); MACvTimer0MicroSDelay(priv, 30);/* 30us */ /* TXDCOC:disable, RCK:disable */ ret &= IFRFbWriteEmbedded(priv, dwAL7230InitTable[CB_AL7230_INIT_SEQ-1]); MACvWordRegBitsOn(iobase, MAC_REG_SOFTPWRCTL, (SOFTPWRCTL_SWPE3 | SOFTPWRCTL_SWPE2 | SOFTPWRCTL_SWPECTI | SOFTPWRCTL_TXPEINV)); BBvPowerSaveModeON(priv); /* RobertYu:20050106 */ /* PE1: TX_ON, PE2: RX_ON, PE3: PLLON */ /* 3-wire control for power saving mode */ VNSvOutPortB(iobase + MAC_REG_PSPWRSIG, (PSSIG_WPE3 | PSSIG_WPE2)); /* 1100 0000 */ return ret; }
VOID GMACvSetPhyId(DWORD dwIoBase, BYTE byRevId, BYTE byPhyId) { BYTE byData; /* set PHY address */ VNSvInPortB(dwIoBase + MAC_REG_MIICFG, &byData); byData = (BYTE)((byData & 0xE0) | (byPhyId & 0x1F)); VNSvOutPortB(dwIoBase + MAC_REG_MIICFG, byData); }
static bool RFbAL2230SelectChannel(struct vnt_private *priv, unsigned char byChannel) { void __iomem *iobase = priv->PortOffset; bool ret; ret = true; ret &= IFRFbWriteEmbedded(priv, dwAL2230ChannelTable0[byChannel - 1]); ret &= IFRFbWriteEmbedded(priv, dwAL2230ChannelTable1[byChannel - 1]); /* Set Channel[7] = 0 to tell H/W channel is changing now. */ VNSvOutPortB(iobase + MAC_REG_CHANNEL, (byChannel & 0x7F)); MACvTimer0MicroSDelay(priv, SWITCH_CHANNEL_DELAY_AL2230); /* Set Channel[7] = 1 to tell H/W channel change is done. */ VNSvOutPortB(iobase + MAC_REG_CHANNEL, (byChannel | 0x80)); return ret; }
VOID GMACvGetVCAMMask(DWORD dwIoBase, PBYTE pbyMask) { BYTE byOrgCAMCR, byData; /* modify CAMCR to select CAM MASK regs */ VNSvInPortB(dwIoBase + MAC_REG_CAMCR, &byOrgCAMCR); byData = (BYTE)((byOrgCAMCR & ~CAMCR_PS1) | CAMCR_PS0); VNSvOutPortB(dwIoBase + MAC_REG_CAMCR, byData); /* select VCAM Mask */ VNSvOutPortB(dwIoBase + MAC_REG_CAMADDR, CAMADDR_VCAMSL); VNSvInPortD(dwIoBase + MAC_REG_CAM, (PDWORD)pbyMask); VNSvInPortD(dwIoBase + MAC_REG_CAM + 4, (PDWORD)(pbyMask + 4)); /* restore to original CAMCR */ VNSvOutPortB(dwIoBase + MAC_REG_CAMCR, byOrgCAMCR); }
VOID GMACvSetTqIndex(DWORD dwIoBase, BYTE byTxQue, WORD wTdIdx) { BYTE byData; /* Clear RUN */ VNSvOutPortB(dwIoBase + MAC_REG_TDCSR_CLR + (byTxQue / 2), (BYTE)(TRDCSR_RUN << ((byTxQue % 2)*4))); /* Wait for RUN clear */ while (TRUE) { VNSvInPortB(dwIoBase + MAC_REG_TDCSR_SET + (byTxQue / 2), &byData); if (BITbIsBitOff(byData, TRDCSR_RUN << ((byTxQue % 2)*4))) break; } /* Set TdIdx */ VNSvOutPortW(dwIoBase + MAC_REG_TDINDX + byTxQue*2, wTdIdx); /* Set RUN */ VNSvOutPortB(dwIoBase + MAC_REG_TDCSR_SET + (byTxQue / 2), (BYTE)(TRDCSR_RUN << ((byTxQue % 2)*4))); }
VOID GMACvGetMCAMMaskByBR(DWORD dwIoBase, PBYTE pbyMask) { BYTE byOrgCAMCR, byData; /* modify CAMCR to select CAM MASK regs */ VNSvInPortB(dwIoBase + MAC_REG_CAMCR, &byOrgCAMCR); byData = (BYTE)((byOrgCAMCR & ~CAMCR_PS1) | CAMCR_PS0); VNSvOutPortB(dwIoBase + MAC_REG_CAMCR, byData); /* Select MCAM Mask */ VNSvOutPortB(dwIoBase + MAC_REG_CAMADDR, 0); UINT uu; for (uu = 0; uu < 8; uu++) VNSvInPortB(dwIoBase + MAC_REG_CAM + uu, (pbyMask + uu)); /* restore to original CAMCR */ VNSvOutPortB(dwIoBase + MAC_REG_CAMCR, byOrgCAMCR); }
VOID GMACvRestoreContext(DWORD dwIoBase, BYTE byRevId, PBYTE pbyCxtBuf) { int ii; /* restore RCR,TCR,CR,ISR,IMR... */ for (ii = MAC_REG_PAR; ii < MAC_REG_DEC_BASE_HI; ii++) { if (ii >= MAC_REG_CR0_CLR && ii <= MAC_REG_CR3_CLR) continue; /* except CR0, because we don't want to start chip now */ if (ii != MAC_REG_CR0_SET) VNSvOutPortB(dwIoBase + ii, *(pbyCxtBuf + ii)); } /* restore MAC_REG_DEC_BASE_HI... */ for (ii = MAC_REG_DEC_BASE_HI; ii < MAC_REG_ISR_CTL; ii += 4) { VNSvOutPortD(dwIoBase + ii, *(PDWORD)(pbyCxtBuf + ii)); /* PCAvDelayByIO(1); */ } /* restore ISR_CTL,ISR,IMR,TDCSR,RDCSR.. */ for (ii = MAC_REG_ISR_CTL; ii < MAC_REG_TDCSR_CLR; ii++) VNSvOutPortB(dwIoBase + ii, *(pbyCxtBuf + ii)); /* restore MAC_REG_RDBASE_LO,MAC_REG_TDBASE_LO... */ for (ii = MAC_REG_RDBASE_LO; ii < MAC_REG_FIFO_TEST0; ii += 4) { VNSvOutPortD(dwIoBase + ii, *(PDWORD)(pbyCxtBuf + ii)); /* PCAvDelayByIO(1); */ } /* restore MIICFG... */ for (ii = MAC_REG_MIICFG; ii < MAC_REG_TBIST; ii++) VNSvOutPortB(dwIoBase + ii, *(pbyCxtBuf + ii)); /* restore GHIPGSR, WOLCR, PWCFG, TestReg, WOLCG ... */ for (ii = MAC_REG_CHIPGSR; ii < MAC_REG_WOLCR0_CLR; ii++) VNSvOutPortB(dwIoBase + ii, *(pbyCxtBuf + ii)); /* restore pattern, mask */ for (ii = MAC_REG_PATRN_CRC0; ii < MAC_REG_BYTEMSK3_3 + 4; ii += 4) { VNSvOutPortD(dwIoBase + ii, *(PDWORD)(pbyCxtBuf + ii)); /* PCAvDelayByIO(1); */ } }
/* * Description: AIROHA IFRF chip init function * * Parameters: * In: * iobase - I/O base address * Out: * none * * Return Value: true if succeeded; false if failed. * */ static bool RFbAL2230Init(struct vnt_private *priv) { void __iomem *iobase = priv->PortOffset; int ii; bool ret; ret = true; /* 3-wire control for normal mode */ VNSvOutPortB(iobase + MAC_REG_SOFTPWRCTL, 0); MACvWordRegBitsOn(iobase, MAC_REG_SOFTPWRCTL, (SOFTPWRCTL_SWPECTI | SOFTPWRCTL_TXPEINV)); /* PLL Off */ MACvWordRegBitsOff(iobase, MAC_REG_SOFTPWRCTL, SOFTPWRCTL_SWPE3); /* patch abnormal AL2230 frequency output */ IFRFbWriteEmbedded(priv, (0x07168700 + (BY_AL2230_REG_LEN << 3) + IFREGCTL_REGW)); for (ii = 0; ii < CB_AL2230_INIT_SEQ; ii++) ret &= IFRFbWriteEmbedded(priv, dwAL2230InitTable[ii]); MACvTimer0MicroSDelay(priv, 30); /* delay 30 us */ /* PLL On */ MACvWordRegBitsOn(iobase, MAC_REG_SOFTPWRCTL, SOFTPWRCTL_SWPE3); MACvTimer0MicroSDelay(priv, 150);/* 150us */ ret &= IFRFbWriteEmbedded(priv, (0x00d80f00 + (BY_AL2230_REG_LEN << 3) + IFREGCTL_REGW)); MACvTimer0MicroSDelay(priv, 30);/* 30us */ ret &= IFRFbWriteEmbedded(priv, (0x00780f00 + (BY_AL2230_REG_LEN << 3) + IFREGCTL_REGW)); MACvTimer0MicroSDelay(priv, 30);/* 30us */ ret &= IFRFbWriteEmbedded(priv, dwAL2230InitTable[CB_AL2230_INIT_SEQ-1]); MACvWordRegBitsOn(iobase, MAC_REG_SOFTPWRCTL, (SOFTPWRCTL_SWPE3 | SOFTPWRCTL_SWPE2 | SOFTPWRCTL_SWPECTI | SOFTPWRCTL_TXPEINV)); /* 3-wire control for power saving mode */ VNSvOutPortB(iobase + MAC_REG_PSPWRSIG, (PSSIG_WPE3 | PSSIG_WPE2)); /* 1100 0000 */ return ret; }
/* * Description: * Micro Second Delay via MAC * * Parameters: * In: * dwIoBase - Base Address for MAC * uDelay - Delay time (timer resolution is 4 us) * Out: * none * * Return Value: none * */ void MACvTimer0MicroSDelay(void __iomem *dwIoBase, unsigned int uDelay) { unsigned char byValue; unsigned int uu, ii; VNSvOutPortB(dwIoBase + MAC_REG_TMCTL0, 0); VNSvOutPortD(dwIoBase + MAC_REG_TMDATA0, uDelay); VNSvOutPortB(dwIoBase + MAC_REG_TMCTL0, (TMCTL_TMD | TMCTL_TE)); for (ii = 0; ii < 66; ii++) { // assume max PCI clock is 66Mhz for (uu = 0; uu < uDelay; uu++) { VNSvInPortB(dwIoBase + MAC_REG_TMCTL0, &byValue); if ((byValue == 0) || (byValue & TMCTL_TSUSP)) { VNSvOutPortB(dwIoBase + MAC_REG_TMCTL0, 0); return; } } } VNSvOutPortB(dwIoBase + MAC_REG_TMCTL0, 0); }