15b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project/************************************************************************** 25b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source ProjectETHERBOOT - BOOTP/TFTP Bootstrap Program 35b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project 45b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source ProjectAuthor: Martin Renters 55b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project Date: May/94 65b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project 75b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project This code is based heavily on David Greenman's if_ed.c driver 85b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project 95b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project Copyright (C) 1993-1994, David Greenman, Martin Renters. 105b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project This software may be used, modified, copied, distributed, and sold, in 115b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project both source and binary form provided that the above copyright and these 125b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project terms are retained. Under no circumstances are the authors responsible for 135b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project the proper functioning of this software, nor do the authors assume any 145b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project responsibility for damages incurred with its use. 155b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project 165b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project3c503 support added by Bill Paul (wpaul@ctr.columbia.edu) on 11/15/94 175b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source ProjectSMC8416 support added by Bill Paul (wpaul@ctr.columbia.edu) on 12/25/94 185b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project3c503 PIO support added by Jim Hague (jim.hague@acm.org) on 2/17/98 195b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source ProjectRX overrun by Klaus Espenlaub (espenlaub@informatik.uni-ulm.de) on 3/10/99 205b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project parts taken from the Linux 8390 driver (by Donald Becker and Paul Gortmaker) 215b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project 225b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project**************************************************************************/ 235b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project 245b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project#include "etherboot.h" 255b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project#include "nic.h" 265b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project#include "ns8390.h" 275b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project#ifdef INCLUDE_NS8390 285b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project#include "pci.h" 295b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project#endif 305b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project#include "cards.h" 315b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project 325b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Projectstatic unsigned char eth_vendor, eth_flags, eth_laar; 335b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Projectstatic unsigned short eth_nic_base, eth_asic_base; 345b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Projectstatic unsigned char eth_memsize, eth_rx_start, eth_tx_start; 355b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Projectstatic Address eth_bmem, eth_rmem; 365b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Projectstatic unsigned char eth_drain_receiver; 375b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project 385b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project#ifdef INCLUDE_WD 395b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Projectstatic struct wd_board { 405b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project const char *name; 415b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project char id; 425b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project char flags; 435b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project char memsize; 445b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project} wd_boards[] = { 455b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project {"WD8003S", TYPE_WD8003S, 0, MEM_8192}, 465b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project {"WD8003E", TYPE_WD8003E, 0, MEM_8192}, 475b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project {"WD8013EBT", TYPE_WD8013EBT, FLAG_16BIT, MEM_16384}, 485b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project {"WD8003W", TYPE_WD8003W, 0, MEM_8192}, 495b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project {"WD8003EB", TYPE_WD8003EB, 0, MEM_8192}, 505b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project {"WD8013W", TYPE_WD8013W, FLAG_16BIT, MEM_16384}, 515b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project {"WD8003EP/WD8013EP", 525b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project TYPE_WD8013EP, 0, MEM_8192}, 535b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project {"WD8013WC", TYPE_WD8013WC, FLAG_16BIT, MEM_16384}, 545b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project {"WD8013EPC", TYPE_WD8013EPC, FLAG_16BIT, MEM_16384}, 555b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project {"SMC8216T", TYPE_SMC8216T, FLAG_16BIT | FLAG_790, MEM_16384}, 565b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project {"SMC8216C", TYPE_SMC8216C, FLAG_16BIT | FLAG_790, MEM_16384}, 575b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project {"SMC8416T", TYPE_SMC8416T, FLAG_16BIT | FLAG_790, MEM_8192}, 585b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project {"SMC8416C/BT", TYPE_SMC8416C, FLAG_16BIT | FLAG_790, MEM_8192}, 595b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project {"SMC8013EBP", TYPE_SMC8013EBP,FLAG_16BIT, MEM_16384}, 605b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project {NULL, 0, 0, 0} 615b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project}; 625b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project#endif 635b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project 645b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project#ifdef INCLUDE_3C503 655b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Projectstatic unsigned char t503_output; /* AUI or internal xcvr (Thinnet) */ 665b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project#endif 675b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project 685b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project#if defined(INCLUDE_WD) 695b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project#define eth_probe wd_probe 705b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project#if defined(INCLUDE_3C503) || defined(INCLUDE_NE) || defined(INCLUDE_NS8390) 715b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source ProjectError you must only define one of INCLUDE_WD, INCLUDE_3C503, INCLUDE_NE, INCLUDE_NS8390 725b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project#endif 735b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project#endif 745b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project 755b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project#if defined(INCLUDE_3C503) 765b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project#define eth_probe t503_probe 775b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project#if defined(INCLUDE_NE) || defined(INCLUDE_NS8390) || defined(INCLUDE_WD) 785b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source ProjectError you must only define one of INCLUDE_WD, INCLUDE_3C503, INCLUDE_NE, INCLUDE_NS8390 795b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project#endif 805b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project#endif 815b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project 825b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project#if defined(INCLUDE_NE) 835b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project#define eth_probe ne_probe 845b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project#if defined(INCLUDE_NS8390) || defined(INCLUDE_3C503) || defined(INCLUDE_WD) 855b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source ProjectError you must only define one of INCLUDE_WD, INCLUDE_3C503, INCLUDE_NE, INCLUDE_NS8390 865b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project#endif 875b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project#endif 885b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project 895b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project#if defined(INCLUDE_NS8390) 905b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project#define eth_probe nepci_probe 915b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project#if defined(INCLUDE_NE) || defined(INCLUDE_3C503) || defined(INCLUDE_WD) 925b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source ProjectError you must only define one of INCLUDE_WD, INCLUDE_3C503, INCLUDE_NE, INCLUDE_NS8390 935b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project#endif 945b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project#endif 955b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project 965b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project#if defined(INCLUDE_3C503) 975b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project#define ASIC_PIO _3COM_RFMSB 985b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project#else 995b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project#if defined(INCLUDE_NE) || defined(INCLUDE_NS8390) 1005b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project#define ASIC_PIO NE_DATA 1015b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project#endif 1025b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project#endif 1035b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project 1045b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project#if defined(INCLUDE_NE) || defined(INCLUDE_NS8390) || (defined(INCLUDE_3C503) && !defined(T503_SHMEM)) 1055b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project/************************************************************************** 1065b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source ProjectETH_PIO_READ - Read a frame via Programmed I/O 1075b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project**************************************************************************/ 1085b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Projectstatic void eth_pio_read(unsigned int src, unsigned char *dst, unsigned int cnt) 1095b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project{ 1105b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project if (eth_flags & FLAG_16BIT) { ++cnt; cnt &= ~1; } 1115b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project outb(D8390_COMMAND_RD2 | 1125b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project D8390_COMMAND_STA, eth_nic_base + D8390_P0_COMMAND); 1135b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project outb(cnt, eth_nic_base + D8390_P0_RBCR0); 1145b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project outb(cnt>>8, eth_nic_base + D8390_P0_RBCR1); 1155b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project outb(src, eth_nic_base + D8390_P0_RSAR0); 1165b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project outb(src>>8, eth_nic_base + D8390_P0_RSAR1); 1175b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project outb(D8390_COMMAND_RD0 | 1185b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project D8390_COMMAND_STA, eth_nic_base + D8390_P0_COMMAND); 1195b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project 1205b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project#ifdef INCLUDE_3C503 1215b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project outb(src & 0xff, eth_asic_base + _3COM_DALSB); 1225b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project outb(src >> 8, eth_asic_base + _3COM_DAMSB); 1235b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project outb(t503_output | _3COM_CR_START, eth_asic_base + _3COM_CR); 1245b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project#endif 1255b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project 1265b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project if (eth_flags & FLAG_16BIT) 1275b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project cnt >>= 1; 1285b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project 1295b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project while(cnt--) { 1305b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project#ifdef INCLUDE_3C503 1315b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project while((inb(eth_asic_base + _3COM_STREG) & _3COM_STREG_DPRDY) == 0) 1325b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project ; 1335b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project#endif 1345b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project 1355b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project if (eth_flags & FLAG_16BIT) { 1365b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project *((unsigned short *)dst) = inw(eth_asic_base + ASIC_PIO); 1375b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project dst += 2; 1385b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project } 1395b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project else 1405b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project *(dst++) = inb(eth_asic_base + ASIC_PIO); 1415b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project } 1425b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project 1435b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project#ifdef INCLUDE_3C503 1445b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project outb(t503_output, eth_asic_base + _3COM_CR); 1455b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project#endif 1465b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project} 1475b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project 1485b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project/************************************************************************** 1495b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source ProjectETH_PIO_WRITE - Write a frame via Programmed I/O 1505b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project**************************************************************************/ 1515b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Projectstatic void eth_pio_write(const unsigned char *src, unsigned int dst, unsigned int cnt) 1525b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project{ 1535b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project#ifdef COMPEX_RL2000_FIX 1545b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project unsigned int x; 1555b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project#endif /* COMPEX_RL2000_FIX */ 1565b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project if (eth_flags & FLAG_16BIT) { ++cnt; cnt &= ~1; } 1575b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project outb(D8390_COMMAND_RD2 | 1585b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project D8390_COMMAND_STA, eth_nic_base + D8390_P0_COMMAND); 1595b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project outb(D8390_ISR_RDC, eth_nic_base + D8390_P0_ISR); 1605b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project outb(cnt, eth_nic_base + D8390_P0_RBCR0); 1615b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project outb(cnt>>8, eth_nic_base + D8390_P0_RBCR1); 1625b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project outb(dst, eth_nic_base + D8390_P0_RSAR0); 1635b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project outb(dst>>8, eth_nic_base + D8390_P0_RSAR1); 1645b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project outb(D8390_COMMAND_RD1 | 1655b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project D8390_COMMAND_STA, eth_nic_base + D8390_P0_COMMAND); 1665b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project 1675b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project#ifdef INCLUDE_3C503 1685b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project outb(dst & 0xff, eth_asic_base + _3COM_DALSB); 1695b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project outb(dst >> 8, eth_asic_base + _3COM_DAMSB); 1705b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project 1715b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project outb(t503_output | _3COM_CR_DDIR | _3COM_CR_START, eth_asic_base + _3COM_CR); 1725b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project#endif 1735b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project 1745b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project if (eth_flags & FLAG_16BIT) 1755b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project cnt >>= 1; 1765b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project 1775b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project while(cnt--) 1785b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project { 1795b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project#ifdef INCLUDE_3C503 1805b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project while((inb(eth_asic_base + _3COM_STREG) & _3COM_STREG_DPRDY) == 0) 1815b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project ; 1825b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project#endif 1835b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project 1845b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project if (eth_flags & FLAG_16BIT) { 1855b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project outw(*((unsigned short *)src), eth_asic_base + ASIC_PIO); 1865b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project src += 2; 1875b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project } 1885b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project else 1895b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project outb(*(src++), eth_asic_base + ASIC_PIO); 1905b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project } 1915b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project 1925b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project#ifdef INCLUDE_3C503 1935b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project outb(t503_output, eth_asic_base + _3COM_CR); 1945b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project#else 1955b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project#ifdef COMPEX_RL2000_FIX 1965b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project for (x = 0; 1975b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project x < COMPEX_RL2000_TRIES && 1985b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project (inb(eth_nic_base + D8390_P0_ISR) & D8390_ISR_RDC) 1995b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project != D8390_ISR_RDC; 2005b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project ++x); 2015b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project if (x >= COMPEX_RL2000_TRIES) 2025b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project printf("Warning: Compex RL2000 aborted wait!\n"); 2035b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project#endif /* COMPEX_RL2000_FIX */ 2045b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project while((inb(eth_nic_base + D8390_P0_ISR) & D8390_ISR_RDC) 2055b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project != D8390_ISR_RDC); 2065b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project#endif 2075b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project} 2085b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project#else 2095b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project/************************************************************************** 2105b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source ProjectETH_PIO_READ - Dummy routine when NE2000 not compiled in 2115b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project**************************************************************************/ 2125b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Projectstatic void eth_pio_read(unsigned int src, unsigned char *dst, unsigned int cnt) {} 2135b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project#endif 2145b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project 2155b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project/************************************************************************** 2165b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source ProjectNS8390_RESET - Reset adapter 2175b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project**************************************************************************/ 2185b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Projectstatic void ns8390_reset(struct nic *nic) 2195b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project{ 2205b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project int i; 2215b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project 2225b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project eth_drain_receiver = 0; 2235b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project#ifdef INCLUDE_WD 2245b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project if (eth_flags & FLAG_790) 2255b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project outb(D8390_COMMAND_PS0 | D8390_COMMAND_STP, eth_nic_base+D8390_P0_COMMAND); 2265b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project else 2275b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project#endif 2285b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project outb(D8390_COMMAND_PS0 | D8390_COMMAND_RD2 | 2295b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project D8390_COMMAND_STP, eth_nic_base+D8390_P0_COMMAND); 2305b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project if (eth_flags & FLAG_16BIT) 2315b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project outb(0x49, eth_nic_base+D8390_P0_DCR); 2325b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project else 2335b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project outb(0x48, eth_nic_base+D8390_P0_DCR); 2345b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project outb(0, eth_nic_base+D8390_P0_RBCR0); 2355b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project outb(0, eth_nic_base+D8390_P0_RBCR1); 2365b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project outb(0x20, eth_nic_base+D8390_P0_RCR); /* monitor mode */ 2375b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project outb(2, eth_nic_base+D8390_P0_TCR); 2385b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project outb(eth_tx_start, eth_nic_base+D8390_P0_TPSR); 2395b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project outb(eth_rx_start, eth_nic_base+D8390_P0_PSTART); 2405b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project#ifdef INCLUDE_WD 2415b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project if (eth_flags & FLAG_790) outb(0, eth_nic_base + 0x09); 2425b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project#endif 2435b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project outb(eth_memsize, eth_nic_base+D8390_P0_PSTOP); 2445b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project outb(eth_memsize - 1, eth_nic_base+D8390_P0_BOUND); 2455b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project outb(0xFF, eth_nic_base+D8390_P0_ISR); 2465b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project outb(0, eth_nic_base+D8390_P0_IMR); 2475b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project#ifdef INCLUDE_WD 2485b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project if (eth_flags & FLAG_790) 2495b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project outb(D8390_COMMAND_PS1 | 2505b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project D8390_COMMAND_STP, eth_nic_base+D8390_P0_COMMAND); 2515b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project else 2525b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project#endif 2535b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project outb(D8390_COMMAND_PS1 | 2545b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project D8390_COMMAND_RD2 | D8390_COMMAND_STP, eth_nic_base+D8390_P0_COMMAND); 2555b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project for (i=0; i<ETH_ALEN; i++) 2565b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project outb(nic->node_addr[i], eth_nic_base+D8390_P1_PAR0+i); 2575b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project for (i=0; i<ETH_ALEN; i++) 2585b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project outb(0xFF, eth_nic_base+D8390_P1_MAR0+i); 2595b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project outb(eth_rx_start, eth_nic_base+D8390_P1_CURR); 2605b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project#ifdef INCLUDE_WD 2615b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project if (eth_flags & FLAG_790) 2625b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project outb(D8390_COMMAND_PS0 | 2635b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project D8390_COMMAND_STA, eth_nic_base+D8390_P0_COMMAND); 2645b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project else 2655b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project#endif 2665b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project outb(D8390_COMMAND_PS0 | 2675b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project D8390_COMMAND_RD2 | D8390_COMMAND_STA, eth_nic_base+D8390_P0_COMMAND); 2685b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project outb(0xFF, eth_nic_base+D8390_P0_ISR); 2695b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project outb(0, eth_nic_base+D8390_P0_TCR); 2705b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project outb(4, eth_nic_base+D8390_P0_RCR); /* allow broadcast frames */ 2715b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project 2725b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project#ifdef INCLUDE_3C503 2735b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project /* 2745b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project * No way to tell whether or not we're supposed to use 2755b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project * the 3Com's transceiver unless the user tells us. 2765b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project * 'flags' should have some compile time default value 2775b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project * which can be changed from the command menu. 2785b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project */ 2795b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project t503_output = (nic->flags) ? 0 : _3COM_CR_XSEL; 2805b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project outb(t503_output, eth_asic_base + _3COM_CR); 2815b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project#endif 2825b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project} 2835b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project 2845b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Projectstatic int ns8390_poll(struct nic *nic); 2855b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project 2865b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project#ifndef INCLUDE_3C503 2875b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project/************************************************************************** 2885b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source ProjectETH_RX_OVERRUN - Bring adapter back to work after an RX overrun 2895b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project**************************************************************************/ 2905b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Projectstatic void eth_rx_overrun(struct nic *nic) 2915b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project{ 2925b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project int start_time; 2935b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project 2945b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project#ifdef INCLUDE_WD 2955b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project if (eth_flags & FLAG_790) 2965b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project outb(D8390_COMMAND_PS0 | D8390_COMMAND_STP, eth_nic_base+D8390_P0_COMMAND); 2975b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project else 2985b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project#endif 2995b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project outb(D8390_COMMAND_PS0 | D8390_COMMAND_RD2 | 3005b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project D8390_COMMAND_STP, eth_nic_base+D8390_P0_COMMAND); 3015b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project 3025b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project /* wait for at least 1.6ms - we wait one timer tick */ 3035b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project start_time = currticks(); 3045b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project while (currticks() - start_time <= 1) 3055b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project /* Nothing */; 3065b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project 3075b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project outb(0, eth_nic_base+D8390_P0_RBCR0); /* reset byte counter */ 3085b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project outb(0, eth_nic_base+D8390_P0_RBCR1); 3095b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project 3105b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project /* 3115b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project * Linux driver checks for interrupted TX here. This is not necessary, 3125b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project * because the transmit routine waits until the frame is sent. 3135b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project */ 3145b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project 3155b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project /* enter loopback mode and restart NIC */ 3165b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project outb(2, eth_nic_base+D8390_P0_TCR); 3175b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project#ifdef INCLUDE_WD 3185b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project if (eth_flags & FLAG_790) 3195b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project outb(D8390_COMMAND_PS0 | D8390_COMMAND_STA, eth_nic_base+D8390_P0_COMMAND); 3205b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project else 3215b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project#endif 3225b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project outb(D8390_COMMAND_PS0 | D8390_COMMAND_RD2 | 3235b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project D8390_COMMAND_STA, eth_nic_base+D8390_P0_COMMAND); 3245b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project 3255b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project /* clear the RX ring, acknowledge overrun interrupt */ 3265b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project eth_drain_receiver = 1; 3275b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project while (ns8390_poll(nic)) 3285b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project /* Nothing */; 3295b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project eth_drain_receiver = 0; 3305b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project outb(D8390_ISR_OVW, eth_nic_base+D8390_P0_ISR); 3315b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project 3325b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project /* leave loopback mode - no packets to be resent (see Linux driver) */ 3335b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project outb(0, eth_nic_base+D8390_P0_TCR); 3345b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project} 3355b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project#endif /* INCLUDE_3C503 */ 3365b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project 3375b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project/************************************************************************** 3385b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source ProjectNS8390_TRANSMIT - Transmit a frame 3395b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project**************************************************************************/ 3405b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Projectstatic void ns8390_transmit( 3415b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project struct nic *nic, 3425b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project const char *d, /* Destination */ 3435b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project unsigned int t, /* Type */ 3445b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project unsigned int s, /* size */ 3455b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project const char *p) /* Packet */ 3465b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project{ 3475b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project#ifdef INCLUDE_3C503 3485b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project if (!(eth_flags & FLAG_PIO)) { 3495b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project memcpy((char *)eth_bmem, d, ETH_ALEN); /* dst */ 3505b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project memcpy((char *)eth_bmem+ETH_ALEN, nic->node_addr, ETH_ALEN); /* src */ 3515b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project *((char *)eth_bmem+12) = t>>8; /* type */ 3525b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project *((char *)eth_bmem+13) = t; 3535b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project memcpy((char *)eth_bmem+ETH_HLEN, p, s); 3545b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project s += ETH_HLEN; 3555b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project while (s < ETH_ZLEN) *((char *)eth_bmem+(s++)) = 0; 3565b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project } 3575b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project#endif 3585b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project 3595b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project#ifdef INCLUDE_WD 3605b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project /* Memory interface */ 3615b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project if (eth_flags & FLAG_16BIT) { 3625b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project outb(eth_laar | WD_LAAR_M16EN, eth_asic_base + WD_LAAR); 3635b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project inb(0x84); 3645b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project } 3655b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project if (eth_flags & FLAG_790) { 3665b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project outb(WD_MSR_MENB, eth_asic_base + WD_MSR); 3675b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project inb(0x84); 3685b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project } 3695b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project inb(0x84); 3705b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project memcpy((char *)eth_bmem, d, ETH_ALEN); /* dst */ 3715b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project memcpy((char *)eth_bmem+ETH_ALEN, nic->node_addr, ETH_ALEN); /* src */ 3725b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project *((char *)eth_bmem+12) = t>>8; /* type */ 3735b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project *((char *)eth_bmem+13) = t; 3745b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project memcpy((char *)eth_bmem+ETH_HLEN, p, s); 3755b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project s += ETH_HLEN; 3765b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project while (s < ETH_ZLEN) *((char *)eth_bmem+(s++)) = 0; 3775b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project if (eth_flags & FLAG_790) { 3785b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project outb(0, eth_asic_base + WD_MSR); 3795b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project inb(0x84); 3805b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project } 3815b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project if (eth_flags & FLAG_16BIT) { 3825b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project outb(eth_laar & ~WD_LAAR_M16EN, eth_asic_base + WD_LAAR); 3835b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project inb(0x84); 3845b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project } 3855b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project#endif 3865b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project 3875b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project#if defined(INCLUDE_3C503) 3885b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project if (eth_flags & FLAG_PIO) { 3895b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project#endif 3905b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project#if defined(INCLUDE_NE) || defined(INCLUDE_NS8390) || (defined(INCLUDE_3C503) && !defined(T503_SHMEM)) 3915b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project /* Programmed I/O */ 3925b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project unsigned short type; 3935b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project type = (t >> 8) | (t << 8); 3945b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project eth_pio_write(d, eth_tx_start<<8, ETH_ALEN); 3955b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project eth_pio_write(nic->node_addr, (eth_tx_start<<8)+ETH_ALEN, ETH_ALEN); 3965b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project /* bcc generates worse code without (const+const) below */ 3975b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project eth_pio_write((unsigned char *)&type, (eth_tx_start<<8)+(ETH_ALEN+ETH_ALEN), 2); 3985b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project eth_pio_write(p, (eth_tx_start<<8)+ETH_HLEN, s); 3995b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project s += ETH_HLEN; 4005b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project if (s < ETH_ZLEN) s = ETH_ZLEN; 4015b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project#endif 4025b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project#if defined(INCLUDE_3C503) 4035b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project } 4045b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project#endif 4055b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project 4065b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project#ifdef INCLUDE_WD 4075b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project if (eth_flags & FLAG_790) 4085b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project outb(D8390_COMMAND_PS0 | 4095b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project D8390_COMMAND_STA, eth_nic_base+D8390_P0_COMMAND); 4105b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project else 4115b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project#endif 4125b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project outb(D8390_COMMAND_PS0 | 4135b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project D8390_COMMAND_RD2 | D8390_COMMAND_STA, eth_nic_base+D8390_P0_COMMAND); 4145b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project outb(eth_tx_start, eth_nic_base+D8390_P0_TPSR); 4155b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project outb(s, eth_nic_base+D8390_P0_TBCR0); 4165b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project outb(s>>8, eth_nic_base+D8390_P0_TBCR1); 4175b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project#ifdef INCLUDE_WD 4185b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project if (eth_flags & FLAG_790) 4195b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project outb(D8390_COMMAND_PS0 | 4205b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project D8390_COMMAND_TXP | D8390_COMMAND_STA, eth_nic_base+D8390_P0_COMMAND); 4215b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project else 4225b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project#endif 4235b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project outb(D8390_COMMAND_PS0 | 4245b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project D8390_COMMAND_TXP | D8390_COMMAND_RD2 | 4255b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project D8390_COMMAND_STA, eth_nic_base+D8390_P0_COMMAND); 4265b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project} 4275b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project 4285b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project/************************************************************************** 4295b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source ProjectNS8390_POLL - Wait for a frame 4305b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project**************************************************************************/ 4315b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Projectstatic int ns8390_poll(struct nic *nic) 4325b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project{ 4335b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project int ret = 0; 4345b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project unsigned char rstat, curr, next; 4355b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project unsigned short len, frag; 4365b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project unsigned short pktoff; 4375b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project unsigned char *p; 4385b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project struct ringbuffer pkthdr; 4395b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project 4405b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project#ifndef INCLUDE_3C503 4415b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project /* avoid infinite recursion: see eth_rx_overrun() */ 4425b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project if (!eth_drain_receiver && (inb(eth_nic_base+D8390_P0_ISR) & D8390_ISR_OVW)) { 4435b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project eth_rx_overrun(nic); 4445b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project return(0); 4455b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project } 4465b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project#endif /* INCLUDE_3C503 */ 4475b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project rstat = inb(eth_nic_base+D8390_P0_RSR); 4485b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project if (!(rstat & D8390_RSTAT_PRX)) return(0); 4495b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project next = inb(eth_nic_base+D8390_P0_BOUND)+1; 4505b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project if (next >= eth_memsize) next = eth_rx_start; 4515b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project outb(D8390_COMMAND_PS1, eth_nic_base+D8390_P0_COMMAND); 4525b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project curr = inb(eth_nic_base+D8390_P1_CURR); 4535b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project outb(D8390_COMMAND_PS0, eth_nic_base+D8390_P0_COMMAND); 4545b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project if (curr >= eth_memsize) curr=eth_rx_start; 4555b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project if (curr == next) return(0); 4565b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project#ifdef INCLUDE_WD 4575b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project if (eth_flags & FLAG_16BIT) { 4585b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project outb(eth_laar | WD_LAAR_M16EN, eth_asic_base + WD_LAAR); 4595b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project inb(0x84); 4605b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project } 4615b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project if (eth_flags & FLAG_790) { 4625b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project outb(WD_MSR_MENB, eth_asic_base + WD_MSR); 4635b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project inb(0x84); 4645b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project } 4655b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project inb(0x84); 4665b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project#endif 4675b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project pktoff = next << 8; 4685b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project if (eth_flags & FLAG_PIO) 4695b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project eth_pio_read(pktoff, (char *)&pkthdr, 4); 4705b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project else 4715b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project memcpy(&pkthdr, (char *)eth_rmem + pktoff, 4); 4725b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project pktoff += sizeof(pkthdr); 4735b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project /* incoming length includes FCS so must sub 4 */ 4745b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project len = pkthdr.len - 4; 4755b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project if ((pkthdr.status & D8390_RSTAT_PRX) == 0 || len < ETH_ZLEN 4765b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project || len > ETH_FRAME_LEN) { 4775b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project printf("Bogus packet, ignoring\n"); 4785b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project return (0); 4795b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project } 4805b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project else { 4815b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project p = nic->packet; 4825b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project nic->packetlen = len; /* available to caller */ 4835b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project frag = (eth_memsize << 8) - pktoff; 4845b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project if (len > frag) { /* We have a wrap-around */ 4855b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project /* read first part */ 4865b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project if (eth_flags & FLAG_PIO) 4875b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project eth_pio_read(pktoff, p, frag); 4885b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project else 4895b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project memcpy(p, (char *)eth_rmem + pktoff, frag); 4905b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project pktoff = eth_rx_start << 8; 4915b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project p += frag; 4925b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project len -= frag; 4935b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project } 4945b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project /* read second part */ 4955b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project if (eth_flags & FLAG_PIO) 4965b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project eth_pio_read(pktoff, p, len); 4975b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project else 4985b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project memcpy(p, (char *)eth_rmem + pktoff, len); 4995b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project ret = 1; 5005b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project } 5015b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project#ifdef INCLUDE_WD 5025b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project if (eth_flags & FLAG_790) { 5035b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project outb(0, eth_asic_base + WD_MSR); 5045b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project inb(0x84); 5055b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project } 5065b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project if (eth_flags & FLAG_16BIT) { 5075b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project outb(eth_laar & ~WD_LAAR_M16EN, eth_asic_base + WD_LAAR); 5085b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project inb(0x84); 5095b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project } 5105b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project inb(0x84); 5115b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project#endif 5125b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project next = pkthdr.next; /* frame number of next packet */ 5135b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project if (next == eth_rx_start) 5145b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project next = eth_memsize; 5155b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project outb(next-1, eth_nic_base+D8390_P0_BOUND); 5165b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project return(ret); 5175b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project} 5185b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project 5195b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project/************************************************************************** 5205b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source ProjectNS8390_DISABLE - Turn off adapter 5215b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project**************************************************************************/ 5225b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Projectstatic void ns8390_disable(struct nic *nic) 5235b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project{ 5245b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project} 5255b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project 5265b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project/************************************************************************** 5275b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source ProjectETH_PROBE - Look for an adapter 5285b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project**************************************************************************/ 5295b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project#ifdef INCLUDE_NS8390 5305b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Projectstruct nic *eth_probe(struct nic *nic, unsigned short *probe_addrs, 5315b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project struct pci_device *pci) 5325b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project#else 5335b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Projectstruct nic *eth_probe(struct nic *nic, unsigned short *probe_addrs) 5345b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project#endif 5355b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project{ 5365b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project int i; 5375b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project struct wd_board *brd; 5385b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project unsigned short chksum; 5395b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project unsigned char c; 5405b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project eth_vendor = VENDOR_NONE; 5415b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project eth_drain_receiver = 0; 5425b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project 5435b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project#ifdef INCLUDE_WD 5445b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project /****************************************************************** 5455b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project Search for WD/SMC cards 5465b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project ******************************************************************/ 5475b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project for (eth_asic_base = WD_LOW_BASE; eth_asic_base <= WD_HIGH_BASE; 5485b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project eth_asic_base += 0x20) { 5495b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project chksum = 0; 5505b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project for (i=8; i<16; i++) 5515b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project chksum += inb(eth_asic_base+i); 5525b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project /* Extra checks to avoid soundcard */ 5535b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project if ((chksum & 0xFF) == 0xFF && 5545b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project inb(eth_asic_base+8) != 0xFF && 5555b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project inb(eth_asic_base+9) != 0xFF) 5565b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project break; 5575b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project } 5585b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project if (eth_asic_base > WD_HIGH_BASE) 5595b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project return (0); 5605b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project /* We've found a board */ 5615b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project eth_vendor = VENDOR_WD; 5625b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project eth_nic_base = eth_asic_base + WD_NIC_ADDR; 5635b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project c = inb(eth_asic_base+WD_BID); /* Get board id */ 5645b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project for (brd = wd_boards; brd->name; brd++) 5655b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project if (brd->id == c) break; 5665b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project if (!brd->name) { 5675b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project printf("Unknown WD/SMC NIC type %hhX\n", c); 5685b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project return (0); /* Unknown type */ 5695b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project } 5705b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project eth_flags = brd->flags; 5715b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project eth_memsize = brd->memsize; 5725b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project eth_tx_start = 0; 5735b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project eth_rx_start = D8390_TXBUF_SIZE; 5745b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project if ((c == TYPE_WD8013EP) && 5755b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project (inb(eth_asic_base + WD_ICR) & WD_ICR_16BIT)) { 5765b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project eth_flags = FLAG_16BIT; 5775b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project eth_memsize = MEM_16384; 5785b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project } 5795b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project if ((c & WD_SOFTCONFIG) && (!(eth_flags & FLAG_790))) { 5805b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project eth_bmem = (0x80000 | 5815b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project ((inb(eth_asic_base + WD_MSR) & 0x3F) << 13)); 5825b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project } else 5835b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project eth_bmem = WD_DEFAULT_MEM; 5845b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project if (brd->id == TYPE_SMC8216T || brd->id == TYPE_SMC8216C) { 5855b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project *((unsigned int *)(eth_bmem + 8192)) = (unsigned int)0; 5865b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project if (*((unsigned int *)(eth_bmem + 8192))) { 5875b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project brd += 2; 5885b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project eth_memsize = brd->memsize; 5895b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project } 5905b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project } 5915b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project outb(0x80, eth_asic_base + WD_MSR); /* Reset */ 5925b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project for (i=0; i<ETH_ALEN; i++) { 5935b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project nic->node_addr[i] = inb(i+eth_asic_base+WD_LAR); 5945b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project } 5955b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project printf("\n%s base %#hx, memory %#hx, addr %!\n", 5965b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project brd->name, eth_asic_base, eth_bmem, nic->node_addr); 5975b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project if (eth_flags & FLAG_790) { 5985b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project outb(WD_MSR_MENB, eth_asic_base+WD_MSR); 5995b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project outb((inb(eth_asic_base+0x04) | 6005b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project 0x80), eth_asic_base+0x04); 6015b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project outb((((unsigned)eth_bmem >> 13) & 0x0F) | 6025b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project (((unsigned)eth_bmem >> 11) & 0x40) | 6035b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project (inb(eth_asic_base+0x0B) & 0xB0), eth_asic_base+0x0B); 6045b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project outb((inb(eth_asic_base+0x04) & 6055b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project ~0x80), eth_asic_base+0x04); 6065b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project } else { 6075b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project outb((((unsigned)eth_bmem >> 13) & 0x3F) | 0x40, eth_asic_base+WD_MSR); 6085b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project } 6095b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project if (eth_flags & FLAG_16BIT) { 6105b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project if (eth_flags & FLAG_790) { 6115b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project eth_laar = inb(eth_asic_base + WD_LAAR); 6125b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project outb(WD_LAAR_M16EN, eth_asic_base + WD_LAAR); 6135b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project } else { 6145b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project outb((eth_laar = 6155b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project WD_LAAR_L16EN | 1), eth_asic_base + WD_LAAR); 6165b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project/* 6175b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project The previous line used to be 6185b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project WD_LAAR_M16EN | WD_LAAR_L16EN | 1)); 6195b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project jluke@deakin.edu.au reported that removing WD_LAAR_M16EN made 6205b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project it work for WD8013s. This seems to work for my 8013 boards. I 6215b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project don't know what is really happening. I wish I had data sheets 6225b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project or more time to decode the Linux driver. - Ken 6235b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project*/ 6245b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project } 6255b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project inb(0x84); 6265b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project } 6275b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project#endif 6285b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project#ifdef INCLUDE_3C503 6295b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project /****************************************************************** 6305b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project Search for 3Com 3c503 if no WD/SMC cards 6315b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project ******************************************************************/ 6325b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project if (eth_vendor == VENDOR_NONE) { 6335b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project int idx; 6345b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project int iobase_reg, membase_reg; 6355b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project static unsigned short base[] = { 6365b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project 0x300, 0x310, 0x330, 0x350, 6375b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project 0x250, 0x280, 0x2A0, 0x2E0, 0 }; 6385b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project 6395b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project /* Loop through possible addresses checking each one */ 6405b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project 6415b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project for (idx = 0; (eth_nic_base = base[idx]) != 0; ++idx) { 6425b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project 6435b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project eth_asic_base = eth_nic_base + _3COM_ASIC_OFFSET; 6445b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project/* 6455b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project * Note that we use the same settings for both 8 and 16 bit cards: 6465b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project * both have an 8K bank of memory at page 1 while only the 16 bit 6475b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project * cards have a bank at page 0. 6485b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project */ 6495b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project eth_memsize = MEM_16384; 6505b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project eth_tx_start = 32; 6515b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project eth_rx_start = 32 + D8390_TXBUF_SIZE; 6525b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project 6535b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project /* Check our base address. iobase and membase should */ 6545b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project /* both have a maximum of 1 bit set or be 0. */ 6555b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project 6565b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project iobase_reg = inb(eth_asic_base + _3COM_BCFR); 6575b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project membase_reg = inb(eth_asic_base + _3COM_PCFR); 6585b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project 6595b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project if ((iobase_reg & (iobase_reg - 1)) || 6605b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project (membase_reg & (membase_reg - 1))) 6615b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project continue; /* nope */ 6625b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project 6635b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project /* Now get the shared memory address */ 6645b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project 6655b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project eth_flags = 0; 6665b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project 6675b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project switch (membase_reg) { 6685b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project case _3COM_PCFR_DC000: 6695b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project eth_bmem = 0xdc000; 6705b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project break; 6715b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project case _3COM_PCFR_D8000: 6725b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project eth_bmem = 0xd8000; 6735b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project break; 6745b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project case _3COM_PCFR_CC000: 6755b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project eth_bmem = 0xcc000; 6765b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project break; 6775b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project case _3COM_PCFR_C8000: 6785b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project eth_bmem = 0xc8000; 6795b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project break; 6805b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project case _3COM_PCFR_PIO: 6815b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project eth_flags |= FLAG_PIO; 6825b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project eth_bmem = 0; 6835b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project break; 6845b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project default: 6855b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project continue; /* nope */ 6865b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project } 6875b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project break; 6885b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project } 6895b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project 6905b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project if (base[idx] == 0) /* not found */ 6915b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project return (0); 6925b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project#ifndef T503_SHMEM 6935b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project eth_flags |= FLAG_PIO; /* force PIO mode */ 6945b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project eth_bmem = 0; 6955b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project#endif 6965b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project eth_vendor = VENDOR_3COM; 6975b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project 6985b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project 6995b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project /* Need this to make ns8390_poll() happy. */ 7005b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project 7015b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project eth_rmem = eth_bmem - 0x2000; 7025b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project 7035b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project /* Reset NIC and ASIC */ 7045b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project 7055b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project outb(_3COM_CR_RST | _3COM_CR_XSEL, eth_asic_base + _3COM_CR ); 7065b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project outb(_3COM_CR_XSEL, eth_asic_base + _3COM_CR ); 7075b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project 7085b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project /* Get our ethernet address */ 7095b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project 7105b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project outb(_3COM_CR_EALO | _3COM_CR_XSEL, eth_asic_base + _3COM_CR); 7115b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project printf("\n3Com 3c503 base %#hx, ", eth_nic_base); 7125b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project if (eth_flags & FLAG_PIO) 7135b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project printf("PIO mode"); 7145b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project else 7155b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project printf("memory %#hx", eth_bmem); 7165b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project for (i=0; i<ETH_ALEN; i++) { 7175b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project nic->node_addr[i] = inb(eth_nic_base+i); 7185b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project } 7195b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project printf(", %s, addr %!\n", nic->flags ? "AUI" : "internal xcvr", 7205b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project nic->node_addr); 7215b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project outb(_3COM_CR_XSEL, eth_asic_base + _3COM_CR); 7225b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project /* 7235b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project * Initialize GA configuration register. Set bank and enable shared 7245b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project * mem. We always use bank 1. Disable interrupts. 7255b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project */ 7265b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project outb(_3COM_GACFR_RSEL | 7275b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project _3COM_GACFR_MBS0 | _3COM_GACFR_TCM | _3COM_GACFR_NIM, eth_asic_base + _3COM_GACFR); 7285b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project 7295b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project outb(0xff, eth_asic_base + _3COM_VPTR2); 7305b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project outb(0xff, eth_asic_base + _3COM_VPTR1); 7315b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project outb(0x00, eth_asic_base + _3COM_VPTR0); 7325b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project /* 7335b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project * Clear memory and verify that it worked (we use only 8K) 7345b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project */ 7355b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project 7365b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project if (!(eth_flags & FLAG_PIO)) { 7375b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project memset((char *)eth_bmem, 0, 0x2000); 7385b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project for(i = 0; i < 0x2000; ++i) 7395b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project if (*(((char *)eth_bmem)+i)) { 7405b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project printf ("Failed to clear 3c503 shared mem.\n"); 7415b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project return (0); 7425b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project } 7435b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project } 7445b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project /* 7455b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project * Initialize GA page/start/stop registers. 7465b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project */ 7475b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project outb(eth_tx_start, eth_asic_base + _3COM_PSTR); 7485b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project outb(eth_memsize, eth_asic_base + _3COM_PSPR); 7495b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project } 7505b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project#endif 7515b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project#if defined(INCLUDE_NE) || defined(INCLUDE_NS8390) 7525b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project /****************************************************************** 7535b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project Search for NE1000/2000 if no WD/SMC or 3com cards 7545b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project ******************************************************************/ 7555b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project if (eth_vendor == VENDOR_NONE) { 7565b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project char romdata[16], testbuf[32]; 7575b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project int idx; 7585b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project static char test[] = "NE*000 memory"; 7595b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project static unsigned short base[] = { 7605b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project#ifdef NE_SCAN 7615b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project NE_SCAN, 7625b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project#endif 7635b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project 0 }; 7645b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project /* if no addresses supplied, fall back on defaults */ 7655b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project if (probe_addrs == 0 || probe_addrs[0] == 0) 7665b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project probe_addrs = base; 7675b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project eth_bmem = 0; /* No shared memory */ 7685b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project for (idx = 0; (eth_nic_base = probe_addrs[idx]) != 0; ++idx) { 7695b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project eth_flags = FLAG_PIO; 7705b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project eth_asic_base = eth_nic_base + NE_ASIC_OFFSET; 7715b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project eth_memsize = MEM_16384; 7725b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project eth_tx_start = 32; 7735b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project eth_rx_start = 32 + D8390_TXBUF_SIZE; 7745b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project c = inb(eth_asic_base + NE_RESET); 7755b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project outb(c, eth_asic_base + NE_RESET); 7765b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project inb(0x84); 7775b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project outb(D8390_COMMAND_STP | 7785b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project D8390_COMMAND_RD2, eth_nic_base + D8390_P0_COMMAND); 7795b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project outb(D8390_RCR_MON, eth_nic_base + D8390_P0_RCR); 7805b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project outb(D8390_DCR_FT1 | D8390_DCR_LS, eth_nic_base + D8390_P0_DCR); 7815b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project outb(MEM_8192, eth_nic_base + D8390_P0_PSTART); 7825b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project outb(MEM_16384, eth_nic_base + D8390_P0_PSTOP); 7835b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project#ifdef NS8390_FORCE_16BIT 7845b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project eth_flags |= FLAG_16BIT; /* force 16-bit mode */ 7855b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project#endif 7865b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project 7875b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project eth_pio_write(test, 8192, sizeof(test)); 7885b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project eth_pio_read(8192, testbuf, sizeof(test)); 7895b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project if (!memcmp(test, testbuf, sizeof(test))) 7905b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project break; 7915b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project eth_flags |= FLAG_16BIT; 7925b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project eth_memsize = MEM_32768; 7935b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project eth_tx_start = 64; 7945b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project eth_rx_start = 64 + D8390_TXBUF_SIZE; 7955b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project outb(D8390_DCR_WTS | 7965b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project D8390_DCR_FT1 | D8390_DCR_LS, eth_nic_base + D8390_P0_DCR); 7975b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project outb(MEM_16384, eth_nic_base + D8390_P0_PSTART); 7985b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project outb(MEM_32768, eth_nic_base + D8390_P0_PSTOP); 7995b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project eth_pio_write(test, 16384, sizeof(test)); 8005b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project eth_pio_read(16384, testbuf, sizeof(test)); 8015b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project if (!memcmp(testbuf, test, sizeof(test))) 8025b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project break; 8035b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project } 8045b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project if (eth_nic_base == 0) 8055b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project return (0); 8065b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project if (eth_nic_base > ISA_MAX_ADDR) /* PCI probably */ 8075b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project eth_flags |= FLAG_16BIT; 8085b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project eth_vendor = VENDOR_NOVELL; 8095b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project eth_pio_read(0, romdata, sizeof(romdata)); 8105b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project for (i=0; i<ETH_ALEN; i++) { 8115b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project nic->node_addr[i] = romdata[i + ((eth_flags & FLAG_16BIT) ? i : 0)]; 8125b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project } 8135b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project printf("\nNE%c000 base %#hx, addr %!\n", 8145b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project (eth_flags & FLAG_16BIT) ? '2' : '1', eth_nic_base, 8155b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project nic->node_addr); 8165b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project } 8175b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project#endif 8185b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project if (eth_vendor == VENDOR_NONE) 8195b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project return(0); 8205b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project if (eth_vendor != VENDOR_3COM) 8215b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project eth_rmem = eth_bmem; 8225b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project ns8390_reset(nic); 8235b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project nic->reset = ns8390_reset; 8245b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project nic->poll = ns8390_poll; 8255b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project nic->transmit = ns8390_transmit; 8265b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project nic->disable = ns8390_disable; 8275b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project return(nic); 8285b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project} 8295b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project 8305b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project/* 8315b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project * Local variables: 8325b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project * c-basic-offset: 8 8335b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project * End: 8345b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project */ 8355b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project 836