iPXE
Defines | Functions | Variables
ne2k_isa.c File Reference
#include "ns8390.h"
#include "etherboot.h"
#include "nic.h"
#include <ipxe/ethernet.h>
#include <ipxe/isa.h>
#include <errno.h>

Go to the source code of this file.

Defines

#define ASIC_PIO   NE_DATA

Functions

 FILE_LICENCE (BSD2)
static void ne_reset (struct nic *nic, struct isa_device *isa)
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 int ne_probe1 (isa_probe_addr_t ioaddr)
static int ne_probe (struct nic *nic, struct isa_device *isa)
static void ne_disable (struct nic *nic, struct isa_device *isa)
static void ne_reset (struct nic *nic, struct isa_device *isa __unused)
static int ne_poll (struct nic *nic __unused, int retrieve __unused)
static void ne_transmit (struct nic *nic, const char *d, unsigned int t, unsigned int s, const char *p)
 ISA_DRIVER (ne_driver, ne_probe_addrs, ne_probe1, GENERIC_ISAPNP_VENDOR, 0x0600)
 DRIVER ("ne", nic_driver, isapnp_driver, ne_driver, ne_probe, ne_disable)
 ISA_ROM ("ne","NE1000/2000 and clones")

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 ne_operations
static isa_probe_addr_t ne_probe_addrs [] = { 0x300, 0x280, 0x320, 0x340, 0x380, 0x220, }

Define Documentation

#define ASIC_PIO   NE_DATA

Definition at line 31 of file ne2k_isa.c.

Referenced by eth_pio_read(), and eth_pio_write().


Function Documentation

FILE_LICENCE ( BSD2  )
static void ne_reset ( struct nic nic,
struct isa_device isa 
) [static]

Referenced by ne_disable(), and ne_probe().

static void eth_pio_read ( unsigned int  src,
unsigned char *  dst,
unsigned int  cnt 
) [static]
static void eth_pio_write ( const unsigned char *  src,
unsigned int  dst,
unsigned int  cnt 
) [static]
static void enable_multicast ( unsigned short  eth_nic_base) [static]

Definition at line 94 of file ne2k_isa.c.

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

Referenced by ne_reset().

                                                          {
        unsigned char mcfilter[8];
        int i;

        memset(mcfilter, 0xFF, 8);
        outb(4, eth_nic_base + D8390_P0_RCR);
        outb(D8390_COMMAND_RD2 + D8390_COMMAND_PS1, eth_nic_base + D8390_P0_COMMAND);
        for (i = 0; i < 8; i++) {
                outb(mcfilter[i], eth_nic_base + 8 + i);
                if (inb(eth_nic_base + 8 + i) != mcfilter[i])
                        DBG("Error SMC 83C690 Multicast filter read/write mishap %d\n",
                                        i);
        }
        outb(D8390_COMMAND_RD2 + D8390_COMMAND_PS0, eth_nic_base + D8390_P0_COMMAND);
        outb(4 | 0x08, eth_nic_base + D8390_P0_RCR);
}
static int ne_probe1 ( isa_probe_addr_t  ioaddr) [static]

Definition at line 114 of file ne2k_isa.c.

References D8390_COMMAND_PS1, D8390_COMMAND_RD2, D8390_COMMAND_STP, D8390_P0_TCR, inb(), outb(), and state.

                                              {
        //From the eCos driver
        unsigned int regd;
        unsigned int state;

        state = inb(ioaddr);
        outb(ioaddr, D8390_COMMAND_RD2 | D8390_COMMAND_PS1 | D8390_COMMAND_STP);
        regd = inb(ioaddr + D8390_P0_TCR);

        if (inb(ioaddr + D8390_P0_TCR)) {
                outb(ioaddr, state);
                outb(ioaddr + 0x0d, regd);
                return 0;
        }

        return 1;
}
static int ne_probe ( struct nic nic,
struct isa_device isa 
) [static]

