1 /* 2 * Copyright (c) 2015-2019 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 __CE_H__ 20 #define __CE_H__ 21 22 #include "qdf_atomic.h" 23 #include "qdf_lock.h" 24 #include "hif_main.h" 25 #include "qdf_util.h" 26 #include "hif_exec.h" 27 28 #ifndef DATA_CE_SW_INDEX_NO_INLINE_UPDATE 29 #define DATA_CE_UPDATE_SWINDEX(x, scn, addr) \ 30 (x = CE_SRC_RING_READ_IDX_GET_FROM_DDR(scn, addr)) 31 #else 32 #define DATA_CE_UPDATE_SWINDEX(x, scn, addr) 33 #endif 34 35 /* 36 * Number of times to check for any pending tx/rx completion on 37 * a copy engine, this count should be big enough. Once we hit 38 * this threashold we'll not check for any Tx/Rx comlpetion in same 39 * interrupt handling. Note that this threashold is only used for 40 * Rx interrupt processing, this can be used tor Tx as well if we 41 * suspect any infinite loop in checking for pending Tx completion. 42 */ 43 #define CE_TXRX_COMP_CHECK_THRESHOLD 20 44 45 #define CE_HTT_T2H_MSG 1 46 #define CE_HTT_H2T_MSG 4 47 48 #define CE_OFFSET 0x00000400 49 #define CE_USEFUL_SIZE 0x00000058 50 #define CE_ALL_BITMAP 0xFFFF 51 52 /** 53 * enum ce_id_type 54 * 55 * @ce_id_type: Copy engine ID 56 */ 57 enum ce_id_type { 58 CE_ID_0, 59 CE_ID_1, 60 CE_ID_2, 61 CE_ID_3, 62 CE_ID_4, 63 CE_ID_5, 64 CE_ID_6, 65 CE_ID_7, 66 CE_ID_8, 67 CE_ID_9, 68 CE_ID_10, 69 CE_ID_11, 70 CE_ID_MAX 71 }; 72 73 enum ce_target_type { 74 CE_SVC_LEGACY, 75 CE_SVC_SRNG, 76 CE_MAX_TARGET_TYPE 77 }; 78 79 #ifdef CONFIG_WIN 80 #define QWLAN_VERSIONSTR "WIN" 81 #endif 82 83 enum ol_ath_hif_pkt_ecodes { 84 HIF_PIPE_NO_RESOURCE = 0 85 }; 86 87 struct HIF_CE_state; 88 89 /* Per-pipe state. */ 90 struct HIF_CE_pipe_info { 91 /* Handle of underlying Copy Engine */ 92 struct CE_handle *ce_hdl; 93 94 /* Our pipe number; facilitiates use of pipe_info ptrs. */ 95 uint8_t pipe_num; 96 97 /* Convenience back pointer to HIF_CE_state. */ 98 struct HIF_CE_state *HIF_CE_state; 99 100 /* Instantaneous number of receive buffers that should be posted */ 101 atomic_t recv_bufs_needed; 102 qdf_size_t buf_sz; 103 qdf_spinlock_t recv_bufs_needed_lock; 104 105 qdf_spinlock_t completion_freeq_lock; 106 /* Limit the number of outstanding send requests. */ 107 int num_sends_allowed; 108 109 /* adding three counts for debugging ring buffer errors */ 110 uint32_t nbuf_alloc_err_count; 111 uint32_t nbuf_dma_err_count; 112 uint32_t nbuf_ce_enqueue_err_count; 113 struct hif_msg_callbacks pipe_callbacks; 114 }; 115 116 /** 117 * struct ce_tasklet_entry 118 * 119 * @intr_tq: intr_tq 120 * @ce_id: ce_id 121 * @inited: inited 122 * @hif_ce_state: hif_ce_state 123 * @from_irq: from_irq 124 */ 125 struct ce_tasklet_entry { 126 struct tasklet_struct intr_tq; 127 enum ce_id_type ce_id; 128 bool inited; 129 void *hif_ce_state; 130 }; 131 132 static inline bool hif_dummy_grp_done(struct hif_exec_context *grp_entry, int 133 work_done) 134 { 135 return true; 136 } 137 138 extern struct hif_execution_ops tasklet_sched_ops; 139 extern struct hif_execution_ops napi_sched_ops; 140 141 struct ce_stats { 142 uint32_t ce_per_cpu[CE_COUNT_MAX][QDF_MAX_AVAILABLE_CPU]; 143 }; 144 145 struct HIF_CE_state { 146 struct hif_softc ol_sc; 147 bool started; 148 struct ce_tasklet_entry tasklets[CE_COUNT_MAX]; 149 struct hif_exec_context *hif_ext_group[HIF_MAX_GROUP]; 150 uint32_t hif_num_extgroup; 151 qdf_spinlock_t keep_awake_lock; 152 qdf_spinlock_t irq_reg_lock; 153 unsigned int keep_awake_count; 154 bool verified_awake; 155 bool fake_sleep; 156 qdf_timer_t sleep_timer; 157 bool sleep_timer_init; 158 qdf_time_t sleep_ticks; 159 uint32_t ce_register_irq_done; 160 161 struct CE_pipe_config *target_ce_config; 162 struct CE_attr *host_ce_config; 163 uint32_t target_ce_config_sz; 164 /* Per-pipe state. */ 165 struct HIF_CE_pipe_info pipe_info[CE_COUNT_MAX]; 166 /* to be activated after BMI_DONE */ 167 struct hif_msg_callbacks msg_callbacks_pending; 168 /* current msg callbacks in use */ 169 struct hif_msg_callbacks msg_callbacks_current; 170 171 /* Target address used to signal a pending firmware event */ 172 uint32_t fw_indicator_address; 173 174 /* Copy Engine used for Diagnostic Accesses */ 175 struct CE_handle *ce_diag; 176 struct ce_stats stats; 177 struct ce_ops *ce_services; 178 }; 179 180 /* 181 * HIA Map Definition 182 */ 183 struct host_interest_area_t { 184 uint32_t hi_interconnect_state; 185 uint32_t hi_early_alloc; 186 uint32_t hi_option_flag2; 187 uint32_t hi_board_data; 188 uint32_t hi_board_data_initialized; 189 uint32_t hi_failure_state; 190 uint32_t hi_rddi_msi_num; 191 uint32_t hi_pcie_perst_couple_en; 192 uint32_t hi_sw_protocol_version; 193 }; 194 195 struct shadow_reg_cfg { 196 uint16_t ce_id; 197 uint16_t reg_offset; 198 }; 199 200 struct shadow_reg_v2_cfg { 201 uint32_t reg_value; 202 }; 203 204 #ifdef CONFIG_BYPASS_QMI 205 206 #define FW_SHARED_MEM (2 * 1024 * 1024) 207 208 #ifdef QCN7605_SUPPORT 209 struct msi_cfg { 210 u16 ce_id; 211 u16 msi_vector; 212 } qdf_packed; 213 214 struct ce_info { 215 u32 rri_over_ddr_low_paddr; 216 u32 rri_over_ddr_high_paddr; 217 struct msi_cfg cfg[CE_COUNT_MAX]; 218 } qdf_packed; 219 #endif 220 #endif 221 222 void hif_ce_stop(struct hif_softc *scn); 223 int hif_dump_ce_registers(struct hif_softc *scn); 224 void 225 hif_ce_dump_target_memory(struct hif_softc *scn, void *ramdump_base, 226 uint32_t address, uint32_t size); 227 228 #ifdef IPA_OFFLOAD 229 void hif_ce_ipa_get_ce_resource(struct hif_softc *scn, 230 qdf_shared_mem_t **ce_sr, 231 uint32_t *ce_sr_ring_size, 232 qdf_dma_addr_t *ce_reg_paddr); 233 #else 234 static inline 235 void hif_ce_ipa_get_ce_resource(struct hif_softc *scn, 236 qdf_shared_mem_t **ce_sr, 237 uint32_t *ce_sr_ring_size, 238 qdf_dma_addr_t *ce_reg_paddr) 239 { 240 } 241 242 #endif 243 int hif_wlan_enable(struct hif_softc *scn); 244 void ce_enable_polling(void *cestate); 245 void ce_disable_polling(void *cestate); 246 void hif_wlan_disable(struct hif_softc *scn); 247 void hif_get_target_ce_config(struct hif_softc *scn, 248 struct CE_pipe_config **target_ce_config_ret, 249 uint32_t *target_ce_config_sz_ret, 250 struct service_to_pipe **target_service_to_ce_map_ret, 251 uint32_t *target_service_to_ce_map_sz_ret, 252 struct shadow_reg_cfg **target_shadow_reg_cfg_v1_ret, 253 uint32_t *shadow_cfg_v1_sz_ret); 254 255 #ifdef WLAN_FEATURE_EPPING 256 void hif_ce_prepare_epping_config(struct HIF_CE_state *hif_state); 257 void hif_select_epping_service_to_pipe_map(struct service_to_pipe 258 **tgt_svc_map_to_use, 259 uint32_t *sz_tgt_svc_map_to_use); 260 261 #else 262 static inline 263 void hif_ce_prepare_epping_config(struct HIF_CE_state *hif_state) 264 { } 265 static inline 266 void hif_select_epping_service_to_pipe_map(struct service_to_pipe 267 **tgt_svc_map_to_use, 268 uint32_t *sz_tgt_svc_map_to_use) 269 { } 270 #endif 271 272 void ce_service_register_module(enum ce_target_type target_type, 273 struct ce_ops* (*ce_attach)(void)); 274 275 #endif /* __CE_H__ */ 276