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