1198160Srrs/*-
2198160Srrs * Copyright (c) 2003-2009 RMI Corporation
3198160Srrs * All rights reserved.
4198160Srrs *
5198160Srrs * Redistribution and use in source and binary forms, with or without
6198160Srrs * modification, are permitted provided that the following conditions
7198160Srrs * are met:
8198160Srrs * 1. Redistributions of source code must retain the above copyright
9198160Srrs *    notice, this list of conditions and the following disclaimer.
10198160Srrs * 2. Redistributions in binary form must reproduce the above copyright
11198160Srrs *    notice, this list of conditions and the following disclaimer in the
12198160Srrs *    documentation and/or other materials provided with the distribution.
13198160Srrs * 3. Neither the name of RMI Corporation, nor the names of its contributors,
14198160Srrs *    may be used to endorse or promote products derived from this software
15198160Srrs *    without specific prior written permission.
16198160Srrs *
17198160Srrs * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
18198160Srrs * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19198160Srrs * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
20198160Srrs * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
21198160Srrs * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
22198160Srrs * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
23198160Srrs * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
24198160Srrs * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
25198160Srrs * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
26198160Srrs * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
27198160Srrs * SUCH DAMAGE.
28211994Sjchandra *
29211994Sjchandra * RMI_BSD
30211811Sjchandra * $FreeBSD$
31211994Sjchandra */
32198160Srrs#ifndef _RMI_MSGRING_H_
33198160Srrs#define _RMI_MSGRING_H_
34198160Srrs
35212321Sjchandra#include <sys/param.h>
36212321Sjchandra#include <sys/systm.h>
37211994Sjchandra#include <sys/types.h>
38212321Sjchandra
39212321Sjchandra#include <machine/cpuregs.h>
40212321Sjchandra#include <machine/cpufunc.h>
41211994Sjchandra#include <mips/rmi/rmi_mips_exts.h>
42198160Srrs
43212321Sjchandra#define	MSGRNG_TX_BUF_REG	0
44212321Sjchandra#define	MSGRNG_RX_BUF_REG	1
45212321Sjchandra#define	MSGRNG_MSG_STATUS_REG	2
46212321Sjchandra#define	MSGRNG_MSG_CONFIG_REG	3
47212321Sjchandra#define MSGRNG_MSG_BUCKSIZE_REG	4
48198160Srrs
49212553Sjchandra#define	MSGRNG_CC_0_REG		16
50212553Sjchandra#define	MSGRNG_CC_1_REG		17
51212553Sjchandra#define	MSGRNG_CC_2_REG		18
52212553Sjchandra#define	MSGRNG_CC_3_REG		19
53212553Sjchandra#define	MSGRNG_CC_4_REG		20
54212553Sjchandra#define	MSGRNG_CC_5_REG		21
55212553Sjchandra#define	MSGRNG_CC_6_REG		22
56212553Sjchandra#define	MSGRNG_CC_7_REG		23
57212553Sjchandra#define	MSGRNG_CC_8_REG		24
58212553Sjchandra#define	MSGRNG_CC_9_REG		25
59212321Sjchandra#define	MSGRNG_CC_10_REG	26
60212321Sjchandra#define	MSGRNG_CC_11_REG	27
61212321Sjchandra#define	MSGRNG_CC_12_REG	28
62212321Sjchandra#define	MSGRNG_CC_13_REG	29
63212321Sjchandra#define	MSGRNG_CC_14_REG	30
64212321Sjchandra#define	MSGRNG_CC_15_REG	31
65198160Srrs
66198160Srrs/* Station IDs */
67212553Sjchandra#define	MSGRNG_STNID_CPU0	0x00
68212553Sjchandra#define	MSGRNG_STNID_CPU1	0x08
69212553Sjchandra#define	MSGRNG_STNID_CPU2	0x10
70212553Sjchandra#define	MSGRNG_STNID_CPU3	0x18
71212553Sjchandra#define	MSGRNG_STNID_CPU4	0x20
72212553Sjchandra#define	MSGRNG_STNID_CPU5	0x28
73212553Sjchandra#define	MSGRNG_STNID_CPU6	0x30
74212553Sjchandra#define	MSGRNG_STNID_CPU7	0x38
75212553Sjchandra#define	MSGRNG_STNID_XGS0_TX	64
76212553Sjchandra#define	MSGRNG_STNID_XMAC0_00_TX	64
77212553Sjchandra#define	MSGRNG_STNID_XMAC0_01_TX	65
78212553Sjchandra#define	MSGRNG_STNID_XMAC0_02_TX	66
79212553Sjchandra#define	MSGRNG_STNID_XMAC0_03_TX	67
80212553Sjchandra#define	MSGRNG_STNID_XMAC0_04_TX	68
81212553Sjchandra#define	MSGRNG_STNID_XMAC0_05_TX	69
82212553Sjchandra#define	MSGRNG_STNID_XMAC0_06_TX	70
83212553Sjchandra#define	MSGRNG_STNID_XMAC0_07_TX	71
84212553Sjchandra#define	MSGRNG_STNID_XMAC0_08_TX	72
85212553Sjchandra#define	MSGRNG_STNID_XMAC0_09_TX	73
86212553Sjchandra#define	MSGRNG_STNID_XMAC0_10_TX	74
87212553Sjchandra#define	MSGRNG_STNID_XMAC0_11_TX	75
88212553Sjchandra#define	MSGRNG_STNID_XMAC0_12_TX	76
89212553Sjchandra#define	MSGRNG_STNID_XMAC0_13_TX	77
90212553Sjchandra#define	MSGRNG_STNID_XMAC0_14_TX	78
91212553Sjchandra#define	MSGRNG_STNID_XMAC0_15_TX	79
92198160Srrs
93212553Sjchandra#define	MSGRNG_STNID_XGS1_TX		80
94212553Sjchandra#define	MSGRNG_STNID_XMAC1_00_TX	80
95212553Sjchandra#define	MSGRNG_STNID_XMAC1_01_TX	81
96212553Sjchandra#define	MSGRNG_STNID_XMAC1_02_TX	82
97212553Sjchandra#define	MSGRNG_STNID_XMAC1_03_TX	83
98212553Sjchandra#define	MSGRNG_STNID_XMAC1_04_TX	84
99212553Sjchandra#define	MSGRNG_STNID_XMAC1_05_TX	85
100212553Sjchandra#define	MSGRNG_STNID_XMAC1_06_TX	86
101212553Sjchandra#define	MSGRNG_STNID_XMAC1_07_TX	87
102212553Sjchandra#define	MSGRNG_STNID_XMAC1_08_TX	88
103212553Sjchandra#define	MSGRNG_STNID_XMAC1_09_TX	89
104212553Sjchandra#define	MSGRNG_STNID_XMAC1_10_TX	90
105212553Sjchandra#define	MSGRNG_STNID_XMAC1_11_TX	91
106212553Sjchandra#define	MSGRNG_STNID_XMAC1_12_TX	92
107212553Sjchandra#define	MSGRNG_STNID_XMAC1_13_TX	93
108212553Sjchandra#define	MSGRNG_STNID_XMAC1_14_TX	94
109212553Sjchandra#define	MSGRNG_STNID_XMAC1_15_TX	95
110198160Srrs
111212553Sjchandra#define	MSGRNG_STNID_GMAC		96
112212553Sjchandra#define	MSGRNG_STNID_GMACJFR_0		96
113212553Sjchandra#define	MSGRNG_STNID_GMACRFR_0		97
114212553Sjchandra#define	MSGRNG_STNID_GMACTX0		98
115212553Sjchandra#define	MSGRNG_STNID_GMACTX1		99
116212553Sjchandra#define	MSGRNG_STNID_GMACTX2		100
117212553Sjchandra#define	MSGRNG_STNID_GMACTX3		101
118212553Sjchandra#define	MSGRNG_STNID_GMACJFR_1		102
119212553Sjchandra#define	MSGRNG_STNID_GMACRFR_1		103
120198160Srrs
121212553Sjchandra#define	MSGRNG_STNID_DMA		104
122212553Sjchandra#define	MSGRNG_STNID_DMA_0		104
123212553Sjchandra#define	MSGRNG_STNID_DMA_1		105
124212553Sjchandra#define	MSGRNG_STNID_DMA_2		106
125212553Sjchandra#define	MSGRNG_STNID_DMA_3		107
126198160Srrs
127212553Sjchandra#define	MSGRNG_STNID_XGS0FR		112
128212553Sjchandra#define	MSGRNG_STNID_XMAC0JFR		112
129212553Sjchandra#define	MSGRNG_STNID_XMAC0RFR		113
130198160Srrs
131212553Sjchandra#define	MSGRNG_STNID_XGS1FR		114
132212553Sjchandra#define	MSGRNG_STNID_XMAC1JFR		114
133212553Sjchandra#define	MSGRNG_STNID_XMAC1RFR		115
134212553Sjchandra#define	MSGRNG_STNID_SEC		120
135212553Sjchandra#define	MSGRNG_STNID_SEC0		120
136212553Sjchandra#define	MSGRNG_STNID_SEC1		121
137212553Sjchandra#define	MSGRNG_STNID_SEC2		122
138212553Sjchandra#define	MSGRNG_STNID_SEC3		123
139212553Sjchandra#define	MSGRNG_STNID_PK0		124
140212553Sjchandra#define	MSGRNG_STNID_SEC_RSA		124
141212553Sjchandra#define	MSGRNG_STNID_SEC_RSVD0		125
142212553Sjchandra#define	MSGRNG_STNID_SEC_RSVD1		126
143212553Sjchandra#define	MSGRNG_STNID_SEC_RSVD2		127
144198160Srrs
145212553Sjchandra#define	MSGRNG_STNID_GMAC1		80
146212553Sjchandra#define	MSGRNG_STNID_GMAC1_FR_0		81
147212553Sjchandra#define	MSGRNG_STNID_GMAC1_TX0		82
148212553Sjchandra#define	MSGRNG_STNID_GMAC1_TX1		83
149212553Sjchandra#define	MSGRNG_STNID_GMAC1_TX2		84
150212553Sjchandra#define	MSGRNG_STNID_GMAC1_TX3		85
151212553Sjchandra#define	MSGRNG_STNID_GMAC1_FR_1		87
152212553Sjchandra#define	MSGRNG_STNID_GMAC0		96
153212553Sjchandra#define	MSGRNG_STNID_GMAC0_FR_0		97
154212553Sjchandra#define	MSGRNG_STNID_GMAC0_TX0		98
155212553Sjchandra#define	MSGRNG_STNID_GMAC0_TX1		99
156212553Sjchandra#define	MSGRNG_STNID_GMAC0_TX2		100
157212553Sjchandra#define	MSGRNG_STNID_GMAC0_TX3		101
158212553Sjchandra#define	MSGRNG_STNID_GMAC0_FR_1		103
159212553Sjchandra#define	MSGRNG_STNID_CMP_0		108
160212553Sjchandra#define	MSGRNG_STNID_CMP_1		109
161212553Sjchandra#define	MSGRNG_STNID_CMP_2		110
162212553Sjchandra#define	MSGRNG_STNID_CMP_3		111
163212553Sjchandra#define	MSGRNG_STNID_PCIE_0		116
164212553Sjchandra#define	MSGRNG_STNID_PCIE_1		117
165212553Sjchandra#define	MSGRNG_STNID_PCIE_2		118
166212553Sjchandra#define	MSGRNG_STNID_PCIE_3		119
167212553Sjchandra#define	MSGRNG_STNID_XLS_PK0		121
168198160Srrs
169212553Sjchandra#define	MSGRNG_CODE_MAC		0
170212553Sjchandra#define	MSGRNG_CODE_XGMAC	2
171212553Sjchandra#define	MSGRNG_CODE_SEC		0
172212553Sjchandra#define	MSGRNG_CODE_BOOT_WAKEUP	200
173212553Sjchandra#define	MSGRNG_CODE_SPI4	3
174213377Sjchandra
175212553Sjchandra#define	msgrng_read_status()	read_c2_register32(MSGRNG_MSG_STATUS_REG, 0)
176212553Sjchandra#define	msgrng_read_config()	read_c2_register32(MSGRNG_MSG_CONFIG_REG, 0)
177212553Sjchandra#define	msgrng_write_config(v)	write_c2_register32(MSGRNG_MSG_CONFIG_REG, 0, v)
178212553Sjchandra#define	msgrng_read_bucksize(b)	read_c2_register32(MSGRNG_MSG_BUCKSIZE_REG, b)
179212553Sjchandra#define	msgrng_write_bucksize(b, v)	write_c2_register32(MSGRNG_MSG_BUCKSIZE_REG, b, v)
180212553Sjchandra#define	msgrng_read_cc(r, s)	read_c2_register32(r, s)
181212553Sjchandra#define	msgrng_write_cc(r, v, s)	write_c2_register32(r, s, v)
182198160Srrs
183212553Sjchandra#define	msgrng_load_rx_msg0()	read_c2_register64(MSGRNG_RX_BUF_REG, 0)
184212553Sjchandra#define	msgrng_load_rx_msg1()	read_c2_register64(MSGRNG_RX_BUF_REG, 1)
185212553Sjchandra#define	msgrng_load_rx_msg2()	read_c2_register64(MSGRNG_RX_BUF_REG, 2)
186212553Sjchandra#define	msgrng_load_rx_msg3()	read_c2_register64(MSGRNG_RX_BUF_REG, 3)
187198160Srrs
188212553Sjchandra#define	msgrng_load_tx_msg0(v)	write_c2_register64(MSGRNG_TX_BUF_REG, 0, v)
189212553Sjchandra#define	msgrng_load_tx_msg1(v)	write_c2_register64(MSGRNG_TX_BUF_REG, 1, v)
190212553Sjchandra#define	msgrng_load_tx_msg2(v)	write_c2_register64(MSGRNG_TX_BUF_REG, 2, v)
191212553Sjchandra#define	msgrng_load_tx_msg3(v)	write_c2_register64(MSGRNG_TX_BUF_REG, 3, v)
192198160Srrs
193212553Sjchandrastatic __inline void
194198625Srrsmsgrng_send(unsigned int stid)
195198160Srrs{
196198625Srrs	__asm__ volatile (
197212553Sjchandra	    ".set	push\n"
198212553Sjchandra	    ".set	noreorder\n"
199212553Sjchandra	    "move	$8, %0\n"
200212553Sjchandra	    "c2		0x80001\n"	/* msgsnd $8 */
201212553Sjchandra	    ".set	pop\n"
202212553Sjchandra	    :: "r" (stid): "$8"
203198625Srrs	);
204198160Srrs}
205198160Srrs
206212553Sjchandrastatic __inline void
207198625Srrsmsgrng_receive(unsigned int pri)
208198160Srrs{
209198625Srrs	__asm__ volatile (
210212553Sjchandra	    ".set	push\n"
211212553Sjchandra	    ".set	noreorder\n"
212212553Sjchandra	    "move	$8, %0\n"
213212553Sjchandra	    "c2		0x80002\n"    /* msgld $8 */
214212553Sjchandra	    ".set	pop\n"
215212553Sjchandra	    :: "r" (pri): "$8"
216198625Srrs	);
217198160Srrs}
218212553Sjchandra
219212553Sjchandrastatic __inline void
220198625Srrsmsgrng_wait(unsigned int mask)
221198160Srrs{
222198625Srrs	__asm__ volatile (
223212553Sjchandra	    ".set	push\n"
224212553Sjchandra	    ".set	noreorder\n"
225212553Sjchandra	    "move	$8, %0\n"
226212553Sjchandra	    "c2		0x80003\n"    /* msgwait $8 */
227212553Sjchandra	    ".set	pop\n"
228212553Sjchandra	    :: "r" (mask): "$8"
229198625Srrs	);
230198160Srrs}
231198160Srrs
232212321Sjchandrastatic __inline uint32_t
233212321Sjchandramsgrng_access_enable(void)
234212321Sjchandra{
235212321Sjchandra	uint32_t sr = mips_rd_status();
236198160Srrs
237212321Sjchandra	mips_wr_status((sr & ~MIPS_SR_INT_IE) | MIPS_SR_COP_2_BIT);
238212321Sjchandra	return (sr);
239212321Sjchandra}
240198160Srrs
241212321Sjchandrastatic __inline void
242212321Sjchandramsgrng_restore(uint32_t sr)
243212321Sjchandra{
244198160Srrs
245212321Sjchandra	mips_wr_status(sr);
246212321Sjchandra}
247212321Sjchandra
248198160Srrsstruct msgrng_msg {
249212553Sjchandra	uint64_t msg0;
250212553Sjchandra	uint64_t msg1;
251212553Sjchandra	uint64_t msg2;
252212553Sjchandra	uint64_t msg3;
253198160Srrs};
254198160Srrs
255212553Sjchandrastatic __inline int
256198625Srrsmessage_send(unsigned int size, unsigned int code,
257198625Srrs    unsigned int stid, struct msgrng_msg *msg)
258198160Srrs{
259198625Srrs	unsigned int dest = 0;
260198625Srrs	unsigned long long status = 0;
261198625Srrs	int i = 0;
262198160Srrs
263212553Sjchandra	/*
264212553Sjchandra	 * Make sure that all the writes pending at the cpu are flushed.
265212553Sjchandra	 * Any writes pending on CPU will not be see by devices. L1/L2
266212553Sjchandra	 * caches are coherent with IO, so no cache flush needed.
267212553Sjchandra	 */
268212553Sjchandra	__asm __volatile ("sync");
269212553Sjchandra
270212553Sjchandra	/* Load TX message buffers */
271198625Srrs	msgrng_load_tx_msg0(msg->msg0);
272198625Srrs	msgrng_load_tx_msg1(msg->msg1);
273198625Srrs	msgrng_load_tx_msg2(msg->msg2);
274198625Srrs	msgrng_load_tx_msg3(msg->msg3);
275212553Sjchandra	dest = ((size - 1) << 16) | (code << 8) | stid;
276198160Srrs
277212553Sjchandra	/*
278212553Sjchandra	 * Retry a few times on credit fail, this should be a
279212553Sjchandra	 * transient condition, unless there is a configuration
280212553Sjchandra	 * failure, or the receiver is stuck.
281212553Sjchandra	 */
282212553Sjchandra	for (i = 0; i < 8; i++) {
283212553Sjchandra		msgrng_send(dest);
284198625Srrs		status = msgrng_read_status();
285212553Sjchandra		KASSERT((status & 0x2) == 0, ("Send pending fail!"));
286212553Sjchandra		if ((status & 0x4) == 0)
287212553Sjchandra			return (0);
288212553Sjchandra	}
289198160Srrs
290212321Sjchandra	/* If there is a credit failure, return error */
291212553Sjchandra	return (status & 0x06);
292198160Srrs}
293198160Srrs
294212321Sjchandrastatic __inline int
295212553Sjchandramessage_receive(int bucket, int *size, int *code, int *stid,
296212553Sjchandra    struct msgrng_msg *msg)
297198160Srrs{
298212553Sjchandra	uint32_t status = 0, tmp = 0;
299212553Sjchandra
300212553Sjchandra	msgrng_receive(bucket);
301198160Srrs
302212553Sjchandra	/* wait for load pending to clear */
303212553Sjchandra	do {
304212553Sjchandra           status = msgrng_read_status();
305212553Sjchandra	} while ((status & 0x08) != 0);
306198160Srrs
307212553Sjchandra	/* receive error bits */
308212553Sjchandra	tmp = status & 0x30;
309212553Sjchandra	if (tmp != 0)
310212553Sjchandra		return (tmp);
311198160Srrs
312212553Sjchandra	*size = ((status & 0xc0) >> 6) + 1;
313212553Sjchandra	*code = (status & 0xff00) >> 8;
314212553Sjchandra	*stid = (status & 0x7f0000) >> 16;
315212553Sjchandra	msg->msg0 = msgrng_load_rx_msg0();
316212553Sjchandra	msg->msg1 = msgrng_load_rx_msg1();
317212553Sjchandra	msg->msg2 = msgrng_load_rx_msg2();
318212553Sjchandra	msg->msg3 = msgrng_load_rx_msg3();
319212553Sjchandra	return (0);
320198160Srrs}
321198625Srrs
322213377Sjchandra#define	MSGRNG_STN_RX_QSIZE	256
323213377Sjchandra#define	MSGRNG_NSTATIONS	128
324213377Sjchandra#define	MSGRNG_CORE_NBUCKETS	8
325198160Srrs
326198160Srrsstruct stn_cc {
327198625Srrs	unsigned short counters[16][8];
328198160Srrs};
329198160Srrs
330198160Srrsstruct bucket_size {
331213377Sjchandra	unsigned short bucket[MSGRNG_NSTATIONS];
332198160Srrs};
333198160Srrs
334198160Srrsextern struct bucket_size bucket_sizes;
335198160Srrs
336198160Srrsextern struct stn_cc cc_table_cpu_0;
337198160Srrsextern struct stn_cc cc_table_cpu_1;
338198160Srrsextern struct stn_cc cc_table_cpu_2;
339198160Srrsextern struct stn_cc cc_table_cpu_3;
340198160Srrsextern struct stn_cc cc_table_cpu_4;
341198160Srrsextern struct stn_cc cc_table_cpu_5;
342198160Srrsextern struct stn_cc cc_table_cpu_6;
343198160Srrsextern struct stn_cc cc_table_cpu_7;
344198160Srrsextern struct stn_cc cc_table_xgs_0;
345198160Srrsextern struct stn_cc cc_table_xgs_1;
346198160Srrsextern struct stn_cc cc_table_gmac;
347198160Srrsextern struct stn_cc cc_table_dma;
348198160Srrsextern struct stn_cc cc_table_sec;
349198160Srrs
350198160Srrsextern struct bucket_size xls_bucket_sizes;
351198160Srrs
352198160Srrsextern struct stn_cc xls_cc_table_cpu_0;
353198160Srrsextern struct stn_cc xls_cc_table_cpu_1;
354198160Srrsextern struct stn_cc xls_cc_table_cpu_2;
355198160Srrsextern struct stn_cc xls_cc_table_cpu_3;
356198160Srrsextern struct stn_cc xls_cc_table_gmac0;
357198160Srrsextern struct stn_cc xls_cc_table_gmac1;
358198160Srrsextern struct stn_cc xls_cc_table_cmp;
359198160Srrsextern struct stn_cc xls_cc_table_pcie;
360198160Srrsextern struct stn_cc xls_cc_table_dma;
361198160Srrsextern struct stn_cc xls_cc_table_sec;
362198160Srrs
363213377Sjchandratypedef void (*msgring_handler)(int, int, int, int, struct msgrng_msg *, void *);
364213377Sjchandraint register_msgring_handler(int startb, int endb, msgring_handler action,
365213377Sjchandra		    void *arg);
366212790Sjchandrauint32_t xlr_msgring_handler(uint8_t bucket_mask, uint32_t max_messages);
367212790Sjchandravoid xlr_msgring_cpu_init(void);
368212790Sjchandravoid xlr_msgring_config(void);
369198160Srrs
370198160Srrs#endif
371