Bring overhauled nfe(4) into tree.
o s/printf/device_printf/g o Nuke OpenBSDism. o Nuke NetBSD/OpenBSD specific DMA sync operations.(we don't have a way to sync a single descriptor within a DMA map.) o Remove recursive mutex. o bus_dma(9) clean up. o 40bit DMA address support. o Add protection for Rx map load failure. o Fix a long standing bug for watchdog timeout. [1] o Add additional protections, missing Tx completion interrupt, losing start Tx command, for watchdog timeout. o Switch to taskqueue(9) API to handle interrupts. o Use our own timer for watchdog instead of if_watchdog/if_timer interface. o Advertise VLAN header length/capability correctly to upper layer. o Remove excessive kernel stack consumption in nfe_encap(). o Handle highly fragmented mbuf chains correctly. o Enable etherenet address reprogramming with ifconfig(8). o Add ALTQ/TSO, MSI/MSIX support. o Increased Rx ring to 256 descriptors from 128. o Align Tx/Rx descriptor ring on sizeof(struct nfe_desc64) boundary. o Remove alignment restrictions on Tx/Rx buffers. o Rewritten jumbo frame support code. o Add support for hardware assistend VLAN tag insertion/stripping. o Add support for Tx/Rx flow control based on patches from Peer Chen. [2] o Add a routine that detects whether ethernet address swap routines is required. [3] o Add a workaround that take MAC/PHY out of power down mode. o Add suspend/resume support. o style(9) and code clean up. Special thanks to Shigeaki Tagashira, the original porter of nfe(4), who submitted lots of patches, performed uncountable number of regression tests and maintained nfe(4) for a long time. Without his enthusiastic help and support I could never have completed this overhauling task. The only weak point of nfe(4) compared to nve(4) is instability of manual half-duplex media selection on certain hardwares(auto sensing media type should work for all cases, though). This was a long standing bug of nfe(4) and I still have no idea why it doesn't work on some hardwares. Obtained from: OpenBSD [1] Submitted by: Peer Chen < pchen at nvidia dot com > [2], [3] Reviewed by: Shigeaki Tagashira < shigeaki AT se DOT hiroshima-u DOT ac DOT jp > Tested by: Shigeaki Tagashira, current Discussed with: current Silence from: obrien
This commit is contained in:
parent
ec6a039b62
commit
36a63ea429
2872
sys/dev/nfe/if_nfe.c
2872
sys/dev/nfe/if_nfe.c
File diff suppressed because it is too large
Load Diff
@ -18,26 +18,47 @@
|
||||
* $FreeBSD$
|
||||
*/
|
||||
|
||||
#define NFE_PCI_BA 0x10
|
||||
|
||||
#define NFE_RX_RING_COUNT 128
|
||||
#define NFE_RX_RING_COUNT 256
|
||||
#define NFE_JUMBO_RX_RING_COUNT NFE_RX_RING_COUNT
|
||||
#define NFE_TX_RING_COUNT 256
|
||||
|
||||
#define NFE_PROC_DEFAULT ((NFE_RX_RING_COUNT * 3) / 4)
|
||||
#define NFE_PROC_MIN 50
|
||||
#define NFE_PROC_MAX (NFE_RX_RING_COUNT - 1)
|
||||
|
||||
#define NFE_INC(x, y) (x) = ((x) + 1) % y
|
||||
|
||||
/* RX/TX MAC addr + type + VLAN + align + slack */
|
||||
#define NFE_RX_HEADERS 64
|
||||
|
||||
/* Maximum MTU size. */
|
||||
#define NV_PKTLIMIT_1 ETH_DATA_LEN /* Hard limit not known. */
|
||||
#define NV_PKTLIMIT_2 9100 /* Actual limit according to NVidia:9202 */
|
||||
#define NFE_JBYTES (ETHER_MAX_LEN_JUMBO + ETHER_ALIGN)
|
||||
#define NFE_JPOOL_COUNT (NFE_RX_RING_COUNT + NFE_RX_HEADERS)
|
||||
|
||||
#define NFE_MAX_SCATTER (NFE_TX_RING_COUNT - 2)
|
||||
#define NFE_JUMBO_FRAMELEN NV_PKTLIMIT_2
|
||||
#define NFE_JUMBO_MTU \
|
||||
(NFE_JUMBO_FRAMELEN - NFE_RX_HEADERS)
|
||||
#define NFE_MIN_FRAMELEN (ETHER_MIN_LEN - ETHER_CRC_LEN)
|
||||
#define NFE_JSLOTS ((NFE_JUMBO_RX_RING_COUNT * 3) / 2)
|
||||
|
||||
#define NFE_JRAWLEN (NFE_JUMBO_FRAMELEN + ETHER_ALIGN)
|
||||
#define NFE_JLEN \
|
||||
(NFE_JRAWLEN + (sizeof(uint64_t) - (NFE_JRAWLEN % sizeof(uint64_t))))
|
||||
#define NFE_JPAGESZ PAGE_SIZE
|
||||
#define NFE_RESID \
|
||||
(NFE_JPAGESZ - (NFE_JLEN * NFE_JSLOTS) % NFE_JPAGESZ)
|
||||
#define NFE_JMEM ((NFE_JLEN * NFE_JSLOTS) + NFE_RESID)
|
||||
|
||||
#define NFE_MAX_SCATTER 32
|
||||
|
||||
#define NFE_IRQ_STATUS 0x000
|
||||
#define NFE_IRQ_MASK 0x004
|
||||
#define NFE_SETUP_R6 0x008
|
||||
#define NFE_IMTIMER 0x00c
|
||||
#define NFE_MSI_MAP0 0x020
|
||||
#define NFE_MSI_MAP1 0x024
|
||||
#define NFE_MSI_IRQ_MASK 0x030
|
||||
#define NFE_MAC_RESET 0x03c
|
||||
#define NFE_MISC1 0x080
|
||||
#define NFE_TX_CTL 0x084
|
||||
#define NFE_TX_STATUS 0x088
|
||||
@ -66,6 +87,7 @@
|
||||
#define NFE_RXTX_CTL 0x144
|
||||
#define NFE_TX_RING_ADDR_HI 0x148
|
||||
#define NFE_RX_RING_ADDR_HI 0x14c
|
||||
#define NFE_TX_PAUSE_FRAME 0x170
|
||||
#define NFE_PHY_STATUS 0x180
|
||||
#define NFE_SETUP_R4 0x184
|
||||
#define NFE_STATUS 0x188
|
||||
@ -78,6 +100,14 @@
|
||||
#define NFE_PWR_CAP 0x268
|
||||
#define NFE_PWR_STATE 0x26c
|
||||
#define NFE_VTAG_CTL 0x300
|
||||
#define NFE_MSIX_MAP0 0x3e0
|
||||
#define NFE_MSIX_MAP1 0x3e4
|
||||
#define NFE_MSIX_IRQ_STATUS 0x3f0
|
||||
#define NFE_PWR2_CTL 0x600
|
||||
|
||||
#define NFE_MAC_RESET_MAGIC 0x00f3
|
||||
|
||||
#define NFE_MAC_ADDR_INORDER 0x8000
|
||||
|
||||
#define NFE_PHY_ERROR 0x00001
|
||||
#define NFE_PHY_WRITE 0x00400
|
||||
@ -86,7 +116,9 @@
|
||||
|
||||
#define NFE_STATUS_MAGIC 0x140000
|
||||
|
||||
#define NFE_R1_MAGIC 0x16070f
|
||||
#define NFE_R1_MAGIC_1000 0x14050f
|
||||
#define NFE_R1_MAGIC_10_100 0x16070f
|
||||
#define NFE_R1_MAGIC_DEFAULT 0x15050f
|
||||
#define NFE_R2_MAGIC 0x16
|
||||
#define NFE_R4_MAGIC 0x08
|
||||
#define NFE_R6_MAGIC 0x03
|
||||
@ -118,9 +150,11 @@
|
||||
#define NFE_RXTX_RXCSUM 0x0400
|
||||
#define NFE_RXTX_V2MAGIC 0x2100
|
||||
#define NFE_RXTX_V3MAGIC 0x2200
|
||||
#define NFE_RXFILTER_MAGIC 0x007f0008
|
||||
#define NFE_U2M (1 << 5)
|
||||
#define NFE_PROMISC (1 << 7)
|
||||
#define NFE_RXFILTER_MAGIC 0x007f0000
|
||||
#define NFE_PFF_RX_PAUSE (1 << 3)
|
||||
#define NFE_PFF_LOOPBACK (1 << 4)
|
||||
#define NFE_PFF_U2M (1 << 5)
|
||||
#define NFE_PFF_PROMISC (1 << 7)
|
||||
#define NFE_CSUM_FEATURES (CSUM_IP | CSUM_TCP | CSUM_UDP)
|
||||
|
||||
/* default interrupt moderation timer of 128us */
|
||||
@ -131,6 +165,9 @@
|
||||
#define NFE_PWR_VALID (1 << 8)
|
||||
#define NFE_PWR_WAKEUP (1 << 15)
|
||||
|
||||
#define NFE_PWR2_WAKEUP_MASK 0x0f11
|
||||
#define NFE_PWR2_REVA3 (1 << 0)
|
||||
|
||||
#define NFE_MEDIA_SET 0x10000
|
||||
#define NFE_MEDIA_1000T 0x00032
|
||||
#define NFE_MEDIA_100TX 0x00064
|
||||
@ -141,13 +178,32 @@
|
||||
#define NFE_PHY_HDX (1 << 8)
|
||||
|
||||
#define NFE_MISC1_MAGIC 0x003b0f3c
|
||||
#define NFE_MISC1_TX_PAUSE (1 << 0)
|
||||
#define NFE_MISC1_HDX (1 << 1)
|
||||
|
||||
#define NFE_TX_PAUSE_FRAME_DISABLE 0x1ff0080
|
||||
#define NFE_TX_PAUSE_FRAME_ENABLE 0x0c00030
|
||||
|
||||
#define NFE_SEED_MASK 0x0003ff00
|
||||
#define NFE_SEED_10T 0x00007f00
|
||||
#define NFE_SEED_100TX 0x00002d00
|
||||
#define NFE_SEED_1000T 0x00007400
|
||||
|
||||
#define NFE_MSI_MESSAGES 8
|
||||
#define NFE_MSI_VECTOR_0_ENABLED 0x01
|
||||
|
||||
/*
|
||||
* It seems that nForce supports only the lower 40 bits of a DMA address.
|
||||
*/
|
||||
#if (BUS_SPACE_MAXADDR < 0xFFFFFFFFFF)
|
||||
#define NFE_DMA_MAXADDR BUS_SPACE_MAXADDR
|
||||
#else
|
||||
#define NFE_DMA_MAXADDR 0xFFFFFFFFFF
|
||||
#endif
|
||||
|
||||
#define NFE_ADDR_LO(x) ((u_int64_t) (x) & 0xffffffff)
|
||||
#define NFE_ADDR_HI(x) ((u_int64_t) (x) >> 32)
|
||||
|
||||
/* Rx/Tx descriptor */
|
||||
struct nfe_desc32 {
|
||||
uint32_t physaddr;
|
||||
@ -179,9 +235,6 @@ struct nfe_desc64 {
|
||||
#define NFE_RX_VALID_V2 (1 << 13)
|
||||
#define NFE_TX_ERROR_V2 0x5c04
|
||||
#define NFE_TX_LASTFRAG_V2 (1 << 13)
|
||||
#define NFE_RX_IP_CSUMOK_V2 0x1000
|
||||
#define NFE_RX_UDP_CSUMOK_V2 0x1400
|
||||
#define NFE_RX_TCP_CSUMOK_V2 0x1800
|
||||
#define NFE_RX_ERROR1_V2 (1<<2)
|
||||
#define NFE_RX_ERROR2_V2 (1<<3)
|
||||
#define NFE_RX_ERROR3_V2 (1<<4)
|
||||
@ -191,19 +244,28 @@ struct nfe_desc64 {
|
||||
#define NFE_V2_TXERR "\020" \
|
||||
"\14FORCEDINT\13LASTPACKET\12UNDERFLOW\10LOSTCARRIER\09DEFERRED\02RETRY"
|
||||
|
||||
#define NFE_RING_ALIGN (sizeof(struct nfe_desc64))
|
||||
|
||||
/* flags common to V1/V2 descriptors */
|
||||
#define NFE_RX_CSUMOK 0x1c00
|
||||
#define NFE_RX_UDP_CSUMOK (1 << 10)
|
||||
#define NFE_RX_TCP_CSUMOK (1 << 11)
|
||||
#define NFE_RX_IP_CSUMOK (1 << 12)
|
||||
#define NFE_RX_ERROR (1 << 14)
|
||||
#define NFE_RX_READY (1 << 15)
|
||||
#define NFE_TX_TCP_CSUM (1 << 10)
|
||||
#define NFE_RX_LEN_MASK 0x3fff
|
||||
#define NFE_TX_TCP_UDP_CSUM (1 << 10)
|
||||
#define NFE_TX_IP_CSUM (1 << 11)
|
||||
#define NFE_TX_TSO (1 << 12)
|
||||
#define NFE_TX_TSO_SHIFT 14
|
||||
#define NFE_TX_VALID (1 << 15)
|
||||
|
||||
#define NFE_READ(sc, reg) \
|
||||
bus_space_read_4((sc)->nfe_memt, (sc)->nfe_memh, (reg))
|
||||
bus_read_4((sc)->nfe_res[0], (reg))
|
||||
|
||||
#define NFE_WRITE(sc, reg, val) \
|
||||
bus_space_write_4((sc)->nfe_memt, (sc)->nfe_memh, (reg), (val))
|
||||
bus_write_4((sc)->nfe_res[0], (reg), (val))
|
||||
|
||||
#define NFE_TIMEOUT 1000
|
||||
|
||||
#ifndef PCI_VENDOR_NVIDIA
|
||||
#define PCI_VENDOR_NVIDIA 0x10DE
|
||||
@ -232,6 +294,10 @@ struct nfe_desc64 {
|
||||
#define PCI_PRODUCT_NVIDIA_MCP65_LAN2 0x0451
|
||||
#define PCI_PRODUCT_NVIDIA_MCP65_LAN3 0x0452
|
||||
#define PCI_PRODUCT_NVIDIA_MCP65_LAN4 0x0453
|
||||
#define PCI_PRODUCT_NVIDIA_MCP67_LAN1 0x054c
|
||||
#define PCI_PRODUCT_NVIDIA_MCP67_LAN2 0x054d
|
||||
#define PCI_PRODUCT_NVIDIA_MCP67_LAN3 0x054e
|
||||
#define PCI_PRODUCT_NVIDIA_MCP67_LAN4 0x054f
|
||||
|
||||
#define PCI_PRODUCT_NVIDIA_NFORCE3_LAN2 PCI_PRODUCT_NVIDIA_NFORCE2_400_LAN1
|
||||
#define PCI_PRODUCT_NVIDIA_NFORCE3_LAN3 PCI_PRODUCT_NVIDIA_NFORCE2_400_LAN2
|
||||
|
@ -18,110 +18,120 @@
|
||||
* $FreeBSD$
|
||||
*/
|
||||
|
||||
#define NFE_IFQ_MAXLEN 64
|
||||
|
||||
struct nfe_tx_data {
|
||||
bus_dmamap_t tx_data_map;
|
||||
bus_dmamap_t active;
|
||||
int nsegs;
|
||||
struct mbuf *m;
|
||||
};
|
||||
|
||||
struct nfe_tx_ring {
|
||||
bus_dma_tag_t tx_desc_tag;
|
||||
bus_dmamap_t tx_desc_map;
|
||||
bus_dma_segment_t tx_desc_segs;
|
||||
bus_addr_t physaddr;
|
||||
struct nfe_desc32 *desc32;
|
||||
struct nfe_desc64 *desc64;
|
||||
bus_dma_tag_t tx_data_tag;
|
||||
struct nfe_tx_data data[NFE_TX_RING_COUNT];
|
||||
int queued;
|
||||
int cur;
|
||||
int next;
|
||||
bus_addr_t tx_desc_addr;
|
||||
bus_addr_t tx_data_addr;
|
||||
bus_dma_tag_t tx_desc_tag;
|
||||
bus_dma_tag_t tx_data_tag;
|
||||
};
|
||||
|
||||
struct nfe_jbuf {
|
||||
caddr_t buf;
|
||||
bus_addr_t physaddr;
|
||||
SLIST_ENTRY(nfe_jbuf) jnext;
|
||||
struct nfe_jpool_entry {
|
||||
int slot;
|
||||
SLIST_ENTRY(nfe_jpool_entry) jpool_entries;
|
||||
};
|
||||
|
||||
struct nfe_rx_data {
|
||||
bus_dmamap_t rx_data_map;
|
||||
bus_dma_tag_t rx_data_tag;
|
||||
bus_addr_t rx_data_addr;
|
||||
bus_dma_segment_t rx_data_segs;
|
||||
bus_addr_t paddr;
|
||||
struct mbuf *m;
|
||||
};
|
||||
|
||||
struct nfe_rx_ring {
|
||||
bus_dma_tag_t rx_desc_tag;
|
||||
bus_dmamap_t rx_desc_map;
|
||||
bus_dma_segment_t rx_desc_segs;
|
||||
bus_dma_tag_t rx_desc_tag;
|
||||
bus_addr_t rx_desc_addr;
|
||||
#ifndef JMBUF
|
||||
bus_dmamap_t rx_jumbo_map;
|
||||
bus_dma_segment_t rx_jumbo_segs;
|
||||
bus_dma_tag_t rx_jumbo_tag;
|
||||
bus_addr_t rx_jumbo_addr;
|
||||
caddr_t jpool;
|
||||
struct nfe_jbuf jbuf[NFE_JPOOL_COUNT];
|
||||
SLIST_HEAD(, nfe_jbuf) jfreelist;
|
||||
#endif
|
||||
bus_addr_t physaddr;
|
||||
struct nfe_desc32 *desc32;
|
||||
struct nfe_desc64 *desc64;
|
||||
bus_dma_tag_t rx_data_tag;
|
||||
bus_dmamap_t rx_spare_map;
|
||||
struct nfe_rx_data data[NFE_RX_RING_COUNT];
|
||||
int bufsz;
|
||||
int cur;
|
||||
int next;
|
||||
};
|
||||
|
||||
struct nfe_jrx_ring {
|
||||
bus_dma_tag_t jrx_desc_tag;
|
||||
bus_dmamap_t jrx_desc_map;
|
||||
bus_dma_tag_t jrx_jumbo_tag;
|
||||
bus_dmamap_t jrx_jumbo_map;
|
||||
void *jpool;
|
||||
caddr_t jslots[NFE_JSLOTS];
|
||||
bus_addr_t jphysaddr;
|
||||
struct nfe_desc32 *jdesc32;
|
||||
struct nfe_desc64 *jdesc64;
|
||||
bus_dma_tag_t jrx_data_tag;
|
||||
bus_dmamap_t jrx_spare_map;
|
||||
struct nfe_rx_data jdata[NFE_JUMBO_RX_RING_COUNT];
|
||||
int jcur;
|
||||
int jnext;
|
||||
};
|
||||
|
||||
struct nfe_softc {
|
||||
struct ifnet *nfe_ifp;
|
||||
device_t nfe_dev;
|
||||
uint16_t nfe_devid;
|
||||
uint16_t nfe_revid;
|
||||
device_t nfe_miibus;
|
||||
struct mtx nfe_mtx;
|
||||
bus_space_handle_t nfe_memh;
|
||||
bus_space_tag_t nfe_memt;
|
||||
struct resource *nfe_res;
|
||||
struct resource *nfe_irq;
|
||||
void *nfe_intrhand;
|
||||
struct mii_data nfe_mii;
|
||||
u_int8_t nfe_unit;
|
||||
struct resource *nfe_res[1];
|
||||
struct resource *nfe_msix_res;
|
||||
struct resource *nfe_msix_pba_res;
|
||||
struct resource *nfe_irq[NFE_MSI_MESSAGES];
|
||||
void *nfe_intrhand[NFE_MSI_MESSAGES];
|
||||
struct callout nfe_stat_ch;
|
||||
int nfe_watchdog_timer;
|
||||
|
||||
struct arpcom nfe_arpcom;
|
||||
bus_dma_tag_t nfe_parent_tag;
|
||||
/* struct timeout nfe_tick_ch; */
|
||||
void *nfe_powerhook;
|
||||
|
||||
int nfe_if_flags;
|
||||
u_int nfe_flags;
|
||||
#define NFE_JUMBO_SUP 0x01
|
||||
#define NFE_40BIT_ADDR 0x02
|
||||
#define NFE_HW_CSUM 0x04
|
||||
#define NFE_HW_VLAN 0x08
|
||||
u_int32_t rxtxctl;
|
||||
u_int32_t nfe_mtu;
|
||||
u_int8_t mii_phyaddr;
|
||||
u_char eaddr[ETHER_ADDR_LEN];
|
||||
struct task nfe_txtask;
|
||||
uint32_t nfe_flags;
|
||||
#define NFE_JUMBO_SUP 0x0001
|
||||
#define NFE_40BIT_ADDR 0x0002
|
||||
#define NFE_HW_CSUM 0x0004
|
||||
#define NFE_HW_VLAN 0x0008
|
||||
#define NFE_PWR_MGMT 0x0010
|
||||
#define NFE_CORRECT_MACADDR 0x0020
|
||||
#define NFE_TX_FLOW_CTRL 0x0040
|
||||
uint32_t rxtxctl;
|
||||
uint8_t mii_phyaddr;
|
||||
uint8_t eaddr[ETHER_ADDR_LEN];
|
||||
struct taskqueue *nfe_tq;
|
||||
struct task nfe_int_task;
|
||||
struct task nfe_tx_task;
|
||||
struct task nfe_link_task;
|
||||
int nfe_link;
|
||||
int nfe_suspended;
|
||||
int nfe_framesize;
|
||||
int nfe_process_limit;
|
||||
int nfe_force_tx;
|
||||
uint32_t nfe_irq_status;
|
||||
uint32_t nfe_irq_mask;
|
||||
uint32_t nfe_intrs;
|
||||
uint32_t nfe_nointrs;
|
||||
uint32_t nfe_msi;
|
||||
uint32_t nfe_msix;
|
||||
|
||||
struct nfe_tx_ring txq;
|
||||
struct nfe_rx_ring rxq;
|
||||
|
||||
#ifdef DEVICE_POLLING
|
||||
int rxcycles;
|
||||
#endif
|
||||
struct nfe_jrx_ring jrxq;
|
||||
SLIST_HEAD(__nfe_jfreehead, nfe_jpool_entry) nfe_jfree_listhead;
|
||||
SLIST_HEAD(__nfe_jinusehead, nfe_jpool_entry) nfe_jinuse_listhead;
|
||||
struct mtx nfe_jlist_mtx;
|
||||
};
|
||||
|
||||
struct nfe_type {
|
||||
u_int16_t vid_id;
|
||||
u_int16_t dev_id;
|
||||
uint16_t vid_id;
|
||||
uint16_t dev_id;
|
||||
char *name;
|
||||
};
|
||||
|
Loading…
Reference in New Issue
Block a user