iPXE
ns8390.c File Reference
#include "etherboot.h"
#include "nic.h"
#include "ns8390.h"
#include <ipxe/ethernet.h>
#include <ipxe/pci.h>

Go to the source code of this file.

Macros

#define INCLUDE_NS8390   1
#define eth_probe   nepci_probe
#define ASIC_PIO   NE_DATA

Functions

 FILE_LICENCE (BSD2)
static void eth_pio_read (unsigned int src, unsigned char *dst, unsigned int cnt)
static void eth_pio_write (const unsigned char *src, unsigned int dst, unsigned int cnt)
static void enable_multicast (unsigned short eth_nic_base)
static void ns8390_reset (struct nic *nic)
static int ns8390_poll (struct nic *nic, int retrieve)
static void eth_rx_overrun (struct nic *nic)
static void ns8390_transmit (struct nic *nic, const char *d, unsigned int t, unsigned int s, const char *p)
static void ns8390_disable (struct nic *nic, void *hwdev __unused)
static void ns8390_irq (struct nic *nic __unused, irq_action_t action __unused)
static int eth_probe (struct nic *nic, struct pci_device *pci)
 PCI_DRIVER (nepci_driver, nepci_nics, PCI_NO_CLASS)
 DRIVER ("NE2000/PCI", nic_driver, pci_driver, nepci_driver, nepci_probe, ns8390_disable, no_fake_bss)

Variables

static unsigned char eth_vendor
static unsigned char eth_flags
static unsigned short eth_nic_base
static unsigned short eth_asic_base
static unsigned char eth_memsize
static unsigned char eth_rx_start
static unsigned char eth_tx_start
static Address eth_bmem
static Address eth_rmem
static unsigned char eth_drain_receiver
static struct nic_operations ns8390_operations
static struct pci_device_id nepci_nics []

Macro Definition Documentation

◆ INCLUDE_NS8390

#define INCLUDE_NS8390   1

Definition at line 38 of file ns8390.c.

◆ eth_probe

#define eth_probe   nepci_probe

Definition at line 113 of file ns8390.c.

◆ ASIC_PIO

#define ASIC_PIO   NE_DATA

Definition at line 123 of file ns8390.c.

Function Documentation

◆ FILE_LICENCE()

FILE_LICENCE ( BSD2 )

◆ eth_pio_read()

void eth_pio_read ( unsigned int src,
unsigned char * dst,
unsigned int cnt )
static

Definition at line 131 of file ns8390.c.

132{
133#ifdef INCLUDE_WD
134 outb(src & 0xff, eth_asic_base + WD_GP2);
135 outb(src >> 8, eth_asic_base + WD_GP2);
136#else
145
146#ifdef INCLUDE_3C503
149 outb(t503_output | _3COM_CR_START, eth_asic_base + _3COM_CR);
150#endif
151#endif
152
153 if (eth_flags & FLAG_16BIT)
154 cnt = (cnt + 1) >> 1;
155
156 while(cnt--) {
157#ifdef INCLUDE_3C503
159 ;
160#endif
161
162 if (eth_flags & FLAG_16BIT) {
163 *((unsigned short *)dst) = inw(eth_asic_base + ASIC_PIO);
164 dst += 2;
165 }
166 else
167 *(dst++) = inb(eth_asic_base + ASIC_PIO);
168 }
169
170#ifdef INCLUDE_3C503
171 outb(t503_output, eth_asic_base + _3COM_CR);
172#endif
173}
static unsigned short eth_nic_base
Definition 3c595.c:38
static const void * src
Definition string.h:48
#define inw(io_addr)
Definition io.h:292
#define outb(data, io_addr)
Definition io.h:310
#define inb(io_addr)
Definition io.h:283
#define ASIC_PIO
Definition ne2k_isa.c:31
static unsigned short eth_asic_base
Definition ne2k_isa.c:34
static unsigned char eth_flags
Definition ne2k_isa.c:33
#define D8390_COMMAND_STA
Definition ns8390.h:203
#define WD_GP2
Definition ns8390.h:46
#define D8390_P0_RBCR1
Definition ns8390.h:180
#define D8390_P0_COMMAND
Definition ns8390.h:168
#define D8390_P0_RSAR1
Definition ns8390.h:178
#define D8390_P0_RSAR0
Definition ns8390.h:177
#define _3COM_CR
Definition ns8390.h:110
#define _3COM_STREG
Definition ns8390.h:128
#define D8390_COMMAND_RD0
Definition ns8390.h:201
#define D8390_P0_RBCR0
Definition ns8390.h:179
#define _3COM_CR_START
Definition ns8390.h:118
#define _3COM_DAMSB
Definition ns8390.h:148
#define _3COM_STREG_DPRDY
Definition ns8390.h:134
#define FLAG_16BIT
Definition ns8390.h:17
#define D8390_COMMAND_RD2
Definition ns8390.h:199
#define _3COM_DALSB
Definition ns8390.h:149

References _3COM_CR, _3COM_CR_START, _3COM_DALSB, _3COM_DAMSB, _3COM_STREG, _3COM_STREG_DPRDY, ASIC_PIO, D8390_COMMAND_RD0, D8390_COMMAND_RD2, D8390_COMMAND_STA, D8390_P0_COMMAND, D8390_P0_RBCR0, D8390_P0_RBCR1, D8390_P0_RSAR0, D8390_P0_RSAR1, eth_asic_base, eth_flags, eth_nic_base, FLAG_16BIT, inb, inw, outb, src, and WD_GP2.

Referenced by eth_probe(), and ns8390_poll().

◆ eth_pio_write()

void eth_pio_write ( const unsigned char * src,
unsigned int dst,
unsigned int cnt )
static

Definition at line 178 of file ns8390.c.

