Path: blob/master/drivers/crypto/cavium/cpt/cptpf_mbox.c
26285 views
// SPDX-License-Identifier: GPL-2.0-only1/*2* Copyright (C) 2016 Cavium, Inc.3*/4#include <linux/module.h>5#include "cptpf.h"67static void cpt_send_msg_to_vf(struct cpt_device *cpt, int vf,8struct cpt_mbox *mbx)9{10/* Writing mbox(0) causes interrupt */11cpt_write_csr64(cpt->reg_base, CPTX_PF_VFX_MBOXX(0, vf, 1),12mbx->data);13cpt_write_csr64(cpt->reg_base, CPTX_PF_VFX_MBOXX(0, vf, 0), mbx->msg);14}1516/* ACKs VF's mailbox message17* @vf: VF to which ACK to be sent18*/19static void cpt_mbox_send_ack(struct cpt_device *cpt, int vf,20struct cpt_mbox *mbx)21{22mbx->data = 0ull;23mbx->msg = CPT_MBOX_MSG_TYPE_ACK;24cpt_send_msg_to_vf(cpt, vf, mbx);25}2627static void cpt_clear_mbox_intr(struct cpt_device *cpt, u32 vf)28{29/* W1C for the VF */30cpt_write_csr64(cpt->reg_base, CPTX_PF_MBOX_INTX(0, 0), (1 << vf));31}3233/*34* Configure QLEN/Chunk sizes for VF35*/36static void cpt_cfg_qlen_for_vf(struct cpt_device *cpt, int vf, u32 size)37{38union cptx_pf_qx_ctl pf_qx_ctl;3940pf_qx_ctl.u = cpt_read_csr64(cpt->reg_base, CPTX_PF_QX_CTL(0, vf));41pf_qx_ctl.s.size = size;42pf_qx_ctl.s.cont_err = true;43cpt_write_csr64(cpt->reg_base, CPTX_PF_QX_CTL(0, vf), pf_qx_ctl.u);44}4546/*47* Configure VQ priority48*/49static void cpt_cfg_vq_priority(struct cpt_device *cpt, int vf, u32 pri)50{51union cptx_pf_qx_ctl pf_qx_ctl;5253pf_qx_ctl.u = cpt_read_csr64(cpt->reg_base, CPTX_PF_QX_CTL(0, vf));54pf_qx_ctl.s.pri = pri;55cpt_write_csr64(cpt->reg_base, CPTX_PF_QX_CTL(0, vf), pf_qx_ctl.u);56}5758static int cpt_bind_vq_to_grp(struct cpt_device *cpt, u8 q, u8 grp)59{60struct microcode *mcode = cpt->mcode;61union cptx_pf_qx_ctl pf_qx_ctl;62struct device *dev = &cpt->pdev->dev;6364if (q >= CPT_MAX_VF_NUM) {65dev_err(dev, "Queues are more than cores in the group");66return -EINVAL;67}68if (grp >= CPT_MAX_CORE_GROUPS) {69dev_err(dev, "Request group is more than possible groups");70return -EINVAL;71}72if (grp >= cpt->next_mc_idx) {73dev_err(dev, "Request group is higher than available functional groups");74return -EINVAL;75}76pf_qx_ctl.u = cpt_read_csr64(cpt->reg_base, CPTX_PF_QX_CTL(0, q));77pf_qx_ctl.s.grp = mcode[grp].group;78cpt_write_csr64(cpt->reg_base, CPTX_PF_QX_CTL(0, q), pf_qx_ctl.u);79dev_dbg(dev, "VF %d TYPE %s", q, (mcode[grp].is_ae ? "AE" : "SE"));8081return mcode[grp].is_ae ? AE_TYPES : SE_TYPES;82}8384/* Interrupt handler to handle mailbox messages from VFs */85static void cpt_handle_mbox_intr(struct cpt_device *cpt, int vf)86{87struct cpt_vf_info *vfx = &cpt->vfinfo[vf];88struct cpt_mbox mbx = {};89int vftype;90struct device *dev = &cpt->pdev->dev;91/*92* MBOX[0] contains msg93* MBOX[1] contains data94*/95mbx.msg = cpt_read_csr64(cpt->reg_base, CPTX_PF_VFX_MBOXX(0, vf, 0));96mbx.data = cpt_read_csr64(cpt->reg_base, CPTX_PF_VFX_MBOXX(0, vf, 1));97dev_dbg(dev, "%s: Mailbox msg 0x%llx from VF%d", __func__, mbx.msg, vf);98switch (mbx.msg) {99case CPT_MSG_VF_UP:100vfx->state = VF_STATE_UP;101try_module_get(THIS_MODULE);102cpt_mbox_send_ack(cpt, vf, &mbx);103break;104case CPT_MSG_READY:105mbx.msg = CPT_MSG_READY;106mbx.data = vf;107cpt_send_msg_to_vf(cpt, vf, &mbx);108break;109case CPT_MSG_VF_DOWN:110/* First msg in VF teardown sequence */111vfx->state = VF_STATE_DOWN;112module_put(THIS_MODULE);113cpt_mbox_send_ack(cpt, vf, &mbx);114break;115case CPT_MSG_QLEN:116vfx->qlen = mbx.data;117cpt_cfg_qlen_for_vf(cpt, vf, vfx->qlen);118cpt_mbox_send_ack(cpt, vf, &mbx);119break;120case CPT_MSG_QBIND_GRP:121vftype = cpt_bind_vq_to_grp(cpt, vf, (u8)mbx.data);122if ((vftype != AE_TYPES) && (vftype != SE_TYPES))123dev_err(dev, "Queue %d binding to group %llu failed",124vf, mbx.data);125else {126dev_dbg(dev, "Queue %d binding to group %llu successful",127vf, mbx.data);128mbx.msg = CPT_MSG_QBIND_GRP;129mbx.data = vftype;130cpt_send_msg_to_vf(cpt, vf, &mbx);131}132break;133case CPT_MSG_VQ_PRIORITY:134vfx->priority = mbx.data;135cpt_cfg_vq_priority(cpt, vf, vfx->priority);136cpt_mbox_send_ack(cpt, vf, &mbx);137break;138default:139dev_err(&cpt->pdev->dev, "Invalid msg from VF%d, msg 0x%llx\n",140vf, mbx.msg);141break;142}143}144145void cpt_mbox_intr_handler (struct cpt_device *cpt, int mbx)146{147u64 intr;148u8 vf;149150intr = cpt_read_csr64(cpt->reg_base, CPTX_PF_MBOX_INTX(0, 0));151dev_dbg(&cpt->pdev->dev, "PF interrupt Mbox%d 0x%llx\n", mbx, intr);152for (vf = 0; vf < CPT_MAX_VF_NUM; vf++) {153if (intr & (1ULL << vf)) {154dev_dbg(&cpt->pdev->dev, "Intr from VF %d\n", vf);155cpt_handle_mbox_intr(cpt, vf);156cpt_clear_mbox_intr(cpt, vf);157}158}159}160161162