Back to home page

OSCL-LXR

 
 

    


0001 /* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */
0002 /*
0003  * PAPR nvDimm Specific Methods (PDSM) and structs for libndctl
0004  *
0005  * (C) Copyright IBM 2020
0006  *
0007  * Author: Vaibhav Jain <vaibhav at linux.ibm.com>
0008  */
0009 
0010 #ifndef _UAPI_ASM_POWERPC_PAPR_PDSM_H_
0011 #define _UAPI_ASM_POWERPC_PAPR_PDSM_H_
0012 
0013 #include <linux/types.h>
0014 #include <linux/ndctl.h>
0015 
0016 /*
0017  * PDSM Envelope:
0018  *
0019  * The ioctl ND_CMD_CALL exchange data between user-space and kernel via
0020  * envelope which consists of 2 headers sections and payload sections as
0021  * illustrated below:
0022  *  +-----------------+---------------+---------------------------+
0023  *  |   64-Bytes      |   8-Bytes     |       Max 184-Bytes       |
0024  *  +-----------------+---------------+---------------------------+
0025  *  | ND-HEADER       |  PDSM-HEADER  |      PDSM-PAYLOAD         |
0026  *  +-----------------+---------------+---------------------------+
0027  *  | nd_family       |               |                           |
0028  *  | nd_size_out     | cmd_status    |                           |
0029  *  | nd_size_in      | reserved      |     nd_pdsm_payload       |
0030  *  | nd_command      | payload   --> |                           |
0031  *  | nd_fw_size      |               |                           |
0032  *  | nd_payload ---> |               |                           |
0033  *  +---------------+-----------------+---------------------------+
0034  *
0035  * ND Header:
0036  * This is the generic libnvdimm header described as 'struct nd_cmd_pkg'
0037  * which is interpreted by libnvdimm before passed on to papr_scm. Important
0038  * member fields used are:
0039  * 'nd_family'      : (In) NVDIMM_FAMILY_PAPR_SCM
0040  * 'nd_size_in'     : (In) PDSM-HEADER + PDSM-IN-PAYLOAD (usually 0)
0041  * 'nd_size_out'        : (In) PDSM-HEADER + PDSM-RETURN-PAYLOAD
0042  * 'nd_command'         : (In) One of PAPR_PDSM_XXX
0043  * 'nd_fw_size'         : (Out) PDSM-HEADER + size of actual payload returned
0044  *
0045  * PDSM Header:
0046  * This is papr-scm specific header that precedes the payload. This is defined
0047  * as nd_cmd_pdsm_pkg.  Following fields aare available in this header:
0048  *
0049  * 'cmd_status'     : (Out) Errors if any encountered while servicing PDSM.
0050  * 'reserved'       : Not used, reserved for future and should be set to 0.
0051  * 'payload'            : A union of all the possible payload structs
0052  *
0053  * PDSM Payload:
0054  *
0055  * The layout of the PDSM Payload is defined by various structs shared between
0056  * papr_scm and libndctl so that contents of payload can be interpreted. As such
0057  * its defined as a union of all possible payload structs as
0058  * 'union nd_pdsm_payload'. Based on the value of 'nd_cmd_pkg.nd_command'
0059  * appropriate member of the union is accessed.
0060  */
0061 
0062 /* Max payload size that we can handle */
0063 #define ND_PDSM_PAYLOAD_MAX_SIZE 184
0064 
0065 /* Max payload size that we can handle */
0066 #define ND_PDSM_HDR_SIZE \
0067     (sizeof(struct nd_pkg_pdsm) - ND_PDSM_PAYLOAD_MAX_SIZE)
0068 
0069 /* Various nvdimm health indicators */
0070 #define PAPR_PDSM_DIMM_HEALTHY       0
0071 #define PAPR_PDSM_DIMM_UNHEALTHY     1
0072 #define PAPR_PDSM_DIMM_CRITICAL      2
0073 #define PAPR_PDSM_DIMM_FATAL         3
0074 
0075 /* struct nd_papr_pdsm_health.extension_flags field flags */
0076 
0077 /* Indicate that the 'dimm_fuel_gauge' field is valid */
0078 #define PDSM_DIMM_HEALTH_RUN_GAUGE_VALID 1
0079 
0080 /* Indicate that the 'dimm_dsc' field is valid */
0081 #define PDSM_DIMM_DSC_VALID 2
0082 
0083 /*
0084  * Struct exchanged between kernel & ndctl in for PAPR_PDSM_HEALTH
0085  * Various flags indicate the health status of the dimm.
0086  *
0087  * extension_flags  : Any extension fields present in the struct.
0088  * dimm_unarmed     : Dimm not armed. So contents wont persist.
0089  * dimm_bad_shutdown    : Previous shutdown did not persist contents.
0090  * dimm_bad_restore : Contents from previous shutdown werent restored.
0091  * dimm_scrubbed    : Contents of the dimm have been scrubbed.
0092  * dimm_locked      : Contents of the dimm cant be modified until CEC reboot
0093  * dimm_encrypted   : Contents of dimm are encrypted.
0094  * dimm_health      : Dimm health indicator. One of PAPR_PDSM_DIMM_XXXX
0095  * dimm_fuel_gauge  : Life remaining of DIMM as a percentage from 0-100
0096  */
0097 struct nd_papr_pdsm_health {
0098     union {
0099         struct {
0100             __u32 extension_flags;
0101             __u8 dimm_unarmed;
0102             __u8 dimm_bad_shutdown;
0103             __u8 dimm_bad_restore;
0104             __u8 dimm_scrubbed;
0105             __u8 dimm_locked;
0106             __u8 dimm_encrypted;
0107             __u16 dimm_health;
0108 
0109             /* Extension flag PDSM_DIMM_HEALTH_RUN_GAUGE_VALID */
0110             __u16 dimm_fuel_gauge;
0111 
0112             /* Extension flag PDSM_DIMM_DSC_VALID */
0113             __u64 dimm_dsc;
0114         };
0115         __u8 buf[ND_PDSM_PAYLOAD_MAX_SIZE];
0116     };
0117 };
0118 
0119 /* Flags for injecting specific smart errors */
0120 #define PDSM_SMART_INJECT_HEALTH_FATAL      (1 << 0)
0121 #define PDSM_SMART_INJECT_BAD_SHUTDOWN      (1 << 1)
0122 
0123 struct nd_papr_pdsm_smart_inject {
0124     union {
0125         struct {
0126             /* One or more of PDSM_SMART_INJECT_ */
0127             __u32 flags;
0128             __u8 fatal_enable;
0129             __u8 unsafe_shutdown_enable;
0130         };
0131         __u8 buf[ND_PDSM_PAYLOAD_MAX_SIZE];
0132     };
0133 };
0134 
0135 /*
0136  * Methods to be embedded in ND_CMD_CALL request. These are sent to the kernel
0137  * via 'nd_cmd_pkg.nd_command' member of the ioctl struct
0138  */
0139 enum papr_pdsm {
0140     PAPR_PDSM_MIN = 0x0,
0141     PAPR_PDSM_HEALTH,
0142     PAPR_PDSM_SMART_INJECT,
0143     PAPR_PDSM_MAX,
0144 };
0145 
0146 /* Maximal union that can hold all possible payload types */
0147 union nd_pdsm_payload {
0148     struct nd_papr_pdsm_health health;
0149     struct nd_papr_pdsm_smart_inject smart_inject;
0150     __u8 buf[ND_PDSM_PAYLOAD_MAX_SIZE];
0151 } __packed;
0152 
0153 /*
0154  * PDSM-header + payload expected with ND_CMD_CALL ioctl from libnvdimm
0155  * Valid member of union 'payload' is identified via 'nd_cmd_pkg.nd_command'
0156  * that should always precede this struct when sent to papr_scm via CMD_CALL
0157  * interface.
0158  */
0159 struct nd_pkg_pdsm {
0160     __s32 cmd_status;   /* Out: Sub-cmd status returned back */
0161     __u16 reserved[2];  /* Ignored and to be set as '0' */
0162     union nd_pdsm_payload payload;
0163 } __packed;
0164 
0165 #endif /* _UAPI_ASM_POWERPC_PAPR_PDSM_H_ */