aboutsummaryrefslogtreecommitdiffstats
path: root/epan/dissectors/packet-nvme.c
diff options
context:
space:
mode:
authorConstantine Gavrilov <constg@il.ibm.com>2021-05-25 18:04:23 +0300
committerWireshark GitLab Utility <gerald+gitlab-utility@wireshark.org>2021-05-28 08:45:26 +0000
commite75998cdedbecc6dd8fd28bee8fa30ffcac9ca0f (patch)
tree9d461e3c885fb9ea7059166ad2a5df30ef7af68b /epan/dissectors/packet-nvme.c
parentd5c1bd9d938cac598af737081addf97dfd7c901f (diff)
NVMe: decode Set Fatures response (DWORD0) in CQE.
Diffstat (limited to 'epan/dissectors/packet-nvme.c')
-rw-r--r--epan/dissectors/packet-nvme.c104
1 files changed, 96 insertions, 8 deletions
diff --git a/epan/dissectors/packet-nvme.c b/epan/dissectors/packet-nvme.c
index d2d211c9c1..65ac0994d5 100644
--- a/epan/dissectors/packet-nvme.c
+++ b/epan/dissectors/packet-nvme.c
@@ -449,6 +449,10 @@ static int hf_nvme_get_logpage_sanitize_rsvd = -1;
/* NVMe CQE fields */
static int hf_nvme_cqe_dword0 = -1;
+static int hf_nvme_cqe_dword0_sf_pm[4] = { NEG_LST_4 };
+static int hf_nvme_cqe_dword0_sf_lbart[3] = { NEG_LST_3 };
+static int hf_nvme_cqe_dword0_sf_nq[3] = { NEG_LST_3 };
+static int hf_nvme_cqe_dword0_sf_err = -1;
static int hf_nvme_cqe_dword1 = -1;
static int hf_nvme_cqe_sqhd = -1;
static int hf_nvme_cqe_sqid = -1;
@@ -2939,6 +2943,10 @@ static const value_string sf_wps[] = {
{ 0, NULL },
};
+static void add_nvme_queues(gchar *result, guint32 val)
+{
+ g_snprintf(result, ITEM_LABEL_LENGTH, "%x (%u)", val, val+1);
+}
static void dissect_nvme_set_features_dword11(tvbuff_t *cmd_tvb, proto_tree *cmd_tree, guint fid)
{
@@ -3188,9 +3196,45 @@ static const char *get_cqe_sc_string(guint sct, guint sc)
}
}
-void
-dissect_nvme_cqe(tvbuff_t *nvme_tvb, packet_info *pinfo, proto_tree *root_tree,
- struct nvme_cmd_ctx *cmd_ctx)
+static const value_string nvme_cqe_sc_sf_err_dword0_tbl[] = {
+ { 0xD, "Feature Identifier Not Saveable" },
+ { 0xE, "Feature Not Changeable" },
+ { 0xF, "Feature Not Namespace Specific" },
+ { 0x14, "Overlapping Range" },
+ { 0, NULL },
+};
+
+static void decode_dword0_cqe(tvbuff_t *nvme_tvb, proto_tree *cqe_tree, guint sc, struct nvme_cmd_ctx *cmd_ctx)
+{
+ switch (cmd_ctx->opcode) {
+ case NVME_AQ_OPC_SET_FEATURES:
+ {
+ if (sc) {
+ proto_tree_add_item(cqe_tree, hf_nvme_cqe_dword0_sf_err, nvme_tvb, 0, 4, ENC_LITTLE_ENDIAN);
+ } else {
+ switch (cmd_ctx->cmd_ctx.set_features.fid) {
+ case F_POWER_MGMT:
+ add_group_mask_entry(nvme_tvb, cqe_tree, 0, 4, ASPEC(hf_nvme_cqe_dword0_sf_pm));
+ break;
+ case F_LBA_RANGE_TYPE:
+ add_group_mask_entry(nvme_tvb, cqe_tree, 0, 4, ASPEC(hf_nvme_cqe_dword0_sf_lbart));
+ break;
+ case F_NUM_OF_QUEUES:
+ add_group_mask_entry(nvme_tvb, cqe_tree, 0, 4, ASPEC(hf_nvme_cqe_dword0_sf_nq));
+ break;
+ default:
+ proto_tree_add_item(cqe_tree, hf_nvme_cqe_dword0, nvme_tvb, 0, 4, ENC_LITTLE_ENDIAN);
+ }
+ }
+ break;
+ }
+ default:
+ proto_tree_add_item(cqe_tree, hf_nvme_cqe_dword0, nvme_tvb, 0, 4, ENC_LITTLE_ENDIAN);
+ break;
+ }
+}
+
+void dissect_nvme_cqe(tvbuff_t *nvme_tvb, packet_info *pinfo, proto_tree *root_tree, struct nvme_cmd_ctx *cmd_ctx)
{
proto_tree *cqe_tree;
proto_item *ti, *grp;
@@ -3206,14 +3250,14 @@ dissect_nvme_cqe(tvbuff_t *nvme_tvb, packet_info *pinfo, proto_tree *root_tree,
nvme_publish_to_cmd_link(cqe_tree, nvme_tvb, hf_nvme_cmd_pkt, cmd_ctx);
nvme_publish_cmd_latency(cqe_tree, cmd_ctx, hf_nvme_cmd_latency);
- proto_tree_add_item(cqe_tree, hf_nvme_cqe_dword0, nvme_tvb, 0, 4, ENC_LITTLE_ENDIAN);
+ val = tvb_get_guint16(nvme_tvb, 14, ENC_LITTLE_ENDIAN);
+ decode_dword0_cqe(nvme_tvb, cqe_tree, ((val & 0x1fe) >> 9), cmd_ctx);
proto_tree_add_item(cqe_tree, hf_nvme_cqe_dword1, nvme_tvb, 4, 4, ENC_LITTLE_ENDIAN);
proto_tree_add_item(cqe_tree, hf_nvme_cqe_sqhd, nvme_tvb, 8, 2, ENC_LITTLE_ENDIAN);
proto_tree_add_item(cqe_tree, hf_nvme_cqe_sqid, nvme_tvb, 10, 2, ENC_LITTLE_ENDIAN);
proto_tree_add_item(cqe_tree, hf_nvme_cqe_cid, nvme_tvb, 12, 2, ENC_LITTLE_ENDIAN);
- val = tvb_get_guint16(nvme_tvb, 14, ENC_LITTLE_ENDIAN);
- ti = proto_tree_add_item(root_tree, hf_nvme_cqe_status[0], nvme_tvb, 14, 2, ENC_LITTLE_ENDIAN);
+ ti = proto_tree_add_item(cqe_tree, hf_nvme_cqe_status[0], nvme_tvb, 14, 2, ENC_LITTLE_ENDIAN);
grp = proto_item_add_subtree(ti, ett_data);
for (i = 1; i < array_length(hf_nvme_cqe_status); i++) {
ti = proto_tree_add_item(grp, hf_nvme_cqe_status[i], nvme_tvb, 14, 2, ENC_LITTLE_ENDIAN);
@@ -3624,11 +3668,11 @@ proto_register_nvme(void)
},
{ &hf_nvme_cmd_set_features_dword11_nq[1],
{ "Number of IO Submission Queues Requested", "nvme.cmd.set_features.dword11.nq.nsqr",
- FT_UINT32, BASE_DEC, NULL, 0xffff, NULL, HFILL}
+ FT_UINT32, BASE_CUSTOM, CF_FUNC(add_nvme_queues), 0xffff, NULL, HFILL}
},
{ &hf_nvme_cmd_set_features_dword11_nq[2],
{ "Number of IO Completion Queues Requested", "nvme.cmd.set_features.dword11.nq.ncqr",
- FT_UINT32, BASE_DEC, NULL, 0xffff0000, NULL, HFILL}
+ FT_UINT32, BASE_CUSTOM, CF_FUNC(add_nvme_queues), 0xffff0000, NULL, HFILL}
},
{ &hf_nvme_cmd_set_features_dword11_irqc[0],
{ "DWORD11", "nvme.cmd.set_features.dword11.irqc",
@@ -6077,6 +6121,50 @@ proto_register_nvme(void)
{ "DWORD0", "nvme.cqe.dword0",
FT_UINT32, BASE_HEX, NULL, 0x0, NULL, HFILL}
},
+ { &hf_nvme_cqe_dword0_sf_err,
+ { "Set Features Error Specific Code", "nvme.cqe.dword0.set_features.err",
+ FT_UINT32, BASE_HEX, VALS(nvme_cqe_sc_sf_err_dword0_tbl), 0x0, NULL, HFILL}
+ },
+ { &hf_nvme_cqe_dword0_sf_pm[0],
+ { "DWORD0: Set Feature Power Management Result", "nvme.cqe.dword0.set_features.pm",
+ FT_UINT32, BASE_HEX, NULL, 0x0, NULL, HFILL}
+ },
+ { &hf_nvme_cqe_dword0_sf_pm[1],
+ { "Power Sate", "nvme.cqe.dword0.set_features.pm.ps",
+ FT_UINT32, BASE_HEX, NULL, 0x1f, NULL, HFILL}
+ },
+ { &hf_nvme_cqe_dword0_sf_pm[2],
+ { "Workload Hint", "nvme.cqe.dword0.set_features.pm.wh",
+ FT_UINT32, BASE_HEX, NULL, 0xe0, NULL, HFILL}
+ },
+ { &hf_nvme_cqe_dword0_sf_pm[3],
+ { "Reserved", "nvme.cqe.dword0.set_features.pm.rsvd",
+ FT_UINT32, BASE_HEX, NULL, 0xffffff00, NULL, HFILL}
+ },
+ { &hf_nvme_cqe_dword0_sf_lbart[0],
+ { "DWORD0: Set Feature LBA Range Type Result", "nvme.cqe.dword0.set_features.lbart",
+ FT_UINT32, BASE_HEX, NULL, 0x0, NULL, HFILL}
+ },
+ { &hf_nvme_cqe_dword0_sf_lbart[1],
+ { "Number of LBA Ranges", "nvme.cqe.dword0.set_features.lbart.num",
+ FT_UINT32, BASE_HEX, NULL, 0x3f, NULL, HFILL}
+ },
+ { &hf_nvme_cqe_dword0_sf_lbart[2],
+ { "Reserved", "nvme.cqe.dword0.set_features.lbart.rsvd",
+ FT_UINT32, BASE_HEX, NULL, 0xffffffc0, NULL, HFILL}
+ },
+ { &hf_nvme_cqe_dword0_sf_nq[0],
+ { "DWORD0: Set Feature Number of Queues Result", "nvme.cqe.dword0.set_features.nq",
+ FT_UINT32, BASE_HEX, NULL, 0x0, NULL, HFILL}
+ },
+ { &hf_nvme_cqe_dword0_sf_nq[1],
+ { "Number of IO Submission Queues Allocated", "nvme.cqe.dword0.set_features.nq.nsqa",
+ FT_UINT32, BASE_CUSTOM, CF_FUNC(add_nvme_queues), 0xffff, NULL, HFILL}
+ },
+ { &hf_nvme_cqe_dword0_sf_nq[2],
+ { "Number of IO Completion Queues Allocated", "nvme.cqe.dword0.set_features.ncqa",
+ FT_UINT32, BASE_CUSTOM, CF_FUNC(add_nvme_queues), 0xffff0000, NULL, HFILL}
+ },
{ &hf_nvme_cqe_dword1,
{ "DWORD1", "nvme.cqe.dword1",
FT_UINT32, BASE_HEX, NULL, 0x0, NULL, HFILL}