| /* |
| * Copyright (c) 1996, 2003 VIA Networking Technologies, Inc. |
| * All rights reserved. |
| * |
| * 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., |
| * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. |
| * |
| * |
| * File: mac.c |
| * |
| * Purpose: MAC routines |
| * |
| * Author: Tevin Chen |
| * |
| * Date: May 21, 1996 |
| * |
| * Functions: |
| * MACvReadAllRegs - Read All MAC Registers to buffer |
| * MACbIsRegBitsOn - Test if All test Bits On |
| * MACbIsRegBitsOff - Test if All test Bits Off |
| * MACbIsIntDisable - Test if MAC interrupt disable |
| * MACbyReadMultiAddr - Read Multicast Address Mask Pattern |
| * MACvWriteMultiAddr - Write Multicast Address Mask Pattern |
| * MACvSetMultiAddrByHash - Set Multicast Address Mask by Hash value |
| * MACvResetMultiAddrByHash - Clear Multicast Address Mask by Hash value |
| * MACvSetRxThreshold - Set Rx Threshold value |
| * MACvGetRxThreshold - Get Rx Threshold value |
| * MACvSetTxThreshold - Set Tx Threshold value |
| * MACvGetTxThreshold - Get Tx Threshold value |
| * MACvSetDmaLength - Set Dma Length value |
| * MACvGetDmaLength - Get Dma Length value |
| * MACvSetShortRetryLimit - Set 802.11 Short Retry limit |
| * MACvGetShortRetryLimit - Get 802.11 Short Retry limit |
| * MACvSetLongRetryLimit - Set 802.11 Long Retry limit |
| * MACvGetLongRetryLimit - Get 802.11 Long Retry limit |
| * MACvSetLoopbackMode - Set MAC Loopback Mode |
| * MACbIsInLoopbackMode - Test if MAC in Loopback mode |
| * MACvSetPacketFilter - Set MAC Address Filter |
| * MACvSaveContext - Save Context of MAC Registers |
| * MACvRestoreContext - Restore Context of MAC Registers |
| * MACbCompareContext - Compare if values of MAC Registers same as Context |
| * MACbSoftwareReset - Software Reset MAC |
| * MACbSafeRxOff - Turn Off MAC Rx |
| * MACbSafeTxOff - Turn Off MAC Tx |
| * MACbSafeStop - Stop MAC function |
| * MACbShutdown - Shut down MAC |
| * MACvInitialize - Initialize MAC |
| * MACvSetCurrRxDescAddr - Set Rx Descriptors Address |
| * MACvSetCurrTx0DescAddr - Set Tx0 Descriptors Address |
| * MACvSetCurrTx1DescAddr - Set Tx1 Descriptors Address |
| * MACvTimer0MicroSDelay - Micro Second Delay Loop by MAC |
| * |
| * Revision History: |
| * 08-22-2003 Kyle Hsu : Porting MAC functions from sim53 |
| * 09-03-2003 Bryan YC Fan : Add MACvClearBusSusInd()& MACvEnableBusSusEn() |
| * 09-18-2003 Jerry Chen : Add MACvSetKeyEntry & MACvDisableKeyEntry |
| * |
| */ |
| |
| #include "tmacro.h" |
| #include "tether.h" |
| #include "mac.h" |
| |
| unsigned short TxRate_iwconfig;//2008-5-8 <add> by chester |
| /*--------------------- Static Definitions -------------------------*/ |
| static int msglevel = MSG_LEVEL_INFO; |
| /*--------------------- Static Classes ----------------------------*/ |
| |
| /*--------------------- Static Variables --------------------------*/ |
| |
| /*--------------------- Static Functions --------------------------*/ |
| |
| /*--------------------- Export Variables --------------------------*/ |
| |
| /*--------------------- Export Functions --------------------------*/ |
| |
| /* |
| * Description: |
| * Read All MAC Registers to buffer |
| * |
| * Parameters: |
| * In: |
| * dwIoBase - Base Address for MAC |
| * Out: |
| * pbyMacRegs - buffer to read |
| * |
| * Return Value: none |
| * |
| */ |
| void MACvReadAllRegs(unsigned long dwIoBase, unsigned char *pbyMacRegs) |
| { |
| int ii; |
| |
| // read page0 register |
| for (ii = 0; ii < MAC_MAX_CONTEXT_SIZE_PAGE0; ii++) { |
| VNSvInPortB(dwIoBase + ii, pbyMacRegs); |
| pbyMacRegs++; |
| } |
| |
| MACvSelectPage1(dwIoBase); |
| |
| // read page1 register |
| for (ii = 0; ii < MAC_MAX_CONTEXT_SIZE_PAGE1; ii++) { |
| VNSvInPortB(dwIoBase + ii, pbyMacRegs); |
| pbyMacRegs++; |
| } |
| |
| MACvSelectPage0(dwIoBase); |
| } |
| |
| /* |
| * Description: |
| * Test if all test bits on |
| * |
| * Parameters: |
| * In: |
| * dwIoBase - Base Address for MAC |
| * byRegOfs - Offset of MAC Register |
| * byTestBits - Test bits |
| * Out: |
| * none |
| * |
| * Return Value: true if all test bits On; otherwise false |
| * |
| */ |
| bool MACbIsRegBitsOn(unsigned long dwIoBase, unsigned char byRegOfs, unsigned char byTestBits) |
| { |
| unsigned char byData; |
| |
| VNSvInPortB(dwIoBase + byRegOfs, &byData); |
| return (byData & byTestBits) == byTestBits; |
| } |
| |
| /* |
| * Description: |
| * Test if all test bits off |
| * |
| * Parameters: |
| * In: |
| * dwIoBase - Base Address for MAC |
| * byRegOfs - Offset of MAC Register |
| * byTestBits - Test bits |
| * Out: |
| * none |
| * |
| * Return Value: true if all test bits Off; otherwise false |
| * |
| */ |
| bool MACbIsRegBitsOff(unsigned long dwIoBase, unsigned char byRegOfs, unsigned char byTestBits) |
| { |
| unsigned char byData; |
| |
| VNSvInPortB(dwIoBase + byRegOfs, &byData); |
| return !(byData & byTestBits); |
| } |
| |
| /* |
| * Description: |
| * Test if MAC interrupt disable |
| * |
| * Parameters: |
| * In: |
| * dwIoBase - Base Address for MAC |
| * Out: |
| * none |
| * |
| * Return Value: true if interrupt is disable; otherwise false |
| * |
| */ |
| bool MACbIsIntDisable(unsigned long dwIoBase) |
| { |
| unsigned long dwData; |
| |
| VNSvInPortD(dwIoBase + MAC_REG_IMR, &dwData); |
| if (dwData != 0) |
| return false; |
| |
| return true; |
| } |
| |
| /* |
| * Description: |
| * Read MAC Multicast Address Mask |
| * |
| * Parameters: |
| * In: |
| * dwIoBase - Base Address for MAC |
| * uByteidx - Index of Mask |
| * Out: |
| * none |
| * |
| * Return Value: Mask Value read |
| * |
| */ |
| unsigned char MACbyReadMultiAddr(unsigned long dwIoBase, unsigned int uByteIdx) |
| { |
| unsigned char byData; |
| |
| MACvSelectPage1(dwIoBase); |
| VNSvInPortB(dwIoBase + MAC_REG_MAR0 + uByteIdx, &byData); |
| MACvSelectPage0(dwIoBase); |
| return byData; |
| } |
| |
| /* |
| * Description: |
| * Write MAC Multicast Address Mask |
| * |
| * Parameters: |
| * In: |
| * dwIoBase - Base Address for MAC |
| * uByteidx - Index of Mask |
| * byData - Mask Value to write |
| * Out: |
| * none |
| * |
| * Return Value: none |
| * |
| */ |
| void MACvWriteMultiAddr(unsigned long dwIoBase, unsigned int uByteIdx, unsigned char byData) |
| { |
| MACvSelectPage1(dwIoBase); |
| VNSvOutPortB(dwIoBase + MAC_REG_MAR0 + uByteIdx, byData); |
| MACvSelectPage0(dwIoBase); |
| } |
| |
| /* |
| * Description: |
| * Set this hash index into multicast address register bit |
| * |
| * Parameters: |
| * In: |
| * dwIoBase - Base Address for MAC |
| * byHashIdx - Hash index to set |
| * Out: |
| * none |
| * |
| * Return Value: none |
| * |
| */ |
| void MACvSetMultiAddrByHash(unsigned long dwIoBase, unsigned char byHashIdx) |
| { |
| unsigned int uByteIdx; |
| unsigned char byBitMask; |
| unsigned char byOrgValue; |
| |
| // calculate byte position |
| uByteIdx = byHashIdx / 8; |
| ASSERT(uByteIdx < 8); |
| // calculate bit position |
| byBitMask = 1; |
| byBitMask <<= (byHashIdx % 8); |
| // turn on the bit |
| byOrgValue = MACbyReadMultiAddr(dwIoBase, uByteIdx); |
| MACvWriteMultiAddr(dwIoBase, uByteIdx, (unsigned char)(byOrgValue | byBitMask)); |
| } |
| |
| /* |
| * Description: |
| * Reset this hash index into multicast address register bit |
| * |
| * Parameters: |
| * In: |
| * dwIoBase - Base Address for MAC |
| * byHashIdx - Hash index to clear |
| * Out: |
| * none |
| * |
| * Return Value: none |
| * |
| */ |
| void MACvResetMultiAddrByHash(unsigned long dwIoBase, unsigned char byHashIdx) |
| { |
| unsigned int uByteIdx; |
| unsigned char byBitMask; |
| unsigned char byOrgValue; |
| |
| // calculate byte position |
| uByteIdx = byHashIdx / 8; |
| ASSERT(uByteIdx < 8); |
| // calculate bit position |
| byBitMask = 1; |
| byBitMask <<= (byHashIdx % 8); |
| // turn off the bit |
| byOrgValue = MACbyReadMultiAddr(dwIoBase, uByteIdx); |
| MACvWriteMultiAddr(dwIoBase, uByteIdx, (unsigned char)(byOrgValue & (~byBitMask))); |
| } |
| |
| /* |
| * Description: |
| * Set Rx Threshold |
| * |
| * Parameters: |
| * In: |
| * dwIoBase - Base Address for MAC |
| * byThreshold - Threshold Value |
| * Out: |
| * none |
| * |
| * Return Value: none |
| * |
| */ |
| void MACvSetRxThreshold(unsigned long dwIoBase, unsigned char byThreshold) |
| { |
| unsigned char byOrgValue; |
| |
| ASSERT(byThreshold < 4); |
| |
| // set FCR0 |
| VNSvInPortB(dwIoBase + MAC_REG_FCR0, &byOrgValue); |
| byOrgValue = (byOrgValue & 0xCF) | (byThreshold << 4); |
| VNSvOutPortB(dwIoBase + MAC_REG_FCR0, byOrgValue); |
| } |
| |
| /* |
| * Description: |
| * Get Rx Threshold |
| * |
| * Parameters: |
| * In: |
| * dwIoBase - Base Address for MAC |
| * Out: |
| * pbyThreshold- Threshold Value Get |
| * |
| * Return Value: none |
| * |
| */ |
| void MACvGetRxThreshold(unsigned long dwIoBase, unsigned char *pbyThreshold) |
| { |
| // get FCR0 |
| VNSvInPortB(dwIoBase + MAC_REG_FCR0, pbyThreshold); |
| *pbyThreshold = (*pbyThreshold >> 4) & 0x03; |
| } |
| |
| /* |
| * Description: |
| * Set Tx Threshold |
| * |
| * Parameters: |
| * In: |
| * dwIoBase - Base Address for MAC |
| * byThreshold - Threshold Value |
| * Out: |
| * none |
| * |
| * Return Value: none |
| * |
| */ |
| void MACvSetTxThreshold(unsigned long dwIoBase, unsigned char byThreshold) |
| { |
| unsigned char byOrgValue; |
| |
| ASSERT(byThreshold < 4); |
| |
| // set FCR0 |
| VNSvInPortB(dwIoBase + MAC_REG_FCR0, &byOrgValue); |
| byOrgValue = (byOrgValue & 0xF3) | (byThreshold << 2); |
| VNSvOutPortB(dwIoBase + MAC_REG_FCR0, byOrgValue); |
| } |
| |
| /* |
| * Description: |
| * Get Tx Threshold |
| * |
| * Parameters: |
| * In: |
| * dwIoBase - Base Address for MAC |
| * Out: |
| * pbyThreshold- Threshold Value Get |
| * |
| * Return Value: none |
| * |
| */ |
| void MACvGetTxThreshold(unsigned long dwIoBase, unsigned char *pbyThreshold) |
| { |
| // get FCR0 |
| VNSvInPortB(dwIoBase + MAC_REG_FCR0, pbyThreshold); |
| *pbyThreshold = (*pbyThreshold >> 2) & 0x03; |
| } |
| |
| /* |
| * Description: |
| * Set Dma Length |
| * |
| * Parameters: |
| * In: |
| * dwIoBase - Base Address for MAC |
| * byDmaLength - Dma Length Value |
| * Out: |
| * none |
| * |
| * Return Value: none |
| * |
| */ |
| void MACvSetDmaLength(unsigned long dwIoBase, unsigned char byDmaLength) |
| { |
| unsigned char byOrgValue; |
| |
| ASSERT(byDmaLength < 4); |
| |
| // set FCR0 |
| VNSvInPortB(dwIoBase + MAC_REG_FCR0, &byOrgValue); |
| byOrgValue = (byOrgValue & 0xFC) | byDmaLength; |
| VNSvOutPortB(dwIoBase + MAC_REG_FCR0, byOrgValue); |
| } |
| |
| /* |
| * Description: |
| * Get Dma Length |
| * |
| * Parameters: |
| * In: |
| * dwIoBase - Base Address for MAC |
| * Out: |
| * pbyDmaLength- Dma Length Value Get |
| * |
| * Return Value: none |
| * |
| */ |
| void MACvGetDmaLength(unsigned long dwIoBase, unsigned char *pbyDmaLength) |
| { |
| // get FCR0 |
| VNSvInPortB(dwIoBase + MAC_REG_FCR0, pbyDmaLength); |
| *pbyDmaLength &= 0x03; |
| } |
| |
| /* |
| * Description: |
| * Set 802.11 Short Retry Limit |
| * |
| * Parameters: |
| * In: |
| * dwIoBase - Base Address for MAC |
| * byRetryLimit- Retry Limit |
| * Out: |
| * none |
| * |
| * Return Value: none |
| * |
| */ |
| void MACvSetShortRetryLimit(unsigned long dwIoBase, unsigned char byRetryLimit) |
| { |
| // set SRT |
| VNSvOutPortB(dwIoBase + MAC_REG_SRT, byRetryLimit); |
| } |
| |
| /* |
| * Description: |
| * Get 802.11 Short Retry Limit |
| * |
| * Parameters: |
| * In: |
| * dwIoBase - Base Address for MAC |
| * Out: |
| * pbyRetryLimit - Retry Limit Get |
| * |
| * Return Value: none |
| * |
| */ |
| void MACvGetShortRetryLimit(unsigned long dwIoBase, unsigned char *pbyRetryLimit) |
| { |
| // get SRT |
| VNSvInPortB(dwIoBase + MAC_REG_SRT, pbyRetryLimit); |
| } |
| |
| /* |
| * Description: |
| * Set 802.11 Long Retry Limit |
| * |
| * Parameters: |
| * In: |
| * dwIoBase - Base Address for MAC |
| * byRetryLimit- Retry Limit |
| * Out: |
| * none |
| * |
| * Return Value: none |
| * |
| */ |
| void MACvSetLongRetryLimit(unsigned long dwIoBase, unsigned char byRetryLimit) |
| { |
| // set LRT |
| VNSvOutPortB(dwIoBase + MAC_REG_LRT, byRetryLimit); |
| } |
| |
| /* |
| * Description: |
| * Get 802.11 Long Retry Limit |
| * |
| * Parameters: |
| * In: |
| * dwIoBase - Base Address for MAC |
| * Out: |
| * pbyRetryLimit - Retry Limit Get |
| * |
| * Return Value: none |
| * |
| */ |
| void MACvGetLongRetryLimit(unsigned long dwIoBase, unsigned char *pbyRetryLimit) |
| { |
| // get LRT |
| VNSvInPortB(dwIoBase + MAC_REG_LRT, pbyRetryLimit); |
| } |
| |
| /* |
| * Description: |
| * Set MAC Loopback mode |
| * |
| * Parameters: |
| * In: |
| * dwIoBase - Base Address for MAC |
| * byLoopbackMode - Loopback Mode |
| * Out: |
| * none |
| * |
| * Return Value: none |
| * |
| */ |
| void MACvSetLoopbackMode(unsigned long dwIoBase, unsigned char byLoopbackMode) |
| { |
| unsigned char byOrgValue; |
| |
| ASSERT(byLoopbackMode < 3); |
| byLoopbackMode <<= 6; |
| // set TCR |
| VNSvInPortB(dwIoBase + MAC_REG_TEST, &byOrgValue); |
| byOrgValue = byOrgValue & 0x3F; |
| byOrgValue = byOrgValue | byLoopbackMode; |
| VNSvOutPortB(dwIoBase + MAC_REG_TEST, byOrgValue); |
| } |
| |
| /* |
| * Description: |
| * Test if MAC in Loopback mode |
| * |
| * Parameters: |
| * In: |
| * dwIoBase - Base Address for MAC |
| * Out: |
| * none |
| * |
| * Return Value: true if in Loopback mode; otherwise false |
| * |
| */ |
| bool MACbIsInLoopbackMode(unsigned long dwIoBase) |
| { |
| unsigned char byOrgValue; |
| |
| VNSvInPortB(dwIoBase + MAC_REG_TEST, &byOrgValue); |
| if (byOrgValue & (TEST_LBINT | TEST_LBEXT)) |
| return true; |
| return false; |
| } |
| |
| /* |
| * Description: |
| * Set MAC Address filter |
| * |
| * Parameters: |
| * In: |
| * dwIoBase - Base Address for MAC |
| * wFilterType - Filter Type |
| * Out: |
| * none |
| * |
| * Return Value: none |
| * |
| */ |
| void MACvSetPacketFilter(unsigned long dwIoBase, unsigned short wFilterType) |
| { |
| unsigned char byOldRCR; |
| unsigned char byNewRCR = 0; |
| |
| // 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 (wFilterType & PKT_TYPE_DIRECTED) { |
| // set multicast address to accept none |
| MACvSelectPage1(dwIoBase); |
| VNSvOutPortD(dwIoBase + MAC_REG_MAR0, 0L); |
| VNSvOutPortD(dwIoBase + MAC_REG_MAR0 + sizeof(unsigned long), 0L); |
| MACvSelectPage0(dwIoBase); |
| } |
| |
| if (wFilterType & (PKT_TYPE_PROMISCUOUS | PKT_TYPE_ALL_MULTICAST)) { |
| // set multicast address to accept all |
| MACvSelectPage1(dwIoBase); |
| VNSvOutPortD(dwIoBase + MAC_REG_MAR0, 0xFFFFFFFFL); |
| VNSvOutPortD(dwIoBase + MAC_REG_MAR0 + sizeof(unsigned long), 0xFFFFFFFFL); |
| MACvSelectPage0(dwIoBase); |
| } |
| |
| if (wFilterType & PKT_TYPE_PROMISCUOUS) { |
| byNewRCR |= (RCR_RXALLTYPE | RCR_UNICAST | RCR_MULTICAST | RCR_BROADCAST); |
| |
| byNewRCR &= ~RCR_BSSID; |
| } |
| |
| if (wFilterType & (PKT_TYPE_ALL_MULTICAST | PKT_TYPE_MULTICAST)) |
| byNewRCR |= RCR_MULTICAST; |
| |
| if (wFilterType & PKT_TYPE_BROADCAST) |
| byNewRCR |= RCR_BROADCAST; |
| |
| if (wFilterType & PKT_TYPE_ERROR_CRC) |
| byNewRCR |= RCR_ERRCRC; |
| |
| VNSvInPortB(dwIoBase + MAC_REG_RCR, &byOldRCR); |
| if (byNewRCR != byOldRCR) { |
| // Modify the Receive Command Register |
| VNSvOutPortB(dwIoBase + MAC_REG_RCR, byNewRCR); |
| } |
| } |
| |
| /* |
| * Description: |
| * Save MAC registers to context buffer |
| * |
| * Parameters: |
| * In: |
| * dwIoBase - Base Address for MAC |
| * Out: |
| * pbyCxtBuf - Context buffer |
| * |
| * Return Value: none |
| * |
| */ |
| void MACvSaveContext(unsigned long 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: |
| * dwIoBase - Base Address for MAC |
| * pbyCxtBuf - Context buffer |
| * Out: |
| * none |
| * |
| * Return Value: none |
| * |
| */ |
| void MACvRestoreContext(unsigned long 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)); |
| } |
| |
| /* |
| * Description: |
| * Compare if MAC registers same as context buffer |
| * |
| * Parameters: |
| * In: |
| * dwIoBase - Base Address for MAC |
| * pbyCxtBuf - Context buffer |
| * Out: |
| * none |
| * |
| * Return Value: true if all values are the same; otherwise false |
| * |
| */ |
| bool MACbCompareContext(unsigned long dwIoBase, unsigned char *pbyCxtBuf) |
| { |
| unsigned long dwData; |
| |
| // compare MAC context to determine if this is a power lost init, |
| // return true for power remaining init, return false for power lost init |
| |
| // compare CURR_RX_DESC_ADDR, CURR_TX_DESC_ADDR |
| VNSvInPortD(dwIoBase + MAC_REG_TXDMAPTR0, &dwData); |
| if (dwData != *(unsigned long *)(pbyCxtBuf + MAC_REG_TXDMAPTR0)) |
| return false; |
| |
| VNSvInPortD(dwIoBase + MAC_REG_AC0DMAPTR, &dwData); |
| if (dwData != *(unsigned long *)(pbyCxtBuf + MAC_REG_AC0DMAPTR)) |
| return false; |
| |
| VNSvInPortD(dwIoBase + MAC_REG_RXDMAPTR0, &dwData); |
| if (dwData != *(unsigned long *)(pbyCxtBuf + MAC_REG_RXDMAPTR0)) |
| return false; |
| |
| VNSvInPortD(dwIoBase + MAC_REG_RXDMAPTR1, &dwData); |
| if (dwData != *(unsigned long *)(pbyCxtBuf + MAC_REG_RXDMAPTR1)) |
| return false; |
| |
| return true; |
| } |
| |
| /* |
| * Description: |
| * Software Reset MAC |
| * |
| * Parameters: |
| * In: |
| * dwIoBase - Base Address for MAC |
| * Out: |
| * none |
| * |
| * Return Value: true if Reset Success; otherwise false |
| * |
| */ |
| bool MACbSoftwareReset(unsigned long dwIoBase) |
| { |
| unsigned char byData; |
| unsigned short ww; |
| |
| // turn on HOSTCR_SOFTRST, just write 0x01 to reset |
| VNSvOutPortB(dwIoBase + MAC_REG_HOSTCR, 0x01); |
| |
| for (ww = 0; ww < W_MAX_TIMEOUT; ww++) { |
| VNSvInPortB(dwIoBase + MAC_REG_HOSTCR, &byData); |
| if (!(byData & HOSTCR_SOFTRST)) |
| break; |
| } |
| if (ww == W_MAX_TIMEOUT) |
| return false; |
| return true; |
| } |
| |
| /* |
| * Description: |
| * save some important register's value, then do reset, then restore register's value |
| * |
| * Parameters: |
| * In: |
| * dwIoBase - Base Address for MAC |
| * Out: |
| * none |
| * |
| * Return Value: true if success; otherwise false |
| * |
| */ |
| bool MACbSafeSoftwareReset(unsigned long dwIoBase) |
| { |
| unsigned char abyTmpRegData[MAC_MAX_CONTEXT_SIZE_PAGE0+MAC_MAX_CONTEXT_SIZE_PAGE1]; |
| bool bRetVal; |
| |
| // PATCH.... |
| // save some important register's value, then do |
| // reset, then restore register's value |
| |
| // save MAC context |
| MACvSaveContext(dwIoBase, abyTmpRegData); |
| // do reset |
| bRetVal = MACbSoftwareReset(dwIoBase); |
| // restore MAC context, except CR0 |
| MACvRestoreContext(dwIoBase, abyTmpRegData); |
| |
| return bRetVal; |
| } |
| |
| /* |
| * Description: |
| * Trun Off MAC Rx |
| * |
| * Parameters: |
| * In: |
| * dwIoBase - Base Address for MAC |
| * Out: |
| * none |
| * |
| * Return Value: true if success; otherwise false |
| * |
| */ |
| bool MACbSafeRxOff(unsigned long dwIoBase) |
| { |
| unsigned short ww; |
| unsigned long dwData; |
| unsigned char byData; |
| |
| // turn off wow temp for turn off Rx safely |
| |
| // Clear RX DMA0,1 |
| VNSvOutPortD(dwIoBase + MAC_REG_RXDMACTL0, DMACTL_CLRRUN); |
| VNSvOutPortD(dwIoBase + MAC_REG_RXDMACTL1, DMACTL_CLRRUN); |
| for (ww = 0; ww < W_MAX_TIMEOUT; ww++) { |
| VNSvInPortD(dwIoBase + MAC_REG_RXDMACTL0, &dwData); |
| if (!(dwData & DMACTL_RUN)) |
| break; |
| } |
| if (ww == W_MAX_TIMEOUT) { |
| DBG_PORT80(0x10); |
| DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " DBG_PORT80(0x10)\n"); |
| return false; |
| } |
| for (ww = 0; ww < W_MAX_TIMEOUT; ww++) { |
| VNSvInPortD(dwIoBase + MAC_REG_RXDMACTL1, &dwData); |
| if (!(dwData & DMACTL_RUN)) |
| break; |
| } |
| if (ww == W_MAX_TIMEOUT) { |
| DBG_PORT80(0x11); |
| DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " DBG_PORT80(0x11)\n"); |
| return false; |
| } |
| |
| // try to safe shutdown RX |
| MACvRegBitsOff(dwIoBase, MAC_REG_HOSTCR, HOSTCR_RXON); |
| // W_MAX_TIMEOUT is the timeout period |
| for (ww = 0; ww < W_MAX_TIMEOUT; ww++) { |
| VNSvInPortB(dwIoBase + MAC_REG_HOSTCR, &byData); |
| if (!(byData & HOSTCR_RXONST)) |
| break; |
| } |
| if (ww == W_MAX_TIMEOUT) { |
| DBG_PORT80(0x12); |
| DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " DBG_PORT80(0x12)\n"); |
| return false; |
| } |
| return true; |
| } |
| |
| /* |
| * Description: |
| * Trun Off MAC Tx |
| * |
| * Parameters: |
| * In: |
| * dwIoBase - Base Address for MAC |
| * Out: |
| * none |
| * |
| * Return Value: true if success; otherwise false |
| * |
| */ |
| bool MACbSafeTxOff(unsigned long dwIoBase) |
| { |
| unsigned short ww; |
| unsigned long dwData; |
| unsigned char byData; |
| |
| // Clear TX DMA |
| //Tx0 |
| VNSvOutPortD(dwIoBase + MAC_REG_TXDMACTL0, DMACTL_CLRRUN); |
| //AC0 |
| VNSvOutPortD(dwIoBase + MAC_REG_AC0DMACTL, DMACTL_CLRRUN); |
| |
| for (ww = 0; ww < W_MAX_TIMEOUT; ww++) { |
| VNSvInPortD(dwIoBase + MAC_REG_TXDMACTL0, &dwData); |
| if (!(dwData & DMACTL_RUN)) |
| break; |
| } |
| if (ww == W_MAX_TIMEOUT) { |
| DBG_PORT80(0x20); |
| DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " DBG_PORT80(0x20)\n"); |
| return false; |
| } |
| for (ww = 0; ww < W_MAX_TIMEOUT; ww++) { |
| VNSvInPortD(dwIoBase + MAC_REG_AC0DMACTL, &dwData); |
| if (!(dwData & DMACTL_RUN)) |
| break; |
| } |
| if (ww == W_MAX_TIMEOUT) { |
| DBG_PORT80(0x21); |
| DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " DBG_PORT80(0x21)\n"); |
| return false; |
| } |
| |
| // try to safe shutdown TX |
| MACvRegBitsOff(dwIoBase, MAC_REG_HOSTCR, HOSTCR_TXON); |
| |
| // W_MAX_TIMEOUT is the timeout period |
| for (ww = 0; ww < W_MAX_TIMEOUT; ww++) { |
| VNSvInPortB(dwIoBase + MAC_REG_HOSTCR, &byData); |
| if (!(byData & HOSTCR_TXONST)) |
| break; |
| } |
| if (ww == W_MAX_TIMEOUT) { |
| DBG_PORT80(0x24); |
| DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " DBG_PORT80(0x24)\n"); |
| return false; |
| } |
| return true; |
| } |
| |
| /* |
| * Description: |
| * Stop MAC function |
| * |
| * Parameters: |
| * In: |
| * dwIoBase - Base Address for MAC |
| * Out: |
| * none |
| * |
| * Return Value: true if success; otherwise false |
| * |
| */ |
| bool MACbSafeStop(unsigned long dwIoBase) |
| { |
| MACvRegBitsOff(dwIoBase, MAC_REG_TCR, TCR_AUTOBCNTX); |
| |
| if (!MACbSafeRxOff(dwIoBase)) { |
| DBG_PORT80(0xA1); |
| DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " MACbSafeRxOff == false)\n"); |
| MACbSafeSoftwareReset(dwIoBase); |
| return false; |
| } |
| if (!MACbSafeTxOff(dwIoBase)) { |
| DBG_PORT80(0xA2); |
| DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " MACbSafeTxOff == false)\n"); |
| MACbSafeSoftwareReset(dwIoBase); |
| return false; |
| } |
| |
| MACvRegBitsOff(dwIoBase, MAC_REG_HOSTCR, HOSTCR_MACEN); |
| |
| return true; |
| } |
| |
| /* |
| * Description: |
| * Shut Down MAC |
| * |
| * Parameters: |
| * In: |
| * dwIoBase - Base Address for MAC |
| * Out: |
| * none |
| * |
| * Return Value: true if success; otherwise false |
| * |
| */ |
| bool MACbShutdown(unsigned long dwIoBase) |
| { |
| // disable MAC IMR |
| MACvIntDisable(dwIoBase); |
| MACvSetLoopbackMode(dwIoBase, MAC_LB_INTERNAL); |
| // stop the adapter |
| if (!MACbSafeStop(dwIoBase)) { |
| MACvSetLoopbackMode(dwIoBase, MAC_LB_NONE); |
| return false; |
| } |
| MACvSetLoopbackMode(dwIoBase, MAC_LB_NONE); |
| return true; |
| } |
| |
| /* |
| * Description: |
| * Initialize MAC |
| * |
| * Parameters: |
| * In: |
| * dwIoBase - Base Address for MAC |
| * Out: |
| * none |
| * |
| * Return Value: none |
| * |
| */ |
| void MACvInitialize(unsigned long 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); |
| |
| // set packet filter |
| // receive directed and broadcast address |
| |
| MACvSetPacketFilter(dwIoBase, PKT_TYPE_DIRECTED | PKT_TYPE_BROADCAST); |
| } |
| |
| /* |
| * Description: |
| * Set the chip with current rx descriptor address |
| * |
| * Parameters: |
| * In: |
| * dwIoBase - Base Address for MAC |
| * dwCurrDescAddr - Descriptor Address |
| * Out: |
| * none |
| * |
| * Return Value: none |
| * |
| */ |
| void MACvSetCurrRx0DescAddr(unsigned long dwIoBase, unsigned long dwCurrDescAddr) |
| { |
| unsigned short ww; |
| unsigned char byData; |
| unsigned char byOrgDMACtl; |
| |
| VNSvInPortB(dwIoBase + MAC_REG_RXDMACTL0, &byOrgDMACtl); |
| if (byOrgDMACtl & DMACTL_RUN) |
| VNSvOutPortB(dwIoBase + MAC_REG_RXDMACTL0+2, DMACTL_RUN); |
| |
| for (ww = 0; ww < W_MAX_TIMEOUT; ww++) { |
| VNSvInPortB(dwIoBase + MAC_REG_RXDMACTL0, &byData); |
| if (!(byData & DMACTL_RUN)) |
| break; |
| } |
| |
| if (ww == W_MAX_TIMEOUT) |
| DBG_PORT80(0x13); |
| |
| VNSvOutPortD(dwIoBase + MAC_REG_RXDMAPTR0, dwCurrDescAddr); |
| if (byOrgDMACtl & DMACTL_RUN) |
| VNSvOutPortB(dwIoBase + MAC_REG_RXDMACTL0, DMACTL_RUN); |
| } |
| |
| /* |
| * Description: |
| * Set the chip with current rx descriptor address |
| * |
| * Parameters: |
| * In: |
| * dwIoBase - Base Address for MAC |
| * dwCurrDescAddr - Descriptor Address |
| * Out: |
| * none |
| * |
| * Return Value: none |
| * |
| */ |
| void MACvSetCurrRx1DescAddr(unsigned long dwIoBase, unsigned long dwCurrDescAddr) |
| { |
| unsigned short ww; |
| unsigned char byData; |
| unsigned char byOrgDMACtl; |
| |
| VNSvInPortB(dwIoBase + MAC_REG_RXDMACTL1, &byOrgDMACtl); |
| if (byOrgDMACtl & DMACTL_RUN) |
| VNSvOutPortB(dwIoBase + MAC_REG_RXDMACTL1+2, DMACTL_RUN); |
| |
| for (ww = 0; ww < W_MAX_TIMEOUT; ww++) { |
| VNSvInPortB(dwIoBase + MAC_REG_RXDMACTL1, &byData); |
| if (!(byData & DMACTL_RUN)) |
| break; |
| } |
| if (ww == W_MAX_TIMEOUT) |
| DBG_PORT80(0x14); |
| |
| VNSvOutPortD(dwIoBase + MAC_REG_RXDMAPTR1, dwCurrDescAddr); |
| if (byOrgDMACtl & DMACTL_RUN) |
| VNSvOutPortB(dwIoBase + MAC_REG_RXDMACTL1, DMACTL_RUN); |
| |
| } |
| |
| /* |
| * Description: |
| * Set the chip with current tx0 descriptor address |
| * |
| * Parameters: |
| * In: |
| * dwIoBase - Base Address for MAC |
| * dwCurrDescAddr - Descriptor Address |
| * Out: |
| * none |
| * |
| * Return Value: none |
| * |
| */ |
| void MACvSetCurrTx0DescAddrEx(unsigned long dwIoBase, unsigned long dwCurrDescAddr) |
| { |
| unsigned short ww; |
| unsigned char byData; |
| unsigned char byOrgDMACtl; |
| |
| VNSvInPortB(dwIoBase + MAC_REG_TXDMACTL0, &byOrgDMACtl); |
| if (byOrgDMACtl & DMACTL_RUN) |
| VNSvOutPortB(dwIoBase + MAC_REG_TXDMACTL0+2, DMACTL_RUN); |
| |
| for (ww = 0; ww < W_MAX_TIMEOUT; ww++) { |
| VNSvInPortB(dwIoBase + MAC_REG_TXDMACTL0, &byData); |
| if (!(byData & DMACTL_RUN)) |
| break; |
| } |
| if (ww == W_MAX_TIMEOUT) |
| DBG_PORT80(0x25); |
| |
| VNSvOutPortD(dwIoBase + MAC_REG_TXDMAPTR0, dwCurrDescAddr); |
| if (byOrgDMACtl & DMACTL_RUN) |
| VNSvOutPortB(dwIoBase + MAC_REG_TXDMACTL0, DMACTL_RUN); |
| } |
| |
| /* |
| * Description: |
| * Set the chip with current AC0 descriptor address |
| * |
| * Parameters: |
| * In: |
| * dwIoBase - Base Address for MAC |
| * dwCurrDescAddr - Descriptor Address |
| * Out: |
| * none |
| * |
| * Return Value: none |
| * |
| */ |
| //TxDMA1 = AC0DMA |
| void MACvSetCurrAC0DescAddrEx(unsigned long dwIoBase, unsigned long dwCurrDescAddr) |
| { |
| unsigned short ww; |
| unsigned char byData; |
| unsigned char byOrgDMACtl; |
| |
| VNSvInPortB(dwIoBase + MAC_REG_AC0DMACTL, &byOrgDMACtl); |
| if (byOrgDMACtl & DMACTL_RUN) |
| VNSvOutPortB(dwIoBase + MAC_REG_AC0DMACTL+2, DMACTL_RUN); |
| |
| for (ww = 0; ww < W_MAX_TIMEOUT; ww++) { |
| VNSvInPortB(dwIoBase + MAC_REG_AC0DMACTL, &byData); |
| if (!(byData & DMACTL_RUN)) |
| break; |
| } |
| if (ww == W_MAX_TIMEOUT) { |
| DBG_PORT80(0x26); |
| DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " DBG_PORT80(0x26)\n"); |
| } |
| VNSvOutPortD(dwIoBase + MAC_REG_AC0DMAPTR, dwCurrDescAddr); |
| if (byOrgDMACtl & DMACTL_RUN) |
| VNSvOutPortB(dwIoBase + MAC_REG_AC0DMACTL, DMACTL_RUN); |
| } |
| |
| void MACvSetCurrTXDescAddr(int iTxType, unsigned long dwIoBase, unsigned long dwCurrDescAddr) |
| { |
| if (iTxType == TYPE_AC0DMA) |
| MACvSetCurrAC0DescAddrEx(dwIoBase, dwCurrDescAddr); |
| else if (iTxType == TYPE_TXDMA0) |
| MACvSetCurrTx0DescAddrEx(dwIoBase, dwCurrDescAddr); |
| } |
| |
| /* |
| * 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(unsigned long 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); |
| } |
| |
| /* |
| * Description: |
| * Micro Second One shot timer via MAC |
| * |
| * Parameters: |
| * In: |
| * dwIoBase - Base Address for MAC |
| * uDelay - Delay time |
| * Out: |
| * none |
| * |
| * Return Value: none |
| * |
| */ |
| void MACvOneShotTimer0MicroSec(unsigned long dwIoBase, unsigned int uDelayTime) |
| { |
| VNSvOutPortB(dwIoBase + MAC_REG_TMCTL0, 0); |
| VNSvOutPortD(dwIoBase + MAC_REG_TMDATA0, uDelayTime); |
| VNSvOutPortB(dwIoBase + MAC_REG_TMCTL0, (TMCTL_TMD | TMCTL_TE)); |
| } |
| |
| /* |
| * Description: |
| * Micro Second One shot timer via MAC |
| * |
| * Parameters: |
| * In: |
| * dwIoBase - Base Address for MAC |
| * uDelay - Delay time |
| * Out: |
| * none |
| * |
| * Return Value: none |
| * |
| */ |
| void MACvOneShotTimer1MicroSec(unsigned long dwIoBase, unsigned int uDelayTime) |
| { |
| VNSvOutPortB(dwIoBase + MAC_REG_TMCTL1, 0); |
| VNSvOutPortD(dwIoBase + MAC_REG_TMDATA1, uDelayTime); |
| VNSvOutPortB(dwIoBase + MAC_REG_TMCTL1, (TMCTL_TMD | TMCTL_TE)); |
| } |
| |
| void MACvSetMISCFifo(unsigned long dwIoBase, unsigned short wOffset, unsigned long dwData) |
| { |
| if (wOffset > 273) |
| return; |
| VNSvOutPortW(dwIoBase + MAC_REG_MISCFFNDEX, wOffset); |
| VNSvOutPortD(dwIoBase + MAC_REG_MISCFFDATA, dwData); |
| VNSvOutPortW(dwIoBase + MAC_REG_MISCFFCTL, MISCFFCTL_WRITE); |
| } |
| |
| bool MACbTxDMAOff(unsigned long dwIoBase, unsigned int idx) |
| { |
| unsigned char byData; |
| unsigned int ww = 0; |
| |
| if (idx == TYPE_TXDMA0) { |
| VNSvOutPortB(dwIoBase + MAC_REG_TXDMACTL0+2, DMACTL_RUN); |
| for (ww = 0; ww < W_MAX_TIMEOUT; ww++) { |
| VNSvInPortB(dwIoBase + MAC_REG_TXDMACTL0, &byData); |
| if (!(byData & DMACTL_RUN)) |
| break; |
| } |
| } else if (idx == TYPE_AC0DMA) { |
| VNSvOutPortB(dwIoBase + MAC_REG_AC0DMACTL+2, DMACTL_RUN); |
| for (ww = 0; ww < W_MAX_TIMEOUT; ww++) { |
| VNSvInPortB(dwIoBase + MAC_REG_AC0DMACTL, &byData); |
| if (!(byData & DMACTL_RUN)) |
| break; |
| } |
| } |
| if (ww == W_MAX_TIMEOUT) { |
| DBG_PORT80(0x29); |
| DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " DBG_PORT80(0x29)\n"); |
| return false; |
| } |
| return true; |
| } |
| |
| void MACvClearBusSusInd(unsigned long dwIoBase) |
| { |
| unsigned long dwOrgValue; |
| unsigned int ww; |
| // check if BcnSusInd enabled |
| VNSvInPortD(dwIoBase + MAC_REG_ENCFG , &dwOrgValue); |
| if (!(dwOrgValue & EnCFG_BcnSusInd)) |
| return; |
| //Set BcnSusClr |
| dwOrgValue = dwOrgValue | EnCFG_BcnSusClr; |
| VNSvOutPortD(dwIoBase + MAC_REG_ENCFG, dwOrgValue); |
| for (ww = 0; ww < W_MAX_TIMEOUT; ww++) { |
| VNSvInPortD(dwIoBase + MAC_REG_ENCFG , &dwOrgValue); |
| if (!(dwOrgValue & EnCFG_BcnSusInd)) |
| break; |
| } |
| if (ww == W_MAX_TIMEOUT) { |
| DBG_PORT80(0x33); |
| DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " DBG_PORT80(0x33)\n"); |
| } |
| } |
| |
| void MACvEnableBusSusEn(unsigned long dwIoBase) |
| { |
| unsigned char byOrgValue; |
| unsigned long dwOrgValue; |
| unsigned int ww; |
| // check if BcnSusInd enabled |
| VNSvInPortB(dwIoBase + MAC_REG_CFG , &byOrgValue); |
| |
| //Set BcnSusEn |
| byOrgValue = byOrgValue | CFG_BCNSUSEN; |
| VNSvOutPortB(dwIoBase + MAC_REG_ENCFG, byOrgValue); |
| for (ww = 0; ww < W_MAX_TIMEOUT; ww++) { |
| VNSvInPortD(dwIoBase + MAC_REG_ENCFG , &dwOrgValue); |
| if (dwOrgValue & EnCFG_BcnSusInd) |
| break; |
| } |
| if (ww == W_MAX_TIMEOUT) { |
| DBG_PORT80(0x34); |
| DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " DBG_PORT80(0x34)\n"); |
| } |
| } |
| |
| bool MACbFlushSYNCFifo(unsigned long dwIoBase) |
| { |
| unsigned char byOrgValue; |
| unsigned int ww; |
| // Read MACCR |
| VNSvInPortB(dwIoBase + MAC_REG_MACCR , &byOrgValue); |
| |
| // Set SYNCFLUSH |
| byOrgValue = byOrgValue | MACCR_SYNCFLUSH; |
| VNSvOutPortB(dwIoBase + MAC_REG_MACCR, byOrgValue); |
| |
| // Check if SyncFlushOK |
| for (ww = 0; ww < W_MAX_TIMEOUT; ww++) { |
| VNSvInPortB(dwIoBase + MAC_REG_MACCR , &byOrgValue); |
| if (byOrgValue & MACCR_SYNCFLUSHOK) |
| break; |
| } |
| if (ww == W_MAX_TIMEOUT) { |
| DBG_PORT80(0x35); |
| DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " DBG_PORT80(0x33)\n"); |
| } |
| return true; |
| } |
| |
| bool MACbPSWakeup(unsigned long dwIoBase) |
| { |
| unsigned char byOrgValue; |
| unsigned int ww; |
| // Read PSCTL |
| if (MACbIsRegBitsOff(dwIoBase, MAC_REG_PSCTL, PSCTL_PS)) |
| return true; |
| |
| // Disable PS |
| MACvRegBitsOff(dwIoBase, MAC_REG_PSCTL, PSCTL_PSEN); |
| |
| // Check if SyncFlushOK |
| for (ww = 0; ww < W_MAX_TIMEOUT; ww++) { |
| VNSvInPortB(dwIoBase + MAC_REG_PSCTL , &byOrgValue); |
| if (byOrgValue & PSCTL_WAKEDONE) |
| break; |
| } |
| if (ww == W_MAX_TIMEOUT) { |
| DBG_PORT80(0x36); |
| DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " DBG_PORT80(0x33)\n"); |
| return false; |
| } |
| return true; |
| } |
| |
| /* |
| * Description: |
| * Set the Key by MISCFIFO |
| * |
| * Parameters: |
| * In: |
| * dwIoBase - Base Address for MAC |
| * |
| * Out: |
| * none |
| * |
| * Return Value: none |
| * |
| */ |
| |
| void MACvSetKeyEntry(unsigned long dwIoBase, unsigned short wKeyCtl, unsigned int uEntryIdx, |
| unsigned int uKeyIdx, unsigned char *pbyAddr, u32 *pdwKey, unsigned char byLocalID) |
| { |
| unsigned short wOffset; |
| u32 dwData; |
| int ii; |
| |
| if (byLocalID <= 1) |
| return; |
| |
| DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "MACvSetKeyEntry\n"); |
| wOffset = MISCFIFO_KEYETRY0; |
| wOffset += (uEntryIdx * MISCFIFO_KEYENTRYSIZE); |
| |
| dwData = 0; |
| dwData |= wKeyCtl; |
| dwData <<= 16; |
| dwData |= MAKEWORD(*(pbyAddr+4), *(pbyAddr+5)); |
| DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "1. wOffset: %d, Data: %X, KeyCtl:%X\n", wOffset, dwData, wKeyCtl); |
| |
| VNSvOutPortW(dwIoBase + MAC_REG_MISCFFNDEX, wOffset); |
| VNSvOutPortD(dwIoBase + MAC_REG_MISCFFDATA, dwData); |
| VNSvOutPortW(dwIoBase + MAC_REG_MISCFFCTL, MISCFFCTL_WRITE); |
| wOffset++; |
| |
| dwData = 0; |
| dwData |= *(pbyAddr+3); |
| dwData <<= 8; |
| dwData |= *(pbyAddr+2); |
| dwData <<= 8; |
| dwData |= *(pbyAddr+1); |
| dwData <<= 8; |
| dwData |= *(pbyAddr+0); |
| DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "2. wOffset: %d, Data: %X\n", wOffset, dwData); |
| |
| VNSvOutPortW(dwIoBase + MAC_REG_MISCFFNDEX, wOffset); |
| VNSvOutPortD(dwIoBase + MAC_REG_MISCFFDATA, dwData); |
| VNSvOutPortW(dwIoBase + MAC_REG_MISCFFCTL, MISCFFCTL_WRITE); |
| wOffset++; |
| |
| wOffset += (uKeyIdx * 4); |
| for (ii = 0; ii < 4; ii++) { |
| // always push 128 bits |
| DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "3.(%d) wOffset: %d, Data: %X\n", ii, wOffset+ii, *pdwKey); |
| VNSvOutPortW(dwIoBase + MAC_REG_MISCFFNDEX, wOffset+ii); |
| VNSvOutPortD(dwIoBase + MAC_REG_MISCFFDATA, *pdwKey++); |
| VNSvOutPortW(dwIoBase + MAC_REG_MISCFFCTL, MISCFFCTL_WRITE); |
| } |
| } |
| |
| /* |
| * Description: |
| * Disable the Key Entry by MISCFIFO |
| * |
| * Parameters: |
| * In: |
| * dwIoBase - Base Address for MAC |
| * |
| * Out: |
| * none |
| * |
| * Return Value: none |
| * |
| */ |
| void MACvDisableKeyEntry(unsigned long dwIoBase, unsigned int uEntryIdx) |
| { |
| unsigned short wOffset; |
| |
| wOffset = MISCFIFO_KEYETRY0; |
| wOffset += (uEntryIdx * MISCFIFO_KEYENTRYSIZE); |
| |
| VNSvOutPortW(dwIoBase + MAC_REG_MISCFFNDEX, wOffset); |
| VNSvOutPortD(dwIoBase + MAC_REG_MISCFFDATA, 0); |
| VNSvOutPortW(dwIoBase + MAC_REG_MISCFFCTL, MISCFFCTL_WRITE); |
| } |
| |
| /* |
| * Description: |
| * Set the default Key (KeyEntry[10]) by MISCFIFO |
| * |
| * Parameters: |
| * In: |
| * dwIoBase - Base Address for MAC |
| * |
| * Out: |
| * none |
| * |
| * Return Value: none |
| * |
| */ |
| |
| void MACvSetDefaultKeyEntry(unsigned long dwIoBase, unsigned int uKeyLen, |
| unsigned int uKeyIdx, unsigned long *pdwKey, unsigned char byLocalID) |
| { |
| unsigned short wOffset; |
| unsigned long dwData; |
| int ii; |
| |
| if (byLocalID <= 1) |
| return; |
| |
| DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "MACvSetDefaultKeyEntry\n"); |
| wOffset = MISCFIFO_KEYETRY0; |
| wOffset += (10 * MISCFIFO_KEYENTRYSIZE); |
| |
| wOffset++; |
| wOffset++; |
| wOffset += (uKeyIdx * 4); |
| // always push 128 bits |
| for (ii = 0; ii < 3; ii++) { |
| DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "(%d) wOffset: %d, Data: %lX\n", ii, wOffset+ii, *pdwKey); |
| VNSvOutPortW(dwIoBase + MAC_REG_MISCFFNDEX, wOffset+ii); |
| VNSvOutPortD(dwIoBase + MAC_REG_MISCFFDATA, *pdwKey++); |
| VNSvOutPortW(dwIoBase + MAC_REG_MISCFFCTL, MISCFFCTL_WRITE); |
| } |
| dwData = *pdwKey; |
| if (uKeyLen == WLAN_WEP104_KEYLEN) |
| dwData |= 0x80000000; |
| |
| VNSvOutPortW(dwIoBase + MAC_REG_MISCFFNDEX, wOffset+3); |
| VNSvOutPortD(dwIoBase + MAC_REG_MISCFFDATA, dwData); |
| VNSvOutPortW(dwIoBase + MAC_REG_MISCFFCTL, MISCFFCTL_WRITE); |
| DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "End. wOffset: %d, Data: %lX\n", wOffset+3, dwData); |
| } |
| |
| /* |
| * Description: |
| * Enable default Key (KeyEntry[10]) by MISCFIFO |
| * |
| * Parameters: |
| * In: |
| * dwIoBase - Base Address for MAC |
| * |
| * Out: |
| * none |
| * |
| * Return Value: none |
| * |
| */ |
| /* |
| void MACvEnableDefaultKey(unsigned long dwIoBase, unsigned char byLocalID) |
| { |
| unsigned short wOffset; |
| unsigned long dwData; |
| |
| if (byLocalID <= 1) |
| return; |
| |
| wOffset = MISCFIFO_KEYETRY0; |
| wOffset += (10 * MISCFIFO_KEYENTRYSIZE); |
| |
| dwData = 0xC0440000; |
| VNSvOutPortW(dwIoBase + MAC_REG_MISCFFNDEX, wOffset); |
| VNSvOutPortD(dwIoBase + MAC_REG_MISCFFDATA, dwData); |
| VNSvOutPortW(dwIoBase + MAC_REG_MISCFFCTL, MISCFFCTL_WRITE); |
| DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "MACvEnableDefaultKey: wOffset: %d, Data: %lX\n", wOffset, dwData); |
| |
| } |
| */ |
| |
| /* |
| * Description: |
| * Disable default Key (KeyEntry[10]) by MISCFIFO |
| * |
| * Parameters: |
| * In: |
| * dwIoBase - Base Address for MAC |
| * |
| * Out: |
| * none |
| * |
| * Return Value: none |
| * |
| */ |
| void MACvDisableDefaultKey(unsigned long dwIoBase) |
| { |
| unsigned short wOffset; |
| unsigned long dwData; |
| |
| wOffset = MISCFIFO_KEYETRY0; |
| wOffset += (10 * MISCFIFO_KEYENTRYSIZE); |
| |
| dwData = 0x0; |
| VNSvOutPortW(dwIoBase + MAC_REG_MISCFFNDEX, wOffset); |
| VNSvOutPortD(dwIoBase + MAC_REG_MISCFFDATA, dwData); |
| VNSvOutPortW(dwIoBase + MAC_REG_MISCFFCTL, MISCFFCTL_WRITE); |
| DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "MACvDisableDefaultKey: wOffset: %d, Data: %lX\n", wOffset, dwData); |
| } |
| |
| /* |
| * Description: |
| * Set the default TKIP Group Key (KeyEntry[10]) by MISCFIFO |
| * |
| * Parameters: |
| * In: |
| * dwIoBase - Base Address for MAC |
| * |
| * Out: |
| * none |
| * |
| * Return Value: none |
| * |
| */ |
| void MACvSetDefaultTKIPKeyEntry(unsigned long dwIoBase, unsigned int uKeyLen, |
| unsigned int uKeyIdx, unsigned long *pdwKey, unsigned char byLocalID) |
| { |
| unsigned short wOffset; |
| unsigned long dwData; |
| int ii; |
| |
| if (byLocalID <= 1) |
| return; |
| |
| DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "MACvSetDefaultTKIPKeyEntry\n"); |
| wOffset = MISCFIFO_KEYETRY0; |
| // Kyle test : change offset from 10 -> 0 |
| wOffset += (10 * MISCFIFO_KEYENTRYSIZE); |
| |
| dwData = 0xC0660000; |
| VNSvOutPortW(dwIoBase + MAC_REG_MISCFFNDEX, wOffset); |
| VNSvOutPortD(dwIoBase + MAC_REG_MISCFFDATA, dwData); |
| VNSvOutPortW(dwIoBase + MAC_REG_MISCFFCTL, MISCFFCTL_WRITE); |
| wOffset++; |
| |
| dwData = 0; |
| VNSvOutPortW(dwIoBase + MAC_REG_MISCFFNDEX, wOffset); |
| VNSvOutPortD(dwIoBase + MAC_REG_MISCFFDATA, dwData); |
| VNSvOutPortW(dwIoBase + MAC_REG_MISCFFCTL, MISCFFCTL_WRITE); |
| wOffset++; |
| |
| wOffset += (uKeyIdx * 4); |
| DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "1. wOffset: %d, Data: %lX, idx:%d\n", wOffset, *pdwKey, uKeyIdx); |
| // always push 128 bits |
| for (ii = 0; ii < 4; ii++) { |
| DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "2.(%d) wOffset: %d, Data: %lX\n", ii, wOffset+ii, *pdwKey); |
| VNSvOutPortW(dwIoBase + MAC_REG_MISCFFNDEX, wOffset+ii); |
| VNSvOutPortD(dwIoBase + MAC_REG_MISCFFDATA, *pdwKey++); |
| VNSvOutPortW(dwIoBase + MAC_REG_MISCFFCTL, MISCFFCTL_WRITE); |
| } |
| } |
| |
| /* |
| * Description: |
| * Set the Key Control by MISCFIFO |
| * |
| * Parameters: |
| * In: |
| * dwIoBase - Base Address for MAC |
| * |
| * Out: |
| * none |
| * |
| * Return Value: none |
| * |
| */ |
| |
| void MACvSetDefaultKeyCtl(unsigned long dwIoBase, unsigned short wKeyCtl, unsigned int uEntryIdx, unsigned char byLocalID) |
| { |
| unsigned short wOffset; |
| unsigned long dwData; |
| |
| if (byLocalID <= 1) |
| return; |
| |
| DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "MACvSetKeyEntry\n"); |
| wOffset = MISCFIFO_KEYETRY0; |
| wOffset += (uEntryIdx * MISCFIFO_KEYENTRYSIZE); |
| |
| dwData = 0; |
| dwData |= wKeyCtl; |
| dwData <<= 16; |
| dwData |= 0xffff; |
| DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "1. wOffset: %d, Data: %lX, KeyCtl:%X\n", wOffset, dwData, wKeyCtl); |
| |
| VNSvOutPortW(dwIoBase + MAC_REG_MISCFFNDEX, wOffset); |
| VNSvOutPortD(dwIoBase + MAC_REG_MISCFFDATA, dwData); |
| VNSvOutPortW(dwIoBase + MAC_REG_MISCFFCTL, MISCFFCTL_WRITE); |
| } |