root/drivers/crypto/cavium/cpt/cptvf_mbox.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. cptvf_send_msg_to_pf
  2. cptvf_handle_mbox_intr
  3. cptvf_send_msg_to_pf_timeout
  4. cptvf_check_pf_ready
  5. cptvf_send_vq_size_msg
  6. cptvf_send_vf_to_grp_msg
  7. cptvf_send_vf_priority_msg
  8. cptvf_send_vf_up
  9. cptvf_send_vf_down

   1 // SPDX-License-Identifier: GPL-2.0-only
   2 /*
   3  * Copyright (C) 2016 Cavium, Inc.
   4  */
   5 
   6 #include "cptvf.h"
   7 
   8 static void cptvf_send_msg_to_pf(struct cpt_vf *cptvf, struct cpt_mbox *mbx)
   9 {
  10         /* Writing mbox(1) causes interrupt */
  11         cpt_write_csr64(cptvf->reg_base, CPTX_VFX_PF_MBOXX(0, 0, 0),
  12                         mbx->msg);
  13         cpt_write_csr64(cptvf->reg_base, CPTX_VFX_PF_MBOXX(0, 0, 1),
  14                         mbx->data);
  15 }
  16 
  17 /* Interrupt handler to handle mailbox messages from VFs */
  18 void cptvf_handle_mbox_intr(struct cpt_vf *cptvf)
  19 {
  20         struct cpt_mbox mbx = {};
  21 
  22         /*
  23          * MBOX[0] contains msg
  24          * MBOX[1] contains data
  25          */
  26         mbx.msg  = cpt_read_csr64(cptvf->reg_base, CPTX_VFX_PF_MBOXX(0, 0, 0));
  27         mbx.data = cpt_read_csr64(cptvf->reg_base, CPTX_VFX_PF_MBOXX(0, 0, 1));
  28         dev_dbg(&cptvf->pdev->dev, "%s: Mailbox msg 0x%llx from PF\n",
  29                 __func__, mbx.msg);
  30         switch (mbx.msg) {
  31         case CPT_MSG_READY:
  32         {
  33                 cptvf->pf_acked = true;
  34                 cptvf->vfid = mbx.data;
  35                 dev_dbg(&cptvf->pdev->dev, "Received VFID %d\n", cptvf->vfid);
  36                 break;
  37         }
  38         case CPT_MSG_QBIND_GRP:
  39                 cptvf->pf_acked = true;
  40                 cptvf->vftype = mbx.data;
  41                 dev_dbg(&cptvf->pdev->dev, "VF %d type %s group %d\n",
  42                         cptvf->vfid, ((mbx.data == SE_TYPES) ? "SE" : "AE"),
  43                         cptvf->vfgrp);
  44                 break;
  45         case CPT_MBOX_MSG_TYPE_ACK:
  46                 cptvf->pf_acked = true;
  47                 break;
  48         case CPT_MBOX_MSG_TYPE_NACK:
  49                 cptvf->pf_nacked = true;
  50                 break;
  51         default:
  52                 dev_err(&cptvf->pdev->dev, "Invalid msg from PF, msg 0x%llx\n",
  53                         mbx.msg);
  54                 break;
  55         }
  56 }
  57 
  58 static int cptvf_send_msg_to_pf_timeout(struct cpt_vf *cptvf,
  59                                         struct cpt_mbox *mbx)
  60 {
  61         int timeout = CPT_MBOX_MSG_TIMEOUT;
  62         int sleep = 10;
  63 
  64         cptvf->pf_acked = false;
  65         cptvf->pf_nacked = false;
  66         cptvf_send_msg_to_pf(cptvf, mbx);
  67         /* Wait for previous message to be acked, timeout 2sec */
  68         while (!cptvf->pf_acked) {
  69                 if (cptvf->pf_nacked)
  70                         return -EINVAL;
  71                 msleep(sleep);
  72                 if (cptvf->pf_acked)
  73                         break;
  74                 timeout -= sleep;
  75                 if (!timeout) {
  76                         dev_err(&cptvf->pdev->dev, "PF didn't ack to mbox msg %llx from VF%u\n",
  77                                 (mbx->msg & 0xFF), cptvf->vfid);
  78                         return -EBUSY;
  79                 }
  80         }
  81 
  82         return 0;
  83 }
  84 
  85 /*
  86  * Checks if VF is able to comminicate with PF
  87  * and also gets the CPT number this VF is associated to.
  88  */
  89 int cptvf_check_pf_ready(struct cpt_vf *cptvf)
  90 {
  91         struct pci_dev *pdev = cptvf->pdev;
  92         struct cpt_mbox mbx = {};
  93 
  94         mbx.msg = CPT_MSG_READY;
  95         if (cptvf_send_msg_to_pf_timeout(cptvf, &mbx)) {
  96                 dev_err(&pdev->dev, "PF didn't respond to READY msg\n");
  97                 return -EBUSY;
  98         }
  99 
 100         return 0;
 101 }
 102 
 103 /*
 104  * Communicate VQs size to PF to program CPT(0)_PF_Q(0-15)_CTL of the VF.
 105  * Must be ACKed.
 106  */
 107 int cptvf_send_vq_size_msg(struct cpt_vf *cptvf)
 108 {
 109         struct pci_dev *pdev = cptvf->pdev;
 110         struct cpt_mbox mbx = {};
 111 
 112         mbx.msg = CPT_MSG_QLEN;
 113         mbx.data = cptvf->qsize;
 114         if (cptvf_send_msg_to_pf_timeout(cptvf, &mbx)) {
 115                 dev_err(&pdev->dev, "PF didn't respond to vq_size msg\n");
 116                 return -EBUSY;
 117         }
 118 
 119         return 0;
 120 }
 121 
 122 /*
 123  * Communicate VF group required to PF and get the VQ binded to that group
 124  */
 125 int cptvf_send_vf_to_grp_msg(struct cpt_vf *cptvf)
 126 {
 127         struct pci_dev *pdev = cptvf->pdev;
 128         struct cpt_mbox mbx = {};
 129 
 130         mbx.msg = CPT_MSG_QBIND_GRP;
 131         /* Convey group of the VF */
 132         mbx.data = cptvf->vfgrp;
 133         if (cptvf_send_msg_to_pf_timeout(cptvf, &mbx)) {
 134                 dev_err(&pdev->dev, "PF didn't respond to vf_type msg\n");
 135                 return -EBUSY;
 136         }
 137 
 138         return 0;
 139 }
 140 
 141 /*
 142  * Communicate VF group required to PF and get the VQ binded to that group
 143  */
 144 int cptvf_send_vf_priority_msg(struct cpt_vf *cptvf)
 145 {
 146         struct pci_dev *pdev = cptvf->pdev;
 147         struct cpt_mbox mbx = {};
 148 
 149         mbx.msg = CPT_MSG_VQ_PRIORITY;
 150         /* Convey group of the VF */
 151         mbx.data = cptvf->priority;
 152         if (cptvf_send_msg_to_pf_timeout(cptvf, &mbx)) {
 153                 dev_err(&pdev->dev, "PF didn't respond to vf_type msg\n");
 154                 return -EBUSY;
 155         }
 156         return 0;
 157 }
 158 
 159 /*
 160  * Communicate to PF that VF is UP and running
 161  */
 162 int cptvf_send_vf_up(struct cpt_vf *cptvf)
 163 {
 164         struct pci_dev *pdev = cptvf->pdev;
 165         struct cpt_mbox mbx = {};
 166 
 167         mbx.msg = CPT_MSG_VF_UP;
 168         if (cptvf_send_msg_to_pf_timeout(cptvf, &mbx)) {
 169                 dev_err(&pdev->dev, "PF didn't respond to UP msg\n");
 170                 return -EBUSY;
 171         }
 172 
 173         return 0;
 174 }
 175 
 176 /*
 177  * Communicate to PF that VF is DOWN and running
 178  */
 179 int cptvf_send_vf_down(struct cpt_vf *cptvf)
 180 {
 181         struct pci_dev *pdev = cptvf->pdev;
 182         struct cpt_mbox mbx = {};
 183 
 184         mbx.msg = CPT_MSG_VF_DOWN;
 185         if (cptvf_send_msg_to_pf_timeout(cptvf, &mbx)) {
 186                 dev_err(&pdev->dev, "PF didn't respond to DOWN msg\n");
 187                 return -EBUSY;
 188         }
 189 
 190         return 0;
 191 }

/* [<][>][^][v][top][bottom][index][help] */