/* SPDX-License-Identifier: GPL-2.0+ */
/*
 * ipmi_smi.h
 *
 * MontaVista IPMI system management interface
 *
 * Author: MontaVista Software, Inc.
 *         Corey Minyard <minyard@mvista.com>
 *         source@mvista.com
 *
 * Copyright 2002 MontaVista Software Inc.
 *
 */

#ifndef __LINUX_IPMI_SMI_H
#define __LINUX_IPMI_SMI_H

#include <linux/ipmi_msgdefs.h>
#include <linux/proc_fs.h>
#include <linux/platform_device.h>
#include <linux/ipmi.h>

struct device;

/* This files describes the interface for IPMI system management interface
   drivers to bind into the IPMI message handler. */

/* Structure for the low-level drivers. */
typedef struct ipmi_smi *ipmi_smi_t;

/*
 * Messages to/from the lower layer.  The smi interface will take one
 * of these to send. After the send has occurred and a response has
 * been received, it will report this same data structure back up to
 * the upper layer.  If an error occurs, it should fill in the
 * response with an error code in the completion code location. When
 * asynchronous data is received, one of these is allocated, the
 * data_size is set to zero and the response holds the data from the
 * get message or get event command that the interface initiated.
 * Note that it is the interfaces responsibility to detect
 * asynchronous data and messages and request them from the
 * interface.
 */
struct ipmi_smi_msg {
	struct list_head link;

	long    msgid;
	void    *user_data;

	int           data_size;
	unsigned char data[IPMI_MAX_MSG_LENGTH];

	int           rsp_size;
	unsigned char rsp[IPMI_MAX_MSG_LENGTH];

	/* Will be called when the system is done with the message
	   (presumably to free it). */
	void (*done)(struct ipmi_smi_msg *msg);
};

struct ipmi_smi_handlers {
	struct module *owner;

	/* The low-level interface cannot start sending messages to
	   the upper layer until this function is called.  This may
	   not be NULL, the lower layer must take the interface from
	   this call. */
	int (*start_processing)(void       *send_info,
				ipmi_smi_t new_intf);

	/*
	 * Get the detailed private info of the low level interface and store
	 * it into the structure of ipmi_smi_data. For example: the
	 * ACPI device handle will be returned for the pnp_acpi IPMI device.
	 */
	int (*get_smi_info)(void *send_info, struct ipmi_smi_info *data);

	/* Called to enqueue an SMI message to be sent.  This
	   operation is not allowed to fail.  If an error occurs, it
	   should report back the error in a received message.  It may
	   do this in the current call context, since no write locks
	   are held when this is run.  Message are delivered one at
	   a time by the message handler, a new message will not be
	   delivered until the previous message is returned. */
	void (*sender)(void                *send_info,
		       struct ipmi_smi_msg *msg);

	/* Called by the upper layer to request that we try to get
	   events from the BMC we are attached to. */
	void (*request_events)(void *send_info);

	/* Called by the upper layer when some user requires that the
	   interface watch for events, received messages, watchdog
	   pretimeouts, or not.  Used by the SMI to know if it should
	   watch for these.  This may be NULL if the SMI does not
	   implement it. */
	void (*set_need_watch)(void *send_info, bool enable);

	/*
	 * Called when flushing all pending messages.
	 */
	void (*flush_messages)(void *send_info);

	/* Called when the interface should go into "run to
	   completion" mode.  If this call sets the value to true, the
	   interface should make sure that all messages are flushed
	   out and that none are pending, and any new requests are run
	   to completion immediately. */
	void (*set_run_to_completion)(void *send_info, bool run_to_completion);

	/* Called to poll for work to do.  This is so upper layers can
	   poll for operations during things like crash dumps. */
	void (*poll)(void *send_info);

	/* Enable/disable firmware maintenance mode.  Note that this
	   is *not* the modes defined, this is simply an on/off
	   setting.  The message handler does the mode handling.  Note
	   that this is called from interrupt context, so it cannot
	   block. */
	void (*set_maintenance_mode)(void *send_info, bool enable);

