if (!sa_base)
return 0;
+ /* Get SA size */
+ sz = roc_nix_inl_inb_sa_sz(roc_nix, inb_inl_dev);
+ if (!sz)
+ return 0;
+
+ if (roc_nix->custom_sa_action)
+ return (sa_base + (spi * sz));
+
/* Check if SPI is in range */
mask = roc_nix_inl_inb_spi_range(roc_nix, inb_inl_dev, &min_spi,
&max_spi);
plt_warn("Inbound SA SPI %u not in range (%u..%u)", spi,
min_spi, max_spi);
- /* Get SA size */
- sz = roc_nix_inl_inb_sa_sz(roc_nix, inb_inl_dev);
- if (!sz)
- return 0;
-
/* Basic logic of SPI->SA for now */
return (sa_base + ((spi & mask) * sz));
}
return 0;
}
+static int
+npc_parse_msns_action(struct roc_npc *roc_npc, const struct roc_npc_action *act,
+ struct roc_npc_flow *flow, uint8_t *has_msns_action)
+{
+ const struct roc_npc_sec_action *sec_action;
+ union {
+ uint64_t reg;
+ union nix_rx_vtag_action_u act;
+ } vtag_act;
+
+ if (roc_npc->roc_nix->custom_sa_action == 0 ||
+ roc_model_is_cn9k() == 1 || act->conf == NULL)
+ return 0;
+
+ *has_msns_action = true;
+ sec_action = act->conf;
+
+ vtag_act.reg = 0;
+ vtag_act.act.sa_xor = sec_action->sa_xor;
+ vtag_act.act.sa_hi = sec_action->sa_hi;
+ vtag_act.act.sa_lo = sec_action->sa_lo;
+
+ switch (sec_action->alg) {
+ case ROC_NPC_SEC_ACTION_ALG0:
+ break;
+ case ROC_NPC_SEC_ACTION_ALG1:
+ vtag_act.act.vtag1_valid = false;
+ vtag_act.act.vtag1_lid = ROC_NPC_SEC_ACTION_ALG1;
+ break;
+ case ROC_NPC_SEC_ACTION_ALG2:
+ vtag_act.act.vtag1_valid = false;
+ vtag_act.act.vtag1_lid = ROC_NPC_SEC_ACTION_ALG2;
+ break;
+ default:
+ return -1;
+ }
+
+ flow->vtag_action = vtag_act.reg;
+
+ return 0;
+}
+
static int
npc_parse_actions(struct roc_npc *roc_npc, const struct roc_npc_attr *attr,
const struct roc_npc_action actions[],
const struct roc_npc_action_queue *act_q;
const struct roc_npc_action_vf *vf_act;
bool vlan_insert_action = false;
+ uint8_t has_msns_act = 0;
int sel_act, req_act = 0;
uint16_t pf_func, vf_id;
int errcode = 0;
int mark = 0;
int rq = 0;
+ int rc = 0;
/* Initialize actions */
flow->ctr_id = NPC_COUNTER_NONE;
rq = 0;
pf_func = nix_inl_dev_pffunc_get();
}
+ rc = npc_parse_msns_action(roc_npc, actions, flow,
+ &has_msns_act);
+ if (rc) {
+ errcode = NPC_ERR_ACTION_NOTSUP;
+ goto err_exit;
+ }
break;
case ROC_NPC_ACTION_TYPE_VLAN_STRIP:
req_act |= ROC_NPC_ACTION_TYPE_VLAN_STRIP;
goto err_exit;
}
+ if (has_msns_act && (vlan_insert_action ||
+ (req_act & ROC_NPC_ACTION_TYPE_VLAN_STRIP))) {
+ plt_err("Both MSNS and VLAN insert/strip action can't be supported"
+ " together");
+ errcode = NPC_ERR_ACTION_NOTSUP;
+ goto err_exit;
+ }
+
/* Both STRIP and INSERT actions are not supported */
if (vlan_insert_action && (req_act & ROC_NPC_ACTION_TYPE_VLAN_STRIP)) {
errcode = NPC_ERR_ACTION_NOTSUP;
uint32_t mtr_id; /**< Meter id to be applied. > */
};
+enum roc_npc_sec_action_alg {
+ ROC_NPC_SEC_ACTION_ALG0,
+ ROC_NPC_SEC_ACTION_ALG1,
+ ROC_NPC_SEC_ACTION_ALG2,
+ ROC_NPC_SEC_ACTION_ALG3,
+};
+
+struct roc_npc_sec_action {
+ /* Used as lookup result for ALG3 */
+ uint32_t sa_index;
+ /* When true XOR initial SA_INDEX with SA_HI/SA_LO to get SA_MCAM */
+ bool sa_xor;
+ uint16_t sa_hi, sa_lo;
+ /* Determines alg to be applied post SA_MCAM computation with/without
+ * XOR
+ */
+ enum roc_npc_sec_action_alg alg;
+};
+
struct roc_npc_attr {
uint32_t priority; /**< Rule priority level within group. */
uint32_t ingress : 1; /**< Rule applies to ingress traffic. */