xref: /linux/drivers/char/ipmi/kcs_bmc.h (revision 20d60f61c58e8c937f3653819816dd203e6e3cb4)
1*20d60f61SHaiyue Wang // SPDX-License-Identifier: GPL-2.0
2*20d60f61SHaiyue Wang // Copyright (c) 2015-2018, Intel Corporation.
3*20d60f61SHaiyue Wang 
4*20d60f61SHaiyue Wang #ifndef __KCS_BMC_H__
5*20d60f61SHaiyue Wang #define __KCS_BMC_H__
6*20d60f61SHaiyue Wang 
7*20d60f61SHaiyue Wang #include <linux/miscdevice.h>
8*20d60f61SHaiyue Wang 
9*20d60f61SHaiyue Wang /* Different phases of the KCS BMC module :
10*20d60f61SHaiyue Wang  *  KCS_PHASE_IDLE :
11*20d60f61SHaiyue Wang  *            BMC should not be expecting nor sending any data.
12*20d60f61SHaiyue Wang  *  KCS_PHASE_WRITE_START :
13*20d60f61SHaiyue Wang  *            BMC is receiving a WRITE_START command from system software.
14*20d60f61SHaiyue Wang  *  KCS_PHASE_WRITE_DATA :
15*20d60f61SHaiyue Wang  *            BMC is receiving a data byte from system software.
16*20d60f61SHaiyue Wang  *  KCS_PHASE_WRITE_END_CMD :
17*20d60f61SHaiyue Wang  *            BMC is waiting a last data byte from system software.
18*20d60f61SHaiyue Wang  *  KCS_PHASE_WRITE_DONE :
19*20d60f61SHaiyue Wang  *            BMC has received the whole request from system software.
20*20d60f61SHaiyue Wang  *  KCS_PHASE_WAIT_READ :
21*20d60f61SHaiyue Wang  *            BMC is waiting the response from the upper IPMI service.
22*20d60f61SHaiyue Wang  *  KCS_PHASE_READ :
23*20d60f61SHaiyue Wang  *            BMC is transferring the response to system software.
24*20d60f61SHaiyue Wang  *  KCS_PHASE_ABORT_ERROR1 :
25*20d60f61SHaiyue Wang  *            BMC is waiting error status request from system software.
26*20d60f61SHaiyue Wang  *  KCS_PHASE_ABORT_ERROR2 :
27*20d60f61SHaiyue Wang  *            BMC is waiting for idle status afer error from system software.
28*20d60f61SHaiyue Wang  *  KCS_PHASE_ERROR :
29*20d60f61SHaiyue Wang  *            BMC has detected a protocol violation at the interface level.
30*20d60f61SHaiyue Wang  */
31*20d60f61SHaiyue Wang enum kcs_phases {
32*20d60f61SHaiyue Wang 	KCS_PHASE_IDLE,
33*20d60f61SHaiyue Wang 
34*20d60f61SHaiyue Wang 	KCS_PHASE_WRITE_START,
35*20d60f61SHaiyue Wang 	KCS_PHASE_WRITE_DATA,
36*20d60f61SHaiyue Wang 	KCS_PHASE_WRITE_END_CMD,
37*20d60f61SHaiyue Wang 	KCS_PHASE_WRITE_DONE,
38*20d60f61SHaiyue Wang 
39*20d60f61SHaiyue Wang 	KCS_PHASE_WAIT_READ,
40*20d60f61SHaiyue Wang 	KCS_PHASE_READ,
41*20d60f61SHaiyue Wang 
42*20d60f61SHaiyue Wang 	KCS_PHASE_ABORT_ERROR1,
43*20d60f61SHaiyue Wang 	KCS_PHASE_ABORT_ERROR2,
44*20d60f61SHaiyue Wang 	KCS_PHASE_ERROR
45*20d60f61SHaiyue Wang };
46*20d60f61SHaiyue Wang 
47*20d60f61SHaiyue Wang /* IPMI 2.0 - Table 9-4, KCS Interface Status Codes */
48*20d60f61SHaiyue Wang enum kcs_errors {
49*20d60f61SHaiyue Wang 	KCS_NO_ERROR                = 0x00,
50*20d60f61SHaiyue Wang 	KCS_ABORTED_BY_COMMAND      = 0x01,
51*20d60f61SHaiyue Wang 	KCS_ILLEGAL_CONTROL_CODE    = 0x02,
52*20d60f61SHaiyue Wang 	KCS_LENGTH_ERROR            = 0x06,
53*20d60f61SHaiyue Wang 	KCS_UNSPECIFIED_ERROR       = 0xFF
54*20d60f61SHaiyue Wang };
55*20d60f61SHaiyue Wang 
56*20d60f61SHaiyue Wang /* IPMI 2.0 - 9.5, KCS Interface Registers
57*20d60f61SHaiyue Wang  * @idr : Input Data Register
58*20d60f61SHaiyue Wang  * @odr : Output Data Register
59*20d60f61SHaiyue Wang  * @str : Status Register
60*20d60f61SHaiyue Wang  */
61*20d60f61SHaiyue Wang struct kcs_ioreg {
62*20d60f61SHaiyue Wang 	u32 idr;
63*20d60f61SHaiyue Wang 	u32 odr;
64*20d60f61SHaiyue Wang 	u32 str;
65*20d60f61SHaiyue Wang };
66*20d60f61SHaiyue Wang 
67*20d60f61SHaiyue Wang struct kcs_bmc {
68*20d60f61SHaiyue Wang 	spinlock_t lock;
69*20d60f61SHaiyue Wang 
70*20d60f61SHaiyue Wang 	u32 channel;
71*20d60f61SHaiyue Wang 	int running;
72*20d60f61SHaiyue Wang 
73*20d60f61SHaiyue Wang 	/* Setup by BMC KCS controller driver */
74*20d60f61SHaiyue Wang 	struct kcs_ioreg ioreg;
75*20d60f61SHaiyue Wang 	u8 (*io_inputb)(struct kcs_bmc *kcs_bmc, u32 reg);
76*20d60f61SHaiyue Wang 	void (*io_outputb)(struct kcs_bmc *kcs_bmc, u32 reg, u8 b);
77*20d60f61SHaiyue Wang 
78*20d60f61SHaiyue Wang 	enum kcs_phases phase;
79*20d60f61SHaiyue Wang 	enum kcs_errors error;
80*20d60f61SHaiyue Wang 
81*20d60f61SHaiyue Wang 	wait_queue_head_t queue;
82*20d60f61SHaiyue Wang 	bool data_in_avail;
83*20d60f61SHaiyue Wang 	int  data_in_idx;
84*20d60f61SHaiyue Wang 	u8  *data_in;
85*20d60f61SHaiyue Wang 
86*20d60f61SHaiyue Wang 	int  data_out_idx;
87*20d60f61SHaiyue Wang 	int  data_out_len;
88*20d60f61SHaiyue Wang 	u8  *data_out;
89*20d60f61SHaiyue Wang 
90*20d60f61SHaiyue Wang 	struct mutex mutex;
91*20d60f61SHaiyue Wang 	u8 *kbuffer;
92*20d60f61SHaiyue Wang 
93*20d60f61SHaiyue Wang 	struct miscdevice miscdev;
94*20d60f61SHaiyue Wang 
95*20d60f61SHaiyue Wang 	unsigned long priv[];
96*20d60f61SHaiyue Wang };
97*20d60f61SHaiyue Wang 
98*20d60f61SHaiyue Wang static inline void *kcs_bmc_priv(struct kcs_bmc *kcs_bmc)
99*20d60f61SHaiyue Wang {
100*20d60f61SHaiyue Wang 	return kcs_bmc->priv;
101*20d60f61SHaiyue Wang }
102*20d60f61SHaiyue Wang 
103*20d60f61SHaiyue Wang int kcs_bmc_handle_event(struct kcs_bmc *kcs_bmc);
104*20d60f61SHaiyue Wang struct kcs_bmc *kcs_bmc_alloc(struct device *dev, int sizeof_priv,
105*20d60f61SHaiyue Wang 					u32 channel);
106*20d60f61SHaiyue Wang #endif
107