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