Linux Audio

Check our new training course

Loading...
Note: File does not exist in v6.8.
  1/******************************************************************************
  2 *
  3 * This file is provided under a dual BSD/GPLv2 license.  When using or
  4 * redistributing this file, you may do so under either license.
  5 *
  6 * GPL LICENSE SUMMARY
  7 *
  8 * Copyright(c) 2008 - 2014 Intel Corporation. All rights reserved.
  9 * Copyright(c) 2013 - 2015 Intel Mobile Communications GmbH
 10 * Copyright(c) 2015        Intel Deutschland GmbH
 11 *
 12 * This program is free software; you can redistribute it and/or modify
 13 * it under the terms of version 2 of the GNU General Public License as
 14 * published by the Free Software Foundation.
 15 *
 16 * This program is distributed in the hope that it will be useful, but
 17 * WITHOUT ANY WARRANTY; without even the implied warranty of
 18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 19 * General Public License for more details.
 20 *
 21 * You should have received a copy of the GNU General Public License
 22 * along with this program;
 23 *
 24 * The full GNU General Public License is included in this distribution
 25 * in the file called COPYING.
 26 *
 27 * Contact Information:
 28 *  Intel Linux Wireless <linuxwifi@intel.com>
 29 * Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
 30 *
 31 * BSD LICENSE
 32 *
 33 * Copyright(c) 2005 - 2014 Intel Corporation. All rights reserved.
 34 * Copyright(c) 2013 - 2015 Intel Mobile Communications GmbH
 35 * Copyright(c) 2015        Intel Deutschland GmbH
 36 * All rights reserved.
 37 *
 38 * Redistribution and use in source and binary forms, with or without
 39 * modification, are permitted provided that the following conditions
 40 * are met:
 41 *
 42 *  * Redistributions of source code must retain the above copyright
 43 *    notice, this list of conditions and the following disclaimer.
 44 *  * Redistributions in binary form must reproduce the above copyright
 45 *    notice, this list of conditions and the following disclaimer in
 46 *    the documentation and/or other materials provided with the
 47 *    distribution.
 48 *  * Neither the name Intel Corporation nor the names of its
 49 *    contributors may be used to endorse or promote products derived
 50 *    from this software without specific prior written permission.
 51 *
 52 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 53 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 54 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
 55 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
 56 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 57 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
 58 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
 59 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
 60 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 61 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 62 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 63 *
 64 *****************************************************************************/
 65
 66#ifndef __mvm_fw_dbg_h__
 67#define __mvm_fw_dbg_h__
 68#include "iwl-fw-file.h"
 69#include "iwl-fw-error-dump.h"
 70#include "mvm.h"
 71
 72void iwl_mvm_fw_error_dump(struct iwl_mvm *mvm);
 73void iwl_mvm_free_fw_dump_desc(struct iwl_mvm *mvm);
 74int iwl_mvm_fw_dbg_collect_desc(struct iwl_mvm *mvm,
 75				const struct iwl_mvm_dump_desc *desc,
 76				const struct iwl_fw_dbg_trigger_tlv *trigger);
 77int iwl_mvm_fw_dbg_collect(struct iwl_mvm *mvm, enum iwl_fw_dbg_trigger trig,
 78			   const char *str, size_t len,
 79			   const struct iwl_fw_dbg_trigger_tlv *trigger);
 80int iwl_mvm_fw_dbg_collect_trig(struct iwl_mvm *mvm,
 81				struct iwl_fw_dbg_trigger_tlv *trigger,
 82				const char *fmt, ...) __printf(3, 4);
 83int iwl_mvm_start_fw_dbg_conf(struct iwl_mvm *mvm, u8 id);
 84
 85#define iwl_fw_dbg_trigger_enabled(fw, id) ({			\
 86	void *__dbg_trigger = (fw)->dbg_trigger_tlv[(id)];	\
 87	unlikely(__dbg_trigger);				\
 88})
 89
 90static inline struct iwl_fw_dbg_trigger_tlv*
 91_iwl_fw_dbg_get_trigger(const struct iwl_fw *fw, enum iwl_fw_dbg_trigger id)
 92{
 93	return fw->dbg_trigger_tlv[id];
 94}
 95
 96#define iwl_fw_dbg_get_trigger(fw, id) ({			\
 97	BUILD_BUG_ON(!__builtin_constant_p(id));		\
 98	BUILD_BUG_ON((id) >= FW_DBG_TRIGGER_MAX);		\
 99	_iwl_fw_dbg_get_trigger((fw), (id));			\
100})
101
102static inline bool
103iwl_fw_dbg_trigger_vif_match(struct iwl_fw_dbg_trigger_tlv *trig,
104			     struct ieee80211_vif *vif)
105{
106	u32 trig_vif = le32_to_cpu(trig->vif_type);
107
108	return trig_vif == IWL_FW_DBG_CONF_VIF_ANY ||
109	       ieee80211_vif_type_p2p(vif) == trig_vif;
110}
111
112static inline bool
113iwl_fw_dbg_trigger_stop_conf_match(struct iwl_mvm *mvm,
114				   struct iwl_fw_dbg_trigger_tlv *trig)
115{
116	return ((trig->mode & IWL_FW_DBG_TRIGGER_STOP) &&
117		(mvm->fw_dbg_conf == FW_DBG_INVALID ||
118		(BIT(mvm->fw_dbg_conf) & le32_to_cpu(trig->stop_conf_ids))));
119}
120
121static inline bool
122iwl_fw_dbg_no_trig_window(struct iwl_mvm *mvm,
123			  struct iwl_fw_dbg_trigger_tlv *trig)
124{
125	unsigned long wind_jiff =
126		msecs_to_jiffies(le16_to_cpu(trig->trig_dis_ms));
127	u32 id = le32_to_cpu(trig->id);
128
129	/* If this is the first event checked, jump to update start ts */
130	if (mvm->fw_dbg_non_collect_ts_start[id] &&
131	    (time_after(mvm->fw_dbg_non_collect_ts_start[id] + wind_jiff,
132			jiffies)))
133		return true;
134
135	mvm->fw_dbg_non_collect_ts_start[id] = jiffies;
136	return false;
137}
138
139static inline bool
140iwl_fw_dbg_trigger_check_stop(struct iwl_mvm *mvm,
141			      struct ieee80211_vif *vif,
142			      struct iwl_fw_dbg_trigger_tlv *trig)
143{
144	if (vif && !iwl_fw_dbg_trigger_vif_match(trig, vif))
145		return false;
146
147	if (iwl_fw_dbg_no_trig_window(mvm, trig)) {
148		IWL_WARN(mvm, "Trigger %d occurred while no-collect window.\n",
149			 trig->id);
150		return false;
151	}
152
153	return iwl_fw_dbg_trigger_stop_conf_match(mvm, trig);
154}
155
156static inline void
157_iwl_fw_dbg_trigger_simple_stop(struct iwl_mvm *mvm,
158				struct ieee80211_vif *vif,
159				struct iwl_fw_dbg_trigger_tlv *trigger)
160{
161	if (!trigger)
162		return;
163
164	if (!iwl_fw_dbg_trigger_check_stop(mvm, vif, trigger))
165		return;
166
167	iwl_mvm_fw_dbg_collect_trig(mvm, trigger, NULL);
168}
169
170#define iwl_fw_dbg_trigger_simple_stop(mvm, vif, trig)	\
171	_iwl_fw_dbg_trigger_simple_stop((mvm), (vif),	\
172					iwl_fw_dbg_get_trigger((mvm)->fw,\
173							       (trig)))
174
175#endif  /* __mvm_fw_dbg_h__ */