1 /* $OpenBSD: if_ex.c,v 1.44 2016/04/13 10:49:26 mpi 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 #include <netinet/in.h> 52 #include <netinet/if_ether.h> 53 54 #if NBPFILTER > 0 55 #include <net/bpf.h> 56 #endif 57 58 #include <machine/cpu.h> 59 #include <machine/bus.h> 60 61 #include <dev/isa/isavar.h> 62 #include <dev/isa/if_exreg.h> 63 64 #ifdef EX_DEBUG 65 #define Start_End 1 66 #define Rcvd_Pkts 2 67 #define Sent_Pkts 4 68 #define Status 8 69 static int debug_mask = 0; 70 static int exintr_count = 0; 71 #define DODEBUG(level, action) if (level & debug_mask) action 72 #else 73 #define DODEBUG(level, action) 74 #endif 75 76 struct ex_softc { 77 struct arpcom arpcom; /* Ethernet common data */ 78 struct ifmedia ifmedia; 79 int iobase; /* I/O base address. */ 80 u_short irq_no; /* IRQ number. */ 81 u_int mem_size; /* Total memory size, in bytes. */ 82 u_int rx_mem_size; /* Rx memory size (by default, first 3/4 of 83 total memory). */ 84 u_int rx_lower_limit, 85 rx_upper_limit; /* Lower and upper limits of receive buffer. */ 86 u_int rx_head; /* Head of receive ring buffer. */ 87 u_int tx_mem_size; /* Tx memory size (by default, last quarter of 88 total memory). */ 89 u_int tx_lower_limit, 90 tx_upper_limit; /* Lower and upper limits of transmit buffer. */ 91 u_int tx_head, tx_tail; /* Head and tail of transmit ring buffer. */ 92 u_int tx_last; /* Pointer to beginning of last frame in the 93 chain. */ 94 bus_space_tag_t sc_iot; /* ISA i/o space tag */ 95 bus_space_handle_t sc_ioh; /* ISA i/o space handle */ 96 void *sc_ih; /* Device interrupt handler */ 97 }; 98 99 static char irq2eemap[] = { -1, -1, 0, 1, -1, 2, -1, -1, -1, 0, 3, 4, -1, -1, 100 -1, -1 }; 101 static u_char ee2irqmap[] = { 9, 3, 5, 10, 11, 0, 0, 0 }; 102 103 int ex_probe(struct device *, void *, void *); 104 void ex_attach(struct device *, struct device *, void *); 105 void ex_init(struct ex_softc *); 106 void ex_start(struct ifnet *); 107 void ex_stop(struct ex_softc *); 108 int ex_ioctl(struct ifnet *, u_long, caddr_t); 109 void ex_setmulti(struct ex_softc *); 110 void ex_reset(struct ex_softc *); 111 void ex_watchdog(struct ifnet *); 112 uint64_t ex_get_media(struct ex_softc *); 113 114 int ex_ifmedia_upd(struct ifnet *); 115 void ex_ifmedia_sts(struct ifnet *, struct ifmediareq *); 116 117 u_short ex_eeprom_read(struct ex_softc *, int); 118 int ex_look_for_card(struct isa_attach_args *, struct ex_softc *sc); 119 120 int ex_intr(void *); 121 void ex_tx_intr(struct ex_softc *); 122 void ex_rx_intr(struct ex_softc *); 123 124 struct cfattach ex_ca = { 125 sizeof(struct ex_softc), ex_probe, ex_attach 126 }; 127 128 struct cfdriver ex_cd = { 129 NULL, "ex", DV_IFNET 130 }; 131 132 #define CSR_READ_1(sc, off) \ 133 bus_space_read_1((sc)->sc_iot, (sc)->sc_ioh, (off)) 134 #define CSR_READ_2(sc, off) \ 135 bus_space_read_2((sc)->sc_iot, (sc)->sc_ioh, (off)) 136 #define CSR_READ_MULTI_2(sc, off, addr, count) \ 137 bus_space_read_multi_2((sc)->sc_iot, (sc)->sc_ioh, (off), \ 138 (u_int16_t *)(addr), (count)) 139 140 #define CSR_WRITE_1(sc, off, value) \ 141 bus_space_write_1((sc)->sc_iot, (sc)->sc_ioh, (off), (value)) 142 #define CSR_WRITE_2(sc, off, value) \ 143 bus_space_write_2((sc)->sc_iot, (sc)->sc_ioh, (off), (value)) 144 #define CSR_WRITE_MULTI_2(sc, off, addr, count) \ 145 bus_space_write_multi_2((sc)->sc_iot, (sc)->sc_ioh, (off), \ 146 (u_int16_t *)(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 256 ifmedia_init(&sc->ifmedia, 0, ex_ifmedia_upd, ex_ifmedia_sts); 257 258 temp = ex_eeprom_read(sc, EE_W5); 259 if (temp & EE_W5_PORT_TPE) 260 ifmedia_add(&sc->ifmedia, IFM_ETHER|IFM_10_T, 0, NULL); 261 if (temp & EE_W5_PORT_BNC) 262 ifmedia_add(&sc->ifmedia, IFM_ETHER|IFM_10_2, 0, NULL); 263 if (temp & EE_W5_PORT_AUI) 264 ifmedia_add(&sc->ifmedia, IFM_ETHER|IFM_10_5, 0, NULL); 265 266 ifmedia_add(&sc->ifmedia, IFM_ETHER|IFM_AUTO, 0, NULL); 267 ifmedia_add(&sc->ifmedia, IFM_ETHER|IFM_NONE, 0, NULL); 268 ifmedia_set(&sc->ifmedia, ex_get_media(sc)); 269 270 ifm = &sc->ifmedia; 271 ifm->ifm_media = ifm->ifm_cur->ifm_media; 272 ex_ifmedia_upd(ifp); 273 274 if_attach(ifp); 275 ether_ifattach(ifp); 276 printf(": address %s\n", 277 ether_sprintf(sc->arpcom.ac_enaddr)); 278 279 sc->sc_ih = isa_intr_establish(ia->ia_ic, ia->ia_irq, IST_EDGE, 280 IPL_NET, ex_intr, sc, self->dv_xname); 281 ex_init(sc); 282 283 DODEBUG(Start_End, printf("ex_attach: finish\n");); 284 } 285 286 void 287 ex_init(struct ex_softc *sc) 288 { 289 struct ifnet *ifp = &sc->arpcom.ac_if; 290 int s, i; 291 unsigned short temp_reg; 292 293 DODEBUG(Start_End, printf("ex_init: start\n");); 294 295 s = splnet(); 296 sc->arpcom.ac_if.if_timer = 0; 297 298 /* 299 * Load the ethernet address into the card. 300 */ 301 CSR_WRITE_1(sc, CMD_REG, Bank2_Sel); 302 temp_reg = CSR_READ_1(sc, EEPROM_REG); 303 if (temp_reg & Trnoff_Enable) 304 CSR_WRITE_1(sc, EEPROM_REG, temp_reg & ~Trnoff_Enable); 305 for (i = 0; i < ETHER_ADDR_LEN; i++) 306 CSR_WRITE_1(sc, I_ADDR_REG0 + i, sc->arpcom.ac_enaddr[i]); 307 /* 308 * - Setup transmit chaining and discard bad received frames. 309 * - Match broadcast. 310 * - Clear test mode. 311 * - Set receiving mode. 312 * - Set IRQ number. 313 */ 314 CSR_WRITE_1(sc, REG1, CSR_READ_1(sc, REG1) | Tx_Chn_Int_Md | 315 Tx_Chn_ErStp | Disc_Bad_Fr); 316 CSR_WRITE_1(sc, REG2, CSR_READ_1(sc, REG2) | No_SA_Ins | 317 RX_CRC_InMem); 318 CSR_WRITE_1(sc, REG3, (CSR_READ_1(sc, REG3) & 0x3f)); 319 CSR_WRITE_1(sc, CMD_REG, Bank1_Sel); 320 CSR_WRITE_1(sc, INT_NO_REG, (CSR_READ_1(sc, INT_NO_REG) & 0xf8) | 321 irq2eemap[sc->irq_no]); 322 323 /* 324 * Divide the available memory in the card into rcv and xmt buffers. 325 * By default, I use the first 3/4 of the memory for the rcv buffer, 326 * and the remaining 1/4 of the memory for the xmt buffer. 327 */ 328 sc->rx_mem_size = sc->mem_size * 3 / 4; 329 sc->tx_mem_size = sc->mem_size - sc->rx_mem_size; 330 sc->rx_lower_limit = 0x0000; 331 sc->rx_upper_limit = sc->rx_mem_size - 2; 332 sc->tx_lower_limit = sc->rx_mem_size; 333 sc->tx_upper_limit = sc->mem_size - 2; 334 CSR_WRITE_1(sc, RCV_LOWER_LIMIT_REG, sc->rx_lower_limit >> 8); 335 CSR_WRITE_1(sc, RCV_UPPER_LIMIT_REG, sc->rx_upper_limit >> 8); 336 CSR_WRITE_1(sc, XMT_LOWER_LIMIT_REG, sc->tx_lower_limit >> 8); 337 CSR_WRITE_1(sc, XMT_UPPER_LIMIT_REG, sc->tx_upper_limit >> 8); 338 339 /* 340 * Enable receive and transmit interrupts, and clear any pending int. 341 */ 342 CSR_WRITE_1(sc, REG1, CSR_READ_1(sc, REG1) | TriST_INT); 343 CSR_WRITE_1(sc, CMD_REG, Bank0_Sel); 344 CSR_WRITE_1(sc, MASK_REG, All_Int & ~(Rx_Int | Tx_Int)); 345 CSR_WRITE_1(sc, STATUS_REG, All_Int); 346 347 /* 348 * Initialize receive and transmit ring buffers. 349 */ 350 CSR_WRITE_2(sc, RCV_BAR, sc->rx_lower_limit); 351 sc->rx_head = sc->rx_lower_limit; 352 CSR_WRITE_2(sc, RCV_STOP_REG, sc->rx_upper_limit | 0xfe); 353 CSR_WRITE_2(sc, XMT_BAR, sc->tx_lower_limit); 354 sc->tx_head = sc->tx_tail = sc->tx_lower_limit; 355 356 ifp->if_flags |= IFF_RUNNING; 357 ifq_clr_oactive(&ifp->if_snd); 358 DODEBUG(Status, printf("OIDLE init\n");); 359 360 ex_setmulti(sc); 361 362 /* 363 * Final reset of the board, and enable operation. 364 */ 365 CSR_WRITE_1(sc, CMD_REG, Sel_Reset_CMD); 366 delay(2); 367 CSR_WRITE_1(sc, CMD_REG, Rcv_Enable_CMD); 368 369 ex_start(ifp); 370 splx(s); 371 372 DODEBUG(Start_End, printf("ex_init: finish\n");); 373 } 374 375 void 376 ex_start(struct ifnet *ifp) 377 { 378 struct ex_softc *sc = ifp->if_softc; 379 int i, len, data_len, avail, dest, next; 380 unsigned char tmp16[2]; 381 struct mbuf *opkt; 382 struct mbuf *m; 383 384 DODEBUG(Start_End, printf("ex_start: start\n");); 385 386 /* 387 * Main loop: send outgoing packets to network card until there are no 388 * more packets left, or the card cannot accept any more yet. 389 */ 390 while (!ifq_is_oactive(&ifp->if_snd)) { 391 opkt = ifq_deq_begin(&ifp->if_snd); 392 if (opkt == NULL) 393 break; 394 395 /* 396 * Ensure there is enough free transmit buffer space for this 397 * packet, including its header. Note: the header cannot wrap 398 * around the end of the transmit buffer and must be kept 399 * together, so we allow space for twice the length of the 400 * header, just in case. 401 */ 402 for (len = 0, m = opkt; m != NULL; m = m->m_next) 403 len += m->m_len; 404 data_len = len; 405 DODEBUG(Sent_Pkts, printf("1. Sending packet with %d data bytes. ", data_len);); 406 if (len & 1) 407 len += XMT_HEADER_LEN + 1; 408 else 409 len += XMT_HEADER_LEN; 410 if ((i = sc->tx_tail - sc->tx_head) >= 0) 411 avail = sc->tx_mem_size - i; 412 else 413 avail = -i; 414 DODEBUG(Sent_Pkts, printf("i=%d, avail=%d\n", i, avail);); 415 if (avail >= len + XMT_HEADER_LEN) { 416 ifq_deq_commit(&ifp->if_snd, opkt); 417 418 #ifdef EX_PSA_INTR 419 /* 420 * Disable rx and tx interrupts, to avoid corruption of 421 * the host address register by interrupt service 422 * routines. XXX Is this necessary with splnet() 423 * enabled? 424 */ 425 CSR_WRITE_2(sc, MASK_REG, All_Int); 426 #endif 427 428 /* 429 * Compute the start and end addresses of this frame 430 * in the tx buffer. 431 */ 432 dest = sc->tx_tail; 433 next = dest + len; 434 if (next > sc->tx_upper_limit) { 435 if ((sc->tx_upper_limit + 2 - sc->tx_tail) <= 436 XMT_HEADER_LEN) { 437 dest = sc->tx_lower_limit; 438 next = dest + len; 439 } else 440 next = sc->tx_lower_limit + next - 441 sc->tx_upper_limit - 2; 442 } 443 444 /* Build the packet frame in the card's ring buffer. */ 445 DODEBUG(Sent_Pkts, printf("2. dest=%d, next=%d. ", dest, next);); 446 CSR_WRITE_2(sc, HOST_ADDR_REG, dest); 447 CSR_WRITE_2(sc, IO_PORT_REG, Transmit_CMD); 448 CSR_WRITE_2(sc, IO_PORT_REG, 0); 449 CSR_WRITE_2(sc, IO_PORT_REG, next); 450 CSR_WRITE_2(sc, IO_PORT_REG, data_len); 451 452 /* 453 * Output the packet data to the card. Ensure all 454 * transfers are 16-bit wide, even if individual mbufs 455 * have odd length. 456 */ 457 458 for (m = opkt, i = 0; m != NULL; m = m->m_next) { 459 DODEBUG(Sent_Pkts, printf("[%d]", m->m_len);); 460 if (i) { 461 tmp16[1] = *(mtod(m, caddr_t)); 462 CSR_WRITE_MULTI_2(sc, IO_PORT_REG, tmp16, 1); 463 } 464 CSR_WRITE_MULTI_2(sc, IO_PORT_REG, mtod(m, caddr_t) 465 + i, (m->m_len - i) / 2); 466 if ((i = (m->m_len - i) & 1)) 467 tmp16[0] = *(mtod(m, caddr_t) + 468 m->m_len - 1); 469 } 470 if (i) 471 CSR_WRITE_MULTI_2(sc, IO_PORT_REG, tmp16, 1); 472 473 /* 474 * If there were other frames chained, update the 475 * chain in the last one. 476 */ 477 if (sc->tx_head != sc->tx_tail) { 478 if (sc->tx_tail != dest) { 479 CSR_WRITE_2(sc, HOST_ADDR_REG, 480 sc->tx_last + XMT_Chain_Point); 481 CSR_WRITE_2(sc, IO_PORT_REG, dest); 482 } 483 CSR_WRITE_2(sc, HOST_ADDR_REG, sc->tx_last + 484 XMT_Byte_Count); 485 i = CSR_READ_2(sc, IO_PORT_REG); 486 CSR_WRITE_2(sc, HOST_ADDR_REG, sc->tx_last + 487 XMT_Byte_Count); 488 CSR_WRITE_2(sc, IO_PORT_REG, i | Ch_bit); 489 } 490 491 /* 492 * Resume normal operation of the card: 493 * -Make a dummy read to flush the DRAM write pipeline. 494 * -Enable receive and transmit interrupts. 495 * -Send Transmit or Resume_XMT command, as appropriate. 496 */ 497 CSR_READ_2(sc, IO_PORT_REG); 498 #ifdef EX_PSA_INTR 499 CSR_WRITE_2(sc, MASK_REG, All_Int & ~(Rx_Int | Tx_Int)); 500 #endif 501 if (sc->tx_head == sc->tx_tail) { 502 CSR_WRITE_2(sc, XMT_BAR, dest); 503 CSR_WRITE_1(sc, CMD_REG, Transmit_CMD); 504 sc->tx_head = dest; 505 DODEBUG(Sent_Pkts, printf("Transmit\n");); 506 } else { 507 CSR_WRITE_1(sc, CMD_REG, Resume_XMT_List_CMD); 508 DODEBUG(Sent_Pkts, printf("Resume\n");); 509 } 510 sc->tx_last = dest; 511 sc->tx_tail = next; 512 #if NBPFILTER > 0 513 if (ifp->if_bpf != NULL) 514 bpf_mtap(ifp->if_bpf, opkt, 515 BPF_DIRECTION_OUT); 516 #endif 517 ifp->if_timer = 2; 518 ifp->if_opackets++; 519 m_freem(opkt); 520 } else { 521 ifq_deq_rollback(&ifp->if_snd, opkt); 522 ifq_set_oactive(&ifp->if_snd); 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 = 0; 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 } 587 } 588 589 /* 590 * If any packet has been transmitted, and there are queued packets to 591 * be sent, attempt to send more packets to the network card. 592 */ 593 594 if (send_pkts && IFQ_IS_EMPTY(&ifp->if_snd) == 0) 595 ex_start(ifp); 596 #ifdef EX_DEBUG 597 exintr_count--; 598 #endif 599 DODEBUG(Start_End, printf("exintr: finish\n");); 600 601 return handled; 602 } 603 604 void 605 ex_tx_intr(struct ex_softc *sc) 606 { 607 struct ifnet *ifp = &sc->arpcom.ac_if; 608 int tx_status; 609 610 DODEBUG(Start_End, printf("ex_tx_intr: start\n");); 611 /* 612 * - Cancel the watchdog. 613 * For all packets transmitted since last transmit interrupt: 614 * - Advance chain pointer to next queued packet. 615 * - Update statistics. 616 */ 617 ifp->if_timer = 0; 618 while (sc->tx_head != sc->tx_tail) { 619 CSR_WRITE_2(sc, HOST_ADDR_REG, sc->tx_head); 620 if (!CSR_READ_2(sc, IO_PORT_REG) & Done_bit) 621 break; 622 tx_status = CSR_READ_2(sc, IO_PORT_REG); 623 sc->tx_head = CSR_READ_2(sc, IO_PORT_REG); 624 if (tx_status & TX_OK_bit) 625 ifp->if_opackets++; 626 else 627 ifp->if_oerrors++; 628 ifp->if_collisions += tx_status & No_Collisions_bits; 629 } 630 631 /* The card should be ready to accept more packets now. */ 632 ifq_clr_oactive(&ifp->if_snd); 633 DODEBUG(Status, printf("OIDLE tx_intr\n");); 634 635 DODEBUG(Start_End, printf("ex_tx_intr: finish\n");); 636 } 637 638 void 639 ex_rx_intr(struct ex_softc *sc) 640 { 641 struct ifnet *ifp = &sc->arpcom.ac_if; 642 struct mbuf_list ml = MBUF_LIST_INITIALIZER(); 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.len = pkt_len; 666 ipkt->m_len = MHLEN; 667 while (pkt_len > 0) { 668 if (pkt_len >= MINCLSIZE) { 669 MCLGET(m, M_DONTWAIT); 670 if (m->m_flags & M_EXT) 671 m->m_len = MCLBYTES; 672 else { 673 m_freem(ipkt); 674 ifp->if_iqdrops++; 675 goto rx_another; 676 } 677 } 678 m->m_len = min(m->m_len, pkt_len); 679 /* 680 * NOTE: I'm assuming that all mbufs 681 * allocated are of even length, except 682 * for the last one in an odd-length 683 * packet. 684 */ 685 CSR_READ_MULTI_2(sc, IO_PORT_REG, 686 mtod(m, caddr_t), m->m_len / 2); 687 if (m->m_len & 1) 688 *(mtod(m, caddr_t) + 689 m->m_len - 1) = 690 CSR_READ_1(sc, IO_PORT_REG); 691 pkt_len -= m->m_len; 692 if (pkt_len > 0) { 693 MGET(m->m_next, M_DONTWAIT, 694 MT_DATA); 695 if (m->m_next == NULL) { 696 m_freem(ipkt); 697 ifp->if_iqdrops++; 698 goto rx_another; 699 } 700 m = m->m_next; 701 m->m_len = MLEN; 702 } 703 } 704 #ifdef EX_DEBUG 705 if (debug_mask & Rcvd_Pkts) { 706 if ((eh->ether_dhost[5] != 0xff) || 707 (eh->ether_dhost[0] != 0xff)) { 708 printf("Receive packet with %d data bytes: %6D -> ", QQQ, eh->ether_shost, ":"); 709 printf("%6D\n", eh->ether_dhost, ":"); 710 } /* QQQ */ 711 } 712 #endif 713 ml_enqueue(&ml, ipkt); 714 } 715 } else 716 ifp->if_ierrors++; 717 CSR_WRITE_2(sc, HOST_ADDR_REG, sc->rx_head); 718 rx_another: ; 719 } 720 if (sc->rx_head < sc->rx_lower_limit + 2) 721 CSR_WRITE_2(sc, RCV_STOP_REG, sc->rx_upper_limit); 722 else 723 CSR_WRITE_2(sc, RCV_STOP_REG, sc->rx_head - 2); 724 725 if_input(ifp, &ml); 726 727 DODEBUG(Start_End, printf("ex_rx_intr: finish\n");); 728 } 729 730 int 731 ex_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data) 732 { 733 struct ex_softc *sc = ifp->if_softc; 734 struct ifreq *ifr = (struct ifreq *) data; 735 int s, error = 0; 736 737 DODEBUG(Start_End, printf("ex_ioctl: start ");); 738 739 s = splnet(); 740 741 switch(cmd) { 742 case SIOCSIFADDR: 743 DODEBUG(Start_End, printf("SIOCSIFADDR");); 744 ifp->if_flags |= IFF_UP; 745 if (!(ifp->if_flags & IFF_RUNNING)) 746 ex_init(sc); 747 break; 748 case SIOCSIFFLAGS: 749 DODEBUG(Start_End, printf("SIOCSIFFLAGS");); 750 if ((ifp->if_flags & IFF_UP) == 0 && ifp->if_flags & IFF_RUNNING) { 751 ifp->if_flags &= ~IFF_RUNNING; 752 ex_stop(sc); 753 } else 754 ex_init(sc); 755 break; 756 case SIOCSIFMEDIA: 757 case SIOCGIFMEDIA: 758 error = ifmedia_ioctl(ifp, ifr, &sc->ifmedia, cmd); 759 break; 760 default: 761 error = ether_ioctl(ifp, &sc->arpcom, cmd, data); 762 } 763 764 if (error == ENETRESET) { 765 if (ifp->if_flags & IFF_RUNNING) 766 ex_init(sc); 767 error = 0; 768 } 769 770 splx(s); 771 DODEBUG(Start_End, printf("\nex_ioctl: finish\n");); 772 return(error); 773 } 774 775 void 776 ex_setmulti(struct ex_softc *sc) 777 { 778 struct arpcom *ac = &sc->arpcom; 779 struct ifnet *ifp = &sc->arpcom.ac_if; 780 struct ether_multi *enm; 781 struct ether_multistep step; 782 uint16_t *addr; 783 int count, timeout, status; 784 785 ifp->if_flags &= ~IFF_ALLMULTI; 786 787 count = 0; 788 ETHER_FIRST_MULTI(step, ac, enm); 789 while (enm != NULL) { 790 count++; 791 ETHER_NEXT_MULTI(step, enm); 792 } 793 794 if (count > 63 || ac->ac_multirangecnt > 0) 795 ifp->if_flags |= IFF_ALLMULTI; 796 797 if (ifp->if_flags & IFF_PROMISC || ifp->if_flags & IFF_ALLMULTI) { 798 /* 799 * Interface is in promiscuous mode, there are too many 800 * multicast addresses for the card to handle or there 801 * is a multicast range 802 */ 803 CSR_WRITE_1(sc, CMD_REG, Bank2_Sel); 804 CSR_WRITE_1(sc, REG2, CSR_READ_1(sc, REG2) | Promisc_Mode); 805 CSR_WRITE_1(sc, REG3, CSR_READ_1(sc, REG3)); 806 CSR_WRITE_1(sc, CMD_REG, Bank0_Sel); 807 } else if (ifp->if_flags & IFF_MULTICAST && count > 0) { 808 /* Program multicast addresses plus our MAC address 809 * into the filter */ 810 CSR_WRITE_1(sc, CMD_REG, Bank2_Sel); 811 CSR_WRITE_1(sc, REG2, CSR_READ_1(sc, REG2) | Multi_IA); 812 CSR_WRITE_1(sc, REG3, CSR_READ_1(sc, REG3)); 813 CSR_WRITE_1(sc, CMD_REG, Bank0_Sel); 814 815 /* Borrow space from TX buffer; this should be safe 816 * as this is only called from ex_init */ 817 818 CSR_WRITE_2(sc, HOST_ADDR_REG, sc->tx_lower_limit); 819 CSR_WRITE_2(sc, IO_PORT_REG, MC_Setup_CMD); 820 CSR_WRITE_2(sc, IO_PORT_REG, 0); 821 CSR_WRITE_2(sc, IO_PORT_REG, 0); 822 CSR_WRITE_2(sc, IO_PORT_REG, (count + 1) * 6); 823 824 ETHER_FIRST_MULTI(step, ac, enm); 825 while (enm != NULL) { 826 addr = (uint16_t*)enm->enm_addrlo; 827 CSR_WRITE_2(sc, IO_PORT_REG, *addr++); 828 CSR_WRITE_2(sc, IO_PORT_REG, *addr++); 829 CSR_WRITE_2(sc, IO_PORT_REG, *addr++); 830 ETHER_NEXT_MULTI(step, enm); 831 } 832 833 /* Program our MAC address as well */ 834 /* XXX: Is this necessary? The Linux driver does this 835 * but the NetBSD driver does not */ 836 addr = (uint16_t*) sc->arpcom.ac_enaddr; 837 CSR_WRITE_2(sc, IO_PORT_REG, *addr++); 838 CSR_WRITE_2(sc, IO_PORT_REG, *addr++); 839 CSR_WRITE_2(sc, IO_PORT_REG, *addr++); 840 841 CSR_READ_2(sc, IO_PORT_REG); 842 CSR_WRITE_2(sc, XMT_BAR, sc->tx_lower_limit); 843 CSR_WRITE_1(sc, CMD_REG, MC_Setup_CMD); 844 845 sc->tx_head = sc->tx_lower_limit; 846 sc->tx_tail = sc->tx_head + XMT_HEADER_LEN + (count + 1) * 6; 847 848 for (timeout = 0; timeout < 100; timeout++) { 849 DELAY(2); 850 if ((CSR_READ_1(sc, STATUS_REG) & Exec_Int) == 0) 851 continue; 852 853 status = CSR_READ_1(sc, CMD_REG); 854 CSR_WRITE_1(sc, STATUS_REG, Exec_Int); 855 break; 856 } 857 858 sc->tx_head = sc->tx_tail; 859 } else { 860 /* No multicast or promiscuous mode */ 861 CSR_WRITE_1(sc, CMD_REG, Bank2_Sel); 862 CSR_WRITE_1(sc, REG2, CSR_READ_1(sc, REG2) & 0xDE); 863 /* ~(Multi_IA | Promisc_Mode) */ 864 CSR_WRITE_1(sc, REG3, CSR_READ_1(sc, REG3)); 865 CSR_WRITE_1(sc, CMD_REG, Bank0_Sel); 866 } 867 } 868 869 void 870 ex_reset(struct ex_softc *sc) 871 { 872 int s; 873 874 DODEBUG(Start_End, printf("ex_reset: start\n");); 875 876 s = splnet(); 877 ex_stop(sc); 878 ex_init(sc); 879 splx(s); 880 881 DODEBUG(Start_End, printf("ex_reset: finish\n");); 882 } 883 884 void 885 ex_watchdog(struct ifnet *ifp) 886 { 887 struct ex_softc *sc = ifp->if_softc; 888 889 DODEBUG(Start_End, printf("ex_watchdog: start\n");); 890 891 ifq_clr_oactive(&ifp->if_snd); 892 DODEBUG(Status, printf("OIDLE watchdog\n");); 893 ifp->if_oerrors++; 894 ex_reset(sc); 895 ex_start(ifp); 896 897 DODEBUG(Start_End, printf("ex_watchdog: finish\n");); 898 } 899 900 uint64_t 901 ex_get_media(struct ex_softc *sc) 902 { 903 int current, media; 904 905 media = ex_eeprom_read(sc, EE_W5); 906 907 CSR_WRITE_1(sc, CMD_REG, Bank2_Sel); 908 current = CSR_READ_1(sc, REG3); 909 CSR_WRITE_1(sc, CMD_REG, Bank0_Sel); 910 911 if ((current & TPE_bit) && (media & EE_W5_PORT_TPE)) 912 return(IFM_ETHER|IFM_10_T); 913 if ((current & BNC_bit) && (media & EE_W5_PORT_BNC)) 914 return(IFM_ETHER|IFM_10_2); 915 916 if (media & EE_W5_PORT_AUI) 917 return (IFM_ETHER|IFM_10_5); 918 919 return (IFM_ETHER|IFM_AUTO); 920 } 921 922 int 923 ex_ifmedia_upd (struct ifnet *ifp) 924 { 925 struct ex_softc *sc = ifp->if_softc; 926 927 if (IFM_TYPE(sc->ifmedia.ifm_media) != IFM_ETHER) 928 return (EINVAL); 929 930 return (0); 931 } 932 933 void 934 ex_ifmedia_sts(struct ifnet *ifp, struct ifmediareq *ifmr) 935 { 936 struct ex_softc *sc = ifp->if_softc; 937 938 ifmr->ifm_status = IFM_AVALID | IFM_ACTIVE; 939 ifmr->ifm_active = ex_get_media(sc); 940 } 941 942 u_short 943 ex_eeprom_read(struct ex_softc *sc, int location) 944 { 945 int i; 946 u_short data = 0; 947 int read_cmd = location | EE_READ_CMD; 948 short ctrl_val = EECS; 949 950 CSR_WRITE_1(sc, CMD_REG, Bank2_Sel); 951 CSR_WRITE_1(sc, EEPROM_REG, EECS); 952 for (i = 8; i >= 0; i--) { 953 short outval = (read_cmd & (1 << i)) ? ctrl_val | EEDI : 954 ctrl_val; 955 CSR_WRITE_1(sc, EEPROM_REG, outval); 956 CSR_WRITE_1(sc, EEPROM_REG, outval | EESK); 957 delay(3); 958 CSR_WRITE_1(sc, EEPROM_REG, outval); 959 delay(2); 960 } 961 CSR_WRITE_1(sc, EEPROM_REG, ctrl_val); 962 for (i = 16; i > 0; i--) { 963 CSR_WRITE_1(sc, EEPROM_REG, ctrl_val | EESK); 964 delay(3); 965 data = (data << 1) | ((CSR_READ_1(sc, EEPROM_REG) & EEDO) ? 1 : 0); 966 CSR_WRITE_1(sc, EEPROM_REG, ctrl_val); 967 delay(2); 968 } 969 ctrl_val &= ~EECS; 970 CSR_WRITE_1(sc, EEPROM_REG, ctrl_val | EESK); 971 delay(3); 972 CSR_WRITE_1(sc, EEPROM_REG, ctrl_val); 973 delay(2); 974 CSR_WRITE_1(sc, CMD_REG, Bank0_Sel); 975 return(data); 976 } 977