linux/drivers/thunderbolt/switch.c
<<
>>
Prefs
   1/*
   2 * Thunderbolt Cactus Ridge driver - switch/port utility functions
   3 *
   4 * Copyright (c) 2014 Andreas Noever <andreas.noever@gmail.com>
   5 */
   6
   7#include <linux/delay.h>
   8#include <linux/slab.h>
   9
  10#include "tb.h"
  11
  12/* port utility functions */
  13
  14static const char *tb_port_type(struct tb_regs_port_header *port)
  15{
  16        switch (port->type >> 16) {
  17        case 0:
  18                switch ((u8) port->type) {
  19                case 0:
  20                        return "Inactive";
  21                case 1:
  22                        return "Port";
  23                case 2:
  24                        return "NHI";
  25                default:
  26                        return "unknown";
  27                }
  28        case 0x2:
  29                return "Ethernet";
  30        case 0x8:
  31                return "SATA";
  32        case 0xe:
  33                return "DP/HDMI";
  34        case 0x10:
  35                return "PCIe";
  36        case 0x20:
  37                return "USB";
  38        default:
  39                return "unknown";
  40        }
  41}
  42
  43static void tb_dump_port(struct tb *tb, struct tb_regs_port_header *port)
  44{
  45        tb_info(tb,
  46                " Port %d: %x:%x (Revision: %d, TB Version: %d, Type: %s (%#x))\n",
  47                port->port_number, port->vendor_id, port->device_id,
  48                port->revision, port->thunderbolt_version, tb_port_type(port),
  49                port->type);
  50        tb_info(tb, "  Max hop id (in/out): %d/%d\n",
  51                port->max_in_hop_id, port->max_out_hop_id);
  52        tb_info(tb, "  Max counters: %d\n", port->max_counters);
  53        tb_info(tb, "  NFC Credits: %#x\n", port->nfc_credits);
  54}
  55
  56/**
  57 * tb_port_state() - get connectedness state of a port
  58 *
  59 * The port must have a TB_CAP_PHY (i.e. it should be a real port).
  60 *
  61 * Return: Returns an enum tb_port_state on success or an error code on failure.
  62 */
  63static int tb_port_state(struct tb_port *port)
  64{
  65        struct tb_cap_phy phy;
  66        int res;
  67        if (port->cap_phy == 0) {
  68                tb_port_WARN(port, "does not have a PHY\n");
  69                return -EINVAL;
  70        }
  71        res = tb_port_read(port, &phy, TB_CFG_PORT, port->cap_phy, 2);
  72        if (res)
  73                return res;
  74        return phy.state;
  75}
  76
  77/**
  78 * tb_wait_for_port() - wait for a port to become ready
  79 *
  80 * Wait up to 1 second for a port to reach state TB_PORT_UP. If
  81 * wait_if_unplugged is set then we also wait if the port is in state
  82 * TB_PORT_UNPLUGGED (it takes a while for the device to be registered after
  83 * switch resume). Otherwise we only wait if a device is registered but the link
  84 * has not yet been established.
  85 *
  86 * Return: Returns an error code on failure. Returns 0 if the port is not
  87 * connected or failed to reach state TB_PORT_UP within one second. Returns 1
  88 * if the port is connected and in state TB_PORT_UP.
  89 */
  90int tb_wait_for_port(struct tb_port *port, bool wait_if_unplugged)
  91{
  92        int retries = 10;
  93        int state;
  94        if (!port->cap_phy) {
  95                tb_port_WARN(port, "does not have PHY\n");
  96                return -EINVAL;
  97        }
  98        if (tb_is_upstream_port(port)) {
  99                tb_port_WARN(port, "is the upstream port\n");
 100                return -EINVAL;
 101        }
 102
 103        while (retries--) {
 104                state = tb_port_state(port);
 105                if (state < 0)
 106                        return state;
 107                if (state == TB_PORT_DISABLED) {
 108                        tb_port_info(port, "is disabled (state: 0)\n");
 109                        return 0;
 110                }
 111                if (state == TB_PORT_UNPLUGGED) {
 112                        if (wait_if_unplugged) {
 113                                /* used during resume */
 114                                tb_port_info(port,
 115                                             "is unplugged (state: 7), retrying...\n");
 116                                msleep(100);
 117                                continue;
 118                        }
 119                        tb_port_info(port, "is unplugged (state: 7)\n");
 120                        return 0;
 121                }
 122                if (state == TB_PORT_UP) {
 123                        tb_port_info(port,
 124                                     "is connected, link is up (state: 2)\n");
 125                        return 1;
 126                }
 127
 128                /*
 129                 * After plug-in the state is TB_PORT_CONNECTING. Give it some
 130                 * time.
 131                 */
 132                tb_port_info(port,
 133                             "is connected, link is not up (state: %d), retrying...\n",
 134                             state);
 135                msleep(100);
 136        }
 137        tb_port_warn(port,
 138                     "failed to reach state TB_PORT_UP. Ignoring port...\n");
 139        return 0;
 140}
 141
 142/**
 143 * tb_port_add_nfc_credits() - add/remove non flow controlled credits to port
 144 *
 145 * Change the number of NFC credits allocated to @port by @credits. To remove
 146 * NFC credits pass a negative amount of credits.
 147 *
 148 * Return: Returns 0 on success or an error code on failure.
 149 */
 150int tb_port_add_nfc_credits(struct tb_port *port, int credits)
 151{
 152        if (credits == 0)
 153                return 0;
 154        tb_port_info(port,
 155                     "adding %#x NFC credits (%#x -> %#x)",
 156                     credits,
 157                     port->config.nfc_credits,
 158                     port->config.nfc_credits + credits);
 159        port->config.nfc_credits += credits;
 160        return tb_port_write(port, &port->config.nfc_credits,
 161                             TB_CFG_PORT, 4, 1);
 162}
 163
 164/**
 165 * tb_port_clear_counter() - clear a counter in TB_CFG_COUNTER
 166 *
 167 * Return: Returns 0 on success or an error code on failure.
 168 */
 169int tb_port_clear_counter(struct tb_port *port, int counter)
 170{
 171        u32 zero[3] = { 0, 0, 0 };
 172        tb_port_info(port, "clearing counter %d\n", counter);
 173        return tb_port_write(port, zero, TB_CFG_COUNTERS, 3 * counter, 3);
 174}
 175
 176/**
 177 * tb_init_port() - initialize a port
 178 *
 179 * This is a helper method for tb_switch_alloc. Does not check or initialize
 180 * any downstream switches.
 181 *
 182 * Return: Returns 0 on success or an error code on failure.
 183 */
 184static int tb_init_port(struct tb_port *port)
 185{
 186        int res;
 187        int cap;
 188
 189        res = tb_port_read(port, &port->config, TB_CFG_PORT, 0, 8);
 190        if (res)
 191                return res;
 192
 193        /* Port 0 is the switch itself and has no PHY. */
 194        if (port->config.type == TB_TYPE_PORT && port->port != 0) {
 195                cap = tb_find_cap(port, TB_CFG_PORT, TB_CAP_PHY);
 196
 197                if (cap > 0)
 198                        port->cap_phy = cap;
 199                else
 200                        tb_port_WARN(port, "non switch port without a PHY\n");
 201        }
 202
 203        tb_dump_port(port->sw->tb, &port->config);
 204
 205        /* TODO: Read dual link port, DP port and more from EEPROM. */
 206        return 0;
 207
 208}
 209
 210/* switch utility functions */
 211
 212static void tb_dump_switch(struct tb *tb, struct tb_regs_switch_header *sw)
 213{
 214        tb_info(tb,
 215                " Switch: %x:%x (Revision: %d, TB Version: %d)\n",
 216                sw->vendor_id, sw->device_id, sw->revision,
 217                sw->thunderbolt_version);
 218        tb_info(tb, "  Max Port Number: %d\n", sw->max_port_number);
 219        tb_info(tb, "  Config:\n");
 220        tb_info(tb,
 221                "   Upstream Port Number: %d Depth: %d Route String: %#llx Enabled: %d, PlugEventsDelay: %dms\n",
 222                sw->upstream_port_number, sw->depth,
 223                (((u64) sw->route_hi) << 32) | sw->route_lo,
 224                sw->enabled, sw->plug_events_delay);
 225        tb_info(tb,
 226                "   unknown1: %#x unknown4: %#x\n",
 227                sw->__unknown1, sw->__unknown4);
 228}
 229
 230/**
 231 * reset_switch() - reconfigure route, enable and send TB_CFG_PKG_RESET
 232 *
 233 * Return: Returns 0 on success or an error code on failure.
 234 */
 235int tb_switch_reset(struct tb *tb, u64 route)
 236{
 237        struct tb_cfg_result res;
 238        struct tb_regs_switch_header header = {
 239                header.route_hi = route >> 32,
 240                header.route_lo = route,
 241                header.enabled = true,
 242        };
 243        tb_info(tb, "resetting switch at %llx\n", route);
 244        res.err = tb_cfg_write(tb->ctl, ((u32 *) &header) + 2, route,
 245                        0, 2, 2, 2);
 246        if (res.err)
 247                return res.err;
 248        res = tb_cfg_reset(tb->ctl, route, TB_CFG_DEFAULT_TIMEOUT);
 249        if (res.err > 0)
 250                return -EIO;
 251        return res.err;
 252}
 253
 254struct tb_switch *get_switch_at_route(struct tb_switch *sw, u64 route)
 255{
 256        u8 next_port = route; /*
 257                               * Routes use a stride of 8 bits,
 258                               * eventhough a port index has 6 bits at most.
 259                               * */
 260        if (route == 0)
 261                return sw;
 262        if (next_port > sw->config.max_port_number)
 263                return NULL;
 264        if (tb_is_upstream_port(&sw->ports[next_port]))
 265                return NULL;
 266        if (!sw->ports[next_port].remote)
 267                return NULL;
 268        return get_switch_at_route(sw->ports[next_port].remote->sw,
 269                                   route >> TB_ROUTE_SHIFT);
 270}
 271
 272/**
 273 * tb_plug_events_active() - enable/disable plug events on a switch
 274 *
 275 * Also configures a sane plug_events_delay of 255ms.
 276 *
 277 * Return: Returns 0 on success or an error code on failure.
 278 */
 279static int tb_plug_events_active(struct tb_switch *sw, bool active)
 280{
 281        u32 data;
 282        int res;
 283
 284        sw->config.plug_events_delay = 0xff;
 285        res = tb_sw_write(sw, ((u32 *) &sw->config) + 4, TB_CFG_SWITCH, 4, 1);
 286        if (res)
 287                return res;
 288
 289        res = tb_sw_read(sw, &data, TB_CFG_SWITCH, sw->cap_plug_events + 1, 1);
 290        if (res)
 291                return res;
 292
 293        if (active) {
 294                data = data & 0xFFFFFF83;
 295                switch (sw->config.device_id) {
 296                case 0x1513:
 297                case 0x151a:
 298                case 0x1549:
 299                        break;
 300                default:
 301                        data |= 4;
 302                }
 303        } else {
 304                data = data | 0x7c;
 305        }
 306        return tb_sw_write(sw, &data, TB_CFG_SWITCH,
 307                           sw->cap_plug_events + 1, 1);
 308}
 309
 310
 311/**
 312 * tb_switch_free() - free a tb_switch and all downstream switches
 313 */
 314void tb_switch_free(struct tb_switch *sw)
 315{
 316        int i;
 317        /* port 0 is the switch itself and never has a remote */
 318        for (i = 1; i <= sw->config.max_port_number; i++) {
 319                if (tb_is_upstream_port(&sw->ports[i]))
 320                        continue;
 321                if (sw->ports[i].remote)
 322                        tb_switch_free(sw->ports[i].remote->sw);
 323                sw->ports[i].remote = NULL;
 324        }
 325
 326        if (!sw->is_unplugged)
 327                tb_plug_events_active(sw, false);
 328
 329        kfree(sw->ports);
 330        kfree(sw->drom);
 331        kfree(sw);
 332}
 333
 334/**
 335 * tb_switch_alloc() - allocate and initialize a switch
 336 *
 337 * Return: Returns a NULL on failure.
 338 */
 339struct tb_switch *tb_switch_alloc(struct tb *tb, u64 route)
 340{
 341        int i;
 342        int cap;
 343        struct tb_switch *sw;
 344        int upstream_port = tb_cfg_get_upstream_port(tb->ctl, route);
 345        if (upstream_port < 0)
 346                return NULL;
 347
 348        sw = kzalloc(sizeof(*sw), GFP_KERNEL);
 349        if (!sw)
 350                return NULL;
 351
 352        sw->tb = tb;
 353        if (tb_cfg_read(tb->ctl, &sw->config, route, 0, 2, 0, 5))
 354                goto err;
 355        tb_info(tb,
 356                "initializing Switch at %#llx (depth: %d, up port: %d)\n",
 357                route, tb_route_length(route), upstream_port);
 358        tb_info(tb, "old switch config:\n");
 359        tb_dump_switch(tb, &sw->config);
 360
 361        /* configure switch */
 362        sw->config.upstream_port_number = upstream_port;
 363        sw->config.depth = tb_route_length(route);
 364        sw->config.route_lo = route;
 365        sw->config.route_hi = route >> 32;
 366        sw->config.enabled = 1;
 367        /* from here on we may use the tb_sw_* functions & macros */
 368
 369        if (sw->config.vendor_id != 0x8086)
 370                tb_sw_warn(sw, "unknown switch vendor id %#x\n",
 371                           sw->config.vendor_id);
 372
 373        if (sw->config.device_id != 0x1547 && sw->config.device_id != 0x1549)
 374                tb_sw_warn(sw, "unsupported switch device id %#x\n",
 375                           sw->config.device_id);
 376
 377        /* upload configuration */
 378        if (tb_sw_write(sw, 1 + (u32 *) &sw->config, TB_CFG_SWITCH, 1, 3))
 379                goto err;
 380
 381        /* initialize ports */
 382        sw->ports = kcalloc(sw->config.max_port_number + 1, sizeof(*sw->ports),
 383                                GFP_KERNEL);
 384        if (!sw->ports)
 385                goto err;
 386
 387        for (i = 0; i <= sw->config.max_port_number; i++) {
 388                /* minimum setup for tb_find_cap and tb_drom_read to work */
 389                sw->ports[i].sw = sw;
 390                sw->ports[i].port = i;
 391        }
 392
 393        cap = tb_find_cap(&sw->ports[0], TB_CFG_SWITCH, TB_CAP_PLUG_EVENTS);
 394        if (cap < 0) {
 395                tb_sw_warn(sw, "cannot find TB_CAP_PLUG_EVENTS aborting\n");
 396                goto err;
 397        }
 398        sw->cap_plug_events = cap;
 399
 400        /* read drom */
 401        if (tb_drom_read(sw))
 402                tb_sw_warn(sw, "tb_eeprom_read_rom failed, continuing\n");
 403        tb_sw_info(sw, "uid: %#llx\n", sw->uid);
 404
 405        for (i = 0; i <= sw->config.max_port_number; i++) {
 406                if (sw->ports[i].disabled) {
 407                        tb_port_info(&sw->ports[i], "disabled by eeprom\n");
 408                        continue;
 409                }
 410                if (tb_init_port(&sw->ports[i]))
 411                        goto err;
 412        }
 413
 414        /* TODO: I2C, IECS, link controller */
 415
 416        if (tb_plug_events_active(sw, true))
 417                goto err;
 418
 419        return sw;
 420err:
 421        kfree(sw->ports);
 422        kfree(sw->drom);
 423        kfree(sw);
 424        return NULL;
 425}
 426
 427/**
 428 * tb_sw_set_unpplugged() - set is_unplugged on switch and downstream switches
 429 */
 430void tb_sw_set_unpplugged(struct tb_switch *sw)
 431{
 432        int i;
 433        if (sw == sw->tb->root_switch) {
 434                tb_sw_WARN(sw, "cannot unplug root switch\n");
 435                return;
 436        }
 437        if (sw->is_unplugged) {
 438                tb_sw_WARN(sw, "is_unplugged already set\n");
 439                return;
 440        }
 441        sw->is_unplugged = true;
 442        for (i = 0; i <= sw->config.max_port_number; i++) {
 443                if (!tb_is_upstream_port(&sw->ports[i]) && sw->ports[i].remote)
 444                        tb_sw_set_unpplugged(sw->ports[i].remote->sw);
 445        }
 446}
 447
 448int tb_switch_resume(struct tb_switch *sw)
 449{
 450        int i, err;
 451        u64 uid;
 452        tb_sw_info(sw, "resuming switch\n");
 453
 454        err = tb_drom_read_uid_only(sw, &uid);
 455        if (err) {
 456                tb_sw_warn(sw, "uid read failed\n");
 457                return err;
 458        }
 459        if (sw->uid != uid) {
 460                tb_sw_info(sw,
 461                        "changed while suspended (uid %#llx -> %#llx)\n",
 462                        sw->uid, uid);
 463                return -ENODEV;
 464        }
 465
 466        /* upload configuration */
 467        err = tb_sw_write(sw, 1 + (u32 *) &sw->config, TB_CFG_SWITCH, 1, 3);
 468        if (err)
 469                return err;
 470
 471        err = tb_plug_events_active(sw, true);
 472        if (err)
 473                return err;
 474
 475        /* check for surviving downstream switches */
 476        for (i = 1; i <= sw->config.max_port_number; i++) {
 477                struct tb_port *port = &sw->ports[i];
 478                if (tb_is_upstream_port(port))
 479                        continue;
 480                if (!port->remote)
 481                        continue;
 482                if (tb_wait_for_port(port, true) <= 0
 483                        || tb_switch_resume(port->remote->sw)) {
 484                        tb_port_warn(port,
 485                                     "lost during suspend, disconnecting\n");
 486                        tb_sw_set_unpplugged(port->remote->sw);
 487                }
 488        }
 489        return 0;
 490}
 491
 492void tb_switch_suspend(struct tb_switch *sw)
 493{
 494        int i, err;
 495        err = tb_plug_events_active(sw, false);
 496        if (err)
 497                return;
 498
 499        for (i = 1; i <= sw->config.max_port_number; i++) {
 500                if (!tb_is_upstream_port(&sw->ports[i]) && sw->ports[i].remote)
 501                        tb_switch_suspend(sw->ports[i].remote->sw);
 502        }
 503        /*
 504         * TODO: invoke tb_cfg_prepare_to_sleep here? does not seem to have any
 505         * effect?
 506         */
 507}
 508