1 /* SPDX-License-Identifier: BSD-3-Clause 2 * Copyright(C) 2024 Marvell. 3 */ 4 5 #include "roc_api.h" 6 #include "roc_priv.h" 7 8 int 9 roc_rvu_lf_dev_init(struct roc_rvu_lf *roc_rvu_lf) 10 { 11 struct plt_pci_device *pci_dev; 12 struct dev *dev; 13 struct rvu_lf *rvu; 14 int rc; 15 16 if (roc_rvu_lf == NULL || roc_rvu_lf->pci_dev == NULL) 17 return RVU_ERR_PARAM; 18 19 rvu = roc_rvu_lf_to_rvu_priv(roc_rvu_lf); 20 pci_dev = roc_rvu_lf->pci_dev; 21 dev = &rvu->dev; 22 23 if (rvu->dev.drv_inited) 24 return 0; 25 26 if (dev->mbox_active) 27 goto skip_dev_init; 28 29 memset(rvu, 0, sizeof(*rvu)); 30 31 /* Initialize device */ 32 rc = dev_init(dev, pci_dev); 33 if (rc) { 34 plt_err("Failed to init roc device"); 35 goto fail; 36 } 37 38 skip_dev_init: 39 dev->roc_rvu_lf = roc_rvu_lf; 40 rvu->pci_dev = pci_dev; 41 42 roc_idev_rvu_lf_set(roc_rvu_lf); 43 rvu->dev.drv_inited = true; 44 45 return 0; 46 fail: 47 return rc; 48 } 49 50 int 51 roc_rvu_lf_dev_fini(struct roc_rvu_lf *roc_rvu_lf) 52 { 53 struct rvu_lf *rvu = roc_rvu_lf_to_rvu_priv(roc_rvu_lf); 54 55 if (rvu == NULL) 56 return NIX_ERR_PARAM; 57 58 rvu->dev.drv_inited = false; 59 60 roc_idev_rvu_lf_free(roc_rvu_lf); 61 62 return dev_fini(&rvu->dev, rvu->pci_dev); 63 } 64 65 uint16_t 66 roc_rvu_lf_pf_func_get(struct roc_rvu_lf *roc_rvu_lf) 67 { 68 struct rvu_lf *rvu = roc_rvu_lf_to_rvu_priv(roc_rvu_lf); 69 struct dev *dev = &rvu->dev; 70 71 return dev->pf_func; 72 } 73 74 int 75 roc_rvu_lf_msg_id_range_set(struct roc_rvu_lf *roc_rvu_lf, uint16_t from, uint16_t to) 76 { 77 struct rvu_lf *rvu = roc_rvu_lf_to_rvu_priv(roc_rvu_lf); 78 79 if (from <= MBOX_MSG_GENERIC_MAX_ID || from > to) 80 return -EINVAL; 81 82 rvu->msg_id_from = from; 83 rvu->msg_id_to = to; 84 85 return 0; 86 } 87 88 bool 89 roc_rvu_lf_msg_id_range_check(struct roc_rvu_lf *roc_rvu_lf, uint16_t msg_id) 90 { 91 struct rvu_lf *rvu; 92 93 if (roc_rvu_lf == NULL) 94 return 0; 95 96 rvu = roc_rvu_lf_to_rvu_priv(roc_rvu_lf); 97 98 if (msg_id > rvu->msg_id_from && msg_id < rvu->msg_id_to) 99 return 1; 100 101 return 0; 102 } 103 104 int 105 roc_rvu_lf_msg_process(struct roc_rvu_lf *roc_rvu_lf, uint16_t vf, uint16_t msg_id, 106 void *req_data, uint16_t req_len, void *rsp_data, uint16_t rsp_len) 107 { 108 struct rvu_lf *rvu = roc_rvu_lf_to_rvu_priv(roc_rvu_lf); 109 struct mbox *mbox; 110 struct rvu_lf_msg *req; 111 struct rvu_lf_msg *rsp; 112 int rc = -ENOSPC; 113 int devid = 0; 114 115 if (rvu->dev.vf == -1 && roc_rvu_lf_msg_id_range_check(roc_rvu_lf, msg_id)) { 116 /* This is PF context */ 117 if (vf >= rvu->dev.maxvf) 118 return -EINVAL; 119 devid = vf; 120 mbox = mbox_get(&rvu->dev.mbox_vfpf_up); 121 } else { 122 /* This is VF context */ 123 devid = 0; /* VF send all message to PF */ 124 mbox = mbox_get(rvu->dev.mbox); 125 } 126 req = (struct rvu_lf_msg *)mbox_alloc_msg_rsp(mbox, devid, 127 req_len + sizeof(struct rvu_lf_msg), 128 rsp_len + sizeof(struct rvu_lf_msg)); 129 if (!req) 130 goto fail; 131 mbox_memcpy(req->data, req_data, req_len); 132 req->hdr.sig = MBOX_REQ_SIG; 133 req->hdr.id = msg_id; 134 req->hdr.pcifunc = roc_rvu_lf_pf_func_get(roc_rvu_lf); 135 136 if (rvu->dev.vf == -1) { 137 mbox_msg_send_up(mbox, devid); 138 rc = mbox_get_rsp(mbox, devid, (void *)&rsp); 139 if (rc) 140 goto fail; 141 } else { 142 rc = mbox_process_msg(mbox, (void *)&rsp); 143 if (rc) 144 goto fail; 145 } 146 if (rsp_len && rsp_data != NULL) 147 mbox_memcpy(rsp_data, rsp->data, rsp_len); 148 fail: 149 mbox_put(mbox); 150 return rc; 151 } 152 153 int 154 roc_rvu_lf_irq_register(struct roc_rvu_lf *roc_rvu_lf, unsigned int irq, 155 roc_rvu_lf_intr_cb_fn cb, void *data) 156 { 157 struct rvu_lf *rvu = roc_rvu_lf_to_rvu_priv(roc_rvu_lf); 158 struct plt_intr_handle *handle; 159 160 handle = rvu->pci_dev->intr_handle; 161 162 return dev_irq_register(handle, (plt_intr_callback_fn)cb, data, irq); 163 } 164 165 int 166 roc_rvu_lf_irq_unregister(struct roc_rvu_lf *roc_rvu_lf, unsigned int irq, 167 roc_rvu_lf_intr_cb_fn cb, void *data) 168 { 169 struct rvu_lf *rvu = roc_rvu_lf_to_rvu_priv(roc_rvu_lf); 170 struct plt_intr_handle *handle; 171 172 handle = rvu->pci_dev->intr_handle; 173 174 dev_irq_unregister(handle, (plt_intr_callback_fn)cb, data, irq); 175 176 return 0; 177 } 178 179 int 180 roc_rvu_lf_msg_handler_register(struct roc_rvu_lf *roc_rvu_lf, roc_rvu_lf_msg_handler_cb_fn cb) 181 { 182 struct rvu_lf *rvu = roc_rvu_lf_to_rvu_priv(roc_rvu_lf); 183 struct dev *dev = &rvu->dev; 184 185 if (cb == NULL) 186 return -EINVAL; 187 188 dev->ops->msg_process_cb = (msg_process_cb_t)cb; 189 190 return 0; 191 } 192 193 int 194 roc_rvu_lf_msg_handler_unregister(struct roc_rvu_lf *roc_rvu_lf) 195 { 196 struct rvu_lf *rvu = roc_rvu_lf_to_rvu_priv(roc_rvu_lf); 197 struct dev *dev = &rvu->dev; 198 199 dev->ops->msg_process_cb = NULL; 200 201 return 0; 202 } 203