chip.c 95.5 KB
Newer Older
1
/*
2 3
 * Marvell 88e6xxx Ethernet switch single-chip support
 *
4 5
 * Copyright (c) 2008 Marvell Semiconductor
 *
6 7 8
 * Copyright (c) 2015 CMC Electronics, Inc.
 *	Added support for VLAN Table Unit operations
 *
9 10
 * Copyright (c) 2016 Andrew Lunn <andrew@lunn.ch>
 *
11 12 13 14 15 16
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.
 */

17
#include <linux/delay.h>
18
#include <linux/etherdevice.h>
19
#include <linux/ethtool.h>
20
#include <linux/if_bridge.h>
21 22 23
#include <linux/interrupt.h>
#include <linux/irq.h>
#include <linux/irqdomain.h>
24
#include <linux/jiffies.h>
25
#include <linux/list.h>
26
#include <linux/mdio.h>
27
#include <linux/module.h>
28
#include <linux/of_device.h>
29
#include <linux/of_irq.h>
30
#include <linux/of_mdio.h>
31
#include <linux/netdevice.h>
32
#include <linux/gpio/consumer.h>
33
#include <linux/phy.h>
34
#include <net/dsa.h>
35
#include <net/switchdev.h>
36

37
#include "mv88e6xxx.h"
38
#include "global1.h"
39
#include "global2.h"
40
#include "port.h"
41

42
static void assert_reg_lock(struct mv88e6xxx_chip *chip)
43
{
44 45
	if (unlikely(!mutex_is_locked(&chip->reg_lock))) {
		dev_err(chip->dev, "Switch registers lock not held!\n");
46 47 48 49
		dump_stack();
	}
}

50 51 52 53 54 55 56 57 58 59
/* The switch ADDR[4:1] configuration pins define the chip SMI device address
 * (ADDR[0] is always zero, thus only even SMI addresses can be strapped).
 *
 * When ADDR is all zero, the chip uses Single-chip Addressing Mode, assuming it
 * is the only device connected to the SMI master. In this mode it responds to
 * all 32 possible SMI addresses, and thus maps directly the internal devices.
 *
 * When ADDR is non-zero, the chip uses Multi-chip Addressing Mode, allowing
 * multiple devices to share the SMI interface. In this mode it responds to only
 * 2 registers, used to indirectly access the internal SMI devices.
60
 */
61

62
static int mv88e6xxx_smi_read(struct mv88e6xxx_chip *chip,
63 64
			      int addr, int reg, u16 *val)
{
65
	if (!chip->smi_ops)
66 67
		return -EOPNOTSUPP;

68
	return chip->smi_ops->read(chip, addr, reg, val);
69 70
}

71
static int mv88e6xxx_smi_write(struct mv88e6xxx_chip *chip,
72 73
			       int addr, int reg, u16 val)
{
74
	if (!chip->smi_ops)
75 76
		return -EOPNOTSUPP;

77
	return chip->smi_ops->write(chip, addr, reg, val);
78 79
}

80
static int mv88e6xxx_smi_single_chip_read(struct mv88e6xxx_chip *chip,
81 82 83 84
					  int addr, int reg, u16 *val)
{
	int ret;

85
	ret = mdiobus_read_nested(chip->bus, addr, reg);
86 87 88 89 90 91 92 93
	if (ret < 0)
		return ret;

	*val = ret & 0xffff;

	return 0;
}

94
static int mv88e6xxx_smi_single_chip_write(struct mv88e6xxx_chip *chip,
95 96 97 98
					   int addr, int reg, u16 val)
{
	int ret;

99
	ret = mdiobus_write_nested(chip->bus, addr, reg, val);
100 101 102 103 104 105
	if (ret < 0)
		return ret;

	return 0;
}

106
static const struct mv88e6xxx_bus_ops mv88e6xxx_smi_single_chip_ops = {
107 108 109 110
	.read = mv88e6xxx_smi_single_chip_read,
	.write = mv88e6xxx_smi_single_chip_write,
};

111
static int mv88e6xxx_smi_multi_chip_wait(struct mv88e6xxx_chip *chip)
112 113 114 115 116
{
	int ret;
	int i;

	for (i = 0; i < 16; i++) {
117
		ret = mdiobus_read_nested(chip->bus, chip->sw_addr, SMI_CMD);
118 119 120
		if (ret < 0)
			return ret;

121
		if ((ret & SMI_CMD_BUSY) == 0)
122 123 124 125 126 127
			return 0;
	}

	return -ETIMEDOUT;
}

128
static int mv88e6xxx_smi_multi_chip_read(struct mv88e6xxx_chip *chip,
129
					 int addr, int reg, u16 *val)
130 131 132
{
	int ret;

133
	/* Wait for the bus to become free. */
134
	ret = mv88e6xxx_smi_multi_chip_wait(chip);
135 136 137
	if (ret < 0)
		return ret;

138
	/* Transmit the read command. */
139
	ret = mdiobus_write_nested(chip->bus, chip->sw_addr, SMI_CMD,
140
				   SMI_CMD_OP_22_READ | (addr << 5) | reg);
141 142 143
	if (ret < 0)
		return ret;

144
	/* Wait for the read command to complete. */
145
	ret = mv88e6xxx_smi_multi_chip_wait(chip);
146 147 148
	if (ret < 0)
		return ret;

149
	/* Read the data. */
150
	ret = mdiobus_read_nested(chip->bus, chip->sw_addr, SMI_DATA);
151 152 153
	if (ret < 0)
		return ret;

154
	*val = ret & 0xffff;
155

156
	return 0;
157 158
}

159
static int mv88e6xxx_smi_multi_chip_write(struct mv88e6xxx_chip *chip,
160
					  int addr, int reg, u16 val)
161 162 163
{
	int ret;

164
	/* Wait for the bus to become free. */
165
	ret = mv88e6xxx_smi_multi_chip_wait(chip);
166 167 168
	if (ret < 0)
		return ret;

169
	/* Transmit the data to write. */
170
	ret = mdiobus_write_nested(chip->bus, chip->sw_addr, SMI_DATA, val);
171 172 173
	if (ret < 0)
		return ret;

174
	/* Transmit the write command. */
175
	ret = mdiobus_write_nested(chip->bus, chip->sw_addr, SMI_CMD,
176
				   SMI_CMD_OP_22_WRITE | (addr << 5) | reg);
177 178 179
	if (ret < 0)
		return ret;

180
	/* Wait for the write command to complete. */
181
	ret = mv88e6xxx_smi_multi_chip_wait(chip);
182 183 184 185 186 187
	if (ret < 0)
		return ret;

	return 0;
}

188
static const struct mv88e6xxx_bus_ops mv88e6xxx_smi_multi_chip_ops = {
189 190 191 192
	.read = mv88e6xxx_smi_multi_chip_read,
	.write = mv88e6xxx_smi_multi_chip_write,
};

193
int mv88e6xxx_read(struct mv88e6xxx_chip *chip, int addr, int reg, u16 *val)
194 195 196
{
	int err;

197
	assert_reg_lock(chip);
198

199
	err = mv88e6xxx_smi_read(chip, addr, reg, val);
200 201 202
	if (err)
		return err;

203
	dev_dbg(chip->dev, "<- addr: 0x%.2x reg: 0x%.2x val: 0x%.4x\n",
204 205 206 207 208
		addr, reg, *val);

	return 0;
}

209
int mv88e6xxx_write(struct mv88e6xxx_chip *chip, int addr, int reg, u16 val)
210
{
211 212
	int err;

213
	assert_reg_lock(chip);
214

215
	err = mv88e6xxx_smi_write(chip, addr, reg, val);
216 217 218
	if (err)
		return err;

219
	dev_dbg(chip->dev, "-> addr: 0x%.2x reg: 0x%.2x val: 0x%.4x\n",
220 221
		addr, reg, val);

222 223 224
	return 0;
}

225 226 227 228 229
static int mv88e6xxx_phy_read(struct mv88e6xxx_chip *chip, int phy,
			      int reg, u16 *val)
{
	int addr = phy; /* PHY devices addresses start at 0x0 */

230
	if (!chip->info->ops->phy_read)
231 232
		return -EOPNOTSUPP;

233
	return chip->info->ops->phy_read(chip, addr, reg, val);
234 235 236 237 238 239 240
}

static int mv88e6xxx_phy_write(struct mv88e6xxx_chip *chip, int phy,
			       int reg, u16 val)
{
	int addr = phy; /* PHY devices addresses start at 0x0 */

241
	if (!chip->info->ops->phy_write)
242 243
		return -EOPNOTSUPP;

244
	return chip->info->ops->phy_write(chip, addr, reg, val);
245 246
}

247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314
static int mv88e6xxx_phy_page_get(struct mv88e6xxx_chip *chip, int phy, u8 page)
{
	if (!mv88e6xxx_has(chip, MV88E6XXX_FLAG_PHY_PAGE))
		return -EOPNOTSUPP;

	return mv88e6xxx_phy_write(chip, phy, PHY_PAGE, page);
}

static void mv88e6xxx_phy_page_put(struct mv88e6xxx_chip *chip, int phy)
{
	int err;

	/* Restore PHY page Copper 0x0 for access via the registered MDIO bus */
	err = mv88e6xxx_phy_write(chip, phy, PHY_PAGE, PHY_PAGE_COPPER);
	if (unlikely(err)) {
		dev_err(chip->dev, "failed to restore PHY %d page Copper (%d)\n",
			phy, err);
	}
}

static int mv88e6xxx_phy_page_read(struct mv88e6xxx_chip *chip, int phy,
				   u8 page, int reg, u16 *val)
{
	int err;

	/* There is no paging for registers 22 */
	if (reg == PHY_PAGE)
		return -EINVAL;

	err = mv88e6xxx_phy_page_get(chip, phy, page);
	if (!err) {
		err = mv88e6xxx_phy_read(chip, phy, reg, val);
		mv88e6xxx_phy_page_put(chip, phy);
	}

	return err;
}

static int mv88e6xxx_phy_page_write(struct mv88e6xxx_chip *chip, int phy,
				    u8 page, int reg, u16 val)
{
	int err;

	/* There is no paging for registers 22 */
	if (reg == PHY_PAGE)
		return -EINVAL;

	err = mv88e6xxx_phy_page_get(chip, phy, page);
	if (!err) {
		err = mv88e6xxx_phy_write(chip, phy, PHY_PAGE, page);
		mv88e6xxx_phy_page_put(chip, phy);
	}

	return err;
}

static int mv88e6xxx_serdes_read(struct mv88e6xxx_chip *chip, int reg, u16 *val)
{
	return mv88e6xxx_phy_page_read(chip, ADDR_SERDES, SERDES_PAGE_FIBER,
				       reg, val);
}

static int mv88e6xxx_serdes_write(struct mv88e6xxx_chip *chip, int reg, u16 val)
{
	return mv88e6xxx_phy_page_write(chip, ADDR_SERDES, SERDES_PAGE_FIBER,
					reg, val);
}

315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472
static void mv88e6xxx_g1_irq_mask(struct irq_data *d)
{
	struct mv88e6xxx_chip *chip = irq_data_get_irq_chip_data(d);
	unsigned int n = d->hwirq;

	chip->g1_irq.masked |= (1 << n);
}

static void mv88e6xxx_g1_irq_unmask(struct irq_data *d)
{
	struct mv88e6xxx_chip *chip = irq_data_get_irq_chip_data(d);
	unsigned int n = d->hwirq;

	chip->g1_irq.masked &= ~(1 << n);
}

static irqreturn_t mv88e6xxx_g1_irq_thread_fn(int irq, void *dev_id)
{
	struct mv88e6xxx_chip *chip = dev_id;
	unsigned int nhandled = 0;
	unsigned int sub_irq;
	unsigned int n;
	u16 reg;
	int err;

	mutex_lock(&chip->reg_lock);
	err = mv88e6xxx_g1_read(chip, GLOBAL_STATUS, &reg);
	mutex_unlock(&chip->reg_lock);

	if (err)
		goto out;

	for (n = 0; n < chip->g1_irq.nirqs; ++n) {
		if (reg & (1 << n)) {
			sub_irq = irq_find_mapping(chip->g1_irq.domain, n);
			handle_nested_irq(sub_irq);
			++nhandled;
		}
	}
out:
	return (nhandled > 0 ? IRQ_HANDLED : IRQ_NONE);
}

static void mv88e6xxx_g1_irq_bus_lock(struct irq_data *d)
{
	struct mv88e6xxx_chip *chip = irq_data_get_irq_chip_data(d);

	mutex_lock(&chip->reg_lock);
}

static void mv88e6xxx_g1_irq_bus_sync_unlock(struct irq_data *d)
{
	struct mv88e6xxx_chip *chip = irq_data_get_irq_chip_data(d);
	u16 mask = GENMASK(chip->g1_irq.nirqs, 0);
	u16 reg;
	int err;

	err = mv88e6xxx_g1_read(chip, GLOBAL_CONTROL, &reg);
	if (err)
		goto out;

	reg &= ~mask;
	reg |= (~chip->g1_irq.masked & mask);

	err = mv88e6xxx_g1_write(chip, GLOBAL_CONTROL, reg);
	if (err)
		goto out;

out:
	mutex_unlock(&chip->reg_lock);
}

static struct irq_chip mv88e6xxx_g1_irq_chip = {
	.name			= "mv88e6xxx-g1",
	.irq_mask		= mv88e6xxx_g1_irq_mask,
	.irq_unmask		= mv88e6xxx_g1_irq_unmask,
	.irq_bus_lock		= mv88e6xxx_g1_irq_bus_lock,
	.irq_bus_sync_unlock	= mv88e6xxx_g1_irq_bus_sync_unlock,
};

static int mv88e6xxx_g1_irq_domain_map(struct irq_domain *d,
				       unsigned int irq,
				       irq_hw_number_t hwirq)
{
	struct mv88e6xxx_chip *chip = d->host_data;

	irq_set_chip_data(irq, d->host_data);
	irq_set_chip_and_handler(irq, &chip->g1_irq.chip, handle_level_irq);
	irq_set_noprobe(irq);

	return 0;
}

static const struct irq_domain_ops mv88e6xxx_g1_irq_domain_ops = {
	.map	= mv88e6xxx_g1_irq_domain_map,
	.xlate	= irq_domain_xlate_twocell,
};

static void mv88e6xxx_g1_irq_free(struct mv88e6xxx_chip *chip)
{
	int irq, virq;

	for (irq = 0; irq < 16; irq++) {
		virq = irq_find_mapping(chip->g2_irq.domain, irq);
		irq_dispose_mapping(virq);
	}

	irq_domain_remove(chip->g2_irq.domain);
}

static int mv88e6xxx_g1_irq_setup(struct mv88e6xxx_chip *chip)
{
	int err, irq;
	u16 reg;

	chip->g1_irq.nirqs = chip->info->g1_irqs;
	chip->g1_irq.domain = irq_domain_add_simple(
		NULL, chip->g1_irq.nirqs, 0,
		&mv88e6xxx_g1_irq_domain_ops, chip);
	if (!chip->g1_irq.domain)
		return -ENOMEM;

	for (irq = 0; irq < chip->g1_irq.nirqs; irq++)
		irq_create_mapping(chip->g1_irq.domain, irq);

	chip->g1_irq.chip = mv88e6xxx_g1_irq_chip;
	chip->g1_irq.masked = ~0;

	err = mv88e6xxx_g1_read(chip, GLOBAL_CONTROL, &reg);
	if (err)
		goto out;

	reg &= ~GENMASK(chip->g1_irq.nirqs, 0);

	err = mv88e6xxx_g1_write(chip, GLOBAL_CONTROL, reg);
	if (err)
		goto out;

	/* Reading the interrupt status clears (most of) them */
	err = mv88e6xxx_g1_read(chip, GLOBAL_STATUS, &reg);
	if (err)
		goto out;

	err = request_threaded_irq(chip->irq, NULL,
				   mv88e6xxx_g1_irq_thread_fn,
				   IRQF_ONESHOT | IRQF_TRIGGER_FALLING,
				   dev_name(chip->dev), chip);
	if (err)
		goto out;

	return 0;

out:
	mv88e6xxx_g1_irq_free(chip);

	return err;
}

473
int mv88e6xxx_wait(struct mv88e6xxx_chip *chip, int addr, int reg, u16 mask)
474
{
475
	int i;
476

477
	for (i = 0; i < 16; i++) {
478 479 480 481 482 483 484 485 486 487 488 489 490
		u16 val;
		int err;

		err = mv88e6xxx_read(chip, addr, reg, &val);
		if (err)
			return err;

		if (!(val & mask))
			return 0;

		usleep_range(1000, 2000);
	}

491
	dev_err(chip->dev, "Timeout while waiting for switch\n");
492 493 494
	return -ETIMEDOUT;
}

495
/* Indirect write to single pointer-data register with an Update bit */
496
int mv88e6xxx_update(struct mv88e6xxx_chip *chip, int addr, int reg, u16 update)
497 498
{
	u16 val;
499
	int err;
500 501

	/* Wait until the previous operation is completed */
502 503 504
	err = mv88e6xxx_wait(chip, addr, reg, BIT(15));
	if (err)
		return err;
505 506 507 508 509 510 511

	/* Set the Update bit to trigger a write operation */
	val = BIT(15) | update;

	return mv88e6xxx_write(chip, addr, reg, val);
}

512
static int mv88e6xxx_ppu_disable(struct mv88e6xxx_chip *chip)
513 514
{
	u16 val;
515
	int i, err;
516

517
	err = mv88e6xxx_g1_read(chip, GLOBAL_CONTROL, &val);
518 519 520
	if (err)
		return err;

521 522 523 524
	err = mv88e6xxx_g1_write(chip, GLOBAL_CONTROL,
				 val & ~GLOBAL_CONTROL_PPU_ENABLE);
	if (err)
		return err;
525

526
	for (i = 0; i < 16; i++) {
527 528 529
		err = mv88e6xxx_g1_read(chip, GLOBAL_STATUS, &val);
		if (err)
			return err;
530

531
		usleep_range(1000, 2000);
532
		if ((val & GLOBAL_STATUS_PPU_MASK) != GLOBAL_STATUS_PPU_POLLING)
533
			return 0;
534 535 536 537 538
	}

	return -ETIMEDOUT;
}

539
static int mv88e6xxx_ppu_enable(struct mv88e6xxx_chip *chip)
540
{
541 542
	u16 val;
	int i, err;
543

544 545 546
	err = mv88e6xxx_g1_read(chip, GLOBAL_CONTROL, &val);
	if (err)
		return err;
547

548 549
	err = mv88e6xxx_g1_write(chip, GLOBAL_CONTROL,
				 val | GLOBAL_CONTROL_PPU_ENABLE);
550 551
	if (err)
		return err;
552

553
	for (i = 0; i < 16; i++) {
554 555 556
		err = mv88e6xxx_g1_read(chip, GLOBAL_STATUS, &val);
		if (err)
			return err;
557

558
		usleep_range(1000, 2000);
559
		if ((val & GLOBAL_STATUS_PPU_MASK) == GLOBAL_STATUS_PPU_POLLING)
560
			return 0;
561 562 563 564 565 566 567
	}

	return -ETIMEDOUT;
}

static void mv88e6xxx_ppu_reenable_work(struct work_struct *ugly)
{
568
	struct mv88e6xxx_chip *chip;
569

570
	chip = container_of(ugly, struct mv88e6xxx_chip, ppu_work);
571

572
	mutex_lock(&chip->reg_lock);
573

574 575 576 577
	if (mutex_trylock(&chip->ppu_mutex)) {
		if (mv88e6xxx_ppu_enable(chip) == 0)
			chip->ppu_disabled = 0;
		mutex_unlock(&chip->ppu_mutex);
578
	}
579

580
	mutex_unlock(&chip->reg_lock);
581 582 583 584
}

static void mv88e6xxx_ppu_reenable_timer(unsigned long _ps)
{
585
	struct mv88e6xxx_chip *chip = (void *)_ps;
586

587
	schedule_work(&chip->ppu_work);
588 589
}

590
static int mv88e6xxx_ppu_access_get(struct mv88e6xxx_chip *chip)
591 592 593
{
	int ret;

594
	mutex_lock(&chip->ppu_mutex);
595

596
	/* If the PHY polling unit is enabled, disable it so that
597 598 599 600
	 * we can access the PHY registers.  If it was already
	 * disabled, cancel the timer that is going to re-enable
	 * it.
	 */
601 602
	if (!chip->ppu_disabled) {
		ret = mv88e6xxx_ppu_disable(chip);
603
		if (ret < 0) {
604
			mutex_unlock(&chip->ppu_mutex);
605 606
			return ret;
		}
607
		chip->ppu_disabled = 1;
608
	} else {
609
		del_timer(&chip->ppu_timer);
610
		ret = 0;
611 612 613 614 615
	}

	return ret;
}

