if_vr.c (180551) | if_vr.c (180552) |
---|---|
1/*- 2 * Copyright (c) 1997, 1998 3 * Bill Paul <wpaul@ctr.columbia.edu>. 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 --- 17 unchanged lines hidden (view full) --- 26 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 27 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 28 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 29 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 30 * THE POSSIBILITY OF SUCH DAMAGE. 31 */ 32 33#include <sys/cdefs.h> | 1/*- 2 * Copyright (c) 1997, 1998 3 * Bill Paul <wpaul@ctr.columbia.edu>. 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 --- 17 unchanged lines hidden (view full) --- 26 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 27 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 28 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 29 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 30 * THE POSSIBILITY OF SUCH DAMAGE. 31 */ 32 33#include <sys/cdefs.h> |
34__FBSDID("$FreeBSD: head/sys/dev/vr/if_vr.c 180551 2008-07-16 08:02:23Z yongari $"); | 34__FBSDID("$FreeBSD: head/sys/dev/vr/if_vr.c 180552 2008-07-16 08:35:29Z yongari $"); |
35 36/* 37 * VIA Rhine fast ethernet PCI NIC driver 38 * 39 * Supports various network adapters based on the VIA Rhine 40 * and Rhine II PCI controllers, including the D-Link DFE530TX. 41 * Datasheets are available at http://www.via.com.tw. 42 * --- 138 unchanged lines hidden (view full) --- 181static int vr_ifmedia_upd(struct ifnet *); 182static void vr_ifmedia_sts(struct ifnet *, struct ifmediareq *); 183 184static int vr_miibus_readreg(device_t, int, int); 185static int vr_miibus_writereg(device_t, int, int, int); 186static void vr_miibus_statchg(device_t); 187 188static void vr_link_task(void *, int); | 35 36/* 37 * VIA Rhine fast ethernet PCI NIC driver 38 * 39 * Supports various network adapters based on the VIA Rhine 40 * and Rhine II PCI controllers, including the D-Link DFE530TX. 41 * Datasheets are available at http://www.via.com.tw. 42 * --- 138 unchanged lines hidden (view full) --- 181static int vr_ifmedia_upd(struct ifnet *); 182static void vr_ifmedia_sts(struct ifnet *, struct ifmediareq *); 183 184static int vr_miibus_readreg(device_t, int, int); 185static int vr_miibus_writereg(device_t, int, int, int); 186static void vr_miibus_statchg(device_t); 187 188static void vr_link_task(void *, int); |
189static int vr_setperf(struct vr_softc *, int, uint8_t *); | 189static void vr_cam_mask(struct vr_softc *, uint32_t, int); 190static int vr_cam_data(struct vr_softc *, int, int, uint8_t *); |
190static void vr_set_filter(struct vr_softc *); 191static void vr_reset(const struct vr_softc *); 192static int vr_tx_ring_init(struct vr_softc *); 193static int vr_rx_ring_init(struct vr_softc *); 194static void vr_setwol(struct vr_softc *); 195static void vr_clrwol(struct vr_softc *); 196static int vr_sysctl_stats(SYSCTL_HANDLER_ARGS); 197 --- 191 unchanged lines hidden (view full) --- 389 sc->vr_flags |= VR_F_RESTART; 390 VR_UNLOCK(sc); 391 return; 392 } 393 } 394 VR_UNLOCK(sc); 395} 396 | 191static void vr_set_filter(struct vr_softc *); 192static void vr_reset(const struct vr_softc *); 193static int vr_tx_ring_init(struct vr_softc *); 194static int vr_rx_ring_init(struct vr_softc *); 195static void vr_setwol(struct vr_softc *); 196static void vr_clrwol(struct vr_softc *); 197static int vr_sysctl_stats(SYSCTL_HANDLER_ARGS); 198 --- 191 unchanged lines hidden (view full) --- 390 sc->vr_flags |= VR_F_RESTART; 391 VR_UNLOCK(sc); 392 return; 393 } 394 } 395 VR_UNLOCK(sc); 396} 397 |
397/* 398 * Copy the address 'mac' into the perfect RX filter entry at 399 * offset 'idx.' The perfect filter only has 32 entries so do 400 * some sanity tests. 401 */ | 398 399static void 400vr_cam_mask(struct vr_softc *sc, uint32_t mask, int type) 401{ 402 403 if (type == VR_MCAST_CAM) 404 CSR_WRITE_1(sc, VR_CAMCTL, VR_CAMCTL_ENA | VR_CAMCTL_MCAST); 405 else 406 CSR_WRITE_1(sc, VR_CAMCTL, VR_CAMCTL_ENA | VR_CAMCTL_VLAN); 407 CSR_WRITE_4(sc, VR_CAMMASK, mask); 408 CSR_WRITE_1(sc, VR_CAMCTL, 0); 409} 410 |
402static int | 411static int |
403vr_setperf(struct vr_softc *sc, int idx, uint8_t *mac) | 412vr_cam_data(struct vr_softc *sc, int type, int idx, uint8_t *mac) |
404{ 405 int i; 406 | 413{ 414 int i; 415 |
407 if (idx < 0 || idx >= VR_CAM_MCAST_CNT || mac == NULL) 408 return (EINVAL); | 416 if (type == VR_MCAST_CAM) { 417 if (idx < 0 || idx >= VR_CAM_MCAST_CNT || mac == NULL) 418 return (EINVAL); 419 CSR_WRITE_1(sc, VR_CAMCTL, VR_CAMCTL_ENA | VR_CAMCTL_MCAST); 420 } else 421 CSR_WRITE_1(sc, VR_CAMCTL, VR_CAMCTL_ENA | VR_CAMCTL_VLAN); |
409 410 /* Set CAM entry address. */ 411 CSR_WRITE_1(sc, VR_CAMADDR, idx); 412 /* Set CAM entry data. */ | 422 423 /* Set CAM entry address. */ 424 CSR_WRITE_1(sc, VR_CAMADDR, idx); 425 /* Set CAM entry data. */ |
413 for (i = 0; i < ETHER_ADDR_LEN; i++) 414 CSR_WRITE_1(sc, VR_MAR0 + i, mac[i]); | 426 if (type == VR_MCAST_CAM) { 427 for (i = 0; i < ETHER_ADDR_LEN; i++) 428 CSR_WRITE_1(sc, VR_MCAM0 + i, mac[i]); 429 } else { 430 CSR_WRITE_1(sc, VR_VCAM0, mac[0]); 431 CSR_WRITE_1(sc, VR_VCAM1, mac[1]); 432 } 433 DELAY(10); |
415 /* Write CAM and wait for self-clear of VR_CAMCTL_WRITE bit. */ | 434 /* Write CAM and wait for self-clear of VR_CAMCTL_WRITE bit. */ |
416 CSR_WRITE_1(sc, VR_CAMCTL, 417 VR_CAMCTL_ENA | VR_CAMCTL_MCAST | VR_CAMCTL_WRITE); | 435 CSR_WRITE_1(sc, VR_CAMCTL, VR_CAMCTL_ENA | VR_CAMCTL_WRITE); |
418 for (i = 0; i < VR_TIMEOUT; i++) { 419 DELAY(1); 420 if ((CSR_READ_1(sc, VR_CAMCTL) & VR_CAMCTL_WRITE) == 0) 421 break; 422 } 423 424 if (i == VR_TIMEOUT) 425 device_printf(sc->vr_dev, "%s: setting CAM filter timeout!\n", 426 __func__); | 436 for (i = 0; i < VR_TIMEOUT; i++) { 437 DELAY(1); 438 if ((CSR_READ_1(sc, VR_CAMCTL) & VR_CAMCTL_WRITE) == 0) 439 break; 440 } 441 442 if (i == VR_TIMEOUT) 443 device_printf(sc->vr_dev, "%s: setting CAM filter timeout!\n", 444 __func__); |
445 CSR_WRITE_1(sc, VR_CAMCTL, 0); |
|
427 428 return (i == VR_TIMEOUT ? ETIMEDOUT : 0); 429} 430 431/* 432 * Program the 64-bit multicast hash filter. 433 */ 434static void --- 21 unchanged lines hidden (view full) --- 456 CSR_WRITE_1(sc, VR_RXCFG, rxfilt); 457 CSR_WRITE_4(sc, VR_MAR0, 0xFFFFFFFF); 458 CSR_WRITE_4(sc, VR_MAR1, 0xFFFFFFFF); 459 return; 460 } 461 462 /* Now program new ones. */ 463 error = 0; | 446 447 return (i == VR_TIMEOUT ? ETIMEDOUT : 0); 448} 449 450/* 451 * Program the 64-bit multicast hash filter. 452 */ 453static void --- 21 unchanged lines hidden (view full) --- 475 CSR_WRITE_1(sc, VR_RXCFG, rxfilt); 476 CSR_WRITE_4(sc, VR_MAR0, 0xFFFFFFFF); 477 CSR_WRITE_4(sc, VR_MAR1, 0xFFFFFFFF); 478 return; 479 } 480 481 /* Now program new ones. */ 482 error = 0; |
483 mcnt = 0; |
|
464 IF_ADDR_LOCK(ifp); 465 if ((sc->vr_quirks & VR_Q_CAM) != 0) { 466 /* 467 * For hardwares that have CAM capability, use 468 * 32 entries multicast perfect filter. 469 */ 470 cam_mask = 0; | 484 IF_ADDR_LOCK(ifp); 485 if ((sc->vr_quirks & VR_Q_CAM) != 0) { 486 /* 487 * For hardwares that have CAM capability, use 488 * 32 entries multicast perfect filter. 489 */ 490 cam_mask = 0; |
471 mcnt = 0; 472 CSR_WRITE_1(sc, VR_CAMCTL, VR_CAMCTL_ENA | VR_CAMCTL_MCAST); | |
473 TAILQ_FOREACH(ifma, &ifp->if_multiaddrs, ifma_link) { 474 if (ifma->ifma_addr->sa_family != AF_LINK) 475 continue; | 491 TAILQ_FOREACH(ifma, &ifp->if_multiaddrs, ifma_link) { 492 if (ifma->ifma_addr->sa_family != AF_LINK) 493 continue; |
476 error = vr_setperf(sc, mcnt, | 494 error = vr_cam_data(sc, VR_MCAST_CAM, mcnt, |
477 LLADDR((struct sockaddr_dl *)ifma->ifma_addr)); 478 if (error != 0) { 479 cam_mask = 0; 480 break; 481 } 482 cam_mask |= 1 << mcnt; 483 mcnt++; 484 } | 495 LLADDR((struct sockaddr_dl *)ifma->ifma_addr)); 496 if (error != 0) { 497 cam_mask = 0; 498 break; 499 } 500 cam_mask |= 1 << mcnt; 501 mcnt++; 502 } |
485 /* Enable multicast CAM entries depending on mask. */ 486 CSR_WRITE_1(sc, VR_CAMMASK, cam_mask); 487 /* Accessing CAM done. */ 488 CSR_WRITE_1(sc, VR_CAMCTL, 0); | 503 vr_cam_mask(sc, VR_MCAST_CAM, cam_mask); |
489 } 490 | 504 } 505 |
491 mcnt = 0; | |
492 if ((sc->vr_quirks & VR_Q_CAM) == 0 || error != 0) { 493 /* 494 * If there are too many multicast addresses or 495 * setting multicast CAM filter failed, use hash 496 * table based filtering. 497 */ | 506 if ((sc->vr_quirks & VR_Q_CAM) == 0 || error != 0) { 507 /* 508 * If there are too many multicast addresses or 509 * setting multicast CAM filter failed, use hash 510 * table based filtering. 511 */ |
512 mcnt = 0; |
|
498 TAILQ_FOREACH(ifma, &ifp->if_multiaddrs, ifma_link) { 499 if (ifma->ifma_addr->sa_family != AF_LINK) 500 continue; 501 h = ether_crc32_be(LLADDR((struct sockaddr_dl *) 502 ifma->ifma_addr), ETHER_ADDR_LEN) >> 26; 503 if (h < 32) 504 hashes[0] |= (1 << h); 505 else --- 1520 unchanged lines hidden (view full) --- 2026 "initialization failed: no memory for rx buffers\n"); 2027 vr_stop(sc); 2028 return; 2029 } 2030 2031 /* Init tx descriptors. */ 2032 vr_tx_ring_init(sc); 2033 | 513 TAILQ_FOREACH(ifma, &ifp->if_multiaddrs, ifma_link) { 514 if (ifma->ifma_addr->sa_family != AF_LINK) 515 continue; 516 h = ether_crc32_be(LLADDR((struct sockaddr_dl *) 517 ifma->ifma_addr), ETHER_ADDR_LEN) >> 26; 518 if (h < 32) 519 hashes[0] |= (1 << h); 520 else --- 1520 unchanged lines hidden (view full) --- 2041 "initialization failed: no memory for rx buffers\n"); 2042 vr_stop(sc); 2043 return; 2044 } 2045 2046 /* Init tx descriptors. */ 2047 vr_tx_ring_init(sc); 2048 |
2034 /* Disable all VLAN CAM entries. */ | |
2035 if ((sc->vr_quirks & VR_Q_CAM) != 0) { | 2049 if ((sc->vr_quirks & VR_Q_CAM) != 0) { |
2036 CSR_WRITE_1(sc, VR_CAMCTL, VR_CAMCTL_ENA | VR_CAMCTL_VLAN); 2037 CSR_WRITE_1(sc, VR_CAMMASK, 0); 2038 CSR_WRITE_1(sc, VR_CAMCTL, 0); | 2050 uint8_t vcam[2] = { 0, 0 }; 2051 2052 /* Disable VLAN hardware tag insertion/stripping. */ 2053 VR_CLRBIT(sc, VR_TXCFG, VR_TXCFG_TXTAGEN | VR_TXCFG_RXTAGCTL); 2054 /* Disable VLAN hardware filtering. */ 2055 VR_CLRBIT(sc, VR_BCR1, VR_BCR1_VLANFILT_ENB); 2056 /* Disable all CAM entries. */ 2057 vr_cam_mask(sc, VR_MCAST_CAM, 0); 2058 vr_cam_mask(sc, VR_VLAN_CAM, 0); 2059 /* Enable the first VLAN CAM. */ 2060 vr_cam_data(sc, VR_VLAN_CAM, 0, vcam); 2061 vr_cam_mask(sc, VR_VLAN_CAM, 1); |
2039 } 2040 2041 /* 2042 * Set up receive filter. 2043 */ 2044 vr_set_filter(sc); 2045 2046 /* --- 544 unchanged lines hidden --- | 2062 } 2063 2064 /* 2065 * Set up receive filter. 2066 */ 2067 vr_set_filter(sc); 2068 2069 /* --- 544 unchanged lines hidden --- |