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

Merge branch 'mlxsw-Spectrum-2-PTP-preparations'



Ido Schimmel says:

====================
mlxsw: Spectrum-2 PTP preparations

This patchset includes various preparations required for Spectrum-2 PTP
support.

Most of the changes are non-functional (e.g., renaming, adding
registers). The only intentional user visible change is in patch #10
where the PHC time is initialized to zero in accordance with the
recommendation of the PTP maintainer.
====================

Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parents e222dc8d a168e13f
Loading
Loading
Loading
Loading
+52 −0
Original line number Diff line number Diff line
@@ -329,6 +329,32 @@ MLXSW_ITEM64(cmd_mbox, query_fw, free_running_clock_offset, 0x50, 0, 64);
 */
MLXSW_ITEM32(cmd_mbox, query_fw, fr_rn_clk_bar, 0x58, 30, 2);

/* cmd_mbox_query_fw_utc_sec_offset
 * The offset of the UTC_Sec page
 */
MLXSW_ITEM64(cmd_mbox, query_fw, utc_sec_offset, 0x70, 0, 64);

/* cmd_mbox_query_fw_utc_sec_bar
 * PCI base address register (BAR) of the UTC_Sec page
 * 0: BAR 0
 * 1: 64 bit BAR
 * Reserved on SwitchX/-2, Switch-IB/2, Spectrum-1
 */
MLXSW_ITEM32(cmd_mbox, query_fw, utc_sec_bar, 0x78, 30, 2);

/* cmd_mbox_query_fw_utc_nsec_offset
 * The offset of the UTC_nSec page
 */
MLXSW_ITEM64(cmd_mbox, query_fw, utc_nsec_offset, 0x80, 0, 64);

/* cmd_mbox_query_fw_utc_nsec_bar
 * PCI base address register (BAR) of the UTC_nSec page
 * 0: BAR 0
 * 1: 64 bit BAR
 * Reserved on SwitchX/-2, Switch-IB/2, Spectrum-1
 */
MLXSW_ITEM32(cmd_mbox, query_fw, utc_nsec_bar, 0x88, 30, 2);

/* QUERY_BOARDINFO - Query Board Information
 * -----------------------------------------
 * OpMod == 0 (N/A), INMmod == 0 (N/A)
@@ -663,6 +689,12 @@ MLXSW_ITEM32(cmd_mbox, config_profile, set_kvd_hash_double_size, 0x0C, 26, 1);
 */
MLXSW_ITEM32(cmd_mbox, config_profile, set_cqe_version, 0x08, 0, 1);

/* cmd_mbox_config_set_cqe_time_stamp_type
 * Capability bit. Setting a bit to 1 configures the profile
 * according to the mailbox contents.
 */
MLXSW_ITEM32(cmd_mbox, config_profile, set_cqe_time_stamp_type, 0x08, 2, 1);

/* cmd_mbox_config_profile_max_vepa_channels
 * Maximum number of VEPA channels per port (0 through 16)
 * 0 - multi-channel VEPA is disabled
@@ -858,6 +890,26 @@ MLXSW_ITEM32_INDEXED(cmd_mbox, config_profile, swid_config_type,
MLXSW_ITEM32_INDEXED(cmd_mbox, config_profile, swid_config_properties,
		     0x60, 0, 8, 0x08, 0x00, false);

enum mlxsw_cmd_mbox_config_profile_cqe_time_stamp_type {
	/* uSec - 1.024uSec (default). Only bits 15:0 are valid. */
	MLXSW_CMD_MBOX_CONFIG_PROFILE_CQE_TIME_STAMP_TYPE_USEC,
	/* FRC - Free Running Clock, units of 1nSec.
	 * Reserved when SwitchX/-2, Switch-IB/2 and Spectrum-1.
	 */
	MLXSW_CMD_MBOX_CONFIG_PROFILE_CQE_TIME_STAMP_TYPE_FRC,
	/* UTC. time_stamp[37:30] = Sec, time_stamp[29:0] = nSec.
	 * Reserved when SwitchX/2, Switch-IB/2 and Spectrum-1.
	 */
	MLXSW_CMD_MBOX_CONFIG_PROFILE_CQE_TIME_STAMP_TYPE_UTC,
};