616
static void mv88e6xxx_ppu_access_put(struct mv88e6xxx_chip *chip)
617
{
618
	/* Schedule a timer to re-enable the PHY polling unit. */
619 620
	mod_timer(&chip->ppu_timer, jiffies + msecs_to_jiffies(10));
	mutex_unlock(&chip->ppu_mutex);
621 622
}

623
static void mv88e6xxx_ppu_state_init(struct mv88e6xxx_chip *chip)
624
{
625 626
	mutex_init(&chip->ppu_mutex);
	INIT_WORK(&chip->ppu_work, mv88e6xxx_ppu_reenable_work);
627 628
	setup_timer(&chip->ppu_timer, mv88e6xxx_ppu_reenable_timer,
		    (unsigned long)chip);
629 630
}

631 632 633 634 635
static void mv88e6xxx_ppu_state_destroy(struct mv88e6xxx_chip *chip)
{
	del_timer_sync(&chip->ppu_timer);
}

636 637
static int mv88e6xxx_phy_ppu_read(struct mv88e6xxx_chip *chip, int addr,
				  int reg, u16 *val)
638
{
639
	int err;
640

641 642 643
	err = mv88e6xxx_ppu_access_get(chip);
	if (!err) {
		err = mv88e6xxx_read(chip, addr, reg, val);
644
		mv88e6xxx_ppu_access_put(chip);
645 646
	}

647
	return err;
648 649
}

650 651
static int mv88e6xxx_phy_ppu_write(struct mv88e6xxx_chip *chip, int addr,
				   int reg, u16 val)
652
{
653
	int err;
654

655 656 657
	err = mv88e6xxx_ppu_access_get(chip);
	if (!err) {
		err = mv88e6xxx_write(chip, addr, reg, val);
658
		mv88e6xxx_ppu_access_put(chip);
659 660
	}

661
	return err;
662 663
}

664
static bool mv88e6xxx_6065_family(struct mv88e6xxx_chip *chip)
665
{
666
	return chip->info->family == MV88E6XXX_FAMILY_6065;
667 668
}

669
static bool mv88e6xxx_6095_family(struct mv88e6xxx_chip *chip)
670
{
671
	return chip->info->family == MV88E6XXX_FAMILY_6095;
672 673
}

674
static bool mv88e6xxx_6097_family(struct mv88e6xxx_chip *chip)
675
{
676
	return chip->info->family == MV88E6XXX_FAMILY_6097;
677 678
}

679
static bool mv88e6xxx_6165_family(struct mv88e6xxx_chip *chip)
680
{
681
	return chip->info->family == MV88E6XXX_FAMILY_6165;
682 683
}

684
static bool mv88e6xxx_6185_family(struct mv88e6xxx_chip *chip)
685
{
686
	return chip->info->family == MV88E6XXX_FAMILY_6185;
687 688
}

689
static bool mv88e6xxx_6320_family(struct mv88e6xxx_chip *chip)
690
{
691
	return chip->info->family == MV88E6XXX_FAMILY_6320;
692 693
}

694
static bool mv88e6xxx_6351_family(struct mv88e6xxx_chip *chip)
695
{
696
	return chip->info->family == MV88E6XXX_FAMILY_6351;
697 698
}

699
static bool mv88e6xxx_6352_family(struct mv88e6xxx_chip *chip)
700
{
701
	return chip->info->family == MV88E6XXX_FAMILY_6352;
702 703
}

704 705 706 707
/* We expect the switch to perform auto negotiation if there is a real
 * phy. However, in the case of a fixed link phy, we force the port
 * settings from the fixed link settings.
 */
708 709
static void mv88e6xxx_adjust_link(struct dsa_switch *ds, int port,
				  struct phy_device *phydev)
710
{
V
Vivien Didelot 已提交
711
	struct mv88e6xxx_chip *chip = ds->priv;
712 713
	u16 reg;
	int err;
714 715 716 717

	if (!phy_is_pseudo_fixed_link(phydev))
		return;

718
	mutex_lock(&chip->reg_lock);
719

720 721
	err = mv88e6xxx_port_read(chip, port, PORT_PCS_CTRL, &reg);
	if (err)
722 723
		goto out;

724 725 726 727 728
	reg &= ~(PORT_PCS_CTRL_LINK_UP |
		 PORT_PCS_CTRL_FORCE_LINK |
		 PORT_PCS_CTRL_DUPLEX_FULL |
		 PORT_PCS_CTRL_FORCE_DUPLEX |
		 PORT_PCS_CTRL_UNFORCED);
729 730 731

	reg |= PORT_PCS_CTRL_FORCE_LINK;
	if (phydev->link)
732
		reg |= PORT_PCS_CTRL_LINK_UP;
733

734
	if (mv88e6xxx_6065_family(chip) && phydev->speed > SPEED_100)
735 736 737 738 739 740 741 742 743 744 745 746 747 748 749 750 751 752 753 754 755
		goto out;

	switch (phydev->speed) {
	case SPEED_1000:
		reg |= PORT_PCS_CTRL_1000;
		break;
	case SPEED_100:
		reg |= PORT_PCS_CTRL_100;
		break;
	case SPEED_10:
		reg |= PORT_PCS_CTRL_10;
		break;
	default:
		pr_info("Unknown speed");
		goto out;
	}

	reg |= PORT_PCS_CTRL_FORCE_DUPLEX;
	if (phydev->duplex == DUPLEX_FULL)
		reg |= PORT_PCS_CTRL_DUPLEX_FULL;

756
	if ((mv88e6xxx_6352_family(chip) || mv88e6xxx_6351_family(chip)) &&
757
	    (port >= mv88e6xxx_num_ports(chip) - 2)) {
758 759 760 761 762 763 764 765
		if (phydev->interface == PHY_INTERFACE_MODE_RGMII_RXID)
			reg |= PORT_PCS_CTRL_RGMII_DELAY_RXCLK;
		if (phydev->interface == PHY_INTERFACE_MODE_RGMII_TXID)
			reg |= PORT_PCS_CTRL_RGMII_DELAY_TXCLK;
		if (phydev->interface == PHY_INTERFACE_MODE_RGMII_ID)
			reg |= (PORT_PCS_CTRL_RGMII_DELAY_RXCLK |
				PORT_PCS_CTRL_RGMII_DELAY_TXCLK);
	}
766
	mv88e6xxx_port_write(chip, port, PORT_PCS_CTRL, reg);
767 768

out:
769
	mutex_unlock(&chip->reg_lock);
770 771
}

772
static int _mv88e6xxx_stats_wait(struct mv88e6xxx_chip *chip)
773
{
774 775
	u16 val;
	int i, err;
776 777

	for (i = 0; i < 10; i++) {
778 779
		err = mv88e6xxx_g1_read(chip, GLOBAL_STATS_OP, &val);
		if ((val & GLOBAL_STATS_OP_BUSY) == 0)
780 781 782 783 784 785
			return 0;
	}

	return -ETIMEDOUT;
}

786
static int _mv88e6xxx_stats_snapshot(struct mv88e6xxx_chip *chip, int port)
787
{
788
	int err;
789

790
	if (mv88e6xxx_6320_family(chip) || mv88e6xxx_6352_family(chip))
791 792
		port = (port + 1) << 5;

793
	/* Snapshot the hardware statistics counters for this port. */
794 795 796 797 798
	err = mv88e6xxx_g1_write(chip, GLOBAL_STATS_OP,
				 GLOBAL_STATS_OP_CAPTURE_PORT |
				 GLOBAL_STATS_OP_HIST_RX_TX | port);
	if (err)
		return err;
799

800
	/* Wait for the snapshotting to complete. */
801
	return _mv88e6xxx_stats_wait(chip);
802 803
}

804
static void _mv88e6xxx_stats_read(struct mv88e6xxx_chip *chip,
805
				  int stat, u32 *val)
806
{
807 808 809
	u32 value;
	u16 reg;
	int err;
810 811 812

	*val = 0;

813 814 815 816
	err = mv88e6xxx_g1_write(chip, GLOBAL_STATS_OP,
				 GLOBAL_STATS_OP_READ_CAPTURED |
				 GLOBAL_STATS_OP_HIST_RX_TX | stat);
	if (err)
817 818
		return;

819 820
	err = _mv88e6xxx_stats_wait(chip);
	if (err)
821 822
		return;

823 824
	err = mv88e6xxx_g1_read(chip, GLOBAL_STATS_COUNTER_32, &reg);
	if (err)
825 826
		return;

827
	value = reg << 16;
828

829 830
	err = mv88e6xxx_g1_read(chip, GLOBAL_STATS_COUNTER_01, &reg);
	if (err)
831 832
		return;

833
	*val = value | reg;
834 835
}

836
static struct mv88e6xxx_hw_stat mv88e6xxx_hw_stats[] = {
837 838 839 840 841 842 843 844 845 846 847 848 849 850 851 852 853 854 855 856 857 858 859 860 861 862 863 864 865 866 867 868 869 870 871 872 873 874 875 876 877 878 879 880 881 882 883 884 885 886 887 888 889 890 891 892 893 894 895
	{ "in_good_octets",	8, 0x00, BANK0, },
	{ "in_bad_octets",	4, 0x02, BANK0, },
	{ "in_unicast",		4, 0x04, BANK0, },
	{ "in_broadcasts",	4, 0x06, BANK0, },
	{ "in_multicasts",	4, 0x07, BANK0, },
	{ "in_pause",		4, 0x16, BANK0, },
	{ "in_undersize",	4, 0x18, BANK0, },
	{ "in_fragments",	4, 0x19, BANK0, },
	{ "in_oversize",	4, 0x1a, BANK0, },
	{ "in_jabber",		4, 0x1b, BANK0, },
	{ "in_rx_error",	4, 0x1c, BANK0, },
	{ "in_fcs_error",	4, 0x1d, BANK0, },
	{ "out_octets",		8, 0x0e, BANK0, },
	{ "out_unicast",	4, 0x10, BANK0, },
	{ "out_broadcasts",	4, 0x13, BANK0, },
	{ "out_multicasts",	4, 0x12, BANK0, },
	{ "out_pause",		4, 0x15, BANK0, },
	{ "excessive",		4, 0x11, BANK0, },
	{ "collisions",		4, 0x1e, BANK0, },
	{ "deferred",		4, 0x05, BANK0, },
	{ "single",		4, 0x14, BANK0, },
	{ "multiple",		4, 0x17, BANK0, },
	{ "out_fcs_error",	4, 0x03, BANK0, },
	{ "late",		4, 0x1f, BANK0, },
	{ "hist_64bytes",	4, 0x08, BANK0, },
	{ "hist_65_127bytes",	4, 0x09, BANK0, },
	{ "hist_128_255bytes",	4, 0x0a, BANK0, },
	{ "hist_256_511bytes",	4, 0x0b, BANK0, },
	{ "hist_512_1023bytes", 4, 0x0c, BANK0, },
	{ "hist_1024_max_bytes", 4, 0x0d, BANK0, },
	{ "sw_in_discards",	4, 0x10, PORT, },
	{ "sw_in_filtered",	2, 0x12, PORT, },
	{ "sw_out_filtered",	2, 0x13, PORT, },
	{ "in_discards",	4, 0x00 | GLOBAL_STATS_OP_BANK_1, BANK1, },
	{ "in_filtered",	4, 0x01 | GLOBAL_STATS_OP_BANK_1, BANK1, },
	{ "in_accepted",	4, 0x02 | GLOBAL_STATS_OP_BANK_1, BANK1, },
	{ "in_bad_accepted",	4, 0x03 | GLOBAL_STATS_OP_BANK_1, BANK1, },
	{ "in_good_avb_class_a", 4, 0x04 | GLOBAL_STATS_OP_BANK_1, BANK1, },
	{ "in_good_avb_class_b", 4, 0x05 | GLOBAL_STATS_OP_BANK_1, BANK1, },
	{ "in_bad_avb_class_a", 4, 0x06 | GLOBAL_STATS_OP_BANK_1, BANK1, },
	{ "in_bad_avb_class_b", 4, 0x07 | GLOBAL_STATS_OP_BANK_1, BANK1, },
	{ "tcam_counter_0",	4, 0x08 | GLOBAL_STATS_OP_BANK_1, BANK1, },
	{ "tcam_counter_1",	4, 0x09 | GLOBAL_STATS_OP_BANK_1, BANK1, },
	{ "tcam_counter_2",	4, 0x0a | GLOBAL_STATS_OP_BANK_1, BANK1, },
	{ "tcam_counter_3",	4, 0x0b | GLOBAL_STATS_OP_BANK_1, BANK1, },
	{ "in_da_unknown",	4, 0x0e | GLOBAL_STATS_OP_BANK_1, BANK1, },
	{ "in_management",	4, 0x0f | GLOBAL_STATS_OP_BANK_1, BANK1, },
	{ "out_queue_0",	4, 0x10 | GLOBAL_STATS_OP_BANK_1, BANK1, },
	{ "out_queue_1",	4, 0x11 | GLOBAL_STATS_OP_BANK_1, BANK1, },
	{ "out_queue_2",	4, 0x12 | GLOBAL_STATS_OP_BANK_1, BANK1, },
	{ "out_queue_3",	4, 0x13 | GLOBAL_STATS_OP_BANK_1, BANK1, },
	{ "out_queue_4",	4, 0x14 | GLOBAL_STATS_OP_BANK_1, BANK1, },
	{ "out_queue_5",	4, 0x15 | GLOBAL_STATS_OP_BANK_1, BANK1, },
	{ "out_queue_6",	4, 0x16 | GLOBAL_STATS_OP_BANK_1, BANK1, },
	{ "out_queue_7",	4, 0x17 | GLOBAL_STATS_OP_BANK_1, BANK1, },
	{ "out_cut_through",	4, 0x18 | GLOBAL_STATS_OP_BANK_1, BANK1, },
	{ "out_octets_a",	4, 0x1a | GLOBAL_STATS_OP_BANK_1, BANK1, },
	{ "out_octets_b",	4, 0x1b | GLOBAL_STATS_OP_BANK_1, BANK1, },
	{ "out_management",	4, 0x1f | GLOBAL_STATS_OP_BANK_1, BANK1, },
896 897
};

898
static bool mv88e6xxx_has_stat(struct mv88e6xxx_chip *chip,
899
			       struct mv88e6xxx_hw_stat *stat)
900
{
901 902
	switch (stat->type) {
	case BANK0:
903
		return true;
904
	case BANK1:
905
		return mv88e6xxx_6320_family(chip);
906
	case PORT:
907 908 909 910 911 912
		return mv88e6xxx_6095_family(chip) ||
			mv88e6xxx_6185_family(chip) ||
			mv88e6xxx_6097_family(chip) ||
			mv88e6xxx_6165_family(chip) ||
			mv88e6xxx_6351_family(chip) ||
			mv88e6xxx_6352_family(chip);
913
	}
914
	return false;
915 916
}

917
static uint64_t _mv88e6xxx_get_ethtool_stat(struct mv88e6xxx_chip *chip,
918
					    struct mv88e6xxx_hw_stat *s,
919 920 921 922
					    int port)
{
	u32 low;
	u32 high = 0;
923 924
	int err;
	u16 reg;
925 926
	u64 value;

927 928
	switch (s->type) {
	case PORT:
929 930
		err = mv88e6xxx_port_read(chip, port, s->reg, &reg);
		if (err)
931 932
			return UINT64_MAX;

933
		low = reg;
934
		if (s->sizeof_stat == 4) {
935 936
			err = mv88e6xxx_port_read(chip, port, s->reg + 1, &reg);
			if (err)
937
				return UINT64_MAX;
938
			high = reg;
939
		}
940 941 942
		break;
	case BANK0:
	case BANK1:
943
		_mv88e6xxx_stats_read(chip, s->reg, &low);
944
		if (s->sizeof_stat == 8)
945
			_mv88e6xxx_stats_read(chip, s->reg + 1, &high);
946 947 948 949 950
	}
	value = (((u64)high) << 16) | low;
	return value;
}

951 952
static void mv88e6xxx_get_strings(struct dsa_switch *ds, int port,
				  uint8_t *data)
953
{
V
Vivien Didelot 已提交
954
	struct mv88e6xxx_chip *chip = ds->priv;
955 956
	struct mv88e6xxx_hw_stat *stat;
	int i, j;
957

958 959
	for (i = 0, j = 0; i < ARRAY_SIZE(mv88e6xxx_hw_stats); i++) {
		stat = &mv88e6xxx_hw_stats[i];
960
		if (mv88e6xxx_has_stat(chip, stat)) {
961 962 963 964
			memcpy(data + j * ETH_GSTRING_LEN, stat->string,
			       ETH_GSTRING_LEN);
			j++;
		}
965
	}
966 967
}

968
static int mv88e6xxx_get_sset_count(struct dsa_switch *ds)
969
{
V
Vivien Didelot 已提交
970
	struct mv88e6xxx_chip *chip = ds->priv;
971 972 973 974 975
	struct mv88e6xxx_hw_stat *stat;
	int i, j;

	for (i = 0, j = 0; i < ARRAY_SIZE(mv88e6xxx_hw_stats); i++) {
		stat = &mv88e6xxx_hw_stats[i];
976
		if (mv88e6xxx_has_stat(chip, stat))
977 978 979
			j++;
	}
	return j;
980 981
}

982 983
static void mv88e6xxx_get_ethtool_stats(struct dsa_switch *ds, int port,
					uint64_t *data)
984
{
V
Vivien Didelot 已提交
985
	struct mv88e6xxx_chip *chip = ds->priv;
986 987 988 989
	struct mv88e6xxx_hw_stat *stat;
	int ret;
	int i, j;

990
	mutex_lock(&chip->reg_lock);
991

992
	ret = _mv88e6xxx_stats_snapshot(chip, port);
993
	if (ret < 0) {
994
		mutex_unlock(&chip->reg_lock);
995 996 997 998
		return;
	}
	for (i = 0, j = 0; i < ARRAY_SIZE(mv88e6xxx_hw_stats); i++) {
		stat = &mv88e6xxx_hw_stats[i];
999 1000
		if (mv88e6xxx_has_stat(chip, stat)) {
			data[j] = _mv88e6xxx_get_ethtool_stat(chip, stat, port);
1001 1002 1003 1004
			j++;
		}
	}

1005
	mutex_unlock(&chip->reg_lock);
1006 1007
}

1008
static int mv88e6xxx_get_regs_len(struct dsa_switch *ds, int port)
1009 1010 1011 1012
{
	return 32 * sizeof(u16);
}

1013 1014
static void mv88e6xxx_get_regs(struct dsa_switch *ds, int port,
			       struct ethtool_regs *regs, void *_p)
1015
{
V
Vivien Didelot 已提交
1016
	struct mv88e6xxx_chip *chip = ds->priv;
1017 1018
	int err;
	u16 reg;
1019 1020 1021 1022 1023 1024 1025
	u16 *p = _p;
	int i;

	regs->version = 0;

	memset(p, 0xff, 32 * sizeof(u16));

1026
	mutex_lock(&chip->reg_lock);
1027

1028 1029
	for (i = 0; i < 32; i++) {

1030 1031 1032
		err = mv88e6xxx_port_read(chip, port, i, &reg);
		if (!err)
			p[i] = reg;
1033
	}
1034

1035
	mutex_unlock(&chip->reg_lock);
1036 1037
}

1038
static int _mv88e6xxx_atu_wait(struct mv88e6xxx_chip *chip)
1039
{
1040
	return mv88e6xxx_g1_wait(chip, GLOBAL_ATU_OP, GLOBAL_ATU_OP_BUSY);
1041 1042
}

1043 1044
static int mv88e6xxx_get_eee(struct dsa_switch *ds, int port,
			     struct ethtool_eee *e)
1045
{
V
Vivien Didelot 已提交
1046
	struct mv88e6xxx_chip *chip = ds->priv;
1047 1048
	u16 reg;
	int err;
1049

1050
	if (!mv88e6xxx_has(chip, MV88E6XXX_FLAG_EEE))
1051 1052
		return -EOPNOTSUPP;

1053
	mutex_lock(&chip->reg_lock);
1054

1055 1056
	err = mv88e6xxx_phy_read(chip, port, 16, &reg);
	if (err)
1057
		goto out;
1058 1059 1060 1061

	e->eee_enabled = !!(reg & 0x0200);
	e->tx_lpi_enabled = !!(reg & 0x0100);

1062
	err = mv88e6xxx_port_read(chip, port, PORT_STATUS, &reg);
1063
	if (err)
1064
		goto out;
1065

1066
	e->eee_active = !!(reg & PORT_STATUS_EEE);
1067
out:
1068
	mutex_unlock(&chip->reg_lock);
1069 1070

	return err;
1071 1072
}

1073 1074
static int mv88e6xxx_set_eee(struct dsa_switch *ds, int port,
			     struct phy_device *phydev, struct ethtool_eee *e)
