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