1/*-
2 * SPDX-License-Identifier: BSD-2-Clause-FreeBSD
3 *
4 * Copyright (c) 2003-2012 Broadcom Corporation
5 * All Rights Reserved
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 *
11 * 1. Redistributions of source code must retain the above copyright
12 *    notice, this list of conditions and the following disclaimer.
13 * 2. Redistributions in binary form must reproduce the above copyright
14 *    notice, this list of conditions and the following disclaimer in
15 *    the documentation and/or other materials provided with the
16 *    distribution.
17 *
18 * THIS SOFTWARE IS PROVIDED BY BROADCOM ``AS IS'' AND ANY EXPRESS OR
19 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
20 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
21 * ARE DISCLAIMED. IN NO EVENT SHALL BROADCOM OR CONTRIBUTORS BE LIABLE
22 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
23 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
24 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
25 * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
26 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
27 * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
28 * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29 *
30 * $FreeBSD$
31 */
32#ifndef __NLM_UCORE_H__
33#define	__NLM_UCORE_H__
34
35/* Microcode registers */
36#define	UCORE_OUTBUF_DONE	0x8000
37#define	UCORE_RX_PKT_RDY	0x8004
38#define	UCORE_RX_PKT_INFO	0x8008
39#define	UCORE_CAM0		0x800c
40#define	UCORE_CAM1		0x8010
41#define	UCORE_CAM2		0x8014
42#define	UCORE_CAM3		0x8018
43#define	UCORE_CAM_RESULT	0x801c
44#define	UCORE_CSUMINFO		0x8020
45#define	UCORE_CRCINFO		0x8024
46#define	UCORE_CRCPOS		0x8028
47#define	UCORE_FR_FIFOEMPTY	0x802c
48#define	UCORE_PKT_DISTR		0x8030
49
50#define	PACKET_MEMORY		0xFFE00
51#define	PACKET_DATA_OFFSET	64
52#define	SHARED_SCRATCH_MEM	0x18000
53
54/* Distribution mode */
55#define	VAL_PDM(x)		(((x) & 0x7) << 0)
56
57/* Dest distribution or distribution list */
58#define	VAL_DEST(x)		(((x) & 0x3ff) << 8)
59#define	VAL_PDL(x)		(((x) & 0xf) << 4)
60
61/*output buffer done*/
62#define	VAL_FSV(x)		(x << 19)
63#define	VAL_FFS(x)		(x << 14)
64
65#define	FWD_DEST_ONLY		1
66#define	FWD_ENQ_DIST_VEC	2
67#define	FWD_ENQ_DEST		3
68#define	FWD_DIST_VEC		4
69#define	FWD_ENQ_DIST_VEC_SER	6
70#define	FWD_ENQ_DEST_SER	7
71
72#define	USE_HASH_DST		(1 << 20)
73
74static __inline unsigned int
75nlm_read_ucore_reg(int reg)
76{
77	volatile unsigned int *addr = (volatile void *)reg;
78
79	return (*addr);
80}
81
82static __inline void
83nlm_write_ucore_reg(int reg, unsigned int val)
84{
85	volatile unsigned int *addr = (volatile void *)reg;
86
87	*addr = val;
88}
89
90#define	NLM_DEFINE_UCORE(name, reg)				\
91static __inline unsigned int					\
92nlm_read_ucore_##name(void)					\
93{								\
94	return nlm_read_ucore_reg(reg);				\
95}								\
96								\
97static __inline void						\
98nlm_write_ucore_##name(unsigned int v)				\
99{								\
100	nlm_write_ucore_reg(reg, v);				\
101} struct __hack
102
103
104NLM_DEFINE_UCORE(obufdone,		UCORE_OUTBUF_DONE);
105NLM_DEFINE_UCORE(rxpktrdy,		UCORE_RX_PKT_RDY);
106NLM_DEFINE_UCORE(rxpktinfo,		UCORE_RX_PKT_INFO);
107NLM_DEFINE_UCORE(cam0,			UCORE_CAM0);
108NLM_DEFINE_UCORE(cam1,			UCORE_CAM1);
109NLM_DEFINE_UCORE(cam2,			UCORE_CAM2);
110NLM_DEFINE_UCORE(cam3,			UCORE_CAM3);
111NLM_DEFINE_UCORE(camresult,		UCORE_CAM_RESULT);
112NLM_DEFINE_UCORE(csuminfo,		UCORE_CSUMINFO);
113NLM_DEFINE_UCORE(crcinfo,		UCORE_CRCINFO);
114NLM_DEFINE_UCORE(crcpos,		UCORE_CRCPOS);
115NLM_DEFINE_UCORE(freefifo_empty,	UCORE_FR_FIFOEMPTY);
116NLM_DEFINE_UCORE(pktdistr,		UCORE_PKT_DISTR);
117
118/*
119 * l3cachelines - number of cache lines to allocate into l3
120 * fsv - 0 : use interface-id for selecting the free fifo pool
121 *       1 : use free fifo pool selected by FFS field
122 * ffs - selects which free fifo pool to use to take a free fifo
123 * prepad_en - If this field is set to 1, part or all of the
124 *             64 byte prepad seen by micro engines, is written
125 *             infront of every packet.
126 * prepad_ovride - If this field is 1, the ucore system uses
127 *                 prepad configuration defined in this register,
128 *                 0 means that it uses the configuration defined
129 *                 in NAE RX_CONFIG register
130 * prepad_size - number of 16 byte words in the 64-byte prepad
131 *               seen by micro engines and dma'ed to memory as
132 *               pkt prepad. This field is meaningful only if
133 *               prepad_en and prepad_ovride is set.
134 *               0 : 1 word
135 *               1 : 2 words
136 *               2 : 3 words
137 *               3 : 4 words
138 * prepad[0-3]: writing 0 to this means that the 1st 16 byte offset
139 *              of prepad in micro engine, gets setup as prepad0/1/2/3.
140 *              prepad word.
141 *              1 : means 2nd 16 byte chunk in prepad0/1/2/3
142 *              2 : means 3rd 16 byte chunk in prepad0/1/2/3
143 *              3 : means 4rth 16 byte chunk in prepad0/1/2/3
144 * pkt_discard - packet will be discarded if this is set to 1
145 * rd5 - value (single bit) to be inserted in bit 5, the unclassified
146 *       pkt bit of receive descriptor. If this bit is set, HPRE bit
147 *       should also be set in ucore_rxpktready register
148 */
149static __inline__ void
150nlm_ucore_pkt_done(int l3cachelines, int fsv, int ffs, int prepad_en,
151    int prepad_ovride, int prepad_size, int prepad0, int prepad1,
152    int prepad2, int prepad3, int pkt_discard, int rd5)
153{
154	unsigned int val = 0;
155
156	val |= ((l3cachelines & 0xfff) << 20);
157	val |= ((fsv & 0x1) << 19);
158	val |= ((ffs & 0x1f) << 14);
159	val |= ((prepad_en & 0x1) << 3);
160	val |= ((prepad_ovride & 0x1) << 2);
161	val |= ((prepad_size & 0x3) << 12);
162	val |= ((prepad0 & 0x3) << 4);
163	val |= ((prepad1 & 0x3) << 6);
164	val |= ((prepad2 & 0x3) << 8);
165	val |= ((prepad3 & 0x3) << 10);
166	val |= ((pkt_discard & 0x1) << 1);
167	val |= ((rd5 & 0x1) << 0);
168
169	nlm_write_ucore_obufdone(val);
170}
171
172/* Get the class full vector field from POE.
173 * The POE maintains a threshold for each class.
174 * A bit in this field will be set corresponding to the class approaching
175 * class full status.
176 */
177static __inline__ int
178nlm_ucore_get_rxpkt_poeclassfullvec(unsigned int pktrdy)
179{
180	return ((pktrdy >> 24) & 0xff);
181}
182
183/* This function returns 1 if the hardware parser extraction process
184 * resulted in an error. Else, returns 0.
185 */
186static __inline__ int
187nlm_ucore_get_rxpkt_hwparsererr(unsigned int pktrdy)
188{
189	return ((pktrdy >> 23) & 0x1);
190}
191
192/* This function returns the context number assigned to incoming
193 * packet
194 */
195static __inline__ int
196nlm_ucore_get_rxpkt_context(unsigned int pktrdy)
197{
198	return ((pktrdy >> 13) & 0x3ff);
199}
200
201/* this function returns the channel number of incoming packet,
202 * and applies only to interlaken.
203 */
204static __inline__ int
205nlm_ucore_get_rxpkt_channel(unsigned int pktrdy)
206{
207	return ((pktrdy >> 5) & 0xff);
208}
209
210/* This function returns the interface number on which the pkt
211 * was received
212 */
213static __inline__ int
214nlm_ucore_get_rxpkt_interface(unsigned int pktrdy)
215{
216	return (pktrdy & 0x1f);
217}
218
219/* This function returns 1 if end of packet (EOP) is set in
220 * packet data.
221 */
222static __inline__ int
223nlm_ucore_get_rxpkt_eop(unsigned int rxpkt_info)
224{
225	return ((rxpkt_info >> 9) & 0x1);
226}
227
228/* This function returns packet length of received pkt */
229static __inline__ int
230nlm_ucore_get_rxpktlen(unsigned int rxpkt_info)
231{
232	return (rxpkt_info & 0x1ff);
233}
234
235/* this function sets up the ucore TCAM keys. */
236static __inline__ void
237nlm_ucore_setup_camkey(unsigned int cam_key0, unsigned int cam_key1,
238    unsigned int cam_key2, unsigned int cam_key3)
239{
240	nlm_write_ucore_cam0(cam_key0);
241	nlm_write_ucore_cam1(cam_key1);
242	nlm_write_ucore_cam2(cam_key2);
243	nlm_write_ucore_cam3(cam_key3);
244}
245
246/* This function checks if the cam result is valid or not.
247 * If valid, it returns the result, else it returns 0.
248 */
249static __inline__ int
250nlm_ucore_get_cam_result(unsigned int cam_result)
251{
252	if (((cam_result >> 15) & 0x1) == 1) /* valid result */
253	    return (cam_result & 0x3fff);
254
255	return 0;
256}
257
258/* This function sets up the csum in ucore.
259 * iphdr_start - defines the start of ip header (to check - is this byte
260 * position???)
261 * iphdr_len - This field is auto filled by h/w parser if zero, else
262 * the value defined will be used.
263 */
264static __inline__ void
265nlm_ucore_csum_setup(int iphdr_start, int iphdr_len)
266{
267	unsigned int val = 0;
268
269	val |= ((iphdr_len & 0xff) << 8);
270	val |= (iphdr_len & 0xff);
271	nlm_write_ucore_csuminfo(val);
272}
273
274/* crcpos - position of crc in pkt. If crc position is within startcrc and
275 * endcrc, zero out these bytes in the packet before computing crc. This
276 * field is not needed for FCoE.
277 * cps - If 1, uses the polynomial in RX_CRC_POLY1 of NAE register.
278 *       if 0, uses the polynomial in RX_CRC_POLY0 of NAE register.
279 * fcoe - If this is 1, crc calculation starts from 'startCRC' and the CRC
280 * engine ends calculation before the last byte.
281 * cbm - if 1, enables crc byte mirroring, where bits within a byte will get
282 * reversed (mirrored) during calculation of crc.
283 * cfi - If 1, performs a final inversion of crc before comarison is done during
284 * pkt reception.
285 * startcrc - This field is always required for both FCoE and SCTP crc.
286 * endcrc - This information needs to be setup only for SCTP. For FCoE this
287 * information is provided by hardware.
288 * valid - if set to 1, CRC status is placed into bit 2 of rx descriptor
289 *         if set to 0, TCP checksum status is placed into bit 2 of rx descriptor
290 * keysize - defines the number of bytes in the pre-pad that contains the key
291 */
292static __inline__ void
293nlm_ucore_crc_setup(int crcpos, int cps, int cfi, int cbm, int fcoe,
294    int keysize, int valid, int startcrc, int endcrc)
295{
296	unsigned int val = 0;
297
298	val |= ((cfi & 0x1) << 20);
299	val |= ((cbm & 0x1) << 19);
300	val |= ((fcoe & 0x1) << 18);
301	val |= ((cps & 0x1) << 16);
302	val |= (crcpos & 0xffff);
303
304	nlm_write_ucore_crcpos(val);
305
306	val = 0;
307	val |= ((keysize & 0x3f) << 25);
308	val |= ((valid & 0x1) << 24);
309	val |= ((endcrc & 0xffff) << 8);
310	val |= (startcrc & 0xff);
311
312	nlm_write_ucore_crcinfo(val);
313}
314
315/* This function returns a fifo empty vector, where each bit provides
316 * the status of a fifo pool, where if the pool is empty the bit gets
317 * set to 1.
318 */
319static __inline__ int
320nlm_ucore_get_fifoempty(unsigned int fifoempty)
321{
322	return (fifoempty & 0xfffff);
323}
324
325/* This function controls how POE will distribute the packet.
326 * pdm - is the packet distribution mode, where
327 *       0x0 - means packet distribution mode is not used
328 *       0x1 - means forwarding based on destination only (no enqueue)
329 *       0x2 - means forwarding based on FID and distr vector (enqueue)
330 *       0x3 - means forwarding based on dest and FID (enqueue)
331 *       0x4 - means forwarding based on distr vec (no enqueue)
332 *       0x6 - means forward based on FID (enqueue), distr vec and serial mode
333 *       0x7 - means forward based on FID (enqueue), dest and serial mode
334 * mc3 - If 1, then the 3 most significant bits of distribution list are taken
335 * from context->class_table
336 * pdl - poe distribution list
337 * dest - fixed destination setup
338 * hash - if 1, use hash based destination
339 */
340static __inline__ void
341nlm_ucore_setup_poepktdistr(int pdm, int mc3, int pdl, int dest, int hash)
342{
343	unsigned int val = 0;
344
345	val |= ((hash & 0x1) << 20);
346	val |= ((dest & 0xfff) << 8);
347	val |= ((pdl & 0xf) << 4);
348	val |= ((mc3 & 0x1) << 3);
349	val |= (pdm & 0x7);
350
351	nlm_write_ucore_pktdistr(val);
352}
353
354#endif
355