179{
180#ifdef COMPEX_RL2000_FIX
181 unsigned int x;
182#endif /* COMPEX_RL2000_FIX */
183#ifdef INCLUDE_WD
184 outb(dst & 0xff, eth_asic_base + WD_GP2);
185 outb(dst >> 8, eth_asic_base + WD_GP2);
186#else
196
197#ifdef INCLUDE_3C503
198 outb(dst & 0xff, eth_asic_base + _3COM_DALSB);
199 outb(dst >> 8, eth_asic_base + _3COM_DAMSB);
200
202#endif
203#endif
204
205 if (eth_flags & FLAG_16BIT)
206 cnt = (cnt + 1) >> 1;
207
208 while(cnt--)
209 {
210#ifdef INCLUDE_3C503
212 ;
213#endif
214
215 if (eth_flags & FLAG_16BIT) {
216 outw(*((unsigned short *)src), eth_asic_base + ASIC_PIO);
217 src += 2;
218 }
219 else
221 }
222
223#ifdef INCLUDE_3C503
224 outb(t503_output, eth_asic_base + _3COM_CR);
225#else
226#ifdef COMPEX_RL2000_FIX
227 for (x = 0;
230 != D8390_ISR_RDC;
231 ++x);
232 if (x >= COMPEX_RL2000_TRIES)
233 printf("Warning: Compex RL2000 aborted wait!\n");
234#endif /* COMPEX_RL2000_FIX */
235#ifndef INCLUDE_WD
237 != D8390_ISR_RDC);
238#endif
239#endif
240}
#define outw(data, io_addr)
Definition io.h:320
#define COMPEX_RL2000_TRIES
Definition ns8390.h:163
#define D8390_COMMAND_RD1
Definition ns8390.h:200
#define D8390_P0_ISR
Definition ns8390.h:176
#define D8390_ISR_RDC
Definition ns8390.h:218
#define _3COM_CR_DDIR
Definition ns8390.h:117
static unsigned int x
Definition pixbuf.h:63
int printf(const char *fmt,...)
Write a formatted string to the console.
Definition vsprintf.c:465

References _3COM_CR, _3COM_CR_DDIR, _3COM_CR_START, _3COM_DALSB, _3COM_DAMSB, _3COM_STREG, _3COM_STREG_DPRDY, ASIC_PIO, COMPEX_RL2000_TRIES, D8390_COMMAND_RD1, D8390_COMMAND_RD2, D8390_COMMAND_STA, D8390_ISR_RDC, D8390_P0_COMMAND, D8390_P0_ISR, D8390_P0_RBCR0, D8390_P0_RBCR1, D8390_P0_RSAR0, D8390_P0_RSAR1, eth_asic_base, eth_flags, eth_nic_base, FLAG_16BIT, inb, outb, outw, printf(), src, WD_GP2, and x.

Referenced by eth_probe(), and ns8390_transmit().

◆ enable_multicast()

void enable_multicast ( unsigned short eth_nic_base)
static

Definition at line 252 of file ns8390.c.

253{
254 unsigned char mcfilter[8];
255 int i;
256 memset(mcfilter, 0xFF, 8);
259 for(i=0;i<8;i++)
260 {
261 outb(mcfilter[i], eth_nic_base + 8 + i);
262 if(inb(eth_nic_base + 8 + i)!=mcfilter[i])
263 printf("Error SMC 83C690 Multicast filter read/write mishap %d\n",i);
264 }
266 outb(4 | 0x08, eth_nic_base+D8390_P0_RCR);
267}
void * memset(void *dest, int character, size_t len) __nonnull
#define D8390_COMMAND_PS1
Definition ns8390.h:197
#define D8390_COMMAND_PS0
Definition ns8390.h:196
#define D8390_P0_RCR
Definition ns8390.h:182

References D8390_COMMAND_PS0, D8390_COMMAND_PS1, D8390_COMMAND_RD2, D8390_P0_COMMAND, D8390_P0_RCR, eth_nic_base, inb, memset(), outb, and printf().

Referenced by ns8390_reset().

◆ ns8390_reset()

void ns8390_reset ( struct nic * nic)
static

Definition at line 272 of file ns8390.c.

273{
274 int i;
275
277#ifdef INCLUDE_WD
278 if (eth_flags & FLAG_790)
280 else
281#endif
284 if (eth_flags & FLAG_16BIT)
286 else
290 outb(0x20, eth_nic_base+D8390_P0_RCR); /* monitor mode */
294#ifdef INCLUDE_WD
295 if (eth_flags & FLAG_790) {
296#ifdef WD_790_PIO
297 outb(0x10, eth_asic_base + 0x06); /* disable interrupts, enable PIO */
298 outb(0x01, eth_nic_base + 0x09); /* enable ring read auto-wrap */
299#else
300 outb(0, eth_nic_base + 0x09);
301#endif
302 }
303#endif
308#ifdef INCLUDE_WD
309 if (eth_flags & FLAG_790)
312 else
313#endif
316 for (i=0; i<ETH_ALEN; i++)
318 for (i=0; i<ETH_ALEN; i++)
321#ifdef INCLUDE_WD
322 if (eth_flags & FLAG_790)
325 else
326#endif
330 outb(0, eth_nic_base+D8390_P0_TCR); /* transmitter on */
331 outb(4, eth_nic_base+D8390_P0_RCR); /* allow rx broadcast frames */
332
334
335#ifdef INCLUDE_3C503
336 /*
337 * No way to tell whether or not we're supposed to use
338 * the 3Com's transceiver unless the user tells us.
339 * 'flags' should have some compile time default value
340 * which can be changed from the command menu.
341 */
342 t503_output = (nic->flags) ? 0 : _3COM_CR_XSEL;
343 outb(t503_output, eth_asic_base + _3COM_CR);
344#endif
345}
#define ETH_ALEN
Definition if_ether.h:9
static unsigned char eth_drain_receiver
Definition ne2k_isa.c:37
static unsigned char eth_tx_start
Definition ne2k_isa.c:35
static unsigned char eth_rx_start
Definition ne2k_isa.c:35
static unsigned char eth_memsize
Definition ne2k_isa.c:35
static void enable_multicast(unsigned short eth_nic_base)
Definition ns8390.c:252
#define D8390_P0_PSTOP
Definition ns8390.h:170
#define D8390_P0_BOUND
Definition ns8390.h:171
#define D8390_P0_IMR
Definition ns8390.h:185
#define D8390_P0_DCR
Definition ns8390.h:184
#define D8390_P0_PSTART
Definition ns8390.h:169
#define _3COM_CR_XSEL
Definition ns8390.h:112
#define D8390_P0_TPSR
Definition ns8390.h:173
#define D8390_P1_PAR0
Definition ns8390.h:187
#define FLAG_790
Definition ns8390.h:18
#define D8390_P0_TCR
Definition ns8390.h:183
#define D8390_P1_MAR0
Definition ns8390.h:194
#define D8390_COMMAND_STP
Definition ns8390.h:204
#define D8390_P1_CURR
Definition ns8390.h:193
Definition nic.h:49
int flags
Definition nic.h:51
unsigned char * node_addr
Definition nic.h:52