1075
{
V
Vivien Didelot 已提交
1076
	struct mv88e6xxx_chip *chip = ds->priv;
1077 1078
	u16 reg;
	int err;
1079

1080
	if (!mv88e6xxx_has(chip, MV88E6XXX_FLAG_EEE))
1081 1082
		return -EOPNOTSUPP;

1083
	mutex_lock(&chip->reg_lock);
1084

1085 1086
	err = mv88e6xxx_phy_read(chip, port, 16, &reg);
	if (err)
1087 1088
		goto out;

1089
	reg &= ~0x0300;
1090 1091 1092 1093 1094
	if (e->eee_enabled)
		reg |= 0x0200;
	if (e->tx_lpi_enabled)
		reg |= 0x0100;

1095
	err = mv88e6xxx_phy_write(chip, port, 16, reg);
1096
out:
1097
	mutex_unlock(&chip->reg_lock);
1098

1099
	return err;
1100 1101
}

1102
static int _mv88e6xxx_atu_cmd(struct mv88e6xxx_chip *chip, u16 fid, u16 cmd)
1103
{
1104 1105
	u16 val;
	int err;
1106

1107
	if (mv88e6xxx_has(chip, MV88E6XXX_FLAG_G1_ATU_FID)) {
1108 1109 1110
		err = mv88e6xxx_g1_write(chip, GLOBAL_ATU_FID, fid);
		if (err)
			return err;
1111
	} else if (mv88e6xxx_num_databases(chip) == 256) {
1112
		/* ATU DBNum[7:4] are located in ATU Control 15:12 */
1113 1114 1115
		err = mv88e6xxx_g1_read(chip, GLOBAL_ATU_CONTROL, &val);
		if (err)
			return err;
1116

1117 1118 1119 1120
		err = mv88e6xxx_g1_write(chip, GLOBAL_ATU_CONTROL,
					 (val & 0xfff) | ((fid << 8) & 0xf000));
		if (err)
			return err;
1121 1122 1123

		/* ATU DBNum[3:0] are located in ATU Operation 3:0 */
		cmd |= fid & 0xf;
1124 1125
	}

1126 1127 1128
	err = mv88e6xxx_g1_write(chip, GLOBAL_ATU_OP, cmd);
	if (err)
		return err;
1129

1130
	return _mv88e6xxx_atu_wait(chip);
1131 1132
}

1133
static int _mv88e6xxx_atu_data_write(struct mv88e6xxx_chip *chip,
1134 1135 1136 1137 1138 1139 1140 1141 1142 1143 1144 1145 1146 1147 1148 1149 1150 1151 1152
				     struct mv88e6xxx_atu_entry *entry)
{
	u16 data = entry->state & GLOBAL_ATU_DATA_STATE_MASK;

	if (entry->state != GLOBAL_ATU_DATA_STATE_UNUSED) {
		unsigned int mask, shift;

		if (entry->trunk) {
			data |= GLOBAL_ATU_DATA_TRUNK;
			mask = GLOBAL_ATU_DATA_TRUNK_ID_MASK;
			shift = GLOBAL_ATU_DATA_TRUNK_ID_SHIFT;
		} else {
			mask = GLOBAL_ATU_DATA_PORT_VECTOR_MASK;
			shift = GLOBAL_ATU_DATA_PORT_VECTOR_SHIFT;
		}

		data |= (entry->portv_trunkid << shift) & mask;
	}

1153
	return mv88e6xxx_g1_write(chip, GLOBAL_ATU_DATA, data);
1154 1155
}

1156
static int _mv88e6xxx_atu_flush_move(struct mv88e6xxx_chip *chip,
1157 1158
				     struct mv88e6xxx_atu_entry *entry,
				     bool static_too)
1159
{
1160 1161
	int op;
	int err;
1162

1163
	err = _mv88e6xxx_atu_wait(chip);
1164 1165
	if (err)
		return err;
1166

1167
	err = _mv88e6xxx_atu_data_write(chip, entry);
1168 1169 1170 1171 1172 1173 1174 1175 1176 1177 1178
	if (err)
		return err;

	if (entry->fid) {
		op = static_too ? GLOBAL_ATU_OP_FLUSH_MOVE_ALL_DB :
			GLOBAL_ATU_OP_FLUSH_MOVE_NON_STATIC_DB;
	} else {
		op = static_too ? GLOBAL_ATU_OP_FLUSH_MOVE_ALL :
			GLOBAL_ATU_OP_FLUSH_MOVE_NON_STATIC;
	}

1179
	return _mv88e6xxx_atu_cmd(chip, entry->fid, op);
1180 1181
}

1182
static int _mv88e6xxx_atu_flush(struct mv88e6xxx_chip *chip,
1183
				u16 fid, bool static_too)
1184 1185 1186 1187 1188
{
	struct mv88e6xxx_atu_entry entry = {
		.fid = fid,
		.state = 0, /* EntryState bits must be 0 */
	};
1189

1190
	return _mv88e6xxx_atu_flush_move(chip, &entry, static_too);
1191 1192
}

1193
static int _mv88e6xxx_atu_move(struct mv88e6xxx_chip *chip, u16 fid,
1194
			       int from_port, int to_port, bool static_too)
1195 1196 1197 1198 1199 1200 1201 1202 1203 1204 1205 1206 1207
{
	struct mv88e6xxx_atu_entry entry = {
		.trunk = false,
		.fid = fid,
	};

	/* EntryState bits must be 0xF */
	entry.state = GLOBAL_ATU_DATA_STATE_MASK;

	/* ToPort and FromPort are respectively in PortVec bits 7:4 and 3:0 */
	entry.portv_trunkid = (to_port & 0x0f) << 4;
	entry.portv_trunkid |= from_port & 0x0f;

1208
	return _mv88e6xxx_atu_flush_move(chip, &entry, static_too);
1209 1210
}

1211
static int _mv88e6xxx_atu_remove(struct mv88e6xxx_chip *chip, u16 fid,
1212
				 int port, bool static_too)
1213 1214
{
	/* Destination port 0xF means remove the entries */
1215
	return _mv88e6xxx_atu_move(chip, fid, port, 0x0f, static_too);
1216 1217
}

1218
static int _mv88e6xxx_port_based_vlan_map(struct mv88e6xxx_chip *chip, int port)
1219
{
1220 1221
	struct net_device *bridge = chip->ports[port].bridge_dev;
	struct dsa_switch *ds = chip->ds;
1222 1223 1224 1225 1226
	u16 output_ports = 0;
	int i;

	/* allow CPU port or DSA link(s) to send frames to every port */
	if (dsa_is_cpu_port(ds, port) || dsa_is_dsa_port(ds, port)) {
1227
		output_ports = ~0;
1228
	} else {
1229
		for (i = 0; i < mv88e6xxx_num_ports(chip); ++i) {
1230
			/* allow sending frames to every group member */
1231
			if (bridge && chip->ports[i].bridge_dev == bridge)
1232 1233 1234 1235 1236 1237 1238 1239 1240 1241
				output_ports |= BIT(i);

			/* allow sending frames to CPU port and DSA link(s) */
			if (dsa_is_cpu_port(ds, i) || dsa_is_dsa_port(ds, i))
				output_ports |= BIT(i);
		}
	}

	/* prevent frames from going back out of the port they came in on */
	output_ports &= ~BIT(port);
1242

1243
	return mv88e6xxx_port_set_vlan_map(chip, port, output_ports);
1244 1245
}

1246 1247
static void mv88e6xxx_port_stp_state_set(struct dsa_switch *ds, int port,
					 u8 state)
1248
{
V
Vivien Didelot 已提交
1249
	struct mv88e6xxx_chip *chip = ds->priv;
1250
	int stp_state;
1251
	int err;
1252 1253 1254

	switch (state) {
	case BR_STATE_DISABLED:
1255
		stp_state = PORT_CONTROL_STATE_DISABLED;
1256 1257 1258
		break;
	case BR_STATE_BLOCKING:
	case BR_STATE_LISTENING:
1259
		stp_state = PORT_CONTROL_STATE_BLOCKING;
1260 1261
		break;
	case BR_STATE_LEARNING:
1262
		stp_state = PORT_CONTROL_STATE_LEARNING;
1263 1264 1265
		break;
	case BR_STATE_FORWARDING:
	default:
1266
		stp_state = PORT_CONTROL_STATE_FORWARDING;
1267 1268 1269
		break;
	}

1270
	mutex_lock(&chip->reg_lock);
1271
	err = mv88e6xxx_port_set_state(chip, port, stp_state);
1272
	mutex_unlock(&chip->reg_lock);
1273 1274

	if (err)
1275
		netdev_err(ds->ports[port].netdev, "failed to update state\n");
1276 1277
}

1278 1279 1280 1281 1282 1283 1284 1285 1286 1287 1288 1289 1290
static void mv88e6xxx_port_fast_age(struct dsa_switch *ds, int port)
{
	struct mv88e6xxx_chip *chip = ds->priv;
	int err;

	mutex_lock(&chip->reg_lock);
	err = _mv88e6xxx_atu_remove(chip, 0, port, false);
	mutex_unlock(&chip->reg_lock);

	if (err)
		netdev_err(ds->ports[port].netdev, "failed to flush ATU\n");
}

1291
static int _mv88e6xxx_port_pvid(struct mv88e6xxx_chip *chip, int port,
1292
				u16 *new, u16 *old)
1293
{
1294
	struct dsa_switch *ds = chip->ds;
1295 1296
	u16 pvid, reg;
	int err;
1297

1298 1299 1300
	err = mv88e6xxx_port_read(chip, port, PORT_DEFAULT_VLAN, &reg);
	if (err)
		return err;
1301

1302
	pvid = reg & PORT_DEFAULT_VLAN_MASK;
1303 1304

	if (new) {
1305 1306
		reg &= ~PORT_DEFAULT_VLAN_MASK;
		reg |= *new & PORT_DEFAULT_VLAN_MASK;
1307

1308 1309 1310
		err = mv88e6xxx_port_write(chip, port, PORT_DEFAULT_VLAN, reg);
		if (err)
			return err;
1311

1312 1313
		netdev_dbg(ds->ports[port].netdev,
			   "DefaultVID %d (was %d)\n", *new, pvid);
1314 1315 1316 1317
	}

	if (old)
		*old = pvid;
1318 1319 1320 1321

	return 0;
}

1322
static int _mv88e6xxx_port_pvid_get(struct mv88e6xxx_chip *chip,
1323
				    int port, u16 *pvid)
1324
{
1325
	return _mv88e6xxx_port_pvid(chip, port, NULL, pvid);
1326 1327
}

1328
static int _mv88e6xxx_port_pvid_set(struct mv88e6xxx_chip *chip,
1329
				    int port, u16 pvid)
1330
{
1331
	return _mv88e6xxx_port_pvid(chip, port, &pvid, NULL);
1332 1333
}

1334
static int _mv88e6xxx_vtu_wait(struct mv88e6xxx_chip *chip)
1335
{
1336
	return mv88e6xxx_g1_wait(chip, GLOBAL_VTU_OP, GLOBAL_VTU_OP_BUSY);
1337 1338
}

1339
static int _mv88e6xxx_vtu_cmd(struct mv88e6xxx_chip *chip, u16 op)
1340
{
1341
	int err;
1342

1343 1344 1345
	err = mv88e6xxx_g1_write(chip, GLOBAL_VTU_OP, op);
	if (err)
		return err;
1346

1347
	return _mv88e6xxx_vtu_wait(chip);
1348 1349
}

1350
static int _mv88e6xxx_vtu_stu_flush(struct mv88e6xxx_chip *chip)
1351 1352 1353
{
	int ret;

1354
	ret = _mv88e6xxx_vtu_wait(chip);
1355 1356 1357
	if (ret < 0)
		return ret;

1358
	return _mv88e6xxx_vtu_cmd(chip, GLOBAL_VTU_OP_FLUSH_ALL);
1359 1360
}

1361
static int _mv88e6xxx_vtu_stu_data_read(struct mv88e6xxx_chip *chip,
1362
					struct mv88e6xxx_vtu_entry *entry,
1363 1364 1365
					unsigned int nibble_offset)
{
	u16 regs[3];
1366
	int i, err;
1367 1368

	for (i = 0; i < 3; ++i) {
1369
		u16 *reg = &regs[i];
1370

1371 1372 1373
		err = mv88e6xxx_g1_read(chip, GLOBAL_VTU_DATA_0_3 + i, reg);
		if (err)
			return err;
1374 1375
	}

1376
	for (i = 0; i < mv88e6xxx_num_ports(chip); ++i) {
1377 1378 1379 1380 1381 1382 1383 1384 1385
		unsigned int shift = (i % 4) * 4 + nibble_offset;
		u16 reg = regs[i / 4];

		entry->data[i] = (reg >> shift) & GLOBAL_VTU_STU_DATA_MASK;
	}

	return 0;
}

1386
static int mv88e6xxx_vtu_data_read(struct mv88e6xxx_chip *chip,
1387
				   struct mv88e6xxx_vtu_entry *entry)
1388
{
1389
	return _mv88e6xxx_vtu_stu_data_read(chip, entry, 0);
1390 1391
}

1392
static int mv88e6xxx_stu_data_read(struct mv88e6xxx_chip *chip,
1393
				   struct mv88e6xxx_vtu_entry *entry)
1394
{
1395
	return _mv88e6xxx_vtu_stu_data_read(chip, entry, 2);
1396 1397
}

1398
static int _mv88e6xxx_vtu_stu_data_write(struct mv88e6xxx_chip *chip,
1399
					 struct mv88e6xxx_vtu_entry *entry,
1400 1401 1402
					 unsigned int nibble_offset)
{
	u16 regs[3] = { 0 };
1403
	int i, err;
1404

1405
	for (i = 0; i < mv88e6xxx_num_ports(chip); ++i) {
1406 1407 1408 1409 1410 1411 1412
		unsigned int shift = (i % 4) * 4 + nibble_offset;
		u8 data = entry->data[i];

		regs[i / 4] |= (data & GLOBAL_VTU_STU_DATA_MASK) << shift;
	}

	for (i = 0; i < 3; ++i) {
1413 1414 1415 1416 1417
		u16 reg = regs[i];

		err = mv88e6xxx_g1_write(chip, GLOBAL_VTU_DATA_0_3 + i, reg);
		if (err)
			return err;
1418 1419 1420 1421 1422
	}

	return 0;
}

1423
static int mv88e6xxx_vtu_data_write(struct mv88e6xxx_chip *chip,
1424
				    struct mv88e6xxx_vtu_entry *entry)
1425
{
1426
	return _mv88e6xxx_vtu_stu_data_write(chip, entry, 0);
1427 1428
}

1429
static int mv88e6xxx_stu_data_write(struct mv88e6xxx_chip *chip,
1430
				    struct mv88e6xxx_vtu_entry *entry)
1431
{
1432
	return _mv88e6xxx_vtu_stu_data_write(chip, entry, 2);
1433 1434
}

1435
static int _mv88e6xxx_vtu_vid_write(struct mv88e6xxx_chip *chip, u16 vid)
1436
{
1437 1438
	return mv88e6xxx_g1_write(chip, GLOBAL_VTU_VID,
				  vid & GLOBAL_VTU_VID_MASK);
1439 1440
}

1441
static int _mv88e6xxx_vtu_getnext(struct mv88e6xxx_chip *chip,
1442
				  struct mv88e6xxx_vtu_entry *entry)
1443
{
1444
	struct mv88e6xxx_vtu_entry next = { 0 };
1445 1446
	u16 val;
	int err;
1447

1448 1449 1450
	err = _mv88e6xxx_vtu_wait(chip);
	if (err)
		return err;
1451

1452 1453 1454
	err = _mv88e6xxx_vtu_cmd(chip, GLOBAL_VTU_OP_VTU_GET_NEXT);
	if (err)
		return err;
1455

1456 1457 1458
	err = mv88e6xxx_g1_read(chip, GLOBAL_VTU_VID, &val);
	if (err)
		return err;
1459

1460 1461
	next.vid = val & GLOBAL_VTU_VID_MASK;
	next.valid = !!(val & GLOBAL_VTU_VID_VALID);
1462 1463

	if (next.valid) {
1464 1465 1466
		err = mv88e6xxx_vtu_data_read(chip, &next);
		if (err)
			return err;
1467

1468
		if (mv88e6xxx_has(chip, MV88E6XXX_FLAG_G1_VTU_FID)) {
1469 1470 1471
			err = mv88e6xxx_g1_read(chip, GLOBAL_VTU_FID, &val);
			if (err)
				return err;
1472

1473
			next.fid = val & GLOBAL_VTU_FID_MASK;
1474
		} else if (mv88e6xxx_num_databases(chip) == 256) {
1475 1476 1477
			/* VTU DBNum[7:4] are located in VTU Operation 11:8, and
			 * VTU DBNum[3:0] are located in VTU Operation 3:0
			 */
1478 1479 1480
			err = mv88e6xxx_g1_read(chip, GLOBAL_VTU_OP, &val);
			if (err)
				return err;
1481

1482 1483
			next.fid = (val & 0xf00) >> 4;
			next.fid |= val & 0xf;
1484
		}
1485

1486
		if (mv88e6xxx_has(chip, MV88E6XXX_FLAG_STU)) {
1487 1488 1489
			err = mv88e6xxx_g1_read(chip, GLOBAL_VTU_SID, &val);
			if (err)
				return err;
1490

1491
			next.sid = val & GLOBAL_VTU_SID_MASK;
1492 1493 1494 1495 1496 1497 1498
		}
	}

	*entry = next;
	return 0;
}

1499 1500 1501
static int mv88e6xxx_port_vlan_dump(struct dsa_switch *ds, int port,
				    struct switchdev_obj_port_vlan *vlan,
				    int (*cb)(struct switchdev_obj *obj))
1502
{
V
Vivien Didelot 已提交
1503
	struct mv88e6xxx_chip *chip = ds->priv;
1504
	struct mv88e6xxx_vtu_entry next;
1505 1506 1507
	u16 pvid;
	int err;

1508
	if (!mv88e6xxx_has(chip, MV88E6XXX_FLAG_VTU))
1509 1510
		return -EOPNOTSUPP;

1511
	mutex_lock(&chip->reg_lock);
1512

1513
	err = _mv88e6xxx_port_pvid_get(chip, port, &pvid);
1514 1515 1516
	if (err)
		goto unlock;

1517
	err = _mv88e6xxx_vtu_vid_write(chip, GLOBAL_VTU_VID_MASK);
1518 1519 1520 1521
	if (err)
		goto unlock;

	do {
1522
		err = _mv88e6xxx_vtu_getnext(chip, &next);
1523 1524 1525 1526 1527 1528 1529 1530 1531 1532
		if (err)
			break;

		if (!next.valid)
			break;

		if (next.data[port] == GLOBAL_VTU_DATA_MEMBER_TAG_NON_MEMBER)
			continue;

		/* reinit and dump this VLAN obj */
1533 1534
		vlan->vid_begin = next.vid;
		vlan->vid_end = next.vid;
1535 1536 1537 1538 1539 1540 1541 1542 1543 1544 1545 1546 1547 1548
		vlan->flags = 0;

		if (next.data[port] == GLOBAL_VTU_DATA_MEMBER_TAG_UNTAGGED)
			vlan->flags |= BRIDGE_VLAN_INFO_UNTAGGED;

		if (next.vid == pvid)
			vlan->flags |= BRIDGE_VLAN_INFO_PVID;

		err = cb(&vlan->obj);
		if (err)
			break;
	} while (next.vid < GLOBAL_VTU_VID_MASK);

unlock:
1549
	mutex_unlock(&chip->reg_lock);
1550 1551 1552 1553

	return err;
}

1554
static int _mv88e6xxx_vtu_loadpurge(struct mv88e6xxx_chip *chip,
1555
				    struct mv88e6xxx_vtu_entry *entry)
1556
{
1557
	u16 op = GLOBAL_VTU_OP_VTU_LOAD_PURGE;
1558
	u16 reg = 0;
1559
	int err;
1560

1561 1562 1563
	err = _mv88e6xxx_vtu_wait(chip);
	if (err)
		return err;
1564 1565 1566 1567 1568

	if (!entry->valid)
		goto loadpurge;

	/* Write port member tags */
1569 1570 1571
	err = mv88e6xxx_vtu_data_write(chip, entry);
	if (err)
		return err;
1572

1573
	if (mv88e6xxx_has(chip, MV88E6XXX_FLAG_STU)) {
1574
		reg = entry->sid & GLOBAL_VTU_SID_MASK;
1575 1576 1577
		err = mv88e6xxx_g1_write(chip, GLOBAL_VTU_SID, reg);
		if (err)
			return err;
1578
	}
1579

1580
	if (mv88e6xxx_has(chip, MV88E6XXX_FLAG_G1_VTU_FID)) {
1581
		reg = entry->fid & GLOBAL_VTU_FID_MASK;
1582 1583 1584
		err = mv88e6xxx_g1_write(chip, GLOBAL_VTU_FID, reg);
		if (err)
			return err;
1585
	} else if (mv88e6xxx_num_databases(chip) == 256) {
1586 1587 1588 1589 1590
		/* VTU DBNum[7:4] are located in VTU Operation 11:8, and
		 * VTU DBNum[3:0] are located in VTU Operation 3:0
		 */
		op |= (entry->fid & 0xf0) << 8;
		op |= entry->fid & 0xf;
1591 1592 1593 1594 1595
	}

	reg = GLOBAL_VTU_VID_VALID;
loadpurge:
	reg |= entry->vid & GLOBAL_VTU_VID_MASK;
1596 1597 1598
	err = mv88e6xxx_g1_write(chip, GLOBAL_VTU_VID, reg);
	if (err)
		return err;
1599

1600
	return _mv88e6xxx_vtu_cmd(chip, op);
1601 1602
}

