1 /** @file mlan_wmm.h
2  *
3  *  @brief This file contains related macros, enum, and struct
4  *  of wmm functionalities
5  *
6  *  Copyright 2008-2024 NXP
7  *
8  *  SPDX-License-Identifier: BSD-3-Clause
9  *
10  */
11 
12 /****************************************************
13 Change log:
14     10/24/2008: initial version
15 ****************************************************/
16 
17 #ifndef _MLAN_WMM_H_
18 #define _MLAN_WMM_H_
19 
20 /**
21  *  @brief This function gets the TID
22  *
23  *  @param pmadapter    A pointer to mlan_adapter structure
24  *  @param ptr          A pointer to RA list table
25  *
26  *  @return 	    TID
27  */
wlan_get_tid(pmlan_adapter pmadapter,raListTbl * ptr)28 static INLINE int wlan_get_tid(pmlan_adapter pmadapter, raListTbl *ptr)
29 {
30     pmlan_buffer mbuf;
31 
32     ENTER();
33     mbuf = (pmlan_buffer)(void *)util_peek_list(pmadapter->pmoal_handle, &ptr->buf_head, MNULL, MNULL);
34     LEAVE();
35 
36     return mbuf->priority;
37 }
38 
39 /**
40  *  @brief This function gets the length of a list
41  *
42  *  @param pmadapter    A pointer to mlan_adapter structure
43  *  @param head         A pointer to mlan_list_head
44  *
45  *  @return 	    Length of list
46  */
wlan_wmm_list_len(pmlan_adapter pmadapter,pmlan_list_head head)47 static INLINE int wlan_wmm_list_len(pmlan_adapter pmadapter, pmlan_list_head head)
48 {
49     pmlan_linked_list pos;
50     int count = 0;
51 
52     ENTER();
53 
54     pos = head->pnext;
55 
56     while (pos != (pmlan_linked_list)(void *)head)
57     {
58         ++count;
59         pos = pos->pnext;
60     }
61 
62     LEAVE();
63     return count;
64 }
65 
66 /**
67  *  @brief This function requests a ralist lock
68  *
69  *  @param priv         A pointer to mlan_private structure
70  *
71  *  @return             N/A
72  */
wlan_request_ralist_lock(pmlan_private priv)73 static INLINE t_void wlan_request_ralist_lock(pmlan_private priv)
74 {
75     ENTER();
76 
77     OSA_MutexLock((osa_mutex_handle_t)priv->tx_ba_stream_tbl_lock, osaWaitForever_c);
78 
79     LEAVE();
80     return;
81 }
82 
83 /**
84  *  @brief This function releases a lock on ralist
85  *
86  *  @param priv         A pointer to mlan_private structure
87  *
88  *  @return             N/A
89  */
wlan_release_ralist_lock(pmlan_private priv)90 static INLINE t_void wlan_release_ralist_lock(pmlan_private priv)
91 {
92     ENTER();
93 
94     OSA_MutexUnlock((osa_mutex_handle_t)priv->tx_ba_stream_tbl_lock);
95 
96     LEAVE();
97     return;
98 }
99 
100 /** Add buffer to WMM Tx queue */
101 void wlan_wmm_add_buf_txqueue(pmlan_adapter pmadapter, pmlan_buffer pmbuf);
102 /** Add to RA list */
103 void wlan_ralist_add(mlan_private *priv, t_u8 *ra);
104 /** Update the RA list */
105 int wlan_ralist_update(mlan_private *priv, t_u8 *old_ra, t_u8 *new_ra);
106 #ifdef STA_SUPPORT
107 /** WMM status change command handler */
108 mlan_status wlan_cmd_wmm_status_change(pmlan_private priv);
109 #endif /* STA_SUPPORT */
110 /** Check if WMM lists are empty */
111 int wlan_wmm_lists_empty(pmlan_adapter pmadapter);
112 /** Process WMM transmission */
113 t_void wlan_wmm_process_tx(pmlan_adapter pmadapter);
114 /** Test to see if the ralist ptr is valid */
115 int wlan_is_ralist_valid(mlan_private *priv, raListTbl *ra_list, int tid);
116 raListTbl *wlan_wmm_get_ralist_node(pmlan_private priv, t_u8 tid, t_u8 *ra_addr);
117 t_u8 wlan_get_random_ba_threshold(pmlan_adapter pmadapter);
118 
119 /** Compute driver packet delay */
120 t_u8 wlan_wmm_compute_driver_packet_delay(pmlan_private priv, const pmlan_buffer pmbuf);
121 /** Initialize WMM */
122 t_void wlan_wmm_init(pmlan_adapter pmadapter);
123 /** Initialize WMM paramter */
124 t_void wlan_init_wmm_param(pmlan_adapter pmadapter);
125 /** Setup WMM queues */
126 extern void wlan_wmm_setup_queues(pmlan_private priv);
127 /* Setup default queues */
128 void wlan_wmm_default_queue_priorities(pmlan_private priv);
129 
130 #ifdef STA_SUPPORT
131 /** Process WMM association request */
132 extern t_u32 wlan_wmm_process_association_req(pmlan_private priv,
133                                               t_u8 **ppAssocBuf,
134                                               IEEEtypes_WmmParameter_t *pWmmIE,
135                                               IEEEtypes_HTCap_t *pHTCap);
136 #endif /* STA_SUPPORT */
137 
138 /** setup wmm queue priorities */
139 void wlan_wmm_setup_queue_priorities(pmlan_private priv, IEEEtypes_WmmParameter_t *wmm_ie);
140 
141 /** Downgrade WMM priority queue */
142 void wlan_wmm_setup_ac_downgrade(pmlan_private priv);
143 /** select WMM queue */
144 t_u8 wlan_wmm_select_queue(mlan_private *pmpriv, t_u8 tid);
145 #ifdef UAP_SUPPORT
146 t_void wlan_wmm_delete_peer_ralist(pmlan_private priv, t_u8 *mac);
147 #endif
148 
149 /** WMM TS_STATUS command handler */
150 extern mlan_status wlan_cmd_wmm_ts_status(IN pmlan_private pmpriv, OUT HostCmd_DS_COMMAND *cmd, IN t_void *pdata_buf);
151 /** WMM ADDTS request command response handler */
152 extern mlan_status wlan_ret_wmm_addts_req(IN pmlan_private pmpriv,
153                                           const IN HostCmd_DS_COMMAND *resp,
154                                           OUT mlan_ioctl_req *pioctl_buf);
155 /** WMM DELTS request command response handler */
156 extern mlan_status wlan_ret_wmm_delts_req(IN pmlan_private pmpriv,
157                                           const IN HostCmd_DS_COMMAND *resp,
158                                           OUT mlan_ioctl_req *pioctl_buf);
159 #ifdef STA_SUPPORT
160 /*
161  *  Functions used in the cmd handling routine
162  */
163 /** WMM ADDTS request command handler */
164 extern mlan_status wlan_cmd_wmm_addts_req(IN pmlan_private pmpriv, OUT HostCmd_DS_COMMAND *cmd, IN t_void *pdata_buf);
165 /** WMM QUEUE_STATS command handler */
166 extern mlan_status wlan_cmd_wmm_queue_stats(IN pmlan_private pmpriv, OUT HostCmd_DS_COMMAND *cmd, IN t_void *pdata_buf);
167 /** WMM QUEUE_CONFIG command handler */
168 extern mlan_status wlan_cmd_wmm_queue_config(IN pmlan_private pmpriv,
169                                              OUT HostCmd_DS_COMMAND *cmd,
170                                              IN t_void *pdata_buf);
171 /** WMM get status command response handler */
172 extern mlan_status wlan_ret_wmm_get_status(IN pmlan_private priv, IN t_u8 *ptlv, IN int resp_len);
173 /** WMM TS_STATUS command response handler */
174 extern mlan_status wlan_ret_wmm_ts_status(IN pmlan_private pmpriv,
175                                           IN HostCmd_DS_COMMAND *resp,
176                                           OUT mlan_ioctl_req *pioctl_buf);
177 /** WMM QUEUE_CONFIG command response handler */
178 extern mlan_status wlan_ret_wmm_queue_config(IN pmlan_private pmpriv,
179                                              const IN HostCmd_DS_COMMAND *resp,
180                                              OUT mlan_ioctl_req *pioctl_buf);
181 /** WMM QUEUE_STATS command response handler */
182 extern mlan_status wlan_ret_wmm_queue_stats(IN pmlan_private pmpriv,
183                                             const IN HostCmd_DS_COMMAND *resp,
184                                             OUT mlan_ioctl_req *pioctl_buf);
185 /** WMM DELTS request command handler */
186 extern mlan_status wlan_cmd_wmm_delts_req(IN pmlan_private pmpriv, OUT HostCmd_DS_COMMAND *cmd, IN t_void *pdata_buf);
187 
188 #endif /* STA_SUPPORT */
189 
190 #ifdef UAP_SUPPORT
191 t_void wlan_wmm_delete_peer_ralist(pmlan_private priv, t_u8 *mac);
192 #endif
193 
194 /* process wmm_param_config command */
195 mlan_status wlan_cmd_wmm_param_config(pmlan_private pmpriv,
196                                       HostCmd_DS_COMMAND *cmd,
197                                       t_u8 cmd_action,
198                                       t_void *pdata_buf);
199 
200 /* process wmm_param_config command response */
201 mlan_status wlan_ret_wmm_param_config(pmlan_private pmpriv, const HostCmd_DS_COMMAND *resp, mlan_ioctl_req *pioctl_buf);
202 
203 #if CONFIG_WMM
204 /* wmm enhance buffer pool */
205 #define MAX_WMM_BUF_NUM 16
206 #define WMM_DATA_LEN    1580
207 #define OUTBUF_WMM_LEN  (sizeof(outbuf_t))
208 
209 typedef struct
210 {
211     mlan_linked_list entry;
212     t_u8 intf_header[INTF_HEADER_LEN];
213     TxPD tx_pd;
214 #if CONFIG_TX_RX_ZERO_COPY
215     t_u8 eth_header[ETH_HDR_LEN];
216 #if CONFIG_AMSDU_IN_AMPDU
217     t_u8 llc_header[LLC_SNAP_LEN];
218 #endif
219     /* Data payload pointer */
220     t_u8 *payload;
221     /* Packet buffer structure pointer */
222     void *buffer;
223 #else
224     t_u8 data[WMM_DATA_LEN];
225 #endif
226 } outbuf_t;
227 
228 typedef struct
229 {
230     mlan_linked_list entry;
231     t_u8 intf_header[INTF_HEADER_LEN];
232     TxPD tx_pd;
233     t_u8 data[1];
234 } bypass_outbuf_t;
235 
236 /* transfer destination address to receive address */
237 void wifi_wmm_da_to_ra(uint8_t *da, uint8_t *ra);
238 
239 /* wmm enhance get free buffer */
240 uint8_t *wifi_wmm_get_outbuf_enh(
241     uint32_t *outbuf_len, mlan_wmm_ac_e queue, const uint8_t interface, uint8_t *ra, bool *is_tx_pause);
242 
243 /* wmm enhance enqueue tx buffer */
244 int wlan_wmm_add_buf_txqueue_enh(const uint8_t interface, const uint8_t *buffer, const uint16_t len, uint8_t pkt_prio);
245 
246 /* wmm enhance buffer pool management */
247 outbuf_t *wifi_wmm_buf_get(void);
248 void wifi_wmm_buf_put(outbuf_t *buf);
249 int wifi_wmm_buf_pool_init(uint8_t *pool);
250 void wifi_wmm_buf_pool_deinit(void);
251 
252 /* wmm enhance ralist operation */
253 void wlan_ralist_add_enh(mlan_private *priv, t_u8 *ra);
254 int wlan_ralist_update_enh(mlan_private *priv, t_u8 *old_ra, t_u8 *new_ra);
255 void wlan_ralist_pkts_free_enh(mlan_private *priv, raListTbl *ra_list, t_u8 ac);
256 void wlan_ralist_del_enh(mlan_private *priv, t_u8 *ra);
257 void wlan_ralist_del_all_enh(mlan_private *priv);
258 void wlan_ralist_deinit_enh(mlan_private *priv);
259 
260 /* debug statistics */
261 void wifi_wmm_drop_err_mem(const uint8_t interface);
262 void wifi_wmm_drop_no_media(const uint8_t interface);
263 void wifi_wmm_drop_retried_drop(const uint8_t interface);
264 void wifi_wmm_drop_pause_drop(const uint8_t interface);
265 void wifi_wmm_drop_pause_replaced(const uint8_t interface);
266 
267 int wifi_bypass_txq_init(void);
268 void wifi_bypass_txq_deinit(void);
269 void wlan_get_bypass_lock(uint8_t interface);
270 void wlan_put_bypass_lock(uint8_t interface);
271 void wlan_add_buf_bypass_txq(const uint8_t *buffer, const uint8_t interface);
272 t_u8 wlan_bypass_txq_empty(uint8_t interface);
273 void wlan_cleanup_bypass_txq(uint8_t interface);
274 #endif
275 
276 #endif /* !_MLAN_WMM_H_ */
277