18c2ecf20Sopenharmony_ci/* SPDX-License-Identifier: GPL-2.0-or-later */
28c2ecf20Sopenharmony_ci
38c2ecf20Sopenharmony_ci/*
48c2ecf20Sopenharmony_ci *  Copyright (c) 2008 Silicon Graphics, Inc.  All Rights Reserved.
58c2ecf20Sopenharmony_ci */
68c2ecf20Sopenharmony_ci#ifndef __GRU_KSERVICES_H_
78c2ecf20Sopenharmony_ci#define __GRU_KSERVICES_H_
88c2ecf20Sopenharmony_ci
98c2ecf20Sopenharmony_ci
108c2ecf20Sopenharmony_ci/*
118c2ecf20Sopenharmony_ci * Message queues using the GRU to send/receive messages.
128c2ecf20Sopenharmony_ci *
138c2ecf20Sopenharmony_ci * These function allow the user to create a message queue for
148c2ecf20Sopenharmony_ci * sending/receiving 1 or 2 cacheline messages using the GRU.
158c2ecf20Sopenharmony_ci *
168c2ecf20Sopenharmony_ci * Processes SENDING messages will use a kernel CBR/DSR to send
178c2ecf20Sopenharmony_ci * the message. This is transparent to the caller.
188c2ecf20Sopenharmony_ci *
198c2ecf20Sopenharmony_ci * The receiver does not use any GRU resources.
208c2ecf20Sopenharmony_ci *
218c2ecf20Sopenharmony_ci * The functions support:
228c2ecf20Sopenharmony_ci * 	- single receiver
238c2ecf20Sopenharmony_ci * 	- multiple senders
248c2ecf20Sopenharmony_ci *	- cross partition message
258c2ecf20Sopenharmony_ci *
268c2ecf20Sopenharmony_ci * Missing features ZZZ:
278c2ecf20Sopenharmony_ci * 	- user options for dealing with timeouts, queue full, etc.
288c2ecf20Sopenharmony_ci * 	- gru_create_message_queue() needs interrupt vector info
298c2ecf20Sopenharmony_ci */
308c2ecf20Sopenharmony_ci
318c2ecf20Sopenharmony_cistruct gru_message_queue_desc {
328c2ecf20Sopenharmony_ci	void		*mq;			/* message queue vaddress */
338c2ecf20Sopenharmony_ci	unsigned long	mq_gpa;			/* global address of mq */
348c2ecf20Sopenharmony_ci	int		qlines;			/* queue size in CL */
358c2ecf20Sopenharmony_ci	int		interrupt_vector;	/* interrupt vector */
368c2ecf20Sopenharmony_ci	int		interrupt_pnode;	/* pnode for interrupt */
378c2ecf20Sopenharmony_ci	int		interrupt_apicid;	/* lapicid for interrupt */
388c2ecf20Sopenharmony_ci};
398c2ecf20Sopenharmony_ci
408c2ecf20Sopenharmony_ci/*
418c2ecf20Sopenharmony_ci * Initialize a user allocated chunk of memory to be used as
428c2ecf20Sopenharmony_ci * a message queue. The caller must ensure that the queue is
438c2ecf20Sopenharmony_ci * in contiguous physical memory and is cacheline aligned.
448c2ecf20Sopenharmony_ci *
458c2ecf20Sopenharmony_ci * Message queue size is the total number of bytes allocated
468c2ecf20Sopenharmony_ci * to the queue including a 2 cacheline header that is used
478c2ecf20Sopenharmony_ci * to manage the queue.
488c2ecf20Sopenharmony_ci *
498c2ecf20Sopenharmony_ci *  Input:
508c2ecf20Sopenharmony_ci * 	mqd	pointer to message queue descriptor
518c2ecf20Sopenharmony_ci * 	p	pointer to user allocated mesq memory.
528c2ecf20Sopenharmony_ci * 	bytes	size of message queue in bytes
538c2ecf20Sopenharmony_ci *      vector	interrupt vector (zero if no interrupts)
548c2ecf20Sopenharmony_ci *      nasid	nasid of blade where interrupt is delivered
558c2ecf20Sopenharmony_ci *      apicid	apicid of cpu for interrupt
568c2ecf20Sopenharmony_ci *
578c2ecf20Sopenharmony_ci *  Errors:
588c2ecf20Sopenharmony_ci *  	0	OK
598c2ecf20Sopenharmony_ci *  	>0	error
608c2ecf20Sopenharmony_ci */
618c2ecf20Sopenharmony_ciextern int gru_create_message_queue(struct gru_message_queue_desc *mqd,
628c2ecf20Sopenharmony_ci		void *p, unsigned int bytes, int nasid, int vector, int apicid);
638c2ecf20Sopenharmony_ci
648c2ecf20Sopenharmony_ci/*
658c2ecf20Sopenharmony_ci * Send a message to a message queue.
668c2ecf20Sopenharmony_ci *
678c2ecf20Sopenharmony_ci * Note: The message queue transport mechanism uses the first 32
688c2ecf20Sopenharmony_ci * bits of the message. Users should avoid using these bits.
698c2ecf20Sopenharmony_ci *
708c2ecf20Sopenharmony_ci *
718c2ecf20Sopenharmony_ci *   Input:
728c2ecf20Sopenharmony_ci * 	mqd	pointer to message queue descriptor
738c2ecf20Sopenharmony_ci * 	mesg	pointer to message. Must be 64-bit aligned
748c2ecf20Sopenharmony_ci * 	bytes	size of message in bytes
758c2ecf20Sopenharmony_ci *
768c2ecf20Sopenharmony_ci *   Output:
778c2ecf20Sopenharmony_ci *      0	message sent
788c2ecf20Sopenharmony_ci *     >0	Send failure - see error codes below
798c2ecf20Sopenharmony_ci *
808c2ecf20Sopenharmony_ci */
818c2ecf20Sopenharmony_ciextern int gru_send_message_gpa(struct gru_message_queue_desc *mqd,
828c2ecf20Sopenharmony_ci			void *mesg, unsigned int bytes);
838c2ecf20Sopenharmony_ci
848c2ecf20Sopenharmony_ci/* Status values for gru_send_message() */
858c2ecf20Sopenharmony_ci#define MQE_OK			0	/* message sent successfully */
868c2ecf20Sopenharmony_ci#define MQE_CONGESTION		1	/* temporary congestion, try again */
878c2ecf20Sopenharmony_ci#define MQE_QUEUE_FULL		2	/* queue is full */
888c2ecf20Sopenharmony_ci#define MQE_UNEXPECTED_CB_ERR	3	/* unexpected CB error */
898c2ecf20Sopenharmony_ci#define MQE_PAGE_OVERFLOW	10	/* BUG - queue overflowed a page */
908c2ecf20Sopenharmony_ci#define MQE_BUG_NO_RESOURCES	11	/* BUG - could not alloc GRU cb/dsr */
918c2ecf20Sopenharmony_ci
928c2ecf20Sopenharmony_ci/*
938c2ecf20Sopenharmony_ci * Advance the receive pointer for the message queue to the next message.
948c2ecf20Sopenharmony_ci * Note: current API requires messages to be gotten & freed in order. Future
958c2ecf20Sopenharmony_ci * API extensions may allow for out-of-order freeing.
968c2ecf20Sopenharmony_ci *
978c2ecf20Sopenharmony_ci *   Input
988c2ecf20Sopenharmony_ci * 	mqd	pointer to message queue descriptor
998c2ecf20Sopenharmony_ci * 	mesq	message being freed
1008c2ecf20Sopenharmony_ci */
1018c2ecf20Sopenharmony_ciextern void gru_free_message(struct gru_message_queue_desc *mqd,
1028c2ecf20Sopenharmony_ci			     void *mesq);
1038c2ecf20Sopenharmony_ci
1048c2ecf20Sopenharmony_ci/*
1058c2ecf20Sopenharmony_ci * Get next message from message queue. Returns pointer to
1068c2ecf20Sopenharmony_ci * message OR NULL if no message present.
1078c2ecf20Sopenharmony_ci * User must call gru_free_message() after message is processed
1088c2ecf20Sopenharmony_ci * in order to move the queue pointers to next message.
1098c2ecf20Sopenharmony_ci *
1108c2ecf20Sopenharmony_ci *   Input
1118c2ecf20Sopenharmony_ci * 	mqd	pointer to message queue descriptor
1128c2ecf20Sopenharmony_ci *
1138c2ecf20Sopenharmony_ci *   Output:
1148c2ecf20Sopenharmony_ci *	p	pointer to message
1158c2ecf20Sopenharmony_ci *	NULL	no message available
1168c2ecf20Sopenharmony_ci */
1178c2ecf20Sopenharmony_ciextern void *gru_get_next_message(struct gru_message_queue_desc *mqd);
1188c2ecf20Sopenharmony_ci
1198c2ecf20Sopenharmony_ci
1208c2ecf20Sopenharmony_ci/*
1218c2ecf20Sopenharmony_ci * Read a GRU global GPA. Source can be located in a remote partition.
1228c2ecf20Sopenharmony_ci *
1238c2ecf20Sopenharmony_ci *    Input:
1248c2ecf20Sopenharmony_ci *    	value		memory address where MMR value is returned
1258c2ecf20Sopenharmony_ci *    	gpa		source numalink physical address of GPA
1268c2ecf20Sopenharmony_ci *
1278c2ecf20Sopenharmony_ci *    Output:
1288c2ecf20Sopenharmony_ci *	0		OK
1298c2ecf20Sopenharmony_ci *	>0		error
1308c2ecf20Sopenharmony_ci */
1318c2ecf20Sopenharmony_ciint gru_read_gpa(unsigned long *value, unsigned long gpa);
1328c2ecf20Sopenharmony_ci
1338c2ecf20Sopenharmony_ci
1348c2ecf20Sopenharmony_ci/*
1358c2ecf20Sopenharmony_ci * Copy data using the GRU. Source or destination can be located in a remote
1368c2ecf20Sopenharmony_ci * partition.
1378c2ecf20Sopenharmony_ci *
1388c2ecf20Sopenharmony_ci *    Input:
1398c2ecf20Sopenharmony_ci *    	dest_gpa	destination global physical address
1408c2ecf20Sopenharmony_ci *    	src_gpa		source global physical address
1418c2ecf20Sopenharmony_ci *    	bytes		number of bytes to copy
1428c2ecf20Sopenharmony_ci *
1438c2ecf20Sopenharmony_ci *    Output:
1448c2ecf20Sopenharmony_ci *	0		OK
1458c2ecf20Sopenharmony_ci *	>0		error
1468c2ecf20Sopenharmony_ci */
1478c2ecf20Sopenharmony_ciextern int gru_copy_gpa(unsigned long dest_gpa, unsigned long src_gpa,
1488c2ecf20Sopenharmony_ci							unsigned int bytes);
1498c2ecf20Sopenharmony_ci
1508c2ecf20Sopenharmony_ci/*
1518c2ecf20Sopenharmony_ci * Reserve GRU resources to be used asynchronously.
1528c2ecf20Sopenharmony_ci *
1538c2ecf20Sopenharmony_ci * 	input:
1548c2ecf20Sopenharmony_ci * 		blade_id  - blade on which resources should be reserved
1558c2ecf20Sopenharmony_ci * 		cbrs	  - number of CBRs
1568c2ecf20Sopenharmony_ci * 		dsr_bytes - number of DSR bytes needed
1578c2ecf20Sopenharmony_ci * 		cmp	  - completion structure for waiting for
1588c2ecf20Sopenharmony_ci * 			    async completions
1598c2ecf20Sopenharmony_ci *	output:
1608c2ecf20Sopenharmony_ci *		handle to identify resource
1618c2ecf20Sopenharmony_ci *		(0 = no resources)
1628c2ecf20Sopenharmony_ci */
1638c2ecf20Sopenharmony_ciextern unsigned long gru_reserve_async_resources(int blade_id, int cbrs, int dsr_bytes,
1648c2ecf20Sopenharmony_ci				struct completion *cmp);
1658c2ecf20Sopenharmony_ci
1668c2ecf20Sopenharmony_ci/*
1678c2ecf20Sopenharmony_ci * Release async resources previously reserved.
1688c2ecf20Sopenharmony_ci *
1698c2ecf20Sopenharmony_ci *	input:
1708c2ecf20Sopenharmony_ci *		han - handle to identify resources
1718c2ecf20Sopenharmony_ci */
1728c2ecf20Sopenharmony_ciextern void gru_release_async_resources(unsigned long han);
1738c2ecf20Sopenharmony_ci
1748c2ecf20Sopenharmony_ci/*
1758c2ecf20Sopenharmony_ci * Wait for async GRU instructions to complete.
1768c2ecf20Sopenharmony_ci *
1778c2ecf20Sopenharmony_ci *	input:
1788c2ecf20Sopenharmony_ci *		han - handle to identify resources
1798c2ecf20Sopenharmony_ci */
1808c2ecf20Sopenharmony_ciextern void gru_wait_async_cbr(unsigned long han);
1818c2ecf20Sopenharmony_ci
1828c2ecf20Sopenharmony_ci/*
1838c2ecf20Sopenharmony_ci * Lock previous reserved async GRU resources
1848c2ecf20Sopenharmony_ci *
1858c2ecf20Sopenharmony_ci *	input:
1868c2ecf20Sopenharmony_ci *		han - handle to identify resources
1878c2ecf20Sopenharmony_ci *	output:
1888c2ecf20Sopenharmony_ci *		cb  - pointer to first CBR
1898c2ecf20Sopenharmony_ci *		dsr - pointer to first DSR
1908c2ecf20Sopenharmony_ci */
1918c2ecf20Sopenharmony_ciextern void gru_lock_async_resource(unsigned long han,  void **cb, void **dsr);
1928c2ecf20Sopenharmony_ci
1938c2ecf20Sopenharmony_ci/*
1948c2ecf20Sopenharmony_ci * Unlock previous reserved async GRU resources
1958c2ecf20Sopenharmony_ci *
1968c2ecf20Sopenharmony_ci *	input:
1978c2ecf20Sopenharmony_ci *		han - handle to identify resources
1988c2ecf20Sopenharmony_ci */
1998c2ecf20Sopenharmony_ciextern void gru_unlock_async_resource(unsigned long han);
2008c2ecf20Sopenharmony_ci
2018c2ecf20Sopenharmony_ci#endif 		/* __GRU_KSERVICES_H_ */
202