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