nss-packages-breeze303/qca-nss-clients/patches-11.4/0027-vlan-backport-12.5.patch
Sean Khan f7d8d21b3d nss-clients: Backport 12.5 changes
Backport some minor patches from QSDK 12.5

Signed-off-by: Sean Khan <datapronix@protonmail.com>
2024-07-08 10:08:59 -04:00

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;
}