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_prepare:39; /* cisEventCount in overlapping CIG prepare */
49 	uint64_t event_count:39;         /* cisEventCount in current CIG event */
50 
51 	/* Acknowledgment and flow control */
52 	uint8_t sn:1;               /* Sequence number */
53 	uint8_t nesn:1;             /* Next expected sequence number */
54 	uint8_t cie:1;              /* Close isochronous event */
55 	uint8_t npi:1;              /* 1 if CIS LLL has Tx-ed Null PDU Indicator */
56 	uint8_t flush:2;            /* See states LLL_CIS_FLUSH_XXX */
57 	uint8_t active:1;           /* 1 if CIS LLL is active */
58 	uint8_t datapath_ready_rx:1;/* 1 if datapath for RX is ready */
59 
60 #if !defined(CONFIG_BT_CTLR_JIT_SCHEDULING)
61 	/* A CIS LLL is active and prepared in a CIG radio event when ACL instant has passed
62 	 * which set the `active` flag and then when CIG event prepare in LLL has picked up the set
63 	 * `active` flag.
64 	 * FIXME: There is suspected possibility that ACL ULL Prepare that is processing LLCP could
65 	 *        execute between CIG ULL Prepare and deferred CIG LLL Prepare say when there is
66 	 *        already another state/role that the CIG tries to pre-empt.
67 	 */
68 	uint8_t prepared:1;
69 	/* Lazy at CIS active. Number of previously skipped CIG events that is
70 	 * determined when CIS is made active and subtracted from total CIG
71 	 * events that where skipped when this CIS gets to use radio for the
72 	 * first time.
73 	 */
74 	uint16_t lazy_active;
75 #endif /* !CONFIG_BT_CTLR_JIT_SCHEDULING */
76 
77 	/* Resumption information */
78 	uint8_t next_subevent;      /* Next subevent to schedule */
79 
80 	/* Transmission queue */
81 	MEMQ_DECLARE(tx);
82 	memq_link_t link_tx;
83 	memq_link_t *link_tx_free;
84 };
85 
86 #define LLL_CONN_ISO_EVENT_COUNT_MAX BIT64_MASK(39)
87 
88 struct lll_conn_iso_group {
89 	struct lll_hdr hdr;
90 
91 	uint16_t handle;      /* CIG handle (internal) */
92 
93 	/* Resumption information */
94 	uint16_t resume_cis;  /* CIS handle to schedule at resume */
95 
96 	/* ISO group information */
97 	uint32_t num_cis:5;   /* Number of CISes in this CIG */
98 	uint32_t role:1;      /* 0: CENTRAL, 1: PERIPHERAL*/
99 	uint32_t paused:1;    /* 1: CIG is paused */
100 	uint32_t rfu0:1;
101 
102 	/* ISO interval to calculate timestamp under FT > 1,
103 	 * maximum ISO interval of 4 seconds can be represented in 22-bits.
104 	 */
105 	uint32_t iso_interval_us:22;
106 	uint32_t rfu1:2;
107 
108 	/* Accumulates LLL prepare callback latencies */
109 	uint16_t latency_prepare;
110 	uint16_t lazy_prepare;
111 	uint16_t latency_event;
112 
113 #if defined(CONFIG_BT_CTLR_PERIPHERAL_ISO)
114 	/* Window widening. Relies on vendor specific conversion macros, e.g.
115 	 * EVENT_US_FRAC_TO_TICKS().
116 	 */
117 	uint32_t window_widening_periodic_us_frac; /* Widening in us fractions
118 						    * per ISO interval.
119 						    */
120 	uint32_t window_widening_prepare_us_frac;  /* Widening in us fractions
121 						    * for active prepare.
122 						    */
123 	uint32_t window_widening_event_us_frac;    /* Accumulated widening in
124 						    * us fractions for active
125 						    * event.
126 						    */
127 	uint32_t window_widening_max_us;	   /* Maximum widening in us */
128 #endif /* CONFIG_BT_CTLR_PERIPHERAL_ISO */
129 };
130 
131 int lll_conn_iso_init(void);
132 int lll_conn_iso_reset(void);
133 void lll_conn_iso_done(struct lll_conn_iso_group *cig, uint32_t trx_performed,
134 		       uint16_t prog_to_anchor_us, uint8_t mic_state);
135 void lll_conn_iso_flush(uint16_t handle, struct lll_conn_iso_stream *lll);
136 
137 extern struct lll_conn_iso_stream *
138 ull_conn_iso_lll_stream_get_by_group(struct lll_conn_iso_group *cig_lll,
139 				     uint16_t *handle_iter);
140 extern struct lll_conn_iso_stream *
141 ull_conn_iso_lll_stream_sorted_get_by_group(struct lll_conn_iso_group *cig_lll,
142 					    uint16_t *handle_iter);
143 extern struct lll_conn_iso_group *
144 ull_conn_iso_lll_group_get_by_stream(struct lll_conn_iso_stream *cis_lll);
145 extern struct lll_conn_iso_stream *ull_conn_iso_lll_stream_get(uint16_t handle);
146 extern void
147 ull_conn_iso_lll_cis_established(struct lll_conn_iso_stream *cis_lll);
148 extern void ll_iso_rx_put(memq_link_t *link, void *rx);
149 extern void ll_rx_sched(void);
150