1 // SPDX-License-Identifier: (GPL-2.0 OR MIT) 2 /* Copyright 2017 Microsemi Corporation 3 * Copyright 2018-2019 NXP Semiconductors 4 */ 5 #include <linux/fsl/enetc_mdio.h> 6 #include <soc/mscc/ocelot_sys.h> 7 #include <soc/mscc/ocelot.h> 8 #include <linux/iopoll.h> 9 #include <linux/pci.h> 10 #include "felix.h" 11 12 /* TODO: should find a better place for these */ 13 #define USXGMII_BMCR_RESET BIT(15) 14 #define USXGMII_BMCR_AN_EN BIT(12) 15 #define USXGMII_BMCR_RST_AN BIT(9) 16 #define USXGMII_BMSR_LNKS(status) (((status) & GENMASK(2, 2)) >> 2) 17 #define USXGMII_BMSR_AN_CMPL(status) (((status) & GENMASK(5, 5)) >> 5) 18 #define USXGMII_ADVERTISE_LNKS(x) (((x) << 15) & BIT(15)) 19 #define USXGMII_ADVERTISE_FDX BIT(12) 20 #define USXGMII_ADVERTISE_SPEED(x) (((x) << 9) & GENMASK(11, 9)) 21 #define USXGMII_LPA_LNKS(lpa) ((lpa) >> 15) 22 #define USXGMII_LPA_DUPLEX(lpa) (((lpa) & GENMASK(12, 12)) >> 12) 23 #define USXGMII_LPA_SPEED(lpa) (((lpa) & GENMASK(11, 9)) >> 9) 24 25 enum usxgmii_speed { 26 USXGMII_SPEED_10 = 0, 27 USXGMII_SPEED_100 = 1, 28 USXGMII_SPEED_1000 = 2, 29 USXGMII_SPEED_2500 = 4, 30 }; 31 32 static const u32 vsc9959_ana_regmap[] = { 33 REG(ANA_ADVLEARN, 0x0089a0), 34 REG(ANA_VLANMASK, 0x0089a4), 35 REG_RESERVED(ANA_PORT_B_DOMAIN), 36 REG(ANA_ANAGEFIL, 0x0089ac), 37 REG(ANA_ANEVENTS, 0x0089b0), 38 REG(ANA_STORMLIMIT_BURST, 0x0089b4), 39 REG(ANA_STORMLIMIT_CFG, 0x0089b8), 40 REG(ANA_ISOLATED_PORTS, 0x0089c8), 41 REG(ANA_COMMUNITY_PORTS, 0x0089cc), 42 REG(ANA_AUTOAGE, 0x0089d0), 43 REG(ANA_MACTOPTIONS, 0x0089d4), 44 REG(ANA_LEARNDISC, 0x0089d8), 45 REG(ANA_AGENCTRL, 0x0089dc), 46 REG(ANA_MIRRORPORTS, 0x0089e0), 47 REG(ANA_EMIRRORPORTS, 0x0089e4), 48 REG(ANA_FLOODING, 0x0089e8), 49 REG(ANA_FLOODING_IPMC, 0x008a08), 50 REG(ANA_SFLOW_CFG, 0x008a0c), 51 REG(ANA_PORT_MODE, 0x008a28), 52 REG(ANA_CUT_THRU_CFG, 0x008a48), 53 REG(ANA_PGID_PGID, 0x008400), 54 REG(ANA_TABLES_ANMOVED, 0x007f1c), 55 REG(ANA_TABLES_MACHDATA, 0x007f20), 56 REG(ANA_TABLES_MACLDATA, 0x007f24), 57 REG(ANA_TABLES_STREAMDATA, 0x007f28), 58 REG(ANA_TABLES_MACACCESS, 0x007f2c), 59 REG(ANA_TABLES_MACTINDX, 0x007f30), 60 REG(ANA_TABLES_VLANACCESS, 0x007f34), 61 REG(ANA_TABLES_VLANTIDX, 0x007f38), 62 REG(ANA_TABLES_ISDXACCESS, 0x007f3c), 63 REG(ANA_TABLES_ISDXTIDX, 0x007f40), 64 REG(ANA_TABLES_ENTRYLIM, 0x007f00), 65 REG(ANA_TABLES_PTP_ID_HIGH, 0x007f44), 66 REG(ANA_TABLES_PTP_ID_LOW, 0x007f48), 67 REG(ANA_TABLES_STREAMACCESS, 0x007f4c), 68 REG(ANA_TABLES_STREAMTIDX, 0x007f50), 69 REG(ANA_TABLES_SEQ_HISTORY, 0x007f54), 70 REG(ANA_TABLES_SEQ_MASK, 0x007f58), 71 REG(ANA_TABLES_SFID_MASK, 0x007f5c), 72 REG(ANA_TABLES_SFIDACCESS, 0x007f60), 73 REG(ANA_TABLES_SFIDTIDX, 0x007f64), 74 REG(ANA_MSTI_STATE, 0x008600), 75 REG(ANA_OAM_UPM_LM_CNT, 0x008000), 76 REG(ANA_SG_ACCESS_CTRL, 0x008a64), 77 REG(ANA_SG_CONFIG_REG_1, 0x007fb0), 78 REG(ANA_SG_CONFIG_REG_2, 0x007fb4), 79 REG(ANA_SG_CONFIG_REG_3, 0x007fb8), 80 REG(ANA_SG_CONFIG_REG_4, 0x007fbc), 81 REG(ANA_SG_CONFIG_REG_5, 0x007fc0), 82 REG(ANA_SG_GCL_GS_CONFIG, 0x007f80), 83 REG(ANA_SG_GCL_TI_CONFIG, 0x007f90), 84 REG(ANA_SG_STATUS_REG_1, 0x008980), 85 REG(ANA_SG_STATUS_REG_2, 0x008984), 86 REG(ANA_SG_STATUS_REG_3, 0x008988), 87 REG(ANA_PORT_VLAN_CFG, 0x007800), 88 REG(ANA_PORT_DROP_CFG, 0x007804), 89 REG(ANA_PORT_QOS_CFG, 0x007808), 90 REG(ANA_PORT_VCAP_CFG, 0x00780c), 91 REG(ANA_PORT_VCAP_S1_KEY_CFG, 0x007810), 92 REG(ANA_PORT_VCAP_S2_CFG, 0x00781c), 93 REG(ANA_PORT_PCP_DEI_MAP, 0x007820), 94 REG(ANA_PORT_CPU_FWD_CFG, 0x007860), 95 REG(ANA_PORT_CPU_FWD_BPDU_CFG, 0x007864), 96 REG(ANA_PORT_CPU_FWD_GARP_CFG, 0x007868), 97 REG(ANA_PORT_CPU_FWD_CCM_CFG, 0x00786c), 98 REG(ANA_PORT_PORT_CFG, 0x007870), 99 REG(ANA_PORT_POL_CFG, 0x007874), 100 REG(ANA_PORT_PTP_CFG, 0x007878), 101 REG(ANA_PORT_PTP_DLY1_CFG, 0x00787c), 102 REG(ANA_PORT_PTP_DLY2_CFG, 0x007880), 103 REG(ANA_PORT_SFID_CFG, 0x007884), 104 REG(ANA_PFC_PFC_CFG, 0x008800), 105 REG_RESERVED(ANA_PFC_PFC_TIMER), 106 REG_RESERVED(ANA_IPT_OAM_MEP_CFG), 107 REG_RESERVED(ANA_IPT_IPT), 108 REG_RESERVED(ANA_PPT_PPT), 109 REG_RESERVED(ANA_FID_MAP_FID_MAP), 110 REG(ANA_AGGR_CFG, 0x008a68), 111 REG(ANA_CPUQ_CFG, 0x008a6c), 112 REG_RESERVED(ANA_CPUQ_CFG2), 113 REG(ANA_CPUQ_8021_CFG, 0x008a74), 114 REG(ANA_DSCP_CFG, 0x008ab4), 115 REG(ANA_DSCP_REWR_CFG, 0x008bb4), 116 REG(ANA_VCAP_RNG_TYPE_CFG, 0x008bf4), 117 REG(ANA_VCAP_RNG_VAL_CFG, 0x008c14), 118 REG_RESERVED(ANA_VRAP_CFG), 119 REG_RESERVED(ANA_VRAP_HDR_DATA), 120 REG_RESERVED(ANA_VRAP_HDR_MASK), 121 REG(ANA_DISCARD_CFG, 0x008c40), 122 REG(ANA_FID_CFG, 0x008c44), 123 REG(ANA_POL_PIR_CFG, 0x004000), 124 REG(ANA_POL_CIR_CFG, 0x004004), 125 REG(ANA_POL_MODE_CFG, 0x004008), 126 REG(ANA_POL_PIR_STATE, 0x00400c), 127 REG(ANA_POL_CIR_STATE, 0x004010), 128 REG_RESERVED(ANA_POL_STATE), 129 REG(ANA_POL_FLOWC, 0x008c48), 130 REG(ANA_POL_HYST, 0x008cb4), 131 REG_RESERVED(ANA_POL_MISC_CFG), 132 }; 133 134 static const u32 vsc9959_qs_regmap[] = { 135 REG(QS_XTR_GRP_CFG, 0x000000), 136 REG(QS_XTR_RD, 0x000008), 137 REG(QS_XTR_FRM_PRUNING, 0x000010), 138 REG(QS_XTR_FLUSH, 0x000018), 139 REG(QS_XTR_DATA_PRESENT, 0x00001c), 140 REG(QS_XTR_CFG, 0x000020), 141 REG(QS_INJ_GRP_CFG, 0x000024), 142 REG(QS_INJ_WR, 0x00002c), 143 REG(QS_INJ_CTRL, 0x000034), 144 REG(QS_INJ_STATUS, 0x00003c), 145 REG(QS_INJ_ERR, 0x000040), 146 REG_RESERVED(QS_INH_DBG), 147 }; 148 149 static const u32 vsc9959_s2_regmap[] = { 150 REG(S2_CORE_UPDATE_CTRL, 0x000000), 151 REG(S2_CORE_MV_CFG, 0x000004), 152 REG(S2_CACHE_ENTRY_DAT, 0x000008), 153 REG(S2_CACHE_MASK_DAT, 0x000108), 154 REG(S2_CACHE_ACTION_DAT, 0x000208), 155 REG(S2_CACHE_CNT_DAT, 0x000308), 156 REG(S2_CACHE_TG_DAT, 0x000388), 157 }; 158 159 static const u32 vsc9959_qsys_regmap[] = { 160 REG(QSYS_PORT_MODE, 0x00f460), 161 REG(QSYS_SWITCH_PORT_MODE, 0x00f480), 162 REG(QSYS_STAT_CNT_CFG, 0x00f49c), 163 REG(QSYS_EEE_CFG, 0x00f4a0), 164 REG(QSYS_EEE_THRES, 0x00f4b8), 165 REG(QSYS_IGR_NO_SHARING, 0x00f4bc), 166 REG(QSYS_EGR_NO_SHARING, 0x00f4c0), 167 REG(QSYS_SW_STATUS, 0x00f4c4), 168 REG(QSYS_EXT_CPU_CFG, 0x00f4e0), 169 REG_RESERVED(QSYS_PAD_CFG), 170 REG(QSYS_CPU_GROUP_MAP, 0x00f4e8), 171 REG_RESERVED(QSYS_QMAP), 172 REG_RESERVED(QSYS_ISDX_SGRP), 173 REG_RESERVED(QSYS_TIMED_FRAME_ENTRY), 174 REG(QSYS_TFRM_MISC, 0x00f50c), 175 REG(QSYS_TFRM_PORT_DLY, 0x00f510), 176 REG(QSYS_TFRM_TIMER_CFG_1, 0x00f514), 177 REG(QSYS_TFRM_TIMER_CFG_2, 0x00f518), 178 REG(QSYS_TFRM_TIMER_CFG_3, 0x00f51c), 179 REG(QSYS_TFRM_TIMER_CFG_4, 0x00f520), 180 REG(QSYS_TFRM_TIMER_CFG_5, 0x00f524), 181 REG(QSYS_TFRM_TIMER_CFG_6, 0x00f528), 182 REG(QSYS_TFRM_TIMER_CFG_7, 0x00f52c), 183 REG(QSYS_TFRM_TIMER_CFG_8, 0x00f530), 184 REG(QSYS_RED_PROFILE, 0x00f534), 185 REG(QSYS_RES_QOS_MODE, 0x00f574), 186 REG(QSYS_RES_CFG, 0x00c000), 187 REG(QSYS_RES_STAT, 0x00c004), 188 REG(QSYS_EGR_DROP_MODE, 0x00f578), 189 REG(QSYS_EQ_CTRL, 0x00f57c), 190 REG_RESERVED(QSYS_EVENTS_CORE), 191 REG(QSYS_QMAXSDU_CFG_0, 0x00f584), 192 REG(QSYS_QMAXSDU_CFG_1, 0x00f5a0), 193 REG(QSYS_QMAXSDU_CFG_2, 0x00f5bc), 194 REG(QSYS_QMAXSDU_CFG_3, 0x00f5d8), 195 REG(QSYS_QMAXSDU_CFG_4, 0x00f5f4), 196 REG(QSYS_QMAXSDU_CFG_5, 0x00f610), 197 REG(QSYS_QMAXSDU_CFG_6, 0x00f62c), 198 REG(QSYS_QMAXSDU_CFG_7, 0x00f648), 199 REG(QSYS_PREEMPTION_CFG, 0x00f664), 200 REG_RESERVED(QSYS_CIR_CFG), 201 REG(QSYS_EIR_CFG, 0x000004), 202 REG(QSYS_SE_CFG, 0x000008), 203 REG(QSYS_SE_DWRR_CFG, 0x00000c), 204 REG_RESERVED(QSYS_SE_CONNECT), 205 REG(QSYS_SE_DLB_SENSE, 0x000040), 206 REG(QSYS_CIR_STATE, 0x000044), 207 REG(QSYS_EIR_STATE, 0x000048), 208 REG_RESERVED(QSYS_SE_STATE), 209 REG(QSYS_HSCH_MISC_CFG, 0x00f67c), 210 REG(QSYS_TAG_CONFIG, 0x00f680), 211 REG(QSYS_TAS_PARAM_CFG_CTRL, 0x00f698), 212 REG(QSYS_PORT_MAX_SDU, 0x00f69c), 213 REG(QSYS_PARAM_CFG_REG_1, 0x00f440), 214 REG(QSYS_PARAM_CFG_REG_2, 0x00f444), 215 REG(QSYS_PARAM_CFG_REG_3, 0x00f448), 216 REG(QSYS_PARAM_CFG_REG_4, 0x00f44c), 217 REG(QSYS_PARAM_CFG_REG_5, 0x00f450), 218 REG(QSYS_GCL_CFG_REG_1, 0x00f454), 219 REG(QSYS_GCL_CFG_REG_2, 0x00f458), 220 REG(QSYS_PARAM_STATUS_REG_1, 0x00f400), 221 REG(QSYS_PARAM_STATUS_REG_2, 0x00f404), 222 REG(QSYS_PARAM_STATUS_REG_3, 0x00f408), 223 REG(QSYS_PARAM_STATUS_REG_4, 0x00f40c), 224 REG(QSYS_PARAM_STATUS_REG_5, 0x00f410), 225 REG(QSYS_PARAM_STATUS_REG_6, 0x00f414), 226 REG(QSYS_PARAM_STATUS_REG_7, 0x00f418), 227 REG(QSYS_PARAM_STATUS_REG_8, 0x00f41c), 228 REG(QSYS_PARAM_STATUS_REG_9, 0x00f420), 229 REG(QSYS_GCL_STATUS_REG_1, 0x00f424), 230 REG(QSYS_GCL_STATUS_REG_2, 0x00f428), 231 }; 232 233 static const u32 vsc9959_rew_regmap[] = { 234 REG(REW_PORT_VLAN_CFG, 0x000000), 235 REG(REW_TAG_CFG, 0x000004), 236 REG(REW_PORT_CFG, 0x000008), 237 REG(REW_DSCP_CFG, 0x00000c), 238 REG(REW_PCP_DEI_QOS_MAP_CFG, 0x000010), 239 REG(REW_PTP_CFG, 0x000050), 240 REG(REW_PTP_DLY1_CFG, 0x000054), 241 REG(REW_RED_TAG_CFG, 0x000058), 242 REG(REW_DSCP_REMAP_DP1_CFG, 0x000410), 243 REG(REW_DSCP_REMAP_CFG, 0x000510), 244 REG_RESERVED(REW_STAT_CFG), 245 REG_RESERVED(REW_REW_STICKY), 246 REG_RESERVED(REW_PPT), 247 }; 248 249 static const u32 vsc9959_sys_regmap[] = { 250 REG(SYS_COUNT_RX_OCTETS, 0x000000), 251 REG(SYS_COUNT_RX_MULTICAST, 0x000008), 252 REG(SYS_COUNT_RX_SHORTS, 0x000010), 253 REG(SYS_COUNT_RX_FRAGMENTS, 0x000014), 254 REG(SYS_COUNT_RX_JABBERS, 0x000018), 255 REG(SYS_COUNT_RX_64, 0x000024), 256 REG(SYS_COUNT_RX_65_127, 0x000028), 257 REG(SYS_COUNT_RX_128_255, 0x00002c), 258 REG(SYS_COUNT_RX_256_1023, 0x000030), 259 REG(SYS_COUNT_RX_1024_1526, 0x000034), 260 REG(SYS_COUNT_RX_1527_MAX, 0x000038), 261 REG(SYS_COUNT_RX_LONGS, 0x000044), 262 REG(SYS_COUNT_TX_OCTETS, 0x000200), 263 REG(SYS_COUNT_TX_COLLISION, 0x000210), 264 REG(SYS_COUNT_TX_DROPS, 0x000214), 265 REG(SYS_COUNT_TX_64, 0x00021c), 266 REG(SYS_COUNT_TX_65_127, 0x000220), 267 REG(SYS_COUNT_TX_128_511, 0x000224), 268 REG(SYS_COUNT_TX_512_1023, 0x000228), 269 REG(SYS_COUNT_TX_1024_1526, 0x00022c), 270 REG(SYS_COUNT_TX_1527_MAX, 0x000230), 271 REG(SYS_COUNT_TX_AGING, 0x000278), 272 REG(SYS_RESET_CFG, 0x000e00), 273 REG(SYS_SR_ETYPE_CFG, 0x000e04), 274 REG(SYS_VLAN_ETYPE_CFG, 0x000e08), 275 REG(SYS_PORT_MODE, 0x000e0c), 276 REG(SYS_FRONT_PORT_MODE, 0x000e2c), 277 REG(SYS_FRM_AGING, 0x000e44), 278 REG(SYS_STAT_CFG, 0x000e48), 279 REG(SYS_SW_STATUS, 0x000e4c), 280 REG_RESERVED(SYS_MISC_CFG), 281 REG(SYS_REW_MAC_HIGH_CFG, 0x000e6c), 282 REG(SYS_REW_MAC_LOW_CFG, 0x000e84), 283 REG(SYS_TIMESTAMP_OFFSET, 0x000e9c), 284 REG(SYS_PAUSE_CFG, 0x000ea0), 285 REG(SYS_PAUSE_TOT_CFG, 0x000ebc), 286 REG(SYS_ATOP, 0x000ec0), 287 REG(SYS_ATOP_TOT_CFG, 0x000edc), 288 REG(SYS_MAC_FC_CFG, 0x000ee0), 289 REG(SYS_MMGT, 0x000ef8), 290 REG_RESERVED(SYS_MMGT_FAST), 291 REG_RESERVED(SYS_EVENTS_DIF), 292 REG_RESERVED(SYS_EVENTS_CORE), 293 REG_RESERVED(SYS_CNT), 294 REG(SYS_PTP_STATUS, 0x000f14), 295 REG(SYS_PTP_TXSTAMP, 0x000f18), 296 REG(SYS_PTP_NXT, 0x000f1c), 297 REG(SYS_PTP_CFG, 0x000f20), 298 REG(SYS_RAM_INIT, 0x000f24), 299 REG_RESERVED(SYS_CM_ADDR), 300 REG_RESERVED(SYS_CM_DATA_WR), 301 REG_RESERVED(SYS_CM_DATA_RD), 302 REG_RESERVED(SYS_CM_OP), 303 REG_RESERVED(SYS_CM_DATA), 304 }; 305 306 static const u32 vsc9959_ptp_regmap[] = { 307 REG(PTP_PIN_CFG, 0x000000), 308 REG(PTP_PIN_TOD_SEC_MSB, 0x000004), 309 REG(PTP_PIN_TOD_SEC_LSB, 0x000008), 310 REG(PTP_PIN_TOD_NSEC, 0x00000c), 311 REG(PTP_CFG_MISC, 0x0000a0), 312 REG(PTP_CLK_CFG_ADJ_CFG, 0x0000a4), 313 REG(PTP_CLK_CFG_ADJ_FREQ, 0x0000a8), 314 }; 315 316 static const u32 vsc9959_gcb_regmap[] = { 317 REG(GCB_SOFT_RST, 0x000004), 318 }; 319 320 static const u32 *vsc9959_regmap[] = { 321 [ANA] = vsc9959_ana_regmap, 322 [QS] = vsc9959_qs_regmap, 323 [QSYS] = vsc9959_qsys_regmap, 324 [REW] = vsc9959_rew_regmap, 325 [SYS] = vsc9959_sys_regmap, 326 [S2] = vsc9959_s2_regmap, 327 [PTP] = vsc9959_ptp_regmap, 328 [GCB] = vsc9959_gcb_regmap, 329 }; 330 331 /* Addresses are relative to the PCI device's base address and 332 * will be fixed up at ioremap time. 333 */ 334 static struct resource vsc9959_target_io_res[] = { 335 [ANA] = { 336 .start = 0x0280000, 337 .end = 0x028ffff, 338 .name = "ana", 339 }, 340 [QS] = { 341 .start = 0x0080000, 342 .end = 0x00800ff, 343 .name = "qs", 344 }, 345 [QSYS] = { 346 .start = 0x0200000, 347 .end = 0x021ffff, 348 .name = "qsys", 349 }, 350 [REW] = { 351 .start = 0x0030000, 352 .end = 0x003ffff, 353 .name = "rew", 354 }, 355 [SYS] = { 356 .start = 0x0010000, 357 .end = 0x001ffff, 358 .name = "sys", 359 }, 360 [S2] = { 361 .start = 0x0060000, 362 .end = 0x00603ff, 363 .name = "s2", 364 }, 365 [PTP] = { 366 .start = 0x0090000, 367 .end = 0x00900cb, 368 .name = "ptp", 369 }, 370 [GCB] = { 371 .start = 0x0070000, 372 .end = 0x00701ff, 373 .name = "devcpu_gcb", 374 }, 375 }; 376 377 static struct resource vsc9959_port_io_res[] = { 378 { 379 .start = 0x0100000, 380 .end = 0x010ffff, 381 .name = "port0", 382 }, 383 { 384 .start = 0x0110000, 385 .end = 0x011ffff, 386 .name = "port1", 387 }, 388 { 389 .start = 0x0120000, 390 .end = 0x012ffff, 391 .name = "port2", 392 }, 393 { 394 .start = 0x0130000, 395 .end = 0x013ffff, 396 .name = "port3", 397 }, 398 { 399 .start = 0x0140000, 400 .end = 0x014ffff, 401 .name = "port4", 402 }, 403 { 404 .start = 0x0150000, 405 .end = 0x015ffff, 406 .name = "port5", 407 }, 408 }; 409 410 /* Port MAC 0 Internal MDIO bus through which the SerDes acting as an 411 * SGMII/QSGMII MAC PCS can be found. 412 */ 413 static struct resource vsc9959_imdio_res = { 414 .start = 0x8030, 415 .end = 0x8040, 416 .name = "imdio", 417 }; 418 419 static const struct reg_field vsc9959_regfields[] = { 420 [ANA_ADVLEARN_VLAN_CHK] = REG_FIELD(ANA_ADVLEARN, 6, 6), 421 [ANA_ADVLEARN_LEARN_MIRROR] = REG_FIELD(ANA_ADVLEARN, 0, 5), 422 [ANA_ANEVENTS_FLOOD_DISCARD] = REG_FIELD(ANA_ANEVENTS, 30, 30), 423 [ANA_ANEVENTS_AUTOAGE] = REG_FIELD(ANA_ANEVENTS, 26, 26), 424 [ANA_ANEVENTS_STORM_DROP] = REG_FIELD(ANA_ANEVENTS, 24, 24), 425 [ANA_ANEVENTS_LEARN_DROP] = REG_FIELD(ANA_ANEVENTS, 23, 23), 426 [ANA_ANEVENTS_AGED_ENTRY] = REG_FIELD(ANA_ANEVENTS, 22, 22), 427 [ANA_ANEVENTS_CPU_LEARN_FAILED] = REG_FIELD(ANA_ANEVENTS, 21, 21), 428 [ANA_ANEVENTS_AUTO_LEARN_FAILED] = REG_FIELD(ANA_ANEVENTS, 20, 20), 429 [ANA_ANEVENTS_LEARN_REMOVE] = REG_FIELD(ANA_ANEVENTS, 19, 19), 430 [ANA_ANEVENTS_AUTO_LEARNED] = REG_FIELD(ANA_ANEVENTS, 18, 18), 431 [ANA_ANEVENTS_AUTO_MOVED] = REG_FIELD(ANA_ANEVENTS, 17, 17), 432 [ANA_ANEVENTS_CLASSIFIED_DROP] = REG_FIELD(ANA_ANEVENTS, 15, 15), 433 [ANA_ANEVENTS_CLASSIFIED_COPY] = REG_FIELD(ANA_ANEVENTS, 14, 14), 434 [ANA_ANEVENTS_VLAN_DISCARD] = REG_FIELD(ANA_ANEVENTS, 13, 13), 435 [ANA_ANEVENTS_FWD_DISCARD] = REG_FIELD(ANA_ANEVENTS, 12, 12), 436 [ANA_ANEVENTS_MULTICAST_FLOOD] = REG_FIELD(ANA_ANEVENTS, 11, 11), 437 [ANA_ANEVENTS_UNICAST_FLOOD] = REG_FIELD(ANA_ANEVENTS, 10, 10), 438 [ANA_ANEVENTS_DEST_KNOWN] = REG_FIELD(ANA_ANEVENTS, 9, 9), 439 [ANA_ANEVENTS_BUCKET3_MATCH] = REG_FIELD(ANA_ANEVENTS, 8, 8), 440 [ANA_ANEVENTS_BUCKET2_MATCH] = REG_FIELD(ANA_ANEVENTS, 7, 7), 441 [ANA_ANEVENTS_BUCKET1_MATCH] = REG_FIELD(ANA_ANEVENTS, 6, 6), 442 [ANA_ANEVENTS_BUCKET0_MATCH] = REG_FIELD(ANA_ANEVENTS, 5, 5), 443 [ANA_ANEVENTS_CPU_OPERATION] = REG_FIELD(ANA_ANEVENTS, 4, 4), 444 [ANA_ANEVENTS_DMAC_LOOKUP] = REG_FIELD(ANA_ANEVENTS, 3, 3), 445 [ANA_ANEVENTS_SMAC_LOOKUP] = REG_FIELD(ANA_ANEVENTS, 2, 2), 446 [ANA_ANEVENTS_SEQ_GEN_ERR_0] = REG_FIELD(ANA_ANEVENTS, 1, 1), 447 [ANA_ANEVENTS_SEQ_GEN_ERR_1] = REG_FIELD(ANA_ANEVENTS, 0, 0), 448 [ANA_TABLES_MACACCESS_B_DOM] = REG_FIELD(ANA_TABLES_MACACCESS, 16, 16), 449 [ANA_TABLES_MACTINDX_BUCKET] = REG_FIELD(ANA_TABLES_MACTINDX, 11, 12), 450 [ANA_TABLES_MACTINDX_M_INDEX] = REG_FIELD(ANA_TABLES_MACTINDX, 0, 10), 451 [SYS_RESET_CFG_CORE_ENA] = REG_FIELD(SYS_RESET_CFG, 0, 0), 452 [GCB_SOFT_RST_SWC_RST] = REG_FIELD(GCB_SOFT_RST, 0, 0), 453 }; 454 455 static const struct ocelot_stat_layout vsc9959_stats_layout[] = { 456 { .offset = 0x00, .name = "rx_octets", }, 457 { .offset = 0x01, .name = "rx_unicast", }, 458 { .offset = 0x02, .name = "rx_multicast", }, 459 { .offset = 0x03, .name = "rx_broadcast", }, 460 { .offset = 0x04, .name = "rx_shorts", }, 461 { .offset = 0x05, .name = "rx_fragments", }, 462 { .offset = 0x06, .name = "rx_jabbers", }, 463 { .offset = 0x07, .name = "rx_crc_align_errs", }, 464 { .offset = 0x08, .name = "rx_sym_errs", }, 465 { .offset = 0x09, .name = "rx_frames_below_65_octets", }, 466 { .offset = 0x0A, .name = "rx_frames_65_to_127_octets", }, 467 { .offset = 0x0B, .name = "rx_frames_128_to_255_octets", }, 468 { .offset = 0x0C, .name = "rx_frames_256_to_511_octets", }, 469 { .offset = 0x0D, .name = "rx_frames_512_to_1023_octets", }, 470 { .offset = 0x0E, .name = "rx_frames_1024_to_1526_octets", }, 471 { .offset = 0x0F, .name = "rx_frames_over_1526_octets", }, 472 { .offset = 0x10, .name = "rx_pause", }, 473 { .offset = 0x11, .name = "rx_control", }, 474 { .offset = 0x12, .name = "rx_longs", }, 475 { .offset = 0x13, .name = "rx_classified_drops", }, 476 { .offset = 0x14, .name = "rx_red_prio_0", }, 477 { .offset = 0x15, .name = "rx_red_prio_1", }, 478 { .offset = 0x16, .name = "rx_red_prio_2", }, 479 { .offset = 0x17, .name = "rx_red_prio_3", }, 480 { .offset = 0x18, .name = "rx_red_prio_4", }, 481 { .offset = 0x19, .name = "rx_red_prio_5", }, 482 { .offset = 0x1A, .name = "rx_red_prio_6", }, 483 { .offset = 0x1B, .name = "rx_red_prio_7", }, 484 { .offset = 0x1C, .name = "rx_yellow_prio_0", }, 485 { .offset = 0x1D, .name = "rx_yellow_prio_1", }, 486 { .offset = 0x1E, .name = "rx_yellow_prio_2", }, 487 { .offset = 0x1F, .name = "rx_yellow_prio_3", }, 488 { .offset = 0x20, .name = "rx_yellow_prio_4", }, 489 { .offset = 0x21, .name = "rx_yellow_prio_5", }, 490 { .offset = 0x22, .name = "rx_yellow_prio_6", }, 491 { .offset = 0x23, .name = "rx_yellow_prio_7", }, 492 { .offset = 0x24, .name = "rx_green_prio_0", }, 493 { .offset = 0x25, .name = "rx_green_prio_1", }, 494 { .offset = 0x26, .name = "rx_green_prio_2", }, 495 { .offset = 0x27, .name = "rx_green_prio_3", }, 496 { .offset = 0x28, .name = "rx_green_prio_4", }, 497 { .offset = 0x29, .name = "rx_green_prio_5", }, 498 { .offset = 0x2A, .name = "rx_green_prio_6", }, 499 { .offset = 0x2B, .name = "rx_green_prio_7", }, 500 { .offset = 0x80, .name = "tx_octets", }, 501 { .offset = 0x81, .name = "tx_unicast", }, 502 { .offset = 0x82, .name = "tx_multicast", }, 503 { .offset = 0x83, .name = "tx_broadcast", }, 504 { .offset = 0x84, .name = "tx_collision", }, 505 { .offset = 0x85, .name = "tx_drops", }, 506 { .offset = 0x86, .name = "tx_pause", }, 507 { .offset = 0x87, .name = "tx_frames_below_65_octets", }, 508 { .offset = 0x88, .name = "tx_frames_65_to_127_octets", }, 509 { .offset = 0x89, .name = "tx_frames_128_255_octets", }, 510 { .offset = 0x8B, .name = "tx_frames_256_511_octets", }, 511 { .offset = 0x8C, .name = "tx_frames_1024_1526_octets", }, 512 { .offset = 0x8D, .name = "tx_frames_over_1526_octets", }, 513 { .offset = 0x8E, .name = "tx_yellow_prio_0", }, 514 { .offset = 0x8F, .name = "tx_yellow_prio_1", }, 515 { .offset = 0x90, .name = "tx_yellow_prio_2", }, 516 { .offset = 0x91, .name = "tx_yellow_prio_3", }, 517 { .offset = 0x92, .name = "tx_yellow_prio_4", }, 518 { .offset = 0x93, .name = "tx_yellow_prio_5", }, 519 { .offset = 0x94, .name = "tx_yellow_prio_6", }, 520 { .offset = 0x95, .name = "tx_yellow_prio_7", }, 521 { .offset = 0x96, .name = "tx_green_prio_0", }, 522 { .offset = 0x97, .name = "tx_green_prio_1", }, 523 { .offset = 0x98, .name = "tx_green_prio_2", }, 524 { .offset = 0x99, .name = "tx_green_prio_3", }, 525 { .offset = 0x9A, .name = "tx_green_prio_4", }, 526 { .offset = 0x9B, .name = "tx_green_prio_5", }, 527 { .offset = 0x9C, .name = "tx_green_prio_6", }, 528 { .offset = 0x9D, .name = "tx_green_prio_7", }, 529 { .offset = 0x9E, .name = "tx_aged", }, 530 { .offset = 0x100, .name = "drop_local", }, 531 { .offset = 0x101, .name = "drop_tail", }, 532 { .offset = 0x102, .name = "drop_yellow_prio_0", }, 533 { .offset = 0x103, .name = "drop_yellow_prio_1", }, 534 { .offset = 0x104, .name = "drop_yellow_prio_2", }, 535 { .offset = 0x105, .name = "drop_yellow_prio_3", }, 536 { .offset = 0x106, .name = "drop_yellow_prio_4", }, 537 { .offset = 0x107, .name = "drop_yellow_prio_5", }, 538 { .offset = 0x108, .name = "drop_yellow_prio_6", }, 539 { .offset = 0x109, .name = "drop_yellow_prio_7", }, 540 { .offset = 0x10A, .name = "drop_green_prio_0", }, 541 { .offset = 0x10B, .name = "drop_green_prio_1", }, 542 { .offset = 0x10C, .name = "drop_green_prio_2", }, 543 { .offset = 0x10D, .name = "drop_green_prio_3", }, 544 { .offset = 0x10E, .name = "drop_green_prio_4", }, 545 { .offset = 0x10F, .name = "drop_green_prio_5", }, 546 { .offset = 0x110, .name = "drop_green_prio_6", }, 547 { .offset = 0x111, .name = "drop_green_prio_7", }, 548 }; 549 550 #define VSC9959_INIT_TIMEOUT 50000 551 #define VSC9959_GCB_RST_SLEEP 100 552 #define VSC9959_SYS_RAMINIT_SLEEP 80 553 554 static int vsc9959_gcb_soft_rst_status(struct ocelot *ocelot) 555 { 556 int val; 557 558 regmap_field_read(ocelot->regfields[GCB_SOFT_RST_SWC_RST], &val); 559 560 return val; 561 } 562 563 static int vsc9959_sys_ram_init_status(struct ocelot *ocelot) 564 { 565 return ocelot_read(ocelot, SYS_RAM_INIT); 566 } 567 568 static int vsc9959_reset(struct ocelot *ocelot) 569 { 570 int val, err; 571 572 /* soft-reset the switch core */ 573 regmap_field_write(ocelot->regfields[GCB_SOFT_RST_SWC_RST], 1); 574 575 err = readx_poll_timeout(vsc9959_gcb_soft_rst_status, ocelot, val, !val, 576 VSC9959_GCB_RST_SLEEP, VSC9959_INIT_TIMEOUT); 577 if (err) { 578 dev_err(ocelot->dev, "timeout: switch core reset\n"); 579 return err; 580 } 581 582 /* initialize switch mem ~40us */ 583 ocelot_write(ocelot, SYS_RAM_INIT_RAM_INIT, SYS_RAM_INIT); 584 err = readx_poll_timeout(vsc9959_sys_ram_init_status, ocelot, val, !val, 585 VSC9959_SYS_RAMINIT_SLEEP, 586 VSC9959_INIT_TIMEOUT); 587 if (err) { 588 dev_err(ocelot->dev, "timeout: switch sram init\n"); 589 return err; 590 } 591 592 /* enable switch core */ 593 regmap_field_write(ocelot->regfields[SYS_RESET_CFG_CORE_ENA], 1); 594 595 return 0; 596 } 597 598 static void vsc9959_pcs_an_restart_sgmii(struct phy_device *pcs) 599 { 600 phy_set_bits(pcs, MII_BMCR, BMCR_ANRESTART); 601 } 602 603 static void vsc9959_pcs_an_restart_usxgmii(struct phy_device *pcs) 604 { 605 phy_write_mmd(pcs, MDIO_MMD_VEND2, MII_BMCR, 606 USXGMII_BMCR_RESET | 607 USXGMII_BMCR_AN_EN | 608 USXGMII_BMCR_RST_AN); 609 } 610 611 static void vsc9959_pcs_an_restart(struct ocelot *ocelot, int port) 612 { 613 struct felix *felix = ocelot_to_felix(ocelot); 614 struct phy_device *pcs = felix->pcs[port]; 615 616 if (!pcs) 617 return; 618 619 switch (pcs->interface) { 620 case PHY_INTERFACE_MODE_SGMII: 621 case PHY_INTERFACE_MODE_QSGMII: 622 vsc9959_pcs_an_restart_sgmii(pcs); 623 break; 624 case PHY_INTERFACE_MODE_USXGMII: 625 vsc9959_pcs_an_restart_usxgmii(pcs); 626 break; 627 default: 628 dev_err(ocelot->dev, "Invalid PCS interface type %s\n", 629 phy_modes(pcs->interface)); 630 break; 631 } 632 } 633 634 /* We enable SGMII AN only when the PHY has managed = "in-band-status" in the 635 * device tree. If we are in MLO_AN_PHY mode, we program directly state->speed 636 * into the PCS, which is retrieved out-of-band over MDIO. This also has the 637 * benefit of working with SGMII fixed-links, like downstream switches, where 638 * both link partners attempt to operate as AN slaves and therefore AN never 639 * completes. But it also has the disadvantage that some PHY chips don't pass 640 * traffic if SGMII AN is enabled but not completed (acknowledged by us), so 641 * setting MLO_AN_INBAND is actually required for those. 642 */ 643 static void vsc9959_pcs_init_sgmii(struct phy_device *pcs, 644 unsigned int link_an_mode, 645 const struct phylink_link_state *state) 646 { 647 if (link_an_mode == MLO_AN_INBAND) { 648 int bmsr, bmcr; 649 650 /* Some PHYs like VSC8234 don't like it when AN restarts on 651 * their system side and they restart line side AN too, going 652 * into an endless link up/down loop. Don't restart PCS AN if 653 * link is up already. 654 * We do check that AN is enabled just in case this is the 1st 655 * call, PCS detects a carrier but AN is disabled from power on 656 * or by boot loader. 657 */ 658 bmcr = phy_read(pcs, MII_BMCR); 659 if (bmcr < 0) 660 return; 661 662 bmsr = phy_read(pcs, MII_BMSR); 663 if (bmsr < 0) 664 return; 665 666 if ((bmcr & BMCR_ANENABLE) && (bmsr & BMSR_LSTATUS)) 667 return; 668 669 /* SGMII spec requires tx_config_Reg[15:0] to be exactly 0x4001 670 * for the MAC PCS in order to acknowledge the AN. 671 */ 672 phy_write(pcs, MII_ADVERTISE, ADVERTISE_SGMII | 673 ADVERTISE_LPACK); 674 675 phy_write(pcs, ENETC_PCS_IF_MODE, 676 ENETC_PCS_IF_MODE_SGMII_EN | 677 ENETC_PCS_IF_MODE_USE_SGMII_AN); 678 679 /* Adjust link timer for SGMII */ 680 phy_write(pcs, ENETC_PCS_LINK_TIMER1, 681 ENETC_PCS_LINK_TIMER1_VAL); 682 phy_write(pcs, ENETC_PCS_LINK_TIMER2, 683 ENETC_PCS_LINK_TIMER2_VAL); 684 685 phy_write(pcs, MII_BMCR, BMCR_ANRESTART | BMCR_ANENABLE); 686 } else { 687 int speed; 688 689 if (state->duplex == DUPLEX_HALF) { 690 phydev_err(pcs, "Half duplex not supported\n"); 691 return; 692 } 693 switch (state->speed) { 694 case SPEED_1000: 695 speed = ENETC_PCS_SPEED_1000; 696 break; 697 case SPEED_100: 698 speed = ENETC_PCS_SPEED_100; 699 break; 700 case SPEED_10: 701 speed = ENETC_PCS_SPEED_10; 702 break; 703 case SPEED_UNKNOWN: 704 /* Silently don't do anything */ 705 return; 706 default: 707 phydev_err(pcs, "Invalid PCS speed %d\n", state->speed); 708 return; 709 } 710 711 phy_write(pcs, ENETC_PCS_IF_MODE, 712 ENETC_PCS_IF_MODE_SGMII_EN | 713 ENETC_PCS_IF_MODE_SGMII_SPEED(speed)); 714 715 /* Yes, not a mistake: speed is given by IF_MODE. */ 716 phy_write(pcs, MII_BMCR, BMCR_RESET | 717 BMCR_SPEED1000 | 718 BMCR_FULLDPLX); 719 } 720 } 721 722 /* 2500Base-X is SerDes protocol 7 on Felix and 6 on ENETC. It is a SerDes lane 723 * clocked at 3.125 GHz which encodes symbols with 8b/10b and does not have 724 * auto-negotiation of any link parameters. Electrically it is compatible with 725 * a single lane of XAUI. 726 * The hardware reference manual wants to call this mode SGMII, but it isn't 727 * really, since the fundamental features of SGMII: 728 * - Downgrading the link speed by duplicating symbols 729 * - Auto-negotiation 730 * are not there. 731 * The speed is configured at 1000 in the IF_MODE and BMCR MDIO registers 732 * because the clock frequency is actually given by a PLL configured in the 733 * Reset Configuration Word (RCW). 734 * Since there is no difference between fixed speed SGMII w/o AN and 802.3z w/o 735 * AN, we call this PHY interface type 2500Base-X. In case a PHY negotiates a 736 * lower link speed on line side, the system-side interface remains fixed at 737 * 2500 Mbps and we do rate adaptation through pause frames. 738 */ 739 static void vsc9959_pcs_init_2500basex(struct phy_device *pcs, 740 unsigned int link_an_mode, 741 const struct phylink_link_state *state) 742 { 743 if (link_an_mode == MLO_AN_INBAND) { 744 phydev_err(pcs, "AN not supported on 3.125GHz SerDes lane\n"); 745 return; 746 } 747 748 phy_write(pcs, ENETC_PCS_IF_MODE, 749 ENETC_PCS_IF_MODE_SGMII_EN | 750 ENETC_PCS_IF_MODE_SGMII_SPEED(ENETC_PCS_SPEED_2500)); 751 752 phy_write(pcs, MII_BMCR, BMCR_SPEED1000 | 753 BMCR_FULLDPLX | 754 BMCR_RESET); 755 } 756 757 static void vsc9959_pcs_init_usxgmii(struct phy_device *pcs, 758 unsigned int link_an_mode, 759 const struct phylink_link_state *state) 760 { 761 if (link_an_mode != MLO_AN_INBAND) { 762 phydev_err(pcs, "USXGMII only supports in-band AN for now\n"); 763 return; 764 } 765 766 /* Configure device ability for the USXGMII Replicator */ 767 phy_write_mmd(pcs, MDIO_MMD_VEND2, MII_ADVERTISE, 768 USXGMII_ADVERTISE_SPEED(USXGMII_SPEED_2500) | 769 USXGMII_ADVERTISE_LNKS(1) | 770 ADVERTISE_SGMII | 771 ADVERTISE_LPACK | 772 USXGMII_ADVERTISE_FDX); 773 } 774 775 static void vsc9959_pcs_init(struct ocelot *ocelot, int port, 776 unsigned int link_an_mode, 777 const struct phylink_link_state *state) 778 { 779 struct felix *felix = ocelot_to_felix(ocelot); 780 struct phy_device *pcs = felix->pcs[port]; 781 782 if (!pcs) 783 return; 784 785 /* The PCS does not implement the BMSR register fully, so capability 786 * detection via genphy_read_abilities does not work. Since we can get 787 * the PHY config word from the LPA register though, there is still 788 * value in using the generic phy_resolve_aneg_linkmode function. So 789 * populate the supported and advertising link modes manually here. 790 */ 791 linkmode_set_bit_array(phy_basic_ports_array, 792 ARRAY_SIZE(phy_basic_ports_array), 793 pcs->supported); 794 linkmode_set_bit(ETHTOOL_LINK_MODE_10baseT_Full_BIT, pcs->supported); 795 linkmode_set_bit(ETHTOOL_LINK_MODE_100baseT_Full_BIT, pcs->supported); 796 linkmode_set_bit(ETHTOOL_LINK_MODE_1000baseT_Full_BIT, pcs->supported); 797 if (pcs->interface == PHY_INTERFACE_MODE_2500BASEX || 798 pcs->interface == PHY_INTERFACE_MODE_USXGMII) 799 linkmode_set_bit(ETHTOOL_LINK_MODE_2500baseX_Full_BIT, 800 pcs->supported); 801 if (pcs->interface != PHY_INTERFACE_MODE_2500BASEX) 802 linkmode_set_bit(ETHTOOL_LINK_MODE_Autoneg_BIT, 803 pcs->supported); 804 phy_advertise_supported(pcs); 805 806 switch (pcs->interface) { 807 case PHY_INTERFACE_MODE_SGMII: 808 case PHY_INTERFACE_MODE_QSGMII: 809 vsc9959_pcs_init_sgmii(pcs, link_an_mode, state); 810 break; 811 case PHY_INTERFACE_MODE_2500BASEX: 812 vsc9959_pcs_init_2500basex(pcs, link_an_mode, state); 813 break; 814 case PHY_INTERFACE_MODE_USXGMII: 815 vsc9959_pcs_init_usxgmii(pcs, link_an_mode, state); 816 break; 817 default: 818 dev_err(ocelot->dev, "Unsupported link mode %s\n", 819 phy_modes(pcs->interface)); 820 } 821 } 822 823 static void vsc9959_pcs_link_state_resolve(struct phy_device *pcs, 824 struct phylink_link_state *state) 825 { 826 state->an_complete = pcs->autoneg_complete; 827 state->an_enabled = pcs->autoneg; 828 state->link = pcs->link; 829 state->duplex = pcs->duplex; 830 state->speed = pcs->speed; 831 /* SGMII AN does not negotiate flow control, but that's ok, 832 * since phylink already knows that, and does: 833 * link_state.pause |= pl->phy_state.pause; 834 */ 835 state->pause = MLO_PAUSE_NONE; 836 837 phydev_dbg(pcs, 838 "mode=%s/%s/%s adv=%*pb lpa=%*pb link=%u an_enabled=%u an_complete=%u\n", 839 phy_modes(pcs->interface), 840 phy_speed_to_str(pcs->speed), 841 phy_duplex_to_str(pcs->duplex), 842 __ETHTOOL_LINK_MODE_MASK_NBITS, pcs->advertising, 843 __ETHTOOL_LINK_MODE_MASK_NBITS, pcs->lp_advertising, 844 pcs->link, pcs->autoneg, pcs->autoneg_complete); 845 } 846 847 static void vsc9959_pcs_link_state_sgmii(struct phy_device *pcs, 848 struct phylink_link_state *state) 849 { 850 int err; 851 852 err = genphy_update_link(pcs); 853 if (err < 0) 854 return; 855 856 if (pcs->autoneg_complete) { 857 u16 lpa = phy_read(pcs, MII_LPA); 858 859 mii_lpa_to_linkmode_lpa_sgmii(pcs->lp_advertising, lpa); 860 861 phy_resolve_aneg_linkmode(pcs); 862 } 863 } 864 865 static void vsc9959_pcs_link_state_2500basex(struct phy_device *pcs, 866 struct phylink_link_state *state) 867 { 868 int err; 869 870 err = genphy_update_link(pcs); 871 if (err < 0) 872 return; 873 874 pcs->speed = SPEED_2500; 875 pcs->asym_pause = true; 876 pcs->pause = true; 877 } 878 879 static void vsc9959_pcs_link_state_usxgmii(struct phy_device *pcs, 880 struct phylink_link_state *state) 881 { 882 int status, lpa; 883 884 status = phy_read_mmd(pcs, MDIO_MMD_VEND2, MII_BMSR); 885 if (status < 0) 886 return; 887 888 pcs->autoneg = true; 889 pcs->autoneg_complete = USXGMII_BMSR_AN_CMPL(status); 890 pcs->link = USXGMII_BMSR_LNKS(status); 891 892 if (!pcs->link || !pcs->autoneg_complete) 893 return; 894 895 lpa = phy_read_mmd(pcs, MDIO_MMD_VEND2, MII_LPA); 896 if (lpa < 0) 897 return; 898 899 switch (USXGMII_LPA_SPEED(lpa)) { 900 case USXGMII_SPEED_10: 901 pcs->speed = SPEED_10; 902 break; 903 case USXGMII_SPEED_100: 904 pcs->speed = SPEED_100; 905 break; 906 case USXGMII_SPEED_1000: 907 pcs->speed = SPEED_1000; 908 break; 909 case USXGMII_SPEED_2500: 910 pcs->speed = SPEED_2500; 911 break; 912 default: 913 break; 914 } 915 916 if (USXGMII_LPA_DUPLEX(lpa)) 917 pcs->duplex = DUPLEX_FULL; 918 else 919 pcs->duplex = DUPLEX_HALF; 920 } 921 922 static void vsc9959_pcs_link_state(struct ocelot *ocelot, int port, 923 struct phylink_link_state *state) 924 { 925 struct felix *felix = ocelot_to_felix(ocelot); 926 struct phy_device *pcs = felix->pcs[port]; 927 928 if (!pcs) 929 return; 930 931 pcs->speed = SPEED_UNKNOWN; 932 pcs->duplex = DUPLEX_UNKNOWN; 933 pcs->pause = 0; 934 pcs->asym_pause = 0; 935 936 switch (pcs->interface) { 937 case PHY_INTERFACE_MODE_SGMII: 938 case PHY_INTERFACE_MODE_QSGMII: 939 vsc9959_pcs_link_state_sgmii(pcs, state); 940 break; 941 case PHY_INTERFACE_MODE_2500BASEX: 942 vsc9959_pcs_link_state_2500basex(pcs, state); 943 break; 944 case PHY_INTERFACE_MODE_USXGMII: 945 vsc9959_pcs_link_state_usxgmii(pcs, state); 946 break; 947 default: 948 return; 949 } 950 951 vsc9959_pcs_link_state_resolve(pcs, state); 952 } 953 954 static int vsc9959_prevalidate_phy_mode(struct ocelot *ocelot, int port, 955 phy_interface_t phy_mode) 956 { 957 switch (phy_mode) { 958 case PHY_INTERFACE_MODE_GMII: 959 /* Only supported on internal to-CPU ports */ 960 if (port != 4 && port != 5) 961 return -ENOTSUPP; 962 return 0; 963 case PHY_INTERFACE_MODE_SGMII: 964 case PHY_INTERFACE_MODE_QSGMII: 965 case PHY_INTERFACE_MODE_USXGMII: 966 case PHY_INTERFACE_MODE_2500BASEX: 967 /* Not supported on internal to-CPU ports */ 968 if (port == 4 || port == 5) 969 return -ENOTSUPP; 970 return 0; 971 default: 972 return -ENOTSUPP; 973 } 974 } 975 976 static const struct ocelot_ops vsc9959_ops = { 977 .reset = vsc9959_reset, 978 }; 979 980 static int vsc9959_mdio_bus_alloc(struct ocelot *ocelot) 981 { 982 struct felix *felix = ocelot_to_felix(ocelot); 983 struct enetc_mdio_priv *mdio_priv; 984 struct device *dev = ocelot->dev; 985 resource_size_t imdio_base; 986 void __iomem *imdio_regs; 987 struct resource *res; 988 struct enetc_hw *hw; 989 struct mii_bus *bus; 990 int port; 991 int rc; 992 993 felix->pcs = devm_kcalloc(dev, felix->info->num_ports, 994 sizeof(struct phy_device *), 995 GFP_KERNEL); 996 if (!felix->pcs) { 997 dev_err(dev, "failed to allocate array for PCS PHYs\n"); 998 return -ENOMEM; 999 } 1000 1001 imdio_base = pci_resource_start(felix->pdev, 1002 felix->info->imdio_pci_bar); 1003 1004 res = felix->info->imdio_res; 1005 res->flags = IORESOURCE_MEM; 1006 res->start += imdio_base; 1007 res->end += imdio_base; 1008 1009 imdio_regs = devm_ioremap_resource(dev, res); 1010 if (IS_ERR(imdio_regs)) { 1011 dev_err(dev, "failed to map internal MDIO registers\n"); 1012 return PTR_ERR(imdio_regs); 1013 } 1014 1015 hw = enetc_hw_alloc(dev, imdio_regs); 1016 if (IS_ERR(hw)) { 1017 dev_err(dev, "failed to allocate ENETC HW structure\n"); 1018 return PTR_ERR(hw); 1019 } 1020 1021 bus = devm_mdiobus_alloc_size(dev, sizeof(*mdio_priv)); 1022 if (!bus) 1023 return -ENOMEM; 1024 1025 bus->name = "VSC9959 internal MDIO bus"; 1026 bus->read = enetc_mdio_read; 1027 bus->write = enetc_mdio_write; 1028 bus->parent = dev; 1029 mdio_priv = bus->priv; 1030 mdio_priv->hw = hw; 1031 /* This gets added to imdio_regs, which already maps addresses 1032 * starting with the proper offset. 1033 */ 1034 mdio_priv->mdio_base = 0; 1035 snprintf(bus->id, MII_BUS_ID_SIZE, "%s-imdio", dev_name(dev)); 1036 1037 /* Needed in order to initialize the bus mutex lock */ 1038 rc = mdiobus_register(bus); 1039 if (rc < 0) { 1040 dev_err(dev, "failed to register MDIO bus\n"); 1041 return rc; 1042 } 1043 1044 felix->imdio = bus; 1045 1046 for (port = 0; port < felix->info->num_ports; port++) { 1047 struct ocelot_port *ocelot_port = ocelot->ports[port]; 1048 struct phy_device *pcs; 1049 bool is_c45 = false; 1050 1051 if (ocelot_port->phy_mode == PHY_INTERFACE_MODE_USXGMII) 1052 is_c45 = true; 1053 1054 pcs = get_phy_device(felix->imdio, port, is_c45); 1055 if (IS_ERR(pcs)) 1056 continue; 1057 1058 pcs->interface = ocelot_port->phy_mode; 1059 felix->pcs[port] = pcs; 1060 1061 dev_info(dev, "Found PCS at internal MDIO address %d\n", port); 1062 } 1063 1064 return 0; 1065 } 1066 1067 static void vsc9959_mdio_bus_free(struct ocelot *ocelot) 1068 { 1069 struct felix *felix = ocelot_to_felix(ocelot); 1070 int port; 1071 1072 for (port = 0; port < ocelot->num_phys_ports; port++) { 1073 struct phy_device *pcs = felix->pcs[port]; 1074 1075 if (!pcs) 1076 continue; 1077 1078 put_device(&pcs->mdio.dev); 1079 } 1080 mdiobus_unregister(felix->imdio); 1081 } 1082 1083 struct felix_info felix_info_vsc9959 = { 1084 .target_io_res = vsc9959_target_io_res, 1085 .port_io_res = vsc9959_port_io_res, 1086 .imdio_res = &vsc9959_imdio_res, 1087 .regfields = vsc9959_regfields, 1088 .map = vsc9959_regmap, 1089 .ops = &vsc9959_ops, 1090 .stats_layout = vsc9959_stats_layout, 1091 .num_stats = ARRAY_SIZE(vsc9959_stats_layout), 1092 .shared_queue_sz = 128 * 1024, 1093 .num_ports = 6, 1094 .switch_pci_bar = 4, 1095 .imdio_pci_bar = 0, 1096 .mdio_bus_alloc = vsc9959_mdio_bus_alloc, 1097 .mdio_bus_free = vsc9959_mdio_bus_free, 1098 .pcs_init = vsc9959_pcs_init, 1099 .pcs_an_restart = vsc9959_pcs_an_restart, 1100 .pcs_link_state = vsc9959_pcs_link_state, 1101 .prevalidate_phy_mode = vsc9959_prevalidate_phy_mode, 1102 }; 1103