1318ee1b0SAkhil Goyal /* SPDX-License-Identifier: BSD-3-Clause 2318ee1b0SAkhil Goyal * Copyright(C) 2024 Marvell. 3318ee1b0SAkhil Goyal */ 4318ee1b0SAkhil Goyal 5318ee1b0SAkhil Goyal #include "roc_api.h" 6318ee1b0SAkhil Goyal #include "roc_priv.h" 7318ee1b0SAkhil Goyal 8318ee1b0SAkhil Goyal int 9318ee1b0SAkhil Goyal roc_rvu_lf_dev_init(struct roc_rvu_lf *roc_rvu_lf) 10318ee1b0SAkhil Goyal { 11318ee1b0SAkhil Goyal struct plt_pci_device *pci_dev; 12318ee1b0SAkhil Goyal struct dev *dev; 13318ee1b0SAkhil Goyal struct rvu_lf *rvu; 14318ee1b0SAkhil Goyal int rc; 15318ee1b0SAkhil Goyal 16318ee1b0SAkhil Goyal if (roc_rvu_lf == NULL || roc_rvu_lf->pci_dev == NULL) 17318ee1b0SAkhil Goyal return RVU_ERR_PARAM; 18318ee1b0SAkhil Goyal 19318ee1b0SAkhil Goyal rvu = roc_rvu_lf_to_rvu_priv(roc_rvu_lf); 20318ee1b0SAkhil Goyal pci_dev = roc_rvu_lf->pci_dev; 21318ee1b0SAkhil Goyal dev = &rvu->dev; 22318ee1b0SAkhil Goyal 23318ee1b0SAkhil Goyal if (rvu->dev.drv_inited) 24318ee1b0SAkhil Goyal return 0; 25318ee1b0SAkhil Goyal 26318ee1b0SAkhil Goyal if (dev->mbox_active) 27318ee1b0SAkhil Goyal goto skip_dev_init; 28318ee1b0SAkhil Goyal 29318ee1b0SAkhil Goyal memset(rvu, 0, sizeof(*rvu)); 30318ee1b0SAkhil Goyal 31318ee1b0SAkhil Goyal /* Initialize device */ 32318ee1b0SAkhil Goyal rc = dev_init(dev, pci_dev); 33318ee1b0SAkhil Goyal if (rc) { 34318ee1b0SAkhil Goyal plt_err("Failed to init roc device"); 35318ee1b0SAkhil Goyal goto fail; 36318ee1b0SAkhil Goyal } 37318ee1b0SAkhil Goyal 38318ee1b0SAkhil Goyal skip_dev_init: 39318ee1b0SAkhil Goyal dev->roc_rvu_lf = roc_rvu_lf; 40318ee1b0SAkhil Goyal rvu->pci_dev = pci_dev; 41318ee1b0SAkhil Goyal 42318ee1b0SAkhil Goyal roc_idev_rvu_lf_set(roc_rvu_lf); 43318ee1b0SAkhil Goyal rvu->dev.drv_inited = true; 44318ee1b0SAkhil Goyal 45318ee1b0SAkhil Goyal return 0; 46318ee1b0SAkhil Goyal fail: 47318ee1b0SAkhil Goyal return rc; 48318ee1b0SAkhil Goyal } 49318ee1b0SAkhil Goyal 50318ee1b0SAkhil Goyal int 51318ee1b0SAkhil Goyal roc_rvu_lf_dev_fini(struct roc_rvu_lf *roc_rvu_lf) 52318ee1b0SAkhil Goyal { 53318ee1b0SAkhil Goyal struct rvu_lf *rvu = roc_rvu_lf_to_rvu_priv(roc_rvu_lf); 54318ee1b0SAkhil Goyal 55318ee1b0SAkhil Goyal if (rvu == NULL) 56318ee1b0SAkhil Goyal return NIX_ERR_PARAM; 57318ee1b0SAkhil Goyal 58318ee1b0SAkhil Goyal rvu->dev.drv_inited = false; 59318ee1b0SAkhil Goyal 60318ee1b0SAkhil Goyal roc_idev_rvu_lf_free(roc_rvu_lf); 61318ee1b0SAkhil Goyal 62318ee1b0SAkhil Goyal return dev_fini(&rvu->dev, rvu->pci_dev); 63318ee1b0SAkhil Goyal } 64f4c67d72SAkhil Goyal 65*fcac76a8SAkhil Goyal uint16_t 66384903edSAkhil Goyal roc_rvu_lf_pf_func_get(struct roc_rvu_lf *roc_rvu_lf) 67384903edSAkhil Goyal { 68384903edSAkhil Goyal struct rvu_lf *rvu = roc_rvu_lf_to_rvu_priv(roc_rvu_lf); 69384903edSAkhil Goyal struct dev *dev = &rvu->dev; 70384903edSAkhil Goyal 71384903edSAkhil Goyal return dev->pf_func; 72384903edSAkhil Goyal } 73384903edSAkhil Goyal 74f4c67d72SAkhil Goyal int 750924cc0bSAkhil Goyal roc_rvu_lf_msg_id_range_set(struct roc_rvu_lf *roc_rvu_lf, uint16_t from, uint16_t to) 760924cc0bSAkhil Goyal { 770924cc0bSAkhil Goyal struct rvu_lf *rvu = roc_rvu_lf_to_rvu_priv(roc_rvu_lf); 780924cc0bSAkhil Goyal 790924cc0bSAkhil Goyal if (from <= MBOX_MSG_GENERIC_MAX_ID || from > to) 800924cc0bSAkhil Goyal return -EINVAL; 810924cc0bSAkhil Goyal 820924cc0bSAkhil Goyal rvu->msg_id_from = from; 830924cc0bSAkhil Goyal rvu->msg_id_to = to; 840924cc0bSAkhil Goyal 850924cc0bSAkhil Goyal return 0; 860924cc0bSAkhil Goyal } 870924cc0bSAkhil Goyal 880924cc0bSAkhil Goyal bool 890924cc0bSAkhil Goyal roc_rvu_lf_msg_id_range_check(struct roc_rvu_lf *roc_rvu_lf, uint16_t msg_id) 900924cc0bSAkhil Goyal { 910924cc0bSAkhil Goyal struct rvu_lf *rvu; 920924cc0bSAkhil Goyal 930924cc0bSAkhil Goyal if (roc_rvu_lf == NULL) 940924cc0bSAkhil Goyal return 0; 950924cc0bSAkhil Goyal 960924cc0bSAkhil Goyal rvu = roc_rvu_lf_to_rvu_priv(roc_rvu_lf); 970924cc0bSAkhil Goyal 980924cc0bSAkhil Goyal if (msg_id > rvu->msg_id_from && msg_id < rvu->msg_id_to) 990924cc0bSAkhil Goyal return 1; 1000924cc0bSAkhil Goyal 1010924cc0bSAkhil Goyal return 0; 1020924cc0bSAkhil Goyal } 1030924cc0bSAkhil Goyal 1040924cc0bSAkhil Goyal int 105384903edSAkhil Goyal roc_rvu_lf_msg_process(struct roc_rvu_lf *roc_rvu_lf, uint16_t vf, uint16_t msg_id, 106384903edSAkhil Goyal void *req_data, uint16_t req_len, void *rsp_data, uint16_t rsp_len) 107384903edSAkhil Goyal { 108384903edSAkhil Goyal struct rvu_lf *rvu = roc_rvu_lf_to_rvu_priv(roc_rvu_lf); 109384903edSAkhil Goyal struct mbox *mbox; 110384903edSAkhil Goyal struct rvu_lf_msg *req; 111384903edSAkhil Goyal struct rvu_lf_msg *rsp; 112384903edSAkhil Goyal int rc = -ENOSPC; 113384903edSAkhil Goyal int devid = 0; 114384903edSAkhil Goyal 115384903edSAkhil Goyal if (rvu->dev.vf == -1 && roc_rvu_lf_msg_id_range_check(roc_rvu_lf, msg_id)) { 116384903edSAkhil Goyal /* This is PF context */ 117384903edSAkhil Goyal if (vf >= rvu->dev.maxvf) 118384903edSAkhil Goyal return -EINVAL; 119384903edSAkhil Goyal devid = vf; 120384903edSAkhil Goyal mbox = mbox_get(&rvu->dev.mbox_vfpf_up); 121384903edSAkhil Goyal } else { 122384903edSAkhil Goyal /* This is VF context */ 123384903edSAkhil Goyal devid = 0; /* VF send all message to PF */ 124384903edSAkhil Goyal mbox = mbox_get(rvu->dev.mbox); 125384903edSAkhil Goyal } 126384903edSAkhil Goyal req = (struct rvu_lf_msg *)mbox_alloc_msg_rsp(mbox, devid, 127384903edSAkhil Goyal req_len + sizeof(struct rvu_lf_msg), 128384903edSAkhil Goyal rsp_len + sizeof(struct rvu_lf_msg)); 129384903edSAkhil Goyal if (!req) 130384903edSAkhil Goyal goto fail; 131384903edSAkhil Goyal mbox_memcpy(req->data, req_data, req_len); 132384903edSAkhil Goyal req->hdr.sig = MBOX_REQ_SIG; 133384903edSAkhil Goyal req->hdr.id = msg_id; 134384903edSAkhil Goyal req->hdr.pcifunc = roc_rvu_lf_pf_func_get(roc_rvu_lf); 135384903edSAkhil Goyal 136384903edSAkhil Goyal if (rvu->dev.vf == -1) { 137384903edSAkhil Goyal mbox_msg_send_up(mbox, devid); 138384903edSAkhil Goyal rc = mbox_get_rsp(mbox, devid, (void *)&rsp); 139384903edSAkhil Goyal if (rc) 140384903edSAkhil Goyal goto fail; 141384903edSAkhil Goyal } else { 142384903edSAkhil Goyal rc = mbox_process_msg(mbox, (void *)&rsp); 143384903edSAkhil Goyal if (rc) 144384903edSAkhil Goyal goto fail; 145384903edSAkhil Goyal } 146384903edSAkhil Goyal if (rsp_len && rsp_data != NULL) 147384903edSAkhil Goyal mbox_memcpy(rsp_data, rsp->data, rsp_len); 148384903edSAkhil Goyal fail: 149384903edSAkhil Goyal mbox_put(mbox); 150384903edSAkhil Goyal return rc; 151384903edSAkhil Goyal } 152384903edSAkhil Goyal 153384903edSAkhil Goyal int 154f4c67d72SAkhil Goyal roc_rvu_lf_irq_register(struct roc_rvu_lf *roc_rvu_lf, unsigned int irq, 155f4c67d72SAkhil Goyal roc_rvu_lf_intr_cb_fn cb, void *data) 156f4c67d72SAkhil Goyal { 157f4c67d72SAkhil Goyal struct rvu_lf *rvu = roc_rvu_lf_to_rvu_priv(roc_rvu_lf); 158f4c67d72SAkhil Goyal struct plt_intr_handle *handle; 159f4c67d72SAkhil Goyal 160f4c67d72SAkhil Goyal handle = rvu->pci_dev->intr_handle; 161f4c67d72SAkhil Goyal 162f4c67d72SAkhil Goyal return dev_irq_register(handle, (plt_intr_callback_fn)cb, data, irq); 163f4c67d72SAkhil Goyal } 164f4c67d72SAkhil Goyal 165f4c67d72SAkhil Goyal int 166f4c67d72SAkhil Goyal roc_rvu_lf_irq_unregister(struct roc_rvu_lf *roc_rvu_lf, unsigned int irq, 167f4c67d72SAkhil Goyal roc_rvu_lf_intr_cb_fn cb, void *data) 168f4c67d72SAkhil Goyal { 169f4c67d72SAkhil Goyal struct rvu_lf *rvu = roc_rvu_lf_to_rvu_priv(roc_rvu_lf); 170f4c67d72SAkhil Goyal struct plt_intr_handle *handle; 171f4c67d72SAkhil Goyal 172f4c67d72SAkhil Goyal handle = rvu->pci_dev->intr_handle; 173f4c67d72SAkhil Goyal 174f4c67d72SAkhil Goyal dev_irq_unregister(handle, (plt_intr_callback_fn)cb, data, irq); 175f4c67d72SAkhil Goyal 176f4c67d72SAkhil Goyal return 0; 177f4c67d72SAkhil Goyal } 1787396eaceSAkhil Goyal 1797396eaceSAkhil Goyal int 1807396eaceSAkhil Goyal roc_rvu_lf_msg_handler_register(struct roc_rvu_lf *roc_rvu_lf, roc_rvu_lf_msg_handler_cb_fn cb) 1817396eaceSAkhil Goyal { 1827396eaceSAkhil Goyal struct rvu_lf *rvu = roc_rvu_lf_to_rvu_priv(roc_rvu_lf); 1837396eaceSAkhil Goyal struct dev *dev = &rvu->dev; 1847396eaceSAkhil Goyal 1857396eaceSAkhil Goyal if (cb == NULL) 1867396eaceSAkhil Goyal return -EINVAL; 1877396eaceSAkhil Goyal 1887396eaceSAkhil Goyal dev->ops->msg_process_cb = (msg_process_cb_t)cb; 1897396eaceSAkhil Goyal 1907396eaceSAkhil Goyal return 0; 1917396eaceSAkhil Goyal } 1927396eaceSAkhil Goyal 1937396eaceSAkhil Goyal int 1947396eaceSAkhil Goyal roc_rvu_lf_msg_handler_unregister(struct roc_rvu_lf *roc_rvu_lf) 1957396eaceSAkhil Goyal { 1967396eaceSAkhil Goyal struct rvu_lf *rvu = roc_rvu_lf_to_rvu_priv(roc_rvu_lf); 1977396eaceSAkhil Goyal struct dev *dev = &rvu->dev; 1987396eaceSAkhil Goyal 1997396eaceSAkhil Goyal dev->ops->msg_process_cb = NULL; 2007396eaceSAkhil Goyal 2017396eaceSAkhil Goyal return 0; 2027396eaceSAkhil Goyal } 203