chip.c 97.0 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

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

49 50 51 52 53 54 55 56 57 58
/* 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.
59
 */
60

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

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

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

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

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

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

	*val = ret & 0xffff;

	return 0;
}

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

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

	return 0;
}

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

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

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

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

	return -ETIMEDOUT;
}

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

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

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

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

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

153
	*val = ret & 0xffff;
154

155
	return 0;
156 157
}

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

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

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

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

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

	return 0;
}

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

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

196
	assert_reg_lock(chip);
197

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

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

	return 0;
}

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

212
	assert_reg_lock(chip);
213

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

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

221 222 223
	return 0;
}

224 225
static int mv88e6xxx_port_read(struct mv88e6xxx_chip *chip, int port, int reg,
			       u16 *val)
226 227 228 229 230 231
{
	int addr = chip->info->port_base_addr + port;

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

232 233
static int mv88e6xxx_port_write(struct mv88e6xxx_chip *chip, int port, int reg,
				u16 val)
234 235 236 237 238 239
{
	int addr = chip->info->port_base_addr + port;

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

240 241 242 243 244
static int mv88e6xxx_phy_read(struct mv88e6xxx_chip *chip, int phy,
			      int reg, u16 *val)
{
	int addr = phy; /* PHY devices addresses start at 0x0 */

245
	if (!chip->info->ops->phy_read)
246 247
		return -EOPNOTSUPP;

248
	return chip->info->ops->phy_read(chip, addr, reg, val);
249 250 251 252 253 254 255
}

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

256
	if (!chip->info->ops->phy_write)
257 258
		return -EOPNOTSUPP;

259
	return chip->info->ops->phy_write(chip, addr, reg, val);
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 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329
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);
}

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 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487
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;
}

488
int mv88e6xxx_wait(struct mv88e6xxx_chip *chip, int addr, int reg, u16 mask)
489
{
490
	int i;
491

492
	for (i = 0; i < 16; i++) {
493 494 495 496 497 498 499 500 501 502 503 504 505
		u16 val;
		int err;

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

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

		usleep_range(1000, 2000);
	}

506
	dev_err(chip->dev, "Timeout while waiting for switch\n");
507 508 509
	return -ETIMEDOUT;
}

510
/* Indirect write to single pointer-data register with an Update bit */
511
int mv88e6xxx_update(struct mv88e6xxx_chip *chip, int addr, int reg, u16 update)
512 513
{
	u16 val;
514
	int err;
515 516

	/* Wait until the previous operation is completed */
517 518 519
	err = mv88e6xxx_wait(chip, addr, reg, BIT(15));
	if (err)
		return err;
520 521 522 523 524 525 526

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

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

527
static int mv88e6xxx_ppu_disable(struct mv88e6xxx_chip *chip)
528 529
{
	u16 val;
530
	int i, err;
531

532
	err = mv88e6xxx_g1_read(chip, GLOBAL_CONTROL, &val);
533 534 535
	if (err)
		return err;

536 537 538 539
	err = mv88e6xxx_g1_write(chip, GLOBAL_CONTROL,
				 val & ~GLOBAL_CONTROL_PPU_ENABLE);
	if (err)
		return err;
540

541
	for (i = 0; i < 16; i++) {
542 543 544
		err = mv88e6xxx_g1_read(chip, GLOBAL_STATUS, &val);
		if (err)
			return err;
545

546
		usleep_range(1000, 2000);
547
		if ((val & GLOBAL_STATUS_PPU_MASK) != GLOBAL_STATUS_PPU_POLLING)
548
			return 0;
549 550 551 552 553
	}

	return -ETIMEDOUT;
}

554
static int mv88e6xxx_ppu_enable(struct mv88e6xxx_chip *chip)
555
{
556 557
	u16 val;
	int i, err;
558

559 560 561
	err = mv88e6xxx_g1_read(chip, GLOBAL_CONTROL, &val);
	if (err)
		return err;
562

563 564
	err = mv88e6xxx_g1_write(chip, GLOBAL_CONTROL,
				 val | GLOBAL_CONTROL_PPU_ENABLE);
565 566
	if (err)
		return err;
567

568
	for (i = 0; i < 16; i++) {
569 570 571
		err = mv88e6xxx_g1_read(chip, GLOBAL_STATUS, &val);
		if (err)
			return err;
572

573
		usleep_range(1000, 2000);
574
		if ((val & GLOBAL_STATUS_PPU_MASK) == GLOBAL_STATUS_PPU_POLLING)
575
			return 0;
576 577 578 579 580 581 582
	}

	return -ETIMEDOUT;
}

static void mv88e6xxx_ppu_reenable_work(struct work_struct *ugly)
{
583
	struct mv88e6xxx_chip *chip;
584

585
	chip = container_of(ugly, struct mv88e6xxx_chip, ppu_work);
586

587
	mutex_lock(&chip->reg_lock);
588

589 590 591 592
	if (mutex_trylock(&chip->ppu_mutex)) {
		if (mv88e6xxx_ppu_enable(chip) == 0)
			chip->ppu_disabled = 0;
		mutex_unlock(&chip->ppu_mutex);
593
	}
594

595
	mutex_unlock(&chip->reg_lock);
596 597 598 599
}

static void mv88e6xxx_ppu_reenable_timer(unsigned long _ps)
{
600
	struct mv88e6xxx_chip *chip = (void *)_ps;
601

602
	schedule_work(&chip->ppu_work);
603 604
}

605
static int mv88e6xxx_ppu_access_get(struct mv88e6xxx_chip *chip)
606 607 608
{
	int ret;

609
	mutex_lock(&chip->ppu_mutex);
610

611
	/* If the PHY polling unit is enabled, disable it so that
612 613 614 615
	 * we can access the PHY registers.  If it was already
	 * disabled, cancel the timer that is going to re-enable
	 * it.
	 */
616 617
	if (!chip->ppu_disabled) {
		ret = mv88e6xxx_ppu_disable(chip);
618
		if (ret < 0) {
619
			mutex_unlock(&chip->ppu_mutex);
620 621
			return ret;
		}
622
		chip->ppu_disabled = 1;
623
	} else {
624
		del_timer(&chip->ppu_timer);
625
		ret = 0;
626 627 628 629 630
	}

	return ret;
}

631
static void mv88e6xxx_ppu_access_put(struct mv88e6xxx_chip *chip)
632
{
633
	/* Schedule a timer to re-enable the PHY polling unit. */
634 635
	mod_timer(&chip->ppu_timer, jiffies + msecs_to_jiffies(10));
	mutex_unlock(&chip->ppu_mutex);
636 637
}

638
static void mv88e6xxx_ppu_state_init(struct mv88e6xxx_chip *chip)
639
{
640 641
	mutex_init(&chip->ppu_mutex);
	INIT_WORK(&chip->ppu_work, mv88e6xxx_ppu_reenable_work);
642 643
	setup_timer(&chip->ppu_timer, mv88e6xxx_ppu_reenable_timer,
		    (unsigned long)chip);
644 645
}

646 647 648 649 650
static void mv88e6xxx_ppu_state_destroy(struct mv88e6xxx_chip *chip)
{
	del_timer_sync(&chip->ppu_timer);
}

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

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

662
	return err;
663 664
}

665 666
static int mv88e6xxx_phy_ppu_write(struct mv88e6xxx_chip *chip, int addr,
				   int reg, u16 val)
667
{
668
	int err;
669

670 671 672
	err = mv88e6xxx_ppu_access_get(chip);
	if (!err) {
		err = mv88e6xxx_write(chip, addr, reg, val);
673
		mv88e6xxx_ppu_access_put(chip);
674 675
	}

676
	return err;
677 678
}

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

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

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

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

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

704
static bool mv88e6xxx_6320_family(struct mv88e6xxx_chip *chip)
705
{
706
	return chip->info->family == MV88E6XXX_FAMILY_6320;
707 708
}

709
static bool mv88e6xxx_6351_family(struct mv88e6xxx_chip *chip)
710
{
711
	return chip->info->family == MV88E6XXX_FAMILY_6351;
712 713
}

714
static bool mv88e6xxx_6352_family(struct mv88e6xxx_chip *chip)
715
{
716
	return chip->info->family == MV88E6XXX_FAMILY_6352;
717 718
}

719 720 721 722
/* 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.
 */
723 724
static void mv88e6xxx_adjust_link(struct dsa_switch *ds, int port,
				  struct phy_device *phydev)
725
{
V
Vivien Didelot 已提交
726
	struct mv88e6xxx_chip *chip = ds->priv;
727 728
	u16 reg;
	int err;
729 730 731 732

	if (!phy_is_pseudo_fixed_link(phydev))
		return;

733
	mutex_lock(&chip->reg_lock);
734

735 736
	err = mv88e6xxx_port_read(chip, port, PORT_PCS_CTRL, &reg);
	if (err)
737 738
		goto out;

739 740 741 742 743
	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);
744 745 746

	reg |= PORT_PCS_CTRL_FORCE_LINK;
	if (phydev->link)
747
		reg |= PORT_PCS_CTRL_LINK_UP;
748

749
	if (mv88e6xxx_6065_family(chip) && phydev->speed > SPEED_100)
750 751 752 753 754 755 756 757 758 759 760 761 762 763 764 765 766 767 768 769 770
		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;

771
	if ((mv88e6xxx_6352_family(chip) || mv88e6xxx_6351_family(chip)) &&
772
	    (port >= mv88e6xxx_num_ports(chip) - 2)) {
773 774 775 776 777 778 779 780
		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);
	}
781
	mv88e6xxx_port_write(chip, port, PORT_PCS_CTRL, reg);
782 783

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

787
static int _mv88e6xxx_stats_wait(struct mv88e6xxx_chip *chip)
788
{
789 790
	u16 val;
	int i, err;
791 792

	for (i = 0; i < 10; i++) {
793 794
		err = mv88e6xxx_g1_read(chip, GLOBAL_STATS_OP, &val);
		if ((val & GLOBAL_STATS_OP_BUSY) == 0)
795 796 797 798 799 800
			return 0;
	}

	return -ETIMEDOUT;
}

801
static int _mv88e6xxx_stats_snapshot(struct mv88e6xxx_chip *chip, int port)
802
{
803
	int err;
804

805
	if (mv88e6xxx_6320_family(chip) || mv88e6xxx_6352_family(chip))
806 807
		port = (port + 1) << 5;

808
	/* Snapshot the hardware statistics counters for this port. */
809 810 811 812 813
	err = mv88e6xxx_g1_write(chip, GLOBAL_STATS_OP,
				 GLOBAL_STATS_OP_CAPTURE_PORT |
				 GLOBAL_STATS_OP_HIST_RX_TX | port);
	if (err)
		return err;
814

815
	/* Wait for the snapshotting to complete. */
816
	return _mv88e6xxx_stats_wait(chip);
817 818
}

819
static void _mv88e6xxx_stats_read(struct mv88e6xxx_chip *chip,
820
				  int stat, u32 *val)
821
{
822 823 824
	u32 value;
	u16 reg;
	int err;
825 826 827

	*val = 0;

828 829 830 831
	err = mv88e6xxx_g1_write(chip, GLOBAL_STATS_OP,
				 GLOBAL_STATS_OP_READ_CAPTURED |
				 GLOBAL_STATS_OP_HIST_RX_TX | stat);
	if (err)
832 833
		return;

834 835
	err = _mv88e6xxx_stats_wait(chip);
	if (err)
836 837
		return;

838 839
	err = mv88e6xxx_g1_read(chip, GLOBAL_STATS_COUNTER_32, &reg);
	if (err)
840 841
		return;

842
	value = reg << 16;
843

844 845
	err = mv88e6xxx_g1_read(chip, GLOBAL_STATS_COUNTER_01, &reg);
	if (err)
846 847
		return;

848
	*val = value | reg;
849 850
}

851
static struct mv88e6xxx_hw_stat mv88e6xxx_hw_stats[] = {
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 896 897 898 899 900 901 902 903 904 905 906 907 908 909 910
	{ "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, },
911 912
};

913
static bool mv88e6xxx_has_stat(struct mv88e6xxx_chip *chip,
914
			       struct mv88e6xxx_hw_stat *stat)
915
{
916 917
	switch (stat->type) {
	case BANK0:
918
		return true;
919
	case BANK1:
920
		return mv88e6xxx_6320_family(chip);
921
	case PORT:
922 923 924 925 926 927
		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);
928
	}
929
	return false;
930 931
}

932
static uint64_t _mv88e6xxx_get_ethtool_stat(struct mv88e6xxx_chip *chip,
933
					    struct mv88e6xxx_hw_stat *s,
934 935 936 937
					    int port)
{
	u32 low;
	u32 high = 0;
938 939
	int err;
	u16 reg;
940 941
	u64 value;

942 943
	switch (s->type) {
	case PORT:
944 945
		err = mv88e6xxx_port_read(chip, port, s->reg, &reg);
		if (err)
946 947
			return UINT64_MAX;

948
		low = reg;
949
		if (s->sizeof_stat == 4) {
950 951
			err = mv88e6xxx_port_read(chip, port, s->reg + 1, &reg);
			if (err)
952
				return UINT64_MAX;
953
			high = reg;
954
		}
955 956 957
		break;
	case BANK0:
	case BANK1:
958
		_mv88e6xxx_stats_read(chip, s->reg, &low);
959
		if (s->sizeof_stat == 8)
960
			_mv88e6xxx_stats_read(chip, s->reg + 1, &high);
961 962 963 964 965
	}
	value = (((u64)high) << 16) | low;
	return value;
}

966 967
static void mv88e6xxx_get_strings(struct dsa_switch *ds, int port,
				  uint8_t *data)
968
{
V
Vivien Didelot 已提交
969
	struct mv88e6xxx_chip *chip = ds->priv;
970 971
	struct mv88e6xxx_hw_stat *stat;
	int i, j;
972

973 974
	for (i = 0, j = 0; i < ARRAY_SIZE(mv88e6xxx_hw_stats); i++) {
		stat = &mv88e6xxx_hw_stats[i];
975
		if (mv88e6xxx_has_stat(chip, stat)) {
976 977 978 979
			memcpy(data + j * ETH_GSTRING_LEN, stat->string,
			       ETH_GSTRING_LEN);
			j++;
		}
980
	}
981 982
}

983
static int mv88e6xxx_get_sset_count(struct dsa_switch *ds)
984
{
V
Vivien Didelot 已提交
985
	struct mv88e6xxx_chip *chip = ds->priv;
986 987 988 989 990
	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];
991
		if (mv88e6xxx_has_stat(chip, stat))
992 993 994
			j++;
	}
	return j;
995 996
}

997 998
static void mv88e6xxx_get_ethtool_stats(struct dsa_switch *ds, int port,
					uint64_t *data)
999
{
V
Vivien Didelot 已提交
1000
	struct mv88e6xxx_chip *chip = ds->priv;
1001 1002 1003 1004
	struct mv88e6xxx_hw_stat *stat;
	int ret;
	int i, j;

1005
	mutex_lock(&chip->reg_lock);
1006

1007
	ret = _mv88e6xxx_stats_snapshot(chip, port);
1008
	if (ret < 0) {
1009
		mutex_unlock(&chip->reg_lock);
1010 1011 1012 1013
		return;
	}
	for (i = 0, j = 0; i < ARRAY_SIZE(mv88e6xxx_hw_stats); i++) {
		stat = &mv88e6xxx_hw_stats[i];
1014 1015
		if (mv88e6xxx_has_stat(chip, stat)) {
			data[j] = _mv88e6xxx_get_ethtool_stat(chip, stat, port);
1016 1017 1018 1019
			j++;
		}
	}

1020
	mutex_unlock(&chip->reg_lock);
1021 1022
}

