1 // Copyright 2020 Espressif Systems (Shanghai) PTE LTD
2 //
3 // Licensed under the Apache License, Version 2.0 (the "License");
4 // you may not use this file except in compliance with the License.
5 // You may obtain a copy of the License at
6 //
7 //     http://www.apache.org/licenses/LICENSE-2.0
8 //
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS,
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 // See the License for the specific language governing permissions and
13 // limitations under the License.
14 
15 #ifndef _ROM_LLDESC_H_
16 #define _ROM_LLDESC_H_
17 
18 #include <stdint.h>
19 
20 #include "sys/queue.h"
21 
22 #ifdef __cplusplus
23 extern "C" {
24 #endif
25 
26 #define LLDESC_TX_MBLK_SIZE                 268 /* */
27 #define LLDESC_RX_SMBLK_SIZE                64  /* small block size, for small mgmt frame */
28 #define LLDESC_RX_MBLK_SIZE                 524 /* rx is large sinec we want to contain mgmt frame in one block*/
29 #define LLDESC_RX_AMPDU_ENTRY_MBLK_SIZE    64  /* it is a small buffer which is a cycle link*/
30 #define LLDESC_RX_AMPDU_LEN_MBLK_SIZE      256 /*for ampdu entry*/
31 #ifdef ESP_MAC_5
32 #define LLDESC_TX_MBLK_NUM                  116  /* 64K / 256 */
33 #define LLDESC_RX_MBLK_NUM                  82 /* 64K / 512 MAX 172*/
34 #define LLDESC_RX_AMPDU_ENTRY_MBLK_NUM     4
35 #define LLDESC_RX_AMPDU_LEN_MLBK_NUM       12
36 #else
37 #ifdef SBUF_RXTX
38 #define LLDESC_TX_MBLK_NUM_MAX    (2 * 48) /* 23K / 260 - 8 */
39 #define LLDESC_RX_MBLK_NUM_MAX    (2 * 48) /* 23K / 524 */
40 #define LLDESC_TX_MBLK_NUM_MIN    (2 * 16) /* 23K / 260 - 8 */
41 #define LLDESC_RX_MBLK_NUM_MIN    (2 * 16) /* 23K / 524 */
42 #endif
43 #define LLDESC_TX_MBLK_NUM      10      //(2 * 32) /* 23K / 260 - 8 */
44 
45 #ifdef IEEE80211_RX_AMPDU
46 #define LLDESC_RX_MBLK_NUM      30
47 #else
48 #define LLDESC_RX_MBLK_NUM      10
49 #endif /*IEEE80211_RX_AMPDU*/
50 
51 #define LLDESC_RX_AMPDU_ENTRY_MBLK_NUM  4
52 #define LLDESC_RX_AMPDU_LEN_MLBK_NUM    8
53 #endif /* !ESP_MAC_5 */
54 /*
55  *  SLC2 DMA Desc struct, aka lldesc_t
56  *
57  * --------------------------------------------------------------
58  * | own | EoF | sub_sof | 5'b0   | length [11:0] | size [11:0] |
59  * --------------------------------------------------------------
60  * |            buf_ptr [31:0]                                  |
61  * --------------------------------------------------------------
62  * |            next_desc_ptr [31:0]                            |
63  * --------------------------------------------------------------
64  */
65 
66 /* this bitfield is start from the LSB!!! */
67 typedef struct lldesc_s {
68     volatile uint32_t size  : 12,
69              length: 12,
70              offset: 5, /* h/w reserved 5bit, s/w use it as offset in buffer */
71              sosf  : 1, /* start of sub-frame */
72              eof   : 1, /* end of frame */
73              owner : 1; /* hw or sw */
74     volatile const uint8_t *buf;       /* point to buffer data */
75     union {
76         volatile uint32_t empty;
77         STAILQ_ENTRY(lldesc_s) qe;  /* pointing to the next desc */
78     };
79 } lldesc_t;
80 
81 typedef struct tx_ampdu_entry_s {
82     uint32_t sub_len  : 12,
83              dili_num : 7,
84              : 1,
85              null_byte: 2,
86              data     : 1,
87              enc      : 1,
88              seq      : 8;
89 } tx_ampdu_entry_t;
90 
91 typedef struct lldesc_chain_s {
92     lldesc_t *head;
93     lldesc_t *tail;
94 } lldesc_chain_t;
95 
96 #ifdef SBUF_RXTX
97 enum sbuf_mask_s  {
98     SBUF_MOVE_NO = 0,
99     SBUF_MOVE_TX2RX,
100     SBUF_MOVE_RX2TX,
101 } ;
102 
103 #define SBUF_MOVE_STEP 8
104 #endif
105 #define LLDESC_SIZE  sizeof(struct lldesc_s)
106 
107 /* SLC Descriptor  */
108 #define LLDESC_OWNER_MASK                  0x80000000
109 #define LLDESC_OWNER_SHIFT                         31
110 #define LLDESC_SW_OWNED                             0
111 #define LLDESC_HW_OWNED                             1
112 
113 #define LLDESC_EOF_MASK                    0x40000000
114 #define LLDESC_EOF_SHIFT                           30
115 
116 #define LLDESC_SOSF_MASK                   0x20000000
117 #define LLDESC_SOSF_SHIFT                          29
118 
119 #define LLDESC_LENGTH_MASK                 0x00fff000
120 #define LLDESC_LENGTH_SHIFT                        12
121 
122 #define LLDESC_SIZE_MASK                   0x00000fff
123 #define LLDESC_SIZE_SHIFT                           0
124 
125 #define LLDESC_ADDR_MASK                    0x000fffff
126 
127 void lldesc_build_chain(uint8_t *descptr, uint32_t desclen, uint8_t *mblkptr, uint32_t buflen, uint32_t blksz, uint8_t owner,
128                         lldesc_t **head,
129 #ifdef TO_HOST_RESTART
130                         lldesc_t **one_before_tail,
131 #endif
132                         lldesc_t **tail);
133 
134 lldesc_t *lldesc_num2link(lldesc_t *head, uint16_t nblks);
135 
136 lldesc_t *lldesc_set_owner(lldesc_t *head, uint16_t nblks, uint8_t owner);
137 
lldesc_get_chain_length(lldesc_t * head)138 static inline uint32_t lldesc_get_chain_length(lldesc_t *head)
139 {
140     lldesc_t *ds = head;
141     uint32_t len = 0;
142 
143     while (ds) {
144         len += ds->length;
145         ds = STAILQ_NEXT(ds, qe);
146     }
147 
148     return len;
149 }
150 
lldesc_config(lldesc_t * ds,uint8_t owner,uint8_t eof,uint8_t sosf,uint16_t len)151 static inline void lldesc_config(lldesc_t *ds, uint8_t owner, uint8_t eof, uint8_t sosf, uint16_t len)
152 {
153     ds->owner  = owner;
154     ds->eof    = eof;
155     ds->sosf   = sosf;
156     ds->length = len;
157 }
158 
159 #define LLDESC_CONFIG(_desc, _owner, _eof, _sosf, _len)        do { \
160         (_desc)->owner  = (_owner); \
161         (_desc)->eof    = (_eof);   \
162         (_desc)->sosf   = (_sosf);  \
163         (_desc)->length = (_len);   \
164 } while(0)
165 
166 #define LLDESC_FROM_HOST_CLEANUP(ds) LLDESC_CONFIG((ds), LLDESC_HW_OWNED, 0, 0, 0)
167 
168 #define LLDESC_MAC_RX_CLEANUP(ds) LLDESC_CONFIG((ds), LLDESC_HW_OWNED, 0, 0, (ds)->size)
169 
170 #define LLDESC_TO_HOST_CLEANUP(ds) LLDESC_CONFIG((ds), LLDESC_HW_OWNED, 0, 0, 0)
171 
172 #ifdef __cplusplus
173 }
174 #endif
175 
176 #endif /* _ROM_LLDESC_H_ */
177