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