1
0
mirror of https://git.FreeBSD.org/src.git synced 2024-12-23 11:18:54 +00:00
freebsd/sys/dev/nge/if_ngereg.h
Pyun YongHyeon f6bc943047 bus_dma(9) conversion and make nge(4) work on all architectures.
o Header file cleanup.
o bus_dma(9) conversion.
  - Removed all consumers of vtophys(9) and converted to use
    bus_dma(9).
  - 64bit DMA support was disabled because DP83821 is not capable
    of handling the DMA request. 64bit DMA request on DP83820
    requires different descriptor structures and it's hard to
    dynamically change descriptor format at run time so I disabled
    it. Note, this is the same behavior as previous one but
    previously nge(4) didn't explicitly disable 64bit mode on
    DP83820.
  - Added Tx/Rx descriptor ring alignment requirements(8 bytes
    alignment).
  - Limit maximum number of Tx DMA segments to 16. In fact,
    controller does not seem to have limitations on number of Tx
    DMA segments but 16 should be enough for most cases and
    m_collapse(9) will handle highly fragmented frames without
    consuming a lot of CPU cycles.
  - Added Rx buffer alignment requirements(8 bytes alignment). This
    means driver should fixup received frames to align on 16bits
    boundary on strict-alignment architectures.
  - Nuked driver private data structure in descriptor ring.
  - Added endianness support code in Tx/Rx descriptor access.
o Prefer faster memory mapped register access to I/O mapped access.
   Added fall-back mechanism to use alternative register access.
   The hardware supports both memory and I/O mapped access.
o Added suspend/resume methods but it wasn't tested as controller I
  have does not support PCI PME.
o Removed swap argument in nge_read_eeprom() since endianness
  should be handled after reading EEPROM.
o Implemented experimental 802.3x full-duplex flow-control. ATM
  it was commented out but will be activated after we have generic
  flow-control framework in mii(4) layer.
o Rearranged promiscuous mode settings and simplified logic.
o Always disable Rx filter prior to changing Rx filter functions as
  indicated in DP83820/DP83821 datasheet.
o Added an explicit DELAY in timeout loop of nge_reset().
o Added a sysctl variable dev.nge.%d.int_holdoff to control
  interrupt moderation. Valid ranges are 1 to 255(default 1) in
  units of 100us. The actual delivery of interrupt would be delayed
  based on the sysctl value. The interface has to be brought down
  and up again before a change takes effect. With proper tuning
  value, users do not need to resort to polling(4) anymore.
o Added ALTQ(4) support.
o Added missing IFCAP_VLAN_HWCSUM as nge(4) can offload Tx/Rx
  checksum calculation on VLAN tagged frames as well as VLAN tag
  insertion/stripping. Also add IFCAP_VLAN_MTU capability as nge(4)
  can handle VLAN tagged oversized frames.
o Fixed media header length for VLAN.
o Rearranged nge_detach routine such that it's now used for general
  clean-up routine.
o Enabled MWI.
o Accessing EEPROM takes very long time so read 6 bytes ethernet
  address with one call instead of 3 separate accesses.
o Don't set if_mtu in device attach, it's already set in
  ether_ifattach().
o Don't do any special things for TBI interface. Remove TBI
  specific media handling in the driver and have gentbi(4) handle
  it. Add glue code to read/write TBI PHY registers in miibus
  method. This change removes a lot of PHY handling code in driver
  and now its functionality is handled by mii(4).
o Alignment fixup code is now applied only for strict-alignment
  architectures. Previously the code was applied for all
  architectures except i386. With this change amd64 will get
  instant Rx performance boost.
o When driver fails to allocate a new mbuf, update if_qdrops so
  users can see what was wrong in Rx path.
o Added a workaround for a hardware bug which resulted in short
  VLAN tagged frames(e.g. ARP) was rejected as if runt frame was
  received. With this workaround nge(4) now accepts the short VLAN
  tagged frame and nge(4) can take full advantage of hardware VLAN
  tag stripping. I have no idea how this bug wasn't known so far,
  without the workaround nge(4) may never work on VLAN
  environments.
o Fixed Rx checksum offload logic such that it now honors active
  interface capability configured with ifconfig(8).
o In nge_start()/nge_txencap(), always leave at least one free
  descriptor as indicated in datasheet. Without this the hardware
  would be confused with ring descriptor structure(e.g. no clue
  for the end of descriptor ring).
o Removed dead-code that checks interrupts on PHY hardware. The
  code was designed to detect link state changes but it was
  disabled as driving nge_tick clock would break auto-negotiation
  timer. This code is no longer needed as nge(4) now uses mii(4)
  and link state change handling is done with mii callback.
o Rearranged ethernet address programming logic such that it works
   on strict-alignment architectures.
o Added IFCAP_VLAN_HWTAGGING/IFCAP_VLAN_HWCSUM handler in
   nge_ioctl() such that the functionality is configurable with
   ifconfig(8). DP83820/DP83821 can do checksum offload for VLAN
   tagged frames so enable Tx/Rx checksum offload for VLAN
   interfaces.
o Simplified IFCAP_POLLING selection logic in nge_ioctl().
o Fixed module unload panic when bpf listeners are active.
o Tx/Rx descriptor ring address uses 64bit DMA address for
   readability. High address part of DMA would be 0 as nge(4)
   disabled 64bit DMA transfers so it's ok for DP83821.
o Removed volatile keyword in softc as bus_dmamap_sync(9) should
   take care of this.
o Removed extra driver private structures in descriptor ring. These
   extra elements are not part of descriptor structure. Embedding
   private driver structure into descriptor ring is not good idea
   as its size may be different on 32bit/64bit architectures.
