[PATCH linux dev-4.13] fsi: occ: Add check for OCC response checksum

Eddie James eajames at linux.vnet.ibm.com
Tue May 1 07:05:21 AEST 2018


The OCC specification indicates that it is an error scenario if the
response checksum doesn't match the sum of the bytes of the response.
The driver needs to perform this calculation and check, and return an
error if it's a mismatch.

Signed-off-by: Eddie James <eajames at linux.vnet.ibm.com>
---
 drivers/fsi/fsi-occ.c | 23 +++++++++++++++++++++++
 1 file changed, 23 insertions(+)

diff --git a/drivers/fsi/fsi-occ.c b/drivers/fsi/fsi-occ.c
index 45ae13c..16f18df 100644
--- a/drivers/fsi/fsi-occ.c
+++ b/drivers/fsi/fsi-occ.c
@@ -427,6 +427,27 @@ static int occ_release(struct inode *inode, struct file *file)
 	.release = occ_release,
 };
 
+static int occ_check_sum(struct occ_response *resp, u16 data_length)
+{
+	unsigned int i;
+	u16 checksum = 0;
+	u16 checksum_resp = get_unaligned_be16(&resp->data[data_length]);
+
+	checksum += resp->seq_no;
+	checksum += resp->cmd_type;
+	checksum += resp->return_status;
+	checksum += (data_length >> 8) + (data_length & 0xFF);
+
+	for (i = 0; i < data_length; ++i) {
+		checksum += resp->data[i];
+	}
+
+	if (checksum != checksum_resp)
+		return -EBADMSG;
+
+	return 0;
+}
+
 static int occ_write_sbefifo(struct sbefifo_client *client, const char *buf,
 			     ssize_t len)
 {
@@ -692,6 +713,8 @@ static void occ_worker(struct work_struct *work)
 
 	xfr->resp_data_length = resp_data_length + 7;
 
+	rc = occ_check_sum(resp, resp_data_length);
+
 done:
 	mutex_unlock(&occ->occ_lock);
 
-- 
1.8.3.1



More information about the openbmc mailing list