Definition at line 135 of file ne2k_isa.c.

References 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_PIO, inb(), isa_device::ioaddr, ISA_MAX_ADDR, MEM_16384, MEM_32768, MEM_8192, memcmp(), NE_ASIC_OFFSET, ne_operations, ne_reset(), NE_RESET, out, outb(), test, VENDOR_3COM, VENDOR_NONE, and VENDOR_NOVELL.

                                                             {
        int i;
        unsigned char c;
        unsigned char romdata[16];
        unsigned char testbuf[32];

        eth_vendor = VENDOR_NONE;
        eth_drain_receiver = 0;

        nic->irqno = 0;
        nic->ioaddr = isa->ioaddr;
        eth_nic_base = isa->ioaddr;

        /******************************************************************
         Search for NE1000/2000 if no WD/SMC or 3com cards
         ******************************************************************/
        if (eth_vendor == VENDOR_NONE) {

                static unsigned char test[] = "NE*000 memory";

                eth_bmem = 0; /* No shared memory */

                eth_flags = FLAG_PIO;
                eth_asic_base = eth_nic_base + NE_ASIC_OFFSET;
                eth_memsize = MEM_16384;
                eth_tx_start = 32;
                eth_rx_start = 32 + D8390_TXBUF_SIZE;
                c = inb(eth_asic_base + NE_RESET);
                outb(c, eth_asic_base + NE_RESET);
                (void) inb(0x84);
                outb(D8390_COMMAND_STP | D8390_COMMAND_RD2, eth_nic_base
                                + D8390_P0_COMMAND);
                outb(D8390_RCR_MON, eth_nic_base + D8390_P0_RCR);
                outb(D8390_DCR_FT1 | D8390_DCR_LS, eth_nic_base + D8390_P0_DCR);
                outb(MEM_8192, eth_nic_base + D8390_P0_PSTART);
                outb(MEM_16384, eth_nic_base + D8390_P0_PSTOP);
                eth_pio_write((unsigned char *) test, 8192, sizeof(test));
                eth_pio_read(8192, testbuf, sizeof(test));
                if (!memcmp(test, testbuf, sizeof(test)))
                        goto out;
                eth_flags |= FLAG_16BIT;
                eth_memsize = MEM_32768;
                eth_tx_start = 64;
                eth_rx_start = 64 + D8390_TXBUF_SIZE;
                outb(D8390_DCR_WTS | D8390_DCR_FT1 | D8390_DCR_LS, eth_nic_base
                                + D8390_P0_DCR);
                outb(MEM_16384, eth_nic_base + D8390_P0_PSTART);
                outb(MEM_32768, eth_nic_base + D8390_P0_PSTOP);
                eth_pio_write((unsigned char *) test, 16384, sizeof(test));
                eth_pio_read(16384, testbuf, sizeof(test));
                if (!memcmp(testbuf, test, sizeof(test)))
                        goto out;


out:
                if (eth_nic_base == 0)
                        return (0);
                if (eth_nic_base > ISA_MAX_ADDR) /* PCI probably */
                        eth_flags |= FLAG_16BIT;
                eth_vendor = VENDOR_NOVELL;
                eth_pio_read(0, romdata, sizeof(romdata));
                for (i = 0; i < ETH_ALEN; i++) {
                        nic->node_addr[i] = romdata[i + ((eth_flags & FLAG_16BIT) ? i : 0)];
                }
                nic->ioaddr = eth_nic_base;
                DBG("\nNE%c000 base %4.4x, MAC Addr %s\n",
                                (eth_flags & FLAG_16BIT) ? '2' : '1', eth_nic_base, eth_ntoa(
                                                nic->node_addr));
        }

        if (eth_vendor == VENDOR_NONE)
                return (0);

        if (eth_vendor != VENDOR_3COM)
                eth_rmem = eth_bmem;

        ne_reset(nic, isa);
        nic->nic_op = &ne_operations;
        return 1;
}
static void ne_disable ( struct nic nic,
struct isa_device isa 
) [static]

