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