/*
 * This file is subject to the terms and conditions of the GNU General Public
 * License.  See the file "COPYING" in the main directory of this archive
 * for more details.
 *
 * (C) Copyright 2020 Hewlett Packard Enterprise Development LP
 * Copyright (C) 2004-2008 Silicon Graphics, Inc. All rights reserved.
 */

/*
 * External Cross Partition (XP) structures and defines.
 */

#ifndef _DRIVERS_MISC_SGIXP_XP_H
#define _DRIVERS_MISC_SGIXP_XP_H

#include <linux/mutex.h>

#if defined CONFIG_X86_UV || defined CONFIG_IA64_SGI_UV
#include <asm/uv/uv.h>
#endif

#ifdef USE_DBUG_ON
#define DBUG_ON(condition)	BUG_ON(condition)
#else
#define DBUG_ON(condition)
#endif

/*
 * Define the maximum number of partitions the system can possibly support.
 * It is based on the maximum number of hardware partitionable regions. The
 * term 'region' in this context refers to the minimum number of nodes that
 * can comprise an access protection grouping. The access protection is in
 * regards to memory, IPI and IOI.
 *
 * The maximum number of hardware partitionable regions is equal to the
 * maximum number of nodes in the entire system divided by the minimum number
 * of nodes that comprise an access protection grouping.
 */
#define XP_MAX_NPARTITIONS_SN2	64
#define XP_MAX_NPARTITIONS_UV	256

/*
 * XPC establishes channel connections between the local partition and any
 * other partition that is currently up. Over these channels, kernel-level
 * `users' can communicate with their counterparts on the other partitions.
 *
 * If the need for additional channels arises, one can simply increase
 * XPC_MAX_NCHANNELS accordingly. If the day should come where that number
 * exceeds the absolute MAXIMUM number of channels possible (eight), then one
 * will need to make changes to the XPC code to accommodate for this.
 *
 * The absolute maximum number of channels possible is limited to eight for
 * performance reasons on sn2 hardware. The internal cross partition structures
 * require sixteen bytes per channel, and eight allows all of this
 * interface-shared info to fit in one 128-byte cacheline.
 */
#define XPC_MEM_CHANNEL		0	/* memory channel number */
#define	XPC_NET_CHANNEL		1	/* network channel number */

#define XPC_MAX_NCHANNELS	2	/* max #of channels allowed */

#if XPC_MAX_NCHANNELS > 8
#error	XPC_MAX_NCHANNELS exceeds absolute MAXIMUM possible.
#endif

/*
 * Define macro, XPC_MSG_SIZE(), is provided for the user
 * that wants to fit as many msg entries as possible in a given memory size
 * (e.g. a memory page).
 */
#define XPC_MSG_MAX_SIZE	128
#define XPC_MSG_HDR_MAX_SIZE	16
#define XPC_MSG_PAYLOAD_MAX_SIZE (XPC_MSG_MAX_SIZE - XPC_MSG_HDR_MAX_SIZE)

#define XPC_MSG_SIZE(_payload_size) \
				ALIGN(XPC_MSG_HDR_MAX_SIZE + (_payload_size), \
				      is_uv_system() ? 64 : 128)


/*
 * Define the return values and values passed to user's callout functions.
 * (It is important to add new value codes at the end just preceding
 * xpUnknownReason, which must have the highest numerical value.)
 */
enum xp_retval {
	xpSuccess = 0,

	xpNotConnected,		/*  1: channel is not connected */
	xpConnected,		/*  2: channel connected (opened) */
	xpRETIRED1,		/*  3: (formerly xpDisconnected) */

	xpMsgReceived,		/*  4: message received */
	xpMsgDelivered,		/*  5: message delivered and acknowledged */

	xpRETIRED2,		/*  6: (formerly xpTransferFailed) */

	xpNoWait,		/*  7: operation would require wait */
	xpRetry,		/*  8: retry operation */
	xpTimeout,		/*  9: timeout in xpc_allocate_msg_wait() */
	xpInterrupted,		/* 10: interrupted wait */

	xpUnequalMsgSizes,	/* 11: message size disparity between sides */
	xpInvalidAddress,	/* 12: invalid address */

	xpNoMemory,		/* 13: no memory available for XPC structures */
	xpLackOfResources,	/* 14: insufficient resources for operation */
	xpUnregistered,		/* 15: channel is not registered */
	xpAlreadyRegistered,	/* 16: channel is already registered */

	xpPartitionDown,	/* 17: remote partition is down */
	xpNotLoaded,		/* 18: XPC module is not loaded */
	xpUnloading,		/* 19: this side is unloading XPC module */

