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

Merge branch 'mlxsw-fixes'



Petr Machata says:

====================
mlxsw: Fixes

This patchset fixes an issue with mlxsw driver initialization, and a
memory corruption issue in shared buffer occupancy handling.

v3:
- Drop the core thermal fix, it's not relevant anymore.
====================

Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parents 11b006d6 c28947de
Loading
Loading
Loading
Loading
+15 −3
Original line number Diff line number Diff line
@@ -1594,18 +1594,25 @@ static int mlxsw_pci_sys_ready_wait(struct mlxsw_pci *mlxsw_pci,
	return -EBUSY;
}

static int mlxsw_pci_reset_at_pci_disable(struct mlxsw_pci *mlxsw_pci)
static int mlxsw_pci_reset_at_pci_disable(struct mlxsw_pci *mlxsw_pci,
					  bool pci_reset_sbr_supported)
{
	struct pci_dev *pdev = mlxsw_pci->pdev;
	char mrsr_pl[MLXSW_REG_MRSR_LEN];
	int err;

	if (!pci_reset_sbr_supported) {
		pci_dbg(pdev, "Performing PCI hot reset instead of \"all reset\"\n");
		goto sbr;
	}

	mlxsw_reg_mrsr_pack(mrsr_pl,
			    MLXSW_REG_MRSR_COMMAND_RESET_AT_PCI_DISABLE);
	err = mlxsw_reg_write(mlxsw_pci->core, MLXSW_REG(mrsr), mrsr_pl);
	if (err)
		return err;

sbr:
	device_lock_assert(&pdev->dev);

	pci_cfg_access_lock(pdev);
@@ -1633,6 +1640,7 @@ static int
mlxsw_pci_reset(struct mlxsw_pci *mlxsw_pci, const struct pci_device_id *id)
{
	struct pci_dev *pdev = mlxsw_pci->pdev;
	bool pci_reset_sbr_supported = false;
	char mcam_pl[MLXSW_REG_MCAM_LEN];
	bool pci_reset_supported = false;
	u32 sys_status;
@@ -1652,13 +1660,17 @@ mlxsw_pci_reset(struct mlxsw_pci *mlxsw_pci, const struct pci_device_id *id)
	mlxsw_reg_mcam_pack(mcam_pl,
			    MLXSW_REG_MCAM_FEATURE_GROUP_ENHANCED_FEATURES);
	err = mlxsw_reg_query(mlxsw_pci->core, MLXSW_REG(mcam), mcam_pl);
	if (!err)
	if (!err) {
		mlxsw_reg_mcam_unpack(mcam_pl, MLXSW_REG_MCAM_PCI_RESET,
				      &pci_reset_supported);
		mlxsw_reg_mcam_unpack(mcam_pl, MLXSW_REG_MCAM_PCI_RESET_SBR,
				      &pci_reset_sbr_supported);
	}

	if (pci_reset_supported) {
		pci_dbg(pdev, "Starting PCI reset flow\n");
		err = mlxsw_pci_reset_at_pci_disable(mlxsw_pci);
		err = mlxsw_pci_reset_at_pci_disable(mlxsw_pci,
						     pci_reset_sbr_supported);
	} else {
		pci_dbg(pdev, "Starting software reset flow\n");
		err = mlxsw_pci_reset_sw(mlxsw_pci);
+2 −0
Original line number Diff line number Diff line
@@ -10671,6 +10671,8 @@ enum mlxsw_reg_mcam_mng_feature_cap_mask_bits {
	MLXSW_REG_MCAM_MCIA_128B = 34,
	/* If set, MRSR.command=6 is supported. */
	MLXSW_REG_MCAM_PCI_RESET = 48,
	/* If set, MRSR.command=6 is supported with Secondary Bus Reset. */
	MLXSW_REG_MCAM_PCI_RESET_SBR = 67,
};

#define MLXSW_REG_BYTES_PER_DWORD 0x4
+14 −6
Original line number Diff line number Diff line
@@ -1607,8 +1607,8 @@ static void mlxsw_sp_sb_sr_occ_query_cb(struct mlxsw_core *mlxsw_core,
int mlxsw_sp_sb_occ_snapshot(struct mlxsw_core *mlxsw_core,
			     unsigned int sb_index)
{
	u16 local_port, local_port_1, first_local_port, last_local_port;
	struct mlxsw_sp *mlxsw_sp = mlxsw_core_driver_priv(mlxsw_core);
	u16 local_port, local_port_1, last_local_port;
	struct mlxsw_sp_sb_sr_occ_query_cb_ctx cb_ctx;
	u8 masked_count, current_page = 0;
	unsigned long cb_priv = 0;
@@ -1628,6 +1628,7 @@ int mlxsw_sp_sb_occ_snapshot(struct mlxsw_core *mlxsw_core,
	masked_count = 0;
	mlxsw_reg_sbsr_pack(sbsr_pl, false);
	mlxsw_reg_sbsr_port_page_set(sbsr_pl, current_page);
	first_local_port = current_page * MLXSW_REG_SBSR_NUM_PORTS_IN_PAGE;
	last_local_port = current_page * MLXSW_REG_SBSR_NUM_PORTS_IN_PAGE +
			  MLXSW_REG_SBSR_NUM_PORTS_IN_PAGE - 1;

@@ -1645,9 +1646,12 @@ int mlxsw_sp_sb_occ_snapshot(struct mlxsw_core *mlxsw_core,
		if (local_port != MLXSW_PORT_CPU_PORT) {
			/* Ingress quotas are not supported for the CPU port */
			mlxsw_reg_sbsr_ingress_port_mask_set(sbsr_pl,
							     local_port, 1);
							     local_port - first_local_port,
							     1);
		}
		mlxsw_reg_sbsr_egress_port_mask_set(sbsr_pl, local_port, 1);
		mlxsw_reg_sbsr_egress_port_mask_set(sbsr_pl,
						    local_port - first_local_port,
						    1);
		for (i = 0; i < mlxsw_sp->sb_vals->pool_count; i++) {
			err = mlxsw_sp_sb_pm_occ_query(mlxsw_sp, local_port, i,
						       &bulk_list);
@@ -1684,7 +1688,7 @@ int mlxsw_sp_sb_occ_max_clear(struct mlxsw_core *mlxsw_core,
			      unsigned int sb_index)
{
	struct mlxsw_sp *mlxsw_sp = mlxsw_core_driver_priv(mlxsw_core);
	u16 local_port, last_local_port;
	u16 local_port, first_local_port, last_local_port;
	LIST_HEAD(bulk_list);
	unsigned int masked_count;
	u8 current_page = 0;
@@ -1702,6 +1706,7 @@ int mlxsw_sp_sb_occ_max_clear(struct mlxsw_core *mlxsw_core,
	masked_count = 0;
	mlxsw_reg_sbsr_pack(sbsr_pl, true);
	mlxsw_reg_sbsr_port_page_set(sbsr_pl, current_page);
	first_local_port = current_page * MLXSW_REG_SBSR_NUM_PORTS_IN_PAGE;
	last_local_port = current_page * MLXSW_REG_SBSR_NUM_PORTS_IN_PAGE +
			  MLXSW_REG_SBSR_NUM_PORTS_IN_PAGE - 1;

@@ -1719,9 +1724,12 @@ int mlxsw_sp_sb_occ_max_clear(struct mlxsw_core *mlxsw_core,
		if (local_port != MLXSW_PORT_CPU_PORT) {
			/* Ingress quotas are not supported for the CPU port */
			mlxsw_reg_sbsr_ingress_port_mask_set(sbsr_pl,
							     local_port, 1);
							     local_port - first_local_port,
							     1);
		}
		mlxsw_reg_sbsr_egress_port_mask_set(sbsr_pl, local_port, 1);
		mlxsw_reg_sbsr_egress_port_mask_set(sbsr_pl,
						    local_port - first_local_port,
						    1);
		for (i = 0; i < mlxsw_sp->sb_vals->pool_count; i++) {
			err = mlxsw_sp_sb_pm_occ_clear(mlxsw_sp, local_port, i,
						       &bulk_list);