dm9000_driver.c
Go to the documentation of this file.
1 /**
2  * @file dm9000_driver.c
3  * @brief DM9000A/B Ethernet controller
4  *
5  * @section License
6  *
7  * Copyright (C) 2010-2018 Oryx Embedded SARL. All rights reserved.
8  *
9  * This file is part of CycloneTCP Open.
10  *
11  * This program is free software; you can redistribute it and/or
12  * modify it under the terms of the GNU General Public License
13  * as published by the Free Software Foundation; either version 2
14  * of the License, or (at your option) any later version.
15  *
16  * This program is distributed in the hope that it will be useful,
17  * but WITHOUT ANY WARRANTY; without even the implied warranty of
18  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19  * GNU General Public License for more details.
20  *
21  * You should have received a copy of the GNU General Public License
22  * along with this program; if not, write to the Free Software Foundation,
23  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
24  *
25  * @author Oryx Embedded SARL (www.oryx-embedded.com)
26  * @version 1.9.0
27  **/
28 
29 //Switch to the appropriate trace level
30 #define TRACE_LEVEL NIC_TRACE_LEVEL
31 
32 //Dependencies
33 #include "core/net.h"
34 #include "core/ethernet.h"
36 #include "debug.h"
37 
38 
39 /**
40  * @brief DM9000 driver
41  **/
42 
44 {
46  ETH_MTU,
47  dm9000Init,
48  dm9000Tick,
54  NULL,
55  NULL,
56  NULL,
57  TRUE,
58  TRUE,
59  TRUE,
60  FALSE
61 };
62 
63 
64 /**
65  * @brief DM9000 controller initialization
66  * @param[in] interface Underlying network interface
67  * @return Error code
68  **/
69 
71 {
72  uint_t i;
73  uint16_t vendorId;
74  uint16_t productId;
75  uint8_t chipRevision;
76  Dm9000Context *context;
77 
78  //Debug message
79  TRACE_INFO("Initializing DM9000 Ethernet controller...\r\n");
80 
81  //Initialize external interrupt line
82  interface->extIntDriver->init();
83 
84  //Point to the driver context
85  context = (Dm9000Context *) interface->nicContext;
86 
87  //Initialize driver specific variables
88  context->queuedPackets = 0;
89 
90  //Allocate TX and RX buffers
93 
94  //Failed to allocate memory?
95  if(context->txBuffer == NULL || context->rxBuffer == NULL)
96  {
97  //Clean up side effects
98  memPoolFree(context->txBuffer);
99  memPoolFree(context->rxBuffer);
100 
101  //Report an error
102  return ERROR_OUT_OF_MEMORY;
103  }
104 
105  //Retrieve vendorID, product ID and chip revision
108  chipRevision = dm9000ReadReg(DM9000_REG_CHIPR);
109 
110  //Check vendor ID and product ID
111  if(vendorId != DM9000_VID || productId != DM9000_PID)
112  return ERROR_WRONG_IDENTIFIER;
113  //Check chip revision
114  if(chipRevision != DM9000A_CHIP_REV && chipRevision != DM9000B_CHIP_REV)
115  return ERROR_WRONG_IDENTIFIER;
116 
117  //Power up the internal PHY by clearing PHYPD
119  //Wait for the PHY to be ready
120  sleep(10);
121 
122  //Software reset
124  //Wait for the reset to complete
126 
127  //PHY software reset
129  //Wait for the PHY reset to complete
131 
132  //Debug message
133  TRACE_INFO(" VID = 0x%04" PRIX16 "\r\n", vendorId);
134  TRACE_INFO(" PID = 0x%04" PRIX16 "\r\n", productId);
135  TRACE_INFO(" CHIPR = 0x%02" PRIX8 "\r\n", chipRevision);
136  TRACE_INFO(" PHYIDR1 = 0x%04" PRIX16 "\r\n", dm9000ReadPhyReg(DM9000_PHY_REG_PHYIDR1));
137  TRACE_INFO(" PHYIDR2 = 0x%04" PRIX16 "\r\n", dm9000ReadPhyReg(DM9000_PHY_REG_PHYIDR2));
138 
139  //Enable loopback mode?
140 #if (DM9000_LOOPBACK_MODE == ENABLED)
143 #endif
144 
145  //Set host MAC address
146  for(i = 0; i < 6; i++)
147  dm9000WriteReg(DM9000_REG_PAR0 + i, interface->macAddr.b[i]);
148 
149  //Initialize hash table
150  for(i = 0; i < 8; i++)
151  dm9000WriteReg(DM9000_REG_MAR0 + i, 0x00);
152 
153  //Always accept broadcast packets
155 
156  //Enable the Pointer Auto Return function
158  //Clear NSR status bits
160  //Clear interrupt flags
162  //Enable interrupts
164  //Enable the receiver by setting RXEN
166 
167  //Accept any packets from the upper layer
168  osSetEvent(&interface->nicTxEvent);
169 
170  //Force the TCP/IP stack to poll the link state at startup
171  interface->nicEvent = TRUE;
172  //Notify the TCP/IP stack of the event
174 
175  //Successful initialization
176  return NO_ERROR;
177 }
178 
179 
180 /**
181  * @brief DM9000 timer handler
182  * @param[in] interface Underlying network interface
183  **/
184 
185 void dm9000Tick(NetInterface *interface)
186 {
187 }
188 
189 
190 /**
191  * @brief Enable interrupts
192  * @param[in] interface Underlying network interface
193  **/
194 
196 {
197  //Enable interrupts
198  interface->extIntDriver->enableIrq();
199 }
200 
201 
202 /**
203  * @brief Disable interrupts
204  * @param[in] interface Underlying network interface
205  **/
206 
208 {
209  //Disable interrupts
210  interface->extIntDriver->disableIrq();
211 }
212 
213 
214 /**
215  * @brief DM9000 interrupt service routine
216  * @param[in] interface Underlying network interface
217  * @return TRUE if a higher priority task must be woken. Else FALSE is returned
218  **/
219 
221 {
222  bool_t flag;
223  uint8_t status;
224  uint8_t mask;
225  Dm9000Context *context;
226 
227  //This flag will be set if a higher priority task must be woken
228  flag = FALSE;
229 
230  //Point to the driver context
231  context = (Dm9000Context *) interface->nicContext;
232 
233  //Read interrupt status register
234  status = dm9000ReadReg(DM9000_REG_ISR);
235 
236  //Link status change?
237  if(status & ISR_LNKCHG)
238  {
239  //Read interrupt mask register
241  //Disable LNKCHGI interrupt
243 
244  //Set event flag
245  interface->nicEvent = TRUE;
246  //Notify the TCP/IP stack of the event
247  flag |= osSetEventFromIsr(&netEvent);
248  }
249 
250  //Packet transmission complete?
251  if(status & ISR_PT)
252  {
253  //Check TX complete status bits
255  {
256  //The transmission of the current packet is complete
257  if(context->queuedPackets > 0)
258  context->queuedPackets--;
259 
260  //Notify the TCP/IP stack that the transmitter is ready to send
261  flag |= osSetEventFromIsr(&interface->nicTxEvent);
262  }
263 
264  //Clear interrupt flag
266  }
267 
268  //Packet received?
269  if(status & ISR_PR)
270  {
271  //Read interrupt mask register
273  //Disable PRI interrupt
275 
276  //Set event flag
277  interface->nicEvent = TRUE;
278  //Notify the TCP/IP stack of the event
279  flag |= osSetEventFromIsr(&netEvent);
280  }
281 
282  //A higher priority task must be woken?
283  return flag;
284 }
285 
286 
287 /**
288  * @brief DM9000 event handler
289  * @param[in] interface Underlying network interface
290  **/
291 
293 {
294  error_t error;
295  uint8_t status;
296 
297  //Read interrupt status register
298  status = dm9000ReadReg(DM9000_REG_ISR);
299 
300  //Check whether the link status has changed?
301  if(status & ISR_LNKCHG)
302  {
303  //Clear interrupt flag
305  //Read network status register
306  status = dm9000ReadReg(DM9000_REG_NSR);
307 
308  //Check link state
309  if(status & NSR_LINKST)
310  {
311  //Get current speed
312  if(status & NSR_SPEED)
313  interface->linkSpeed = NIC_LINK_SPEED_10MBPS;
314  else
315  interface->linkSpeed = NIC_LINK_SPEED_100MBPS;
316 
317  //Read network control register
318  status = dm9000ReadReg(DM9000_REG_NCR);
319 
320  //Determine the new duplex mode
321  if(status & NCR_FDX)
322  interface->duplexMode = NIC_FULL_DUPLEX_MODE;
323  else
324  interface->duplexMode = NIC_HALF_DUPLEX_MODE;
325 
326  //Link is up
327  interface->linkState = TRUE;
328  }
329  else
330  {
331  //Link is down
332  interface->linkState = FALSE;
333  }
334 
335  //Process link state change event
336  nicNotifyLinkChange(interface);
337  }
338 
339  //Check whether a packet has been received?
340  if(status & ISR_PR)
341  {
342  //Clear interrupt flag
344 
345  //Process all pending packets
346  do
347  {
348  //Read incoming packet
349  error = dm9000ReceivePacket(interface);
350 
351  //No more data in the receive buffer?
352  } while(error != ERROR_BUFFER_EMPTY);
353  }
354 
355  //Re-enable LNKCHGI and PRI interrupts
357 }
358 
359 
360 /**
361  * @brief Send a packet to DM9000
362  * @param[in] interface Underlying network interface
363  * @param[in] buffer Multi-part buffer containing the data to send
364  * @param[in] offset Offset to the first data byte
365  * @return Error code
366  **/
367 
369  const NetBuffer *buffer, size_t offset)
370 {
371  size_t i;
372  size_t length;
373  uint16_t *p;
374  Dm9000Context *context;
375 
376  //Point to the driver context
377  context = (Dm9000Context *) interface->nicContext;
378 
379  //Retrieve the length of the packet
380  length = netBufferGetLength(buffer) - offset;
381 
382  //Check the frame length
384  {
385  //The transmitter can accept another packet
386  osSetEvent(&interface->nicTxEvent);
387  //Report an error
388  return ERROR_INVALID_LENGTH;
389  }
390 
391  //Copy user data
392  netBufferRead(context->txBuffer, buffer, offset, length);
393 
394  //A dummy write is required before accessing FIFO
396  //Select MWCMD register
398 
399  //Point to the beginning of the buffer
400  p = (uint16_t *) context->txBuffer;
401 
402  //Write data to the FIFO using 16-bit mode
403  for(i = length; i > 1; i -= 2)
404  DM9000_DATA_REG = *(p++);
405 
406  //Odd number of bytes?
407  if(i > 0)
408  DM9000_DATA_REG = *((uint8_t *) p);
409 
410  //Write the number of bytes to send
413 
414  //Clear interrupt flag
416  //Start data transfer
418 
419  //The packet was successfully written to FIFO
420  context->queuedPackets++;
421 
422  //Successful processing
423  return NO_ERROR;
424 }
425 
426 
427 /**
428  * @brief Receive a packet
429  * @param[in] interface Underlying network interface
430  * @return Error code
431  **/
432 
434 {
435  error_t error;
436  size_t i;
437  size_t n;
438  size_t length;
439  volatile uint8_t status;
440  volatile uint16_t data;
441  Dm9000Context *context;
442 
443  //Point to the driver context
444  context = (Dm9000Context *) interface->nicContext;
445 
446  //A dummy read is required before accessing the 4-byte header
448 
449  //Select MRCMDX1 register
451  //Read the first byte of the header
452  status = LSB(DM9000_DATA_REG);
453 
454  //The first byte indicates if a packet has been received
455  if(status == 0x01)
456  {
457  //Select MRCMD register
459  //The second byte is the RX status byte
460  status = MSB(DM9000_DATA_REG);
461 
462  //Retrieve packet length
464  //Limit the number of data to read
466 
467  //Point to the beginning of the buffer
468  i = 0;
469 
470  //Make sure no error occurred
471  if(!(status & (RSR_LCS | RSR_RWTO | RSR_PLE | RSR_AE | RSR_CE | RSR_FOE)))
472  {
473  //Read data from FIFO using 16-bit mode
474  while((i + 1) < n)
475  {
477  context->rxBuffer[i++] = LSB(data);
478  context->rxBuffer[i++] = MSB(data);
479  }
480 
481  //Odd number of bytes to read?
482  if((i + 1) == n)
483  {
485  context->rxBuffer[i] = LSB(data);
486  i += 2;
487  }
488 
489  //Valid packet received
490  error = NO_ERROR;
491  }
492  else
493  {
494  //The received packet contains an error
495  error = ERROR_INVALID_PACKET;
496  }
497 
498  //Flush remaining bytes
499  while(i < length)
500  {
502  i += 2;
503  }
504  }
505  else
506  {
507  //No more data in the receive buffer
508  error = ERROR_BUFFER_EMPTY;
509  }
510 
511  //Check whether a valid packet has been received
512  if(!error)
513  {
514  //Pass the packet to the upper layer
515  nicProcessPacket(interface, context->rxBuffer, n);
516  }
517 
518  //Return status code
519  return error;
520 }
521 
522 
523 /**
524  * @brief Configure MAC address filtering
525  * @param[in] interface Underlying network interface
526  * @return Error code
527  **/
528 
530 {
531  uint_t i;
532  uint_t k;
533  uint32_t crc;
534  uint8_t hashTable[8];
535  MacFilterEntry *entry;
536 
537  //Debug message
538  TRACE_DEBUG("Updating DM9000 hash table...\r\n");
539 
540  //Clear hash table
541  memset(hashTable, 0, sizeof(hashTable));
542  //Always accept broadcast packets regardless of the MAC filter table
543  hashTable[7] = 0x80;
544 
545  //The MAC address filter contains the list of MAC addresses to accept
546  //when receiving an Ethernet frame
547  for(i = 0; i < MAC_ADDR_FILTER_SIZE; i++)
548  {
549  //Point to the current entry
550  entry = &interface->macAddrFilter[i];
551 
552  //Valid entry?
553  if(entry->refCount > 0)
554  {
555  //Compute CRC over the current MAC address
556  crc = dm9000CalcCrc(&entry->addr, sizeof(MacAddr));
557  //Calculate the corresponding index in the table
558  k = crc & 0x3F;
559  //Update hash table contents
560  hashTable[k / 8] |= (1 << (k % 8));
561  }
562  }
563 
564  //Write the hash table to the DM9000 controller
565  for(i = 0; i < 8; i++)
566  dm9000WriteReg(DM9000_REG_MAR0 + i, hashTable[i]);
567 
568  //Debug message
569  TRACE_DEBUG(" MAR = %02" PRIX8 " %02" PRIX8 " %02" PRIX8 " %02" PRIX8 " "
570  "%02" PRIX8 " %02" PRIX8 " %02" PRIX8 " %02" PRIX8 "\r\n",
575 
576  //Successful processing
577  return NO_ERROR;
578 }
579 
580 
581 /**
582  * @brief Write DM9000 register
583  * @param[in] address Register address
584  * @param[in] data Register value
585  **/
586 
587 void dm9000WriteReg(uint8_t address, uint8_t data)
588 {
589  //Write register address to INDEX register
591  //Write register value to DATA register
593 }
594 
595 
596 /**
597  * @brief Read DM9000 register
598  * @param[in] address Register address
599  * @return Register value
600  **/
601 
602 uint8_t dm9000ReadReg(uint8_t address)
603 {
604  //Write register address to INDEX register
606  //Read register value from DATA register
607  return DM9000_DATA_REG;
608 }
609 
610 
611 /**
612  * @brief Write DM9000 PHY register
613  * @param[in] address PHY register address
614  * @param[in] data Register value
615  **/
616 
617 void dm9000WritePhyReg(uint8_t address, uint16_t data)
618 {
619  //Write PHY register address
621  //Write register value
624 
625  //Start the write operation
627  //PHY access is still in progress?
629 
630  //Wait 5us minimum
631  usleep(5);
632  //Clear command register
634 }
635 
636 
637 /**
638  * @brief Read DM9000 PHY register
639  * @param[in] address PHY register address
640  * @return Register value
641  **/
642 
643 uint16_t dm9000ReadPhyReg(uint8_t address)
644 {
645  //Write PHY register address
647 
648  //Start the read operation
650  //PHY access is still in progress?
652 
653  //Clear command register
655  //Wait 5us minimum
656  usleep(5);
657 
658  //Return register value
660 }
661 
662 
663 /**
664  * @brief CRC calculation
665  * @param[in] data Pointer to the data over which to calculate the CRC
666  * @param[in] length Number of bytes to process
667  * @return Resulting CRC value
668  **/
669 
670 uint32_t dm9000CalcCrc(const void *data, size_t length)
671 {
672  uint_t i;
673  uint_t j;
674 
675  //Point to the data over which to calculate the CRC
676  const uint8_t *p = (uint8_t *) data;
677  //CRC preset value
678  uint32_t crc = 0xFFFFFFFF;
679 
680  //Loop through data
681  for(i = 0; i < length; i++)
682  {
683  //Update CRC value
684  crc ^= p[i];
685  //The message is processed bit by bit
686  for(j = 0; j < 8; j++)
687  {
688  if(crc & 0x00000001)
689  crc = (crc >> 1) ^ 0xEDB88320;
690  else
691  crc = crc >> 1;
692  }
693  }
694 
695  //Return CRC value
696  return crc;
697 }
void dm9000EventHandler(NetInterface *interface)
DM9000 event handler.
#define DM9000_REG_TXPLH
void dm9000Tick(NetInterface *interface)
DM9000 timer handler.
MacAddr addr
MAC address.
Definition: ethernet.h:210
#define ETH_MAX_FRAME_SIZE
Definition: ethernet.h:80
#define DM9000_REG_VIDH
#define DM9000_REG_EPDRH
Definition: dm9000_driver.h:81
void nicNotifyLinkChange(NetInterface *interface)
Process link state change event.
Definition: nic.c:298
#define TCR_TXREQ
#define NSR_TX2END
const NicDriver dm9000Driver
DM9000 driver.
Definition: dm9000_driver.c:43
#define MSB(x)
Definition: os_port.h:56
TCP/IP stack core.
#define DM9000_REG_MWCMD
Debugging facilities.
uint8_t p
Definition: ndp.h:295
size_t netBufferGetLength(const NetBuffer *buffer)
Get the actual length of a multi-part buffer.
Definition: net_mem.c:295
error_t dm9000Init(NetInterface *interface)
DM9000 controller initialization.
Definition: dm9000_driver.c:70
#define DM9000_REG_CHIPR
#define DM9000_REG_PIDH
#define NCR_FDX
void dm9000WritePhyReg(uint8_t address, uint16_t data)
Write DM9000 PHY register.
uint16_t dm9000ReadPhyReg(uint8_t address)
Read DM9000 PHY register.
void dm9000WriteReg(uint8_t address, uint8_t data)
Write DM9000 register.
void * memPoolAlloc(size_t size)
Allocate a memory block.
Definition: net_mem.c:98
#define IMR_PAR
#define DM9000_REG_IMR
#define DM9000_REG_MAR0
Definition: dm9000_driver.h:89
#define sleep(delay)
Definition: os_port.h:126
#define DM9000_REG_TCR
Definition: dm9000_driver.h:69
#define DM9000_REG_MAR4
Definition: dm9000_driver.h:93
#define DM9000_INDEX_REG
Definition: dm9000_driver.h:44
uint_t queuedPackets
Number of packets in transmission buffer.
#define LSB(x)
Definition: os_port.h:52
#define RSR_RWTO
DM9000 driver context.
#define DM9000_REG_EPDRL
Definition: dm9000_driver.h:80
#define BMCR_LOOPBACK
#define DM9000_PID
Definition: dm9000_driver.h:62
#define DM9000_REG_MAR7
Definition: dm9000_driver.h:96
#define DM9000_REG_PIDL
#define TRUE
Definition: os_port.h:48
#define BMCR_SPEED_SEL
#define MAC_ADDR_FILTER_SIZE
Definition: ethernet.h:65
#define RSR_PLE
#define DM9000_REG_PAR0
Definition: dm9000_driver.h:83
#define ISR_PR
#define NSR_SPEED
#define IMR_PRI
#define DM9000_LBK_PHY
Ethernet.
uint8_t mask
Definition: web_socket.h:315
#define RSR_CE
#define EPCR_ERRE
uint8_t dm9000ReadReg(uint8_t address)
Read DM9000 register.
#define DM9000_REG_MWCMDX
void memPoolFree(void *p)
Release a memory block.
Definition: net_mem.c:164
#define DM9000_REG_MAR3
Definition: dm9000_driver.h:92
#define DM9000_REG_MAR6
Definition: dm9000_driver.h:95
#define RSR_FOE
uint32_t dm9000CalcCrc(const void *data, size_t length)
CRC calculation.
size_t netBufferRead(void *dest, const NetBuffer *src, size_t srcOffset, size_t length)
Read data from a multi-part buffer.
Definition: net_mem.c:670
#define DM9000_REG_MAR1
Definition: dm9000_driver.h:90
#define RSR_AE
#define usleep(delay)
Definition: os_port.h:122
NIC driver.
Definition: nic.h:161
error_t dm9000ReceivePacket(NetInterface *interface)
Receive a packet.
#define DM9000_PHY_REG_PHYIDR1
Structure describing a buffer that spans multiple chunks.
Definition: net_mem.h:86
#define MIN(a, b)
Definition: os_port.h:60
#define DM9000_DATA_REG
Definition: dm9000_driver.h:49
bool_t osSetEventFromIsr(OsEvent *event)
Set an event object to the signaled state from an interrupt service routine.
void dm9000DisableIrq(NetInterface *interface)
Disable interrupts.
#define DM9000_VID
Definition: dm9000_driver.h:61
bool_t dm9000IrqHandler(NetInterface *interface)
DM9000 interrupt service routine.
#define NSR_TX1END
#define TRACE_INFO(...)
Definition: debug.h:86
#define RCR_DIS_CRC
#define ETH_MTU
Definition: ethernet.h:82
#define DM9000_PHY_REG_PHYIDR2
Ethernet interface.
Definition: nic.h:69
Success.
Definition: error.h:42
#define DM9000_REG_MAR5
Definition: dm9000_driver.h:94
Ipv6Addr address
OsEvent netEvent
Definition: net.c:72
#define IMR_PTI
#define ISR_ROS
void nicProcessPacket(NetInterface *interface, void *packet, size_t length)
Handle a packet received by the network controller.
Definition: nic.c:239
#define RCR_RXEN
uint_t refCount
Reference count for the current entry.
Definition: ethernet.h:211
void osSetEvent(OsEvent *event)
Set the specified event object to the signaled state.
error_t
Error codes.
Definition: error.h:40
#define RSR_LCS
#define DM9000_REG_VIDL
#define DM9000_PHY_REG_BMCR
#define NCR_RST
unsigned int uint_t
Definition: compiler_port.h:43
#define DM9000_REG_ISR
__start_packed struct @112 MacAddr
MAC address.
uint8_t data[]
Definition: dtls_misc.h:167
#define DM9000_REG_EPAR
Definition: dm9000_driver.h:79
#define DM9000_REG_GPR
Definition: dm9000_driver.h:98
#define NetInterface
Definition: net.h:34
void dm9000EnableIrq(NetInterface *interface)
Enable interrupts.
#define ISR_PT
#define BMCR_AN_EN
#define ISR_LNKCHG
#define DM9000_REG_NCR
Definition: dm9000_driver.h:67
uint8_t * txBuffer
Transmit buffer.
#define DM9000_REG_MRCMD
#define DM9000_REG_MRCMDX1
#define EPCR_ERPRW
#define DM9000_REG_NSR
Definition: dm9000_driver.h:68
#define NSR_WAKEST
#define EPCR_ERPRR
#define RCR_DIS_LONG
#define ISR_ROO
#define DM9000_REG_MRCMDX
#define BMCR_DUPLEX_MODE
#define DM9000B_CHIP_REV
Definition: dm9000_driver.h:64
#define DM9000A_CHIP_REV
Definition: dm9000_driver.h:63
error_t dm9000UpdateMacAddrFilter(NetInterface *interface)
Configure MAC address filtering.
#define IMR_LNKCHGI
#define NSR_LINKST
#define DM9000_REG_RCR
Definition: dm9000_driver.h:72
uint8_t length
Definition: dtls_misc.h:140
uint8_t n
#define FALSE
Definition: os_port.h:44
#define ISR_UDRUN
DM9000A/B Ethernet controller.
int bool_t
Definition: compiler_port.h:47
#define BMCR_RST
uint8_t * rxBuffer
Receive buffer.
error_t dm9000SendPacket(NetInterface *interface, const NetBuffer *buffer, size_t offset)
Send a packet to DM9000.
#define DM9000_REG_TXPLL
MAC filter table entry.
Definition: ethernet.h:208
#define DM9000_REG_EPCR
Definition: dm9000_driver.h:78
#define TRACE_DEBUG(...)
Definition: debug.h:98
#define EPCR_EPOS
#define DM9000_REG_MAR2
Definition: dm9000_driver.h:91