Contiki 2.5
lanc111.c
1 #define INLINE
2 #define CONST const
3 #define NETBUF char
4 /*
5  * Copyright (C) 2003-2005 by egnite Software GmbH. All rights reserved.
6  *
7  * Redistribution and use in source and binary forms, with or without
8  * modification, are permitted provided that the following conditions
9  * are met:
10  *
11  * 1. Redistributions of source code must retain the above copyright
12  * notice, this list of conditions and the following disclaimer.
13  * 2. Redistributions in binary form must reproduce the above copyright
14  * notice, this list of conditions and the following disclaimer in the
15  * documentation and/or other materials provided with the distribution.
16  * 3. Neither the name of the copyright holders nor the names of
17  * contributors may be used to endorse or promote products derived
18  * from this software without specific prior written permission.
19  *
20  * THIS SOFTWARE IS PROVIDED BY EGNITE SOFTWARE GMBH AND CONTRIBUTORS
21  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
22  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
23  * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL EGNITE
24  * SOFTWARE GMBH OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
25  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
26  * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
27  * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
28  * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
29  * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
30  * THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
31  * SUCH DAMAGE.
32  *
33  * For additional information see http://www.ethernut.de/
34  *
35  */
36 
37 /*
38  * $Log: lanc111.c,v $
39  * Revision 1.1 2006/06/17 22:41:21 adamdunkels
40  * Import of the contiki-2.x development code from the SICS internal CVS server
41  *
42  * Revision 1.1 2005/09/19 23:05:34 adam
43  * AVR device drivers
44  *
45  * Revision 1.1 2005/05/19 09:06:25 adam
46  * Very initial version of the LANC111 Ethernet driver, imported from Nut/OS code - does not work yet
47  *
48  * Revision 1.12 2005/02/02 19:55:34 haraldkipp
49  * If no Ethernet link was available on the LAN91C111, each outgoing packet
50  * took 15 seconds and, even worse, the ouput routine doesn't return an error.
51  * Now the first attempt to send a packet without Ethernet link will wait for
52  * 5 seconds and subsequent attempts take 0.5 seconds only, always returning
53  * an error.
54  *
55  * Revision 1.11 2005/01/24 21:11:49 freckle
56  * renamed NutEventPostFromIRQ into NutEventPostFromIrq
57  *
58  * Revision 1.10 2005/01/22 19:24:11 haraldkipp
59  * Changed AVR port configuration names from PORTx to AVRPORTx.
60  *
61  * Revision 1.9 2005/01/21 16:49:45 freckle
62  * Seperated calls to NutEventPostAsync between Threads and IRQs
63  *
64  * Revision 1.8 2004/09/22 08:14:48 haraldkipp
65  * Made configurable
66  *
67  * Revision 1.7 2004/03/08 11:14:17 haraldkipp
68  * Added quick hack for fixed mode.
69  *
70  * Revision 1.6 2004/02/25 16:22:33 haraldkipp
71  * Do not initialize MAC with all zeros
72  *
73  * Revision 1.5 2004/01/14 19:31:43 drsung
74  * Speed improvement to NicWrite applied. Thanks to Kolja Waschk
75  *
76  * Revision 1.4 2003/11/06 09:26:50 haraldkipp
77  * Removed silly line with hardcoded MAC, left over from testing
78  *
79  * Revision 1.3 2003/11/04 17:54:47 haraldkipp
80  * PHY configuration timing changed again for reliable linking
81  *
82  * Revision 1.2 2003/11/03 17:12:53 haraldkipp
83  * Allow linking with RTL8019 driver.
84  * Links more reliable to 10 MBit networks now.
85  * Reset MMU on allocation failures.
86  * Some optimizations.
87  *
88  * Revision 1.1 2003/10/13 10:13:49 haraldkipp
89  * First release
90  *
91  */
92 
93 #include "contiki.h"
94 
95 #include <string.h>
96 
97 #include <avr/io.h>
98 
99 /*
100  * Determine ports, which had not been explicitely configured.
101  */
102 #ifndef LANC111_BASE_ADDR
103 #define LANC111_BASE_ADDR 0xC000
104 #endif
105 
106 #ifndef LANC111_SIGNAL_IRQ
107 #define LANC111_SIGNAL_IRQ INT5
108 #endif
109 
110 #ifdef LANC111_RESET_BIT
111 
112 #if (LANC111_RESET_AVRPORT == AVRPORTB)
113 #define LANC111_RESET_PORT PORTB
114 #define LANC111_RESET_DDR DDRB
115 
116 #elif (LANC111_RESET_AVRPORT == AVRPORTD)
117 #define LANC111_RESET_PORT PORTD
118 #define LANC111_RESET_DDR DDRD
119 
120 #elif (LANC111_RESET_AVRPORT == AVRPORTE)
121 #define LANC111_RESET_PORT PORTE
122 #define LANC111_RESET_DDR DDRE
123 
124 #elif (LANC111_RESET_AVRPORT == AVRPORTF)
125 #define LANC111_RESET_PORT PORTF
126 #define LANC111_RESET_DDR DDRF
127 
128 #endif /* LANC111_RESET_AVRPORT */
129 
130 #endif /* LANC111_RESET_BIT */
131 
132 /*
133  * Determine interrupt settings.
134  */
135 #if (LANC111_SIGNAL_IRQ == INT0)
136 #define LANC111_SIGNAL sig_INTERRUPT0
137 #define LANC111_SIGNAL_MODE() sbi(EICRA, ISC00); sbi(EICRA, ISC01)
138 
139 #elif (LANC111_SIGNAL_IRQ == INT1)
140 #define LANC111_SIGNAL sig_INTERRUPT1
141 #define LANC111_SIGNAL_MODE() sbi(EICRA, ISC10); sbi(EICRA, ISC11)
142 
143 #elif (LANC111_SIGNAL_IRQ == INT2)
144 #define LANC111_SIGNAL sig_INTERRUPT2
145 #define LANC111_SIGNAL_MODE() sbi(EICRA, ISC20); sbi(EICRA, ISC21)
146 
147 #elif (LANC111_SIGNAL_IRQ == INT3)
148 #define LANC111_SIGNAL sig_INTERRUPT3
149 #define LANC111_SIGNAL_MODE() sbi(EICRA, ISC30); sbi(EICRA, ISC31)
150 
151 #elif (LANC111_SIGNAL_IRQ == INT4)
152 #define LANC111_SIGNAL sig_INTERRUPT4
153 #define LANC111_SIGNAL_MODE() sbi(EICRB, ISC40); sbi(EICRB, ISC41)
154 
155 #elif (LANC111_SIGNAL_IRQ == INT6)
156 #define LANC111_SIGNAL sig_INTERRUPT6
157 #define LANC111_SIGNAL_MODE() sbi(EICRB, ISC60); sbi(EICRB, ISC61)
158 
159 #elif (LANC111_SIGNAL_IRQ == INT7)
160 #define LANC111_SIGNAL sig_INTERRUPT7
161 #define LANC111_SIGNAL_MODE() sbi(EICRB, ISC70); sbi(EICRB, ISC71)
162 
163 #else
164 #define LANC111_SIGNAL sig_INTERRUPT5
165 #define LANC111_SIGNAL_MODE() sbi(EICRB, ISC50); sbi(EICRB, ISC51)
166 
167 #endif
168 
169 /*!
170  * \addtogroup xgSmscRegs
171  */
172 /*@{*/
173 
174 /*!
175  * \brief Bank select register.
176  */
177 #define NIC_BSR (LANC111_BASE_ADDR + 0x0E)
178 
179 /*!
180  * \brief Bank 0 - Transmit control register.
181  */
182 #define NIC_TCR (LANC111_BASE_ADDR + 0x00)
183 
184 #define TCR_SWFDUP 0x8000 /*!< \ref NIC_TCR bit mask, enables full duplex. */
185 #define TCR_EPH_LOOP 0x2000 /*!< \ref NIC_TCR bit mask, enables internal loopback. */
186 #define TCR_STP_SQET 0x1000 /*!< \ref NIC_TCR bit mask, enables transmission stop on SQET error. */
187 #define TCR_FDUPLX 0x0800 /*!< \ref NIC_TCR bit mask, enables receiving own frames. */
188 #define TCR_MON_CSN 0x0400 /*!< \ref NIC_TCR bit mask, enables carrier monitoring. */
189 #define TCR_NOCRC 0x0100 /*!< \ref NIC_TCR bit mask, disables CRC transmission. */
190 #define TCR_PAD_EN 0x0080 /*!< \ref NIC_TCR bit mask, enables automatic padding. */
191 #define TCR_FORCOL 0x0004 /*!< \ref NIC_TCR bit mask, forces collision. */
192 #define TCR_LOOP 0x0002 /*!< \ref NIC_TCR bit mask, enables PHY loopback. */
193 #define TCR_TXENA 0x0001 /*!< \ref NIC_TCR bit mask, enables transmitter. */
194 
195 
196 /*!
197  * \brief Bank 0 - EPH status register.
198  */
199 #define NIC_EPHSR (LANC111_BASE_ADDR + 0x02)
200 
201 /*!
202  * \brief Bank 0 - Receive control register.
203  */
204 #define NIC_RCR (LANC111_BASE_ADDR + 0x04)
205 
206 #define RCR_SOFT_RST 0x8000 /*!< \ref NIC_RCR bit mask, activates software reset. */
207 #define RCR_FILT_CAR 0x4000 /*!< \ref NIC_RCR bit mask, enables carrier filter. */
208 #define RCR_ABORT_ENB 0x2000 /*!< \ref NIC_RCR bit mask, enables receive abort on collision. */
209 #define RCR_STRIP_CRC 0x0200 /*!< \ref NIC_RCR bit mask, strips CRC. */
210 #define RCR_RXEN 0x0100 /*!< \ref NIC_RCR bit mask, enables receiver. */
211 #define RCR_ALMUL 0x0004 /*!< \ref NIC_RCR bit mask, multicast frames accepted when set. */
212 #define RCR_PRMS 0x0002 /*!< \ref NIC_RCR bit mask, enables promiscuous mode. */
213 #define RCR_RX_ABORT 0x0001 /*!< \ref NIC_RCR bit mask, set when receive was aborted. */
214 
215 /*!
216  * \brief Bank 0 - Counter register.
217  */
218 #define NIC_ECR (LANC111_BASE_ADDR + 0x06)
219 
220 /*!
221  * \brief Bank 0 - Memory information register.
222  */
223 #define NIC_MIR (LANC111_BASE_ADDR + 0x08)
224 
225 /*!
226  * \brief Bank 0 - Receive / PHY control register.
227  */
228 #define NIC_RPCR (LANC111_BASE_ADDR + 0x0A)
229 
230 #define RPCR_SPEED 0x2000 /*!< \ref NIC_RPCR bit mask, PHY operates at 100 Mbps. */
231 #define RPCR_DPLX 0x1000 /*!< \ref NIC_RPCR bit mask, PHY operates at full duplex mode. */
232 #define RPCR_ANEG 0x0800 /*!< \ref NIC_RPCR bit mask, sets PHY in auto-negotiation mode. */
233 #define RPCR_LEDA_PAT 0x0000 /*!< \ref NIC_RPCR bit mask for LEDA mode. */
234 #define RPCR_LEDB_PAT 0x0010 /*!< \ref NIC_RPCR bit mask for LEDB mode. */
235 
236 /*!
237  * \brief Bank 1 - Configuration register.
238  */
239 #define NIC_CR (LANC111_BASE_ADDR + 0x00)
240 
241 #define CR_EPH_EN 0x8000 /*!< \ref NIC_CR bit mask, . */
242 
243 /*!
244  * \brief Bank 1 - Base address register.
245  */
246 #define NIC_BAR (LANC111_BASE_ADDR + 0x02)
247 
248 /*!
249  * \brief Bank 1 - Individual address register.
250  */
251 #define NIC_IAR (LANC111_BASE_ADDR + 0x04)
252 
253 /*!
254  * \brief Bank 1 - General purpose register.
255  */
256 #define NIC_GPR (LANC111_BASE_ADDR + 0x0A)
257 
258 /*!
259  * \brief Bank 1 - Control register.
260  */
261 #define NIC_CTR (LANC111_BASE_ADDR + 0x0C)
262 
263 #define CTR_RCV_BAD 0x4000 /*!< \ref NIC_CTR bit mask. */
264 #define CTR_AUTO_RELEASE 0x0800 /*!< \ref NIC_CTR bit mask, transmit packets automatically released. */
265 
266 /*!
267  * \brief Bank 2 - MMU command register.
268  */
269 #define NIC_MMUCR (LANC111_BASE_ADDR + 0x00)
270 
271 #define MMUCR_BUSY 0x0001
272 
273 #define MMU_NOP 0
274 #define MMU_ALO (1<<5)
275 #define MMU_RST (2<<5)
276 #define MMU_REM (3<<5)
277 #define MMU_TOP (4<<5)
278 #define MMU_PKT (5<<5)
279 #define MMU_ENQ (6<<5)
280 #define MMU_RTX (7<<5)
281 
282 /*!
283  * \brief Bank 2 - Packet number register.
284  *
285  * This byte register specifies the accessible transmit packet number.
286  */
287 #define NIC_PNR (LANC111_BASE_ADDR + 0x02)
288 
289 /*!
290  * \brief Bank 2 - Allocation result register.
291  *
292  * This byte register is updated upon a \ref MMU_ALO command.
293  */
294 #define NIC_ARR (LANC111_BASE_ADDR + 0x03)
295 
296 #define ARR_FAILED 0x80
297 
298 /*!
299  * \brief Bank 2 - FIFO ports register.
300  */
301 #define NIC_FIFO (LANC111_BASE_ADDR + 0x04)
302 
303 /*!
304  * \brief Bank 2 - Pointer register.
305  */
306 #define NIC_PTR (LANC111_BASE_ADDR + 0x06)
307 
308 #define PTR_RCV 0x8000 /*! \ref NIC_PTR bit mask, specifies receive or transmit buffer. */
309 #define PTR_AUTO_INCR 0x4000 /*! \ref NIC_PTR bit mask, enables automatic pointer increment. */
310 #define PTR_READ 0x2000 /*! \ref NIC_PTR bit mask, indicates type of access. */
311 #define PTR_ETEN 0x1000 /*! \ref NIC_PTR bit mask, enables early transmit underrun detection. */
312 #define PTR_NOT_EMPTY 0x0800 /*! \ref NIC_PTR bit mask, set when write data fifo is not empty. */
313 
314 /*!
315  * \brief Bank 2 - Data register.
316  */
317 #define NIC_DATA (LANC111_BASE_ADDR + 0x08)
318 
319 /*!
320  * \brief Bank 2 - Interrupt status register.
321  */
322 #define NIC_IST (LANC111_BASE_ADDR + 0x0C)
323 
324 /*!
325  * \brief Bank 2 - Interrupt acknowledge register.
326  */
327 #define NIC_ACK (LANC111_BASE_ADDR + 0x0C)
328 
329 /*!
330  * \brief Bank 2 - Interrupt mask register.
331  */
332 #define NIC_MSK (LANC111_BASE_ADDR + 0x0D)
333 
334 #define INT_MD 0x80 /*!< \ref PHY state change interrupt bit mask. */
335 #define INT_ERCV 0x40 /*!< \ref Early receive interrupt bit mask. */
336 #define INT_EPH 0x20 /*!< \ref Ethernet protocol interrupt bit mask. */
337 #define INT_RX_OVRN 0x10 /*!< \ref Receive overrun interrupt bit mask. */
338 #define INT_ALLOC 0x08 /*!< \ref Transmit allocation interrupt bit mask. */
339 #define INT_TX_EMPTY 0x04 /*!< \ref Transmitter empty interrupt bit mask. */
340 #define INT_TX 0x02 /*!< \ref Transmit complete interrupt bit mask. */
341 #define INT_RCV 0x01 /*!< \ref Receive interrupt bit mask. */
342 
343 /*!
344  * \brief Bank 3 - Multicast table register.
345  */
346 #define NIC_MT (LANC111_BASE_ADDR + 0x00)
347 
348 /*!
349  * \brief Bank 3 - Management interface register.
350  */
351 #define NIC_MGMT (LANC111_BASE_ADDR + 0x08)
352 
353 #define MGMT_MDOE 0x08 /*!< \ref NIC_MGMT bit mask, enables MDO pin. */
354 #define MGMT_MCLK 0x04 /*!< \ref NIC_MGMT bit mask, drives MDCLK pin. */
355 #define MGMT_MDI 0x02 /*!< \ref NIC_MGMT bit mask, reflects MDI pin status. */
356 #define MGMT_MDO 0x01 /*!< \ref NIC_MGMT bit mask, drives MDO pin. */
357 
358 /*!
359  * \brief Bank 3 - Revision register.
360  */
361 #define NIC_REV (LANC111_BASE_ADDR + 0x0A)
362 
363 /*!
364  * \brief Bank 3 - Early RCV register.
365  */
366 #define NIC_ERCV (LANC111_BASE_ADDR + 0x0C)
367 
368 /*!
369  * \brief PHY control register.
370  */
371 #define NIC_PHYCR 0
372 
373 #define PHYCR_RST 0x8000 /*!< \ref NIC_PHYCR bit mask, resets PHY. */
374 #define PHYCR_LPBK 0x4000 /*!< \ref NIC_PHYCR bit mask, . */
375 #define PHYCR_SPEED 0x2000 /*!< \ref NIC_PHYCR bit mask, . */
376 #define PHYCR_ANEG_EN 0x1000 /*!< \ref NIC_PHYCR bit mask, . */
377 #define PHYCR_PDN 0x0800 /*!< \ref NIC_PHYCR bit mask, . */
378 #define PHYCR_MII_DIS 0x0400 /*!< \ref NIC_PHYCR bit mask, . */
379 #define PHYCR_ANEG_RST 0x0200 /*!< \ref NIC_PHYCR bit mask, . */
380 #define PHYCR_DPLX 0x0100 /*!< \ref NIC_PHYCR bit mask, . */
381 #define PHYCR_COLST 0x0080 /*!< \ref NIC_PHYCR bit mask, . */
382 
383 
384 /*!
385  * \brief PHY status register.
386  */
387 #define NIC_PHYSR 1
388 
389 #define PHYSR_CAP_T4 0x8000 /*!< \ref NIC_PHYSR bit mask, indicates 100BASE-T4 capability. */
390 #define PHYSR_CAP_TXF 0x4000 /*!< \ref NIC_PHYSR bit mask, indicates 100BASE-TX full duplex capability. */
391 #define PHYSR_CAP_TXH 0x2000 /*!< \ref NIC_PHYSR bit mask, indicates 100BASE-TX half duplex capability. */
392 #define PHYSR_CAP_TF 0x1000 /*!< \ref NIC_PHYSR bit mask, indicates 10BASE-T full duplex capability. */
393 #define PHYSR_CAP_TH 0x0800 /*!< \ref NIC_PHYSR bit mask, indicates 10BASE-T half duplex capability. */
394 #define PHYSR_CAP_SUPR 0x0040 /*!< \ref NIC_PHYSR bit mask, indicates preamble suppression capability. */
395 #define PHYSR_ANEG_ACK 0x0020 /*!< \ref NIC_PHYSR bit mask, auto-negotiation completed. */
396 #define PHYSR_REM_FLT 0x0010 /*!< \ref NIC_PHYSR bit mask, remote fault detected. */
397 #define PHYSR_CAP_ANEG 0x0008 /*!< \ref NIC_PHYSR bit mask, indicates auto-negotiation capability. */
398 #define PHYSR_LINK 0x0004 /*!< \ref NIC_PHYSR bit mask, valid link status. */
399 #define PHYSR_JAB 0x0002 /*!< \ref NIC_PHYSR bit mask, jabber collision detected. */
400 #define PHYSR_EXREG 0x0001 /*!< \ref NIC_PHYSR bit mask, extended capabilities available. */
401 
402 
403 /*!
404  * \brief PHY identifier register 1.
405  */
406 #define NIC_PHYID1 2
407 
408 /*!
409  * \brief PHY identifier register 1.
410  */
411 #define NIC_PHYID2 3
412 
413 /*!
414  * \brief PHY auto-negotiation advertisement register.
415  */
416 #define NIC_PHYANAD 4
417 
418 #define PHYANAD_NP 0x8000 /*!< \ref NIC_PHYANAD bit mask, exchanging next page information. */
419 #define PHYANAD_ACK 0x4000 /*!< \ref NIC_PHYANAD bit mask, acknowledged. */
420 #define PHYANAD_RF 0x2000 /*!< \ref NIC_PHYANAD bit mask, remote fault. */
421 #define PHYANAD_T4 0x0200 /*!< \ref NIC_PHYANAD bit mask, indicates 100BASE-T4 capability. */
422 #define PHYANAD_TX_FDX 0x0100 /*!< \ref NIC_PHYANAD bit mask, indicates 100BASE-TX full duplex capability. */
423 #define PHYANAD_TX_HDX 0x0080 /*!< \ref NIC_PHYANAD bit mask, indicates 100BASE-TX half duplex capability. */
424 #define PHYANAD_10FDX 0x0040 /*!< \ref NIC_PHYANAD bit mask, indicates 10BASE-T full duplex capability. */
425 #define PHYANAD_10_HDX 0x0020 /*!< \ref NIC_PHYANAD bit mask, indicates 10BASE-T half duplex capability. */
426 #define PHYANAD_CSMA 0x0001 /*!< \ref NIC_PHYANAD bit mask, indicates 802.3 CSMA capability. */
427 
428 /*!
429  * \brief PHY auto-negotiation remote end capability register.
430  */
431 #define NIC_PHYANRC 5
432 
433 /*!
434  * \brief PHY configuration register 1.
435  */
436 #define NIC_PHYCFR1 16
437 
438 /*!
439  * \brief PHY configuration register 2.
440  */
441 #define NIC_PHYCFR2 17
442 
443 /*!
444  * \brief PHY status output register.
445  */
446 #define NIC_PHYSOR 18
447 
448 #define PHYSOR_INT 0x8000 /*!< \ref NIC_PHYSOR bit mask, interrupt bits changed. */
449 #define PHYSOR_LNKFAIL 0x4000 /*!< \ref NIC_PHYSOR bit mask, link failure detected. */
450 #define PHYSOR_LOSSSYNC 0x2000 /*!< \ref NIC_PHYSOR bit mask, descrambler sync lost detected. */
451 #define PHYSOR_CWRD 0x1000 /*!< \ref NIC_PHYSOR bit mask, code word error detected. */
452 #define PHYSOR_SSD 0x0800 /*!< \ref NIC_PHYSOR bit mask, start of stream error detected. */
453 #define PHYSOR_ESD 0x0400 /*!< \ref NIC_PHYSOR bit mask, end of stream error detected. */
454 #define PHYSOR_RPOL 0x0200 /*!< \ref NIC_PHYSOR bit mask, reverse polarity detected. */
455 #define PHYSOR_JAB 0x0100 /*!< \ref NIC_PHYSOR bit mask, jabber detected. */
456 #define PHYSOR_SPDDET 0x0080 /*!< \ref NIC_PHYSOR bit mask, 100/10 speed detected. */
457 #define PHYSOR_DPLXDET 0x0040 /*!< \ref NIC_PHYSOR bit mask, duplex detected. */
458 
459 /*!
460  * \brief PHY mask register.
461  */
462 #define NIC_PHYMSK 19
463 
464 #define PHYMSK_MINT 0x8000 /*!< \ref NIC_PHYMSK bit mask, enables \ref PHYSOR_INT interrupt. */
465 #define PHYMSK_MLNKFAIL 0x4000 /*!< \ref NIC_PHYMSK bit mask, enables \ref PHYSOR_LNKFAIL interrupt. */
466 #define PHYMSK_MLOSSSYN 0x2000 /*!< \ref NIC_PHYMSK bit mask, enables \ref PHYSOR_LOSSSYNC interrupt. */
467 #define PHYMSK_MCWRD 0x1000 /*!< \ref NIC_PHYMSK bit mask, enables \ref PHYSOR_CWRD interrupt. */
468 #define PHYMSK_MSSD 0x0800 /*!< \ref NIC_PHYMSK bit mask, enables \ref PHYSOR_SSD interrupt. */
469 #define PHYMSK_MESD 0x0400 /*!< \ref NIC_PHYMSK bit mask, enables \ref PHYSOR_ESD interrupt. */
470 #define PHYMSK_MRPOL 0x0200 /*!< \ref NIC_PHYMSK bit mask, enables \ref PHYSOR_RPOL interrupt. */
471 #define PHYMSK_MJAB 0x0100 /*!< \ref NIC_PHYMSK bit mask, enables \ref PHYSOR_JAB interrupt. */
472 #define PHYMSK_MSPDDT 0x0080 /*!< \ref NIC_PHYMSK bit mask, enables \ref PHYSOR_SPDDET interrupt. */
473 #define PHYMSK_MDPLDT 0x0040 /*!< \ref NIC_PHYMSK bit mask, enables \ref PHYSOR_DPLXDET interrupt. */
474 
475 
476 
477 #define MSBV(bit) (1 << ((bit) - 8))
478 
479 #define nic_outlb(addr, val) (*(volatile u8_t *)(addr) = (val))
480 #define nic_outhb(addr, val) (*(volatile u8_t *)((addr) + 1) = (val))
481 #define nic_outwx(addr, val) (*(volatile u16_t *)(addr) = (val))
482 #define nic_outw(addr, val) { \
483  *(volatile u8_t *)(addr) = (u8_t)(val); \
484  *((volatile u8_t *)(addr) + 1) = (u8_t)((val) >> 8); \
485 }
486 
487 #define nic_inlb(addr) (*(volatile u8_t *)(addr))
488 #define nic_inhb(addr) (*(volatile u8_t *)((addr) + 1))
489 #define nic_inw(addr) (*(volatile u16_t *)(addr))
490 
491 #define nic_bs(bank) nic_outlb(NIC_BSR, bank)
492 
493 /*!
494  * \struct _NICINFO lanc111.h dev/lanc111.h
495  * \brief Network interface controller information structure.
496  */
497 /*@}*/
498 
499 /*!
500  * \addtogroup xgNicLanc111
501  */
502 /*@{*/
503 
504 
505 
506 /*!
507  * \brief Select specified PHY register for reading or writing.
508  *
509  * \note NIC interrupts must have been disabled before calling this routine.
510  *
511  * \param reg PHY register number.
512  * \param we Indicates type of access, 1 for write and 0 for read.
513  *
514  * \return Contents of the PHY interface rgister.
515  */
516 static u8_t NicPhyRegSelect(u8_t reg, u8_t we)
517 {
518  u8_t rs;
519  u8_t msk;
520  u8_t i;
521 
522  nic_bs(3);
523  rs = (nic_inlb(NIC_MGMT) & ~(MGMT_MCLK | MGMT_MDO)) | MGMT_MDOE;
524 
525  /* Send idle pattern. */
526  for (i = 0; i < 33; i++) {
527  nic_outlb(NIC_MGMT, rs | MGMT_MDO);
528  nic_outlb(NIC_MGMT, rs | MGMT_MDO | MGMT_MCLK);
529  }
530 
531  /* Send start sequence. */
532  nic_outlb(NIC_MGMT, rs);
533  nic_outlb(NIC_MGMT, rs | MGMT_MCLK);
534  nic_outlb(NIC_MGMT, rs | MGMT_MDO);
535  nic_outlb(NIC_MGMT, rs | MGMT_MDO | MGMT_MCLK);
536 
537  /* Write or read mode. */
538  if (we) {
539  nic_outlb(NIC_MGMT, rs);
540  nic_outlb(NIC_MGMT, rs | MGMT_MCLK);
541  nic_outlb(NIC_MGMT, rs | MGMT_MDO);
542  nic_outlb(NIC_MGMT, rs | MGMT_MDO | MGMT_MCLK);
543  } else {
544  nic_outlb(NIC_MGMT, rs | MGMT_MDO);
545  nic_outlb(NIC_MGMT, rs | MGMT_MDO | MGMT_MCLK);
546  nic_outlb(NIC_MGMT, rs);
547  nic_outlb(NIC_MGMT, rs | MGMT_MCLK);
548  }
549 
550  /* Send PHY address. Zero is used for the internal PHY. */
551  for (i = 0; i < 5; i++) {
552  nic_outlb(NIC_MGMT, rs);
553  nic_outlb(NIC_MGMT, rs | MGMT_MCLK);
554  }
555 
556  /* Send PHY register number. */
557  for (msk = 0x10; msk; msk >>= 1) {
558  if (reg & msk) {
559  nic_outlb(NIC_MGMT, rs | MGMT_MDO);
560  nic_outlb(NIC_MGMT, rs | MGMT_MDO | MGMT_MCLK);
561  } else {
562  nic_outlb(NIC_MGMT, rs);
563  nic_outlb(NIC_MGMT, rs | MGMT_MCLK);
564  }
565  }
566  nic_outlb(NIC_MGMT, rs);
567 
568  return rs;
569 }
570 
571 /*!
572  * \brief Read contents of PHY register.
573  *
574  * \note NIC interrupts must have been disabled before calling this routine.
575  *
576  * \param reg PHY register number.
577  *
578  * \return Contents of the specified register.
579  */
580 static u16_t NicPhyRead(u8_t reg)
581 {
582  u16_t rc = 0;
583  u8_t rs;
584  u8_t i;
585 
586  /* Select register for reading. */
587  rs = NicPhyRegSelect(reg, 0);
588 
589  /* Switch data direction. */
590  rs &= ~MGMT_MDOE;
591  nic_outlb(NIC_MGMT, rs);
592  nic_outlb(NIC_MGMT, rs | MGMT_MCLK);
593 
594  /* Clock data in. */
595  for (i = 0; i < 16; i++) {
596  nic_outlb(NIC_MGMT, rs);
597  nic_outlb(NIC_MGMT, rs | MGMT_MCLK);
598  rc <<= 1;
599  rc |= (nic_inlb(NIC_MGMT) & MGMT_MDI) != 0;
600  }
601 
602  /* This will set the clock line to low. */
603  nic_outlb(NIC_MGMT, rs);
604 
605  return rc;
606 }
607 
608 /*!
609  * \brief Write value to PHY register.
610  *
611  * \note NIC interrupts must have been disabled before calling this routine.
612  *
613  * \param reg PHY register number.
614  * \param val Value to write.
615  */
616 static void NicPhyWrite(u8_t reg, u16_t val)
617 {
618  u16_t msk;
619  u8_t rs;
620 
621  /* Select register for writing. */
622  rs = NicPhyRegSelect(reg, 1);
623 
624  /* Switch data direction dummy. */
625  nic_outlb(NIC_MGMT, rs | MGMT_MDO);
626  nic_outlb(NIC_MGMT, rs | MGMT_MDO | MGMT_MCLK);
627  nic_outlb(NIC_MGMT, rs);
628  nic_outlb(NIC_MGMT, rs | MGMT_MCLK);
629 
630  /* Clock data out. */
631  for (msk = 0x8000; msk; msk >>= 1) {
632  if (val & msk) {
633  nic_outlb(NIC_MGMT, rs | MGMT_MDO);
634  nic_outlb(NIC_MGMT, rs | MGMT_MDO | MGMT_MCLK);
635  } else {
636  nic_outlb(NIC_MGMT, rs);
637  nic_outlb(NIC_MGMT, rs | MGMT_MCLK);
638  }
639  }
640 
641  /* Set clock line low and output line int z-state. */
642  nic_outlb(NIC_MGMT, rs & ~MGMT_MDOE);
643 }
644 
645 /*!
646  * \brief Configure the internal PHY.
647  *
648  * Reset the PHY and initiate auto-negotiation.
649  */
650 static int NicPhyConfig(void)
651 {
652  u16_t phy_sor;
653  u16_t phy_sr;
654  u16_t phy_to;
655  u16_t mode;
656 
657  /*
658  * Reset the PHY and wait until this self clearing bit
659  * becomes zero. We sleep 63 ms before each poll and
660  * give up after 3 retries.
661  */
662  //printf("Reset PHY..");
663  NicPhyWrite(NIC_PHYCR, PHYCR_RST);
664  for (phy_to = 0;; phy_to++) {
665  NutSleep(63);
666  if ((NicPhyRead(NIC_PHYCR) & PHYCR_RST) == 0)
667  break;
668  if (phy_to > 3)
669  return -1;
670  }
671  //printf("OK\n");
672 
673  /* Store PHY status output. */
674  phy_sor = NicPhyRead(NIC_PHYSOR);
675 
676  /* Enable PHY interrupts. */
679 
680  /* Set RPC register. */
682  nic_bs(0);
683  nic_outw(NIC_RPCR, mode);
684 
685 #ifdef NIC_FIXED
686  /* Disable link. */
687  phy_sr = NicPhyRead(NIC_PHYCFR1);
688  NicPhyWrite(NIC_PHYCFR1, phy_sr | 0x8000);
689  NutSleep(63);
690 
691  /* Set fixed capabilities. */
692  NicPhyWrite(NIC_PHYCR, NIC_FIXED);
693  nic_bs(0);
694  nic_outw(NIC_RPCR, mode);
695 
696  /* Enable link. */
697  phy_sr = NicPhyRead(NIC_PHYCFR1);
698  NicPhyWrite(NIC_PHYCFR1, phy_sr & ~0x8000);
699  phy_sr = NicPhyRead(NIC_PHYCFR1);
700 
701 #else
702  /*
703  * Advertise our capabilities, initiate auto negotiation
704  * and wait until this has been completed.
705  */
706  //printf("Negotiate..");
708  NutSleep(63);
709  for (phy_to = 0, phy_sr = 0;; phy_to++) {
710  /* Give up after 10 seconds. */
711  if (phy_to >= 1024)
712  return -1;
713  /* Restart auto negotiation every 4 seconds or on failures. */
714  if ((phy_to & 127) == 0 /* || (phy_sr & PHYSR_REM_FLT) != 0 */ ) {
715  NicPhyWrite(NIC_PHYCR, PHYCR_ANEG_EN | PHYCR_ANEG_RST);
716  //printf("Restart..");
717  NutSleep(63);
718  }
719  /* Check if we are done. */
720  phy_sr = NicPhyRead(NIC_PHYSR);
721  //printf("[SR %04X]", phy_sr);
722  if (phy_sr & PHYSR_ANEG_ACK)
723  break;
724  NutSleep(63);
725  }
726  //printf("OK\n");
727 #endif
728 
729  return 0;
730 }
731 
732 /*!
733  * \brief Wait until MMU is ready.
734  *
735  * Poll the MMU command register until \ref MMUCR_BUSY
736  * is cleared.
737  *
738  * \param tmo Timeout in milliseconds.
739  *
740  * \return 0 on success or -1 on timeout.
741  */
742 static INLINE int NicMmuWait(u16_t tmo)
743 {
744  while (tmo--) {
745  if ((nic_inlb(NIC_MMUCR) & MMUCR_BUSY) == 0)
746  break;
747  NutDelay(1);
748  }
749  return tmo ? 0 : -1;
750 }
751 
752 /*!
753  * \brief Reset the Ethernet controller.
754  *
755  * \return 0 on success, -1 otherwise.
756  */
757 static int NicReset(void)
758 {
759 #ifdef LANC111_RESET_BIT
760  sbi(LANC111_RESET_DDR, LANC111_RESET_BIT);
761  sbi(LANC111_RESET_PORT, LANC111_RESET_BIT);
762  NutDelay(WAIT100);
763  cbi(LANC111_RESET_PORT, LANC111_RESET_BIT);
764  NutDelay(WAIT250);
765  NutDelay(WAIT250);
766 #endif
767 
768  /* Disable all interrupts. */
769  nic_outlb(NIC_MSK, 0);
770 
771  /* MAC and PHY software reset. */
772  nic_bs(0);
773  nic_outw(NIC_RCR, RCR_SOFT_RST);
774 
775  /* Enable Ethernet protocol handler. */
776  nic_bs(1);
777  nic_outw(NIC_CR, CR_EPH_EN);
778 
779  NutDelay(10);
780 
781  /* Disable transmit and receive. */
782  nic_bs(0);
783  nic_outw(NIC_RCR, 0);
784  nic_outw(NIC_TCR, 0);
785 
786  /* Enable auto release. */
787  nic_bs(1);
788  nic_outw(NIC_CTR, CTR_AUTO_RELEASE);
789 
790  /* Reset MMU. */
791  nic_bs(2);
792  nic_outlb(NIC_MMUCR, MMU_RST);
793  if (NicMmuWait(1000))
794  return -1;
795 
796  return 0;
797 }
798 
799 /*
800  * Fires up the network interface. NIC interrupts
801  * should have been disabled when calling this
802  * function.
803  *
804  * \param mac Six byte unique MAC address.
805  */
806 static int NicStart(CONST u8_t * mac)
807 {
808  u8_t i;
809 
810  if (NicReset())
811  return -1;
812 
813  /* Enable receiver. */
814  nic_bs(3);
815  nic_outlb(NIC_ERCV, 7);
816  nic_bs(0);
817  nic_outw(NIC_RCR, RCR_RXEN);
818 
819  /* Enable transmitter and padding. */
820  nic_outw(NIC_TCR, TCR_PAD_EN | TCR_TXENA);
821 
822  /* Configure the PHY. */
823  if (NicPhyConfig())
824  return -1;
825 
826  /* Set MAC address. */
827  //printf("Set MAC %02X%02X%02X%02X%02X%02X", mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]);
828  nic_bs(1);
829  for (i = 0; i < 6; i++)
830  nic_outlb(NIC_IAR + i, mac[i]);
831  //printf("OK\n");
832 
833  /* Enable interrupts. */
834  nic_bs(2);
835  nic_outlb(NIC_MSK, INT_ERCV | INT_RCV | INT_RX_OVRN);
836 
837  return 0;
838 }
839 
840 /*
841  * NIC interrupt entry.
842  */
843 #if 0
844 static void NicInterrupt(void *arg)
845 {
846  u8_t isr;
847  u8_t imr;
848  NICINFO *ni = (NICINFO *) ((NUTDEVICE *) arg)->dev_dcb;
849 
850  ni->ni_interrupts++;
851 
852  /* Read the interrupt mask and disable all interrupts. */
853  nic_bs(2);
854  imr = nic_inlb(NIC_MSK);
855  nic_outlb(NIC_MSK, 0);
856 
857  /* Read the interrupt status and acknowledge all interrupts. */
858  isr = nic_inlb(NIC_IST);
859  //printf("\n!%02X-%02X ", isr, imr);
860  isr &= imr;
861 
862  /*
863  * If this is a transmit interrupt, then a packet has been sent.
864  * So we can clear the transmitter busy flag and wake up the
865  * transmitter thread.
866  */
867  if (isr & INT_TX_EMPTY) {
868  nic_outlb(NIC_ACK, INT_TX_EMPTY);
869  imr &= ~INT_TX_EMPTY;
870  NutEventPostFromIrq(&ni->ni_tx_rdy);
871  }
872  /* Transmit error. */
873  else if (isr & INT_TX) {
874  /* re-enable transmit */
875  nic_bs(0);
876  nic_outw(NIC_TCR, nic_inlb(NIC_TCR) | TCR_TXENA);
877  nic_bs(2);
878  nic_outlb(NIC_ACK, INT_TX);
879  /* kill the packet */
880  nic_outlb(NIC_MMUCR, MMU_PKT);
881 
882  NutEventPostFromIrq(&ni->ni_tx_rdy);
883  }
884 
885 
886  /*
887  * If this is a receive interrupt, then wake up the receiver
888  * thread.
889  */
890  if (isr & INT_RX_OVRN) {
891  nic_outlb(NIC_ACK, INT_RX_OVRN);
892  //nic_outlb(NIC_MMUCR, MMU_TOP);
893  }
894  if (isr & INT_ERCV) {
895  nic_outlb(NIC_ACK, INT_ERCV);
896  NutEventPostFromIrq(&ni->ni_rx_rdy);
897  }
898  if (isr & INT_RCV) {
899  nic_outlb(NIC_ACK, INT_RCV);
900  imr &= ~INT_RCV;
901  NutEventPostFromIrq(&ni->ni_rx_rdy);
902  }
903 
904  if (isr & INT_ALLOC) {
905  imr &= ~INT_ALLOC;
906  NutEventPostFromIrq(&maq);
907  }
908  //printf(" -%02X-%02X- ", nic_inlb(NIC_IST), inb(PINE) & 0x20);
909  nic_outlb(NIC_MSK, imr);
910 }
911 #endif /* 0 */
912 /*
913  * Write data block to the NIC.
914  */
915 static void NicWrite(u8_t * buf, u16_t len)
916 {
917  register u16_t l = len - 1;
918  register u8_t ih = (u16_t) l >> 8;
919  register u8_t il = (u8_t) l;
920 
921  if (!len)
922  return;
923 
924  do {
925  do {
926  nic_outlb(NIC_DATA, *buf++);
927  } while (il-- != 0);
928  } while (ih-- != 0);
929 }
930 
931 /*
932  * Read data block from the NIC.
933  */
934 static void NicRead(u8_t * buf, u16_t len)
935 {
936  register u16_t l = len - 1;
937  register u8_t ih = (u16_t) l >> 8;
938  register u8_t il = (u8_t) l;
939 
940  if (!len)
941  return;
942 
943  do {
944  do {
945  *buf++ = nic_inlb(NIC_DATA);
946  } while (il-- != 0);
947  } while (ih-- != 0);
948 }
949 
950 /*!
951  * \brief Fetch the next packet out of the receive ring buffer.
952  *
953  * Nic interrupts must be disabled when calling this funtion.
954  *
955  * \return Pointer to an allocated ::NETBUF. If there is no
956  * no data available, then the function returns a
957  * null pointer. If the NIC's buffer seems to be
958  * corrupted, a pointer to 0xFFFF is returned.
959  */
960 static NETBUF *NicGetPacket(void)
961 {
962  NETBUF *nb = 0;
963  //u8_t *buf;
964  u16_t fsw;
965  u16_t fbc;
966 
967  /* Check the fifo empty bit. If it is set, then there is
968  nothing in the receiver fifo. */
969  nic_bs(2);
970  if (nic_inw(NIC_FIFO) & 0x8000) {
971  return 0;
972  }
973 
974  /* Inialize pointer register. */
975  nic_outw(NIC_PTR, PTR_READ | PTR_RCV | PTR_AUTO_INCR);
976  _NOP();
977  _NOP();
978  _NOP();
979  _NOP();
980 
981  /* Read status word and byte count. */
982  fsw = nic_inw(NIC_DATA);
983  fbc = nic_inw(NIC_DATA);
984  //printf("[SW=%04X,BC=%04X]", fsw, fbc);
985 
986  /* Check for frame errors. */
987  if (fsw & 0xAC00) {
988  nb = (NETBUF *) 0xFFFF;
989  }
990  /* Check the byte count. */
991  else if (fbc < 66 || fbc > 1524) {
992  nb = (NETBUF *) 0xFFFF;
993  }
994 
995  else {
996  /*
997  * Allocate a NETBUF.
998  * Hack alert: Rev A chips never set the odd frame indicator.
999  */
1000  fbc -= 3;
1001  /* nb = NutNetBufAlloc(0, NBAF_DATALINK, fbc);*/
1002 
1003  /* Perform the read. */
1004 /* if (nb)
1005  NicRead(nb->nb_dl.vp, fbc);*/
1006  }
1007 
1008  /* Release the packet. */
1009  nic_outlb(NIC_MMUCR, MMU_TOP);
1010 
1011  return nb;
1012 }
1013 
1014 /*!
1015  * \brief Load a packet into the nic's transmit ring buffer.
1016  *
1017  * Interupts must have been disabled when calling this function.
1018  *
1019  * \param nb Network buffer structure containing the packet to be sent.
1020  * The structure must have been allocated by a previous
1021  * call NutNetBufAlloc(). This routine will automatically
1022  * release the buffer in case of an error.
1023  *
1024  * \return 0 on success, -1 in case of any errors. Errors
1025  * will automatically release the network buffer
1026  * structure.
1027  */
1028 #if 0
1029 static int NicPutPacket(NETBUF * nb)
1030 {
1031  u16_t sz;
1032  u8_t odd = 0;
1033  u8_t imsk;
1034 
1035  //printf("[P]");
1036  /*
1037  * Calculate the number of bytes to be send. Do not send packets
1038  * larger than the Ethernet maximum transfer unit. The MTU
1039  * consist of 1500 data bytes plus the 14 byte Ethernet header
1040  * plus 4 bytes CRC. We check the data bytes only.
1041  */
1042  if ((sz = nb->nb_nw.sz + nb->nb_tp.sz + nb->nb_ap.sz) > ETHERMTU)
1043  return -1;
1044 
1045  /* Disable all interrupts. */
1046  imsk = nic_inlb(NIC_MSK);
1047  nic_outlb(NIC_MSK, 0);
1048 
1049  /* Allocate packet buffer space. */
1050  nic_bs(2);
1051  nic_outlb(NIC_MMUCR, MMU_ALO);
1052  if (NicMmuWait(100))
1053  return -1;
1054 
1055  /* Enable interrupts including allocation success. */
1056  nic_outlb(NIC_MSK, imsk | INT_ALLOC);
1057 
1058  /* The MMU needs some time. Use it to calculate the byte count. */
1059  sz += nb->nb_dl.sz;
1060  sz += 6;
1061  if (sz & 1) {
1062  sz++;
1063  odd++;
1064  }
1065 
1066  /* Wait for allocation success. */
1067  while ((nic_inlb(NIC_IST) & INT_ALLOC) == 0) {
1068  if (NutEventWait(&maq, 125)) {
1069  nic_outlb(NIC_MMUCR, MMU_RST);
1070  NicMmuWait(1000);
1071  nic_outlb(NIC_MMUCR, MMU_ALO);
1072  if (NicMmuWait(100) || (nic_inlb(NIC_IST) & INT_ALLOC) == 0) {
1073  if (NutEventWait(&maq, 125)) {
1074  return -1;
1075  }
1076  }
1077  }
1078  }
1079 
1080  /* Disable interrupts. */
1081  imsk = nic_inlb(NIC_MSK);
1082  nic_outlb(NIC_MSK, 0);
1083 
1084 
1085  nic_outlb(NIC_PNR, nic_inhb(NIC_PNR));
1086 
1087  nic_outw(NIC_PTR, 0x4000);
1088 
1089  /* Transfer control word. */
1090  nic_outlb(NIC_DATA, 0);
1091  nic_outlb(NIC_DATA, 0);
1092 
1093  /* Transfer the byte count. */
1094  nic_outw(NIC_DATA, sz);
1095 
1096  /* Transfer the Ethernet frame. */
1097  NicWrite(nb->nb_dl.vp, nb->nb_dl.sz);
1098  NicWrite(nb->nb_nw.vp, nb->nb_nw.sz);
1099  NicWrite(nb->nb_tp.vp, nb->nb_tp.sz);
1100  NicWrite(nb->nb_ap.vp, nb->nb_ap.sz);
1101 
1102  if (odd)
1103  nic_outlb(NIC_DATA, 0);
1104 
1105  /* Transfer the control word. */
1106  nic_outw(NIC_DATA, 0);
1107 
1108  /* Enqueue packet. */
1109  if (NicMmuWait(100))
1110  return -1;
1111  nic_outlb(NIC_MMUCR, MMU_ENQ);
1112 
1113  /* Enable interrupts. */
1114  imsk |= INT_TX | INT_TX_EMPTY;
1115  nic_outlb(NIC_MSK, imsk);
1116 
1117  return 0;
1118 }
1119 #endif
1120 
1121 /*! \fn NicRxLanc(void *arg)
1122  * \brief NIC receiver thread.
1123  *
1124  */
1125 #if 1
1126 PROCESS_THREAD(lanc111_process, ev, data)
1127  /*THREAD(NicRxLanc, arg)*/
1128 {
1129  /* NUTDEVICE *dev;
1130  IFNET *ifn;
1131  NICINFO *ni;
1132  NETBUF *nb;*/
1133  u8_t imsk;
1134  static struct etimer et;
1135 
1136  /* dev = arg;
1137  ifn = (IFNET *) dev->dev_icb;
1138  ni = (NICINFO *) dev->dev_dcb;*/
1139 
1140  /*
1141  * This is a temporary hack. Due to a change in initialization,
1142  * we may not have got a MAC address yet. Wait until one has been
1143  * set.
1144  */
1145 
1146  PROCESS_BEGIN();
1147 
1148  /* while(*((u_long *) (ifn->if_mac)) &&
1149  *((u_long *) (ifn->if_mac)) != 0xFFFFFFFFUL) {*/
1150  while(0) {
1151  etimer_set(&et, CLOCK_SECOND / 8);
1153  }
1154 
1155  /*
1156  * Do not continue unless we managed to start the NIC. We are
1157  * trapped here if the Ethernet link cannot be established.
1158  * This happens, for example, if no Ethernet cable is plugged
1159  * in.
1160  */
1161  /* while(NicStart(ifn->if_mac)) {*/
1162  while(0) {
1163  /*NutSleep(1000);*/
1164  etimer_set(&et, CLOCK_SECOND);
1166  }
1167 
1168  LANC111_SIGNAL_MODE();
1169  sbi(EIMSK, LANC111_SIGNAL_IRQ);
1170 
1171  /* NutEventPost(&mutex);*/
1172 
1173  /* Run at high priority. */
1174  /* NutThreadSetPriority(9);*/
1175 
1176  for (;;) {
1177 
1178  /*
1179  * Wait for the arrival of new packets or
1180  * check the receiver every two second.
1181  */
1182  /* NutEventWait(&ni->ni_rx_rdy, 2000);*/
1184 
1185  /*
1186  * Fetch all packets from the NIC's internal
1187  * buffer and pass them to the registered handler.
1188  */
1189  imsk = nic_inlb(NIC_MSK);
1190  nic_outlb(NIC_MSK, 0);
1191  /* while ((nb = NicGetPacket()) != 0) {
1192  if (nb != (NETBUF *) 0xFFFF) {
1193  ni->ni_rx_packets++;
1194  (*ifn->if_recv) (dev, nb);
1195  }
1196  }*/
1197  nic_outlb(NIC_MSK, imsk | INT_RCV | INT_ERCV);
1198  }
1199 
1200  PROCESS_END();
1201 }
1202 #endif /* 0 */
1203 /*!
1204  * \brief Send Ethernet packet.
1205  *
1206  * \param dev Identifies the device to use.
1207  * \param nb Network buffer structure containing the packet to be sent.
1208  * The structure must have been allocated by a previous
1209  * call NutNetBufAlloc().
1210  *
1211  * \return 0 on success, -1 in case of any errors.
1212  */
1213 #if 0
1214 int LancOutput(NUTDEVICE * dev, NETBUF * nb)
1215 {
1216  static u_long mx_wait = 5000;
1217  int rc = -1;
1218  NICINFO *ni;
1219 
1220  /*
1221  * After initialization we are waiting for a long time to give
1222  * the PHY a chance to establish an Ethernet link.
1223  */
1224  if (NutEventWait(&mutex, mx_wait) == 0) {
1225  ni = (NICINFO *) dev->dev_dcb;
1226 
1227  if (NicPutPacket(nb) == 0) {
1228  ni->ni_tx_packets++;
1229  rc = 0;
1230  /* Ethernet works. Set a long waiting time in case we
1231  temporarly lose the link next time. */
1232  mx_wait = 5000;
1233  }
1234  NutEventPost(&mutex);
1235  }
1236  /*
1237  * Probably no Ethernet link. Significantly reduce the waiting
1238  * time, so following transmission will soon return an error.
1239  */
1240  else {
1241  mx_wait = 500;
1242  }
1243  return rc;
1244 }
1245 #endif
1246 #if 0
1247 /*!
1248  * \brief Initialize Ethernet hardware.
1249  *
1250  * Resets the LAN91C111 Ethernet controller, initializes all required
1251  * hardware registers and starts a background thread for incoming
1252  * Ethernet traffic.
1253  *
1254  * Applications should do not directly call this function. It is
1255  * automatically executed during during device registration by
1256  * NutRegisterDevice().
1257  *
1258  * If the network configuration hasn't been set by the application
1259  * before registering the specified device, this function will
1260  * call NutNetLoadConfig() to get the MAC address.
1261  *
1262  * \param dev Identifies the device to initialize.
1263  */
1264 int LancInit(NUTDEVICE * dev)
1265 {
1266  /* Disable NIC interrupt and clear NICINFO structure. */
1267  cbi(EIMSK, LANC111_SIGNAL_IRQ);
1268  memset(dev->dev_dcb, 0, sizeof(NICINFO));
1269 
1270  /* Register interrupt handler and enable interrupts. */
1271  if (NutRegisterIrqHandler(&LANC111_SIGNAL, NicInterrupt, dev))
1272  return -1;
1273 
1274  /*
1275  * Start the receiver thread.
1276  */
1277  NutThreadCreate("rxi5", NicRxLanc, dev, 640);
1278 
1279  //NutSleep(500);
1280 
1281  return 0;
1282 }
1283 
1284 /*@}*/
1285 
1286 /*!
1287  * \addtogroup xgSmscDev
1288  */
1289 /*@{*/
1290 
1291 static NICINFO dcb_eth0;
1292 
1293 /*!
1294  * \brief Network interface information structure.
1295  *
1296  * Used to call.
1297  */
1298 static IFNET ifn_eth0 = {
1299  IFT_ETHER, /*!< \brief Interface type. */
1300  {0, 0, 0, 0, 0, 0}, /*!< \brief Hardware net address. */
1301  0, /*!< \brief IP address. */
1302  0, /*!< \brief Remote IP address for point to point. */
1303  0, /*!< \brief IP network mask. */
1304  ETHERMTU, /*!< \brief Maximum size of a transmission unit. */
1305  0, /*!< \brief Packet identifier. */
1306  0, /*!< \brief Linked list of arp entries. */
1307  NutEtherInput, /*!< \brief Routine to pass received data to, if_recv(). */
1308  LancOutput, /*!< \brief Driver output routine, if_send(). */
1309  NutEtherOutput /*!< \brief Media output routine, if_output(). */
1310 };
1311 
1312 /*!
1313  * \brief Device information structure.
1314  *
1315  * A pointer to this structure must be passed to NutRegisterDevice()
1316  * to bind this Ethernet device driver to the Nut/OS kernel.
1317  * An application may then call NutNetIfConfig() with the name \em eth0
1318  * of this driver to initialize the network interface.
1319  *
1320  */
1321 NUTDEVICE devSmsc111 = {
1322  0, /* Pointer to next device. */
1323  {'e', 't', 'h', '0', 0, 0, 0, 0, 0}, /* Unique device name. */
1324  IFTYP_NET, /* Type of device. */
1325  0, /* Base address. */
1326  0, /* First interrupt number. */
1327  &ifn_eth0, /* Interface control block. */
1328  &dcb_eth0, /* Driver control block. */
1329  LancInit, /* Driver initialization routine. */
1330  0, /* Driver specific control function. */
1331  0, /* Read from device. */
1332  0, /* Write to device. */
1333  0, /* Write from program space data to device. */
1334  0, /* Open a device or file. */
1335  0, /* Close a device or file. */
1336  0 /* Request file size. */
1337 };
1338 
1339 /*@}*/
1340 #endif
1341 
1342 
1343 int
1345 {
1346  /* Disable NIC interrupt and clear NICINFO structure. */
1347  cbi(EIMSK, LANC111_SIGNAL_IRQ);
1348 
1349  /* Register interrupt handler and enable interrupts. */
1350  /* if (NutRegisterIrqHandler(&LANC111_SIGNAL, NicInterrupt, dev))
1351  return -1;*/
1352 
1353  /*
1354  * Start the receiver thread.
1355  */
1356  /* NutThreadCreate("rxi5", NicRxLanc, dev, 640);*/
1357 
1358  //NutSleep(500);
1359 
1360  return 0;
1361 }
1362