summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--drivers/net/ethernet/rocker/rocker.c49
1 files changed, 26 insertions, 23 deletions
diff --git a/drivers/net/ethernet/rocker/rocker.c b/drivers/net/ethernet/rocker/rocker.c
index 0f5e962d691c..701ffc200917 100644
--- a/drivers/net/ethernet/rocker/rocker.c
+++ b/drivers/net/ethernet/rocker/rocker.c
@@ -2909,9 +2909,13 @@ static struct rocker_neigh_tbl_entry *
}
static void _rocker_neigh_add(struct rocker *rocker,
+ enum switchdev_trans trans,
struct rocker_neigh_tbl_entry *entry)
{
- entry->index = rocker->neigh_tbl_next_index++;
+ entry->index = rocker->neigh_tbl_next_index;
+ if (trans == SWITCHDEV_TRANS_PREPARE)
+ return;
+ rocker->neigh_tbl_next_index++;
entry->ref_count++;
hash_add(rocker->neigh_tbl, &entry->entry,
be32_to_cpu(entry->ip_addr));
@@ -2921,6 +2925,8 @@ static void _rocker_neigh_del(struct rocker_port *rocker_port,
enum switchdev_trans trans,
struct rocker_neigh_tbl_entry *entry)
{
+ if (trans == SWITCHDEV_TRANS_PREPARE)
+ return;
if (--entry->ref_count == 0) {
hash_del(&entry->entry);
rocker_port_kfree(rocker_port, trans, entry);
@@ -2928,12 +2934,13 @@ static void _rocker_neigh_del(struct rocker_port *rocker_port,
}
static void _rocker_neigh_update(struct rocker_neigh_tbl_entry *entry,
+ enum switchdev_trans trans,
u8 *eth_dst, bool ttl_check)
{
if (eth_dst) {
ether_addr_copy(entry->eth_dst, eth_dst);
entry->ttl_check = ttl_check;
- } else {
+ } else if (trans != SWITCHDEV_TRANS_PREPARE) {
entry->ref_count++;
}
}
@@ -2973,12 +2980,12 @@ static int rocker_port_ipv4_neigh(struct rocker_port *rocker_port,
entry->dev = rocker_port->dev;
ether_addr_copy(entry->eth_dst, eth_dst);
entry->ttl_check = true;
- _rocker_neigh_add(rocker, entry);
+ _rocker_neigh_add(rocker, trans, entry);
} else if (removing) {
memcpy(entry, found, sizeof(*entry));
_rocker_neigh_del(rocker_port, trans, found);
} else if (updating) {
- _rocker_neigh_update(found, eth_dst, true);
+ _rocker_neigh_update(found, trans, eth_dst, true);
memcpy(entry, found, sizeof(*entry));
} else {
err = -ENOENT;
@@ -3089,13 +3096,13 @@ static int rocker_port_ipv4_nh(struct rocker_port *rocker_port,
if (adding) {
entry->ip_addr = ip_addr;
entry->dev = rocker_port->dev;
- _rocker_neigh_add(rocker, entry);
+ _rocker_neigh_add(rocker, trans, entry);
*index = entry->index;
resolved = false;
} else if (removing) {
_rocker_neigh_del(rocker_port, trans, found);
} else if (updating) {
- _rocker_neigh_update(found, NULL, false);
+ _rocker_neigh_update(found, trans, NULL, false);
resolved = !is_zero_ether_addr(found->eth_dst);
} else {
err = -ENOENT;
@@ -3612,9 +3619,11 @@ static int rocker_port_fdb(struct rocker_port *rocker_port,
if (removing && found) {
rocker_port_kfree(rocker_port, trans, fdb);
- hash_del(&found->entry);
+ if (trans != SWITCHDEV_TRANS_PREPARE)
+ hash_del(&found->entry);
} else if (!removing && !found) {
- hash_add(rocker->fdb_tbl, &fdb->entry, fdb->key_crc32);
+ if (trans != SWITCHDEV_TRANS_PREPARE)
+ hash_add(rocker->fdb_tbl, &fdb->entry, fdb->key_crc32);
}
spin_unlock_irqrestore(&rocker->fdb_tbl_lock, lock_flags);
@@ -3658,7 +3667,8 @@ static int rocker_port_fdb_flush(struct rocker_port *rocker_port,
found->key.vlan_id);
if (err)
goto err_out;
- hash_del(&found->entry);
+ if (trans != SWITCHDEV_TRANS_PREPARE)
+ hash_del(&found->entry);
}
err_out:
@@ -3843,7 +3853,6 @@ rocker_internal_vlan_tbl_find(struct rocker *rocker, int ifindex)
}
static __be16 rocker_port_internal_vlan_id_get(struct rocker_port *rocker_port,
- enum switchdev_trans trans,
int ifindex)
{
struct rocker *rocker = rocker_port->rocker;
@@ -3852,7 +3861,7 @@ static __be16 rocker_port_internal_vlan_id_get(struct rocker_port *rocker_port,
unsigned long lock_flags;
int i;
- entry = rocker_port_kzalloc(rocker_port, trans, sizeof(*entry));
+ entry = kzalloc(sizeof(*entry), GFP_KERNEL);
if (!entry)
return 0;
@@ -3862,7 +3871,7 @@ static __be16 rocker_port_internal_vlan_id_get(struct rocker_port *rocker_port,
found = rocker_internal_vlan_tbl_find(rocker, ifindex);
if (found) {
- rocker_port_kfree(rocker_port, trans, entry);
+ kfree(entry);
goto found;
}
@@ -3886,7 +3895,6 @@ found:
}
static void rocker_port_internal_vlan_id_put(struct rocker_port *rocker_port,
- enum switchdev_trans trans,
int ifindex)
{
struct rocker *rocker = rocker_port->rocker;
@@ -3908,7 +3916,7 @@ static void rocker_port_internal_vlan_id_put(struct rocker_port *rocker_port,
bit = ntohs(found->vlan_id) - ROCKER_INTERNAL_VLAN_ID_BASE;
clear_bit(bit, rocker->internal_vlan_bitmap);
hash_del(&found->entry);
- rocker_port_kfree(rocker_port, trans, found);
+ kfree(found);
}
not_found:
@@ -4894,9 +4902,7 @@ static int rocker_probe_port(struct rocker *rocker, unsigned int port_number)
rocker_port_set_learning(rocker_port, SWITCHDEV_TRANS_NONE);
rocker_port->internal_vlan_id =
- rocker_port_internal_vlan_id_get(rocker_port,
- SWITCHDEV_TRANS_NONE,
- dev->ifindex);
+ rocker_port_internal_vlan_id_get(rocker_port, dev->ifindex);
err = rocker_port_ig_tbl(rocker_port, SWITCHDEV_TRANS_NONE, 0);
if (err) {
dev_err(&pdev->dev, "install ig port table failed\n");
@@ -5144,7 +5150,7 @@ static int rocker_port_bridge_join(struct rocker_port *rocker_port,
{
int err;
- rocker_port_internal_vlan_id_put(rocker_port, SWITCHDEV_TRANS_NONE,
+ rocker_port_internal_vlan_id_put(rocker_port,
rocker_port->dev->ifindex);
rocker_port->bridge_dev = bridge;
@@ -5155,9 +5161,7 @@ static int rocker_port_bridge_join(struct rocker_port *rocker_port,
if (err)
return err;
rocker_port->internal_vlan_id =
- rocker_port_internal_vlan_id_get(rocker_port,
- SWITCHDEV_TRANS_NONE,
- bridge->ifindex);
+ rocker_port_internal_vlan_id_get(rocker_port, bridge->ifindex);
return rocker_port_vlan(rocker_port, SWITCHDEV_TRANS_NONE, 0, 0);
}
@@ -5165,7 +5169,7 @@ static int rocker_port_bridge_leave(struct rocker_port *rocker_port)
{
int err;
- rocker_port_internal_vlan_id_put(rocker_port, SWITCHDEV_TRANS_NONE,
+ rocker_port_internal_vlan_id_put(rocker_port,
rocker_port->bridge_dev->ifindex);
rocker_port->bridge_dev = NULL;
@@ -5177,7 +5181,6 @@ static int rocker_port_bridge_leave(struct rocker_port *rocker_port)
return err;
rocker_port->internal_vlan_id =
rocker_port_internal_vlan_id_get(rocker_port,
- SWITCHDEV_TRANS_NONE,
rocker_port->dev->ifindex);
err = rocker_port_vlan(rocker_port, SWITCHDEV_TRANS_NONE, 0, 0);
if (err)