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