18c2ecf20Sopenharmony_ci/* SPDX-License-Identifier: GPL-2.0+ */
28c2ecf20Sopenharmony_ci/*
38c2ecf20Sopenharmony_ci *  Copyright IBM Corp. 2001, 2006
48c2ecf20Sopenharmony_ci *  Author(s): Robert Burroughs
58c2ecf20Sopenharmony_ci *	       Eric Rossman (edrossma@us.ibm.com)
68c2ecf20Sopenharmony_ci *
78c2ecf20Sopenharmony_ci *  Hotplug & misc device support: Jochen Roehrig (roehrig@de.ibm.com)
88c2ecf20Sopenharmony_ci *  Major cleanup & driver split: Martin Schwidefsky <schwidefsky@de.ibm.com>
98c2ecf20Sopenharmony_ci */
108c2ecf20Sopenharmony_ci
118c2ecf20Sopenharmony_ci#ifndef _ZCRYPT_ERROR_H_
128c2ecf20Sopenharmony_ci#define _ZCRYPT_ERROR_H_
138c2ecf20Sopenharmony_ci
148c2ecf20Sopenharmony_ci#include <linux/atomic.h>
158c2ecf20Sopenharmony_ci#include "zcrypt_debug.h"
168c2ecf20Sopenharmony_ci#include "zcrypt_api.h"
178c2ecf20Sopenharmony_ci#include "zcrypt_msgtype6.h"
188c2ecf20Sopenharmony_ci
198c2ecf20Sopenharmony_ci/**
208c2ecf20Sopenharmony_ci * Reply Messages
218c2ecf20Sopenharmony_ci *
228c2ecf20Sopenharmony_ci * Error reply messages are of two types:
238c2ecf20Sopenharmony_ci *    82:  Error (see below)
248c2ecf20Sopenharmony_ci *    88:  Error (see below)
258c2ecf20Sopenharmony_ci * Both type 82 and type 88 have the same structure in the header.
268c2ecf20Sopenharmony_ci *
278c2ecf20Sopenharmony_ci * Request reply messages are of three known types:
288c2ecf20Sopenharmony_ci *    80:  Reply from a Type 50 Request (see CEX2A-RELATED STRUCTS)
298c2ecf20Sopenharmony_ci *    84:  Reply from a Type 4 Request (see PCICA-RELATED STRUCTS)
308c2ecf20Sopenharmony_ci *    86:  Reply from a Type 6 Request (see PCICC/PCIXCC/CEX2C-RELATED STRUCTS)
318c2ecf20Sopenharmony_ci *
328c2ecf20Sopenharmony_ci */
338c2ecf20Sopenharmony_cistruct error_hdr {
348c2ecf20Sopenharmony_ci	unsigned char reserved1;	/* 0x00			*/
358c2ecf20Sopenharmony_ci	unsigned char type;		/* 0x82 or 0x88		*/
368c2ecf20Sopenharmony_ci	unsigned char reserved2[2];	/* 0x0000		*/
378c2ecf20Sopenharmony_ci	unsigned char reply_code;	/* reply code		*/
388c2ecf20Sopenharmony_ci	unsigned char reserved3[3];	/* 0x000000		*/
398c2ecf20Sopenharmony_ci};
408c2ecf20Sopenharmony_ci
418c2ecf20Sopenharmony_ci#define TYPE82_RSP_CODE 0x82
428c2ecf20Sopenharmony_ci#define TYPE88_RSP_CODE 0x88
438c2ecf20Sopenharmony_ci
448c2ecf20Sopenharmony_ci#define REP82_ERROR_MACHINE_FAILURE	    0x10
458c2ecf20Sopenharmony_ci#define REP82_ERROR_PREEMPT_FAILURE	    0x12
468c2ecf20Sopenharmony_ci#define REP82_ERROR_CHECKPT_FAILURE	    0x14
478c2ecf20Sopenharmony_ci#define REP82_ERROR_MESSAGE_TYPE	    0x20
488c2ecf20Sopenharmony_ci#define REP82_ERROR_INVALID_COMM_CD	    0x21 /* Type 84	*/
498c2ecf20Sopenharmony_ci#define REP82_ERROR_INVALID_MSG_LEN	    0x23
508c2ecf20Sopenharmony_ci#define REP82_ERROR_RESERVD_FIELD	    0x24 /* was 0x50	*/
518c2ecf20Sopenharmony_ci#define REP82_ERROR_FORMAT_FIELD	    0x29
528c2ecf20Sopenharmony_ci#define REP82_ERROR_INVALID_COMMAND	    0x30
538c2ecf20Sopenharmony_ci#define REP82_ERROR_MALFORMED_MSG	    0x40
548c2ecf20Sopenharmony_ci#define REP82_ERROR_INVALID_SPECIAL_CMD	    0x41
558c2ecf20Sopenharmony_ci#define REP82_ERROR_RESERVED_FIELDO	    0x50 /* old value	*/
568c2ecf20Sopenharmony_ci#define REP82_ERROR_WORD_ALIGNMENT	    0x60
578c2ecf20Sopenharmony_ci#define REP82_ERROR_MESSAGE_LENGTH	    0x80
588c2ecf20Sopenharmony_ci#define REP82_ERROR_OPERAND_INVALID	    0x82
598c2ecf20Sopenharmony_ci#define REP82_ERROR_OPERAND_SIZE	    0x84
608c2ecf20Sopenharmony_ci#define REP82_ERROR_EVEN_MOD_IN_OPND	    0x85
618c2ecf20Sopenharmony_ci#define REP82_ERROR_RESERVED_FIELD	    0x88
628c2ecf20Sopenharmony_ci#define REP82_ERROR_INVALID_DOMAIN_PENDING  0x8A
638c2ecf20Sopenharmony_ci#define REP82_ERROR_FILTERED_BY_HYPERVISOR  0x8B
648c2ecf20Sopenharmony_ci#define REP82_ERROR_TRANSPORT_FAIL	    0x90
658c2ecf20Sopenharmony_ci#define REP82_ERROR_PACKET_TRUNCATED	    0xA0
668c2ecf20Sopenharmony_ci#define REP82_ERROR_ZERO_BUFFER_LEN	    0xB0
678c2ecf20Sopenharmony_ci
688c2ecf20Sopenharmony_ci#define REP88_ERROR_MODULE_FAILURE	    0x10
698c2ecf20Sopenharmony_ci#define REP88_ERROR_MESSAGE_TYPE	    0x20
708c2ecf20Sopenharmony_ci#define REP88_ERROR_MESSAGE_MALFORMD	    0x22
718c2ecf20Sopenharmony_ci#define REP88_ERROR_MESSAGE_LENGTH	    0x23
728c2ecf20Sopenharmony_ci#define REP88_ERROR_RESERVED_FIELD	    0x24
738c2ecf20Sopenharmony_ci#define REP88_ERROR_KEY_TYPE		    0x34
748c2ecf20Sopenharmony_ci#define REP88_ERROR_INVALID_KEY	    0x82 /* CEX2A	*/
758c2ecf20Sopenharmony_ci#define REP88_ERROR_OPERAND		    0x84 /* CEX2A	*/
768c2ecf20Sopenharmony_ci#define REP88_ERROR_OPERAND_EVEN_MOD	    0x85 /* CEX2A	*/
778c2ecf20Sopenharmony_ci
788c2ecf20Sopenharmony_cistatic inline int convert_error(struct zcrypt_queue *zq,
798c2ecf20Sopenharmony_ci				struct ap_message *reply)
808c2ecf20Sopenharmony_ci{
818c2ecf20Sopenharmony_ci	struct error_hdr *ehdr = reply->msg;
828c2ecf20Sopenharmony_ci	int card = AP_QID_CARD(zq->queue->qid);
838c2ecf20Sopenharmony_ci	int queue = AP_QID_QUEUE(zq->queue->qid);
848c2ecf20Sopenharmony_ci
858c2ecf20Sopenharmony_ci	switch (ehdr->reply_code) {
868c2ecf20Sopenharmony_ci	case REP82_ERROR_INVALID_MSG_LEN:	 /* 0x23 */
878c2ecf20Sopenharmony_ci	case REP82_ERROR_RESERVD_FIELD:		 /* 0x24 */
888c2ecf20Sopenharmony_ci	case REP82_ERROR_FORMAT_FIELD:		 /* 0x29 */
898c2ecf20Sopenharmony_ci	case REP82_ERROR_MALFORMED_MSG:		 /* 0x40 */
908c2ecf20Sopenharmony_ci	case REP82_ERROR_INVALID_SPECIAL_CMD:	 /* 0x41 */
918c2ecf20Sopenharmony_ci	case REP82_ERROR_MESSAGE_LENGTH:	 /* 0x80 */
928c2ecf20Sopenharmony_ci	case REP82_ERROR_OPERAND_INVALID:	 /* 0x82 */
938c2ecf20Sopenharmony_ci	case REP82_ERROR_OPERAND_SIZE:		 /* 0x84 */
948c2ecf20Sopenharmony_ci	case REP82_ERROR_EVEN_MOD_IN_OPND:	 /* 0x85 */
958c2ecf20Sopenharmony_ci	case REP82_ERROR_INVALID_DOMAIN_PENDING: /* 0x8A */
968c2ecf20Sopenharmony_ci	case REP82_ERROR_FILTERED_BY_HYPERVISOR: /* 0x8B */
978c2ecf20Sopenharmony_ci	case REP82_ERROR_PACKET_TRUNCATED:	 /* 0xA0 */
988c2ecf20Sopenharmony_ci	case REP88_ERROR_MESSAGE_MALFORMD:	 /* 0x22 */
998c2ecf20Sopenharmony_ci	case REP88_ERROR_KEY_TYPE:		 /* 0x34 */
1008c2ecf20Sopenharmony_ci		/* RY indicates malformed request */
1018c2ecf20Sopenharmony_ci		ZCRYPT_DBF(DBF_WARN,
1028c2ecf20Sopenharmony_ci			   "dev=%02x.%04x RY=0x%02x => rc=EINVAL\n",
1038c2ecf20Sopenharmony_ci			   card, queue, ehdr->reply_code);
1048c2ecf20Sopenharmony_ci		return -EINVAL;
1058c2ecf20Sopenharmony_ci	case REP82_ERROR_MACHINE_FAILURE:	 /* 0x10 */
1068c2ecf20Sopenharmony_ci	case REP82_ERROR_MESSAGE_TYPE:		 /* 0x20 */
1078c2ecf20Sopenharmony_ci	case REP82_ERROR_TRANSPORT_FAIL:	 /* 0x90 */
1088c2ecf20Sopenharmony_ci		/*
1098c2ecf20Sopenharmony_ci		 * Msg to wrong type or card/infrastructure failure.
1108c2ecf20Sopenharmony_ci		 * Trigger rescan of the ap bus, trigger retry request.
1118c2ecf20Sopenharmony_ci		 */
1128c2ecf20Sopenharmony_ci		atomic_set(&zcrypt_rescan_req, 1);
1138c2ecf20Sopenharmony_ci		/* For type 86 response show the apfs value (failure reason) */
1148c2ecf20Sopenharmony_ci		if (ehdr->reply_code == REP82_ERROR_TRANSPORT_FAIL &&
1158c2ecf20Sopenharmony_ci		    ehdr->type == TYPE86_RSP_CODE) {
1168c2ecf20Sopenharmony_ci			struct {
1178c2ecf20Sopenharmony_ci				struct type86_hdr hdr;
1188c2ecf20Sopenharmony_ci				struct type86_fmt2_ext fmt2;
1198c2ecf20Sopenharmony_ci			} __packed * head = reply->msg;
1208c2ecf20Sopenharmony_ci			unsigned int apfs = *((u32 *)head->fmt2.apfs);
1218c2ecf20Sopenharmony_ci
1228c2ecf20Sopenharmony_ci			ZCRYPT_DBF(DBF_WARN,
1238c2ecf20Sopenharmony_ci				   "dev=%02x.%04x RY=0x%02x apfs=0x%x => bus rescan, rc=EAGAIN\n",
1248c2ecf20Sopenharmony_ci				   card, queue, ehdr->reply_code, apfs);
1258c2ecf20Sopenharmony_ci		} else
1268c2ecf20Sopenharmony_ci			ZCRYPT_DBF(DBF_WARN,
1278c2ecf20Sopenharmony_ci				   "dev=%02x.%04x RY=0x%02x => bus rescan, rc=EAGAIN\n",
1288c2ecf20Sopenharmony_ci				   card, queue, ehdr->reply_code);
1298c2ecf20Sopenharmony_ci		return -EAGAIN;
1308c2ecf20Sopenharmony_ci	default:
1318c2ecf20Sopenharmony_ci		/* Assume request is valid and a retry will be worth it */
1328c2ecf20Sopenharmony_ci		ZCRYPT_DBF(DBF_WARN,
1338c2ecf20Sopenharmony_ci			   "dev=%02x.%04x RY=0x%02x => rc=EAGAIN\n",
1348c2ecf20Sopenharmony_ci			   card, queue, ehdr->reply_code);
1358c2ecf20Sopenharmony_ci		return -EAGAIN;
1368c2ecf20Sopenharmony_ci	}
1378c2ecf20Sopenharmony_ci}
1388c2ecf20Sopenharmony_ci
1398c2ecf20Sopenharmony_ci#endif /* _ZCRYPT_ERROR_H_ */
140