1603
static int _mv88e6xxx_stu_getnext(struct mv88e6xxx_chip *chip, u8 sid,
1604
				  struct mv88e6xxx_vtu_entry *entry)
1605
{
1606
	struct mv88e6xxx_vtu_entry next = { 0 };
1607 1608
	u16 val;
	int err;
1609

1610 1611 1612
	err = _mv88e6xxx_vtu_wait(chip);
	if (err)
		return err;
1613

1614 1615 1616 1617
	err = mv88e6xxx_g1_write(chip, GLOBAL_VTU_SID,
				 sid & GLOBAL_VTU_SID_MASK);
	if (err)
		return err;
1618

1619 1620 1621
	err = _mv88e6xxx_vtu_cmd(chip, GLOBAL_VTU_OP_STU_GET_NEXT);
	if (err)
		return err;
1622

1623 1624 1625
	err = mv88e6xxx_g1_read(chip, GLOBAL_VTU_SID, &val);
	if (err)
		return err;
1626

1627
	next.sid = val & GLOBAL_VTU_SID_MASK;
1628

1629 1630 1631
	err = mv88e6xxx_g1_read(chip, GLOBAL_VTU_VID, &val);
	if (err)
		return err;
1632

1633
	next.valid = !!(val & GLOBAL_VTU_VID_VALID);
1634 1635

	if (next.valid) {
1636 1637 1638
		err = mv88e6xxx_stu_data_read(chip, &next);
		if (err)
			return err;
1639 1640 1641 1642 1643 1644
	}

	*entry = next;
	return 0;
}

1645
static int _mv88e6xxx_stu_loadpurge(struct mv88e6xxx_chip *chip,
1646
				    struct mv88e6xxx_vtu_entry *entry)
1647 1648
{
	u16 reg = 0;
1649
	int err;
1650

1651 1652 1653
	err = _mv88e6xxx_vtu_wait(chip);
	if (err)
		return err;
1654 1655 1656 1657 1658

	if (!entry->valid)
		goto loadpurge;

	/* Write port states */
1659 1660 1661
	err = mv88e6xxx_stu_data_write(chip, entry);
	if (err)
		return err;
1662 1663 1664

	reg = GLOBAL_VTU_VID_VALID;
loadpurge:
1665 1666 1667
	err = mv88e6xxx_g1_write(chip, GLOBAL_VTU_VID, reg);
	if (err)
		return err;
1668 1669

	reg = entry->sid & GLOBAL_VTU_SID_MASK;
1670 1671 1672
	err = mv88e6xxx_g1_write(chip, GLOBAL_VTU_SID, reg);
	if (err)
		return err;
1673

1674
	return _mv88e6xxx_vtu_cmd(chip, GLOBAL_VTU_OP_STU_LOAD_PURGE);
1675 1676
}

1677
static int _mv88e6xxx_port_fid(struct mv88e6xxx_chip *chip, int port,
1678
			       u16 *new, u16 *old)
1679
{
1680
	struct dsa_switch *ds = chip->ds;
1681
	u16 upper_mask;
1682
	u16 fid;
1683 1684
	u16 reg;
	int err;
1685

1686
	if (mv88e6xxx_num_databases(chip) == 4096)
1687
		upper_mask = 0xff;
1688
	else if (mv88e6xxx_num_databases(chip) == 256)
1689
		upper_mask = 0xf;
1690 1691 1692
	else
		return -EOPNOTSUPP;

1693
	/* Port's default FID bits 3:0 are located in reg 0x06, offset 12 */
1694 1695 1696
	err = mv88e6xxx_port_read(chip, port, PORT_BASE_VLAN, &reg);
	if (err)
		return err;
1697

1698
	fid = (reg & PORT_BASE_VLAN_FID_3_0_MASK) >> 12;
1699 1700

	if (new) {
1701 1702
		reg &= ~PORT_BASE_VLAN_FID_3_0_MASK;
		reg |= (*new << 12) & PORT_BASE_VLAN_FID_3_0_MASK;
1703

1704 1705 1706
		err = mv88e6xxx_port_write(chip, port, PORT_BASE_VLAN, reg);
		if (err)
			return err;
1707 1708 1709
	}

	/* Port's default FID bits 11:4 are located in reg 0x05, offset 0 */
1710 1711 1712
	err = mv88e6xxx_port_read(chip, port, PORT_CONTROL_1, &reg);
	if (err)
		return err;
1713

1714
	fid |= (reg & upper_mask) << 4;
1715 1716

	if (new) {
1717 1718
		reg &= ~upper_mask;
		reg |= (*new >> 4) & upper_mask;
1719

1720 1721 1722
		err = mv88e6xxx_port_write(chip, port, PORT_CONTROL_1, reg);
		if (err)
			return err;
1723

1724 1725
		netdev_dbg(ds->ports[port].netdev,
			   "FID %d (was %d)\n", *new, fid);
1726 1727 1728 1729 1730 1731 1732 1733
	}

	if (old)
		*old = fid;

	return 0;
}

1734
static int _mv88e6xxx_port_fid_get(struct mv88e6xxx_chip *chip,
1735
				   int port, u16 *fid)
1736
{
1737
	return _mv88e6xxx_port_fid(chip, port, NULL, fid);
1738 1739
}

1740
static int _mv88e6xxx_port_fid_set(struct mv88e6xxx_chip *chip,
1741
				   int port, u16 fid)
1742
{
1743
	return _mv88e6xxx_port_fid(chip, port, &fid, NULL);
1744 1745
}

1746
static int _mv88e6xxx_fid_new(struct mv88e6xxx_chip *chip, u16 *fid)
1747 1748
{
	DECLARE_BITMAP(fid_bitmap, MV88E6XXX_N_FID);
1749
	struct mv88e6xxx_vtu_entry vlan;
1750
	int i, err;
1751 1752 1753

	bitmap_zero(fid_bitmap, MV88E6XXX_N_FID);

1754
	/* Set every FID bit used by the (un)bridged ports */
1755
	for (i = 0; i < mv88e6xxx_num_ports(chip); ++i) {
1756
		err = _mv88e6xxx_port_fid_get(chip, i, fid);
1757 1758 1759 1760 1761 1762
		if (err)
			return err;

		set_bit(*fid, fid_bitmap);
	}

1763
	/* Set every FID bit used by the VLAN entries */
1764
	err = _mv88e6xxx_vtu_vid_write(chip, GLOBAL_VTU_VID_MASK);
1765 1766 1767 1768
	if (err)
		return err;

	do {
1769
		err = _mv88e6xxx_vtu_getnext(chip, &vlan);
1770 1771 1772 1773 1774 1775 1776 1777 1778 1779 1780 1781 1782
		if (err)
			return err;

		if (!vlan.valid)
			break;

		set_bit(vlan.fid, fid_bitmap);
	} while (vlan.vid < GLOBAL_VTU_VID_MASK);

	/* The reset value 0x000 is used to indicate that multiple address
	 * databases are not needed. Return the next positive available.
	 */
	*fid = find_next_zero_bit(fid_bitmap, MV88E6XXX_N_FID, 1);
1783
	if (unlikely(*fid >= mv88e6xxx_num_databases(chip)))
1784 1785 1786
		return -ENOSPC;

	/* Clear the database */
1787
	return _mv88e6xxx_atu_flush(chip, *fid, true);
1788 1789
}

1790
static int _mv88e6xxx_vtu_new(struct mv88e6xxx_chip *chip, u16 vid,
1791
			      struct mv88e6xxx_vtu_entry *entry)
1792
{
1793
	struct dsa_switch *ds = chip->ds;
1794
	struct mv88e6xxx_vtu_entry vlan = {
1795 1796 1797
		.valid = true,
		.vid = vid,
	};
1798 1799
	int i, err;

1800
	err = _mv88e6xxx_fid_new(chip, &vlan.fid);
1801 1802
	if (err)
		return err;
1803

1804
	/* exclude all ports except the CPU and DSA ports */
1805
	for (i = 0; i < mv88e6xxx_num_ports(chip); ++i)
1806 1807 1808
		vlan.data[i] = dsa_is_cpu_port(ds, i) || dsa_is_dsa_port(ds, i)
			? GLOBAL_VTU_DATA_MEMBER_TAG_UNMODIFIED
			: GLOBAL_VTU_DATA_MEMBER_TAG_NON_MEMBER;
1809

1810 1811
	if (mv88e6xxx_6097_family(chip) || mv88e6xxx_6165_family(chip) ||
	    mv88e6xxx_6351_family(chip) || mv88e6xxx_6352_family(chip)) {
1812
		struct mv88e6xxx_vtu_entry vstp;
1813 1814 1815 1816 1817 1818

		/* Adding a VTU entry requires a valid STU entry. As VSTP is not
		 * implemented, only one STU entry is needed to cover all VTU
		 * entries. Thus, validate the SID 0.
		 */
		vlan.sid = 0;
1819
		err = _mv88e6xxx_stu_getnext(chip, GLOBAL_VTU_SID_MASK, &vstp);
1820 1821 1822 1823 1824 1825 1826 1827
		if (err)
			return err;

		if (vstp.sid != vlan.sid || !vstp.valid) {
			memset(&vstp, 0, sizeof(vstp));
			vstp.valid = true;
			vstp.sid = vlan.sid;

1828
			err = _mv88e6xxx_stu_loadpurge(chip, &vstp);
1829 1830 1831 1832 1833 1834 1835 1836 1837
			if (err)
				return err;
		}
	}

	*entry = vlan;
	return 0;
}

1838
static int _mv88e6xxx_vtu_get(struct mv88e6xxx_chip *chip, u16 vid,
1839
			      struct mv88e6xxx_vtu_entry *entry, bool creat)
1840 1841 1842 1843 1844 1845
{
	int err;

	if (!vid)
		return -EINVAL;

1846
	err = _mv88e6xxx_vtu_vid_write(chip, vid - 1);
1847 1848 1849
	if (err)
		return err;

1850
	err = _mv88e6xxx_vtu_getnext(chip, entry);
1851 1852 1853 1854 1855 1856 1857 1858 1859 1860
	if (err)
		return err;

	if (entry->vid != vid || !entry->valid) {
		if (!creat)
			return -EOPNOTSUPP;
		/* -ENOENT would've been more appropriate, but switchdev expects
		 * -EOPNOTSUPP to inform bridge about an eventual software VLAN.
		 */

1861
		err = _mv88e6xxx_vtu_new(chip, vid, entry);
1862 1863 1864 1865 1866
	}

	return err;
}

1867 1868 1869
static int mv88e6xxx_port_check_hw_vlan(struct dsa_switch *ds, int port,
					u16 vid_begin, u16 vid_end)
{
V
Vivien Didelot 已提交
1870
	struct mv88e6xxx_chip *chip = ds->priv;
1871
	struct mv88e6xxx_vtu_entry vlan;
1872 1873 1874 1875 1876
	int i, err;

	if (!vid_begin)
		return -EOPNOTSUPP;

1877
	mutex_lock(&chip->reg_lock);
1878

1879
	err = _mv88e6xxx_vtu_vid_write(chip, vid_begin - 1);
1880 1881 1882 1883
	if (err)
		goto unlock;

	do {
1884
		err = _mv88e6xxx_vtu_getnext(chip, &vlan);
1885 1886 1887 1888 1889 1890 1891 1892 1893
		if (err)
			goto unlock;

		if (!vlan.valid)
			break;

		if (vlan.vid > vid_end)
			break;

1894
		for (i = 0; i < mv88e6xxx_num_ports(chip); ++i) {
1895 1896 1897 1898 1899 1900 1901
			if (dsa_is_dsa_port(ds, i) || dsa_is_cpu_port(ds, i))
				continue;

			if (vlan.data[i] ==
			    GLOBAL_VTU_DATA_MEMBER_TAG_NON_MEMBER)
				continue;

1902 1903
			if (chip->ports[i].bridge_dev ==
			    chip->ports[port].bridge_dev)
1904 1905
				break; /* same bridge, check next VLAN */

1906
			netdev_warn(ds->ports[port].netdev,
1907 1908
				    "hardware VLAN %d already used by %s\n",
				    vlan.vid,
1909
				    netdev_name(chip->ports[i].bridge_dev));
1910 1911 1912 1913 1914 1915
			err = -EOPNOTSUPP;
			goto unlock;
		}
	} while (vlan.vid < vid_end);

unlock:
1916
	mutex_unlock(&chip->reg_lock);
1917 1918 1919 1920

	return err;
}

1921 1922 1923 1924 1925 1926 1927
static const char * const mv88e6xxx_port_8021q_mode_names[] = {
	[PORT_CONTROL_2_8021Q_DISABLED] = "Disabled",
	[PORT_CONTROL_2_8021Q_FALLBACK] = "Fallback",
	[PORT_CONTROL_2_8021Q_CHECK] = "Check",
	[PORT_CONTROL_2_8021Q_SECURE] = "Secure",
};

1928 1929
static int mv88e6xxx_port_vlan_filtering(struct dsa_switch *ds, int port,
					 bool vlan_filtering)
1930
{
V
Vivien Didelot 已提交
1931
	struct mv88e6xxx_chip *chip = ds->priv;
1932 1933
	u16 old, new = vlan_filtering ? PORT_CONTROL_2_8021Q_SECURE :
		PORT_CONTROL_2_8021Q_DISABLED;
1934 1935
	u16 reg;
	int err;
1936

1937
	if (!mv88e6xxx_has(chip, MV88E6XXX_FLAG_VTU))
1938 1939
		return -EOPNOTSUPP;

1940
	mutex_lock(&chip->reg_lock);
1941

1942 1943
	err = mv88e6xxx_port_read(chip, port, PORT_CONTROL_2, &reg);
	if (err)
1944 1945
		goto unlock;

1946
	old = reg & PORT_CONTROL_2_8021Q_MASK;
1947

1948
	if (new != old) {
1949 1950
		reg &= ~PORT_CONTROL_2_8021Q_MASK;
		reg |= new & PORT_CONTROL_2_8021Q_MASK;
1951

1952 1953
		err = mv88e6xxx_port_write(chip, port, PORT_CONTROL_2, reg);
		if (err)
1954 1955
			goto unlock;

1956
		netdev_dbg(ds->ports[port].netdev, "802.1Q Mode %s (was %s)\n",
1957 1958 1959
			   mv88e6xxx_port_8021q_mode_names[new],
			   mv88e6xxx_port_8021q_mode_names[old]);
	}
1960

1961
	err = 0;
1962
unlock:
1963
	mutex_unlock(&chip->reg_lock);
1964

1965
	return err;
1966 1967
}

1968 1969 1970 1971
static int
mv88e6xxx_port_vlan_prepare(struct dsa_switch *ds, int port,
			    const struct switchdev_obj_port_vlan *vlan,
			    struct switchdev_trans *trans)
1972
{
V
Vivien Didelot 已提交
1973
	struct mv88e6xxx_chip *chip = ds->priv;
1974 1975
	int err;

1976
	if (!mv88e6xxx_has(chip, MV88E6XXX_FLAG_VTU))
1977 1978
		return -EOPNOTSUPP;

1979 1980 1981 1982 1983 1984 1985 1986
	/* If the requested port doesn't belong to the same bridge as the VLAN
	 * members, do not support it (yet) and fallback to software VLAN.
	 */
	err = mv88e6xxx_port_check_hw_vlan(ds, port, vlan->vid_begin,
					   vlan->vid_end);
	if (err)
		return err;

1987 1988 1989 1990 1991 1992
	/* We don't need any dynamic resource from the kernel (yet),
	 * so skip the prepare phase.
	 */
	return 0;
}

1993
static int _mv88e6xxx_port_vlan_add(struct mv88e6xxx_chip *chip, int port,
1994
				    u16 vid, bool untagged)
1995
{
1996
	struct mv88e6xxx_vtu_entry vlan;
1997 1998
	int err;

1999
	err = _mv88e6xxx_vtu_get(chip, vid, &vlan, true);
2000
	if (err)
2001
		return err;
2002 2003 2004 2005 2006

	vlan.data[port] = untagged ?
		GLOBAL_VTU_DATA_MEMBER_TAG_UNTAGGED :
		GLOBAL_VTU_DATA_MEMBER_TAG_TAGGED;

2007
	return _mv88e6xxx_vtu_loadpurge(chip, &vlan);
2008 2009
}

2010 2011 2012
static void mv88e6xxx_port_vlan_add(struct dsa_switch *ds, int port,
				    const struct switchdev_obj_port_vlan *vlan,
				    struct switchdev_trans *trans)
2013
{
V
Vivien Didelot 已提交
2014
	struct mv88e6xxx_chip *chip = ds->priv;
2015 2016 2017 2018
	bool untagged = vlan->flags & BRIDGE_VLAN_INFO_UNTAGGED;
	bool pvid = vlan->flags & BRIDGE_VLAN_INFO_PVID;
	u16 vid;

2019
	if (!mv88e6xxx_has(chip, MV88E6XXX_FLAG_VTU))
2020 2021
		return;

2022
	mutex_lock(&chip->reg_lock);
2023

2024
	for (vid = vlan->vid_begin; vid <= vlan->vid_end; ++vid)
2025
		if (_mv88e6xxx_port_vlan_add(chip, port, vid, untagged))
2026 2027
			netdev_err(ds->ports[port].netdev,
				   "failed to add VLAN %d%c\n",
2028
				   vid, untagged ? 'u' : 't');
2029

2030
	if (pvid && _mv88e6xxx_port_pvid_set(chip, port, vlan->vid_end))
2031
		netdev_err(ds->ports[port].netdev, "failed to set PVID %d\n",
2032
			   vlan->vid_end);
2033

2034
	mutex_unlock(&chip->reg_lock);
2035 2036
}

2037
static int _mv88e6xxx_port_vlan_del(struct mv88e6xxx_chip *chip,
2038
				    int port, u16 vid)
2039
{
2040
	struct dsa_switch *ds = chip->ds;
2041
	struct mv88e6xxx_vtu_entry vlan;
2042 2043
	int i, err;

2044
	err = _mv88e6xxx_vtu_get(chip, vid, &vlan, false);
2045
	if (err)
2046
		return err;
2047

2048 2049
	/* Tell switchdev if this VLAN is handled in software */
	if (vlan.data[port] == GLOBAL_VTU_DATA_MEMBER_TAG_NON_MEMBER)
2050
		return -EOPNOTSUPP;
2051 2052 2053 2054

	vlan.data[port] = GLOBAL_VTU_DATA_MEMBER_TAG_NON_MEMBER;

	/* keep the VLAN unless all ports are excluded */
2055
	vlan.valid = false;
2056
	for (i = 0; i < mv88e6xxx_num_ports(chip); ++i) {
2057
		if (dsa_is_cpu_port(ds, i) || dsa_is_dsa_port(ds, i))
2058 2059 2060
			continue;

		if (vlan.data[i] != GLOBAL_VTU_DATA_MEMBER_TAG_NON_MEMBER) {
2061
			vlan.valid = true;
2062 2063 2064 2065
			break;
		}
	}

2066
	err = _mv88e6xxx_vtu_loadpurge(chip, &vlan);
2067 2068 2069
	if (err)
		return err;

2070
	return _mv88e6xxx_atu_remove(chip, vlan.fid, port, false);
2071 2072
}

2073 2074
static int mv88e6xxx_port_vlan_del(struct dsa_switch *ds, int port,
				   const struct switchdev_obj_port_vlan *vlan)
2075
{
V
Vivien Didelot 已提交
2076
	struct mv88e6xxx_chip *chip = ds->priv;
2077 2078 2079
	u16 pvid, vid;
	int err = 0;

2080
	if (!mv88e6xxx_has(chip, MV88E6XXX_FLAG_VTU))
2081 2082
		return -EOPNOTSUPP;

2083
	mutex_lock(&chip->reg_lock);
2084

2085
	err = _mv88e6xxx_port_pvid_get(chip, port, &pvid);
2086 2087 2088
	if (err)
		goto unlock;

2089
	for (vid = vlan->vid_begin; vid <= vlan->vid_end; ++vid) {
2090
		err = _mv88e6xxx_port_vlan_del(chip, port, vid);
2091 2092 2093 2094
		if (err)
			goto unlock;

		if (vid == pvid) {
2095
			err = _mv88e6xxx_port_pvid_set(chip, port, 0);
2096 2097 2098 2099 2100
			if (err)
				goto unlock;
		}
	}

2101
unlock:
2102
	mutex_unlock(&chip->reg_lock);
2103 2104 2105 2106

	return err;
}