/* cmd_mbox_config_profile_cqe_time_stamp_type
 * CQE time_stamp_type for non-mirror-packets.
 * Configured if set_cqe_time_stamp_type is set.
 * Reserved when SwitchX/-2, Switch-IB/2 and Spectrum-1.
 */
MLXSW_ITEM32(cmd_mbox, config_profile, cqe_time_stamp_type, 0xB0, 8, 2);

/* cmd_mbox_config_profile_cqe_version
 * CQE version:
 * 0: CQE version is 0
+4 −2
Original line number Diff line number Diff line
@@ -296,7 +296,8 @@ struct mlxsw_config_profile {
		used_ar_sec:1,
		used_adaptive_routing_group_cap:1,
		used_ubridge:1,
		used_kvd_sizes:1;
		used_kvd_sizes:1,
		used_cqe_time_stamp_type:1;
	u8	max_vepa_channels;
	u16	max_mid;
	u16	max_pgt;
@@ -319,6 +320,7 @@ struct mlxsw_config_profile {
	u32	kvd_linear_size;
	u8	kvd_hash_single_parts;
	u8	kvd_hash_double_parts;
	u8	cqe_time_stamp_type;
	struct mlxsw_swid_config swid_config[MLXSW_CONFIG_PROFILE_SWID_COUNT];
};

@@ -485,7 +487,7 @@ struct mlxsw_bus_info {
	u8 vsd[MLXSW_CMD_BOARDINFO_VSD_LEN];
	u8 psid[MLXSW_CMD_BOARDINFO_PSID_LEN];
	u8 low_frequency:1,
	   read_frc_capable:1;
	   read_clock_capable:1;
};

struct mlxsw_hwmon;
+20 −7
Original line number Diff line number Diff line
@@ -505,6 +505,12 @@ static void mlxsw_pci_cq_fini(struct mlxsw_pci *mlxsw_pci,
	mlxsw_cmd_hw2sw_cq(mlxsw_pci->core, q->num);
}

static unsigned int mlxsw_pci_read32_off(struct mlxsw_pci *mlxsw_pci,
					 ptrdiff_t off)
{
	return ioread32be(mlxsw_pci->hw_addr + off);
}

static void mlxsw_pci_cqe_sdq_handle(struct mlxsw_pci *mlxsw_pci,
				     struct mlxsw_pci_queue *q,
				     u16 consumer_counter_limit,
@@ -1267,6 +1273,13 @@ static int mlxsw_pci_config_profile(struct mlxsw_pci *mlxsw_pci, char *mbox,
		mlxsw_cmd_mbox_config_profile_cqe_version_set(mbox, 1);
	}

	if (profile->used_cqe_time_stamp_type) {
		mlxsw_cmd_mbox_config_profile_set_cqe_time_stamp_type_set(mbox,
									  1);
		mlxsw_cmd_mbox_config_profile_cqe_time_stamp_type_set(mbox,
					profile->cqe_time_stamp_type);
	}

	return mlxsw_cmd_config_profile_set(mlxsw_pci->core, mbox);
}

@@ -1802,19 +1815,19 @@ static int mlxsw_pci_cmd_exec(void *bus_priv, u16 opcode, u8 opcode_mod,
static u32 mlxsw_pci_read_frc_h(void *bus_priv)
{
	struct mlxsw_pci *mlxsw_pci = bus_priv;
	u64 frc_offset;
	u64 frc_offset_h;

	frc_offset = mlxsw_pci->free_running_clock_offset;
	return mlxsw_pci_read32(mlxsw_pci, FREE_RUNNING_CLOCK_H(frc_offset));
	frc_offset_h = mlxsw_pci->free_running_clock_offset;
	return mlxsw_pci_read32_off(mlxsw_pci, frc_offset_h);
}

static u32 mlxsw_pci_read_frc_l(void *bus_priv)
{
	struct mlxsw_pci *mlxsw_pci = bus_priv;
	u64 frc_offset;
	u64 frc_offset_l;

	frc_offset = mlxsw_pci->free_running_clock_offset;
	return mlxsw_pci_read32(mlxsw_pci, FREE_RUNNING_CLOCK_L(frc_offset));
	frc_offset_l = mlxsw_pci->free_running_clock_offset + 4;
	return mlxsw_pci_read32_off(mlxsw_pci, frc_offset_l);
}

static const struct mlxsw_bus mlxsw_pci_bus = {
@@ -1916,7 +1929,7 @@ static int mlxsw_pci_probe(struct pci_dev *pdev, const struct pci_device_id *id)
	mlxsw_pci->bus_info.device_kind = driver_name;
	mlxsw_pci->bus_info.device_name = pci_name(mlxsw_pci->pdev);
	mlxsw_pci->bus_info.dev = &pdev->dev;
	mlxsw_pci->bus_info.read_frc_capable = true;
	mlxsw_pci->bus_info.read_clock_capable = true;
	mlxsw_pci->id = id;

	err = mlxsw_core_bus_device_register(&mlxsw_pci->bus_info,
+78 −3
Original line number Diff line number Diff line
@@ -41,9 +41,6 @@
#define MLXSW_PCI_DOORBELL(offset, type_offset, num)	\
	((offset) + (type_offset) + (num) * 4)

#define MLXSW_PCI_FREE_RUNNING_CLOCK_H(offset)	(offset)
#define MLXSW_PCI_FREE_RUNNING_CLOCK_L(offset)	((offset) + 4)

#define MLXSW_PCI_CQS_MAX	96
#define MLXSW_PCI_EQS_COUNT	2
#define MLXSW_PCI_EQ_ASYNC_NUM	0
@@ -217,6 +214,25 @@ MLXSW_ITEM32(pci, cqe0, dqn, 0x0C, 1, 5);
MLXSW_ITEM32(pci, cqe12, dqn, 0x0C, 1, 6);
mlxsw_pci_cqe_item_helpers(dqn, 0, 12, 12);

/* pci_cqe_time_stamp_low
 * Time stamp of the CQE
 * Format according to time_stamp_type:
 * 0: uSec - 1.024uSec (default for devices which do not support
 * time_stamp_type). Only bits 15:0 are valid
 * 1: FRC - Free Running Clock - units of 1nSec
 * 2: UTC - time_stamp[37:30] = Sec
 *	  - time_stamp[29:0] = nSec
 * 3: Mirror_UTC. UTC time stamp of the original packet that has
 * MIRROR_SESSION traps
 *   - time_stamp[37:30] = Sec
 *   - time_stamp[29:0] = nSec
 *   Formats 0..2 are configured by
 *   CONFIG_PROFILE.cqe_time_stamp_type for PTP traps
 *   Format 3 is used for MIRROR_SESSION traps
 *   Note that Spectrum does not reveal FRC, UTC and Mirror_UTC
 */
