1  /*
2   * Copyright (c) 2014-2021 The Linux Foundation. All rights reserved.
3   * Copyright (c) 2021-2023 Qualcomm Innovation Center, Inc. All rights reserved.
4   *
5   * Permission to use, copy, modify, and/or distribute this software for
6   * any purpose with or without fee is hereby granted, provided that the
7   * above copyright notice and this permission notice appear in all
8   * copies.
9   *
10   * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
11   * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
12   * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
13   * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
14   * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
15   * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
16   * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
17   * PERFORMANCE OF THIS SOFTWARE.
18   */
19  
20  #include <linux/firmware.h>
21  #include "ol_if_athvar.h"
22  #include "qdf_time.h"
23  #include "targaddrs.h"
24  #include "ol_cfg.h"
25  #include "cds_api.h"
26  #include "wma_api.h"
27  #include "wma.h"
28  #include "bin_sig.h"
29  #include "i_ar6320v2_regtable.h"
30  #include "epping_main.h"
31  #ifdef HIF_PCI
32  #include "ce_reg.h"
33  #endif
34  #if defined(HIF_SDIO)
35  #include "if_sdio.h"
36  #include "regtable_sdio.h"
37  #endif
38  #if defined(HIF_USB)
39  #include "if_usb.h"
40  #include "regtable_usb.h"
41  #endif
42  #include "pld_common.h"
43  #include "hif_main.h"
44  
45  #include "i_bmi.h"
46  #include "qwlan_version.h"
47  #include "wlan_policy_mgr_api.h"
48  #include "dbglog_host.h"
49  
50  #ifdef FEATURE_SECURE_FIRMWARE
51  static struct hash_fw fw_hash;
52  #endif
53  
54  static uint32_t refclk_speed_to_hz[] = {
55  	48000000,               /* SOC_REFCLK_48_MHZ */
56  	19200000,               /* SOC_REFCLK_19_2_MHZ */
57  	24000000,               /* SOC_REFCLK_24_MHZ */
58  	26000000,               /* SOC_REFCLK_26_MHZ */
59  	37400000,               /* SOC_REFCLK_37_4_MHZ */
60  	38400000,               /* SOC_REFCLK_38_4_MHZ */
61  	40000000,               /* SOC_REFCLK_40_MHZ */
62  	52000000,               /* SOC_REFCLK_52_MHZ */
63  };
64  
65  static int ol_target_coredump(void *inst, void *memory_block,
66  					uint32_t block_len);
67  
68  #ifdef FEATURE_SECURE_FIRMWARE
ol_check_fw_hash(struct device * dev,const u8 * data,u32 fw_size,enum ATH_BIN_FILE file)69  static int ol_check_fw_hash(struct device *dev, const u8 *data,
70  			    u32 fw_size, enum ATH_BIN_FILE file)
71  {
72  	u8 *hash = NULL;
73  	u8 *fw_mem = NULL;
74  	u8 digest[SHA256_DIGEST_SIZE];
75  	u8 temp[SHA256_DIGEST_SIZE] = { };
76  	int ret = 0;
77  
78  	switch (file) {
79  	case ATH_BOARD_DATA_FILE:
80  		hash = fw_hash.bdwlan;
81  		break;
82  	case ATH_OTP_FILE:
83  		hash = fw_hash.otp;
84  		break;
85  	case ATH_FIRMWARE_FILE:
86  #ifdef QCA_WIFI_FTM
87  		if (cds_get_conparam() == QDF_GLOBAL_FTM_MODE) {
88  			hash = fw_hash.utf;
89  			break;
90  		}
91  #endif
92  		hash = fw_hash.qwlan;
93  	default:
94  		break;
95  	}
96  
97  	if (!hash) {
98  		BMI_INFO("No entry for file:%d Download FW in non-secure mode",
99  									file);
100  		goto end;
101  	}
102  
103  	if (qdf_mem_cmp(hash, temp, SHA256_DIGEST_SIZE)) {
104  		BMI_INFO("Download FW in non-secure mode:%d", file);
105  		goto end;
106  	}
107  
108  	fw_mem = pld_get_fw_ptr(dev);
109  	if (!fw_mem || (fw_size > MAX_FIRMWARE_SIZE)) {
110  		BMI_ERR("No Memory to copy FW data");
111  		ret = -1;
112  		goto end;
113  	}
114  	qdf_mem_copy(fw_mem, data, fw_size);
115  
116  	ret = pld_get_sha_hash(dev, fw_mem, fw_size, "sha256", digest);
117  
118  	if (ret) {
119  		BMI_ERR("Sha256 Hash computation failed err:%d", ret);
120  		goto end;
121  	}
122  
123  	if (qdf_mem_cmp(hash, digest, SHA256_DIGEST_SIZE)) {
124  		BMI_ERR("Hash Mismatch");
125  		qdf_trace_hex_dump(QDF_MODULE_ID_QDF, QDF_TRACE_LEVEL_FATAL,
126  				   digest, SHA256_DIGEST_SIZE);
127  		qdf_trace_hex_dump(QDF_MODULE_ID_QDF, QDF_TRACE_LEVEL_FATAL,
128  				   hash, SHA256_DIGEST_SIZE);
129  		ret = QDF_STATUS_E_FAILURE;
130  	}
131  end:
132  	return ret;
133  }
134  #endif
135  
136  /**
137   * ol_board_id_to_filename() - Auto BDF board_id to filename conversion
138   * @old_name: name of the default board data file
139   * @board_id: board ID
140   *
141   * The API return board filename based on the board_id and chip_id.
142   * eg: input = "bdwlan30.bin", board_id = 0x01, board_file = "bdwlan30.b01"
143   * Return: The buffer with the formatted board filename.
144   */
ol_board_id_to_filename(const char * old_name,uint16_t board_id)145  static char *ol_board_id_to_filename(const char *old_name,
146  				     uint16_t board_id)
147  {
148  	int name_len;
149  	char *new_name;
150  
151  	name_len = strlen(old_name);
152  	new_name = qdf_mem_malloc(name_len + 1);
153  
154  	if (!new_name)
155  		goto out;
156  
157  	if (board_id > 0xFF)
158  		board_id = 0x0;
159  
160  	qdf_mem_copy(new_name, old_name, name_len);
161  	snprintf(&new_name[name_len - 2], 3, "%.2x", board_id);
162  out:
163  	return new_name;
164  }
165  
166  #ifdef QCA_SIGNED_SPLIT_BINARY_SUPPORT
167  #define SIGNED_SPLIT_BINARY_VALUE true
168  #else
169  #define SIGNED_SPLIT_BINARY_VALUE false
170  #endif
171  
172  static int
__ol_transfer_bin_file(struct ol_context * ol_ctx,enum ATH_BIN_FILE file,uint32_t address,bool compressed)173  __ol_transfer_bin_file(struct ol_context *ol_ctx, enum ATH_BIN_FILE file,
174  		       uint32_t address, bool compressed)
175  {
176  	struct hif_opaque_softc *scn = ol_ctx->scn;
177  	int status = 0;
178  	const char *filename;
179  	const struct firmware *fw_entry;
180  	uint32_t fw_entry_size;
181  	uint8_t *temp_eeprom;
182  	uint32_t board_data_size;
183  	bool bin_sign = false;
184  	int bin_off, bin_len;
185  	SIGN_HEADER_T *sign_header;
186  	struct hif_target_info *tgt_info = hif_get_target_info_handle(scn);
187  	uint32_t target_type = tgt_info->target_type;
188  	struct bmi_info *bmi_ctx = GET_BMI_CONTEXT(ol_ctx);
189  	qdf_device_t qdf_dev = ol_ctx->qdf_dev;
190  	int i;
191  
192  	/*
193  	 * If there is no board data file bases on board id, the default
194  	 * board data file should be used.
195  	 * For factory mode, the sequence for file selection should be
196  	 * utfbd.board_id -> utfbd.bin -> bd.board_id -> bd.bin. So we
197  	 * need to cache 4 file names.
198  	 */
199  	uint32_t bd_files = 1;
200  	char *bd_id_filename[2] = {NULL, NULL};
201  	const char *bd_filename[2] = {NULL, NULL};
202  
203  	switch (file) {
204  	default:
205  		BMI_ERR("%s: Unknown file type", __func__);
206  		return -EINVAL;
207  	case ATH_OTP_FILE:
208  		filename = bmi_ctx->fw_files.otp_data;
209  		if (SIGNED_SPLIT_BINARY_VALUE)
210  			bin_sign = true;
211  
212  		break;
213  	case ATH_FIRMWARE_FILE:
214  		if (QDF_IS_EPPING_ENABLED(cds_get_conparam())) {
215  			filename = bmi_ctx->fw_files.epping_file;
216  			BMI_INFO("%s: Loading epping firmware file %s",
217  						__func__, filename);
218  			break;
219  		}
220  #ifdef QCA_WIFI_FTM
221  		if (cds_get_conparam() == QDF_GLOBAL_FTM_MODE) {
222  			filename = bmi_ctx->fw_files.utf_file;
223  			if (SIGNED_SPLIT_BINARY_VALUE)
224  				bin_sign = true;
225  			BMI_INFO("%s: Loading firmware file %s",
226  						__func__, filename);
227  			break;
228  		}
229  #endif
230  		if (cds_get_conparam() == QDF_GLOBAL_IBSS_MODE &&
231  		    (bmi_ctx->fw_files.ibss_image_file[0] != '\0')) {
232  			filename = bmi_ctx->fw_files.ibss_image_file;
233  		} else {
234  			filename = bmi_ctx->fw_files.image_file;
235  		}
236  
237  		if (SIGNED_SPLIT_BINARY_VALUE)
238  			bin_sign = true;
239  		break;
240  	case ATH_PATCH_FILE:
241  		BMI_INFO("%s: no Patch file defined", __func__);
242  		return 0;
243  	case ATH_BOARD_DATA_FILE:
244  		filename = bmi_ctx->fw_files.board_data;
245  #ifdef QCA_WIFI_FTM
246  		if (cds_get_conparam() == QDF_GLOBAL_FTM_MODE) {
247  			filename = bmi_ctx->fw_files.utf_board_data;
248  			if (SIGNED_SPLIT_BINARY_VALUE)
249  				bin_sign = true;
250  
251  			BMI_INFO("%s: Loading board data file %s",
252  						__func__, filename);
253  
254  			/*
255  			 * In FTM mode, if utf files do not exit.
256  			 * bdwlan should be used.
257  			 */
258  			bd_files = 2;
259  		}
260  #endif /* QCA_WIFI_FTM */
261  		if (SIGNED_SPLIT_BINARY_VALUE)
262  			bin_sign = false;
263  
264  		bd_filename[0] = filename;
265  
266  		/*
267  		 * For factory mode, we should cache 2 group of file names.
268  		 * For mission mode, bd_files==1, only one group of file names.
269  		 */
270  		bd_filename[bd_files - 1] =
271  					bmi_ctx->fw_files.board_data;
272  		for (i = 0; i < bd_files; i++) {
273  			bd_id_filename[i] =
274  				ol_board_id_to_filename(bd_filename[i],
275  							bmi_ctx->board_id);
276  			if (bd_id_filename[i]) {
277  				BMI_INFO("%s: board data file is %s",
278  					 __func__, bd_id_filename[i]);
279  			} else {
280  				BMI_ERR("%s: Fail to allocate board filename",
281  					__func__);
282  			}
283  		}
284  		break;
285  	case ATH_SETUP_FILE:
286  		if (cds_get_conparam() != QDF_GLOBAL_FTM_MODE &&
287  		    !QDF_IS_EPPING_ENABLED(cds_get_conparam())) {
288  			filename = bmi_ctx->fw_files.setup_file;
289  			if (filename[0] == 0) {
290  				BMI_INFO("%s: no Setup file defined", __func__);
291  				return -EPERM;
292  			}
293  
294  			if (SIGNED_SPLIT_BINARY_VALUE)
295  				bin_sign = true;
296  
297  			BMI_INFO("%s: Loading setup file %s",
298  			       __func__, filename);
299  		} else {
300  			BMI_INFO("%s: no Setup file needed", __func__);
301  			return -EPERM;
302  		}
303  		break;
304  	}
305  
306  	/* For FTM mode. bd.bin is used if there is no utf.bin */
307  	if (file == ATH_BOARD_DATA_FILE) {
308  		for (i = 0; i < bd_files; i++) {
309  			if (bd_id_filename[i]) {
310  				BMI_DBG("%s: Trying to load %s",
311  					 __func__, bd_id_filename[i]);
312  				status = request_firmware(&fw_entry,
313  							  bd_id_filename[i],
314  							  qdf_dev->dev);
315  				if (!status)
316  					break;
317  				BMI_ERR("%s: Failed to get %s:%d",
318  					__func__, bd_id_filename[i],
319  					status);
320  			}
321  
322  			/* bd.board_id not exits, using bd.bin */
323  			BMI_DBG("%s: Trying to load default %s",
324  				 __func__, bd_filename[i]);
325  			status = request_firmware(&fw_entry, bd_filename[i],
326  						  qdf_dev->dev);
327  			if (!status)
328  				break;
329  			BMI_ERR("%s: Failed to get default %s:%d",
330  				__func__, bd_filename[i], status);
331  		}
332  	} else {
333  		status = request_firmware(&fw_entry, filename, qdf_dev->dev);
334  	}
335  
336  	if (status) {
337  		BMI_ERR("%s: Failed to get %s", __func__, filename);
338  		status = -ENOENT;
339  		goto release_fw;
340  	}
341  
342  	if (!fw_entry || !fw_entry->data) {
343  		BMI_ERR("Invalid fw_entries");
344  		status = -ENOENT;
345  		goto release_fw;
346  	}
347  
348  	fw_entry_size = fw_entry->size;
349  	temp_eeprom = NULL;
350  
351  #ifdef FEATURE_SECURE_FIRMWARE
352  	if (ol_check_fw_hash(qdf_dev->dev, fw_entry->data,
353  			     fw_entry_size, file)) {
354  		BMI_ERR("Hash Check failed for file:%s", filename);
355  		status = -EINVAL;
356  		goto end;
357  	}
358  #endif
359  
360  	if (file == ATH_BOARD_DATA_FILE) {
361  		uint32_t board_ext_address = 0;
362  		int32_t board_ext_data_size;
363  
364  		temp_eeprom = qdf_mem_malloc(fw_entry_size);
365  		if (!temp_eeprom) {
366  			status = -ENOMEM;
367  			goto release_fw;
368  		}
369  
370  		qdf_mem_copy(temp_eeprom, (uint8_t *) fw_entry->data,
371  			  fw_entry_size);
372  
373  		switch (target_type) {
374  		case TARGET_TYPE_AR6004:
375  			board_data_size = AR6004_BOARD_DATA_SZ;
376  			board_ext_data_size = AR6004_BOARD_EXT_DATA_SZ;
377  			break;
378  		case TARGET_TYPE_AR9888:
379  			board_data_size = AR9888_BOARD_DATA_SZ;
380  			board_ext_data_size = AR9888_BOARD_EXT_DATA_SZ;
381  			break;
382  		default:
383  			board_data_size = 0;
384  			board_ext_data_size = 0;
385  			break;
386  		}
387  
388  		/* Determine where in Target RAM to write Board Data */
389  		bmi_read_memory(HOST_INTEREST_ITEM_ADDRESS(target_type,
390  							   hi_board_ext_data),
391  				(uint8_t *) &board_ext_address, 4, ol_ctx);
392  		BMI_INFO("Board extended Data download address: 0x%x",
393  		       board_ext_address);
394  
395  		/* Check whether the target has allocated memory for extended
396  		 * board data and file contains extended board data
397  		 */
398  
399  		if ((board_ext_address)
400  		    && (fw_entry_size ==
401  			(board_data_size + board_ext_data_size))) {
402  			uint32_t param;
403  
404  			status = bmi_write_memory(board_ext_address,
405  					(uint8_t *)(temp_eeprom +
406  					board_data_size),
407  					board_ext_data_size, ol_ctx);
408  
409  			if (status)
410  				goto end;
411  
412  			/* Record extended board Data initialized */
413  			param = (board_ext_data_size << 16) | 1;
414  			bmi_write_memory(
415  				HOST_INTEREST_ITEM_ADDRESS(target_type,
416  					hi_board_ext_data_config),
417  					(uint8_t *)&param, 4, ol_ctx);
418  
419  			fw_entry_size = board_data_size;
420  		}
421  	}
422  
423  	if (bin_sign && SIGNED_SPLIT_BINARY_VALUE) {
424  		uint32_t chip_id;
425  
426  		if (fw_entry_size < sizeof(SIGN_HEADER_T)) {
427  			BMI_ERR("Invalid binary size %d", fw_entry_size);
428  			status = -EINVAL;
429  			goto end;
430  		}
431  
432  		sign_header = (SIGN_HEADER_T *) fw_entry->data;
433  		chip_id = cpu_to_le32(sign_header->product_id);
434  		if (sign_header->magic_num == SIGN_HEADER_MAGIC
435  		    && (chip_id == AR6320_REV1_1_VERSION
436  			|| chip_id == AR6320_REV1_3_VERSION
437  			|| chip_id == AR6320_REV2_1_VERSION)) {
438  
439  			bin_off = sizeof(SIGN_HEADER_T);
440  			status = bmi_sign_stream_start(address,
441  						(uint8_t *)fw_entry->data,
442  						bin_off, ol_ctx);
443  			if (status) {
444  				BMI_ERR("unable to start sign stream");
445  				status = -EINVAL;
446  				goto end;
447  			}
448  
449  			bin_len = sign_header->rampatch_len - bin_off;
450  			if (bin_len <= 0 || bin_len > fw_entry_size - bin_off) {
451  				BMI_ERR("Invalid sign header");
452  				status = -EINVAL;
453  				goto end;
454  			}
455  		} else {
456  			bin_sign = false;
457  			bin_off = 0;
458  			bin_len = fw_entry_size;
459  		}
460  	} else {
461  		bin_len = fw_entry_size;
462  		bin_off = 0;
463  	}
464  
465  	if (compressed) {
466  		status = bmi_fast_download(address,
467  					   (uint8_t *) fw_entry->data + bin_off,
468  					   bin_len, ol_ctx);
469  	} else {
470  		if (file == ATH_BOARD_DATA_FILE && fw_entry->data) {
471  			status = bmi_write_memory(address,
472  						  (uint8_t *) temp_eeprom,
473  						  fw_entry_size, ol_ctx);
474  		} else {
475  			status = bmi_write_memory(address,
476  						  (uint8_t *) fw_entry->data
477  						  + bin_off, bin_len, ol_ctx);
478  		}
479  	}
480  
481  	if (bin_sign && SIGNED_SPLIT_BINARY_VALUE) {
482  		bin_off += bin_len;
483  		bin_len = sign_header->total_len - sign_header->rampatch_len;
484  
485  		if (bin_len > 0 && bin_len <= fw_entry_size - bin_off) {
486  			status = bmi_sign_stream_start(0,
487  					(uint8_t *)fw_entry->data +
488  					bin_off, bin_len, ol_ctx);
489  			if (status)
490  				BMI_ERR("sign stream error");
491  		}
492  	}
493  
494  end:
495  	if (temp_eeprom)
496  		qdf_mem_free(temp_eeprom);
497  
498  release_fw:
499  	if (fw_entry)
500  		release_firmware(fw_entry);
501  
502  	for (i = 0; i < bd_files; i++) {
503  		if (bd_id_filename[i]) {
504  			qdf_mem_free(bd_id_filename[i]);
505  			bd_id_filename[i] = NULL;
506  		}
507  	}
508  
509  	if (status)
510  		BMI_ERR("%s, BMI operation failed: %d", __func__, __LINE__);
511  	else
512  		BMI_INFO("transferring file: %s size %d bytes done!",
513  			 (filename) ? filename : " ", fw_entry_size);
514  	return status;
515  }
516  
517  static int
ol_transfer_bin_file(struct ol_context * ol_ctx,enum ATH_BIN_FILE file,uint32_t address,bool compressed)518  ol_transfer_bin_file(struct ol_context *ol_ctx, enum ATH_BIN_FILE file,
519  		     uint32_t address, bool compressed)
520  {
521  #define MAX_WAKELOCK_FOR_FW_DOWNLOAD 1000	//1s
522  	int ret;
523  
524  	qdf_wake_lock_timeout_acquire(&ol_ctx->fw_dl_wakelock,
525  				      MAX_WAKELOCK_FOR_FW_DOWNLOAD);
526  
527  	ret = __ol_transfer_bin_file(ol_ctx, file, address, compressed);
528  
529  	qdf_wake_lock_release(&ol_ctx->fw_dl_wakelock, 0);
530  
531  	return ret;
532  }
533  
534  /**
535   * struct ramdump_info: Structure to hold ramdump information
536   * @base: Base address for Ramdump collection
537   * @size: Size of the dump
538   *
539   * Ramdump information.
540   */
541  struct ramdump_info {
542  	void *base;
543  	unsigned long size;
544  };
545  
546  /*
547   * if have platform driver support, reinit will be called by CNSS.
548   * recovery flag will be cleaned and CRASHED indication will be sent
549   * to user space by reinit function. If not support, clean recovery
550   * flag and send CRASHED indication in CLD driver.
551   */
ol_check_clean_recovery_flag(struct ol_context * ol_ctx)552  static inline void ol_check_clean_recovery_flag(struct ol_context *ol_ctx)
553  {
554  	qdf_device_t qdf_dev = ol_ctx->qdf_dev;
555  
556  	if (!pld_have_platform_driver_support(qdf_dev->dev)) {
557  		if (ol_ctx->fw_crashed_cb)
558  			ol_ctx->fw_crashed_cb();
559  	}
560  }
561  
562  #if !defined(QCA_WIFI_3_0)
ol_get_ramdump_mem(struct device * dev,struct ramdump_info * info)563  static inline void ol_get_ramdump_mem(struct device *dev,
564  				      struct ramdump_info *info)
565  {
566  	info->base = pld_get_virt_ramdump_mem(dev, &info->size);
567  }
568  
ol_release_ramdump_mem(struct device * dev,struct ramdump_info * info)569  static inline void ol_release_ramdump_mem(struct device *dev,
570  					  struct ramdump_info *info)
571  {
572  	pld_release_virt_ramdump_mem(dev, info->base);
573  }
574  #else
ol_get_ramdump_mem(struct device * dev,struct ramdump_info * info)575  static inline void ol_get_ramdump_mem(struct device *dev,
576  				      struct ramdump_info *info) { }
ol_release_ramdump_mem(struct device * dev,struct ramdump_info * info)577  static inline void ol_release_ramdump_mem(struct device *dev,
578  					  struct ramdump_info *info) { }
579  #endif
580  
ol_copy_ramdump(struct hif_opaque_softc * scn)581  int ol_copy_ramdump(struct hif_opaque_softc *scn)
582  {
583  	int ret = -1;
584  	struct ramdump_info *info;
585  	qdf_device_t qdf_dev = cds_get_context(QDF_MODULE_ID_QDF_DEVICE);
586  
587  	if (!qdf_dev)
588  		return -EINVAL;
589  
590  	if (pld_is_fw_dump_skipped(qdf_dev->dev)) {
591  		BMI_INFO("%s ssr enabled, skip ramdump", __func__);
592  		return 0;
593  	}
594  	info = qdf_mem_malloc(sizeof(struct ramdump_info));
595  	if (!info)
596  		return -ENOMEM;
597  
598  	ol_get_ramdump_mem(qdf_dev->dev, info);
599  
600  	if (!info->base || !info->size) {
601  		BMI_ERR("%s:ramdump collection fail", __func__);
602  		qdf_mem_free(info);
603  		return -EACCES;
604  	}
605  
606  	ret = ol_target_coredump(scn, info->base, info->size);
607  
608  	ol_release_ramdump_mem(qdf_dev->dev, info);
609  	qdf_mem_free(info);
610  	return ret;
611  }
612  
__ramdump_work_handler(void * data)613  static void __ramdump_work_handler(void *data)
614  {
615  	int ret;
616  	uint32_t host_interest_address;
617  	uint32_t dram_dump_values[4];
618  	uint32_t target_type;
619  	struct hif_target_info *tgt_info;
620  	struct ol_context *ol_ctx = data;
621  	struct hif_opaque_softc *ramdump_scn = ol_ctx->scn;
622  	qdf_device_t qdf_dev = ol_ctx->qdf_dev;
623  	struct ol_config_info *ini_cfg = ol_get_ini_handle(ol_ctx);
624  	tp_wma_handle wma = cds_get_context(QDF_MODULE_ID_WMA);
625  
626  	if (!ramdump_scn) {
627  		BMI_ERR("%s:Ramdump_scn is null:", __func__);
628  		goto out_fail;
629  	}
630  	tgt_info = hif_get_target_info_handle(ramdump_scn);
631  	target_type = tgt_info->target_type;
632  #ifdef WLAN_DEBUG
633  	ret = hif_check_soc_status(ramdump_scn);
634  	if (ret)
635  		goto out_fail;
636  
637  	ret = hif_dump_registers(ramdump_scn);
638  	if (ret)
639  		goto out_fail;
640  
641  #endif
642  
643  	if (hif_diag_read_mem(ramdump_scn,
644  			hif_hia_item_address(target_type,
645  			offsetof(struct host_interest_s, hi_failure_state)),
646  			(uint8_t *)&host_interest_address,
647  			sizeof(uint32_t)) != QDF_STATUS_SUCCESS) {
648  		BMI_ERR("HifDiagReadiMem FW Dump Area Pointer failed!");
649  		ol_copy_ramdump(ramdump_scn);
650  		pld_device_crashed(qdf_dev->dev);
651  		ol_check_clean_recovery_flag(ol_ctx);
652  
653  		return;
654  	}
655  
656  	BMI_ERR("Host interest item address: 0x%08x", host_interest_address);
657  
658  	if (hif_diag_read_mem(ramdump_scn, host_interest_address,
659  			      (uint8_t *) &dram_dump_values[0],
660  			      4 * sizeof(uint32_t)) != QDF_STATUS_SUCCESS) {
661  		BMI_ERR("HifDiagReadiMem FW Dump Area failed!");
662  		goto out_fail;
663  	}
664  	BMI_ERR("FW Assertion at PC: 0x%08x BadVA: 0x%08x TargetID: 0x%08x",
665  	       dram_dump_values[2], dram_dump_values[3], dram_dump_values[0]);
666  
667  	if (ol_copy_ramdump(ramdump_scn))
668  		goto out_fail;
669  
670  	BMI_ERR("%s: RAM dump collecting completed!", __func__);
671  	qdf_event_set(&wma->recovery_event);
672  
673  	/*
674  	 * if unloading is in progress, then skip SSR,
675  	 * otherwise notify SSR framework the target has crashed.
676  	 */
677  	if (cds_is_load_or_unload_in_progress())
678  		cds_set_recovery_in_progress(false);
679  	else {
680  		pld_device_crashed(qdf_dev->dev);
681  		ol_check_clean_recovery_flag(ol_ctx);
682  	}
683  	return;
684  
685  out_fail:
686  	qdf_event_set(&wma->recovery_event);
687  	/* Silent SSR on dump failure */
688  	if (ini_cfg->enable_self_recovery)
689  		pld_device_self_recovery(qdf_dev->dev,
690  					 PLD_REASON_DEFAULT);
691  	else
692  		pld_device_crashed(qdf_dev->dev);
693  
694  	ol_check_clean_recovery_flag(ol_ctx);
695  }
696  
ramdump_work_handler(void * data)697  void ramdump_work_handler(void *data)
698  {
699  	struct qdf_op_sync *op_sync;
700  
701  	if (qdf_op_protect(&op_sync))
702  		return;
703  
704  	__ramdump_work_handler(data);
705  
706  	qdf_op_unprotect(op_sync);
707  }
708  
fw_indication_work_handler(void * data)709  void fw_indication_work_handler(void *data)
710  {
711  	struct ol_context *ol_ctx = data;
712  	qdf_device_t qdf_dev = ol_ctx->qdf_dev;
713  
714  	pld_device_self_recovery(qdf_dev->dev,
715  				 PLD_REASON_DEFAULT);
716  
717  	ol_check_clean_recovery_flag(ol_ctx);
718  }
719  
ol_target_failure(void * instance,QDF_STATUS status)720  void ol_target_failure(void *instance, QDF_STATUS status)
721  {
722  	struct ol_context *ol_ctx = instance;
723  	struct hif_opaque_softc *scn = ol_ctx->scn;
724  	tp_wma_handle wma = cds_get_context(QDF_MODULE_ID_WMA);
725  	struct ol_config_info *ini_cfg = ol_get_ini_handle(ol_ctx);
726  	qdf_device_t qdf_dev = ol_ctx->qdf_dev;
727  	int ret;
728  	bool skip_recovering_check = false;
729  	enum hif_target_status target_status = hif_get_target_status(scn);
730  
731  	if (hif_get_bus_type(scn) == QDF_BUS_TYPE_SNOC) {
732  		BMI_ERR("SNOC doesn't support this code path!");
733  		return;
734  	}
735  
736  	/* If Host driver trigger target failure, skip recovering check */
737  	if (cds_is_target_asserting())
738  		skip_recovering_check = true;
739  
740  	if (TARGET_STATUS_RESET == target_status) {
741  		BMI_ERR("Target is already asserted, ignore!");
742  		goto out;
743  	}
744  
745  	hif_set_target_status(scn, TARGET_STATUS_RESET);
746  
747  	if (hif_get_bus_type(scn) == QDF_BUS_TYPE_USB) {
748  		if (status == QDF_STATUS_E_USB_ERROR)
749  			hif_ramdump_handler(scn);
750  		goto out;
751  	}
752  
753  	if (!skip_recovering_check && cds_is_driver_recovering()) {
754  		BMI_ERR("%s: Recovery in progress, ignore!\n", __func__);
755  		return;
756  	}
757  
758  	if (cds_is_driver_in_bad_state()) {
759  		BMI_ERR("%s: Driver in bad state, ignore!\n", __func__);
760  		goto out;
761  	}
762  
763  	if (cds_is_load_or_unload_in_progress()) {
764  		BMI_ERR("%s: Loading/Unloading is in progress, ignore!",
765  		       __func__);
766  		goto out;
767  	}
768  	cds_set_target_ready(false);
769  	cds_set_recovery_in_progress(true);
770  
771  	ret = hif_check_fw_reg(scn);
772  	if (0 == ret) {
773  		if (ini_cfg->enable_self_recovery) {
774  			qdf_sched_work(0, &ol_ctx->fw_indication_work);
775  			goto out;
776  		}
777  	} else if (-1 == ret) {
778  		goto out;
779  	}
780  
781  	BMI_ERR("XXX TARGET ASSERTED XXX");
782  
783  	cds_svc_fw_shutdown_ind(qdf_dev->dev);
784  	/* Collect the RAM dump through a workqueue */
785  	if (ini_cfg->enable_ramdump_collection) {
786  		qdf_sched_work(0, &ol_ctx->ramdump_work);
787  	} else {
788  		pr_debug("%s: athdiag read for target reg\n", __func__);
789  		qdf_event_set(&wma->recovery_event);
790  	}
791  
792  	return;
793  out:
794  	qdf_event_set(&wma->recovery_event);
795  	return;
796  }
797  
798  #ifdef CONFIG_DISABLE_CDC_MAX_PERF_WAR
ol_disable_cdc_max_perf(struct ol_context * ol_ctx)799  static QDF_STATUS ol_disable_cdc_max_perf(struct ol_context *ol_ctx)
800  {
801  	uint32_t param;
802  	struct hif_opaque_softc *scn = ol_ctx->scn;
803  	struct hif_target_info *tgt_info = hif_get_target_info_handle(scn);
804  	uint32_t target_type = tgt_info->target_type;
805  
806  	/* set the firmware to disable CDC max perf WAR */
807  		if (bmi_read_memory(hif_hia_item_address(target_type,
808  			offsetof(struct host_interest_s, hi_option_flag2)),
809  			(uint8_t *) &param, 4, ol_ctx) != QDF_STATUS_SUCCESS) {
810  			BMI_ERR("BMI READ for setting cdc max perf failed");
811  			return QDF_STATUS_E_FAILURE;
812  		}
813  
814  		param |= HI_OPTION_DISABLE_CDC_MAX_PERF_WAR;
815  		if (bmi_write_memory(
816  			hif_hia_item_address(target_type,
817  			offsetof(struct host_interest_s, hi_option_flag2)),
818  			(uint8_t *)&param, 4, ol_ctx) != QDF_STATUS_SUCCESS) {
819  			BMI_ERR("setting cdc max perf failed");
820  			return QDF_STATUS_E_FAILURE;
821  		}
822  
823  	return QDF_STATUS_SUCCESS;
824  }
825  
826  #else
ol_disable_cdc_max_perf(struct ol_context * ol_ctx)827  static QDF_STATUS ol_disable_cdc_max_perf(struct ol_context *ol_ctx)
828  {
829  	return QDF_STATUS_SUCCESS;
830  }
831  
832  #endif
833  
834  #ifdef WLAN_FEATURE_LPSS
ol_set_lpass_support(struct ol_context * ol_ctx)835  static QDF_STATUS ol_set_lpass_support(struct ol_context *ol_ctx)
836  {
837  	uint32_t param;
838  	struct hif_opaque_softc *scn = ol_ctx->scn;
839  	struct hif_target_info *tgt_info = hif_get_target_info_handle(scn);
840  	struct ol_config_info *ini_cfg = ol_get_ini_handle(ol_ctx);
841  	uint32_t target_type = tgt_info->target_type;
842  
843  	if (ini_cfg->enable_lpass_support) {
844  		if (bmi_read_memory(hif_hia_item_address(target_type,
845  			offsetof(struct host_interest_s, hi_option_flag2)),
846  			(uint8_t *) &param, 4, ol_ctx) != QDF_STATUS_SUCCESS) {
847  			BMI_ERR("BMI READ:Setting LPASS Support failed");
848  			return QDF_STATUS_E_FAILURE;
849  		}
850  
851  		param |= HI_OPTION_DBUART_SUPPORT;
852  		if (bmi_write_memory(
853  			hif_hia_item_address(target_type,
854  			offsetof(struct host_interest_s, hi_option_flag2)),
855  			(uint8_t *)&param, 4, ol_ctx) != QDF_STATUS_SUCCESS) {
856  			BMI_ERR("BMI_READ for setting LPASS Support fail");
857  			return QDF_STATUS_E_FAILURE;
858  		}
859  	}
860  
861  	return QDF_STATUS_SUCCESS;
862  }
863  
864  #else
ol_set_lpass_support(struct ol_context * ol_ctx)865  static QDF_STATUS ol_set_lpass_support(struct ol_context *ol_ctx)
866  {
867  	return QDF_STATUS_SUCCESS;
868  }
869  
870  #endif
871  
872  
ol_configure_target(struct ol_context * ol_ctx)873  QDF_STATUS ol_configure_target(struct ol_context *ol_ctx)
874  {
875  	uint32_t param;
876  	struct pld_platform_cap cap = {0};
877  	int ret;
878  	struct hif_opaque_softc *scn = ol_ctx->scn;
879  	struct hif_target_info *tgt_info = hif_get_target_info_handle(scn);
880  	uint32_t target_type = tgt_info->target_type;
881  	qdf_device_t qdf_dev = ol_ctx->qdf_dev;
882  
883  	/* Tell target which HTC version it is used */
884  	param = HTC_PROTOCOL_VERSION;
885  	if (bmi_write_memory(
886  		hif_hia_item_address(target_type,
887  		offsetof(struct host_interest_s, hi_app_host_interest)),
888  		(uint8_t *) &param, 4, ol_ctx) != QDF_STATUS_SUCCESS) {
889  		BMI_ERR("bmi_write_memory for htc version failed");
890  		return QDF_STATUS_E_FAILURE;
891  	}
892  
893  	/* set the firmware mode to STA/IBSS/AP */
894  	{
895  		if (bmi_read_memory(hif_hia_item_address(target_type,
896  			offsetof(struct host_interest_s, hi_option_flag)),
897  			(uint8_t *)&param, 4, ol_ctx) != QDF_STATUS_SUCCESS) {
898  			BMI_ERR("bmi_read_memory for setting fwmode failed");
899  			return QDF_STATUS_E_FAILURE;
900  		}
901  
902  		/* TODO following parameters need to be re-visited. */
903  		param |= (1 << HI_OPTION_NUM_DEV_SHIFT); /* num_device */
904  		/* Firmware mode ?? */
905  		param |= (HI_OPTION_FW_MODE_AP << HI_OPTION_FW_MODE_SHIFT);
906  		/* mac_addr_method */
907  		param |= (1 << HI_OPTION_MAC_ADDR_METHOD_SHIFT);
908  		/* firmware_bridge */
909  		param |= (0 << HI_OPTION_FW_BRIDGE_SHIFT);
910  		/* fwsubmode */
911  		param |= (0 << HI_OPTION_FW_SUBMODE_SHIFT);
912  
913  		BMI_INFO("NUM_DEV=%d FWMODE=0x%x FWSUBMODE=0x%x FWBR_BUF %d",
914  		       1, HI_OPTION_FW_MODE_AP, 0, 0);
915  
916  		if (bmi_write_memory(
917  			hif_hia_item_address(target_type,
918  			offsetof(struct host_interest_s, hi_option_flag)),
919  			(uint8_t *)&param, 4, ol_ctx) != QDF_STATUS_SUCCESS) {
920  			BMI_ERR("BMI WRITE for setting fwmode failed");
921  			return QDF_STATUS_E_FAILURE;
922  		}
923  	}
924  	if (hif_get_bus_type(scn) == QDF_BUS_TYPE_PCI) {
925  		if (ol_disable_cdc_max_perf(ol_ctx))
926  			return QDF_STATUS_E_FAILURE;
927  
928  		qdf_mem_zero(&cap, sizeof(cap));
929  
930  		ret = pld_get_platform_cap(qdf_dev->dev, &cap);
931  		if (ret)
932  			BMI_ERR("platform capability info not available");
933  
934  		if (!ret && cap.cap_flag & PLD_HAS_EXTERNAL_SWREG) {
935  			if (bmi_read_memory(hif_hia_item_address(target_type,
936  				offsetof(struct host_interest_s,
937  					 hi_option_flag2)),
938  				(uint8_t *)&param, 4, ol_ctx) !=
939  							QDF_STATUS_SUCCESS) {
940  				BMI_ERR("BMI READ failed for external SWREG");
941  				return QDF_STATUS_E_FAILURE;
942  			}
943  
944  			param |= HI_OPTION_USE_EXT_LDO;
945  			if (bmi_write_memory(
946  				hif_hia_item_address(target_type,
947  					offsetof(struct host_interest_s,
948  						 hi_option_flag2)),
949  					(uint8_t *)&param, 4, ol_ctx) !=
950  							QDF_STATUS_SUCCESS) {
951  				BMI_ERR("BMI WRITE failed for external SWREG");
952  				return QDF_STATUS_E_FAILURE;
953  			}
954  		}
955  
956  		if (ol_set_lpass_support(ol_ctx))
957  			return QDF_STATUS_E_FAILURE;
958  	}
959  
960  	/* If host is running on a BE CPU, set the host interest area */
961  	{
962  #ifdef BIG_ENDIAN_HOST
963  		param = 1;
964  #else
965  		param = 0;
966  #endif
967  		if (bmi_write_memory(
968  			hif_hia_item_address(target_type,
969  			offsetof(struct host_interest_s, hi_be)),
970  			(uint8_t *) &param, 4, ol_ctx) != QDF_STATUS_SUCCESS) {
971  			BMI_ERR("setting host CPU BE mode failed");
972  			return QDF_STATUS_E_FAILURE;
973  		}
974  	}
975  
976  	/* FW descriptor/Data swap flags */
977  	param = 0;
978  	if (bmi_write_memory(
979  		hif_hia_item_address(target_type,
980  		offsetof(struct host_interest_s, hi_fw_swap)),
981  		(uint8_t *) &param, 4, ol_ctx) != QDF_STATUS_SUCCESS) {
982  		BMI_ERR("BMI WRITE failed setting FW data/desc swap flags");
983  		return QDF_STATUS_E_FAILURE;
984  	}
985  
986  	return QDF_STATUS_SUCCESS;
987  }
988  
989  static int
ol_check_dataset_patch(struct hif_opaque_softc * scn,uint32_t * address)990  ol_check_dataset_patch(struct hif_opaque_softc *scn, uint32_t *address)
991  {
992  	/* Check if patch file needed for this target type/version. */
993  	return 0;
994  }
995  
ol_fw_populate_clk_settings(enum a_refclk_speed_t refclk,struct cmnos_clock_s * clock_s)996  static QDF_STATUS ol_fw_populate_clk_settings(enum a_refclk_speed_t refclk,
997  					      struct cmnos_clock_s *clock_s)
998  {
999  	if (!clock_s)
1000  		return QDF_STATUS_E_FAILURE;
1001  
1002  	switch (refclk) {
1003  	case SOC_REFCLK_48_MHZ:
1004  		clock_s->wlan_pll.div = 0xE;
1005  		clock_s->wlan_pll.rnfrac = 0x2AAA8;
1006  		clock_s->pll_settling_time = 2400;
1007  		break;
1008  	case SOC_REFCLK_19_2_MHZ:
1009  		clock_s->wlan_pll.div = 0x24;
1010  		clock_s->wlan_pll.rnfrac = 0x2AAA8;
1011  		clock_s->pll_settling_time = 960;
1012  		break;
1013  	case SOC_REFCLK_24_MHZ:
1014  		clock_s->wlan_pll.div = 0x1D;
1015  		clock_s->wlan_pll.rnfrac = 0x15551;
1016  		clock_s->pll_settling_time = 1200;
1017  		break;
1018  	case SOC_REFCLK_26_MHZ:
1019  		clock_s->wlan_pll.div = 0x1B;
1020  		clock_s->wlan_pll.rnfrac = 0x4EC4;
1021  		clock_s->pll_settling_time = 1300;
1022  		break;
1023  	case SOC_REFCLK_37_4_MHZ:
1024  		clock_s->wlan_pll.div = 0x12;
1025  		clock_s->wlan_pll.rnfrac = 0x34B49;
1026  		clock_s->pll_settling_time = 1870;
1027  		break;
1028  	case SOC_REFCLK_38_4_MHZ:
1029  		clock_s->wlan_pll.div = 0x12;
1030  		clock_s->wlan_pll.rnfrac = 0x15551;
1031  		clock_s->pll_settling_time = 1920;
1032  		break;
1033  	case SOC_REFCLK_40_MHZ:
1034  		clock_s->wlan_pll.div = 0x11;
1035  		clock_s->wlan_pll.rnfrac = 0x26665;
1036  		clock_s->pll_settling_time = 2000;
1037  		break;
1038  	case SOC_REFCLK_52_MHZ:
1039  		clock_s->wlan_pll.div = 0x1B;
1040  		clock_s->wlan_pll.rnfrac = 0x4EC4;
1041  		clock_s->pll_settling_time = 2600;
1042  		break;
1043  	case SOC_REFCLK_UNKNOWN:
1044  		clock_s->wlan_pll.refdiv = 0;
1045  		clock_s->wlan_pll.div = 0;
1046  		clock_s->wlan_pll.rnfrac = 0;
1047  		clock_s->wlan_pll.outdiv = 0;
1048  		clock_s->pll_settling_time = 1024;
1049  		clock_s->refclk_hz = 0;
1050  		fallthrough;
1051  	default:
1052  		return QDF_STATUS_E_FAILURE;
1053  	}
1054  
1055  	clock_s->refclk_hz = refclk_speed_to_hz[refclk];
1056  	clock_s->wlan_pll.refdiv = 0;
1057  	clock_s->wlan_pll.outdiv = 1;
1058  
1059  	return QDF_STATUS_SUCCESS;
1060  }
1061  
ol_patch_pll_switch(struct ol_context * ol_ctx)1062  static QDF_STATUS ol_patch_pll_switch(struct ol_context *ol_ctx)
1063  {
1064  	struct hif_opaque_softc *hif = ol_ctx->scn;
1065  	QDF_STATUS status = QDF_STATUS_SUCCESS;
1066  	uint32_t addr = 0;
1067  	uint32_t reg_val = 0;
1068  	uint32_t mem_val = 0;
1069  	struct cmnos_clock_s clock_s;
1070  	uint32_t cmnos_core_clk_div_addr = 0;
1071  	uint32_t cmnos_cpu_pll_init_done_addr = 0;
1072  	uint32_t cmnos_cpu_speed_addr = 0;
1073  	struct hif_target_info *tgt_info = hif_get_target_info_handle(hif);
1074  	uint32_t target_version = tgt_info->target_version;
1075  	struct targetdef_t *scn = &ol_ctx->tgt_def;
1076  
1077  	switch (target_version) {
1078  	case AR6320_REV1_1_VERSION:
1079  		cmnos_core_clk_div_addr = AR6320_CORE_CLK_DIV_ADDR;
1080  		cmnos_cpu_pll_init_done_addr = AR6320_CPU_PLL_INIT_DONE_ADDR;
1081  		cmnos_cpu_speed_addr = AR6320_CPU_SPEED_ADDR;
1082  		break;
1083  	case AR6320_REV1_3_VERSION:
1084  	case AR6320_REV2_1_VERSION:
1085  		cmnos_core_clk_div_addr = AR6320V2_CORE_CLK_DIV_ADDR;
1086  		cmnos_cpu_pll_init_done_addr = AR6320V2_CPU_PLL_INIT_DONE_ADDR;
1087  		cmnos_cpu_speed_addr = AR6320V2_CPU_SPEED_ADDR;
1088  		break;
1089  	case AR6320_REV3_VERSION:
1090  	case AR6320_REV3_2_VERSION:
1091  	case QCA9379_REV1_VERSION:
1092  	case QCA9377_REV1_1_VERSION:
1093  		cmnos_core_clk_div_addr = AR6320V3_CORE_CLK_DIV_ADDR;
1094  		cmnos_cpu_pll_init_done_addr = AR6320V3_CPU_PLL_INIT_DONE_ADDR;
1095  		cmnos_cpu_speed_addr = AR6320V3_CPU_SPEED_ADDR;
1096  		break;
1097  	default:
1098  		BMI_ERR("%s: Unsupported target version %x", __func__,
1099  							target_version);
1100  		goto end;
1101  	}
1102  
1103  	addr = (RTC_SOC_BASE_ADDRESS | EFUSE_OFFSET);
1104  	status = bmi_read_soc_register(addr, &reg_val, ol_ctx);
1105  	if (status != QDF_STATUS_SUCCESS) {
1106  		BMI_ERR("Failed to read EFUSE Addr");
1107  		goto end;
1108  	}
1109  
1110  	status = ol_fw_populate_clk_settings(EFUSE_XTAL_SEL_GET(reg_val),
1111  					     &clock_s);
1112  	if (status != QDF_STATUS_SUCCESS) {
1113  		BMI_ERR("Failed to set clock settings");
1114  		goto end;
1115  	}
1116  	BMI_DBG("crystal_freq: %dHz", clock_s.refclk_hz);
1117  
1118  	/* ------Step 1---- */
1119  	reg_val = 0;
1120  	addr = (RTC_SOC_BASE_ADDRESS | BB_PLL_CONFIG_OFFSET);
1121  	status = bmi_read_soc_register(addr, &reg_val, ol_ctx);
1122  	if (status != QDF_STATUS_SUCCESS) {
1123  		BMI_ERR("Failed to read PLL_CONFIG Addr");
1124  		goto end;
1125  	}
1126  	BMI_DBG("Step 1a: %8X", reg_val);
1127  
1128  	reg_val &= ~(BB_PLL_CONFIG_FRAC_MASK | BB_PLL_CONFIG_OUTDIV_MASK);
1129  	reg_val |= (BB_PLL_CONFIG_FRAC_SET(clock_s.wlan_pll.rnfrac) |
1130  		    BB_PLL_CONFIG_OUTDIV_SET(clock_s.wlan_pll.outdiv));
1131  	status = bmi_write_soc_register(addr, reg_val, ol_ctx);
1132  	if (status != QDF_STATUS_SUCCESS) {
1133  		BMI_ERR("Failed to write PLL_CONFIG Addr");
1134  		goto end;
1135  	}
1136  
1137  	reg_val = 0;
1138  	status = bmi_read_soc_register(addr, &reg_val, ol_ctx);
1139  	if (status != QDF_STATUS_SUCCESS) {
1140  		BMI_ERR("Failed to read back PLL_CONFIG Addr");
1141  		goto end;
1142  	}
1143  	BMI_DBG("Step 1b: %8X", reg_val);
1144  
1145  	/* ------Step 2---- */
1146  	reg_val = 0;
1147  	addr = (RTC_WMAC_BASE_ADDRESS | WLAN_PLL_SETTLE_OFFSET);
1148  	status = bmi_read_soc_register(addr, &reg_val, ol_ctx);
1149  	if (status != QDF_STATUS_SUCCESS) {
1150  		BMI_ERR("Failed to read PLL_SETTLE Addr");
1151  		goto end;
1152  	}
1153  	BMI_DBG("Step 2a: %8X", reg_val);
1154  
1155  	reg_val &= ~WLAN_PLL_SETTLE_TIME_MASK;
1156  	reg_val |= WLAN_PLL_SETTLE_TIME_SET(clock_s.pll_settling_time);
1157  	status = bmi_write_soc_register(addr, reg_val, ol_ctx);
1158  	if (status != QDF_STATUS_SUCCESS) {
1159  		BMI_ERR("Failed to write PLL_SETTLE Addr");
1160  		goto end;
1161  	}
1162  
1163  	reg_val = 0;
1164  	status = bmi_read_soc_register(addr, &reg_val, ol_ctx);
1165  	if (status != QDF_STATUS_SUCCESS) {
1166  		BMI_ERR("Failed to read back PLL_SETTLE Addr");
1167  		goto end;
1168  	}
1169  	BMI_DBG("Step 2b: %8X", reg_val);
1170  
1171  	/* ------Step 3---- */
1172  	reg_val = 0;
1173  	addr = (RTC_SOC_BASE_ADDRESS | SOC_CORE_CLK_CTRL_OFFSET);
1174  	status = bmi_read_soc_register(addr, &reg_val, ol_ctx);
1175  	if (status != QDF_STATUS_SUCCESS) {
1176  		BMI_ERR("Failed to read CLK_CTRL Addr");
1177  		goto end;
1178  	}
1179  	BMI_DBG("Step 3a: %8X", reg_val);
1180  
1181  	reg_val &= ~SOC_CORE_CLK_CTRL_DIV_MASK;
1182  	reg_val |= SOC_CORE_CLK_CTRL_DIV_SET(1);
1183  	status = bmi_write_soc_register(addr, reg_val, ol_ctx);
1184  	if (status != QDF_STATUS_SUCCESS) {
1185  		BMI_ERR("Failed to write CLK_CTRL Addr");
1186  		goto end;
1187  	}
1188  
1189  	reg_val = 0;
1190  	status = bmi_read_soc_register(addr, &reg_val, ol_ctx);
1191  	if (status != QDF_STATUS_SUCCESS) {
1192  		BMI_ERR("Failed to read back CLK_CTRL Addr");
1193  		goto end;
1194  	}
1195  	BMI_DBG("Step 3b: %8X", reg_val);
1196  
1197  	/* ------Step 4----- */
1198  	mem_val = 1;
1199  	status = bmi_write_memory(cmnos_core_clk_div_addr,
1200  				  (uint8_t *) &mem_val, 4, ol_ctx);
1201  	if (status != QDF_STATUS_SUCCESS) {
1202  		BMI_ERR("Failed to write CLK_DIV Addr");
1203  		goto end;
1204  	}
1205  
1206  	/* ------Step 5----- */
1207  	reg_val = 0;
1208  	addr = (RTC_WMAC_BASE_ADDRESS | WLAN_PLL_CONTROL_OFFSET);
1209  	status = bmi_read_soc_register(addr, &reg_val, ol_ctx);
1210  	if (status != QDF_STATUS_SUCCESS) {
1211  		BMI_ERR("Failed to read PLL_CTRL Addr");
1212  		goto end;
1213  	}
1214  	BMI_DBG("Step 5a: %8X", reg_val);
1215  
1216  	reg_val &= ~(WLAN_PLL_CONTROL_REFDIV_MASK | WLAN_PLL_CONTROL_DIV_MASK |
1217  		     WLAN_PLL_CONTROL_NOPWD_MASK);
1218  	reg_val |= (WLAN_PLL_CONTROL_REFDIV_SET(clock_s.wlan_pll.refdiv) |
1219  		    WLAN_PLL_CONTROL_DIV_SET(clock_s.wlan_pll.div) |
1220  		    WLAN_PLL_CONTROL_NOPWD_SET(1));
1221  	status = bmi_write_soc_register(addr, reg_val, ol_ctx);
1222  	if (status != QDF_STATUS_SUCCESS) {
1223  		BMI_ERR("Failed to write PLL_CTRL Addr");
1224  		goto end;
1225  	}
1226  
1227  	reg_val = 0;
1228  	status = bmi_read_soc_register(addr, &reg_val, ol_ctx);
1229  	if (status != QDF_STATUS_SUCCESS) {
1230  		BMI_ERR("Failed to read back PLL_CTRL Addr");
1231  		goto end;
1232  	}
1233  	qdf_udelay(100);
1234  	BMI_DBG("Step 5b: %8X", reg_val);
1235  
1236  	/* ------Step 6------- */
1237  	do {
1238  		reg_val = 0;
1239  		status = bmi_read_soc_register((RTC_WMAC_BASE_ADDRESS |
1240  				RTC_SYNC_STATUS_OFFSET), &reg_val, ol_ctx);
1241  		if (status != QDF_STATUS_SUCCESS) {
1242  			BMI_ERR("Failed to read RTC_SYNC_STATUS Addr");
1243  			goto end;
1244  		}
1245  	} while (RTC_SYNC_STATUS_PLL_CHANGING_GET(reg_val));
1246  
1247  	/* ------Step 7------- */
1248  	reg_val = 0;
1249  	addr = (RTC_WMAC_BASE_ADDRESS | WLAN_PLL_CONTROL_OFFSET);
1250  	status = bmi_read_soc_register(addr, &reg_val, ol_ctx);
1251  	if (status != QDF_STATUS_SUCCESS) {
1252  		BMI_ERR("Failed to read PLL_CTRL Addr for CTRL_BYPASS");
1253  		goto end;
1254  	}
1255  	BMI_DBG("Step 7a: %8X", reg_val);
1256  
1257  	reg_val &= ~WLAN_PLL_CONTROL_BYPASS_MASK;
1258  	reg_val |= WLAN_PLL_CONTROL_BYPASS_SET(0);
1259  	status = bmi_write_soc_register(addr, reg_val, ol_ctx);
1260  	if (status != QDF_STATUS_SUCCESS) {
1261  		BMI_ERR("Failed to write PLL_CTRL Addr for CTRL_BYPASS");
1262  		goto end;
1263  	}
1264  
1265  	reg_val = 0;
1266  	status = bmi_read_soc_register(addr, &reg_val, ol_ctx);
1267  	if (status != QDF_STATUS_SUCCESS) {
1268  		BMI_ERR("Failed to read back PLL_CTRL Addr for CTRL_BYPASS");
1269  		goto end;
1270  	}
1271  	BMI_DBG("Step 7b: %8X", reg_val);
1272  
1273  	/* ------Step 8-------- */
1274  	do {
1275  		reg_val = 0;
1276  		status = bmi_read_soc_register((RTC_WMAC_BASE_ADDRESS |
1277  				RTC_SYNC_STATUS_OFFSET), &reg_val, ol_ctx);
1278  		if (status != QDF_STATUS_SUCCESS) {
1279  			BMI_ERR("Failed to read SYNC_STATUS Addr");
1280  			goto end;
1281  		}
1282  	} while (RTC_SYNC_STATUS_PLL_CHANGING_GET(reg_val));
1283  
1284  	/* ------Step 9-------- */
1285  	reg_val = 0;
1286  	addr = (RTC_SOC_BASE_ADDRESS | SOC_CPU_CLOCK_OFFSET);
1287  	status = bmi_read_soc_register(addr, &reg_val, ol_ctx);
1288  	if (status != QDF_STATUS_SUCCESS) {
1289  		BMI_ERR("Failed to read CPU_CLK Addr");
1290  		goto end;
1291  	}
1292  	BMI_DBG("Step 9a: %8X", reg_val);
1293  
1294  	reg_val &= ~SOC_CPU_CLOCK_STANDARD_MASK;
1295  	reg_val |= SOC_CPU_CLOCK_STANDARD_SET(1);
1296  	status = bmi_write_soc_register(addr, reg_val, ol_ctx);
1297  	if (status != QDF_STATUS_SUCCESS) {
1298  		BMI_ERR("Failed to write CPU_CLK Addr");
1299  		goto end;
1300  	}
1301  
1302  	reg_val = 0;
1303  	status = bmi_read_soc_register(addr, &reg_val, ol_ctx);
1304  	if (status != QDF_STATUS_SUCCESS) {
1305  		BMI_ERR("Failed to read back CPU_CLK Addr");
1306  		goto end;
1307  	}
1308  	BMI_DBG("Step 9b: %8X", reg_val);
1309  
1310  	/* ------Step 10------- */
1311  	reg_val = 0;
1312  	addr = (RTC_WMAC_BASE_ADDRESS | WLAN_PLL_CONTROL_OFFSET);
1313  	status = bmi_read_soc_register(addr, &reg_val, ol_ctx);
1314  	if (status != QDF_STATUS_SUCCESS) {
1315  		BMI_ERR("Failed to read PLL_CTRL Addr for NOPWD");
1316  		goto end;
1317  	}
1318  	BMI_DBG("Step 10a: %8X", reg_val);
1319  
1320  	reg_val &= ~WLAN_PLL_CONTROL_NOPWD_MASK;
1321  	status = bmi_write_soc_register(addr, reg_val, ol_ctx);
1322  	if (status != QDF_STATUS_SUCCESS) {
1323  		BMI_ERR("Failed to write PLL_CTRL Addr for NOPWD");
1324  		goto end;
1325  	}
1326  	reg_val = 0;
1327  	status = bmi_read_soc_register(addr, &reg_val, ol_ctx);
1328  	if (status != QDF_STATUS_SUCCESS) {
1329  		BMI_ERR("Failed to read back PLL_CTRL Addr for NOPWD");
1330  		goto end;
1331  	}
1332  	BMI_DBG("Step 10b: %8X", reg_val);
1333  
1334  	/* ------Step 11------- */
1335  	mem_val = 1;
1336  	status = bmi_write_memory(cmnos_cpu_pll_init_done_addr,
1337  				  (uint8_t *) &mem_val, 4, ol_ctx);
1338  	if (status != QDF_STATUS_SUCCESS) {
1339  		BMI_ERR("Failed to write PLL_INIT Addr");
1340  		goto end;
1341  	}
1342  
1343  	mem_val = TARGET_CPU_FREQ;
1344  	status = bmi_write_memory(cmnos_cpu_speed_addr,
1345  				  (uint8_t *) &mem_val, 4, ol_ctx);
1346  	if (status != QDF_STATUS_SUCCESS) {
1347  		BMI_ERR("Failed to write CPU_SPEED Addr");
1348  		goto end;
1349  	}
1350  
1351  end:
1352  	return status;
1353  }
1354  
ol_download_firmware(struct ol_context * ol_ctx)1355  QDF_STATUS ol_download_firmware(struct ol_context *ol_ctx)
1356  {
1357  	struct hif_opaque_softc *scn = ol_ctx->scn;
1358  	uint32_t param, address = 0;
1359  	QDF_STATUS status = !QDF_STATUS_SUCCESS;
1360  	QDF_STATUS ret;
1361  	struct hif_target_info *tgt_info = hif_get_target_info_handle(scn);
1362  	struct ol_config_info *ini_cfg = ol_get_ini_handle(ol_ctx);
1363  	uint32_t target_type = tgt_info->target_type;
1364  	uint32_t target_version = tgt_info->target_version;
1365  	struct bmi_info *bmi_ctx = GET_BMI_CONTEXT(ol_ctx);
1366  	qdf_device_t qdf_dev = ol_ctx->qdf_dev;
1367  
1368  	if (0 != pld_get_fw_files_for_target(qdf_dev->dev,
1369  					     &bmi_ctx->fw_files,
1370  					      target_type,
1371  					      target_version)) {
1372  		BMI_ERR("%s: No FW files from platform driver", __func__);
1373  		return QDF_STATUS_E_FAILURE;
1374  	}
1375  
1376  	/* Transfer Board Data from Target EEPROM to Target RAM */
1377  	/* Determine where in Target RAM to write Board Data */
1378  	bmi_read_memory(hif_hia_item_address(target_type,
1379  			offsetof(struct host_interest_s, hi_board_data)),
1380  			(uint8_t *)&address, 4, ol_ctx);
1381  
1382  	if (!address) {
1383  		address = AR6004_REV5_BOARD_DATA_ADDRESS;
1384  		BMI_DBG("%s: Target address not known! Using 0x%x",
1385  						__func__, address);
1386  	}
1387  
1388  	if (hif_get_bus_type(scn) != QDF_BUS_TYPE_USB) {
1389  		ret = ol_patch_pll_switch(ol_ctx);
1390  		if (ret != QDF_STATUS_SUCCESS) {
1391  			BMI_ERR("pll switch failed. status %d", ret);
1392  			return ret;
1393  		}
1394  	}
1395  
1396  	if (ol_ctx->cal_in_flash) {
1397  		/* Write EEPROM or Flash data to Target RAM */
1398  		status = ol_transfer_bin_file(ol_ctx, ATH_FLASH_FILE,
1399  						address, false);
1400  	}
1401  
1402  	if (!status) {
1403  		/* Record the fact that Board Data is initialized */
1404  		param = 1;
1405  		bmi_write_memory(
1406  			hif_hia_item_address(target_type,
1407  			offsetof(struct host_interest_s,
1408  				hi_board_data_initialized)),
1409  				(uint8_t *) &param, 4, ol_ctx);
1410  	} else {
1411  		/* Transfer One Time Programmable data */
1412  		address = BMI_SEGMENTED_WRITE_ADDR;
1413  		BMI_INFO("%s: Using 0x%x for the remainder of init",
1414  				__func__, address);
1415  
1416  		status = ol_transfer_bin_file(ol_ctx, ATH_OTP_FILE,
1417  					      address, true);
1418  		/* Execute the OTP code only if entry found and downloaded */
1419  		if (!status) {
1420  			uint16_t board_id = 0xffff;
1421  			/* get board id */
1422  			param = 0x10;
1423  			bmi_execute(address, &param, ol_ctx);
1424  			if (!(param & 0xff))
1425  				board_id = (param >> 8) & 0xffff;
1426  			BMI_INFO("%s: board ID is 0x%0x", __func__, board_id);
1427  			bmi_ctx->board_id = board_id;
1428  		} else if (status < 0) {
1429  			return status;
1430  		}
1431  
1432  		bmi_read_memory(hif_hia_item_address(target_type,
1433  				offsetof(struct host_interest_s,
1434  					hi_board_data)),
1435  				(uint8_t *)&address, 4, ol_ctx);
1436  
1437  		if (!address) {
1438  			address = AR6004_REV5_BOARD_DATA_ADDRESS;
1439  			pr_err("%s: Target address not known! Using 0x%x\n",
1440  			       __func__, address);
1441  		}
1442  
1443  		/* Flash is either not available or invalid */
1444  		if (ol_transfer_bin_file(ol_ctx, ATH_BOARD_DATA_FILE,
1445  					 address, false)) {
1446  			return QDF_STATUS_E_FAILURE;
1447  		}
1448  
1449  		/* Record the fact that Board Data is initialized */
1450  		param = 1;
1451  		bmi_write_memory(hif_hia_item_address(target_type,
1452  				 offsetof(struct host_interest_s,
1453  					  hi_board_data_initialized)),
1454  				 (uint8_t *) &param, 4, ol_ctx);
1455  		address = BMI_SEGMENTED_WRITE_ADDR;
1456  		param = 0;
1457  		bmi_execute(address, &param, ol_ctx);
1458  	}
1459  
1460  	if (!ol_transfer_bin_file(ol_ctx, ATH_SETUP_FILE,
1461  				  BMI_SEGMENTED_WRITE_ADDR, true)) {
1462  		param = 0;
1463  		bmi_execute(address, &param, ol_ctx);
1464  	}
1465  
1466  	/* Download Target firmware
1467  	 * TODO point to target specific files in runtime
1468  	 */
1469  	address = BMI_SEGMENTED_WRITE_ADDR;
1470  	if (ol_transfer_bin_file(ol_ctx, ATH_FIRMWARE_FILE,
1471  				 address, true)) {
1472  		return QDF_STATUS_E_FAILURE;
1473  	}
1474  
1475  	/* Apply the patches */
1476  	if (ol_check_dataset_patch(scn, &address)) {
1477  		if (ol_transfer_bin_file(ol_ctx, ATH_PATCH_FILE, address,
1478  					 false)) {
1479  			return QDF_STATUS_E_FAILURE;
1480  		}
1481  		bmi_write_memory(hif_hia_item_address(target_type,
1482  			offsetof(struct host_interest_s, hi_dset_list_head)),
1483  			(uint8_t *) &address, 4, ol_ctx);
1484  	}
1485  
1486  	switch (target_version) {
1487  	case AR6004_VERSION_REV1_3:
1488  		param = 11;
1489  		break;
1490  	case AR6320_REV1_VERSION:
1491  	case AR6320_REV2_VERSION:
1492  	case AR6320_REV3_VERSION:
1493  	case AR6320_REV3_2_VERSION:
1494  	case QCA9377_REV1_1_VERSION:
1495  	case QCA9379_REV1_VERSION:
1496  	case AR6320_REV4_VERSION:
1497  	case AR6320_DEV_VERSION:
1498  		/*
1499  		 * In sdio interface chip, both sdio_data2 and uart_tx pin
1500  		 * will use GPIO6. It is set by fw rom code, which will cause
1501  		 * sdio CRC error when there is sdio transaction.
1502  		 * Override uart tx pin to avoid side effect to sdio pin.
1503  		 */
1504  		if (hif_get_bus_type(scn) == QDF_BUS_TYPE_SDIO)
1505  			param = 19;
1506  		else
1507  			param = 6;
1508  		break;
1509  	default:
1510  	/* Configure GPIO AR9888 UART */
1511  		param = 7;
1512  	}
1513  
1514  	bmi_write_memory(hif_hia_item_address(target_type,
1515  		offsetof(struct host_interest_s, hi_dbg_uart_txpin)),
1516  		(uint8_t *)&param, 4, ol_ctx);
1517  
1518  	if (ini_cfg->enable_uart_print) {
1519  		param = 1;
1520  		bmi_write_memory(hif_hia_item_address(target_type,
1521  			offsetof(struct host_interest_s, hi_serial_enable)),
1522  			(uint8_t *)&param, 4, ol_ctx);
1523  	} else {
1524  		/*
1525  		 * Explicitly setting UART prints to zero as target turns it on
1526  		 * based on scratch registers.
1527  		 */
1528  		param = 0;
1529  		bmi_write_memory(hif_hia_item_address(target_type,
1530  			offsetof(struct host_interest_s, hi_serial_enable)),
1531  			(uint8_t *)&param, 4, ol_ctx);
1532  	}
1533  
1534  	if (ini_cfg->enable_fw_log) {
1535  		bmi_read_memory(hif_hia_item_address(target_type,
1536  			offsetof(struct host_interest_s, hi_option_flag)),
1537  			(uint8_t *)&param, 4, ol_ctx);
1538  
1539  		param &= ~(HI_OPTION_DISABLE_DBGLOG);
1540  		bmi_write_memory(hif_hia_item_address(target_type,
1541  			offsetof(struct host_interest_s, hi_option_flag)),
1542  			(uint8_t *)&param, 4, ol_ctx);
1543  	} else {
1544  		/*
1545  		 * Explicitly setting fwlog prints to zero as target turns it on
1546  		 * based on scratch registers.
1547  		 */
1548  		bmi_read_memory(hif_hia_item_address(target_type,
1549  			offsetof(struct host_interest_s, hi_option_flag)),
1550  			(uint8_t *)&param, 4, ol_ctx);
1551  
1552  		param |= HI_OPTION_DISABLE_DBGLOG;
1553  		bmi_write_memory(hif_hia_item_address(target_type,
1554  			offsetof(struct host_interest_s, hi_option_flag)),
1555  			(uint8_t *) &param, 4, ol_ctx);
1556  	}
1557  	status = ol_extra_initialization(ol_ctx);
1558  
1559  	return status;
1560  }
1561  
ol_diag_read(struct hif_opaque_softc * scn,uint8_t * buffer,uint32_t pos,size_t count)1562  static int ol_diag_read(struct hif_opaque_softc *scn, uint8_t *buffer,
1563  			uint32_t pos, size_t count)
1564  {
1565  	int result = 0;
1566  
1567  	if ((4 == count) && ((pos & 3) == 0)) {
1568  		result = hif_diag_read_access(scn, pos,
1569  					      (uint32_t *) buffer);
1570  	} else {
1571  		size_t amount_read = 0;
1572  		size_t readSize = PCIE_READ_LIMIT;
1573  		size_t remainder = 0;
1574  
1575  		if (count > PCIE_READ_LIMIT) {
1576  			while ((amount_read < count) && (0 == result)) {
1577  				result = hif_diag_read_mem(scn, pos,
1578  							   buffer, readSize);
1579  				if (0 == result) {
1580  					buffer += readSize;
1581  					pos += readSize;
1582  					amount_read += readSize;
1583  					remainder = count - amount_read;
1584  					if (remainder < PCIE_READ_LIMIT)
1585  						readSize = remainder;
1586  				}
1587  			}
1588  		} else {
1589  		result = hif_diag_read_mem(scn, pos,
1590  					   buffer, count);
1591  		}
1592  	}
1593  
1594  	if (!result)
1595  		return count;
1596  	else
1597  		return -EIO;
1598  }
1599  
ol_ath_get_reg_table(struct hif_opaque_softc * scn,uint32_t target_version,struct tgt_reg_table * reg_table)1600  static int ol_ath_get_reg_table(struct hif_opaque_softc *scn,
1601  				uint32_t target_version,
1602  				struct tgt_reg_table *reg_table)
1603  {
1604  	int section_len = 0;
1605  
1606  	if (!reg_table) {
1607  		qdf_assert(0);
1608  		return section_len;
1609  	}
1610  
1611  	if (hif_get_bus_type(scn) != QDF_BUS_TYPE_PCI &&
1612  	    hif_get_bus_type(scn) != QDF_BUS_TYPE_SDIO)
1613  		return section_len;
1614  
1615  	switch (target_version) {
1616  	case AR6320_REV2_1_VERSION:
1617  		reg_table->section = ar6320v2_reg_table;
1618  		reg_table->section_size = ARRAY_SIZE(ar6320v2_reg_table);
1619  		section_len = AR6320_REV2_1_REG_SIZE;
1620  		break;
1621  	case AR6320_REV3_VERSION:
1622  	case AR6320_REV3_2_VERSION:
1623  	case QCA9379_REV1_VERSION:
1624  	case QCA9377_REV1_1_VERSION:
1625  		reg_table->section = ar6320v3_reg_table;
1626  		reg_table->section_size = ARRAY_SIZE(ar6320v3_reg_table);
1627  		section_len = AR6320_REV3_REG_SIZE;
1628  		break;
1629  	default:
1630  		reg_table->section = NULL;
1631  		reg_table->section_size = 0;
1632  		section_len = 0;
1633  	}
1634  
1635  	return section_len;
1636  }
1637  
ol_diag_read_reg_loc(struct hif_opaque_softc * scn,uint8_t * buffer,uint32_t buffer_len)1638  static int ol_diag_read_reg_loc(struct hif_opaque_softc *scn, uint8_t *buffer,
1639  				uint32_t buffer_len)
1640  {
1641  	int i, len, section_len, fill_len;
1642  	int dump_len, result = 0;
1643  	struct tgt_reg_table reg_table;
1644  	const struct tgt_reg_section *curr_sec, *next_sec;
1645  	struct hif_target_info *tgt_info = hif_get_target_info_handle(scn);
1646  	uint32_t target_version =  tgt_info->target_version;
1647  
1648  	reg_table.section = NULL;
1649  	reg_table.section_size = 0;
1650  
1651  	section_len = ol_ath_get_reg_table(scn, target_version, &reg_table);
1652  
1653  	if (!reg_table.section || !reg_table.section_size || !section_len) {
1654  		BMI_ERR("%s: failed to get reg table", __func__);
1655  		result = -EIO;
1656  		goto out;
1657  	}
1658  
1659  	curr_sec = reg_table.section;
1660  	for (i = 0; i < reg_table.section_size; i++) {
1661  
1662  		dump_len = curr_sec->end_addr - curr_sec->start_addr;
1663  
1664  		if ((buffer_len - result) < dump_len) {
1665  			BMI_ERR("No buffer to dump regs:%d: 0x%08x-0x%08x",
1666  				i, curr_sec->start_addr, curr_sec->end_addr);
1667  			goto out;
1668  		}
1669  
1670  		len = ol_diag_read(scn, buffer, curr_sec->start_addr, dump_len);
1671  
1672  		if (len != -EIO) {
1673  			buffer += len;
1674  			result += len;
1675  		} else {
1676  			BMI_ERR("%s: can't read reg 0x%08x len = %d",
1677  				__func__, curr_sec->start_addr, dump_len);
1678  			result = -EIO;
1679  			goto out;
1680  		}
1681  
1682  		if (result < section_len) {
1683  			next_sec = (struct tgt_reg_section *) ((uint8_t *)
1684  						 curr_sec + sizeof(*curr_sec));
1685  			fill_len = next_sec->start_addr - curr_sec->end_addr;
1686  			if ((buffer_len - result) < fill_len) {
1687  				BMI_ERR("No buf to fill regs:%d: 0x%08x-0x%08x",
1688  					i, curr_sec->end_addr,
1689  					next_sec->start_addr);
1690  				goto out;
1691  			}
1692  
1693  			if (fill_len) {
1694  				buffer += fill_len;
1695  				result += fill_len;
1696  			}
1697  		}
1698  		curr_sec++;
1699  	}
1700  
1701  out:
1702  	return result;
1703  }
1704  
1705  static
ol_dump_target_memory(struct hif_opaque_softc * scn,void * memory_block)1706  void ol_dump_target_memory(struct hif_opaque_softc *scn, void *memory_block)
1707  {
1708  	char *buffer_loc = memory_block;
1709  	u_int32_t section_count = 0;
1710  	u_int32_t address = 0;
1711  	u_int32_t size = 0;
1712  
1713  	if (hif_get_bus_type(scn) == QDF_BUS_TYPE_SDIO ||
1714  	    hif_get_bus_type(scn) == QDF_BUS_TYPE_USB)
1715  		return;
1716  
1717  	for (; section_count < 2; section_count++) {
1718  		switch (section_count) {
1719  		case 0:
1720  			address = DRAM_LOCAL_BASE_ADDR;
1721  			size = DRAM_SIZE;
1722  			break;
1723  		case 1:
1724  			address = AXI_LOCATION;
1725  			size = AXI_SIZE;
1726  			break;
1727  		default:
1728  			break;
1729  		}
1730  		hif_dump_target_memory(scn, buffer_loc, address, size);
1731  		buffer_loc += size;
1732  	}
1733  }
1734  
1735  static int
ol_dump_ce_register(struct hif_opaque_softc * scn,void * memory_block)1736  ol_dump_ce_register(struct hif_opaque_softc *scn, void *memory_block)
1737  {
1738  	int ret;
1739  
1740  	BMI_ERR("Could not read dump section!");
1741  
1742  	if (hif_get_bus_type(scn) == QDF_BUS_TYPE_SDIO ||
1743  	    hif_get_bus_type(scn) == QDF_BUS_TYPE_USB)
1744  		return 0;
1745  
1746  	if (hif_dump_registers(scn))
1747  		BMI_ERR("Failed to dump bus registers");
1748  
1749  	ol_dump_target_memory(scn, memory_block);
1750  	ret = -EACCES;
1751  
1752  	return ret;
1753  }
1754  
1755  static inline uint32_t
ol_get_max_section_count(struct hif_opaque_softc * scn)1756  ol_get_max_section_count(struct hif_opaque_softc *scn)
1757  {
1758  	if (hif_get_bus_type(scn) == QDF_BUS_TYPE_PCI)
1759  		return 5;
1760  	else
1761  		return 4;
1762  }
1763  
1764  /**
1765   * ol_set_ram_config_reg() - set target RAM configuration register
1766   * @scn: pointer of hif_softc context
1767   * @config: value to be written to the register
1768   *
1769   * This function will write the given value to target RAM configuration
1770   * register which is bit[23-20] of target CPU inbound address in order to
1771   * provide correct address mapping.
1772   *
1773   * Return: 0 for success or reasons for failure
1774   */
ol_set_ram_config_reg(struct hif_opaque_softc * scn,uint32_t config)1775  static int ol_set_ram_config_reg(struct hif_opaque_softc *scn, uint32_t config)
1776  {
1777  	QDF_STATUS status;
1778  	uint32_t val;
1779  	struct targetdef_s *targetdef =
1780  		(struct targetdef_s *)hif_get_targetdef(scn);
1781  	uint32_t ram_config_addr =
1782  		targetdef->d_SOC_CORE_BASE_ADDRESS + FW_RAM_CONFIG_ADDRESS;
1783  
1784  	if (hif_get_bus_type(scn) != QDF_BUS_TYPE_PCI)
1785  		return -EACCES;
1786  
1787  	status = hif_diag_write_access(scn, ram_config_addr, config);
1788  	if (QDF_IS_STATUS_ERROR(status)) {
1789  		return -EACCES;
1790  	}
1791  	status = hif_diag_read_access(scn, ram_config_addr, &val);
1792  	if (QDF_IS_STATUS_ERROR(status)) {
1793  		return -EACCES;
1794  	}
1795  	if (val != config) {
1796  		BMI_ERR("%s: Failed to set RAM config reg from 0x%x to 0x%x",
1797  			__func__, val, config);
1798  		return -EACCES;
1799  	}
1800  	return 0;
1801  }
1802  
1803  static int
ol_get_iram_len_and_pos(struct hif_opaque_softc * scn,uint32_t * pos,uint32_t * len,uint32_t section)1804  ol_get_iram_len_and_pos(struct hif_opaque_softc *scn, uint32_t *pos,
1805  			uint32_t *len, uint32_t section)
1806  {
1807  	enum hif_target_status status;
1808  	uint32_t iram_addr, iram_size;
1809  	int ret;
1810  
1811  	if (hif_get_bus_type(scn) != QDF_BUS_TYPE_PCI) {
1812  		*pos = IRAM_LOCATION;
1813  		*len = IRAM_SIZE;
1814  		BMI_ERR("%s: Dumping IRAM Section", __func__);
1815  		return 0;
1816  	}
1817  
1818  	status = hif_get_target_status(scn);
1819  	if (status != TARGET_STATUS_RESET) {
1820  		BMI_ERR("%s: Target status invalid: %d", __func__, status);
1821  		return -EBUSY;
1822  	}
1823  
1824  	switch (section) {
1825  	case 3:
1826  		BMI_ERR("%s: Dumping IRAM1 section", __func__);
1827  		iram_addr = IRAM1_LOCATION;
1828  		iram_size = IRAM1_SIZE;
1829  		break;
1830  	case 4:
1831  		BMI_ERR("%s: Dumping IRAM2 section", __func__);
1832  		iram_addr = IRAM2_LOCATION;
1833  		iram_size = IRAM2_SIZE;
1834  		break;
1835  	default:
1836  		BMI_ERR("%s: Invalid input iram section %d",
1837  			__func__, section);
1838  		return A_EINVAL;
1839  	}
1840  
1841  	ret = ol_set_ram_config_reg(scn, iram_addr >> 20);
1842  	if (ret) {
1843  		BMI_ERR("%s: Skip IRAM1 ret:%d", __func__, ret);
1844  		return -EBUSY;
1845  	}
1846  
1847  	*pos = iram_addr;
1848  	*len = iram_size;
1849  	return 0;
1850  }
1851  
1852  /**
1853   * ol_target_coredump() - API to collect target ramdump
1854   * @inst: private context
1855   * @memory_block: non-NULL reserved memory location
1856   * @block_len: size of the dump to collect
1857   *
1858   * Function to perform core dump for the target.
1859   *
1860   * Return: int
1861   */
ol_target_coredump(void * inst,void * memory_block,uint32_t block_len)1862  static int ol_target_coredump(void *inst, void *memory_block,
1863  					uint32_t block_len)
1864  {
1865  	struct hif_opaque_softc *scn = (struct hif_opaque_softc *)inst;
1866  	int8_t *buffer_loc = memory_block;
1867  	int result = 0;
1868  	int ret = 0;
1869  	uint32_t amount_read = 0;
1870  	uint32_t section_count = 0;
1871  	uint32_t pos = 0;
1872  	uint32_t read_len = 0;
1873  	uint32_t max_count = ol_get_max_section_count(scn);
1874  
1875  	while ((section_count < max_count) && (amount_read < block_len)) {
1876  		switch (section_count) {
1877  		case 0:
1878  			pos = DRAM_LOCATION;
1879  			read_len = DRAM_SIZE;
1880  			BMI_ERR("%s: Dumping DRAM section...", __func__);
1881  			break;
1882  		case 1:
1883  			pos = AXI_LOCATION;
1884  			read_len = AXI_SIZE;
1885  			BMI_ERR("%s: Dumping AXI section...", __func__);
1886  			break;
1887  		case 2:
1888  			pos = REGISTER_LOCATION;
1889  			/* ol_diag_read_reg_loc checks for buffer overrun */
1890  			read_len = 0;
1891  			BMI_ERR("%s: Dumping Register section...", __func__);
1892  			break;
1893  		case 3:
1894  		case 4:
1895  			ret = ol_get_iram_len_and_pos(scn, &pos, &read_len,
1896  						      section_count);
1897  			if (ret) {
1898  				BMI_ERR("%s: Fail to Dump IRAM Section "
1899  					"ret:%d", __func__, ret);
1900  				return ret;
1901  			}
1902  			break;
1903  		default:
1904  			BMI_ERR("%s: INVALID SECTION_:%d", __func__,
1905  				section_count);
1906  			return 0;
1907  		}
1908  
1909  		if (block_len - amount_read < read_len) {
1910  			BMI_ERR("%s: No memory to dump section:%d buffer!",
1911  				__func__, section_count);
1912  			return -ENOMEM;
1913  		}
1914  
1915  		if (((hif_get_bus_type(scn) == QDF_BUS_TYPE_PCI) ||
1916  		     (hif_get_bus_type(scn) == QDF_BUS_TYPE_SDIO)) &&
1917  		    pos == REGISTER_LOCATION)
1918  			result = ol_diag_read_reg_loc(scn, buffer_loc,
1919  						      block_len - amount_read);
1920  		else
1921  			result = ol_diag_read(scn, buffer_loc, pos, read_len);
1922  
1923  		if (result == -EIO)
1924  			return ol_dump_ce_register(scn, memory_block);
1925  
1926  		BMI_INFO("%s: Section:%d Bytes Read:%0x", __func__,
1927  			 section_count, result);
1928  
1929  		amount_read += result;
1930  		buffer_loc += result;
1931  		section_count++;
1932  	}
1933  	return ret;
1934  }
1935  
1936  /**
1937   * ol_get_ini_handle() - API to get Ol INI configuration
1938   * @ol_ctx: OL Context
1939   *
1940   * Return: pointer to OL configuration
1941   */
ol_get_ini_handle(struct ol_context * ol_ctx)1942  struct ol_config_info *ol_get_ini_handle(struct ol_context *ol_ctx)
1943  {
1944  	return &ol_ctx->cfg_info;
1945  }
1946  
1947  /**
1948   * ol_init_ini_config() - API to initialize INI configuration
1949   * @ol_ctx: OL Context
1950   * @cfg: OL ini configuration
1951   *
1952   * Return: void
1953   */
ol_init_ini_config(struct ol_context * ol_ctx,struct ol_config_info * cfg)1954  void ol_init_ini_config(struct ol_context *ol_ctx,
1955  			struct ol_config_info *cfg)
1956  {
1957  	qdf_mem_copy(&ol_ctx->cfg_info, cfg, sizeof(struct ol_config_info));
1958  }
1959  
ol_set_fw_crashed_cb(struct ol_context * ol_ctx,void (* callback_fn)(void))1960  void ol_set_fw_crashed_cb(struct ol_context *ol_ctx,
1961  			  void (*callback_fn)(void))
1962  {
1963  	ol_ctx->fw_crashed_cb = callback_fn;
1964  }
1965