Linux Audio

Check our new training course

Linux kernel drivers training

Mar 31-Apr 9, 2025, special US time zones
Register
Loading...
v3.15
  1/*
  2 * net/dsa/mv88e6xxx.c - Marvell 88e6xxx switch chip support
  3 * Copyright (c) 2008 Marvell Semiconductor
  4 *
  5 * This program is free software; you can redistribute it and/or modify
  6 * it under the terms of the GNU General Public License as published by
  7 * the Free Software Foundation; either version 2 of the License, or
  8 * (at your option) any later version.
  9 */
 10
 11#include <linux/delay.h>
 12#include <linux/jiffies.h>
 13#include <linux/list.h>
 14#include <linux/module.h>
 15#include <linux/netdevice.h>
 16#include <linux/phy.h>
 17#include <net/dsa.h>
 18#include "mv88e6xxx.h"
 19
 20/* If the switch's ADDR[4:0] strap pins are strapped to zero, it will
 
 21 * use all 32 SMI bus addresses on its SMI bus, and all switch registers
 22 * will be directly accessible on some {device address,register address}
 23 * pair.  If the ADDR[4:0] pins are not strapped to zero, the switch
 24 * will only respond to SMI transactions to that specific address, and
 25 * an indirect addressing mechanism needs to be used to access its
 26 * registers.
 27 */
 28static int mv88e6xxx_reg_wait_ready(struct mii_bus *bus, int sw_addr)
 29{
 30	int ret;
 31	int i;
 32
 33	for (i = 0; i < 16; i++) {
 34		ret = mdiobus_read(bus, sw_addr, 0);
 35		if (ret < 0)
 36			return ret;
 37
 38		if ((ret & 0x8000) == 0)
 39			return 0;
 40	}
 41
 42	return -ETIMEDOUT;
 43}
 44
 45int __mv88e6xxx_reg_read(struct mii_bus *bus, int sw_addr, int addr, int reg)
 46{
 47	int ret;
 48
 49	if (sw_addr == 0)
 50		return mdiobus_read(bus, addr, reg);
 51
 52	/* Wait for the bus to become free. */
 
 
 53	ret = mv88e6xxx_reg_wait_ready(bus, sw_addr);
 54	if (ret < 0)
 55		return ret;
 56
 57	/* Transmit the read command. */
 
 
 58	ret = mdiobus_write(bus, sw_addr, 0, 0x9800 | (addr << 5) | reg);
 59	if (ret < 0)
 60		return ret;
 61
 62	/* Wait for the read command to complete. */
 
 
 63	ret = mv88e6xxx_reg_wait_ready(bus, sw_addr);
 64	if (ret < 0)
 65		return ret;
 66
 67	/* Read the data. */
 
 
 68	ret = mdiobus_read(bus, sw_addr, 1);
 69	if (ret < 0)
 70		return ret;
 71
 72	return ret & 0xffff;
 73}
 74
 75int mv88e6xxx_reg_read(struct dsa_switch *ds, int addr, int reg)
 76{
 77	struct mv88e6xxx_priv_state *ps = (void *)(ds + 1);
 78	int ret;
 79
 80	mutex_lock(&ps->smi_mutex);
 81	ret = __mv88e6xxx_reg_read(ds->master_mii_bus,
 82				   ds->pd->sw_addr, addr, reg);
 83	mutex_unlock(&ps->smi_mutex);
 84
 85	return ret;
 86}
 87
 88int __mv88e6xxx_reg_write(struct mii_bus *bus, int sw_addr, int addr,
 89			  int reg, u16 val)
 90{
 91	int ret;
 92
 93	if (sw_addr == 0)
 94		return mdiobus_write(bus, addr, reg, val);
 95
 96	/* Wait for the bus to become free. */
 
 
 97	ret = mv88e6xxx_reg_wait_ready(bus, sw_addr);
 98	if (ret < 0)
 99		return ret;
100
101	/* Transmit the data to write. */
 
 
102	ret = mdiobus_write(bus, sw_addr, 1, val);
103	if (ret < 0)
104		return ret;
105
106	/* Transmit the write command. */
 
 
107	ret = mdiobus_write(bus, sw_addr, 0, 0x9400 | (addr << 5) | reg);
108	if (ret < 0)
109		return ret;
110
111	/* Wait for the write command to complete. */
 
 
112	ret = mv88e6xxx_reg_wait_ready(bus, sw_addr);
113	if (ret < 0)
114		return ret;
115
116	return 0;
117}
118
119int mv88e6xxx_reg_write(struct dsa_switch *ds, int addr, int reg, u16 val)
120{
121	struct mv88e6xxx_priv_state *ps = (void *)(ds + 1);
122	int ret;
123
124	mutex_lock(&ps->smi_mutex);
125	ret = __mv88e6xxx_reg_write(ds->master_mii_bus,
126				    ds->pd->sw_addr, addr, reg, val);
127	mutex_unlock(&ps->smi_mutex);
128
129	return ret;
130}
131
132int mv88e6xxx_config_prio(struct dsa_switch *ds)
133{
134	/* Configure the IP ToS mapping registers. */
 
 
135	REG_WRITE(REG_GLOBAL, 0x10, 0x0000);
136	REG_WRITE(REG_GLOBAL, 0x11, 0x0000);
137	REG_WRITE(REG_GLOBAL, 0x12, 0x5555);
138	REG_WRITE(REG_GLOBAL, 0x13, 0x5555);
139	REG_WRITE(REG_GLOBAL, 0x14, 0xaaaa);
140	REG_WRITE(REG_GLOBAL, 0x15, 0xaaaa);
141	REG_WRITE(REG_GLOBAL, 0x16, 0xffff);
142	REG_WRITE(REG_GLOBAL, 0x17, 0xffff);
143
144	/* Configure the IEEE 802.1p priority mapping register. */
 
 
145	REG_WRITE(REG_GLOBAL, 0x18, 0xfa41);
146
147	return 0;
148}
149
150int mv88e6xxx_set_addr_direct(struct dsa_switch *ds, u8 *addr)
151{
152	REG_WRITE(REG_GLOBAL, 0x01, (addr[0] << 8) | addr[1]);
153	REG_WRITE(REG_GLOBAL, 0x02, (addr[2] << 8) | addr[3]);
154	REG_WRITE(REG_GLOBAL, 0x03, (addr[4] << 8) | addr[5]);
155
156	return 0;
157}
158
159int mv88e6xxx_set_addr_indirect(struct dsa_switch *ds, u8 *addr)
160{
161	int i;
162	int ret;
163
164	for (i = 0; i < 6; i++) {
165		int j;
166
167		/* Write the MAC address byte. */
 
 
168		REG_WRITE(REG_GLOBAL2, 0x0d, 0x8000 | (i << 8) | addr[i]);
169
170		/* Wait for the write to complete. */
 
 
171		for (j = 0; j < 16; j++) {
172			ret = REG_READ(REG_GLOBAL2, 0x0d);
173			if ((ret & 0x8000) == 0)
174				break;
175		}
176		if (j == 16)
177			return -ETIMEDOUT;
178	}
179
180	return 0;
181}
182
183int mv88e6xxx_phy_read(struct dsa_switch *ds, int addr, int regnum)
184{
185	if (addr >= 0)
186		return mv88e6xxx_reg_read(ds, addr, regnum);
187	return 0xffff;
188}
189
190int mv88e6xxx_phy_write(struct dsa_switch *ds, int addr, int regnum, u16 val)
191{
192	if (addr >= 0)
193		return mv88e6xxx_reg_write(ds, addr, regnum, val);
194	return 0;
195}
196
197#ifdef CONFIG_NET_DSA_MV88E6XXX_NEED_PPU
198static int mv88e6xxx_ppu_disable(struct dsa_switch *ds)
199{
200	int ret;
201	unsigned long timeout;
202
203	ret = REG_READ(REG_GLOBAL, 0x04);
204	REG_WRITE(REG_GLOBAL, 0x04, ret & ~0x4000);
205
206	timeout = jiffies + 1 * HZ;
207	while (time_before(jiffies, timeout)) {
208		ret = REG_READ(REG_GLOBAL, 0x00);
209		usleep_range(1000, 2000);
210		if ((ret & 0xc000) != 0xc000)
211			return 0;
212	}
213
214	return -ETIMEDOUT;
215}
216
217static int mv88e6xxx_ppu_enable(struct dsa_switch *ds)
218{
219	int ret;
220	unsigned long timeout;
221
222	ret = REG_READ(REG_GLOBAL, 0x04);
223	REG_WRITE(REG_GLOBAL, 0x04, ret | 0x4000);
224
225	timeout = jiffies + 1 * HZ;
226	while (time_before(jiffies, timeout)) {
227		ret = REG_READ(REG_GLOBAL, 0x00);
228		usleep_range(1000, 2000);
229		if ((ret & 0xc000) == 0xc000)
230			return 0;
231	}
232
233	return -ETIMEDOUT;
234}
235
236static void mv88e6xxx_ppu_reenable_work(struct work_struct *ugly)
237{
238	struct mv88e6xxx_priv_state *ps;
239
240	ps = container_of(ugly, struct mv88e6xxx_priv_state, ppu_work);
241	if (mutex_trylock(&ps->ppu_mutex)) {
242		struct dsa_switch *ds = ((struct dsa_switch *)ps) - 1;
243
244		if (mv88e6xxx_ppu_enable(ds) == 0)
245			ps->ppu_disabled = 0;
246		mutex_unlock(&ps->ppu_mutex);
247	}
248}
249
250static void mv88e6xxx_ppu_reenable_timer(unsigned long _ps)
251{
252	struct mv88e6xxx_priv_state *ps = (void *)_ps;
253
254	schedule_work(&ps->ppu_work);
255}
256
257static int mv88e6xxx_ppu_access_get(struct dsa_switch *ds)
258{
259	struct mv88e6xxx_priv_state *ps = (void *)(ds + 1);
260	int ret;
261
262	mutex_lock(&ps->ppu_mutex);
263
264	/* If the PHY polling unit is enabled, disable it so that
 
265	 * we can access the PHY registers.  If it was already
266	 * disabled, cancel the timer that is going to re-enable
267	 * it.
268	 */
269	if (!ps->ppu_disabled) {
270		ret = mv88e6xxx_ppu_disable(ds);
271		if (ret < 0) {
272			mutex_unlock(&ps->ppu_mutex);
273			return ret;
274		}
275		ps->ppu_disabled = 1;
276	} else {
277		del_timer(&ps->ppu_timer);
278		ret = 0;
279	}
280
281	return ret;
282}
283
284static void mv88e6xxx_ppu_access_put(struct dsa_switch *ds)
285{
286	struct mv88e6xxx_priv_state *ps = (void *)(ds + 1);
287
288	/* Schedule a timer to re-enable the PHY polling unit. */
 
 
289	mod_timer(&ps->ppu_timer, jiffies + msecs_to_jiffies(10));
290	mutex_unlock(&ps->ppu_mutex);
291}
292
293void mv88e6xxx_ppu_state_init(struct dsa_switch *ds)
294{
295	struct mv88e6xxx_priv_state *ps = (void *)(ds + 1);
296
297	mutex_init(&ps->ppu_mutex);
298	INIT_WORK(&ps->ppu_work, mv88e6xxx_ppu_reenable_work);
299	init_timer(&ps->ppu_timer);
300	ps->ppu_timer.data = (unsigned long)ps;
301	ps->ppu_timer.function = mv88e6xxx_ppu_reenable_timer;
302}
303
304int mv88e6xxx_phy_read_ppu(struct dsa_switch *ds, int addr, int regnum)
305{
306	int ret;
307
308	ret = mv88e6xxx_ppu_access_get(ds);
309	if (ret >= 0) {
310		ret = mv88e6xxx_reg_read(ds, addr, regnum);
311		mv88e6xxx_ppu_access_put(ds);
312	}
313
314	return ret;
315}
316
317int mv88e6xxx_phy_write_ppu(struct dsa_switch *ds, int addr,
318			    int regnum, u16 val)
319{
320	int ret;
321
322	ret = mv88e6xxx_ppu_access_get(ds);
323	if (ret >= 0) {
324		ret = mv88e6xxx_reg_write(ds, addr, regnum, val);
325		mv88e6xxx_ppu_access_put(ds);
326	}
327
328	return ret;
329}
330#endif
331
332void mv88e6xxx_poll_link(struct dsa_switch *ds)
333{
334	int i;
335
336	for (i = 0; i < DSA_MAX_PORTS; i++) {
337		struct net_device *dev;
338		int uninitialized_var(port_status);
339		int link;
340		int speed;
341		int duplex;
342		int fc;
343
344		dev = ds->ports[i];
345		if (dev == NULL)
346			continue;
347
348		link = 0;
349		if (dev->flags & IFF_UP) {
350			port_status = mv88e6xxx_reg_read(ds, REG_PORT(i), 0x00);
351			if (port_status < 0)
352				continue;
353
354			link = !!(port_status & 0x0800);
355		}
356
357		if (!link) {
358			if (netif_carrier_ok(dev)) {
359				netdev_info(dev, "link down\n");
360				netif_carrier_off(dev);
361			}
362			continue;
363		}
364
365		switch (port_status & 0x0300) {
366		case 0x0000:
367			speed = 10;
368			break;
369		case 0x0100:
370			speed = 100;
371			break;
372		case 0x0200:
373			speed = 1000;
374			break;
375		default:
376			speed = -1;
377			break;
378		}
379		duplex = (port_status & 0x0400) ? 1 : 0;
380		fc = (port_status & 0x8000) ? 1 : 0;
381
382		if (!netif_carrier_ok(dev)) {
383			netdev_info(dev,
384				    "link up, %d Mb/s, %s duplex, flow control %sabled\n",
385				    speed,
386				    duplex ? "full" : "half",
387				    fc ? "en" : "dis");
388			netif_carrier_on(dev);
389		}
390	}
391}
392
393static int mv88e6xxx_stats_wait(struct dsa_switch *ds)
394{
395	int ret;
396	int i;
397
398	for (i = 0; i < 10; i++) {
399		ret = REG_READ(REG_GLOBAL, 0x1d);
400		if ((ret & 0x8000) == 0)
401			return 0;
402	}
403
404	return -ETIMEDOUT;
405}
406
407static int mv88e6xxx_stats_snapshot(struct dsa_switch *ds, int port)
408{
409	int ret;
410
411	/* Snapshot the hardware statistics counters for this port. */
 
 
412	REG_WRITE(REG_GLOBAL, 0x1d, 0xdc00 | port);
413
414	/* Wait for the snapshotting to complete. */
 
 
415	ret = mv88e6xxx_stats_wait(ds);
416	if (ret < 0)
417		return ret;
418
419	return 0;
420}
421
422static void mv88e6xxx_stats_read(struct dsa_switch *ds, int stat, u32 *val)
423{
424	u32 _val;
425	int ret;
426
427	*val = 0;
428
429	ret = mv88e6xxx_reg_write(ds, REG_GLOBAL, 0x1d, 0xcc00 | stat);
430	if (ret < 0)
431		return;
432
433	ret = mv88e6xxx_stats_wait(ds);
434	if (ret < 0)
435		return;
436
437	ret = mv88e6xxx_reg_read(ds, REG_GLOBAL, 0x1e);
438	if (ret < 0)
439		return;
440
441	_val = ret << 16;
442
443	ret = mv88e6xxx_reg_read(ds, REG_GLOBAL, 0x1f);
444	if (ret < 0)
445		return;
446
447	*val = _val | ret;
448}
449
450void mv88e6xxx_get_strings(struct dsa_switch *ds,
451			   int nr_stats, struct mv88e6xxx_hw_stat *stats,
452			   int port, uint8_t *data)
453{
454	int i;
455
456	for (i = 0; i < nr_stats; i++) {
457		memcpy(data + i * ETH_GSTRING_LEN,
458		       stats[i].string, ETH_GSTRING_LEN);
459	}
460}
461
462void mv88e6xxx_get_ethtool_stats(struct dsa_switch *ds,
463				 int nr_stats, struct mv88e6xxx_hw_stat *stats,
464				 int port, uint64_t *data)
465{
466	struct mv88e6xxx_priv_state *ps = (void *)(ds + 1);
467	int ret;
468	int i;
469
470	mutex_lock(&ps->stats_mutex);
471
472	ret = mv88e6xxx_stats_snapshot(ds, port);
473	if (ret < 0) {
474		mutex_unlock(&ps->stats_mutex);
475		return;
476	}
477
478	/* Read each of the counters. */
 
 
479	for (i = 0; i < nr_stats; i++) {
480		struct mv88e6xxx_hw_stat *s = stats + i;
481		u32 low;
482		u32 high;
483
484		mv88e6xxx_stats_read(ds, s->reg, &low);
485		if (s->sizeof_stat == 8)
486			mv88e6xxx_stats_read(ds, s->reg + 1, &high);
487		else
488			high = 0;
489
490		data[i] = (((u64)high) << 32) | low;
491	}
492
493	mutex_unlock(&ps->stats_mutex);
494}
495
496static int __init mv88e6xxx_init(void)
497{
498#if IS_ENABLED(CONFIG_NET_DSA_MV88E6131)
499	register_switch_driver(&mv88e6131_switch_driver);
500#endif
501#if IS_ENABLED(CONFIG_NET_DSA_MV88E6123_61_65)
502	register_switch_driver(&mv88e6123_61_65_switch_driver);
503#endif
504	return 0;
505}
506module_init(mv88e6xxx_init);
507
508static void __exit mv88e6xxx_cleanup(void)
509{
510#if IS_ENABLED(CONFIG_NET_DSA_MV88E6123_61_65)
511	unregister_switch_driver(&mv88e6123_61_65_switch_driver);
512#endif
513#if IS_ENABLED(CONFIG_NET_DSA_MV88E6131)
514	unregister_switch_driver(&mv88e6131_switch_driver);
515#endif
516}
517module_exit(mv88e6xxx_cleanup);
518
519MODULE_AUTHOR("Lennert Buytenhek <buytenh@wantstofly.org>");
520MODULE_DESCRIPTION("Driver for Marvell 88E6XXX ethernet switch chips");
521MODULE_LICENSE("GPL");
v3.5.6
  1/*
  2 * net/dsa/mv88e6xxx.c - Marvell 88e6xxx switch chip support
  3 * Copyright (c) 2008 Marvell Semiconductor
  4 *
  5 * This program is free software; you can redistribute it and/or modify
  6 * it under the terms of the GNU General Public License as published by
  7 * the Free Software Foundation; either version 2 of the License, or
  8 * (at your option) any later version.
  9 */
 10
 
 
 11#include <linux/list.h>
 12#include <linux/module.h>
 13#include <linux/netdevice.h>
 14#include <linux/phy.h>
 15#include <net/dsa.h>
 16#include "mv88e6xxx.h"
 17
 18/*
 19 * If the switch's ADDR[4:0] strap pins are strapped to zero, it will
 20 * use all 32 SMI bus addresses on its SMI bus, and all switch registers
 21 * will be directly accessible on some {device address,register address}
 22 * pair.  If the ADDR[4:0] pins are not strapped to zero, the switch
 23 * will only respond to SMI transactions to that specific address, and
 24 * an indirect addressing mechanism needs to be used to access its
 25 * registers.
 26 */
 27static int mv88e6xxx_reg_wait_ready(struct mii_bus *bus, int sw_addr)
 28{
 29	int ret;
 30	int i;
 31
 32	for (i = 0; i < 16; i++) {
 33		ret = mdiobus_read(bus, sw_addr, 0);
 34		if (ret < 0)
 35			return ret;
 36
 37		if ((ret & 0x8000) == 0)
 38			return 0;
 39	}
 40
 41	return -ETIMEDOUT;
 42}
 43
 44int __mv88e6xxx_reg_read(struct mii_bus *bus, int sw_addr, int addr, int reg)
 45{
 46	int ret;
 47
 48	if (sw_addr == 0)
 49		return mdiobus_read(bus, addr, reg);
 50
 51	/*
 52	 * Wait for the bus to become free.
 53	 */
 54	ret = mv88e6xxx_reg_wait_ready(bus, sw_addr);
 55	if (ret < 0)
 56		return ret;
 57
 58	/*
 59	 * Transmit the read command.
 60	 */
 61	ret = mdiobus_write(bus, sw_addr, 0, 0x9800 | (addr << 5) | reg);
 62	if (ret < 0)
 63		return ret;
 64
 65	/*
 66	 * Wait for the read command to complete.
 67	 */
 68	ret = mv88e6xxx_reg_wait_ready(bus, sw_addr);
 69	if (ret < 0)
 70		return ret;
 71
 72	/*
 73	 * Read the data.
 74	 */
 75	ret = mdiobus_read(bus, sw_addr, 1);
 76	if (ret < 0)
 77		return ret;
 78
 79	return ret & 0xffff;
 80}
 81
 82int mv88e6xxx_reg_read(struct dsa_switch *ds, int addr, int reg)
 83{
 84	struct mv88e6xxx_priv_state *ps = (void *)(ds + 1);
 85	int ret;
 86
 87	mutex_lock(&ps->smi_mutex);
 88	ret = __mv88e6xxx_reg_read(ds->master_mii_bus,
 89				   ds->pd->sw_addr, addr, reg);
 90	mutex_unlock(&ps->smi_mutex);
 91
 92	return ret;
 93}
 94
 95int __mv88e6xxx_reg_write(struct mii_bus *bus, int sw_addr, int addr,
 96			  int reg, u16 val)
 97{
 98	int ret;
 99
100	if (sw_addr == 0)
101		return mdiobus_write(bus, addr, reg, val);
102
103	/*
104	 * Wait for the bus to become free.
105	 */
106	ret = mv88e6xxx_reg_wait_ready(bus, sw_addr);
107	if (ret < 0)
108		return ret;
109
110	/*
111	 * Transmit the data to write.
112	 */
113	ret = mdiobus_write(bus, sw_addr, 1, val);
114	if (ret < 0)
115		return ret;
116
117	/*
118	 * Transmit the write command.
119	 */
120	ret = mdiobus_write(bus, sw_addr, 0, 0x9400 | (addr << 5) | reg);
121	if (ret < 0)
122		return ret;
123
124	/*
125	 * Wait for the write command to complete.
126	 */
127	ret = mv88e6xxx_reg_wait_ready(bus, sw_addr);
128	if (ret < 0)
129		return ret;
130
131	return 0;
132}
133
134int mv88e6xxx_reg_write(struct dsa_switch *ds, int addr, int reg, u16 val)
135{
136	struct mv88e6xxx_priv_state *ps = (void *)(ds + 1);
137	int ret;
138
139	mutex_lock(&ps->smi_mutex);
140	ret = __mv88e6xxx_reg_write(ds->master_mii_bus,
141				    ds->pd->sw_addr, addr, reg, val);
142	mutex_unlock(&ps->smi_mutex);
143
144	return ret;
145}
146
147int mv88e6xxx_config_prio(struct dsa_switch *ds)
148{
149	/*
150	 * Configure the IP ToS mapping registers.
151	 */
152	REG_WRITE(REG_GLOBAL, 0x10, 0x0000);
153	REG_WRITE(REG_GLOBAL, 0x11, 0x0000);
154	REG_WRITE(REG_GLOBAL, 0x12, 0x5555);
155	REG_WRITE(REG_GLOBAL, 0x13, 0x5555);
156	REG_WRITE(REG_GLOBAL, 0x14, 0xaaaa);
157	REG_WRITE(REG_GLOBAL, 0x15, 0xaaaa);
158	REG_WRITE(REG_GLOBAL, 0x16, 0xffff);
159	REG_WRITE(REG_GLOBAL, 0x17, 0xffff);
160
161	/*
162	 * Configure the IEEE 802.1p priority mapping register.
163	 */
164	REG_WRITE(REG_GLOBAL, 0x18, 0xfa41);
165
166	return 0;
167}
168
169int mv88e6xxx_set_addr_direct(struct dsa_switch *ds, u8 *addr)
170{
171	REG_WRITE(REG_GLOBAL, 0x01, (addr[0] << 8) | addr[1]);
172	REG_WRITE(REG_GLOBAL, 0x02, (addr[2] << 8) | addr[3]);
173	REG_WRITE(REG_GLOBAL, 0x03, (addr[4] << 8) | addr[5]);
174
175	return 0;
176}
177
178int mv88e6xxx_set_addr_indirect(struct dsa_switch *ds, u8 *addr)
179{
180	int i;
181	int ret;
182
183	for (i = 0; i < 6; i++) {
184		int j;
185
186		/*
187		 * Write the MAC address byte.
188		 */
189		REG_WRITE(REG_GLOBAL2, 0x0d, 0x8000 | (i << 8) | addr[i]);
190
191		/*
192		 * Wait for the write to complete.
193		 */
194		for (j = 0; j < 16; j++) {
195			ret = REG_READ(REG_GLOBAL2, 0x0d);
196			if ((ret & 0x8000) == 0)
197				break;
198		}
199		if (j == 16)
200			return -ETIMEDOUT;
201	}
202
203	return 0;
204}
205
206int mv88e6xxx_phy_read(struct dsa_switch *ds, int addr, int regnum)
207{
208	if (addr >= 0)
209		return mv88e6xxx_reg_read(ds, addr, regnum);
210	return 0xffff;
211}
212
213int mv88e6xxx_phy_write(struct dsa_switch *ds, int addr, int regnum, u16 val)
214{
215	if (addr >= 0)
216		return mv88e6xxx_reg_write(ds, addr, regnum, val);
217	return 0;
218}
219
220#ifdef CONFIG_NET_DSA_MV88E6XXX_NEED_PPU
221static int mv88e6xxx_ppu_disable(struct dsa_switch *ds)
222{
223	int ret;
224	int i;
225
226	ret = REG_READ(REG_GLOBAL, 0x04);
227	REG_WRITE(REG_GLOBAL, 0x04, ret & ~0x4000);
228
229	for (i = 0; i < 1000; i++) {
230	        ret = REG_READ(REG_GLOBAL, 0x00);
231	        msleep(1);
232	        if ((ret & 0xc000) != 0xc000)
233	                return 0;
 
234	}
235
236	return -ETIMEDOUT;
237}
238
239static int mv88e6xxx_ppu_enable(struct dsa_switch *ds)
240{
241	int ret;
242	int i;
243
244	ret = REG_READ(REG_GLOBAL, 0x04);
245	REG_WRITE(REG_GLOBAL, 0x04, ret | 0x4000);
246
247	for (i = 0; i < 1000; i++) {
248	        ret = REG_READ(REG_GLOBAL, 0x00);
249	        msleep(1);
250	        if ((ret & 0xc000) == 0xc000)
251	                return 0;
 
252	}
253
254	return -ETIMEDOUT;
255}
256
257static void mv88e6xxx_ppu_reenable_work(struct work_struct *ugly)
258{
259	struct mv88e6xxx_priv_state *ps;
260
261	ps = container_of(ugly, struct mv88e6xxx_priv_state, ppu_work);
262	if (mutex_trylock(&ps->ppu_mutex)) {
263	        struct dsa_switch *ds = ((struct dsa_switch *)ps) - 1;
264
265	        if (mv88e6xxx_ppu_enable(ds) == 0)
266	                ps->ppu_disabled = 0;
267	        mutex_unlock(&ps->ppu_mutex);
268	}
269}
270
271static void mv88e6xxx_ppu_reenable_timer(unsigned long _ps)
272{
273	struct mv88e6xxx_priv_state *ps = (void *)_ps;
274
275	schedule_work(&ps->ppu_work);
276}
277
278static int mv88e6xxx_ppu_access_get(struct dsa_switch *ds)
279{
280	struct mv88e6xxx_priv_state *ps = (void *)(ds + 1);
281	int ret;
282
283	mutex_lock(&ps->ppu_mutex);
284
285	/*
286	 * If the PHY polling unit is enabled, disable it so that
287	 * we can access the PHY registers.  If it was already
288	 * disabled, cancel the timer that is going to re-enable
289	 * it.
290	 */
291	if (!ps->ppu_disabled) {
292	        ret = mv88e6xxx_ppu_disable(ds);
293	        if (ret < 0) {
294	                mutex_unlock(&ps->ppu_mutex);
295	                return ret;
296	        }
297	        ps->ppu_disabled = 1;
298	} else {
299	        del_timer(&ps->ppu_timer);
300	        ret = 0;
301	}
302
303	return ret;
304}
305
306static void mv88e6xxx_ppu_access_put(struct dsa_switch *ds)
307{
308	struct mv88e6xxx_priv_state *ps = (void *)(ds + 1);
309
310	/*
311	 * Schedule a timer to re-enable the PHY polling unit.
312	 */
313	mod_timer(&ps->ppu_timer, jiffies + msecs_to_jiffies(10));
314	mutex_unlock(&ps->ppu_mutex);
315}
316
317void mv88e6xxx_ppu_state_init(struct dsa_switch *ds)
318{
319	struct mv88e6xxx_priv_state *ps = (void *)(ds + 1);
320
321	mutex_init(&ps->ppu_mutex);
322	INIT_WORK(&ps->ppu_work, mv88e6xxx_ppu_reenable_work);
323	init_timer(&ps->ppu_timer);
324	ps->ppu_timer.data = (unsigned long)ps;
325	ps->ppu_timer.function = mv88e6xxx_ppu_reenable_timer;
326}
327
328int mv88e6xxx_phy_read_ppu(struct dsa_switch *ds, int addr, int regnum)
329{
330	int ret;
331
332	ret = mv88e6xxx_ppu_access_get(ds);
333	if (ret >= 0) {
334	        ret = mv88e6xxx_reg_read(ds, addr, regnum);
335	        mv88e6xxx_ppu_access_put(ds);
336	}
337
338	return ret;
339}
340
341int mv88e6xxx_phy_write_ppu(struct dsa_switch *ds, int addr,
342			    int regnum, u16 val)
343{
344	int ret;
345
346	ret = mv88e6xxx_ppu_access_get(ds);
347	if (ret >= 0) {
348	        ret = mv88e6xxx_reg_write(ds, addr, regnum, val);
349	        mv88e6xxx_ppu_access_put(ds);
350	}
351
352	return ret;
353}
354#endif
355
356void mv88e6xxx_poll_link(struct dsa_switch *ds)
357{
358	int i;
359
360	for (i = 0; i < DSA_MAX_PORTS; i++) {
361		struct net_device *dev;
362		int uninitialized_var(port_status);
363		int link;
364		int speed;
365		int duplex;
366		int fc;
367
368		dev = ds->ports[i];
369		if (dev == NULL)
370			continue;
371
372		link = 0;
373		if (dev->flags & IFF_UP) {
374			port_status = mv88e6xxx_reg_read(ds, REG_PORT(i), 0x00);
375			if (port_status < 0)
376				continue;
377
378			link = !!(port_status & 0x0800);
379		}
380
381		if (!link) {
382			if (netif_carrier_ok(dev)) {
383				printk(KERN_INFO "%s: link down\n", dev->name);
384				netif_carrier_off(dev);
385			}
386			continue;
387		}
388
389		switch (port_status & 0x0300) {
390		case 0x0000:
391			speed = 10;
392			break;
393		case 0x0100:
394			speed = 100;
395			break;
396		case 0x0200:
397			speed = 1000;
398			break;
399		default:
400			speed = -1;
401			break;
402		}
403		duplex = (port_status & 0x0400) ? 1 : 0;
404		fc = (port_status & 0x8000) ? 1 : 0;
405
406		if (!netif_carrier_ok(dev)) {
407			printk(KERN_INFO "%s: link up, %d Mb/s, %s duplex, "
408					 "flow control %sabled\n", dev->name,
409					 speed, duplex ? "full" : "half",
410					 fc ? "en" : "dis");
 
411			netif_carrier_on(dev);
412		}
413	}
414}
415
416static int mv88e6xxx_stats_wait(struct dsa_switch *ds)
417{
418	int ret;
419	int i;
420
421	for (i = 0; i < 10; i++) {
422		ret = REG_READ(REG_GLOBAL, 0x1d);
423		if ((ret & 0x8000) == 0)
424			return 0;
425	}
426
427	return -ETIMEDOUT;
428}
429
430static int mv88e6xxx_stats_snapshot(struct dsa_switch *ds, int port)
431{
432	int ret;
433
434	/*
435	 * Snapshot the hardware statistics counters for this port.
436	 */
437	REG_WRITE(REG_GLOBAL, 0x1d, 0xdc00 | port);
438
439	/*
440	 * Wait for the snapshotting to complete.
441	 */
442	ret = mv88e6xxx_stats_wait(ds);
443	if (ret < 0)
444		return ret;
445
446	return 0;
447}
448
449static void mv88e6xxx_stats_read(struct dsa_switch *ds, int stat, u32 *val)
450{
451	u32 _val;
452	int ret;
453
454	*val = 0;
455
456	ret = mv88e6xxx_reg_write(ds, REG_GLOBAL, 0x1d, 0xcc00 | stat);
457	if (ret < 0)
458		return;
459
460	ret = mv88e6xxx_stats_wait(ds);
461	if (ret < 0)
462		return;
463
464	ret = mv88e6xxx_reg_read(ds, REG_GLOBAL, 0x1e);
465	if (ret < 0)
466		return;
467
468	_val = ret << 16;
469
470	ret = mv88e6xxx_reg_read(ds, REG_GLOBAL, 0x1f);
471	if (ret < 0)
472		return;
473
474	*val = _val | ret;
475}
476
477void mv88e6xxx_get_strings(struct dsa_switch *ds,
478			   int nr_stats, struct mv88e6xxx_hw_stat *stats,
479			   int port, uint8_t *data)
480{
481	int i;
482
483	for (i = 0; i < nr_stats; i++) {
484		memcpy(data + i * ETH_GSTRING_LEN,
485		       stats[i].string, ETH_GSTRING_LEN);
486	}
487}
488
489void mv88e6xxx_get_ethtool_stats(struct dsa_switch *ds,
490				 int nr_stats, struct mv88e6xxx_hw_stat *stats,
491				 int port, uint64_t *data)
492{
493	struct mv88e6xxx_priv_state *ps = (void *)(ds + 1);
494	int ret;
495	int i;
496
497	mutex_lock(&ps->stats_mutex);
498
499	ret = mv88e6xxx_stats_snapshot(ds, port);
500	if (ret < 0) {
501		mutex_unlock(&ps->stats_mutex);
502		return;
503	}
504
505	/*
506	 * Read each of the counters.
507	 */
508	for (i = 0; i < nr_stats; i++) {
509		struct mv88e6xxx_hw_stat *s = stats + i;
510		u32 low;
511		u32 high;
512
513		mv88e6xxx_stats_read(ds, s->reg, &low);
514		if (s->sizeof_stat == 8)
515			mv88e6xxx_stats_read(ds, s->reg + 1, &high);
516		else
517			high = 0;
518
519		data[i] = (((u64)high) << 32) | low;
520	}
521
522	mutex_unlock(&ps->stats_mutex);
523}
524
525static int __init mv88e6xxx_init(void)
526{
527#if IS_ENABLED(CONFIG_NET_DSA_MV88E6131)
528	register_switch_driver(&mv88e6131_switch_driver);
529#endif
530#if IS_ENABLED(CONFIG_NET_DSA_MV88E6123_61_65)
531	register_switch_driver(&mv88e6123_61_65_switch_driver);
532#endif
533	return 0;
534}
535module_init(mv88e6xxx_init);
536
537static void __exit mv88e6xxx_cleanup(void)
538{
539#if IS_ENABLED(CONFIG_NET_DSA_MV88E6123_61_65)
540	unregister_switch_driver(&mv88e6123_61_65_switch_driver);
541#endif
542#if IS_ENABLED(CONFIG_NET_DSA_MV88E6131)
543	unregister_switch_driver(&mv88e6131_switch_driver);
544#endif
545}
546module_exit(mv88e6xxx_cleanup);
547
548MODULE_AUTHOR("Lennert Buytenhek <buytenh@wantstofly.org>");
549MODULE_DESCRIPTION("Driver for Marvell 88E6XXX ethernet switch chips");
550MODULE_LICENSE("GPL");