References _3COM_CR, _3COM_CR_XSEL, D8390_COMMAND_PS0, D8390_COMMAND_PS1, D8390_COMMAND_RD2, D8390_COMMAND_STA, D8390_COMMAND_STP, D8390_P0_BOUND, D8390_P0_COMMAND, D8390_P0_DCR, D8390_P0_IMR, D8390_P0_ISR, D8390_P0_PSTART, D8390_P0_PSTOP, D8390_P0_RBCR0, D8390_P0_RBCR1, D8390_P0_RCR, D8390_P0_TCR, D8390_P0_TPSR, D8390_P1_CURR, D8390_P1_MAR0, D8390_P1_PAR0, enable_multicast(), ETH_ALEN, eth_asic_base, eth_drain_receiver, eth_flags, eth_memsize, eth_nic_base, eth_rx_start, eth_tx_start, FLAG_16BIT, FLAG_790, nic::flags, nic::node_addr, and outb.

Referenced by eth_probe(), and ns8390_disable().

◆ ns8390_poll()

int ns8390_poll ( struct nic * nic,
int retrieve )
static

Definition at line 502 of file ns8390.c.

503{
504 int ret = 0;
505 unsigned char rstat, curr, next;
506 unsigned short len, frag;
507 unsigned short pktoff;
508 unsigned char *p;
509 struct ringbuffer pkthdr;
510
511#ifndef INCLUDE_3C503
512 /* avoid infinite recursion: see eth_rx_overrun() */
515 return(0);
516 }
517#endif /* INCLUDE_3C503 */
519 if (!(rstat & D8390_RSTAT_PRX)) return(0);
525 if (curr >= eth_memsize) curr=eth_rx_start;
526 if (curr == next) return(0);
527
528 if ( ! retrieve ) return 1;
529
530#ifdef INCLUDE_WD
531 if (eth_flags & FLAG_16BIT) {
533 inb(0x84);
534 }
535#ifndef WD_790_PIO
536 if (eth_flags & FLAG_790) {
538 inb(0x84);
539 }
540#endif
541 inb(0x84);
542#endif
543 pktoff = next << 8;
544 if (eth_flags & FLAG_PIO)
545 eth_pio_read(pktoff, (unsigned char *)&pkthdr, 4);
546 else
547 memcpy(&pkthdr, bus_to_virt(eth_rmem + pktoff), 4);
548 pktoff += sizeof(pkthdr);
549 /* incoming length includes FCS so must sub 4 */
550 len = pkthdr.len - 4;
551 if ((pkthdr.status & D8390_RSTAT_PRX) == 0 || len < ETH_ZLEN
552 || len > ETH_FRAME_LEN) {
553 printf("Bogus packet, ignoring\n");
554 return (0);
555 }
556 else {
557 p = nic->packet;
558 nic->packetlen = len; /* available to caller */
559 frag = (eth_memsize << 8) - pktoff;
560 if (len > frag) { /* We have a wrap-around */
561 /* read first part */
562 if (eth_flags & FLAG_PIO)
563 eth_pio_read(pktoff, p, frag);
564 else
565 memcpy(p, bus_to_virt(eth_rmem + pktoff), frag);
566 pktoff = eth_rx_start << 8;
567 p += frag;
568 len -= frag;
569 }
570 /* read second part */
571 if (eth_flags & FLAG_PIO)
572 eth_pio_read(pktoff, p, len);
573 else
574 memcpy(p, bus_to_virt(eth_rmem + pktoff), len);
575 ret = 1;
576 }
577#ifdef INCLUDE_WD
578#ifndef WD_790_PIO
579 if (eth_flags & FLAG_790) {
581 inb(0x84);
582 }
583#endif
584 if (eth_flags & FLAG_16BIT) {
585 outb(eth_laar & ~WD_LAAR_M16EN, eth_asic_base + WD_LAAR);
586 inb(0x84);
587 }
588 inb(0x84);
589#endif
590 next = pkthdr.next; /* frame number of next packet */
591 if (next == eth_rx_start)
594 return(ret);
595}
uint32_t next
Next descriptor address.
Definition dwmac.h:11
ring len
Length.
Definition dwmac.h:226
#define ETH_ZLEN
Definition if_ether.h:11
#define ETH_FRAME_LEN
Definition if_ether.h:12
static __always_inline void * bus_to_virt(unsigned long bus_addr)
Convert bus address to a virtual address.
Definition io.h:196
void * memcpy(void *dest, const void *src, size_t len) __nonnull
static Address eth_rmem
Definition ne2k_isa.c:36
static void eth_rx_overrun(struct nic *nic)
Definition ns8390.c:353
static void eth_pio_read(unsigned int src, unsigned char *dst, unsigned int cnt)
Definition ns8390.c:131
#define WD_LAAR
Definition ns8390.h:44
#define D8390_RSTAT_PRX
Definition ns8390.h:221
#define WD_MSR
Definition ns8390.h:39
#define WD_LAAR_M16EN
Definition ns8390.h:55
#define D8390_ISR_OVW
Definition ns8390.h:216
#define D8390_P0_RSR
Definition ns8390.h:181
#define WD_MSR_MENB
Definition ns8390.h:52
#define FLAG_PIO
Definition ns8390.h:16
unsigned char * packet
Definition nic.h:53
unsigned int packetlen
Definition nic.h:54

