15b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project/************************************************************************** 25b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source ProjectEtherboot - BOOTP/TFTP Bootstrap Program 35b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source ProjectLANCE NIC driver for Etherboot 45b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source ProjectLarge portions borrowed from the Linux LANCE driver by Donald Becker 55b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source ProjectKen Yap, July 1997 65b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project***************************************************************************/ 75b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project 85b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project/* 95b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project * This program is free software; you can redistribute it and/or 105b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project * modify it under the terms of the GNU General Public License as 115b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project * published by the Free Software Foundation; either version 2, or (at 125b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project * your option) any later version. 135b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project */ 145b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project 155b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project/* to get some global routines like printf */ 165b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project#include "etherboot.h" 175b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project/* to get the interface to the body of the program */ 185b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project#include "nic.h" 195b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project#ifdef INCLUDE_LANCE 205b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project#include "pci.h" 215b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project#endif 225b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project#include "cards.h" 235b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project 245b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project/* Offsets from base I/O address */ 255b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project#if defined(INCLUDE_NE2100) || defined(INCLUDE_LANCE) 265b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project#define LANCE_ETH_ADDR 0x0 275b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project#define LANCE_DATA 0x10 285b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project#define LANCE_ADDR 0x12 295b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project#define LANCE_RESET 0x14 305b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project#define LANCE_BUS_IF 0x16 315b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project#define LANCE_TOTAL_SIZE 0x18 325b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project#endif 335b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project#ifdef INCLUDE_NI6510 345b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project#define LANCE_ETH_ADDR 0x8 355b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project#define LANCE_DATA 0x0 365b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project#define LANCE_ADDR 0x2 375b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project#define LANCE_RESET 0x4 385b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project#define LANCE_BUS_IF 0x6 395b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project#define LANCE_TOTAL_SIZE 0x10 405b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project#endif 415b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project 425b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project/* lance_poll() now can use multiple Rx buffers to prevent packet loss. Set 435b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project * Set LANCE_LOG_RX_BUFFERS to 0..7 for 1, 2, 4, 8, 16, 32, 64 or 128 Rx 445b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project * buffers. Usually 4 (=16 Rx buffers) is a good value. (Andreas Neuhaus) 455b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project * Decreased to 2 (=4 Rx buffers) (Ken Yap, 20010305) */ 465b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project 475b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project#define LANCE_LOG_RX_BUFFERS 2 /* Use 2^2=4 Rx buffers */ 485b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project 495b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project#define RX_RING_SIZE (1 << (LANCE_LOG_RX_BUFFERS)) 505b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project#define RX_RING_MOD_MASK (RX_RING_SIZE - 1) 515b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project#define RX_RING_LEN_BITS ((LANCE_LOG_RX_BUFFERS) << 29) 525b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project 535b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Projectstruct lance_init_block 545b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project{ 555b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project unsigned short mode; 565b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project unsigned char phys_addr[ETH_ALEN]; 575b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project unsigned long filter[2]; 585b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project Address rx_ring; 595b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project Address tx_ring; 605b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project}; 615b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project 625b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Projectstruct lance_rx_head 635b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project{ 645b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project union { 655b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project Address base; 665b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project unsigned char addr[4]; 675b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project } u; 685b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project short buf_length; /* 2s complement */ 695b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project short msg_length; 705b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project}; 715b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project 725b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Projectstruct lance_tx_head 735b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project{ 745b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project union { 755b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project Address base; 765b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project unsigned char addr[4]; 775b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project } u; 785b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project short buf_length; /* 2s complement */ 795b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project short misc; 805b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project}; 815b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project 825b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Projectstruct lance_interface 835b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project{ 845b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project struct lance_init_block init_block; 855b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project struct lance_rx_head rx_ring[RX_RING_SIZE]; 865b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project struct lance_tx_head tx_ring; 875b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project unsigned char rbuf[RX_RING_SIZE][ETH_FRAME_LEN+4]; 885b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project unsigned char tbuf[ETH_FRAME_LEN]; 895b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project /* 905b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project * Do not alter the order of the struct members above; 915b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project * the hardware depends on the correct alignment. 925b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project */ 935b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project int rx_idx; 945b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project}; 955b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project 965b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project#define LANCE_MUST_PAD 0x00000001 975b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project#define LANCE_ENABLE_AUTOSELECT 0x00000002 985b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project#define LANCE_SELECT_PHONELINE 0x00000004 995b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project#define LANCE_MUST_UNRESET 0x00000008 1005b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project 1015b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project/* A mapping from the chip ID number to the part number and features. 1025b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project These are from the datasheets -- in real life the '970 version 1035b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project reportedly has the same ID as the '965. */ 1045b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Projectstatic const struct lance_chip_type 1055b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project{ 1065b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project int id_number; 1075b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project const char *name; 1085b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project int flags; 1095b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project} chip_table[] = { 1105b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project {0x0000, "LANCE 7990", /* Ancient lance chip. */ 1115b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project LANCE_MUST_PAD + LANCE_MUST_UNRESET}, 1125b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project {0x0003, "PCnet/ISA 79C960", /* 79C960 PCnet/ISA. */ 1135b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project LANCE_ENABLE_AUTOSELECT}, 1145b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project {0x2260, "PCnet/ISA+ 79C961", /* 79C961 PCnet/ISA+, Plug-n-Play. */ 1155b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project LANCE_ENABLE_AUTOSELECT}, 1165b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project {0x2420, "PCnet/PCI 79C970", /* 79C970 or 79C974 PCnet-SCSI, PCI. */ 1175b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project LANCE_ENABLE_AUTOSELECT}, 1185b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project /* Bug: the PCnet/PCI actually uses the PCnet/VLB ID number, so just call 1195b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project it the PCnet32. */ 1205b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project {0x2430, "PCnet32", /* 79C965 PCnet for VL bus. */ 1215b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project LANCE_ENABLE_AUTOSELECT}, 1225b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project {0x2621, "PCnet/PCI-II 79C970A", /* 79C970A PCInetPCI II. */ 1235b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project LANCE_ENABLE_AUTOSELECT}, 1245b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project {0x2625, "PCnet-FAST III 79C973", /* 79C973 PCInet-FAST III. */ 1255b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project LANCE_ENABLE_AUTOSELECT}, 1265b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project {0x2626, "PCnet/HomePNA 79C978", 1275b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project LANCE_ENABLE_AUTOSELECT|LANCE_SELECT_PHONELINE}, 1285b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project {0x0, "PCnet (unknown)", 1295b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project LANCE_ENABLE_AUTOSELECT}, 1305b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project}; 1315b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project 1325b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project/* Define a macro for converting program addresses to real addresses */ 1335b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project#undef virt_to_bus 1345b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project#define virt_to_bus(x) ((unsigned long)x) 1355b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project 1365b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Projectstatic int chip_version; 1375b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Projectstatic int lance_version; 1385b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Projectstatic unsigned short ioaddr; 1395b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project#ifndef INCLUDE_LANCE 1405b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Projectstatic int dma; 1415b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project#endif 1425b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Projectstatic struct lance_interface *lp; 1435b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project 1445b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project/* additional 8 bytes for 8-byte alignment space */ 1455b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project#ifdef USE_LOWMEM_BUFFER 1465b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project#define lance ((char *)0x10000 - (sizeof(struct lance_interface)+8)) 1475b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project#else 1485b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Projectstatic char lance[sizeof(struct lance_interface)+8]; 1495b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project#endif 1505b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project 1515b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project#ifndef INCLUDE_LANCE 1525b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project/* DMA defines and helper routines */ 1535b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project 1545b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project/* DMA controller registers */ 1555b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project#define DMA1_CMD_REG 0x08 /* command register (w) */ 1565b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project#define DMA1_STAT_REG 0x08 /* status register (r) */ 1575b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project#define DMA1_REQ_REG 0x09 /* request register (w) */ 1585b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project#define DMA1_MASK_REG 0x0A /* single-channel mask (w) */ 1595b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project#define DMA1_MODE_REG 0x0B /* mode register (w) */ 1605b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project#define DMA1_CLEAR_FF_REG 0x0C /* clear pointer flip-flop (w) */ 1615b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project#define DMA1_TEMP_REG 0x0D /* Temporary Register (r) */ 1625b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project#define DMA1_RESET_REG 0x0D /* Master Clear (w) */ 1635b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project#define DMA1_CLR_MASK_REG 0x0E /* Clear Mask */ 1645b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project#define DMA1_MASK_ALL_REG 0x0F /* all-channels mask (w) */ 1655b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project 1665b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project#define DMA2_CMD_REG 0xD0 /* command register (w) */ 1675b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project#define DMA2_STAT_REG 0xD0 /* status register (r) */ 1685b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project#define DMA2_REQ_REG 0xD2 /* request register (w) */ 1695b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project#define DMA2_MASK_REG 0xD4 /* single-channel mask (w) */ 1705b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project#define DMA2_MODE_REG 0xD6 /* mode register (w) */ 1715b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project#define DMA2_CLEAR_FF_REG 0xD8 /* clear pointer flip-flop (w) */ 1725b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project#define DMA2_TEMP_REG 0xDA /* Temporary Register (r) */ 1735b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project#define DMA2_RESET_REG 0xDA /* Master Clear (w) */ 1745b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project#define DMA2_CLR_MASK_REG 0xDC /* Clear Mask */ 1755b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project#define DMA2_MASK_ALL_REG 0xDE /* all-channels mask (w) */ 1765b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project 1775b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project 1785b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project#define DMA_MODE_READ 0x44 /* I/O to memory, no autoinit, increment, single mode */ 1795b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project#define DMA_MODE_WRITE 0x48 /* memory to I/O, no autoinit, increment, single mode */ 1805b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project#define DMA_MODE_CASCADE 0xC0 /* pass thru DREQ->HRQ, DACK<-HLDA only */ 1815b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project 1825b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project/* enable/disable a specific DMA channel */ 1835b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Projectstatic void enable_dma(unsigned int dmanr) 1845b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project{ 1855b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project if (dmanr <= 3) 1865b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project outb_p(dmanr, DMA1_MASK_REG); 1875b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project else 1885b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project outb_p(dmanr & 3, DMA2_MASK_REG); 1895b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project} 1905b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project 1915b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Projectstatic void disable_dma(unsigned int dmanr) 1925b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project{ 1935b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project if (dmanr <= 3) 1945b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project outb_p(dmanr | 4, DMA1_MASK_REG); 1955b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project else 1965b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project outb_p((dmanr & 3) | 4, DMA2_MASK_REG); 1975b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project} 1985b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project 1995b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project/* set mode (above) for a specific DMA channel */ 2005b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Projectstatic void set_dma_mode(unsigned int dmanr, char mode) 2015b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project{ 2025b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project if (dmanr <= 3) 2035b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project outb_p(mode | dmanr, DMA1_MODE_REG); 2045b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project else 2055b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project outb_p(mode | (dmanr&3), DMA2_MODE_REG); 2065b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project} 2075b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project#endif /* !INCLUDE_LANCE */ 2085b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project 2095b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project/************************************************************************** 2105b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source ProjectRESET - Reset adapter 2115b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project***************************************************************************/ 2125b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Projectstatic void lance_reset(struct nic *nic) 2135b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project{ 2145b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project int i; 2155b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project Address l; 2165b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project 2175b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project /* Reset the LANCE */ 2185b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project (void)inw(ioaddr+LANCE_RESET); 2195b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project /* Un-Reset the LANCE, needed only for the NE2100 */ 2205b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project if (chip_table[lance_version].flags & LANCE_MUST_UNRESET) 2215b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project outw(0, ioaddr+LANCE_RESET); 2225b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project if (chip_table[lance_version].flags & LANCE_ENABLE_AUTOSELECT) 2235b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project { 2245b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project /* This is 79C960 specific; Turn on auto-select of media 2255b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project (AUI, BNC). */ 2265b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project outw(0x2, ioaddr+LANCE_ADDR); 2275b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project /* Don't touch 10base2 power bit. */ 2285b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project outw(inw(ioaddr+LANCE_BUS_IF) | 0x2, ioaddr+LANCE_BUS_IF); 2295b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project } 2305b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project /* HomePNA cards need to explicitly pick the phoneline interface. 2315b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project * Some of these cards have ethernet interfaces as well, this 2325b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project * code might require some modification for those. 2335b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project */ 2345b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project if (chip_table[lance_version].flags & LANCE_SELECT_PHONELINE) { 2355b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project short media, check ; 2365b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project /* this is specific to HomePNA cards... */ 2375b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project outw(49, ioaddr+0x12) ; 2385b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project media = inw(ioaddr+0x16) ; 2395b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project#ifdef DEBUG 2405b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project printf("media was %d\n", media) ; 2415b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project#endif 2425b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project media &= ~3 ; 2435b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project media |= 1 ; 2445b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project#ifdef DEBUG 2455b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project printf("media changed to %d\n", media) ; 2465b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project#endif 2475b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project media &= ~3 ; 2485b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project media |= 1 ; 2495b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project outw(49, ioaddr+0x12) ; 2505b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project outw(media, ioaddr+0x16) ; 2515b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project outw(49, ioaddr+0x12) ; 2525b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project check = inw(ioaddr+0x16) ; 2535b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project#ifdef DEBUG 2545b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project printf("check %s, media was set properly\n", 2555b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project check == media ? "passed" : "FAILED" ) ; 2565b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project#endif 2575b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project } 2585b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project 2595b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project /* Re-initialise the LANCE, and start it when done. */ 2605b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project /* Set station address */ 2615b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project for (i = 0; i < ETH_ALEN; ++i) 2625b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project lp->init_block.phys_addr[i] = nic->node_addr[i]; 2635b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project /* Preset the receive ring headers */ 2645b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project for (i=0; i<RX_RING_SIZE; i++) { 2655b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project lp->rx_ring[i].buf_length = -ETH_FRAME_LEN-4; 2665b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project /* OWN */ 2675b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project lp->rx_ring[i].u.base = virt_to_bus(lp->rbuf[i]) & 0xffffff; 2685b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project /* we set the top byte as the very last thing */ 2695b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project lp->rx_ring[i].u.addr[3] = 0x80; 2705b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project } 2715b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project lp->rx_idx = 0; 2725b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project lp->init_block.mode = 0x0; /* enable Rx and Tx */ 2735b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project l = (Address)virt_to_bus(&lp->init_block); 2745b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project outw(0x1, ioaddr+LANCE_ADDR); 2755b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project (void)inw(ioaddr+LANCE_ADDR); 2765b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project outw((short)l, ioaddr+LANCE_DATA); 2775b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project outw(0x2, ioaddr+LANCE_ADDR); 2785b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project (void)inw(ioaddr+LANCE_ADDR); 2795b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project outw((short)(l >> 16), ioaddr+LANCE_DATA); 2805b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project outw(0x4, ioaddr+LANCE_ADDR); 2815b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project (void)inw(ioaddr+LANCE_ADDR); 2825b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project outw(0x915, ioaddr+LANCE_DATA); 2835b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project outw(0x0, ioaddr+LANCE_ADDR); 2845b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project (void)inw(ioaddr+LANCE_ADDR); 2855b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project outw(0x4, ioaddr+LANCE_DATA); /* stop */ 2865b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project outw(0x1, ioaddr+LANCE_DATA); /* init */ 2875b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project for (i = 10000; i > 0; --i) 2885b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project if (inw(ioaddr+LANCE_DATA) & 0x100) 2895b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project break; 2905b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project#ifdef DEBUG 2915b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project if (i <= 0) 2925b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project printf("Init timed out\n"); 2935b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project#endif 2945b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project /* Apparently clearing the InitDone bit here triggers a bug 2955b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project in the '974. (Mark Stockton) */ 2965b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project outw(0x2, ioaddr+LANCE_DATA); /* start */ 2975b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project} 2985b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project 2995b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project/************************************************************************** 3005b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source ProjectPOLL - Wait for a frame 3015b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project***************************************************************************/ 3025b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Projectstatic int lance_poll(struct nic *nic) 3035b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project{ 3045b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project int status; 3055b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project 3065b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project status = lp->rx_ring[lp->rx_idx].u.base >> 24; 3075b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project if (status & 0x80) 3085b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project return (0); 3095b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project#ifdef DEBUG 3105b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project printf("LANCE packet received rx_ring.u.base %X mcnt %hX csr0 %hX\n", 3115b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project lp->rx_ring[lp->rx_idx].u.base, lp->rx_ring[lp->rx_idx].msg_length, 3125b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project inw(ioaddr+LANCE_DATA)); 3135b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project#endif 3145b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project if (status == 0x3) 3155b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project memcpy(nic->packet, lp->rbuf[lp->rx_idx], nic->packetlen = lp->rx_ring[lp->rx_idx].msg_length); 3165b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project /* Andrew Boyd of QNX reports that some revs of the 79C765 3175b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project clear the buffer length */ 3185b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project lp->rx_ring[lp->rx_idx].buf_length = -ETH_FRAME_LEN-4; 3195b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project lp->rx_ring[lp->rx_idx].u.addr[3] |= 0x80; /* prime for next receive */ 3205b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project 3215b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project /* I'm not sure if the following is still ok with multiple Rx buffers, but it works */ 3225b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project outw(0x0, ioaddr+LANCE_ADDR); 3235b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project (void)inw(ioaddr+LANCE_ADDR); 3245b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project outw(0x500, ioaddr+LANCE_DATA); /* clear receive + InitDone */ 3255b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project 3265b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project /* Switch to the next Rx ring buffer */ 3275b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project lp->rx_idx = (lp->rx_idx + 1) & RX_RING_MOD_MASK; 3285b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project 3295b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project return (status == 0x3); 3305b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project} 3315b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project 3325b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project/************************************************************************** 3335b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source ProjectTRANSMIT - Transmit a frame 3345b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project***************************************************************************/ 3355b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Projectstatic void lance_transmit( 3365b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project struct nic *nic, 3375b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project const char *d, /* Destination */ 3385b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project unsigned int t, /* Type */ 3395b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project unsigned int s, /* size */ 3405b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project const char *p) /* Packet */ 3415b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project{ 3425b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project unsigned long time; 3435b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project 3445b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project /* copy the packet to ring buffer */ 3455b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project memcpy(lp->tbuf, d, ETH_ALEN); /* dst */ 3465b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project memcpy(&lp->tbuf[ETH_ALEN], nic->node_addr, ETH_ALEN); /* src */ 3475b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project lp->tbuf[ETH_ALEN+ETH_ALEN] = t >> 8; /* type */ 3485b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project lp->tbuf[ETH_ALEN+ETH_ALEN+1] = t; /* type */ 3495b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project memcpy(&lp->tbuf[ETH_HLEN], p, s); 3505b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project s += ETH_HLEN; 3515b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project if (chip_table[chip_version].flags & LANCE_MUST_PAD) 3525b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project while (s < ETH_ZLEN) /* pad to min length */ 3535b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project lp->tbuf[s++] = 0; 3545b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project lp->tx_ring.buf_length = -s; 3555b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project lp->tx_ring.misc = 0x0; 3565b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project /* OWN, STP, ENP */ 3575b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project lp->tx_ring.u.base = virt_to_bus(lp->tbuf) & 0xffffff; 3585b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project /* we set the top byte as the very last thing */ 3595b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project lp->tx_ring.u.addr[3] = 0x83; 3605b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project /* Trigger an immediate send poll */ 3615b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project outw(0x0, ioaddr+LANCE_ADDR); 3625b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project (void)inw(ioaddr+LANCE_ADDR); /* as in the datasheets... */ 3635b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project /* Klaus Espenlaub: the value below was 0x48, but that enabled the 3645b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project * interrupt line, causing a hang if for some reasone the interrupt 3655b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project * controller had the LANCE interrupt enabled. I have no idea why 3665b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project * nobody ran into this before... */ 3675b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project outw(0x08, ioaddr+LANCE_DATA); 3685b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project /* wait for transmit complete */ 3695b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project time = currticks() + TICKS_PER_SEC; /* wait one second */ 3705b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project while (currticks() < time && (lp->tx_ring.u.base & 0x80000000) != 0) 3715b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project ; 3725b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project if ((lp->tx_ring.u.base & 0x80000000) != 0) 3735b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project printf("LANCE timed out on transmit\n"); 3745b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project (void)inw(ioaddr+LANCE_ADDR); 3755b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project outw(0x200, ioaddr+LANCE_DATA); /* clear transmit + InitDone */ 3765b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project#ifdef DEBUG 3775b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project printf("tx_ring.u.base %X tx_ring.buf_length %hX tx_ring.misc %hX csr0 %hX\n", 3785b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project lp->tx_ring.u.base, lp->tx_ring.buf_length, lp->tx_ring.misc, 3795b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project inw(ioaddr+LANCE_DATA)); 3805b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project#endif 3815b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project} 3825b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project 3835b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Projectstatic void lance_disable(struct nic *nic) 3845b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project{ 3855b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project (void)inw(ioaddr+LANCE_RESET); 3865b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project if (chip_table[lance_version].flags & LANCE_MUST_UNRESET) 3875b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project outw(0, ioaddr+LANCE_RESET); 3885b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project 3895b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project outw(0, ioaddr+LANCE_ADDR); 3905b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project outw(0x0004, ioaddr+LANCE_DATA); /* stop the LANCE */ 3915b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project 3925b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project#ifndef INCLUDE_LANCE 3935b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project disable_dma(dma); 3945b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project#endif 3955b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project} 3965b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project 3975b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project#ifdef INCLUDE_LANCE 3985b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Projectstatic int lance_probe1(struct nic *nic, struct pci_device *pci) 3995b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project#else 4005b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Projectstatic int lance_probe1(struct nic *nic) 4015b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project#endif 4025b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project{ 4035b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project int reset_val ; 4045b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project unsigned int i; 4055b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project Address l; 4065b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project short dma_channels; 4075b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project#ifndef INCLUDE_LANCE 4085b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project static const char dmas[] = { 5, 6, 7, 3 }; 4095b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project#endif 4105b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project 4115b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project reset_val = inw(ioaddr+LANCE_RESET); 4125b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project outw(reset_val, ioaddr+LANCE_RESET); 4135b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project#if 1 /* Klaus Espenlaub -- was #ifdef INCLUDE_NE2100*/ 4145b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project outw(0x0, ioaddr+LANCE_ADDR); /* Switch to window 0 */ 4155b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project if (inw(ioaddr+LANCE_DATA) != 0x4) 4165b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project return (-1); 4175b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project#endif 4185b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project outw(88, ioaddr+LANCE_ADDR); /* Get the version of the chip */ 4195b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project if (inw(ioaddr+LANCE_ADDR) != 88) 4205b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project lance_version = 0; 4215b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project else 4225b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project { 4235b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project chip_version = inw(ioaddr+LANCE_DATA); 4245b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project outw(89, ioaddr+LANCE_ADDR); 4255b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project chip_version |= inw(ioaddr+LANCE_DATA) << 16; 4265b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project if ((chip_version & 0xfff) != 0x3) 4275b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project return (-1); 4285b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project chip_version = (chip_version >> 12) & 0xffff; 4295b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project for (lance_version = 1; chip_table[lance_version].id_number != 0; ++lance_version) 4305b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project if (chip_table[lance_version].id_number == chip_version) 4315b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project break; 4325b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project } 4335b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project /* make sure data structure is 8-byte aligned */ 4345b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project l = ((Address)lance + 7) & ~7; 4355b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project lp = (struct lance_interface *)l; 4365b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project lp->init_block.mode = 0x3; /* disable Rx and Tx */ 4375b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project lp->init_block.filter[0] = lp->init_block.filter[1] = 0x0; 4385b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project /* using multiple Rx buffer and a single Tx buffer */ 4395b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project lp->init_block.rx_ring = (virt_to_bus(&lp->rx_ring) & 0xffffff) | RX_RING_LEN_BITS; 4405b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project lp->init_block.tx_ring = virt_to_bus(&lp->tx_ring) & 0xffffff; 4415b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project l = virt_to_bus(&lp->init_block); 4425b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project outw(0x1, ioaddr+LANCE_ADDR); 4435b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project (void)inw(ioaddr+LANCE_ADDR); 4445b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project outw((unsigned short)l, ioaddr+LANCE_DATA); 4455b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project outw(0x2, ioaddr+LANCE_ADDR); 4465b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project (void)inw(ioaddr+LANCE_ADDR); 4475b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project outw((unsigned short)(l >> 16), ioaddr+LANCE_DATA); 4485b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project outw(0x4, ioaddr+LANCE_ADDR); 4495b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project (void)inw(ioaddr+LANCE_ADDR); 4505b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project outw(0x915, ioaddr+LANCE_DATA); 4515b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project outw(0x0, ioaddr+LANCE_ADDR); 4525b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project (void)inw(ioaddr+LANCE_ADDR); 4535b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project /* Get station address */ 4545b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project for (i = 0; i < ETH_ALEN; ++i) { 4555b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project nic->node_addr[i] = inb(ioaddr+LANCE_ETH_ADDR+i); 4565b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project } 4575b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project#ifndef INCLUDE_LANCE 4585b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project /* now probe for DMA channel */ 4595b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project dma_channels = ((inb(DMA1_STAT_REG) >> 4) & 0xf) | 4605b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project (inb(DMA2_STAT_REG) & 0xf0); 4615b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project /* need to fix when PCI provides DMA info */ 4625b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project for (i = 0; i < (sizeof(dmas)/sizeof(dmas[0])); ++i) 4635b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project { 4645b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project int j; 4655b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project 4665b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project dma = dmas[i]; 4675b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project /* Don't enable a permanently busy DMA channel, 4685b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project or the machine will hang */ 4695b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project if (dma_channels & (1 << dma)) 4705b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project continue; 4715b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project outw(0x7f04, ioaddr+LANCE_DATA); /* clear memory error bits */ 4725b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project set_dma_mode(dma, DMA_MODE_CASCADE); 4735b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project enable_dma(dma); 4745b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project outw(0x1, ioaddr+LANCE_DATA); /* init */ 4755b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project for (j = 100; j > 0; --j) 4765b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project if (inw(ioaddr+LANCE_DATA) & 0x900) 4775b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project break; 4785b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project if (inw(ioaddr+LANCE_DATA) & 0x100) 4795b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project break; 4805b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project else 4815b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project disable_dma(dma); 4825b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project } 4835b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project if (i >= (sizeof(dmas)/sizeof(dmas[0]))) 4845b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project dma = 0; 4855b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project printf("\n%s base %#X, DMA %d, addr %!\n", 4865b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project chip_table[lance_version].name, ioaddr, dma, nic->node_addr); 4875b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project#else 4885b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project printf(" %s base %#hX, addr %!\n", chip_table[lance_version].name, ioaddr, nic->node_addr); 4895b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project#endif 4905b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project if (chip_table[chip_version].flags & LANCE_ENABLE_AUTOSELECT) { 4915b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project /* Turn on auto-select of media (10baseT or BNC) so that the 4925b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project * user watch the LEDs. */ 4935b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project outw(0x0002, ioaddr+LANCE_ADDR); 4945b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project /* Don't touch 10base2 power bit. */ 4955b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project outw(inw(ioaddr+LANCE_BUS_IF) | 0x0002, ioaddr+LANCE_BUS_IF); 4965b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project } 4975b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project return (lance_version); 4985b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project} 4995b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project 5005b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project/************************************************************************** 5015b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source ProjectPROBE - Look for an adapter, this routine's visible to the outside 5025b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project***************************************************************************/ 5035b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project 5045b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project#ifdef INCLUDE_LANCE 5055b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Projectstruct nic *lancepci_probe(struct nic *nic, unsigned short *probe_addrs, struct pci_device *pci) 5065b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project#endif 5075b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project#ifdef INCLUDE_NE2100 5085b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Projectstruct nic *ne2100_probe(struct nic *nic, unsigned short *probe_addrs) 5095b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project#endif 5105b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project#ifdef INCLUDE_NI6510 5115b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Projectstruct nic *ni6510_probe(struct nic *nic, unsigned short *probe_addrs) 5125b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project#endif 5135b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project{ 5145b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project unsigned short *p; 5155b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project#ifndef INCLUDE_LANCE 5165b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project static unsigned short io_addrs[] = { 0x300, 0x320, 0x340, 0x360, 0 }; 5175b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project#endif 5185b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project 5195b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project /* if probe_addrs is 0, then routine can use a hardwired default */ 5205b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project if (probe_addrs == 0) { 5215b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project#ifdef INCLUDE_LANCE 5225b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project return 0; 5235b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project#else 5245b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project probe_addrs = io_addrs; 5255b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project#endif 5265b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project } 5275b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project for (p = probe_addrs; (ioaddr = *p) != 0; ++p) 5285b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project { 5295b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project char offset15, offset14 = inb(ioaddr + 14); 5305b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project unsigned short pci_cmd; 5315b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project 5325b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project#ifdef INCLUDE_NE2100 5335b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project if ((offset14 == 0x52 || offset14 == 0x57) && 5345b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project ((offset15 = inb(ioaddr + 15)) == 0x57 || offset15 == 0x44)) 5355b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project if (lance_probe1(nic) >= 0) 5365b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project break; 5375b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project#endif 5385b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project#ifdef INCLUDE_NI6510 5395b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project if ((offset14 == 0x00 || offset14 == 0x52) && 5405b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project ((offset15 = inb(ioaddr + 15)) == 0x55 || offset15 == 0x44)) 5415b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project if (lance_probe1(nic) >= 0) 5425b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project break; 5435b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project#endif 5445b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project#ifdef INCLUDE_LANCE 5455b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project adjust_pci_device(pci); 5465b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project if (lance_probe1(nic, pci) >= 0) 5475b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project break; 5485b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project#endif 5495b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project } 5505b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project /* if board found */ 5515b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project if (ioaddr != 0) 5525b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project { 5535b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project /* point to NIC specific routines */ 5545b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project lance_reset(nic); 5555b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project nic->reset = lance_reset; 5565b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project nic->poll = lance_poll; 5575b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project nic->transmit = lance_transmit; 5585b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project nic->disable = lance_disable; 5595b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project return nic; 5605b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project } 5615b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project 5625b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project /* no board found */ 5635b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project return 0; 5645b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4The Android Open Source Project} 565