1 /* 2 * Copyright (c) 2013-2019 The Linux Foundation. All rights reserved. 3 * Copyright (c) 2023 Qualcomm Innovation Center, Inc. All rights reserved. 4 * 5 * Permission to use, copy, modify, and/or distribute this software for any 6 * purpose with or without fee is hereby granted, provided that the above 7 * copyright notice and this permission notice appear in all copies. 8 * 9 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 10 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 11 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 12 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 13 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 14 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 15 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 16 */ 17 18 #include "athdefs.h" 19 #include "a_types.h" 20 #include "a_osapi.h" 21 #define ATH_MODULE_NAME hif 22 #include "a_debug.h" 23 #define ATH_DEBUG_BMI ATH_DEBUG_MAKE_MODULE_MASK(0) 24 #include "hif.h" 25 #include "bmi.h" 26 #include "htc_api.h" 27 #include "if_sdio.h" 28 #include "regtable_sdio.h" 29 #include "hif_sdio_dev.h" 30 31 #define BMI_COMMUNICATION_TIMEOUT 100000 32 33 static bool pending_events_func_check; 34 static uint32_t command_credits; 35 static uint32_t *p_bmi_cmd_credits = &command_credits; 36 37 /* BMI Access routines */ 38 39 /** 40 * hif_bmi_buffer_send - call to send bmi buffer 41 * @scn: hif context 42 * @device: hif SDIO device 43 * @buffer: buffer 44 * @length: length 45 * 46 * Return: QDF_STATUS_SUCCESS for success. 47 */ 48 static QDF_STATUS 49 hif_bmi_buffer_send(struct hif_sdio_softc *scn, struct hif_sdio_dev *device, 50 char *buffer, uint32_t length) 51 { 52 QDF_STATUS status; 53 uint32_t timeout; 54 uint32_t address; 55 uint32_t mbox_address[HTC_MAILBOX_NUM_MAX]; 56 57 hif_configure_device(NULL, device, HIF_DEVICE_GET_FIFO_ADDR, 58 &mbox_address[0], sizeof(mbox_address)); 59 60 *p_bmi_cmd_credits = 0; 61 timeout = BMI_COMMUNICATION_TIMEOUT; 62 63 while (timeout-- && !(*p_bmi_cmd_credits)) { 64 /* Read the counter register to get the command credits */ 65 address = 66 COUNT_DEC_ADDRESS + (HTC_MAILBOX_NUM_MAX + ENDPOINT1) * 4; 67 /* hit the credit counter with a 4-byte access, the first 68 * byte read will hit the counter and cause 69 * a decrement, while the remaining 3 bytes has no effect. 70 * The rationale behind this is to make all HIF accesses 71 * 4-byte aligned 72 */ 73 status = 74 hif_read_write(device, address, 75 (uint8_t *) p_bmi_cmd_credits, 4, 76 HIF_RD_SYNC_BYTE_INC, NULL); 77 if (status != QDF_STATUS_SUCCESS) { 78 AR_DEBUG_PRINTF(ATH_DEBUG_ERR, 79 ("%s:Unable to decrement the credit count register\n", 80 __func__)); 81 return QDF_STATUS_E_FAILURE; 82 } 83 /* the counter is only 8=bits, ignore anything in the 84 * upper 3 bytes 85 */ 86 (*p_bmi_cmd_credits) &= 0xFF; 87 } 88 89 if (*p_bmi_cmd_credits) { 90 address = mbox_address[ENDPOINT1]; 91 status = hif_read_write(device, address, buffer, length, 92 HIF_WR_SYNC_BYTE_INC, NULL); 93 if (status != QDF_STATUS_SUCCESS) { 94 AR_DEBUG_PRINTF(ATH_DEBUG_ERR, 95 ("%s:Unable to send the BMI data to the device\n", 96 __func__)); 97 return QDF_STATUS_E_FAILURE; 98 } 99 } else { 100 AR_DEBUG_PRINTF(ATH_DEBUG_ERR, 101 ("%s:BMI Communication timeout - hif_bmi_buffer_send\n", 102 __func__)); 103 return QDF_STATUS_E_FAILURE; 104 } 105 106 return status; 107 } 108 109 #if defined(SDIO_3_0) 110 111 static QDF_STATUS 112 hif_bmi_read_write(struct hif_sdio_dev *device, 113 char *buffer, uint32_t length) 114 { 115 QDF_STATUS status; 116 117 status = hif_read_write(device, HOST_INT_STATUS_ADDRESS, 118 buffer, length, 119 HIF_RD_SYNC_BYTE_INC, NULL); 120 if (status != QDF_STATUS_SUCCESS) { 121 AR_DEBUG_PRINTF(ATH_DEBUG_ERR, 122 ("%s:Unable to read int status reg\n", 123 __func__)); 124 return QDF_STATUS_E_FAILURE; 125 } 126 *buffer = (HOST_INT_STATUS_MBOX_DATA_GET(*buffer) & (1 << ENDPOINT1)); 127 return status; 128 } 129 #else 130 131 static QDF_STATUS 132 hif_bmi_read_write(struct hif_sdio_dev *device, 133 char *buffer, uint32_t length) 134 { 135 QDF_STATUS status; 136 137 status = hif_read_write(device, RX_LOOKAHEAD_VALID_ADDRESS, 138 buffer, length, 139 HIF_RD_SYNC_BYTE_INC, NULL); 140 if (status != QDF_STATUS_SUCCESS) { 141 AR_DEBUG_PRINTF(ATH_DEBUG_ERR, 142 ("%s:Unable to read rx lookahead reg\n", 143 __func__)); 144 return QDF_STATUS_E_FAILURE; 145 } 146 *buffer &= (1 << ENDPOINT1); 147 return status; 148 } 149 #endif 150 151 /** 152 * hif_bmi_buffer_receive - call when bmi buffer is received 153 * @device: hif context 154 * @buffer: buffer 155 * @length: length 156 * @want_timeout: timeout is needed or not 157 * 158 * Return: QDF_STATUS_SUCCESS for success. 159 */ 160 static QDF_STATUS 161 hif_bmi_buffer_receive(struct hif_sdio_dev *device, 162 char *buffer, uint32_t length, bool want_timeout) 163 { 164 QDF_STATUS status; 165 uint32_t address; 166 uint32_t mbox_address[HTC_MAILBOX_NUM_MAX]; 167 struct _HIF_PENDING_EVENTS_INFO hif_pending_events; 168 169 static HIF_PENDING_EVENTS_FUNC get_pending_events_func; 170 171 if (!pending_events_func_check) { 172 /* see if the HIF layer implements an alternative 173 * function to get pending events 174 * do this only once! 175 */ 176 hif_configure_device(NULL, device, 177 HIF_DEVICE_GET_PENDING_EVENTS_FUNC, 178 &get_pending_events_func, 179 sizeof(get_pending_events_func)); 180 pending_events_func_check = true; 181 } 182 183 hif_configure_device(NULL, device, HIF_DEVICE_GET_FIFO_ADDR, 184 &mbox_address[0], sizeof(mbox_address)); 185 186 /* 187 * During normal bootup, small reads may be required. 188 * Rather than issue an HIF Read and then wait as the Target 189 * adds successive bytes to the FIFO, we wait here until 190 * we know that response data is available. 191 * 192 * This allows us to cleanly timeout on an unexpected 193 * Target failure rather than risk problems at the HIF level. In 194 * particular, this avoids SDIO timeouts and possibly garbage 195 * data on some host controllers. And on an interconnect 196 * such as Compact Flash (as well as some SDIO masters) which 197 * does not provide any indication on data timeout, it avoids 198 * a potential hang or garbage response. 199 * 200 * Synchronization is more difficult for reads larger than the 201 * size of the MBOX FIFO (128B), because the Target is unable 202 * to push the 129th byte of data until AFTER the Host posts an 203 * HIF Read and removes some FIFO data. So for large reads the 204 * Host proceeds to post an HIF Read BEFORE all the data is 205 * actually available to read. Fortunately, large BMI reads do 206 * not occur in practice -- they're supported for debug/development. 207 * 208 * So Host/Target BMI synchronization is divided into these cases: 209 * CASE 1: length < 4 210 * Should not happen 211 * 212 * CASE 2: 4 <= length <= 128 213 * Wait for first 4 bytes to be in FIFO 214 * If CONSERVATIVE_BMI_READ is enabled, also wait for 215 * a BMI command credit, which indicates that the ENTIRE 216 * response is available in the the FIFO 217 * 218 * CASE 3: length > 128 219 * Wait for the first 4 bytes to be in FIFO 220 * 221 * For most uses, a small timeout should be sufficient and we will 222 * usually see a response quickly; but there may be some unusual 223 * (debug) cases of BMI_EXECUTE where we want an larger timeout. 224 * For now, we use an unbounded busy loop while waiting for 225 * BMI_EXECUTE. 226 * 227 * If BMI_EXECUTE ever needs to support longer-latency execution, 228 * especially in production, this code needs to be enhanced to sleep 229 * and yield. Also note that BMI_COMMUNICATION_TIMEOUT is currently 230 * a function of Host processor speed. 231 */ 232 if (length >= 4) { /* NB: Currently, always true */ 233 /* 234 * NB: word_available is declared static for esoteric reasons 235 * having to do with protection on some OSes. 236 */ 237 static uint32_t word_available; 238 uint32_t timeout; 239 240 word_available = 0; 241 timeout = BMI_COMMUNICATION_TIMEOUT; 242 while ((!want_timeout || timeout--) && !word_available) { 243 244 if (get_pending_events_func) { 245 status = get_pending_events_func(device, 246 &hif_pending_events, 247 NULL); 248 if (status != QDF_STATUS_SUCCESS) { 249 AR_DEBUG_PRINTF(ATH_DEBUG_ERR, 250 ("%s:Failed to get pending events\n", 251 __func__)); 252 break; 253 } 254 255 if (hif_pending_events.available_recv_bytes >= 256 sizeof(uint32_t)) { 257 word_available = 1; 258 } 259 continue; 260 } 261 status = hif_bmi_read_write(device, 262 (uint8_t *) &word_available, 263 sizeof(word_available)); 264 if (status != QDF_STATUS_SUCCESS) 265 return QDF_STATUS_E_FAILURE; 266 } 267 268 if (!word_available) { 269 AR_DEBUG_PRINTF(ATH_DEBUG_ERR, 270 ("%s:BMI Communication timeout FIFO empty\n", 271 __func__)); 272 return QDF_STATUS_E_FAILURE; 273 } 274 } 275 276 address = mbox_address[ENDPOINT1]; 277 status = hif_read_write(device, address, buffer, length, 278 HIF_RD_SYNC_BYTE_INC, NULL); 279 if (status != QDF_STATUS_SUCCESS) { 280 AR_DEBUG_PRINTF(ATH_DEBUG_ERR, 281 ("%s:Unable to read the BMI data from the device\n", 282 __func__)); 283 return QDF_STATUS_E_FAILURE; 284 } 285 286 return QDF_STATUS_SUCCESS; 287 } 288 289 /** 290 * hif_reg_based_get_target_info - to retrieve target info 291 * @hif_ctx: hif context 292 * @targ_info: bmi target info 293 * 294 * Return: QDF_STATUS_SUCCESS for success. 295 */ 296 QDF_STATUS 297 hif_reg_based_get_target_info(struct hif_opaque_softc *hif_ctx, 298 struct bmi_target_info *targ_info) 299 { 300 QDF_STATUS status; 301 uint32_t cid; 302 struct hif_sdio_softc *scn = HIF_GET_SDIO_SOFTC(hif_ctx); 303 struct hif_sdio_dev *device = scn->hif_handle; 304 305 AR_DEBUG_PRINTF(ATH_DEBUG_ERR, 306 ("BMI Get Target Info: Enter (device: 0x%pK)\n", 307 device)); 308 cid = BMI_GET_TARGET_INFO; 309 status = hif_bmi_buffer_send(scn, device, (char *)&cid, sizeof(cid)); 310 if (status != QDF_STATUS_SUCCESS) { 311 AR_DEBUG_PRINTF(ATH_DEBUG_ERR, 312 ("%s:Unable to write to the device\n", 313 __func__)); 314 return QDF_STATUS_E_FAILURE; 315 } 316 317 status = hif_bmi_buffer_receive(device, 318 (char *) &targ_info->target_ver, 319 sizeof(targ_info->target_ver), true); 320 if (status != QDF_STATUS_SUCCESS) { 321 AR_DEBUG_PRINTF(ATH_DEBUG_ERR, 322 ("%s:Unable to read Target Version from the device\n", 323 __func__)); 324 return QDF_STATUS_E_FAILURE; 325 } 326 327 if (targ_info->target_ver == TARGET_VERSION_SENTINAL) { 328 /* Determine how many bytes are in the Target's targ_info */ 329 status = hif_bmi_buffer_receive(device, 330 (char *) &targ_info-> 331 target_info_byte_count, 332 sizeof(targ_info-> 333 target_info_byte_count), 334 true); 335 if (status != QDF_STATUS_SUCCESS) { 336 AR_DEBUG_PRINTF(ATH_DEBUG_ERR, 337 ("%s:Unable to read target Info\n", 338 __func__)); 339 return QDF_STATUS_E_FAILURE; 340 } 341 342 /* 343 * The Target's targ_info doesn't match the Host's targ_info. 344 * We need to do some backwards compatibility work to make this 345 * OK. 346 */ 347 QDF_ASSERT(targ_info->target_info_byte_count == 348 sizeof(*targ_info)); 349 /* Read the remainder of the targ_info */ 350 status = hif_bmi_buffer_receive(device, 351 ((char *) targ_info) + 352 sizeof(targ_info-> 353 target_info_byte_count), 354 sizeof(*targ_info) - 355 sizeof(targ_info-> 356 target_info_byte_count), 357 true); 358 if (status != QDF_STATUS_SUCCESS) { 359 AR_DEBUG_PRINTF(ATH_DEBUG_ERR, 360 ("%s:Unable to read Target Info (%d bytes)\n", 361 __func__, targ_info->target_info_byte_count)); 362 return QDF_STATUS_E_FAILURE; 363 } 364 } else { 365 /* 366 * Target must be an AR6001 whose firmware does not 367 * support BMI_GET_TARGET_INFO. Construct the data 368 * that it would have sent. 369 */ 370 targ_info->target_info_byte_count = sizeof(*targ_info); 371 targ_info->target_type = TARGET_TYPE_AR6001; 372 } 373 374 AR_DEBUG_PRINTF(ATH_DEBUG_ERR, 375 ("BMI Get Target Info: Exit (ver: 0x%x type: 0x%x)\n", 376 targ_info->target_ver, 377 targ_info->target_type)); 378 379 return QDF_STATUS_SUCCESS; 380 } 381 382 /** 383 * hif_exchange_bmi_msg - API to handle HIF-specific BMI message exchanges 384 * @hif_ctx: hif context 385 * @bmi_cmd_da: bmi cmd 386 * @bmi_rsp_da: bmi rsp 387 * @send_message: send message 388 * @length: length 389 * @response_message: response message 390 * @response_length: response length 391 * @timeout_ms: timeout in ms 392 * 393 * This API is synchronous 394 * and only allowed to be called from a context that can block (sleep) 395 * 396 * Return: QDF_STATUS_SUCCESS for success. 397 */ 398 QDF_STATUS hif_exchange_bmi_msg(struct hif_opaque_softc *hif_ctx, 399 qdf_dma_addr_t bmi_cmd_da, 400 qdf_dma_addr_t bmi_rsp_da, 401 uint8_t *send_message, 402 uint32_t length, 403 uint8_t *response_message, 404 uint32_t *response_length, 405 uint32_t timeout_ms) { 406 struct hif_sdio_softc *scn = HIF_GET_SDIO_SOFTC(hif_ctx); 407 struct hif_sdio_dev *device = scn->hif_handle; 408 QDF_STATUS status = QDF_STATUS_SUCCESS; 409 410 if (!device) { 411 AR_DEBUG_PRINTF(ATH_DEBUG_ERR, 412 ("%s:Null device argument\n", 413 __func__)); 414 return QDF_STATUS_E_INVAL; 415 } 416 417 status = hif_bmi_buffer_send(scn, device, send_message, length); 418 if (QDF_IS_STATUS_ERROR(status)) { 419 AR_DEBUG_PRINTF(ATH_DEBUG_ERR, 420 ("%s:Unable to Send Message to device\n", 421 __func__)); 422 return status; 423 } 424 425 if (response_message) { 426 status = hif_bmi_buffer_receive(device, response_message, 427 *response_length, 428 timeout_ms ? true : false); 429 if (QDF_IS_STATUS_ERROR(status)) { 430 AR_DEBUG_PRINTF(ATH_DEBUG_ERR, 431 ("%s:Unable to read response\n", 432 __func__)); 433 return status; 434 } 435 } 436 437 return status; 438 } 439 440 void hif_register_bmi_callbacks(struct hif_opaque_softc *hif_ctx) 441 { 442 } 443 444 #ifdef BRINGUP_DEBUG 445 #define SDIO_SCRATCH_1_ADDRESS 0x864 446 /*Functions used for debugging*/ 447 /** 448 * hif_bmi_write_scratch_register - API to write scratch register 449 * @device: hif context 450 * @buffer: buffer 451 * 452 * Return: QDF_STATUS_SUCCESS for success. 453 */ 454 QDF_STATUS hif_bmi_write_scratch_register(struct hif_sdio_dev *device, 455 uint32_t buffer) { 456 QDF_STATUS status = QDF_STATUS_SUCCESS; 457 458 status = hif_read_write(device, SDIO_SCRATCH_1_ADDRESS, 459 (uint8_t *) &buffer, 4, 460 HIF_WR_SYNC_BYTE_INC, NULL); 461 if (status != QDF_STATUS_SUCCESS) { 462 AR_DEBUG_PRINTF(ATH_DEBUG_ERR, 463 ("%s: Unable to write to 0x%x\n", 464 __func__, SDIO_SCRATCH_1_ADDRESS)); 465 return QDF_STATUS_E_FAILURE; 466 } 467 AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("%s: wrote 0x%x to 0x%x\n", __func__, 468 buffer, SDIO_SCRATCH_1_ADDRESS)); 469 470 return status; 471 } 472 473 /** 474 * hif_bmi_read_scratch_register - API to read from scratch register 475 * @device: hif context 476 * 477 * Return: QDF_STATUS_SUCCESS for success. 478 */ 479 QDF_STATUS hif_bmi_read_scratch_register(struct hif_sdio_dev *device) 480 { 481 QDF_STATUS status = QDF_STATUS_SUCCESS; 482 uint32_t buffer = 0; 483 484 status = hif_read_write(device, SDIO_SCRATCH_1_ADDRESS, 485 (uint8_t *) &buffer, 4, 486 HIF_RD_SYNC_BYTE_INC, NULL); 487 if (status != QDF_STATUS_SUCCESS) { 488 AR_DEBUG_PRINTF(ATH_DEBUG_ERR, 489 ("%s: Unable to read from 0x%x\n", 490 __func__, SDIO_SCRATCH_1_ADDRESS)); 491 return QDF_STATUS_E_FAILURE; 492 } 493 AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("%s: read 0x%x from 0x%x\n", __func__, 494 buffer, SDIO_SCRATCH_1_ADDRESS)); 495 496 return status; 497 } 498 #endif 499