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 */ |
18 | static int sdp_pf_num[MAX_SDP] = {-1, -1}; |
19 | |
20 | bool 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 | |
37 | bool 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 |
44 | bool 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 | |
53 | int 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 | |
92 | int |
93 | rvu_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 | |
106 | int |
107 | rvu_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 | |