	xpBadMagic,		/* 20: XPC MAGIC string not found */

	xpReactivating,		/* 21: remote partition was reactivated */

	xpUnregistering,	/* 22: this side is unregistering channel */
	xpOtherUnregistering,	/* 23: other side is unregistering channel */

	xpCloneKThread,		/* 24: cloning kernel thread */
	xpCloneKThreadFailed,	/* 25: cloning kernel thread failed */

	xpNoHeartbeat,		/* 26: remote partition has no heartbeat */

	xpPioReadError,		/* 27: PIO read error */
	xpPhysAddrRegFailed,	/* 28: registration of phys addr range failed */

	xpRETIRED3,		/* 29: (formerly xpBteDirectoryError) */
	xpRETIRED4,		/* 30: (formerly xpBtePoisonError) */
	xpRETIRED5,		/* 31: (formerly xpBteWriteError) */
	xpRETIRED6,		/* 32: (formerly xpBteAccessError) */
	xpRETIRED7,		/* 33: (formerly xpBtePWriteError) */
	xpRETIRED8,		/* 34: (formerly xpBtePReadError) */
	xpRETIRED9,		/* 35: (formerly xpBteTimeOutError) */
	xpRETIRED10,		/* 36: (formerly xpBteXtalkError) */
	xpRETIRED11,		/* 37: (formerly xpBteNotAvailable) */
	xpRETIRED12,		/* 38: (formerly xpBteUnmappedError) */

	xpBadVersion,		/* 39: bad version number */
	xpVarsNotSet,		/* 40: the XPC variables are not set up */
	xpNoRsvdPageAddr,	/* 41: unable to get rsvd page's phys addr */
	xpInvalidPartid,	/* 42: invalid partition ID */
	xpLocalPartid,		/* 43: local partition ID */

	xpOtherGoingDown,	/* 44: other side going down, reason unknown */
	xpSystemGoingDown,	/* 45: system is going down, reason unknown */
	xpSystemHalt,		/* 46: system is being halted */
	xpSystemReboot,		/* 47: system is being rebooted */
	xpSystemPoweroff,	/* 48: system is being powered off */

	xpDisconnecting,	/* 49: channel disconnecting (closing) */

	xpOpenCloseError,	/* 50: channel open/close protocol error */

	xpDisconnected,		/* 51: channel disconnected (closed) */

	xpBteCopyError,		/* 52: bte_copy() returned error */
	xpSalError,		/* 53: sn SAL error */
	xpRsvdPageNotSet,	/* 54: the reserved page is not set up */
	xpPayloadTooBig,	/* 55: payload too large for message slot */

	xpUnsupported,		/* 56: unsupported functionality or resource */
	xpNeedMoreInfo,		/* 57: more info is needed by SAL */

	xpGruCopyError,		/* 58: gru_copy_gru() returned error */
	xpGruSendMqError,	/* 59: gru send message queue related error */

	xpBadChannelNumber,	/* 60: invalid channel number */
	xpBadMsgType,		/* 61: invalid message type */
	xpBiosError,		/* 62: BIOS error */

	xpUnknownReason		/* 63: unknown reason - must be last in enum */
};

/*
 * Define the callout function type used by XPC to update the user on
 * connection activity and state changes via the user function registered
 * by xpc_connect().
 *
 * Arguments:
 *
 *	reason - reason code.
 *	partid - partition ID associated with condition.
 *	ch_number - channel # associated with condition.
 *	data - pointer to optional data.
 *	key - pointer to optional user-defined value provided as the "key"
 *	      argument to xpc_connect().
 *
 * A reason code of xpConnected indicates that a connection has been
 * established to the specified partition on the specified channel. The data
 * argument indicates the max number of entries allowed in the message queue.
 *
 * A reason code of xpMsgReceived indicates that a XPC message arrived from
 * the specified partition on the specified channel. The data argument
 * specifies the address of the message's payload. The user must call
 * xpc_received() when finished with the payload.
 *
 * All other reason codes indicate failure. The data argmument is NULL.
 * When a failure reason code is received, one can assume that the channel
 * is not connected.
 */
typedef void (*xpc_channel_func) (enum xp_retval reason, short partid,
				  int ch_number, void *data, void *key);

/*
 * Define the callout function type used by XPC to notify the user of
 * messages received and delivered via the user function registered by
 * xpc_send_notify().
 *
 * Arguments:
 *
 *	reason - reason code.
 *	partid - partition ID associated with condition.
 *	ch_number - channel # associated with condition.
 *	key - pointer to optional user-defined value provided as the "key"
 *	      argument to xpc_send_notify().
 *
 * A reason code of xpMsgDelivered indicates that the message was delivered
 * to the intended recipient and that they have acknowledged its receipt by
 * calling xpc_received().
 *
 * All other reason codes indicate failure.
 *
 * NOTE: The user defined function must be callable by an interrupt handler
 *       and thus cannot block.
 */
