blob: 07355db2ad81ec4c1b37c6aee2f236c1c10f6556 [file] [log] [blame]
Juergen Beiserta1292592017-04-18 10:48:25 +02001/*
2 * Copyright (C) 2017 Pengutronix, Juergen Borleis <kernel@pengutronix.de>
3 *
4 * This program is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU General Public License
6 * version 2, as published by the Free Software Foundation.
7 *
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
12 *
13 */
14#include <linux/kernel.h>
15#include <linux/module.h>
16#include <linux/gpio/consumer.h>
17#include <linux/regmap.h>
18#include <linux/mutex.h>
19#include <linux/mii.h>
Egil Hjelmeland4d6a78b2017-09-19 10:09:24 +020020#include <linux/phy.h>
Juergen Beiserta1292592017-04-18 10:48:25 +020021
22#include "lan9303.h"
23
Egil Hjelmelanda368ca52017-08-05 13:05:47 +020024#define LAN9303_NUM_PORTS 3
25
Egil Hjelmelandab78acb2017-07-30 19:58:54 +020026/* 13.2 System Control and Status Registers
27 * Multiply register number by 4 to get address offset.
28 */
Juergen Beiserta1292592017-04-18 10:48:25 +020029#define LAN9303_CHIP_REV 0x14
30# define LAN9303_CHIP_ID 0x9303
31#define LAN9303_IRQ_CFG 0x15
32# define LAN9303_IRQ_CFG_IRQ_ENABLE BIT(8)
33# define LAN9303_IRQ_CFG_IRQ_POL BIT(4)
34# define LAN9303_IRQ_CFG_IRQ_TYPE BIT(0)
35#define LAN9303_INT_STS 0x16
36# define LAN9303_INT_STS_PHY_INT2 BIT(27)
37# define LAN9303_INT_STS_PHY_INT1 BIT(26)
38#define LAN9303_INT_EN 0x17
39# define LAN9303_INT_EN_PHY_INT2_EN BIT(27)
40# define LAN9303_INT_EN_PHY_INT1_EN BIT(26)
41#define LAN9303_HW_CFG 0x1D
42# define LAN9303_HW_CFG_READY BIT(27)
43# define LAN9303_HW_CFG_AMDX_EN_PORT2 BIT(26)
44# define LAN9303_HW_CFG_AMDX_EN_PORT1 BIT(25)
45#define LAN9303_PMI_DATA 0x29
46#define LAN9303_PMI_ACCESS 0x2A
47# define LAN9303_PMI_ACCESS_PHY_ADDR(x) (((x) & 0x1f) << 11)
48# define LAN9303_PMI_ACCESS_MIIRINDA(x) (((x) & 0x1f) << 6)
49# define LAN9303_PMI_ACCESS_MII_BUSY BIT(0)
50# define LAN9303_PMI_ACCESS_MII_WRITE BIT(1)
51#define LAN9303_MANUAL_FC_1 0x68
52#define LAN9303_MANUAL_FC_2 0x69
53#define LAN9303_MANUAL_FC_0 0x6a
54#define LAN9303_SWITCH_CSR_DATA 0x6b
55#define LAN9303_SWITCH_CSR_CMD 0x6c
56#define LAN9303_SWITCH_CSR_CMD_BUSY BIT(31)
57#define LAN9303_SWITCH_CSR_CMD_RW BIT(30)
58#define LAN9303_SWITCH_CSR_CMD_LANES (BIT(19) | BIT(18) | BIT(17) | BIT(16))
59#define LAN9303_VIRT_PHY_BASE 0x70
60#define LAN9303_VIRT_SPECIAL_CTRL 0x77
Egil Hjelmeland4d6a78b2017-09-19 10:09:24 +020061#define LAN9303_VIRT_SPECIAL_TURBO BIT(10) /*Turbo MII Enable*/
Juergen Beiserta1292592017-04-18 10:48:25 +020062
Egil Hjelmelandab78acb2017-07-30 19:58:54 +020063/*13.4 Switch Fabric Control and Status Registers
64 * Accessed indirectly via SWITCH_CSR_CMD, SWITCH_CSR_DATA.
65 */
Juergen Beiserta1292592017-04-18 10:48:25 +020066#define LAN9303_SW_DEV_ID 0x0000
67#define LAN9303_SW_RESET 0x0001
68#define LAN9303_SW_RESET_RESET BIT(0)
69#define LAN9303_SW_IMR 0x0004
70#define LAN9303_SW_IPR 0x0005
71#define LAN9303_MAC_VER_ID_0 0x0400
72#define LAN9303_MAC_RX_CFG_0 0x0401
73# define LAN9303_MAC_RX_CFG_X_REJECT_MAC_TYPES BIT(1)
74# define LAN9303_MAC_RX_CFG_X_RX_ENABLE BIT(0)
75#define LAN9303_MAC_RX_UNDSZE_CNT_0 0x0410
76#define LAN9303_MAC_RX_64_CNT_0 0x0411
77#define LAN9303_MAC_RX_127_CNT_0 0x0412
78#define LAN9303_MAC_RX_255_CNT_0 0x413
79#define LAN9303_MAC_RX_511_CNT_0 0x0414
80#define LAN9303_MAC_RX_1023_CNT_0 0x0415
81#define LAN9303_MAC_RX_MAX_CNT_0 0x0416
82#define LAN9303_MAC_RX_OVRSZE_CNT_0 0x0417
83#define LAN9303_MAC_RX_PKTOK_CNT_0 0x0418
84#define LAN9303_MAC_RX_CRCERR_CNT_0 0x0419
85#define LAN9303_MAC_RX_MULCST_CNT_0 0x041a
86#define LAN9303_MAC_RX_BRDCST_CNT_0 0x041b
87#define LAN9303_MAC_RX_PAUSE_CNT_0 0x041c
88#define LAN9303_MAC_RX_FRAG_CNT_0 0x041d
89#define LAN9303_MAC_RX_JABB_CNT_0 0x041e
90#define LAN9303_MAC_RX_ALIGN_CNT_0 0x041f
91#define LAN9303_MAC_RX_PKTLEN_CNT_0 0x0420
92#define LAN9303_MAC_RX_GOODPKTLEN_CNT_0 0x0421
93#define LAN9303_MAC_RX_SYMBL_CNT_0 0x0422
94#define LAN9303_MAC_RX_CTLFRM_CNT_0 0x0423
95
96#define LAN9303_MAC_TX_CFG_0 0x0440
97# define LAN9303_MAC_TX_CFG_X_TX_IFG_CONFIG_DEFAULT (21 << 2)
98# define LAN9303_MAC_TX_CFG_X_TX_PAD_ENABLE BIT(1)
99# define LAN9303_MAC_TX_CFG_X_TX_ENABLE BIT(0)
100#define LAN9303_MAC_TX_DEFER_CNT_0 0x0451
101#define LAN9303_MAC_TX_PAUSE_CNT_0 0x0452
102#define LAN9303_MAC_TX_PKTOK_CNT_0 0x0453
103#define LAN9303_MAC_TX_64_CNT_0 0x0454
104#define LAN9303_MAC_TX_127_CNT_0 0x0455
105#define LAN9303_MAC_TX_255_CNT_0 0x0456
106#define LAN9303_MAC_TX_511_CNT_0 0x0457
107#define LAN9303_MAC_TX_1023_CNT_0 0x0458
108#define LAN9303_MAC_TX_MAX_CNT_0 0x0459
109#define LAN9303_MAC_TX_UNDSZE_CNT_0 0x045a
110#define LAN9303_MAC_TX_PKTLEN_CNT_0 0x045c
111#define LAN9303_MAC_TX_BRDCST_CNT_0 0x045d
112#define LAN9303_MAC_TX_MULCST_CNT_0 0x045e
113#define LAN9303_MAC_TX_LATECOL_0 0x045f
114#define LAN9303_MAC_TX_EXCOL_CNT_0 0x0460
115#define LAN9303_MAC_TX_SNGLECOL_CNT_0 0x0461
116#define LAN9303_MAC_TX_MULTICOL_CNT_0 0x0462
117#define LAN9303_MAC_TX_TOTALCOL_CNT_0 0x0463
118
119#define LAN9303_MAC_VER_ID_1 0x0800
120#define LAN9303_MAC_RX_CFG_1 0x0801
121#define LAN9303_MAC_TX_CFG_1 0x0840
122#define LAN9303_MAC_VER_ID_2 0x0c00
123#define LAN9303_MAC_RX_CFG_2 0x0c01
124#define LAN9303_MAC_TX_CFG_2 0x0c40
125#define LAN9303_SWE_ALR_CMD 0x1800
126#define LAN9303_SWE_VLAN_CMD 0x180b
127# define LAN9303_SWE_VLAN_CMD_RNW BIT(5)
128# define LAN9303_SWE_VLAN_CMD_PVIDNVLAN BIT(4)
129#define LAN9303_SWE_VLAN_WR_DATA 0x180c
130#define LAN9303_SWE_VLAN_RD_DATA 0x180e
131# define LAN9303_SWE_VLAN_MEMBER_PORT2 BIT(17)
132# define LAN9303_SWE_VLAN_UNTAG_PORT2 BIT(16)
133# define LAN9303_SWE_VLAN_MEMBER_PORT1 BIT(15)
134# define LAN9303_SWE_VLAN_UNTAG_PORT1 BIT(14)
135# define LAN9303_SWE_VLAN_MEMBER_PORT0 BIT(13)
136# define LAN9303_SWE_VLAN_UNTAG_PORT0 BIT(12)
137#define LAN9303_SWE_VLAN_CMD_STS 0x1810
138#define LAN9303_SWE_GLB_INGRESS_CFG 0x1840
139#define LAN9303_SWE_PORT_STATE 0x1843
140# define LAN9303_SWE_PORT_STATE_FORWARDING_PORT2 (0)
141# define LAN9303_SWE_PORT_STATE_LEARNING_PORT2 BIT(5)
142# define LAN9303_SWE_PORT_STATE_BLOCKING_PORT2 BIT(4)
143# define LAN9303_SWE_PORT_STATE_FORWARDING_PORT1 (0)
144# define LAN9303_SWE_PORT_STATE_LEARNING_PORT1 BIT(3)
145# define LAN9303_SWE_PORT_STATE_BLOCKING_PORT1 BIT(2)
146# define LAN9303_SWE_PORT_STATE_FORWARDING_PORT0 (0)
147# define LAN9303_SWE_PORT_STATE_LEARNING_PORT0 BIT(1)
148# define LAN9303_SWE_PORT_STATE_BLOCKING_PORT0 BIT(0)
149#define LAN9303_SWE_PORT_MIRROR 0x1846
150# define LAN9303_SWE_PORT_MIRROR_SNIFF_ALL BIT(8)
151# define LAN9303_SWE_PORT_MIRROR_SNIFFER_PORT2 BIT(7)
152# define LAN9303_SWE_PORT_MIRROR_SNIFFER_PORT1 BIT(6)
153# define LAN9303_SWE_PORT_MIRROR_SNIFFER_PORT0 BIT(5)
154# define LAN9303_SWE_PORT_MIRROR_MIRRORED_PORT2 BIT(4)
155# define LAN9303_SWE_PORT_MIRROR_MIRRORED_PORT1 BIT(3)
156# define LAN9303_SWE_PORT_MIRROR_MIRRORED_PORT0 BIT(2)
157# define LAN9303_SWE_PORT_MIRROR_ENABLE_RX_MIRRORING BIT(1)
158# define LAN9303_SWE_PORT_MIRROR_ENABLE_TX_MIRRORING BIT(0)
159#define LAN9303_SWE_INGRESS_PORT_TYPE 0x1847
160#define LAN9303_BM_CFG 0x1c00
161#define LAN9303_BM_EGRSS_PORT_TYPE 0x1c0c
162# define LAN9303_BM_EGRSS_PORT_TYPE_SPECIAL_TAG_PORT2 (BIT(17) | BIT(16))
163# define LAN9303_BM_EGRSS_PORT_TYPE_SPECIAL_TAG_PORT1 (BIT(9) | BIT(8))
164# define LAN9303_BM_EGRSS_PORT_TYPE_SPECIAL_TAG_PORT0 (BIT(1) | BIT(0))
165
Egil Hjelmeland451d3ca2017-08-05 13:05:46 +0200166#define LAN9303_SWITCH_PORT_REG(port, reg0) (0x400 * (port) + (reg0))
Juergen Beiserta1292592017-04-18 10:48:25 +0200167
168/* the built-in PHYs are of type LAN911X */
169#define MII_LAN911X_SPECIAL_MODES 0x12
170#define MII_LAN911X_SPECIAL_CONTROL_STATUS 0x1f
171
172static const struct regmap_range lan9303_valid_regs[] = {
173 regmap_reg_range(0x14, 0x17), /* misc, interrupt */
174 regmap_reg_range(0x19, 0x19), /* endian test */
175 regmap_reg_range(0x1d, 0x1d), /* hardware config */
176 regmap_reg_range(0x23, 0x24), /* general purpose timer */
177 regmap_reg_range(0x27, 0x27), /* counter */
178 regmap_reg_range(0x29, 0x2a), /* PMI index regs */
179 regmap_reg_range(0x68, 0x6a), /* flow control */
180 regmap_reg_range(0x6b, 0x6c), /* switch fabric indirect regs */
181 regmap_reg_range(0x6d, 0x6f), /* misc */
182 regmap_reg_range(0x70, 0x77), /* virtual phy */
183 regmap_reg_range(0x78, 0x7a), /* GPIO */
184 regmap_reg_range(0x7c, 0x7e), /* MAC & reset */
185 regmap_reg_range(0x80, 0xb7), /* switch fabric direct regs (wr only) */
186};
187
188static const struct regmap_range lan9303_reserved_ranges[] = {
189 regmap_reg_range(0x00, 0x13),
190 regmap_reg_range(0x18, 0x18),
191 regmap_reg_range(0x1a, 0x1c),
192 regmap_reg_range(0x1e, 0x22),
193 regmap_reg_range(0x25, 0x26),
194 regmap_reg_range(0x28, 0x28),
195 regmap_reg_range(0x2b, 0x67),
196 regmap_reg_range(0x7b, 0x7b),
197 regmap_reg_range(0x7f, 0x7f),
198 regmap_reg_range(0xb8, 0xff),
199};
200
201const struct regmap_access_table lan9303_register_set = {
202 .yes_ranges = lan9303_valid_regs,
203 .n_yes_ranges = ARRAY_SIZE(lan9303_valid_regs),
204 .no_ranges = lan9303_reserved_ranges,
205 .n_no_ranges = ARRAY_SIZE(lan9303_reserved_ranges),
206};
207EXPORT_SYMBOL(lan9303_register_set);
208
209static int lan9303_read(struct regmap *regmap, unsigned int offset, u32 *reg)
210{
211 int ret, i;
212
213 /* we can lose arbitration for the I2C case, because the device
214 * tries to detect and read an external EEPROM after reset and acts as
215 * a master on the shared I2C bus itself. This conflicts with our
216 * attempts to access the device as a slave at the same moment.
217 */
218 for (i = 0; i < 5; i++) {
219 ret = regmap_read(regmap, offset, reg);
220 if (!ret)
221 return 0;
222 if (ret != -EAGAIN)
223 break;
224 msleep(500);
225 }
226
227 return -EIO;
228}
229
230static int lan9303_virt_phy_reg_read(struct lan9303 *chip, int regnum)
231{
232 int ret;
233 u32 val;
234
235 if (regnum > MII_EXPANSION)
236 return -EINVAL;
237
238 ret = lan9303_read(chip->regmap, LAN9303_VIRT_PHY_BASE + regnum, &val);
239 if (ret)
240 return ret;
241
242 return val & 0xffff;
243}
244
245static int lan9303_virt_phy_reg_write(struct lan9303 *chip, int regnum, u16 val)
246{
247 if (regnum > MII_EXPANSION)
248 return -EINVAL;
249
250 return regmap_write(chip->regmap, LAN9303_VIRT_PHY_BASE + regnum, val);
251}
252
Egil Hjelmeland9e866e52017-07-30 19:58:55 +0200253static int lan9303_indirect_phy_wait_for_completion(struct lan9303 *chip)
Juergen Beiserta1292592017-04-18 10:48:25 +0200254{
255 int ret, i;
256 u32 reg;
257
258 for (i = 0; i < 25; i++) {
259 ret = lan9303_read(chip->regmap, LAN9303_PMI_ACCESS, &reg);
260 if (ret) {
261 dev_err(chip->dev,
262 "Failed to read pmi access status: %d\n", ret);
263 return ret;
264 }
265 if (!(reg & LAN9303_PMI_ACCESS_MII_BUSY))
266 return 0;
267 msleep(1);
268 }
269
270 return -EIO;
271}
272
Egil Hjelmeland9e866e52017-07-30 19:58:55 +0200273static int lan9303_indirect_phy_read(struct lan9303 *chip, int addr, int regnum)
Juergen Beiserta1292592017-04-18 10:48:25 +0200274{
275 int ret;
276 u32 val;
277
278 val = LAN9303_PMI_ACCESS_PHY_ADDR(addr);
279 val |= LAN9303_PMI_ACCESS_MIIRINDA(regnum);
280
281 mutex_lock(&chip->indirect_mutex);
282
Egil Hjelmeland9e866e52017-07-30 19:58:55 +0200283 ret = lan9303_indirect_phy_wait_for_completion(chip);
Juergen Beiserta1292592017-04-18 10:48:25 +0200284 if (ret)
285 goto on_error;
286
287 /* start the MII read cycle */
288 ret = regmap_write(chip->regmap, LAN9303_PMI_ACCESS, val);
289 if (ret)
290 goto on_error;
291
Egil Hjelmeland9e866e52017-07-30 19:58:55 +0200292 ret = lan9303_indirect_phy_wait_for_completion(chip);
Juergen Beiserta1292592017-04-18 10:48:25 +0200293 if (ret)
294 goto on_error;
295
296 /* read the result of this operation */
297 ret = lan9303_read(chip->regmap, LAN9303_PMI_DATA, &val);
298 if (ret)
299 goto on_error;
300
301 mutex_unlock(&chip->indirect_mutex);
302
303 return val & 0xffff;
304
305on_error:
306 mutex_unlock(&chip->indirect_mutex);
307 return ret;
308}
309
Egil Hjelmeland9e866e52017-07-30 19:58:55 +0200310static int lan9303_indirect_phy_write(struct lan9303 *chip, int addr,
311 int regnum, u16 val)
Juergen Beiserta1292592017-04-18 10:48:25 +0200312{
313 int ret;
314 u32 reg;
315
316 reg = LAN9303_PMI_ACCESS_PHY_ADDR(addr);
317 reg |= LAN9303_PMI_ACCESS_MIIRINDA(regnum);
318 reg |= LAN9303_PMI_ACCESS_MII_WRITE;
319
320 mutex_lock(&chip->indirect_mutex);
321
Egil Hjelmeland9e866e52017-07-30 19:58:55 +0200322 ret = lan9303_indirect_phy_wait_for_completion(chip);
Juergen Beiserta1292592017-04-18 10:48:25 +0200323 if (ret)
324 goto on_error;
325
326 /* write the data first... */
327 ret = regmap_write(chip->regmap, LAN9303_PMI_DATA, val);
328 if (ret)
329 goto on_error;
330
331 /* ...then start the MII write cycle */
332 ret = regmap_write(chip->regmap, LAN9303_PMI_ACCESS, reg);
333
334on_error:
335 mutex_unlock(&chip->indirect_mutex);
336 return ret;
337}
338
Egil Hjelmeland2c340892017-07-30 19:58:56 +0200339const struct lan9303_phy_ops lan9303_indirect_phy_ops = {
340 .phy_read = lan9303_indirect_phy_read,
341 .phy_write = lan9303_indirect_phy_write,
342};
343EXPORT_SYMBOL_GPL(lan9303_indirect_phy_ops);
344
Juergen Beiserta1292592017-04-18 10:48:25 +0200345static int lan9303_switch_wait_for_completion(struct lan9303 *chip)
346{
347 int ret, i;
348 u32 reg;
349
350 for (i = 0; i < 25; i++) {
351 ret = lan9303_read(chip->regmap, LAN9303_SWITCH_CSR_CMD, &reg);
352 if (ret) {
353 dev_err(chip->dev,
354 "Failed to read csr command status: %d\n", ret);
355 return ret;
356 }
357 if (!(reg & LAN9303_SWITCH_CSR_CMD_BUSY))
358 return 0;
359 msleep(1);
360 }
361
362 return -EIO;
363}
364
365static int lan9303_write_switch_reg(struct lan9303 *chip, u16 regnum, u32 val)
366{
367 u32 reg;
368 int ret;
369
370 reg = regnum;
371 reg |= LAN9303_SWITCH_CSR_CMD_LANES;
372 reg |= LAN9303_SWITCH_CSR_CMD_BUSY;
373
374 mutex_lock(&chip->indirect_mutex);
375
376 ret = lan9303_switch_wait_for_completion(chip);
377 if (ret)
378 goto on_error;
379
380 ret = regmap_write(chip->regmap, LAN9303_SWITCH_CSR_DATA, val);
381 if (ret) {
382 dev_err(chip->dev, "Failed to write csr data reg: %d\n", ret);
383 goto on_error;
384 }
385
386 /* trigger write */
387 ret = regmap_write(chip->regmap, LAN9303_SWITCH_CSR_CMD, reg);
388 if (ret)
389 dev_err(chip->dev, "Failed to write csr command reg: %d\n",
390 ret);
391
392on_error:
393 mutex_unlock(&chip->indirect_mutex);
394 return ret;
395}
396
397static int lan9303_read_switch_reg(struct lan9303 *chip, u16 regnum, u32 *val)
398{
399 u32 reg;
400 int ret;
401
402 reg = regnum;
403 reg |= LAN9303_SWITCH_CSR_CMD_LANES;
404 reg |= LAN9303_SWITCH_CSR_CMD_RW;
405 reg |= LAN9303_SWITCH_CSR_CMD_BUSY;
406
407 mutex_lock(&chip->indirect_mutex);
408
409 ret = lan9303_switch_wait_for_completion(chip);
410 if (ret)
411 goto on_error;
412
413 /* trigger read */
414 ret = regmap_write(chip->regmap, LAN9303_SWITCH_CSR_CMD, reg);
415 if (ret) {
416 dev_err(chip->dev, "Failed to write csr command reg: %d\n",
417 ret);
418 goto on_error;
419 }
420
421 ret = lan9303_switch_wait_for_completion(chip);
422 if (ret)
423 goto on_error;
424
425 ret = lan9303_read(chip->regmap, LAN9303_SWITCH_CSR_DATA, val);
426 if (ret)
427 dev_err(chip->dev, "Failed to read csr data reg: %d\n", ret);
428on_error:
429 mutex_unlock(&chip->indirect_mutex);
430 return ret;
431}
432
Egil Hjelmeland451d3ca2017-08-05 13:05:46 +0200433static int lan9303_write_switch_port(struct lan9303 *chip, int port,
434 u16 regnum, u32 val)
435{
436 return lan9303_write_switch_reg(
437 chip, LAN9303_SWITCH_PORT_REG(port, regnum), val);
438}
439
Egil Hjelmeland0a967b42017-08-05 13:05:50 +0200440static int lan9303_read_switch_port(struct lan9303 *chip, int port,
441 u16 regnum, u32 *val)
442{
443 return lan9303_read_switch_reg(
444 chip, LAN9303_SWITCH_PORT_REG(port, regnum), val);
445}
446
Juergen Beiserta1292592017-04-18 10:48:25 +0200447static int lan9303_detect_phy_setup(struct lan9303 *chip)
448{
449 int reg;
450
451 /* depending on the 'phy_addr_sel_strap' setting, the three phys are
452 * using IDs 0-1-2 or IDs 1-2-3. We cannot read back the
453 * 'phy_addr_sel_strap' setting directly, so we need a test, which
454 * configuration is active:
455 * Special reg 18 of phy 3 reads as 0x0000, if 'phy_addr_sel_strap' is 0
456 * and the IDs are 0-1-2, else it contains something different from
457 * 0x0000, which means 'phy_addr_sel_strap' is 1 and the IDs are 1-2-3.
Egil Hjelmelandd329ac82017-07-30 19:58:53 +0200458 * 0xffff is returned on MDIO read with no response.
Juergen Beiserta1292592017-04-18 10:48:25 +0200459 */
Egil Hjelmeland2c340892017-07-30 19:58:56 +0200460 reg = chip->ops->phy_read(chip, 3, MII_LAN911X_SPECIAL_MODES);
Juergen Beiserta1292592017-04-18 10:48:25 +0200461 if (reg < 0) {
462 dev_err(chip->dev, "Failed to detect phy config: %d\n", reg);
463 return reg;
464 }
465
Egil Hjelmelandd329ac82017-07-30 19:58:53 +0200466 if ((reg != 0) && (reg != 0xffff))
Juergen Beiserta1292592017-04-18 10:48:25 +0200467 chip->phy_addr_sel_strap = 1;
468 else
469 chip->phy_addr_sel_strap = 0;
470
471 dev_dbg(chip->dev, "Phy setup '%s' detected\n",
472 chip->phy_addr_sel_strap ? "1-2-3" : "0-1-2");
473
474 return 0;
475}
476
Egil Hjelmeland9c842582017-08-05 13:05:49 +0200477static int lan9303_disable_processing_port(struct lan9303 *chip,
478 unsigned int port)
Juergen Beiserta1292592017-04-18 10:48:25 +0200479{
480 int ret;
481
482 /* disable RX, but keep register reset default values else */
Egil Hjelmeland451d3ca2017-08-05 13:05:46 +0200483 ret = lan9303_write_switch_port(chip, port, LAN9303_MAC_RX_CFG_0,
484 LAN9303_MAC_RX_CFG_X_REJECT_MAC_TYPES);
Juergen Beiserta1292592017-04-18 10:48:25 +0200485 if (ret)
486 return ret;
487
488 /* disable TX, but keep register reset default values else */
Egil Hjelmeland451d3ca2017-08-05 13:05:46 +0200489 return lan9303_write_switch_port(chip, port, LAN9303_MAC_TX_CFG_0,
Juergen Beiserta1292592017-04-18 10:48:25 +0200490 LAN9303_MAC_TX_CFG_X_TX_IFG_CONFIG_DEFAULT |
491 LAN9303_MAC_TX_CFG_X_TX_PAD_ENABLE);
492}
493
Egil Hjelmeland9c842582017-08-05 13:05:49 +0200494static int lan9303_enable_processing_port(struct lan9303 *chip,
495 unsigned int port)
Juergen Beiserta1292592017-04-18 10:48:25 +0200496{
497 int ret;
498
499 /* enable RX and keep register reset default values else */
Egil Hjelmeland451d3ca2017-08-05 13:05:46 +0200500 ret = lan9303_write_switch_port(chip, port, LAN9303_MAC_RX_CFG_0,
501 LAN9303_MAC_RX_CFG_X_REJECT_MAC_TYPES |
502 LAN9303_MAC_RX_CFG_X_RX_ENABLE);
Juergen Beiserta1292592017-04-18 10:48:25 +0200503 if (ret)
504 return ret;
505
506 /* enable TX and keep register reset default values else */
Egil Hjelmeland451d3ca2017-08-05 13:05:46 +0200507 return lan9303_write_switch_port(chip, port, LAN9303_MAC_TX_CFG_0,
Juergen Beiserta1292592017-04-18 10:48:25 +0200508 LAN9303_MAC_TX_CFG_X_TX_IFG_CONFIG_DEFAULT |
509 LAN9303_MAC_TX_CFG_X_TX_PAD_ENABLE |
510 LAN9303_MAC_TX_CFG_X_TX_ENABLE);
511}
512
513/* We want a special working switch:
514 * - do not forward packets between port 1 and 2
515 * - forward everything from port 1 to port 0
516 * - forward everything from port 2 to port 0
517 * - forward special tagged packets from port 0 to port 1 *or* port 2
518 */
519static int lan9303_separate_ports(struct lan9303 *chip)
520{
521 int ret;
522
523 ret = lan9303_write_switch_reg(chip, LAN9303_SWE_PORT_MIRROR,
524 LAN9303_SWE_PORT_MIRROR_SNIFFER_PORT0 |
525 LAN9303_SWE_PORT_MIRROR_MIRRORED_PORT1 |
526 LAN9303_SWE_PORT_MIRROR_MIRRORED_PORT2 |
527 LAN9303_SWE_PORT_MIRROR_ENABLE_RX_MIRRORING |
528 LAN9303_SWE_PORT_MIRROR_SNIFF_ALL);
529 if (ret)
530 return ret;
531
532 /* enable defining the destination port via special VLAN tagging
533 * for port 0
534 */
535 ret = lan9303_write_switch_reg(chip, LAN9303_SWE_INGRESS_PORT_TYPE,
536 0x03);
537 if (ret)
538 return ret;
539
540 /* tag incoming packets at port 1 and 2 on their way to port 0 to be
541 * able to discover their source port
542 */
543 ret = lan9303_write_switch_reg(chip, LAN9303_BM_EGRSS_PORT_TYPE,
544 LAN9303_BM_EGRSS_PORT_TYPE_SPECIAL_TAG_PORT0);
545 if (ret)
546 return ret;
547
548 /* prevent port 1 and 2 from forwarding packets by their own */
549 return lan9303_write_switch_reg(chip, LAN9303_SWE_PORT_STATE,
550 LAN9303_SWE_PORT_STATE_FORWARDING_PORT0 |
551 LAN9303_SWE_PORT_STATE_BLOCKING_PORT1 |
552 LAN9303_SWE_PORT_STATE_BLOCKING_PORT2);
553}
554
555static int lan9303_handle_reset(struct lan9303 *chip)
556{
557 if (!chip->reset_gpio)
558 return 0;
559
560 if (chip->reset_duration != 0)
561 msleep(chip->reset_duration);
562
563 /* release (deassert) reset and activate the device */
564 gpiod_set_value_cansleep(chip->reset_gpio, 0);
565
566 return 0;
567}
568
569/* stop processing packets for all ports */
570static int lan9303_disable_processing(struct lan9303 *chip)
571{
Egil Hjelmelandb3d14a22017-08-05 13:05:48 +0200572 int p;
Juergen Beiserta1292592017-04-18 10:48:25 +0200573
Egil Hjelmelandb3d14a22017-08-05 13:05:48 +0200574 for (p = 0; p < LAN9303_NUM_PORTS; p++) {
Egil Hjelmeland9c842582017-08-05 13:05:49 +0200575 int ret = lan9303_disable_processing_port(chip, p);
Egil Hjelmelandb3d14a22017-08-05 13:05:48 +0200576
577 if (ret)
578 return ret;
579 }
580
581 return 0;
Juergen Beiserta1292592017-04-18 10:48:25 +0200582}
583
584static int lan9303_check_device(struct lan9303 *chip)
585{
586 int ret;
587 u32 reg;
588
589 ret = lan9303_read(chip->regmap, LAN9303_CHIP_REV, &reg);
590 if (ret) {
591 dev_err(chip->dev, "failed to read chip revision register: %d\n",
592 ret);
593 if (!chip->reset_gpio) {
594 dev_dbg(chip->dev,
595 "hint: maybe failed due to missing reset GPIO\n");
596 }
597 return ret;
598 }
599
600 if ((reg >> 16) != LAN9303_CHIP_ID) {
601 dev_err(chip->dev, "expecting LAN9303 chip, but found: %X\n",
602 reg >> 16);
603 return ret;
604 }
605
606 /* The default state of the LAN9303 device is to forward packets between
607 * all ports (if not configured differently by an external EEPROM).
608 * The initial state of a DSA device must be forwarding packets only
609 * between the external and the internal ports and no forwarding
610 * between the external ports. In preparation we stop packet handling
611 * at all for now until the LAN9303 device is re-programmed accordingly.
612 */
613 ret = lan9303_disable_processing(chip);
614 if (ret)
615 dev_warn(chip->dev, "failed to disable switching %d\n", ret);
616
617 dev_info(chip->dev, "Found LAN9303 rev. %u\n", reg & 0xffff);
618
619 ret = lan9303_detect_phy_setup(chip);
620 if (ret) {
621 dev_err(chip->dev,
622 "failed to discover phy bootstrap setup: %d\n", ret);
623 return ret;
624 }
625
626 return 0;
627}
628
629/* ---------------------------- DSA -----------------------------------*/
630
631static enum dsa_tag_protocol lan9303_get_tag_protocol(struct dsa_switch *ds)
632{
633 return DSA_TAG_PROTO_LAN9303;
634}
635
636static int lan9303_setup(struct dsa_switch *ds)
637{
638 struct lan9303 *chip = ds->priv;
639 int ret;
640
641 /* Make sure that port 0 is the cpu port */
642 if (!dsa_is_cpu_port(ds, 0)) {
643 dev_err(chip->dev, "port 0 is not the CPU port\n");
644 return -EINVAL;
645 }
646
647 ret = lan9303_separate_ports(chip);
648 if (ret)
649 dev_err(chip->dev, "failed to separate ports %d\n", ret);
650
Egil Hjelmeland9c842582017-08-05 13:05:49 +0200651 ret = lan9303_enable_processing_port(chip, 0);
Juergen Beiserta1292592017-04-18 10:48:25 +0200652 if (ret)
653 dev_err(chip->dev, "failed to re-enable switching %d\n", ret);
654
655 return 0;
656}
657
658struct lan9303_mib_desc {
659 unsigned int offset; /* offset of first MAC */
660 const char *name;
661};
662
663static const struct lan9303_mib_desc lan9303_mib[] = {
664 { .offset = LAN9303_MAC_RX_BRDCST_CNT_0, .name = "RxBroad", },
665 { .offset = LAN9303_MAC_RX_PAUSE_CNT_0, .name = "RxPause", },
666 { .offset = LAN9303_MAC_RX_MULCST_CNT_0, .name = "RxMulti", },
667 { .offset = LAN9303_MAC_RX_PKTOK_CNT_0, .name = "RxOk", },
668 { .offset = LAN9303_MAC_RX_CRCERR_CNT_0, .name = "RxCrcErr", },
669 { .offset = LAN9303_MAC_RX_ALIGN_CNT_0, .name = "RxAlignErr", },
670 { .offset = LAN9303_MAC_RX_JABB_CNT_0, .name = "RxJabber", },
671 { .offset = LAN9303_MAC_RX_FRAG_CNT_0, .name = "RxFragment", },
672 { .offset = LAN9303_MAC_RX_64_CNT_0, .name = "Rx64Byte", },
673 { .offset = LAN9303_MAC_RX_127_CNT_0, .name = "Rx128Byte", },
674 { .offset = LAN9303_MAC_RX_255_CNT_0, .name = "Rx256Byte", },
675 { .offset = LAN9303_MAC_RX_511_CNT_0, .name = "Rx512Byte", },
676 { .offset = LAN9303_MAC_RX_1023_CNT_0, .name = "Rx1024Byte", },
677 { .offset = LAN9303_MAC_RX_MAX_CNT_0, .name = "RxMaxByte", },
678 { .offset = LAN9303_MAC_RX_PKTLEN_CNT_0, .name = "RxByteCnt", },
679 { .offset = LAN9303_MAC_RX_SYMBL_CNT_0, .name = "RxSymbolCnt", },
680 { .offset = LAN9303_MAC_RX_CTLFRM_CNT_0, .name = "RxCfs", },
681 { .offset = LAN9303_MAC_RX_OVRSZE_CNT_0, .name = "RxOverFlow", },
682 { .offset = LAN9303_MAC_TX_UNDSZE_CNT_0, .name = "TxShort", },
683 { .offset = LAN9303_MAC_TX_BRDCST_CNT_0, .name = "TxBroad", },
684 { .offset = LAN9303_MAC_TX_PAUSE_CNT_0, .name = "TxPause", },
685 { .offset = LAN9303_MAC_TX_MULCST_CNT_0, .name = "TxMulti", },
686 { .offset = LAN9303_MAC_RX_UNDSZE_CNT_0, .name = "TxUnderRun", },
687 { .offset = LAN9303_MAC_TX_64_CNT_0, .name = "Tx64Byte", },
688 { .offset = LAN9303_MAC_TX_127_CNT_0, .name = "Tx128Byte", },
689 { .offset = LAN9303_MAC_TX_255_CNT_0, .name = "Tx256Byte", },
690 { .offset = LAN9303_MAC_TX_511_CNT_0, .name = "Tx512Byte", },
691 { .offset = LAN9303_MAC_TX_1023_CNT_0, .name = "Tx1024Byte", },
692 { .offset = LAN9303_MAC_TX_MAX_CNT_0, .name = "TxMaxByte", },
693 { .offset = LAN9303_MAC_TX_PKTLEN_CNT_0, .name = "TxByteCnt", },
694 { .offset = LAN9303_MAC_TX_PKTOK_CNT_0, .name = "TxOk", },
695 { .offset = LAN9303_MAC_TX_TOTALCOL_CNT_0, .name = "TxCollision", },
696 { .offset = LAN9303_MAC_TX_MULTICOL_CNT_0, .name = "TxMultiCol", },
697 { .offset = LAN9303_MAC_TX_SNGLECOL_CNT_0, .name = "TxSingleCol", },
698 { .offset = LAN9303_MAC_TX_EXCOL_CNT_0, .name = "TxExcCol", },
699 { .offset = LAN9303_MAC_TX_DEFER_CNT_0, .name = "TxDefer", },
700 { .offset = LAN9303_MAC_TX_LATECOL_0, .name = "TxLateCol", },
701};
702
703static void lan9303_get_strings(struct dsa_switch *ds, int port, uint8_t *data)
704{
705 unsigned int u;
706
707 for (u = 0; u < ARRAY_SIZE(lan9303_mib); u++) {
708 strncpy(data + u * ETH_GSTRING_LEN, lan9303_mib[u].name,
709 ETH_GSTRING_LEN);
710 }
711}
712
713static void lan9303_get_ethtool_stats(struct dsa_switch *ds, int port,
714 uint64_t *data)
715{
716 struct lan9303 *chip = ds->priv;
Egil Hjelmeland0a967b42017-08-05 13:05:50 +0200717 unsigned int u;
Juergen Beiserta1292592017-04-18 10:48:25 +0200718
719 for (u = 0; u < ARRAY_SIZE(lan9303_mib); u++) {
Egil Hjelmeland0a967b42017-08-05 13:05:50 +0200720 u32 reg;
721 int ret;
722
723 ret = lan9303_read_switch_port(
724 chip, port, lan9303_mib[u].offset, &reg);
725
Juergen Beiserta1292592017-04-18 10:48:25 +0200726 if (ret)
Egil Hjelmeland0a967b42017-08-05 13:05:50 +0200727 dev_warn(chip->dev, "Reading status port %d reg %u failed\n",
728 port, lan9303_mib[u].offset);
Juergen Beiserta1292592017-04-18 10:48:25 +0200729 data[u] = reg;
730 }
731}
732
733static int lan9303_get_sset_count(struct dsa_switch *ds)
734{
735 return ARRAY_SIZE(lan9303_mib);
736}
737
738static int lan9303_phy_read(struct dsa_switch *ds, int phy, int regnum)
739{
740 struct lan9303 *chip = ds->priv;
741 int phy_base = chip->phy_addr_sel_strap;
742
743 if (phy == phy_base)
744 return lan9303_virt_phy_reg_read(chip, regnum);
745 if (phy > phy_base + 2)
746 return -ENODEV;
747
Egil Hjelmeland2c340892017-07-30 19:58:56 +0200748 return chip->ops->phy_read(chip, phy, regnum);
Juergen Beiserta1292592017-04-18 10:48:25 +0200749}
750
751static int lan9303_phy_write(struct dsa_switch *ds, int phy, int regnum,
752 u16 val)
753{
754 struct lan9303 *chip = ds->priv;
755 int phy_base = chip->phy_addr_sel_strap;
756
757 if (phy == phy_base)
758 return lan9303_virt_phy_reg_write(chip, regnum, val);
759 if (phy > phy_base + 2)
760 return -ENODEV;
761
Egil Hjelmeland2c340892017-07-30 19:58:56 +0200762 return chip->ops->phy_write(chip, phy, regnum, val);
Juergen Beiserta1292592017-04-18 10:48:25 +0200763}
764
Egil Hjelmeland4d6a78b2017-09-19 10:09:24 +0200765static void lan9303_adjust_link(struct dsa_switch *ds, int port,
766 struct phy_device *phydev)
767{
768 struct lan9303 *chip = ds->priv;
769 int ctl, res;
770
771 if (!phy_is_pseudo_fixed_link(phydev))
772 return;
773
774 ctl = lan9303_phy_read(ds, port, MII_BMCR);
775
776 ctl &= ~BMCR_ANENABLE;
777
778 if (phydev->speed == SPEED_100)
779 ctl |= BMCR_SPEED100;
780 else if (phydev->speed == SPEED_10)
781 ctl &= ~BMCR_SPEED100;
782 else
783 dev_err(ds->dev, "unsupported speed: %d\n", phydev->speed);
784
785 if (phydev->duplex == DUPLEX_FULL)
786 ctl |= BMCR_FULLDPLX;
787 else
788 ctl &= ~BMCR_FULLDPLX;
789
790 res = lan9303_phy_write(ds, port, MII_BMCR, ctl);
791
792 if (port == chip->phy_addr_sel_strap) {
793 /* Virtual Phy: Remove Turbo 200Mbit mode */
794 lan9303_read(chip->regmap, LAN9303_VIRT_SPECIAL_CTRL, &ctl);
795
796 ctl &= ~LAN9303_VIRT_SPECIAL_TURBO;
797 res = regmap_write(chip->regmap,
798 LAN9303_VIRT_SPECIAL_CTRL, ctl);
799 }
800}
801
Juergen Beiserta1292592017-04-18 10:48:25 +0200802static int lan9303_port_enable(struct dsa_switch *ds, int port,
803 struct phy_device *phy)
804{
805 struct lan9303 *chip = ds->priv;
806
807 /* enable internal packet processing */
808 switch (port) {
809 case 1:
Juergen Beiserta1292592017-04-18 10:48:25 +0200810 case 2:
Egil Hjelmeland9c842582017-08-05 13:05:49 +0200811 return lan9303_enable_processing_port(chip, port);
Juergen Beiserta1292592017-04-18 10:48:25 +0200812 default:
813 dev_dbg(chip->dev,
814 "Error: request to power up invalid port %d\n", port);
815 }
816
817 return -ENODEV;
818}
819
820static void lan9303_port_disable(struct dsa_switch *ds, int port,
821 struct phy_device *phy)
822{
823 struct lan9303 *chip = ds->priv;
824
825 /* disable internal packet processing */
826 switch (port) {
827 case 1:
Juergen Beiserta1292592017-04-18 10:48:25 +0200828 case 2:
Egil Hjelmeland9c842582017-08-05 13:05:49 +0200829 lan9303_disable_processing_port(chip, port);
Egil Hjelmelandb3d14a22017-08-05 13:05:48 +0200830 lan9303_phy_write(ds, chip->phy_addr_sel_strap + port,
Egil Hjelmeland2c340892017-07-30 19:58:56 +0200831 MII_BMCR, BMCR_PDOWN);
Juergen Beiserta1292592017-04-18 10:48:25 +0200832 break;
833 default:
834 dev_dbg(chip->dev,
835 "Error: request to power down invalid port %d\n", port);
836 }
837}
838
Bhumika Goyald78d6772017-08-09 10:34:15 +0530839static const struct dsa_switch_ops lan9303_switch_ops = {
Juergen Beiserta1292592017-04-18 10:48:25 +0200840 .get_tag_protocol = lan9303_get_tag_protocol,
841 .setup = lan9303_setup,
842 .get_strings = lan9303_get_strings,
843 .phy_read = lan9303_phy_read,
844 .phy_write = lan9303_phy_write,
Egil Hjelmeland4d6a78b2017-09-19 10:09:24 +0200845 .adjust_link = lan9303_adjust_link,
Juergen Beiserta1292592017-04-18 10:48:25 +0200846 .get_ethtool_stats = lan9303_get_ethtool_stats,
847 .get_sset_count = lan9303_get_sset_count,
848 .port_enable = lan9303_port_enable,
849 .port_disable = lan9303_port_disable,
850};
851
852static int lan9303_register_switch(struct lan9303 *chip)
853{
Egil Hjelmeland274cdb42017-08-08 00:22:21 +0200854 chip->ds = dsa_switch_alloc(chip->dev, LAN9303_NUM_PORTS);
Juergen Beiserta1292592017-04-18 10:48:25 +0200855 if (!chip->ds)
856 return -ENOMEM;
857
858 chip->ds->priv = chip;
859 chip->ds->ops = &lan9303_switch_ops;
860 chip->ds->phys_mii_mask = chip->phy_addr_sel_strap ? 0xe : 0x7;
861
Vivien Didelot23c9ee42017-05-26 18:12:51 -0400862 return dsa_register_switch(chip->ds);
Juergen Beiserta1292592017-04-18 10:48:25 +0200863}
864
865static void lan9303_probe_reset_gpio(struct lan9303 *chip,
866 struct device_node *np)
867{
868 chip->reset_gpio = devm_gpiod_get_optional(chip->dev, "reset",
869 GPIOD_OUT_LOW);
870
871 if (!chip->reset_gpio) {
872 dev_dbg(chip->dev, "No reset GPIO defined\n");
873 return;
874 }
875
876 chip->reset_duration = 200;
877
878 if (np) {
879 of_property_read_u32(np, "reset-duration",
880 &chip->reset_duration);
881 } else {
882 dev_dbg(chip->dev, "reset duration defaults to 200 ms\n");
883 }
884
885 /* A sane reset duration should not be longer than 1s */
886 if (chip->reset_duration > 1000)
887 chip->reset_duration = 1000;
888}
889
890int lan9303_probe(struct lan9303 *chip, struct device_node *np)
891{
892 int ret;
893
894 mutex_init(&chip->indirect_mutex);
895
896 lan9303_probe_reset_gpio(chip, np);
897
898 ret = lan9303_handle_reset(chip);
899 if (ret)
900 return ret;
901
902 ret = lan9303_check_device(chip);
903 if (ret)
904 return ret;
905
906 ret = lan9303_register_switch(chip);
907 if (ret) {
908 dev_dbg(chip->dev, "Failed to register switch: %d\n", ret);
909 return ret;
910 }
911
912 return 0;
913}
914EXPORT_SYMBOL(lan9303_probe);
915
916int lan9303_remove(struct lan9303 *chip)
917{
918 int rc;
919
920 rc = lan9303_disable_processing(chip);
921 if (rc != 0)
922 dev_warn(chip->dev, "shutting down failed\n");
923
924 dsa_unregister_switch(chip->ds);
925
926 /* assert reset to the whole device to prevent it from doing anything */
927 gpiod_set_value_cansleep(chip->reset_gpio, 1);
928 gpiod_unexport(chip->reset_gpio);
929
930 return 0;
931}
932EXPORT_SYMBOL(lan9303_remove);
933
934MODULE_AUTHOR("Juergen Borleis <kernel@pengutronix.de>");
935MODULE_DESCRIPTION("Core driver for SMSC/Microchip LAN9303 three port ethernet switch");
936MODULE_LICENSE("GPL v2");