linux/drivers/char/ipmi/kcs_bmc_cdev_ipmi.c
<<
>>
Prefs
   1// SPDX-License-Identifier: GPL-2.0
   2/*
   3 * Copyright (c) 2015-2018, Intel Corporation.
   4 */
   5
   6#define pr_fmt(fmt) "kcs-bmc: " fmt
   7
   8#include <linux/errno.h>
   9#include <linux/io.h>
  10#include <linux/ipmi_bmc.h>
  11#include <linux/list.h>
  12#include <linux/miscdevice.h>
  13#include <linux/module.h>
  14#include <linux/mutex.h>
  15#include <linux/platform_device.h>
  16#include <linux/poll.h>
  17#include <linux/sched.h>
  18#include <linux/slab.h>
  19
  20#include "kcs_bmc_client.h"
  21
  22/* Different phases of the KCS BMC module.
  23 *  KCS_PHASE_IDLE:
  24 *            BMC should not be expecting nor sending any data.
  25 *  KCS_PHASE_WRITE_START:
  26 *            BMC is receiving a WRITE_START command from system software.
  27 *  KCS_PHASE_WRITE_DATA:
  28 *            BMC is receiving a data byte from system software.
  29 *  KCS_PHASE_WRITE_END_CMD:
  30 *            BMC is waiting a last data byte from system software.
  31 *  KCS_PHASE_WRITE_DONE:
  32 *            BMC has received the whole request from system software.
  33 *  KCS_PHASE_WAIT_READ:
  34 *            BMC is waiting the response from the upper IPMI service.
  35 *  KCS_PHASE_READ:
  36 *            BMC is transferring the response to system software.
  37 *  KCS_PHASE_ABORT_ERROR1:
  38 *            BMC is waiting error status request from system software.
  39 *  KCS_PHASE_ABORT_ERROR2:
  40 *            BMC is waiting for idle status afer error from system software.
  41 *  KCS_PHASE_ERROR:
  42 *            BMC has detected a protocol violation at the interface level.
  43 */
  44enum kcs_ipmi_phases {
  45        KCS_PHASE_IDLE,
  46
  47        KCS_PHASE_WRITE_START,
  48        KCS_PHASE_WRITE_DATA,
  49        KCS_PHASE_WRITE_END_CMD,
  50        KCS_PHASE_WRITE_DONE,
  51
  52        KCS_PHASE_WAIT_READ,
  53        KCS_PHASE_READ,
  54
  55        KCS_PHASE_ABORT_ERROR1,
  56        KCS_PHASE_ABORT_ERROR2,
  57        KCS_PHASE_ERROR
  58};
  59
  60/* IPMI 2.0 - Table 9-4, KCS Interface Status Codes */
  61enum kcs_ipmi_errors {
  62        KCS_NO_ERROR                = 0x00,
  63        KCS_ABORTED_BY_COMMAND      = 0x01,
  64        KCS_ILLEGAL_CONTROL_CODE    = 0x02,
  65        KCS_LENGTH_ERROR            = 0x06,
  66        KCS_UNSPECIFIED_ERROR       = 0xFF
  67};
  68
  69struct kcs_bmc_ipmi {
  70        struct list_head entry;
  71
  72        struct kcs_bmc_client client;
  73
  74        spinlock_t lock;
  75
  76        enum kcs_ipmi_phases phase;
  77        enum kcs_ipmi_errors error;
  78
  79        wait_queue_head_t queue;
  80        bool data_in_avail;
  81        int  data_in_idx;
  82        u8  *data_in;
  83
  84        int  data_out_idx;
  85        int  data_out_len;
  86        u8  *data_out;
  87
  88        struct mutex mutex;
  89        u8 *kbuffer;
  90
  91        struct miscdevice miscdev;
  92};
  93
  94#define DEVICE_NAME "ipmi-kcs"
  95
  96#define KCS_MSG_BUFSIZ    1000
  97
  98#define KCS_ZERO_DATA     0
  99
 100/* IPMI 2.0 - Table 9-1, KCS Interface Status Register Bits */
 101#define KCS_STATUS_STATE(state) (state << 6)
 102#define KCS_STATUS_STATE_MASK   GENMASK(7, 6)
 103#define KCS_STATUS_CMD_DAT      BIT(3)
 104#define KCS_STATUS_SMS_ATN      BIT(2)
 105#define KCS_STATUS_IBF          BIT(1)
 106#define KCS_STATUS_OBF          BIT(0)
 107
 108/* IPMI 2.0 - Table 9-2, KCS Interface State Bits */
 109enum kcs_states {
 110        IDLE_STATE  = 0,
 111        READ_STATE  = 1,
 112        WRITE_STATE = 2,
 113        ERROR_STATE = 3,
 114};
 115
 116/* IPMI 2.0 - Table 9-3, KCS Interface Control Codes */
 117#define KCS_CMD_GET_STATUS_ABORT  0x60
 118#define KCS_CMD_WRITE_START       0x61
 119#define KCS_CMD_WRITE_END         0x62
 120#define KCS_CMD_READ_BYTE         0x68
 121
 122static inline void set_state(struct kcs_bmc_ipmi *priv, u8 state)
 123{
 124        kcs_bmc_update_status(priv->client.dev, KCS_STATUS_STATE_MASK, KCS_STATUS_STATE(state));
 125}
 126
 127static void kcs_bmc_ipmi_force_abort(struct kcs_bmc_ipmi *priv)
 128{
 129        set_state(priv, ERROR_STATE);
 130        kcs_bmc_read_data(priv->client.dev);
 131        kcs_bmc_write_data(priv->client.dev, KCS_ZERO_DATA);
 132
 133        priv->phase = KCS_PHASE_ERROR;
 134        priv->data_in_avail = false;
 135        priv->data_in_idx = 0;
 136}
 137
 138static void kcs_bmc_ipmi_handle_data(struct kcs_bmc_ipmi *priv)
 139{
 140        struct kcs_bmc_device *dev;
 141        u8 data;
 142
 143        dev = priv->client.dev;
 144
 145        switch (priv->phase) {
 146        case KCS_PHASE_WRITE_START:
 147                priv->phase = KCS_PHASE_WRITE_DATA;
 148                fallthrough;
 149
 150        case KCS_PHASE_WRITE_DATA:
 151                if (priv->data_in_idx < KCS_MSG_BUFSIZ) {
 152                        set_state(priv, WRITE_STATE);
 153                        kcs_bmc_write_data(dev, KCS_ZERO_DATA);
 154                        priv->data_in[priv->data_in_idx++] = kcs_bmc_read_data(dev);
 155                } else {
 156                        kcs_bmc_ipmi_force_abort(priv);
 157                        priv->error = KCS_LENGTH_ERROR;
 158                }
 159                break;
 160
 161        case KCS_PHASE_WRITE_END_CMD:
 162                if (priv->data_in_idx < KCS_MSG_BUFSIZ) {
 163                        set_state(priv, READ_STATE);
 164                        priv->data_in[priv->data_in_idx++] = kcs_bmc_read_data(dev);
 165                        priv->phase = KCS_PHASE_WRITE_DONE;
 166                        priv->data_in_avail = true;
 167                        wake_up_interruptible(&priv->queue);
 168                } else {
 169                        kcs_bmc_ipmi_force_abort(priv);
 170                        priv->error = KCS_LENGTH_ERROR;
 171                }
 172                break;
 173
 174        case KCS_PHASE_READ:
 175                if (priv->data_out_idx == priv->data_out_len)
 176                        set_state(priv, IDLE_STATE);
 177
 178                data = kcs_bmc_read_data(dev);
 179                if (data != KCS_CMD_READ_BYTE) {
 180                        set_state(priv, ERROR_STATE);
 181                        kcs_bmc_write_data(dev, KCS_ZERO_DATA);
 182                        break;
 183                }
 184
 185                if (priv->data_out_idx == priv->data_out_len) {
 186                        kcs_bmc_write_data(dev, KCS_ZERO_DATA);
 187                        priv->phase = KCS_PHASE_IDLE;
 188                        break;
 189                }
 190
 191                kcs_bmc_write_data(dev, priv->data_out[priv->data_out_idx++]);
 192                break;
 193
 194        case KCS_PHASE_ABORT_ERROR1:
 195                set_state(priv, READ_STATE);
 196                kcs_bmc_read_data(dev);
 197                kcs_bmc_write_data(dev, priv->error);
 198                priv->phase = KCS_PHASE_ABORT_ERROR2;
 199                break;
 200
 201        case KCS_PHASE_ABORT_ERROR2:
 202                set_state(priv, IDLE_STATE);
 203                kcs_bmc_read_data(dev);
 204                kcs_bmc_write_data(dev, KCS_ZERO_DATA);
 205                priv->phase = KCS_PHASE_IDLE;
 206                break;
 207
 208        default:
 209                kcs_bmc_ipmi_force_abort(priv);
 210                break;
 211        }
 212}
 213
 214static void kcs_bmc_ipmi_handle_cmd(struct kcs_bmc_ipmi *priv)
 215{
 216        u8 cmd;
 217
 218        set_state(priv, WRITE_STATE);
 219        kcs_bmc_write_data(priv->client.dev, KCS_ZERO_DATA);
 220
 221        cmd = kcs_bmc_read_data(priv->client.dev);
 222        switch (cmd) {
 223        case KCS_CMD_WRITE_START:
 224                priv->phase = KCS_PHASE_WRITE_START;
 225                priv->error = KCS_NO_ERROR;
 226                priv->data_in_avail = false;
 227                priv->data_in_idx = 0;
 228                break;
 229
 230        case KCS_CMD_WRITE_END:
 231                if (priv->phase != KCS_PHASE_WRITE_DATA) {
 232                        kcs_bmc_ipmi_force_abort(priv);
 233                        break;
 234                }
 235
 236                priv->phase = KCS_PHASE_WRITE_END_CMD;
 237                break;
 238
 239        case KCS_CMD_GET_STATUS_ABORT:
 240                if (priv->error == KCS_NO_ERROR)
 241                        priv->error = KCS_ABORTED_BY_COMMAND;
 242
 243                priv->phase = KCS_PHASE_ABORT_ERROR1;
 244                priv->data_in_avail = false;
 245                priv->data_in_idx = 0;
 246                break;
 247
 248        default:
 249                kcs_bmc_ipmi_force_abort(priv);
 250                priv->error = KCS_ILLEGAL_CONTROL_CODE;
 251                break;
 252        }
 253}
 254
 255static inline struct kcs_bmc_ipmi *client_to_kcs_bmc_ipmi(struct kcs_bmc_client *client)
 256{
 257        return container_of(client, struct kcs_bmc_ipmi, client);
 258}
 259
 260static irqreturn_t kcs_bmc_ipmi_event(struct kcs_bmc_client *client)
 261{
 262        struct kcs_bmc_ipmi *priv;
 263        u8 status;
 264        int ret;
 265
 266        priv = client_to_kcs_bmc_ipmi(client);
 267        if (!priv)
 268                return IRQ_NONE;
 269
 270        spin_lock(&priv->lock);
 271
 272        status = kcs_bmc_read_status(client->dev);
 273        if (status & KCS_STATUS_IBF) {
 274                if (status & KCS_STATUS_CMD_DAT)
 275                        kcs_bmc_ipmi_handle_cmd(priv);
 276                else
 277                        kcs_bmc_ipmi_handle_data(priv);
 278
 279                ret = IRQ_HANDLED;
 280        } else {
 281                ret = IRQ_NONE;
 282        }
 283
 284        spin_unlock(&priv->lock);
 285
 286        return ret;
 287}
 288
 289static const struct kcs_bmc_client_ops kcs_bmc_ipmi_client_ops = {
 290        .event = kcs_bmc_ipmi_event,
 291};
 292
 293static inline struct kcs_bmc_ipmi *to_kcs_bmc(struct file *filp)
 294{
 295        return container_of(filp->private_data, struct kcs_bmc_ipmi, miscdev);
 296}
 297
 298static int kcs_bmc_ipmi_open(struct inode *inode, struct file *filp)
 299{
 300        struct kcs_bmc_ipmi *priv = to_kcs_bmc(filp);
 301
 302        return kcs_bmc_enable_device(priv->client.dev, &priv->client);
 303}
 304
 305static __poll_t kcs_bmc_ipmi_poll(struct file *filp, poll_table *wait)
 306{
 307        struct kcs_bmc_ipmi *priv = to_kcs_bmc(filp);
 308        __poll_t mask = 0;
 309
 310        poll_wait(filp, &priv->queue, wait);
 311
 312        spin_lock_irq(&priv->lock);
 313        if (priv->data_in_avail)
 314                mask |= EPOLLIN;
 315        spin_unlock_irq(&priv->lock);
 316
 317        return mask;
 318}
 319
 320static ssize_t kcs_bmc_ipmi_read(struct file *filp, char __user *buf,
 321                            size_t count, loff_t *ppos)
 322{
 323        struct kcs_bmc_ipmi *priv = to_kcs_bmc(filp);
 324        bool data_avail;
 325        size_t data_len;
 326        ssize_t ret;
 327
 328        if (!(filp->f_flags & O_NONBLOCK))
 329                wait_event_interruptible(priv->queue,
 330                                         priv->data_in_avail);
 331
 332        mutex_lock(&priv->mutex);
 333
 334        spin_lock_irq(&priv->lock);
 335        data_avail = priv->data_in_avail;
 336        if (data_avail) {
 337                data_len = priv->data_in_idx;
 338                memcpy(priv->kbuffer, priv->data_in, data_len);
 339        }
 340        spin_unlock_irq(&priv->lock);
 341
 342        if (!data_avail) {
 343                ret = -EAGAIN;
 344                goto out_unlock;
 345        }
 346
 347        if (count < data_len) {
 348                pr_err("channel=%u with too large data : %zu\n",
 349                        priv->client.dev->channel, data_len);
 350
 351                spin_lock_irq(&priv->lock);
 352                kcs_bmc_ipmi_force_abort(priv);
 353                spin_unlock_irq(&priv->lock);
 354
 355                ret = -EOVERFLOW;
 356                goto out_unlock;
 357        }
 358
 359        if (copy_to_user(buf, priv->kbuffer, data_len)) {
 360                ret = -EFAULT;
 361                goto out_unlock;
 362        }
 363
 364        ret = data_len;
 365
 366        spin_lock_irq(&priv->lock);
 367        if (priv->phase == KCS_PHASE_WRITE_DONE) {
 368                priv->phase = KCS_PHASE_WAIT_READ;
 369                priv->data_in_avail = false;
 370                priv->data_in_idx = 0;
 371        } else {
 372                ret = -EAGAIN;
 373        }
 374        spin_unlock_irq(&priv->lock);
 375
 376out_unlock:
 377        mutex_unlock(&priv->mutex);
 378
 379        return ret;
 380}
 381
 382static ssize_t kcs_bmc_ipmi_write(struct file *filp, const char __user *buf,
 383                             size_t count, loff_t *ppos)
 384{
 385        struct kcs_bmc_ipmi *priv = to_kcs_bmc(filp);
 386        ssize_t ret;
 387
 388        /* a minimum response size '3' : netfn + cmd + ccode */
 389        if (count < 3 || count > KCS_MSG_BUFSIZ)
 390                return -EINVAL;
 391
 392        mutex_lock(&priv->mutex);
 393
 394        if (copy_from_user(priv->kbuffer, buf, count)) {
 395                ret = -EFAULT;
 396                goto out_unlock;
 397        }
 398
 399        spin_lock_irq(&priv->lock);
 400        if (priv->phase == KCS_PHASE_WAIT_READ) {
 401                priv->phase = KCS_PHASE_READ;
 402                priv->data_out_idx = 1;
 403                priv->data_out_len = count;
 404                memcpy(priv->data_out, priv->kbuffer, count);
 405                kcs_bmc_write_data(priv->client.dev, priv->data_out[0]);
 406                ret = count;
 407        } else {
 408                ret = -EINVAL;
 409        }
 410        spin_unlock_irq(&priv->lock);
 411
 412out_unlock:
 413        mutex_unlock(&priv->mutex);
 414
 415        return ret;
 416}
 417
 418static long kcs_bmc_ipmi_ioctl(struct file *filp, unsigned int cmd,
 419                          unsigned long arg)
 420{
 421        struct kcs_bmc_ipmi *priv = to_kcs_bmc(filp);
 422        long ret = 0;
 423
 424        spin_lock_irq(&priv->lock);
 425
 426        switch (cmd) {
 427        case IPMI_BMC_IOCTL_SET_SMS_ATN:
 428                kcs_bmc_update_status(priv->client.dev, KCS_STATUS_SMS_ATN, KCS_STATUS_SMS_ATN);
 429                break;
 430
 431        case IPMI_BMC_IOCTL_CLEAR_SMS_ATN:
 432                kcs_bmc_update_status(priv->client.dev, KCS_STATUS_SMS_ATN, 0);
 433                break;
 434
 435        case IPMI_BMC_IOCTL_FORCE_ABORT:
 436                kcs_bmc_ipmi_force_abort(priv);
 437                break;
 438
 439        default:
 440                ret = -EINVAL;
 441                break;
 442        }
 443
 444        spin_unlock_irq(&priv->lock);
 445
 446        return ret;
 447}
 448
 449static int kcs_bmc_ipmi_release(struct inode *inode, struct file *filp)
 450{
 451        struct kcs_bmc_ipmi *priv = to_kcs_bmc(filp);
 452
 453        kcs_bmc_ipmi_force_abort(priv);
 454        kcs_bmc_disable_device(priv->client.dev, &priv->client);
 455
 456        return 0;
 457}
 458
 459static const struct file_operations kcs_bmc_ipmi_fops = {
 460        .owner          = THIS_MODULE,
 461        .open           = kcs_bmc_ipmi_open,
 462        .read           = kcs_bmc_ipmi_read,
 463        .write          = kcs_bmc_ipmi_write,
 464        .release        = kcs_bmc_ipmi_release,
 465        .poll           = kcs_bmc_ipmi_poll,
 466        .unlocked_ioctl = kcs_bmc_ipmi_ioctl,
 467};
 468
 469static DEFINE_SPINLOCK(kcs_bmc_ipmi_instances_lock);
 470static LIST_HEAD(kcs_bmc_ipmi_instances);
 471
 472static int kcs_bmc_ipmi_add_device(struct kcs_bmc_device *kcs_bmc)
 473{
 474        struct kcs_bmc_ipmi *priv;
 475        int rc;
 476
 477        priv = devm_kzalloc(kcs_bmc->dev, sizeof(*priv), GFP_KERNEL);
 478        if (!priv)
 479                return -ENOMEM;
 480
 481        spin_lock_init(&priv->lock);
 482        mutex_init(&priv->mutex);
 483
 484        init_waitqueue_head(&priv->queue);
 485
 486        priv->client.dev = kcs_bmc;
 487        priv->client.ops = &kcs_bmc_ipmi_client_ops;
 488        priv->data_in = devm_kmalloc(kcs_bmc->dev, KCS_MSG_BUFSIZ, GFP_KERNEL);
 489        priv->data_out = devm_kmalloc(kcs_bmc->dev, KCS_MSG_BUFSIZ, GFP_KERNEL);
 490        priv->kbuffer = devm_kmalloc(kcs_bmc->dev, KCS_MSG_BUFSIZ, GFP_KERNEL);
 491
 492        priv->miscdev.minor = MISC_DYNAMIC_MINOR;
 493        priv->miscdev.name = devm_kasprintf(kcs_bmc->dev, GFP_KERNEL, "%s%u", DEVICE_NAME,
 494                                           kcs_bmc->channel);
 495        if (!priv->data_in || !priv->data_out || !priv->kbuffer || !priv->miscdev.name)
 496                return -EINVAL;
 497
 498        priv->miscdev.fops = &kcs_bmc_ipmi_fops;
 499
 500        rc = misc_register(&priv->miscdev);
 501        if (rc) {
 502                dev_err(kcs_bmc->dev, "Unable to register device: %d\n", rc);
 503                return rc;
 504        }
 505
 506        spin_lock_irq(&kcs_bmc_ipmi_instances_lock);
 507        list_add(&priv->entry, &kcs_bmc_ipmi_instances);
 508        spin_unlock_irq(&kcs_bmc_ipmi_instances_lock);
 509
 510        dev_info(kcs_bmc->dev, "Initialised IPMI client for channel %d", kcs_bmc->channel);
 511
 512        return 0;
 513}
 514
 515static int kcs_bmc_ipmi_remove_device(struct kcs_bmc_device *kcs_bmc)
 516{
 517        struct kcs_bmc_ipmi *priv = NULL, *pos;
 518
 519        spin_lock_irq(&kcs_bmc_ipmi_instances_lock);
 520        list_for_each_entry(pos, &kcs_bmc_ipmi_instances, entry) {
 521                if (pos->client.dev == kcs_bmc) {
 522                        priv = pos;
 523                        list_del(&pos->entry);
 524                        break;
 525                }
 526        }
 527        spin_unlock_irq(&kcs_bmc_ipmi_instances_lock);
 528
 529        if (!priv)
 530                return -ENODEV;
 531
 532        misc_deregister(&priv->miscdev);
 533        kcs_bmc_disable_device(priv->client.dev, &priv->client);
 534        devm_kfree(kcs_bmc->dev, priv->kbuffer);
 535        devm_kfree(kcs_bmc->dev, priv->data_out);
 536        devm_kfree(kcs_bmc->dev, priv->data_in);
 537        devm_kfree(kcs_bmc->dev, priv);
 538
 539        return 0;
 540}
 541
 542static const struct kcs_bmc_driver_ops kcs_bmc_ipmi_driver_ops = {
 543        .add_device = kcs_bmc_ipmi_add_device,
 544        .remove_device = kcs_bmc_ipmi_remove_device,
 545};
 546
 547static struct kcs_bmc_driver kcs_bmc_ipmi_driver = {
 548        .ops = &kcs_bmc_ipmi_driver_ops,
 549};
 550
 551static int kcs_bmc_ipmi_init(void)
 552{
 553        kcs_bmc_register_driver(&kcs_bmc_ipmi_driver);
 554
 555        return 0;
 556}
 557module_init(kcs_bmc_ipmi_init);
 558
 559static void kcs_bmc_ipmi_exit(void)
 560{
 561        kcs_bmc_unregister_driver(&kcs_bmc_ipmi_driver);
 562}
 563module_exit(kcs_bmc_ipmi_exit);
 564
 565MODULE_LICENSE("GPL v2");
 566MODULE_AUTHOR("Haiyue Wang <haiyue.wang@linux.intel.com>");
 567MODULE_AUTHOR("Andrew Jeffery <andrew@aj.id.au>");
 568MODULE_DESCRIPTION("KCS BMC to handle the IPMI request from system software");
 569