1023
static int mv88e6xxx_get_regs_len(struct dsa_switch *ds, int port)
1024 1025 1026 1027
{
	return 32 * sizeof(u16);
}

1028 1029
static void mv88e6xxx_get_regs(struct dsa_switch *ds, int port,
			       struct ethtool_regs *regs, void *_p)
1030
{
V
Vivien Didelot 已提交
1031
	struct mv88e6xxx_chip *chip = ds->priv;
1032 1033
	int err;
	u16 reg;
1034 1035 1036 1037 1038 1039 1040
	u16 *p = _p;
	int i;

	regs->version = 0;

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

1041
	mutex_lock(&chip->reg_lock);
1042

1043 1044
	for (i = 0; i < 32; i++) {

1045 1046 1047
		err = mv88e6xxx_port_read(chip, port, i, &reg);
		if (!err)
			p[i] = reg;
1048
	}
1049

1050
	mutex_unlock(&chip->reg_lock);
1051 1052
}

1053
static int _mv88e6xxx_atu_wait(struct mv88e6xxx_chip *chip)
1054
{
1055
	return mv88e6xxx_g1_wait(chip, GLOBAL_ATU_OP, GLOBAL_ATU_OP_BUSY);
1056 1057
}

1058 1059
static int mv88e6xxx_get_eee(struct dsa_switch *ds, int port,
			     struct ethtool_eee *e)
1060
{
V
Vivien Didelot 已提交
1061
	struct mv88e6xxx_chip *chip = ds->priv;
1062 1063
	u16 reg;
	int err;
1064

1065
	if (!mv88e6xxx_has(chip, MV88E6XXX_FLAG_EEE))
1066 1067
		return -EOPNOTSUPP;

1068
	mutex_lock(&chip->reg_lock);
1069

1070 1071
	err = mv88e6xxx_phy_read(chip, port, 16, &reg);
	if (err)
1072
		goto out;
1073 1074 1075 1076

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

1077
	err = mv88e6xxx_port_read(chip, port, PORT_STATUS, &reg);
1078
	if (err)
1079
		goto out;
1080

1081
	e->eee_active = !!(reg & PORT_STATUS_EEE);
1082
out:
1083
	mutex_unlock(&chip->reg_lock);
1084 1085

	return err;
1086 1087
}

1088 1089
static int mv88e6xxx_set_eee(struct dsa_switch *ds, int port,
			     struct phy_device *phydev, struct ethtool_eee *e)
1090
{
V
Vivien Didelot 已提交
1091
	struct mv88e6xxx_chip *chip = ds->priv;
1092 1093
	u16 reg;
	int err;
1094

1095
	if (!mv88e6xxx_has(chip, MV88E6XXX_FLAG_EEE))
1096 1097
		return -EOPNOTSUPP;

1098
	mutex_lock(&chip->reg_lock);
1099

1100 1101
	err = mv88e6xxx_phy_read(chip, port, 16, &reg);
	if (err)
1102 1103
		goto out;

1104
	reg &= ~0x0300;
1105 1106 1107 1108 1109
	if (e->eee_enabled)
		reg |= 0x0200;
	if (e->tx_lpi_enabled)
		reg |= 0x0100;

1110
	err = mv88e6xxx_phy_write(chip, port, 16, reg);
1111
out:
1112
	mutex_unlock(&chip->reg_lock);
1113

1114
	return err;
1115 1116
}

1117
static int _mv88e6xxx_atu_cmd(struct mv88e6xxx_chip *chip, u16 fid, u16 cmd)
1118
{
1119 1120
	u16 val;
	int err;
1121

1122
	if (mv88e6xxx_has(chip, MV88E6XXX_FLAG_G1_ATU_FID)) {
1123 1124 1125
		err = mv88e6xxx_g1_write(chip, GLOBAL_ATU_FID, fid);
		if (err)
			return err;
1126
	} else if (mv88e6xxx_num_databases(chip) == 256) {
1127
		/* ATU DBNum[7:4] are located in ATU Control 15:12 */
1128 1129 1130
		err = mv88e6xxx_g1_read(chip, GLOBAL_ATU_CONTROL, &val);
		if (err)
			return err;
1131

1132 1133 1134 1135
		err = mv88e6xxx_g1_write(chip, GLOBAL_ATU_CONTROL,
					 (val & 0xfff) | ((fid << 8) & 0xf000));
		if (err)
			return err;
1136 1137 1138

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

1141 1142 1143
	err = mv88e6xxx_g1_write(chip, GLOBAL_ATU_OP, cmd);
	if (err)
		return err;
1144

1145
	return _mv88e6xxx_atu_wait(chip);
1146 1147
}

1148
static int _mv88e6xxx_atu_data_write(struct mv88e6xxx_chip *chip,
1149 1150 1151 1152 1153 1154 1155 1156 1157 1158 1159 1160 1161 1162 1163 1164 1165 1166 1167
				     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;
	}

1168
	return mv88e6xxx_g1_write(chip, GLOBAL_ATU_DATA, data);
1169 1170
}

1171
static int _mv88e6xxx_atu_flush_move(struct mv88e6xxx_chip *chip,
1172 1173
				     struct mv88e6xxx_atu_entry *entry,
				     bool static_too)
1174
{
1175 1176
	int op;
	int err;
1177

1178
	err = _mv88e6xxx_atu_wait(chip);
1179 1180
	if (err)
		return err;
1181

1182
	err = _mv88e6xxx_atu_data_write(chip, entry);
1183 1184 1185 1186 1187 1188 1189 1190 1191 1192 1193
	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;
	}

1194
	return _mv88e6xxx_atu_cmd(chip, entry->fid, op);
1195 1196
}

1197
static int _mv88e6xxx_atu_flush(struct mv88e6xxx_chip *chip,
1198
				u16 fid, bool static_too)
1199 1200 1201 1202 1203
{
	struct mv88e6xxx_atu_entry entry = {
		.fid = fid,
		.state = 0, /* EntryState bits must be 0 */
	};
1204

1205
	return _mv88e6xxx_atu_flush_move(chip, &entry, static_too);
1206 1207
}

1208
static int _mv88e6xxx_atu_move(struct mv88e6xxx_chip *chip, u16 fid,
1209
			       int from_port, int to_port, bool static_too)
1210 1211 1212 1213 1214 1215 1216 1217 1218 1219 1220 1221 1222
{
	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;

1223
	return _mv88e6xxx_atu_flush_move(chip, &entry, static_too);
1224 1225
}

1226
static int _mv88e6xxx_atu_remove(struct mv88e6xxx_chip *chip, u16 fid,
1227
				 int port, bool static_too)
1228 1229
{
	/* Destination port 0xF means remove the entries */
1230
	return _mv88e6xxx_atu_move(chip, fid, port, 0x0f, static_too);
1231 1232
}

1233 1234 1235 1236 1237 1238 1239
static const char * const mv88e6xxx_port_state_names[] = {
	[PORT_CONTROL_STATE_DISABLED] = "Disabled",
	[PORT_CONTROL_STATE_BLOCKING] = "Blocking/Listening",
	[PORT_CONTROL_STATE_LEARNING] = "Learning",
	[PORT_CONTROL_STATE_FORWARDING] = "Forwarding",
};

1240
static int _mv88e6xxx_port_state(struct mv88e6xxx_chip *chip, int port,
1241
				 u8 state)
1242
{
1243
	struct dsa_switch *ds = chip->ds;
1244 1245
	u16 reg;
	int err;
1246 1247
	u8 oldstate;

1248 1249 1250
	err = mv88e6xxx_port_read(chip, port, PORT_CONTROL, &reg);
	if (err)
		return err;
1251

1252
	oldstate = reg & PORT_CONTROL_STATE_MASK;
1253

1254 1255
	reg &= ~PORT_CONTROL_STATE_MASK;
	reg |= state;
1256

1257 1258 1259
	err = mv88e6xxx_port_write(chip, port, PORT_CONTROL, reg);
	if (err)
		return err;
1260

1261 1262 1263
	netdev_dbg(ds->ports[port].netdev, "PortState %s (was %s)\n",
		   mv88e6xxx_port_state_names[state],
		   mv88e6xxx_port_state_names[oldstate]);
1264

1265
	return 0;
1266 1267
}

1268
static int _mv88e6xxx_port_based_vlan_map(struct mv88e6xxx_chip *chip, int port)
1269
{
1270
	struct net_device *bridge = chip->ports[port].bridge_dev;
1271
	const u16 mask = (1 << mv88e6xxx_num_ports(chip)) - 1;
1272
	struct dsa_switch *ds = chip->ds;
1273
	u16 output_ports = 0;
1274 1275
	u16 reg;
	int err;
1276 1277 1278 1279 1280 1281
	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)) {
		output_ports = mask;
	} else {
1282
		for (i = 0; i < mv88e6xxx_num_ports(chip); ++i) {
1283
			/* allow sending frames to every group member */
1284
			if (bridge && chip->ports[i].bridge_dev == bridge)
1285 1286 1287 1288 1289 1290 1291 1292 1293 1294
				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);
1295

1296 1297 1298
	err = mv88e6xxx_port_read(chip, port, PORT_BASE_VLAN, &reg);
	if (err)
		return err;
1299

1300 1301
	reg &= ~mask;
	reg |= output_ports & mask;
1302

1303
	return mv88e6xxx_port_write(chip, port, PORT_BASE_VLAN, reg);
1304 1305
}

1306 1307
static void mv88e6xxx_port_stp_state_set(struct dsa_switch *ds, int port,
					 u8 state)
1308
{
V
Vivien Didelot 已提交
1309
	struct mv88e6xxx_chip *chip = ds->priv;
1310
	int stp_state;
1311
	int err;
1312 1313 1314

	switch (state) {
	case BR_STATE_DISABLED:
1315
		stp_state = PORT_CONTROL_STATE_DISABLED;
1316 1317 1318
		break;
	case BR_STATE_BLOCKING:
	case BR_STATE_LISTENING:
1319
		stp_state = PORT_CONTROL_STATE_BLOCKING;
1320 1321
		break;
	case BR_STATE_LEARNING:
1322
		stp_state = PORT_CONTROL_STATE_LEARNING;
1323 1324 1325
		break;
	case BR_STATE_FORWARDING:
	default:
1326
		stp_state = PORT_CONTROL_STATE_FORWARDING;
1327 1328 1329
		break;
	}

1330 1331 1332
	mutex_lock(&chip->reg_lock);
	err = _mv88e6xxx_port_state(chip, port, stp_state);
	mutex_unlock(&chip->reg_lock);
1333 1334

	if (err)
1335 1336
		netdev_err(ds->ports[port].netdev,
			   "failed to update state to %s\n",
1337
			   mv88e6xxx_port_state_names[stp_state]);
1338 1339
}

1340 1341 1342 1343 1344 1345 1346 1347 1348 1349 1350 1351 1352
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");
}

1353
static int _mv88e6xxx_port_pvid(struct mv88e6xxx_chip *chip, int port,
1354
				u16 *new, u16 *old)
1355
{
1356
	struct dsa_switch *ds = chip->ds;
1357 1358
	u16 pvid, reg;
	int err;
1359

1360 1361 1362
	err = mv88e6xxx_port_read(chip, port, PORT_DEFAULT_VLAN, &reg);
	if (err)
		return err;
1363

1364
	pvid = reg & PORT_DEFAULT_VLAN_MASK;
1365 1366

	if (new) {
1367 1368
		reg &= ~PORT_DEFAULT_VLAN_MASK;
		reg |= *new & PORT_DEFAULT_VLAN_MASK;
1369

1370 1371 1372
		err = mv88e6xxx_port_write(chip, port, PORT_DEFAULT_VLAN, reg);
		if (err)
			return err;
1373

1374 1375
		netdev_dbg(ds->ports[port].netdev,
			   "DefaultVID %d (was %d)\n", *new, pvid);
1376 1377 1378 1379
	}

	if (old)
		*old = pvid;
1380 1381 1382 1383

	return 0;
}

1384
static int _mv88e6xxx_port_pvid_get(struct mv88e6xxx_chip *chip,
1385
				    int port, u16 *pvid)
1386
{
1387
	return _mv88e6xxx_port_pvid(chip, port, NULL, pvid);
1388 1389
}

1390
static int _mv88e6xxx_port_pvid_set(struct mv88e6xxx_chip *chip,
1391
				    int port, u16 pvid)
1392
{
1393
	return _mv88e6xxx_port_pvid(chip, port, &pvid, NULL);
1394 1395
}

1396
static int _mv88e6xxx_vtu_wait(struct mv88e6xxx_chip *chip)
1397
{
1398
	return mv88e6xxx_g1_wait(chip, GLOBAL_VTU_OP, GLOBAL_VTU_OP_BUSY);
1399 1400
}

1401
static int _mv88e6xxx_vtu_cmd(struct mv88e6xxx_chip *chip, u16 op)
1402
{
1403
	int err;
1404

1405 1406 1407
	err = mv88e6xxx_g1_write(chip, GLOBAL_VTU_OP, op);
	if (err)
		return err;
1408

1409
	return _mv88e6xxx_vtu_wait(chip);
1410 1411
}

1412
static int _mv88e6xxx_vtu_stu_flush(struct mv88e6xxx_chip *chip)
1413 1414 1415
{
	int ret;

1416
	ret = _mv88e6xxx_vtu_wait(chip);
1417 1418 1419
	if (ret < 0)
		return ret;

1420
	return _mv88e6xxx_vtu_cmd(chip, GLOBAL_VTU_OP_FLUSH_ALL);
1421 1422
}

1423
static int _mv88e6xxx_vtu_stu_data_read(struct mv88e6xxx_chip *chip,
1424
					struct mv88e6xxx_vtu_entry *entry,
1425 1426 1427
					unsigned int nibble_offset)
{
	u16 regs[3];
1428
	int i, err;
1429 1430

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

1433 1434 1435
		err = mv88e6xxx_g1_read(chip, GLOBAL_VTU_DATA_0_3 + i, reg);
		if (err)
			return err;
1436 1437
	}

1438
	for (i = 0; i < mv88e6xxx_num_ports(chip); ++i) {
1439 1440 1441 1442 1443 1444 1445 1446 1447
		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;
}

1448
static int mv88e6xxx_vtu_data_read(struct mv88e6xxx_chip *chip,
1449
				   struct mv88e6xxx_vtu_entry *entry)
1450
{
1451
	return _mv88e6xxx_vtu_stu_data_read(chip, entry, 0);
1452 1453
}

1454
static int mv88e6xxx_stu_data_read(struct mv88e6xxx_chip *chip,
1455
				   struct mv88e6xxx_vtu_entry *entry)
1456
{
1457
	return _mv88e6xxx_vtu_stu_data_read(chip, entry, 2);
1458 1459
}

