blob: 2215ec1fbe1e92e197b1bedfcac7119524f17ec5 [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
Egil Hjelmelandf7e3bfa2017-10-10 14:49:52 +0200160#define LAN9303_SWE_INGRESS_PORT_TYPE_VLAN 3
Juergen Beiserta1292592017-04-18 10:48:25 +0200161#define LAN9303_BM_CFG 0x1c00
162#define LAN9303_BM_EGRSS_PORT_TYPE 0x1c0c
163# define LAN9303_BM_EGRSS_PORT_TYPE_SPECIAL_TAG_PORT2 (BIT(17) | BIT(16))
164# define LAN9303_BM_EGRSS_PORT_TYPE_SPECIAL_TAG_PORT1 (BIT(9) | BIT(8))
165# define LAN9303_BM_EGRSS_PORT_TYPE_SPECIAL_TAG_PORT0 (BIT(1) | BIT(0))
166
Egil Hjelmeland451d3ca2017-08-05 13:05:46 +0200167#define LAN9303_SWITCH_PORT_REG(port, reg0) (0x400 * (port) + (reg0))
Juergen Beiserta1292592017-04-18 10:48:25 +0200168
169/* the built-in PHYs are of type LAN911X */
170#define MII_LAN911X_SPECIAL_MODES 0x12
171#define MII_LAN911X_SPECIAL_CONTROL_STATUS 0x1f
172
173static const struct regmap_range lan9303_valid_regs[] = {
174 regmap_reg_range(0x14, 0x17), /* misc, interrupt */
175 regmap_reg_range(0x19, 0x19), /* endian test */
176 regmap_reg_range(0x1d, 0x1d), /* hardware config */
177 regmap_reg_range(0x23, 0x24), /* general purpose timer */
178 regmap_reg_range(0x27, 0x27), /* counter */
179 regmap_reg_range(0x29, 0x2a), /* PMI index regs */
180 regmap_reg_range(0x68, 0x6a), /* flow control */
181 regmap_reg_range(0x6b, 0x6c), /* switch fabric indirect regs */
182 regmap_reg_range(0x6d, 0x6f), /* misc */
183 regmap_reg_range(0x70, 0x77), /* virtual phy */
184 regmap_reg_range(0x78, 0x7a), /* GPIO */
185 regmap_reg_range(0x7c, 0x7e), /* MAC & reset */
186 regmap_reg_range(0x80, 0xb7), /* switch fabric direct regs (wr only) */
187};
188
189static const struct regmap_range lan9303_reserved_ranges[] = {
190 regmap_reg_range(0x00, 0x13),
191 regmap_reg_range(0x18, 0x18),
192 regmap_reg_range(0x1a, 0x1c),
193 regmap_reg_range(0x1e, 0x22),
194 regmap_reg_range(0x25, 0x26),
195 regmap_reg_range(0x28, 0x28),
196 regmap_reg_range(0x2b, 0x67),
197 regmap_reg_range(0x7b, 0x7b),
198 regmap_reg_range(0x7f, 0x7f),
199 regmap_reg_range(0xb8, 0xff),
200};
201
202const struct regmap_access_table lan9303_register_set = {
203 .yes_ranges = lan9303_valid_regs,
204 .n_yes_ranges = ARRAY_SIZE(lan9303_valid_regs),
205 .no_ranges = lan9303_reserved_ranges,
206 .n_no_ranges = ARRAY_SIZE(lan9303_reserved_ranges),
207};
208EXPORT_SYMBOL(lan9303_register_set);
209
210static int lan9303_read(struct regmap *regmap, unsigned int offset, u32 *reg)
211{
212 int ret, i;
213
214 /* we can lose arbitration for the I2C case, because the device
215 * tries to detect and read an external EEPROM after reset and acts as
216 * a master on the shared I2C bus itself. This conflicts with our
217 * attempts to access the device as a slave at the same moment.
218 */
219 for (i = 0; i < 5; i++) {
220 ret = regmap_read(regmap, offset, reg);
221 if (!ret)
222 return 0;
223 if (ret != -EAGAIN)
224 break;
225 msleep(500);
226 }
227
228 return -EIO;
229}
230
231static int lan9303_virt_phy_reg_read(struct lan9303 *chip, int regnum)
232{
233 int ret;
234 u32 val;
235
236 if (regnum > MII_EXPANSION)
237 return -EINVAL;
238
239 ret = lan9303_read(chip->regmap, LAN9303_VIRT_PHY_BASE + regnum, &val);
240 if (ret)
241 return ret;
242
243 return val & 0xffff;
244}
245
246static int lan9303_virt_phy_reg_write(struct lan9303 *chip, int regnum, u16 val)
247{
248 if (regnum > MII_EXPANSION)
249 return -EINVAL;
250
251 return regmap_write(chip->regmap, LAN9303_VIRT_PHY_BASE + regnum, val);
252}
253
Egil Hjelmeland9e866e52017-07-30 19:58:55 +0200254static int lan9303_indirect_phy_wait_for_completion(struct lan9303 *chip)
Juergen Beiserta1292592017-04-18 10:48:25 +0200255{
256 int ret, i;
257 u32 reg;
258
259 for (i = 0; i < 25; i++) {
260 ret = lan9303_read(chip->regmap, LAN9303_PMI_ACCESS, &reg);
261 if (ret) {
262 dev_err(chip->dev,
263 "Failed to read pmi access status: %d\n", ret);
264 return ret;
265 }
266 if (!(reg & LAN9303_PMI_ACCESS_MII_BUSY))
267 return 0;
268 msleep(1);
269 }
270
271 return -EIO;
272}
273
Egil Hjelmeland9e866e52017-07-30 19:58:55 +0200274static int lan9303_indirect_phy_read(struct lan9303 *chip, int addr, int regnum)
Juergen Beiserta1292592017-04-18 10:48:25 +0200275{
276 int ret;
277 u32 val;
278
279 val = LAN9303_PMI_ACCESS_PHY_ADDR(addr);
280 val |= LAN9303_PMI_ACCESS_MIIRINDA(regnum);
281
282 mutex_lock(&chip->indirect_mutex);
283
Egil Hjelmeland9e866e52017-07-30 19:58:55 +0200284 ret = lan9303_indirect_phy_wait_for_completion(chip);
Juergen Beiserta1292592017-04-18 10:48:25 +0200285 if (ret)
286 goto on_error;
287
288 /* start the MII read cycle */
289 ret = regmap_write(chip->regmap, LAN9303_PMI_ACCESS, val);
290 if (ret)
291 goto on_error;
292
Egil Hjelmeland9e866e52017-07-30 19:58:55 +0200293 ret = lan9303_indirect_phy_wait_for_completion(chip);
Juergen Beiserta1292592017-04-18 10:48:25 +0200294 if (ret)
295 goto on_error;
296
297 /* read the result of this operation */
298 ret = lan9303_read(chip->regmap, LAN9303_PMI_DATA, &val);
299 if (ret)
300 goto on_error;
301
302 mutex_unlock(&chip->indirect_mutex);
303
304 return val & 0xffff;
305
306on_error:
307 mutex_unlock(&chip->indirect_mutex);
308 return ret;
309}
310
Egil Hjelmeland9e866e52017-07-30 19:58:55 +0200311static int lan9303_indirect_phy_write(struct lan9303 *chip, int addr,
312 int regnum, u16 val)
Juergen Beiserta1292592017-04-18 10:48:25 +0200313{
314 int ret;
315 u32 reg;
316
317 reg = LAN9303_PMI_ACCESS_PHY_ADDR(addr);
318 reg |= LAN9303_PMI_ACCESS_MIIRINDA(regnum);
319 reg |= LAN9303_PMI_ACCESS_MII_WRITE;
320
321 mutex_lock(&chip->indirect_mutex);
322
Egil Hjelmeland9e866e52017-07-30 19:58:55 +0200323 ret = lan9303_indirect_phy_wait_for_completion(chip);
Juergen Beiserta1292592017-04-18 10:48:25 +0200324 if (ret)
325 goto on_error;
326
327 /* write the data first... */
328 ret = regmap_write(chip->regmap, LAN9303_PMI_DATA, val);
329 if (ret)
330 goto on_error;
331
332 /* ...then start the MII write cycle */
333 ret = regmap_write(chip->regmap, LAN9303_PMI_ACCESS, reg);
334
335on_error:
336 mutex_unlock(&chip->indirect_mutex);
337 return ret;
338}
339
Egil Hjelmeland2c340892017-07-30 19:58:56 +0200340const struct lan9303_phy_ops lan9303_indirect_phy_ops = {
341 .phy_read = lan9303_indirect_phy_read,
342 .phy_write = lan9303_indirect_phy_write,
343};
344EXPORT_SYMBOL_GPL(lan9303_indirect_phy_ops);
345
Juergen Beiserta1292592017-04-18 10:48:25 +0200346static int lan9303_switch_wait_for_completion(struct lan9303 *chip)
347{
348 int ret, i;
349 u32 reg;
350
351 for (i = 0; i < 25; i++) {
352 ret = lan9303_read(chip->regmap, LAN9303_SWITCH_CSR_CMD, &reg);
353 if (ret) {
354 dev_err(chip->dev,
355 "Failed to read csr command status: %d\n", ret);
356 return ret;
357 }
358 if (!(reg & LAN9303_SWITCH_CSR_CMD_BUSY))
359 return 0;
360 msleep(1);
361 }
362
363 return -EIO;
364}
365
366static int lan9303_write_switch_reg(struct lan9303 *chip, u16 regnum, u32 val)
367{
368 u32 reg;
369 int ret;
370
371 reg = regnum;
372 reg |= LAN9303_SWITCH_CSR_CMD_LANES;
373 reg |= LAN9303_SWITCH_CSR_CMD_BUSY;
374
375 mutex_lock(&chip->indirect_mutex);
376
377 ret = lan9303_switch_wait_for_completion(chip);
378 if (ret)
379 goto on_error;
380
381 ret = regmap_write(chip->regmap, LAN9303_SWITCH_CSR_DATA, val);
382 if (ret) {
383 dev_err(chip->dev, "Failed to write csr data reg: %d\n", ret);
384 goto on_error;
385 }
386
387 /* trigger write */
388 ret = regmap_write(chip->regmap, LAN9303_SWITCH_CSR_CMD, reg);
389 if (ret)
390 dev_err(chip->dev, "Failed to write csr command reg: %d\n",
391 ret);
392
393on_error:
394 mutex_unlock(&chip->indirect_mutex);
395 return ret;
396}
397
398static int lan9303_read_switch_reg(struct lan9303 *chip, u16 regnum, u32 *val)
399{
400 u32 reg;
401 int ret;
402
403 reg = regnum;
404 reg |= LAN9303_SWITCH_CSR_CMD_LANES;
405 reg |= LAN9303_SWITCH_CSR_CMD_RW;
406 reg |= LAN9303_SWITCH_CSR_CMD_BUSY;
407
408 mutex_lock(&chip->indirect_mutex);
409
410 ret = lan9303_switch_wait_for_completion(chip);
411 if (ret)
412 goto on_error;
413
414 /* trigger read */
415 ret = regmap_write(chip->regmap, LAN9303_SWITCH_CSR_CMD, reg);
416 if (ret) {
417 dev_err(chip->dev, "Failed to write csr command reg: %d\n",
418 ret);
419 goto on_error;
420 }
421
422 ret = lan9303_switch_wait_for_completion(chip);
423 if (ret)
424 goto on_error;
425
426 ret = lan9303_read(chip->regmap, LAN9303_SWITCH_CSR_DATA, val);
427 if (ret)
428 dev_err(chip->dev, "Failed to read csr data reg: %d\n", ret);
429on_error:
430 mutex_unlock(&chip->indirect_mutex);
431 return ret;
432}
433
Egil Hjelmeland451d3ca2017-08-05 13:05:46 +0200434static int lan9303_write_switch_port(struct lan9303 *chip, int port,
435 u16 regnum, u32 val)
436{
437 return lan9303_write_switch_reg(
438 chip, LAN9303_SWITCH_PORT_REG(port, regnum), val);
439}
440
Egil Hjelmeland0a967b42017-08-05 13:05:50 +0200441static int lan9303_read_switch_port(struct lan9303 *chip, int port,
442 u16 regnum, u32 *val)
443{
444 return lan9303_read_switch_reg(
445 chip, LAN9303_SWITCH_PORT_REG(port, regnum), val);
446}
447
Juergen Beiserta1292592017-04-18 10:48:25 +0200448static int lan9303_detect_phy_setup(struct lan9303 *chip)
449{
450 int reg;
451
452 /* depending on the 'phy_addr_sel_strap' setting, the three phys are
453 * using IDs 0-1-2 or IDs 1-2-3. We cannot read back the
454 * 'phy_addr_sel_strap' setting directly, so we need a test, which
455 * configuration is active:
456 * Special reg 18 of phy 3 reads as 0x0000, if 'phy_addr_sel_strap' is 0
457 * and the IDs are 0-1-2, else it contains something different from
458 * 0x0000, which means 'phy_addr_sel_strap' is 1 and the IDs are 1-2-3.
Egil Hjelmelandd329ac82017-07-30 19:58:53 +0200459 * 0xffff is returned on MDIO read with no response.
Juergen Beiserta1292592017-04-18 10:48:25 +0200460 */
Egil Hjelmeland2c340892017-07-30 19:58:56 +0200461 reg = chip->ops->phy_read(chip, 3, MII_LAN911X_SPECIAL_MODES);
Juergen Beiserta1292592017-04-18 10:48:25 +0200462 if (reg < 0) {
463 dev_err(chip->dev, "Failed to detect phy config: %d\n", reg);
464 return reg;
465 }
466
Egil Hjelmelandd329ac82017-07-30 19:58:53 +0200467 if ((reg != 0) && (reg != 0xffff))
Juergen Beiserta1292592017-04-18 10:48:25 +0200468 chip->phy_addr_sel_strap = 1;
469 else
470 chip->phy_addr_sel_strap = 0;
471
472 dev_dbg(chip->dev, "Phy setup '%s' detected\n",
473 chip->phy_addr_sel_strap ? "1-2-3" : "0-1-2");
474
475 return 0;
476}
477
Egil Hjelmeland9c842582017-08-05 13:05:49 +0200478static int lan9303_disable_processing_port(struct lan9303 *chip,
479 unsigned int port)
Juergen Beiserta1292592017-04-18 10:48:25 +0200480{
481 int ret;
482
483 /* disable RX, but keep register reset default values else */
Egil Hjelmeland451d3ca2017-08-05 13:05:46 +0200484 ret = lan9303_write_switch_port(chip, port, LAN9303_MAC_RX_CFG_0,
485 LAN9303_MAC_RX_CFG_X_REJECT_MAC_TYPES);
Juergen Beiserta1292592017-04-18 10:48:25 +0200486 if (ret)
487 return ret;
488
489 /* disable TX, but keep register reset default values else */
Egil Hjelmeland451d3ca2017-08-05 13:05:46 +0200490 return lan9303_write_switch_port(chip, port, LAN9303_MAC_TX_CFG_0,
Juergen Beiserta1292592017-04-18 10:48:25 +0200491 LAN9303_MAC_TX_CFG_X_TX_IFG_CONFIG_DEFAULT |
492 LAN9303_MAC_TX_CFG_X_TX_PAD_ENABLE);
493}
494
Egil Hjelmeland9c842582017-08-05 13:05:49 +0200495static int lan9303_enable_processing_port(struct lan9303 *chip,
496 unsigned int port)
Juergen Beiserta1292592017-04-18 10:48:25 +0200497{
498 int ret;
499
500 /* enable RX and keep register reset default values else */
Egil Hjelmeland451d3ca2017-08-05 13:05:46 +0200501 ret = lan9303_write_switch_port(chip, port, LAN9303_MAC_RX_CFG_0,
502 LAN9303_MAC_RX_CFG_X_REJECT_MAC_TYPES |
503 LAN9303_MAC_RX_CFG_X_RX_ENABLE);
Juergen Beiserta1292592017-04-18 10:48:25 +0200504 if (ret)
505 return ret;
506
507 /* enable TX and keep register reset default values else */
Egil Hjelmeland451d3ca2017-08-05 13:05:46 +0200508 return lan9303_write_switch_port(chip, port, LAN9303_MAC_TX_CFG_0,
Juergen Beiserta1292592017-04-18 10:48:25 +0200509 LAN9303_MAC_TX_CFG_X_TX_IFG_CONFIG_DEFAULT |
510 LAN9303_MAC_TX_CFG_X_TX_PAD_ENABLE |
511 LAN9303_MAC_TX_CFG_X_TX_ENABLE);
512}
513
Egil Hjelmelandf7e3bfa2017-10-10 14:49:52 +0200514/* forward special tagged packets from port 0 to port 1 *or* port 2 */
515static int lan9303_setup_tagging(struct lan9303 *chip)
516{
517 int ret;
518 u32 val;
519 /* enable defining the destination port via special VLAN tagging
520 * for port 0
521 */
522 ret = lan9303_write_switch_reg(chip, LAN9303_SWE_INGRESS_PORT_TYPE,
523 LAN9303_SWE_INGRESS_PORT_TYPE_VLAN);
524 if (ret)
525 return ret;
526
527 /* tag incoming packets at port 1 and 2 on their way to port 0 to be
528 * able to discover their source port
529 */
530 val = LAN9303_BM_EGRSS_PORT_TYPE_SPECIAL_TAG_PORT0;
531 return lan9303_write_switch_reg(chip, LAN9303_BM_EGRSS_PORT_TYPE, val);
532}
533
Juergen Beiserta1292592017-04-18 10:48:25 +0200534/* We want a special working switch:
535 * - do not forward packets between port 1 and 2
536 * - forward everything from port 1 to port 0
537 * - forward everything from port 2 to port 0
Juergen Beiserta1292592017-04-18 10:48:25 +0200538 */
539static int lan9303_separate_ports(struct lan9303 *chip)
540{
541 int ret;
542
543 ret = lan9303_write_switch_reg(chip, LAN9303_SWE_PORT_MIRROR,
544 LAN9303_SWE_PORT_MIRROR_SNIFFER_PORT0 |
545 LAN9303_SWE_PORT_MIRROR_MIRRORED_PORT1 |
546 LAN9303_SWE_PORT_MIRROR_MIRRORED_PORT2 |
547 LAN9303_SWE_PORT_MIRROR_ENABLE_RX_MIRRORING |
548 LAN9303_SWE_PORT_MIRROR_SNIFF_ALL);
549 if (ret)
550 return ret;
551
Juergen Beiserta1292592017-04-18 10:48:25 +0200552 /* prevent port 1 and 2 from forwarding packets by their own */
553 return lan9303_write_switch_reg(chip, LAN9303_SWE_PORT_STATE,
554 LAN9303_SWE_PORT_STATE_FORWARDING_PORT0 |
555 LAN9303_SWE_PORT_STATE_BLOCKING_PORT1 |
556 LAN9303_SWE_PORT_STATE_BLOCKING_PORT2);
557}
558
559static int lan9303_handle_reset(struct lan9303 *chip)
560{
561 if (!chip->reset_gpio)
562 return 0;
563
564 if (chip->reset_duration != 0)
565 msleep(chip->reset_duration);
566
567 /* release (deassert) reset and activate the device */
568 gpiod_set_value_cansleep(chip->reset_gpio, 0);
569
570 return 0;
571}
572
573/* stop processing packets for all ports */
574static int lan9303_disable_processing(struct lan9303 *chip)
575{
Egil Hjelmelandb3d14a22017-08-05 13:05:48 +0200576 int p;
Juergen Beiserta1292592017-04-18 10:48:25 +0200577
Egil Hjelmelandb3d14a22017-08-05 13:05:48 +0200578 for (p = 0; p < LAN9303_NUM_PORTS; p++) {
Egil Hjelmeland9c842582017-08-05 13:05:49 +0200579 int ret = lan9303_disable_processing_port(chip, p);
Egil Hjelmelandb3d14a22017-08-05 13:05:48 +0200580
581 if (ret)
582 return ret;
583 }
584
585 return 0;
Juergen Beiserta1292592017-04-18 10:48:25 +0200586}
587
588static int lan9303_check_device(struct lan9303 *chip)
589{
590 int ret;
591 u32 reg;
592
593 ret = lan9303_read(chip->regmap, LAN9303_CHIP_REV, &reg);
594 if (ret) {
595 dev_err(chip->dev, "failed to read chip revision register: %d\n",
596 ret);
597 if (!chip->reset_gpio) {
598 dev_dbg(chip->dev,
599 "hint: maybe failed due to missing reset GPIO\n");
600 }
601 return ret;
602 }
603
604 if ((reg >> 16) != LAN9303_CHIP_ID) {
605 dev_err(chip->dev, "expecting LAN9303 chip, but found: %X\n",
606 reg >> 16);
607 return ret;
608 }
609
610 /* The default state of the LAN9303 device is to forward packets between
611 * all ports (if not configured differently by an external EEPROM).
612 * The initial state of a DSA device must be forwarding packets only
613 * between the external and the internal ports and no forwarding
614 * between the external ports. In preparation we stop packet handling
615 * at all for now until the LAN9303 device is re-programmed accordingly.
616 */
617 ret = lan9303_disable_processing(chip);
618 if (ret)
619 dev_warn(chip->dev, "failed to disable switching %d\n", ret);
620
621 dev_info(chip->dev, "Found LAN9303 rev. %u\n", reg & 0xffff);
622
623 ret = lan9303_detect_phy_setup(chip);
624 if (ret) {
625 dev_err(chip->dev,
626 "failed to discover phy bootstrap setup: %d\n", ret);
627 return ret;
628 }
629
630 return 0;
631}
632
633/* ---------------------------- DSA -----------------------------------*/
634
635static enum dsa_tag_protocol lan9303_get_tag_protocol(struct dsa_switch *ds)
636{
637 return DSA_TAG_PROTO_LAN9303;
638}
639
640static int lan9303_setup(struct dsa_switch *ds)
641{
642 struct lan9303 *chip = ds->priv;
643 int ret;
644
645 /* Make sure that port 0 is the cpu port */
646 if (!dsa_is_cpu_port(ds, 0)) {
647 dev_err(chip->dev, "port 0 is not the CPU port\n");
648 return -EINVAL;
649 }
650
Egil Hjelmelandf7e3bfa2017-10-10 14:49:52 +0200651 ret = lan9303_setup_tagging(chip);
652 if (ret)
653 dev_err(chip->dev, "failed to setup port tagging %d\n", ret);
654
Juergen Beiserta1292592017-04-18 10:48:25 +0200655 ret = lan9303_separate_ports(chip);
656 if (ret)
657 dev_err(chip->dev, "failed to separate ports %d\n", ret);
658
Egil Hjelmeland9c842582017-08-05 13:05:49 +0200659 ret = lan9303_enable_processing_port(chip, 0);
Juergen Beiserta1292592017-04-18 10:48:25 +0200660 if (ret)
661 dev_err(chip->dev, "failed to re-enable switching %d\n", ret);
662
663 return 0;
664}
665
666struct lan9303_mib_desc {
667 unsigned int offset; /* offset of first MAC */
668 const char *name;
669};
670
671static const struct lan9303_mib_desc lan9303_mib[] = {
672 { .offset = LAN9303_MAC_RX_BRDCST_CNT_0, .name = "RxBroad", },
673 { .offset = LAN9303_MAC_RX_PAUSE_CNT_0, .name = "RxPause", },
674 { .offset = LAN9303_MAC_RX_MULCST_CNT_0, .name = "RxMulti", },
675 { .offset = LAN9303_MAC_RX_PKTOK_CNT_0, .name = "RxOk", },
676 { .offset = LAN9303_MAC_RX_CRCERR_CNT_0, .name = "RxCrcErr", },
677 { .offset = LAN9303_MAC_RX_ALIGN_CNT_0, .name = "RxAlignErr", },
678 { .offset = LAN9303_MAC_RX_JABB_CNT_0, .name = "RxJabber", },
679 { .offset = LAN9303_MAC_RX_FRAG_CNT_0, .name = "RxFragment", },
680 { .offset = LAN9303_MAC_RX_64_CNT_0, .name = "Rx64Byte", },
681 { .offset = LAN9303_MAC_RX_127_CNT_0, .name = "Rx128Byte", },
682 { .offset = LAN9303_MAC_RX_255_CNT_0, .name = "Rx256Byte", },
683 { .offset = LAN9303_MAC_RX_511_CNT_0, .name = "Rx512Byte", },
684 { .offset = LAN9303_MAC_RX_1023_CNT_0, .name = "Rx1024Byte", },
685 { .offset = LAN9303_MAC_RX_MAX_CNT_0, .name = "RxMaxByte", },
686 { .offset = LAN9303_MAC_RX_PKTLEN_CNT_0, .name = "RxByteCnt", },
687 { .offset = LAN9303_MAC_RX_SYMBL_CNT_0, .name = "RxSymbolCnt", },
688 { .offset = LAN9303_MAC_RX_CTLFRM_CNT_0, .name = "RxCfs", },
689 { .offset = LAN9303_MAC_RX_OVRSZE_CNT_0, .name = "RxOverFlow", },
690 { .offset = LAN9303_MAC_TX_UNDSZE_CNT_0, .name = "TxShort", },
691 { .offset = LAN9303_MAC_TX_BRDCST_CNT_0, .name = "TxBroad", },
692 { .offset = LAN9303_MAC_TX_PAUSE_CNT_0, .name = "TxPause", },
693 { .offset = LAN9303_MAC_TX_MULCST_CNT_0, .name = "TxMulti", },
694 { .offset = LAN9303_MAC_RX_UNDSZE_CNT_0, .name = "TxUnderRun", },
695 { .offset = LAN9303_MAC_TX_64_CNT_0, .name = "Tx64Byte", },
696 { .offset = LAN9303_MAC_TX_127_CNT_0, .name = "Tx128Byte", },
697 { .offset = LAN9303_MAC_TX_255_CNT_0, .name = "Tx256Byte", },
698 { .offset = LAN9303_MAC_TX_511_CNT_0, .name = "Tx512Byte", },
699 { .offset = LAN9303_MAC_TX_1023_CNT_0, .name = "Tx1024Byte", },
700 { .offset = LAN9303_MAC_TX_MAX_CNT_0, .name = "TxMaxByte", },
701 { .offset = LAN9303_MAC_TX_PKTLEN_CNT_0, .name = "TxByteCnt", },
702 { .offset = LAN9303_MAC_TX_PKTOK_CNT_0, .name = "TxOk", },
703 { .offset = LAN9303_MAC_TX_TOTALCOL_CNT_0, .name = "TxCollision", },
704 { .offset = LAN9303_MAC_TX_MULTICOL_CNT_0, .name = "TxMultiCol", },
705 { .offset = LAN9303_MAC_TX_SNGLECOL_CNT_0, .name = "TxSingleCol", },
706 { .offset = LAN9303_MAC_TX_EXCOL_CNT_0, .name = "TxExcCol", },
707 { .offset = LAN9303_MAC_TX_DEFER_CNT_0, .name = "TxDefer", },
708 { .offset = LAN9303_MAC_TX_LATECOL_0, .name = "TxLateCol", },
709};
710
711static void lan9303_get_strings(struct dsa_switch *ds, int port, uint8_t *data)
712{
713 unsigned int u;
714
715 for (u = 0; u < ARRAY_SIZE(lan9303_mib); u++) {
716 strncpy(data + u * ETH_GSTRING_LEN, lan9303_mib[u].name,
717 ETH_GSTRING_LEN);
718 }
719}
720
721static void lan9303_get_ethtool_stats(struct dsa_switch *ds, int port,
722 uint64_t *data)
723{
724 struct lan9303 *chip = ds->priv;
Egil Hjelmeland0a967b42017-08-05 13:05:50 +0200725 unsigned int u;
Juergen Beiserta1292592017-04-18 10:48:25 +0200726
727 for (u = 0; u < ARRAY_SIZE(lan9303_mib); u++) {
Egil Hjelmeland0a967b42017-08-05 13:05:50 +0200728 u32 reg;
729 int ret;
730
731 ret = lan9303_read_switch_port(
732 chip, port, lan9303_mib[u].offset, &reg);
733
Juergen Beiserta1292592017-04-18 10:48:25 +0200734 if (ret)
Egil Hjelmeland0a967b42017-08-05 13:05:50 +0200735 dev_warn(chip->dev, "Reading status port %d reg %u failed\n",
736 port, lan9303_mib[u].offset);
Juergen Beiserta1292592017-04-18 10:48:25 +0200737 data[u] = reg;
738 }
739}
740
741static int lan9303_get_sset_count(struct dsa_switch *ds)
742{
743 return ARRAY_SIZE(lan9303_mib);
744}
745
746static int lan9303_phy_read(struct dsa_switch *ds, int phy, int regnum)
747{
748 struct lan9303 *chip = ds->priv;
749 int phy_base = chip->phy_addr_sel_strap;
750
751 if (phy == phy_base)
752 return lan9303_virt_phy_reg_read(chip, regnum);
753 if (phy > phy_base + 2)
754 return -ENODEV;
755
Egil Hjelmeland2c340892017-07-30 19:58:56 +0200756 return chip->ops->phy_read(chip, phy, regnum);
Juergen Beiserta1292592017-04-18 10:48:25 +0200757}
758
759static int lan9303_phy_write(struct dsa_switch *ds, int phy, int regnum,
760 u16 val)
761{
762 struct lan9303 *chip = ds->priv;
763 int phy_base = chip->phy_addr_sel_strap;
764
765 if (phy == phy_base)
766 return lan9303_virt_phy_reg_write(chip, regnum, val);
767 if (phy > phy_base + 2)
768 return -ENODEV;
769
Egil Hjelmeland2c340892017-07-30 19:58:56 +0200770 return chip->ops->phy_write(chip, phy, regnum, val);
Juergen Beiserta1292592017-04-18 10:48:25 +0200771}
772
Egil Hjelmeland4d6a78b2017-09-19 10:09:24 +0200773static void lan9303_adjust_link(struct dsa_switch *ds, int port,
774 struct phy_device *phydev)
775{
776 struct lan9303 *chip = ds->priv;
777 int ctl, res;
778
779 if (!phy_is_pseudo_fixed_link(phydev))
780 return;
781
782 ctl = lan9303_phy_read(ds, port, MII_BMCR);
783
784 ctl &= ~BMCR_ANENABLE;
785
786 if (phydev->speed == SPEED_100)
787 ctl |= BMCR_SPEED100;
788 else if (phydev->speed == SPEED_10)
789 ctl &= ~BMCR_SPEED100;
790 else
791 dev_err(ds->dev, "unsupported speed: %d\n", phydev->speed);
792
793 if (phydev->duplex == DUPLEX_FULL)
794 ctl |= BMCR_FULLDPLX;
795 else
796 ctl &= ~BMCR_FULLDPLX;
797
798 res = lan9303_phy_write(ds, port, MII_BMCR, ctl);
799
800 if (port == chip->phy_addr_sel_strap) {
801 /* Virtual Phy: Remove Turbo 200Mbit mode */
802 lan9303_read(chip->regmap, LAN9303_VIRT_SPECIAL_CTRL, &ctl);
803
804 ctl &= ~LAN9303_VIRT_SPECIAL_TURBO;
805 res = regmap_write(chip->regmap,
806 LAN9303_VIRT_SPECIAL_CTRL, ctl);
807 }
808}
809
Juergen Beiserta1292592017-04-18 10:48:25 +0200810static int lan9303_port_enable(struct dsa_switch *ds, int port,
811 struct phy_device *phy)
812{
813 struct lan9303 *chip = ds->priv;
814
815 /* enable internal packet processing */
816 switch (port) {
817 case 1:
Juergen Beiserta1292592017-04-18 10:48:25 +0200818 case 2:
Egil Hjelmeland9c842582017-08-05 13:05:49 +0200819 return lan9303_enable_processing_port(chip, port);
Juergen Beiserta1292592017-04-18 10:48:25 +0200820 default:
821 dev_dbg(chip->dev,
822 "Error: request to power up invalid port %d\n", port);
823 }
824
825 return -ENODEV;
826}
827
828static void lan9303_port_disable(struct dsa_switch *ds, int port,
829 struct phy_device *phy)
830{
831 struct lan9303 *chip = ds->priv;
832
833 /* disable internal packet processing */
834 switch (port) {
835 case 1:
Juergen Beiserta1292592017-04-18 10:48:25 +0200836 case 2:
Egil Hjelmeland9c842582017-08-05 13:05:49 +0200837 lan9303_disable_processing_port(chip, port);
Egil Hjelmelandb3d14a22017-08-05 13:05:48 +0200838 lan9303_phy_write(ds, chip->phy_addr_sel_strap + port,
Egil Hjelmeland2c340892017-07-30 19:58:56 +0200839 MII_BMCR, BMCR_PDOWN);
Juergen Beiserta1292592017-04-18 10:48:25 +0200840 break;
841 default:
842 dev_dbg(chip->dev,
843 "Error: request to power down invalid port %d\n", port);
844 }
845}
846
Bhumika Goyald78d6772017-08-09 10:34:15 +0530847static const struct dsa_switch_ops lan9303_switch_ops = {
Juergen Beiserta1292592017-04-18 10:48:25 +0200848 .get_tag_protocol = lan9303_get_tag_protocol,
849 .setup = lan9303_setup,
850 .get_strings = lan9303_get_strings,
851 .phy_read = lan9303_phy_read,
852 .phy_write = lan9303_phy_write,
Egil Hjelmeland4d6a78b2017-09-19 10:09:24 +0200853 .adjust_link = lan9303_adjust_link,
Juergen Beiserta1292592017-04-18 10:48:25 +0200854 .get_ethtool_stats = lan9303_get_ethtool_stats,
855 .get_sset_count = lan9303_get_sset_count,
856 .port_enable = lan9303_port_enable,
857 .port_disable = lan9303_port_disable,
858};
859
860static int lan9303_register_switch(struct lan9303 *chip)
861{
Egil Hjelmeland274cdb42017-08-08 00:22:21 +0200862 chip->ds = dsa_switch_alloc(chip->dev, LAN9303_NUM_PORTS);
Juergen Beiserta1292592017-04-18 10:48:25 +0200863 if (!chip->ds)
864 return -ENOMEM;
865
866 chip->ds->priv = chip;
867 chip->ds->ops = &lan9303_switch_ops;
868 chip->ds->phys_mii_mask = chip->phy_addr_sel_strap ? 0xe : 0x7;
869
Vivien Didelot23c9ee42017-05-26 18:12:51 -0400870 return dsa_register_switch(chip->ds);
Juergen Beiserta1292592017-04-18 10:48:25 +0200871}
872
873static void lan9303_probe_reset_gpio(struct lan9303 *chip,
874 struct device_node *np)
875{
876 chip->reset_gpio = devm_gpiod_get_optional(chip->dev, "reset",
877 GPIOD_OUT_LOW);
878
879 if (!chip->reset_gpio) {
880 dev_dbg(chip->dev, "No reset GPIO defined\n");
881 return;
882 }
883
884 chip->reset_duration = 200;
885
886 if (np) {
887 of_property_read_u32(np, "reset-duration",
888 &chip->reset_duration);
889 } else {
890 dev_dbg(chip->dev, "reset duration defaults to 200 ms\n");
891 }
892
893 /* A sane reset duration should not be longer than 1s */
894 if (chip->reset_duration > 1000)
895 chip->reset_duration = 1000;
896}
897
898int lan9303_probe(struct lan9303 *chip, struct device_node *np)
899{
900 int ret;
901
902 mutex_init(&chip->indirect_mutex);
903
904 lan9303_probe_reset_gpio(chip, np);
905
906 ret = lan9303_handle_reset(chip);
907 if (ret)
908 return ret;
909
910 ret = lan9303_check_device(chip);
911 if (ret)
912 return ret;
913
914 ret = lan9303_register_switch(chip);
915 if (ret) {
916 dev_dbg(chip->dev, "Failed to register switch: %d\n", ret);
917 return ret;
918 }
919
920 return 0;
921}
922EXPORT_SYMBOL(lan9303_probe);
923
924int lan9303_remove(struct lan9303 *chip)
925{
926 int rc;
927
928 rc = lan9303_disable_processing(chip);
929 if (rc != 0)
930 dev_warn(chip->dev, "shutting down failed\n");
931
932 dsa_unregister_switch(chip->ds);
933
934 /* assert reset to the whole device to prevent it from doing anything */
935 gpiod_set_value_cansleep(chip->reset_gpio, 1);
936 gpiod_unexport(chip->reset_gpio);
937
938 return 0;
939}
940EXPORT_SYMBOL(lan9303_remove);
941
942MODULE_AUTHOR("Juergen Borleis <kernel@pengutronix.de>");
943MODULE_DESCRIPTION("Core driver for SMSC/Microchip LAN9303 three port ethernet switch");
944MODULE_LICENSE("GPL v2");