hellcreek.h 9.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321
  1. /* SPDX-License-Identifier: (GPL-2.0 or MIT) */
  2. /*
  3. * DSA driver for:
  4. * Hirschmann Hellcreek TSN switch.
  5. *
  6. * Copyright (C) 2019-2021 Linutronix GmbH
  7. * Author Kurt Kanzenbach <[email protected]>
  8. */
  9. #ifndef _HELLCREEK_H_
  10. #define _HELLCREEK_H_
  11. #include <linux/bitmap.h>
  12. #include <linux/bitops.h>
  13. #include <linux/device.h>
  14. #include <linux/kernel.h>
  15. #include <linux/mutex.h>
  16. #include <linux/workqueue.h>
  17. #include <linux/leds.h>
  18. #include <linux/platform_data/hirschmann-hellcreek.h>
  19. #include <linux/ptp_clock_kernel.h>
  20. #include <linux/timecounter.h>
  21. #include <net/dsa.h>
  22. #include <net/pkt_sched.h>
  23. /* Ports:
  24. * - 0: CPU
  25. * - 1: Tunnel
  26. * - 2: TSN front port 1
  27. * - 3: TSN front port 2
  28. * - ...
  29. */
  30. #define CPU_PORT 0
  31. #define TUNNEL_PORT 1
  32. #define HELLCREEK_VLAN_NO_MEMBER 0x0
  33. #define HELLCREEK_VLAN_UNTAGGED_MEMBER 0x1
  34. #define HELLCREEK_VLAN_TAGGED_MEMBER 0x3
  35. #define HELLCREEK_NUM_EGRESS_QUEUES 8
  36. #define HELLCREEK_DEFAULT_MAX_SDU 1536
  37. /* Register definitions */
  38. #define HR_MODID_C (0 * 2)
  39. #define HR_REL_L_C (1 * 2)
  40. #define HR_REL_H_C (2 * 2)
  41. #define HR_BLD_L_C (3 * 2)
  42. #define HR_BLD_H_C (4 * 2)
  43. #define HR_CTRL_C (5 * 2)
  44. #define HR_CTRL_C_READY BIT(14)
  45. #define HR_CTRL_C_TRANSITION BIT(13)
  46. #define HR_CTRL_C_ENABLE BIT(0)
  47. #define HR_PSEL (0xa6 * 2)
  48. #define HR_PSEL_PTWSEL_SHIFT 4
  49. #define HR_PSEL_PTWSEL_MASK GENMASK(5, 4)
  50. #define HR_PSEL_PRTCWSEL_SHIFT 0
  51. #define HR_PSEL_PRTCWSEL_MASK GENMASK(2, 0)
  52. #define HR_PTCFG (0xa7 * 2)
  53. #define HR_PTCFG_MLIMIT_EN BIT(13)
  54. #define HR_PTCFG_UMC_FLT BIT(10)
  55. #define HR_PTCFG_UUC_FLT BIT(9)
  56. #define HR_PTCFG_UNTRUST BIT(8)
  57. #define HR_PTCFG_TAG_REQUIRED BIT(7)
  58. #define HR_PTCFG_PPRIO_SHIFT 4
  59. #define HR_PTCFG_PPRIO_MASK GENMASK(6, 4)
  60. #define HR_PTCFG_INGRESSFLT BIT(3)
  61. #define HR_PTCFG_BLOCKED BIT(2)
  62. #define HR_PTCFG_LEARNING_EN BIT(1)
  63. #define HR_PTCFG_ADMIN_EN BIT(0)
  64. #define HR_PRTCCFG (0xa8 * 2)
  65. #define HR_PRTCCFG_PCP_TC_MAP_SHIFT 0
  66. #define HR_PRTCCFG_PCP_TC_MAP_MASK GENMASK(2, 0)
  67. #define HR_PTPRTCCFG (0xa9 * 2)
  68. #define HR_PTPRTCCFG_SET_QTRACK BIT(15)
  69. #define HR_PTPRTCCFG_REJECT BIT(14)
  70. #define HR_PTPRTCCFG_MAXSDU_SHIFT 0
  71. #define HR_PTPRTCCFG_MAXSDU_MASK GENMASK(10, 0)
  72. #define HR_CSEL (0x8d * 2)
  73. #define HR_CSEL_SHIFT 0
  74. #define HR_CSEL_MASK GENMASK(7, 0)
  75. #define HR_CRDL (0x8e * 2)
  76. #define HR_CRDH (0x8f * 2)
  77. #define HR_SWTRC_CFG (0x90 * 2)
  78. #define HR_SWTRC0 (0x91 * 2)
  79. #define HR_SWTRC1 (0x92 * 2)
  80. #define HR_PFREE (0x93 * 2)
  81. #define HR_MFREE (0x94 * 2)
  82. #define HR_FDBAGE (0x97 * 2)
  83. #define HR_FDBMAX (0x98 * 2)
  84. #define HR_FDBRDL (0x99 * 2)
  85. #define HR_FDBRDM (0x9a * 2)
  86. #define HR_FDBRDH (0x9b * 2)
  87. #define HR_FDBMDRD (0x9c * 2)
  88. #define HR_FDBMDRD_PORTMASK_SHIFT 0
  89. #define HR_FDBMDRD_PORTMASK_MASK GENMASK(3, 0)
  90. #define HR_FDBMDRD_AGE_SHIFT 4
  91. #define HR_FDBMDRD_AGE_MASK GENMASK(7, 4)
  92. #define HR_FDBMDRD_OBT BIT(8)
  93. #define HR_FDBMDRD_PASS_BLOCKED BIT(9)
  94. #define HR_FDBMDRD_STATIC BIT(11)
  95. #define HR_FDBMDRD_REPRIO_TC_SHIFT 12
  96. #define HR_FDBMDRD_REPRIO_TC_MASK GENMASK(14, 12)
  97. #define HR_FDBMDRD_REPRIO_EN BIT(15)
  98. #define HR_FDBWDL (0x9d * 2)
  99. #define HR_FDBWDM (0x9e * 2)
  100. #define HR_FDBWDH (0x9f * 2)
  101. #define HR_FDBWRM0 (0xa0 * 2)
  102. #define HR_FDBWRM0_PORTMASK_SHIFT 0
  103. #define HR_FDBWRM0_PORTMASK_MASK GENMASK(3, 0)
  104. #define HR_FDBWRM0_OBT BIT(8)
  105. #define HR_FDBWRM0_PASS_BLOCKED BIT(9)
  106. #define HR_FDBWRM0_REPRIO_TC_SHIFT 12
  107. #define HR_FDBWRM0_REPRIO_TC_MASK GENMASK(14, 12)
  108. #define HR_FDBWRM0_REPRIO_EN BIT(15)
  109. #define HR_FDBWRM1 (0xa1 * 2)
  110. #define HR_FDBWRCMD (0xa2 * 2)
  111. #define HR_FDBWRCMD_FDBDEL BIT(9)
  112. #define HR_SWCFG (0xa3 * 2)
  113. #define HR_SWCFG_GM_STATEMD BIT(15)
  114. #define HR_SWCFG_LAS_MODE_SHIFT 12
  115. #define HR_SWCFG_LAS_MODE_MASK GENMASK(13, 12)
  116. #define HR_SWCFG_LAS_OFF (0x00)
  117. #define HR_SWCFG_LAS_ON (0x01)
  118. #define HR_SWCFG_LAS_STATIC (0x10)
  119. #define HR_SWCFG_CT_EN BIT(11)
  120. #define HR_SWCFG_VLAN_UNAWARE BIT(10)
  121. #define HR_SWCFG_ALWAYS_OBT BIT(9)
  122. #define HR_SWCFG_FDBAGE_EN BIT(5)
  123. #define HR_SWCFG_FDBLRN_EN BIT(4)
  124. #define HR_SWSTAT (0xa4 * 2)
  125. #define HR_SWSTAT_FAIL BIT(4)
  126. #define HR_SWSTAT_BUSY BIT(0)
  127. #define HR_SWCMD (0xa5 * 2)
  128. #define HW_SWCMD_FLUSH BIT(0)
  129. #define HR_VIDCFG (0xaa * 2)
  130. #define HR_VIDCFG_VID_SHIFT 0
  131. #define HR_VIDCFG_VID_MASK GENMASK(11, 0)
  132. #define HR_VIDCFG_PVID BIT(12)
  133. #define HR_VIDMBRCFG (0xab * 2)
  134. #define HR_VIDMBRCFG_P0MBR_SHIFT 0
  135. #define HR_VIDMBRCFG_P0MBR_MASK GENMASK(1, 0)
  136. #define HR_VIDMBRCFG_P1MBR_SHIFT 2
  137. #define HR_VIDMBRCFG_P1MBR_MASK GENMASK(3, 2)
  138. #define HR_VIDMBRCFG_P2MBR_SHIFT 4
  139. #define HR_VIDMBRCFG_P2MBR_MASK GENMASK(5, 4)
  140. #define HR_VIDMBRCFG_P3MBR_SHIFT 6
  141. #define HR_VIDMBRCFG_P3MBR_MASK GENMASK(7, 6)
  142. #define HR_FEABITS0 (0xac * 2)
  143. #define HR_FEABITS0_FDBBINS_SHIFT 4
  144. #define HR_FEABITS0_FDBBINS_MASK GENMASK(7, 4)
  145. #define HR_FEABITS0_PCNT_SHIFT 8
  146. #define HR_FEABITS0_PCNT_MASK GENMASK(11, 8)
  147. #define HR_FEABITS0_MCNT_SHIFT 12
  148. #define HR_FEABITS0_MCNT_MASK GENMASK(15, 12)
  149. #define TR_QTRACK (0xb1 * 2)
  150. #define TR_TGDVER (0xb3 * 2)
  151. #define TR_TGDVER_REV_MIN_MASK GENMASK(7, 0)
  152. #define TR_TGDVER_REV_MIN_SHIFT 0
  153. #define TR_TGDVER_REV_MAJ_MASK GENMASK(15, 8)
  154. #define TR_TGDVER_REV_MAJ_SHIFT 8
  155. #define TR_TGDSEL (0xb4 * 2)
  156. #define TR_TGDSEL_TDGSEL_MASK GENMASK(1, 0)
  157. #define TR_TGDSEL_TDGSEL_SHIFT 0
  158. #define TR_TGDCTRL (0xb5 * 2)
  159. #define TR_TGDCTRL_GATE_EN BIT(0)
  160. #define TR_TGDCTRL_CYC_SNAP BIT(4)
  161. #define TR_TGDCTRL_SNAP_EST BIT(5)
  162. #define TR_TGDCTRL_ADMINGATESTATES_MASK GENMASK(15, 8)
  163. #define TR_TGDCTRL_ADMINGATESTATES_SHIFT 8
  164. #define TR_TGDSTAT0 (0xb6 * 2)
  165. #define TR_TGDSTAT1 (0xb7 * 2)
  166. #define TR_ESTWRL (0xb8 * 2)
  167. #define TR_ESTWRH (0xb9 * 2)
  168. #define TR_ESTCMD (0xba * 2)
  169. #define TR_ESTCMD_ESTSEC_MASK GENMASK(2, 0)
  170. #define TR_ESTCMD_ESTSEC_SHIFT 0
  171. #define TR_ESTCMD_ESTARM BIT(4)
  172. #define TR_ESTCMD_ESTSWCFG BIT(5)
  173. #define TR_EETWRL (0xbb * 2)
  174. #define TR_EETWRH (0xbc * 2)
  175. #define TR_EETCMD (0xbd * 2)
  176. #define TR_EETCMD_EETSEC_MASK GEMASK(2, 0)
  177. #define TR_EETCMD_EETSEC_SHIFT 0
  178. #define TR_EETCMD_EETARM BIT(4)
  179. #define TR_CTWRL (0xbe * 2)
  180. #define TR_CTWRH (0xbf * 2)
  181. #define TR_LCNSL (0xc1 * 2)
  182. #define TR_LCNSH (0xc2 * 2)
  183. #define TR_LCS (0xc3 * 2)
  184. #define TR_GCLDAT (0xc4 * 2)
  185. #define TR_GCLDAT_GCLWRGATES_MASK GENMASK(7, 0)
  186. #define TR_GCLDAT_GCLWRGATES_SHIFT 0
  187. #define TR_GCLDAT_GCLWRLAST BIT(8)
  188. #define TR_GCLDAT_GCLOVRI BIT(9)
  189. #define TR_GCLTIL (0xc5 * 2)
  190. #define TR_GCLTIH (0xc6 * 2)
  191. #define TR_GCLCMD (0xc7 * 2)
  192. #define TR_GCLCMD_GCLWRADR_MASK GENMASK(7, 0)
  193. #define TR_GCLCMD_GCLWRADR_SHIFT 0
  194. #define TR_GCLCMD_INIT_GATE_STATES_MASK GENMASK(15, 8)
  195. #define TR_GCLCMD_INIT_GATE_STATES_SHIFT 8
  196. struct hellcreek_counter {
  197. u8 offset;
  198. const char *name;
  199. };
  200. struct hellcreek;
  201. /* State flags for hellcreek_port_hwtstamp::state */
  202. enum {
  203. HELLCREEK_HWTSTAMP_ENABLED,
  204. HELLCREEK_HWTSTAMP_TX_IN_PROGRESS,
  205. };
  206. /* A structure to hold hardware timestamping information per port */
  207. struct hellcreek_port_hwtstamp {
  208. /* Timestamping state */
  209. unsigned long state;
  210. /* Resources for receive timestamping */
  211. struct sk_buff_head rx_queue; /* For synchronization messages */
  212. /* Resources for transmit timestamping */
  213. unsigned long tx_tstamp_start;
  214. struct sk_buff *tx_skb;
  215. /* Current timestamp configuration */
  216. struct hwtstamp_config tstamp_config;
  217. };
  218. struct hellcreek_port {
  219. struct hellcreek *hellcreek;
  220. unsigned long *vlan_dev_bitmap;
  221. int port;
  222. u16 ptcfg; /* ptcfg shadow */
  223. u64 *counter_values;
  224. /* Per-port timestamping resources */
  225. struct hellcreek_port_hwtstamp port_hwtstamp;
  226. /* Per-port Qbv schedule information */
  227. struct tc_taprio_qopt_offload *current_schedule;
  228. struct delayed_work schedule_work;
  229. };
  230. struct hellcreek_fdb_entry {
  231. size_t idx;
  232. unsigned char mac[ETH_ALEN];
  233. u8 portmask;
  234. u8 age;
  235. u8 is_obt;
  236. u8 pass_blocked;
  237. u8 is_static;
  238. u8 reprio_tc;
  239. u8 reprio_en;
  240. };
  241. struct hellcreek {
  242. const struct hellcreek_platform_data *pdata;
  243. struct device *dev;
  244. struct dsa_switch *ds;
  245. struct ptp_clock *ptp_clock;
  246. struct ptp_clock_info ptp_clock_info;
  247. struct hellcreek_port *ports;
  248. struct delayed_work overflow_work;
  249. struct led_classdev led_is_gm;
  250. struct led_classdev led_sync_good;
  251. struct mutex reg_lock; /* Switch IP register lock */
  252. struct mutex vlan_lock; /* VLAN bitmaps lock */
  253. struct mutex ptp_lock; /* PTP IP register lock */
  254. struct devlink_region *vlan_region;
  255. struct devlink_region *fdb_region;
  256. void __iomem *base;
  257. void __iomem *ptp_base;
  258. u16 swcfg; /* swcfg shadow */
  259. u8 *vidmbrcfg; /* vidmbrcfg shadow */
  260. u64 seconds; /* PTP seconds */
  261. u64 last_ts; /* Used for overflow detection */
  262. u16 status_out; /* ptp.status_out shadow */
  263. size_t fdb_entries;
  264. };
  265. /* A Qbv schedule can only started up to 8 seconds in the future. If the delta
  266. * between the base time and the current ptp time is larger than 8 seconds, then
  267. * use periodic work to check for the schedule to be started. The delayed work
  268. * cannot be armed directly to $base_time - 8 + X, because for large deltas the
  269. * PTP frequency matters.
  270. */
  271. #define HELLCREEK_SCHEDULE_PERIOD (2 * HZ)
  272. #define dw_to_hellcreek_port(dw) \
  273. container_of(dw, struct hellcreek_port, schedule_work)
  274. /* Devlink resources */
  275. enum hellcreek_devlink_resource_id {
  276. HELLCREEK_DEVLINK_PARAM_ID_VLAN_TABLE,
  277. HELLCREEK_DEVLINK_PARAM_ID_FDB_TABLE,
  278. };
  279. struct hellcreek_devlink_vlan_entry {
  280. u16 vid;
  281. u16 member;
  282. };
  283. #endif /* _HELLCREEK_H_ */