References bus_to_virt(), D8390_COMMAND_PS0, D8390_COMMAND_PS1, D8390_ISR_OVW, D8390_P0_BOUND, D8390_P0_COMMAND, D8390_P0_ISR, D8390_P0_RSR, D8390_P1_CURR, D8390_RSTAT_PRX, eth_asic_base, eth_drain_receiver, eth_flags, ETH_FRAME_LEN, eth_memsize, eth_nic_base, eth_pio_read(), eth_rmem, eth_rx_overrun(), eth_rx_start, ETH_ZLEN, FLAG_16BIT, FLAG_790, FLAG_PIO, inb, len, ringbuffer::len, memcpy(), next, ringbuffer::next, outb, nic::packet, nic::packetlen, printf(), ringbuffer::status, WD_LAAR, WD_LAAR_M16EN, WD_MSR, and WD_MSR_MENB.

Referenced by eth_rx_overrun().

◆ eth_rx_overrun()

void eth_rx_overrun ( struct nic * nic)
static

Definition at line 353 of file ns8390.c.

354{
355 int start_time;
356
357#ifdef INCLUDE_WD
358 if (eth_flags & FLAG_790)
360 else
361#endif
364
365 /* wait for at least 1.6ms - we wait one timer tick */
366 start_time = currticks();
367 while (currticks() - start_time <= 1)
368 /* Nothing */;
369
370 outb(0, eth_nic_base+D8390_P0_RBCR0); /* reset byte counter */
372
373 /*
374 * Linux driver checks for interrupted TX here. This is not necessary,
375 * because the transmit routine waits until the frame is sent.
376 */
377
378 /* enter loopback mode and restart NIC */
380#ifdef INCLUDE_WD
381 if (eth_flags & FLAG_790)
383 else
384#endif
387
388 /* clear the RX ring, acknowledge overrun interrupt */
390 while (ns8390_poll(nic, 1))
391 /* Nothing */;
394
395 /* leave loopback mode - no packets to be resent (see Linux driver) */
397}
static int ns8390_poll(struct nic *nic, int retrieve)
Definition ns8390.c:502
unsigned long currticks(void)
Get current system time in ticks.
Definition timer.c:43

References currticks(), D8390_COMMAND_PS0, D8390_COMMAND_RD2, D8390_COMMAND_STA, D8390_COMMAND_STP, D8390_ISR_OVW, D8390_P0_COMMAND, D8390_P0_ISR, D8390_P0_RBCR0, D8390_P0_RBCR1, D8390_P0_TCR, eth_drain_receiver, eth_flags, eth_nic_base, FLAG_790, ns8390_poll(), and outb.

Referenced by ns8390_poll().

◆ ns8390_transmit()

void ns8390_transmit ( struct nic * nic,
const char * d,
unsigned int t,
unsigned int s,
const char * p )
static

Definition at line 403 of file ns8390.c.

409{
410#if defined(INCLUDE_3C503) || (defined(INCLUDE_WD) && ! defined(WD_790_PIO))
411 Address eth_vmem = bus_to_virt(eth_bmem);
412#endif
413#ifdef INCLUDE_3C503
414 if (!(eth_flags & FLAG_PIO)) {
415 memcpy((char *)eth_vmem, d, ETH_ALEN); /* dst */
416 memcpy((char *)eth_vmem+ETH_ALEN, nic->node_addr, ETH_ALEN); /* src */
417 *((char *)eth_vmem+12) = t>>8; /* type */
418 *((char *)eth_vmem+13) = t;
419 memcpy((char *)eth_vmem+ETH_HLEN, p, s);
420 s += ETH_HLEN;
421 while (s < ETH_ZLEN) *((char *)eth_vmem+(s++)) = 0;
422 }
423#endif
424
425#ifdef INCLUDE_WD
426 if (eth_flags & FLAG_16BIT) {
428 inb(0x84);
429 }
430#ifndef WD_790_PIO
431 /* Memory interface */
432 if (eth_flags & FLAG_790) {
434 inb(0x84);
435 }
436 inb(0x84);
437 memcpy((char *)eth_vmem, d, ETH_ALEN); /* dst */
438 memcpy((char *)eth_vmem+ETH_ALEN, nic->node_addr, ETH_ALEN); /* src */
439 *((char *)eth_vmem+12) = t>>8; /* type */
440 *((char *)eth_vmem+13) = t;
441 memcpy((char *)eth_vmem+ETH_HLEN, p, s);
442 s += ETH_HLEN;
443 while (s < ETH_ZLEN) *((char *)eth_vmem+(s++)) = 0;
444 if (eth_flags & FLAG_790) {
446 inb(0x84);
447 }
448#else
449 inb(0x84);
450#endif
451#endif
452
453#if defined(INCLUDE_3C503)
454 if (eth_flags & FLAG_PIO)
455#endif
456#if defined(INCLUDE_NE) || defined(INCLUDE_NS8390) || (defined(INCLUDE_3C503) && !defined(T503_SHMEM)) || (defined(INCLUDE_WD) && defined(WD_790_PIO))
457 {
458 /* Programmed I/O */
459 unsigned short type;
460 type = (t >> 8) | (t << 8);
461 eth_pio_write( (unsigned char *) d, eth_tx_start<<8, ETH_ALEN);
463 /* bcc generates worse code without (const+const) below */
464 eth_pio_write((unsigned char *)&type, (eth_tx_start<<8)+(ETH_ALEN+ETH_ALEN), 2);
465 eth_pio_write( (unsigned char *) p, (eth_tx_start<<8)+ETH_HLEN, s);
466 s += ETH_HLEN;
467 if (s < ETH_ZLEN) s = ETH_ZLEN;
468 }
469#endif
470#if defined(INCLUDE_3C503)
471#endif
472
473#ifdef INCLUDE_WD
474 if (eth_flags & FLAG_16BIT) {
475 outb(eth_laar & ~WD_LAAR_M16EN, eth_asic_base + WD_LAAR);
476 inb(0x84);
477 }
478 if (eth_flags & FLAG_790)
481 else
482#endif
488#ifdef INCLUDE_WD
489 if (eth_flags & FLAG_790)
492 else
493#endif
497}
uint32_t type
Operating system type.
Definition ena.h:1
unsigned long Address
Definition etherboot.h:21
#define ETH_HLEN
Definition if_ether.h:10
static Address eth_bmem
Definition ne2k_isa.c:36
static void eth_pio_write(const unsigned char *src, unsigned int dst, unsigned int cnt)
Definition ns8390.c:178
#define D8390_P0_TBCR1
Definition ns8390.h:175
#define D8390_P0_TBCR0
Definition ns8390.h:174
#define D8390_COMMAND_TXP
Definition ns8390.h:202

