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 	/* Lazy at CIS active. Number of previously skipped CIG events that is
62 	 * determined when CIS is made active and subtracted from total CIG
63 	 * events that where skipped when this CIS gets to use radio for the
64 	 * first time.
65 	 */
66 	uint16_t lazy_active;
67 #endif /* !CONFIG_BT_CTLR_JIT_SCHEDULING */
68 
69 	/* Resumption information */
70 	uint8_t next_subevent;      /* Next subevent to schedule */
71 
72 	/* Transmission queue */
73 	MEMQ_DECLARE(tx);
74 	memq_link_t link_tx;
75 	memq_link_t *link_tx_free;
76 };
77 
78 #define LLL_CONN_ISO_EVENT_COUNT_MAX BIT64_MASK(39)
79 
80 struct lll_conn_iso_group {
81 	struct lll_hdr hdr;
82 
83 	uint16_t handle;      /* CIG handle (internal) */
84 
85 	/* Resumption information */
86 	uint16_t resume_cis;  /* CIS handle to schedule at resume */
87 
88 	/* ISO group information */
89 	uint32_t num_cis:5;   /* Number of CISes in this CIG */
90 	uint32_t role:1;      /* 0: CENTRAL, 1: PERIPHERAL*/
91 	uint32_t paused:1;    /* 1: CIG is paused */
92 	uint32_t rfu0:1;
93 
94 	/* ISO interval to calculate timestamp under FT > 1,
95 	 * maximum ISO interval of 4 seconds can be represented in 22-bits.
96 	 */
97 	uint32_t iso_interval_us:22;
98 	uint32_t rfu1:2;
99 
100 	/* Accumulates LLL prepare callback latencies */
101 	uint16_t latency_prepare;
102 	uint16_t lazy_prepare;
103 	uint16_t latency_event;
104 
105 #if defined(CONFIG_BT_CTLR_PERIPHERAL_ISO)
106 	/* Window widening. Relies on vendor specific conversion macros, e.g.
107 	 * EVENT_US_FRAC_TO_TICKS().
108 	 */
109 	uint32_t window_widening_periodic_us_frac; /* Widening in us fractions
110 						    * per ISO interval.
111 						    */
112 	uint32_t window_widening_prepare_us_frac;  /* Widening in us fractions
113 						    * for active prepare.
114 						    */
115 	uint32_t window_widening_event_us_frac;    /* Accumulated widening in
116 						    * us fractions for active
117 						    * event.
118 						    */
119 	uint32_t window_widening_max_us;	   /* Maximum widening in us */
120 #endif /* CONFIG_BT_CTLR_PERIPHERAL_ISO */
121 };
122 
123 int lll_conn_iso_init(void);
124 int lll_conn_iso_reset(void);
125 void lll_conn_iso_done(struct lll_conn_iso_group *cig, uint32_t trx_performed,
126 		       uint16_t prog_to_anchor_us, uint8_t mic_state);
127 void lll_conn_iso_flush(uint16_t handle, struct lll_conn_iso_stream *lll);
128 
129 extern struct lll_conn_iso_stream *
130 ull_conn_iso_lll_stream_get_by_group(struct lll_conn_iso_group *cig_lll,
131 				     uint16_t *handle_iter);
132 extern struct lll_conn_iso_stream *
133 ull_conn_iso_lll_stream_sorted_get_by_group(struct lll_conn_iso_group *cig_lll,
134 					    uint16_t *handle_iter);
135 extern struct lll_conn_iso_group *
136 ull_conn_iso_lll_group_get_by_stream(struct lll_conn_iso_stream *cis_lll);
137 extern struct lll_conn_iso_stream *ull_conn_iso_lll_stream_get(uint16_t handle);
138 extern void
139 ull_conn_iso_lll_cis_established(struct lll_conn_iso_stream *cis_lll);
140 extern void ll_iso_rx_put(memq_link_t *link, void *rx);
141 extern void ll_rx_sched(void);
142