summaryrefslogtreecommitdiff
path: root/gpxe/src/drivers/net/ne2k_isa.c
diff options
context:
space:
mode:
Diffstat (limited to 'gpxe/src/drivers/net/ne2k_isa.c')
-rw-r--r--gpxe/src/drivers/net/ne2k_isa.c375
1 files changed, 0 insertions, 375 deletions
diff --git a/gpxe/src/drivers/net/ne2k_isa.c b/gpxe/src/drivers/net/ne2k_isa.c
deleted file mode 100644
index 603d1edb..00000000
--- a/gpxe/src/drivers/net/ne2k_isa.c
+++ /dev/null
@@ -1,375 +0,0 @@
-/**************************************************************************
- ETHERBOOT - BOOTP/TFTP Bootstrap Program
-
- Author: Martin Renters
- Date: May/94
-
- This code is based heavily on David Greenman's if_ed.c driver
-
- Copyright (C) 1993-1994, David Greenman, Martin Renters.
- This software may be used, modified, copied, distributed, and sold, in
- both source and binary form provided that the above copyright and these
- terms are retained. Under no circumstances are the authors responsible for
- the proper functioning of this software, nor do the authors assume any
- responsibility for damages incurred with its use.
-
- Multicast support added by Timothy Legge (timlegge@users.sourceforge.net) 09/28/2003
- Relocation support added by Ken Yap (ken_yap@users.sourceforge.net) 28/12/02
- Card Detect support adapted from the eCos driver (Christian Plessl <cplessl@ee.ethz.ch>)
- Extracted from ns8390.c and adapted by Pantelis Koukousoulas <pktoss@gmail.com>
- **************************************************************************/
-
-FILE_LICENCE ( BSD2 );
-
-#include "ns8390.h"
-#include "etherboot.h"
-#include "nic.h"
-#include <gpxe/ethernet.h>
-#include <gpxe/isa.h>
-#include <errno.h>
-
-#define ASIC_PIO NE_DATA
-
-static unsigned char eth_vendor, eth_flags;
-static unsigned short eth_nic_base, eth_asic_base;
-static unsigned char eth_memsize, eth_rx_start, eth_tx_start;
-static Address eth_bmem, eth_rmem;
-static unsigned char eth_drain_receiver;
-
-static struct nic_operations ne_operations;
-static void ne_reset(struct nic *nic, struct isa_device *isa);
-
-static isa_probe_addr_t ne_probe_addrs[] = { 0x300, 0x280, 0x320, 0x340, 0x380, 0x220, };
-
-/**************************************************************************
- ETH_PIO_READ - Read a frame via Programmed I/O
- **************************************************************************/
-static void eth_pio_read(unsigned int src, unsigned char *dst, unsigned int cnt) {
- outb(D8390_COMMAND_RD2 | D8390_COMMAND_STA, eth_nic_base + D8390_P0_COMMAND);
- outb(cnt, eth_nic_base + D8390_P0_RBCR0);
- outb(cnt >> 8, eth_nic_base + D8390_P0_RBCR1);
- outb(src, eth_nic_base + D8390_P0_RSAR0);
- outb(src >> 8, eth_nic_base + D8390_P0_RSAR1);
- outb(D8390_COMMAND_RD0 | D8390_COMMAND_STA, eth_nic_base + D8390_P0_COMMAND);
- if (eth_flags & FLAG_16BIT)
- cnt = (cnt + 1) >> 1;
-
- while (cnt--) {
- if (eth_flags & FLAG_16BIT) {
- *((unsigned short *) dst) = inw(eth_asic_base + ASIC_PIO);
- dst += 2;
- } else
- *(dst++) = inb(eth_asic_base + ASIC_PIO);
- }
-}
-
-/**************************************************************************
- ETH_PIO_WRITE - Write a frame via Programmed I/O
- **************************************************************************/
-static void eth_pio_write(const unsigned char *src, unsigned int dst,
- unsigned int cnt) {
- outb(D8390_COMMAND_RD2 | D8390_COMMAND_STA, eth_nic_base + D8390_P0_COMMAND);
- outb(D8390_ISR_RDC, eth_nic_base + D8390_P0_ISR);
- outb(cnt, eth_nic_base + D8390_P0_RBCR0);
- outb(cnt >> 8, eth_nic_base + D8390_P0_RBCR1);
- outb(dst, eth_nic_base + D8390_P0_RSAR0);
- outb(dst >> 8, eth_nic_base + D8390_P0_RSAR1);
- outb(D8390_COMMAND_RD1 | D8390_COMMAND_STA, eth_nic_base + D8390_P0_COMMAND);
- if (eth_flags & FLAG_16BIT)
- cnt = (cnt + 1) >> 1;
-
- while (cnt--) {
-
- if (eth_flags & FLAG_16BIT) {
- outw(*((unsigned short *) src), eth_asic_base + ASIC_PIO);
- src += 2;
- } else
- outb(*(src++), eth_asic_base + ASIC_PIO);
- }
-}
-
-/**************************************************************************
- enable_multicast - Enable Multicast
- **************************************************************************/
-static void enable_multicast(unsigned short eth_nic_base) {
- 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);
-}
-
-/**************************************************************************
- NE_PROBE1 - Look for an adapter on the ISA bus
- **************************************************************************/
-static int ne_probe1(isa_probe_addr_t ioaddr) {
- //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;
-}
-
-/**************************************************************************
- NE_PROBE - Initialize an adapter ???
- **************************************************************************/
-static int ne_probe(struct nic *nic, struct isa_device *isa) {
- 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;
-}
-
-
-/**************************************************************************
- NE_DISABLE - Turn off adapter
- **************************************************************************/
-static void ne_disable(struct nic *nic, struct isa_device *isa) {
- ne_reset(nic, isa);
-}
-
-
-/**************************************************************************
- NE_RESET - Reset adapter
- **************************************************************************/
-static void ne_reset(struct nic *nic, struct isa_device *isa __unused)
-{
- int i;
-
- eth_drain_receiver = 0;
- outb(D8390_COMMAND_PS0 | D8390_COMMAND_RD2 |
- D8390_COMMAND_STP, eth_nic_base+D8390_P0_COMMAND);
- if (eth_flags & FLAG_16BIT)
- outb(0x49, eth_nic_base+D8390_P0_DCR);
- else
- outb(0x48, eth_nic_base+D8390_P0_DCR);
- outb(0, eth_nic_base+D8390_P0_RBCR0);
- outb(0, eth_nic_base+D8390_P0_RBCR1);
- outb(0x20, eth_nic_base+D8390_P0_RCR); /* monitor mode */
- outb(2, eth_nic_base+D8390_P0_TCR);
- outb(eth_tx_start, eth_nic_base+D8390_P0_TPSR);
- outb(eth_rx_start, eth_nic_base+D8390_P0_PSTART);
-
- outb(eth_memsize, eth_nic_base+D8390_P0_PSTOP);
- outb(eth_memsize - 1, eth_nic_base+D8390_P0_BOUND);
- outb(0xFF, eth_nic_base+D8390_P0_ISR);
- outb(0, eth_nic_base+D8390_P0_IMR);
- outb(D8390_COMMAND_PS1 |
- D8390_COMMAND_RD2 | D8390_COMMAND_STP, eth_nic_base+D8390_P0_COMMAND);
-
- for (i=0; i<ETH_ALEN; i++)
- outb(nic->node_addr[i], eth_nic_base+D8390_P1_PAR0+i);
- for (i=0; i<ETH_ALEN; i++)
- outb(0xFF, eth_nic_base+D8390_P1_MAR0+i);
- outb(eth_rx_start, eth_nic_base+D8390_P1_CURR);
- outb(D8390_COMMAND_PS0 |
- D8390_COMMAND_RD2 | D8390_COMMAND_STA, eth_nic_base+D8390_P0_COMMAND);
- outb(0xFF, eth_nic_base+D8390_P0_ISR);
- outb(0, eth_nic_base+D8390_P0_TCR); /* transmitter on */
- outb(4, eth_nic_base+D8390_P0_RCR); /* allow rx broadcast frames */
-
- enable_multicast(eth_nic_base);
-}
-
-
-/**************************************************************************
- NE_POLL - Wait for a frame
- **************************************************************************/
-static int ne_poll(struct nic *nic __unused, int retrieve __unused)
-{
- 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);
-}
-
-
-/**************************************************************************
- NE_TRANSMIT - Transmit a frame
- **************************************************************************/
-static void ne_transmit(struct nic *nic, const char *d, /* Destination */
-unsigned int t, /* Type */
-unsigned int s, /* size */
-const char *p) { /* 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);
-}
-
-static struct nic_operations ne_operations = { .connect = dummy_connect,
- .poll = ne_poll, .transmit = ne_transmit, .irq = dummy_irq,
-};
-
-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");