Nothing lives outside the repo: the bench ixgbe driver source moves in tracked at kernel/ixgbe-sff/ (build artifacts gitignored, load-ixgbe repointed, module build verified from the new home — the reg_ops/ts_bench bench extras are finally versioned), the ice sff_i2c patch is vendored at docs/nics/e810/ice-sff-i2c.patch with its out-of-tree build recipe (TRACE_INCLUDE_PATH fixup, version-matched Makefile), the e810 NVM flash logistics land in the e810 README (exact package name, rollback -m B49691D578EC into the inactive bank, post-flash inventory failing until power cycle is the expected tell), and every ~/work/phydiag-work pointer becomes an inline statement; phydiag-work, ice-sff, e810nvm and the wiitekphy CLI (a duplicate of documented transport+protocol) are deleted
This commit is contained in:
@@ -0,0 +1,202 @@
|
||||
diff --git a/drivers/net/ethernet/intel/ice/ice_debugfs.c b/drivers/net/ethernet/intel/ice/ice_debugfs.c
|
||||
index f450250fc..f0205e58a 100644
|
||||
--- a/drivers/net/ethernet/intel/ice/ice_debugfs.c
|
||||
+++ b/drivers/net/ethernet/intel/ice/ice_debugfs.c
|
||||
@@ -2,10 +2,187 @@
|
||||
/* Copyright (c) 2022, Intel Corporation. */
|
||||
|
||||
#include <linux/debugfs.h>
|
||||
+#include <linux/uaccess.h>
|
||||
#include "ice.h"
|
||||
|
||||
static struct dentry *ice_debugfs_root;
|
||||
|
||||
+#define ICE_SFF_I2C_MAX_DATA 16
|
||||
+
|
||||
+struct ice_sff_i2c_ctx {
|
||||
+ struct ice_pf *pf;
|
||||
+ char resp[ICE_SFF_I2C_MAX_DATA * 3 + 32];
|
||||
+ size_t resp_len;
|
||||
+};
|
||||
+
|
||||
+static int ice_sff_i2c_open(struct inode *inode, struct file *filp)
|
||||
+{
|
||||
+ struct ice_sff_i2c_ctx *ctx;
|
||||
+
|
||||
+ ctx = kzalloc(sizeof(*ctx), GFP_KERNEL);
|
||||
+ if (!ctx)
|
||||
+ return -ENOMEM;
|
||||
+
|
||||
+ ctx->pf = inode->i_private;
|
||||
+ filp->private_data = ctx;
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+static int ice_sff_i2c_release(struct inode *inode, struct file *filp)
|
||||
+{
|
||||
+ kfree(filp->private_data);
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+static ssize_t ice_sff_i2c_write(struct file *filp, const char __user *ubuf,
|
||||
+ size_t count, loff_t *ppos)
|
||||
+{
|
||||
+ struct ice_sff_i2c_ctx *ctx = filp->private_data;
|
||||
+ struct ice_hw *hw = &ctx->pf->hw;
|
||||
+ u8 data[ICE_SFF_I2C_MAX_DATA] = {};
|
||||
+ u8 bus, off, arg;
|
||||
+ char cmd[64];
|
||||
+ char op;
|
||||
+ int ret;
|
||||
+
|
||||
+ if (!count || count >= sizeof(cmd))
|
||||
+ return -EINVAL;
|
||||
+ if (copy_from_user(cmd, ubuf, count))
|
||||
+ return -EFAULT;
|
||||
+ cmd[count] = '\0';
|
||||
+
|
||||
+ switch (cmd[0]) {
|
||||
+ case 'r':
|
||||
+ if (sscanf(cmd, "%c %hhx %hhx %hhx", &op, &bus, &off, &arg) != 4)
|
||||
+ return -EINVAL;
|
||||
+ if (arg < 1 || arg > ICE_SFF_I2C_MAX_DATA)
|
||||
+ return -EINVAL;
|
||||
+ ret = ice_aq_sff_eeprom(hw, 0, bus, off, 0, 0, data, arg,
|
||||
+ false, NULL);
|
||||
+ break;
|
||||
+ case 'w':
|
||||
+ if (sscanf(cmd, "%c %hhx %hhx %hhx", &op, &bus, &off, &arg) != 4)
|
||||
+ return -EINVAL;
|
||||
+ data[0] = arg;
|
||||
+ ret = ice_aq_sff_eeprom(hw, 0, bus, off, 0, 0, data, 1,
|
||||
+ true, NULL);
|
||||
+ break;
|
||||
+ case 't': {
|
||||
+ struct ice_aqc_get_link_topo tcmd = {};
|
||||
+ u8 part;
|
||||
+ u16 handle;
|
||||
+
|
||||
+ if (sscanf(cmd, "%c %hhx %hhx", &op,
|
||||
+ &tcmd.addr.topo_params.node_type_ctx,
|
||||
+ &tcmd.addr.topo_params.index) != 3)
|
||||
+ return -EINVAL;
|
||||
+ ret = ice_aq_get_netlist_node(hw, &tcmd, &part, &handle);
|
||||
+ if (!ret) {
|
||||
+ ctx->resp_len = scnprintf(ctx->resp, sizeof(ctx->resp),
|
||||
+ "ok %02x %04x\n", part,
|
||||
+ handle);
|
||||
+ *ppos = 0;
|
||||
+ return count;
|
||||
+ }
|
||||
+ break;
|
||||
+ }
|
||||
+ case 'i': case 'j': {
|
||||
+ struct ice_aqc_link_topo_addr topo = {};
|
||||
+ u16 bus16, addr16, handle;
|
||||
+ u8 params, n;
|
||||
+ int fields;
|
||||
+
|
||||
+ fields = sscanf(cmd,
|
||||
+ "%c %hhx %hhx %hx %hx %hx %hhx %hhx %hhx %hhx %hhx",
|
||||
+ &op, &topo.topo_params.node_type_ctx,
|
||||
+ &topo.topo_params.index, &handle, &bus16,
|
||||
+ &addr16, ¶ms, &data[0], &data[1], &data[2],
|
||||
+ &data[3]);
|
||||
+ if (fields < 7)
|
||||
+ return -EINVAL;
|
||||
+ topo.handle = cpu_to_le16(handle);
|
||||
+ n = params & ICE_AQC_I2C_DATA_SIZE_M;
|
||||
+ arg = n;
|
||||
+ if (op == 'i') {
|
||||
+ if (fields != 7 || n < 1)
|
||||
+ return -EINVAL;
|
||||
+ ret = ice_aq_read_i2c(hw, topo, bus16,
|
||||
+ cpu_to_le16(addr16), params,
|
||||
+ data, NULL);
|
||||
+ } else {
|
||||
+ if (n < 1 || n > 4 || fields != 7 + n)
|
||||
+ return -EINVAL;
|
||||
+ ret = ice_aq_write_i2c(hw, topo, bus16,
|
||||
+ cpu_to_le16(addr16), params,
|
||||
+ data, NULL);
|
||||
+ }
|
||||
+ op = op == 'i' ? 'r' : 'w';
|
||||
+ break;
|
||||
+ }
|
||||
+ case 'x': {
|
||||
+ struct libie_aq_desc desc = {};
|
||||
+ u16 opcode, flags;
|
||||
+ u32 p[4] = {};
|
||||
+
|
||||
+ if (sscanf(cmd, "%c %hx %hx %x %x %x %x", &op, &flags, &opcode,
|
||||
+ &p[0], &p[1], &p[2], &p[3]) != 7)
|
||||
+ return -EINVAL;
|
||||
+ desc.flags = cpu_to_le16(flags);
|
||||
+ desc.opcode = cpu_to_le16(opcode);
|
||||
+ desc.params.generic.param0 = cpu_to_le32(p[0]);
|
||||
+ desc.params.generic.param1 = cpu_to_le32(p[1]);
|
||||
+ desc.params.generic.addr_high = cpu_to_le32(p[2]);
|
||||
+ desc.params.generic.addr_low = cpu_to_le32(p[3]);
|
||||
+ ret = ice_aq_send_cmd(hw, &desc, NULL, 0, NULL);
|
||||
+ ctx->resp_len = scnprintf(ctx->resp, sizeof(ctx->resp),
|
||||
+ "%s %d aq %d wb %08x %08x %08x %08x\n",
|
||||
+ ret ? "err" : "ok", ret,
|
||||
+ hw->adminq.sq_last_status,
|
||||
+ le32_to_cpu(desc.params.generic.param0),
|
||||
+ le32_to_cpu(desc.params.generic.param1),
|
||||
+ le32_to_cpu(desc.params.generic.addr_high),
|
||||
+ le32_to_cpu(desc.params.generic.addr_low));
|
||||
+ *ppos = 0;
|
||||
+ return count;
|
||||
+ }
|
||||
+ default:
|
||||
+ return -EINVAL;
|
||||
+ }
|
||||
+
|
||||
+ if (ret)
|
||||
+ ctx->resp_len = scnprintf(ctx->resp, sizeof(ctx->resp),
|
||||
+ "err %d aq %d\n", ret,
|
||||
+ hw->adminq.sq_last_status);
|
||||
+ else if (op == 'r')
|
||||
+ ctx->resp_len = scnprintf(ctx->resp, sizeof(ctx->resp),
|
||||
+ "ok %*ph\n", (int)arg, data);
|
||||
+ else
|
||||
+ ctx->resp_len = scnprintf(ctx->resp, sizeof(ctx->resp), "ok\n");
|
||||
+
|
||||
+ *ppos = 0;
|
||||
+
|
||||
+ return count;
|
||||
+}
|
||||
+
|
||||
+static ssize_t ice_sff_i2c_read(struct file *filp, char __user *ubuf,
|
||||
+ size_t count, loff_t *ppos)
|
||||
+{
|
||||
+ struct ice_sff_i2c_ctx *ctx = filp->private_data;
|
||||
+
|
||||
+ return simple_read_from_buffer(ubuf, count, ppos, ctx->resp,
|
||||
+ ctx->resp_len);
|
||||
+}
|
||||
+
|
||||
+static const struct file_operations ice_sff_i2c_fops = {
|
||||
+ .owner = THIS_MODULE,
|
||||
+ .open = ice_sff_i2c_open,
|
||||
+ .release = ice_sff_i2c_release,
|
||||
+ .read = ice_sff_i2c_read,
|
||||
+ .write = ice_sff_i2c_write,
|
||||
+};
|
||||
+
|
||||
int ice_debugfs_pf_init(struct ice_pf *pf)
|
||||
{
|
||||
const char *name = pci_name(pf->pdev);
|
||||
@@ -14,6 +191,9 @@ int ice_debugfs_pf_init(struct ice_pf *pf)
|
||||
if (IS_ERR(pf->ice_debugfs_pf))
|
||||
return PTR_ERR(pf->ice_debugfs_pf);
|
||||
|
||||
+ debugfs_create_file("sff_i2c", 0600, pf->ice_debugfs_pf, pf,
|
||||
+ &ice_sff_i2c_fops);
|
||||
+
|
||||
return 0;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user