2107
static int _mv88e6xxx_atu_mac_write(struct mv88e6xxx_chip *chip,
2108
				    const unsigned char *addr)
2109
{
2110
	int i, err;
2111 2112

	for (i = 0; i < 3; i++) {
2113 2114 2115 2116
		err = mv88e6xxx_g1_write(chip, GLOBAL_ATU_MAC_01 + i,
					 (addr[i * 2] << 8) | addr[i * 2 + 1]);
		if (err)
			return err;
2117 2118 2119 2120 2121
	}

	return 0;
}

2122
static int _mv88e6xxx_atu_mac_read(struct mv88e6xxx_chip *chip,
2123
				   unsigned char *addr)
2124
{
2125 2126
	u16 val;
	int i, err;
2127 2128

	for (i = 0; i < 3; i++) {
2129 2130 2131 2132 2133 2134
		err = mv88e6xxx_g1_read(chip, GLOBAL_ATU_MAC_01 + i, &val);
		if (err)
			return err;

		addr[i * 2] = val >> 8;
		addr[i * 2 + 1] = val & 0xff;
2135 2136 2137 2138 2139
	}

	return 0;
}

2140
static int _mv88e6xxx_atu_load(struct mv88e6xxx_chip *chip,
2141
			       struct mv88e6xxx_atu_entry *entry)
2142
{
2143 2144
	int ret;

2145
	ret = _mv88e6xxx_atu_wait(chip);
2146 2147 2148
	if (ret < 0)
		return ret;

2149
	ret = _mv88e6xxx_atu_mac_write(chip, entry->mac);
2150 2151 2152
	if (ret < 0)
		return ret;

2153
	ret = _mv88e6xxx_atu_data_write(chip, entry);
2154
	if (ret < 0)
2155 2156
		return ret;

2157
	return _mv88e6xxx_atu_cmd(chip, entry->fid, GLOBAL_ATU_OP_LOAD_DB);
2158
}
2159

2160 2161 2162 2163 2164 2165 2166 2167 2168 2169 2170 2171 2172 2173 2174 2175 2176 2177 2178 2179 2180 2181 2182 2183 2184 2185 2186 2187 2188 2189 2190 2191 2192 2193 2194 2195
static int _mv88e6xxx_atu_getnext(struct mv88e6xxx_chip *chip, u16 fid,
				  struct mv88e6xxx_atu_entry *entry);

static int mv88e6xxx_atu_get(struct mv88e6xxx_chip *chip, int fid,
			     const u8 *addr, struct mv88e6xxx_atu_entry *entry)
{
	struct mv88e6xxx_atu_entry next;
	int err;

	eth_broadcast_addr(next.mac);

	err = _mv88e6xxx_atu_mac_write(chip, next.mac);
	if (err)
		return err;

	do {
		err = _mv88e6xxx_atu_getnext(chip, fid, &next);
		if (err)
			return err;

		if (next.state == GLOBAL_ATU_DATA_STATE_UNUSED)
			break;

		if (ether_addr_equal(next.mac, addr)) {
			*entry = next;
			return 0;
		}
	} while (!is_broadcast_ether_addr(next.mac));

	memset(entry, 0, sizeof(*entry));
	entry->fid = fid;
	ether_addr_copy(entry->mac, addr);

	return 0;
}

2196 2197 2198
static int mv88e6xxx_port_db_load_purge(struct mv88e6xxx_chip *chip, int port,
					const unsigned char *addr, u16 vid,
					u8 state)
2199
{
2200
	struct mv88e6xxx_vtu_entry vlan;
2201
	struct mv88e6xxx_atu_entry entry;
2202 2203
	int err;

2204 2205
	/* Null VLAN ID corresponds to the port private database */
	if (vid == 0)
2206
		err = _mv88e6xxx_port_fid_get(chip, port, &vlan.fid);
2207
	else
2208
		err = _mv88e6xxx_vtu_get(chip, vid, &vlan, false);
2209 2210
	if (err)
		return err;
2211

2212 2213 2214 2215 2216 2217 2218 2219 2220 2221 2222 2223
	err = mv88e6xxx_atu_get(chip, vlan.fid, addr, &entry);
	if (err)
		return err;

	/* Purge the ATU entry only if no port is using it anymore */
	if (state == GLOBAL_ATU_DATA_STATE_UNUSED) {
		entry.portv_trunkid &= ~BIT(port);
		if (!entry.portv_trunkid)
			entry.state = GLOBAL_ATU_DATA_STATE_UNUSED;
	} else {
		entry.portv_trunkid |= BIT(port);
		entry.state = state;
2224 2225
	}

2226
	return _mv88e6xxx_atu_load(chip, &entry);
2227 2228
}

2229 2230 2231
static int mv88e6xxx_port_fdb_prepare(struct dsa_switch *ds, int port,
				      const struct switchdev_obj_port_fdb *fdb,
				      struct switchdev_trans *trans)
V
Vivien Didelot 已提交
2232 2233 2234 2235 2236 2237 2238
{
	/* We don't need any dynamic resource from the kernel (yet),
	 * so skip the prepare phase.
	 */
	return 0;
}

2239 2240 2241
static void mv88e6xxx_port_fdb_add(struct dsa_switch *ds, int port,
				   const struct switchdev_obj_port_fdb *fdb,
				   struct switchdev_trans *trans)
2242
{
V
Vivien Didelot 已提交
2243
	struct mv88e6xxx_chip *chip = ds->priv;
2244

2245
	mutex_lock(&chip->reg_lock);
2246 2247 2248
	if (mv88e6xxx_port_db_load_purge(chip, port, fdb->addr, fdb->vid,
					 GLOBAL_ATU_DATA_STATE_UC_STATIC))
		netdev_err(ds->ports[port].netdev, "failed to load unicast MAC address\n");
2249
	mutex_unlock(&chip->reg_lock);
2250 2251
}

2252 2253
static int mv88e6xxx_port_fdb_del(struct dsa_switch *ds, int port,
				  const struct switchdev_obj_port_fdb *fdb)
2254
{
V
Vivien Didelot 已提交
2255
	struct mv88e6xxx_chip *chip = ds->priv;
2256
	int err;
2257

2258
	mutex_lock(&chip->reg_lock);
2259 2260
	err = mv88e6xxx_port_db_load_purge(chip, port, fdb->addr, fdb->vid,
					   GLOBAL_ATU_DATA_STATE_UNUSED);
2261
	mutex_unlock(&chip->reg_lock);
2262

2263
	return err;
2264 2265
}

2266
static int _mv88e6xxx_atu_getnext(struct mv88e6xxx_chip *chip, u16 fid,
2267
				  struct mv88e6xxx_atu_entry *entry)
2268
{
2269
	struct mv88e6xxx_atu_entry next = { 0 };
2270 2271
	u16 val;
	int err;
2272 2273

	next.fid = fid;
2274

2275 2276 2277
	err = _mv88e6xxx_atu_wait(chip);
	if (err)
		return err;
2278

2279 2280 2281
	err = _mv88e6xxx_atu_cmd(chip, fid, GLOBAL_ATU_OP_GET_NEXT_DB);
	if (err)
		return err;
2282

2283 2284 2285
	err = _mv88e6xxx_atu_mac_read(chip, next.mac);
	if (err)
		return err;
2286

2287 2288 2289
	err = mv88e6xxx_g1_read(chip, GLOBAL_ATU_DATA, &val);
	if (err)
		return err;
2290

2291
	next.state = val & GLOBAL_ATU_DATA_STATE_MASK;
2292 2293 2294
	if (next.state != GLOBAL_ATU_DATA_STATE_UNUSED) {
		unsigned int mask, shift;

2295
		if (val & GLOBAL_ATU_DATA_TRUNK) {
2296 2297 2298 2299 2300 2301 2302 2303 2304
			next.trunk = true;
			mask = GLOBAL_ATU_DATA_TRUNK_ID_MASK;
			shift = GLOBAL_ATU_DATA_TRUNK_ID_SHIFT;
		} else {
			next.trunk = false;
			mask = GLOBAL_ATU_DATA_PORT_VECTOR_MASK;
			shift = GLOBAL_ATU_DATA_PORT_VECTOR_SHIFT;
		}

2305
		next.portv_trunkid = (val & mask) >> shift;
2306
	}
2307

2308
	*entry = next;
2309 2310 2311
	return 0;
}

2312 2313 2314 2315
static int mv88e6xxx_port_db_dump_fid(struct mv88e6xxx_chip *chip,
				      u16 fid, u16 vid, int port,
				      struct switchdev_obj *obj,
				      int (*cb)(struct switchdev_obj *obj))
2316 2317 2318 2319 2320 2321
{
	struct mv88e6xxx_atu_entry addr = {
		.mac = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff },
	};
	int err;

2322
	err = _mv88e6xxx_atu_mac_write(chip, addr.mac);
2323 2324 2325 2326
	if (err)
		return err;

	do {
2327
		err = _mv88e6xxx_atu_getnext(chip, fid, &addr);
2328
		if (err)
2329
			return err;
2330 2331 2332 2333

		if (addr.state == GLOBAL_ATU_DATA_STATE_UNUSED)
			break;

2334 2335 2336 2337 2338
		if (addr.trunk || (addr.portv_trunkid & BIT(port)) == 0)
			continue;

		if (obj->id == SWITCHDEV_OBJ_ID_PORT_FDB) {
			struct switchdev_obj_port_fdb *fdb;
2339

2340 2341 2342 2343
			if (!is_unicast_ether_addr(addr.mac))
				continue;

			fdb = SWITCHDEV_OBJ_PORT_FDB(obj);
2344 2345
			fdb->vid = vid;
			ether_addr_copy(fdb->addr, addr.mac);
2346 2347 2348 2349
			if (addr.state == GLOBAL_ATU_DATA_STATE_UC_STATIC)
				fdb->ndm_state = NUD_NOARP;
			else
				fdb->ndm_state = NUD_REACHABLE;
2350 2351 2352 2353 2354 2355 2356 2357 2358
		} else if (obj->id == SWITCHDEV_OBJ_ID_PORT_MDB) {
			struct switchdev_obj_port_mdb *mdb;

			if (!is_multicast_ether_addr(addr.mac))
				continue;

			mdb = SWITCHDEV_OBJ_PORT_MDB(obj);
			mdb->vid = vid;
			ether_addr_copy(mdb->addr, addr.mac);
2359 2360
		} else {
			return -EOPNOTSUPP;
2361
		}
2362 2363 2364 2365

		err = cb(obj);
		if (err)
			return err;
2366 2367 2368 2369 2370
	} while (!is_broadcast_ether_addr(addr.mac));

	return err;
}

2371 2372 2373
static int mv88e6xxx_port_db_dump(struct mv88e6xxx_chip *chip, int port,
				  struct switchdev_obj *obj,
				  int (*cb)(struct switchdev_obj *obj))
2374
{
2375
	struct mv88e6xxx_vtu_entry vlan = {
2376 2377
		.vid = GLOBAL_VTU_VID_MASK, /* all ones */
	};
2378
	u16 fid;
2379 2380
	int err;

2381
	/* Dump port's default Filtering Information Database (VLAN ID 0) */
2382
	err = _mv88e6xxx_port_fid_get(chip, port, &fid);
2383
	if (err)
2384
		return err;
2385

2386
	err = mv88e6xxx_port_db_dump_fid(chip, fid, 0, port, obj, cb);
2387
	if (err)
2388
		return err;
2389

2390
	/* Dump VLANs' Filtering Information Databases */
2391
	err = _mv88e6xxx_vtu_vid_write(chip, vlan.vid);
2392
	if (err)
2393
		return err;
2394 2395

	do {
2396
		err = _mv88e6xxx_vtu_getnext(chip, &vlan);
2397
		if (err)
2398
			return err;
2399 2400 2401 2402

		if (!vlan.valid)
			break;

2403 2404
		err = mv88e6xxx_port_db_dump_fid(chip, vlan.fid, vlan.vid, port,
						 obj, cb);
2405
		if (err)
2406
			return err;
2407 2408
	} while (vlan.vid < GLOBAL_VTU_VID_MASK);

2409 2410 2411 2412 2413 2414 2415
	return err;
}

static int mv88e6xxx_port_fdb_dump(struct dsa_switch *ds, int port,
				   struct switchdev_obj_port_fdb *fdb,
				   int (*cb)(struct switchdev_obj *obj))
{
V
Vivien Didelot 已提交
2416
	struct mv88e6xxx_chip *chip = ds->priv;
2417 2418 2419 2420
	int err;

	mutex_lock(&chip->reg_lock);
	err = mv88e6xxx_port_db_dump(chip, port, &fdb->obj, cb);
2421
	mutex_unlock(&chip->reg_lock);
2422 2423 2424 2425

	return err;
}

2426 2427
static int mv88e6xxx_port_bridge_join(struct dsa_switch *ds, int port,
				      struct net_device *bridge)
2428
{
V
Vivien Didelot 已提交
2429
	struct mv88e6xxx_chip *chip = ds->priv;
2430
	int i, err = 0;
2431

2432
	mutex_lock(&chip->reg_lock);
2433

2434
	/* Assign the bridge and remap each port's VLANTable */
2435
	chip->ports[port].bridge_dev = bridge;
2436

2437
	for (i = 0; i < mv88e6xxx_num_ports(chip); ++i) {
2438 2439
		if (chip->ports[i].bridge_dev == bridge) {
			err = _mv88e6xxx_port_based_vlan_map(chip, i);
2440 2441 2442 2443 2444
			if (err)
				break;
		}
	}

2445
	mutex_unlock(&chip->reg_lock);
2446

2447
	return err;
2448 2449
}

2450
static void mv88e6xxx_port_bridge_leave(struct dsa_switch *ds, int port)
2451
{
V
Vivien Didelot 已提交
2452
	struct mv88e6xxx_chip *chip = ds->priv;
2453
	struct net_device *bridge = chip->ports[port].bridge_dev;
2454
	int i;
2455

2456
	mutex_lock(&chip->reg_lock);
2457

2458
	/* Unassign the bridge and remap each port's VLANTable */
2459
	chip->ports[port].bridge_dev = NULL;
2460

2461
	for (i = 0; i < mv88e6xxx_num_ports(chip); ++i)
2462 2463
		if (i == port || chip->ports[i].bridge_dev == bridge)
			if (_mv88e6xxx_port_based_vlan_map(chip, i))
2464 2465
				netdev_warn(ds->ports[i].netdev,
					    "failed to remap\n");
2466

2467
	mutex_unlock(&chip->reg_lock);
2468 2469
}

2470
static int mv88e6xxx_switch_reset(struct mv88e6xxx_chip *chip)
2471
{
2472
	bool ppu_active = mv88e6xxx_has(chip, MV88E6XXX_FLAG_PPU_ACTIVE);
2473
	u16 is_reset = (ppu_active ? 0x8800 : 0xc800);
2474
	struct gpio_desc *gpiod = chip->reset;
2475
	unsigned long timeout;
2476
	u16 reg;
2477
	int err;
2478 2479 2480
	int i;

	/* Set all ports to the disabled state. */
2481
	for (i = 0; i < mv88e6xxx_num_ports(chip); i++) {
2482 2483
		err = mv88e6xxx_port_set_state(chip, i,
					       PORT_CONTROL_STATE_DISABLED);
2484 2485
		if (err)
			return err;
2486 2487 2488 2489 2490 2491 2492 2493 2494 2495 2496 2497 2498 2499 2500 2501 2502 2503
	}

	/* Wait for transmit queues to drain. */
	usleep_range(2000, 4000);

	/* If there is a gpio connected to the reset pin, toggle it */
	if (gpiod) {
		gpiod_set_value_cansleep(gpiod, 1);
		usleep_range(10000, 20000);
		gpiod_set_value_cansleep(gpiod, 0);
		usleep_range(10000, 20000);
	}

	/* Reset the switch. Keep the PPU active if requested. The PPU
	 * needs to be active to support indirect phy register access
	 * through global registers 0x18 and 0x19.
	 */
	if (ppu_active)
2504
		err = mv88e6xxx_g1_write(chip, 0x04, 0xc000);
2505
	else
2506
		err = mv88e6xxx_g1_write(chip, 0x04, 0xc400);
2507 2508
	if (err)
		return err;
2509 2510 2511 2512

	/* Wait up to one second for reset to complete. */
	timeout = jiffies + 1 * HZ;
	while (time_before(jiffies, timeout)) {
2513 2514 2515
		err = mv88e6xxx_g1_read(chip, 0x00, &reg);
		if (err)
			return err;
2516

2517
		if ((reg & is_reset) == is_reset)
2518 2519 2520 2521
			break;
		usleep_range(1000, 2000);
	}
	if (time_after(jiffies, timeout))
2522
		err = -ETIMEDOUT;
2523
	else
2524
		err = 0;
2525

2526
	return err;
2527 2528
}

2529
static int mv88e6xxx_serdes_power_on(struct mv88e6xxx_chip *chip)
2530
{
2531 2532
	u16 val;
	int err;
2533

2534 2535 2536 2537
	/* Clear Power Down bit */
	err = mv88e6xxx_serdes_read(chip, MII_BMCR, &val);
	if (err)
		return err;
2538

2539 2540 2541
	if (val & BMCR_PDOWN) {
		val &= ~BMCR_PDOWN;
		err = mv88e6xxx_serdes_write(chip, MII_BMCR, val);
2542 2543
	}

2544
	return err;
2545 2546
}

