1 /*
2  * Copyright (c) 2021 Demant
3  *
4  * SPDX-License-Identifier: Apache-2.0
5  */
6 
7 #define LLL_CIS_FLUSH_NONE      0
8 #define LLL_CIS_FLUSH_PENDING   1
9 #define LLL_CIS_FLUSH_COMPLETE  2
10 
11 struct lll_conn_iso_stream_rxtx {
12 	uint64_t payload_count:39; /* cisPayloadCounter */
13 	uint64_t phy_flags:1;      /* S2 or S8 coding scheme */
14 	uint64_t max_pdu:8;        /* Maximum PDU size */
15 	uint64_t ft:8;             /* Flush timeout (FT) */
16 	uint64_t bn:4;             /* Burst number (BN) */
17 	uint64_t phy:3;            /* PHY */
18 	uint64_t rfu0:1;
19 
20 	uint8_t bn_curr:4;        /* Current burst number */
21 	uint8_t rfu1:4;
22 
23 #if defined(CONFIG_BT_CTLR_LE_ENC)
24 	struct ccm ccm;
25 #endif /* CONFIG_BT_CTLR_LE_ENC */
26 };
27 
28 struct lll_conn_iso_stream {
29 	uint16_t acl_handle;        /* ACL connection handle (for encryption,
30 				     * channel map, crc init)
31 				     */
32 	uint16_t handle;            /* CIS handle */
33 
34 	/* Connection parameters */
35 	uint8_t  access_addr[4];    /* Access address */
36 	uint32_t offset;            /* Offset of CIS from start of CIG in us */
37 	uint32_t sub_interval;      /* Interval between subevents in us */
38 	uint8_t  nse:5;             /* Number of subevents */
39 
40 	/* Frame Spacing */
41 	uint16_t tifs_us;
42 
43 	/* Stream parameters */
44 	struct lll_conn_iso_stream_rxtx rx; /* RX parameters */
45 	struct lll_conn_iso_stream_rxtx tx; /* TX parameters */
46 
47 	/* Event and payload counters */
48 	uint64_t event_count:39;    /* cisEventCount */
49 
50 	/* Acknowledgment and flow control */
51 	uint8_t sn:1;               /* Sequence number */
52 	uint8_t nesn:1;             /* Next expected sequence number */
53 	uint8_t cie:1;              /* Close isochronous event */
54 	uint8_t npi:1;              /* 1 if CIS LLL has Tx-ed Null PDU Indicator */
55 	uint8_t flush:2;            /* See states LLL_CIS_FLUSH_XXX */
56 	uint8_t active:1;           /* 1 if CIS LLL is active */
57 	uint8_t datapath_ready_rx:1;/* 1 if datapath for RX is ready */
58 
59 #if !defined(CONFIG_BT_CTLR_JIT_SCHEDULING)
60 	/* Lazy at CIS active. Number of previously skipped CIG events that is
61 	 * determined when CIS is made active and subtracted from total CIG
62 	 * events that where skipped when this CIS gets to use radio for the
63 	 * first time.
64 	 */
65 	uint16_t lazy_active;
66 #endif /* !CONFIG_BT_CTLR_JIT_SCHEDULING */
67 
68 	/* Resumption information */
69 	uint8_t next_subevent;      /* Next subevent to schedule */
70 
71 	/* Transmission queue */
72 	MEMQ_DECLARE(tx);
73 	memq_link_t link_tx;
74 	memq_link_t *link_tx_free;
75 };
76 
77 #define LLL_CONN_ISO_EVENT_COUNT_MAX BIT64_MASK(39)
78 
79 struct lll_conn_iso_group {
80 	struct lll_hdr hdr;
81 
82 	uint16_t handle;      /* CIG handle (internal) */
83 
84 	/* Resumption information */
85 	uint16_t resume_cis;  /* CIS handle to schedule at resume */
86 
87 	/* ISO group information */
88 	uint32_t num_cis:5;   /* Number of CISes in this CIG */
89 	uint32_t role:1;      /* 0: CENTRAL, 1: PERIPHERAL*/
90 	uint32_t paused:1;    /* 1: CIG is paused */
91 	uint32_t rfu0:1;
92 
93 	/* ISO interval to calculate timestamp under FT > 1,
94 	 * maximum ISO interval of 4 seconds can be represented in 22-bits.
95 	 */
96 	uint32_t iso_interval_us:22;
97 	uint32_t rfu1:2;
98 
99 	/* Accumulates LLL prepare callback latencies */
100 	uint16_t latency_prepare;
101 	uint16_t lazy_prepare;
102 	uint16_t latency_event;
103 
104 #if defined(CONFIG_BT_CTLR_PERIPHERAL_ISO)
105 	/* Window widening. Relies on vendor specific conversion macros, e.g.
106 	 * EVENT_US_FRAC_TO_TICKS().
107 	 */
108 	uint32_t window_widening_periodic_us_frac; /* Widening in us fractions
109 						    * per ISO interval.
110 						    */
111 	uint32_t window_widening_prepare_us_frac;  /* Widening in us fractions
112 						    * for active prepare.
113 						    */
114 	uint32_t window_widening_event_us_frac;    /* Accumulated widening in
115 						    * us fractions for active
116 						    * event.
117 						    */
118 	uint32_t window_widening_max_us;	   /* Maximum widening in us */
119 #endif /* CONFIG_BT_CTLR_PERIPHERAL_ISO */
120 };
121 
122 int lll_conn_iso_init(void);
123 int lll_conn_iso_reset(void);
124 void lll_conn_iso_done(struct lll_conn_iso_group *cig, uint32_t trx_performed,
125 		       uint16_t prog_to_anchor_us, uint8_t mic_state);
126 void lll_conn_iso_flush(uint16_t handle, struct lll_conn_iso_stream *lll);
127 
128 extern struct lll_conn_iso_stream *
129 ull_conn_iso_lll_stream_get_by_group(struct lll_conn_iso_group *cig_lll,
130 				     uint16_t *handle_iter);
131 extern struct lll_conn_iso_stream *
132 ull_conn_iso_lll_stream_sorted_get_by_group(struct lll_conn_iso_group *cig_lll,
133 					    uint16_t *handle_iter);
134 extern struct lll_conn_iso_group *
135 ull_conn_iso_lll_group_get_by_stream(struct lll_conn_iso_stream *cis_lll);
136 extern struct lll_conn_iso_stream *ull_conn_iso_lll_stream_get(uint16_t handle);
137 extern void
138 ull_conn_iso_lll_cis_established(struct lll_conn_iso_stream *cis_lll);
139 extern void ll_iso_rx_put(memq_link_t *link, void *rx);
140 extern void ll_rx_sched(void);
141