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