o Added miibus_linkchg method handler to catch link state changes.
o Removed unneeded nge_ifmedia in softc. All TBI access is handled
  in gentbi(4). There is no difference between TBI and non-TBI case
  now.
o Removed "gigabit link up" message handling in nge_tick. Link
  state change notification is already performed by mii(4) and
  checking link state by accessing PHY registers in periodic timer
  handler of driver is wrong. All link state and speed/duplex
  monitoring should be handled in PHY driver.
o Use our own timer for watchdog instead of if_watchdog/if_timer
  interface.
o Added hardware MAC statistics counter, users canget current MAC
  statistics from dev.nge.%d.stats sysctl node(%d is unit number of
  a device).
o Removed unused macros, NGE_LASTDESC, NGE_MODE, NGE_OWNDESC,
  NGE_RXBYTES.
o Increased number of Tx/Rx descriptors from 128 to 256. From my
  experience on gigabit ethernet controllers, number of descriptors
  should be 256 or higher to get an optimal performance on gigabit
  link.
o Increased jumbo frame length to 9022 bytes to cope with other
  gigabit ethernet drivers. Experimentation shows no problems with
  9022 bytes.
o Removed unused member variables in softc.
o Switched from bus_space_{read|write}_4 to bus_{read|write}_4.
o Added support for WOL.
2009-05-21 02:12:10 +00:00

743 lines
24 KiB
C