1460
static int _mv88e6xxx_vtu_stu_data_write(struct mv88e6xxx_chip *chip,
1461
					 struct mv88e6xxx_vtu_entry *entry,
1462 1463 1464
					 unsigned int nibble_offset)
{
	u16 regs[3] = { 0 };
1465
	int i, err;
1466

1467
	for (i = 0; i < mv88e6xxx_num_ports(chip); ++i) {
1468 1469 1470 1471 1472 1473 1474
		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) {
1475 1476 1477 1478 1479
		u16 reg = regs[i];

		err = mv88e6xxx_g1_write(chip, GLOBAL_VTU_DATA_0_3 + i, reg);
		if (err)
			return err;
1480 1481 1482 1483 1484
	}

	return 0;
}

1485
static int mv88e6xxx_vtu_data_write(struct mv88e6xxx_chip *chip,
1486
				    struct mv88e6xxx_vtu_entry *entry)
1487
{
1488
	return _mv88e6xxx_vtu_stu_data_write(chip, entry, 0);
1489 1490
}

1491
static int mv88e6xxx_stu_data_write(struct mv88e6xxx_chip *chip,
1492
				    struct mv88e6xxx_vtu_entry *entry)
1493
{
1494
	return _mv88e6xxx_vtu_stu_data_write(chip, entry, 2);
1495 1496
}

1497
static int _mv88e6xxx_vtu_vid_write(struct mv88e6xxx_chip *chip, u16 vid)
1498
{
1499 1500
	return mv88e6xxx_g1_write(chip, GLOBAL_VTU_VID,
				  vid & GLOBAL_VTU_VID_MASK);
1501 1502
}

1503
static int _mv88e6xxx_vtu_getnext(struct mv88e6xxx_chip *chip,
1504
				  struct mv88e6xxx_vtu_entry *entry)
1505
{
1506
	struct mv88e6xxx_vtu_entry next = { 0 };
1507 1508
	u16 val;
	int err;
1509

1510 1511 1512
	err = _mv88e6xxx_vtu_wait(chip);
	if (err)
		return err;
1513

1514 1515 1516
	err = _mv88e6xxx_vtu_cmd(chip, GLOBAL_VTU_OP_VTU_GET_NEXT);
	if (err)
		return err;
1517

1518 1519 1520
	err = mv88e6xxx_g1_read(chip, GLOBAL_VTU_VID, &val);
	if (err)
		return err;
1521

1522 1523
	next.vid = val & GLOBAL_VTU_VID_MASK;
	next.valid = !!(val & GLOBAL_VTU_VID_VALID);
1524 1525

	if (next.valid) {
1526 1527 1528
		err = mv88e6xxx_vtu_data_read(chip, &next);
		if (err)
			return err;
1529

1530
		if (mv88e6xxx_has(chip, MV88E6XXX_FLAG_G1_VTU_FID)) {
1531 1532 1533
			err = mv88e6xxx_g1_read(chip, GLOBAL_VTU_FID, &val);
			if (err)
				return err;
1534

1535
			next.fid = val & GLOBAL_VTU_FID_MASK;
1536
		} else if (mv88e6xxx_num_databases(chip) == 256) {
1537 1538 1539
			/* VTU DBNum[7:4] are located in VTU Operation 11:8, and
			 * VTU DBNum[3:0] are located in VTU Operation 3:0
			 */
1540 1541 1542
			err = mv88e6xxx_g1_read(chip, GLOBAL_VTU_OP, &val);
			if (err)
				return err;
1543

1544 1545
			next.fid = (val & 0xf00) >> 4;
			next.fid |= val & 0xf;
1546
		}
1547

1548
		if (mv88e6xxx_has(chip, MV88E6XXX_FLAG_STU)) {
1549 1550 1551
			err = mv88e6xxx_g1_read(chip, GLOBAL_VTU_SID, &val);
			if (err)
				return err;
1552

1553
			next.sid = val & GLOBAL_VTU_SID_MASK;
1554 1555 1556 1557 1558 1559 1560
		}
	}

	*entry = next;
	return 0;
}

1561 1562 1563
static int mv88e6xxx_port_vlan_dump(struct dsa_switch *ds, int port,
				    struct switchdev_obj_port_vlan *vlan,
				    int (*cb)(struct switchdev_obj *obj))