References bus_to_virt(), D8390_COMMAND_PS0, D8390_COMMAND_RD2, D8390_COMMAND_STA, D8390_COMMAND_TXP, D8390_P0_COMMAND, D8390_P0_TBCR0, D8390_P0_TBCR1, D8390_P0_TPSR, ETH_ALEN, eth_asic_base, eth_bmem, eth_flags, ETH_HLEN, eth_nic_base, eth_pio_write(), eth_tx_start, ETH_ZLEN, FLAG_16BIT, FLAG_790, FLAG_PIO, inb, memcpy(), nic::node_addr, outb, type, WD_LAAR, WD_LAAR_M16EN, WD_MSR, and WD_MSR_MENB.

◆ ns8390_disable()

void ns8390_disable ( struct nic * nic,
void *hwdev __unused )
static

Definition at line 600 of file ns8390.c.

600 {
602}
static void ns8390_reset(struct nic *nic)
Definition ns8390.c:272

References __unused, and ns8390_reset().

Referenced by DRIVER().

◆ ns8390_irq()

void ns8390_irq ( struct nic *nic __unused,
irq_action_t action __unused )
static

Definition at line 607 of file ns8390.c.

608{
609 switch ( action ) {
610 case DISABLE :
611 break;
612 case ENABLE :
613 break;
614 case FORCE :
615 break;
616 }
617}
@ FORCE
Definition nic.h:37
@ ENABLE
Definition nic.h:36
@ DISABLE
Definition nic.h:35

References __unused, DISABLE, ENABLE, and FORCE.

◆ eth_probe()

int eth_probe ( struct nic * nic,
struct pci_device * pci )
static

Definition at line 631 of file ns8390.c.

