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