1 /*
2 * Copyright (c) 2013-2021 The Linux Foundation. All rights reserved.
3 * Copyright (c) 2021-2023 Qualcomm Innovation Center, Inc. All rights reserved.
4 *
5 * Permission to use, copy, modify, and/or distribute this software for
6 * any purpose with or without fee is hereby granted, provided that the
7 * above copyright notice and this permission notice appear in all
8 * copies.
9 *
10 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
11 * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
12 * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
13 * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
14 * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
15 * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
16 * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
17 * PERFORMANCE OF THIS SOFTWARE.
18 */
19
20 #if !defined(WLAN_HDD_TX_RX_H)
21 #define WLAN_HDD_TX_RX_H
22
23 /**
24 * DOC: wlan_hdd_tx_rx.h
25 *
26 * Linux HDD Tx/RX APIs
27 */
28
29 #include <wlan_hdd_includes.h>
30 #include <cds_api.h>
31 #include <linux/skbuff.h>
32 #include "cdp_txrx_flow_ctrl_legacy.h"
33 #include <qdf_tracepoint.h>
34 #include <qdf_pkt_add_timestamp.h>
35 #include "wlan_dp_public_struct.h"
36
37 struct hdd_netif_queue_history;
38 struct hdd_context;
39
40 #define hdd_dp_alert(params...) QDF_TRACE_FATAL(QDF_MODULE_ID_HDD_DATA, params)
41 #define hdd_dp_err(params...) QDF_TRACE_ERROR(QDF_MODULE_ID_HDD_DATA, params)
42 #define hdd_dp_warn(params...) QDF_TRACE_WARN(QDF_MODULE_ID_HDD_DATA, params)
43 #define hdd_dp_info(params...) QDF_TRACE_INFO(QDF_MODULE_ID_HDD_DATA, params)
44 #define hdd_dp_debug(params...) QDF_TRACE_DEBUG(QDF_MODULE_ID_HDD_DATA, params)
45
46 #define hdd_dp_nofl_alert(params...) \
47 QDF_TRACE_FATAL_NO_FL(QDF_MODULE_ID_HDD_DATA, params)
48 #define hdd_dp_nofl_err(params...) \
49 QDF_TRACE_ERROR_NO_FL(QDF_MODULE_ID_HDD_DATA, params)
50 #define hdd_dp_nofl_warn(params...) \
51 QDF_TRACE_WARN_NO_FL(QDF_MODULE_ID_HDD_DATA, params)
52 #define hdd_dp_nofl_info(params...) \
53 QDF_TRACE_INFO_NO_FL(QDF_MODULE_ID_HDD_DATA, params)
54 #define hdd_dp_nofl_debug(params...) \
55 QDF_TRACE_DEBUG_NO_FL(QDF_MODULE_ID_HDD_DATA, params)
56
57 #define hdd_dp_alert_rl(params...) \
58 QDF_TRACE_FATAL_RL(QDF_MODULE_ID_HDD_DATA, params)
59 #define hdd_dp_err_rl(params...) \
60 QDF_TRACE_ERROR_RL(QDF_MODULE_ID_HDD_DATA, params)
61 #define hdd_dp_warn_rl(params...) \
62 QDF_TRACE_WARN_RL(QDF_MODULE_ID_HDD_DATA, params)
63 #define hdd_dp_info_rl(params...) \
64 QDF_TRACE_INFO_RL(QDF_MODULE_ID_HDD_DATA, params)
65 #define hdd_dp_debug_rl(params...) \
66 QDF_TRACE_DEBUG_RL(QDF_MODULE_ID_HDD_DATA, params)
67
68 #define hdd_dp_enter() hdd_dp_debug("enter")
69 #define hdd_dp_enter_dev(dev) hdd_dp_debug("enter(%s)", (dev)->name)
70 #define hdd_dp_exit() hdd_dp_debug("exit")
71
72 #define HDD_ETHERTYPE_802_1_X 0x888E
73 #ifdef FEATURE_WLAN_WAPI
74 #define HDD_ETHERTYPE_WAI 0x88b4
75 #define IS_HDD_ETHERTYPE_WAI(_skb) (ntohs(_skb->protocol) == \
76 HDD_ETHERTYPE_WAI)
77 #else
78 #define IS_HDD_ETHERTYPE_WAI(_skb) (false)
79 #endif
80
81 #define HDD_PSB_CFG_INVALID 0xFF
82 #define HDD_PSB_CHANGED 0xFF
83 #define SME_QOS_UAPSD_CFG_BK_CHANGED_MASK 0xF1
84 #define SME_QOS_UAPSD_CFG_BE_CHANGED_MASK 0xF2
85 #define SME_QOS_UAPSD_CFG_VI_CHANGED_MASK 0xF4
86 #define SME_QOS_UAPSD_CFG_VO_CHANGED_MASK 0xF8
87
88 #ifdef CFG80211_CTRL_FRAME_SRC_ADDR_TA_ADDR
89 #define SEND_EAPOL_OVER_NL true
90 #else
91 #define SEND_EAPOL_OVER_NL false
92 #endif
93
94 netdev_tx_t hdd_hard_start_xmit(struct sk_buff *skb, struct net_device *dev);
95
96 /**
97 * hdd_tx_timeout() - Wrapper function to protect __hdd_tx_timeout from SSR
98 * @dev: pointer to net_device structure
99 * @txqueue: tx queue
100 *
101 * Function called by OS if there is any timeout during transmission.
102 * Since HDD simply enqueues packet and returns control to OS right away,
103 * this would never be invoked
104 *
105 * Return: none
106 */
107 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(5, 6, 0))
108 void hdd_tx_timeout(struct net_device *dev, unsigned int txqueue);
109 #else
110 void hdd_tx_timeout(struct net_device *dev);
111 #endif
112
113 #ifdef WLAN_FEATURE_TSF_PLUS_SOCK_TS
114 /**
115 * hdd_tsf_timestamp_rx() - HDD function to set rx packet timestamp
116 * @ctx: pointer to HDD context
117 * @netbuf: pointer to skb
118 *
119 * Return: None
120 */
121 void hdd_tsf_timestamp_rx(hdd_cb_handle ctx, qdf_nbuf_t netbuf);
122
123 /**
124 * hdd_get_tsf_time_cb() - HDD helper function to get TSF time
125 * @netdev: netdev
126 * @input_time: Input time
127 * @tsf_time: time from TFS module
128 *
129 * Return: None
130 */
131 void hdd_get_tsf_time_cb(qdf_netdev_t netdev, uint64_t input_time,
132 uint64_t *tsf_time);
133 #else
134 static inline
hdd_tsf_timestamp_rx(hdd_cb_handle ctx,qdf_nbuf_t netbuf)135 void hdd_tsf_timestamp_rx(hdd_cb_handle ctx, qdf_nbuf_t netbuf) { }
136
137 static inline
hdd_get_tsf_time_cb(qdf_netdev_t netdev,uint64_t input_time,uint64_t * tsf_time)138 void hdd_get_tsf_time_cb(qdf_netdev_t netdev, uint64_t input_time,
139 uint64_t *tsf_time)
140 {
141 }
142 #endif
143
144 /**
145 * hdd_legacy_gro_get_napi() - HDD function to get napi in legacy gro case
146 * @nbuf: n/w buffer pointer
147 * @enable_rxthread: Rx thread enabled/disabled
148 *
149 * Return: qdf napi struct on success, NULL on failure
150 */
151 qdf_napi_struct
152 *hdd_legacy_gro_get_napi(qdf_nbuf_t nbuf, bool enable_rxthread);
153
154 /**
155 * hdd_disable_rx_ol_in_concurrency() - Disable RX Offload in concurrency
156 * for rx
157 * @disable: true if rx offload should be disabled in concurrency
158 *
159 * Return: none
160 */
161 void hdd_disable_rx_ol_in_concurrency(bool disable);
162
163 /**
164 * hdd_tx_queue_cb() - Disable/Enable the Transmit Queues
165 * @hdd_handle: HDD handle
166 * @vdev_id: vdev id
167 * @action: Action to be taken on the Tx Queues
168 * @reason: Reason for the netif action
169 *
170 * Return: None
171 */
172 void hdd_tx_queue_cb(hdd_handle_t hdd_handle, uint32_t vdev_id,
173 enum netif_action_type action,
174 enum netif_reason_type reason);
175
176 #ifdef QCA_LL_LEGACY_TX_FLOW_CONTROL
177 void hdd_tx_resume_cb(void *adapter_context, bool tx_resume);
178
179 /**
180 * hdd_tx_flow_control_is_pause() - Is TX Q paused by flow control
181 * @adapter_context: pointer to vdev apdapter
182 *
183 * Return: true if TX Q is paused by flow control
184 */
185 bool hdd_tx_flow_control_is_pause(void *adapter_context);
186
187 /**
188 * hdd_register_tx_flow_control() - Register TX Flow control
189 * @adapter: adapter handle
190 * @timer_callback: timer callback
191 * @flow_control_fp: txrx flow control
192 * @flow_control_is_pause_fp: is txrx paused by flow control
193 *
194 * Return: none
195 */
196 void hdd_register_tx_flow_control(struct hdd_adapter *adapter,
197 qdf_mc_timer_callback_t timer_callback,
198 ol_txrx_tx_flow_control_fp flow_control_fp,
199 ol_txrx_tx_flow_control_is_pause_fp flow_control_is_pause_fp);
200 void hdd_deregister_tx_flow_control(struct hdd_adapter *adapter);
201
202 /**
203 * hdd_get_tx_resource() - check tx resources and take action
204 * @vdev_id: vdev id mapped to HDD adapter
205 * @mac_addr: mac address
206 *
207 * Return: none
208 */
209 void hdd_get_tx_resource(uint8_t vdev_id,
210 struct qdf_mac_addr *mac_addr);
211
212 /**
213 * hdd_get_tx_flow_low_watermark() - Get TX flow low watermark info
214 * @cb_ctx: HDD opaque ctx
215 * @netdev: netdev
216 *
217 * Return: flow low watermark value
218 */
219 unsigned int
220 hdd_get_tx_flow_low_watermark(hdd_cb_handle cb_ctx, qdf_netdev_t netdev);
221 #else
hdd_tx_resume_cb(void * adapter_context,bool tx_resume)222 static inline void hdd_tx_resume_cb(void *adapter_context, bool tx_resume)
223 {
224 }
hdd_tx_flow_control_is_pause(void * adapter_context)225 static inline bool hdd_tx_flow_control_is_pause(void *adapter_context)
226 {
227 return false;
228 }
hdd_register_tx_flow_control(struct hdd_adapter * adapter,qdf_mc_timer_callback_t timer_callback,ol_txrx_tx_flow_control_fp flow_control_fp,ol_txrx_tx_flow_control_is_pause_fp flow_control_is_pause)229 static inline void hdd_register_tx_flow_control(struct hdd_adapter *adapter,
230 qdf_mc_timer_callback_t timer_callback,
231 ol_txrx_tx_flow_control_fp flow_control_fp,
232 ol_txrx_tx_flow_control_is_pause_fp flow_control_is_pause)
233 {
234 }
hdd_deregister_tx_flow_control(struct hdd_adapter * adapter)235 static inline void hdd_deregister_tx_flow_control(struct hdd_adapter *adapter)
236 {
237 }
238
239 /**
240 * hdd_get_tx_resource() - check tx resources and take action
241 * @vdev_id: vdev id mapped to HDD adapter
242 * @mac_addr: mac address
243 *
244 * Return: none
245 */
246 static inline
hdd_get_tx_resource(uint8_t vdev_id,struct qdf_mac_addr * mac_addr)247 void hdd_get_tx_resource(uint8_t vdev_id,
248 struct qdf_mac_addr *mac_addr) { }
249
250 static inline unsigned int
hdd_get_tx_flow_low_watermark(hdd_cb_handle cb_ctx,qdf_netdev_t netdev)251 hdd_get_tx_flow_low_watermark(hdd_cb_handle cb_ctx, qdf_netdev_t netdev)
252 {
253 return 0;
254 }
255 #endif /* QCA_LL_LEGACY_TX_FLOW_CONTROL */
256
257 #if defined(QCA_LL_LEGACY_TX_FLOW_CONTROL) || \
258 defined(QCA_HL_NETDEV_FLOW_CONTROL)
259 void hdd_tx_resume_timer_expired_handler(void *adapter_context);
260 #else
hdd_tx_resume_timer_expired_handler(void * adapter_context)261 static inline void hdd_tx_resume_timer_expired_handler(void *adapter_context)
262 {
263 }
264 #endif
265
266 #ifdef QCA_HL_NETDEV_FLOW_CONTROL
267 void hdd_register_hl_netdev_fc_timer(struct hdd_adapter *adapter,
268 qdf_mc_timer_callback_t timer_callback);
269 void hdd_deregister_hl_netdev_fc_timer(struct hdd_adapter *adapter);
270 #else
hdd_register_hl_netdev_fc_timer(struct hdd_adapter * adapter,qdf_mc_timer_callback_t timer_callback)271 static inline void hdd_register_hl_netdev_fc_timer(struct hdd_adapter *adapter,
272 qdf_mc_timer_callback_t
273 timer_callback)
274 {}
275
276 static inline void
hdd_deregister_hl_netdev_fc_timer(struct hdd_adapter * adapter)277 hdd_deregister_hl_netdev_fc_timer(struct hdd_adapter *adapter)
278 {}
279 #endif /* QCA_HL_NETDEV_FLOW_CONTROL */
280
281 const char *hdd_reason_type_to_string(enum netif_reason_type reason);
282 const char *hdd_action_type_to_string(enum netif_action_type action);
283
284 void wlan_hdd_netif_queue_control(struct hdd_adapter *adapter,
285 enum netif_action_type action, enum netif_reason_type reason);
286
287 #ifdef FEATURE_MONITOR_MODE_SUPPORT
288 int hdd_set_mon_rx_cb(struct net_device *dev);
289 #else
290 static inline
hdd_set_mon_rx_cb(struct net_device * dev)291 int hdd_set_mon_rx_cb(struct net_device *dev)
292 {
293 return 0;
294 }
295 #endif
296
297 /**
298 * hdd_set_udp_qos_upgrade_config() - Set the threshold for UDP packet
299 * QoS upgrade.
300 * @adapter: adapter for which this configuration is to be applied
301 * @priority: the threshold priority
302 *
303 * Returns: 0 on success, -EINVAL on failure
304 */
305 int hdd_set_udp_qos_upgrade_config(struct hdd_adapter *adapter,
306 uint8_t priority);
307
308 /*
309 * As of the 4.7 kernel, net_device->trans_start is removed. Create shims to
310 * support compiling against older versions of the kernel.
311 */
312 #if (LINUX_VERSION_CODE < KERNEL_VERSION(4, 7, 0))
netif_trans_update(struct net_device * dev)313 static inline void netif_trans_update(struct net_device *dev)
314 {
315 dev->trans_start = jiffies;
316 }
317
318 #define TX_TIMEOUT_TRACE(dev, module_id) QDF_TRACE( \
319 module_id, QDF_TRACE_LEVEL_ERROR, \
320 "%s: Transmission timeout occurred jiffies %lu trans_start %lu", \
321 __func__, jiffies, dev->trans_start)
322 #else
323 #define TX_TIMEOUT_TRACE(dev, module_id) QDF_TRACE( \
324 module_id, QDF_TRACE_LEVEL_ERROR, \
325 "%s: Transmission timeout occurred jiffies %lu", \
326 __func__, jiffies)
327 #endif
328
329 /**
330 * hdd_dp_cfg_update() - update hdd config for HDD DP INIs
331 * @psoc: Pointer to psoc obj
332 * @hdd_ctx: Pointer to hdd context
333 *
334 * Return: None
335 */
336 void hdd_dp_cfg_update(struct wlan_objmgr_psoc *psoc,
337 struct hdd_context *hdd_ctx);
338
339 /**
340 * hdd_print_netdev_txq_status() - print netdev tx queue status
341 * @dev: Pointer to network device
342 *
343 * This function is used to print netdev tx queue status
344 *
345 * Return: None
346 */
347 void hdd_print_netdev_txq_status(struct net_device *dev);
348
349 /**
350 * wlan_hdd_dump_queue_history_state() - Dump hdd queue history states
351 * @q_hist: pointer to hdd queue history structure
352 * @buf: buffer where the queue history string is dumped
353 * @size: size of the buffer
354 *
355 * Dump hdd queue history states into a buffer
356 *
357 * Return: number of bytes written to the buffer
358 */
359 uint32_t
360 wlan_hdd_dump_queue_history_state(struct hdd_netif_queue_history *q_hist,
361 char *buf, uint32_t size);
362
363 #ifdef QCA_LL_LEGACY_TX_FLOW_CONTROL
364 /**
365 * wlan_hdd_set_tx_flow_info() - To set TX flow info
366 *
367 * This routine is called to set TX flow info
368 *
369 * Return: None
370 */
371 void wlan_hdd_set_tx_flow_info(void);
372 #else
wlan_hdd_set_tx_flow_info(void)373 static inline void wlan_hdd_set_tx_flow_info(void)
374 {
375 }
376 #endif
377 #endif /* end #if !defined(WLAN_HDD_TX_RX_H) */
378