1 /* $NetBSD: 3c590.c,v 1.11 1999/11/05 22:57:39 drochner Exp $ */ 2 3 /* stripped down from freebsd:sys/i386/netboot/3c509.c */ 4 5 6 /************************************************************************** 7 NETBOOT - BOOTP/TFTP Bootstrap Program 8 9 Author: Martin Renters. 10 Date: Mar 22 1995 11 12 This code is based heavily on David Greenman's if_ed.c driver and 13 Andres Vega Garcia's if_ep.c driver. 14 15 Copyright (C) 1993-1994, David Greenman, Martin Renters. 16 Copyright (C) 1993-1995, Andres Vega Garcia. 17 Copyright (C) 1995, Serge Babkin. 18 This software may be used, modified, copied, distributed, and sold, in 19 both source and binary form provided that the above copyright and these 20 terms are retained. Under no circumstances are the authors responsible for 21 the proper functioning of this software, nor do the authors assume any 22 responsibility for damages incurred with its use. 23 24 3c509 support added by Serge Babkin (babkin@hq.icb.chel.su) 25 26 3c509.c,v 1.2 1995/05/30 07:58:52 rgrimes Exp 27 28 ***************************************************************************/ 29 30 #include <sys/types.h> 31 #include <machine/pio.h> 32 33 #include <lib/libsa/stand.h> 34 35 #include <libi386.h> 36 #include <pcivar.h> 37 38 #if defined(_STANDALONE) && !defined(SUPPORT_NO_NETBSD) 39 #include <lib/libkern/libkern.h> 40 #include <bootinfo.h> 41 #endif 42 43 #include "etherdrv.h" 44 #include "3c509.h" 45 46 #define EP_W3_INTERNAL_CONFIG 0x00 /* 32 bits */ 47 #define EP_W3_RESET_OPTIONS 0x08 /* 16 bits */ 48 49 int ether_medium; 50 unsigned short eth_base; 51 52 extern void epreset __P((void)); 53 extern int ep_get_e __P((int)); 54 55 u_char eth_myaddr[6]; 56 57 static struct mtabentry { 58 int address_cfg; /* configured connector */ 59 int config_bit; /* connector present */ 60 char *name; 61 } mediatab[] = { /* indexed by media type - etherdrv.h */ 62 {3, 0x10, "BNC"}, 63 {0, 0x08, "UTP"}, 64 {1, 0x20, "AUI"}, 65 {6, 0x40, "MII"}, 66 }; 67 68 #if defined(_STANDALONE) && !defined(SUPPORT_NO_NETBSD) 69 static struct btinfo_netif bi_netif; 70 #endif 71 72 /************************************************************************** 73 ETH_PROBE - Look for an adapter 74 ***************************************************************************/ 75 int EtherInit(myadr) 76 unsigned char *myadr; 77 { 78 /* common variables */ 79 int i, j; 80 /* variables for 3C509 */ 81 short *p; 82 struct mtabentry *m; 83 84 /********************************************************* 85 Search for 3Com 590 card 86 ***********************************************************/ 87 88 pcihdl_t hdl; 89 int iobase; 90 91 if(pcicheck() == -1) { 92 printf("cannot access PCI\n"); 93 return(0); 94 } 95 96 if (pcifinddev(0x10b7, 0x5900, &hdl) && 97 pcifinddev(0x10b7, 0x5950, &hdl) && 98 pcifinddev(0x10b7, 0x9000, &hdl) && 99 pcifinddev(0x10b7, 0x9001, &hdl) && 100 pcifinddev(0x10b7, 0x9050, &hdl)) { 101 printf("cannot find 3c59x / 3c90x\n"); 102 return(0); 103 } 104 105 if(pcicfgread(&hdl, 0x10, &iobase) || !(iobase & 1)) { 106 printf("cannot map IO space\n"); 107 return(0); 108 } 109 eth_base = iobase & 0xfffffffc; 110 111 /* test for presence of connectors */ 112 GO_WINDOW(3); 113 i = inb(IS_BASE + EP_W3_RESET_OPTIONS); 114 j = (inw(IS_BASE + EP_W3_INTERNAL_CONFIG + 2) >> 4) & 7; 115 116 GO_WINDOW(0); 117 118 for(ether_medium = 0, m = mediatab; 119 ether_medium < sizeof(mediatab) / sizeof(mediatab[0]); 120 ether_medium++, m++) { 121 if(j == m->address_cfg) { 122 if(!(i & m->config_bit)) { 123 printf("%s not present\n", m->name); 124 return(0); 125 } 126 printf("using %s\n", m->name); 127 goto ok; 128 } 129 } 130 printf("unknown connector\n"); 131 return(0); 132 133 ok: 134 /* 135 * Read the station address from the eeprom 136 */ 137 p = (u_short *) eth_myaddr; 138 for (i = 0; i < 3; i++) { 139 u_short help; 140 GO_WINDOW(0); 141 help = ep_get_e(i); 142 p[i] = ((help & 0xff) << 8) | ((help & 0xff00) >> 8); 143 GO_WINDOW(2); 144 outw(BASE + EP_W2_ADDR_0 + (i * 2), help); 145 } 146 for(i = 0; i < 6; i++) 147 myadr[i] = eth_myaddr[i]; 148 149 epreset(); 150 151 152 #if defined(_STANDALONE) && !defined(SUPPORT_NO_NETBSD) 153 strncpy(bi_netif.ifname, "ep", sizeof(bi_netif.ifname)); 154 bi_netif.bus = BI_BUS_PCI; 155 bi_netif.addr.tag = hdl; 156 157 BI_ADD(&bi_netif, BTINFO_NETIF, sizeof(bi_netif)); 158 #endif 159 160 return(1); 161 } 162