• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2021 Chipsea Technologies (Shenzhen) Corp., Ltd. All rights reserved.
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 _WIFI_HOST_TX_H
16 #define _WIFI_HOST_TX_H
17 
18 #include "al_rtos.h"
19 #include "porting_net_al.h"
20 #include "wb_co_list.h"
21 #include "wifi_tx_swdesc.h"
22 #include "wifi_host.h"
23 #ifdef CFG_HOSTIF
24 #include "hostif.h"
25 #endif /* CFG_HOSTIF */
26 
27 #define TX_WAIT_FW_BUFFER_TIME_MS      20
28 
29 /// Number of TX flow control credits allocated by default per RA/TID (UMAC only)
30 #define NX_DEFAULT_TX_CREDIT_CNT 4
31 /// Number of elements in the TX message queue
32 #define FHOST_TX_QUEUE_MSG_ELT_CNT     64
33 
34 /// Frame transmission done
35 #define TX_STATUS_DONE                 CO_BIT(0)
36 /// Frame retry required
37 #define TX_STATUS_RETRY_REQUIRED       CO_BIT(1)
38 /// Frame sw retry required
39 #define TX_STATUS_SW_RETRY_REQUIRED    CO_BIT(2)
40 /// Frame acknoledged
41 #define TX_STATUS_ACKNOWLEDGED         CO_BIT(3)
42 
43 #define TXU_CNTRL_RETRY        BIT(0)
44 #define TXU_CNTRL_MORE_DATA    BIT(2)
45 #define TXU_CNTRL_MGMT         BIT(3)
46 #define TXU_CNTRL_MGMT_NO_CCK  BIT(4)
47 #define TXU_CNTRL_AMSDU        BIT(6)
48 #define TXU_CNTRL_MGMT_ROBUST  BIT(7)
49 #define TXU_CNTRL_USE_4ADDR    BIT(8)
50 #define TXU_CNTRL_EOSP         BIT(9)
51 #define TXU_CNTRL_MESH_FWD     BIT(10)
52 #define TXU_CNTRL_TDLS         BIT(11)
53 /// This frame is postponed internally because of PS. (only for AP)
54 #define TXU_CNTRL_POSTPONE_PS   BIT(12)
55 /// Internal flag indicating that this packet should use the trial rate as first or second rate
56 #define TXU_CNTRL_RC_TRIAL      BIT(13)
57 /// Internal flag indicating that this is a UAPSD trigger frame
58 #define TXU_CNTRL_UASPD_TRIGGER BIT(14)
59 //add by cs
60 #define TXU_CNTRL_AMPDU_MPDU_RETRY  BIT(15)
61 
62 /// Stored in hostdesc.status_desc_addr
63 #ifndef CFG_WIFI_RAM_VER
64 #define TXU_CNTRL_NEED_CFM      BIT(0)
65 #else /* CFG_WIFI_RAM_VER */
66 #define TXU_CNTRL_NEED_CFM      BIT(31)
67 #endif /* CFG_WIFI_RAM_VER */
68 
69 /// IDs of messages received by the FHOST TX task
70 enum fhost_tx_msg_id
71 {
72     /// Indicate that a STA is connected
73     FHOST_TX_STA_ADD = 0,
74     /// Indicate that a STA is disconnected
75     FHOST_TX_STA_DEL,
76     /// Indicate that the credits for a TX queue are updated
77     FHOST_TX_CREDITS_UPDATE,
78     /// Enable TXQ associated to a VIF
79     FHOST_TX_VIF_ENABLE,
80     /// Disable TXQ associated to a VIF
81     FHOST_TX_VIF_DISABLE,
82     /// Indicate that a STA enabled PowerSave mode
83     FHOST_TX_STA_ENTER_PS,
84     /// Indicate that a STA disabled PowerSave mode
85     FHOST_TX_STA_EXIT_PS,
86     /// Request trafiic for STA in PS mode
87     FHOST_TX_PS_TRAFFIC_REQ,
88 };
89 
90 /// TXQ status flag
91 enum fhost_txq_flags {
92     /// The queue is scheduled for transmission
93     TXQ_IN_HWQ_LIST  = CO_BIT(0),
94     /// No more credits for the queue
95     TXQ_STOP_FULL    = CO_BIT(1),
96     /// CSA is in progress
97     TXQ_STOP_CSA     = CO_BIT(2),
98     /// Destination sta is currently in power save mode
99     TXQ_STOP_STA_PS  = CO_BIT(3),
100     /// VIF owning this queue is currently in power save mode
101     TXQ_STOP_VIF_PS  = CO_BIT(4),
102     /// Channel of this queue is not the current active channel
103     TXQ_STOP_CHAN    = CO_BIT(5),
104     TXQ_STOP_TIMER   = CO_BIT(6),
105     /// All possible reasons to have a txq stopped
106     TXQ_STOP         = (TXQ_STOP_FULL | TXQ_STOP_CSA | TXQ_STOP_STA_PS | TXQ_STOP_VIF_PS |
107                         TXQ_STOP_CHAN | TXQ_STOP_TIMER),
108     /// TX queue is enabled, i.e. meaning that it can be used for transmission
109     TXQ_ENABLED      = CO_BIT(7),
110 };
111 
112 /// Type of PS traffic
113 enum fhost_tx_ps_type
114 {
115     /// Legacy power save
116     PS_LEGACY,
117     /// UAPSD
118     PS_UAPSD,
119     /// Number of PS traffic
120     PS_TYPE_CNT,
121 };
122 
123 /*
124  * TYPE DEFINITIONS
125  ****************************************************************************************
126  */
127 /// Structure used for the inter-task communication
128 struct fhost_tx_msg_tag
129 {
130     /// Message ID (from @ref fhost_tx_msg_id)
131     enum fhost_tx_msg_id msg_id;
132     /// Message structure
133     union
134     {
135         /// Add station
136         struct
137         {
138             /// Id of the station to add
139             uint8_t sta_id;
140         } sta_add;
141         /// Delete station
142         struct
143         {
144             /// Id of the station to delete
145             uint8_t sta_id;
146         } sta_del;
147         /// Update credits
148         struct
149         {
150             /// Id of the station for which credits are updated
151             uint8_t sta_id;
152             /// TID for which credits are updated
153             uint8_t tid;
154             /// Credits
155             int8_t credits;
156         } credits_upd;
157     } u;
158 };
159 
160 
161 /// Structure mapped into the TX buffer for internal handling
162 struct fhost_tx_desc_tag
163 {
164     /// Chained list element
165     struct co_list_hdr hdr;
166     /// TX descriptor passed to MAC
167     struct txdesc txdesc;
168     uint8_t pbd_cnt;
169 };
170 
171 /// TX queue structure
172 struct fhost_tx_queue_tag
173 {
174     /// Next TX queue element (used to chain the TX queue to the scheduler)
175     struct fhost_tx_queue_tag *next;
176     /// Next TX queue element (used to chain the TX queue to the scheduler)
177     struct fhost_tx_queue_tag *prev;
178     /// List of TX buffers ready for transmission (@ref fhost_tx_desc_tag.hdr)
179     struct co_list ready;
180     /// Status of the queue - see @ref fhost_txq_flags
181     uint8_t status;
182     /// Number of credits currently available in this queue
183     int8_t credits;
184     #if NX_BEACONING
185     /// TXQ PS type (@ref fhost_tx_ps_type)
186     int8_t ps_type;
187     /// Number of packet queued in 'ready' list
188     uint16_t nb_ready;
189     /// Number of packet to push to complete PS service period
190     uint16_t limit;
191     #endif //NX_BEACONING
192 };
193 
194 /// TX queue scheduler structure
195 struct fhost_tx_queue_sched_tag
196 {
197     /// Current TX queue element being scheduled
198     struct fhost_tx_queue_tag *current;
199 };
200 /// Traffic information for one station
201 struct fhost_tx_sta_traffic
202 {
203     /// Number of packet ready for PS service period among all STA's TXQ
204     /// (-1 if station is not in PS mode)
205     int ps_ready[PS_TYPE_CNT];
206     /// Number of packet to push to complete the PS service period
207     int sp_cnt[PS_TYPE_CNT];
208 };
209 
210 /**
211  * Number of TXQ allocated
212  *
213  * Currently we have:
214  * - One TXQ per TID and per STA:
215  *   TXQ id is @verbatim  <sta_id> * TID_MAX + <tid> @endverbatim
216  * - One TXQ for unknown STA for each VIF (Only enabled for AP and Monitor interface)
217  *   TXQ id is @verbatim (NX_REMOTE_STA_MAX * TID_MAX) + <vif_idx> @endverbatim
218  */
219 #define FHOST_TXQ_CNT ((STA_MAX * TID_MAX) + NX_VIRT_DEV_MAX)
220 
221 /// FHOST RX environment structure
222 struct fhost_tx_env_tag
223 {
224     /// Queues used for the transmission requests sent to the WiFi task
225     //rtos_queue queue_tx[NX_TXQ_CNT];
226     /// Queue used to allow other tasks interacting with the FHOST TX task (confirmations
227     /// from the WiFi task, transmission requests from the networking stack, etc.)
228     rtos_queue queue_msg;
229     /// Internal per-STA/TID TX queues
230     struct fhost_tx_queue_tag tx_q[FHOST_TXQ_CNT];
231     /// TX queue scheduler structures (one per HW queue)
232     struct fhost_tx_queue_sched_tag sched[NX_TXQ_CNT];
233     /// Semaphore used for TX locking
234     rtos_semaphore tx_lock;
235     rtos_semaphore txq_lock;
236 #if NX_BEACONING
237     /// Traffic information for each station(only used by AP interface)
238     struct fhost_tx_sta_traffic traffic[STA_MAX];
239 #endif
240     TimerHandle_t periodic_tx_timer;
241     uint8_t       periodic_tx_num;
242     uint8_t       to_times;
243 
244 };
245 
246 /// FHOST STA PS environment structure
247 struct fhost_tx_sta_ps_env_tag
248 {
249     /// True when the sta is in PS mode, If false, other values should be ignored.
250     uint8_t ps[NX_REMOTE_STA_MAX];
251     /// Number of packets buffered for the sta in fhost's txq(1 counter for Legacy PS & 1 for U-APSD)
252     uint16_t pkt_ready[2];
253     /// Number of packets that remain to be pushed in the service period.
254     /// 0 means that no service period is in progress(1 counter for Legacy PS & 1 for U-APSD)
255     uint16_t sp_cnt[2];
256 };
257 
258 #define LEGACY_PS_ID  (0)
259 #define UAPSD_ID      (1)
260 
261 /// Macro used to lock the TX mutex
262 #define FHOST_TX_LOCK()    rtos_mutex_lock(fhost_tx_env.tx_lock, -1)
263 /// Macro used to unlock the TX mutex
264 #define FHOST_TX_UNLOCK()  rtos_mutex_unlock(fhost_tx_env.tx_lock)
265 
266 /// Macro used to lock the TXQ
267 #define FHOST_TXQ_LOCK()    rtos_mutex_lock(fhost_tx_env.txq_lock, -1)
268 /// Macro used to unlock the TX mutex
269 #define FHOST_TXQ_UNLOCK()  rtos_mutex_unlock(fhost_tx_env.txq_lock)
270 
271 /*
272  * GLOBAL VARIABLES
273  ****************************************************************************************
274  */
275 /// FHOST RX environment
276 extern struct fhost_tx_env_tag fhost_tx_env;
277 extern struct co_list tx_desc_free_list;
278 
279 /*
280  * FUNCTIONS
281  ****************************************************************************************
282  */
283 /**
284  ****************************************************************************************
285  * @brief Initialization of the TX task.
286  * This function initializes the different data structures used for the TX and creates the
287  * RTOS task dedicated to the TX processing.
288  *
289  * @return 0 on success and != 0 if error occurred.
290  ****************************************************************************************
291  */
292 int fhost_tx_init(void);
293 
294 /**
295  ****************************************************************************************
296  * @brief Push a buffer for transmission.
297  *
298  * The buffer is directly pushed with the TX mutex hold.
299  *
300  * @param[in] net_if      Pointer to the net interface for which the packet is pushed
301  * @param[in] net_buf     Pointer to the net buffer to transmit.
302  * @param[in] cfm_cb      Callback when transmission has been completed (may be NULL)
303  * @param[in] cfm_cb_arg  Private argument for the callback.
304  *
305  * @return 0 on success and != 0 if error occurred.
306  ****************************************************************************************
307  */
308 int fhost_tx_start(net_if_t *net_if, net_buf_tx_t *net_buf,
309                    cb_fhost_tx cfm_cb, void *cfm_cb_arg);
310 
311 /**
312  ****************************************************************************************
313  * @brief Push a TX confirmation to the FHOST TX task
314  *
315  * @param[in] statinfo TX status information
316  *
317  ****************************************************************************************
318  */
319 void fhost_tx_cfm_push(uint32_t statinfo);
320 
321 /**
322  ****************************************************************************************
323  * @brief Update the credits of a TX queue, upon the creation or deletion of a BlockAck
324  * agreement of the association STA/TID pair.
325  *
326  * @param[in] sta_id Index of the station
327  * @param[in] tid Priority
328  * @param[in] credits Number of credits to add/remove on the TX queue
329  ****************************************************************************************
330  */
331 void fhost_tx_credits_update(uint8_t sta_id, uint8_t tid, int8_t credits);
332 
333 /**
334  ****************************************************************************************
335  * @brief Enable the TX queues for the given STA.
336  *
337  * Send message @ref FHOST_TX_STA_ADD to FHOST TX thread to enable the TX queues
338  * associated to this STA.
339  *
340  * @param[in] sta_id Station index to add
341  ****************************************************************************************
342  */
343 void fhost_tx_sta_add(uint8_t sta_id);
344 
345 /**
346  ****************************************************************************************
347  * @brief Disable the TX queues for the given STA.
348  *
349  * Send message @ref FHOST_TX_STA_DEL to FHOST TX thread to disable the TX queues
350  * associated to this STA. Any pending packets in the queues will be freed.
351  *
352  * @param[in] sta_id Station index to delete
353  ****************************************************************************************
354  */
355 void fhost_tx_sta_del(uint8_t sta_id);
356 /// @}
357 void fhost_tx_enqueue_cfm_list(struct fhost_tx_desc_tag *desc);
358 void fhost_tx_desc_netbuf_free(struct fhost_tx_desc_tag *desc);
359 void fhost_tx_do_sta_add(uint8_t sta_id);
360 void fhost_tx_do_sta_del(uint8_t sta_id);
361 
362 int fhost_tx_sta_ps_enable(uint8_t sta_id, bool enable);
363 void fhost_tx_do_ps_traffic_req(uint8_t sta_id, int req_cnt, enum fhost_tx_ps_type ps_type);
364 void fhost_tx_do_vif_disable(uint8_t vif_idx);
365 void fhost_tx_vif_txq_enable(struct fhost_vif_tag *fhost_vif);
366 void fhost_txq_vif_stop(uint8_t sta_id, uint16_t reason);
367 void fhost_txq_vif_start(uint8_t sta_id, uint16_t reason);
368 
369 int fhost_tx_cntrl_by_timer(uint32_t timeout_ms, uint8_t num);
370 int fhost_stop_tx_cntrl_by_timer();
371 uint8_t fhost_tx_get_to_times(void);
372 int fhost_tx_task_init(void);
373 void fhost_tx_task_deinit(void);
374 
375 #if defined(CONFIG_RWNX_LWIP) && defined(CFG_HOSTIF)
376 int hostif_tx_start(struct hostif_msg *msg);
377 void hostif_tx_deinit(void);
378 int hostif_tx_init(void);
379 #endif /* defined(CONFIG_RWNX_LWIP) && defined(CFG_HOSTIF) */
380 
381 #endif // _WIFI_HOST_TX_H
382 
383