1 // SPDX-License-Identifier: GPL-2.0
2 /* Marvell OcteonTx2 RVU Admin Function driver
4 * Copyright (C) 2021 Marvell.
7 #include <linux/bitfield.h>
10 static int rvu_switch_install_rx_rule(struct rvu *rvu, u16 pcifunc,
13 struct npc_install_flow_req req = { 0 };
14 struct npc_install_flow_rsp rsp = { 0 };
15 struct rvu_pfvf *pfvf;
17 pfvf = rvu_get_pfvf(rvu, pcifunc);
18 /* If the pcifunc is not initialized then nothing to do.
19 * This same function will be called again via rvu_switch_update_rules
20 * after pcifunc is initialized.
22 if (!test_bit(NIXLF_INITIALIZED, &pfvf->flags))
25 ether_addr_copy(req.packet.dmac, pfvf->mac_addr);
26 eth_broadcast_addr((u8 *)&req.mask.dmac);
27 req.hdr.pcifunc = 0; /* AF is requester */
29 req.features = BIT_ULL(NPC_DMAC);
30 req.channel = pfvf->rx_chan_base;
31 req.chan_mask = chan_mask;
32 req.intf = pfvf->nix_rx_intf;
33 req.op = NIX_RX_ACTION_DEFAULT;
36 return rvu_mbox_handler_npc_install_flow(rvu, &req, &rsp);
39 static int rvu_switch_install_tx_rule(struct rvu *rvu, u16 pcifunc, u16 entry)
41 struct npc_install_flow_req req = { 0 };
42 struct npc_install_flow_rsp rsp = { 0 };
43 struct rvu_pfvf *pfvf;
46 pfvf = rvu_get_pfvf(rvu, pcifunc);
47 /* If the pcifunc is not initialized then nothing to do.
48 * This same function will be called again via rvu_switch_update_rules
49 * after pcifunc is initialized.
51 if (!test_bit(NIXLF_INITIALIZED, &pfvf->flags))
54 lbkid = pfvf->nix_blkaddr == BLKADDR_NIX0 ? 0 : 1;
55 ether_addr_copy(req.packet.dmac, pfvf->mac_addr);
56 eth_broadcast_addr((u8 *)&req.mask.dmac);
57 req.hdr.pcifunc = 0; /* AF is requester */
60 req.features = BIT_ULL(NPC_DMAC);
61 req.intf = pfvf->nix_tx_intf;
62 req.op = NIX_TX_ACTIONOP_UCAST_CHAN;
63 req.index = (lbkid << 8) | RVU_SWITCH_LBK_CHAN;
66 return rvu_mbox_handler_npc_install_flow(rvu, &req, &rsp);
69 static int rvu_switch_install_rules(struct rvu *rvu)
71 struct rvu_switch *rswitch = &rvu->rswitch;
72 u16 start = rswitch->start_entry;
73 struct rvu_hwinfo *hw = rvu->hw;
74 u16 pcifunc, entry = 0;
78 for (pf = 1; pf < hw->total_pfs; pf++) {
79 if (!is_pf_cgxmapped(rvu, pf))
83 /* rvu_get_nix_blkaddr sets up the corresponding NIX block
84 * address and NIX RX and TX interfaces for a pcifunc.
85 * Generally it is called during attach call of a pcifunc but it
86 * is called here since we are pre-installing rules before
89 rvu_get_nix_blkaddr(rvu, pcifunc);
91 /* MCAM RX rule for a PF/VF already exists as default unicast
92 * rules installed by AF. Hence change the channel in those
93 * rules to ignore channel so that packets with the required
94 * DMAC received from LBK(by other PF/VFs in system) or from
95 * external world (from wire) are accepted.
97 err = rvu_switch_install_rx_rule(rvu, pcifunc, 0x0);
99 dev_err(rvu->dev, "RX rule for PF%d failed(%d)\n",
104 err = rvu_switch_install_tx_rule(rvu, pcifunc, start + entry);
106 dev_err(rvu->dev, "TX rule for PF%d failed(%d)\n",
111 rswitch->entry2pcifunc[entry++] = pcifunc;
113 rvu_get_pf_numvfs(rvu, pf, &numvfs, NULL);
114 for (vf = 0; vf < numvfs; vf++) {
115 pcifunc = pf << 10 | ((vf + 1) & 0x3FF);
116 rvu_get_nix_blkaddr(rvu, pcifunc);
118 err = rvu_switch_install_rx_rule(rvu, pcifunc, 0x0);
121 "RX rule for PF%dVF%d failed(%d)\n",
126 err = rvu_switch_install_tx_rule(rvu, pcifunc,
130 "TX rule for PF%dVF%d failed(%d)\n",
135 rswitch->entry2pcifunc[entry++] = pcifunc;
142 void rvu_switch_enable(struct rvu *rvu)
144 struct npc_mcam_alloc_entry_req alloc_req = { 0 };
145 struct npc_mcam_alloc_entry_rsp alloc_rsp = { 0 };
146 struct npc_delete_flow_req uninstall_req = { 0 };
147 struct npc_mcam_free_entry_req free_req = { 0 };
148 struct rvu_switch *rswitch = &rvu->rswitch;
152 alloc_req.contig = true;
153 alloc_req.count = rvu->cgx_mapped_pfs + rvu->cgx_mapped_vfs;
154 ret = rvu_mbox_handler_npc_mcam_alloc_entry(rvu, &alloc_req,
158 "Unable to allocate MCAM entries\n");
162 if (alloc_rsp.count != alloc_req.count) {
164 "Unable to allocate %d MCAM entries, got %d\n",
165 alloc_req.count, alloc_rsp.count);
169 rswitch->entry2pcifunc = kcalloc(alloc_req.count, sizeof(u16),
171 if (!rswitch->entry2pcifunc)
174 rswitch->used_entries = alloc_rsp.count;
175 rswitch->start_entry = alloc_rsp.entry;
177 ret = rvu_switch_install_rules(rvu);
179 goto uninstall_rules;
184 uninstall_req.start = rswitch->start_entry;
185 uninstall_req.end = rswitch->start_entry + rswitch->used_entries - 1;
186 rvu_mbox_handler_npc_delete_flow(rvu, &uninstall_req, &rsp);
187 kfree(rswitch->entry2pcifunc);
190 rvu_mbox_handler_npc_mcam_free_entry(rvu, &free_req, &rsp);
195 void rvu_switch_disable(struct rvu *rvu)
197 struct npc_delete_flow_req uninstall_req = { 0 };
198 struct npc_mcam_free_entry_req free_req = { 0 };
199 struct rvu_switch *rswitch = &rvu->rswitch;
200 struct rvu_hwinfo *hw = rvu->hw;
206 if (!rswitch->used_entries)
209 for (pf = 1; pf < hw->total_pfs; pf++) {
210 if (!is_pf_cgxmapped(rvu, pf))
214 err = rvu_switch_install_rx_rule(rvu, pcifunc, 0xFFF);
217 "Reverting RX rule for PF%d failed(%d)\n",
220 rvu_get_pf_numvfs(rvu, pf, &numvfs, NULL);
221 for (vf = 0; vf < numvfs; vf++) {
222 pcifunc = pf << 10 | ((vf + 1) & 0x3FF);
223 err = rvu_switch_install_rx_rule(rvu, pcifunc, 0xFFF);
226 "Reverting RX rule for PF%dVF%d failed(%d)\n",
231 uninstall_req.start = rswitch->start_entry;
232 uninstall_req.end = rswitch->start_entry + rswitch->used_entries - 1;
234 rvu_mbox_handler_npc_delete_flow(rvu, &uninstall_req, &rsp);
235 rvu_mbox_handler_npc_mcam_free_entry(rvu, &free_req, &rsp);
236 rswitch->used_entries = 0;
237 kfree(rswitch->entry2pcifunc);
240 void rvu_switch_update_rules(struct rvu *rvu, u16 pcifunc)
242 struct rvu_switch *rswitch = &rvu->rswitch;
243 u32 max = rswitch->used_entries;
246 if (!rswitch->used_entries)
249 for (entry = 0; entry < max; entry++) {
250 if (rswitch->entry2pcifunc[entry] == pcifunc)
257 rvu_switch_install_tx_rule(rvu, pcifunc, rswitch->start_entry + entry);
258 rvu_switch_install_rx_rule(rvu, pcifunc, 0x0);