Deleted Added
full compact
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 ---