msgring.h revision 212553
1/*-
2 * Copyright (c) 2003-2009 RMI Corporation
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 * 1. Redistributions of source code must retain the above copyright
9 *    notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright
11 *    notice, this list of conditions and the following disclaimer in the
12 *    documentation and/or other materials provided with the distribution.
13 * 3. Neither the name of RMI Corporation, nor the names of its contributors,
14 *    may be used to endorse or promote products derived from this software
15 *    without specific prior written permission.
16 *
17 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
18 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
20 * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
21 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
22 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
23 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
24 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
25 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
26 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
27 * SUCH DAMAGE.
28 *
29 * RMI_BSD
30 * $FreeBSD: head/sys/mips/rmi/msgring.h 212553 2010-09-13 13:11:50Z jchandra $
31 */
32#ifndef _RMI_MSGRING_H_
33#define _RMI_MSGRING_H_
34
35#include <sys/param.h>
36#include <sys/systm.h>
37#include <sys/types.h>
38
39#include <machine/cpuregs.h>
40#include <machine/cpufunc.h>
41#include <mips/rmi/rmi_mips_exts.h>
42
43#define	MSGRNG_TX_BUF_REG	0
44#define	MSGRNG_RX_BUF_REG	1
45#define	MSGRNG_MSG_STATUS_REG	2
46#define	MSGRNG_MSG_CONFIG_REG	3
47#define MSGRNG_MSG_BUCKSIZE_REG	4
48
49#define	MSGRNG_CC_0_REG		16
50#define	MSGRNG_CC_1_REG		17
51#define	MSGRNG_CC_2_REG		18
52#define	MSGRNG_CC_3_REG		19
53#define	MSGRNG_CC_4_REG		20
54#define	MSGRNG_CC_5_REG		21
55#define	MSGRNG_CC_6_REG		22
56#define	MSGRNG_CC_7_REG		23
57#define	MSGRNG_CC_8_REG		24
58#define	MSGRNG_CC_9_REG		25
59#define	MSGRNG_CC_10_REG	26
60#define	MSGRNG_CC_11_REG	27
61#define	MSGRNG_CC_12_REG	28
62#define	MSGRNG_CC_13_REG	29
63#define	MSGRNG_CC_14_REG	30
64#define	MSGRNG_CC_15_REG	31
65
66/* Station IDs */
67#define	MSGRNG_STNID_CPU0	0x00
68#define	MSGRNG_STNID_CPU1	0x08
69#define	MSGRNG_STNID_CPU2	0x10
70#define	MSGRNG_STNID_CPU3	0x18
71#define	MSGRNG_STNID_CPU4	0x20
72#define	MSGRNG_STNID_CPU5	0x28
73#define	MSGRNG_STNID_CPU6	0x30
74#define	MSGRNG_STNID_CPU7	0x38
75#define	MSGRNG_STNID_XGS0_TX	64
76#define	MSGRNG_STNID_XMAC0_00_TX	64
77#define	MSGRNG_STNID_XMAC0_01_TX	65
78#define	MSGRNG_STNID_XMAC0_02_TX	66
79#define	MSGRNG_STNID_XMAC0_03_TX	67
80#define	MSGRNG_STNID_XMAC0_04_TX	68
81#define	MSGRNG_STNID_XMAC0_05_TX	69
82#define	MSGRNG_STNID_XMAC0_06_TX	70
83#define	MSGRNG_STNID_XMAC0_07_TX	71
84#define	MSGRNG_STNID_XMAC0_08_TX	72
85#define	MSGRNG_STNID_XMAC0_09_TX	73
86#define	MSGRNG_STNID_XMAC0_10_TX	74
87#define	MSGRNG_STNID_XMAC0_11_TX	75
88#define	MSGRNG_STNID_XMAC0_12_TX	76
89#define	MSGRNG_STNID_XMAC0_13_TX	77
90#define	MSGRNG_STNID_XMAC0_14_TX	78
91#define	MSGRNG_STNID_XMAC0_15_TX	79
92
93#define	MSGRNG_STNID_XGS1_TX		80
94#define	MSGRNG_STNID_XMAC1_00_TX	80
95#define	MSGRNG_STNID_XMAC1_01_TX	81
96#define	MSGRNG_STNID_XMAC1_02_TX	82
97#define	MSGRNG_STNID_XMAC1_03_TX	83
98#define	MSGRNG_STNID_XMAC1_04_TX	84
99#define	MSGRNG_STNID_XMAC1_05_TX	85
100#define	MSGRNG_STNID_XMAC1_06_TX	86
101#define	MSGRNG_STNID_XMAC1_07_TX	87
102#define	MSGRNG_STNID_XMAC1_08_TX	88
103#define	MSGRNG_STNID_XMAC1_09_TX	89
104#define	MSGRNG_STNID_XMAC1_10_TX	90
105#define	MSGRNG_STNID_XMAC1_11_TX	91
106#define	MSGRNG_STNID_XMAC1_12_TX	92
107#define	MSGRNG_STNID_XMAC1_13_TX	93
108#define	MSGRNG_STNID_XMAC1_14_TX	94
109#define	MSGRNG_STNID_XMAC1_15_TX	95
110
111#define	MSGRNG_STNID_GMAC		96
112#define	MSGRNG_STNID_GMACJFR_0		96
113#define	MSGRNG_STNID_GMACRFR_0		97
114#define	MSGRNG_STNID_GMACTX0		98
115#define	MSGRNG_STNID_GMACTX1		99
116#define	MSGRNG_STNID_GMACTX2		100
117#define	MSGRNG_STNID_GMACTX3		101
118#define	MSGRNG_STNID_GMACJFR_1		102
119#define	MSGRNG_STNID_GMACRFR_1		103
120
121#define	MSGRNG_STNID_DMA		104
122#define	MSGRNG_STNID_DMA_0		104
123#define	MSGRNG_STNID_DMA_1		105
124#define	MSGRNG_STNID_DMA_2		106
125#define	MSGRNG_STNID_DMA_3		107
126
127#define	MSGRNG_STNID_XGS0FR		112
128#define	MSGRNG_STNID_XMAC0JFR		112
129#define	MSGRNG_STNID_XMAC0RFR		113
130
131#define	MSGRNG_STNID_XGS1FR		114
132#define	MSGRNG_STNID_XMAC1JFR		114
133#define	MSGRNG_STNID_XMAC1RFR		115
134#define	MSGRNG_STNID_SEC		120
135#define	MSGRNG_STNID_SEC0		120
136#define	MSGRNG_STNID_SEC1		121
137#define	MSGRNG_STNID_SEC2		122
138#define	MSGRNG_STNID_SEC3		123
139#define	MSGRNG_STNID_PK0		124
140#define	MSGRNG_STNID_SEC_RSA		124
141#define	MSGRNG_STNID_SEC_RSVD0		125
142#define	MSGRNG_STNID_SEC_RSVD1		126
143#define	MSGRNG_STNID_SEC_RSVD2		127
144
145#define	MSGRNG_STNID_GMAC1		80
146#define	MSGRNG_STNID_GMAC1_FR_0		81
147#define	MSGRNG_STNID_GMAC1_TX0		82
148#define	MSGRNG_STNID_GMAC1_TX1		83
149#define	MSGRNG_STNID_GMAC1_TX2		84
150#define	MSGRNG_STNID_GMAC1_TX3		85
151#define	MSGRNG_STNID_GMAC1_FR_1		87
152#define	MSGRNG_STNID_GMAC0		96
153#define	MSGRNG_STNID_GMAC0_FR_0		97
154#define	MSGRNG_STNID_GMAC0_TX0		98
155#define	MSGRNG_STNID_GMAC0_TX1		99
156#define	MSGRNG_STNID_GMAC0_TX2		100
157#define	MSGRNG_STNID_GMAC0_TX3		101
158#define	MSGRNG_STNID_GMAC0_FR_1		103
159#define	MSGRNG_STNID_CMP_0		108
160#define	MSGRNG_STNID_CMP_1		109
161#define	MSGRNG_STNID_CMP_2		110
162#define	MSGRNG_STNID_CMP_3		111
163#define	MSGRNG_STNID_PCIE_0		116
164#define	MSGRNG_STNID_PCIE_1		117
165#define	MSGRNG_STNID_PCIE_2		118
166#define	MSGRNG_STNID_PCIE_3		119
167#define	MSGRNG_STNID_XLS_PK0		121
168
169#define	MSGRNG_CODE_MAC		0
170#define	MSGRNG_CODE_XGMAC	2
171#define	MSGRNG_CODE_SEC		0
172#define	MSGRNG_CODE_BOOT_WAKEUP	200
173#define	MSGRNG_CODE_SPI4	3
174#define	msgrng_read_status()	read_c2_register32(MSGRNG_MSG_STATUS_REG, 0)
175
176#define	msgrng_read_config()	read_c2_register32(MSGRNG_MSG_CONFIG_REG, 0)
177#define	msgrng_write_config(v)	write_c2_register32(MSGRNG_MSG_CONFIG_REG, 0, v)
178
179#define	msgrng_read_bucksize(b)	read_c2_register32(MSGRNG_MSG_BUCKSIZE_REG, b)
180#define	msgrng_write_bucksize(b, v)	write_c2_register32(MSGRNG_MSG_BUCKSIZE_REG, b, v)
181
182#define	msgrng_read_cc(r, s)	read_c2_register32(r, s)
183#define	msgrng_write_cc(r, v, s)	write_c2_register32(r, s, v)
184
185#define	msgrng_load_rx_msg0()	read_c2_register64(MSGRNG_RX_BUF_REG, 0)
186#define	msgrng_load_rx_msg1()	read_c2_register64(MSGRNG_RX_BUF_REG, 1)
187#define	msgrng_load_rx_msg2()	read_c2_register64(MSGRNG_RX_BUF_REG, 2)
188#define	msgrng_load_rx_msg3()	read_c2_register64(MSGRNG_RX_BUF_REG, 3)
189
190#define	msgrng_load_tx_msg0(v)	write_c2_register64(MSGRNG_TX_BUF_REG, 0, v)
191#define	msgrng_load_tx_msg1(v)	write_c2_register64(MSGRNG_TX_BUF_REG, 1, v)
192#define	msgrng_load_tx_msg2(v)	write_c2_register64(MSGRNG_TX_BUF_REG, 2, v)
193#define	msgrng_load_tx_msg3(v)	write_c2_register64(MSGRNG_TX_BUF_REG, 3, v)
194
195static __inline void
196msgrng_send(unsigned int stid)
197{
198	__asm__ volatile (
199	    ".set	push\n"
200	    ".set	noreorder\n"
201	    "move	$8, %0\n"
202	    "c2		0x80001\n"	/* msgsnd $8 */
203	    ".set	pop\n"
204	    :: "r" (stid): "$8"
205	);
206}
207
208static __inline void
209msgrng_receive(unsigned int pri)
210{
211	__asm__ volatile (
212	    ".set	push\n"
213	    ".set	noreorder\n"
214	    "move	$8, %0\n"
215	    "c2		0x80002\n"    /* msgld $8 */
216	    ".set	pop\n"
217	    :: "r" (pri): "$8"
218	);
219}
220
221static __inline void
222msgrng_wait(unsigned int mask)
223{
224	__asm__ volatile (
225	    ".set	push\n"
226	    ".set	noreorder\n"
227	    "move	$8, %0\n"
228	    "c2		0x80003\n"    /* msgwait $8 */
229	    ".set	pop\n"
230	    :: "r" (mask): "$8"
231	);
232}
233
234static __inline uint32_t
235msgrng_access_enable(void)
236{
237	uint32_t sr = mips_rd_status();
238
239	mips_wr_status((sr & ~MIPS_SR_INT_IE) | MIPS_SR_COP_2_BIT);
240	return (sr);
241}
242
243static __inline void
244msgrng_restore(uint32_t sr)
245{
246
247	mips_wr_status(sr);
248}
249
250struct msgrng_msg {
251	uint64_t msg0;
252	uint64_t msg1;
253	uint64_t msg2;
254	uint64_t msg3;
255};
256
257static __inline int
258message_send(unsigned int size, unsigned int code,
259    unsigned int stid, struct msgrng_msg *msg)
260{
261	unsigned int dest = 0;
262	unsigned long long status = 0;
263	int i = 0;
264
265	/*
266	 * Make sure that all the writes pending at the cpu are flushed.
267	 * Any writes pending on CPU will not be see by devices. L1/L2
268	 * caches are coherent with IO, so no cache flush needed.
269	 */
270	__asm __volatile ("sync");
271
272	/* Load TX message buffers */
273	msgrng_load_tx_msg0(msg->msg0);
274	msgrng_load_tx_msg1(msg->msg1);
275	msgrng_load_tx_msg2(msg->msg2);
276	msgrng_load_tx_msg3(msg->msg3);
277	dest = ((size - 1) << 16) | (code << 8) | stid;
278
279	/*
280	 * Retry a few times on credit fail, this should be a
281	 * transient condition, unless there is a configuration
282	 * failure, or the receiver is stuck.
283	 */
284	for (i = 0; i < 8; i++) {
285		msgrng_send(dest);
286		status = msgrng_read_status();
287		KASSERT((status & 0x2) == 0, ("Send pending fail!"));
288		if ((status & 0x4) == 0)
289			return (0);
290	}
291
292	/* If there is a credit failure, return error */
293	return (status & 0x06);
294}
295
296static __inline int
297message_receive(int bucket, int *size, int *code, int *stid,
298    struct msgrng_msg *msg)
299{
300	uint32_t status = 0, tmp = 0;
301
302	msgrng_receive(bucket);
303
304	/* wait for load pending to clear */
305	do {
306           status = msgrng_read_status();
307	} while ((status & 0x08) != 0);
308
309	/* receive error bits */
310	tmp = status & 0x30;
311	if (tmp != 0)
312		return (tmp);
313
314	*size = ((status & 0xc0) >> 6) + 1;
315	*code = (status & 0xff00) >> 8;
316	*stid = (status & 0x7f0000) >> 16;
317	msg->msg0 = msgrng_load_rx_msg0();
318	msg->msg1 = msgrng_load_rx_msg1();
319	msg->msg2 = msgrng_load_rx_msg2();
320	msg->msg3 = msgrng_load_rx_msg3();
321	return (0);
322}
323
324#define MSGRNG_STN_RX_QSIZE 256
325
326struct stn_cc {
327	unsigned short counters[16][8];
328};
329
330struct bucket_size {
331	unsigned short bucket[128];
332};
333
334extern struct bucket_size bucket_sizes;
335
336extern struct stn_cc cc_table_cpu_0;
337extern struct stn_cc cc_table_cpu_1;
338extern struct stn_cc cc_table_cpu_2;
339extern struct stn_cc cc_table_cpu_3;
340extern struct stn_cc cc_table_cpu_4;
341extern struct stn_cc cc_table_cpu_5;
342extern struct stn_cc cc_table_cpu_6;
343extern struct stn_cc cc_table_cpu_7;
344extern struct stn_cc cc_table_xgs_0;
345extern struct stn_cc cc_table_xgs_1;
346extern struct stn_cc cc_table_gmac;
347extern struct stn_cc cc_table_dma;
348extern struct stn_cc cc_table_sec;
349
350extern struct bucket_size xls_bucket_sizes;
351
352extern struct stn_cc xls_cc_table_cpu_0;
353extern struct stn_cc xls_cc_table_cpu_1;
354extern struct stn_cc xls_cc_table_cpu_2;
355extern struct stn_cc xls_cc_table_cpu_3;
356extern struct stn_cc xls_cc_table_gmac0;
357extern struct stn_cc xls_cc_table_gmac1;
358extern struct stn_cc xls_cc_table_cmp;
359extern struct stn_cc xls_cc_table_pcie;
360extern struct stn_cc xls_cc_table_dma;
361extern struct stn_cc xls_cc_table_sec;
362
363/*
364 * NOTE: this is not stationid/8, ie the station numbers below are just
365 * for internal use
366 */
367enum {
368	TX_STN_CPU_0,
369	TX_STN_CPU_1,
370	TX_STN_CPU_2,
371	TX_STN_CPU_3,
372	TX_STN_CPU_4,
373	TX_STN_CPU_5,
374	TX_STN_CPU_6,
375	TX_STN_CPU_7,
376	TX_STN_GMAC,
377	TX_STN_DMA,
378	TX_STN_XGS_0,
379	TX_STN_XGS_1,
380	TX_STN_SAE,
381	TX_STN_GMAC0,
382	TX_STN_GMAC1,
383	TX_STN_CDE,
384	TX_STN_PCIE,
385	TX_STN_INVALID,
386	MAX_TX_STNS
387};
388
389extern int register_msgring_handler(int major,
390    void (*action) (int, int, int, int, struct msgrng_msg *, void *),
391    void *dev_id);
392extern void xlr_msgring_cpu_init(void);
393extern void xlr_msgring_config(void);
394
395#endif
396