1233545Sjchandra/*-
2233545Sjchandra * Copyright (c) 2003-2012 Broadcom Corporation
3233545Sjchandra * All Rights Reserved
4233545Sjchandra *
5233545Sjchandra * Redistribution and use in source and binary forms, with or without
6233545Sjchandra * modification, are permitted provided that the following conditions
7233545Sjchandra * are met:
8233545Sjchandra *
9233545Sjchandra * 1. Redistributions of source code must retain the above copyright
10233545Sjchandra *    notice, this list of conditions and the following disclaimer.
11233545Sjchandra * 2. Redistributions in binary form must reproduce the above copyright
12233545Sjchandra *    notice, this list of conditions and the following disclaimer in
13233545Sjchandra *    the documentation and/or other materials provided with the
14233545Sjchandra *    distribution.
15233545Sjchandra *
16233545Sjchandra * THIS SOFTWARE IS PROVIDED BY BROADCOM ``AS IS'' AND ANY EXPRESS OR
17233545Sjchandra * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18233545Sjchandra * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
19233545Sjchandra * ARE DISCLAIMED. IN NO EVENT SHALL BROADCOM OR CONTRIBUTORS BE LIABLE
20233545Sjchandra * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
21233545Sjchandra * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
22233545Sjchandra * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
23233545Sjchandra * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
24233545Sjchandra * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
25233545Sjchandra * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
26233545Sjchandra * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27233545Sjchandra *
28233545Sjchandra * $FreeBSD$
29233545Sjchandra */
30233545Sjchandra#ifndef __NLM_UCORE_H__
31233545Sjchandra#define	__NLM_UCORE_H__
32233545Sjchandra
33233545Sjchandra/* Microcode registers */
34233545Sjchandra#define	UCORE_OUTBUF_DONE	0x8000
35233545Sjchandra#define	UCORE_RX_PKT_RDY	0x8004
36233545Sjchandra#define	UCORE_RX_PKT_INFO	0x8008
37233545Sjchandra#define	UCORE_CAM0		0x800c
38233545Sjchandra#define	UCORE_CAM1		0x8010
39233545Sjchandra#define	UCORE_CAM2		0x8014
40233545Sjchandra#define	UCORE_CAM3		0x8018
41233545Sjchandra#define	UCORE_CAM_RESULT	0x801c
42233545Sjchandra#define	UCORE_CSUMINFO		0x8020
43233545Sjchandra#define	UCORE_CRCINFO		0x8024
44233545Sjchandra#define	UCORE_CRCPOS		0x8028
45233545Sjchandra#define	UCORE_FR_FIFOEMPTY	0x802c
46233545Sjchandra#define	UCORE_PKT_DISTR		0x8030
47233545Sjchandra
48233657Sjchandra#define	PACKET_MEMORY		0xFFE00
49233657Sjchandra#define	PACKET_DATA_OFFSET	64
50233545Sjchandra#define	SHARED_SCRATCH_MEM	0x18000
51233545Sjchandra
52233545Sjchandra/* Distribution mode */
53233545Sjchandra#define	VAL_PDM(x)		(((x) & 0x7) << 0)
54233545Sjchandra
55233545Sjchandra/* Dest distribution or distribution list */
56233545Sjchandra#define	VAL_DEST(x)		(((x) & 0x3ff) << 8)
57233545Sjchandra#define	VAL_PDL(x)		(((x) & 0xf) << 4)
58233545Sjchandra
59233545Sjchandra/*output buffer done*/
60233657Sjchandra#define	VAL_FSV(x)		(x << 19)
61233657Sjchandra#define	VAL_FFS(x)		(x << 14)
62233545Sjchandra
63233545Sjchandra#define	FWD_DEST_ONLY		1
64233545Sjchandra#define	FWD_ENQ_DIST_VEC	2
65233545Sjchandra#define	FWD_ENQ_DEST		3
66233545Sjchandra#define	FWD_DIST_VEC		4
67233545Sjchandra#define	FWD_ENQ_DIST_VEC_SER	6
68233545Sjchandra#define	FWD_ENQ_DEST_SER	7
69233545Sjchandra
70233545Sjchandra#define	USE_HASH_DST		(1 << 20)
71233545Sjchandra
72233657Sjchandrastatic __inline unsigned int
73233657Sjchandranlm_read_ucore_reg(int reg)
74233657Sjchandra{
75233657Sjchandra	volatile unsigned int *addr = (volatile void *)reg;
76233545Sjchandra
77233657Sjchandra	return (*addr);
78233657Sjchandra}
79233657Sjchandra
80233657Sjchandrastatic __inline void
81233657Sjchandranlm_write_ucore_reg(int reg, unsigned int val)
82233657Sjchandra{
83233657Sjchandra	volatile unsigned int *addr = (volatile void *)reg;
84233657Sjchandra
85233657Sjchandra	*addr = val;
86233657Sjchandra}
87233657Sjchandra
88233545Sjchandra#define	NLM_DEFINE_UCORE(name, reg)				\
89233657Sjchandrastatic __inline unsigned int					\
90233657Sjchandranlm_read_ucore_##name(void)					\
91233545Sjchandra{								\
92233657Sjchandra	return nlm_read_ucore_reg(reg);				\
93233545Sjchandra}								\
94233545Sjchandra								\
95233657Sjchandrastatic __inline void						\
96233657Sjchandranlm_write_ucore_##name(unsigned int v)				\
97233545Sjchandra{								\
98233657Sjchandra	nlm_write_ucore_reg(reg, v);				\
99233545Sjchandra} struct __hack
100233545Sjchandra
101233545Sjchandra
102233545SjchandraNLM_DEFINE_UCORE(obufdone,		UCORE_OUTBUF_DONE);
103233545SjchandraNLM_DEFINE_UCORE(rxpktrdy,		UCORE_RX_PKT_RDY);
104233545SjchandraNLM_DEFINE_UCORE(rxpktinfo,		UCORE_RX_PKT_INFO);
105233545SjchandraNLM_DEFINE_UCORE(cam0,			UCORE_CAM0);
106233545SjchandraNLM_DEFINE_UCORE(cam1,			UCORE_CAM1);
107233545SjchandraNLM_DEFINE_UCORE(cam2,			UCORE_CAM2);
108233545SjchandraNLM_DEFINE_UCORE(cam3,			UCORE_CAM3);
109233545SjchandraNLM_DEFINE_UCORE(camresult,		UCORE_CAM_RESULT);
110233545SjchandraNLM_DEFINE_UCORE(csuminfo,		UCORE_CSUMINFO);
111233545SjchandraNLM_DEFINE_UCORE(crcinfo,		UCORE_CRCINFO);
112233545SjchandraNLM_DEFINE_UCORE(crcpos,		UCORE_CRCPOS);
113233545SjchandraNLM_DEFINE_UCORE(freefifo_empty,	UCORE_FR_FIFOEMPTY);
114233545SjchandraNLM_DEFINE_UCORE(pktdistr,		UCORE_PKT_DISTR);
115233545Sjchandra
116233545Sjchandra/*
117233545Sjchandra * l3cachelines - number of cache lines to allocate into l3
118233545Sjchandra * fsv - 0 : use interface-id for selecting the free fifo pool
119233545Sjchandra *       1 : use free fifo pool selected by FFS field
120233545Sjchandra * ffs - selects which free fifo pool to use to take a free fifo
121233545Sjchandra * prepad_en - If this field is set to 1, part or all of the
122233545Sjchandra *             64 byte prepad seen by micro engines, is written
123233545Sjchandra *             infront of every packet.
124233545Sjchandra * prepad_ovride - If this field is 1, the ucore system uses
125233545Sjchandra *                 prepad configuration defined in this register,
126233545Sjchandra *                 0 means that it uses the configuration defined
127233545Sjchandra *                 in NAE RX_CONFIG register
128233545Sjchandra * prepad_size - number of 16 byte words in the 64-byte prepad
129233545Sjchandra *               seen by micro engines and dma'ed to memory as
130233545Sjchandra *               pkt prepad. This field is meaningful only if
131233545Sjchandra *               prepad_en and prepad_ovride is set.
132233545Sjchandra *               0 : 1 word
133233545Sjchandra *               1 : 2 words
134233545Sjchandra *               2 : 3 words
135233545Sjchandra *               3 : 4 words
136233545Sjchandra * prepad[0-3]: writing 0 to this means that the 1st 16 byte offset
137233545Sjchandra *              of prepad in micro engine, gets setup as prepad0/1/2/3.
138233545Sjchandra *              prepad word.
139233545Sjchandra *              1 : means 2nd 16 byte chunk in prepad0/1/2/3
140233545Sjchandra *              2 : means 3rd 16 byte chunk in prepad0/1/2/3
141233545Sjchandra *              3 : means 4rth 16 byte chunk in prepad0/1/2/3
142233545Sjchandra * pkt_discard - packet will be discarded if this is set to 1
143233545Sjchandra * rd5 - value (single bit) to be inserted in bit 5, the unclassified
144233545Sjchandra *       pkt bit of receive descriptor. If this bit is set, HPRE bit
145233545Sjchandra *       should also be set in ucore_rxpktready register
146233545Sjchandra */
147233545Sjchandrastatic __inline__ void
148233545Sjchandranlm_ucore_pkt_done(int l3cachelines, int fsv, int ffs, int prepad_en,
149233545Sjchandra    int prepad_ovride, int prepad_size, int prepad0, int prepad1,
150233545Sjchandra    int prepad2, int prepad3, int pkt_discard, int rd5)
151233545Sjchandra{
152233545Sjchandra	unsigned int val = 0;
153233545Sjchandra
154233545Sjchandra	val |= ((l3cachelines & 0xfff) << 20);
155233545Sjchandra	val |= ((fsv & 0x1) << 19);
156233545Sjchandra	val |= ((ffs & 0x1f) << 14);
157233545Sjchandra	val |= ((prepad_en & 0x1) << 3);
158233545Sjchandra	val |= ((prepad_ovride & 0x1) << 2);
159233545Sjchandra	val |= ((prepad_size & 0x3) << 12);
160233545Sjchandra	val |= ((prepad0 & 0x3) << 4);
161233545Sjchandra	val |= ((prepad1 & 0x3) << 6);
162233545Sjchandra	val |= ((prepad2 & 0x3) << 8);
163233545Sjchandra	val |= ((prepad3 & 0x3) << 10);
164233545Sjchandra	val |= ((pkt_discard & 0x1) << 1);
165233545Sjchandra	val |= ((rd5 & 0x1) << 0);
166233545Sjchandra
167233545Sjchandra	nlm_write_ucore_obufdone(val);
168233545Sjchandra}
169233545Sjchandra
170233545Sjchandra/* Get the class full vector field from POE.
171233545Sjchandra * The POE maintains a threshold for each class.
172233545Sjchandra * A bit in this field will be set corresponding to the class approaching
173233545Sjchandra * class full status.
174233545Sjchandra */
175233545Sjchandrastatic __inline__ int
176233545Sjchandranlm_ucore_get_rxpkt_poeclassfullvec(unsigned int pktrdy)
177233545Sjchandra{
178233545Sjchandra	return ((pktrdy >> 24) & 0xff);
179233545Sjchandra}
180233545Sjchandra
181233545Sjchandra/* This function returns 1 if the hardware parser extraction process
182233545Sjchandra * resulted in an error. Else, returns 0.
183233545Sjchandra */
184233545Sjchandrastatic __inline__ int
185233545Sjchandranlm_ucore_get_rxpkt_hwparsererr(unsigned int pktrdy)
186233545Sjchandra{
187233545Sjchandra	return ((pktrdy >> 23) & 0x1);
188233545Sjchandra}
189233545Sjchandra
190233545Sjchandra/* This function returns the context number assigned to incoming
191233545Sjchandra * packet
192233545Sjchandra */
193233545Sjchandrastatic __inline__ int
194233545Sjchandranlm_ucore_get_rxpkt_context(unsigned int pktrdy)
195233545Sjchandra{
196233545Sjchandra	return ((pktrdy >> 13) & 0x3ff);
197233545Sjchandra}
198233545Sjchandra
199233545Sjchandra/* this function returns the channel number of incoming packet,
200233545Sjchandra * and applies only to interlaken.
201233545Sjchandra */
202233545Sjchandrastatic __inline__ int
203233545Sjchandranlm_ucore_get_rxpkt_channel(unsigned int pktrdy)
204233545Sjchandra{
205233545Sjchandra	return ((pktrdy >> 5) & 0xff);
206233545Sjchandra}
207233545Sjchandra
208233545Sjchandra/* This function returns the interface number on which the pkt
209233545Sjchandra * was received
210233545Sjchandra */
211233545Sjchandrastatic __inline__ int
212233545Sjchandranlm_ucore_get_rxpkt_interface(unsigned int pktrdy)
213233545Sjchandra{
214233545Sjchandra	return (pktrdy & 0x1f);
215233545Sjchandra}
216233545Sjchandra
217233545Sjchandra/* This function returns 1 if end of packet (EOP) is set in
218233545Sjchandra * packet data.
219233545Sjchandra */
220233545Sjchandrastatic __inline__ int
221233545Sjchandranlm_ucore_get_rxpkt_eop(unsigned int rxpkt_info)
222233545Sjchandra{
223233545Sjchandra	return ((rxpkt_info >> 9) & 0x1);
224233545Sjchandra}
225233545Sjchandra
226233545Sjchandra/* This function returns packet length of received pkt */
227233545Sjchandrastatic __inline__ int
228233545Sjchandranlm_ucore_get_rxpktlen(unsigned int rxpkt_info)
229233545Sjchandra{
230233545Sjchandra	return (rxpkt_info & 0x1ff);
231233545Sjchandra}
232233545Sjchandra
233233545Sjchandra/* this function sets up the ucore TCAM keys. */
234233545Sjchandrastatic __inline__ void
235233545Sjchandranlm_ucore_setup_camkey(unsigned int cam_key0, unsigned int cam_key1,
236233545Sjchandra    unsigned int cam_key2, unsigned int cam_key3)
237233545Sjchandra{
238233545Sjchandra	nlm_write_ucore_cam0(cam_key0);
239233545Sjchandra	nlm_write_ucore_cam1(cam_key1);
240233545Sjchandra	nlm_write_ucore_cam2(cam_key2);
241233545Sjchandra	nlm_write_ucore_cam3(cam_key3);
242233545Sjchandra}
243233545Sjchandra
244233545Sjchandra/* This function checks if the cam result is valid or not.
245233545Sjchandra * If valid, it returns the result, else it returns 0.
246233545Sjchandra */
247233545Sjchandrastatic __inline__ int
248233545Sjchandranlm_ucore_get_cam_result(unsigned int cam_result)
249233545Sjchandra{
250233545Sjchandra	if (((cam_result >> 15) & 0x1) == 1) /* valid result */
251233545Sjchandra	    return (cam_result & 0x3fff);
252233545Sjchandra
253233545Sjchandra	return 0;
254233545Sjchandra}
255233545Sjchandra
256233545Sjchandra/* This function sets up the csum in ucore.
257233545Sjchandra * iphdr_start - defines the start of ip header (to check - is this byte
258233545Sjchandra * position???)
259233545Sjchandra * iphdr_len - This field is auto filled by h/w parser if zero, else
260233545Sjchandra * the value defined will be used.
261233545Sjchandra */
262233545Sjchandrastatic __inline__ void
263233545Sjchandranlm_ucore_csum_setup(int iphdr_start, int iphdr_len)
264233545Sjchandra{
265233545Sjchandra	unsigned int val = 0;
266233545Sjchandra
267233545Sjchandra	val |= ((iphdr_len & 0xff) << 8);
268233545Sjchandra	val |= (iphdr_len & 0xff);
269233545Sjchandra	nlm_write_ucore_csuminfo(val);
270233545Sjchandra}
271233545Sjchandra
272233545Sjchandra/* crcpos - position of crc in pkt. If crc position is within startcrc and
273233545Sjchandra * endcrc, zero out these bytes in the packet before computing crc. This
274233545Sjchandra * field is not needed for FCoE.
275233545Sjchandra * cps - If 1, uses the polynomial in RX_CRC_POLY1 of NAE register.
276233545Sjchandra *       if 0, uses the polynomial in RX_CRC_POLY0 of NAE register.
277233545Sjchandra * fcoe - If this is 1, crc calculation starts from 'startCRC' and the CRC
278233545Sjchandra * engine ends calculation before the last byte.
279233545Sjchandra * cbm - if 1, enables crc byte mirroring, where bits within a byte will get
280233545Sjchandra * reversed (mirrored) during calculation of crc.
281233545Sjchandra * cfi - If 1, performs a final inversion of crc before comarison is done during
282233545Sjchandra * pkt reception.
283233545Sjchandra * startcrc - This field is always required for both FCoE and SCTP crc.
284233545Sjchandra * endcrc - This information needs to be setup only for SCTP. For FCoE this
285233545Sjchandra * information is provided by hardware.
286233545Sjchandra * valid - if set to 1, CRC status is placed into bit 2 of rx descriptor
287233545Sjchandra *         if set to 0, TCP checksum status is placed into bit 2 of rx descriptor
288233545Sjchandra * keysize - defines the number of bytes in the pre-pad that contains the key
289233545Sjchandra */
290233545Sjchandrastatic __inline__ void
291233545Sjchandranlm_ucore_crc_setup(int crcpos, int cps, int cfi, int cbm, int fcoe,
292233545Sjchandra    int keysize, int valid, int startcrc, int endcrc)
293233545Sjchandra{
294233545Sjchandra	unsigned int val = 0;
295233545Sjchandra
296233545Sjchandra	val |= ((cfi & 0x1) << 20);
297233545Sjchandra	val |= ((cbm & 0x1) << 19);
298233545Sjchandra	val |= ((fcoe & 0x1) << 18);
299233545Sjchandra	val |= ((cps & 0x1) << 16);
300233545Sjchandra	val |= (crcpos & 0xffff);
301233545Sjchandra
302233545Sjchandra	nlm_write_ucore_crcpos(val);
303233545Sjchandra
304233545Sjchandra	val = 0;
305233545Sjchandra	val |= ((keysize & 0x3f) << 25);
306233545Sjchandra	val |= ((valid & 0x1) << 24);
307233545Sjchandra	val |= ((endcrc & 0xffff) << 8);
308233545Sjchandra	val |= (startcrc & 0xff);
309233545Sjchandra
310233545Sjchandra	nlm_write_ucore_crcinfo(val);
311233545Sjchandra}
312233545Sjchandra
313233545Sjchandra/* This function returns a fifo empty vector, where each bit provides
314233545Sjchandra * the status of a fifo pool, where if the pool is empty the bit gets
315233545Sjchandra * set to 1.
316233545Sjchandra */
317233545Sjchandrastatic __inline__ int
318233545Sjchandranlm_ucore_get_fifoempty(unsigned int fifoempty)
319233545Sjchandra{
320233545Sjchandra	return (fifoempty & 0xfffff);
321233545Sjchandra}
322233545Sjchandra
323233545Sjchandra/* This function controls how POE will distribute the packet.
324233545Sjchandra * pdm - is the packet distribution mode, where
325233545Sjchandra *       0x0 - means packet distribution mode is not used
326233545Sjchandra *       0x1 - means forwarding based on destination only (no enqueue)
327233545Sjchandra *       0x2 - means forwarding based on FID and distr vector (enqueue)
328233545Sjchandra *       0x3 - means forwarding based on dest and FID (enqueue)
329233545Sjchandra *       0x4 - means forwarding based on distr vec (no enqueue)
330233545Sjchandra *       0x6 - means forward based on FID (enqueue), distr vec and serial mode
331233545Sjchandra *       0x7 - means forward based on FID (enqueue), dest and serial mode
332233545Sjchandra * mc3 - If 1, then the 3 most significant bits of distribution list are taken
333233545Sjchandra * from context->class_table
334233545Sjchandra * pdl - poe distribution list
335233545Sjchandra * dest - fixed destination setup
336233545Sjchandra * hash - if 1, use hash based destination
337233545Sjchandra */
338233545Sjchandrastatic __inline__ void
339233545Sjchandranlm_ucore_setup_poepktdistr(int pdm, int mc3, int pdl, int dest, int hash)
340233545Sjchandra{
341233545Sjchandra	unsigned int val = 0;
342233545Sjchandra
343233545Sjchandra	val |= ((hash & 0x1) << 20);
344233545Sjchandra	val |= ((dest & 0xfff) << 8);
345233545Sjchandra	val |= ((pdl & 0xf) << 4);
346233545Sjchandra	val |= ((mc3 & 0x1) << 3);
347233545Sjchandra	val |= (pdm & 0x7);
348233545Sjchandra
349233545Sjchandra	nlm_write_ucore_pktdistr(val);
350233545Sjchandra}
351233545Sjchandra
352233545Sjchandra#endif
353