MLXSW_ITEM32(pci, cqe2, time_stamp_low, 0x0C, 16, 16);

#define MLXSW_PCI_CQE2_MIRROR_TCLASS_INVALID	0x1F

/* pci_cqe_mirror_tclass
@@ -280,8 +296,67 @@ MLXSW_ITEM32(pci, cqe2, user_def_val_orig_pkt_len, 0x14, 0, 20);
 */
MLXSW_ITEM32(pci, cqe2, mirror_reason, 0x18, 24, 8);

enum mlxsw_pci_cqe_time_stamp_type {
	MLXSW_PCI_CQE_TIME_STAMP_TYPE_USEC,
	MLXSW_PCI_CQE_TIME_STAMP_TYPE_FRC,
	MLXSW_PCI_CQE_TIME_STAMP_TYPE_UTC,
	MLXSW_PCI_CQE_TIME_STAMP_TYPE_MIRROR_UTC,
};

/* pci_cqe_time_stamp_type
 * Time stamp type:
 * 0: uSec - 1.024uSec (default for devices which do not support
 * time_stamp_type)
 * 1: FRC - Free Running Clock - units of 1nSec
 * 2: UTC
 * 3: Mirror_UTC. UTC time stamp of the original packet that has
 * MIRROR_SESSION traps
 */
MLXSW_ITEM32(pci, cqe2, time_stamp_type, 0x18, 22, 2);

#define MLXSW_PCI_CQE2_MIRROR_LATENCY_INVALID	0xFFFFFF

/* pci_cqe_time_stamp_high
 * Time stamp of the CQE
 * Format according to time_stamp_type:
 * 0: uSec - 1.024uSec (default for devices which do not support
 * time_stamp_type). Only bits 15:0 are valid
 * 1: FRC - Free Running Clock - units of 1nSec
 * 2: UTC - time_stamp[37:30] = Sec
 *	  - time_stamp[29:0] = nSec
 * 3: Mirror_UTC. UTC time stamp of the original packet that has
 * MIRROR_SESSION traps
 *   - time_stamp[37:30] = Sec
 *   - time_stamp[29:0] = nSec
 *   Formats 0..2 are configured by
 *   CONFIG_PROFILE.cqe_time_stamp_type for PTP traps
 *   Format 3 is used for MIRROR_SESSION traps
 *   Note that Spectrum does not reveal FRC, UTC and Mirror_UTC
 */