Definition at line 220 of file ne2k_isa.c.

References ne_reset().

                                                                {
        ne_reset(nic, isa);
}
static void ne_reset ( struct nic nic,
struct isa_device *isa  __unused 
) [static]

Definition at line 228 of file ne2k_isa.c.

References 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_drain_receiver, eth_flags, eth_memsize, eth_nic_base, eth_rx_start, eth_tx_start, FLAG_16BIT, and outb().

static int ne_poll ( struct nic *nic  __unused,
int retrieve  __unused 
) [static]

Definition at line 271 of file ne2k_isa.c.

References bus_to_virt(), D8390_COMMAND_PS0, D8390_COMMAND_PS1, D8390_P0_BOUND, D8390_P0_COMMAND, D8390_P0_RSR, D8390_P1_CURR, D8390_RSTAT_PRX, DBG, eth_flags, ETH_FRAME_LEN, eth_memsize, eth_nic_base, eth_pio_read(), eth_rmem, eth_rx_start, ETH_ZLEN, FLAG_PIO, inb(), len, memcpy(), next, nic, outb(), and ret.

{
        int ret = 0;
        unsigned char rstat, curr, next;
        unsigned short len, frag;
        unsigned short pktoff;
        unsigned char *p;
        struct ringbuffer pkthdr;

        rstat = inb(eth_nic_base+D8390_P0_RSR);
        if (!(rstat & D8390_RSTAT_PRX)) return(0);
        next = inb(eth_nic_base+D8390_P0_BOUND)+1;
        if (next >= eth_memsize) next = eth_rx_start;
        outb(D8390_COMMAND_PS1, eth_nic_base+D8390_P0_COMMAND);
        curr = inb(eth_nic_base+D8390_P1_CURR);
        outb(D8390_COMMAND_PS0, eth_nic_base+D8390_P0_COMMAND);
        if (curr >= eth_memsize) curr=eth_rx_start;
        if (curr == next) return(0);

        if ( ! retrieve ) return 1;

        pktoff = next << 8;
        if (eth_flags & FLAG_PIO)
        eth_pio_read(pktoff, (unsigned char *)&pkthdr, 4);
        else
        memcpy(&pkthdr, bus_to_virt(eth_rmem + pktoff), 4);
        pktoff += sizeof(pkthdr);
        /* incoming length includes FCS so must sub 4 */
        len = pkthdr.len - 4;
        if ((pkthdr.status & D8390_RSTAT_PRX) == 0 || len < ETH_ZLEN
                        || len> ETH_FRAME_LEN) {
                DBG("Bogus packet, ignoring\n");
                return (0);
        }
        else {
                p = nic->packet;
                nic->packetlen = len; /* available to caller */
                frag = (eth_memsize << 8) - pktoff;
                if (len> frag) { /* We have a wrap-around */
                        /* read first part */
                        if (eth_flags & FLAG_PIO)
                        eth_pio_read(pktoff, p, frag);
                        else
                        memcpy(p, bus_to_virt(eth_rmem + pktoff), frag);
                        pktoff = eth_rx_start << 8;
                        p += frag;
                        len -= frag;
                }
                /* read second part */
                if (eth_flags & FLAG_PIO)
                eth_pio_read(pktoff, p, len);
                else
                memcpy(p, bus_to_virt(eth_rmem + pktoff), len);
                ret = 1;
        }
        next = pkthdr.next; /* frame number of next packet */
        if (next == eth_rx_start)
        next = eth_memsize;
        outb(next-1, eth_nic_base+D8390_P0_BOUND);
        return(ret);
}
static void ne_transmit ( struct nic nic,
const char *  d,
unsigned int  t,
unsigned int  s,
const char *  p 
) [static]

Definition at line 337 of file ne2k_isa.c.

