1 // SPDX-License-Identifier: GPL-2.0
4 * IPMB driver to receive a request and send a response
6 * Copyright (C) 2019 Mellanox Techologies, Ltd.
8 * This was inspired by Brendan Higgins' ipmi-bmc-bt-i2c driver.
11 #include <linux/acpi.h>
12 #include <linux/errno.h>
13 #include <linux/i2c.h>
14 #include <linux/miscdevice.h>
15 #include <linux/module.h>
16 #include <linux/mutex.h>
17 #include <linux/poll.h>
18 #include <linux/slab.h>
19 #include <linux/spinlock.h>
20 #include <linux/wait.h>
22 #define MAX_MSG_LEN 128
23 #define IPMB_REQUEST_LEN_MIN 7
24 #define NETFN_RSP_BIT_MASK 0x4
25 #define REQUEST_QUEUE_MAX_LEN 256
27 #define IPMB_MSG_LEN_IDX 0
28 #define RQ_SA_8BIT_IDX 1
29 #define NETFN_LUN_IDX 2
31 #define GET_7BIT_ADDR(addr_8bit) (addr_8bit >> 1)
32 #define GET_8BIT_ADDR(addr_7bit) ((addr_7bit << 1) & 0xff)
34 #define IPMB_MSG_PAYLOAD_LEN_MAX (MAX_MSG_LEN - IPMB_REQUEST_LEN_MIN - 1)
36 #define SMBUS_MSG_HEADER_LENGTH 2
37 #define SMBUS_MSG_IDX_OFFSET (SMBUS_MSG_HEADER_LENGTH + 1)
47 u8 payload
[IPMB_MSG_PAYLOAD_LEN_MAX
];
48 /* checksum2 is included in payload */
51 struct ipmb_request_elem
{
52 struct list_head list
;
53 struct ipmb_msg request
;
57 struct i2c_client
*client
;
58 struct miscdevice miscdev
;
59 struct ipmb_msg request
;
60 struct list_head request_queue
;
61 atomic_t request_queue_len
;
64 wait_queue_head_t wait_queue
;
65 struct mutex file_mutex
;
68 static inline struct ipmb_dev
*to_ipmb_dev(struct file
*file
)
70 return container_of(file
->private_data
, struct ipmb_dev
, miscdev
);
73 static ssize_t
ipmb_read(struct file
*file
, char __user
*buf
, size_t count
,
76 struct ipmb_dev
*ipmb_dev
= to_ipmb_dev(file
);
77 struct ipmb_request_elem
*queue_elem
;
81 memset(&msg
, 0, sizeof(msg
));
83 spin_lock_irq(&ipmb_dev
->lock
);
85 while (list_empty(&ipmb_dev
->request_queue
)) {
86 spin_unlock_irq(&ipmb_dev
->lock
);
88 if (file
->f_flags
& O_NONBLOCK
)
91 ret
= wait_event_interruptible(ipmb_dev
->wait_queue
,
92 !list_empty(&ipmb_dev
->request_queue
));
96 spin_lock_irq(&ipmb_dev
->lock
);
99 queue_elem
= list_first_entry(&ipmb_dev
->request_queue
,
100 struct ipmb_request_elem
, list
);
101 memcpy(&msg
, &queue_elem
->request
, sizeof(msg
));
102 list_del(&queue_elem
->list
);
104 atomic_dec(&ipmb_dev
->request_queue_len
);
106 spin_unlock_irq(&ipmb_dev
->lock
);
108 count
= min_t(size_t, count
, msg
.len
+ 1);
109 if (copy_to_user(buf
, &msg
, count
))
112 return ret
< 0 ? ret
: count
;
115 static ssize_t
ipmb_write(struct file
*file
, const char __user
*buf
,
116 size_t count
, loff_t
*ppos
)
118 struct ipmb_dev
*ipmb_dev
= to_ipmb_dev(file
);
119 u8 rq_sa
, netf_rq_lun
, msg_len
;
120 union i2c_smbus_data data
;
124 if (count
> sizeof(msg
))
127 if (copy_from_user(&msg
, buf
, count
))
133 rq_sa
= GET_7BIT_ADDR(msg
[RQ_SA_8BIT_IDX
]);
134 netf_rq_lun
= msg
[NETFN_LUN_IDX
];
136 if (!(netf_rq_lun
& NETFN_RSP_BIT_MASK
))
140 * subtract rq_sa and netf_rq_lun from the length of the msg passed to
143 msg_len
= msg
[IPMB_MSG_LEN_IDX
] - SMBUS_MSG_HEADER_LENGTH
;
144 if (msg_len
> I2C_SMBUS_BLOCK_MAX
)
145 msg_len
= I2C_SMBUS_BLOCK_MAX
;
147 data
.block
[0] = msg_len
;
148 memcpy(&data
.block
[1], msg
+ SMBUS_MSG_IDX_OFFSET
, msg_len
);
149 ret
= i2c_smbus_xfer(ipmb_dev
->client
->adapter
, rq_sa
,
150 ipmb_dev
->client
->flags
,
151 I2C_SMBUS_WRITE
, netf_rq_lun
,
152 I2C_SMBUS_BLOCK_DATA
, &data
);
154 return ret
? : count
;
157 static unsigned int ipmb_poll(struct file
*file
, poll_table
*wait
)
159 struct ipmb_dev
*ipmb_dev
= to_ipmb_dev(file
);
160 unsigned int mask
= POLLOUT
;
162 mutex_lock(&ipmb_dev
->file_mutex
);
163 poll_wait(file
, &ipmb_dev
->wait_queue
, wait
);
165 if (atomic_read(&ipmb_dev
->request_queue_len
))
167 mutex_unlock(&ipmb_dev
->file_mutex
);
172 static const struct file_operations ipmb_fops
= {
173 .owner
= THIS_MODULE
,
179 /* Called with ipmb_dev->lock held. */
180 static void ipmb_handle_request(struct ipmb_dev
*ipmb_dev
)
182 struct ipmb_request_elem
*queue_elem
;
184 if (atomic_read(&ipmb_dev
->request_queue_len
) >=
185 REQUEST_QUEUE_MAX_LEN
)
188 queue_elem
= kmalloc(sizeof(*queue_elem
), GFP_ATOMIC
);
192 memcpy(&queue_elem
->request
, &ipmb_dev
->request
,
193 sizeof(struct ipmb_msg
));
194 list_add(&queue_elem
->list
, &ipmb_dev
->request_queue
);
195 atomic_inc(&ipmb_dev
->request_queue_len
);
196 wake_up_all(&ipmb_dev
->wait_queue
);
199 static u8
ipmb_verify_checksum1(struct ipmb_dev
*ipmb_dev
, u8 rs_sa
)
201 /* The 8 lsb of the sum is 0 when the checksum is valid */
202 return (rs_sa
+ ipmb_dev
->request
.netfn_rs_lun
+
203 ipmb_dev
->request
.checksum1
);
206 static bool is_ipmb_request(struct ipmb_dev
*ipmb_dev
, u8 rs_sa
)
208 if (ipmb_dev
->msg_idx
>= IPMB_REQUEST_LEN_MIN
) {
209 if (ipmb_verify_checksum1(ipmb_dev
, rs_sa
))
213 * Check whether this is an IPMB request or
215 * The 6 MSB of netfn_rs_lun are dedicated to the netfn
216 * while the remaining bits are dedicated to the lun.
217 * If the LSB of the netfn is cleared, it is associated
218 * with an IPMB request.
219 * If the LSB of the netfn is set, it is associated with
222 if (!(ipmb_dev
->request
.netfn_rs_lun
& NETFN_RSP_BIT_MASK
))
229 * The IPMB protocol only supports I2C Writes so there is no need
230 * to support I2C_SLAVE_READ* events.
231 * This i2c callback function only monitors IPMB request messages
232 * and adds them in a queue, so that they can be handled by
233 * receive_ipmb_request.
235 static int ipmb_slave_cb(struct i2c_client
*client
,
236 enum i2c_slave_event event
, u8
*val
)
238 struct ipmb_dev
*ipmb_dev
= i2c_get_clientdata(client
);
239 u8
*buf
= (u8
*)&ipmb_dev
->request
;
242 spin_lock_irqsave(&ipmb_dev
->lock
, flags
);
244 case I2C_SLAVE_WRITE_REQUESTED
:
245 memset(&ipmb_dev
->request
, 0, sizeof(ipmb_dev
->request
));
246 ipmb_dev
->msg_idx
= 0;
249 * At index 0, ipmb_msg stores the length of msg,
251 * The len will be populated once the whole
254 * The I2C bus driver's responsibility is to pass the
255 * data bytes to the backend driver; it does not
256 * forward the i2c slave address.
257 * Since the first byte in the IPMB message is the
258 * address of the responder, it is the responsibility
259 * of the IPMB driver to format the message properly.
260 * So this driver prepends the address of the responder
261 * to the received i2c data before the request message
262 * is handled in userland.
264 buf
[++ipmb_dev
->msg_idx
] = GET_8BIT_ADDR(client
->addr
);
267 case I2C_SLAVE_WRITE_RECEIVED
:
268 if (ipmb_dev
->msg_idx
>= sizeof(struct ipmb_msg
))
271 buf
[++ipmb_dev
->msg_idx
] = *val
;
275 ipmb_dev
->request
.len
= ipmb_dev
->msg_idx
;
277 if (is_ipmb_request(ipmb_dev
, GET_8BIT_ADDR(client
->addr
)))
278 ipmb_handle_request(ipmb_dev
);
284 spin_unlock_irqrestore(&ipmb_dev
->lock
, flags
);
289 static int ipmb_probe(struct i2c_client
*client
,
290 const struct i2c_device_id
*id
)
292 struct ipmb_dev
*ipmb_dev
;
295 ipmb_dev
= devm_kzalloc(&client
->dev
, sizeof(*ipmb_dev
),
300 spin_lock_init(&ipmb_dev
->lock
);
301 init_waitqueue_head(&ipmb_dev
->wait_queue
);
302 atomic_set(&ipmb_dev
->request_queue_len
, 0);
303 INIT_LIST_HEAD(&ipmb_dev
->request_queue
);
305 mutex_init(&ipmb_dev
->file_mutex
);
307 ipmb_dev
->miscdev
.minor
= MISC_DYNAMIC_MINOR
;
309 ipmb_dev
->miscdev
.name
= devm_kasprintf(&client
->dev
, GFP_KERNEL
,
311 client
->adapter
->nr
);
312 ipmb_dev
->miscdev
.fops
= &ipmb_fops
;
313 ipmb_dev
->miscdev
.parent
= &client
->dev
;
314 ret
= misc_register(&ipmb_dev
->miscdev
);
318 ipmb_dev
->client
= client
;
319 i2c_set_clientdata(client
, ipmb_dev
);
320 ret
= i2c_slave_register(client
, ipmb_slave_cb
);
322 misc_deregister(&ipmb_dev
->miscdev
);
329 static int ipmb_remove(struct i2c_client
*client
)
331 struct ipmb_dev
*ipmb_dev
= i2c_get_clientdata(client
);
333 i2c_slave_unregister(client
);
334 misc_deregister(&ipmb_dev
->miscdev
);
339 static const struct i2c_device_id ipmb_id
[] = {
343 MODULE_DEVICE_TABLE(i2c
, ipmb_id
);
345 static const struct acpi_device_id acpi_ipmb_id
[] = {
349 MODULE_DEVICE_TABLE(acpi
, acpi_ipmb_id
);
351 static struct i2c_driver ipmb_driver
= {
354 .acpi_match_table
= ACPI_PTR(acpi_ipmb_id
),
357 .remove
= ipmb_remove
,
360 module_i2c_driver(ipmb_driver
);
362 MODULE_AUTHOR("Mellanox Technologies");
363 MODULE_DESCRIPTION("IPMB driver");
364 MODULE_LICENSE("GPL v2");