summaryrefslogtreecommitdiff
path: root/zephyr/include/emul/tcpc/emul_tcpci_partner_common.h
blob: fb715a47dc560c6cd59640b328ad7c34a8c67bc2 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
/* Copyright 2021 The ChromiumOS Authors
 * Use of this source code is governed by a BSD-style license that can be
 * found in the LICENSE file.
 */

/**
 * @file
 *
 * @brief Common code used by TCPCI partner device emulators
 */

#ifndef __EMUL_TCPCI_PARTNER_COMMON_H
#define __EMUL_TCPCI_PARTNER_COMMON_H

#include <zephyr/drivers/emul.h>
#include <zephyr/kernel.h>
#include <zephyr/sys/atomic.h>
#include <stdbool.h>
#include <stdint.h>

#include "ec_commands.h"
#include "emul/tcpc/emul_tcpci.h"
#include "usb_pd.h"

/**
 * @brief Common code used by TCPCI partner device emulators
 * @defgroup tcpci_partner Common code for TCPCI partner device emulators
 * @{
 *
 * Common code for TCPCI partner device emulators allows to send SOP messages
 * in generic way using optional delay.
 */

/** Timeout for other side to respond to PD message */
#define TCPCI_PARTNER_RESPONSE_TIMEOUT_MS 30
#define TCPCI_PARTNER_RESPONSE_TIMEOUT K_MSEC(TCPCI_PARTNER_RESPONSE_TIMEOUT_MS)
/** Timeout for source to transition to requested state after accept */
#define TCPCI_PARTNER_TRANSITION_TIMEOUT_MS 550
#define TCPCI_PARTNER_TRANSITION_TIMEOUT \
	K_MSEC(TCPCI_PARTNER_TRANSITION_TIMEOUT_MS)
/** Timeout for source to send capability again after failure */
#define TCPCI_SOURCE_CAPABILITY_TIMEOUT_MS 150
#define TCPCI_SOURCE_CAPABILITY_TIMEOUT \
	K_MSEC(TCPCI_SOURCE_CAPABILITY_TIMEOUT_MS)
/** Timeout for source to send capability message after power swap */
#define TCPCI_SWAP_SOURCE_START_TIMEOUT_MS 20
#define TCPCI_SWAP_SOURCE_START_TIMEOUT \
	K_MSEC(TCPCI_SWAP_SOURCE_START_TIMEOUT_MS)