1564
{
V
Vivien Didelot 已提交
1565
	struct mv88e6xxx_chip *chip = ds->priv;
1566
	struct mv88e6xxx_vtu_entry next;
1567 1568 1569
	u16 pvid;
	int err;

1570
	if (!mv88e6xxx_has(chip, MV88E6XXX_FLAG_VTU))
1571 1572
		return -EOPNOTSUPP;

1573
	mutex_lock(&chip->reg_lock);
1574

1575
	err = _mv88e6xxx_port_pvid_get(chip, port, &pvid);
1576 1577 1578
	if (err)
		goto unlock;

1579
	err = _mv88e6xxx_vtu_vid_write(chip, GLOBAL_VTU_VID_MASK);
1580 1581 1582 1583
	if (err)
		goto unlock;

	do {
1584
		err = _mv88e6xxx_vtu_getnext(chip, &next);
1585 1586 1587 1588 1589 1590 1591 1592 1593 1594
		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 */
1595 1596
		vlan->vid_begin = next.vid;
		vlan->vid_end = next.vid;
1597 1598 1599 1600 1601 1602 1603 1604 1605 1606 1607 1608 1609 1610
		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:
1611
	mutex_unlock(&chip->reg_lock);
1612 1613 1614 1615

	return err;
}

1616
static int _mv88e6xxx_vtu_loadpurge(struct mv88e6xxx_chip *chip,
1617
				    struct mv88e6xxx_vtu_entry *entry)
1618
{
1619
	u16 op = GLOBAL_VTU_OP_VTU_LOAD_PURGE;
1620
	u16 reg = 0;
1621
	int err;
1622

1623 1624 1625
	err = _mv88e6xxx_vtu_wait(chip);
	if (err)
		return err;
1626 1627 1628 1629 1630

	if (!entry->valid)
		goto loadpurge;

	/* Write port member tags */
1631 1632 1633
	err = mv88e6xxx_vtu_data_write(chip, entry);
	if (err)
		return err;
1634

1635
	if (mv88e6xxx_has(chip, MV88E6XXX_FLAG_STU)) {
1636
		reg = entry->sid & GLOBAL_VTU_SID_MASK;
1637 1638 1639
		err = mv88e6xxx_g1_write(chip, GLOBAL_VTU_SID, reg);
		if (err)
			return err;
1640
	}
1641

1642
	if (mv88e6xxx_has(chip, MV88E6XXX_FLAG_G1_VTU_FID)) {
1643
		reg = entry->fid & GLOBAL_VTU_FID_MASK;
1644 1645 1646
		err = mv88e6xxx_g1_write(chip, GLOBAL_VTU_FID, reg);
		if (err)
			return err;
1647
	} else if (mv88e6xxx_num_databases(chip) == 256) {
1648 1649 1650 1651 1652
		/* 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;
1653 1654 1655 1656 1657
	}

	reg = GLOBAL_VTU_VID_VALID;
loadpurge:
	reg |= entry->vid & GLOBAL_VTU_VID_MASK;
1658 1659 1660
	err = mv88e6xxx_g1_write(chip, GLOBAL_VTU_VID, reg);
	if (err)
		return err;
1661

1662
	return _mv88e6xxx_vtu_cmd(chip, op);
1663 1664
}

1665
static int _mv88e6xxx_stu_getnext(struct mv88e6xxx_chip *chip, u8 sid,
1666
				  struct mv88e6xxx_vtu_entry *entry)
1667
{
1668
	struct mv88e6xxx_vtu_entry next = { 0 };
1669 1670
	u16 val;
	int err;
1671

1672 1673 1674
	err = _mv88e6xxx_vtu_wait(chip);
	if (err)
		return err;
1675

1676 1677 1678 1679
	err = mv88e6xxx_g1_write(chip, GLOBAL_VTU_SID,
				 sid & GLOBAL_VTU_SID_MASK);
	if (err)
		return err;
1680

1681 1682 1683
	err = _mv88e6xxx_vtu_cmd(chip, GLOBAL_VTU_OP_STU_GET_NEXT);
	if (err)
		return err;
1684

1685 1686 1687
	err = mv88e6xxx_g1_read(chip, GLOBAL_VTU_SID, &val);
	if (err)
		return err;
1688

1689
	next.sid = val & GLOBAL_VTU_SID_MASK;
1690

1691 1692 1693
	err = mv88e6xxx_g1_read(chip, GLOBAL_VTU_VID, &val);
	if (err)
		return err;
1694

1695
	next.valid = !!(val & GLOBAL_VTU_VID_VALID);
1696 1697

	if (next.valid) {
1698 1699 1700
		err = mv88e6xxx_stu_data_read(chip, &next);
		if (err)
			return err;
1701 1702 1703 1704 1705 1706
	}

	*entry = next;
	return 0;
}

1707
static int _mv88e6xxx_stu_loadpurge(struct mv88e6xxx_chip *chip,
1708
				    struct mv88e6xxx_vtu_entry *entry)
1709 1710
{
	u16 reg = 0;
1711
	int err;
1712

1713 1714 1715
	err = _mv88e6xxx_vtu_wait(chip);
	if (err)
		return err;
1716 1717 1718 1719 1720

	if (!entry->valid)
		goto loadpurge;

	/* Write port states */
1721 1722 1723
	err = mv88e6xxx_stu_data_write(chip, entry);
	if (err)
		return err;
1724 1725 1726

	reg = GLOBAL_VTU_VID_VALID;
loadpurge:
1727 1728 1729
	err = mv88e6xxx_g1_write(chip, GLOBAL_VTU_VID, reg);
	if (err)
		return err;
1730 1731

	reg = entry->sid & GLOBAL_VTU_SID_MASK;
1732 1733 1734
	err = mv88e6xxx_g1_write(chip, GLOBAL_VTU_SID, reg);
	if (err)
		return err;
1735

1736
	return _mv88e6xxx_vtu_cmd(chip, GLOBAL_VTU_OP_STU_LOAD_PURGE);
1737 1738
}

1739
static int _mv88e6xxx_port_fid(struct mv88e6xxx_chip *chip, int port,
1740
			       u16 *new, u16 *old)
1741
{
1742
	struct dsa_switch *ds = chip->ds;
1743
	u16 upper_mask;
1744
	u16 fid;
1745 1746
	u16 reg;
	int err;
1747

1748
	if (mv88e6xxx_num_databases(chip) == 4096)
1749
		upper_mask = 0xff;
1750
	else if (mv88e6xxx_num_databases(chip) == 256)
1751
		upper_mask = 0xf;
1752 1753 1754
	else
		return -EOPNOTSUPP;

1755
	/* Port's default FID bits 3:0 are located in reg 0x06, offset 12 */
1756 1757 1758
	err = mv88e6xxx_port_read(chip, port, PORT_BASE_VLAN, &reg);
	if (err)
		return err;
1759

1760
	fid = (reg & PORT_BASE_VLAN_FID_3_0_MASK) >> 12;
1761 1762

	if (new) {
1763 1764
		reg &= ~PORT_BASE_VLAN_FID_3_0_MASK;
		reg |= (*new << 12) & PORT_BASE_VLAN_FID_3_0_MASK;
1765

1766 1767 1768
		err = mv88e6xxx_port_write(chip, port, PORT_BASE_VLAN, reg);
		if (err)
			return err;
1769 1770 1771
	}

	/* Port's default FID bits 11:4 are located in reg 0x05, offset 0 */
1772 1773 1774
	err = mv88e6xxx_port_read(chip, port, PORT_CONTROL_1, &reg);
	if (err)
		return err;
1775

1776
	fid |= (reg & upper_mask) << 4;
1777 1778

	if (new) {
1779 1780
		reg &= ~upper_mask;
		reg |= (*new >> 4) & upper_mask;
1781

1782 1783 1784
		err = mv88e6xxx_port_write(chip, port, PORT_CONTROL_1, reg);
		if (err)
			return err;
1785

1786 1787
		netdev_dbg(ds->ports[port].netdev,
			   "FID %d (was %d)\n", *new, fid);
1788 1789 1790 1791 1792 1793 1794 1795
	}

	if (old)
		*old = fid;

	return 0;
}

1796
static int _mv88e6xxx_port_fid_get(struct mv88e6xxx_chip *chip,
1797
				   int port, u16 *fid)
1798
{
1799
	return _mv88e6xxx_port_fid(chip, port, NULL, fid);
1800 1801
}

1802
static int _mv88e6xxx_port_fid_set(struct mv88e6xxx_chip *chip,
1803
				   int port, u16 fid)
1804
{
1805
	return _mv88e6xxx_port_fid(chip, port, &fid, NULL);
1806 1807
}

1808
static int _mv88e6xxx_fid_new(struct mv88e6xxx_chip *chip, u16 *fid)
1809 1810
{
	DECLARE_BITMAP(fid_bitmap, MV88E6XXX_N_FID);
1811
	struct mv88e6xxx_vtu_entry vlan;
1812
	int i, err;
1813 1814 1815

	bitmap_zero(fid_bitmap, MV88E6XXX_N_FID);

1816
	/* Set every FID bit used by the (un)bridged ports */
1817
	for (i = 0; i < mv88e6xxx_num_ports(chip); ++i) {
1818
		err = _mv88e6xxx_port_fid_get(chip, i, fid);
1819 1820 1821 1822 1823 1824
		if (err)
			return err;

		set_bit(*fid, fid_bitmap);
	}

1825
	/* Set every FID bit used by the VLAN entries */
1826
	err = _mv88e6xxx_vtu_vid_write(chip, GLOBAL_VTU_VID_MASK);
1827 1828 1829 1830
	if (err)
		return err;

	do {
1831
		err = _mv88e6xxx_vtu_getnext(chip, &vlan);
1832 1833 1834 1835 1836 1837 1838 1839 1840 1841 1842 1843 1844
		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);
1845
	if (unlikely(*fid >= mv88e6xxx_num_databases(chip)))
1846 1847 1848
		return -ENOSPC;

	/* Clear the database */
1849
	return _mv88e6xxx_atu_flush(chip, *fid, true);
1850 1851
}

1852
static int _mv88e6xxx_vtu_new(struct mv88e6xxx_chip *chip, u16 vid,
1853
			      struct mv88e6xxx_vtu_entry *entry)
1854
{
1855
	struct dsa_switch *ds = chip->ds;
1856
	struct mv88e6xxx_vtu_entry vlan = {
1857 1858 1859
		.valid = true,
		.vid = vid,
	};
1860 1861
	int i, err;

1862
	err = _mv88e6xxx_fid_new(chip, &vlan.fid);
1863 1864
	if (err)
		return err;
1865

1866
	/* exclude all ports except the CPU and DSA ports */
1867
	for (i = 0; i < mv88e6xxx_num_ports(chip); ++i)
1868 1869 1870
		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;
1871

1872 1873
	if (mv88e6xxx_6097_family(chip) || mv88e6xxx_6165_family(chip) ||
	    mv88e6xxx_6351_family(chip) || mv88e6xxx_6352_family(chip)) {
1874
		struct mv88e6xxx_vtu_entry vstp;
1875 1876 1877 1878 1879 1880

		/* 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;
1881
		err = _mv88e6xxx_stu_getnext(chip, GLOBAL_VTU_SID_MASK, &vstp);
1882 1883 1884 1885 1886 1887 1888 1889
		if (err)
			return err;

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

1890
			err = _mv88e6xxx_stu_loadpurge(chip, &vstp);
1891 1892 1893 1894 1895 1896 1897 1898 1899
			if (err)
				return err;
		}
	}

	*entry = vlan;
	return 0;
}

1900
static int _mv88e6xxx_vtu_get(struct mv88e6xxx_chip *chip, u16 vid,
1901
			      struct mv88e6xxx_vtu_entry *entry, bool creat)
1902 1903 1904 1905 1906 1907
{
	int err;

	if (!vid)
		return -EINVAL;

1908
	err = _mv88e6xxx_vtu_vid_write(chip, vid - 1);
1909 1910 1911
	if (err)
		return err;

1912
	err = _mv88e6xxx_vtu_getnext(chip, entry);
1913 1914 1915 1916 1917 1918 1919 1920 1921 1922
	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.
		 */

1923
		err = _mv88e6xxx_vtu_new(chip, vid, entry);
1924 1925 1926 1927 1928
	}

	return err;
}

1929 1930 1931
static int mv88e6xxx_port_check_hw_vlan(struct dsa_switch *ds, int port,
					u16 vid_begin, u16 vid_end)
{
V
Vivien Didelot 已提交
1932
	struct mv88e6xxx_chip *chip = ds->priv;
1933
	struct mv88e6xxx_vtu_entry vlan;
1934 1935 1936 1937 1938
	int i, err;

	if (!vid_begin)
		return -EOPNOTSUPP;

1939
	mutex_lock(&chip->reg_lock);
1940

1941
	err = _mv88e6xxx_vtu_vid_write(chip, vid_begin - 1);
1942 1943 1944 1945
	if (err)
		goto unlock;

	do {
1946
		err = _mv88e6xxx_vtu_getnext(chip, &vlan);
1947 1948 1949 1950 1951 1952 1953 1954 1955
		if (err)
			goto unlock;

		if (!vlan.valid)
			break;

		if (vlan.vid > vid_end)
			break;

1956
		for (i = 0; i < mv88e6xxx_num_ports(chip); ++i) {
1957 1958 1959 1960 1961 1962 1963
			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;

1964 1965
			if (chip->ports[i].bridge_dev ==
			    chip->ports[port].bridge_dev)
1966 1967
				break; /* same bridge, check next VLAN */

1968
			netdev_warn(ds->ports[port].netdev,
1969 1970
				    "hardware VLAN %d already used by %s\n",
				    vlan.vid,
1971
				    netdev_name(chip->ports[i].bridge_dev));
1972 1973 1974 1975 1976 1977
			err = -EOPNOTSUPP;
			goto unlock;
		}
	} while (vlan.vid < vid_end);

unlock:
1978
	mutex_unlock(&chip->reg_lock);
1979 1980 1981 1982

	return err;
}

1983 1984 1985 1986 1987 1988 1989
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",
};

1990 1991
static int mv88e6xxx_port_vlan_filtering(struct dsa_switch *ds, int port,
					 bool vlan_filtering)
1992
{
V
Vivien Didelot 已提交
1993
	struct mv88e6xxx_chip *chip = ds->priv;
1994 1995
	u16 old, new = vlan_filtering ? PORT_CONTROL_2_8021Q_SECURE :
		PORT_CONTROL_2_8021Q_DISABLED;
1996 1997
	u16 reg;
	int err;
1998

1999
	if (!mv88e6xxx_has(chip, MV88E6XXX_FLAG_VTU))
2000 2001
		return -EOPNOTSUPP;

2002
	mutex_lock(&chip->reg_lock);
2003

2004 2005
	err = mv88e6xxx_port_read(chip, port, PORT_CONTROL_2, &reg);
	if (err)
2006 2007
		goto unlock;

2008
	old = reg & PORT_CONTROL_2_8021Q_MASK;
2009

2010
	if (new != old) {
2011 2012
		reg &= ~PORT_CONTROL_2_8021Q_MASK;
		reg |= new & PORT_CONTROL_2_8021Q_MASK;
2013

2014 2015
		err = mv88e6xxx_port_write(chip, port, PORT_CONTROL_2, reg);
		if (err)
2016 2017
			goto unlock;

2018
		netdev_dbg(ds->ports[port].netdev, "802.1Q Mode %s (was %s)\n",
2019 2020 2021
			   mv88e6xxx_port_8021q_mode_names[new],
			   mv88e6xxx_port_8021q_mode_names[old]);
	}
2022

2023
	err = 0;
2024
unlock:
2025
	mutex_unlock(&chip->reg_lock);
2026

2027
	return err;
2028 2029
}

2030 2031 2032 2033
static int
mv88e6xxx_port_vlan_prepare(struct dsa_switch *ds, int port,
			    const struct switchdev_obj_port_vlan *vlan,
			    struct switchdev_trans *trans)
2034
{
V
Vivien Didelot 已提交
2035
	struct mv88e6xxx_chip *chip = ds->priv;
2036 2037
	int err;

2038
	if (!mv88e6xxx_has(chip, MV88E6XXX_FLAG_VTU))
2039 2040
		return -EOPNOTSUPP;

2041 2042 2043 2044 2045 2046 2047 2048
	/* 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;

2049 2050 2051 2052 2053 2054
	/* We don't need any dynamic resource from the kernel (yet),
	 * so skip the prepare phase.
	 */
	return 0;
}

2055
static int _mv88e6xxx_port_vlan_add(struct mv88e6xxx_chip *chip, int port,
2056
				    u16 vid, bool untagged)
2057
{
2058
	struct mv88e6xxx_vtu_entry vlan;
2059 2060
	int err;

2061
	err = _mv88e6xxx_vtu_get(chip, vid, &vlan, true);
2062
	if (err)
2063
		return err;
2064 2065 2066 2067 2068

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

2069
	return _mv88e6xxx_vtu_loadpurge(chip, &vlan);
2070 2071
}

2072 2073 2074
static void mv88e6xxx_port_vlan_add(struct dsa_switch *ds, int port,
				    const struct switchdev_obj_port_vlan *vlan,
				    struct switchdev_trans *trans)
2075
{
V
Vivien Didelot 已提交
2076
	struct mv88e6xxx_chip *chip = ds->priv;
2077 2078 2079 2080
	bool untagged = vlan->flags & BRIDGE_VLAN_INFO_UNTAGGED;
	bool pvid = vlan->flags & BRIDGE_VLAN_INFO_PVID;
	u16 vid;

2081
	if (!mv88e6xxx_has(chip, MV88E6XXX_FLAG_VTU))
2082 2083
		return;

2084
	mutex_lock(&chip->reg_lock);
2085

2086
	for (vid = vlan->vid_begin; vid <= vlan->vid_end; ++vid)
2087
		if (_mv88e6xxx_port_vlan_add(chip, port, vid, untagged))
2088 2089
			netdev_err(ds->ports[port].netdev,
				   "failed to add VLAN %d%c\n",
2090
				   vid, untagged ? 'u' : 't');
2091

2092
	if (pvid && _mv88e6xxx_port_pvid_set(chip, port, vlan->vid_end))
2093
		netdev_err(ds->ports[port].netdev, "failed to set PVID %d\n",
2094
			   vlan->vid_end);
2095

2096
	mutex_unlock(&chip->reg_lock);
2097 2098
}

2099
static int _mv88e6xxx_port_vlan_del(struct mv88e6xxx_chip *chip,
2100
				    int port, u16 vid)
2101
{
2102
	struct dsa_switch *ds = chip->ds;
2103
	struct mv88e6xxx_vtu_entry vlan;
2104 2105
	int i, err;

2106
	err = _mv88e6xxx_vtu_get(chip, vid, &vlan, false);
2107
	if (err)
2108
		return err;
2109

2110 2111
	/* Tell switchdev if this VLAN is handled in software */
	if (vlan.data[port] == GLOBAL_VTU_DATA_MEMBER_TAG_NON_MEMBER)
2112
		return -EOPNOTSUPP;
2113 2114 2115 2116

	vlan.data[port] = GLOBAL_VTU_DATA_MEMBER_TAG_NON_MEMBER;

	/* keep the VLAN unless all ports are excluded */
2117
	vlan.valid = false;
2118
	for (i = 0; i < mv88e6xxx_num_ports(chip); ++i) {
2119
		if (dsa_is_cpu_port(ds, i) || dsa_is_dsa_port(ds, i))
2120 2121 2122
			continue;

		if (vlan.data[i] != GLOBAL_VTU_DATA_MEMBER_TAG_NON_MEMBER) {
2123
			vlan.valid = true;
2124 2125 2126 2127
			break;
		}
	}

2128
	err = _mv88e6xxx_vtu_loadpurge(chip, &vlan);
2129 2130 2131
	if (err)
		return err;

2132
	return _mv88e6xxx_atu_remove(chip, vlan.fid, port, false);
2133 2134
}

2135 2136
static int mv88e6xxx_port_vlan_del(struct dsa_switch *ds, int port,
				   const struct switchdev_obj_port_vlan *vlan)
2137
{
V
Vivien Didelot 已提交
2138
	struct mv88e6xxx_chip *chip = ds->priv;
2139 2140 2141
	u16 pvid, vid;
	int err = 0;

2142
	if (!mv88e6xxx_has(chip, MV88E6XXX_FLAG_VTU))
2143 2144
		return -EOPNOTSUPP;

2145
	mutex_lock(&chip->reg_lock);
2146

2147
	err = _mv88e6xxx_port_pvid_get(chip, port, &pvid);
2148 2149 2150
	if (err)
		goto unlock;

2151
	for (vid = vlan->vid_begin; vid <= vlan->vid_end; ++vid) {
2152
		err = _mv88e6xxx_port_vlan_del(chip, port, vid);
2153 2154 2155 2156
		if (err)
			goto unlock;

		if (vid == pvid) {
2157
			err = _mv88e6xxx_port_pvid_set(chip, port, 0);
2158 2159 2160 2161 2162
			if (err)
				goto unlock;
		}
	}

2163
unlock:
2164
	mutex_unlock(&chip->reg_lock);
2165 2166 2167 2168

	return err;
}

2169
static int _mv88e6xxx_atu_mac_write(struct mv88e6xxx_chip *chip,
2170
				    const unsigned char *addr)
2171
{
2172
	int i, err;
2173 2174

	for (i = 0; i < 3; i++) {
2175 2176 2177 2178
		err = mv88e6xxx_g1_write(chip, GLOBAL_ATU_MAC_01 + i,
					 (addr[i * 2] << 8) | addr[i * 2 + 1]);
		if (err)
			return err;
2179 2180 2181 2182 2183
	}

	return 0;
}

2184
static int _mv88e6xxx_atu_mac_read(struct mv88e6xxx_chip *chip,
2185
				   unsigned char *addr)
2186
{
2187 2188
	u16 val;
	int i, err;
2189 2190

	for (i = 0; i < 3; i++) {
2191 2192 2193 2194 2195 2196
		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;
2197 2198 2199 2200 2201
	}

	return 0;
}

2202
static int _mv88e6xxx_atu_load(struct mv88e6xxx_chip *chip,
2203
			       struct mv88e6xxx_atu_entry *entry)
2204
{
2205 2206
	int ret;

2207
	ret = _mv88e6xxx_atu_wait(chip);
2208 2209 2210
	if (ret < 0)
		return ret;

2211
	ret = _mv88e6xxx_atu_mac_write(chip, entry->mac);
2212 2213 2214
	if (ret < 0)
		return ret;

2215
	ret = _mv88e6xxx_atu_data_write(chip, entry);
2216
	if (ret < 0)
2217 2218
		return ret;

2219
	return _mv88e6xxx_atu_cmd(chip, entry->fid, GLOBAL_ATU_OP_LOAD_DB);
2220
}
2221

2222 2223 2224 2225 2226 2227 2228 2229 2230 2231 2232 2233 2234 2235 2236 2237 2238 2239 2240 2241 2242 2243 2244 2245 2246 2247 2248 2249 2250 2251 2252 2253 2254 2255 2256 2257
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;
}

2258 2259 2260
static int mv88e6xxx_port_db_load_purge(struct mv88e6xxx_chip *chip, int port,
					const unsigned char *addr, u16 vid,
					u8 state)
2261
{
2262
	struct mv88e6xxx_vtu_entry vlan;
2263
	struct mv88e6xxx_atu_entry entry;
2264 2265
	int err;

2266 2267
	/* Null VLAN ID corresponds to the port private database */
	if (vid == 0)
2268
		err = _mv88e6xxx_port_fid_get(chip, port, &vlan.fid);
2269
	else
2270
		err = _mv88e6xxx_vtu_get(chip, vid, &vlan, false);
2271 2272
	if (err)
		return err;
2273

2274 2275 2276 2277 2278 2279 2280 2281 2282 2283 2284 2285
	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;
2286 2287
	}

2288
	return _mv88e6xxx_atu_load(chip, &entry);
2289 2290
}

2291 2292 2293
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 已提交
2294 2295 2296 2297 2298 2299 2300
{
	/* We don't need any dynamic resource from the kernel (yet),
	 * so skip the prepare phase.
	 */
	return 0;
}

2301 2302 2303
static void mv88e6xxx_port_fdb_add(struct dsa_switch *ds, int port,
				   const struct switchdev_obj_port_fdb *fdb,
				   struct switchdev_trans *trans)
2304
{
V
Vivien Didelot 已提交
2305
	struct mv88e6xxx_chip *chip = ds->priv;
2306

2307
	mutex_lock(&chip->reg_lock);
2308 2309 2310
	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");
2311
	mutex_unlock(&chip->reg_lock);
2312 2313
}

2314 2315
static int mv88e6xxx_port_fdb_del(struct dsa_switch *ds, int port,
				  const struct switchdev_obj_port_fdb *fdb)
2316
{
V
Vivien Didelot 已提交
2317
	struct mv88e6xxx_chip *chip = ds->priv;
2318
	int err;
2319

2320
	mutex_lock(&chip->reg_lock);
2321 2322
	err = mv88e6xxx_port_db_load_purge(chip, port, fdb->addr, fdb->vid,
					   GLOBAL_ATU_DATA_STATE_UNUSED);
2323
	mutex_unlock(&chip->reg_lock);
2324

2325
	return err;
2326 2327
}

2328
static int _mv88e6xxx_atu_getnext(struct mv88e6xxx_chip *chip, u16 fid,
2329
				  struct mv88e6xxx_atu_entry *entry)
2330
{
2331
	struct mv88e6xxx_atu_entry next = { 0 };
2332 2333
	u16 val;
	int err;
2334 2335

	next.fid = fid;
2336

2337 2338 2339
	err = _mv88e6xxx_atu_wait(chip);
	if (err)
		return err;
2340

2341 2342 2343
	err = _mv88e6xxx_atu_cmd(chip, fid, GLOBAL_ATU_OP_GET_NEXT_DB);
	if (err)
		return err;
2344

2345 2346 2347
	err = _mv88e6xxx_atu_mac_read(chip, next.mac);
	if (err)
		return err;
2348

2349 2350 2351
	err = mv88e6xxx_g1_read(chip, GLOBAL_ATU_DATA, &val);
	if (err)
		return err;
2352

2353
	next.state = val & GLOBAL_ATU_DATA_STATE_MASK;
2354 2355 2356
	if (next.state != GLOBAL_ATU_DATA_STATE_UNUSED) {
		unsigned int mask, shift;

2357
		if (val & GLOBAL_ATU_DATA_TRUNK) {
2358 2359 2360 2361 2362 2363 2364 2365 2366
			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;
		}

2367
		next.portv_trunkid = (val & mask) >> shift;
2368
	}
2369

2370
	*entry = next;
2371 2372 2373
	return 0;
}

