linux/drivers/thunderbolt/tb_regs.h
<<
>>
Prefs
   1/*
   2 * Thunderbolt Cactus Ridge driver - Port/Switch config area registers
   3 *
   4 * Every thunderbolt device consists (logically) of a switch with multiple
   5 * ports. Every port contains up to four config regions (HOPS, PORT, SWITCH,
   6 * COUNTERS) which are used to configure the device.
   7 *
   8 * Copyright (c) 2014 Andreas Noever <andreas.noever@gmail.com>
   9 */
  10
  11#ifndef _TB_REGS
  12#define _TB_REGS
  13
  14#include <linux/types.h>
  15
  16
  17#define TB_ROUTE_SHIFT 8  /* number of bits in a port entry of a route */
  18
  19
  20/*
  21 * TODO: should be 63? But we do not know how to receive frames larger than 256
  22 * bytes at the frame level. (header + checksum = 16, 60*4 = 240)
  23 */
  24#define TB_MAX_CONFIG_RW_LENGTH 60
  25
  26enum tb_cap {
  27        TB_CAP_PHY              = 0x0001,
  28        TB_CAP_TIME1            = 0x0003,
  29        TB_CAP_PCIE             = 0x0004,
  30        TB_CAP_I2C              = 0x0005,
  31        TB_CAP_PLUG_EVENTS      = 0x0105, /* also EEPROM */
  32        TB_CAP_TIME2            = 0x0305,
  33        TB_CAL_IECS             = 0x0405,
  34        TB_CAP_LINK_CONTROLLER  = 0x0605, /* also IECS */
  35};
  36
  37enum tb_port_state {
  38        TB_PORT_DISABLED        = 0, /* tb_cap_phy.disable == 1 */
  39        TB_PORT_CONNECTING      = 1, /* retry */
  40        TB_PORT_UP              = 2,
  41        TB_PORT_UNPLUGGED       = 7,
  42};
  43
  44/* capability headers */
  45
  46struct tb_cap_basic {
  47        u8 next;
  48        /* enum tb_cap cap:8; prevent "narrower than values of its type" */
  49        u8 cap; /* if cap == 0x05 then we have a extended capability */
  50} __packed;
  51
  52struct tb_cap_extended_short {
  53        u8 next; /* if next and length are zero then we have a long cap */
  54        enum tb_cap cap:16;
  55        u8 length;
  56} __packed;
  57
  58struct tb_cap_extended_long {
  59        u8 zero1;
  60        enum tb_cap cap:16;
  61        u8 zero2;
  62        u16 next;
  63        u16 length;
  64} __packed;
  65
  66/* capabilities */
  67
  68struct tb_cap_link_controller {
  69        struct tb_cap_extended_long cap_header;
  70        u32 count:4; /* number of link controllers */
  71        u32 unknown1:4;
  72        u32 base_offset:8; /*
  73                            * offset (into this capability) of the configuration
  74                            * area of the first link controller
  75                            */
  76        u32 length:12; /* link controller configuration area length */
  77        u32 unknown2:4; /* TODO check that length is correct */
  78} __packed;
  79
  80struct tb_cap_phy {
  81        struct tb_cap_basic cap_header;
  82        u32 unknown1:16;
  83        u32 unknown2:14;
  84        bool disable:1;
  85        u32 unknown3:11;
  86        enum tb_port_state state:4;
  87        u32 unknown4:2;
  88} __packed;
  89
  90struct tb_eeprom_ctl {
  91        bool clock:1; /* send pulse to transfer one bit */
  92        bool access_low:1; /* set to 0 before access */
  93        bool data_out:1; /* to eeprom */
  94        bool data_in:1; /* from eeprom */
  95        bool access_high:1; /* set to 1 before access */
  96        bool not_present:1; /* should be 0 */
  97        bool unknown1:1;
  98        bool present:1; /* should be 1 */
  99        u32 unknown2:24;
 100} __packed;
 101
 102struct tb_cap_plug_events {
 103        struct tb_cap_extended_short cap_header;
 104        u32 __unknown1:2;
 105        u32 plug_events:5;
 106        u32 __unknown2:25;
 107        u32 __unknown3;
 108        u32 __unknown4;
 109        struct tb_eeprom_ctl eeprom_ctl;
 110        u32 __unknown5[7];
 111        u32 drom_offset; /* 32 bit register, but eeprom addresses are 16 bit */
 112} __packed;
 113
 114/* device headers */
 115
 116/* Present on port 0 in TB_CFG_SWITCH at address zero. */
 117struct tb_regs_switch_header {
 118        /* DWORD 0 */
 119        u16 vendor_id;
 120        u16 device_id;
 121        /* DWORD 1 */
 122        u32 first_cap_offset:8;
 123        u32 upstream_port_number:6;
 124        u32 max_port_number:6;
 125        u32 depth:3;
 126        u32 __unknown1:1;
 127        u32 revision:8;
 128        /* DWORD 2 */
 129        u32 route_lo;
 130        /* DWORD 3 */
 131        u32 route_hi:31;
 132        bool enabled:1;
 133        /* DWORD 4 */
 134        u32 plug_events_delay:8; /*
 135                                  * RW, pause between plug events in
 136                                  * milliseconds. Writing 0x00 is interpreted
 137                                  * as 255ms.
 138                                  */
 139        u32 __unknown4:16;
 140        u32 thunderbolt_version:8;
 141} __packed;
 142
 143enum tb_port_type {
 144        TB_TYPE_INACTIVE        = 0x000000,
 145        TB_TYPE_PORT            = 0x000001,
 146        TB_TYPE_NHI             = 0x000002,
 147        /* TB_TYPE_ETHERNET     = 0x020000, lower order bits are not known */
 148        /* TB_TYPE_SATA         = 0x080000, lower order bits are not known */
 149        TB_TYPE_DP_HDMI_IN      = 0x0e0101,
 150        TB_TYPE_DP_HDMI_OUT     = 0x0e0102,
 151        TB_TYPE_PCIE_DOWN       = 0x100101,
 152        TB_TYPE_PCIE_UP         = 0x100102,
 153        /* TB_TYPE_USB          = 0x200000, lower order bits are not known */
 154};
 155
 156/* Present on every port in TB_CF_PORT at address zero. */
 157struct tb_regs_port_header {
 158        /* DWORD 0 */
 159        u16 vendor_id;
 160        u16 device_id;
 161        /* DWORD 1 */
 162        u32 first_cap_offset:8;
 163        u32 max_counters:11;
 164        u32 __unknown1:5;
 165        u32 revision:8;
 166        /* DWORD 2 */
 167        enum tb_port_type type:24;
 168        u32 thunderbolt_version:8;
 169        /* DWORD 3 */
 170        u32 __unknown2:20;
 171        u32 port_number:6;
 172        u32 __unknown3:6;
 173        /* DWORD 4 */
 174        u32 nfc_credits;
 175        /* DWORD 5 */
 176        u32 max_in_hop_id:11;
 177        u32 max_out_hop_id:11;
 178        u32 __unkown4:10;
 179        /* DWORD 6 */
 180        u32 __unknown5;
 181        /* DWORD 7 */
 182        u32 __unknown6;
 183
 184} __packed;
 185
 186/* Hop register from TB_CFG_HOPS. 8 byte per entry. */
 187struct tb_regs_hop {
 188        /* DWORD 0 */
 189        u32 next_hop:11; /*
 190                          * hop to take after sending the packet through
 191                          * out_port (on the incoming port of the next switch)
 192                          */
 193        u32 out_port:6; /* next port of the path (on the same switch) */
 194        u32 initial_credits:8;
 195        u32 unknown1:6; /* set to zero */
 196        bool enable:1;
 197
 198        /* DWORD 1 */
 199        u32 weight:4;
 200        u32 unknown2:4; /* set to zero */
 201        u32 priority:3;
 202        bool drop_packages:1;
 203        u32 counter:11; /* index into TB_CFG_COUNTERS on this port */
 204        bool counter_enable:1;
 205        bool ingress_fc:1;
 206        bool egress_fc:1;
 207        bool ingress_shared_buffer:1;
 208        bool egress_shared_buffer:1;
 209        u32 unknown3:4; /* set to zero */
 210} __packed;
 211
 212
 213#endif
 214