@@ -78,6 +78,54 @@ void efx_update_debugfs_netdev(struct efx_nic *efx)
mutex_unlock(&efx->debugfs_symlink_mutex);
}
+#define EFX_DEBUGFS_CHANNEL(_type, _name) \
+ debugfs_create_##_type(#_name, 0444, channel->debug_dir, &channel->_name)
+
+/* Create basic debugfs parameter files for an Efx channel */
+static void efx_init_debugfs_channel_files(struct efx_channel *channel)
+{
+ EFX_DEBUGFS_CHANNEL(bool, enabled);
+ EFX_DEBUGFS_CHANNEL(u32, irq); /* actually an int */
+ EFX_DEBUGFS_CHANNEL(u32, eventq_read_ptr);
+}
+
+/**
+ * efx_init_debugfs_channel - create debugfs directory for channel
+ * @channel: Efx channel
+ *
+ * Create a debugfs directory containing parameter-files for @channel.
+ * The directory must be cleaned up using efx_fini_debugfs_channel().
+ *
+ * Return: a negative error code or 0 on success.
+ */
+int efx_init_debugfs_channel(struct efx_channel *channel)
+{
+ char name[EFX_DEBUGFS_NAME_LEN];
+
+ if (!channel->efx->debug_channels_dir)
+ return -ENODEV;
+ if (snprintf(name, sizeof(name), "%d", channel->channel)
+ >= sizeof(name))
+ return -ENAMETOOLONG;
+ channel->debug_dir = debugfs_create_dir(name, channel->efx->debug_channels_dir);
+ if (!channel->debug_dir)
+ return -ENOMEM;
+ efx_init_debugfs_channel_files(channel);
+ return 0;
+}
+
+/**
+ * efx_fini_debugfs_channel - remove debugfs directory for channel
+ * @channel: Efx channel
+ *
+ * Remove directory created for @channel by efx_init_debugfs_channel().
+ */
+void efx_fini_debugfs_channel(struct efx_channel *channel)
+{
+ debugfs_remove_recursive(channel->debug_dir);
+ channel->debug_dir = NULL;
+}
+
static int efx_debugfs_enum_read(struct seq_file *s, void *d)
{
struct efx_debugfs_enum_data *data = s->private;
@@ -160,6 +208,9 @@ int efx_init_debugfs_nic(struct efx_nic *efx)
if (!efx->debug_dir)
return -ENOMEM;
efx_init_debugfs_nic_files(efx);
+ /* Create channels subdirectory */
+ efx->debug_channels_dir = debugfs_create_dir("channels",
+ efx->debug_dir);
return 0;
}
@@ -22,11 +22,20 @@
* bound and created a &struct efx_nic, there is a directory &efx_nic.debug_dir
* in "cards" whose name is the PCI address of the device; it is to this
* directory that the netdev symlink points.
+ *
+ * Under this directory, besides top-level parameter files, are:
+ *
+ * * "channels/" (&efx_nic.debug_channels_dir). For each channel, this will
+ * contain a directory (&efx_channel.debug_dir), whose name is the channel
+ * index (in decimal).
*/
void efx_fini_debugfs_netdev(struct net_device *net_dev);
void efx_update_debugfs_netdev(struct efx_nic *efx);
+int efx_init_debugfs_channel(struct efx_channel *channel);
+void efx_fini_debugfs_channel(struct efx_channel *channel);
+
int efx_init_debugfs_nic(struct efx_nic *efx);
void efx_fini_debugfs_nic(struct efx_nic *efx);
@@ -39,6 +48,12 @@ static inline void efx_fini_debugfs_netdev(struct net_device *net_dev) {}
static inline void efx_update_debugfs_netdev(struct efx_nic *efx) {}
+int efx_init_debugfs_channel(struct efx_channel *channel)
+{
+ return 0;
+}
+void efx_fini_debugfs_channel(struct efx_channel *channel) {}
+
static inline int efx_init_debugfs_nic(struct efx_nic *efx)
{
return 0;
@@ -19,6 +19,7 @@
#include "nic.h"
#include "sriov.h"
#include "workarounds.h"
+#include "debugfs.h"
/* This is the first interrupt mode to try out of:
* 0 => MSI-X
@@ -667,6 +668,12 @@ static int efx_probe_channel(struct efx_channel *channel)
channel->rx_list = NULL;
+ rc = efx_init_debugfs_channel(channel);
+ if (rc) /* not fatal */
+ netif_err(channel->efx, drv, channel->efx->net_dev,
+ "Failed to create debugfs for channel %d, rc=%d\n",
+ channel->channel, rc);
+
return 0;
fail:
@@ -743,6 +750,7 @@ void efx_remove_channel(struct efx_channel *channel)
netif_dbg(channel->efx, drv, channel->efx->net_dev,
"destroy chan %d\n", channel->channel);
+ efx_fini_debugfs_channel(channel);
efx_for_each_channel_rx_queue(rx_queue, channel)
efx_remove_rx_queue(rx_queue);
@@ -528,6 +528,10 @@ struct efx_channel {
#define RPS_FLOW_ID_INVALID 0xFFFFFFFF
u32 *rps_flow_id;
#endif
+#ifdef CONFIG_DEBUG_FS
+ /** @debug_dir: Channel debugfs directory (under @efx->debug_channels_dir) */
+ struct dentry *debug_dir;
+#endif
unsigned int n_rx_tobe_disc;
unsigned int n_rx_ip_hdr_chksum_err;
@@ -1144,6 +1148,8 @@ struct efx_nic {
#ifdef CONFIG_DEBUG_FS
/** @debug_dir: NIC debugfs directory */
struct dentry *debug_dir;
+ /** @debug_channels_dir: contains channel debugfs dirs. Under @debug_dir */
+ struct dentry *debug_channels_dir;
/** @debug_symlink: NIC debugfs symlink (``nic_eth%d``) */
struct dentry *debug_symlink;
/** @debug_interrupt_mode: debugfs details for printing @interrupt_mode */