1*4882a593Smuzhiyun /*
2*4882a593Smuzhiyun * Copyright (C) 2017 NXP Semiconductors
3*4882a593Smuzhiyun * Copyright (C) 2017 Bin Meng <bmeng.cn@gmail.com>
4*4882a593Smuzhiyun *
5*4882a593Smuzhiyun * SPDX-License-Identifier: GPL-2.0+
6*4882a593Smuzhiyun */
7*4882a593Smuzhiyun
8*4882a593Smuzhiyun #include <common.h>
9*4882a593Smuzhiyun #include <dm.h>
10*4882a593Smuzhiyun #include <errno.h>
11*4882a593Smuzhiyun #include <memalign.h>
12*4882a593Smuzhiyun #include <nvme.h>
13*4882a593Smuzhiyun #include "nvme.h"
14*4882a593Smuzhiyun
print_optional_admin_cmd(u16 oacs,int devnum)15*4882a593Smuzhiyun static void print_optional_admin_cmd(u16 oacs, int devnum)
16*4882a593Smuzhiyun {
17*4882a593Smuzhiyun printf("Blk device %d: Optional Admin Command Support:\n",
18*4882a593Smuzhiyun devnum);
19*4882a593Smuzhiyun printf("\tNamespace Management/Attachment: %s\n",
20*4882a593Smuzhiyun oacs & 0x08 ? "yes" : "no");
21*4882a593Smuzhiyun printf("\tFirmware Commit/Image download: %s\n",
22*4882a593Smuzhiyun oacs & 0x04 ? "yes" : "no");
23*4882a593Smuzhiyun printf("\tFormat NVM: %s\n",
24*4882a593Smuzhiyun oacs & 0x02 ? "yes" : "no");
25*4882a593Smuzhiyun printf("\tSecurity Send/Receive: %s\n",
26*4882a593Smuzhiyun oacs & 0x01 ? "yes" : "no");
27*4882a593Smuzhiyun }
28*4882a593Smuzhiyun
print_optional_nvm_cmd(u16 oncs,int devnum)29*4882a593Smuzhiyun static void print_optional_nvm_cmd(u16 oncs, int devnum)
30*4882a593Smuzhiyun {
31*4882a593Smuzhiyun printf("Blk device %d: Optional NVM Command Support:\n",
32*4882a593Smuzhiyun devnum);
33*4882a593Smuzhiyun printf("\tReservation: %s\n",
34*4882a593Smuzhiyun oncs & 0x10 ? "yes" : "no");
35*4882a593Smuzhiyun printf("\tSave/Select field in the Set/Get features: %s\n",
36*4882a593Smuzhiyun oncs & 0x08 ? "yes" : "no");
37*4882a593Smuzhiyun printf("\tWrite Zeroes: %s\n",
38*4882a593Smuzhiyun oncs & 0x04 ? "yes" : "no");
39*4882a593Smuzhiyun printf("\tDataset Management: %s\n",
40*4882a593Smuzhiyun oncs & 0x02 ? "yes" : "no");
41*4882a593Smuzhiyun printf("\tWrite Uncorrectable: %s\n",
42*4882a593Smuzhiyun oncs & 0x01 ? "yes" : "no");
43*4882a593Smuzhiyun }
44*4882a593Smuzhiyun
print_format_nvme_attributes(u8 fna,int devnum)45*4882a593Smuzhiyun static void print_format_nvme_attributes(u8 fna, int devnum)
46*4882a593Smuzhiyun {
47*4882a593Smuzhiyun printf("Blk device %d: Format NVM Attributes:\n", devnum);
48*4882a593Smuzhiyun printf("\tSupport Cryptographic Erase: %s\n",
49*4882a593Smuzhiyun fna & 0x04 ? "yes" : "No");
50*4882a593Smuzhiyun printf("\tSupport erase a particular namespace: %s\n",
51*4882a593Smuzhiyun fna & 0x02 ? "No" : "Yes");
52*4882a593Smuzhiyun printf("\tSupport format a particular namespace: %s\n",
53*4882a593Smuzhiyun fna & 0x01 ? "No" : "Yes");
54*4882a593Smuzhiyun }
55*4882a593Smuzhiyun
print_format(struct nvme_lbaf * lbaf)56*4882a593Smuzhiyun static void print_format(struct nvme_lbaf *lbaf)
57*4882a593Smuzhiyun {
58*4882a593Smuzhiyun u8 str[][10] = {"Best", "Better", "Good", "Degraded"};
59*4882a593Smuzhiyun
60*4882a593Smuzhiyun printf("\t\tMetadata Size: %d\n", le16_to_cpu(lbaf->ms));
61*4882a593Smuzhiyun printf("\t\tLBA Data Size: %d\n", 1 << lbaf->ds);
62*4882a593Smuzhiyun printf("\t\tRelative Performance: %s\n", str[lbaf->rp & 0x03]);
63*4882a593Smuzhiyun }
64*4882a593Smuzhiyun
print_formats(struct nvme_id_ns * id,struct nvme_ns * ns)65*4882a593Smuzhiyun static void print_formats(struct nvme_id_ns *id, struct nvme_ns *ns)
66*4882a593Smuzhiyun {
67*4882a593Smuzhiyun int i;
68*4882a593Smuzhiyun
69*4882a593Smuzhiyun printf("Blk device %d: LBA Format Support:\n", ns->devnum);
70*4882a593Smuzhiyun
71*4882a593Smuzhiyun for (i = 0; i < id->nlbaf; i++) {
72*4882a593Smuzhiyun printf("\tLBA Foramt %d Support: ", i);
73*4882a593Smuzhiyun if (i == ns->flbas)
74*4882a593Smuzhiyun printf("(current)\n");
75*4882a593Smuzhiyun else
76*4882a593Smuzhiyun printf("\n");
77*4882a593Smuzhiyun print_format(id->lbaf + i);
78*4882a593Smuzhiyun }
79*4882a593Smuzhiyun }
80*4882a593Smuzhiyun
print_data_protect_cap(u8 dpc,int devnum)81*4882a593Smuzhiyun static void print_data_protect_cap(u8 dpc, int devnum)
82*4882a593Smuzhiyun {
83*4882a593Smuzhiyun printf("Blk device %d: End-to-End Data", devnum);
84*4882a593Smuzhiyun printf("Protect Capabilities:\n");
85*4882a593Smuzhiyun printf("\tAs last eight bytes: %s\n",
86*4882a593Smuzhiyun dpc & 0x10 ? "yes" : "No");
87*4882a593Smuzhiyun printf("\tAs first eight bytes: %s\n",
88*4882a593Smuzhiyun dpc & 0x08 ? "yes" : "No");
89*4882a593Smuzhiyun printf("\tSupport Type3: %s\n",
90*4882a593Smuzhiyun dpc & 0x04 ? "yes" : "No");
91*4882a593Smuzhiyun printf("\tSupport Type2: %s\n",
92*4882a593Smuzhiyun dpc & 0x02 ? "yes" : "No");
93*4882a593Smuzhiyun printf("\tSupport Type1: %s\n",
94*4882a593Smuzhiyun dpc & 0x01 ? "yes" : "No");
95*4882a593Smuzhiyun }
96*4882a593Smuzhiyun
print_metadata_cap(u8 mc,int devnum)97*4882a593Smuzhiyun static void print_metadata_cap(u8 mc, int devnum)
98*4882a593Smuzhiyun {
99*4882a593Smuzhiyun printf("Blk device %d: Metadata capabilities:\n", devnum);
100*4882a593Smuzhiyun printf("\tAs part of a separate buffer: %s\n",
101*4882a593Smuzhiyun mc & 0x02 ? "yes" : "No");
102*4882a593Smuzhiyun printf("\tAs part of an extended data LBA: %s\n",
103*4882a593Smuzhiyun mc & 0x01 ? "yes" : "No");
104*4882a593Smuzhiyun }
105*4882a593Smuzhiyun
nvme_print_info(struct udevice * udev)106*4882a593Smuzhiyun int nvme_print_info(struct udevice *udev)
107*4882a593Smuzhiyun {
108*4882a593Smuzhiyun struct nvme_ns *ns = dev_get_priv(udev);
109*4882a593Smuzhiyun struct nvme_dev *dev = ns->dev;
110*4882a593Smuzhiyun ALLOC_CACHE_ALIGN_BUFFER(char, buf_ns, sizeof(struct nvme_id_ns));
111*4882a593Smuzhiyun struct nvme_id_ns *id = (struct nvme_id_ns *)buf_ns;
112*4882a593Smuzhiyun ALLOC_CACHE_ALIGN_BUFFER(char, buf_ctrl, sizeof(struct nvme_id_ctrl));
113*4882a593Smuzhiyun struct nvme_id_ctrl *ctrl = (struct nvme_id_ctrl *)buf_ctrl;
114*4882a593Smuzhiyun
115*4882a593Smuzhiyun if (nvme_identify(dev, 0, 1, (dma_addr_t)(long)ctrl))
116*4882a593Smuzhiyun return -EIO;
117*4882a593Smuzhiyun
118*4882a593Smuzhiyun print_optional_admin_cmd(le16_to_cpu(ctrl->oacs), ns->devnum);
119*4882a593Smuzhiyun print_optional_nvm_cmd(le16_to_cpu(ctrl->oncs), ns->devnum);
120*4882a593Smuzhiyun print_format_nvme_attributes(ctrl->fna, ns->devnum);
121*4882a593Smuzhiyun
122*4882a593Smuzhiyun if (nvme_identify(dev, ns->ns_id, 0, (dma_addr_t)(long)id))
123*4882a593Smuzhiyun return -EIO;
124*4882a593Smuzhiyun
125*4882a593Smuzhiyun print_formats(id, ns);
126*4882a593Smuzhiyun print_data_protect_cap(id->dpc, ns->devnum);
127*4882a593Smuzhiyun print_metadata_cap(id->mc, ns->devnum);
128*4882a593Smuzhiyun
129*4882a593Smuzhiyun return 0;
130*4882a593Smuzhiyun }
131