0001
0002
0003
0004
0005
0006
0007
0008 #include <linux/bitfield.h>
0009 #include "rvu.h"
0010
0011 static int rvu_switch_install_rx_rule(struct rvu *rvu, u16 pcifunc,
0012 u16 chan_mask)
0013 {
0014 struct npc_install_flow_req req = { 0 };
0015 struct npc_install_flow_rsp rsp = { 0 };
0016 struct rvu_pfvf *pfvf;
0017
0018 pfvf = rvu_get_pfvf(rvu, pcifunc);
0019
0020
0021
0022
0023 if (!test_bit(NIXLF_INITIALIZED, &pfvf->flags))
0024 return 0;
0025
0026 ether_addr_copy(req.packet.dmac, pfvf->mac_addr);
0027 eth_broadcast_addr((u8 *)&req.mask.dmac);
0028 req.hdr.pcifunc = 0;
0029 req.vf = pcifunc;
0030 req.features = BIT_ULL(NPC_DMAC);
0031 req.channel = pfvf->rx_chan_base;
0032 req.chan_mask = chan_mask;
0033 req.intf = pfvf->nix_rx_intf;
0034 req.op = NIX_RX_ACTION_DEFAULT;
0035 req.default_rule = 1;
0036
0037 return rvu_mbox_handler_npc_install_flow(rvu, &req, &rsp);
0038 }
0039
0040 static int rvu_switch_install_tx_rule(struct rvu *rvu, u16 pcifunc, u16 entry)
0041 {
0042 struct npc_install_flow_req req = { 0 };
0043 struct npc_install_flow_rsp rsp = { 0 };
0044 struct rvu_pfvf *pfvf;
0045 u8 lbkid;
0046
0047 pfvf = rvu_get_pfvf(rvu, pcifunc);
0048
0049
0050
0051
0052 if (!test_bit(NIXLF_INITIALIZED, &pfvf->flags))
0053 return 0;
0054
0055 lbkid = pfvf->nix_blkaddr == BLKADDR_NIX0 ? 0 : 1;
0056 ether_addr_copy(req.packet.dmac, pfvf->mac_addr);
0057 eth_broadcast_addr((u8 *)&req.mask.dmac);
0058 req.hdr.pcifunc = 0;
0059 req.vf = pcifunc;
0060 req.entry = entry;
0061 req.features = BIT_ULL(NPC_DMAC);
0062 req.intf = pfvf->nix_tx_intf;
0063 req.op = NIX_TX_ACTIONOP_UCAST_CHAN;
0064 req.index = (lbkid << 8) | RVU_SWITCH_LBK_CHAN;
0065 req.set_cntr = 1;
0066
0067 return rvu_mbox_handler_npc_install_flow(rvu, &req, &rsp);
0068 }
0069
0070 static int rvu_switch_install_rules(struct rvu *rvu)
0071 {
0072 struct rvu_switch *rswitch = &rvu->rswitch;
0073 u16 start = rswitch->start_entry;
0074 struct rvu_hwinfo *hw = rvu->hw;
0075 u16 pcifunc, entry = 0;
0076 int pf, vf, numvfs;
0077 int err;
0078
0079 for (pf = 1; pf < hw->total_pfs; pf++) {
0080 if (!is_pf_cgxmapped(rvu, pf))
0081 continue;
0082
0083 pcifunc = pf << 10;
0084
0085
0086
0087
0088
0089
0090 rvu_get_nix_blkaddr(rvu, pcifunc);
0091
0092
0093
0094
0095
0096
0097
0098 err = rvu_switch_install_rx_rule(rvu, pcifunc, 0x0);
0099 if (err) {
0100 dev_err(rvu->dev, "RX rule for PF%d failed(%d)\n",
0101 pf, err);
0102 return err;
0103 }
0104
0105 err = rvu_switch_install_tx_rule(rvu, pcifunc, start + entry);
0106 if (err) {
0107 dev_err(rvu->dev, "TX rule for PF%d failed(%d)\n",
0108 pf, err);
0109 return err;
0110 }
0111
0112 rswitch->entry2pcifunc[entry++] = pcifunc;
0113
0114 rvu_get_pf_numvfs(rvu, pf, &numvfs, NULL);
0115 for (vf = 0; vf < numvfs; vf++) {
0116 pcifunc = pf << 10 | ((vf + 1) & 0x3FF);
0117 rvu_get_nix_blkaddr(rvu, pcifunc);
0118
0119 err = rvu_switch_install_rx_rule(rvu, pcifunc, 0x0);
0120 if (err) {
0121 dev_err(rvu->dev,
0122 "RX rule for PF%dVF%d failed(%d)\n",
0123 pf, vf, err);
0124 return err;
0125 }
0126
0127 err = rvu_switch_install_tx_rule(rvu, pcifunc,
0128 start + entry);
0129 if (err) {
0130 dev_err(rvu->dev,
0131 "TX rule for PF%dVF%d failed(%d)\n",
0132 pf, vf, err);
0133 return err;
0134 }
0135
0136 rswitch->entry2pcifunc[entry++] = pcifunc;
0137 }
0138 }
0139
0140 return 0;
0141 }
0142
0143 void rvu_switch_enable(struct rvu *rvu)
0144 {
0145 struct npc_mcam_alloc_entry_req alloc_req = { 0 };
0146 struct npc_mcam_alloc_entry_rsp alloc_rsp = { 0 };
0147 struct npc_delete_flow_req uninstall_req = { 0 };
0148 struct npc_mcam_free_entry_req free_req = { 0 };
0149 struct rvu_switch *rswitch = &rvu->rswitch;
0150 struct msg_rsp rsp;
0151 int ret;
0152
0153 alloc_req.contig = true;
0154 alloc_req.count = rvu->cgx_mapped_pfs + rvu->cgx_mapped_vfs;
0155 ret = rvu_mbox_handler_npc_mcam_alloc_entry(rvu, &alloc_req,
0156 &alloc_rsp);
0157 if (ret) {
0158 dev_err(rvu->dev,
0159 "Unable to allocate MCAM entries\n");
0160 goto exit;
0161 }
0162
0163 if (alloc_rsp.count != alloc_req.count) {
0164 dev_err(rvu->dev,
0165 "Unable to allocate %d MCAM entries, got %d\n",
0166 alloc_req.count, alloc_rsp.count);
0167 goto free_entries;
0168 }
0169
0170 rswitch->entry2pcifunc = kcalloc(alloc_req.count, sizeof(u16),
0171 GFP_KERNEL);
0172 if (!rswitch->entry2pcifunc)
0173 goto free_entries;
0174
0175 rswitch->used_entries = alloc_rsp.count;
0176 rswitch->start_entry = alloc_rsp.entry;
0177
0178 ret = rvu_switch_install_rules(rvu);
0179 if (ret)
0180 goto uninstall_rules;
0181
0182 return;
0183
0184 uninstall_rules:
0185 uninstall_req.start = rswitch->start_entry;
0186 uninstall_req.end = rswitch->start_entry + rswitch->used_entries - 1;
0187 rvu_mbox_handler_npc_delete_flow(rvu, &uninstall_req, &rsp);
0188 kfree(rswitch->entry2pcifunc);
0189 free_entries:
0190 free_req.all = 1;
0191 rvu_mbox_handler_npc_mcam_free_entry(rvu, &free_req, &rsp);
0192 exit:
0193 return;
0194 }
0195
0196 void rvu_switch_disable(struct rvu *rvu)
0197 {
0198 struct npc_delete_flow_req uninstall_req = { 0 };
0199 struct npc_mcam_free_entry_req free_req = { 0 };
0200 struct rvu_switch *rswitch = &rvu->rswitch;
0201 struct rvu_hwinfo *hw = rvu->hw;
0202 int pf, vf, numvfs;
0203 struct msg_rsp rsp;
0204 u16 pcifunc;
0205 int err;
0206
0207 if (!rswitch->used_entries)
0208 return;
0209
0210 for (pf = 1; pf < hw->total_pfs; pf++) {
0211 if (!is_pf_cgxmapped(rvu, pf))
0212 continue;
0213
0214 pcifunc = pf << 10;
0215 err = rvu_switch_install_rx_rule(rvu, pcifunc, 0xFFF);
0216 if (err)
0217 dev_err(rvu->dev,
0218 "Reverting RX rule for PF%d failed(%d)\n",
0219 pf, err);
0220
0221 rvu_get_pf_numvfs(rvu, pf, &numvfs, NULL);
0222 for (vf = 0; vf < numvfs; vf++) {
0223 pcifunc = pf << 10 | ((vf + 1) & 0x3FF);
0224 err = rvu_switch_install_rx_rule(rvu, pcifunc, 0xFFF);
0225 if (err)
0226 dev_err(rvu->dev,
0227 "Reverting RX rule for PF%dVF%d failed(%d)\n",
0228 pf, vf, err);
0229 }
0230 }
0231
0232 uninstall_req.start = rswitch->start_entry;
0233 uninstall_req.end = rswitch->start_entry + rswitch->used_entries - 1;
0234 free_req.all = 1;
0235 rvu_mbox_handler_npc_delete_flow(rvu, &uninstall_req, &rsp);
0236 rvu_mbox_handler_npc_mcam_free_entry(rvu, &free_req, &rsp);
0237 rswitch->used_entries = 0;
0238 kfree(rswitch->entry2pcifunc);
0239 }
0240
0241 void rvu_switch_update_rules(struct rvu *rvu, u16 pcifunc)
0242 {
0243 struct rvu_switch *rswitch = &rvu->rswitch;
0244 u32 max = rswitch->used_entries;
0245 u16 entry;
0246
0247 if (!rswitch->used_entries)
0248 return;
0249
0250 for (entry = 0; entry < max; entry++) {
0251 if (rswitch->entry2pcifunc[entry] == pcifunc)
0252 break;
0253 }
0254
0255 if (entry >= max)
0256 return;
0257
0258 rvu_switch_install_tx_rule(rvu, pcifunc, rswitch->start_entry + entry);
0259 rvu_switch_install_rx_rule(rvu, pcifunc, 0x0);
0260 }