Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

ipmi: ssif_bmc: Add SSIF BMC driver

The SMBus system interface (SSIF) IPMI BMC driver can be used to perform
in-band IPMI communication with their host in management (BMC) side.

Thanks Dan for the copy_from_user() fix in the link below.

Link: https://lore.kernel.org/linux-arm-kernel/20220310114119.13736-4-quan@os.amperecomputing.com/
Signed-off-by: Quan Nguyen <quan@os.amperecomputing.com>
Message-Id: <20221004093106.1653317-2-quan@os.amperecomputing.com>
Signed-off-by: Corey Minyard <cminyard@mvista.com>

authored by

Quan Nguyen and committed by
Corey Minyard
dd2bc5cc 9abf2313

+902
+10
drivers/char/ipmi/Kconfig
··· 169 169 found on Aspeed SOCs (AST2400 and AST2500). The driver 170 170 implements the BMC side of the BT interface. 171 171 172 + config SSIF_IPMI_BMC 173 + tristate "SSIF IPMI BMC driver" 174 + depends on I2C && I2C_SLAVE 175 + help 176 + This enables the IPMI SMBus system interface (SSIF) at the 177 + management (BMC) side. 178 + 179 + The driver implements the BMC side of the SMBus system 180 + interface (SSIF). 181 + 172 182 config IPMB_DEVICE_INTERFACE 173 183 tristate 'IPMB Interface handler' 174 184 depends on I2C
+1
drivers/char/ipmi/Makefile
··· 30 30 obj-$(CONFIG_ASPEED_KCS_IPMI_BMC) += kcs_bmc_aspeed.o 31 31 obj-$(CONFIG_NPCM7XX_KCS_IPMI_BMC) += kcs_bmc_npcm7xx.o 32 32 obj-$(CONFIG_IPMB_DEVICE_INTERFACE) += ipmb_dev_int.o 33 + obj-$(CONFIG_SSIF_IPMI_BMC) += ssif_bmc.o
+873
drivers/char/ipmi/ssif_bmc.c
··· 1 + // SPDX-License-Identifier: GPL-2.0-only 2 + /* 3 + * The driver for BMC side of SSIF interface 4 + * 5 + * Copyright (c) 2022, Ampere Computing LLC 6 + * 7 + */ 8 + 9 + #include <linux/i2c.h> 10 + #include <linux/miscdevice.h> 11 + #include <linux/module.h> 12 + #include <linux/of.h> 13 + #include <linux/platform_device.h> 14 + #include <linux/poll.h> 15 + #include <linux/sched.h> 16 + #include <linux/mutex.h> 17 + #include <linux/spinlock.h> 18 + #include <linux/timer.h> 19 + #include <linux/jiffies.h> 20 + #include <linux/ipmi_ssif_bmc.h> 21 + 22 + #define DEVICE_NAME "ipmi-ssif-host" 23 + 24 + #define GET_8BIT_ADDR(addr_7bit) (((addr_7bit) << 1) & 0xff) 25 + 26 + /* A standard SMBus Transaction is limited to 32 data bytes */ 27 + #define MAX_PAYLOAD_PER_TRANSACTION 32 28 + /* Transaction includes the address, the command, the length and the PEC byte */ 29 + #define MAX_TRANSACTION (MAX_PAYLOAD_PER_TRANSACTION + 4) 30 + 31 + #define MAX_IPMI_DATA_PER_START_TRANSACTION 30 32 + #define MAX_IPMI_DATA_PER_MIDDLE_TRANSACTION 31 33 + 34 + #define SSIF_IPMI_SINGLEPART_WRITE 0x2 35 + #define SSIF_IPMI_SINGLEPART_READ 0x3 36 + #define SSIF_IPMI_MULTIPART_WRITE_START 0x6 37 + #define SSIF_IPMI_MULTIPART_WRITE_MIDDLE 0x7 38 + #define SSIF_IPMI_MULTIPART_WRITE_END 0x8 39 + #define SSIF_IPMI_MULTIPART_READ_START 0x3 40 + #define SSIF_IPMI_MULTIPART_READ_MIDDLE 0x9 41 + 42 + /* 43 + * IPMI 2.0 Spec, section 12.7 SSIF Timing, 44 + * Request-to-Response Time is T6max(250ms) - T1max(20ms) - 3ms = 227ms 45 + * Recover ssif_bmc from busy state if it takes up to 500ms 46 + */ 47 + #define RESPONSE_TIMEOUT 500 /* ms */ 48 + 49 + struct ssif_part_buffer { 50 + u8 address; 51 + u8 smbus_cmd; 52 + u8 length; 53 + u8 payload[MAX_PAYLOAD_PER_TRANSACTION]; 54 + u8 pec; 55 + u8 index; 56 + }; 57 + 58 + /* 59 + * SSIF internal states: 60 + * SSIF_READY 0x00 : Ready state 61 + * SSIF_START 0x01 : Start smbus transaction 62 + * SSIF_SMBUS_CMD 0x02 : Received SMBus command 63 + * SSIF_REQ_RECVING 0x03 : Receiving request 64 + * SSIF_RES_SENDING 0x04 : Sending response 65 + * SSIF_ABORTING 0x05 : Aborting state 66 + */ 67 + enum ssif_state { 68 + SSIF_READY, 69 + SSIF_START, 70 + SSIF_SMBUS_CMD, 71 + SSIF_REQ_RECVING, 72 + SSIF_RES_SENDING, 73 + SSIF_ABORTING, 74 + SSIF_STATE_MAX 75 + }; 76 + 77 + struct ssif_bmc_ctx { 78 + struct i2c_client *client; 79 + struct miscdevice miscdev; 80 + int msg_idx; 81 + bool pec_support; 82 + /* ssif bmc spinlock */ 83 + spinlock_t lock; 84 + wait_queue_head_t wait_queue; 85 + u8 running; 86 + enum ssif_state state; 87 + /* Timeout waiting for response */ 88 + struct timer_list response_timer; 89 + bool response_timer_inited; 90 + /* Flag to identify a Multi-part Read Transaction */ 91 + bool is_singlepart_read; 92 + u8 nbytes_processed; 93 + u8 remain_len; 94 + u8 recv_len; 95 + /* Block Number of a Multi-part Read Transaction */ 96 + u8 block_num; 97 + bool request_available; 98 + bool response_in_progress; 99 + bool busy; 100 + bool aborting; 101 + /* Buffer for SSIF Transaction part*/ 102 + struct ssif_part_buffer part_buf; 103 + struct ipmi_ssif_msg response; 104 + struct ipmi_ssif_msg request; 105 + }; 106 + 107 + static inline struct ssif_bmc_ctx *to_ssif_bmc(struct file *file) 108 + { 109 + return container_of(file->private_data, struct ssif_bmc_ctx, miscdev); 110 + } 111 + 112 + static const char *state_to_string(enum ssif_state state) 113 + { 114 + switch (state) { 115 + case SSIF_READY: 116 + return "SSIF_READY"; 117 + case SSIF_START: 118 + return "SSIF_START"; 119 + case SSIF_SMBUS_CMD: 120 + return "SSIF_SMBUS_CMD"; 121 + case SSIF_REQ_RECVING: 122 + return "SSIF_REQ_RECVING"; 123 + case SSIF_RES_SENDING: 124 + return "SSIF_RES_SENDING"; 125 + case SSIF_ABORTING: 126 + return "SSIF_ABORTING"; 127 + default: 128 + return "SSIF_STATE_UNKNOWN"; 129 + } 130 + } 131 + 132 + /* Handle SSIF message that will be sent to user */ 133 + static ssize_t ssif_bmc_read(struct file *file, char __user *buf, size_t count, loff_t *ppos) 134 + { 135 + struct ssif_bmc_ctx *ssif_bmc = to_ssif_bmc(file); 136 + struct ipmi_ssif_msg msg; 137 + unsigned long flags; 138 + ssize_t ret; 139 + 140 + spin_lock_irqsave(&ssif_bmc->lock, flags); 141 + while (!ssif_bmc->request_available) { 142 + spin_unlock_irqrestore(&ssif_bmc->lock, flags); 143 + if (file->f_flags & O_NONBLOCK) 144 + return -EAGAIN; 145 + ret = wait_event_interruptible(ssif_bmc->wait_queue, 146 + ssif_bmc->request_available); 147 + if (ret) 148 + return ret; 149 + spin_lock_irqsave(&ssif_bmc->lock, flags); 150 + } 151 + 152 + if (count < min_t(ssize_t, 153 + sizeof_field(struct ipmi_ssif_msg, len) + ssif_bmc->request.len, 154 + sizeof(struct ipmi_ssif_msg))) { 155 + spin_unlock_irqrestore(&ssif_bmc->lock, flags); 156 + ret = -EINVAL; 157 + } else { 158 + count = min_t(ssize_t, 159 + sizeof_field(struct ipmi_ssif_msg, len) + ssif_bmc->request.len, 160 + sizeof(struct ipmi_ssif_msg)); 161 + memcpy(&msg, &ssif_bmc->request, count); 162 + ssif_bmc->request_available = false; 163 + spin_unlock_irqrestore(&ssif_bmc->lock, flags); 164 + 165 + ret = copy_to_user(buf, &msg, count); 166 + } 167 + 168 + return (ret < 0) ? ret : count; 169 + } 170 + 171 + /* Handle SSIF message that is written by user */ 172 + static ssize_t ssif_bmc_write(struct file *file, const char __user *buf, size_t count, 173 + loff_t *ppos) 174 + { 175 + struct ssif_bmc_ctx *ssif_bmc = to_ssif_bmc(file); 176 + struct ipmi_ssif_msg msg; 177 + unsigned long flags; 178 + ssize_t ret; 179 + 180 + if (count > sizeof(struct ipmi_ssif_msg)) 181 + return -EINVAL; 182 + 183 + if (copy_from_user(&msg, buf, count)) 184 + return -EFAULT; 185 + 186 + if (!msg.len || count < sizeof_field(struct ipmi_ssif_msg, len) + msg.len) 187 + return -EINVAL; 188 + 189 + spin_lock_irqsave(&ssif_bmc->lock, flags); 190 + while (ssif_bmc->response_in_progress) { 191 + spin_unlock_irqrestore(&ssif_bmc->lock, flags); 192 + if (file->f_flags & O_NONBLOCK) 193 + return -EAGAIN; 194 + ret = wait_event_interruptible(ssif_bmc->wait_queue, 195 + !ssif_bmc->response_in_progress); 196 + if (ret) 197 + return ret; 198 + spin_lock_irqsave(&ssif_bmc->lock, flags); 199 + } 200 + 201 + /* 202 + * The write must complete before the response timeout fired, otherwise 203 + * the response is aborted and wait for next request 204 + * Return -EINVAL if the response is aborted 205 + */ 206 + ret = (ssif_bmc->response_timer_inited) ? 0 : -EINVAL; 207 + if (ret) 208 + goto exit; 209 + 210 + del_timer(&ssif_bmc->response_timer); 211 + ssif_bmc->response_timer_inited = false; 212 + 213 + memcpy(&ssif_bmc->response, &msg, count); 214 + ssif_bmc->is_singlepart_read = (msg.len <= MAX_PAYLOAD_PER_TRANSACTION); 215 + 216 + ssif_bmc->response_in_progress = true; 217 + 218 + /* ssif_bmc not busy */ 219 + ssif_bmc->busy = false; 220 + 221 + /* Clean old request buffer */ 222 + memset(&ssif_bmc->request, 0, sizeof(struct ipmi_ssif_msg)); 223 + exit: 224 + spin_unlock_irqrestore(&ssif_bmc->lock, flags); 225 + 226 + return (ret < 0) ? ret : count; 227 + } 228 + 229 + static int ssif_bmc_open(struct inode *inode, struct file *file) 230 + { 231 + struct ssif_bmc_ctx *ssif_bmc = to_ssif_bmc(file); 232 + int ret = 0; 233 + 234 + spin_lock_irq(&ssif_bmc->lock); 235 + if (!ssif_bmc->running) 236 + ssif_bmc->running = 1; 237 + else 238 + ret = -EBUSY; 239 + spin_unlock_irq(&ssif_bmc->lock); 240 + 241 + return ret; 242 + } 243 + 244 + static __poll_t ssif_bmc_poll(struct file *file, poll_table *wait) 245 + { 246 + struct ssif_bmc_ctx *ssif_bmc = to_ssif_bmc(file); 247 + __poll_t mask = 0; 248 + 249 + poll_wait(file, &ssif_bmc->wait_queue, wait); 250 + 251 + spin_lock_irq(&ssif_bmc->lock); 252 + /* The request is available, userspace application can get the request */ 253 + if (ssif_bmc->request_available) 254 + mask |= POLLIN; 255 + 256 + spin_unlock_irq(&ssif_bmc->lock); 257 + 258 + return mask; 259 + } 260 + 261 + static int ssif_bmc_release(struct inode *inode, struct file *file) 262 + { 263 + struct ssif_bmc_ctx *ssif_bmc = to_ssif_bmc(file); 264 + 265 + spin_lock_irq(&ssif_bmc->lock); 266 + ssif_bmc->running = 0; 267 + spin_unlock_irq(&ssif_bmc->lock); 268 + 269 + return 0; 270 + } 271 + 272 + /* 273 + * System calls to device interface for user apps 274 + */ 275 + static const struct file_operations ssif_bmc_fops = { 276 + .owner = THIS_MODULE, 277 + .open = ssif_bmc_open, 278 + .read = ssif_bmc_read, 279 + .write = ssif_bmc_write, 280 + .release = ssif_bmc_release, 281 + .poll = ssif_bmc_poll, 282 + }; 283 + 284 + /* Called with ssif_bmc->lock held. */ 285 + static void complete_response(struct ssif_bmc_ctx *ssif_bmc) 286 + { 287 + /* Invalidate response in buffer to denote it having been sent. */ 288 + ssif_bmc->response.len = 0; 289 + ssif_bmc->response_in_progress = false; 290 + ssif_bmc->nbytes_processed = 0; 291 + ssif_bmc->remain_len = 0; 292 + ssif_bmc->busy = false; 293 + memset(&ssif_bmc->part_buf, 0, sizeof(struct ssif_part_buffer)); 294 + wake_up_all(&ssif_bmc->wait_queue); 295 + } 296 + 297 + static void response_timeout(struct timer_list *t) 298 + { 299 + struct ssif_bmc_ctx *ssif_bmc = from_timer(ssif_bmc, t, response_timer); 300 + unsigned long flags; 301 + 302 + spin_lock_irqsave(&ssif_bmc->lock, flags); 303 + 304 + /* Do nothing if the response is in progress */ 305 + if (!ssif_bmc->response_in_progress) { 306 + /* Recover ssif_bmc from busy */ 307 + ssif_bmc->busy = false; 308 + ssif_bmc->response_timer_inited = false; 309 + /* Set aborting flag */ 310 + ssif_bmc->aborting = true; 311 + } 312 + 313 + spin_unlock_irqrestore(&ssif_bmc->lock, flags); 314 + } 315 + 316 + /* Called with ssif_bmc->lock held. */ 317 + static void handle_request(struct ssif_bmc_ctx *ssif_bmc) 318 + { 319 + /* set ssif_bmc to busy waiting for response */ 320 + ssif_bmc->busy = true; 321 + /* Request message is available to process */ 322 + ssif_bmc->request_available = true; 323 + /* Clean old response buffer */ 324 + memset(&ssif_bmc->response, 0, sizeof(struct ipmi_ssif_msg)); 325 + /* This is the new READ request.*/ 326 + wake_up_all(&ssif_bmc->wait_queue); 327 + 328 + /* Armed timer to recover slave from busy state in case of no response */ 329 + if (!ssif_bmc->response_timer_inited) { 330 + timer_setup(&ssif_bmc->response_timer, response_timeout, 0); 331 + ssif_bmc->response_timer_inited = true; 332 + } 333 + mod_timer(&ssif_bmc->response_timer, jiffies + msecs_to_jiffies(RESPONSE_TIMEOUT)); 334 + } 335 + 336 + static void calculate_response_part_pec(struct ssif_part_buffer *part) 337 + { 338 + u8 addr = part->address; 339 + 340 + /* PEC - Start Read Address */ 341 + part->pec = i2c_smbus_pec(0, &addr, 1); 342 + /* PEC - SSIF Command */ 343 + part->pec = i2c_smbus_pec(part->pec, &part->smbus_cmd, 1); 344 + /* PEC - Restart Write Address */ 345 + addr = addr | 0x01; 346 + part->pec = i2c_smbus_pec(part->pec, &addr, 1); 347 + part->pec = i2c_smbus_pec(part->pec, &part->length, 1); 348 + if (part->length) 349 + part->pec = i2c_smbus_pec(part->pec, part->payload, part->length); 350 + } 351 + 352 + static void set_singlepart_response_buffer(struct ssif_bmc_ctx *ssif_bmc) 353 + { 354 + struct ssif_part_buffer *part = &ssif_bmc->part_buf; 355 + 356 + part->address = GET_8BIT_ADDR(ssif_bmc->client->addr); 357 + part->length = (u8)ssif_bmc->response.len; 358 + 359 + /* Clear the rest to 0 */ 360 + memset(part->payload + part->length, 0, MAX_PAYLOAD_PER_TRANSACTION - part->length); 361 + memcpy(&part->payload[0], &ssif_bmc->response.payload[0], part->length); 362 + } 363 + 364 + static void set_multipart_response_buffer(struct ssif_bmc_ctx *ssif_bmc) 365 + { 366 + struct ssif_part_buffer *part = &ssif_bmc->part_buf; 367 + u8 part_len = 0; 368 + 369 + part->address = GET_8BIT_ADDR(ssif_bmc->client->addr); 370 + switch (part->smbus_cmd) { 371 + case SSIF_IPMI_MULTIPART_READ_START: 372 + /* 373 + * Read Start length is 32 bytes. 374 + * Read Start transfer first 30 bytes of IPMI response 375 + * and 2 special code 0x00, 0x01. 376 + */ 377 + ssif_bmc->nbytes_processed = 0; 378 + ssif_bmc->block_num = 0; 379 + part->length = MAX_PAYLOAD_PER_TRANSACTION; 380 + part_len = MAX_IPMI_DATA_PER_START_TRANSACTION; 381 + ssif_bmc->remain_len = ssif_bmc->response.len - part_len; 382 + 383 + part->payload[0] = 0x00; /* Start Flag */ 384 + part->payload[1] = 0x01; /* Start Flag */ 385 + 386 + memcpy(&part->payload[2], &ssif_bmc->response.payload[0], part_len); 387 + break; 388 + 389 + case SSIF_IPMI_MULTIPART_READ_MIDDLE: 390 + /* 391 + * IPMI READ Middle or READ End messages can carry up to 31 bytes 392 + * IPMI data plus block number byte. 393 + */ 394 + if (ssif_bmc->remain_len <= MAX_IPMI_DATA_PER_MIDDLE_TRANSACTION) { 395 + /* 396 + * This is READ End message 397 + * Return length is the remaining response data length 398 + * plus block number 399 + * Block number 0xFF is to indicate this is last message 400 + * 401 + */ 402 + /* Clean the buffer */ 403 + memset(&part->payload[0], 0, MAX_PAYLOAD_PER_TRANSACTION); 404 + part->length = ssif_bmc->remain_len + 1; 405 + part_len = ssif_bmc->remain_len; 406 + ssif_bmc->block_num = 0xFF; 407 + part->payload[0] = ssif_bmc->block_num; 408 + } else { 409 + /* 410 + * This is READ Middle message 411 + * Response length is the maximum SMBUS transfer length 412 + * Block number byte is incremented 413 + * Return length is maximum SMBUS transfer length 414 + */ 415 + part->length = MAX_PAYLOAD_PER_TRANSACTION; 416 + part_len = MAX_IPMI_DATA_PER_MIDDLE_TRANSACTION; 417 + part->payload[0] = ssif_bmc->block_num; 418 + ssif_bmc->block_num++; 419 + } 420 + 421 + ssif_bmc->remain_len -= part_len; 422 + memcpy(&part->payload[1], ssif_bmc->response.payload + ssif_bmc->nbytes_processed, 423 + part_len); 424 + break; 425 + 426 + default: 427 + /* Do not expect to go to this case */ 428 + dev_err(&ssif_bmc->client->dev, "%s: Unexpected SMBus command 0x%x\n", 429 + __func__, part->smbus_cmd); 430 + break; 431 + } 432 + 433 + ssif_bmc->nbytes_processed += part_len; 434 + } 435 + 436 + static bool supported_read_cmd(u8 cmd) 437 + { 438 + if (cmd == SSIF_IPMI_SINGLEPART_READ || 439 + cmd == SSIF_IPMI_MULTIPART_READ_START || 440 + cmd == SSIF_IPMI_MULTIPART_READ_MIDDLE) 441 + return true; 442 + 443 + return false; 444 + } 445 + 446 + static bool supported_write_cmd(u8 cmd) 447 + { 448 + if (cmd == SSIF_IPMI_SINGLEPART_WRITE || 449 + cmd == SSIF_IPMI_MULTIPART_WRITE_START || 450 + cmd == SSIF_IPMI_MULTIPART_WRITE_MIDDLE || 451 + cmd == SSIF_IPMI_MULTIPART_WRITE_END) 452 + return true; 453 + 454 + return false; 455 + } 456 + 457 + /* Process the IPMI response that will be read by master */ 458 + static void handle_read_processed(struct ssif_bmc_ctx *ssif_bmc, u8 *val) 459 + { 460 + struct ssif_part_buffer *part = &ssif_bmc->part_buf; 461 + 462 + /* msg_idx start from 0 */ 463 + if (part->index < part->length) 464 + *val = part->payload[part->index]; 465 + else if (part->index == part->length && ssif_bmc->pec_support) 466 + *val = part->pec; 467 + else 468 + *val = 0; 469 + 470 + part->index++; 471 + } 472 + 473 + static void handle_write_received(struct ssif_bmc_ctx *ssif_bmc, u8 *val) 474 + { 475 + /* 476 + * The msg_idx must be 1 when first enter SSIF_REQ_RECVING state 477 + * And it would never exceeded 36 bytes included the 32 bytes max payload + 478 + * the address + the command + the len and the PEC. 479 + */ 480 + if (ssif_bmc->msg_idx < 1 || ssif_bmc->msg_idx > MAX_TRANSACTION) 481 + return; 482 + 483 + if (ssif_bmc->msg_idx == 1) { 484 + ssif_bmc->part_buf.length = *val; 485 + ssif_bmc->part_buf.index = 0; 486 + } else { 487 + ssif_bmc->part_buf.payload[ssif_bmc->part_buf.index++] = *val; 488 + } 489 + 490 + ssif_bmc->msg_idx++; 491 + } 492 + 493 + static bool validate_request_part(struct ssif_bmc_ctx *ssif_bmc) 494 + { 495 + struct ssif_part_buffer *part = &ssif_bmc->part_buf; 496 + bool ret = true; 497 + u8 cpec; 498 + u8 addr; 499 + 500 + if (part->index == part->length) { 501 + /* PEC is not included */ 502 + ssif_bmc->pec_support = false; 503 + ret = true; 504 + goto exit; 505 + } 506 + 507 + if (part->index != part->length + 1) { 508 + ret = false; 509 + goto exit; 510 + } 511 + 512 + /* PEC is included */ 513 + ssif_bmc->pec_support = true; 514 + part->pec = part->payload[part->length]; 515 + addr = GET_8BIT_ADDR(ssif_bmc->client->addr); 516 + cpec = i2c_smbus_pec(0, &addr, 1); 517 + cpec = i2c_smbus_pec(cpec, &part->smbus_cmd, 1); 518 + cpec = i2c_smbus_pec(cpec, &part->length, 1); 519 + /* 520 + * As SMBus specification does not allow the length 521 + * (byte count) in the Write-Block protocol to be zero. 522 + * Therefore, it is illegal to have the last Middle 523 + * transaction in the sequence carry 32-byte and have 524 + * a length of ‘0’ in the End transaction. 525 + * But some users may try to use this way and we should 526 + * prevent ssif_bmc driver broken in this case. 527 + */ 528 + if (part->length) 529 + cpec = i2c_smbus_pec(cpec, part->payload, part->length); 530 + 531 + if (cpec != part->pec) 532 + ret = false; 533 + 534 + exit: 535 + return ret; 536 + } 537 + 538 + static void process_request_part(struct ssif_bmc_ctx *ssif_bmc) 539 + { 540 + struct ssif_part_buffer *part = &ssif_bmc->part_buf; 541 + unsigned int len; 542 + 543 + switch (part->smbus_cmd) { 544 + case SSIF_IPMI_SINGLEPART_WRITE: 545 + /* save the whole part to request*/ 546 + ssif_bmc->request.len = part->length; 547 + memcpy(ssif_bmc->request.payload, part->payload, part->length); 548 + 549 + break; 550 + case SSIF_IPMI_MULTIPART_WRITE_START: 551 + ssif_bmc->request.len = 0; 552 + 553 + fallthrough; 554 + case SSIF_IPMI_MULTIPART_WRITE_MIDDLE: 555 + case SSIF_IPMI_MULTIPART_WRITE_END: 556 + len = ssif_bmc->request.len + part->length; 557 + /* Do the bound check here, not allow the request len exceed 254 bytes */ 558 + if (len > IPMI_SSIF_PAYLOAD_MAX) { 559 + dev_warn(&ssif_bmc->client->dev, 560 + "Warn: Request exceeded 254 bytes, aborting"); 561 + /* Request too long, aborting */ 562 + ssif_bmc->aborting = true; 563 + } else { 564 + memcpy(ssif_bmc->request.payload + ssif_bmc->request.len, 565 + part->payload, part->length); 566 + ssif_bmc->request.len += part->length; 567 + } 568 + break; 569 + default: 570 + /* Do not expect to go to this case */ 571 + dev_err(&ssif_bmc->client->dev, "%s: Unexpected SMBus command 0x%x\n", 572 + __func__, part->smbus_cmd); 573 + break; 574 + } 575 + } 576 + 577 + static void process_smbus_cmd(struct ssif_bmc_ctx *ssif_bmc, u8 *val) 578 + { 579 + /* SMBUS command can vary (single or multi-part) */ 580 + ssif_bmc->part_buf.smbus_cmd = *val; 581 + ssif_bmc->msg_idx = 1; 582 + memset(&ssif_bmc->part_buf.payload[0], 0, MAX_PAYLOAD_PER_TRANSACTION); 583 + 584 + if (*val == SSIF_IPMI_SINGLEPART_WRITE || *val == SSIF_IPMI_MULTIPART_WRITE_START) { 585 + /* 586 + * The response maybe not come in-time, causing host SSIF driver 587 + * to timeout and resend a new request. In such case check for 588 + * pending response and clear it 589 + */ 590 + if (ssif_bmc->response_in_progress) 591 + complete_response(ssif_bmc); 592 + 593 + /* This is new request, flip aborting flag if set */ 594 + if (ssif_bmc->aborting) 595 + ssif_bmc->aborting = false; 596 + } 597 + } 598 + 599 + static void on_read_requested_event(struct ssif_bmc_ctx *ssif_bmc, u8 *val) 600 + { 601 + if (ssif_bmc->state == SSIF_READY || 602 + ssif_bmc->state == SSIF_START || 603 + ssif_bmc->state == SSIF_REQ_RECVING || 604 + ssif_bmc->state == SSIF_RES_SENDING) { 605 + dev_warn(&ssif_bmc->client->dev, 606 + "Warn: %s unexpected READ REQUESTED in state=%s\n", 607 + __func__, state_to_string(ssif_bmc->state)); 608 + ssif_bmc->state = SSIF_ABORTING; 609 + *val = 0; 610 + return; 611 + 612 + } else if (ssif_bmc->state == SSIF_SMBUS_CMD) { 613 + if (!supported_read_cmd(ssif_bmc->part_buf.smbus_cmd)) { 614 + dev_warn(&ssif_bmc->client->dev, "Warn: Unknown SMBus read command=0x%x", 615 + ssif_bmc->part_buf.smbus_cmd); 616 + ssif_bmc->aborting = true; 617 + } 618 + 619 + if (ssif_bmc->aborting) 620 + ssif_bmc->state = SSIF_ABORTING; 621 + else 622 + ssif_bmc->state = SSIF_RES_SENDING; 623 + } 624 + 625 + ssif_bmc->msg_idx = 0; 626 + 627 + /* Send 0 if there is nothing to send */ 628 + if (!ssif_bmc->response_in_progress || ssif_bmc->state == SSIF_ABORTING) { 629 + *val = 0; 630 + return; 631 + } 632 + 633 + if (ssif_bmc->is_singlepart_read) 634 + set_singlepart_response_buffer(ssif_bmc); 635 + else 636 + set_multipart_response_buffer(ssif_bmc); 637 + 638 + calculate_response_part_pec(&ssif_bmc->part_buf); 639 + ssif_bmc->part_buf.index = 0; 640 + *val = ssif_bmc->part_buf.length; 641 + } 642 + 643 + static void on_read_processed_event(struct ssif_bmc_ctx *ssif_bmc, u8 *val) 644 + { 645 + if (ssif_bmc->state == SSIF_READY || 646 + ssif_bmc->state == SSIF_START || 647 + ssif_bmc->state == SSIF_REQ_RECVING || 648 + ssif_bmc->state == SSIF_SMBUS_CMD) { 649 + dev_warn(&ssif_bmc->client->dev, 650 + "Warn: %s unexpected READ PROCESSED in state=%s\n", 651 + __func__, state_to_string(ssif_bmc->state)); 652 + ssif_bmc->state = SSIF_ABORTING; 653 + *val = 0; 654 + return; 655 + } 656 + 657 + /* Send 0 if there is nothing to send */ 658 + if (!ssif_bmc->response_in_progress || ssif_bmc->state == SSIF_ABORTING) { 659 + *val = 0; 660 + return; 661 + } 662 + 663 + handle_read_processed(ssif_bmc, val); 664 + } 665 + 666 + static void on_write_requested_event(struct ssif_bmc_ctx *ssif_bmc, u8 *val) 667 + { 668 + if (ssif_bmc->state == SSIF_READY || ssif_bmc->state == SSIF_SMBUS_CMD) { 669 + ssif_bmc->state = SSIF_START; 670 + 671 + } else if (ssif_bmc->state == SSIF_START || 672 + ssif_bmc->state == SSIF_REQ_RECVING || 673 + ssif_bmc->state == SSIF_RES_SENDING) { 674 + dev_warn(&ssif_bmc->client->dev, 675 + "Warn: %s unexpected WRITE REQUEST in state=%s\n", 676 + __func__, state_to_string(ssif_bmc->state)); 677 + ssif_bmc->state = SSIF_ABORTING; 678 + return; 679 + } 680 + 681 + ssif_bmc->msg_idx = 0; 682 + ssif_bmc->part_buf.address = *val; 683 + } 684 + 685 + static void on_write_received_event(struct ssif_bmc_ctx *ssif_bmc, u8 *val) 686 + { 687 + if (ssif_bmc->state == SSIF_READY || 688 + ssif_bmc->state == SSIF_RES_SENDING) { 689 + dev_warn(&ssif_bmc->client->dev, 690 + "Warn: %s unexpected WRITE RECEIVED in state=%s\n", 691 + __func__, state_to_string(ssif_bmc->state)); 692 + ssif_bmc->state = SSIF_ABORTING; 693 + 694 + } else if (ssif_bmc->state == SSIF_START) { 695 + ssif_bmc->state = SSIF_SMBUS_CMD; 696 + 697 + } else if (ssif_bmc->state == SSIF_SMBUS_CMD) { 698 + if (!supported_write_cmd(ssif_bmc->part_buf.smbus_cmd)) { 699 + dev_warn(&ssif_bmc->client->dev, "Warn: Unknown SMBus write command=0x%x", 700 + ssif_bmc->part_buf.smbus_cmd); 701 + ssif_bmc->aborting = true; 702 + } 703 + 704 + if (ssif_bmc->aborting) 705 + ssif_bmc->state = SSIF_ABORTING; 706 + else 707 + ssif_bmc->state = SSIF_REQ_RECVING; 708 + } 709 + 710 + /* This is response sending state */ 711 + if (ssif_bmc->state == SSIF_REQ_RECVING) 712 + handle_write_received(ssif_bmc, val); 713 + else if (ssif_bmc->state == SSIF_SMBUS_CMD) 714 + process_smbus_cmd(ssif_bmc, val); 715 + } 716 + 717 + static void on_stop_event(struct ssif_bmc_ctx *ssif_bmc, u8 *val) 718 + { 719 + if (ssif_bmc->state == SSIF_READY || 720 + ssif_bmc->state == SSIF_START || 721 + ssif_bmc->state == SSIF_SMBUS_CMD || 722 + ssif_bmc->state == SSIF_ABORTING) { 723 + dev_warn(&ssif_bmc->client->dev, 724 + "Warn: %s unexpected SLAVE STOP in state=%s\n", 725 + __func__, state_to_string(ssif_bmc->state)); 726 + ssif_bmc->state = SSIF_READY; 727 + 728 + } else if (ssif_bmc->state == SSIF_REQ_RECVING) { 729 + if (validate_request_part(ssif_bmc)) { 730 + process_request_part(ssif_bmc); 731 + if (ssif_bmc->part_buf.smbus_cmd == SSIF_IPMI_SINGLEPART_WRITE || 732 + ssif_bmc->part_buf.smbus_cmd == SSIF_IPMI_MULTIPART_WRITE_END) 733 + handle_request(ssif_bmc); 734 + ssif_bmc->state = SSIF_READY; 735 + } else { 736 + /* 737 + * A BMC that receives an invalid request drop the data for the write 738 + * transaction and any further transactions (read or write) until 739 + * the next valid read or write Start transaction is received 740 + */ 741 + dev_err(&ssif_bmc->client->dev, "Error: invalid pec\n"); 742 + ssif_bmc->aborting = true; 743 + } 744 + } else if (ssif_bmc->state == SSIF_RES_SENDING) { 745 + if (ssif_bmc->is_singlepart_read || ssif_bmc->block_num == 0xFF) 746 + /* Invalidate response buffer to denote it is sent */ 747 + complete_response(ssif_bmc); 748 + ssif_bmc->state = SSIF_READY; 749 + } 750 + 751 + /* Reset message index */ 752 + ssif_bmc->msg_idx = 0; 753 + } 754 + 755 + /* 756 + * Callback function to handle I2C slave events 757 + */ 758 + static int ssif_bmc_cb(struct i2c_client *client, enum i2c_slave_event event, u8 *val) 759 + { 760 + unsigned long flags; 761 + struct ssif_bmc_ctx *ssif_bmc = i2c_get_clientdata(client); 762 + int ret = 0; 763 + 764 + spin_lock_irqsave(&ssif_bmc->lock, flags); 765 + 766 + switch (event) { 767 + case I2C_SLAVE_READ_REQUESTED: 768 + on_read_requested_event(ssif_bmc, val); 769 + break; 770 + 771 + case I2C_SLAVE_WRITE_REQUESTED: 772 + on_write_requested_event(ssif_bmc, val); 773 + break; 774 + 775 + case I2C_SLAVE_READ_PROCESSED: 776 + on_read_processed_event(ssif_bmc, val); 777 + break; 778 + 779 + case I2C_SLAVE_WRITE_RECEIVED: 780 + on_write_received_event(ssif_bmc, val); 781 + break; 782 + 783 + case I2C_SLAVE_STOP: 784 + on_stop_event(ssif_bmc, val); 785 + break; 786 + 787 + default: 788 + dev_warn(&ssif_bmc->client->dev, "Warn: Unknown i2c slave event\n"); 789 + break; 790 + } 791 + 792 + if (!ssif_bmc->aborting && ssif_bmc->busy) 793 + ret = -EBUSY; 794 + 795 + spin_unlock_irqrestore(&ssif_bmc->lock, flags); 796 + 797 + return ret; 798 + } 799 + 800 + static int ssif_bmc_probe(struct i2c_client *client, const struct i2c_device_id *id) 801 + { 802 + struct ssif_bmc_ctx *ssif_bmc; 803 + int ret; 804 + 805 + ssif_bmc = devm_kzalloc(&client->dev, sizeof(*ssif_bmc), GFP_KERNEL); 806 + if (!ssif_bmc) 807 + return -ENOMEM; 808 + 809 + spin_lock_init(&ssif_bmc->lock); 810 + 811 + init_waitqueue_head(&ssif_bmc->wait_queue); 812 + ssif_bmc->request_available = false; 813 + ssif_bmc->response_in_progress = false; 814 + ssif_bmc->busy = false; 815 + ssif_bmc->response_timer_inited = false; 816 + 817 + /* Register misc device interface */ 818 + ssif_bmc->miscdev.minor = MISC_DYNAMIC_MINOR; 819 + ssif_bmc->miscdev.name = DEVICE_NAME; 820 + ssif_bmc->miscdev.fops = &ssif_bmc_fops; 821 + ssif_bmc->miscdev.parent = &client->dev; 822 + ret = misc_register(&ssif_bmc->miscdev); 823 + if (ret) 824 + return ret; 825 + 826 + ssif_bmc->client = client; 827 + ssif_bmc->client->flags |= I2C_CLIENT_SLAVE; 828 + 829 + /* Register I2C slave */ 830 + i2c_set_clientdata(client, ssif_bmc); 831 + ret = i2c_slave_register(client, ssif_bmc_cb); 832 + if (ret) 833 + misc_deregister(&ssif_bmc->miscdev); 834 + 835 + return ret; 836 + } 837 + 838 + static void ssif_bmc_remove(struct i2c_client *client) 839 + { 840 + struct ssif_bmc_ctx *ssif_bmc = i2c_get_clientdata(client); 841 + 842 + i2c_slave_unregister(client); 843 + misc_deregister(&ssif_bmc->miscdev); 844 + } 845 + 846 + static const struct of_device_id ssif_bmc_match[] = { 847 + { .compatible = "ssif-bmc" }, 848 + { }, 849 + }; 850 + MODULE_DEVICE_TABLE(of, ssif_bmc_match); 851 + 852 + static const struct i2c_device_id ssif_bmc_id[] = { 853 + { DEVICE_NAME, 0 }, 854 + { }, 855 + }; 856 + MODULE_DEVICE_TABLE(i2c, ssif_bmc_id); 857 + 858 + static struct i2c_driver ssif_bmc_driver = { 859 + .driver = { 860 + .name = DEVICE_NAME, 861 + .of_match_table = ssif_bmc_match, 862 + }, 863 + .probe = ssif_bmc_probe, 864 + .remove = ssif_bmc_remove, 865 + .id_table = ssif_bmc_id, 866 + }; 867 + 868 + module_i2c_driver(ssif_bmc_driver); 869 + 870 + MODULE_AUTHOR("Quan Nguyen <quan@os.amperecomputing.com>"); 871 + MODULE_AUTHOR("Chuong Tran <chuong@os.amperecomputing.com>"); 872 + MODULE_DESCRIPTION("Linux device driver of the BMC IPMI SSIF interface."); 873 + MODULE_LICENSE("GPL");
+18
include/uapi/linux/ipmi_ssif_bmc.h
··· 1 + /* SPDX-License-Identifier: GPL-2.0-only WITH Linux-syscall-note*/ 2 + /* 3 + * Copyright (c) 2022, Ampere Computing LLC. 4 + */ 5 + 6 + #ifndef _UAPI_LINUX_IPMI_SSIF_BMC_H 7 + #define _UAPI_LINUX_IPMI_SSIF_BMC_H 8 + 9 + #include <linux/types.h> 10 + 11 + /* Max length of ipmi ssif message included netfn and cmd field */ 12 + #define IPMI_SSIF_PAYLOAD_MAX 254 13 + struct ipmi_ssif_msg { 14 + unsigned int len; 15 + __u8 payload[IPMI_SSIF_PAYLOAD_MAX]; 16 + }; 17 + 18 + #endif /* _UAPI_LINUX_IPMI_SSIF_BMC_H */