| // SPDX-License-Identifier: GPL-2.0 |
| /* Marvell RVU Admin Function driver |
| * |
| * Copyright (C) 2021 Marvell. |
| * |
| */ |
| |
| #include <linux/pci.h> |
| #include "rvu.h" |
| |
| /* SDP PF device id */ |
| #define PCI_DEVID_OTX2_SDP_PF 0xA0F6 |
| |
| /* Maximum SDP blocks in a chip */ |
| #define MAX_SDP 2 |
| |
| /* SDP PF number */ |
| static int sdp_pf_num[MAX_SDP] = {-1, -1}; |
| |
| bool is_sdp_pfvf(u16 pcifunc) |
| { |
| u16 pf = rvu_get_pf(pcifunc); |
| u32 found = 0, i = 0; |
| |
| while (i < MAX_SDP) { |
| if (pf == sdp_pf_num[i]) |
| found = 1; |
| i++; |
| } |
| |
| if (!found) |
| return false; |
| |
| return true; |
| } |
| |
| bool is_sdp_pf(u16 pcifunc) |
| { |
| return (is_sdp_pfvf(pcifunc) && |
| !(pcifunc & RVU_PFVF_FUNC_MASK)); |
| } |
| |
| bool is_sdp_vf(u16 pcifunc) |
| { |
| return (is_sdp_pfvf(pcifunc) && |
| !!(pcifunc & RVU_PFVF_FUNC_MASK)); |
| } |
| |
| int rvu_sdp_init(struct rvu *rvu) |
| { |
| struct pci_dev *pdev = NULL; |
| struct rvu_pfvf *pfvf; |
| u32 i = 0; |
| |
| while ((i < MAX_SDP) && (pdev = pci_get_device(PCI_VENDOR_ID_CAVIUM, |
| PCI_DEVID_OTX2_SDP_PF, |
| pdev)) != NULL) { |
| /* The RVU PF number is one less than bus number */ |
| sdp_pf_num[i] = pdev->bus->number - 1; |
| pfvf = &rvu->pf[sdp_pf_num[i]]; |
| |
| pfvf->sdp_info = devm_kzalloc(rvu->dev, |
| sizeof(struct sdp_node_info), |
| GFP_KERNEL); |
| if (!pfvf->sdp_info) { |
| pci_dev_put(pdev); |
| return -ENOMEM; |
| } |
| |
| dev_info(rvu->dev, "SDP PF number:%d\n", sdp_pf_num[i]); |
| |
| i++; |
| } |
| |
| pci_dev_put(pdev); |
| |
| return 0; |
| } |
| |
| int |
| rvu_mbox_handler_set_sdp_chan_info(struct rvu *rvu, |
| struct sdp_chan_info_msg *req, |
| struct msg_rsp *rsp) |
| { |
| struct rvu_pfvf *pfvf = rvu_get_pfvf(rvu, req->hdr.pcifunc); |
| |
| memcpy(pfvf->sdp_info, &req->info, sizeof(struct sdp_node_info)); |
| dev_info(rvu->dev, "AF: SDP%d max_vfs %d num_pf_rings %d pf_srn %d\n", |
| req->info.node_id, req->info.max_vfs, req->info.num_pf_rings, |
| req->info.pf_srn); |
| return 0; |
| } |
| |
| int |
| rvu_mbox_handler_get_sdp_chan_info(struct rvu *rvu, struct msg_req *req, |
| struct sdp_get_chan_info_msg *rsp) |
| { |
| struct rvu_hwinfo *hw = rvu->hw; |
| int blkaddr; |
| |
| if (!hw->cap.programmable_chans) { |
| rsp->chan_base = NIX_CHAN_SDP_CH_START; |
| rsp->num_chan = NIX_CHAN_SDP_NUM_CHANS; |
| } else { |
| blkaddr = rvu_get_blkaddr(rvu, BLKTYPE_NIX, 0); |
| rsp->chan_base = hw->sdp_chan_base; |
| rsp->num_chan = rvu_read64(rvu, blkaddr, NIX_AF_CONST1) & 0xFFFUL; |
| } |
| |
| return 0; |
| } |