162306a36Sopenharmony_ci/* SPDX-License-Identifier: GPL-2.0+ */
262306a36Sopenharmony_ci/*
362306a36Sopenharmony_ci *  Copyright IBM Corp. 2001, 2006
462306a36Sopenharmony_ci *  Author(s): Robert Burroughs
562306a36Sopenharmony_ci *	       Eric Rossman (edrossma@us.ibm.com)
662306a36Sopenharmony_ci *
762306a36Sopenharmony_ci *  Hotplug & misc device support: Jochen Roehrig (roehrig@de.ibm.com)
862306a36Sopenharmony_ci *  Major cleanup & driver split: Martin Schwidefsky <schwidefsky@de.ibm.com>
962306a36Sopenharmony_ci */
1062306a36Sopenharmony_ci
1162306a36Sopenharmony_ci#ifndef _ZCRYPT_ERROR_H_
1262306a36Sopenharmony_ci#define _ZCRYPT_ERROR_H_
1362306a36Sopenharmony_ci
1462306a36Sopenharmony_ci#include <linux/atomic.h>
1562306a36Sopenharmony_ci#include "zcrypt_debug.h"
1662306a36Sopenharmony_ci#include "zcrypt_api.h"
1762306a36Sopenharmony_ci#include "zcrypt_msgtype6.h"
1862306a36Sopenharmony_ci
1962306a36Sopenharmony_ci/**
2062306a36Sopenharmony_ci * Reply Messages
2162306a36Sopenharmony_ci *
2262306a36Sopenharmony_ci * Error reply messages are of two types:
2362306a36Sopenharmony_ci *    82:  Error (see below)
2462306a36Sopenharmony_ci *    88:  Error (see below)
2562306a36Sopenharmony_ci * Both type 82 and type 88 have the same structure in the header.
2662306a36Sopenharmony_ci *
2762306a36Sopenharmony_ci * Request reply messages are of three known types:
2862306a36Sopenharmony_ci *    80:  Reply from a Type 50 Request (see CEX2A-RELATED STRUCTS)
2962306a36Sopenharmony_ci *    84:  Reply from a Type 4 Request (see PCICA-RELATED STRUCTS)
3062306a36Sopenharmony_ci *    86:  Reply from a Type 6 Request (see PCICC/PCIXCC/CEX2C-RELATED STRUCTS)
3162306a36Sopenharmony_ci *
3262306a36Sopenharmony_ci */
3362306a36Sopenharmony_cistruct error_hdr {
3462306a36Sopenharmony_ci	unsigned char reserved1;	/* 0x00			*/
3562306a36Sopenharmony_ci	unsigned char type;		/* 0x82 or 0x88		*/
3662306a36Sopenharmony_ci	unsigned char reserved2[2];	/* 0x0000		*/
3762306a36Sopenharmony_ci	unsigned char reply_code;	/* reply code		*/
3862306a36Sopenharmony_ci	unsigned char reserved3[3];	/* 0x000000		*/
3962306a36Sopenharmony_ci};
4062306a36Sopenharmony_ci
4162306a36Sopenharmony_ci#define TYPE82_RSP_CODE 0x82
4262306a36Sopenharmony_ci#define TYPE88_RSP_CODE 0x88
4362306a36Sopenharmony_ci
4462306a36Sopenharmony_ci#define REP82_ERROR_MACHINE_FAILURE	    0x10
4562306a36Sopenharmony_ci#define REP82_ERROR_PREEMPT_FAILURE	    0x12
4662306a36Sopenharmony_ci#define REP82_ERROR_CHECKPT_FAILURE	    0x14
4762306a36Sopenharmony_ci#define REP82_ERROR_MESSAGE_TYPE	    0x20
4862306a36Sopenharmony_ci#define REP82_ERROR_INVALID_COMM_CD	    0x21 /* Type 84	*/
4962306a36Sopenharmony_ci#define REP82_ERROR_INVALID_MSG_LEN	    0x23
5062306a36Sopenharmony_ci#define REP82_ERROR_RESERVD_FIELD	    0x24 /* was 0x50	*/
5162306a36Sopenharmony_ci#define REP82_ERROR_FORMAT_FIELD	    0x29
5262306a36Sopenharmony_ci#define REP82_ERROR_INVALID_COMMAND	    0x30
5362306a36Sopenharmony_ci#define REP82_ERROR_MALFORMED_MSG	    0x40
5462306a36Sopenharmony_ci#define REP82_ERROR_INVALID_SPECIAL_CMD	    0x41
5562306a36Sopenharmony_ci#define REP82_ERROR_RESERVED_FIELDO	    0x50 /* old value	*/
5662306a36Sopenharmony_ci#define REP82_ERROR_WORD_ALIGNMENT	    0x60
5762306a36Sopenharmony_ci#define REP82_ERROR_MESSAGE_LENGTH	    0x80
5862306a36Sopenharmony_ci#define REP82_ERROR_OPERAND_INVALID	    0x82
5962306a36Sopenharmony_ci#define REP82_ERROR_OPERAND_SIZE	    0x84
6062306a36Sopenharmony_ci#define REP82_ERROR_EVEN_MOD_IN_OPND	    0x85
6162306a36Sopenharmony_ci#define REP82_ERROR_RESERVED_FIELD	    0x88
6262306a36Sopenharmony_ci#define REP82_ERROR_INVALID_DOMAIN_PENDING  0x8A
6362306a36Sopenharmony_ci#define REP82_ERROR_FILTERED_BY_HYPERVISOR  0x8B
6462306a36Sopenharmony_ci#define REP82_ERROR_TRANSPORT_FAIL	    0x90
6562306a36Sopenharmony_ci#define REP82_ERROR_PACKET_TRUNCATED	    0xA0
6662306a36Sopenharmony_ci#define REP82_ERROR_ZERO_BUFFER_LEN	    0xB0
6762306a36Sopenharmony_ci
6862306a36Sopenharmony_ci#define REP88_ERROR_MODULE_FAILURE	    0x10
6962306a36Sopenharmony_ci#define REP88_ERROR_MESSAGE_TYPE	    0x20
7062306a36Sopenharmony_ci#define REP88_ERROR_MESSAGE_MALFORMD	    0x22
7162306a36Sopenharmony_ci#define REP88_ERROR_MESSAGE_LENGTH	    0x23
7262306a36Sopenharmony_ci#define REP88_ERROR_RESERVED_FIELD	    0x24
7362306a36Sopenharmony_ci#define REP88_ERROR_KEY_TYPE		    0x34
7462306a36Sopenharmony_ci#define REP88_ERROR_INVALID_KEY	    0x82 /* CEX2A	*/
7562306a36Sopenharmony_ci#define REP88_ERROR_OPERAND		    0x84 /* CEX2A	*/
7662306a36Sopenharmony_ci#define REP88_ERROR_OPERAND_EVEN_MOD	    0x85 /* CEX2A	*/
7762306a36Sopenharmony_ci
7862306a36Sopenharmony_cistatic inline int convert_error(struct zcrypt_queue *zq,
7962306a36Sopenharmony_ci				struct ap_message *reply)
8062306a36Sopenharmony_ci{
8162306a36Sopenharmony_ci	struct error_hdr *ehdr = reply->msg;
8262306a36Sopenharmony_ci	int card = AP_QID_CARD(zq->queue->qid);
8362306a36Sopenharmony_ci	int queue = AP_QID_QUEUE(zq->queue->qid);
8462306a36Sopenharmony_ci
8562306a36Sopenharmony_ci	switch (ehdr->reply_code) {
8662306a36Sopenharmony_ci	case REP82_ERROR_INVALID_MSG_LEN:	 /* 0x23 */
8762306a36Sopenharmony_ci	case REP82_ERROR_RESERVD_FIELD:		 /* 0x24 */
8862306a36Sopenharmony_ci	case REP82_ERROR_FORMAT_FIELD:		 /* 0x29 */
8962306a36Sopenharmony_ci	case REP82_ERROR_MALFORMED_MSG:		 /* 0x40 */
9062306a36Sopenharmony_ci	case REP82_ERROR_INVALID_SPECIAL_CMD:	 /* 0x41 */
9162306a36Sopenharmony_ci	case REP82_ERROR_MESSAGE_LENGTH:	 /* 0x80 */
9262306a36Sopenharmony_ci	case REP82_ERROR_OPERAND_INVALID:	 /* 0x82 */
9362306a36Sopenharmony_ci	case REP82_ERROR_OPERAND_SIZE:		 /* 0x84 */
9462306a36Sopenharmony_ci	case REP82_ERROR_EVEN_MOD_IN_OPND:	 /* 0x85 */
9562306a36Sopenharmony_ci	case REP82_ERROR_INVALID_DOMAIN_PENDING: /* 0x8A */
9662306a36Sopenharmony_ci	case REP82_ERROR_FILTERED_BY_HYPERVISOR: /* 0x8B */
9762306a36Sopenharmony_ci	case REP82_ERROR_PACKET_TRUNCATED:	 /* 0xA0 */
9862306a36Sopenharmony_ci	case REP88_ERROR_MESSAGE_MALFORMD:	 /* 0x22 */
9962306a36Sopenharmony_ci	case REP88_ERROR_KEY_TYPE:		 /* 0x34 */
10062306a36Sopenharmony_ci		/* RY indicates malformed request */
10162306a36Sopenharmony_ci		ZCRYPT_DBF_WARN("%s dev=%02x.%04x RY=0x%02x => rc=EINVAL\n",
10262306a36Sopenharmony_ci				__func__, card, queue, ehdr->reply_code);
10362306a36Sopenharmony_ci		return -EINVAL;
10462306a36Sopenharmony_ci	case REP82_ERROR_MACHINE_FAILURE:	 /* 0x10 */
10562306a36Sopenharmony_ci	case REP82_ERROR_MESSAGE_TYPE:		 /* 0x20 */
10662306a36Sopenharmony_ci	case REP82_ERROR_TRANSPORT_FAIL:	 /* 0x90 */
10762306a36Sopenharmony_ci		/*
10862306a36Sopenharmony_ci		 * Msg to wrong type or card/infrastructure failure.
10962306a36Sopenharmony_ci		 * Trigger rescan of the ap bus, trigger retry request.
11062306a36Sopenharmony_ci		 */
11162306a36Sopenharmony_ci		atomic_set(&zcrypt_rescan_req, 1);
11262306a36Sopenharmony_ci		/* For type 86 response show the apfs value (failure reason) */
11362306a36Sopenharmony_ci		if (ehdr->reply_code == REP82_ERROR_TRANSPORT_FAIL &&
11462306a36Sopenharmony_ci		    ehdr->type == TYPE86_RSP_CODE) {
11562306a36Sopenharmony_ci			struct {
11662306a36Sopenharmony_ci				struct type86_hdr hdr;
11762306a36Sopenharmony_ci				struct type86_fmt2_ext fmt2;
11862306a36Sopenharmony_ci			} __packed * head = reply->msg;
11962306a36Sopenharmony_ci			unsigned int apfs = *((u32 *)head->fmt2.apfs);
12062306a36Sopenharmony_ci
12162306a36Sopenharmony_ci			ZCRYPT_DBF_WARN(
12262306a36Sopenharmony_ci				"%s dev=%02x.%04x RY=0x%02x apfs=0x%x => bus rescan, rc=EAGAIN\n",
12362306a36Sopenharmony_ci				__func__, card, queue, ehdr->reply_code, apfs);
12462306a36Sopenharmony_ci		} else {
12562306a36Sopenharmony_ci			ZCRYPT_DBF_WARN("%s dev=%02x.%04x RY=0x%02x => bus rescan, rc=EAGAIN\n",
12662306a36Sopenharmony_ci					__func__, card, queue,
12762306a36Sopenharmony_ci					ehdr->reply_code);
12862306a36Sopenharmony_ci		}
12962306a36Sopenharmony_ci		return -EAGAIN;
13062306a36Sopenharmony_ci	default:
13162306a36Sopenharmony_ci		/* Assume request is valid and a retry will be worth it */
13262306a36Sopenharmony_ci		ZCRYPT_DBF_WARN("%s dev=%02x.%04x RY=0x%02x => rc=EAGAIN\n",
13362306a36Sopenharmony_ci				__func__, card, queue, ehdr->reply_code);
13462306a36Sopenharmony_ci		return -EAGAIN;
13562306a36Sopenharmony_ci	}
13662306a36Sopenharmony_ci}
13762306a36Sopenharmony_ci
13862306a36Sopenharmony_ci#endif /* _ZCRYPT_ERROR_H_ */
139