2547
static int mv88e6xxx_setup_port(struct mv88e6xxx_chip *chip, int port)
2548
{
2549
	struct dsa_switch *ds = chip->ds;
2550
	int err;
2551
	u16 reg;
2552

2553 2554 2555 2556
	if (mv88e6xxx_6352_family(chip) || mv88e6xxx_6351_family(chip) ||
	    mv88e6xxx_6165_family(chip) || mv88e6xxx_6097_family(chip) ||
	    mv88e6xxx_6185_family(chip) || mv88e6xxx_6095_family(chip) ||
	    mv88e6xxx_6065_family(chip) || mv88e6xxx_6320_family(chip)) {
2557 2558 2559 2560 2561 2562
		/* MAC Forcing register: don't force link, speed,
		 * duplex or flow control state to any particular
		 * values on physical ports, but force the CPU port
		 * and all DSA ports to their maximum bandwidth and
		 * full duplex.
		 */
2563
		err = mv88e6xxx_port_read(chip, port, PORT_PCS_CTRL, &reg);
2564
		if (dsa_is_cpu_port(ds, port) || dsa_is_dsa_port(ds, port)) {
2565
			reg &= ~PORT_PCS_CTRL_UNFORCED;
2566 2567 2568 2569
			reg |= PORT_PCS_CTRL_FORCE_LINK |
				PORT_PCS_CTRL_LINK_UP |
				PORT_PCS_CTRL_DUPLEX_FULL |
				PORT_PCS_CTRL_FORCE_DUPLEX;
2570
			if (mv88e6xxx_6065_family(chip))
2571 2572 2573 2574 2575 2576 2577
				reg |= PORT_PCS_CTRL_100;
			else
				reg |= PORT_PCS_CTRL_1000;
		} else {
			reg |= PORT_PCS_CTRL_UNFORCED;
		}

2578 2579 2580
		err = mv88e6xxx_port_write(chip, port, PORT_PCS_CTRL, reg);
		if (err)
			return err;
2581 2582 2583 2584 2585 2586 2587 2588 2589 2590 2591 2592 2593 2594 2595 2596 2597
	}

	/* Port Control: disable Drop-on-Unlock, disable Drop-on-Lock,
	 * disable Header mode, enable IGMP/MLD snooping, disable VLAN
	 * tunneling, determine priority by looking at 802.1p and IP
	 * priority fields (IP prio has precedence), and set STP state
	 * to Forwarding.
	 *
	 * If this is the CPU link, use DSA or EDSA tagging depending
	 * on which tagging mode was configured.
	 *
	 * If this is a link to another switch, use DSA tagging mode.
	 *
	 * If this is the upstream port for this switch, enable
	 * forwarding of unknown unicasts and multicasts.
	 */
	reg = 0;
2598 2599 2600 2601
	if (mv88e6xxx_6352_family(chip) || mv88e6xxx_6351_family(chip) ||
	    mv88e6xxx_6165_family(chip) || mv88e6xxx_6097_family(chip) ||
	    mv88e6xxx_6095_family(chip) || mv88e6xxx_6065_family(chip) ||
	    mv88e6xxx_6185_family(chip) || mv88e6xxx_6320_family(chip))
2602 2603 2604 2605
		reg = PORT_CONTROL_IGMP_MLD_SNOOP |
		PORT_CONTROL_USE_TAG | PORT_CONTROL_USE_IP |
		PORT_CONTROL_STATE_FORWARDING;
	if (dsa_is_cpu_port(ds, port)) {
2606
		if (mv88e6xxx_has(chip, MV88E6XXX_FLAG_EDSA))
2607
			reg |= PORT_CONTROL_FRAME_ETHER_TYPE_DSA |
2608
				PORT_CONTROL_FORWARD_UNKNOWN_MC;
2609 2610
		else
			reg |= PORT_CONTROL_DSA_TAG;
2611 2612
		reg |= PORT_CONTROL_EGRESS_ADD_TAG |
			PORT_CONTROL_FORWARD_UNKNOWN;
2613
	}
2614
	if (dsa_is_dsa_port(ds, port)) {
2615 2616
		if (mv88e6xxx_6095_family(chip) ||
		    mv88e6xxx_6185_family(chip))
2617
			reg |= PORT_CONTROL_DSA_TAG;
2618 2619 2620 2621 2622
		if (mv88e6xxx_6352_family(chip) ||
		    mv88e6xxx_6351_family(chip) ||
		    mv88e6xxx_6165_family(chip) ||
		    mv88e6xxx_6097_family(chip) ||
		    mv88e6xxx_6320_family(chip)) {
2623
			reg |= PORT_CONTROL_FRAME_MODE_DSA;
2624 2625
		}

2626 2627 2628 2629 2630
		if (port == dsa_upstream_port(ds))
			reg |= PORT_CONTROL_FORWARD_UNKNOWN |
				PORT_CONTROL_FORWARD_UNKNOWN_MC;
	}
	if (reg) {
2631 2632 2633
		err = mv88e6xxx_port_write(chip, port, PORT_CONTROL, reg);
		if (err)
			return err;
2634 2635
	}

2636 2637 2638
	/* If this port is connected to a SerDes, make sure the SerDes is not
	 * powered down.
	 */
2639
	if (mv88e6xxx_has(chip, MV88E6XXX_FLAGS_SERDES)) {
2640 2641 2642 2643 2644 2645 2646 2647 2648 2649
		err = mv88e6xxx_port_read(chip, port, PORT_STATUS, &reg);
		if (err)
			return err;
		reg &= PORT_STATUS_CMODE_MASK;
		if ((reg == PORT_STATUS_CMODE_100BASE_X) ||
		    (reg == PORT_STATUS_CMODE_1000BASE_X) ||
		    (reg == PORT_STATUS_CMODE_SGMII)) {
			err = mv88e6xxx_serdes_power_on(chip);
			if (err < 0)
				return err;
2650 2651 2652
		}
	}

2653
	/* Port Control 2: don't force a good FCS, set the maximum frame size to
2654
	 * 10240 bytes, disable 802.1q tags checking, don't discard tagged or
2655 2656 2657
	 * untagged frames on this port, do a destination address lookup on all
	 * received packets as usual, disable ARP mirroring and don't send a
	 * copy of all transmitted/received frames on this port to the CPU.
2658 2659
	 */
	reg = 0;
2660 2661 2662 2663
	if (mv88e6xxx_6352_family(chip) || mv88e6xxx_6351_family(chip) ||
	    mv88e6xxx_6165_family(chip) || mv88e6xxx_6097_family(chip) ||
	    mv88e6xxx_6095_family(chip) || mv88e6xxx_6320_family(chip) ||
	    mv88e6xxx_6185_family(chip))
2664 2665
		reg = PORT_CONTROL_2_MAP_DA;

2666 2667
	if (mv88e6xxx_6352_family(chip) || mv88e6xxx_6351_family(chip) ||
	    mv88e6xxx_6165_family(chip) || mv88e6xxx_6320_family(chip))
2668 2669
		reg |= PORT_CONTROL_2_JUMBO_10240;

2670
	if (mv88e6xxx_6095_family(chip) || mv88e6xxx_6185_family(chip)) {
2671 2672 2673 2674 2675 2676 2677 2678 2679
		/* Set the upstream port this port should use */
		reg |= dsa_upstream_port(ds);
		/* enable forwarding of unknown multicast addresses to
		 * the upstream port
		 */
		if (port == dsa_upstream_port(ds))
			reg |= PORT_CONTROL_2_FORWARD_UNKNOWN;
	}

2680
	reg |= PORT_CONTROL_2_8021Q_DISABLED;
2681

2682
	if (reg) {
2683 2684 2685
		err = mv88e6xxx_port_write(chip, port, PORT_CONTROL_2, reg);
		if (err)
			return err;
2686 2687 2688 2689 2690 2691 2692
	}

	/* Port Association Vector: when learning source addresses
	 * of packets, add the address to the address database using
	 * a port bitmap that has only the bit for this port set and
	 * the other bits clear.
	 */
2693
	reg = 1 << port;
2694 2695
	/* Disable learning for CPU port */
	if (dsa_is_cpu_port(ds, port))
2696
		reg = 0;
2697

2698 2699 2700
	err = mv88e6xxx_port_write(chip, port, PORT_ASSOC_VECTOR, reg);
	if (err)
		return err;
2701 2702

	/* Egress rate control 2: disable egress rate control. */
2703 2704 2705
	err = mv88e6xxx_port_write(chip, port, PORT_RATE_CONTROL_2, 0x0000);
	if (err)
		return err;
2706

2707 2708 2709
	if (mv88e6xxx_6352_family(chip) || mv88e6xxx_6351_family(chip) ||
	    mv88e6xxx_6165_family(chip) || mv88e6xxx_6097_family(chip) ||
	    mv88e6xxx_6320_family(chip)) {
2710 2711 2712 2713
		/* Do not limit the period of time that this port can
		 * be paused for by the remote end or the period of
		 * time that this port can pause the remote end.
		 */
2714 2715 2716
		err = mv88e6xxx_port_write(chip, port, PORT_PAUSE_CTRL, 0x0000);
		if (err)
			return err;
2717 2718 2719 2720 2721

		/* Port ATU control: disable limiting the number of
		 * address database entries that this port is allowed
		 * to use.
		 */
2722 2723
		err = mv88e6xxx_port_write(chip, port, PORT_ATU_CONTROL,
					   0x0000);
2724 2725 2726
		/* Priority Override: disable DA, SA and VTU priority
		 * override.
		 */
2727 2728 2729 2730
		err = mv88e6xxx_port_write(chip, port, PORT_PRI_OVERRIDE,
					   0x0000);
		if (err)
			return err;
2731 2732 2733 2734

		/* Port Ethertype: use the Ethertype DSA Ethertype
		 * value.
		 */
2735
		if (mv88e6xxx_has(chip, MV88E6XXX_FLAG_EDSA)) {
2736 2737 2738 2739
			err = mv88e6xxx_port_write(chip, port, PORT_ETH_TYPE,
						   ETH_P_EDSA);
			if (err)
				return err;
2740 2741
		}

2742 2743 2744
		/* Tag Remap: use an identity 802.1p prio -> switch
		 * prio mapping.
		 */
2745 2746 2747 2748
		err = mv88e6xxx_port_write(chip, port, PORT_TAG_REGMAP_0123,
					   0x3210);
		if (err)
			return err;
2749 2750 2751 2752

		/* Tag Remap 2: use an identity 802.1p prio -> switch
		 * prio mapping.
		 */
2753 2754 2755 2756
		err = mv88e6xxx_port_write(chip, port, PORT_TAG_REGMAP_4567,
					   0x7654);
		if (err)
			return err;
2757 2758
	}

2759
	/* Rate Control: disable ingress rate limiting. */
2760 2761 2762
	if (mv88e6xxx_6352_family(chip) || mv88e6xxx_6351_family(chip) ||
	    mv88e6xxx_6165_family(chip) || mv88e6xxx_6097_family(chip) ||
	    mv88e6xxx_6320_family(chip)) {
2763 2764 2765 2766
		err = mv88e6xxx_port_write(chip, port, PORT_RATE_CONTROL,
					   0x0001);
		if (err)
			return err;
2767
	} else if (mv88e6xxx_6185_family(chip) || mv88e6xxx_6095_family(chip)) {
2768 2769 2770 2771
		err = mv88e6xxx_port_write(chip, port, PORT_RATE_CONTROL,
					   0x0000);
		if (err)
			return err;
2772 2773
	}

2774 2775
	/* Port Control 1: disable trunking, disable sending
	 * learning messages to this port.
2776
	 */
2777 2778 2779
	err = mv88e6xxx_port_write(chip, port, PORT_CONTROL_1, 0x0000);
	if (err)
		return err;
2780

2781
	/* Port based VLAN map: give each port the same default address
2782 2783
	 * database, and allow bidirectional communication between the
	 * CPU and DSA port(s), and the other ports.
2784
	 */
2785 2786 2787
	err = _mv88e6xxx_port_fid_set(chip, port, 0);
	if (err)
		return err;
2788

2789 2790 2791
	err = _mv88e6xxx_port_based_vlan_map(chip, port);
	if (err)
		return err;
2792 2793 2794 2795

	/* Default VLAN ID and priority: don't set a default VLAN
	 * ID, and set the default packet priority to zero.
	 */
2796
	return mv88e6xxx_port_write(chip, port, PORT_DEFAULT_VLAN, 0x0000);
2797 2798
}

2799
static int mv88e6xxx_g1_set_switch_mac(struct mv88e6xxx_chip *chip, u8 *addr)
2800 2801 2802
{
	int err;

2803
	err = mv88e6xxx_g1_write(chip, GLOBAL_MAC_01, (addr[0] << 8) | addr[1]);
2804 2805 2806
	if (err)
		return err;

2807
	err = mv88e6xxx_g1_write(chip, GLOBAL_MAC_23, (addr[2] << 8) | addr[3]);
2808 2809 2810
	if (err)
		return err;

2811 2812 2813 2814 2815
	err = mv88e6xxx_g1_write(chip, GLOBAL_MAC_45, (addr[4] << 8) | addr[5]);
	if (err)
		return err;

	return 0;
2816 2817
}

2818 2819 2820 2821 2822 2823 2824 2825 2826 2827 2828 2829 2830 2831 2832 2833
static int mv88e6xxx_g1_set_age_time(struct mv88e6xxx_chip *chip,
				     unsigned int msecs)
{
	const unsigned int coeff = chip->info->age_time_coeff;
	const unsigned int min = 0x01 * coeff;
	const unsigned int max = 0xff * coeff;
	u8 age_time;
	u16 val;
	int err;

	if (msecs < min || msecs > max)
		return -ERANGE;

	/* Round to nearest multiple of coeff */
	age_time = (msecs + coeff / 2) / coeff;

2834
	err = mv88e6xxx_g1_read(chip, GLOBAL_ATU_CONTROL, &val);
2835 2836 2837 2838 2839 2840 2841
	if (err)
		return err;

	/* AgeTime is 11:4 bits */
	val &= ~0xff0;
	val |= age_time << 4;

2842
	return mv88e6xxx_g1_write(chip, GLOBAL_ATU_CONTROL, val);
2843 2844
}

2845 2846 2847
static int mv88e6xxx_set_ageing_time(struct dsa_switch *ds,
				     unsigned int ageing_time)
{
V
Vivien Didelot 已提交
2848
	struct mv88e6xxx_chip *chip = ds->priv;
2849 2850 2851 2852 2853 2854 2855 2856 2857
	int err;

	mutex_lock(&chip->reg_lock);
	err = mv88e6xxx_g1_set_age_time(chip, ageing_time);
	mutex_unlock(&chip->reg_lock);

	return err;
}

2858
static int mv88e6xxx_g1_setup(struct mv88e6xxx_chip *chip)
2859
{
2860
	struct dsa_switch *ds = chip->ds;
2861
	u32 upstream_port = dsa_upstream_port(ds);
2862
	u16 reg;
2863
	int err;
2864

2865 2866 2867
	/* Enable the PHY Polling Unit if present, don't discard any packets,
	 * and mask all interrupt sources.
	 */
2868 2869 2870 2871 2872
	err = mv88e6xxx_g1_read(chip, GLOBAL_CONTROL, &reg);
	if (err < 0)
		return err;

	reg &= ~GLOBAL_CONTROL_PPU_ENABLE;
2873 2874
	if (mv88e6xxx_has(chip, MV88E6XXX_FLAG_PPU) ||
	    mv88e6xxx_has(chip, MV88E6XXX_FLAG_PPU_ACTIVE))
2875 2876
		reg |= GLOBAL_CONTROL_PPU_ENABLE;

2877
	err = mv88e6xxx_g1_write(chip, GLOBAL_CONTROL, reg);
2878 2879 2880
	if (err)
		return err;

2881 2882 2883 2884 2885 2886
	/* Configure the upstream port, and configure it as the port to which
	 * ingress and egress and ARP monitor frames are to be sent.
	 */
	reg = upstream_port << GLOBAL_MONITOR_CONTROL_INGRESS_SHIFT |
		upstream_port << GLOBAL_MONITOR_CONTROL_EGRESS_SHIFT |
		upstream_port << GLOBAL_MONITOR_CONTROL_ARP_SHIFT;
2887
	err = mv88e6xxx_g1_write(chip, GLOBAL_MONITOR_CONTROL, reg);
2888 2889 2890
	if (err)
		return err;

2891
	/* Disable remote management, and set the switch's DSA device number. */
2892 2893 2894
	err = mv88e6xxx_g1_write(chip, GLOBAL_CONTROL_2,
				 GLOBAL_CONTROL_2_MULTIPLE_CASCADE |
				 (ds->index & 0x1f));
2895 2896 2897
	if (err)
		return err;

2898 2899 2900 2901 2902
	/* Clear all the VTU and STU entries */
	err = _mv88e6xxx_vtu_stu_flush(chip);
	if (err < 0)
		return err;

2903 2904 2905 2906
	/* Set the default address aging time to 5 minutes, and
	 * enable address learn messages to be sent to all message
	 * ports.
	 */
2907 2908
	err = mv88e6xxx_g1_write(chip, GLOBAL_ATU_CONTROL,
				 GLOBAL_ATU_CONTROL_LEARN2ALL);
2909
	if (err)
2910
		return err;
2911

2912 2913
	err = mv88e6xxx_g1_set_age_time(chip, 300000);
	if (err)
2914 2915 2916 2917 2918 2919 2920
		return err;

	/* Clear all ATU entries */
	err = _mv88e6xxx_atu_flush(chip, 0, true);
	if (err)
		return err;

2921
	/* Configure the IP ToS mapping registers. */
2922
	err = mv88e6xxx_g1_write(chip, GLOBAL_IP_PRI_0, 0x0000);
2923
	if (err)
2924
		return err;
2925
	err = mv88e6xxx_g1_write(chip, GLOBAL_IP_PRI_1, 0x0000);
2926
	if (err)
2927
		return err;
2928
	err = mv88e6xxx_g1_write(chip, GLOBAL_IP_PRI_2, 0x5555);
2929
	if (err)
2930
		return err;
2931
	err = mv88e6xxx_g1_write(chip, GLOBAL_IP_PRI_3, 0x5555);
2932
	if (err)
2933
		return err;
2934
	err = mv88e6xxx_g1_write(chip, GLOBAL_IP_PRI_4, 0xaaaa);
2935
	if (err)
2936
		return err;
2937
	err = mv88e6xxx_g1_write(chip, GLOBAL_IP_PRI_5, 0xaaaa);
2938
	if (err)
2939
		return err;
2940
	err = mv88e6xxx_g1_write(chip, GLOBAL_IP_PRI_6, 0xffff);
2941
	if (err)
2942
		return err;
2943
	err = mv88e6xxx_g1_write(chip, GLOBAL_IP_PRI_7, 0xffff);
2944
	if (err)
2945
		return err;
2946 2947

	/* Configure the IEEE 802.1p priority mapping register. */
2948
	err = mv88e6xxx_g1_write(chip, GLOBAL_IEEE_PRI, 0xfa41);
2949
	if (err)
2950
		return err;
2951

2952
	/* Clear the statistics counters for all ports */
2953 2954
	err = mv88e6xxx_g1_write(chip, GLOBAL_STATS_OP,
				 GLOBAL_STATS_OP_FLUSH_ALL);
2955 2956 2957 2958 2959 2960 2961 2962 2963 2964 2965
	if (err)
		return err;

	/* Wait for the flush to complete. */
	err = _mv88e6xxx_stats_wait(chip);
	if (err)
		return err;

	return 0;
}

2966
static int mv88e6xxx_setup(struct dsa_switch *ds)
2967
{
V
Vivien Didelot 已提交
2968
	struct mv88e6xxx_chip *chip = ds->priv;
2969
	int err;
2970 2971
	int i;

2972 2973
	chip->ds = ds;
	ds->slave_mii_bus = chip->mdio_bus;
2974

2975
	mutex_lock(&chip->reg_lock);
2976

2977
	/* Setup Switch Port Registers */
2978
	for (i = 0; i < mv88e6xxx_num_ports(chip); i++) {
2979 2980 2981 2982 2983 2984 2985
		err = mv88e6xxx_setup_port(chip, i);
		if (err)
			goto unlock;
	}

	/* Setup Switch Global 1 Registers */
	err = mv88e6xxx_g1_setup(chip);
2986 2987 2988
	if (err)
		goto unlock;

2989 2990 2991
	/* Setup Switch Global 2 Registers */
	if (mv88e6xxx_has(chip, MV88E6XXX_FLAG_GLOBAL2)) {
		err = mv88e6xxx_g2_setup(chip);
2992 2993 2994
		if (err)
			goto unlock;
	}
2995

2996
unlock:
2997
	mutex_unlock(&chip->reg_lock);
2998

2999
	return err;
3000 3001
}

3002 3003
static int mv88e6xxx_set_addr(struct dsa_switch *ds, u8 *addr)
{
V
Vivien Didelot 已提交
3004
	struct mv88e6xxx_chip *chip = ds->priv;
3005 3006
	int err;

3007 3008
	if (!chip->info->ops->set_switch_mac)
		return -EOPNOTSUPP;
3009

3010 3011
	mutex_lock(&chip->reg_lock);
	err = chip->info->ops->set_switch_mac(chip, addr);
3012 3013 3014 3015 3016
	mutex_unlock(&chip->reg_lock);

	return err;
}

3017
static int mv88e6xxx_mdio_read(struct mii_bus *bus, int phy, int reg)
3018
{
3019
	struct mv88e6xxx_chip *chip = bus->priv;
3020 3021
	u16 val;
	int err;
3022

3023
	if (phy >= mv88e6xxx_num_ports(chip))
3024
		return 0xffff;
3025

3026
	mutex_lock(&chip->reg_lock);
3027
	err = mv88e6xxx_phy_read(chip, phy, reg, &val);
3028
	mutex_unlock(&chip->reg_lock);
3029 3030

	return err ? err : val;
3031 3032
}

3033
static int mv88e6xxx_mdio_write(struct mii_bus *bus, int phy, int reg, u16 val)
3034
{
3035
	struct mv88e6xxx_chip *chip = bus->priv;
3036
	int err;
3037

3038
	if (phy >= mv88e6xxx_num_ports(chip))
3039
		return 0xffff;
3040

3041
	mutex_lock(&chip->reg_lock);
3042
	err = mv88e6xxx_phy_write(chip, phy, reg, val);
3043
	mutex_unlock(&chip->reg_lock);
3044 3045

	return err;
3046 3047
}

3048
static int mv88e6xxx_mdio_register(struct mv88e6xxx_chip *chip,
3049 3050 3051 3052 3053 3054 3055
				   struct device_node *np)
{
	static int index;
	struct mii_bus *bus;
	int err;

	if (np)
3056
		chip->mdio_np = of_get_child_by_name(np, "mdio");
3057

3058
	bus = devm_mdiobus_alloc(chip->dev);
3059 3060 3061
	if (!bus)
		return -ENOMEM;

3062
	bus->priv = (void *)chip;
3063 3064 3065 3066 3067 3068 3069 3070 3071 3072
	if (np) {
		bus->name = np->full_name;
		snprintf(bus->id, MII_BUS_ID_SIZE, "%s", np->full_name);
	} else {
		bus->name = "mv88e6xxx SMI";
		snprintf(bus->id, MII_BUS_ID_SIZE, "mv88e6xxx-%d", index++);
	}

	bus->read = mv88e6xxx_mdio_read;
	bus->write = mv88e6xxx_mdio_write;
3073
	bus->parent = chip->dev;
3074

3075 3076
	if (chip->mdio_np)
		err = of_mdiobus_register(bus, chip->mdio_np);
3077 3078 3079
	else
		err = mdiobus_register(bus);
	if (err) {
3080
		dev_err(chip->dev, "Cannot register MDIO bus (%d)\n", err);
3081 3082
		goto out;
	}
3083
	chip->mdio_bus = bus;
3084 3085 3086 3087

	return 0;

out:
3088 3089
	if (chip->mdio_np)
		of_node_put(chip->mdio_np);
3090 3091 3092 3093

	return err;
}

3094
static void mv88e6xxx_mdio_unregister(struct mv88e6xxx_chip *chip)
3095 3096

{
3097
	struct mii_bus *bus = chip->mdio_bus;
3098 3099 3100

	mdiobus_unregister(bus);

3101 3102
	if (chip->mdio_np)
		of_node_put(chip->mdio_np);
3103 3104
}

3105 3106 3107 3108
#ifdef CONFIG_NET_DSA_HWMON

