roc_nix_maxsqesz_w8 = NIX_MAXSQESZ_W8,
};
+enum roc_nix_vlan_type {
+ ROC_NIX_VLAN_TYPE_INNER = 0x01,
+ ROC_NIX_VLAN_TYPE_OUTER = 0x02,
+};
+
+struct roc_nix_vlan_config {
+ uint32_t type;
+ union {
+ struct {
+ uint32_t vtag_inner;
+ uint32_t vtag_outer;
+ } vlan;
+
+ struct {
+ int idx_inner;
+ int idx_outer;
+ } mcam;
+ };
+};
+
/* Range to adjust PTP frequency. Valid range is
* (-ROC_NIX_PTP_FREQ_ADJUST, ROC_NIX_PTP_FREQ_ADJUST)
*/
ptp_info_update_t ptp_update);
void __roc_api roc_nix_ptp_info_cb_unregister(struct roc_nix *roc_nix);
+/* VLAN */
+int __roc_api
+roc_nix_vlan_mcam_entry_read(struct roc_nix *roc_nix, uint32_t index,
+ struct npc_mcam_read_entry_rsp **rsp);
+int __roc_api roc_nix_vlan_mcam_entry_write(struct roc_nix *roc_nix,
+ uint32_t index,
+ struct mcam_entry *entry,
+ uint8_t intf, uint8_t enable);
+int __roc_api roc_nix_vlan_mcam_entry_alloc_and_write(struct roc_nix *roc_nix,
+ struct mcam_entry *entry,
+ uint8_t intf,
+ uint8_t priority,
+ uint8_t ref_entry);
+int __roc_api roc_nix_vlan_mcam_entry_free(struct roc_nix *roc_nix,
+ uint32_t index);
+int __roc_api roc_nix_vlan_mcam_entry_ena_dis(struct roc_nix *roc_nix,
+ uint32_t index, const int enable);
+int __roc_api roc_nix_vlan_strip_vtag_ena_dis(struct roc_nix *roc_nix,
+ bool enable);
+int __roc_api roc_nix_vlan_insert_ena_dis(struct roc_nix *roc_nix,
+ struct roc_nix_vlan_config *vlan_cfg,
+ uint64_t *mcam_index, bool enable);
+int __roc_api roc_nix_vlan_tpid_set(struct roc_nix *roc_nix, uint32_t type,
+ uint16_t tpid);
+
/* MCAST*/
int __roc_api roc_nix_mcast_mcam_entry_alloc(struct roc_nix *roc_nix,
uint16_t nb_entries,
--- /dev/null
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright(C) 2021 Marvell.
+ */
+
+#include "roc_api.h"
+#include "roc_priv.h"
+
+static inline struct mbox *
+get_mbox(struct roc_nix *roc_nix)
+{
+ struct nix *nix = roc_nix_to_nix_priv(roc_nix);
+ struct dev *dev = &nix->dev;
+
+ return dev->mbox;
+}
+
+int
+roc_nix_vlan_mcam_entry_read(struct roc_nix *roc_nix, uint32_t index,
+ struct npc_mcam_read_entry_rsp **rsp)
+{
+ struct mbox *mbox = get_mbox(roc_nix);
+ struct npc_mcam_read_entry_req *req;
+ int rc = -ENOSPC;
+
+ req = mbox_alloc_msg_npc_mcam_read_entry(mbox);
+ if (req == NULL)
+ return rc;
+ req->entry = index;
+
+ return mbox_process_msg(mbox, (void **)rsp);
+}
+
+int
+roc_nix_vlan_mcam_entry_write(struct roc_nix *roc_nix, uint32_t index,
+ struct mcam_entry *entry, uint8_t intf,
+ uint8_t enable)
+{
+ struct mbox *mbox = get_mbox(roc_nix);
+ struct npc_mcam_write_entry_req *req;
+ struct msghdr *rsp;
+ int rc = -ENOSPC;
+
+ req = mbox_alloc_msg_npc_mcam_write_entry(mbox);
+ if (req == NULL)
+ return rc;
+ req->entry = index;
+ req->intf = intf;
+ req->enable_entry = enable;
+ mbox_memcpy(&req->entry_data, entry, sizeof(struct mcam_entry));
+
+ return mbox_process_msg(mbox, (void *)&rsp);
+}
+
+int
+roc_nix_vlan_mcam_entry_alloc_and_write(struct roc_nix *roc_nix,
+ struct mcam_entry *entry, uint8_t intf,
+ uint8_t priority, uint8_t ref_entry)
+{
+ struct npc_mcam_alloc_and_write_entry_req *req;
+ struct npc_mcam_alloc_and_write_entry_rsp *rsp;
+ struct mbox *mbox = get_mbox(roc_nix);
+ int rc = -ENOSPC;
+
+ req = mbox_alloc_msg_npc_mcam_alloc_and_write_entry(mbox);
+ if (req == NULL)
+ return rc;
+ req->priority = priority;
+ req->ref_entry = ref_entry;
+ req->intf = intf;
+ req->enable_entry = true;
+ mbox_memcpy(&req->entry_data, entry, sizeof(struct mcam_entry));
+
+ rc = mbox_process_msg(mbox, (void *)&rsp);
+ if (rc)
+ return rc;
+
+ return rsp->entry;
+}
+
+int
+roc_nix_vlan_mcam_entry_free(struct roc_nix *roc_nix, uint32_t index)
+{
+ struct mbox *mbox = get_mbox(roc_nix);
+ struct npc_mcam_free_entry_req *req;
+ int rc = -ENOSPC;
+
+ req = mbox_alloc_msg_npc_mcam_free_entry(mbox);
+ if (req == NULL)
+ return rc;
+ req->entry = index;
+
+ return mbox_process_msg(mbox, NULL);
+}
+
+int
+roc_nix_vlan_mcam_entry_ena_dis(struct roc_nix *roc_nix, uint32_t index,
+ const int enable)
+{
+ struct npc_mcam_ena_dis_entry_req *req;
+ struct mbox *mbox = get_mbox(roc_nix);
+ int rc = -ENOSPC;
+
+ if (enable) {
+ req = mbox_alloc_msg_npc_mcam_ena_entry(mbox);
+ if (req == NULL)
+ return rc;
+ } else {
+ req = mbox_alloc_msg_npc_mcam_dis_entry(mbox);
+ if (req == NULL)
+ return rc;
+ }
+
+ req->entry = index;
+ return mbox_process_msg(mbox, NULL);
+}
+
+int
+roc_nix_vlan_strip_vtag_ena_dis(struct roc_nix *roc_nix, bool enable)
+{
+ struct mbox *mbox = get_mbox(roc_nix);
+ struct nix_vtag_config *vtag_cfg;
+ int rc = -ENOSPC;
+
+ vtag_cfg = mbox_alloc_msg_nix_vtag_cfg(mbox);
+ if (vtag_cfg == NULL)
+ return rc;
+ vtag_cfg->vtag_size = NIX_VTAGSIZE_T4;
+ vtag_cfg->cfg_type = 1; /* Rx VLAN configuration */
+ vtag_cfg->rx.capture_vtag = 1; /* Always capture */
+ vtag_cfg->rx.vtag_type = 0; /* Use index 0 */
+
+ if (enable)
+ vtag_cfg->rx.strip_vtag = 1;
+ else
+ vtag_cfg->rx.strip_vtag = 0;
+
+ return mbox_process(mbox);
+}
+
+int
+roc_nix_vlan_insert_ena_dis(struct roc_nix *roc_nix,
+ struct roc_nix_vlan_config *vlan_cfg,
+ uint64_t *mcam_index, bool enable)
+{
+ struct mbox *mbox = get_mbox(roc_nix);
+ struct nix_vtag_config *vtag_cfg;
+ struct nix_vtag_config_rsp *rsp;
+ int rc = -ENOSPC;
+
+ vtag_cfg = mbox_alloc_msg_nix_vtag_cfg(mbox);
+ if (vtag_cfg == NULL)
+ return rc;
+ vtag_cfg->cfg_type = 0; /* Tx VLAN configuration */
+ vtag_cfg->vtag_size = NIX_VTAGSIZE_T4;
+
+ if (enable) {
+ if (vlan_cfg->type & ROC_NIX_VLAN_TYPE_INNER) {
+ vtag_cfg->tx.vtag0 = vlan_cfg->vlan.vtag_inner;
+ vtag_cfg->tx.cfg_vtag0 = true;
+ }
+ if (vlan_cfg->type & ROC_NIX_VLAN_TYPE_OUTER) {
+ vtag_cfg->tx.vtag1 = vlan_cfg->vlan.vtag_outer;
+ vtag_cfg->tx.cfg_vtag1 = true;
+ }
+ } else {
+ if (vlan_cfg->type & ROC_NIX_VLAN_TYPE_INNER) {
+ vtag_cfg->tx.vtag0_idx = vlan_cfg->mcam.idx_inner;
+ vtag_cfg->tx.free_vtag0 = true;
+ }
+ if (vlan_cfg->type & ROC_NIX_VLAN_TYPE_OUTER) {
+ vtag_cfg->tx.vtag1_idx = vlan_cfg->mcam.idx_outer;
+ vtag_cfg->tx.free_vtag1 = true;
+ }
+ }
+
+ rc = mbox_process_msg(mbox, (void *)&rsp);
+ if (rc)
+ return rc;
+
+ if (enable)
+ *mcam_index =
+ (((uint64_t)rsp->vtag1_idx << 32) | rsp->vtag0_idx);
+
+ return 0;
+}
+
+int
+roc_nix_vlan_tpid_set(struct roc_nix *roc_nix, uint32_t type, uint16_t tpid)
+{
+ struct mbox *mbox = get_mbox(roc_nix);
+ struct nix_set_vlan_tpid *tpid_cfg;
+ int rc = -ENOSPC;
+
+ tpid_cfg = mbox_alloc_msg_nix_set_vlan_tpid(mbox);
+ if (tpid_cfg == NULL)
+ return rc;
+ tpid_cfg->tpid = tpid;
+
+ if (type & ROC_NIX_VLAN_TYPE_OUTER)
+ tpid_cfg->vlan_type = NIX_VLAN_TYPE_OUTER;
+ else
+ tpid_cfg->vlan_type = NIX_VLAN_TYPE_INNER;
+
+ return mbox_process(mbox);
+}