Changeset View
Changeset View
Standalone View
Standalone View
head/sys/dev/neta/if_mvnetavar.h
Property | Old Value | New Value |
---|---|---|
svn:eol-style | null | native \ No newline at end of property |
svn:keywords | null | FreeBSD=%H \ No newline at end of property |
svn:mime-type | null | text/plain \ No newline at end of property |
/* | |||||
* Copyright (c) 2017 Stormshield. | |||||
* Copyright (c) 2017 Semihalf. | |||||
* 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. | |||||
* | |||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 THE AUTHOR 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$ | |||||
* | |||||
*/ | |||||
#ifndef _IF_MVNETAVAR_H_ | |||||
#define _IF_MVNETAVAR_H_ | |||||
#include <net/if.h> | |||||
#define MVNETA_HWHEADER_SIZE 2 /* Marvell Header */ | |||||
#define MVNETA_ETHER_SIZE 22 /* Maximum ether size */ | |||||
#define MVNETA_MAX_CSUM_MTU 1600 /* Port1,2 hw limit */ | |||||
/* | |||||
* Limit support for frame up to hw csum limit | |||||
* until jumbo frame support is added. | |||||
*/ | |||||
#define MVNETA_MAX_FRAME (MVNETA_MAX_CSUM_MTU + MVNETA_ETHER_SIZE) | |||||
/* | |||||
* Default limit of queue length | |||||
* | |||||
* queue 0 is lowest priority and queue 7 is highest priority. | |||||
* IP packet is received on queue 7 by default. | |||||
*/ | |||||
#define MVNETA_TX_RING_CNT 512 | |||||
#define MVNETA_RX_RING_CNT 256 | |||||
#define MVNETA_BUFRING_SIZE 1024 | |||||
#define MVNETA_PACKET_OFFSET 64 | |||||
#define MVNETA_PACKET_SIZE MCLBYTES | |||||
#define MVNETA_RXTH_COUNT 128 | |||||
#define MVNETA_RX_REFILL_COUNT 8 | |||||
#define MVNETA_TX_RECLAIM_COUNT 32 | |||||
/* | |||||
* Device Register access | |||||
*/ | |||||
#define MVNETA_READ(sc, reg) \ | |||||
bus_read_4((sc)->res[0], (reg)) | |||||
#define MVNETA_WRITE(sc, reg, val) \ | |||||
bus_write_4((sc)->res[0], (reg), (val)) | |||||
#define MVNETA_READ_REGION(sc, reg, val, c) \ | |||||
bus_read_region_4((sc)->res[0], (reg), (val), (c)) | |||||
#define MVNETA_WRITE_REGION(sc, reg, val, c) \ | |||||
bus_write_region_4((sc)->res[0], (reg), (val), (c)) | |||||
#define MVNETA_READ_MIB_4(sc, reg) \ | |||||
bus_read_4((sc)->res[0], MVNETA_PORTMIB_BASE + (reg)) | |||||
#define MVNETA_READ_MIB_8(sc, reg) \ | |||||
bus_read_8((sc)->res[0], MVNETA_PORTMIB_BASE + (reg)) | |||||
#define MVNETA_IS_LINKUP(sc) \ | |||||
(MVNETA_READ((sc), MVNETA_PSR) & MVNETA_PSR_LINKUP) | |||||
#define MVNETA_IS_QUEUE_SET(queues, q) \ | |||||
((((queues) >> (q)) & 0x1)) | |||||
/* | |||||
* EEE: Lower Power Idle config | |||||
* Default timer is duration of MTU sized frame transmission. | |||||
* The timer can be negotiated by LLDP protocol, but we have no | |||||
* support. | |||||
*/ | |||||
#define MVNETA_LPI_TS (ETHERMTU * 8 / 1000) /* [us] */ | |||||
#define MVNETA_LPI_TW (ETHERMTU * 8 / 1000) /* [us] */ | |||||
#define MVNETA_LPI_LI (ETHERMTU * 8 / 1000) /* [us] */ | |||||
/* | |||||
* DMA Descriptor | |||||
* | |||||
* the ethernet device has 8 rx/tx DMA queues. each of queue has its own | |||||
* decriptor list. descriptors are simply index by counter inside the device. | |||||
*/ | |||||
#define MVNETA_TX_SEGLIMIT 32 | |||||
#define MVNETA_QUEUE_IDLE 1 | |||||
#define MVNETA_QUEUE_WORKING 2 | |||||
#define MVNETA_QUEUE_DISABLED 3 | |||||
struct mvneta_buf { | |||||
struct mbuf * m; /* pointer to related mbuf */ | |||||
bus_dmamap_t dmap; | |||||
}; | |||||
struct mvneta_rx_ring { | |||||
int queue_status; | |||||
/* Real descriptors array. shared by RxDMA */ | |||||
struct mvneta_rx_desc *desc; | |||||
bus_dmamap_t desc_map; | |||||
bus_addr_t desc_pa; | |||||
/* Managment entries for each of descritors */ | |||||
struct mvneta_buf rxbuf[MVNETA_RX_RING_CNT]; | |||||
/* locks */ | |||||
struct mtx ring_mtx; | |||||
/* Index */ | |||||
int dma; | |||||
int cpu; | |||||
/* Limit */ | |||||
int queue_th_received; | |||||
int queue_th_time; /* [Tclk] */ | |||||
/* LRO */ | |||||
struct lro_ctrl lro; | |||||
boolean_t lro_enabled; | |||||
/* Is this queue out of mbuf */ | |||||
boolean_t needs_refill; | |||||
} __aligned(CACHE_LINE_SIZE); | |||||
struct mvneta_tx_ring { | |||||
/* Index of this queue */ | |||||
int qidx; | |||||
/* IFNET pointer */ | |||||
struct ifnet *ifp; | |||||
/* Ring buffer for IFNET */ | |||||
struct buf_ring *br; | |||||
/* Real descriptors array. shared by TxDMA */ | |||||
struct mvneta_tx_desc *desc; | |||||
bus_dmamap_t desc_map; | |||||
bus_addr_t desc_pa; | |||||
/* Managment entries for each of descritors */ | |||||
struct mvneta_buf txbuf[MVNETA_TX_RING_CNT]; | |||||
/* locks */ | |||||
struct mtx ring_mtx; | |||||
/* Index */ | |||||
int used; | |||||
int dma; | |||||
int cpu; | |||||
/* watchdog */ | |||||
#define MVNETA_WATCHDOG_TXCOMP (hz / 10) /* 100ms */ | |||||
#define MVNETA_WATCHDOG (10 * hz) /* 10s */ | |||||
int watchdog_time; | |||||
int queue_status; | |||||
boolean_t queue_hung; | |||||
/* Task */ | |||||
struct task task; | |||||
struct taskqueue *taskq; | |||||
/* Stats */ | |||||
uint32_t drv_error; | |||||
} __aligned(CACHE_LINE_SIZE); | |||||
static __inline int | |||||
tx_counter_adv(int ctr, int n) | |||||
{ | |||||
ctr += n; | |||||
while (__predict_false(ctr >= MVNETA_TX_RING_CNT)) | |||||
ctr -= MVNETA_TX_RING_CNT; | |||||
return (ctr); | |||||
} | |||||
static __inline int | |||||
rx_counter_adv(int ctr, int n) | |||||
{ | |||||
ctr += n; | |||||
while (__predict_false(ctr >= MVNETA_RX_RING_CNT)) | |||||
ctr -= MVNETA_RX_RING_CNT; | |||||
return (ctr); | |||||
} | |||||
/* | |||||
* Timeout control | |||||
*/ | |||||
#define MVNETA_PHY_TIMEOUT 10000 /* msec */ | |||||
#define RX_DISABLE_TIMEOUT 0x1000000 /* times */ | |||||
#define TX_DISABLE_TIMEOUT 0x1000000 /* times */ | |||||
#define TX_FIFO_EMPTY_TIMEOUT 0x1000000 /* times */ | |||||
/* | |||||
* Debug | |||||
*/ | |||||
#define KASSERT_SC_MTX(sc) \ | |||||
KASSERT(mtx_owned(&(sc)->mtx), ("SC mutex not owned")) | |||||
#define KASSERT_BM_MTX(sc) \ | |||||
KASSERT(mtx_owned(&(sc)->bm.bm_mtx), ("BM mutex not owned")) | |||||
#define KASSERT_RX_MTX(sc, q) \ | |||||
KASSERT(mtx_owned(&(sc)->rx_ring[(q)].ring_mtx),\ | |||||
("RX mutex not owned")) | |||||
#define KASSERT_TX_MTX(sc, q) \ | |||||
KASSERT(mtx_owned(&(sc)->tx_ring[(q)].ring_mtx),\ | |||||
("TX mutex not owned")) | |||||
/* | |||||
* sysctl(9) parameters | |||||
*/ | |||||
struct mvneta_sysctl_queue { | |||||
struct mvneta_softc *sc; | |||||
int rxtx; | |||||
int queue; | |||||
}; | |||||
#define MVNETA_SYSCTL_RX 0 | |||||
#define MVNETA_SYSCTL_TX 1 | |||||
struct mvneta_sysctl_mib { | |||||
struct mvneta_softc *sc; | |||||
int index; | |||||
uint64_t counter; | |||||
}; | |||||
enum mvneta_phy_mode { | |||||
MVNETA_PHY_QSGMII, | |||||
MVNETA_PHY_SGMII, | |||||
MVNETA_PHY_RGMII, | |||||
MVNETA_PHY_RGMII_ID | |||||
}; | |||||
/* | |||||
* Ethernet Device main context | |||||
*/ | |||||
DECLARE_CLASS(mvneta_driver); | |||||
struct mvneta_softc { | |||||
device_t dev; | |||||
uint32_t version; | |||||
/* | |||||
* mtx must be held by interface functions to/from | |||||
* other frameworks. interrupt hander, sysctl hander, | |||||
* ioctl hander, and so on. | |||||
*/ | |||||
struct mtx mtx; | |||||
struct resource *res[2]; | |||||
void *ih_cookie[1]; | |||||
struct ifnet *ifp; | |||||
uint32_t mvneta_if_flags; | |||||
uint32_t mvneta_media; | |||||
int phy_attached; | |||||
enum mvneta_phy_mode phy_mode; | |||||
int phy_addr; | |||||
int phy_speed; /* PHY speed */ | |||||
boolean_t phy_fdx; /* Full duplex mode */ | |||||
boolean_t autoneg; /* Autonegotiation status */ | |||||
boolean_t use_inband_status; /* In-band link status */ | |||||
/* | |||||
* Link State control | |||||
*/ | |||||
boolean_t linkup; | |||||
device_t miibus; | |||||
struct mii_data *mii; | |||||
uint8_t enaddr[ETHER_ADDR_LEN]; | |||||
struct ifmedia mvneta_ifmedia; | |||||
bus_dma_tag_t rx_dtag; | |||||
bus_dma_tag_t rxbuf_dtag; | |||||
bus_dma_tag_t tx_dtag; | |||||
bus_dma_tag_t txmbuf_dtag; | |||||
struct mvneta_rx_ring rx_ring[MVNETA_RX_QNUM_MAX]; | |||||
struct mvneta_tx_ring tx_ring[MVNETA_TX_QNUM_MAX]; | |||||
/* | |||||
* Maintance clock | |||||
*/ | |||||
struct callout tick_ch; | |||||
int cf_lpi; | |||||
int cf_fc; | |||||
int debug; | |||||
/* | |||||
* Sysctl interfaces | |||||
*/ | |||||
struct mvneta_sysctl_queue sysctl_rx_queue[MVNETA_RX_QNUM_MAX]; | |||||
struct mvneta_sysctl_queue sysctl_tx_queue[MVNETA_TX_QNUM_MAX]; | |||||
/* | |||||
* MIB counter | |||||
*/ | |||||
struct mvneta_sysctl_mib sysctl_mib[MVNETA_PORTMIB_NOCOUNTER]; | |||||
uint64_t counter_pdfc; | |||||
uint64_t counter_pofc; | |||||
uint32_t counter_watchdog; /* manual reset when clearing mib */ | |||||
uint32_t counter_watchdog_mib; /* reset after each mib update */ | |||||
}; | |||||
#define MVNETA_RX_RING(sc, q) \ | |||||
(&(sc)->rx_ring[(q)]) | |||||
#define MVNETA_TX_RING(sc, q) \ | |||||
(&(sc)->tx_ring[(q)]) | |||||
int mvneta_attach(device_t); | |||||
#ifdef FDT | |||||
int mvneta_fdt_mac_address(struct mvneta_softc *, uint8_t *); | |||||
#endif | |||||
#endif /* _IF_MVNETAVAR_H_ */ |