linux/drivers/thunderbolt/retimer.c
<<
>>
Prefs
   1// SPDX-License-Identifier: GPL-2.0
   2/*
   3 * Thunderbolt/USB4 retimer support.
   4 *
   5 * Copyright (C) 2020, Intel Corporation
   6 * Authors: Kranthi Kuntala <kranthi.kuntala@intel.com>
   7 *          Mika Westerberg <mika.westerberg@linux.intel.com>
   8 */
   9
  10#include <linux/delay.h>
  11#include <linux/pm_runtime.h>
  12#include <linux/sched/signal.h>
  13
  14#include "sb_regs.h"
  15#include "tb.h"
  16
  17#define TB_MAX_RETIMER_INDEX    6
  18
  19static int tb_retimer_nvm_read(void *priv, unsigned int offset, void *val,
  20                               size_t bytes)
  21{
  22        struct tb_nvm *nvm = priv;
  23        struct tb_retimer *rt = tb_to_retimer(nvm->dev);
  24        int ret;
  25
  26        pm_runtime_get_sync(&rt->dev);
  27
  28        if (!mutex_trylock(&rt->tb->lock)) {
  29                ret = restart_syscall();
  30                goto out;
  31        }
  32
  33        ret = usb4_port_retimer_nvm_read(rt->port, rt->index, offset, val, bytes);
  34        mutex_unlock(&rt->tb->lock);
  35
  36out:
  37        pm_runtime_mark_last_busy(&rt->dev);
  38        pm_runtime_put_autosuspend(&rt->dev);
  39
  40        return ret;
  41}
  42
  43static int tb_retimer_nvm_write(void *priv, unsigned int offset, void *val,
  44                                size_t bytes)
  45{
  46        struct tb_nvm *nvm = priv;
  47        struct tb_retimer *rt = tb_to_retimer(nvm->dev);
  48        int ret = 0;
  49
  50        if (!mutex_trylock(&rt->tb->lock))
  51                return restart_syscall();
  52
  53        ret = tb_nvm_write_buf(nvm, offset, val, bytes);
  54        mutex_unlock(&rt->tb->lock);
  55
  56        return ret;
  57}
  58
  59static int tb_retimer_nvm_add(struct tb_retimer *rt)
  60{
  61        struct tb_nvm *nvm;
  62        u32 val, nvm_size;
  63        int ret;
  64
  65        nvm = tb_nvm_alloc(&rt->dev);
  66        if (IS_ERR(nvm))
  67                return PTR_ERR(nvm);
  68
  69        ret = usb4_port_retimer_nvm_read(rt->port, rt->index, NVM_VERSION, &val,
  70                                         sizeof(val));
  71        if (ret)
  72                goto err_nvm;
  73
  74        nvm->major = val >> 16;
  75        nvm->minor = val >> 8;
  76
  77        ret = usb4_port_retimer_nvm_read(rt->port, rt->index, NVM_FLASH_SIZE,
  78                                         &val, sizeof(val));
  79        if (ret)
  80                goto err_nvm;
  81
  82        nvm_size = (SZ_1M << (val & 7)) / 8;
  83        nvm_size = (nvm_size - SZ_16K) / 2;
  84
  85        ret = tb_nvm_add_active(nvm, nvm_size, tb_retimer_nvm_read);
  86        if (ret)
  87                goto err_nvm;
  88
  89        ret = tb_nvm_add_non_active(nvm, NVM_MAX_SIZE, tb_retimer_nvm_write);
  90        if (ret)
  91                goto err_nvm;
  92
  93        rt->nvm = nvm;
  94        return 0;
  95
  96err_nvm:
  97        tb_nvm_free(nvm);
  98        return ret;
  99}
 100
 101static int tb_retimer_nvm_validate_and_write(struct tb_retimer *rt)
 102{
 103        unsigned int image_size, hdr_size;
 104        const u8 *buf = rt->nvm->buf;
 105        u16 ds_size, device;
 106
 107        image_size = rt->nvm->buf_data_size;
 108        if (image_size < NVM_MIN_SIZE || image_size > NVM_MAX_SIZE)
 109                return -EINVAL;
 110
 111        /*
 112         * FARB pointer must point inside the image and must at least
 113         * contain parts of the digital section we will be reading here.
 114         */
 115        hdr_size = (*(u32 *)buf) & 0xffffff;
 116        if (hdr_size + NVM_DEVID + 2 >= image_size)
 117                return -EINVAL;
 118
 119        /* Digital section start should be aligned to 4k page */
 120        if (!IS_ALIGNED(hdr_size, SZ_4K))
 121                return -EINVAL;
 122
 123        /*
 124         * Read digital section size and check that it also fits inside
 125         * the image.
 126         */
 127        ds_size = *(u16 *)(buf + hdr_size);
 128        if (ds_size >= image_size)
 129                return -EINVAL;
 130
 131        /*
 132         * Make sure the device ID in the image matches the retimer
 133         * hardware.
 134         */
 135        device = *(u16 *)(buf + hdr_size + NVM_DEVID);
 136        if (device != rt->device)
 137                return -EINVAL;
 138
 139        /* Skip headers in the image */
 140        buf += hdr_size;
 141        image_size -= hdr_size;
 142
 143        return usb4_port_retimer_nvm_write(rt->port, rt->index, 0, buf,
 144                                           image_size);
 145}
 146
 147static ssize_t device_show(struct device *dev, struct device_attribute *attr,
 148                           char *buf)
 149{
 150        struct tb_retimer *rt = tb_to_retimer(dev);
 151
 152        return sprintf(buf, "%#x\n", rt->device);
 153}
 154static DEVICE_ATTR_RO(device);
 155
 156static ssize_t nvm_authenticate_show(struct device *dev,
 157        struct device_attribute *attr, char *buf)
 158{
 159        struct tb_retimer *rt = tb_to_retimer(dev);
 160        int ret;
 161
 162        if (!mutex_trylock(&rt->tb->lock))
 163                return restart_syscall();
 164
 165        if (!rt->nvm)
 166                ret = -EAGAIN;
 167        else
 168                ret = sprintf(buf, "%#x\n", rt->auth_status);
 169
 170        mutex_unlock(&rt->tb->lock);
 171
 172        return ret;
 173}
 174
 175static ssize_t nvm_authenticate_store(struct device *dev,
 176        struct device_attribute *attr, const char *buf, size_t count)
 177{
 178        struct tb_retimer *rt = tb_to_retimer(dev);
 179        bool val;
 180        int ret;
 181
 182        pm_runtime_get_sync(&rt->dev);
 183
 184        if (!mutex_trylock(&rt->tb->lock)) {
 185                ret = restart_syscall();
 186                goto exit_rpm;
 187        }
 188
 189        if (!rt->nvm) {
 190                ret = -EAGAIN;
 191                goto exit_unlock;
 192        }
 193
 194        ret = kstrtobool(buf, &val);
 195        if (ret)
 196                goto exit_unlock;
 197
 198        /* Always clear status */
 199        rt->auth_status = 0;
 200
 201        if (val) {
 202                if (!rt->nvm->buf) {
 203                        ret = -EINVAL;
 204                        goto exit_unlock;
 205                }
 206
 207                ret = tb_retimer_nvm_validate_and_write(rt);
 208                if (ret)
 209                        goto exit_unlock;
 210
 211                ret = usb4_port_retimer_nvm_authenticate(rt->port, rt->index);
 212        }
 213
 214exit_unlock:
 215        mutex_unlock(&rt->tb->lock);
 216exit_rpm:
 217        pm_runtime_mark_last_busy(&rt->dev);
 218        pm_runtime_put_autosuspend(&rt->dev);
 219
 220        if (ret)
 221                return ret;
 222        return count;
 223}
 224static DEVICE_ATTR_RW(nvm_authenticate);
 225
 226static ssize_t nvm_version_show(struct device *dev,
 227                                struct device_attribute *attr, char *buf)
 228{
 229        struct tb_retimer *rt = tb_to_retimer(dev);
 230        int ret;
 231
 232        if (!mutex_trylock(&rt->tb->lock))
 233                return restart_syscall();
 234
 235        if (!rt->nvm)
 236                ret = -EAGAIN;
 237        else
 238                ret = sprintf(buf, "%x.%x\n", rt->nvm->major, rt->nvm->minor);
 239
 240        mutex_unlock(&rt->tb->lock);
 241        return ret;
 242}
 243static DEVICE_ATTR_RO(nvm_version);
 244
 245static ssize_t vendor_show(struct device *dev, struct device_attribute *attr,
 246                           char *buf)
 247{
 248        struct tb_retimer *rt = tb_to_retimer(dev);
 249
 250        return sprintf(buf, "%#x\n", rt->vendor);
 251}
 252static DEVICE_ATTR_RO(vendor);
 253
 254static struct attribute *retimer_attrs[] = {
 255        &dev_attr_device.attr,
 256        &dev_attr_nvm_authenticate.attr,
 257        &dev_attr_nvm_version.attr,
 258        &dev_attr_vendor.attr,
 259        NULL
 260};
 261
 262static const struct attribute_group retimer_group = {
 263        .attrs = retimer_attrs,
 264};
 265
 266static const struct attribute_group *retimer_groups[] = {
 267        &retimer_group,
 268        NULL
 269};
 270
 271static void tb_retimer_release(struct device *dev)
 272{
 273        struct tb_retimer *rt = tb_to_retimer(dev);
 274
 275        kfree(rt);
 276}
 277
 278struct device_type tb_retimer_type = {
 279        .name = "thunderbolt_retimer",
 280        .groups = retimer_groups,
 281        .release = tb_retimer_release,
 282};
 283
 284static int tb_retimer_add(struct tb_port *port, u8 index, u32 auth_status)
 285{
 286        struct tb_retimer *rt;
 287        u32 vendor, device;
 288        int ret;
 289
 290        if (!port->cap_usb4)
 291                return -EINVAL;
 292
 293        ret = usb4_port_retimer_read(port, index, USB4_SB_VENDOR_ID, &vendor,
 294                                     sizeof(vendor));
 295        if (ret) {
 296                if (ret != -ENODEV)
 297                        tb_port_warn(port, "failed read retimer VendorId: %d\n", ret);
 298                return ret;
 299        }
 300
 301        ret = usb4_port_retimer_read(port, index, USB4_SB_PRODUCT_ID, &device,
 302                                     sizeof(device));
 303        if (ret) {
 304                if (ret != -ENODEV)
 305                        tb_port_warn(port, "failed read retimer ProductId: %d\n", ret);
 306                return ret;
 307        }
 308
 309        if (vendor != PCI_VENDOR_ID_INTEL && vendor != 0x8087) {
 310                tb_port_info(port, "retimer NVM format of vendor %#x is not supported\n",
 311                             vendor);
 312                return -EOPNOTSUPP;
 313        }
 314
 315        /*
 316         * Check that it supports NVM operations. If not then don't add
 317         * the device at all.
 318         */
 319        ret = usb4_port_retimer_nvm_sector_size(port, index);
 320        if (ret < 0)
 321                return ret;
 322
 323        rt = kzalloc(sizeof(*rt), GFP_KERNEL);
 324        if (!rt)
 325                return -ENOMEM;
 326
 327        rt->index = index;
 328        rt->vendor = vendor;
 329        rt->device = device;
 330        rt->auth_status = auth_status;
 331        rt->port = port;
 332        rt->tb = port->sw->tb;
 333
 334        rt->dev.parent = &port->sw->dev;
 335        rt->dev.bus = &tb_bus_type;
 336        rt->dev.type = &tb_retimer_type;
 337        dev_set_name(&rt->dev, "%s:%u.%u", dev_name(&port->sw->dev),
 338                     port->port, index);
 339
 340        ret = device_register(&rt->dev);
 341        if (ret) {
 342                dev_err(&rt->dev, "failed to register retimer: %d\n", ret);
 343                put_device(&rt->dev);
 344                return ret;
 345        }
 346
 347        ret = tb_retimer_nvm_add(rt);
 348        if (ret) {
 349                dev_err(&rt->dev, "failed to add NVM devices: %d\n", ret);
 350                device_unregister(&rt->dev);
 351                return ret;
 352        }
 353
 354        dev_info(&rt->dev, "new retimer found, vendor=%#x device=%#x\n",
 355                 rt->vendor, rt->device);
 356
 357        pm_runtime_no_callbacks(&rt->dev);
 358        pm_runtime_set_active(&rt->dev);
 359        pm_runtime_enable(&rt->dev);
 360        pm_runtime_set_autosuspend_delay(&rt->dev, TB_AUTOSUSPEND_DELAY);
 361        pm_runtime_mark_last_busy(&rt->dev);
 362        pm_runtime_use_autosuspend(&rt->dev);
 363
 364        return 0;
 365}
 366
 367static void tb_retimer_remove(struct tb_retimer *rt)
 368{
 369        dev_info(&rt->dev, "retimer disconnected\n");
 370        tb_nvm_free(rt->nvm);
 371        device_unregister(&rt->dev);
 372}
 373
 374struct tb_retimer_lookup {
 375        const struct tb_port *port;
 376        u8 index;
 377};
 378
 379static int retimer_match(struct device *dev, void *data)
 380{
 381        const struct tb_retimer_lookup *lookup = data;
 382        struct tb_retimer *rt = tb_to_retimer(dev);
 383
 384        return rt && rt->port == lookup->port && rt->index == lookup->index;
 385}
 386
 387static struct tb_retimer *tb_port_find_retimer(struct tb_port *port, u8 index)
 388{
 389        struct tb_retimer_lookup lookup = { .port = port, .index = index };
 390        struct device *dev;
 391
 392        dev = device_find_child(&port->sw->dev, &lookup, retimer_match);
 393        if (dev)
 394                return tb_to_retimer(dev);
 395
 396        return NULL;
 397}
 398
 399/**
 400 * tb_retimer_scan() - Scan for on-board retimers under port
 401 * @port: USB4 port to scan
 402 *
 403 * Tries to enumerate on-board retimers connected to @port. Found
 404 * retimers are registered as children of @port. Does not scan for cable
 405 * retimers for now.
 406 */
 407int tb_retimer_scan(struct tb_port *port)
 408{
 409        u32 status[TB_MAX_RETIMER_INDEX + 1] = {};
 410        int ret, i, last_idx = 0;
 411
 412        if (!port->cap_usb4)
 413                return 0;
 414
 415        /*
 416         * Send broadcast RT to make sure retimer indices facing this
 417         * port are set.
 418         */
 419        ret = usb4_port_enumerate_retimers(port);
 420        if (ret)
 421                return ret;
 422
 423        /*
 424         * Before doing anything else, read the authentication status.
 425         * If the retimer has it set, store it for the new retimer
 426         * device instance.
 427         */
 428        for (i = 1; i <= TB_MAX_RETIMER_INDEX; i++)
 429                usb4_port_retimer_nvm_authenticate_status(port, i, &status[i]);
 430
 431        for (i = 1; i <= TB_MAX_RETIMER_INDEX; i++) {
 432                /*
 433                 * Last retimer is true only for the last on-board
 434                 * retimer (the one connected directly to the Type-C
 435                 * port).
 436                 */
 437                ret = usb4_port_retimer_is_last(port, i);
 438                if (ret > 0)
 439                        last_idx = i;
 440                else if (ret < 0)
 441                        break;
 442        }
 443
 444        if (!last_idx)
 445                return 0;
 446
 447        /* Add on-board retimers if they do not exist already */
 448        for (i = 1; i <= last_idx; i++) {
 449                struct tb_retimer *rt;
 450
 451                rt = tb_port_find_retimer(port, i);
 452                if (rt) {
 453                        put_device(&rt->dev);
 454                } else {
 455                        ret = tb_retimer_add(port, i, status[i]);
 456                        if (ret && ret != -EOPNOTSUPP)
 457                                return ret;
 458                }
 459        }
 460
 461        return 0;
 462}
 463
 464static int remove_retimer(struct device *dev, void *data)
 465{
 466        struct tb_retimer *rt = tb_to_retimer(dev);
 467        struct tb_port *port = data;
 468
 469        if (rt && rt->port == port)
 470                tb_retimer_remove(rt);
 471        return 0;
 472}
 473
 474/**
 475 * tb_retimer_remove_all() - Remove all retimers under port
 476 * @port: USB4 port whose retimers to remove
 477 *
 478 * This removes all previously added retimers under @port.
 479 */
 480void tb_retimer_remove_all(struct tb_port *port)
 481{
 482        if (port->cap_usb4)
 483                device_for_each_child_reverse(&port->sw->dev, port,
 484                                              remove_retimer);
 485}
 486