Skip to content

Commit

Permalink
Merge branch 'mlxsw-fixes'
Browse files Browse the repository at this point in the history
Ido Schimmel says:

====================
mlxsw: Various fixes

This patchset contains small fixes in mlxsw and one fix in the bridge
driver.

Patches #1-#4 perform small adjustments in PCI and FID code following
recent tests that were performed on the Spectrum-2 ASIC.

Patch #5 fixes the bridge driver to mark FDB entries that were added by
user as such. Otherwise, these entries will be ignored by underlying
switch drivers.

Patch #6 fixes a long standing issue in mlxsw where the driver
incorrectly programmed static FDB entries as both static and sticky.

Patches linux-sunxi#7-linux-sunxi#8 add test cases for above mentioned bugs.

Please consider patches #1, #2 and #4 for stable.
====================

Signed-off-by: David S. Miller <davem@davemloft.net>
  • Loading branch information
davem330 committed Jan 18, 2019
2 parents 20f5248 + 479a2b7 commit efa8c81
Show file tree
Hide file tree
Showing 7 changed files with 77 additions and 17 deletions.
16 changes: 9 additions & 7 deletions drivers/net/ethernet/mellanox/mlxsw/pci.c
Original file line number Diff line number Diff line change
Expand Up @@ -604,29 +604,31 @@ static void mlxsw_pci_cq_tasklet(unsigned long data)
u16 wqe_counter = mlxsw_pci_cqe_wqe_counter_get(cqe);
u8 sendq = mlxsw_pci_cqe_sr_get(q->u.cq.v, cqe);
u8 dqn = mlxsw_pci_cqe_dqn_get(q->u.cq.v, cqe);
char ncqe[MLXSW_PCI_CQE_SIZE_MAX];

memcpy(ncqe, cqe, q->elem_size);
mlxsw_pci_queue_doorbell_consumer_ring(mlxsw_pci, q);

if (sendq) {
struct mlxsw_pci_queue *sdq;

sdq = mlxsw_pci_sdq_get(mlxsw_pci, dqn);
mlxsw_pci_cqe_sdq_handle(mlxsw_pci, sdq,
wqe_counter, cqe);
wqe_counter, ncqe);
q->u.cq.comp_sdq_count++;
} else {
struct mlxsw_pci_queue *rdq;

rdq = mlxsw_pci_rdq_get(mlxsw_pci, dqn);
mlxsw_pci_cqe_rdq_handle(mlxsw_pci, rdq,
wqe_counter, q->u.cq.v, cqe);
wqe_counter, q->u.cq.v, ncqe);
q->u.cq.comp_rdq_count++;
}
if (++items == credits)
break;
}
if (items) {
mlxsw_pci_queue_doorbell_consumer_ring(mlxsw_pci, q);
if (items)
mlxsw_pci_queue_doorbell_arm_consumer_ring(mlxsw_pci, q);
}
}

static u16 mlxsw_pci_cq_elem_count(const struct mlxsw_pci_queue *q)
Expand Down Expand Up @@ -1365,10 +1367,10 @@ static int mlxsw_pci_sw_reset(struct mlxsw_pci *mlxsw_pci,
u32 val = mlxsw_pci_read32(mlxsw_pci, FW_READY);

if ((val & MLXSW_PCI_FW_READY_MASK) == MLXSW_PCI_FW_READY_MAGIC)
break;
return 0;
cond_resched();
} while (time_before(jiffies, end));
return 0;
return -EBUSY;
}

static int mlxsw_pci_alloc_irq_vectors(struct mlxsw_pci *mlxsw_pci)
Expand Down
3 changes: 2 additions & 1 deletion drivers/net/ethernet/mellanox/mlxsw/pci_hw.h
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@