2374 2375 2376 2377
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))
2378 2379 2380 2381 2382 2383
{
	struct mv88e6xxx_atu_entry addr = {
		.mac = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff },
	};
	int err;

2384
	err = _mv88e6xxx_atu_mac_write(chip, addr.mac);
2385 2386 2387 2388
	if (err)
		return err;

	do {
2389
		err = _mv88e6xxx_atu_getnext(chip, fid, &addr);
2390
		if (err)
2391
			return err;
2392 2393 2394 2395

		if (addr.state == GLOBAL_ATU_DATA_STATE_UNUSED)
			break;

2396 2397 2398 2399 2400
		if (addr.trunk || (addr.portv_trunkid & BIT(port)) == 0)
			continue;

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

2402 2403 2404 2405
			if (!is_unicast_ether_addr(addr.mac))
				continue;

			fdb = SWITCHDEV_OBJ_PORT_FDB(obj);
2406 2407
			fdb->vid = vid;
			ether_addr_copy(fdb->addr, addr.mac);
2408 2409 2410 2411
			if (addr.state == GLOBAL_ATU_DATA_STATE_UC_STATIC)
				fdb->ndm_state = NUD_NOARP;
			else
				fdb->ndm_state = NUD_REACHABLE;
2412 2413 2414 2415 2416 2417 2418 2419 2420
		} 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);
2421 2422
		} else {
			return -EOPNOTSUPP;
2423
		}
2424 2425 2426 2427

		err = cb(obj);
		if (err)
			return err;
2428 2429 2430 2431 2432
	} while (!is_broadcast_ether_addr(addr.mac));

	return err;
}

2433 2434 2435
static int mv88e6xxx_port_db_dump(struct mv88e6xxx_chip *chip, int port,
				  struct switchdev_obj *obj,
				  int (*cb)(struct switchdev_obj *obj))
2436
{
2437
	struct mv88e6xxx_vtu_entry vlan = {
2438 2439
		.vid = GLOBAL_VTU_VID_MASK, /* all ones */
	};
2440
	u16 fid;
2441 2442
	int err;

2443
	/* Dump port's default Filtering Information Database (VLAN ID 0) */
2444
	err = _mv88e6xxx_port_fid_get(chip, port, &fid);
2445
	if (err)
2446
		return err;
2447

2448
	err = mv88e6xxx_port_db_dump_fid(chip, fid, 0, port, obj, cb);
2449
	if (err)
2450
		return err;
2451

2452
	/* Dump VLANs' Filtering Information Databases */
2453
	err = _mv88e6xxx_vtu_vid_write(chip, vlan.vid);
2454
	if (err)
2455
		return err;
2456 2457

	do {
2458
		err = _mv88e6xxx_vtu_getnext(chip, &vlan);
2459
		if (err)
2460
			return err;
2461 2462 2463 2464

		if (!vlan.valid)
			break;

2465 2466
		err = mv88e6xxx_port_db_dump_fid(chip, vlan.fid, vlan.vid, port,
						 obj, cb);
2467
		if (err)
2468
			return err;
2469 2470
	} while (vlan.vid < GLOBAL_VTU_VID_MASK);

2471 2472 2473 2474 2475 2476 2477
	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 已提交
2478
	struct mv88e6xxx_chip *chip = ds->priv;
2479 2480 2481 2482
	int err;

	mutex_lock(&chip->reg_lock);
	err = mv88e6xxx_port_db_dump(chip, port, &fdb->obj, cb);
2483
	mutex_unlock(&chip->reg_lock);
2484 2485 2486 2487

	return err;
}

2488 2489
static int mv88e6xxx_port_bridge_join(struct dsa_switch *ds, int port,
				      struct net_device *bridge)
2490
{
V
Vivien Didelot 已提交
2491
	struct mv88e6xxx_chip *chip = ds->priv;
2492
	int i, err = 0;
2493

2494
	mutex_lock(&chip->reg_lock);
2495

2496
	/* Assign the bridge and remap each port's VLANTable */
2497
	chip->ports[port].bridge_dev = bridge;
2498

2499
	for (i = 0; i < mv88e6xxx_num_ports(chip); ++i) {
2500 2501
		if (chip->ports[i].bridge_dev == bridge) {
			err = _mv88e6xxx_port_based_vlan_map(chip, i);
2502 2503 2504 2505 2506
			if (err)
				break;
		}
	}

2507
	mutex_unlock(&chip->reg_lock);
2508

2509
	return err;
2510 2511
}

2512
static void mv88e6xxx_port_bridge_leave(struct dsa_switch *ds, int port)
2513
{
V
Vivien Didelot 已提交
2514
	struct mv88e6xxx_chip *chip = ds->priv;
2515
	struct net_device *bridge = chip->ports[port].bridge_dev;
2516
	int i;
2517

2518
	mutex_lock(&chip->reg_lock);
2519

2520
	/* Unassign the bridge and remap each port's VLANTable */
2521
	chip->ports[port].bridge_dev = NULL;
2522

2523
	for (i = 0; i < mv88e6xxx_num_ports(chip); ++i)
2524 2525
		if (i == port || chip->ports[i].bridge_dev == bridge)
			if (_mv88e6xxx_port_based_vlan_map(chip, i))
2526 2527
				netdev_warn(ds->ports[i].netdev,
					    "failed to remap\n");
2528

2529
	mutex_unlock(&chip->reg_lock);
2530 2531
}

2532
static int mv88e6xxx_switch_reset(struct mv88e6xxx_chip *chip)
2533
{
2534
	bool ppu_active = mv88e6xxx_has(chip, MV88E6XXX_FLAG_PPU_ACTIVE);
2535
	u16 is_reset = (ppu_active ? 0x8800 : 0xc800);
2536
	struct gpio_desc *gpiod = chip->reset;
2537
	unsigned long timeout;
2538
	u16 reg;
2539
	int err;
2540 2541 2542
	int i;

	/* Set all ports to the disabled state. */
2543
	for (i = 0; i < mv88e6xxx_num_ports(chip); i++) {
2544 2545 2546
		err = mv88e6xxx_port_read(chip, i, PORT_CONTROL, &reg);
		if (err)
			return err;
2547

2548 2549 2550 2551
		err = mv88e6xxx_port_write(chip, i, PORT_CONTROL,
					   reg & 0xfffc);
		if (err)
			return err;
2552 2553 2554 2555 2556 2557 2558 2559 2560 2561 2562 2563 2564 2565 2566 2567 2568 2569
	}

	/* 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)
2570
		err = mv88e6xxx_g1_write(chip, 0x04, 0xc000);
2571
	else
2572
		err = mv88e6xxx_g1_write(chip, 0x04, 0xc400);
2573 2574
	if (err)
		return err;
2575 2576 2577 2578

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

2583
		if ((reg & is_reset) == is_reset)
2584 2585 2586 2587
			break;
		usleep_range(1000, 2000);
	}
	if (time_after(jiffies, timeout))
2588
		err = -ETIMEDOUT;
2589
	else
2590
		err = 0;
2591

2592
	return err;
2593 2594
}

2595
static int mv88e6xxx_serdes_power_on(struct mv88e6xxx_chip *chip)
2596
{
2597 2598
	u16 val;
	int err;
2599

2600 2601 2602 2603
	/* Clear Power Down bit */
	err = mv88e6xxx_serdes_read(chip, MII_BMCR, &val);
	if (err)
		return err;
2604

2605 2606 2607
	if (val & BMCR_PDOWN) {
		val &= ~BMCR_PDOWN;
		err = mv88e6xxx_serdes_write(chip, MII_BMCR, val);
2608 2609
	}

2610
	return err;
2611 2612
}

2613
static int mv88e6xxx_setup_port(struct mv88e6xxx_chip *chip, int port)
2614
{
2615
	struct dsa_switch *ds = chip->ds;
2616
	int err;
2617
	u16 reg;
2618

2619 2620 2621 2622
	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)) {
2623 2624 2625 2626 2627 2628
		/* 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.
		 */
2629
		err = mv88e6xxx_port_read(chip, port, PORT_PCS_CTRL, &reg);
2630
		if (dsa_is_cpu_port(ds, port) || dsa_is_dsa_port(ds, port)) {
2631
			reg &= ~PORT_PCS_CTRL_UNFORCED;
2632 2633 2634 2635
			reg |= PORT_PCS_CTRL_FORCE_LINK |
				PORT_PCS_CTRL_LINK_UP |
				PORT_PCS_CTRL_DUPLEX_FULL |
				PORT_PCS_CTRL_FORCE_DUPLEX;
2636
			if (mv88e6xxx_6065_family(chip))
2637 2638 2639 2640 2641 2642 2643
				reg |= PORT_PCS_CTRL_100;
			else
				reg |= PORT_PCS_CTRL_1000;
		} else {
			reg |= PORT_PCS_CTRL_UNFORCED;
		}

2644 2645 2646
		err = mv88e6xxx_port_write(chip, port, PORT_PCS_CTRL, reg);
		if (err)
			return err;
2647 2648 2649 2650 2651 2652 2653 2654 2655 2656 2657 2658 2659 2660 2661 2662 2663
	}

	/* 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;
2664 2665 2666 2667
	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))
2668 2669 2670 2671
		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)) {
2672
		if (mv88e6xxx_has(chip, MV88E6XXX_FLAG_EDSA))
2673
			reg |= PORT_CONTROL_FRAME_ETHER_TYPE_DSA |
2674
				PORT_CONTROL_FORWARD_UNKNOWN_MC;
2675 2676
		else
			reg |= PORT_CONTROL_DSA_TAG;
2677 2678
		reg |= PORT_CONTROL_EGRESS_ADD_TAG |
			PORT_CONTROL_FORWARD_UNKNOWN;
2679
	}
2680
	if (dsa_is_dsa_port(ds, port)) {
2681 2682
		if (mv88e6xxx_6095_family(chip) ||
		    mv88e6xxx_6185_family(chip))
2683
			reg |= PORT_CONTROL_DSA_TAG;
2684 2685 2686 2687 2688
		if (mv88e6xxx_6352_family(chip) ||
		    mv88e6xxx_6351_family(chip) ||
		    mv88e6xxx_6165_family(chip) ||
		    mv88e6xxx_6097_family(chip) ||
		    mv88e6xxx_6320_family(chip)) {
2689
			reg |= PORT_CONTROL_FRAME_MODE_DSA;
2690 2691
		}

2692 2693 2694 2695 2696
		if (port == dsa_upstream_port(ds))
			reg |= PORT_CONTROL_FORWARD_UNKNOWN |
				PORT_CONTROL_FORWARD_UNKNOWN_MC;
	}
	if (reg) {
2697 2698 2699
		err = mv88e6xxx_port_write(chip, port, PORT_CONTROL, reg);
		if (err)
			return err;
2700 2701
	}

2702 2703 2704
	/* If this port is connected to a SerDes, make sure the SerDes is not
	 * powered down.
	 */
2705
	if (mv88e6xxx_has(chip, MV88E6XXX_FLAGS_SERDES)) {
2706 2707 2708 2709 2710 2711 2712 2713 2714 2715
		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;
2716 2717 2718
		}
	}

2719
	/* Port Control 2: don't force a good FCS, set the maximum frame size to
2720
	 * 10240 bytes, disable 802.1q tags checking, don't discard tagged or
2721 2722 2723
	 * 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.
2724 2725
	 */
	reg = 0;
2726 2727 2728 2729
	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))
2730 2731
		reg = PORT_CONTROL_2_MAP_DA;

2732 2733
	if (mv88e6xxx_6352_family(chip) || mv88e6xxx_6351_family(chip) ||
	    mv88e6xxx_6165_family(chip) || mv88e6xxx_6320_family(chip))
2734 2735
		reg |= PORT_CONTROL_2_JUMBO_10240;

2736
	if (mv88e6xxx_6095_family(chip) || mv88e6xxx_6185_family(chip)) {
2737 2738 2739 2740 2741 2742 2743 2744 2745
		/* 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;
	}

2746
	reg |= PORT_CONTROL_2_8021Q_DISABLED;
2747

2748
	if (reg) {
2749 2750 2751
		err = mv88e6xxx_port_write(chip, port, PORT_CONTROL_2, reg);
		if (err)
			return err;
2752 2753 2754 2755 2756 2757 2758
	}

	/* 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.
	 */
2759
	reg = 1 << port;
2760 2761
	/* Disable learning for CPU port */
	if (dsa_is_cpu_port(ds, port))
2762
		reg = 0;
2763

2764 2765 2766
	err = mv88e6xxx_port_write(chip, port, PORT_ASSOC_VECTOR, reg);
	if (err)
		return err;
2767 2768

	/* Egress rate control 2: disable egress rate control. */
2769 2770 2771
	err = mv88e6xxx_port_write(chip, port, PORT_RATE_CONTROL_2, 0x0000);
	if (err)
		return err;
2772

2773 2774 2775
	if (mv88e6xxx_6352_family(chip) || mv88e6xxx_6351_family(chip) ||
	    mv88e6xxx_6165_family(chip) || mv88e6xxx_6097_family(chip) ||
	    mv88e6xxx_6320_family(chip)) {
2776 2777 2778 2779
		/* 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.
		 */
2780 2781 2782
		err = mv88e6xxx_port_write(chip, port, PORT_PAUSE_CTRL, 0x0000);
		if (err)
			return err;
2783 2784 2785 2786 2787

		/* Port ATU control: disable limiting the number of
		 * address database entries that this port is allowed
		 * to use.
		 */
2788 2789
		err = mv88e6xxx_port_write(chip, port, PORT_ATU_CONTROL,
					   0x0000);
2790 2791 2792
		/* Priority Override: disable DA, SA and VTU priority
		 * override.
		 */
2793 2794 2795 2796
		err = mv88e6xxx_port_write(chip, port, PORT_PRI_OVERRIDE,
					   0x0000);
		if (err)
			return err;
2797 2798 2799 2800

		/* Port Ethertype: use the Ethertype DSA Ethertype
		 * value.
		 */
2801
		if (mv88e6xxx_has(chip, MV88E6XXX_FLAG_EDSA)) {
2802 2803 2804 2805
			err = mv88e6xxx_port_write(chip, port, PORT_ETH_TYPE,
						   ETH_P_EDSA);
			if (err)
				return err;
2806 2807
		}

2808 2809 2810
		/* Tag Remap: use an identity 802.1p prio -> switch
		 * prio mapping.
		 */
2811 2812 2813 2814
		err = mv88e6xxx_port_write(chip, port, PORT_TAG_REGMAP_0123,
					   0x3210);
		if (err)
			return err;
2815 2816 2817 2818

		/* Tag Remap 2: use an identity 802.1p prio -> switch
		 * prio mapping.
		 */
2819 2820 2821 2822
		err = mv88e6xxx_port_write(chip, port, PORT_TAG_REGMAP_4567,
					   0x7654);
		if (err)
			return err;
2823 2824
	}

2825
	/* Rate Control: disable ingress rate limiting. */
2826 2827 2828
	if (mv88e6xxx_6352_family(chip) || mv88e6xxx_6351_family(chip) ||
	    mv88e6xxx_6165_family(chip) || mv88e6xxx_6097_family(chip) ||
	    mv88e6xxx_6320_family(chip)) {
2829 2830 2831 2832
		err = mv88e6xxx_port_write(chip, port, PORT_RATE_CONTROL,
					   0x0001);
		if (err)
			return err;
2833
	} else if (mv88e6xxx_6185_family(chip) || mv88e6xxx_6095_family(chip)) {
2834 2835 2836 2837
		err = mv88e6xxx_port_write(chip, port, PORT_RATE_CONTROL,
					   0x0000);
		if (err)
			return err;
2838 2839
	}

2840 2841
	/* Port Control 1: disable trunking, disable sending
	 * learning messages to this port.
2842
	 */
2843 2844 2845
	err = mv88e6xxx_port_write(chip, port, PORT_CONTROL_1, 0x0000);
	if (err)
		return err;
2846

2847
	/* Port based VLAN map: give each port the same default address
2848 2849
	 * database, and allow bidirectional communication between the
	 * CPU and DSA port(s), and the other ports.
2850
	 */
2851 2852 2853
	err = _mv88e6xxx_port_fid_set(chip, port, 0);
	if (err)
		return err;
2854

2855 2856 2857
	err = _mv88e6xxx_port_based_vlan_map(chip, port);
	if (err)
		return err;
2858 2859 2860 2861

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

2865
static int mv88e6xxx_g1_set_switch_mac(struct mv88e6xxx_chip *chip, u8 *addr)
2866 2867 2868
{
	int err;

2869
	err = mv88e6xxx_g1_write(chip, GLOBAL_MAC_01, (addr[0] << 8) | addr[1]);
2870 2871 2872
	if (err)
		return err;

2873
	err = mv88e6xxx_g1_write(chip, GLOBAL_MAC_23, (addr[2] << 8) | addr[3]);
2874 2875 2876
	if (err)
		return err;

2877 2878 2879 2880 2881
	err = mv88e6xxx_g1_write(chip, GLOBAL_MAC_45, (addr[4] << 8) | addr[5]);
	if (err)
		return err;

	return 0;
2882 2883
}

2884 2885 2886 2887 2888 2889 2890 2891 2892 2893 2894 2895 2896 2897 2898 2899
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;

2900
	err = mv88e6xxx_g1_read(chip, GLOBAL_ATU_CONTROL, &val);
2901 2902 2903 2904 2905 2906 2907
	if (err)
		return err;

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

2908
	return mv88e6xxx_g1_write(chip, GLOBAL_ATU_CONTROL, val);
2909 2910
}

