1 // SPDX-License-Identifier: (GPL-2.0 OR MIT) 2 /* 3 * Microsemi Ocelot Switch driver 4 * 5 * Copyright (c) 2017 Microsemi Corporation 6 */ 7 #include <linux/dsa/ocelot.h> 8 #include <linux/interrupt.h> 9 #include <linux/module.h> 10 #include <linux/of_net.h> 11 #include <linux/netdevice.h> 12 #include <linux/phylink.h> 13 #include <linux/of_mdio.h> 14 #include <linux/of_platform.h> 15 #include <linux/mfd/syscon.h> 16 #include <linux/skbuff.h> 17 #include <net/switchdev.h> 18 19 #include <soc/mscc/ocelot_vcap.h> 20 #include <soc/mscc/ocelot_hsio.h> 21 #include <soc/mscc/vsc7514_regs.h> 22 #include "ocelot_fdma.h" 23 #include "ocelot.h" 24 25 #define VSC7514_VCAP_POLICER_BASE 128 26 #define VSC7514_VCAP_POLICER_MAX 191 27 28 static const u32 *ocelot_regmap[TARGET_MAX] = { 29 [ANA] = vsc7514_ana_regmap, 30 [QS] = vsc7514_qs_regmap, 31 [QSYS] = vsc7514_qsys_regmap, 32 [REW] = vsc7514_rew_regmap, 33 [SYS] = vsc7514_sys_regmap, 34 [S0] = vsc7514_vcap_regmap, 35 [S1] = vsc7514_vcap_regmap, 36 [S2] = vsc7514_vcap_regmap, 37 [PTP] = vsc7514_ptp_regmap, 38 [DEV_GMII] = vsc7514_dev_gmii_regmap, 39 }; 40 41 static const struct reg_field ocelot_regfields[REGFIELD_MAX] = { 42 [ANA_ADVLEARN_VLAN_CHK] = REG_FIELD(ANA_ADVLEARN, 11, 11), 43 [ANA_ADVLEARN_LEARN_MIRROR] = REG_FIELD(ANA_ADVLEARN, 0, 10), 44 [ANA_ANEVENTS_MSTI_DROP] = REG_FIELD(ANA_ANEVENTS, 27, 27), 45 [ANA_ANEVENTS_ACLKILL] = REG_FIELD(ANA_ANEVENTS, 26, 26), 46 [ANA_ANEVENTS_ACLUSED] = REG_FIELD(ANA_ANEVENTS, 25, 25), 47 [ANA_ANEVENTS_AUTOAGE] = REG_FIELD(ANA_ANEVENTS, 24, 24), 48 [ANA_ANEVENTS_VS2TTL1] = REG_FIELD(ANA_ANEVENTS, 23, 23), 49 [ANA_ANEVENTS_STORM_DROP] = REG_FIELD(ANA_ANEVENTS, 22, 22), 50 [ANA_ANEVENTS_LEARN_DROP] = REG_FIELD(ANA_ANEVENTS, 21, 21), 51 [ANA_ANEVENTS_AGED_ENTRY] = REG_FIELD(ANA_ANEVENTS, 20, 20), 52 [ANA_ANEVENTS_CPU_LEARN_FAILED] = REG_FIELD(ANA_ANEVENTS, 19, 19), 53 [ANA_ANEVENTS_AUTO_LEARN_FAILED] = REG_FIELD(ANA_ANEVENTS, 18, 18), 54 [ANA_ANEVENTS_LEARN_REMOVE] = REG_FIELD(ANA_ANEVENTS, 17, 17), 55 [ANA_ANEVENTS_AUTO_LEARNED] = REG_FIELD(ANA_ANEVENTS, 16, 16), 56 [ANA_ANEVENTS_AUTO_MOVED] = REG_FIELD(ANA_ANEVENTS, 15, 15), 57 [ANA_ANEVENTS_DROPPED] = REG_FIELD(ANA_ANEVENTS, 14, 14), 58 [ANA_ANEVENTS_CLASSIFIED_DROP] = REG_FIELD(ANA_ANEVENTS, 13, 13), 59 [ANA_ANEVENTS_CLASSIFIED_COPY] = REG_FIELD(ANA_ANEVENTS, 12, 12), 60 [ANA_ANEVENTS_VLAN_DISCARD] = REG_FIELD(ANA_ANEVENTS, 11, 11), 61 [ANA_ANEVENTS_FWD_DISCARD] = REG_FIELD(ANA_ANEVENTS, 10, 10), 62 [ANA_ANEVENTS_MULTICAST_FLOOD] = REG_FIELD(ANA_ANEVENTS, 9, 9), 63 [ANA_ANEVENTS_UNICAST_FLOOD] = REG_FIELD(ANA_ANEVENTS, 8, 8), 64 [ANA_ANEVENTS_DEST_KNOWN] = REG_FIELD(ANA_ANEVENTS, 7, 7), 65 [ANA_ANEVENTS_BUCKET3_MATCH] = REG_FIELD(ANA_ANEVENTS, 6, 6), 66 [ANA_ANEVENTS_BUCKET2_MATCH] = REG_FIELD(ANA_ANEVENTS, 5, 5), 67 [ANA_ANEVENTS_BUCKET1_MATCH] = REG_FIELD(ANA_ANEVENTS, 4, 4), 68 [ANA_ANEVENTS_BUCKET0_MATCH] = REG_FIELD(ANA_ANEVENTS, 3, 3), 69 [ANA_ANEVENTS_CPU_OPERATION] = REG_FIELD(ANA_ANEVENTS, 2, 2), 70 [ANA_ANEVENTS_DMAC_LOOKUP] = REG_FIELD(ANA_ANEVENTS, 1, 1), 71 [ANA_ANEVENTS_SMAC_LOOKUP] = REG_FIELD(ANA_ANEVENTS, 0, 0), 72 [ANA_TABLES_MACACCESS_B_DOM] = REG_FIELD(ANA_TABLES_MACACCESS, 18, 18), 73 [ANA_TABLES_MACTINDX_BUCKET] = REG_FIELD(ANA_TABLES_MACTINDX, 10, 11), 74 [ANA_TABLES_MACTINDX_M_INDEX] = REG_FIELD(ANA_TABLES_MACTINDX, 0, 9), 75 [QSYS_TIMED_FRAME_ENTRY_TFRM_VLD] = REG_FIELD(QSYS_TIMED_FRAME_ENTRY, 20, 20), 76 [QSYS_TIMED_FRAME_ENTRY_TFRM_FP] = REG_FIELD(QSYS_TIMED_FRAME_ENTRY, 8, 19), 77 [QSYS_TIMED_FRAME_ENTRY_TFRM_PORTNO] = REG_FIELD(QSYS_TIMED_FRAME_ENTRY, 4, 7), 78 [QSYS_TIMED_FRAME_ENTRY_TFRM_TM_SEL] = REG_FIELD(QSYS_TIMED_FRAME_ENTRY, 1, 3), 79 [QSYS_TIMED_FRAME_ENTRY_TFRM_TM_T] = REG_FIELD(QSYS_TIMED_FRAME_ENTRY, 0, 0), 80 [SYS_RESET_CFG_CORE_ENA] = REG_FIELD(SYS_RESET_CFG, 2, 2), 81 [SYS_RESET_CFG_MEM_ENA] = REG_FIELD(SYS_RESET_CFG, 1, 1), 82 [SYS_RESET_CFG_MEM_INIT] = REG_FIELD(SYS_RESET_CFG, 0, 0), 83 /* Replicated per number of ports (12), register size 4 per port */ 84 [QSYS_SWITCH_PORT_MODE_PORT_ENA] = REG_FIELD_ID(QSYS_SWITCH_PORT_MODE, 14, 14, 12, 4), 85 [QSYS_SWITCH_PORT_MODE_SCH_NEXT_CFG] = REG_FIELD_ID(QSYS_SWITCH_PORT_MODE, 11, 13, 12, 4), 86 [QSYS_SWITCH_PORT_MODE_YEL_RSRVD] = REG_FIELD_ID(QSYS_SWITCH_PORT_MODE, 10, 10, 12, 4), 87 [QSYS_SWITCH_PORT_MODE_INGRESS_DROP_MODE] = REG_FIELD_ID(QSYS_SWITCH_PORT_MODE, 9, 9, 12, 4), 88 [QSYS_SWITCH_PORT_MODE_TX_PFC_ENA] = REG_FIELD_ID(QSYS_SWITCH_PORT_MODE, 1, 8, 12, 4), 89 [QSYS_SWITCH_PORT_MODE_TX_PFC_MODE] = REG_FIELD_ID(QSYS_SWITCH_PORT_MODE, 0, 0, 12, 4), 90 [SYS_PORT_MODE_DATA_WO_TS] = REG_FIELD_ID(SYS_PORT_MODE, 5, 6, 12, 4), 91 [SYS_PORT_MODE_INCL_INJ_HDR] = REG_FIELD_ID(SYS_PORT_MODE, 3, 4, 12, 4), 92 [SYS_PORT_MODE_INCL_XTR_HDR] = REG_FIELD_ID(SYS_PORT_MODE, 1, 2, 12, 4), 93 [SYS_PORT_MODE_INCL_HDR_ERR] = REG_FIELD_ID(SYS_PORT_MODE, 0, 0, 12, 4), 94 [SYS_PAUSE_CFG_PAUSE_START] = REG_FIELD_ID(SYS_PAUSE_CFG, 10, 18, 12, 4), 95 [SYS_PAUSE_CFG_PAUSE_STOP] = REG_FIELD_ID(SYS_PAUSE_CFG, 1, 9, 12, 4), 96 [SYS_PAUSE_CFG_PAUSE_ENA] = REG_FIELD_ID(SYS_PAUSE_CFG, 0, 1, 12, 4), 97 }; 98 99 static const struct ocelot_stat_layout ocelot_stats_layout[OCELOT_NUM_STATS] = { 100 [OCELOT_STAT_RX_OCTETS] = { 101 .name = "rx_octets", 102 .reg = SYS_COUNT_RX_OCTETS, 103 }, 104 [OCELOT_STAT_RX_UNICAST] = { 105 .name = "rx_unicast", 106 .reg = SYS_COUNT_RX_UNICAST, 107 }, 108 [OCELOT_STAT_RX_MULTICAST] = { 109 .name = "rx_multicast", 110 .reg = SYS_COUNT_RX_MULTICAST, 111 }, 112 [OCELOT_STAT_RX_BROADCAST] = { 113 .name = "rx_broadcast", 114 .reg = SYS_COUNT_RX_BROADCAST, 115 }, 116 [OCELOT_STAT_RX_SHORTS] = { 117 .name = "rx_shorts", 118 .reg = SYS_COUNT_RX_SHORTS, 119 }, 120 [OCELOT_STAT_RX_FRAGMENTS] = { 121 .name = "rx_fragments", 122 .reg = SYS_COUNT_RX_FRAGMENTS, 123 }, 124 [OCELOT_STAT_RX_JABBERS] = { 125 .name = "rx_jabbers", 126 .reg = SYS_COUNT_RX_JABBERS, 127 }, 128 [OCELOT_STAT_RX_CRC_ALIGN_ERRS] = { 129 .name = "rx_crc_align_errs", 130 .reg = SYS_COUNT_RX_CRC_ALIGN_ERRS, 131 }, 132 [OCELOT_STAT_RX_SYM_ERRS] = { 133 .name = "rx_sym_errs", 134 .reg = SYS_COUNT_RX_SYM_ERRS, 135 }, 136 [OCELOT_STAT_RX_64] = { 137 .name = "rx_frames_below_65_octets", 138 .reg = SYS_COUNT_RX_64, 139 }, 140 [OCELOT_STAT_RX_65_127] = { 141 .name = "rx_frames_65_to_127_octets", 142 .reg = SYS_COUNT_RX_65_127, 143 }, 144 [OCELOT_STAT_RX_128_255] = { 145 .name = "rx_frames_128_to_255_octets", 146 .reg = SYS_COUNT_RX_128_255, 147 }, 148 [OCELOT_STAT_RX_256_511] = { 149 .name = "rx_frames_256_to_511_octets", 150 .reg = SYS_COUNT_RX_256_511, 151 }, 152 [OCELOT_STAT_RX_512_1023] = { 153 .name = "rx_frames_512_to_1023_octets", 154 .reg = SYS_COUNT_RX_512_1023, 155 }, 156 [OCELOT_STAT_RX_1024_1526] = { 157 .name = "rx_frames_1024_to_1526_octets", 158 .reg = SYS_COUNT_RX_1024_1526, 159 }, 160 [OCELOT_STAT_RX_1527_MAX] = { 161 .name = "rx_frames_over_1526_octets", 162 .reg = SYS_COUNT_RX_1527_MAX, 163 }, 164 [OCELOT_STAT_RX_PAUSE] = { 165 .name = "rx_pause", 166 .reg = SYS_COUNT_RX_PAUSE, 167 }, 168 [OCELOT_STAT_RX_CONTROL] = { 169 .name = "rx_control", 170 .reg = SYS_COUNT_RX_CONTROL, 171 }, 172 [OCELOT_STAT_RX_LONGS] = { 173 .name = "rx_longs", 174 .reg = SYS_COUNT_RX_LONGS, 175 }, 176 [OCELOT_STAT_RX_CLASSIFIED_DROPS] = { 177 .name = "rx_classified_drops", 178 .reg = SYS_COUNT_RX_CLASSIFIED_DROPS, 179 }, 180 [OCELOT_STAT_RX_RED_PRIO_0] = { 181 .name = "rx_red_prio_0", 182 .reg = SYS_COUNT_RX_RED_PRIO_0, 183 }, 184 [OCELOT_STAT_RX_RED_PRIO_1] = { 185 .name = "rx_red_prio_1", 186 .reg = SYS_COUNT_RX_RED_PRIO_1, 187 }, 188 [OCELOT_STAT_RX_RED_PRIO_2] = { 189 .name = "rx_red_prio_2", 190 .reg = SYS_COUNT_RX_RED_PRIO_2, 191 }, 192 [OCELOT_STAT_RX_RED_PRIO_3] = { 193 .name = "rx_red_prio_3", 194 .reg = SYS_COUNT_RX_RED_PRIO_3, 195 }, 196 [OCELOT_STAT_RX_RED_PRIO_4] = { 197 .name = "rx_red_prio_4", 198 .reg = SYS_COUNT_RX_RED_PRIO_4, 199 }, 200 [OCELOT_STAT_RX_RED_PRIO_5] = { 201 .name = "rx_red_prio_5", 202 .reg = SYS_COUNT_RX_RED_PRIO_5, 203 }, 204 [OCELOT_STAT_RX_RED_PRIO_6] = { 205 .name = "rx_red_prio_6", 206 .reg = SYS_COUNT_RX_RED_PRIO_6, 207 }, 208 [OCELOT_STAT_RX_RED_PRIO_7] = { 209 .name = "rx_red_prio_7", 210 .reg = SYS_COUNT_RX_RED_PRIO_7, 211 }, 212 [OCELOT_STAT_RX_YELLOW_PRIO_0] = { 213 .name = "rx_yellow_prio_0", 214 .reg = SYS_COUNT_RX_YELLOW_PRIO_0, 215 }, 216 [OCELOT_STAT_RX_YELLOW_PRIO_1] = { 217 .name = "rx_yellow_prio_1", 218 .reg = SYS_COUNT_RX_YELLOW_PRIO_1, 219 }, 220 [OCELOT_STAT_RX_YELLOW_PRIO_2] = { 221 .name = "rx_yellow_prio_2", 222 .reg = SYS_COUNT_RX_YELLOW_PRIO_2, 223 }, 224 [OCELOT_STAT_RX_YELLOW_PRIO_3] = { 225 .name = "rx_yellow_prio_3", 226 .reg = SYS_COUNT_RX_YELLOW_PRIO_3, 227 }, 228 [OCELOT_STAT_RX_YELLOW_PRIO_4] = { 229 .name = "rx_yellow_prio_4", 230 .reg = SYS_COUNT_RX_YELLOW_PRIO_4, 231 }, 232 [OCELOT_STAT_RX_YELLOW_PRIO_5] = { 233 .name = "rx_yellow_prio_5", 234 .reg = SYS_COUNT_RX_YELLOW_PRIO_5, 235 }, 236 [OCELOT_STAT_RX_YELLOW_PRIO_6] = { 237 .name = "rx_yellow_prio_6", 238 .reg = SYS_COUNT_RX_YELLOW_PRIO_6, 239 }, 240 [OCELOT_STAT_RX_YELLOW_PRIO_7] = { 241 .name = "rx_yellow_prio_7", 242 .reg = SYS_COUNT_RX_YELLOW_PRIO_7, 243 }, 244 [OCELOT_STAT_RX_GREEN_PRIO_0] = { 245 .name = "rx_green_prio_0", 246 .reg = SYS_COUNT_RX_GREEN_PRIO_0, 247 }, 248 [OCELOT_STAT_RX_GREEN_PRIO_1] = { 249 .name = "rx_green_prio_1", 250 .reg = SYS_COUNT_RX_GREEN_PRIO_1, 251 }, 252 [OCELOT_STAT_RX_GREEN_PRIO_2] = { 253 .name = "rx_green_prio_2", 254 .reg = SYS_COUNT_RX_GREEN_PRIO_2, 255 }, 256 [OCELOT_STAT_RX_GREEN_PRIO_3] = { 257 .name = "rx_green_prio_3", 258 .reg = SYS_COUNT_RX_GREEN_PRIO_3, 259 }, 260 [OCELOT_STAT_RX_GREEN_PRIO_4] = { 261 .name = "rx_green_prio_4", 262 .reg = SYS_COUNT_RX_GREEN_PRIO_4, 263 }, 264 [OCELOT_STAT_RX_GREEN_PRIO_5] = { 265 .name = "rx_green_prio_5", 266 .reg = SYS_COUNT_RX_GREEN_PRIO_5, 267 }, 268 [OCELOT_STAT_RX_GREEN_PRIO_6] = { 269 .name = "rx_green_prio_6", 270 .reg = SYS_COUNT_RX_GREEN_PRIO_6, 271 }, 272 [OCELOT_STAT_RX_GREEN_PRIO_7] = { 273 .name = "rx_green_prio_7", 274 .reg = SYS_COUNT_RX_GREEN_PRIO_7, 275 }, 276 [OCELOT_STAT_TX_OCTETS] = { 277 .name = "tx_octets", 278 .reg = SYS_COUNT_TX_OCTETS, 279 }, 280 [OCELOT_STAT_TX_UNICAST] = { 281 .name = "tx_unicast", 282 .reg = SYS_COUNT_TX_UNICAST, 283 }, 284 [OCELOT_STAT_TX_MULTICAST] = { 285 .name = "tx_multicast", 286 .reg = SYS_COUNT_TX_MULTICAST, 287 }, 288 [OCELOT_STAT_TX_BROADCAST] = { 289 .name = "tx_broadcast", 290 .reg = SYS_COUNT_TX_BROADCAST, 291 }, 292 [OCELOT_STAT_TX_COLLISION] = { 293 .name = "tx_collision", 294 .reg = SYS_COUNT_TX_COLLISION, 295 }, 296 [OCELOT_STAT_TX_DROPS] = { 297 .name = "tx_drops", 298 .reg = SYS_COUNT_TX_DROPS, 299 }, 300 [OCELOT_STAT_TX_PAUSE] = { 301 .name = "tx_pause", 302 .reg = SYS_COUNT_TX_PAUSE, 303 }, 304 [OCELOT_STAT_TX_64] = { 305 .name = "tx_frames_below_65_octets", 306 .reg = SYS_COUNT_TX_64, 307 }, 308 [OCELOT_STAT_TX_65_127] = { 309 .name = "tx_frames_65_to_127_octets", 310 .reg = SYS_COUNT_TX_65_127, 311 }, 312 [OCELOT_STAT_TX_128_255] = { 313 .name = "tx_frames_128_255_octets", 314 .reg = SYS_COUNT_TX_128_255, 315 }, 316 [OCELOT_STAT_TX_256_511] = { 317 .name = "tx_frames_256_511_octets", 318 .reg = SYS_COUNT_TX_256_511, 319 }, 320 [OCELOT_STAT_TX_512_1023] = { 321 .name = "tx_frames_512_1023_octets", 322 .reg = SYS_COUNT_TX_512_1023, 323 }, 324 [OCELOT_STAT_TX_1024_1526] = { 325 .name = "tx_frames_1024_1526_octets", 326 .reg = SYS_COUNT_TX_1024_1526, 327 }, 328 [OCELOT_STAT_TX_1527_MAX] = { 329 .name = "tx_frames_over_1526_octets", 330 .reg = SYS_COUNT_TX_1527_MAX, 331 }, 332 [OCELOT_STAT_TX_YELLOW_PRIO_0] = { 333 .name = "tx_yellow_prio_0", 334 .reg = SYS_COUNT_TX_YELLOW_PRIO_0, 335 }, 336 [OCELOT_STAT_TX_YELLOW_PRIO_1] = { 337 .name = "tx_yellow_prio_1", 338 .reg = SYS_COUNT_TX_YELLOW_PRIO_1, 339 }, 340 [OCELOT_STAT_TX_YELLOW_PRIO_2] = { 341 .name = "tx_yellow_prio_2", 342 .reg = SYS_COUNT_TX_YELLOW_PRIO_2, 343 }, 344 [OCELOT_STAT_TX_YELLOW_PRIO_3] = { 345 .name = "tx_yellow_prio_3", 346 .reg = SYS_COUNT_TX_YELLOW_PRIO_3, 347 }, 348 [OCELOT_STAT_TX_YELLOW_PRIO_4] = { 349 .name = "tx_yellow_prio_4", 350 .reg = SYS_COUNT_TX_YELLOW_PRIO_4, 351 }, 352 [OCELOT_STAT_TX_YELLOW_PRIO_5] = { 353 .name = "tx_yellow_prio_5", 354 .reg = SYS_COUNT_TX_YELLOW_PRIO_5, 355 }, 356 [OCELOT_STAT_TX_YELLOW_PRIO_6] = { 357 .name = "tx_yellow_prio_6", 358 .reg = SYS_COUNT_TX_YELLOW_PRIO_6, 359 }, 360 [OCELOT_STAT_TX_YELLOW_PRIO_7] = { 361 .name = "tx_yellow_prio_7", 362 .reg = SYS_COUNT_TX_YELLOW_PRIO_7, 363 }, 364 [OCELOT_STAT_TX_GREEN_PRIO_0] = { 365 .name = "tx_green_prio_0", 366 .reg = SYS_COUNT_TX_GREEN_PRIO_0, 367 }, 368 [OCELOT_STAT_TX_GREEN_PRIO_1] = { 369 .name = "tx_green_prio_1", 370 .reg = SYS_COUNT_TX_GREEN_PRIO_1, 371 }, 372 [OCELOT_STAT_TX_GREEN_PRIO_2] = { 373 .name = "tx_green_prio_2", 374 .reg = SYS_COUNT_TX_GREEN_PRIO_2, 375 }, 376 [OCELOT_STAT_TX_GREEN_PRIO_3] = { 377 .name = "tx_green_prio_3", 378 .reg = SYS_COUNT_TX_GREEN_PRIO_3, 379 }, 380 [OCELOT_STAT_TX_GREEN_PRIO_4] = { 381 .name = "tx_green_prio_4", 382 .reg = SYS_COUNT_TX_GREEN_PRIO_4, 383 }, 384 [OCELOT_STAT_TX_GREEN_PRIO_5] = { 385 .name = "tx_green_prio_5", 386 .reg = SYS_COUNT_TX_GREEN_PRIO_5, 387 }, 388 [OCELOT_STAT_TX_GREEN_PRIO_6] = { 389 .name = "tx_green_prio_6", 390 .reg = SYS_COUNT_TX_GREEN_PRIO_6, 391 }, 392 [OCELOT_STAT_TX_GREEN_PRIO_7] = { 393 .name = "tx_green_prio_7", 394 .reg = SYS_COUNT_TX_GREEN_PRIO_7, 395 }, 396 [OCELOT_STAT_TX_AGED] = { 397 .name = "tx_aged", 398 .reg = SYS_COUNT_TX_AGING, 399 }, 400 [OCELOT_STAT_DROP_LOCAL] = { 401 .name = "drop_local", 402 .reg = SYS_COUNT_DROP_LOCAL, 403 }, 404 [OCELOT_STAT_DROP_TAIL] = { 405 .name = "drop_tail", 406 .reg = SYS_COUNT_DROP_TAIL, 407 }, 408 [OCELOT_STAT_DROP_YELLOW_PRIO_0] = { 409 .name = "drop_yellow_prio_0", 410 .reg = SYS_COUNT_DROP_YELLOW_PRIO_0, 411 }, 412 [OCELOT_STAT_DROP_YELLOW_PRIO_1] = { 413 .name = "drop_yellow_prio_1", 414 .reg = SYS_COUNT_DROP_YELLOW_PRIO_1, 415 }, 416 [OCELOT_STAT_DROP_YELLOW_PRIO_2] = { 417 .name = "drop_yellow_prio_2", 418 .reg = SYS_COUNT_DROP_YELLOW_PRIO_2, 419 }, 420 [OCELOT_STAT_DROP_YELLOW_PRIO_3] = { 421 .name = "drop_yellow_prio_3", 422 .reg = SYS_COUNT_DROP_YELLOW_PRIO_3, 423 }, 424 [OCELOT_STAT_DROP_YELLOW_PRIO_4] = { 425 .name = "drop_yellow_prio_4", 426 .reg = SYS_COUNT_DROP_YELLOW_PRIO_4, 427 }, 428 [OCELOT_STAT_DROP_YELLOW_PRIO_5] = { 429 .name = "drop_yellow_prio_5", 430 .reg = SYS_COUNT_DROP_YELLOW_PRIO_5, 431 }, 432 [OCELOT_STAT_DROP_YELLOW_PRIO_6] = { 433 .name = "drop_yellow_prio_6", 434 .reg = SYS_COUNT_DROP_YELLOW_PRIO_6, 435 }, 436 [OCELOT_STAT_DROP_YELLOW_PRIO_7] = { 437 .name = "drop_yellow_prio_7", 438 .reg = SYS_COUNT_DROP_YELLOW_PRIO_7, 439 }, 440 [OCELOT_STAT_DROP_GREEN_PRIO_0] = { 441 .name = "drop_green_prio_0", 442 .reg = SYS_COUNT_DROP_GREEN_PRIO_0, 443 }, 444 [OCELOT_STAT_DROP_GREEN_PRIO_1] = { 445 .name = "drop_green_prio_1", 446 .reg = SYS_COUNT_DROP_GREEN_PRIO_1, 447 }, 448 [OCELOT_STAT_DROP_GREEN_PRIO_2] = { 449 .name = "drop_green_prio_2", 450 .reg = SYS_COUNT_DROP_GREEN_PRIO_2, 451 }, 452 [OCELOT_STAT_DROP_GREEN_PRIO_3] = { 453 .name = "drop_green_prio_3", 454 .reg = SYS_COUNT_DROP_GREEN_PRIO_3, 455 }, 456 [OCELOT_STAT_DROP_GREEN_PRIO_4] = { 457 .name = "drop_green_prio_4", 458 .reg = SYS_COUNT_DROP_GREEN_PRIO_4, 459 }, 460 [OCELOT_STAT_DROP_GREEN_PRIO_5] = { 461 .name = "drop_green_prio_5", 462 .reg = SYS_COUNT_DROP_GREEN_PRIO_5, 463 }, 464 [OCELOT_STAT_DROP_GREEN_PRIO_6] = { 465 .name = "drop_green_prio_6", 466 .reg = SYS_COUNT_DROP_GREEN_PRIO_6, 467 }, 468 [OCELOT_STAT_DROP_GREEN_PRIO_7] = { 469 .name = "drop_green_prio_7", 470 .reg = SYS_COUNT_DROP_GREEN_PRIO_7, 471 }, 472 }; 473 474 static void ocelot_pll5_init(struct ocelot *ocelot) 475 { 476 /* Configure PLL5. This will need a proper CCF driver 477 * The values are coming from the VTSS API for Ocelot 478 */ 479 regmap_write(ocelot->targets[HSIO], HSIO_PLL5G_CFG4, 480 HSIO_PLL5G_CFG4_IB_CTRL(0x7600) | 481 HSIO_PLL5G_CFG4_IB_BIAS_CTRL(0x8)); 482 regmap_write(ocelot->targets[HSIO], HSIO_PLL5G_CFG0, 483 HSIO_PLL5G_CFG0_CORE_CLK_DIV(0x11) | 484 HSIO_PLL5G_CFG0_CPU_CLK_DIV(2) | 485 HSIO_PLL5G_CFG0_ENA_BIAS | 486 HSIO_PLL5G_CFG0_ENA_VCO_BUF | 487 HSIO_PLL5G_CFG0_ENA_CP1 | 488 HSIO_PLL5G_CFG0_SELCPI(2) | 489 HSIO_PLL5G_CFG0_LOOP_BW_RES(0xe) | 490 HSIO_PLL5G_CFG0_SELBGV820(4) | 491 HSIO_PLL5G_CFG0_DIV4 | 492 HSIO_PLL5G_CFG0_ENA_CLKTREE | 493 HSIO_PLL5G_CFG0_ENA_LANE); 494 regmap_write(ocelot->targets[HSIO], HSIO_PLL5G_CFG2, 495 HSIO_PLL5G_CFG2_EN_RESET_FRQ_DET | 496 HSIO_PLL5G_CFG2_EN_RESET_OVERRUN | 497 HSIO_PLL5G_CFG2_GAIN_TEST(0x8) | 498 HSIO_PLL5G_CFG2_ENA_AMPCTRL | 499 HSIO_PLL5G_CFG2_PWD_AMPCTRL_N | 500 HSIO_PLL5G_CFG2_AMPC_SEL(0x10)); 501 } 502 503 static int ocelot_chip_init(struct ocelot *ocelot, const struct ocelot_ops *ops) 504 { 505 int ret; 506 507 ocelot->map = ocelot_regmap; 508 ocelot->stats_layout = ocelot_stats_layout; 509 ocelot->num_mact_rows = 1024; 510 ocelot->ops = ops; 511 512 ret = ocelot_regfields_init(ocelot, ocelot_regfields); 513 if (ret) 514 return ret; 515 516 ocelot_pll5_init(ocelot); 517 518 eth_random_addr(ocelot->base_mac); 519 ocelot->base_mac[5] &= 0xf0; 520 521 return 0; 522 } 523 524 static irqreturn_t ocelot_xtr_irq_handler(int irq, void *arg) 525 { 526 struct ocelot *ocelot = arg; 527 int grp = 0, err; 528 529 while (ocelot_read(ocelot, QS_XTR_DATA_PRESENT) & BIT(grp)) { 530 struct sk_buff *skb; 531 532 err = ocelot_xtr_poll_frame(ocelot, grp, &skb); 533 if (err) 534 goto out; 535 536 skb->dev->stats.rx_bytes += skb->len; 537 skb->dev->stats.rx_packets++; 538 539 if (!skb_defer_rx_timestamp(skb)) 540 netif_rx(skb); 541 } 542 543 out: 544 if (err < 0) 545 ocelot_drain_cpu_queue(ocelot, 0); 546 547 return IRQ_HANDLED; 548 } 549 550 static irqreturn_t ocelot_ptp_rdy_irq_handler(int irq, void *arg) 551 { 552 struct ocelot *ocelot = arg; 553 554 ocelot_get_txtstamp(ocelot); 555 556 return IRQ_HANDLED; 557 } 558 559 static const struct of_device_id mscc_ocelot_match[] = { 560 { .compatible = "mscc,vsc7514-switch" }, 561 { } 562 }; 563 MODULE_DEVICE_TABLE(of, mscc_ocelot_match); 564 565 static int ocelot_reset(struct ocelot *ocelot) 566 { 567 int retries = 100; 568 u32 val; 569 570 regmap_field_write(ocelot->regfields[SYS_RESET_CFG_MEM_INIT], 1); 571 regmap_field_write(ocelot->regfields[SYS_RESET_CFG_MEM_ENA], 1); 572 573 do { 574 msleep(1); 575 regmap_field_read(ocelot->regfields[SYS_RESET_CFG_MEM_INIT], 576 &val); 577 } while (val && --retries); 578 579 if (!retries) 580 return -ETIMEDOUT; 581 582 regmap_field_write(ocelot->regfields[SYS_RESET_CFG_MEM_ENA], 1); 583 regmap_field_write(ocelot->regfields[SYS_RESET_CFG_CORE_ENA], 1); 584 585 return 0; 586 } 587 588 /* Watermark encode 589 * Bit 8: Unit; 0:1, 1:16 590 * Bit 7-0: Value to be multiplied with unit 591 */ 592 static u16 ocelot_wm_enc(u16 value) 593 { 594 WARN_ON(value >= 16 * BIT(8)); 595 596 if (value >= BIT(8)) 597 return BIT(8) | (value / 16); 598 599 return value; 600 } 601 602 static u16 ocelot_wm_dec(u16 wm) 603 { 604 if (wm & BIT(8)) 605 return (wm & GENMASK(7, 0)) * 16; 606 607 return wm; 608 } 609 610 static void ocelot_wm_stat(u32 val, u32 *inuse, u32 *maxuse) 611 { 612 *inuse = (val & GENMASK(23, 12)) >> 12; 613 *maxuse = val & GENMASK(11, 0); 614 } 615 616 static const struct ocelot_ops ocelot_ops = { 617 .reset = ocelot_reset, 618 .wm_enc = ocelot_wm_enc, 619 .wm_dec = ocelot_wm_dec, 620 .wm_stat = ocelot_wm_stat, 621 .port_to_netdev = ocelot_port_to_netdev, 622 .netdev_to_port = ocelot_netdev_to_port, 623 }; 624 625 static struct vcap_props vsc7514_vcap_props[] = { 626 [VCAP_ES0] = { 627 .action_type_width = 0, 628 .action_table = { 629 [ES0_ACTION_TYPE_NORMAL] = { 630 .width = 73, /* HIT_STICKY not included */ 631 .count = 1, 632 }, 633 }, 634 .target = S0, 635 .keys = vsc7514_vcap_es0_keys, 636 .actions = vsc7514_vcap_es0_actions, 637 }, 638 [VCAP_IS1] = { 639 .action_type_width = 0, 640 .action_table = { 641 [IS1_ACTION_TYPE_NORMAL] = { 642 .width = 78, /* HIT_STICKY not included */ 643 .count = 4, 644 }, 645 }, 646 .target = S1, 647 .keys = vsc7514_vcap_is1_keys, 648 .actions = vsc7514_vcap_is1_actions, 649 }, 650 [VCAP_IS2] = { 651 .action_type_width = 1, 652 .action_table = { 653 [IS2_ACTION_TYPE_NORMAL] = { 654 .width = 49, 655 .count = 2 656 }, 657 [IS2_ACTION_TYPE_SMAC_SIP] = { 658 .width = 6, 659 .count = 4 660 }, 661 }, 662 .target = S2, 663 .keys = vsc7514_vcap_is2_keys, 664 .actions = vsc7514_vcap_is2_actions, 665 }, 666 }; 667 668 static struct ptp_clock_info ocelot_ptp_clock_info = { 669 .owner = THIS_MODULE, 670 .name = "ocelot ptp", 671 .max_adj = 0x7fffffff, 672 .n_alarm = 0, 673 .n_ext_ts = 0, 674 .n_per_out = OCELOT_PTP_PINS_NUM, 675 .n_pins = OCELOT_PTP_PINS_NUM, 676 .pps = 0, 677 .gettime64 = ocelot_ptp_gettime64, 678 .settime64 = ocelot_ptp_settime64, 679 .adjtime = ocelot_ptp_adjtime, 680 .adjfine = ocelot_ptp_adjfine, 681 .verify = ocelot_ptp_verify, 682 .enable = ocelot_ptp_enable, 683 }; 684 685 static void mscc_ocelot_teardown_devlink_ports(struct ocelot *ocelot) 686 { 687 int port; 688 689 for (port = 0; port < ocelot->num_phys_ports; port++) 690 ocelot_port_devlink_teardown(ocelot, port); 691 } 692 693 static void mscc_ocelot_release_ports(struct ocelot *ocelot) 694 { 695 int port; 696 697 for (port = 0; port < ocelot->num_phys_ports; port++) { 698 struct ocelot_port *ocelot_port; 699 700 ocelot_port = ocelot->ports[port]; 701 if (!ocelot_port) 702 continue; 703 704 ocelot_deinit_port(ocelot, port); 705 ocelot_release_port(ocelot_port); 706 } 707 } 708 709 static int mscc_ocelot_init_ports(struct platform_device *pdev, 710 struct device_node *ports) 711 { 712 struct ocelot *ocelot = platform_get_drvdata(pdev); 713 u32 devlink_ports_registered = 0; 714 struct device_node *portnp; 715 int port, err; 716 u32 reg; 717 718 ocelot->ports = devm_kcalloc(ocelot->dev, ocelot->num_phys_ports, 719 sizeof(struct ocelot_port *), GFP_KERNEL); 720 if (!ocelot->ports) 721 return -ENOMEM; 722 723 ocelot->devlink_ports = devm_kcalloc(ocelot->dev, 724 ocelot->num_phys_ports, 725 sizeof(*ocelot->devlink_ports), 726 GFP_KERNEL); 727 if (!ocelot->devlink_ports) 728 return -ENOMEM; 729 730 for_each_available_child_of_node(ports, portnp) { 731 struct ocelot_port_private *priv; 732 struct ocelot_port *ocelot_port; 733 struct devlink_port *dlp; 734 struct regmap *target; 735 struct resource *res; 736 char res_name[8]; 737 738 if (of_property_read_u32(portnp, "reg", ®)) 739 continue; 740 741 port = reg; 742 if (port < 0 || port >= ocelot->num_phys_ports) { 743 dev_err(ocelot->dev, 744 "invalid port number: %d >= %d\n", port, 745 ocelot->num_phys_ports); 746 continue; 747 } 748 749 snprintf(res_name, sizeof(res_name), "port%d", port); 750 751 res = platform_get_resource_byname(pdev, IORESOURCE_MEM, 752 res_name); 753 target = ocelot_regmap_init(ocelot, res); 754 if (IS_ERR(target)) { 755 err = PTR_ERR(target); 756 of_node_put(portnp); 757 goto out_teardown; 758 } 759 760 err = ocelot_port_devlink_init(ocelot, port, 761 DEVLINK_PORT_FLAVOUR_PHYSICAL); 762 if (err) { 763 of_node_put(portnp); 764 goto out_teardown; 765 } 766 767 err = ocelot_probe_port(ocelot, port, target, portnp); 768 if (err) { 769 ocelot_port_devlink_teardown(ocelot, port); 770 continue; 771 } 772 773 devlink_ports_registered |= BIT(port); 774 775 ocelot_port = ocelot->ports[port]; 776 priv = container_of(ocelot_port, struct ocelot_port_private, 777 port); 778 dlp = &ocelot->devlink_ports[port]; 779 devlink_port_type_eth_set(dlp, priv->dev); 780 } 781 782 /* Initialize unused devlink ports at the end */ 783 for (port = 0; port < ocelot->num_phys_ports; port++) { 784 if (devlink_ports_registered & BIT(port)) 785 continue; 786 787 err = ocelot_port_devlink_init(ocelot, port, 788 DEVLINK_PORT_FLAVOUR_UNUSED); 789 if (err) 790 goto out_teardown; 791 792 devlink_ports_registered |= BIT(port); 793 } 794 795 return 0; 796 797 out_teardown: 798 /* Unregister the network interfaces */ 799 mscc_ocelot_release_ports(ocelot); 800 /* Tear down devlink ports for the registered network interfaces */ 801 for (port = 0; port < ocelot->num_phys_ports; port++) { 802 if (devlink_ports_registered & BIT(port)) 803 ocelot_port_devlink_teardown(ocelot, port); 804 } 805 return err; 806 } 807 808 static int mscc_ocelot_probe(struct platform_device *pdev) 809 { 810 struct device_node *np = pdev->dev.of_node; 811 int err, irq_xtr, irq_ptp_rdy; 812 struct device_node *ports; 813 struct devlink *devlink; 814 struct ocelot *ocelot; 815 struct regmap *hsio; 816 unsigned int i; 817 818 struct { 819 enum ocelot_target id; 820 char *name; 821 u8 optional:1; 822 } io_target[] = { 823 { SYS, "sys" }, 824 { REW, "rew" }, 825 { QSYS, "qsys" }, 826 { ANA, "ana" }, 827 { QS, "qs" }, 828 { S0, "s0" }, 829 { S1, "s1" }, 830 { S2, "s2" }, 831 { PTP, "ptp", 1 }, 832 { FDMA, "fdma", 1 }, 833 }; 834 835 if (!np && !pdev->dev.platform_data) 836 return -ENODEV; 837 838 devlink = 839 devlink_alloc(&ocelot_devlink_ops, sizeof(*ocelot), &pdev->dev); 840 if (!devlink) 841 return -ENOMEM; 842 843 ocelot = devlink_priv(devlink); 844 ocelot->devlink = priv_to_devlink(ocelot); 845 platform_set_drvdata(pdev, ocelot); 846 ocelot->dev = &pdev->dev; 847 848 for (i = 0; i < ARRAY_SIZE(io_target); i++) { 849 struct regmap *target; 850 struct resource *res; 851 852 res = platform_get_resource_byname(pdev, IORESOURCE_MEM, 853 io_target[i].name); 854 855 target = ocelot_regmap_init(ocelot, res); 856 if (IS_ERR(target)) { 857 if (io_target[i].optional) { 858 ocelot->targets[io_target[i].id] = NULL; 859 continue; 860 } 861 err = PTR_ERR(target); 862 goto out_free_devlink; 863 } 864 865 ocelot->targets[io_target[i].id] = target; 866 } 867 868 if (ocelot->targets[FDMA]) 869 ocelot_fdma_init(pdev, ocelot); 870 871 hsio = syscon_regmap_lookup_by_compatible("mscc,ocelot-hsio"); 872 if (IS_ERR(hsio)) { 873 dev_err(&pdev->dev, "missing hsio syscon\n"); 874 err = PTR_ERR(hsio); 875 goto out_free_devlink; 876 } 877 878 ocelot->targets[HSIO] = hsio; 879 880 err = ocelot_chip_init(ocelot, &ocelot_ops); 881 if (err) 882 goto out_free_devlink; 883 884 irq_xtr = platform_get_irq_byname(pdev, "xtr"); 885 if (irq_xtr < 0) { 886 err = irq_xtr; 887 goto out_free_devlink; 888 } 889 890 err = devm_request_threaded_irq(&pdev->dev, irq_xtr, NULL, 891 ocelot_xtr_irq_handler, IRQF_ONESHOT, 892 "frame extraction", ocelot); 893 if (err) 894 goto out_free_devlink; 895 896 irq_ptp_rdy = platform_get_irq_byname(pdev, "ptp_rdy"); 897 if (irq_ptp_rdy > 0 && ocelot->targets[PTP]) { 898 err = devm_request_threaded_irq(&pdev->dev, irq_ptp_rdy, NULL, 899 ocelot_ptp_rdy_irq_handler, 900 IRQF_ONESHOT, "ptp ready", 901 ocelot); 902 if (err) 903 goto out_free_devlink; 904 905 /* Both the PTP interrupt and the PTP bank are available */ 906 ocelot->ptp = 1; 907 } 908 909 ports = of_get_child_by_name(np, "ethernet-ports"); 910 if (!ports) { 911 dev_err(ocelot->dev, "no ethernet-ports child node found\n"); 912 err = -ENODEV; 913 goto out_free_devlink; 914 } 915 916 ocelot->num_phys_ports = of_get_child_count(ports); 917 ocelot->num_flooding_pgids = 1; 918 919 ocelot->vcap = vsc7514_vcap_props; 920 921 ocelot->vcap_pol.base = VSC7514_VCAP_POLICER_BASE; 922 ocelot->vcap_pol.max = VSC7514_VCAP_POLICER_MAX; 923 924 ocelot->npi = -1; 925 926 err = ocelot_init(ocelot); 927 if (err) 928 goto out_put_ports; 929 930 err = mscc_ocelot_init_ports(pdev, ports); 931 if (err) 932 goto out_ocelot_devlink_unregister; 933 934 if (ocelot->fdma) 935 ocelot_fdma_start(ocelot); 936 937 err = ocelot_devlink_sb_register(ocelot); 938 if (err) 939 goto out_ocelot_release_ports; 940 941 if (ocelot->ptp) { 942 err = ocelot_init_timestamp(ocelot, &ocelot_ptp_clock_info); 943 if (err) { 944 dev_err(ocelot->dev, 945 "Timestamp initialization failed\n"); 946 ocelot->ptp = 0; 947 } 948 } 949 950 register_netdevice_notifier(&ocelot_netdevice_nb); 951 register_switchdev_notifier(&ocelot_switchdev_nb); 952 register_switchdev_blocking_notifier(&ocelot_switchdev_blocking_nb); 953 954 of_node_put(ports); 955 devlink_register(devlink); 956 957 dev_info(&pdev->dev, "Ocelot switch probed\n"); 958 959 return 0; 960 961 out_ocelot_release_ports: 962 mscc_ocelot_release_ports(ocelot); 963 mscc_ocelot_teardown_devlink_ports(ocelot); 964 out_ocelot_devlink_unregister: 965 ocelot_deinit(ocelot); 966 out_put_ports: 967 of_node_put(ports); 968 out_free_devlink: 969 devlink_free(devlink); 970 return err; 971 } 972 973 static int mscc_ocelot_remove(struct platform_device *pdev) 974 { 975 struct ocelot *ocelot = platform_get_drvdata(pdev); 976 977 if (ocelot->fdma) 978 ocelot_fdma_deinit(ocelot); 979 devlink_unregister(ocelot->devlink); 980 ocelot_deinit_timestamp(ocelot); 981 ocelot_devlink_sb_unregister(ocelot); 982 mscc_ocelot_release_ports(ocelot); 983 mscc_ocelot_teardown_devlink_ports(ocelot); 984 ocelot_deinit(ocelot); 985 unregister_switchdev_blocking_notifier(&ocelot_switchdev_blocking_nb); 986 unregister_switchdev_notifier(&ocelot_switchdev_nb); 987 unregister_netdevice_notifier(&ocelot_netdevice_nb); 988 devlink_free(ocelot->devlink); 989 990 return 0; 991 } 992 993 static struct platform_driver mscc_ocelot_driver = { 994 .probe = mscc_ocelot_probe, 995 .remove = mscc_ocelot_remove, 996 .driver = { 997 .name = "ocelot-switch", 998 .of_match_table = mscc_ocelot_match, 999 }, 1000 }; 1001 1002 module_platform_driver(mscc_ocelot_driver); 1003 1004 MODULE_DESCRIPTION("Microsemi Ocelot switch driver"); 1005 MODULE_AUTHOR("Alexandre Belloni <alexandre.belloni@bootlin.com>"); 1006 MODULE_LICENSE("Dual MIT/GPL"); 1007