cvs commit: src/sys/dev/vr if_vr.c if_vrreg.h

Pyun YongHyeon yongari at
Tue Mar 11 04:51:23 UTC 2008

yongari     2008-03-11 04:51:22 UTC

  FreeBSD src repository

  Modified files:
    sys/dev/vr           if_vr.c if_vrreg.h 
  Teach vr(4) to use bus_dma(9) and major overhauling to handle link
  state change and reliable error recovery.
   o Moved vr_softc structure and relevant macros to header file.
   o Use PCIR_BAR macro to get BARs.
   o Implemented suspend/resume methods.
   o Implemented automatic Tx threshold configuration which will be
     activated when it suffers from Tx underrun. Also Tx underrun
     will try to restart only Tx path and resort to previous
     full-reset(both Rx/Tx) operation if restarting Tx path have failed.
   o Removed old bit-banging MII interface. Rhine provides simple and
     efficient MII interface. While I'm here show PHY address and PHY
     register number when its read/write operation was failed.
   o Define VR_MII_TIMEOUT constant and use it in MII access routines.
   o Always honor link up/down state reported by mii layers. The link
     state information is used in vr_start() to determine whether we
     got a valid link.
   o Removed vr_setcfg() which is now handled in vr_link_task(), link
     state taskqueue handler. When mii layer reports link state changes
     the taskqueue handler reprograms MAC to reflect negotiated duplex
     settings. Flow-control changes are not handled yet and it should
     be revisited when mii layer knows the notion of flow-control.
   o Added a new sysctl interface to get statistics of an instance of
     the driver.(sysctl dev.vr.0.stats=1)
   o Chip name was renamed to reflect the official name of the chips
     described in VIA Rhine I/II/III datasheet.
          REV_ID_3065_A -> REV_ID_VT6102_A
          REV_ID_3065_B -> REV_ID_VT6102_B
          REV_ID_3065_C -> REV_ID_VT6102_C
          REV_ID_3106_J -> REV_ID_VT6105_A0
          REV_ID_3106_S -> REV_ID_VT6105M_A0
     The following chip revisions were added.
          #define REV_ID_VT6105_B0        0x83
          #define REV_ID_VT6105_LOM       0x8A
          #define REV_ID_VT6107_A0        0x8C
          #define REV_ID_VT6107_A1        0x8D
          #define REV_ID_VT6105M_B1       0x94
   o Always show chip revision number in device attach. This shall help
     identifying revision specific issues.
   o Check whether EEPROM reloading is complete by inspecting the state
     of VR_EECSR_LOAD bit. This bit is self-cleared after the EEPROM
     reloading. Previously vr(4) blindly spins for 200us which may/may
     not enough to complete the EEPROM reload.
   o Removed if_mtu setup. It's done in ether_ifattach().
   o Use our own callout to drive watchdog timer.
   o In vr_attach disable further interrupts after reset. For VT6102 or
     newer hardwares, diable MII state change interrupt as well because
     mii state handling is done by mii layer.
   o Add more sane register initialization for VT6102 or newer chips.
      - Have NIC report error instead of retrying forever.
      - Let hardware detect MII coding error.
      - Enable MODE10T mode.
      - Enable memory-read-multiple for VT6107.
   o PHY address for VT6105 or newer chips is located at fixed address 1.
     For older chips the PHY address is stored in VR_PHYADDR register.
     Armed with these information, there is no need to re-read
     VR_PHYADDR register in miibus handler to get PHY address. This
     saves one register access cycle for each MII access.
   o Don't reprogram VR_PHYADDR register whenever access to a register
     located at a PHY address is made. Rhine fmaily allows reprogramming
     PHY address location via VR_PHYADDR register depending on
     VR_MIISTAT_PHYOPT bit of VR_MIISTAT register. This used to lead
     numerous phantom PHYs attached to miibus during phy probe phase and
     driver used to limit allowable PHY address in mii register accessors
     for certain chip revisions. This removes one more register access
     cycle for each MII access.
   o Correctly set VLAN header length.
   o bus_dma(9) conversion.
      - Limit DMA access to be in range of 32bit address space. Hardware
        doesn't support DAC.
      - Apply descriptor ring alignment requirements(16 bytes alignment)
      - Apply Rx buffer address alignment requirements(4 bytes alignment)
      - Apply Tx buffer address alignment requirements(4 bytes alignment)
        for Rhine I chip. Rhine II or III has no Tx buffer address
        alignment restrictions, though.
      - Reduce number of allowable number of DMA segments to 8.
      - Removed the atomic(9) used in descriptor ownership managements
        as it's job of bus_dmamap_sync(9).
      With these change vr(4) should work on all platforms.
   o Rhine uses two separated 8bits command registers to control Tx/Rx
     MAC. So don't access it as a single 16bit register.
   o For non-strict alignment architectures vr(4) no longer require
     time-consuming copy operation for received frames to align IP
     header. This greatly improves Rx performance on i386/amd64
     platforms. However the alignment is still necessary for
     strict-alignment platforms(e.g. sparc64). The alignment is handled
     in new fuction vr_fixup_rx().
   o vr_rxeof() now rejects multiple-segmented(fragmented) frames as
     vr(4) is not ready to handle this situation. Datasheet said nothing
     about the reason when/why it happens.
   o In vr_newbuf() don't set VR_RXSTAT_FIRSTFRAG/VR_RXSTAT_LASTFRAG
     bits as it's set by hardware.
   o Don't pass checksum offload information to upper layer for
     fragmented frames. The hardware assisted checksum is valid only
     when the frame is non-fragmented IP frames. Also mark the checksum
     is valid for corrupted frames such that upper layers doesn't need
     to recompute the checksum with software routine.
   o Removed vr_rxeoc(). RxDMA doesn't seem to need to be idle before
     sending VR_CMD_RX_GO command. Previously it used to stop RxDMA
     first which in turn resulted in long delays in Rx error recovery.
   o Rewrote Tx completion handler.
      - Always check VR_TXSTAT_OWN bit in status word prior to
        inspecting other status bits in the status word.
      - Collision counter updates were corrected as VT3071 or newer
        ones use different bits to notify collisions.
      - Unlike other chip revisions, VT86C100A uses different bit to
        indicate Tx underrun. For VT3071 or newer ones, check both
        VR_TXSTAT_TBUFF and VR_TXSTAT_UDF bits to see whether Tx
        underrun was happend. In case of Tx underrun requeue the failed
        frame and restart stalled Tx SM. Also double Tx DMA threshold
        size on each failure to mitigate future Tx underruns.
      - Disarm watchdog timer only if we have no queued packets,
        otherwise don't touch watchdog timer.
   o Rewrote interrupt handler.
      - status word in Tx/Rx descriptors indicates more detailed error
        state required to recover from the specific error. There is no
        need to rely on interrupt status word to recover from Tx/Rx
        error except PCI bus error. Other event notifications like
        statistics counter overflows or link state events will be
        handled in main interrupt handler.
      - Don't touch VR_IMR register if we are in suspend mode. Touching
        the register may hang the hardware if we are in suspended state.
        Previously it seems that touching VR_IMR register in interrupt
        handler was to work-around panic occurred in system shutdown
        stage on SMP systems. I think that work-around would hide
        root-cause of the panic and I couldn't reproduce the panic
        with multiple attempts on my box.
   o While padding space to meet minimum frame size, zero the pad data
     in order to avoid possibly leaking sensitive data.
   o Rewrote vr_start_locked().
      - Don't try to queue packets if number of available Tx descriptors
        are short than that of required one.
   o Don't reinitialize hardware whenever media configuration is
     changed. Media/link state changes are reported from mii layer if
     this happens and vr_link_task() will perform necessary changes.
   o Don't reinitialize hardware if only PROMISC bit was changed. Just
     toggle the PROMISC bit in hardware is sufficient to reflect the
   o Rearrganed the IFCAP_POLLING/IFCAP_HWCSUM handling in vr_ioctl().
   o Generate Tx completion interrupts for every VR_TX_INTR_THRESH-th
     frames. This reduces Tx completion interrupts under heavy network
   o Since vr(4) doesn't request Tx interrupts for every queued frames,
     reclaim any pending descriptors not handled in Tx completion
     handler before actually firing up watchdog timeouts.
   o Added vr_tx_stop()/vr_rx_stop() to wait for the end of active
     TxDMA/RxDMA cycles(draining). These routines are used in vr_stop()
     to ensure sane state of MAC before releasing allocated Tx/Rx
     buffers. vr_link_task() also takes advantage of these functions to
     get to idle state prior to restarting Tx/Rx.
   o Added vr_tx_start()/vr_rx_start() to restart Rx/Tx. By separating
     Rx operation from Tx operation vr(4) no longer need to full-reset
     the hardware in case of Tx/Rx error recovery.
   o Implemented WOL.
   o Added VT6105M specific register definitions. VT6105M has the
     following hardware capabilities.
      - Tx/Rx IP/TCP/UDP checksum offload.
      - VLAN hardware tag insertion/extraction. Due to lack of information
         for getting extracted VLAN tag in Rx path, VLAN hardware support
         was not implemented yet.
      - CAM(Content Addressable Memory) based 32 entry perfect multicast/
        VLAN filtering.
      - 8 priority queues.
   o Implemented CAM based 32 entry perfect multicast filtering for
     VT6105M. If number of multicast entry is greater than 32, vr(4)
     uses traditional hash based filtering.
   o Reflect real Tx/Rx descriptor structure. Previously vr(4) used to
     embed other driver (private) data into these structure. This type
     of embedding make it hard to work on LP64 systems.
   o Removed unused vr_mii_frame structure and MII bit-baning
   o Added new PCI configuration registers that controls mii operation
     and mode selection.
   o Reduced number of Tx/Rx descriptors to 128 from 256. From my
     testing, increasing number of descriptors above than 64 didn't help
     increasing performance at all. Experimentations show 128 Rx
     descriptors seems to help a lot reducing Rx FIFO overruns under
     high system loads. It seems the poor Tx performance of Rhine
     hardwares comes from the limitation of hardware. You wouldn't
     satuarte the link with vr(4) no matter how fast CPU/large number of
     descriptors are used.
   o Added vr_statistics structure to hold various counter values.
  No regression was reported but one variant of Rhine III(VT6105M)
  found on RouterBOARD 44 does not work yet(Reported by Milan Obuch).
  I hope this would be resolved in near future.
  I'd like to say big thanks to Mike Tancsa who kindly donated a Rhine
  hardware to me. Without his enthusiastic testing and feedbacks
  overhauling vr(4) never have been possible. Also thanks to Masayuki
  Murayama who provided some good comments on the hardware's internals.
  This driver is result of combined effort of many users who provided
  many feedbacks so I'd like to say special thanks to them.
  Hardware donated by:    Mike Tancsa (mike AT sentex dot net)
  Reviewed by:            remko (initial version)
  Tested by:              Mike Tancsa(x86), JoaoBR ( joao AT matik DOT com DOT br )
                          Marcin Wisnicki ( mwisnicki+freebsd AT gmail DOT com )
                          Stefan Ehmann ( shoesoft AT gmx DOT net )
                          Florian Smeets ( flo AT kasimir DOT com )
                          Phil Oleson ( oz AT nixil DOT net )
                          Larry Baird ( lab AT gta DOT com )
                          Milan Obuch ( freebsd-current AT dino DOT sk )
                          remko (initial version)
  Revision  Changes     Path
  1.130     +1699 -714  src/sys/dev/vr/if_vr.c
  1.36      +330 -98    src/sys/dev/vr/if_vrreg.h

More information about the cvs-src mailing list