2911 2912 2913
static int mv88e6xxx_set_ageing_time(struct dsa_switch *ds,
				     unsigned int ageing_time)
{
V
Vivien Didelot 已提交
2914
	struct mv88e6xxx_chip *chip = ds->priv;
2915 2916 2917 2918 2919 2920 2921 2922 2923
	int err;

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

	return err;
}

2924
static int mv88e6xxx_g1_setup(struct mv88e6xxx_chip *chip)
2925
{
2926
	struct dsa_switch *ds = chip->ds;
2927
	u32 upstream_port = dsa_upstream_port(ds);
2928
	u16 reg;
2929
	int err;
2930

2931 2932 2933
	/* Enable the PHY Polling Unit if present, don't discard any packets,
	 * and mask all interrupt sources.
	 */
2934 2935 2936 2937 2938
	err = mv88e6xxx_g1_read(chip, GLOBAL_CONTROL, &reg);
	if (err < 0)
		return err;

	reg &= ~GLOBAL_CONTROL_PPU_ENABLE;
2939 2940
	if (mv88e6xxx_has(chip, MV88E6XXX_FLAG_PPU) ||
	    mv88e6xxx_has(chip, MV88E6XXX_FLAG_PPU_ACTIVE))
2941 2942
		reg |= GLOBAL_CONTROL_PPU_ENABLE;

2943
	err = mv88e6xxx_g1_write(chip, GLOBAL_CONTROL, reg);
2944 2945 2946
	if (err)
		return err;

2947 2948 2949 2950 2951 2952
	/* 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;
2953
	err = mv88e6xxx_g1_write(chip, GLOBAL_MONITOR_CONTROL, reg);
2954 2955 2956
	if (err)
		return err;

2957
	/* Disable remote management, and set the switch's DSA device number. */
2958 2959 2960
	err = mv88e6xxx_g1_write(chip, GLOBAL_CONTROL_2,
				 GLOBAL_CONTROL_2_MULTIPLE_CASCADE |
				 (ds->index & 0x1f));
2961 2962 2963
	if (err)
		return err;

2964 2965 2966 2967 2968
	/* Clear all the VTU and STU entries */
	err = _mv88e6xxx_vtu_stu_flush(chip);
	if (err < 0)
		return err;

2969 2970 2971 2972
	/* Set the default address aging time to 5 minutes, and
	 * enable address learn messages to be sent to all message
	 * ports.
	 */
2973 2974
	err = mv88e6xxx_g1_write(chip, GLOBAL_ATU_CONTROL,
				 GLOBAL_ATU_CONTROL_LEARN2ALL);
2975
	if (err)
2976
		return err;
2977

2978 2979
	err = mv88e6xxx_g1_set_age_time(chip, 300000);
	if (err)
2980 2981 2982 2983 2984 2985 2986
		return err;

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

2987
	/* Configure the IP ToS mapping registers. */
2988
	err = mv88e6xxx_g1_write(chip, GLOBAL_IP_PRI_0, 0x0000);
2989
	if (err)
2990
		return err;
2991
	err = mv88e6xxx_g1_write(chip, GLOBAL_IP_PRI_1, 0x0000);
2992
	if (err)
2993
		return err;
2994
	err = mv88e6xxx_g1_write(chip, GLOBAL_IP_PRI_2, 0x5555);
2995
	if (err)
2996
		return err;
2997
	err = mv88e6xxx_g1_write(chip, GLOBAL_IP_PRI_3, 0x5555);
2998
	if (err)
2999
		return err;
3000
	err = mv88e6xxx_g1_write(chip, GLOBAL_IP_PRI_4, 0xaaaa);
3001
	if (err)
3002
		return err;
3003
	err = mv88e6xxx_g1_write(chip, GLOBAL_IP_PRI_5, 0xaaaa);
3004
	if (err)
3005
		return err;
3006
	err = mv88e6xxx_g1_write(chip, GLOBAL_IP_PRI_6, 0xffff);
3007
	if (err)
3008
		return err;
3009
	err = mv88e6xxx_g1_write(chip, GLOBAL_IP_PRI_7, 0xffff);
3010
	if (err)
3011
		return err;
3012 3013

	/* Configure the IEEE 802.1p priority mapping register. */
3014
	err = mv88e6xxx_g1_write(chip, GLOBAL_IEEE_PRI, 0xfa41);
3015
	if (err)
3016
		return err;
3017

3018
	/* Clear the statistics counters for all ports */
3019 3020
	err = mv88e6xxx_g1_write(chip, GLOBAL_STATS_OP,
				 GLOBAL_STATS_OP_FLUSH_ALL);
3021 3022 3023 3024 3025 3026 3027 3028 3029 3030 3031
	if (err)
		return err;

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

	return 0;
}

3032
static int mv88e6xxx_setup(struct dsa_switch *ds)
3033
{
V
Vivien Didelot 已提交
3034
	struct mv88e6xxx_chip *chip = ds->priv;
3035
	int err;
3036 3037
	int i;

3038 3039
	chip->ds = ds;
	ds->slave_mii_bus = chip->mdio_bus;
3040

3041
	mutex_lock(&chip->reg_lock);
3042

3043
	/* Setup Switch Port Registers */
3044
	for (i = 0; i < mv88e6xxx_num_ports(chip); i++) {
3045 3046 3047 3048 3049 3050 3051
		err = mv88e6xxx_setup_port(chip, i);
		if (err)
			goto unlock;
	}

	/* Setup Switch Global 1 Registers */
	err = mv88e6xxx_g1_setup(chip);
3052 3053 3054
	if (err)
		goto unlock;

3055 3056 3057
	/* Setup Switch Global 2 Registers */
	if (mv88e6xxx_has(chip, MV88E6XXX_FLAG_GLOBAL2)) {
		err = mv88e6xxx_g2_setup(chip);
3058 3059 3060
		if (err)
			goto unlock;
	}
3061

3062
unlock:
3063
	mutex_unlock(&chip->reg_lock);
3064

3065
	return err;
3066 3067
}

3068 3069
static int mv88e6xxx_set_addr(struct dsa_switch *ds, u8 *addr)
{
V
Vivien Didelot 已提交
3070
	struct mv88e6xxx_chip *chip = ds->priv;
3071 3072
	int err;

3073 3074
	if (!chip->info->ops->set_switch_mac)
		return -EOPNOTSUPP;
3075

3076 3077
	mutex_lock(&chip->reg_lock);
	err = chip->info->ops->set_switch_mac(chip, addr);
3078 3079 3080 3081 3082
	mutex_unlock(&chip->reg_lock);

	return err;
}

3083
static int mv88e6xxx_mdio_read(struct mii_bus *bus, int phy, int reg)
3084
{
3085
	struct mv88e6xxx_chip *chip = bus->priv;
3086 3087
	u16 val;
	int err;
3088

3089
	if (phy >= mv88e6xxx_num_ports(chip))
3090
		return 0xffff;
3091

3092
	mutex_lock(&chip->reg_lock);
3093
	err = mv88e6xxx_phy_read(chip, phy, reg, &val);
3094
	mutex_unlock(&chip->reg_lock);
3095 3096

	return err ? err : val;
3097 3098
}

3099
static int mv88e6xxx_mdio_write(struct mii_bus *bus, int phy, int reg, u16 val)
3100
{
3101
	struct mv88e6xxx_chip *chip = bus->priv;
3102
	int err;
3103

3104
	if (phy >= mv88e6xxx_num_ports(chip))
3105
		return 0xffff;
3106

3107
	mutex_lock(&chip->reg_lock);
3108
	err = mv88e6xxx_phy_write(chip, phy, reg, val);
3109
	mutex_unlock(&chip->reg_lock);
3110 3111

	return err;
3112 3113
}

3114
static int mv88e6xxx_mdio_register(struct mv88e6xxx_chip *chip,
3115 3116 3117 3118 3119 3120 3121
				   struct device_node *np)
{
	static int index;
	struct mii_bus *bus;
	int err;

	if (np)
3122
		chip->mdio_np = of_get_child_by_name(np, "mdio");
3123

3124
	bus = devm_mdiobus_alloc(chip->dev);
3125 3126 3127
	if (!bus)
		return -ENOMEM;

3128
	bus->priv = (void *)chip;
3129 3130 3131 3132 3133 3134 3135 3136 3137 3138
	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;
3139
	bus->parent = chip->dev;
3140

3141 3142
	if (chip->mdio_np)
		err = of_mdiobus_register(bus, chip->mdio_np);
3143 3144 3145
	else
		err = mdiobus_register(bus);
	if (err) {
3146
		dev_err(chip->dev, "Cannot register MDIO bus (%d)\n", err);
3147 3148
		goto out;
	}
3149
	chip->mdio_bus = bus;
3150 3151 3152 3153

	return 0;

out:
3154 3155
	if (chip->mdio_np)
		of_node_put(chip->mdio_np);
3156 3157 3158 3159

	return err;
}

3160
static void mv88e6xxx_mdio_unregister(struct mv88e6xxx_chip *chip)
3161 3162

{
3163
	struct mii_bus *bus = chip->mdio_bus;
3164 3165 3166

	mdiobus_unregister(bus);

3167 3168
	if (chip->mdio_np)
		of_node_put(chip->mdio_np);
3169 3170
}

3171 3172 3173 3174
#ifdef CONFIG_NET_DSA_HWMON

static int mv88e61xx_get_temp(struct dsa_switch *ds, int *temp)
{
V
Vivien Didelot 已提交
3175
	struct mv88e6xxx_chip *chip = ds->priv;
3176
	u16 val;
3177 3178 3179 3180
	int ret;

	*temp = 0;

3181
	mutex_lock(&chip->reg_lock);
3182

3183
	ret = mv88e6xxx_phy_write(chip, 0x0, 0x16, 0x6);
3184 3185 3186 3187
	if (ret < 0)
		goto error;

	/* Enable temperature sensor */
3188
	ret = mv88e6xxx_phy_read(chip, 0x0, 0x1a, &val);
3189 3190 3191
	if (ret < 0)
		goto error;

3192
	ret = mv88e6xxx_phy_write(chip, 0x0, 0x1a, val | (1 << 5));
3193 3194 3195 3196 3197 3198
	if (ret < 0)
		goto error;

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

3199 3200
	ret = mv88e6xxx_phy_read(chip, 0x0, 0x1a, &val);
	if (ret < 0)
3201 3202 3203
		goto error;

	/* Disable temperature sensor */
3204
	ret = mv88e6xxx_phy_write(chip, 0x0, 0x1a, val & ~(1 << 5));
3205 3206 3207 3208 3209 3210
	if (ret < 0)
		goto error;

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

error:
3211
	mv88e6xxx_phy_write(chip, 0x0, 0x16, 0x0);
3212
	mutex_unlock(&chip->reg_lock);
3213 3214 3215 3216 3217
	return ret;
}

static int mv88e63xx_get_temp(struct dsa_switch *ds, int *temp)
{
V
Vivien Didelot 已提交
3218
	struct mv88e6xxx_chip *chip = ds->priv;
3219
	int phy = mv88e6xxx_6320_family(chip) ? 3 : 0;
3220
	u16 val;
3221 3222 3223 3224
	int ret;

	*temp = 0;

3225 3226 3227
	mutex_lock(&chip->reg_lock);
	ret = mv88e6xxx_phy_page_read(chip, phy, 6, 27, &val);
	mutex_unlock(&chip->reg_lock);
3228 3229 3230
	if (ret < 0)
		return ret;

3231
	*temp = (val & 0xff) - 25;
3232 3233 3234 3235

	return 0;
}

3236
static int mv88e6xxx_get_temp(struct dsa_switch *ds, int *temp)
3237
{
V
Vivien Didelot 已提交
3238
	struct mv88e6xxx_chip *chip = ds->priv;
3239

3240
	if (!mv88e6xxx_has(chip, MV88E6XXX_FLAG_TEMP))
3241 3242
		return -EOPNOTSUPP;

3243
	if (mv88e6xxx_6320_family(chip) || mv88e6xxx_6352_family(chip))
3244 3245 3246 3247 3248
		return mv88e63xx_get_temp(ds, temp);

	return mv88e61xx_get_temp(ds, temp);
}

3249
static int mv88e6xxx_get_temp_limit(struct dsa_switch *ds, int *temp)
3250
{
V
Vivien Didelot 已提交
3251
	struct mv88e6xxx_chip *chip = ds->priv;
3252
	int phy = mv88e6xxx_6320_family(chip) ? 3 : 0;
3253
	u16 val;
3254 3255
	int ret;

3256
	if (!mv88e6xxx_has(chip, MV88E6XXX_FLAG_TEMP_LIMIT))
3257 3258 3259 3260
		return -EOPNOTSUPP;

	*temp = 0;

3261 3262 3263
	mutex_lock(&chip->reg_lock);
	ret = mv88e6xxx_phy_page_read(chip, phy, 6, 26, &val);
	mutex_unlock(&chip->reg_lock);
3264 3265 3266
	if (ret < 0)
		return ret;

3267
	*temp = (((val >> 8) & 0x1f) * 5) - 25;
3268 3269 3270 3271

	return 0;
}

