^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1) // SPDX-License-Identifier: GPL-2.0-or-later
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3) * Marvell 88e6xxx Ethernet switch single-chip support
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5) * Copyright (c) 2008 Marvell Semiconductor
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7) * Copyright (c) 2016 Andrew Lunn <andrew@lunn.ch>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9) * Copyright (c) 2016-2017 Savoir-faire Linux Inc.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10) * Vivien Didelot <vivien.didelot@savoirfairelinux.com>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13) #include <linux/bitfield.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14) #include <linux/delay.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15) #include <linux/etherdevice.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16) #include <linux/ethtool.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17) #include <linux/if_bridge.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18) #include <linux/interrupt.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19) #include <linux/irq.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20) #include <linux/irqdomain.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21) #include <linux/jiffies.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22) #include <linux/list.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23) #include <linux/mdio.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24) #include <linux/module.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25) #include <linux/of_device.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26) #include <linux/of_irq.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27) #include <linux/of_mdio.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28) #include <linux/platform_data/mv88e6xxx.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29) #include <linux/netdevice.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30) #include <linux/gpio/consumer.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31) #include <linux/phylink.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32) #include <net/dsa.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34) #include "chip.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35) #include "devlink.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36) #include "global1.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37) #include "global2.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38) #include "hwtstamp.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39) #include "phy.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40) #include "port.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41) #include "ptp.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42) #include "serdes.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43) #include "smi.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45) static void assert_reg_lock(struct mv88e6xxx_chip *chip)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47) if (unlikely(!mutex_is_locked(&chip->reg_lock))) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48) dev_err(chip->dev, "Switch registers lock not held!\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49) dump_stack();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53) int mv88e6xxx_read(struct mv88e6xxx_chip *chip, int addr, int reg, u16 *val)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55) int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57) assert_reg_lock(chip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59) err = mv88e6xxx_smi_read(chip, addr, reg, val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60) if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63) dev_dbg(chip->dev, "<- addr: 0x%.2x reg: 0x%.2x val: 0x%.4x\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64) addr, reg, *val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69) int mv88e6xxx_write(struct mv88e6xxx_chip *chip, int addr, int reg, u16 val)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71) int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73) assert_reg_lock(chip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75) err = mv88e6xxx_smi_write(chip, addr, reg, val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76) if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79) dev_dbg(chip->dev, "-> addr: 0x%.2x reg: 0x%.2x val: 0x%.4x\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80) addr, reg, val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85) int mv88e6xxx_wait_mask(struct mv88e6xxx_chip *chip, int addr, int reg,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86) u16 mask, u16 val)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88) u16 data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89) int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92) /* There's no bus specific operation to wait for a mask */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93) for (i = 0; i < 16; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94) err = mv88e6xxx_read(chip, addr, reg, &data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95) if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98) if ((data & mask) == val)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) usleep_range(1000, 2000);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) dev_err(chip->dev, "Timeout while waiting for switch\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) return -ETIMEDOUT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) int mv88e6xxx_wait_bit(struct mv88e6xxx_chip *chip, int addr, int reg,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) int bit, int val)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) return mv88e6xxx_wait_mask(chip, addr, reg, BIT(bit),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) val ? BIT(bit) : 0x0000);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) struct mii_bus *mv88e6xxx_default_mdio_bus(struct mv88e6xxx_chip *chip)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) struct mv88e6xxx_mdio_bus *mdio_bus;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) mdio_bus = list_first_entry(&chip->mdios, struct mv88e6xxx_mdio_bus,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) if (!mdio_bus)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) return mdio_bus->bus;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) static void mv88e6xxx_g1_irq_mask(struct irq_data *d)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) struct mv88e6xxx_chip *chip = irq_data_get_irq_chip_data(d);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) unsigned int n = d->hwirq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) chip->g1_irq.masked |= (1 << n);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) static void mv88e6xxx_g1_irq_unmask(struct irq_data *d)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) struct mv88e6xxx_chip *chip = irq_data_get_irq_chip_data(d);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) unsigned int n = d->hwirq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) chip->g1_irq.masked &= ~(1 << n);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) static irqreturn_t mv88e6xxx_g1_irq_thread_work(struct mv88e6xxx_chip *chip)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) unsigned int nhandled = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) unsigned int sub_irq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) unsigned int n;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) u16 reg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) u16 ctl1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) mv88e6xxx_reg_lock(chip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) err = mv88e6xxx_g1_read(chip, MV88E6XXX_G1_STS, ®);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) mv88e6xxx_reg_unlock(chip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) do {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) for (n = 0; n < chip->g1_irq.nirqs; ++n) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) if (reg & (1 << n)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) sub_irq = irq_find_mapping(chip->g1_irq.domain,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) n);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) handle_nested_irq(sub_irq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) ++nhandled;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) mv88e6xxx_reg_lock(chip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170) err = mv88e6xxx_g1_read(chip, MV88E6XXX_G1_CTL1, &ctl1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) goto unlock;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) err = mv88e6xxx_g1_read(chip, MV88E6XXX_G1_STS, ®);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) unlock:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175) mv88e6xxx_reg_unlock(chip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176) if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178) ctl1 &= GENMASK(chip->g1_irq.nirqs, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179) } while (reg & ctl1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182) return (nhandled > 0 ? IRQ_HANDLED : IRQ_NONE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185) static irqreturn_t mv88e6xxx_g1_irq_thread_fn(int irq, void *dev_id)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187) struct mv88e6xxx_chip *chip = dev_id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189) return mv88e6xxx_g1_irq_thread_work(chip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192) static void mv88e6xxx_g1_irq_bus_lock(struct irq_data *d)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194) struct mv88e6xxx_chip *chip = irq_data_get_irq_chip_data(d);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196) mv88e6xxx_reg_lock(chip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199) static void mv88e6xxx_g1_irq_bus_sync_unlock(struct irq_data *d)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201) struct mv88e6xxx_chip *chip = irq_data_get_irq_chip_data(d);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202) u16 mask = GENMASK(chip->g1_irq.nirqs, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203) u16 reg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204) int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206) err = mv88e6xxx_g1_read(chip, MV88E6XXX_G1_CTL1, ®);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207) if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210) reg &= ~mask;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211) reg |= (~chip->g1_irq.masked & mask);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213) err = mv88e6xxx_g1_write(chip, MV88E6XXX_G1_CTL1, reg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214) if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218) mv88e6xxx_reg_unlock(chip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221) static const struct irq_chip mv88e6xxx_g1_irq_chip = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222) .name = "mv88e6xxx-g1",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223) .irq_mask = mv88e6xxx_g1_irq_mask,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224) .irq_unmask = mv88e6xxx_g1_irq_unmask,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225) .irq_bus_lock = mv88e6xxx_g1_irq_bus_lock,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226) .irq_bus_sync_unlock = mv88e6xxx_g1_irq_bus_sync_unlock,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229) static int mv88e6xxx_g1_irq_domain_map(struct irq_domain *d,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230) unsigned int irq,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231) irq_hw_number_t hwirq)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233) struct mv88e6xxx_chip *chip = d->host_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235) irq_set_chip_data(irq, d->host_data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236) irq_set_chip_and_handler(irq, &chip->g1_irq.chip, handle_level_irq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237) irq_set_noprobe(irq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242) static const struct irq_domain_ops mv88e6xxx_g1_irq_domain_ops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243) .map = mv88e6xxx_g1_irq_domain_map,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244) .xlate = irq_domain_xlate_twocell,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247) /* To be called with reg_lock held */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248) static void mv88e6xxx_g1_irq_free_common(struct mv88e6xxx_chip *chip)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250) int irq, virq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251) u16 mask;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253) mv88e6xxx_g1_read(chip, MV88E6XXX_G1_CTL1, &mask);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254) mask &= ~GENMASK(chip->g1_irq.nirqs, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255) mv88e6xxx_g1_write(chip, MV88E6XXX_G1_CTL1, mask);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257) for (irq = 0; irq < chip->g1_irq.nirqs; irq++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258) virq = irq_find_mapping(chip->g1_irq.domain, irq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 259) irq_dispose_mapping(virq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 260) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 261)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 262) irq_domain_remove(chip->g1_irq.domain);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 263) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 264)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 265) static void mv88e6xxx_g1_irq_free(struct mv88e6xxx_chip *chip)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 266) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 267) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 268) * free_irq must be called without reg_lock taken because the irq
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 269) * handler takes this lock, too.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 270) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 271) free_irq(chip->irq, chip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 272)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 273) mv88e6xxx_reg_lock(chip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 274) mv88e6xxx_g1_irq_free_common(chip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 275) mv88e6xxx_reg_unlock(chip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 276) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 277)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 278) static int mv88e6xxx_g1_irq_setup_common(struct mv88e6xxx_chip *chip)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 279) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 280) int err, irq, virq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 281) u16 reg, mask;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 282)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 283) chip->g1_irq.nirqs = chip->info->g1_irqs;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 284) chip->g1_irq.domain = irq_domain_add_simple(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 285) NULL, chip->g1_irq.nirqs, 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 286) &mv88e6xxx_g1_irq_domain_ops, chip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 287) if (!chip->g1_irq.domain)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 288) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 289)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 290) for (irq = 0; irq < chip->g1_irq.nirqs; irq++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 291) irq_create_mapping(chip->g1_irq.domain, irq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 292)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 293) chip->g1_irq.chip = mv88e6xxx_g1_irq_chip;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 294) chip->g1_irq.masked = ~0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 295)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 296) err = mv88e6xxx_g1_read(chip, MV88E6XXX_G1_CTL1, &mask);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 297) if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 298) goto out_mapping;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 299)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 300) mask &= ~GENMASK(chip->g1_irq.nirqs, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 301)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 302) err = mv88e6xxx_g1_write(chip, MV88E6XXX_G1_CTL1, mask);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 303) if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 304) goto out_disable;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 305)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 306) /* Reading the interrupt status clears (most of) them */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 307) err = mv88e6xxx_g1_read(chip, MV88E6XXX_G1_STS, ®);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 308) if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 309) goto out_disable;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 310)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 311) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 312)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 313) out_disable:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 314) mask &= ~GENMASK(chip->g1_irq.nirqs, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 315) mv88e6xxx_g1_write(chip, MV88E6XXX_G1_CTL1, mask);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 316)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 317) out_mapping:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 318) for (irq = 0; irq < 16; irq++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 319) virq = irq_find_mapping(chip->g1_irq.domain, irq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 320) irq_dispose_mapping(virq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 321) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 322)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 323) irq_domain_remove(chip->g1_irq.domain);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 324)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 325) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 326) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 327)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 328) static int mv88e6xxx_g1_irq_setup(struct mv88e6xxx_chip *chip)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 329) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 330) static struct lock_class_key lock_key;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 331) static struct lock_class_key request_key;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 332) int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 333)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 334) err = mv88e6xxx_g1_irq_setup_common(chip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 335) if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 336) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 337)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 338) /* These lock classes tells lockdep that global 1 irqs are in
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 339) * a different category than their parent GPIO, so it won't
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 340) * report false recursion.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 341) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 342) irq_set_lockdep_class(chip->irq, &lock_key, &request_key);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 343)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 344) snprintf(chip->irq_name, sizeof(chip->irq_name),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 345) "mv88e6xxx-%s", dev_name(chip->dev));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 346)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 347) mv88e6xxx_reg_unlock(chip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 348) err = request_threaded_irq(chip->irq, NULL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 349) mv88e6xxx_g1_irq_thread_fn,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 350) IRQF_ONESHOT | IRQF_SHARED,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 351) chip->irq_name, chip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 352) mv88e6xxx_reg_lock(chip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 353) if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 354) mv88e6xxx_g1_irq_free_common(chip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 355)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 356) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 357) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 358)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 359) static void mv88e6xxx_irq_poll(struct kthread_work *work)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 360) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 361) struct mv88e6xxx_chip *chip = container_of(work,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 362) struct mv88e6xxx_chip,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 363) irq_poll_work.work);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 364) mv88e6xxx_g1_irq_thread_work(chip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 365)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 366) kthread_queue_delayed_work(chip->kworker, &chip->irq_poll_work,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 367) msecs_to_jiffies(100));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 368) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 369)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 370) static int mv88e6xxx_irq_poll_setup(struct mv88e6xxx_chip *chip)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 371) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 372) int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 373)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 374) err = mv88e6xxx_g1_irq_setup_common(chip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 375) if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 376) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 377)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 378) kthread_init_delayed_work(&chip->irq_poll_work,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 379) mv88e6xxx_irq_poll);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 380)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 381) chip->kworker = kthread_create_worker(0, "%s", dev_name(chip->dev));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 382) if (IS_ERR(chip->kworker))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 383) return PTR_ERR(chip->kworker);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 384)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 385) kthread_queue_delayed_work(chip->kworker, &chip->irq_poll_work,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 386) msecs_to_jiffies(100));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 387)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 388) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 389) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 390)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 391) static void mv88e6xxx_irq_poll_free(struct mv88e6xxx_chip *chip)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 392) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 393) kthread_cancel_delayed_work_sync(&chip->irq_poll_work);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 394) kthread_destroy_worker(chip->kworker);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 395)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 396) mv88e6xxx_reg_lock(chip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 397) mv88e6xxx_g1_irq_free_common(chip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 398) mv88e6xxx_reg_unlock(chip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 399) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 400)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 401) static int mv88e6xxx_port_config_interface(struct mv88e6xxx_chip *chip,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 402) int port, phy_interface_t interface)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 403) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 404) int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 405)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 406) if (chip->info->ops->port_set_rgmii_delay) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 407) err = chip->info->ops->port_set_rgmii_delay(chip, port,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 408) interface);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 409) if (err && err != -EOPNOTSUPP)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 410) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 411) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 412)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 413) if (chip->info->ops->port_set_cmode) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 414) err = chip->info->ops->port_set_cmode(chip, port,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 415) interface);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 416) if (err && err != -EOPNOTSUPP)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 417) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 418) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 419)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 420) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 421) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 422)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 423) static int mv88e6xxx_port_setup_mac(struct mv88e6xxx_chip *chip, int port,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 424) int link, int speed, int duplex, int pause,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 425) phy_interface_t mode)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 426) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 427) int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 428)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 429) if (!chip->info->ops->port_set_link)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 430) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 431)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 432) /* Port's MAC control must not be changed unless the link is down */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 433) err = chip->info->ops->port_set_link(chip, port, LINK_FORCED_DOWN);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 434) if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 435) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 436)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 437) if (chip->info->ops->port_set_speed_duplex) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 438) err = chip->info->ops->port_set_speed_duplex(chip, port,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 439) speed, duplex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 440) if (err && err != -EOPNOTSUPP)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 441) goto restore_link;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 442) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 443)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 444) if (speed == SPEED_MAX && chip->info->ops->port_max_speed_mode)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 445) mode = chip->info->ops->port_max_speed_mode(port);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 446)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 447) if (chip->info->ops->port_set_pause) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 448) err = chip->info->ops->port_set_pause(chip, port, pause);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 449) if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 450) goto restore_link;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 451) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 452)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 453) err = mv88e6xxx_port_config_interface(chip, port, mode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 454) restore_link:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 455) if (chip->info->ops->port_set_link(chip, port, link))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 456) dev_err(chip->dev, "p%d: failed to restore MAC's link\n", port);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 457)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 458) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 459) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 460)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 461) static int mv88e6xxx_phy_is_internal(struct dsa_switch *ds, int port)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 462) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 463) struct mv88e6xxx_chip *chip = ds->priv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 464)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 465) return port < chip->info->num_internal_phys;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 466) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 467)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 468) static int mv88e6xxx_port_ppu_updates(struct mv88e6xxx_chip *chip, int port)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 469) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 470) u16 reg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 471) int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 472)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 473) err = mv88e6xxx_port_read(chip, port, MV88E6XXX_PORT_STS, ®);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 474) if (err) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 475) dev_err(chip->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 476) "p%d: %s: failed to read port status\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 477) port, __func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 478) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 479) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 480)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 481) return !!(reg & MV88E6XXX_PORT_STS_PHY_DETECT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 482) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 483)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 484) static int mv88e6xxx_serdes_pcs_get_state(struct dsa_switch *ds, int port,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 485) struct phylink_link_state *state)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 486) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 487) struct mv88e6xxx_chip *chip = ds->priv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 488) u8 lane;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 489) int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 490)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 491) mv88e6xxx_reg_lock(chip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 492) lane = mv88e6xxx_serdes_get_lane(chip, port);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 493) if (lane && chip->info->ops->serdes_pcs_get_state)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 494) err = chip->info->ops->serdes_pcs_get_state(chip, port, lane,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 495) state);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 496) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 497) err = -EOPNOTSUPP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 498) mv88e6xxx_reg_unlock(chip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 499)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 500) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 501) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 502)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 503) static int mv88e6xxx_serdes_pcs_config(struct mv88e6xxx_chip *chip, int port,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 504) unsigned int mode,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 505) phy_interface_t interface,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 506) const unsigned long *advertise)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 507) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 508) const struct mv88e6xxx_ops *ops = chip->info->ops;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 509) u8 lane;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 510)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 511) if (ops->serdes_pcs_config) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 512) lane = mv88e6xxx_serdes_get_lane(chip, port);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 513) if (lane)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 514) return ops->serdes_pcs_config(chip, port, lane, mode,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 515) interface, advertise);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 516) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 517)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 518) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 519) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 520)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 521) static void mv88e6xxx_serdes_pcs_an_restart(struct dsa_switch *ds, int port)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 522) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 523) struct mv88e6xxx_chip *chip = ds->priv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 524) const struct mv88e6xxx_ops *ops;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 525) int err = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 526) u8 lane;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 527)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 528) ops = chip->info->ops;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 529)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 530) if (ops->serdes_pcs_an_restart) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 531) mv88e6xxx_reg_lock(chip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 532) lane = mv88e6xxx_serdes_get_lane(chip, port);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 533) if (lane)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 534) err = ops->serdes_pcs_an_restart(chip, port, lane);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 535) mv88e6xxx_reg_unlock(chip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 536)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 537) if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 538) dev_err(ds->dev, "p%d: failed to restart AN\n", port);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 539) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 540) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 541)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 542) static int mv88e6xxx_serdes_pcs_link_up(struct mv88e6xxx_chip *chip, int port,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 543) unsigned int mode,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 544) int speed, int duplex)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 545) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 546) const struct mv88e6xxx_ops *ops = chip->info->ops;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 547) u8 lane;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 548)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 549) if (!phylink_autoneg_inband(mode) && ops->serdes_pcs_link_up) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 550) lane = mv88e6xxx_serdes_get_lane(chip, port);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 551) if (lane)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 552) return ops->serdes_pcs_link_up(chip, port, lane,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 553) speed, duplex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 554) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 555)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 556) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 557) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 558)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 559) static void mv88e6065_phylink_validate(struct mv88e6xxx_chip *chip, int port,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 560) unsigned long *mask,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 561) struct phylink_link_state *state)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 562) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 563) if (!phy_interface_mode_is_8023z(state->interface)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 564) /* 10M and 100M are only supported in non-802.3z mode */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 565) phylink_set(mask, 10baseT_Half);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 566) phylink_set(mask, 10baseT_Full);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 567) phylink_set(mask, 100baseT_Half);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 568) phylink_set(mask, 100baseT_Full);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 569) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 570) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 571)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 572) static void mv88e6185_phylink_validate(struct mv88e6xxx_chip *chip, int port,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 573) unsigned long *mask,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 574) struct phylink_link_state *state)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 575) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 576) /* FIXME: if the port is in 1000Base-X mode, then it only supports
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 577) * 1000M FD speeds. In this case, CMODE will indicate 5.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 578) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 579) phylink_set(mask, 1000baseT_Full);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 580) phylink_set(mask, 1000baseX_Full);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 581)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 582) mv88e6065_phylink_validate(chip, port, mask, state);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 583) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 584)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 585) static void mv88e6341_phylink_validate(struct mv88e6xxx_chip *chip, int port,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 586) unsigned long *mask,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 587) struct phylink_link_state *state)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 588) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 589) if (port >= 5)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 590) phylink_set(mask, 2500baseX_Full);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 591)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 592) /* No ethtool bits for 200Mbps */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 593) phylink_set(mask, 1000baseT_Full);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 594) phylink_set(mask, 1000baseX_Full);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 595)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 596) mv88e6065_phylink_validate(chip, port, mask, state);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 597) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 598)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 599) static void mv88e6352_phylink_validate(struct mv88e6xxx_chip *chip, int port,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 600) unsigned long *mask,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 601) struct phylink_link_state *state)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 602) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 603) /* No ethtool bits for 200Mbps */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 604) phylink_set(mask, 1000baseT_Full);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 605) phylink_set(mask, 1000baseX_Full);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 606)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 607) mv88e6065_phylink_validate(chip, port, mask, state);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 608) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 609)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 610) static void mv88e6390_phylink_validate(struct mv88e6xxx_chip *chip, int port,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 611) unsigned long *mask,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 612) struct phylink_link_state *state)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 613) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 614) if (port >= 9) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 615) phylink_set(mask, 2500baseX_Full);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 616) phylink_set(mask, 2500baseT_Full);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 617) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 618)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 619) /* No ethtool bits for 200Mbps */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 620) phylink_set(mask, 1000baseT_Full);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 621) phylink_set(mask, 1000baseX_Full);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 622)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 623) mv88e6065_phylink_validate(chip, port, mask, state);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 624) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 625)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 626) static void mv88e6390x_phylink_validate(struct mv88e6xxx_chip *chip, int port,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 627) unsigned long *mask,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 628) struct phylink_link_state *state)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 629) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 630) if (port >= 9) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 631) phylink_set(mask, 10000baseT_Full);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 632) phylink_set(mask, 10000baseKR_Full);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 633) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 634)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 635) mv88e6390_phylink_validate(chip, port, mask, state);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 636) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 637)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 638) static void mv88e6xxx_validate(struct dsa_switch *ds, int port,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 639) unsigned long *supported,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 640) struct phylink_link_state *state)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 641) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 642) __ETHTOOL_DECLARE_LINK_MODE_MASK(mask) = { 0, };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 643) struct mv88e6xxx_chip *chip = ds->priv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 644)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 645) /* Allow all the expected bits */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 646) phylink_set(mask, Autoneg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 647) phylink_set(mask, Pause);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 648) phylink_set_port_modes(mask);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 649)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 650) if (chip->info->ops->phylink_validate)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 651) chip->info->ops->phylink_validate(chip, port, mask, state);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 652)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 653) bitmap_and(supported, supported, mask, __ETHTOOL_LINK_MODE_MASK_NBITS);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 654) bitmap_and(state->advertising, state->advertising, mask,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 655) __ETHTOOL_LINK_MODE_MASK_NBITS);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 656)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 657) /* We can only operate at 2500BaseX or 1000BaseX. If requested
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 658) * to advertise both, only report advertising at 2500BaseX.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 659) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 660) phylink_helper_basex_speed(state);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 661) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 662)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 663) static void mv88e6xxx_mac_config(struct dsa_switch *ds, int port,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 664) unsigned int mode,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 665) const struct phylink_link_state *state)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 666) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 667) struct mv88e6xxx_chip *chip = ds->priv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 668) struct mv88e6xxx_port *p;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 669) int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 670)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 671) p = &chip->ports[port];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 672)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 673) /* FIXME: is this the correct test? If we're in fixed mode on an
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 674) * internal port, why should we process this any different from
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 675) * PHY mode? On the other hand, the port may be automedia between
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 676) * an internal PHY and the serdes...
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 677) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 678) if ((mode == MLO_AN_PHY) && mv88e6xxx_phy_is_internal(ds, port))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 679) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 680)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 681) mv88e6xxx_reg_lock(chip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 682) /* In inband mode, the link may come up at any time while the link
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 683) * is not forced down. Force the link down while we reconfigure the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 684) * interface mode.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 685) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 686) if (mode == MLO_AN_INBAND && p->interface != state->interface &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 687) chip->info->ops->port_set_link)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 688) chip->info->ops->port_set_link(chip, port, LINK_FORCED_DOWN);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 689)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 690) err = mv88e6xxx_port_config_interface(chip, port, state->interface);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 691) if (err && err != -EOPNOTSUPP)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 692) goto err_unlock;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 693)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 694) err = mv88e6xxx_serdes_pcs_config(chip, port, mode, state->interface,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 695) state->advertising);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 696) /* FIXME: we should restart negotiation if something changed - which
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 697) * is something we get if we convert to using phylinks PCS operations.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 698) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 699) if (err > 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 700) err = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 701)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 702) /* Undo the forced down state above after completing configuration
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 703) * irrespective of its state on entry, which allows the link to come up.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 704) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 705) if (mode == MLO_AN_INBAND && p->interface != state->interface &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 706) chip->info->ops->port_set_link)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 707) chip->info->ops->port_set_link(chip, port, LINK_UNFORCED);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 708)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 709) p->interface = state->interface;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 710)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 711) err_unlock:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 712) mv88e6xxx_reg_unlock(chip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 713)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 714) if (err && err != -EOPNOTSUPP)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 715) dev_err(ds->dev, "p%d: failed to configure MAC/PCS\n", port);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 716) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 717)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 718) static void mv88e6xxx_mac_link_down(struct dsa_switch *ds, int port,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 719) unsigned int mode,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 720) phy_interface_t interface)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 721) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 722) struct mv88e6xxx_chip *chip = ds->priv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 723) const struct mv88e6xxx_ops *ops;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 724) int err = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 725)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 726) ops = chip->info->ops;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 727)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 728) mv88e6xxx_reg_lock(chip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 729) /* Internal PHYs propagate their configuration directly to the MAC.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 730) * External PHYs depend on whether the PPU is enabled for this port.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 731) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 732) if (((!mv88e6xxx_phy_is_internal(ds, port) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 733) !mv88e6xxx_port_ppu_updates(chip, port)) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 734) mode == MLO_AN_FIXED) && ops->port_set_link)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 735) err = ops->port_set_link(chip, port, LINK_FORCED_DOWN);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 736) mv88e6xxx_reg_unlock(chip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 737)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 738) if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 739) dev_err(chip->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 740) "p%d: failed to force MAC link down\n", port);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 741) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 742)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 743) static void mv88e6xxx_mac_link_up(struct dsa_switch *ds, int port,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 744) unsigned int mode, phy_interface_t interface,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 745) struct phy_device *phydev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 746) int speed, int duplex,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 747) bool tx_pause, bool rx_pause)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 748) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 749) struct mv88e6xxx_chip *chip = ds->priv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 750) const struct mv88e6xxx_ops *ops;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 751) int err = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 752)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 753) ops = chip->info->ops;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 754)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 755) mv88e6xxx_reg_lock(chip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 756) /* Internal PHYs propagate their configuration directly to the MAC.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 757) * External PHYs depend on whether the PPU is enabled for this port.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 758) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 759) if ((!mv88e6xxx_phy_is_internal(ds, port) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 760) !mv88e6xxx_port_ppu_updates(chip, port)) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 761) mode == MLO_AN_FIXED) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 762) /* FIXME: for an automedia port, should we force the link
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 763) * down here - what if the link comes up due to "other" media
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 764) * while we're bringing the port up, how is the exclusivity
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 765) * handled in the Marvell hardware? E.g. port 2 on 88E6390
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 766) * shared between internal PHY and Serdes.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 767) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 768) err = mv88e6xxx_serdes_pcs_link_up(chip, port, mode, speed,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 769) duplex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 770) if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 771) goto error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 772)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 773) if (ops->port_set_speed_duplex) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 774) err = ops->port_set_speed_duplex(chip, port,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 775) speed, duplex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 776) if (err && err != -EOPNOTSUPP)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 777) goto error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 778) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 779)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 780) if (ops->port_set_link)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 781) err = ops->port_set_link(chip, port, LINK_FORCED_UP);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 782) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 783) error:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 784) mv88e6xxx_reg_unlock(chip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 785)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 786) if (err && err != -EOPNOTSUPP)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 787) dev_err(ds->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 788) "p%d: failed to configure MAC link up\n", port);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 789) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 790)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 791) static int mv88e6xxx_stats_snapshot(struct mv88e6xxx_chip *chip, int port)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 792) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 793) if (!chip->info->ops->stats_snapshot)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 794) return -EOPNOTSUPP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 795)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 796) return chip->info->ops->stats_snapshot(chip, port);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 797) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 798)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 799) static struct mv88e6xxx_hw_stat mv88e6xxx_hw_stats[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 800) { "in_good_octets", 8, 0x00, STATS_TYPE_BANK0, },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 801) { "in_bad_octets", 4, 0x02, STATS_TYPE_BANK0, },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 802) { "in_unicast", 4, 0x04, STATS_TYPE_BANK0, },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 803) { "in_broadcasts", 4, 0x06, STATS_TYPE_BANK0, },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 804) { "in_multicasts", 4, 0x07, STATS_TYPE_BANK0, },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 805) { "in_pause", 4, 0x16, STATS_TYPE_BANK0, },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 806) { "in_undersize", 4, 0x18, STATS_TYPE_BANK0, },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 807) { "in_fragments", 4, 0x19, STATS_TYPE_BANK0, },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 808) { "in_oversize", 4, 0x1a, STATS_TYPE_BANK0, },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 809) { "in_jabber", 4, 0x1b, STATS_TYPE_BANK0, },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 810) { "in_rx_error", 4, 0x1c, STATS_TYPE_BANK0, },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 811) { "in_fcs_error", 4, 0x1d, STATS_TYPE_BANK0, },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 812) { "out_octets", 8, 0x0e, STATS_TYPE_BANK0, },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 813) { "out_unicast", 4, 0x10, STATS_TYPE_BANK0, },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 814) { "out_broadcasts", 4, 0x13, STATS_TYPE_BANK0, },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 815) { "out_multicasts", 4, 0x12, STATS_TYPE_BANK0, },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 816) { "out_pause", 4, 0x15, STATS_TYPE_BANK0, },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 817) { "excessive", 4, 0x11, STATS_TYPE_BANK0, },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 818) { "collisions", 4, 0x1e, STATS_TYPE_BANK0, },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 819) { "deferred", 4, 0x05, STATS_TYPE_BANK0, },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 820) { "single", 4, 0x14, STATS_TYPE_BANK0, },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 821) { "multiple", 4, 0x17, STATS_TYPE_BANK0, },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 822) { "out_fcs_error", 4, 0x03, STATS_TYPE_BANK0, },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 823) { "late", 4, 0x1f, STATS_TYPE_BANK0, },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 824) { "hist_64bytes", 4, 0x08, STATS_TYPE_BANK0, },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 825) { "hist_65_127bytes", 4, 0x09, STATS_TYPE_BANK0, },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 826) { "hist_128_255bytes", 4, 0x0a, STATS_TYPE_BANK0, },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 827) { "hist_256_511bytes", 4, 0x0b, STATS_TYPE_BANK0, },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 828) { "hist_512_1023bytes", 4, 0x0c, STATS_TYPE_BANK0, },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 829) { "hist_1024_max_bytes", 4, 0x0d, STATS_TYPE_BANK0, },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 830) { "sw_in_discards", 4, 0x10, STATS_TYPE_PORT, },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 831) { "sw_in_filtered", 2, 0x12, STATS_TYPE_PORT, },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 832) { "sw_out_filtered", 2, 0x13, STATS_TYPE_PORT, },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 833) { "in_discards", 4, 0x00, STATS_TYPE_BANK1, },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 834) { "in_filtered", 4, 0x01, STATS_TYPE_BANK1, },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 835) { "in_accepted", 4, 0x02, STATS_TYPE_BANK1, },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 836) { "in_bad_accepted", 4, 0x03, STATS_TYPE_BANK1, },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 837) { "in_good_avb_class_a", 4, 0x04, STATS_TYPE_BANK1, },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 838) { "in_good_avb_class_b", 4, 0x05, STATS_TYPE_BANK1, },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 839) { "in_bad_avb_class_a", 4, 0x06, STATS_TYPE_BANK1, },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 840) { "in_bad_avb_class_b", 4, 0x07, STATS_TYPE_BANK1, },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 841) { "tcam_counter_0", 4, 0x08, STATS_TYPE_BANK1, },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 842) { "tcam_counter_1", 4, 0x09, STATS_TYPE_BANK1, },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 843) { "tcam_counter_2", 4, 0x0a, STATS_TYPE_BANK1, },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 844) { "tcam_counter_3", 4, 0x0b, STATS_TYPE_BANK1, },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 845) { "in_da_unknown", 4, 0x0e, STATS_TYPE_BANK1, },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 846) { "in_management", 4, 0x0f, STATS_TYPE_BANK1, },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 847) { "out_queue_0", 4, 0x10, STATS_TYPE_BANK1, },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 848) { "out_queue_1", 4, 0x11, STATS_TYPE_BANK1, },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 849) { "out_queue_2", 4, 0x12, STATS_TYPE_BANK1, },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 850) { "out_queue_3", 4, 0x13, STATS_TYPE_BANK1, },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 851) { "out_queue_4", 4, 0x14, STATS_TYPE_BANK1, },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 852) { "out_queue_5", 4, 0x15, STATS_TYPE_BANK1, },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 853) { "out_queue_6", 4, 0x16, STATS_TYPE_BANK1, },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 854) { "out_queue_7", 4, 0x17, STATS_TYPE_BANK1, },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 855) { "out_cut_through", 4, 0x18, STATS_TYPE_BANK1, },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 856) { "out_octets_a", 4, 0x1a, STATS_TYPE_BANK1, },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 857) { "out_octets_b", 4, 0x1b, STATS_TYPE_BANK1, },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 858) { "out_management", 4, 0x1f, STATS_TYPE_BANK1, },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 859) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 860)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 861) static uint64_t _mv88e6xxx_get_ethtool_stat(struct mv88e6xxx_chip *chip,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 862) struct mv88e6xxx_hw_stat *s,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 863) int port, u16 bank1_select,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 864) u16 histogram)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 865) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 866) u32 low;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 867) u32 high = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 868) u16 reg = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 869) int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 870) u64 value;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 871)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 872) switch (s->type) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 873) case STATS_TYPE_PORT:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 874) err = mv88e6xxx_port_read(chip, port, s->reg, ®);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 875) if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 876) return U64_MAX;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 877)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 878) low = reg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 879) if (s->size == 4) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 880) err = mv88e6xxx_port_read(chip, port, s->reg + 1, ®);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 881) if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 882) return U64_MAX;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 883) low |= ((u32)reg) << 16;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 884) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 885) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 886) case STATS_TYPE_BANK1:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 887) reg = bank1_select;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 888) fallthrough;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 889) case STATS_TYPE_BANK0:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 890) reg |= s->reg | histogram;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 891) mv88e6xxx_g1_stats_read(chip, reg, &low);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 892) if (s->size == 8)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 893) mv88e6xxx_g1_stats_read(chip, reg + 1, &high);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 894) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 895) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 896) return U64_MAX;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 897) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 898) value = (((u64)high) << 32) | low;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 899) return value;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 900) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 901)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 902) static int mv88e6xxx_stats_get_strings(struct mv88e6xxx_chip *chip,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 903) uint8_t *data, int types)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 904) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 905) struct mv88e6xxx_hw_stat *stat;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 906) int i, j;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 907)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 908) for (i = 0, j = 0; i < ARRAY_SIZE(mv88e6xxx_hw_stats); i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 909) stat = &mv88e6xxx_hw_stats[i];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 910) if (stat->type & types) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 911) memcpy(data + j * ETH_GSTRING_LEN, stat->string,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 912) ETH_GSTRING_LEN);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 913) j++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 914) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 915) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 916)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 917) return j;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 918) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 919)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 920) static int mv88e6095_stats_get_strings(struct mv88e6xxx_chip *chip,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 921) uint8_t *data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 922) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 923) return mv88e6xxx_stats_get_strings(chip, data,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 924) STATS_TYPE_BANK0 | STATS_TYPE_PORT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 925) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 926)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 927) static int mv88e6250_stats_get_strings(struct mv88e6xxx_chip *chip,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 928) uint8_t *data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 929) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 930) return mv88e6xxx_stats_get_strings(chip, data, STATS_TYPE_BANK0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 931) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 932)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 933) static int mv88e6320_stats_get_strings(struct mv88e6xxx_chip *chip,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 934) uint8_t *data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 935) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 936) return mv88e6xxx_stats_get_strings(chip, data,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 937) STATS_TYPE_BANK0 | STATS_TYPE_BANK1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 938) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 939)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 940) static const uint8_t *mv88e6xxx_atu_vtu_stats_strings[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 941) "atu_member_violation",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 942) "atu_miss_violation",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 943) "atu_full_violation",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 944) "vtu_member_violation",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 945) "vtu_miss_violation",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 946) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 947)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 948) static void mv88e6xxx_atu_vtu_get_strings(uint8_t *data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 949) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 950) unsigned int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 951)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 952) for (i = 0; i < ARRAY_SIZE(mv88e6xxx_atu_vtu_stats_strings); i++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 953) strlcpy(data + i * ETH_GSTRING_LEN,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 954) mv88e6xxx_atu_vtu_stats_strings[i],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 955) ETH_GSTRING_LEN);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 956) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 957)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 958) static void mv88e6xxx_get_strings(struct dsa_switch *ds, int port,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 959) u32 stringset, uint8_t *data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 960) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 961) struct mv88e6xxx_chip *chip = ds->priv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 962) int count = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 963)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 964) if (stringset != ETH_SS_STATS)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 965) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 966)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 967) mv88e6xxx_reg_lock(chip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 968)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 969) if (chip->info->ops->stats_get_strings)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 970) count = chip->info->ops->stats_get_strings(chip, data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 971)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 972) if (chip->info->ops->serdes_get_strings) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 973) data += count * ETH_GSTRING_LEN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 974) count = chip->info->ops->serdes_get_strings(chip, port, data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 975) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 976)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 977) data += count * ETH_GSTRING_LEN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 978) mv88e6xxx_atu_vtu_get_strings(data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 979)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 980) mv88e6xxx_reg_unlock(chip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 981) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 982)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 983) static int mv88e6xxx_stats_get_sset_count(struct mv88e6xxx_chip *chip,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 984) int types)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 985) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 986) struct mv88e6xxx_hw_stat *stat;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 987) int i, j;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 988)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 989) for (i = 0, j = 0; i < ARRAY_SIZE(mv88e6xxx_hw_stats); i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 990) stat = &mv88e6xxx_hw_stats[i];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 991) if (stat->type & types)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 992) j++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 993) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 994) return j;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 995) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 996)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 997) static int mv88e6095_stats_get_sset_count(struct mv88e6xxx_chip *chip)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 998) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 999) return mv88e6xxx_stats_get_sset_count(chip, STATS_TYPE_BANK0 |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1000) STATS_TYPE_PORT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1001) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1002)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1003) static int mv88e6250_stats_get_sset_count(struct mv88e6xxx_chip *chip)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1004) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1005) return mv88e6xxx_stats_get_sset_count(chip, STATS_TYPE_BANK0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1006) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1007)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1008) static int mv88e6320_stats_get_sset_count(struct mv88e6xxx_chip *chip)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1009) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1010) return mv88e6xxx_stats_get_sset_count(chip, STATS_TYPE_BANK0 |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1011) STATS_TYPE_BANK1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1012) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1013)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1014) static int mv88e6xxx_get_sset_count(struct dsa_switch *ds, int port, int sset)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1015) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1016) struct mv88e6xxx_chip *chip = ds->priv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1017) int serdes_count = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1018) int count = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1019)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1020) if (sset != ETH_SS_STATS)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1021) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1022)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1023) mv88e6xxx_reg_lock(chip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1024) if (chip->info->ops->stats_get_sset_count)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1025) count = chip->info->ops->stats_get_sset_count(chip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1026) if (count < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1027) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1028)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1029) if (chip->info->ops->serdes_get_sset_count)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1030) serdes_count = chip->info->ops->serdes_get_sset_count(chip,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1031) port);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1032) if (serdes_count < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1033) count = serdes_count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1034) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1035) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1036) count += serdes_count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1037) count += ARRAY_SIZE(mv88e6xxx_atu_vtu_stats_strings);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1038)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1039) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1040) mv88e6xxx_reg_unlock(chip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1041)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1042) return count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1043) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1044)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1045) static int mv88e6xxx_stats_get_stats(struct mv88e6xxx_chip *chip, int port,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1046) uint64_t *data, int types,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1047) u16 bank1_select, u16 histogram)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1048) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1049) struct mv88e6xxx_hw_stat *stat;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1050) int i, j;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1051)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1052) for (i = 0, j = 0; i < ARRAY_SIZE(mv88e6xxx_hw_stats); i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1053) stat = &mv88e6xxx_hw_stats[i];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1054) if (stat->type & types) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1055) mv88e6xxx_reg_lock(chip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1056) data[j] = _mv88e6xxx_get_ethtool_stat(chip, stat, port,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1057) bank1_select,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1058) histogram);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1059) mv88e6xxx_reg_unlock(chip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1060)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1061) j++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1062) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1063) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1064) return j;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1065) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1066)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1067) static int mv88e6095_stats_get_stats(struct mv88e6xxx_chip *chip, int port,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1068) uint64_t *data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1069) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1070) return mv88e6xxx_stats_get_stats(chip, port, data,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1071) STATS_TYPE_BANK0 | STATS_TYPE_PORT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1072) 0, MV88E6XXX_G1_STATS_OP_HIST_RX_TX);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1073) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1074)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1075) static int mv88e6250_stats_get_stats(struct mv88e6xxx_chip *chip, int port,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1076) uint64_t *data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1077) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1078) return mv88e6xxx_stats_get_stats(chip, port, data, STATS_TYPE_BANK0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1079) 0, MV88E6XXX_G1_STATS_OP_HIST_RX_TX);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1080) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1081)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1082) static int mv88e6320_stats_get_stats(struct mv88e6xxx_chip *chip, int port,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1083) uint64_t *data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1084) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1085) return mv88e6xxx_stats_get_stats(chip, port, data,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1086) STATS_TYPE_BANK0 | STATS_TYPE_BANK1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1087) MV88E6XXX_G1_STATS_OP_BANK_1_BIT_9,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1088) MV88E6XXX_G1_STATS_OP_HIST_RX_TX);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1089) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1090)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1091) static int mv88e6390_stats_get_stats(struct mv88e6xxx_chip *chip, int port,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1092) uint64_t *data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1093) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1094) return mv88e6xxx_stats_get_stats(chip, port, data,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1095) STATS_TYPE_BANK0 | STATS_TYPE_BANK1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1096) MV88E6XXX_G1_STATS_OP_BANK_1_BIT_10,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1097) 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1098) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1099)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1100) static void mv88e6xxx_atu_vtu_get_stats(struct mv88e6xxx_chip *chip, int port,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1101) uint64_t *data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1102) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1103) *data++ = chip->ports[port].atu_member_violation;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1104) *data++ = chip->ports[port].atu_miss_violation;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1105) *data++ = chip->ports[port].atu_full_violation;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1106) *data++ = chip->ports[port].vtu_member_violation;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1107) *data++ = chip->ports[port].vtu_miss_violation;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1108) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1109)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1110) static void mv88e6xxx_get_stats(struct mv88e6xxx_chip *chip, int port,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1111) uint64_t *data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1112) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1113) int count = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1114)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1115) if (chip->info->ops->stats_get_stats)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1116) count = chip->info->ops->stats_get_stats(chip, port, data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1117)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1118) mv88e6xxx_reg_lock(chip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1119) if (chip->info->ops->serdes_get_stats) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1120) data += count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1121) count = chip->info->ops->serdes_get_stats(chip, port, data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1122) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1123) data += count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1124) mv88e6xxx_atu_vtu_get_stats(chip, port, data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1125) mv88e6xxx_reg_unlock(chip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1126) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1127)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1128) static void mv88e6xxx_get_ethtool_stats(struct dsa_switch *ds, int port,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1129) uint64_t *data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1130) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1131) struct mv88e6xxx_chip *chip = ds->priv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1132) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1133)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1134) mv88e6xxx_reg_lock(chip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1135)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1136) ret = mv88e6xxx_stats_snapshot(chip, port);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1137) mv88e6xxx_reg_unlock(chip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1138)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1139) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1140) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1141)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1142) mv88e6xxx_get_stats(chip, port, data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1143)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1144) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1145)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1146) static int mv88e6xxx_get_regs_len(struct dsa_switch *ds, int port)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1147) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1148) struct mv88e6xxx_chip *chip = ds->priv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1149) int len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1150)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1151) len = 32 * sizeof(u16);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1152) if (chip->info->ops->serdes_get_regs_len)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1153) len += chip->info->ops->serdes_get_regs_len(chip, port);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1154)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1155) return len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1156) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1157)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1158) static void mv88e6xxx_get_regs(struct dsa_switch *ds, int port,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1159) struct ethtool_regs *regs, void *_p)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1160) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1161) struct mv88e6xxx_chip *chip = ds->priv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1162) int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1163) u16 reg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1164) u16 *p = _p;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1165) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1166)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1167) regs->version = chip->info->prod_num;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1168)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1169) memset(p, 0xff, 32 * sizeof(u16));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1170)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1171) mv88e6xxx_reg_lock(chip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1172)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1173) for (i = 0; i < 32; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1174)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1175) err = mv88e6xxx_port_read(chip, port, i, ®);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1176) if (!err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1177) p[i] = reg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1178) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1179)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1180) if (chip->info->ops->serdes_get_regs)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1181) chip->info->ops->serdes_get_regs(chip, port, &p[i]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1182)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1183) mv88e6xxx_reg_unlock(chip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1184) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1185)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1186) static int mv88e6xxx_get_mac_eee(struct dsa_switch *ds, int port,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1187) struct ethtool_eee *e)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1188) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1189) /* Nothing to do on the port's MAC */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1190) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1191) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1192)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1193) static int mv88e6xxx_set_mac_eee(struct dsa_switch *ds, int port,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1194) struct ethtool_eee *e)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1195) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1196) /* Nothing to do on the port's MAC */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1197) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1198) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1199)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1200) /* Mask of the local ports allowed to receive frames from a given fabric port */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1201) static u16 mv88e6xxx_port_vlan(struct mv88e6xxx_chip *chip, int dev, int port)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1202) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1203) struct dsa_switch *ds = chip->ds;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1204) struct dsa_switch_tree *dst = ds->dst;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1205) struct net_device *br;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1206) struct dsa_port *dp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1207) bool found = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1208) u16 pvlan;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1209)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1210) list_for_each_entry(dp, &dst->ports, list) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1211) if (dp->ds->index == dev && dp->index == port) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1212) found = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1213) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1214) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1215) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1216)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1217) /* Prevent frames from unknown switch or port */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1218) if (!found)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1219) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1220)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1221) /* Frames from DSA links and CPU ports can egress any local port */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1222) if (dp->type == DSA_PORT_TYPE_CPU || dp->type == DSA_PORT_TYPE_DSA)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1223) return mv88e6xxx_port_mask(chip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1224)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1225) br = dp->bridge_dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1226) pvlan = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1227)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1228) /* Frames from user ports can egress any local DSA links and CPU ports,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1229) * as well as any local member of their bridge group.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1230) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1231) list_for_each_entry(dp, &dst->ports, list)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1232) if (dp->ds == ds &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1233) (dp->type == DSA_PORT_TYPE_CPU ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1234) dp->type == DSA_PORT_TYPE_DSA ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1235) (br && dp->bridge_dev == br)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1236) pvlan |= BIT(dp->index);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1237)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1238) return pvlan;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1239) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1240)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1241) static int mv88e6xxx_port_vlan_map(struct mv88e6xxx_chip *chip, int port)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1242) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1243) u16 output_ports = mv88e6xxx_port_vlan(chip, chip->ds->index, port);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1244)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1245) /* prevent frames from going back out of the port they came in on */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1246) output_ports &= ~BIT(port);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1247)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1248) return mv88e6xxx_port_set_vlan_map(chip, port, output_ports);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1249) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1250)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1251) static void mv88e6xxx_port_stp_state_set(struct dsa_switch *ds, int port,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1252) u8 state)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1253) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1254) struct mv88e6xxx_chip *chip = ds->priv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1255) int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1256)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1257) mv88e6xxx_reg_lock(chip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1258) err = mv88e6xxx_port_set_state(chip, port, state);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1259) mv88e6xxx_reg_unlock(chip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1260)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1261) if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1262) dev_err(ds->dev, "p%d: failed to update state\n", port);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1263) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1264)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1265) static int mv88e6xxx_pri_setup(struct mv88e6xxx_chip *chip)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1266) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1267) int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1268)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1269) if (chip->info->ops->ieee_pri_map) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1270) err = chip->info->ops->ieee_pri_map(chip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1271) if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1272) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1273) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1274)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1275) if (chip->info->ops->ip_pri_map) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1276) err = chip->info->ops->ip_pri_map(chip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1277) if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1278) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1279) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1280)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1281) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1282) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1283)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1284) static int mv88e6xxx_devmap_setup(struct mv88e6xxx_chip *chip)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1285) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1286) struct dsa_switch *ds = chip->ds;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1287) int target, port;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1288) int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1289)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1290) if (!chip->info->global2_addr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1291) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1292)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1293) /* Initialize the routing port to the 32 possible target devices */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1294) for (target = 0; target < 32; target++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1295) port = dsa_routing_port(ds, target);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1296) if (port == ds->num_ports)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1297) port = 0x1f;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1298)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1299) err = mv88e6xxx_g2_device_mapping_write(chip, target, port);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1300) if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1301) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1302) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1303)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1304) if (chip->info->ops->set_cascade_port) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1305) port = MV88E6XXX_CASCADE_PORT_MULTIPLE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1306) err = chip->info->ops->set_cascade_port(chip, port);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1307) if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1308) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1309) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1310)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1311) err = mv88e6xxx_g1_set_device_number(chip, chip->ds->index);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1312) if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1313) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1314)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1315) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1316) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1317)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1318) static int mv88e6xxx_trunk_setup(struct mv88e6xxx_chip *chip)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1319) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1320) /* Clear all trunk masks and mapping */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1321) if (chip->info->global2_addr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1322) return mv88e6xxx_g2_trunk_clear(chip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1323)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1324) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1325) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1326)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1327) static int mv88e6xxx_rmu_setup(struct mv88e6xxx_chip *chip)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1328) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1329) if (chip->info->ops->rmu_disable)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1330) return chip->info->ops->rmu_disable(chip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1331)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1332) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1333) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1334)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1335) static int mv88e6xxx_pot_setup(struct mv88e6xxx_chip *chip)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1336) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1337) if (chip->info->ops->pot_clear)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1338) return chip->info->ops->pot_clear(chip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1339)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1340) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1341) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1342)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1343) static int mv88e6xxx_rsvd2cpu_setup(struct mv88e6xxx_chip *chip)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1344) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1345) if (chip->info->ops->mgmt_rsvd2cpu)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1346) return chip->info->ops->mgmt_rsvd2cpu(chip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1347)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1348) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1349) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1350)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1351) static int mv88e6xxx_atu_setup(struct mv88e6xxx_chip *chip)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1352) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1353) int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1354)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1355) err = mv88e6xxx_g1_atu_flush(chip, 0, true);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1356) if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1357) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1358)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1359) err = mv88e6xxx_g1_atu_set_learn2all(chip, true);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1360) if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1361) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1362)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1363) return mv88e6xxx_g1_atu_set_age_time(chip, 300000);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1364) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1365)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1366) static int mv88e6xxx_irl_setup(struct mv88e6xxx_chip *chip)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1367) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1368) int port;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1369) int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1370)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1371) if (!chip->info->ops->irl_init_all)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1372) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1373)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1374) for (port = 0; port < mv88e6xxx_num_ports(chip); port++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1375) /* Disable ingress rate limiting by resetting all per port
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1376) * ingress rate limit resources to their initial state.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1377) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1378) err = chip->info->ops->irl_init_all(chip, port);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1379) if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1380) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1381) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1382)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1383) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1384) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1385)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1386) static int mv88e6xxx_mac_setup(struct mv88e6xxx_chip *chip)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1387) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1388) if (chip->info->ops->set_switch_mac) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1389) u8 addr[ETH_ALEN];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1390)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1391) eth_random_addr(addr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1392)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1393) return chip->info->ops->set_switch_mac(chip, addr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1394) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1395)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1396) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1397) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1398)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1399) static int mv88e6xxx_pvt_map(struct mv88e6xxx_chip *chip, int dev, int port)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1400) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1401) u16 pvlan = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1402)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1403) if (!mv88e6xxx_has_pvt(chip))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1404) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1405)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1406) /* Skip the local source device, which uses in-chip port VLAN */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1407) if (dev != chip->ds->index)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1408) pvlan = mv88e6xxx_port_vlan(chip, dev, port);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1409)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1410) return mv88e6xxx_g2_pvt_write(chip, dev, port, pvlan);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1411) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1412)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1413) static int mv88e6xxx_pvt_setup(struct mv88e6xxx_chip *chip)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1414) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1415) int dev, port;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1416) int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1417)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1418) if (!mv88e6xxx_has_pvt(chip))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1419) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1420)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1421) /* Clear 5 Bit Port for usage with Marvell Link Street devices:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1422) * use 4 bits for the Src_Port/Src_Trunk and 5 bits for the Src_Dev.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1423) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1424) err = mv88e6xxx_g2_misc_4_bit_port(chip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1425) if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1426) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1427)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1428) for (dev = 0; dev < MV88E6XXX_MAX_PVT_SWITCHES; ++dev) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1429) for (port = 0; port < MV88E6XXX_MAX_PVT_PORTS; ++port) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1430) err = mv88e6xxx_pvt_map(chip, dev, port);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1431) if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1432) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1433) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1434) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1435)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1436) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1437) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1438)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1439) static void mv88e6xxx_port_fast_age(struct dsa_switch *ds, int port)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1440) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1441) struct mv88e6xxx_chip *chip = ds->priv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1442) int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1443)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1444) mv88e6xxx_reg_lock(chip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1445) err = mv88e6xxx_g1_atu_remove(chip, 0, port, false);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1446) mv88e6xxx_reg_unlock(chip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1447)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1448) if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1449) dev_err(ds->dev, "p%d: failed to flush ATU\n", port);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1450) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1451)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1452) static int mv88e6xxx_vtu_setup(struct mv88e6xxx_chip *chip)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1453) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1454) if (!chip->info->max_vid)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1455) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1456)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1457) return mv88e6xxx_g1_vtu_flush(chip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1458) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1459)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1460) static int mv88e6xxx_vtu_getnext(struct mv88e6xxx_chip *chip,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1461) struct mv88e6xxx_vtu_entry *entry)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1462) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1463) if (!chip->info->ops->vtu_getnext)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1464) return -EOPNOTSUPP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1465)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1466) return chip->info->ops->vtu_getnext(chip, entry);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1467) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1468)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1469) static int mv88e6xxx_vtu_loadpurge(struct mv88e6xxx_chip *chip,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1470) struct mv88e6xxx_vtu_entry *entry)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1471) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1472) if (!chip->info->ops->vtu_loadpurge)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1473) return -EOPNOTSUPP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1474)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1475) return chip->info->ops->vtu_loadpurge(chip, entry);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1476) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1477)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1478) int mv88e6xxx_fid_map(struct mv88e6xxx_chip *chip, unsigned long *fid_bitmap)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1479) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1480) struct mv88e6xxx_vtu_entry vlan;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1481) int i, err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1482) u16 fid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1483)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1484) bitmap_zero(fid_bitmap, MV88E6XXX_N_FID);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1485)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1486) /* Set every FID bit used by the (un)bridged ports */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1487) for (i = 0; i < mv88e6xxx_num_ports(chip); ++i) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1488) err = mv88e6xxx_port_get_fid(chip, i, &fid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1489) if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1490) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1491)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1492) set_bit(fid, fid_bitmap);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1493) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1494)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1495) /* Set every FID bit used by the VLAN entries */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1496) vlan.vid = chip->info->max_vid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1497) vlan.valid = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1498)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1499) do {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1500) err = mv88e6xxx_vtu_getnext(chip, &vlan);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1501) if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1502) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1503)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1504) if (!vlan.valid)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1505) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1506)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1507) set_bit(vlan.fid, fid_bitmap);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1508) } while (vlan.vid < chip->info->max_vid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1509)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1510) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1511) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1512)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1513) static int mv88e6xxx_atu_new(struct mv88e6xxx_chip *chip, u16 *fid)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1514) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1515) DECLARE_BITMAP(fid_bitmap, MV88E6XXX_N_FID);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1516) int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1517)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1518) err = mv88e6xxx_fid_map(chip, fid_bitmap);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1519) if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1520) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1521)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1522) /* The reset value 0x000 is used to indicate that multiple address
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1523) * databases are not needed. Return the next positive available.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1524) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1525) *fid = find_next_zero_bit(fid_bitmap, MV88E6XXX_N_FID, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1526) if (unlikely(*fid >= mv88e6xxx_num_databases(chip)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1527) return -ENOSPC;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1528)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1529) /* Clear the database */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1530) return mv88e6xxx_g1_atu_flush(chip, *fid, true);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1531) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1532)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1533) static int mv88e6xxx_port_check_hw_vlan(struct dsa_switch *ds, int port,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1534) u16 vid_begin, u16 vid_end)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1535) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1536) struct mv88e6xxx_chip *chip = ds->priv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1537) struct mv88e6xxx_vtu_entry vlan;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1538) int i, err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1539)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1540) /* DSA and CPU ports have to be members of multiple vlans */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1541) if (dsa_is_dsa_port(ds, port) || dsa_is_cpu_port(ds, port))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1542) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1543)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1544) if (!vid_begin)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1545) return -EOPNOTSUPP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1546)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1547) vlan.vid = vid_begin - 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1548) vlan.valid = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1549)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1550) do {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1551) err = mv88e6xxx_vtu_getnext(chip, &vlan);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1552) if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1553) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1554)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1555) if (!vlan.valid)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1556) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1557)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1558) if (vlan.vid > vid_end)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1559) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1560)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1561) for (i = 0; i < mv88e6xxx_num_ports(chip); ++i) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1562) if (dsa_is_dsa_port(ds, i) || dsa_is_cpu_port(ds, i))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1563) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1564)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1565) if (!dsa_to_port(ds, i)->slave)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1566) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1567)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1568) if (vlan.member[i] ==
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1569) MV88E6XXX_G1_VTU_DATA_MEMBER_TAG_NON_MEMBER)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1570) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1571)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1572) if (dsa_to_port(ds, i)->bridge_dev ==
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1573) dsa_to_port(ds, port)->bridge_dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1574) break; /* same bridge, check next VLAN */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1575)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1576) if (!dsa_to_port(ds, i)->bridge_dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1577) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1578)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1579) dev_err(ds->dev, "p%d: hw VLAN %d already used by port %d in %s\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1580) port, vlan.vid, i,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1581) netdev_name(dsa_to_port(ds, i)->bridge_dev));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1582) return -EOPNOTSUPP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1583) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1584) } while (vlan.vid < vid_end);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1585)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1586) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1587) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1588)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1589) static int mv88e6xxx_port_vlan_filtering(struct dsa_switch *ds, int port,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1590) bool vlan_filtering,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1591) struct switchdev_trans *trans)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1592) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1593) struct mv88e6xxx_chip *chip = ds->priv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1594) u16 mode = vlan_filtering ? MV88E6XXX_PORT_CTL2_8021Q_MODE_SECURE :
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1595) MV88E6XXX_PORT_CTL2_8021Q_MODE_DISABLED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1596) int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1597)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1598) if (switchdev_trans_ph_prepare(trans))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1599) return chip->info->max_vid ? 0 : -EOPNOTSUPP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1600)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1601) mv88e6xxx_reg_lock(chip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1602) err = mv88e6xxx_port_set_8021q_mode(chip, port, mode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1603) mv88e6xxx_reg_unlock(chip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1604)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1605) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1606) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1607)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1608) static int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1609) mv88e6xxx_port_vlan_prepare(struct dsa_switch *ds, int port,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1610) const struct switchdev_obj_port_vlan *vlan)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1611) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1612) struct mv88e6xxx_chip *chip = ds->priv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1613) int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1614)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1615) if (!chip->info->max_vid)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1616) return -EOPNOTSUPP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1617)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1618) /* If the requested port doesn't belong to the same bridge as the VLAN
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1619) * members, do not support it (yet) and fallback to software VLAN.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1620) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1621) mv88e6xxx_reg_lock(chip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1622) err = mv88e6xxx_port_check_hw_vlan(ds, port, vlan->vid_begin,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1623) vlan->vid_end);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1624) mv88e6xxx_reg_unlock(chip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1625)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1626) /* We don't need any dynamic resource from the kernel (yet),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1627) * so skip the prepare phase.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1628) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1629) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1630) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1631)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1632) static int mv88e6xxx_port_db_load_purge(struct mv88e6xxx_chip *chip, int port,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1633) const unsigned char *addr, u16 vid,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1634) u8 state)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1635) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1636) struct mv88e6xxx_atu_entry entry;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1637) struct mv88e6xxx_vtu_entry vlan;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1638) u16 fid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1639) int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1640)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1641) /* Null VLAN ID corresponds to the port private database */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1642) if (vid == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1643) err = mv88e6xxx_port_get_fid(chip, port, &fid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1644) if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1645) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1646) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1647) vlan.vid = vid - 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1648) vlan.valid = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1649)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1650) err = mv88e6xxx_vtu_getnext(chip, &vlan);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1651) if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1652) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1653)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1654) /* switchdev expects -EOPNOTSUPP to honor software VLANs */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1655) if (vlan.vid != vid || !vlan.valid)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1656) return -EOPNOTSUPP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1657)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1658) fid = vlan.fid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1659) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1660)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1661) entry.state = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1662) ether_addr_copy(entry.mac, addr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1663) eth_addr_dec(entry.mac);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1664)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1665) err = mv88e6xxx_g1_atu_getnext(chip, fid, &entry);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1666) if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1667) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1668)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1669) /* Initialize a fresh ATU entry if it isn't found */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1670) if (!entry.state || !ether_addr_equal(entry.mac, addr)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1671) memset(&entry, 0, sizeof(entry));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1672) ether_addr_copy(entry.mac, addr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1673) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1674)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1675) /* Purge the ATU entry only if no port is using it anymore */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1676) if (!state) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1677) entry.portvec &= ~BIT(port);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1678) if (!entry.portvec)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1679) entry.state = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1680) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1681) if (state == MV88E6XXX_G1_ATU_DATA_STATE_UC_STATIC)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1682) entry.portvec = BIT(port);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1683) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1684) entry.portvec |= BIT(port);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1685)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1686) entry.state = state;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1687) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1688)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1689) return mv88e6xxx_g1_atu_loadpurge(chip, fid, &entry);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1690) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1691)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1692) static int mv88e6xxx_policy_apply(struct mv88e6xxx_chip *chip, int port,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1693) const struct mv88e6xxx_policy *policy)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1694) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1695) enum mv88e6xxx_policy_mapping mapping = policy->mapping;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1696) enum mv88e6xxx_policy_action action = policy->action;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1697) const u8 *addr = policy->addr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1698) u16 vid = policy->vid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1699) u8 state;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1700) int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1701) int id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1702)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1703) if (!chip->info->ops->port_set_policy)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1704) return -EOPNOTSUPP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1705)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1706) switch (mapping) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1707) case MV88E6XXX_POLICY_MAPPING_DA:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1708) case MV88E6XXX_POLICY_MAPPING_SA:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1709) if (action == MV88E6XXX_POLICY_ACTION_NORMAL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1710) state = 0; /* Dissociate the port and address */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1711) else if (action == MV88E6XXX_POLICY_ACTION_DISCARD &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1712) is_multicast_ether_addr(addr))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1713) state = MV88E6XXX_G1_ATU_DATA_STATE_MC_STATIC_POLICY;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1714) else if (action == MV88E6XXX_POLICY_ACTION_DISCARD &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1715) is_unicast_ether_addr(addr))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1716) state = MV88E6XXX_G1_ATU_DATA_STATE_UC_STATIC_POLICY;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1717) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1718) return -EOPNOTSUPP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1719)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1720) err = mv88e6xxx_port_db_load_purge(chip, port, addr, vid,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1721) state);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1722) if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1723) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1724) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1725) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1726) return -EOPNOTSUPP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1727) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1728)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1729) /* Skip the port's policy clearing if the mapping is still in use */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1730) if (action == MV88E6XXX_POLICY_ACTION_NORMAL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1731) idr_for_each_entry(&chip->policies, policy, id)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1732) if (policy->port == port &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1733) policy->mapping == mapping &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1734) policy->action != action)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1735) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1736)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1737) return chip->info->ops->port_set_policy(chip, port, mapping, action);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1738) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1739)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1740) static int mv88e6xxx_policy_insert(struct mv88e6xxx_chip *chip, int port,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1741) struct ethtool_rx_flow_spec *fs)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1742) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1743) struct ethhdr *mac_entry = &fs->h_u.ether_spec;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1744) struct ethhdr *mac_mask = &fs->m_u.ether_spec;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1745) enum mv88e6xxx_policy_mapping mapping;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1746) enum mv88e6xxx_policy_action action;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1747) struct mv88e6xxx_policy *policy;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1748) u16 vid = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1749) u8 *addr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1750) int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1751) int id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1752)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1753) if (fs->location != RX_CLS_LOC_ANY)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1754) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1755)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1756) if (fs->ring_cookie == RX_CLS_FLOW_DISC)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1757) action = MV88E6XXX_POLICY_ACTION_DISCARD;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1758) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1759) return -EOPNOTSUPP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1760)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1761) switch (fs->flow_type & ~FLOW_EXT) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1762) case ETHER_FLOW:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1763) if (!is_zero_ether_addr(mac_mask->h_dest) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1764) is_zero_ether_addr(mac_mask->h_source)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1765) mapping = MV88E6XXX_POLICY_MAPPING_DA;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1766) addr = mac_entry->h_dest;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1767) } else if (is_zero_ether_addr(mac_mask->h_dest) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1768) !is_zero_ether_addr(mac_mask->h_source)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1769) mapping = MV88E6XXX_POLICY_MAPPING_SA;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1770) addr = mac_entry->h_source;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1771) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1772) /* Cannot support DA and SA mapping in the same rule */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1773) return -EOPNOTSUPP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1774) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1775) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1776) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1777) return -EOPNOTSUPP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1778) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1779)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1780) if ((fs->flow_type & FLOW_EXT) && fs->m_ext.vlan_tci) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1781) if (fs->m_ext.vlan_tci != htons(0xffff))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1782) return -EOPNOTSUPP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1783) vid = be16_to_cpu(fs->h_ext.vlan_tci) & VLAN_VID_MASK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1784) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1785)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1786) idr_for_each_entry(&chip->policies, policy, id) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1787) if (policy->port == port && policy->mapping == mapping &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1788) policy->action == action && policy->vid == vid &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1789) ether_addr_equal(policy->addr, addr))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1790) return -EEXIST;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1791) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1792)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1793) policy = devm_kzalloc(chip->dev, sizeof(*policy), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1794) if (!policy)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1795) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1796)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1797) fs->location = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1798) err = idr_alloc_u32(&chip->policies, policy, &fs->location, 0xffffffff,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1799) GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1800) if (err) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1801) devm_kfree(chip->dev, policy);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1802) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1803) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1804)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1805) memcpy(&policy->fs, fs, sizeof(*fs));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1806) ether_addr_copy(policy->addr, addr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1807) policy->mapping = mapping;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1808) policy->action = action;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1809) policy->port = port;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1810) policy->vid = vid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1811)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1812) err = mv88e6xxx_policy_apply(chip, port, policy);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1813) if (err) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1814) idr_remove(&chip->policies, fs->location);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1815) devm_kfree(chip->dev, policy);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1816) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1817) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1818)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1819) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1820) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1821)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1822) static int mv88e6xxx_get_rxnfc(struct dsa_switch *ds, int port,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1823) struct ethtool_rxnfc *rxnfc, u32 *rule_locs)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1824) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1825) struct ethtool_rx_flow_spec *fs = &rxnfc->fs;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1826) struct mv88e6xxx_chip *chip = ds->priv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1827) struct mv88e6xxx_policy *policy;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1828) int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1829) int id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1830)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1831) mv88e6xxx_reg_lock(chip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1832)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1833) switch (rxnfc->cmd) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1834) case ETHTOOL_GRXCLSRLCNT:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1835) rxnfc->data = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1836) rxnfc->data |= RX_CLS_LOC_SPECIAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1837) rxnfc->rule_cnt = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1838) idr_for_each_entry(&chip->policies, policy, id)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1839) if (policy->port == port)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1840) rxnfc->rule_cnt++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1841) err = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1842) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1843) case ETHTOOL_GRXCLSRULE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1844) err = -ENOENT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1845) policy = idr_find(&chip->policies, fs->location);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1846) if (policy) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1847) memcpy(fs, &policy->fs, sizeof(*fs));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1848) err = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1849) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1850) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1851) case ETHTOOL_GRXCLSRLALL:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1852) rxnfc->data = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1853) rxnfc->rule_cnt = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1854) idr_for_each_entry(&chip->policies, policy, id)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1855) if (policy->port == port)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1856) rule_locs[rxnfc->rule_cnt++] = id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1857) err = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1858) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1859) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1860) err = -EOPNOTSUPP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1861) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1862) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1863)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1864) mv88e6xxx_reg_unlock(chip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1865)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1866) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1867) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1868)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1869) static int mv88e6xxx_set_rxnfc(struct dsa_switch *ds, int port,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1870) struct ethtool_rxnfc *rxnfc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1871) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1872) struct ethtool_rx_flow_spec *fs = &rxnfc->fs;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1873) struct mv88e6xxx_chip *chip = ds->priv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1874) struct mv88e6xxx_policy *policy;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1875) int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1876)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1877) mv88e6xxx_reg_lock(chip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1878)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1879) switch (rxnfc->cmd) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1880) case ETHTOOL_SRXCLSRLINS:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1881) err = mv88e6xxx_policy_insert(chip, port, fs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1882) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1883) case ETHTOOL_SRXCLSRLDEL:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1884) err = -ENOENT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1885) policy = idr_remove(&chip->policies, fs->location);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1886) if (policy) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1887) policy->action = MV88E6XXX_POLICY_ACTION_NORMAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1888) err = mv88e6xxx_policy_apply(chip, port, policy);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1889) devm_kfree(chip->dev, policy);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1890) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1891) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1892) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1893) err = -EOPNOTSUPP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1894) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1895) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1896)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1897) mv88e6xxx_reg_unlock(chip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1898)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1899) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1900) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1901)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1902) static int mv88e6xxx_port_add_broadcast(struct mv88e6xxx_chip *chip, int port,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1903) u16 vid)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1904) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1905) const char broadcast[6] = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1906) u8 state = MV88E6XXX_G1_ATU_DATA_STATE_MC_STATIC;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1907)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1908) return mv88e6xxx_port_db_load_purge(chip, port, broadcast, vid, state);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1909) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1910)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1911) static int mv88e6xxx_broadcast_setup(struct mv88e6xxx_chip *chip, u16 vid)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1912) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1913) int port;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1914) int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1915)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1916) for (port = 0; port < mv88e6xxx_num_ports(chip); port++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1917) err = mv88e6xxx_port_add_broadcast(chip, port, vid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1918) if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1919) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1920) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1921)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1922) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1923) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1924)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1925) static int mv88e6xxx_port_vlan_join(struct mv88e6xxx_chip *chip, int port,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1926) u16 vid, u8 member, bool warn)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1927) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1928) const u8 non_member = MV88E6XXX_G1_VTU_DATA_MEMBER_TAG_NON_MEMBER;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1929) struct mv88e6xxx_vtu_entry vlan;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1930) int i, err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1931)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1932) if (!vid)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1933) return -EOPNOTSUPP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1934)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1935) vlan.vid = vid - 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1936) vlan.valid = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1937)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1938) err = mv88e6xxx_vtu_getnext(chip, &vlan);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1939) if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1940) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1941)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1942) if (vlan.vid != vid || !vlan.valid) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1943) memset(&vlan, 0, sizeof(vlan));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1944)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1945) err = mv88e6xxx_atu_new(chip, &vlan.fid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1946) if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1947) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1948)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1949) for (i = 0; i < mv88e6xxx_num_ports(chip); ++i)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1950) if (i == port)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1951) vlan.member[i] = member;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1952) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1953) vlan.member[i] = non_member;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1954)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1955) vlan.vid = vid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1956) vlan.valid = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1957)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1958) err = mv88e6xxx_vtu_loadpurge(chip, &vlan);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1959) if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1960) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1961)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1962) err = mv88e6xxx_broadcast_setup(chip, vlan.vid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1963) if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1964) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1965) } else if (vlan.member[port] != member) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1966) vlan.member[port] = member;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1967)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1968) err = mv88e6xxx_vtu_loadpurge(chip, &vlan);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1969) if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1970) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1971) } else if (warn) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1972) dev_info(chip->dev, "p%d: already a member of VLAN %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1973) port, vid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1974) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1975)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1976) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1977) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1978)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1979) static void mv88e6xxx_port_vlan_add(struct dsa_switch *ds, int port,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1980) const struct switchdev_obj_port_vlan *vlan)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1981) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1982) struct mv88e6xxx_chip *chip = ds->priv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1983) bool untagged = vlan->flags & BRIDGE_VLAN_INFO_UNTAGGED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1984) bool pvid = vlan->flags & BRIDGE_VLAN_INFO_PVID;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1985) bool warn;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1986) u8 member;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1987) u16 vid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1988)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1989) if (!chip->info->max_vid)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1990) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1991)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1992) if (dsa_is_dsa_port(ds, port) || dsa_is_cpu_port(ds, port))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1993) member = MV88E6XXX_G1_VTU_DATA_MEMBER_TAG_UNMODIFIED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1994) else if (untagged)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1995) member = MV88E6XXX_G1_VTU_DATA_MEMBER_TAG_UNTAGGED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1996) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1997) member = MV88E6XXX_G1_VTU_DATA_MEMBER_TAG_TAGGED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1998)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1999) /* net/dsa/slave.c will call dsa_port_vlan_add() for the affected port
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2000) * and then the CPU port. Do not warn for duplicates for the CPU port.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2001) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2002) warn = !dsa_is_cpu_port(ds, port) && !dsa_is_dsa_port(ds, port);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2003)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2004) mv88e6xxx_reg_lock(chip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2005)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2006) for (vid = vlan->vid_begin; vid <= vlan->vid_end; ++vid)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2007) if (mv88e6xxx_port_vlan_join(chip, port, vid, member, warn))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2008) dev_err(ds->dev, "p%d: failed to add VLAN %d%c\n", port,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2009) vid, untagged ? 'u' : 't');
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2010)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2011) if (pvid && mv88e6xxx_port_set_pvid(chip, port, vlan->vid_end))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2012) dev_err(ds->dev, "p%d: failed to set PVID %d\n", port,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2013) vlan->vid_end);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2014)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2015) mv88e6xxx_reg_unlock(chip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2016) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2017)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2018) static int mv88e6xxx_port_vlan_leave(struct mv88e6xxx_chip *chip,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2019) int port, u16 vid)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2020) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2021) struct mv88e6xxx_vtu_entry vlan;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2022) int i, err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2023)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2024) if (!vid)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2025) return -EOPNOTSUPP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2026)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2027) vlan.vid = vid - 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2028) vlan.valid = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2029)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2030) err = mv88e6xxx_vtu_getnext(chip, &vlan);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2031) if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2032) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2033)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2034) /* If the VLAN doesn't exist in hardware or the port isn't a member,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2035) * tell switchdev that this VLAN is likely handled in software.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2036) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2037) if (vlan.vid != vid || !vlan.valid ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2038) vlan.member[port] == MV88E6XXX_G1_VTU_DATA_MEMBER_TAG_NON_MEMBER)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2039) return -EOPNOTSUPP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2040)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2041) vlan.member[port] = MV88E6XXX_G1_VTU_DATA_MEMBER_TAG_NON_MEMBER;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2042)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2043) /* keep the VLAN unless all ports are excluded */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2044) vlan.valid = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2045) for (i = 0; i < mv88e6xxx_num_ports(chip); ++i) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2046) if (vlan.member[i] !=
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2047) MV88E6XXX_G1_VTU_DATA_MEMBER_TAG_NON_MEMBER) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2048) vlan.valid = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2049) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2050) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2051) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2052)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2053) err = mv88e6xxx_vtu_loadpurge(chip, &vlan);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2054) if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2055) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2056)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2057) return mv88e6xxx_g1_atu_remove(chip, vlan.fid, port, false);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2058) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2059)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2060) static int mv88e6xxx_port_vlan_del(struct dsa_switch *ds, int port,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2061) const struct switchdev_obj_port_vlan *vlan)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2062) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2063) struct mv88e6xxx_chip *chip = ds->priv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2064) u16 pvid, vid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2065) int err = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2066)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2067) if (!chip->info->max_vid)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2068) return -EOPNOTSUPP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2069)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2070) mv88e6xxx_reg_lock(chip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2071)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2072) err = mv88e6xxx_port_get_pvid(chip, port, &pvid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2073) if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2074) goto unlock;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2075)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2076) for (vid = vlan->vid_begin; vid <= vlan->vid_end; ++vid) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2077) err = mv88e6xxx_port_vlan_leave(chip, port, vid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2078) if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2079) goto unlock;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2080)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2081) if (vid == pvid) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2082) err = mv88e6xxx_port_set_pvid(chip, port, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2083) if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2084) goto unlock;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2085) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2086) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2087)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2088) unlock:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2089) mv88e6xxx_reg_unlock(chip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2090)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2091) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2092) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2093)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2094) static int mv88e6xxx_port_fdb_add(struct dsa_switch *ds, int port,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2095) const unsigned char *addr, u16 vid)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2096) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2097) struct mv88e6xxx_chip *chip = ds->priv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2098) int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2099)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2100) mv88e6xxx_reg_lock(chip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2101) err = mv88e6xxx_port_db_load_purge(chip, port, addr, vid,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2102) MV88E6XXX_G1_ATU_DATA_STATE_UC_STATIC);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2103) mv88e6xxx_reg_unlock(chip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2104)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2105) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2106) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2107)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2108) static int mv88e6xxx_port_fdb_del(struct dsa_switch *ds, int port,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2109) const unsigned char *addr, u16 vid)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2110) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2111) struct mv88e6xxx_chip *chip = ds->priv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2112) int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2113)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2114) mv88e6xxx_reg_lock(chip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2115) err = mv88e6xxx_port_db_load_purge(chip, port, addr, vid, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2116) mv88e6xxx_reg_unlock(chip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2117)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2118) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2119) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2120)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2121) static int mv88e6xxx_port_db_dump_fid(struct mv88e6xxx_chip *chip,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2122) u16 fid, u16 vid, int port,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2123) dsa_fdb_dump_cb_t *cb, void *data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2124) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2125) struct mv88e6xxx_atu_entry addr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2126) bool is_static;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2127) int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2128)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2129) addr.state = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2130) eth_broadcast_addr(addr.mac);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2131)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2132) do {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2133) err = mv88e6xxx_g1_atu_getnext(chip, fid, &addr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2134) if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2135) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2136)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2137) if (!addr.state)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2138) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2139)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2140) if (addr.trunk || (addr.portvec & BIT(port)) == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2141) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2142)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2143) if (!is_unicast_ether_addr(addr.mac))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2144) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2145)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2146) is_static = (addr.state ==
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2147) MV88E6XXX_G1_ATU_DATA_STATE_UC_STATIC);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2148) err = cb(addr.mac, vid, is_static, data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2149) if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2150) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2151) } while (!is_broadcast_ether_addr(addr.mac));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2152)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2153) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2154) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2155)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2156) static int mv88e6xxx_port_db_dump(struct mv88e6xxx_chip *chip, int port,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2157) dsa_fdb_dump_cb_t *cb, void *data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2158) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2159) struct mv88e6xxx_vtu_entry vlan;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2160) u16 fid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2161) int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2162)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2163) /* Dump port's default Filtering Information Database (VLAN ID 0) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2164) err = mv88e6xxx_port_get_fid(chip, port, &fid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2165) if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2166) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2167)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2168) err = mv88e6xxx_port_db_dump_fid(chip, fid, 0, port, cb, data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2169) if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2170) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2171)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2172) /* Dump VLANs' Filtering Information Databases */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2173) vlan.vid = chip->info->max_vid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2174) vlan.valid = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2175)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2176) do {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2177) err = mv88e6xxx_vtu_getnext(chip, &vlan);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2178) if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2179) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2180)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2181) if (!vlan.valid)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2182) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2183)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2184) err = mv88e6xxx_port_db_dump_fid(chip, vlan.fid, vlan.vid, port,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2185) cb, data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2186) if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2187) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2188) } while (vlan.vid < chip->info->max_vid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2189)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2190) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2191) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2192)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2193) static int mv88e6xxx_port_fdb_dump(struct dsa_switch *ds, int port,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2194) dsa_fdb_dump_cb_t *cb, void *data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2195) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2196) struct mv88e6xxx_chip *chip = ds->priv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2197) int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2198)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2199) mv88e6xxx_reg_lock(chip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2200) err = mv88e6xxx_port_db_dump(chip, port, cb, data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2201) mv88e6xxx_reg_unlock(chip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2202)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2203) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2204) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2205)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2206) static int mv88e6xxx_bridge_map(struct mv88e6xxx_chip *chip,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2207) struct net_device *br)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2208) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2209) struct dsa_switch *ds = chip->ds;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2210) struct dsa_switch_tree *dst = ds->dst;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2211) struct dsa_port *dp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2212) int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2213)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2214) list_for_each_entry(dp, &dst->ports, list) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2215) if (dp->bridge_dev == br) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2216) if (dp->ds == ds) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2217) /* This is a local bridge group member,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2218) * remap its Port VLAN Map.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2219) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2220) err = mv88e6xxx_port_vlan_map(chip, dp->index);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2221) if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2222) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2223) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2224) /* This is an external bridge group member,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2225) * remap its cross-chip Port VLAN Table entry.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2226) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2227) err = mv88e6xxx_pvt_map(chip, dp->ds->index,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2228) dp->index);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2229) if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2230) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2231) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2232) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2233) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2234)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2235) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2236) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2237)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2238) static int mv88e6xxx_port_bridge_join(struct dsa_switch *ds, int port,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2239) struct net_device *br)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2240) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2241) struct mv88e6xxx_chip *chip = ds->priv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2242) int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2243)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2244) mv88e6xxx_reg_lock(chip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2245) err = mv88e6xxx_bridge_map(chip, br);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2246) mv88e6xxx_reg_unlock(chip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2247)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2248) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2249) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2250)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2251) static void mv88e6xxx_port_bridge_leave(struct dsa_switch *ds, int port,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2252) struct net_device *br)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2253) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2254) struct mv88e6xxx_chip *chip = ds->priv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2255)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2256) mv88e6xxx_reg_lock(chip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2257) if (mv88e6xxx_bridge_map(chip, br) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2258) mv88e6xxx_port_vlan_map(chip, port))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2259) dev_err(ds->dev, "failed to remap in-chip Port VLAN\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2260) mv88e6xxx_reg_unlock(chip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2261) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2262)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2263) static int mv88e6xxx_crosschip_bridge_join(struct dsa_switch *ds,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2264) int tree_index, int sw_index,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2265) int port, struct net_device *br)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2266) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2267) struct mv88e6xxx_chip *chip = ds->priv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2268) int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2269)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2270) if (tree_index != ds->dst->index)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2271) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2272)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2273) mv88e6xxx_reg_lock(chip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2274) err = mv88e6xxx_pvt_map(chip, sw_index, port);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2275) mv88e6xxx_reg_unlock(chip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2276)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2277) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2278) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2279)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2280) static void mv88e6xxx_crosschip_bridge_leave(struct dsa_switch *ds,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2281) int tree_index, int sw_index,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2282) int port, struct net_device *br)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2283) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2284) struct mv88e6xxx_chip *chip = ds->priv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2285)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2286) if (tree_index != ds->dst->index)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2287) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2288)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2289) mv88e6xxx_reg_lock(chip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2290) if (mv88e6xxx_pvt_map(chip, sw_index, port))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2291) dev_err(ds->dev, "failed to remap cross-chip Port VLAN\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2292) mv88e6xxx_reg_unlock(chip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2293) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2294)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2295) static int mv88e6xxx_software_reset(struct mv88e6xxx_chip *chip)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2296) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2297) if (chip->info->ops->reset)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2298) return chip->info->ops->reset(chip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2299)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2300) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2301) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2302)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2303) static void mv88e6xxx_hardware_reset(struct mv88e6xxx_chip *chip)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2304) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2305) struct gpio_desc *gpiod = chip->reset;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2306)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2307) /* If there is a GPIO connected to the reset pin, toggle it */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2308) if (gpiod) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2309) gpiod_set_value_cansleep(gpiod, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2310) usleep_range(10000, 20000);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2311) gpiod_set_value_cansleep(gpiod, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2312) usleep_range(10000, 20000);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2313)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2314) mv88e6xxx_g1_wait_eeprom_done(chip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2315) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2316) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2317)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2318) static int mv88e6xxx_disable_ports(struct mv88e6xxx_chip *chip)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2319) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2320) int i, err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2321)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2322) /* Set all ports to the Disabled state */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2323) for (i = 0; i < mv88e6xxx_num_ports(chip); i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2324) err = mv88e6xxx_port_set_state(chip, i, BR_STATE_DISABLED);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2325) if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2326) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2327) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2328)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2329) /* Wait for transmit queues to drain,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2330) * i.e. 2ms for a maximum frame to be transmitted at 10 Mbps.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2331) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2332) usleep_range(2000, 4000);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2333)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2334) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2335) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2336)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2337) static int mv88e6xxx_switch_reset(struct mv88e6xxx_chip *chip)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2338) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2339) int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2340)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2341) err = mv88e6xxx_disable_ports(chip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2342) if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2343) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2344)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2345) mv88e6xxx_hardware_reset(chip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2346)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2347) return mv88e6xxx_software_reset(chip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2348) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2349)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2350) static int mv88e6xxx_set_port_mode(struct mv88e6xxx_chip *chip, int port,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2351) enum mv88e6xxx_frame_mode frame,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2352) enum mv88e6xxx_egress_mode egress, u16 etype)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2353) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2354) int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2355)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2356) if (!chip->info->ops->port_set_frame_mode)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2357) return -EOPNOTSUPP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2358)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2359) err = mv88e6xxx_port_set_egress_mode(chip, port, egress);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2360) if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2361) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2362)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2363) err = chip->info->ops->port_set_frame_mode(chip, port, frame);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2364) if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2365) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2366)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2367) if (chip->info->ops->port_set_ether_type)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2368) return chip->info->ops->port_set_ether_type(chip, port, etype);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2369)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2370) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2371) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2372)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2373) static int mv88e6xxx_set_port_mode_normal(struct mv88e6xxx_chip *chip, int port)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2374) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2375) return mv88e6xxx_set_port_mode(chip, port, MV88E6XXX_FRAME_MODE_NORMAL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2376) MV88E6XXX_EGRESS_MODE_UNMODIFIED,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2377) MV88E6XXX_PORT_ETH_TYPE_DEFAULT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2378) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2379)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2380) static int mv88e6xxx_set_port_mode_dsa(struct mv88e6xxx_chip *chip, int port)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2381) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2382) return mv88e6xxx_set_port_mode(chip, port, MV88E6XXX_FRAME_MODE_DSA,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2383) MV88E6XXX_EGRESS_MODE_UNMODIFIED,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2384) MV88E6XXX_PORT_ETH_TYPE_DEFAULT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2385) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2386)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2387) static int mv88e6xxx_set_port_mode_edsa(struct mv88e6xxx_chip *chip, int port)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2388) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2389) return mv88e6xxx_set_port_mode(chip, port,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2390) MV88E6XXX_FRAME_MODE_ETHERTYPE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2391) MV88E6XXX_EGRESS_MODE_ETHERTYPE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2392) ETH_P_EDSA);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2393) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2394)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2395) static int mv88e6xxx_setup_port_mode(struct mv88e6xxx_chip *chip, int port)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2396) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2397) if (dsa_is_dsa_port(chip->ds, port))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2398) return mv88e6xxx_set_port_mode_dsa(chip, port);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2399)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2400) if (dsa_is_user_port(chip->ds, port))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2401) return mv88e6xxx_set_port_mode_normal(chip, port);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2402)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2403) /* Setup CPU port mode depending on its supported tag format */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2404) if (chip->info->tag_protocol == DSA_TAG_PROTO_DSA)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2405) return mv88e6xxx_set_port_mode_dsa(chip, port);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2406)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2407) if (chip->info->tag_protocol == DSA_TAG_PROTO_EDSA)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2408) return mv88e6xxx_set_port_mode_edsa(chip, port);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2409)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2410) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2411) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2412)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2413) static int mv88e6xxx_setup_message_port(struct mv88e6xxx_chip *chip, int port)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2414) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2415) bool message = dsa_is_dsa_port(chip->ds, port);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2416)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2417) return mv88e6xxx_port_set_message_port(chip, port, message);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2418) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2419)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2420) static int mv88e6xxx_setup_egress_floods(struct mv88e6xxx_chip *chip, int port)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2421) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2422) struct dsa_switch *ds = chip->ds;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2423) bool flood;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2424)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2425) /* Upstream ports flood frames with unknown unicast or multicast DA */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2426) flood = dsa_is_cpu_port(ds, port) || dsa_is_dsa_port(ds, port);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2427) if (chip->info->ops->port_set_egress_floods)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2428) return chip->info->ops->port_set_egress_floods(chip, port,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2429) flood, flood);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2430)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2431) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2432) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2433)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2434) static irqreturn_t mv88e6xxx_serdes_irq_thread_fn(int irq, void *dev_id)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2435) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2436) struct mv88e6xxx_port *mvp = dev_id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2437) struct mv88e6xxx_chip *chip = mvp->chip;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2438) irqreturn_t ret = IRQ_NONE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2439) int port = mvp->port;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2440) u8 lane;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2441)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2442) mv88e6xxx_reg_lock(chip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2443) lane = mv88e6xxx_serdes_get_lane(chip, port);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2444) if (lane)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2445) ret = mv88e6xxx_serdes_irq_status(chip, port, lane);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2446) mv88e6xxx_reg_unlock(chip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2447)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2448) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2449) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2450)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2451) static int mv88e6xxx_serdes_irq_request(struct mv88e6xxx_chip *chip, int port,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2452) u8 lane)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2453) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2454) struct mv88e6xxx_port *dev_id = &chip->ports[port];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2455) unsigned int irq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2456) int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2457)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2458) /* Nothing to request if this SERDES port has no IRQ */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2459) irq = mv88e6xxx_serdes_irq_mapping(chip, port);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2460) if (!irq)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2461) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2462)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2463) snprintf(dev_id->serdes_irq_name, sizeof(dev_id->serdes_irq_name),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2464) "mv88e6xxx-%s-serdes-%d", dev_name(chip->dev), port);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2465)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2466) /* Requesting the IRQ will trigger IRQ callbacks, so release the lock */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2467) mv88e6xxx_reg_unlock(chip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2468) err = request_threaded_irq(irq, NULL, mv88e6xxx_serdes_irq_thread_fn,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2469) IRQF_ONESHOT, dev_id->serdes_irq_name,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2470) dev_id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2471) mv88e6xxx_reg_lock(chip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2472) if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2473) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2474)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2475) dev_id->serdes_irq = irq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2476)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2477) return mv88e6xxx_serdes_irq_enable(chip, port, lane);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2478) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2479)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2480) static int mv88e6xxx_serdes_irq_free(struct mv88e6xxx_chip *chip, int port,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2481) u8 lane)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2482) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2483) struct mv88e6xxx_port *dev_id = &chip->ports[port];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2484) unsigned int irq = dev_id->serdes_irq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2485) int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2486)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2487) /* Nothing to free if no IRQ has been requested */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2488) if (!irq)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2489) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2490)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2491) err = mv88e6xxx_serdes_irq_disable(chip, port, lane);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2492)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2493) /* Freeing the IRQ will trigger IRQ callbacks, so release the lock */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2494) mv88e6xxx_reg_unlock(chip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2495) free_irq(irq, dev_id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2496) mv88e6xxx_reg_lock(chip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2497)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2498) dev_id->serdes_irq = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2499)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2500) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2501) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2502)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2503) static int mv88e6xxx_serdes_power(struct mv88e6xxx_chip *chip, int port,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2504) bool on)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2505) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2506) u8 lane;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2507) int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2508)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2509) lane = mv88e6xxx_serdes_get_lane(chip, port);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2510) if (!lane)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2511) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2512)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2513) if (on) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2514) err = mv88e6xxx_serdes_power_up(chip, port, lane);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2515) if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2516) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2517)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2518) err = mv88e6xxx_serdes_irq_request(chip, port, lane);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2519) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2520) err = mv88e6xxx_serdes_irq_free(chip, port, lane);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2521) if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2522) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2523)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2524) err = mv88e6xxx_serdes_power_down(chip, port, lane);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2525) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2526)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2527) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2528) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2529)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2530) static int mv88e6xxx_setup_upstream_port(struct mv88e6xxx_chip *chip, int port)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2531) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2532) struct dsa_switch *ds = chip->ds;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2533) int upstream_port;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2534) int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2535)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2536) upstream_port = dsa_upstream_port(ds, port);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2537) if (chip->info->ops->port_set_upstream_port) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2538) err = chip->info->ops->port_set_upstream_port(chip, port,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2539) upstream_port);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2540) if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2541) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2542) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2543)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2544) if (port == upstream_port) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2545) if (chip->info->ops->set_cpu_port) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2546) err = chip->info->ops->set_cpu_port(chip,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2547) upstream_port);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2548) if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2549) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2550) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2551)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2552) if (chip->info->ops->set_egress_port) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2553) err = chip->info->ops->set_egress_port(chip,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2554) MV88E6XXX_EGRESS_DIR_INGRESS,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2555) upstream_port);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2556) if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2557) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2558)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2559) err = chip->info->ops->set_egress_port(chip,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2560) MV88E6XXX_EGRESS_DIR_EGRESS,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2561) upstream_port);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2562) if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2563) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2564) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2565) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2566)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2567) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2568) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2569)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2570) static int mv88e6xxx_setup_port(struct mv88e6xxx_chip *chip, int port)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2571) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2572) struct dsa_switch *ds = chip->ds;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2573) int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2574) u16 reg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2575)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2576) chip->ports[port].chip = chip;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2577) chip->ports[port].port = port;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2578)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2579) /* MAC Forcing register: don't force link, speed, duplex or flow control
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2580) * state to any particular values on physical ports, but force the CPU
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2581) * port and all DSA ports to their maximum bandwidth and full duplex.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2582) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2583) if (dsa_is_cpu_port(ds, port) || dsa_is_dsa_port(ds, port))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2584) err = mv88e6xxx_port_setup_mac(chip, port, LINK_FORCED_UP,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2585) SPEED_MAX, DUPLEX_FULL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2586) PAUSE_OFF,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2587) PHY_INTERFACE_MODE_NA);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2588) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2589) err = mv88e6xxx_port_setup_mac(chip, port, LINK_UNFORCED,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2590) SPEED_UNFORCED, DUPLEX_UNFORCED,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2591) PAUSE_ON,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2592) PHY_INTERFACE_MODE_NA);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2593) if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2594) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2595)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2596) /* Port Control: disable Drop-on-Unlock, disable Drop-on-Lock,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2597) * disable Header mode, enable IGMP/MLD snooping, disable VLAN
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2598) * tunneling, determine priority by looking at 802.1p and IP
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2599) * priority fields (IP prio has precedence), and set STP state
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2600) * to Forwarding.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2601) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2602) * If this is the CPU link, use DSA or EDSA tagging depending
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2603) * on which tagging mode was configured.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2604) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2605) * If this is a link to another switch, use DSA tagging mode.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2606) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2607) * If this is the upstream port for this switch, enable
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2608) * forwarding of unknown unicasts and multicasts.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2609) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2610) reg = MV88E6XXX_PORT_CTL0_IGMP_MLD_SNOOP |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2611) MV88E6185_PORT_CTL0_USE_TAG | MV88E6185_PORT_CTL0_USE_IP |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2612) MV88E6XXX_PORT_CTL0_STATE_FORWARDING;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2613) err = mv88e6xxx_port_write(chip, port, MV88E6XXX_PORT_CTL0, reg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2614) if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2615) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2616)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2617) err = mv88e6xxx_setup_port_mode(chip, port);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2618) if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2619) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2620)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2621) err = mv88e6xxx_setup_egress_floods(chip, port);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2622) if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2623) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2624)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2625) /* Port Control 2: don't force a good FCS, set the MTU size to
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2626) * 10222 bytes, disable 802.1q tags checking, don't discard tagged or
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2627) * untagged frames on this port, do a destination address lookup on all
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2628) * received packets as usual, disable ARP mirroring and don't send a
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2629) * copy of all transmitted/received frames on this port to the CPU.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2630) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2631) err = mv88e6xxx_port_set_map_da(chip, port);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2632) if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2633) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2634)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2635) err = mv88e6xxx_setup_upstream_port(chip, port);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2636) if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2637) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2638)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2639) err = mv88e6xxx_port_set_8021q_mode(chip, port,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2640) MV88E6XXX_PORT_CTL2_8021Q_MODE_DISABLED);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2641) if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2642) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2643)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2644) if (chip->info->ops->port_set_jumbo_size) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2645) err = chip->info->ops->port_set_jumbo_size(chip, port, 10218);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2646) if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2647) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2648) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2649)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2650) /* Port Association Vector: when learning source addresses
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2651) * of packets, add the address to the address database using
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2652) * a port bitmap that has only the bit for this port set and
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2653) * the other bits clear.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2654) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2655) reg = 1 << port;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2656) /* Disable learning for CPU port */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2657) if (dsa_is_cpu_port(ds, port))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2658) reg = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2659)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2660) err = mv88e6xxx_port_write(chip, port, MV88E6XXX_PORT_ASSOC_VECTOR,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2661) reg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2662) if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2663) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2664)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2665) /* Egress rate control 2: disable egress rate control. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2666) err = mv88e6xxx_port_write(chip, port, MV88E6XXX_PORT_EGRESS_RATE_CTL2,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2667) 0x0000);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2668) if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2669) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2670)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2671) if (chip->info->ops->port_pause_limit) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2672) err = chip->info->ops->port_pause_limit(chip, port, 0, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2673) if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2674) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2675) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2676)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2677) if (chip->info->ops->port_disable_learn_limit) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2678) err = chip->info->ops->port_disable_learn_limit(chip, port);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2679) if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2680) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2681) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2682)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2683) if (chip->info->ops->port_disable_pri_override) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2684) err = chip->info->ops->port_disable_pri_override(chip, port);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2685) if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2686) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2687) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2688)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2689) if (chip->info->ops->port_tag_remap) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2690) err = chip->info->ops->port_tag_remap(chip, port);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2691) if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2692) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2693) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2694)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2695) if (chip->info->ops->port_egress_rate_limiting) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2696) err = chip->info->ops->port_egress_rate_limiting(chip, port);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2697) if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2698) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2699) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2700)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2701) if (chip->info->ops->port_setup_message_port) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2702) err = chip->info->ops->port_setup_message_port(chip, port);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2703) if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2704) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2705) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2706)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2707) /* Port based VLAN map: give each port the same default address
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2708) * database, and allow bidirectional communication between the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2709) * CPU and DSA port(s), and the other ports.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2710) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2711) err = mv88e6xxx_port_set_fid(chip, port, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2712) if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2713) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2714)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2715) err = mv88e6xxx_port_vlan_map(chip, port);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2716) if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2717) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2718)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2719) /* Default VLAN ID and priority: don't set a default VLAN
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2720) * ID, and set the default packet priority to zero.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2721) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2722) return mv88e6xxx_port_write(chip, port, MV88E6XXX_PORT_DEFAULT_VLAN, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2723) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2724)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2725) static int mv88e6xxx_get_max_mtu(struct dsa_switch *ds, int port)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2726) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2727) struct mv88e6xxx_chip *chip = ds->priv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2728)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2729) if (chip->info->ops->port_set_jumbo_size)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2730) return 10240 - VLAN_ETH_HLEN - EDSA_HLEN - ETH_FCS_LEN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2731) else if (chip->info->ops->set_max_frame_size)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2732) return 1632 - VLAN_ETH_HLEN - EDSA_HLEN - ETH_FCS_LEN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2733) return 1522 - VLAN_ETH_HLEN - EDSA_HLEN - ETH_FCS_LEN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2734) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2735)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2736) static int mv88e6xxx_change_mtu(struct dsa_switch *ds, int port, int new_mtu)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2737) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2738) struct mv88e6xxx_chip *chip = ds->priv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2739) int ret = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2740)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2741) if (dsa_is_dsa_port(ds, port) || dsa_is_cpu_port(ds, port))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2742) new_mtu += EDSA_HLEN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2743)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2744) mv88e6xxx_reg_lock(chip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2745) if (chip->info->ops->port_set_jumbo_size)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2746) ret = chip->info->ops->port_set_jumbo_size(chip, port, new_mtu);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2747) else if (chip->info->ops->set_max_frame_size)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2748) ret = chip->info->ops->set_max_frame_size(chip, new_mtu);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2749) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2750) if (new_mtu > 1522)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2751) ret = -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2752) mv88e6xxx_reg_unlock(chip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2753)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2754) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2755) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2756)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2757) static int mv88e6xxx_port_enable(struct dsa_switch *ds, int port,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2758) struct phy_device *phydev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2759) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2760) struct mv88e6xxx_chip *chip = ds->priv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2761) int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2762)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2763) mv88e6xxx_reg_lock(chip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2764) err = mv88e6xxx_serdes_power(chip, port, true);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2765) mv88e6xxx_reg_unlock(chip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2766)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2767) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2768) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2769)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2770) static void mv88e6xxx_port_disable(struct dsa_switch *ds, int port)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2771) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2772) struct mv88e6xxx_chip *chip = ds->priv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2773)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2774) mv88e6xxx_reg_lock(chip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2775) if (mv88e6xxx_serdes_power(chip, port, false))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2776) dev_err(chip->dev, "failed to power off SERDES\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2777) mv88e6xxx_reg_unlock(chip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2778) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2779)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2780) static int mv88e6xxx_set_ageing_time(struct dsa_switch *ds,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2781) unsigned int ageing_time)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2782) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2783) struct mv88e6xxx_chip *chip = ds->priv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2784) int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2785)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2786) mv88e6xxx_reg_lock(chip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2787) err = mv88e6xxx_g1_atu_set_age_time(chip, ageing_time);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2788) mv88e6xxx_reg_unlock(chip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2789)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2790) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2791) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2792)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2793) static int mv88e6xxx_stats_setup(struct mv88e6xxx_chip *chip)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2794) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2795) int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2796)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2797) /* Initialize the statistics unit */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2798) if (chip->info->ops->stats_set_histogram) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2799) err = chip->info->ops->stats_set_histogram(chip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2800) if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2801) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2802) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2803)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2804) return mv88e6xxx_g1_stats_clear(chip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2805) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2806)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2807) /* Check if the errata has already been applied. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2808) static bool mv88e6390_setup_errata_applied(struct mv88e6xxx_chip *chip)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2809) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2810) int port;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2811) int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2812) u16 val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2813)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2814) for (port = 0; port < mv88e6xxx_num_ports(chip); port++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2815) err = mv88e6xxx_port_hidden_read(chip, 0xf, port, 0, &val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2816) if (err) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2817) dev_err(chip->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2818) "Error reading hidden register: %d\n", err);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2819) return false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2820) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2821) if (val != 0x01c0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2822) return false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2823) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2824)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2825) return true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2826) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2827)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2828) /* The 6390 copper ports have an errata which require poking magic
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2829) * values into undocumented hidden registers and then performing a
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2830) * software reset.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2831) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2832) static int mv88e6390_setup_errata(struct mv88e6xxx_chip *chip)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2833) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2834) int port;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2835) int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2836)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2837) if (mv88e6390_setup_errata_applied(chip))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2838) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2839)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2840) /* Set the ports into blocking mode */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2841) for (port = 0; port < mv88e6xxx_num_ports(chip); port++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2842) err = mv88e6xxx_port_set_state(chip, port, BR_STATE_DISABLED);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2843) if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2844) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2845) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2846)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2847) for (port = 0; port < mv88e6xxx_num_ports(chip); port++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2848) err = mv88e6xxx_port_hidden_write(chip, 0xf, port, 0, 0x01c0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2849) if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2850) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2851) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2852)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2853) return mv88e6xxx_software_reset(chip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2854) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2855)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2856) static void mv88e6xxx_teardown(struct dsa_switch *ds)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2857) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2858) mv88e6xxx_teardown_devlink_params(ds);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2859) dsa_devlink_resources_unregister(ds);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2860) mv88e6xxx_teardown_devlink_regions(ds);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2861) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2862)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2863) static int mv88e6xxx_setup(struct dsa_switch *ds)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2864) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2865) struct mv88e6xxx_chip *chip = ds->priv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2866) u8 cmode;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2867) int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2868) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2869)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2870) chip->ds = ds;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2871) ds->slave_mii_bus = mv88e6xxx_default_mdio_bus(chip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2872)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2873) mv88e6xxx_reg_lock(chip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2874)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2875) if (chip->info->ops->setup_errata) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2876) err = chip->info->ops->setup_errata(chip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2877) if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2878) goto unlock;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2879) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2880)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2881) /* Cache the cmode of each port. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2882) for (i = 0; i < mv88e6xxx_num_ports(chip); i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2883) if (chip->info->ops->port_get_cmode) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2884) err = chip->info->ops->port_get_cmode(chip, i, &cmode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2885) if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2886) goto unlock;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2887)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2888) chip->ports[i].cmode = cmode;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2889) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2890) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2891)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2892) /* Setup Switch Port Registers */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2893) for (i = 0; i < mv88e6xxx_num_ports(chip); i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2894) if (dsa_is_unused_port(ds, i))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2895) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2896)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2897) /* Prevent the use of an invalid port. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2898) if (mv88e6xxx_is_invalid_port(chip, i)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2899) dev_err(chip->dev, "port %d is invalid\n", i);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2900) err = -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2901) goto unlock;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2902) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2903)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2904) err = mv88e6xxx_setup_port(chip, i);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2905) if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2906) goto unlock;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2907) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2908)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2909) err = mv88e6xxx_irl_setup(chip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2910) if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2911) goto unlock;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2912)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2913) err = mv88e6xxx_mac_setup(chip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2914) if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2915) goto unlock;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2916)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2917) err = mv88e6xxx_phy_setup(chip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2918) if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2919) goto unlock;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2920)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2921) err = mv88e6xxx_vtu_setup(chip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2922) if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2923) goto unlock;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2924)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2925) err = mv88e6xxx_pvt_setup(chip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2926) if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2927) goto unlock;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2928)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2929) err = mv88e6xxx_atu_setup(chip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2930) if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2931) goto unlock;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2932)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2933) err = mv88e6xxx_broadcast_setup(chip, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2934) if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2935) goto unlock;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2936)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2937) err = mv88e6xxx_pot_setup(chip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2938) if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2939) goto unlock;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2940)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2941) err = mv88e6xxx_rmu_setup(chip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2942) if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2943) goto unlock;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2944)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2945) err = mv88e6xxx_rsvd2cpu_setup(chip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2946) if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2947) goto unlock;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2948)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2949) err = mv88e6xxx_trunk_setup(chip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2950) if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2951) goto unlock;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2952)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2953) err = mv88e6xxx_devmap_setup(chip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2954) if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2955) goto unlock;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2956)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2957) err = mv88e6xxx_pri_setup(chip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2958) if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2959) goto unlock;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2960)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2961) /* Setup PTP Hardware Clock and timestamping */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2962) if (chip->info->ptp_support) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2963) err = mv88e6xxx_ptp_setup(chip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2964) if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2965) goto unlock;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2966)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2967) err = mv88e6xxx_hwtstamp_setup(chip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2968) if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2969) goto unlock;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2970) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2971)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2972) err = mv88e6xxx_stats_setup(chip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2973) if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2974) goto unlock;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2975)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2976) unlock:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2977) mv88e6xxx_reg_unlock(chip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2978)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2979) if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2980) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2981)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2982) /* Have to be called without holding the register lock, since
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2983) * they take the devlink lock, and we later take the locks in
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2984) * the reverse order when getting/setting parameters or
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2985) * resource occupancy.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2986) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2987) err = mv88e6xxx_setup_devlink_resources(ds);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2988) if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2989) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2990)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2991) err = mv88e6xxx_setup_devlink_params(ds);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2992) if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2993) goto out_resources;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2994)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2995) err = mv88e6xxx_setup_devlink_regions(ds);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2996) if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2997) goto out_params;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2998)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2999) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3000)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3001) out_params:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3002) mv88e6xxx_teardown_devlink_params(ds);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3003) out_resources:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3004) dsa_devlink_resources_unregister(ds);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3005)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3006) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3007) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3008)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3009) /* prod_id for switch families which do not have a PHY model number */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3010) static const u16 family_prod_id_table[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3011) [MV88E6XXX_FAMILY_6341] = MV88E6XXX_PORT_SWITCH_ID_PROD_6341,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3012) [MV88E6XXX_FAMILY_6390] = MV88E6XXX_PORT_SWITCH_ID_PROD_6390,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3013) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3014)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3015) static int mv88e6xxx_mdio_read(struct mii_bus *bus, int phy, int reg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3016) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3017) struct mv88e6xxx_mdio_bus *mdio_bus = bus->priv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3018) struct mv88e6xxx_chip *chip = mdio_bus->chip;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3019) u16 prod_id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3020) u16 val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3021) int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3022)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3023) if (!chip->info->ops->phy_read)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3024) return -EOPNOTSUPP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3025)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3026) mv88e6xxx_reg_lock(chip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3027) err = chip->info->ops->phy_read(chip, bus, phy, reg, &val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3028) mv88e6xxx_reg_unlock(chip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3029)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3030) /* Some internal PHYs don't have a model number. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3031) if (reg == MII_PHYSID2 && !(val & 0x3f0) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3032) chip->info->family < ARRAY_SIZE(family_prod_id_table)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3033) prod_id = family_prod_id_table[chip->info->family];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3034) if (prod_id)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3035) val |= prod_id >> 4;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3036) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3037)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3038) return err ? err : val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3039) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3040)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3041) static int mv88e6xxx_mdio_write(struct mii_bus *bus, int phy, int reg, u16 val)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3042) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3043) struct mv88e6xxx_mdio_bus *mdio_bus = bus->priv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3044) struct mv88e6xxx_chip *chip = mdio_bus->chip;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3045) int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3046)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3047) if (!chip->info->ops->phy_write)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3048) return -EOPNOTSUPP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3049)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3050) mv88e6xxx_reg_lock(chip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3051) err = chip->info->ops->phy_write(chip, bus, phy, reg, val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3052) mv88e6xxx_reg_unlock(chip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3053)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3054) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3055) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3056)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3057) static int mv88e6xxx_mdio_register(struct mv88e6xxx_chip *chip,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3058) struct device_node *np,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3059) bool external)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3060) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3061) static int index;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3062) struct mv88e6xxx_mdio_bus *mdio_bus;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3063) struct mii_bus *bus;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3064) int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3065)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3066) if (external) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3067) mv88e6xxx_reg_lock(chip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3068) err = mv88e6xxx_g2_scratch_gpio_set_smi(chip, true);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3069) mv88e6xxx_reg_unlock(chip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3070)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3071) if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3072) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3073) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3074)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3075) bus = mdiobus_alloc_size(sizeof(*mdio_bus));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3076) if (!bus)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3077) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3078)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3079) mdio_bus = bus->priv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3080) mdio_bus->bus = bus;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3081) mdio_bus->chip = chip;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3082) INIT_LIST_HEAD(&mdio_bus->list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3083) mdio_bus->external = external;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3084)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3085) if (np) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3086) bus->name = np->full_name;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3087) snprintf(bus->id, MII_BUS_ID_SIZE, "%pOF", np);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3088) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3089) bus->name = "mv88e6xxx SMI";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3090) snprintf(bus->id, MII_BUS_ID_SIZE, "mv88e6xxx-%d", index++);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3091) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3092)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3093) bus->read = mv88e6xxx_mdio_read;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3094) bus->write = mv88e6xxx_mdio_write;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3095) bus->parent = chip->dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3096)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3097) if (!external) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3098) err = mv88e6xxx_g2_irq_mdio_setup(chip, bus);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3099) if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3100) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3101) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3102)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3103) err = of_mdiobus_register(bus, np);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3104) if (err) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3105) dev_err(chip->dev, "Cannot register MDIO bus (%d)\n", err);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3106) mv88e6xxx_g2_irq_mdio_free(chip, bus);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3107) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3108) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3109)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3110) if (external)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3111) list_add_tail(&mdio_bus->list, &chip->mdios);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3112) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3113) list_add(&mdio_bus->list, &chip->mdios);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3114)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3115) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3116)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3117) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3118) mdiobus_free(bus);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3119) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3120) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3121)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3122) static void mv88e6xxx_mdios_unregister(struct mv88e6xxx_chip *chip)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3123)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3124) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3125) struct mv88e6xxx_mdio_bus *mdio_bus, *p;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3126) struct mii_bus *bus;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3127)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3128) list_for_each_entry_safe(mdio_bus, p, &chip->mdios, list) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3129) bus = mdio_bus->bus;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3130)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3131) if (!mdio_bus->external)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3132) mv88e6xxx_g2_irq_mdio_free(chip, bus);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3133)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3134) mdiobus_unregister(bus);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3135) mdiobus_free(bus);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3136) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3137) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3138)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3139) static int mv88e6xxx_mdios_register(struct mv88e6xxx_chip *chip,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3140) struct device_node *np)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3141) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3142) struct device_node *child;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3143) int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3144)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3145) /* Always register one mdio bus for the internal/default mdio
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3146) * bus. This maybe represented in the device tree, but is
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3147) * optional.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3148) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3149) child = of_get_child_by_name(np, "mdio");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3150) err = mv88e6xxx_mdio_register(chip, child, false);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3151) if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3152) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3153)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3154) /* Walk the device tree, and see if there are any other nodes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3155) * which say they are compatible with the external mdio
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3156) * bus.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3157) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3158) for_each_available_child_of_node(np, child) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3159) if (of_device_is_compatible(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3160) child, "marvell,mv88e6xxx-mdio-external")) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3161) err = mv88e6xxx_mdio_register(chip, child, true);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3162) if (err) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3163) mv88e6xxx_mdios_unregister(chip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3164) of_node_put(child);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3165) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3166) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3167) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3168) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3169)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3170) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3171) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3172)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3173) static int mv88e6xxx_get_eeprom_len(struct dsa_switch *ds)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3174) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3175) struct mv88e6xxx_chip *chip = ds->priv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3176)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3177) return chip->eeprom_len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3178) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3179)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3180) static int mv88e6xxx_get_eeprom(struct dsa_switch *ds,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3181) struct ethtool_eeprom *eeprom, u8 *data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3182) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3183) struct mv88e6xxx_chip *chip = ds->priv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3184) int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3185)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3186) if (!chip->info->ops->get_eeprom)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3187) return -EOPNOTSUPP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3188)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3189) mv88e6xxx_reg_lock(chip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3190) err = chip->info->ops->get_eeprom(chip, eeprom, data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3191) mv88e6xxx_reg_unlock(chip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3192)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3193) if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3194) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3195)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3196) eeprom->magic = 0xc3ec4951;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3197)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3198) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3199) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3200)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3201) static int mv88e6xxx_set_eeprom(struct dsa_switch *ds,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3202) struct ethtool_eeprom *eeprom, u8 *data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3203) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3204) struct mv88e6xxx_chip *chip = ds->priv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3205) int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3206)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3207) if (!chip->info->ops->set_eeprom)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3208) return -EOPNOTSUPP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3209)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3210) if (eeprom->magic != 0xc3ec4951)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3211) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3212)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3213) mv88e6xxx_reg_lock(chip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3214) err = chip->info->ops->set_eeprom(chip, eeprom, data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3215) mv88e6xxx_reg_unlock(chip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3216)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3217) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3218) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3219)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3220) static const struct mv88e6xxx_ops mv88e6085_ops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3221) /* MV88E6XXX_FAMILY_6097 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3222) .ieee_pri_map = mv88e6085_g1_ieee_pri_map,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3223) .ip_pri_map = mv88e6085_g1_ip_pri_map,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3224) .irl_init_all = mv88e6352_g2_irl_init_all,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3225) .set_switch_mac = mv88e6xxx_g1_set_switch_mac,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3226) .phy_read = mv88e6185_phy_ppu_read,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3227) .phy_write = mv88e6185_phy_ppu_write,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3228) .port_set_link = mv88e6xxx_port_set_link,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3229) .port_set_speed_duplex = mv88e6185_port_set_speed_duplex,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3230) .port_tag_remap = mv88e6095_port_tag_remap,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3231) .port_set_frame_mode = mv88e6351_port_set_frame_mode,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3232) .port_set_egress_floods = mv88e6352_port_set_egress_floods,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3233) .port_set_ether_type = mv88e6351_port_set_ether_type,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3234) .port_egress_rate_limiting = mv88e6097_port_egress_rate_limiting,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3235) .port_pause_limit = mv88e6097_port_pause_limit,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3236) .port_disable_learn_limit = mv88e6xxx_port_disable_learn_limit,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3237) .port_disable_pri_override = mv88e6xxx_port_disable_pri_override,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3238) .port_get_cmode = mv88e6185_port_get_cmode,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3239) .port_setup_message_port = mv88e6xxx_setup_message_port,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3240) .stats_snapshot = mv88e6xxx_g1_stats_snapshot,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3241) .stats_set_histogram = mv88e6095_g1_stats_set_histogram,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3242) .stats_get_sset_count = mv88e6095_stats_get_sset_count,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3243) .stats_get_strings = mv88e6095_stats_get_strings,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3244) .stats_get_stats = mv88e6095_stats_get_stats,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3245) .set_cpu_port = mv88e6095_g1_set_cpu_port,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3246) .set_egress_port = mv88e6095_g1_set_egress_port,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3247) .watchdog_ops = &mv88e6097_watchdog_ops,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3248) .mgmt_rsvd2cpu = mv88e6352_g2_mgmt_rsvd2cpu,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3249) .pot_clear = mv88e6xxx_g2_pot_clear,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3250) .ppu_enable = mv88e6185_g1_ppu_enable,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3251) .ppu_disable = mv88e6185_g1_ppu_disable,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3252) .reset = mv88e6185_g1_reset,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3253) .rmu_disable = mv88e6085_g1_rmu_disable,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3254) .vtu_getnext = mv88e6352_g1_vtu_getnext,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3255) .vtu_loadpurge = mv88e6352_g1_vtu_loadpurge,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3256) .phylink_validate = mv88e6185_phylink_validate,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3257) .set_max_frame_size = mv88e6185_g1_set_max_frame_size,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3258) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3259)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3260) static const struct mv88e6xxx_ops mv88e6095_ops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3261) /* MV88E6XXX_FAMILY_6095 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3262) .ieee_pri_map = mv88e6085_g1_ieee_pri_map,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3263) .ip_pri_map = mv88e6085_g1_ip_pri_map,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3264) .set_switch_mac = mv88e6xxx_g1_set_switch_mac,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3265) .phy_read = mv88e6185_phy_ppu_read,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3266) .phy_write = mv88e6185_phy_ppu_write,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3267) .port_set_link = mv88e6xxx_port_set_link,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3268) .port_set_speed_duplex = mv88e6185_port_set_speed_duplex,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3269) .port_set_frame_mode = mv88e6085_port_set_frame_mode,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3270) .port_set_egress_floods = mv88e6185_port_set_egress_floods,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3271) .port_set_upstream_port = mv88e6095_port_set_upstream_port,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3272) .port_get_cmode = mv88e6185_port_get_cmode,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3273) .port_setup_message_port = mv88e6xxx_setup_message_port,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3274) .stats_snapshot = mv88e6xxx_g1_stats_snapshot,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3275) .stats_set_histogram = mv88e6095_g1_stats_set_histogram,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3276) .stats_get_sset_count = mv88e6095_stats_get_sset_count,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3277) .stats_get_strings = mv88e6095_stats_get_strings,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3278) .stats_get_stats = mv88e6095_stats_get_stats,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3279) .mgmt_rsvd2cpu = mv88e6185_g2_mgmt_rsvd2cpu,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3280) .ppu_enable = mv88e6185_g1_ppu_enable,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3281) .ppu_disable = mv88e6185_g1_ppu_disable,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3282) .reset = mv88e6185_g1_reset,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3283) .vtu_getnext = mv88e6185_g1_vtu_getnext,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3284) .vtu_loadpurge = mv88e6185_g1_vtu_loadpurge,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3285) .phylink_validate = mv88e6185_phylink_validate,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3286) .set_max_frame_size = mv88e6185_g1_set_max_frame_size,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3287) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3288)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3289) static const struct mv88e6xxx_ops mv88e6097_ops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3290) /* MV88E6XXX_FAMILY_6097 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3291) .ieee_pri_map = mv88e6085_g1_ieee_pri_map,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3292) .ip_pri_map = mv88e6085_g1_ip_pri_map,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3293) .irl_init_all = mv88e6352_g2_irl_init_all,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3294) .set_switch_mac = mv88e6xxx_g2_set_switch_mac,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3295) .phy_read = mv88e6xxx_g2_smi_phy_read,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3296) .phy_write = mv88e6xxx_g2_smi_phy_write,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3297) .port_set_link = mv88e6xxx_port_set_link,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3298) .port_set_speed_duplex = mv88e6185_port_set_speed_duplex,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3299) .port_tag_remap = mv88e6095_port_tag_remap,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3300) .port_set_policy = mv88e6352_port_set_policy,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3301) .port_set_frame_mode = mv88e6351_port_set_frame_mode,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3302) .port_set_egress_floods = mv88e6352_port_set_egress_floods,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3303) .port_set_ether_type = mv88e6351_port_set_ether_type,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3304) .port_egress_rate_limiting = mv88e6095_port_egress_rate_limiting,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3305) .port_pause_limit = mv88e6097_port_pause_limit,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3306) .port_disable_learn_limit = mv88e6xxx_port_disable_learn_limit,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3307) .port_disable_pri_override = mv88e6xxx_port_disable_pri_override,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3308) .port_get_cmode = mv88e6185_port_get_cmode,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3309) .port_setup_message_port = mv88e6xxx_setup_message_port,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3310) .stats_snapshot = mv88e6xxx_g1_stats_snapshot,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3311) .stats_set_histogram = mv88e6095_g1_stats_set_histogram,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3312) .stats_get_sset_count = mv88e6095_stats_get_sset_count,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3313) .stats_get_strings = mv88e6095_stats_get_strings,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3314) .stats_get_stats = mv88e6095_stats_get_stats,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3315) .set_cpu_port = mv88e6095_g1_set_cpu_port,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3316) .set_egress_port = mv88e6095_g1_set_egress_port,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3317) .watchdog_ops = &mv88e6097_watchdog_ops,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3318) .mgmt_rsvd2cpu = mv88e6352_g2_mgmt_rsvd2cpu,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3319) .pot_clear = mv88e6xxx_g2_pot_clear,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3320) .reset = mv88e6352_g1_reset,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3321) .rmu_disable = mv88e6085_g1_rmu_disable,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3322) .vtu_getnext = mv88e6352_g1_vtu_getnext,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3323) .vtu_loadpurge = mv88e6352_g1_vtu_loadpurge,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3324) .phylink_validate = mv88e6185_phylink_validate,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3325) .set_max_frame_size = mv88e6185_g1_set_max_frame_size,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3326) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3327)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3328) static const struct mv88e6xxx_ops mv88e6123_ops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3329) /* MV88E6XXX_FAMILY_6165 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3330) .ieee_pri_map = mv88e6085_g1_ieee_pri_map,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3331) .ip_pri_map = mv88e6085_g1_ip_pri_map,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3332) .irl_init_all = mv88e6352_g2_irl_init_all,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3333) .set_switch_mac = mv88e6xxx_g2_set_switch_mac,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3334) .phy_read = mv88e6xxx_g2_smi_phy_read,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3335) .phy_write = mv88e6xxx_g2_smi_phy_write,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3336) .port_set_link = mv88e6xxx_port_set_link,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3337) .port_set_speed_duplex = mv88e6185_port_set_speed_duplex,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3338) .port_set_frame_mode = mv88e6085_port_set_frame_mode,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3339) .port_set_egress_floods = mv88e6352_port_set_egress_floods,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3340) .port_disable_learn_limit = mv88e6xxx_port_disable_learn_limit,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3341) .port_disable_pri_override = mv88e6xxx_port_disable_pri_override,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3342) .port_get_cmode = mv88e6185_port_get_cmode,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3343) .port_setup_message_port = mv88e6xxx_setup_message_port,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3344) .stats_snapshot = mv88e6320_g1_stats_snapshot,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3345) .stats_set_histogram = mv88e6095_g1_stats_set_histogram,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3346) .stats_get_sset_count = mv88e6095_stats_get_sset_count,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3347) .stats_get_strings = mv88e6095_stats_get_strings,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3348) .stats_get_stats = mv88e6095_stats_get_stats,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3349) .set_cpu_port = mv88e6095_g1_set_cpu_port,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3350) .set_egress_port = mv88e6095_g1_set_egress_port,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3351) .watchdog_ops = &mv88e6097_watchdog_ops,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3352) .mgmt_rsvd2cpu = mv88e6352_g2_mgmt_rsvd2cpu,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3353) .pot_clear = mv88e6xxx_g2_pot_clear,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3354) .reset = mv88e6352_g1_reset,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3355) .atu_get_hash = mv88e6165_g1_atu_get_hash,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3356) .atu_set_hash = mv88e6165_g1_atu_set_hash,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3357) .vtu_getnext = mv88e6352_g1_vtu_getnext,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3358) .vtu_loadpurge = mv88e6352_g1_vtu_loadpurge,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3359) .phylink_validate = mv88e6185_phylink_validate,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3360) .set_max_frame_size = mv88e6185_g1_set_max_frame_size,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3361) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3362)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3363) static const struct mv88e6xxx_ops mv88e6131_ops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3364) /* MV88E6XXX_FAMILY_6185 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3365) .ieee_pri_map = mv88e6085_g1_ieee_pri_map,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3366) .ip_pri_map = mv88e6085_g1_ip_pri_map,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3367) .set_switch_mac = mv88e6xxx_g1_set_switch_mac,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3368) .phy_read = mv88e6185_phy_ppu_read,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3369) .phy_write = mv88e6185_phy_ppu_write,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3370) .port_set_link = mv88e6xxx_port_set_link,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3371) .port_set_speed_duplex = mv88e6185_port_set_speed_duplex,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3372) .port_tag_remap = mv88e6095_port_tag_remap,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3373) .port_set_frame_mode = mv88e6351_port_set_frame_mode,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3374) .port_set_egress_floods = mv88e6185_port_set_egress_floods,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3375) .port_set_ether_type = mv88e6351_port_set_ether_type,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3376) .port_set_upstream_port = mv88e6095_port_set_upstream_port,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3377) .port_set_jumbo_size = mv88e6165_port_set_jumbo_size,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3378) .port_egress_rate_limiting = mv88e6097_port_egress_rate_limiting,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3379) .port_pause_limit = mv88e6097_port_pause_limit,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3380) .port_set_pause = mv88e6185_port_set_pause,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3381) .port_get_cmode = mv88e6185_port_get_cmode,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3382) .port_setup_message_port = mv88e6xxx_setup_message_port,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3383) .stats_snapshot = mv88e6xxx_g1_stats_snapshot,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3384) .stats_set_histogram = mv88e6095_g1_stats_set_histogram,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3385) .stats_get_sset_count = mv88e6095_stats_get_sset_count,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3386) .stats_get_strings = mv88e6095_stats_get_strings,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3387) .stats_get_stats = mv88e6095_stats_get_stats,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3388) .set_cpu_port = mv88e6095_g1_set_cpu_port,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3389) .set_egress_port = mv88e6095_g1_set_egress_port,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3390) .watchdog_ops = &mv88e6097_watchdog_ops,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3391) .mgmt_rsvd2cpu = mv88e6185_g2_mgmt_rsvd2cpu,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3392) .ppu_enable = mv88e6185_g1_ppu_enable,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3393) .set_cascade_port = mv88e6185_g1_set_cascade_port,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3394) .ppu_disable = mv88e6185_g1_ppu_disable,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3395) .reset = mv88e6185_g1_reset,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3396) .vtu_getnext = mv88e6185_g1_vtu_getnext,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3397) .vtu_loadpurge = mv88e6185_g1_vtu_loadpurge,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3398) .phylink_validate = mv88e6185_phylink_validate,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3399) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3400)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3401) static const struct mv88e6xxx_ops mv88e6141_ops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3402) /* MV88E6XXX_FAMILY_6341 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3403) .ieee_pri_map = mv88e6085_g1_ieee_pri_map,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3404) .ip_pri_map = mv88e6085_g1_ip_pri_map,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3405) .irl_init_all = mv88e6352_g2_irl_init_all,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3406) .get_eeprom = mv88e6xxx_g2_get_eeprom8,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3407) .set_eeprom = mv88e6xxx_g2_set_eeprom8,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3408) .set_switch_mac = mv88e6xxx_g2_set_switch_mac,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3409) .phy_read = mv88e6xxx_g2_smi_phy_read,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3410) .phy_write = mv88e6xxx_g2_smi_phy_write,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3411) .port_set_link = mv88e6xxx_port_set_link,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3412) .port_set_rgmii_delay = mv88e6390_port_set_rgmii_delay,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3413) .port_set_speed_duplex = mv88e6341_port_set_speed_duplex,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3414) .port_max_speed_mode = mv88e6341_port_max_speed_mode,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3415) .port_tag_remap = mv88e6095_port_tag_remap,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3416) .port_set_frame_mode = mv88e6351_port_set_frame_mode,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3417) .port_set_egress_floods = mv88e6352_port_set_egress_floods,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3418) .port_set_ether_type = mv88e6351_port_set_ether_type,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3419) .port_set_jumbo_size = mv88e6165_port_set_jumbo_size,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3420) .port_egress_rate_limiting = mv88e6097_port_egress_rate_limiting,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3421) .port_pause_limit = mv88e6097_port_pause_limit,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3422) .port_disable_learn_limit = mv88e6xxx_port_disable_learn_limit,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3423) .port_disable_pri_override = mv88e6xxx_port_disable_pri_override,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3424) .port_get_cmode = mv88e6352_port_get_cmode,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3425) .port_set_cmode = mv88e6341_port_set_cmode,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3426) .port_setup_message_port = mv88e6xxx_setup_message_port,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3427) .stats_snapshot = mv88e6390_g1_stats_snapshot,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3428) .stats_set_histogram = mv88e6390_g1_stats_set_histogram,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3429) .stats_get_sset_count = mv88e6320_stats_get_sset_count,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3430) .stats_get_strings = mv88e6320_stats_get_strings,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3431) .stats_get_stats = mv88e6390_stats_get_stats,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3432) .set_cpu_port = mv88e6390_g1_set_cpu_port,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3433) .set_egress_port = mv88e6390_g1_set_egress_port,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3434) .watchdog_ops = &mv88e6390_watchdog_ops,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3435) .mgmt_rsvd2cpu = mv88e6390_g1_mgmt_rsvd2cpu,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3436) .pot_clear = mv88e6xxx_g2_pot_clear,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3437) .reset = mv88e6352_g1_reset,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3438) .rmu_disable = mv88e6390_g1_rmu_disable,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3439) .atu_get_hash = mv88e6165_g1_atu_get_hash,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3440) .atu_set_hash = mv88e6165_g1_atu_set_hash,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3441) .vtu_getnext = mv88e6352_g1_vtu_getnext,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3442) .vtu_loadpurge = mv88e6352_g1_vtu_loadpurge,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3443) .serdes_power = mv88e6390_serdes_power,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3444) .serdes_get_lane = mv88e6341_serdes_get_lane,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3445) /* Check status register pause & lpa register */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3446) .serdes_pcs_get_state = mv88e6390_serdes_pcs_get_state,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3447) .serdes_pcs_config = mv88e6390_serdes_pcs_config,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3448) .serdes_pcs_an_restart = mv88e6390_serdes_pcs_an_restart,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3449) .serdes_pcs_link_up = mv88e6390_serdes_pcs_link_up,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3450) .serdes_irq_mapping = mv88e6390_serdes_irq_mapping,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3451) .serdes_irq_enable = mv88e6390_serdes_irq_enable,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3452) .serdes_irq_status = mv88e6390_serdes_irq_status,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3453) .gpio_ops = &mv88e6352_gpio_ops,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3454) .serdes_get_sset_count = mv88e6390_serdes_get_sset_count,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3455) .serdes_get_strings = mv88e6390_serdes_get_strings,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3456) .serdes_get_stats = mv88e6390_serdes_get_stats,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3457) .serdes_get_regs_len = mv88e6390_serdes_get_regs_len,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3458) .serdes_get_regs = mv88e6390_serdes_get_regs,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3459) .phylink_validate = mv88e6341_phylink_validate,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3460) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3461)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3462) static const struct mv88e6xxx_ops mv88e6161_ops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3463) /* MV88E6XXX_FAMILY_6165 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3464) .ieee_pri_map = mv88e6085_g1_ieee_pri_map,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3465) .ip_pri_map = mv88e6085_g1_ip_pri_map,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3466) .irl_init_all = mv88e6352_g2_irl_init_all,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3467) .set_switch_mac = mv88e6xxx_g2_set_switch_mac,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3468) .phy_read = mv88e6xxx_g2_smi_phy_read,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3469) .phy_write = mv88e6xxx_g2_smi_phy_write,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3470) .port_set_link = mv88e6xxx_port_set_link,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3471) .port_set_speed_duplex = mv88e6185_port_set_speed_duplex,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3472) .port_tag_remap = mv88e6095_port_tag_remap,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3473) .port_set_frame_mode = mv88e6351_port_set_frame_mode,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3474) .port_set_egress_floods = mv88e6352_port_set_egress_floods,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3475) .port_set_ether_type = mv88e6351_port_set_ether_type,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3476) .port_egress_rate_limiting = mv88e6097_port_egress_rate_limiting,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3477) .port_pause_limit = mv88e6097_port_pause_limit,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3478) .port_disable_learn_limit = mv88e6xxx_port_disable_learn_limit,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3479) .port_disable_pri_override = mv88e6xxx_port_disable_pri_override,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3480) .port_get_cmode = mv88e6185_port_get_cmode,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3481) .port_setup_message_port = mv88e6xxx_setup_message_port,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3482) .stats_snapshot = mv88e6xxx_g1_stats_snapshot,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3483) .stats_set_histogram = mv88e6095_g1_stats_set_histogram,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3484) .stats_get_sset_count = mv88e6095_stats_get_sset_count,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3485) .stats_get_strings = mv88e6095_stats_get_strings,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3486) .stats_get_stats = mv88e6095_stats_get_stats,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3487) .set_cpu_port = mv88e6095_g1_set_cpu_port,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3488) .set_egress_port = mv88e6095_g1_set_egress_port,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3489) .watchdog_ops = &mv88e6097_watchdog_ops,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3490) .mgmt_rsvd2cpu = mv88e6352_g2_mgmt_rsvd2cpu,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3491) .pot_clear = mv88e6xxx_g2_pot_clear,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3492) .reset = mv88e6352_g1_reset,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3493) .atu_get_hash = mv88e6165_g1_atu_get_hash,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3494) .atu_set_hash = mv88e6165_g1_atu_set_hash,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3495) .vtu_getnext = mv88e6352_g1_vtu_getnext,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3496) .vtu_loadpurge = mv88e6352_g1_vtu_loadpurge,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3497) .avb_ops = &mv88e6165_avb_ops,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3498) .ptp_ops = &mv88e6165_ptp_ops,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3499) .phylink_validate = mv88e6185_phylink_validate,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3500) .set_max_frame_size = mv88e6185_g1_set_max_frame_size,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3501) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3502)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3503) static const struct mv88e6xxx_ops mv88e6165_ops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3504) /* MV88E6XXX_FAMILY_6165 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3505) .ieee_pri_map = mv88e6085_g1_ieee_pri_map,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3506) .ip_pri_map = mv88e6085_g1_ip_pri_map,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3507) .irl_init_all = mv88e6352_g2_irl_init_all,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3508) .set_switch_mac = mv88e6xxx_g2_set_switch_mac,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3509) .phy_read = mv88e6165_phy_read,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3510) .phy_write = mv88e6165_phy_write,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3511) .port_set_link = mv88e6xxx_port_set_link,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3512) .port_set_speed_duplex = mv88e6185_port_set_speed_duplex,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3513) .port_disable_learn_limit = mv88e6xxx_port_disable_learn_limit,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3514) .port_disable_pri_override = mv88e6xxx_port_disable_pri_override,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3515) .port_get_cmode = mv88e6185_port_get_cmode,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3516) .port_setup_message_port = mv88e6xxx_setup_message_port,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3517) .stats_snapshot = mv88e6xxx_g1_stats_snapshot,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3518) .stats_set_histogram = mv88e6095_g1_stats_set_histogram,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3519) .stats_get_sset_count = mv88e6095_stats_get_sset_count,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3520) .stats_get_strings = mv88e6095_stats_get_strings,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3521) .stats_get_stats = mv88e6095_stats_get_stats,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3522) .set_cpu_port = mv88e6095_g1_set_cpu_port,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3523) .set_egress_port = mv88e6095_g1_set_egress_port,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3524) .watchdog_ops = &mv88e6097_watchdog_ops,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3525) .mgmt_rsvd2cpu = mv88e6352_g2_mgmt_rsvd2cpu,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3526) .pot_clear = mv88e6xxx_g2_pot_clear,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3527) .reset = mv88e6352_g1_reset,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3528) .atu_get_hash = mv88e6165_g1_atu_get_hash,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3529) .atu_set_hash = mv88e6165_g1_atu_set_hash,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3530) .vtu_getnext = mv88e6352_g1_vtu_getnext,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3531) .vtu_loadpurge = mv88e6352_g1_vtu_loadpurge,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3532) .avb_ops = &mv88e6165_avb_ops,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3533) .ptp_ops = &mv88e6165_ptp_ops,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3534) .phylink_validate = mv88e6185_phylink_validate,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3535) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3536)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3537) static const struct mv88e6xxx_ops mv88e6171_ops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3538) /* MV88E6XXX_FAMILY_6351 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3539) .ieee_pri_map = mv88e6085_g1_ieee_pri_map,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3540) .ip_pri_map = mv88e6085_g1_ip_pri_map,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3541) .irl_init_all = mv88e6352_g2_irl_init_all,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3542) .set_switch_mac = mv88e6xxx_g2_set_switch_mac,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3543) .phy_read = mv88e6xxx_g2_smi_phy_read,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3544) .phy_write = mv88e6xxx_g2_smi_phy_write,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3545) .port_set_link = mv88e6xxx_port_set_link,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3546) .port_set_rgmii_delay = mv88e6352_port_set_rgmii_delay,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3547) .port_set_speed_duplex = mv88e6185_port_set_speed_duplex,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3548) .port_tag_remap = mv88e6095_port_tag_remap,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3549) .port_set_frame_mode = mv88e6351_port_set_frame_mode,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3550) .port_set_egress_floods = mv88e6352_port_set_egress_floods,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3551) .port_set_ether_type = mv88e6351_port_set_ether_type,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3552) .port_set_jumbo_size = mv88e6165_port_set_jumbo_size,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3553) .port_egress_rate_limiting = mv88e6097_port_egress_rate_limiting,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3554) .port_pause_limit = mv88e6097_port_pause_limit,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3555) .port_disable_learn_limit = mv88e6xxx_port_disable_learn_limit,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3556) .port_disable_pri_override = mv88e6xxx_port_disable_pri_override,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3557) .port_get_cmode = mv88e6352_port_get_cmode,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3558) .port_setup_message_port = mv88e6xxx_setup_message_port,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3559) .stats_snapshot = mv88e6320_g1_stats_snapshot,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3560) .stats_set_histogram = mv88e6095_g1_stats_set_histogram,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3561) .stats_get_sset_count = mv88e6095_stats_get_sset_count,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3562) .stats_get_strings = mv88e6095_stats_get_strings,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3563) .stats_get_stats = mv88e6095_stats_get_stats,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3564) .set_cpu_port = mv88e6095_g1_set_cpu_port,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3565) .set_egress_port = mv88e6095_g1_set_egress_port,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3566) .watchdog_ops = &mv88e6097_watchdog_ops,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3567) .mgmt_rsvd2cpu = mv88e6352_g2_mgmt_rsvd2cpu,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3568) .pot_clear = mv88e6xxx_g2_pot_clear,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3569) .reset = mv88e6352_g1_reset,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3570) .atu_get_hash = mv88e6165_g1_atu_get_hash,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3571) .atu_set_hash = mv88e6165_g1_atu_set_hash,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3572) .vtu_getnext = mv88e6352_g1_vtu_getnext,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3573) .vtu_loadpurge = mv88e6352_g1_vtu_loadpurge,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3574) .phylink_validate = mv88e6185_phylink_validate,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3575) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3576)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3577) static const struct mv88e6xxx_ops mv88e6172_ops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3578) /* MV88E6XXX_FAMILY_6352 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3579) .ieee_pri_map = mv88e6085_g1_ieee_pri_map,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3580) .ip_pri_map = mv88e6085_g1_ip_pri_map,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3581) .irl_init_all = mv88e6352_g2_irl_init_all,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3582) .get_eeprom = mv88e6xxx_g2_get_eeprom16,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3583) .set_eeprom = mv88e6xxx_g2_set_eeprom16,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3584) .set_switch_mac = mv88e6xxx_g2_set_switch_mac,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3585) .phy_read = mv88e6xxx_g2_smi_phy_read,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3586) .phy_write = mv88e6xxx_g2_smi_phy_write,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3587) .port_set_link = mv88e6xxx_port_set_link,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3588) .port_set_rgmii_delay = mv88e6352_port_set_rgmii_delay,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3589) .port_set_speed_duplex = mv88e6352_port_set_speed_duplex,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3590) .port_tag_remap = mv88e6095_port_tag_remap,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3591) .port_set_policy = mv88e6352_port_set_policy,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3592) .port_set_frame_mode = mv88e6351_port_set_frame_mode,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3593) .port_set_egress_floods = mv88e6352_port_set_egress_floods,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3594) .port_set_ether_type = mv88e6351_port_set_ether_type,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3595) .port_set_jumbo_size = mv88e6165_port_set_jumbo_size,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3596) .port_egress_rate_limiting = mv88e6097_port_egress_rate_limiting,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3597) .port_pause_limit = mv88e6097_port_pause_limit,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3598) .port_disable_learn_limit = mv88e6xxx_port_disable_learn_limit,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3599) .port_disable_pri_override = mv88e6xxx_port_disable_pri_override,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3600) .port_get_cmode = mv88e6352_port_get_cmode,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3601) .port_setup_message_port = mv88e6xxx_setup_message_port,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3602) .stats_snapshot = mv88e6320_g1_stats_snapshot,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3603) .stats_set_histogram = mv88e6095_g1_stats_set_histogram,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3604) .stats_get_sset_count = mv88e6095_stats_get_sset_count,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3605) .stats_get_strings = mv88e6095_stats_get_strings,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3606) .stats_get_stats = mv88e6095_stats_get_stats,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3607) .set_cpu_port = mv88e6095_g1_set_cpu_port,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3608) .set_egress_port = mv88e6095_g1_set_egress_port,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3609) .watchdog_ops = &mv88e6097_watchdog_ops,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3610) .mgmt_rsvd2cpu = mv88e6352_g2_mgmt_rsvd2cpu,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3611) .pot_clear = mv88e6xxx_g2_pot_clear,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3612) .reset = mv88e6352_g1_reset,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3613) .rmu_disable = mv88e6352_g1_rmu_disable,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3614) .atu_get_hash = mv88e6165_g1_atu_get_hash,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3615) .atu_set_hash = mv88e6165_g1_atu_set_hash,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3616) .vtu_getnext = mv88e6352_g1_vtu_getnext,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3617) .vtu_loadpurge = mv88e6352_g1_vtu_loadpurge,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3618) .serdes_get_lane = mv88e6352_serdes_get_lane,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3619) .serdes_pcs_get_state = mv88e6352_serdes_pcs_get_state,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3620) .serdes_pcs_config = mv88e6352_serdes_pcs_config,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3621) .serdes_pcs_an_restart = mv88e6352_serdes_pcs_an_restart,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3622) .serdes_pcs_link_up = mv88e6352_serdes_pcs_link_up,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3623) .serdes_power = mv88e6352_serdes_power,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3624) .serdes_get_regs_len = mv88e6352_serdes_get_regs_len,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3625) .serdes_get_regs = mv88e6352_serdes_get_regs,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3626) .gpio_ops = &mv88e6352_gpio_ops,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3627) .phylink_validate = mv88e6352_phylink_validate,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3628) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3629)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3630) static const struct mv88e6xxx_ops mv88e6175_ops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3631) /* MV88E6XXX_FAMILY_6351 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3632) .ieee_pri_map = mv88e6085_g1_ieee_pri_map,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3633) .ip_pri_map = mv88e6085_g1_ip_pri_map,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3634) .irl_init_all = mv88e6352_g2_irl_init_all,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3635) .set_switch_mac = mv88e6xxx_g2_set_switch_mac,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3636) .phy_read = mv88e6xxx_g2_smi_phy_read,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3637) .phy_write = mv88e6xxx_g2_smi_phy_write,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3638) .port_set_link = mv88e6xxx_port_set_link,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3639) .port_set_rgmii_delay = mv88e6352_port_set_rgmii_delay,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3640) .port_set_speed_duplex = mv88e6185_port_set_speed_duplex,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3641) .port_tag_remap = mv88e6095_port_tag_remap,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3642) .port_set_policy = mv88e6352_port_set_policy,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3643) .port_set_frame_mode = mv88e6351_port_set_frame_mode,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3644) .port_set_egress_floods = mv88e6352_port_set_egress_floods,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3645) .port_set_ether_type = mv88e6351_port_set_ether_type,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3646) .port_set_jumbo_size = mv88e6165_port_set_jumbo_size,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3647) .port_egress_rate_limiting = mv88e6097_port_egress_rate_limiting,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3648) .port_pause_limit = mv88e6097_port_pause_limit,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3649) .port_disable_learn_limit = mv88e6xxx_port_disable_learn_limit,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3650) .port_disable_pri_override = mv88e6xxx_port_disable_pri_override,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3651) .port_get_cmode = mv88e6352_port_get_cmode,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3652) .port_setup_message_port = mv88e6xxx_setup_message_port,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3653) .stats_snapshot = mv88e6320_g1_stats_snapshot,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3654) .stats_set_histogram = mv88e6095_g1_stats_set_histogram,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3655) .stats_get_sset_count = mv88e6095_stats_get_sset_count,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3656) .stats_get_strings = mv88e6095_stats_get_strings,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3657) .stats_get_stats = mv88e6095_stats_get_stats,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3658) .set_cpu_port = mv88e6095_g1_set_cpu_port,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3659) .set_egress_port = mv88e6095_g1_set_egress_port,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3660) .watchdog_ops = &mv88e6097_watchdog_ops,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3661) .mgmt_rsvd2cpu = mv88e6352_g2_mgmt_rsvd2cpu,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3662) .pot_clear = mv88e6xxx_g2_pot_clear,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3663) .reset = mv88e6352_g1_reset,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3664) .atu_get_hash = mv88e6165_g1_atu_get_hash,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3665) .atu_set_hash = mv88e6165_g1_atu_set_hash,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3666) .vtu_getnext = mv88e6352_g1_vtu_getnext,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3667) .vtu_loadpurge = mv88e6352_g1_vtu_loadpurge,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3668) .phylink_validate = mv88e6185_phylink_validate,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3669) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3670)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3671) static const struct mv88e6xxx_ops mv88e6176_ops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3672) /* MV88E6XXX_FAMILY_6352 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3673) .ieee_pri_map = mv88e6085_g1_ieee_pri_map,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3674) .ip_pri_map = mv88e6085_g1_ip_pri_map,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3675) .irl_init_all = mv88e6352_g2_irl_init_all,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3676) .get_eeprom = mv88e6xxx_g2_get_eeprom16,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3677) .set_eeprom = mv88e6xxx_g2_set_eeprom16,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3678) .set_switch_mac = mv88e6xxx_g2_set_switch_mac,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3679) .phy_read = mv88e6xxx_g2_smi_phy_read,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3680) .phy_write = mv88e6xxx_g2_smi_phy_write,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3681) .port_set_link = mv88e6xxx_port_set_link,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3682) .port_set_rgmii_delay = mv88e6352_port_set_rgmii_delay,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3683) .port_set_speed_duplex = mv88e6352_port_set_speed_duplex,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3684) .port_tag_remap = mv88e6095_port_tag_remap,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3685) .port_set_policy = mv88e6352_port_set_policy,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3686) .port_set_frame_mode = mv88e6351_port_set_frame_mode,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3687) .port_set_egress_floods = mv88e6352_port_set_egress_floods,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3688) .port_set_ether_type = mv88e6351_port_set_ether_type,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3689) .port_set_jumbo_size = mv88e6165_port_set_jumbo_size,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3690) .port_egress_rate_limiting = mv88e6097_port_egress_rate_limiting,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3691) .port_pause_limit = mv88e6097_port_pause_limit,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3692) .port_disable_learn_limit = mv88e6xxx_port_disable_learn_limit,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3693) .port_disable_pri_override = mv88e6xxx_port_disable_pri_override,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3694) .port_get_cmode = mv88e6352_port_get_cmode,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3695) .port_setup_message_port = mv88e6xxx_setup_message_port,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3696) .stats_snapshot = mv88e6320_g1_stats_snapshot,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3697) .stats_set_histogram = mv88e6095_g1_stats_set_histogram,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3698) .stats_get_sset_count = mv88e6095_stats_get_sset_count,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3699) .stats_get_strings = mv88e6095_stats_get_strings,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3700) .stats_get_stats = mv88e6095_stats_get_stats,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3701) .set_cpu_port = mv88e6095_g1_set_cpu_port,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3702) .set_egress_port = mv88e6095_g1_set_egress_port,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3703) .watchdog_ops = &mv88e6097_watchdog_ops,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3704) .mgmt_rsvd2cpu = mv88e6352_g2_mgmt_rsvd2cpu,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3705) .pot_clear = mv88e6xxx_g2_pot_clear,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3706) .reset = mv88e6352_g1_reset,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3707) .rmu_disable = mv88e6352_g1_rmu_disable,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3708) .atu_get_hash = mv88e6165_g1_atu_get_hash,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3709) .atu_set_hash = mv88e6165_g1_atu_set_hash,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3710) .vtu_getnext = mv88e6352_g1_vtu_getnext,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3711) .vtu_loadpurge = mv88e6352_g1_vtu_loadpurge,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3712) .serdes_get_lane = mv88e6352_serdes_get_lane,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3713) .serdes_pcs_get_state = mv88e6352_serdes_pcs_get_state,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3714) .serdes_pcs_config = mv88e6352_serdes_pcs_config,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3715) .serdes_pcs_an_restart = mv88e6352_serdes_pcs_an_restart,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3716) .serdes_pcs_link_up = mv88e6352_serdes_pcs_link_up,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3717) .serdes_power = mv88e6352_serdes_power,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3718) .serdes_irq_mapping = mv88e6352_serdes_irq_mapping,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3719) .serdes_irq_enable = mv88e6352_serdes_irq_enable,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3720) .serdes_irq_status = mv88e6352_serdes_irq_status,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3721) .serdes_get_regs_len = mv88e6352_serdes_get_regs_len,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3722) .serdes_get_regs = mv88e6352_serdes_get_regs,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3723) .gpio_ops = &mv88e6352_gpio_ops,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3724) .phylink_validate = mv88e6352_phylink_validate,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3725) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3726)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3727) static const struct mv88e6xxx_ops mv88e6185_ops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3728) /* MV88E6XXX_FAMILY_6185 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3729) .ieee_pri_map = mv88e6085_g1_ieee_pri_map,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3730) .ip_pri_map = mv88e6085_g1_ip_pri_map,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3731) .set_switch_mac = mv88e6xxx_g1_set_switch_mac,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3732) .phy_read = mv88e6185_phy_ppu_read,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3733) .phy_write = mv88e6185_phy_ppu_write,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3734) .port_set_link = mv88e6xxx_port_set_link,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3735) .port_set_speed_duplex = mv88e6185_port_set_speed_duplex,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3736) .port_set_frame_mode = mv88e6085_port_set_frame_mode,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3737) .port_set_egress_floods = mv88e6185_port_set_egress_floods,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3738) .port_egress_rate_limiting = mv88e6095_port_egress_rate_limiting,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3739) .port_set_upstream_port = mv88e6095_port_set_upstream_port,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3740) .port_set_pause = mv88e6185_port_set_pause,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3741) .port_get_cmode = mv88e6185_port_get_cmode,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3742) .port_setup_message_port = mv88e6xxx_setup_message_port,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3743) .stats_snapshot = mv88e6xxx_g1_stats_snapshot,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3744) .stats_set_histogram = mv88e6095_g1_stats_set_histogram,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3745) .stats_get_sset_count = mv88e6095_stats_get_sset_count,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3746) .stats_get_strings = mv88e6095_stats_get_strings,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3747) .stats_get_stats = mv88e6095_stats_get_stats,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3748) .set_cpu_port = mv88e6095_g1_set_cpu_port,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3749) .set_egress_port = mv88e6095_g1_set_egress_port,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3750) .watchdog_ops = &mv88e6097_watchdog_ops,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3751) .mgmt_rsvd2cpu = mv88e6185_g2_mgmt_rsvd2cpu,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3752) .set_cascade_port = mv88e6185_g1_set_cascade_port,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3753) .ppu_enable = mv88e6185_g1_ppu_enable,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3754) .ppu_disable = mv88e6185_g1_ppu_disable,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3755) .reset = mv88e6185_g1_reset,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3756) .vtu_getnext = mv88e6185_g1_vtu_getnext,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3757) .vtu_loadpurge = mv88e6185_g1_vtu_loadpurge,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3758) .phylink_validate = mv88e6185_phylink_validate,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3759) .set_max_frame_size = mv88e6185_g1_set_max_frame_size,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3760) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3761)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3762) static const struct mv88e6xxx_ops mv88e6190_ops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3763) /* MV88E6XXX_FAMILY_6390 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3764) .setup_errata = mv88e6390_setup_errata,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3765) .irl_init_all = mv88e6390_g2_irl_init_all,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3766) .get_eeprom = mv88e6xxx_g2_get_eeprom8,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3767) .set_eeprom = mv88e6xxx_g2_set_eeprom8,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3768) .set_switch_mac = mv88e6xxx_g2_set_switch_mac,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3769) .phy_read = mv88e6xxx_g2_smi_phy_read,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3770) .phy_write = mv88e6xxx_g2_smi_phy_write,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3771) .port_set_link = mv88e6xxx_port_set_link,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3772) .port_set_rgmii_delay = mv88e6390_port_set_rgmii_delay,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3773) .port_set_speed_duplex = mv88e6390_port_set_speed_duplex,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3774) .port_max_speed_mode = mv88e6390_port_max_speed_mode,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3775) .port_tag_remap = mv88e6390_port_tag_remap,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3776) .port_set_policy = mv88e6352_port_set_policy,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3777) .port_set_frame_mode = mv88e6351_port_set_frame_mode,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3778) .port_set_egress_floods = mv88e6352_port_set_egress_floods,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3779) .port_set_ether_type = mv88e6351_port_set_ether_type,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3780) .port_set_jumbo_size = mv88e6165_port_set_jumbo_size,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3781) .port_pause_limit = mv88e6390_port_pause_limit,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3782) .port_disable_learn_limit = mv88e6xxx_port_disable_learn_limit,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3783) .port_disable_pri_override = mv88e6xxx_port_disable_pri_override,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3784) .port_get_cmode = mv88e6352_port_get_cmode,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3785) .port_set_cmode = mv88e6390_port_set_cmode,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3786) .port_setup_message_port = mv88e6xxx_setup_message_port,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3787) .stats_snapshot = mv88e6390_g1_stats_snapshot,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3788) .stats_set_histogram = mv88e6390_g1_stats_set_histogram,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3789) .stats_get_sset_count = mv88e6320_stats_get_sset_count,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3790) .stats_get_strings = mv88e6320_stats_get_strings,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3791) .stats_get_stats = mv88e6390_stats_get_stats,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3792) .set_cpu_port = mv88e6390_g1_set_cpu_port,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3793) .set_egress_port = mv88e6390_g1_set_egress_port,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3794) .watchdog_ops = &mv88e6390_watchdog_ops,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3795) .mgmt_rsvd2cpu = mv88e6390_g1_mgmt_rsvd2cpu,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3796) .pot_clear = mv88e6xxx_g2_pot_clear,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3797) .reset = mv88e6352_g1_reset,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3798) .rmu_disable = mv88e6390_g1_rmu_disable,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3799) .atu_get_hash = mv88e6165_g1_atu_get_hash,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3800) .atu_set_hash = mv88e6165_g1_atu_set_hash,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3801) .vtu_getnext = mv88e6390_g1_vtu_getnext,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3802) .vtu_loadpurge = mv88e6390_g1_vtu_loadpurge,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3803) .serdes_power = mv88e6390_serdes_power,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3804) .serdes_get_lane = mv88e6390_serdes_get_lane,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3805) /* Check status register pause & lpa register */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3806) .serdes_pcs_get_state = mv88e6390_serdes_pcs_get_state,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3807) .serdes_pcs_config = mv88e6390_serdes_pcs_config,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3808) .serdes_pcs_an_restart = mv88e6390_serdes_pcs_an_restart,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3809) .serdes_pcs_link_up = mv88e6390_serdes_pcs_link_up,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3810) .serdes_irq_mapping = mv88e6390_serdes_irq_mapping,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3811) .serdes_irq_enable = mv88e6390_serdes_irq_enable,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3812) .serdes_irq_status = mv88e6390_serdes_irq_status,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3813) .serdes_get_strings = mv88e6390_serdes_get_strings,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3814) .serdes_get_stats = mv88e6390_serdes_get_stats,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3815) .serdes_get_regs_len = mv88e6390_serdes_get_regs_len,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3816) .serdes_get_regs = mv88e6390_serdes_get_regs,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3817) .gpio_ops = &mv88e6352_gpio_ops,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3818) .phylink_validate = mv88e6390_phylink_validate,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3819) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3820)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3821) static const struct mv88e6xxx_ops mv88e6190x_ops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3822) /* MV88E6XXX_FAMILY_6390 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3823) .setup_errata = mv88e6390_setup_errata,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3824) .irl_init_all = mv88e6390_g2_irl_init_all,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3825) .get_eeprom = mv88e6xxx_g2_get_eeprom8,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3826) .set_eeprom = mv88e6xxx_g2_set_eeprom8,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3827) .set_switch_mac = mv88e6xxx_g2_set_switch_mac,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3828) .phy_read = mv88e6xxx_g2_smi_phy_read,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3829) .phy_write = mv88e6xxx_g2_smi_phy_write,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3830) .port_set_link = mv88e6xxx_port_set_link,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3831) .port_set_rgmii_delay = mv88e6390_port_set_rgmii_delay,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3832) .port_set_speed_duplex = mv88e6390x_port_set_speed_duplex,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3833) .port_max_speed_mode = mv88e6390x_port_max_speed_mode,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3834) .port_tag_remap = mv88e6390_port_tag_remap,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3835) .port_set_policy = mv88e6352_port_set_policy,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3836) .port_set_frame_mode = mv88e6351_port_set_frame_mode,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3837) .port_set_egress_floods = mv88e6352_port_set_egress_floods,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3838) .port_set_ether_type = mv88e6351_port_set_ether_type,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3839) .port_set_jumbo_size = mv88e6165_port_set_jumbo_size,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3840) .port_pause_limit = mv88e6390_port_pause_limit,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3841) .port_disable_learn_limit = mv88e6xxx_port_disable_learn_limit,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3842) .port_disable_pri_override = mv88e6xxx_port_disable_pri_override,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3843) .port_get_cmode = mv88e6352_port_get_cmode,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3844) .port_set_cmode = mv88e6390x_port_set_cmode,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3845) .port_setup_message_port = mv88e6xxx_setup_message_port,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3846) .stats_snapshot = mv88e6390_g1_stats_snapshot,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3847) .stats_set_histogram = mv88e6390_g1_stats_set_histogram,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3848) .stats_get_sset_count = mv88e6320_stats_get_sset_count,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3849) .stats_get_strings = mv88e6320_stats_get_strings,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3850) .stats_get_stats = mv88e6390_stats_get_stats,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3851) .set_cpu_port = mv88e6390_g1_set_cpu_port,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3852) .set_egress_port = mv88e6390_g1_set_egress_port,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3853) .watchdog_ops = &mv88e6390_watchdog_ops,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3854) .mgmt_rsvd2cpu = mv88e6390_g1_mgmt_rsvd2cpu,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3855) .pot_clear = mv88e6xxx_g2_pot_clear,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3856) .reset = mv88e6352_g1_reset,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3857) .rmu_disable = mv88e6390_g1_rmu_disable,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3858) .atu_get_hash = mv88e6165_g1_atu_get_hash,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3859) .atu_set_hash = mv88e6165_g1_atu_set_hash,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3860) .vtu_getnext = mv88e6390_g1_vtu_getnext,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3861) .vtu_loadpurge = mv88e6390_g1_vtu_loadpurge,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3862) .serdes_power = mv88e6390_serdes_power,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3863) .serdes_get_lane = mv88e6390x_serdes_get_lane,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3864) /* Check status register pause & lpa register */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3865) .serdes_pcs_get_state = mv88e6390_serdes_pcs_get_state,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3866) .serdes_pcs_config = mv88e6390_serdes_pcs_config,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3867) .serdes_pcs_an_restart = mv88e6390_serdes_pcs_an_restart,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3868) .serdes_pcs_link_up = mv88e6390_serdes_pcs_link_up,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3869) .serdes_irq_mapping = mv88e6390_serdes_irq_mapping,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3870) .serdes_irq_enable = mv88e6390_serdes_irq_enable,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3871) .serdes_irq_status = mv88e6390_serdes_irq_status,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3872) .serdes_get_strings = mv88e6390_serdes_get_strings,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3873) .serdes_get_stats = mv88e6390_serdes_get_stats,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3874) .serdes_get_regs_len = mv88e6390_serdes_get_regs_len,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3875) .serdes_get_regs = mv88e6390_serdes_get_regs,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3876) .gpio_ops = &mv88e6352_gpio_ops,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3877) .phylink_validate = mv88e6390x_phylink_validate,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3878) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3879)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3880) static const struct mv88e6xxx_ops mv88e6191_ops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3881) /* MV88E6XXX_FAMILY_6390 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3882) .setup_errata = mv88e6390_setup_errata,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3883) .irl_init_all = mv88e6390_g2_irl_init_all,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3884) .get_eeprom = mv88e6xxx_g2_get_eeprom8,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3885) .set_eeprom = mv88e6xxx_g2_set_eeprom8,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3886) .set_switch_mac = mv88e6xxx_g2_set_switch_mac,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3887) .phy_read = mv88e6xxx_g2_smi_phy_read,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3888) .phy_write = mv88e6xxx_g2_smi_phy_write,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3889) .port_set_link = mv88e6xxx_port_set_link,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3890) .port_set_rgmii_delay = mv88e6390_port_set_rgmii_delay,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3891) .port_set_speed_duplex = mv88e6390_port_set_speed_duplex,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3892) .port_max_speed_mode = mv88e6390_port_max_speed_mode,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3893) .port_tag_remap = mv88e6390_port_tag_remap,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3894) .port_set_frame_mode = mv88e6351_port_set_frame_mode,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3895) .port_set_egress_floods = mv88e6352_port_set_egress_floods,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3896) .port_set_ether_type = mv88e6351_port_set_ether_type,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3897) .port_pause_limit = mv88e6390_port_pause_limit,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3898) .port_disable_learn_limit = mv88e6xxx_port_disable_learn_limit,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3899) .port_disable_pri_override = mv88e6xxx_port_disable_pri_override,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3900) .port_get_cmode = mv88e6352_port_get_cmode,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3901) .port_set_cmode = mv88e6390_port_set_cmode,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3902) .port_setup_message_port = mv88e6xxx_setup_message_port,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3903) .stats_snapshot = mv88e6390_g1_stats_snapshot,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3904) .stats_set_histogram = mv88e6390_g1_stats_set_histogram,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3905) .stats_get_sset_count = mv88e6320_stats_get_sset_count,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3906) .stats_get_strings = mv88e6320_stats_get_strings,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3907) .stats_get_stats = mv88e6390_stats_get_stats,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3908) .set_cpu_port = mv88e6390_g1_set_cpu_port,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3909) .set_egress_port = mv88e6390_g1_set_egress_port,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3910) .watchdog_ops = &mv88e6390_watchdog_ops,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3911) .mgmt_rsvd2cpu = mv88e6390_g1_mgmt_rsvd2cpu,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3912) .pot_clear = mv88e6xxx_g2_pot_clear,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3913) .reset = mv88e6352_g1_reset,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3914) .rmu_disable = mv88e6390_g1_rmu_disable,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3915) .atu_get_hash = mv88e6165_g1_atu_get_hash,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3916) .atu_set_hash = mv88e6165_g1_atu_set_hash,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3917) .vtu_getnext = mv88e6390_g1_vtu_getnext,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3918) .vtu_loadpurge = mv88e6390_g1_vtu_loadpurge,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3919) .serdes_power = mv88e6390_serdes_power,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3920) .serdes_get_lane = mv88e6390_serdes_get_lane,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3921) /* Check status register pause & lpa register */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3922) .serdes_pcs_get_state = mv88e6390_serdes_pcs_get_state,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3923) .serdes_pcs_config = mv88e6390_serdes_pcs_config,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3924) .serdes_pcs_an_restart = mv88e6390_serdes_pcs_an_restart,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3925) .serdes_pcs_link_up = mv88e6390_serdes_pcs_link_up,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3926) .serdes_irq_mapping = mv88e6390_serdes_irq_mapping,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3927) .serdes_irq_enable = mv88e6390_serdes_irq_enable,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3928) .serdes_irq_status = mv88e6390_serdes_irq_status,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3929) .serdes_get_strings = mv88e6390_serdes_get_strings,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3930) .serdes_get_stats = mv88e6390_serdes_get_stats,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3931) .serdes_get_regs_len = mv88e6390_serdes_get_regs_len,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3932) .serdes_get_regs = mv88e6390_serdes_get_regs,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3933) .avb_ops = &mv88e6390_avb_ops,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3934) .ptp_ops = &mv88e6352_ptp_ops,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3935) .phylink_validate = mv88e6390_phylink_validate,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3936) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3937)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3938) static const struct mv88e6xxx_ops mv88e6240_ops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3939) /* MV88E6XXX_FAMILY_6352 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3940) .ieee_pri_map = mv88e6085_g1_ieee_pri_map,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3941) .ip_pri_map = mv88e6085_g1_ip_pri_map,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3942) .irl_init_all = mv88e6352_g2_irl_init_all,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3943) .get_eeprom = mv88e6xxx_g2_get_eeprom16,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3944) .set_eeprom = mv88e6xxx_g2_set_eeprom16,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3945) .set_switch_mac = mv88e6xxx_g2_set_switch_mac,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3946) .phy_read = mv88e6xxx_g2_smi_phy_read,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3947) .phy_write = mv88e6xxx_g2_smi_phy_write,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3948) .port_set_link = mv88e6xxx_port_set_link,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3949) .port_set_rgmii_delay = mv88e6352_port_set_rgmii_delay,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3950) .port_set_speed_duplex = mv88e6352_port_set_speed_duplex,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3951) .port_tag_remap = mv88e6095_port_tag_remap,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3952) .port_set_policy = mv88e6352_port_set_policy,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3953) .port_set_frame_mode = mv88e6351_port_set_frame_mode,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3954) .port_set_egress_floods = mv88e6352_port_set_egress_floods,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3955) .port_set_ether_type = mv88e6351_port_set_ether_type,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3956) .port_set_jumbo_size = mv88e6165_port_set_jumbo_size,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3957) .port_egress_rate_limiting = mv88e6097_port_egress_rate_limiting,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3958) .port_pause_limit = mv88e6097_port_pause_limit,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3959) .port_disable_learn_limit = mv88e6xxx_port_disable_learn_limit,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3960) .port_disable_pri_override = mv88e6xxx_port_disable_pri_override,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3961) .port_get_cmode = mv88e6352_port_get_cmode,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3962) .port_setup_message_port = mv88e6xxx_setup_message_port,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3963) .stats_snapshot = mv88e6320_g1_stats_snapshot,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3964) .stats_set_histogram = mv88e6095_g1_stats_set_histogram,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3965) .stats_get_sset_count = mv88e6095_stats_get_sset_count,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3966) .stats_get_strings = mv88e6095_stats_get_strings,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3967) .stats_get_stats = mv88e6095_stats_get_stats,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3968) .set_cpu_port = mv88e6095_g1_set_cpu_port,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3969) .set_egress_port = mv88e6095_g1_set_egress_port,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3970) .watchdog_ops = &mv88e6097_watchdog_ops,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3971) .mgmt_rsvd2cpu = mv88e6352_g2_mgmt_rsvd2cpu,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3972) .pot_clear = mv88e6xxx_g2_pot_clear,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3973) .reset = mv88e6352_g1_reset,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3974) .rmu_disable = mv88e6352_g1_rmu_disable,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3975) .atu_get_hash = mv88e6165_g1_atu_get_hash,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3976) .atu_set_hash = mv88e6165_g1_atu_set_hash,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3977) .vtu_getnext = mv88e6352_g1_vtu_getnext,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3978) .vtu_loadpurge = mv88e6352_g1_vtu_loadpurge,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3979) .serdes_get_lane = mv88e6352_serdes_get_lane,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3980) .serdes_pcs_get_state = mv88e6352_serdes_pcs_get_state,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3981) .serdes_pcs_config = mv88e6352_serdes_pcs_config,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3982) .serdes_pcs_an_restart = mv88e6352_serdes_pcs_an_restart,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3983) .serdes_pcs_link_up = mv88e6352_serdes_pcs_link_up,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3984) .serdes_power = mv88e6352_serdes_power,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3985) .serdes_irq_mapping = mv88e6352_serdes_irq_mapping,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3986) .serdes_irq_enable = mv88e6352_serdes_irq_enable,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3987) .serdes_irq_status = mv88e6352_serdes_irq_status,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3988) .serdes_get_regs_len = mv88e6352_serdes_get_regs_len,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3989) .serdes_get_regs = mv88e6352_serdes_get_regs,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3990) .gpio_ops = &mv88e6352_gpio_ops,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3991) .avb_ops = &mv88e6352_avb_ops,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3992) .ptp_ops = &mv88e6352_ptp_ops,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3993) .phylink_validate = mv88e6352_phylink_validate,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3994) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3995)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3996) static const struct mv88e6xxx_ops mv88e6250_ops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3997) /* MV88E6XXX_FAMILY_6250 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3998) .ieee_pri_map = mv88e6250_g1_ieee_pri_map,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3999) .ip_pri_map = mv88e6085_g1_ip_pri_map,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4000) .irl_init_all = mv88e6352_g2_irl_init_all,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4001) .get_eeprom = mv88e6xxx_g2_get_eeprom16,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4002) .set_eeprom = mv88e6xxx_g2_set_eeprom16,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4003) .set_switch_mac = mv88e6xxx_g2_set_switch_mac,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4004) .phy_read = mv88e6xxx_g2_smi_phy_read,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4005) .phy_write = mv88e6xxx_g2_smi_phy_write,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4006) .port_set_link = mv88e6xxx_port_set_link,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4007) .port_set_rgmii_delay = mv88e6352_port_set_rgmii_delay,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4008) .port_set_speed_duplex = mv88e6250_port_set_speed_duplex,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4009) .port_tag_remap = mv88e6095_port_tag_remap,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4010) .port_set_frame_mode = mv88e6351_port_set_frame_mode,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4011) .port_set_egress_floods = mv88e6352_port_set_egress_floods,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4012) .port_set_ether_type = mv88e6351_port_set_ether_type,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4013) .port_egress_rate_limiting = mv88e6097_port_egress_rate_limiting,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4014) .port_pause_limit = mv88e6097_port_pause_limit,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4015) .port_disable_pri_override = mv88e6xxx_port_disable_pri_override,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4016) .stats_snapshot = mv88e6320_g1_stats_snapshot,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4017) .stats_set_histogram = mv88e6095_g1_stats_set_histogram,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4018) .stats_get_sset_count = mv88e6250_stats_get_sset_count,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4019) .stats_get_strings = mv88e6250_stats_get_strings,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4020) .stats_get_stats = mv88e6250_stats_get_stats,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4021) .set_cpu_port = mv88e6095_g1_set_cpu_port,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4022) .set_egress_port = mv88e6095_g1_set_egress_port,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4023) .watchdog_ops = &mv88e6250_watchdog_ops,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4024) .mgmt_rsvd2cpu = mv88e6352_g2_mgmt_rsvd2cpu,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4025) .pot_clear = mv88e6xxx_g2_pot_clear,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4026) .reset = mv88e6250_g1_reset,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4027) .vtu_getnext = mv88e6250_g1_vtu_getnext,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4028) .vtu_loadpurge = mv88e6250_g1_vtu_loadpurge,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4029) .avb_ops = &mv88e6352_avb_ops,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4030) .ptp_ops = &mv88e6250_ptp_ops,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4031) .phylink_validate = mv88e6065_phylink_validate,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4032) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4033)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4034) static const struct mv88e6xxx_ops mv88e6290_ops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4035) /* MV88E6XXX_FAMILY_6390 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4036) .setup_errata = mv88e6390_setup_errata,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4037) .irl_init_all = mv88e6390_g2_irl_init_all,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4038) .get_eeprom = mv88e6xxx_g2_get_eeprom8,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4039) .set_eeprom = mv88e6xxx_g2_set_eeprom8,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4040) .set_switch_mac = mv88e6xxx_g2_set_switch_mac,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4041) .phy_read = mv88e6xxx_g2_smi_phy_read,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4042) .phy_write = mv88e6xxx_g2_smi_phy_write,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4043) .port_set_link = mv88e6xxx_port_set_link,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4044) .port_set_rgmii_delay = mv88e6390_port_set_rgmii_delay,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4045) .port_set_speed_duplex = mv88e6390_port_set_speed_duplex,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4046) .port_max_speed_mode = mv88e6390_port_max_speed_mode,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4047) .port_tag_remap = mv88e6390_port_tag_remap,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4048) .port_set_policy = mv88e6352_port_set_policy,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4049) .port_set_frame_mode = mv88e6351_port_set_frame_mode,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4050) .port_set_egress_floods = mv88e6352_port_set_egress_floods,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4051) .port_set_ether_type = mv88e6351_port_set_ether_type,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4052) .port_pause_limit = mv88e6390_port_pause_limit,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4053) .port_disable_learn_limit = mv88e6xxx_port_disable_learn_limit,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4054) .port_disable_pri_override = mv88e6xxx_port_disable_pri_override,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4055) .port_get_cmode = mv88e6352_port_get_cmode,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4056) .port_set_cmode = mv88e6390_port_set_cmode,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4057) .port_setup_message_port = mv88e6xxx_setup_message_port,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4058) .stats_snapshot = mv88e6390_g1_stats_snapshot,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4059) .stats_set_histogram = mv88e6390_g1_stats_set_histogram,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4060) .stats_get_sset_count = mv88e6320_stats_get_sset_count,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4061) .stats_get_strings = mv88e6320_stats_get_strings,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4062) .stats_get_stats = mv88e6390_stats_get_stats,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4063) .set_cpu_port = mv88e6390_g1_set_cpu_port,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4064) .set_egress_port = mv88e6390_g1_set_egress_port,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4065) .watchdog_ops = &mv88e6390_watchdog_ops,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4066) .mgmt_rsvd2cpu = mv88e6390_g1_mgmt_rsvd2cpu,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4067) .pot_clear = mv88e6xxx_g2_pot_clear,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4068) .reset = mv88e6352_g1_reset,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4069) .rmu_disable = mv88e6390_g1_rmu_disable,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4070) .atu_get_hash = mv88e6165_g1_atu_get_hash,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4071) .atu_set_hash = mv88e6165_g1_atu_set_hash,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4072) .vtu_getnext = mv88e6390_g1_vtu_getnext,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4073) .vtu_loadpurge = mv88e6390_g1_vtu_loadpurge,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4074) .serdes_power = mv88e6390_serdes_power,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4075) .serdes_get_lane = mv88e6390_serdes_get_lane,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4076) /* Check status register pause & lpa register */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4077) .serdes_pcs_get_state = mv88e6390_serdes_pcs_get_state,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4078) .serdes_pcs_config = mv88e6390_serdes_pcs_config,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4079) .serdes_pcs_an_restart = mv88e6390_serdes_pcs_an_restart,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4080) .serdes_pcs_link_up = mv88e6390_serdes_pcs_link_up,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4081) .serdes_irq_mapping = mv88e6390_serdes_irq_mapping,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4082) .serdes_irq_enable = mv88e6390_serdes_irq_enable,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4083) .serdes_irq_status = mv88e6390_serdes_irq_status,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4084) .serdes_get_strings = mv88e6390_serdes_get_strings,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4085) .serdes_get_stats = mv88e6390_serdes_get_stats,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4086) .serdes_get_regs_len = mv88e6390_serdes_get_regs_len,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4087) .serdes_get_regs = mv88e6390_serdes_get_regs,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4088) .gpio_ops = &mv88e6352_gpio_ops,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4089) .avb_ops = &mv88e6390_avb_ops,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4090) .ptp_ops = &mv88e6352_ptp_ops,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4091) .phylink_validate = mv88e6390_phylink_validate,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4092) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4093)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4094) static const struct mv88e6xxx_ops mv88e6320_ops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4095) /* MV88E6XXX_FAMILY_6320 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4096) .ieee_pri_map = mv88e6085_g1_ieee_pri_map,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4097) .ip_pri_map = mv88e6085_g1_ip_pri_map,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4098) .irl_init_all = mv88e6352_g2_irl_init_all,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4099) .get_eeprom = mv88e6xxx_g2_get_eeprom16,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4100) .set_eeprom = mv88e6xxx_g2_set_eeprom16,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4101) .set_switch_mac = mv88e6xxx_g2_set_switch_mac,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4102) .phy_read = mv88e6xxx_g2_smi_phy_read,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4103) .phy_write = mv88e6xxx_g2_smi_phy_write,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4104) .port_set_link = mv88e6xxx_port_set_link,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4105) .port_set_speed_duplex = mv88e6185_port_set_speed_duplex,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4106) .port_tag_remap = mv88e6095_port_tag_remap,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4107) .port_set_frame_mode = mv88e6351_port_set_frame_mode,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4108) .port_set_egress_floods = mv88e6352_port_set_egress_floods,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4109) .port_set_ether_type = mv88e6351_port_set_ether_type,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4110) .port_set_jumbo_size = mv88e6165_port_set_jumbo_size,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4111) .port_egress_rate_limiting = mv88e6097_port_egress_rate_limiting,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4112) .port_pause_limit = mv88e6097_port_pause_limit,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4113) .port_disable_learn_limit = mv88e6xxx_port_disable_learn_limit,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4114) .port_disable_pri_override = mv88e6xxx_port_disable_pri_override,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4115) .port_get_cmode = mv88e6352_port_get_cmode,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4116) .port_setup_message_port = mv88e6xxx_setup_message_port,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4117) .stats_snapshot = mv88e6320_g1_stats_snapshot,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4118) .stats_set_histogram = mv88e6095_g1_stats_set_histogram,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4119) .stats_get_sset_count = mv88e6320_stats_get_sset_count,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4120) .stats_get_strings = mv88e6320_stats_get_strings,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4121) .stats_get_stats = mv88e6320_stats_get_stats,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4122) .set_cpu_port = mv88e6095_g1_set_cpu_port,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4123) .set_egress_port = mv88e6095_g1_set_egress_port,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4124) .watchdog_ops = &mv88e6390_watchdog_ops,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4125) .mgmt_rsvd2cpu = mv88e6352_g2_mgmt_rsvd2cpu,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4126) .pot_clear = mv88e6xxx_g2_pot_clear,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4127) .reset = mv88e6352_g1_reset,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4128) .vtu_getnext = mv88e6185_g1_vtu_getnext,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4129) .vtu_loadpurge = mv88e6185_g1_vtu_loadpurge,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4130) .gpio_ops = &mv88e6352_gpio_ops,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4131) .avb_ops = &mv88e6352_avb_ops,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4132) .ptp_ops = &mv88e6352_ptp_ops,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4133) .phylink_validate = mv88e6185_phylink_validate,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4134) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4135)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4136) static const struct mv88e6xxx_ops mv88e6321_ops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4137) /* MV88E6XXX_FAMILY_6320 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4138) .ieee_pri_map = mv88e6085_g1_ieee_pri_map,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4139) .ip_pri_map = mv88e6085_g1_ip_pri_map,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4140) .irl_init_all = mv88e6352_g2_irl_init_all,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4141) .get_eeprom = mv88e6xxx_g2_get_eeprom16,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4142) .set_eeprom = mv88e6xxx_g2_set_eeprom16,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4143) .set_switch_mac = mv88e6xxx_g2_set_switch_mac,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4144) .phy_read = mv88e6xxx_g2_smi_phy_read,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4145) .phy_write = mv88e6xxx_g2_smi_phy_write,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4146) .port_set_link = mv88e6xxx_port_set_link,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4147) .port_set_speed_duplex = mv88e6185_port_set_speed_duplex,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4148) .port_tag_remap = mv88e6095_port_tag_remap,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4149) .port_set_frame_mode = mv88e6351_port_set_frame_mode,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4150) .port_set_egress_floods = mv88e6352_port_set_egress_floods,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4151) .port_set_ether_type = mv88e6351_port_set_ether_type,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4152) .port_set_jumbo_size = mv88e6165_port_set_jumbo_size,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4153) .port_egress_rate_limiting = mv88e6097_port_egress_rate_limiting,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4154) .port_pause_limit = mv88e6097_port_pause_limit,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4155) .port_disable_learn_limit = mv88e6xxx_port_disable_learn_limit,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4156) .port_disable_pri_override = mv88e6xxx_port_disable_pri_override,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4157) .port_get_cmode = mv88e6352_port_get_cmode,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4158) .port_setup_message_port = mv88e6xxx_setup_message_port,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4159) .stats_snapshot = mv88e6320_g1_stats_snapshot,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4160) .stats_set_histogram = mv88e6095_g1_stats_set_histogram,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4161) .stats_get_sset_count = mv88e6320_stats_get_sset_count,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4162) .stats_get_strings = mv88e6320_stats_get_strings,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4163) .stats_get_stats = mv88e6320_stats_get_stats,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4164) .set_cpu_port = mv88e6095_g1_set_cpu_port,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4165) .set_egress_port = mv88e6095_g1_set_egress_port,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4166) .watchdog_ops = &mv88e6390_watchdog_ops,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4167) .reset = mv88e6352_g1_reset,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4168) .vtu_getnext = mv88e6185_g1_vtu_getnext,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4169) .vtu_loadpurge = mv88e6185_g1_vtu_loadpurge,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4170) .gpio_ops = &mv88e6352_gpio_ops,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4171) .avb_ops = &mv88e6352_avb_ops,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4172) .ptp_ops = &mv88e6352_ptp_ops,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4173) .phylink_validate = mv88e6185_phylink_validate,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4174) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4175)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4176) static const struct mv88e6xxx_ops mv88e6341_ops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4177) /* MV88E6XXX_FAMILY_6341 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4178) .ieee_pri_map = mv88e6085_g1_ieee_pri_map,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4179) .ip_pri_map = mv88e6085_g1_ip_pri_map,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4180) .irl_init_all = mv88e6352_g2_irl_init_all,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4181) .get_eeprom = mv88e6xxx_g2_get_eeprom8,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4182) .set_eeprom = mv88e6xxx_g2_set_eeprom8,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4183) .set_switch_mac = mv88e6xxx_g2_set_switch_mac,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4184) .phy_read = mv88e6xxx_g2_smi_phy_read,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4185) .phy_write = mv88e6xxx_g2_smi_phy_write,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4186) .port_set_link = mv88e6xxx_port_set_link,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4187) .port_set_rgmii_delay = mv88e6390_port_set_rgmii_delay,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4188) .port_set_speed_duplex = mv88e6341_port_set_speed_duplex,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4189) .port_max_speed_mode = mv88e6341_port_max_speed_mode,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4190) .port_tag_remap = mv88e6095_port_tag_remap,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4191) .port_set_frame_mode = mv88e6351_port_set_frame_mode,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4192) .port_set_egress_floods = mv88e6352_port_set_egress_floods,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4193) .port_set_ether_type = mv88e6351_port_set_ether_type,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4194) .port_set_jumbo_size = mv88e6165_port_set_jumbo_size,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4195) .port_egress_rate_limiting = mv88e6097_port_egress_rate_limiting,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4196) .port_pause_limit = mv88e6097_port_pause_limit,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4197) .port_disable_learn_limit = mv88e6xxx_port_disable_learn_limit,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4198) .port_disable_pri_override = mv88e6xxx_port_disable_pri_override,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4199) .port_get_cmode = mv88e6352_port_get_cmode,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4200) .port_set_cmode = mv88e6341_port_set_cmode,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4201) .port_setup_message_port = mv88e6xxx_setup_message_port,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4202) .stats_snapshot = mv88e6390_g1_stats_snapshot,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4203) .stats_set_histogram = mv88e6390_g1_stats_set_histogram,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4204) .stats_get_sset_count = mv88e6320_stats_get_sset_count,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4205) .stats_get_strings = mv88e6320_stats_get_strings,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4206) .stats_get_stats = mv88e6390_stats_get_stats,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4207) .set_cpu_port = mv88e6390_g1_set_cpu_port,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4208) .set_egress_port = mv88e6390_g1_set_egress_port,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4209) .watchdog_ops = &mv88e6390_watchdog_ops,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4210) .mgmt_rsvd2cpu = mv88e6390_g1_mgmt_rsvd2cpu,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4211) .pot_clear = mv88e6xxx_g2_pot_clear,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4212) .reset = mv88e6352_g1_reset,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4213) .rmu_disable = mv88e6390_g1_rmu_disable,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4214) .atu_get_hash = mv88e6165_g1_atu_get_hash,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4215) .atu_set_hash = mv88e6165_g1_atu_set_hash,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4216) .vtu_getnext = mv88e6352_g1_vtu_getnext,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4217) .vtu_loadpurge = mv88e6352_g1_vtu_loadpurge,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4218) .serdes_power = mv88e6390_serdes_power,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4219) .serdes_get_lane = mv88e6341_serdes_get_lane,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4220) /* Check status register pause & lpa register */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4221) .serdes_pcs_get_state = mv88e6390_serdes_pcs_get_state,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4222) .serdes_pcs_config = mv88e6390_serdes_pcs_config,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4223) .serdes_pcs_an_restart = mv88e6390_serdes_pcs_an_restart,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4224) .serdes_pcs_link_up = mv88e6390_serdes_pcs_link_up,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4225) .serdes_irq_mapping = mv88e6390_serdes_irq_mapping,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4226) .serdes_irq_enable = mv88e6390_serdes_irq_enable,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4227) .serdes_irq_status = mv88e6390_serdes_irq_status,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4228) .gpio_ops = &mv88e6352_gpio_ops,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4229) .avb_ops = &mv88e6390_avb_ops,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4230) .ptp_ops = &mv88e6352_ptp_ops,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4231) .serdes_get_sset_count = mv88e6390_serdes_get_sset_count,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4232) .serdes_get_strings = mv88e6390_serdes_get_strings,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4233) .serdes_get_stats = mv88e6390_serdes_get_stats,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4234) .serdes_get_regs_len = mv88e6390_serdes_get_regs_len,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4235) .serdes_get_regs = mv88e6390_serdes_get_regs,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4236) .phylink_validate = mv88e6341_phylink_validate,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4237) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4238)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4239) static const struct mv88e6xxx_ops mv88e6350_ops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4240) /* MV88E6XXX_FAMILY_6351 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4241) .ieee_pri_map = mv88e6085_g1_ieee_pri_map,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4242) .ip_pri_map = mv88e6085_g1_ip_pri_map,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4243) .irl_init_all = mv88e6352_g2_irl_init_all,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4244) .set_switch_mac = mv88e6xxx_g2_set_switch_mac,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4245) .phy_read = mv88e6xxx_g2_smi_phy_read,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4246) .phy_write = mv88e6xxx_g2_smi_phy_write,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4247) .port_set_link = mv88e6xxx_port_set_link,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4248) .port_set_rgmii_delay = mv88e6352_port_set_rgmii_delay,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4249) .port_set_speed_duplex = mv88e6185_port_set_speed_duplex,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4250) .port_tag_remap = mv88e6095_port_tag_remap,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4251) .port_set_frame_mode = mv88e6351_port_set_frame_mode,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4252) .port_set_egress_floods = mv88e6352_port_set_egress_floods,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4253) .port_set_ether_type = mv88e6351_port_set_ether_type,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4254) .port_set_jumbo_size = mv88e6165_port_set_jumbo_size,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4255) .port_egress_rate_limiting = mv88e6097_port_egress_rate_limiting,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4256) .port_pause_limit = mv88e6097_port_pause_limit,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4257) .port_disable_learn_limit = mv88e6xxx_port_disable_learn_limit,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4258) .port_disable_pri_override = mv88e6xxx_port_disable_pri_override,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4259) .port_get_cmode = mv88e6352_port_get_cmode,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4260) .port_setup_message_port = mv88e6xxx_setup_message_port,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4261) .stats_snapshot = mv88e6320_g1_stats_snapshot,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4262) .stats_set_histogram = mv88e6095_g1_stats_set_histogram,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4263) .stats_get_sset_count = mv88e6095_stats_get_sset_count,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4264) .stats_get_strings = mv88e6095_stats_get_strings,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4265) .stats_get_stats = mv88e6095_stats_get_stats,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4266) .set_cpu_port = mv88e6095_g1_set_cpu_port,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4267) .set_egress_port = mv88e6095_g1_set_egress_port,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4268) .watchdog_ops = &mv88e6097_watchdog_ops,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4269) .mgmt_rsvd2cpu = mv88e6352_g2_mgmt_rsvd2cpu,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4270) .pot_clear = mv88e6xxx_g2_pot_clear,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4271) .reset = mv88e6352_g1_reset,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4272) .atu_get_hash = mv88e6165_g1_atu_get_hash,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4273) .atu_set_hash = mv88e6165_g1_atu_set_hash,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4274) .vtu_getnext = mv88e6352_g1_vtu_getnext,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4275) .vtu_loadpurge = mv88e6352_g1_vtu_loadpurge,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4276) .phylink_validate = mv88e6185_phylink_validate,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4277) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4278)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4279) static const struct mv88e6xxx_ops mv88e6351_ops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4280) /* MV88E6XXX_FAMILY_6351 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4281) .ieee_pri_map = mv88e6085_g1_ieee_pri_map,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4282) .ip_pri_map = mv88e6085_g1_ip_pri_map,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4283) .irl_init_all = mv88e6352_g2_irl_init_all,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4284) .set_switch_mac = mv88e6xxx_g2_set_switch_mac,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4285) .phy_read = mv88e6xxx_g2_smi_phy_read,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4286) .phy_write = mv88e6xxx_g2_smi_phy_write,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4287) .port_set_link = mv88e6xxx_port_set_link,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4288) .port_set_rgmii_delay = mv88e6352_port_set_rgmii_delay,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4289) .port_set_speed_duplex = mv88e6185_port_set_speed_duplex,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4290) .port_tag_remap = mv88e6095_port_tag_remap,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4291) .port_set_policy = mv88e6352_port_set_policy,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4292) .port_set_frame_mode = mv88e6351_port_set_frame_mode,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4293) .port_set_egress_floods = mv88e6352_port_set_egress_floods,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4294) .port_set_ether_type = mv88e6351_port_set_ether_type,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4295) .port_set_jumbo_size = mv88e6165_port_set_jumbo_size,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4296) .port_egress_rate_limiting = mv88e6097_port_egress_rate_limiting,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4297) .port_pause_limit = mv88e6097_port_pause_limit,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4298) .port_disable_learn_limit = mv88e6xxx_port_disable_learn_limit,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4299) .port_disable_pri_override = mv88e6xxx_port_disable_pri_override,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4300) .port_get_cmode = mv88e6352_port_get_cmode,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4301) .port_setup_message_port = mv88e6xxx_setup_message_port,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4302) .stats_snapshot = mv88e6320_g1_stats_snapshot,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4303) .stats_set_histogram = mv88e6095_g1_stats_set_histogram,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4304) .stats_get_sset_count = mv88e6095_stats_get_sset_count,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4305) .stats_get_strings = mv88e6095_stats_get_strings,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4306) .stats_get_stats = mv88e6095_stats_get_stats,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4307) .set_cpu_port = mv88e6095_g1_set_cpu_port,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4308) .set_egress_port = mv88e6095_g1_set_egress_port,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4309) .watchdog_ops = &mv88e6097_watchdog_ops,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4310) .mgmt_rsvd2cpu = mv88e6352_g2_mgmt_rsvd2cpu,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4311) .pot_clear = mv88e6xxx_g2_pot_clear,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4312) .reset = mv88e6352_g1_reset,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4313) .atu_get_hash = mv88e6165_g1_atu_get_hash,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4314) .atu_set_hash = mv88e6165_g1_atu_set_hash,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4315) .vtu_getnext = mv88e6352_g1_vtu_getnext,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4316) .vtu_loadpurge = mv88e6352_g1_vtu_loadpurge,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4317) .avb_ops = &mv88e6352_avb_ops,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4318) .ptp_ops = &mv88e6352_ptp_ops,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4319) .phylink_validate = mv88e6185_phylink_validate,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4320) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4321)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4322) static const struct mv88e6xxx_ops mv88e6352_ops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4323) /* MV88E6XXX_FAMILY_6352 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4324) .ieee_pri_map = mv88e6085_g1_ieee_pri_map,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4325) .ip_pri_map = mv88e6085_g1_ip_pri_map,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4326) .irl_init_all = mv88e6352_g2_irl_init_all,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4327) .get_eeprom = mv88e6xxx_g2_get_eeprom16,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4328) .set_eeprom = mv88e6xxx_g2_set_eeprom16,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4329) .set_switch_mac = mv88e6xxx_g2_set_switch_mac,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4330) .phy_read = mv88e6xxx_g2_smi_phy_read,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4331) .phy_write = mv88e6xxx_g2_smi_phy_write,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4332) .port_set_link = mv88e6xxx_port_set_link,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4333) .port_set_rgmii_delay = mv88e6352_port_set_rgmii_delay,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4334) .port_set_speed_duplex = mv88e6352_port_set_speed_duplex,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4335) .port_tag_remap = mv88e6095_port_tag_remap,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4336) .port_set_policy = mv88e6352_port_set_policy,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4337) .port_set_frame_mode = mv88e6351_port_set_frame_mode,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4338) .port_set_egress_floods = mv88e6352_port_set_egress_floods,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4339) .port_set_ether_type = mv88e6351_port_set_ether_type,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4340) .port_set_jumbo_size = mv88e6165_port_set_jumbo_size,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4341) .port_egress_rate_limiting = mv88e6097_port_egress_rate_limiting,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4342) .port_pause_limit = mv88e6097_port_pause_limit,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4343) .port_disable_learn_limit = mv88e6xxx_port_disable_learn_limit,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4344) .port_disable_pri_override = mv88e6xxx_port_disable_pri_override,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4345) .port_get_cmode = mv88e6352_port_get_cmode,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4346) .port_setup_message_port = mv88e6xxx_setup_message_port,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4347) .stats_snapshot = mv88e6320_g1_stats_snapshot,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4348) .stats_set_histogram = mv88e6095_g1_stats_set_histogram,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4349) .stats_get_sset_count = mv88e6095_stats_get_sset_count,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4350) .stats_get_strings = mv88e6095_stats_get_strings,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4351) .stats_get_stats = mv88e6095_stats_get_stats,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4352) .set_cpu_port = mv88e6095_g1_set_cpu_port,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4353) .set_egress_port = mv88e6095_g1_set_egress_port,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4354) .watchdog_ops = &mv88e6097_watchdog_ops,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4355) .mgmt_rsvd2cpu = mv88e6352_g2_mgmt_rsvd2cpu,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4356) .pot_clear = mv88e6xxx_g2_pot_clear,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4357) .reset = mv88e6352_g1_reset,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4358) .rmu_disable = mv88e6352_g1_rmu_disable,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4359) .atu_get_hash = mv88e6165_g1_atu_get_hash,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4360) .atu_set_hash = mv88e6165_g1_atu_set_hash,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4361) .vtu_getnext = mv88e6352_g1_vtu_getnext,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4362) .vtu_loadpurge = mv88e6352_g1_vtu_loadpurge,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4363) .serdes_get_lane = mv88e6352_serdes_get_lane,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4364) .serdes_pcs_get_state = mv88e6352_serdes_pcs_get_state,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4365) .serdes_pcs_config = mv88e6352_serdes_pcs_config,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4366) .serdes_pcs_an_restart = mv88e6352_serdes_pcs_an_restart,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4367) .serdes_pcs_link_up = mv88e6352_serdes_pcs_link_up,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4368) .serdes_power = mv88e6352_serdes_power,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4369) .serdes_irq_mapping = mv88e6352_serdes_irq_mapping,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4370) .serdes_irq_enable = mv88e6352_serdes_irq_enable,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4371) .serdes_irq_status = mv88e6352_serdes_irq_status,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4372) .gpio_ops = &mv88e6352_gpio_ops,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4373) .avb_ops = &mv88e6352_avb_ops,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4374) .ptp_ops = &mv88e6352_ptp_ops,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4375) .serdes_get_sset_count = mv88e6352_serdes_get_sset_count,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4376) .serdes_get_strings = mv88e6352_serdes_get_strings,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4377) .serdes_get_stats = mv88e6352_serdes_get_stats,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4378) .serdes_get_regs_len = mv88e6352_serdes_get_regs_len,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4379) .serdes_get_regs = mv88e6352_serdes_get_regs,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4380) .phylink_validate = mv88e6352_phylink_validate,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4381) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4382)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4383) static const struct mv88e6xxx_ops mv88e6390_ops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4384) /* MV88E6XXX_FAMILY_6390 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4385) .setup_errata = mv88e6390_setup_errata,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4386) .irl_init_all = mv88e6390_g2_irl_init_all,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4387) .get_eeprom = mv88e6xxx_g2_get_eeprom8,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4388) .set_eeprom = mv88e6xxx_g2_set_eeprom8,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4389) .set_switch_mac = mv88e6xxx_g2_set_switch_mac,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4390) .phy_read = mv88e6xxx_g2_smi_phy_read,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4391) .phy_write = mv88e6xxx_g2_smi_phy_write,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4392) .port_set_link = mv88e6xxx_port_set_link,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4393) .port_set_rgmii_delay = mv88e6390_port_set_rgmii_delay,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4394) .port_set_speed_duplex = mv88e6390_port_set_speed_duplex,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4395) .port_max_speed_mode = mv88e6390_port_max_speed_mode,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4396) .port_tag_remap = mv88e6390_port_tag_remap,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4397) .port_set_policy = mv88e6352_port_set_policy,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4398) .port_set_frame_mode = mv88e6351_port_set_frame_mode,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4399) .port_set_egress_floods = mv88e6352_port_set_egress_floods,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4400) .port_set_ether_type = mv88e6351_port_set_ether_type,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4401) .port_set_jumbo_size = mv88e6165_port_set_jumbo_size,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4402) .port_egress_rate_limiting = mv88e6097_port_egress_rate_limiting,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4403) .port_pause_limit = mv88e6390_port_pause_limit,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4404) .port_disable_learn_limit = mv88e6xxx_port_disable_learn_limit,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4405) .port_disable_pri_override = mv88e6xxx_port_disable_pri_override,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4406) .port_get_cmode = mv88e6352_port_get_cmode,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4407) .port_set_cmode = mv88e6390_port_set_cmode,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4408) .port_setup_message_port = mv88e6xxx_setup_message_port,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4409) .stats_snapshot = mv88e6390_g1_stats_snapshot,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4410) .stats_set_histogram = mv88e6390_g1_stats_set_histogram,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4411) .stats_get_sset_count = mv88e6320_stats_get_sset_count,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4412) .stats_get_strings = mv88e6320_stats_get_strings,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4413) .stats_get_stats = mv88e6390_stats_get_stats,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4414) .set_cpu_port = mv88e6390_g1_set_cpu_port,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4415) .set_egress_port = mv88e6390_g1_set_egress_port,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4416) .watchdog_ops = &mv88e6390_watchdog_ops,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4417) .mgmt_rsvd2cpu = mv88e6390_g1_mgmt_rsvd2cpu,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4418) .pot_clear = mv88e6xxx_g2_pot_clear,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4419) .reset = mv88e6352_g1_reset,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4420) .rmu_disable = mv88e6390_g1_rmu_disable,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4421) .atu_get_hash = mv88e6165_g1_atu_get_hash,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4422) .atu_set_hash = mv88e6165_g1_atu_set_hash,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4423) .vtu_getnext = mv88e6390_g1_vtu_getnext,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4424) .vtu_loadpurge = mv88e6390_g1_vtu_loadpurge,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4425) .serdes_power = mv88e6390_serdes_power,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4426) .serdes_get_lane = mv88e6390_serdes_get_lane,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4427) /* Check status register pause & lpa register */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4428) .serdes_pcs_get_state = mv88e6390_serdes_pcs_get_state,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4429) .serdes_pcs_config = mv88e6390_serdes_pcs_config,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4430) .serdes_pcs_an_restart = mv88e6390_serdes_pcs_an_restart,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4431) .serdes_pcs_link_up = mv88e6390_serdes_pcs_link_up,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4432) .serdes_irq_mapping = mv88e6390_serdes_irq_mapping,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4433) .serdes_irq_enable = mv88e6390_serdes_irq_enable,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4434) .serdes_irq_status = mv88e6390_serdes_irq_status,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4435) .gpio_ops = &mv88e6352_gpio_ops,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4436) .avb_ops = &mv88e6390_avb_ops,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4437) .ptp_ops = &mv88e6352_ptp_ops,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4438) .serdes_get_sset_count = mv88e6390_serdes_get_sset_count,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4439) .serdes_get_strings = mv88e6390_serdes_get_strings,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4440) .serdes_get_stats = mv88e6390_serdes_get_stats,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4441) .serdes_get_regs_len = mv88e6390_serdes_get_regs_len,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4442) .serdes_get_regs = mv88e6390_serdes_get_regs,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4443) .phylink_validate = mv88e6390_phylink_validate,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4444) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4445)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4446) static const struct mv88e6xxx_ops mv88e6390x_ops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4447) /* MV88E6XXX_FAMILY_6390 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4448) .setup_errata = mv88e6390_setup_errata,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4449) .irl_init_all = mv88e6390_g2_irl_init_all,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4450) .get_eeprom = mv88e6xxx_g2_get_eeprom8,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4451) .set_eeprom = mv88e6xxx_g2_set_eeprom8,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4452) .set_switch_mac = mv88e6xxx_g2_set_switch_mac,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4453) .phy_read = mv88e6xxx_g2_smi_phy_read,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4454) .phy_write = mv88e6xxx_g2_smi_phy_write,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4455) .port_set_link = mv88e6xxx_port_set_link,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4456) .port_set_rgmii_delay = mv88e6390_port_set_rgmii_delay,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4457) .port_set_speed_duplex = mv88e6390x_port_set_speed_duplex,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4458) .port_max_speed_mode = mv88e6390x_port_max_speed_mode,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4459) .port_tag_remap = mv88e6390_port_tag_remap,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4460) .port_set_policy = mv88e6352_port_set_policy,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4461) .port_set_frame_mode = mv88e6351_port_set_frame_mode,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4462) .port_set_egress_floods = mv88e6352_port_set_egress_floods,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4463) .port_set_ether_type = mv88e6351_port_set_ether_type,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4464) .port_set_jumbo_size = mv88e6165_port_set_jumbo_size,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4465) .port_egress_rate_limiting = mv88e6097_port_egress_rate_limiting,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4466) .port_pause_limit = mv88e6390_port_pause_limit,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4467) .port_disable_learn_limit = mv88e6xxx_port_disable_learn_limit,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4468) .port_disable_pri_override = mv88e6xxx_port_disable_pri_override,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4469) .port_get_cmode = mv88e6352_port_get_cmode,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4470) .port_set_cmode = mv88e6390x_port_set_cmode,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4471) .port_setup_message_port = mv88e6xxx_setup_message_port,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4472) .stats_snapshot = mv88e6390_g1_stats_snapshot,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4473) .stats_set_histogram = mv88e6390_g1_stats_set_histogram,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4474) .stats_get_sset_count = mv88e6320_stats_get_sset_count,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4475) .stats_get_strings = mv88e6320_stats_get_strings,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4476) .stats_get_stats = mv88e6390_stats_get_stats,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4477) .set_cpu_port = mv88e6390_g1_set_cpu_port,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4478) .set_egress_port = mv88e6390_g1_set_egress_port,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4479) .watchdog_ops = &mv88e6390_watchdog_ops,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4480) .mgmt_rsvd2cpu = mv88e6390_g1_mgmt_rsvd2cpu,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4481) .pot_clear = mv88e6xxx_g2_pot_clear,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4482) .reset = mv88e6352_g1_reset,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4483) .rmu_disable = mv88e6390_g1_rmu_disable,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4484) .atu_get_hash = mv88e6165_g1_atu_get_hash,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4485) .atu_set_hash = mv88e6165_g1_atu_set_hash,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4486) .vtu_getnext = mv88e6390_g1_vtu_getnext,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4487) .vtu_loadpurge = mv88e6390_g1_vtu_loadpurge,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4488) .serdes_power = mv88e6390_serdes_power,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4489) .serdes_get_lane = mv88e6390x_serdes_get_lane,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4490) .serdes_pcs_get_state = mv88e6390_serdes_pcs_get_state,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4491) .serdes_pcs_config = mv88e6390_serdes_pcs_config,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4492) .serdes_pcs_an_restart = mv88e6390_serdes_pcs_an_restart,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4493) .serdes_pcs_link_up = mv88e6390_serdes_pcs_link_up,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4494) .serdes_irq_mapping = mv88e6390_serdes_irq_mapping,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4495) .serdes_irq_enable = mv88e6390_serdes_irq_enable,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4496) .serdes_irq_status = mv88e6390_serdes_irq_status,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4497) .serdes_get_sset_count = mv88e6390_serdes_get_sset_count,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4498) .serdes_get_strings = mv88e6390_serdes_get_strings,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4499) .serdes_get_stats = mv88e6390_serdes_get_stats,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4500) .serdes_get_regs_len = mv88e6390_serdes_get_regs_len,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4501) .serdes_get_regs = mv88e6390_serdes_get_regs,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4502) .gpio_ops = &mv88e6352_gpio_ops,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4503) .avb_ops = &mv88e6390_avb_ops,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4504) .ptp_ops = &mv88e6352_ptp_ops,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4505) .phylink_validate = mv88e6390x_phylink_validate,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4506) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4507)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4508) static const struct mv88e6xxx_info mv88e6xxx_table[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4509) [MV88E6085] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4510) .prod_num = MV88E6XXX_PORT_SWITCH_ID_PROD_6085,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4511) .family = MV88E6XXX_FAMILY_6097,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4512) .name = "Marvell 88E6085",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4513) .num_databases = 4096,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4514) .num_macs = 8192,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4515) .num_ports = 10,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4516) .num_internal_phys = 5,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4517) .max_vid = 4095,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4518) .port_base_addr = 0x10,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4519) .phy_base_addr = 0x0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4520) .global1_addr = 0x1b,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4521) .global2_addr = 0x1c,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4522) .age_time_coeff = 15000,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4523) .g1_irqs = 8,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4524) .g2_irqs = 10,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4525) .atu_move_port_mask = 0xf,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4526) .pvt = true,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4527) .multi_chip = true,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4528) .tag_protocol = DSA_TAG_PROTO_DSA,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4529) .ops = &mv88e6085_ops,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4530) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4531)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4532) [MV88E6095] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4533) .prod_num = MV88E6XXX_PORT_SWITCH_ID_PROD_6095,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4534) .family = MV88E6XXX_FAMILY_6095,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4535) .name = "Marvell 88E6095/88E6095F",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4536) .num_databases = 256,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4537) .num_macs = 8192,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4538) .num_ports = 11,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4539) .num_internal_phys = 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4540) .max_vid = 4095,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4541) .port_base_addr = 0x10,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4542) .phy_base_addr = 0x0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4543) .global1_addr = 0x1b,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4544) .global2_addr = 0x1c,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4545) .age_time_coeff = 15000,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4546) .g1_irqs = 8,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4547) .atu_move_port_mask = 0xf,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4548) .multi_chip = true,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4549) .tag_protocol = DSA_TAG_PROTO_DSA,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4550) .ops = &mv88e6095_ops,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4551) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4552)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4553) [MV88E6097] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4554) .prod_num = MV88E6XXX_PORT_SWITCH_ID_PROD_6097,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4555) .family = MV88E6XXX_FAMILY_6097,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4556) .name = "Marvell 88E6097/88E6097F",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4557) .num_databases = 4096,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4558) .num_macs = 8192,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4559) .num_ports = 11,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4560) .num_internal_phys = 8,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4561) .max_vid = 4095,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4562) .port_base_addr = 0x10,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4563) .phy_base_addr = 0x0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4564) .global1_addr = 0x1b,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4565) .global2_addr = 0x1c,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4566) .age_time_coeff = 15000,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4567) .g1_irqs = 8,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4568) .g2_irqs = 10,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4569) .atu_move_port_mask = 0xf,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4570) .pvt = true,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4571) .multi_chip = true,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4572) .tag_protocol = DSA_TAG_PROTO_EDSA,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4573) .ops = &mv88e6097_ops,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4574) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4575)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4576) [MV88E6123] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4577) .prod_num = MV88E6XXX_PORT_SWITCH_ID_PROD_6123,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4578) .family = MV88E6XXX_FAMILY_6165,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4579) .name = "Marvell 88E6123",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4580) .num_databases = 4096,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4581) .num_macs = 1024,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4582) .num_ports = 3,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4583) .num_internal_phys = 5,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4584) .max_vid = 4095,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4585) .port_base_addr = 0x10,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4586) .phy_base_addr = 0x0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4587) .global1_addr = 0x1b,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4588) .global2_addr = 0x1c,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4589) .age_time_coeff = 15000,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4590) .g1_irqs = 9,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4591) .g2_irqs = 10,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4592) .atu_move_port_mask = 0xf,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4593) .pvt = true,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4594) .multi_chip = true,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4595) .tag_protocol = DSA_TAG_PROTO_EDSA,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4596) .ops = &mv88e6123_ops,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4597) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4598)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4599) [MV88E6131] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4600) .prod_num = MV88E6XXX_PORT_SWITCH_ID_PROD_6131,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4601) .family = MV88E6XXX_FAMILY_6185,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4602) .name = "Marvell 88E6131",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4603) .num_databases = 256,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4604) .num_macs = 8192,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4605) .num_ports = 8,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4606) .num_internal_phys = 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4607) .max_vid = 4095,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4608) .port_base_addr = 0x10,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4609) .phy_base_addr = 0x0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4610) .global1_addr = 0x1b,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4611) .global2_addr = 0x1c,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4612) .age_time_coeff = 15000,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4613) .g1_irqs = 9,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4614) .atu_move_port_mask = 0xf,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4615) .multi_chip = true,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4616) .tag_protocol = DSA_TAG_PROTO_DSA,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4617) .ops = &mv88e6131_ops,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4618) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4619)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4620) [MV88E6141] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4621) .prod_num = MV88E6XXX_PORT_SWITCH_ID_PROD_6141,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4622) .family = MV88E6XXX_FAMILY_6341,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4623) .name = "Marvell 88E6141",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4624) .num_databases = 4096,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4625) .num_macs = 2048,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4626) .num_ports = 6,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4627) .num_internal_phys = 5,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4628) .num_gpio = 11,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4629) .max_vid = 4095,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4630) .port_base_addr = 0x10,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4631) .phy_base_addr = 0x10,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4632) .global1_addr = 0x1b,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4633) .global2_addr = 0x1c,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4634) .age_time_coeff = 3750,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4635) .atu_move_port_mask = 0x1f,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4636) .g1_irqs = 9,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4637) .g2_irqs = 10,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4638) .pvt = true,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4639) .multi_chip = true,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4640) .tag_protocol = DSA_TAG_PROTO_EDSA,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4641) .ops = &mv88e6141_ops,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4642) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4643)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4644) [MV88E6161] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4645) .prod_num = MV88E6XXX_PORT_SWITCH_ID_PROD_6161,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4646) .family = MV88E6XXX_FAMILY_6165,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4647) .name = "Marvell 88E6161",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4648) .num_databases = 4096,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4649) .num_macs = 1024,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4650) .num_ports = 6,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4651) .num_internal_phys = 5,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4652) .max_vid = 4095,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4653) .port_base_addr = 0x10,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4654) .phy_base_addr = 0x0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4655) .global1_addr = 0x1b,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4656) .global2_addr = 0x1c,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4657) .age_time_coeff = 15000,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4658) .g1_irqs = 9,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4659) .g2_irqs = 10,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4660) .atu_move_port_mask = 0xf,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4661) .pvt = true,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4662) .multi_chip = true,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4663) .tag_protocol = DSA_TAG_PROTO_EDSA,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4664) .ptp_support = true,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4665) .ops = &mv88e6161_ops,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4666) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4667)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4668) [MV88E6165] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4669) .prod_num = MV88E6XXX_PORT_SWITCH_ID_PROD_6165,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4670) .family = MV88E6XXX_FAMILY_6165,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4671) .name = "Marvell 88E6165",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4672) .num_databases = 4096,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4673) .num_macs = 8192,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4674) .num_ports = 6,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4675) .num_internal_phys = 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4676) .max_vid = 4095,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4677) .port_base_addr = 0x10,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4678) .phy_base_addr = 0x0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4679) .global1_addr = 0x1b,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4680) .global2_addr = 0x1c,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4681) .age_time_coeff = 15000,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4682) .g1_irqs = 9,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4683) .g2_irqs = 10,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4684) .atu_move_port_mask = 0xf,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4685) .pvt = true,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4686) .multi_chip = true,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4687) .tag_protocol = DSA_TAG_PROTO_DSA,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4688) .ptp_support = true,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4689) .ops = &mv88e6165_ops,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4690) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4691)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4692) [MV88E6171] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4693) .prod_num = MV88E6XXX_PORT_SWITCH_ID_PROD_6171,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4694) .family = MV88E6XXX_FAMILY_6351,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4695) .name = "Marvell 88E6171",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4696) .num_databases = 4096,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4697) .num_macs = 8192,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4698) .num_ports = 7,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4699) .num_internal_phys = 5,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4700) .max_vid = 4095,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4701) .port_base_addr = 0x10,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4702) .phy_base_addr = 0x0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4703) .global1_addr = 0x1b,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4704) .global2_addr = 0x1c,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4705) .age_time_coeff = 15000,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4706) .g1_irqs = 9,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4707) .g2_irqs = 10,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4708) .atu_move_port_mask = 0xf,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4709) .pvt = true,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4710) .multi_chip = true,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4711) .tag_protocol = DSA_TAG_PROTO_EDSA,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4712) .ops = &mv88e6171_ops,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4713) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4714)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4715) [MV88E6172] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4716) .prod_num = MV88E6XXX_PORT_SWITCH_ID_PROD_6172,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4717) .family = MV88E6XXX_FAMILY_6352,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4718) .name = "Marvell 88E6172",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4719) .num_databases = 4096,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4720) .num_macs = 8192,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4721) .num_ports = 7,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4722) .num_internal_phys = 5,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4723) .num_gpio = 15,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4724) .max_vid = 4095,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4725) .port_base_addr = 0x10,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4726) .phy_base_addr = 0x0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4727) .global1_addr = 0x1b,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4728) .global2_addr = 0x1c,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4729) .age_time_coeff = 15000,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4730) .g1_irqs = 9,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4731) .g2_irqs = 10,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4732) .atu_move_port_mask = 0xf,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4733) .pvt = true,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4734) .multi_chip = true,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4735) .tag_protocol = DSA_TAG_PROTO_EDSA,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4736) .ops = &mv88e6172_ops,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4737) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4738)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4739) [MV88E6175] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4740) .prod_num = MV88E6XXX_PORT_SWITCH_ID_PROD_6175,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4741) .family = MV88E6XXX_FAMILY_6351,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4742) .name = "Marvell 88E6175",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4743) .num_databases = 4096,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4744) .num_macs = 8192,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4745) .num_ports = 7,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4746) .num_internal_phys = 5,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4747) .max_vid = 4095,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4748) .port_base_addr = 0x10,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4749) .phy_base_addr = 0x0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4750) .global1_addr = 0x1b,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4751) .global2_addr = 0x1c,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4752) .age_time_coeff = 15000,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4753) .g1_irqs = 9,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4754) .g2_irqs = 10,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4755) .atu_move_port_mask = 0xf,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4756) .pvt = true,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4757) .multi_chip = true,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4758) .tag_protocol = DSA_TAG_PROTO_EDSA,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4759) .ops = &mv88e6175_ops,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4760) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4761)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4762) [MV88E6176] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4763) .prod_num = MV88E6XXX_PORT_SWITCH_ID_PROD_6176,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4764) .family = MV88E6XXX_FAMILY_6352,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4765) .name = "Marvell 88E6176",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4766) .num_databases = 4096,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4767) .num_macs = 8192,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4768) .num_ports = 7,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4769) .num_internal_phys = 5,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4770) .num_gpio = 15,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4771) .max_vid = 4095,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4772) .port_base_addr = 0x10,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4773) .phy_base_addr = 0x0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4774) .global1_addr = 0x1b,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4775) .global2_addr = 0x1c,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4776) .age_time_coeff = 15000,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4777) .g1_irqs = 9,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4778) .g2_irqs = 10,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4779) .atu_move_port_mask = 0xf,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4780) .pvt = true,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4781) .multi_chip = true,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4782) .tag_protocol = DSA_TAG_PROTO_EDSA,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4783) .ops = &mv88e6176_ops,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4784) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4785)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4786) [MV88E6185] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4787) .prod_num = MV88E6XXX_PORT_SWITCH_ID_PROD_6185,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4788) .family = MV88E6XXX_FAMILY_6185,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4789) .name = "Marvell 88E6185",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4790) .num_databases = 256,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4791) .num_macs = 8192,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4792) .num_ports = 10,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4793) .num_internal_phys = 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4794) .max_vid = 4095,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4795) .port_base_addr = 0x10,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4796) .phy_base_addr = 0x0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4797) .global1_addr = 0x1b,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4798) .global2_addr = 0x1c,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4799) .age_time_coeff = 15000,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4800) .g1_irqs = 8,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4801) .atu_move_port_mask = 0xf,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4802) .multi_chip = true,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4803) .tag_protocol = DSA_TAG_PROTO_EDSA,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4804) .ops = &mv88e6185_ops,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4805) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4806)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4807) [MV88E6190] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4808) .prod_num = MV88E6XXX_PORT_SWITCH_ID_PROD_6190,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4809) .family = MV88E6XXX_FAMILY_6390,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4810) .name = "Marvell 88E6190",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4811) .num_databases = 4096,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4812) .num_macs = 16384,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4813) .num_ports = 11, /* 10 + Z80 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4814) .num_internal_phys = 9,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4815) .num_gpio = 16,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4816) .max_vid = 8191,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4817) .port_base_addr = 0x0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4818) .phy_base_addr = 0x0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4819) .global1_addr = 0x1b,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4820) .global2_addr = 0x1c,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4821) .tag_protocol = DSA_TAG_PROTO_DSA,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4822) .age_time_coeff = 3750,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4823) .g1_irqs = 9,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4824) .g2_irqs = 14,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4825) .pvt = true,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4826) .multi_chip = true,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4827) .atu_move_port_mask = 0x1f,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4828) .ops = &mv88e6190_ops,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4829) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4830)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4831) [MV88E6190X] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4832) .prod_num = MV88E6XXX_PORT_SWITCH_ID_PROD_6190X,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4833) .family = MV88E6XXX_FAMILY_6390,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4834) .name = "Marvell 88E6190X",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4835) .num_databases = 4096,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4836) .num_macs = 16384,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4837) .num_ports = 11, /* 10 + Z80 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4838) .num_internal_phys = 9,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4839) .num_gpio = 16,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4840) .max_vid = 8191,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4841) .port_base_addr = 0x0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4842) .phy_base_addr = 0x0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4843) .global1_addr = 0x1b,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4844) .global2_addr = 0x1c,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4845) .age_time_coeff = 3750,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4846) .g1_irqs = 9,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4847) .g2_irqs = 14,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4848) .atu_move_port_mask = 0x1f,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4849) .pvt = true,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4850) .multi_chip = true,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4851) .tag_protocol = DSA_TAG_PROTO_DSA,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4852) .ops = &mv88e6190x_ops,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4853) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4854)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4855) [MV88E6191] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4856) .prod_num = MV88E6XXX_PORT_SWITCH_ID_PROD_6191,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4857) .family = MV88E6XXX_FAMILY_6390,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4858) .name = "Marvell 88E6191",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4859) .num_databases = 4096,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4860) .num_macs = 16384,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4861) .num_ports = 11, /* 10 + Z80 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4862) .num_internal_phys = 9,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4863) .max_vid = 8191,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4864) .port_base_addr = 0x0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4865) .phy_base_addr = 0x0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4866) .global1_addr = 0x1b,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4867) .global2_addr = 0x1c,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4868) .age_time_coeff = 3750,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4869) .g1_irqs = 9,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4870) .g2_irqs = 14,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4871) .atu_move_port_mask = 0x1f,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4872) .pvt = true,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4873) .multi_chip = true,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4874) .tag_protocol = DSA_TAG_PROTO_DSA,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4875) .ptp_support = true,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4876) .ops = &mv88e6191_ops,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4877) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4878)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4879) [MV88E6220] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4880) .prod_num = MV88E6XXX_PORT_SWITCH_ID_PROD_6220,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4881) .family = MV88E6XXX_FAMILY_6250,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4882) .name = "Marvell 88E6220",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4883) .num_databases = 64,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4884)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4885) /* Ports 2-4 are not routed to pins
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4886) * => usable ports 0, 1, 5, 6
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4887) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4888) .num_ports = 7,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4889) .num_internal_phys = 2,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4890) .invalid_port_mask = BIT(2) | BIT(3) | BIT(4),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4891) .max_vid = 4095,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4892) .port_base_addr = 0x08,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4893) .phy_base_addr = 0x00,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4894) .global1_addr = 0x0f,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4895) .global2_addr = 0x07,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4896) .age_time_coeff = 15000,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4897) .g1_irqs = 9,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4898) .g2_irqs = 10,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4899) .atu_move_port_mask = 0xf,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4900) .dual_chip = true,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4901) .tag_protocol = DSA_TAG_PROTO_DSA,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4902) .ptp_support = true,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4903) .ops = &mv88e6250_ops,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4904) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4905)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4906) [MV88E6240] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4907) .prod_num = MV88E6XXX_PORT_SWITCH_ID_PROD_6240,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4908) .family = MV88E6XXX_FAMILY_6352,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4909) .name = "Marvell 88E6240",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4910) .num_databases = 4096,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4911) .num_macs = 8192,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4912) .num_ports = 7,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4913) .num_internal_phys = 5,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4914) .num_gpio = 15,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4915) .max_vid = 4095,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4916) .port_base_addr = 0x10,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4917) .phy_base_addr = 0x0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4918) .global1_addr = 0x1b,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4919) .global2_addr = 0x1c,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4920) .age_time_coeff = 15000,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4921) .g1_irqs = 9,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4922) .g2_irqs = 10,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4923) .atu_move_port_mask = 0xf,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4924) .pvt = true,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4925) .multi_chip = true,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4926) .tag_protocol = DSA_TAG_PROTO_EDSA,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4927) .ptp_support = true,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4928) .ops = &mv88e6240_ops,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4929) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4930)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4931) [MV88E6250] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4932) .prod_num = MV88E6XXX_PORT_SWITCH_ID_PROD_6250,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4933) .family = MV88E6XXX_FAMILY_6250,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4934) .name = "Marvell 88E6250",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4935) .num_databases = 64,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4936) .num_ports = 7,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4937) .num_internal_phys = 5,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4938) .max_vid = 4095,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4939) .port_base_addr = 0x08,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4940) .phy_base_addr = 0x00,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4941) .global1_addr = 0x0f,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4942) .global2_addr = 0x07,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4943) .age_time_coeff = 15000,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4944) .g1_irqs = 9,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4945) .g2_irqs = 10,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4946) .atu_move_port_mask = 0xf,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4947) .dual_chip = true,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4948) .tag_protocol = DSA_TAG_PROTO_DSA,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4949) .ptp_support = true,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4950) .ops = &mv88e6250_ops,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4951) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4952)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4953) [MV88E6290] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4954) .prod_num = MV88E6XXX_PORT_SWITCH_ID_PROD_6290,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4955) .family = MV88E6XXX_FAMILY_6390,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4956) .name = "Marvell 88E6290",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4957) .num_databases = 4096,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4958) .num_ports = 11, /* 10 + Z80 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4959) .num_internal_phys = 9,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4960) .num_gpio = 16,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4961) .max_vid = 8191,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4962) .port_base_addr = 0x0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4963) .phy_base_addr = 0x0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4964) .global1_addr = 0x1b,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4965) .global2_addr = 0x1c,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4966) .age_time_coeff = 3750,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4967) .g1_irqs = 9,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4968) .g2_irqs = 14,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4969) .atu_move_port_mask = 0x1f,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4970) .pvt = true,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4971) .multi_chip = true,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4972) .tag_protocol = DSA_TAG_PROTO_DSA,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4973) .ptp_support = true,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4974) .ops = &mv88e6290_ops,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4975) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4976)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4977) [MV88E6320] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4978) .prod_num = MV88E6XXX_PORT_SWITCH_ID_PROD_6320,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4979) .family = MV88E6XXX_FAMILY_6320,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4980) .name = "Marvell 88E6320",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4981) .num_databases = 4096,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4982) .num_macs = 8192,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4983) .num_ports = 7,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4984) .num_internal_phys = 5,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4985) .num_gpio = 15,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4986) .max_vid = 4095,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4987) .port_base_addr = 0x10,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4988) .phy_base_addr = 0x0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4989) .global1_addr = 0x1b,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4990) .global2_addr = 0x1c,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4991) .age_time_coeff = 15000,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4992) .g1_irqs = 8,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4993) .g2_irqs = 10,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4994) .atu_move_port_mask = 0xf,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4995) .pvt = true,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4996) .multi_chip = true,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4997) .tag_protocol = DSA_TAG_PROTO_EDSA,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4998) .ptp_support = true,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4999) .ops = &mv88e6320_ops,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5000) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5001)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5002) [MV88E6321] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5003) .prod_num = MV88E6XXX_PORT_SWITCH_ID_PROD_6321,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5004) .family = MV88E6XXX_FAMILY_6320,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5005) .name = "Marvell 88E6321",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5006) .num_databases = 4096,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5007) .num_macs = 8192,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5008) .num_ports = 7,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5009) .num_internal_phys = 5,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5010) .num_gpio = 15,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5011) .max_vid = 4095,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5012) .port_base_addr = 0x10,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5013) .phy_base_addr = 0x0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5014) .global1_addr = 0x1b,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5015) .global2_addr = 0x1c,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5016) .age_time_coeff = 15000,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5017) .g1_irqs = 8,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5018) .g2_irqs = 10,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5019) .atu_move_port_mask = 0xf,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5020) .multi_chip = true,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5021) .tag_protocol = DSA_TAG_PROTO_EDSA,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5022) .ptp_support = true,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5023) .ops = &mv88e6321_ops,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5024) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5025)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5026) [MV88E6341] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5027) .prod_num = MV88E6XXX_PORT_SWITCH_ID_PROD_6341,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5028) .family = MV88E6XXX_FAMILY_6341,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5029) .name = "Marvell 88E6341",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5030) .num_databases = 4096,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5031) .num_macs = 2048,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5032) .num_internal_phys = 5,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5033) .num_ports = 6,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5034) .num_gpio = 11,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5035) .max_vid = 4095,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5036) .port_base_addr = 0x10,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5037) .phy_base_addr = 0x10,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5038) .global1_addr = 0x1b,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5039) .global2_addr = 0x1c,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5040) .age_time_coeff = 3750,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5041) .atu_move_port_mask = 0x1f,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5042) .g1_irqs = 9,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5043) .g2_irqs = 10,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5044) .pvt = true,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5045) .multi_chip = true,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5046) .tag_protocol = DSA_TAG_PROTO_EDSA,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5047) .ptp_support = true,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5048) .ops = &mv88e6341_ops,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5049) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5050)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5051) [MV88E6350] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5052) .prod_num = MV88E6XXX_PORT_SWITCH_ID_PROD_6350,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5053) .family = MV88E6XXX_FAMILY_6351,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5054) .name = "Marvell 88E6350",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5055) .num_databases = 4096,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5056) .num_macs = 8192,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5057) .num_ports = 7,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5058) .num_internal_phys = 5,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5059) .max_vid = 4095,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5060) .port_base_addr = 0x10,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5061) .phy_base_addr = 0x0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5062) .global1_addr = 0x1b,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5063) .global2_addr = 0x1c,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5064) .age_time_coeff = 15000,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5065) .g1_irqs = 9,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5066) .g2_irqs = 10,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5067) .atu_move_port_mask = 0xf,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5068) .pvt = true,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5069) .multi_chip = true,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5070) .tag_protocol = DSA_TAG_PROTO_EDSA,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5071) .ops = &mv88e6350_ops,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5072) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5073)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5074) [MV88E6351] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5075) .prod_num = MV88E6XXX_PORT_SWITCH_ID_PROD_6351,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5076) .family = MV88E6XXX_FAMILY_6351,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5077) .name = "Marvell 88E6351",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5078) .num_databases = 4096,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5079) .num_macs = 8192,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5080) .num_ports = 7,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5081) .num_internal_phys = 5,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5082) .max_vid = 4095,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5083) .port_base_addr = 0x10,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5084) .phy_base_addr = 0x0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5085) .global1_addr = 0x1b,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5086) .global2_addr = 0x1c,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5087) .age_time_coeff = 15000,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5088) .g1_irqs = 9,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5089) .g2_irqs = 10,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5090) .atu_move_port_mask = 0xf,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5091) .pvt = true,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5092) .multi_chip = true,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5093) .tag_protocol = DSA_TAG_PROTO_EDSA,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5094) .ops = &mv88e6351_ops,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5095) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5096)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5097) [MV88E6352] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5098) .prod_num = MV88E6XXX_PORT_SWITCH_ID_PROD_6352,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5099) .family = MV88E6XXX_FAMILY_6352,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5100) .name = "Marvell 88E6352",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5101) .num_databases = 4096,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5102) .num_macs = 8192,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5103) .num_ports = 7,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5104) .num_internal_phys = 5,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5105) .num_gpio = 15,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5106) .max_vid = 4095,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5107) .port_base_addr = 0x10,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5108) .phy_base_addr = 0x0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5109) .global1_addr = 0x1b,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5110) .global2_addr = 0x1c,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5111) .age_time_coeff = 15000,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5112) .g1_irqs = 9,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5113) .g2_irqs = 10,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5114) .atu_move_port_mask = 0xf,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5115) .pvt = true,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5116) .multi_chip = true,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5117) .tag_protocol = DSA_TAG_PROTO_EDSA,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5118) .ptp_support = true,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5119) .ops = &mv88e6352_ops,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5120) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5121) [MV88E6390] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5122) .prod_num = MV88E6XXX_PORT_SWITCH_ID_PROD_6390,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5123) .family = MV88E6XXX_FAMILY_6390,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5124) .name = "Marvell 88E6390",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5125) .num_databases = 4096,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5126) .num_macs = 16384,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5127) .num_ports = 11, /* 10 + Z80 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5128) .num_internal_phys = 9,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5129) .num_gpio = 16,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5130) .max_vid = 8191,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5131) .port_base_addr = 0x0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5132) .phy_base_addr = 0x0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5133) .global1_addr = 0x1b,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5134) .global2_addr = 0x1c,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5135) .age_time_coeff = 3750,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5136) .g1_irqs = 9,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5137) .g2_irqs = 14,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5138) .atu_move_port_mask = 0x1f,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5139) .pvt = true,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5140) .multi_chip = true,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5141) .tag_protocol = DSA_TAG_PROTO_DSA,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5142) .ptp_support = true,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5143) .ops = &mv88e6390_ops,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5144) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5145) [MV88E6390X] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5146) .prod_num = MV88E6XXX_PORT_SWITCH_ID_PROD_6390X,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5147) .family = MV88E6XXX_FAMILY_6390,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5148) .name = "Marvell 88E6390X",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5149) .num_databases = 4096,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5150) .num_macs = 16384,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5151) .num_ports = 11, /* 10 + Z80 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5152) .num_internal_phys = 9,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5153) .num_gpio = 16,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5154) .max_vid = 8191,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5155) .port_base_addr = 0x0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5156) .phy_base_addr = 0x0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5157) .global1_addr = 0x1b,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5158) .global2_addr = 0x1c,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5159) .age_time_coeff = 3750,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5160) .g1_irqs = 9,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5161) .g2_irqs = 14,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5162) .atu_move_port_mask = 0x1f,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5163) .pvt = true,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5164) .multi_chip = true,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5165) .tag_protocol = DSA_TAG_PROTO_DSA,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5166) .ptp_support = true,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5167) .ops = &mv88e6390x_ops,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5168) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5169) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5170)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5171) static const struct mv88e6xxx_info *mv88e6xxx_lookup_info(unsigned int prod_num)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5172) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5173) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5174)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5175) for (i = 0; i < ARRAY_SIZE(mv88e6xxx_table); ++i)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5176) if (mv88e6xxx_table[i].prod_num == prod_num)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5177) return &mv88e6xxx_table[i];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5178)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5179) return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5180) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5181)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5182) static int mv88e6xxx_detect(struct mv88e6xxx_chip *chip)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5183) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5184) const struct mv88e6xxx_info *info;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5185) unsigned int prod_num, rev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5186) u16 id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5187) int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5188)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5189) mv88e6xxx_reg_lock(chip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5190) err = mv88e6xxx_port_read(chip, 0, MV88E6XXX_PORT_SWITCH_ID, &id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5191) mv88e6xxx_reg_unlock(chip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5192) if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5193) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5194)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5195) prod_num = id & MV88E6XXX_PORT_SWITCH_ID_PROD_MASK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5196) rev = id & MV88E6XXX_PORT_SWITCH_ID_REV_MASK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5197)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5198) info = mv88e6xxx_lookup_info(prod_num);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5199) if (!info)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5200) return -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5201)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5202) /* Update the compatible info with the probed one */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5203) chip->info = info;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5204)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5205) err = mv88e6xxx_g2_require(chip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5206) if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5207) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5208)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5209) dev_info(chip->dev, "switch 0x%x detected: %s, revision %u\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5210) chip->info->prod_num, chip->info->name, rev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5211)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5212) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5213) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5214)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5215) static struct mv88e6xxx_chip *mv88e6xxx_alloc_chip(struct device *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5216) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5217) struct mv88e6xxx_chip *chip;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5218)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5219) chip = devm_kzalloc(dev, sizeof(*chip), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5220) if (!chip)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5221) return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5222)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5223) chip->dev = dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5224)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5225) mutex_init(&chip->reg_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5226) INIT_LIST_HEAD(&chip->mdios);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5227) idr_init(&chip->policies);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5228)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5229) return chip;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5230) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5231)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5232) static enum dsa_tag_protocol mv88e6xxx_get_tag_protocol(struct dsa_switch *ds,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5233) int port,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5234) enum dsa_tag_protocol m)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5235) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5236) struct mv88e6xxx_chip *chip = ds->priv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5237)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5238) return chip->info->tag_protocol;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5239) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5240)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5241) static int mv88e6xxx_port_mdb_prepare(struct dsa_switch *ds, int port,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5242) const struct switchdev_obj_port_mdb *mdb)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5243) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5244) /* We don't need any dynamic resource from the kernel (yet),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5245) * so skip the prepare phase.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5246) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5247)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5248) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5249) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5250)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5251) static void mv88e6xxx_port_mdb_add(struct dsa_switch *ds, int port,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5252) const struct switchdev_obj_port_mdb *mdb)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5253) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5254) struct mv88e6xxx_chip *chip = ds->priv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5255)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5256) mv88e6xxx_reg_lock(chip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5257) if (mv88e6xxx_port_db_load_purge(chip, port, mdb->addr, mdb->vid,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5258) MV88E6XXX_G1_ATU_DATA_STATE_MC_STATIC))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5259) dev_err(ds->dev, "p%d: failed to load multicast MAC address\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5260) port);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5261) mv88e6xxx_reg_unlock(chip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5262) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5263)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5264) static int mv88e6xxx_port_mdb_del(struct dsa_switch *ds, int port,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5265) const struct switchdev_obj_port_mdb *mdb)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5266) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5267) struct mv88e6xxx_chip *chip = ds->priv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5268) int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5269)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5270) mv88e6xxx_reg_lock(chip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5271) err = mv88e6xxx_port_db_load_purge(chip, port, mdb->addr, mdb->vid, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5272) mv88e6xxx_reg_unlock(chip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5273)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5274) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5275) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5276)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5277) static int mv88e6xxx_port_mirror_add(struct dsa_switch *ds, int port,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5278) struct dsa_mall_mirror_tc_entry *mirror,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5279) bool ingress)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5280) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5281) enum mv88e6xxx_egress_direction direction = ingress ?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5282) MV88E6XXX_EGRESS_DIR_INGRESS :
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5283) MV88E6XXX_EGRESS_DIR_EGRESS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5284) struct mv88e6xxx_chip *chip = ds->priv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5285) bool other_mirrors = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5286) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5287) int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5288)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5289) if (!chip->info->ops->set_egress_port)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5290) return -EOPNOTSUPP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5291)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5292) mutex_lock(&chip->reg_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5293) if ((ingress ? chip->ingress_dest_port : chip->egress_dest_port) !=
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5294) mirror->to_local_port) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5295) for (i = 0; i < mv88e6xxx_num_ports(chip); i++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5296) other_mirrors |= ingress ?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5297) chip->ports[i].mirror_ingress :
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5298) chip->ports[i].mirror_egress;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5299)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5300) /* Can't change egress port when other mirror is active */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5301) if (other_mirrors) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5302) err = -EBUSY;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5303) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5304) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5305)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5306) err = chip->info->ops->set_egress_port(chip,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5307) direction,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5308) mirror->to_local_port);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5309) if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5310) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5311) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5312)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5313) err = mv88e6xxx_port_set_mirror(chip, port, direction, true);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5314) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5315) mutex_unlock(&chip->reg_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5316)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5317) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5318) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5319)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5320) static void mv88e6xxx_port_mirror_del(struct dsa_switch *ds, int port,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5321) struct dsa_mall_mirror_tc_entry *mirror)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5322) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5323) enum mv88e6xxx_egress_direction direction = mirror->ingress ?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5324) MV88E6XXX_EGRESS_DIR_INGRESS :
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5325) MV88E6XXX_EGRESS_DIR_EGRESS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5326) struct mv88e6xxx_chip *chip = ds->priv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5327) bool other_mirrors = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5328) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5329)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5330) mutex_lock(&chip->reg_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5331) if (mv88e6xxx_port_set_mirror(chip, port, direction, false))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5332) dev_err(ds->dev, "p%d: failed to disable mirroring\n", port);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5333)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5334) for (i = 0; i < mv88e6xxx_num_ports(chip); i++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5335) other_mirrors |= mirror->ingress ?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5336) chip->ports[i].mirror_ingress :
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5337) chip->ports[i].mirror_egress;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5338)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5339) /* Reset egress port when no other mirror is active */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5340) if (!other_mirrors) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5341) if (chip->info->ops->set_egress_port(chip,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5342) direction,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5343) dsa_upstream_port(ds,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5344) port)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5345) dev_err(ds->dev, "failed to set egress port\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5346) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5347)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5348) mutex_unlock(&chip->reg_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5349) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5350)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5351) static int mv88e6xxx_port_egress_floods(struct dsa_switch *ds, int port,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5352) bool unicast, bool multicast)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5353) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5354) struct mv88e6xxx_chip *chip = ds->priv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5355) int err = -EOPNOTSUPP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5356)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5357) mv88e6xxx_reg_lock(chip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5358) if (chip->info->ops->port_set_egress_floods)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5359) err = chip->info->ops->port_set_egress_floods(chip, port,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5360) unicast,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5361) multicast);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5362) mv88e6xxx_reg_unlock(chip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5363)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5364) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5365) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5366)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5367) static const struct dsa_switch_ops mv88e6xxx_switch_ops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5368) .get_tag_protocol = mv88e6xxx_get_tag_protocol,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5369) .setup = mv88e6xxx_setup,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5370) .teardown = mv88e6xxx_teardown,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5371) .phylink_validate = mv88e6xxx_validate,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5372) .phylink_mac_link_state = mv88e6xxx_serdes_pcs_get_state,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5373) .phylink_mac_config = mv88e6xxx_mac_config,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5374) .phylink_mac_an_restart = mv88e6xxx_serdes_pcs_an_restart,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5375) .phylink_mac_link_down = mv88e6xxx_mac_link_down,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5376) .phylink_mac_link_up = mv88e6xxx_mac_link_up,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5377) .get_strings = mv88e6xxx_get_strings,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5378) .get_ethtool_stats = mv88e6xxx_get_ethtool_stats,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5379) .get_sset_count = mv88e6xxx_get_sset_count,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5380) .port_enable = mv88e6xxx_port_enable,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5381) .port_disable = mv88e6xxx_port_disable,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5382) .port_max_mtu = mv88e6xxx_get_max_mtu,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5383) .port_change_mtu = mv88e6xxx_change_mtu,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5384) .get_mac_eee = mv88e6xxx_get_mac_eee,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5385) .set_mac_eee = mv88e6xxx_set_mac_eee,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5386) .get_eeprom_len = mv88e6xxx_get_eeprom_len,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5387) .get_eeprom = mv88e6xxx_get_eeprom,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5388) .set_eeprom = mv88e6xxx_set_eeprom,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5389) .get_regs_len = mv88e6xxx_get_regs_len,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5390) .get_regs = mv88e6xxx_get_regs,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5391) .get_rxnfc = mv88e6xxx_get_rxnfc,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5392) .set_rxnfc = mv88e6xxx_set_rxnfc,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5393) .set_ageing_time = mv88e6xxx_set_ageing_time,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5394) .port_bridge_join = mv88e6xxx_port_bridge_join,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5395) .port_bridge_leave = mv88e6xxx_port_bridge_leave,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5396) .port_egress_floods = mv88e6xxx_port_egress_floods,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5397) .port_stp_state_set = mv88e6xxx_port_stp_state_set,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5398) .port_fast_age = mv88e6xxx_port_fast_age,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5399) .port_vlan_filtering = mv88e6xxx_port_vlan_filtering,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5400) .port_vlan_prepare = mv88e6xxx_port_vlan_prepare,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5401) .port_vlan_add = mv88e6xxx_port_vlan_add,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5402) .port_vlan_del = mv88e6xxx_port_vlan_del,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5403) .port_fdb_add = mv88e6xxx_port_fdb_add,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5404) .port_fdb_del = mv88e6xxx_port_fdb_del,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5405) .port_fdb_dump = mv88e6xxx_port_fdb_dump,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5406) .port_mdb_prepare = mv88e6xxx_port_mdb_prepare,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5407) .port_mdb_add = mv88e6xxx_port_mdb_add,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5408) .port_mdb_del = mv88e6xxx_port_mdb_del,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5409) .port_mirror_add = mv88e6xxx_port_mirror_add,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5410) .port_mirror_del = mv88e6xxx_port_mirror_del,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5411) .crosschip_bridge_join = mv88e6xxx_crosschip_bridge_join,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5412) .crosschip_bridge_leave = mv88e6xxx_crosschip_bridge_leave,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5413) .port_hwtstamp_set = mv88e6xxx_port_hwtstamp_set,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5414) .port_hwtstamp_get = mv88e6xxx_port_hwtstamp_get,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5415) .port_txtstamp = mv88e6xxx_port_txtstamp,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5416) .port_rxtstamp = mv88e6xxx_port_rxtstamp,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5417) .get_ts_info = mv88e6xxx_get_ts_info,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5418) .devlink_param_get = mv88e6xxx_devlink_param_get,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5419) .devlink_param_set = mv88e6xxx_devlink_param_set,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5420) .devlink_info_get = mv88e6xxx_devlink_info_get,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5421) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5422)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5423) static int mv88e6xxx_register_switch(struct mv88e6xxx_chip *chip)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5424) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5425) struct device *dev = chip->dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5426) struct dsa_switch *ds;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5427)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5428) ds = devm_kzalloc(dev, sizeof(*ds), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5429) if (!ds)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5430) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5431)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5432) ds->dev = dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5433) ds->num_ports = mv88e6xxx_num_ports(chip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5434) ds->priv = chip;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5435) ds->dev = dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5436) ds->ops = &mv88e6xxx_switch_ops;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5437) ds->ageing_time_min = chip->info->age_time_coeff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5438) ds->ageing_time_max = chip->info->age_time_coeff * U8_MAX;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5439)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5440) dev_set_drvdata(dev, ds);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5441)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5442) return dsa_register_switch(ds);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5443) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5444)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5445) static void mv88e6xxx_unregister_switch(struct mv88e6xxx_chip *chip)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5446) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5447) dsa_unregister_switch(chip->ds);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5448) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5449)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5450) static const void *pdata_device_get_match_data(struct device *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5451) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5452) const struct of_device_id *matches = dev->driver->of_match_table;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5453) const struct dsa_mv88e6xxx_pdata *pdata = dev->platform_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5454)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5455) for (; matches->name[0] || matches->type[0] || matches->compatible[0];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5456) matches++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5457) if (!strcmp(pdata->compatible, matches->compatible))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5458) return matches->data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5459) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5460) return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5461) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5462)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5463) /* There is no suspend to RAM support at DSA level yet, the switch configuration
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5464) * would be lost after a power cycle so prevent it to be suspended.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5465) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5466) static int __maybe_unused mv88e6xxx_suspend(struct device *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5467) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5468) return -EOPNOTSUPP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5469) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5470)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5471) static int __maybe_unused mv88e6xxx_resume(struct device *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5472) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5473) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5474) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5475)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5476) static SIMPLE_DEV_PM_OPS(mv88e6xxx_pm_ops, mv88e6xxx_suspend, mv88e6xxx_resume);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5477)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5478) static int mv88e6xxx_probe(struct mdio_device *mdiodev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5479) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5480) struct dsa_mv88e6xxx_pdata *pdata = mdiodev->dev.platform_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5481) const struct mv88e6xxx_info *compat_info = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5482) struct device *dev = &mdiodev->dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5483) struct device_node *np = dev->of_node;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5484) struct mv88e6xxx_chip *chip;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5485) int port;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5486) int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5487)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5488) if (!np && !pdata)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5489) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5490)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5491) if (np)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5492) compat_info = of_device_get_match_data(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5493)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5494) if (pdata) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5495) compat_info = pdata_device_get_match_data(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5496)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5497) if (!pdata->netdev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5498) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5499)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5500) for (port = 0; port < DSA_MAX_PORTS; port++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5501) if (!(pdata->enabled_ports & (1 << port)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5502) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5503) if (strcmp(pdata->cd.port_names[port], "cpu"))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5504) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5505) pdata->cd.netdev[port] = &pdata->netdev->dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5506) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5507) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5508) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5509)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5510) if (!compat_info)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5511) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5512)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5513) chip = mv88e6xxx_alloc_chip(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5514) if (!chip) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5515) err = -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5516) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5517) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5518)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5519) chip->info = compat_info;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5520)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5521) err = mv88e6xxx_smi_init(chip, mdiodev->bus, mdiodev->addr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5522) if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5523) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5524)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5525) chip->reset = devm_gpiod_get_optional(dev, "reset", GPIOD_OUT_LOW);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5526) if (IS_ERR(chip->reset)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5527) err = PTR_ERR(chip->reset);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5528) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5529) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5530) if (chip->reset)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5531) usleep_range(1000, 2000);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5532)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5533) err = mv88e6xxx_detect(chip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5534) if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5535) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5536)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5537) mv88e6xxx_phy_init(chip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5538)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5539) if (chip->info->ops->get_eeprom) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5540) if (np)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5541) of_property_read_u32(np, "eeprom-length",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5542) &chip->eeprom_len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5543) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5544) chip->eeprom_len = pdata->eeprom_len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5545) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5546)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5547) mv88e6xxx_reg_lock(chip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5548) err = mv88e6xxx_switch_reset(chip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5549) mv88e6xxx_reg_unlock(chip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5550) if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5551) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5552)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5553) if (np) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5554) chip->irq = of_irq_get(np, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5555) if (chip->irq == -EPROBE_DEFER) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5556) err = chip->irq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5557) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5558) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5559) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5560)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5561) if (pdata)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5562) chip->irq = pdata->irq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5563)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5564) /* Has to be performed before the MDIO bus is created, because
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5565) * the PHYs will link their interrupts to these interrupt
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5566) * controllers
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5567) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5568) mv88e6xxx_reg_lock(chip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5569) if (chip->irq > 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5570) err = mv88e6xxx_g1_irq_setup(chip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5571) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5572) err = mv88e6xxx_irq_poll_setup(chip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5573) mv88e6xxx_reg_unlock(chip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5574)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5575) if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5576) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5577)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5578) if (chip->info->g2_irqs > 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5579) err = mv88e6xxx_g2_irq_setup(chip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5580) if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5581) goto out_g1_irq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5582) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5583)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5584) err = mv88e6xxx_g1_atu_prob_irq_setup(chip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5585) if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5586) goto out_g2_irq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5587)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5588) err = mv88e6xxx_g1_vtu_prob_irq_setup(chip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5589) if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5590) goto out_g1_atu_prob_irq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5591)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5592) err = mv88e6xxx_mdios_register(chip, np);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5593) if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5594) goto out_g1_vtu_prob_irq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5595)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5596) err = mv88e6xxx_register_switch(chip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5597) if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5598) goto out_mdio;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5599)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5600) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5601)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5602) out_mdio:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5603) mv88e6xxx_mdios_unregister(chip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5604) out_g1_vtu_prob_irq:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5605) mv88e6xxx_g1_vtu_prob_irq_free(chip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5606) out_g1_atu_prob_irq:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5607) mv88e6xxx_g1_atu_prob_irq_free(chip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5608) out_g2_irq:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5609) if (chip->info->g2_irqs > 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5610) mv88e6xxx_g2_irq_free(chip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5611) out_g1_irq:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5612) if (chip->irq > 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5613) mv88e6xxx_g1_irq_free(chip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5614) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5615) mv88e6xxx_irq_poll_free(chip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5616) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5617) if (pdata)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5618) dev_put(pdata->netdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5619)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5620) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5621) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5622)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5623) static void mv88e6xxx_remove(struct mdio_device *mdiodev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5624) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5625) struct dsa_switch *ds = dev_get_drvdata(&mdiodev->dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5626) struct mv88e6xxx_chip *chip = ds->priv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5627)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5628) if (chip->info->ptp_support) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5629) mv88e6xxx_hwtstamp_free(chip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5630) mv88e6xxx_ptp_free(chip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5631) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5632)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5633) mv88e6xxx_phy_destroy(chip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5634) mv88e6xxx_unregister_switch(chip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5635) mv88e6xxx_mdios_unregister(chip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5636)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5637) mv88e6xxx_g1_vtu_prob_irq_free(chip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5638) mv88e6xxx_g1_atu_prob_irq_free(chip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5639)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5640) if (chip->info->g2_irqs > 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5641) mv88e6xxx_g2_irq_free(chip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5642)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5643) if (chip->irq > 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5644) mv88e6xxx_g1_irq_free(chip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5645) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5646) mv88e6xxx_irq_poll_free(chip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5647) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5648)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5649) static const struct of_device_id mv88e6xxx_of_match[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5650) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5651) .compatible = "marvell,mv88e6085",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5652) .data = &mv88e6xxx_table[MV88E6085],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5653) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5654) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5655) .compatible = "marvell,mv88e6190",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5656) .data = &mv88e6xxx_table[MV88E6190],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5657) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5658) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5659) .compatible = "marvell,mv88e6250",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5660) .data = &mv88e6xxx_table[MV88E6250],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5661) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5662) { /* sentinel */ },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5663) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5664)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5665) MODULE_DEVICE_TABLE(of, mv88e6xxx_of_match);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5666)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5667) static struct mdio_driver mv88e6xxx_driver = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5668) .probe = mv88e6xxx_probe,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5669) .remove = mv88e6xxx_remove,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5670) .mdiodrv.driver = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5671) .name = "mv88e6085",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5672) .of_match_table = mv88e6xxx_of_match,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5673) .pm = &mv88e6xxx_pm_ops,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5674) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5675) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5676)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5677) mdio_module_driver(mv88e6xxx_driver);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5678)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5679) MODULE_AUTHOR("Lennert Buytenhek <buytenh@wantstofly.org>");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5680) MODULE_DESCRIPTION("Driver for Marvell 88E6XXX ethernet switch chips");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5681) MODULE_LICENSE("GPL");