1 /* SPDX-License-Identifier: GPL-2.0 */ 2 /* 3 * Thunderbolt driver - control channel and configuration commands 4 * 5 * Copyright (c) 2014 Andreas Noever <andreas.noever@gmail.com> 6 * Copyright (C) 2018, Intel Corporation 7 */ 8 9 #ifndef _TB_CFG 10 #define _TB_CFG 11 12 #include <linux/kref.h> 13 #include <linux/thunderbolt.h> 14 15 #include "nhi.h" 16 #include "tb_msgs.h" 17 18 /* control channel */ 19 struct tb_ctl; 20 21 typedef bool (*event_cb)(void *data, enum tb_cfg_pkg_type type, 22 const void *buf, size_t size); 23 24 struct tb_ctl *tb_ctl_alloc(struct tb_nhi *nhi, int timeout_msec, event_cb cb, 25 void *cb_data); 26 void tb_ctl_start(struct tb_ctl *ctl); 27 void tb_ctl_stop(struct tb_ctl *ctl); 28 void tb_ctl_free(struct tb_ctl *ctl); 29 30 /* configuration commands */ 31 32 struct tb_cfg_result { 33 u64 response_route; 34 u32 response_port; /* 35 * If err = 1 then this is the port that send the 36 * error. 37 * If err = 0 and if this was a cfg_read/write then 38 * this is the upstream port of the responding 39 * switch. 40 * Otherwise the field is set to zero. 41 */ 42 int err; /* negative errors, 0 for success, 1 for tb errors */ 43 enum tb_cfg_error tb_error; /* valid if err == 1 */ 44 }; 45 46 struct ctl_pkg { 47 struct tb_ctl *ctl; 48 void *buffer; 49 struct ring_frame frame; 50 }; 51 52 /** 53 * struct tb_cfg_request - Control channel request 54 * @kref: Reference count 55 * @ctl: Pointer to the control channel structure. Only set when the 56 * request is queued. 57 * @request_size: Size of the request packet (in bytes) 58 * @request_type: Type of the request packet 59 * @response: Response is stored here 60 * @response_size: Maximum size of one response packet 61 * @response_type: Expected type of the response packet 62 * @npackets: Number of packets expected to be returned with this request 63 * @match: Function used to match the incoming packet 64 * @copy: Function used to copy the incoming packet to @response 65 * @callback: Callback called when the request is finished successfully 66 * @callback_data: Data to be passed to @callback 67 * @flags: Flags for the request 68 * @work: Work item used to complete the request 69 * @result: Result after the request has been completed 70 * @list: Requests are queued using this field 71 * 72 * An arbitrary request over Thunderbolt control channel. For standard 73 * control channel message, one should use tb_cfg_read/write() and 74 * friends if possible. 75 */ 76 struct tb_cfg_request { 77 struct kref kref; 78 struct tb_ctl *ctl; 79 const void *request; 80 size_t request_size; 81 enum tb_cfg_pkg_type request_type; 82 void *response; 83 size_t response_size; 84 enum tb_cfg_pkg_type response_type; 85 size_t npackets; 86 bool (*match)(const struct tb_cfg_request *req, 87 const struct ctl_pkg *pkg); 88 bool (*copy)(struct tb_cfg_request *req, const struct ctl_pkg *pkg); 89 void (*callback)(void *callback_data); 90 void *callback_data; 91 unsigned long flags; 92 struct work_struct work; 93 struct tb_cfg_result result; 94 struct list_head list; 95 }; 96 97 #define TB_CFG_REQUEST_ACTIVE 0 98 #define TB_CFG_REQUEST_CANCELED 1 99 100 struct tb_cfg_request *tb_cfg_request_alloc(void); 101 void tb_cfg_request_get(struct tb_cfg_request *req); 102 void tb_cfg_request_put(struct tb_cfg_request *req); 103 int tb_cfg_request(struct tb_ctl *ctl, struct tb_cfg_request *req, 104 void (*callback)(void *), void *callback_data); 105 void tb_cfg_request_cancel(struct tb_cfg_request *req, int err); 106 struct tb_cfg_result tb_cfg_request_sync(struct tb_ctl *ctl, 107 struct tb_cfg_request *req, int timeout_msec); 108 109 static inline u64 tb_cfg_get_route(const struct tb_cfg_header *header) 110 { 111 return (u64) header->route_hi << 32 | header->route_lo; 112 } 113 114 static inline struct tb_cfg_header tb_cfg_make_header(u64 route) 115 { 116 struct tb_cfg_header header = { 117 .route_hi = route >> 32, 118 .route_lo = route, 119 }; 120 /* check for overflow, route_hi is not 32 bits! */ 121 WARN_ON(tb_cfg_get_route(&header) != route); 122 return header; 123 } 124 125 int tb_cfg_ack_notification(struct tb_ctl *ctl, u64 route, 126 const struct cfg_error_pkg *error); 127 int tb_cfg_ack_plug(struct tb_ctl *ctl, u64 route, u32 port, bool unplug); 128 struct tb_cfg_result tb_cfg_reset(struct tb_ctl *ctl, u64 route); 129 struct tb_cfg_result tb_cfg_read_raw(struct tb_ctl *ctl, void *buffer, 130 u64 route, u32 port, 131 enum tb_cfg_space space, u32 offset, 132 u32 length, int timeout_msec); 133 struct tb_cfg_result tb_cfg_write_raw(struct tb_ctl *ctl, const void *buffer, 134 u64 route, u32 port, 135 enum tb_cfg_space space, u32 offset, 136 u32 length, int timeout_msec); 137 int tb_cfg_read(struct tb_ctl *ctl, void *buffer, u64 route, u32 port, 138 enum tb_cfg_space space, u32 offset, u32 length); 139 int tb_cfg_write(struct tb_ctl *ctl, const void *buffer, u64 route, u32 port, 140 enum tb_cfg_space space, u32 offset, u32 length); 141 int tb_cfg_get_upstream_port(struct tb_ctl *ctl, u64 route); 142 143 144 #endif 145