3272
static int mv88e6xxx_set_temp_limit(struct dsa_switch *ds, int temp)
3273
{
V
Vivien Didelot 已提交
3274
	struct mv88e6xxx_chip *chip = ds->priv;
3275
	int phy = mv88e6xxx_6320_family(chip) ? 3 : 0;
3276 3277
	u16 val;
	int err;
3278

3279
	if (!mv88e6xxx_has(chip, MV88E6XXX_FLAG_TEMP_LIMIT))
3280 3281
		return -EOPNOTSUPP;

3282 3283 3284 3285
	mutex_lock(&chip->reg_lock);
	err = mv88e6xxx_phy_page_read(chip, phy, 6, 26, &val);
	if (err)
		goto unlock;
3286
	temp = clamp_val(DIV_ROUND_CLOSEST(temp, 5) + 5, 0, 0x1f);
3287 3288 3289 3290 3291 3292
	err = mv88e6xxx_phy_page_write(chip, phy, 6, 26,
				       (val & 0xe0ff) | (temp << 8));
unlock:
	mutex_unlock(&chip->reg_lock);

	return err;
3293 3294
}

3295
static int mv88e6xxx_get_temp_alarm(struct dsa_switch *ds, bool *alarm)
3296
{
V
Vivien Didelot 已提交
3297
	struct mv88e6xxx_chip *chip = ds->priv;
3298
	int phy = mv88e6xxx_6320_family(chip) ? 3 : 0;
3299
	u16 val;
3300 3301
	int ret;

3302
	if (!mv88e6xxx_has(chip, MV88E6XXX_FLAG_TEMP_LIMIT))
3303 3304 3305 3306
		return -EOPNOTSUPP;

	*alarm = false;

3307 3308 3309
	mutex_lock(&chip->reg_lock);
	ret = mv88e6xxx_phy_page_read(chip, phy, 6, 26, &val);
	mutex_unlock(&chip->reg_lock);
3310 3311 3312
	if (ret < 0)
		return ret;

3313
	*alarm = !!(val & 0x40);
3314 3315 3316 3317 3318

	return 0;
}
#endif /* CONFIG_NET_DSA_HWMON */

3319 3320
static int mv88e6xxx_get_eeprom_len(struct dsa_switch *ds)
{
V
Vivien Didelot 已提交
3321
	struct mv88e6xxx_chip *chip = ds->priv;
3322 3323 3324 3325 3326 3327 3328

	return chip->eeprom_len;
}

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

3332 3333
	if (!chip->info->ops->get_eeprom)
		return -EOPNOTSUPP;
3334

3335 3336
	mutex_lock(&chip->reg_lock);
	err = chip->info->ops->get_eeprom(chip, eeprom, data);
3337 3338 3339 3340 3341 3342 3343 3344 3345 3346 3347 3348 3349
	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 已提交
3350
	struct mv88e6xxx_chip *chip = ds->priv;
3351 3352
	int err;

3353 3354 3355
	if (!chip->info->ops->set_eeprom)
		return -EOPNOTSUPP;

3356 3357 3358 3359
	if (eeprom->magic != 0xc3ec4951)
		return -EINVAL;

	mutex_lock(&chip->reg_lock);
3360
	err = chip->info->ops->set_eeprom(chip, eeprom, data);
3361 3362 3363 3364 3365
	mutex_unlock(&chip->reg_lock);

	return err;
}

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

static const struct mv88e6xxx_ops mv88e6095_ops = {
3373
	.set_switch_mac = mv88e6xxx_g1_set_switch_mac,
3374 3375 3376 3377 3378
	.phy_read = mv88e6xxx_phy_ppu_read,
	.phy_write = mv88e6xxx_phy_ppu_write,
};

static const struct mv88e6xxx_ops mv88e6123_ops = {
3379
	.set_switch_mac = mv88e6xxx_g2_set_switch_mac,
3380 3381 3382 3383 3384
	.phy_read = mv88e6xxx_read,
	.phy_write = mv88e6xxx_write,
};

static const struct mv88e6xxx_ops mv88e6131_ops = {
3385
	.set_switch_mac = mv88e6xxx_g1_set_switch_mac,
3386 3387 3388 3389 3390
	.phy_read = mv88e6xxx_phy_ppu_read,
	.phy_write = mv88e6xxx_phy_ppu_write,
};

static const struct mv88e6xxx_ops mv88e6161_ops = {
3391
	.set_switch_mac = mv88e6xxx_g2_set_switch_mac,
3392 3393 3394 3395 3396
	.phy_read = mv88e6xxx_read,
	.phy_write = mv88e6xxx_write,
};

static const struct mv88e6xxx_ops mv88e6165_ops = {
3397
	.set_switch_mac = mv88e6xxx_g2_set_switch_mac,
3398 3399 3400 3401 3402
	.phy_read = mv88e6xxx_read,
	.phy_write = mv88e6xxx_write,
};

static const struct mv88e6xxx_ops mv88e6171_ops = {
3403
	.set_switch_mac = mv88e6xxx_g2_set_switch_mac,
3404 3405 3406 3407 3408
	.phy_read = mv88e6xxx_g2_smi_phy_read,
	.phy_write = mv88e6xxx_g2_smi_phy_write,
};

static const struct mv88e6xxx_ops mv88e6172_ops = {
3409 3410
	.get_eeprom = mv88e6xxx_g2_get_eeprom16,
	.set_eeprom = mv88e6xxx_g2_set_eeprom16,
3411
	.set_switch_mac = mv88e6xxx_g2_set_switch_mac,
3412 3413 3414 3415 3416
	.phy_read = mv88e6xxx_g2_smi_phy_read,
	.phy_write = mv88e6xxx_g2_smi_phy_write,
};

static const struct mv88e6xxx_ops mv88e6175_ops = {
3417
	.set_switch_mac = mv88e6xxx_g2_set_switch_mac,
3418 3419 3420 3421 3422
	.phy_read = mv88e6xxx_g2_smi_phy_read,
	.phy_write = mv88e6xxx_g2_smi_phy_write,
};

static const struct mv88e6xxx_ops mv88e6176_ops = {
3423 3424
	.get_eeprom = mv88e6xxx_g2_get_eeprom16,
	.set_eeprom = mv88e6xxx_g2_set_eeprom16,
3425
	.set_switch_mac = mv88e6xxx_g2_set_switch_mac,
3426 3427 3428 3429 3430
	.phy_read = mv88e6xxx_g2_smi_phy_read,
	.phy_write = mv88e6xxx_g2_smi_phy_write,
};

static const struct mv88e6xxx_ops mv88e6185_ops = {
3431
	.set_switch_mac = mv88e6xxx_g1_set_switch_mac,
3432 3433 3434 3435 3436
	.phy_read = mv88e6xxx_phy_ppu_read,
	.phy_write = mv88e6xxx_phy_ppu_write,
};

static const struct mv88e6xxx_ops mv88e6240_ops = {
3437 3438
	.get_eeprom = mv88e6xxx_g2_get_eeprom16,
	.set_eeprom = mv88e6xxx_g2_set_eeprom16,
3439
	.set_switch_mac = mv88e6xxx_g2_set_switch_mac,
3440 3441 3442 3443 3444
	.phy_read = mv88e6xxx_g2_smi_phy_read,
	.phy_write = mv88e6xxx_g2_smi_phy_write,
};

static const struct mv88e6xxx_ops mv88e6320_ops = {
3445 3446
	.get_eeprom = mv88e6xxx_g2_get_eeprom16,
	.set_eeprom = mv88e6xxx_g2_set_eeprom16,
3447
	.set_switch_mac = mv88e6xxx_g2_set_switch_mac,
3448 3449 3450 3451 3452
	.phy_read = mv88e6xxx_g2_smi_phy_read,
	.phy_write = mv88e6xxx_g2_smi_phy_write,
};

static const struct mv88e6xxx_ops mv88e6321_ops = {
3453 3454
	.get_eeprom = mv88e6xxx_g2_get_eeprom16,
	.set_eeprom = mv88e6xxx_g2_set_eeprom16,
3455
	.set_switch_mac = mv88e6xxx_g2_set_switch_mac,
3456 3457 3458 3459 3460
	.phy_read = mv88e6xxx_g2_smi_phy_read,
	.phy_write = mv88e6xxx_g2_smi_phy_write,
};

static const struct mv88e6xxx_ops mv88e6350_ops = {
3461
	.set_switch_mac = mv88e6xxx_g2_set_switch_mac,
3462 3463 3464 3465 3466
	.phy_read = mv88e6xxx_g2_smi_phy_read,
	.phy_write = mv88e6xxx_g2_smi_phy_write,
};

static const struct mv88e6xxx_ops mv88e6351_ops = {
3467
	.set_switch_mac = mv88e6xxx_g2_set_switch_mac,
3468 3469 3470 3471 3472
	.phy_read = mv88e6xxx_g2_smi_phy_read,
	.phy_write = mv88e6xxx_g2_smi_phy_write,
};

static const struct mv88e6xxx_ops mv88e6352_ops = {
3473 3474
	.get_eeprom = mv88e6xxx_g2_get_eeprom16,
	.set_eeprom = mv88e6xxx_g2_set_eeprom16,
3475
	.set_switch_mac = mv88e6xxx_g2_set_switch_mac,
3476 3477 3478 3479
	.phy_read = mv88e6xxx_g2_smi_phy_read,
	.phy_write = mv88e6xxx_g2_smi_phy_write,
};

3480 3481 3482 3483 3484 3485 3486
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,
3487
		.port_base_addr = 0x10,
3488
		.global1_addr = 0x1b,
3489
		.age_time_coeff = 15000,
3490
		.g1_irqs = 8,
3491
		.flags = MV88E6XXX_FLAGS_FAMILY_6097,
3492
		.ops = &mv88e6085_ops,
3493 3494 3495 3496 3497 3498 3499 3500
	},

	[MV88E6095] = {
		.prod_num = PORT_SWITCH_ID_PROD_NUM_6095,
		.family = MV88E6XXX_FAMILY_6095,
		.name = "Marvell 88E6095/88E6095F",
		.num_databases = 256,
		.num_ports = 11,
3501
		.port_base_addr = 0x10,
3502
		.global1_addr = 0x1b,
3503
		.age_time_coeff = 15000,
3504
		.g1_irqs = 8,
3505
		.flags = MV88E6XXX_FLAGS_FAMILY_6095,
3506
		.ops = &mv88e6095_ops,
3507 3508 3509 3510 3511 3512 3513 3514
	},

	[MV88E6123] = {
		.prod_num = PORT_SWITCH_ID_PROD_NUM_6123,
		.family = MV88E6XXX_FAMILY_6165,
		.name = "Marvell 88E6123",
		.num_databases = 4096,
		.num_ports = 3,
3515
		.port_base_addr = 0x10,
3516
		.global1_addr = 0x1b,
3517
		.age_time_coeff = 15000,
3518
		.g1_irqs = 9,
3519
		.flags = MV88E6XXX_FLAGS_FAMILY_6165,
3520
		.ops = &mv88e6123_ops,
3521 3522 3523 3524 3525 3526 3527 3528
	},

	[MV88E6131] = {
		.prod_num = PORT_SWITCH_ID_PROD_NUM_6131,
		.family = MV88E6XXX_FAMILY_6185,
		.name = "Marvell 88E6131",
		.num_databases = 256,
		.num_ports = 8,
3529
		.port_base_addr = 0x10,
3530
		.global1_addr = 0x1b,
3531
		.age_time_coeff = 15000,
3532
		.g1_irqs = 9,
3533
		.flags = MV88E6XXX_FLAGS_FAMILY_6185,
3534
		.ops = &mv88e6131_ops,
3535 3536 3537 3538 3539 3540 3541 3542
	},

	[MV88E6161] = {
		.prod_num = PORT_SWITCH_ID_PROD_NUM_6161,
		.family = MV88E6XXX_FAMILY_6165,
		.name = "Marvell 88E6161",
		.num_databases = 4096,
		.num_ports = 6,
3543
		.port_base_addr = 0x10,
3544
		.global1_addr = 0x1b,
3545
		.age_time_coeff = 15000,
3546
		.g1_irqs = 9,
3547
		.flags = MV88E6XXX_FLAGS_FAMILY_6165,
3548
		.ops = &mv88e6161_ops,
3549 3550 3551 3552 3553 3554 3555 3556
	},

	[MV88E6165] = {
		.prod_num = PORT_SWITCH_ID_PROD_NUM_6165,
		.family = MV88E6XXX_FAMILY_6165,
		.name = "Marvell 88E6165",
		.num_databases = 4096,
		.num_ports = 6,
3557
		.port_base_addr = 0x10,
3558
		.global1_addr = 0x1b,
3559
		.age_time_coeff = 15000,
3560
		.g1_irqs = 9,
3561
		.flags = MV88E6XXX_FLAGS_FAMILY_6165,
3562
		.ops = &mv88e6165_ops,
3563 3564 3565 3566 3567 3568 3569 3570
	},

	[MV88E6171] = {
		.prod_num = PORT_SWITCH_ID_PROD_NUM_6171,
		.family = MV88E6XXX_FAMILY_6351,
		.name = "Marvell 88E6171",
		.num_databases = 4096,
		.num_ports = 7,
3571
		.port_base_addr = 0x10,
3572
		.global1_addr = 0x1b,
3573
		.age_time_coeff = 15000,
3574
		.g1_irqs = 9,
3575
		.flags = MV88E6XXX_FLAGS_FAMILY_6351,
3576
		.ops = &mv88e6171_ops,
3577 3578 3579 3580 3581 3582 3583 3584
	},

	[MV88E6172] = {
		.prod_num = PORT_SWITCH_ID_PROD_NUM_6172,
		.family = MV88E6XXX_FAMILY_6352,
		.name = "Marvell 88E6172",
		.num_databases = 4096,
		.num_ports = 7,
3585
		.port_base_addr = 0x10,
3586
		.global1_addr = 0x1b,
3587
		.age_time_coeff = 15000,
3588
		.g1_irqs = 9,
3589
		.flags = MV88E6XXX_FLAGS_FAMILY_6352,
3590
		.ops = &mv88e6172_ops,
3591 3592 3593 3594 3595 3596 3597 3598
	},

	[MV88E6175] = {
		.prod_num = PORT_SWITCH_ID_PROD_NUM_6175,
		.family = MV88E6XXX_FAMILY_6351,
		.name = "Marvell 88E6175",
		.num_databases = 4096,
		.num_ports = 7,
3599
		.port_base_addr = 0x10,
3600
		.global1_addr = 0x1b,
3601
		.age_time_coeff = 15000,
3602
		.g1_irqs = 9,
3603
		.flags = MV88E6XXX_FLAGS_FAMILY_6351,
3604
		.ops = &mv88e6175_ops,
3605 3606 3607 3608 3609 3610 3611 3612
	},

	[MV88E6176] = {
		.prod_num = PORT_SWITCH_ID_PROD_NUM_6176,
		.family = MV88E6XXX_FAMILY_6352,
		.name = "Marvell 88E6176",
		.num_databases = 4096,
		.num_ports = 7,
3613
		.port_base_addr = 0x10,
3614
		.global1_addr = 0x1b,
3615
		.age_time_coeff = 15000,
3616
		.g1_irqs = 9,
3617
		.flags = MV88E6XXX_FLAGS_FAMILY_6352,
3618
		.ops = &mv88e6176_ops,
3619 3620 3621 3622 3623 3624 3625 3626
	},

	[MV88E6185] = {
		.prod_num = PORT_SWITCH_ID_PROD_NUM_6185,
		.family = MV88E6XXX_FAMILY_6185,
		.name = "Marvell 88E6185",
		.num_databases = 256,
		.num_ports = 10,
3627
		.port_base_addr = 0x10,
3628
		.global1_addr = 0x1b,
3629
		.age_time_coeff = 15000,
3630
		.g1_irqs = 8,
3631
		.flags = MV88E6XXX_FLAGS_FAMILY_6185,
3632
		.ops = &mv88e6185_ops,
3633 3634 3635 3636 3637 3638 3639 3640
	},

	[MV88E6240] = {
		.prod_num = PORT_SWITCH_ID_PROD_NUM_6240,
		.family = MV88E6XXX_FAMILY_6352,
		.name = "Marvell 88E6240",
		.num_databases = 4096,
		.num_ports = 7,
3641
		.port_base_addr = 0x10,
3642
		.global1_addr = 0x1b,
3643
		.age_time_coeff = 15000,
3644
		.g1_irqs = 9,
3645
		.flags = MV88E6XXX_FLAGS_FAMILY_6352,
3646
		.ops = &mv88e6240_ops,
3647 3648 3649 3650 3651 3652 3653 3654
	},

	[MV88E6320] = {
		.prod_num = PORT_SWITCH_ID_PROD_NUM_6320,
		.family = MV88E6XXX_FAMILY_6320,
		.name = "Marvell 88E6320",
		.num_databases = 4096,
		.num_ports = 7,
3655
		.port_base_addr = 0x10,
3656
		.global1_addr = 0x1b,
3657
		.age_time_coeff = 15000,
3658
		.g1_irqs = 8,
3659
		.flags = MV88E6XXX_FLAGS_FAMILY_6320,
3660
		.ops = &mv88e6320_ops,
3661 3662 3663 3664 3665 3666 3667 3668
	},

	[MV88E6321] = {
		.prod_num = PORT_SWITCH_ID_PROD_NUM_6321,
		.family = MV88E6XXX_FAMILY_6320,
		.name = "Marvell 88E6321",
		.num_databases = 4096,
		.num_ports = 7,
3669
		.port_base_addr = 0x10,
3670
		.global1_addr = 0x1b,
3671
		.age_time_coeff = 15000,
3672
		.g1_irqs = 8,
3673
		.flags = MV88E6XXX_FLAGS_FAMILY_6320,
3674
		.ops = &mv88e6321_ops,
3675 3676 3677 3678 3679 3680 3681 3682
	},

	[MV88E6350] = {
		.prod_num = PORT_SWITCH_ID_PROD_NUM_6350,
		.family = MV88E6XXX_FAMILY_6351,
		.name = "Marvell 88E6350",
		.num_databases = 4096,
		.num_ports = 7,
3683
		.port_base_addr = 0x10,
3684
		.global1_addr = 0x1b,
3685
		.age_time_coeff = 15000,
3686
		.g1_irqs = 9,
3687
		.flags = MV88E6XXX_FLAGS_FAMILY_6351,
3688
		.ops = &mv88e6350_ops,
3689 3690 3691 3692 3693 3694 3695 3696
	},

	[MV88E6351] = {
		.prod_num = PORT_SWITCH_ID_PROD_NUM_6351,
		.family = MV88E6XXX_FAMILY_6351,
		.name = "Marvell 88E6351",
		.num_databases = 4096,
		.num_ports = 7,
3697
		.port_base_addr = 0x10,
3698
		.global1_addr = 0x1b,
3699
		.age_time_coeff = 15000,
3700
		.g1_irqs = 9,
3701
		.flags = MV88E6XXX_FLAGS_FAMILY_6351,
3702
		.ops = &mv88e6351_ops,
3703 3704 3705 3706 3707 3708 3709 3710
	},

	[MV88E6352] = {
		.prod_num = PORT_SWITCH_ID_PROD_NUM_6352,
		.family = MV88E6XXX_FAMILY_6352,
		.name = "Marvell 88E6352",
		.num_databases = 4096,
		.num_ports = 7,
3711
		.port_base_addr = 0x10,
3712
		.global1_addr = 0x1b,
3713
		.age_time_coeff = 15000,
3714
		.g1_irqs = 9,
3715
		.flags = MV88E6XXX_FLAGS_FAMILY_6352,
3716
		.ops = &mv88e6352_ops,
3717 3718 3719
	},
};

