/* SPDX-License-Identifier: GPL-2.0 */
/*
* Thunderbolt driver - bus logic (NHI independent)
*
* Copyright (c) 2014 Andreas Noever <andreas.noever@gmail.com>
* Copyright (C) 2018, Intel Corporation
*/
#ifndef TB_H_
#define TB_H_
#include <linux/debugfs.h>
#include <linux/nvmem-provider.h>
#include <linux/pci.h>
#include <linux/thunderbolt.h>
#include <linux/uuid.h>
#include <linux/bitfield.h>
#include "tb_regs.h"
#include "ctl.h"
#include "dma_port.h"
/* Keep link controller awake during update */
#define QUIRK_FORCE_POWER_LINK_CONTROLLER BIT(0)
/* Disable CLx if not supported */
#define QUIRK_NO_CLX BIT(1)
/* Need to keep power on while USB4 port is in redrive mode */
#define QUIRK_KEEP_POWER_IN_DP_REDRIVE BIT(2)
/**
* struct tb_nvm - Structure holding NVM information
* @dev: Owner of the NVM
* @major: Major version number of the active NVM portion
* @minor: Minor version number of the active NVM portion
* @id: Identifier used with both NVM portions
* @active: Active portion NVMem device
* @active_size: Size in bytes of the active NVM
* @non_active: Non-active portion NVMem device
* @buf: Buffer where the NVM image is stored before it is written to
* the actual NVM flash device
* @buf_data_start: Where the actual image starts after skipping
* possible headers
* @buf_data_size: Number of bytes actually consumed by the new NVM
* image
* @authenticating: The device is authenticating the new NVM
* @flushed: The image has been flushed to the storage area
* @vops: Router vendor specific NVM operations (optional)
*
* The user of this structure needs to handle serialization of possible
* concurrent access.
*/
struct tb_nvm {
struct device *dev;
u32 major;
u32 minor;
int id;
struct nvmem_device *active;
size_t active_size;
struct nvmem_device *non_active;
void *buf;
void *buf_data_start;
size_t buf_data_size;
bool authenticating;
bool flushed;
const struct tb_nvm_vendor_ops *vops;
};
enum tb_nvm_write_ops {
WRITE_AND_AUTHENTICATE = 1,
WRITE_ONLY = 2,
AUTHENTICATE_ONLY = 3,
};
#define TB_SWITCH_KEY_SIZE 32
#define TB_SWITCH_MAX_DEPTH 6
#define USB4_SWITCH_MAX_DEPTH 5
/**
* enum tb_switch_tmu_mode - TMU mode
* @TB_SWITCH_TMU_MODE_OFF: TMU is off
* @TB_SWITCH_TMU_MODE_LOWRES: Uni-directional, normal mode
* @TB_SWITCH_TMU_MODE_HIFI_UNI: Uni-directional, HiFi mode
* @TB_SWITCH_TMU_MODE_HIFI_BI: Bi-directional, HiFi mode
* @TB_SWITCH_TMU_MODE_MEDRES_ENHANCED_UNI: Enhanced Uni-directional, MedRes mode
*
* Ordering is based on TMU accuracy level (highest last).
*/
enum tb_switch_tmu_mode {
TB_SWITCH_TMU_MODE_OFF,
TB_SWITCH_TMU_MODE_LOWRES,
TB_SWITCH_TMU_MODE_HIFI_UNI,
TB_SWITCH_TMU_MODE_HIFI_BI,
TB_SWITCH_TMU_MODE_MEDRES_ENHANCED_UNI,
};
/**
* struct tb_switch_tmu - Structure holding router TMU configuration
* @cap: Offset to the TMU capability (%0 if not found)
* @has_ucap: Does the switch support uni-directional mode
* @mode: TMU mode related to the upstream router. Reflects the HW
* setting. Don't care for host router.
* @mode_request: TMU mode requested to set. Related to upstream router.
* Don't care for host router.
*/
struct tb_switch_tmu {
int cap;
bool has_ucap;
enum tb_switch_tmu_mode mode;
enum tb_switch_tmu_mode mode_request;
};
/**
* struct tb_switch - a thunderbolt switch
* @dev: Device for the switch
* @config: Switch configuration
* @ports: Ports in this switch
* @dma_port: If the switch has port supporting DMA configuration based
* mailbox this will hold the pointer to that (%NULL
* otherwise). If set it also means the switch has
* upgradeable NVM.
* @tmu: The switch TMU configuration
* @tb: Pointer to the domain the switch belongs to
* @uid: Unique ID of the switch
* @uuid: UUID of the switch (or %NULL if not supported)
* @vendor: Vendor ID of the switch
* @device: Device ID of the switch
* @vendor_name: Name of the vendor (or %NULL if not known)
* @device_name: Name of the device (or %NULL if not known)
* @link_speed: Speed of the link in Gb/s
* @link_width: Width of the upstream facing link
* @preferred_link_width: Router preferred link width (only set for Gen 4 links)
* @link_usb4: Upstream link is USB4
* @generation: Switch Thunderbolt generation
* @cap_plug_events: Offset to the plug events capability (%0 if not found)
* @cap_vsec_tmu: Offset to the TMU vendor specific capability (%0 if not found)
* @cap_lc: Offset to the link controller capability (%0 if not found)
* @cap_lp: Offset to the low power (CLx for TBT) capability (%0 if not found)
* @is_unplugged: The switch is going away
* @drom: DROM of the switch (%NULL if not found)
* @nvm: Pointer to the NVM if the switch has one (%NULL otherwise)
* @no_nvm_upgrade: Prevent NVM upgrade of this switch
* @safe_mode: The switch is in safe-mode
* @boot: Whether the switch was already authorized on boot or not
* @rpm: The switch supports runtime PM
* @authorized: Whether the switch is authorized by user or policy
* @security_level: Switch supported security level
* @debugfs_dir: Pointer to the debugfs structure
* @key: Contains the key used to challenge the device or %NULL if not
* supported. Size of the key is %TB_SWITCH_KEY_SIZE.
* @connection_id: Connection ID used with ICM messaging
* @connection_key: Connection key used with ICM messaging
* @link: Root switch link this switch is connected (ICM only)
* @depth: Depth in the chain this switch is connected (ICM only)
* @rpm_complete: Completion used to wait for runtime resume to
* complete (ICM only)
* @quirks: Quirks used for this Thunderbolt switch
* @credit_allocation: Are the below buffer allocation parameters valid
* @max_usb3_credits: Router preferred number of buffers for USB 3.x
* @min_dp_aux_credits: Router preferred minimum number of buffers for DP AUX
* @min_dp_main_credits: Router preferred minimum number of buffers for DP MAIN
* @max_pcie_credits: Router preferred number of buffers for PCIe
* @max_dma_credits: Router preferred number of buffers for DMA/P2P
* @clx: CLx states on the upstream link of the router
* @drom_blob: DROM debugfs blob wrapper
*
* When the switch is being added or removed to the domain (other
* switches) you need to have domain lock held.
*
* In USB4 terminology this structure represents a router.
*/
struct tb_switch {
struct device dev;
struct tb_regs_switch_header config;
struct tb_port *ports;
struct tb_dma_port *dma_port;
struct tb_switch_tmu tmu;
struct tb *tb;
u64 uid;
uuid_t *uuid
|