Additional features for the tsec(4) Ethernet driver.
- interrupt coalescing - polling - jumbo frames - multicast - VLAN tagging The enhanced version of the chip (eTSEC) can also take advantage of: - TCP/IP checksum calculation h/w offloading Obtained from: Freescale, Semihalf
This commit is contained in:
parent
553bf6a453
commit
bd37530ee4
File diff suppressed because it is too large
Load Diff
@ -31,6 +31,17 @@
|
||||
#define TSEC_RX_NUM_DESC 256
|
||||
#define TSEC_TX_NUM_DESC 256
|
||||
|
||||
/* Interrupt Coalescing types */
|
||||
#define TSEC_IC_RX 0
|
||||
#define TSEC_IC_TX 1
|
||||
|
||||
/* eTSEC ID */
|
||||
#define TSEC_ETSEC_ID 0x0124
|
||||
|
||||
/* Frame sizes */
|
||||
#define TSEC_MIN_FRAME_SIZE 64
|
||||
#define TSEC_MAX_FRAME_SIZE 9600
|
||||
|
||||
struct tsec_softc {
|
||||
/* XXX MII bus requires that struct ifnet is first!!! */
|
||||
struct ifnet *tsec_ifp;
|
||||
@ -84,6 +95,7 @@ struct tsec_softc {
|
||||
int sc_error_irid;
|
||||
|
||||
int tsec_if_flags;
|
||||
int is_etsec;
|
||||
|
||||
/* Watchdog and MII tick related */
|
||||
struct callout tsec_callout;
|
||||
@ -106,6 +118,16 @@ struct tsec_softc {
|
||||
uint32_t tx_mbuf_used_get_cnt;
|
||||
uint32_t tx_mbuf_used_put_cnt;
|
||||
struct mbuf *tx_mbuf_used_data[TSEC_TX_NUM_DESC];
|
||||
|
||||
/* interrupt coalescing */
|
||||
struct mtx ic_lock;
|
||||
uint32_t rx_ic_time; /* RW, valid values 0..65535 */
|
||||
uint32_t rx_ic_count; /* RW, valid values 0..255 */
|
||||
uint32_t tx_ic_time;
|
||||
uint32_t tx_ic_count;
|
||||
|
||||
/* currently received frame */
|
||||
struct mbuf *frame;
|
||||
};
|
||||
|
||||
/* interface to get/put generic objects */
|
||||
@ -235,14 +257,23 @@ struct tsec_softc {
|
||||
#define TSEC_TRANSMIT_LOCK_ASSERT(sc) mtx_assert(&(sc)->transmit_lock, MA_OWNED)
|
||||
|
||||
/* Lock for receiver */
|
||||
#define TSEC_RECEIVE_LOCK(sc) do { \
|
||||
mtx_assert(&(sc)->transmit_lock, MA_NOTOWNED); \
|
||||
mtx_lock(&(sc)->receive_lock); \
|
||||
#define TSEC_RECEIVE_LOCK(sc) do { \
|
||||
mtx_assert(&(sc)->transmit_lock, MA_NOTOWNED); \
|
||||
mtx_lock(&(sc)->receive_lock); \
|
||||
} while (0)
|
||||
|
||||
#define TSEC_RECEIVE_UNLOCK(sc) mtx_unlock(&(sc)->receive_lock)
|
||||
#define TSEC_RECEIVE_LOCK_ASSERT(sc) mtx_assert(&(sc)->receive_lock, MA_OWNED)
|
||||
|
||||
/* Lock for interrupts coalescing */
|
||||
#define TSEC_IC_LOCK(sc) do { \
|
||||
mtx_assert(&(sc)->ic_lock, MA_NOTOWNED); \
|
||||
mtx_lock(&(sc)->ic_lock); \
|
||||
} while (0)
|
||||
|
||||
#define TSEC_IC_UNLOCK(sc) mtx_unlock(&(sc)->ic_lock)
|
||||
#define TSEC_IC_LOCK_ASSERT(sc) mtx_assert(&(sc)->ic_lock, MA_OWNED)
|
||||
|
||||
/* Global tsec lock (with all locks) */
|
||||
#define TSEC_GLOBAL_LOCK(sc) do { \
|
||||
if ((mtx_owned(&(sc)->transmit_lock) ? 1 : 0) != \
|
||||
@ -273,14 +304,49 @@ struct tsec_softc {
|
||||
} while (0)
|
||||
|
||||
struct tsec_desc {
|
||||
volatile uint16_t flags; /* descriptor flags */
|
||||
volatile uint16_t length; /* buffer length */
|
||||
volatile uint32_t bufptr; /* buffer pointer */
|
||||
volatile uint16_t flags; /* descriptor flags */
|
||||
volatile uint16_t length; /* buffer length */
|
||||
volatile uint32_t bufptr; /* buffer pointer */
|
||||
};
|
||||
|
||||
#define TSEC_READ_RETRY 10000
|
||||
#define TSEC_READ_DELAY 100
|
||||
|
||||
/* Structures and defines for TCP/IP Off-load */
|
||||
struct tsec_tx_fcb {
|
||||
volatile uint16_t flags;
|
||||
volatile uint8_t l4_offset;
|
||||
volatile uint8_t l3_offset;
|
||||
volatile uint16_t ph_chsum;
|
||||
volatile uint16_t vlan;
|
||||
};
|
||||
|
||||
struct tsec_rx_fcb {
|
||||
volatile uint16_t flags;
|
||||
volatile uint8_t rq_index;
|
||||
volatile uint8_t protocol;
|
||||
volatile uint16_t unused;
|
||||
volatile uint16_t vlan;
|
||||
};
|
||||
|
||||
#define TSEC_CHECKSUM_FEATURES (CSUM_IP | CSUM_TCP | CSUM_UDP)
|
||||
|
||||
#define TSEC_TX_FCB_IP4 TSEC_TX_FCB_L3_IS_IP
|
||||
#define TSEC_TX_FCB_IP6 (TSEC_TX_FCB_L3_IS_IP | TSEC_TX_FCB_L3_IS_IP6)
|
||||
|
||||
#define TSEC_TX_FCB_TCP TSEC_TX_FCB_L4_IS_TCP_UDP
|
||||
#define TSEC_TX_FCB_UDP (TSEC_TX_FCB_L4_IS_TCP_UDP | TSEC_TX_FCB_L4_IS_UDP)
|
||||
|
||||
#define TSEC_RX_FCB_IP_CSUM_CHECKED(flags) \
|
||||
((flags & (TSEC_RX_FCB_IP_FOUND | TSEC_RX_FCB_IP6_FOUND | \
|
||||
TSEC_RX_FCB_IP_CSUM | TSEC_RX_FCB_PARSE_ERROR)) \
|
||||
== (TSEC_RX_FCB_IP_FOUND | TSEC_RX_FCB_IP_CSUM))
|
||||
|
||||
#define TSEC_RX_FCB_TCP_UDP_CSUM_CHECKED(flags) \
|
||||
((flags & (TSEC_RX_FCB_TCP_UDP_FOUND | TSEC_RX_FCB_TCP_UDP_CSUM \
|
||||
| TSEC_RX_FCB_PARSE_ERROR)) \
|
||||
== (TSEC_RX_FCB_TCP_UDP_FOUND | TSEC_RX_FCB_TCP_UDP_CSUM))
|
||||
|
||||
/* Prototypes */
|
||||
extern devclass_t tsec_devclass;
|
||||
|
||||
|
@ -134,15 +134,23 @@ tsec_ocp_probe(device_t dev)
|
||||
sc->sc_bas.bsh = rman_get_bushandle(sc->sc_rres);
|
||||
sc->sc_bas.bst = rman_get_bustag(sc->sc_rres);
|
||||
|
||||
/* Check that we actually have a TSEC at this address */
|
||||
id = TSEC_READ(sc, TSEC_REG_ID) | TSEC_READ(sc, TSEC_REG_ID2);
|
||||
/* Check if we are eTSEC (enhanced TSEC) */
|
||||
id = TSEC_READ(sc, TSEC_REG_ID);
|
||||
sc->is_etsec = ((id >> 16) == TSEC_ETSEC_ID) ? 1 : 0;
|
||||
id |= TSEC_READ(sc, TSEC_REG_ID2);
|
||||
|
||||
bus_release_resource(dev, SYS_RES_MEMORY, sc->sc_rrid, sc->sc_rres);
|
||||
|
||||
if (id == 0)
|
||||
if (id == 0) {
|
||||
device_printf(dev, "could not identify TSEC type\n");
|
||||
return (ENXIO);
|
||||
}
|
||||
|
||||
if (sc->is_etsec)
|
||||
device_set_desc(dev, "Enhanced Three-Speed Ethernet Controller");
|
||||
else
|
||||
device_set_desc(dev, "Three-Speed Ethernet Controller");
|
||||
|
||||
device_set_desc(dev, "Three-Speed Ethernet Controller");
|
||||
return (BUS_PROBE_DEFAULT);
|
||||
}
|
||||
|
||||
@ -167,6 +175,8 @@ tsec_ocp_attach(device_t dev)
|
||||
MTX_DEF);
|
||||
mtx_init(&sc->receive_lock, device_get_nameunit(dev), "TSEC RX lock",
|
||||
MTX_DEF);
|
||||
mtx_init(&sc->ic_lock, device_get_nameunit(dev), "TSEC IC lock",
|
||||
MTX_DEF);
|
||||
|
||||
/* Allocate IO memory for TSEC registers */
|
||||
sc->sc_rrid = 0;
|
||||
@ -300,6 +310,7 @@ tsec_ocp_detach(device_t dev)
|
||||
/* Destroy locks */
|
||||
mtx_destroy(&sc->receive_lock);
|
||||
mtx_destroy(&sc->transmit_lock);
|
||||
mtx_destroy(&sc->ic_lock);
|
||||
return (0);
|
||||
}
|
||||
|
||||
|
@ -1,9 +1,8 @@
|
||||
/*-
|
||||
* Copyright (C) 2006-2007 Semihalf
|
||||
* Copyright (C) 2008-2009 Semihalf, Piotr Ziecik
|
||||
* Copyright (C) 2006-2007 Semihalf, Piotr Kruszynski
|
||||
* All rights reserved.
|
||||
*
|
||||
* Written by: Piotr Kruszynski <ppk@semihalf.com>
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
@ -12,8 +11,6 @@
|
||||
* 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. The name of the author may not be used to endorse or promote products
|
||||
* derived from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
|
||||
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||||
@ -192,13 +189,15 @@
|
||||
#define TSEC_REG_GADDR5 0x894 /* Group address register 5 */
|
||||
#define TSEC_REG_GADDR6 0x898 /* Group address register 6 */
|
||||
#define TSEC_REG_GADDR7 0x89c /* Group address register 7 */
|
||||
#define TSEC_REG_IADDR(n) (TSEC_REG_IADDR0 + (n << 2))
|
||||
#define TSEC_REG_GADDR(n) (TSEC_REG_GADDR0 + (n << 2))
|
||||
|
||||
/* TSEC attribute registers */
|
||||
#define TSEC_REG_ATTR 0xbf8 /* Attributes Register */
|
||||
#define TSEC_REG_ATTRELI 0xbfc /* Attributes EL & EI register */
|
||||
|
||||
/* Size of TSEC registers area */
|
||||
#define TSEC_IO_SIZE 0x1000
|
||||
#define TSEC_IO_SIZE 0x1000
|
||||
|
||||
/* reg bits */
|
||||
#define TSEC_FIFO_PAUSE_CTRL_EN 0x0002
|
||||
@ -210,10 +209,25 @@
|
||||
#define DMACTRL_WWR 0x00000002 /* Write with response */
|
||||
#define DMACTRL_WOP 0x00000001 /* Wait or poll */
|
||||
|
||||
#define TSEC_RCTRL_VLEX 0x00002000 /* Enable automatic VLAN tag
|
||||
* extraction and deletion
|
||||
* from Ethernet frames */
|
||||
#define TSEC_RCTRL_IPCSEN 0x00000200 /* IP Checksum verification enable */
|
||||
#define TSEC_RCTRL_TUCSEN 0x00000100 /* TCP or UDP Checksum verification enable */
|
||||
#define TSEC_RCTRL_PRSDEP 0x000000C0 /* Parser control */
|
||||
#define TSEC_RCRTL_PRSFM 0x00000020 /* FIFO-mode parsing */
|
||||
#define TSEC_RCTRL_BC_REJ 0x00000010 /* Broadcast frame reject */
|
||||
#define TSEC_RCTRL_PROM 0x00000008 /* Promiscuous mode */
|
||||
#define TSEC_RCTRL_RSF 0x00000004 /* Receive short frame mode */
|
||||
|
||||
#define TSEC_RCTRL_PRSDEP_PARSER_OFF 0x00000000 /* Parser Disabled */
|
||||
#define TSEC_RCTRL_PRSDEP_PARSE_L2 0x00000040 /* Parse L2 */
|
||||
#define TSEC_RCTRL_PRSDEP_PARSE_L23 0x00000080 /* Parse L2 and L3 */
|
||||
#define TSEC_RCTRL_PRSDEP_PARSE_L234 0x000000C0 /* Parse L2, L3 and L4 */
|
||||
|
||||
#define TSEC_TCTRL_IPCSEN 0x00004000 /* IP header checksum generation enable */
|
||||
#define TSEC_TCTRL_TUCSEN 0x00002000 /* TCP/UDP header checksum generation enable */
|
||||
|
||||
#define TSEC_TSTAT_THLT 0x80000000 /* Transmit halt */
|
||||
#define TSEC_RSTAT_QHLT 0x00800000 /* RxBD queue is halted */
|
||||
|
||||
@ -325,6 +339,7 @@
|
||||
#define TSEC_TXBD_HFE 0x0080 /* Huge frame enable (written by user) */
|
||||
#define TSEC_TXBD_LC 0x0080 /* Late collision (written by TSEC) */
|
||||
#define TSEC_TXBD_RL 0x0040 /* Retransmission Limit */
|
||||
#define TSEC_TXBD_TOE 0x0002 /* TCP/IP Offload Enable */
|
||||
#define TSEC_TXBD_UN 0x0002 /* Underrun */
|
||||
#define TSEC_TXBD_TXTRUNC 0x0001 /* TX truncation */
|
||||
|
||||
@ -351,5 +366,25 @@
|
||||
|
||||
#define TSEC_TXBUFFER_ALIGNMENT 64
|
||||
#define TSEC_RXBUFFER_ALIGNMENT 64
|
||||
#define TSEC_DEFAULT_MAX_RX_BUFFER_SIZE 0x0600
|
||||
#define TSEC_DEFAULT_MIN_RX_BUFFER_SIZE 0x0040
|
||||
|
||||
/* Transmit Path Off-Load Frame Control Block flags */
|
||||
#define TSEC_TX_FCB_VLAN 0x8000 /* VLAN control word valid */
|
||||
#define TSEC_TX_FCB_L3_IS_IP 0x4000 /* Layer 3 header is an IP header */
|
||||
#define TSEC_TX_FCB_L3_IS_IP6 0x2000 /* IP header is IP version 6 */
|
||||
#define TSEC_TX_FCB_L4_IS_TCP_UDP 0x1000 /* Layer 4 header is a TCP or UDP header */
|
||||
#define TSEC_TX_FCB_L4_IS_UDP 0x0800 /* UDP protocol at layer 4 */
|
||||
#define TSEC_TX_FCB_CSUM_IP 0x0400 /* Checksum IP header enable */
|
||||
#define TSEC_TX_FCB_CSUM_TCP_UDP 0x0200 /* Checksum TCP or UDP header enable */
|
||||
#define TSEC_TX_FCB_FLAG_NO_PH_CSUM 0x0100 /* Disable pseudo-header checksum */
|
||||
#define TSEC_TX_FCB_FLAG_PTP 0x0001 /* This is a PTP packet */
|
||||
|
||||
/* Receive Path Off-Load Frame Control Block flags */
|
||||
#define TSEC_RX_FCB_VLAN 0x8000 /* VLAN tag recognized */
|
||||
#define TSEC_RX_FCB_IP_FOUND 0x4000 /* IP header found at layer 3 */
|
||||
#define TSEC_RX_FCB_IP6_FOUND 0x2000 /* IP version 6 header found at layer 3 */
|
||||
#define TSEC_RX_FCB_TCP_UDP_FOUND 0x1000 /* TCP or UDP header found at layer 4 */
|
||||
#define TSEC_RX_FCB_IP_CSUM 0x0800 /* IPv4 header checksum checked */
|
||||
#define TSEC_RX_FCB_TCP_UDP_CSUM 0x0400 /* TCP or UDP header checksum checked */
|
||||
#define TSEC_RX_FCB_IP_CSUM_ERROR 0x0200 /* IPv4 header checksum verification error */
|
||||
#define TSEC_RX_FCB_TCP_UDP_CSUM_ERROR 0x0100 /* TCP or UDP header checksum verification error */
|
||||
#define TSEC_RX_FCB_PARSE_ERROR 0x000C /* Parse error */
|
||||
|
@ -22,6 +22,8 @@ options BOOTP_WIRED_TO=tsec0
|
||||
options CD9660
|
||||
options COMPAT_43
|
||||
options DDB
|
||||
options DEVICE_POLLING
|
||||
options HZ=1000
|
||||
#options DIAGNOSTIC
|
||||
options FFS
|
||||
options GDB
|
||||
@ -72,3 +74,4 @@ device ugen
|
||||
#device uhci
|
||||
device umass
|
||||
device usb
|
||||
device vlan
|
||||
|
Loading…
x
Reference in New Issue
Block a user