0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011 #include <linux/delay.h>
0012 #include "otx_cptvf.h"
0013
0014 #define CPT_MBOX_MSG_TIMEOUT 2000
0015
0016 static char *get_mbox_opcode_str(int msg_opcode)
0017 {
0018 char *str = "Unknown";
0019
0020 switch (msg_opcode) {
0021 case OTX_CPT_MSG_VF_UP:
0022 str = "UP";
0023 break;
0024
0025 case OTX_CPT_MSG_VF_DOWN:
0026 str = "DOWN";
0027 break;
0028
0029 case OTX_CPT_MSG_READY:
0030 str = "READY";
0031 break;
0032
0033 case OTX_CPT_MSG_QLEN:
0034 str = "QLEN";
0035 break;
0036
0037 case OTX_CPT_MSG_QBIND_GRP:
0038 str = "QBIND_GRP";
0039 break;
0040
0041 case OTX_CPT_MSG_VQ_PRIORITY:
0042 str = "VQ_PRIORITY";
0043 break;
0044
0045 case OTX_CPT_MSG_PF_TYPE:
0046 str = "PF_TYPE";
0047 break;
0048
0049 case OTX_CPT_MSG_ACK:
0050 str = "ACK";
0051 break;
0052
0053 case OTX_CPT_MSG_NACK:
0054 str = "NACK";
0055 break;
0056 }
0057 return str;
0058 }
0059
0060 static void dump_mbox_msg(struct otx_cpt_mbox *mbox_msg, int vf_id)
0061 {
0062 char raw_data_str[OTX_CPT_MAX_MBOX_DATA_STR_SIZE];
0063
0064 hex_dump_to_buffer(mbox_msg, sizeof(struct otx_cpt_mbox), 16, 8,
0065 raw_data_str, OTX_CPT_MAX_MBOX_DATA_STR_SIZE, false);
0066 if (vf_id >= 0)
0067 pr_debug("MBOX msg %s received from VF%d raw_data %s",
0068 get_mbox_opcode_str(mbox_msg->msg), vf_id,
0069 raw_data_str);
0070 else
0071 pr_debug("MBOX msg %s received from PF raw_data %s",
0072 get_mbox_opcode_str(mbox_msg->msg), raw_data_str);
0073 }
0074
0075 static void cptvf_send_msg_to_pf(struct otx_cptvf *cptvf,
0076 struct otx_cpt_mbox *mbx)
0077 {
0078
0079 writeq(mbx->msg, cptvf->reg_base + OTX_CPT_VFX_PF_MBOXX(0, 0));
0080 writeq(mbx->data, cptvf->reg_base + OTX_CPT_VFX_PF_MBOXX(0, 1));
0081 }
0082
0083
0084 void otx_cptvf_handle_mbox_intr(struct otx_cptvf *cptvf)
0085 {
0086 struct otx_cpt_mbox mbx = {};
0087
0088
0089
0090
0091
0092 mbx.msg = readq(cptvf->reg_base + OTX_CPT_VFX_PF_MBOXX(0, 0));
0093 mbx.data = readq(cptvf->reg_base + OTX_CPT_VFX_PF_MBOXX(0, 1));
0094
0095 dump_mbox_msg(&mbx, -1);
0096
0097 switch (mbx.msg) {
0098 case OTX_CPT_MSG_VF_UP:
0099 cptvf->pf_acked = true;
0100 cptvf->num_vfs = mbx.data;
0101 break;
0102 case OTX_CPT_MSG_READY:
0103 cptvf->pf_acked = true;
0104 cptvf->vfid = mbx.data;
0105 dev_dbg(&cptvf->pdev->dev, "Received VFID %d\n", cptvf->vfid);
0106 break;
0107 case OTX_CPT_MSG_QBIND_GRP:
0108 cptvf->pf_acked = true;
0109 cptvf->vftype = mbx.data;
0110 dev_dbg(&cptvf->pdev->dev, "VF %d type %s group %d\n",
0111 cptvf->vfid,
0112 ((mbx.data == OTX_CPT_SE_TYPES) ? "SE" : "AE"),
0113 cptvf->vfgrp);
0114 break;
0115 case OTX_CPT_MSG_ACK:
0116 cptvf->pf_acked = true;
0117 break;
0118 case OTX_CPT_MSG_NACK:
0119 cptvf->pf_nacked = true;
0120 break;
0121 default:
0122 dev_err(&cptvf->pdev->dev, "Invalid msg from PF, msg 0x%llx\n",
0123 mbx.msg);
0124 break;
0125 }
0126 }
0127
0128 static int cptvf_send_msg_to_pf_timeout(struct otx_cptvf *cptvf,
0129 struct otx_cpt_mbox *mbx)
0130 {
0131 int timeout = CPT_MBOX_MSG_TIMEOUT;
0132 int sleep = 10;
0133
0134 cptvf->pf_acked = false;
0135 cptvf->pf_nacked = false;
0136 cptvf_send_msg_to_pf(cptvf, mbx);
0137
0138 while (!cptvf->pf_acked) {
0139 if (cptvf->pf_nacked)
0140 return -EINVAL;
0141 msleep(sleep);
0142 if (cptvf->pf_acked)
0143 break;
0144 timeout -= sleep;
0145 if (!timeout) {
0146 dev_err(&cptvf->pdev->dev,
0147 "PF didn't ack to mbox msg %llx from VF%u\n",
0148 mbx->msg, cptvf->vfid);
0149 return -EBUSY;
0150 }
0151 }
0152 return 0;
0153 }
0154
0155
0156
0157
0158
0159 int otx_cptvf_check_pf_ready(struct otx_cptvf *cptvf)
0160 {
0161 struct otx_cpt_mbox mbx = {};
0162 int ret;
0163
0164 mbx.msg = OTX_CPT_MSG_READY;
0165 ret = cptvf_send_msg_to_pf_timeout(cptvf, &mbx);
0166
0167 return ret;
0168 }
0169
0170
0171
0172
0173
0174 int otx_cptvf_send_vq_size_msg(struct otx_cptvf *cptvf)
0175 {
0176 struct otx_cpt_mbox mbx = {};
0177 int ret;
0178
0179 mbx.msg = OTX_CPT_MSG_QLEN;
0180 mbx.data = cptvf->qsize;
0181 ret = cptvf_send_msg_to_pf_timeout(cptvf, &mbx);
0182
0183 return ret;
0184 }
0185
0186
0187
0188
0189 int otx_cptvf_send_vf_to_grp_msg(struct otx_cptvf *cptvf, int group)
0190 {
0191 struct otx_cpt_mbox mbx = {};
0192 int ret;
0193
0194 mbx.msg = OTX_CPT_MSG_QBIND_GRP;
0195
0196 mbx.data = group;
0197 ret = cptvf_send_msg_to_pf_timeout(cptvf, &mbx);
0198 if (ret)
0199 return ret;
0200 cptvf->vfgrp = group;
0201
0202 return 0;
0203 }
0204
0205
0206
0207
0208 int otx_cptvf_send_vf_priority_msg(struct otx_cptvf *cptvf)
0209 {
0210 struct otx_cpt_mbox mbx = {};
0211 int ret;
0212
0213 mbx.msg = OTX_CPT_MSG_VQ_PRIORITY;
0214
0215 mbx.data = cptvf->priority;
0216 ret = cptvf_send_msg_to_pf_timeout(cptvf, &mbx);
0217
0218 return ret;
0219 }
0220
0221
0222
0223
0224 int otx_cptvf_send_vf_up(struct otx_cptvf *cptvf)
0225 {
0226 struct otx_cpt_mbox mbx = {};
0227 int ret;
0228
0229 mbx.msg = OTX_CPT_MSG_VF_UP;
0230 ret = cptvf_send_msg_to_pf_timeout(cptvf, &mbx);
0231
0232 return ret;
0233 }
0234
0235
0236
0237
0238 int otx_cptvf_send_vf_down(struct otx_cptvf *cptvf)
0239 {
0240 struct otx_cpt_mbox mbx = {};
0241 int ret;
0242
0243 mbx.msg = OTX_CPT_MSG_VF_DOWN;
0244 ret = cptvf_send_msg_to_pf_timeout(cptvf, &mbx);
0245
0246 return ret;
0247 }