typedef void (*xpc_notify_func) (enum xp_retval reason, short partid,
				 int ch_number, void *key);

/*
 * The following is a registration entry. There is a global array of these,
 * one per channel. It is used to record the connection registration made
 * by the users of XPC. As long as a registration entry exists, for any
 * partition that comes up, XPC will attempt to establish a connection on
 * that channel. Notification that a connection has been made will occur via
 * the xpc_channel_func function.
 *
 * The 'func' field points to the function to call when aynchronous
 * notification is required for such events as: a connection established/lost,
 * or an incoming message received, or an error condition encountered. A
 * non-NULL 'func' field indicates that there is an active registration for
 * the channel.
 */
struct xpc_registration {
	struct mutex mutex;
	xpc_channel_func func;	/* function to call */
	void *key;		/* pointer to user's key */
	u16 nentries;		/* #of msg entries in local msg queue */
	u16 entry_size;		/* message queue's message entry size */
	u32 assigned_limit;	/* limit on #of assigned kthreads */
	u32 idle_limit;		/* limit on #of idle kthreads */
} ____cacheline_aligned;

#define XPC_CHANNEL_REGISTERED(_c)	(xpc_registrations[_c].func != NULL)

/* the following are valid xpc_send() or xpc_send_notify() flags */
#define XPC_WAIT	0	/* wait flag */
#define XPC_NOWAIT	1	/* no wait flag */

struct xpc_interface {
	void (*connect) (int);
	void (*disconnect) (int);
	enum xp_retval (*send) (short, int, u32, void *, u16);
	enum xp_retval (*send_notify) (short, int, u32, void *, u16,
					xpc_notify_func, void *);
	void (*received) (short, int, void *);
	enum xp_retval (*partid_to_nasids) (short, void *);
};

extern struct xpc_interface xpc_interface;

extern void xpc_set_interface(void (*)(int),
			      void (*)(int),
			      enum xp_retval (*)(short, int, u32, void *, u16),
			      enum xp_retval (*)(short, int, u32, void *, u16,
						 xpc_notify_func, void *),
			      void (*)(short, int, void *),
			      enum xp_retval (*)(short, void *));
extern void xpc_clear_interface(void);

extern enum xp_retval xpc_connect(int, xpc_channel_func, void *, u16,
				   u16, u32, u32);
extern void xpc_disconnect(int);

static inline enum xp_retval
xpc_send(short partid, int ch_number, u32 flags, void *payload,
	 u16 payload_size)
{
	if (!xpc_interface.send)
		return xpNotLoaded;

	return xpc_interface.send(partid, ch_number, flags, payload,
				  payload_size);
}

static inline enum xp_retval
xpc_send_notify(short partid, int ch_number, u32 flags, void *payload,
		u16 payload_size, xpc_notify_func func, void *key)
{
	if (!xpc_interface.send_notify)
		return xpNotLoaded;

	return xpc_interface.send_notify(partid, ch_number, flags, payload,
					 payload_size, func, key);
}

static inline void
xpc_received(short partid, int ch_number, void *payload)
{
	if (xpc_interface.received)
		xpc_interface.received(partid, ch_number, payload);
}

static inline enum xp_retval
xpc_partid_to_nasids(short partid, void *nasids)
{
	if (!xpc_interface.partid_to_nasids)
		return xpNotLoaded;

	return xpc_interface.partid_to_nasids(partid, nasids);
}

extern short xp_max_npartitions;
extern short xp_partition_id;
extern u8 xp_region_size;

extern unsigned long (*xp_pa) (void *);
extern unsigned long (*xp_socket_pa) (unsigned long);
extern enum xp_retval (*xp_remote_memcpy) (unsigned long, const unsigned long,
		       size_t);
extern int (*xp_cpu_to_nasid) (int);
extern enum xp_retval (*xp_expand_memprotect) (unsigned long, unsigned long);
extern enum xp_retval (*xp_restrict_memprotect) (unsigned long, unsigned long);

extern u64 xp_nofault_PIOR_target;
extern int xp_nofault_PIOR(void *);
extern int xp_error_PIOR(void);

extern struct device *xp;
extern enum xp_retval xp_init_uv(void);
extern void xp_exit_uv(void);

#endif /* _DRIVERS_MISC_SGIXP_XP_H */
