iPXE
ne2k_isa.c
Go to the documentation of this file.
1/**************************************************************************
2 ETHERBOOT - BOOTP/TFTP Bootstrap Program
3
4 Author: Martin Renters
5 Date: May/94
6
7 This code is based heavily on David Greenman's if_ed.c driver
8
9 Copyright (C) 1993-1994, David Greenman, Martin Renters.
10 This software may be used, modified, copied, distributed, and sold, in
11 both source and binary form provided that the above copyright and these
12 terms are retained. Under no circumstances are the authors responsible for
13 the proper functioning of this software, nor do the authors assume any
14 responsibility for damages incurred with its use.
15
16 Multicast support added by Timothy Legge (timlegge@users.sourceforge.net) 09/28/2003
17 Relocation support added by Ken Yap (ken_yap@users.sourceforge.net) 28/12/02
18 Card Detect support adapted from the eCos driver (Christian Plessl <cplessl@ee.ethz.ch>)
19 Extracted from ns8390.c and adapted by Pantelis Koukousoulas <pktoss@gmail.com>
20 **************************************************************************/
21
22FILE_LICENCE ( BSD2 );
23
24#include "ns8390.h"
25#include "etherboot.h"
26#include "nic.h"
27#include <ipxe/ethernet.h>
28#include <ipxe/isa.h>
29#include <errno.h>
30
31#define ASIC_PIO NE_DATA
32
33static unsigned char eth_vendor, eth_flags;
34static unsigned short eth_nic_base, eth_asic_base;
35static unsigned char eth_memsize, eth_rx_start, eth_tx_start;
37static unsigned char eth_drain_receiver;
38
40static void ne_reset(struct nic *nic, struct isa_device *isa);
41
42static isa_probe_addr_t ne_probe_addrs[] = { 0x300, 0x280, 0x320, 0x340, 0x380, 0x220, };
43
44/**************************************************************************
45 ETH_PIO_READ - Read a frame via Programmed I/O
46 **************************************************************************/
47static void eth_pio_read(unsigned int src, unsigned char *dst, unsigned int cnt) {
50 outb(cnt >> 8, eth_nic_base + D8390_P0_RBCR1);
55 cnt = (cnt + 1) >> 1;
56
57 while (cnt--) {
58 if (eth_flags & FLAG_16BIT) {
59 *((unsigned short *) dst) = inw(eth_asic_base + ASIC_PIO);
60 dst += 2;
61 } else
62 *(dst++) = inb(eth_asic_base + ASIC_PIO);
63 }
64}
65
66/**************************************************************************
67 ETH_PIO_WRITE - Write a frame via Programmed I/O
68 **************************************************************************/
69static void eth_pio_write(const unsigned char *src, unsigned int dst,
70 unsigned int cnt) {
74 outb(cnt >> 8, eth_nic_base + D8390_P0_RBCR1);
76 outb(dst >> 8, eth_nic_base + D8390_P0_RSAR1);
79 cnt = (cnt + 1) >> 1;
80
81 while (cnt--) {
82
83 if (eth_flags & FLAG_16BIT) {
84 outw(*((unsigned short *) src), eth_asic_base + ASIC_PIO);
85 src += 2;
86 } else
88 }
89}
90
91/**************************************************************************
92 enable_multicast - Enable Multicast
93 **************************************************************************/
94static void enable_multicast(unsigned short eth_nic_base) {
95 unsigned char mcfilter[8];
96 int i;
97
98 memset(mcfilter, 0xFF, 8);
101 for (i = 0; i < 8; i++) {
102 outb(mcfilter[i], eth_nic_base + 8 + i);
103 if (inb(eth_nic_base + 8 + i) != mcfilter[i])
104 DBG("Error SMC 83C690 Multicast filter read/write mishap %d\n",
105 i);
106 }
108 outb(4 | 0x08, eth_nic_base + D8390_P0_RCR);
109}
110
111/**************************************************************************
112 NE_PROBE1 - Look for an adapter on the ISA bus
113 **************************************************************************/
115 //From the eCos driver
116 unsigned int regd;
117 unsigned int state;
118
119 state = inb(ioaddr);
121 regd = inb(ioaddr + D8390_P0_TCR);
122
123 if (inb(ioaddr + D8390_P0_TCR)) {
124 outb(ioaddr, state);
125 outb(ioaddr + 0x0d, regd);
126 return 0;
127 }
128
129 return 1;
130}
131
132/**************************************************************************
133 NE_PROBE - Initialize an adapter ???
134 **************************************************************************/
135static int ne_probe(struct nic *nic, struct isa_device *isa) {
136 int i;
137 unsigned char c;
138 unsigned char romdata[16];
139 unsigned char testbuf[32];
140
143
144 nic->irqno = 0;
145 nic->ioaddr = isa->ioaddr;
146 eth_nic_base = isa->ioaddr;
147
148 /******************************************************************
149 Search for NE1000/2000 if no WD/SMC or 3com cards
150 ******************************************************************/
151 if (eth_vendor == VENDOR_NONE) {
152
153 static unsigned char test[] = "NE*000 memory";
154
155 eth_bmem = 0; /* No shared memory */
156
160 eth_tx_start = 32;
164 (void) inb(0x84);
171 eth_pio_write((unsigned char *) test, 8192, sizeof(test));
172 eth_pio_read(8192, testbuf, sizeof(test));
173 if (!memcmp(test, testbuf, sizeof(test)))
174 goto out;
177 eth_tx_start = 64;
180 + D8390_P0_DCR);
183 eth_pio_write((unsigned char *) test, 16384, sizeof(test));
184 eth_pio_read(16384, testbuf, sizeof(test));
185 if (!memcmp(testbuf, test, sizeof(test)))
186 goto out;
187
188
189out:
190 if (eth_nic_base == 0)
191 return (0);
192 if (eth_nic_base > ISA_MAX_ADDR) /* PCI probably */
195 eth_pio_read(0, romdata, sizeof(romdata));
196 for (i = 0; i < ETH_ALEN; i++) {
197 nic->node_addr[i] = romdata[i + ((eth_flags & FLAG_16BIT) ? i : 0)];
198 }
200 DBG("\nNE%c000 base %4.4x, MAC Addr %s\n",
201 (eth_flags & FLAG_16BIT) ? '2' : '1', eth_nic_base, eth_ntoa(
202 nic->node_addr));
203 }
204
205 if (eth_vendor == VENDOR_NONE)
206 return (0);
207
208 if (eth_vendor != VENDOR_3COM)
210
211 ne_reset(nic, isa);
213 return 1;
214}
215
216
217/**************************************************************************
218 NE_DISABLE - Turn off adapter
219 **************************************************************************/
220static void ne_disable(struct nic *nic, struct isa_device *isa) {
221 ne_reset(nic, isa);
222}
223
224
225/**************************************************************************
226 NE_RESET - Reset adapter
227 **************************************************************************/
266
267
268/**************************************************************************
269 NE_POLL - Wait for a frame
270 **************************************************************************/
271static int ne_poll(struct nic *nic __unused, int retrieve __unused)
272{
273 int ret = 0;
274 unsigned char rstat, curr, next;
275 unsigned short len, frag;
276 unsigned short pktoff;
277 unsigned char *p;
278 struct ringbuffer pkthdr;
279
281 if (!(rstat & D8390_RSTAT_PRX)) return(0);
287 if (curr >= eth_memsize) curr=eth_rx_start;
288 if (curr == next) return(0);
289
290 if ( ! retrieve ) return 1;
291
292 pktoff = next << 8;
293 if (eth_flags & FLAG_PIO)
294 eth_pio_read(pktoff, (unsigned char *)&pkthdr, 4);
295 else
296 memcpy(&pkthdr, bus_to_virt(eth_rmem + pktoff), 4);
297 pktoff += sizeof(pkthdr);
298 /* incoming length includes FCS so must sub 4 */
299 len = pkthdr.len - 4;
300 if ((pkthdr.status & D8390_RSTAT_PRX) == 0 || len < ETH_ZLEN
301 || len> ETH_FRAME_LEN) {
302 DBG("Bogus packet, ignoring\n");
303 return (0);
304 }
305 else {
306 p = nic->packet;
307 nic->packetlen = len; /* available to caller */
308 frag = (eth_memsize << 8) - pktoff;
309 if (len> frag) { /* We have a wrap-around */
310 /* read first part */
311 if (eth_flags & FLAG_PIO)
312 eth_pio_read(pktoff, p, frag);
313 else
314 memcpy(p, bus_to_virt(eth_rmem + pktoff), frag);
315 pktoff = eth_rx_start << 8;
316 p += frag;
317 len -= frag;
318 }
319 /* read second part */
320 if (eth_flags & FLAG_PIO)
321 eth_pio_read(pktoff, p, len);
322 else
323 memcpy(p, bus_to_virt(eth_rmem + pktoff), len);
324 ret = 1;
325 }
326 next = pkthdr.next; /* frame number of next packet */
327 if (next == eth_rx_start)
330 return(ret);
331}
332
333
334/**************************************************************************
335 NE_TRANSMIT - Transmit a frame
336 **************************************************************************/
337static void ne_transmit(struct nic *nic, const char *d, /* Destination */
338unsigned int t, /* Type */
339unsigned int s, /* size */
340const char *p) { /* Packet */
341
342 /* Programmed I/O */
343 unsigned short type;
344 type = (t >> 8) | (t << 8);
345 eth_pio_write((unsigned char *) d, eth_tx_start << 8, ETH_ALEN);
347 /* bcc generates worse code without (const+const) below */
348 eth_pio_write((unsigned char *) &type, (eth_tx_start << 8) + (ETH_ALEN
349 + ETH_ALEN), 2);
350 eth_pio_write((unsigned char *) p, (eth_tx_start << 8) + ETH_HLEN, s);
351 s += ETH_HLEN;
352 if (s < ETH_ZLEN)
353 s = ETH_ZLEN;
354
360
363}
364
365static struct nic_operations ne_operations = { .connect = dummy_connect,
366 .poll = ne_poll, .transmit = ne_transmit, .irq = dummy_irq,
367};
368
370 GENERIC_ISAPNP_VENDOR, 0x0600 );
371
372DRIVER ( "ne", nic_driver, isapnp_driver, ne_driver,
374
375ISA_ROM("ne","NE1000/2000 and clones");
static unsigned short eth_nic_base
Definition 3c595.c:38
__be32 out[4]
Definition CIB_PRM.h:8
static const void * src
Definition string.h:48
static unsigned long ioaddr
Definition davicom.c:129
uint32_t next
Next descriptor address.
Definition dwmac.h:11
ring len
Length.
Definition dwmac.h:226
uint32_t type
Operating system type.
Definition ena.h:1
static int test
Definition epic100.c:73
Error codes.
uint8_t state
State.
Definition eth_slow.h:36
unsigned long Address
Definition etherboot.h:21
const char * eth_ntoa(const void *ll_addr)
Transcribe Ethernet address.
Definition ethernet.c:176
Ethernet protocol.
#define __unused
Declare a variable or data structure as unused.
Definition compiler.h:573
#define DBG(...)
Print a debugging message.
Definition compiler.h:498
#define FILE_LICENCE(_licence)
Declare a particular licence as applying to a file.
Definition compiler.h:896
#define ETH_ZLEN
Definition if_ether.h:11
#define ETH_FRAME_LEN
Definition if_ether.h:12
#define ETH_ALEN
Definition if_ether.h:9
#define ETH_HLEN
Definition if_ether.h:10
#define inw(io_addr)
Definition io.h:292
#define outb(data, io_addr)
Definition io.h:310
static __always_inline void * bus_to_virt(unsigned long bus_addr)
Convert bus address to a virtual address.
Definition io.h:196
#define outw(data, io_addr)
Definition io.h:320
#define inb(io_addr)
Definition io.h:283
uint16_t isa_probe_addr_t
Definition isa.h:31
#define ISA_ROM(IMAGE, DESCRIPTION)
Definition isa.h:92
void * memcpy(void *dest, const void *src, size_t len) __nonnull
void * memset(void *dest, int character, size_t len) __nonnull
#define GENERIC_ISAPNP_VENDOR
Definition isa_ids.h:38
int dummy_connect(struct nic *nic __unused)
Definition legacy.c:175
void dummy_irq(struct nic *nic __unused, irq_action_t irq_action __unused)
Definition legacy.c:179
static void enable_multicast(unsigned short eth_nic_base)
Definition ne2k_isa.c:94
static unsigned char eth_drain_receiver
Definition ne2k_isa.c:37
static Address eth_rmem
Definition ne2k_isa.c:36
static void ne_disable(struct nic *nic, struct isa_device *isa)
Definition ne2k_isa.c:220
static Address eth_bmem
Definition ne2k_isa.c:36
static void ne_reset(struct nic *nic, struct isa_device *isa)
static unsigned char eth_vendor
Definition ne2k_isa.c:33
static void eth_pio_write(const unsigned char *src, unsigned int dst, unsigned int cnt)
Definition ne2k_isa.c:69
#define ASIC_PIO
Definition ne2k_isa.c:31
static isa_probe_addr_t ne_probe_addrs[]
Definition ne2k_isa.c:42
static int ne_poll(struct nic *nic __unused, int retrieve __unused)
Definition ne2k_isa.c:271
static int ne_probe(struct nic *nic, struct isa_device *isa)
Definition ne2k_isa.c:135
static void eth_pio_read(unsigned int src, unsigned char *dst, unsigned int cnt)
Definition ne2k_isa.c:47
static unsigned char eth_tx_start
Definition ne2k_isa.c:35
static int ne_probe1(isa_probe_addr_t ioaddr)
Definition ne2k_isa.c:114
static struct nic_operations ne_operations
Definition ne2k_isa.c:39
static unsigned short eth_asic_base
Definition ne2k_isa.c:34
static void ne_transmit(struct nic *nic, const char *d, unsigned int t, unsigned int s, const char *p)
Definition ne2k_isa.c:337
static unsigned char eth_rx_start
Definition ne2k_isa.c:35
static unsigned char eth_flags
Definition ne2k_isa.c:33
static unsigned char eth_memsize
Definition ne2k_isa.c:35
#define DRIVER(_name_text, _unused2, _unused3, _name, _probe, _disable, _fake_bss)
Definition nic.h:220
#define ISA_DRIVER(_name, _probe_addrs, _probe_addr, _vendor_id, _prod_id)
Definition nic.h:188
struct @002057171240057303273132130141036221271355330106 no_fake_bss
#define VENDOR_NONE
Definition ns8390.h:11
#define D8390_P0_PSTOP
Definition ns8390.h:170
#define VENDOR_NOVELL
Definition ns8390.h:13
#define D8390_P0_BOUND
Definition ns8390.h:171
#define D8390_RSTAT_PRX
Definition ns8390.h:221
#define NE_ASIC_OFFSET
Definition ns8390.h:159
#define D8390_COMMAND_STA
Definition ns8390.h:203
#define D8390_P0_IMR
Definition ns8390.h:185
#define D8390_P0_TBCR1
Definition ns8390.h:175
#define D8390_COMMAND_PS1
Definition ns8390.h:197
#define D8390_DCR_WTS
Definition ns8390.h:210
#define D8390_P0_RBCR1
Definition ns8390.h:180
#define D8390_P0_DCR
Definition ns8390.h:184
#define D8390_P0_PSTART
Definition ns8390.h:169
#define D8390_P0_COMMAND
Definition ns8390.h:168
#define D8390_P0_RSAR1
Definition ns8390.h:178
#define D8390_P0_TBCR0
Definition ns8390.h:174
#define D8390_P0_RSAR0
Definition ns8390.h:177
#define D8390_COMMAND_PS0
Definition ns8390.h:196
#define MEM_8192
Definition ns8390.h:20
#define NE_RESET
Definition ns8390.h:160
#define D8390_COMMAND_RD0
Definition ns8390.h:201
#define D8390_COMMAND_RD1
Definition ns8390.h:200
#define D8390_P0_TPSR
Definition ns8390.h:173
#define D8390_DCR_LS
Definition ns8390.h:209
#define D8390_P0_ISR
Definition ns8390.h:176
#define D8390_P0_RBCR0
Definition ns8390.h:179
#define MEM_16384
Definition ns8390.h:21
#define D8390_P1_PAR0
Definition ns8390.h:187
#define MEM_32768
Definition ns8390.h:22
#define D8390_TXBUF_SIZE
Definition ns8390.h:226
#define ISA_MAX_ADDR
Definition ns8390.h:24
#define D8390_ISR_RDC
Definition ns8390.h:218
#define D8390_P0_RSR
Definition ns8390.h:181
#define D8390_P0_RCR
Definition ns8390.h:182
#define FLAG_PIO
Definition ns8390.h:16
#define D8390_COMMAND_TXP
Definition ns8390.h:202
#define VENDOR_3COM
Definition ns8390.h:14
#define D8390_DCR_FT1
Definition ns8390.h:208
#define D8390_P0_TCR
Definition ns8390.h:183
#define FLAG_16BIT
Definition ns8390.h:17
#define D8390_COMMAND_RD2
Definition ns8390.h:199
#define D8390_P1_MAR0
Definition ns8390.h:194
#define D8390_COMMAND_STP
Definition ns8390.h:204
#define D8390_P1_CURR
Definition ns8390.h:193
#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
An ISA device.
Definition isa.h:12
uint16_t ioaddr
I/O address.
Definition isa.h:16
An ISAPnP driver.
Definition isapnp.h:199
Definition nic.h:49
unsigned char * packet
Definition nic.h:53
unsigned char * node_addr
Definition nic.h:52
unsigned int packetlen
Definition nic.h:54
unsigned char irqno
Definition nic.h:56
unsigned int ioaddr
Definition nic.h:55
struct nic_operations * nic_op
Definition nic.h:50
unsigned char status
Definition ns8390.h:231
unsigned short len
Definition ns8390.h:233
unsigned char next
Definition ns8390.h:232