perf record: Add missing -C option support for specifying profile cpu
[linux-2.6/mini2440.git] / drivers / staging / epl / Edrv8139.c
blob44e3f7b144bcb415ecf590a978525f5f1febca17
1 /****************************************************************************
3 (c) SYSTEC electronic GmbH, D-07973 Greiz, August-Bebel-Str. 29
4 www.systec-electronic.com
6 Project: openPOWERLINK
8 Description: Ethernet driver for Realtek RTL8139 chips
9 except the RTL8139C+, because it has a different
10 Tx descriptor handling.
12 License:
14 Redistribution and use in source and binary forms, with or without
15 modification, are permitted provided that the following conditions
16 are met:
18 1. Redistributions of source code must retain the above copyright
19 notice, this list of conditions and the following disclaimer.
21 2. Redistributions in binary form must reproduce the above copyright
22 notice, this list of conditions and the following disclaimer in the
23 documentation and/or other materials provided with the distribution.
25 3. Neither the name of SYSTEC electronic GmbH nor the names of its
26 contributors may be used to endorse or promote products derived
27 from this software without prior written permission. For written
28 permission, please contact info@systec-electronic.com.
30 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
31 "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
32 LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
33 FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
34 COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
35 INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
36 BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
37 LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
38 CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
39 LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
40 ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
41 POSSIBILITY OF SUCH DAMAGE.
43 Severability Clause:
45 If a provision of this License is or becomes illegal, invalid or
46 unenforceable in any jurisdiction, that shall not affect:
47 1. the validity or enforceability in that jurisdiction of any other
48 provision of this License; or
49 2. the validity or enforceability in other jurisdictions of that or
50 any other provision of this License.
52 -------------------------------------------------------------------------
54 $RCSfile: Edrv8139.c,v $
56 $Author: D.Krueger $
58 $Revision: 1.10 $ $Date: 2008/11/21 09:00:38 $
60 $State: Exp $
62 Build Environment:
63 Dev C++ and GNU-Compiler for m68k
65 -------------------------------------------------------------------------
67 Revision History:
69 2008/02/05 d.k.: start of implementation
71 ****************************************************************************/
73 #include "global.h"
74 #include "EplInc.h"
75 #include "edrv.h"
77 #include <linux/module.h>
78 #include <linux/kernel.h>
79 #include <linux/pci.h>
80 #include <linux/interrupt.h>
81 #include <linux/init.h>
82 #include <linux/errno.h>
83 #include <linux/major.h>
84 #include <asm/io.h>
85 #include <asm/uaccess.h>
86 #include <asm/atomic.h>
87 #include <asm/irq.h>
88 #include <linux/sched.h>
89 #include <linux/delay.h>
91 /***************************************************************************/
92 /* */
93 /* */
94 /* G L O B A L D E F I N I T I O N S */
95 /* */
96 /* */
97 /***************************************************************************/
99 // Buffer handling:
100 // All buffers are created statically (i.e. at compile time resp. at
101 // initialisation via kmalloc() ) and not dynamically on request (i.e. via
102 // EdrvAllocTxMsgBuffer().
103 // EdrvAllocTxMsgBuffer() searches for an unused buffer which is large enough.
104 // EdrvInit() may allocate some buffers with sizes less than maximum frame
105 // size (i.e. 1514 bytes), e.g. for SoC, SoA, StatusResponse, IdentResponse,
106 // NMT requests / commands. The less the size of the buffer the less the
107 // number of the buffer.
109 //---------------------------------------------------------------------------
110 // const defines
111 //---------------------------------------------------------------------------
113 #ifndef EDRV_MAX_TX_BUFFERS
114 #define EDRV_MAX_TX_BUFFERS 20
115 #endif
117 #define EDRV_MAX_FRAME_SIZE 0x600
119 #define EDRV_RX_BUFFER_SIZE 0x8610 // 32 kB + 16 Byte + 1,5 kB (WRAP is enabled)
120 #define EDRV_RX_BUFFER_LENGTH (EDRV_RX_BUFFER_SIZE & 0xF800) // buffer size cut down to 2 kB alignment
122 #define EDRV_TX_BUFFER_SIZE (EDRV_MAX_TX_BUFFERS * EDRV_MAX_FRAME_SIZE) // n * (MTU + 14 + 4)
124 #define DRV_NAME "epl"
126 #define EDRV_REGW_INT_MASK 0x3C // interrupt mask register
127 #define EDRV_REGW_INT_STATUS 0x3E // interrupt status register
128 #define EDRV_REGW_INT_ROK 0x0001 // Receive OK interrupt
129 #define EDRV_REGW_INT_RER 0x0002 // Receive error interrupt
130 #define EDRV_REGW_INT_TOK 0x0004 // Transmit OK interrupt
131 #define EDRV_REGW_INT_TER 0x0008 // Transmit error interrupt
132 #define EDRV_REGW_INT_RXOVW 0x0010 // Rx buffer overflow interrupt
133 #define EDRV_REGW_INT_PUN 0x0020 // Packet underrun/ link change interrupt
134 #define EDRV_REGW_INT_FOVW 0x0040 // Rx FIFO overflow interrupt
135 #define EDRV_REGW_INT_LENCHG 0x2000 // Cable length change interrupt
136 #define EDRV_REGW_INT_TIMEOUT 0x4000 // Time out interrupt
137 #define EDRV_REGW_INT_SERR 0x8000 // System error interrupt
138 #define EDRV_REGW_INT_MASK_DEF (EDRV_REGW_INT_ROK \
139 | EDRV_REGW_INT_RER \
140 | EDRV_REGW_INT_TOK \
141 | EDRV_REGW_INT_TER \
142 | EDRV_REGW_INT_RXOVW \
143 | EDRV_REGW_INT_FOVW \
144 | EDRV_REGW_INT_PUN \
145 | EDRV_REGW_INT_TIMEOUT \
146 | EDRV_REGW_INT_SERR) // default interrupt mask
148 #define EDRV_REGB_COMMAND 0x37 // command register
149 #define EDRV_REGB_COMMAND_RST 0x10
150 #define EDRV_REGB_COMMAND_RE 0x08
151 #define EDRV_REGB_COMMAND_TE 0x04
152 #define EDRV_REGB_COMMAND_BUFE 0x01
154 #define EDRV_REGB_CMD9346 0x50 // 93C46 command register
155 #define EDRV_REGB_CMD9346_LOCK 0x00 // lock configuration registers
156 #define EDRV_REGB_CMD9346_UNLOCK 0xC0 // unlock configuration registers
158 #define EDRV_REGDW_RCR 0x44 // Rx configuration register
159 #define EDRV_REGDW_RCR_NO_FTH 0x0000E000 // no receive FIFO threshold
160 #define EDRV_REGDW_RCR_RBLEN32K 0x00001000 // 32 kB receive buffer
161 #define EDRV_REGDW_RCR_MXDMAUNL 0x00000700 // unlimited maximum DMA burst size
162 #define EDRV_REGDW_RCR_NOWRAP 0x00000080 // do not wrap frame at end of buffer
163 #define EDRV_REGDW_RCR_AER 0x00000020 // accept error frames (CRC, alignment, collided)
164 #define EDRV_REGDW_RCR_AR 0x00000010 // accept runt
165 #define EDRV_REGDW_RCR_AB 0x00000008 // accept broadcast frames
166 #define EDRV_REGDW_RCR_AM 0x00000004 // accept multicast frames
167 #define EDRV_REGDW_RCR_APM 0x00000002 // accept physical match frames
168 #define EDRV_REGDW_RCR_AAP 0x00000001 // accept all frames
169 #define EDRV_REGDW_RCR_DEF (EDRV_REGDW_RCR_NO_FTH \
170 | EDRV_REGDW_RCR_RBLEN32K \
171 | EDRV_REGDW_RCR_MXDMAUNL \
172 | EDRV_REGDW_RCR_NOWRAP \
173 | EDRV_REGDW_RCR_AB \
174 | EDRV_REGDW_RCR_AM \
175 | EDRV_REGDW_RCR_APM) // default value
177 #define EDRV_REGDW_TCR 0x40 // Tx configuration register
178 #define EDRV_REGDW_TCR_VER_MASK 0x7CC00000 // mask for hardware version
179 #define EDRV_REGDW_TCR_VER_C 0x74000000 // RTL8139C
180 #define EDRV_REGDW_TCR_VER_D 0x74400000 // RTL8139D
181 #define EDRV_REGDW_TCR_IFG96 0x03000000 // default interframe gap (960 ns)
182 #define EDRV_REGDW_TCR_CRC 0x00010000 // disable appending of CRC by the controller
183 #define EDRV_REGDW_TCR_MXDMAUNL 0x00000700 // maximum DMA burst size of 2048 b
184 #define EDRV_REGDW_TCR_TXRETRY 0x00000000 // 16 retries
185 #define EDRV_REGDW_TCR_DEF (EDRV_REGDW_TCR_IFG96 \
186 | EDRV_REGDW_TCR_MXDMAUNL \
187 | EDRV_REGDW_TCR_TXRETRY)
189 #define EDRV_REGW_MULINT 0x5C // multiple interrupt select register
191 #define EDRV_REGDW_MPC 0x4C // missed packet counter register
193 #define EDRV_REGDW_TSAD0 0x20 // Transmit start address of descriptor 0
194 #define EDRV_REGDW_TSAD1 0x24 // Transmit start address of descriptor 1
195 #define EDRV_REGDW_TSAD2 0x28 // Transmit start address of descriptor 2
196 #define EDRV_REGDW_TSAD3 0x2C // Transmit start address of descriptor 3
197 #define EDRV_REGDW_TSD0 0x10 // Transmit status of descriptor 0
198 #define EDRV_REGDW_TSD_CRS 0x80000000 // Carrier sense lost
199 #define EDRV_REGDW_TSD_TABT 0x40000000 // Transmit Abort
200 #define EDRV_REGDW_TSD_OWC 0x20000000 // Out of window collision
201 #define EDRV_REGDW_TSD_TXTH_DEF 0x00020000 // Transmit FIFO threshold of 64 bytes
202 #define EDRV_REGDW_TSD_TOK 0x00008000 // Transmit OK
203 #define EDRV_REGDW_TSD_TUN 0x00004000 // Transmit FIFO underrun
204 #define EDRV_REGDW_TSD_OWN 0x00002000 // Owner
206 #define EDRV_REGDW_RBSTART 0x30 // Receive buffer start address
208 #define EDRV_REGW_CAPR 0x38 // Current address of packet read
210 #define EDRV_REGDW_IDR0 0x00 // ID register 0
211 #define EDRV_REGDW_IDR4 0x04 // ID register 4
213 #define EDRV_REGDW_MAR0 0x08 // Multicast address register 0
214 #define EDRV_REGDW_MAR4 0x0C // Multicast address register 4
216 // defines for the status word in the receive buffer
217 #define EDRV_RXSTAT_MAR 0x8000 // Multicast address received
218 #define EDRV_RXSTAT_PAM 0x4000 // Physical address matched
219 #define EDRV_RXSTAT_BAR 0x2000 // Broadcast address received
220 #define EDRV_RXSTAT_ISE 0x0020 // Invalid symbol error
221 #define EDRV_RXSTAT_RUNT 0x0010 // Runt packet received
222 #define EDRV_RXSTAT_LONG 0x0008 // Long packet
223 #define EDRV_RXSTAT_CRC 0x0004 // CRC error
224 #define EDRV_RXSTAT_FAE 0x0002 // Frame alignment error
225 #define EDRV_RXSTAT_ROK 0x0001 // Receive OK
227 #define EDRV_REGDW_WRITE(dwReg, dwVal) writel(dwVal, EdrvInstance_l.m_pIoAddr + dwReg)
228 #define EDRV_REGW_WRITE(dwReg, wVal) writew(wVal, EdrvInstance_l.m_pIoAddr + dwReg)
229 #define EDRV_REGB_WRITE(dwReg, bVal) writeb(bVal, EdrvInstance_l.m_pIoAddr + dwReg)
230 #define EDRV_REGDW_READ(dwReg) readl(EdrvInstance_l.m_pIoAddr + dwReg)
231 #define EDRV_REGW_READ(dwReg) readw(EdrvInstance_l.m_pIoAddr + dwReg)
232 #define EDRV_REGB_READ(dwReg) readb(EdrvInstance_l.m_pIoAddr + dwReg)
234 // TracePoint support for realtime-debugging
235 #ifdef _DBG_TRACE_POINTS_
236 void TgtDbgSignalTracePoint(u8 bTracePointNumber_p);
237 void TgtDbgPostTraceValue(u32 dwTraceValue_p);
238 #define TGT_DBG_SIGNAL_TRACE_POINT(p) TgtDbgSignalTracePoint(p)
239 #define TGT_DBG_POST_TRACE_VALUE(v) TgtDbgPostTraceValue(v)
240 #else
241 #define TGT_DBG_SIGNAL_TRACE_POINT(p)
242 #define TGT_DBG_POST_TRACE_VALUE(v)
243 #endif
245 #define EDRV_COUNT_SEND TGT_DBG_SIGNAL_TRACE_POINT(2)
246 #define EDRV_COUNT_TIMEOUT TGT_DBG_SIGNAL_TRACE_POINT(3)
247 #define EDRV_COUNT_PCI_ERR TGT_DBG_SIGNAL_TRACE_POINT(4)
248 #define EDRV_COUNT_TX TGT_DBG_SIGNAL_TRACE_POINT(5)
249 #define EDRV_COUNT_RX TGT_DBG_SIGNAL_TRACE_POINT(6)
250 #define EDRV_COUNT_LATECOLLISION TGT_DBG_SIGNAL_TRACE_POINT(10)
251 #define EDRV_COUNT_TX_COL_RL TGT_DBG_SIGNAL_TRACE_POINT(11)
252 #define EDRV_COUNT_TX_FUN TGT_DBG_SIGNAL_TRACE_POINT(12)
253 #define EDRV_COUNT_TX_ERR TGT_DBG_SIGNAL_TRACE_POINT(13)
254 #define EDRV_COUNT_RX_CRC TGT_DBG_SIGNAL_TRACE_POINT(14)
255 #define EDRV_COUNT_RX_ERR TGT_DBG_SIGNAL_TRACE_POINT(15)
256 #define EDRV_COUNT_RX_FOVW TGT_DBG_SIGNAL_TRACE_POINT(16)
257 #define EDRV_COUNT_RX_PUN TGT_DBG_SIGNAL_TRACE_POINT(17)
258 #define EDRV_COUNT_RX_FAE TGT_DBG_SIGNAL_TRACE_POINT(18)
259 #define EDRV_COUNT_RX_OVW TGT_DBG_SIGNAL_TRACE_POINT(19)
261 #define EDRV_TRACE_CAPR(x) TGT_DBG_POST_TRACE_VALUE(((x) & 0xFFFF) | 0x06000000)
262 #define EDRV_TRACE_RX_CRC(x) TGT_DBG_POST_TRACE_VALUE(((x) & 0xFFFF) | 0x0E000000)
263 #define EDRV_TRACE_RX_ERR(x) TGT_DBG_POST_TRACE_VALUE(((x) & 0xFFFF) | 0x0F000000)
264 #define EDRV_TRACE_RX_PUN(x) TGT_DBG_POST_TRACE_VALUE(((x) & 0xFFFF) | 0x11000000)
265 #define EDRV_TRACE(x) TGT_DBG_POST_TRACE_VALUE(((x) & 0xFFFF0000) | 0x0000FEC0)
267 //---------------------------------------------------------------------------
268 // local types
269 //---------------------------------------------------------------------------
271 typedef struct
273 BOOL m_fUsed;
274 unsigned int m_uiSize;
275 MCD_bufDescFec *m_pBufDescr;
277 } tEdrvTxBufferIntern;
280 // Private structure
281 typedef struct {
282 struct pci_dev *m_pPciDev; // pointer to PCI device structure
283 void *m_pIoAddr; // pointer to register space of Ethernet controller
284 u8 *m_pbRxBuf; // pointer to Rx buffer
285 dma_addr_t m_pRxBufDma;
286 u8 *m_pbTxBuf; // pointer to Tx buffer
287 dma_addr_t m_pTxBufDma;
288 BOOL m_afTxBufUsed[EDRV_MAX_TX_BUFFERS];
289 unsigned int m_uiCurTxDesc;
291 tEdrvInitParam m_InitParam;
292 tEdrvTxBuffer *m_pLastTransmittedTxBuffer;
294 } tEdrvInstance;
296 //---------------------------------------------------------------------------
297 // local function prototypes
298 //---------------------------------------------------------------------------
300 static int EdrvInitOne(struct pci_dev *pPciDev,
301 const struct pci_device_id *pId);
303 static void EdrvRemoveOne(struct pci_dev *pPciDev);
305 //---------------------------------------------------------------------------
306 // modul globale vars
307 //---------------------------------------------------------------------------
308 // buffers and buffer descriptors and pointers
310 static struct pci_device_id aEdrvPciTbl[] = {
311 {0x10ec, 0x8139, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
312 {0,}
315 MODULE_DEVICE_TABLE(pci, aEdrvPciTbl);
317 static tEdrvInstance EdrvInstance_l;
319 static struct pci_driver EdrvDriver = {
320 .name = DRV_NAME,
321 .id_table = aEdrvPciTbl,
322 .probe = EdrvInitOne,
323 .remove = EdrvRemoveOne,
326 /***************************************************************************/
327 /* */
328 /* */
329 /* C L A S S <edrv> */
330 /* */
331 /* */
332 /***************************************************************************/
334 // Description:
337 /***************************************************************************/
339 //=========================================================================//
340 // //
341 // P R I V A T E D E F I N I T I O N S //
342 // //
343 //=========================================================================//
345 //---------------------------------------------------------------------------
346 // const defines
347 //---------------------------------------------------------------------------
349 //---------------------------------------------------------------------------
350 // local types
351 //---------------------------------------------------------------------------
353 //---------------------------------------------------------------------------
354 // local vars
355 //---------------------------------------------------------------------------
357 //---------------------------------------------------------------------------
358 // local function prototypes
359 //---------------------------------------------------------------------------
361 static u8 EdrvCalcHash(u8 * pbMAC_p);
363 //---------------------------------------------------------------------------
365 // Function: EdrvInit
367 // Description: function for init of the Ethernet controller
369 // Parameters: pEdrvInitParam_p = pointer to struct including the init-parameters
371 // Returns: Errorcode = kEplSuccessful
372 // = kEplNoResource
374 // State:
376 //---------------------------------------------------------------------------
377 tEplKernel EdrvInit(tEdrvInitParam * pEdrvInitParam_p)
379 tEplKernel Ret;
380 int iResult;
382 Ret = kEplSuccessful;
384 // clear instance structure
385 EPL_MEMSET(&EdrvInstance_l, 0, sizeof(EdrvInstance_l));
387 // save the init data
388 EdrvInstance_l.m_InitParam = *pEdrvInitParam_p;
390 // register PCI driver
391 iResult = pci_register_driver(&EdrvDriver);
392 if (iResult != 0) {
393 printk("%s pci_register_driver failed with %d\n", __func__,
394 iResult);
395 Ret = kEplNoResource;
396 goto Exit;
399 if (EdrvInstance_l.m_pPciDev == NULL) {
400 printk("%s m_pPciDev=NULL\n", __func__);
401 Ret = kEplNoResource;
402 goto Exit;
404 // read MAC address from controller
405 printk("%s local MAC = ", __func__);
406 for (iResult = 0; iResult < 6; iResult++) {
407 pEdrvInitParam_p->m_abMyMacAddr[iResult] =
408 EDRV_REGB_READ((EDRV_REGDW_IDR0 + iResult));
409 printk("%02X ",
410 (unsigned int)pEdrvInitParam_p->m_abMyMacAddr[iResult]);
412 printk("\n");
414 Exit:
415 return Ret;
419 //---------------------------------------------------------------------------
421 // Function: EdrvShutdown
423 // Description: Shutdown the Ethernet controller
425 // Parameters: void
427 // Returns: Errorcode = kEplSuccessful
429 // State:
431 //---------------------------------------------------------------------------
432 tEplKernel EdrvShutdown(void)
435 // unregister PCI driver
436 printk("%s calling pci_unregister_driver()\n", __func__);
437 pci_unregister_driver(&EdrvDriver);
439 return kEplSuccessful;
442 //---------------------------------------------------------------------------
444 // Function: EdrvDefineRxMacAddrEntry
446 // Description: Set a multicast entry into the Ethernet controller
448 // Parameters: pbMacAddr_p = pointer to multicast entry to set
450 // Returns: Errorcode = kEplSuccessful
452 // State:
454 //---------------------------------------------------------------------------
455 tEplKernel EdrvDefineRxMacAddrEntry(u8 * pbMacAddr_p)
457 tEplKernel Ret = kEplSuccessful;
458 u32 dwData;
459 u8 bHash;
461 bHash = EdrvCalcHash(pbMacAddr_p);
463 dwData = ether_crc(6, pbMacAddr_p);
465 printk("EdrvDefineRxMacAddrEntry('%02X:%02X:%02X:%02X:%02X:%02X') hash = %u / %u ether_crc = 0x%08lX\n",
466 (u16) pbMacAddr_p[0], (u16) pbMacAddr_p[1], (u16) pbMacAddr_p[2],
467 (u16) pbMacAddr_p[3], (u16) pbMacAddr_p[4], (u16) pbMacAddr_p[5],
468 (u16) bHash, (u16) (dwData >> 26), dwData);
470 if (bHash > 31) {
471 dwData = EDRV_REGDW_READ(EDRV_REGDW_MAR4);
472 dwData |= 1 << (bHash - 32);
473 EDRV_REGDW_WRITE(EDRV_REGDW_MAR4, dwData);
474 } else {
475 dwData = EDRV_REGDW_READ(EDRV_REGDW_MAR0);
476 dwData |= 1 << bHash;
477 EDRV_REGDW_WRITE(EDRV_REGDW_MAR0, dwData);
480 return Ret;
483 //---------------------------------------------------------------------------
485 // Function: EdrvUndefineRxMacAddrEntry
487 // Description: Reset a multicast entry in the Ethernet controller
489 // Parameters: pbMacAddr_p = pointer to multicast entry to reset
491 // Returns: Errorcode = kEplSuccessful
493 // State:
495 //---------------------------------------------------------------------------
496 tEplKernel EdrvUndefineRxMacAddrEntry(u8 * pbMacAddr_p)
498 tEplKernel Ret = kEplSuccessful;
499 u32 dwData;
500 u8 bHash;
502 bHash = EdrvCalcHash(pbMacAddr_p);
504 if (bHash > 31) {
505 dwData = EDRV_REGDW_READ(EDRV_REGDW_MAR4);
506 dwData &= ~(1 << (bHash - 32));
507 EDRV_REGDW_WRITE(EDRV_REGDW_MAR4, dwData);
508 } else {
509 dwData = EDRV_REGDW_READ(EDRV_REGDW_MAR0);
510 dwData &= ~(1 << bHash);
511 EDRV_REGDW_WRITE(EDRV_REGDW_MAR0, dwData);
514 return Ret;
517 //---------------------------------------------------------------------------
519 // Function: EdrvAllocTxMsgBuffer
521 // Description: Register a Tx-Buffer
523 // Parameters: pBuffer_p = pointer to Buffer structure
525 // Returns: Errorcode = kEplSuccessful
526 // = kEplEdrvNoFreeBufEntry
528 // State:
530 //---------------------------------------------------------------------------
531 tEplKernel EdrvAllocTxMsgBuffer(tEdrvTxBuffer * pBuffer_p)
533 tEplKernel Ret = kEplSuccessful;
534 u32 i;
536 if (pBuffer_p->m_uiMaxBufferLen > EDRV_MAX_FRAME_SIZE) {
537 Ret = kEplEdrvNoFreeBufEntry;
538 goto Exit;
540 // search a free Tx buffer with appropriate size
541 for (i = 0; i < EDRV_MAX_TX_BUFFERS; i++) {
542 if (EdrvInstance_l.m_afTxBufUsed[i] == FALSE) {
543 // free channel found
544 EdrvInstance_l.m_afTxBufUsed[i] = TRUE;
545 pBuffer_p->m_uiBufferNumber = i;
546 pBuffer_p->m_pbBuffer =
547 EdrvInstance_l.m_pbTxBuf +
548 (i * EDRV_MAX_FRAME_SIZE);
549 pBuffer_p->m_uiMaxBufferLen = EDRV_MAX_FRAME_SIZE;
550 break;
553 if (i >= EDRV_MAX_TX_BUFFERS) {
554 Ret = kEplEdrvNoFreeBufEntry;
555 goto Exit;
558 Exit:
559 return Ret;
563 //---------------------------------------------------------------------------
565 // Function: EdrvReleaseTxMsgBuffer
567 // Description: Register a Tx-Buffer
569 // Parameters: pBuffer_p = pointer to Buffer structure
571 // Returns: Errorcode = kEplSuccessful
573 // State:
575 //---------------------------------------------------------------------------
576 tEplKernel EdrvReleaseTxMsgBuffer(tEdrvTxBuffer * pBuffer_p)
578 unsigned int uiBufferNumber;
580 uiBufferNumber = pBuffer_p->m_uiBufferNumber;
582 if (uiBufferNumber < EDRV_MAX_TX_BUFFERS) {
583 EdrvInstance_l.m_afTxBufUsed[uiBufferNumber] = FALSE;
586 return kEplSuccessful;
590 //---------------------------------------------------------------------------
592 // Function: EdrvSendTxMsg
594 // Description: immediately starts the transmission of the buffer
596 // Parameters: pBuffer_p = buffer descriptor to transmit
598 // Returns: Errorcode = kEplSuccessful
600 // State:
602 //---------------------------------------------------------------------------
603 tEplKernel EdrvSendTxMsg(tEdrvTxBuffer * pBuffer_p)
605 tEplKernel Ret = kEplSuccessful;
606 unsigned int uiBufferNumber;
607 u32 dwTemp;
609 uiBufferNumber = pBuffer_p->m_uiBufferNumber;
611 if ((uiBufferNumber >= EDRV_MAX_TX_BUFFERS)
612 || (EdrvInstance_l.m_afTxBufUsed[uiBufferNumber] == FALSE)) {
613 Ret = kEplEdrvBufNotExisting;
614 goto Exit;
617 if (EdrvInstance_l.m_pLastTransmittedTxBuffer != NULL) { // transmission is already active
618 Ret = kEplInvalidOperation;
619 dwTemp =
620 EDRV_REGDW_READ((EDRV_REGDW_TSD0 +
621 (EdrvInstance_l.m_uiCurTxDesc *
622 sizeof(u32))));
623 printk("%s InvOp TSD%u = 0x%08X", __func__,
624 EdrvInstance_l.m_uiCurTxDesc, dwTemp);
625 printk(" Cmd = 0x%02X\n",
626 (u16) EDRV_REGB_READ(EDRV_REGB_COMMAND));
627 goto Exit;
629 // save pointer to buffer structure for TxHandler
630 EdrvInstance_l.m_pLastTransmittedTxBuffer = pBuffer_p;
632 EDRV_COUNT_SEND;
634 // pad with zeros if necessary, because controller does not do it
635 if (pBuffer_p->m_uiTxMsgLen < MIN_ETH_SIZE) {
636 EPL_MEMSET(pBuffer_p->m_pbBuffer + pBuffer_p->m_uiTxMsgLen, 0,
637 MIN_ETH_SIZE - pBuffer_p->m_uiTxMsgLen);
638 pBuffer_p->m_uiTxMsgLen = MIN_ETH_SIZE;
640 // set DMA address of buffer
641 EDRV_REGDW_WRITE((EDRV_REGDW_TSAD0 +
642 (EdrvInstance_l.m_uiCurTxDesc * sizeof(u32))),
643 (EdrvInstance_l.m_pTxBufDma +
644 (uiBufferNumber * EDRV_MAX_FRAME_SIZE)));
645 dwTemp =
646 EDRV_REGDW_READ((EDRV_REGDW_TSAD0 +
647 (EdrvInstance_l.m_uiCurTxDesc * sizeof(u32))));
648 // printk("%s TSAD%u = 0x%08lX", __func__, EdrvInstance_l.m_uiCurTxDesc, dwTemp);
650 // start transmission
651 EDRV_REGDW_WRITE((EDRV_REGDW_TSD0 +
652 (EdrvInstance_l.m_uiCurTxDesc * sizeof(u32))),
653 (EDRV_REGDW_TSD_TXTH_DEF | pBuffer_p->m_uiTxMsgLen));
654 dwTemp =
655 EDRV_REGDW_READ((EDRV_REGDW_TSD0 +
656 (EdrvInstance_l.m_uiCurTxDesc * sizeof(u32))));
657 // printk(" TSD%u = 0x%08lX / 0x%08lX\n", EdrvInstance_l.m_uiCurTxDesc, dwTemp, (u32)(EDRV_REGDW_TSD_TXTH_DEF | pBuffer_p->m_uiTxMsgLen));
659 Exit:
660 return Ret;
663 #if 0
664 //---------------------------------------------------------------------------
666 // Function: EdrvTxMsgReady
668 // Description: starts copying the buffer to the ethernet controller's FIFO
670 // Parameters: pbBuffer_p - bufferdescriptor to transmit
672 // Returns: Errorcode - kEplSuccessful
674 // State:
676 //---------------------------------------------------------------------------
677 tEplKernel EdrvTxMsgReady(tEdrvTxBuffer * pBuffer_p)
679 tEplKernel Ret = kEplSuccessful;
680 unsigned int uiBufferNumber;
682 Exit:
683 return Ret;
686 //---------------------------------------------------------------------------
688 // Function: EdrvTxMsgStart
690 // Description: starts transmission of the ethernet controller's FIFO
692 // Parameters: pbBuffer_p - bufferdescriptor to transmit
694 // Returns: Errorcode - kEplSuccessful
696 // State:
698 //---------------------------------------------------------------------------
699 tEplKernel EdrvTxMsgStart(tEdrvTxBuffer * pBuffer_p)
701 tEplKernel Ret = kEplSuccessful;
703 return Ret;
705 #endif
707 //---------------------------------------------------------------------------
709 // Function: EdrvReinitRx
711 // Description: reinitialize the Rx process, because of error
713 // Parameters: void
715 // Returns: void
717 // State:
719 //---------------------------------------------------------------------------
720 static void EdrvReinitRx(void)
722 u8 bCmd;
724 // simply switch off and on the receiver
725 // this will reset the CAPR register
726 bCmd = EDRV_REGB_READ(EDRV_REGB_COMMAND);
727 EDRV_REGB_WRITE(EDRV_REGB_COMMAND, (bCmd & ~EDRV_REGB_COMMAND_RE));
728 EDRV_REGB_WRITE(EDRV_REGB_COMMAND, bCmd);
730 // set receive configuration register
731 EDRV_REGDW_WRITE(EDRV_REGDW_RCR, EDRV_REGDW_RCR_DEF);
734 //---------------------------------------------------------------------------
736 // Function: EdrvInterruptHandler
738 // Description: interrupt handler
740 // Parameters: void
742 // Returns: void
744 // State:
746 //---------------------------------------------------------------------------
747 #if 0
748 void EdrvInterruptHandler(void)
751 #endif
753 static int TgtEthIsr(int nIrqNum_p, void *ppDevInstData_p)
755 // EdrvInterruptHandler();
756 tEdrvRxBuffer RxBuffer;
757 tEdrvTxBuffer *pTxBuffer;
758 u16 wStatus;
759 u32 dwTxStatus;
760 u32 dwRxStatus;
761 u16 wCurRx;
762 u8 *pbRxBuf;
763 unsigned int uiLength;
764 int iHandled = IRQ_HANDLED;
766 // printk("¤");
768 // read the interrupt status
769 wStatus = EDRV_REGW_READ(EDRV_REGW_INT_STATUS);
771 // acknowledge the interrupts
772 EDRV_REGW_WRITE(EDRV_REGW_INT_STATUS, wStatus);
774 if (wStatus == 0) {
775 iHandled = IRQ_NONE;
776 goto Exit;
778 // process tasks
779 if ((wStatus & (EDRV_REGW_INT_TER | EDRV_REGW_INT_TOK)) != 0) { // transmit interrupt
781 if (EdrvInstance_l.m_pbTxBuf == NULL) {
782 printk("%s Tx buffers currently not allocated\n",
783 __func__);
784 goto Exit;
786 // read transmit status
787 dwTxStatus =
788 EDRV_REGDW_READ((EDRV_REGDW_TSD0 +
789 (EdrvInstance_l.m_uiCurTxDesc *
790 sizeof(u32))));
791 if ((dwTxStatus & (EDRV_REGDW_TSD_TOK | EDRV_REGDW_TSD_TABT | EDRV_REGDW_TSD_TUN)) != 0) { // transmit finished
792 EdrvInstance_l.m_uiCurTxDesc =
793 (EdrvInstance_l.m_uiCurTxDesc + 1) & 0x03;
794 pTxBuffer = EdrvInstance_l.m_pLastTransmittedTxBuffer;
795 EdrvInstance_l.m_pLastTransmittedTxBuffer = NULL;
797 if ((dwTxStatus & EDRV_REGDW_TSD_TOK) != 0) {
798 EDRV_COUNT_TX;
799 } else if ((dwTxStatus & EDRV_REGDW_TSD_TUN) != 0) {
800 EDRV_COUNT_TX_FUN;
801 } else { // assume EDRV_REGDW_TSD_TABT
802 EDRV_COUNT_TX_COL_RL;
805 // printk("T");
806 if (pTxBuffer != NULL) {
807 // call Tx handler of Data link layer
808 EdrvInstance_l.m_InitParam.
809 m_pfnTxHandler(pTxBuffer);
811 } else {
812 EDRV_COUNT_TX_ERR;
816 if ((wStatus & (EDRV_REGW_INT_RER | EDRV_REGW_INT_FOVW | EDRV_REGW_INT_RXOVW | EDRV_REGW_INT_PUN)) != 0) { // receive error interrupt
818 if ((wStatus & EDRV_REGW_INT_FOVW) != 0) {
819 EDRV_COUNT_RX_FOVW;
820 } else if ((wStatus & EDRV_REGW_INT_RXOVW) != 0) {
821 EDRV_COUNT_RX_OVW;
822 } else if ((wStatus & EDRV_REGW_INT_PUN) != 0) { // Packet underrun
823 EDRV_TRACE_RX_PUN(wStatus);
824 EDRV_COUNT_RX_PUN;
825 } else { /*if ((wStatus & EDRV_REGW_INT_RER) != 0) */
827 EDRV_TRACE_RX_ERR(wStatus);
828 EDRV_COUNT_RX_ERR;
831 // reinitialize Rx process
832 EdrvReinitRx();
835 if ((wStatus & EDRV_REGW_INT_ROK) != 0) { // receive interrupt
837 if (EdrvInstance_l.m_pbRxBuf == NULL) {
838 printk("%s Rx buffers currently not allocated\n",
839 __func__);
840 goto Exit;
842 // read current offset in receive buffer
843 wCurRx =
844 (EDRV_REGW_READ(EDRV_REGW_CAPR) +
845 0x10) % EDRV_RX_BUFFER_LENGTH;
847 while ((EDRV_REGB_READ(EDRV_REGB_COMMAND) & EDRV_REGB_COMMAND_BUFE) == 0) { // frame available
849 // calculate pointer to current frame in receive buffer
850 pbRxBuf = EdrvInstance_l.m_pbRxBuf + wCurRx;
852 // read receive status u32
853 dwRxStatus = le32_to_cpu(*((u32 *) pbRxBuf));
855 // calculate length of received frame
856 uiLength = dwRxStatus >> 16;
858 if (uiLength == 0xFFF0) { // frame is unfinished (maybe early Rx interrupt is active)
859 break;
862 if ((dwRxStatus & EDRV_RXSTAT_ROK) == 0) { // error occured while receiving this frame
863 // ignore it
864 if ((dwRxStatus & EDRV_RXSTAT_FAE) != 0) {
865 EDRV_COUNT_RX_FAE;
866 } else if ((dwRxStatus & EDRV_RXSTAT_CRC) != 0) {
867 EDRV_TRACE_RX_CRC(dwRxStatus);
868 EDRV_COUNT_RX_CRC;
869 } else {
870 EDRV_TRACE_RX_ERR(dwRxStatus);
871 EDRV_COUNT_RX_ERR;
874 // reinitialize Rx process
875 EdrvReinitRx();
877 break;
878 } else { // frame is OK
879 RxBuffer.m_BufferInFrame =
880 kEdrvBufferLastInFrame;
881 RxBuffer.m_uiRxMsgLen = uiLength - ETH_CRC_SIZE;
882 RxBuffer.m_pbBuffer =
883 pbRxBuf + sizeof(dwRxStatus);
885 // printk("R");
886 EDRV_COUNT_RX;
888 // call Rx handler of Data link layer
889 EdrvInstance_l.m_InitParam.
890 m_pfnRxHandler(&RxBuffer);
893 // calulate new offset (u32 aligned)
894 wCurRx =
895 (u16) ((wCurRx + uiLength + sizeof(dwRxStatus) +
896 3) & ~0x3);
897 EDRV_TRACE_CAPR(wCurRx - 0x10);
898 EDRV_REGW_WRITE(EDRV_REGW_CAPR, wCurRx - 0x10);
900 // reread current offset in receive buffer
901 wCurRx =
902 (EDRV_REGW_READ(EDRV_REGW_CAPR) +
903 0x10) % EDRV_RX_BUFFER_LENGTH;
908 if ((wStatus & EDRV_REGW_INT_SERR) != 0) { // PCI error
909 EDRV_COUNT_PCI_ERR;
912 if ((wStatus & EDRV_REGW_INT_TIMEOUT) != 0) { // Timeout
913 EDRV_COUNT_TIMEOUT;
916 Exit:
917 return iHandled;
920 //---------------------------------------------------------------------------
922 // Function: EdrvInitOne
924 // Description: initializes one PCI device
926 // Parameters: pPciDev = pointer to corresponding PCI device structure
927 // pId = PCI device ID
929 // Returns: (int) = error code
931 // State:
933 //---------------------------------------------------------------------------
935 static int EdrvInitOne(struct pci_dev *pPciDev, const struct pci_device_id *pId)
937 int iResult = 0;
938 u32 dwTemp;
940 if (EdrvInstance_l.m_pPciDev != NULL) { // Edrv is already connected to a PCI device
941 printk("%s device %s discarded\n", __func__,
942 pci_name(pPciDev));
943 iResult = -ENODEV;
944 goto Exit;
947 if (pPciDev->revision >= 0x20) {
948 printk
949 ("%s device %s is an enhanced 8139C+ version, which is not supported\n",
950 __func__, pci_name(pPciDev));
951 iResult = -ENODEV;
952 goto Exit;
955 EdrvInstance_l.m_pPciDev = pPciDev;
957 // enable device
958 printk("%s enable device\n", __func__);
959 iResult = pci_enable_device(pPciDev);
960 if (iResult != 0) {
961 goto Exit;
964 if ((pci_resource_flags(pPciDev, 1) & IORESOURCE_MEM) == 0) {
965 iResult = -ENODEV;
966 goto Exit;
969 printk("%s request regions\n", __func__);
970 iResult = pci_request_regions(pPciDev, DRV_NAME);
971 if (iResult != 0) {
972 goto Exit;
975 printk("%s ioremap\n", __func__);
976 EdrvInstance_l.m_pIoAddr =
977 ioremap(pci_resource_start(pPciDev, 1),
978 pci_resource_len(pPciDev, 1));
979 if (EdrvInstance_l.m_pIoAddr == NULL) { // remap of controller's register space failed
980 iResult = -EIO;
981 goto Exit;
983 // enable PCI busmaster
984 printk("%s enable busmaster\n", __func__);
985 pci_set_master(pPciDev);
987 // reset controller
988 printk("%s reset controller\n", __func__);
989 EDRV_REGB_WRITE(EDRV_REGB_COMMAND, EDRV_REGB_COMMAND_RST);
991 // wait until reset has finished
992 for (iResult = 500; iResult > 0; iResult--) {
993 if ((EDRV_REGB_READ(EDRV_REGB_COMMAND) & EDRV_REGB_COMMAND_RST)
994 == 0) {
995 break;
998 schedule_timeout(10);
1001 // check hardware version, i.e. chip ID
1002 dwTemp = EDRV_REGDW_READ(EDRV_REGDW_TCR);
1003 if (((dwTemp & EDRV_REGDW_TCR_VER_MASK) != EDRV_REGDW_TCR_VER_C)
1004 && ((dwTemp & EDRV_REGDW_TCR_VER_MASK) != EDRV_REGDW_TCR_VER_D)) { // unsupported chip
1005 printk("%s Unsupported chip! TCR = 0x%08X\n", __func__,
1006 dwTemp);
1007 iResult = -ENODEV;
1008 goto Exit;
1010 // disable interrupts
1011 printk("%s disable interrupts\n", __func__);
1012 EDRV_REGW_WRITE(EDRV_REGW_INT_MASK, 0);
1013 // acknowledge all pending interrupts
1014 EDRV_REGW_WRITE(EDRV_REGW_INT_STATUS,
1015 EDRV_REGW_READ(EDRV_REGW_INT_STATUS));
1017 // install interrupt handler
1018 printk("%s install interrupt handler\n", __func__);
1019 iResult =
1020 request_irq(pPciDev->irq, TgtEthIsr, IRQF_SHARED,
1021 DRV_NAME /*pPciDev->dev.name */ , pPciDev);
1022 if (iResult != 0) {
1023 goto Exit;
1027 // unlock configuration registers
1028 printk("%s unlock configuration registers\n", __func__);
1029 EDRV_REGB_WRITE(EDRV_REGB_CMD9346, EDRV_REGB_CMD9346_UNLOCK);
1031 // check if user specified a MAC address
1032 printk("%s check specified MAC address\n", __func__);
1033 for (iResult = 0; iResult < 6; iResult++)
1035 if (EdrvInstance_l.m_InitParam.m_abMyMacAddr[iResult] != 0)
1037 printk("%s set local MAC address\n", __func__);
1038 // write this MAC address to controller
1039 EDRV_REGDW_WRITE(EDRV_REGDW_IDR0,
1040 le32_to_cpu(*((u32*)&EdrvInstance_l.m_InitParam.m_abMyMacAddr[0])));
1041 dwTemp = EDRV_REGDW_READ(EDRV_REGDW_IDR0);
1043 EDRV_REGDW_WRITE(EDRV_REGDW_IDR4,
1044 le32_to_cpu(*((u32*)&EdrvInstance_l.m_InitParam.m_abMyMacAddr[4])));
1045 dwTemp = EDRV_REGDW_READ(EDRV_REGDW_IDR4);
1046 break;
1049 iResult = 0;
1051 // lock configuration registers
1052 EDRV_REGB_WRITE(EDRV_REGB_CMD9346, EDRV_REGB_CMD9346_LOCK);
1055 // allocate buffers
1056 printk("%s allocate buffers\n", __func__);
1057 EdrvInstance_l.m_pbTxBuf =
1058 pci_alloc_consistent(pPciDev, EDRV_TX_BUFFER_SIZE,
1059 &EdrvInstance_l.m_pTxBufDma);
1060 if (EdrvInstance_l.m_pbTxBuf == NULL) {
1061 iResult = -ENOMEM;
1062 goto Exit;
1065 EdrvInstance_l.m_pbRxBuf =
1066 pci_alloc_consistent(pPciDev, EDRV_RX_BUFFER_SIZE,
1067 &EdrvInstance_l.m_pRxBufDma);
1068 if (EdrvInstance_l.m_pbRxBuf == NULL) {
1069 iResult = -ENOMEM;
1070 goto Exit;
1072 // reset pointers for Tx buffers
1073 printk("%s reset pointers fo Tx buffers\n", __func__);
1074 EDRV_REGDW_WRITE(EDRV_REGDW_TSAD0, 0);
1075 dwTemp = EDRV_REGDW_READ(EDRV_REGDW_TSAD0);
1076 EDRV_REGDW_WRITE(EDRV_REGDW_TSAD1, 0);
1077 dwTemp = EDRV_REGDW_READ(EDRV_REGDW_TSAD1);
1078 EDRV_REGDW_WRITE(EDRV_REGDW_TSAD2, 0);
1079 dwTemp = EDRV_REGDW_READ(EDRV_REGDW_TSAD2);
1080 EDRV_REGDW_WRITE(EDRV_REGDW_TSAD3, 0);
1081 dwTemp = EDRV_REGDW_READ(EDRV_REGDW_TSAD3);
1083 printk(" Command = 0x%02X\n",
1084 (u16) EDRV_REGB_READ(EDRV_REGB_COMMAND));
1086 // set pointer for receive buffer in controller
1087 printk("%s set pointer to Rx buffer\n", __func__);
1088 EDRV_REGDW_WRITE(EDRV_REGDW_RBSTART, EdrvInstance_l.m_pRxBufDma);
1090 // enable transmitter and receiver
1091 printk("%s enable Tx and Rx", __func__);
1092 EDRV_REGB_WRITE(EDRV_REGB_COMMAND,
1093 (EDRV_REGB_COMMAND_RE | EDRV_REGB_COMMAND_TE));
1094 printk(" Command = 0x%02X\n",
1095 (u16) EDRV_REGB_READ(EDRV_REGB_COMMAND));
1097 // clear missed packet counter to enable Rx/Tx process
1098 EDRV_REGDW_WRITE(EDRV_REGDW_MPC, 0);
1100 // set transmit configuration register
1101 printk("%s set Tx conf register", __func__);
1102 EDRV_REGDW_WRITE(EDRV_REGDW_TCR, EDRV_REGDW_TCR_DEF);
1103 printk(" = 0x%08X\n", EDRV_REGDW_READ(EDRV_REGDW_TCR));
1105 // set receive configuration register
1106 printk("%s set Rx conf register", __func__);
1107 EDRV_REGDW_WRITE(EDRV_REGDW_RCR, EDRV_REGDW_RCR_DEF);
1108 printk(" = 0x%08X\n", EDRV_REGDW_READ(EDRV_REGDW_RCR));
1110 // reset multicast MAC address filter
1111 EDRV_REGDW_WRITE(EDRV_REGDW_MAR0, 0);
1112 dwTemp = EDRV_REGDW_READ(EDRV_REGDW_MAR0);
1113 EDRV_REGDW_WRITE(EDRV_REGDW_MAR4, 0);
1114 dwTemp = EDRV_REGDW_READ(EDRV_REGDW_MAR4);
1117 // enable transmitter and receiver
1118 printk("%s enable Tx and Rx", __func__);
1119 EDRV_REGB_WRITE(EDRV_REGB_COMMAND, (EDRV_REGB_COMMAND_RE | EDRV_REGB_COMMAND_TE));
1120 printk(" Command = 0x%02X\n", (u16) EDRV_REGB_READ(EDRV_REGB_COMMAND));
1122 // disable early interrupts
1123 EDRV_REGW_WRITE(EDRV_REGW_MULINT, 0);
1125 // enable interrupts
1126 printk("%s enable interrupts\n", __func__);
1127 EDRV_REGW_WRITE(EDRV_REGW_INT_MASK, EDRV_REGW_INT_MASK_DEF);
1129 Exit:
1130 printk("%s finished with %d\n", __func__, iResult);
1131 return iResult;
1134 //---------------------------------------------------------------------------
1136 // Function: EdrvRemoveOne
1138 // Description: shuts down one PCI device
1140 // Parameters: pPciDev = pointer to corresponding PCI device structure
1142 // Returns: (void)
1144 // State:
1146 //---------------------------------------------------------------------------
1148 static void EdrvRemoveOne(struct pci_dev *pPciDev)
1151 if (EdrvInstance_l.m_pPciDev != pPciDev) { // trying to remove unknown device
1152 BUG_ON(EdrvInstance_l.m_pPciDev != pPciDev);
1153 goto Exit;
1155 // disable transmitter and receiver
1156 EDRV_REGB_WRITE(EDRV_REGB_COMMAND, 0);
1158 // disable interrupts
1159 EDRV_REGW_WRITE(EDRV_REGW_INT_MASK, 0);
1161 // remove interrupt handler
1162 free_irq(pPciDev->irq, pPciDev);
1164 // free buffers
1165 if (EdrvInstance_l.m_pbTxBuf != NULL) {
1166 pci_free_consistent(pPciDev, EDRV_TX_BUFFER_SIZE,
1167 EdrvInstance_l.m_pbTxBuf,
1168 EdrvInstance_l.m_pTxBufDma);
1169 EdrvInstance_l.m_pbTxBuf = NULL;
1172 if (EdrvInstance_l.m_pbRxBuf != NULL) {
1173 pci_free_consistent(pPciDev, EDRV_RX_BUFFER_SIZE,
1174 EdrvInstance_l.m_pbRxBuf,
1175 EdrvInstance_l.m_pRxBufDma);
1176 EdrvInstance_l.m_pbRxBuf = NULL;
1178 // unmap controller's register space
1179 if (EdrvInstance_l.m_pIoAddr != NULL) {
1180 iounmap(EdrvInstance_l.m_pIoAddr);
1182 // disable the PCI device
1183 pci_disable_device(pPciDev);
1185 // release memory regions
1186 pci_release_regions(pPciDev);
1188 EdrvInstance_l.m_pPciDev = NULL;
1190 Exit:;
1193 //---------------------------------------------------------------------------
1195 // Function: EdrvCalcHash
1197 // Description: function calculates the entry for the hash-table from MAC
1198 // address
1200 // Parameters: pbMAC_p - pointer to MAC address
1202 // Returns: hash value
1204 // State:
1206 //---------------------------------------------------------------------------
1207 #define HASH_BITS 6 // used bits in hash
1208 #define CRC32_POLY 0x04C11DB6 //
1209 //#define CRC32_POLY 0xEDB88320 //
1210 // G(x) = x32 + x26 + x23 + x22 + x16 + x12 + x11 + x10 + x8 + x7 + x5 + x4 + x2 + x + 1
1212 static u8 EdrvCalcHash(u8 * pbMAC_p)
1214 u32 dwByteCounter;
1215 u32 dwBitCounter;
1216 u32 dwData;
1217 u32 dwCrc;
1218 u32 dwCarry;
1219 u8 *pbData;
1220 u8 bHash;
1222 pbData = pbMAC_p;
1224 // calculate crc32 value of mac address
1225 dwCrc = 0xFFFFFFFF;
1227 for (dwByteCounter = 0; dwByteCounter < 6; dwByteCounter++) {
1228 dwData = *pbData;
1229 pbData++;
1230 for (dwBitCounter = 0; dwBitCounter < 8;
1231 dwBitCounter++, dwData >>= 1) {
1232 dwCarry = (((dwCrc >> 31) ^ dwData) & 1);
1233 dwCrc = dwCrc << 1;
1234 if (dwCarry != 0) {
1235 dwCrc = (dwCrc ^ CRC32_POLY) | dwCarry;
1240 // printk("MyCRC = 0x%08lX\n", dwCrc);
1241 // only upper 6 bits (HASH_BITS) are used
1242 // which point to specific bit in the hash registers
1243 bHash = (u8) ((dwCrc >> (32 - HASH_BITS)) & 0x3f);
1245 return bHash;