[PATCH v1 4/5] net/ixgbe: add ACI debug printouts
Anatoly Burakov
anatoly.burakov at intel.com
Mon Jun 9 12:25:37 CEST 2025
From: Piotr Kwapulinski <piotr.kwapulinski at intel.com>
Add more verbose printouts for ACI when debugging is enabled.
Signed-off-by: Piotr Kwapulinski <piotr.kwapulinski at intel.com>
Signed-off-by: Anatoly Burakov <anatoly.burakov at intel.com>
---
drivers/net/intel/ixgbe/base/ixgbe_e610.c | 110 ++++++++++++++++++
drivers/net/intel/ixgbe/base/ixgbe_e610.h | 2 +
drivers/net/intel/ixgbe/base/ixgbe_osdep.h | 1 +
.../net/intel/ixgbe/base/ixgbe_type_e610.h | 1 +
4 files changed, 114 insertions(+)
diff --git a/drivers/net/intel/ixgbe/base/ixgbe_e610.c b/drivers/net/intel/ixgbe/base/ixgbe_e610.c
index cf45db3bc4..06a69d1d62 100644
--- a/drivers/net/intel/ixgbe/base/ixgbe_e610.c
+++ b/drivers/net/intel/ixgbe/base/ixgbe_e610.c
@@ -31,6 +31,99 @@ void ixgbe_shutdown_aci(struct ixgbe_hw *hw)
ixgbe_destroy_lock(&hw->aci.lock);
}
+/**
+ * ixgbe_aci_debug_array - dump a buffer of data row by row
+ * @row_size: size in bytes of data dumped in a single row
+ * @buf: data to be dumped into the debug log
+ * @buf_size: size of buffer
+ *
+ * Debug function for dumping a binary blob of data row by row.
+ */
+STATIC void ixgbe_aci_debug_array(struct ixgbe_hw *hw, u16 row_size, u8 *buf,
+ u16 buf_size)
+{
+ char debug_portion[IXGBE_ACI_MAX_DEBUG_STRING_LENGTH] = {'\0'};
+ char debug_string[IXGBE_ACI_MAX_DEBUG_STRING_LENGTH] = {'\0'};
+ u16 i = 0, j = 0;
+ s16 remaining_space = IXGBE_ACI_MAX_DEBUG_STRING_LENGTH - 1;
+ s16 nbytes = 0;
+ if (!hw)
+ return;
+ if (buf && buf_size && row_size) {
+ if (buf_size >= row_size) {
+ for (i = 0; i < (buf_size - row_size); i += row_size) {
+ nbytes = snprintf(debug_string, sizeof(debug_string), "0x%04X : ", i);
+ remaining_space = IXGBE_ACI_MAX_DEBUG_STRING_LENGTH - nbytes - 1;
+ for (j = 0; j < row_size; j++) {
+ nbytes = snprintf(debug_portion, sizeof(debug_portion), "0x%02X ", buf[i + j]);
+ strncat(debug_string, debug_portion, remaining_space);
+ remaining_space -= nbytes;
+ if (remaining_space <= 0) break;
+ }
+ strncat(debug_string, "\n", remaining_space);
+ DEBUGOUT1("%s", debug_string);
+ memset(debug_string, 0, IXGBE_ACI_MAX_DEBUG_STRING_LENGTH);
+ }
+ }
+ if (i < buf_size) {
+ nbytes = snprintf(debug_string, sizeof(debug_string), "0x%04X : ", i);
+ remaining_space = IXGBE_ACI_MAX_DEBUG_STRING_LENGTH - nbytes - 1;
+ for (j = 0; j < (buf_size - i); j++) {
+ nbytes = snprintf(debug_portion, sizeof(debug_portion), "0x%02X ", buf[i + j]);
+ strncat(debug_string, debug_portion, remaining_space);
+ remaining_space -= nbytes;
+ if (remaining_space <= 0) break;
+ }
+ strncat(debug_string, "\n", remaining_space);
+ DEBUGOUT1("%s", debug_string);
+ }
+ }
+}
+
+/**
+ * ixgbe_aci_debug - dump the ACI data with the descriptor contents.
+ * @hw: pointer to the hardware structure
+ * @desc: pointer to control queue descriptor
+ * @buf: pointer to command buffer
+ * @buf_len: max length of buf
+ *
+ * Debug function for dumping logs about ACI command with descriptor contents.
+ */
+void ixgbe_aci_debug(struct ixgbe_hw *hw, void *desc, void *buf, u16 buf_len)
+{
+ struct ixgbe_aci_desc *aci_desc = (struct ixgbe_aci_desc *)desc;
+ u16 datalen, flags;
+
+ if (!hw || !desc)
+ return;
+
+ datalen = IXGBE_LE16_TO_CPU(aci_desc->datalen);
+ flags = IXGBE_LE16_TO_CPU(aci_desc->flags);
+
+ DEBUGOUT4("CQ CMD: opcode 0x%04X, flags 0x%04X, datalen 0x%04X, retval 0x%04X\n",
+ IXGBE_LE16_TO_CPU(aci_desc->opcode), flags, datalen,
+ IXGBE_LE16_TO_CPU(aci_desc->retval));
+ DEBUGOUT2("\tcookie (h,l) 0x%08X 0x%08X\n",
+ IXGBE_LE32_TO_CPU(aci_desc->cookie_high),
+ IXGBE_LE32_TO_CPU(aci_desc->cookie_low));
+ DEBUGOUT2("\tparam (0,1) 0x%08X 0x%08X\n",
+ IXGBE_LE32_TO_CPU(aci_desc->params.generic.param0),
+ IXGBE_LE32_TO_CPU(aci_desc->params.generic.param1));
+ DEBUGOUT2("\taddr (h,l) 0x%08X 0x%08X\n",
+ IXGBE_LE32_TO_CPU(aci_desc->params.generic.addr_high),
+ IXGBE_LE32_TO_CPU(aci_desc->params.generic.addr_low));
+
+ /* Dump buffer if 1) one exists and 2) is either a response indicated
+ * by the DD and/or CMP flag set or a command with the RD flag set.
+ */
+ if (buf && aci_desc->datalen != 0 &&
+ (flags & (IXGBE_ACI_FLAG_DD | IXGBE_ACI_FLAG_CMP) ||
+ flags & IXGBE_ACI_FLAG_RD)) {
+ DEBUGOUT("Buffer:\n");
+ ixgbe_aci_debug_array(hw, 16, (u8 *)buf, min(buf_len, datalen));
+ }
+}
+
/**
* ixgbe_should_retry_aci_send_cmd_execute - decide if ACI command should
* be resent
@@ -94,10 +187,12 @@ ixgbe_aci_send_cmd_execute(struct ixgbe_hw *hw, struct ixgbe_aci_desc *desc,
/* It's necessary to check if mechanism is enabled */
hicr = IXGBE_READ_REG(hw, PF_HICR);
if (!(hicr & PF_HICR_EN)) {
+ DEBUGOUT("CSR mechanism is not enabled\n");
status = IXGBE_ERR_ACI_DISABLED;
break;
}
if (hicr & PF_HICR_C) {
+ DEBUGOUT("CSR mechanism is busy\n");
hw->aci.last_status = IXGBE_ACI_RC_EBUSY;
status = IXGBE_ERR_ACI_BUSY;
break;
@@ -105,6 +200,7 @@ ixgbe_aci_send_cmd_execute(struct ixgbe_hw *hw, struct ixgbe_aci_desc *desc,
opcode = desc->opcode;
if (buf_size > IXGBE_ACI_MAX_BUFFER_SIZE) {
+ DEBUGOUT("buf_size is too big\n");
status = IXGBE_ERR_PARAM;
break;
}
@@ -117,6 +213,7 @@ ixgbe_aci_send_cmd_execute(struct ixgbe_hw *hw, struct ixgbe_aci_desc *desc,
if ((buf && buf_size == 0) ||
(buf == NULL && buf_size)) {
status = IXGBE_ERR_PARAM;
+ DEBUGOUT("Error: Invalid argument buf or buf_size\n");
break;
}
if (buf && buf_size)
@@ -156,6 +253,8 @@ ixgbe_aci_send_cmd_execute(struct ixgbe_hw *hw, struct ixgbe_aci_desc *desc,
}
}
+ ixgbe_aci_debug(hw, (void *)desc, tmp_buf, (u16)tmp_buf_size);
+
/* Descriptor is written to specific registers */
for (i = 0; i < IXGBE_ACI_DESC_SIZE_IN_DWORDS; i++)
IXGBE_WRITE_REG(hw, PF_HIDA(i),
@@ -195,6 +294,7 @@ ixgbe_aci_send_cmd_execute(struct ixgbe_hw *hw, struct ixgbe_aci_desc *desc,
raw_desc[i] = IXGBE_READ_REG(hw, PF_HIDA(i));
raw_desc[i] = IXGBE_CPU_TO_LE32(raw_desc[i]);
}
+ ixgbe_aci_debug(hw, (void *)raw_desc, NULL, 0);
}
/* Read async Admin Command response */
@@ -203,13 +303,18 @@ ixgbe_aci_send_cmd_execute(struct ixgbe_hw *hw, struct ixgbe_aci_desc *desc,
raw_desc[i] = IXGBE_READ_REG(hw, PF_HIDA_2(i));
raw_desc[i] = IXGBE_CPU_TO_LE32(raw_desc[i]);
}
+ ixgbe_aci_debug(hw, (void *)raw_desc, NULL, 0);
}
/* Handle timeout and invalid state of HICR register */
if (hicr & PF_HICR_C) {
+ DEBUGOUT1("Error: Admin Command 0x%X command timeout\n",
+ desc->opcode);
status = IXGBE_ERR_ACI_TIMEOUT;
break;
} else if (!(hicr & PF_HICR_SV) && !(hicr & PF_HICR_EV)) {
+ DEBUGOUT1("Error: Admin Command 0x%X invalid state of HICR register\n",
+ desc->opcode);
status = IXGBE_ERR_ACI_ERROR;
break;
}
@@ -221,11 +326,14 @@ ixgbe_aci_send_cmd_execute(struct ixgbe_hw *hw, struct ixgbe_aci_desc *desc,
*/
if (desc->opcode != opcode &&
opcode != IXGBE_CPU_TO_LE16(ixgbe_aci_opc_get_fw_event)) {
+ DEBUGOUT("Error: Admin Command failed because of bad opcode was returned\n");
status = IXGBE_ERR_ACI_ERROR;
break;
}
if (desc->retval != IXGBE_ACI_RC_OK) {
+ DEBUGOUT1("Error: Admin Command failed with error %x\n",
+ desc->retval);
hw->aci.last_status = (enum ixgbe_aci_err)desc->retval;
status = IXGBE_ERR_ACI_ERROR;
break;
@@ -239,6 +347,8 @@ ixgbe_aci_send_cmd_execute(struct ixgbe_hw *hw, struct ixgbe_aci_desc *desc,
tmp_buf[i] = IXGBE_CPU_TO_LE32(tmp_buf[i]);
}
memcpy(buf, tmp_buf, buf_size);
+ ixgbe_aci_debug(hw, (void *)raw_desc, tmp_buf,
+ (u16)tmp_buf_size);
}
} while (0);
diff --git a/drivers/net/intel/ixgbe/base/ixgbe_e610.h b/drivers/net/intel/ixgbe/base/ixgbe_e610.h
index f60268cf91..e950f89e80 100644
--- a/drivers/net/intel/ixgbe/base/ixgbe_e610.h
+++ b/drivers/net/intel/ixgbe/base/ixgbe_e610.h
@@ -10,6 +10,8 @@
void ixgbe_init_aci(struct ixgbe_hw *hw);
void ixgbe_shutdown_aci(struct ixgbe_hw *hw);
+void ixgbe_aci_debug(struct ixgbe_hw *hw, void *desc, void *buf, u16 buf_len);
+
s32 ixgbe_aci_send_cmd(struct ixgbe_hw *hw, struct ixgbe_aci_desc *desc,
void *buf, u16 buf_size);
bool ixgbe_aci_check_event_pending(struct ixgbe_hw *hw);
diff --git a/drivers/net/intel/ixgbe/base/ixgbe_osdep.h b/drivers/net/intel/ixgbe/base/ixgbe_osdep.h
index 53d0422193..4dfed02137 100644
--- a/drivers/net/intel/ixgbe/base/ixgbe_osdep.h
+++ b/drivers/net/intel/ixgbe/base/ixgbe_osdep.h
@@ -39,6 +39,7 @@
#define DEBUGOUT1(S, ...) DEBUGOUT(S, ##__VA_ARGS__)
#define DEBUGOUT2(S, ...) DEBUGOUT(S, ##__VA_ARGS__)
#define DEBUGOUT3(S, ...) DEBUGOUT(S, ##__VA_ARGS__)
+#define DEBUGOUT4(S, ...) DEBUGOUT(S, ##__VA_ARGS__)
#define DEBUGOUT6(S, ...) DEBUGOUT(S, ##__VA_ARGS__)
#define DEBUGOUT7(S, ...) DEBUGOUT(S, ##__VA_ARGS__)
diff --git a/drivers/net/intel/ixgbe/base/ixgbe_type_e610.h b/drivers/net/intel/ixgbe/base/ixgbe_type_e610.h
index e804172252..9348294735 100644
--- a/drivers/net/intel/ixgbe/base/ixgbe_type_e610.h
+++ b/drivers/net/intel/ixgbe/base/ixgbe_type_e610.h
@@ -361,6 +361,7 @@
#define IXGBE_ACI_DESC_COOKIE_L_DWORD_OFFSET 3
#define IXGBE_ACI_SEND_DELAY_TIME_MS 10
#define IXGBE_ACI_SEND_MAX_EXECUTE 3
+#define IXGBE_ACI_MAX_DEBUG_STRING_LENGTH 128
/* [ms] timeout of waiting for sync response */
#define IXGBE_ACI_SYNC_RESPONSE_TIMEOUT 100000
/* [ms] timeout of waiting for async response */
--
2.47.1
More information about the dev
mailing list