References 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_HLEN, eth_nic_base, eth_pio_write(), eth_tx_start, ETH_ZLEN, outb(), and type.

               { /* Packet */

        /* Programmed I/O */
        unsigned short type;
        type = (t >> 8) | (t << 8);
        eth_pio_write((unsigned char *) d, eth_tx_start << 8, ETH_ALEN);
        eth_pio_write(nic->node_addr, (eth_tx_start << 8) + ETH_ALEN, ETH_ALEN);
        /* bcc generates worse code without (const+const) below */
        eth_pio_write((unsigned char *) &type, (eth_tx_start << 8) + (ETH_ALEN
                        + ETH_ALEN), 2);
        eth_pio_write((unsigned char *) p, (eth_tx_start << 8) + ETH_HLEN, s);
        s += ETH_HLEN;
        if (s < ETH_ZLEN)
                s = ETH_ZLEN;

        outb(D8390_COMMAND_PS0 | D8390_COMMAND_RD2 | D8390_COMMAND_STA,
                        eth_nic_base + D8390_P0_COMMAND);
        outb(eth_tx_start, eth_nic_base + D8390_P0_TPSR);
        outb(s, eth_nic_base + D8390_P0_TBCR0);
        outb(s >> 8, eth_nic_base + D8390_P0_TBCR1);

        outb(D8390_COMMAND_PS0 | D8390_COMMAND_TXP | D8390_COMMAND_RD2
                        | D8390_COMMAND_STA, eth_nic_base + D8390_P0_COMMAND);
}
ISA_DRIVER ( ne_driver  ,
ne_probe_addrs  ,
ne_probe1  ,
GENERIC_ISAPNP_VENDOR  ,
0x0600   
)
DRIVER ( "ne"  ,
nic_driver  ,
isapnp_driver  ,
ne_driver  ,
ne_probe  ,
ne_disable   
)
ISA_ROM ( "ne"  ,
"NE1000/2000 and clones"   
)

Variable Documentation

unsigned char eth_vendor [static]

Definition at line 33 of file ne2k_isa.c.

Referenced by ne_probe().

unsigned char eth_flags [static]

Definition at line 33 of file ne2k_isa.c.

Referenced by eth_pio_read(), eth_pio_write(), ne_poll(), ne_probe(), and ne_reset().

unsigned short eth_nic_base [static]

Definition at line 34 of file ne2k_isa.c.

Referenced by eth_pio_read(), eth_pio_write(), ne_poll(), ne_probe(), ne_reset(), and ne_transmit().

unsigned short eth_asic_base [static]

Definition at line 34 of file ne2k_isa.c.

Referenced by eth_pio_read(), eth_pio_write(), and ne_probe().

unsigned char eth_memsize [static]

Definition at line 35 of file ne2k_isa.c.

Referenced by ne_poll(), ne_probe(), and ne_reset().

unsigned char eth_rx_start [static]

Definition at line 35 of file ne2k_isa.c.

Referenced by ne_poll(), ne_probe(), and ne_reset().

unsigned char eth_tx_start [static]

Definition at line 35 of file ne2k_isa.c.

Referenced by ne_probe(), ne_reset(), and ne_transmit().

Address eth_bmem [static]

Definition at line 36 of file ne2k_isa.c.

Referenced by ne_probe().

Address eth_rmem [static]

Definition at line 36 of file ne2k_isa.c.

Referenced by ne_poll(), and ne_probe().

unsigned char eth_drain_receiver [static]

Definition at line 37 of file ne2k_isa.c.

Referenced by ne_probe(), and ne_reset().

static struct nic_operations ne_operations [static]
Initial value:
 { .connect = dummy_connect,
                .poll = ne_poll, .transmit = ne_transmit, .irq = dummy_irq,
}

Definition at line 39 of file ne2k_isa.c.

Referenced by ne_probe().

isa_probe_addr_t ne_probe_addrs[] = { 0x300, 0x280, 0x320, 0x340, 0x380, 0x220, } [static]

Definition at line 42 of file ne2k_isa.c.