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