aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSunil Goutham <sgoutham@marvell.com>2018-10-22 13:55:55 -0400
committerDavid S. Miller <davem@davemloft.net>2018-10-22 23:15:38 -0400
commit4b05528ebf0c3ffd61543cfcca78844f05d8eb9d (patch)
treed812cb4126823bc07fcaba50e82f254f9ec983ba
parent52d3d327a2595be7b69c956b45ad44de4ea6f692 (diff)
octeontx2-af: Update bcast list upon NIXLF alloc/free
Upon NIXLF ALLOC/FREE, add or remove corresponding PF_FUNC from the broadcast packet replication list of the CGX LMAC mapped RVU PF. Signed-off-by: Sunil Goutham <sgoutham@marvell.com> Signed-off-by: David S. Miller <davem@davemloft.net>
-rw-r--r--drivers/net/ethernet/marvell/octeontx2/af/rvu_nix.c133
1 files changed, 133 insertions, 0 deletions
diff --git a/drivers/net/ethernet/marvell/octeontx2/af/rvu_nix.c b/drivers/net/ethernet/marvell/octeontx2/af/rvu_nix.c
index 947424a9600f..833328330519 100644
--- a/drivers/net/ethernet/marvell/octeontx2/af/rvu_nix.c
+++ b/drivers/net/ethernet/marvell/octeontx2/af/rvu_nix.c
@@ -16,6 +16,8 @@
16#include "rvu.h" 16#include "rvu.h"
17#include "cgx.h" 17#include "cgx.h"
18 18
19static int nix_update_bcast_mce_list(struct rvu *rvu, u16 pcifunc, bool add);
20
19enum mc_tbl_sz { 21enum mc_tbl_sz {
20 MC_TBL_SZ_256, 22 MC_TBL_SZ_256,
21 MC_TBL_SZ_512, 23 MC_TBL_SZ_512,
@@ -108,6 +110,7 @@ static int nix_interface_init(struct rvu *rvu, u16 pcifunc, int type, int nixlf)
108 struct rvu_pfvf *pfvf = rvu_get_pfvf(rvu, pcifunc); 110 struct rvu_pfvf *pfvf = rvu_get_pfvf(rvu, pcifunc);
109 u8 cgx_id, lmac_id; 111 u8 cgx_id, lmac_id;
110 int pkind, pf; 112 int pkind, pf;
113 int err;
111 114
112 pf = rvu_get_pf(pcifunc); 115 pf = rvu_get_pf(pcifunc);
113 if (!is_pf_cgxmapped(rvu, pf) && type != NIX_INTF_TYPE_LBK) 116 if (!is_pf_cgxmapped(rvu, pf) && type != NIX_INTF_TYPE_LBK)
@@ -130,9 +133,30 @@ static int nix_interface_init(struct rvu *rvu, u16 pcifunc, int type, int nixlf)
130 case NIX_INTF_TYPE_LBK: 133 case NIX_INTF_TYPE_LBK:
131 break; 134 break;
132 } 135 }
136
137 /* Add this PF_FUNC to bcast pkt replication list */
138 err = nix_update_bcast_mce_list(rvu, pcifunc, true);
139 if (err) {
140 dev_err(rvu->dev,
141 "Bcast list, failed to enable PF_FUNC 0x%x\n",
142 pcifunc);
143 }
133 return 0; 144 return 0;
134} 145}
135 146
147static void nix_interface_deinit(struct rvu *rvu, u16 pcifunc, u8 nixlf)
148{
149 int err;
150
151 /* Remove this PF_FUNC from bcast pkt replication list */
152 err = nix_update_bcast_mce_list(rvu, pcifunc, false);
153 if (err) {
154 dev_err(rvu->dev,
155 "Bcast list, failed to disable PF_FUNC 0x%x\n",
156 pcifunc);
157 }
158}
159
136static void nix_setup_lso_tso_l3(struct rvu *rvu, int blkaddr, 160static void nix_setup_lso_tso_l3(struct rvu *rvu, int blkaddr,
137 u64 format, bool v4, u64 *fidx) 161 u64 format, bool v4, u64 *fidx)
138{ 162{
@@ -786,6 +810,8 @@ int rvu_mbox_handler_NIX_LF_FREE(struct rvu *rvu, struct msg_req *req,
786 if (nixlf < 0) 810 if (nixlf < 0)
787 return NIX_AF_ERR_AF_LF_INVALID; 811 return NIX_AF_ERR_AF_LF_INVALID;
788 812
813 nix_interface_deinit(rvu, pcifunc, nixlf);
814
789 /* Reset this NIX LF */ 815 /* Reset this NIX LF */
790 err = rvu_lf_reset(rvu, block, nixlf); 816 err = rvu_lf_reset(rvu, block, nixlf);
791 if (err) { 817 if (err) {
@@ -1147,6 +1173,113 @@ static int nix_setup_mce(struct rvu *rvu, int mce, u8 op,
1147 return 0; 1173 return 0;
1148} 1174}
1149 1175
1176static int nix_update_mce_list(struct nix_mce_list *mce_list,
1177 u16 pcifunc, int idx, bool add)
1178{
1179 struct mce *mce, *tail = NULL;
1180 bool delete = false;
1181
1182 /* Scan through the current list */
1183 hlist_for_each_entry(mce, &mce_list->head, node) {
1184 /* If already exists, then delete */
1185 if (mce->pcifunc == pcifunc && !add) {
1186 delete = true;
1187 break;
1188 }
1189 tail = mce;
1190 }
1191
1192 if (delete) {
1193 hlist_del(&mce->node);
1194 kfree(mce);
1195 mce_list->count--;
1196 return 0;
1197 }
1198
1199 if (!add)
1200 return 0;
1201
1202 /* Add a new one to the list, at the tail */
1203 mce = kzalloc(sizeof(*mce), GFP_KERNEL);
1204 if (!mce)
1205 return -ENOMEM;
1206 mce->idx = idx;
1207 mce->pcifunc = pcifunc;
1208 if (!tail)
1209 hlist_add_head(&mce->node, &mce_list->head);
1210 else
1211 hlist_add_behind(&mce->node, &tail->node);
1212 mce_list->count++;
1213 return 0;
1214}
1215
1216static int nix_update_bcast_mce_list(struct rvu *rvu, u16 pcifunc, bool add)
1217{
1218 int err = 0, idx, next_idx, count;
1219 struct nix_mce_list *mce_list;
1220 struct mce *mce, *next_mce;
1221 struct nix_mcast *mcast;
1222 struct nix_hw *nix_hw;
1223 struct rvu_pfvf *pfvf;
1224 int blkaddr;
1225
1226 blkaddr = rvu_get_blkaddr(rvu, BLKTYPE_NIX, pcifunc);
1227 if (blkaddr < 0)
1228 return 0;
1229
1230 nix_hw = get_nix_hw(rvu->hw, blkaddr);
1231 if (!nix_hw)
1232 return 0;
1233
1234 mcast = &nix_hw->mcast;
1235
1236 /* Get this PF/VF func's MCE index */
1237 pfvf = rvu_get_pfvf(rvu, pcifunc & ~RVU_PFVF_FUNC_MASK);
1238 idx = pfvf->bcast_mce_idx + (pcifunc & RVU_PFVF_FUNC_MASK);
1239
1240 mce_list = &pfvf->bcast_mce_list;
1241 if (idx > (pfvf->bcast_mce_idx + mce_list->max)) {
1242 dev_err(rvu->dev,
1243 "%s: Idx %d > max MCE idx %d, for PF%d bcast list\n",
1244 __func__, idx, mce_list->max,
1245 pcifunc >> RVU_PFVF_PF_SHIFT);
1246 return -EINVAL;
1247 }
1248
1249 spin_lock(&mcast->mce_lock);
1250
1251 err = nix_update_mce_list(mce_list, pcifunc, idx, add);
1252 if (err)
1253 goto end;
1254
1255 /* Disable MCAM entry in NPC */
1256
1257 if (!mce_list->count)
1258 goto end;
1259 count = mce_list->count;
1260
1261 /* Dump the updated list to HW */
1262 hlist_for_each_entry(mce, &mce_list->head, node) {
1263 next_idx = 0;
1264 count--;
1265 if (count) {
1266 next_mce = hlist_entry(mce->node.next,
1267 struct mce, node);
1268 next_idx = next_mce->idx;
1269 }
1270 /* EOL should be set in last MCE */
1271 err = nix_setup_mce(rvu, mce->idx,
1272 NIX_AQ_INSTOP_WRITE, mce->pcifunc,
1273 next_idx, count ? false : true);
1274 if (err)
1275 goto end;
1276 }
1277
1278end:
1279 spin_unlock(&mcast->mce_lock);
1280 return err;
1281}
1282
1150static int nix_setup_bcast_tables(struct rvu *rvu, struct nix_hw *nix_hw) 1283static int nix_setup_bcast_tables(struct rvu *rvu, struct nix_hw *nix_hw)
1151{ 1284{
1152 struct nix_mcast *mcast = &nix_hw->mcast; 1285 struct nix_mcast *mcast = &nix_hw->mcast;