blob: 8d817c7e3baa40c202b428a76bd54eb1b1c2be52 [file] [log] [blame]
Prakash Dhavalid5c9f1c2015-11-08 19:04:44 -08001/*
Houston Hoffman47e387b2015-10-20 17:04:42 -07002 * Copyright (c) 2013-2016 The Linux Foundation. All rights reserved.
Prakash Dhavalid5c9f1c2015-11-08 19:04:44 -08003 *
4 * Previously licensed under the ISC license by Qualcomm Atheros, Inc.
5 *
6 *
7 * Permission to use, copy, modify, and/or distribute this software for
8 * any purpose with or without fee is hereby granted, provided that the
9 * above copyright notice and this permission notice appear in all
10 * copies.
11 *
12 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
13 * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
14 * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
15 * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
16 * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
17 * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
18 * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
19 * PERFORMANCE OF THIS SOFTWARE.
20 */
21
22/*
23 * This file was originally distributed by Qualcomm Atheros, Inc.
24 * under proprietary terms before Copyright ownership was assigned
25 * to the Linux Foundation.
26 */
27
28#ifndef _HTC_INTERNAL_H_
29#define _HTC_INTERNAL_H_
30
31#ifdef __cplusplus
32extern "C" {
33#endif /* __cplusplus */
34
Vishwajith Upendra70f8b6e2016-03-01 16:28:23 +053035#include <qdf_nbuf.h>
Chouhan, Anuragfc06aa92016-03-03 19:05:05 +053036#include <qdf_types.h>
37#include <qdf_lock.h>
38#include <qdf_timer.h>
39#include <qdf_atomic.h>
Prakash Dhavalid5c9f1c2015-11-08 19:04:44 -080040#include "hif.h"
41#include <htc.h>
42#include "htc_api.h"
43#include "htc_packet.h"
44
45/* HTC operational parameters */
46#define HTC_TARGET_RESPONSE_TIMEOUT 2000 /* in ms */
47#define HTC_TARGET_DEBUG_INTR_MASK 0x01
48#define HTC_TARGET_CREDIT_INTR_MASK 0xF0
49#define HTC_MIN_MSG_PER_BUNDLE 2
50#if defined(HIF_USB)
51#define HTC_MAX_MSG_PER_BUNDLE 9
52#else
53#define HTC_MAX_MSG_PER_BUNDLE 16
54#endif
55/*
56 * HTC_MAX_TX_BUNDLE_SEND_LIMIT -
57 * This value is in units of tx frame fragments.
58 * It needs to be at least as large as the maximum number of tx frames in a
59 * HTC download bundle times the average number of fragments in each such frame
60 * (In certain operating systems, such as Linux, we expect to only have
61 * a single fragment per frame anyway.)
62 */
63#define HTC_MAX_TX_BUNDLE_SEND_LIMIT 255
64
65#define HTC_PACKET_CONTAINER_ALLOCATION 32
66#define NUM_CONTROL_TX_BUFFERS 2
67#define HTC_CONTROL_BUFFER_SIZE (HTC_MAX_CONTROL_MESSAGE_LENGTH + HTC_HDR_LENGTH)
68#define HTC_CONTROL_BUFFER_ALIGN 32
69#define HTC_TARGET_RESPONSE_POLL_MS 10
70#if !defined(A_SIMOS_DEVHOST)
71#define HTC_TARGET_MAX_RESPONSE_POLL 200 /* actual HW */
72#else
73#define HTC_TARGET_MAX_RESPONSE_POLL 600 /* host + target simulation */
74#endif
75
76#define HTC_SERVICE_TX_PACKET_TAG HTC_TX_PACKET_TAG_INTERNAL
77
78#define HTC_CREDIT_HISTORY_MAX 1024
79
80typedef enum {
81 HTC_REQUEST_CREDIT,
82 HTC_PROCESS_CREDIT_REPORT,
83 HTC_SUSPEND_ACK,
84 HTC_SUSPEND_NACK,
85} htc_credit_exchange_type;
86
87typedef struct {
88 htc_credit_exchange_type type;
89 uint64_t time;
90 uint32_t tx_credit;
91 uint32_t htc_tx_queue_depth;
92} HTC_CREDIT_HISTORY;
93
94typedef struct _HTC_ENDPOINT {
95 HTC_ENDPOINT_ID Id;
Houston Hoffman4f2f4592015-10-20 18:00:29 -070096
97 /* service ID this endpoint is bound to
98 * non-zero value means this endpoint is in use
99 */
100 HTC_SERVICE_ID service_id;
101
Prakash Dhavalid5c9f1c2015-11-08 19:04:44 -0800102 HTC_EP_CALLBACKS EpCallBacks; /* callbacks associated with this endpoint */
103 HTC_PACKET_QUEUE TxQueue; /* HTC frame buffer TX queue */
104 int MaxTxQueueDepth; /* max depth of the TX queue before we need to
Chouhan, Anuragfc06aa92016-03-03 19:05:05 +0530105 call driver's full handler */
Prakash Dhavalid5c9f1c2015-11-08 19:04:44 -0800106 int MaxMsgLength; /* max length of endpoint message */
107 uint8_t UL_PipeID;
108 uint8_t DL_PipeID;
109 int ul_is_polled; /* Need to call HIF to get tx completion callbacks? */
Chouhan, Anuragfc06aa92016-03-03 19:05:05 +0530110 qdf_timer_t ul_poll_timer;
Prakash Dhavalid5c9f1c2015-11-08 19:04:44 -0800111 int ul_poll_timer_active;
112 int ul_outstanding_cnt;
113 int dl_is_polled; /* Need to call HIF to fetch rx? (Not currently supported.) */
114#if 0 /* not currently supported */
Chouhan, Anuragfc06aa92016-03-03 19:05:05 +0530115 qdf_timer_t dl_poll_timer;
Prakash Dhavalid5c9f1c2015-11-08 19:04:44 -0800116#endif
117
118 HTC_PACKET_QUEUE TxLookupQueue; /* lookup queue to match netbufs to htc packets */
119 HTC_PACKET_QUEUE RxBufferHoldQueue; /* temporary hold queue for back compatibility */
120 A_UINT8 SeqNo; /* TX seq no (helpful) for debugging */
Chouhan, Anuragfc06aa92016-03-03 19:05:05 +0530121 qdf_atomic_t TxProcessCount; /* serialization */
Prakash Dhavalid5c9f1c2015-11-08 19:04:44 -0800122 struct _HTC_TARGET *target;
123 int TxCredits; /* TX credits available on this endpoint */
124 int TxCreditSize; /* size in bytes of each credit (set by HTC) */
125 int TxCreditsPerMaxMsg; /* credits required per max message (precalculated) */
126#ifdef HTC_EP_STAT_PROFILING
Houston Hoffman29573d92015-10-20 17:49:44 -0700127 HTC_ENDPOINT_STATS endpoint_stats; /* endpoint statistics */
Prakash Dhavalid5c9f1c2015-11-08 19:04:44 -0800128#endif
129 A_BOOL TxCreditFlowEnabled;
130} HTC_ENDPOINT;
131
132#ifdef HTC_EP_STAT_PROFILING
Houston Hoffman29573d92015-10-20 17:49:44 -0700133#define INC_HTC_EP_STAT(p, stat, count) ((p)->endpoint_stats.stat += (count))
Prakash Dhavalid5c9f1c2015-11-08 19:04:44 -0800134#else
Houston Hoffman29573d92015-10-20 17:49:44 -0700135#define INC_HTC_EP_STAT(p, stat, count)
Prakash Dhavalid5c9f1c2015-11-08 19:04:44 -0800136#endif
137
138typedef struct {
Houston Hoffman4f2f4592015-10-20 18:00:29 -0700139 A_UINT16 service_id;
Prakash Dhavalid5c9f1c2015-11-08 19:04:44 -0800140 A_UINT8 CreditAllocation;
141} HTC_SERVICE_TX_CREDIT_ALLOCATION;
142
143#define HTC_MAX_SERVICE_ALLOC_ENTRIES 8
144
145/* Error codes for HTC layer packet stats*/
146enum ol_ath_htc_pkt_ecodes {
147 GET_HTC_PKT_Q_FAIL = 0, /* error- get packet at head of HTC_PACKET_Q */
148 HTC_PKT_Q_EMPTY,
149 HTC_SEND_Q_EMPTY
150};
151/* our HTC target state */
152typedef struct _HTC_TARGET {
Komal Seelam5584a7c2016-02-24 19:22:48 +0530153 struct hif_opaque_softc *hif_dev;
Houston Hoffman29573d92015-10-20 17:49:44 -0700154 HTC_ENDPOINT endpoint[ENDPOINT_MAX];
Chouhan, Anuragfc06aa92016-03-03 19:05:05 +0530155 qdf_spinlock_t HTCLock;
156 qdf_spinlock_t HTCRxLock;
157 qdf_spinlock_t HTCTxLock;
158 qdf_spinlock_t HTCCreditLock;
Prakash Dhavalid5c9f1c2015-11-08 19:04:44 -0800159 A_UINT32 HTCStateFlags;
160 void *host_handle;
161 HTC_INIT_INFO HTCInitInfo;
162 HTC_PACKET *pHTCPacketStructPool; /* pool of HTC packets */
163 HTC_PACKET_QUEUE ControlBufferTXFreeList;
164 A_UINT8 CtrlResponseBuffer[HTC_MAX_CONTROL_MESSAGE_LENGTH];
165 int CtrlResponseLength;
Chouhan, Anuragfc06aa92016-03-03 19:05:05 +0530166 qdf_event_t ctrl_response_valid;
Prakash Dhavalid5c9f1c2015-11-08 19:04:44 -0800167 A_BOOL CtrlResponseProcessing;
168 int TotalTransmitCredits;
169 HTC_SERVICE_TX_CREDIT_ALLOCATION
170 ServiceTxAllocTable[HTC_MAX_SERVICE_ALLOC_ENTRIES];
171 int TargetCreditSize;
172#ifdef RX_SG_SUPPORT
Vishwajith Upendra70f8b6e2016-03-01 16:28:23 +0530173 qdf_nbuf_queue_t RxSgQueue;
Prakash Dhavalid5c9f1c2015-11-08 19:04:44 -0800174 A_BOOL IsRxSgInprogress;
175 A_UINT32 CurRxSgTotalLen; /* current total length */
176 A_UINT32 ExpRxSgTotalLen; /* expected total length */
177#endif
Chouhan, Anuragfc06aa92016-03-03 19:05:05 +0530178 qdf_device_t osdev;
Prakash Dhavalid5c9f1c2015-11-08 19:04:44 -0800179 struct ol_ath_htc_stats htc_pkt_stats;
180 HTC_PACKET *pBundleFreeList;
181 A_UINT32 ce_send_cnt;
182 A_UINT32 TX_comp_cnt;
183 A_UINT8 MaxMsgsPerHTCBundle;
Chouhan, Anuragfc06aa92016-03-03 19:05:05 +0530184 qdf_work_t queue_kicker;
Prakash Dhavalid5c9f1c2015-11-08 19:04:44 -0800185} HTC_TARGET;
186
187#define HTC_ENABLE_BUNDLE(target) (target->MaxMsgsPerHTCBundle > 1)
188#ifdef RX_SG_SUPPORT
189#define RESET_RX_SG_CONFIG(_target) \
190 _target->ExpRxSgTotalLen = 0; \
191 _target->CurRxSgTotalLen = 0; \
192 _target->IsRxSgInprogress = false;
193#endif
194
195#define HTC_STATE_STOPPING (1 << 0)
196#define HTC_STOPPING(t) ((t)->HTCStateFlags & HTC_STATE_STOPPING)
Chouhan, Anuragfc06aa92016-03-03 19:05:05 +0530197#define LOCK_HTC(t) qdf_spin_lock_bh(&(t)->HTCLock);
198#define UNLOCK_HTC(t) qdf_spin_unlock_bh(&(t)->HTCLock);
199#define LOCK_HTC_RX(t) qdf_spin_lock_bh(&(t)->HTCRxLock);
200#define UNLOCK_HTC_RX(t) qdf_spin_unlock_bh(&(t)->HTCRxLock);
201#define LOCK_HTC_TX(t) qdf_spin_lock_bh(&(t)->HTCTxLock);
202#define UNLOCK_HTC_TX(t) qdf_spin_unlock_bh(&(t)->HTCTxLock);
203#define LOCK_HTC_CREDIT(t) qdf_spin_lock_bh(&(t)->HTCCreditLock);
204#define UNLOCK_HTC_CREDIT(t) qdf_spin_unlock_bh(&(t)->HTCCreditLock);
Prakash Dhavalid5c9f1c2015-11-08 19:04:44 -0800205
206#define GET_HTC_TARGET_FROM_HANDLE(hnd) ((HTC_TARGET *)(hnd))
207
208#define IS_TX_CREDIT_FLOW_ENABLED(ep) ((ep)->TxCreditFlowEnabled)
209
210#define HTC_POLL_CLEANUP_PERIOD_MS 10 /* milliseconds */
211
212/* Macro to Increment the HTC_PACKET_ERRORS for Tx.*/
Chouhan, Anuragfc06aa92016-03-03 19:05:05 +0530213#define OL_ATH_HTC_PKT_ERROR_COUNT_INCR(_target, _ecode) \
Prakash Dhavalid5c9f1c2015-11-08 19:04:44 -0800214 do { \
Chouhan, Anuragfc06aa92016-03-03 19:05:05 +0530215 if (_ecode == GET_HTC_PKT_Q_FAIL) \
216 (_target->htc_pkt_stats.htc_get_pkt_q_fail_count) += 1 \
217 ; \
218 if (_ecode == HTC_PKT_Q_EMPTY) \
219 (_target->htc_pkt_stats.htc_pkt_q_empty_count) += 1 \
220 ; \
221 if (_ecode == HTC_SEND_Q_EMPTY) \
222 (_target->htc_pkt_stats.htc_send_q_empty_count) += 1 \
223 ; \
224 } while (0);
Prakash Dhavalid5c9f1c2015-11-08 19:04:44 -0800225/* internal HTC functions */
226
Vishwajith Upendra70f8b6e2016-03-01 16:28:23 +0530227QDF_STATUS htc_rx_completion_handler(void *Context, qdf_nbuf_t netbuf,
Prakash Dhavalid5c9f1c2015-11-08 19:04:44 -0800228 uint8_t pipeID);
Vishwajith Upendra70f8b6e2016-03-01 16:28:23 +0530229QDF_STATUS htc_tx_completion_handler(void *Context, qdf_nbuf_t netbuf,
Prakash Dhavalid5c9f1c2015-11-08 19:04:44 -0800230 unsigned int transferID, uint32_t toeplitz_hash_result);
231
232HTC_PACKET *allocate_htc_bundle_packet(HTC_TARGET *target);
233void free_htc_bundle_packet(HTC_TARGET *target, HTC_PACKET *pPacket);
234
235HTC_PACKET *allocate_htc_packet_container(HTC_TARGET *target);
236void free_htc_packet_container(HTC_TARGET *target, HTC_PACKET *pPacket);
237void htc_flush_rx_hold_queue(HTC_TARGET *target, HTC_ENDPOINT *pEndpoint);
238void htc_flush_endpoint_tx(HTC_TARGET *target, HTC_ENDPOINT *pEndpoint,
239 HTC_TX_TAG Tag);
240void htc_recv_init(HTC_TARGET *target);
241A_STATUS htc_wait_recv_ctrl_message(HTC_TARGET *target);
242void htc_free_control_tx_packet(HTC_TARGET *target, HTC_PACKET *pPacket);
243HTC_PACKET *htc_alloc_control_tx_packet(HTC_TARGET *target);
Houston Hoffman4f2f4592015-10-20 18:00:29 -0700244A_UINT8 htc_get_credit_allocation(HTC_TARGET *target, A_UINT16 service_id);
Prakash Dhavalid5c9f1c2015-11-08 19:04:44 -0800245void htc_tx_resource_avail_handler(void *context, A_UINT8 pipeID);
246void htc_control_rx_complete(void *Context, HTC_PACKET *pPacket);
247void htc_process_credit_rpt(HTC_TARGET *target,
248 HTC_CREDIT_REPORT *pRpt,
249 int NumEntries, HTC_ENDPOINT_ID FromEndpoint);
Chouhan, Anuragfc06aa92016-03-03 19:05:05 +0530250void htc_fw_event_handler(void *context, QDF_STATUS status);
Prakash Dhavalid5c9f1c2015-11-08 19:04:44 -0800251void htc_send_complete_check_cleanup(void *context);
Houston Hoffman47e387b2015-10-20 17:04:42 -0700252void htc_runtime_pm_init(HTC_TARGET *target);
253void htc_kick_queues(void *context);
Prakash Dhavalid5c9f1c2015-11-08 19:04:44 -0800254
255void htc_credit_record(htc_credit_exchange_type type, uint32_t tx_credit,
256 uint32_t htc_tx_queue_depth);
257
258static inline void htc_send_complete_poll_timer_stop(HTC_ENDPOINT *
259 pEndpoint) {
260 LOCK_HTC_TX(pEndpoint->target);
261 if (pEndpoint->ul_poll_timer_active) {
Chouhan, Anuragfc06aa92016-03-03 19:05:05 +0530262 /* qdf_timer_stop(&pEndpoint->ul_poll_timer); */
Prakash Dhavalid5c9f1c2015-11-08 19:04:44 -0800263 pEndpoint->ul_poll_timer_active = 0;
264 }
265 UNLOCK_HTC_TX(pEndpoint->target);
266}
267
268static inline void htc_send_complete_poll_timer_start(HTC_ENDPOINT *
269 pEndpoint) {
270 LOCK_HTC_TX(pEndpoint->target);
271 if (pEndpoint->ul_outstanding_cnt
272 && !pEndpoint->ul_poll_timer_active) {
273 /*
Chouhan, Anuragfc06aa92016-03-03 19:05:05 +0530274 qdf_timer_start(
Prakash Dhavalid5c9f1c2015-11-08 19:04:44 -0800275 &pEndpoint->ul_poll_timer, HTC_POLL_CLEANUP_PERIOD_MS);
276 */
277 pEndpoint->ul_poll_timer_active = 1;
278 }
279 UNLOCK_HTC_TX(pEndpoint->target);
280}
281
282static inline void
283htc_send_complete_check(HTC_ENDPOINT *pEndpoint, int force) {
284 /*
285 * Stop the polling-cleanup timer that will result in a later call to
286 * this function. It may get started again below, if there are still
287 * outsending sends.
288 */
289 htc_send_complete_poll_timer_stop(pEndpoint);
290 /*
291 * Check whether HIF has any prior sends that have finished,
292 * have not had the post-processing done.
293 */
294 hif_send_complete_check(pEndpoint->target->hif_dev,
295 pEndpoint->UL_PipeID, force);
296 /*
297 * If there are still outstanding sends after polling, start a timer
298 * to check again a little later.
299 */
300 htc_send_complete_poll_timer_start(pEndpoint);
301}
302
303#ifdef __cplusplus
304}
305#endif
306
307#ifndef DEBUG_BUNDLE
308#define DEBUG_BUNDLE 0
309#endif
310
311#ifdef HIF_SDIO
312#ifndef ENABLE_BUNDLE_TX
313#define ENABLE_BUNDLE_TX 1
314#endif
315
316#ifndef ENABLE_BUNDLE_RX
317#define ENABLE_BUNDLE_RX 1
318#endif
319#endif /* HIF_SDIO */
320#endif /* !_HTC_HOST_INTERNAL_H_ */