linux/drivers/watchdog/mei_wdt.c
<<
>>
Prefs
   1/*
   2 * Intel Management Engine Interface (Intel MEI) Linux driver
   3 * Copyright (c) 2015, Intel Corporation.
   4 *
   5 * This program is free software; you can redistribute it and/or modify it
   6 * under the terms and conditions of the GNU General Public License,
   7 * version 2, as published by the Free Software Foundation.
   8 *
   9 * This program is distributed in the hope it will be useful, but WITHOUT
  10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
  12 * more details.
  13 */
  14
  15#include <linux/module.h>
  16#include <linux/slab.h>
  17#include <linux/interrupt.h>
  18#include <linux/debugfs.h>
  19#include <linux/completion.h>
  20#include <linux/watchdog.h>
  21
  22#include <linux/uuid.h>
  23#include <linux/mei_cl_bus.h>
  24
  25/*
  26 * iAMT Watchdog Device
  27 */
  28#define INTEL_AMT_WATCHDOG_ID "iamt_wdt"
  29
  30#define MEI_WDT_DEFAULT_TIMEOUT   120  /* seconds */
  31#define MEI_WDT_MIN_TIMEOUT       120  /* seconds */
  32#define MEI_WDT_MAX_TIMEOUT     65535  /* seconds */
  33
  34/* Commands */
  35#define MEI_MANAGEMENT_CONTROL 0x02
  36
  37/* MEI Management Control version number */
  38#define MEI_MC_VERSION_NUMBER  0x10
  39
  40/* Sub Commands */
  41#define MEI_MC_START_WD_TIMER_REQ  0x13
  42#define MEI_MC_START_WD_TIMER_RES  0x83
  43#define   MEI_WDT_STATUS_SUCCESS 0
  44#define   MEI_WDT_WDSTATE_NOT_REQUIRED 0x1
  45#define MEI_MC_STOP_WD_TIMER_REQ   0x14
  46
  47/**
  48 * enum mei_wdt_state - internal watchdog state
  49 *
  50 * @MEI_WDT_PROBE: wd in probing stage
  51 * @MEI_WDT_IDLE: wd is idle and not opened
  52 * @MEI_WDT_START: wd was opened, start was called
  53 * @MEI_WDT_RUNNING: wd is expecting keep alive pings
  54 * @MEI_WDT_STOPPING: wd is stopping and will move to IDLE
  55 * @MEI_WDT_NOT_REQUIRED: wd device is not required
  56 */
  57enum mei_wdt_state {
  58        MEI_WDT_PROBE,
  59        MEI_WDT_IDLE,
  60        MEI_WDT_START,
  61        MEI_WDT_RUNNING,
  62        MEI_WDT_STOPPING,
  63        MEI_WDT_NOT_REQUIRED,
  64};
  65
  66static const char *mei_wdt_state_str(enum mei_wdt_state state)
  67{
  68        switch (state) {
  69        case MEI_WDT_PROBE:
  70                return "PROBE";
  71        case MEI_WDT_IDLE:
  72                return "IDLE";
  73        case MEI_WDT_START:
  74                return "START";
  75        case MEI_WDT_RUNNING:
  76                return "RUNNING";
  77        case MEI_WDT_STOPPING:
  78                return "STOPPING";
  79        case MEI_WDT_NOT_REQUIRED:
  80                return "NOT_REQUIRED";
  81        default:
  82                return "unknown";
  83        }
  84}
  85
  86/**
  87 * struct mei_wdt - mei watchdog driver
  88 * @wdd: watchdog device
  89 *
  90 * @cldev: mei watchdog client device
  91 * @state: watchdog internal state
  92 * @resp_required: ping required response
  93 * @response: ping response completion
  94 * @unregister: unregister worker
  95 * @reg_lock: watchdog device registration lock
  96 * @timeout: watchdog current timeout
  97 *
  98 * @dbgfs_dir: debugfs dir entry
  99 */
 100struct mei_wdt {
 101        struct watchdog_device wdd;
 102
 103        struct mei_cl_device *cldev;
 104        enum mei_wdt_state state;
 105        bool resp_required;
 106        struct completion response;
 107        struct work_struct unregister;
 108        struct mutex reg_lock;
 109        u16 timeout;
 110
 111#if IS_ENABLED(CONFIG_DEBUG_FS)
 112        struct dentry *dbgfs_dir;
 113#endif /* CONFIG_DEBUG_FS */
 114};
 115
 116/*
 117 * struct mei_mc_hdr - Management Control Command Header
 118 *
 119 * @command: Management Control (0x2)
 120 * @bytecount: Number of bytes in the message beyond this byte
 121 * @subcommand: Management Control Subcommand
 122 * @versionnumber: Management Control Version (0x10)
 123 */
 124struct mei_mc_hdr {
 125        u8 command;
 126        u8 bytecount;
 127        u8 subcommand;
 128        u8 versionnumber;
 129};
 130
 131/**
 132 * struct mei_wdt_start_request watchdog start/ping
 133 *
 134 * @hdr: Management Control Command Header
 135 * @timeout: timeout value
 136 * @reserved: reserved (legacy)
 137 */
 138struct mei_wdt_start_request {
 139        struct mei_mc_hdr hdr;
 140        u16 timeout;
 141        u8 reserved[17];
 142} __packed;
 143
 144/**
 145 * struct mei_wdt_start_response watchdog start/ping response
 146 *
 147 * @hdr: Management Control Command Header
 148 * @status: operation status
 149 * @wdstate: watchdog status bit mask
 150 */
 151struct mei_wdt_start_response {
 152        struct mei_mc_hdr hdr;
 153        u8 status;
 154        u8 wdstate;
 155} __packed;
 156
 157/**
 158 * struct mei_wdt_stop_request - watchdog stop
 159 *
 160 * @hdr: Management Control Command Header
 161 */
 162struct mei_wdt_stop_request {
 163        struct mei_mc_hdr hdr;
 164} __packed;
 165
 166/**
 167 * mei_wdt_ping - send wd start/ping command
 168 *
 169 * @wdt: mei watchdog device
 170 *
 171 * Return: 0 on success,
 172 *         negative errno code on failure
 173 */
 174static int mei_wdt_ping(struct mei_wdt *wdt)
 175{
 176        struct mei_wdt_start_request req;
 177        const size_t req_len = sizeof(req);
 178        int ret;
 179
 180        memset(&req, 0, req_len);
 181        req.hdr.command = MEI_MANAGEMENT_CONTROL;
 182        req.hdr.bytecount = req_len - offsetof(struct mei_mc_hdr, subcommand);
 183        req.hdr.subcommand = MEI_MC_START_WD_TIMER_REQ;
 184        req.hdr.versionnumber = MEI_MC_VERSION_NUMBER;
 185        req.timeout = wdt->timeout;
 186
 187        ret = mei_cldev_send(wdt->cldev, (u8 *)&req, req_len);
 188        if (ret < 0)
 189                return ret;
 190
 191        return 0;
 192}
 193
 194/**
 195 * mei_wdt_stop - send wd stop command
 196 *
 197 * @wdt: mei watchdog device
 198 *
 199 * Return: 0 on success,
 200 *         negative errno code on failure
 201 */
 202static int mei_wdt_stop(struct mei_wdt *wdt)
 203{
 204        struct mei_wdt_stop_request req;
 205        const size_t req_len = sizeof(req);
 206        int ret;
 207
 208        memset(&req, 0, req_len);
 209        req.hdr.command = MEI_MANAGEMENT_CONTROL;
 210        req.hdr.bytecount = req_len - offsetof(struct mei_mc_hdr, subcommand);
 211        req.hdr.subcommand = MEI_MC_STOP_WD_TIMER_REQ;
 212        req.hdr.versionnumber = MEI_MC_VERSION_NUMBER;
 213
 214        ret = mei_cldev_send(wdt->cldev, (u8 *)&req, req_len);
 215        if (ret < 0)
 216                return ret;
 217
 218        return 0;
 219}
 220
 221/**
 222 * mei_wdt_ops_start - wd start command from the watchdog core.
 223 *
 224 * @wdd: watchdog device
 225 *
 226 * Return: 0 on success or -ENODEV;
 227 */
 228static int mei_wdt_ops_start(struct watchdog_device *wdd)
 229{
 230        struct mei_wdt *wdt = watchdog_get_drvdata(wdd);
 231
 232        wdt->state = MEI_WDT_START;
 233        wdd->timeout = wdt->timeout;
 234        return 0;
 235}
 236
 237/**
 238 * mei_wdt_ops_stop - wd stop command from the watchdog core.
 239 *
 240 * @wdd: watchdog device
 241 *
 242 * Return: 0 if success, negative errno code for failure
 243 */
 244static int mei_wdt_ops_stop(struct watchdog_device *wdd)
 245{
 246        struct mei_wdt *wdt = watchdog_get_drvdata(wdd);
 247        int ret;
 248
 249        if (wdt->state != MEI_WDT_RUNNING)
 250                return 0;
 251
 252        wdt->state = MEI_WDT_STOPPING;
 253
 254        ret = mei_wdt_stop(wdt);
 255        if (ret)
 256                return ret;
 257
 258        wdt->state = MEI_WDT_IDLE;
 259
 260        return 0;
 261}
 262
 263/**
 264 * mei_wdt_ops_ping - wd ping command from the watchdog core.
 265 *
 266 * @wdd: watchdog device
 267 *
 268 * Return: 0 if success, negative errno code on failure
 269 */
 270static int mei_wdt_ops_ping(struct watchdog_device *wdd)
 271{
 272        struct mei_wdt *wdt = watchdog_get_drvdata(wdd);
 273        int ret;
 274
 275        if (wdt->state != MEI_WDT_START && wdt->state != MEI_WDT_RUNNING)
 276                return 0;
 277
 278        if (wdt->resp_required)
 279                init_completion(&wdt->response);
 280
 281        wdt->state = MEI_WDT_RUNNING;
 282        ret = mei_wdt_ping(wdt);
 283        if (ret)
 284                return ret;
 285
 286        if (wdt->resp_required)
 287                ret = wait_for_completion_killable(&wdt->response);
 288
 289        return ret;
 290}
 291
 292/**
 293 * mei_wdt_ops_set_timeout - wd set timeout command from the watchdog core.
 294 *
 295 * @wdd: watchdog device
 296 * @timeout: timeout value to set
 297 *
 298 * Return: 0 if success, negative errno code for failure
 299 */
 300static int mei_wdt_ops_set_timeout(struct watchdog_device *wdd,
 301                                   unsigned int timeout)
 302{
 303
 304        struct mei_wdt *wdt = watchdog_get_drvdata(wdd);
 305
 306        /* valid value is already checked by the caller */
 307        wdt->timeout = timeout;
 308        wdd->timeout = timeout;
 309
 310        return 0;
 311}
 312
 313static const struct watchdog_ops wd_ops = {
 314        .owner       = THIS_MODULE,
 315        .start       = mei_wdt_ops_start,
 316        .stop        = mei_wdt_ops_stop,
 317        .ping        = mei_wdt_ops_ping,
 318        .set_timeout = mei_wdt_ops_set_timeout,
 319};
 320
 321/* not const as the firmware_version field need to be retrieved */
 322static struct watchdog_info wd_info = {
 323        .identity = INTEL_AMT_WATCHDOG_ID,
 324        .options  = WDIOF_KEEPALIVEPING |
 325                    WDIOF_SETTIMEOUT |
 326                    WDIOF_ALARMONLY,
 327};
 328
 329/**
 330 * __mei_wdt_is_registered - check if wdt is registered
 331 *
 332 * @wdt: mei watchdog device
 333 *
 334 * Return: true if the wdt is registered with the watchdog subsystem
 335 * Locking: should be called under wdt->reg_lock
 336 */
 337static inline bool __mei_wdt_is_registered(struct mei_wdt *wdt)
 338{
 339        return !!watchdog_get_drvdata(&wdt->wdd);
 340}
 341
 342/**
 343 * mei_wdt_unregister - unregister from the watchdog subsystem
 344 *
 345 * @wdt: mei watchdog device
 346 */
 347static void mei_wdt_unregister(struct mei_wdt *wdt)
 348{
 349        mutex_lock(&wdt->reg_lock);
 350
 351        if (__mei_wdt_is_registered(wdt)) {
 352                watchdog_unregister_device(&wdt->wdd);
 353                watchdog_set_drvdata(&wdt->wdd, NULL);
 354                memset(&wdt->wdd, 0, sizeof(wdt->wdd));
 355        }
 356
 357        mutex_unlock(&wdt->reg_lock);
 358}
 359
 360/**
 361 * mei_wdt_register - register with the watchdog subsystem
 362 *
 363 * @wdt: mei watchdog device
 364 *
 365 * Return: 0 if success, negative errno code for failure
 366 */
 367static int mei_wdt_register(struct mei_wdt *wdt)
 368{
 369        struct device *dev;
 370        int ret;
 371
 372        if (!wdt || !wdt->cldev)
 373                return -EINVAL;
 374
 375        dev = &wdt->cldev->dev;
 376
 377        mutex_lock(&wdt->reg_lock);
 378
 379        if (__mei_wdt_is_registered(wdt)) {
 380                ret = 0;
 381                goto out;
 382        }
 383
 384        wdt->wdd.info = &wd_info;
 385        wdt->wdd.ops = &wd_ops;
 386        wdt->wdd.parent = dev;
 387        wdt->wdd.timeout = MEI_WDT_DEFAULT_TIMEOUT;
 388        wdt->wdd.min_timeout = MEI_WDT_MIN_TIMEOUT;
 389        wdt->wdd.max_timeout = MEI_WDT_MAX_TIMEOUT;
 390
 391        watchdog_set_drvdata(&wdt->wdd, wdt);
 392        watchdog_stop_on_reboot(&wdt->wdd);
 393
 394        ret = watchdog_register_device(&wdt->wdd);
 395        if (ret) {
 396                dev_err(dev, "unable to register watchdog device = %d.\n", ret);
 397                watchdog_set_drvdata(&wdt->wdd, NULL);
 398        }
 399
 400        wdt->state = MEI_WDT_IDLE;
 401
 402out:
 403        mutex_unlock(&wdt->reg_lock);
 404        return ret;
 405}
 406
 407static void mei_wdt_unregister_work(struct work_struct *work)
 408{
 409        struct mei_wdt *wdt = container_of(work, struct mei_wdt, unregister);
 410
 411        mei_wdt_unregister(wdt);
 412}
 413
 414/**
 415 * mei_wdt_rx - callback for data receive
 416 *
 417 * @cldev: bus device
 418 */
 419static void mei_wdt_rx(struct mei_cl_device *cldev)
 420{
 421        struct mei_wdt *wdt = mei_cldev_get_drvdata(cldev);
 422        struct mei_wdt_start_response res;
 423        const size_t res_len = sizeof(res);
 424        int ret;
 425
 426        ret = mei_cldev_recv(wdt->cldev, (u8 *)&res, res_len);
 427        if (ret < 0) {
 428                dev_err(&cldev->dev, "failure in recv %d\n", ret);
 429                return;
 430        }
 431
 432        /* Empty response can be sent on stop */
 433        if (ret == 0)
 434                return;
 435
 436        if (ret < sizeof(struct mei_mc_hdr)) {
 437                dev_err(&cldev->dev, "recv small data %d\n", ret);
 438                return;
 439        }
 440
 441        if (res.hdr.command != MEI_MANAGEMENT_CONTROL ||
 442            res.hdr.versionnumber != MEI_MC_VERSION_NUMBER) {
 443                dev_err(&cldev->dev, "wrong command received\n");
 444                return;
 445        }
 446
 447        if (res.hdr.subcommand != MEI_MC_START_WD_TIMER_RES) {
 448                dev_warn(&cldev->dev, "unsupported command %d :%s[%d]\n",
 449                         res.hdr.subcommand,
 450                         mei_wdt_state_str(wdt->state),
 451                         wdt->state);
 452                return;
 453        }
 454
 455        /* Run the unregistration in a worker as this can be
 456         * run only after ping completion, otherwise the flow will
 457         * deadlock on watchdog core mutex.
 458         */
 459        if (wdt->state == MEI_WDT_RUNNING) {
 460                if (res.wdstate & MEI_WDT_WDSTATE_NOT_REQUIRED) {
 461                        wdt->state = MEI_WDT_NOT_REQUIRED;
 462                        schedule_work(&wdt->unregister);
 463                }
 464                goto out;
 465        }
 466
 467        if (wdt->state == MEI_WDT_PROBE) {
 468                if (res.wdstate & MEI_WDT_WDSTATE_NOT_REQUIRED) {
 469                        wdt->state = MEI_WDT_NOT_REQUIRED;
 470                } else {
 471                        /* stop the watchdog and register watchdog device */
 472                        mei_wdt_stop(wdt);
 473                        mei_wdt_register(wdt);
 474                }
 475                return;
 476        }
 477
 478        dev_warn(&cldev->dev, "not in correct state %s[%d]\n",
 479                         mei_wdt_state_str(wdt->state), wdt->state);
 480
 481out:
 482        if (!completion_done(&wdt->response))
 483                complete(&wdt->response);
 484}
 485
 486/*
 487 * mei_wdt_notif - callback for event notification
 488 *
 489 * @cldev: bus device
 490 */
 491static void mei_wdt_notif(struct mei_cl_device *cldev)
 492{
 493        struct mei_wdt *wdt = mei_cldev_get_drvdata(cldev);
 494
 495        if (wdt->state != MEI_WDT_NOT_REQUIRED)
 496                return;
 497
 498        mei_wdt_register(wdt);
 499}
 500
 501#if IS_ENABLED(CONFIG_DEBUG_FS)
 502
 503static ssize_t mei_dbgfs_read_activation(struct file *file, char __user *ubuf,
 504                                        size_t cnt, loff_t *ppos)
 505{
 506        struct mei_wdt *wdt = file->private_data;
 507        const size_t bufsz = 32;
 508        char buf[32];
 509        ssize_t pos;
 510
 511        mutex_lock(&wdt->reg_lock);
 512        pos = scnprintf(buf, bufsz, "%s\n",
 513                __mei_wdt_is_registered(wdt) ? "activated" : "deactivated");
 514        mutex_unlock(&wdt->reg_lock);
 515
 516        return simple_read_from_buffer(ubuf, cnt, ppos, buf, pos);
 517}
 518
 519static const struct file_operations dbgfs_fops_activation = {
 520        .open    = simple_open,
 521        .read    = mei_dbgfs_read_activation,
 522        .llseek  = generic_file_llseek,
 523};
 524
 525static ssize_t mei_dbgfs_read_state(struct file *file, char __user *ubuf,
 526                                    size_t cnt, loff_t *ppos)
 527{
 528        struct mei_wdt *wdt = file->private_data;
 529        const size_t bufsz = 32;
 530        char buf[bufsz];
 531        ssize_t pos;
 532
 533        pos = scnprintf(buf, bufsz, "state: %s\n",
 534                         mei_wdt_state_str(wdt->state));
 535
 536        return simple_read_from_buffer(ubuf, cnt, ppos, buf, pos);
 537}
 538
 539static const struct file_operations dbgfs_fops_state = {
 540        .open = simple_open,
 541        .read = mei_dbgfs_read_state,
 542        .llseek = generic_file_llseek,
 543};
 544
 545static void dbgfs_unregister(struct mei_wdt *wdt)
 546{
 547        debugfs_remove_recursive(wdt->dbgfs_dir);
 548        wdt->dbgfs_dir = NULL;
 549}
 550
 551static int dbgfs_register(struct mei_wdt *wdt)
 552{
 553        struct dentry *dir, *f;
 554
 555        dir = debugfs_create_dir(KBUILD_MODNAME, NULL);
 556        if (!dir)
 557                return -ENOMEM;
 558
 559        wdt->dbgfs_dir = dir;
 560        f = debugfs_create_file("state", S_IRUSR, dir, wdt, &dbgfs_fops_state);
 561        if (!f)
 562                goto err;
 563
 564        f = debugfs_create_file("activation",  S_IRUSR,
 565                                dir, wdt, &dbgfs_fops_activation);
 566        if (!f)
 567                goto err;
 568
 569        return 0;
 570err:
 571        dbgfs_unregister(wdt);
 572        return -ENODEV;
 573}
 574
 575#else
 576
 577static inline void dbgfs_unregister(struct mei_wdt *wdt) {}
 578
 579static inline int dbgfs_register(struct mei_wdt *wdt)
 580{
 581        return 0;
 582}
 583#endif /* CONFIG_DEBUG_FS */
 584
 585static int mei_wdt_probe(struct mei_cl_device *cldev,
 586                         const struct mei_cl_device_id *id)
 587{
 588        struct mei_wdt *wdt;
 589        int ret;
 590
 591        wdt = kzalloc(sizeof(struct mei_wdt), GFP_KERNEL);
 592        if (!wdt)
 593                return -ENOMEM;
 594
 595        wdt->timeout = MEI_WDT_DEFAULT_TIMEOUT;
 596        wdt->state = MEI_WDT_PROBE;
 597        wdt->cldev = cldev;
 598        wdt->resp_required = mei_cldev_ver(cldev) > 0x1;
 599        mutex_init(&wdt->reg_lock);
 600        init_completion(&wdt->response);
 601        INIT_WORK(&wdt->unregister, mei_wdt_unregister_work);
 602
 603        mei_cldev_set_drvdata(cldev, wdt);
 604
 605        ret = mei_cldev_enable(cldev);
 606        if (ret < 0) {
 607                dev_err(&cldev->dev, "Could not enable cl device\n");
 608                goto err_out;
 609        }
 610
 611        ret = mei_cldev_register_rx_cb(wdt->cldev, mei_wdt_rx);
 612        if (ret) {
 613                dev_err(&cldev->dev, "Could not reg rx event ret=%d\n", ret);
 614                goto err_disable;
 615        }
 616
 617        ret = mei_cldev_register_notif_cb(wdt->cldev, mei_wdt_notif);
 618        /* on legacy devices notification is not supported
 619         */
 620        if (ret && ret != -EOPNOTSUPP) {
 621                dev_err(&cldev->dev, "Could not reg notif event ret=%d\n", ret);
 622                goto err_disable;
 623        }
 624
 625        wd_info.firmware_version = mei_cldev_ver(cldev);
 626
 627        if (wdt->resp_required)
 628                ret = mei_wdt_ping(wdt);
 629        else
 630                ret = mei_wdt_register(wdt);
 631
 632        if (ret)
 633                goto err_disable;
 634
 635        if (dbgfs_register(wdt))
 636                dev_warn(&cldev->dev, "cannot register debugfs\n");
 637
 638        return 0;
 639
 640err_disable:
 641        mei_cldev_disable(cldev);
 642
 643err_out:
 644        kfree(wdt);
 645
 646        return ret;
 647}
 648
 649static int mei_wdt_remove(struct mei_cl_device *cldev)
 650{
 651        struct mei_wdt *wdt = mei_cldev_get_drvdata(cldev);
 652
 653        /* Free the caller in case of fw initiated or unexpected reset */
 654        if (!completion_done(&wdt->response))
 655                complete(&wdt->response);
 656
 657        cancel_work_sync(&wdt->unregister);
 658
 659        mei_wdt_unregister(wdt);
 660
 661        mei_cldev_disable(cldev);
 662
 663        dbgfs_unregister(wdt);
 664
 665        kfree(wdt);
 666
 667        return 0;
 668}
 669
 670#define MEI_UUID_WD UUID_LE(0x05B79A6F, 0x4628, 0x4D7F, \
 671                            0x89, 0x9D, 0xA9, 0x15, 0x14, 0xCB, 0x32, 0xAB)
 672
 673static struct mei_cl_device_id mei_wdt_tbl[] = {
 674        { .uuid = MEI_UUID_WD, .version = MEI_CL_VERSION_ANY },
 675        /* required last entry */
 676        { }
 677};
 678MODULE_DEVICE_TABLE(mei, mei_wdt_tbl);
 679
 680static struct mei_cl_driver mei_wdt_driver = {
 681        .id_table = mei_wdt_tbl,
 682        .name = KBUILD_MODNAME,
 683
 684        .probe = mei_wdt_probe,
 685        .remove = mei_wdt_remove,
 686};
 687
 688module_mei_cl_driver(mei_wdt_driver);
 689
 690MODULE_AUTHOR("Intel Corporation");
 691MODULE_LICENSE("GPL");
 692MODULE_DESCRIPTION("Device driver for Intel MEI iAMT watchdog");
 693