xref: /wlan-dirver/qca-wifi-host-cmn/htc/htc_internal.h (revision 6d768494e5ce14eb1603a695c86739d12ecc6ec2) !
1 /*
2  * Copyright (c) 2013-2020 The Linux Foundation. All rights reserved.
3  *
4  * Permission to use, copy, modify, and/or distribute this software for
5  * any purpose with or without fee is hereby granted, provided that the
6  * above copyright notice and this permission notice appear in all
7  * copies.
8  *
9  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
10  * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
11  * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
12  * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
13  * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
14  * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
15  * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
16  * PERFORMANCE OF THIS SOFTWARE.
17  */
18 
19 #ifndef _HTC_INTERNAL_H_
20 #define _HTC_INTERNAL_H_
21 
22 #ifdef __cplusplus
23 extern "C" {
24 #endif /* __cplusplus */
25 
26 #include "htc_api.h"
27 #include "htc_packet.h"
28 #include <hif.h>
29 #include <htc.h>
30 #include <qdf_atomic.h>
31 #include <qdf_event.h>
32 #include <qdf_lock.h>
33 #include <qdf_nbuf.h>
34 #include <qdf_timer.h>
35 #include <qdf_types.h>
36 
37 /* HTC operational parameters */
38 #define HTC_TARGET_RESPONSE_TIMEOUT         2000        /* in ms */
39 #define HTC_TARGET_DEBUG_INTR_MASK          0x01
40 #define HTC_TARGET_CREDIT_INTR_MASK         0xF0
41 #define HTC_MIN_MSG_PER_BUNDLE              2
42 
43 #if defined(HIF_USB)
44 
45 #define HTC_MAX_MSG_PER_BUNDLE_RX           11
46 #if defined(CFG_HTC_MAX_MSG_PER_BUNDLE_TX)
47 #define HTC_MAX_MSG_PER_BUNDLE_TX	 CFG_HTC_MAX_MSG_PER_BUNDLE_TX
48 #else
49 #define HTC_MAX_MSG_PER_BUNDLE_TX	8
50 #endif /* CFG_HTC_MAX_MSG_PER_BUNDLE_TX */
51 #else
52 #define HTC_MAX_MSG_PER_BUNDLE_RX           64
53 #define HTC_MAX_MSG_PER_BUNDLE              16
54 #define HTC_MAX_MSG_PER_BUNDLE_TX           32
55 #endif
56 
57 #ifdef HIF_SDIO
58 #define UPDATE_ALT_CREDIT(tar, val) (tar->AltDataCreditSize = (uint16_t) val)
59 #else
60 #define UPDATE_ALT_CREDIT(tar, val) /* no-op */
61 #endif
62 
63 /*
64  * HTC_MAX_TX_BUNDLE_SEND_LIMIT -
65  * This value is in units of tx frame fragments.
66  * It needs to be at least as large as the maximum number of tx frames in a
67  * HTC download bundle times the average number of fragments in each such frame
68  * (In certain operating systems, such as Linux, we expect to only have
69  * a single fragment per frame anyway.)
70  */
71 #define HTC_MAX_TX_BUNDLE_SEND_LIMIT        255
72 
73 #define HTC_PACKET_CONTAINER_ALLOCATION     32
74 #define NUM_CONTROL_TX_BUFFERS              2
75 #define HTC_CONTROL_BUFFER_SIZE             (HTC_MAX_CONTROL_MESSAGE_LENGTH + \
76 					     HTC_HDR_LENGTH)
77 #define HTC_CONTROL_BUFFER_ALIGN            32
78 #define HTC_TARGET_RESPONSE_POLL_MS         10
79 #if !defined(A_SIMOS_DEVHOST)
80 #define HTC_TARGET_MAX_RESPONSE_POLL        200 /* actual HW */
81 #else
82 #define HTC_TARGET_MAX_RESPONSE_POLL        600 /* host + target simulation */
83 #endif
84 
85 #define HTC_SERVICE_TX_PACKET_TAG  HTC_TX_PACKET_TAG_INTERNAL
86 
87 #ifndef HTC_CREDIT_HISTORY_MAX
88 #define HTC_CREDIT_HISTORY_MAX              1024
89 #endif
90 
91 #define HTC_IS_EPPING_ENABLED(_x)           ((_x) == QDF_GLOBAL_EPPING_MODE)
92 
93 enum htc_credit_exchange_type {
94 	HTC_REQUEST_CREDIT,
95 	HTC_PROCESS_CREDIT_REPORT,
96 	HTC_SUSPEND_ACK,
97 	HTC_SUSPEND_NACK,
98 	HTC_INITIAL_WAKE_UP,
99 };
100 
101 static inline const char*
102 htc_credit_exchange_type_str(enum htc_credit_exchange_type type)
103 {
104 	switch (type) {
105 	case HTC_REQUEST_CREDIT:
106 		return "HTC_REQUEST_CREDIT";
107 	case HTC_PROCESS_CREDIT_REPORT:
108 		return "HTC_PROCESS_CREDIT_REPORT";
109 	case HTC_SUSPEND_ACK:
110 		return "HTC_SUSPEND_ACK";
111 	case HTC_SUSPEND_NACK:
112 		return "HTC_SUSPEND_NACK";
113 	case HTC_INITIAL_WAKE_UP:
114 		return "HTC_INITIAL_WAKE_UP";
115 	default:
116 		return "Unknown htc_credit_exchange_type";
117 	}
118 }
119 
120 typedef struct _HTC_ENDPOINT {
121 	HTC_ENDPOINT_ID Id;
122 
123 	/* service ID this endpoint is bound to
124 	 * non-zero value means this endpoint is in use
125 	 */
126 	HTC_SERVICE_ID service_id;
127 
128 	/* callbacks associated with this endpoint */
129 	struct htc_ep_callbacks EpCallBacks;
130 	/* HTC frame buffer TX queue */
131 	HTC_PACKET_QUEUE TxQueue;
132 	/* max depth of the TX queue before calling driver's full handler */
133 	int MaxTxQueueDepth;
134 	/* max length of endpoint message */
135 	int MaxMsgLength;
136 	uint8_t UL_PipeID;
137 	uint8_t DL_PipeID;
138 	/* Need to call HIF to get tx completion callbacks? */
139 	int ul_is_polled;
140 	qdf_timer_t ul_poll_timer;
141 	int ul_poll_timer_active;
142 	int ul_outstanding_cnt;
143 	uint32_t htc_send_cnt;
144 	uint32_t htc_comp_cnt;
145 	/* Need to call HIF to fetch rx?  (Not currently supported.) */
146 	int dl_is_polled;
147 	/* not currently supported */
148 	/* qdf_timer_t dl_poll_timer; */
149 
150 	/* lookup queue to match netbufs to htc packets */
151 	HTC_PACKET_QUEUE TxLookupQueue;
152 	/* temporary hold queue for back compatibility */
153 	HTC_PACKET_QUEUE RxBufferHoldQueue;
154 	/* TX seq no (helpful) for debugging */
155 	uint8_t SeqNo;
156 	/* serialization */
157 	qdf_atomic_t TxProcessCount;
158 	struct _HTC_TARGET *target;
159 	/* TX credits available on this endpoint */
160 	int TxCredits;
161 	/* size in bytes of each credit (set by HTC) */
162 	int TxCreditSize;
163 	/* credits required per max message (precalculated) */
164 	int TxCreditsPerMaxMsg;
165 #ifdef HTC_EP_STAT_PROFILING
166 	/* endpoint statistics */
167 	struct htc_endpoint_stats endpoint_stats;
168 #endif
169 	bool TxCreditFlowEnabled;
170 	bool async_update;  /* packets can be queued asynchronously */
171 	qdf_spinlock_t lookup_queue_lock;
172 
173 	/* number of consecutive requeue attempts used for print */
174 	uint32_t num_requeues_warn;
175 	/* total number of requeue attempts */
176 	uint32_t total_num_requeues;
177 
178 } HTC_ENDPOINT;
179 
180 #ifdef HTC_EP_STAT_PROFILING
181 #define INC_HTC_EP_STAT(p, stat, count) ((p)->endpoint_stats.stat += (count))
182 #else
183 #define INC_HTC_EP_STAT(p, stat, count)
184 #endif
185 
186 struct htc_service_tx_credit_allocation {
187 	uint16_t service_id;
188 	uint8_t CreditAllocation;
189 };
190 
191 #define HTC_MAX_SERVICE_ALLOC_ENTRIES 8
192 
193 /* Error codes for HTC layer packet stats*/
194 enum ol_ath_htc_pkt_ecodes {
195 	/* error- get packet at head of HTC_PACKET_Q */
196 	GET_HTC_PKT_Q_FAIL = 0,
197 	HTC_PKT_Q_EMPTY,
198 	HTC_SEND_Q_EMPTY
199 };
200 /* our HTC target state */
201 typedef struct _HTC_TARGET {
202 	struct hif_opaque_softc *hif_dev;
203 	HTC_ENDPOINT endpoint[ENDPOINT_MAX];
204 	qdf_spinlock_t HTCLock;
205 	qdf_spinlock_t HTCRxLock;
206 	qdf_spinlock_t HTCTxLock;
207 	uint32_t HTCStateFlags;
208 	void *host_handle;
209 	struct htc_init_info HTCInitInfo;
210 	HTC_PACKET *pHTCPacketStructPool; /* pool of HTC packets */
211 	HTC_PACKET_QUEUE ControlBufferTXFreeList;
212 	uint8_t CtrlResponseBuffer[HTC_MAX_CONTROL_MESSAGE_LENGTH];
213 	int CtrlResponseLength;
214 	qdf_event_t ctrl_response_valid;
215 	bool CtrlResponseProcessing;
216 	int TotalTransmitCredits;
217 	struct htc_service_tx_credit_allocation
218 		ServiceTxAllocTable[HTC_MAX_SERVICE_ALLOC_ENTRIES];
219 	int TargetCreditSize;
220 #ifdef RX_SG_SUPPORT
221 	qdf_nbuf_queue_t RxSgQueue;
222 	bool IsRxSgInprogress;
223 	uint32_t CurRxSgTotalLen;               /* current total length */
224 	uint32_t ExpRxSgTotalLen;               /* expected total length */
225 #endif
226 	qdf_device_t osdev;
227 	struct ol_ath_htc_stats htc_pkt_stats;
228 	HTC_PACKET *pBundleFreeList;
229 	uint32_t ce_send_cnt;
230 	uint32_t TX_comp_cnt;
231 	uint8_t MaxMsgsPerHTCBundle;
232 	qdf_work_t queue_kicker;
233 
234 #ifdef HIF_SDIO
235 	uint16_t AltDataCreditSize;
236 #endif
237 	uint32_t avail_tx_credits;
238 #if defined(DEBUG_HL_LOGGING) && defined(CONFIG_HL_SUPPORT)
239 	uint32_t rx_bundle_stats[HTC_MAX_MSG_PER_BUNDLE_RX];
240 	uint32_t tx_bundle_stats[HTC_MAX_MSG_PER_BUNDLE_TX];
241 #endif
242 
243 	uint32_t con_mode;
244 
245 	/*
246 	 * This flag is from the mboxping tool. It indicates that we cannot
247 	 * drop it. Besides, nodrop pkts have higher priority than normal pkts.
248 	 */
249 	A_BOOL is_nodrop_pkt;
250 
251 	/*
252 	 * Number of WMI endpoints used.
253 	 * Default value is 1. But it should be overidden after htc_create to
254 	 * reflect the actual count.
255 	 */
256 	uint8_t wmi_ep_count;
257 	/* Flag to indicate whether htc header length check is required */
258 	bool htc_hdr_length_check;
259 
260 	/* flag to enable packet send debug */
261 	bool htc_pkt_dbg;
262 
263 } HTC_TARGET;
264 
265 
266 #ifdef RX_SG_SUPPORT
267 #define RESET_RX_SG_CONFIG(_target) \
268 do { \
269 	_target->ExpRxSgTotalLen = 0; \
270 	_target->CurRxSgTotalLen = 0; \
271 	_target->IsRxSgInprogress = false; \
272 } while (0)
273 #endif
274 
275 #define HTC_STATE_STOPPING         (1 << 0)
276 #define HTC_STOPPING(t)            ((t)->HTCStateFlags & HTC_STATE_STOPPING)
277 #define LOCK_HTC(t)                qdf_spin_lock_bh(&(t)->HTCLock)
278 #define UNLOCK_HTC(t)              qdf_spin_unlock_bh(&(t)->HTCLock)
279 #define LOCK_HTC_RX(t)             qdf_spin_lock_bh(&(t)->HTCRxLock)
280 #define UNLOCK_HTC_RX(t)           qdf_spin_unlock_bh(&(t)->HTCRxLock)
281 #define LOCK_HTC_TX(t)             qdf_spin_lock_bh(&(t)->HTCTxLock)
282 #define UNLOCK_HTC_TX(t)           qdf_spin_unlock_bh(&(t)->HTCTxLock)
283 #define LOCK_HTC_EP_TX_LOOKUP(t)   qdf_spin_lock_bh(&(t)->lookup_queue_lock)
284 #define UNLOCK_HTC_EP_TX_LOOKUP(t) qdf_spin_unlock_bh(&(t)->lookup_queue_lock)
285 
286 #define GET_HTC_TARGET_FROM_HANDLE(hnd) ((HTC_TARGET *)(hnd))
287 
288 #define IS_TX_CREDIT_FLOW_ENABLED(ep)  ((ep)->TxCreditFlowEnabled)
289 
290 #define HTC_POLL_CLEANUP_PERIOD_MS 10   /* milliseconds */
291 
292 /* Macro to Increment the  HTC_PACKET_ERRORS for Tx.*/
293 #define OL_ATH_HTC_PKT_ERROR_COUNT_INCR(_target, _ecode)	\
294 	do { \
295 		if (_ecode == GET_HTC_PKT_Q_FAIL) \
296 		(_target->htc_pkt_stats.htc_get_pkt_q_fail_count) += 1; \
297 		if (_ecode == HTC_PKT_Q_EMPTY) \
298 		(_target->htc_pkt_stats.htc_pkt_q_empty_count) += 1; \
299 		if (_ecode == HTC_SEND_Q_EMPTY) \
300 		(_target->htc_pkt_stats.htc_send_q_empty_count) += 1; \
301 	} while (0)
302 /* internal HTC functions */
303 
304 QDF_STATUS htc_rx_completion_handler(void *Context, qdf_nbuf_t netbuf,
305 				   uint8_t pipeID);
306 QDF_STATUS htc_tx_completion_handler(void *Context, qdf_nbuf_t netbuf,
307 					unsigned int transferID,
308 					uint32_t toeplitz_hash_result);
309 
310 HTC_PACKET *allocate_htc_bundle_packet(HTC_TARGET *target);
311 void free_htc_bundle_packet(HTC_TARGET *target, HTC_PACKET *pPacket);
312 
313 HTC_PACKET *allocate_htc_packet_container(HTC_TARGET *target);
314 void free_htc_packet_container(HTC_TARGET *target, HTC_PACKET *pPacket);
315 void htc_flush_rx_hold_queue(HTC_TARGET *target, HTC_ENDPOINT *pEndpoint);
316 void htc_flush_endpoint_tx(HTC_TARGET *target, HTC_ENDPOINT *pEndpoint,
317 			   HTC_TX_TAG Tag);
318 
319 /**
320  * htc_flush_endpoint_txlookupQ() - Flush EP's lookup queue
321  * @target: HTC target
322  * @endpoint_id: EP ID
323  * @call_ep_callback: whether to call EP tx completion callback
324  *
325  * Return: void
326  */
327 void htc_flush_endpoint_txlookupQ(HTC_TARGET *target,
328 				  HTC_ENDPOINT_ID endpoint_id,
329 				  bool call_ep_callback);
330 
331 void htc_recv_init(HTC_TARGET *target);
332 QDF_STATUS htc_wait_recv_ctrl_message(HTC_TARGET *target);
333 void htc_free_control_tx_packet(HTC_TARGET *target, HTC_PACKET *pPacket);
334 HTC_PACKET *htc_alloc_control_tx_packet(HTC_TARGET *target);
335 uint8_t htc_get_credit_allocation(HTC_TARGET *target, uint16_t service_id);
336 void htc_tx_resource_avail_handler(void *context, uint8_t pipeID);
337 void htc_control_rx_complete(void *Context, HTC_PACKET *pPacket);
338 void htc_process_credit_rpt(HTC_TARGET *target,
339 			    HTC_CREDIT_REPORT *pRpt,
340 			    int NumEntries, HTC_ENDPOINT_ID FromEndpoint);
341 void htc_fw_event_handler(void *context, QDF_STATUS status);
342 void htc_send_complete_check_cleanup(void *context);
343 #ifdef FEATURE_RUNTIME_PM
344 void htc_kick_queues(void *context);
345 #endif
346 
347 static inline void htc_send_complete_poll_timer_stop(HTC_ENDPOINT *
348 						     pEndpoint) {
349 	LOCK_HTC_TX(pEndpoint->target);
350 	if (pEndpoint->ul_poll_timer_active) {
351 		/* qdf_timer_stop(&pEndpoint->ul_poll_timer); */
352 		pEndpoint->ul_poll_timer_active = 0;
353 	}
354 	UNLOCK_HTC_TX(pEndpoint->target);
355 }
356 
357 static inline void htc_send_complete_poll_timer_start(HTC_ENDPOINT *
358 						      pEndpoint) {
359 	LOCK_HTC_TX(pEndpoint->target);
360 	if (pEndpoint->ul_outstanding_cnt
361 	    && !pEndpoint->ul_poll_timer_active) {
362 		/* qdf_timer_start(
363 		 * &pEndpoint->ul_poll_timer, HTC_POLL_CLEANUP_PERIOD_MS);
364 		 */
365 		pEndpoint->ul_poll_timer_active = 1;
366 	}
367 	UNLOCK_HTC_TX(pEndpoint->target);
368 }
369 
370 static inline void
371 htc_send_complete_check(HTC_ENDPOINT *pEndpoint, int force) {
372 	/*
373 	 * Stop the polling-cleanup timer that will result in a later call to
374 	 * this function.  It may get started again below, if there are still
375 	 * outsending sends.
376 	 */
377 	htc_send_complete_poll_timer_stop(pEndpoint);
378 	/*
379 	 * Check whether HIF has any prior sends that have finished,
380 	 * have not had the post-processing done.
381 	 */
382 	hif_send_complete_check(pEndpoint->target->hif_dev,
383 				pEndpoint->UL_PipeID, force);
384 	/*
385 	 * If there are still outstanding sends after polling, start a timer
386 	 * to check again a little later.
387 	 */
388 	htc_send_complete_poll_timer_start(pEndpoint);
389 }
390 
391 #ifdef __cplusplus
392 }
393 #endif
394 
395 #ifndef DEBUG_BUNDLE
396 #define DEBUG_BUNDLE 0
397 #endif
398 
399 #if defined(HIF_SDIO) || defined(HIF_USB)
400 #ifndef ENABLE_BUNDLE_TX
401 #define ENABLE_BUNDLE_TX 1
402 #endif
403 
404 #ifndef ENABLE_BUNDLE_RX
405 #define ENABLE_BUNDLE_RX 1
406 #endif
407 #endif /*defined(HIF_SDIO) || defined(HIF_USB)*/
408 
409 #if defined ENABLE_BUNDLE_TX
410 #define HTC_TX_BUNDLE_ENABLED(target) (target->MaxMsgsPerHTCBundle > 1)
411 #else
412 #define HTC_TX_BUNDLE_ENABLED(target) 0
413 #endif
414 
415 #if defined ENABLE_BUNDLE_RX
416 #define HTC_RX_BUNDLE_ENABLED(target) (target->MaxMsgsPerHTCBundle > 1)
417 #else
418 #define HTC_RX_BUNDLE_ENABLED(target) 0
419 #endif
420 
421 #define HTC_ENABLE_BUNDLE(target) (target->MaxMsgsPerHTCBundle > 1)
422 
423 #endif /* !_HTC_HOST_INTERNAL_H_ */
424