112 lines
2.3 KiB
C
112 lines
2.3 KiB
C
|
// 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;
|
||
|
}
|