15b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project/*
25b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project    DAVICOM DM9009/DM9102/DM9102A Etherboot Driver	V1.00
35b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
45b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project    This driver was ported from Marty Conner's Tulip Etherboot driver.
55b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project    Thanks Marty Connor (mdc@thinguin.org)
65b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project    You can get Tulip driver source file from this URL:
75b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
85b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project    "http://etherboot.sourceforge..net/#Distribution"
95b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
105b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project    This davicom etherboot driver supports DM9009/DM9102/DM9102A/
115b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project    DM9102A+DM9801/DM9102A+DM9802 NICs.
125b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
135b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project    This software may be used and distributed according to the terms
145b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project    of the GNU Public License, incorporated herein by reference.
155b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
165b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project*/
175b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
185b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project/*********************************************************************/
195b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project/* Revision History                                                  */
205b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project/*********************************************************************/
215b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
225b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project/*
235b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project  19 OCT 2000  Sten     1.00
245b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project			Different half and full duplex mode
255b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project			Do the different programming for DM9801/DM9802
265b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
275b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project  12 OCT 2000  Sten     0.90
285b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project			This driver was ported from tulip driver and it
295b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project			has the following difference.
305b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project			Changed symbol tulip/TULIP to davicom/DAVICOM
315b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project			Deleted some code that did not use in this driver.
325b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project			Used chain-strcture to replace ring structure
335b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project			for both TX/RX descriptor.
345b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project			Allocated two tx descriptor.
355b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project			According current media mode to set operating
365b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project			register(CR6)
375b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project*/
385b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
395b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
405b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project/*********************************************************************/
415b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project/* Declarations                                                      */
425b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project/*********************************************************************/
435b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
445b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project#include "etherboot.h"
455b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project#include "nic.h"
465b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project#include "pci.h"
475b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project#include "cards.h"
485b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
495b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project#undef DAVICOM_DEBUG
505b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project#undef DAVICOM_DEBUG_WHERE
515b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
525b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project#define TX_TIME_OUT       2*TICKS_PER_SEC
535b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
545b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Projecttypedef unsigned char  u8;
555b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Projecttypedef   signed char  s8;
565b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Projecttypedef unsigned short u16;
575b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Projecttypedef   signed short s16;
585b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Projecttypedef unsigned int   u32;
595b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Projecttypedef   signed int   s32;
605b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
615b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project/* Register offsets for davicom device */
625b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Projectenum davicom_offsets {
635b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project   CSR0=0,     CSR1=0x08,  CSR2=0x10,  CSR3=0x18,  CSR4=0x20,  CSR5=0x28,
645b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project   CSR6=0x30,  CSR7=0x38,  CSR8=0x40,  CSR9=0x48, CSR10=0x50, CSR11=0x58,
655b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project  CSR12=0x60, CSR13=0x68, CSR14=0x70, CSR15=0x78, CSR16=0x80, CSR20=0xA0
665b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project};
675b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
685b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project/* EEPROM Address width definitions */
695b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project#define EEPROM_ADDRLEN 6
705b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project#define EEPROM_SIZE    32              /* 1 << EEPROM_ADDRLEN */
715b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project/* Used to be 128, but we only need to read enough to get the MAC
725b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project   address at bytes 20..25 */
735b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
745b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project/* Data Read from the EEPROM */
755b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Projectstatic unsigned char ee_data[EEPROM_SIZE];
765b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
775b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project/* The EEPROM commands include the alway-set leading bit. */
785b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project#define EE_WRITE_CMD    (5 << addr_len)
795b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project#define EE_READ_CMD     (6 << addr_len)
805b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project#define EE_ERASE_CMD    (7 << addr_len)
815b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
825b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project/* EEPROM_Ctrl bits. */
835b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project#define EE_SHIFT_CLK    0x02    /* EEPROM shift clock. */
845b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project#define EE_CS           0x01    /* EEPROM chip select. */
855b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project#define EE_DATA_WRITE   0x04    /* EEPROM chip data in. */
865b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project#define EE_WRITE_0      0x01
875b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project#define EE_WRITE_1      0x05
885b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project#define EE_DATA_READ    0x08    /* EEPROM chip data out. */
895b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project#define EE_ENB          (0x4800 | EE_CS)
905b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
915b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project/* Sten 10/11 for phyxcer */
925b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project#define PHY_DATA_0	0x0
935b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project#define PHY_DATA_1	0x20000
945b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project#define MDCLKH		0x10000
955b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
965b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project/* Delay between EEPROM clock transitions.  Even at 33Mhz current PCI
975b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project   implementations don't overrun the EEPROM clock.  We add a bus
985b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project   turn-around to insure that this remains true.  */
995b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project#define eeprom_delay()  inl(ee_addr)
1005b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
1015b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project/* helpful macro if on a big_endian machine for changing byte order.
1025b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project   not strictly needed on Intel */
1035b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project#define le16_to_cpu(val) (val)
1045b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
1055b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project/* transmit and receive descriptor format */
1065b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Projectstruct txdesc {
1075b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project  volatile unsigned long   status;         /* owner, status */
1085b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project  unsigned long   buf1sz:11,      /* size of buffer 1 */
1095b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project    buf2sz:11,                    /* size of buffer 2 */
1105b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project    control:10;                   /* control bits */
1115b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project  const unsigned char *buf1addr;  /* buffer 1 address */
1125b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project  const unsigned char *buf2addr;  /* buffer 2 address */
1135b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project};
1145b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
1155b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Projectstruct rxdesc {
1165b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project  volatile unsigned long   status;         /* owner, status */
1175b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project  unsigned long   buf1sz:11,      /* size of buffer 1 */
1185b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project    buf2sz:11,                    /* size of buffer 2 */
1195b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project    control:10;                   /* control bits */
1205b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project  unsigned char   *buf1addr;      /* buffer 1 address */
1215b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project  unsigned char   *buf2addr;      /* buffer 2 address */
1225b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project};
1235b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
1245b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project/* Size of transmit and receive buffers */
1255b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project#define BUFLEN 1536
1265b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
1275b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project/*********************************************************************/
1285b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project/* Global Storage                                                    */
1295b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project/*********************************************************************/
1305b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
1315b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project/* PCI Bus parameters */
1325b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Projectstatic unsigned short vendor, dev_id;
1335b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Projectstatic unsigned long ioaddr;
1345b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
1355b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project/* Note: transmit and receive buffers must be longword aligned and
1365b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project   longword divisable */
1375b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
1385b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project/* transmit descriptor and buffer */
1395b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project#define NTXD 2
1405b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Projectstatic struct txdesc txd[NTXD] __attribute__ ((aligned(4)));
1415b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project#ifdef	USE_LOWMEM_BUFFER
1425b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project#define txb ((char *)0x10000 - BUFLEN)
1435b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project#else
1445b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Projectstatic unsigned char txb[BUFLEN] __attribute__ ((aligned(4)));
1455b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project#endif
1465b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
1475b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project/* receive descriptor(s) and buffer(s) */
1485b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project#define NRXD 4
1495b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Projectstatic struct rxdesc rxd[NRXD] __attribute__ ((aligned(4)));
1505b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project#ifdef	USE_LOWMEM_BUFFER
1515b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project#define rxb ((char *)0x10000 - NRXD * BUFLEN - BUFLEN)
1525b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project#else
1535b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Projectstatic unsigned char rxb[NRXD * BUFLEN] __attribute__ ((aligned(4)));
1545b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project#endif
1555b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Projectstatic int rxd_tail;
1565b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Projectstatic int TxPtr;
1575b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
1585b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
1595b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project/*********************************************************************/
1605b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project/* Function Prototypes                                               */
1615b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project/*********************************************************************/
1625b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Projectstatic void whereami(const char *str);
1635b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Projectstatic int read_eeprom(unsigned long ioaddr, int location, int addr_len);
1645b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Projectstruct nic *davicom_probe(struct nic *nic, unsigned short *io_addrs,
1655b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project			struct pci_device *pci);
1665b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Projectstatic void davicom_init_chain(struct nic *nic);	/* Sten 10/9 */
1675b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Projectstatic void davicom_reset(struct nic *nic);
1685b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Projectstatic void davicom_transmit(struct nic *nic, const char *d, unsigned int t,
1695b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project			   unsigned int s, const char *p);
1705b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Projectstatic int davicom_poll(struct nic *nic);
1715b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Projectstatic void davicom_disable(struct nic *nic);
1725b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Projectstatic void whereami (const char *str);
1735b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project#ifdef	DAVICOM_DEBUG
1745b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Projectstatic void davicom_more(void);
1755b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project#endif /* DAVICOM_DEBUG */
1765b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Projectstatic void davicom_wait(unsigned int nticks);
1775b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Projectstatic int phy_read(int);
1785b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Projectstatic void phy_write(int, u16);
1795b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Projectstatic void phy_write_1bit(u32, u32);
1805b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Projectstatic int phy_read_1bit(u32);
1815b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Projectstatic void davicom_media_chk(struct nic *);
1825b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
1835b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
1845b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project/*********************************************************************/
1855b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project/* Utility Routines                                                  */
1865b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project/*********************************************************************/
1875b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
1885b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Projectstatic inline void whereami (const char *str)
1895b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project{
1905b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project#ifdef	DAVICOM_DEBUG_WHERE
1915b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project  printf("%s\n", str);
1925b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project  /* sleep(2); */
1935b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project#endif
1945b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project}
1955b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
1965b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project#ifdef	DAVICOM_DEBUG
1975b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Projectstatic void davicom_more()
1985b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project{
1995b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project  printf("\n\n-- more --");
2005b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project  while (!iskey())
2015b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project    /* wait */;
2025b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project  getchar();
2035b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project  printf("\n\n");
2045b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project}
2055b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project#endif /* DAVICOM_DEBUG */
2065b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
2075b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Projectstatic void davicom_wait(unsigned int nticks)
2085b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project{
2095b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project  unsigned int to = currticks() + nticks;
2105b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project  while (currticks() < to)
2115b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project    /* wait */ ;
2125b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project}
2135b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
2145b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
2155b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project/*********************************************************************/
2165b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project/* For DAVICOM phyxcer register by MII interface		     */
2175b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project/*********************************************************************/
2185b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project/*
2195b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project  Read a word data from phy register
2205b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project*/
2215b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Projectstatic int phy_read(int location)
2225b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project{
2235b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project int i, phy_addr=1;
2245b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project u16 phy_data;
2255b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project u32 io_dcr9;
2265b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
2275b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project whereami("phy_read\n");
2285b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
2295b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project io_dcr9 = ioaddr + CSR9;
2305b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
2315b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project /* Send 33 synchronization clock to Phy controller */
2325b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project for (i=0; i<34; i++)
2335b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project     phy_write_1bit(io_dcr9, PHY_DATA_1);
2345b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
2355b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project /* Send start command(01) to Phy */
2365b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project phy_write_1bit(io_dcr9, PHY_DATA_0);
2375b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project phy_write_1bit(io_dcr9, PHY_DATA_1);
2385b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
2395b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project /* Send read command(10) to Phy */
2405b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project phy_write_1bit(io_dcr9, PHY_DATA_1);
2415b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project phy_write_1bit(io_dcr9, PHY_DATA_0);
2425b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
2435b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project /* Send Phy addres */
2445b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project for (i=0x10; i>0; i=i>>1)
2455b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project     phy_write_1bit(io_dcr9, phy_addr&i ? PHY_DATA_1: PHY_DATA_0);
2465b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
2475b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project /* Send register addres */
2485b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project for (i=0x10; i>0; i=i>>1)
2495b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project     phy_write_1bit(io_dcr9, location&i ? PHY_DATA_1: PHY_DATA_0);
2505b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
2515b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project /* Skip transition state */
2525b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project phy_read_1bit(io_dcr9);
2535b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
2545b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project /* read 16bit data */
2555b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project for (phy_data=0, i=0; i<16; i++) {
2565b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project   phy_data<<=1;
2575b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project   phy_data|=phy_read_1bit(io_dcr9);
2585b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project }
2595b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
2605b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project return phy_data;
2615b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project}
2625b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
2635b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project/*
2645b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project  Write a word to Phy register
2655b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project*/
2665b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Projectstatic void phy_write(int location, u16 phy_data)
2675b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project{
2685b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project u16 i, phy_addr=1;
2695b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project u32 io_dcr9;
2705b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
2715b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project whereami("phy_write\n");
2725b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
2735b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project io_dcr9 = ioaddr + CSR9;
2745b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
2755b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project /* Send 33 synchronization clock to Phy controller */
2765b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project for (i=0; i<34; i++)
2775b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project   phy_write_1bit(io_dcr9, PHY_DATA_1);
2785b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
2795b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project /* Send start command(01) to Phy */
2805b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project phy_write_1bit(io_dcr9, PHY_DATA_0);
2815b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project phy_write_1bit(io_dcr9, PHY_DATA_1);
2825b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
2835b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project /* Send write command(01) to Phy */
2845b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project phy_write_1bit(io_dcr9, PHY_DATA_0);
2855b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project phy_write_1bit(io_dcr9, PHY_DATA_1);
2865b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
2875b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project /* Send Phy addres */
2885b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project for (i=0x10; i>0; i=i>>1)
2895b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project   phy_write_1bit(io_dcr9, phy_addr&i ? PHY_DATA_1: PHY_DATA_0);
2905b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
2915b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project /* Send register addres */
2925b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project for (i=0x10; i>0; i=i>>1)
2935b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project   phy_write_1bit(io_dcr9, location&i ? PHY_DATA_1: PHY_DATA_0);
2945b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
2955b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project /* written trasnition */
2965b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project phy_write_1bit(io_dcr9, PHY_DATA_1);
2975b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project phy_write_1bit(io_dcr9, PHY_DATA_0);
2985b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
2995b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project /* Write a word data to PHY controller */
3005b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project for (i=0x8000; i>0; i>>=1)
3015b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project   phy_write_1bit(io_dcr9, phy_data&i ? PHY_DATA_1: PHY_DATA_0);
3025b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project}
3035b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
3045b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project/*
3055b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project  Write one bit data to Phy Controller
3065b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project*/
3075b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Projectstatic void phy_write_1bit(u32 ee_addr, u32 phy_data)
3085b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project{
3095b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project whereami("phy_write_1bit\n");
3105b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project outl(phy_data, ee_addr);                        /* MII Clock Low */
3115b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project eeprom_delay();
3125b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project outl(phy_data|MDCLKH, ee_addr);                 /* MII Clock High */
3135b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project eeprom_delay();
3145b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project outl(phy_data, ee_addr);                        /* MII Clock Low */
3155b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project eeprom_delay();
3165b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project}
3175b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
3185b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project/*
3195b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project  Read one bit phy data from PHY controller
3205b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project*/
3215b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Projectstatic int phy_read_1bit(u32 ee_addr)
3225b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project{
3235b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project int phy_data;
3245b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
3255b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project whereami("phy_read_1bit\n");
3265b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
3275b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project outl(0x50000, ee_addr);
3285b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project eeprom_delay();
3295b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
3305b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project phy_data=(inl(ee_addr)>>19) & 0x1;
3315b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
3325b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project outl(0x40000, ee_addr);
3335b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project eeprom_delay();
3345b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
3355b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project return phy_data;
3365b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project}
3375b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
3385b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project/*
3395b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project  DM9801/DM9802 present check and program
3405b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project*/
3415b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Projectstatic void HPNA_process(void)
3425b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project{
3435b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
3445b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project if ( (phy_read(3) & 0xfff0) == 0xb900 ) {
3455b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project   if ( phy_read(31) == 0x4404 ) {
3465b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project     /* DM9801 present */
3475b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project     if (phy_read(3) == 0xb901)
3485b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project       phy_write(16, 0x5);	/* DM9801 E4 */
3495b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project     else
3505b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project       phy_write(16, 0x1005); /* DM9801 E3 and others */
3515b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project     phy_write(25, ((phy_read(24) + 3) & 0xff) | 0xf000);
3525b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project   } else {
3535b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project     /* DM9802 present */
3545b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project     phy_write(16, 0x5);
3555b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project     phy_write(25, (phy_read(25) & 0xff00) + 2);
3565b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project   }
3575b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project }
3585b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project}
3595b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
3605b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project/*
3615b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project  Sense media mode and set CR6
3625b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project*/
3635b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Projectstatic void davicom_media_chk(struct nic * nic)
3645b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project{
3655b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project  unsigned long to, csr6;
3665b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
3675b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project  csr6 = 0x00200000;	/* SF */
3685b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project  outl(csr6, ioaddr + CSR6);
3695b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
3705b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project  if (vendor == PCI_VENDOR_ID_DAVICOM && dev_id == PCI_DEVICE_ID_DM9009) {
3715b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project    /* Set to 10BaseT mode for DM9009 */
3725b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project    phy_write(0, 0);
3735b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project  } else {
3745b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project    /* For DM9102/DM9102A */
3755b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project    to = currticks() + 2 * TICKS_PER_SEC;
3765b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project    while ( ((phy_read(1) & 0x24)!=0x24) && (currticks() < to))
3775b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project      /* wait */ ;
3785b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
3795b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project    if ( (phy_read(1) & 0x24) == 0x24 ) {
3805b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project      if (phy_read(17) & 0xa000)
3815b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project        csr6 |= 0x00000200;	/* Full Duplex mode */
3825b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project    } else
3835b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project      csr6 |= 0x00040000; /* Select DM9801/DM9802 when Ethernet link failed */
3845b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project  }
3855b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
3865b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project  /* set the chip's operating mode */
3875b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project  outl(csr6, ioaddr + CSR6);
3885b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
3895b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project  /* DM9801/DM9802 present check & program */
3905b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project  if (csr6 & 0x40000)
3915b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project    HPNA_process();
3925b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project}
3935b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
3945b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
3955b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project/*********************************************************************/
3965b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project/* EEPROM Reading Code                                               */
3975b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project/*********************************************************************/
3985b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project/* EEPROM routines adapted from the Linux Tulip Code */
3995b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project/* Reading a serial EEPROM is a "bit" grungy, but we work our way
4005b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project   through:->.
4015b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project*/
4025b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Projectstatic int read_eeprom(unsigned long ioaddr, int location, int addr_len)
4035b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project{
4045b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project  int i;
4055b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project  unsigned short retval = 0;
4065b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project  long ee_addr = ioaddr + CSR9;
4075b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project  int read_cmd = location | EE_READ_CMD;
4085b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
4095b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project  whereami("read_eeprom\n");
4105b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
4115b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project  outl(EE_ENB & ~EE_CS, ee_addr);
4125b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project  outl(EE_ENB, ee_addr);
4135b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
4145b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project  /* Shift the read command bits out. */
4155b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project  for (i = 4 + addr_len; i >= 0; i--) {
4165b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project    short dataval = (read_cmd & (1 << i)) ? EE_DATA_WRITE : 0;
4175b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project    outl(EE_ENB | dataval, ee_addr);
4185b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project    eeprom_delay();
4195b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project    outl(EE_ENB | dataval | EE_SHIFT_CLK, ee_addr);
4205b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project    eeprom_delay();
4215b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project  }
4225b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project  outl(EE_ENB, ee_addr);
4235b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
4245b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project  for (i = 16; i > 0; i--) {
4255b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project    outl(EE_ENB | EE_SHIFT_CLK, ee_addr);
4265b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project    eeprom_delay();
4275b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project    retval = (retval << 1) | ((inl(ee_addr) & EE_DATA_READ) ? 1 : 0);
4285b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project    outl(EE_ENB, ee_addr);
4295b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project    eeprom_delay();
4305b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project  }
4315b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
4325b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project  /* Terminate the EEPROM access. */
4335b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project  outl(EE_ENB & ~EE_CS, ee_addr);
4345b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project  return retval;
4355b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project}
4365b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
4375b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project/*********************************************************************/
4385b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project/* davicom_init_chain - setup the tx and rx descriptors                */
4395b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project/* Sten 10/9							     */
4405b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project/*********************************************************************/
4415b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Projectstatic void davicom_init_chain(struct nic *nic)
4425b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project{
4435b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project  int i;
4445b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
4455b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project  /* setup the transmit descriptor */
4465b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project  /* Sten: Set 2 TX descriptor but use one TX buffer because
4475b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project	   it transmit a packet and wait complete every time. */
4485b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project  for (i=0; i<NTXD; i++) {
4495b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project    txd[i].buf1addr = &txb[0];		/* Used same TX buffer */
4505b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project    txd[i].buf2addr = (unsigned char *)&txd[i+1]; /*  Point to Next TX desc */
4515b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project    txd[i].buf1sz   = 0;
4525b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project    txd[i].buf2sz   = 0;
4535b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project    txd[i].control  = 0x184;           /* Begin/End/Chain */
4545b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project    txd[i].status   = 0x00000000;      /* give ownership to Host */
4555b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project  }
4565b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
4575b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project  /* construct perfect filter frame with mac address as first match
4585b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project     and broadcast address for all others */
4595b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project  for (i=0; i<192; i++) txb[i] = 0xFF;
4605b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project  txb[0] = nic->node_addr[0];
4615b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project  txb[1] = nic->node_addr[1];
4625b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project  txb[4] = nic->node_addr[2];
4635b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project  txb[5] = nic->node_addr[3];
4645b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project  txb[8] = nic->node_addr[4];
4655b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project  txb[9] = nic->node_addr[5];
4665b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
4675b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project  /* setup receive descriptor */
4685b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project  for (i=0; i<NRXD; i++) {
4695b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project    rxd[i].buf1addr = &rxb[i * BUFLEN];
4705b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project    rxd[i].buf2addr = (unsigned char *)&rxd[i+1]; /* Point to Next RX desc */
4715b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project    rxd[i].buf1sz   = BUFLEN;
4725b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project    rxd[i].buf2sz   = 0;        /* not used */
4735b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project    rxd[i].control  = 0x4;		/* Chain Structure */
4745b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project    rxd[i].status   = 0x80000000;   /* give ownership to device */
4755b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project  }
4765b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
4775b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project  /* Chain the last descriptor to first */
4785b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project  txd[NTXD - 1].buf2addr = (unsigned char *)&txd[0];
4795b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project  rxd[NRXD - 1].buf2addr = (unsigned char *)&rxd[0];
4805b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project  TxPtr = 0;
4815b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project  rxd_tail = 0;
4825b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project}
4835b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
4845b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
4855b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project/*********************************************************************/
4865b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project/* davicom_reset - Reset adapter                                         */
4875b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project/*********************************************************************/
4885b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Projectstatic void davicom_reset(struct nic *nic)
4895b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project{
4905b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project  unsigned long to;
4915b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project  u32 addr_low, addr_high;
4925b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
4935b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project  whereami("davicom_reset\n");
4945b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
4955b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project  /* Stop Tx and RX */
4965b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project  outl(inl(ioaddr + CSR6) & ~0x00002002, ioaddr + CSR6);
4975b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
4985b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project  /* Reset the chip, holding bit 0 set at least 50 PCI cycles. */
4995b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project  outl(0x00000001, ioaddr + CSR0);
5005b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
5015b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project  davicom_wait(TICKS_PER_SEC);
5025b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
5035b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project  /* TX/RX descriptor burst */
5045b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project  outl(0x0C00000, ioaddr + CSR0);	/* Sten 10/9 */
5055b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
5065b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project  /* set up transmit and receive descriptors */
5075b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project  davicom_init_chain(nic);	/* Sten 10/9 */
5085b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
5095b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project  /* Point to receive descriptor */
5105b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project  outl((unsigned long)&rxd[0], ioaddr + CSR3);
5115b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project  outl((unsigned long)&txd[0], ioaddr + CSR4);	/* Sten 10/9 */
5125b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
5135b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project  /* According phyxcer media mode to set CR6,
5145b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project     DM9102/A phyxcer can auto-detect media mode */
5155b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project  davicom_media_chk(nic);
5165b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
5175b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project  /* Prepare Setup Frame Sten 10/9 */
5185b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project  txd[TxPtr].buf1sz = 192;
5195b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project  txd[TxPtr].control = 0x024;		/* SF/CE */
5205b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project  txd[TxPtr].status = 0x80000000;	/* Give ownership to device */
5215b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
5225b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project  /* Start Tx */
5235b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project  outl(inl(ioaddr + CSR6) | 0x00002000, ioaddr + CSR6);
5245b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project  /* immediate transmit demand */
5255b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project  outl(0, ioaddr + CSR1);
5265b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
5275b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project  to = currticks() + TX_TIME_OUT;
5285b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project  while ((txd[TxPtr].status & 0x80000000) && (currticks() < to)) /* Sten 10/9 */
5295b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project    /* wait */ ;
5305b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
5315b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project  if (currticks() >= to) {
5325b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project    printf ("TX Setup Timeout!\n");
5335b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project  }
5345b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project  /* Point to next TX descriptor */
5355b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project TxPtr = (++TxPtr >= NTXD) ? 0:TxPtr;	/* Sten 10/9 */
5365b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
5375b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project#ifdef DAVICOM_DEBUG
5385b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project  printf("txd.status = %X\n", txd.status);
5395b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project  printf("ticks = %d\n", currticks() - (to - TX_TIME_OUT));
5405b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project  davicom_more();
5415b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project#endif
5425b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
5435b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project  /* enable RX */
5445b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project  outl(inl(ioaddr + CSR6) | 0x00000002, ioaddr + CSR6);
5455b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project  /* immediate poll demand */
5465b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project  outl(0, ioaddr + CSR2);
5475b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project}
5485b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
5495b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
5505b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project/*********************************************************************/
5515b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project/* eth_transmit - Transmit a frame                                   */
5525b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project/*********************************************************************/
5535b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Projectstatic void davicom_transmit(struct nic *nic, const char *d, unsigned int t,
5545b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project                           unsigned int s, const char *p)
5555b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project{
5565b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project  unsigned long to;
5575b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
5585b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project  whereami("davicom_transmit\n");
5595b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
5605b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project  /* Stop Tx */
5615b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project  /* outl(inl(ioaddr + CSR6) & ~0x00002000, ioaddr + CSR6); */
5625b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
5635b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project  /* setup ethernet header */
5645b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project  memcpy(&txb[0], d, ETH_ALEN);	/* DA 6byte */
5655b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project  memcpy(&txb[ETH_ALEN], nic->node_addr, ETH_ALEN); /* SA 6byte*/
5665b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project  txb[ETH_ALEN*2] = (t >> 8) & 0xFF; /* Frame type: 2byte */
5675b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project  txb[ETH_ALEN*2+1] = t & 0xFF;
5685b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project  memcpy(&txb[ETH_HLEN], p, s); /* Frame data */
5695b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
5705b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project  /* setup the transmit descriptor */
5715b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project  txd[TxPtr].buf1sz   = ETH_HLEN+s;
5725b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project  txd[TxPtr].control  = 0x00000184;      /* LS+FS+CE */
5735b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project  txd[TxPtr].status   = 0x80000000;      /* give ownership to device */
5745b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
5755b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project  /* immediate transmit demand */
5765b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project  outl(0, ioaddr + CSR1);
5775b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
5785b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project  to = currticks() + TX_TIME_OUT;
5795b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project  while ((txd[TxPtr].status & 0x80000000) && (currticks() < to))
5805b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project    /* wait */ ;
5815b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
5825b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project  if (currticks() >= to) {
5835b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project    printf ("TX Timeout!\n");
5845b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project  }
5855b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
5865b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project  /* Point to next TX descriptor */
5875b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project  TxPtr = (++TxPtr >= NTXD) ? 0:TxPtr;	/* Sten 10/9 */
5885b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
5895b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project}
5905b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
5915b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project/*********************************************************************/
5925b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project/* eth_poll - Wait for a frame                                       */
5935b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project/*********************************************************************/
5945b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Projectstatic int davicom_poll(struct nic *nic)
5955b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project{
5965b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project  whereami("davicom_poll\n");
5975b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
5985b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project  if (rxd[rxd_tail].status & 0x80000000)
5995b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project    return 0;
6005b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
6015b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project  whereami("davicom_poll got one\n");
6025b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
6035b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project  nic->packetlen = (rxd[rxd_tail].status & 0x3FFF0000) >> 16;
6045b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
6055b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project  if( rxd[rxd_tail].status & 0x00008000){
6065b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project      rxd[rxd_tail].status = 0x80000000;
6075b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project      rxd_tail++;
6085b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project      if (rxd_tail == NRXD) rxd_tail = 0;
6095b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project      return 0;
6105b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project  }
6115b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
6125b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project  /* copy packet to working buffer */
6135b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project  /* XXX - this copy could be avoided with a little more work
6145b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project     but for now we are content with it because the optimised
6155b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project     memcpy is quite fast */
6165b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
6175b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project  memcpy(nic->packet, rxb + rxd_tail * BUFLEN, nic->packetlen);
6185b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
6195b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project  /* return the descriptor and buffer to receive ring */
6205b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project  rxd[rxd_tail].status = 0x80000000;
6215b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project  rxd_tail++;
6225b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project  if (rxd_tail == NRXD) rxd_tail = 0;
6235b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
6245b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project  return 1;
6255b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project}
6265b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
6275b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project/*********************************************************************/
6285b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project/* eth_disable - Disable the interface                               */
6295b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project/*********************************************************************/
6305b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Projectstatic void davicom_disable(struct nic *nic)
6315b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project{
6325b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project  whereami("davicom_disable\n");
6335b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
6345b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project  /* disable interrupts */
6355b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project  outl(0x00000000, ioaddr + CSR7);
6365b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
6375b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project  /* Stop the chip's Tx and Rx processes. */
6385b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project  outl(inl(ioaddr + CSR6) & ~0x00002002, ioaddr + CSR6);
6395b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
6405b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project  /* Clear the missed-packet counter. */
6415b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project  (volatile unsigned long)inl(ioaddr + CSR8);
6425b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project}
6435b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
6445b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project/*********************************************************************/
6455b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project/* eth_probe - Look for an adapter                                   */
6465b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project/*********************************************************************/
6475b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Projectstruct nic *davicom_probe(struct nic *nic, unsigned short *io_addrs,
6485b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project                          struct pci_device *pci)
6495b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project{
6505b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project  unsigned int i;
6515b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project  u32 l1, l2;
6525b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
6535b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project  whereami("davicom_probe\n");
6545b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
6555b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project  if (io_addrs == 0 || *io_addrs == 0)
6565b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project    return 0;
6575b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
6585b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project  vendor  = pci->vendor;
6595b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project  dev_id  = pci->dev_id;
6605b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project  ioaddr  = *io_addrs;
6615b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
6625b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project  /* wakeup chip */
6635b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project  pcibios_write_config_dword(pci->bus, pci->devfn, 0x40, 0x00000000);
6645b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
6655b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project  /* Stop the chip's Tx and Rx processes. */
6665b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project  outl(inl(ioaddr + CSR6) & ~0x00002002, ioaddr + CSR6);
6675b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
6685b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project  /* Clear the missed-packet counter. */
6695b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project  (volatile unsigned long)inl(ioaddr + CSR8);
6705b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
6715b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project  /* Get MAC Address */
6725b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project  /* read EEPROM data */
6735b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project  for (i = 0; i < sizeof(ee_data)/2; i++)
6745b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project    ((unsigned short *)ee_data)[i] =
6755b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project        le16_to_cpu(read_eeprom(ioaddr, i, EEPROM_ADDRLEN));
6765b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
6775b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project  /* extract MAC address from EEPROM buffer */
6785b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project  for (i=0; i<ETH_ALEN; i++)
6795b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project    nic->node_addr[i] = ee_data[20+i];
6805b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
6815b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project  printf("Davicom %! at ioaddr %#hX\n", nic->node_addr, ioaddr);
6825b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
6835b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project  /* initialize device */
6845b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project  davicom_reset(nic);
6855b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
6865b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project  nic->reset    = davicom_reset;
6875b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project  nic->poll     = davicom_poll;
6885b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project  nic->transmit = davicom_transmit;
6895b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project  nic->disable  = davicom_disable;
6905b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project
6915b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project  return nic;
6925b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project}
693