1 /* $OpenBSD: if_ex.c,v 1.36 2010/07/02 02:29:45 tedu 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 = 0; 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 } 589 } 590 591 /* 592 * If any packet has been transmitted, and there are queued packets to 593 * be sent, attempt to send more packets to the network card. 594 */ 595 596 if (send_pkts && IFQ_IS_EMPTY(&ifp->if_snd) == 0) 597 ex_start(ifp); 598 #ifdef EX_DEBUG 599 exintr_count--; 600 #endif 601 DODEBUG(Start_End, printf("exintr: finish\n");); 602 603 return handled; 604 } 605 606 void 607 ex_tx_intr(struct ex_softc *sc) 608 { 609 struct ifnet *ifp = &sc->arpcom.ac_if; 610 int tx_status; 611 612 DODEBUG(Start_End, printf("ex_tx_intr: start\n");); 613 /* 614 * - Cancel the watchdog. 615 * For all packets transmitted since last transmit interrupt: 616 * - Advance chain pointer to next queued packet. 617 * - Update statistics. 618 */ 619 ifp->if_timer = 0; 620 while (sc->tx_head != sc->tx_tail) { 621 CSR_WRITE_2(sc, HOST_ADDR_REG, sc->tx_head); 622 if (!CSR_READ_2(sc, IO_PORT_REG) & Done_bit) 623 break; 624 tx_status = CSR_READ_2(sc, IO_PORT_REG); 625 sc->tx_head = CSR_READ_2(sc, IO_PORT_REG); 626 if (tx_status & TX_OK_bit) 627 ifp->if_opackets++; 628 else 629 ifp->if_oerrors++; 630 ifp->if_collisions += tx_status & No_Collisions_bits; 631 } 632 633 /* The card should be ready to accept more packets now. */ 634 ifp->if_flags &= ~IFF_OACTIVE; 635 DODEBUG(Status, printf("OIDLE tx_intr\n");); 636 637 DODEBUG(Start_End, printf("ex_tx_intr: finish\n");); 638 } 639 640 void 641 ex_rx_intr(struct ex_softc *sc) 642 { 643 struct ifnet *ifp = &sc->arpcom.ac_if; 644 int rx_status, pkt_len, QQQ; 645 struct mbuf *m, *ipkt; 646 647 DODEBUG(Start_End, printf("ex_rx_intr: start\n");); 648 /* 649 * For all packets received since last receive interrupt: 650 * - If packet ok, read it into a new mbuf and queue it to interface, 651 * updating statistics. 652 * - If packet bad, just discard it, and update statistics. 653 * Finally, advance receive stop limit in card's memory to new location. 654 */ 655 CSR_WRITE_2(sc, HOST_ADDR_REG, sc->rx_head); 656 while (CSR_READ_2(sc, IO_PORT_REG) == RCV_Done) { 657 rx_status = CSR_READ_2(sc, IO_PORT_REG); 658 sc->rx_head = CSR_READ_2(sc, IO_PORT_REG); 659 QQQ = pkt_len = CSR_READ_2(sc, IO_PORT_REG); 660 if (rx_status & RCV_OK_bit) { 661 MGETHDR(m, M_DONTWAIT, MT_DATA); 662 ipkt = m; 663 if (ipkt == NULL) 664 ifp->if_iqdrops++; 665 else { 666 ipkt->m_pkthdr.rcvif = ifp; 667 ipkt->m_pkthdr.len = pkt_len; 668 ipkt->m_len = MHLEN; 669 while (pkt_len > 0) { 670 if (pkt_len >= MINCLSIZE) { 671 MCLGET(m, M_DONTWAIT); 672 if (m->m_flags & M_EXT) 673 m->m_len = MCLBYTES; 674 else { 675 m_freem(ipkt); 676 ifp->if_iqdrops++; 677 goto rx_another; 678 } 679 } 680 m->m_len = min(m->m_len, pkt_len); 681 /* 682 * NOTE: I'm assuming that all mbufs 683 * allocated are of even length, except 684 * for the last one in an odd-length 685 * packet. 686 */ 687 CSR_READ_MULTI_2(sc, IO_PORT_REG, 688 mtod(m, caddr_t), m->m_len / 2); 689 if (m->m_len & 1) 690 *(mtod(m, caddr_t) + 691 m->m_len - 1) = 692 CSR_READ_1(sc, IO_PORT_REG); 693 pkt_len -= m->m_len; 694 if (pkt_len > 0) { 695 MGET(m->m_next, M_DONTWAIT, 696 MT_DATA); 697 if (m->m_next == NULL) { 698 m_freem(ipkt); 699 ifp->if_iqdrops++; 700 goto rx_another; 701 } 702 m = m->m_next; 703 m->m_len = MLEN; 704 } 705 } 706 #ifdef EX_DEBUG 707 if (debug_mask & Rcvd_Pkts) { 708 if ((eh->ether_dhost[5] != 0xff) || 709 (eh->ether_dhost[0] != 0xff)) { 710 printf("Receive packet with %d data bytes: %6D -> ", QQQ, eh->ether_shost, ":"); 711 printf("%6D\n", eh->ether_dhost, ":"); 712 } /* QQQ */ 713 } 714 #endif 715 #if NBPFILTER > 0 716 if (ifp->if_bpf != NULL) 717 bpf_mtap(ifp->if_bpf, ipkt, 718 BPF_DIRECTION_IN); 719 #endif 720 ether_input_mbuf(ifp, ipkt); 721 ifp->if_ipackets++; 722 } 723 } else 724 ifp->if_ierrors++; 725 CSR_WRITE_2(sc, HOST_ADDR_REG, sc->rx_head); 726 rx_another: ; 727 } 728 if (sc->rx_head < sc->rx_lower_limit + 2) 729 CSR_WRITE_2(sc, RCV_STOP_REG, sc->rx_upper_limit); 730 else 731 CSR_WRITE_2(sc, RCV_STOP_REG, sc->rx_head - 2); 732 733 DODEBUG(Start_End, printf("ex_rx_intr: finish\n");); 734 } 735 736 int 737 ex_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data) 738 { 739 struct ex_softc *sc = ifp->if_softc; 740 struct ifaddr *ifa = (struct ifaddr *) data; 741 struct ifreq *ifr = (struct ifreq *) data; 742 int s, error = 0; 743 744 DODEBUG(Start_End, printf("ex_ioctl: start ");); 745 746 s = splnet(); 747 748 switch(cmd) { 749 case SIOCSIFADDR: 750 DODEBUG(Start_End, printf("SIOCSIFADDR");); 751 ifp->if_flags |= IFF_UP; 752 if (!(ifp->if_flags & IFF_RUNNING)) 753 ex_init(sc); 754 #ifdef INET 755 if (ifa->ifa_addr->sa_family == AF_INET) 756 arp_ifinit(&sc->arpcom, ifa); 757 #endif 758 break; 759 case SIOCSIFFLAGS: 760 DODEBUG(Start_End, printf("SIOCSIFFLAGS");); 761 if ((ifp->if_flags & IFF_UP) == 0 && ifp->if_flags & IFF_RUNNING) { 762 ifp->if_flags &= ~IFF_RUNNING; 763 ex_stop(sc); 764 } else 765 ex_init(sc); 766 break; 767 case SIOCSIFMEDIA: 768 case SIOCGIFMEDIA: 769 error = ifmedia_ioctl(ifp, ifr, &sc->ifmedia, cmd); 770 break; 771 default: 772 error = ether_ioctl(ifp, &sc->arpcom, cmd, data); 773 } 774 775 if (error == ENETRESET) { 776 if (ifp->if_flags & IFF_RUNNING) 777 ex_init(sc); 778 error = 0; 779 } 780 781 splx(s); 782 DODEBUG(Start_End, printf("\nex_ioctl: finish\n");); 783 return(error); 784 } 785 786 void 787 ex_setmulti(struct ex_softc *sc) 788 { 789 struct arpcom *ac = &sc->arpcom; 790 struct ifnet *ifp = &sc->arpcom.ac_if; 791 struct ether_multi *enm; 792 struct ether_multistep step; 793 uint16_t *addr; 794 int count, timeout, status; 795 796 ifp->if_flags &= ~IFF_ALLMULTI; 797 798 count = 0; 799 ETHER_FIRST_MULTI(step, ac, enm); 800 while (enm != NULL) { 801 count++; 802 ETHER_NEXT_MULTI(step, enm); 803 } 804 805 if (count > 63 || ac->ac_multirangecnt > 0) 806 ifp->if_flags |= IFF_ALLMULTI; 807 808 if (ifp->if_flags & IFF_PROMISC || ifp->if_flags & IFF_ALLMULTI) { 809 /* 810 * Interface is in promiscuous mode, there are too many 811 * multicast addresses for the card to handle or there 812 * is a multicast range 813 */ 814 CSR_WRITE_1(sc, CMD_REG, Bank2_Sel); 815 CSR_WRITE_1(sc, REG2, CSR_READ_1(sc, REG2) | Promisc_Mode); 816 CSR_WRITE_1(sc, REG3, CSR_READ_1(sc, REG3)); 817 CSR_WRITE_1(sc, CMD_REG, Bank0_Sel); 818 } else if (ifp->if_flags & IFF_MULTICAST && count > 0) { 819 /* Program multicast addresses plus our MAC address 820 * into the filter */ 821 CSR_WRITE_1(sc, CMD_REG, Bank2_Sel); 822 CSR_WRITE_1(sc, REG2, CSR_READ_1(sc, REG2) | Multi_IA); 823 CSR_WRITE_1(sc, REG3, CSR_READ_1(sc, REG3)); 824 CSR_WRITE_1(sc, CMD_REG, Bank0_Sel); 825 826 /* Borrow space from TX buffer; this should be safe 827 * as this is only called from ex_init */ 828 829 CSR_WRITE_2(sc, HOST_ADDR_REG, sc->tx_lower_limit); 830 CSR_WRITE_2(sc, IO_PORT_REG, MC_Setup_CMD); 831 CSR_WRITE_2(sc, IO_PORT_REG, 0); 832 CSR_WRITE_2(sc, IO_PORT_REG, 0); 833 CSR_WRITE_2(sc, IO_PORT_REG, (count + 1) * 6); 834 835 ETHER_FIRST_MULTI(step, ac, enm); 836 while (enm != NULL) { 837 addr = (uint16_t*)enm->enm_addrlo; 838 CSR_WRITE_2(sc, IO_PORT_REG, *addr++); 839 CSR_WRITE_2(sc, IO_PORT_REG, *addr++); 840 CSR_WRITE_2(sc, IO_PORT_REG, *addr++); 841 ETHER_NEXT_MULTI(step, enm); 842 } 843 844 /* Program our MAC address as well */ 845 /* XXX: Is this necessary? The Linux driver does this 846 * but the NetBSD driver does not */ 847 addr = (uint16_t*) sc->arpcom.ac_enaddr; 848 CSR_WRITE_2(sc, IO_PORT_REG, *addr++); 849 CSR_WRITE_2(sc, IO_PORT_REG, *addr++); 850 CSR_WRITE_2(sc, IO_PORT_REG, *addr++); 851 852 CSR_READ_2(sc, IO_PORT_REG); 853 CSR_WRITE_2(sc, XMT_BAR, sc->tx_lower_limit); 854 CSR_WRITE_1(sc, CMD_REG, MC_Setup_CMD); 855 856 sc->tx_head = sc->tx_lower_limit; 857 sc->tx_tail = sc->tx_head + XMT_HEADER_LEN + (count + 1) * 6; 858 859 for (timeout = 0; timeout < 100; timeout++) { 860 DELAY(2); 861 if ((CSR_READ_1(sc, STATUS_REG) & Exec_Int) == 0) 862 continue; 863 864 status = CSR_READ_1(sc, CMD_REG); 865 CSR_WRITE_1(sc, STATUS_REG, Exec_Int); 866 break; 867 } 868 869 sc->tx_head = sc->tx_tail; 870 } else { 871 /* No multicast or promiscuous mode */ 872 CSR_WRITE_1(sc, CMD_REG, Bank2_Sel); 873 CSR_WRITE_1(sc, REG2, CSR_READ_1(sc, REG2) & 0xDE); 874 /* ~(Multi_IA | Promisc_Mode) */ 875 CSR_WRITE_1(sc, REG3, CSR_READ_1(sc, REG3)); 876 CSR_WRITE_1(sc, CMD_REG, Bank0_Sel); 877 } 878 } 879 880 void 881 ex_reset(struct ex_softc *sc) 882 { 883 int s; 884 885 DODEBUG(Start_End, printf("ex_reset: start\n");); 886 887 s = splnet(); 888 ex_stop(sc); 889 ex_init(sc); 890 splx(s); 891 892 DODEBUG(Start_End, printf("ex_reset: finish\n");); 893 } 894 895 void 896 ex_watchdog(struct ifnet *ifp) 897 { 898 struct ex_softc *sc = ifp->if_softc; 899 900 DODEBUG(Start_End, printf("ex_watchdog: start\n");); 901 902 ifp->if_flags &= ~IFF_OACTIVE; 903 DODEBUG(Status, printf("OIDLE watchdog\n");); 904 ifp->if_oerrors++; 905 ex_reset(sc); 906 ex_start(ifp); 907 908 DODEBUG(Start_End, printf("ex_watchdog: finish\n");); 909 } 910 911 int 912 ex_get_media(struct ex_softc *sc) 913 { 914 int current, media; 915 916 media = ex_eeprom_read(sc, EE_W5); 917 918 CSR_WRITE_1(sc, CMD_REG, Bank2_Sel); 919 current = CSR_READ_1(sc, REG3); 920 CSR_WRITE_1(sc, CMD_REG, Bank0_Sel); 921 922 if ((current & TPE_bit) && (media & EE_W5_PORT_TPE)) 923 return(IFM_ETHER|IFM_10_T); 924 if ((current & BNC_bit) && (media & EE_W5_PORT_BNC)) 925 return(IFM_ETHER|IFM_10_2); 926 927 if (media & EE_W5_PORT_AUI) 928 return (IFM_ETHER|IFM_10_5); 929 930 return (IFM_ETHER|IFM_AUTO); 931 } 932 933 int 934 ex_ifmedia_upd (struct ifnet *ifp) 935 { 936 struct ex_softc *sc = ifp->if_softc; 937 938 if (IFM_TYPE(sc->ifmedia.ifm_media) != IFM_ETHER) 939 return (EINVAL); 940 941 return (0); 942 } 943 944 void 945 ex_ifmedia_sts(struct ifnet *ifp, struct ifmediareq *ifmr) 946 { 947 struct ex_softc *sc = ifp->if_softc; 948 949 ifmr->ifm_status = IFM_AVALID | IFM_ACTIVE; 950 ifmr->ifm_active = ex_get_media(sc); 951 } 952 953 u_short 954 ex_eeprom_read(struct ex_softc *sc, int location) 955 { 956 int i; 957 u_short data = 0; 958 int read_cmd = location | EE_READ_CMD; 959 short ctrl_val = EECS; 960 961 CSR_WRITE_1(sc, CMD_REG, Bank2_Sel); 962 CSR_WRITE_1(sc, EEPROM_REG, EECS); 963 for (i = 8; i >= 0; i--) { 964 short outval = (read_cmd & (1 << i)) ? ctrl_val | EEDI : 965 ctrl_val; 966 CSR_WRITE_1(sc, EEPROM_REG, outval); 967 CSR_WRITE_1(sc, EEPROM_REG, outval | EESK); 968 delay(3); 969 CSR_WRITE_1(sc, EEPROM_REG, outval); 970 delay(2); 971 } 972 CSR_WRITE_1(sc, EEPROM_REG, ctrl_val); 973 for (i = 16; i > 0; i--) { 974 CSR_WRITE_1(sc, EEPROM_REG, ctrl_val | EESK); 975 delay(3); 976 data = (data << 1) | ((CSR_READ_1(sc, EEPROM_REG) & EEDO) ? 1 : 0); 977 CSR_WRITE_1(sc, EEPROM_REG, ctrl_val); 978 delay(2); 979 } 980 ctrl_val &= ~EECS; 981 CSR_WRITE_1(sc, EEPROM_REG, ctrl_val | EESK); 982 delay(3); 983 CSR_WRITE_1(sc, EEPROM_REG, ctrl_val); 984 delay(2); 985 CSR_WRITE_1(sc, CMD_REG, Bank0_Sel); 986 return(data); 987 } 988