]> Git Repo - linux.git/blob - drivers/net/dsa/ocelot/felix_vsc9959.c
efi/x86: add headroom to decompressor BSS to account for setup block
[linux.git] / drivers / net / dsa / ocelot / felix_vsc9959.c
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 };
This page took 0.10023 seconds and 4 git commands to generate.