635{
636 int i;
637#ifdef INCLUDE_NS8390
638 unsigned short pci_probe_addrs[] = { pci->ioaddr, 0 };
639 unsigned short *probe_addrs = pci_probe_addrs;
640#endif
643
644 nic->irqno = 0;
645
646#ifdef INCLUDE_WD
647{
648 /******************************************************************
649 Search for WD/SMC cards
650 ******************************************************************/
651 struct wd_board *brd;
652 unsigned short chksum;
653 unsigned char c;
655 eth_asic_base += 0x20) {
656 chksum = 0;
657 for (i=8; i<16; i++)
658 chksum += inb(eth_asic_base+i);
659 /* Extra checks to avoid soundcard */
660 if ((chksum & 0xFF) == 0xFF &&
661 inb(eth_asic_base+8) != 0xFF &&
662 inb(eth_asic_base+9) != 0xFF)
663 break;
664 }
666 return (0);
667 /* We've found a board */
670
672
673 c = inb(eth_asic_base+WD_BID); /* Get board id */
674 for (brd = wd_boards; brd->name; brd++)
675 if (brd->id == c) break;
676 if (!brd->name) {
677 printf("Unknown WD/SMC NIC type %hhX\n", c);
678 return (0); /* Unknown type */
679 }
680 eth_flags = brd->flags;
681 eth_memsize = brd->memsize;
682 eth_tx_start = 0;
684 if ((c == TYPE_WD8013EP) &&
688 }
689 if ((c & WD_SOFTCONFIG) && (!(eth_flags & FLAG_790))) {
690 eth_bmem = (0x80000 |
691 ((inb(eth_asic_base + WD_MSR) & 0x3F) << 13));
692 } else
694 if (brd->id == TYPE_SMC8216T || brd->id == TYPE_SMC8216C) {
695 /* from Linux driver, 8416BT detects as 8216 sometimes */
696 unsigned int addr = inb(eth_asic_base + 0xb);
697 if (((addr >> 4) & 3) == 0) {
698 brd += 2;
699 eth_memsize = brd->memsize;
700 }
701 }
702 outb(0x80, eth_asic_base + WD_MSR); /* Reset */
703 for (i=0; i<ETH_ALEN; i++) {
705 }
706 DBG ( "\n%s base %4.4x", brd->name, eth_asic_base );
707 if (eth_flags & FLAG_790) {
708#ifdef WD_790_PIO
709 DBG ( ", PIO mode, addr %s\n", eth_ntoa ( nic->node_addr ) );
710 eth_bmem = 0;
711 eth_flags |= FLAG_PIO; /* force PIO mode */
713#else
714 DBG ( ", Memory %x, MAC Addr %s\n", eth_bmem, eth_ntoa ( nic->node_addr) );
715
717 outb((inb(eth_asic_base+0x04) |
718 0x80), eth_asic_base+0x04);
719 outb(((unsigned)(eth_bmem >> 13) & 0x0F) |
720 ((unsigned)(eth_bmem >> 11) & 0x40) |
721 (inb(eth_asic_base+0x0B) & 0xB0), eth_asic_base+0x0B);
722 outb((inb(eth_asic_base+0x04) &
723 ~0x80), eth_asic_base+0x04);
724#endif
725 } else {
726
727 DBG (", Memory %x, MAC Addr %s\n", eth_bmem, eth_ntoa ( nic->node_addr) );
728
729 outb(((unsigned)(eth_bmem >> 13) & 0x3F) | 0x40, eth_asic_base+WD_MSR);
730 }
731 if (eth_flags & FLAG_16BIT) {
732 if (eth_flags & FLAG_790) {
733 eth_laar = inb(eth_asic_base + WD_LAAR);
735 } else {
736 outb((eth_laar =
738/*
739 The previous line used to be
740 WD_LAAR_M16EN | WD_LAAR_L16EN | 1));
741 jluke@deakin.edu.au reported that removing WD_LAAR_M16EN made
742 it work for WD8013s. This seems to work for my 8013 boards. I
743 don't know what is really happening. I wish I had data sheets
744 or more time to decode the Linux driver. - Ken
745*/
746 }
747 inb(0x84);
748 }
749}
750#endif
751#ifdef INCLUDE_3C503
752#ifdef T503_AUI
753 nic->flags = 1; /* aui */
754#else
755 nic->flags = 0; /* no aui */
756#endif
757 /******************************************************************
758 Search for 3Com 3c503 if no WD/SMC cards
759 ******************************************************************/
760 if (eth_vendor == VENDOR_NONE) {
761 int idx;
762 int iobase_reg, membase_reg;
763 static unsigned short base[] = {
764 0x300, 0x310, 0x330, 0x350,
765 0x250, 0x280, 0x2A0, 0x2E0, 0 };
766
767 /* Loop through possible addresses checking each one */
768
769 for (idx = 0; (eth_nic_base = base[idx]) != 0; ++idx) {
770
772/*
773 * Note that we use the same settings for both 8 and 16 bit cards:
774 * both have an 8K bank of memory at page 1 while only the 16 bit
775 * cards have a bank at page 0.
776 */
778 eth_tx_start = 32;
780
781 /* Check our base address. iobase and membase should */
782 /* both have a maximum of 1 bit set or be 0. */
783
784 iobase_reg = inb(eth_asic_base + _3COM_BCFR);
785 membase_reg = inb(eth_asic_base + _3COM_PCFR);
786
787 if ((iobase_reg & (iobase_reg - 1)) ||
788 (membase_reg & (membase_reg - 1)))
789 continue; /* nope */
790
791 /* Now get the shared memory address */
792
793 eth_flags = 0;
794
795 switch (membase_reg) {
796 case _3COM_PCFR_DC000:
797 eth_bmem = 0xdc000;
798 break;
799 case _3COM_PCFR_D8000:
800 eth_bmem = 0xd8000;
801 break;
802 case _3COM_PCFR_CC000:
803 eth_bmem = 0xcc000;
804 break;
805 case _3COM_PCFR_C8000:
806 eth_bmem = 0xc8000;
807 break;
808 case _3COM_PCFR_PIO:
810 eth_bmem = 0;
811 break;
812 default:
813 continue; /* nope */
814 }
815 break;
816 }
817
818 if (base[idx] == 0) /* not found */
819 return (0);
820#ifndef T503_SHMEM
821 eth_flags |= FLAG_PIO; /* force PIO mode */
822 eth_bmem = 0;
823#endif
825
826
827 /* Need this to make ns8390_poll() happy. */
828
829 eth_rmem = eth_bmem - 0x2000;
830
831 /* Reset NIC and ASIC */
832
835
836 /* Get our ethernet address */
837
840 DBG ( "\n3Com 3c503 base %4.4x, ", eth_nic_base );
841 if (eth_flags & FLAG_PIO)
842 DBG ( "PIO mode" );
843 else
844 DBG ( "memory %4.4x", eth_bmem );
845 for (i=0; i<ETH_ALEN; i++) {
846 nic->node_addr[i] = inb(eth_nic_base+i);
847 }
848 DBG ( ", %s, MAC Addr %s\n", nic->flags ? "AUI" : "internal xcvr",
849 eth_ntoa ( nic->node_addr ) );
850
852 /*
853 * Initialize GA configuration register. Set bank and enable shared
854 * mem. We always use bank 1. Disable interrupts.
855 */
858
862 /*
863 * Clear memory and verify that it worked (we use only 8K)
864 */
865
866 if (!(eth_flags & FLAG_PIO)) {
867 memset(bus_to_virt(eth_bmem), 0, 0x2000);
868 for(i = 0; i < 0x2000; ++i)
869 if (*((char *)(bus_to_virt(eth_bmem+i)))) {
870 printf ("Failed to clear 3c503 shared mem.\n");
871 return (0);
872 }
873 }
874 /*
875 * Initialize GA page/start/stop registers.
876 */
879 }
880#endif
881#if defined(INCLUDE_NE) || defined(INCLUDE_NS8390)
882{
883 /******************************************************************
884 Search for NE1000/2000 if no WD/SMC or 3com cards
885 ******************************************************************/
886 unsigned char c;
887 if (eth_vendor == VENDOR_NONE) {
888 unsigned char romdata[16];
889 unsigned char testbuf[32];
890 int idx;
891 static unsigned char test[] = "NE*000 memory";
892 static unsigned short base[] = {
893#ifdef NE_SCAN
894 NE_SCAN,
895#endif
896 0 };
897 /* if no addresses supplied, fall back on defaults */
898 if (probe_addrs == NULL || probe_addrs[0] == 0)
899 probe_addrs = base;
900 eth_bmem = 0; /* No shared memory */
901 for (idx = 0; (eth_nic_base = probe_addrs[idx]) != 0; ++idx) {
905 eth_tx_start = 32;
909 (void) inb(0x84);
916#ifdef NS8390_FORCE_16BIT
917 eth_flags |= FLAG_16BIT; /* force 16-bit mode */
918#endif
919
920 eth_pio_write( (unsigned char *) test, 8192, sizeof(test));
921 eth_pio_read(8192, testbuf, sizeof(test));
922 if (!memcmp(test, testbuf, sizeof(test)))
923 break;
926 eth_tx_start = 64;
932 eth_pio_write( (unsigned char *) test, 16384, sizeof(test));
933 eth_pio_read(16384, testbuf, sizeof(test));
934 if (!memcmp(testbuf, test, sizeof(test)))
935 break;
936 }
937 if (eth_nic_base == 0)
938 return (0);
939 if (eth_nic_base > ISA_MAX_ADDR) /* PCI probably */
942 eth_pio_read(0, romdata, sizeof(romdata));
943 for (i=0; i<ETH_ALEN; i++) {
944 nic->node_addr[i] = romdata[i + ((eth_flags & FLAG_16BIT) ? i : 0)];
945 }
947 DBG ( "\nNE%c000 base %4.4x, MAC Addr %s\n",
948 (eth_flags & FLAG_16BIT) ? '2' : '1', eth_nic_base,
949 eth_ntoa ( nic->node_addr ) );
950 }
951}
952#endif
953 if (eth_vendor == VENDOR_NONE)
954 return(0);
955 if (eth_vendor != VENDOR_3COM)
959
960 /* Based on PnP ISA map */
961#ifdef INCLUDE_WD
962 dev->devid.vendor_id = htons(GENERIC_ISAPNP_VENDOR);
963 dev->devid.device_id = htons(0x812a);
964#endif
965#ifdef INCLUDE_3C503
966 dev->devid.vendor_id = htons(GENERIC_ISAPNP_VENDOR);
967 dev->devid.device_id = htons(0x80f3);
968#endif
969#ifdef INCLUDE_NE
970 dev->devid.vendor_id = htons(GENERIC_ISAPNP_VENDOR);
971 dev->devid.device_id = htons(0x80d6);
972#endif
973 return 1;
974}
#define NULL
NULL pointer (VOID *)
Definition Base.h:322
uint32_t addr
Buffer address.
Definition dwmac.h:9
static int test
Definition epic100.c:73
const char * eth_ntoa(const void *ll_addr)
Transcribe Ethernet address.
Definition ethernet.c:176
#define DBG(...)
Print a debugging message.
Definition compiler.h:498
#define htons(value)
Definition byteswap.h:136
#define GENERIC_ISAPNP_VENDOR
Definition isa_ids.h:38
uint32_t base
Base.
Definition librm.h:3
static unsigned char eth_vendor
Definition ne2k_isa.c:33
static struct nic_operations ns8390_operations
Definition ns8390.c:619
#define WD_ICR_16BIT
Definition ns8390.h:50
#define VENDOR_NONE
Definition ns8390.h:11
#define VENDOR_NOVELL
Definition ns8390.h:13
#define WD_HIGH_BASE
Definition ns8390.h:30
#define WD_ICR
Definition ns8390.h:40
#define NE_ASIC_OFFSET
Definition ns8390.h:159
#define _3COM_PCFR_PIO
Definition ns8390.h:105
#define _3COM_PCFR_C8000
Definition ns8390.h:106
#define _3COM_GACFR_TCM
Definition ns8390.h:126
#define D8390_DCR_WTS
Definition ns8390.h:210
#define VENDOR_WD
Definition ns8390.h:12
#define _3COM_CR_EALO
Definition ns8390.h:113
#define _3COM_VPTR0
Definition ns8390.h:152
#define _3COM_PSTR
Definition ns8390.h:92
#define _3COM_GACFR
Definition ns8390.h:119
#define _3COM_PCFR_DC000
Definition ns8390.h:109
#define _3COM_PCFR_D8000
Definition ns8390.h:108
#define _3COM_PSPR
Definition ns8390.h:93
#define TYPE_WD8013EP
Definition ns8390.h:68
#define MEM_8192
Definition ns8390.h:20
#define NE_RESET
Definition ns8390.h:160
#define WD_LAAR_L16EN
Definition ns8390.h:54
#define D8390_DCR_LS
Definition ns8390.h:209
#define WD_BID
Definition ns8390.h:48
#define _3COM_GACFR_MBS0
Definition ns8390.h:120
#define WD_SOFTCONFIG
Definition ns8390.h:57
#define TYPE_SMC8216T
Definition ns8390.h:71
#define TYPE_SMC8216C
Definition ns8390.h:72
#define MEM_16384
Definition ns8390.h:21
#define _3COM_GACFR_NIM
Definition ns8390.h:127
#define MEM_32768
Definition ns8390.h:22
#define _3COM_GACFR_RSEL
Definition ns8390.h:123
#define D8390_TXBUF_SIZE
Definition ns8390.h:226
#define ISA_MAX_ADDR
Definition ns8390.h:24
#define _3COM_VPTR2
Definition ns8390.h:150
#define WD_NIC_ADDR
Definition ns8390.h:34
#define VENDOR_3COM
Definition ns8390.h:14
#define _3COM_PCFR
Definition ns8390.h:104
#define D8390_DCR_FT1
Definition ns8390.h:208
#define _3COM_PCFR_CC000
Definition ns8390.h:107
#define WD_LAR
Definition ns8390.h:47
#define WD_DEFAULT_MEM
Definition ns8390.h:32
#define WD_LOW_BASE
Definition ns8390.h:29
#define _3COM_ASIC_OFFSET
Definition ns8390.h:89
#define _3COM_CR_RST
Definition ns8390.h:111
#define _3COM_BCFR
Definition ns8390.h:95
#define _3COM_VPTR1
Definition ns8390.h:151
#define D8390_RCR_MON
Definition ns8390.h:206
int memcmp(const void *first, const void *second, size_t len)
Compare memory regions.
Definition string.c:115
unsigned char irqno
Definition nic.h:56
unsigned int ioaddr
Definition nic.h:55
struct nic_operations * nic_op
Definition nic.h:50
unsigned long ioaddr
I/O address.
Definition pci.h:226

References _3COM_ASIC_OFFSET, _3COM_BCFR, _3COM_CR, _3COM_CR_EALO, _3COM_CR_RST, _3COM_CR_XSEL, _3COM_GACFR, _3COM_GACFR_MBS0, _3COM_GACFR_NIM, _3COM_GACFR_RSEL, _3COM_GACFR_TCM, _3COM_PCFR, _3COM_PCFR_C8000, _3COM_PCFR_CC000, _3COM_PCFR_D8000, _3COM_PCFR_DC000, _3COM_PCFR_PIO, _3COM_PSPR, _3COM_PSTR, _3COM_VPTR0, _3COM_VPTR1, _3COM_VPTR2, __unused, addr, base, bus_to_virt(), D8390_COMMAND_RD2, D8390_COMMAND_STP, D8390_DCR_FT1, D8390_DCR_LS, D8390_DCR_WTS, D8390_P0_COMMAND, D8390_P0_DCR, D8390_P0_PSTART, D8390_P0_PSTOP, D8390_P0_RCR, D8390_RCR_MON, D8390_TXBUF_SIZE, DBG, ETH_ALEN, eth_asic_base, eth_bmem, eth_drain_receiver, eth_flags, eth_memsize, eth_nic_base, eth_ntoa(), eth_pio_read(), eth_pio_write(), eth_rmem, eth_rx_start, eth_tx_start, eth_vendor, FLAG_16BIT, FLAG_790, FLAG_PIO, nic::flags, GENERIC_ISAPNP_VENDOR, htons, inb, nic::ioaddr, pci_device::ioaddr, nic::irqno, ISA_MAX_ADDR, MEM_16384, MEM_32768, MEM_8192, memcmp(), memset(), NE_ASIC_OFFSET, NE_RESET, nic::nic_op, nic::node_addr, ns8390_operations, ns8390_reset(), NULL, outb, printf(), test, TYPE_SMC8216C, TYPE_SMC8216T, TYPE_WD8013EP, VENDOR_3COM, VENDOR_NONE, VENDOR_NOVELL, VENDOR_WD, WD_BID, WD_DEFAULT_MEM, WD_HIGH_BASE, WD_ICR, WD_ICR_16BIT, WD_LAAR, WD_LAAR_L16EN, WD_LAAR_M16EN, WD_LAR, WD_LOW_BASE, WD_MSR, WD_MSR_MENB, WD_NIC_ADDR, and WD_SOFTCONFIG.

◆ PCI_DRIVER()

PCI_DRIVER ( nepci_driver ,
nepci_nics ,
PCI_NO_CLASS  )

References nepci_nics.

◆ DRIVER()

DRIVER ( "NE2000/PCI" ,
nic_driver ,
pci_driver ,
nepci_driver ,
nepci_probe ,
ns8390_disable ,
no_fake_bss  )

References no_fake_bss, and ns8390_disable().

Variable Documentation

◆ eth_vendor

unsigned char eth_vendor
static

Definition at line 51 of file ns8390.c.

◆ eth_flags

unsigned char eth_flags
static

Definition at line 51 of file ns8390.c.

◆ eth_nic_base

unsigned short eth_nic_base
static

Definition at line 55 of file ns8390.c.

◆ eth_asic_base

unsigned short eth_asic_base
static

Definition at line 55 of file ns8390.c.

◆ eth_memsize

unsigned char eth_memsize
static

Definition at line 56 of file ns8390.c.

◆ eth_rx_start

unsigned char eth_rx_start
static

Definition at line 56 of file ns8390.c.

◆ eth_tx_start

unsigned char eth_tx_start
static

Definition at line 56 of file ns8390.c.

◆ eth_bmem

Address eth_bmem
static

Definition at line 57 of file ns8390.c.

◆ eth_rmem

Address eth_rmem
static

Definition at line 57 of file ns8390.c.

◆ eth_drain_receiver

unsigned char eth_drain_receiver
static

Definition at line 58 of file ns8390.c.

◆ ns8390_operations

struct nic_operations ns8390_operations
static
Initial value:
= {
.connect = dummy_connect,
.poll = ns8390_poll,
.transmit = ns8390_transmit,
.irq = ns8390_irq,
}
int dummy_connect(struct nic *nic __unused)
Definition legacy.c:175
static void ns8390_irq(struct nic *nic __unused, irq_action_t action __unused)
Definition ns8390.c:607
static void ns8390_transmit(struct nic *nic, const char *d, unsigned int t, unsigned int s, const char *p)
Definition ns8390.c:403

Definition at line 619 of file ns8390.c.

Referenced by eth_probe().

◆ nepci_nics

struct pci_device_id nepci_nics[]
static
Initial value:
= {
PCI_ROM(0x1050, 0x0940, "winbond940", "Winbond NE2000-PCI", 0),
PCI_ROM(0x1050, 0x5a5a, "winbond940f", "Winbond W89c940F", 0),
PCI_ROM(0x10bd, 0x0e34, "surecom-ne34", "Surecom NE34", 0),
PCI_ROM(0x10ec, 0x8029, "rtl8029", "Realtek 8029", 0),
PCI_ROM(0x1106, 0x0926, "via86c926", "Via 86c926", 0),
PCI_ROM(0x1186, 0x0300, "dlink-528", "D-Link DE-528", 0),
PCI_ROM(0x11f6, 0x1401, "compexrl2000", "Compex ReadyLink 2000", 0),
PCI_ROM(0x12c3, 0x0058, "holtek80232", "Holtek HT80232", 0),
PCI_ROM(0x12c3, 0x5598, "holtek80229", "Holtek HT80229", 0),
PCI_ROM(0x4a14, 0x5000, "nv5000sc", "NetVin NV5000SC", 0),
PCI_ROM(0x8e2e, 0x3000, "ktiet32p2", "KTI ET32P2", 0),
}
#define PCI_ROM(_vendor, _device, _name, _description, _data)
Definition pci.h:308

Definition at line 1007 of file ns8390.c.

1007 {
1008/* A few NE2000 PCI clones, list not exhaustive */
1009PCI_ROM(0x1050, 0x0940, "winbond940", "Winbond NE2000-PCI", 0), /* Winbond 86C940 / 89C940 */
1010PCI_ROM(0x1050, 0x5a5a, "winbond940f", "Winbond W89c940F", 0), /* Winbond 89C940F */
1011PCI_ROM(0x10bd, 0x0e34, "surecom-ne34", "Surecom NE34", 0),
1012PCI_ROM(0x10ec, 0x8029, "rtl8029", "Realtek 8029", 0),
1013PCI_ROM(0x1106, 0x0926, "via86c926", "Via 86c926", 0),
1014PCI_ROM(0x1186, 0x0300, "dlink-528", "D-Link DE-528", 0),
1015PCI_ROM(0x11f6, 0x1401, "compexrl2000", "Compex ReadyLink 2000", 0),
1016PCI_ROM(0x12c3, 0x0058, "holtek80232", "Holtek HT80232", 0),
1017PCI_ROM(0x12c3, 0x5598, "holtek80229", "Holtek HT80229", 0),
1018PCI_ROM(0x4a14, 0x5000, "nv5000sc", "NetVin NV5000SC", 0),
1019PCI_ROM(0x8e2e, 0x3000, "ktiet32p2", "KTI ET32P2", 0),
1020};

Referenced by PCI_DRIVER().