1 /* 2 * Copyright (c) 2015-2018 The Linux Foundation. All rights reserved. 3 * 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 __CE_H__ 29 #define __CE_H__ 30 31 #include "qdf_atomic.h" 32 #include "qdf_lock.h" 33 #include "hif_main.h" 34 #include "qdf_util.h" 35 #include "hif_exec.h" 36 37 #define CE_HTT_T2H_MSG 1 38 #define CE_HTT_H2T_MSG 4 39 40 #define CE_OFFSET 0x00000400 41 #define CE_USEFUL_SIZE 0x00000058 42 #define CE_ALL_BITMAP 0xFFFF 43 44 /** 45 * enum ce_id_type 46 * 47 * @ce_id_type: Copy engine ID 48 */ 49 enum ce_id_type { 50 CE_ID_0, 51 CE_ID_1, 52 CE_ID_2, 53 CE_ID_3, 54 CE_ID_4, 55 CE_ID_5, 56 CE_ID_6, 57 CE_ID_7, 58 CE_ID_8, 59 CE_ID_9, 60 CE_ID_10, 61 CE_ID_11, 62 CE_ID_MAX 63 }; 64 65 #ifdef CONFIG_WIN 66 #define QWLAN_VERSIONSTR "WIN" 67 #endif 68 69 enum ol_ath_hif_pkt_ecodes { 70 HIF_PIPE_NO_RESOURCE = 0 71 }; 72 73 struct HIF_CE_state; 74 75 /* Per-pipe state. */ 76 struct HIF_CE_pipe_info { 77 /* Handle of underlying Copy Engine */ 78 struct CE_handle *ce_hdl; 79 80 /* Our pipe number; facilitiates use of pipe_info ptrs. */ 81 uint8_t pipe_num; 82 83 /* Convenience back pointer to HIF_CE_state. */ 84 struct HIF_CE_state *HIF_CE_state; 85 86 /* Instantaneous number of receive buffers that should be posted */ 87 atomic_t recv_bufs_needed; 88 qdf_size_t buf_sz; 89 qdf_spinlock_t recv_bufs_needed_lock; 90 91 qdf_spinlock_t completion_freeq_lock; 92 /* Limit the number of outstanding send requests. */ 93 int num_sends_allowed; 94 95 /* adding three counts for debugging ring buffer errors */ 96 uint32_t nbuf_alloc_err_count; 97 uint32_t nbuf_dma_err_count; 98 uint32_t nbuf_ce_enqueue_err_count; 99 struct hif_msg_callbacks pipe_callbacks; 100 }; 101 102 /** 103 * struct ce_tasklet_entry 104 * 105 * @intr_tq: intr_tq 106 * @ce_id: ce_id 107 * @inited: inited 108 * @hif_ce_state: hif_ce_state 109 * @from_irq: from_irq 110 */ 111 struct ce_tasklet_entry { 112 struct tasklet_struct intr_tq; 113 enum ce_id_type ce_id; 114 bool inited; 115 void *hif_ce_state; 116 }; 117 118 static inline bool hif_dummy_grp_done(struct hif_exec_context *grp_entry, int 119 work_done) 120 { 121 return true; 122 } 123 124 extern struct hif_execution_ops tasklet_sched_ops; 125 extern struct hif_execution_ops napi_sched_ops; 126 127 struct ce_stats { 128 uint32_t ce_per_cpu[CE_COUNT_MAX][QDF_MAX_AVAILABLE_CPU]; 129 }; 130 131 struct HIF_CE_state { 132 struct hif_softc ol_sc; 133 bool started; 134 struct ce_tasklet_entry tasklets[CE_COUNT_MAX]; 135 struct hif_exec_context *hif_ext_group[HIF_MAX_GROUP]; 136 uint32_t hif_num_extgroup; 137 qdf_spinlock_t keep_awake_lock; 138 qdf_spinlock_t irq_reg_lock; 139 unsigned int keep_awake_count; 140 bool verified_awake; 141 bool fake_sleep; 142 qdf_timer_t sleep_timer; 143 bool sleep_timer_init; 144 qdf_time_t sleep_ticks; 145 uint32_t ce_register_irq_done; 146 147 struct CE_pipe_config *target_ce_config; 148 struct CE_attr *host_ce_config; 149 uint32_t target_ce_config_sz; 150 /* Per-pipe state. */ 151 struct HIF_CE_pipe_info pipe_info[CE_COUNT_MAX]; 152 /* to be activated after BMI_DONE */ 153 struct hif_msg_callbacks msg_callbacks_pending; 154 /* current msg callbacks in use */ 155 struct hif_msg_callbacks msg_callbacks_current; 156 157 /* Target address used to signal a pending firmware event */ 158 uint32_t fw_indicator_address; 159 160 /* Copy Engine used for Diagnostic Accesses */ 161 struct CE_handle *ce_diag; 162 struct ce_stats stats; 163 struct ce_ops *ce_services; 164 }; 165 166 /* 167 * HIA Map Definition 168 */ 169 struct host_interest_area_t { 170 uint32_t hi_interconnect_state; 171 uint32_t hi_early_alloc; 172 uint32_t hi_option_flag2; 173 uint32_t hi_board_data; 174 uint32_t hi_board_data_initialized; 175 uint32_t hi_failure_state; 176 uint32_t hi_rddi_msi_num; 177 uint32_t hi_pcie_perst_couple_en; 178 uint32_t hi_sw_protocol_version; 179 }; 180 181 struct shadow_reg_cfg { 182 uint16_t ce_id; 183 uint16_t reg_offset; 184 }; 185 186 struct shadow_reg_v2_cfg { 187 uint32_t reg_value; 188 }; 189 190 void hif_ce_stop(struct hif_softc *scn); 191 int hif_dump_ce_registers(struct hif_softc *scn); 192 void 193 hif_ce_dump_target_memory(struct hif_softc *scn, void *ramdump_base, 194 uint32_t address, uint32_t size); 195 196 #ifdef IPA_OFFLOAD 197 void hif_ce_ipa_get_ce_resource(struct hif_softc *scn, 198 qdf_dma_addr_t *ce_sr_base_paddr, 199 uint32_t *ce_sr_ring_size, 200 qdf_dma_addr_t *ce_reg_paddr); 201 #else 202 static inline 203 void hif_ce_ipa_get_ce_resource(struct hif_softc *scn, 204 qdf_dma_addr_t *ce_sr_base_paddr, 205 uint32_t *ce_sr_ring_size, 206 qdf_dma_addr_t *ce_reg_paddr) 207 { 208 } 209 210 #endif 211 int hif_wlan_enable(struct hif_softc *scn); 212 void hif_wlan_disable(struct hif_softc *scn); 213 void hif_get_target_ce_config(struct hif_softc *scn, 214 struct CE_pipe_config **target_ce_config_ret, 215 uint32_t *target_ce_config_sz_ret, 216 struct service_to_pipe **target_service_to_ce_map_ret, 217 uint32_t *target_service_to_ce_map_sz_ret, 218 struct shadow_reg_cfg **target_shadow_reg_cfg_v1_ret, 219 uint32_t *shadow_cfg_v1_sz_ret); 220 221 #ifdef WLAN_FEATURE_EPPING 222 void hif_ce_prepare_epping_config(struct HIF_CE_state *hif_state); 223 void hif_select_epping_service_to_pipe_map(struct service_to_pipe 224 **tgt_svc_map_to_use, 225 uint32_t *sz_tgt_svc_map_to_use); 226 227 #else 228 static inline 229 void hif_ce_prepare_epping_config(struct HIF_CE_state *hif_state) 230 { } 231 static inline 232 void hif_select_epping_service_to_pipe_map(struct service_to_pipe 233 **tgt_svc_map_to_use, 234 uint32_t *sz_tgt_svc_map_to_use) 235 { } 236 #endif 237 238 #endif /* __CE_H__ */ 239