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: releng/10.3/sys/mips/rmi/msgring.h 213377 2010-10-03 04:33:58Z 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
175#define	msgrng_read_status()	read_c2_register32(MSGRNG_MSG_STATUS_REG, 0)
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#define	msgrng_read_bucksize(b)	read_c2_register32(MSGRNG_MSG_BUCKSIZE_REG, b)
179#define	msgrng_write_bucksize(b, v)	write_c2_register32(MSGRNG_MSG_BUCKSIZE_REG, b, v)
180#define	msgrng_read_cc(r, s)	read_c2_register32(r, s)
181#define	msgrng_write_cc(r, v, s)	write_c2_register32(r, s, v)
182
183#define	msgrng_load_rx_msg0()	read_c2_register64(MSGRNG_RX_BUF_REG, 0)
184#define	msgrng_load_rx_msg1()	read_c2_register64(MSGRNG_RX_BUF_REG, 1)
185#define	msgrng_load_rx_msg2()	read_c2_register64(MSGRNG_RX_BUF_REG, 2)
186#define	msgrng_load_rx_msg3()	read_c2_register64(MSGRNG_RX_BUF_REG, 3)
187
188#define	msgrng_load_tx_msg0(v)	write_c2_register64(MSGRNG_TX_BUF_REG, 0, v)
189#define	msgrng_load_tx_msg1(v)	write_c2_register64(MSGRNG_TX_BUF_REG, 1, v)
190#define	msgrng_load_tx_msg2(v)	write_c2_register64(MSGRNG_TX_BUF_REG, 2, v)
191#define	msgrng_load_tx_msg3(v)	write_c2_register64(MSGRNG_TX_BUF_REG, 3, v)
192
193static __inline void
194msgrng_send(unsigned int stid)
195{
196	__asm__ volatile (
197	    ".set	push\n"
198	    ".set	noreorder\n"
199	    "move	$8, %0\n"
200	    "c2		0x80001\n"	/* msgsnd $8 */
201	    ".set	pop\n"
202	    :: "r" (stid): "$8"
203	);
204}
205
206static __inline void
207msgrng_receive(unsigned int pri)
208{
209	__asm__ volatile (
210	    ".set	push\n"
211	    ".set	noreorder\n"
212	    "move	$8, %0\n"
213	    "c2		0x80002\n"    /* msgld $8 */
214	    ".set	pop\n"
215	    :: "r" (pri): "$8"
216	);
217}
218
219static __inline void
220msgrng_wait(unsigned int mask)
221{
222	__asm__ volatile (
223	    ".set	push\n"
224	    ".set	noreorder\n"
225	    "move	$8, %0\n"
226	    "c2		0x80003\n"    /* msgwait $8 */
227	    ".set	pop\n"
228	    :: "r" (mask): "$8"
229	);
230}
231
232static __inline uint32_t
233msgrng_access_enable(void)
234{
235	uint32_t sr = mips_rd_status();
236
237	mips_wr_status((sr & ~MIPS_SR_INT_IE) | MIPS_SR_COP_2_BIT);
238	return (sr);
239}
240
241static __inline void
242msgrng_restore(uint32_t sr)
243{
244
245	mips_wr_status(sr);
246}
247
248struct msgrng_msg {
249	uint64_t msg0;
250	uint64_t msg1;
251	uint64_t msg2;
252	uint64_t msg3;
253};
254
255static __inline int
256message_send(unsigned int size, unsigned int code,
257    unsigned int stid, struct msgrng_msg *msg)
258{
259	unsigned int dest = 0;
260	unsigned long long status = 0;
261	int i = 0;
262
263	/*
264	 * Make sure that all the writes pending at the cpu are flushed.
265	 * Any writes pending on CPU will not be see by devices. L1/L2
266	 * caches are coherent with IO, so no cache flush needed.
267	 */
268	__asm __volatile ("sync");
269
270	/* Load TX message buffers */
271	msgrng_load_tx_msg0(msg->msg0);
272	msgrng_load_tx_msg1(msg->msg1);
273	msgrng_load_tx_msg2(msg->msg2);
274	msgrng_load_tx_msg3(msg->msg3);
275	dest = ((size - 1) << 16) | (code << 8) | stid;
276
277	/*
278	 * Retry a few times on credit fail, this should be a
279	 * transient condition, unless there is a configuration
280	 * failure, or the receiver is stuck.
281	 */
282	for (i = 0; i < 8; i++) {
283		msgrng_send(dest);
284		status = msgrng_read_status();
285		KASSERT((status & 0x2) == 0, ("Send pending fail!"));
286		if ((status & 0x4) == 0)
287			return (0);
288	}
289
290	/* If there is a credit failure, return error */
291	return (status & 0x06);
292}
293
294static __inline int
295message_receive(int bucket, int *size, int *code, int *stid,
296    struct msgrng_msg *msg)
297{
298	uint32_t status = 0, tmp = 0;
299
300	msgrng_receive(bucket);
301
302	/* wait for load pending to clear */
303	do {
304           status = msgrng_read_status();
305	} while ((status & 0x08) != 0);
306
307	/* receive error bits */
308	tmp = status & 0x30;
309	if (tmp != 0)
310		return (tmp);
311
312	*size = ((status & 0xc0) >> 6) + 1;
313	*code = (status & 0xff00) >> 8;
314	*stid = (status & 0x7f0000) >> 16;
315	msg->msg0 = msgrng_load_rx_msg0();
316	msg->msg1 = msgrng_load_rx_msg1();
317	msg->msg2 = msgrng_load_rx_msg2();
318	msg->msg3 = msgrng_load_rx_msg3();
319	return (0);
320}
321
322#define	MSGRNG_STN_RX_QSIZE	256
323#define	MSGRNG_NSTATIONS	128
324#define	MSGRNG_CORE_NBUCKETS	8
325
326struct stn_cc {
327	unsigned short counters[16][8];
328};
329
330struct bucket_size {
331	unsigned short bucket[MSGRNG_NSTATIONS];
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
363typedef void (*msgring_handler)(int, int, int, int, struct msgrng_msg *, void *);
364int register_msgring_handler(int startb, int endb, msgring_handler action,
365		    void *arg);
366uint32_t xlr_msgring_handler(uint8_t bucket_mask, uint32_t max_messages);
367void xlr_msgring_cpu_init(void);
368void xlr_msgring_config(void);
369
370#endif
371