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