Back to home page

OSCL-LXR

 
 

    


0001 /* SPDX-License-Identifier: (GPL-2.0 or MIT) */
0002 /*
0003  * DSA driver for:
0004  * Hirschmann Hellcreek TSN switch.
0005  *
0006  * Copyright (C) 2019-2021 Linutronix GmbH
0007  * Author Kurt Kanzenbach <kurt@linutronix.de>
0008  */
0009 
0010 #ifndef _HELLCREEK_H_
0011 #define _HELLCREEK_H_
0012 
0013 #include <linux/bitmap.h>
0014 #include <linux/bitops.h>
0015 #include <linux/device.h>
0016 #include <linux/kernel.h>
0017 #include <linux/mutex.h>
0018 #include <linux/workqueue.h>
0019 #include <linux/leds.h>
0020 #include <linux/platform_data/hirschmann-hellcreek.h>
0021 #include <linux/ptp_clock_kernel.h>
0022 #include <linux/timecounter.h>
0023 #include <net/dsa.h>
0024 #include <net/pkt_sched.h>
0025 
0026 /* Ports:
0027  *  - 0: CPU
0028  *  - 1: Tunnel
0029  *  - 2: TSN front port 1
0030  *  - 3: TSN front port 2
0031  *  - ...
0032  */
0033 #define CPU_PORT            0
0034 #define TUNNEL_PORT         1
0035 
0036 #define HELLCREEK_VLAN_NO_MEMBER    0x0
0037 #define HELLCREEK_VLAN_UNTAGGED_MEMBER  0x1
0038 #define HELLCREEK_VLAN_TAGGED_MEMBER    0x3
0039 #define HELLCREEK_NUM_EGRESS_QUEUES 8
0040 
0041 /* Register definitions */
0042 #define HR_MODID_C          (0 * 2)
0043 #define HR_REL_L_C          (1 * 2)
0044 #define HR_REL_H_C          (2 * 2)
0045 #define HR_BLD_L_C          (3 * 2)
0046 #define HR_BLD_H_C          (4 * 2)
0047 #define HR_CTRL_C           (5 * 2)
0048 #define HR_CTRL_C_READY         BIT(14)
0049 #define HR_CTRL_C_TRANSITION        BIT(13)
0050 #define HR_CTRL_C_ENABLE        BIT(0)
0051 
0052 #define HR_PSEL             (0xa6 * 2)
0053 #define HR_PSEL_PTWSEL_SHIFT        4
0054 #define HR_PSEL_PTWSEL_MASK     GENMASK(5, 4)
0055 #define HR_PSEL_PRTCWSEL_SHIFT      0
0056 #define HR_PSEL_PRTCWSEL_MASK       GENMASK(2, 0)
0057 
0058 #define HR_PTCFG            (0xa7 * 2)
0059 #define HR_PTCFG_MLIMIT_EN      BIT(13)
0060 #define HR_PTCFG_UMC_FLT        BIT(10)
0061 #define HR_PTCFG_UUC_FLT        BIT(9)
0062 #define HR_PTCFG_UNTRUST        BIT(8)
0063 #define HR_PTCFG_TAG_REQUIRED       BIT(7)
0064 #define HR_PTCFG_PPRIO_SHIFT        4
0065 #define HR_PTCFG_PPRIO_MASK     GENMASK(6, 4)
0066 #define HR_PTCFG_INGRESSFLT     BIT(3)
0067 #define HR_PTCFG_BLOCKED        BIT(2)
0068 #define HR_PTCFG_LEARNING_EN        BIT(1)
0069 #define HR_PTCFG_ADMIN_EN       BIT(0)
0070 
0071 #define HR_PRTCCFG          (0xa8 * 2)
0072 #define HR_PRTCCFG_PCP_TC_MAP_SHIFT 0
0073 #define HR_PRTCCFG_PCP_TC_MAP_MASK  GENMASK(2, 0)
0074 
0075 #define HR_CSEL             (0x8d * 2)
0076 #define HR_CSEL_SHIFT           0
0077 #define HR_CSEL_MASK            GENMASK(7, 0)
0078 #define HR_CRDL             (0x8e * 2)
0079 #define HR_CRDH             (0x8f * 2)
0080 
0081 #define HR_SWTRC_CFG            (0x90 * 2)
0082 #define HR_SWTRC0           (0x91 * 2)
0083 #define HR_SWTRC1           (0x92 * 2)
0084 #define HR_PFREE            (0x93 * 2)
0085 #define HR_MFREE            (0x94 * 2)
0086 
0087 #define HR_FDBAGE           (0x97 * 2)
0088 #define HR_FDBMAX           (0x98 * 2)
0089 #define HR_FDBRDL           (0x99 * 2)
0090 #define HR_FDBRDM           (0x9a * 2)
0091 #define HR_FDBRDH           (0x9b * 2)
0092 
0093 #define HR_FDBMDRD          (0x9c * 2)
0094 #define HR_FDBMDRD_PORTMASK_SHIFT   0
0095 #define HR_FDBMDRD_PORTMASK_MASK    GENMASK(3, 0)
0096 #define HR_FDBMDRD_AGE_SHIFT        4
0097 #define HR_FDBMDRD_AGE_MASK     GENMASK(7, 4)
0098 #define HR_FDBMDRD_OBT          BIT(8)
0099 #define HR_FDBMDRD_PASS_BLOCKED     BIT(9)
0100 #define HR_FDBMDRD_STATIC       BIT(11)
0101 #define HR_FDBMDRD_REPRIO_TC_SHIFT  12
0102 #define HR_FDBMDRD_REPRIO_TC_MASK   GENMASK(14, 12)
0103 #define HR_FDBMDRD_REPRIO_EN        BIT(15)
0104 
0105 #define HR_FDBWDL           (0x9d * 2)
0106 #define HR_FDBWDM           (0x9e * 2)
0107 #define HR_FDBWDH           (0x9f * 2)
0108 #define HR_FDBWRM0          (0xa0 * 2)
0109 #define HR_FDBWRM0_PORTMASK_SHIFT   0
0110 #define HR_FDBWRM0_PORTMASK_MASK    GENMASK(3, 0)
0111 #define HR_FDBWRM0_OBT          BIT(8)
0112 #define HR_FDBWRM0_PASS_BLOCKED     BIT(9)
0113 #define HR_FDBWRM0_REPRIO_TC_SHIFT  12
0114 #define HR_FDBWRM0_REPRIO_TC_MASK   GENMASK(14, 12)
0115 #define HR_FDBWRM0_REPRIO_EN        BIT(15)
0116 #define HR_FDBWRM1          (0xa1 * 2)
0117 
0118 #define HR_FDBWRCMD         (0xa2 * 2)
0119 #define HR_FDBWRCMD_FDBDEL      BIT(9)
0120 
0121 #define HR_SWCFG            (0xa3 * 2)
0122 #define HR_SWCFG_GM_STATEMD     BIT(15)
0123 #define HR_SWCFG_LAS_MODE_SHIFT     12
0124 #define HR_SWCFG_LAS_MODE_MASK      GENMASK(13, 12)
0125 #define HR_SWCFG_LAS_OFF        (0x00)
0126 #define HR_SWCFG_LAS_ON         (0x01)
0127 #define HR_SWCFG_LAS_STATIC     (0x10)
0128 #define HR_SWCFG_CT_EN          BIT(11)
0129 #define HR_SWCFG_VLAN_UNAWARE       BIT(10)
0130 #define HR_SWCFG_ALWAYS_OBT     BIT(9)
0131 #define HR_SWCFG_FDBAGE_EN      BIT(5)
0132 #define HR_SWCFG_FDBLRN_EN      BIT(4)
0133 
0134 #define HR_SWSTAT           (0xa4 * 2)
0135 #define HR_SWSTAT_FAIL          BIT(4)
0136 #define HR_SWSTAT_BUSY          BIT(0)
0137 
0138 #define HR_SWCMD            (0xa5 * 2)
0139 #define HW_SWCMD_FLUSH          BIT(0)
0140 
0141 #define HR_VIDCFG           (0xaa * 2)
0142 #define HR_VIDCFG_VID_SHIFT     0
0143 #define HR_VIDCFG_VID_MASK      GENMASK(11, 0)
0144 #define HR_VIDCFG_PVID          BIT(12)
0145 
0146 #define HR_VIDMBRCFG            (0xab * 2)
0147 #define HR_VIDMBRCFG_P0MBR_SHIFT    0
0148 #define HR_VIDMBRCFG_P0MBR_MASK     GENMASK(1, 0)
0149 #define HR_VIDMBRCFG_P1MBR_SHIFT    2
0150 #define HR_VIDMBRCFG_P1MBR_MASK     GENMASK(3, 2)
0151 #define HR_VIDMBRCFG_P2MBR_SHIFT    4
0152 #define HR_VIDMBRCFG_P2MBR_MASK     GENMASK(5, 4)
0153 #define HR_VIDMBRCFG_P3MBR_SHIFT    6
0154 #define HR_VIDMBRCFG_P3MBR_MASK     GENMASK(7, 6)
0155 
0156 #define HR_FEABITS0         (0xac * 2)
0157 #define HR_FEABITS0_FDBBINS_SHIFT   4
0158 #define HR_FEABITS0_FDBBINS_MASK    GENMASK(7, 4)
0159 #define HR_FEABITS0_PCNT_SHIFT      8
0160 #define HR_FEABITS0_PCNT_MASK       GENMASK(11, 8)
0161 #define HR_FEABITS0_MCNT_SHIFT      12
0162 #define HR_FEABITS0_MCNT_MASK       GENMASK(15, 12)
0163 
0164 #define TR_QTRACK           (0xb1 * 2)
0165 #define TR_TGDVER           (0xb3 * 2)
0166 #define TR_TGDVER_REV_MIN_MASK      GENMASK(7, 0)
0167 #define TR_TGDVER_REV_MIN_SHIFT     0
0168 #define TR_TGDVER_REV_MAJ_MASK      GENMASK(15, 8)
0169 #define TR_TGDVER_REV_MAJ_SHIFT     8
0170 #define TR_TGDSEL           (0xb4 * 2)
0171 #define TR_TGDSEL_TDGSEL_MASK       GENMASK(1, 0)
0172 #define TR_TGDSEL_TDGSEL_SHIFT      0
0173 #define TR_TGDCTRL          (0xb5 * 2)
0174 #define TR_TGDCTRL_GATE_EN      BIT(0)
0175 #define TR_TGDCTRL_CYC_SNAP     BIT(4)
0176 #define TR_TGDCTRL_SNAP_EST     BIT(5)
0177 #define TR_TGDCTRL_ADMINGATESTATES_MASK GENMASK(15, 8)
0178 #define TR_TGDCTRL_ADMINGATESTATES_SHIFT    8
0179 #define TR_TGDSTAT0         (0xb6 * 2)
0180 #define TR_TGDSTAT1         (0xb7 * 2)
0181 #define TR_ESTWRL           (0xb8 * 2)
0182 #define TR_ESTWRH           (0xb9 * 2)
0183 #define TR_ESTCMD           (0xba * 2)
0184 #define TR_ESTCMD_ESTSEC_MASK       GENMASK(2, 0)
0185 #define TR_ESTCMD_ESTSEC_SHIFT      0
0186 #define TR_ESTCMD_ESTARM        BIT(4)
0187 #define TR_ESTCMD_ESTSWCFG      BIT(5)
0188 #define TR_EETWRL           (0xbb * 2)
0189 #define TR_EETWRH           (0xbc * 2)
0190 #define TR_EETCMD           (0xbd * 2)
0191 #define TR_EETCMD_EETSEC_MASK       GEMASK(2, 0)
0192 #define TR_EETCMD_EETSEC_SHIFT      0
0193 #define TR_EETCMD_EETARM        BIT(4)
0194 #define TR_CTWRL            (0xbe * 2)
0195 #define TR_CTWRH            (0xbf * 2)
0196 #define TR_LCNSL            (0xc1 * 2)
0197 #define TR_LCNSH            (0xc2 * 2)
0198 #define TR_LCS              (0xc3 * 2)
0199 #define TR_GCLDAT           (0xc4 * 2)
0200 #define TR_GCLDAT_GCLWRGATES_MASK   GENMASK(7, 0)
0201 #define TR_GCLDAT_GCLWRGATES_SHIFT  0
0202 #define TR_GCLDAT_GCLWRLAST     BIT(8)
0203 #define TR_GCLDAT_GCLOVRI       BIT(9)
0204 #define TR_GCLTIL           (0xc5 * 2)
0205 #define TR_GCLTIH           (0xc6 * 2)
0206 #define TR_GCLCMD           (0xc7 * 2)
0207 #define TR_GCLCMD_GCLWRADR_MASK     GENMASK(7, 0)
0208 #define TR_GCLCMD_GCLWRADR_SHIFT    0
0209 #define TR_GCLCMD_INIT_GATE_STATES_MASK GENMASK(15, 8)
0210 #define TR_GCLCMD_INIT_GATE_STATES_SHIFT    8
0211 
0212 struct hellcreek_counter {
0213     u8 offset;
0214     const char *name;
0215 };
0216 
0217 struct hellcreek;
0218 
0219 /* State flags for hellcreek_port_hwtstamp::state */
0220 enum {
0221     HELLCREEK_HWTSTAMP_ENABLED,
0222     HELLCREEK_HWTSTAMP_TX_IN_PROGRESS,
0223 };
0224 
0225 /* A structure to hold hardware timestamping information per port */
0226 struct hellcreek_port_hwtstamp {
0227     /* Timestamping state */
0228     unsigned long state;
0229 
0230     /* Resources for receive timestamping */
0231     struct sk_buff_head rx_queue; /* For synchronization messages */
0232 
0233     /* Resources for transmit timestamping */
0234     unsigned long tx_tstamp_start;
0235     struct sk_buff *tx_skb;
0236 
0237     /* Current timestamp configuration */
0238     struct hwtstamp_config tstamp_config;
0239 };
0240 
0241 struct hellcreek_port {
0242     struct hellcreek *hellcreek;
0243     unsigned long *vlan_dev_bitmap;
0244     int port;
0245     u16 ptcfg;      /* ptcfg shadow */
0246     u64 *counter_values;
0247 
0248     /* Per-port timestamping resources */
0249     struct hellcreek_port_hwtstamp port_hwtstamp;
0250 
0251     /* Per-port Qbv schedule information */
0252     struct tc_taprio_qopt_offload *current_schedule;
0253     struct delayed_work schedule_work;
0254 };
0255 
0256 struct hellcreek_fdb_entry {
0257     size_t idx;
0258     unsigned char mac[ETH_ALEN];
0259     u8 portmask;
0260     u8 age;
0261     u8 is_obt;
0262     u8 pass_blocked;
0263     u8 is_static;
0264     u8 reprio_tc;
0265     u8 reprio_en;
0266 };
0267 
0268 struct hellcreek {
0269     const struct hellcreek_platform_data *pdata;
0270     struct device *dev;
0271     struct dsa_switch *ds;
0272     struct ptp_clock *ptp_clock;
0273     struct ptp_clock_info ptp_clock_info;
0274     struct hellcreek_port *ports;
0275     struct delayed_work overflow_work;
0276     struct led_classdev led_is_gm;
0277     struct led_classdev led_sync_good;
0278     struct mutex reg_lock;  /* Switch IP register lock */
0279     struct mutex vlan_lock; /* VLAN bitmaps lock */
0280     struct mutex ptp_lock;  /* PTP IP register lock */
0281     struct devlink_region *vlan_region;
0282     struct devlink_region *fdb_region;
0283     void __iomem *base;
0284     void __iomem *ptp_base;
0285     u16 swcfg;      /* swcfg shadow */
0286     u8 *vidmbrcfg;      /* vidmbrcfg shadow */
0287     u64 seconds;        /* PTP seconds */
0288     u64 last_ts;        /* Used for overflow detection */
0289     u16 status_out;     /* ptp.status_out shadow */
0290     size_t fdb_entries;
0291 };
0292 
0293 /* A Qbv schedule can only started up to 8 seconds in the future. If the delta
0294  * between the base time and the current ptp time is larger than 8 seconds, then
0295  * use periodic work to check for the schedule to be started. The delayed work
0296  * cannot be armed directly to $base_time - 8 + X, because for large deltas the
0297  * PTP frequency matters.
0298  */
0299 #define HELLCREEK_SCHEDULE_PERIOD   (2 * HZ)
0300 #define dw_to_hellcreek_port(dw)                \
0301     container_of(dw, struct hellcreek_port, schedule_work)
0302 
0303 /* Devlink resources */
0304 enum hellcreek_devlink_resource_id {
0305     HELLCREEK_DEVLINK_PARAM_ID_VLAN_TABLE,
0306     HELLCREEK_DEVLINK_PARAM_ID_FDB_TABLE,
0307 };
0308 
0309 struct hellcreek_devlink_vlan_entry {
0310     u16 vid;
0311     u16 member;
0312 };
0313 
0314 #endif /* _HELLCREEK_H_ */