/** Common data for TCPCI partner device emulators */
struct tcpci_partner_data {
	/** List of extensions used in TCPCI partner emulator */
	struct tcpci_partner_extension *extensions;
	/** Operations used by TCPCI emulator */
	struct tcpci_emul_partner_ops ops;
	/** Timer used to send message with delay */
	struct k_timer delayed_send;
	/** Reserved for fifo, used for scheduling messages */
	void *fifo_data;
	/** Pointer to connected TCPCI emulator */
	const struct emul *tcpci_emul;
	/** Queue for delayed messages */
	sys_slist_t to_send;
	/** Mutex for to_send queue */
	struct k_mutex to_send_mutex;
	/** Next SOP message id */
	int sop_msg_id;
	/** Next SOP' message id */
	int sop_prime_msg_id;
	/** Last received message id */
	int sop_recv_msg_id;
	/** Last received SOP' message id */
	int sop_prime_recv_msg_id;
	/** Power role (used in message header) */
	enum pd_power_role power_role;
	/** Data role (used in message header) */
	enum pd_data_role data_role;
	/** VConn role (used in message header) */
	enum pd_vconn_role vconn_role;
	/** Revision (used in message header) */
	enum pd_rev_type rev;
	/** Resistor set at the CC1 line of partner emulator */
	enum tcpc_cc_voltage_status cc1;
	/** Resistor set at the CC2 line of partner emulator */
	enum tcpc_cc_voltage_status cc2;
	/**
	 * Polarity of the partner emulator. It controls to which CC line of
	 * TCPC emulator the partner emulator CC1 line should be connected.
	 */
	enum tcpc_cc_polarity polarity;
	/**
	 * Mask for control message types that shouldn't be handled
	 * in common message handler
	 */
	uint32_t common_handler_masked;
	/**
	 * True if accept and reject messages shouldn't trigger soft reset
	 * in common message handler
	 */
	bool wait_for_response;
	/**
	 * If emulator triggers soft reset, it waits for accept. If accept
	 * doesn't arrive, hard reset is triggered.
	 */
	bool in_soft_reset;
	/** Current AMS Control request being handled */
	enum pd_ctrl_msg_type cur_ams_ctrl_req;
	/**
	 * If common code should send GoodCRC for each message. If false,
	 * then one of extensions should call tcpci_emul_partner_msg_status().
	 * If message is handled by common code, than GoodCRC is send regardless
	 * of send_goodcrc value.
	 */
	bool send_goodcrc;
	/**
	 * Mutex for TCPCI transmit handler. Should be used to synchronise
	 * access to partner emulator with TCPCI emulator.
	 */
	struct k_mutex transmit_mutex;
	/** Delayed work which is executed when response timeout occurs */
	struct k_work_delayable sender_response_timeout;
	/** Number of TCPM timeouts. Test may chekck if timeout occurs */
	int tcpm_timeouts;
	/** List with logged PD messages */
	sys_slist_t msg_log;
	/** Flag which controls if messages should be logged */
	bool collect_msg_log;
	/** Mutex for msg_log */
	struct k_mutex msg_log_mutex;
	/**
	 * Pointer to last received message status. This pointer is set only
	 * when message logging is enabled. It used to track if partner set
	 * any status to received message.
	 */
	enum tcpci_emul_tx_status *received_msg_status;
	/** Whether port partner is configured in DisplayPort mode */
	bool displayport_configured;
	/** The number of Enter Mode REQs received since connection
	 *  or the last Hard Reset, whichever was more recent.
	 */
	atomic_t mode_enter_attempts;
	/* SVID of entered mode (0 if no mode is entered) */
	uint16_t entered_svid;

	/* VDMs with which the partner responds to discovery REQs. The VDM
	 * buffers include the VDM header, and the VDO counts include 1 for the
	 * VDM header. This structure has space for the mode response for a
	 * single supported SVID.
	 */
	uint32_t identity_vdm[VDO_MAX_SIZE];
	int identity_vdos;
	uint32_t svids_vdm[VDO_MAX_SIZE];
	int svids_vdos;
	uint32_t modes_vdm[VDO_MAX_SIZE];
	int modes_vdos;
	/* VDMs sent when responding to a mode entry command */
	uint32_t enter_mode_vdm[VDO_MAX_SIZE];
	int enter_mode_vdos;
	/* VDMs sent when responding to DisplayPort status update command */
	uint32_t dp_status_vdm[VDO_MAX_SIZE];
	int dp_status_vdos;
	/* VDMs sent when responding to DisplayPort config command */
	uint32_t dp_config_vdm[VDO_MAX_SIZE];
	int dp_config_vdos;
	struct {
		/* Index of the last battery we requested capabilities for. The
		 * BCDB response does not include the index so we need to track
		 * it manually. -1 indicates no outstanding request.
		 */
		int index;
		/* Stores Battery Capability Data Blocks (BCDBs) requested and
		 * received from the TCPM for later analysis. See USB-PD spec
		 * Rev 3.1, Ver 1.3 section 6.5.5
		 */
		struct pd_bcdb bcdb[PD_BATT_MAX];
		/* Stores a boolean status for each battery index indicating
		 * whether we have received a BCDB response for that battery.
		 */
		bool have_response[PD_BATT_MAX];
	} battery_capabilities;

