1 /* $NetBSD: i82557.c,v 1.7 2002/01/24 02:52:15 gson Exp $ */ 2 3 /* 4 * Copyright (c) 1998, 1999 5 * Matthias Drochner. All rights reserved. 6 * Copyright (c) 1995, David Greenman 7 * All rights reserved. 8 * 9 * Redistribution and use in source and binary forms, with or without 10 * modification, are permitted provided that the following conditions 11 * are met: 12 * 1. Redistributions of source code must retain the above copyright 13 * notice unmodified, this list of conditions, and the following 14 * disclaimer. 15 * 2. Redistributions in binary form must reproduce the above copyright 16 * notice, this list of conditions and the following disclaimer in the 17 * documentation and/or other materials provided with the distribution. 18 * 19 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 20 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 21 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 22 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 23 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 24 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 25 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 26 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 27 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 28 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 29 * SUCH DAMAGE. 30 */ 31 32 #include <sys/types.h> 33 #include <machine/pio.h> 34 35 #include <dev/ic/i82557reg.h> 36 37 #include <lib/libsa/stand.h> 38 39 #include <libi386.h> 40 #include <pcivar.h> 41 42 #if defined(_STANDALONE) && !defined(SUPPORT_NO_NETBSD) 43 #include <lib/libkern/libkern.h> 44 #include <bootinfo.h> 45 #endif 46 47 #include "etherdrv.h" 48 49 #define RECVBUF_SIZE 1600 /* struct fxp_rfa + packet */ 50 51 #ifdef _STANDALONE 52 static pcihdl_t mytag; 53 static char recvbuf[RECVBUF_SIZE]; 54 #define RECVBUF_PHYS vtophys(recvbuf) 55 #define RECVBUF_VIRT ((void *)recvbuf) 56 static union _sndbuf { 57 struct fxp_cb_config cbp; 58 struct fxp_cb_ias cb_ias; 59 struct fxp_cb_tx txp; 60 } sndbuf; 61 #define SNDBUF_PHYS vtophys(&sndbuf) 62 #define SNDBUF_VIRT ((void *)&sndbuf) 63 #else /* !standalone, userspace testing environment */ 64 #define PCI_MODE1_ENABLE 0x80000000UL 65 static pcihdl_t mytag = PCI_MODE1_ENABLE | (PCIDEVNO << 11); 66 67 extern caddr_t mapmem __P((int, int)); 68 void *dmamem; /* virtual */ 69 #define RECVBUF_PHYS DMABASE 70 #define RECVBUF_VIRT dmamem 71 #define SNDBUF_PHYS (DMABASE + RECVBUF_SIZE) 72 #define SNDBUF_VIRT ((void *)(((char *)dmamem) + RECVBUF_SIZE)) 73 #endif /* _STANDALONE */ 74 75 static void fxp_read_eeprom __P((u_int16_t *, int, int)); 76 static inline void fxp_scb_wait __P((void)); 77 #ifdef DEBUG 78 static void fxp_checkintr __P((char *)); 79 #else 80 #define fxp_checkintr(x) 81 #endif 82 static void fxp_startreceiver __P((void)); 83 84 /* 85 * Template for default configuration parameters. 86 * See struct fxp_cb_config for the bit definitions. 87 */ 88 static u_int8_t fxp_cb_config_template[] = { 89 0x0, 0x0, /* cb_status */ 90 0x80, 0x2, /* cb_command */ 91 0xff, 0xff, 0xff, 0xff, /* link_addr */ 92 0x16, /* 0 */ 93 0x8, /* 1 */ 94 0x0, /* 2 */ 95 0x0, /* 3 */ 96 0x0, /* 4 */ 97 0x80, /* 5 */ 98 0xb2, /* 6 */ 99 0x3, /* 7 */ 100 0x1, /* 8 */ 101 0x0, /* 9 */ 102 0x26, /* 10 */ 103 0x0, /* 11 */ 104 0x60, /* 12 */ 105 0x0, /* 13 */ 106 0xf2, /* 14 */ 107 0x48, /* 15 */ 108 0x0, /* 16 */ 109 0x40, /* 17 */ 110 0xf3, /* 18 */ 111 0x0, /* 19 */ 112 0x3f, /* 20 */ 113 0x5 /* 21 */ 114 }; 115 116 static int tx_threshold = 64; /* x8, max 192 */ 117 118 #define CSR_READ_1(reg) inb(iobase + (reg)) 119 #define CSR_READ_2(reg) inw(iobase + (reg)) 120 #define CSR_WRITE_1(reg, val) outb(iobase + (reg), val) 121 #define CSR_WRITE_2(reg, val) outw(iobase + (reg), val) 122 #define CSR_WRITE_4(reg, val) outl(iobase + (reg), val) 123 #define DELAY(n) delay(n) 124 125 static int iobase; 126 127 #if defined(_STANDALONE) && !defined(SUPPORT_NO_NETBSD) 128 static struct btinfo_netif bi_netif; 129 #endif 130 131 /* 132 * Wait for the previous command to be accepted (but not necessarily 133 * completed). 134 */ 135 static inline void 136 fxp_scb_wait() 137 { 138 int i = 10000; 139 140 while (CSR_READ_1(FXP_CSR_SCB_COMMAND) && --i) 141 DELAY(1); 142 if (i == 0) 143 printf("fxp: WARNING: SCB timed out!\n"); 144 } 145 146 #ifdef DEBUG 147 static void 148 fxp_checkintr(msg) 149 char *msg; 150 { 151 u_int8_t statack; 152 int i = 10000; 153 154 do { 155 statack = CSR_READ_1(FXP_CSR_SCB_STATACK); 156 } while ((statack == 0) && (--i > 0)); 157 158 if (statack != 0) { 159 CSR_WRITE_1(FXP_CSR_SCB_STATACK, statack); 160 printf("%s: ack'd irq %x, i=%d\n", msg, statack, i); 161 } 162 } 163 #endif 164 165 int 166 EtherInit(myadr) 167 unsigned char *myadr; 168 { 169 #ifndef _STANDALONE 170 u_int32_t id; 171 #endif 172 volatile struct fxp_cb_config *cbp; 173 volatile struct fxp_cb_ias *cb_ias; 174 int i; 175 176 if (pcicheck()) { 177 printf("pcicheck failed\n"); 178 return (0); 179 } 180 #ifdef _STANDALONE 181 if (pcifinddev(0x8086, 0x1229, &mytag)) { 182 printf("no fxp\n"); 183 return (0); 184 } 185 #else 186 pcicfgread(&mytag, 0, &id); 187 if (id != 0x12298086) { 188 printf("no fxp\n"); 189 return (0); 190 } 191 #endif 192 193 pcicfgread(&mytag, FXP_PCI_IOBA, &iobase); 194 iobase &= ~3; 195 196 #ifndef _STANDALONE 197 dmamem = mapmem(DMABASE, DMASIZE); 198 if (!dmamem) 199 return (0); 200 #endif 201 202 fxp_read_eeprom((void *)myadr, 0, 3); 203 204 /* 205 * Initialize base of CBL and RFA memory. Loading with zero 206 * sets it up for regular linear addressing. 207 */ 208 CSR_WRITE_4(FXP_CSR_SCB_GENERAL, 0); 209 CSR_WRITE_1(FXP_CSR_SCB_COMMAND, FXP_SCB_COMMAND_CU_BASE); 210 211 fxp_scb_wait(); 212 CSR_WRITE_1(FXP_CSR_SCB_COMMAND, FXP_SCB_COMMAND_RU_BASE); 213 214 cbp = SNDBUF_VIRT; 215 /* 216 * This memcpy is kind of disgusting, but there are a bunch of must be 217 * zero and must be one bits in this structure and this is the easiest 218 * way to initialize them all to proper values. 219 */ 220 memcpy((void *)cbp, fxp_cb_config_template, 221 sizeof(fxp_cb_config_template)); 222 223 #define prm 0 224 #define phy_10Mbps_only 0 225 #define all_mcasts 0 226 cbp->cb_status = 0; 227 cbp->cb_command = FXP_CB_COMMAND_CONFIG | FXP_CB_COMMAND_EL; 228 cbp->link_addr = -1; /* (no) next command */ 229 cbp->byte_count = 22; /* (22) bytes to config */ 230 cbp->rx_fifo_limit = 8; /* rx fifo threshold (32 bytes) */ 231 cbp->tx_fifo_limit = 0; /* tx fifo threshold (0 bytes) */ 232 cbp->adaptive_ifs = 0; /* (no) adaptive interframe spacing */ 233 cbp->rx_dma_bytecount = 0; /* (no) rx DMA max */ 234 cbp->tx_dma_bytecount = 0; /* (no) tx DMA max */ 235 cbp->dma_mbce = 0; /* (disable) dma max counters */ 236 cbp->late_scb = 0; /* (don't) defer SCB update */ 237 cbp->tno_int_or_tco_en = 0; /* (disable) tx not okay interrupt */ 238 cbp->ci_int = 0; /* interrupt on CU not active */ 239 cbp->save_bf = prm; /* save bad frames */ 240 cbp->disc_short_rx = !prm; /* discard short packets */ 241 cbp->underrun_retry = 1; /* retry mode (1) on DMA underrun */ 242 cbp->mediatype = !phy_10Mbps_only; /* interface mode */ 243 cbp->nsai = 1; /* (don't) disable source addr insert */ 244 cbp->preamble_length = 2; /* (7 byte) preamble */ 245 cbp->loopback = 0; /* (don't) loopback */ 246 cbp->linear_priority = 0; /* (normal CSMA/CD operation) */ 247 cbp->linear_pri_mode = 0; /* (wait after xmit only) */ 248 cbp->interfrm_spacing = 6; /* (96 bits of) interframe spacing */ 249 cbp->promiscuous = prm; /* promiscuous mode */ 250 cbp->bcast_disable = 0; /* (don't) disable broadcasts */ 251 cbp->crscdt = 0; /* (CRS only) */ 252 cbp->stripping = !prm; /* truncate rx packet to byte count */ 253 cbp->padding = 1; /* (do) pad short tx packets */ 254 cbp->rcv_crc_xfer = 0; /* (don't) xfer CRC to host */ 255 cbp->force_fdx = 0; /* (don't) force full duplex */ 256 cbp->fdx_pin_en = 1; /* (enable) FDX# pin */ 257 cbp->multi_ia = 0; /* (don't) accept multiple IAs */ 258 cbp->mc_all = all_mcasts;/* accept all multicasts */ 259 #undef prm 260 #undef phy_10Mbps_only 261 #undef all_mcasts 262 263 /* 264 * Start the config command/DMA. 265 */ 266 fxp_scb_wait(); 267 CSR_WRITE_4(FXP_CSR_SCB_GENERAL, SNDBUF_PHYS); 268 CSR_WRITE_1(FXP_CSR_SCB_COMMAND, FXP_SCB_COMMAND_CU_START); 269 /* ...and wait for it to complete. */ 270 i = 10000; 271 while (!(cbp->cb_status & FXP_CB_STATUS_C) && (--i > 0)) 272 DELAY(1); 273 if (i == 0) 274 printf("config timeout"); 275 276 fxp_checkintr("config"); 277 278 cb_ias = SNDBUF_VIRT; 279 /* 280 * Now initialize the station address. Temporarily use the TxCB 281 * memory area like we did above for the config CB. 282 */ 283 cb_ias->cb_status = 0; 284 cb_ias->cb_command = FXP_CB_COMMAND_IAS | FXP_CB_COMMAND_EL; 285 cb_ias->link_addr = -1; 286 memcpy((void *)cb_ias->macaddr, myadr, 6); 287 288 /* 289 * Start the IAS (Individual Address Setup) command/DMA. 290 */ 291 fxp_scb_wait(); 292 /* address is still there */ 293 CSR_WRITE_1(FXP_CSR_SCB_COMMAND, FXP_SCB_COMMAND_CU_START); 294 /* ...and wait for it to complete. */ 295 i = 10000; 296 while (!(cb_ias->cb_status & FXP_CB_STATUS_C) && (--i > 0)) 297 DELAY(1); 298 if (i == 0) 299 printf("ias timeout"); 300 301 fxp_checkintr("ias"); 302 303 fxp_startreceiver(); 304 305 #if defined(_STANDALONE) && !defined(SUPPORT_NO_NETBSD) 306 strncpy(bi_netif.ifname, "fxp", sizeof(bi_netif.ifname)); 307 bi_netif.bus = BI_BUS_PCI; 308 bi_netif.addr.tag = mytag; 309 310 BI_ADD(&bi_netif, BTINFO_NETIF, sizeof(bi_netif)); 311 #endif 312 313 return (1); 314 } 315 316 void 317 EtherStop() 318 { 319 /* 320 * Issue software reset 321 */ 322 CSR_WRITE_4(FXP_CSR_PORT, FXP_PORT_SELECTIVE_RESET); 323 DELAY(10); 324 } 325 326 int EtherSend(pkt, len) 327 char *pkt; 328 int len; 329 { 330 volatile struct fxp_cb_tx *txp; 331 #ifdef _STANDALONE 332 static volatile struct fxp_tbd tbd; 333 #endif 334 volatile struct fxp_tbd *tbdp; 335 int i; 336 337 txp = SNDBUF_VIRT; 338 #ifdef _STANDALONE 339 tbdp = &tbd; 340 txp->tbd_array_addr = vtophys((void *)&tbd); 341 tbdp->tb_addr = vtophys(pkt); 342 #else 343 /* XXX assuming we send at max 400 bytes */ 344 tbdp = (struct fxp_tbd *)(SNDBUF_VIRT + 440); 345 txp->tbd_array_addr = SNDBUF_PHYS + 440; 346 memcpy(SNDBUF_VIRT + 400, pkt, len); 347 tbdp->tb_addr = SNDBUF_PHYS + 400; 348 #endif 349 tbdp->tb_size = len; 350 txp->tbd_number = 1; 351 txp->cb_status = 0; 352 txp->cb_command = 353 FXP_CB_COMMAND_XMIT | FXP_CB_COMMAND_SF | FXP_CB_COMMAND_EL; 354 txp->tx_threshold = tx_threshold; 355 356 txp->link_addr = -1; 357 txp->byte_count = 0; 358 359 fxp_scb_wait(); 360 CSR_WRITE_4(FXP_CSR_SCB_GENERAL, SNDBUF_PHYS); 361 CSR_WRITE_1(FXP_CSR_SCB_COMMAND, FXP_SCB_COMMAND_CU_START); 362 /* ...and wait for it to complete. */ 363 i = 10000; 364 while (!(txp->cb_status & FXP_CB_STATUS_C) && (--i > 0)) 365 DELAY(1); 366 if (i == 0) 367 printf("send timeout"); 368 369 fxp_checkintr("send"); 370 371 return (len); 372 } 373 374 static void 375 fxp_startreceiver() 376 { 377 volatile struct fxp_rfa *rfa; 378 u_int32_t v; 379 380 rfa = RECVBUF_VIRT; 381 rfa->size = RECVBUF_SIZE - sizeof(struct fxp_rfa); 382 rfa->rfa_status = 0; 383 rfa->rfa_control = FXP_RFA_CONTROL_S; 384 rfa->actual_size = 0; 385 v = RECVBUF_PHYS; /* close the "ring" */ 386 memcpy((void *)&rfa->link_addr, &v, sizeof(v)); 387 v = -1; 388 memcpy((void *)&rfa->rbd_addr, &v, sizeof(v)); 389 390 fxp_scb_wait(); 391 CSR_WRITE_4(FXP_CSR_SCB_GENERAL, RECVBUF_PHYS); 392 CSR_WRITE_1(FXP_CSR_SCB_COMMAND, FXP_SCB_COMMAND_RU_START); 393 } 394 395 int 396 EtherReceive(pkt, maxlen) 397 char *pkt; 398 int maxlen; 399 { 400 u_int8_t ruscus; 401 volatile struct fxp_rfa *rfa; 402 int len = 0; 403 404 ruscus = CSR_READ_1(FXP_CSR_SCB_RUSCUS); 405 if (((ruscus >> 2) & 0x0f) == FXP_SCB_RUS_READY) 406 return (0); 407 if (((ruscus >> 2) & 0x0f) != FXP_SCB_RUS_SUSPENDED) { 408 printf("rcv: ruscus=%x\n", ruscus); 409 return (0); 410 } 411 412 rfa = RECVBUF_VIRT; 413 if (rfa->rfa_status & FXP_RFA_STATUS_C) { 414 len = rfa->actual_size & 0x7ff; 415 if (len <= maxlen) { 416 memcpy(pkt, (caddr_t) rfa + RFA_SIZE, maxlen); 417 #if 0 418 printf("rfa status=%x, len=%x\n", 419 rfa->rfa_status, len); 420 #endif 421 } else 422 len = 0; 423 } 424 425 fxp_scb_wait(); 426 CSR_WRITE_1(FXP_CSR_SCB_COMMAND, FXP_SCB_COMMAND_RU_RESUME); 427 428 return (len); 429 } 430 431 /* 432 * Read from the serial EEPROM. Basically, you manually shift in 433 * the read opcode (one bit at a time) and then shift in the address, 434 * and then you shift out the data (all of this one bit at a time). 435 * The word size is 16 bits, so you have to provide the address for 436 * every 16 bits of data. 437 */ 438 static void 439 fxp_read_eeprom(data, offset, words) 440 u_int16_t *data; 441 int offset; 442 int words; 443 { 444 u_int16_t reg; 445 int i, x; 446 447 for (i = 0; i < words; i++) { 448 CSR_WRITE_2(FXP_CSR_EEPROMCONTROL, FXP_EEPROM_EECS); 449 /* 450 * Shift in read opcode. 451 */ 452 for (x = 3; x > 0; x--) { 453 if (FXP_EEPROM_OPC_READ & (1 << (x - 1))) { 454 reg = FXP_EEPROM_EECS | FXP_EEPROM_EEDI; 455 } else { 456 reg = FXP_EEPROM_EECS; 457 } 458 CSR_WRITE_2(FXP_CSR_EEPROMCONTROL, reg); 459 CSR_WRITE_2(FXP_CSR_EEPROMCONTROL, 460 reg | FXP_EEPROM_EESK); 461 DELAY(1); 462 CSR_WRITE_2(FXP_CSR_EEPROMCONTROL, reg); 463 DELAY(1); 464 } 465 /* 466 * Shift in address. 467 */ 468 for (x = 6; x > 0; x--) { 469 if ((i + offset) & (1 << (x - 1))) { 470 reg = FXP_EEPROM_EECS | FXP_EEPROM_EEDI; 471 } else { 472 reg = FXP_EEPROM_EECS; 473 } 474 CSR_WRITE_2(FXP_CSR_EEPROMCONTROL, reg); 475 CSR_WRITE_2(FXP_CSR_EEPROMCONTROL, 476 reg | FXP_EEPROM_EESK); 477 DELAY(1); 478 CSR_WRITE_2(FXP_CSR_EEPROMCONTROL, reg); 479 DELAY(1); 480 } 481 reg = FXP_EEPROM_EECS; 482 data[i] = 0; 483 /* 484 * Shift out data. 485 */ 486 for (x = 16; x > 0; x--) { 487 CSR_WRITE_2(FXP_CSR_EEPROMCONTROL, 488 reg | FXP_EEPROM_EESK); 489 DELAY(1); 490 if (CSR_READ_2(FXP_CSR_EEPROMCONTROL) & 491 FXP_EEPROM_EEDO) 492 data[i] |= (1 << (x - 1)); 493 CSR_WRITE_2(FXP_CSR_EEPROMCONTROL, reg); 494 DELAY(1); 495 } 496 CSR_WRITE_2(FXP_CSR_EEPROMCONTROL, 0); 497 DELAY(1); 498 } 499 } 500 501