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