forked from Minki/linux
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: David S. Miller <davem@davemloft.net>
This commit is contained in:
commit
360f9f3152
@ -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
|
||||
|
@ -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;
|
||||
|
@ -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,
|
||||
|
@ -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
|
||||
|
@ -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,15 +11072,76 @@ 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,
|
||||
enum mlxsw_reg_mtptpt_trap_id trap_id,
|
||||
u16 message_type)
|
||||
static inline void mlxsw_reg_mtptpt_pack(char *payload,
|
||||
enum mlxsw_reg_mtptpt_trap_id trap_id,
|
||||
u16 message_type)
|
||||
{
|
||||
MLXSW_REG_ZERO(mtptpt, payload);
|
||||
mlxsw_reg_mtptpt_trap_id_set(payload, trap_id);
|
||||
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),
|
||||
|
@ -24,6 +24,7 @@ enum mlxsw_res_id {
|
||||
MLXSW_RES_ID_COUNTER_SIZE_PACKETS_BYTES,
|
||||
MLXSW_RES_ID_COUNTER_SIZE_ROUTER_BASIC,
|
||||
MLXSW_RES_ID_MAX_SYSTEM_PORT,
|
||||
MLXSW_RES_ID_FID,
|
||||
MLXSW_RES_ID_MAX_LAG,
|
||||
MLXSW_RES_ID_MAX_LAG_MEMBERS,
|
||||
MLXSW_RES_ID_GUARANTEED_SHARED_BUFFER,
|
||||
@ -83,6 +84,7 @@ static u16 mlxsw_res_ids[] = {
|
||||
[MLXSW_RES_ID_COUNTER_SIZE_PACKETS_BYTES] = 0x2443,
|
||||
[MLXSW_RES_ID_COUNTER_SIZE_ROUTER_BASIC] = 0x2449,
|
||||
[MLXSW_RES_ID_MAX_SYSTEM_PORT] = 0x2502,
|
||||
[MLXSW_RES_ID_FID] = 0x2512,
|
||||
[MLXSW_RES_ID_MAX_LAG] = 0x2520,
|
||||
[MLXSW_RES_ID_MAX_LAG_MEMBERS] = 0x2521,
|
||||
[MLXSW_RES_ID_GUARANTEED_SHARED_BUFFER] = 0x2805, /* Bytes */
|
||||
|
@ -166,7 +166,7 @@ MLXSW_ITEM32(tx, hdr, port_mid, 0x04, 16, 16);
|
||||
* set, otherwise calculated based on the packet's VID using VID to FID mapping.
|
||||
* Valid for data packets only.
|
||||
*/
|
||||
MLXSW_ITEM32(tx, hdr, fid, 0x08, 0, 16);
|
||||
MLXSW_ITEM32(tx, hdr, fid, 0x08, 16, 16);
|
||||
|
||||
/* tx_hdr_type
|
||||
* 0 - Data packets
|
||||
@ -3096,7 +3096,7 @@ static int mlxsw_sp_init(struct mlxsw_core *mlxsw_core,
|
||||
goto err_router_init;
|
||||
}
|
||||
|
||||
if (mlxsw_sp->bus_info->read_frc_capable) {
|
||||
if (mlxsw_sp->bus_info->read_clock_capable) {
|
||||
/* NULL is a valid return value from clock_init */
|
||||
mlxsw_sp->clock =
|
||||
mlxsw_sp->ptp_ops->clock_init(mlxsw_sp,
|
||||
@ -3411,6 +3411,8 @@ static const struct mlxsw_config_profile mlxsw_sp2_config_profile = {
|
||||
.type = MLXSW_PORT_SWID_TYPE_ETH,
|
||||
}
|
||||
},
|
||||
.used_cqe_time_stamp_type = 1,
|
||||
.cqe_time_stamp_type = MLXSW_CMD_MBOX_CONFIG_PROFILE_CQE_TIME_STAMP_TYPE_UTC,
|
||||
};
|
||||
|
||||
static void
|
||||
|
@ -29,6 +29,10 @@
|
||||
|
||||
struct mlxsw_sp_ptp_state {
|
||||
struct mlxsw_sp *mlxsw_sp;
|
||||
};
|
||||
|
||||
struct mlxsw_sp1_ptp_state {
|
||||
struct mlxsw_sp_ptp_state common;
|
||||
struct rhltable unmatched_ht;
|
||||
spinlock_t unmatched_lock; /* protects the HT */
|
||||
struct delayed_work ht_gc_dw;
|
||||
@ -60,20 +64,37 @@ static const struct rhashtable_params mlxsw_sp1_ptp_unmatched_ht_params = {
|
||||
|
||||
struct mlxsw_sp_ptp_clock {
|
||||
struct mlxsw_core *core;
|
||||
struct ptp_clock *ptp;
|
||||
struct ptp_clock_info ptp_info;
|
||||
};
|
||||
|
||||
struct mlxsw_sp1_ptp_clock {
|
||||
struct mlxsw_sp_ptp_clock common;
|
||||
spinlock_t lock; /* protect this structure */
|
||||
struct cyclecounter cycles;
|
||||
struct timecounter tc;
|
||||
u32 nominal_c_mult;
|
||||
struct ptp_clock *ptp;
|
||||
struct ptp_clock_info ptp_info;
|
||||
unsigned long overflow_period;
|
||||
struct delayed_work overflow_work;
|
||||
};
|
||||
|
||||
static u64 __mlxsw_sp1_ptp_read_frc(struct mlxsw_sp_ptp_clock *clock,
|
||||
static struct mlxsw_sp1_ptp_state *
|
||||
mlxsw_sp1_ptp_state(struct mlxsw_sp *mlxsw_sp)
|
||||
{
|
||||
return container_of(mlxsw_sp->ptp_state, struct mlxsw_sp1_ptp_state,
|
||||
common);
|
||||
}
|
||||
|
||||
static struct mlxsw_sp1_ptp_clock *
|
||||
mlxsw_sp1_ptp_clock(struct ptp_clock_info *ptp)
|
||||
{
|
||||
return container_of(ptp, struct mlxsw_sp1_ptp_clock, common.ptp_info);
|
||||
}
|
||||
|
||||
static u64 __mlxsw_sp1_ptp_read_frc(struct mlxsw_sp1_ptp_clock *clock,
|
||||
struct ptp_system_timestamp *sts)
|
||||
{
|
||||
struct mlxsw_core *mlxsw_core = clock->core;
|
||||
struct mlxsw_core *mlxsw_core = clock->common.core;
|
||||
u32 frc_h1, frc_h2, frc_l;
|
||||
|
||||
frc_h1 = mlxsw_core_read_frc_h(mlxsw_core);
|
||||
@ -94,20 +115,20 @@ static u64 __mlxsw_sp1_ptp_read_frc(struct mlxsw_sp_ptp_clock *clock,
|
||||
|
||||
static u64 mlxsw_sp1_ptp_read_frc(const struct cyclecounter *cc)
|
||||
{
|
||||
struct mlxsw_sp_ptp_clock *clock =
|
||||
container_of(cc, struct mlxsw_sp_ptp_clock, cycles);
|
||||
struct mlxsw_sp1_ptp_clock *clock =
|
||||
container_of(cc, struct mlxsw_sp1_ptp_clock, cycles);
|
||||
|
||||
return __mlxsw_sp1_ptp_read_frc(clock, NULL) & cc->mask;
|
||||
}
|
||||
|
||||
static int
|
||||
mlxsw_sp1_ptp_phc_adjfreq(struct mlxsw_sp_ptp_clock *clock, int freq_adj)
|
||||
mlxsw_sp_ptp_phc_adjfreq(struct mlxsw_sp_ptp_clock *clock, int freq_adj)
|
||||
{
|
||||
struct mlxsw_core *mlxsw_core = clock->core;
|
||||
char mtutc_pl[MLXSW_REG_MTUTC_LEN];
|
||||
|
||||
mlxsw_reg_mtutc_pack(mtutc_pl, MLXSW_REG_MTUTC_OPERATION_ADJUST_FREQ,
|
||||
freq_adj, 0);
|
||||
freq_adj, 0, 0, 0);
|
||||
return mlxsw_reg_write(mlxsw_core, MLXSW_REG(mtutc), mtutc_pl);
|
||||
}
|
||||
|
||||
@ -122,9 +143,9 @@ static u64 mlxsw_sp1_ptp_ns2cycles(const struct timecounter *tc, u64 nsec)
|
||||
}
|
||||
|
||||
static int
|
||||
mlxsw_sp1_ptp_phc_settime(struct mlxsw_sp_ptp_clock *clock, u64 nsec)
|
||||
mlxsw_sp1_ptp_phc_settime(struct mlxsw_sp1_ptp_clock *clock, u64 nsec)
|
||||
{
|
||||
struct mlxsw_core *mlxsw_core = clock->core;
|
||||
struct mlxsw_core *mlxsw_core = clock->common.core;
|
||||
u64 next_sec, next_sec_in_nsec, cycles;
|
||||
char mtutc_pl[MLXSW_REG_MTUTC_LEN];
|
||||
char mtpps_pl[MLXSW_REG_MTPPS_LEN];
|
||||
@ -144,14 +165,13 @@ mlxsw_sp1_ptp_phc_settime(struct mlxsw_sp_ptp_clock *clock, u64 nsec)
|
||||
|
||||
mlxsw_reg_mtutc_pack(mtutc_pl,
|
||||
MLXSW_REG_MTUTC_OPERATION_SET_TIME_AT_NEXT_SEC,
|
||||
0, next_sec);
|
||||
0, next_sec, 0, 0);
|
||||
return mlxsw_reg_write(mlxsw_core, MLXSW_REG(mtutc), mtutc_pl);
|
||||
}
|
||||
|
||||
static int mlxsw_sp1_ptp_adjfine(struct ptp_clock_info *ptp, long scaled_ppm)
|
||||
{
|
||||
struct mlxsw_sp_ptp_clock *clock =
|
||||
container_of(ptp, struct mlxsw_sp_ptp_clock, ptp_info);
|
||||
struct mlxsw_sp1_ptp_clock *clock = mlxsw_sp1_ptp_clock(ptp);
|
||||
int neg_adj = 0;
|
||||
u32 diff;
|
||||
u64 adj;
|
||||
@ -174,13 +194,12 @@ static int mlxsw_sp1_ptp_adjfine(struct ptp_clock_info *ptp, long scaled_ppm)
|
||||
clock->nominal_c_mult + diff;
|
||||
spin_unlock_bh(&clock->lock);
|
||||
|
||||
return mlxsw_sp1_ptp_phc_adjfreq(clock, neg_adj ? -ppb : ppb);
|
||||
return mlxsw_sp_ptp_phc_adjfreq(&clock->common, neg_adj ? -ppb : ppb);
|
||||
}
|
||||
|
||||
static int mlxsw_sp1_ptp_adjtime(struct ptp_clock_info *ptp, s64 delta)
|
||||
{
|
||||
struct mlxsw_sp_ptp_clock *clock =
|
||||
container_of(ptp, struct mlxsw_sp_ptp_clock, ptp_info);
|
||||
struct mlxsw_sp1_ptp_clock *clock = mlxsw_sp1_ptp_clock(ptp);
|
||||
u64 nsec;
|
||||
|
||||
spin_lock_bh(&clock->lock);
|
||||
@ -195,8 +214,7 @@ static int mlxsw_sp1_ptp_gettimex(struct ptp_clock_info *ptp,
|
||||
struct timespec64 *ts,
|
||||
struct ptp_system_timestamp *sts)
|
||||
{
|
||||
struct mlxsw_sp_ptp_clock *clock =
|
||||
container_of(ptp, struct mlxsw_sp_ptp_clock, ptp_info);
|
||||
struct mlxsw_sp1_ptp_clock *clock = mlxsw_sp1_ptp_clock(ptp);
|
||||
u64 cycles, nsec;
|
||||
|
||||
spin_lock_bh(&clock->lock);
|
||||
@ -212,8 +230,7 @@ static int mlxsw_sp1_ptp_gettimex(struct ptp_clock_info *ptp,
|
||||
static int mlxsw_sp1_ptp_settime(struct ptp_clock_info *ptp,
|
||||
const struct timespec64 *ts)
|
||||
{
|
||||
struct mlxsw_sp_ptp_clock *clock =
|
||||
container_of(ptp, struct mlxsw_sp_ptp_clock, ptp_info);
|
||||
struct mlxsw_sp1_ptp_clock *clock = mlxsw_sp1_ptp_clock(ptp);
|
||||
u64 nsec = timespec64_to_ns(ts);
|
||||
|
||||
spin_lock_bh(&clock->lock);
|
||||
@ -237,9 +254,9 @@ static const struct ptp_clock_info mlxsw_sp1_ptp_clock_info = {
|
||||
static void mlxsw_sp1_ptp_clock_overflow(struct work_struct *work)
|
||||
{
|
||||
struct delayed_work *dwork = to_delayed_work(work);
|
||||
struct mlxsw_sp_ptp_clock *clock;
|
||||
struct mlxsw_sp1_ptp_clock *clock;
|
||||
|
||||
clock = container_of(dwork, struct mlxsw_sp_ptp_clock, overflow_work);
|
||||
clock = container_of(dwork, struct mlxsw_sp1_ptp_clock, overflow_work);
|
||||
|
||||
spin_lock_bh(&clock->lock);
|
||||
timecounter_read(&clock->tc);
|
||||
@ -251,7 +268,7 @@ struct mlxsw_sp_ptp_clock *
|
||||
mlxsw_sp1_ptp_clock_init(struct mlxsw_sp *mlxsw_sp, struct device *dev)
|
||||
{
|
||||
u64 overflow_cycles, nsec, frac = 0;
|
||||
struct mlxsw_sp_ptp_clock *clock;
|
||||
struct mlxsw_sp1_ptp_clock *clock;
|
||||
int err;
|
||||
|
||||
clock = kzalloc(sizeof(*clock), GFP_KERNEL);
|
||||
@ -265,10 +282,9 @@ mlxsw_sp1_ptp_clock_init(struct mlxsw_sp *mlxsw_sp, struct device *dev)
|
||||
clock->cycles.shift);
|
||||
clock->nominal_c_mult = clock->cycles.mult;
|
||||
clock->cycles.mask = CLOCKSOURCE_MASK(MLXSW_SP1_PTP_CLOCK_MASK);
|
||||
clock->core = mlxsw_sp->core;
|
||||
clock->common.core = mlxsw_sp->core;
|
||||
|
||||
timecounter_init(&clock->tc, &clock->cycles,
|
||||
ktime_to_ns(ktime_get_real()));
|
||||
timecounter_init(&clock->tc, &clock->cycles, 0);
|
||||
|
||||
/* Calculate period in seconds to call the overflow watchdog - to make
|
||||
* sure counter is checked at least twice every wrap around.
|
||||
@ -286,15 +302,15 @@ mlxsw_sp1_ptp_clock_init(struct mlxsw_sp *mlxsw_sp, struct device *dev)
|
||||
INIT_DELAYED_WORK(&clock->overflow_work, mlxsw_sp1_ptp_clock_overflow);
|
||||
mlxsw_core_schedule_dw(&clock->overflow_work, 0);
|
||||
|
||||
clock->ptp_info = mlxsw_sp1_ptp_clock_info;
|
||||
clock->ptp = ptp_clock_register(&clock->ptp_info, dev);
|
||||
if (IS_ERR(clock->ptp)) {
|
||||
err = PTR_ERR(clock->ptp);
|
||||
clock->common.ptp_info = mlxsw_sp1_ptp_clock_info;
|
||||
clock->common.ptp = ptp_clock_register(&clock->common.ptp_info, dev);
|
||||
if (IS_ERR(clock->common.ptp)) {
|
||||
err = PTR_ERR(clock->common.ptp);
|
||||
dev_err(dev, "ptp_clock_register failed %d\n", err);
|
||||
goto err_ptp_clock_register;
|
||||
}
|
||||
|
||||
return clock;
|
||||
return &clock->common;
|
||||
|
||||
err_ptp_clock_register:
|
||||
cancel_delayed_work_sync(&clock->overflow_work);
|
||||
@ -302,9 +318,12 @@ err_ptp_clock_register:
|
||||
return ERR_PTR(err);
|
||||
}
|
||||
|
||||
void mlxsw_sp1_ptp_clock_fini(struct mlxsw_sp_ptp_clock *clock)
|
||||
void mlxsw_sp1_ptp_clock_fini(struct mlxsw_sp_ptp_clock *clock_common)
|
||||
{
|
||||
ptp_clock_unregister(clock->ptp);
|
||||
struct mlxsw_sp1_ptp_clock *clock =
|
||||
container_of(clock_common, struct mlxsw_sp1_ptp_clock, common);
|
||||
|
||||
ptp_clock_unregister(clock_common->ptp);
|
||||
cancel_delayed_work_sync(&clock->overflow_work);
|
||||
kfree(clock);
|
||||
}
|
||||
@ -348,7 +367,7 @@ mlxsw_sp1_ptp_unmatched_save(struct mlxsw_sp *mlxsw_sp,
|
||||
u64 timestamp)
|
||||
{
|
||||
int cycles = MLXSW_SP1_PTP_HT_GC_TIMEOUT / MLXSW_SP1_PTP_HT_GC_INTERVAL;
|
||||
struct mlxsw_sp_ptp_state *ptp_state = mlxsw_sp->ptp_state;
|
||||
struct mlxsw_sp1_ptp_state *ptp_state = mlxsw_sp1_ptp_state(mlxsw_sp);
|
||||
struct mlxsw_sp1_ptp_unmatched *unmatched;
|
||||
int err;
|
||||
|
||||
@ -359,7 +378,7 @@ mlxsw_sp1_ptp_unmatched_save(struct mlxsw_sp *mlxsw_sp,
|
||||
unmatched->key = key;
|
||||
unmatched->skb = skb;
|
||||
unmatched->timestamp = timestamp;
|
||||
unmatched->gc_cycle = mlxsw_sp->ptp_state->gc_cycle + cycles;
|
||||
unmatched->gc_cycle = ptp_state->gc_cycle + cycles;
|
||||
|
||||
err = rhltable_insert(&ptp_state->unmatched_ht, &unmatched->ht_node,
|
||||
mlxsw_sp1_ptp_unmatched_ht_params);
|
||||
@ -373,11 +392,12 @@ static struct mlxsw_sp1_ptp_unmatched *
|
||||
mlxsw_sp1_ptp_unmatched_lookup(struct mlxsw_sp *mlxsw_sp,
|
||||
struct mlxsw_sp1_ptp_key key, int *p_length)
|
||||
{
|
||||
struct mlxsw_sp1_ptp_state *ptp_state = mlxsw_sp1_ptp_state(mlxsw_sp);
|
||||
struct mlxsw_sp1_ptp_unmatched *unmatched, *last = NULL;
|
||||
struct rhlist_head *tmp, *list;
|
||||
int length = 0;
|
||||
|
||||
list = rhltable_lookup(&mlxsw_sp->ptp_state->unmatched_ht, &key,
|
||||
list = rhltable_lookup(&ptp_state->unmatched_ht, &key,
|
||||
mlxsw_sp1_ptp_unmatched_ht_params);
|
||||
rhl_for_each_entry_rcu(unmatched, tmp, list, ht_node) {
|
||||
last = unmatched;
|
||||
@ -392,7 +412,9 @@ static int
|
||||
mlxsw_sp1_ptp_unmatched_remove(struct mlxsw_sp *mlxsw_sp,
|
||||
struct mlxsw_sp1_ptp_unmatched *unmatched)
|
||||
{
|
||||
return rhltable_remove(&mlxsw_sp->ptp_state->unmatched_ht,
|
||||
struct mlxsw_sp1_ptp_state *ptp_state = mlxsw_sp1_ptp_state(mlxsw_sp);
|
||||
|
||||
return rhltable_remove(&ptp_state->unmatched_ht,
|
||||
&unmatched->ht_node,
|
||||
mlxsw_sp1_ptp_unmatched_ht_params);
|
||||
}
|
||||
@ -438,12 +460,16 @@ static void mlxsw_sp1_packet_timestamp(struct mlxsw_sp *mlxsw_sp,
|
||||
struct sk_buff *skb,
|
||||
u64 timestamp)
|
||||
{
|
||||
struct mlxsw_sp_ptp_clock *clock_common = mlxsw_sp->clock;
|
||||
struct mlxsw_sp1_ptp_clock *clock =
|
||||
container_of(clock_common, struct mlxsw_sp1_ptp_clock, common);
|
||||
|
||||
struct skb_shared_hwtstamps hwtstamps;
|
||||
u64 nsec;
|
||||
|
||||
spin_lock_bh(&mlxsw_sp->clock->lock);
|
||||
nsec = timecounter_cyc2time(&mlxsw_sp->clock->tc, timestamp);
|
||||
spin_unlock_bh(&mlxsw_sp->clock->lock);
|
||||
spin_lock_bh(&clock->lock);
|
||||
nsec = timecounter_cyc2time(&clock->tc, timestamp);
|
||||
spin_unlock_bh(&clock->lock);
|
||||
|
||||
hwtstamps.hwtstamp = ns_to_ktime(nsec);
|
||||
mlxsw_sp1_ptp_packet_finish(mlxsw_sp, skb,
|
||||
@ -481,13 +507,14 @@ static void mlxsw_sp1_ptp_got_piece(struct mlxsw_sp *mlxsw_sp,
|
||||
struct mlxsw_sp1_ptp_key key,
|
||||
struct sk_buff *skb, u64 timestamp)
|
||||
{
|
||||
struct mlxsw_sp1_ptp_state *ptp_state = mlxsw_sp1_ptp_state(mlxsw_sp);
|
||||
struct mlxsw_sp1_ptp_unmatched *unmatched;
|
||||
int length;
|
||||
int err;
|
||||
|
||||
rcu_read_lock();
|
||||
|
||||
spin_lock(&mlxsw_sp->ptp_state->unmatched_lock);
|
||||
spin_lock(&ptp_state->unmatched_lock);
|
||||
|
||||
unmatched = mlxsw_sp1_ptp_unmatched_lookup(mlxsw_sp, key, &length);
|
||||
if (skb && unmatched && unmatched->timestamp) {
|
||||
@ -515,7 +542,7 @@ static void mlxsw_sp1_ptp_got_piece(struct mlxsw_sp *mlxsw_sp,
|
||||
WARN_ON_ONCE(err);
|
||||
}
|
||||
|
||||
spin_unlock(&mlxsw_sp->ptp_state->unmatched_lock);
|
||||
spin_unlock(&ptp_state->unmatched_lock);
|
||||
|
||||
if (unmatched)
|
||||
mlxsw_sp1_ptp_unmatched_finish(mlxsw_sp, unmatched);
|
||||
@ -611,9 +638,10 @@ void mlxsw_sp1_ptp_transmitted(struct mlxsw_sp *mlxsw_sp,
|
||||
}
|
||||
|
||||
static void
|
||||
mlxsw_sp1_ptp_ht_gc_collect(struct mlxsw_sp_ptp_state *ptp_state,
|
||||
mlxsw_sp1_ptp_ht_gc_collect(struct mlxsw_sp1_ptp_state *ptp_state,
|
||||
struct mlxsw_sp1_ptp_unmatched *unmatched)
|
||||
{
|
||||
struct mlxsw_sp *mlxsw_sp = ptp_state->common.mlxsw_sp;
|
||||
struct mlxsw_sp_ptp_port_dir_stats *stats;
|
||||
struct mlxsw_sp_port *mlxsw_sp_port;
|
||||
int err;
|
||||
@ -636,7 +664,7 @@ mlxsw_sp1_ptp_ht_gc_collect(struct mlxsw_sp_ptp_state *ptp_state,
|
||||
/* The packet was matched with timestamp during the walk. */
|
||||
goto out;
|
||||
|
||||
mlxsw_sp_port = ptp_state->mlxsw_sp->ports[unmatched->key.local_port];
|
||||
mlxsw_sp_port = mlxsw_sp->ports[unmatched->key.local_port];
|
||||
if (mlxsw_sp_port) {
|
||||
stats = unmatched->key.ingress ?
|
||||
&mlxsw_sp_port->ptp.stats.rx_gcd :
|
||||
@ -653,7 +681,7 @@ mlxsw_sp1_ptp_ht_gc_collect(struct mlxsw_sp_ptp_state *ptp_state,
|
||||
* netif_receive_skb(), in process context, is seen elsewhere in the
|
||||
* kernel, notably in pktgen.
|
||||
*/
|
||||
mlxsw_sp1_ptp_unmatched_finish(ptp_state->mlxsw_sp, unmatched);
|
||||
mlxsw_sp1_ptp_unmatched_finish(mlxsw_sp, unmatched);
|
||||
|
||||
out:
|
||||
local_bh_enable();
|
||||
@ -663,12 +691,12 @@ static void mlxsw_sp1_ptp_ht_gc(struct work_struct *work)
|
||||
{
|
||||
struct delayed_work *dwork = to_delayed_work(work);
|
||||
struct mlxsw_sp1_ptp_unmatched *unmatched;
|
||||
struct mlxsw_sp_ptp_state *ptp_state;
|
||||
struct mlxsw_sp1_ptp_state *ptp_state;
|
||||
struct rhashtable_iter iter;
|
||||
u32 gc_cycle;
|
||||
void *obj;
|
||||
|
||||
ptp_state = container_of(dwork, struct mlxsw_sp_ptp_state, ht_gc_dw);
|
||||
ptp_state = container_of(dwork, struct mlxsw_sp1_ptp_state, ht_gc_dw);
|
||||
gc_cycle = ptp_state->gc_cycle++;
|
||||
|
||||
rhltable_walk_enter(&ptp_state->unmatched_ht, &iter);
|
||||
@ -694,7 +722,7 @@ static int mlxsw_sp_ptp_mtptpt_set(struct mlxsw_sp *mlxsw_sp,
|
||||
{
|
||||
char mtptpt_pl[MLXSW_REG_MTPTPT_LEN];
|
||||
|
||||
mlxsw_reg_mtptptp_pack(mtptpt_pl, trap_id, message_type);
|
||||
mlxsw_reg_mtptpt_pack(mtptpt_pl, trap_id, message_type);
|
||||
return mlxsw_reg_write(mlxsw_sp->core, MLXSW_REG(mtptpt), mtptpt_pl);
|
||||
}
|
||||
|
||||
@ -809,7 +837,7 @@ static int mlxsw_sp1_ptp_shaper_params_set(struct mlxsw_sp *mlxsw_sp)
|
||||
|
||||
struct mlxsw_sp_ptp_state *mlxsw_sp1_ptp_init(struct mlxsw_sp *mlxsw_sp)
|
||||
{
|
||||
struct mlxsw_sp_ptp_state *ptp_state;
|
||||
struct mlxsw_sp1_ptp_state *ptp_state;
|
||||
u16 message_type;
|
||||
int err;
|
||||
|
||||
@ -820,7 +848,7 @@ struct mlxsw_sp_ptp_state *mlxsw_sp1_ptp_init(struct mlxsw_sp *mlxsw_sp)
|
||||
ptp_state = kzalloc(sizeof(*ptp_state), GFP_KERNEL);
|
||||
if (!ptp_state)
|
||||
return ERR_PTR(-ENOMEM);
|
||||
ptp_state->mlxsw_sp = mlxsw_sp;
|
||||
ptp_state->common.mlxsw_sp = mlxsw_sp;
|
||||
|
||||
spin_lock_init(&ptp_state->unmatched_lock);
|
||||
|
||||
@ -853,7 +881,7 @@ struct mlxsw_sp_ptp_state *mlxsw_sp1_ptp_init(struct mlxsw_sp *mlxsw_sp)
|
||||
INIT_DELAYED_WORK(&ptp_state->ht_gc_dw, mlxsw_sp1_ptp_ht_gc);
|
||||
mlxsw_core_schedule_dw(&ptp_state->ht_gc_dw,
|
||||
MLXSW_SP1_PTP_HT_GC_INTERVAL);
|
||||
return ptp_state;
|
||||
return &ptp_state->common;
|
||||
|
||||
err_fifo_clr:
|
||||
mlxsw_sp_ptp_mtptpt_set(mlxsw_sp, MLXSW_REG_MTPTPT_TRAP_ID_PTP1, 0);
|
||||
@ -866,9 +894,12 @@ err_hashtable_init:
|
||||
return ERR_PTR(err);
|
||||
}
|
||||
|
||||
void mlxsw_sp1_ptp_fini(struct mlxsw_sp_ptp_state *ptp_state)
|
||||
void mlxsw_sp1_ptp_fini(struct mlxsw_sp_ptp_state *ptp_state_common)
|
||||
{
|
||||
struct mlxsw_sp *mlxsw_sp = ptp_state->mlxsw_sp;
|
||||
struct mlxsw_sp *mlxsw_sp = ptp_state_common->mlxsw_sp;
|
||||
struct mlxsw_sp1_ptp_state *ptp_state;
|
||||
|
||||
ptp_state = mlxsw_sp1_ptp_state(mlxsw_sp);
|
||||
|
||||
cancel_delayed_work_sync(&ptp_state->ht_gc_dw);
|
||||
mlxsw_sp1_ptp_mtpppc_set(mlxsw_sp, 0, 0);
|
||||
@ -887,9 +918,10 @@ int mlxsw_sp1_ptp_hwtstamp_get(struct mlxsw_sp_port *mlxsw_sp_port,
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int mlxsw_sp_ptp_get_message_types(const struct hwtstamp_config *config,
|
||||
u16 *p_ing_types, u16 *p_egr_types,
|
||||
enum hwtstamp_rx_filters *p_rx_filter)
|
||||
static int
|
||||
mlxsw_sp1_ptp_get_message_types(const struct hwtstamp_config *config,
|
||||
u16 *p_ing_types, u16 *p_egr_types,
|
||||
enum hwtstamp_rx_filters *p_rx_filter)
|
||||
{
|
||||
enum hwtstamp_rx_filters rx_filter = config->rx_filter;
|
||||
enum hwtstamp_tx_types tx_type = config->tx_type;
|
||||
@ -1050,8 +1082,8 @@ int mlxsw_sp1_ptp_hwtstamp_set(struct mlxsw_sp_port *mlxsw_sp_port,
|
||||
u16 egr_types;
|
||||
int err;
|
||||
|
||||
err = mlxsw_sp_ptp_get_message_types(config, &ing_types, &egr_types,
|
||||
&rx_filter);
|
||||
err = mlxsw_sp1_ptp_get_message_types(config, &ing_types, &egr_types,
|
||||
&rx_filter);
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user