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