15b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project/**************************************************************************
25b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source ProjectEtherboot -  BOOTP/TFTP Bootstrap Program
35b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Projecti82586 NIC driver for Etherboot
45b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source ProjectKen Yap, January 1998
55b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project***************************************************************************/
65b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
75b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project/*
85b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project * This program is free software; you can redistribute it and/or
95b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project * modify it under the terms of the GNU General Public License as
105b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project * published by the Free Software Foundation; either version 2, or (at
115b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project * your option) any later version.
125b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project */
135b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
145b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project#include "etherboot.h"
155b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project#include "nic.h"
165b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project#include "cards.h"
175b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project#include "timer.h"
185b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
195b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project#define	udelay(n)	waiton_timer2(((n)*TICKS_PER_MS)/1000)
205b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
215b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project/* Sources of information:
225b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
235b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project   Donald Becker's excellent 3c507 driver in Linux
245b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project   Intel 82596 data sheet (yes, 82596; it has a 586 compatibility mode)
255b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project*/
265b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
275b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project/* Code below mostly stolen wholesale from 3c507.c driver in Linux */
285b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
295b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project/*
305b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project		Details of the i82586.
315b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
325b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project   You'll really need the databook to understand the details of this part,
335b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project   but the outline is that the i82586 has two separate processing units.
345b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project   Both are started from a list of three configuration tables, of which only
355b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project   the last, the System Control Block (SCB), is used after reset-time.  The SCB
365b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project   has the following fields:
375b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project		Status word
385b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project		Command word
395b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project		Tx/Command block addr.
405b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project		Rx block addr.
415b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project   The command word accepts the following controls for the Tx and Rx units:
425b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project  */
435b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
445b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project#define	CUC_START	0x0100
455b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project#define	CUC_RESUME	0x0200
465b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project#define	CUC_SUSPEND	0x0300
475b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project#define	RX_START	0x0010
485b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project#define	RX_RESUME	0x0020
495b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project#define	RX_SUSPEND	0x0030
505b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
515b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project/* The Rx unit uses a list of frame descriptors and a list of data buffer
525b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project   descriptors.  We use full-sized (1518 byte) data buffers, so there is
535b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project   a one-to-one pairing of frame descriptors to buffer descriptors.
545b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
555b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project   The Tx ("command") unit executes a list of commands that look like:
565b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	Status word	Written by the 82586 when the command is done.
575b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	Command word	Command in lower 3 bits, post-command action in upper 3
585b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	Link word	The address of the next command.
595b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	Parameters	(as needed).
605b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
615b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	Some definitions related to the Command Word are:
625b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project */
635b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project#define CMD_EOL		0x8000		/* The last command of the list, stop. */
645b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project#define CMD_SUSP	0x4000		/* Suspend after doing cmd. */
655b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project#define CMD_INTR	0x2000		/* Interrupt after doing cmd. */
665b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
675b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Projectenum commands {
685b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	CmdNOp = 0, CmdSASetup = 1, CmdConfigure = 2, CmdMulticastList = 3,
695b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	CmdTx = 4, CmdTDR = 5, CmdDump = 6, CmdDiagnose = 7};
705b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
715b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project/*
725b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project		Details of the EtherLink16 Implementation
735b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
745b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project  The 3c507 and NI5210 are generic shared-memory i82586 implementations.
755b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project  3c507: The host can map 16K, 32K, 48K, or 64K of the 64K memory into
765b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project  0x0[CD][08]0000, or all 64K into 0xF[02468]0000.
775b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project  NI5210: The host can map 8k or 16k at 0x[CDE][048C]000 but we
785b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project  assume 8k because to have 16k you cannot put a ROM on the NIC.
795b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project  */
805b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
815b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project/* Offsets from the base I/O address. */
825b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
835b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project#ifdef	INCLUDE_3C507
845b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
855b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project#define	SA_DATA		0	/* Station address data, or 3Com signature. */
865b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project#define MISC_CTRL	6	/* Switch the SA_DATA banks, and bus config bits. */
875b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project#define RESET_IRQ	10	/* Reset the latched IRQ line. */
885b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project#define I82586_ATTN	11	/* Frob the 82586 Channel Attention line. */
895b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project#define ROM_CONFIG	13
905b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project#define MEM_CONFIG	14
915b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project#define IRQ_CONFIG	15
925b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project#define EL16_IO_EXTENT	16
935b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
945b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project/* The ID port is used at boot-time to locate the ethercard. */
955b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project#define ID_PORT		0x100
965b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
975b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project#endif
985b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
995b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project#ifdef	INCLUDE_NI5210
1005b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
1015b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project#define	NI52_RESET	0  /* writing to this address, resets the i82586 */
1025b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project#define	I82586_ATTN	1  /* channel attention, kick the 586 */
1035b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
1045b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project#endif
1055b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
1065b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project#ifdef	INCLUDE_EXOS205
1075b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
1085b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project#define	EXOS205_RESET	0  /* writing to this address, resets the i82586 */
1095b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project#define	I82586_ATTN	1  /* channel attention, kick the 586 */
1105b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
1115b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project#endif
1125b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
1135b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project/* Offsets to registers in the mailbox (SCB). */
1145b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project#define iSCB_STATUS	0x8
1155b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project#define iSCB_CMD	0xA
1165b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project#define iSCB_CBL	0xC	/* Command BLock offset. */
1175b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project#define iSCB_RFA	0xE	/* Rx Frame Area offset. */
1185b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
1195b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project/*  Since the 3c507 maps the shared memory window so that the last byte is
1205b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Projectat 82586 address FFFF, the first byte is at 82586 address 0, 16K, 32K, or
1215b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project48K corresponding to window sizes of 64K, 48K, 32K and 16K respectively.
1225b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source ProjectWe can account for this be setting the 'SBC Base' entry in the ISCP table
1235b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Projectbelow for all the 16 bit offset addresses, and also adding the 'SCB Base'
1245b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Projectvalue to all 24 bit physical addresses (in the SCP table and the TX and RX
1255b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source ProjectBuffer Descriptors).
1265b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project				-Mark
1275b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project*/
1285b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
1295b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project/*
1305b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project  What follows in 'init_words[]' is the "program" that is downloaded to the
1315b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project  82586 memory.  It's mostly tables and command blocks, and starts at the
1325b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project  reset address 0xfffff6.  This is designed to be similar to the EtherExpress,
1335b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project  thus the unusual location of the SCB at 0x0008.
1345b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
1355b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project  Even with the additional "don't care" values, doing it this way takes less
1365b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project  program space than initializing the individual tables, and I feel it's much
1375b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project  cleaner.
1385b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
1395b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project  The databook is particularly useless for the first two structures, I had
1405b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project  to use the Crynwr driver as an example.
1415b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
1425b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project  The memory setup is as follows:
1435b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project*/
1445b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
1455b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project#define CONFIG_CMD	0x18
1465b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project#define SET_SA_CMD	0x24
1475b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project#define SA_OFFSET	0x2A
1485b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project#define IDLELOOP	0x30
1495b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project#define TDR_CMD		0x38
1505b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project#define TDR_TIME	0x3C
1515b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project#define DUMP_CMD	0x40
1525b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project#define DIAG_CMD	0x48
1535b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project#define SET_MC_CMD	0x4E
1545b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project#define DUMP_DATA	0x56	/* A 170 byte buffer for dump and Set-MC into. */
1555b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
1565b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project#define TX_BUF_START	0x0100
1575b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project#define TX_BUF_SIZE	(1518+14+20+16) /* packet+header+TBD */
1585b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
1595b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project#define RX_BUF_START	0x1000
1605b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project#define RX_BUF_SIZE	(1518+14+18)	/* packet+header+RBD */
1615b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project#define RX_BUF_END	(mem_end - mem_start - 20)
1625b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
1635b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project/*
1645b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project  That's it: only 86 bytes to set up the beast, including every extra
1655b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project  command available.  The 170 byte buffer at DUMP_DATA is shared between the
1665b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project  Dump command (called only by the diagnostic program) and the SetMulticastList
1675b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project  command.
1685b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
1695b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project  To complete the memory setup you only have to write the station address at
1705b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project  SA_OFFSET and create the Tx & Rx buffer lists.
1715b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
1725b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project  The Tx command chain and buffer list is setup as follows:
1735b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project  A Tx command table, with the data buffer pointing to...
1745b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project  A Tx data buffer descriptor.  The packet is in a single buffer, rather than
1755b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	chaining together several smaller buffers.
1765b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project  A NoOp command, which initially points to itself,
1775b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project  And the packet data.
1785b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
1795b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project  A transmit is done by filling in the Tx command table and data buffer,
1805b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project  re-writing the NoOp command, and finally changing the offset of the last
1815b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project  command to point to the current Tx command.  When the Tx command is finished,
1825b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project  it jumps to the NoOp, when it loops until the next Tx command changes the
1835b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project  "link offset" in the NoOp.  This way the 82586 never has to go through the
1845b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project  slow restart sequence.
1855b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
1865b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project  The Rx buffer list is set up in the obvious ring structure.  We have enough
1875b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project  memory (and low enough interrupt latency) that we can avoid the complicated
1885b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project  Rx buffer linked lists by alway associating a full-size Rx data buffer with
1895b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project  each Rx data frame.
1905b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
1915b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project  I currently use one transmit buffer starting at TX_BUF_START (0x0100), and
1925b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project  use the rest of memory, from RX_BUF_START to RX_BUF_END, for Rx buffers.
1935b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
1945b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project  */
1955b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
1965b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Projectstatic unsigned short init_words[] = {
1975b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	/*	System Configuration Pointer (SCP). */
1985b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project#if	defined(INCLUDE_3C507)
1995b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	0x0000,					/* Set bus size to 16 bits. */
2005b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project#else
2015b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	0x0001,					/* Set bus size to 8 bits */
2025b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project#endif
2035b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	0,0,					/* pad words. */
2045b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	0x0000,0x0000,				/* ISCP phys addr, set in init_82586_mem(). */
2055b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
2065b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	/*	Intermediate System Configuration Pointer (ISCP). */
2075b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	0x0001,					/* Status word that's cleared when init is done. */
2085b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	0x0008,0,0,				/* SCB offset, (skip, skip) */
2095b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
2105b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	/* System Control Block (SCB). */
2115b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	0,0xf000|RX_START|CUC_START,		/* SCB status and cmd. */
2125b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	CONFIG_CMD,				/* Command list pointer, points to Configure. */
2135b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	RX_BUF_START,				/* Rx block list. */
2145b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	0,0,0,0,				/* Error count: CRC, align, buffer, overrun. */
2155b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
2165b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	/* 0x0018: Configure command.  Change to put MAC data with packet. */
2175b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	0, CmdConfigure,			/* Status, command. */
2185b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	SET_SA_CMD,				/* Next command is Set Station Addr. */
2195b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	0x0804,					/* "4" bytes of config data, 8 byte FIFO. */
2205b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	0x2e40,					/* Magic values, including MAC data location. */
2215b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	0,					/* Unused pad word. */
2225b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
2235b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	/* 0x0024: Setup station address command. */
2245b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	0, CmdSASetup,
2255b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	SET_MC_CMD,				/* Next command. */
2265b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	0xaa00,0xb000,0x0bad,	/* Station address (to be filled in) */
2275b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
2285b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	/* 0x0030: NOP, looping back to itself.  Point to first Tx buffer to Tx. */
2295b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	0, CmdNOp, IDLELOOP, 0 /* pad */,
2305b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
2315b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	/* 0x0038: A unused Time-Domain Reflectometer command. */
2325b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	0, CmdTDR, IDLELOOP, 0,
2335b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
2345b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	/* 0x0040: An unused Dump State command. */
2355b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	0, CmdDump, IDLELOOP, DUMP_DATA,
2365b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
2375b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	/* 0x0048: An unused Diagnose command. */
2385b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	0, CmdDiagnose, IDLELOOP,
2395b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
2405b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	/* 0x004E: An empty set-multicast-list command. */
2415b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	0, CmdMulticastList, IDLELOOP, 0,
2425b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project};
2435b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
2445b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project/* NIC specific static variables go here */
2455b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
2465b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Projectstatic unsigned short		ioaddr, irq, scb_base;
2475b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Projectstatic Address			mem_start, mem_end;
2485b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Projectstatic unsigned short		rx_head, rx_tail;
2495b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
2505b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project#define	read_mem(m,s)	fmemcpy((char *)s, m, sizeof(s))
2515b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
2525b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Projectstatic void setup_rx_buffers(struct nic *nic)
2535b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project{
2545b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	Address			write_ptr;
2555b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	unsigned short		cur_rx_buf;
2565b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	static unsigned short	rx_cmd[16] = {
2575b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project		0x0000,			/* Rx status */
2585b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project		0x0000,			/* Rx command, only and last */
2595b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project		RX_BUF_START,		/* Link (will be adjusted) */
2605b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project		RX_BUF_START + 22,	/* Buffer offset (will be adjusted) */
2615b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project		0x0000, 0x0000, 0x0000,	/* Pad for dest addr */
2625b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project		0x0000, 0x0000, 0x0000,	/* Pad for source addr */
2635b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project		0x0000,			/* Pad for protocol */
2645b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project		0x0000,			/* Buffer: Actual count */
2655b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project		-1,			/* Buffer: Next (none) */
2665b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project		RX_BUF_START + 0x20,	/* Buffer: Address low (+ scb_base) (will be adjusted) */
2675b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project		0x0000,			/* Buffer: Address high */
2685b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project		0x8000 | (RX_BUF_SIZE - 0x20)
2695b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	};
2705b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
2715b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	cur_rx_buf = rx_head = RX_BUF_START;
2725b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	do {		/* While there is room for one more buffer */
2735b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project		write_ptr = mem_start + cur_rx_buf;
2745b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project		/* adjust some contents */
2755b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project		rx_cmd[1] = 0x0000;
2765b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project		rx_cmd[2] = cur_rx_buf + RX_BUF_SIZE;
2775b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project		rx_cmd[3] = cur_rx_buf + 22;
2785b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project		rx_cmd[13] = cur_rx_buf + 0x20 + scb_base;
2795b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project		memcpy((char *)write_ptr, (char *)rx_cmd, sizeof(rx_cmd));
2805b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project		rx_tail = cur_rx_buf;
2815b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project		cur_rx_buf += RX_BUF_SIZE;
2825b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	} while (cur_rx_buf <= RX_BUF_END - RX_BUF_SIZE);
2835b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	/* Terminate the list by setting the EOL bit and wrap ther pointer
2845b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	   to make the list a ring. */
2855b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	write_ptr = mem_start + rx_tail;
2865b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	rx_cmd[1] = 0xC000;
2875b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	rx_cmd[2] = rx_head;
2885b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	memcpy((char *)write_ptr, (char *)rx_cmd, sizeof(unsigned short) * 3);
2895b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project}
2905b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
2915b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Projectstatic void ack_status(void)
2925b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project{
2935b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	unsigned short	cmd, status;
2945b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	unsigned short	*shmem = (short *)mem_start;
2955b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
2965b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	cmd = (status = shmem[iSCB_STATUS>>1]) & 0xf000;
2975b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	if (status & 0x100)		/* CU suspended? */
2985b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project		cmd |= CUC_RESUME;
2995b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	if ((status & 0x200) == 0)	/* CU not active? */
3005b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project		cmd |= CUC_START;
3015b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	if (status & 0x010)		/* RU suspended? */
3025b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project		cmd |= RX_RESUME;
3035b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	else if ((status & 0x040) == 0)	/* RU not active? */
3045b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project		cmd |= RX_START;
3055b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	if (cmd == 0)			/* Nothing to do */
3065b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project		return;
3075b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	shmem[iSCB_CMD>>1] = cmd;
3085b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project#if	defined(DEBUG)
3095b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	printf("Status %hX Command %hX\n", status, cmd);
3105b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project#endif
3115b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	outb(0, ioaddr + I82586_ATTN);
3125b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project}
3135b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
3145b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project/**************************************************************************
3155b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source ProjectRESET - Reset adapter
3165b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project***************************************************************************/
3175b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
3185b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Projectstatic void i82586_reset(struct nic *nic)
3195b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project{
3205b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	unsigned long	time;
3215b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	unsigned short	*shmem = (short *)mem_start;
3225b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
3235b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	/* put the card in its initial state */
3245b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
3255b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project#ifdef	INCLUDE_3C507
3265b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	/* Enable loopback to protect the wire while starting up,
3275b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	   and hold the 586 in reset during the memory initialisation. */
3285b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	outb(0x20, ioaddr + MISC_CTRL);
3295b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project#endif
3305b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
3315b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	/* Fix the ISCP address and base. */
3325b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	init_words[3] = scb_base;
3335b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	init_words[7] = scb_base;
3345b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
3355b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	/* Write the words at 0xfff6. */
3365b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	/* Write the words at 0x0000. */
3375b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	/* Fill in the station address. */
3385b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	memcpy((char *)(mem_end - 10), (char *)init_words, 10);
3395b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	memcpy((char *)mem_start, (char *)&init_words[5], sizeof(init_words) - 10);
3405b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	memcpy((char *)mem_start + SA_OFFSET, nic->node_addr, ETH_ALEN);
3415b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	setup_rx_buffers(nic);
3425b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
3435b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project#ifdef	INCLUDE_3C507
3445b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	/* Start the 586 by releasing the reset line, but leave loopback. */
3455b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	outb(0xA0, ioaddr + MISC_CTRL);
3465b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project#endif
3475b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
3485b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	/* This was time consuming to track down; you need to give two channel
3495b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	   attention signals to reliably start up the i82586. */
3505b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	outb(0, ioaddr + I82586_ATTN);
3515b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	time = currticks() + TICKS_PER_SEC;	/* allow 1 second to init */
3525b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	while (
3535b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project			shmem[iSCB_STATUS>>1] == 0)
3545b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	{
3555b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project		if (currticks() > time)
3565b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project		{
3575b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project			printf("i82586 initialisation timed out with status %hX, cmd %hX\n",
3585b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project					shmem[iSCB_STATUS>>1], shmem[iSCB_CMD>>1]);
3595b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project			break;
3605b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project		}
3615b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	}
3625b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	/* Issue channel-attn -- the 82586 won't start. */
3635b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	outb(0, ioaddr + I82586_ATTN);
3645b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
3655b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project#ifdef	INCLUDE_3C507
3665b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	/* Disable loopback. */
3675b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	outb(0x80, ioaddr + MISC_CTRL);
3685b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project#endif
3695b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project#if	defined(DEBUG)
3705b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	printf("i82586 status %hX, cmd %hX\n",
3715b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project			shmem[iSCB_STATUS>>1], shmem[iSCB_CMD>>1]);
3725b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project#endif
3735b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project}
3745b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
3755b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project/**************************************************************************
3765b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project  POLL - Wait for a frame
3775b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project ***************************************************************************/
3785b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Projectstatic int i82586_poll(struct nic *nic)
3795b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project{
3805b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	int		status;
3815b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	unsigned short	rfd_cmd, next_rx_frame, data_buffer_addr,
3825b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	frame_status, pkt_len;
3835b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	unsigned short	*shmem = (short *)mem_start + rx_head;
3845b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
3855b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	/* return true if there's an ethernet packet ready to read */
3865b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	if (
3875b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project			((frame_status = shmem[0]) & 0x8000) == 0)
3885b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project		return (0);		/* nope */
3895b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	rfd_cmd = shmem[1];
3905b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	next_rx_frame = shmem[2];
3915b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	data_buffer_addr = shmem[3];
3925b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	pkt_len = shmem[11];
3935b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	status = 0;
3945b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	if (rfd_cmd != 0 || data_buffer_addr != rx_head + 22
3955b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project			|| (pkt_len & 0xC000) != 0xC000)
3965b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project		printf("\nRx frame corrupt, discarded");
3975b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	else if ((frame_status & 0x2000) == 0)
3985b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project		printf("\nRx frame had error");
3995b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	else
4005b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	{
4015b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project		/* We have a frame, copy it to our buffer */
4025b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project		pkt_len &= 0x3FFF;
4035b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project		memcpy(nic->packet, (char *)mem_start + rx_head + 0x20, pkt_len);
4045b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project		/* Only packets not from ourself */
4055b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project		if (memcmp(nic->packet + ETH_ALEN, nic->node_addr, ETH_ALEN) != 0)
4065b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project		{
4075b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project			nic->packetlen = pkt_len;
4085b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project			status = 1;
4095b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project		}
4105b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	}
4115b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	/* Clear the status word and set EOL on Rx frame */
4125b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	shmem[0] = 0;
4135b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	shmem[1] = 0xC000;
4145b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	*(short *)(mem_start + rx_tail + 2) = 0;
4155b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	rx_tail = rx_head;
4165b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	rx_head = next_rx_frame;
4175b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	ack_status();
4185b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	return (status);
4195b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project}
4205b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
4215b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project/**************************************************************************
4225b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project  TRANSMIT - Transmit a frame
4235b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project ***************************************************************************/
4245b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Projectstatic void i82586_transmit(
4255b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project		struct nic *nic,
4265b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project		const char *d,			/* Destination */
4275b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project		unsigned int t,			/* Type */
4285b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project		unsigned int s,			/* size */
4295b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project		const char *p)			/* Packet */
4305b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project{
4315b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	Address			bptr;
4325b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	unsigned short		type, z;
4335b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	static unsigned short	tx_cmd[11] = {
4345b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project		0x0,			/* Tx status */
4355b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project		CmdTx,			/* Tx command */
4365b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project		TX_BUF_START+16,	/* Next command is a NoOp */
4375b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project		TX_BUF_START+8,		/* Data Buffer offset */
4385b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project		0x8000,			/* | with size */
4395b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project		0xffff,			/* No next data buffer */
4405b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project		TX_BUF_START+22,	/* + scb_base */
4415b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project		0x0,			/* Buffer address high bits (always zero) */
4425b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project		0x0,			/* Nop status */
4435b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project		CmdNOp,			/* Nop command */
4445b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project		TX_BUF_START+16		/* Next is myself */
4455b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	};
4465b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	unsigned short	*shmem = (short *)mem_start + TX_BUF_START;
4475b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
4485b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	/* send the packet to destination */
4495b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	/* adjust some contents */
4505b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	type = htons(t);
4515b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	if (s < ETH_ZLEN)
4525b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project		s = ETH_ZLEN;
4535b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	tx_cmd[4] = (s + ETH_HLEN) | 0x8000;
4545b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	tx_cmd[6] = TX_BUF_START + 22 + scb_base;
4555b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	bptr = mem_start + TX_BUF_START;
4565b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	memcpy((char *)bptr, (char *)tx_cmd, sizeof(tx_cmd));
4575b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	bptr += sizeof(tx_cmd);
4585b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	memcpy((char *)bptr, d, ETH_ALEN);
4595b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	bptr += ETH_ALEN;
4605b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	memcpy((char *)bptr, nic->node_addr, ETH_ALEN);
4615b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	bptr += ETH_ALEN;
4625b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	memcpy((char *)bptr, (char *)&type, sizeof(type));
4635b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	bptr += sizeof(type);
4645b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	memcpy((char *)bptr, p, s);
4655b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	/* Change the offset in the IDLELOOP */
4665b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	*(unsigned short *)(mem_start + IDLELOOP + 4) = TX_BUF_START;
4675b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	/* Wait for transmit completion */
4685b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	while (
4695b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project			(shmem[0] & 0x2000) == 0)
4705b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project		;
4715b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	/* Change the offset in the IDLELOOP back and
4725b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	   change the final loop to point here */
4735b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	*(unsigned short *)(mem_start + IDLELOOP + 4) = IDLELOOP;
4745b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	*(unsigned short *)(mem_start + TX_BUF_START + 20) = IDLELOOP;
4755b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	ack_status();
4765b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project}
4775b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
4785b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project/**************************************************************************
4795b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project  DISABLE - Turn off ethernet interface
4805b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project ***************************************************************************/
4815b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Projectstatic void i82586_disable(struct nic *nic)
4825b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project{
4835b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	unsigned short	*shmem = (short *)mem_start;
4845b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
4855b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project#if	0
4865b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	/* Flush the Tx and disable Rx. */
4875b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	shmem[iSCB_CMD>>1] = RX_SUSPEND | CUC_SUSPEND;
4885b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	outb(0, ioaddr + I82586_ATTN);
4895b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project#ifdef	INCLUDE_NI5210
4905b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	outb(0, ioaddr + NI52_RESET);
4915b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project#endif
4925b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project#endif	/* 0 */
4935b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project}
4945b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
4955b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project#ifdef	INCLUDE_3C507
4965b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
4975b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Projectstatic int t507_probe1(struct nic *nic, unsigned short ioaddr)
4985b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project{
4995b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	int			i;
5005b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	Address			size;
5015b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	char			mem_config;
5025b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	char			if_port;
5035b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
5045b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	if (inb(ioaddr) != '*' || inb(ioaddr+1) != '3'
5055b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project		|| inb(ioaddr+2) != 'C' || inb(ioaddr+3) != 'O')
5065b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project		return (0);
5075b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	irq = inb(ioaddr + IRQ_CONFIG) & 0x0f;
5085b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	mem_config = inb(ioaddr + MEM_CONFIG);
5095b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	if (mem_config & 0x20)
5105b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	{
5115b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project		size = 65536L;
5125b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project		mem_start = 0xf00000L + (mem_config & 0x08 ? 0x080000L
5135b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project			: (((Address)mem_config & 0x3) << 17));
5145b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	}
5155b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	else
5165b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	{
5175b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project		size = ((((Address)mem_config & 0x3) + 1) << 14);
5185b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project		mem_start = 0x0c0000L + (((Address)mem_config & 0x18) << 12);
5195b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	}
5205b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	mem_end = mem_start + size;
5215b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	scb_base = 65536L - size;
5225b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	if_port = inb(ioaddr + ROM_CONFIG) & 0x80;
5235b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	/* Get station address */
5245b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	outb(0x01, ioaddr + MISC_CTRL);
5255b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	for (i = 0; i < ETH_ALEN; ++i)
5265b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	{
5275b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project		nic->node_addr[i] = inb(ioaddr+i);
5285b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	}
5295b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	printf("\n3c507 ioaddr %#hX, IRQ %d, mem [%#X-%#X], %sternal xcvr, addr %!\n",
5305b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project		ioaddr, irq, mem_start, mem_end, if_port ? "in" : "ex", nic->node_addr);
5315b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	return (1);
5325b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project}
5335b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
5345b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project/**************************************************************************
5355b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source ProjectPROBE - Look for an adapter, this routine's visible to the outside
5365b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project***************************************************************************/
5375b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
5385b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Projectstruct nic *t507_probe(struct nic *nic, unsigned short *probe_addrs)
5395b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project{
5405b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	static unsigned char	init_ID_done = 0;
5415b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	unsigned short		lrs_state = 0xff;
5425b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	static unsigned short	io_addrs[] = { 0x300, 0x320, 0x340, 0x280, 0 };
5435b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	unsigned short		*p;
5445b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	int			i;
5455b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
5465b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	if (init_ID_done == 0)
5475b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	{
5485b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project		/* Send the ID sequence to the ID_PORT to enable the board */
5495b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project		outb(0x00, ID_PORT);
5505b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project		for (i = 0; i < 255; ++i)
5515b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project		{
5525b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project			outb(lrs_state, ID_PORT);
5535b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project			lrs_state <<= 1;
5545b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project			if (lrs_state & 0x100)
5555b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project				lrs_state ^= 0xe7;
5565b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project		}
5575b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project		outb(0x00, ID_PORT);
5585b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project		init_ID_done = 1;
5595b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	}
5605b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	/* if probe_addrs is 0, then routine can use a hardwired default */
5615b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	if (probe_addrs == 0)
5625b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project		probe_addrs = io_addrs;
5635b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	for (p = probe_addrs; (ioaddr = *p) != 0; ++p)
5645b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project		if (t507_probe1(nic, ioaddr))
5655b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project			break;
5665b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	if (ioaddr != 0)
5675b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	{
5685b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project		/* point to NIC specific routines */
5695b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project		i82586_reset(nic);
5705b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project		nic->reset = i82586_reset;
5715b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project		nic->poll = i82586_poll;
5725b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project		nic->transmit = i82586_transmit;
5735b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project		nic->disable = i82586_disable;
5745b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project		return nic;
5755b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	}
5765b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	/* else */
5775b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	{
5785b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project		return 0;
5795b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	}
5805b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project}
5815b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
5825b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project#endif
5835b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
5845b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project#ifdef	INCLUDE_NI5210
5855b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
5865b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Projectstatic int ni5210_probe2(void)
5875b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project{
5885b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	unsigned short		i;
5895b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	unsigned short		shmem[10];
5905b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
5915b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	/* Fix the ISCP address and base. */
5925b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	init_words[3] = scb_base;
5935b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	init_words[7] = scb_base;
5945b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
5955b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	/* Write the words at 0xfff6. */
5965b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	/* Write the words at 0x0000. */
5975b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	memcpy((char *)(mem_end - 10), (char *)init_words, 10);
5985b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	memcpy((char *)mem_start, (char *)&init_words[5], sizeof(init_words) - 10);
5995b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	if (*(unsigned short *)mem_start != 1)
6005b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project		return (0);
6015b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	outb(0, ioaddr + NI52_RESET);
6025b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	outb(0, ioaddr + I82586_ATTN);
6035b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	udelay(32);
6045b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	i = 50;
6055b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	while (
6065b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project		shmem[iSCB_STATUS>>1] == 0)
6075b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	{
6085b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project		if (--i == 0)
6095b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project		{
6105b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project			printf("i82586 initialisation timed out with status %hX, cmd %hX\n",
6115b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project				shmem[iSCB_STATUS>>1], shmem[iSCB_CMD>>1]);
6125b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project			break;
6135b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project		}
6145b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	}
6155b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	/* Issue channel-attn -- the 82586 won't start. */
6165b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	outb(0, ioaddr + I82586_ATTN);
6175b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	if (*(unsigned short *)mem_start != 0)
6185b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project		return (0);
6195b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	return (1);
6205b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project}
6215b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
6225b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Projectstatic int ni5210_probe1(struct nic *nic)
6235b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project{
6245b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	int			i;
6255b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	static Address		mem_addrs[] = {
6265b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project		0xc0000, 0xc4000, 0xc8000, 0xcc000,
6275b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project		0xd0000, 0xd4000, 0xd8000, 0xdc000,
6285b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project		0xe0000, 0xe4000, 0xe8000, 0xec000,
6295b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project		0 };
6305b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	Address			*p;
6315b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
6325b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	if (inb(ioaddr + 6) != 0x0 || inb(ioaddr + 7) != 0x55)
6335b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project		return (0);
6345b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	scb_base = -8192;		/* assume 8k memory */
6355b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	for (p = mem_addrs; (mem_start = *p) != 0; ++p)
6365b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project		if (mem_end = mem_start + 8192, ni5210_probe2())
6375b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project			break;
6385b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	if (mem_start == 0)
6395b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project		return (0);
6405b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	/* Get station address */
6415b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	for (i = 0; i < ETH_ALEN; ++i)
6425b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	{
6435b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project		nic->node_addr[i] = inb(ioaddr+i);
6445b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	}
6455b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	printf("\nNI5210 ioaddr %#hX, mem [%#X-%#X], addr %!\n",
6465b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project		ioaddr, mem_start, mem_end, nic->node_addr);
6475b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	return (1);
6485b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project}
6495b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
6505b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Projectstruct nic *ni5210_probe(struct nic *nic, unsigned short *probe_addrs)
6515b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project{
6525b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	/* missing entries are addresses usually already used */
6535b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	static unsigned short	io_addrs[] = {
6545b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project		0x200, 0x208, 0x210, 0x218, 0x220, 0x228, 0x230, 0x238,
6555b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project		0x240, 0x248, 0x250, 0x258, 0x260, 0x268, 0x270, /*Par*/
6565b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project		0x280, 0x288, 0x290, 0x298, 0x2A0, 0x2A8, 0x2B0, 0x2B8,
6575b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project		0x2C0, 0x2C8, 0x2D0, 0x2D8, 0x2E0, 0x2E8, 0x2F0, /*Ser*/
6585b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project		0x300, 0x308, 0x310, 0x318, 0x320, 0x328, 0x330, 0x338,
6595b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project		0x340, 0x348, 0x350, 0x358, 0x360, 0x368, 0x370, /*Par*/
6605b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project		0x380, 0x388, 0x390, 0x398, 0x3A0, 0x3A8, /*Vid,Par*/
6615b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project		0x3C0, 0x3C8, 0x3D0, 0x3D8, 0x3E0, 0x3E8, /*Ser*/
6625b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project		0x0
6635b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	};
6645b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	unsigned short		*p;
6655b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	int			i;
6665b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
6675b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	/* if probe_addrs is 0, then routine can use a hardwired default */
6685b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	if (probe_addrs == 0)
6695b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project		probe_addrs = io_addrs;
6705b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	for (p = probe_addrs; (ioaddr = *p) != 0; ++p)
6715b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project		if (ni5210_probe1(nic))
6725b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project			break;
6735b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	if (ioaddr != 0)
6745b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	{
6755b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project		/* point to NIC specific routines */
6765b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project		i82586_reset(nic);
6775b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project		nic->reset = i82586_reset;
6785b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project		nic->poll = i82586_poll;
6795b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project		nic->transmit = i82586_transmit;
6805b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project		nic->disable = i82586_disable;
6815b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project		return nic;
6825b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	}
6835b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	/* else */
6845b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	{
6855b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project		return 0;
6865b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	}
6875b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project}
6885b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project#endif
6895b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
6905b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project#ifdef	INCLUDE_EXOS205
6915b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
6925b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project/*
6935b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project * Code to download to I186 in EXOS205
6945b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project */
6955b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
6965b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Projectstatic unsigned char exos_i186_init[] =
6975b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project{
6985b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project0x08,0x00,0x14,0x00,0x00,0x00,0xaa,0xfa,0x33,0xc0,0xba,0xfe,0xff,0xef,0xb8,0xf8,
6995b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project0xff,0xe7,0xa0,0xb8,0x7c,0x00,0xe7,0xa4,0xb8,0xbc,0x80,0xe7,0xa8,0x8c,0xc8,0x8e,
7005b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project0xd8,0xbb,0x2f,0x0e,0xc6,0x07,0xa5,0x33,0xc9,0xeb,0x00,0xeb,0x00,0xeb,0x00,0xe2,
7015b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project0xf8,0xbe,0x2c,0x0e,0xba,0x02,0x05,0x33,0xdb,0xb9,0x03,0x00,0xec,0x24,0x0f,0x8a,
7025b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project0xe0,0x02,0xd8,0x42,0x42,0xec,0x02,0xd8,0xd0,0xe0,0xd0,0xe0,0xd0,0xe0,0xd0,0xe0,
7035b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project0x0a,0xc4,0x88,0x04,0x42,0x42,0x46,0xe2,0xe3,0x8a,0xe3,0xd0,0xec,0xd0,0xec,0xd0,
7045b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project0xec,0xd0,0xec,0x80,0xe3,0x0f,0x02,0xe3,0x80,0xf4,0x05,0xec,0x3a,0xe0,0x74,0x05,
7055b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project0xc6,0x04,0x5a,0xeb,0xfe,0xc6,0x04,0x55,0x33,0xc0,0x8e,0xd8,0xbe,0x38,0x00,0xc7,
7065b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project0x04,0xce,0x0e,0x46,0x46,0xc7,0x04,0x00,0xff,0xfb,0xba,0x3c,0x00,0xb8,0x03,0x00,
7075b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project0xef,0x33,0xdb,0x33,0xc9,0xbd,0x04,0x0f,0x90,0x90,0x90,0x90,0xe2,0xfa,0x43,0x2e,
7085b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project0x89,0x5e,0x00,0xeb,0xf3,0x52,0xba,0x00,0x06,0xef,0x50,0x53,0x55,0xbd,0xf8,0x0e,
7095b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project0x2e,0x8b,0x5e,0x00,0x43,0x2e,0x89,0x5e,0x00,0xba,0x22,0x00,0xb8,0x00,0x80,0xef,
7105b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project0x5d,0x5b,0x58,0x5a,0xcf,0x49,0x4e,0x54,0x52,0x20,0x63,0x6e,0x74,0x2d,0x3e,0x00,
7115b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project0x00,0x4c,0x4f,0x4f,0x50,0x20,0x63,0x6e,0x74,0x2d,0x3e,0x00,0x00,0x00,0x00,0x00,
7125b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
7135b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
7145b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
7155b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
7165b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
7175b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
7185b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
7195b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
7205b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
7215b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
7225b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
7235b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
7245b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
7255b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
7265b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xea,0x30,0x0e,0x00,0xff,0x00,0x00,0x00,0x00,
7275b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project0x00,0x00,0x00,0x00,0x00,0x00,00
7285b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project};
7295b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
7305b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project/* These offsets are from the end of the i186 download code */
7315b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
7325b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project#define	OFFSET_SEMA		0x1D1
7335b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project#define	OFFSET_ADDR		0x1D7
7345b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
7355b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Projectstatic int exos205_probe2(void)
7365b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project{
7375b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	unsigned short		i;
7385b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	unsigned short		shmem[10];
7395b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
7405b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	/* Fix the ISCP address and base. */
7415b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	init_words[3] = scb_base;
7425b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	init_words[7] = scb_base;
7435b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
7445b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	/* Write the words at 0xfff6. */
7455b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	/* Write the words at 0x0000. */
7465b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	memcpy((char *)(mem_end - 10), (char *)init_words, 10);
7475b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	memcpy((char *)mem_start, (char *)&init_words[5], sizeof(init_words) - 10);
7485b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	if (*(unsigned short *)mem_start != 1)
7495b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project		return (0);
7505b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	outb(0, ioaddr + EXOS205_RESET);
7515b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	outb(0, ioaddr + I82586_ATTN);
7525b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	i = 50;
7535b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	while (
7545b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project		shmem[iSCB_STATUS>>1] == 0)
7555b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	{
7565b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project		if (--i == 0)
7575b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project		{
7585b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project			printf("i82586 initialisation timed out with status %hX, cmd %hX\n",
7595b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project				shmem[iSCB_STATUS>>1], shmem[iSCB_CMD>>1]);
7605b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project			break;
7615b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project		}
7625b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	}
7635b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	/* Issue channel-attn -- the 82586 won't start. */
7645b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	outb(0, ioaddr + I82586_ATTN);
7655b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	if (*(unsigned short *)mem_start != 0)
7665b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project		return (0);
7675b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	return (1);
7685b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project}
7695b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
7705b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Projectstatic int exos205_probe1(struct nic *nic)
7715b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project{
7725b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	int			i;
7735b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	/* If you know the other addresses please let me know */
7745b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	static Address		mem_addrs[] = {
7755b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project		0xcc000, 0 };
7765b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	Address			*p;
7775b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
7785b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	scb_base = -16384;		/* assume 8k memory */
7795b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	for (p = mem_addrs; (mem_start = *p) != 0; ++p)
7805b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project		if (mem_end = mem_start + 16384, exos205_probe2())
7815b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project			break;
7825b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	if (mem_start == 0)
7835b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project		return (0);
7845b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	/* Get station address */
7855b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	for (i = 0; i < ETH_ALEN; ++i)
7865b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	{
7875b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project		nic->node_addr[i] = inb(ioaddr+i);
7885b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	}
7895b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	printf("\nEXOS205 ioaddr %#hX, mem [%#X-%#X], addr %!\n",
7905b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project		ioaddr, mem_start, mem_end, nic->node_addr);
7915b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	return (1);
7925b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project}
7935b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
7945b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Projectstruct nic *exos205_probe(struct nic *nic, unsigned short *probe_addrs)
7955b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project{
7965b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	/* If you know the other addresses, please let me know */
7975b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	static unsigned short	io_addrs[] = {
7985b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project		0x310, 0x0
7995b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	};
8005b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	unsigned short		*p;
8015b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	int			i;
8025b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
8035b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	/* if probe_addrs is 0, then routine can use a hardwired default */
8045b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	if (probe_addrs == 0)
8055b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project		probe_addrs = io_addrs;
8065b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	for (p = probe_addrs; (ioaddr = *p) != 0; ++p)
8075b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project		if (exos205_probe1(nic))
8085b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project			break;
8095b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	if (ioaddr != 0)
8105b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	{
8115b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project		/* point to NIC specific routines */
8125b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project		i82586_reset(nic);
8135b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project		nic->reset = i82586_reset;
8145b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project		nic->poll = i82586_poll;
8155b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project		nic->transmit = i82586_transmit;
8165b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project		nic->disable = i82586_disable;
8175b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project		return nic;
8185b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	}
8195b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	/* else */
8205b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	{
8215b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project		return 0;
8225b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	}
8235b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project}
8245b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
8255b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project#endif
826