| 
									
										
										
										
											2011-04-05 09:42:12 -07:00
										 |  |  | /******************************************************************************
 | 
					
						
							|  |  |  |  * | 
					
						
							| 
									
										
										
										
											2013-12-30 13:15:54 +02:00
										 |  |  |  * Copyright(c) 2003 - 2014 Intel Corporation. All rights reserved. | 
					
						
							| 
									
										
										
										
											2011-04-05 09:42:12 -07:00
										 |  |  |  * | 
					
						
							|  |  |  |  * Portions of this file are derived from the ipw3945 project. | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * This program is free software; you can redistribute it and/or modify it | 
					
						
							|  |  |  |  * under the terms of version 2 of the GNU General Public License as | 
					
						
							|  |  |  |  * published by the Free Software Foundation. | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * This program is distributed in the hope that it will be useful, but WITHOUT | 
					
						
							|  |  |  |  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | 
					
						
							|  |  |  |  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for | 
					
						
							|  |  |  |  * more details. | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * You should have received a copy of the GNU General Public License along with | 
					
						
							|  |  |  |  * this program; if not, write to the Free Software Foundation, Inc., | 
					
						
							|  |  |  |  * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * The full GNU General Public License is included in this distribution in the | 
					
						
							|  |  |  |  * file called LICENSE. | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * Contact Information: | 
					
						
							|  |  |  |  *  Intel Linux Wireless <ilw@linux.intel.com> | 
					
						
							|  |  |  |  * Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497 | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  *****************************************************************************/ | 
					
						
							| 
									
										
										
										
											2011-08-25 23:11:14 -07:00
										 |  |  | #include <linux/delay.h>
 | 
					
						
							|  |  |  | #include <linux/device.h>
 | 
					
						
							| 
									
										
										
										
											2012-05-16 22:54:27 +02:00
										 |  |  | #include <linux/export.h>
 | 
					
						
							| 
									
										
										
										
											2011-04-05 09:42:12 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-03-01 00:13:33 +01:00
										 |  |  | #include "iwl-drv.h"
 | 
					
						
							| 
									
										
										
										
											2011-04-05 09:42:12 -07:00
										 |  |  | #include "iwl-io.h"
 | 
					
						
							| 
									
										
										
										
											2012-06-06 14:17:46 +02:00
										 |  |  | #include "iwl-csr.h"
 | 
					
						
							| 
									
										
										
										
											2011-08-25 23:11:14 -07:00
										 |  |  | #include "iwl-debug.h"
 | 
					
						
							| 
									
										
										
										
											2014-04-27 16:46:09 +03:00
										 |  |  | #include "iwl-prph.h"
 | 
					
						
							| 
									
										
										
										
											2013-06-24 10:35:53 +03:00
										 |  |  | #include "iwl-fh.h"
 | 
					
						
							| 
									
										
										
										
											2011-04-05 09:42:12 -07:00
										 |  |  | 
 | 
					
						
							|  |  |  | #define IWL_POLL_INTERVAL 10	/* microseconds */
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-01-03 16:56:15 +02:00
										 |  |  | int iwl_poll_bit(struct iwl_trans *trans, u32 addr, | 
					
						
							| 
									
										
										
										
											2011-04-05 09:42:12 -07:00
										 |  |  | 		 u32 bits, u32 mask, int timeout) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	int t = 0; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	do { | 
					
						
							| 
									
										
										
										
											2012-01-03 16:56:15 +02:00
										 |  |  | 		if ((iwl_read32(trans, addr) & mask) == (bits & mask)) | 
					
						
							| 
									
										
										
										
											2011-04-05 09:42:12 -07:00
										 |  |  | 			return t; | 
					
						
							|  |  |  | 		udelay(IWL_POLL_INTERVAL); | 
					
						
							|  |  |  | 		t += IWL_POLL_INTERVAL; | 
					
						
							|  |  |  | 	} while (t < timeout); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	return -ETIMEDOUT; | 
					
						
							|  |  |  | } | 
					
						
							| 
									
										
										
										
											2013-03-01 00:13:33 +01:00
										 |  |  | IWL_EXPORT_SYMBOL(iwl_poll_bit); | 
					
						
							| 
									
										
										
										
											2011-04-05 09:42:12 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-01-03 16:56:15 +02:00
										 |  |  | u32 iwl_read_direct32(struct iwl_trans *trans, u32 reg) | 
					
						
							| 
									
										
										
										
											2011-04-05 09:42:12 -07:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2012-12-31 13:46:42 +02:00
										 |  |  | 	u32 value = 0x5a5a5a5a; | 
					
						
							| 
									
										
										
										
											2011-04-05 09:42:12 -07:00
										 |  |  | 	unsigned long flags; | 
					
						
							| 
									
										
										
										
											2013-01-16 11:34:49 +02:00
										 |  |  | 	if (iwl_trans_grab_nic_access(trans, false, &flags)) { | 
					
						
							| 
									
										
										
										
											2012-12-31 13:46:42 +02:00
										 |  |  | 		value = iwl_read32(trans, reg); | 
					
						
							| 
									
										
										
										
											2013-01-16 11:34:49 +02:00
										 |  |  | 		iwl_trans_release_nic_access(trans, &flags); | 
					
						
							| 
									
										
										
										
											2012-12-31 13:46:42 +02:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2011-04-05 09:42:12 -07:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	return value; | 
					
						
							|  |  |  | } | 
					
						
							| 
									
										
										
										
											2013-03-01 00:13:33 +01:00
										 |  |  | IWL_EXPORT_SYMBOL(iwl_read_direct32); | 
					
						
							| 
									
										
										
										
											2011-04-05 09:42:12 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-01-03 16:56:15 +02:00
										 |  |  | void iwl_write_direct32(struct iwl_trans *trans, u32 reg, u32 value) | 
					
						
							| 
									
										
										
										
											2011-04-05 09:42:12 -07:00
										 |  |  | { | 
					
						
							|  |  |  | 	unsigned long flags; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-01-16 11:34:49 +02:00
										 |  |  | 	if (iwl_trans_grab_nic_access(trans, false, &flags)) { | 
					
						
							| 
									
										
										
										
											2012-01-03 16:56:15 +02:00
										 |  |  | 		iwl_write32(trans, reg, value); | 
					
						
							| 
									
										
										
										
											2013-01-16 11:34:49 +02:00
										 |  |  | 		iwl_trans_release_nic_access(trans, &flags); | 
					
						
							| 
									
										
										
										
											2011-04-05 09:42:12 -07:00
										 |  |  | 	} | 
					
						
							|  |  |  | } | 
					
						
							| 
									
										
										
										
											2013-03-01 00:13:33 +01:00
										 |  |  | IWL_EXPORT_SYMBOL(iwl_write_direct32); | 
					
						
							| 
									
										
										
										
											2011-04-05 09:42:12 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-01-03 16:56:15 +02:00
										 |  |  | int iwl_poll_direct_bit(struct iwl_trans *trans, u32 addr, u32 mask, | 
					
						
							| 
									
										
										
										
											2011-04-05 09:42:12 -07:00
										 |  |  | 			int timeout) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	int t = 0; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	do { | 
					
						
							| 
									
										
										
										
											2012-01-03 16:56:15 +02:00
										 |  |  | 		if ((iwl_read_direct32(trans, addr) & mask) == mask) | 
					
						
							| 
									
										
										
										
											2011-04-05 09:42:12 -07:00
										 |  |  | 			return t; | 
					
						
							|  |  |  | 		udelay(IWL_POLL_INTERVAL); | 
					
						
							|  |  |  | 		t += IWL_POLL_INTERVAL; | 
					
						
							|  |  |  | 	} while (t < timeout); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	return -ETIMEDOUT; | 
					
						
							|  |  |  | } | 
					
						
							| 
									
										
										
										
											2013-03-01 00:13:33 +01:00
										 |  |  | IWL_EXPORT_SYMBOL(iwl_poll_direct_bit); | 
					
						
							| 
									
										
										
										
											2011-04-05 09:42:12 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-02-18 16:45:00 +01:00
										 |  |  | u32 __iwl_read_prph(struct iwl_trans *trans, u32 ofs) | 
					
						
							| 
									
										
										
										
											2011-04-05 09:42:12 -07:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2012-12-02 13:07:30 +02:00
										 |  |  | 	u32 val = iwl_trans_read_prph(trans, ofs); | 
					
						
							|  |  |  | 	trace_iwlwifi_dev_ioread_prph32(trans->dev, ofs, val); | 
					
						
							|  |  |  | 	return val; | 
					
						
							| 
									
										
										
										
											2011-04-05 09:42:12 -07:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-02-18 16:45:00 +01:00
										 |  |  | void __iwl_write_prph(struct iwl_trans *trans, u32 ofs, u32 val) | 
					
						
							| 
									
										
										
										
											2011-04-05 09:42:12 -07:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2012-12-02 13:07:30 +02:00
										 |  |  | 	trace_iwlwifi_dev_iowrite_prph32(trans->dev, ofs, val); | 
					
						
							|  |  |  | 	iwl_trans_write_prph(trans, ofs, val); | 
					
						
							| 
									
										
										
										
											2011-04-05 09:42:12 -07:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-12-02 13:07:30 +02:00
										 |  |  | u32 iwl_read_prph(struct iwl_trans *trans, u32 ofs) | 
					
						
							| 
									
										
										
										
											2011-04-05 09:42:12 -07:00
										 |  |  | { | 
					
						
							|  |  |  | 	unsigned long flags; | 
					
						
							| 
									
										
										
										
											2012-12-31 13:46:42 +02:00
										 |  |  | 	u32 val = 0x5a5a5a5a; | 
					
						
							| 
									
										
										
										
											2011-04-05 09:42:12 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-01-16 11:34:49 +02:00
										 |  |  | 	if (iwl_trans_grab_nic_access(trans, false, &flags)) { | 
					
						
							| 
									
										
										
										
											2012-12-31 13:46:42 +02:00
										 |  |  | 		val = __iwl_read_prph(trans, ofs); | 
					
						
							| 
									
										
										
										
											2013-01-16 11:34:49 +02:00
										 |  |  | 		iwl_trans_release_nic_access(trans, &flags); | 
					
						
							| 
									
										
										
										
											2012-12-31 13:46:42 +02:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2011-04-05 09:42:12 -07:00
										 |  |  | 	return val; | 
					
						
							|  |  |  | } | 
					
						
							| 
									
										
										
										
											2013-03-01 00:13:33 +01:00
										 |  |  | IWL_EXPORT_SYMBOL(iwl_read_prph); | 
					
						
							| 
									
										
										
										
											2011-04-05 09:42:12 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-12-02 13:07:30 +02:00
										 |  |  | void iwl_write_prph(struct iwl_trans *trans, u32 ofs, u32 val) | 
					
						
							| 
									
										
										
										
											2011-04-05 09:42:12 -07:00
										 |  |  | { | 
					
						
							|  |  |  | 	unsigned long flags; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-01-16 11:34:49 +02:00
										 |  |  | 	if (iwl_trans_grab_nic_access(trans, false, &flags)) { | 
					
						
							| 
									
										
										
										
											2012-12-02 13:07:30 +02:00
										 |  |  | 		__iwl_write_prph(trans, ofs, val); | 
					
						
							| 
									
										
										
										
											2013-01-16 11:34:49 +02:00
										 |  |  | 		iwl_trans_release_nic_access(trans, &flags); | 
					
						
							| 
									
										
										
										
											2011-04-05 09:42:12 -07:00
										 |  |  | 	} | 
					
						
							|  |  |  | } | 
					
						
							| 
									
										
										
										
											2013-03-01 00:13:33 +01:00
										 |  |  | IWL_EXPORT_SYMBOL(iwl_write_prph); | 
					
						
							| 
									
										
										
										
											2011-04-05 09:42:12 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-01-23 16:26:32 +02:00
										 |  |  | int iwl_poll_prph_bit(struct iwl_trans *trans, u32 addr, | 
					
						
							|  |  |  | 		      u32 bits, u32 mask, int timeout) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	int t = 0; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	do { | 
					
						
							|  |  |  | 		if ((iwl_read_prph(trans, addr) & mask) == (bits & mask)) | 
					
						
							|  |  |  | 			return t; | 
					
						
							|  |  |  | 		udelay(IWL_POLL_INTERVAL); | 
					
						
							|  |  |  | 		t += IWL_POLL_INTERVAL; | 
					
						
							|  |  |  | 	} while (t < timeout); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	return -ETIMEDOUT; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-12-02 13:07:30 +02:00
										 |  |  | void iwl_set_bits_prph(struct iwl_trans *trans, u32 ofs, u32 mask) | 
					
						
							| 
									
										
										
										
											2011-04-05 09:42:12 -07:00
										 |  |  | { | 
					
						
							|  |  |  | 	unsigned long flags; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-01-16 11:34:49 +02:00
										 |  |  | 	if (iwl_trans_grab_nic_access(trans, false, &flags)) { | 
					
						
							| 
									
										
										
										
											2012-12-02 13:07:30 +02:00
										 |  |  | 		__iwl_write_prph(trans, ofs, | 
					
						
							|  |  |  | 				 __iwl_read_prph(trans, ofs) | mask); | 
					
						
							| 
									
										
										
										
											2013-01-16 11:34:49 +02:00
										 |  |  | 		iwl_trans_release_nic_access(trans, &flags); | 
					
						
							| 
									
										
										
										
											2012-03-07 09:52:24 -08:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2011-04-05 09:42:12 -07:00
										 |  |  | } | 
					
						
							| 
									
										
										
										
											2013-03-01 00:13:33 +01:00
										 |  |  | IWL_EXPORT_SYMBOL(iwl_set_bits_prph); | 
					
						
							| 
									
										
										
										
											2011-04-05 09:42:12 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-12-02 13:07:30 +02:00
										 |  |  | void iwl_set_bits_mask_prph(struct iwl_trans *trans, u32 ofs, | 
					
						
							| 
									
										
										
										
											2011-04-05 09:42:12 -07:00
										 |  |  | 			    u32 bits, u32 mask) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	unsigned long flags; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-01-16 11:34:49 +02:00
										 |  |  | 	if (iwl_trans_grab_nic_access(trans, false, &flags)) { | 
					
						
							| 
									
										
										
										
											2012-12-02 13:07:30 +02:00
										 |  |  | 		__iwl_write_prph(trans, ofs, | 
					
						
							|  |  |  | 				 (__iwl_read_prph(trans, ofs) & mask) | bits); | 
					
						
							| 
									
										
										
										
											2013-01-16 11:34:49 +02:00
										 |  |  | 		iwl_trans_release_nic_access(trans, &flags); | 
					
						
							| 
									
										
										
										
											2012-03-07 09:52:24 -08:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2011-04-05 09:42:12 -07:00
										 |  |  | } | 
					
						
							| 
									
										
										
										
											2013-03-01 00:13:33 +01:00
										 |  |  | IWL_EXPORT_SYMBOL(iwl_set_bits_mask_prph); | 
					
						
							| 
									
										
										
										
											2011-04-05 09:42:12 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-12-02 13:07:30 +02:00
										 |  |  | void iwl_clear_bits_prph(struct iwl_trans *trans, u32 ofs, u32 mask) | 
					
						
							| 
									
										
										
										
											2011-04-05 09:42:12 -07:00
										 |  |  | { | 
					
						
							|  |  |  | 	unsigned long flags; | 
					
						
							|  |  |  | 	u32 val; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-01-16 11:34:49 +02:00
										 |  |  | 	if (iwl_trans_grab_nic_access(trans, false, &flags)) { | 
					
						
							| 
									
										
										
										
											2012-12-02 13:07:30 +02:00
										 |  |  | 		val = __iwl_read_prph(trans, ofs); | 
					
						
							|  |  |  | 		__iwl_write_prph(trans, ofs, (val & ~mask)); | 
					
						
							| 
									
										
										
										
											2013-01-16 11:34:49 +02:00
										 |  |  | 		iwl_trans_release_nic_access(trans, &flags); | 
					
						
							| 
									
										
										
										
											2012-03-07 09:52:24 -08:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2011-04-05 09:42:12 -07:00
										 |  |  | } | 
					
						
							| 
									
										
										
										
											2013-03-01 00:13:33 +01:00
										 |  |  | IWL_EXPORT_SYMBOL(iwl_clear_bits_prph); | 
					
						
							| 
									
										
										
										
											2013-06-24 10:35:53 +03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-04-27 16:46:09 +03:00
										 |  |  | void iwl_force_nmi(struct iwl_trans *trans) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	/*
 | 
					
						
							|  |  |  | 	 * In HW previous to the 8000 HW family, and in the 8000 HW family | 
					
						
							|  |  |  | 	 * itself when the revision step==0, the DEVICE_SET_NMI_REG is used | 
					
						
							|  |  |  | 	 * to force an NMI. Otherwise, a different register - | 
					
						
							|  |  |  | 	 * DEVICE_SET_NMI_8000B_REG - is used. | 
					
						
							|  |  |  | 	 */ | 
					
						
							|  |  |  | 	if ((trans->cfg->device_family != IWL_DEVICE_FAMILY_8000) || | 
					
						
							| 
									
										
										
										
											2015-01-07 16:44:06 +02:00
										 |  |  | 	    (CSR_HW_REV_STEP(trans->hw_rev) == SILICON_A_STEP)) { | 
					
						
							|  |  |  | 		iwl_write_prph(trans, DEVICE_SET_NMI_REG, | 
					
						
							|  |  |  | 			       DEVICE_SET_NMI_VAL_DRV); | 
					
						
							|  |  |  | 		iwl_write_prph(trans, DEVICE_SET_NMI_REG, | 
					
						
							|  |  |  | 			       DEVICE_SET_NMI_VAL_HW); | 
					
						
							|  |  |  | 	} else { | 
					
						
							| 
									
										
										
										
											2014-04-27 16:46:09 +03:00
										 |  |  | 		iwl_write_prph(trans, DEVICE_SET_NMI_8000B_REG, | 
					
						
							|  |  |  | 			       DEVICE_SET_NMI_8000B_VAL); | 
					
						
							| 
									
										
										
										
											2015-01-07 16:44:06 +02:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2014-04-27 16:46:09 +03:00
										 |  |  | } | 
					
						
							|  |  |  | IWL_EXPORT_SYMBOL(iwl_force_nmi); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-06-24 10:35:53 +03:00
										 |  |  | static const char *get_fh_string(int cmd) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | #define IWL_CMD(x) case x: return #x
 | 
					
						
							|  |  |  | 	switch (cmd) { | 
					
						
							|  |  |  | 	IWL_CMD(FH_RSCSR_CHNL0_STTS_WPTR_REG); | 
					
						
							|  |  |  | 	IWL_CMD(FH_RSCSR_CHNL0_RBDCB_BASE_REG); | 
					
						
							|  |  |  | 	IWL_CMD(FH_RSCSR_CHNL0_WPTR); | 
					
						
							|  |  |  | 	IWL_CMD(FH_MEM_RCSR_CHNL0_CONFIG_REG); | 
					
						
							|  |  |  | 	IWL_CMD(FH_MEM_RSSR_SHARED_CTRL_REG); | 
					
						
							|  |  |  | 	IWL_CMD(FH_MEM_RSSR_RX_STATUS_REG); | 
					
						
							|  |  |  | 	IWL_CMD(FH_MEM_RSSR_RX_ENABLE_ERR_IRQ2DRV); | 
					
						
							|  |  |  | 	IWL_CMD(FH_TSSR_TX_STATUS_REG); | 
					
						
							|  |  |  | 	IWL_CMD(FH_TSSR_TX_ERROR_REG); | 
					
						
							|  |  |  | 	default: | 
					
						
							|  |  |  | 		return "UNKNOWN"; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | #undef IWL_CMD
 | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | int iwl_dump_fh(struct iwl_trans *trans, char **buf) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	int i; | 
					
						
							|  |  |  | 	static const u32 fh_tbl[] = { | 
					
						
							|  |  |  | 		FH_RSCSR_CHNL0_STTS_WPTR_REG, | 
					
						
							|  |  |  | 		FH_RSCSR_CHNL0_RBDCB_BASE_REG, | 
					
						
							|  |  |  | 		FH_RSCSR_CHNL0_WPTR, | 
					
						
							|  |  |  | 		FH_MEM_RCSR_CHNL0_CONFIG_REG, | 
					
						
							|  |  |  | 		FH_MEM_RSSR_SHARED_CTRL_REG, | 
					
						
							|  |  |  | 		FH_MEM_RSSR_RX_STATUS_REG, | 
					
						
							|  |  |  | 		FH_MEM_RSSR_RX_ENABLE_ERR_IRQ2DRV, | 
					
						
							|  |  |  | 		FH_TSSR_TX_STATUS_REG, | 
					
						
							|  |  |  | 		FH_TSSR_TX_ERROR_REG | 
					
						
							|  |  |  | 	}; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #ifdef CONFIG_IWLWIFI_DEBUGFS
 | 
					
						
							|  |  |  | 	if (buf) { | 
					
						
							|  |  |  | 		int pos = 0; | 
					
						
							|  |  |  | 		size_t bufsz = ARRAY_SIZE(fh_tbl) * 48 + 40; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		*buf = kmalloc(bufsz, GFP_KERNEL); | 
					
						
							|  |  |  | 		if (!*buf) | 
					
						
							|  |  |  | 			return -ENOMEM; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		pos += scnprintf(*buf + pos, bufsz - pos, | 
					
						
							|  |  |  | 				"FH register values:\n"); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		for (i = 0; i < ARRAY_SIZE(fh_tbl); i++) | 
					
						
							|  |  |  | 			pos += scnprintf(*buf + pos, bufsz - pos, | 
					
						
							|  |  |  | 				"  %34s: 0X%08x\n", | 
					
						
							|  |  |  | 				get_fh_string(fh_tbl[i]), | 
					
						
							|  |  |  | 				iwl_read_direct32(trans, fh_tbl[i])); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		return pos; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | #endif
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	IWL_ERR(trans, "FH register values:\n"); | 
					
						
							|  |  |  | 	for (i = 0; i <  ARRAY_SIZE(fh_tbl); i++) | 
					
						
							|  |  |  | 		IWL_ERR(trans, "  %34s: 0X%08x\n", | 
					
						
							|  |  |  | 			get_fh_string(fh_tbl[i]), | 
					
						
							|  |  |  | 			iwl_read_direct32(trans, fh_tbl[i])); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	return 0; | 
					
						
							|  |  |  | } |