1 /* $OpenBSD: if_ex.c,v 1.35 2008/11/28 02:44:17 brad Exp $ */ 2 /* 3 * Copyright (c) 1997, Donald A. Schmidt 4 * Copyright (c) 1996, Javier Mart�n Rueda (jmrueda@diatel.upm.es) 5 * All rights reserved. 6 * 7 * Redistribution and use in source and binary forms, with or without 8 * modification, are permitted provided that the following conditions 9 * are met: 10 * 1. Redistributions of source code must retain the above copyright 11 * notice unmodified, this list of conditions, and the following 12 * disclaimer. 13 * 2. Redistributions in binary form must reproduce the above copyright 14 * notice, this list of conditions and the following disclaimer in the 15 * documentation and/or other materials provided with the distribution. 16 * 17 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 18 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 19 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 20 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 21 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 22 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 23 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 24 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 25 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 26 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 27 * SUCH DAMAGE. 28 */ 29 30 /* 31 * Intel EtherExpress Pro/10 Ethernet driver 32 * 33 * Revision history: 34 * 35 * 30-Oct-1996: first beta version. Inet and BPF supported, but no multicast. 36 */ 37 38 #include "bpfilter.h" 39 40 #include <sys/param.h> 41 #include <sys/systm.h> 42 #include <sys/conf.h> 43 #include <sys/sockio.h> 44 #include <sys/mbuf.h> 45 #include <sys/socket.h> 46 #include <sys/device.h> 47 48 #include <net/if.h> 49 #include <net/if_media.h> 50 51 #ifdef INET 52 #include <netinet/in.h> 53 #include <netinet/if_ether.h> 54 #endif 55 56 #if NBPFILTER > 0 57 #include <net/bpf.h> 58 #endif 59 60 #include <machine/cpu.h> 61 #include <machine/bus.h> 62 63 #include <dev/isa/isavar.h> 64 #include <dev/isa/if_exreg.h> 65 66 #ifdef EX_DEBUG 67 #define Start_End 1 68 #define Rcvd_Pkts 2 69 #define Sent_Pkts 4 70 #define Status 8 71 static int debug_mask = 0; 72 static int exintr_count = 0; 73 #define DODEBUG(level, action) if (level & debug_mask) action 74 #else 75 #define DODEBUG(level, action) 76 #endif 77 78 struct ex_softc { 79 struct arpcom arpcom; /* Ethernet common data */ 80 struct ifmedia ifmedia; 81 int iobase; /* I/O base address. */ 82 u_short irq_no; /* IRQ number. */ 83 u_int mem_size; /* Total memory size, in bytes. */ 84 u_int rx_mem_size; /* Rx memory size (by default, first 3/4 of 85 total memory). */ 86 u_int rx_lower_limit, 87 rx_upper_limit; /* Lower and upper limits of receive buffer. */ 88 u_int rx_head; /* Head of receive ring buffer. */ 89 u_int tx_mem_size; /* Tx memory size (by default, last quarter of 90 total memory). */ 91 u_int tx_lower_limit, 92 tx_upper_limit; /* Lower and upper limits of transmit buffer. */ 93 u_int tx_head, tx_tail; /* Head and tail of transmit ring buffer. */ 94 u_int tx_last; /* Pointer to beginning of last frame in the 95 chain. */ 96 bus_space_tag_t sc_iot; /* ISA i/o space tag */ 97 bus_space_handle_t sc_ioh; /* ISA i/o space handle */ 98 void *sc_ih; /* Device interrupt handler */ 99 }; 100 101 static char irq2eemap[] = { -1, -1, 0, 1, -1, 2, -1, -1, -1, 0, 3, 4, -1, -1, 102 -1, -1 }; 103 static u_char ee2irqmap[] = { 9, 3, 5, 10, 11, 0, 0, 0 }; 104 105 int ex_probe(struct device *, void *, void *); 106 void ex_attach(struct device *, struct device *, void *); 107 void ex_init(struct ex_softc *); 108 void ex_start(struct ifnet *); 109 void ex_stop(struct ex_softc *); 110 int ex_ioctl(struct ifnet *, u_long, caddr_t); 111 void ex_setmulti(struct ex_softc *); 112 void ex_reset(struct ex_softc *); 113 void ex_watchdog(struct ifnet *); 114 int ex_get_media(struct ex_softc *); 115 116 int ex_ifmedia_upd(struct ifnet *); 117 void ex_ifmedia_sts(struct ifnet *, struct ifmediareq *); 118 119 u_short ex_eeprom_read(struct ex_softc *, int); 120 int ex_look_for_card(struct isa_attach_args *, struct ex_softc *sc); 121 122 int ex_intr(void *); 123 void ex_tx_intr(struct ex_softc *); 124 void ex_rx_intr(struct ex_softc *); 125 126 struct cfattach ex_ca = { 127 sizeof(struct ex_softc), ex_probe, ex_attach 128 }; 129 130 struct cfdriver ex_cd = { 131 NULL, "ex", DV_IFNET 132 }; 133 134 #define CSR_READ_1(sc, off) \ 135 bus_space_read_1((sc)->sc_iot, (sc)->sc_ioh, (off)) 136 #define CSR_READ_2(sc, off) \ 137 bus_space_read_2((sc)->sc_iot, (sc)->sc_ioh, (off)) 138 #define CSR_READ_MULTI_2(sc, off, addr, count) \ 139 bus_space_read_multi_2((sc)->sc_iot, (sc)->sc_ioh, (off), \ 140 (u_int16_t *)(addr), (count)) 141 142 #define CSR_WRITE_1(sc, off, value) \ 143 bus_space_write_1((sc)->sc_iot, (sc)->sc_ioh, (off), (value)) 144 #define CSR_WRITE_2(sc, off, value) \ 145 bus_space_write_2((sc)->sc_iot, (sc)->sc_ioh, (off), (value)) 146 #define CSR_WRITE_MULTI_2(sc, off, addr, count) \ 147 bus_space_write_multi_2((sc)->sc_iot, (sc)->sc_ioh, (off), \ 148 (u_int16_t *)(addr), (count)) 149 150 int 151 ex_look_for_card(struct isa_attach_args *ia, struct ex_softc *sc) 152 { 153 int count1, count2; 154 155 /* 156 * Check for the i82595 signature, and check that the round robin 157 * counter actually advances. 158 */ 159 if (((count1 = CSR_READ_1(sc, ID_REG)) & Id_Mask) != Id_Sig) 160 return(0); 161 count2 = CSR_READ_1(sc, ID_REG); 162 count2 = CSR_READ_1(sc, ID_REG); 163 count2 = CSR_READ_1(sc, ID_REG); 164 if ((count2 & Counter_bits) == ((count1 + 0xc0) & Counter_bits)) 165 return(1); 166 else 167 return(0); 168 } 169 170 int 171 ex_probe(struct device *parent, void *match, void *aux) 172 { 173 struct ex_softc *sc = match; 174 struct isa_attach_args *ia = aux; 175 u_short eaddr_tmp; 176 int tmp; 177 178 DODEBUG(Start_End, printf("ex_probe: start\n");); 179 180 if ((ia->ia_iobase >= 0x200) && (ia->ia_iobase <= 0x3a0)) { 181 sc->sc_iot = ia->ia_iot; 182 if(bus_space_map(sc->sc_iot, ia->ia_iobase, EX_IOSIZE, 0, 183 &sc->sc_ioh)) 184 return(0); 185 186 if (!ex_look_for_card(ia, sc)) { 187 bus_space_unmap(sc->sc_iot, sc->sc_ioh, EX_IOSIZE); 188 return(0); 189 } 190 } else 191 return(0); 192 193 ia->ia_iosize = EX_IOSIZE; 194 195 /* 196 * Reset the card. 197 */ 198 CSR_WRITE_1(sc, CMD_REG, Reset_CMD); 199 delay(200); 200 201 /* 202 * Fill in several fields of the softc structure: 203 * - I/O base address. 204 * - Hardware Ethernet address. 205 * - IRQ number (if not supplied in config file, read it from 206 * EEPROM). 207 */ 208 sc->iobase = ia->ia_iobase; 209 eaddr_tmp = ex_eeprom_read(sc, EE_Eth_Addr_Lo); 210 sc->arpcom.ac_enaddr[5] = eaddr_tmp & 0xff; 211 sc->arpcom.ac_enaddr[4] = eaddr_tmp >> 8; 212 eaddr_tmp = ex_eeprom_read(sc, EE_Eth_Addr_Mid); 213 sc->arpcom.ac_enaddr[3] = eaddr_tmp & 0xff; 214 sc->arpcom.ac_enaddr[2] = eaddr_tmp >> 8; 215 eaddr_tmp = ex_eeprom_read(sc, EE_Eth_Addr_Hi); 216 sc->arpcom.ac_enaddr[1] = eaddr_tmp & 0xff; 217 sc->arpcom.ac_enaddr[0] = eaddr_tmp >> 8; 218 tmp = ex_eeprom_read(sc, EE_IRQ_No) & IRQ_No_Mask; 219 if (ia->ia_irq > 0) { 220 if (ee2irqmap[tmp] != ia->ia_irq) 221 printf("ex: WARING: board's EEPROM is configured for IRQ %d, using %d\n", ee2irqmap[tmp], ia->ia_irq); 222 sc->irq_no = ia->ia_irq; 223 } 224 else { 225 sc->irq_no = ee2irqmap[tmp]; 226 ia->ia_irq = sc->irq_no; 227 } 228 if (sc->irq_no == 0) { 229 printf("ex: invalid IRQ.\n"); 230 return(0); 231 } 232 233 sc->mem_size = CARD_RAM_SIZE; /* XXX This should be read from the card 234 itself. */ 235 236 DODEBUG(Start_End, printf("ex_probe: finish\n");); 237 return(1); 238 } 239 240 void 241 ex_attach(struct device *parent, struct device *self, void *aux) 242 { 243 struct ex_softc *sc = (void *)self; 244 struct isa_attach_args *ia = aux; 245 struct ifnet *ifp = &sc->arpcom.ac_if; 246 struct ifmedia *ifm; 247 int temp; 248 249 DODEBUG(Start_End, printf("ex_attach: start\n");); 250 251 ifp->if_softc = sc; 252 bcopy(self->dv_xname, ifp->if_xname, IFNAMSIZ); 253 ifp->if_start = ex_start; 254 ifp->if_ioctl = ex_ioctl; 255 ifp->if_watchdog = ex_watchdog; 256 ifp->if_flags = IFF_SIMPLEX | IFF_BROADCAST | IFF_MULTICAST; 257 IFQ_SET_READY(&ifp->if_snd); 258 259 ifmedia_init(&sc->ifmedia, 0, ex_ifmedia_upd, ex_ifmedia_sts); 260 261 temp = ex_eeprom_read(sc, EE_W5); 262 if (temp & EE_W5_PORT_TPE) 263 ifmedia_add(&sc->ifmedia, IFM_ETHER|IFM_10_T, 0, NULL); 264 if (temp & EE_W5_PORT_BNC) 265 ifmedia_add(&sc->ifmedia, IFM_ETHER|IFM_10_2, 0, NULL); 266 if (temp & EE_W5_PORT_AUI) 267 ifmedia_add(&sc->ifmedia, IFM_ETHER|IFM_10_5, 0, NULL); 268 269 ifmedia_add(&sc->ifmedia, IFM_ETHER|IFM_AUTO, 0, NULL); 270 ifmedia_add(&sc->ifmedia, IFM_ETHER|IFM_NONE, 0, NULL); 271 ifmedia_set(&sc->ifmedia, ex_get_media(sc)); 272 273 ifm = &sc->ifmedia; 274 ifm->ifm_media = ifm->ifm_cur->ifm_media; 275 ex_ifmedia_upd(ifp); 276 277 if_attach(ifp); 278 ether_ifattach(ifp); 279 printf(": address %s\n", 280 ether_sprintf(sc->arpcom.ac_enaddr)); 281 282 sc->sc_ih = isa_intr_establish(ia->ia_ic, ia->ia_irq, IST_EDGE, 283 IPL_NET, ex_intr, sc, self->dv_xname); 284 ex_init(sc); 285 286 DODEBUG(Start_End, printf("ex_attach: finish\n");); 287 } 288 289 void 290 ex_init(struct ex_softc *sc) 291 { 292 struct ifnet *ifp = &sc->arpcom.ac_if; 293 int s, i; 294 unsigned short temp_reg; 295 296 DODEBUG(Start_End, printf("ex_init: start\n");); 297 298 s = splnet(); 299 sc->arpcom.ac_if.if_timer = 0; 300 301 /* 302 * Load the ethernet address into the card. 303 */ 304 CSR_WRITE_1(sc, CMD_REG, Bank2_Sel); 305 temp_reg = CSR_READ_1(sc, EEPROM_REG); 306 if (temp_reg & Trnoff_Enable) 307 CSR_WRITE_1(sc, EEPROM_REG, temp_reg & ~Trnoff_Enable); 308 for (i = 0; i < ETHER_ADDR_LEN; i++) 309 CSR_WRITE_1(sc, I_ADDR_REG0 + i, sc->arpcom.ac_enaddr[i]); 310 /* 311 * - Setup transmit chaining and discard bad received frames. 312 * - Match broadcast. 313 * - Clear test mode. 314 * - Set receiving mode. 315 * - Set IRQ number. 316 */ 317 CSR_WRITE_1(sc, REG1, CSR_READ_1(sc, REG1) | Tx_Chn_Int_Md | 318 Tx_Chn_ErStp | Disc_Bad_Fr); 319 CSR_WRITE_1(sc, REG2, CSR_READ_1(sc, REG2) | No_SA_Ins | 320 RX_CRC_InMem); 321 CSR_WRITE_1(sc, REG3, (CSR_READ_1(sc, REG3) & 0x3f)); 322 CSR_WRITE_1(sc, CMD_REG, Bank1_Sel); 323 CSR_WRITE_1(sc, INT_NO_REG, (CSR_READ_1(sc, INT_NO_REG) & 0xf8) | 324 irq2eemap[sc->irq_no]); 325 326 /* 327 * Divide the available memory in the card into rcv and xmt buffers. 328 * By default, I use the first 3/4 of the memory for the rcv buffer, 329 * and the remaining 1/4 of the memory for the xmt buffer. 330 */ 331 sc->rx_mem_size = sc->mem_size * 3 / 4; 332 sc->tx_mem_size = sc->mem_size - sc->rx_mem_size; 333 sc->rx_lower_limit = 0x0000; 334 sc->rx_upper_limit = sc->rx_mem_size - 2; 335 sc->tx_lower_limit = sc->rx_mem_size; 336 sc->tx_upper_limit = sc->mem_size - 2; 337 CSR_WRITE_1(sc, RCV_LOWER_LIMIT_REG, sc->rx_lower_limit >> 8); 338 CSR_WRITE_1(sc, RCV_UPPER_LIMIT_REG, sc->rx_upper_limit >> 8); 339 CSR_WRITE_1(sc, XMT_LOWER_LIMIT_REG, sc->tx_lower_limit >> 8); 340 CSR_WRITE_1(sc, XMT_UPPER_LIMIT_REG, sc->tx_upper_limit >> 8); 341 342 /* 343 * Enable receive and transmit interrupts, and clear any pending int. 344 */ 345 CSR_WRITE_1(sc, REG1, CSR_READ_1(sc, REG1) | TriST_INT); 346 CSR_WRITE_1(sc, CMD_REG, Bank0_Sel); 347 CSR_WRITE_1(sc, MASK_REG, All_Int & ~(Rx_Int | Tx_Int)); 348 CSR_WRITE_1(sc, STATUS_REG, All_Int); 349 350 /* 351 * Initialize receive and transmit ring buffers. 352 */ 353 CSR_WRITE_2(sc, RCV_BAR, sc->rx_lower_limit); 354 sc->rx_head = sc->rx_lower_limit; 355 CSR_WRITE_2(sc, RCV_STOP_REG, sc->rx_upper_limit | 0xfe); 356 CSR_WRITE_2(sc, XMT_BAR, sc->tx_lower_limit); 357 sc->tx_head = sc->tx_tail = sc->tx_lower_limit; 358 359 ifp->if_flags |= IFF_RUNNING; 360 ifp->if_flags &= ~IFF_OACTIVE; 361 DODEBUG(Status, printf("OIDLE init\n");); 362 363 ex_setmulti(sc); 364 365 /* 366 * Final reset of the board, and enable operation. 367 */ 368 CSR_WRITE_1(sc, CMD_REG, Sel_Reset_CMD); 369 delay(2); 370 CSR_WRITE_1(sc, CMD_REG, Rcv_Enable_CMD); 371 372 ex_start(ifp); 373 splx(s); 374 375 DODEBUG(Start_End, printf("ex_init: finish\n");); 376 } 377 378 void 379 ex_start(struct ifnet *ifp) 380 { 381 struct ex_softc *sc = ifp->if_softc; 382 int i, len, data_len, avail, dest, next; 383 unsigned char tmp16[2]; 384 struct mbuf *opkt; 385 struct mbuf *m; 386 387 DODEBUG(Start_End, printf("ex_start: start\n");); 388 389 /* 390 * Main loop: send outgoing packets to network card until there are no 391 * more packets left, or the card cannot accept any more yet. 392 */ 393 while (!(ifp->if_flags & IFF_OACTIVE)) { 394 IFQ_POLL(&ifp->if_snd, opkt); 395 if (opkt == NULL) 396 break; 397 398 /* 399 * Ensure there is enough free transmit buffer space for this 400 * packet, including its header. Note: the header cannot wrap 401 * around the end of the transmit buffer and must be kept 402 * together, so we allow space for twice the length of the 403 * header, just in case. 404 */ 405 for (len = 0, m = opkt; m != NULL; m = m->m_next) 406 len += m->m_len; 407 data_len = len; 408 DODEBUG(Sent_Pkts, printf("1. Sending packet with %d data bytes. ", data_len);); 409 if (len & 1) 410 len += XMT_HEADER_LEN + 1; 411 else 412 len += XMT_HEADER_LEN; 413 if ((i = sc->tx_tail - sc->tx_head) >= 0) 414 avail = sc->tx_mem_size - i; 415 else 416 avail = -i; 417 DODEBUG(Sent_Pkts, printf("i=%d, avail=%d\n", i, avail);); 418 if (avail >= len + XMT_HEADER_LEN) { 419 IFQ_DEQUEUE(&ifp->if_snd, opkt); 420 421 #ifdef EX_PSA_INTR 422 /* 423 * Disable rx and tx interrupts, to avoid corruption of 424 * the host address register by interrupt service 425 * routines. XXX Is this necessary with splnet() 426 * enabled? 427 */ 428 CSR_WRITE_2(sc, MASK_REG, All_Int); 429 #endif 430 431 /* 432 * Compute the start and end addresses of this frame 433 * in the tx buffer. 434 */ 435 dest = sc->tx_tail; 436 next = dest + len; 437 if (next > sc->tx_upper_limit) { 438 if ((sc->tx_upper_limit + 2 - sc->tx_tail) <= 439 XMT_HEADER_LEN) { 440 dest = sc->tx_lower_limit; 441 next = dest + len; 442 } else 443 next = sc->tx_lower_limit + next - 444 sc->tx_upper_limit - 2; 445 } 446 447 /* Build the packet frame in the card's ring buffer. */ 448 DODEBUG(Sent_Pkts, printf("2. dest=%d, next=%d. ", dest, next);); 449 CSR_WRITE_2(sc, HOST_ADDR_REG, dest); 450 CSR_WRITE_2(sc, IO_PORT_REG, Transmit_CMD); 451 CSR_WRITE_2(sc, IO_PORT_REG, 0); 452 CSR_WRITE_2(sc, IO_PORT_REG, next); 453 CSR_WRITE_2(sc, IO_PORT_REG, data_len); 454 455 /* 456 * Output the packet data to the card. Ensure all 457 * transfers are 16-bit wide, even if individual mbufs 458 * have odd length. 459 */ 460 461 for (m = opkt, i = 0; m != NULL; m = m->m_next) { 462 DODEBUG(Sent_Pkts, printf("[%d]", m->m_len);); 463 if (i) { 464 tmp16[1] = *(mtod(m, caddr_t)); 465 CSR_WRITE_MULTI_2(sc, IO_PORT_REG, tmp16, 1); 466 } 467 CSR_WRITE_MULTI_2(sc, IO_PORT_REG, mtod(m, caddr_t) 468 + i, (m->m_len - i) / 2); 469 if ((i = (m->m_len - i) & 1)) 470 tmp16[0] = *(mtod(m, caddr_t) + 471 m->m_len - 1); 472 } 473 if (i) 474 CSR_WRITE_MULTI_2(sc, IO_PORT_REG, tmp16, 1); 475 476 /* 477 * If there were other frames chained, update the 478 * chain in the last one. 479 */ 480 if (sc->tx_head != sc->tx_tail) { 481 if (sc->tx_tail != dest) { 482 CSR_WRITE_2(sc, HOST_ADDR_REG, 483 sc->tx_last + XMT_Chain_Point); 484 CSR_WRITE_2(sc, IO_PORT_REG, dest); 485 } 486 CSR_WRITE_2(sc, HOST_ADDR_REG, sc->tx_last + 487 XMT_Byte_Count); 488 i = CSR_READ_2(sc, IO_PORT_REG); 489 CSR_WRITE_2(sc, HOST_ADDR_REG, sc->tx_last + 490 XMT_Byte_Count); 491 CSR_WRITE_2(sc, IO_PORT_REG, i | Ch_bit); 492 } 493 494 /* 495 * Resume normal operation of the card: 496 * -Make a dummy read to flush the DRAM write pipeline. 497 * -Enable receive and transmit interrupts. 498 * -Send Transmit or Resume_XMT command, as appropriate. 499 */ 500 CSR_READ_2(sc, IO_PORT_REG); 501 #ifdef EX_PSA_INTR 502 CSR_WRITE_2(sc, MASK_REG, All_Int & ~(Rx_Int | Tx_Int)); 503 #endif 504 if (sc->tx_head == sc->tx_tail) { 505 CSR_WRITE_2(sc, XMT_BAR, dest); 506 CSR_WRITE_1(sc, CMD_REG, Transmit_CMD); 507 sc->tx_head = dest; 508 DODEBUG(Sent_Pkts, printf("Transmit\n");); 509 } else { 510 CSR_WRITE_1(sc, CMD_REG, Resume_XMT_List_CMD); 511 DODEBUG(Sent_Pkts, printf("Resume\n");); 512 } 513 sc->tx_last = dest; 514 sc->tx_tail = next; 515 #if NBPFILTER > 0 516 if (ifp->if_bpf != NULL) 517 bpf_mtap(ifp->if_bpf, opkt, 518 BPF_DIRECTION_OUT); 519 #endif 520 ifp->if_timer = 2; 521 ifp->if_opackets++; 522 m_freem(opkt); 523 } else { 524 ifp->if_flags |= IFF_OACTIVE; 525 DODEBUG(Status, printf("OACTIVE start\n");); 526 } 527 } 528 529 DODEBUG(Start_End, printf("ex_start: finish\n");); 530 } 531 532 void 533 ex_stop(struct ex_softc *sc) 534 { 535 DODEBUG(Start_End, printf("ex_stop: start\n");); 536 537 /* 538 * Disable card operation: 539 * - Disable the interrupt line. 540 * - Flush transmission and disable reception. 541 * - Mask and clear all interrupts. 542 * - Reset the 82595. 543 */ 544 CSR_WRITE_1(sc, CMD_REG, Bank1_Sel); 545 CSR_WRITE_1(sc, REG1, CSR_READ_1(sc, REG1) & ~TriST_INT); 546 CSR_WRITE_1(sc, CMD_REG, Bank0_Sel); 547 CSR_WRITE_1(sc, CMD_REG, Rcv_Stop); 548 sc->tx_head = sc->tx_tail = sc->tx_lower_limit; 549 sc->tx_last = 0; /* XXX I think these two lines are not necessary, 550 because ex_init will always be called again 551 to reinit the interface. */ 552 CSR_WRITE_1(sc, MASK_REG, All_Int); 553 CSR_WRITE_1(sc, STATUS_REG, All_Int); 554 CSR_WRITE_1(sc, CMD_REG, Reset_CMD); 555 delay(200); 556 557 DODEBUG(Start_End, printf("ex_stop: finish\n");); 558 } 559 560 561 int 562 ex_intr(void *arg) 563 { 564 struct ex_softc *sc = arg; 565 struct ifnet *ifp = &sc->arpcom.ac_if; 566 int int_status, send_pkts; 567 int handled; 568 569 DODEBUG(Start_End, printf("exintr: start\n");); 570 571 #ifdef EX_DEBUG 572 if (++exintr_count != 1) 573 printf("WARNING: nested interrupt (%d). Mail the author.\n", 574 exintr_count); 575 #endif 576 577 send_pkts = 0; 578 while ((int_status = CSR_READ_1(sc, STATUS_REG)) & (Tx_Int | Rx_Int)) { 579 if (int_status & Rx_Int) { 580 CSR_WRITE_1(sc, STATUS_REG, Rx_Int); 581 handled = 1; 582 ex_rx_intr(sc); 583 } else if (int_status & Tx_Int) { 584 CSR_WRITE_1(sc, STATUS_REG, Tx_Int); 585 handled = 1; 586 ex_tx_intr(sc); 587 send_pkts = 1; 588 } else 589 handled = 0; 590 } 591 592 /* 593 * If any packet has been transmitted, and there are queued packets to 594 * be sent, attempt to send more packets to the network card. 595 */ 596 597 if (send_pkts && IFQ_IS_EMPTY(&ifp->if_snd) == 0) 598 ex_start(ifp); 599 #ifdef EX_DEBUG 600 exintr_count--; 601 #endif 602 DODEBUG(Start_End, printf("exintr: finish\n");); 603 604 return handled; 605 } 606 607 void 608 ex_tx_intr(struct ex_softc *sc) 609 { 610 struct ifnet *ifp = &sc->arpcom.ac_if; 611 int tx_status; 612 613 DODEBUG(Start_End, printf("ex_tx_intr: start\n");); 614 /* 615 * - Cancel the watchdog. 616 * For all packets transmitted since last transmit interrupt: 617 * - Advance chain pointer to next queued packet. 618 * - Update statistics. 619 */ 620 ifp->if_timer = 0; 621 while (sc->tx_head != sc->tx_tail) { 622 CSR_WRITE_2(sc, HOST_ADDR_REG, sc->tx_head); 623 if (!CSR_READ_2(sc, IO_PORT_REG) & Done_bit) 624 break; 625 tx_status = CSR_READ_2(sc, IO_PORT_REG); 626 sc->tx_head = CSR_READ_2(sc, IO_PORT_REG); 627 if (tx_status & TX_OK_bit) 628 ifp->if_opackets++; 629 else 630 ifp->if_oerrors++; 631 ifp->if_collisions += tx_status & No_Collisions_bits; 632 } 633 634 /* The card should be ready to accept more packets now. */ 635 ifp->if_flags &= ~IFF_OACTIVE; 636 DODEBUG(Status, printf("OIDLE tx_intr\n");); 637 638 DODEBUG(Start_End, printf("ex_tx_intr: finish\n");); 639 } 640 641 void 642 ex_rx_intr(struct ex_softc *sc) 643 { 644 struct ifnet *ifp = &sc->arpcom.ac_if; 645 int rx_status, pkt_len, QQQ; 646 struct mbuf *m, *ipkt; 647 648 DODEBUG(Start_End, printf("ex_rx_intr: start\n");); 649 /* 650 * For all packets received since last receive interrupt: 651 * - If packet ok, read it into a new mbuf and queue it to interface, 652 * updating statistics. 653 * - If packet bad, just discard it, and update statistics. 654 * Finally, advance receive stop limit in card's memory to new location. 655 */ 656 CSR_WRITE_2(sc, HOST_ADDR_REG, sc->rx_head); 657 while (CSR_READ_2(sc, IO_PORT_REG) == RCV_Done) { 658 rx_status = CSR_READ_2(sc, IO_PORT_REG); 659 sc->rx_head = CSR_READ_2(sc, IO_PORT_REG); 660 QQQ = pkt_len = CSR_READ_2(sc, IO_PORT_REG); 661 if (rx_status & RCV_OK_bit) { 662 MGETHDR(m, M_DONTWAIT, MT_DATA); 663 ipkt = m; 664 if (ipkt == NULL) 665 ifp->if_iqdrops++; 666 else { 667 ipkt->m_pkthdr.rcvif = ifp; 668 ipkt->m_pkthdr.len = pkt_len; 669 ipkt->m_len = MHLEN; 670 while (pkt_len > 0) { 671 if (pkt_len >= MINCLSIZE) { 672 MCLGET(m, M_DONTWAIT); 673 if (m->m_flags & M_EXT) 674 m->m_len = MCLBYTES; 675 else { 676 m_freem(ipkt); 677 ifp->if_iqdrops++; 678 goto rx_another; 679 } 680 } 681 m->m_len = min(m->m_len, pkt_len); 682 /* 683 * NOTE: I'm assuming that all mbufs 684 * allocated are of even length, except 685 * for the last one in an odd-length 686 * packet. 687 */ 688 CSR_READ_MULTI_2(sc, IO_PORT_REG, 689 mtod(m, caddr_t), m->m_len / 2); 690 if (m->m_len & 1) 691 *(mtod(m, caddr_t) + 692 m->m_len - 1) = 693 CSR_READ_1(sc, IO_PORT_REG); 694 pkt_len -= m->m_len; 695 if (pkt_len > 0) { 696 MGET(m->m_next, M_DONTWAIT, 697 MT_DATA); 698 if (m->m_next == NULL) { 699 m_freem(ipkt); 700 ifp->if_iqdrops++; 701 goto rx_another; 702 } 703 m = m->m_next; 704 m->m_len = MLEN; 705 } 706 } 707 #ifdef EX_DEBUG 708 if (debug_mask & Rcvd_Pkts) { 709 if ((eh->ether_dhost[5] != 0xff) || 710 (eh->ether_dhost[0] != 0xff)) { 711 printf("Receive packet with %d data bytes: %6D -> ", QQQ, eh->ether_shost, ":"); 712 printf("%6D\n", eh->ether_dhost, ":"); 713 } /* QQQ */ 714 } 715 #endif 716 #if NBPFILTER > 0 717 if (ifp->if_bpf != NULL) 718 bpf_mtap(ifp->if_bpf, ipkt, 719 BPF_DIRECTION_IN); 720 #endif 721 ether_input_mbuf(ifp, ipkt); 722 ifp->if_ipackets++; 723 } 724 } else 725 ifp->if_ierrors++; 726 CSR_WRITE_2(sc, HOST_ADDR_REG, sc->rx_head); 727 rx_another: ; 728 } 729 if (sc->rx_head < sc->rx_lower_limit + 2) 730 CSR_WRITE_2(sc, RCV_STOP_REG, sc->rx_upper_limit); 731 else 732 CSR_WRITE_2(sc, RCV_STOP_REG, sc->rx_head - 2); 733 734 DODEBUG(Start_End, printf("ex_rx_intr: finish\n");); 735 } 736 737 int 738 ex_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data) 739 { 740 struct ex_softc *sc = ifp->if_softc; 741 struct ifaddr *ifa = (struct ifaddr *) data; 742 struct ifreq *ifr = (struct ifreq *) data; 743 int s, error = 0; 744 745 DODEBUG(Start_End, printf("ex_ioctl: start ");); 746 747 s = splnet(); 748 749 switch(cmd) { 750 case SIOCSIFADDR: 751 DODEBUG(Start_End, printf("SIOCSIFADDR");); 752 ifp->if_flags |= IFF_UP; 753 if (!(ifp->if_flags & IFF_RUNNING)) 754 ex_init(sc); 755 #ifdef INET 756 if (ifa->ifa_addr->sa_family == AF_INET) 757 arp_ifinit(&sc->arpcom, ifa); 758 #endif 759 break; 760 case SIOCSIFFLAGS: 761 DODEBUG(Start_End, printf("SIOCSIFFLAGS");); 762 if ((ifp->if_flags & IFF_UP) == 0 && ifp->if_flags & IFF_RUNNING) { 763 ifp->if_flags &= ~IFF_RUNNING; 764 ex_stop(sc); 765 } else 766 ex_init(sc); 767 break; 768 case SIOCSIFMEDIA: 769 case SIOCGIFMEDIA: 770 error = ifmedia_ioctl(ifp, ifr, &sc->ifmedia, cmd); 771 break; 772 default: 773 error = ether_ioctl(ifp, &sc->arpcom, cmd, data); 774 } 775 776 if (error == ENETRESET) { 777 if (ifp->if_flags & IFF_RUNNING) 778 ex_init(sc); 779 error = 0; 780 } 781 782 splx(s); 783 DODEBUG(Start_End, printf("\nex_ioctl: finish\n");); 784 return(error); 785 } 786 787 void 788 ex_setmulti(struct ex_softc *sc) 789 { 790 struct arpcom *ac = &sc->arpcom; 791 struct ifnet *ifp = &sc->arpcom.ac_if; 792 struct ether_multi *enm; 793 struct ether_multistep step; 794 uint16_t *addr; 795 int count, timeout, status; 796 797 ifp->if_flags &= ~IFF_ALLMULTI; 798 799 count = 0; 800 ETHER_FIRST_MULTI(step, ac, enm); 801 while (enm != NULL) { 802 count++; 803 ETHER_NEXT_MULTI(step, enm); 804 } 805 806 if (count > 63 || ac->ac_multirangecnt > 0) 807 ifp->if_flags |= IFF_ALLMULTI; 808 809 if (ifp->if_flags & IFF_PROMISC || ifp->if_flags & IFF_ALLMULTI) { 810 /* 811 * Interface is in promiscuous mode, there are too many 812 * multicast addresses for the card to handle or there 813 * is a multicast range 814 */ 815 CSR_WRITE_1(sc, CMD_REG, Bank2_Sel); 816 CSR_WRITE_1(sc, REG2, CSR_READ_1(sc, REG2) | Promisc_Mode); 817 CSR_WRITE_1(sc, REG3, CSR_READ_1(sc, REG3)); 818 CSR_WRITE_1(sc, CMD_REG, Bank0_Sel); 819 } else if (ifp->if_flags & IFF_MULTICAST && count > 0) { 820 /* Program multicast addresses plus our MAC address 821 * into the filter */ 822 CSR_WRITE_1(sc, CMD_REG, Bank2_Sel); 823 CSR_WRITE_1(sc, REG2, CSR_READ_1(sc, REG2) | Multi_IA); 824 CSR_WRITE_1(sc, REG3, CSR_READ_1(sc, REG3)); 825 CSR_WRITE_1(sc, CMD_REG, Bank0_Sel); 826 827 /* Borrow space from TX buffer; this should be safe 828 * as this is only called from ex_init */ 829 830 CSR_WRITE_2(sc, HOST_ADDR_REG, sc->tx_lower_limit); 831 CSR_WRITE_2(sc, IO_PORT_REG, MC_Setup_CMD); 832 CSR_WRITE_2(sc, IO_PORT_REG, 0); 833 CSR_WRITE_2(sc, IO_PORT_REG, 0); 834 CSR_WRITE_2(sc, IO_PORT_REG, (count + 1) * 6); 835 836 ETHER_FIRST_MULTI(step, ac, enm); 837 while (enm != NULL) { 838 addr = (uint16_t*)enm->enm_addrlo; 839 CSR_WRITE_2(sc, IO_PORT_REG, *addr++); 840 CSR_WRITE_2(sc, IO_PORT_REG, *addr++); 841 CSR_WRITE_2(sc, IO_PORT_REG, *addr++); 842 ETHER_NEXT_MULTI(step, enm); 843 } 844 845 /* Program our MAC address as well */ 846 /* XXX: Is this necessary? The Linux driver does this 847 * but the NetBSD driver does not */ 848 addr = (uint16_t*) sc->arpcom.ac_enaddr; 849 CSR_WRITE_2(sc, IO_PORT_REG, *addr++); 850 CSR_WRITE_2(sc, IO_PORT_REG, *addr++); 851 CSR_WRITE_2(sc, IO_PORT_REG, *addr++); 852 853 CSR_READ_2(sc, IO_PORT_REG); 854 CSR_WRITE_2(sc, XMT_BAR, sc->tx_lower_limit); 855 CSR_WRITE_1(sc, CMD_REG, MC_Setup_CMD); 856 857 sc->tx_head = sc->tx_lower_limit; 858 sc->tx_tail = sc->tx_head + XMT_HEADER_LEN + (count + 1) * 6; 859 860 for (timeout = 0; timeout < 100; timeout++) { 861 DELAY(2); 862 if ((CSR_READ_1(sc, STATUS_REG) & Exec_Int) == 0) 863 continue; 864 865 status = CSR_READ_1(sc, CMD_REG); 866 CSR_WRITE_1(sc, STATUS_REG, Exec_Int); 867 break; 868 } 869 870 sc->tx_head = sc->tx_tail; 871 } else { 872 /* No multicast or promiscuous mode */ 873 CSR_WRITE_1(sc, CMD_REG, Bank2_Sel); 874 CSR_WRITE_1(sc, REG2, CSR_READ_1(sc, REG2) & 0xDE); 875 /* ~(Multi_IA | Promisc_Mode) */ 876 CSR_WRITE_1(sc, REG3, CSR_READ_1(sc, REG3)); 877 CSR_WRITE_1(sc, CMD_REG, Bank0_Sel); 878 } 879 } 880 881 void 882 ex_reset(struct ex_softc *sc) 883 { 884 int s; 885 886 DODEBUG(Start_End, printf("ex_reset: start\n");); 887 888 s = splnet(); 889 ex_stop(sc); 890 ex_init(sc); 891 splx(s); 892 893 DODEBUG(Start_End, printf("ex_reset: finish\n");); 894 } 895 896 void 897 ex_watchdog(struct ifnet *ifp) 898 { 899 struct ex_softc *sc = ifp->if_softc; 900 901 DODEBUG(Start_End, printf("ex_watchdog: start\n");); 902 903 ifp->if_flags &= ~IFF_OACTIVE; 904 DODEBUG(Status, printf("OIDLE watchdog\n");); 905 ifp->if_oerrors++; 906 ex_reset(sc); 907 ex_start(ifp); 908 909 DODEBUG(Start_End, printf("ex_watchdog: finish\n");); 910 } 911 912 int 913 ex_get_media(struct ex_softc *sc) 914 { 915 int current, media; 916 917 media = ex_eeprom_read(sc, EE_W5); 918 919 CSR_WRITE_1(sc, CMD_REG, Bank2_Sel); 920 current = CSR_READ_1(sc, REG3); 921 CSR_WRITE_1(sc, CMD_REG, Bank0_Sel); 922 923 if ((current & TPE_bit) && (media & EE_W5_PORT_TPE)) 924 return(IFM_ETHER|IFM_10_T); 925 if ((current & BNC_bit) && (media & EE_W5_PORT_BNC)) 926 return(IFM_ETHER|IFM_10_2); 927 928 if (media & EE_W5_PORT_AUI) 929 return (IFM_ETHER|IFM_10_5); 930 931 return (IFM_ETHER|IFM_AUTO); 932 } 933 934 int 935 ex_ifmedia_upd (struct ifnet *ifp) 936 { 937 struct ex_softc *sc = ifp->if_softc; 938 939 if (IFM_TYPE(sc->ifmedia.ifm_media) != IFM_ETHER) 940 return (EINVAL); 941 942 return (0); 943 } 944 945 void 946 ex_ifmedia_sts(struct ifnet *ifp, struct ifmediareq *ifmr) 947 { 948 struct ex_softc *sc = ifp->if_softc; 949 950 ifmr->ifm_status = IFM_AVALID | IFM_ACTIVE; 951 ifmr->ifm_active = ex_get_media(sc); 952 } 953 954 u_short 955 ex_eeprom_read(struct ex_softc *sc, int location) 956 { 957 int i; 958 u_short data = 0; 959 int read_cmd = location | EE_READ_CMD; 960 short ctrl_val = EECS; 961 962 CSR_WRITE_1(sc, CMD_REG, Bank2_Sel); 963 CSR_WRITE_1(sc, EEPROM_REG, EECS); 964 for (i = 8; i >= 0; i--) { 965 short outval = (read_cmd & (1 << i)) ? ctrl_val | EEDI : 966 ctrl_val; 967 CSR_WRITE_1(sc, EEPROM_REG, outval); 968 CSR_WRITE_1(sc, EEPROM_REG, outval | EESK); 969 delay(3); 970 CSR_WRITE_1(sc, EEPROM_REG, outval); 971 delay(2); 972 } 973 CSR_WRITE_1(sc, EEPROM_REG, ctrl_val); 974 for (i = 16; i > 0; i--) { 975 CSR_WRITE_1(sc, EEPROM_REG, ctrl_val | EESK); 976 delay(3); 977 data = (data << 1) | ((CSR_READ_1(sc, EEPROM_REG) & EEDO) ? 1 : 0); 978 CSR_WRITE_1(sc, EEPROM_REG, ctrl_val); 979 delay(2); 980 } 981 ctrl_val &= ~EECS; 982 CSR_WRITE_1(sc, EEPROM_REG, ctrl_val | EESK); 983 delay(3); 984 CSR_WRITE_1(sc, EEPROM_REG, ctrl_val); 985 delay(2); 986 CSR_WRITE_1(sc, CMD_REG, Bank0_Sel); 987 return(data); 988 } 989