/* * 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)); }
/** * 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; }
/* * Description: * Save MAC registers to context buffer * * Parameters: * In: * io_base - Base Address for MAC * Out: * cxt_buf - Context buffer * * Return Value: none * */ void MACvSaveContext(struct vnt_private *priv, unsigned char *cxt_buf) { void __iomem *io_base = priv->PortOffset; /* read page0 register */ memcpy_fromio(cxt_buf, io_base, MAC_MAX_CONTEXT_SIZE_PAGE0); MACvSelectPage1(io_base); /* read page1 register */ memcpy_fromio(cxt_buf + MAC_MAX_CONTEXT_SIZE_PAGE0, io_base, MAC_MAX_CONTEXT_SIZE_PAGE1); MACvSelectPage0(io_base); }
/* * Description: * Save MAC registers to context buffer * * Parameters: * In: * dwIoBase - Base Address for MAC * Out: * pbyCxtBuf - Context buffer * * Return Value: none * */ void MACvSaveContext(void __iomem *dwIoBase, unsigned char *pbyCxtBuf) { int ii; // read page0 register for (ii = 0; ii < MAC_MAX_CONTEXT_SIZE_PAGE0; ii++) VNSvInPortB((dwIoBase + ii), (pbyCxtBuf + ii)); MACvSelectPage1(dwIoBase); // read page1 register for (ii = 0; ii < MAC_MAX_CONTEXT_SIZE_PAGE1; ii++) VNSvInPortB((dwIoBase + ii), (pbyCxtBuf + MAC_MAX_CONTEXT_SIZE_PAGE0 + ii)); MACvSelectPage0(dwIoBase); }
/* * Description: * Restore MAC registers from context buffer * * Parameters: * In: * io_base - Base Address for MAC * cxt_buf - Context buffer * Out: * none * * Return Value: none * */ void MACvRestoreContext(struct vnt_private *priv, unsigned char *cxt_buf) { void __iomem *io_base = priv->PortOffset; MACvSelectPage1(io_base); /* restore page1 */ memcpy_toio(io_base, cxt_buf + MAC_MAX_CONTEXT_SIZE_PAGE0, MAC_MAX_CONTEXT_SIZE_PAGE1); MACvSelectPage0(io_base); /* restore RCR,TCR,IMR... */ memcpy_toio(io_base + MAC_REG_RCR, cxt_buf + MAC_REG_RCR, MAC_REG_ISR - MAC_REG_RCR); /* restore MAC Config. */ memcpy_toio(io_base + MAC_REG_LRT, cxt_buf + MAC_REG_LRT, MAC_REG_PAGE1SEL - MAC_REG_LRT); iowrite8(*(cxt_buf + MAC_REG_CFG), io_base + MAC_REG_CFG); /* restore PS Config. */ memcpy_toio(io_base + MAC_REG_PSCFG, cxt_buf + MAC_REG_PSCFG, MAC_REG_BBREGCTL - MAC_REG_PSCFG); /* restore CURR_RX_DESC_ADDR, CURR_TX_DESC_ADDR */ iowrite32(*(u32 *)(cxt_buf + MAC_REG_TXDMAPTR0), io_base + MAC_REG_TXDMAPTR0); iowrite32(*(u32 *)(cxt_buf + MAC_REG_AC0DMAPTR), io_base + MAC_REG_AC0DMAPTR); iowrite32(*(u32 *)(cxt_buf + MAC_REG_BCNDMAPTR), io_base + MAC_REG_BCNDMAPTR); iowrite32(*(u32 *)(cxt_buf + MAC_REG_RXDMAPTR0), io_base + MAC_REG_RXDMAPTR0); iowrite32(*(u32 *)(cxt_buf + MAC_REG_RXDMAPTR1), io_base + MAC_REG_RXDMAPTR1); }
static void device_init_registers(struct vnt_private *pDevice) { unsigned long flags; unsigned int ii; unsigned char byValue; unsigned char byCCKPwrdBm = 0; unsigned char byOFDMPwrdBm = 0; MACbShutdown(pDevice->PortOffset); BBvSoftwareReset(pDevice); /* Do MACbSoftwareReset in MACvInitialize */ MACbSoftwareReset(pDevice->PortOffset); pDevice->bAES = false; /* Only used in 11g type, sync with ERP IE */ pDevice->bProtectMode = false; pDevice->bNonERPPresent = false; pDevice->bBarkerPreambleMd = false; pDevice->wCurrentRate = RATE_1M; pDevice->byTopOFDMBasicRate = RATE_24M; pDevice->byTopCCKBasicRate = RATE_1M; /* Target to IF pin while programming to RF chip. */ pDevice->byRevId = 0; /* init MAC */ MACvInitialize(pDevice->PortOffset); /* Get Local ID */ VNSvInPortB(pDevice->PortOffset + MAC_REG_LOCALID, &pDevice->byLocalID); spin_lock_irqsave(&pDevice->lock, flags); SROMvReadAllContents(pDevice->PortOffset, pDevice->abyEEPROM); spin_unlock_irqrestore(&pDevice->lock, flags); /* Get Channel range */ pDevice->byMinChannel = 1; pDevice->byMaxChannel = CB_MAX_CHANNEL; /* Get Antena */ byValue = SROMbyReadEmbedded(pDevice->PortOffset, EEP_OFS_ANTENNA); if (byValue & EEP_ANTINV) pDevice->bTxRxAntInv = true; else pDevice->bTxRxAntInv = false; byValue &= (EEP_ANTENNA_AUX | EEP_ANTENNA_MAIN); /* if not set default is All */ if (byValue == 0) byValue = (EEP_ANTENNA_AUX | EEP_ANTENNA_MAIN); if (byValue == (EEP_ANTENNA_AUX | EEP_ANTENNA_MAIN)) { pDevice->byAntennaCount = 2; pDevice->byTxAntennaMode = ANT_B; pDevice->dwTxAntennaSel = 1; pDevice->dwRxAntennaSel = 1; if (pDevice->bTxRxAntInv) pDevice->byRxAntennaMode = ANT_A; else pDevice->byRxAntennaMode = ANT_B; } else { pDevice->byAntennaCount = 1; pDevice->dwTxAntennaSel = 0; pDevice->dwRxAntennaSel = 0; if (byValue & EEP_ANTENNA_AUX) { pDevice->byTxAntennaMode = ANT_A; if (pDevice->bTxRxAntInv) pDevice->byRxAntennaMode = ANT_B; else pDevice->byRxAntennaMode = ANT_A; } else { pDevice->byTxAntennaMode = ANT_B; if (pDevice->bTxRxAntInv) pDevice->byRxAntennaMode = ANT_A; else pDevice->byRxAntennaMode = ANT_B; } } /* Set initial antenna mode */ BBvSetTxAntennaMode(pDevice, pDevice->byTxAntennaMode); BBvSetRxAntennaMode(pDevice, pDevice->byRxAntennaMode); /* zonetype initial */ pDevice->byOriginalZonetype = pDevice->abyEEPROM[EEP_OFS_ZONETYPE]; /* Get RFType */ pDevice->byRFType = SROMbyReadEmbedded(pDevice->PortOffset, EEP_OFS_RFTYPE); /* force change RevID for VT3253 emu */ if ((pDevice->byRFType & RF_EMU) != 0) pDevice->byRevId = 0x80; pDevice->byRFType &= RF_MASK; pr_debug("pDevice->byRFType = %x\n", pDevice->byRFType); if (!pDevice->bZoneRegExist) pDevice->byZoneType = pDevice->abyEEPROM[EEP_OFS_ZONETYPE]; pr_debug("pDevice->byZoneType = %x\n", pDevice->byZoneType); /* Init RF module */ RFbInit(pDevice); /* Get Desire Power Value */ pDevice->byCurPwr = 0xFF; pDevice->byCCKPwr = SROMbyReadEmbedded(pDevice->PortOffset, EEP_OFS_PWR_CCK); pDevice->byOFDMPwrG = SROMbyReadEmbedded(pDevice->PortOffset, EEP_OFS_PWR_OFDMG); /* Load power Table */ for (ii = 0; ii < CB_MAX_CHANNEL_24G; ii++) { pDevice->abyCCKPwrTbl[ii + 1] = SROMbyReadEmbedded(pDevice->PortOffset, (unsigned char)(ii + EEP_OFS_CCK_PWR_TBL)); if (pDevice->abyCCKPwrTbl[ii + 1] == 0) pDevice->abyCCKPwrTbl[ii+1] = pDevice->byCCKPwr; pDevice->abyOFDMPwrTbl[ii + 1] = SROMbyReadEmbedded(pDevice->PortOffset, (unsigned char)(ii + EEP_OFS_OFDM_PWR_TBL)); if (pDevice->abyOFDMPwrTbl[ii + 1] == 0) pDevice->abyOFDMPwrTbl[ii + 1] = pDevice->byOFDMPwrG; pDevice->abyCCKDefaultPwr[ii + 1] = byCCKPwrdBm; pDevice->abyOFDMDefaultPwr[ii + 1] = byOFDMPwrdBm; } /* recover 12,13 ,14channel for EUROPE by 11 channel */ for (ii = 11; ii < 14; ii++) { pDevice->abyCCKPwrTbl[ii] = pDevice->abyCCKPwrTbl[10]; pDevice->abyOFDMPwrTbl[ii] = pDevice->abyOFDMPwrTbl[10]; } /* Load OFDM A Power Table */ for (ii = 0; ii < CB_MAX_CHANNEL_5G; ii++) { pDevice->abyOFDMPwrTbl[ii + CB_MAX_CHANNEL_24G + 1] = SROMbyReadEmbedded(pDevice->PortOffset, (unsigned char)(ii + EEP_OFS_OFDMA_PWR_TBL)); pDevice->abyOFDMDefaultPwr[ii + CB_MAX_CHANNEL_24G + 1] = SROMbyReadEmbedded(pDevice->PortOffset, (unsigned char)(ii + EEP_OFS_OFDMA_PWR_dBm)); } if (pDevice->byLocalID > REV_ID_VT3253_B1) { MACvSelectPage1(pDevice->PortOffset); VNSvOutPortB(pDevice->PortOffset + MAC_REG_MSRCTL + 1, (MSRCTL1_TXPWR | MSRCTL1_CSAPAREN)); MACvSelectPage0(pDevice->PortOffset); } /* use relative tx timeout and 802.11i D4 */ MACvWordRegBitsOn(pDevice->PortOffset, MAC_REG_CFG, (CFG_TKIPOPT | CFG_NOTXTIMEOUT)); /* set performance parameter by registry */ MACvSetShortRetryLimit(pDevice->PortOffset, pDevice->byShortRetryLimit); MACvSetLongRetryLimit(pDevice->PortOffset, pDevice->byLongRetryLimit); /* reset TSF counter */ VNSvOutPortB(pDevice->PortOffset + MAC_REG_TFTCTL, TFTCTL_TSFCNTRST); /* enable TSF counter */ VNSvOutPortB(pDevice->PortOffset + MAC_REG_TFTCTL, TFTCTL_TSFCNTREN); /* initialize BBP registers */ BBbVT3253Init(pDevice); if (pDevice->bUpdateBBVGA) { pDevice->byBBVGACurrent = pDevice->abyBBVGA[0]; pDevice->byBBVGANew = pDevice->byBBVGACurrent; BBvSetVGAGainOffset(pDevice, pDevice->abyBBVGA[0]); } BBvSetRxAntennaMode(pDevice, pDevice->byRxAntennaMode); BBvSetTxAntennaMode(pDevice, pDevice->byTxAntennaMode); /* Set BB and packet type at the same time. */ /* Set Short Slot Time, xIFS, and RSPINF. */ pDevice->wCurrentRate = RATE_54M; pDevice->bRadioOff = false; pDevice->byRadioCtl = SROMbyReadEmbedded(pDevice->PortOffset, EEP_OFS_RADIOCTL); pDevice->bHWRadioOff = false; if (pDevice->byRadioCtl & EEP_RADIOCTL_ENABLE) { /* Get GPIO */ MACvGPIOIn(pDevice->PortOffset, &pDevice->byGPIO); if (((pDevice->byGPIO & GPIO0_DATA) && !(pDevice->byRadioCtl & EEP_RADIOCTL_INV)) || (!(pDevice->byGPIO & GPIO0_DATA) && (pDevice->byRadioCtl & EEP_RADIOCTL_INV))) pDevice->bHWRadioOff = true; } if (pDevice->bHWRadioOff || pDevice->bRadioControlOff) CARDbRadioPowerOff(pDevice); /* get Permanent network address */ SROMvReadEtherAddress(pDevice->PortOffset, pDevice->abyCurrentNetAddr); pr_debug("Network address = %pM\n", pDevice->abyCurrentNetAddr); /* reset Tx pointer */ CARDvSafeResetRx(pDevice); /* reset Rx pointer */ CARDvSafeResetTx(pDevice); if (pDevice->byLocalID <= REV_ID_VT3253_A1) MACvRegBitsOn(pDevice->PortOffset, MAC_REG_RCR, RCR_WPAERR); /* Turn On Rx DMA */ MACvReceive0(pDevice->PortOffset); MACvReceive1(pDevice->PortOffset); /* start the adapter */ MACvStart(pDevice->PortOffset); }
static irqreturn_t device_intr(int irq, void *dev_instance) { struct vnt_private *pDevice = dev_instance; int max_count = 0; unsigned long dwMIBCounter = 0; unsigned char byOrgPageSel = 0; int handled = 0; unsigned long flags; MACvReadISR(pDevice->PortOffset, &pDevice->dwIsr); if (pDevice->dwIsr == 0) return IRQ_RETVAL(handled); if (pDevice->dwIsr == 0xffffffff) { pr_debug("dwIsr = 0xffff\n"); return IRQ_RETVAL(handled); } handled = 1; MACvIntDisable(pDevice->PortOffset); spin_lock_irqsave(&pDevice->lock, flags); //Make sure current page is 0 VNSvInPortB(pDevice->PortOffset + MAC_REG_PAGE1SEL, &byOrgPageSel); if (byOrgPageSel == 1) MACvSelectPage0(pDevice->PortOffset); else byOrgPageSel = 0; MACvReadMIBCounter(pDevice->PortOffset, &dwMIBCounter); // TBD.... // Must do this after doing rx/tx, cause ISR bit is slow // than RD/TD write back // update ISR counter STAvUpdate802_11Counter(&pDevice->s802_11Counter, &pDevice->scStatistic, dwMIBCounter); while (pDevice->dwIsr != 0) { STAvUpdateIsrStatCounter(&pDevice->scStatistic, pDevice->dwIsr); MACvWriteISR(pDevice->PortOffset, pDevice->dwIsr); if (pDevice->dwIsr & ISR_FETALERR) { pr_debug(" ISR_FETALERR\n"); VNSvOutPortB(pDevice->PortOffset + MAC_REG_SOFTPWRCTL, 0); VNSvOutPortW(pDevice->PortOffset + MAC_REG_SOFTPWRCTL, SOFTPWRCTL_SWPECTI); device_error(pDevice, pDevice->dwIsr); } if (pDevice->dwIsr & ISR_TBTT) { if (pDevice->vif && pDevice->op_mode != NL80211_IFTYPE_ADHOC) vnt_check_bb_vga(pDevice); pDevice->bBeaconSent = false; if (pDevice->bEnablePSMode) PSbIsNextTBTTWakeUp((void *)pDevice); if ((pDevice->op_mode == NL80211_IFTYPE_AP || pDevice->op_mode == NL80211_IFTYPE_ADHOC) && pDevice->vif->bss_conf.enable_beacon) { MACvOneShotTimer1MicroSec(pDevice->PortOffset, (pDevice->vif->bss_conf.beacon_int - MAKE_BEACON_RESERVED) << 10); } /* TODO: adhoc PS mode */ } if (pDevice->dwIsr & ISR_BNTX) { if (pDevice->op_mode == NL80211_IFTYPE_ADHOC) { pDevice->bIsBeaconBufReadySet = false; pDevice->cbBeaconBufReadySetCnt = 0; } pDevice->bBeaconSent = true; } if (pDevice->dwIsr & ISR_RXDMA0) max_count += device_rx_srv(pDevice, TYPE_RXDMA0); if (pDevice->dwIsr & ISR_RXDMA1) max_count += device_rx_srv(pDevice, TYPE_RXDMA1); if (pDevice->dwIsr & ISR_TXDMA0) max_count += device_tx_srv(pDevice, TYPE_TXDMA0); if (pDevice->dwIsr & ISR_AC0DMA) max_count += device_tx_srv(pDevice, TYPE_AC0DMA); if (pDevice->dwIsr & ISR_SOFTTIMER1) { if (pDevice->vif) { if (pDevice->vif->bss_conf.enable_beacon) vnt_beacon_make(pDevice, pDevice->vif); } } /* If both buffers available wake the queue */ if (pDevice->vif) { if (AVAIL_TD(pDevice, TYPE_TXDMA0) && AVAIL_TD(pDevice, TYPE_AC0DMA) && ieee80211_queue_stopped(pDevice->hw, 0)) ieee80211_wake_queues(pDevice->hw); } MACvReadISR(pDevice->PortOffset, &pDevice->dwIsr); MACvReceive0(pDevice->PortOffset); MACvReceive1(pDevice->PortOffset); if (max_count > pDevice->sOpts.int_works) break; } if (byOrgPageSel == 1) MACvSelectPage1(pDevice->PortOffset); spin_unlock_irqrestore(&pDevice->lock, flags); MACvIntEnable(pDevice->PortOffset, IMR_MASK_VALUE); return IRQ_RETVAL(handled); }