	/*
	 * Cable which is "plugged in" to this port partner
	 * Note: Much as in real life, cable should be attached before the port
	 * partner can be plugged in to properly discover its information.
	 * For tests, this means this poitner should be set before connecting
	 * the source or sink partner.
	 */
	struct tcpci_cable_data *cable;
};

struct tcpci_cable_data {
	/*
	 * Identity VDM ACKs which the cable is expected to send
	 * These include the VDM header
	 */
	uint32_t identity_vdm[VDO_MAX_SIZE];
	int identity_vdos;
};

/** Structure of message used by TCPCI partner emulator */
struct tcpci_partner_msg {
	/** Reserved for sys_slist_* usage */
	sys_snode_t node;
	/** TCPCI emulator message */
	struct tcpci_emul_msg msg;
	/** Time when message should be sent if message is delayed */
	uint64_t time;
	/** Message type that is placed in the Message Header. Its meaning
	 *  depends on the class of message:
	 *   - for Control Messages, see `enum pd_ctrl_msg_type`
	 *   - for Data Messages, see `enum pd_data_msg_type`
	 *   - for Extended Messages, see `enum pd_ext_msg_type`
	 */
	int type;
	/** Number of data objects */
	int data_objects;
	/** True if this is an extended message */
	bool extended;
};

/** Identify sender of logged PD message */
enum tcpci_partner_msg_sender {
	TCPCI_PARTNER_SENDER_PARTNER,
	TCPCI_PARTNER_SENDER_TCPM
};

/** Structure of logged PD message */
struct tcpci_partner_log_msg {
	/** Reserved for sys_slist_* usage */
	sys_snode_t node;
	/** Pointer to buffer for header and message */
	uint8_t *buf;
	/** Number of bytes in buf */
	int cnt;
	/** Type of message (SOP, SOP', etc) */
	uint8_t sop;
	/** Time when message was send or received by partner emulator */
	uint64_t time;
	/** Sender of the message */
	enum tcpci_partner_msg_sender sender;
	/** Status of sending this message */
	enum tcpci_emul_tx_status status;
};

/** Result of common handler */
enum tcpci_partner_handler_res {
	TCPCI_PARTNER_COMMON_MSG_HANDLED,
	TCPCI_PARTNER_COMMON_MSG_NOT_HANDLED,
	TCPCI_PARTNER_COMMON_MSG_HARD_RESET,
	TCPCI_PARTNER_COMMON_MSG_NO_GOODCRC,
};

/** Structure of TCPCI partner extension */
struct tcpci_partner_extension {
	/** Pointer to next extension or NULL */
	struct tcpci_partner_extension *next;
	/** Pointer to callbacks of the extension */
	struct tcpci_partner_extension_ops *ops;
};

/**
 * Extension callbacks. They are called after the common partner emulator code
 * starting from the extension pointed by extensions field in
 * struct tcpci_partner_data. Rest of extensions are called in order established
 * by next field in struct tcpci_partner_extension.
 * If not required, each callback can be NULL. The NULL callback is ignored and
 * next extension in chain is called.
 * It may be useful for extension to mask message handling in common code using
 * @ref tcpci_partner_common_handler_mask_msg to alter emulator behavior in case
 * of receiving some messages.
 */
struct tcpci_partner_extension_ops {
	/**
	 * @brief Function called when message from TCPM is handled
	 *
	 * @param ext Pointer to partner extension
	 * @param common_data Pointer to TCPCI partner emulator
	 * @param msg Pointer to received message
	 *
	 * @return TCPCI_PARTNER_COMMON_MSG_HANDLED to indicate that message
	 *         is handled and ignore other extensions sop_msg_handler
	 * @return TCPCI_PARTNER_COMMON_MSG_NOT_HANDLED to indicate that
	 *         message wasn't handled
	 */
	enum tcpci_partner_handler_res (*sop_msg_handler)(
		struct tcpci_partner_extension *ext,
		struct tcpci_partner_data *common_data,
		const struct tcpci_emul_msg *msg);