#define MLXSW_PCI_SW_RESET 0xF0010
#define MLXSW_PCI_SW_RESET_RST_BIT BIT(0)
#define MLXSW_PCI_SW_RESET_TIMEOUT_MSECS 5000
#define MLXSW_PCI_SW_RESET_TIMEOUT_MSECS 13000
#define MLXSW_PCI_SW_RESET_WAIT_MSECS 100
#define MLXSW_PCI_FW_READY 0xA1844
#define MLXSW_PCI_FW_READY_MASK 0xFFFF
Expand All @@ -53,6 +53,7 @@
#define MLXSW_PCI_WQE_SIZE 32 /* 32 bytes per element */
#define MLXSW_PCI_CQE01_SIZE 16 /* 16 bytes per element */
#define MLXSW_PCI_CQE2_SIZE 32 /* 32 bytes per element */
#define MLXSW_PCI_CQE_SIZE_MAX MLXSW_PCI_CQE2_SIZE
#define MLXSW_PCI_EQE_SIZE 16 /* 16 bytes per element */
#define MLXSW_PCI_WQE_COUNT (MLXSW_PCI_AQ_SIZE / MLXSW_PCI_WQE_SIZE)
#define MLXSW_PCI_CQE01_COUNT (MLXSW_PCI_AQ_SIZE / MLXSW_PCI_CQE01_SIZE)
Expand Down
4 changes: 2 additions & 2 deletions drivers/net/ethernet/mellanox/mlxsw/spectrum_fid.c
Original file line number Diff line number Diff line change
Expand Up @@ -997,8 +997,8 @@ static const struct mlxsw_sp_fid_ops mlxsw_sp_fid_dummy_ops = {
static const struct mlxsw_sp_fid_family mlxsw_sp_fid_dummy_family = {
.type = MLXSW_SP_FID_TYPE_DUMMY,
.fid_size = sizeof(struct mlxsw_sp_fid),
.start_index = MLXSW_SP_RFID_BASE - 1,
.end_index = MLXSW_SP_RFID_BASE - 1,
.start_index = VLAN_N_VID - 1,
.end_index = VLAN_N_VID - 1,
.ops = &mlxsw_sp_fid_dummy_ops,
};

Expand Down
12 changes: 6 additions & 6 deletions drivers/net/ethernet/mellanox/mlxsw/spectrum_switchdev.c
Original file line number Diff line number Diff line change
Expand Up @@ -1233,7 +1233,7 @@ mlxsw_sp_bridge_port_fdb_flush(struct mlxsw_sp *mlxsw_sp,
static enum mlxsw_reg_sfd_rec_policy mlxsw_sp_sfd_rec_policy(bool dynamic)
{
return dynamic ? MLXSW_REG_SFD_REC_POLICY_DYNAMIC_ENTRY_INGRESS :
MLXSW_REG_SFD_REC_POLICY_STATIC_ENTRY;
MLXSW_REG_SFD_REC_POLICY_DYNAMIC_ENTRY_MLAG;
}

static enum mlxsw_reg_sfd_op mlxsw_sp_sfd_op(bool adding)
Expand Down Expand Up @@ -1290,7 +1290,7 @@ static int mlxsw_sp_port_fdb_tunnel_uc_op(struct mlxsw_sp *mlxsw_sp,
static int __mlxsw_sp_port_fdb_uc_op(struct mlxsw_sp *mlxsw_sp, u8 local_port,
const char *mac, u16 fid, bool adding,
enum mlxsw_reg_sfd_rec_action action,
bool dynamic)
enum mlxsw_reg_sfd_rec_policy policy)
{
char *sfd_pl;
u8 num_rec;
Expand All @@ -1301,8 +1301,7 @@ static int __mlxsw_sp_port_fdb_uc_op(struct mlxsw_sp *mlxsw_sp, u8 local_port,
return -ENOMEM;

mlxsw_reg_sfd_pack(sfd_pl, mlxsw_sp_sfd_op(adding), 0);
mlxsw_reg_sfd_uc_pack(sfd_pl, 0, mlxsw_sp_sfd_rec_policy(dynamic),
mac, fid, action, local_port);
mlxsw_reg_sfd_uc_pack(sfd_pl, 0, policy, mac, fid, action, local_port);
num_rec = mlxsw_reg_sfd_num_rec_get(sfd_pl);
err = mlxsw_reg_write(mlxsw_sp->core, MLXSW_REG(sfd), sfd_pl);
if (err)
Expand All @@ -1321,15 +1320,16 @@ static int mlxsw_sp_port_fdb_uc_op(struct mlxsw_sp *mlxsw_sp, u8 local_port,
bool dynamic)
{
return __mlxsw_sp_port_fdb_uc_op(mlxsw_sp, local_port, mac, fid, adding,
MLXSW_REG_SFD_REC_ACTION_NOP, dynamic);
MLXSW_REG_SFD_REC_ACTION_NOP,
mlxsw_sp_sfd_rec_policy(dynamic));
}

int mlxsw_sp_rif_fdb_op(struct mlxsw_sp *mlxsw_sp, const char *mac, u16 fid,
bool adding)
{
return __mlxsw_sp_port_fdb_uc_op(mlxsw_sp, 0, mac, fid, adding,
MLXSW_REG_SFD_REC_ACTION_FORWARD_IP_ROUTER,
false);
MLXSW_REG_SFD_REC_POLICY_STATIC_ENTRY);
}

static int mlxsw_sp_port_fdb_uc_lag_op(struct mlxsw_sp *mlxsw_sp, u16 lag_id,
Expand Down
5 changes: 5 additions & 0 deletions net/bridge/br_fdb.c
Original file line number Diff line number Diff line change
Expand Up @@ -1128,6 +1128,8 @@ int br_fdb_external_learn_add(struct net_bridge *br, struct net_bridge_port *p,
err = -ENOMEM;
goto err_unlock;
}
if (swdev_notify)
fdb->added_by_user = 1;
fdb->added_by_external_learn = 1;
fdb_notify(br, fdb, RTM_NEWNEIGH, swdev_notify);
} else {
Expand All @@ -1147,6 +1149,9 @@ int br_fdb_external_learn_add(struct net_bridge *br, struct net_bridge_port *p,
modified = true;
}

if (swdev_notify)
fdb->added_by_user = 1;

if (modified)
fdb_notify(br, fdb, RTM_NEWNEIGH, swdev_notify);
}
Expand Down
20 changes: 20 additions & 0 deletions tools/testing/selftests/drivers/net/mlxsw/rtnetlink.sh
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ ALL_TESTS="
lag_unlink_slaves_test
lag_dev_deletion_test
vlan_interface_uppers_test
bridge_extern_learn_test
devlink_reload_test
"
NUM_NETIFS=2
Expand Down Expand Up @@ -541,6 +542,25 @@ vlan_interface_uppers_test()
ip link del dev br0
}

bridge_extern_learn_test()
{
# Test that externally learned entries added from user space are
# marked as offloaded
RET=0

ip link add name br0 type bridge
ip link set dev $swp1 master br0

bridge fdb add de:ad:be:ef:13:37 dev $swp1 master extern_learn

bridge fdb show brport $swp1 | grep de:ad:be:ef:13:37 | grep -q offload
check_err $? "fdb entry not marked as offloaded when should"

log_test "externally learned fdb entry"

ip link del dev br0
}

devlink_reload_test()
{
# Test that after executing all the above configuration tests, a
Expand Down
34 changes: 33 additions & 1 deletion tools/testing/selftests/net/forwarding/bridge_vlan_aware.sh
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
#!/bin/bash
# SPDX-License-Identifier: GPL-2.0

ALL_TESTS="ping_ipv4 ping_ipv6 learning flooding vlan_deletion"
ALL_TESTS="ping_ipv4 ping_ipv6 learning flooding vlan_deletion extern_learn"
NUM_NETIFS=4
CHECK_TC="yes"
source lib.sh
Expand Down Expand Up @@ -109,6 +109,38 @@ vlan_deletion()
ping_ipv6
}

extern_learn()
{
local mac=de:ad:be:ef:13:37
local ageing_time

# Test that externally learned FDB entries can roam, but not age out
RET=0

bridge fdb add de:ad:be:ef:13:37 dev $swp1 master extern_learn vlan 1

bridge fdb show brport $swp1 | grep -q de:ad:be:ef:13:37
check_err $? "Did not find FDB entry when should"

# Wait for 10 seconds after the ageing time to make sure the FDB entry
# was not aged out
ageing_time=$(bridge_ageing_time_get br0)
sleep $((ageing_time + 10))

bridge fdb show brport $swp1 | grep -q de:ad:be:ef:13:37
check_err $? "FDB entry was aged out when should not"

$MZ $h2 -c 1 -p 64 -a $mac -t ip -q

bridge fdb show brport $swp2 | grep -q de:ad:be:ef:13:37
check_err $? "FDB entry did not roam when should"

log_test "Externally learned FDB entry - ageing & roaming"

bridge fdb del de:ad:be:ef:13:37 dev $swp2 master vlan 1 &> /dev/null
bridge fdb del de:ad:be:ef:13:37 dev $swp1 master vlan 1 &> /dev/null
}

trap cleanup EXIT

setup_prepare
Expand Down

0 comments on commit efa8c81

Please sign in to comment.