static int mv88e61xx_get_temp(struct dsa_switch *ds, int *temp)
{
V
Vivien Didelot 已提交
3109
	struct mv88e6xxx_chip *chip = ds->priv;
3110
	u16 val;
3111 3112 3113 3114
	int ret;

	*temp = 0;

3115
	mutex_lock(&chip->reg_lock);
3116

3117
	ret = mv88e6xxx_phy_write(chip, 0x0, 0x16, 0x6);
3118 3119 3120 3121
	if (ret < 0)
		goto error;

	/* Enable temperature sensor */
3122
	ret = mv88e6xxx_phy_read(chip, 0x0, 0x1a, &val);
3123 3124 3125
	if (ret < 0)
		goto error;

3126
	ret = mv88e6xxx_phy_write(chip, 0x0, 0x1a, val | (1 << 5));
3127 3128 3129 3130 3131 3132
	if (ret < 0)
		goto error;

	/* Wait for temperature to stabilize */
	usleep_range(10000, 12000);

3133 3134
	ret = mv88e6xxx_phy_read(chip, 0x0, 0x1a, &val);
	if (ret < 0)
3135 3136 3137
		goto error;

	/* Disable temperature sensor */
3138
	ret = mv88e6xxx_phy_write(chip, 0x0, 0x1a, val & ~(1 << 5));
3139 3140 3141 3142 3143 3144
	if (ret < 0)
		goto error;

	*temp = ((val & 0x1f) - 5) * 5;

error:
3145
	mv88e6xxx_phy_write(chip, 0x0, 0x16, 0x0);
3146
	mutex_unlock(&chip->reg_lock);
3147 3148 3149 3150 3151
	return ret;
}

static int mv88e63xx_get_temp(struct dsa_switch *ds, int *temp)
{
V
Vivien Didelot 已提交
3152
	struct mv88e6xxx_chip *chip = ds->priv;
3153
	int phy = mv88e6xxx_6320_family(chip) ? 3 : 0;
3154
	u16 val;
3155 3156 3157 3158
	int ret;

	*temp = 0;

3159 3160 3161
	mutex_lock(&chip->reg_lock);
	ret = mv88e6xxx_phy_page_read(chip, phy, 6, 27, &val);
	mutex_unlock(&chip->reg_lock);
3162 3163 3164
	if (ret < 0)
		return ret;

3165
	*temp = (val & 0xff) - 25;
3166 3167 3168 3169

	return 0;
}

3170
static int mv88e6xxx_get_temp(struct dsa_switch *ds, int *temp)
3171
{
V
Vivien Didelot 已提交
3172
	struct mv88e6xxx_chip *chip = ds->priv;
3173

3174
	if (!mv88e6xxx_has(chip, MV88E6XXX_FLAG_TEMP))
3175 3176
		return -EOPNOTSUPP;

3177
	if (mv88e6xxx_6320_family(chip) || mv88e6xxx_6352_family(chip))
3178 3179 3180 3181 3182
		return mv88e63xx_get_temp(ds, temp);

	return mv88e61xx_get_temp(ds, temp);
}

3183
static int mv88e6xxx_get_temp_limit(struct dsa_switch *ds, int *temp)
3184
{
V
Vivien Didelot 已提交
3185
	struct mv88e6xxx_chip *chip = ds->priv;
3186
	int phy = mv88e6xxx_6320_family(chip) ? 3 : 0;
3187
	u16 val;
3188 3189
	int ret;

3190
	if (!mv88e6xxx_has(chip, MV88E6XXX_FLAG_TEMP_LIMIT))
3191 3192 3193 3194
		return -EOPNOTSUPP;

	*temp = 0;

3195 3196 3197
	mutex_lock(&chip->reg_lock);
	ret = mv88e6xxx_phy_page_read(chip, phy, 6, 26, &val);
	mutex_unlock(&chip->reg_lock);
3198 3199 3200
	if (ret < 0)
		return ret;

3201
	*temp = (((val >> 8) & 0x1f) * 5) - 25;
3202 3203 3204 3205

	return 0;
}

3206
static int mv88e6xxx_set_temp_limit(struct dsa_switch *ds, int temp)
3207
{
V
Vivien Didelot 已提交
3208
	struct mv88e6xxx_chip *chip = ds->priv;
3209
	int phy = mv88e6xxx_6320_family(chip) ? 3 : 0;
3210 3211
	u16 val;
	int err;
3212

3213
	if (!mv88e6xxx_has(chip, MV88E6XXX_FLAG_TEMP_LIMIT))
3214 3215
		return -EOPNOTSUPP;

3216 3217 3218 3219
	mutex_lock(&chip->reg_lock);
	err = mv88e6xxx_phy_page_read(chip, phy, 6, 26, &val);
	if (err)
		goto unlock;
3220
	temp = clamp_val(DIV_ROUND_CLOSEST(temp, 5) + 5, 0, 0x1f);
3221 3222 3223 3224 3225 3226
	err = mv88e6xxx_phy_page_write(chip, phy, 6, 26,
				       (val & 0xe0ff) | (temp << 8));
unlock:
	mutex_unlock(&chip->reg_lock);

	return err;
3227 3228
}

3229
static int mv88e6xxx_get_temp_alarm(struct dsa_switch *ds, bool *alarm)
3230
{
V
Vivien Didelot 已提交
3231
	struct mv88e6xxx_chip *chip = ds->priv;
3232
	int phy = mv88e6xxx_6320_family(chip) ? 3 : 0;
3233
	u16 val;
3234 3235
	int ret;

3236
	if (!mv88e6xxx_has(chip, MV88E6XXX_FLAG_TEMP_LIMIT))
3237 3238 3239 3240
		return -EOPNOTSUPP;

	*alarm = false;

3241 3242 3243
	mutex_lock(&chip->reg_lock);
	ret = mv88e6xxx_phy_page_read(chip, phy, 6, 26, &val);
	mutex_unlock(&chip->reg_lock);
3244 3245 3246
	if (ret < 0)
		return ret;

3247
	*alarm = !!(val & 0x40);
3248 3249 3250 3251 3252

	return 0;
}
#endif /* CONFIG_NET_DSA_HWMON */

3253 3254
static int mv88e6xxx_get_eeprom_len(struct dsa_switch *ds)
{
V
Vivien Didelot 已提交
3255
	struct mv88e6xxx_chip *chip = ds->priv;
3256 3257 3258 3259 3260 3261 3262

	return chip->eeprom_len;
}

static int mv88e6xxx_get_eeprom(struct dsa_switch *ds,
				struct ethtool_eeprom *eeprom, u8 *data)
{
V
Vivien Didelot 已提交
3263
	struct mv88e6xxx_chip *chip = ds->priv;
3264 3265
	int err;

3266 3267
	if (!chip->info->ops->get_eeprom)
		return -EOPNOTSUPP;
3268

3269 3270
	mutex_lock(&chip->reg_lock);
	err = chip->info->ops->get_eeprom(chip, eeprom, data);
3271 3272 3273 3274 3275 3276 3277 3278 3279 3280 3281 3282 3283
	mutex_unlock(&chip->reg_lock);

	if (err)
		return err;

	eeprom->magic = 0xc3ec4951;

	return 0;
}

static int mv88e6xxx_set_eeprom(struct dsa_switch *ds,
				struct ethtool_eeprom *eeprom, u8 *data)
{
V
Vivien Didelot 已提交
3284
	struct mv88e6xxx_chip *chip = ds->priv;
3285 3286
	int err;

3287 3288 3289
	if (!chip->info->ops->set_eeprom)
		return -EOPNOTSUPP;

3290 3291 3292 3293
	if (eeprom->magic != 0xc3ec4951)
		return -EINVAL;

	mutex_lock(&chip->reg_lock);
3294
	err = chip->info->ops->set_eeprom(chip, eeprom, data);
3295 3296 3297 3298 3299
	mutex_unlock(&chip->reg_lock);

	return err;
}

3300
static const struct mv88e6xxx_ops mv88e6085_ops = {
3301
	.set_switch_mac = mv88e6xxx_g1_set_switch_mac,
3302 3303 3304 3305 3306
	.phy_read = mv88e6xxx_phy_ppu_read,
	.phy_write = mv88e6xxx_phy_ppu_write,
};

static const struct mv88e6xxx_ops mv88e6095_ops = {
3307
	.set_switch_mac = mv88e6xxx_g1_set_switch_mac,
3308 3309 3310 3311 3312
	.phy_read = mv88e6xxx_phy_ppu_read,
	.phy_write = mv88e6xxx_phy_ppu_write,
};

static const struct mv88e6xxx_ops mv88e6123_ops = {
3313
	.set_switch_mac = mv88e6xxx_g2_set_switch_mac,
3314 3315 3316 3317 3318
	.phy_read = mv88e6xxx_read,
	.phy_write = mv88e6xxx_write,
};

static const struct mv88e6xxx_ops mv88e6131_ops = {
3319
	.set_switch_mac = mv88e6xxx_g1_set_switch_mac,
3320 3321 3322 3323 3324
	.phy_read = mv88e6xxx_phy_ppu_read,
	.phy_write = mv88e6xxx_phy_ppu_write,
};

static const struct mv88e6xxx_ops mv88e6161_ops = {
3325
	.set_switch_mac = mv88e6xxx_g2_set_switch_mac,
3326 3327 3328 3329 3330
	.phy_read = mv88e6xxx_read,
	.phy_write = mv88e6xxx_write,
};

static const struct mv88e6xxx_ops mv88e6165_ops = {
3331
	.set_switch_mac = mv88e6xxx_g2_set_switch_mac,
3332 3333 3334 3335 3336
	.phy_read = mv88e6xxx_read,
	.phy_write = mv88e6xxx_write,
};

static const struct mv88e6xxx_ops mv88e6171_ops = {
3337
	.set_switch_mac = mv88e6xxx_g2_set_switch_mac,
3338 3339 3340 3341 3342
	.phy_read = mv88e6xxx_g2_smi_phy_read,
	.phy_write = mv88e6xxx_g2_smi_phy_write,
};

static const struct mv88e6xxx_ops mv88e6172_ops = {
3343 3344
	.get_eeprom = mv88e6xxx_g2_get_eeprom16,
	.set_eeprom = mv88e6xxx_g2_set_eeprom16,
3345
	.set_switch_mac = mv88e6xxx_g2_set_switch_mac,
3346 3347 3348 3349 3350
	.phy_read = mv88e6xxx_g2_smi_phy_read,
	.phy_write = mv88e6xxx_g2_smi_phy_write,
};

static const struct mv88e6xxx_ops mv88e6175_ops = {
3351
	.set_switch_mac = mv88e6xxx_g2_set_switch_mac,
3352 3353 3354 3355 3356
	.phy_read = mv88e6xxx_g2_smi_phy_read,
	.phy_write = mv88e6xxx_g2_smi_phy_write,
};

static const struct mv88e6xxx_ops mv88e6176_ops = {
3357 3358
	.get_eeprom = mv88e6xxx_g2_get_eeprom16,
	.set_eeprom = mv88e6xxx_g2_set_eeprom16,
3359
	.set_switch_mac = mv88e6xxx_g2_set_switch_mac,
3360 3361 3362 3363 3364
	.phy_read = mv88e6xxx_g2_smi_phy_read,
	.phy_write = mv88e6xxx_g2_smi_phy_write,
};

static const struct mv88e6xxx_ops mv88e6185_ops = {
3365
	.set_switch_mac = mv88e6xxx_g1_set_switch_mac,
3366 3367 3368 3369 3370
	.phy_read = mv88e6xxx_phy_ppu_read,
	.phy_write = mv88e6xxx_phy_ppu_write,
};

static const struct mv88e6xxx_ops mv88e6240_ops = {
3371 3372
	.get_eeprom = mv88e6xxx_g2_get_eeprom16,
	.set_eeprom = mv88e6xxx_g2_set_eeprom16,
3373
	.set_switch_mac = mv88e6xxx_g2_set_switch_mac,
3374 3375 3376 3377 3378
	.phy_read = mv88e6xxx_g2_smi_phy_read,
	.phy_write = mv88e6xxx_g2_smi_phy_write,
};

static const struct mv88e6xxx_ops mv88e6320_ops = {
3379 3380
	.get_eeprom = mv88e6xxx_g2_get_eeprom16,
	.set_eeprom = mv88e6xxx_g2_set_eeprom16,
3381
	.set_switch_mac = mv88e6xxx_g2_set_switch_mac,
3382 3383 3384 3385 3386
	.phy_read = mv88e6xxx_g2_smi_phy_read,
	.phy_write = mv88e6xxx_g2_smi_phy_write,
};

static const struct mv88e6xxx_ops mv88e6321_ops = {
3387 3388
	.get_eeprom = mv88e6xxx_g2_get_eeprom16,
	.set_eeprom = mv88e6xxx_g2_set_eeprom16,
3389
	.set_switch_mac = mv88e6xxx_g2_set_switch_mac,
3390 3391 3392 3393 3394
	.phy_read = mv88e6xxx_g2_smi_phy_read,
	.phy_write = mv88e6xxx_g2_smi_phy_write,
};

static const struct mv88e6xxx_ops mv88e6350_ops = {
3395
	.set_switch_mac = mv88e6xxx_g2_set_switch_mac,
3396 3397 3398 3399 3400
	.phy_read = mv88e6xxx_g2_smi_phy_read,
	.phy_write = mv88e6xxx_g2_smi_phy_write,
};

static const struct mv88e6xxx_ops mv88e6351_ops = {
3401
	.set_switch_mac = mv88e6xxx_g2_set_switch_mac,
3402 3403 3404 3405 3406
	.phy_read = mv88e6xxx_g2_smi_phy_read,
	.phy_write = mv88e6xxx_g2_smi_phy_write,
};

static const struct mv88e6xxx_ops mv88e6352_ops = {
3407 3408
	.get_eeprom = mv88e6xxx_g2_get_eeprom16,
	.set_eeprom = mv88e6xxx_g2_set_eeprom16,
3409
	.set_switch_mac = mv88e6xxx_g2_set_switch_mac,
3410 3411 3412 3413
	.phy_read = mv88e6xxx_g2_smi_phy_read,
	.phy_write = mv88e6xxx_g2_smi_phy_write,
};

3414 3415 3416 3417 3418 3419 3420
static const struct mv88e6xxx_info mv88e6xxx_table[] = {
	[MV88E6085] = {
		.prod_num = PORT_SWITCH_ID_PROD_NUM_6085,
		.family = MV88E6XXX_FAMILY_6097,
		.name = "Marvell 88E6085",
		.num_databases = 4096,
		.num_ports = 10,
3421
		.port_base_addr = 0x10,
3422
		.global1_addr = 0x1b,
3423
		.age_time_coeff = 15000,
3424
		.g1_irqs = 8,
3425
		.flags = MV88E6XXX_FLAGS_FAMILY_6097,
3426
		.ops = &mv88e6085_ops,
3427 3428 3429 3430 3431 3432 3433 3434
	},

	[MV88E6095] = {
		.prod_num = PORT_SWITCH_ID_PROD_NUM_6095,
		.family = MV88E6XXX_FAMILY_6095,
		.name = "Marvell 88E6095/88E6095F",
		.num_databases = 256,
		.num_ports = 11,
3435
		.port_base_addr = 0x10,
3436
		.global1_addr = 0x1b,
3437
		.age_time_coeff = 15000,
3438
		.g1_irqs = 8,
3439
		.flags = MV88E6XXX_FLAGS_FAMILY_6095,
3440
		.ops = &mv88e6095_ops,
3441 3442 3443 3444 3445 3446 3447 3448
	},

	[MV88E6123] = {
		.prod_num = PORT_SWITCH_ID_PROD_NUM_6123,
		.family = MV88E6XXX_FAMILY_6165,
		.name = "Marvell 88E6123",
		.num_databases = 4096,
		.num_ports = 3,
3449
		.port_base_addr = 0x10,
3450
		.global1_addr = 0x1b,
3451
		.age_time_coeff = 15000,
3452
		.g1_irqs = 9,
3453
		.flags = MV88E6XXX_FLAGS_FAMILY_6165,
3454
		.ops = &mv88e6123_ops,
3455 3456 3457 3458 3459 3460 3461 3462
	},

	[MV88E6131] = {
		.prod_num = PORT_SWITCH_ID_PROD_NUM_6131,
		.family = MV88E6XXX_FAMILY_6185,
		.name = "Marvell 88E6131",
		.num_databases = 256,
		.num_ports = 8,
3463
		.port_base_addr = 0x10,
3464
		.global1_addr = 0x1b,
3465
		.age_time_coeff = 15000,
3466
		.g1_irqs = 9,
3467
		.flags = MV88E6XXX_FLAGS_FAMILY_6185,
3468
		.ops = &mv88e6131_ops,
3469 3470 3471 3472 3473 3474 3475 3476
	},

	[MV88E6161] = {
		.prod_num = PORT_SWITCH_ID_PROD_NUM_6161,
		.family = MV88E6XXX_FAMILY_6165,
		.name = "Marvell 88E6161",
		.num_databases = 4096,
		.num_ports = 6,
3477
		.port_base_addr = 0x10,
3478
		.global1_addr = 0x1b,
3479
		.age_time_coeff = 15000,
3480
		.g1_irqs = 9,
3481
		.flags = MV88E6XXX_FLAGS_FAMILY_6165,
3482
		.ops = &mv88e6161_ops,
3483 3484 3485 3486 3487 3488 3489 3490
	},

	[MV88E6165] = {
		.prod_num = PORT_SWITCH_ID_PROD_NUM_6165,
		.family = MV88E6XXX_FAMILY_6165,
		.name = "Marvell 88E6165",
		.num_databases = 4096,
		.num_ports = 6,
3491
		.port_base_addr = 0x10,
3492
		.global1_addr = 0x1b,
3493
		.age_time_coeff = 15000,
3494
		.g1_irqs = 9,
3495
		.flags = MV88E6XXX_FLAGS_FAMILY_6165,
3496
		.ops = &mv88e6165_ops,
3497 3498 3499 3500 3501 3502 3503 3504
	},

	[MV88E6171] = {
		.prod_num = PORT_SWITCH_ID_PROD_NUM_6171,
		.family = MV88E6XXX_FAMILY_6351,
		.name = "Marvell 88E6171",
		.num_databases = 4096,
		.num_ports = 7,
3505
		.port_base_addr = 0x10,
3506
		.global1_addr = 0x1b,
3507
		.age_time_coeff = 15000,
3508
		.g1_irqs = 9,
3509
		.flags = MV88E6XXX_FLAGS_FAMILY_6351,
3510
		.ops = &mv88e6171_ops,
3511 3512 3513 3514 3515 3516 3517 3518
	},

	[MV88E6172] = {
		.prod_num = PORT_SWITCH_ID_PROD_NUM_6172,
		.family = MV88E6XXX_FAMILY_6352,
		.name = "Marvell 88E6172",
		.num_databases = 4096,
		.num_ports = 7,
3519
		.port_base_addr = 0x10,
3520
		.global1_addr = 0x1b,
3521
		.age_time_coeff = 15000,
3522
		.g1_irqs = 9,
3523
		.flags = MV88E6XXX_FLAGS_FAMILY_6352,
3524
		.ops = &mv88e6172_ops,
3525 3526 3527 3528 3529 3530 3531 3532
	},

	[MV88E6175] = {
		.prod_num = PORT_SWITCH_ID_PROD_NUM_6175,
		.family = MV88E6XXX_FAMILY_6351,
		.name = "Marvell 88E6175",
		.num_databases = 4096,
		.num_ports = 7,
3533
		.port_base_addr = 0x10,
3534
		.global1_addr = 0x1b,
3535
		.age_time_coeff = 15000,
3536
		.g1_irqs = 9,
3537
		.flags = MV88E6XXX_FLAGS_FAMILY_6351,
3538
		.ops = &mv88e6175_ops,
3539 3540 3541 3542 3543 3544 3545 3546
	},

	[MV88E6176] = {
		.prod_num = PORT_SWITCH_ID_PROD_NUM_6176,
		.family = MV88E6XXX_FAMILY_6352,
		.name = "Marvell 88E6176",
		.num_databases = 4096,
		.num_ports = 7,
3547
		.port_base_addr = 0x10,
3548
		.global1_addr = 0x1b,
3549
		.age_time_coeff = 15000,
3550
		.g1_irqs = 9,
3551
		.flags = MV88E6XXX_FLAGS_FAMILY_6352,
3552
		.ops = &mv88e6176_ops,
3553 3554 3555 3556 3557 3558 3559 3560
	},

	[MV88E6185] = {
		.prod_num = PORT_SWITCH_ID_PROD_NUM_6185,
		.family = MV88E6XXX_FAMILY_6185,
		.name = "Marvell 88E6185",
		.num_databases = 256,
		.num_ports = 10,
3561
		.port_base_addr = 0x10,
3562
		.global1_addr = 0x1b,
3563
		.age_time_coeff = 15000,
3564
		.g1_irqs = 8,
3565
		.flags = MV88E6XXX_FLAGS_FAMILY_6185,
3566
		.ops = &mv88e6185_ops,
3567 3568 3569 3570 3571 3572 3573 3574
	},

	[MV88E6240] = {
		.prod_num = PORT_SWITCH_ID_PROD_NUM_6240,
		.family = MV88E6XXX_FAMILY_6352,
		.name = "Marvell 88E6240",
		.num_databases = 4096,
		.num_ports = 7,
3575
		.port_base_addr = 0x10,
3576
		.global1_addr = 0x1b,
3577
		.age_time_coeff = 15000,
3578
		.g1_irqs = 9,
3579
		.flags = MV88E6XXX_FLAGS_FAMILY_6352,
3580
		.ops = &mv88e6240_ops,
3581 3582 3583 3584 3585 3586 3587 3588
	},

	[MV88E6320] = {
		.prod_num = PORT_SWITCH_ID_PROD_NUM_6320,
		.family = MV88E6XXX_FAMILY_6320,
		.name = "Marvell 88E6320",
		.num_databases = 4096,
		.num_ports = 7,
3589
		.port_base_addr = 0x10,
3590
		.global1_addr = 0x1b,
3591
		.age_time_coeff = 15000,
3592
		.g1_irqs = 8,
3593
		.flags = MV88E6XXX_FLAGS_FAMILY_6320,
3594
		.ops = &mv88e6320_ops,
3595 3596 3597 3598 3599 3600 3601 3602
	},

	[MV88E6321] = {
		.prod_num = PORT_SWITCH_ID_PROD_NUM_6321,
		.family = MV88E6XXX_FAMILY_6320,
		.name = "Marvell 88E6321",
		.num_databases = 4096,
		.num_ports = 7,
3603
		.port_base_addr = 0x10,
3604
		.global1_addr = 0x1b,
3605
		.age_time_coeff = 15000,
3606
		.g1_irqs = 8,
3607
		.flags = MV88E6XXX_FLAGS_FAMILY_6320,
3608
		.ops = &mv88e6321_ops,
3609 3610 3611 3612 3613 3614 3615 3616
	},

	[MV88E6350] = {
		.prod_num = PORT_SWITCH_ID_PROD_NUM_6350,
		.family = MV88E6XXX_FAMILY_6351,
		.name = "Marvell 88E6350",
		.num_databases = 4096,
		.num_ports = 7,
3617
		.port_base_addr = 0x10,
3618
		.global1_addr = 0x1b,
3619
		.age_time_coeff = 15000,
3620
		.g1_irqs = 9,
3621
		.flags = MV88E6XXX_FLAGS_FAMILY_6351,
3622
		.ops = &mv88e6350_ops,
3623 3624 3625 3626 3627 3628 3629 3630
	},

	[MV88E6351] = {
		.prod_num = PORT_SWITCH_ID_PROD_NUM_6351,
		.family = MV88E6XXX_FAMILY_6351,
		.name = "Marvell 88E6351",
		.num_databases = 4096,
		.num_ports = 7,
3631
		.port_base_addr = 0x10,
3632
		.global1_addr = 0x1b,
3633
		.age_time_coeff = 15000,
3634
		.g1_irqs = 9,
3635
		.flags = MV88E6XXX_FLAGS_FAMILY_6351,
3636
		.ops = &mv88e6351_ops,
3637 3638 3639 3640 3641 3642 3643 3644
	},

	[MV88E6352] = {
		.prod_num = PORT_SWITCH_ID_PROD_NUM_6352,
		.family = MV88E6XXX_FAMILY_6352,
		.name = "Marvell 88E6352",
		.num_databases = 4096,
		.num_ports = 7,
3645
		.port_base_addr = 0x10,
3646
		.global1_addr = 0x1b,
3647
		.age_time_coeff = 15000,
3648
		.g1_irqs = 9,
3649
		.flags = MV88E6XXX_FLAGS_FAMILY_6352,
3650
		.ops = &mv88e6352_ops,
3651 3652 3653
	},
};

