Path: blob/master/drivers/crypto/cavium/cpt/cptvf_mbox.c
26285 views
// SPDX-License-Identifier: GPL-2.0-only1/*2* Copyright (C) 2016 Cavium, Inc.3*/45#include "cptvf.h"67static void cptvf_send_msg_to_pf(struct cpt_vf *cptvf, struct cpt_mbox *mbx)8{9/* Writing mbox(1) causes interrupt */10cpt_write_csr64(cptvf->reg_base, CPTX_VFX_PF_MBOXX(0, 0, 0),11mbx->msg);12cpt_write_csr64(cptvf->reg_base, CPTX_VFX_PF_MBOXX(0, 0, 1),13mbx->data);14}1516/* Interrupt handler to handle mailbox messages from VFs */17void cptvf_handle_mbox_intr(struct cpt_vf *cptvf)18{19struct cpt_mbox mbx = {};2021/*22* MBOX[0] contains msg23* MBOX[1] contains data24*/25mbx.msg = cpt_read_csr64(cptvf->reg_base, CPTX_VFX_PF_MBOXX(0, 0, 0));26mbx.data = cpt_read_csr64(cptvf->reg_base, CPTX_VFX_PF_MBOXX(0, 0, 1));27dev_dbg(&cptvf->pdev->dev, "%s: Mailbox msg 0x%llx from PF\n",28__func__, mbx.msg);29switch (mbx.msg) {30case CPT_MSG_READY:31{32cptvf->pf_acked = true;33cptvf->vfid = mbx.data;34dev_dbg(&cptvf->pdev->dev, "Received VFID %d\n", cptvf->vfid);35break;36}37case CPT_MSG_QBIND_GRP:38cptvf->pf_acked = true;39cptvf->vftype = mbx.data;40dev_dbg(&cptvf->pdev->dev, "VF %d type %s group %d\n",41cptvf->vfid, ((mbx.data == SE_TYPES) ? "SE" : "AE"),42cptvf->vfgrp);43break;44case CPT_MBOX_MSG_TYPE_ACK:45cptvf->pf_acked = true;46break;47case CPT_MBOX_MSG_TYPE_NACK:48cptvf->pf_nacked = true;49break;50default:51dev_err(&cptvf->pdev->dev, "Invalid msg from PF, msg 0x%llx\n",52mbx.msg);53break;54}55}5657static int cptvf_send_msg_to_pf_timeout(struct cpt_vf *cptvf,58struct cpt_mbox *mbx)59{60int timeout = CPT_MBOX_MSG_TIMEOUT;61int sleep = 10;6263cptvf->pf_acked = false;64cptvf->pf_nacked = false;65cptvf_send_msg_to_pf(cptvf, mbx);66/* Wait for previous message to be acked, timeout 2sec */67while (!cptvf->pf_acked) {68if (cptvf->pf_nacked)69return -EINVAL;70msleep(sleep);71if (cptvf->pf_acked)72break;73timeout -= sleep;74if (!timeout) {75dev_err(&cptvf->pdev->dev, "PF didn't ack to mbox msg %llx from VF%u\n",76(mbx->msg & 0xFF), cptvf->vfid);77return -EBUSY;78}79}8081return 0;82}8384/*85* Checks if VF is able to comminicate with PF86* and also gets the CPT number this VF is associated to.87*/88int cptvf_check_pf_ready(struct cpt_vf *cptvf)89{90struct pci_dev *pdev = cptvf->pdev;91struct cpt_mbox mbx = {};9293mbx.msg = CPT_MSG_READY;94if (cptvf_send_msg_to_pf_timeout(cptvf, &mbx)) {95dev_err(&pdev->dev, "PF didn't respond to READY msg\n");96return -EBUSY;97}9899return 0;100}101102/*103* Communicate VQs size to PF to program CPT(0)_PF_Q(0-15)_CTL of the VF.104* Must be ACKed.105*/106int cptvf_send_vq_size_msg(struct cpt_vf *cptvf)107{108struct pci_dev *pdev = cptvf->pdev;109struct cpt_mbox mbx = {};110111mbx.msg = CPT_MSG_QLEN;112mbx.data = cptvf->qsize;113if (cptvf_send_msg_to_pf_timeout(cptvf, &mbx)) {114dev_err(&pdev->dev, "PF didn't respond to vq_size msg\n");115return -EBUSY;116}117118return 0;119}120121/*122* Communicate VF group required to PF and get the VQ binded to that group123*/124int cptvf_send_vf_to_grp_msg(struct cpt_vf *cptvf)125{126struct pci_dev *pdev = cptvf->pdev;127struct cpt_mbox mbx = {};128129mbx.msg = CPT_MSG_QBIND_GRP;130/* Convey group of the VF */131mbx.data = cptvf->vfgrp;132if (cptvf_send_msg_to_pf_timeout(cptvf, &mbx)) {133dev_err(&pdev->dev, "PF didn't respond to vf_type msg\n");134return -EBUSY;135}136137return 0;138}139140/*141* Communicate VF group required to PF and get the VQ binded to that group142*/143int cptvf_send_vf_priority_msg(struct cpt_vf *cptvf)144{145struct pci_dev *pdev = cptvf->pdev;146struct cpt_mbox mbx = {};147148mbx.msg = CPT_MSG_VQ_PRIORITY;149/* Convey group of the VF */150mbx.data = cptvf->priority;151if (cptvf_send_msg_to_pf_timeout(cptvf, &mbx)) {152dev_err(&pdev->dev, "PF didn't respond to vf_type msg\n");153return -EBUSY;154}155return 0;156}157158/*159* Communicate to PF that VF is UP and running160*/161int cptvf_send_vf_up(struct cpt_vf *cptvf)162{163struct pci_dev *pdev = cptvf->pdev;164struct cpt_mbox mbx = {};165166mbx.msg = CPT_MSG_VF_UP;167if (cptvf_send_msg_to_pf_timeout(cptvf, &mbx)) {168dev_err(&pdev->dev, "PF didn't respond to UP msg\n");169return -EBUSY;170}171172return 0;173}174175/*176* Communicate to PF that VF is DOWN and running177*/178int cptvf_send_vf_down(struct cpt_vf *cptvf)179{180struct pci_dev *pdev = cptvf->pdev;181struct cpt_mbox mbx = {};182183mbx.msg = CPT_MSG_VF_DOWN;184if (cptvf_send_msg_to_pf_timeout(cptvf, &mbx)) {185dev_err(&pdev->dev, "PF didn't respond to DOWN msg\n");186return -EBUSY;187}188189return 0;190}191192193