	/**
	 * @brief Function called when HardReset message is received or sent
	 *
	 * @param ext Pointer to partner extension
	 * @param common_data Pointer to TCPCI partner emulator
	 */
	void (*hard_reset)(struct tcpci_partner_extension *ext,
			   struct tcpci_partner_data *common_data);

	/**
	 * @brief Function called when SoftReset message is received
	 *
	 * @param ext Pointer to partner extension
	 * @param common_data Pointer to TCPCI partner emulator
	 */
	void (*soft_reset)(struct tcpci_partner_extension *ext,
			   struct tcpci_partner_data *common_data);

	/**
	 * @brief Function called when partner emulator is disconnected from
	 *        TCPM
	 *
	 * @param ext Pointer to partner extension
	 * @param common_data Pointer to TCPCI partner emulator
	 */
	void (*disconnect)(struct tcpci_partner_extension *ext,
			   struct tcpci_partner_data *common_data);

	/**
	 * @brief Function called when partner emulator is connected to TCPM.
	 *        In connect callback, any message cannot be sent with 0 delay
	 *
	 * @param ext Pointer to partner extension
	 * @param common_data Pointer to TCPCI partner emulator
	 *
	 * @return Negative value on error
	 * @return 0 on success
	 */
	int (*connect)(struct tcpci_partner_extension *ext,
		       struct tcpci_partner_data *common_data);
};

/**
 * @brief Initialise common TCPCI partner emulator. Need to be called before
 *        any other tcpci_partner_* function and init functions of extensions.
 *
 * @param data Pointer to USB-C charger emulator
 * @param rev PD revision of the emulator
 */
void tcpci_partner_init(struct tcpci_partner_data *data, enum pd_rev_type rev);

/**
 * @brief Free message's memory
 *
 * @param msg Pointer to message
 */
void tcpci_partner_free_msg(struct tcpci_partner_msg *msg);

/**
 * @brief Set header of the message
 *
 * @param data Pointer to TCPCI partner emulator
 * @param msg Pointer to message
 */
void tcpci_partner_set_header(struct tcpci_partner_data *data,
			      struct tcpci_partner_msg *msg);

/**
 * @brief Send message to TCPCI emulator or schedule message. On error message
 *        is freed.
 *
 * @param data Pointer to TCPCI partner emulator
 * @param msg Pointer to message to send
 * @param delay Optional delay
 *
 * @return TCPCI_EMUL_TX_SUCCESS on success
 * @return TCPCI_EMUL_TX_FAILED when TCPCI is configured to not handle
 *                              messages of this type
 * @return negative on failure
 */
int tcpci_partner_send_msg(struct tcpci_partner_data *data,
			   struct tcpci_partner_msg *msg, uint64_t delay);

/**
 * @brief Send control message with optional delay
 *
 * @param data Pointer to TCPCI partner emulator
 * @param type Type of message
 * @param delay Optional delay
 *
 * @return TCPCI_EMUL_TX_SUCCESS on success
 * @return TCPCI_EMUL_TX_FAILED when TCPCI is configured to not handle
 *                              messages of this type
 * @return -ENOMEM when there is no free memory for message
 * @return negative on failure
 */
int tcpci_partner_send_control_msg(struct tcpci_partner_data *data,
				   enum pd_ctrl_msg_type type, uint64_t delay);

/**
 * @brief Send data message with optional delay. Data objects are copied to
 *        message.
 *
 * @param data Pointer to TCPCI partner emulator
 * @param type Type of message
 * @param data_obj Pointer to array of data objects
 * @param data_obj_num Number of data objects
 * @param delay Optional delay in milliseconds
 *
 * @return TCPCI_EMUL_TX_SUCCESS on success
 * @return TCPCI_EMUL_TX_FAILED when TCPCI is configured to not handle
 *                              messages of this type
 * @return -ENOMEM when there is no free memory for message
 * @return negative on failure
 */