3720
static const struct mv88e6xxx_info *mv88e6xxx_lookup_info(unsigned int prod_num)
3721
{
3722
	int i;
3723

3724 3725 3726
	for (i = 0; i < ARRAY_SIZE(mv88e6xxx_table); ++i)
		if (mv88e6xxx_table[i].prod_num == prod_num)
			return &mv88e6xxx_table[i];
3727 3728 3729 3730

	return NULL;
}

3731
static int mv88e6xxx_detect(struct mv88e6xxx_chip *chip)
3732 3733
{
	const struct mv88e6xxx_info *info;
3734 3735 3736
	unsigned int prod_num, rev;
	u16 id;
	int err;
3737

3738 3739 3740 3741 3742
	mutex_lock(&chip->reg_lock);
	err = mv88e6xxx_port_read(chip, 0, PORT_SWITCH_ID, &id);
	mutex_unlock(&chip->reg_lock);
	if (err)
		return err;
3743 3744 3745 3746 3747 3748 3749 3750

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

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

3751
	/* Update the compatible info with the probed one */
3752
	chip->info = info;
3753

3754 3755 3756 3757
	err = mv88e6xxx_g2_require(chip);
	if (err)
		return err;

3758 3759
	dev_info(chip->dev, "switch 0x%x detected: %s, revision %u\n",
		 chip->info->prod_num, chip->info->name, rev);
3760 3761 3762 3763

	return 0;
}

3764
static struct mv88e6xxx_chip *mv88e6xxx_alloc_chip(struct device *dev)
3765
{
3766
	struct mv88e6xxx_chip *chip;
3767

3768 3769
	chip = devm_kzalloc(dev, sizeof(*chip), GFP_KERNEL);
	if (!chip)
3770 3771
		return NULL;

3772
	chip->dev = dev;
3773

3774
	mutex_init(&chip->reg_lock);
3775

3776
	return chip;
3777 3778
}

3779 3780
static void mv88e6xxx_phy_init(struct mv88e6xxx_chip *chip)
{
3781
	if (mv88e6xxx_has(chip, MV88E6XXX_FLAG_PPU))
3782 3783 3784
		mv88e6xxx_ppu_state_init(chip);
}

3785 3786
static void mv88e6xxx_phy_destroy(struct mv88e6xxx_chip *chip)
{
3787
	if (mv88e6xxx_has(chip, MV88E6XXX_FLAG_PPU))
3788 3789 3790
		mv88e6xxx_ppu_state_destroy(chip);
}

3791
static int mv88e6xxx_smi_init(struct mv88e6xxx_chip *chip,
3792 3793 3794 3795 3796 3797
			      struct mii_bus *bus, int sw_addr)
{
	/* ADDR[0] pin is unavailable externally and considered zero */
	if (sw_addr & 0x1)
		return -EINVAL;

3798
	if (sw_addr == 0)
3799
		chip->smi_ops = &mv88e6xxx_smi_single_chip_ops;
3800
	else if (mv88e6xxx_has(chip, MV88E6XXX_FLAGS_MULTI_CHIP))
3801
		chip->smi_ops = &mv88e6xxx_smi_multi_chip_ops;
3802 3803 3804
	else
		return -EINVAL;

3805 3806
	chip->bus = bus;
	chip->sw_addr = sw_addr;
3807 3808 3809 3810

	return 0;
}

3811 3812
static enum dsa_tag_protocol mv88e6xxx_get_tag_protocol(struct dsa_switch *ds)
{
V
Vivien Didelot 已提交
3813
	struct mv88e6xxx_chip *chip = ds->priv;
3814 3815 3816 3817 3818

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

	return DSA_TAG_PROTO_DSA;
3819 3820
}

3821 3822 3823
static const char *mv88e6xxx_drv_probe(struct device *dsa_dev,
				       struct device *host_dev, int sw_addr,
				       void **priv)
3824
{
3825
	struct mv88e6xxx_chip *chip;
3826
	struct mii_bus *bus;
3827
	int err;
3828

3829
	bus = dsa_host_dev_to_mii_bus(host_dev);
3830 3831 3832
	if (!bus)
		return NULL;

3833 3834
	chip = mv88e6xxx_alloc_chip(dsa_dev);
	if (!chip)
3835 3836
		return NULL;

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

3840
	err = mv88e6xxx_smi_init(chip, bus, sw_addr);
3841 3842 3843
	if (err)
		goto free;

3844
	err = mv88e6xxx_detect(chip);
3845
	if (err)
3846
		goto free;
3847

3848 3849 3850 3851 3852 3853
	mutex_lock(&chip->reg_lock);
	err = mv88e6xxx_switch_reset(chip);
	mutex_unlock(&chip->reg_lock);
	if (err)
		goto free;

3854 3855
	mv88e6xxx_phy_init(chip);

3856
	err = mv88e6xxx_mdio_register(chip, NULL);
3857
	if (err)
3858
		goto free;
3859

3860
	*priv = chip;
3861

3862
	return chip->info->name;
3863
free:
3864
	devm_kfree(dsa_dev, chip);
3865 3866

	return NULL;
3867 3868
}

3869 3870 3871 3872 3873 3874 3875 3876 3877 3878 3879 3880 3881 3882 3883
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 已提交
3884
	struct mv88e6xxx_chip *chip = ds->priv;
3885 3886 3887 3888 3889 3890 3891 3892 3893 3894 3895

	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 已提交
3896
	struct mv88e6xxx_chip *chip = ds->priv;
3897 3898 3899 3900 3901 3902 3903 3904 3905 3906 3907 3908 3909 3910
	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 已提交
3911
	struct mv88e6xxx_chip *chip = ds->priv;
3912 3913 3914 3915 3916 3917 3918 3919 3920
	int err;

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

	return err;
}

3921
static struct dsa_switch_ops mv88e6xxx_switch_ops = {
3922
	.probe			= mv88e6xxx_drv_probe,
3923
	.get_tag_protocol	= mv88e6xxx_get_tag_protocol,
3924 3925 3926 3927 3928 3929 3930 3931 3932 3933 3934 3935 3936 3937
	.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
3938
	.get_eeprom_len		= mv88e6xxx_get_eeprom_len,
3939 3940 3941 3942
	.get_eeprom		= mv88e6xxx_get_eeprom,
	.set_eeprom		= mv88e6xxx_set_eeprom,
	.get_regs_len		= mv88e6xxx_get_regs_len,
	.get_regs		= mv88e6xxx_get_regs,
3943
	.set_ageing_time	= mv88e6xxx_set_ageing_time,
3944 3945 3946
	.port_bridge_join	= mv88e6xxx_port_bridge_join,
	.port_bridge_leave	= mv88e6xxx_port_bridge_leave,
	.port_stp_state_set	= mv88e6xxx_port_stp_state_set,
3947
	.port_fast_age		= mv88e6xxx_port_fast_age,
3948 3949 3950 3951 3952 3953 3954 3955 3956
	.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,
3957 3958 3959 3960
	.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,
3961 3962
};

3963
static int mv88e6xxx_register_switch(struct mv88e6xxx_chip *chip,
3964 3965
				     struct device_node *np)
{
3966
	struct device *dev = chip->dev;
3967 3968 3969 3970 3971 3972 3973
	struct dsa_switch *ds;

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

	ds->dev = dev;
3974
	ds->priv = chip;
3975
	ds->ops = &mv88e6xxx_switch_ops;
3976 3977 3978 3979 3980 3981

	dev_set_drvdata(dev, ds);

	return dsa_register_switch(ds, np);
}

3982
static void mv88e6xxx_unregister_switch(struct mv88e6xxx_chip *chip)
3983
{
3984
	dsa_unregister_switch(chip->ds);
3985 3986
}

3987
static int mv88e6xxx_probe(struct mdio_device *mdiodev)
3988
{
3989
	struct device *dev = &mdiodev->dev;
3990
	struct device_node *np = dev->of_node;
3991
	const struct mv88e6xxx_info *compat_info;
3992
	struct mv88e6xxx_chip *chip;
3993
	u32 eeprom_len;
3994
	int err;
3995

3996 3997 3998 3999
	compat_info = of_device_get_match_data(dev);
	if (!compat_info)
		return -EINVAL;

4000 4001
	chip = mv88e6xxx_alloc_chip(dev);
	if (!chip)
4002 4003
		return -ENOMEM;

4004
	chip->info = compat_info;
4005

4006
	err = mv88e6xxx_smi_init(chip, mdiodev->bus, mdiodev->addr);
4007 4008
	if (err)
		return err;
4009

4010
	err = mv88e6xxx_detect(chip);
4011 4012
	if (err)
		return err;
4013

4014 4015
	mv88e6xxx_phy_init(chip);

4016 4017 4018
	chip->reset = devm_gpiod_get_optional(dev, "reset", GPIOD_ASIS);
	if (IS_ERR(chip->reset))
		return PTR_ERR(chip->reset);
4019

4020
	if (chip->info->ops->get_eeprom &&
4021
	    !of_property_read_u32(np, "eeprom-length", &eeprom_len))
4022
		chip->eeprom_len = eeprom_len;
4023

4024 4025 4026 4027 4028 4029 4030 4031 4032 4033 4034 4035 4036 4037 4038 4039 4040 4041 4042 4043 4044 4045 4046 4047 4048 4049 4050 4051 4052 4053 4054
	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;
		}
	}

4055
	err = mv88e6xxx_mdio_register(chip, np);
4056
	if (err)
4057
		goto out_g2_irq;
4058

4059
	err = mv88e6xxx_register_switch(chip, np);
4060 4061
	if (err)
		goto out_mdio;
4062

4063
	return 0;
4064 4065 4066 4067 4068 4069 4070 4071 4072 4073

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;
4074
}
4075 4076 4077 4078

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

4081
	mv88e6xxx_phy_destroy(chip);
4082 4083
	mv88e6xxx_unregister_switch(chip);
	mv88e6xxx_mdio_unregister(chip);
4084 4085 4086 4087

	if (mv88e6xxx_has(chip, MV88E6XXX_FLAG_G2_INT))
		mv88e6xxx_g2_irq_free(chip);
	mv88e6xxx_g1_irq_free(chip);
4088 4089 4090
}

static const struct of_device_id mv88e6xxx_of_match[] = {
4091 4092 4093 4094
	{
		.compatible = "marvell,mv88e6085",
		.data = &mv88e6xxx_table[MV88E6085],
	},
4095 4096 4097 4098 4099 4100 4101 4102 4103 4104 4105 4106 4107 4108 4109 4110
	{ /* 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)
{
4111
	register_switch_driver(&mv88e6xxx_switch_ops);
4112 4113
	return mdio_driver_register(&mv88e6xxx_driver);
}
4114 4115 4116 4117
module_init(mv88e6xxx_init);

static void __exit mv88e6xxx_cleanup(void)
{
4118
	mdio_driver_unregister(&mv88e6xxx_driver);
4119
	unregister_switch_driver(&mv88e6xxx_switch_ops);
4120 4121
}
module_exit(mv88e6xxx_cleanup);
4122 4123 4124 4125

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