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