Add support for HSR and PRP protocol frame filtering in the ICSSG classifier by configuring filter table 3 (FT3) to detect PTP frames (EtherType 0x88F7) in HSR/PRP tagged packets. Also add rx_class_or_base to miig_rt_offsets structure to support RX_CLASS_OR register access, and fix typos in FT1_N_REG and FT3_N_REG macros (slize -> slice). Signed-off-by: MD Danish Anwar --- .../net/ethernet/ti/icssg/icssg_classifier.c | 69 ++++++++++++++++++- drivers/net/ethernet/ti/icssg/icssg_prueth.c | 6 ++ drivers/net/ethernet/ti/icssg/icssg_prueth.h | 2 + 3 files changed, 75 insertions(+), 2 deletions(-) diff --git a/drivers/net/ethernet/ti/icssg/icssg_classifier.c b/drivers/net/ethernet/ti/icssg/icssg_classifier.c index 833ca86d0b71..cde53d9aaa7b 100644 --- a/drivers/net/ethernet/ti/icssg/icssg_classifier.c +++ b/drivers/net/ethernet/ti/icssg/icssg_classifier.c @@ -27,7 +27,7 @@ #define FT1_DA0_MASK 0x8 #define FT1_DA1_MASK 0xc -#define FT1_N_REG(slize, n, reg) \ +#define FT1_N_REG(slice, n, reg) \ (offs[slice].ft1_slot_base + FT1_SLOT_SIZE * (n) + (reg)) #define FT1_LEN_MASK GENMASK(19, 16) @@ -62,7 +62,7 @@ enum ft1_cfg_type { #define FT3_T 0x18 #define FT3_T_MASK 0x1c -#define FT3_N_REG(slize, n, reg) \ +#define FT3_N_REG(slice, n, reg) \ (offs[slice].ft3_slot_base + FT3_SLOT_SIZE * (n) + (reg)) /* offsets from rx_class n's base */ @@ -74,6 +74,9 @@ enum ft1_cfg_type { #define RX_CLASS_N_REG(slice, n, reg) \ (offs[slice].rx_class_base + RX_CLASS_EN_SIZE * (n) + (reg)) +#define RX_CLASS_OR_REG(slice, n, reg) \ + (offs[slice].rx_class_or_base + RX_CLASS_EN_SIZE * (n) + (reg)) + /* RX Class Gates */ #define RX_CLASS_GATES_SIZE 0x4 /* bytes */ @@ -102,6 +105,22 @@ enum ft1_cfg_type { ((BIT(slot) << RX_CLASS_FT_FT1_MATCH_SHIFT) & \ RX_CLASS_FT_FT1_MATCH_MASK) +/* HSR/PRP protocol frame filtering */ +#define HSR_PTP_ETHERTYPE_OFFSET 0x12 +#define PRP_PTP_ETHERTYPE_OFFSET 0x0C +#define FT3_PTP_PATTERN 0xF788 +#define FT3_ETHERTYPE_MASK 0xFFFF0000U +#define FT3_VLAN_MODE_BOTH 0x1 +#define RX_CLASS_OR_DUP_PTP 0x4200 +#define RX_CLASS_OR_HSR_TAG 0x4000 +#define RX_CLASS_GATE_PTP 0x50 +#define RX_CLASS_DISABLE 0x0 + +/* HSR/PRP classifier indices */ +#define CLASSIFIER_PTP_DUP 10 +#define CLASSIFIER_HSR_TAG 11 +#define FT3_PTP_SLOT 14 + /* RX class type */ enum rx_class_sel_type { RX_CLASS_SEL_TYPE_OR = 0, @@ -133,6 +152,7 @@ struct miig_rt_offsets { u32 ft3_p_base; u32 ft_rx_ptr; u32 rx_class_base; + u32 rx_class_or_base; u32 rx_class_cfg1; u32 rx_class_cfg2; u32 rx_class_gates_base; @@ -161,6 +181,7 @@ static const struct miig_rt_offsets offs[] = { 0x308, 0x408, 0x40c, + 0x410, 0x48c, 0x490, 0x494, @@ -186,6 +207,7 @@ static const struct miig_rt_offsets offs[] = { 0x8d4, 0x9d4, 0x9d8, + 0x9dc, 0xa58, 0xa5c, 0xa60, @@ -467,3 +489,46 @@ void icssg_ft1_set_mac_addr(struct regmap *miig_rt, int slice, u8 *mac_addr) rx_class_ft1_cfg_set_type(miig_rt, slice, 0, FT1_CFG_TYPE_EQ); } EXPORT_SYMBOL_GPL(icssg_ft1_set_mac_addr); + +/** + * icssg_ft3_hsr_configurations - Configure filter table for HSR/PRP protocol frames + * @miig_rt: Pointer to the MII-G register map + * @slice: ICSSG slice number (0 or 1) + * @prueth: Pointer to prueth structure to determine HSR/PRP mode + * + * Configures FT3 to detect PTP frames (EtherType 0x88F7) in HSR/PRP tagged packets. + * HSR frames have a 6-byte tag, while PRP has no tag offset for EtherType detection. + */ +void icssg_ft3_hsr_configurations(struct regmap *miig_rt, int slice, + struct prueth *prueth) +{ + u8 offset = (prueth->hsr_prp_version == PRP_V1) ? + PRP_PTP_ETHERTYPE_OFFSET : HSR_PTP_ETHERTYPE_OFFSET; + + regmap_write(miig_rt, FT3_N_REG(slice, FT3_PTP_SLOT, FT3_START), offset); + regmap_write(miig_rt, FT3_N_REG(slice, FT3_PTP_SLOT, FT3_START_AUTO), 0); + regmap_write(miig_rt, FT3_N_REG(slice, FT3_PTP_SLOT, FT3_START_OFFSET), 0); + regmap_write(miig_rt, FT3_N_REG(slice, FT3_PTP_SLOT, FT3_JUMP_OFFSET), 0); + regmap_write(miig_rt, FT3_N_REG(slice, FT3_PTP_SLOT, FT3_LEN), 0); + regmap_write(miig_rt, FT3_N_REG(slice, FT3_PTP_SLOT, FT3_CFG), FT3_VLAN_MODE_BOTH); + regmap_write(miig_rt, FT3_N_REG(slice, FT3_PTP_SLOT, FT3_T), FT3_PTP_PATTERN); + regmap_write(miig_rt, FT3_N_REG(slice, FT3_PTP_SLOT, FT3_T_MASK), + FT3_ETHERTYPE_MASK); + + regmap_write(miig_rt, RX_CLASS_N_REG(slice, CLASSIFIER_PTP_DUP, RX_CLASS_AND_EN), + RX_CLASS_DISABLE); + regmap_write(miig_rt, RX_CLASS_OR_REG(slice, CLASSIFIER_PTP_DUP, RX_CLASS_OR_EN), + RX_CLASS_OR_DUP_PTP); + regmap_write(miig_rt, RX_CLASS_GATES_N_REG(slice, CLASSIFIER_PTP_DUP), + RX_CLASS_GATE_PTP); + + if (prueth->hsr_prp_version != PRP_V1) { + regmap_write(miig_rt, RX_CLASS_N_REG(slice, CLASSIFIER_HSR_TAG, RX_CLASS_AND_EN), + RX_CLASS_DISABLE); + regmap_write(miig_rt, RX_CLASS_OR_REG(slice, CLASSIFIER_HSR_TAG, RX_CLASS_OR_EN), + RX_CLASS_OR_HSR_TAG); + regmap_write(miig_rt, RX_CLASS_GATES_N_REG(slice, CLASSIFIER_HSR_TAG), + RX_CLASS_GATE_PTP); + } +} +EXPORT_SYMBOL_GPL(icssg_ft3_hsr_configurations); diff --git a/drivers/net/ethernet/ti/icssg/icssg_prueth.c b/drivers/net/ethernet/ti/icssg/icssg_prueth.c index 0939994c932f..9efa39069c8c 100644 --- a/drivers/net/ethernet/ti/icssg/icssg_prueth.c +++ b/drivers/net/ethernet/ti/icssg/icssg_prueth.c @@ -260,6 +260,12 @@ static int prueth_emac_common_start(struct prueth *prueth) icssg_class_default(prueth->miig_rt, ICSS_SLICE0, 0, false); icssg_class_default(prueth->miig_rt, ICSS_SLICE1, 0, false); + /* Configure HSR/PRP protocol filtering if in HSR offload mode */ + if (prueth->is_hsr_offload_mode) { + icssg_ft3_hsr_configurations(prueth->miig_rt, ICSS_SLICE0, prueth); + icssg_ft3_hsr_configurations(prueth->miig_rt, ICSS_SLICE1, prueth); + } + if (prueth->is_switch_mode || prueth->is_hsr_offload_mode) icssg_init_fw_offload_mode(prueth); else diff --git a/drivers/net/ethernet/ti/icssg/icssg_prueth.h b/drivers/net/ethernet/ti/icssg/icssg_prueth.h index 3d94fa5a7ac1..df93d15c5b78 100644 --- a/drivers/net/ethernet/ti/icssg/icssg_prueth.h +++ b/drivers/net/ethernet/ti/icssg/icssg_prueth.h @@ -423,6 +423,8 @@ void icssg_class_promiscuous_sr1(struct regmap *miig_rt, int slice); void icssg_class_add_mcast_sr1(struct regmap *miig_rt, int slice, struct net_device *ndev); void icssg_ft1_set_mac_addr(struct regmap *miig_rt, int slice, u8 *mac_addr); +void icssg_ft3_hsr_configurations(struct regmap *miig_rt, int slice, + struct prueth *prueth); /* config helpers */ void icssg_config_ipg(struct prueth_emac *emac); base-commit: fd6dad4e1ae296b67b87291256878a58dad36c93 -- 2.34.1