#include <linux/device.h>
#include <linux/delay.h>
#include <linux/kmod.h>
#include <linux/module.h>
#include <linux/pm_runtime.h>
#include <linux/prandom.h>
#include <linux/string_helpers.h>
#include <linux/utsname.h>
#include <linux/uuid.h>
#include <linux/workqueue.h>
#include "tb.h"
#define XDOMAIN_SHORT_TIMEOUT …
#define XDOMAIN_DEFAULT_TIMEOUT …
#define XDOMAIN_BONDING_TIMEOUT …
#define XDOMAIN_RETRIES …
#define XDOMAIN_DEFAULT_MAX_HOPID …
enum { … };
static const char * const state_names[] = …;
struct xdomain_request_work { … };
static bool tb_xdomain_enabled = …;
module_param_named(xdomain, tb_xdomain_enabled, bool, 0444);
MODULE_PARM_DESC(…) …;
static DEFINE_MUTEX(xdomain_lock);
static struct tb_property_dir *xdomain_property_dir;
static u32 xdomain_property_block_gen;
static LIST_HEAD(protocol_handlers);
static const uuid_t tb_xdp_uuid = …;
bool tb_is_xdomain_enabled(void)
{ … }
static bool tb_xdomain_match(const struct tb_cfg_request *req,
const struct ctl_pkg *pkg)
{ … }
static bool tb_xdomain_copy(struct tb_cfg_request *req,
const struct ctl_pkg *pkg)
{ … }
static void response_ready(void *data)
{ … }
static int __tb_xdomain_response(struct tb_ctl *ctl, const void *response,
size_t size, enum tb_cfg_pkg_type type)
{ … }
int tb_xdomain_response(struct tb_xdomain *xd, const void *response,
size_t size, enum tb_cfg_pkg_type type)
{ … }
EXPORT_SYMBOL_GPL(…);
static int __tb_xdomain_request(struct tb_ctl *ctl, const void *request,
size_t request_size, enum tb_cfg_pkg_type request_type, void *response,
size_t response_size, enum tb_cfg_pkg_type response_type,
unsigned int timeout_msec)
{ … }
int tb_xdomain_request(struct tb_xdomain *xd, const void *request,
size_t request_size, enum tb_cfg_pkg_type request_type,
void *response, size_t response_size,
enum tb_cfg_pkg_type response_type, unsigned int timeout_msec)
{ … }
EXPORT_SYMBOL_GPL(…);
static inline void tb_xdp_fill_header(struct tb_xdp_header *hdr, u64 route,
u8 sequence, enum tb_xdp_type type, size_t size)
{ … }
static int tb_xdp_handle_error(const struct tb_xdp_error_response *res)
{ … }
static int tb_xdp_uuid_request(struct tb_ctl *ctl, u64 route, int retry,
uuid_t *uuid, u64 *remote_route)
{ … }
static int tb_xdp_uuid_response(struct tb_ctl *ctl, u64 route, u8 sequence,
const uuid_t *uuid)
{ … }
static int tb_xdp_error_response(struct tb_ctl *ctl, u64 route, u8 sequence,
enum tb_xdp_error error)
{ … }
static int tb_xdp_properties_request(struct tb_ctl *ctl, u64 route,
const uuid_t *src_uuid, const uuid_t *dst_uuid, int retry,
u32 **block, u32 *generation)
{ … }
static int tb_xdp_properties_response(struct tb *tb, struct tb_ctl *ctl,
struct tb_xdomain *xd, u8 sequence, const struct tb_xdp_properties *req)
{ … }
static int tb_xdp_properties_changed_request(struct tb_ctl *ctl, u64 route,
int retry, const uuid_t *uuid)
{ … }
static int
tb_xdp_properties_changed_response(struct tb_ctl *ctl, u64 route, u8 sequence)
{ … }
static int tb_xdp_link_state_status_request(struct tb_ctl *ctl, u64 route,
u8 sequence, u8 *slw, u8 *tlw,
u8 *sls, u8 *tls)
{ … }
static int tb_xdp_link_state_status_response(struct tb *tb, struct tb_ctl *ctl,
struct tb_xdomain *xd, u8 sequence)
{ … }
static int tb_xdp_link_state_change_request(struct tb_ctl *ctl, u64 route,
u8 sequence, u8 tlw, u8 tls)
{ … }
static int tb_xdp_link_state_change_response(struct tb_ctl *ctl, u64 route,
u8 sequence, u32 status)
{ … }
int tb_register_protocol_handler(struct tb_protocol_handler *handler)
{ … }
EXPORT_SYMBOL_GPL(…);
void tb_unregister_protocol_handler(struct tb_protocol_handler *handler)
{ … }
EXPORT_SYMBOL_GPL(…);
static void update_property_block(struct tb_xdomain *xd)
{ … }
static void start_handshake(struct tb_xdomain *xd)
{ … }
static void __stop_handshake(struct tb_xdomain *xd)
{ … }
static void stop_handshake(struct tb_xdomain *xd)
{ … }
static void tb_xdp_handle_request(struct work_struct *work)
{ … }
static bool
tb_xdp_schedule_request(struct tb *tb, const struct tb_xdp_header *hdr,
size_t size)
{ … }
int tb_register_service_driver(struct tb_service_driver *drv)
{ … }
EXPORT_SYMBOL_GPL(…);
void tb_unregister_service_driver(struct tb_service_driver *drv)
{ … }
EXPORT_SYMBOL_GPL(…);
static ssize_t key_show(struct device *dev, struct device_attribute *attr,
char *buf)
{ … }
static DEVICE_ATTR_RO(key);
static int get_modalias(const struct tb_service *svc, char *buf, size_t size)
{ … }
static ssize_t modalias_show(struct device *dev, struct device_attribute *attr,
char *buf)
{ … }
static DEVICE_ATTR_RO(modalias);
static ssize_t prtcid_show(struct device *dev, struct device_attribute *attr,
char *buf)
{ … }
static DEVICE_ATTR_RO(prtcid);
static ssize_t prtcvers_show(struct device *dev, struct device_attribute *attr,
char *buf)
{ … }
static DEVICE_ATTR_RO(prtcvers);
static ssize_t prtcrevs_show(struct device *dev, struct device_attribute *attr,
char *buf)
{ … }
static DEVICE_ATTR_RO(prtcrevs);
static ssize_t prtcstns_show(struct device *dev, struct device_attribute *attr,
char *buf)
{ … }
static DEVICE_ATTR_RO(prtcstns);
static struct attribute *tb_service_attrs[] = …;
static const struct attribute_group tb_service_attr_group = …;
static const struct attribute_group *tb_service_attr_groups[] = …;
static int tb_service_uevent(const struct device *dev, struct kobj_uevent_env *env)
{ … }
static void tb_service_release(struct device *dev)
{ … }
const struct device_type tb_service_type = …;
EXPORT_SYMBOL_GPL(…);
static int remove_missing_service(struct device *dev, void *data)
{ … }
static int find_service(struct device *dev, void *data)
{ … }
static int populate_service(struct tb_service *svc,
struct tb_property *property)
{ … }
static void enumerate_services(struct tb_xdomain *xd)
{ … }
static int populate_properties(struct tb_xdomain *xd,
struct tb_property_dir *dir)
{ … }
static int tb_xdomain_update_link_attributes(struct tb_xdomain *xd)
{ … }
static int tb_xdomain_get_uuid(struct tb_xdomain *xd)
{ … }
static int tb_xdomain_get_link_status(struct tb_xdomain *xd)
{ … }
static int tb_xdomain_link_state_change(struct tb_xdomain *xd,
unsigned int width)
{ … }
static int tb_xdomain_bond_lanes_uuid_high(struct tb_xdomain *xd)
{ … }
static int tb_xdomain_get_properties(struct tb_xdomain *xd)
{ … }
static void tb_xdomain_queue_uuid(struct tb_xdomain *xd)
{ … }
static void tb_xdomain_queue_link_status(struct tb_xdomain *xd)
{ … }
static void tb_xdomain_queue_link_status2(struct tb_xdomain *xd)
{ … }
static void tb_xdomain_queue_bonding(struct tb_xdomain *xd)
{ … }
static void tb_xdomain_queue_bonding_uuid_low(struct tb_xdomain *xd)
{ … }
static void tb_xdomain_queue_properties(struct tb_xdomain *xd)
{ … }
static void tb_xdomain_queue_properties_changed(struct tb_xdomain *xd)
{ … }
static void tb_xdomain_failed(struct tb_xdomain *xd)
{ … }
static void tb_xdomain_state_work(struct work_struct *work)
{ … }
static void tb_xdomain_properties_changed(struct work_struct *work)
{ … }
static ssize_t device_show(struct device *dev, struct device_attribute *attr,
char *buf)
{ … }
static DEVICE_ATTR_RO(device);
static ssize_t
device_name_show(struct device *dev, struct device_attribute *attr, char *buf)
{ … }
static DEVICE_ATTR_RO(device_name);
static ssize_t maxhopid_show(struct device *dev, struct device_attribute *attr,
char *buf)
{ … }
static DEVICE_ATTR_RO(maxhopid);
static ssize_t vendor_show(struct device *dev, struct device_attribute *attr,
char *buf)
{ … }
static DEVICE_ATTR_RO(vendor);
static ssize_t
vendor_name_show(struct device *dev, struct device_attribute *attr, char *buf)
{ … }
static DEVICE_ATTR_RO(vendor_name);
static ssize_t unique_id_show(struct device *dev, struct device_attribute *attr,
char *buf)
{ … }
static DEVICE_ATTR_RO(unique_id);
static ssize_t speed_show(struct device *dev, struct device_attribute *attr,
char *buf)
{ … }
static DEVICE_ATTR(rx_speed, 0444, speed_show, NULL);
static DEVICE_ATTR(tx_speed, 0444, speed_show, NULL);
static ssize_t rx_lanes_show(struct device *dev, struct device_attribute *attr,
char *buf)
{ … }
static DEVICE_ATTR(rx_lanes, 0444, rx_lanes_show, NULL);
static ssize_t tx_lanes_show(struct device *dev, struct device_attribute *attr,
char *buf)
{ … }
static DEVICE_ATTR(tx_lanes, 0444, tx_lanes_show, NULL);
static struct attribute *xdomain_attrs[] = …;
static const struct attribute_group xdomain_attr_group = …;
static const struct attribute_group *xdomain_attr_groups[] = …;
static void tb_xdomain_release(struct device *dev)
{ … }
static int __maybe_unused tb_xdomain_suspend(struct device *dev)
{ … }
static int __maybe_unused tb_xdomain_resume(struct device *dev)
{ … }
static const struct dev_pm_ops tb_xdomain_pm_ops = …;
const struct device_type tb_xdomain_type = …;
EXPORT_SYMBOL_GPL(…);
static void tb_xdomain_link_init(struct tb_xdomain *xd, struct tb_port *down)
{ … }
static void tb_xdomain_link_exit(struct tb_xdomain *xd)
{ … }
struct tb_xdomain *tb_xdomain_alloc(struct tb *tb, struct device *parent,
u64 route, const uuid_t *local_uuid,
const uuid_t *remote_uuid)
{ … }
void tb_xdomain_add(struct tb_xdomain *xd)
{ … }
static int unregister_service(struct device *dev, void *data)
{ … }
void tb_xdomain_remove(struct tb_xdomain *xd)
{ … }
int tb_xdomain_lane_bonding_enable(struct tb_xdomain *xd)
{ … }
EXPORT_SYMBOL_GPL(…);
void tb_xdomain_lane_bonding_disable(struct tb_xdomain *xd)
{ … }
EXPORT_SYMBOL_GPL(…);
int tb_xdomain_alloc_in_hopid(struct tb_xdomain *xd, int hopid)
{ … }
EXPORT_SYMBOL_GPL(…);
int tb_xdomain_alloc_out_hopid(struct tb_xdomain *xd, int hopid)
{ … }
EXPORT_SYMBOL_GPL(…);
void tb_xdomain_release_in_hopid(struct tb_xdomain *xd, int hopid)
{ … }
EXPORT_SYMBOL_GPL(…);
void tb_xdomain_release_out_hopid(struct tb_xdomain *xd, int hopid)
{ … }
EXPORT_SYMBOL_GPL(…);
int tb_xdomain_enable_paths(struct tb_xdomain *xd, int transmit_path,
int transmit_ring, int receive_path,
int receive_ring)
{ … }
EXPORT_SYMBOL_GPL(…);
int tb_xdomain_disable_paths(struct tb_xdomain *xd, int transmit_path,
int transmit_ring, int receive_path,
int receive_ring)
{ … }
EXPORT_SYMBOL_GPL(…);
struct tb_xdomain_lookup { … };
static struct tb_xdomain *switch_find_xdomain(struct tb_switch *sw,
const struct tb_xdomain_lookup *lookup)
{ … }
struct tb_xdomain *tb_xdomain_find_by_uuid(struct tb *tb, const uuid_t *uuid)
{ … }
EXPORT_SYMBOL_GPL(…);
struct tb_xdomain *tb_xdomain_find_by_link_depth(struct tb *tb, u8 link,
u8 depth)
{ … }
struct tb_xdomain *tb_xdomain_find_by_route(struct tb *tb, u64 route)
{ … }
EXPORT_SYMBOL_GPL(…);
bool tb_xdomain_handle_request(struct tb *tb, enum tb_cfg_pkg_type type,
const void *buf, size_t size)
{ … }
static int update_xdomain(struct device *dev, void *data)
{ … }
static void update_all_xdomains(void)
{ … }
static bool remove_directory(const char *key, const struct tb_property_dir *dir)
{ … }
int tb_register_property_dir(const char *key, struct tb_property_dir *dir)
{ … }
EXPORT_SYMBOL_GPL(…);
void tb_unregister_property_dir(const char *key, struct tb_property_dir *dir)
{ … }
EXPORT_SYMBOL_GPL(…);
int tb_xdomain_init(void)
{ … }
void tb_xdomain_exit(void)
{ … }