summaryrefslogtreecommitdiffstats
path: root/sys/dev/neta/if_mvnetavar.h
diff options
context:
space:
mode:
Diffstat (limited to 'sys/dev/neta/if_mvnetavar.h')
-rw-r--r--sys/dev/neta/if_mvnetavar.h327
1 files changed, 327 insertions, 0 deletions
diff --git a/sys/dev/neta/if_mvnetavar.h b/sys/dev/neta/if_mvnetavar.h
new file mode 100644
index 0000000..912e9d7
--- /dev/null
+++ b/sys/dev/neta/if_mvnetavar.h
@@ -0,0 +1,327 @@
+/*
+ * 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 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_ */
OpenPOWER on IntegriCloud