int tcpci_partner_send_data_msg(struct tcpci_partner_data *data,
				enum pd_data_msg_type type, uint32_t *data_obj,
				int data_obj_num, uint64_t delay);

/**
 * @brief Send an extended PD message to the port partner
 *
 * @param data Pointer to TCPCI partner emulator
 * @param type Extended message type
 * @param delay Message send delay in milliseconds, or zero for no delay.
 * @param payload Pointer to data payload. Does not include any headers.
 * @param payload_size Number of bytes in above payload
 * @return negative on failure, 0 on success
 */
int tcpci_partner_send_extended_msg(struct tcpci_partner_data *data,
				    enum pd_ext_msg_type type, uint64_t delay,
				    uint8_t *payload, size_t payload_size);

/**
 * @brief Remove all messages that are in delayed message queue
 *
 * @param data Pointer to TCPCI partner emulator
 *
 * @return 0 on success
 * @return negative on failure
 */
int tcpci_partner_clear_msg_queue(struct tcpci_partner_data *data);

/**
 * @brief Send hard reset and set common data to state after hard reset (reset
 *        counters, flags, clear message queue)
 *
 * @param data Pointer to TCPCI partner emulator
 */
void tcpci_partner_common_send_hard_reset(struct tcpci_partner_data *data);

/**
 * @brief Send hard reset and set common data to state after soft reset (reset
 *        counters, set flags to wait for accept)
 *
 * @param data Pointer to TCPCI partner emulator
 */
void tcpci_partner_common_send_soft_reset(struct tcpci_partner_data *data);

/**
 * @brief Send a Get Battery Capabilities request to the TCPM
 *
 * @param data Pointer to TCPCI partner emulator
 * @param battery_index Request capability info on this battery. Must
 *        be (0 <= battery_index < PD_BATT_MAX)
 */
void tcpci_partner_common_send_get_battery_capabilities(
	struct tcpci_partner_data *data, int battery_index);

/**
 * @brief Resets the data structure used for tracking battery capability
 *        requests and responses.
 *
 * @param data Emulator state
 */
void tcpci_partner_reset_battery_capability_state(
	struct tcpci_partner_data *data);

/**
 * @brief Start sender response timer for TCPCI_PARTNER_RESPONSE_TIMEOUT_MS.
 *        If @ref tcpci_partner_stop_sender_response_timer wasn't called before
 *        timeout, @ref tcpci_partner_sender_response_timeout is called.
 *        The wait_for_response flag is set on timer start.
 *
 * @param data Pointer to TCPCI partner emulator
 */
void tcpci_partner_start_sender_response_timer(struct tcpci_partner_data *data);

/**
 * @brief Stop sender response timer. The wait_for_response flag is unset.
 *        Timeout handler will not execute.
 *
 * @param data Pointer to TCPCI partner emulator
 */
void tcpci_partner_stop_sender_response_timer(struct tcpci_partner_data *data);

/**
 * @brief Select if @ref tcpci_partner_common_msg_handler should handle specific
 *        control message type.
 *
 * @param data Pointer to TCPCI partner emulator
 * @param type Control message to mask/unmask
 * @param enable If true message of that type is handled, if false common
 *               handler doesn't handle message of that type
 */
void tcpci_partner_common_handler_mask_msg(struct tcpci_partner_data *data,
					   enum pd_ctrl_msg_type type,
					   bool enable);

/**
 * @brief Common disconnect function which clears messages queue, sets
 *        tcpci_emul field in struct tcpci_partner_data to NULL, and stops
 *        timers.
 *
 * @param data Pointer to TCPCI partner emulator
 */
void tcpci_partner_common_disconnect(struct tcpci_partner_data *data);

/**
 * @brief Select if PD messages should be logged or not.
 *
 * @param data Pointer to TCPCI partner emulator
 * @param enable If true, PD messages are logged, false otherwise
 *
 * @return 0 on success
 * @return non-zero on failure
 */
