Lines Matching +full:chip +full:- +full:reset
1 // SPDX-License-Identifier: GPL-2.0-or-later
3 * Marvell 88e6xxx Ethernet switch single-chip support
9 * Copyright (c) 2016-2017 Savoir-faire Linux Inc.
35 #include "chip.h"
46 static void assert_reg_lock(struct mv88e6xxx_chip *chip) in assert_reg_lock() argument
48 if (unlikely(!mutex_is_locked(&chip->reg_lock))) { in assert_reg_lock()
49 dev_err(chip->dev, "Switch registers lock not held!\n"); in assert_reg_lock()
54 int mv88e6xxx_read(struct mv88e6xxx_chip *chip, int addr, int reg, u16 *val) in mv88e6xxx_read() argument
58 assert_reg_lock(chip); in mv88e6xxx_read()
60 err = mv88e6xxx_smi_read(chip, addr, reg, val); in mv88e6xxx_read()
64 dev_dbg(chip->dev, "<- addr: 0x%.2x reg: 0x%.2x val: 0x%.4x\n", in mv88e6xxx_read()
70 int mv88e6xxx_write(struct mv88e6xxx_chip *chip, int addr, int reg, u16 val) in mv88e6xxx_write() argument
74 assert_reg_lock(chip); in mv88e6xxx_write()
76 err = mv88e6xxx_smi_write(chip, addr, reg, val); in mv88e6xxx_write()
80 dev_dbg(chip->dev, "-> addr: 0x%.2x reg: 0x%.2x val: 0x%.4x\n", in mv88e6xxx_write()
86 int mv88e6xxx_wait_mask(struct mv88e6xxx_chip *chip, int addr, int reg, in mv88e6xxx_wait_mask() argument
99 err = mv88e6xxx_read(chip, addr, reg, &data); in mv88e6xxx_wait_mask()
112 err = mv88e6xxx_read(chip, addr, reg, &data); in mv88e6xxx_wait_mask()
119 dev_err(chip->dev, "Timeout while waiting for switch\n"); in mv88e6xxx_wait_mask()
120 return -ETIMEDOUT; in mv88e6xxx_wait_mask()
123 int mv88e6xxx_wait_bit(struct mv88e6xxx_chip *chip, int addr, int reg, in mv88e6xxx_wait_bit() argument
126 return mv88e6xxx_wait_mask(chip, addr, reg, BIT(bit), in mv88e6xxx_wait_bit()
130 struct mii_bus *mv88e6xxx_default_mdio_bus(struct mv88e6xxx_chip *chip) in mv88e6xxx_default_mdio_bus() argument
134 mdio_bus = list_first_entry_or_null(&chip->mdios, in mv88e6xxx_default_mdio_bus()
139 return mdio_bus->bus; in mv88e6xxx_default_mdio_bus()
144 struct mv88e6xxx_chip *chip = irq_data_get_irq_chip_data(d); in mv88e6xxx_g1_irq_mask() local
145 unsigned int n = d->hwirq; in mv88e6xxx_g1_irq_mask()
147 chip->g1_irq.masked |= (1 << n); in mv88e6xxx_g1_irq_mask()
152 struct mv88e6xxx_chip *chip = irq_data_get_irq_chip_data(d); in mv88e6xxx_g1_irq_unmask() local
153 unsigned int n = d->hwirq; in mv88e6xxx_g1_irq_unmask()
155 chip->g1_irq.masked &= ~(1 << n); in mv88e6xxx_g1_irq_unmask()
158 static irqreturn_t mv88e6xxx_g1_irq_thread_work(struct mv88e6xxx_chip *chip) in mv88e6xxx_g1_irq_thread_work() argument
167 mv88e6xxx_reg_lock(chip); in mv88e6xxx_g1_irq_thread_work()
168 err = mv88e6xxx_g1_read(chip, MV88E6XXX_G1_STS, ®); in mv88e6xxx_g1_irq_thread_work()
169 mv88e6xxx_reg_unlock(chip); in mv88e6xxx_g1_irq_thread_work()
175 for (n = 0; n < chip->g1_irq.nirqs; ++n) { in mv88e6xxx_g1_irq_thread_work()
177 sub_irq = irq_find_mapping(chip->g1_irq.domain, in mv88e6xxx_g1_irq_thread_work()
184 mv88e6xxx_reg_lock(chip); in mv88e6xxx_g1_irq_thread_work()
185 err = mv88e6xxx_g1_read(chip, MV88E6XXX_G1_CTL1, &ctl1); in mv88e6xxx_g1_irq_thread_work()
188 err = mv88e6xxx_g1_read(chip, MV88E6XXX_G1_STS, ®); in mv88e6xxx_g1_irq_thread_work()
190 mv88e6xxx_reg_unlock(chip); in mv88e6xxx_g1_irq_thread_work()
193 ctl1 &= GENMASK(chip->g1_irq.nirqs, 0); in mv88e6xxx_g1_irq_thread_work()
202 struct mv88e6xxx_chip *chip = dev_id; in mv88e6xxx_g1_irq_thread_fn() local
204 return mv88e6xxx_g1_irq_thread_work(chip); in mv88e6xxx_g1_irq_thread_fn()
209 struct mv88e6xxx_chip *chip = irq_data_get_irq_chip_data(d); in mv88e6xxx_g1_irq_bus_lock() local
211 mv88e6xxx_reg_lock(chip); in mv88e6xxx_g1_irq_bus_lock()
216 struct mv88e6xxx_chip *chip = irq_data_get_irq_chip_data(d); in mv88e6xxx_g1_irq_bus_sync_unlock() local
217 u16 mask = GENMASK(chip->g1_irq.nirqs, 0); in mv88e6xxx_g1_irq_bus_sync_unlock()
221 err = mv88e6xxx_g1_read(chip, MV88E6XXX_G1_CTL1, ®); in mv88e6xxx_g1_irq_bus_sync_unlock()
226 reg |= (~chip->g1_irq.masked & mask); in mv88e6xxx_g1_irq_bus_sync_unlock()
228 err = mv88e6xxx_g1_write(chip, MV88E6XXX_G1_CTL1, reg); in mv88e6xxx_g1_irq_bus_sync_unlock()
233 mv88e6xxx_reg_unlock(chip); in mv88e6xxx_g1_irq_bus_sync_unlock()
237 .name = "mv88e6xxx-g1",
248 struct mv88e6xxx_chip *chip = d->host_data; in mv88e6xxx_g1_irq_domain_map() local
250 irq_set_chip_data(irq, d->host_data); in mv88e6xxx_g1_irq_domain_map()
251 irq_set_chip_and_handler(irq, &chip->g1_irq.chip, handle_level_irq); in mv88e6xxx_g1_irq_domain_map()
263 static void mv88e6xxx_g1_irq_free_common(struct mv88e6xxx_chip *chip) in mv88e6xxx_g1_irq_free_common() argument
268 mv88e6xxx_g1_read(chip, MV88E6XXX_G1_CTL1, &mask); in mv88e6xxx_g1_irq_free_common()
269 mask &= ~GENMASK(chip->g1_irq.nirqs, 0); in mv88e6xxx_g1_irq_free_common()
270 mv88e6xxx_g1_write(chip, MV88E6XXX_G1_CTL1, mask); in mv88e6xxx_g1_irq_free_common()
272 for (irq = 0; irq < chip->g1_irq.nirqs; irq++) { in mv88e6xxx_g1_irq_free_common()
273 virq = irq_find_mapping(chip->g1_irq.domain, irq); in mv88e6xxx_g1_irq_free_common()
277 irq_domain_remove(chip->g1_irq.domain); in mv88e6xxx_g1_irq_free_common()
280 static void mv88e6xxx_g1_irq_free(struct mv88e6xxx_chip *chip) in mv88e6xxx_g1_irq_free() argument
286 free_irq(chip->irq, chip); in mv88e6xxx_g1_irq_free()
288 mv88e6xxx_reg_lock(chip); in mv88e6xxx_g1_irq_free()
289 mv88e6xxx_g1_irq_free_common(chip); in mv88e6xxx_g1_irq_free()
290 mv88e6xxx_reg_unlock(chip); in mv88e6xxx_g1_irq_free()
293 static int mv88e6xxx_g1_irq_setup_common(struct mv88e6xxx_chip *chip) in mv88e6xxx_g1_irq_setup_common() argument
298 chip->g1_irq.nirqs = chip->info->g1_irqs; in mv88e6xxx_g1_irq_setup_common()
299 chip->g1_irq.domain = irq_domain_add_simple( in mv88e6xxx_g1_irq_setup_common()
300 NULL, chip->g1_irq.nirqs, 0, in mv88e6xxx_g1_irq_setup_common()
301 &mv88e6xxx_g1_irq_domain_ops, chip); in mv88e6xxx_g1_irq_setup_common()
302 if (!chip->g1_irq.domain) in mv88e6xxx_g1_irq_setup_common()
303 return -ENOMEM; in mv88e6xxx_g1_irq_setup_common()
305 for (irq = 0; irq < chip->g1_irq.nirqs; irq++) in mv88e6xxx_g1_irq_setup_common()
306 irq_create_mapping(chip->g1_irq.domain, irq); in mv88e6xxx_g1_irq_setup_common()
308 chip->g1_irq.chip = mv88e6xxx_g1_irq_chip; in mv88e6xxx_g1_irq_setup_common()
309 chip->g1_irq.masked = ~0; in mv88e6xxx_g1_irq_setup_common()
311 err = mv88e6xxx_g1_read(chip, MV88E6XXX_G1_CTL1, &mask); in mv88e6xxx_g1_irq_setup_common()
315 mask &= ~GENMASK(chip->g1_irq.nirqs, 0); in mv88e6xxx_g1_irq_setup_common()
317 err = mv88e6xxx_g1_write(chip, MV88E6XXX_G1_CTL1, mask); in mv88e6xxx_g1_irq_setup_common()
322 err = mv88e6xxx_g1_read(chip, MV88E6XXX_G1_STS, ®); in mv88e6xxx_g1_irq_setup_common()
329 mask &= ~GENMASK(chip->g1_irq.nirqs, 0); in mv88e6xxx_g1_irq_setup_common()
330 mv88e6xxx_g1_write(chip, MV88E6XXX_G1_CTL1, mask); in mv88e6xxx_g1_irq_setup_common()
334 virq = irq_find_mapping(chip->g1_irq.domain, irq); in mv88e6xxx_g1_irq_setup_common()
338 irq_domain_remove(chip->g1_irq.domain); in mv88e6xxx_g1_irq_setup_common()
343 static int mv88e6xxx_g1_irq_setup(struct mv88e6xxx_chip *chip) in mv88e6xxx_g1_irq_setup() argument
349 err = mv88e6xxx_g1_irq_setup_common(chip); in mv88e6xxx_g1_irq_setup()
357 irq_set_lockdep_class(chip->irq, &lock_key, &request_key); in mv88e6xxx_g1_irq_setup()
359 snprintf(chip->irq_name, sizeof(chip->irq_name), in mv88e6xxx_g1_irq_setup()
360 "mv88e6xxx-%s", dev_name(chip->dev)); in mv88e6xxx_g1_irq_setup()
362 mv88e6xxx_reg_unlock(chip); in mv88e6xxx_g1_irq_setup()
363 err = request_threaded_irq(chip->irq, NULL, in mv88e6xxx_g1_irq_setup()
366 chip->irq_name, chip); in mv88e6xxx_g1_irq_setup()
367 mv88e6xxx_reg_lock(chip); in mv88e6xxx_g1_irq_setup()
369 mv88e6xxx_g1_irq_free_common(chip); in mv88e6xxx_g1_irq_setup()
376 struct mv88e6xxx_chip *chip = container_of(work, in mv88e6xxx_irq_poll() local
379 mv88e6xxx_g1_irq_thread_work(chip); in mv88e6xxx_irq_poll()
381 kthread_queue_delayed_work(chip->kworker, &chip->irq_poll_work, in mv88e6xxx_irq_poll()
385 static int mv88e6xxx_irq_poll_setup(struct mv88e6xxx_chip *chip) in mv88e6xxx_irq_poll_setup() argument
389 err = mv88e6xxx_g1_irq_setup_common(chip); in mv88e6xxx_irq_poll_setup()
393 kthread_init_delayed_work(&chip->irq_poll_work, in mv88e6xxx_irq_poll_setup()
396 chip->kworker = kthread_create_worker(0, "%s", dev_name(chip->dev)); in mv88e6xxx_irq_poll_setup()
397 if (IS_ERR(chip->kworker)) in mv88e6xxx_irq_poll_setup()
398 return PTR_ERR(chip->kworker); in mv88e6xxx_irq_poll_setup()
400 kthread_queue_delayed_work(chip->kworker, &chip->irq_poll_work, in mv88e6xxx_irq_poll_setup()
406 static void mv88e6xxx_irq_poll_free(struct mv88e6xxx_chip *chip) in mv88e6xxx_irq_poll_free() argument
408 kthread_cancel_delayed_work_sync(&chip->irq_poll_work); in mv88e6xxx_irq_poll_free()
409 kthread_destroy_worker(chip->kworker); in mv88e6xxx_irq_poll_free()
411 mv88e6xxx_reg_lock(chip); in mv88e6xxx_irq_poll_free()
412 mv88e6xxx_g1_irq_free_common(chip); in mv88e6xxx_irq_poll_free()
413 mv88e6xxx_reg_unlock(chip); in mv88e6xxx_irq_poll_free()
416 static int mv88e6xxx_port_config_interface(struct mv88e6xxx_chip *chip, in mv88e6xxx_port_config_interface() argument
421 if (chip->info->ops->port_set_rgmii_delay) { in mv88e6xxx_port_config_interface()
422 err = chip->info->ops->port_set_rgmii_delay(chip, port, in mv88e6xxx_port_config_interface()
424 if (err && err != -EOPNOTSUPP) in mv88e6xxx_port_config_interface()
428 if (chip->info->ops->port_set_cmode) { in mv88e6xxx_port_config_interface()
429 err = chip->info->ops->port_set_cmode(chip, port, in mv88e6xxx_port_config_interface()
431 if (err && err != -EOPNOTSUPP) in mv88e6xxx_port_config_interface()
438 static int mv88e6xxx_port_setup_mac(struct mv88e6xxx_chip *chip, int port, in mv88e6xxx_port_setup_mac() argument
444 if (!chip->info->ops->port_set_link) in mv88e6xxx_port_setup_mac()
448 err = chip->info->ops->port_set_link(chip, port, LINK_FORCED_DOWN); in mv88e6xxx_port_setup_mac()
452 if (chip->info->ops->port_set_speed_duplex) { in mv88e6xxx_port_setup_mac()
453 err = chip->info->ops->port_set_speed_duplex(chip, port, in mv88e6xxx_port_setup_mac()
455 if (err && err != -EOPNOTSUPP) in mv88e6xxx_port_setup_mac()
459 if (chip->info->ops->port_set_pause) { in mv88e6xxx_port_setup_mac()
460 err = chip->info->ops->port_set_pause(chip, port, pause); in mv88e6xxx_port_setup_mac()
465 err = mv88e6xxx_port_config_interface(chip, port, mode); in mv88e6xxx_port_setup_mac()
467 if (chip->info->ops->port_set_link(chip, port, link)) in mv88e6xxx_port_setup_mac()
468 dev_err(chip->dev, "p%d: failed to restore MAC's link\n", port); in mv88e6xxx_port_setup_mac()
473 static int mv88e6xxx_phy_is_internal(struct mv88e6xxx_chip *chip, int port) in mv88e6xxx_phy_is_internal() argument
475 return port >= chip->info->internal_phys_offset && in mv88e6xxx_phy_is_internal()
476 port < chip->info->num_internal_phys + in mv88e6xxx_phy_is_internal()
477 chip->info->internal_phys_offset; in mv88e6xxx_phy_is_internal()
480 static int mv88e6xxx_port_ppu_updates(struct mv88e6xxx_chip *chip, int port) in mv88e6xxx_port_ppu_updates() argument
488 if (chip->info->family == MV88E6XXX_FAMILY_6250) in mv88e6xxx_port_ppu_updates()
489 return mv88e6xxx_phy_is_internal(chip, port); in mv88e6xxx_port_ppu_updates()
491 err = mv88e6xxx_port_read(chip, port, MV88E6XXX_PORT_STS, ®); in mv88e6xxx_port_ppu_updates()
493 dev_err(chip->dev, in mv88e6xxx_port_ppu_updates()
512 static void mv88e6095_phylink_get_caps(struct mv88e6xxx_chip *chip, int port, in mv88e6095_phylink_get_caps() argument
515 u8 cmode = chip->ports[port].cmode; in mv88e6095_phylink_get_caps()
517 config->mac_capabilities = MAC_SYM_PAUSE | MAC_10 | MAC_100; in mv88e6095_phylink_get_caps()
519 if (mv88e6xxx_phy_is_internal(chip, port)) { in mv88e6095_phylink_get_caps()
520 __set_bit(PHY_INTERFACE_MODE_MII, config->supported_interfaces); in mv88e6095_phylink_get_caps()
525 config->supported_interfaces); in mv88e6095_phylink_get_caps()
527 config->mac_capabilities |= MAC_1000FD; in mv88e6095_phylink_get_caps()
531 static void mv88e6185_phylink_get_caps(struct mv88e6xxx_chip *chip, int port, in mv88e6185_phylink_get_caps() argument
534 u8 cmode = chip->ports[port].cmode; in mv88e6185_phylink_get_caps()
539 config->supported_interfaces); in mv88e6185_phylink_get_caps()
541 config->mac_capabilities = MAC_SYM_PAUSE | MAC_10 | MAC_100 | in mv88e6185_phylink_get_caps()
570 mv88e6250_setup_supported_interfaces(struct mv88e6xxx_chip *chip, int port, in mv88e6250_setup_supported_interfaces() argument
573 unsigned long *supported = config->supported_interfaces; in mv88e6250_setup_supported_interfaces()
577 err = mv88e6xxx_port_read(chip, port, MV88E6XXX_PORT_STS, ®); in mv88e6250_setup_supported_interfaces()
579 dev_err(chip->dev, "p%d: failed to read port status\n", port); in mv88e6250_setup_supported_interfaces()
613 dev_err(chip->dev, in mv88e6250_setup_supported_interfaces()
619 static void mv88e6250_phylink_get_caps(struct mv88e6xxx_chip *chip, int port, in mv88e6250_phylink_get_caps() argument
622 if (!mv88e6xxx_phy_is_internal(chip, port)) in mv88e6250_phylink_get_caps()
623 mv88e6250_setup_supported_interfaces(chip, port, config); in mv88e6250_phylink_get_caps()
625 config->mac_capabilities = MAC_SYM_PAUSE | MAC_10 | MAC_100; in mv88e6250_phylink_get_caps()
628 static void mv88e6351_phylink_get_caps(struct mv88e6xxx_chip *chip, int port, in mv88e6351_phylink_get_caps() argument
631 unsigned long *supported = config->supported_interfaces; in mv88e6351_phylink_get_caps()
634 mv88e6xxx_translate_cmode(chip->ports[port].cmode, supported); in mv88e6351_phylink_get_caps()
636 config->mac_capabilities = MAC_SYM_PAUSE | MAC_10 | MAC_100 | in mv88e6351_phylink_get_caps()
640 static int mv88e63xx_get_port_serdes_cmode(struct mv88e6xxx_chip *chip, int port) in mv88e63xx_get_port_serdes_cmode() argument
645 err = mv88e6xxx_port_read(chip, port, MV88E6XXX_PORT_STS, ®); in mv88e63xx_get_port_serdes_cmode()
649 /* If PHY_DETECT is zero, then we are not in auto-media mode */ in mv88e63xx_get_port_serdes_cmode()
654 err = mv88e6xxx_port_write(chip, port, MV88E6XXX_PORT_STS, val); in mv88e63xx_get_port_serdes_cmode()
658 err = mv88e6xxx_port_read(chip, port, MV88E6XXX_PORT_STS, &val); in mv88e63xx_get_port_serdes_cmode()
663 err = mv88e6xxx_port_write(chip, port, MV88E6XXX_PORT_STS, reg); in mv88e63xx_get_port_serdes_cmode()
670 static void mv88e6352_phylink_get_caps(struct mv88e6xxx_chip *chip, int port, in mv88e6352_phylink_get_caps() argument
673 unsigned long *supported = config->supported_interfaces; in mv88e6352_phylink_get_caps()
677 mv88e6xxx_translate_cmode(chip->ports[port].cmode, supported); in mv88e6352_phylink_get_caps()
679 config->mac_capabilities = MAC_SYM_PAUSE | MAC_10 | MAC_100 | in mv88e6352_phylink_get_caps()
684 err = mv88e6352_g2_scratch_port_has_serdes(chip, port); in mv88e6352_phylink_get_caps()
686 dev_err(chip->dev, "p%d: failed to read scratch\n", in mv88e6352_phylink_get_caps()
691 cmode = mv88e63xx_get_port_serdes_cmode(chip, port); in mv88e6352_phylink_get_caps()
693 dev_err(chip->dev, "p%d: failed to read serdes cmode\n", in mv88e6352_phylink_get_caps()
700 static void mv88e632x_phylink_get_caps(struct mv88e6xxx_chip *chip, int port, in mv88e632x_phylink_get_caps() argument
703 unsigned long *supported = config->supported_interfaces; in mv88e632x_phylink_get_caps()
707 mv88e6xxx_translate_cmode(chip->ports[port].cmode, supported); in mv88e632x_phylink_get_caps()
709 config->mac_capabilities = MAC_SYM_PAUSE | MAC_10 | MAC_100 | in mv88e632x_phylink_get_caps()
714 cmode = mv88e63xx_get_port_serdes_cmode(chip, port); in mv88e632x_phylink_get_caps()
716 dev_err(chip->dev, "p%d: failed to read serdes cmode\n", in mv88e632x_phylink_get_caps()
723 static void mv88e6341_phylink_get_caps(struct mv88e6xxx_chip *chip, int port, in mv88e6341_phylink_get_caps() argument
726 unsigned long *supported = config->supported_interfaces; in mv88e6341_phylink_get_caps()
729 mv88e6xxx_translate_cmode(chip->ports[port].cmode, supported); in mv88e6341_phylink_get_caps()
732 config->mac_capabilities = MAC_SYM_PAUSE | MAC_10 | MAC_100 | in mv88e6341_phylink_get_caps()
741 config->mac_capabilities |= MAC_2500FD; in mv88e6341_phylink_get_caps()
745 static void mv88e6390_phylink_get_caps(struct mv88e6xxx_chip *chip, int port, in mv88e6390_phylink_get_caps() argument
748 unsigned long *supported = config->supported_interfaces; in mv88e6390_phylink_get_caps()
751 mv88e6xxx_translate_cmode(chip->ports[port].cmode, supported); in mv88e6390_phylink_get_caps()
754 config->mac_capabilities = MAC_SYM_PAUSE | MAC_10 | MAC_100 | in mv88e6390_phylink_get_caps()
763 config->mac_capabilities |= MAC_2500FD; in mv88e6390_phylink_get_caps()
767 static void mv88e6390x_phylink_get_caps(struct mv88e6xxx_chip *chip, int port, in mv88e6390x_phylink_get_caps() argument
770 unsigned long *supported = config->supported_interfaces; in mv88e6390x_phylink_get_caps()
772 mv88e6390_phylink_get_caps(chip, port, config); in mv88e6390x_phylink_get_caps()
774 /* For the 6x90X, ports 2-7 can be in automedia mode. in mv88e6390x_phylink_get_caps()
777 * Port 2 can also support 1000BASE-X in automedia mode if port 9 is in mv88e6390x_phylink_get_caps()
778 * configured for 1000BASE-X, SGMII or 2500BASE-X. in mv88e6390x_phylink_get_caps()
779 * Port 3-4 can also support 1000BASE-X in automedia mode if port 9 is in mv88e6390x_phylink_get_caps()
780 * configured for RXAUI, 1000BASE-X, SGMII or 2500BASE-X. in mv88e6390x_phylink_get_caps()
782 * Port 5 can also support 1000BASE-X in automedia mode if port 10 is in mv88e6390x_phylink_get_caps()
783 * configured for 1000BASE-X, SGMII or 2500BASE-X. in mv88e6390x_phylink_get_caps()
784 * Port 6-7 can also support 1000BASE-X in automedia mode if port 10 is in mv88e6390x_phylink_get_caps()
785 * configured for RXAUI, 1000BASE-X, SGMII or 2500BASE-X. in mv88e6390x_phylink_get_caps()
787 * For now, be permissive (as the old code was) and allow 1000BASE-X in mv88e6390x_phylink_get_caps()
798 config->mac_capabilities |= MAC_10000FD; in mv88e6390x_phylink_get_caps()
802 static void mv88e6393x_phylink_get_caps(struct mv88e6xxx_chip *chip, int port, in mv88e6393x_phylink_get_caps() argument
805 unsigned long *supported = config->supported_interfaces; in mv88e6393x_phylink_get_caps()
807 chip->info->prod_num == MV88E6XXX_PORT_SWITCH_ID_PROD_6191X; in mv88e6393x_phylink_get_caps()
809 chip->info->prod_num == MV88E6XXX_PORT_SWITCH_ID_PROD_6361; in mv88e6393x_phylink_get_caps()
811 mv88e6xxx_translate_cmode(chip->ports[port].cmode, supported); in mv88e6393x_phylink_get_caps()
813 config->mac_capabilities = MAC_SYM_PAUSE | MAC_10 | MAC_100 | in mv88e6393x_phylink_get_caps()
824 config->mac_capabilities |= MAC_2500FD; in mv88e6393x_phylink_get_caps()
831 config->mac_capabilities |= MAC_5000FD | in mv88e6393x_phylink_get_caps()
849 struct mv88e6xxx_chip *chip = ds->priv; in mv88e6xxx_get_caps() local
851 mv88e6xxx_reg_lock(chip); in mv88e6xxx_get_caps()
852 chip->info->ops->phylink_get_caps(chip, port, config); in mv88e6xxx_get_caps()
853 mv88e6xxx_reg_unlock(chip); in mv88e6xxx_get_caps()
855 if (mv88e6xxx_phy_is_internal(chip, port)) { in mv88e6xxx_get_caps()
857 config->supported_interfaces); in mv88e6xxx_get_caps()
858 /* Internal ports with no phy-mode need GMII for PHYLIB */ in mv88e6xxx_get_caps()
860 config->supported_interfaces); in mv88e6xxx_get_caps()
869 struct mv88e6xxx_chip *chip = dp->ds->priv; in mv88e6xxx_mac_select_pcs() local
870 struct phylink_pcs *pcs = ERR_PTR(-EOPNOTSUPP); in mv88e6xxx_mac_select_pcs()
872 if (chip->info->ops->pcs_ops) in mv88e6xxx_mac_select_pcs()
873 pcs = chip->info->ops->pcs_ops->pcs_select(chip, dp->index, in mv88e6xxx_mac_select_pcs()
883 struct mv88e6xxx_chip *chip = dp->ds->priv; in mv88e6xxx_mac_prepare() local
884 int port = dp->index; in mv88e6xxx_mac_prepare()
892 chip->ports[port].interface != interface && in mv88e6xxx_mac_prepare()
893 chip->info->ops->port_set_link) { in mv88e6xxx_mac_prepare()
894 mv88e6xxx_reg_lock(chip); in mv88e6xxx_mac_prepare()
895 err = chip->info->ops->port_set_link(chip, port, in mv88e6xxx_mac_prepare()
897 mv88e6xxx_reg_unlock(chip); in mv88e6xxx_mac_prepare()
908 struct mv88e6xxx_chip *chip = dp->ds->priv; in mv88e6xxx_mac_config() local
909 int port = dp->index; in mv88e6xxx_mac_config()
912 mv88e6xxx_reg_lock(chip); in mv88e6xxx_mac_config()
914 if (mode != MLO_AN_PHY || !mv88e6xxx_phy_is_internal(chip, port)) { in mv88e6xxx_mac_config()
915 err = mv88e6xxx_port_config_interface(chip, port, in mv88e6xxx_mac_config()
916 state->interface); in mv88e6xxx_mac_config()
917 if (err && err != -EOPNOTSUPP) in mv88e6xxx_mac_config()
922 mv88e6xxx_reg_unlock(chip); in mv88e6xxx_mac_config()
924 if (err && err != -EOPNOTSUPP) in mv88e6xxx_mac_config()
925 dev_err(chip->dev, "p%d: failed to configure MAC/PCS\n", port); in mv88e6xxx_mac_config()
932 struct mv88e6xxx_chip *chip = dp->ds->priv; in mv88e6xxx_mac_finish() local
933 int port = dp->index; in mv88e6xxx_mac_finish()
938 * up in the in-band case where there is no separate SERDES. Also in mv88e6xxx_mac_finish()
940 * in PHY mode (we treat the PPU as an effective in-band mechanism.) in mv88e6xxx_mac_finish()
942 mv88e6xxx_reg_lock(chip); in mv88e6xxx_mac_finish()
944 if (chip->info->ops->port_set_link && in mv88e6xxx_mac_finish()
946 chip->ports[port].interface != interface) || in mv88e6xxx_mac_finish()
947 (mode == MLO_AN_PHY && mv88e6xxx_port_ppu_updates(chip, port)))) in mv88e6xxx_mac_finish()
948 err = chip->info->ops->port_set_link(chip, port, LINK_UNFORCED); in mv88e6xxx_mac_finish()
950 mv88e6xxx_reg_unlock(chip); in mv88e6xxx_mac_finish()
952 chip->ports[port].interface = interface; in mv88e6xxx_mac_finish()
962 struct mv88e6xxx_chip *chip = dp->ds->priv; in mv88e6xxx_mac_link_down() local
964 int port = dp->index; in mv88e6xxx_mac_link_down()
967 ops = chip->info->ops; in mv88e6xxx_mac_link_down()
969 mv88e6xxx_reg_lock(chip); in mv88e6xxx_mac_link_down()
971 * updated by the switch or if we are using fixed-link mode. in mv88e6xxx_mac_link_down()
973 if ((!mv88e6xxx_port_ppu_updates(chip, port) || in mv88e6xxx_mac_link_down()
974 mode == MLO_AN_FIXED) && ops->port_sync_link) in mv88e6xxx_mac_link_down()
975 err = ops->port_sync_link(chip, port, mode, false); in mv88e6xxx_mac_link_down()
977 if (!err && ops->port_set_speed_duplex) in mv88e6xxx_mac_link_down()
978 err = ops->port_set_speed_duplex(chip, port, SPEED_UNFORCED, in mv88e6xxx_mac_link_down()
980 mv88e6xxx_reg_unlock(chip); in mv88e6xxx_mac_link_down()
983 dev_err(chip->dev, in mv88e6xxx_mac_link_down()
994 struct mv88e6xxx_chip *chip = dp->ds->priv; in mv88e6xxx_mac_link_up() local
996 int port = dp->index; in mv88e6xxx_mac_link_up()
999 ops = chip->info->ops; in mv88e6xxx_mac_link_up()
1001 mv88e6xxx_reg_lock(chip); in mv88e6xxx_mac_link_up()
1003 * automatically updated by the switch or if we are using fixed-link in mv88e6xxx_mac_link_up()
1006 if (!mv88e6xxx_port_ppu_updates(chip, port) || in mv88e6xxx_mac_link_up()
1008 if (ops->port_set_speed_duplex) { in mv88e6xxx_mac_link_up()
1009 err = ops->port_set_speed_duplex(chip, port, in mv88e6xxx_mac_link_up()
1011 if (err && err != -EOPNOTSUPP) in mv88e6xxx_mac_link_up()
1015 if (ops->port_sync_link) in mv88e6xxx_mac_link_up()
1016 err = ops->port_sync_link(chip, port, mode, true); in mv88e6xxx_mac_link_up()
1019 mv88e6xxx_reg_unlock(chip); in mv88e6xxx_mac_link_up()
1021 if (err && err != -EOPNOTSUPP) in mv88e6xxx_mac_link_up()
1022 dev_err(chip->dev, in mv88e6xxx_mac_link_up()
1026 static int mv88e6xxx_stats_snapshot(struct mv88e6xxx_chip *chip, int port) in mv88e6xxx_stats_snapshot() argument
1030 if (!chip->info->ops->stats_snapshot) in mv88e6xxx_stats_snapshot()
1031 return -EOPNOTSUPP; in mv88e6xxx_stats_snapshot()
1033 mv88e6xxx_reg_lock(chip); in mv88e6xxx_stats_snapshot()
1034 err = chip->info->ops->stats_snapshot(chip, port); in mv88e6xxx_stats_snapshot()
1035 mv88e6xxx_reg_unlock(chip); in mv88e6xxx_stats_snapshot()
1114 static uint64_t _mv88e6xxx_get_ethtool_stat(struct mv88e6xxx_chip *chip, in _mv88e6xxx_get_ethtool_stat() argument
1125 switch (s->type) { in _mv88e6xxx_get_ethtool_stat()
1127 err = mv88e6xxx_port_read(chip, port, s->reg, ®); in _mv88e6xxx_get_ethtool_stat()
1132 if (s->size == 4) { in _mv88e6xxx_get_ethtool_stat()
1133 err = mv88e6xxx_port_read(chip, port, s->reg + 1, ®); in _mv88e6xxx_get_ethtool_stat()
1143 reg |= s->reg | histogram; in _mv88e6xxx_get_ethtool_stat()
1144 mv88e6xxx_g1_stats_read(chip, reg, &low); in _mv88e6xxx_get_ethtool_stat()
1145 if (s->size == 8) in _mv88e6xxx_get_ethtool_stat()
1146 mv88e6xxx_g1_stats_read(chip, reg + 1, &high); in _mv88e6xxx_get_ethtool_stat()
1155 static int mv88e6xxx_stats_get_strings(struct mv88e6xxx_chip *chip, in mv88e6xxx_stats_get_strings() argument
1163 if (stat->type & types) { in mv88e6xxx_stats_get_strings()
1164 memcpy(data + j * ETH_GSTRING_LEN, stat->string, in mv88e6xxx_stats_get_strings()
1173 static int mv88e6095_stats_get_strings(struct mv88e6xxx_chip *chip, in mv88e6095_stats_get_strings() argument
1176 return mv88e6xxx_stats_get_strings(chip, data, in mv88e6095_stats_get_strings()
1180 static int mv88e6250_stats_get_strings(struct mv88e6xxx_chip *chip, in mv88e6250_stats_get_strings() argument
1183 return mv88e6xxx_stats_get_strings(chip, data, STATS_TYPE_BANK0); in mv88e6250_stats_get_strings()
1186 static int mv88e6320_stats_get_strings(struct mv88e6xxx_chip *chip, in mv88e6320_stats_get_strings() argument
1189 return mv88e6xxx_stats_get_strings(chip, data, in mv88e6320_stats_get_strings()
1214 struct mv88e6xxx_chip *chip = ds->priv; in mv88e6xxx_get_strings() local
1220 mv88e6xxx_reg_lock(chip); in mv88e6xxx_get_strings()
1222 if (chip->info->ops->stats_get_strings) in mv88e6xxx_get_strings()
1223 count = chip->info->ops->stats_get_strings(chip, data); in mv88e6xxx_get_strings()
1225 if (chip->info->ops->serdes_get_strings) { in mv88e6xxx_get_strings()
1227 count = chip->info->ops->serdes_get_strings(chip, port, data); in mv88e6xxx_get_strings()
1233 mv88e6xxx_reg_unlock(chip); in mv88e6xxx_get_strings()
1236 static int mv88e6xxx_stats_get_sset_count(struct mv88e6xxx_chip *chip, in mv88e6xxx_stats_get_sset_count() argument
1244 if (stat->type & types) in mv88e6xxx_stats_get_sset_count()
1250 static int mv88e6095_stats_get_sset_count(struct mv88e6xxx_chip *chip) in mv88e6095_stats_get_sset_count() argument
1252 return mv88e6xxx_stats_get_sset_count(chip, STATS_TYPE_BANK0 | in mv88e6095_stats_get_sset_count()
1256 static int mv88e6250_stats_get_sset_count(struct mv88e6xxx_chip *chip) in mv88e6250_stats_get_sset_count() argument
1258 return mv88e6xxx_stats_get_sset_count(chip, STATS_TYPE_BANK0); in mv88e6250_stats_get_sset_count()
1261 static int mv88e6320_stats_get_sset_count(struct mv88e6xxx_chip *chip) in mv88e6320_stats_get_sset_count() argument
1263 return mv88e6xxx_stats_get_sset_count(chip, STATS_TYPE_BANK0 | in mv88e6320_stats_get_sset_count()
1269 struct mv88e6xxx_chip *chip = ds->priv; in mv88e6xxx_get_sset_count() local
1276 mv88e6xxx_reg_lock(chip); in mv88e6xxx_get_sset_count()
1277 if (chip->info->ops->stats_get_sset_count) in mv88e6xxx_get_sset_count()
1278 count = chip->info->ops->stats_get_sset_count(chip); in mv88e6xxx_get_sset_count()
1282 if (chip->info->ops->serdes_get_sset_count) in mv88e6xxx_get_sset_count()
1283 serdes_count = chip->info->ops->serdes_get_sset_count(chip, in mv88e6xxx_get_sset_count()
1293 mv88e6xxx_reg_unlock(chip); in mv88e6xxx_get_sset_count()
1298 static size_t mv88e6095_stats_get_stat(struct mv88e6xxx_chip *chip, int port, in mv88e6095_stats_get_stat() argument
1302 if (!(stat->type & (STATS_TYPE_BANK0 | STATS_TYPE_PORT))) in mv88e6095_stats_get_stat()
1305 *data = _mv88e6xxx_get_ethtool_stat(chip, stat, port, 0, in mv88e6095_stats_get_stat()
1310 static size_t mv88e6250_stats_get_stat(struct mv88e6xxx_chip *chip, int port, in mv88e6250_stats_get_stat() argument
1314 if (!(stat->type & STATS_TYPE_BANK0)) in mv88e6250_stats_get_stat()
1317 *data = _mv88e6xxx_get_ethtool_stat(chip, stat, port, 0, in mv88e6250_stats_get_stat()
1322 static size_t mv88e6320_stats_get_stat(struct mv88e6xxx_chip *chip, int port, in mv88e6320_stats_get_stat() argument
1326 if (!(stat->type & (STATS_TYPE_BANK0 | STATS_TYPE_BANK1))) in mv88e6320_stats_get_stat()
1329 *data = _mv88e6xxx_get_ethtool_stat(chip, stat, port, in mv88e6320_stats_get_stat()
1335 static size_t mv88e6390_stats_get_stat(struct mv88e6xxx_chip *chip, int port, in mv88e6390_stats_get_stat() argument
1339 if (!(stat->type & (STATS_TYPE_BANK0 | STATS_TYPE_BANK1))) in mv88e6390_stats_get_stat()
1342 *data = _mv88e6xxx_get_ethtool_stat(chip, stat, port, in mv88e6390_stats_get_stat()
1348 static size_t mv88e6xxx_stats_get_stat(struct mv88e6xxx_chip *chip, int port, in mv88e6xxx_stats_get_stat() argument
1354 if (chip->info->ops->stats_get_stat) { in mv88e6xxx_stats_get_stat()
1355 mv88e6xxx_reg_lock(chip); in mv88e6xxx_stats_get_stat()
1356 ret = chip->info->ops->stats_get_stat(chip, port, stat, data); in mv88e6xxx_stats_get_stat()
1357 mv88e6xxx_reg_unlock(chip); in mv88e6xxx_stats_get_stat()
1363 static size_t mv88e6xxx_stats_get_stats(struct mv88e6xxx_chip *chip, int port, in mv88e6xxx_stats_get_stats() argument
1371 j += mv88e6xxx_stats_get_stat(chip, port, stat, &data[j]); in mv88e6xxx_stats_get_stats()
1376 static void mv88e6xxx_atu_vtu_get_stats(struct mv88e6xxx_chip *chip, int port, in mv88e6xxx_atu_vtu_get_stats() argument
1379 *data++ = chip->ports[port].atu_member_violation; in mv88e6xxx_atu_vtu_get_stats()
1380 *data++ = chip->ports[port].atu_miss_violation; in mv88e6xxx_atu_vtu_get_stats()
1381 *data++ = chip->ports[port].atu_full_violation; in mv88e6xxx_atu_vtu_get_stats()
1382 *data++ = chip->ports[port].vtu_member_violation; in mv88e6xxx_atu_vtu_get_stats()
1383 *data++ = chip->ports[port].vtu_miss_violation; in mv88e6xxx_atu_vtu_get_stats()
1386 static void mv88e6xxx_get_stats(struct mv88e6xxx_chip *chip, int port, in mv88e6xxx_get_stats() argument
1391 count = mv88e6xxx_stats_get_stats(chip, port, data); in mv88e6xxx_get_stats()
1393 mv88e6xxx_reg_lock(chip); in mv88e6xxx_get_stats()
1394 if (chip->info->ops->serdes_get_stats) { in mv88e6xxx_get_stats()
1396 count = chip->info->ops->serdes_get_stats(chip, port, data); in mv88e6xxx_get_stats()
1399 mv88e6xxx_atu_vtu_get_stats(chip, port, data); in mv88e6xxx_get_stats()
1400 mv88e6xxx_reg_unlock(chip); in mv88e6xxx_get_stats()
1406 struct mv88e6xxx_chip *chip = ds->priv; in mv88e6xxx_get_ethtool_stats() local
1409 ret = mv88e6xxx_stats_snapshot(chip, port); in mv88e6xxx_get_ethtool_stats()
1413 mv88e6xxx_get_stats(chip, port, data); in mv88e6xxx_get_ethtool_stats()
1419 struct mv88e6xxx_chip *chip = ds->priv; in mv88e6xxx_get_eth_mac_stats() local
1422 ret = mv88e6xxx_stats_snapshot(chip, port); in mv88e6xxx_get_eth_mac_stats()
1427 mv88e6xxx_stats_get_stat(chip, port, \ in mv88e6xxx_get_eth_mac_stats()
1429 &mac_stats->stats._member) in mv88e6xxx_get_eth_mac_stats()
1448 mac_stats->stats.FramesTransmittedOK += mac_stats->stats.MulticastFramesXmittedOK; in mv88e6xxx_get_eth_mac_stats()
1449 mac_stats->stats.FramesTransmittedOK += mac_stats->stats.BroadcastFramesXmittedOK; in mv88e6xxx_get_eth_mac_stats()
1450 mac_stats->stats.FramesReceivedOK += mac_stats->stats.MulticastFramesReceivedOK; in mv88e6xxx_get_eth_mac_stats()
1451 mac_stats->stats.FramesReceivedOK += mac_stats->stats.BroadcastFramesReceivedOK; in mv88e6xxx_get_eth_mac_stats()
1467 struct mv88e6xxx_chip *chip = ds->priv; in mv88e6xxx_get_rmon_stats() local
1470 ret = mv88e6xxx_stats_snapshot(chip, port); in mv88e6xxx_get_rmon_stats()
1475 mv88e6xxx_stats_get_stat(chip, port, \ in mv88e6xxx_get_rmon_stats()
1477 &rmon_stats->stats._member) in mv88e6xxx_get_rmon_stats()
1497 struct mv88e6xxx_chip *chip = ds->priv; in mv88e6xxx_get_regs_len() local
1501 if (chip->info->ops->serdes_get_regs_len) in mv88e6xxx_get_regs_len()
1502 len += chip->info->ops->serdes_get_regs_len(chip, port); in mv88e6xxx_get_regs_len()
1510 struct mv88e6xxx_chip *chip = ds->priv; in mv88e6xxx_get_regs() local
1516 regs->version = chip->info->prod_num; in mv88e6xxx_get_regs()
1520 mv88e6xxx_reg_lock(chip); in mv88e6xxx_get_regs()
1524 err = mv88e6xxx_port_read(chip, port, i, ®); in mv88e6xxx_get_regs()
1529 if (chip->info->ops->serdes_get_regs) in mv88e6xxx_get_regs()
1530 chip->info->ops->serdes_get_regs(chip, port, &p[i]); in mv88e6xxx_get_regs()
1532 mv88e6xxx_reg_unlock(chip); in mv88e6xxx_get_regs()
1550 static u16 mv88e6xxx_port_vlan(struct mv88e6xxx_chip *chip, int dev, int port) in mv88e6xxx_port_vlan() argument
1552 struct dsa_switch *ds = chip->ds; in mv88e6xxx_port_vlan()
1553 struct dsa_switch_tree *dst = ds->dst; in mv88e6xxx_port_vlan()
1559 if (dev <= dst->last_switch) { in mv88e6xxx_port_vlan()
1560 list_for_each_entry(dp, &dst->ports, list) { in mv88e6xxx_port_vlan()
1561 if (dp->ds->index == dev && dp->index == port) { in mv88e6xxx_port_vlan()
1572 list_for_each_entry(dp, &dst->ports, list) { in mv88e6xxx_port_vlan()
1578 if (bridge_num + dst->last_switch != dev) in mv88e6xxx_port_vlan()
1591 if (dp->type == DSA_PORT_TYPE_CPU || dp->type == DSA_PORT_TYPE_DSA) in mv88e6xxx_port_vlan()
1592 return mv88e6xxx_port_mask(chip); in mv88e6xxx_port_vlan()
1607 if (other_dp->type == DSA_PORT_TYPE_CPU || in mv88e6xxx_port_vlan()
1608 other_dp->type == DSA_PORT_TYPE_DSA || in mv88e6xxx_port_vlan()
1610 pvlan |= BIT(other_dp->index); in mv88e6xxx_port_vlan()
1615 static int mv88e6xxx_port_vlan_map(struct mv88e6xxx_chip *chip, int port) in mv88e6xxx_port_vlan_map() argument
1617 u16 output_ports = mv88e6xxx_port_vlan(chip, chip->ds->index, port); in mv88e6xxx_port_vlan_map()
1622 return mv88e6xxx_port_set_vlan_map(chip, port, output_ports); in mv88e6xxx_port_vlan_map()
1628 struct mv88e6xxx_chip *chip = ds->priv; in mv88e6xxx_port_stp_state_set() local
1631 mv88e6xxx_reg_lock(chip); in mv88e6xxx_port_stp_state_set()
1632 err = mv88e6xxx_port_set_state(chip, port, state); in mv88e6xxx_port_stp_state_set()
1633 mv88e6xxx_reg_unlock(chip); in mv88e6xxx_port_stp_state_set()
1636 dev_err(ds->dev, "p%d: failed to update state\n", port); in mv88e6xxx_port_stp_state_set()
1639 static int mv88e6xxx_pri_setup(struct mv88e6xxx_chip *chip) in mv88e6xxx_pri_setup() argument
1643 if (chip->info->ops->ieee_pri_map) { in mv88e6xxx_pri_setup()
1644 err = chip->info->ops->ieee_pri_map(chip); in mv88e6xxx_pri_setup()
1649 if (chip->info->ops->ip_pri_map) { in mv88e6xxx_pri_setup()
1650 err = chip->info->ops->ip_pri_map(chip); in mv88e6xxx_pri_setup()
1658 static int mv88e6xxx_devmap_setup(struct mv88e6xxx_chip *chip) in mv88e6xxx_devmap_setup() argument
1660 struct dsa_switch *ds = chip->ds; in mv88e6xxx_devmap_setup()
1664 if (!chip->info->global2_addr) in mv88e6xxx_devmap_setup()
1670 if (port == ds->num_ports) in mv88e6xxx_devmap_setup()
1673 err = mv88e6xxx_g2_device_mapping_write(chip, target, port); in mv88e6xxx_devmap_setup()
1678 if (chip->info->ops->set_cascade_port) { in mv88e6xxx_devmap_setup()
1680 err = chip->info->ops->set_cascade_port(chip, port); in mv88e6xxx_devmap_setup()
1685 err = mv88e6xxx_g1_set_device_number(chip, chip->ds->index); in mv88e6xxx_devmap_setup()
1692 static int mv88e6xxx_trunk_setup(struct mv88e6xxx_chip *chip) in mv88e6xxx_trunk_setup() argument
1695 if (chip->info->global2_addr) in mv88e6xxx_trunk_setup()
1696 return mv88e6xxx_g2_trunk_clear(chip); in mv88e6xxx_trunk_setup()
1701 static int mv88e6xxx_rmu_setup(struct mv88e6xxx_chip *chip) in mv88e6xxx_rmu_setup() argument
1703 if (chip->info->ops->rmu_disable) in mv88e6xxx_rmu_setup()
1704 return chip->info->ops->rmu_disable(chip); in mv88e6xxx_rmu_setup()
1709 static int mv88e6xxx_pot_setup(struct mv88e6xxx_chip *chip) in mv88e6xxx_pot_setup() argument
1711 if (chip->info->ops->pot_clear) in mv88e6xxx_pot_setup()
1712 return chip->info->ops->pot_clear(chip); in mv88e6xxx_pot_setup()
1717 static int mv88e6xxx_rsvd2cpu_setup(struct mv88e6xxx_chip *chip) in mv88e6xxx_rsvd2cpu_setup() argument
1719 if (chip->info->ops->mgmt_rsvd2cpu) in mv88e6xxx_rsvd2cpu_setup()
1720 return chip->info->ops->mgmt_rsvd2cpu(chip); in mv88e6xxx_rsvd2cpu_setup()
1725 static int mv88e6xxx_atu_setup(struct mv88e6xxx_chip *chip) in mv88e6xxx_atu_setup() argument
1729 err = mv88e6xxx_g1_atu_flush(chip, 0, true); in mv88e6xxx_atu_setup()
1736 * ->port_setup_message_port. in mv88e6xxx_atu_setup()
1738 if (chip->info->ops->port_setup_message_port) { in mv88e6xxx_atu_setup()
1739 err = mv88e6xxx_g1_atu_set_learn2all(chip, true); in mv88e6xxx_atu_setup()
1744 return mv88e6xxx_g1_atu_set_age_time(chip, 300000); in mv88e6xxx_atu_setup()
1747 static int mv88e6xxx_irl_setup(struct mv88e6xxx_chip *chip) in mv88e6xxx_irl_setup() argument
1752 if (!chip->info->ops->irl_init_all) in mv88e6xxx_irl_setup()
1755 for (port = 0; port < mv88e6xxx_num_ports(chip); port++) { in mv88e6xxx_irl_setup()
1759 err = chip->info->ops->irl_init_all(chip, port); in mv88e6xxx_irl_setup()
1767 static int mv88e6xxx_mac_setup(struct mv88e6xxx_chip *chip) in mv88e6xxx_mac_setup() argument
1769 if (chip->info->ops->set_switch_mac) { in mv88e6xxx_mac_setup()
1774 return chip->info->ops->set_switch_mac(chip, addr); in mv88e6xxx_mac_setup()
1780 static int mv88e6xxx_pvt_map(struct mv88e6xxx_chip *chip, int dev, int port) in mv88e6xxx_pvt_map() argument
1782 struct dsa_switch_tree *dst = chip->ds->dst; in mv88e6xxx_pvt_map()
1787 if (!mv88e6xxx_has_pvt(chip)) in mv88e6xxx_pvt_map()
1790 /* Skip the local source device, which uses in-chip port VLAN */ in mv88e6xxx_pvt_map()
1791 if (dev != chip->ds->index) { in mv88e6xxx_pvt_map()
1792 pvlan = mv88e6xxx_port_vlan(chip, dev, port); in mv88e6xxx_pvt_map()
1794 ds = dsa_switch_find(dst->index, dev); in mv88e6xxx_pvt_map()
1796 if (dp && dp->lag) { in mv88e6xxx_pvt_map()
1801 * the LAG ID (one-based) as the port number in mv88e6xxx_pvt_map()
1802 * (zero-based). in mv88e6xxx_pvt_map()
1805 port = dsa_port_lag_id_get(dp) - 1; in mv88e6xxx_pvt_map()
1809 return mv88e6xxx_g2_pvt_write(chip, dev, port, pvlan); in mv88e6xxx_pvt_map()
1812 static int mv88e6xxx_pvt_setup(struct mv88e6xxx_chip *chip) in mv88e6xxx_pvt_setup() argument
1817 if (!mv88e6xxx_has_pvt(chip)) in mv88e6xxx_pvt_setup()
1823 err = mv88e6xxx_g2_misc_4_bit_port(chip); in mv88e6xxx_pvt_setup()
1829 err = mv88e6xxx_pvt_map(chip, dev, port); in mv88e6xxx_pvt_setup()
1838 static int mv88e6xxx_port_fast_age_fid(struct mv88e6xxx_chip *chip, int port, in mv88e6xxx_port_fast_age_fid() argument
1841 if (dsa_to_port(chip->ds, port)->lag) in mv88e6xxx_port_fast_age_fid()
1842 /* Hardware is incapable of fast-aging a LAG through a in mv88e6xxx_port_fast_age_fid()
1844 * more fancy in place this is a no-op. in mv88e6xxx_port_fast_age_fid()
1846 return -EOPNOTSUPP; in mv88e6xxx_port_fast_age_fid()
1848 return mv88e6xxx_g1_atu_remove(chip, fid, port, false); in mv88e6xxx_port_fast_age_fid()
1853 struct mv88e6xxx_chip *chip = ds->priv; in mv88e6xxx_port_fast_age() local
1856 mv88e6xxx_reg_lock(chip); in mv88e6xxx_port_fast_age()
1857 err = mv88e6xxx_port_fast_age_fid(chip, port, 0); in mv88e6xxx_port_fast_age()
1858 mv88e6xxx_reg_unlock(chip); in mv88e6xxx_port_fast_age()
1861 dev_err(chip->ds->dev, "p%d: failed to flush ATU: %d\n", in mv88e6xxx_port_fast_age()
1865 static int mv88e6xxx_vtu_setup(struct mv88e6xxx_chip *chip) in mv88e6xxx_vtu_setup() argument
1867 if (!mv88e6xxx_max_vid(chip)) in mv88e6xxx_vtu_setup()
1870 return mv88e6xxx_g1_vtu_flush(chip); in mv88e6xxx_vtu_setup()
1873 static int mv88e6xxx_vtu_get(struct mv88e6xxx_chip *chip, u16 vid, in mv88e6xxx_vtu_get() argument
1878 if (!chip->info->ops->vtu_getnext) in mv88e6xxx_vtu_get()
1879 return -EOPNOTSUPP; in mv88e6xxx_vtu_get()
1881 entry->vid = vid ? vid - 1 : mv88e6xxx_max_vid(chip); in mv88e6xxx_vtu_get()
1882 entry->valid = false; in mv88e6xxx_vtu_get()
1884 err = chip->info->ops->vtu_getnext(chip, entry); in mv88e6xxx_vtu_get()
1886 if (entry->vid != vid) in mv88e6xxx_vtu_get()
1887 entry->valid = false; in mv88e6xxx_vtu_get()
1892 int mv88e6xxx_vtu_walk(struct mv88e6xxx_chip *chip, in mv88e6xxx_vtu_walk() argument
1893 int (*cb)(struct mv88e6xxx_chip *chip, in mv88e6xxx_vtu_walk() argument
1899 .vid = mv88e6xxx_max_vid(chip), in mv88e6xxx_vtu_walk()
1904 if (!chip->info->ops->vtu_getnext) in mv88e6xxx_vtu_walk()
1905 return -EOPNOTSUPP; in mv88e6xxx_vtu_walk()
1908 err = chip->info->ops->vtu_getnext(chip, &entry); in mv88e6xxx_vtu_walk()
1915 err = cb(chip, &entry, priv); in mv88e6xxx_vtu_walk()
1918 } while (entry.vid < mv88e6xxx_max_vid(chip)); in mv88e6xxx_vtu_walk()
1923 static int mv88e6xxx_vtu_loadpurge(struct mv88e6xxx_chip *chip, in mv88e6xxx_vtu_loadpurge() argument
1926 if (!chip->info->ops->vtu_loadpurge) in mv88e6xxx_vtu_loadpurge()
1927 return -EOPNOTSUPP; in mv88e6xxx_vtu_loadpurge()
1929 return chip->info->ops->vtu_loadpurge(chip, entry); in mv88e6xxx_vtu_loadpurge()
1932 static int mv88e6xxx_fid_map_vlan(struct mv88e6xxx_chip *chip, in mv88e6xxx_fid_map_vlan() argument
1938 set_bit(entry->fid, fid_bitmap); in mv88e6xxx_fid_map_vlan()
1942 int mv88e6xxx_fid_map(struct mv88e6xxx_chip *chip, unsigned long *fid_bitmap) in mv88e6xxx_fid_map() argument
1949 return mv88e6xxx_vtu_walk(chip, mv88e6xxx_fid_map_vlan, fid_bitmap); in mv88e6xxx_fid_map()
1952 static int mv88e6xxx_atu_new(struct mv88e6xxx_chip *chip, u16 *fid) in mv88e6xxx_atu_new() argument
1957 err = mv88e6xxx_fid_map(chip, fid_bitmap); in mv88e6xxx_atu_new()
1962 if (unlikely(*fid >= mv88e6xxx_num_databases(chip))) in mv88e6xxx_atu_new()
1963 return -ENOSPC; in mv88e6xxx_atu_new()
1966 return mv88e6xxx_g1_atu_flush(chip, *fid, true); in mv88e6xxx_atu_new()
1969 static int mv88e6xxx_stu_loadpurge(struct mv88e6xxx_chip *chip, in mv88e6xxx_stu_loadpurge() argument
1972 if (!chip->info->ops->stu_loadpurge) in mv88e6xxx_stu_loadpurge()
1973 return -EOPNOTSUPP; in mv88e6xxx_stu_loadpurge()
1975 return chip->info->ops->stu_loadpurge(chip, entry); in mv88e6xxx_stu_loadpurge()
1978 static int mv88e6xxx_stu_setup(struct mv88e6xxx_chip *chip) in mv88e6xxx_stu_setup() argument
1985 if (!mv88e6xxx_has_stu(chip)) in mv88e6xxx_stu_setup()
1993 return mv88e6xxx_stu_loadpurge(chip, &stu); in mv88e6xxx_stu_setup()
1996 static int mv88e6xxx_sid_get(struct mv88e6xxx_chip *chip, u8 *sid) in mv88e6xxx_sid_get() argument
2003 list_for_each_entry(mst, &chip->msts, node) in mv88e6xxx_sid_get()
2004 __set_bit(mst->stu.sid, busy); in mv88e6xxx_sid_get()
2008 return (*sid >= mv88e6xxx_max_sid(chip)) ? -ENOSPC : 0; in mv88e6xxx_sid_get()
2011 static int mv88e6xxx_mst_put(struct mv88e6xxx_chip *chip, u8 sid) in mv88e6xxx_mst_put() argument
2019 list_for_each_entry_safe(mst, tmp, &chip->msts, node) { in mv88e6xxx_mst_put()
2020 if (mst->stu.sid != sid) in mv88e6xxx_mst_put()
2023 if (!refcount_dec_and_test(&mst->refcnt)) in mv88e6xxx_mst_put()
2026 mst->stu.valid = false; in mv88e6xxx_mst_put()
2027 err = mv88e6xxx_stu_loadpurge(chip, &mst->stu); in mv88e6xxx_mst_put()
2029 refcount_set(&mst->refcnt, 1); in mv88e6xxx_mst_put()
2033 list_del(&mst->node); in mv88e6xxx_mst_put()
2038 return -ENOENT; in mv88e6xxx_mst_put()
2041 static int mv88e6xxx_mst_get(struct mv88e6xxx_chip *chip, struct net_device *br, in mv88e6xxx_mst_get() argument
2047 if (!mv88e6xxx_has_stu(chip)) { in mv88e6xxx_mst_get()
2048 err = -EOPNOTSUPP; in mv88e6xxx_mst_get()
2057 list_for_each_entry(mst, &chip->msts, node) { in mv88e6xxx_mst_get()
2058 if (mst->br == br && mst->msti == msti) { in mv88e6xxx_mst_get()
2059 refcount_inc(&mst->refcnt); in mv88e6xxx_mst_get()
2060 *sid = mst->stu.sid; in mv88e6xxx_mst_get()
2065 err = mv88e6xxx_sid_get(chip, sid); in mv88e6xxx_mst_get()
2071 err = -ENOMEM; in mv88e6xxx_mst_get()
2075 INIT_LIST_HEAD(&mst->node); in mv88e6xxx_mst_get()
2076 refcount_set(&mst->refcnt, 1); in mv88e6xxx_mst_get()
2077 mst->br = br; in mv88e6xxx_mst_get()
2078 mst->msti = msti; in mv88e6xxx_mst_get()
2079 mst->stu.valid = true; in mv88e6xxx_mst_get()
2080 mst->stu.sid = *sid; in mv88e6xxx_mst_get()
2083 * a STU state of disabled means to go by the port-global in mv88e6xxx_mst_get()
2087 for (i = 0; i < mv88e6xxx_num_ports(chip); i++) in mv88e6xxx_mst_get()
2088 mst->stu.state[i] = dsa_is_user_port(chip->ds, i) ? in mv88e6xxx_mst_get()
2092 err = mv88e6xxx_stu_loadpurge(chip, &mst->stu); in mv88e6xxx_mst_get()
2096 list_add_tail(&mst->node, &chip->msts); in mv88e6xxx_mst_get()
2109 struct mv88e6xxx_chip *chip = ds->priv; in mv88e6xxx_port_mst_state_set() local
2114 if (!mv88e6xxx_has_stu(chip)) in mv88e6xxx_port_mst_state_set()
2115 return -EOPNOTSUPP; in mv88e6xxx_port_mst_state_set()
2117 switch (st->state) { in mv88e6xxx_port_mst_state_set()
2130 return -EINVAL; in mv88e6xxx_port_mst_state_set()
2133 list_for_each_entry(mst, &chip->msts, node) { in mv88e6xxx_port_mst_state_set()
2134 if (mst->br == dsa_port_bridge_dev_get(dp) && in mv88e6xxx_port_mst_state_set()
2135 mst->msti == st->msti) { in mv88e6xxx_port_mst_state_set()
2136 if (mst->stu.state[port] == state) in mv88e6xxx_port_mst_state_set()
2139 mst->stu.state[port] = state; in mv88e6xxx_port_mst_state_set()
2140 mv88e6xxx_reg_lock(chip); in mv88e6xxx_port_mst_state_set()
2141 err = mv88e6xxx_stu_loadpurge(chip, &mst->stu); in mv88e6xxx_port_mst_state_set()
2142 mv88e6xxx_reg_unlock(chip); in mv88e6xxx_port_mst_state_set()
2147 return -ENOENT; in mv88e6xxx_port_mst_state_set()
2154 struct mv88e6xxx_chip *chip = ds->priv; in mv88e6xxx_port_check_hw_vlan() local
2162 err = mv88e6xxx_vtu_get(chip, vid, &vlan); in mv88e6xxx_port_check_hw_vlan()
2172 if (vlan.member[other_dp->index] == in mv88e6xxx_port_check_hw_vlan()
2183 dev_err(ds->dev, "p%d: hw VLAN %d already used by port %d in %s\n", in mv88e6xxx_port_check_hw_vlan()
2184 port, vlan.vid, other_dp->index, netdev_name(other_br)); in mv88e6xxx_port_check_hw_vlan()
2185 return -EOPNOTSUPP; in mv88e6xxx_port_check_hw_vlan()
2191 static int mv88e6xxx_port_commit_pvid(struct mv88e6xxx_chip *chip, int port) in mv88e6xxx_port_commit_pvid() argument
2193 struct dsa_port *dp = dsa_to_port(chip->ds, port); in mv88e6xxx_port_commit_pvid()
2195 struct mv88e6xxx_port *p = &chip->ports[port]; in mv88e6xxx_port_commit_pvid()
2202 pvid = p->bridge_pvid.vid; in mv88e6xxx_port_commit_pvid()
2203 drop_untagged = !p->bridge_pvid.valid; in mv88e6xxx_port_commit_pvid()
2209 err = mv88e6xxx_port_set_pvid(chip, port, pvid); in mv88e6xxx_port_commit_pvid()
2213 return mv88e6xxx_port_drop_untagged(chip, port, drop_untagged); in mv88e6xxx_port_commit_pvid()
2220 struct mv88e6xxx_chip *chip = ds->priv; in mv88e6xxx_port_vlan_filtering() local
2225 if (!mv88e6xxx_max_vid(chip)) in mv88e6xxx_port_vlan_filtering()
2226 return -EOPNOTSUPP; in mv88e6xxx_port_vlan_filtering()
2228 mv88e6xxx_reg_lock(chip); in mv88e6xxx_port_vlan_filtering()
2230 err = mv88e6xxx_port_set_8021q_mode(chip, port, mode); in mv88e6xxx_port_vlan_filtering()
2234 err = mv88e6xxx_port_commit_pvid(chip, port); in mv88e6xxx_port_vlan_filtering()
2239 mv88e6xxx_reg_unlock(chip); in mv88e6xxx_port_vlan_filtering()
2248 struct mv88e6xxx_chip *chip = ds->priv; in mv88e6xxx_port_vlan_prepare() local
2251 if (!mv88e6xxx_max_vid(chip)) in mv88e6xxx_port_vlan_prepare()
2252 return -EOPNOTSUPP; in mv88e6xxx_port_vlan_prepare()
2257 mv88e6xxx_reg_lock(chip); in mv88e6xxx_port_vlan_prepare()
2258 err = mv88e6xxx_port_check_hw_vlan(ds, port, vlan->vid); in mv88e6xxx_port_vlan_prepare()
2259 mv88e6xxx_reg_unlock(chip); in mv88e6xxx_port_vlan_prepare()
2264 static int mv88e6xxx_port_db_load_purge(struct mv88e6xxx_chip *chip, int port, in mv88e6xxx_port_db_load_purge() argument
2278 * VLAN ID into the port's database used for VLAN-unaware bridging. in mv88e6xxx_port_db_load_purge()
2283 err = mv88e6xxx_vtu_get(chip, vid, &vlan); in mv88e6xxx_port_db_load_purge()
2287 /* switchdev expects -EOPNOTSUPP to honor software VLANs */ in mv88e6xxx_port_db_load_purge()
2289 return -EOPNOTSUPP; in mv88e6xxx_port_db_load_purge()
2298 err = mv88e6xxx_g1_atu_getnext(chip, fid, &entry); in mv88e6xxx_port_db_load_purge()
2322 return mv88e6xxx_g1_atu_loadpurge(chip, fid, &entry); in mv88e6xxx_port_db_load_purge()
2325 static int mv88e6xxx_policy_apply(struct mv88e6xxx_chip *chip, int port, in mv88e6xxx_policy_apply() argument
2328 enum mv88e6xxx_policy_mapping mapping = policy->mapping; in mv88e6xxx_policy_apply()
2329 enum mv88e6xxx_policy_action action = policy->action; in mv88e6xxx_policy_apply()
2330 const u8 *addr = policy->addr; in mv88e6xxx_policy_apply()
2331 u16 vid = policy->vid; in mv88e6xxx_policy_apply()
2336 if (!chip->info->ops->port_set_policy) in mv88e6xxx_policy_apply()
2337 return -EOPNOTSUPP; in mv88e6xxx_policy_apply()
2351 return -EOPNOTSUPP; in mv88e6xxx_policy_apply()
2353 err = mv88e6xxx_port_db_load_purge(chip, port, addr, vid, in mv88e6xxx_policy_apply()
2359 return -EOPNOTSUPP; in mv88e6xxx_policy_apply()
2364 idr_for_each_entry(&chip->policies, policy, id) in mv88e6xxx_policy_apply()
2365 if (policy->port == port && in mv88e6xxx_policy_apply()
2366 policy->mapping == mapping && in mv88e6xxx_policy_apply()
2367 policy->action != action) in mv88e6xxx_policy_apply()
2370 return chip->info->ops->port_set_policy(chip, port, mapping, action); in mv88e6xxx_policy_apply()
2373 static int mv88e6xxx_policy_insert(struct mv88e6xxx_chip *chip, int port, in mv88e6xxx_policy_insert() argument
2376 struct ethhdr *mac_entry = &fs->h_u.ether_spec; in mv88e6xxx_policy_insert()
2377 struct ethhdr *mac_mask = &fs->m_u.ether_spec; in mv88e6xxx_policy_insert()
2386 if (fs->location != RX_CLS_LOC_ANY) in mv88e6xxx_policy_insert()
2387 return -EINVAL; in mv88e6xxx_policy_insert()
2389 if (fs->ring_cookie == RX_CLS_FLOW_DISC) in mv88e6xxx_policy_insert()
2392 return -EOPNOTSUPP; in mv88e6xxx_policy_insert()
2394 switch (fs->flow_type & ~FLOW_EXT) { in mv88e6xxx_policy_insert()
2396 if (!is_zero_ether_addr(mac_mask->h_dest) && in mv88e6xxx_policy_insert()
2397 is_zero_ether_addr(mac_mask->h_source)) { in mv88e6xxx_policy_insert()
2399 addr = mac_entry->h_dest; in mv88e6xxx_policy_insert()
2400 } else if (is_zero_ether_addr(mac_mask->h_dest) && in mv88e6xxx_policy_insert()
2401 !is_zero_ether_addr(mac_mask->h_source)) { in mv88e6xxx_policy_insert()
2403 addr = mac_entry->h_source; in mv88e6xxx_policy_insert()
2406 return -EOPNOTSUPP; in mv88e6xxx_policy_insert()
2410 return -EOPNOTSUPP; in mv88e6xxx_policy_insert()
2413 if ((fs->flow_type & FLOW_EXT) && fs->m_ext.vlan_tci) { in mv88e6xxx_policy_insert()
2414 if (fs->m_ext.vlan_tci != htons(0xffff)) in mv88e6xxx_policy_insert()
2415 return -EOPNOTSUPP; in mv88e6xxx_policy_insert()
2416 vid = be16_to_cpu(fs->h_ext.vlan_tci) & VLAN_VID_MASK; in mv88e6xxx_policy_insert()
2419 idr_for_each_entry(&chip->policies, policy, id) { in mv88e6xxx_policy_insert()
2420 if (policy->port == port && policy->mapping == mapping && in mv88e6xxx_policy_insert()
2421 policy->action == action && policy->vid == vid && in mv88e6xxx_policy_insert()
2422 ether_addr_equal(policy->addr, addr)) in mv88e6xxx_policy_insert()
2423 return -EEXIST; in mv88e6xxx_policy_insert()
2426 policy = devm_kzalloc(chip->dev, sizeof(*policy), GFP_KERNEL); in mv88e6xxx_policy_insert()
2428 return -ENOMEM; in mv88e6xxx_policy_insert()
2430 fs->location = 0; in mv88e6xxx_policy_insert()
2431 err = idr_alloc_u32(&chip->policies, policy, &fs->location, 0xffffffff, in mv88e6xxx_policy_insert()
2434 devm_kfree(chip->dev, policy); in mv88e6xxx_policy_insert()
2438 memcpy(&policy->fs, fs, sizeof(*fs)); in mv88e6xxx_policy_insert()
2439 ether_addr_copy(policy->addr, addr); in mv88e6xxx_policy_insert()
2440 policy->mapping = mapping; in mv88e6xxx_policy_insert()
2441 policy->action = action; in mv88e6xxx_policy_insert()
2442 policy->port = port; in mv88e6xxx_policy_insert()
2443 policy->vid = vid; in mv88e6xxx_policy_insert()
2445 err = mv88e6xxx_policy_apply(chip, port, policy); in mv88e6xxx_policy_insert()
2447 idr_remove(&chip->policies, fs->location); in mv88e6xxx_policy_insert()
2448 devm_kfree(chip->dev, policy); in mv88e6xxx_policy_insert()
2458 struct ethtool_rx_flow_spec *fs = &rxnfc->fs; in mv88e6xxx_get_rxnfc()
2459 struct mv88e6xxx_chip *chip = ds->priv; in mv88e6xxx_get_rxnfc() local
2464 mv88e6xxx_reg_lock(chip); in mv88e6xxx_get_rxnfc()
2466 switch (rxnfc->cmd) { in mv88e6xxx_get_rxnfc()
2468 rxnfc->data = 0; in mv88e6xxx_get_rxnfc()
2469 rxnfc->data |= RX_CLS_LOC_SPECIAL; in mv88e6xxx_get_rxnfc()
2470 rxnfc->rule_cnt = 0; in mv88e6xxx_get_rxnfc()
2471 idr_for_each_entry(&chip->policies, policy, id) in mv88e6xxx_get_rxnfc()
2472 if (policy->port == port) in mv88e6xxx_get_rxnfc()
2473 rxnfc->rule_cnt++; in mv88e6xxx_get_rxnfc()
2477 err = -ENOENT; in mv88e6xxx_get_rxnfc()
2478 policy = idr_find(&chip->policies, fs->location); in mv88e6xxx_get_rxnfc()
2480 memcpy(fs, &policy->fs, sizeof(*fs)); in mv88e6xxx_get_rxnfc()
2485 rxnfc->data = 0; in mv88e6xxx_get_rxnfc()
2486 rxnfc->rule_cnt = 0; in mv88e6xxx_get_rxnfc()
2487 idr_for_each_entry(&chip->policies, policy, id) in mv88e6xxx_get_rxnfc()
2488 if (policy->port == port) in mv88e6xxx_get_rxnfc()
2489 rule_locs[rxnfc->rule_cnt++] = id; in mv88e6xxx_get_rxnfc()
2493 err = -EOPNOTSUPP; in mv88e6xxx_get_rxnfc()
2497 mv88e6xxx_reg_unlock(chip); in mv88e6xxx_get_rxnfc()
2505 struct ethtool_rx_flow_spec *fs = &rxnfc->fs; in mv88e6xxx_set_rxnfc()
2506 struct mv88e6xxx_chip *chip = ds->priv; in mv88e6xxx_set_rxnfc() local
2510 mv88e6xxx_reg_lock(chip); in mv88e6xxx_set_rxnfc()
2512 switch (rxnfc->cmd) { in mv88e6xxx_set_rxnfc()
2514 err = mv88e6xxx_policy_insert(chip, port, fs); in mv88e6xxx_set_rxnfc()
2517 err = -ENOENT; in mv88e6xxx_set_rxnfc()
2518 policy = idr_remove(&chip->policies, fs->location); in mv88e6xxx_set_rxnfc()
2520 policy->action = MV88E6XXX_POLICY_ACTION_NORMAL; in mv88e6xxx_set_rxnfc()
2521 err = mv88e6xxx_policy_apply(chip, port, policy); in mv88e6xxx_set_rxnfc()
2522 devm_kfree(chip->dev, policy); in mv88e6xxx_set_rxnfc()
2526 err = -EOPNOTSUPP; in mv88e6xxx_set_rxnfc()
2530 mv88e6xxx_reg_unlock(chip); in mv88e6xxx_set_rxnfc()
2535 static int mv88e6xxx_port_add_broadcast(struct mv88e6xxx_chip *chip, int port, in mv88e6xxx_port_add_broadcast() argument
2543 return mv88e6xxx_port_db_load_purge(chip, port, broadcast, vid, state); in mv88e6xxx_port_add_broadcast()
2546 static int mv88e6xxx_broadcast_setup(struct mv88e6xxx_chip *chip, u16 vid) in mv88e6xxx_broadcast_setup() argument
2551 for (port = 0; port < mv88e6xxx_num_ports(chip); port++) { in mv88e6xxx_broadcast_setup()
2552 struct dsa_port *dp = dsa_to_port(chip->ds, port); in mv88e6xxx_broadcast_setup()
2555 if (dsa_is_unused_port(chip->ds, port)) in mv88e6xxx_broadcast_setup()
2565 err = mv88e6xxx_port_add_broadcast(chip, port, vid); in mv88e6xxx_broadcast_setup()
2579 mv88e6xxx_port_broadcast_sync_vlan(struct mv88e6xxx_chip *chip, in mv88e6xxx_port_broadcast_sync_vlan() argument
2587 if (ctx->flood) in mv88e6xxx_port_broadcast_sync_vlan()
2594 return mv88e6xxx_port_db_load_purge(chip, ctx->port, broadcast, in mv88e6xxx_port_broadcast_sync_vlan()
2595 vlan->vid, state); in mv88e6xxx_port_broadcast_sync_vlan()
2598 static int mv88e6xxx_port_broadcast_sync(struct mv88e6xxx_chip *chip, int port, in mv88e6xxx_port_broadcast_sync() argument
2611 err = mv88e6xxx_port_broadcast_sync_vlan(chip, &vid0, &ctx); in mv88e6xxx_port_broadcast_sync()
2616 return mv88e6xxx_vtu_walk(chip, mv88e6xxx_port_broadcast_sync_vlan, in mv88e6xxx_port_broadcast_sync()
2620 static int mv88e6xxx_port_vlan_join(struct mv88e6xxx_chip *chip, int port, in mv88e6xxx_port_vlan_join() argument
2627 err = mv88e6xxx_vtu_get(chip, vid, &vlan); in mv88e6xxx_port_vlan_join()
2637 err = mv88e6xxx_atu_new(chip, &vlan.fid); in mv88e6xxx_port_vlan_join()
2641 for (i = 0; i < mv88e6xxx_num_ports(chip); ++i) in mv88e6xxx_port_vlan_join()
2650 err = mv88e6xxx_vtu_loadpurge(chip, &vlan); in mv88e6xxx_port_vlan_join()
2654 err = mv88e6xxx_broadcast_setup(chip, vlan.vid); in mv88e6xxx_port_vlan_join()
2660 err = mv88e6xxx_vtu_loadpurge(chip, &vlan); in mv88e6xxx_port_vlan_join()
2664 dev_info(chip->dev, "p%d: already a member of VLAN %d\n", in mv88e6xxx_port_vlan_join()
2675 struct mv88e6xxx_chip *chip = ds->priv; in mv88e6xxx_port_vlan_add() local
2676 bool untagged = vlan->flags & BRIDGE_VLAN_INFO_UNTAGGED; in mv88e6xxx_port_vlan_add()
2677 bool pvid = vlan->flags & BRIDGE_VLAN_INFO_PVID; in mv88e6xxx_port_vlan_add()
2678 struct mv88e6xxx_port *p = &chip->ports[port]; in mv88e6xxx_port_vlan_add()
2683 if (!vlan->vid) in mv88e6xxx_port_vlan_add()
2702 mv88e6xxx_reg_lock(chip); in mv88e6xxx_port_vlan_add()
2704 err = mv88e6xxx_port_vlan_join(chip, port, vlan->vid, member, warn); in mv88e6xxx_port_vlan_add()
2706 dev_err(ds->dev, "p%d: failed to add VLAN %d%c\n", port, in mv88e6xxx_port_vlan_add()
2707 vlan->vid, untagged ? 'u' : 't'); in mv88e6xxx_port_vlan_add()
2712 p->bridge_pvid.vid = vlan->vid; in mv88e6xxx_port_vlan_add()
2713 p->bridge_pvid.valid = true; in mv88e6xxx_port_vlan_add()
2715 err = mv88e6xxx_port_commit_pvid(chip, port); in mv88e6xxx_port_vlan_add()
2718 } else if (vlan->vid && p->bridge_pvid.vid == vlan->vid) { in mv88e6xxx_port_vlan_add()
2719 /* The old pvid was reinstalled as a non-pvid VLAN */ in mv88e6xxx_port_vlan_add()
2720 p->bridge_pvid.valid = false; in mv88e6xxx_port_vlan_add()
2722 err = mv88e6xxx_port_commit_pvid(chip, port); in mv88e6xxx_port_vlan_add()
2728 mv88e6xxx_reg_unlock(chip); in mv88e6xxx_port_vlan_add()
2733 static int mv88e6xxx_port_vlan_leave(struct mv88e6xxx_chip *chip, in mv88e6xxx_port_vlan_leave() argument
2742 err = mv88e6xxx_vtu_get(chip, vid, &vlan); in mv88e6xxx_port_vlan_leave()
2751 return -EOPNOTSUPP; in mv88e6xxx_port_vlan_leave()
2757 for (i = 0; i < mv88e6xxx_num_ports(chip); ++i) { in mv88e6xxx_port_vlan_leave()
2765 err = mv88e6xxx_vtu_loadpurge(chip, &vlan); in mv88e6xxx_port_vlan_leave()
2770 err = mv88e6xxx_mst_put(chip, vlan.sid); in mv88e6xxx_port_vlan_leave()
2775 return mv88e6xxx_g1_atu_remove(chip, vlan.fid, port, false); in mv88e6xxx_port_vlan_leave()
2781 struct mv88e6xxx_chip *chip = ds->priv; in mv88e6xxx_port_vlan_del() local
2782 struct mv88e6xxx_port *p = &chip->ports[port]; in mv88e6xxx_port_vlan_del()
2786 if (!mv88e6xxx_max_vid(chip)) in mv88e6xxx_port_vlan_del()
2787 return -EOPNOTSUPP; in mv88e6xxx_port_vlan_del()
2796 mv88e6xxx_reg_lock(chip); in mv88e6xxx_port_vlan_del()
2798 err = mv88e6xxx_port_get_pvid(chip, port, &pvid); in mv88e6xxx_port_vlan_del()
2802 err = mv88e6xxx_port_vlan_leave(chip, port, vlan->vid); in mv88e6xxx_port_vlan_del()
2806 if (vlan->vid == pvid) { in mv88e6xxx_port_vlan_del()
2807 p->bridge_pvid.valid = false; in mv88e6xxx_port_vlan_del()
2809 err = mv88e6xxx_port_commit_pvid(chip, port); in mv88e6xxx_port_vlan_del()
2815 mv88e6xxx_reg_unlock(chip); in mv88e6xxx_port_vlan_del()
2822 struct mv88e6xxx_chip *chip = ds->priv; in mv88e6xxx_port_vlan_fast_age() local
2826 mv88e6xxx_reg_lock(chip); in mv88e6xxx_port_vlan_fast_age()
2828 err = mv88e6xxx_vtu_get(chip, vid, &vlan); in mv88e6xxx_port_vlan_fast_age()
2832 err = mv88e6xxx_port_fast_age_fid(chip, port, vlan.fid); in mv88e6xxx_port_vlan_fast_age()
2835 mv88e6xxx_reg_unlock(chip); in mv88e6xxx_port_vlan_fast_age()
2844 struct mv88e6xxx_chip *chip = ds->priv; in mv88e6xxx_vlan_msti_set() local
2849 if (!mv88e6xxx_has_stu(chip)) in mv88e6xxx_vlan_msti_set()
2850 return -EOPNOTSUPP; in mv88e6xxx_vlan_msti_set()
2852 mv88e6xxx_reg_lock(chip); in mv88e6xxx_vlan_msti_set()
2854 err = mv88e6xxx_vtu_get(chip, msti->vid, &vlan); in mv88e6xxx_vlan_msti_set()
2859 err = -EINVAL; in mv88e6xxx_vlan_msti_set()
2865 err = mv88e6xxx_mst_get(chip, bridge.dev, msti->msti, &new_sid); in mv88e6xxx_vlan_msti_set()
2872 err = mv88e6xxx_vtu_loadpurge(chip, &vlan); in mv88e6xxx_vlan_msti_set()
2874 mv88e6xxx_mst_put(chip, new_sid); in mv88e6xxx_vlan_msti_set()
2879 err = mv88e6xxx_mst_put(chip, old_sid); in mv88e6xxx_vlan_msti_set()
2882 mv88e6xxx_reg_unlock(chip); in mv88e6xxx_vlan_msti_set()
2890 struct mv88e6xxx_chip *chip = ds->priv; in mv88e6xxx_port_fdb_add() local
2893 mv88e6xxx_reg_lock(chip); in mv88e6xxx_port_fdb_add()
2894 err = mv88e6xxx_port_db_load_purge(chip, port, addr, vid, in mv88e6xxx_port_fdb_add()
2896 mv88e6xxx_reg_unlock(chip); in mv88e6xxx_port_fdb_add()
2905 struct mv88e6xxx_chip *chip = ds->priv; in mv88e6xxx_port_fdb_del() local
2908 mv88e6xxx_reg_lock(chip); in mv88e6xxx_port_fdb_del()
2909 err = mv88e6xxx_port_db_load_purge(chip, port, addr, vid, 0); in mv88e6xxx_port_fdb_del()
2910 mv88e6xxx_reg_unlock(chip); in mv88e6xxx_port_fdb_del()
2915 static int mv88e6xxx_port_db_dump_fid(struct mv88e6xxx_chip *chip, in mv88e6xxx_port_db_dump_fid() argument
2927 err = mv88e6xxx_g1_atu_getnext(chip, fid, &addr); in mv88e6xxx_port_db_dump_fid()
2956 static int mv88e6xxx_port_db_dump_vlan(struct mv88e6xxx_chip *chip, in mv88e6xxx_port_db_dump_vlan() argument
2962 return mv88e6xxx_port_db_dump_fid(chip, entry->fid, entry->vid, in mv88e6xxx_port_db_dump_vlan()
2963 ctx->port, ctx->cb, ctx->data); in mv88e6xxx_port_db_dump_vlan()
2966 static int mv88e6xxx_port_db_dump(struct mv88e6xxx_chip *chip, int port, in mv88e6xxx_port_db_dump() argument
2978 err = mv88e6xxx_port_get_fid(chip, port, &fid); in mv88e6xxx_port_db_dump()
2982 err = mv88e6xxx_port_db_dump_fid(chip, fid, 0, port, cb, data); in mv88e6xxx_port_db_dump()
2986 return mv88e6xxx_vtu_walk(chip, mv88e6xxx_port_db_dump_vlan, &ctx); in mv88e6xxx_port_db_dump()
2992 struct mv88e6xxx_chip *chip = ds->priv; in mv88e6xxx_port_fdb_dump() local
2995 mv88e6xxx_reg_lock(chip); in mv88e6xxx_port_fdb_dump()
2996 err = mv88e6xxx_port_db_dump(chip, port, cb, data); in mv88e6xxx_port_fdb_dump()
2997 mv88e6xxx_reg_unlock(chip); in mv88e6xxx_port_fdb_dump()
3002 static int mv88e6xxx_bridge_map(struct mv88e6xxx_chip *chip, in mv88e6xxx_bridge_map() argument
3005 struct dsa_switch *ds = chip->ds; in mv88e6xxx_bridge_map()
3006 struct dsa_switch_tree *dst = ds->dst; in mv88e6xxx_bridge_map()
3010 list_for_each_entry(dp, &dst->ports, list) { in mv88e6xxx_bridge_map()
3012 if (dp->ds == ds) { in mv88e6xxx_bridge_map()
3016 err = mv88e6xxx_port_vlan_map(chip, dp->index); in mv88e6xxx_bridge_map()
3021 * remap its cross-chip Port VLAN Table entry. in mv88e6xxx_bridge_map()
3023 err = mv88e6xxx_pvt_map(chip, dp->ds->index, in mv88e6xxx_bridge_map()
3024 dp->index); in mv88e6xxx_bridge_map()
3034 /* Treat the software bridge as a virtual single-port switch behind the
3035 * CPU and map in the PVT. First dst->last_switch elements are taken by
3041 u8 dev = bridge_num + ds->dst->last_switch; in mv88e6xxx_map_virtual_bridge_to_pvt()
3042 struct mv88e6xxx_chip *chip = ds->priv; in mv88e6xxx_map_virtual_bridge_to_pvt() local
3044 return mv88e6xxx_pvt_map(chip, dev, 0); in mv88e6xxx_map_virtual_bridge_to_pvt()
3052 struct mv88e6xxx_chip *chip = ds->priv; in mv88e6xxx_port_bridge_join() local
3055 mv88e6xxx_reg_lock(chip); in mv88e6xxx_port_bridge_join()
3057 err = mv88e6xxx_bridge_map(chip, bridge); in mv88e6xxx_port_bridge_join()
3061 err = mv88e6xxx_port_set_map_da(chip, port, true); in mv88e6xxx_port_bridge_join()
3065 err = mv88e6xxx_port_commit_pvid(chip, port); in mv88e6xxx_port_bridge_join()
3069 if (mv88e6xxx_has_pvt(chip)) { in mv88e6xxx_port_bridge_join()
3078 mv88e6xxx_reg_unlock(chip); in mv88e6xxx_port_bridge_join()
3086 struct mv88e6xxx_chip *chip = ds->priv; in mv88e6xxx_port_bridge_leave() local
3089 mv88e6xxx_reg_lock(chip); in mv88e6xxx_port_bridge_leave()
3093 dev_err(ds->dev, "failed to remap cross-chip Port VLAN\n"); in mv88e6xxx_port_bridge_leave()
3095 if (mv88e6xxx_bridge_map(chip, bridge) || in mv88e6xxx_port_bridge_leave()
3096 mv88e6xxx_port_vlan_map(chip, port)) in mv88e6xxx_port_bridge_leave()
3097 dev_err(ds->dev, "failed to remap in-chip Port VLAN\n"); in mv88e6xxx_port_bridge_leave()
3099 err = mv88e6xxx_port_set_map_da(chip, port, false); in mv88e6xxx_port_bridge_leave()
3101 dev_err(ds->dev, in mv88e6xxx_port_bridge_leave()
3102 "port %d failed to restore map-DA: %pe\n", in mv88e6xxx_port_bridge_leave()
3105 err = mv88e6xxx_port_commit_pvid(chip, port); in mv88e6xxx_port_bridge_leave()
3107 dev_err(ds->dev, in mv88e6xxx_port_bridge_leave()
3111 mv88e6xxx_reg_unlock(chip); in mv88e6xxx_port_bridge_leave()
3119 struct mv88e6xxx_chip *chip = ds->priv; in mv88e6xxx_crosschip_bridge_join() local
3122 if (tree_index != ds->dst->index) in mv88e6xxx_crosschip_bridge_join()
3125 mv88e6xxx_reg_lock(chip); in mv88e6xxx_crosschip_bridge_join()
3126 err = mv88e6xxx_pvt_map(chip, sw_index, port); in mv88e6xxx_crosschip_bridge_join()
3128 mv88e6xxx_reg_unlock(chip); in mv88e6xxx_crosschip_bridge_join()
3137 struct mv88e6xxx_chip *chip = ds->priv; in mv88e6xxx_crosschip_bridge_leave() local
3139 if (tree_index != ds->dst->index) in mv88e6xxx_crosschip_bridge_leave()
3142 mv88e6xxx_reg_lock(chip); in mv88e6xxx_crosschip_bridge_leave()
3143 if (mv88e6xxx_pvt_map(chip, sw_index, port) || in mv88e6xxx_crosschip_bridge_leave()
3145 dev_err(ds->dev, "failed to remap cross-chip Port VLAN\n"); in mv88e6xxx_crosschip_bridge_leave()
3146 mv88e6xxx_reg_unlock(chip); in mv88e6xxx_crosschip_bridge_leave()
3149 static int mv88e6xxx_software_reset(struct mv88e6xxx_chip *chip) in mv88e6xxx_software_reset() argument
3151 if (chip->info->ops->reset) in mv88e6xxx_software_reset()
3152 return chip->info->ops->reset(chip); in mv88e6xxx_software_reset()
3157 static void mv88e6xxx_hardware_reset(struct mv88e6xxx_chip *chip) in mv88e6xxx_hardware_reset() argument
3159 struct gpio_desc *gpiod = chip->reset; in mv88e6xxx_hardware_reset()
3162 /* If there is a GPIO connected to the reset pin, toggle it */ in mv88e6xxx_hardware_reset()
3164 /* If the switch has just been reset and not yet completed in mv88e6xxx_hardware_reset()
3165 * loading EEPROM, the reset may interrupt the I2C transaction in mv88e6xxx_hardware_reset()
3166 * mid-byte, causing the first EEPROM read after the reset in mv88e6xxx_hardware_reset()
3170 * generally wait for EEPROM loads to complete as their pre- in mv88e6xxx_hardware_reset()
3171 * and post-reset handlers. in mv88e6xxx_hardware_reset()
3173 if (chip->info->ops->hardware_reset_pre) { in mv88e6xxx_hardware_reset()
3174 err = chip->info->ops->hardware_reset_pre(chip); in mv88e6xxx_hardware_reset()
3176 dev_err(chip->dev, "pre-reset error: %d\n", err); in mv88e6xxx_hardware_reset()
3184 if (chip->info->ops->hardware_reset_post) { in mv88e6xxx_hardware_reset()
3185 err = chip->info->ops->hardware_reset_post(chip); in mv88e6xxx_hardware_reset()
3187 dev_err(chip->dev, "post-reset error: %d\n", err); in mv88e6xxx_hardware_reset()
3192 static int mv88e6xxx_disable_ports(struct mv88e6xxx_chip *chip) in mv88e6xxx_disable_ports() argument
3197 for (i = 0; i < mv88e6xxx_num_ports(chip); i++) { in mv88e6xxx_disable_ports()
3198 err = mv88e6xxx_port_set_state(chip, i, BR_STATE_DISABLED); in mv88e6xxx_disable_ports()
3211 static int mv88e6xxx_switch_reset(struct mv88e6xxx_chip *chip) in mv88e6xxx_switch_reset() argument
3215 err = mv88e6xxx_disable_ports(chip); in mv88e6xxx_switch_reset()
3219 mv88e6xxx_hardware_reset(chip); in mv88e6xxx_switch_reset()
3221 return mv88e6xxx_software_reset(chip); in mv88e6xxx_switch_reset()
3224 static int mv88e6xxx_set_port_mode(struct mv88e6xxx_chip *chip, int port, in mv88e6xxx_set_port_mode() argument
3230 if (!chip->info->ops->port_set_frame_mode) in mv88e6xxx_set_port_mode()
3231 return -EOPNOTSUPP; in mv88e6xxx_set_port_mode()
3233 err = mv88e6xxx_port_set_egress_mode(chip, port, egress); in mv88e6xxx_set_port_mode()
3237 err = chip->info->ops->port_set_frame_mode(chip, port, frame); in mv88e6xxx_set_port_mode()
3241 if (chip->info->ops->port_set_ether_type) in mv88e6xxx_set_port_mode()
3242 return chip->info->ops->port_set_ether_type(chip, port, etype); in mv88e6xxx_set_port_mode()
3247 static int mv88e6xxx_set_port_mode_normal(struct mv88e6xxx_chip *chip, int port) in mv88e6xxx_set_port_mode_normal() argument
3249 return mv88e6xxx_set_port_mode(chip, port, MV88E6XXX_FRAME_MODE_NORMAL, in mv88e6xxx_set_port_mode_normal()
3254 static int mv88e6xxx_set_port_mode_dsa(struct mv88e6xxx_chip *chip, int port) in mv88e6xxx_set_port_mode_dsa() argument
3256 return mv88e6xxx_set_port_mode(chip, port, MV88E6XXX_FRAME_MODE_DSA, in mv88e6xxx_set_port_mode_dsa()
3261 static int mv88e6xxx_set_port_mode_edsa(struct mv88e6xxx_chip *chip, int port) in mv88e6xxx_set_port_mode_edsa() argument
3263 return mv88e6xxx_set_port_mode(chip, port, in mv88e6xxx_set_port_mode_edsa()
3269 static int mv88e6xxx_setup_port_mode(struct mv88e6xxx_chip *chip, int port) in mv88e6xxx_setup_port_mode() argument
3271 if (dsa_is_dsa_port(chip->ds, port)) in mv88e6xxx_setup_port_mode()
3272 return mv88e6xxx_set_port_mode_dsa(chip, port); in mv88e6xxx_setup_port_mode()
3274 if (dsa_is_user_port(chip->ds, port)) in mv88e6xxx_setup_port_mode()
3275 return mv88e6xxx_set_port_mode_normal(chip, port); in mv88e6xxx_setup_port_mode()
3278 if (chip->tag_protocol == DSA_TAG_PROTO_DSA) in mv88e6xxx_setup_port_mode()
3279 return mv88e6xxx_set_port_mode_dsa(chip, port); in mv88e6xxx_setup_port_mode()
3281 if (chip->tag_protocol == DSA_TAG_PROTO_EDSA) in mv88e6xxx_setup_port_mode()
3282 return mv88e6xxx_set_port_mode_edsa(chip, port); in mv88e6xxx_setup_port_mode()
3284 return -EINVAL; in mv88e6xxx_setup_port_mode()
3287 static int mv88e6xxx_setup_message_port(struct mv88e6xxx_chip *chip, int port) in mv88e6xxx_setup_message_port() argument
3289 bool message = dsa_is_dsa_port(chip->ds, port); in mv88e6xxx_setup_message_port()
3291 return mv88e6xxx_port_set_message_port(chip, port, message); in mv88e6xxx_setup_message_port()
3294 static int mv88e6xxx_setup_egress_floods(struct mv88e6xxx_chip *chip, int port) in mv88e6xxx_setup_egress_floods() argument
3298 if (chip->info->ops->port_set_ucast_flood) { in mv88e6xxx_setup_egress_floods()
3299 err = chip->info->ops->port_set_ucast_flood(chip, port, true); in mv88e6xxx_setup_egress_floods()
3303 if (chip->info->ops->port_set_mcast_flood) { in mv88e6xxx_setup_egress_floods()
3304 err = chip->info->ops->port_set_mcast_flood(chip, port, true); in mv88e6xxx_setup_egress_floods()
3312 static int mv88e6xxx_set_egress_port(struct mv88e6xxx_chip *chip, in mv88e6xxx_set_egress_port() argument
3318 if (!chip->info->ops->set_egress_port) in mv88e6xxx_set_egress_port()
3319 return -EOPNOTSUPP; in mv88e6xxx_set_egress_port()
3321 err = chip->info->ops->set_egress_port(chip, direction, port); in mv88e6xxx_set_egress_port()
3326 chip->ingress_dest_port = port; in mv88e6xxx_set_egress_port()
3328 chip->egress_dest_port = port; in mv88e6xxx_set_egress_port()
3333 static int mv88e6xxx_setup_upstream_port(struct mv88e6xxx_chip *chip, int port) in mv88e6xxx_setup_upstream_port() argument
3335 struct dsa_switch *ds = chip->ds; in mv88e6xxx_setup_upstream_port()
3340 if (chip->info->ops->port_set_upstream_port) { in mv88e6xxx_setup_upstream_port()
3341 err = chip->info->ops->port_set_upstream_port(chip, port, in mv88e6xxx_setup_upstream_port()
3348 if (chip->info->ops->set_cpu_port) { in mv88e6xxx_setup_upstream_port()
3349 err = chip->info->ops->set_cpu_port(chip, in mv88e6xxx_setup_upstream_port()
3355 err = mv88e6xxx_set_egress_port(chip, in mv88e6xxx_setup_upstream_port()
3358 if (err && err != -EOPNOTSUPP) in mv88e6xxx_setup_upstream_port()
3361 err = mv88e6xxx_set_egress_port(chip, in mv88e6xxx_setup_upstream_port()
3364 if (err && err != -EOPNOTSUPP) in mv88e6xxx_setup_upstream_port()
3371 static int mv88e6xxx_setup_port(struct mv88e6xxx_chip *chip, int port) in mv88e6xxx_setup_port() argument
3374 struct dsa_switch *ds = chip->ds; in mv88e6xxx_setup_port()
3380 chip->ports[port].chip = chip; in mv88e6xxx_setup_port()
3381 chip->ports[port].port = port; in mv88e6xxx_setup_port()
3383 err = mv88e6xxx_port_setup_mac(chip, port, LINK_UNFORCED, in mv88e6xxx_setup_port()
3389 /* Port Control: disable Drop-on-Unlock, disable Drop-on-Lock, in mv88e6xxx_setup_port()
3411 err = mv88e6xxx_port_write(chip, port, MV88E6XXX_PORT_CTL0, reg); in mv88e6xxx_setup_port()
3415 err = mv88e6xxx_setup_port_mode(chip, port); in mv88e6xxx_setup_port()
3419 err = mv88e6xxx_setup_egress_floods(chip, port); in mv88e6xxx_setup_port()
3430 err = mv88e6xxx_port_set_map_da(chip, port, !dsa_is_user_port(ds, port)); in mv88e6xxx_setup_port()
3434 err = mv88e6xxx_setup_upstream_port(chip, port); in mv88e6xxx_setup_port()
3446 chip->info->ops->port_set_policy) { in mv88e6xxx_setup_port()
3447 err = chip->info->ops->port_set_policy(chip, port, in mv88e6xxx_setup_port()
3456 * loaded in the VTU - therefore, enable 802.1Q in order to take in mv88e6xxx_setup_port()
3459 err = mv88e6xxx_port_set_8021q_mode(chip, port, in mv88e6xxx_setup_port()
3473 err = mv88e6xxx_port_vlan_join(chip, port, MV88E6XXX_VID_STANDALONE, in mv88e6xxx_setup_port()
3482 * as the private PVID on ports under a VLAN-unaware bridge. in mv88e6xxx_setup_port()
3487 err = mv88e6xxx_port_vlan_join(chip, port, MV88E6XXX_VID_BRIDGED, in mv88e6xxx_setup_port()
3493 if (chip->info->ops->port_set_jumbo_size) { in mv88e6xxx_setup_port()
3494 err = chip->info->ops->port_set_jumbo_size(chip, port, 10218); in mv88e6xxx_setup_port()
3514 err = mv88e6xxx_port_write(chip, port, MV88E6XXX_PORT_ASSOC_VECTOR, in mv88e6xxx_setup_port()
3520 err = mv88e6xxx_port_write(chip, port, MV88E6XXX_PORT_EGRESS_RATE_CTL2, in mv88e6xxx_setup_port()
3525 if (chip->info->ops->port_pause_limit) { in mv88e6xxx_setup_port()
3526 err = chip->info->ops->port_pause_limit(chip, port, 0, 0); in mv88e6xxx_setup_port()
3531 if (chip->info->ops->port_disable_learn_limit) { in mv88e6xxx_setup_port()
3532 err = chip->info->ops->port_disable_learn_limit(chip, port); in mv88e6xxx_setup_port()
3537 if (chip->info->ops->port_disable_pri_override) { in mv88e6xxx_setup_port()
3538 err = chip->info->ops->port_disable_pri_override(chip, port); in mv88e6xxx_setup_port()
3543 if (chip->info->ops->port_tag_remap) { in mv88e6xxx_setup_port()
3544 err = chip->info->ops->port_tag_remap(chip, port); in mv88e6xxx_setup_port()
3549 if (chip->info->ops->port_egress_rate_limiting) { in mv88e6xxx_setup_port()
3550 err = chip->info->ops->port_egress_rate_limiting(chip, port); in mv88e6xxx_setup_port()
3555 if (chip->info->ops->port_setup_message_port) { in mv88e6xxx_setup_port()
3556 err = chip->info->ops->port_setup_message_port(chip, port); in mv88e6xxx_setup_port()
3561 if (chip->info->ops->serdes_set_tx_amplitude) { in mv88e6xxx_setup_port()
3564 phy_handle = of_parse_phandle(dp->dn, "phy-handle", 0); in mv88e6xxx_setup_port()
3567 "tx-p2p-microvolt", in mv88e6xxx_setup_port()
3569 err = chip->info->ops->serdes_set_tx_amplitude(chip, in mv88e6xxx_setup_port()
3582 err = mv88e6xxx_port_set_fid(chip, port, MV88E6XXX_FID_STANDALONE); in mv88e6xxx_setup_port()
3586 err = mv88e6xxx_port_vlan_map(chip, port); in mv88e6xxx_setup_port()
3593 return mv88e6xxx_port_write(chip, port, MV88E6XXX_PORT_DEFAULT_VLAN, 0); in mv88e6xxx_setup_port()
3598 struct mv88e6xxx_chip *chip = ds->priv; in mv88e6xxx_get_max_mtu() local
3600 if (chip->info->ops->port_set_jumbo_size) in mv88e6xxx_get_max_mtu()
3601 return 10240 - VLAN_ETH_HLEN - EDSA_HLEN - ETH_FCS_LEN; in mv88e6xxx_get_max_mtu()
3602 else if (chip->info->ops->set_max_frame_size) in mv88e6xxx_get_max_mtu()
3603 return 1632 - VLAN_ETH_HLEN - EDSA_HLEN - ETH_FCS_LEN; in mv88e6xxx_get_max_mtu()
3609 struct mv88e6xxx_chip *chip = ds->priv; in mv88e6xxx_change_mtu() local
3615 if (!chip->info->ops->port_set_jumbo_size && in mv88e6xxx_change_mtu()
3616 !chip->info->ops->set_max_frame_size) { in mv88e6xxx_change_mtu()
3618 return -EINVAL; in mv88e6xxx_change_mtu()
3626 mv88e6xxx_reg_lock(chip); in mv88e6xxx_change_mtu()
3627 if (chip->info->ops->port_set_jumbo_size) in mv88e6xxx_change_mtu()
3628 ret = chip->info->ops->port_set_jumbo_size(chip, port, new_mtu); in mv88e6xxx_change_mtu()
3629 else if (chip->info->ops->set_max_frame_size && in mv88e6xxx_change_mtu()
3631 ret = chip->info->ops->set_max_frame_size(chip, new_mtu); in mv88e6xxx_change_mtu()
3632 mv88e6xxx_reg_unlock(chip); in mv88e6xxx_change_mtu()
3640 struct mv88e6xxx_chip *chip = ds->priv; in mv88e6xxx_set_ageing_time() local
3643 mv88e6xxx_reg_lock(chip); in mv88e6xxx_set_ageing_time()
3644 err = mv88e6xxx_g1_atu_set_age_time(chip, ageing_time); in mv88e6xxx_set_ageing_time()
3645 mv88e6xxx_reg_unlock(chip); in mv88e6xxx_set_ageing_time()
3650 static int mv88e6xxx_stats_setup(struct mv88e6xxx_chip *chip) in mv88e6xxx_stats_setup() argument
3655 if (chip->info->ops->stats_set_histogram) { in mv88e6xxx_stats_setup()
3656 err = chip->info->ops->stats_set_histogram(chip); in mv88e6xxx_stats_setup()
3661 return mv88e6xxx_g1_stats_clear(chip); in mv88e6xxx_stats_setup()
3665 static bool mv88e6390_setup_errata_applied(struct mv88e6xxx_chip *chip) in mv88e6390_setup_errata_applied() argument
3671 for (port = 0; port < mv88e6xxx_num_ports(chip); port++) { in mv88e6390_setup_errata_applied()
3672 err = mv88e6xxx_port_hidden_read(chip, 0xf, port, 0, &val); in mv88e6390_setup_errata_applied()
3674 dev_err(chip->dev, in mv88e6390_setup_errata_applied()
3687 * software reset.
3689 static int mv88e6390_setup_errata(struct mv88e6xxx_chip *chip) in mv88e6390_setup_errata() argument
3694 if (mv88e6390_setup_errata_applied(chip)) in mv88e6390_setup_errata()
3698 for (port = 0; port < mv88e6xxx_num_ports(chip); port++) { in mv88e6390_setup_errata()
3699 err = mv88e6xxx_port_set_state(chip, port, BR_STATE_DISABLED); in mv88e6390_setup_errata()
3704 for (port = 0; port < mv88e6xxx_num_ports(chip); port++) { in mv88e6390_setup_errata()
3705 err = mv88e6xxx_port_hidden_write(chip, 0xf, port, 0, 0x01c0); in mv88e6390_setup_errata()
3710 return mv88e6xxx_software_reset(chip); in mv88e6390_setup_errata()
3722 struct mv88e6xxx_mdio_bus *mdio_bus = bus->priv; in mv88e6xxx_mdio_read()
3723 struct mv88e6xxx_chip *chip = mdio_bus->chip; in mv88e6xxx_mdio_read() local
3728 if (!chip->info->ops->phy_read) in mv88e6xxx_mdio_read()
3729 return -EOPNOTSUPP; in mv88e6xxx_mdio_read()
3731 mv88e6xxx_reg_lock(chip); in mv88e6xxx_mdio_read()
3732 err = chip->info->ops->phy_read(chip, bus, phy, reg, &val); in mv88e6xxx_mdio_read()
3733 mv88e6xxx_reg_unlock(chip); in mv88e6xxx_mdio_read()
3737 chip->info->family < ARRAY_SIZE(family_prod_id_table)) { in mv88e6xxx_mdio_read()
3738 prod_id = family_prod_id_table[chip->info->family]; in mv88e6xxx_mdio_read()
3749 struct mv88e6xxx_mdio_bus *mdio_bus = bus->priv; in mv88e6xxx_mdio_read_c45()
3750 struct mv88e6xxx_chip *chip = mdio_bus->chip; in mv88e6xxx_mdio_read_c45() local
3754 if (!chip->info->ops->phy_read_c45) in mv88e6xxx_mdio_read_c45()
3755 return -ENODEV; in mv88e6xxx_mdio_read_c45()
3757 mv88e6xxx_reg_lock(chip); in mv88e6xxx_mdio_read_c45()
3758 err = chip->info->ops->phy_read_c45(chip, bus, phy, devad, reg, &val); in mv88e6xxx_mdio_read_c45()
3759 mv88e6xxx_reg_unlock(chip); in mv88e6xxx_mdio_read_c45()
3766 struct mv88e6xxx_mdio_bus *mdio_bus = bus->priv; in mv88e6xxx_mdio_write()
3767 struct mv88e6xxx_chip *chip = mdio_bus->chip; in mv88e6xxx_mdio_write() local
3770 if (!chip->info->ops->phy_write) in mv88e6xxx_mdio_write()
3771 return -EOPNOTSUPP; in mv88e6xxx_mdio_write()
3773 mv88e6xxx_reg_lock(chip); in mv88e6xxx_mdio_write()
3774 err = chip->info->ops->phy_write(chip, bus, phy, reg, val); in mv88e6xxx_mdio_write()
3775 mv88e6xxx_reg_unlock(chip); in mv88e6xxx_mdio_write()
3783 struct mv88e6xxx_mdio_bus *mdio_bus = bus->priv; in mv88e6xxx_mdio_write_c45()
3784 struct mv88e6xxx_chip *chip = mdio_bus->chip; in mv88e6xxx_mdio_write_c45() local
3787 if (!chip->info->ops->phy_write_c45) in mv88e6xxx_mdio_write_c45()
3788 return -EOPNOTSUPP; in mv88e6xxx_mdio_write_c45()
3790 mv88e6xxx_reg_lock(chip); in mv88e6xxx_mdio_write_c45()
3791 err = chip->info->ops->phy_write_c45(chip, bus, phy, devad, reg, val); in mv88e6xxx_mdio_write_c45()
3792 mv88e6xxx_reg_unlock(chip); in mv88e6xxx_mdio_write_c45()
3797 static int mv88e6xxx_mdio_register(struct mv88e6xxx_chip *chip, in mv88e6xxx_mdio_register() argument
3807 mv88e6xxx_reg_lock(chip); in mv88e6xxx_mdio_register()
3808 if (chip->info->family == MV88E6XXX_FAMILY_6393) in mv88e6xxx_mdio_register()
3809 err = mv88e6393x_g2_scratch_gpio_set_smi(chip, true); in mv88e6xxx_mdio_register()
3811 err = mv88e6390_g2_scratch_gpio_set_smi(chip, true); in mv88e6xxx_mdio_register()
3812 mv88e6xxx_reg_unlock(chip); in mv88e6xxx_mdio_register()
3820 return -ENOMEM; in mv88e6xxx_mdio_register()
3822 mdio_bus = bus->priv; in mv88e6xxx_mdio_register()
3823 mdio_bus->bus = bus; in mv88e6xxx_mdio_register()
3824 mdio_bus->chip = chip; in mv88e6xxx_mdio_register()
3825 INIT_LIST_HEAD(&mdio_bus->list); in mv88e6xxx_mdio_register()
3826 mdio_bus->external = external; in mv88e6xxx_mdio_register()
3829 bus->name = np->full_name; in mv88e6xxx_mdio_register()
3830 snprintf(bus->id, MII_BUS_ID_SIZE, "%pOF", np); in mv88e6xxx_mdio_register()
3832 bus->name = "mv88e6xxx SMI"; in mv88e6xxx_mdio_register()
3833 snprintf(bus->id, MII_BUS_ID_SIZE, "mv88e6xxx-%d", index++); in mv88e6xxx_mdio_register()
3836 bus->read = mv88e6xxx_mdio_read; in mv88e6xxx_mdio_register()
3837 bus->write = mv88e6xxx_mdio_write; in mv88e6xxx_mdio_register()
3838 bus->read_c45 = mv88e6xxx_mdio_read_c45; in mv88e6xxx_mdio_register()
3839 bus->write_c45 = mv88e6xxx_mdio_write_c45; in mv88e6xxx_mdio_register()
3840 bus->parent = chip->dev; in mv88e6xxx_mdio_register()
3841 bus->phy_mask = ~GENMASK(chip->info->phy_base_addr + in mv88e6xxx_mdio_register()
3842 mv88e6xxx_num_ports(chip) - 1, in mv88e6xxx_mdio_register()
3843 chip->info->phy_base_addr); in mv88e6xxx_mdio_register()
3846 err = mv88e6xxx_g2_irq_mdio_setup(chip, bus); in mv88e6xxx_mdio_register()
3853 dev_err(chip->dev, "Cannot register MDIO bus (%d)\n", err); in mv88e6xxx_mdio_register()
3854 mv88e6xxx_g2_irq_mdio_free(chip, bus); in mv88e6xxx_mdio_register()
3859 list_add_tail(&mdio_bus->list, &chip->mdios); in mv88e6xxx_mdio_register()
3861 list_add(&mdio_bus->list, &chip->mdios); in mv88e6xxx_mdio_register()
3870 static void mv88e6xxx_mdios_unregister(struct mv88e6xxx_chip *chip) in mv88e6xxx_mdios_unregister() argument
3876 list_for_each_entry_safe(mdio_bus, p, &chip->mdios, list) { in mv88e6xxx_mdios_unregister()
3877 bus = mdio_bus->bus; in mv88e6xxx_mdios_unregister()
3879 if (!mdio_bus->external) in mv88e6xxx_mdios_unregister()
3880 mv88e6xxx_g2_irq_mdio_free(chip, bus); in mv88e6xxx_mdios_unregister()
3887 static int mv88e6xxx_mdios_register(struct mv88e6xxx_chip *chip) in mv88e6xxx_mdios_register() argument
3889 struct device_node *np = chip->dev->of_node; in mv88e6xxx_mdios_register()
3898 err = mv88e6xxx_mdio_register(chip, child, false); in mv88e6xxx_mdios_register()
3909 child, "marvell,mv88e6xxx-mdio-external")) { in mv88e6xxx_mdios_register()
3910 err = mv88e6xxx_mdio_register(chip, child, true); in mv88e6xxx_mdios_register()
3912 mv88e6xxx_mdios_unregister(chip); in mv88e6xxx_mdios_register()
3924 struct mv88e6xxx_chip *chip = ds->priv; in mv88e6xxx_teardown() local
3929 mv88e6xxx_mdios_unregister(chip); in mv88e6xxx_teardown()
3934 struct mv88e6xxx_chip *chip = ds->priv; in mv88e6xxx_setup() local
3939 err = mv88e6xxx_mdios_register(chip); in mv88e6xxx_setup()
3943 chip->ds = ds; in mv88e6xxx_setup()
3944 ds->user_mii_bus = mv88e6xxx_default_mdio_bus(chip); in mv88e6xxx_setup()
3951 if (mv88e6xxx_has_pvt(chip)) in mv88e6xxx_setup()
3952 ds->max_num_bridges = MV88E6XXX_MAX_PVT_SWITCHES - in mv88e6xxx_setup()
3953 ds->dst->last_switch - 1; in mv88e6xxx_setup()
3955 mv88e6xxx_reg_lock(chip); in mv88e6xxx_setup()
3957 if (chip->info->ops->setup_errata) { in mv88e6xxx_setup()
3958 err = chip->info->ops->setup_errata(chip); in mv88e6xxx_setup()
3964 for (i = 0; i < mv88e6xxx_num_ports(chip); i++) { in mv88e6xxx_setup()
3965 if (chip->info->ops->port_get_cmode) { in mv88e6xxx_setup()
3966 err = chip->info->ops->port_get_cmode(chip, i, &cmode); in mv88e6xxx_setup()
3970 chip->ports[i].cmode = cmode; in mv88e6xxx_setup()
3974 err = mv88e6xxx_vtu_setup(chip); in mv88e6xxx_setup()
3981 err = mv88e6xxx_stu_setup(chip); in mv88e6xxx_setup()
3986 for (i = 0; i < mv88e6xxx_num_ports(chip); i++) { in mv88e6xxx_setup()
3991 if (mv88e6xxx_is_invalid_port(chip, i)) { in mv88e6xxx_setup()
3992 dev_err(chip->dev, "port %d is invalid\n", i); in mv88e6xxx_setup()
3993 err = -EINVAL; in mv88e6xxx_setup()
3997 err = mv88e6xxx_setup_port(chip, i); in mv88e6xxx_setup()
4002 err = mv88e6xxx_irl_setup(chip); in mv88e6xxx_setup()
4006 err = mv88e6xxx_mac_setup(chip); in mv88e6xxx_setup()
4010 err = mv88e6xxx_phy_setup(chip); in mv88e6xxx_setup()
4014 err = mv88e6xxx_pvt_setup(chip); in mv88e6xxx_setup()
4018 err = mv88e6xxx_atu_setup(chip); in mv88e6xxx_setup()
4022 err = mv88e6xxx_broadcast_setup(chip, 0); in mv88e6xxx_setup()
4026 err = mv88e6xxx_pot_setup(chip); in mv88e6xxx_setup()
4030 err = mv88e6xxx_rmu_setup(chip); in mv88e6xxx_setup()
4034 err = mv88e6xxx_rsvd2cpu_setup(chip); in mv88e6xxx_setup()
4038 err = mv88e6xxx_trunk_setup(chip); in mv88e6xxx_setup()
4042 err = mv88e6xxx_devmap_setup(chip); in mv88e6xxx_setup()
4046 err = mv88e6xxx_pri_setup(chip); in mv88e6xxx_setup()
4051 if (chip->info->ptp_support) { in mv88e6xxx_setup()
4052 err = mv88e6xxx_ptp_setup(chip); in mv88e6xxx_setup()
4056 err = mv88e6xxx_hwtstamp_setup(chip); in mv88e6xxx_setup()
4061 err = mv88e6xxx_stats_setup(chip); in mv88e6xxx_setup()
4066 mv88e6xxx_reg_unlock(chip); in mv88e6xxx_setup()
4095 mv88e6xxx_mdios_unregister(chip); in mv88e6xxx_setup()
4102 struct mv88e6xxx_chip *chip = ds->priv; in mv88e6xxx_port_setup() local
4105 if (chip->info->ops->pcs_ops && in mv88e6xxx_port_setup()
4106 chip->info->ops->pcs_ops->pcs_init) { in mv88e6xxx_port_setup()
4107 err = chip->info->ops->pcs_ops->pcs_init(chip, port); in mv88e6xxx_port_setup()
4117 struct mv88e6xxx_chip *chip = ds->priv; in mv88e6xxx_port_teardown() local
4121 if (chip->info->ops->pcs_ops && in mv88e6xxx_port_teardown()
4122 chip->info->ops->pcs_ops->pcs_teardown) in mv88e6xxx_port_teardown()
4123 chip->info->ops->pcs_ops->pcs_teardown(chip, port); in mv88e6xxx_port_teardown()
4128 struct mv88e6xxx_chip *chip = ds->priv; in mv88e6xxx_get_eeprom_len() local
4130 return chip->eeprom_len; in mv88e6xxx_get_eeprom_len()
4136 struct mv88e6xxx_chip *chip = ds->priv; in mv88e6xxx_get_eeprom() local
4139 if (!chip->info->ops->get_eeprom) in mv88e6xxx_get_eeprom()
4140 return -EOPNOTSUPP; in mv88e6xxx_get_eeprom()
4142 mv88e6xxx_reg_lock(chip); in mv88e6xxx_get_eeprom()
4143 err = chip->info->ops->get_eeprom(chip, eeprom, data); in mv88e6xxx_get_eeprom()
4144 mv88e6xxx_reg_unlock(chip); in mv88e6xxx_get_eeprom()
4149 eeprom->magic = 0xc3ec4951; in mv88e6xxx_get_eeprom()
4157 struct mv88e6xxx_chip *chip = ds->priv; in mv88e6xxx_set_eeprom() local
4160 if (!chip->info->ops->set_eeprom) in mv88e6xxx_set_eeprom()
4161 return -EOPNOTSUPP; in mv88e6xxx_set_eeprom()
4163 if (eeprom->magic != 0xc3ec4951) in mv88e6xxx_set_eeprom()
4164 return -EINVAL; in mv88e6xxx_set_eeprom()
4166 mv88e6xxx_reg_lock(chip); in mv88e6xxx_set_eeprom()
4167 err = chip->info->ops->set_eeprom(chip, eeprom, data); in mv88e6xxx_set_eeprom()
4168 mv88e6xxx_reg_unlock(chip); in mv88e6xxx_set_eeprom()
4208 .reset = mv88e6185_g1_reset,
4242 .reset = mv88e6185_g1_reset,
4286 .reset = mv88e6352_g1_reset,
4327 .reset = mv88e6352_g1_reset,
4372 .reset = mv88e6185_g1_reset,
4421 .reset = mv88e6352_g1_reset,
4476 .reset = mv88e6352_g1_reset,
4514 .reset = mv88e6352_g1_reset,
4562 .reset = mv88e6352_g1_reset,
4613 .reset = mv88e6352_g1_reset,
4664 .reset = mv88e6352_g1_reset,
4715 .reset = mv88e6352_g1_reset,
4762 .reset = mv88e6185_g1_reset,
4811 .reset = mv88e6352_g1_reset,
4871 .reset = mv88e6352_g1_reset,
4929 .reset = mv88e6352_g1_reset,
4990 .reset = mv88e6352_g1_reset,
5045 .reset = mv88e6250_g1_reset,
5094 .reset = mv88e6352_g1_reset,
5155 .reset = mv88e6352_g1_reset,
5203 .reset = mv88e6352_g1_reset,
5255 .reset = mv88e6352_g1_reset,
5313 .reset = mv88e6352_g1_reset,
5359 .reset = mv88e6352_g1_reset,
5412 .reset = mv88e6352_g1_reset,
5476 .reset = mv88e6352_g1_reset,
5540 .reset = mv88e6352_g1_reset,
5607 .reset = mv88e6352_g1_reset,
5631 /* Ports 2-4 are not routed to pins
6100 /* Ports 2-4 are not routed to pins
6452 static int mv88e6xxx_detect(struct mv88e6xxx_chip *chip) in mv88e6xxx_detect() argument
6459 mv88e6xxx_reg_lock(chip); in mv88e6xxx_detect()
6460 err = mv88e6xxx_port_read(chip, 0, MV88E6XXX_PORT_SWITCH_ID, &id); in mv88e6xxx_detect()
6461 mv88e6xxx_reg_unlock(chip); in mv88e6xxx_detect()
6470 return -ENODEV; in mv88e6xxx_detect()
6473 chip->info = info; in mv88e6xxx_detect()
6475 dev_info(chip->dev, "switch 0x%x detected: %s, revision %u\n", in mv88e6xxx_detect()
6476 chip->info->prod_num, chip->info->name, rev); in mv88e6xxx_detect()
6481 static int mv88e6xxx_single_chip_detect(struct mv88e6xxx_chip *chip, in mv88e6xxx_single_chip_detect() argument
6486 /* dual_chip takes precedence over single/multi-chip modes */ in mv88e6xxx_single_chip_detect()
6487 if (chip->info->dual_chip) in mv88e6xxx_single_chip_detect()
6488 return -EINVAL; in mv88e6xxx_single_chip_detect()
6491 * (e.g. mv88e6*41) in single chip addressing mode the device may be in mv88e6xxx_single_chip_detect()
6492 * configured in single chip addressing mode. Setup the smi access as in mv88e6xxx_single_chip_detect()
6493 * single chip addressing mode and attempt to detect the model of the in mv88e6xxx_single_chip_detect()
6494 * switch, if this fails the device is not configured in single chip in mv88e6xxx_single_chip_detect()
6497 if (mdiodev->addr != 16) in mv88e6xxx_single_chip_detect()
6498 return -EINVAL; in mv88e6xxx_single_chip_detect()
6500 err = mv88e6xxx_smi_init(chip, mdiodev->bus, 0); in mv88e6xxx_single_chip_detect()
6504 return mv88e6xxx_detect(chip); in mv88e6xxx_single_chip_detect()
6509 struct mv88e6xxx_chip *chip; in mv88e6xxx_alloc_chip() local
6511 chip = devm_kzalloc(dev, sizeof(*chip), GFP_KERNEL); in mv88e6xxx_alloc_chip()
6512 if (!chip) in mv88e6xxx_alloc_chip()
6515 chip->dev = dev; in mv88e6xxx_alloc_chip()
6517 mutex_init(&chip->reg_lock); in mv88e6xxx_alloc_chip()
6518 INIT_LIST_HEAD(&chip->mdios); in mv88e6xxx_alloc_chip()
6519 idr_init(&chip->policies); in mv88e6xxx_alloc_chip()
6520 INIT_LIST_HEAD(&chip->msts); in mv88e6xxx_alloc_chip()
6522 return chip; in mv88e6xxx_alloc_chip()
6529 struct mv88e6xxx_chip *chip = ds->priv; in mv88e6xxx_get_tag_protocol() local
6531 return chip->tag_protocol; in mv88e6xxx_get_tag_protocol()
6537 struct mv88e6xxx_chip *chip = ds->priv; in mv88e6xxx_change_tag_protocol() local
6544 switch (chip->info->edsa_support) { in mv88e6xxx_change_tag_protocol()
6546 return -EPROTONOSUPPORT; in mv88e6xxx_change_tag_protocol()
6548 dev_warn(chip->dev, "Relying on undocumented EDSA tagging behavior\n"); in mv88e6xxx_change_tag_protocol()
6557 return -EPROTONOSUPPORT; in mv88e6xxx_change_tag_protocol()
6560 old_protocol = chip->tag_protocol; in mv88e6xxx_change_tag_protocol()
6561 chip->tag_protocol = proto; in mv88e6xxx_change_tag_protocol()
6563 mv88e6xxx_reg_lock(chip); in mv88e6xxx_change_tag_protocol()
6565 err = mv88e6xxx_setup_port_mode(chip, cpu_dp->index); in mv88e6xxx_change_tag_protocol()
6567 mv88e6xxx_reg_unlock(chip); in mv88e6xxx_change_tag_protocol()
6571 mv88e6xxx_reg_unlock(chip); in mv88e6xxx_change_tag_protocol()
6576 chip->tag_protocol = old_protocol; in mv88e6xxx_change_tag_protocol()
6578 mv88e6xxx_reg_lock(chip); in mv88e6xxx_change_tag_protocol()
6580 mv88e6xxx_setup_port_mode(chip, cpu_dp->index); in mv88e6xxx_change_tag_protocol()
6581 mv88e6xxx_reg_unlock(chip); in mv88e6xxx_change_tag_protocol()
6590 struct mv88e6xxx_chip *chip = ds->priv; in mv88e6xxx_port_mdb_add() local
6593 mv88e6xxx_reg_lock(chip); in mv88e6xxx_port_mdb_add()
6594 err = mv88e6xxx_port_db_load_purge(chip, port, mdb->addr, mdb->vid, in mv88e6xxx_port_mdb_add()
6596 mv88e6xxx_reg_unlock(chip); in mv88e6xxx_port_mdb_add()
6605 struct mv88e6xxx_chip *chip = ds->priv; in mv88e6xxx_port_mdb_del() local
6608 mv88e6xxx_reg_lock(chip); in mv88e6xxx_port_mdb_del()
6609 err = mv88e6xxx_port_db_load_purge(chip, port, mdb->addr, mdb->vid, 0); in mv88e6xxx_port_mdb_del()
6610 mv88e6xxx_reg_unlock(chip); in mv88e6xxx_port_mdb_del()
6623 struct mv88e6xxx_chip *chip = ds->priv; in mv88e6xxx_port_mirror_add() local
6628 mutex_lock(&chip->reg_lock); in mv88e6xxx_port_mirror_add()
6629 if ((ingress ? chip->ingress_dest_port : chip->egress_dest_port) != in mv88e6xxx_port_mirror_add()
6630 mirror->to_local_port) { in mv88e6xxx_port_mirror_add()
6631 for (i = 0; i < mv88e6xxx_num_ports(chip); i++) in mv88e6xxx_port_mirror_add()
6633 chip->ports[i].mirror_ingress : in mv88e6xxx_port_mirror_add()
6634 chip->ports[i].mirror_egress; in mv88e6xxx_port_mirror_add()
6638 err = -EBUSY; in mv88e6xxx_port_mirror_add()
6642 err = mv88e6xxx_set_egress_port(chip, direction, in mv88e6xxx_port_mirror_add()
6643 mirror->to_local_port); in mv88e6xxx_port_mirror_add()
6648 err = mv88e6xxx_port_set_mirror(chip, port, direction, true); in mv88e6xxx_port_mirror_add()
6650 mutex_unlock(&chip->reg_lock); in mv88e6xxx_port_mirror_add()
6658 enum mv88e6xxx_egress_direction direction = mirror->ingress ? in mv88e6xxx_port_mirror_del()
6661 struct mv88e6xxx_chip *chip = ds->priv; in mv88e6xxx_port_mirror_del() local
6665 mutex_lock(&chip->reg_lock); in mv88e6xxx_port_mirror_del()
6666 if (mv88e6xxx_port_set_mirror(chip, port, direction, false)) in mv88e6xxx_port_mirror_del()
6667 dev_err(ds->dev, "p%d: failed to disable mirroring\n", port); in mv88e6xxx_port_mirror_del()
6669 for (i = 0; i < mv88e6xxx_num_ports(chip); i++) in mv88e6xxx_port_mirror_del()
6670 other_mirrors |= mirror->ingress ? in mv88e6xxx_port_mirror_del()
6671 chip->ports[i].mirror_ingress : in mv88e6xxx_port_mirror_del()
6672 chip->ports[i].mirror_egress; in mv88e6xxx_port_mirror_del()
6674 /* Reset egress port when no other mirror is active */ in mv88e6xxx_port_mirror_del()
6676 if (mv88e6xxx_set_egress_port(chip, direction, in mv88e6xxx_port_mirror_del()
6678 dev_err(ds->dev, "failed to set egress port\n"); in mv88e6xxx_port_mirror_del()
6681 mutex_unlock(&chip->reg_lock); in mv88e6xxx_port_mirror_del()
6688 struct mv88e6xxx_chip *chip = ds->priv; in mv88e6xxx_port_pre_bridge_flags() local
6693 return -EINVAL; in mv88e6xxx_port_pre_bridge_flags()
6695 ops = chip->info->ops; in mv88e6xxx_port_pre_bridge_flags()
6697 if ((flags.mask & BR_FLOOD) && !ops->port_set_ucast_flood) in mv88e6xxx_port_pre_bridge_flags()
6698 return -EINVAL; in mv88e6xxx_port_pre_bridge_flags()
6700 if ((flags.mask & BR_MCAST_FLOOD) && !ops->port_set_mcast_flood) in mv88e6xxx_port_pre_bridge_flags()
6701 return -EINVAL; in mv88e6xxx_port_pre_bridge_flags()
6710 struct mv88e6xxx_chip *chip = ds->priv; in mv88e6xxx_port_bridge_flags() local
6713 mv88e6xxx_reg_lock(chip); in mv88e6xxx_port_bridge_flags()
6719 err = mv88e6xxx_port_set_assoc_vector(chip, port, pav); in mv88e6xxx_port_bridge_flags()
6727 err = chip->info->ops->port_set_ucast_flood(chip, port, in mv88e6xxx_port_bridge_flags()
6736 err = chip->info->ops->port_set_mcast_flood(chip, port, in mv88e6xxx_port_bridge_flags()
6745 err = mv88e6xxx_port_broadcast_sync(chip, port, broadcast); in mv88e6xxx_port_bridge_flags()
6753 mv88e6xxx_port_set_mab(chip, port, mab); in mv88e6xxx_port_bridge_flags()
6759 err = mv88e6xxx_port_set_lock(chip, port, locked); in mv88e6xxx_port_bridge_flags()
6764 mv88e6xxx_reg_unlock(chip); in mv88e6xxx_port_bridge_flags()
6774 struct mv88e6xxx_chip *chip = ds->priv; in mv88e6xxx_lag_can_offload() local
6778 if (!mv88e6xxx_has_lag(chip)) { in mv88e6xxx_lag_can_offload()
6779 NL_SET_ERR_MSG_MOD(extack, "Chip does not support LAG offload"); in mv88e6xxx_lag_can_offload()
6786 dsa_lag_foreach_port(dp, ds->dst, &lag) in mv88e6xxx_lag_can_offload()
6799 if (info->tx_type != NETDEV_LAG_TX_TYPE_HASH) { in mv88e6xxx_lag_can_offload()
6814 struct mv88e6xxx_chip *chip = ds->priv; in mv88e6xxx_lag_sync_map() local
6819 /* DSA LAG IDs are one-based, hardware is zero-based */ in mv88e6xxx_lag_sync_map()
6820 id = lag.id - 1; in mv88e6xxx_lag_sync_map()
6824 * port if the LAG port is on a remote chip. in mv88e6xxx_lag_sync_map()
6826 dsa_lag_foreach_port(dp, ds->dst, &lag) in mv88e6xxx_lag_sync_map()
6827 map |= BIT(dsa_towards_port(ds, dp->ds->index, dp->index)); in mv88e6xxx_lag_sync_map()
6829 return mv88e6xxx_g2_trunk_mapping_write(chip, id, map); in mv88e6xxx_lag_sync_map()
6859 active = mv88e6xxx_lag_mask_table[num_tx - 1][nth]; in mv88e6xxx_lag_set_port_mask()
6869 struct mv88e6xxx_chip *chip = ds->priv; in mv88e6xxx_lag_sync_masks() local
6878 ivec = BIT(mv88e6xxx_num_ports(chip)) - 1; in mv88e6xxx_lag_sync_masks()
6882 if (!dp->lag) in mv88e6xxx_lag_sync_masks()
6885 ivec &= ~BIT(dp->index); in mv88e6xxx_lag_sync_masks()
6894 dsa_lags_foreach_id(id, ds->dst) { in mv88e6xxx_lag_sync_masks()
6895 lag = dsa_lag_by_id(ds->dst, id); in mv88e6xxx_lag_sync_masks()
6900 dsa_lag_foreach_port(dp, ds->dst, lag) { in mv88e6xxx_lag_sync_masks()
6901 if (dp->lag_tx_enabled) in mv88e6xxx_lag_sync_masks()
6909 dsa_lag_foreach_port(dp, ds->dst, lag) { in mv88e6xxx_lag_sync_masks()
6910 if (!dp->lag_tx_enabled) in mv88e6xxx_lag_sync_masks()
6913 if (dp->ds == ds) in mv88e6xxx_lag_sync_masks()
6914 mv88e6xxx_lag_set_port_mask(mask, dp->index, in mv88e6xxx_lag_sync_masks()
6922 err = mv88e6xxx_g2_trunk_mask_write(chip, i, true, mask[i]); in mv88e6xxx_lag_sync_masks()
6945 struct mv88e6xxx_chip *chip = ds->priv; in mv88e6xxx_port_lag_change() local
6948 mv88e6xxx_reg_lock(chip); in mv88e6xxx_port_lag_change()
6950 mv88e6xxx_reg_unlock(chip); in mv88e6xxx_port_lag_change()
6959 struct mv88e6xxx_chip *chip = ds->priv; in mv88e6xxx_port_lag_join() local
6963 return -EOPNOTSUPP; in mv88e6xxx_port_lag_join()
6965 /* DSA LAG IDs are one-based */ in mv88e6xxx_port_lag_join()
6966 id = lag.id - 1; in mv88e6xxx_port_lag_join()
6968 mv88e6xxx_reg_lock(chip); in mv88e6xxx_port_lag_join()
6970 err = mv88e6xxx_port_set_trunk(chip, port, true, id); in mv88e6xxx_port_lag_join()
6978 mv88e6xxx_reg_unlock(chip); in mv88e6xxx_port_lag_join()
6982 mv88e6xxx_port_set_trunk(chip, port, false, 0); in mv88e6xxx_port_lag_join()
6984 mv88e6xxx_reg_unlock(chip); in mv88e6xxx_port_lag_join()
6991 struct mv88e6xxx_chip *chip = ds->priv; in mv88e6xxx_port_lag_leave() local
6994 mv88e6xxx_reg_lock(chip); in mv88e6xxx_port_lag_leave()
6996 err_trunk = mv88e6xxx_port_set_trunk(chip, port, false, 0); in mv88e6xxx_port_lag_leave()
6997 mv88e6xxx_reg_unlock(chip); in mv88e6xxx_port_lag_leave()
7004 struct mv88e6xxx_chip *chip = ds->priv; in mv88e6xxx_crosschip_lag_change() local
7007 mv88e6xxx_reg_lock(chip); in mv88e6xxx_crosschip_lag_change()
7009 mv88e6xxx_reg_unlock(chip); in mv88e6xxx_crosschip_lag_change()
7018 struct mv88e6xxx_chip *chip = ds->priv; in mv88e6xxx_crosschip_lag_join() local
7022 return -EOPNOTSUPP; in mv88e6xxx_crosschip_lag_join()
7024 mv88e6xxx_reg_lock(chip); in mv88e6xxx_crosschip_lag_join()
7030 err = mv88e6xxx_pvt_map(chip, sw_index, port); in mv88e6xxx_crosschip_lag_join()
7033 mv88e6xxx_reg_unlock(chip); in mv88e6xxx_crosschip_lag_join()
7040 struct mv88e6xxx_chip *chip = ds->priv; in mv88e6xxx_crosschip_lag_leave() local
7043 mv88e6xxx_reg_lock(chip); in mv88e6xxx_crosschip_lag_leave()
7045 err_pvt = mv88e6xxx_pvt_map(chip, sw_index, port); in mv88e6xxx_crosschip_lag_leave()
7046 mv88e6xxx_reg_unlock(chip); in mv88e6xxx_crosschip_lag_leave()
7121 static int mv88e6xxx_register_switch(struct mv88e6xxx_chip *chip) in mv88e6xxx_register_switch() argument
7123 struct device *dev = chip->dev; in mv88e6xxx_register_switch()
7128 return -ENOMEM; in mv88e6xxx_register_switch()
7130 ds->dev = dev; in mv88e6xxx_register_switch()
7131 ds->num_ports = mv88e6xxx_num_ports(chip); in mv88e6xxx_register_switch()
7132 ds->priv = chip; in mv88e6xxx_register_switch()
7133 ds->dev = dev; in mv88e6xxx_register_switch()
7134 ds->ops = &mv88e6xxx_switch_ops; in mv88e6xxx_register_switch()
7135 ds->phylink_mac_ops = &mv88e6xxx_phylink_mac_ops; in mv88e6xxx_register_switch()
7136 ds->ageing_time_min = chip->info->age_time_coeff; in mv88e6xxx_register_switch()
7137 ds->ageing_time_max = chip->info->age_time_coeff * U8_MAX; in mv88e6xxx_register_switch()
7140 * 5-bit port mode, which we do not support. 640k^W16 ought to in mv88e6xxx_register_switch()
7143 ds->num_lag_ids = mv88e6xxx_has_lag(chip) ? 16 : 0; in mv88e6xxx_register_switch()
7150 static void mv88e6xxx_unregister_switch(struct mv88e6xxx_chip *chip) in mv88e6xxx_unregister_switch() argument
7152 dsa_unregister_switch(chip->ds); in mv88e6xxx_unregister_switch()
7157 const struct of_device_id *matches = dev->driver->of_match_table; in pdata_device_get_match_data()
7158 const struct dsa_mv88e6xxx_pdata *pdata = dev->platform_data; in pdata_device_get_match_data()
7160 for (; matches->name[0] || matches->type[0] || matches->compatible[0]; in pdata_device_get_match_data()
7162 if (!strcmp(pdata->compatible, matches->compatible)) in pdata_device_get_match_data()
7163 return matches->data; in pdata_device_get_match_data()
7173 return -EOPNOTSUPP; in mv88e6xxx_suspend()
7185 struct dsa_mv88e6xxx_pdata *pdata = mdiodev->dev.platform_data; in mv88e6xxx_probe()
7187 struct device *dev = &mdiodev->dev; in mv88e6xxx_probe()
7188 struct device_node *np = dev->of_node; in mv88e6xxx_probe()
7189 struct mv88e6xxx_chip *chip; in mv88e6xxx_probe() local
7194 return -EINVAL; in mv88e6xxx_probe()
7202 if (!pdata->netdev) in mv88e6xxx_probe()
7203 return -EINVAL; in mv88e6xxx_probe()
7206 if (!(pdata->enabled_ports & (1 << port))) in mv88e6xxx_probe()
7208 if (strcmp(pdata->cd.port_names[port], "cpu")) in mv88e6xxx_probe()
7210 pdata->cd.netdev[port] = &pdata->netdev->dev; in mv88e6xxx_probe()
7216 return -EINVAL; in mv88e6xxx_probe()
7218 chip = mv88e6xxx_alloc_chip(dev); in mv88e6xxx_probe()
7219 if (!chip) { in mv88e6xxx_probe()
7220 err = -ENOMEM; in mv88e6xxx_probe()
7224 chip->info = compat_info; in mv88e6xxx_probe()
7226 chip->reset = devm_gpiod_get_optional(dev, "reset", GPIOD_OUT_LOW); in mv88e6xxx_probe()
7227 if (IS_ERR(chip->reset)) { in mv88e6xxx_probe()
7228 err = PTR_ERR(chip->reset); in mv88e6xxx_probe()
7231 if (chip->reset) in mv88e6xxx_probe()
7234 /* Detect if the device is configured in single chip addressing mode, in mv88e6xxx_probe()
7237 err = mv88e6xxx_single_chip_detect(chip, mdiodev); in mv88e6xxx_probe()
7239 err = mv88e6xxx_smi_init(chip, mdiodev->bus, mdiodev->addr); in mv88e6xxx_probe()
7243 err = mv88e6xxx_detect(chip); in mv88e6xxx_probe()
7248 if (chip->info->edsa_support == MV88E6XXX_EDSA_SUPPORTED) in mv88e6xxx_probe()
7249 chip->tag_protocol = DSA_TAG_PROTO_EDSA; in mv88e6xxx_probe()
7251 chip->tag_protocol = DSA_TAG_PROTO_DSA; in mv88e6xxx_probe()
7253 mv88e6xxx_phy_init(chip); in mv88e6xxx_probe()
7255 if (chip->info->ops->get_eeprom) { in mv88e6xxx_probe()
7257 of_property_read_u32(np, "eeprom-length", in mv88e6xxx_probe()
7258 &chip->eeprom_len); in mv88e6xxx_probe()
7260 chip->eeprom_len = pdata->eeprom_len; in mv88e6xxx_probe()
7263 mv88e6xxx_reg_lock(chip); in mv88e6xxx_probe()
7264 err = mv88e6xxx_switch_reset(chip); in mv88e6xxx_probe()
7265 mv88e6xxx_reg_unlock(chip); in mv88e6xxx_probe()
7270 chip->irq = of_irq_get(np, 0); in mv88e6xxx_probe()
7271 if (chip->irq == -EPROBE_DEFER) { in mv88e6xxx_probe()
7272 err = chip->irq; in mv88e6xxx_probe()
7278 chip->irq = pdata->irq; in mv88e6xxx_probe()
7284 mv88e6xxx_reg_lock(chip); in mv88e6xxx_probe()
7285 if (chip->irq > 0) in mv88e6xxx_probe()
7286 err = mv88e6xxx_g1_irq_setup(chip); in mv88e6xxx_probe()
7288 err = mv88e6xxx_irq_poll_setup(chip); in mv88e6xxx_probe()
7289 mv88e6xxx_reg_unlock(chip); in mv88e6xxx_probe()
7294 if (chip->info->g2_irqs > 0) { in mv88e6xxx_probe()
7295 err = mv88e6xxx_g2_irq_setup(chip); in mv88e6xxx_probe()
7300 err = mv88e6xxx_g1_atu_prob_irq_setup(chip); in mv88e6xxx_probe()
7304 err = mv88e6xxx_g1_vtu_prob_irq_setup(chip); in mv88e6xxx_probe()
7308 err = mv88e6xxx_register_switch(chip); in mv88e6xxx_probe()
7315 mv88e6xxx_g1_vtu_prob_irq_free(chip); in mv88e6xxx_probe()
7317 mv88e6xxx_g1_atu_prob_irq_free(chip); in mv88e6xxx_probe()
7319 if (chip->info->g2_irqs > 0) in mv88e6xxx_probe()
7320 mv88e6xxx_g2_irq_free(chip); in mv88e6xxx_probe()
7322 if (chip->irq > 0) in mv88e6xxx_probe()
7323 mv88e6xxx_g1_irq_free(chip); in mv88e6xxx_probe()
7325 mv88e6xxx_irq_poll_free(chip); in mv88e6xxx_probe()
7328 dev_put(pdata->netdev); in mv88e6xxx_probe()
7335 struct dsa_switch *ds = dev_get_drvdata(&mdiodev->dev); in mv88e6xxx_remove()
7336 struct mv88e6xxx_chip *chip; in mv88e6xxx_remove() local
7341 chip = ds->priv; in mv88e6xxx_remove()
7343 if (chip->info->ptp_support) { in mv88e6xxx_remove()
7344 mv88e6xxx_hwtstamp_free(chip); in mv88e6xxx_remove()
7345 mv88e6xxx_ptp_free(chip); in mv88e6xxx_remove()
7348 mv88e6xxx_phy_destroy(chip); in mv88e6xxx_remove()
7349 mv88e6xxx_unregister_switch(chip); in mv88e6xxx_remove()
7351 mv88e6xxx_g1_vtu_prob_irq_free(chip); in mv88e6xxx_remove()
7352 mv88e6xxx_g1_atu_prob_irq_free(chip); in mv88e6xxx_remove()
7354 if (chip->info->g2_irqs > 0) in mv88e6xxx_remove()
7355 mv88e6xxx_g2_irq_free(chip); in mv88e6xxx_remove()
7357 if (chip->irq > 0) in mv88e6xxx_remove()
7358 mv88e6xxx_g1_irq_free(chip); in mv88e6xxx_remove()
7360 mv88e6xxx_irq_poll_free(chip); in mv88e6xxx_remove()
7365 struct dsa_switch *ds = dev_get_drvdata(&mdiodev->dev); in mv88e6xxx_shutdown()
7372 dev_set_drvdata(&mdiodev->dev, NULL); in mv88e6xxx_shutdown()