Commit efa8c819 authored by David S. Miller's avatar David S. Miller
Browse files

Merge branch 'mlxsw-fixes'



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 #7-#8 add test cases for above mentioned bugs.

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

Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parents 20f5248a 479a2b76
Loading
Loading
Loading
Loading
+9 −7
Original line number Diff line number Diff line
@@ -604,30 +604,32 @@ 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)
{
@@ -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)
+2 −1
Original line number Diff line number Diff line
@@ -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
@@ -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)
+2 −2
Original line number Diff line number Diff line
@@ -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,
};

+6 −6
Original line number Diff line number Diff line
@@ -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)
@@ -1290,7 +1290,7 @@ out:
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;
@@ -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)
@@ -1321,7 +1320,8 @@ 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,
@@ -1329,7 +1329,7 @@ int mlxsw_sp_rif_fdb_op(struct mlxsw_sp *mlxsw_sp, const char *mac, u16 fid,
{
	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,
+5 −0
Original line number Diff line number Diff line
@@ -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 {
@@ -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);
	}
Loading