diff options
author | Russell King <rmk+kernel@arm.linux.org.uk> | 2009-09-22 19:54:53 (GMT) |
---|---|---|
committer | Russell King <rmk+kernel@arm.linux.org.uk> | 2009-09-22 20:01:40 (GMT) |
commit | ae19ffbadc1b2100285a5b5b3d0a4e0a11390904 (patch) | |
tree | 3c2086ab67398a019089a47ca3f362a4bc6db74f /drivers/staging/epl/Edrv8139.c | |
parent | 34e84f39a27d059a3e6ec6e8b94aafa702e6f220 (diff) | |
parent | 9173a8ef24a6b1b8031507b35b8ffe5f85a87692 (diff) | |
download | linux-fsl-qoriq-ae19ffbadc1b2100285a5b5b3d0a4e0a11390904.tar.xz |
Merge branch 'master' into for-linus
Diffstat (limited to 'drivers/staging/epl/Edrv8139.c')
-rw-r--r-- | drivers/staging/epl/Edrv8139.c | 1246 |
1 files changed, 0 insertions, 1246 deletions
diff --git a/drivers/staging/epl/Edrv8139.c b/drivers/staging/epl/Edrv8139.c deleted file mode 100644 index 44e3f7b..0000000 --- a/drivers/staging/epl/Edrv8139.c +++ /dev/null @@ -1,1246 +0,0 @@ -/**************************************************************************** - - (c) SYSTEC electronic GmbH, D-07973 Greiz, August-Bebel-Str. 29 - www.systec-electronic.com - - Project: openPOWERLINK - - Description: Ethernet driver for Realtek RTL8139 chips - except the RTL8139C+, because it has a different - Tx descriptor handling. - - License: - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions - are met: - - 1. Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. - - 2. Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in the - documentation and/or other materials provided with the distribution. - - 3. Neither the name of SYSTEC electronic GmbH nor the names of its - contributors may be used to endorse or promote products derived - from this software without prior written permission. For written - permission, please contact info@systec-electronic.com. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS - FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE - COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, - INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, - BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER - CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN - ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - POSSIBILITY OF SUCH DAMAGE. - - Severability Clause: - - If a provision of this License is or becomes illegal, invalid or - unenforceable in any jurisdiction, that shall not affect: - 1. the validity or enforceability in that jurisdiction of any other - provision of this License; or - 2. the validity or enforceability in other jurisdictions of that or - any other provision of this License. - - ------------------------------------------------------------------------- - - $RCSfile: Edrv8139.c,v $ - - $Author: D.Krueger $ - - $Revision: 1.10 $ $Date: 2008/11/21 09:00:38 $ - - $State: Exp $ - - Build Environment: - Dev C++ and GNU-Compiler for m68k - - ------------------------------------------------------------------------- - - Revision History: - - 2008/02/05 d.k.: start of implementation - -****************************************************************************/ - -#include "global.h" -#include "EplInc.h" -#include "edrv.h" - -#include <linux/module.h> -#include <linux/kernel.h> -#include <linux/pci.h> -#include <linux/interrupt.h> -#include <linux/init.h> -#include <linux/errno.h> -#include <linux/major.h> -#include <asm/io.h> -#include <asm/uaccess.h> -#include <asm/atomic.h> -#include <asm/irq.h> -#include <linux/sched.h> -#include <linux/delay.h> - -/***************************************************************************/ -/* */ -/* */ -/* G L O B A L D E F I N I T I O N S */ -/* */ -/* */ -/***************************************************************************/ - -// Buffer handling: -// All buffers are created statically (i.e. at compile time resp. at -// initialisation via kmalloc() ) and not dynamically on request (i.e. via -// EdrvAllocTxMsgBuffer(). -// EdrvAllocTxMsgBuffer() searches for an unused buffer which is large enough. -// EdrvInit() may allocate some buffers with sizes less than maximum frame -// size (i.e. 1514 bytes), e.g. for SoC, SoA, StatusResponse, IdentResponse, -// NMT requests / commands. The less the size of the buffer the less the -// number of the buffer. - -//--------------------------------------------------------------------------- -// const defines -//--------------------------------------------------------------------------- - -#ifndef EDRV_MAX_TX_BUFFERS -#define EDRV_MAX_TX_BUFFERS 20 -#endif - -#define EDRV_MAX_FRAME_SIZE 0x600 - -#define EDRV_RX_BUFFER_SIZE 0x8610 // 32 kB + 16 Byte + 1,5 kB (WRAP is enabled) -#define EDRV_RX_BUFFER_LENGTH (EDRV_RX_BUFFER_SIZE & 0xF800) // buffer size cut down to 2 kB alignment - -#define EDRV_TX_BUFFER_SIZE (EDRV_MAX_TX_BUFFERS * EDRV_MAX_FRAME_SIZE) // n * (MTU + 14 + 4) - -#define DRV_NAME "epl" - -#define EDRV_REGW_INT_MASK 0x3C // interrupt mask register -#define EDRV_REGW_INT_STATUS 0x3E // interrupt status register -#define EDRV_REGW_INT_ROK 0x0001 // Receive OK interrupt -#define EDRV_REGW_INT_RER 0x0002 // Receive error interrupt -#define EDRV_REGW_INT_TOK 0x0004 // Transmit OK interrupt -#define EDRV_REGW_INT_TER 0x0008 // Transmit error interrupt -#define EDRV_REGW_INT_RXOVW 0x0010 // Rx buffer overflow interrupt -#define EDRV_REGW_INT_PUN 0x0020 // Packet underrun/ link change interrupt -#define EDRV_REGW_INT_FOVW 0x0040 // Rx FIFO overflow interrupt -#define EDRV_REGW_INT_LENCHG 0x2000 // Cable length change interrupt -#define EDRV_REGW_INT_TIMEOUT 0x4000 // Time out interrupt -#define EDRV_REGW_INT_SERR 0x8000 // System error interrupt -#define EDRV_REGW_INT_MASK_DEF (EDRV_REGW_INT_ROK \ - | EDRV_REGW_INT_RER \ - | EDRV_REGW_INT_TOK \ - | EDRV_REGW_INT_TER \ - | EDRV_REGW_INT_RXOVW \ - | EDRV_REGW_INT_FOVW \ - | EDRV_REGW_INT_PUN \ - | EDRV_REGW_INT_TIMEOUT \ - | EDRV_REGW_INT_SERR) // default interrupt mask - -#define EDRV_REGB_COMMAND 0x37 // command register -#define EDRV_REGB_COMMAND_RST 0x10 -#define EDRV_REGB_COMMAND_RE 0x08 -#define EDRV_REGB_COMMAND_TE 0x04 -#define EDRV_REGB_COMMAND_BUFE 0x01 - -#define EDRV_REGB_CMD9346 0x50 // 93C46 command register -#define EDRV_REGB_CMD9346_LOCK 0x00 // lock configuration registers -#define EDRV_REGB_CMD9346_UNLOCK 0xC0 // unlock configuration registers - -#define EDRV_REGDW_RCR 0x44 // Rx configuration register -#define EDRV_REGDW_RCR_NO_FTH 0x0000E000 // no receive FIFO threshold -#define EDRV_REGDW_RCR_RBLEN32K 0x00001000 // 32 kB receive buffer -#define EDRV_REGDW_RCR_MXDMAUNL 0x00000700 // unlimited maximum DMA burst size -#define EDRV_REGDW_RCR_NOWRAP 0x00000080 // do not wrap frame at end of buffer -#define EDRV_REGDW_RCR_AER 0x00000020 // accept error frames (CRC, alignment, collided) -#define EDRV_REGDW_RCR_AR 0x00000010 // accept runt -#define EDRV_REGDW_RCR_AB 0x00000008 // accept broadcast frames -#define EDRV_REGDW_RCR_AM 0x00000004 // accept multicast frames -#define EDRV_REGDW_RCR_APM 0x00000002 // accept physical match frames -#define EDRV_REGDW_RCR_AAP 0x00000001 // accept all frames -#define EDRV_REGDW_RCR_DEF (EDRV_REGDW_RCR_NO_FTH \ - | EDRV_REGDW_RCR_RBLEN32K \ - | EDRV_REGDW_RCR_MXDMAUNL \ - | EDRV_REGDW_RCR_NOWRAP \ - | EDRV_REGDW_RCR_AB \ - | EDRV_REGDW_RCR_AM \ - | EDRV_REGDW_RCR_APM) // default value - -#define EDRV_REGDW_TCR 0x40 // Tx configuration register -#define EDRV_REGDW_TCR_VER_MASK 0x7CC00000 // mask for hardware version -#define EDRV_REGDW_TCR_VER_C 0x74000000 // RTL8139C -#define EDRV_REGDW_TCR_VER_D 0x74400000 // RTL8139D -#define EDRV_REGDW_TCR_IFG96 0x03000000 // default interframe gap (960 ns) -#define EDRV_REGDW_TCR_CRC 0x00010000 // disable appending of CRC by the controller -#define EDRV_REGDW_TCR_MXDMAUNL 0x00000700 // maximum DMA burst size of 2048 b -#define EDRV_REGDW_TCR_TXRETRY 0x00000000 // 16 retries -#define EDRV_REGDW_TCR_DEF (EDRV_REGDW_TCR_IFG96 \ - | EDRV_REGDW_TCR_MXDMAUNL \ - | EDRV_REGDW_TCR_TXRETRY) - -#define EDRV_REGW_MULINT 0x5C // multiple interrupt select register - -#define EDRV_REGDW_MPC 0x4C // missed packet counter register - -#define EDRV_REGDW_TSAD0 0x20 // Transmit start address of descriptor 0 -#define EDRV_REGDW_TSAD1 0x24 // Transmit start address of descriptor 1 -#define EDRV_REGDW_TSAD2 0x28 // Transmit start address of descriptor 2 -#define EDRV_REGDW_TSAD3 0x2C // Transmit start address of descriptor 3 -#define EDRV_REGDW_TSD0 0x10 // Transmit status of descriptor 0 -#define EDRV_REGDW_TSD_CRS 0x80000000 // Carrier sense lost -#define EDRV_REGDW_TSD_TABT 0x40000000 // Transmit Abort -#define EDRV_REGDW_TSD_OWC 0x20000000 // Out of window collision -#define EDRV_REGDW_TSD_TXTH_DEF 0x00020000 // Transmit FIFO threshold of 64 bytes -#define EDRV_REGDW_TSD_TOK 0x00008000 // Transmit OK -#define EDRV_REGDW_TSD_TUN 0x00004000 // Transmit FIFO underrun -#define EDRV_REGDW_TSD_OWN 0x00002000 // Owner - -#define EDRV_REGDW_RBSTART 0x30 // Receive buffer start address - -#define EDRV_REGW_CAPR 0x38 // Current address of packet read - -#define EDRV_REGDW_IDR0 0x00 // ID register 0 -#define EDRV_REGDW_IDR4 0x04 // ID register 4 - -#define EDRV_REGDW_MAR0 0x08 // Multicast address register 0 -#define EDRV_REGDW_MAR4 0x0C // Multicast address register 4 - -// defines for the status word in the receive buffer -#define EDRV_RXSTAT_MAR 0x8000 // Multicast address received -#define EDRV_RXSTAT_PAM 0x4000 // Physical address matched -#define EDRV_RXSTAT_BAR 0x2000 // Broadcast address received -#define EDRV_RXSTAT_ISE 0x0020 // Invalid symbol error -#define EDRV_RXSTAT_RUNT 0x0010 // Runt packet received -#define EDRV_RXSTAT_LONG 0x0008 // Long packet -#define EDRV_RXSTAT_CRC 0x0004 // CRC error -#define EDRV_RXSTAT_FAE 0x0002 // Frame alignment error -#define EDRV_RXSTAT_ROK 0x0001 // Receive OK - -#define EDRV_REGDW_WRITE(dwReg, dwVal) writel(dwVal, EdrvInstance_l.m_pIoAddr + dwReg) -#define EDRV_REGW_WRITE(dwReg, wVal) writew(wVal, EdrvInstance_l.m_pIoAddr + dwReg) -#define EDRV_REGB_WRITE(dwReg, bVal) writeb(bVal, EdrvInstance_l.m_pIoAddr + dwReg) -#define EDRV_REGDW_READ(dwReg) readl(EdrvInstance_l.m_pIoAddr + dwReg) -#define EDRV_REGW_READ(dwReg) readw(EdrvInstance_l.m_pIoAddr + dwReg) -#define EDRV_REGB_READ(dwReg) readb(EdrvInstance_l.m_pIoAddr + dwReg) - -// TracePoint support for realtime-debugging -#ifdef _DBG_TRACE_POINTS_ -void TgtDbgSignalTracePoint(u8 bTracePointNumber_p); -void TgtDbgPostTraceValue(u32 dwTraceValue_p); -#define TGT_DBG_SIGNAL_TRACE_POINT(p) TgtDbgSignalTracePoint(p) -#define TGT_DBG_POST_TRACE_VALUE(v) TgtDbgPostTraceValue(v) -#else -#define TGT_DBG_SIGNAL_TRACE_POINT(p) -#define TGT_DBG_POST_TRACE_VALUE(v) -#endif - -#define EDRV_COUNT_SEND TGT_DBG_SIGNAL_TRACE_POINT(2) -#define EDRV_COUNT_TIMEOUT TGT_DBG_SIGNAL_TRACE_POINT(3) -#define EDRV_COUNT_PCI_ERR TGT_DBG_SIGNAL_TRACE_POINT(4) -#define EDRV_COUNT_TX TGT_DBG_SIGNAL_TRACE_POINT(5) -#define EDRV_COUNT_RX TGT_DBG_SIGNAL_TRACE_POINT(6) -#define EDRV_COUNT_LATECOLLISION TGT_DBG_SIGNAL_TRACE_POINT(10) -#define EDRV_COUNT_TX_COL_RL TGT_DBG_SIGNAL_TRACE_POINT(11) -#define EDRV_COUNT_TX_FUN TGT_DBG_SIGNAL_TRACE_POINT(12) -#define EDRV_COUNT_TX_ERR TGT_DBG_SIGNAL_TRACE_POINT(13) -#define EDRV_COUNT_RX_CRC TGT_DBG_SIGNAL_TRACE_POINT(14) -#define EDRV_COUNT_RX_ERR TGT_DBG_SIGNAL_TRACE_POINT(15) -#define EDRV_COUNT_RX_FOVW TGT_DBG_SIGNAL_TRACE_POINT(16) -#define EDRV_COUNT_RX_PUN TGT_DBG_SIGNAL_TRACE_POINT(17) -#define EDRV_COUNT_RX_FAE TGT_DBG_SIGNAL_TRACE_POINT(18) -#define EDRV_COUNT_RX_OVW TGT_DBG_SIGNAL_TRACE_POINT(19) - -#define EDRV_TRACE_CAPR(x) TGT_DBG_POST_TRACE_VALUE(((x) & 0xFFFF) | 0x06000000) -#define EDRV_TRACE_RX_CRC(x) TGT_DBG_POST_TRACE_VALUE(((x) & 0xFFFF) | 0x0E000000) -#define EDRV_TRACE_RX_ERR(x) TGT_DBG_POST_TRACE_VALUE(((x) & 0xFFFF) | 0x0F000000) -#define EDRV_TRACE_RX_PUN(x) TGT_DBG_POST_TRACE_VALUE(((x) & 0xFFFF) | 0x11000000) -#define EDRV_TRACE(x) TGT_DBG_POST_TRACE_VALUE(((x) & 0xFFFF0000) | 0x0000FEC0) - -//--------------------------------------------------------------------------- -// local types -//--------------------------------------------------------------------------- -/* -typedef struct -{ - BOOL m_fUsed; - unsigned int m_uiSize; - MCD_bufDescFec *m_pBufDescr; - -} tEdrvTxBufferIntern; -*/ - -// Private structure -typedef struct { - struct pci_dev *m_pPciDev; // pointer to PCI device structure - void *m_pIoAddr; // pointer to register space of Ethernet controller - u8 *m_pbRxBuf; // pointer to Rx buffer - dma_addr_t m_pRxBufDma; - u8 *m_pbTxBuf; // pointer to Tx buffer - dma_addr_t m_pTxBufDma; - BOOL m_afTxBufUsed[EDRV_MAX_TX_BUFFERS]; - unsigned int m_uiCurTxDesc; - - tEdrvInitParam m_InitParam; - tEdrvTxBuffer *m_pLastTransmittedTxBuffer; - -} tEdrvInstance; - -//--------------------------------------------------------------------------- -// local function prototypes -//--------------------------------------------------------------------------- - -static int EdrvInitOne(struct pci_dev *pPciDev, - const struct pci_device_id *pId); - -static void EdrvRemoveOne(struct pci_dev *pPciDev); - -//--------------------------------------------------------------------------- -// modul globale vars -//--------------------------------------------------------------------------- -// buffers and buffer descriptors and pointers - -static struct pci_device_id aEdrvPciTbl[] = { - {0x10ec, 0x8139, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, - {0,} -}; - -MODULE_DEVICE_TABLE(pci, aEdrvPciTbl); - -static tEdrvInstance EdrvInstance_l; - -static struct pci_driver EdrvDriver = { - .name = DRV_NAME, - .id_table = aEdrvPciTbl, - .probe = EdrvInitOne, - .remove = EdrvRemoveOne, -}; - -/***************************************************************************/ -/* */ -/* */ -/* C L A S S <edrv> */ -/* */ -/* */ -/***************************************************************************/ -// -// Description: -// -// -/***************************************************************************/ - -//=========================================================================// -// // -// P R I V A T E D E F I N I T I O N S // -// // -//=========================================================================// - -//--------------------------------------------------------------------------- -// const defines -//--------------------------------------------------------------------------- - -//--------------------------------------------------------------------------- -// local types -//--------------------------------------------------------------------------- - -//--------------------------------------------------------------------------- -// local vars -//--------------------------------------------------------------------------- - -//--------------------------------------------------------------------------- -// local function prototypes -//--------------------------------------------------------------------------- - -static u8 EdrvCalcHash(u8 * pbMAC_p); - -//--------------------------------------------------------------------------- -// -// Function: EdrvInit -// -// Description: function for init of the Ethernet controller -// -// Parameters: pEdrvInitParam_p = pointer to struct including the init-parameters -// -// Returns: Errorcode = kEplSuccessful -// = kEplNoResource -// -// State: -// -//--------------------------------------------------------------------------- -tEplKernel EdrvInit(tEdrvInitParam * pEdrvInitParam_p) -{ - tEplKernel Ret; - int iResult; - - Ret = kEplSuccessful; - - // clear instance structure - EPL_MEMSET(&EdrvInstance_l, 0, sizeof(EdrvInstance_l)); - - // save the init data - EdrvInstance_l.m_InitParam = *pEdrvInitParam_p; - - // register PCI driver - iResult = pci_register_driver(&EdrvDriver); - if (iResult != 0) { - printk("%s pci_register_driver failed with %d\n", __func__, - iResult); - Ret = kEplNoResource; - goto Exit; - } - - if (EdrvInstance_l.m_pPciDev == NULL) { - printk("%s m_pPciDev=NULL\n", __func__); - Ret = kEplNoResource; - goto Exit; - } - // read MAC address from controller - printk("%s local MAC = ", __func__); - for (iResult = 0; iResult < 6; iResult++) { - pEdrvInitParam_p->m_abMyMacAddr[iResult] = - EDRV_REGB_READ((EDRV_REGDW_IDR0 + iResult)); - printk("%02X ", - (unsigned int)pEdrvInitParam_p->m_abMyMacAddr[iResult]); - } - printk("\n"); - - Exit: - return Ret; - -} - -//--------------------------------------------------------------------------- -// -// Function: EdrvShutdown -// -// Description: Shutdown the Ethernet controller -// -// Parameters: void -// -// Returns: Errorcode = kEplSuccessful -// -// State: -// -//--------------------------------------------------------------------------- -tEplKernel EdrvShutdown(void) -{ - - // unregister PCI driver - printk("%s calling pci_unregister_driver()\n", __func__); - pci_unregister_driver(&EdrvDriver); - - return kEplSuccessful; -} - -//--------------------------------------------------------------------------- -// -// Function: EdrvDefineRxMacAddrEntry -// -// Description: Set a multicast entry into the Ethernet controller -// -// Parameters: pbMacAddr_p = pointer to multicast entry to set -// -// Returns: Errorcode = kEplSuccessful -// -// State: -// -//--------------------------------------------------------------------------- -tEplKernel EdrvDefineRxMacAddrEntry(u8 * pbMacAddr_p) -{ - tEplKernel Ret = kEplSuccessful; - u32 dwData; - u8 bHash; - - bHash = EdrvCalcHash(pbMacAddr_p); -/* - dwData = ether_crc(6, pbMacAddr_p); - - printk("EdrvDefineRxMacAddrEntry('%02X:%02X:%02X:%02X:%02X:%02X') hash = %u / %u ether_crc = 0x%08lX\n", - (u16) pbMacAddr_p[0], (u16) pbMacAddr_p[1], (u16) pbMacAddr_p[2], - (u16) pbMacAddr_p[3], (u16) pbMacAddr_p[4], (u16) pbMacAddr_p[5], - (u16) bHash, (u16) (dwData >> 26), dwData); -*/ - if (bHash > 31) { - dwData = EDRV_REGDW_READ(EDRV_REGDW_MAR4); - dwData |= 1 << (bHash - 32); - EDRV_REGDW_WRITE(EDRV_REGDW_MAR4, dwData); - } else { - dwData = EDRV_REGDW_READ(EDRV_REGDW_MAR0); - dwData |= 1 << bHash; - EDRV_REGDW_WRITE(EDRV_REGDW_MAR0, dwData); - } - - return Ret; -} - -//--------------------------------------------------------------------------- -// -// Function: EdrvUndefineRxMacAddrEntry -// -// Description: Reset a multicast entry in the Ethernet controller -// -// Parameters: pbMacAddr_p = pointer to multicast entry to reset -// -// Returns: Errorcode = kEplSuccessful -// -// State: -// -//--------------------------------------------------------------------------- -tEplKernel EdrvUndefineRxMacAddrEntry(u8 * pbMacAddr_p) -{ - tEplKernel Ret = kEplSuccessful; - u32 dwData; - u8 bHash; - - bHash = EdrvCalcHash(pbMacAddr_p); - - if (bHash > 31) { - dwData = EDRV_REGDW_READ(EDRV_REGDW_MAR4); - dwData &= ~(1 << (bHash - 32)); - EDRV_REGDW_WRITE(EDRV_REGDW_MAR4, dwData); - } else { - dwData = EDRV_REGDW_READ(EDRV_REGDW_MAR0); - dwData &= ~(1 << bHash); - EDRV_REGDW_WRITE(EDRV_REGDW_MAR0, dwData); - } - - return Ret; -} - -//--------------------------------------------------------------------------- -// -// Function: EdrvAllocTxMsgBuffer -// -// Description: Register a Tx-Buffer -// -// Parameters: pBuffer_p = pointer to Buffer structure -// -// Returns: Errorcode = kEplSuccessful -// = kEplEdrvNoFreeBufEntry -// -// State: -// -//--------------------------------------------------------------------------- -tEplKernel EdrvAllocTxMsgBuffer(tEdrvTxBuffer * pBuffer_p) -{ - tEplKernel Ret = kEplSuccessful; - u32 i; - - if (pBuffer_p->m_uiMaxBufferLen > EDRV_MAX_FRAME_SIZE) { - Ret = kEplEdrvNoFreeBufEntry; - goto Exit; - } - // search a free Tx buffer with appropriate size - for (i = 0; i < EDRV_MAX_TX_BUFFERS; i++) { - if (EdrvInstance_l.m_afTxBufUsed[i] == FALSE) { - // free channel found - EdrvInstance_l.m_afTxBufUsed[i] = TRUE; - pBuffer_p->m_uiBufferNumber = i; - pBuffer_p->m_pbBuffer = - EdrvInstance_l.m_pbTxBuf + - (i * EDRV_MAX_FRAME_SIZE); - pBuffer_p->m_uiMaxBufferLen = EDRV_MAX_FRAME_SIZE; - break; - } - } - if (i >= EDRV_MAX_TX_BUFFERS) { - Ret = kEplEdrvNoFreeBufEntry; - goto Exit; - } - - Exit: - return Ret; - -} - -//--------------------------------------------------------------------------- -// -// Function: EdrvReleaseTxMsgBuffer -// -// Description: Register a Tx-Buffer -// -// Parameters: pBuffer_p = pointer to Buffer structure -// -// Returns: Errorcode = kEplSuccessful -// -// State: -// -//--------------------------------------------------------------------------- -tEplKernel EdrvReleaseTxMsgBuffer(tEdrvTxBuffer * pBuffer_p) -{ - unsigned int uiBufferNumber; - - uiBufferNumber = pBuffer_p->m_uiBufferNumber; - - if (uiBufferNumber < EDRV_MAX_TX_BUFFERS) { - EdrvInstance_l.m_afTxBufUsed[uiBufferNumber] = FALSE; - } - - return kEplSuccessful; - -} - -//--------------------------------------------------------------------------- -// -// Function: EdrvSendTxMsg -// -// Description: immediately starts the transmission of the buffer -// -// Parameters: pBuffer_p = buffer descriptor to transmit -// -// Returns: Errorcode = kEplSuccessful -// -// State: -// -//--------------------------------------------------------------------------- -tEplKernel EdrvSendTxMsg(tEdrvTxBuffer * pBuffer_p) -{ - tEplKernel Ret = kEplSuccessful; - unsigned int uiBufferNumber; - u32 dwTemp; - - uiBufferNumber = pBuffer_p->m_uiBufferNumber; - - if ((uiBufferNumber >= EDRV_MAX_TX_BUFFERS) - || (EdrvInstance_l.m_afTxBufUsed[uiBufferNumber] == FALSE)) { - Ret = kEplEdrvBufNotExisting; - goto Exit; - } - - if (EdrvInstance_l.m_pLastTransmittedTxBuffer != NULL) { // transmission is already active - Ret = kEplInvalidOperation; - dwTemp = - EDRV_REGDW_READ((EDRV_REGDW_TSD0 + - (EdrvInstance_l.m_uiCurTxDesc * - sizeof(u32)))); - printk("%s InvOp TSD%u = 0x%08X", __func__, - EdrvInstance_l.m_uiCurTxDesc, dwTemp); - printk(" Cmd = 0x%02X\n", - (u16) EDRV_REGB_READ(EDRV_REGB_COMMAND)); - goto Exit; - } - // save pointer to buffer structure for TxHandler - EdrvInstance_l.m_pLastTransmittedTxBuffer = pBuffer_p; - - EDRV_COUNT_SEND; - - // pad with zeros if necessary, because controller does not do it - if (pBuffer_p->m_uiTxMsgLen < MIN_ETH_SIZE) { - EPL_MEMSET(pBuffer_p->m_pbBuffer + pBuffer_p->m_uiTxMsgLen, 0, - MIN_ETH_SIZE - pBuffer_p->m_uiTxMsgLen); - pBuffer_p->m_uiTxMsgLen = MIN_ETH_SIZE; - } - // set DMA address of buffer - EDRV_REGDW_WRITE((EDRV_REGDW_TSAD0 + - (EdrvInstance_l.m_uiCurTxDesc * sizeof(u32))), - (EdrvInstance_l.m_pTxBufDma + - (uiBufferNumber * EDRV_MAX_FRAME_SIZE))); - dwTemp = - EDRV_REGDW_READ((EDRV_REGDW_TSAD0 + - (EdrvInstance_l.m_uiCurTxDesc * sizeof(u32)))); -// printk("%s TSAD%u = 0x%08lX", __func__, EdrvInstance_l.m_uiCurTxDesc, dwTemp); - - // start transmission - EDRV_REGDW_WRITE((EDRV_REGDW_TSD0 + - (EdrvInstance_l.m_uiCurTxDesc * sizeof(u32))), - (EDRV_REGDW_TSD_TXTH_DEF | pBuffer_p->m_uiTxMsgLen)); - dwTemp = - EDRV_REGDW_READ((EDRV_REGDW_TSD0 + - (EdrvInstance_l.m_uiCurTxDesc * sizeof(u32)))); -// printk(" TSD%u = 0x%08lX / 0x%08lX\n", EdrvInstance_l.m_uiCurTxDesc, dwTemp, (u32)(EDRV_REGDW_TSD_TXTH_DEF | pBuffer_p->m_uiTxMsgLen)); - - Exit: - return Ret; -} - -#if 0 -//--------------------------------------------------------------------------- -// -// Function: EdrvTxMsgReady -// -// Description: starts copying the buffer to the ethernet controller's FIFO -// -// Parameters: pbBuffer_p - bufferdescriptor to transmit -// -// Returns: Errorcode - kEplSuccessful -// -// State: -// -//--------------------------------------------------------------------------- -tEplKernel EdrvTxMsgReady(tEdrvTxBuffer * pBuffer_p) -{ - tEplKernel Ret = kEplSuccessful; - unsigned int uiBufferNumber; - - Exit: - return Ret; -} - -//--------------------------------------------------------------------------- -// -// Function: EdrvTxMsgStart -// -// Description: starts transmission of the ethernet controller's FIFO -// -// Parameters: pbBuffer_p - bufferdescriptor to transmit -// -// Returns: Errorcode - kEplSuccessful -// -// State: -// -//--------------------------------------------------------------------------- -tEplKernel EdrvTxMsgStart(tEdrvTxBuffer * pBuffer_p) -{ - tEplKernel Ret = kEplSuccessful; - - return Ret; -} -#endif - -//--------------------------------------------------------------------------- -// -// Function: EdrvReinitRx -// -// Description: reinitialize the Rx process, because of error -// -// Parameters: void -// -// Returns: void -// -// State: -// -//--------------------------------------------------------------------------- -static void EdrvReinitRx(void) -{ - u8 bCmd; - - // simply switch off and on the receiver - // this will reset the CAPR register - bCmd = EDRV_REGB_READ(EDRV_REGB_COMMAND); - EDRV_REGB_WRITE(EDRV_REGB_COMMAND, (bCmd & ~EDRV_REGB_COMMAND_RE)); - EDRV_REGB_WRITE(EDRV_REGB_COMMAND, bCmd); - - // set receive configuration register - EDRV_REGDW_WRITE(EDRV_REGDW_RCR, EDRV_REGDW_RCR_DEF); -} - -//--------------------------------------------------------------------------- -// -// Function: EdrvInterruptHandler -// -// Description: interrupt handler -// -// Parameters: void -// -// Returns: void -// -// State: -// -//--------------------------------------------------------------------------- -#if 0 -void EdrvInterruptHandler(void) -{ -} -#endif - -static int TgtEthIsr(int nIrqNum_p, void *ppDevInstData_p) -{ -// EdrvInterruptHandler(); - tEdrvRxBuffer RxBuffer; - tEdrvTxBuffer *pTxBuffer; - u16 wStatus; - u32 dwTxStatus; - u32 dwRxStatus; - u16 wCurRx; - u8 *pbRxBuf; - unsigned int uiLength; - int iHandled = IRQ_HANDLED; - -// printk("¤"); - - // read the interrupt status - wStatus = EDRV_REGW_READ(EDRV_REGW_INT_STATUS); - - // acknowledge the interrupts - EDRV_REGW_WRITE(EDRV_REGW_INT_STATUS, wStatus); - - if (wStatus == 0) { - iHandled = IRQ_NONE; - goto Exit; - } - // process tasks - if ((wStatus & (EDRV_REGW_INT_TER | EDRV_REGW_INT_TOK)) != 0) { // transmit interrupt - - if (EdrvInstance_l.m_pbTxBuf == NULL) { - printk("%s Tx buffers currently not allocated\n", - __func__); - goto Exit; - } - // read transmit status - dwTxStatus = - EDRV_REGDW_READ((EDRV_REGDW_TSD0 + - (EdrvInstance_l.m_uiCurTxDesc * - sizeof(u32)))); - if ((dwTxStatus & (EDRV_REGDW_TSD_TOK | EDRV_REGDW_TSD_TABT | EDRV_REGDW_TSD_TUN)) != 0) { // transmit finished - EdrvInstance_l.m_uiCurTxDesc = - (EdrvInstance_l.m_uiCurTxDesc + 1) & 0x03; - pTxBuffer = EdrvInstance_l.m_pLastTransmittedTxBuffer; - EdrvInstance_l.m_pLastTransmittedTxBuffer = NULL; - - if ((dwTxStatus & EDRV_REGDW_TSD_TOK) != 0) { - EDRV_COUNT_TX; - } else if ((dwTxStatus & EDRV_REGDW_TSD_TUN) != 0) { - EDRV_COUNT_TX_FUN; - } else { // assume EDRV_REGDW_TSD_TABT - EDRV_COUNT_TX_COL_RL; - } - -// printk("T"); - if (pTxBuffer != NULL) { - // call Tx handler of Data link layer - EdrvInstance_l.m_InitParam. - m_pfnTxHandler(pTxBuffer); - } - } else { - EDRV_COUNT_TX_ERR; - } - } - - if ((wStatus & (EDRV_REGW_INT_RER | EDRV_REGW_INT_FOVW | EDRV_REGW_INT_RXOVW | EDRV_REGW_INT_PUN)) != 0) { // receive error interrupt - - if ((wStatus & EDRV_REGW_INT_FOVW) != 0) { - EDRV_COUNT_RX_FOVW; - } else if ((wStatus & EDRV_REGW_INT_RXOVW) != 0) { - EDRV_COUNT_RX_OVW; - } else if ((wStatus & EDRV_REGW_INT_PUN) != 0) { // Packet underrun - EDRV_TRACE_RX_PUN(wStatus); - EDRV_COUNT_RX_PUN; - } else { /*if ((wStatus & EDRV_REGW_INT_RER) != 0) */ - - EDRV_TRACE_RX_ERR(wStatus); - EDRV_COUNT_RX_ERR; - } - - // reinitialize Rx process - EdrvReinitRx(); - } - - if ((wStatus & EDRV_REGW_INT_ROK) != 0) { // receive interrupt - - if (EdrvInstance_l.m_pbRxBuf == NULL) { - printk("%s Rx buffers currently not allocated\n", - __func__); - goto Exit; - } - // read current offset in receive buffer - wCurRx = - (EDRV_REGW_READ(EDRV_REGW_CAPR) + - 0x10) % EDRV_RX_BUFFER_LENGTH; - - while ((EDRV_REGB_READ(EDRV_REGB_COMMAND) & EDRV_REGB_COMMAND_BUFE) == 0) { // frame available - - // calculate pointer to current frame in receive buffer - pbRxBuf = EdrvInstance_l.m_pbRxBuf + wCurRx; - - // read receive status u32 - dwRxStatus = le32_to_cpu(*((u32 *) pbRxBuf)); - - // calculate length of received frame - uiLength = dwRxStatus >> 16; - - if (uiLength == 0xFFF0) { // frame is unfinished (maybe early Rx interrupt is active) - break; - } - - if ((dwRxStatus & EDRV_RXSTAT_ROK) == 0) { // error occured while receiving this frame - // ignore it - if ((dwRxStatus & EDRV_RXSTAT_FAE) != 0) { - EDRV_COUNT_RX_FAE; - } else if ((dwRxStatus & EDRV_RXSTAT_CRC) != 0) { - EDRV_TRACE_RX_CRC(dwRxStatus); - EDRV_COUNT_RX_CRC; - } else { - EDRV_TRACE_RX_ERR(dwRxStatus); - EDRV_COUNT_RX_ERR; - } - - // reinitialize Rx process - EdrvReinitRx(); - - break; - } else { // frame is OK - RxBuffer.m_BufferInFrame = - kEdrvBufferLastInFrame; - RxBuffer.m_uiRxMsgLen = uiLength - ETH_CRC_SIZE; - RxBuffer.m_pbBuffer = - pbRxBuf + sizeof(dwRxStatus); - -// printk("R"); - EDRV_COUNT_RX; - - // call Rx handler of Data link layer - EdrvInstance_l.m_InitParam. - m_pfnRxHandler(&RxBuffer); - } - - // calulate new offset (u32 aligned) - wCurRx = - (u16) ((wCurRx + uiLength + sizeof(dwRxStatus) + - 3) & ~0x3); - EDRV_TRACE_CAPR(wCurRx - 0x10); - EDRV_REGW_WRITE(EDRV_REGW_CAPR, wCurRx - 0x10); - - // reread current offset in receive buffer - wCurRx = - (EDRV_REGW_READ(EDRV_REGW_CAPR) + - 0x10) % EDRV_RX_BUFFER_LENGTH; - - } - } - - if ((wStatus & EDRV_REGW_INT_SERR) != 0) { // PCI error - EDRV_COUNT_PCI_ERR; - } - - if ((wStatus & EDRV_REGW_INT_TIMEOUT) != 0) { // Timeout - EDRV_COUNT_TIMEOUT; - } - - Exit: - return iHandled; -} - -//--------------------------------------------------------------------------- -// -// Function: EdrvInitOne -// -// Description: initializes one PCI device -// -// Parameters: pPciDev = pointer to corresponding PCI device structure -// pId = PCI device ID -// -// Returns: (int) = error code -// -// State: -// -//--------------------------------------------------------------------------- - -static int EdrvInitOne(struct pci_dev *pPciDev, const struct pci_device_id *pId) -{ - int iResult = 0; - u32 dwTemp; - - if (EdrvInstance_l.m_pPciDev != NULL) { // Edrv is already connected to a PCI device - printk("%s device %s discarded\n", __func__, - pci_name(pPciDev)); - iResult = -ENODEV; - goto Exit; - } - - if (pPciDev->revision >= 0x20) { - printk - ("%s device %s is an enhanced 8139C+ version, which is not supported\n", - __func__, pci_name(pPciDev)); - iResult = -ENODEV; - goto Exit; - } - - EdrvInstance_l.m_pPciDev = pPciDev; - - // enable device - printk("%s enable device\n", __func__); - iResult = pci_enable_device(pPciDev); - if (iResult != 0) { - goto Exit; - } - - if ((pci_resource_flags(pPciDev, 1) & IORESOURCE_MEM) == 0) { - iResult = -ENODEV; - goto Exit; - } - - printk("%s request regions\n", __func__); - iResult = pci_request_regions(pPciDev, DRV_NAME); - if (iResult != 0) { - goto Exit; - } - - printk("%s ioremap\n", __func__); - EdrvInstance_l.m_pIoAddr = - ioremap(pci_resource_start(pPciDev, 1), - pci_resource_len(pPciDev, 1)); - if (EdrvInstance_l.m_pIoAddr == NULL) { // remap of controller's register space failed - iResult = -EIO; - goto Exit; - } - // enable PCI busmaster - printk("%s enable busmaster\n", __func__); - pci_set_master(pPciDev); - - // reset controller - printk("%s reset controller\n", __func__); - EDRV_REGB_WRITE(EDRV_REGB_COMMAND, EDRV_REGB_COMMAND_RST); - - // wait until reset has finished - for (iResult = 500; iResult > 0; iResult--) { - if ((EDRV_REGB_READ(EDRV_REGB_COMMAND) & EDRV_REGB_COMMAND_RST) - == 0) { - break; - } - - schedule_timeout(10); - } - - // check hardware version, i.e. chip ID - dwTemp = EDRV_REGDW_READ(EDRV_REGDW_TCR); - if (((dwTemp & EDRV_REGDW_TCR_VER_MASK) != EDRV_REGDW_TCR_VER_C) - && ((dwTemp & EDRV_REGDW_TCR_VER_MASK) != EDRV_REGDW_TCR_VER_D)) { // unsupported chip - printk("%s Unsupported chip! TCR = 0x%08X\n", __func__, - dwTemp); - iResult = -ENODEV; - goto Exit; - } - // disable interrupts - printk("%s disable interrupts\n", __func__); - EDRV_REGW_WRITE(EDRV_REGW_INT_MASK, 0); - // acknowledge all pending interrupts - EDRV_REGW_WRITE(EDRV_REGW_INT_STATUS, - EDRV_REGW_READ(EDRV_REGW_INT_STATUS)); - - // install interrupt handler - printk("%s install interrupt handler\n", __func__); - iResult = - request_irq(pPciDev->irq, TgtEthIsr, IRQF_SHARED, - DRV_NAME /*pPciDev->dev.name */ , pPciDev); - if (iResult != 0) { - goto Exit; - } - -/* - // unlock configuration registers - printk("%s unlock configuration registers\n", __func__); - EDRV_REGB_WRITE(EDRV_REGB_CMD9346, EDRV_REGB_CMD9346_UNLOCK); - - // check if user specified a MAC address - printk("%s check specified MAC address\n", __func__); - for (iResult = 0; iResult < 6; iResult++) - { - if (EdrvInstance_l.m_InitParam.m_abMyMacAddr[iResult] != 0) - { - printk("%s set local MAC address\n", __func__); - // write this MAC address to controller - EDRV_REGDW_WRITE(EDRV_REGDW_IDR0, - le32_to_cpu(*((u32*)&EdrvInstance_l.m_InitParam.m_abMyMacAddr[0]))); - dwTemp = EDRV_REGDW_READ(EDRV_REGDW_IDR0); - - EDRV_REGDW_WRITE(EDRV_REGDW_IDR4, - le32_to_cpu(*((u32*)&EdrvInstance_l.m_InitParam.m_abMyMacAddr[4]))); - dwTemp = EDRV_REGDW_READ(EDRV_REGDW_IDR4); - break; - } - } - iResult = 0; - - // lock configuration registers - EDRV_REGB_WRITE(EDRV_REGB_CMD9346, EDRV_REGB_CMD9346_LOCK); -*/ - - // allocate buffers - printk("%s allocate buffers\n", __func__); - EdrvInstance_l.m_pbTxBuf = - pci_alloc_consistent(pPciDev, EDRV_TX_BUFFER_SIZE, - &EdrvInstance_l.m_pTxBufDma); - if (EdrvInstance_l.m_pbTxBuf == NULL) { - iResult = -ENOMEM; - goto Exit; - } - - EdrvInstance_l.m_pbRxBuf = - pci_alloc_consistent(pPciDev, EDRV_RX_BUFFER_SIZE, - &EdrvInstance_l.m_pRxBufDma); - if (EdrvInstance_l.m_pbRxBuf == NULL) { - iResult = -ENOMEM; - goto Exit; - } - // reset pointers for Tx buffers - printk("%s reset pointers fo Tx buffers\n", __func__); - EDRV_REGDW_WRITE(EDRV_REGDW_TSAD0, 0); - dwTemp = EDRV_REGDW_READ(EDRV_REGDW_TSAD0); - EDRV_REGDW_WRITE(EDRV_REGDW_TSAD1, 0); - dwTemp = EDRV_REGDW_READ(EDRV_REGDW_TSAD1); - EDRV_REGDW_WRITE(EDRV_REGDW_TSAD2, 0); - dwTemp = EDRV_REGDW_READ(EDRV_REGDW_TSAD2); - EDRV_REGDW_WRITE(EDRV_REGDW_TSAD3, 0); - dwTemp = EDRV_REGDW_READ(EDRV_REGDW_TSAD3); - - printk(" Command = 0x%02X\n", - (u16) EDRV_REGB_READ(EDRV_REGB_COMMAND)); - - // set pointer for receive buffer in controller - printk("%s set pointer to Rx buffer\n", __func__); - EDRV_REGDW_WRITE(EDRV_REGDW_RBSTART, EdrvInstance_l.m_pRxBufDma); - - // enable transmitter and receiver - printk("%s enable Tx and Rx", __func__); - EDRV_REGB_WRITE(EDRV_REGB_COMMAND, - (EDRV_REGB_COMMAND_RE | EDRV_REGB_COMMAND_TE)); - printk(" Command = 0x%02X\n", - (u16) EDRV_REGB_READ(EDRV_REGB_COMMAND)); - - // clear missed packet counter to enable Rx/Tx process - EDRV_REGDW_WRITE(EDRV_REGDW_MPC, 0); - - // set transmit configuration register - printk("%s set Tx conf register", __func__); - EDRV_REGDW_WRITE(EDRV_REGDW_TCR, EDRV_REGDW_TCR_DEF); - printk(" = 0x%08X\n", EDRV_REGDW_READ(EDRV_REGDW_TCR)); - - // set receive configuration register - printk("%s set Rx conf register", __func__); - EDRV_REGDW_WRITE(EDRV_REGDW_RCR, EDRV_REGDW_RCR_DEF); - printk(" = 0x%08X\n", EDRV_REGDW_READ(EDRV_REGDW_RCR)); - - // reset multicast MAC address filter - EDRV_REGDW_WRITE(EDRV_REGDW_MAR0, 0); - dwTemp = EDRV_REGDW_READ(EDRV_REGDW_MAR0); - EDRV_REGDW_WRITE(EDRV_REGDW_MAR4, 0); - dwTemp = EDRV_REGDW_READ(EDRV_REGDW_MAR4); - -/* - // enable transmitter and receiver - printk("%s enable Tx and Rx", __func__); - EDRV_REGB_WRITE(EDRV_REGB_COMMAND, (EDRV_REGB_COMMAND_RE | EDRV_REGB_COMMAND_TE)); - printk(" Command = 0x%02X\n", (u16) EDRV_REGB_READ(EDRV_REGB_COMMAND)); -*/ - // disable early interrupts - EDRV_REGW_WRITE(EDRV_REGW_MULINT, 0); - - // enable interrupts - printk("%s enable interrupts\n", __func__); - EDRV_REGW_WRITE(EDRV_REGW_INT_MASK, EDRV_REGW_INT_MASK_DEF); - - Exit: - printk("%s finished with %d\n", __func__, iResult); - return iResult; -} - -//--------------------------------------------------------------------------- -// -// Function: EdrvRemoveOne -// -// Description: shuts down one PCI device -// -// Parameters: pPciDev = pointer to corresponding PCI device structure -// -// Returns: (void) -// -// State: -// -//--------------------------------------------------------------------------- - -static void EdrvRemoveOne(struct pci_dev *pPciDev) -{ - - if (EdrvInstance_l.m_pPciDev != pPciDev) { // trying to remove unknown device - BUG_ON(EdrvInstance_l.m_pPciDev != pPciDev); - goto Exit; - } - // disable transmitter and receiver - EDRV_REGB_WRITE(EDRV_REGB_COMMAND, 0); - - // disable interrupts - EDRV_REGW_WRITE(EDRV_REGW_INT_MASK, 0); - - // remove interrupt handler - free_irq(pPciDev->irq, pPciDev); - - // free buffers - if (EdrvInstance_l.m_pbTxBuf != NULL) { - pci_free_consistent(pPciDev, EDRV_TX_BUFFER_SIZE, - EdrvInstance_l.m_pbTxBuf, - EdrvInstance_l.m_pTxBufDma); - EdrvInstance_l.m_pbTxBuf = NULL; - } - - if (EdrvInstance_l.m_pbRxBuf != NULL) { - pci_free_consistent(pPciDev, EDRV_RX_BUFFER_SIZE, - EdrvInstance_l.m_pbRxBuf, - EdrvInstance_l.m_pRxBufDma); - EdrvInstance_l.m_pbRxBuf = NULL; - } - // unmap controller's register space - if (EdrvInstance_l.m_pIoAddr != NULL) { - iounmap(EdrvInstance_l.m_pIoAddr); - } - // disable the PCI device - pci_disable_device(pPciDev); - - // release memory regions - pci_release_regions(pPciDev); - - EdrvInstance_l.m_pPciDev = NULL; - - Exit:; -} - -//--------------------------------------------------------------------------- -// -// Function: EdrvCalcHash -// -// Description: function calculates the entry for the hash-table from MAC -// address -// -// Parameters: pbMAC_p - pointer to MAC address -// -// Returns: hash value -// -// State: -// -//--------------------------------------------------------------------------- -#define HASH_BITS 6 // used bits in hash -#define CRC32_POLY 0x04C11DB6 // -//#define CRC32_POLY 0xEDB88320 // -// G(x) = x32 + x26 + x23 + x22 + x16 + x12 + x11 + x10 + x8 + x7 + x5 + x4 + x2 + x + 1 - -static u8 EdrvCalcHash(u8 * pbMAC_p) -{ - u32 dwByteCounter; - u32 dwBitCounter; - u32 dwData; - u32 dwCrc; - u32 dwCarry; - u8 *pbData; - u8 bHash; - - pbData = pbMAC_p; - - // calculate crc32 value of mac address - dwCrc = 0xFFFFFFFF; - - for (dwByteCounter = 0; dwByteCounter < 6; dwByteCounter++) { - dwData = *pbData; - pbData++; - for (dwBitCounter = 0; dwBitCounter < 8; - dwBitCounter++, dwData >>= 1) { - dwCarry = (((dwCrc >> 31) ^ dwData) & 1); - dwCrc = dwCrc << 1; - if (dwCarry != 0) { - dwCrc = (dwCrc ^ CRC32_POLY) | dwCarry; - } - } - } - -// printk("MyCRC = 0x%08lX\n", dwCrc); - // only upper 6 bits (HASH_BITS) are used - // which point to specific bit in the hash registers - bHash = (u8) ((dwCrc >> (32 - HASH_BITS)) & 0x3f); - - return bHash; -} |