MLXSW_ITEM32(pci, cqe2, time_stamp_high, 0x18, 0, 22);

static inline u64 mlxsw_pci_cqe2_time_stamp_get(const char *cqe)
{
	u64 ts_high = mlxsw_pci_cqe2_time_stamp_high_get(cqe);
	u64 ts_low = mlxsw_pci_cqe2_time_stamp_low_get(cqe);

	return ts_high << 16 | ts_low;
}

static inline u8 mlxsw_pci_cqe2_time_stamp_sec_get(const char *cqe)
{
	u64 full_ts = mlxsw_pci_cqe2_time_stamp_get(cqe);

	return full_ts >> 30 & 0xFF;
}

static inline u32 mlxsw_pci_cqe2_time_stamp_nsec_get(const char *cqe)
{
	u64 full_ts = mlxsw_pci_cqe2_time_stamp_get(cqe);

	return full_ts & 0x3FFFFFFF;
}

/* pci_cqe_mirror_latency
 * End-to-end latency of the original packet that does mirroring to the CPU.
 * Value of 0xFFFFFF means that the latency is invalid. Units are according to
+94 −5
Original line number Diff line number Diff line
@@ -10347,6 +10347,8 @@ MLXSW_REG_DEFINE(mtutc, MLXSW_REG_MTUTC_ID, MLXSW_REG_MTUTC_LEN);

enum mlxsw_reg_mtutc_operation {
	MLXSW_REG_MTUTC_OPERATION_SET_TIME_AT_NEXT_SEC = 0,
	MLXSW_REG_MTUTC_OPERATION_SET_TIME_IMMEDIATE = 1,
	MLXSW_REG_MTUTC_OPERATION_ADJUST_TIME = 2,
	MLXSW_REG_MTUTC_OPERATION_ADJUST_FREQ = 3,
};

@@ -10359,25 +10361,50 @@ MLXSW_ITEM32(reg, mtutc, operation, 0x00, 0, 4);
/* reg_mtutc_freq_adjustment
 * Frequency adjustment: Every PPS the HW frequency will be
 * adjusted by this value. Units of HW clock, where HW counts
 * 10^9 HW clocks for 1 HW second.
 * 10^9 HW clocks for 1 HW second. Range is from -50,000,000 to +50,000,000.
 * In Spectrum-2, the field is reversed, positive values mean to decrease the
 * frequency.
 * Access: RW
 */
MLXSW_ITEM32(reg, mtutc, freq_adjustment, 0x04, 0, 32);

#define MLXSW_REG_MTUTC_MAX_FREQ_ADJ (50 * 1000 * 1000)

/* reg_mtutc_utc_sec
 * UTC seconds.
 * Access: WO
 */
MLXSW_ITEM32(reg, mtutc, utc_sec, 0x10, 0, 32);

/* reg_mtutc_utc_nsec
 * UTC nSecs.
 * Range 0..(10^9-1)
 * Updated when operation is SET_TIME_IMMEDIATE.
 * Reserved on Spectrum-1.
 * Access: WO
 */
MLXSW_ITEM32(reg, mtutc, utc_nsec, 0x14, 0, 30);

/* reg_mtutc_time_adjustment
 * Time adjustment.
 * Units of nSec.
 * Range is from -32768 to +32767.
 * Updated when operation is ADJUST_TIME.
 * Reserved on Spectrum-1.
 * Access: WO
 */
MLXSW_ITEM32(reg, mtutc, time_adjustment, 0x18, 0, 32);

static inline void
mlxsw_reg_mtutc_pack(char *payload, enum mlxsw_reg_mtutc_operation oper,
		     u32 freq_adj, u32 utc_sec)
		     u32 freq_adj, u32 utc_sec, u32 utc_nsec, u32 time_adj)
{
	MLXSW_REG_ZERO(mtutc, payload);
	mlxsw_reg_mtutc_operation_set(payload, oper);
	mlxsw_reg_mtutc_freq_adjustment_set(payload, freq_adj);
	mlxsw_reg_mtutc_utc_sec_set(payload, utc_sec);
	mlxsw_reg_mtutc_utc_nsec_set(payload, utc_nsec);
	mlxsw_reg_mtutc_time_adjustment_set(payload, time_adj);
}

