1 /* SPDX-License-Identifier: GPL-2.0-or-later */
2 
3 /*
4  *  Copyright (c) 2008 Silicon Graphics, Inc.  All Rights Reserved.
5  */
6 #ifndef __GRU_KSERVICES_H_
7 #define __GRU_KSERVICES_H_
8 
9 
10 /*
11  * Message queues using the GRU to send/receive messages.
12  *
13  * These function allow the user to create a message queue for
14  * sending/receiving 1 or 2 cacheline messages using the GRU.
15  *
16  * Processes SENDING messages will use a kernel CBR/DSR to send
17  * the message. This is transparent to the caller.
18  *
19  * The receiver does not use any GRU resources.
20  *
21  * The functions support:
22  * 	- single receiver
23  * 	- multiple senders
24  *	- cross partition message
25  *
26  * Missing features ZZZ:
27  * 	- user options for dealing with timeouts, queue full, etc.
28  * 	- gru_create_message_queue() needs interrupt vector info
29  */
30 
31 struct gru_message_queue_desc {
32 	void		*mq;			/* message queue vaddress */
33 	unsigned long	mq_gpa;			/* global address of mq */
34 	int		qlines;			/* queue size in CL */
35 	int		interrupt_vector;	/* interrupt vector */
36 	int		interrupt_pnode;	/* pnode for interrupt */
37 	int		interrupt_apicid;	/* lapicid for interrupt */
38 };
39 
40 /*
41  * Initialize a user allocated chunk of memory to be used as
42  * a message queue. The caller must ensure that the queue is
43  * in contiguous physical memory and is cacheline aligned.
44  *
45  * Message queue size is the total number of bytes allocated
46  * to the queue including a 2 cacheline header that is used
47  * to manage the queue.
48  *
49  *  Input:
50  * 	mqd	pointer to message queue descriptor
51  * 	p	pointer to user allocated mesq memory.
52  * 	bytes	size of message queue in bytes
53  *      vector	interrupt vector (zero if no interrupts)
54  *      nasid	nasid of blade where interrupt is delivered
55  *      apicid	apicid of cpu for interrupt
56  *
57  *  Errors:
58  *  	0	OK
59  *  	>0	error
60  */
61 extern int gru_create_message_queue(struct gru_message_queue_desc *mqd,
62 		void *p, unsigned int bytes, int nasid, int vector, int apicid);
63 
64 /*
65  * Send a message to a message queue.
66  *
67  * Note: The message queue transport mechanism uses the first 32
68  * bits of the message. Users should avoid using these bits.
69  *
70  *
71  *   Input:
72  * 	mqd	pointer to message queue descriptor
73  * 	mesg	pointer to message. Must be 64-bit aligned
74  * 	bytes	size of message in bytes
75  *
76  *   Output:
77  *      0	message sent
78  *     >0	Send failure - see error codes below
79  *
80  */
81 extern int gru_send_message_gpa(struct gru_message_queue_desc *mqd,
82 			void *mesg, unsigned int bytes);
83 
84 /* Status values for gru_send_message() */
85 #define MQE_OK			0	/* message sent successfully */
86 #define MQE_CONGESTION		1	/* temporary congestion, try again */
87 #define MQE_QUEUE_FULL		2	/* queue is full */
88 #define MQE_UNEXPECTED_CB_ERR	3	/* unexpected CB error */
89 #define MQE_PAGE_OVERFLOW	10	/* BUG - queue overflowed a page */
90 #define MQE_BUG_NO_RESOURCES	11	/* BUG - could not alloc GRU cb/dsr */
91 
92 /*
93  * Advance the receive pointer for the message queue to the next message.
94  * Note: current API requires messages to be gotten & freed in order. Future
95  * API extensions may allow for out-of-order freeing.
96  *
97  *   Input
98  * 	mqd	pointer to message queue descriptor
99  * 	mesq	message being freed
100  */
101 extern void gru_free_message(struct gru_message_queue_desc *mqd,
102 			     void *mesq);
103 
104 /*
105  * Get next message from message queue. Returns pointer to
106  * message OR NULL if no message present.
107  * User must call gru_free_message() after message is processed
108  * in order to move the queue pointers to next message.
109  *
110  *   Input
111  * 	mqd	pointer to message queue descriptor
112  *
113  *   Output:
114  *	p	pointer to message
115  *	NULL	no message available
116  */
117 extern void *gru_get_next_message(struct gru_message_queue_desc *mqd);
118 
119 
120 /*
121  * Read a GRU global GPA. Source can be located in a remote partition.
122  *
123  *    Input:
124  *    	value		memory address where MMR value is returned
125  *    	gpa		source numalink physical address of GPA
126  *
127  *    Output:
128  *	0		OK
129  *	>0		error
130  */
131 int gru_read_gpa(unsigned long *value, unsigned long gpa);
132 
133 
134 /*
135  * Copy data using the GRU. Source or destination can be located in a remote
136  * partition.
137  *
138  *    Input:
139  *    	dest_gpa	destination global physical address
140  *    	src_gpa		source global physical address
141  *    	bytes		number of bytes to copy
142  *
143  *    Output:
144  *	0		OK
145  *	>0		error
146  */
147 extern int gru_copy_gpa(unsigned long dest_gpa, unsigned long src_gpa,
148 							unsigned int bytes);
149 
150 /*
151  * Reserve GRU resources to be used asynchronously.
152  *
153  * 	input:
154  * 		blade_id  - blade on which resources should be reserved
155  * 		cbrs	  - number of CBRs
156  * 		dsr_bytes - number of DSR bytes needed
157  * 		cmp	  - completion structure for waiting for
158  * 			    async completions
159  *	output:
160  *		handle to identify resource
161  *		(0 = no resources)
162  */
163 extern unsigned long gru_reserve_async_resources(int blade_id, int cbrs, int dsr_bytes,
164 				struct completion *cmp);
165 
166 /*
167  * Release async resources previously reserved.
168  *
169  *	input:
170  *		han - handle to identify resources
171  */
172 extern void gru_release_async_resources(unsigned long han);
173 
174 /*
175  * Wait for async GRU instructions to complete.
176  *
177  *	input:
178  *		han - handle to identify resources
179  */
180 extern void gru_wait_async_cbr(unsigned long han);
181 
182 /*
183  * Lock previous reserved async GRU resources
184  *
185  *	input:
186  *		han - handle to identify resources
187  *	output:
188  *		cb  - pointer to first CBR
189  *		dsr - pointer to first DSR
190  */
191 extern void gru_lock_async_resource(unsigned long han,  void **cb, void **dsr);
192 
193 /*
194  * Unlock previous reserved async GRU resources
195  *
196  *	input:
197  *		han - handle to identify resources
198  */
199 extern void gru_unlock_async_resource(unsigned long han);
200 
201 #endif 		/* __GRU_KSERVICES_H_ */
202