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 SMSC Registers
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 /*!
275  * \brief MMU command register busy flag.
276  */
277 #define MMUCR_BUSY 0x0001
278 
279 #define MMU_NOP 0
280 #define MMU_ALO (1<<5)
281 #define MMU_RST (2<<5)
282 #define MMU_REM (3<<5)
283 #define MMU_TOP (4<<5)
284 #define MMU_PKT (5<<5)
285 #define MMU_ENQ (6<<5)
286 #define MMU_RTX (7<<5)
287 
288 /*!
289  * \brief Bank 2 - Packet number register.
290  *
291  * This byte register specifies the accessible transmit packet number.
292  */
293 #define NIC_PNR (LANC111_BASE_ADDR + 0x02)
294 
295 /*!
296  * \brief Bank 2 - Allocation result register.
297  *
298  * This byte register is updated upon a MMU_ALO command.
299  */
300 #define NIC_ARR (LANC111_BASE_ADDR + 0x03)
301 
302 #define ARR_FAILED 0x80
303 
304 /*!
305  * \brief Bank 2 - FIFO ports register.
306  */
307 #define NIC_FIFO (LANC111_BASE_ADDR + 0x04)
308 
309 /*!
310  * \brief Bank 2 - Pointer register.
311  */
312 #define NIC_PTR (LANC111_BASE_ADDR + 0x06)
313 
314 #define PTR_RCV 0x8000 /*! \ref NIC_PTR bit mask, specifies receive or transmit buffer. */
315 #define PTR_AUTO_INCR 0x4000 /*! \ref NIC_PTR bit mask, enables automatic pointer increment. */
316 #define PTR_READ 0x2000 /*! \ref NIC_PTR bit mask, indicates type of access. */
317 #define PTR_ETEN 0x1000 /*! \ref NIC_PTR bit mask, enables early transmit underrun detection. */
318 #define PTR_NOT_EMPTY 0x0800 /*! \ref NIC_PTR bit mask, set when write data fifo is not empty. */
319 
320 /*!
321  * \brief Bank 2 - Data register.
322  */
323 #define NIC_DATA (LANC111_BASE_ADDR + 0x08)
324 
325 /*!
326  * \brief Bank 2 - Interrupt status register.
327  */
328 #define NIC_IST (LANC111_BASE_ADDR + 0x0C)
329 
330 /*!
331  * \brief Bank 2 - Interrupt acknowledge register.
332  */
333 #define NIC_ACK (LANC111_BASE_ADDR + 0x0C)
334 
335 /*!
336  * \brief Bank 2 - Interrupt mask register.
337  */
338 #define NIC_MSK (LANC111_BASE_ADDR + 0x0D)
339 
340 #define INT_MD 0x80 /*!< PHY state change interrupt bit mask. */
341 #define INT_ERCV 0x40 /*!< Early receive interrupt bit mask. */
342 #define INT_EPH 0x20 /*!< Ethernet protocol interrupt bit mask. */
343 #define INT_RX_OVRN 0x10 /*!< Receive overrun interrupt bit mask. */
344 #define INT_ALLOC 0x08 /*!< Transmit allocation interrupt bit mask. */
345 #define INT_TX_EMPTY 0x04 /*!< Transmitter empty interrupt bit mask. */
346 #define INT_TX 0x02 /*!< Transmit complete interrupt bit mask. */
347 #define INT_RCV 0x01 /*!< Receive interrupt bit mask. */
348 
349 /*!
350  * \brief Bank 3 - Multicast table register.
351  */
352 #define NIC_MT (LANC111_BASE_ADDR + 0x00)
353 
354 /*!
355  * \brief Bank 3 - Management interface register.
356  */
357 #define NIC_MGMT (LANC111_BASE_ADDR + 0x08)
358 
359 #define MGMT_MDOE 0x08 /*!< \ref NIC_MGMT bit mask, enables MDO pin. */
360 #define MGMT_MCLK 0x04 /*!< \ref NIC_MGMT bit mask, drives MDCLK pin. */
361 #define MGMT_MDI 0x02 /*!< \ref NIC_MGMT bit mask, reflects MDI pin status. */
362 #define MGMT_MDO 0x01 /*!< \ref NIC_MGMT bit mask, drives MDO pin. */
363 
364 /*!
365  * \brief Bank 3 - Revision register.
366  */
367 #define NIC_REV (LANC111_BASE_ADDR + 0x0A)
368 
369 /*!
370  * \brief Bank 3 - Early RCV register.
371  */
372 #define NIC_ERCV (LANC111_BASE_ADDR + 0x0C)
373 
374 /*!
375  * \brief PHY control register.
376  */
377 #define NIC_PHYCR 0
378 
379 #define PHYCR_RST 0x8000 /*!< \ref NIC_PHYCR bit mask, resets PHY. */
380 #define PHYCR_LPBK 0x4000 /*!< \ref NIC_PHYCR bit mask, . */
381 #define PHYCR_SPEED 0x2000 /*!< \ref NIC_PHYCR bit mask, . */
382 #define PHYCR_ANEG_EN 0x1000 /*!< \ref NIC_PHYCR bit mask, . */
383 #define PHYCR_PDN 0x0800 /*!< \ref NIC_PHYCR bit mask, . */
384 #define PHYCR_MII_DIS 0x0400 /*!< \ref NIC_PHYCR bit mask, . */
385 #define PHYCR_ANEG_RST 0x0200 /*!< \ref NIC_PHYCR bit mask, . */
386 #define PHYCR_DPLX 0x0100 /*!< \ref NIC_PHYCR bit mask, . */
387 #define PHYCR_COLST 0x0080 /*!< \ref NIC_PHYCR bit mask, . */
388 
389 
390 /*!
391  * \brief PHY status register.
392  */
393 #define NIC_PHYSR 1
394 
395 #define PHYSR_CAP_T4 0x8000 /*!< \ref NIC_PHYSR bit mask, indicates 100BASE-T4 capability. */
396 #define PHYSR_CAP_TXF 0x4000 /*!< \ref NIC_PHYSR bit mask, indicates 100BASE-TX full duplex capability. */
397 #define PHYSR_CAP_TXH 0x2000 /*!< \ref NIC_PHYSR bit mask, indicates 100BASE-TX half duplex capability. */
398 #define PHYSR_CAP_TF 0x1000 /*!< \ref NIC_PHYSR bit mask, indicates 10BASE-T full duplex capability. */
399 #define PHYSR_CAP_TH 0x0800 /*!< \ref NIC_PHYSR bit mask, indicates 10BASE-T half duplex capability. */
400 #define PHYSR_CAP_SUPR 0x0040 /*!< \ref NIC_PHYSR bit mask, indicates preamble suppression capability. */
401 #define PHYSR_ANEG_ACK 0x0020 /*!< \ref NIC_PHYSR bit mask, auto-negotiation completed. */
402 #define PHYSR_REM_FLT 0x0010 /*!< \ref NIC_PHYSR bit mask, remote fault detected. */
403 #define PHYSR_CAP_ANEG 0x0008 /*!< \ref NIC_PHYSR bit mask, indicates auto-negotiation capability. */
404 #define PHYSR_LINK 0x0004 /*!< \ref NIC_PHYSR bit mask, valid link status. */
405 #define PHYSR_JAB 0x0002 /*!< \ref NIC_PHYSR bit mask, jabber collision detected. */
406 #define PHYSR_EXREG 0x0001 /*!< \ref NIC_PHYSR bit mask, extended capabilities available. */
407 
408 
409 /*!
410  * \brief PHY identifier register 1.
411  */
412 #define NIC_PHYID1 2
413 
414 /*!
415  * \brief PHY identifier register 1.
416  */
417 #define NIC_PHYID2 3
418 
419 /*!
420  * \brief PHY auto-negotiation advertisement register.
421  */
422 #define NIC_PHYANAD 4
423 
424 #define PHYANAD_NP 0x8000 /*!< \ref NIC_PHYANAD bit mask, exchanging next page information. */
425 #define PHYANAD_ACK 0x4000 /*!< \ref NIC_PHYANAD bit mask, acknowledged. */
426 #define PHYANAD_RF 0x2000 /*!< \ref NIC_PHYANAD bit mask, remote fault. */
427 #define PHYANAD_T4 0x0200 /*!< \ref NIC_PHYANAD bit mask, indicates 100BASE-T4 capability. */
428 #define PHYANAD_TX_FDX 0x0100 /*!< \ref NIC_PHYANAD bit mask, indicates 100BASE-TX full duplex capability. */
429 #define PHYANAD_TX_HDX 0x0080 /*!< \ref NIC_PHYANAD bit mask, indicates 100BASE-TX half duplex capability. */
430 #define PHYANAD_10FDX 0x0040 /*!< \ref NIC_PHYANAD bit mask, indicates 10BASE-T full duplex capability. */
431 #define PHYANAD_10_HDX 0x0020 /*!< \ref NIC_PHYANAD bit mask, indicates 10BASE-T half duplex capability. */
432 #define PHYANAD_CSMA 0x0001 /*!< \ref NIC_PHYANAD bit mask, indicates 802.3 CSMA capability. */
433 
434 /*!
435  * \brief PHY auto-negotiation remote end capability register.
436  */
437 #define NIC_PHYANRC 5
438 
439 /*!
440  * \brief PHY configuration register 1.
441  */
442 #define NIC_PHYCFR1 16
443 
444 /*!
445  * \brief PHY configuration register 2.
446  */
447 #define NIC_PHYCFR2 17
448 
449 /*!
450  * \brief PHY status output register.
451  */
452 #define NIC_PHYSOR 18
453 
454 #define PHYSOR_INT 0x8000 /*!< \ref NIC_PHYSOR bit mask, interrupt bits changed. */
455 #define PHYSOR_LNKFAIL 0x4000 /*!< \ref NIC_PHYSOR bit mask, link failure detected. */
456 #define PHYSOR_LOSSSYNC 0x2000 /*!< \ref NIC_PHYSOR bit mask, descrambler sync lost detected. */
457 #define PHYSOR_CWRD 0x1000 /*!< \ref NIC_PHYSOR bit mask, code word error detected. */
458 #define PHYSOR_SSD 0x0800 /*!< \ref NIC_PHYSOR bit mask, start of stream error detected. */
459 #define PHYSOR_ESD 0x0400 /*!< \ref NIC_PHYSOR bit mask, end of stream error detected. */
460 #define PHYSOR_RPOL 0x0200 /*!< \ref NIC_PHYSOR bit mask, reverse polarity detected. */
461 #define PHYSOR_JAB 0x0100 /*!< \ref NIC_PHYSOR bit mask, jabber detected. */
462 #define PHYSOR_SPDDET 0x0080 /*!< \ref NIC_PHYSOR bit mask, 100/10 speed detected. */
463 #define PHYSOR_DPLXDET 0x0040 /*!< \ref NIC_PHYSOR bit mask, duplex detected. */
464 
465 /*!
466  * \brief PHY mask register.
467  */
468 #define NIC_PHYMSK 19
469 
470 #define PHYMSK_MINT 0x8000 /*!< \ref NIC_PHYMSK bit mask, enables \ref PHYSOR_INT interrupt. */
471 #define PHYMSK_MLNKFAIL 0x4000 /*!< \ref NIC_PHYMSK bit mask, enables \ref PHYSOR_LNKFAIL interrupt. */
472 #define PHYMSK_MLOSSSYN 0x2000 /*!< \ref NIC_PHYMSK bit mask, enables \ref PHYSOR_LOSSSYNC interrupt. */
473 #define PHYMSK_MCWRD 0x1000 /*!< \ref NIC_PHYMSK bit mask, enables \ref PHYSOR_CWRD interrupt. */
474 #define PHYMSK_MSSD 0x0800 /*!< \ref NIC_PHYMSK bit mask, enables \ref PHYSOR_SSD interrupt. */
475 #define PHYMSK_MESD 0x0400 /*!< \ref NIC_PHYMSK bit mask, enables \ref PHYSOR_ESD interrupt. */
476 #define PHYMSK_MRPOL 0x0200 /*!< \ref NIC_PHYMSK bit mask, enables \ref PHYSOR_RPOL interrupt. */
477 #define PHYMSK_MJAB 0x0100 /*!< \ref NIC_PHYMSK bit mask, enables \ref PHYSOR_JAB interrupt. */
478 #define PHYMSK_MSPDDT 0x0080 /*!< \ref NIC_PHYMSK bit mask, enables \ref PHYSOR_SPDDET interrupt. */
479 #define PHYMSK_MDPLDT 0x0040 /*!< \ref NIC_PHYMSK bit mask, enables \ref PHYSOR_DPLXDET interrupt. */
480 
481 
482 
483 #define MSBV(bit) (1 << ((bit) - 8))
484 
485 #define nic_outlb(addr, val) (*(volatile uint8_t *)(addr) = (val))
486 #define nic_outhb(addr, val) (*(volatile uint8_t *)((addr) + 1) = (val))
487 #define nic_outwx(addr, val) (*(volatile uint16_t *)(addr) = (val))
488 #define nic_outw(addr, val) { \
489  *(volatile uint8_t *)(addr) = (uint8_t)(val); \
490  *((volatile uint8_t *)(addr) + 1) = (uint8_t)((val) >> 8); \
491 }
492 
493 #define nic_inlb(addr) (*(volatile uint8_t *)(addr))
494 #define nic_inhb(addr) (*(volatile uint8_t *)((addr) + 1))
495 #define nic_inw(addr) (*(volatile uint16_t *)(addr))
496 
497 #define nic_bs(bank) nic_outlb(NIC_BSR, bank)
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 uint8_t NicPhyRegSelect(uint8_t reg, uint8_t we)
517 {
518  uint8_t rs;
519  uint8_t msk;
520  uint8_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 uint16_t NicPhyRead(uint8_t reg)
581 {
582  uint16_t rc = 0;
583  uint8_t rs;
584  uint8_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(uint8_t reg, uint16_t val)
617 {
618  uint16_t msk;
619  uint8_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  uint16_t phy_sor;
653  uint16_t phy_sr;
654  uint16_t phy_to;
655  uint16_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..");
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 */ ) {
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(uint16_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 uint8_t * mac)
807 {
808  uint8_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 #if 0
841 /*
842  * NIC interrupt entry.
843  */
844 static void NicInterrupt(void *arg)
845 {
846  uint8_t isr;
847  uint8_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(uint8_t * buf, uint16_t len)
916 {
917  register uint16_t l = len - 1;
918  register uint8_t ih = (uint16_t) l >> 8;
919  register uint8_t il = (uint8_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(uint8_t * buf, uint16_t len)
935 {
936  register uint16_t l = len - 1;
937  register uint8_t ih = (uint16_t) l >> 8;
938  register uint8_t il = (uint8_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  //uint8_t *buf;
964  uint16_t fsw;
965  uint16_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 #if 0
1015 /*!
1016  * \brief Load a packet into the nic's transmit ring buffer.
1017  *
1018  * Interupts must have been disabled when calling this function.
1019  *
1020  * \param nb Network buffer structure containing the packet to be sent.
1021  * The structure must have been allocated by a previous
1022  * call NutNetBufAlloc(). This routine will automatically
1023  * release the buffer in case of an error.
1024  *
1025  * \return 0 on success, -1 in case of any errors. Errors
1026  * will automatically release the network buffer
1027  * structure.
1028  */
1029 static int NicPutPacket(NETBUF * nb)
1030 {
1031  uint16_t sz;
1032  uint8_t odd = 0;
1033  uint8_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 /* 0 */
1120 
1121 #if 1
1122 /*!
1123  * \brief NIC receiver thread.
1124  */
1125 PROCESS_THREAD(lanc111_process, ev, data)
1126  /*THREAD(NicRxLanc, arg)*/
1127 {
1128  /* NUTDEVICE *dev;
1129  IFNET *ifn;
1130  NICINFO *ni;
1131  NETBUF *nb;*/
1132  uint8_t imsk;
1133  static struct etimer et;
1134 
1135  /* dev = arg;
1136  ifn = (IFNET *) dev->dev_icb;
1137  ni = (NICINFO *) dev->dev_dcb;*/
1138 
1139  /*
1140  * This is a temporary hack. Due to a change in initialization,
1141  * we may not have got a MAC address yet. Wait until one has been
1142  * set.
1143  */
1144 
1145  PROCESS_BEGIN();
1146 
1147  /* while(*((u_long *) (ifn->if_mac)) &&
1148  *((u_long *) (ifn->if_mac)) != 0xFFFFFFFFUL) {*/
1149  while(0) {
1150  etimer_set(&et, CLOCK_SECOND / 8);
1152  }
1153 
1154  /*
1155  * Do not continue unless we managed to start the NIC. We are
1156  * trapped here if the Ethernet link cannot be established.
1157  * This happens, for example, if no Ethernet cable is plugged
1158  * in.
1159  */
1160  /* while(NicStart(ifn->if_mac)) {*/
1161  while(0) {
1162  /*NutSleep(1000);*/
1165  }
1166 
1167  LANC111_SIGNAL_MODE();
1168  sbi(EIMSK, LANC111_SIGNAL_IRQ);
1169 
1170  /* NutEventPost(&mutex);*/
1171 
1172  /* Run at high priority. */
1173  /* NutThreadSetPriority(9);*/
1174 
1175  for (;;) {
1176 
1177  /*
1178  * Wait for the arrival of new packets or
1179  * check the receiver every two second.
1180  */
1181  /* NutEventWait(&ni->ni_rx_rdy, 2000);*/
1183 
1184  /*
1185  * Fetch all packets from the NIC's internal
1186  * buffer and pass them to the registered handler.
1187  */
1188  imsk = nic_inlb(NIC_MSK);
1189  nic_outlb(NIC_MSK, 0);
1190  /* while ((nb = NicGetPacket()) != 0) {
1191  if (nb != (NETBUF *) 0xFFFF) {
1192  ni->ni_rx_packets++;
1193  (*ifn->if_recv) (dev, nb);
1194  }
1195  }*/
1196  nic_outlb(NIC_MSK, imsk | INT_RCV | INT_ERCV);
1197  }
1198 
1199  PROCESS_END();
1200 }
1201 #endif /* 1 */
1202 #if 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 int LancOutput(NUTDEVICE * dev, NETBUF * nb)
1214 {
1215  static u_long mx_wait = 5000;
1216  int rc = -1;
1217  NICINFO *ni;
1218 
1219  /*
1220  * After initialization we are waiting for a long time to give
1221  * the PHY a chance to establish an Ethernet link.
1222  */
1223  if (NutEventWait(&mutex, mx_wait) == 0) {
1224  ni = (NICINFO *) dev->dev_dcb;
1225 
1226  if (NicPutPacket(nb) == 0) {
1227  ni->ni_tx_packets++;
1228  rc = 0;
1229  /* Ethernet works. Set a long waiting time in case we
1230  temporarly lose the link next time. */
1231  mx_wait = 5000;
1232  }
1233  NutEventPost(&mutex);
1234  }
1235  /*
1236  * Probably no Ethernet link. Significantly reduce the waiting
1237  * time, so following transmission will soon return an error.
1238  */
1239  else {
1240  mx_wait = 500;
1241  }
1242  return rc;
1243 }
1244 #endif /* 0 */
1245 #if 0
1246 /*!
1247  * \brief Initialize Ethernet hardware.
1248  *
1249  * Resets the LAN91C111 Ethernet controller, initializes all required
1250  * hardware registers and starts a background thread for incoming
1251  * Ethernet traffic.
1252  *
1253  * Applications should do not directly call this function. It is
1254  * automatically executed during during device registration by
1255  * NutRegisterDevice().
1256  *
1257  * If the network configuration hasn't been set by the application
1258  * before registering the specified device, this function will
1259  * call NutNetLoadConfig() to get the MAC address.
1260  *
1261  * \param dev Identifies the device to initialize.
1262  */
1263 int LancInit(NUTDEVICE * dev)
1264 {
1265  /* Disable NIC interrupt and clear NICINFO structure. */
1266  cbi(EIMSK, LANC111_SIGNAL_IRQ);
1267  memset(dev->dev_dcb, 0, sizeof(NICINFO));
1268 
1269  /* Register interrupt handler and enable interrupts. */
1270  if (NutRegisterIrqHandler(&LANC111_SIGNAL, NicInterrupt, dev))
1271  return -1;
1272 
1273  /*
1274  * Start the receiver thread.
1275  */
1276  NutThreadCreate("rxi5", NicRxLanc, dev, 640);
1277 
1278  //NutSleep(500);
1279 
1280  return 0;
1281 }
1282 
1283 /*@}*/
1284 
1285 /*!
1286  * \addtogroup xgSmscDev
1287  */
1288 /*@{*/
1289 
1290 static NICINFO dcb_eth0;
1291 
1292 /*!
1293  * \brief Network interface information structure.
1294  *
1295  * Used to call.
1296  */
1297 static IFNET ifn_eth0 = {
1298  IFT_ETHER, /*!< \brief Interface type. */
1299  {0, 0, 0, 0, 0, 0}, /*!< \brief Hardware net address. */
1300  0, /*!< \brief IP address. */
1301  0, /*!< \brief Remote IP address for point to point. */
1302  0, /*!< \brief IP network mask. */
1303  ETHERMTU, /*!< \brief Maximum size of a transmission unit. */
1304  0, /*!< \brief Packet identifier. */
1305  0, /*!< \brief Linked list of arp entries. */
1306  NutEtherInput, /*!< \brief Routine to pass received data to, if_recv(). */
1307  LancOutput, /*!< \brief Driver output routine, if_send(). */
1308  NutEtherOutput /*!< \brief Media output routine, if_output(). */
1309 };
1310 
1311 /*!
1312  * \brief Device information structure.
1313  *
1314  * A pointer to this structure must be passed to NutRegisterDevice()
1315  * to bind this Ethernet device driver to the Nut/OS kernel.
1316  * An application may then call NutNetIfConfig() with the name \em eth0
1317  * of this driver to initialize the network interface.
1318  *
1319  */
1320 NUTDEVICE devSmsc111 = {
1321  0, /* Pointer to next device. */
1322  {'e', 't', 'h', '0', 0, 0, 0, 0, 0}, /* Unique device name. */
1323  IFTYP_NET, /* Type of device. */
1324  0, /* Base address. */
1325  0, /* First interrupt number. */
1326  &ifn_eth0, /* Interface control block. */
1327  &dcb_eth0, /* Driver control block. */
1328  LancInit, /* Driver initialization routine. */
1329  0, /* Driver specific control function. */
1330  0, /* Read from device. */
1331  0, /* Write to device. */
1332  0, /* Write from program space data to device. */
1333  0, /* Open a device or file. */
1334  0, /* Close a device or file. */
1335  0 /* Request file size. */
1336 };
1337 
1338 /*@}*/
1339 #endif /* 0 */
1340 
1341 
1342 int
1343 lanc111_init(void)
1344 {
1345  /* Disable NIC interrupt and clear NICINFO structure. */
1346  cbi(EIMSK, LANC111_SIGNAL_IRQ);
1347 
1348  /* Register interrupt handler and enable interrupts. */
1349  /* if (NutRegisterIrqHandler(&LANC111_SIGNAL, NicInterrupt, dev))
1350  return -1;*/
1351 
1352  /*
1353  * Start the receiver thread.
1354  */
1355  /* NutThreadCreate("rxi5", NicRxLanc, dev, 640);*/
1356 
1357  //NutSleep(500);
1358 
1359  return 0;
1360 }
1361 
1362 /** @} */
1363 /** @} */
1364 
1365 /** @} */
#define NIC_MSK
Bank 2 - Interrupt mask register.
Definition: lanc111.c:338
#define MGMT_MDOE
Definition: lanc111.c:359
#define NIC_PHYCR
PHY control register.
Definition: lanc111.c:377
#define RPCR_ANEG
Definition: lanc111.c:235
#define NIC_PHYMSK
PHY mask register.
Definition: lanc111.c:468
#define PHYMSK_MESD
Definition: lanc111.c:475
#define NIC_CTR
Bank 1 - Control register.
Definition: lanc111.c:264
#define PHYCR_ANEG_EN
Definition: lanc111.c:382
#define INT_TX_EMPTY
Definition: lanc111.c:345
#define PHYMSK_MRPOL
Definition: lanc111.c:476
#define NIC_FIFO
Bank 2 - FIFO ports register.
Definition: lanc111.c:307
#define PHYMSK_MSSD
Definition: lanc111.c:474
#define PHYANAD_10_HDX
Definition: lanc111.c:431
void etimer_set(struct etimer *et, clock_time_t interval)
Set an event timer.
Definition: etimer.c:177
#define PROCESS_END()
Define the end of a process.
Definition: process.h:131
#define PHYMSK_MJAB
Definition: lanc111.c:477
#define PROCESS_THREAD(name, ev, data)
Define the body of a process.
Definition: process.h:273
static struct etimer et
NIC receiver thread.
Definition: lanc111.c:1133
A timer.
Definition: etimer.h:76
#define NIC_PHYSR
PHY status register.
Definition: lanc111.c:393
#define TCR_TXENA
Definition: lanc111.c:196
#define MGMT_MDI
Definition: lanc111.c:361
#define NIC_DATA
Bank 2 - Data register.
Definition: lanc111.c:323
#define PHYCR_ANEG_RST
Definition: lanc111.c:385
#define PHYANAD_10FDX
Definition: lanc111.c:430
static int NicPhyConfig(void)
Configure the internal PHY.
Definition: lanc111.c:650
#define INT_TX
Definition: lanc111.c:346
#define PHYANAD_TX_FDX
Definition: lanc111.c:428
#define NIC_MMUCR
Bank 2 - MMU command register.
Definition: lanc111.c:272
#define NIC_ACK
Bank 2 - Interrupt acknowledge register.
Definition: lanc111.c:333
static uint16_t NicPhyRead(uint8_t reg)
Read contents of PHY register.
Definition: lanc111.c:580
static INLINE int NicMmuWait(uint16_t tmo)
Wait until MMU is ready.
Definition: lanc111.c:742
#define CR_EPH_EN
Definition: lanc111.c:244
#define NIC_TCR
Bank 0 - Transmit control register.
Definition: lanc111.c:185
#define PHYMSK_MDPLDT
Definition: lanc111.c:479
#define RCR_SOFT_RST
Definition: lanc111.c:209
#define NIC_PHYSOR
PHY status output register.
Definition: lanc111.c:452
#define RPCR_LEDA_PAT
Definition: lanc111.c:236
#define RPCR_LEDB_PAT
Definition: lanc111.c:237
#define NIC_PHYCFR1
PHY configuration register 1.
Definition: lanc111.c:442
#define NIC_PHYANAD
PHY auto-negotiation advertisement register.
Definition: lanc111.c:422
#define INT_ALLOC
Definition: lanc111.c:344
#define NIC_IAR
Bank 1 - Individual address register.
Definition: lanc111.c:254
#define PHYMSK_MLOSSSYN
Definition: lanc111.c:472
#define NIC_CR
Bank 1 - Configuration register.
Definition: lanc111.c:242
#define MGMT_MDO
Definition: lanc111.c:362
#define PHYMSK_MCWRD
Definition: lanc111.c:473
#define NIC_PNR
Bank 2 - Packet number register.
Definition: lanc111.c:293
int etimer_expired(struct etimer *et)
Check if an event timer has expired.
Definition: etimer.c:213
#define INT_ERCV
Definition: lanc111.c:341
static void NicPhyWrite(uint8_t reg, uint16_t val)
Write value to PHY register.
Definition: lanc111.c:616
#define PHYCR_RST
Definition: lanc111.c:379
#define CLOCK_SECOND
A second, measured in system clock time.
Definition: clock.h:82
#define NIC_RCR
Bank 0 - Receive control register.
Definition: lanc111.c:207
#define RCR_RXEN
Definition: lanc111.c:213
#define NIC_RPCR
Bank 0 - Receive / PHY control register.
Definition: lanc111.c:231
static NETBUF * NicGetPacket(void)
Fetch the next packet out of the receive ring buffer.
Definition: lanc111.c:960
static int NicReset(void)
Reset the Ethernet controller.
Definition: lanc111.c:757
#define NIC_MGMT
Bank 3 - Management interface register.
Definition: lanc111.c:357
#define NIC_IST
Bank 2 - Interrupt status register.
Definition: lanc111.c:328
#define TCR_PAD_EN
Definition: lanc111.c:193
#define PHYANAD_TX_HDX
Definition: lanc111.c:429
#define NIC_PTR
Bank 2 - Pointer register.
Definition: lanc111.c:312
#define CTR_AUTO_RELEASE
Definition: lanc111.c:267
#define PROCESS_WAIT_UNTIL(c)
Wait for a condition to occur.
Definition: process.h:192
#define PHYMSK_MSPDDT
Definition: lanc111.c:478
static uint8_t NicPhyRegSelect(uint8_t reg, uint8_t we)
Select specified PHY register for reading or writing.
Definition: lanc111.c:516
#define PHYANAD_CSMA
Definition: lanc111.c:432
#define PHYSR_ANEG_ACK
Definition: lanc111.c:401
#define INT_RX_OVRN
Definition: lanc111.c:343
#define MGMT_MCLK
Definition: lanc111.c:360
#define NIC_ERCV
Bank 3 - Early RCV register.
Definition: lanc111.c:372
#define MMUCR_BUSY
MMU command register busy flag.
Definition: lanc111.c:277
#define PROCESS_WAIT_EVENT()
Wait for an event to be posted to the process.
Definition: process.h:141
#define INT_RCV
Definition: lanc111.c:347
#define PROCESS_BEGIN()
Define the beginning of a process.
Definition: process.h:120