File Index
Files and directories
Sign in
FILE

debugfs.h

File preview with syntax highlighting.

linux-6.19.14/drivers/net/wireless/intel/iwlwifi/mld/debugfs.h C
  1/* SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause */
  2/*
  3 * Copyright (C) 2024-2025 Intel Corporation
  4 */
  5#include "iface.h"
  6#include "sta.h"
  7
  8#define MLD_DEBUGFS_OPEN_WRAPPER(name, buflen, argtype)			\
  9struct dbgfs_##name##_data {						\
 10	argtype *arg;							\
 11	bool read_done;							\
 12	ssize_t rlen;							\
 13	char buf[buflen];						\
 14};									\
 15static int _iwl_dbgfs_##name##_open(struct inode *inode,		\
 16				    struct file *file)			\
 17{									\
 18	struct dbgfs_##name##_data *data;				\
 19									\
 20	if ((file->f_flags & O_ACCMODE) == O_RDWR)			\
 21		return -EOPNOTSUPP;					\
 22									\
 23	data = kzalloc(sizeof(*data), GFP_KERNEL);			\
 24	if (!data)							\
 25		return -ENOMEM;						\
 26									\
 27	data->read_done = false;					\
 28	data->arg = inode->i_private;					\
 29	file->private_data = data;					\
 30									\
 31	return 0;							\
 32}
 33
 34#define MLD_DEBUGFS_READ_WRAPPER(name)					\
 35static ssize_t _iwl_dbgfs_##name##_read(struct file *file,		\
 36					char __user *user_buf,		\
 37					size_t count, loff_t *ppos)	\
 38{									\
 39	struct dbgfs_##name##_data *data = file->private_data;		\
 40									\
 41	if (!data->read_done) {						\
 42		data->read_done = true;					\
 43		data->rlen = iwl_dbgfs_##name##_read(data->arg,		\
 44						     sizeof(data->buf),\
 45						     data->buf);	\
 46	}								\
 47									\
 48	if (data->rlen < 0)						\
 49		return data->rlen;					\
 50	return simple_read_from_buffer(user_buf, count, ppos,		\
 51				       data->buf, data->rlen);		\
 52}
 53
 54static int _iwl_dbgfs_release(struct inode *inode, struct file *file)
 55{
 56	kfree(file->private_data);
 57	return 0;
 58}
 59
 60#define _MLD_DEBUGFS_READ_FILE_OPS(name, buflen, argtype)		\
 61MLD_DEBUGFS_OPEN_WRAPPER(name, buflen, argtype)				\
 62MLD_DEBUGFS_READ_WRAPPER(name)						\
 63static const struct file_operations iwl_dbgfs_##name##_ops = {		\
 64	.read = _iwl_dbgfs_##name##_read,				\
 65	.open = _iwl_dbgfs_##name##_open,				\
 66	.llseek = generic_file_llseek,					\
 67	.release = _iwl_dbgfs_release,					\
 68}
 69
 70#define WIPHY_DEBUGFS_WRITE_HANDLER_WRAPPER(name)			\
 71static ssize_t iwl_dbgfs_##name##_write_handler(struct wiphy *wiphy,	\
 72				       struct file *file, char *buf,	\
 73				       size_t count, void *data)	\
 74{									\
 75	struct ieee80211_hw *hw = wiphy_to_ieee80211_hw(wiphy);		\
 76	struct iwl_mld *mld = IWL_MAC80211_GET_MLD(hw);			\
 77	return iwl_dbgfs_##name##_write(mld, buf, count, data);		\
 78}
 79
 80static inline struct iwl_mld *
 81iwl_mld_from_link_sta(struct ieee80211_link_sta *link_sta)
 82{
 83	struct ieee80211_vif *vif =
 84		iwl_mld_sta_from_mac80211(link_sta->sta)->vif;
 85	return iwl_mld_vif_from_mac80211(vif)->mld;
 86}
 87
 88static inline struct iwl_mld *
 89iwl_mld_from_bss_conf(struct ieee80211_bss_conf *link)
 90{
 91	return iwl_mld_vif_from_mac80211(link->vif)->mld;
 92}
 93
 94static inline struct iwl_mld *iwl_mld_from_vif(struct ieee80211_vif *vif)
 95{
 96	return iwl_mld_vif_from_mac80211(vif)->mld;
 97}
 98
 99#define WIPHY_DEBUGFS_WRITE_WRAPPER(name, bufsz, objtype)		\
