15b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project/*
25b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project* 3c595.c -- 3COM 3C595 Fast Etherlink III PCI driver for etherboot
35b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project*
45b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project* Copyright (C) 2000 Shusuke Nisiyama <shu@athena.qe.eng.hokudai.ac.jp>
55b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project* All rights reserved.
65b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project* Mar. 14, 2000
75b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project*
85b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project*  This software may be used, modified, copied, distributed, and sold, in
95b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project*  both source and binary form provided that the above copyright and these
105b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project*  terms are retained. Under no circumstances are the authors responsible for
115b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project*  the proper functioning of this software, nor do the authors assume any
125b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project*  responsibility for damages incurred with its use.
135b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project*
145b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project* This code is based on Martin Renters' etherboot-4.4.3 3c509.c and
155b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project* Herb Peyerl's FreeBSD 3.4-RELEASE if_vx.c driver.
165b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project*
175b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project*  Copyright (C) 1993-1994, David Greenman, Martin Renters.
185b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project*  Copyright (C) 1993-1995, Andres Vega Garcia.
195b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project*  Copyright (C) 1995, Serge Babkin.
205b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project*
215b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project*  Copyright (c) 1994 Herb Peyerl <hpeyerl@novatel.ca>
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 "pci.h"
305b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project#include "3c595.h"
315b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project#include "timer.h"
325b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
335b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Projectstatic unsigned short	eth_nic_base, eth_asic_base;
345b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Projectstatic unsigned short	vx_connector, vx_connectors;
355b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
365b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Projectstatic struct connector_entry {
375b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project  int bit;
385b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project  char *name;
395b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project} conn_tab[VX_CONNECTORS] = {
405b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project#define CONNECTOR_UTP   0
415b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project  { 0x08, "utp"},
425b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project#define CONNECTOR_AUI   1
435b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project  { 0x20, "aui"},
445b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project/* dummy */
455b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project  { 0, "???"},
465b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project#define CONNECTOR_BNC   3
475b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project  { 0x10, "bnc"},
485b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project#define CONNECTOR_TX    4
495b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project  { 0x02, "tx"},
505b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project#define CONNECTOR_FX    5
515b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project  { 0x04, "fx"},
525b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project#define CONNECTOR_MII   6
535b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project  { 0x40, "mii"},
545b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project  { 0, "???"}
555b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project};
565b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
575b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Projectstatic void vxgetlink(void);
585b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Projectstatic void vxsetlink(void);
595b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
605b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project#define	udelay(n)	waiton_timer2(((n)*TICKS_PER_MS)/1000)
615b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
625b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project/**************************************************************************
635b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source ProjectETH_RESET - Reset adapter
645b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project***************************************************************************/
655b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Projectstatic void t595_reset(struct nic *nic)
665b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project{
675b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	int i, j;
685b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
695b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	/***********************************************************
705b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project			Reset 3Com 595 card
715b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	*************************************************************/
725b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
735b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	/* stop card */
745b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	outw(RX_DISABLE, BASE + VX_COMMAND);
755b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	outw(RX_DISCARD_TOP_PACK, BASE + VX_COMMAND);
765b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	VX_BUSY_WAIT;
775b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	outw(TX_DISABLE, BASE + VX_COMMAND);
785b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	outw(STOP_TRANSCEIVER, BASE + VX_COMMAND);
795b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	udelay(8000);
805b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	outw(RX_RESET, BASE + VX_COMMAND);
815b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	VX_BUSY_WAIT;
825b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	outw(TX_RESET, BASE + VX_COMMAND);
835b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	VX_BUSY_WAIT;
845b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	outw(C_INTR_LATCH, BASE + VX_COMMAND);
855b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	outw(SET_RD_0_MASK, BASE + VX_COMMAND);
865b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	outw(SET_INTR_MASK, BASE + VX_COMMAND);
875b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	outw(SET_RX_FILTER, BASE + VX_COMMAND);
885b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
895b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	/*
905b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	* initialize card
915b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	*/
925b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	VX_BUSY_WAIT;
935b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
945b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	GO_WINDOW(0);
955b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
965b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	/* Disable the card */
975b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project/*	outw(0, BASE + VX_W0_CONFIG_CTRL); */
985b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
995b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	/* Configure IRQ to none */
1005b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project/*	outw(SET_IRQ(0), BASE + VX_W0_RESOURCE_CFG); */
1015b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
1025b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	/* Enable the card */
1035b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project/*	outw(ENABLE_DRQ_IRQ, BASE + VX_W0_CONFIG_CTRL); */
1045b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
1055b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	GO_WINDOW(2);
1065b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
1075b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	/* Reload the ether_addr. */
1085b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	for (i = 0; i < ETH_ALEN; i++)
1095b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project		outb(nic->node_addr[i], BASE + VX_W2_ADDR_0 + i);
1105b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
1115b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	outw(RX_RESET, BASE + VX_COMMAND);
1125b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	VX_BUSY_WAIT;
1135b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	outw(TX_RESET, BASE + VX_COMMAND);
1145b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	VX_BUSY_WAIT;
1155b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
1165b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	/* Window 1 is operating window */
1175b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	GO_WINDOW(1);
1185b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	for (i = 0; i < 31; i++)
1195b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project		inb(BASE + VX_W1_TX_STATUS);
1205b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
1215b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	outw(SET_RD_0_MASK | S_CARD_FAILURE | S_RX_COMPLETE |
1225b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project		S_TX_COMPLETE | S_TX_AVAIL, BASE + VX_COMMAND);
1235b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	outw(SET_INTR_MASK | S_CARD_FAILURE | S_RX_COMPLETE |
1245b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project		S_TX_COMPLETE | S_TX_AVAIL, BASE + VX_COMMAND);
1255b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
1265b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project/*
1275b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project * Attempt to get rid of any stray interrupts that occured during
1285b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project * configuration.  On the i386 this isn't possible because one may
1295b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project * already be queued.  However, a single stray interrupt is
1305b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project * unimportant.
1315b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project */
1325b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
1335b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	outw(ACK_INTR | 0xff, BASE + VX_COMMAND);
1345b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
1355b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	outw(SET_RX_FILTER | FIL_INDIVIDUAL |
1365b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	    FIL_BRDCST, BASE + VX_COMMAND);
1375b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
1385b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	vxsetlink();
1395b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project/*{
1405b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	int i,j;
1415b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	i = CONNECTOR_TX;
1425b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	GO_WINDOW(3);
1435b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	j = inl(BASE + VX_W3_INTERNAL_CFG) & ~INTERNAL_CONNECTOR_MASK;
1445b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	outl(BASE + VX_W3_INTERNAL_CFG, j | (i <<INTERNAL_CONNECTOR_BITS));
1455b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project        GO_WINDOW(4);
1465b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project        outw(LINKBEAT_ENABLE, BASE + VX_W4_MEDIA_TYPE);
1475b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project        GO_WINDOW(1);
1485b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project}*/
1495b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
1505b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	/* start tranciever and receiver */
1515b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	outw(RX_ENABLE, BASE + VX_COMMAND);
1525b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	outw(TX_ENABLE, BASE + VX_COMMAND);
1535b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
1545b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project}
1555b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
1565b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project/**************************************************************************
1575b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source ProjectETH_TRANSMIT - Transmit a frame
1585b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project***************************************************************************/
1595b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Projectstatic char padmap[] = {
1605b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	0, 3, 2, 1};
1615b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
1625b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Projectstatic void t595_transmit(
1635b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Projectstruct nic *nic,
1645b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Projectconst char *d,			/* Destination */
1655b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Projectunsigned int t,			/* Type */
1665b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Projectunsigned int s,			/* size */
1675b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Projectconst char *p)			/* Packet */
1685b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project{
1695b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	register int len;
1705b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	int pad;
1715b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	int status;
1725b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
1735b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project#ifdef EDEBUG
1745b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	printf("{l=%d,t=%hX}",s+ETH_HLEN,t);
1755b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project#endif
1765b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
1775b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	/* swap bytes of type */
1785b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	t= htons(t);
1795b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
1805b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	len=s+ETH_HLEN; /* actual length of packet */
1815b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	pad = padmap[len & 3];
1825b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
1835b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	/*
1845b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	* The 3c595 automatically pads short packets to minimum ethernet length,
1855b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	* but we drop packets that are too large. Perhaps we should truncate
1865b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	* them instead?
1875b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	*/
1885b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	if (len + pad > ETH_FRAME_LEN) {
1895b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project		return;
1905b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	}
1915b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
1925b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	/* drop acknowledgements */
1935b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	while(( status=inb(BASE + VX_W1_TX_STATUS) )& TXS_COMPLETE ) {
1945b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project		if(status & (TXS_UNDERRUN|TXS_MAX_COLLISION|TXS_STATUS_OVERFLOW)) {
1955b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project			outw(TX_RESET, BASE + VX_COMMAND);
1965b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project			outw(TX_ENABLE, BASE + VX_COMMAND);
1975b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project		}
1985b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
1995b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project		outb(0x0, BASE + VX_W1_TX_STATUS);
2005b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	}
2015b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
2025b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	while (inw(BASE + VX_W1_FREE_TX) < len + pad + 4) {
2035b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project		/* no room in FIFO */
2045b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	}
2055b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
2065b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	outw(len, BASE + VX_W1_TX_PIO_WR_1);
2075b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	outw(0x0, BASE + VX_W1_TX_PIO_WR_1);	/* Second dword meaningless */
2085b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
2095b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	/* write packet */
2105b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	outsw(BASE + VX_W1_TX_PIO_WR_1, d, ETH_ALEN/2);
2115b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	outsw(BASE + VX_W1_TX_PIO_WR_1, nic->node_addr, ETH_ALEN/2);
2125b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	outw(t, BASE + VX_W1_TX_PIO_WR_1);
2135b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	outsw(BASE + VX_W1_TX_PIO_WR_1, p, s / 2);
2145b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	if (s & 1)
2155b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project		outb(*(p+s - 1), BASE + VX_W1_TX_PIO_WR_1);
2165b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
2175b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	while (pad--)
2185b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project		outb(0, BASE + VX_W1_TX_PIO_WR_1);	/* Padding */
2195b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
2205b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project        /* wait for Tx complete */
2215b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project        while((inw(BASE + VX_STATUS) & S_COMMAND_IN_PROGRESS) != 0)
2225b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project                ;
2235b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project}
2245b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
2255b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project/**************************************************************************
2265b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source ProjectETH_POLL - Wait for a frame
2275b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project***************************************************************************/
2285b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Projectstatic int t595_poll(struct nic *nic)
2295b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project{
2305b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	/* common variables */
2315b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	unsigned short type = 0;	/* used by EDEBUG */
2325b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	/* variables for 3C595 */
2335b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	short status, cst;
2345b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	register short rx_fifo;
2355b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
2365b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	cst=inw(BASE + VX_STATUS);
2375b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
2385b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project#ifdef EDEBUG
2395b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	if(cst & 0x1FFF)
2405b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project		printf("-%hX-",cst);
2415b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project#endif
2425b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
2435b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	if( (cst & S_RX_COMPLETE)==0 ) {
2445b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project		/* acknowledge  everything */
2455b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project		outw(ACK_INTR | cst, BASE + VX_COMMAND);
2465b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project		outw(C_INTR_LATCH, BASE + VX_COMMAND);
2475b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
2485b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project		return 0;
2495b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	}
2505b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
2515b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	status = inw(BASE + VX_W1_RX_STATUS);
2525b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project#ifdef EDEBUG
2535b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	printf("*%hX*",status);
2545b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project#endif
2555b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
2565b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	if (status & ERR_RX) {
2575b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project		outw(RX_DISCARD_TOP_PACK, BASE + VX_COMMAND);
2585b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project		return 0;
2595b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	}
2605b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
2615b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	rx_fifo = status & RX_BYTES_MASK;
2625b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	if (rx_fifo==0)
2635b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project		return 0;
2645b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
2655b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project		/* read packet */
2665b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project#ifdef EDEBUG
2675b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	printf("[l=%d",rx_fifo);
2685b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project#endif
2695b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	insw(BASE + VX_W1_RX_PIO_RD_1, nic->packet, rx_fifo / 2);
2705b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	if(rx_fifo & 1)
2715b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project		nic->packet[rx_fifo-1]=inb(BASE + VX_W1_RX_PIO_RD_1);
2725b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	nic->packetlen=rx_fifo;
2735b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
2745b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	while(1) {
2755b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project		status = inw(BASE + VX_W1_RX_STATUS);
2765b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project#ifdef EDEBUG
2775b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project		printf("*%hX*",status);
2785b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project#endif
2795b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project		rx_fifo = status & RX_BYTES_MASK;
2805b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
2815b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project		if(rx_fifo>0) {
2825b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project			insw(BASE + VX_W1_RX_PIO_RD_1, nic->packet+nic->packetlen, rx_fifo / 2);
2835b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project			if(rx_fifo & 1)
2845b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project				nic->packet[nic->packetlen+rx_fifo-1]=inb(BASE + VX_W1_RX_PIO_RD_1);
2855b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project			nic->packetlen+=rx_fifo;
2865b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project#ifdef EDEBUG
2875b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project			printf("+%d",rx_fifo);
2885b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project#endif
2895b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project		}
2905b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project		if(( status & RX_INCOMPLETE )==0) {
2915b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project#ifdef EDEBUG
2925b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project			printf("=%d",nic->packetlen);
2935b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project#endif
2945b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project			break;
2955b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project		}
2965b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project		udelay(1000);
2975b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	}
2985b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
2995b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	/* acknowledge reception of packet */
3005b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	outw(RX_DISCARD_TOP_PACK, BASE + VX_COMMAND);
3015b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	while (inw(BASE + VX_STATUS) & S_COMMAND_IN_PROGRESS);
3025b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project#ifdef EDEBUG
3035b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	type = (nic->packet[12]<<8) | nic->packet[13];
3045b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	if(nic->packet[0]+nic->packet[1]+nic->packet[2]+nic->packet[3]+nic->packet[4]+
3055b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	    nic->packet[5] == 0xFF*ETH_ALEN)
3065b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project		printf(",t=%hX,b]",type);
3075b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	else
3085b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project		printf(",t=%hX]",type);
3095b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project#endif
3105b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	return 1;
3115b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project}
3125b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
3135b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
3145b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project/*************************************************************************
3155b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	3Com 595 - specific routines
3165b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project**************************************************************************/
3175b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
3185b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Projectstatic int
3195b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Projecteeprom_rdy()
3205b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project{
3215b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	int i;
3225b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
3235b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	for (i = 0; is_eeprom_busy(BASE) && i < MAX_EEPROMBUSY; i++)
3245b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project		udelay(1000);
3255b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	if (i >= MAX_EEPROMBUSY) {
3265b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	        /* printf("3c595: eeprom failed to come ready.\n"); */
3275b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project		printf("3c595: eeprom is busy.\n"); /* memory in EPROM is tight */
3285b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project		return (0);
3295b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	}
3305b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	return (1);
3315b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project}
3325b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
3335b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project/*
3345b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project * get_e: gets a 16 bits word from the EEPROM. we must have set the window
3355b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project * before
3365b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project */
3375b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Projectstatic int
3385b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Projectget_e(offset)
3395b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Projectint offset;
3405b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project{
3415b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	if (!eeprom_rdy())
3425b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project		return (0xffff);
3435b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	outw(EEPROM_CMD_RD | offset, BASE + VX_W0_EEPROM_COMMAND);
3445b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	if (!eeprom_rdy())
3455b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project		return (0xffff);
3465b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	return (inw(BASE + VX_W0_EEPROM_DATA));
3475b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project}
3485b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
3495b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Projectstatic void
3505b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Projectvxgetlink(void)
3515b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project{
3525b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project    int n, k;
3535b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
3545b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project    GO_WINDOW(3);
3555b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project    vx_connectors = inw(BASE + VX_W3_RESET_OPT) & 0x7f;
3565b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project    for (n = 0, k = 0; k < VX_CONNECTORS; k++) {
3575b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project      if (vx_connectors & conn_tab[k].bit) {
3585b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project        if (n > 0) {
3595b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project          printf("/");
3605b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	}
3615b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project        printf(conn_tab[k].name);
3625b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project        n++;
3635b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project      }
3645b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project    }
3655b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project    if (vx_connectors == 0) {
3665b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project        printf("no connectors!");
3675b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project        return;
3685b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project    }
3695b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project    GO_WINDOW(3);
3705b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project    vx_connector = (inl(BASE + VX_W3_INTERNAL_CFG)
3715b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project                        & INTERNAL_CONNECTOR_MASK)
3725b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project                        >> INTERNAL_CONNECTOR_BITS;
3735b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project    if (vx_connector & 0x10) {
3745b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project        vx_connector &= 0x0f;
3755b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project        printf("[*%s*]", conn_tab[vx_connector].name);
3765b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project        printf(": disable 'auto select' with DOS util!");
3775b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project    } else {
3785b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project        printf("[*%s*]", conn_tab[vx_connector].name);
3795b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project    }
3805b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project}
3815b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
3825b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Projectstatic void
3835b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Projectvxsetlink(void)
3845b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project{
3855b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project    int i, j, k;
3865b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project    char *reason, *warning;
3875b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project    static short prev_flags;
3885b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project    static char prev_conn = -1;
3895b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
3905b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project    if (prev_conn == -1) {
3915b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project        prev_conn = vx_connector;
3925b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project    }
3935b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
3945b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project    i = vx_connector;       /* default in EEPROM */
3955b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project    reason = "default";
3965b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project    warning = 0;
3975b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
3985b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project    if ((vx_connectors & conn_tab[vx_connector].bit) == 0) {
3995b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project        warning = "strange connector type in EEPROM.";
4005b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project        reason = "forced";
4015b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project        i = CONNECTOR_UTP;
4025b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project    }
4035b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
4045b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project        if (warning != 0) {
4055b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project            printf("warning: %s\n", warning);
4065b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project        }
4075b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project        printf("selected %s. (%s)\n", conn_tab[i].name, reason);
4085b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
4095b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project    /* Set the selected connector. */
4105b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project    GO_WINDOW(3);
4115b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project    j = inl(BASE + VX_W3_INTERNAL_CFG) & ~INTERNAL_CONNECTOR_MASK;
4125b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project    outl(j | (i <<INTERNAL_CONNECTOR_BITS), BASE + VX_W3_INTERNAL_CFG);
4135b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
4145b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project    /* First, disable all. */
4155b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project    outw(STOP_TRANSCEIVER, BASE + VX_COMMAND);
4165b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project    udelay(8000);
4175b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project    GO_WINDOW(4);
4185b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project    outw(0, BASE + VX_W4_MEDIA_TYPE);
4195b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
4205b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project    /* Second, enable the selected one. */
4215b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project    switch(i) {
4225b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project      case CONNECTOR_UTP:
4235b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project        GO_WINDOW(4);
4245b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project        outw(ENABLE_UTP, BASE + VX_W4_MEDIA_TYPE);
4255b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project        break;
4265b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project      case CONNECTOR_BNC:
4275b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project        outw(START_TRANSCEIVER,BASE + VX_COMMAND);
4285b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project        udelay(8000);
4295b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project        break;
4305b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project      case CONNECTOR_TX:
4315b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project      case CONNECTOR_FX:
4325b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project        GO_WINDOW(4);
4335b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project        outw(LINKBEAT_ENABLE, BASE + VX_W4_MEDIA_TYPE);
4345b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project        break;
4355b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project      default:  /* AUI and MII fall here */
4365b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project        break;
4375b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project    }
4385b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project    GO_WINDOW(1);
4395b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project}
4405b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
4415b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Projectstatic void t595_disable(struct nic *nic)
4425b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project{
4435b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project    outw(STOP_TRANSCEIVER, BASE + VX_COMMAND);
4445b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project    udelay(8000);
4455b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project    GO_WINDOW(4);
4465b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project    outw(0, BASE + VX_W4_MEDIA_TYPE);
4475b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project    GO_WINDOW(1);
4485b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project}
4495b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
4505b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project/**************************************************************************
4515b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source ProjectETH_PROBE - Look for an adapter
4525b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project***************************************************************************/
4535b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Projectstruct nic *t595_probe(struct nic *nic, unsigned short *probeaddrs, struct pci_device *pci)
4545b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project{
4555b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	int i;
4565b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	unsigned short *p;
4575b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
4585b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	if (probeaddrs == 0 || probeaddrs[0] == 0)
4595b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project		return 0;
4605b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project/*	eth_nic_base = probeaddrs[0] & ~3; */
4615b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	eth_nic_base = pci->ioaddr;
4625b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
4635b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	GO_WINDOW(0);
4645b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	outw(GLOBAL_RESET, BASE + VX_COMMAND);
4655b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	VX_BUSY_WAIT;
4665b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
4675b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	vxgetlink();
4685b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
4695b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project/*
4705b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	printf("\nEEPROM:");
4715b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	for (i = 0; i < (EEPROMSIZE/2); i++) {
4725b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	  printf("%hX:", get_e(i));
4735b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	}
4745b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	printf("\n");
4755b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project*/
4765b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	/*
4775b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	* Read the station address from the eeprom
4785b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	*/
4795b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	p = (unsigned short *) nic->node_addr;
4805b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	for (i = 0; i < 3; i++) {
4815b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project		GO_WINDOW(0);
4825b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project		p[i] = htons(get_e(EEPROM_OEM_ADDR_0 + i));
4835b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project		GO_WINDOW(2);
4845b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project		outw(ntohs(p[i]), BASE + VX_W2_ADDR_0 + (i * 2));
4855b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	}
4865b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
4875b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	printf("Ethernet address: %!\n", nic->node_addr);
4885b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
4895b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	t595_reset(nic);
4905b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	nic->reset = t595_reset;
4915b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	nic->poll = t595_poll;
4925b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	nic->transmit = t595_transmit;
4935b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	nic->disable = t595_disable;
4945b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	return nic;
4955b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
4965b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project}
4975b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
4985b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project/*
4995b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project * Local variables:
5005b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project *  c-basic-offset: 8
5015b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project * End:
5025b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project */
5035b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
504