15b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project/**************************************************************************
25b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source ProjectETHERBOOT -  BOOTP/TFTP Bootstrap Program
35b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
45b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source ProjectAuthor: Martin Renters.
55b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project  Date: Mar 22 1995
65b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
75b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project This code is based heavily on David Greenman's if_ed.c driver and
85b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project  Andres Vega Garcia's if_ep.c driver.
95b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
105b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project Copyright (C) 1993-1994, David Greenman, Martin Renters.
115b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project Copyright (C) 1993-1995, Andres Vega Garcia.
125b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project Copyright (C) 1995, Serge Babkin.
135b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project  This software may be used, modified, copied, distributed, and sold, in
145b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project  both source and binary form provided that the above copyright and these
155b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project  terms are retained. Under no circumstances are the authors responsible for
165b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project  the proper functioning of this software, nor do the authors assume any
175b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project  responsibility for damages incurred with its use.
185b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
195b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project3c509 support added by Serge Babkin (babkin@hq.icb.chel.su)
205b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
215b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project$Id: 3c509.c,v 1.4 2002/01/02 21:56:40 okuji Exp $
225b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
235b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project***************************************************************************/
245b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
255b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project/* #define EDEBUG */
265b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
275b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project#include "etherboot.h"
285b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project#include "nic.h"
295b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project#include "cards.h"
305b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project#include "timer.h"
315b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project#include "3c509.h"
325b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
335b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project#define	udelay(n)	waiton_timer2(((n)*TICKS_PER_MS)/1000)
345b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
355b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Projectstatic unsigned short	eth_nic_base;
365b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Projectstatic enum { none, bnc, utp } connector = none;	/* for 3C509 */
375b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
385b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project#ifdef	INCLUDE_3C529
395b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project/*
405b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project * This table and several other pieces of the MCA support
415b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project * code were shamelessly borrowed from the Linux kernel source.
425b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project *
435b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project * MCA support added by Adam Fritzler (mid@auk.cx)
445b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project *
455b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project */
465b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Projectstruct el3_mca_adapters_struct {
475b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project        const char *name;
485b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project        int id;
495b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project};
505b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Projectstatic struct el3_mca_adapters_struct el3_mca_adapters[] = {
515b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project        { "3Com 3c529 EtherLink III (10base2)", 0x627c },
525b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project        { "3Com 3c529 EtherLink III (10baseT)", 0x627d },
535b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project        { "3Com 3c529 EtherLink III (test mode)", 0x62db },
545b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project        { "3Com 3c529 EtherLink III (TP or coax)", 0x62f6 },
555b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project        { "3Com 3c529 EtherLink III (TP)", 0x62f7 },
565b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project        { NULL, 0 },
575b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project};
585b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project#endif
595b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
605b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project/**************************************************************************
615b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source ProjectETH_RESET - Reset adapter
625b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project***************************************************************************/
635b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Projectstatic void t509_reset(struct nic *nic)
645b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project{
655b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	int i;
665b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
675b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	/***********************************************************
685b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project			Reset 3Com 509 card
695b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	*************************************************************/
705b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
715b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	/* stop card */
725b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	outw(RX_DISABLE, BASE + EP_COMMAND);
735b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	outw(RX_DISCARD_TOP_PACK, BASE + EP_COMMAND);
745b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	while (inw(BASE + EP_STATUS) & S_COMMAND_IN_PROGRESS)
755b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project		;
765b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	outw(TX_DISABLE, BASE + EP_COMMAND);
775b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	outw(STOP_TRANSCEIVER, BASE + EP_COMMAND);
785b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	udelay(1000);
795b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	outw(RX_RESET, BASE + EP_COMMAND);
805b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	outw(TX_RESET, BASE + EP_COMMAND);
815b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	outw(C_INTR_LATCH, BASE + EP_COMMAND);
825b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	outw(SET_RD_0_MASK, BASE + EP_COMMAND);
835b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	outw(SET_INTR_MASK, BASE + EP_COMMAND);
845b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	outw(SET_RX_FILTER, BASE + EP_COMMAND);
855b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
865b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	/*
875b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	* initialize card
885b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	*/
895b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	while (inw(BASE + EP_STATUS) & S_COMMAND_IN_PROGRESS)
905b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project		;
915b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
925b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	GO_WINDOW(0);
935b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
945b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	/* Disable the card */
955b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	outw(0, BASE + EP_W0_CONFIG_CTRL);
965b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
975b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	/* Configure IRQ to none */
985b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	outw(SET_IRQ(0), BASE + EP_W0_RESOURCE_CFG);
995b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
1005b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	/* Enable the card */
1015b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	outw(ENABLE_DRQ_IRQ, BASE + EP_W0_CONFIG_CTRL);
1025b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
1035b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	GO_WINDOW(2);
1045b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
1055b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	/* Reload the ether_addr. */
1065b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	for (i = 0; i < ETH_ALEN; i++)
1075b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project		outb(nic->node_addr[i], BASE + EP_W2_ADDR_0 + i);
1085b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
1095b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	outw(RX_RESET, BASE + EP_COMMAND);
1105b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	outw(TX_RESET, BASE + EP_COMMAND);
1115b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
1125b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	/* Window 1 is operating window */
1135b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	GO_WINDOW(1);
1145b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	for (i = 0; i < 31; i++)
1155b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project		inb(BASE + EP_W1_TX_STATUS);
1165b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
1175b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	/* get rid of stray intr's */
1185b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	outw(ACK_INTR | 0xff, BASE + EP_COMMAND);
1195b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
1205b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	outw(SET_RD_0_MASK | S_5_INTS, BASE + EP_COMMAND);
1215b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
1225b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	outw(SET_INTR_MASK, BASE + EP_COMMAND);
1235b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
1245b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	outw(SET_RX_FILTER | FIL_INDIVIDUAL | FIL_BRDCST, BASE + EP_COMMAND);
1255b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
1265b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	/* configure BNC */
1275b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	if (connector == bnc) {
1285b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project		outw(START_TRANSCEIVER, BASE + EP_COMMAND);
1295b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project		udelay(1000);
1305b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	}
1315b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	/* configure UTP */
1325b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	else if (connector == utp) {
1335b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project		GO_WINDOW(4);
1345b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project		outw(ENABLE_UTP, BASE + EP_W4_MEDIA_TYPE);
1355b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project		sleep(2);	/* Give time for media to negotiate */
1365b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project		GO_WINDOW(1);
1375b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	}
1385b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
1395b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	/* start transceiver and receiver */
1405b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	outw(RX_ENABLE, BASE + EP_COMMAND);
1415b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	outw(TX_ENABLE, BASE + EP_COMMAND);
1425b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
1435b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	/* set early threshold for minimal packet length */
1445b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	outw(SET_RX_EARLY_THRESH | ETH_ZLEN, BASE + EP_COMMAND);
1455b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	outw(SET_TX_START_THRESH | 16, BASE + EP_COMMAND);
1465b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project}
1475b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
1485b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project/**************************************************************************
1495b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source ProjectETH_TRANSMIT - Transmit a frame
1505b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project***************************************************************************/
1515b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Projectstatic char padmap[] = {
1525b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	0, 3, 2, 1};
1535b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
1545b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Projectstatic void t509_transmit(
1555b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Projectstruct nic *nic,
1565b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Projectconst char *d,			/* Destination */
1575b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Projectunsigned int t,			/* Type */
1585b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Projectunsigned int s,			/* size */
1595b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Projectconst char *p)			/* Packet */
1605b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project{
1615b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	register unsigned int len;
1625b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	int pad;
1635b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	int status;
1645b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
1655b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project#ifdef	EDEBUG
1665b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	printf("{l=%d,t=%hX}",s+ETH_HLEN,t);
1675b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project#endif
1685b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
1695b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	/* swap bytes of type */
1705b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	t= htons(t);
1715b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
1725b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	len=s+ETH_HLEN; /* actual length of packet */
1735b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	pad = padmap[len & 3];
1745b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
1755b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	/*
1765b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	* The 3c509 automatically pads short packets to minimum ethernet length,
1775b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	* but we drop packets that are too large. Perhaps we should truncate
1785b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	* them instead?
1795b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	*/
1805b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	if (len + pad > ETH_FRAME_LEN) {
1815b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project		return;
1825b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	}
1835b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
1845b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	/* drop acknowledgements */
1855b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	while ((status=inb(BASE + EP_W1_TX_STATUS)) & TXS_COMPLETE ) {
1865b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project		if (status & (TXS_UNDERRUN|TXS_MAX_COLLISION|TXS_STATUS_OVERFLOW)) {
1875b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project			outw(TX_RESET, BASE + EP_COMMAND);
1885b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project			outw(TX_ENABLE, BASE + EP_COMMAND);
1895b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project		}
1905b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project		outb(0x0, BASE + EP_W1_TX_STATUS);
1915b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	}
1925b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
1935b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	while (inw(BASE + EP_W1_FREE_TX) < (unsigned short)len + pad + 4)
1945b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project		; /* no room in FIFO */
1955b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
1965b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	outw(len, BASE + EP_W1_TX_PIO_WR_1);
1975b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	outw(0x0, BASE + EP_W1_TX_PIO_WR_1);	/* Second dword meaningless */
1985b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
1995b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	/* write packet */
2005b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	outsw(BASE + EP_W1_TX_PIO_WR_1, d, ETH_ALEN/2);
2015b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	outsw(BASE + EP_W1_TX_PIO_WR_1, nic->node_addr, ETH_ALEN/2);
2025b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	outw(t, BASE + EP_W1_TX_PIO_WR_1);
2035b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	outsw(BASE + EP_W1_TX_PIO_WR_1, p, s / 2);
2045b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	if (s & 1)
2055b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project		outb(*(p+s - 1), BASE + EP_W1_TX_PIO_WR_1);
2065b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
2075b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	while (pad--)
2085b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project		outb(0, BASE + EP_W1_TX_PIO_WR_1);	/* Padding */
2095b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
2105b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	/* wait for Tx complete */
2115b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	while((inw(BASE + EP_STATUS) & S_COMMAND_IN_PROGRESS) != 0)
2125b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project		;
2135b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project}
2145b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
2155b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project/**************************************************************************
2165b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source ProjectETH_POLL - Wait for a frame
2175b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project***************************************************************************/
2185b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Projectstatic int t509_poll(struct nic *nic)
2195b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project{
2205b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	/* common variables */
2215b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	unsigned short type = 0;	/* used by EDEBUG */
2225b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	/* variables for 3C509 */
2235b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	short status, cst;
2245b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	register short rx_fifo;
2255b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
2265b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	cst=inw(BASE + EP_STATUS);
2275b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
2285b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project#ifdef	EDEBUG
2295b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	if(cst & 0x1FFF)
2305b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project		printf("-%hX-",cst);
2315b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project#endif
2325b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
2335b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	if( (cst & S_RX_COMPLETE)==0 ) {
2345b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project		/* acknowledge  everything */
2355b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project		outw(ACK_INTR| (cst & S_5_INTS), BASE + EP_COMMAND);
2365b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project		outw(C_INTR_LATCH, BASE + EP_COMMAND);
2375b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
2385b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project		return 0;
2395b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	}
2405b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
2415b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	status = inw(BASE + EP_W1_RX_STATUS);
2425b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project#ifdef	EDEBUG
2435b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	printf("*%hX*",status);
2445b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project#endif
2455b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
2465b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	if (status & ERR_RX) {
2475b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project		outw(RX_DISCARD_TOP_PACK, BASE + EP_COMMAND);
2485b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project		return 0;
2495b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	}
2505b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
2515b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	rx_fifo = status & RX_BYTES_MASK;
2525b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	if (rx_fifo==0)
2535b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project		return 0;
2545b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
2555b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project		/* read packet */
2565b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project#ifdef	EDEBUG
2575b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	printf("[l=%d",rx_fifo);
2585b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project#endif
2595b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	insw(BASE + EP_W1_RX_PIO_RD_1, nic->packet, rx_fifo / 2);
2605b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	if(rx_fifo & 1)
2615b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project		nic->packet[rx_fifo-1]=inb(BASE + EP_W1_RX_PIO_RD_1);
2625b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	nic->packetlen=rx_fifo;
2635b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
2645b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	while(1) {
2655b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project		status = inw(BASE + EP_W1_RX_STATUS);
2665b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project#ifdef	EDEBUG
2675b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project		printf("*%hX*",status);
2685b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project#endif
2695b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project		rx_fifo = status & RX_BYTES_MASK;
2705b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project		if(rx_fifo>0) {
2715b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project			insw(BASE + EP_W1_RX_PIO_RD_1, nic->packet+nic->packetlen, rx_fifo / 2);
2725b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project			if(rx_fifo & 1)
2735b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project				nic->packet[nic->packetlen+rx_fifo-1]=inb(BASE + EP_W1_RX_PIO_RD_1);
2745b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project			nic->packetlen+=rx_fifo;
2755b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project#ifdef	EDEBUG
2765b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project			printf("+%d",rx_fifo);
2775b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project#endif
2785b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project		}
2795b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project		if(( status & RX_INCOMPLETE )==0) {
2805b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project#ifdef	EDEBUG
2815b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project			printf("=%d",nic->packetlen);
2825b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project#endif
2835b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project			break;
2845b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project		}
2855b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project		udelay(1000);	/* if incomplete wait 1 ms */
2865b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	}
2875b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	/* acknowledge reception of packet */
2885b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	outw(RX_DISCARD_TOP_PACK, BASE + EP_COMMAND);
2895b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	while (inw(BASE + EP_STATUS) & S_COMMAND_IN_PROGRESS)
2905b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project		;
2915b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project#ifdef	EDEBUG
2925b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	type = (nic->packet[12]<<8) | nic->packet[13];
2935b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	if(nic->packet[0]+nic->packet[1]+nic->packet[2]+nic->packet[3]+nic->packet[4]+
2945b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	    nic->packet[5] == 0xFF*ETH_ALEN)
2955b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project		printf(",t=%hX,b]",type);
2965b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	else
2975b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project		printf(",t=%hX]",type);
2985b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project#endif
2995b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	return (1);
3005b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project}
3015b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
3025b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project/*************************************************************************
3035b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	3Com 509 - specific routines
3045b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project**************************************************************************/
3055b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
3065b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Projectstatic int
3075b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Projecteeprom_rdy(void)
3085b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project{
3095b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	int i;
3105b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
3115b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	for (i = 0; is_eeprom_busy(IS_BASE) && i < MAX_EEPROMBUSY; i++);
3125b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	if (i >= MAX_EEPROMBUSY) {
3135b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project		/* printf("3c509: eeprom failed to come ready.\n"); */
3145b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project		printf("3c509: eeprom busy.\n"); /* memory in EPROM is tight */
3155b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project		return (0);
3165b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	}
3175b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	return (1);
3185b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project}
3195b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
3205b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project/*
3215b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project * get_e: gets a 16 bits word from the EEPROM. we must have set the window
3225b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project * before
3235b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project */
3245b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Projectstatic int
3255b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Projectget_e(int offset)
3265b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project{
3275b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	if (!eeprom_rdy())
3285b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project		return (0xffff);
3295b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	outw(EEPROM_CMD_RD | offset, IS_BASE + EP_W0_EEPROM_COMMAND);
3305b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	if (!eeprom_rdy())
3315b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project		return (0xffff);
3325b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	return (inw(IS_BASE + EP_W0_EEPROM_DATA));
3335b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project}
3345b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
3355b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Projectstatic int
3365b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Projectsend_ID_sequence(int port)
3375b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project{
3385b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	int cx, al;
3395b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
3405b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	for (al = 0xff, cx = 0; cx < 255; cx++) {
3415b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project		outb(al, port);
3425b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project		al <<= 1;
3435b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project		if (al & 0x100)
3445b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project			al ^= 0xcf;
3455b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	}
3465b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	return (1);
3475b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project}
3485b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
3495b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
3505b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project/*
3515b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project * We get eeprom data from the id_port given an offset into the eeprom.
3525b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project * Basically; after the ID_sequence is sent to all of the cards; they enter
3535b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project * the ID_CMD state where they will accept command requests. 0x80-0xbf loads
3545b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project * the eeprom data.  We then read the port 16 times and with every read; the
3555b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project * cards check for contention (ie: if one card writes a 0 bit and another
3565b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project * writes a 1 bit then the host sees a 0. At the end of the cycle; each card
3575b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project * compares the data on the bus; if there is a difference then that card goes
3585b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project * into ID_WAIT state again). In the meantime; one bit of data is returned in
3595b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project * the AX register which is conveniently returned to us by inb().  Hence; we
3605b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project * read 16 times getting one bit of data with each read.
3615b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project */
3625b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Projectstatic int
3635b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Projectget_eeprom_data(int id_port, int offset)
3645b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project{
3655b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	int i, data = 0;
3665b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	outb(0x80 + offset, id_port);
3675b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	/* Do we really need this wait? Won't be noticeable anyway */
3685b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	udelay(10000);
3695b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	for (i = 0; i < 16; i++)
3705b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project		data = (data << 1) | (inw(id_port) & 1);
3715b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	return (data);
3725b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project}
3735b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
3745b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Projectstatic void t509_disable(struct nic *nic)
3755b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project{
3765b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	outb(0xc0, EP_ID_PORT);
3775b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project}
3785b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
3795b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project/**************************************************************************
3805b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source ProjectETH_PROBE - Look for an adapter
3815b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project***************************************************************************/
3825b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project#ifdef	INCLUDE_3C529
3835b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Projectstruct nic *t529_probe(struct nic *nic, unsigned short *probe_addrs)
3845b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project#else
3855b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Projectstruct nic *t509_probe(struct nic *nic, unsigned short *probe_addrs)
3865b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project#endif
3875b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project{
3885b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	/* common variables */
3895b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	int i;
3905b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	int failcount;
3915b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
3925b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project#ifdef	INCLUDE_3C529
3935b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	struct el3_mca_adapters_struct *mcafound = NULL;
3945b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	int mca_pos4 = 0, mca_pos5 = 0, mca_irq = 0;
3955b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project#endif
3965b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
3975b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	t509_disable(nic);		/* in case board was active */
3985b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project					/* note that nic is not used */
3995b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	for (failcount = 0; failcount < 4000; failcount++) {
4005b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project		int data, j, io_base, id_port;
4015b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project		unsigned short k;
4025b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project		int ep_current_tag;
4035b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project		short *p;
4045b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project#ifdef	INCLUDE_3C529
4055b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project		int curboard;
4065b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project#endif
4075b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
4085b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project		id_port = EP_ID_PORT;
4095b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project		ep_current_tag = EP_LAST_TAG + 1;
4105b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
4115b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	/*********************************************************
4125b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project			Search for 3Com 509 card
4135b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	***********************************************************/
4145b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project#ifdef	INCLUDE_3C529
4155b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project		/*
4165b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project		 * XXX: We should really check to make sure we have an MCA
4175b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project		 * bus controller before going ahead with this...
4185b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project		 *
4195b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project		 * For now, we avoid any hassle by making it a compile
4205b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project		 * time option.
4215b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project		 *
4225b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project		 */
4235b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project		printf("\nWarning: Assuming presence of MCA bus\n");
4245b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
4255b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project                /* Make sure motherboard setup is off */
4265b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project                outb_p(0xff, MCA_MOTHERBOARD_SETUP_REG);
4275b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
4285b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project		/* Cycle through slots */
4295b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project		for(curboard=0; curboard<MCA_MAX_SLOT_NR; curboard++) {
4305b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project			int boardid;
4315b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project			int curcard;
4325b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
4335b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project			outb_p(0x8|(curboard&0xf), MCA_ADAPTER_SETUP_REG);
4345b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
4355b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project			boardid = inb_p(MCA_POS_REG(0));
4365b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project			boardid += inb_p(MCA_POS_REG(1)) << 8;
4375b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
4385b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project			curcard = 0;
4395b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project			while (el3_mca_adapters[curcard].name) {
4405b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project				if (el3_mca_adapters[curcard].id == boardid) {
4415b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project					mcafound = &el3_mca_adapters[curcard];
4425b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
4435b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project					mca_pos4 = inb_p(MCA_POS_REG(4));
4445b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project					mca_pos5 = inb_p(MCA_POS_REG(5));
4455b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
4465b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project					goto donewithdetect;
4475b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project				}
4485b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project				else
4495b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project					curcard++;
4505b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project			}
4515b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
4525b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project		}
4535b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	donewithdetect:
4545b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project		/* Kill all setup modes */
4555b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project		outb_p(0, MCA_ADAPTER_SETUP_REG);
4565b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
4575b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project		if (mcafound) {
4585b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project			eth_nic_base = ((short)((mca_pos4&0xfc)|0x02)) << 8;
4595b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project			mca_irq = mca_pos5 & 0x0f;
4605b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project			ep_current_tag--;
4615b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project		}
4625b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project		else
4635b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project			printf("MCA Card not found\n");
4645b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project#endif
4655b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	/* Look for the EISA boards, leave them activated */
4665b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	/* search for the first card, ignore all others */
4675b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	for(j = 1; j < 16; j++) {
4685b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project		io_base = (j * EP_EISA_START) | EP_EISA_W0;
4695b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project		if (inw(io_base + EP_W0_MFG_ID) != MFG_ID)
4705b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project			continue;
4715b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
4725b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project		/* we must have found 0x1f if the board is EISA configurated */
4735b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project		if ((inw(io_base + EP_W0_ADDRESS_CFG) & 0x1f) != 0x1f)
4745b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project			continue;
4755b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
4765b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project		/* Reset and Enable the card */
4775b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project		outb(W0_P4_CMD_RESET_ADAPTER, io_base + EP_W0_CONFIG_CTRL);
4785b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project		udelay(1000); /* Must wait 800 �s, be conservative */
4795b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project		outb(W0_P4_CMD_ENABLE_ADAPTER, io_base + EP_W0_CONFIG_CTRL);
4805b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
4815b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project		/*
4825b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project		 * Once activated, all the registers are mapped in the range
4835b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project		 * x000 - x00F, where x is the slot number.
4845b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project		 */
4855b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project		eth_nic_base = j * EP_EISA_START;
4865b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project		break;
4875b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	}
4885b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	ep_current_tag--;
4895b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
4905b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	/* Look for the ISA boards. Init and leave them actived */
4915b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	/* search for the first card, ignore all others */
4925b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	outb(0xc0, id_port);	/* Global reset */
4935b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	udelay(1000);		/* wait 1 ms */
4945b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	for (i = 0; i < EP_MAX_BOARDS; i++) {
4955b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project		outb(0, id_port);
4965b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project		outb(0, id_port);
4975b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project		send_ID_sequence(id_port);
4985b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
4995b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project		data = get_eeprom_data(id_port, EEPROM_MFG_ID);
5005b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project		if (data != MFG_ID)
5015b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project			break;
5025b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
5035b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project		/* resolve contention using the Ethernet address */
5045b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project		for (j = 0; j < 3; j++)
5055b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project			data = get_eeprom_data(id_port, j);
5065b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
5075b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project		eth_nic_base =
5085b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project		    (get_eeprom_data(id_port, EEPROM_ADDR_CFG) & 0x1f) * 0x10 + 0x200;
5095b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project		outb(ep_current_tag, id_port);	/* tags board */
5105b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project		outb(ACTIVATE_ADAPTER_TO_CONFIG, id_port);
5115b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project		ep_current_tag--;
5125b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project		break;
5135b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	}
5145b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
5155b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	if (i >= EP_MAX_BOARDS)
5165b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project		goto no3c509;
5175b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
5185b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	/*
5195b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	* The iobase was found and MFG_ID was 0x6d50. PROD_ID should be
5205b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	* 0x9[0-f]50
5215b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	*/
5225b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	GO_WINDOW(0);
5235b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	k = get_e(EEPROM_PROD_ID);
5245b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project#ifdef	INCLUDE_3C529
5255b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	/*
5265b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	 * On MCA, the PROD_ID matches the MCA card ID (POS0+POS1)
5275b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	 */
5285b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	if (mcafound) {
5295b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project		if (mcafound->id != k) {
5305b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project			printf("MCA: PROD_ID in EEPROM does not match MCA card ID! (%hX != %hX)\n", k, mcafound->id);
5315b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project			goto no3c509;
5325b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project		}
5335b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	} else { /* for ISA/EISA */
5345b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project		if ((k & 0xf0ff) != (PROD_ID & 0xf0ff))
5355b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project			goto no3c509;
5365b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	}
5375b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project#else
5385b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	if ((k & 0xf0ff) != (PROD_ID & 0xf0ff))
5395b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project		goto no3c509;
5405b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project#endif
5415b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
5425b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project#ifdef	INCLUDE_3C529
5435b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	if (mcafound) {
5445b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project		printf("%s board found on MCA at %#hx IRQ %d -",
5455b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project		       mcafound->name, eth_nic_base, mca_irq);
5465b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	} else {
5475b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project#endif
5485b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project		if(eth_nic_base >= EP_EISA_START)
5495b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project			printf("3C5x9 board on EISA at %#hx - ",eth_nic_base);
5505b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project		else
5515b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project			printf("3C5x9 board on ISA at %#hx - ",eth_nic_base);
5525b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project#ifdef	INCLUDE_3C529
5535b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	}
5545b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project#endif
5555b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
5565b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	/* test for presence of connectors */
5575b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	i = inw(IS_BASE + EP_W0_CONFIG_CTRL);
5585b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	j = (inw(IS_BASE + EP_W0_ADDRESS_CFG) >> 14) & 0x3;
5595b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
5605b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	switch(j) {
5615b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project		case 0:
5625b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project			if (i & IS_UTP) {
5635b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project				printf("10baseT\n");
5645b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project				connector = utp;
5655b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project				}
5665b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project			else {
5675b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project				printf("10baseT not present\n");
5685b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project				goto no3c509;
5695b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project				}
5705b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project			break;
5715b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project		case 1:
5725b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project			if (i & IS_AUI)
5735b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project				printf("10base5\n");
5745b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project			else {
5755b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project				printf("10base5 not present\n");
5765b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project				goto no3c509;
5775b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project				}
5785b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project			break;
5795b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project		case 3:
5805b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project			if (i & IS_BNC) {
5815b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project				printf("10base2\n");
5825b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project				connector = bnc;
5835b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project				}
5845b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project			else {
5855b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project				printf("10base2 not present\n");
5865b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project				goto no3c509;
5875b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project				}
5885b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project			break;
5895b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project		default:
5905b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project			printf("unknown connector\n");
5915b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project			goto no3c509;
5925b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project		}
5935b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	/*
5945b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	* Read the station address from the eeprom
5955b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	*/
5965b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	p = (unsigned short *) nic->node_addr;
5975b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	for (i = 0; i < ETH_ALEN / 2; i++) {
5985b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project		GO_WINDOW(0);
5995b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project		p[i] = htons(get_e(i));
6005b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project		GO_WINDOW(2);
6015b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project		outw(ntohs(p[i]), BASE + EP_W2_ADDR_0 + (i * 2));
6025b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	}
6035b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	printf("Ethernet address: %!\n", nic->node_addr);
6045b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	t509_reset(nic);
6055b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	nic->reset = t509_reset;
6065b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	nic->poll = t509_poll;
6075b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	nic->transmit = t509_transmit;
6085b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	nic->disable = t509_disable;
6095b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	return nic;
6105b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Projectno3c509:
6115b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	printf("(probe fail)");
6125b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	}
6135b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	return 0;
6145b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project}
6155b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
6165b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project/*
6175b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project * Local variables:
6185b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project *  c-basic-offset: 8
6195b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project * End:
6205b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project */
621