int tcpci_partner_common_enable_pd_logging(struct tcpci_partner_data *data,
					   bool enable);

/**
 * @brief Print all logged PD messages
 *
 * @param data Pointer to TCPCI partner emulator
 */
void tcpci_partner_common_print_logged_msgs(struct tcpci_partner_data *data);

/**
 * @brief Clear all logged PD messages
 *
 * @param data Pointer to TCPCI partner emulator
 */
void tcpci_partner_common_clear_logged_msgs(struct tcpci_partner_data *data);

/**
 * @brief Set the discovery responses (Vendor Defined Messages) for the partner.
 *
 * If a response for a command type is not defined, the partner will ignore
 * requests of that type. To emulate compliant behavior, the discover responses
 * should be internally consistent, e.g., if there is a DisplayPort VID in
 * Discover SVIDs ACK, there should be a Discover Modes ACK for DisplayPort.
 *
 * @param data          Pointer to TCPCI partner emulator
 * @param identity_vdos Number of 32-bit Vendor Defined Objects in the Discover
 *                      Identity response VDM
 * @param identity_vdm  Pointer to the Discover Identity response VDM, including
 *                      the VDM header
 * @param svids_vdos    Number of VDOs in the Discover SVIDs response
 * @param svids_vdm     Pointer to the Discover SVIDs response
 * @param modes_vdos    Number of VDOs in the Discover Modes response
 * @param modes_vdm     Pointer to the Discover Modes response; only currently
 *                      supports a response for a single SVID
 */
void tcpci_partner_set_discovery_info(struct tcpci_partner_data *data,
				      int identity_vdos, uint32_t *identity_vdm,
				      int svids_vdos, uint32_t *svids_vdm,
				      int modes_vdos, uint32_t *modes_vdm);

/**
 * @brief Sets cur_ams_ctrl_req to msg_type to track current request
 *
 * @param data          Pointer to TCPCI partner data
 * @param msg_type      enum pd_ctrl_msg_type
 */
void tcpci_partner_common_set_ams_ctrl_msg(struct tcpci_partner_data *data,
					   enum pd_ctrl_msg_type msg_type);

/**
 * @brief Sets cur_ams_ctrl_req to INVALID
 *
 * @param data          Pointer to TCPCI partner data
 */
void tcpci_partner_common_clear_ams_ctrl_msg(struct tcpci_partner_data *data);

/**
 * @brief Called by partner emulators internally. Resets the common tcpci
 * partner data with the provided role.
 *
 * @param data          Pointer to TCPCI partner data
 * @param power_role    USB PD power role
 */
void tcpci_partner_common_hard_reset_as_role(struct tcpci_partner_data *data,
					     enum pd_power_role power_role);

/**
 * @brief Connect emulated device to TCPCI. The connect callback is executed on
 *        all extensions.
 *
 * @param data Pointer to TCPCI partner emulator
 * @param tcpci_emul Pointer to TCPCI emulator to connect
 *
 * @return 0 on success
 * @return negative on TCPCI connect error
 */
int tcpci_partner_connect_to_tcpci(struct tcpci_partner_data *data,
				   const struct emul *tcpci_emul);

/**
 * @brief Inform TCPCI about status of received message (TCPCI_EMUL_TX_SUCCESS
 *        GoodCRC send to TCPCI, TCPCI_EMUL_TX_DISCARDED partner message send in
 *        the same time as TCPCI message, TCPCI_EMUL_TX_FAILED GoodCRC doesn't
 *        send to TCPCI)
 *
 * @param data Pointer to TCPCI partner emulator
 * @param status Status of received message
 */
void tcpci_partner_received_msg_status(struct tcpci_partner_data *data,
				       enum tcpci_emul_tx_status status);

/**
 * @}
 */

#endif /* __EMUL_TCPCI_PARTNER_COMMON_H */