cs8900a.c 18 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681
  1. /*
  2. * Copyright (C) 2003-2005 by egnite Software GmbH. All rights reserved.
  3. *
  4. * Redistribution and use in source and binary forms, with or without
  5. * modification, are permitted provided that the following conditions
  6. * are met:
  7. *
  8. * 1. Redistributions of source code must retain the above copyright
  9. * notice, this list of conditions and the following disclaimer.
  10. * 2. Redistributions in binary form must reproduce the above copyright
  11. * notice, this list of conditions and the following disclaimer in the
  12. * documentation and/or other materials provided with the distribution.
  13. * 3. Neither the name of the copyright holders nor the names of
  14. * contributors may be used to endorse or promote products derived
  15. * from this software without specific prior written permission.
  16. *
  17. * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
  18. * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
  19. * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
  20. * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
  21. * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
  22. * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
  23. * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
  24. * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
  25. * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
  26. * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
  27. * THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  28. * SUCH DAMAGE.
  29. *
  30. * For additional information see http://www.ethernut.de/
  31. *
  32. */
  33. /*
  34. * $Log$
  35. * Revision 1.5 2008/08/28 11:12:15 haraldkipp
  36. * Added interface flags, which will be required to implement Ethernet ioctl
  37. * functions.
  38. *
  39. * Revision 1.4 2008/08/11 06:59:07 haraldkipp
  40. * BSD types replaced by stdint types (feature request #1282721).
  41. *
  42. * Revision 1.3 2007/05/02 11:22:51 haraldkipp
  43. * Added multicast table entry.
  44. *
  45. * Revision 1.2 2006/05/25 09:09:57 haraldkipp
  46. * API documentation updated and corrected.
  47. *
  48. * Revision 1.1 2006/02/23 15:33:59 haraldkipp
  49. * Support for Philips LPC2xxx Family and LPC-E2294 Board from Olimex added.
  50. * Many thanks to Michael Fischer for this port.
  51. *
  52. * Revision 1.2 2005/08/02 17:46:45 haraldkipp
  53. * Major API documentation update.
  54. *
  55. * Revision 1.1 2005/07/26 18:02:40 haraldkipp
  56. * Moved from dev.
  57. *
  58. * Revision 1.13 2005/04/30 16:42:41 chaac
  59. * Fixed bug in handling of NUTDEBUG. Added include for cfg/os.h. If NUTDEBUG
  60. * is defined in NutConf, it will make effect where it is used.
  61. *
  62. * Revision 1.12 2005/02/02 19:55:34 haraldkipp
  63. * If no Ethernet link was available on the LAN91C111, each outgoing packet
  64. * took 15 seconds and, even worse, the ouput routine doesn't return an error.
  65. * Now the first attempt to send a packet without Ethernet link will wait for
  66. * 5 seconds and subsequent attempts take 0.5 seconds only, always returning
  67. * an error.
  68. *
  69. * Revision 1.11 2005/01/24 21:11:49 freckle
  70. * renamed NutEventPostFromIRQ into NutEventPostFromIrq
  71. *
  72. * Revision 1.10 2005/01/22 19:24:11 haraldkipp
  73. * Changed AVR port configuration names from PORTx to AVRPORTx.
  74. *
  75. * Revision 1.9 2005/01/21 16:49:45 freckle
  76. * Seperated calls to NutEventPostAsync between Threads and IRQs
  77. *
  78. * Revision 1.8 2004/09/22 08:14:48 haraldkipp
  79. * Made configurable
  80. *
  81. * Revision 1.7 2004/03/08 11:14:17 haraldkipp
  82. * Added quick hack for fixed mode.
  83. *
  84. * Revision 1.6 2004/02/25 16:22:33 haraldkipp
  85. * Do not initialize MAC with all zeros
  86. *
  87. * Revision 1.5 2004/01/14 19:31:43 drsung
  88. * Speed improvement to NicWrite applied. Thanks to Kolja Waschk
  89. *
  90. * Revision 1.4 2003/11/06 09:26:50 haraldkipp
  91. * Removed silly line with hardcoded MAC, left over from testing
  92. *
  93. * Revision 1.3 2003/11/04 17:54:47 haraldkipp
  94. * PHY configuration timing changed again for reliable linking
  95. *
  96. * Revision 1.2 2003/11/03 17:12:53 haraldkipp
  97. * Allow linking with RTL8019 driver.
  98. * Links more reliable to 10 MBit networks now.
  99. * Reset MMU on allocation failures.
  100. * Some optimizations.
  101. *
  102. * Revision 1.1 2003/10/13 10:13:49 haraldkipp
  103. * First release
  104. *
  105. */
  106. #include <cfg/os.h>
  107. #include <cfg/arch/avr.h>
  108. #include <string.h>
  109. #include <sys/atom.h>
  110. #include <sys/heap.h>
  111. #include <sys/thread.h>
  112. #include <sys/event.h>
  113. #include <sys/timer.h>
  114. #include <sys/confnet.h>
  115. #include <netinet/if_ether.h>
  116. #include <net/ether.h>
  117. #include <net/if_var.h>
  118. #include <dev/irqreg.h>
  119. #include <dev/cs8900a.h>
  120. #ifdef NUTDEBUG
  121. #include <stdio.h>
  122. #endif
  123. /*
  124. * This file is for the Olimex LPC-E2294 board @@MF
  125. */
  126. #include <arch/arm/lpc2xxx.h>
  127. #include <__armlib.h>
  128. #define cli() __ARMLIB_disableIRQ()
  129. #define sei() __ARMLIB_enableIRQ()
  130. /*=========================================================================*/
  131. /* DEFINE: All Structures and Common Constants */
  132. /*=========================================================================*/
  133. /*
  134. * Cirrus Logic CS8900a I/O Registers
  135. */
  136. #define CS_DATA_P0 (cs_base + 0x0000UL)
  137. #define CS_DATA_P1 (cs_base + 0x0002UL)
  138. #define CS_TX_CMD_I (cs_base + 0x0004UL)
  139. #define CS_TX_LEN_I (cs_base + 0x0006UL)
  140. #define CS_INT_STAT (cs_base + 0x0008UL)
  141. #define CS_PP_PTR (cs_base + 0x000AUL)
  142. #define CS_PP_DATA0 (cs_base + 0x000CUL)
  143. #define CS_PP_DATA1 (cs_base + 0x000EUL)
  144. // Cirrus Logic CS8900a Packet Page registers
  145. #define CS_PROD_ID 0x0000
  146. #define CS_IO_BASE 0x0020
  147. #define CS_INT_NUM 0x0022
  148. #define CS_DMA_CHAN 0x0024
  149. #define CS_DMA_SOF 0x0026
  150. #define CS_DMA_FCNT 0x0028
  151. #define CS_DMA_RXCNT 0x002A
  152. #define CS_MEM_BASE 0x002C
  153. #define CS_BOOT_BASE 0x0030
  154. #define CS_BOOT_MASK 0x0034
  155. #define CS_EE_CMD 0x0040
  156. #define CS_EE_DATA 0x0042
  157. #define CS_RX_FRM_CNT 0x0050
  158. #define CS_ISQ 0x0120
  159. #define CS_RX_CFG 0x0102
  160. #define CS_RX_EVENT 0x0124
  161. #define CS_RX_CTL 0x0104
  162. #define CS_TX_CFG 0x0106
  163. #define CS_TX_EVENT 0x0128
  164. #define CS_TX_CMD_P 0x0108
  165. #define CS_BUF_CFG 0x010A
  166. #define CS_BUF_EVENT 0x012C
  167. #define CS_RX_MISS 0x0130
  168. #define CS_TX_COLL 0x0132
  169. #define CS_LINE_CTRL 0x0112
  170. #define CS_LINE_STAT 0x0134
  171. #define CS_SELF_CTRL 0x0114
  172. #define CS_SELF_STAT 0x0136
  173. #define CS_BUS_CTRL 0x0116
  174. #define CS_BUS_STAT 0x0138
  175. #define CS_TEST_CTRL 0x0118
  176. #define CS_AUI_TDR 0x013C
  177. #define CS_PP_TX_CMD 0x0144
  178. #define CS_PP_TX_LEN 0x0146
  179. #define CS_IEEE_ADDR 0x0158
  180. /*!
  181. * \addtogroup xgNicCs8900
  182. */
  183. /*@{*/
  184. /*!
  185. * \struct _NICINFO
  186. * \brief Network interface controller information structure.
  187. */
  188. struct _NICINFO {
  189. uint32_t ni_rx_packets; /*!< Number of packets received. */
  190. uint32_t ni_tx_packets; /*!< Number of packets sent. */
  191. };
  192. /*!
  193. * \brief Network interface controller information type.
  194. */
  195. typedef struct _NICINFO NICINFO;
  196. /*=========================================================================*/
  197. /* DEFINE: Definition of all local Data */
  198. /*=========================================================================*/
  199. // Ethernet flags byte
  200. // Bit 0 = transmit byte flag
  201. static uint8_t cs_flags = 0;
  202. volatile uint32_t cs_base = 0x82000000UL;
  203. /*=========================================================================*/
  204. /* DEFINE: Definition of all local Procedures */
  205. /*=========================================================================*/
  206. void CSWrite16(uint32_t addr, uint16_t data)
  207. {
  208. uint8_t *p;
  209. p = (uint8_t *) addr;
  210. cli();
  211. *p = data;
  212. p++;
  213. *p = data >> 8;
  214. sei();
  215. }
  216. void CSWritePP16(uint16_t addr, uint16_t data)
  217. {
  218. uint8_t *p;
  219. cli();
  220. p = (uint8_t *) CS_PP_PTR;
  221. *p = addr;
  222. p++;
  223. *p = addr >> 8;
  224. CSWrite16(CS_PP_DATA0, data);
  225. return;
  226. }
  227. uint16_t CSRead16(uint32_t addr)
  228. {
  229. uint8_t *p;
  230. uint16_t d;
  231. cli();
  232. p = (uint8_t *) addr;
  233. d = *p;
  234. p++;
  235. d |= (*p << 8);
  236. sei();
  237. return d;
  238. }
  239. uint16_t CSReadPP16(uint16_t addr)
  240. {
  241. uint8_t *p;
  242. cli();
  243. p = (uint8_t *) CS_PP_PTR;
  244. *p = addr;
  245. p++;
  246. *p = addr >> 8;
  247. return CSRead16(CS_PP_DATA0);
  248. }
  249. void CSBeginFrame(void)
  250. {
  251. cs_flags &= ~1;
  252. }
  253. void CSEndFrame(void)
  254. {
  255. uint8_t *p;
  256. cli();
  257. p = (uint8_t *) CS_DATA_P0 + 1;
  258. sei();
  259. // If odd number of bytes in packet pad it out
  260. if (cs_flags & 1)
  261. p = 0;
  262. }
  263. void CSWriteFrameByte(uint8_t data)
  264. {
  265. uint8_t *p;
  266. if (cs_flags & 1)
  267. p = (uint8_t *) CS_DATA_P0 + 1;
  268. else
  269. p = (uint8_t *) CS_DATA_P0;
  270. *p = data;
  271. cs_flags ^= 1;
  272. }
  273. static int CSEthPutPacket(NUTDEVICE * dev, NETBUF * nb)
  274. {
  275. uint16_t i;
  276. uint16_t sz;
  277. uint8_t *p;
  278. NICINFO *ni;
  279. ni = (NICINFO *) dev->dev_dcb;
  280. //
  281. // Calculate the number of bytes to be send. Do not
  282. // send packets larger than 1536 bytes.
  283. //
  284. sz = nb->nb_dl.sz + nb->nb_nw.sz + nb->nb_tp.sz + nb->nb_ap.sz;
  285. if (sz >= 0x600) {
  286. NutNetBufFree(nb);
  287. return -1;
  288. }
  289. #if 0
  290. if (tcp_trace) {
  291. NutPrintFormat_P(dev_debug, PSTR("[ETHTX-%u]\r\n"), sz);
  292. NutPrintFlush(dev_debug);
  293. }
  294. #endif
  295. // Start transmission after entire frame is loaded into CS8900
  296. CSWrite16(CS_TX_CMD_I, 0xC0);
  297. // Set frame size
  298. CSWrite16(CS_TX_LEN_I, sz);
  299. // Wait for buffer space, but only for a while (200ms)
  300. // If the cable is disconnected this will never become true
  301. // If we don't get the go ahead within 200ms return 0 (Sucess)
  302. // And let the upper layers deal with re-transmission
  303. // If we return failure TCP sockets will close straight away which probably
  304. // isn't the correct behaviour
  305. i = 0;
  306. while ((CSReadPP16(CS_BUS_STAT) & 0x0100) == 0) {
  307. i++;
  308. if (i > 20)
  309. return 0;
  310. NutSleep(10);
  311. }
  312. //
  313. // Transfer ethernet physical header.
  314. //
  315. CSBeginFrame();
  316. p = nb->nb_dl.vp;
  317. for (i = 0; i < nb->nb_dl.sz; i++) {
  318. CSWriteFrameByte(*p++);
  319. }
  320. p = nb->nb_nw.vp;
  321. for (i = 0; i < nb->nb_nw.sz; i++) {
  322. CSWriteFrameByte(*p++);
  323. }
  324. p = nb->nb_tp.vp;
  325. for (i = 0; i < nb->nb_tp.sz; i++) {
  326. CSWriteFrameByte(*p++);
  327. }
  328. p = nb->nb_ap.vp;
  329. for (i = 0; i < nb->nb_ap.sz; i++) {
  330. CSWriteFrameByte(*p++);
  331. }
  332. CSEndFrame();
  333. return 0;
  334. }
  335. void CSSoftwareWakeup(void)
  336. {
  337. volatile uint8_t *p;
  338. uint16_t data = CS_SELF_CTRL;
  339. p = (uint8_t *) CS_PP_PTR;
  340. *p = data;
  341. p++;
  342. *p = data >> 8;
  343. NutDelay(10);
  344. }
  345. void CSSoftwareReset(void)
  346. {
  347. volatile uint8_t *p;
  348. uint16_t data;
  349. data = CS_SELF_CTRL;
  350. p = (uint8_t *) CS_PP_PTR;
  351. *p = data;
  352. p++;
  353. *p = data >> 8;
  354. data = 0x0040;
  355. p = (uint8_t *) CS_DATA_P0;
  356. *p = data;
  357. p++;
  358. *p = data >> 8;
  359. }
  360. THREAD(CSNICrx, arg)
  361. {
  362. NUTDEVICE *dev;
  363. IFNET *ifn;
  364. NICINFO *ni;
  365. NETBUF *nb;
  366. uint8_t *p;
  367. uint8_t *q;
  368. uint16_t i, m;
  369. volatile uint16_t l;
  370. dev = arg;
  371. ifn = (IFNET *) dev->dev_icb;
  372. ni = (NICINFO *) dev->dev_dcb;
  373. #if 0
  374. if (tcp_trace) {
  375. NutPrintFormat_P(dev_debug, PSTR("Enter ETHReceive\r\n"));
  376. NutPrintFlush(dev_debug);
  377. }
  378. #endif
  379. l = 0;
  380. NutThreadSetPriority(8);
  381. for (;;) {
  382. while ((CSReadPP16(CS_RX_EVENT) & 0x0100) == 0) {
  383. NutSleep(10);
  384. }
  385. l = *(uint8_t *) (CS_DATA_P0 + 1) << 8 | *(uint8_t *) (CS_DATA_P0);
  386. l = *(uint8_t *) (CS_DATA_P0 + 1) << 8 | *(uint8_t *) (CS_DATA_P0);
  387. //NutPrintFormat_P(dev_debug,PSTR("RxLength = %x \r\n"), l);
  388. //NutPrintFlush(dev_debug);
  389. // Account for odd length packets
  390. if (l & 1)
  391. m = l - 1;
  392. else
  393. m = l;
  394. nb = NutNetBufAlloc(0, NBAF_DATALINK, l);
  395. if (nb) {
  396. q = nb->nb_dl.vp;
  397. for (i = 0; i < m; i += 2) {
  398. p = (uint8_t *) CS_DATA_P0;
  399. *q++ = *p;
  400. p = (uint8_t *) CS_DATA_P0 + 1;
  401. *q++ = *p;
  402. }
  403. // Odd length packets
  404. if (m != l) {
  405. p = (uint8_t *) CS_DATA_P0;
  406. *q++ = *p;
  407. p = (uint8_t *) CS_DATA_P0 + 1;
  408. m = *p;
  409. }
  410. ni->ni_rx_packets++;
  411. (*ifn->if_recv) (dev, nb);
  412. }
  413. }
  414. }
  415. /*=========================================================================*/
  416. /* DEFINE: All code exported */
  417. /*=========================================================================*/
  418. /*!
  419. * \brief Send Ethernet packet.
  420. *
  421. * \param dev Identifies the device to use.
  422. * \param nb Network buffer structure containing the packet to be sent.
  423. * The structure must have been allocated by a previous
  424. * call NutNetBufAlloc().
  425. *
  426. * \return 0 on success, -1 in case of any errors.
  427. */
  428. int cs8900Output(NUTDEVICE * dev, NETBUF * nb)
  429. {
  430. int rc = -1;
  431. NICINFO *ni;
  432. ni = (NICINFO *) dev->dev_dcb;
  433. #if 0
  434. if (tcp_trace) {
  435. NutPrintFormat_P(dev_debug, PSTR("Enter EthOutput\r\n"));
  436. NutPrintFlush(dev_debug);
  437. }
  438. #endif
  439. if ((rc = CSEthPutPacket(dev, nb)) == 0)
  440. ni->ni_tx_packets++;
  441. return rc;
  442. }
  443. /*!
  444. * \brief Initialize Ethernet hardware.
  445. *
  446. * Resets the CS8900 Ethernet controller, initializes all required
  447. * hardware registers and starts a background thread for incoming
  448. * Ethernet traffic.
  449. *
  450. * Applications should do not directly call this function. It is
  451. * automatically executed during during device registration by
  452. * NutRegisterDevice().
  453. *
  454. * If the network configuration hasn't been set by the application
  455. * before registering the specified device, this function will
  456. * call NutNetLoadConfig() to get the MAC address.
  457. *
  458. * \param dev Identifies the device to initialize.
  459. */
  460. int cs8900Init(NUTDEVICE * dev)
  461. {
  462. uint16_t i;
  463. uint16_t j;
  464. IFNET *ifn;
  465. NICINFO *ni;
  466. #if 0
  467. if (tcp_trace) {
  468. NutPrintFormat_P(dev_debug, PSTR("Enter NicInit \r\n"));
  469. NutPrintFlush(dev_debug);
  470. }
  471. #endif
  472. cs_base = dev->dev_base;
  473. #if defined(OLIMEX_LPCE2294)
  474. if (cs_base == 0)
  475. {
  476. cs_base = 0x82000000UL;
  477. }
  478. #endif
  479. if (confnet.cd_size == 0)
  480. NutNetLoadConfig(dev->dev_name);
  481. ifn = dev->dev_icb;
  482. #if 0 /* @@MF */
  483. memcpy(ifn->if_mac, confnet.cdn_mac, 6);
  484. #else
  485. ifn->if_mac[0] = 0x00;
  486. ifn->if_mac[1] = 0x06;
  487. ifn->if_mac[2] = 0x98;
  488. ifn->if_mac[3] = 0x00;
  489. ifn->if_mac[4] = 0x00;
  490. ifn->if_mac[5] = 0x00;
  491. #endif
  492. memset(dev->dev_dcb, 0, sizeof(NICINFO));
  493. ni = (NICINFO *) dev->dev_dcb;
  494. // Take CS8900 out of reset and wait for internal reset to complete
  495. CSSoftwareWakeup();
  496. CSSoftwareReset();
  497. NutDelay(100);
  498. // Check for presence
  499. if (CSReadPP16(CS_PROD_ID) != 0x630E)
  500. return -1;
  501. //
  502. // Copy our MAC address to the NIC
  503. //
  504. for (i = 0; i < 6; i += 2) {
  505. j = ifn->if_mac[i] << 8;
  506. j |= ifn->if_mac[i + 1];
  507. CSWritePP16(CS_IEEE_ADDR + i, j);
  508. j = CSReadPP16(CS_IEEE_ADDR + i);
  509. #if 0
  510. if (tcp_trace) {
  511. NutPrintFormat_P(dev_debug, PSTR("ADDR = %x\r\n"), j);
  512. NutPrintFlush(dev_debug);
  513. }
  514. #endif
  515. }
  516. //
  517. // Enable the Transmitter and Receiver
  518. //
  519. CSWritePP16(CS_LINE_CTRL, 0x00C0);
  520. //i = CSReadPP16(CS_LINE_CTRL);
  521. //NutPrintFormat_P(dev_debug,PSTR("CS_LINE_CTRL = %x\r\n"), i);
  522. CSWritePP16(CS_RX_CTL, 0x0F40);
  523. //i = CSReadPP16(CS_RX_CTL);
  524. //NutPrintFormat_P(dev_debug,PSTR("CS_RX_CTL = %x\r\n"), i);
  525. //
  526. // Start receiver thread
  527. //
  528. NutThreadCreate("csnicrx", CSNICrx, dev, 768);
  529. return 0;
  530. }
  531. static NICINFO dcb_eth0;
  532. /*!
  533. * \brief Network interface information structure.
  534. *
  535. * Used to call.
  536. */
  537. static IFNET ifn_eth0 = {
  538. IFT_ETHER, /*!< \brief Interface type. */
  539. 0, /*!< \brief Interface flags, if_flags. */
  540. {0, 0, 0, 0, 0, 0}, /*!< \brief Hardware net address. */
  541. 0, /*!< \brief IP address. */
  542. 0, /*!< \brief Remote IP address for point to point. */
  543. 0, /*!< \brief IP network mask. */
  544. ETHERMTU, /*!< \brief Maximum size of a transmission unit. */
  545. 0, /*!< \brief Packet identifier. */
  546. 0, /*!< \brief Linked list of arp entries. */
  547. 0, /*!< \brief Linked list of multicast address entries, if_mcast. */
  548. NutEtherInput, /*!< \brief Routine to pass received data to, if_recv(). */
  549. cs8900Output, /*!< \brief Driver output routine, if_send(). */
  550. NutEtherOutput, /*!< \brief Media output routine, if_output(). */
  551. NULL /*!< \brief Interface specific control function, if_ioctl(). */
  552. #ifdef NUT_PERFMON
  553. , 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
  554. #endif
  555. };
  556. /*!
  557. * \brief Device information structure.
  558. *
  559. * A pointer to this structure must be passed to NutRegisterDevice()
  560. * to bind this Ethernet device driver to the Nut/OS kernel.
  561. * An application may then call NutNetIfConfig() with the name \em eth0
  562. * of this driver to initialize the network interface.
  563. *
  564. */
  565. NUTDEVICE devCS8900A = {
  566. 0, /* Pointer to next device. */
  567. {'e', 't', 'h', '0', 0, 0, 0, 0, 0}, /* Unique device name. */
  568. IFTYP_NET, /* Type of device. */
  569. 0, /* Base address. */
  570. 0, /* First interrupt number. */
  571. &ifn_eth0, /* Interface control block. */
  572. &dcb_eth0, /* Driver control block. */
  573. cs8900Init, /* Driver initialization routine. */
  574. 0, /* Driver specific control function. */
  575. 0, /* Read from device. */
  576. 0, /* Write to device. */
  577. 0, /* Open a device or file. */
  578. 0, /* Close a device or file. */
  579. 0, /* Request file size. */
  580. 0, /* Select function, optional, not yet implemented */
  581. };
  582. /*@}*/