cachepc-linux

Fork of AMDESE/linux with modifications for CachePC side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-linux
Log | Files | Refs | README | LICENSE | sfeed.txt

ipmi_smi.h (10061B)


      1/* SPDX-License-Identifier: GPL-2.0+ */
      2/*
      3 * ipmi_smi.h
      4 *
      5 * MontaVista IPMI system management interface
      6 *
      7 * Author: MontaVista Software, Inc.
      8 *         Corey Minyard <minyard@mvista.com>
      9 *         source@mvista.com
     10 *
     11 * Copyright 2002 MontaVista Software Inc.
     12 *
     13 */
     14
     15#ifndef __LINUX_IPMI_SMI_H
     16#define __LINUX_IPMI_SMI_H
     17
     18#include <linux/ipmi_msgdefs.h>
     19#include <linux/proc_fs.h>
     20#include <linux/platform_device.h>
     21#include <linux/ipmi.h>
     22
     23struct device;
     24
     25/*
     26 * This files describes the interface for IPMI system management interface
     27 * drivers to bind into the IPMI message handler.
     28 */
     29
     30/* Structure for the low-level drivers. */
     31struct ipmi_smi;
     32
     33/*
     34 * Flags for set_check_watch() below.  Tells if the SMI should be
     35 * waiting for watchdog timeouts, commands and/or messages.
     36 */
     37#define IPMI_WATCH_MASK_CHECK_MESSAGES	(1 << 0)
     38#define IPMI_WATCH_MASK_CHECK_WATCHDOG	(1 << 1)
     39#define IPMI_WATCH_MASK_CHECK_COMMANDS	(1 << 2)
     40
     41/*
     42 * SMI messages
     43 *
     44 * When communicating with an SMI, messages come in two formats:
     45 *
     46 * * Normal (to a BMC over a BMC interface)
     47 *
     48 * * IPMB (over a IPMB to another MC)
     49 *
     50 * When normal, commands are sent using the format defined by a
     51 * standard message over KCS (NetFn must be even):
     52 *
     53 *   +-----------+-----+------+
     54 *   | NetFn/LUN | Cmd | Data |
     55 *   +-----------+-----+------+
     56 *
     57 * And responses, similarly, with an completion code added (NetFn must
     58 * be odd):
     59 *
     60 *   +-----------+-----+------+------+
     61 *   | NetFn/LUN | Cmd | CC   | Data |
     62 *   +-----------+-----+------+------+
     63 *
     64 * With normal messages, only commands are sent and only responses are
     65 * received.
     66 *
     67 * In IPMB mode, we are acting as an IPMB device. Commands will be in
     68 * the following format (NetFn must be even):
     69 *
     70 *   +-------------+------+-------------+-----+------+
     71 *   | NetFn/rsLUN | Addr | rqSeq/rqLUN | Cmd | Data |
     72 *   +-------------+------+-------------+-----+------+
     73 *
     74 * Responses will using the following format:
     75 *
     76 *   +-------------+------+-------------+-----+------+------+
     77 *   | NetFn/rqLUN | Addr | rqSeq/rsLUN | Cmd | CC   | Data |
     78 *   +-------------+------+-------------+-----+------+------+
     79 *
     80 * This is similar to the format defined in the IPMB manual section
     81 * 2.11.1 with the checksums and the first address removed.  Also, the
     82 * address is always the remote address.
     83 *
     84 * IPMB messages can be commands and responses in both directions.
     85 * Received commands are handled as received commands from the message
     86 * queue.
     87 */
     88
     89enum ipmi_smi_msg_type {
     90	IPMI_SMI_MSG_TYPE_NORMAL = 0,
     91	IPMI_SMI_MSG_TYPE_IPMB_DIRECT
     92};
     93
     94/*
     95 * Messages to/from the lower layer.  The smi interface will take one
     96 * of these to send. After the send has occurred and a response has
     97 * been received, it will report this same data structure back up to
     98 * the upper layer.  If an error occurs, it should fill in the
     99 * response with an error code in the completion code location. When
    100 * asynchronous data is received, one of these is allocated, the
    101 * data_size is set to zero and the response holds the data from the
    102 * get message or get event command that the interface initiated.
    103 * Note that it is the interfaces responsibility to detect
    104 * asynchronous data and messages and request them from the
    105 * interface.
    106 */
    107struct ipmi_smi_msg {
    108	struct list_head link;
    109
    110	enum ipmi_smi_msg_type type;
    111
    112	long    msgid;
    113	void    *user_data;
    114
    115	int           data_size;
    116	unsigned char data[IPMI_MAX_MSG_LENGTH];
    117
    118	int           rsp_size;
    119	unsigned char rsp[IPMI_MAX_MSG_LENGTH];
    120
    121	/*
    122	 * Will be called when the system is done with the message
    123	 * (presumably to free it).
    124	 */
    125	void (*done)(struct ipmi_smi_msg *msg);
    126};
    127
    128#define INIT_IPMI_SMI_MSG(done_handler) \
    129{						\
    130	.done = done_handler,			\
    131	.type = IPMI_SMI_MSG_TYPE_NORMAL	\
    132}
    133
    134struct ipmi_smi_handlers {
    135	struct module *owner;
    136
    137	/* Capabilities of the SMI. */
    138#define IPMI_SMI_CAN_HANDLE_IPMB_DIRECT		(1 << 0)
    139	unsigned int flags;
    140
    141	/*
    142	 * The low-level interface cannot start sending messages to
    143	 * the upper layer until this function is called.  This may
    144	 * not be NULL, the lower layer must take the interface from
    145	 * this call.
    146	 */
    147	int (*start_processing)(void            *send_info,
    148				struct ipmi_smi *new_intf);
    149
    150	/*
    151	 * When called, the low-level interface should disable all
    152	 * processing, it should be complete shut down when it returns.
    153	 */
    154	void (*shutdown)(void *send_info);
    155
    156	/*
    157	 * Get the detailed private info of the low level interface and store
    158	 * it into the structure of ipmi_smi_data. For example: the
    159	 * ACPI device handle will be returned for the pnp_acpi IPMI device.
    160	 */
    161	int (*get_smi_info)(void *send_info, struct ipmi_smi_info *data);
    162
    163	/*
    164	 * Called to enqueue an SMI message to be sent.  This
    165	 * operation is not allowed to fail.  If an error occurs, it
    166	 * should report back the error in a received message.  It may
    167	 * do this in the current call context, since no write locks
    168	 * are held when this is run.  Message are delivered one at
    169	 * a time by the message handler, a new message will not be
    170	 * delivered until the previous message is returned.
    171	 */
    172	void (*sender)(void                *send_info,
    173		       struct ipmi_smi_msg *msg);
    174
    175	/*
    176	 * Called by the upper layer to request that we try to get
    177	 * events from the BMC we are attached to.
    178	 */
    179	void (*request_events)(void *send_info);
    180
    181	/*
    182	 * Called by the upper layer when some user requires that the
    183	 * interface watch for received messages and watchdog
    184	 * pretimeouts (basically do a "Get Flags", or not.  Used by
    185	 * the SMI to know if it should watch for these.  This may be
    186	 * NULL if the SMI does not implement it.  watch_mask is from
    187	 * IPMI_WATCH_MASK_xxx above.  The interface should run slower
    188	 * timeouts for just watchdog checking or faster timeouts when
    189	 * waiting for the message queue.
    190	 */
    191	void (*set_need_watch)(void *send_info, unsigned int watch_mask);
    192
    193	/*
    194	 * Called when flushing all pending messages.
    195	 */
    196	void (*flush_messages)(void *send_info);
    197
    198	/*
    199	 * Called when the interface should go into "run to
    200	 * completion" mode.  If this call sets the value to true, the
    201	 * interface should make sure that all messages are flushed
    202	 * out and that none are pending, and any new requests are run
    203	 * to completion immediately.
    204	 */
    205	void (*set_run_to_completion)(void *send_info, bool run_to_completion);
    206
    207	/*
    208	 * Called to poll for work to do.  This is so upper layers can
    209	 * poll for operations during things like crash dumps.
    210	 */
    211	void (*poll)(void *send_info);
    212
    213	/*
    214	 * Enable/disable firmware maintenance mode.  Note that this
    215	 * is *not* the modes defined, this is simply an on/off
    216	 * setting.  The message handler does the mode handling.  Note
    217	 * that this is called from interrupt context, so it cannot
    218	 * block.
    219	 */
    220	void (*set_maintenance_mode)(void *send_info, bool enable);
    221};
    222
    223struct ipmi_device_id {
    224	unsigned char device_id;
    225	unsigned char device_revision;
    226	unsigned char firmware_revision_1;
    227	unsigned char firmware_revision_2;
    228	unsigned char ipmi_version;
    229	unsigned char additional_device_support;
    230	unsigned int  manufacturer_id;
    231	unsigned int  product_id;
    232	unsigned char aux_firmware_revision[4];
    233	unsigned int  aux_firmware_revision_set : 1;
    234};
    235
    236#define ipmi_version_major(v) ((v)->ipmi_version & 0xf)
    237#define ipmi_version_minor(v) ((v)->ipmi_version >> 4)
    238
    239/*
    240 * Take a pointer to an IPMI response and extract device id information from
    241 * it. @netfn is in the IPMI_NETFN_ format, so may need to be shifted from
    242 * a SI response.
    243 */
    244static inline int ipmi_demangle_device_id(uint8_t netfn, uint8_t cmd,
    245					  const unsigned char *data,
    246					  unsigned int data_len,
    247					  struct ipmi_device_id *id)
    248{
    249	if (data_len < 7)
    250		return -EINVAL;
    251	if (netfn != IPMI_NETFN_APP_RESPONSE || cmd != IPMI_GET_DEVICE_ID_CMD)
    252		/* Strange, didn't get the response we expected. */
    253		return -EINVAL;
    254	if (data[0] != 0)
    255		/* That's odd, it shouldn't be able to fail. */
    256		return -EINVAL;
    257
    258	data++;
    259	data_len--;
    260
    261	id->device_id = data[0];
    262	id->device_revision = data[1];
    263	id->firmware_revision_1 = data[2];
    264	id->firmware_revision_2 = data[3];
    265	id->ipmi_version = data[4];
    266	id->additional_device_support = data[5];
    267	if (data_len >= 11) {
    268		id->manufacturer_id = (data[6] | (data[7] << 8) |
    269				       (data[8] << 16));
    270		id->product_id = data[9] | (data[10] << 8);
    271	} else {
    272		id->manufacturer_id = 0;
    273		id->product_id = 0;
    274	}
    275	if (data_len >= 15) {
    276		memcpy(id->aux_firmware_revision, data+11, 4);
    277		id->aux_firmware_revision_set = 1;
    278	} else
    279		id->aux_firmware_revision_set = 0;
    280
    281	return 0;
    282}
    283
    284/*
    285 * Add a low-level interface to the IPMI driver.  Note that if the
    286 * interface doesn't know its slave address, it should pass in zero.
    287 * The low-level interface should not deliver any messages to the
    288 * upper layer until the start_processing() function in the handlers
    289 * is called, and the lower layer must get the interface from that
    290 * call.
    291 */
    292int ipmi_add_smi(struct module            *owner,
    293		 const struct ipmi_smi_handlers *handlers,
    294		 void                     *send_info,
    295		 struct device            *dev,
    296		 unsigned char            slave_addr);
    297
    298#define ipmi_register_smi(handlers, send_info, dev, slave_addr) \
    299	ipmi_add_smi(THIS_MODULE, handlers, send_info, dev, slave_addr)
    300
    301/*
    302 * Remove a low-level interface from the IPMI driver.  This will
    303 * return an error if the interface is still in use by a user.
    304 */
    305void ipmi_unregister_smi(struct ipmi_smi *intf);
    306
    307/*
    308 * The lower layer reports received messages through this interface.
    309 * The data_size should be zero if this is an asynchronous message.  If
    310 * the lower layer gets an error sending a message, it should format
    311 * an error response in the message response.
    312 */
    313void ipmi_smi_msg_received(struct ipmi_smi     *intf,
    314			   struct ipmi_smi_msg *msg);
    315
    316/* The lower layer received a watchdog pre-timeout on interface. */
    317void ipmi_smi_watchdog_pretimeout(struct ipmi_smi *intf);
    318
    319struct ipmi_smi_msg *ipmi_alloc_smi_msg(void);
    320static inline void ipmi_free_smi_msg(struct ipmi_smi_msg *msg)
    321{
    322	msg->done(msg);
    323}
    324
    325#endif /* __LINUX_IPMI_SMI_H */