lanc111.c 41 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405
  1. /*
  2. * Copyright (C) 2003-2006 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. * \file arch/avr/dev/lanc111.c
  35. * \brief AVR network driver for SMSC LAN91C111.
  36. *
  37. * \verbatim
  38. * $Id: lanc111.c 5472 2013-12-06 00:16:28Z olereinhardt $
  39. * \endverbatim
  40. */
  41. #include <cfg/os.h>
  42. #include <cfg/arch/avr.h>
  43. #include <sys/atom.h>
  44. #include <sys/heap.h>
  45. #include <sys/thread.h>
  46. #include <sys/event.h>
  47. #include <sys/timer.h>
  48. #include <sys/confnet.h>
  49. #include <stdlib.h>
  50. #include <string.h>
  51. #include <netinet/if_ether.h>
  52. #include <net/ether.h>
  53. #include <net/if_var.h>
  54. #include <dev/irqreg.h>
  55. #include <dev/lanc111.h>
  56. #include <stdlib.h>
  57. #include <string.h>
  58. #ifdef NUTDEBUG
  59. #include <stdio.h>
  60. #endif
  61. #ifndef NUT_THREAD_LANCRXSTACK
  62. #if defined(__GNUC__)
  63. /* avr-gcc size optimized code used 76 bytes.
  64. Sigh! 144 bytes are reported using avr-gcc 4.3.3 and Nut/OS 4.9.10. */
  65. #define NUT_THREAD_LANCRXSTACK 256
  66. #else
  67. /* icc-avr v7.19 used 200 bytes. */
  68. #define NUT_THREAD_LANCRXSTACK 384
  69. #endif
  70. #endif
  71. /*
  72. * Determine ports, which had not been explicitely configured.
  73. */
  74. #ifndef LANC111_BASE_ADDR
  75. #define LANC111_BASE_ADDR 0xC000
  76. #endif
  77. #ifndef LANC111_SIGNAL_IRQ
  78. #define LANC111_SIGNAL_IRQ INT5
  79. #endif
  80. #ifdef LANC111_RESET_BIT
  81. #if (LANC111_RESET_AVRPORT == AVRPORTB)
  82. #define LANC111_RESET_PORT PORTB
  83. #define LANC111_RESET_DDR DDRB
  84. #elif (LANC111_RESET_AVRPORT == AVRPORTD)
  85. #define LANC111_RESET_PORT PORTD
  86. #define LANC111_RESET_DDR DDRD
  87. #elif (LANC111_RESET_AVRPORT == AVRPORTE)
  88. #define LANC111_RESET_PORT PORTE
  89. #define LANC111_RESET_DDR DDRE
  90. #elif (LANC111_RESET_AVRPORT == AVRPORTF)
  91. #define LANC111_RESET_PORT PORTF
  92. #define LANC111_RESET_DDR DDRF
  93. #endif /* LANC111_RESET_AVRPORT */
  94. #endif /* LANC111_RESET_BIT */
  95. /*
  96. * Determine interrupt settings.
  97. */
  98. #if (LANC111_SIGNAL_IRQ == INT0)
  99. #define LANC111_SIGNAL sig_INTERRUPT0
  100. #define LANC111_SIGNAL_MODE() sbi(EICRA, ISC00); sbi(EICRA, ISC01)
  101. #elif (LANC111_SIGNAL_IRQ == INT1)
  102. #define LANC111_SIGNAL sig_INTERRUPT1
  103. #define LANC111_SIGNAL_MODE() sbi(EICRA, ISC10); sbi(EICRA, ISC11)
  104. #elif (LANC111_SIGNAL_IRQ == INT2)
  105. #define LANC111_SIGNAL sig_INTERRUPT2
  106. #define LANC111_SIGNAL_MODE() sbi(EICRA, ISC20); sbi(EICRA, ISC21)
  107. #elif (LANC111_SIGNAL_IRQ == INT3)
  108. #define LANC111_SIGNAL sig_INTERRUPT3
  109. #define LANC111_SIGNAL_MODE() sbi(EICRA, ISC30); sbi(EICRA, ISC31)
  110. #elif (LANC111_SIGNAL_IRQ == INT4)
  111. #define LANC111_SIGNAL sig_INTERRUPT4
  112. #define LANC111_SIGNAL_MODE() sbi(EICR, ISC40); sbi(EICR, ISC41)
  113. #elif (LANC111_SIGNAL_IRQ == INT6)
  114. #define LANC111_SIGNAL sig_INTERRUPT6
  115. #define LANC111_SIGNAL_MODE() sbi(EICR, ISC60); sbi(EICR, ISC61)
  116. #elif (LANC111_SIGNAL_IRQ == INT7)
  117. #define LANC111_SIGNAL sig_INTERRUPT7
  118. #define LANC111_SIGNAL_MODE() sbi(EICR, ISC70); sbi(EICR, ISC71)
  119. #else
  120. #define LANC111_SIGNAL sig_INTERRUPT5
  121. #define LANC111_SIGNAL_MODE() sbi(EICR, ISC50); sbi(EICR, ISC51)
  122. #endif
  123. /*!
  124. * \addtogroup xgSmscRegs
  125. */
  126. /*@{*/
  127. /*!
  128. * \brief Bank select register.
  129. */
  130. #define NIC_BSR (LANC111_BASE_ADDR + 0x0E)
  131. /*!
  132. * \brief Bank 0 - Transmit control register.
  133. */
  134. #define NIC_TCR (LANC111_BASE_ADDR + 0x00)
  135. #define TCR_SWFDUP 0x8000 /*!< \ref NIC_TCR bit mask, enables full duplex. */
  136. #define TCR_EPH_LOOP 0x2000 /*!< \ref NIC_TCR bit mask, enables internal loopback. */
  137. #define TCR_STP_SQET 0x1000 /*!< \ref NIC_TCR bit mask, enables transmission stop on SQET error. */
  138. #define TCR_FDUPLX 0x0800 /*!< \ref NIC_TCR bit mask, enables receiving own frames. */
  139. #define TCR_MON_CSN 0x0400 /*!< \ref NIC_TCR bit mask, enables carrier monitoring. */
  140. #define TCR_NOCRC 0x0100 /*!< \ref NIC_TCR bit mask, disables CRC transmission. */
  141. #define TCR_PAD_EN 0x0080 /*!< \ref NIC_TCR bit mask, enables automatic padding. */
  142. #define TCR_FORCOL 0x0004 /*!< \ref NIC_TCR bit mask, forces collision. */
  143. #define TCR_LOOP 0x0002 /*!< \ref NIC_TCR bit mask, enables PHY loopback. */
  144. #define TCR_TXENA 0x0001 /*!< \ref NIC_TCR bit mask, enables transmitter. */
  145. /*!
  146. * \brief Bank 0 - EPH status register.
  147. */
  148. #define NIC_EPHSR (LANC111_BASE_ADDR + 0x02)
  149. /*!
  150. * \brief Bank 0 - Receive control register.
  151. */
  152. #define NIC_RCR (LANC111_BASE_ADDR + 0x04)
  153. #define RCR_SOFT_RST 0x8000 /*!< \ref NIC_RCR bit mask, activates software reset. */
  154. #define RCR_FILT_CAR 0x4000 /*!< \ref NIC_RCR bit mask, enables carrier filter. */
  155. #define RCR_ABORT_ENB 0x2000 /*!< \ref NIC_RCR bit mask, enables receive abort on collision. */
  156. #define RCR_STRIP_CRC 0x0200 /*!< \ref NIC_RCR bit mask, strips CRC. */
  157. #define RCR_RXEN 0x0100 /*!< \ref NIC_RCR bit mask, enables receiver. */
  158. #define RCR_ALMUL 0x0004 /*!< \ref NIC_RCR bit mask, multicast frames accepted when set. */
  159. #define RCR_PRMS 0x0002 /*!< \ref NIC_RCR bit mask, enables promiscuous mode. */
  160. #define RCR_RX_ABORT 0x0001 /*!< \ref NIC_RCR bit mask, set when receive was aborted. */
  161. /*!
  162. * \brief Bank 0 - Counter register.
  163. */
  164. #define NIC_ECR (LANC111_BASE_ADDR + 0x06)
  165. /*!
  166. * \brief Bank 0 - Memory information register.
  167. */
  168. #define NIC_MIR (LANC111_BASE_ADDR + 0x08)
  169. /*!
  170. * \brief Bank 0 - Receive / PHY control register.
  171. */
  172. #define NIC_RPCR (LANC111_BASE_ADDR + 0x0A)
  173. #define RPCR_SPEED 0x2000 /*!< \ref NIC_RPCR bit mask, PHY operates at 100 Mbps. */
  174. #define RPCR_DPLX 0x1000 /*!< \ref NIC_RPCR bit mask, PHY operates at full duplex mode. */
  175. #define RPCR_ANEG 0x0800 /*!< \ref NIC_RPCR bit mask, sets PHY in auto-negotiation mode. */
  176. #define RPCR_LEDA_PAT 0x0000 /*!< \ref NIC_RPCR bit mask for LEDA mode. */
  177. #define RPCR_LEDB_PAT 0x0010 /*!< \ref NIC_RPCR bit mask for LEDB mode. */
  178. /*!
  179. * \brief Bank 1 - Configuration register.
  180. */
  181. #define NIC_CR (LANC111_BASE_ADDR + 0x00)
  182. #define CR_EPH_EN 0x8000 /*!< \ref NIC_CR bit mask, . */
  183. /*!
  184. * \brief Bank 1 - Base address register.
  185. */
  186. #define NIC_BAR (LANC111_BASE_ADDR + 0x02)
  187. /*!
  188. * \brief Bank 1 - Individual address register.
  189. */
  190. #define NIC_IAR (LANC111_BASE_ADDR + 0x04)
  191. /*!
  192. * \brief Bank 1 - General purpose register.
  193. */
  194. #define NIC_GPR (LANC111_BASE_ADDR + 0x0A)
  195. /*!
  196. * \brief Bank 1 - Control register.
  197. */
  198. #define NIC_CTR (LANC111_BASE_ADDR + 0x0C)
  199. #define CTR_RCV_BAD 0x4000 /*!< \ref NIC_CTR bit mask. */
  200. #define CTR_AUTO_RELEASE 0x0800 /*!< \ref NIC_CTR bit mask, transmit packets automatically released. */
  201. /*!
  202. * \brief Bank 2 - MMU command register.
  203. */
  204. #define NIC_MMUCR (LANC111_BASE_ADDR + 0x00)
  205. #define MMUCR_BUSY 0x0001
  206. #define MMU_NOP 0
  207. #define MMU_ALO (1<<5)
  208. #define MMU_RST (2<<5)
  209. #define MMU_REM (3<<5)
  210. #define MMU_TOP (4<<5)
  211. #define MMU_PKT (5<<5)
  212. #define MMU_ENQ (6<<5)
  213. #define MMU_RTX (7<<5)
  214. /*!
  215. * \brief Bank 2 - Packet number register.
  216. *
  217. * This byte register specifies the accessible transmit packet number.
  218. */
  219. #define NIC_PNR (LANC111_BASE_ADDR + 0x02)
  220. /*!
  221. * \brief Bank 2 - Allocation result register.
  222. *
  223. * This byte register is updated upon a MMU_ALO command.
  224. */
  225. #define NIC_ARR (LANC111_BASE_ADDR + 0x03)
  226. #define ARR_FAILED 0x80
  227. /*!
  228. * \brief Bank 2 - FIFO ports register.
  229. */
  230. #define NIC_FIFO (LANC111_BASE_ADDR + 0x04)
  231. /*!
  232. * \brief Bank 2 - Pointer register.
  233. */
  234. #define NIC_PTR (LANC111_BASE_ADDR + 0x06)
  235. #define PTR_RCV 0x8000 /*! \ref NIC_PTR bit mask, specifies receive or transmit buffer. */
  236. #define PTR_AUTO_INCR 0x4000 /*! \ref NIC_PTR bit mask, enables automatic pointer increment. */
  237. #define PTR_READ 0x2000 /*! \ref NIC_PTR bit mask, indicates type of access. */
  238. #define PTR_ETEN 0x1000 /*! \ref NIC_PTR bit mask, enables early transmit underrun detection. */
  239. #define PTR_NOT_EMPTY 0x0800 /*! \ref NIC_PTR bit mask, set when write data fifo is not empty. */
  240. /*!
  241. * \brief Bank 2 - Data register.
  242. */
  243. #define NIC_DATA (LANC111_BASE_ADDR + 0x08)
  244. /*!
  245. * \brief Bank 2 - Interrupt status register.
  246. */
  247. #define NIC_IST (LANC111_BASE_ADDR + 0x0C)
  248. /*!
  249. * \brief Bank 2 - Interrupt acknowledge register.
  250. */
  251. #define NIC_ACK (LANC111_BASE_ADDR + 0x0C)
  252. /*!
  253. * \brief Bank 2 - Interrupt mask register.
  254. */
  255. #define NIC_MSK (LANC111_BASE_ADDR + 0x0D)
  256. #define INT_MD 0x80 /*!< \brief PHY state change interrupt bit mask. */
  257. #define INT_ERCV 0x40 /*!< \brief Early receive interrupt bit mask. */
  258. #define INT_EPH 0x20 /*!< \brief Ethernet protocol interrupt bit mask. */
  259. #define INT_RX_OVRN 0x10 /*!< \brief Receive overrun interrupt bit mask. */
  260. #define INT_ALLOC 0x08 /*!< \brief Transmit allocation interrupt bit mask. */
  261. #define INT_TX_EMPTY 0x04 /*!< \brief Transmitter empty interrupt bit mask. */
  262. #define INT_TX 0x02 /*!< \brief Transmit complete interrupt bit mask. */
  263. #define INT_RCV 0x01 /*!< \brief Receive interrupt bit mask. */
  264. /*!
  265. * \brief Bank 3 - Multicast table register.
  266. */
  267. #define NIC_MT (LANC111_BASE_ADDR + 0x00)
  268. /*!
  269. * \brief Bank 3 - Management interface register.
  270. */
  271. #define NIC_MGMT (LANC111_BASE_ADDR + 0x08)
  272. #define MGMT_MDOE 0x08 /*!< \ref NIC_MGMT bit mask, enables MDO pin. */
  273. #define MGMT_MCLK 0x04 /*!< \ref NIC_MGMT bit mask, drives MDCLK pin. */
  274. #define MGMT_MDI 0x02 /*!< \ref NIC_MGMT bit mask, reflects MDI pin status. */
  275. #define MGMT_MDO 0x01 /*!< \ref NIC_MGMT bit mask, drives MDO pin. */
  276. /*!
  277. * \brief Bank 3 - Revision register.
  278. */
  279. #define NIC_REV (LANC111_BASE_ADDR + 0x0A)
  280. /*!
  281. * \brief Bank 3 - Early RCV register.
  282. */
  283. #define NIC_ERCV (LANC111_BASE_ADDR + 0x0C)
  284. /*!
  285. * \brief PHY control register.
  286. */
  287. #define NIC_PHYCR 0
  288. #define PHYCR_RST 0x8000 /*!< \ref NIC_PHYCR bit mask, resets PHY. */
  289. #define PHYCR_LPBK 0x4000 /*!< \ref NIC_PHYCR bit mask, . */
  290. #define PHYCR_SPEED 0x2000 /*!< \ref NIC_PHYCR bit mask, . */
  291. #define PHYCR_ANEG_EN 0x1000 /*!< \ref NIC_PHYCR bit mask, . */
  292. #define PHYCR_PDN 0x0800 /*!< \ref NIC_PHYCR bit mask, . */
  293. #define PHYCR_MII_DIS 0x0400 /*!< \ref NIC_PHYCR bit mask, . */
  294. #define PHYCR_ANEG_RST 0x0200 /*!< \ref NIC_PHYCR bit mask, . */
  295. #define PHYCR_DPLX 0x0100 /*!< \ref NIC_PHYCR bit mask, . */
  296. #define PHYCR_COLST 0x0080 /*!< \ref NIC_PHYCR bit mask, . */
  297. /*!
  298. * \brief PHY status register.
  299. */
  300. #define NIC_PHYSR 1
  301. #define PHYSR_CAP_T4 0x8000 /*!< \ref NIC_PHYSR bit mask, indicates 100BASE-T4 capability. */
  302. #define PHYSR_CAP_TXF 0x4000 /*!< \ref NIC_PHYSR bit mask, indicates 100BASE-TX full duplex capability. */
  303. #define PHYSR_CAP_TXH 0x2000 /*!< \ref NIC_PHYSR bit mask, indicates 100BASE-TX half duplex capability. */
  304. #define PHYSR_CAP_TF 0x1000 /*!< \ref NIC_PHYSR bit mask, indicates 10BASE-T full duplex capability. */
  305. #define PHYSR_CAP_TH 0x0800 /*!< \ref NIC_PHYSR bit mask, indicates 10BASE-T half duplex capability. */
  306. #define PHYSR_CAP_SUPR 0x0040 /*!< \ref NIC_PHYSR bit mask, indicates preamble suppression capability. */
  307. #define PHYSR_ANEG_ACK 0x0020 /*!< \ref NIC_PHYSR bit mask, auto-negotiation completed. */
  308. #define PHYSR_REM_FLT 0x0010 /*!< \ref NIC_PHYSR bit mask, remote fault detected. */
  309. #define PHYSR_CAP_ANEG 0x0008 /*!< \ref NIC_PHYSR bit mask, indicates auto-negotiation capability. */
  310. #define PHYSR_LINK 0x0004 /*!< \ref NIC_PHYSR bit mask, valid link status. */
  311. #define PHYSR_JAB 0x0002 /*!< \ref NIC_PHYSR bit mask, jabber collision detected. */
  312. #define PHYSR_EXREG 0x0001 /*!< \ref NIC_PHYSR bit mask, extended capabilities available. */
  313. /*!
  314. * \brief PHY identifier register 1.
  315. */
  316. #define NIC_PHYID1 2
  317. /*!
  318. * \brief PHY identifier register 1.
  319. */
  320. #define NIC_PHYID2 3
  321. /*!
  322. * \brief PHY auto-negotiation advertisement register.
  323. */
  324. #define NIC_PHYANAD 4
  325. #define PHYANAD_NP 0x8000 /*!< \ref NIC_PHYANAD bit mask, exchanging next page information. */
  326. #define PHYANAD_ACK 0x4000 /*!< \ref NIC_PHYANAD bit mask, acknowledged. */
  327. #define PHYANAD_RF 0x2000 /*!< \ref NIC_PHYANAD bit mask, remote fault. */
  328. #define PHYANAD_T4 0x0200 /*!< \ref NIC_PHYANAD bit mask, indicates 100BASE-T4 capability. */
  329. #define PHYANAD_TX_FDX 0x0100 /*!< \ref NIC_PHYANAD bit mask, indicates 100BASE-TX full duplex capability. */
  330. #define PHYANAD_TX_HDX 0x0080 /*!< \ref NIC_PHYANAD bit mask, indicates 100BASE-TX half duplex capability. */
  331. #define PHYANAD_10FDX 0x0040 /*!< \ref NIC_PHYANAD bit mask, indicates 10BASE-T full duplex capability. */
  332. #define PHYANAD_10_HDX 0x0020 /*!< \ref NIC_PHYANAD bit mask, indicates 10BASE-T half duplex capability. */
  333. #define PHYANAD_CSMA 0x0001 /*!< \ref NIC_PHYANAD bit mask, indicates 802.3 CSMA capability. */
  334. /*!
  335. * \brief PHY auto-negotiation remote end capability register.
  336. */
  337. #define NIC_PHYANRC 5
  338. /*!
  339. * \brief PHY configuration register 1.
  340. */
  341. #define NIC_PHYCFR1 16
  342. /*!
  343. * \brief PHY configuration register 2.
  344. */
  345. #define NIC_PHYCFR2 17
  346. /*!
  347. * \brief PHY status output register.
  348. */
  349. #define NIC_PHYSOR 18
  350. #define PHYSOR_INT 0x8000 /*!< \ref NIC_PHYSOR bit mask, interrupt bits changed. */
  351. #define PHYSOR_LNKFAIL 0x4000 /*!< \ref NIC_PHYSOR bit mask, link failure detected. */
  352. #define PHYSOR_LOSSSYNC 0x2000 /*!< \ref NIC_PHYSOR bit mask, descrambler sync lost detected. */
  353. #define PHYSOR_CWRD 0x1000 /*!< \ref NIC_PHYSOR bit mask, code word error detected. */
  354. #define PHYSOR_SSD 0x0800 /*!< \ref NIC_PHYSOR bit mask, start of stream error detected. */
  355. #define PHYSOR_ESD 0x0400 /*!< \ref NIC_PHYSOR bit mask, end of stream error detected. */
  356. #define PHYSOR_RPOL 0x0200 /*!< \ref NIC_PHYSOR bit mask, reverse polarity detected. */
  357. #define PHYSOR_JAB 0x0100 /*!< \ref NIC_PHYSOR bit mask, jabber detected. */
  358. #define PHYSOR_SPDDET 0x0080 /*!< \ref NIC_PHYSOR bit mask, 100/10 speed detected. */
  359. #define PHYSOR_DPLXDET 0x0040 /*!< \ref NIC_PHYSOR bit mask, duplex detected. */
  360. /*!
  361. * \brief PHY mask register.
  362. */
  363. #define NIC_PHYMSK 19
  364. #define PHYMSK_MINT 0x8000 /*!< \ref NIC_PHYMSK bit mask, enables \ref PHYSOR_INT interrupt. */
  365. #define PHYMSK_MLNKFAIL 0x4000 /*!< \ref NIC_PHYMSK bit mask, enables \ref PHYSOR_LNKFAIL interrupt. */
  366. #define PHYMSK_MLOSSSYN 0x2000 /*!< \ref NIC_PHYMSK bit mask, enables \ref PHYSOR_LOSSSYNC interrupt. */
  367. #define PHYMSK_MCWRD 0x1000 /*!< \ref NIC_PHYMSK bit mask, enables \ref PHYSOR_CWRD interrupt. */
  368. #define PHYMSK_MSSD 0x0800 /*!< \ref NIC_PHYMSK bit mask, enables \ref PHYSOR_SSD interrupt. */
  369. #define PHYMSK_MESD 0x0400 /*!< \ref NIC_PHYMSK bit mask, enables \ref PHYSOR_ESD interrupt. */
  370. #define PHYMSK_MRPOL 0x0200 /*!< \ref NIC_PHYMSK bit mask, enables \ref PHYSOR_RPOL interrupt. */
  371. #define PHYMSK_MJAB 0x0100 /*!< \ref NIC_PHYMSK bit mask, enables \ref PHYSOR_JAB interrupt. */
  372. #define PHYMSK_MSPDDT 0x0080 /*!< \ref NIC_PHYMSK bit mask, enables \ref PHYSOR_SPDDET interrupt. */
  373. #define PHYMSK_MDPLDT 0x0040 /*!< \ref NIC_PHYMSK bit mask, enables \ref PHYSOR_DPLXDET interrupt. */
  374. #define MSBV(bit) (1 << ((bit) - 8))
  375. #define nic_outlb(addr, val) (*(volatile uint8_t *)(addr) = (val))
  376. #define nic_outhb(addr, val) (*(volatile uint8_t *)((addr) + 1) = (val))
  377. #define nic_outwx(addr, val) (*(volatile uint16_t *)(addr) = (val))
  378. #define nic_outw(addr, val) { \
  379. *(volatile uint8_t *)(addr) = (uint8_t)(val); \
  380. *((volatile uint8_t *)(addr) + 1) = (uint8_t)((val) >> 8); \
  381. }
  382. #define nic_inlb(addr) (*(volatile uint8_t *)(addr))
  383. #define nic_inhb(addr) (*(volatile uint8_t *)((addr) + 1))
  384. #define nic_inw(addr) (*(volatile uint16_t *)(addr))
  385. #define nic_bs(bank) nic_outlb(NIC_BSR, bank)
  386. /*!
  387. * \struct _NICINFO lanc111.h dev/lanc111.h
  388. * \brief Network interface controller information structure.
  389. */
  390. struct _NICINFO {
  391. HANDLE volatile ni_rx_rdy; /*!< Receiver event queue. */
  392. uint16_t ni_tx_cnt; /*!< Number of bytes in transmission queue. */
  393. uint32_t ni_rx_packets; /*!< Number of packets received. */
  394. uint32_t ni_tx_packets; /*!< Number of packets sent. */
  395. uint32_t ni_interrupts; /*!< Number of interrupts. */
  396. uint32_t ni_overruns; /*!< Number of packet overruns. */
  397. uint32_t ni_rx_frame_errors; /*!< Number of frame errors. */
  398. uint32_t ni_rx_crc_errors; /*!< Number of CRC errors. */
  399. uint32_t ni_rx_missed_errors; /*!< Number of missed packets. */
  400. uint8_t ni_mar[8]; /*!< Multicast Address Register. */
  401. };
  402. /*!
  403. * \brief Network interface controller information type.
  404. */
  405. typedef struct _NICINFO NICINFO;
  406. /*@}*/
  407. /*!
  408. * \addtogroup xgNicLanc111
  409. */
  410. /*@{*/
  411. static HANDLE mutex;
  412. static HANDLE maq;
  413. /*!
  414. * \brief Select specified PHY register for reading or writing.
  415. *
  416. * \note NIC interrupts must have been disabled before calling this routine.
  417. *
  418. * \param reg PHY register number.
  419. * \param we Indicates type of access, 1 for write and 0 for read.
  420. *
  421. * \return Contents of the PHY interface rgister.
  422. */
  423. static uint8_t NicPhyRegSelect(uint8_t reg, uint8_t we)
  424. {
  425. uint8_t rs;
  426. uint8_t msk;
  427. uint8_t i;
  428. nic_bs(3);
  429. rs = (nic_inlb(NIC_MGMT) & ~(MGMT_MCLK | MGMT_MDO)) | MGMT_MDOE;
  430. /* Send idle pattern. */
  431. for (i = 0; i < 33; i++) {
  432. nic_outlb(NIC_MGMT, rs | MGMT_MDO);
  433. nic_outlb(NIC_MGMT, rs | MGMT_MDO | MGMT_MCLK);
  434. }
  435. /* Send start sequence. */
  436. nic_outlb(NIC_MGMT, rs);
  437. nic_outlb(NIC_MGMT, rs | MGMT_MCLK);
  438. nic_outlb(NIC_MGMT, rs | MGMT_MDO);
  439. nic_outlb(NIC_MGMT, rs | MGMT_MDO | MGMT_MCLK);
  440. /* Write or read mode. */
  441. if (we) {
  442. nic_outlb(NIC_MGMT, rs);
  443. nic_outlb(NIC_MGMT, rs | MGMT_MCLK);
  444. nic_outlb(NIC_MGMT, rs | MGMT_MDO);
  445. nic_outlb(NIC_MGMT, rs | MGMT_MDO | MGMT_MCLK);
  446. } else {
  447. nic_outlb(NIC_MGMT, rs | MGMT_MDO);
  448. nic_outlb(NIC_MGMT, rs | MGMT_MDO | MGMT_MCLK);
  449. nic_outlb(NIC_MGMT, rs);
  450. nic_outlb(NIC_MGMT, rs | MGMT_MCLK);
  451. }
  452. /* Send PHY address. Zero is used for the internal PHY. */
  453. for (i = 0; i < 5; i++) {
  454. nic_outlb(NIC_MGMT, rs);
  455. nic_outlb(NIC_MGMT, rs | MGMT_MCLK);
  456. }
  457. /* Send PHY register number. */
  458. for (msk = 0x10; msk; msk >>= 1) {
  459. if (reg & msk) {
  460. nic_outlb(NIC_MGMT, rs | MGMT_MDO);
  461. nic_outlb(NIC_MGMT, rs | MGMT_MDO | MGMT_MCLK);
  462. } else {
  463. nic_outlb(NIC_MGMT, rs);
  464. nic_outlb(NIC_MGMT, rs | MGMT_MCLK);
  465. }
  466. }
  467. nic_outlb(NIC_MGMT, rs);
  468. return rs;
  469. }
  470. /*!
  471. * \brief Read contents of PHY register.
  472. *
  473. * \note NIC interrupts must have been disabled before calling this routine.
  474. *
  475. * \param reg PHY register number.
  476. *
  477. * \return Contents of the specified register.
  478. */
  479. static uint16_t NicPhyRead(uint8_t reg)
  480. {
  481. uint16_t rc = 0;
  482. uint8_t rs;
  483. uint8_t i;
  484. /* Select register for reading. */
  485. rs = NicPhyRegSelect(reg, 0);
  486. /* Switch data direction. */
  487. rs &= ~MGMT_MDOE;
  488. nic_outlb(NIC_MGMT, rs);
  489. nic_outlb(NIC_MGMT, rs | MGMT_MCLK);
  490. /* Clock data in. */
  491. for (i = 0; i < 16; i++) {
  492. nic_outlb(NIC_MGMT, rs);
  493. nic_outlb(NIC_MGMT, rs | MGMT_MCLK);
  494. rc <<= 1;
  495. rc |= (nic_inlb(NIC_MGMT) & MGMT_MDI) != 0;
  496. }
  497. /* This will set the clock line to low. */
  498. nic_outlb(NIC_MGMT, rs);
  499. return rc;
  500. }
  501. /*!
  502. * \brief Write value to PHY register.
  503. *
  504. * \note NIC interrupts must have been disabled before calling this routine.
  505. *
  506. * \param reg PHY register number.
  507. * \param val Value to write.
  508. */
  509. static void NicPhyWrite(uint8_t reg, uint16_t val)
  510. {
  511. uint16_t msk;
  512. uint8_t rs;
  513. /* Select register for writing. */
  514. rs = NicPhyRegSelect(reg, 1);
  515. /* Switch data direction dummy. */
  516. nic_outlb(NIC_MGMT, rs | MGMT_MDO);
  517. nic_outlb(NIC_MGMT, rs | MGMT_MDO | MGMT_MCLK);
  518. nic_outlb(NIC_MGMT, rs);
  519. nic_outlb(NIC_MGMT, rs | MGMT_MCLK);
  520. /* Clock data out. */
  521. for (msk = 0x8000; msk; msk >>= 1) {
  522. if (val & msk) {
  523. nic_outlb(NIC_MGMT, rs | MGMT_MDO);
  524. nic_outlb(NIC_MGMT, rs | MGMT_MDO | MGMT_MCLK);
  525. } else {
  526. nic_outlb(NIC_MGMT, rs);
  527. nic_outlb(NIC_MGMT, rs | MGMT_MCLK);
  528. }
  529. }
  530. /* Set clock line low and output line int z-state. */
  531. nic_outlb(NIC_MGMT, rs & ~MGMT_MDOE);
  532. }
  533. /*!
  534. * \brief Configure the internal PHY.
  535. *
  536. * Reset the PHY and initiate auto-negotiation.
  537. */
  538. static int NicPhyConfig(void)
  539. {
  540. uint16_t phy_sr;
  541. uint16_t phy_to;
  542. uint16_t mode;
  543. /*
  544. * Reset the PHY and wait until this self clearing bit
  545. * becomes zero. We sleep 63 ms before each poll and
  546. * give up after 3 retries.
  547. */
  548. //printf("Reset PHY..");
  549. NicPhyWrite(NIC_PHYCR, PHYCR_RST);
  550. for (phy_to = 0;; phy_to++) {
  551. NutSleep(63);
  552. if ((NicPhyRead(NIC_PHYCR) & PHYCR_RST) == 0)
  553. break;
  554. if (phy_to > 3)
  555. return -1;
  556. }
  557. //printf("OK\n");
  558. /* Store PHY status output. */
  559. NicPhyRead(NIC_PHYSOR);
  560. /* Enable PHY interrupts. */
  561. NicPhyWrite(NIC_PHYMSK, PHYMSK_MLOSSSYN | PHYMSK_MCWRD | PHYMSK_MSSD |
  562. PHYMSK_MESD | PHYMSK_MRPOL | PHYMSK_MJAB | PHYMSK_MSPDDT | PHYMSK_MDPLDT);
  563. /* Set RPC register. */
  564. mode = RPCR_ANEG | RPCR_LEDA_PAT | RPCR_LEDB_PAT;
  565. nic_bs(0);
  566. nic_outw(NIC_RPCR, mode);
  567. #ifdef NIC_FIXED
  568. /* Disable link. */
  569. phy_sr = NicPhyRead(NIC_PHYCFR1);
  570. NicPhyWrite(NIC_PHYCFR1, phy_sr | 0x8000);
  571. NutSleep(63);
  572. /* Set fixed capabilities. */
  573. NicPhyWrite(NIC_PHYCR, NIC_FIXED);
  574. nic_bs(0);
  575. nic_outw(NIC_RPCR, mode);
  576. /* Enable link. */
  577. phy_sr = NicPhyRead(NIC_PHYCFR1);
  578. NicPhyWrite(NIC_PHYCFR1, phy_sr & ~0x8000);
  579. phy_sr = NicPhyRead(NIC_PHYCFR1);
  580. #else
  581. /*
  582. * Advertise our capabilities, initiate auto negotiation
  583. * and wait until this has been completed.
  584. */
  585. //printf("Negotiate..");
  586. NicPhyWrite(NIC_PHYANAD, PHYANAD_TX_FDX | PHYANAD_TX_HDX | PHYANAD_10FDX | PHYANAD_10_HDX | PHYANAD_CSMA);
  587. NutSleep(63);
  588. for (phy_to = 0, phy_sr = 0;; phy_to++) {
  589. /* Give up after 10 seconds. */
  590. if (phy_to >= 1024)
  591. return -1;
  592. /* Restart auto negotiation every 4 seconds or on failures. */
  593. if ((phy_to & 127) == 0 /* || (phy_sr & PHYSR_REM_FLT) != 0 */ ) {
  594. NicPhyWrite(NIC_PHYCR, PHYCR_ANEG_EN | PHYCR_ANEG_RST);
  595. //printf("Restart..");
  596. NutSleep(63);
  597. }
  598. /* Check if we are done. */
  599. phy_sr = NicPhyRead(NIC_PHYSR);
  600. //printf("[SR %04X]", phy_sr);
  601. if (phy_sr & PHYSR_ANEG_ACK)
  602. break;
  603. NutSleep(63);
  604. }
  605. //printf("OK\n");
  606. #endif
  607. return 0;
  608. }
  609. /*!
  610. * \brief Wait until MMU is ready.
  611. *
  612. * Poll the MMU command register until \ref MMUCR_BUSY
  613. * is cleared.
  614. *
  615. * \param tmo Timeout in milliseconds.
  616. *
  617. * \return 0 on success or -1 on timeout.
  618. */
  619. static NUT_INLINE_FUNC int NicMmuWait(uint16_t tmo)
  620. {
  621. while (tmo--) {
  622. if ((nic_inlb(NIC_MMUCR) & MMUCR_BUSY) == 0)
  623. break;
  624. NutDelay(1);
  625. }
  626. return tmo ? 0 : -1;
  627. }
  628. /*!
  629. * \brief Reset the Ethernet controller.
  630. *
  631. * \return 0 on success, -1 otherwise.
  632. */
  633. static int NicReset(void)
  634. {
  635. #ifdef LANC111_RESET_BIT
  636. sbi(LANC111_RESET_DDR, LANC111_RESET_BIT);
  637. sbi(LANC111_RESET_PORT, LANC111_RESET_BIT);
  638. NutDelay(WAIT100);
  639. cbi(LANC111_RESET_PORT, LANC111_RESET_BIT);
  640. NutDelay(WAIT250);
  641. NutDelay(WAIT250);
  642. #endif
  643. /* Disable all interrupts. */
  644. nic_outlb(NIC_MSK, 0);
  645. /* MAC and PHY software reset. */
  646. nic_bs(0);
  647. nic_outw(NIC_RCR, RCR_SOFT_RST);
  648. /* Enable Ethernet protocol handler. */
  649. nic_bs(1);
  650. nic_outw(NIC_CR, CR_EPH_EN);
  651. NutDelay(10);
  652. /* Disable transmit and receive. */
  653. nic_bs(0);
  654. nic_outw(NIC_RCR, 0);
  655. nic_outw(NIC_TCR, 0);
  656. /* Enable auto release. */
  657. nic_bs(1);
  658. nic_outw(NIC_CTR, CTR_AUTO_RELEASE);
  659. /* Reset MMU. */
  660. nic_bs(2);
  661. nic_outlb(NIC_MMUCR, MMU_RST);
  662. if (NicMmuWait(1000))
  663. return -1;
  664. return 0;
  665. }
  666. /*!
  667. * \brief Update the multicast register.
  668. *
  669. * \param Network interface controller information.
  670. */
  671. static void NicUpdateMCHardware(NICINFO * ni)
  672. {
  673. int i;
  674. /* Set multicast address register */
  675. nic_bs(3);
  676. for (i = 0; i < 7; i++) {
  677. nic_outlb(NIC_MT + i, ni->ni_mar[i]);
  678. }
  679. }
  680. /*
  681. * Fires up the network interface. NIC interrupts
  682. * should have been disabled when calling this
  683. * function.
  684. *
  685. * \param mac Six byte unique MAC address.
  686. */
  687. static int NicStart(const uint8_t * mac, NICINFO * ni)
  688. {
  689. uint8_t i;
  690. if (NicReset())
  691. return -1;
  692. /* Enable receiver. */
  693. nic_bs(3);
  694. nic_outlb(NIC_ERCV, 7);
  695. nic_bs(0);
  696. nic_outw(NIC_RCR, RCR_RXEN);
  697. /* Enable transmitter and padding. */
  698. nic_outw(NIC_TCR, TCR_PAD_EN | TCR_TXENA);
  699. /* Configure the PHY. */
  700. if (NicPhyConfig())
  701. return -1;
  702. /* Set MAC address. */
  703. //printf("Set MAC %02X%02X%02X%02X%02X%02X", mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]);
  704. nic_bs(1);
  705. for (i = 0; i < 6; i++)
  706. nic_outlb(NIC_IAR + i, mac[i]);
  707. //printf("OK\n");
  708. /* Set multicast address register */
  709. NicUpdateMCHardware(ni);
  710. /* Enable interrupts. */
  711. nic_bs(2);
  712. nic_outlb(NIC_MSK, INT_ERCV | INT_RCV | INT_RX_OVRN);
  713. return 0;
  714. }
  715. /*
  716. * NIC interrupt entry.
  717. */
  718. static void NicInterrupt(void *arg)
  719. {
  720. uint8_t isr;
  721. uint8_t imr;
  722. NICINFO *ni = (NICINFO *) ((NUTDEVICE *) arg)->dev_dcb;
  723. ni->ni_interrupts++;
  724. /* Read the interrupt mask and disable all interrupts. */
  725. nic_bs(2);
  726. imr = nic_inlb(NIC_MSK);
  727. nic_outlb(NIC_MSK, 0);
  728. /* Read the interrupt status and acknowledge all interrupts. */
  729. isr = nic_inlb(NIC_IST);
  730. //printf("\n!%02X-%02X ", isr, imr);
  731. isr &= imr;
  732. /*
  733. * If this is a transmit interrupt, then a packet has been sent.
  734. * So we can clear the transmitter busy flag and wake up the
  735. * transmitter thread.
  736. */
  737. if (isr & INT_TX_EMPTY) {
  738. nic_outlb(NIC_ACK, INT_TX_EMPTY);
  739. imr &= ~INT_TX_EMPTY;
  740. }
  741. /* Transmit error. */
  742. else if (isr & INT_TX) {
  743. /* re-enable transmit */
  744. nic_bs(0);
  745. nic_outw(NIC_TCR, nic_inlb(NIC_TCR) | TCR_TXENA);
  746. nic_bs(2);
  747. nic_outlb(NIC_ACK, INT_TX);
  748. /* kill the packet */
  749. nic_outlb(NIC_MMUCR, MMU_PKT);
  750. }
  751. /*
  752. * If this is a receive interrupt, then wake up the receiver
  753. * thread.
  754. */
  755. if (isr & INT_RX_OVRN) {
  756. nic_outlb(NIC_ACK, INT_RX_OVRN);
  757. //nic_outlb(NIC_MMUCR, MMU_TOP);
  758. NutEventPostFromIrq(&ni->ni_rx_rdy);
  759. }
  760. if (isr & INT_ERCV) {
  761. nic_outlb(NIC_ACK, INT_ERCV);
  762. NutEventPostFromIrq(&ni->ni_rx_rdy);
  763. }
  764. if (isr & INT_RCV) {
  765. nic_outlb(NIC_ACK, INT_RCV);
  766. imr &= ~INT_RCV;
  767. NutEventPostFromIrq(&ni->ni_rx_rdy);
  768. }
  769. if (isr & INT_ALLOC) {
  770. imr &= ~INT_ALLOC;
  771. NutEventPostFromIrq(&maq);
  772. }
  773. //printf(" -%02X-%02X- ", nic_inlb(NIC_IST), inb(PINE) & 0x20);
  774. nic_outlb(NIC_MSK, imr);
  775. }
  776. /*
  777. * Write data block to the NIC.
  778. */
  779. static void NicWrite(uint8_t * buf, uint16_t len)
  780. {
  781. register uint16_t l = len - 1;
  782. register uint8_t ih = (uint16_t) l >> 8;
  783. register uint8_t il = (uint8_t) l;
  784. if (!len)
  785. return;
  786. do {
  787. do {
  788. nic_outlb(NIC_DATA, *buf++);
  789. } while (il-- != 0);
  790. } while (ih-- != 0);
  791. }
  792. /*
  793. * Read data block from the NIC.
  794. */
  795. static void NicRead(uint8_t * buf, uint16_t len)
  796. {
  797. register uint16_t l = len - 1;
  798. register uint8_t ih = (uint16_t) l >> 8;
  799. register uint8_t il = (uint8_t) l;
  800. if (!len)
  801. return;
  802. do {
  803. do {
  804. *buf++ = nic_inlb(NIC_DATA);
  805. } while (il-- != 0);
  806. } while (ih-- != 0);
  807. }
  808. /*!
  809. * \brief Fetch the next packet out of the receive ring buffer.
  810. *
  811. * Nic interrupts must be disabled when calling this funtion.
  812. *
  813. * \return Pointer to an allocated ::NETBUF. If there is no
  814. * no data available, then the function returns a
  815. * null pointer. If the NIC's buffer seems to be
  816. * corrupted, a pointer to 0xFFFF is returned.
  817. */
  818. static NETBUF *NicGetPacket(void)
  819. {
  820. NETBUF *nb = 0;
  821. //uint8_t *buf;
  822. uint16_t fsw;
  823. uint16_t fbc;
  824. /* Check the fifo empty bit. If it is set, then there is
  825. nothing in the receiver fifo. */
  826. nic_bs(2);
  827. if (nic_inw(NIC_FIFO) & 0x8000) {
  828. return 0;
  829. }
  830. /* Inialize pointer register. */
  831. nic_outw(NIC_PTR, PTR_READ | PTR_RCV | PTR_AUTO_INCR);
  832. _NOP();
  833. _NOP();
  834. _NOP();
  835. _NOP();
  836. /* Read status word and byte count. */
  837. fsw = nic_inw(NIC_DATA);
  838. fbc = nic_inw(NIC_DATA);
  839. //printf("[SW=%04X,BC=%04X]", fsw, fbc);
  840. /* Check for frame errors. */
  841. if (fsw & 0xAC00) {
  842. nb = (NETBUF *) 0xFFFF;
  843. }
  844. /* Check the byte count. */
  845. else if (fbc < 66 || fbc > 1524) {
  846. nb = (NETBUF *) 0xFFFF;
  847. }
  848. else {
  849. /*
  850. * Allocate a NETBUF.
  851. * Hack alert: Rev A chips never set the odd frame indicator.
  852. */
  853. fbc -= 3;
  854. nb = NutNetBufAlloc(0, NBAF_DATALINK, fbc);
  855. /* Perform the read. */
  856. if (nb)
  857. NicRead(nb->nb_dl.vp, fbc);
  858. }
  859. /* Release the packet. */
  860. nic_outlb(NIC_MMUCR, MMU_TOP);
  861. return nb;
  862. }
  863. /*!
  864. * \brief Load a packet into the nic's transmit ring buffer.
  865. *
  866. * Interupts must have been disabled when calling this function.
  867. *
  868. * \param nb Network buffer structure containing the packet to be sent.
  869. * The structure must have been allocated by a previous
  870. * call NutNetBufAlloc(). This routine will automatically
  871. * release the buffer in case of an error.
  872. *
  873. * \return 0 on success, -1 in case of any errors. Errors
  874. * will automatically release the network buffer
  875. * structure.
  876. */
  877. static int NicPutPacket(NETBUF * nb)
  878. {
  879. uint16_t sz;
  880. uint8_t odd = 0;
  881. uint8_t imsk;
  882. //printf("[P]");
  883. /*
  884. * Calculate the number of bytes to be send. Do not send packets
  885. * larger than the Ethernet maximum transfer unit. The MTU
  886. * consist of 1500 data bytes plus the 14 byte Ethernet header
  887. * plus 4 bytes CRC. We check the data bytes only.
  888. */
  889. if ((sz = nb->nb_nw.sz + nb->nb_tp.sz + nb->nb_ap.sz) > ETHERMTU)
  890. return -1;
  891. /* Disable all interrupts. */
  892. imsk = nic_inlb(NIC_MSK);
  893. nic_outlb(NIC_MSK, 0);
  894. /* Allocate packet buffer space. */
  895. nic_bs(2);
  896. nic_outlb(NIC_MMUCR, MMU_ALO);
  897. if (NicMmuWait(100))
  898. return -1;
  899. /* Enable interrupts including allocation success. */
  900. nic_outlb(NIC_MSK, imsk | INT_ALLOC);
  901. /* The MMU needs some time. Use it to calculate the byte count. */
  902. sz += nb->nb_dl.sz;
  903. sz += 6;
  904. if (sz & 1) {
  905. sz++;
  906. odd++;
  907. }
  908. /* Wait for allocation success. */
  909. while ((nic_inlb(NIC_IST) & INT_ALLOC) == 0) {
  910. if (NutEventWait(&maq, 125)) {
  911. nic_outlb(NIC_MMUCR, MMU_RST);
  912. NicMmuWait(1000);
  913. nic_outlb(NIC_MMUCR, MMU_ALO);
  914. if (NicMmuWait(100) || (nic_inlb(NIC_IST) & INT_ALLOC) == 0) {
  915. if (NutEventWait(&maq, 125)) {
  916. return -1;
  917. }
  918. }
  919. }
  920. }
  921. /* Disable interrupts. */
  922. imsk = nic_inlb(NIC_MSK);
  923. nic_outlb(NIC_MSK, 0);
  924. nic_outlb(NIC_PNR, nic_inhb(NIC_PNR));
  925. nic_outw(NIC_PTR, 0x4000);
  926. /* Transfer control word. */
  927. nic_outlb(NIC_DATA, 0);
  928. nic_outlb(NIC_DATA, 0);
  929. /* Transfer the byte count. */
  930. nic_outw(NIC_DATA, sz);
  931. /* Transfer the Ethernet frame. */
  932. NicWrite(nb->nb_dl.vp, nb->nb_dl.sz);
  933. NicWrite(nb->nb_nw.vp, nb->nb_nw.sz);
  934. NicWrite(nb->nb_tp.vp, nb->nb_tp.sz);
  935. NicWrite(nb->nb_ap.vp, nb->nb_ap.sz);
  936. if (odd)
  937. nic_outlb(NIC_DATA, 0);
  938. /* Transfer the control word. */
  939. nic_outw(NIC_DATA, 0);
  940. /* Enqueue packet. */
  941. if (NicMmuWait(100))
  942. return -1;
  943. nic_outlb(NIC_MMUCR, MMU_ENQ);
  944. /* Enable interrupts. */
  945. imsk |= INT_TX | INT_TX_EMPTY;
  946. nic_outlb(NIC_MSK, imsk);
  947. return 0;
  948. }
  949. /*! \fn NicRxLanc(void *arg)
  950. * \brief NIC receiver thread.
  951. *
  952. */
  953. THREAD(NicRxLanc, arg)
  954. {
  955. NUTDEVICE *dev;
  956. IFNET *ifn;
  957. NICINFO *ni;
  958. NETBUF *nb;
  959. uint8_t imsk;
  960. dev = arg;
  961. ifn = (IFNET *) dev->dev_icb;
  962. ni = (NICINFO *) dev->dev_dcb;
  963. /*
  964. * This is a temporary hack. Due to a change in initialization,
  965. * we may not have got a MAC address yet. Wait until a valid one
  966. * has been set.
  967. */
  968. while (!ETHER_IS_UNICAST(ifn->if_mac)) {
  969. NutSleep(10);
  970. }
  971. /*
  972. * Do not continue unless we managed to start the NIC. We are
  973. * trapped here if the Ethernet link cannot be established.
  974. * This happens, for example, if no Ethernet cable is plugged
  975. * in.
  976. */
  977. while (NicStart(ifn->if_mac, ni)) {
  978. NutSleep(1000);
  979. }
  980. LANC111_SIGNAL_MODE();
  981. sbi(EIMSK, LANC111_SIGNAL_IRQ);
  982. NutEventPost(&mutex);
  983. /* Run at high priority. */
  984. NutThreadSetPriority(9);
  985. for (;;) {
  986. /*
  987. * Wait for the arrival of new packets or
  988. * check the receiver every two second.
  989. */
  990. NutEventWait(&ni->ni_rx_rdy, 2000);
  991. /*
  992. * Fetch all packets from the NIC's internal
  993. * buffer and pass them to the registered handler.
  994. */
  995. imsk = nic_inlb(NIC_MSK);
  996. nic_outlb(NIC_MSK, 0);
  997. while ((nb = NicGetPacket()) != 0) {
  998. if (nb != (NETBUF *) 0xFFFF) {
  999. ni->ni_rx_packets++;
  1000. (*ifn->if_recv) (dev, nb);
  1001. }
  1002. }
  1003. nic_outlb(NIC_MSK, imsk | INT_RCV | INT_ERCV);
  1004. }
  1005. }
  1006. /*!
  1007. * \brief Send Ethernet packet.
  1008. *
  1009. * \param dev Identifies the device to use.
  1010. * \param nb Network buffer structure containing the packet to be sent.
  1011. * The structure must have been allocated by a previous
  1012. * call NutNetBufAlloc().
  1013. *
  1014. * \return 0 on success, -1 in case of any errors.
  1015. */
  1016. int LancOutput(NUTDEVICE * dev, NETBUF * nb)
  1017. {
  1018. static uint32_t mx_wait = 5000;
  1019. int rc = -1;
  1020. NICINFO *ni;
  1021. /*
  1022. * After initialization we are waiting for a long time to give
  1023. * the PHY a chance to establish an Ethernet link.
  1024. */
  1025. if (NutEventWait(&mutex, mx_wait) == 0) {
  1026. ni = (NICINFO *) dev->dev_dcb;
  1027. if (NicPutPacket(nb) == 0) {
  1028. ni->ni_tx_packets++;
  1029. rc = 0;
  1030. /* Ethernet works. Set a long waiting time in case we
  1031. temporarly lose the link next time. */
  1032. mx_wait = 5000;
  1033. }
  1034. NutEventPost(&mutex);
  1035. }
  1036. /*
  1037. * Probably no Ethernet link. Significantly reduce the waiting
  1038. * time, so following transmission will soon return an error.
  1039. */
  1040. else {
  1041. mx_wait = 500;
  1042. }
  1043. return rc;
  1044. }
  1045. /*!
  1046. * \brief Initialize Ethernet hardware.
  1047. *
  1048. * Resets the LAN91C111 Ethernet controller, initializes all required
  1049. * hardware registers and starts a background thread for incoming
  1050. * Ethernet traffic.
  1051. *
  1052. * Applications should do not directly call this function. It is
  1053. * automatically executed during during device registration by
  1054. * NutRegisterDevice().
  1055. *
  1056. * If the network configuration hasn't been set by the application
  1057. * before registering the specified device, this function will
  1058. * call NutNetLoadConfig() to get the MAC address.
  1059. *
  1060. * \param dev Identifies the device to initialize.
  1061. */
  1062. int LancInit(NUTDEVICE * dev)
  1063. {
  1064. /* Disable NIC interrupt and clear NICINFO structure. */
  1065. cbi(EIMSK, LANC111_SIGNAL_IRQ);
  1066. memset(dev->dev_dcb, 0, sizeof(NICINFO));
  1067. /* Register interrupt handler and enable interrupts. */
  1068. if (NutRegisterIrqHandler(&LANC111_SIGNAL, NicInterrupt, dev))
  1069. return -1;
  1070. /*
  1071. * Start the receiver thread.
  1072. *
  1073. * avr-gcc size optimized code used 76 bytes.
  1074. */
  1075. NutThreadCreate("rxi5", NicRxLanc, dev, (NUT_THREAD_LANCRXSTACK * NUT_THREAD_STACK_MULT) + NUT_THREAD_STACK_ADD);
  1076. //NutSleep(500);
  1077. return 0;
  1078. }
  1079. static int LancIOCtl(NUTDEVICE * dev, int req, void *conf)
  1080. {
  1081. int rc = 0;
  1082. IFNET *nif = (IFNET *) dev->dev_icb;
  1083. NICINFO *ni = (NICINFO *) dev->dev_dcb;
  1084. uint32_t i;
  1085. MCASTENTRY *mcast;
  1086. uint8_t mac[6];
  1087. switch (req) {
  1088. /* Set interface address */
  1089. case SIOCSIFADDR:
  1090. /* Set interface hardware address. */
  1091. memcpy(nif->if_mac, conf, sizeof(nif->if_mac));
  1092. break;
  1093. /* Add multicast address */
  1094. case SIOCADDMULTI:
  1095. mac[0] = 0x01;
  1096. mac[1] = 0x00;
  1097. mac[2] = 0x5E;
  1098. mac[3] = ((uint8_t *) conf)[1] & 0x7f;
  1099. mac[4] = ((uint8_t *) conf)[2];
  1100. mac[5] = ((uint8_t *) conf)[3];
  1101. mcast = malloc(sizeof(MCASTENTRY));
  1102. if (mcast != NULL) {
  1103. /*
  1104. * HACK ALERT (MF):
  1105. * I do not know the correct algorithm. The algorithm
  1106. * which works for the dm9000 does not work here.
  1107. * Therefore set all bits to 1.
  1108. */
  1109. for (i = 0; i < 7; i++) {
  1110. ni->ni_mar[i] = 0xFF;
  1111. }
  1112. /* Add new mcast to the mcast list */
  1113. memcpy(mcast->mca_ha, mac, 6);
  1114. mcast->mca_ip = *((uint32_t *) conf);
  1115. mcast->mca_next = nif->if_mcast;
  1116. nif->if_mcast = mcast;
  1117. /* Update the MC hardware */
  1118. NicUpdateMCHardware(ni);
  1119. } else {
  1120. rc = -1;
  1121. }
  1122. break;
  1123. /* Delete multicast address */
  1124. case SIOCDELMULTI:
  1125. /* Will be implemented later */
  1126. rc = -1;
  1127. break;
  1128. default:
  1129. rc = -1;
  1130. break;
  1131. }
  1132. return rc;
  1133. }
  1134. static NICINFO dcb_eth0;
  1135. /*!
  1136. * \brief Network interface information structure.
  1137. *
  1138. * Used to call.
  1139. */
  1140. static IFNET ifn_eth0 = {
  1141. IFT_ETHER, /*!< \brief Interface type. */
  1142. 0, /*!< \brief Interface flags, if_flags. */
  1143. {0, 0, 0, 0, 0, 0}, /*!< \brief Hardware net address. */
  1144. 0, /*!< \brief IP address. */
  1145. 0, /*!< \brief Remote IP address for point to point. */
  1146. 0, /*!< \brief IP network mask. */
  1147. ETHERMTU, /*!< \brief Maximum size of a transmission unit. */
  1148. 0, /*!< \brief Packet identifier. */
  1149. 0, /*!< \brief Linked list of arp entries. */
  1150. 0, /*!< \brief Linked list of multicast address entries, if_mcast. */
  1151. NutEtherInput, /*!< \brief Routine to pass received data to, if_recv(). */
  1152. LancOutput, /*!< \brief Driver output routine, if_send(). */
  1153. NutEtherOutput, /*!< \brief Media output routine, if_output(). */
  1154. NULL /*!< \brief Interface specific control function, if_ioctl(). */
  1155. #ifdef NUT_PERFMON
  1156. , 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
  1157. #endif
  1158. };
  1159. /*!
  1160. * \brief Device information structure.
  1161. *
  1162. * A pointer to this structure must be passed to NutRegisterDevice()
  1163. * to bind this Ethernet device driver to the Nut/OS kernel.
  1164. * An application may then call NutNetIfConfig() with the name \em eth0
  1165. * of this driver to initialize the network interface.
  1166. *
  1167. */
  1168. NUTDEVICE devSmsc111 = {
  1169. 0, /* Pointer to next device. */
  1170. {'e', 't', 'h', '0', 0, 0, 0, 0, 0}, /* Unique device name. */
  1171. IFTYP_NET, /* Type of device. */
  1172. 0, /* Base address. */
  1173. 0, /* First interrupt number. */
  1174. &ifn_eth0, /* Interface control block. */
  1175. &dcb_eth0, /* Driver control block. */
  1176. LancInit, /* Driver initialization routine. */
  1177. LancIOCtl, /* Driver specific control function. */
  1178. 0, /* Read from device. */
  1179. 0, /* Write to device. */
  1180. 0, /* Write from program space data to device. */
  1181. 0, /* Open a device or file. */
  1182. 0, /* Close a device or file. */
  1183. 0, /* Request file size. */
  1184. 0, /* Select function, optional, not yet implemented */
  1185. };
  1186. /*@}*/