	/* Tell the handler that we are using it/not using it.  The
	   message handler get the modules that this handler belongs
	   to; this function lets the SMI claim any modules that it
	   uses.  These may be NULL if this is not required. */
	int (*inc_usecount)(void *send_info);
	void (*dec_usecount)(void *send_info);
};

struct ipmi_device_id {
	unsigned char device_id;
	unsigned char device_revision;
	unsigned char firmware_revision_1;
	unsigned char firmware_revision_2;
	unsigned char ipmi_version;
	unsigned char additional_device_support;
	unsigned int  manufacturer_id;
	unsigned int  product_id;
	unsigned char aux_firmware_revision[4];
	unsigned int  aux_firmware_revision_set : 1;
};

#define ipmi_version_major(v) ((v)->ipmi_version & 0xf)
#define ipmi_version_minor(v) ((v)->ipmi_version >> 4)

/* Take a pointer to an IPMI response and extract device id information from
 * it. @netfn is in the IPMI_NETFN_ format, so may need to be shifted from
 * a SI response.
 */
static inline int ipmi_demangle_device_id(uint8_t netfn, uint8_t cmd,
					  const unsigned char *data,
					  unsigned int data_len,
					  struct ipmi_device_id *id)
{
	if (data_len < 7)
		return -EINVAL;
	if (netfn != IPMI_NETFN_APP_RESPONSE || cmd != IPMI_GET_DEVICE_ID_CMD)
		/* Strange, didn't get the response we expected. */
		return -EINVAL;
	if (data[0] != 0)
		/* That's odd, it shouldn't be able to fail. */
		return -EINVAL;

	data++;
	data_len--;

	id->device_id = data[0];
	id->device_revision = data[1];
	id->firmware_revision_1 = data[2];
	id->firmware_revision_2 = data[3];
	id->ipmi_version = data[4];
	id->additional_device_support = data[5];
	if (data_len >= 11) {
		id->manufacturer_id = (data[6] | (data[7] << 8) |
				       (data[8] << 16));
		id->product_id = data[9] | (data[10] << 8);
	} else {
		id->manufacturer_id = 0;
		id->product_id = 0;
	}
	if (data_len >= 15) {
		memcpy(id->aux_firmware_revision, data+11, 4);
		id->aux_firmware_revision_set = 1;
	} else
		id->aux_firmware_revision_set = 0;

	return 0;
}

/* Add a low-level interface to the IPMI driver.  Note that if the
   interface doesn't know its slave address, it should pass in zero.
   The low-level interface should not deliver any messages to the
   upper layer until the start_processing() function in the handlers
   is called, and the lower layer must get the interface from that
   call. */
int ipmi_register_smi(const struct ipmi_smi_handlers *handlers,
		      void                     *send_info,
		      struct device            *dev,
		      unsigned char            slave_addr);

/*
 * Remove a low-level interface from the IPMI driver.  This will
 * return an error if the interface is still in use by a user.
 */
int ipmi_unregister_smi(ipmi_smi_t intf);

/*
 * The lower layer reports received messages through this interface.
 * The data_size should be zero if this is an asynchronous message.  If
 * the lower layer gets an error sending a message, it should format
 * an error response in the message response.
 */
void ipmi_smi_msg_received(ipmi_smi_t          intf,
			   struct ipmi_smi_msg *msg);

/* The lower layer received a watchdog pre-timeout on interface. */
void ipmi_smi_watchdog_pretimeout(ipmi_smi_t intf);

struct ipmi_smi_msg *ipmi_alloc_smi_msg(void);
static inline void ipmi_free_smi_msg(struct ipmi_smi_msg *msg)
{
	msg->done(msg);
}

#ifdef CONFIG_IPMI_PROC_INTERFACE
/* Allow the lower layer to add things to the proc filesystem
   directory for this interface.  Note that the entry will
   automatically be dstroyed when the interface is destroyed. */
int ipmi_smi_add_proc_entry(ipmi_smi_t smi, char *name,
			    const struct file_operations *proc_ops,
			    void *data);
#endif

#endif /* __LINUX_IPMI_SMI_H */
