1195838Sbz/*-
2195838Sbz * SPDX-License-Identifier: BSD-2-Clause
3195838Sbz *
4195838Sbz * Copyright (c) 2015 Bjoern A. Zeeb
5195838Sbz * Copyright (c) 2020 Denis Salopek
6195838Sbz *
7195838Sbz * This software was developed by SRI International and the University of
8195838Sbz * Cambridge Computer Laboratory under DARPA/AFRL contract FA8750-11-C-0249
9195838Sbz * ("MRC2"), as part of the DARPA MRC research programme.
10195838Sbz *
11195838Sbz * Redistribution and use in source and binary forms, with or without
12195838Sbz * modification, are permitted provided that the following conditions
13195838Sbz * are met:
14195838Sbz * 1. Redistributions of source code must retain the above copyright
15195838Sbz *    notice, this list of conditions and the following disclaimer.
16195838Sbz * 2. Redistributions in binary form must reproduce the above copyright
17195838Sbz *    notice, this list of conditions and the following disclaimer in the
18195838Sbz *    documentation and/or other materials provided with the distribution.
19195838Sbz *
20195838Sbz * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
21195838Sbz * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
22195838Sbz * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
23195838Sbz * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
24195838Sbz * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
25195838Sbz * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
26195838Sbz * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
27195838Sbz * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
28195838Sbz * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
29195838Sbz * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
30195838Sbz * POSSIBILITY OF SUCH DAMAGE.
31195838Sbz */
32195838Sbz
33195838Sbz
34195838Sbz#define	DEFAULT_ETHER_ADDRESS		"\02SUME\00"
35195838Sbz#define	SUME_ETH_DEVICE_NAME		"sume"
36195838Sbz#define	MAX_IFC_NAME_LEN		8
37195838Sbz
38195838Sbz#define	SUME_NPORTS			4
39195838Sbz
40195838Sbz#define	SUME_IOCTL_CMD_WRITE_REG	(SIOCGPRIVATE_0)
41195838Sbz#define	SUME_IOCTL_CMD_READ_REG		(SIOCGPRIVATE_1)
42195838Sbz
43195838Sbz#define	SUME_LOCK(adapter)		mtx_lock(&adapter->lock);
44195838Sbz#define	SUME_UNLOCK(adapter)		mtx_unlock(&adapter->lock);
45195838Sbz
46195838Sbz/* Currently SUME only uses 2 fixed channels for all port traffic and regs. */
47195838Sbz#define	SUME_RIFFA_CHANNEL_DATA		0
48195838Sbz#define	SUME_RIFFA_CHANNEL_REG		1
49195838Sbz#define	SUME_RIFFA_CHANNELS		2
50195838Sbz
51195838Sbz/* RIFFA constants. */
52195838Sbz#define	RIFFA_MAX_CHNLS			12
53195838Sbz#define	RIFFA_MAX_BUS_WIDTH_PARAM	4
54195838Sbz#define	RIFFA_SG_BUF_SIZE		(4*1024)
55195838Sbz#define	RIFFA_SG_ELEMS			200
56195838Sbz
57195838Sbz/* RIFFA register offsets. */
58195838Sbz#define	RIFFA_RX_SG_LEN_REG_OFF		0x0
59195838Sbz#define	RIFFA_RX_SG_ADDR_LO_REG_OFF	0x1
60195838Sbz#define	RIFFA_RX_SG_ADDR_HI_REG_OFF	0x2
61195838Sbz#define	RIFFA_RX_LEN_REG_OFF		0x3
62195838Sbz#define	RIFFA_RX_OFFLAST_REG_OFF	0x4
63195838Sbz#define	RIFFA_TX_SG_LEN_REG_OFF		0x5
64195838Sbz#define	RIFFA_TX_SG_ADDR_LO_REG_OFF	0x6
65195838Sbz#define	RIFFA_TX_SG_ADDR_HI_REG_OFF	0x7
66195838Sbz#define	RIFFA_TX_LEN_REG_OFF		0x8
67195838Sbz#define	RIFFA_TX_OFFLAST_REG_OFF	0x9
68195838Sbz#define	RIFFA_INFO_REG_OFF		0xA
69195838Sbz#define	RIFFA_IRQ_REG0_OFF		0xB
70195838Sbz#define	RIFFA_IRQ_REG1_OFF		0xC
71195838Sbz#define	RIFFA_RX_TNFR_LEN_REG_OFF	0xD
72195838Sbz#define	RIFFA_TX_TNFR_LEN_REG_OFF	0xE
73195838Sbz
74195838Sbz#define	RIFFA_CHNL_REG(c, o)		((c << 4) + o)
75195838Sbz
76195838Sbz/*
77195838Sbz * RIFFA state machine;
78195838Sbz * rather than using complex circular buffers for 1 transaction.
79195838Sbz */
80195838Sbz#define	SUME_RIFFA_CHAN_STATE_IDLE	0x01
81195838Sbz#define	SUME_RIFFA_CHAN_STATE_READY	0x02
82195838Sbz#define	SUME_RIFFA_CHAN_STATE_READ	0x04
83195838Sbz#define	SUME_RIFFA_CHAN_STATE_LEN	0x08
84217744Suqs
85217744Suqs/* Accessor macros. */
86217744Suqs#define	SUME_OFFLAST			((0 << 1) | (1 & 0x01))
87217744Suqs#define	SUME_RIFFA_LAST(offlast)	((offlast) & 0x01)
88217744Suqs#define	SUME_RIFFA_OFFSET(offlast)	((uint64_t)((offlast) >> 1) << 2)
89217744Suqs#define	SUME_RIFFA_LEN(len)		((uint64_t)(len) << 2)
90195838Sbz
91195838Sbz#define	SUME_RIFFA_LO_ADDR(addr)	(addr & 0xFFFFFFFF)
92195838Sbz#define	SUME_RIFFA_HI_ADDR(addr)	((addr >> 32) & 0xFFFFFFFF)
93195838Sbz
94195838Sbz/* Vector bits. */
95195838Sbz#define	SUME_MSI_RXQUE			(1 << 0)
96195838Sbz#define	SUME_MSI_RXBUF			(1 << 1)
97195838Sbz#define	SUME_MSI_RXDONE			(1 << 2)
98195838Sbz#define	SUME_MSI_TXBUF			(1 << 3)
99195838Sbz#define	SUME_MSI_TXDONE			(1 << 4)
100195838Sbz
101195838Sbz/* Invalid vector. */
102195838Sbz#define	SUME_INVALID_VECT		0xc0000000
103195838Sbz
104195838Sbz/* Module register data (packet counters, link status...) */
105195838Sbz#define	SUME_MOD0_REG_BASE		0x44040000
106195838Sbz#define	SUME_MOD_REG(port)		(SUME_MOD0_REG_BASE + 0x10000 * port)
107195838Sbz
108195838Sbz#define	SUME_RESET_OFFSET		0x8
109195838Sbz#define	SUME_PKTIN_OFFSET		0x18
110195838Sbz#define	SUME_PKTOUT_OFFSET		0x1c
111195838Sbz#define	SUME_STATUS_OFFSET		0x48
112195838Sbz
113195838Sbz#define	SUME_RESET_ADDR(p)		(SUME_MOD_REG(p) + SUME_RESET_OFFSET)
114195838Sbz#define	SUME_STAT_RX_ADDR(p)		(SUME_MOD_REG(p) + SUME_PKTIN_OFFSET)
115195838Sbz#define	SUME_STAT_TX_ADDR(p)		(SUME_MOD_REG(p) + SUME_PKTOUT_OFFSET)
116195838Sbz#define	SUME_STATUS_ADDR(p)		(SUME_MOD_REG(p) + SUME_STATUS_OFFSET)
117195838Sbz
118195838Sbz#define	SUME_LINK_STATUS(val)		((val >> 12) & 0x1)
119195838Sbz
120195838Sbz/* Various bits and pieces. */
121195838Sbz#define	SUME_RIFFA_MAGIC		0xcafe
122195838Sbz#define	SUME_MR_WRITE			0x1f
123195838Sbz#define	SUME_MR_READ			0x00
124204435Srwatson#define	SUME_INIT_RTAG			-3
125204435Srwatson#define	SUME_DPORT_MASK			0xaa
126195838Sbz#define	SUME_MIN_PKT_SIZE		(ETHER_MIN_LEN - ETHER_CRC_LEN)
127195838Sbz
128195838Sbzstruct irq {
129195838Sbz	uint32_t		rid;
130195838Sbz	struct resource		*res;
131195838Sbz	void			*tag;
132195838Sbz} __aligned(CACHE_LINE_SIZE);
133195838Sbz
134195838Sbzstruct nf_stats {
135195838Sbz	uint64_t		hw_rx_packets;
136195838Sbz	uint64_t		hw_tx_packets;
137195838Sbz	uint64_t		ifc_down_bytes;
138195838Sbz	uint64_t		ifc_down_packets;
139195838Sbz	uint64_t		rx_bytes;
140195838Sbz	uint64_t		rx_dropped;
141195838Sbz	uint64_t		rx_packets;
142195838Sbz	uint64_t		tx_bytes;
143195838Sbz	uint64_t		tx_dropped;
144195838Sbz	uint64_t		tx_packets;
145195838Sbz};
146195838Sbz
147195838Sbzstruct riffa_chnl_dir {
148195838Sbz	uint32_t		state;
149195838Sbz	bus_dma_tag_t		ch_tag;
150195838Sbz	bus_dmamap_t		ch_map;
151195838Sbz	char			*buf_addr;	/* bouncebuf addresses+len. */
152195838Sbz	bus_addr_t		buf_hw_addr;	/* -- " -- mapped. */
153195838Sbz	uint32_t		num_sg;
154195838Sbz	uint32_t		event;		/* Used for modreg r/w */
155195838Sbz	uint32_t		len;		/* words */
156195838Sbz	uint32_t		offlast;
157195838Sbz	uint32_t		recovery;
158195838Sbz	uint32_t		rtag;
159195838Sbz};
160195838Sbz
161195838Sbzstruct sume_ifreq {
162195838Sbz	uint32_t		addr;
163195838Sbz	uint32_t		val;
164195838Sbz};
165195838Sbz
166195838Sbzstruct nf_priv {
167195838Sbz	struct sume_adapter	*adapter;
168195838Sbz	struct ifmedia		media;
169195838Sbz	struct nf_stats		stats;
170195838Sbz	uint32_t		unit;
171195838Sbz	uint32_t		port;
172195838Sbz	uint32_t		link_up;
173195838Sbz};
174195838Sbz
175195838Sbzstruct sume_adapter {
176195838Sbz	struct mtx		lock;
177195838Sbz	uint32_t		running;
178195838Sbz	uint32_t		rid;
179195838Sbz	struct riffa_chnl_dir	**recv;
180195838Sbz	struct riffa_chnl_dir	**send;
181195838Sbz	device_t		dev;
182195838Sbz	if_t			ifp[SUME_NPORTS];
183195838Sbz	struct resource		*bar0_addr;
184195838Sbz	bus_space_tag_t		bt;
185195838Sbz	bus_space_handle_t	bh;
186195838Sbz	bus_size_t		bar0_len;
187195838Sbz	struct irq		irq;
188195838Sbz	struct callout		timer;
189195838Sbz	struct task		stat_task;
190195838Sbz	struct taskqueue	*tq;
191195838Sbz	uint64_t		bytes_err;
192195838Sbz	uint64_t		packets_err;
193195838Sbz	uint32_t		last_ifc;
194195838Sbz	uint32_t		num_sg;
195195838Sbz	uint32_t		sg_buf_size;
196195838Sbz	uint32_t		sume_debug;
197195838Sbz	uint32_t		wd_counter;
198195838Sbz};
199195838Sbz
200195838Sbz/* SUME metadata:
201196185Sbz * sport - not used for RX. For TX, set to 0x02, 0x08, 0x20, 0x80, depending on
202195838Sbz *     the sending interface (nf0, nf1, nf2 or nf3).
203195838Sbz * dport - For RX, is set to 0x02, 0x08, 0x20, 0x80, depending on the receiving
204195838Sbz *     interface (nf0, nf1, nf2 or nf3). For TX, set to 0x01, 0x04, 0x10, 0x40,
205195838Sbz *     depending on the sending HW interface (nf0, nf1, nf2 or nf3).
206195838Sbz * plen - length of the send/receive packet data (in bytes)
207195838Sbz * magic - SUME hardcoded magic number which should be 0xcafe
208195838Sbz * t1, t1 - could be used for timestamping by SUME
209195838Sbz */
210195838Sbzstruct nf_metadata {
211195838Sbz	uint16_t		sport;
212195838Sbz	uint16_t		dport;
213195838Sbz	uint16_t		plen;
214195838Sbz	uint16_t		magic;
215195838Sbz	uint32_t		t1;
216195838Sbz	uint32_t		t2;
217195838Sbz};
218195838Sbz
219195838Sbz/* Used for ioctl communication with the rwaxi program used to read/write SUME
220195838Sbz *    internally defined register data.
221195838Sbz * addr - address of the SUME module register to read/write
222195838Sbz * val - value to write/read to/from the register
223195838Sbz * rtag - returned on read: transaction tag, for syncronization
224195838Sbz * optype - 0x1f when writing, 0x00 for reading
225195838Sbz */
226195838Sbzstruct nf_regop_data {
227195838Sbz	uint32_t		addr;
228195838Sbz	uint32_t		val;
229195838Sbz	uint32_t		rtag;
230195838Sbz	uint32_t		optype;
231195838Sbz};
232195838Sbz
233195838Sbz/* Our bouncebuffer "descriptor". This holds our physical address (lower and
234195838Sbz * upper values) of the beginning of the DMA data to RX/TX. The len is number
235195838Sbz * of words to transmit.
236195838Sbz */
237195838Sbzstruct nf_bb_desc {
238195838Sbz	uint32_t		lower;
239195838Sbz	uint32_t		upper;
240	uint32_t		len;
241};
242