100WIPHY_DEBUGFS_WRITE_HANDLER_WRAPPER(name)				\
101static ssize_t __iwl_dbgfs_##name##_write(struct file *file,		\
102					  const char __user *user_buf,	\
103					  size_t count, loff_t *ppos)	\
104{									\
105	struct ieee80211_##objtype *arg = file->private_data;		\
106	struct iwl_mld *mld = iwl_mld_from_##objtype(arg);		\
107	char buf[bufsz] = {};						\
108									\
109	return wiphy_locked_debugfs_write(mld->wiphy, file,		\
110				buf, sizeof(buf),			\
111				user_buf, count,			\
112				iwl_dbgfs_##name##_write_handler,	\
113				arg);					\
114}
115
116#define WIPHY_DEBUGFS_WRITE_FILE_OPS(name, bufsz, objtype)		\
117	WIPHY_DEBUGFS_WRITE_WRAPPER(name, bufsz, objtype)		\
118	static const struct file_operations iwl_dbgfs_##name##_ops = {	\
119		.write = __iwl_dbgfs_##name##_write,			\
120		.open = simple_open,					\
121		.llseek = generic_file_llseek,				\
122	}
123
124#define WIPHY_DEBUGFS_READ_HANDLER_WRAPPER_MLD(name)			\
125static ssize_t iwl_dbgfs_##name##_read_handler(struct wiphy *wiphy,	\
126				       struct file *file, char *buf,	\
127				       size_t count, void *data)	\
128{									\
129	struct ieee80211_hw *hw = wiphy_to_ieee80211_hw(wiphy);		\
130	struct iwl_mld *mld = IWL_MAC80211_GET_MLD(hw);			\
131	return iwl_dbgfs_##name##_read(mld, buf, count);		\
132}
133
134#define WIPHY_DEBUGFS_WRITE_HANDLER_WRAPPER_MLD(name)			\
135static ssize_t iwl_dbgfs_##name##_write_handler(struct wiphy *wiphy,	\
136				       struct file *file, char *buf,	\
137				       size_t count, void *data)	\
138{									\
139	struct ieee80211_hw *hw = wiphy_to_ieee80211_hw(wiphy);		\
140	struct iwl_mld *mld = IWL_MAC80211_GET_MLD(hw);			\
141	return iwl_dbgfs_##name##_write(mld, buf, count);		\
142}
143
144#define WIPHY_DEBUGFS_WRITE_WRAPPER_MLD(name)				\
145WIPHY_DEBUGFS_WRITE_HANDLER_WRAPPER_MLD(name)				\
146static ssize_t __iwl_dbgfs_##name##_write(struct file *file,		\
147					  const char __user *user_buf,	\
148					  size_t count, loff_t *ppos)	\
149{									\
150	struct dbgfs_##name##_data *data = file->private_data;		\
151	struct iwl_mld *mld = data->arg;				\
152									\
153	return wiphy_locked_debugfs_write(mld->wiphy, file,		\
154				data->buf, sizeof(data->buf),		\
155				user_buf, count,			\
156				iwl_dbgfs_##name##_write_handler,	\
157				NULL);					\
158}
159
160#define WIPHY_DEBUGFS_READ_WRAPPER_MLD(name)				\
161WIPHY_DEBUGFS_READ_HANDLER_WRAPPER_MLD(name)				\
162static ssize_t __iwl_dbgfs_##name##_read(struct file *file,		\
163					char __user *user_buf,		\
164					size_t count, loff_t *ppos)	\
165{									\
166	struct dbgfs_##name##_data *data = file->private_data;		\
167	struct iwl_mld *mld = data->arg;				\
168									\
169	if (!data->read_done) {						\
170		data->read_done = true;					\
171		data->rlen = wiphy_locked_debugfs_read(mld->wiphy,	\
172				file, data->buf, sizeof(data->buf),	\
173				user_buf, count, ppos,			\
174				iwl_dbgfs_##name##_read_handler, NULL);	\
175		return data->rlen;					\
176	}								\
177									\
178	if (data->rlen < 0)						\
179		return data->rlen;					\
180	return simple_read_from_buffer(user_buf, count, ppos,		\
181				       data->buf, data->rlen);		\
182}
183
184#define WIPHY_DEBUGFS_READ_FILE_OPS_MLD(name, bufsz)			\
185	MLD_DEBUGFS_OPEN_WRAPPER(name, bufsz, struct iwl_mld)		\
186	WIPHY_DEBUGFS_READ_WRAPPER_MLD(name)				\
187	static const struct file_operations iwl_dbgfs_##name##_ops = {	\
188		.read = __iwl_dbgfs_##name##_read,			\
189		.open = _iwl_dbgfs_##name##_open,			\
190		.llseek = generic_file_llseek,				\
191		.release = _iwl_dbgfs_release,				\
192	}
193
194#define WIPHY_DEBUGFS_WRITE_FILE_OPS_MLD(name, bufsz)			\
195	MLD_DEBUGFS_OPEN_WRAPPER(name, bufsz, struct iwl_mld)		\
196	WIPHY_DEBUGFS_WRITE_WRAPPER_MLD(name)				\
197	static const struct file_operations iwl_dbgfs_##name##_ops = {	\
198		.write = __iwl_dbgfs_##name##_write,			\
199		.open = _iwl_dbgfs_##name##_open,			\
200		.llseek = generic_file_llseek,				\
201		.release = _iwl_dbgfs_release,				\
202	}
203
204#define WIPHY_DEBUGFS_READ_WRITE_FILE_OPS_MLD(name, bufsz)		\
205	MLD_DEBUGFS_OPEN_WRAPPER(name, bufsz, struct iwl_mld)		\
206	WIPHY_DEBUGFS_WRITE_WRAPPER_MLD(name)				\
207	WIPHY_DEBUGFS_READ_WRAPPER_MLD(name)				\
208	static const struct file_operations iwl_dbgfs_##name##_ops = {	\
209		.write = __iwl_dbgfs_##name##_write,			\
210		.read = __iwl_dbgfs_##name##_read,			\
211		.open = _iwl_dbgfs_##name##_open,			\
212		.llseek = generic_file_llseek,				\
213		.release = _iwl_dbgfs_release,				\
214	}
215
216#define WIPHY_DEBUGFS_WRITE_WRAPPER_IEEE80211(name, bufsz, objtype)	\
217WIPHY_DEBUGFS_WRITE_HANDLER_WRAPPER(name)				\
218static ssize_t _iwl_dbgfs_##name##_write(struct file *file,		\
219					  const char __user *user_buf,	\
220					  size_t count, loff_t *ppos)	\
221{									\
222	struct dbgfs_##name##_data *data = file->private_data;		\
223	struct ieee80211_##objtype *arg = data->arg;			\
224	struct iwl_mld *mld = iwl_mld_from_##objtype(arg);		\
225	char buf[bufsz] = {};						\
226									\
227	return wiphy_locked_debugfs_write(mld->wiphy, file,		\
228				buf, sizeof(buf),			\
229				user_buf, count,			\
230				iwl_dbgfs_##name##_write_handler,	\
231				arg);					\
232}
233
234#define IEEE80211_WIPHY_DEBUGFS_READ_WRITE_FILE_OPS(name, bufsz, objtype) \
235	MLD_DEBUGFS_OPEN_WRAPPER(name, bufsz, struct ieee80211_##objtype) \
236	WIPHY_DEBUGFS_WRITE_WRAPPER_IEEE80211(name, bufsz, objtype)	  \
237	MLD_DEBUGFS_READ_WRAPPER(name)					  \
238	static const struct file_operations iwl_dbgfs_##name##_ops = {	  \
239		.write = _iwl_dbgfs_##name##_write,			  \
240		.read = _iwl_dbgfs_##name##_read,			  \
241		.open = _iwl_dbgfs_##name##_open,			  \
242		.llseek = generic_file_llseek,				  \
243		.release = _iwl_dbgfs_release,				  \
244	}
~/ Read-only file preview.