102 #ifndef LANC111_BASE_ADDR
103 #define LANC111_BASE_ADDR 0xC000
106 #ifndef LANC111_SIGNAL_IRQ
107 #define LANC111_SIGNAL_IRQ INT5
110 #ifdef LANC111_RESET_BIT
112 #if (LANC111_RESET_AVRPORT == AVRPORTB)
113 #define LANC111_RESET_PORT PORTB
114 #define LANC111_RESET_DDR DDRB
116 #elif (LANC111_RESET_AVRPORT == AVRPORTD)
117 #define LANC111_RESET_PORT PORTD
118 #define LANC111_RESET_DDR DDRD
120 #elif (LANC111_RESET_AVRPORT == AVRPORTE)
121 #define LANC111_RESET_PORT PORTE
122 #define LANC111_RESET_DDR DDRE
124 #elif (LANC111_RESET_AVRPORT == AVRPORTF)
125 #define LANC111_RESET_PORT PORTF
126 #define LANC111_RESET_DDR DDRF
135 #if (LANC111_SIGNAL_IRQ == INT0)
136 #define LANC111_SIGNAL sig_INTERRUPT0
137 #define LANC111_SIGNAL_MODE() sbi(EICRA, ISC00); sbi(EICRA, ISC01)
139 #elif (LANC111_SIGNAL_IRQ == INT1)
140 #define LANC111_SIGNAL sig_INTERRUPT1
141 #define LANC111_SIGNAL_MODE() sbi(EICRA, ISC10); sbi(EICRA, ISC11)
143 #elif (LANC111_SIGNAL_IRQ == INT2)
144 #define LANC111_SIGNAL sig_INTERRUPT2
145 #define LANC111_SIGNAL_MODE() sbi(EICRA, ISC20); sbi(EICRA, ISC21)
147 #elif (LANC111_SIGNAL_IRQ == INT3)
148 #define LANC111_SIGNAL sig_INTERRUPT3
149 #define LANC111_SIGNAL_MODE() sbi(EICRA, ISC30); sbi(EICRA, ISC31)
151 #elif (LANC111_SIGNAL_IRQ == INT4)
152 #define LANC111_SIGNAL sig_INTERRUPT4
153 #define LANC111_SIGNAL_MODE() sbi(EICRB, ISC40); sbi(EICRB, ISC41)
155 #elif (LANC111_SIGNAL_IRQ == INT6)
156 #define LANC111_SIGNAL sig_INTERRUPT6
157 #define LANC111_SIGNAL_MODE() sbi(EICRB, ISC60); sbi(EICRB, ISC61)
159 #elif (LANC111_SIGNAL_IRQ == INT7)
160 #define LANC111_SIGNAL sig_INTERRUPT7
161 #define LANC111_SIGNAL_MODE() sbi(EICRB, ISC70); sbi(EICRB, ISC71)
164 #define LANC111_SIGNAL sig_INTERRUPT5
165 #define LANC111_SIGNAL_MODE() sbi(EICRB, ISC50); sbi(EICRB, ISC51)
180 #define NIC_BSR (LANC111_BASE_ADDR + 0x0E)
185 #define NIC_TCR (LANC111_BASE_ADDR + 0x00)
187 #define TCR_SWFDUP 0x8000
188 #define TCR_EPH_LOOP 0x2000
189 #define TCR_STP_SQET 0x1000
190 #define TCR_FDUPLX 0x0800
191 #define TCR_MON_CSN 0x0400
192 #define TCR_NOCRC 0x0100
193 #define TCR_PAD_EN 0x0080
194 #define TCR_FORCOL 0x0004
195 #define TCR_LOOP 0x0002
196 #define TCR_TXENA 0x0001
202 #define NIC_EPHSR (LANC111_BASE_ADDR + 0x02)
207 #define NIC_RCR (LANC111_BASE_ADDR + 0x04)
209 #define RCR_SOFT_RST 0x8000
210 #define RCR_FILT_CAR 0x4000
211 #define RCR_ABORT_ENB 0x2000
212 #define RCR_STRIP_CRC 0x0200
213 #define RCR_RXEN 0x0100
214 #define RCR_ALMUL 0x0004
215 #define RCR_PRMS 0x0002
216 #define RCR_RX_ABORT 0x0001
221 #define NIC_ECR (LANC111_BASE_ADDR + 0x06)
226 #define NIC_MIR (LANC111_BASE_ADDR + 0x08)
231 #define NIC_RPCR (LANC111_BASE_ADDR + 0x0A)
233 #define RPCR_SPEED 0x2000
234 #define RPCR_DPLX 0x1000
235 #define RPCR_ANEG 0x0800
236 #define RPCR_LEDA_PAT 0x0000
237 #define RPCR_LEDB_PAT 0x0010
242 #define NIC_CR (LANC111_BASE_ADDR + 0x00)
244 #define CR_EPH_EN 0x8000
249 #define NIC_BAR (LANC111_BASE_ADDR + 0x02)
254 #define NIC_IAR (LANC111_BASE_ADDR + 0x04)
259 #define NIC_GPR (LANC111_BASE_ADDR + 0x0A)
264 #define NIC_CTR (LANC111_BASE_ADDR + 0x0C)
266 #define CTR_RCV_BAD 0x4000
267 #define CTR_AUTO_RELEASE 0x0800
272 #define NIC_MMUCR (LANC111_BASE_ADDR + 0x00)
274 #define MMUCR_BUSY 0x0001
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)
290 #define NIC_PNR (LANC111_BASE_ADDR + 0x02)
297 #define NIC_ARR (LANC111_BASE_ADDR + 0x03)
299 #define ARR_FAILED 0x80
304 #define NIC_FIFO (LANC111_BASE_ADDR + 0x04)
309 #define NIC_PTR (LANC111_BASE_ADDR + 0x06)
311 #define PTR_RCV 0x8000
312 #define PTR_AUTO_INCR 0x4000
313 #define PTR_READ 0x2000
314 #define PTR_ETEN 0x1000
315 #define PTR_NOT_EMPTY 0x0800
320 #define NIC_DATA (LANC111_BASE_ADDR + 0x08)
325 #define NIC_IST (LANC111_BASE_ADDR + 0x0C)
330 #define NIC_ACK (LANC111_BASE_ADDR + 0x0C)
335 #define NIC_MSK (LANC111_BASE_ADDR + 0x0D)
338 #define INT_ERCV 0x40
340 #define INT_RX_OVRN 0x10
341 #define INT_ALLOC 0x08
342 #define INT_TX_EMPTY 0x04
349 #define NIC_MT (LANC111_BASE_ADDR + 0x00)
354 #define NIC_MGMT (LANC111_BASE_ADDR + 0x08)
356 #define MGMT_MDOE 0x08
357 #define MGMT_MCLK 0x04
358 #define MGMT_MDI 0x02
359 #define MGMT_MDO 0x01
364 #define NIC_REV (LANC111_BASE_ADDR + 0x0A)
369 #define NIC_ERCV (LANC111_BASE_ADDR + 0x0C)
376 #define PHYCR_RST 0x8000
377 #define PHYCR_LPBK 0x4000
378 #define PHYCR_SPEED 0x2000
379 #define PHYCR_ANEG_EN 0x1000
380 #define PHYCR_PDN 0x0800
381 #define PHYCR_MII_DIS 0x0400
382 #define PHYCR_ANEG_RST 0x0200
383 #define PHYCR_DPLX 0x0100
384 #define PHYCR_COLST 0x0080
392 #define PHYSR_CAP_T4 0x8000
393 #define PHYSR_CAP_TXF 0x4000
394 #define PHYSR_CAP_TXH 0x2000
395 #define PHYSR_CAP_TF 0x1000
396 #define PHYSR_CAP_TH 0x0800
397 #define PHYSR_CAP_SUPR 0x0040
398 #define PHYSR_ANEG_ACK 0x0020
399 #define PHYSR_REM_FLT 0x0010
400 #define PHYSR_CAP_ANEG 0x0008
401 #define PHYSR_LINK 0x0004
402 #define PHYSR_JAB 0x0002
403 #define PHYSR_EXREG 0x0001
419 #define NIC_PHYANAD 4
421 #define PHYANAD_NP 0x8000
422 #define PHYANAD_ACK 0x4000
423 #define PHYANAD_RF 0x2000
424 #define PHYANAD_T4 0x0200
425 #define PHYANAD_TX_FDX 0x0100
426 #define PHYANAD_TX_HDX 0x0080
427 #define PHYANAD_10FDX 0x0040
428 #define PHYANAD_10_HDX 0x0020
429 #define PHYANAD_CSMA 0x0001
434 #define NIC_PHYANRC 5
439 #define NIC_PHYCFR1 16
444 #define NIC_PHYCFR2 17
449 #define NIC_PHYSOR 18
451 #define PHYSOR_INT 0x8000
452 #define PHYSOR_LNKFAIL 0x4000
453 #define PHYSOR_LOSSSYNC 0x2000
454 #define PHYSOR_CWRD 0x1000
455 #define PHYSOR_SSD 0x0800
456 #define PHYSOR_ESD 0x0400
457 #define PHYSOR_RPOL 0x0200
458 #define PHYSOR_JAB 0x0100
459 #define PHYSOR_SPDDET 0x0080
460 #define PHYSOR_DPLXDET 0x0040
465 #define NIC_PHYMSK 19
467 #define PHYMSK_MINT 0x8000
468 #define PHYMSK_MLNKFAIL 0x4000
469 #define PHYMSK_MLOSSSYN 0x2000
470 #define PHYMSK_MCWRD 0x1000
471 #define PHYMSK_MSSD 0x0800
472 #define PHYMSK_MESD 0x0400
473 #define PHYMSK_MRPOL 0x0200
474 #define PHYMSK_MJAB 0x0100
475 #define PHYMSK_MSPDDT 0x0080
476 #define PHYMSK_MDPLDT 0x0040
480 #define MSBV(bit) (1 << ((bit) - 8))
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); \
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))
494 #define nic_bs(bank) nic_outlb(NIC_BSR, bank)
519 static uint8_t NicPhyRegSelect(uint8_t reg, uint8_t we)
529 for (i = 0; i < 33; i++) {
554 for (i = 0; i < 5; i++) {
560 for (msk = 0x10; msk; msk >>= 1) {
583 static uint16_t NicPhyRead(uint8_t reg)
590 rs = NicPhyRegSelect(reg, 0);
598 for (i = 0; i < 16; i++) {
619 static void NicPhyWrite(uint8_t reg, uint16_t val)
625 rs = NicPhyRegSelect(reg, 1);
634 for (msk = 0x8000; msk; msk >>= 1) {
653 static int NicPhyConfig(
void)
667 for (phy_to = 0;; phy_to++) {
712 for (phy_to = 0, phy_sr = 0;; phy_to++) {
717 if ((phy_to & 127) == 0 ) {
745 static INLINE
int NicMmuWait(uint16_t tmo)
748 if ((nic_inlb(
NIC_MMUCR) & MMUCR_BUSY) == 0)
760 static int NicReset(
void)
762 #ifdef LANC111_RESET_BIT
763 sbi(LANC111_RESET_DDR, LANC111_RESET_BIT);
764 sbi(LANC111_RESET_PORT, LANC111_RESET_BIT);
766 cbi(LANC111_RESET_PORT, LANC111_RESET_BIT);
796 if (NicMmuWait(1000))
809 static int NicStart(CONST uint8_t * mac)
832 for (i = 0; i < 6; i++)
833 nic_outlb(
NIC_IAR + i, mac[i]);
847 static void NicInterrupt(
void *arg)
851 NICINFO *ni = (NICINFO *) ((NUTDEVICE *) arg)->dev_dcb;
871 nic_outlb(
NIC_ACK, INT_TX_EMPTY);
872 imr &= ~INT_TX_EMPTY;
873 NutEventPostFromIrq(&ni->ni_tx_rdy);
885 NutEventPostFromIrq(&ni->ni_tx_rdy);
894 nic_outlb(
NIC_ACK, INT_RX_OVRN);
899 NutEventPostFromIrq(&ni->ni_rx_rdy);
904 NutEventPostFromIrq(&ni->ni_rx_rdy);
909 NutEventPostFromIrq(&maq);
918 static void NicWrite(uint8_t * buf, uint16_t len)
920 register uint16_t l = len - 1;
921 register uint8_t ih = (uint16_t) l >> 8;
922 register uint8_t il = (uint8_t) l;
937 static void NicRead(uint8_t * buf, uint16_t len)
939 register uint16_t l = len - 1;
940 register uint8_t ih = (uint16_t) l >> 8;
941 register uint8_t il = (uint8_t) l;
963 static NETBUF *NicGetPacket(
void)
978 nic_outw(
NIC_PTR, PTR_READ | PTR_RCV | PTR_AUTO_INCR);
991 nb = (NETBUF *) 0xFFFF;
994 else if (fbc < 66 || fbc > 1524) {
995 nb = (NETBUF *) 0xFFFF;
1032 static int NicPutPacket(NETBUF * nb)
1045 if ((sz = nb->nb_nw.sz + nb->nb_tp.sz + nb->nb_ap.sz) > ETHERMTU)
1055 if (NicMmuWait(100))
1071 if (NutEventWait(&maq, 125)) {
1075 if (NicMmuWait(100) || (nic_inlb(
NIC_IST) & INT_ALLOC) == 0) {
1076 if (NutEventWait(&maq, 125)) {
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);
1112 if (NicMmuWait(100))
1171 LANC111_SIGNAL_MODE();
1172 sbi(EIMSK, LANC111_SIGNAL_IRQ);
1200 nic_outlb(
NIC_MSK, imsk | INT_RCV | INT_ERCV);
1217 int LancOutput(NUTDEVICE * dev, NETBUF * nb)
1219 static u_long mx_wait = 5000;
1227 if (NutEventWait(&mutex, mx_wait) == 0) {
1228 ni = (NICINFO *) dev->dev_dcb;
1230 if (NicPutPacket(nb) == 0) {
1231 ni->ni_tx_packets++;
1237 NutEventPost(&mutex);
1267 int LancInit(NUTDEVICE * dev)
1270 cbi(EIMSK, LANC111_SIGNAL_IRQ);
1271 memset(dev->dev_dcb, 0,
sizeof(NICINFO));
1274 if (NutRegisterIrqHandler(&LANC111_SIGNAL, NicInterrupt, dev))
1280 NutThreadCreate(
"rxi5", NicRxLanc, dev, 640);
1294 static NICINFO dcb_eth0;
1301 static IFNET ifn_eth0 = {
1324 NUTDEVICE devSmsc111 = {
1326 {
'e',
't',
'h',
'0', 0, 0, 0, 0, 0},
1350 cbi(EIMSK, LANC111_SIGNAL_IRQ);
#define NIC_PHYANAD
PHY auto-negotiation advertisement register.
int etimer_expired(struct etimer *et)
Check if an event timer has expired.
#define PROCESS_WAIT_UNTIL(c)
Wait for a condition to occur.
#define NIC_ACK
Bank 2 - Interrupt acknowledge register.
#define PROCESS_BEGIN()
Define the beginning of a process.
#define NIC_PHYSR
PHY status register.
#define NIC_PNR
Bank 2 - Packet number register.
#define NIC_RPCR
Bank 0 - Receive / PHY control register.
#define NIC_FIFO
Bank 2 - FIFO ports register.
#define NIC_TCR
Bank 0 - Transmit control register.
#define NIC_PHYCFR1
PHY configuration register 1.
#define NIC_CR
Bank 1 - Configuration register.
#define NIC_MSK
Bank 2 - Interrupt mask register.
#define NIC_PHYSOR
PHY status output register.
#define NIC_ERCV
Bank 3 - Early RCV register.
#define PROCESS_THREAD(name, ev, data)
Define the body of a process.
#define PROCESS_END()
Define the end of a process.
#define NIC_MMUCR
Bank 2 - MMU command register.
#define NIC_PTR
Bank 2 - Pointer register.
#define NIC_DATA
Bank 2 - Data register.
#define PROCESS_WAIT_EVENT()
Wait for an event to be posted to the process.
#define NIC_IST
Bank 2 - Interrupt status register.
void etimer_set(struct etimer *et, clock_time_t interval)
Set an event timer.
#define NIC_CTR
Bank 1 - Control register.
#define NIC_PHYMSK
PHY mask register.
#define NIC_MGMT
Bank 3 - Management interface register.
#define NIC_RCR
Bank 0 - Receive control register.
#define NIC_IAR
Bank 1 - Individual address register.
#define NIC_PHYCR
PHY control register.
int lanc111_init(void)
Send Ethernet packet.
#define CLOCK_SECOND
A second, measured in system clock time.