1 /******************************************************************************
2  * Copyright (c) 2022 Telink Semiconductor (Shanghai) Co., Ltd. ("TELINK")
3  * All rights reserved.
4  *
5  * Licensed under the Apache License, Version 2.0 (the "License");
6  * you may not use this file except in compliance with the License.
7  * You may obtain a copy of the License at
8  *
9  *   http://www.apache.org/licenses/LICENSE-2.0
10  *
11  * Unless required by applicable law or agreed to in writing, software
12  * distributed under the License is distributed on an "AS IS" BASIS,
13  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14  * See the License for the specific language governing permissions and
15  * limitations under the License.
16  *
17  *****************************************************************************/
18 
19 #ifndef B91_BT_BUFFER_H_
20 #define B91_BT_BUFFER_H_
21 
22 #include "stack/ble/ble.h"
23 #include "zephyr/bluetooth/buf.h"
24 
25 #define BT_BUF_TX_SIZE                                                                             \
26 	MAX(BT_BUF_CMD_SIZE(CONFIG_BT_BUF_CMD_TX_SIZE), BT_BUF_ACL_SIZE(CONFIG_BT_BUF_ACL_TX_SIZE))
27 
28 #define ACL_CONN_MAX_RX_OCTETS (BT_BUF_RX_SIZE > 251 ? 251 : BT_BUF_RX_SIZE)
29 #define ACL_SLAVE_MAX_TX_OCTETS (CONFIG_BT_BUF_ACL_TX_SIZE > 251 ? 251 : CONFIG_BT_BUF_ACL_TX_SIZE)
30 #define ACL_MASTER_MAX_TX_OCTETS (CONFIG_BT_BUF_ACL_TX_SIZE > 251 ? 251 : CONFIG_BT_BUF_ACL_TX_SIZE)
31 
32 /* Macroses to align values to specific size */
33 #define ALIGN_2 1
34 #define ALIGN_4 2
35 #define ALIGN_8 3
36 #define ALIGN_16 4
37 #define ALIGN(x, order)                                                                            \
38 	(((x) % (1 << (order))) == 0 ? (x) : ((((x) >> (order)) << (order)) + (1 << order)))
39 
40 /* Macro to find next power of two value */
41 /* Found Here: https://lists.freebsd.org/pipermail/freebsd-current/2007-February/069093.html */
42 #define NPOT2(x) ((x) | ((x) >> 1))
43 #define NPOT4(x) (NPOT2(x) | (NPOT2(x) >> 2))
44 #define NPOT8(x) (NPOT4(x) | (NPOT4(x) >> 4))
45 #define NPOT16(x) (NPOT8(x) | (NPOT8(x) >> 8))
46 #define NPOT32(x) (NPOT16(x) | (NPOT16(x) >> 16))
47 #define NEXT_POWER_OF_2(x) (NPOT32(x - 1) + 1)
48 
49 /* Macro to calculate ACL TX master/slave buffer number. */
50 /* According to Telink implementation, shall be 9, 17 or 33 */
51 #define CAL_LL_ACL_BUF_NUM(x) (x <= 9 ? 9 : x <= 17 ? 17 : 33)
52 
53 /*
54     TX from host CMD or ACL buffer, RX to Contorller HCI buffer
55     According to Telink implementatios, the buffer shall be alligned to 16.
56 */
57 #define HCI_RX_FIFO_SIZE HCI_FIFO_SIZE(BT_BUF_TX_SIZE)
58 
59 /*
60     According to Telink implementation shall number of buffers shall be power of 2
61 */
62 #define HCI_RX_FIFO_NUM NEXT_POWER_OF_2(MAX(CONFIG_BT_BUF_CMD_TX_COUNT, CONFIG_BT_BUF_ACL_TX_COUNT))
63 
64 /*
65     TX from controller, RX to Host
66     According to Telink implementatios, the buffer shall be alligned to 4.
67 */
68 #define HCI_TX_FIFO_SIZE HCI_FIFO_SIZE(BT_BUF_RX_SIZE)
69 
70 /*
71     According to Telink implementation shall number of buffers shall be power of 2
72 */
73 #define HCI_TX_FIFO_NUM NEXT_POWER_OF_2(BT_BUF_RX_COUNT)
74 
75 /*
76     Intermediate ACL buffer that takes data from HCI RX and pass it to ACL TX
77     According to Telink implementatios, the buffer shall be alligned to 4.
78 */
79 #define HCI_RX_ACL_FIFO_SIZE ALIGN(BT_BUF_ACL_SIZE(CONFIG_BT_BUF_ACL_TX_SIZE), ALIGN_4)
80 
81 /*
82     According to Telink implementation shall number of buffers shall be power of 2
83 */
84 #define HCI_RX_ACL_FIFO_NUM NEXT_POWER_OF_2(CONFIG_BT_BUF_ACL_TX_COUNT)
85 
86 /*
87     Data from radio to RX ACL buffer
88     According to Telink implementatios, the buffer shall be alligned to 16.
89 */
90 #define ACL_RX_FIFO_SIZE CAL_LL_ACL_RX_FIFO_SIZE(BT_BUF_RX_SIZE)
91 
92 /*
93     Number of ACL RX buffers. Shall be power of 2
94 */
95 #define ACL_RX_FIFO_NUM NEXT_POWER_OF_2(BT_BUF_RX_COUNT)
96 
97 /*
98     Data from ACL TX to radio
99     According to Telink implementatios, the buffer shall be alligned to 16.
100 */
101 #define ACL_SLAVE_TX_FIFO_SIZE CAL_LL_ACL_TX_FIFO_SIZE(CONFIG_BT_BUF_ACL_TX_SIZE)
102 
103 /*
104     Number of ACL TX buffers. Shall be 9, 17, 33
105 */
106 #define ACL_SLAVE_TX_FIFO_NUM CAL_LL_ACL_BUF_NUM(CONFIG_BT_BUF_ACL_TX_COUNT)
107 
108 /*
109     Data from ACL TX to radio
110     According to Telink implementatios, the buffer shall be alligned to 16.
111 */
112 #define ACL_MASTER_TX_FIFO_SIZE CAL_LL_ACL_TX_FIFO_SIZE(CONFIG_BT_BUF_ACL_TX_SIZE)
113 
114 /*
115     Number of ACL TX buffers. Shall be 9, 17, 33
116 */
117 #define ACL_MASTER_TX_FIFO_NUM CAL_LL_ACL_BUF_NUM(CONFIG_BT_BUF_ACL_TX_COUNT)
118 
119 extern u8 app_acl_rxfifo[];
120 extern u8 app_acl_mstTxfifo[];
121 extern u8 app_acl_slvTxfifo[];
122 
123 extern u8 app_hci_rxfifo[];
124 extern u8 app_hci_txfifo[];
125 extern u8 app_hci_rxAclfifo[];
126 
127 #endif /* B91_BT_BUFFER_H_ */
128