/* MCQI - Management Component Query Information
@@ -11045,7 +11072,7 @@ MLXSW_ITEM32(reg, mtptpt, trap_id, 0x00, 0, 4);
 */
MLXSW_ITEM32(reg, mtptpt, message_type, 0x04, 0, 16);

static inline void mlxsw_reg_mtptptp_pack(char *payload,
static inline void mlxsw_reg_mtptpt_pack(char *payload,
					 enum mlxsw_reg_mtptpt_trap_id trap_id,
					 u16 message_type)
{
@@ -11054,6 +11081,67 @@ static inline void mlxsw_reg_mtptptp_pack(char *payload,
	mlxsw_reg_mtptpt_message_type_set(payload, message_type);
}

/* MTPCPC - Monitoring Time Precision Correction Port Configuration Register
 * -------------------------------------------------------------------------
 */
#define MLXSW_REG_MTPCPC_ID 0x9093
#define MLXSW_REG_MTPCPC_LEN 0x2C

MLXSW_REG_DEFINE(mtpcpc, MLXSW_REG_MTPCPC_ID, MLXSW_REG_MTPCPC_LEN);

/* reg_mtpcpc_pport
 * Per port:
 * 0: config is global. When reading - the local_port is 1.
 * 1: config is per port.
 * Access: Index
 */
MLXSW_ITEM32(reg, mtpcpc, pport, 0x00, 31, 1);

/* reg_mtpcpc_local_port
 * Local port number.
 * Supported to/from CPU port.
 * Reserved when pport = 0.
 * Access: Index
 */
MLXSW_ITEM32_LP(reg, mtpcpc, 0x00, 16, 0x00, 12);

/* reg_mtpcpc_ptp_trap_en
 * Enable PTP traps.
 * The trap_id is configured by MTPTPT.
 * Access: RW
 */
MLXSW_ITEM32(reg, mtpcpc, ptp_trap_en, 0x04, 0, 1);

/* reg_mtpcpc_ing_correction_message_type
 * Bitwise vector of PTP message types to update correction-field at ingress.
 * MessageType field as defined by IEEE 1588 Each bit corresponds to a value
 * (e.g. Bit0: Sync, Bit1: Delay_Req). Supported also from CPU port.
 * Default all 0
 * Access: RW
 */
MLXSW_ITEM32(reg, mtpcpc, ing_correction_message_type, 0x10, 0, 16);

/* reg_mtpcpc_egr_correction_message_type
 * Bitwise vector of PTP message types to update correction-field at egress.
 * MessageType field as defined by IEEE 1588 Each bit corresponds to a value
 * (e.g. Bit0: Sync, Bit1: Delay_Req). Supported also from CPU port.
 * Default all 0
 * Access: RW
 */
MLXSW_ITEM32(reg, mtpcpc, egr_correction_message_type, 0x14, 0, 16);

static inline void mlxsw_reg_mtpcpc_pack(char *payload, bool pport,
					 u16 local_port, bool ptp_trap_en,
					 u16 ing, u16 egr)
{
	MLXSW_REG_ZERO(mtpcpc, payload);
	mlxsw_reg_mtpcpc_pport_set(payload, pport);
	mlxsw_reg_mtpcpc_local_port_set(payload, pport ? local_port : 0);
	mlxsw_reg_mtpcpc_ptp_trap_en_set(payload, ptp_trap_en);
	mlxsw_reg_mtpcpc_ing_correction_message_type_set(payload, ing);
	mlxsw_reg_mtpcpc_egr_correction_message_type_set(payload, egr);
}

/* MFGD - Monitoring FW General Debug Register
 * -------------------------------------------
 */
@@ -12770,6 +12858,7 @@ static const struct mlxsw_reg_info *mlxsw_reg_infos[] = {
	MLXSW_REG(mtpppc),
	MLXSW_REG(mtpptr),
	MLXSW_REG(mtptpt),
	MLXSW_REG(mtpcpc),
	MLXSW_REG(mfgd),
	MLXSW_REG(mgpir),
	MLXSW_REG(mbct),
Loading