1 /* 2 * Copyright (c) 2013-2017 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 #include <qdf_types.h> 20 #include <qdf_status.h> 21 #include <qdf_timer.h> 22 #include <qdf_time.h> 23 #include <qdf_lock.h> 24 #include <qdf_mem.h> 25 #include <qdf_util.h> 26 #include <qdf_defer.h> 27 #include <qdf_atomic.h> 28 #include <qdf_nbuf.h> 29 #include <athdefs.h> 30 #include "qdf_net_types.h" 31 #include "a_types.h" 32 #include "athdefs.h" 33 #include "a_osapi.h" 34 #include <hif.h> 35 #include <htc_services.h> 36 #include <a_debug.h> 37 #include "hif_sdio_dev.h" 38 #include "if_sdio.h" 39 #include "regtable_sdio.h" 40 41 #define ATH_MODULE_NAME hif_sdio 42 43 /** 44 * hif_start() - start hif bus interface. 45 * @hif_ctx: HIF context 46 * 47 * Enables hif device interrupts 48 * 49 * Return: int 50 */ 51 uint32_t hif_start(struct hif_opaque_softc *hif_ctx) 52 { 53 struct hif_sdio_softc *scn = HIF_GET_SDIO_SOFTC(hif_ctx); 54 struct hif_sdio_dev *hif_device = scn->hif_handle; 55 struct hif_sdio_device *htc_sdio_device = hif_dev_from_hif(hif_device); 56 57 HIF_ENTER(); 58 hif_dev_enable_interrupts(htc_sdio_device); 59 HIF_EXIT(); 60 return QDF_STATUS_SUCCESS; 61 } 62 63 /** 64 * hif_flush_surprise_remove() - remove hif bus interface. 65 * @hif_ctx: HIF context 66 * 67 * 68 * Return: none 69 */ 70 void hif_flush_surprise_remove(struct hif_opaque_softc *hif_ctx) 71 { 72 73 } 74 75 /** 76 * hif_sdio_stop() - stop hif bus interface. 77 * @hif_ctx: HIF context 78 * 79 * Disable hif device interrupts and destroy hif context 80 * 81 * Return: none 82 */ 83 void hif_sdio_stop(struct hif_softc *hif_ctx) 84 { 85 struct hif_sdio_softc *scn = HIF_GET_SDIO_SOFTC(hif_ctx); 86 struct hif_sdio_dev *hif_device = scn->hif_handle; 87 struct hif_sdio_device *htc_sdio_device = hif_dev_from_hif(hif_device); 88 89 HIF_ENTER(); 90 if (htc_sdio_device != NULL) { 91 hif_dev_disable_interrupts(htc_sdio_device); 92 hif_dev_destroy(htc_sdio_device); 93 } 94 HIF_EXIT(); 95 } 96 97 /** 98 * hif_send_head() - send data on hif bus interface. 99 * @hif_ctx: HIF context 100 * 101 * send tx data on a given pipe id 102 * 103 * Return: int 104 */ 105 QDF_STATUS hif_send_head(struct hif_opaque_softc *hif_ctx, uint8_t pipe, 106 uint32_t transfer_id, uint32_t nbytes, qdf_nbuf_t buf, 107 uint32_t data_attr) 108 { 109 struct hif_sdio_softc *scn = HIF_GET_SDIO_SOFTC(hif_ctx); 110 struct hif_sdio_dev *hif_device = scn->hif_handle; 111 struct hif_sdio_device *htc_sdio_device = hif_dev_from_hif(hif_device); 112 113 return hif_dev_send_buffer(htc_sdio_device, 114 transfer_id, pipe, 115 nbytes, buf); 116 } 117 118 /** 119 * hif_map_service_to_pipe() - maps ul/dl pipe to service id. 120 * @hif_ctx: HIF hdl 121 * @ServiceId: sevice index 122 * @ULPipe: uplink pipe id 123 * @DLPipe: down-linklink pipe id 124 * @ul_is_polled: if ul is polling based 125 * @ul_is_polled: if dl is polling based 126 * 127 * Return: int 128 */ 129 int hif_map_service_to_pipe(struct hif_opaque_softc *hif_hdl, 130 uint16_t service_id, uint8_t *ul_pipe, 131 uint8_t *dl_pipe, int *ul_is_polled, 132 int *dl_is_polled) 133 { 134 struct hif_sdio_softc *scn = HIF_GET_SDIO_SOFTC(hif_hdl); 135 struct hif_sdio_dev *hif_device = scn->hif_handle; 136 struct hif_sdio_device *htc_sdio_device = hif_dev_from_hif(hif_device); 137 138 return hif_dev_map_service_to_pipe(htc_sdio_device, 139 service_id, ul_pipe, dl_pipe, 140 hif_device->swap_mailbox); 141 } 142 143 /** 144 * hif_map_service_to_pipe() - maps ul/dl pipe to service id. 145 * @scn: HIF context 146 * @ServiceId: sevice index 147 * @ULPipe: uplink pipe id 148 * @DLPipe: down-linklink pipe id 149 * @ul_is_polled: if ul is polling based 150 * @ul_is_polled: if dl is polling based 151 * 152 * Return: int 153 */ 154 void hif_get_default_pipe(struct hif_opaque_softc *scn, uint8_t *ul_pipe, 155 uint8_t *dl_pipe) 156 { 157 hif_map_service_to_pipe(scn, HTC_CTRL_RSVD_SVC, 158 ul_pipe, dl_pipe, NULL, NULL); 159 } 160 161 /** 162 * hif_post_init() - create hif device after probe. 163 * @hif_ctx: HIF context 164 * @target: HIF target 165 * @callbacks: htc callbacks 166 * 167 * 168 * Return: int 169 */ 170 void hif_post_init(struct hif_opaque_softc *hif_ctx, void *target, 171 struct hif_msg_callbacks *callbacks) 172 { 173 struct hif_sdio_softc *scn = HIF_GET_SDIO_SOFTC(hif_ctx); 174 struct hif_sdio_dev *hif_device = scn->hif_handle; 175 struct hif_sdio_device *htc_sdio_device = hif_dev_from_hif(hif_device); 176 177 if (htc_sdio_device == NULL) 178 htc_sdio_device = hif_dev_create(hif_device, callbacks, target); 179 180 if (htc_sdio_device) 181 hif_dev_setup(htc_sdio_device); 182 } 183 184 /** 185 * hif_get_free_queue_number() - create hif device after probe. 186 * @hif_ctx: HIF context 187 * @pipe: pipe id 188 * 189 * SDIO uses credit based flow control at the HTC layer 190 * so transmit resource checks are bypassed 191 * Return: int 192 */ 193 uint16_t hif_get_free_queue_number(struct hif_opaque_softc *hif_ctx, 194 uint8_t pipe) 195 { 196 uint16_t rv; 197 198 rv = 1; 199 return rv; 200 } 201 202 /** 203 * hif_send_complete_check() - check tx complete on a given pipe. 204 * @hif_ctx: HIF context 205 * @pipe: HIF target 206 * @force: check if need to pool for completion 207 * Decide whether to actually poll for completions, or just 208 * wait for a later chance. 209 * 210 * Return: int 211 */ 212 void hif_send_complete_check(struct hif_opaque_softc *hif_ctx, uint8_t pipe, 213 int force) 214 { 215 216 } 217 218