3654
static const struct mv88e6xxx_info *mv88e6xxx_lookup_info(unsigned int prod_num)
3655
{
3656
	int i;
3657

3658 3659 3660
	for (i = 0; i < ARRAY_SIZE(mv88e6xxx_table); ++i)
		if (mv88e6xxx_table[i].prod_num == prod_num)
			return &mv88e6xxx_table[i];
3661 3662 3663 3664

	return NULL;
}

3665
static int mv88e6xxx_detect(struct mv88e6xxx_chip *chip)
3666 3667
{
	const struct mv88e6xxx_info *info;
3668 3669 3670
	unsigned int prod_num, rev;
	u16 id;
	int err;
3671

3672 3673 3674 3675 3676
	mutex_lock(&chip->reg_lock);
	err = mv88e6xxx_port_read(chip, 0, PORT_SWITCH_ID, &id);
	mutex_unlock(&chip->reg_lock);
	if (err)
		return err;
3677 3678 3679 3680 3681 3682 3683 3684

	prod_num = (id & 0xfff0) >> 4;
	rev = id & 0x000f;

	info = mv88e6xxx_lookup_info(prod_num);
	if (!info)
		return -ENODEV;

3685
	/* Update the compatible info with the probed one */
3686
	chip->info = info;
3687

3688 3689 3690 3691
	err = mv88e6xxx_g2_require(chip);
	if (err)
		return err;

3692 3693
	dev_info(chip->dev, "switch 0x%x detected: %s, revision %u\n",
		 chip->info->prod_num, chip->info->name, rev);
3694 3695 3696 3697

	return 0;
}

3698
static struct mv88e6xxx_chip *mv88e6xxx_alloc_chip(struct device *dev)
3699
{
3700
	struct mv88e6xxx_chip *chip;
3701

3702 3703
	chip = devm_kzalloc(dev, sizeof(*chip), GFP_KERNEL);
	if (!chip)
3704 3705
		return NULL;

3706
	chip->dev = dev;
3707

3708
	mutex_init(&chip->reg_lock);
3709

3710
	return chip;
3711 3712
}

3713 3714
static void mv88e6xxx_phy_init(struct mv88e6xxx_chip *chip)
{
3715
	if (mv88e6xxx_has(chip, MV88E6XXX_FLAG_PPU))
3716 3717 3718
		mv88e6xxx_ppu_state_init(chip);
}

3719 3720
static void mv88e6xxx_phy_destroy(struct mv88e6xxx_chip *chip)
{
3721
	if (mv88e6xxx_has(chip, MV88E6XXX_FLAG_PPU))
3722 3723 3724
		mv88e6xxx_ppu_state_destroy(chip);
}

3725
static int mv88e6xxx_smi_init(struct mv88e6xxx_chip *chip,
3726 3727 3728 3729 3730 3731
			      struct mii_bus *bus, int sw_addr)
{
	/* ADDR[0] pin is unavailable externally and considered zero */
	if (sw_addr & 0x1)
		return -EINVAL;

3732
	if (sw_addr == 0)
3733
		chip->smi_ops = &mv88e6xxx_smi_single_chip_ops;
3734
	else if (mv88e6xxx_has(chip, MV88E6XXX_FLAGS_MULTI_CHIP))
3735
		chip->smi_ops = &mv88e6xxx_smi_multi_chip_ops;
3736 3737 3738
	else
		return -EINVAL;

3739 3740
	chip->bus = bus;
	chip->sw_addr = sw_addr;
3741 3742 3743 3744

	return 0;
}

3745 3746
static enum dsa_tag_protocol mv88e6xxx_get_tag_protocol(struct dsa_switch *ds)
{
V
Vivien Didelot 已提交
3747
	struct mv88e6xxx_chip *chip = ds->priv;
3748 3749 3750 3751 3752

	if (mv88e6xxx_has(chip, MV88E6XXX_FLAG_EDSA))
		return DSA_TAG_PROTO_EDSA;

	return DSA_TAG_PROTO_DSA;
3753 3754
}

3755 3756 3757
static const char *mv88e6xxx_drv_probe(struct device *dsa_dev,
				       struct device *host_dev, int sw_addr,
				       void **priv)
3758
{
3759
	struct mv88e6xxx_chip *chip;
3760
	struct mii_bus *bus;
3761
	int err;
3762

3763
	bus = dsa_host_dev_to_mii_bus(host_dev);
3764 3765 3766
	if (!bus)
		return NULL;

3767 3768
	chip = mv88e6xxx_alloc_chip(dsa_dev);
	if (!chip)
3769 3770
		return NULL;

3771
	/* Legacy SMI probing will only support chips similar to 88E6085 */
3772
	chip->info = &mv88e6xxx_table[MV88E6085];
3773

3774
	err = mv88e6xxx_smi_init(chip, bus, sw_addr);
3775 3776 3777
	if (err)
		goto free;

3778
	err = mv88e6xxx_detect(chip);
3779
	if (err)
3780
		goto free;
3781

3782 3783 3784 3785 3786 3787
	mutex_lock(&chip->reg_lock);
	err = mv88e6xxx_switch_reset(chip);
	mutex_unlock(&chip->reg_lock);
	if (err)
		goto free;

3788 3789
	mv88e6xxx_phy_init(chip);

3790
	err = mv88e6xxx_mdio_register(chip, NULL);
3791
	if (err)
3792
		goto free;
3793

3794
	*priv = chip;
3795

3796
	return chip->info->name;
3797
free:
3798
	devm_kfree(dsa_dev, chip);
3799 3800

	return NULL;
3801 3802
}

3803 3804 3805 3806 3807 3808 3809 3810 3811 3812 3813 3814 3815 3816 3817
static int mv88e6xxx_port_mdb_prepare(struct dsa_switch *ds, int port,
				      const struct switchdev_obj_port_mdb *mdb,
				      struct switchdev_trans *trans)
{
	/* We don't need any dynamic resource from the kernel (yet),
	 * so skip the prepare phase.
	 */

	return 0;
}

static void mv88e6xxx_port_mdb_add(struct dsa_switch *ds, int port,
				   const struct switchdev_obj_port_mdb *mdb,
				   struct switchdev_trans *trans)
{
V
Vivien Didelot 已提交
3818
	struct mv88e6xxx_chip *chip = ds->priv;
3819 3820 3821 3822 3823 3824 3825 3826 3827 3828 3829

	mutex_lock(&chip->reg_lock);
	if (mv88e6xxx_port_db_load_purge(chip, port, mdb->addr, mdb->vid,
					 GLOBAL_ATU_DATA_STATE_MC_STATIC))
		netdev_err(ds->ports[port].netdev, "failed to load multicast MAC address\n");
	mutex_unlock(&chip->reg_lock);
}

static int mv88e6xxx_port_mdb_del(struct dsa_switch *ds, int port,
				  const struct switchdev_obj_port_mdb *mdb)
{
V
Vivien Didelot 已提交
3830
	struct mv88e6xxx_chip *chip = ds->priv;
3831 3832 3833 3834 3835 3836 3837 3838 3839 3840 3841 3842 3843 3844
	int err;

	mutex_lock(&chip->reg_lock);
	err = mv88e6xxx_port_db_load_purge(chip, port, mdb->addr, mdb->vid,
					   GLOBAL_ATU_DATA_STATE_UNUSED);
	mutex_unlock(&chip->reg_lock);

	return err;
}

static int mv88e6xxx_port_mdb_dump(struct dsa_switch *ds, int port,
				   struct switchdev_obj_port_mdb *mdb,
				   int (*cb)(struct switchdev_obj *obj))
{
V
Vivien Didelot 已提交
3845
	struct mv88e6xxx_chip *chip = ds->priv;
3846 3847 3848 3849 3850 3851 3852 3853 3854
	int err;

	mutex_lock(&chip->reg_lock);
	err = mv88e6xxx_port_db_dump(chip, port, &mdb->obj, cb);
	mutex_unlock(&chip->reg_lock);

	return err;
}

3855
static struct dsa_switch_ops mv88e6xxx_switch_ops = {
3856
	.probe			= mv88e6xxx_drv_probe,
3857
	.get_tag_protocol	= mv88e6xxx_get_tag_protocol,
3858 3859 3860 3861 3862 3863 3864 3865 3866 3867 3868 3869 3870 3871
	.setup			= mv88e6xxx_setup,
	.set_addr		= mv88e6xxx_set_addr,
	.adjust_link		= mv88e6xxx_adjust_link,
	.get_strings		= mv88e6xxx_get_strings,
	.get_ethtool_stats	= mv88e6xxx_get_ethtool_stats,
	.get_sset_count		= mv88e6xxx_get_sset_count,
	.set_eee		= mv88e6xxx_set_eee,
	.get_eee		= mv88e6xxx_get_eee,
#ifdef CONFIG_NET_DSA_HWMON
	.get_temp		= mv88e6xxx_get_temp,
	.get_temp_limit		= mv88e6xxx_get_temp_limit,
	.set_temp_limit		= mv88e6xxx_set_temp_limit,
	.get_temp_alarm		= mv88e6xxx_get_temp_alarm,
#endif
3872
	.get_eeprom_len		= mv88e6xxx_get_eeprom_len,
3873 3874 3875 3876
	.get_eeprom		= mv88e6xxx_get_eeprom,
	.set_eeprom		= mv88e6xxx_set_eeprom,
	.get_regs_len		= mv88e6xxx_get_regs_len,
	.get_regs		= mv88e6xxx_get_regs,
3877
	.set_ageing_time	= mv88e6xxx_set_ageing_time,
3878 3879 3880
	.port_bridge_join	= mv88e6xxx_port_bridge_join,
	.port_bridge_leave	= mv88e6xxx_port_bridge_leave,
	.port_stp_state_set	= mv88e6xxx_port_stp_state_set,
3881
	.port_fast_age		= mv88e6xxx_port_fast_age,
3882 3883 3884 3885 3886 3887 3888 3889 3890
	.port_vlan_filtering	= mv88e6xxx_port_vlan_filtering,
	.port_vlan_prepare	= mv88e6xxx_port_vlan_prepare,
	.port_vlan_add		= mv88e6xxx_port_vlan_add,
	.port_vlan_del		= mv88e6xxx_port_vlan_del,
	.port_vlan_dump		= mv88e6xxx_port_vlan_dump,
	.port_fdb_prepare       = mv88e6xxx_port_fdb_prepare,
	.port_fdb_add           = mv88e6xxx_port_fdb_add,
	.port_fdb_del           = mv88e6xxx_port_fdb_del,
	.port_fdb_dump          = mv88e6xxx_port_fdb_dump,
3891 3892 3893 3894
	.port_mdb_prepare       = mv88e6xxx_port_mdb_prepare,
	.port_mdb_add           = mv88e6xxx_port_mdb_add,
	.port_mdb_del           = mv88e6xxx_port_mdb_del,
	.port_mdb_dump          = mv88e6xxx_port_mdb_dump,
3895 3896
};

3897
static int mv88e6xxx_register_switch(struct mv88e6xxx_chip *chip,
3898 3899
				     struct device_node *np)
{
3900
	struct device *dev = chip->dev;
3901 3902 3903 3904 3905 3906 3907
	struct dsa_switch *ds;

	ds = devm_kzalloc(dev, sizeof(*ds), GFP_KERNEL);
	if (!ds)
		return -ENOMEM;

	ds->dev = dev;
3908
	ds->priv = chip;
3909
	ds->ops = &mv88e6xxx_switch_ops;
3910 3911 3912 3913 3914 3915

	dev_set_drvdata(dev, ds);

	return dsa_register_switch(ds, np);
}

3916
static void mv88e6xxx_unregister_switch(struct mv88e6xxx_chip *chip)
3917
{
3918
	dsa_unregister_switch(chip->ds);
3919 3920
}

3921
static int mv88e6xxx_probe(struct mdio_device *mdiodev)
3922
{
3923
	struct device *dev = &mdiodev->dev;
3924
	struct device_node *np = dev->of_node;
3925
	const struct mv88e6xxx_info *compat_info;
3926
	struct mv88e6xxx_chip *chip;
3927
	u32 eeprom_len;
3928
	int err;
3929

3930 3931 3932 3933
	compat_info = of_device_get_match_data(dev);
	if (!compat_info)
		return -EINVAL;

3934 3935
	chip = mv88e6xxx_alloc_chip(dev);
	if (!chip)
3936 3937
		return -ENOMEM;

3938
	chip->info = compat_info;
3939

3940
	err = mv88e6xxx_smi_init(chip, mdiodev->bus, mdiodev->addr);
3941 3942
	if (err)
		return err;
3943

3944
	err = mv88e6xxx_detect(chip);
3945 3946
	if (err)
		return err;
3947

3948 3949
	mv88e6xxx_phy_init(chip);

3950 3951 3952
	chip->reset = devm_gpiod_get_optional(dev, "reset", GPIOD_ASIS);
	if (IS_ERR(chip->reset))
		return PTR_ERR(chip->reset);
3953

3954
	if (chip->info->ops->get_eeprom &&
3955
	    !of_property_read_u32(np, "eeprom-length", &eeprom_len))
3956
		chip->eeprom_len = eeprom_len;
3957

3958 3959 3960 3961 3962 3963 3964 3965 3966 3967 3968 3969 3970 3971 3972 3973 3974 3975 3976 3977 3978 3979 3980 3981 3982 3983 3984 3985 3986 3987 3988
	mutex_lock(&chip->reg_lock);
	err = mv88e6xxx_switch_reset(chip);
	mutex_unlock(&chip->reg_lock);
	if (err)
		goto out;

	chip->irq = of_irq_get(np, 0);
	if (chip->irq == -EPROBE_DEFER) {
		err = chip->irq;
		goto out;
	}

	if (chip->irq > 0) {
		/* Has to be performed before the MDIO bus is created,
		 * because the PHYs will link there interrupts to these
		 * interrupt controllers
		 */
		mutex_lock(&chip->reg_lock);
		err = mv88e6xxx_g1_irq_setup(chip);
		mutex_unlock(&chip->reg_lock);

		if (err)
			goto out;

		if (mv88e6xxx_has(chip, MV88E6XXX_FLAG_G2_INT)) {
			err = mv88e6xxx_g2_irq_setup(chip);
			if (err)
				goto out_g1_irq;
		}
	}

3989
	err = mv88e6xxx_mdio_register(chip, np);
3990
	if (err)
3991
		goto out_g2_irq;
3992

3993
	err = mv88e6xxx_register_switch(chip, np);
3994 3995
	if (err)
		goto out_mdio;
3996

3997
	return 0;
3998 3999 4000 4001 4002 4003 4004 4005 4006 4007

out_mdio:
	mv88e6xxx_mdio_unregister(chip);
out_g2_irq:
	if (mv88e6xxx_has(chip, MV88E6XXX_FLAG_G2_INT))
		mv88e6xxx_g2_irq_free(chip);
out_g1_irq:
	mv88e6xxx_g1_irq_free(chip);
out:
	return err;
4008
}
4009 4010 4011 4012

static void mv88e6xxx_remove(struct mdio_device *mdiodev)
{
	struct dsa_switch *ds = dev_get_drvdata(&mdiodev->dev);
V
Vivien Didelot 已提交
4013
	struct mv88e6xxx_chip *chip = ds->priv;
4014

4015
	mv88e6xxx_phy_destroy(chip);
4016 4017
	mv88e6xxx_unregister_switch(chip);
	mv88e6xxx_mdio_unregister(chip);
4018 4019 4020 4021

	if (mv88e6xxx_has(chip, MV88E6XXX_FLAG_G2_INT))
		mv88e6xxx_g2_irq_free(chip);
	mv88e6xxx_g1_irq_free(chip);
4022 4023 4024
}

static const struct of_device_id mv88e6xxx_of_match[] = {
4025 4026 4027 4028
	{
		.compatible = "marvell,mv88e6085",
		.data = &mv88e6xxx_table[MV88E6085],
	},
4029 4030 4031 4032 4033 4034 4035 4036 4037 4038 4039 4040 4041 4042 4043 4044
	{ /* sentinel */ },
};

MODULE_DEVICE_TABLE(of, mv88e6xxx_of_match);

static struct mdio_driver mv88e6xxx_driver = {
	.probe	= mv88e6xxx_probe,
	.remove = mv88e6xxx_remove,
	.mdiodrv.driver = {
		.name = "mv88e6085",
		.of_match_table = mv88e6xxx_of_match,
	},
};

static int __init mv88e6xxx_init(void)
{
4045
	register_switch_driver(&mv88e6xxx_switch_ops);
4046 4047
	return mdio_driver_register(&mv88e6xxx_driver);
}
4048 4049 4050 4051
module_init(mv88e6xxx_init);

static void __exit mv88e6xxx_cleanup(void)
{
4052
	mdio_driver_unregister(&mv88e6xxx_driver);
4053
	unregister_switch_driver(&mv88e6xxx_switch_ops);
4054 4055
}
module_exit(mv88e6xxx_cleanup);
4056 4057 4058 4059

MODULE_AUTHOR("Lennert Buytenhek <buytenh@wantstofly.org>");
MODULE_DESCRIPTION("Driver for Marvell 88E6XXX ethernet switch chips");
MODULE_LICENSE("GPL");