1// SPDX-License-Identifier: GPL-2.0
2/* Marvell RVU Admin Function driver
3 *
4 * Copyright (C) 2021 Marvell.
5 *
6 */
7
8#include <linux/pci.h>
9#include "rvu.h"
10
11/* SDP PF device id */
12#define PCI_DEVID_OTX2_SDP_PF 0xA0F6
13
14/* Maximum SDP blocks in a chip */
15#define MAX_SDP 2
16
17/* SDP PF number */
18static int sdp_pf_num[MAX_SDP] = {-1, -1};
19
20bool is_sdp_pfvf(u16 pcifunc)
21{
22 u16 pf = rvu_get_pf(pcifunc);
23 u32 found = 0, i = 0;
24
25 while (i < MAX_SDP) {
26 if (pf == sdp_pf_num[i])
27 found = 1;
28 i++;
29 }
30
31 if (!found)
32 return false;
33
34 return true;
35}
36
37bool is_sdp_pf(u16 pcifunc)
38{
39 return (is_sdp_pfvf(pcifunc) &&
40 !(pcifunc & RVU_PFVF_FUNC_MASK));
41}
42
43#define RVU_SDP_VF_DEVID 0xA0F7
44bool is_sdp_vf(struct rvu *rvu, u16 pcifunc)
45{
46 if (!(pcifunc & ~RVU_PFVF_FUNC_MASK))
47 return (rvu->vf_devid == RVU_SDP_VF_DEVID);
48
49 return (is_sdp_pfvf(pcifunc) &&
50 !!(pcifunc & RVU_PFVF_FUNC_MASK));
51}
52
53int rvu_sdp_init(struct rvu *rvu)
54{
55 struct pci_dev *pdev = NULL;
56 struct rvu_pfvf *pfvf;
57 u32 i = 0;
58
59 if (rvu->fwdata->channel_data.valid) {
60 sdp_pf_num[0] = 0;
61 pfvf = &rvu->pf[sdp_pf_num[0]];
62 pfvf->sdp_info = &rvu->fwdata->channel_data.info;
63
64 return 0;
65 }
66
67 while ((i < MAX_SDP) && (pdev = pci_get_device(PCI_VENDOR_ID_CAVIUM,
68 PCI_DEVID_OTX2_SDP_PF,
69 from: pdev)) != NULL) {
70 /* The RVU PF number is one less than bus number */
71 sdp_pf_num[i] = pdev->bus->number - 1;
72 pfvf = &rvu->pf[sdp_pf_num[i]];
73
74 pfvf->sdp_info = devm_kzalloc(dev: rvu->dev,
75 size: sizeof(struct sdp_node_info),
76 GFP_KERNEL);
77 if (!pfvf->sdp_info) {
78 pci_dev_put(dev: pdev);
79 return -ENOMEM;
80 }
81
82 dev_info(rvu->dev, "SDP PF number:%d\n", sdp_pf_num[i]);
83
84 i++;
85 }
86
87 pci_dev_put(dev: pdev);
88
89 return 0;
90}
91
92int
93rvu_mbox_handler_set_sdp_chan_info(struct rvu *rvu,
94 struct sdp_chan_info_msg *req,
95 struct msg_rsp *rsp)
96{
97 struct rvu_pfvf *pfvf = rvu_get_pfvf(rvu, pcifunc: req->hdr.pcifunc);
98
99 memcpy(pfvf->sdp_info, &req->info, sizeof(struct sdp_node_info));
100 dev_info(rvu->dev, "AF: SDP%d max_vfs %d num_pf_rings %d pf_srn %d\n",
101 req->info.node_id, req->info.max_vfs, req->info.num_pf_rings,
102 req->info.pf_srn);
103 return 0;
104}
105
106int
107rvu_mbox_handler_get_sdp_chan_info(struct rvu *rvu, struct msg_req *req,
108 struct sdp_get_chan_info_msg *rsp)
109{
110 struct rvu_hwinfo *hw = rvu->hw;
111 int blkaddr;
112
113 if (!hw->cap.programmable_chans) {
114 rsp->chan_base = NIX_CHAN_SDP_CH_START;
115 rsp->num_chan = NIX_CHAN_SDP_NUM_CHANS;
116 } else {
117 blkaddr = rvu_get_blkaddr(rvu, blktype: BLKTYPE_NIX, pcifunc: 0);
118 rsp->chan_base = hw->sdp_chan_base;
119 rsp->num_chan = rvu_read64(rvu, block: blkaddr, NIX_AF_CONST1) & 0xFFFUL;
120 }
121
122 return 0;
123}
124

source code of linux/drivers/net/ethernet/marvell/octeontx2/af/rvu_sdp.c