mirror of
https://github.com/breeze303/nss-packages.git
synced 2025-12-16 08:44:52 +00:00
Backport some minor patches from QSDK 12.5 Signed-off-by: Sean Khan <datapronix@protonmail.com>
526 lines
15 KiB
Diff
526 lines
15 KiB
Diff
--- a/vlan/nss_vlan_mgr.c
|
|
+++ b/vlan/nss_vlan_mgr.c
|
|
@@ -1,9 +1,12 @@
|
|
/*
|
|
**************************************************************************
|
|
* Copyright (c) 2017-2018, 2020 The Linux Foundation. All rights reserved.
|
|
+ * Copyright (c) 2022, 2024 Qualcomm Innovation Center, Inc. All rights reserved.
|
|
+ *
|
|
* Permission to use, copy, modify, and/or distribute this software for
|
|
* any purpose with or without fee is hereby granted, provided that the
|
|
* above copyright notice and this permission notice appear in all copies.
|
|
+ *
|
|
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
|
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
|
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
|
@@ -154,15 +157,6 @@ static struct nss_vlan_pvt *nss_vlan_mgr
|
|
return NULL;
|
|
}
|
|
|
|
-/*
|
|
- * nss_vlan_mgr_instance_deref()
|
|
- */
|
|
-static void nss_vlan_mgr_instance_deref(struct nss_vlan_pvt *v)
|
|
-{
|
|
- spin_lock(&vlan_mgr_ctx.lock);
|
|
- BUG_ON(!(--v->refs));
|
|
- spin_unlock(&vlan_mgr_ctx.lock);
|
|
-}
|
|
|
|
#ifdef NSS_VLAN_MGR_PPE_SUPPORT
|
|
/*
|
|
@@ -365,22 +359,16 @@ static void nss_vlan_mgr_port_role_event
|
|
* nss_vlan_mgr_bond_configure_ppe()
|
|
* Configure PPE for bond device
|
|
*/
|
|
-static int nss_vlan_mgr_bond_configure_ppe(struct nss_vlan_pvt *v, struct net_device *bond_dev)
|
|
+static int nss_vlan_mgr_bond_configure_ppe(struct nss_vlan_pvt *v, struct net_device *bond_dev, uint32_t vsi)
|
|
{
|
|
- uint32_t vsi;
|
|
int ret = 0;
|
|
struct net_device *slave;
|
|
int32_t port;
|
|
int vlan_mgr_bond_port_role = -1;
|
|
|
|
- if (ppe_vsi_alloc(NSS_VLAN_MGR_SWITCH_ID, &vsi)) {
|
|
- nss_vlan_mgr_warn("%s: failed to allocate VSI for bond vlan device", bond_dev->name);
|
|
- return -1;
|
|
- }
|
|
-
|
|
if (nss_vlan_tx_vsi_attach_msg(v->nss_if, vsi) != NSS_TX_SUCCESS) {
|
|
nss_vlan_mgr_warn("%s: failed to attach VSI to bond vlan interface\n", bond_dev->name);
|
|
- goto free_vsi;
|
|
+ return -1;
|
|
}
|
|
|
|
/*
|
|
@@ -393,7 +381,7 @@ static int nss_vlan_mgr_bond_configure_p
|
|
if (!NSS_VLAN_PHY_PORT_CHK(port)) {
|
|
rcu_read_unlock();
|
|
nss_vlan_mgr_warn("%s: %d is not valid physical port\n", slave->name, port);
|
|
- goto free_vsi;
|
|
+ return -1;
|
|
}
|
|
|
|
/*
|
|
@@ -409,7 +397,7 @@ static int nss_vlan_mgr_bond_configure_p
|
|
* In case the bond interface has no slaves, we do not want to proceed further
|
|
*/
|
|
if (vlan_mgr_bond_port_role == -1) {
|
|
- goto free_vsi;
|
|
+ return -1;
|
|
}
|
|
|
|
/*
|
|
@@ -436,6 +424,12 @@ static int nss_vlan_mgr_bond_configure_p
|
|
rcu_read_lock();
|
|
for_each_netdev_in_bond_rcu(bond_dev, slave) {
|
|
port = nss_cmn_get_interface_number_by_dev(slave);
|
|
+ if (!NSS_VLAN_PHY_PORT_CHK(port)) {
|
|
+ rcu_read_unlock();
|
|
+ nss_vlan_mgr_warn("%s: %d is not valid physical port\n", slave->name, port);
|
|
+ return -1;
|
|
+ }
|
|
+
|
|
ret = ppe_port_vlan_vsi_set(NSS_VLAN_MGR_SWITCH_ID, v->port[port - 1], v->ppe_svid, v->ppe_cvid, vsi);
|
|
if (ret != SW_OK) {
|
|
rcu_read_unlock();
|
|
@@ -471,6 +465,12 @@ static int nss_vlan_mgr_bond_configure_p
|
|
rcu_read_lock();
|
|
for_each_netdev_in_bond_rcu(bond_dev, slave) {
|
|
port = nss_cmn_get_interface_number_by_dev(slave);
|
|
+ if (!NSS_VLAN_PHY_PORT_CHK(port)) {
|
|
+ rcu_read_unlock();
|
|
+ nss_vlan_mgr_warn("%s: %d is not valid physical port\n", slave->name, port);
|
|
+ return -1;
|
|
+ }
|
|
+
|
|
v->eg_xlt_rule.port_bitmap |= (1 << v->port[port - 1]);
|
|
ret = fal_port_vlan_trans_adv_add(NSS_VLAN_MGR_SWITCH_ID, v->port[port - 1],
|
|
FAL_PORT_VLAN_EGRESS, &v->eg_xlt_rule, &v->eg_xlt_action);
|
|
@@ -490,6 +490,11 @@ static int nss_vlan_mgr_bond_configure_p
|
|
for_each_netdev_in_bond_rcu(bond_dev, slave) {
|
|
fal_port_qinq_role_t mode;
|
|
port = nss_cmn_get_interface_number_by_dev(slave);
|
|
+ if (!NSS_VLAN_PHY_PORT_CHK(port)) {
|
|
+ rcu_read_unlock();
|
|
+ nss_vlan_mgr_warn("%s: %d is not valid physical port\n", slave->name, port);
|
|
+ return -1;
|
|
+ }
|
|
|
|
/*
|
|
* If double tag, we should set physical port as core port
|
|
@@ -513,13 +518,18 @@ static int nss_vlan_mgr_bond_configure_p
|
|
ret = NSS_VLAN_PORT_ROLE_CHANGED;
|
|
}
|
|
|
|
- v->ppe_vsi = vsi;
|
|
return ret;
|
|
|
|
delete_egress_rule:
|
|
rcu_read_lock();
|
|
for_each_netdev_in_bond_rcu(bond_dev, slave) {
|
|
port = nss_cmn_get_interface_number_by_dev(slave);
|
|
+ if (!NSS_VLAN_PHY_PORT_CHK(port)) {
|
|
+ rcu_read_unlock();
|
|
+ nss_vlan_mgr_warn("%s: %d is not valid physical port\n", slave->name, port);
|
|
+ return -1;
|
|
+ }
|
|
+
|
|
ret = fal_port_vlan_trans_adv_del(NSS_VLAN_MGR_SWITCH_ID, v->port[port - 1],
|
|
FAL_PORT_VLAN_EGRESS,
|
|
&v->eg_xlt_rule, &v->eg_xlt_action);
|
|
@@ -533,6 +543,12 @@ delete_ingress_rule:
|
|
rcu_read_lock();
|
|
for_each_netdev_in_bond_rcu(bond_dev, slave) {
|
|
port = nss_cmn_get_interface_number_by_dev(slave);
|
|
+ if (!NSS_VLAN_PHY_PORT_CHK(port)) {
|
|
+ rcu_read_unlock();
|
|
+ nss_vlan_mgr_warn("%s: %d is not valid physical port\n", slave->name, port);
|
|
+ return -1;
|
|
+ }
|
|
+
|
|
ret = ppe_port_vlan_vsi_set(NSS_VLAN_MGR_SWITCH_ID, v->port[port - 1], v->ppe_svid, v->ppe_cvid, PPE_VSI_INVALID);
|
|
if (ret != SW_OK) {
|
|
nss_vlan_mgr_warn("%px: Failed to delete ingress translation rule for port:%d, error: %d\n", v, v->port[port - 1], ret);
|
|
@@ -545,30 +561,19 @@ detach_vsi:
|
|
nss_vlan_mgr_warn("%px: Failed to detach vsi %d\n", v, vsi);
|
|
}
|
|
|
|
-free_vsi:
|
|
- if (ppe_vsi_free(NSS_VLAN_MGR_SWITCH_ID, vsi)) {
|
|
- nss_vlan_mgr_warn("%px: Failed to free VLAN VSI\n", v);
|
|
- }
|
|
-
|
|
return -1;
|
|
}
|
|
/*
|
|
* nss_vlan_mgr_configure_ppe()
|
|
* Configure PPE for physical devices
|
|
*/
|
|
-static int nss_vlan_mgr_configure_ppe(struct nss_vlan_pvt *v, struct net_device *dev)
|
|
+static int nss_vlan_mgr_configure_ppe(struct nss_vlan_pvt *v, struct net_device *dev, uint32_t vsi)
|
|
{
|
|
- uint32_t vsi;
|
|
int ret = 0;
|
|
|
|
- if (ppe_vsi_alloc(NSS_VLAN_MGR_SWITCH_ID, &vsi)) {
|
|
- nss_vlan_mgr_warn("%s: failed to allocate VSI for vlan device", dev->name);
|
|
- return -1;
|
|
- }
|
|
-
|
|
if (nss_vlan_tx_vsi_attach_msg(v->nss_if, vsi) != NSS_TX_SUCCESS) {
|
|
nss_vlan_mgr_warn("%s: failed to attach VSI to vlan interface\n", dev->name);
|
|
- goto free_vsi;
|
|
+ return -1;
|
|
}
|
|
|
|
/*
|
|
@@ -652,7 +657,6 @@ static int nss_vlan_mgr_configure_ppe(st
|
|
ret = NSS_VLAN_PORT_ROLE_CHANGED;
|
|
}
|
|
|
|
- v->ppe_vsi = vsi;
|
|
return ret;
|
|
|
|
delete_egress_rule:
|
|
@@ -674,16 +678,119 @@ detach_vsi:
|
|
nss_vlan_mgr_warn("%px: Failed to detach vsi %d\n", v, vsi);
|
|
}
|
|
|
|
-free_vsi:
|
|
- if (ppe_vsi_free(NSS_VLAN_MGR_SWITCH_ID, vsi)) {
|
|
- nss_vlan_mgr_warn("%px: Failed to free VLAN VSI\n", v);
|
|
- }
|
|
-
|
|
return -1;
|
|
}
|
|
#endif
|
|
|
|
/*
|
|
+ * nss_vlan_mgr_instance_free()
|
|
+ * Destroy vlan instance
|
|
+ */
|
|
+static void nss_vlan_mgr_instance_free(struct nss_vlan_pvt *v)
|
|
+{
|
|
+#ifdef NSS_VLAN_MGR_PPE_SUPPORT
|
|
+ int32_t i;
|
|
+ int ret = 0;
|
|
+#endif
|
|
+
|
|
+#ifdef NSS_VLAN_MGR_PPE_SUPPORT
|
|
+ if (v->ppe_vsi) {
|
|
+ /*
|
|
+ * Detach VSI
|
|
+ */
|
|
+ if (nss_vlan_tx_vsi_detach_msg(v->nss_if, v->ppe_vsi)) {
|
|
+ nss_vlan_mgr_warn("%px: Failed to detach vsi %d\n", v, v->ppe_vsi);
|
|
+ }
|
|
+
|
|
+ /*
|
|
+ * Delete ingress vlan translation rule
|
|
+ */
|
|
+ for (i = 0; i < NSS_VLAN_PHY_PORT_MAX; i++) {
|
|
+ if (!v->port[i])
|
|
+ continue;
|
|
+ ret = ppe_port_vlan_vsi_set(NSS_VLAN_MGR_SWITCH_ID, v->port[i], v->ppe_svid, v->ppe_cvid, PPE_VSI_INVALID);
|
|
+ if (ret != SW_OK)
|
|
+ nss_vlan_mgr_warn("%px: Failed to delete old ingress translation rule, error: %d\n", v, ret);
|
|
+ }
|
|
+
|
|
+ /*
|
|
+ * Delete egress vlan translation rule
|
|
+ */
|
|
+ v->eg_xlt_rule.port_bitmap = 0;
|
|
+ for (i = 0; i < NSS_VLAN_PHY_PORT_MAX; i++) {
|
|
+ if (!v->port[i])
|
|
+ continue;
|
|
+ v->eg_xlt_rule.port_bitmap |= (1 << v->port[i]);
|
|
+ ret = fal_port_vlan_trans_adv_del(NSS_VLAN_MGR_SWITCH_ID, v->port[i],
|
|
+ FAL_PORT_VLAN_EGRESS,
|
|
+ &v->eg_xlt_rule, &v->eg_xlt_action);
|
|
+ if (ret != SW_OK) {
|
|
+ nss_vlan_mgr_warn("%px: Failed to delete vlan translation rule, error:%d\n", v, ret);
|
|
+ }
|
|
+ }
|
|
+
|
|
+ /*
|
|
+ * We will always have a VSI since this is allocated in beginning
|
|
+ * of the code.
|
|
+ */
|
|
+ if (ppe_vsi_free(NSS_VLAN_MGR_SWITCH_ID, v->ppe_vsi)) {
|
|
+ nss_vlan_mgr_warn("%px: Failed to free VLAN VSI\n", v);
|
|
+ }
|
|
+ }
|
|
+
|
|
+ /*
|
|
+ * Need to change the physical port role. While adding
|
|
+ * eth0.10.20/bond0.10.20, the role of the physical port(s) changed
|
|
+ * from EDGE to CORE. So, while removing eth0.10.20/bond0.10.20, the
|
|
+ * role of the physical port(s) should be changed from CORE to EDGE.
|
|
+ */
|
|
+ for (i = 0; i < NSS_VLAN_PHY_PORT_MAX; i++) {
|
|
+ if (v->port[i]) {
|
|
+ if (nss_vlan_mgr_calculate_new_port_role(v->port[i], i)) {
|
|
+ nss_vlan_mgr_port_role_event(v->port[i], i);
|
|
+ }
|
|
+ }
|
|
+ }
|
|
+#endif
|
|
+
|
|
+ if (v->nss_if) {
|
|
+ nss_unregister_vlan_if(v->nss_if);
|
|
+ if (nss_dynamic_interface_dealloc_node(v->nss_if, NSS_DYNAMIC_INTERFACE_TYPE_VLAN) != NSS_TX_SUCCESS)
|
|
+ nss_vlan_mgr_warn("%px: Failed to dealloc vlan dynamic interface\n", v);
|
|
+ }
|
|
+
|
|
+ kfree(v);
|
|
+}
|
|
+
|
|
+/*
|
|
+ * nss_vlan_mgr_instance_deref()
|
|
+ */
|
|
+static void nss_vlan_mgr_instance_deref(struct nss_vlan_pvt *v)
|
|
+{
|
|
+ struct nss_vlan_pvt *parent = NULL;
|
|
+ spin_lock(&vlan_mgr_ctx.lock);
|
|
+ BUG_ON(v->refs == 0);
|
|
+ v->refs--;
|
|
+
|
|
+ if (v->refs) {
|
|
+ spin_unlock(&vlan_mgr_ctx.lock);
|
|
+ return;
|
|
+ }
|
|
+
|
|
+ if (!list_empty(&v->list)) {
|
|
+ list_del(&v->list);
|
|
+ }
|
|
+
|
|
+ spin_unlock(&vlan_mgr_ctx.lock);
|
|
+
|
|
+ parent = v->parent;
|
|
+ nss_vlan_mgr_instance_free(v);
|
|
+
|
|
+ if (parent)
|
|
+ nss_vlan_mgr_instance_deref(parent);
|
|
+}
|
|
+
|
|
+/*
|
|
* nss_vlan_mgr_create_instance()
|
|
* Create vlan instance
|
|
*/
|
|
@@ -816,95 +923,6 @@ static struct nss_vlan_pvt *nss_vlan_mgr
|
|
}
|
|
|
|
/*
|
|
- * nss_vlan_mgr_instance_free()
|
|
- * Destroy vlan instance
|
|
- */
|
|
-static void nss_vlan_mgr_instance_free(struct nss_vlan_pvt *v)
|
|
-{
|
|
-#ifdef NSS_VLAN_MGR_PPE_SUPPORT
|
|
- int32_t i;
|
|
- int ret = 0;
|
|
-#endif
|
|
-
|
|
- spin_lock(&vlan_mgr_ctx.lock);
|
|
- BUG_ON(--v->refs);
|
|
- if (!list_empty(&v->list)) {
|
|
- list_del(&v->list);
|
|
- }
|
|
- spin_unlock(&vlan_mgr_ctx.lock);
|
|
-
|
|
-#ifdef NSS_VLAN_MGR_PPE_SUPPORT
|
|
- if (v->ppe_vsi) {
|
|
- /*
|
|
- * Detach VSI
|
|
- */
|
|
- if (nss_vlan_tx_vsi_detach_msg(v->nss_if, v->ppe_vsi)) {
|
|
- nss_vlan_mgr_warn("%px: Failed to detach vsi %d\n", v, v->ppe_vsi);
|
|
- }
|
|
-
|
|
- /*
|
|
- * Delete ingress vlan translation rule
|
|
- */
|
|
- for (i = 0; i < NSS_VLAN_PHY_PORT_MAX; i++) {
|
|
- if (!v->port[i])
|
|
- continue;
|
|
- ret = ppe_port_vlan_vsi_set(NSS_VLAN_MGR_SWITCH_ID, v->port[i], v->ppe_svid, v->ppe_cvid, PPE_VSI_INVALID);
|
|
- if (ret != SW_OK)
|
|
- nss_vlan_mgr_warn("%px: Failed to delete old ingress translation rule, error: %d\n", v, ret);
|
|
- }
|
|
-
|
|
- /*
|
|
- * Delete egress vlan translation rule
|
|
- */
|
|
- v->eg_xlt_rule.port_bitmap = 0;
|
|
- for (i = 0; i < NSS_VLAN_PHY_PORT_MAX; i++) {
|
|
- if (!v->port[i])
|
|
- continue;
|
|
- v->eg_xlt_rule.port_bitmap |= (1 << v->port[i]);
|
|
- ret = fal_port_vlan_trans_adv_del(NSS_VLAN_MGR_SWITCH_ID, v->port[i],
|
|
- FAL_PORT_VLAN_EGRESS,
|
|
- &v->eg_xlt_rule, &v->eg_xlt_action);
|
|
- if (ret != SW_OK) {
|
|
- nss_vlan_mgr_warn("%px: Failed to delete vlan translation rule, error:%d\n", v, ret);
|
|
- }
|
|
- }
|
|
-
|
|
- /*
|
|
- * Free PPE VSI
|
|
- */
|
|
- if (ppe_vsi_free(NSS_VLAN_MGR_SWITCH_ID, v->ppe_vsi)) {
|
|
- nss_vlan_mgr_warn("%px: Failed to free VLAN VSI\n", v);
|
|
- }
|
|
- }
|
|
-
|
|
- /*
|
|
- * Need to change the physical port role. While adding
|
|
- * eth0.10.20/bond0.10.20, the role of the physical port(s) changed
|
|
- * from EDGE to CORE. So, while removing eth0.10.20/bond0.10.20, the
|
|
- * role of the physical port(s) should be changed from CORE to EDGE.
|
|
- */
|
|
- for (i = 0; i < NSS_VLAN_PHY_PORT_MAX; i++) {
|
|
- if (v->port[i]) {
|
|
- if (nss_vlan_mgr_calculate_new_port_role(v->port[i], i)) {
|
|
- nss_vlan_mgr_port_role_event(v->port[i], i);
|
|
- }
|
|
- }
|
|
- }
|
|
-#endif
|
|
-
|
|
- if (v->nss_if) {
|
|
- nss_unregister_vlan_if(v->nss_if);
|
|
- if (nss_dynamic_interface_dealloc_node(v->nss_if, NSS_DYNAMIC_INTERFACE_TYPE_VLAN) != NSS_TX_SUCCESS)
|
|
- nss_vlan_mgr_warn("%px: Failed to dealloc vlan dynamic interface\n", v);
|
|
- }
|
|
-
|
|
- if (v->parent)
|
|
- nss_vlan_mgr_instance_deref(v->parent);
|
|
-
|
|
- kfree(v);
|
|
-}
|
|
-
|
|
-/*
|
|
* nss_vlan_mgr_changemtu_event()
|
|
*/
|
|
static int nss_vlan_mgr_changemtu_event(struct netdev_notifier_info *info)
|
|
@@ -979,6 +997,7 @@ static int nss_vlan_mgr_register_event(s
|
|
struct nss_vlan_pvt *v;
|
|
int if_num;
|
|
#ifdef NSS_VLAN_MGR_PPE_SUPPORT
|
|
+ uint32_t vsi;
|
|
int ret;
|
|
#endif
|
|
uint32_t vlan_tag;
|
|
@@ -995,19 +1014,25 @@ static int nss_vlan_mgr_register_event(s
|
|
if (!v)
|
|
return NOTIFY_DONE;
|
|
|
|
+ /*
|
|
+ * Allocate the VSI here.
|
|
+ */
|
|
+#ifdef NSS_VLAN_MGR_PPE_SUPPORT
|
|
+ if (ppe_vsi_alloc(NSS_VLAN_MGR_SWITCH_ID, &vsi)) {
|
|
+ nss_vlan_mgr_warn("%s: failed to allocate VSI for vlan device", dev->name);
|
|
+ return NOTIFY_DONE;
|
|
+ }
|
|
+#endif
|
|
+
|
|
if_num = nss_dynamic_interface_alloc_node(NSS_DYNAMIC_INTERFACE_TYPE_VLAN);
|
|
if (if_num < 0) {
|
|
nss_vlan_mgr_warn("%s: failed to alloc NSS dynamic interface\n", dev->name);
|
|
- nss_vlan_mgr_instance_free(v);
|
|
- return NOTIFY_DONE;
|
|
+ goto vsi_alloc_free;
|
|
}
|
|
|
|
if (!nss_register_vlan_if(if_num, NULL, dev, 0, v)) {
|
|
nss_vlan_mgr_warn("%s: failed to register NSS dynamic interface", dev->name);
|
|
- if (nss_dynamic_interface_dealloc_node(if_num, NSS_DYNAMIC_INTERFACE_TYPE_VLAN) != NSS_TX_SUCCESS)
|
|
- nss_vlan_mgr_warn("%px: Failed to dealloc vlan dynamic interface\n", v);
|
|
- nss_vlan_mgr_instance_free(v);
|
|
- return NOTIFY_DONE;
|
|
+ goto free_dynamic_interface;
|
|
}
|
|
v->nss_if = if_num;
|
|
|
|
@@ -1021,26 +1046,25 @@ static int nss_vlan_mgr_register_event(s
|
|
|
|
#ifdef NSS_VLAN_MGR_PPE_SUPPORT
|
|
if (!is_bond_master)
|
|
- ret = nss_vlan_mgr_configure_ppe(v, dev);
|
|
+ ret = nss_vlan_mgr_configure_ppe(v, dev, vsi);
|
|
else
|
|
- ret = nss_vlan_mgr_bond_configure_ppe(v, real_dev);
|
|
+ ret = nss_vlan_mgr_bond_configure_ppe(v, real_dev, vsi);
|
|
|
|
if (ret < 0) {
|
|
- nss_vlan_mgr_instance_free(v);
|
|
- return NOTIFY_DONE;
|
|
+ goto vlan_instance_free;
|
|
}
|
|
+
|
|
+ v->ppe_vsi = vsi;
|
|
#endif
|
|
|
|
if (nss_vlan_tx_set_mac_addr_msg(v->nss_if, v->dev_addr) != NSS_TX_SUCCESS) {
|
|
nss_vlan_mgr_warn("%s: failed to set mac_addr msg\n", dev->name);
|
|
- nss_vlan_mgr_instance_free(v);
|
|
- return NOTIFY_DONE;
|
|
+ goto vlan_instance_free;
|
|
}
|
|
|
|
if (nss_vlan_tx_set_mtu_msg(v->nss_if, v->mtu) != NSS_TX_SUCCESS) {
|
|
nss_vlan_mgr_warn("%s: failed to set mtu msg\n", dev->name);
|
|
- nss_vlan_mgr_instance_free(v);
|
|
- return NOTIFY_DONE;
|
|
+ goto vlan_instance_free;
|
|
}
|
|
|
|
vlan_tag = (v->tpid << NSS_VLAN_TPID_SHIFT | v->vid);
|
|
@@ -1049,8 +1073,7 @@ static int nss_vlan_mgr_register_event(s
|
|
(v->parent ? v->parent->nss_if : port_if),
|
|
port_if) != NSS_TX_SUCCESS) {
|
|
nss_vlan_mgr_warn("%s: failed to add vlan in nss\n", dev->name);
|
|
- nss_vlan_mgr_instance_free(v);
|
|
- return NOTIFY_DONE;
|
|
+ goto vlan_instance_free;
|
|
}
|
|
|
|
spin_lock(&vlan_mgr_ctx.lock);
|
|
@@ -1078,6 +1101,21 @@ static int nss_vlan_mgr_register_event(s
|
|
}
|
|
#endif
|
|
return NOTIFY_DONE;
|
|
+
|
|
+free_dynamic_interface:
|
|
+ if (nss_dynamic_interface_dealloc_node(if_num, NSS_DYNAMIC_INTERFACE_TYPE_VLAN) != NSS_TX_SUCCESS)
|
|
+ nss_vlan_mgr_warn("%px: Failed to dealloc vlan dynamic interface\n", v);
|
|
+
|
|
+vsi_alloc_free:
|
|
+#ifdef NSS_VLAN_MGR_PPE_SUPPORT
|
|
+ if (ppe_vsi_free(NSS_VLAN_MGR_SWITCH_ID, v->ppe_vsi)) {
|
|
+ nss_vlan_mgr_warn("%px: Failed to free VLAN VSI\n", v);
|
|
+ }
|
|
+#endif
|
|
+
|
|
+vlan_instance_free:
|
|
+ nss_vlan_mgr_instance_free(v);
|
|
+ return NOTIFY_DONE;
|
|
}
|
|
|
|
/*
|
|
@@ -1102,9 +1140,9 @@ static int nss_vlan_mgr_unregister_event
|
|
nss_vlan_mgr_instance_deref(v);
|
|
|
|
/*
|
|
- * Free instance
|
|
+ * Release reference take during register_event
|
|
*/
|
|
- nss_vlan_mgr_instance_free(v);
|
|
+ nss_vlan_mgr_instance_deref(v);
|
|
|
|
return NOTIFY_DONE;
|
|
}
|