summaryrefslogtreecommitdiffstats
path: root/sys/dev/sf/if_sfreg.h
diff options
context:
space:
mode:
authoryongari <yongari@FreeBSD.org>2008-01-21 06:38:23 +0000
committeryongari <yongari@FreeBSD.org>2008-01-21 06:38:23 +0000
commit571e260180484c6d93e823cd1e5880766ab87dac (patch)
treeb8f4dbd9936e5d0c7c4f1c03dc66965b6c6cc3f4 /sys/dev/sf/if_sfreg.h
parentd1a53c74fd4abe2edc0759384d92723f41bd1026 (diff)
downloadFreeBSD-src-571e260180484c6d93e823cd1e5880766ab87dac.zip
FreeBSD-src-571e260180484c6d93e823cd1e5880766ab87dac.tar.gz
Overhaul sf(4) to make it run on all architectures and implement
checksum offoload by downloading AIC-6915 firmware. Changes are o Header file cleanup. o Simplified probe logic. o s/u_int{8,16,32}_t/uint{8,16,32}_t/g o K&R -> ANSI C. o In register access function, added support both memory mapped and IO space register acccess. The function will dynamically detect which method would be choosed. o sf_setperf() was modified to support strict-alignment architectures. o Use SF_MII_DATAPORT instead of hardcoded value 0xffff. o Added link state/speed, duplex changes handling task q. The task q is also responsible for flow control settings. o Always hornor link up/down state reported by mii layers. The link state information is used in sf_start() to determine whether we got a valid link. o Added experimental flow-control setup. It was commented out but will be activated once we have flow-cotrol infrastructure in mii layer. o Simplify IFF_UP/IFCAP_POLLING and IFF_PROMISC handling logic. Rx filter always honors promiscuous mode. o Implemented suspend/resume methods. o Reorganized Rx filter routine so promiscuous mode changes doesn't require interface re-initialization. o Reimplemnted driver probe routine such that it looks for matching device from supported hardware list table. This change will help to add newer hardware revision to the driver. o Use ETHER_ADDR_LEN instead of hardcoded value. o Prefer memory space register mapping over I/O space as the hardware requires lots of register access to get various consumer/producer index. Failing to get memory space mapping, sf(4) falls back to I/O space mapping. Use of memory space register mapping requires somewhat large memory space(512K), though. o Switch to simpler bus_{read,write}_{1,2,4}. o Use PCIR_BAR macro to get BARs. o Program PCI cache line size if the cache line size was set to 0 and enable PCI MWI. o Add a new sysctl node 'dev.sf.N.stats' that shows various MAC counters for Rx/Tx statistics. o Add a sysctl node to configure interrupt moderation timer. The timer defers interrupts generation until time specified in timer control register is expired. The value in the timer register is in units of 102.4us. The allowable range for the timer is 0 - 31 (0 ~ 3.276ms). The default value is 1(102.4us). Users can change the timer value with dev.sf.N.int_mod sysctl(8) variable/loader(8) tunable. o bus_dma(9) conversion - Enable 64bit DMA addressing. - Enable 64bit descriptor format support. - Apply descriptor ring alignment requirements(256 bytes alignment). - Apply Rx buffer address alignment requirements(4 bytes alignment). - Apply 4GB boundary restrictions(Tx/Rx ring and its completion ring should live in the same 4GB address space.) - Set number of allowable number of DMA segments to 16. In fact, AIC-6915 doesn't have a limit for number of DMA segments but it would be waste of Tx descriptor resource if we allow more than 16. - Rx/Tx side bus_dmamap_load_mbuf_sg(9) support. - Added alignment fixup code for strict-alignment architectures. - Added endianness support code in Tx/Rx descriptor access. With these changes sf(4) should work on all platforms. o Don't set if_mtu in device attach, it's handled in ether_ifattach. o Use our own callout to drive watchdog timer. o Enable VLAN oversized frames and announce sf(4)'s VLAN capability to upper layer. o In sf_detach(), remove mtx_initialized KASSERT as it's not possible to get there without initialzing the mutex. Also mark that we're about to detaching so active bpf listeners do not panic the system. o To reduce PCI register access cycles, Rx completion ring is directly scanned instead of reading consumer/producer index registers. In theory, Tx completion ring also can be directly scanned. However the completion ring is composed of two types completion(1 for Tx done and 1 and DMA done). So reading producer index via register access would be more safer way to detect the ring wrap-around. o In sf_rxeof(), don't use m_devget(9) to align recevied frames. The alignment is required only for strict-alignment architectures and now the alignment is handled by sf_fixup_rx() if required. The removal of the copy operation in fast path should increase Rx performance a lot on non-strict-alignemnt architectures such as i386 and amd64. o In sf_newbuf(), don't set descriptor valid bit as sf(4) is programmed to run with normal mode. In normal mode, the valid bit have no meaning. The valid bit should be used only when the hardware uses polling(prefetch) mode. The end of descriptor queue bit could be used if needed, but sf(4) relys on auto-wrapping of hardware on 256 descriptor queue entries so both valid and descriptor end bit are not used anymore. o Don't disable generation of Tx DMA completion as said in datasheet and use the Tx DMA completion entry instead of relying on Tx done completion entry. Also added additional Tx completion entry type check in Tx completion handler. o Don't blindly reset watchdog timer in sf_txeof(). sf(4) now unarm the the watchdog only if there are no active Tx descriptors in Tx queue. o Don't manually update various counters in driver, instead, use built-in MAC statistic registers to update them. The statistic registers are updated in every second. o Modified Tx underrun handlers to increase the threshold value in units of 256 bytes. Previously it used to increase 16 bytes at a time which seems to take too long to stabalize whenever Tx underrun occurrs. o In interrupt handler, additional check for the interrupt is performed such that interrupts only for this device is allowed to process descriptor rings. Because reading SF_ISR register clears all interrtups, nuke writing to a SF_ISR register. o Tx underrun is abonormal condition and SF_ISR_ABNORMALINTR includes the interrupt. So there is no need to inspect the Tx underrun again in main interrupt loop. o Don't blindly reinitialize hardware for abnormal interrupt condition. sf(4) reintializes the hardware only when it encounters DMA error which requires an explicit hardware reinitialization. o Fix a long standing bug that incorrectly clears MAC statistic registers in sf_init_locked. o Added strict-alignment safe way of ethernet address reprogramming as IF_LLADDR may return unaligned address. o Move sf_reset() to sf_init_locked in order to always reset the hardware to a known state prior to configuring hardware. o Set default Rx DMA, Tx DMA paramters as shown in datasheet. o Enable PCI busmaster logic and autopadding for VLAN frames. o Rework sf_encap. - Previously sf(4) used to type 0 of Tx descriptor with padding enabled to store driver private data. Emebedding private data structures into descriptors is bad idea as the structure size would be different between 64bit and 32bit architectures. The type 0 descriptor allows fixed number of DMA segments in a descriptor format and provides relatively simple interface to manage multi-fragmented frames. However, it wastes lots of Tx descriptors as not all frames are fragmented as the number of allowable segments in a descriptor. - To overcome the limitation of type 0 descriptor, switch to type 2 descriptor which allows 64bit DMA addressing and can handle unliumited number of fragmented DMA segments. The drawback of type 2 descriptor is in its complexity in managing descriptors as driver should handle the end of Tx ring manually. - Manually set Tx desciptor queue end mark and record number of used descriptors to reclaim used descriptors in sf_txeof(). o Rework sf_start. - Honor link up/down state before attempting transmission. - Because sf(4) uses only one of two Tx queues, use low priority queue instead of high one. This will remove one shift operation in each Tx kick command. - Cache last produder index into softc such that subsequenet Tx operation doesn't need to access producer index register. o Rewrote sf_stats_update to include all available MAC statistic counters. o Employ AIC-6915 firmware from Adaptec and implement firmware download routine and TCP/UDP checksum offload. Partial checksum offload support was commented out due to the possibility of firmware bug in RxGFP. The firmware can strip VLAN tag in Rx path but the lack of firmware assistance of VLAN tag insertion in transmit side made it useless on FreeBSD. Unlike checksum offload, FreeBSD requires both Tx/Rx hardware VLAN assistance capability. The firmware may also detect wakeup frame and can wake system up from states other than D0. However, the lack of wakeup support form D3cold state keep me from adding WOL capability. Also detecting WOL frame requires firmware support but it's not yet known to me whether the firmware can process the WOL frame. o Changed *_ADDR_HIADDR to *_ADDR_HI to match other definitions of registers. o Added definitioan to interrupt moderation related constants. o Redefined SF_INTRS to include Tx DMA done and DMA errors. Removed Tx done as it's not needed anymore. o Added definition for Rx/Tx DMA high priority threshold. o Nuked unused marco SF_IDX_LO, SF_IDX_HI. o Added complete MAC statistic register definition. o Modified sf_stats structure to hold all MAC statistic regiters. o Nuke various driver private padding data in Tx/Rx descriptor definition. sf(4) no longer requires private padding. Also remove unused padding related definitions. This greatly simplifies descriptor manipulation on 64bit architectures. o Becase we no longer pad driver private data into descriptor, remove deprecated/not-applicable comments for padding. o Redefine Rx/Tx desciptor status. sf(4) doesn't use bit fileds anymore to support endianness. Tested by: bruffer (initial version)
Diffstat (limited to 'sys/dev/sf/if_sfreg.h')
-rw-r--r--sys/dev/sf/if_sfreg.h571
1 files changed, 308 insertions, 263 deletions
diff --git a/sys/dev/sf/if_sfreg.h b/sys/dev/sf/if_sfreg.h
index 29861ef..3ccfb80 100644
--- a/sys/dev/sf/if_sfreg.h
+++ b/sys/dev/sf/if_sfreg.h
@@ -196,13 +196,13 @@
#define SF_TXDQ_CTL 0x0090
#define SF_TXDQ_ADDR_HIPRIO 0x0094
#define SF_TXDQ_ADDR_LOPRIO 0x0098
-#define SF_TXDQ_ADDR_HIADDR 0x009C
+#define SF_TXDQ_ADDR_HI 0x009C
#define SF_TXDQ_PRODIDX 0x00A0
#define SF_TXDQ_CONSIDX 0x00A4
#define SF_TXDMA_STS1 0x00A8
#define SF_TXDMA_STS2 0x00AC
#define SF_TX_FRAMCTL 0x00B0
-#define SF_TXCQ_ADDR_HI 0x00B4
+#define SF_CQ_ADDR_HI 0x00B4
#define SF_TXCQ_CTL 0x00B8
#define SF_RXCQ_CTL_1 0x00BC
#define SF_RXCQ_CTL_2 0x00C0
@@ -212,7 +212,7 @@
#define SF_RXDMA_CTL 0x00D0
#define SF_RXDQ_CTL_1 0x00D4
#define SF_RXDQ_CTL_2 0x00D8
-#define SF_RXDQ_ADDR_HIADDR 0x00DC
+#define SF_RXDQ_ADDR_HI 0x00DC
#define SF_RXDQ_ADDR_Q1 0x00E0
#define SF_RXDQ_ADDR_Q2 0x00E4
#define SF_RXDQ_PTR_Q1 0x00E8
@@ -249,6 +249,11 @@
#define SF_TIMER_RXQ1DONE_DLY 0x40000000
#define SF_TIMER_EARLYRX1_DLY 0x80000000
+/* Timer resolution is 0.8us * 128. */
+#define SF_IM_MIN 0
+#define SF_IM_MAX 0x1F /* 3.276ms */
+#define SF_IM_DEFAULT 1 /* 102.4us */
+
/* Interrupt status register */
#define SF_ISR_PCIINT_ASSERTED 0x00000001
#define SF_ISR_GFP_TX 0x00000002
@@ -347,10 +352,11 @@
#define SF_INTRS \
(SF_IMR_RXDQ2_NOBUFS|SF_IMR_RXDQ1_DMADONE|SF_IMR_RXDQ2_DMADONE| \
- SF_IMR_TX_TXDONE|SF_IMR_RXDQ1_NOBUFS|SF_IMR_RXDQ2_DMADONE| \
+ SF_IMR_TX_DMADONE|SF_IMR_RXDQ1_NOBUFS|SF_IMR_RXDQ2_DMADONE| \
SF_IMR_NORMALINTR|SF_IMR_ABNORMALINTR|SF_IMR_TXCQ_NOBUFS| \
SF_IMR_RXCQ1_NOBUFS|SF_IMR_RXCQ2_NOBUFS|SF_IMR_STATSOFLOW| \
- SF_IMR_TX_LOFIFO)
+ SF_IMR_TX_LOFIFO|SF_IMR_DMAERR|SF_IMR_RXGFP_NORESP| \
+ SF_IMR_NO_TX_CSUM)
/* TX descriptor queue control registers */
#define SF_TXDQCTL_DESCTYPE 0x00000007
@@ -361,6 +367,9 @@
#define SF_TXDQCTL_SKIPLEN 0x001F0000
#define SF_TXDQCTL_HIPRIOTHRESH 0xFF000000
+#define SF_TXDMA_HIPRIO_THRESH 2
+#define SF_TXDDMA_BURST (128 / 32)
+
#define SF_TXBUFDESC_TYPE0 0x00000000
#define SF_TXBUFDESC_TYPE1 0x00000001
#define SF_TXBUFDESC_TYPE2 0x00000002
@@ -434,9 +443,6 @@
#define SF_CQ_TXTHRMODE_INT_ON 0x80000000
#define SF_CQ_TXTHRMODE_INT_OFF 0x00000000
-#define SF_IDX_LO(x) ((x) & 0x000007FF)
-#define SF_IDX_HI(x) (((x) >> 16) & 0x000007FF)
-
/* RX DMA control register */
#define SF_RXDMA_BURSTSIZE 0x0000007F
#define SF_RXDMA_FPTESTMODE 0x00000080
@@ -453,6 +459,8 @@
#define SF_RXDMA_DMABADPKTS 0x20000000
#define SF_RXDMA_DMARUNTS 0x40000000
#define SF_RXDMA_REPORTBADPKTS 0x80000000
+#define SF_RXDMA_HIGHPRIO_THRESH 6
+#define SF_RXDMA_BURST (64 / 32)
#define SF_RXDQMODE_Q1ONLY 0x00100000
#define SF_RXDQMODE_Q2_ON_FP 0x00200000
@@ -567,8 +575,8 @@
#define SF_MII_DATAPORT 0x0000FFFF
#define SF_PHY_REG(phy, reg) \
- (SF_MIIADDR_BASE + (phy * SF_MII_BLOCKS * sizeof(u_int32_t)) + \
- (reg * sizeof(u_int32_t)))
+ (SF_MIIADDR_BASE + ((phy) * SF_MII_BLOCKS * sizeof(uint32_t)) + \
+ ((reg) * sizeof(uint32_t)))
/*
* Ethernet extra registers 0x4000 to 0x4FFF
@@ -613,6 +621,8 @@
#define SF_MACCFG1_MIILOOPBK 0x00004000
#define SF_MACCFG1_SOFTRESET 0x00008000
+#define SF_MACCFG2_AUTOVLANPAD 0x00000020
+
/*
* There are the recommended IPG nibble counter settings
* specified in the Adaptec manual for full duplex and
@@ -643,13 +653,53 @@
#define SF_STATS_BASE 0x7000
#define SF_STATS_END 0x7FFF
+#define SF_STATS_TX_FRAMES 0x0000
+#define SF_STATS_TX_SINGLE_COL 0x0004
+#define SF_STATS_TX_MULTI_COL 0x0008
+#define SF_STATS_TX_CRC_ERRS 0x000C
+#define SF_STATS_TX_BYTES 0x0010
+#define SF_STATS_TX_DEFERRED 0x0014
+#define SF_STATS_TX_LATE_COL 0x0018
+#define SF_STATS_TX_PAUSE 0x001C
+#define SF_STATS_TX_CTL_FRAME 0x0020
+#define SF_STATS_TX_EXCESS_COL 0x0024
+#define SF_STATS_TX_EXCESS_DEF 0x0028
+#define SF_STATS_TX_MULTI 0x002C
+#define SF_STATS_TX_BCAST 0x0030
+#define SF_STATS_TX_FRAME_LOST 0x0034
+#define SF_STATS_RX_FRAMES 0x0038
+#define SF_STATS_RX_CRC_ERRS 0x003C
+#define SF_STATS_RX_ALIGN_ERRS 0x0040
+#define SF_STATS_RX_BYTES 0x0044
+#define SF_STATS_RX_PAUSE 0x0048
+#define SF_STATS_RX_CTL_FRAME 0x004C
+#define SF_STATS_RX_UNSUP_FRAME 0x0050
+#define SF_STATS_RX_GIANTS 0x0054
+#define SF_STATS_RX_RUNTS 0x0058
+#define SF_STATS_RX_JABBER 0x005C
+#define SF_STATS_RX_FRAGMENTS 0x0060
+#define SF_STATS_RX_64 0x0064
+#define SF_STATS_RX_65_127 0x0068
+#define SF_STATS_RX_128_255 0x006C
+#define SF_STATS_RX_256_511 0x0070
+#define SF_STATS_RX_512_1023 0x0074
+#define SF_STATS_RX_1024_1518 0x0078
+#define SF_STATS_RX_FRAME_LOST 0x007C
+#define SF_STATS_TX_UNDERRUN 0x0080
+
/*
* TX frame processor instruction space 0x8000 to 0x9FFF
*/
+#define SF_TXGFP_MEM_BASE 0x8000
+#define SF_TXGFP_MEM_END 0x8FFF
+/* Number of bytes of an GFP instruction. */
+#define SF_GFP_INST_BYTES 6
/*
* RX frame processor instruction space 0xA000 to 0xBFFF
*/
+#define SF_RXGFP_MEM_BASE 0xA000
+#define SF_RXGFP_MEM_END 0xBFFF
/*
* Ethernet FIFO access space 0xC000 to 0xDFFF
@@ -663,52 +713,31 @@
* Descriptor data structures.
*/
-
-/* Receive descriptor formats. */
-#define SF_RX_MINSPACING 8
-#define SF_RX_DLIST_CNT 256
-#define SF_RX_CLIST_CNT 1024
-#define SF_RX_HOSTADDR(x) (((x) >> 2) & 0x3FFFFFFF)
-
/*
- * RX buffer descriptor type 0, 32-bit addressing. Note that we
- * program the RX buffer queue control register(s) to allow a
- * descriptor spacing of 16 bytes, which leaves room after each
- * descriptor to store a pointer to the mbuf for each buffer.
+ * RX buffer descriptor type 0, 32-bit addressing.
*/
struct sf_rx_bufdesc_type0 {
- u_int32_t sf_valid:1,
- sf_end:1,
- sf_addrlo:30;
- u_int32_t sf_pad0;
-#ifdef __i386__
- u_int32_t sf_pad1;
-#endif
- struct mbuf *sf_mbuf;
+ uint32_t sf_addrlo;
+#define SF_RX_DESC_VALID 0x00000001
+#define SF_RX_DESC_END 0x00000002
};
/*
- * RX buffer descriptor type 0, 64-bit addressing.
+ * RX buffer descriptor type 1, 64-bit addressing.
*/
struct sf_rx_bufdesc_type1 {
- u_int32_t sf_valid:1,
- sf_end:1,
- sf_addrlo:30;
- u_int32_t sf_addrhi;
-#ifdef __i386__
- u_int32_t sf_pad;
-#endif
- struct mbuf *sf_mbuf;
+ uint64_t sf_addr;
};
/*
* RX completion descriptor, type 0 (short).
*/
struct sf_rx_cmpdesc_type0 {
- u_int32_t sf_len:16,
- sf_endidx:11,
- sf_status1:3,
- sf_id:2;
+ uint32_t sf_rx_status1;
+#define SF_RX_CMPDESC_LEN 0x0000ffff
+#define SF_RX_CMPDESC_EIDX 0x07ff0000
+#define SF_RX_CMPDESC_STAT1 0x38000000
+#define SF_RX_CMPDESC_ID 0x40000000
};
/*
@@ -716,12 +745,10 @@ struct sf_rx_cmpdesc_type0 {
* if this is a vlan-addressed packet, plus extended status.
*/
struct sf_rx_cmpdesc_type1 {
- u_int32_t sf_len:16,
- sf_endidx:11,
- sf_status1:3,
- sf_id:2;
- u_int16_t sf_status2;
- u_int16_t sf_vlanid;
+ uint32_t sf_rx_status1;
+ uint32_t sf_rx_status2;
+#define SF_RX_CMPDESC_VLAN 0x0000ffff
+#define SF_RX_CMPDESC_STAT2 0xffff0000
};
/*
@@ -729,12 +756,9 @@ struct sf_rx_cmpdesc_type1 {
* checksum instead of vlan tag, plus extended status.
*/
struct sf_rx_cmpdesc_type2 {
- u_int32_t sf_len:16,
- sf_endidx:11,
- sf_status1:3,
- sf_id:2;
- u_int16_t sf_status2;
- u_int16_t sf_cksum;
+ uint32_t sf_rx_status1;
+ uint32_t sf_rx_status2;
+#define SF_RX_CMPDESC_CSUM2 0x0000ffff
};
/*
@@ -742,81 +766,64 @@ struct sf_rx_cmpdesc_type2 {
* TCP/IP checksum, vlan tag plus priority, two extended status fields.
*/
struct sf_rx_cmpdesc_type3 {
- u_int32_t sf_len:16,
- sf_endidx:11,
- sf_status1:3,
- sf_id:2;
- u_int32_t sf_startidx:10,
- sf_status3:6,
- sf_status2:16;
- u_int16_t sf_cksum;
- u_int16_t sf_vlanid_prio;
- u_int32_t sf_timestamp;
+ uint32_t sf_rx_status1;
+ uint32_t sf_rx_status2;
+ uint32_t sf_rx_status3;
+#define SF_RX_CMPDESC_CSUM3 0xffff0000
+#define SF_RX_CMPDESC_VLANPRI 0x0000ffff
+ uint32_t sf_rx_timestamp;
};
-#define SF_RXSTAT1_QUEUE 0x1
-#define SF_RXSTAT1_FIFOFULL 0x2
-#define SF_RXSTAT1_OK 0x4
-
- /* 0=unknown,5=unsupported */
-#define SF_RXSTAT2_FRAMETYPE 0x0007 /* 1=IPv4,2=IPv2,3=IPX,4=ICMP */
-#define SF_RXSTAT2_UDP 0x0008
-#define SF_RXSTAT2_TCP 0x0010
-#define SF_RXSTAT2_FRAG 0x0020
-#define SF_RXSTAT2_PCSUM_OK 0x0040 /* partial checksum ok */
-#define SF_RXSTAT2_CSUM_BAD 0x0080 /* TCP/IP checksum bad */
-#define SF_RXSTAT2_CSUM_OK 0x0100 /* TCP/IP checksum ok */
-#define SF_RXSTAT2_VLAN 0x0200
-#define SF_RXSTAT2_BADRXCODE 0x0400
-#define SF_RXSTAT2_DRIBBLE 0x0800
-#define SF_RXSTAT2_ISL_CRCERR 0x1000
-#define SF_RXSTAT2_CRCERR 0x2000
-#define SF_RXSTAT2_HASH 0x4000
-#define SF_RXSTAT2_PERFECT 0x8000
-
-#define SF_RXSTAT3_TRAILER 0x01
-#define SF_RXSTAT3_HEADER 0x02
-#define SF_RXSTAT3_CONTROL 0x04
-#define SF_RXSTAT3_PAUSE 0x08
-#define SF_RXSTAT3_ISL 0x10
-
-/*
- * Transmit descriptor formats.
- * Each transmit descriptor type allows for a skip field at the
- * start of each structure. The size of the skip field can vary,
- * however we always set it for 8 bytes, which is enough to hold
- * a pointer (32 bits on x86, 64-bits on alpha) that we can use
- * to hold the address of the head of the mbuf chain for the
- * frame or fragment associated with the descriptor. This saves
- * us from having to create a separate pointer array to hold
- * the mbuf addresses.
- */
-#define SF_TX_BUFDESC_ID 0xB
-#define SF_MAXFRAGS 14
-#define SF_TX_MINSPACING 128
-#define SF_TX_DLIST_CNT 128
-#define SF_TX_DLIST_SIZE 16384
-#define SF_TX_SKIPLEN 1
-#define SF_TX_CLIST_CNT 1024
+#define SF_RXSTAT1_QUEUE 0x08000000
+#define SF_RXSTAT1_FIFOFULL 0x10000000
+#define SF_RXSTAT1_OK 0x20000000
+
+#define SF_RXSTAT2_FRAMETYPE_MASK 0x00070000
+#define SF_RXSTAT2_FRAMETYPE_UNKN 0x00000000
+#define SF_RXSTAT2_FRAMETYPE_IPV4 0x00010000
+#define SF_RXSTAT2_FRAMETYPE_IPV6 0x00020000
+#define SF_RXSTAT2_FRAMETYPE_IPX 0x00030000
+#define SF_RXSTAT2_FRAMETYPE_ICMP 0x00040000
+#define SF_RXSTAT2_FRAMETYPE_UNSPRT 0x00050000
+#define SF_RXSTAT2_UDP 0x00080000
+#define SF_RXSTAT2_TCP 0x00100000
+#define SF_RXSTAT2_FRAG 0x00200000
+#define SF_RXSTAT2_PCSUM_OK 0x00400000 /* partial checksum ok */
+#define SF_RXSTAT2_CSUM_BAD 0x00800000 /* TCP/IP checksum bad */
+#define SF_RXSTAT2_CSUM_OK 0x01000000 /* TCP/IP checksum ok */
+#define SF_RXSTAT2_VLAN 0x02000000
+#define SF_RXSTAT2_BADRXCODE 0x04000000
+#define SF_RXSTAT2_DRIBBLE 0x08000000
+#define SF_RXSTAT2_ISL_CRCERR 0x10000000
+#define SF_RXSTAT2_CRCERR 0x20000000
+#define SF_RXSTAT2_HASH 0x40000000
+#define SF_RXSTAT2_PERFECT 0x80000000
+#define SF_RXSTAT2_MASK 0xFFFF0000
+
+#define SF_RXSTAT3_ISL 0x00008000
+#define SF_RXSTAT3_PAUSE 0x00004000
+#define SF_RXSTAT3_CONTROL 0x00002000
+#define SF_RXSTAT3_HEADER 0x00001000
+#define SF_RXSTAT3_TRAILER 0x00000800
+#define SF_RXSTAT3_START_IDX_MASK 0x000007FF
struct sf_frag {
- u_int32_t sf_addr;
- u_int16_t sf_fraglen;
- u_int16_t sf_pktlen;
+ uint32_t sf_addr;
+ uint16_t sf_fraglen;
+ uint16_t sf_pktlen;
};
struct sf_frag_msdos {
- u_int16_t sf_pktlen;
- u_int16_t sf_fraglen;
- u_int32_t sf_addr;
+ uint16_t sf_pktlen;
+ uint16_t sf_fraglen;
+ uint32_t sf_addr;
};
/*
* TX frame descriptor type 0, 32-bit addressing. One descriptor can
- * be used to map multiple packet fragments. We use this format since
- * BSD networking fragments packet data across mbuf chains. Note that
- * the number of fragments can be variable depending on how the descriptor
- * spacing is specified in the TX descriptor queue control register.
+ * be used to map multiple packet fragments. Note that the number of
+ * fragments can be variable depending on how the descriptor spacing
+ * is specified in the TX descriptor queue control register.
* We always use a spacing of 128 bytes, and a skipfield length of 8
* bytes: this means 16 bytes for the descriptor, including the skipfield,
* with 121 bytes left for fragment maps. Each fragment requires 8 bytes,
@@ -825,20 +832,18 @@ struct sf_frag_msdos {
* 128 bytes per descriptor, we have room for 128 descriptors in the queue.
*/
struct sf_tx_bufdesc_type0 {
-#ifdef __i386__
- u_int32_t sf_pad;
-#endif
- struct mbuf *sf_mbuf;
- u_int32_t sf_rsvd0:24,
- sf_crcen:1,
- sf_caltcp:1,
- sf_end:1,
- sf_intr:1,
- sf_id:4;
- u_int8_t sf_fragcnt;
- u_int8_t sf_rsvd2;
- u_int16_t sf_rsvd1;
- struct sf_frag sf_frags[14];
+ uint32_t sf_tx_ctrl;
+#define SF_TX_DESC_CRCEN 0x01000000
+#define SF_TX_DESC_CALTCP 0x02000000
+#define SF_TX_DESC_END 0x04000000
+#define SF_TX_DESC_INTR 0x08000000
+#define SF_TX_DESC_ID 0xb0000000
+ uint32_t sf_tx_frag;
+ /*
+ * Depending on descriptor spacing/skip field length it
+ * can have fixed number of struct sf_frag.
+ * struct sf_frag sf_frags[14];
+ */
};
/*
@@ -846,18 +851,10 @@ struct sf_tx_bufdesc_type0 {
* maps a single fragment.
*/
struct sf_tx_bufdesc_type1 {
-#ifdef __i386__
- u_int32_t sf_pad;
-#endif
- struct mbuf *sf_mbuf;
- u_int32_t sf_fraglen:16,
- sf_fragcnt:8,
- sf_crcen:1,
- sf_caltcp:1,
- sf_end:1,
- sf_intr:1,
- sf_id:4;
- u_int32_t sf_addr;
+ uint32_t sf_tx_ctrl;
+#define SF_TX_DESC_FRAGLEN 0x0000ffff
+#define SF_TX_DESC_FRAGCNT 0x00ff0000
+ uint32_t sf_addrlo;
};
/*
@@ -865,19 +862,9 @@ struct sf_tx_bufdesc_type1 {
* maps a single fragment.
*/
struct sf_tx_bufdesc_type2 {
-#ifdef __i386__
- u_int32_t sf_pad;
-#endif
- struct mbuf *sf_mbuf;
- u_int32_t sf_fraglen:16,
- sf_fragcnt:8,
- sf_crcen:1,
- sf_caltcp:1,
- sf_end:1,
- sf_intr:1,
- sf_id:4;
- u_int32_t sf_addrlo;
- u_int32_t sf_addrhi;
+ uint32_t sf_tx_ctrl;
+ uint32_t sf_tx_reserved;
+ uint64_t sf_addr;
};
/* TX buffer descriptor type 3 is not defined. */
@@ -889,20 +876,14 @@ struct sf_tx_bufdesc_type2 {
* to optimize copies in MS-DOS and OS/2 drivers.
*/
struct sf_tx_bufdesc_type4 {
-#ifdef __i386__
- u_int32_t sf_pad;
-#endif
- struct mbuf *sf_mbuf;
- u_int32_t sf_rsvd0:24,
- sf_crcen:1,
- sf_caltcp:1,
- sf_end:1,
- sf_intr:1,
- sf_id:4;
- u_int8_t sf_fragcnt;
- u_int8_t sf_rsvd2;
- u_int16_t sf_rsvd1;
- struct sf_frag_msdos sf_frags[14];
+ uint32_t sf_tx_ctrl;
+ uint32_t sf_tx_frag;
+ /*
+ * Depending on descriptor spacing/skip field length it
+ * can have fixed number of struct sf_frag_msdos.
+ *
+ * struct sf_frag_msdos sf_frags[14];
+ */
};
/*
@@ -912,139 +893,203 @@ struct sf_tx_bufdesc_type4 {
/*
* Transmit DMA completion descriptor, type 0.
*/
-#define SF_TXCMPTYPE_DMA 0x4
+#define SF_TXCMPTYPE_DMA 0x80000000
+#define SF_TXCMPTYPE_TX 0xa0000000
struct sf_tx_cmpdesc_type0 {
- u_int32_t sf_index:15,
- sf_priority:1,
- sf_timestamp:13,
- sf_type:3;
+ uint32_t sf_tx_status1;
+#define SF_TX_CMPDESC_IDX 0x00007fff
+#define SF_TX_CMPDESC_HIPRI 0x00008000
+#define SF_TX_CMPDESC_STAT 0x1fff0000
+#define SF_TX_CMPDESC_TYPE 0xe0000000
};
/*
* Transmit completion descriptor, type 1.
*/
-#define SF_TXCMPTYPE_TX 0x5
struct sf_tx_cmpdesc_type1 {
- u_int32_t sf_index:15,
- sf_priority:1,
- sf_txstat:13,
- sf_type:3;
+ uint32_t sf_tx_status1;
+ uint32_t sf_tx_status2;
};
-#define SF_TXSTAT_CRCERR 0x0001
-#define SF_TXSTAT_LENCHECKERR 0x0002
-#define SF_TXSTAT_LENRANGEERR 0x0004
-#define SF_TXSTAT_TX_OK 0x0008
-#define SF_TXSTAT_TX_DEFERED 0x0010
-#define SF_TXSTAT_EXCESS_DEFER 0x0020
-#define SF_TXSTAT_EXCESS_COLL 0x0040
-#define SF_TXSTAT_LATE_COLL 0x0080
-#define SF_TXSTAT_TOOBIG 0x0100
-#define SF_TXSTAT_TX_UNDERRUN 0x0200
-#define SF_TXSTAT_CTLFRAME_OK 0x0400
-#define SF_TXSTAT_PAUSEFRAME_OK 0x0800
-#define SF_TXSTAT_PAUSED 0x1000
+#define SF_TXSTAT_CRCERR 0x00010000
+#define SF_TXSTAT_LENCHECKERR 0x00020000
+#define SF_TXSTAT_LENRANGEERR 0x00040000
+#define SF_TXSTAT_TX_OK 0x00080000
+#define SF_TXSTAT_TX_DEFERED 0x00100000
+#define SF_TXSTAT_EXCESS_DEFER 0x00200000
+#define SF_TXSTAT_EXCESS_COLL 0x00400000
+#define SF_TXSTAT_LATE_COLL 0x00800000
+#define SF_TXSTAT_TOOBIG 0x01000000
+#define SF_TXSTAT_TX_UNDERRUN 0x02000000
+#define SF_TXSTAT_CTLFRAME_OK 0x04000000
+#define SF_TXSTAT_PAUSEFRAME_OK 0x08000000
+#define SF_TXSTAT_PAUSED 0x10000000
/* Statistics counters. */
struct sf_stats {
- u_int32_t sf_tx_frames;
- u_int32_t sf_tx_single_colls;
- u_int32_t sf_tx_multi_colls;
- u_int32_t sf_tx_crcerrs;
- u_int32_t sf_tx_bytes;
- u_int32_t sf_tx_defered;
- u_int32_t sf_tx_late_colls;
- u_int32_t sf_tx_pause_frames;
- u_int32_t sf_tx_control_frames;
- u_int32_t sf_tx_excess_colls;
- u_int32_t sf_tx_excess_defer;
- u_int32_t sf_tx_mcast_frames;
- u_int32_t sf_tx_bcast_frames;
- u_int32_t sf_tx_frames_lost;
- u_int32_t sf_rx_rx_frames;
- u_int32_t sf_rx_crcerrs;
- u_int32_t sf_rx_alignerrs;
- u_int32_t sf_rx_bytes;
- u_int32_t sf_rx_control_frames;
- u_int32_t sf_rx_unsup_control_frames;
- u_int32_t sf_rx_giants;
- u_int32_t sf_rx_runts;
- u_int32_t sf_rx_jabbererrs;
- u_int32_t sf_rx_pkts_64;
- u_int32_t sf_rx_pkts_65_127;
- u_int32_t sf_rx_pkts_128_255;
- u_int32_t sf_rx_pkts_256_511;
- u_int32_t sf_rx_pkts_512_1023;
- u_int32_t sf_rx_pkts_1024_1518;
- u_int32_t sf_rx_frames_lost;
- u_int16_t sf_tx_underruns;
- u_int16_t sf_pad;
+ uint64_t sf_tx_frames;
+ uint32_t sf_tx_single_colls;
+ uint32_t sf_tx_multi_colls;
+ uint32_t sf_tx_crcerrs;
+ uint64_t sf_tx_bytes;
+ uint32_t sf_tx_deferred;
+ uint32_t sf_tx_late_colls;
+ uint32_t sf_tx_pause_frames;
+ uint32_t sf_tx_control_frames;
+ uint32_t sf_tx_excess_colls;
+ uint32_t sf_tx_excess_defer;
+ uint32_t sf_tx_mcast_frames;
+ uint32_t sf_tx_bcast_frames;
+ uint32_t sf_tx_frames_lost;
+ uint64_t sf_rx_frames;
+ uint32_t sf_rx_crcerrs;
+ uint32_t sf_rx_alignerrs;
+ uint64_t sf_rx_bytes;
+ uint32_t sf_rx_pause_frames;
+ uint32_t sf_rx_control_frames;
+ uint32_t sf_rx_unsup_control_frames;
+ uint32_t sf_rx_giants;
+ uint32_t sf_rx_runts;
+ uint32_t sf_rx_jabbererrs;
+ uint32_t sf_rx_fragments;
+ uint64_t sf_rx_pkts_64;
+ uint64_t sf_rx_pkts_65_127;
+ uint64_t sf_rx_pkts_128_255;
+ uint64_t sf_rx_pkts_256_511;
+ uint64_t sf_rx_pkts_512_1023;
+ uint64_t sf_rx_pkts_1024_1518;
+ uint32_t sf_rx_frames_lost;
+ uint32_t sf_tx_underruns;
+ uint32_t sf_tx_gfp_stall;
+ uint32_t sf_rx_gfp_stall;
};
/*
* register space access macros
*/
#define CSR_WRITE_4(sc, reg, val) \
- bus_space_write_4(sc->sf_btag, sc->sf_bhandle, reg, val)
+ bus_write_4((sc)->sf_res, reg, val)
#define CSR_READ_4(sc, reg) \
- bus_space_read_4(sc->sf_btag, sc->sf_bhandle, reg)
+ bus_read_4((sc)->sf_res, reg)
#define CSR_READ_1(sc, reg) \
- bus_space_read_1(sc->sf_btag, sc->sf_bhandle, reg)
+ bus_read_1((sc)->sf_res, reg)
struct sf_type {
- u_int16_t sf_vid;
- u_int16_t sf_did;
+ uint16_t sf_vid;
+ uint16_t sf_did;
char *sf_name;
+ uint16_t sf_sdid;
+ char *sf_sname;
};
-#define SF_INC(x, y) (x) = (x + 1) % y
+/* Use Tx descriptor type 2 : 64bit buffer descriptor */
+#define sf_tx_rdesc sf_tx_bufdesc_type2
+/* Use Rx descriptor type 1 : 64bit buffer descriptor */
+#define sf_rx_rdesc sf_rx_bufdesc_type1
+/* Use Tx completion type 0 */
+#define sf_tx_rcdesc sf_tx_cmpdesc_type0
+/* Use Rx completion type 2 : checksum */
+#define sf_rx_rcdesc sf_rx_cmpdesc_type2
-#define ETHER_ALIGN 2
+#define SF_TX_DLIST_CNT 256
+#define SF_RX_DLIST_CNT 256
+#define SF_TX_CLIST_CNT 1024
+#define SF_RX_CLIST_CNT 1024
+#define SF_TX_DLIST_SIZE (sizeof(struct sf_tx_rdesc) * SF_TX_DLIST_CNT)
+#define SF_TX_CLIST_SIZE (sizeof(struct sf_tx_rcdesc) * SF_TX_CLIST_CNT)
+#define SF_RX_DLIST_SIZE (sizeof(struct sf_rx_rdesc) * SF_RX_DLIST_CNT)
+#define SF_RX_CLIST_SIZE (sizeof(struct sf_rx_rcdesc) * SF_RX_CLIST_CNT)
+#define SF_RING_ALIGN 256
+#define SF_RX_ALIGN sizeof(uint32_t)
+#define SF_MAXTXSEGS 16
+
+#define SF_ADDR_LO(x) ((uint64_t)(x) & 0xffffffff)
+#define SF_ADDR_HI(x) ((uint64_t)(x) >> 32)
+#define SF_TX_DLIST_ADDR(sc, i) \
+ ((sc)->sf_rdata.sf_tx_ring_paddr + sizeof(struct sf_tx_rdesc) * (i))
+#define SF_TX_CLIST_ADDR(sc, i) \
+ ((sc)->sf_rdata.sf_tx_cring_paddr + sizeof(struct sf_tx_crdesc) * (i))
+#define SF_RX_DLIST_ADDR(sc, i) \
+ ((sc)->sf_rdata.sf_rx_ring_paddr + sizeof(struct sf_rx_rdesc) * (i))
+#define SF_RX_CLIST_ADDR(sc, i) \
+ ((sc)->sf_rdata.sf_rx_cring_paddr + sizeof(struct sf_rx_rcdesc) * (i))
+
+#define SF_INC(x, y) (x) = ((x) + 1) % y
+
+#define SF_MAX_FRAMELEN 1536
+#define SF_TX_THRESHOLD_UNIT 16
+#define SF_MAX_TX_THRESHOLD (SF_MAX_FRAMELEN / SF_TX_THRESHOLD_UNIT)
+#define SF_MIN_TX_THRESHOLD (128 / SF_TX_THRESHOLD_UNIT)
+
+struct sf_txdesc {
+ struct mbuf *tx_m;
+ int ndesc;
+ bus_dmamap_t tx_dmamap;
+};
-/*
- * Note: alignment is important here: each list must be aligned to
- * a 256-byte boundary. It turns out that each ring is some multiple
- * of 4K in length, so we can stack them all on top of each other
- * and just worry about aligning the whole mess. There's one transmit
- * buffer ring and two receive buffer rings: one RX ring is for small
- * packets and the other is for large packets. Each buffer ring also
- * has a companion completion queue.
- */
-struct sf_list_data {
- struct sf_tx_bufdesc_type0 sf_tx_dlist[SF_TX_DLIST_CNT];
- struct sf_tx_cmpdesc_type1 sf_tx_clist[SF_TX_CLIST_CNT];
- struct sf_rx_bufdesc_type0 sf_rx_dlist_big[SF_RX_DLIST_CNT];
-#ifdef notdef
- /*
- * Unfortunately, because the Starfire doesn't allow arbitrary
- * byte alignment, we have to copy packets in the RX handler in
- * order to align the payload correctly. This means that we
- * don't gain anything by having separate large and small descriptor
- * lists, so for now we don't bother with the small one.
- */
- struct sf_rx_bufdesc_type0 sf_rx_dlist_small[SF_RX_DLIST_CNT];
-#endif
- struct sf_rx_cmpdesc_type3 sf_rx_clist[SF_RX_CLIST_CNT];
+struct sf_rxdesc {
+ struct mbuf *rx_m;
+ bus_dmamap_t rx_dmamap;
};
+struct sf_chain_data {
+ bus_dma_tag_t sf_parent_tag;
+ bus_dma_tag_t sf_tx_tag;
+ struct sf_txdesc sf_txdesc[SF_TX_DLIST_CNT];
+ bus_dma_tag_t sf_rx_tag;
+ struct sf_rxdesc sf_rxdesc[SF_RX_DLIST_CNT];
+ bus_dma_tag_t sf_tx_ring_tag;
+ bus_dma_tag_t sf_rx_ring_tag;
+ bus_dma_tag_t sf_tx_cring_tag;
+ bus_dma_tag_t sf_rx_cring_tag;
+ bus_dmamap_t sf_tx_ring_map;
+ bus_dmamap_t sf_rx_ring_map;
+ bus_dmamap_t sf_rx_sparemap;
+ bus_dmamap_t sf_tx_cring_map;
+ bus_dmamap_t sf_rx_cring_map;
+ int sf_tx_prod;
+ int sf_tx_cnt;
+ int sf_txc_cons;
+ int sf_rxc_cons;
+};
+
+struct sf_ring_data {
+ struct sf_tx_rdesc *sf_tx_ring;
+ bus_addr_t sf_tx_ring_paddr;
+ struct sf_tx_rcdesc *sf_tx_cring;
+ bus_addr_t sf_tx_cring_paddr;
+ struct sf_rx_rdesc *sf_rx_ring;
+ bus_addr_t sf_rx_ring_paddr;
+ struct sf_rx_rcdesc *sf_rx_cring;
+ bus_addr_t sf_rx_cring_paddr;
+};
+
+
struct sf_softc {
struct ifnet *sf_ifp; /* interface info */
device_t sf_dev; /* device info */
- bus_space_handle_t sf_bhandle; /* bus space handle */
- bus_space_tag_t sf_btag; /* bus space tag */
void *sf_intrhand; /* interrupt handler cookie */
struct resource *sf_irq; /* irq resource descriptor */
struct resource *sf_res; /* mem/ioport resource */
+ int sf_restype;
+ int sf_rid;
struct sf_type *sf_info; /* Starfire adapter info */
device_t sf_miibus;
- struct sf_list_data *sf_ldata;
- int sf_tx_cnt;
- u_int8_t sf_link;
+ struct sf_chain_data sf_cdata;
+ struct sf_ring_data sf_rdata;
int sf_if_flags;
- struct callout sf_stat_callout;
+ struct callout sf_co;
+ int sf_watchdog_timer;
+ struct task sf_link_task;
+ int sf_link;
+ int sf_suspended;
+ int sf_detach;
+ uint32_t sf_txthresh;
+ int sf_int_mod;
+ struct sf_stats sf_statistics;
struct mtx sf_mtx;
#ifdef DEVICE_POLLING
int rxcycles;
OpenPOWER on IntegriCloud