1 /*
2  * Copyright (c) 2020-2021 Huawei Device Co., Ltd.
3  *
4  * HDF is dual licensed: you can use it either under the terms of
5  * the GPL, or the BSD license, at your option.
6  * See the LICENSE file in the root of this repository for complete details.
7  */
8 
9 /**
10  * @addtogroup WLAN
11  * @{
12  *
13  * @brief Provides cross-OS migration, component adaptation, and modular assembly and compilation.
14  *
15  * Based on the unified APIs provided by the WLAN module, developers of the Hardware Driver Interface
16  * (HDI) are capable of creating, disabling, scanning for, and connecting to WLAN hotspots, managing WLAN chips,
17  * network devices, and power, and applying for, releasing, and moving network data buffers.
18  *
19  * @since 1.0
20  * @version 1.0
21  */
22 
23 /**
24  * @file flow_control.h
25  *
26  * @brief Declares flow control modules and provides functions such as initializing and deinitializing a
27  * flow control module, and transmitting and receiving data packets based on the flow control priority.
28  *
29  * @since 1.0
30  * @version 1.0
31  */
32 
33 #ifndef WIFI_FLOW_CONTROL_H
34 #define WIFI_FLOW_CONTROL_H
35 #include "osal_sem.h"
36 #include "osal_spinlock.h"
37 #include "osal_thread.h"
38 #include "hdf_netbuf.h"
39 
40 /**
41  * @brief Enumerates flow control queue IDs.
42  *
43  * @since 1.0
44  * @version 1.0
45  */
46 typedef enum {
47     CTRL_QUEUE_ID = 0,  /**< Control queue ID */
48     VIP_QUEUE_ID,       /**< VIP queue ID */
49     NORMAL_QUEUE_ID,    /**< Normal queue ID */
50     TCP_DATA_QUEUE_ID,  /**< TCP data queue ID */
51     TCP_ACK_QUEUE_ID,   /**< TCP ACK queue ID */
52     BK_QUEUE_ID,        /**< Background flow queue ID */
53     BE_QUEUE_ID,        /**< Best-effort flow queue ID */
54     VI_QUEUE_ID,        /**< Video flow queue ID */
55     VO_QUEUE_ID,        /**< Voice flow queue ID */
56     QUEUE_ID_COUNT      /**< Total number of queue IDs */
57 } FlowControlQueueID;
58 
59 /**
60  * @brief Enumerates flow directions.
61  *
62  * @since 1.0
63  * @version 1.0
64  */
65 typedef enum {
66     FLOW_TX = 0,    /**< Transmit */
67     FLOW_RX,        /**< Receive */
68     FLOW_DIR_COUNT  /**< Total number of flow directions */
69 } FlowDir;
70 
71 /**
72  * @brief Enumerates flow control thread statuses.
73  *
74  * @since 1.0
75  * @version 1.0
76  */
77 typedef enum {
78     THREAD_INIT_FAIL = 0,  /**< Failed to initialize */
79     THREAD_INIT_SUCCESS,   /**< Initialized successfully */
80     THREAD_STARTING,       /**< Starting */
81     THREAD_WAITING,        /**< Waiting */
82     THREAD_RUNNING,        /**< Running */
83     THREAD_STOPPING,       /**< Stopping */
84     THREAD_STOPPED,        /**< Stopped */
85     THREAD_DESTROYED,      /**< Destroyed */
86     THREAD_STATUS_COUNT    /**< Total number of thread statuses */
87 }FcThreadStatus;
88 
89 /**
90  * @brief Describes a flow control queue.
91  *
92  * @since 1.0
93  * @version 1.0
94  */
95 struct FlowControlQueue {
96     FlowControlQueueID queueID;  /**< Flow control queue ID */
97     NetBufQueue dataQueue;       /**< Network data queue */
98     uint32_t queueThreshold;     /**< Network data queue threshold */
99     OsalSpinlock lock;           /**< Queue lock */
100     uint32_t pktCount;           /**< Number of packets received by the network data queue */
101 };
102 
103 /**
104  * @brief Manages flow control queues.
105  *
106  * @since 1.0
107  * @version 1.0
108  */
109 struct FlowControlQueues {
110     struct FlowControlQueue queues[QUEUE_ID_COUNT];  /**< Array of flow control queues */
111 };
112 
113 
114 /**
115  * @brief Provides flow control operations.
116  *
117  * @since 1.0
118  * @version 1.0
119  */
120 struct FlowControlOp {
121     /**
122      * @brief Checks whether the device is a station or P2P client.
123      *
124      * @return Returns <b>true</b> if the device is a station or P2P client; returns <b>false</b> otherwise.
125      *
126      * @since 1.0
127      * @version 1.0
128      */
129     bool (*isDeviceStaOrP2PClient)(void);
130 
131     /**
132      * @brief Transmits data packets.
133      *
134      * @param q Indicates the pointer to the network data queue.
135      * @param fcmPrivate Indicates the pointer to the private structure in the WLAN driver for
136      * transmitting data packets.
137      * @param fwPriorityId Indicates the ID of the flow control priority.
138      * @return Returns <b>0</b> if data packets are transmitted; returns a negative value otherwise.
139      *
140      * @since 1.0
141      * @version 1.0
142      */
143     int32_t (*txDataPacket)(NetBufQueue *q, void *fcmPrivate, int32_t fwPriorityId);
144 
145     /**
146      * @brief Receives data packets.
147      *
148      * @param q Indicates the pointer to the network data queue.
149      * @param fcmPrivate Indicates the pointer to the private structure in the WLAN driver for receiving data packets.
150      * @param fwPriorityId Indicates the ID of the flow control priority.
151      * @return Returns <b>0</b> if data packets are received; returns a negative value otherwise.
152      *
153      * @since 1.0
154      * @version 1.0
155      */
156     int32_t (*rxDataPacket)(NetBufQueue *q, void *fcmPrivate, int32_t fwPriorityId);
157 
158     /**
159      * @brief Obtains the transmit flow control queue ID defined by the driver vendor.
160      *
161      * @param para Indicates the pointer to the structure defined by the driver and used to obtain the transmit
162      * flow control queue ID.
163      * @return Returns the pointer to the transmit flow control queue ID, as enumerated in {@link FlowControlQueueID}.
164      *
165      * @since 1.0
166      * @version 1.0
167      */
168     FlowControlQueueID (*getTxQueueId)(const void *para);
169 
170     /**
171      * @brief Obtains the receive flow control queue ID defined by the driver vendor.
172      *
173      * @param para Indicates the pointer to the structure defined by the driver and used to obtain the receive
174      * flow control queue ID.
175      * @return Returns the pointer to the receive flow control queue ID, as enumerated in {@link FlowControlQueueID}.
176      *
177      * @since 1.0
178      * @version 1.0
179      */
180     FlowControlQueueID (*getRxQueueId)(const void *para);
181 
182     /**
183      * @brief Obtains the ID of the priority of a specified transmit flow control queue.
184      *
185      * @param id Indicates the ID of the transmit flow control queue.
186      * @return Returns <b>0</b> if the priority ID is obtained; returns a negative value otherwise.
187      *
188      * @since 1.0
189      * @version 1.0
190      */
191     int32_t (*getTxPriorityId)(FlowControlQueueID id);
192 
193     /**
194      * @brief Obtains the ID of the priority of a specified receive flow control queue.
195      *
196      * @param id Indicates the ID of the receive flow control queue.
197      * @return Returns <b>0</b> if the priority ID is obtained; returns a negative value otherwise.
198      *
199      * @since 1.0
200      * @version 1.0
201      */
202     int32_t (*getRxPriorityId)(FlowControlQueueID id);
203 };
204 
205 /**
206  * @brief Describes a flow control module.
207  *
208  * @since 1.0
209  * @version 1.0
210  */
211 struct FlowControlModule {
212     OSAL_DECLARE_THREAD(txTransferThread);              /**< Transmit flow transfer thread */
213     OSAL_DECLARE_THREAD(rxTransferThread);              /**< Receive flow transfer thread */
214     struct OsalSem sem[FLOW_DIR_COUNT];                 /**< Array of semaphores */
215     FcThreadStatus threadStatus[FLOW_DIR_COUNT];        /**< Array of flow control thread statuses */
216     struct FlowControlQueues fcmQueue[FLOW_DIR_COUNT];  /**< Array of flow control queues */
217     struct FlowControlOp *op;                           /**< Flow control operation */
218     struct FlowControlInterface *interface;             /**< Flow control function */
219     void *fcmPriv;                                      /**< Private data of the flow control module */
220 };
221 
222 /**
223  * @brief Provides flow control functions, such as obtaining the queue ID and registering a flow control operation API.
224  *
225  * @since 1.0
226  * @version 1.0
227  */
228 struct FlowControlInterface {
229     /**
230      * @brief Obtains the flow control queue ID based on the network data buffer.
231      *
232      * @param buff Indicates the pointer to the network data buffer.
233      * @return Returns the {@link FlowControlQueueID}.
234      *
235      * @since 1.0
236      * @version 1.0
237      */
238     FlowControlQueueID (*getQueueIdByEtherBuff)(const NetBuf *buff);
239 
240     /**
241      * @brief Sets the threshold for a specified flow control queue.
242      *
243      * @param fcm Indicates the pointer to the {@link FlowControlModule} that contains the flow control queue.
244      * @param queueThreshold Indicates the threshold to set.
245      * @param id Indicates the ID of the flow control queue.
246      * @param dir Indicates the flow control direction, as enumerated in {@link FlowDir}.
247      * @return Returns <b>0</b> if the threshold is set; returns a negative value otherwise.
248      *
249      * @since 1.0
250      * @version 1.0
251      */
252     int32_t (*setQueueThreshold)(struct FlowControlModule *fcm, uint32_t queueThreshold, uint32_t id, uint32_t dir);
253 
254     /**
255      * @brief Sends data to a specified {@link FlowControlModule}.
256      *
257      * @param fcm Indicates the pointer to the {@link FlowControlModule}.
258      * @param buff Indicates the pointer to the buffer that stores the data to send.
259      * @param id Indicates the ID of the flow control queue.
260      * @param dir Indicates the flow control direction, as enumerated in {@link FlowDir}.
261      * @return Returns <b>0</b> if the data is sent; returns a negative value otherwise.
262      *
263      * @since 1.0
264      * @version 1.0
265      */
266     int32_t (*sendBuffToFCM)(struct FlowControlModule *fcm, NetBuf *buff, uint32_t id, uint32_t dir);
267 
268     /**
269      * @brief Schedules a specified {@link FlowControlModule}.
270      *
271      * @param fcm Indicates the pointer to the {@link FlowControlModule}.
272      * @param dir Indicates the flow control direction, as enumerated in {@link FlowDir}.
273      * @return Returns <b>0</b> if the {@link FlowControlModule} is scheduled; returns a negative value otherwise.
274      *
275      * @since 1.0
276      * @version 1.0
277      */
278     int32_t (*schedFCM)(struct FlowControlModule *fcm, FlowDir dir);
279 
280     /**
281      * @brief Registers a specified flow control operation API.
282      *
283      * @param fcm Indicates the pointer to the {@link FlowControlModule}.
284      * @param op Indicates the pointer to the flow control operation API to register.
285      * @return Returns <b>0</b> if the API is registered; returns a negative value otherwise.
286      *
287      * @since 1.0
288      * @version 1.0
289      */
290     int32_t (*registerFlowControlOp)(struct FlowControlModule *fcm, struct FlowControlOp *op);
291 };
292 
293 /**
294  * @brief Processes Ethernet data.
295  *
296  * @param buff Indicates the pointer to the data to process.
297  * @param len Indicates the data length.
298  *
299  * @return Returns the {@link FlowControlQueueID}.
300  *
301  * @since 1.0
302  * @version 1.0
303  */
304 typedef FlowControlQueueID (*EtherTypeProcessFun)(const void *buff, uint32_t len);
305 
306 /**
307  * @brief Describes how to process Ethernet data.
308  *
309  * @since 1.0
310  * @version 1.0
311  */
312 struct EtherProcessMap {
313     uint16_t etherType;              /**< Ethernet data type */
314     EtherTypeProcessFun processFun;  /**< Function for processing Ethernet data */
315 };
316 
317 /**
318  * @brief Initializes a specified {@link FlowControlModule}.
319  *
320  * @param fcmPriv Indicates the pointer to the private data of the {@link FlowControlModule}.
321  *
322  * @return Returns the pointer to the initialized {@link FlowControlModule}.
323  *
324  * @since 1.0
325  * @version 1.0
326  */
327 struct FlowControlModule *InitFlowControl(void *fcmPriv);
328 
329 /**
330  * @brief Obtains a {@link FlowControlModule}.
331  *
332  * @return Returns the pointer to the {@link FlowControlModule}.
333  *
334  * @since 1.0
335  * @version 1.0
336  */
337 struct FlowControlModule *GetFlowControlModule(void);
338 
339 /**
340  * @brief Deinitializes a specified {@link FlowControlModule}.
341  *
342  * @param fcm Indicates the pointer to the {@link FlowControlModule}.
343  *
344  * @since 1.0
345  * @version 1.0
346  */
347 void DeInitFlowControl(struct FlowControlModule *fcm);
348 
349 /**
350  * @brief Sends a flow control queue.
351  *
352  * @param fcm Indicates the pointer to the {@link FlowControlModule} that contains the flow control queue.
353  * @param id Indicates the ID of the flow control queue.
354  * @param dir Indicates the flow control direction, as enumerated in {@link FlowDir}.
355  *
356  * @return Returns <b>0</b> if the flow control queue is sent; returns a negative value otherwise.
357  *
358  * @since 1.0
359  * @version 1.0
360  */
361 int32_t SendFlowControlQueue(struct FlowControlModule *fcm, uint32_t id, uint32_t dir);
362 
363 #endif /* WIFI_FLOW_CONTROL_H */
364 /** @} */
365