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