/*-
* Copyright (c) 2001 Wind River Systems
* Copyright (c) 1997, 1998, 1999, 2000, 2001
* Bill Paul <wpaul@bsdi.com>. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by Bill Paul.
* 4. Neither the name of the author nor the names of any co-contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY Bill Paul AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL Bill Paul OR THE VOICES IN HIS HEAD
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
* THE POSSIBILITY OF SUCH DAMAGE.
*
* $FreeBSD$
*/
#define NGE_CSR 0x00
#define NGE_CFG 0x04
#define NGE_MEAR 0x08
#define NGE_PCITST 0x0C
#define NGE_ISR 0x10
#define NGE_IMR 0x14
#define NGE_IER 0x18
#define NGE_IHR 0x1C
#define NGE_TX_LISTPTR_LO 0x20
#define NGE_TX_LISTPTR_HI 0x24
#define NGE_TX_LISTPTR NGE_TX_LISTPTR_LO
#define NGE_TX_CFG 0x28
#define NGE_GPIO 0x2C
#define NGE_RX_LISTPTR_LO 0x30
#define NGE_RX_LISTPTR_HI 0x34
#define NGE_RX_LISTPTR NGE_RX_LISTPTR_LO
#define NGE_RX_CFG 0x38
#define NGE_PRIOQCTL 0x3C
#define NGE_WOLCSR 0x40
#define NGE_PAUSECSR 0x44
#define NGE_RXFILT_CTL 0x48
#define NGE_RXFILT_DATA 0x4C
#define NGE_BOOTROM_ADDR 0x50
#define NGE_BOOTROM_DATA 0x54
#define NGE_SILICONREV 0x58
#define NGE_MIBCTL 0x5C
#define NGE_MIB_RXERRPKT 0x60
#define NGE_MIB_RXERRFCS 0x64
#define NGE_MIB_RXERRMISSEDPKT 0x68
#define NGE_MIB_RXERRALIGN 0x6C
#define NGE_MIB_RXERRSYM 0x70
#define NGE_MIB_RXERRGIANT 0x74
#define NGE_MIB_RXERRRANGLEN 0x78
#define NGE_MIB_RXBADOPCODE 0x7C
#define NGE_MIB_RXPAUSEPKTS 0x80
#define NGE_MIB_TXPAUSEPKTS 0x84
#define NGE_MIB_TXERRSQE 0x88
#define NGE_TXPRIOQ_PTR1 0xA0
#define NGE_TXPRIOQ_PTR2 0xA4
#define NGE_TXPRIOQ_PTR3 0xA8
#define NGE_RXPRIOQ_PTR1 0xB0
#define NGE_RXPRIOQ_PTR2 0xB4
#define NGE_RXPRIOQ_PTR3 0xB8
#define NGE_VLAN_IP_RXCTL 0xBC
#define NGE_VLAN_IP_TXCTL 0xC0
#define NGE_VLAN_DATA 0xC4
#define NGE_CLKRUN 0xCC
#define NGE_TBI_BMCR 0xE0
#define NGE_TBI_BMSR 0xE4
#define NGE_TBI_ANAR 0xE8
#define NGE_TBI_ANLPAR 0xEC
#define NGE_TBI_ANER 0xF0
#define NGE_TBI_ESR 0xF4
/* Control/status register */
#define NGE_CSR_TX_ENABLE 0x00000001
#define NGE_CSR_TX_DISABLE 0x00000002
#define NGE_CSR_RX_ENABLE 0x00000004
#define NGE_CSR_RX_DISABLE 0x00000008
#define NGE_CSR_TX_RESET 0x00000010
#define NGE_CSR_RX_RESET 0x00000020
#define NGE_CSR_SOFTINTR 0x00000080
#define NGE_CSR_RESET 0x00000100
#define NGE_CSR_TX_PRIOQ_ENB0 0x00000200
#define NGE_CSR_TX_PRIOQ_ENB1 0x00000400
#define NGE_CSR_TX_PRIOQ_ENB2 0x00000800
#define NGE_CSR_TX_PRIOQ_ENB3 0x00001000
#define NGE_CSR_RX_PRIOQ_ENB0 0x00002000
#define NGE_CSR_RX_PRIOQ_ENB1 0x00004000
#define NGE_CSR_RX_PRIOQ_ENB2 0x00008000
#define NGE_CSR_RX_PRIOQ_ENB3 0x00010000
/* Configuration register */
#define NGE_CFG_BIGENDIAN 0x00000001
#define NGE_CFG_EXT_125MHZ 0x00000002
#define NGE_CFG_BOOTROM_DIS 0x00000004
#define NGE_CFG_PERR_DETECT 0x00000008
#define NGE_CFG_DEFER_DISABLE 0x00000010
#define NGE_CFG_OUTOFWIN_TIMER 0x00000020
#define NGE_CFG_SINGLE_BACKOFF 0x00000040
#define NGE_CFG_PCIREQ_ALG 0x00000080
#define NGE_CFG_EXTSTS_ENB 0x00000100
#define NGE_CFG_PHY_DIS 0x00000200
#define NGE_CFG_PHY_RST 0x00000400
#define NGE_CFG_64BIT_ADDR_ENB 0x00000800
#define NGE_CFG_64BIT_DATA_ENB 0x00001000
#define NGE_CFG_64BIT_PCI_DET 0x00002000
#define NGE_CFG_64BIT_TARG 0x00004000
#define NGE_CFG_MWI_DIS 0x00008000
#define NGE_CFG_MRM_DIS 0x00010000
#define NGE_CFG_TMRTST 0x00020000
#define NGE_CFG_PHYINTR_SPD 0x00040000
#define NGE_CFG_PHYINTR_LNK 0x00080000
#define NGE_CFG_PHYINTR_DUP 0x00100000
#define NGE_CFG_MODE_1000 0x00400000
#define NGE_CFG_TBI_EN 0x01000000
#define NGE_CFG_DUPLEX_STS 0x10000000
#define NGE_CFG_SPEED_STS 0x60000000
#define NGE_CFG_LINK_STS 0x80000000
/* MII/EEPROM control register */
#define NGE_MEAR_EE_DIN 0x00000001
#define NGE_MEAR_EE_DOUT 0x00000002
#define NGE_MEAR_EE_CLK 0x00000004
#define NGE_MEAR_EE_CSEL 0x00000008
#define NGE_MEAR_MII_DATA 0x00000010
#define NGE_MEAR_MII_DIR 0x00000020
#define NGE_MEAR_MII_CLK 0x00000040
#define NGE_EECMD_WRITE 0x140
#define NGE_EECMD_READ 0x180
#define NGE_EECMD_ERASE 0x1c0
#define NGE_EE_NODEADDR 0xA
/* PCI control register */
#define NGE_PCICTL_SRAMADDR 0x0000001F
#define NGE_PCICTL_RAMTSTENB 0x00000020
#define NGE_PCICTL_TXTSTENB 0x00000040
#define NGE_PCICTL_RXTSTENB 0x00000080
#define NGE_PCICTL_BMTSTENB 0x00000200
#define NGE_PCICTL_RAMADDR 0x001F0000
#define NGE_PCICTL_ROMTIME 0x0F000000
#define NGE_PCICTL_DISCTEST 0x40000000
/* Interrupt/status register */
#define NGE_ISR_RX_OK 0x00000001
#define NGE_ISR_RX_DESC_OK 0x00000002
#define NGE_ISR_RX_ERR 0x00000004
#define NGE_ISR_RX_EARLY 0x00000008
#define NGE_ISR_RX_IDLE 0x00000010
#define NGE_ISR_RX_OFLOW 0x00000020
#define NGE_ISR_TX_OK 0x00000040
#define NGE_ISR_TX_DESC_OK 0x00000080
#define NGE_ISR_TX_ERR 0x00000100
#define NGE_ISR_TX_IDLE 0x00000200
#define NGE_ISR_TX_UFLOW 0x00000400
#define NGE_ISR_MIB_SERVICE 0x00000800
#define NGE_ISR_SOFTINTR 0x00001000
#define NGE_ISR_PME_EVENT 0x00002000
#define NGE_ISR_PHY_INTR 0x00004000
#define NGE_ISR_HIBITS 0x00008000
#define NGE_ISR_RX_FIFO_OFLOW 0x00010000
#define NGE_ISR_TGT_ABRT 0x00020000
#define NGE_ISR_BM_ABRT 0x00040000
#define NGE_ISR_SYSERR 0x00080000
#define NGE_ISR_PARITY_ERR 0x00100000
#define NGE_ISR_RX_RESET_DONE 0x00200000
#define NGE_ISR_TX_RESET_DONE 0x00400000
#define NGE_ISR_RX_PRIOQ_DESC0 0x00800000
#define NGE_ISR_RX_PRIOQ_DESC1 0x01000000
#define NGE_ISR_RX_PRIOQ_DESC2 0x02000000
#define NGE_ISR_RX_PRIOQ_DESC3 0x04000000
#define NGE_ISR_TX_PRIOQ_DESC0 0x08000000
#define NGE_ISR_TX_PRIOQ_DESC1 0x10000000
#define NGE_ISR_TX_PRIOQ_DESC2 0x20000000
#define NGE_ISR_TX_PRIOQ_DESC3 0x40000000
/* Interrupt mask register */
#define NGE_IMR_RX_OK 0x00000001
#define NGE_IMR_RX_DESC_OK 0x00000002
#define NGE_IMR_RX_ERR 0x00000004
#define NGE_IMR_RX_EARLY 0x00000008
#define NGE_IMR_RX_IDLE 0x00000010
#define NGE_IMR_RX_OFLOW 0x00000020
#define NGE_IMR_TX_OK 0x00000040
#define NGE_IMR_TX_DESC_OK 0x00000080
#define NGE_IMR_TX_ERR 0x00000100
#define NGE_IMR_TX_IDLE 0x00000200
#define NGE_IMR_TX_UFLOW 0x00000400
#define NGE_IMR_MIB_SERVICE 0x00000800
#define NGE_IMR_SOFTINTR 0x00001000
#define NGE_IMR_PME_EVENT 0x00002000
#define NGE_IMR_PHY_INTR 0x00004000
#define NGE_IMR_HIBITS 0x00008000
#define NGE_IMR_RX_FIFO_OFLOW 0x00010000
#define NGE_IMR_TGT_ABRT 0x00020000
#define NGE_IMR_BM_ABRT 0x00040000
#define NGE_IMR_SYSERR 0x00080000
#define NGE_IMR_PARITY_ERR 0x00100000
#define NGE_IMR_RX_RESET_DONE 0x00200000
#define NGE_IMR_TX_RESET_DONE 0x00400000
#define NGE_IMR_RX_PRIOQ_DESC0 0x00800000
#define NGE_IMR_RX_PRIOQ_DESC1 0x01000000
#define NGE_IMR_RX_PRIOQ_DESC2 0x02000000
#define NGE_IMR_RX_PRIOQ_DESC3 0x04000000
#define NGE_IMR_TX_PRIOQ_DESC0 0x08000000
#define NGE_IMR_TX_PRIOQ_DESC1 0x10000000
#define NGE_IMR_TX_PRIOQ_DESC2 0x20000000
#define NGE_IMR_TX_PRIOQ_DESC3 0x40000000
#define NGE_INTRS \
(NGE_IMR_RX_OFLOW|NGE_IMR_TX_UFLOW|NGE_IMR_TX_OK|\
NGE_IMR_TX_IDLE|NGE_IMR_RX_OK|NGE_IMR_RX_ERR|\
NGE_IMR_SYSERR|NGE_IMR_PHY_INTR|\
NGE_IMR_RX_IDLE|NGE_IMR_RX_FIFO_OFLOW)
/* Interrupt enable register */
#define NGE_IER_INTRENB 0x00000001
/* Interrupt moderation timer register */
#define NGE_IHR_HOLDOFF 0x000000FF
#define NGE_IHR_HOLDCTL 0x00000100
/* Transmit configuration register */
#define NGE_TXCFG_DRAIN_THRESH 0x000000FF /* 32-byte units */
#define NGE_TXCFG_FILL_THRESH 0x0000FF00 /* 32-byte units */
#define NGE_1000MB_BURST_DIS 0x00080000
#define NGE_TXCFG_DMABURST 0x00700000
#define NGE_TXCFG_ECRETRY 0x00800000
#define NGE_TXCFG_AUTOPAD 0x10000000
#define NGE_TXCFG_LOOPBK 0x20000000
#define NGE_TXCFG_IGN_HBEAT 0x40000000
#define NGE_TXCFG_IGN_CARR 0x80000000
#define NGE_TXCFG_DRAIN(x) (((x) >> 5) & NGE_TXCFG_DRAIN_THRESH)
#define NGE_TXCFG_FILL(x) ((((x) >> 5) << 8) & NGE_TXCFG_FILL_THRESH)
#define NGE_TXDMA_1024BYTES 0x00000000
#define NGE_TXDMA_8BYTES 0x00100000
#define NGE_TXDMA_16BYTES 0x00200000
#define NGE_TXDMA_32BYTES 0x00300000
#define NGE_TXDMA_64BYTES 0x00400000
#define NGE_TXDMA_128BYTES 0x00500000
#define NGE_TXDMA_256BYTES 0x00600000
#define NGE_TXDMA_512BYTES 0x00700000
#define NGE_TXCFG \
(NGE_TXDMA_512BYTES|NGE_TXCFG_AUTOPAD|\
NGE_TXCFG_FILL(64)|NGE_TXCFG_DRAIN(6400))
/* GPIO register */
#define NGE_GPIO_GP1_OUT 0x00000001
#define NGE_GPIO_GP2_OUT 0x00000002
#define NGE_GPIO_GP3_OUT 0x00000004
#define NGE_GPIO_GP4_OUT 0x00000008
#define NGE_GPIO_GP5_OUT 0x00000010
#define NGE_GPIO_GP1_OUTENB 0x00000020
#define NGE_GPIO_GP2_OUTENB 0x00000040
#define NGE_GPIO_GP3_OUTENB 0x00000080
#define NGE_GPIO_GP4_OUTENB 0x00000100
#define NGE_GPIO_GP5_OUTENB 0x00000200
#define NGE_GPIO_GP1_IN 0x00000400
#define NGE_GPIO_GP2_IN 0x00000800
#define NGE_GPIO_GP3_IN 0x00001000
#define NGE_GPIO_GP4_IN 0x00002000
#define NGE_GPIO_GP5_IN 0x00004000
/* Receive configuration register */
#define NGE_RXCFG_DRAIN_THRESH 0x0000003E /* 8-byte units */
#define NGE_RXCFG_DMABURST 0x00700000
#define NGE_RXCFG_RX_RANGEERR 0x04000000 /* accept in-range err frames */
#define NGE_RXCFG_RX_GIANTS 0x08000000 /* accept packets > 1518 bytes */
#define NGE_RXCFG_RX_FDX 0x10000000 /* full duplex receive */
#define NGE_RXCFG_RX_NOCRC 0x20000000 /* strip CRC */
#define NGE_RXCFG_RX_RUNT 0x40000000 /* accept short frames */
#define NGE_RXCFG_RX_BADPKTS 0x80000000 /* accept error frames */
#define NGE_RXCFG_DRAIN(x) ((((x) >> 3) << 1) & NGE_RXCFG_DRAIN_THRESH)
#define NGE_RXDMA_1024BYTES 0x00000000
#define NGE_RXDMA_8BYTES 0x00100000
#define NGE_RXDMA_16BYTES 0x00200000
#define NGE_RXDMA_32YTES 0x00300000
#define NGE_RXDMA_64BYTES 0x00400000
#define NGE_RXDMA_128BYTES 0x00500000
#define NGE_RXDMA_256BYTES 0x00600000
#define NGE_RXDMA_512BYTES 0x00700000
/*
* DP83820/DP83821 with H/W VLAN stripping does not accept short VLAN
* tagged packets such as ARP, short icmp echo request, etc. It seems
* that MAC checks frame length for VLAN tagged packets after stripping
* the VLAN tag. For short VLAN tagged packets it would would be 56
* (64 - CRC - VLAN info) bytes in length after stripping VLAN tag.
* If the VLAN tag stripped frames are less than 60 bytes in length
* the hardware think it received runt packets!
* Therefore we should accept runt frames to get VLAN tagged ARP
* packets. In addition, it is known that some revisions of
* DP83820/DP83821 have another bug that prevent fragmented IP packets
* from accepting. So we also should accept errored frames.
*/
#define NGE_RXCFG \
(NGE_RXCFG_DRAIN(64) | NGE_RXDMA_256BYTES| \
NGE_RXCFG_RX_RANGEERR | NGE_RXCFG_RX_BADPKTS | NGE_RXCFG_RX_RUNT | \
NGE_RXCFG_RX_GIANTS | NGE_RXCFG_RX_NOCRC)
/* Priority queue control */
#define NGE_PRIOQCTL_TXPRIO_ENB 0x00000001
#define NGE_PRIOQCTL_TXFAIR_ENB 0x00000002
#define NGE_PRIOQCTL_RXPRIO 0x0000000C
#define NGE_RXPRIOQ_DISABLED 0x00000000
#define NGE_RXPRIOQ_TWOQS 0x00000004
#define NGE_RXPRIOQ_THREEQS 0x00000008
#define NGE_RXPRIOQ_FOURQS 0x0000000C
/* Wake On LAN command/status register */
#define NGE_WOLCSR_WAKE_ON_PHYINTR 0x00000001
#define NGE_WOLCSR_WAKE_ON_UNICAST 0x00000002
#define NGE_WOLCSR_WAKE_ON_MULTICAST 0x00000004
#define NGE_WOLCSR_WAKE_ON_BROADCAST 0x00000008
#define NGE_WOLCSR_WAKE_ON_ARP 0x00000010
#define NGE_WOLCSR_WAKE_ON_PAT0_MATCH 0x00000020
#define NGE_WOLCSR_WAKE_ON_PAT1_MATCH 0x00000040
#define NGE_WOLCSR_WAKE_ON_PAT2_MATCH 0x00000080
#define NGE_WOLCSR_WAKE_ON_PAT3_MATCH 0x00000100
#define NGE_WOLCSR_WAKE_ON_MAGICPKT 0x00000200
#define NGE_WOLCSR_SECUREON_ENB 0x00000400
#define NGE_WOLCSR_SECUREON_HACK 0x00200000
#define NGE_WOLCSR_PHYINTR 0x00400000
#define NGE_WOLCSR_UNICAST 0x00800000
#define NGE_WOLCSR_MULTICAST 0x01000000
#define NGE_WOLCSR_BROADCAST 0x02000000
#define NGE_WOLCSR_ARP_RCVD 0x04000000
#define NGE_WOLCSR_PAT0_MATCH 0x08000000
#define NGE_WOLCSR_PAT1_MATCH 0x10000000
#define NGE_WOLCSR_PAT2_MATCH 0x20000000
#define NGE_WOLCSR_PAT3_MATCH 0x40000000
#define NGE_WOLCSR_MAGICPKT 0x80000000
/* Pause control/status register */
#define NGE_PAUSECSR_CNT 0x0000FFFF
#define NGE_PAUSECSR_PFRAME_SENT 0x00020000
#define NGE_PAUSECSR_RX_DATAFIFO_THR_LO 0x000C0000
#define NGE_PAUSECSR_RX_DATAFIFO_THR_HI 0x00300000
#define NGE_PAUSECSR_RX_STATFIFO_THR_LO 0x00C00000
#define NGE_PAUSECSR_RX_STATFIFO_THR_HI 0x03000000
#define NGE_PAUSECSR_PFRAME_RCVD 0x08000000
#define NGE_PAUSECSR_PAUSE_ACTIVE 0x10000000
#define NGE_PAUSECSR_PAUSE_ON_DA 0x20000000 /* pause on direct addr */
#define NGE_PAUSECSR_PAUSE_ON_MCAST 0x40000000 /* pause on mcast */
#define NGE_PAUSECSR_PAUSE_ENB 0x80000000
/* Receive filter/match control message */
#define MGE_RXFILTCTL_ADDR 0x000003FF
#define NGE_RXFILTCTL_ULMASK 0x00080000
#define NGE_RXFILTCTL_UCHASH 0x00100000
#define NGE_RXFILTCTL_MCHASH 0x00200000
#define NGE_RXFILTCTL_ARP 0x00400000
#define NGE_RXFILTCTL_PMATCH0 0x00800000
#define NGE_RXFILTCTL_PMATCH1 0x01000000
#define NGE_RXFILTCTL_PMATCH2 0x02000000
#define NGE_RXFILTCTL_PMATCH3 0x04000000
#define NGE_RXFILTCTL_PERFECT 0x08000000
#define NGE_RXFILTCTL_ALLPHYS 0x10000000
#define NGE_RXFILTCTL_ALLMULTI 0x20000000
#define NGE_RXFILTCTL_BROAD 0x40000000
#define NGE_RXFILTCTL_ENABLE 0x80000000
#define NGE_FILTADDR_PAR0 0x00000000
#define NGE_FILTADDR_PAR1 0x00000002
#define NGE_FILTADDR_PAR2 0x00000004
#define NGE_FILTADDR_PMATCH0 0x00000006
#define NGE_FILTADDR_PMATCH1 0x00000008
#define NGE_FILTADDR_SOPASS0 0x0000000A
#define NGE_FILTADDR_SOPASS1 0x0000000C
#define NGE_FILTADDR_SOPASS2 0x0000000E
#define NGE_FILTADDR_FMEM_LO 0x00000100
#define NGE_FILTADDR_FMEM_HI 0x000003FE
#define NGE_FILTADDR_MCAST_LO 0x00000100 /* start of multicast filter */
#define NGE_FILTADDR_MCAST_HI 0x000001FE /* end of multicast filter */
#define NGE_MCAST_FILTER_LEN 256 /* bytes */
#define NGE_FILTADDR_PBUF0 0x00000200 /* pattern buffer 0 */
#define NGE_FILTADDR_PBUF1 0x00000280 /* pattern buffer 1 */
#define NGE_FILTADDR_PBUF2 0x00000300 /* pattern buffer 2 */
#define NGE_FILTADDR_PBUF3 0x00000380 /* pattern buffer 3 */
/* MIB control register */
#define NGE_MIBCTL_WARNTEST 0x00000001
#define NGE_MIBCTL_FREEZE_CNT 0x00000002
#define NGE_MIBCTL_CLEAR_CNT 0x00000004
#define NGE_MIBCTL_STROBE_CNT 0x00000008
/* VLAN/IP RX control register */
#define NGE_VIPRXCTL_TAG_DETECT_ENB 0x00000001
#define NGE_VIPRXCTL_TAG_STRIP_ENB 0x00000002
#define NGE_VIPRXCTL_DROP_TAGGEDPKTS 0x00000004
#define NGE_VIPRXCTL_DROP_UNTAGGEDPKTS 0x00000008
#define NGE_VIPRXCTL_IPCSUM_ENB 0x00000010
#define NGE_VIPRXCTL_REJECT_BADIPCSUM 0x00000020
#define NGE_VIPRXCTL_REJECT_BADTCPCSUM 0x00000040
#define NGE_VIPRXCTL_REJECT_BADUDPCSUM 0x00000080
/* VLAN/IP TX control register */
#define NGE_VIPTXCTL_TAG_ALL 0x00000001
#define NGE_VIPTXCTL_TAG_PER_PKT 0x00000002
#define NGE_VIPTXCTL_CSUM_ALL 0x00000004
#define NGE_VIPTXCTL_CSUM_PER_PKT 0x00000008
/* VLAN data register */
#define NGE_VLANDATA_VTYPE 0x0000FFFF
#define NGE_VLANDATA_VTCI 0xFFFF0000
/* Clockrun register */
#define NGE_CLKRUN_PMESTS 0x00008000
#define NGE_CLKRUN_PMEENB 0x00000100
#define NGE_CLNRUN_CLKRUN_ENB 0x00000001
/* TBI BMCR */
#define NGE_TBIBMCR_RESTART_ANEG 0x00000200
#define NGE_TBIBMCR_ENABLE_ANEG 0x00001000
#define NGE_TBIBMCR_LOOPBACK 0x00004000
/* TBI BMSR */
#define NGE_TBIBMSR_ANEG_DONE 0x00000004
#define NGE_TBIBMSR_LINKSTAT 0x00000020
/* TBI ANAR */
#define NGE_TBIANAR_HDX 0x00000020
#define NGE_TBIANAR_FDX 0x00000040
#define NGE_TBIANAR_PS1 0x00000080
#define NGE_TBIANAR_PS2 0x00000100
#define NGE_TBIANAR_PCAP 0x00000180
#define NGE_TBIANAR_REMFAULT 0x00003000
#define NGE_TBIANAR_NEXTPAGE 0x00008000
/* TBI ANLPAR */
#define NGE_TBIANLPAR_HDX 0x00000020
#define NGE_TBIANLPAR_FDX 0x00000040
#define NGE_TBIANAR_PS1 0x00000080
#define NGE_TBIANAR_PS2 0x00000100
#define NGE_TBIANLPAR_PCAP 0x00000180
#define NGE_TBIANLPAR_REMFAULT 0x00003000
#define NGE_TBIANLPAR_NEXTPAGE 0x00008000
/* TBI ANER */
#define NGE_TBIANER_PAGERCVD 0x00000002
#define NGE_TBIANER_NEXTPGABLE 0x00000004
/* TBI EXTSTS */
#define NGE_TBIEXTSTS_HXD 0x00004000
#define NGE_TBIEXTSTS_FXD 0x00008000
/*
* DMA descriptor structures. The RX and TX descriptor formats are
* deliberately designed to be similar to facilitate passing them between
* RX and TX queues on multiple controllers, in the case where you have
* multiple MACs in a switching configuration. With the 83820, the pointer
* values can be either 64 bits or 32 bits depending on how the chip is
* configured. For the 83821, the fields are always 32-bits. There is
* also an optional extended status field for VLAN and TCP/IP checksum
* functions. We use the checksum feature so we enable the use of this
* field. Descriptors must be 64-bit aligned.
*/
struct nge_desc_64 {
/* Hardware descriptor section */
uint32_t nge_next_lo;
uint32_t nge_next_hi;
uint32_t nge_ptr_lo;
uint32_t nge_ptr_hi;
uint32_t nge_cmdsts;
uint32_t nge_extsts;
};
struct nge_desc_32 {
/* Hardware descriptor section */
uint32_t nge_next;
uint32_t nge_ptr;
uint32_t nge_cmdsts;
uint32_t nge_extsts;
};
#define nge_desc nge_desc_32
#define NGE_CMDSTS_BUFLEN 0x0000FFFF
#define NGE_CMDSTS_PKT_OK 0x08000000
#define NGE_CMDSTS_CRC 0x10000000
#define NGE_CMDSTS_INTR 0x20000000
#define NGE_CMDSTS_MORE 0x40000000
#define NGE_CMDSTS_OWN 0x80000000
#define NGE_INC(x, y) (x) = ((x) + 1) % y
#define NGE_RXSTAT_RANGELENERR 0x00010000
#define NGE_RXSTAT_LOOPBK 0x00020000
#define NGE_RXSTAT_ALIGNERR 0x00040000
#define NGE_RXSTAT_CRCERR 0x00080000
#define NGE_RXSTAT_SYMBOLERR 0x00100000
#define NGE_RXSTAT_RUNT 0x00200000
#define NGE_RXSTAT_GIANT 0x00400000
#define NGE_RXSTAT_DSTCLASS 0x01800000
#define NGE_RXSTAT_OVERRUN 0x02000000
#define NGE_RXSTAT_RX_ABORT 0x04000000
#define NGE_DSTCLASS_REJECT 0x00000000
#define NGE_DSTCLASS_UNICAST 0x00800000
#define NGE_DSTCLASS_MULTICAST 0x01000000
#define NGE_DSTCLASS_BROADCAST 0x02000000
#define NGE_TXSTAT_COLLCNT 0x000F0000
#define NGE_TXSTAT_EXCESSCOLLS 0x00100000
#define NGE_TXSTAT_OUTOFWINCOLL 0x00200000
#define NGE_TXSTAT_EXCESS_DEFER 0x00400000
#define NGE_TXSTAT_DEFERED 0x00800000
#define NGE_TXSTAT_CARR_LOST 0x01000000
#define NGE_TXSTAT_UNDERRUN 0x02000000
#define NGE_TXSTAT_TX_ABORT 0x04000000
#define NGE_TXEXTSTS_VLAN_TCI 0x0000FFFF
#define NGE_TXEXTSTS_VLANPKT 0x00010000
#define NGE_TXEXTSTS_IPCSUM 0x00020000
#define NGE_TXEXTSTS_TCPCSUM 0x00080000
#define NGE_TXEXTSTS_UDPCSUM 0x00200000
#define NGE_RXEXTSTS_VTCI 0x0000FFFF
#define NGE_RXEXTSTS_VLANPKT 0x00010000
#define NGE_RXEXTSTS_IPPKT 0x00020000
#define NGE_RXEXTSTS_IPCSUMERR 0x00040000
#define NGE_RXEXTSTS_TCPPKT 0x00080000
#define NGE_RXEXTSTS_TCPCSUMERR 0x00100000
#define NGE_RXEXTSTS_UDPPKT 0x00200000
#define NGE_RXEXTSTS_UDPCSUMERR 0x00400000
#define NGE_TX_RING_CNT 256
#define NGE_RX_RING_CNT 256
#define NGE_TX_RING_SIZE sizeof(struct nge_desc) * NGE_TX_RING_CNT
#define NGE_RX_RING_SIZE sizeof(struct nge_desc) * NGE_RX_RING_CNT
#define NGE_RING_ALIGN sizeof(uint64_t)
#define NGE_RX_ALIGN sizeof(uint64_t)
#define NGE_MAXTXSEGS 16
#define NGE_ADDR_LO(x) ((uint64_t)(x) & 0xffffffff)
#define NGE_ADDR_HI(x) ((uint64_t)(x) >> 32)
#define NGE_TX_RING_ADDR(sc, i) \
((sc)->nge_rdata.nge_tx_ring_paddr + sizeof(struct nge_desc) * (i))
#define NGE_RX_RING_ADDR(sc, i) \
((sc)->nge_rdata.nge_rx_ring_paddr + sizeof(struct nge_desc) * (i))
struct nge_txdesc {
struct mbuf *tx_m;
bus_dmamap_t tx_dmamap;
};
struct nge_rxdesc {
struct mbuf *rx_m;
bus_dmamap_t rx_dmamap;
};
struct nge_chain_data {
bus_dma_tag_t nge_parent_tag;
bus_dma_tag_t nge_tx_tag;
struct nge_txdesc nge_txdesc[NGE_TX_RING_CNT];
bus_dma_tag_t nge_rx_tag;
struct nge_rxdesc nge_rxdesc[NGE_RX_RING_CNT];
bus_dma_tag_t nge_tx_ring_tag;
bus_dma_tag_t nge_rx_ring_tag;
bus_dmamap_t nge_tx_ring_map;
bus_dmamap_t nge_rx_ring_map;
bus_dmamap_t nge_rx_sparemap;
int nge_tx_prod;
int nge_tx_cons;
int nge_tx_cnt;
int nge_rx_cons;
};
struct nge_ring_data {
struct nge_desc *nge_tx_ring;
bus_addr_t nge_tx_ring_paddr;
struct nge_desc *nge_rx_ring;
bus_addr_t nge_rx_ring_paddr;
};
/*
* NatSemi PCI vendor ID.
*/
#define NGE_VENDORID 0x100B
/*
* 83820/83821 PCI device IDs
*/
#define NGE_DEVICEID 0x0022
struct nge_type {
uint16_t nge_vid;
uint16_t nge_did;
char *nge_name;
};
struct nge_mii_frame {
uint8_t mii_stdelim;
uint8_t mii_opcode;
uint8_t mii_phyaddr;
uint8_t mii_regaddr;
uint8_t mii_turnaround;
uint16_t mii_data;
};
/*
* MII constants
*/
#define NGE_MII_STARTDELIM 0x01
#define NGE_MII_READOP 0x02
#define NGE_MII_WRITEOP 0x01
#define NGE_MII_TURNAROUND 0x02
#define NGE_JUMBO_FRAMELEN 9022
#define NGE_JUMBO_MTU \
(NGE_JUMBO_FRAMELEN - sizeof(struct ether_vlan_header) - ETHER_CRC_LEN)
/* Statistics counters. */
struct nge_stats {
uint32_t rx_pkts_errs;
uint32_t rx_crc_errs;
uint32_t rx_fifo_oflows;
uint32_t rx_align_errs;
uint32_t rx_sym_errs;
uint32_t rx_pkts_jumbos;
uint32_t rx_len_errs;
uint32_t rx_unctl_frames;
uint32_t rx_pause;
uint32_t tx_pause;
uint32_t tx_seq_errs;
};
struct nge_softc {
struct ifnet *nge_ifp;
device_t nge_dev;
struct resource *nge_res;
int nge_res_type;
int nge_res_id;
struct resource *nge_irq;
void *nge_intrhand;
device_t nge_miibus;
int nge_if_flags;
uint32_t nge_flags;
#define NGE_FLAG_TBI 0x0002
#define NGE_FLAG_SUSPENDED 0x2000
#define NGE_FLAG_DETACH 0x4000
#define NGE_FLAG_LINK 0x8000
struct nge_chain_data nge_cdata;
struct nge_ring_data nge_rdata;
struct callout nge_stat_ch;
struct nge_stats nge_stats;
struct mtx nge_mtx;
#ifdef DEVICE_POLLING
int rxcycles;
#endif
int nge_watchdog_timer;
int nge_int_holdoff;
struct mbuf *nge_head;
struct mbuf *nge_tail;
};
#define NGE_LOCK_INIT(_sc, _name) \
mtx_init(&(_sc)->nge_mtx, _name, MTX_NETWORK_LOCK, MTX_DEF)
#define NGE_LOCK(_sc) mtx_lock(&(_sc)->nge_mtx)
#define NGE_LOCK_ASSERT(_sc) mtx_assert(&(_sc)->nge_mtx, MA_OWNED)
#define NGE_UNLOCK(_sc) mtx_unlock(&(_sc)->nge_mtx)
#define NGE_LOCK_DESTROY(_sc) mtx_destroy(&(_sc)->nge_mtx)
/*
* register space access macros
*/
#define CSR_WRITE_4(sc, reg, val) \
bus_write_4((sc)->nge_res, reg, val)
#define CSR_BARRIER_WRITE_4(sc, reg) \
bus_barrier((sc)->nge_res, reg, 4, BUS_SPACE_BARRIER_WRITE)
#define CSR_READ_4(sc, reg) \
bus_read_4((sc)->nge_res, reg)
#define NGE_TIMEOUT 1000
#define NGE_INT_HOLDOFF_DEFAULT 1
#define NGE_INT_HOLDOFF_MIN 0
#define NGE_INT_HOLDOFF_MAX 255
/*
* PCI low memory base and low I/O base register, and
* other PCI registers.
*/
#define NGE_PCI_VENDOR_ID 0x00
#define NGE_PCI_DEVICE_ID 0x02
#define NGE_PCI_COMMAND 0x04
#define NGE_PCI_STATUS 0x06
#define NGE_PCI_REVID 0x08
#define NGE_PCI_CLASSCODE 0x09
#define NGE_PCI_CACHELEN 0x0C
#define NGE_PCI_LATENCY_TIMER 0x0D
#define NGE_PCI_HEADER_TYPE 0x0E
#define NGE_PCI_LOIO 0x10
#define NGE_PCI_LOMEM 0x14
#define NGE_PCI_BIOSROM 0x30
#define NGE_PCI_INTLINE 0x3C
#define NGE_PCI_INTPIN 0x3D
#define NGE_PCI_MINGNT 0x3E
#define NGE_PCI_MINLAT 0x0F
#define NGE_PCI_RESETOPT 0x48
#define NGE_PCI_EEPROM_DATA 0x4C
/* power management registers */
#define NGE_PCI_CAPID 0x50 /* 8 bits */
#define NGE_PCI_NEXTPTR 0x51 /* 8 bits */
#define NGE_PCI_PWRMGMTCAP 0x52 /* 16 bits */
#define NGE_PCI_PWRMGMTCTRL 0x54 /* 16 bits */
#define NGE_PSTATE_MASK 0x0003
#define NGE_PSTATE_D0 0x0000
#define NGE_PSTATE_D1 0x0001
#define NGE_PSTATE_D2 0x0002
#define NGE_PSTATE_D3 0x0003
#define NGE_PME_EN 0x0010
#define NGE_PME_STATUS 0x8000