aboutsummaryrefslogtreecommitdiff
path: root/sys/dev/nge/if_ngereg.h
diff options
context:
space:
mode:
authorPyun YongHyeon <yongari@FreeBSD.org>2009-05-21 02:12:10 +0000
committerPyun YongHyeon <yongari@FreeBSD.org>2009-05-21 02:12:10 +0000
commitf6bc943047f37ee4312fbbf78574b314dfe7c6ad (patch)
treedd9e0aee37470c30145b7e48a0ef91c18bfbf37b /sys/dev/nge/if_ngereg.h
parentfadc970b778f682f4c7d290f426597967ddae9bb (diff)
downloadsrc-f6bc943047f37ee4312fbbf78574b314dfe7c6ad.tar.gz
src-f6bc943047f37ee4312fbbf78574b314dfe7c6ad.zip
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.
Notes
Notes: svn path=/head/; revision=192506
Diffstat (limited to 'sys/dev/nge/if_ngereg.h')
-rw-r--r--sys/dev/nge/if_ngereg.h218
1 files changed, 113 insertions, 105 deletions
diff --git a/sys/dev/nge/if_ngereg.h b/sys/dev/nge/if_ngereg.h
index e4d5e527cf15..4ad1bf9be2ab 100644
--- a/sys/dev/nge/if_ngereg.h
+++ b/sys/dev/nge/if_ngereg.h
@@ -302,9 +302,23 @@
#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_GIANTS|NGE_RXCFG_RX_NOCRC)
+ (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
@@ -320,13 +334,14 @@
#define NGE_WOLCSR_WAKE_ON_PHYINTR 0x00000001
#define NGE_WOLCSR_WAKE_ON_UNICAST 0x00000002
#define NGE_WOLCSR_WAKE_ON_MULTICAST 0x00000004
-#define NGR_WOLCSR_WAKE_ON_BROADCAST 0x00000008
+#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_SECUREON_ENB 0x00000200
+#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
@@ -464,58 +479,25 @@
* 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.
- * After this, we include some additional structure members for
- * use by the driver. Note that for this structure will be a different
- * size on the alpha, but that's okay as long as it's a multiple of 4
- * bytes in size.
- *
*/
struct nge_desc_64 {
/* Hardware descriptor section */
- volatile uint32_t nge_next_lo;
- volatile uint32_t nge_next_hi;
- volatile uint32_t nge_ptr_lo;
- volatile uint32_t nge_ptr_hi;
- volatile uint32_t nge_cmdsts;
-#define nge_rxstat nge_cmdsts
-#define nge_txstat nge_cmdsts
-#define nge_ctl nge_cmdsts
- volatile uint32_t nge_extsts;
- /* Driver software section */
- union {
- struct mbuf *nge_mbuf;
- uint64_t nge_dummy;
- } nge_mb_u;
- union {
- struct nge_desc_32 *nge_nextdesc;
- uint64_t nge_dummy;
- } nge_nd_u;
+ 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 */
- volatile uint32_t nge_next;
- volatile uint32_t nge_ptr;
- volatile uint32_t nge_cmdsts;
-#define nge_rxstat nge_cmdsts
-#define nge_txstat nge_cmdsts
-#define nge_ctl nge_cmdsts
- volatile uint32_t nge_extsts;
- /* Driver software section */
- union {
- struct mbuf *nge_mbuf;
- uint64_t nge_dummy;
- } nge_mb_u;
- union {
- struct nge_desc_32 *nge_nextdesc;
- uint64_t nge_dummy;
- } nge_nd_u;
+ uint32_t nge_next;
+ uint32_t nge_ptr;
+ uint32_t nge_cmdsts;
+ uint32_t nge_extsts;
};
-#define nge_mbuf nge_mb_u.nge_mbuf
-#define nge_nextdesc nge_nd_u.nge_nextdesc
-
-
#define nge_desc nge_desc_32
#define NGE_CMDSTS_BUFLEN 0x0000FFFF
@@ -525,11 +507,7 @@ struct nge_desc_32 {
#define NGE_CMDSTS_MORE 0x40000000
#define NGE_CMDSTS_OWN 0x80000000
-#define NGE_LASTDESC(x) (!((x)->nge_ctl & NGE_CMDSTS_MORE))
-#define NGE_MORE(x) ((x)->nge_ctl & NGE_CMDSTS_MORE)
-#define NGE_OWNDESC(x) ((x)->nge_ctl & NGE_CMDSTS_OWN)
-#define NGE_INC(x, y) (x) = (x + 1) % y
-#define NGE_RXBYTES(x) ((x)->nge_ctl & NGE_CMDSTS_BUFLEN)
+#define NGE_INC(x, y) (x) = ((x) + 1) % y
#define NGE_RXSTAT_RANGELENERR 0x00010000
#define NGE_RXSTAT_LOOPBK 0x00020000
@@ -571,34 +549,54 @@ struct nge_desc_32 {
#define NGE_RXEXTSTS_UDPPKT 0x00200000
#define NGE_RXEXTSTS_UDPCSUMERR 0x00400000
-#define NGE_RX_LIST_CNT 128
-#define NGE_TX_LIST_CNT 128
-
-struct nge_list_data {
- struct nge_desc nge_rx_list[NGE_RX_LIST_CNT];
- struct nge_desc nge_tx_list[NGE_TX_LIST_CNT];
-#ifdef notyet
- int vge_tx_prodidx;
- int vge_rx_prodidx;
- int vge_tx_considx;
- int vge_tx_free;
-
- struct nge_desc *nge_tx_list;
- struct mbuf *nge_tx_mbuf[NGE_TX_DESC_CNT]
- bus_dmamap_t nge_tx_dmamap[NGE_TX_DESC_CNT];
- bus_dma_tag_t nge_tx_list_tag;
- bus_dmamap_t nge_tx_list_map[NGE_TX_DESC_CNT];
- bus_addr_t nge_tx_list_add[NGE_TX_DESC_CNT];
-
- struct nge_desc *nge_rx_list;
- struct mbuf *nge_rx_mbuf[NGE_RX_DESC_CNT]
- bus_dmamap_t nge_rx_dmamap[NGE_RX_DESC_CNT];
- bus_dma_tag_t nge_rx_list_tag;
- bus_dmamap_t nge_rx_list_map[NGE_RX_DESC_CNT];
- bus_addr_t nge_rx_list_addr[NGE_RX_DESC_CNT];
-#endif
+#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.
@@ -633,44 +631,50 @@ struct nge_mii_frame {
#define NGE_MII_WRITEOP 0x01
#define NGE_MII_TURNAROUND 0x02
-#define NGE_JUMBO_FRAMELEN 9018
-#define NGE_JUMBO_MTU (NGE_JUMBO_FRAMELEN-ETHER_HDR_LEN-ETHER_CRC_LEN)
-
-#if !defined(__i386__)
-#define NGE_FIXUP_RX
-#endif
-
-struct nge_ring_data {
- int nge_rx_prod;
- int nge_tx_prod;
- int nge_tx_cons;
- int nge_tx_cnt;
+#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;
- bus_space_handle_t nge_bhandle;
- bus_space_tag_t nge_btag;
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;
- uint8_t nge_type;
- uint8_t nge_link;
- uint8_t nge_width;
-#define NGE_WIDTH_32BITS 0
-#define NGE_WIDTH_64BITS 1
- struct nge_list_data *nge_ldata;
- struct nge_ring_data nge_cdata;
+ 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;
- uint8_t nge_tbi;
- struct ifmedia nge_ifmedia;
#ifdef DEVICE_POLLING
int rxcycles;
#endif
+ int nge_watchdog_timer;
+ int nge_int_holdoff;
struct mbuf *nge_head;
struct mbuf *nge_tail;
};
@@ -686,14 +690,18 @@ struct nge_softc {
* register space access macros
*/
#define CSR_WRITE_4(sc, reg, val) \
- bus_space_write_4(sc->nge_btag, sc->nge_bhandle, 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_space_read_4(sc->nge_btag, sc->nge_bhandle, reg)
+ bus_read_4((sc)->nge_res, reg)
#define NGE_TIMEOUT 1000
-#define NGE_RXLEN 1536
-#define NGE_MIN_FRAMELEN 60
+
+#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