* [PATCH net-next v2 00/12] net: dsa: management mode for bcm_sf2
From: Florian Fainelli @ 2019-01-30 0:55 UTC (permalink / raw)
To: netdev
Cc: Florian Fainelli, andrew, vivien.didelot, davem, idosch, jiri,
ilias.apalodimas, ivan.khoronzhuk, roopa, nikolay
Hi all,
This patch series does a number of things in order to enable management
mode for bcm_sf2 (which could be easily extended to b53 with proper
testing later on). In order to get there, there were several use cases
that did not work correctly and that needed to be fixed:
- VLAN devices on top of switch ports not being member of a bridge, with
other switch ports being bridged, with the bridge having VLAN
filtering enabled.
- lack of multicast filtering by default on network ports which should
be happening in order for the non-bridged DSA ports to behave strictly
as Ethernet NICs with proper filering. This is accomplished by hooking
a ndo_set_rx_mode() function to the DSA slave network devices
- when VLAN filtering is globally enabled on the switch (because at
least a bridge device requires it), then we also need to make sure
that when doing multicast over VLAN devices over a switch port
(bridged or not) happens with the correct MDB address *and* VID
Hopefully the changes to net/8021q and net/bridge are deemed acceptable.
The Broadcom switches have a switch-wide VLAN filtering attribute,
which is why we must always make sure there is a valid VLAN entry even
for switch ports which are not part of a bridge device, yet there is at
least one bridge device spanning the switch.
Multicast flooding can be done on a per-port basis, including for the
CPU/management port, however, once multicast reception is enabled on the
CPU port, it bypasses the ARL (Address Resolution Logic), so we receive
*all* multicast, even from ports do not have their flooding bit set,
which is unfortunate. This is the reason why we must continue adding
enough HOST_MDB notifications to let the CPU port continue to filter
multicast traffic.
Changes in v2:
- correctly propagate return from br_mc_disabled_update() called from
br_multicast_toggle
- dropped changes to VLAN and bridge code that was pushing multicast
entries with VID and instead refuse disabling multicast snooping in
b53 when there is another standalone port, or that there are other
bridged ports with multicast snooping enabled
Florian Fainelli (12):
net: bridge: multicast: Propagate br_mc_disabled_update() return
net: dsa: b53: Fix default VLAN ID
net: dsa: b53: Properly account for VLAN filtering
net: systemport: Fix reception of BPDUs
net: dsa: b53: Define registers for IGMP snooping
net: dsa: b53: Add support for MDB
net: dsa: Add ability to program multicast filter for CPU port
net: dsa: Add ndo_vlan_rx_{add,kill}_vid implementation
net: dsa: Make VLAN filtering use DSA notifiers
net: dsa: Wire up multicast IGMP snooping attribute notification
net: dsa: b53: Add support for toggling IGMP snooping
net: dsa: bcm_sf2: Enable management mode
drivers/net/dsa/b53/b53_common.c | 257 +++++++++++++++++++--
drivers/net/dsa/b53/b53_priv.h | 14 +-
drivers/net/dsa/b53/b53_regs.h | 22 ++
drivers/net/dsa/bcm_sf2.c | 56 +++--
drivers/net/dsa/bcm_sf2_regs.h | 5 +
drivers/net/ethernet/broadcom/bcmsysport.c | 4 +
include/net/dsa.h | 2 +
net/bridge/br_multicast.c | 23 +-
net/dsa/dsa_priv.h | 22 +-
net/dsa/port.c | 42 +++-
net/dsa/slave.c | 107 ++++++++-
net/dsa/switch.c | 57 +++++
12 files changed, 552 insertions(+), 59 deletions(-)
--
2.17.1
^ permalink raw reply
* [PATCH RFC RFT net-next 08/10] net: dsa: Remove legacy probing support
From: Andrew Lunn @ 2019-01-30 0:37 UTC (permalink / raw)
To: netdev; +Cc: Vivien Didelot, Florian Fainelli, Pavel Machek, Andrew Lunn
In-Reply-To: <20190130003758.23852-1-andrew@lunn.ch>
Now that all drivers can be probed using more traditional methods,
remove the legacy probe code.
Signed-off-by: Andrew Lunn <andrew@lunn.ch>
---
include/net/dsa.h | 23 --
net/dsa/Kconfig | 9 -
net/dsa/Makefile | 1 -
net/dsa/dsa.c | 5 -
net/dsa/dsa_priv.h | 12 -
net/dsa/legacy.c | 745 ---------------------------------------------
6 files changed, 795 deletions(-)
diff --git a/include/net/dsa.h b/include/net/dsa.h
index 7f2a668ef2cc..59a834207f66 100644
--- a/include/net/dsa.h
+++ b/include/net/dsa.h
@@ -277,15 +277,6 @@ static inline unsigned int dsa_upstream_port(struct dsa_switch *ds, int port)
typedef int dsa_fdb_dump_cb_t(const unsigned char *addr, u16 vid,
bool is_static, void *data);
struct dsa_switch_ops {
-#if IS_ENABLED(CONFIG_NET_DSA_LEGACY)
- /*
- * Legacy probing.
- */
- const char *(*probe)(struct device *dsa_dev,
- struct device *host_dev, int sw_addr,
- void **priv);
-#endif
-
enum dsa_tag_protocol (*get_tag_protocol)(struct dsa_switch *ds,
int port);
@@ -474,20 +465,6 @@ struct dsa_switch_driver {
const struct dsa_switch_ops *ops;
};
-#if IS_ENABLED(CONFIG_NET_DSA_LEGACY)
-/* Legacy driver registration */
-void register_switch_driver(struct dsa_switch_driver *type);
-void unregister_switch_driver(struct dsa_switch_driver *type);
-struct mii_bus *dsa_host_dev_to_mii_bus(struct device *dev);
-
-#else
-static inline void register_switch_driver(struct dsa_switch_driver *type) { }
-static inline void unregister_switch_driver(struct dsa_switch_driver *type) { }
-static inline struct mii_bus *dsa_host_dev_to_mii_bus(struct device *dev)
-{
- return NULL;
-}
-#endif
struct net_device *dsa_dev_to_net_device(struct device *dev);
/* Keep inline for faster access in hot path */
diff --git a/net/dsa/Kconfig b/net/dsa/Kconfig
index 91e52973ee13..80692d6cc531 100644
--- a/net/dsa/Kconfig
+++ b/net/dsa/Kconfig
@@ -16,15 +16,6 @@ config NET_DSA
if NET_DSA
-config NET_DSA_LEGACY
- bool "Support for older platform device and Device Tree registration"
- default y
- ---help---
- Say Y if you want to enable support for the older platform device and
- deprecated Device Tree binding registration.
-
- This feature is scheduled for removal in 4.17.
-
# tagging formats
config NET_DSA_TAG_BRCM
bool
diff --git a/net/dsa/Makefile b/net/dsa/Makefile
index 6e721f7a2947..cf59f3783c3c 100644
--- a/net/dsa/Makefile
+++ b/net/dsa/Makefile
@@ -2,7 +2,6 @@
# the core
obj-$(CONFIG_NET_DSA) += dsa_core.o
dsa_core-y += dsa.o dsa2.o master.o port.o slave.o switch.o
-dsa_core-$(CONFIG_NET_DSA_LEGACY) += legacy.o
# tagging formats
dsa_core-$(CONFIG_NET_DSA_TAG_BRCM) += tag_brcm.o
diff --git a/net/dsa/dsa.c b/net/dsa/dsa.c
index aee909bcddc4..70b9d2b9b002 100644
--- a/net/dsa/dsa.c
+++ b/net/dsa/dsa.c
@@ -344,10 +344,6 @@ static int __init dsa_init_module(void)
if (rc)
return rc;
- rc = dsa_legacy_register();
- if (rc)
- return rc;
-
dev_add_pack(&dsa_pack_type);
return 0;
@@ -358,7 +354,6 @@ static void __exit dsa_cleanup_module(void)
{
dsa_slave_unregister_notifier();
dev_remove_pack(&dsa_pack_type);
- dsa_legacy_unregister();
destroy_workqueue(dsa_owq);
}
module_exit(dsa_cleanup_module);
diff --git a/net/dsa/dsa_priv.h b/net/dsa/dsa_priv.h
index 1f4972dab9f2..9c9d94efafdf 100644
--- a/net/dsa/dsa_priv.h
+++ b/net/dsa/dsa_priv.h
@@ -88,18 +88,6 @@ const struct dsa_device_ops *dsa_resolve_tag_protocol(int tag_protocol);
bool dsa_schedule_work(struct work_struct *work);
const char *dsa_tag_protocol_to_str(const struct dsa_device_ops *ops);
-/* legacy.c */
-#if IS_ENABLED(CONFIG_NET_DSA_LEGACY)
-int dsa_legacy_register(void);
-void dsa_legacy_unregister(void);
-#else
-static inline int dsa_legacy_register(void)
-{
- return 0;
-}
-
-static inline void dsa_legacy_unregister(void) { }
-#endif
int dsa_legacy_fdb_add(struct ndmsg *ndm, struct nlattr *tb[],
struct net_device *dev,
const unsigned char *addr, u16 vid,
diff --git a/net/dsa/legacy.c b/net/dsa/legacy.c
index cb42939db776..e69de29bb2d1 100644
--- a/net/dsa/legacy.c
+++ b/net/dsa/legacy.c
@@ -1,745 +0,0 @@
-/*
- * net/dsa/legacy.c - Hardware switch handling
- * Copyright (c) 2008-2009 Marvell Semiconductor
- * Copyright (c) 2013 Florian Fainelli <florian@openwrt.org>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- */
-
-#include <linux/device.h>
-#include <linux/list.h>
-#include <linux/platform_device.h>
-#include <linux/slab.h>
-#include <linux/module.h>
-#include <linux/of.h>
-#include <linux/of_mdio.h>
-#include <linux/of_platform.h>
-#include <linux/of_net.h>
-#include <linux/netdevice.h>
-#include <linux/sysfs.h>
-#include <linux/phy_fixed.h>
-#include <linux/etherdevice.h>
-
-#include "dsa_priv.h"
-
-/* switch driver registration ***********************************************/
-static DEFINE_MUTEX(dsa_switch_drivers_mutex);
-static LIST_HEAD(dsa_switch_drivers);
-
-void register_switch_driver(struct dsa_switch_driver *drv)
-{
- mutex_lock(&dsa_switch_drivers_mutex);
- list_add_tail(&drv->list, &dsa_switch_drivers);
- mutex_unlock(&dsa_switch_drivers_mutex);
-}
-EXPORT_SYMBOL_GPL(register_switch_driver);
-
-void unregister_switch_driver(struct dsa_switch_driver *drv)
-{
- mutex_lock(&dsa_switch_drivers_mutex);
- list_del_init(&drv->list);
- mutex_unlock(&dsa_switch_drivers_mutex);
-}
-EXPORT_SYMBOL_GPL(unregister_switch_driver);
-
-static const struct dsa_switch_ops *
-dsa_switch_probe(struct device *parent, struct device *host_dev, int sw_addr,
- const char **_name, void **priv)
-{
- const struct dsa_switch_ops *ret;
- struct list_head *list;
- const char *name;
-
- ret = NULL;
- name = NULL;
-
- mutex_lock(&dsa_switch_drivers_mutex);
- list_for_each(list, &dsa_switch_drivers) {
- const struct dsa_switch_ops *ops;
- struct dsa_switch_driver *drv;
-
- drv = list_entry(list, struct dsa_switch_driver, list);
- ops = drv->ops;
-
- name = ops->probe(parent, host_dev, sw_addr, priv);
- if (name != NULL) {
- ret = ops;
- break;
- }
- }
- mutex_unlock(&dsa_switch_drivers_mutex);
-
- *_name = name;
-
- return ret;
-}
-
-/* basic switch operations **************************************************/
-static int dsa_cpu_dsa_setups(struct dsa_switch *ds)
-{
- int ret, port;
-
- for (port = 0; port < ds->num_ports; port++) {
- if (!(dsa_is_cpu_port(ds, port) || dsa_is_dsa_port(ds, port)))
- continue;
-
- ret = dsa_port_link_register_of(&ds->ports[port]);
- if (ret)
- return ret;
- }
- return 0;
-}
-
-static int dsa_switch_setup_one(struct dsa_switch *ds,
- struct net_device *master)
-{
- const struct dsa_switch_ops *ops = ds->ops;
- struct dsa_switch_tree *dst = ds->dst;
- struct dsa_chip_data *cd = ds->cd;
- bool valid_name_found = false;
- int index = ds->index;
- struct dsa_port *dp;
- int i, ret;
-
- /*
- * Validate supplied switch configuration.
- */
- for (i = 0; i < ds->num_ports; i++) {
- char *name;
-
- dp = &ds->ports[i];
-
- name = cd->port_names[i];
- if (name == NULL)
- continue;
- dp->name = name;
-
- if (!strcmp(name, "cpu")) {
- if (dst->cpu_dp) {
- netdev_err(master,
- "multiple cpu ports?!\n");
- return -EINVAL;
- }
- dst->cpu_dp = &ds->ports[i];
- dst->cpu_dp->master = master;
- dp->type = DSA_PORT_TYPE_CPU;
- } else if (!strcmp(name, "dsa")) {
- dp->type = DSA_PORT_TYPE_DSA;
- } else {
- dp->type = DSA_PORT_TYPE_USER;
- }
- valid_name_found = true;
- }
-
- if (!valid_name_found && i == ds->num_ports)
- return -EINVAL;
-
- /* Make the built-in MII bus mask match the number of ports,
- * switch drivers can override this later
- */
- ds->phys_mii_mask |= dsa_user_ports(ds);
-
- /*
- * If the CPU connects to this switch, set the switch tree
- * tagging protocol to the preferred tagging format of this
- * switch.
- */
- if (dst->cpu_dp->ds == ds) {
- const struct dsa_device_ops *tag_ops;
- enum dsa_tag_protocol tag_protocol;
-
- tag_protocol = ops->get_tag_protocol(ds, dst->cpu_dp->index);
- tag_ops = dsa_resolve_tag_protocol(tag_protocol);
- if (IS_ERR(tag_ops))
- return PTR_ERR(tag_ops);
-
- dst->cpu_dp->tag_ops = tag_ops;
-
- /* Few copies for faster access in master receive hot path */
- dst->cpu_dp->rcv = dst->cpu_dp->tag_ops->rcv;
- dst->cpu_dp->dst = dst;
- }
-
- memcpy(ds->rtable, cd->rtable, sizeof(ds->rtable));
-
- /*
- * Do basic register setup.
- */
- ret = ops->setup(ds);
- if (ret < 0)
- return ret;
-
- ret = dsa_switch_register_notifier(ds);
- if (ret)
- return ret;
-
- if (!ds->slave_mii_bus && ops->phy_read) {
- ds->slave_mii_bus = devm_mdiobus_alloc(ds->dev);
- if (!ds->slave_mii_bus)
- return -ENOMEM;
- dsa_slave_mii_bus_init(ds);
-
- ret = mdiobus_register(ds->slave_mii_bus);
- if (ret < 0)
- return ret;
- }
-
- /*
- * Create network devices for physical switch ports.
- */
- for (i = 0; i < ds->num_ports; i++) {
- ds->ports[i].dn = cd->port_dn[i];
- ds->ports[i].cpu_dp = dst->cpu_dp;
-
- if (!dsa_is_user_port(ds, i))
- continue;
-
- ret = dsa_slave_create(&ds->ports[i]);
- if (ret < 0)
- netdev_err(master, "[%d]: can't create dsa slave device for port %d(%s): %d\n",
- index, i, cd->port_names[i], ret);
- }
-
- /* Perform configuration of the CPU and DSA ports */
- ret = dsa_cpu_dsa_setups(ds);
- if (ret < 0)
- netdev_err(master, "[%d] : can't configure CPU and DSA ports\n",
- index);
-
- return 0;
-}
-
-static struct dsa_switch *
-dsa_switch_setup(struct dsa_switch_tree *dst, struct net_device *master,
- int index, struct device *parent, struct device *host_dev)
-{
- struct dsa_chip_data *cd = dst->pd->chip + index;
- const struct dsa_switch_ops *ops;
- struct dsa_switch *ds;
- int ret;
- const char *name;
- void *priv;
-
- /*
- * Probe for switch model.
- */
- ops = dsa_switch_probe(parent, host_dev, cd->sw_addr, &name, &priv);
- if (!ops) {
- netdev_err(master, "[%d]: could not detect attached switch\n",
- index);
- return ERR_PTR(-EINVAL);
- }
- netdev_info(master, "[%d]: detected a %s switch\n",
- index, name);
-
-
- /*
- * Allocate and initialise switch state.
- */
- ds = dsa_switch_alloc(parent, DSA_MAX_PORTS);
- if (!ds)
- return ERR_PTR(-ENOMEM);
-
- ds->dst = dst;
- ds->index = index;
- ds->cd = cd;
- ds->ops = ops;
- ds->priv = priv;
-
- ret = dsa_switch_setup_one(ds, master);
- if (ret)
- return ERR_PTR(ret);
-
- return ds;
-}
-
-static void dsa_switch_destroy(struct dsa_switch *ds)
-{
- int port;
-
- /* Destroy network devices for physical switch ports. */
- for (port = 0; port < ds->num_ports; port++) {
- if (!dsa_is_user_port(ds, port))
- continue;
-
- if (!ds->ports[port].slave)
- continue;
-
- dsa_slave_destroy(ds->ports[port].slave);
- }
-
- /* Disable configuration of the CPU and DSA ports */
- for (port = 0; port < ds->num_ports; port++) {
- if (!(dsa_is_cpu_port(ds, port) || dsa_is_dsa_port(ds, port)))
- continue;
- dsa_port_link_unregister_of(&ds->ports[port]);
- }
-
- if (ds->slave_mii_bus && ds->ops->phy_read)
- mdiobus_unregister(ds->slave_mii_bus);
-
- dsa_switch_unregister_notifier(ds);
-}
-
-/* platform driver init and cleanup *****************************************/
-static int dev_is_class(struct device *dev, void *class)
-{
- if (dev->class != NULL && !strcmp(dev->class->name, class))
- return 1;
-
- return 0;
-}
-
-static struct device *dev_find_class(struct device *parent, char *class)
-{
- if (dev_is_class(parent, class)) {
- get_device(parent);
- return parent;
- }
-
- return device_find_child(parent, class, dev_is_class);
-}
-
-struct mii_bus *dsa_host_dev_to_mii_bus(struct device *dev)
-{
- struct device *d;
-
- d = dev_find_class(dev, "mdio_bus");
- if (d != NULL) {
- struct mii_bus *bus;
-
- bus = to_mii_bus(d);
- put_device(d);
-
- return bus;
- }
-
- return NULL;
-}
-EXPORT_SYMBOL_GPL(dsa_host_dev_to_mii_bus);
-
-#ifdef CONFIG_OF
-static int dsa_of_setup_routing_table(struct dsa_platform_data *pd,
- struct dsa_chip_data *cd,
- int chip_index, int port_index,
- struct device_node *link)
-{
- const __be32 *reg;
- int link_sw_addr;
- struct device_node *parent_sw;
- int len;
-
- parent_sw = of_get_parent(link);
- if (!parent_sw)
- return -EINVAL;
-
- reg = of_get_property(parent_sw, "reg", &len);
- if (!reg || (len != sizeof(*reg) * 2))
- return -EINVAL;
-
- /*
- * Get the destination switch number from the second field of its 'reg'
- * property, i.e. for "reg = <0x19 1>" sw_addr is '1'.
- */
- link_sw_addr = be32_to_cpup(reg + 1);
-
- if (link_sw_addr >= pd->nr_chips)
- return -EINVAL;
-
- cd->rtable[link_sw_addr] = port_index;
-
- return 0;
-}
-
-static int dsa_of_probe_links(struct dsa_platform_data *pd,
- struct dsa_chip_data *cd,
- int chip_index, int port_index,
- struct device_node *port,
- const char *port_name)
-{
- struct device_node *link;
- int link_index;
- int ret;
-
- for (link_index = 0;; link_index++) {
- link = of_parse_phandle(port, "link", link_index);
- if (!link)
- break;
-
- if (!strcmp(port_name, "dsa") && pd->nr_chips > 1) {
- ret = dsa_of_setup_routing_table(pd, cd, chip_index,
- port_index, link);
- if (ret)
- return ret;
- }
- }
- return 0;
-}
-
-static void dsa_of_free_platform_data(struct dsa_platform_data *pd)
-{
- int i;
- int port_index;
-
- for (i = 0; i < pd->nr_chips; i++) {
- port_index = 0;
- while (port_index < DSA_MAX_PORTS) {
- kfree(pd->chip[i].port_names[port_index]);
- port_index++;
- }
-
- /* Drop our reference to the MDIO bus device */
- put_device(pd->chip[i].host_dev);
- }
- kfree(pd->chip);
-}
-
-static int dsa_of_probe(struct device *dev)
-{
- struct device_node *np = dev->of_node;
- struct device_node *child, *mdio, *ethernet, *port;
- struct mii_bus *mdio_bus, *mdio_bus_switch;
- struct net_device *ethernet_dev;
- struct dsa_platform_data *pd;
- struct dsa_chip_data *cd;
- const char *port_name;
- int chip_index, port_index;
- const unsigned int *sw_addr, *port_reg;
- u32 eeprom_len;
- int ret;
-
- mdio = of_parse_phandle(np, "dsa,mii-bus", 0);
- if (!mdio)
- return -EINVAL;
-
- mdio_bus = of_mdio_find_bus(mdio);
- if (!mdio_bus)
- return -EPROBE_DEFER;
-
- ethernet = of_parse_phandle(np, "dsa,ethernet", 0);
- if (!ethernet) {
- ret = -EINVAL;
- goto out_put_mdio;
- }
-
- ethernet_dev = of_find_net_device_by_node(ethernet);
- if (!ethernet_dev) {
- ret = -EPROBE_DEFER;
- goto out_put_mdio;
- }
-
- pd = kzalloc(sizeof(*pd), GFP_KERNEL);
- if (!pd) {
- ret = -ENOMEM;
- goto out_put_ethernet;
- }
-
- dev->platform_data = pd;
- pd->of_netdev = ethernet_dev;
- pd->nr_chips = of_get_available_child_count(np);
- if (pd->nr_chips > DSA_MAX_SWITCHES)
- pd->nr_chips = DSA_MAX_SWITCHES;
-
- pd->chip = kcalloc(pd->nr_chips, sizeof(struct dsa_chip_data),
- GFP_KERNEL);
- if (!pd->chip) {
- ret = -ENOMEM;
- goto out_free;
- }
-
- chip_index = -1;
- for_each_available_child_of_node(np, child) {
- int i;
-
- chip_index++;
- cd = &pd->chip[chip_index];
-
- cd->of_node = child;
-
- /* Initialize the routing table */
- for (i = 0; i < DSA_MAX_SWITCHES; ++i)
- cd->rtable[i] = DSA_RTABLE_NONE;
-
- /* When assigning the host device, increment its refcount */
- cd->host_dev = get_device(&mdio_bus->dev);
-
- sw_addr = of_get_property(child, "reg", NULL);
- if (!sw_addr)
- continue;
-
- cd->sw_addr = be32_to_cpup(sw_addr);
- if (cd->sw_addr >= PHY_MAX_ADDR)
- continue;
-
- if (!of_property_read_u32(child, "eeprom-length", &eeprom_len))
- cd->eeprom_len = eeprom_len;
-
- mdio = of_parse_phandle(child, "mii-bus", 0);
- if (mdio) {
- mdio_bus_switch = of_mdio_find_bus(mdio);
- if (!mdio_bus_switch) {
- ret = -EPROBE_DEFER;
- goto out_free_chip;
- }
-
- /* Drop the mdio_bus device ref, replacing the host
- * device with the mdio_bus_switch device, keeping
- * the refcount from of_mdio_find_bus() above.
- */
- put_device(cd->host_dev);
- cd->host_dev = &mdio_bus_switch->dev;
- }
-
- for_each_available_child_of_node(child, port) {
- port_reg = of_get_property(port, "reg", NULL);
- if (!port_reg)
- continue;
-
- port_index = be32_to_cpup(port_reg);
- if (port_index >= DSA_MAX_PORTS)
- break;
-
- port_name = of_get_property(port, "label", NULL);
- if (!port_name)
- continue;
-
- cd->port_dn[port_index] = port;
-
- cd->port_names[port_index] = kstrdup(port_name,
- GFP_KERNEL);
- if (!cd->port_names[port_index]) {
- ret = -ENOMEM;
- goto out_free_chip;
- }
-
- ret = dsa_of_probe_links(pd, cd, chip_index,
- port_index, port, port_name);
- if (ret)
- goto out_free_chip;
-
- }
- }
-
- /* The individual chips hold their own refcount on the mdio bus,
- * so drop ours */
- put_device(&mdio_bus->dev);
-
- return 0;
-
-out_free_chip:
- dsa_of_free_platform_data(pd);
-out_free:
- kfree(pd);
- dev->platform_data = NULL;
-out_put_ethernet:
- put_device(ðernet_dev->dev);
-out_put_mdio:
- put_device(&mdio_bus->dev);
- return ret;
-}
-
-static void dsa_of_remove(struct device *dev)
-{
- struct dsa_platform_data *pd = dev->platform_data;
-
- if (!dev->of_node)
- return;
-
- dsa_of_free_platform_data(pd);
- put_device(&pd->of_netdev->dev);
- kfree(pd);
-}
-#else
-static inline int dsa_of_probe(struct device *dev)
-{
- return 0;
-}
-
-static inline void dsa_of_remove(struct device *dev)
-{
-}
-#endif
-
-static int dsa_setup_dst(struct dsa_switch_tree *dst, struct net_device *dev,
- struct device *parent, struct dsa_platform_data *pd)
-{
- int i;
- unsigned configured = 0;
-
- dst->pd = pd;
-
- for (i = 0; i < pd->nr_chips; i++) {
- struct dsa_switch *ds;
-
- ds = dsa_switch_setup(dst, dev, i, parent, pd->chip[i].host_dev);
- if (IS_ERR(ds)) {
- netdev_err(dev, "[%d]: couldn't create dsa switch instance (error %ld)\n",
- i, PTR_ERR(ds));
- continue;
- }
-
- dst->ds[i] = ds;
-
- ++configured;
- }
-
- /*
- * If no switch was found, exit cleanly
- */
- if (!configured)
- return -EPROBE_DEFER;
-
- return dsa_master_setup(dst->cpu_dp->master, dst->cpu_dp);
-}
-
-static int dsa_probe(struct platform_device *pdev)
-{
- struct dsa_platform_data *pd = pdev->dev.platform_data;
- struct net_device *dev;
- struct dsa_switch_tree *dst;
- int ret;
-
- if (pdev->dev.of_node) {
- ret = dsa_of_probe(&pdev->dev);
- if (ret)
- return ret;
-
- pd = pdev->dev.platform_data;
- }
-
- if (pd == NULL || (pd->netdev == NULL && pd->of_netdev == NULL))
- return -EINVAL;
-
- if (pd->of_netdev) {
- dev = pd->of_netdev;
- dev_hold(dev);
- } else {
- dev = dsa_dev_to_net_device(pd->netdev);
- }
- if (dev == NULL) {
- ret = -EPROBE_DEFER;
- goto out;
- }
-
- if (dev->dsa_ptr != NULL) {
- dev_put(dev);
- ret = -EEXIST;
- goto out;
- }
-
- dst = devm_kzalloc(&pdev->dev, sizeof(*dst), GFP_KERNEL);
- if (dst == NULL) {
- dev_put(dev);
- ret = -ENOMEM;
- goto out;
- }
-
- platform_set_drvdata(pdev, dst);
-
- ret = dsa_setup_dst(dst, dev, &pdev->dev, pd);
- if (ret) {
- dev_put(dev);
- goto out;
- }
-
- return 0;
-
-out:
- dsa_of_remove(&pdev->dev);
-
- return ret;
-}
-
-static void dsa_remove_dst(struct dsa_switch_tree *dst)
-{
- int i;
-
- dsa_master_teardown(dst->cpu_dp->master);
-
- for (i = 0; i < dst->pd->nr_chips; i++) {
- struct dsa_switch *ds = dst->ds[i];
-
- if (ds)
- dsa_switch_destroy(ds);
- }
-
- dev_put(dst->cpu_dp->master);
-}
-
-static int dsa_remove(struct platform_device *pdev)
-{
- struct dsa_switch_tree *dst = platform_get_drvdata(pdev);
-
- dsa_remove_dst(dst);
- dsa_of_remove(&pdev->dev);
-
- return 0;
-}
-
-static void dsa_shutdown(struct platform_device *pdev)
-{
-}
-
-#ifdef CONFIG_PM_SLEEP
-static int dsa_suspend(struct device *d)
-{
- struct dsa_switch_tree *dst = dev_get_drvdata(d);
- int i, ret = 0;
-
- for (i = 0; i < dst->pd->nr_chips; i++) {
- struct dsa_switch *ds = dst->ds[i];
-
- if (ds != NULL)
- ret = dsa_switch_suspend(ds);
- }
-
- return ret;
-}
-
-static int dsa_resume(struct device *d)
-{
- struct dsa_switch_tree *dst = dev_get_drvdata(d);
- int i, ret = 0;
-
- for (i = 0; i < dst->pd->nr_chips; i++) {
- struct dsa_switch *ds = dst->ds[i];
-
- if (ds != NULL)
- ret = dsa_switch_resume(ds);
- }
-
- return ret;
-}
-#endif
-
-static SIMPLE_DEV_PM_OPS(dsa_pm_ops, dsa_suspend, dsa_resume);
-
-static const struct of_device_id dsa_of_match_table[] = {
- { .compatible = "marvell,dsa", },
- {}
-};
-MODULE_DEVICE_TABLE(of, dsa_of_match_table);
-
-static struct platform_driver dsa_driver = {
- .probe = dsa_probe,
- .remove = dsa_remove,
- .shutdown = dsa_shutdown,
- .driver = {
- .name = "dsa",
- .of_match_table = dsa_of_match_table,
- .pm = &dsa_pm_ops,
- },
-};
-
-int dsa_legacy_register(void)
-{
- return platform_driver_register(&dsa_driver);
-}
-
-void dsa_legacy_unregister(void)
-{
- platform_driver_unregister(&dsa_driver);
-}
--
2.20.1
^ permalink raw reply related
* [PATCH RFC RFT net-next 07/10] net: dsa: mv88e6060: Add SPDX header
From: Andrew Lunn @ 2019-01-30 0:37 UTC (permalink / raw)
To: netdev; +Cc: Vivien Didelot, Florian Fainelli, Pavel Machek, Andrew Lunn
In-Reply-To: <20190130003758.23852-1-andrew@lunn.ch>
Add an SPDX header, and remove the license text.
Signed-off-by: Andrew Lunn <andrew@lunn.ch>
---
drivers/net/dsa/mv88e6060.c | 6 +-----
1 file changed, 1 insertion(+), 5 deletions(-)
diff --git a/drivers/net/dsa/mv88e6060.c b/drivers/net/dsa/mv88e6060.c
index 792091a7153b..df5940259604 100644
--- a/drivers/net/dsa/mv88e6060.c
+++ b/drivers/net/dsa/mv88e6060.c
@@ -1,11 +1,7 @@
+// SPDX-License-Identifier: GPL-2.0+
/*
* net/dsa/mv88e6060.c - Driver for Marvell 88e6060 switch chips
* Copyright (c) 2008-2009 Marvell Semiconductor
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
*/
#include <linux/delay.h>
--
2.20.1
^ permalink raw reply related
* [PATCH RFC RFT net-next 05/10] net: dsa: mv88e6060: Support probing as an mdio device
From: Andrew Lunn @ 2019-01-30 0:37 UTC (permalink / raw)
To: netdev; +Cc: Vivien Didelot, Florian Fainelli, Pavel Machek, Andrew Lunn
In-Reply-To: <20190130003758.23852-1-andrew@lunn.ch>
Probing DSA devices as platform devices has been superseded by using
normal bus drivers. Add support for probing the mv88e6060 device as an
mdio device.
Signed-off-by: Andrew Lunn <andrew@lunn.ch>
---
drivers/net/dsa/mv88e6060.c | 61 ++++++++++++++++++++++++++++++++++++-
1 file changed, 60 insertions(+), 1 deletion(-)
diff --git a/drivers/net/dsa/mv88e6060.c b/drivers/net/dsa/mv88e6060.c
index 00fdf155dcec..aaa176edafc0 100644
--- a/drivers/net/dsa/mv88e6060.c
+++ b/drivers/net/dsa/mv88e6060.c
@@ -280,19 +280,78 @@ static struct dsa_switch_driver mv88e6060_switch_drv = {
.ops = &mv88e6060_switch_ops,
};
+static int mv88e6060_probe(struct mdio_device *mdiodev)
+{
+ struct device *dev = &mdiodev->dev;
+ struct mv88e6060_priv *priv;
+ struct dsa_switch *ds;
+ const char *name;
+
+ priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);
+ if (!priv)
+ return -ENOMEM;
+
+ priv->bus = mdiodev->bus;
+ priv->sw_addr = mdiodev->addr;
+
+ name = mv88e6060_get_name(priv->bus, priv->sw_addr);
+ if (!name)
+ return -ENODEV;
+
+ dev_info(dev, "switch %s detected\n", name);
+
+ ds = dsa_switch_alloc(dev, MV88E6060_PORTS);
+ if (!ds)
+ return -ENOMEM;
+
+ ds->priv = priv;
+ ds->dev = dev;
+ ds->ops = &mv88e6060_switch_ops;
+
+ dev_set_drvdata(dev, ds);
+
+ return dsa_register_switch(ds);
+}
+
+static void mv88e6060_remove(struct mdio_device *mdiodev)
+{
+ struct dsa_switch *ds = dev_get_drvdata(&mdiodev->dev);
+
+ dsa_unregister_switch(ds);
+}
+
+static const struct of_device_id mv88e6060_of_match[] = {
+ {
+ .compatible = "marvell,mv88e6060",
+ },
+ { /* sentinel */ },
+};
+
+static struct mdio_driver mv88e6060_driver = {
+ .probe = mv88e6060_probe,
+ .remove = mv88e6060_remove,
+ .mdiodrv.driver = {
+ .name = "mv88e6060",
+ .of_match_table = mv88e6060_of_match,
+ },
+};
+
static int __init mv88e6060_init(void)
{
register_switch_driver(&mv88e6060_switch_drv);
- return 0;
+ return mdio_driver_register(&mv88e6060_driver);
}
module_init(mv88e6060_init);
static void __exit mv88e6060_cleanup(void)
{
+ mdio_driver_unregister(&mv88e6060_driver);
unregister_switch_driver(&mv88e6060_switch_drv);
}
module_exit(mv88e6060_cleanup);
+
+
MODULE_AUTHOR("Lennert Buytenhek <buytenh@wantstofly.org>");
MODULE_DESCRIPTION("Driver for Marvell 88E6060 ethernet switch chip");
MODULE_LICENSE("GPL");
--
2.20.1
^ permalink raw reply related
* [PATCH RFC RFT net-next 04/10] net: dsa: mv88e6060: Replace REG_READ macro
From: Andrew Lunn @ 2019-01-30 0:37 UTC (permalink / raw)
To: netdev; +Cc: Vivien Didelot, Florian Fainelli, Pavel Machek, Andrew Lunn
In-Reply-To: <20190130003758.23852-1-andrew@lunn.ch>
The REG_READ macro contains a return statement, making it not very
safe. Remove it by inlining the code.
Signed-off-by: Andrew Lunn <andrew@lunn.ch>
---
drivers/net/dsa/mv88e6060.c | 20 +++++++-------------
1 file changed, 7 insertions(+), 13 deletions(-)
diff --git a/drivers/net/dsa/mv88e6060.c b/drivers/net/dsa/mv88e6060.c
index da88c56e092c..00fdf155dcec 100644
--- a/drivers/net/dsa/mv88e6060.c
+++ b/drivers/net/dsa/mv88e6060.c
@@ -23,17 +23,6 @@ static int reg_read(struct mv88e6060_priv *priv, int addr, int reg)
return mdiobus_read_nested(priv->bus, priv->sw_addr + addr, reg);
}
-#define REG_READ(addr, reg) \
- ({ \
- int __ret; \
- \
- __ret = reg_read(priv, addr, reg); \
- if (__ret < 0) \
- return __ret; \
- __ret; \
- })
-
-
static int reg_write(struct mv88e6060_priv *priv, int addr, int reg, u16 val)
{
return mdiobus_write_nested(priv->bus, priv->sw_addr + addr, reg, val);
@@ -92,7 +81,9 @@ static int mv88e6060_switch_reset(struct mv88e6060_priv *priv)
/* Set all ports to the disabled state. */
for (i = 0; i < MV88E6060_PORTS; i++) {
- ret = REG_READ(REG_PORT(i), PORT_CONTROL);
+ ret = reg_read(priv, REG_PORT(i), PORT_CONTROL);
+ if (ret < 0)
+ return ret;
ret = reg_write(priv, REG_PORT(i), PORT_CONTROL,
ret & ~PORT_CONTROL_STATE_MASK);
if (ret)
@@ -112,7 +103,10 @@ static int mv88e6060_switch_reset(struct mv88e6060_priv *priv)
/* Wait up to one second for reset to complete. */
timeout = jiffies + 1 * HZ;
while (time_before(jiffies, timeout)) {
- ret = REG_READ(REG_GLOBAL, GLOBAL_STATUS);
+ ret = reg_read(priv, REG_GLOBAL, GLOBAL_STATUS);
+ if (ret < 0)
+ return ret;
+
if (ret & GLOBAL_STATUS_INIT_READY)
break;
--
2.20.1
^ permalink raw reply related
* [PATCH RFC RFT net-next 03/10] net: dsa: mv88e6060: Replace REG_WRITE macro
From: Andrew Lunn @ 2019-01-30 0:37 UTC (permalink / raw)
To: netdev; +Cc: Vivien Didelot, Florian Fainelli, Pavel Machek, Andrew Lunn
In-Reply-To: <20190130003758.23852-1-andrew@lunn.ch>
The REG_WRITE macro contains a return statement, making it not very
safe. Remove it by inlining the code.
Signed-off-by: Andrew Lunn <andrew@lunn.ch>
---
drivers/net/dsa/mv88e6060.c | 73 +++++++++++++++++++++----------------
1 file changed, 41 insertions(+), 32 deletions(-)
diff --git a/drivers/net/dsa/mv88e6060.c b/drivers/net/dsa/mv88e6060.c
index 631358bf3d6b..da88c56e092c 100644
--- a/drivers/net/dsa/mv88e6060.c
+++ b/drivers/net/dsa/mv88e6060.c
@@ -39,15 +39,6 @@ static int reg_write(struct mv88e6060_priv *priv, int addr, int reg, u16 val)
return mdiobus_write_nested(priv->bus, priv->sw_addr + addr, reg, val);
}
-#define REG_WRITE(addr, reg, val) \
- ({ \
- int __ret; \
- \
- __ret = reg_write(priv, addr, reg, val); \
- if (__ret < 0) \
- return __ret; \
- })
-
static const char *mv88e6060_get_name(struct mii_bus *bus, int sw_addr)
{
int ret;
@@ -102,17 +93,21 @@ static int mv88e6060_switch_reset(struct mv88e6060_priv *priv)
/* Set all ports to the disabled state. */
for (i = 0; i < MV88E6060_PORTS; i++) {
ret = REG_READ(REG_PORT(i), PORT_CONTROL);
- REG_WRITE(REG_PORT(i), PORT_CONTROL,
- ret & ~PORT_CONTROL_STATE_MASK);
+ ret = reg_write(priv, REG_PORT(i), PORT_CONTROL,
+ ret & ~PORT_CONTROL_STATE_MASK);
+ if (ret)
+ return ret;
}
/* Wait for transmit queues to drain. */
usleep_range(2000, 4000);
/* Reset the switch. */
- REG_WRITE(REG_GLOBAL, GLOBAL_ATU_CONTROL,
- GLOBAL_ATU_CONTROL_SWRESET |
- GLOBAL_ATU_CONTROL_LEARNDIS);
+ ret = reg_write(priv, REG_GLOBAL, GLOBAL_ATU_CONTROL,
+ GLOBAL_ATU_CONTROL_SWRESET |
+ GLOBAL_ATU_CONTROL_LEARNDIS);
+ if (ret)
+ return ret;
/* Wait up to one second for reset to complete. */
timeout = jiffies + 1 * HZ;
@@ -131,59 +126,67 @@ static int mv88e6060_switch_reset(struct mv88e6060_priv *priv)
static int mv88e6060_setup_global(struct mv88e6060_priv *priv)
{
+ int ret;
+
/* Disable discarding of frames with excessive collisions,
* set the maximum frame size to 1536 bytes, and mask all
* interrupt sources.
*/
- REG_WRITE(REG_GLOBAL, GLOBAL_CONTROL, GLOBAL_CONTROL_MAX_FRAME_1536);
+ ret = reg_write(priv, REG_GLOBAL, GLOBAL_CONTROL,
+ GLOBAL_CONTROL_MAX_FRAME_1536);
+ if (ret)
+ return ret;
/* Disable automatic address learning.
*/
- REG_WRITE(REG_GLOBAL, GLOBAL_ATU_CONTROL,
- GLOBAL_ATU_CONTROL_LEARNDIS);
-
- return 0;
+ return reg_write(priv, REG_GLOBAL, GLOBAL_ATU_CONTROL,
+ GLOBAL_ATU_CONTROL_LEARNDIS);
}
static int mv88e6060_setup_port(struct mv88e6060_priv *priv, int p)
{
int addr = REG_PORT(p);
+ int ret;
/* Do not force flow control, disable Ingress and Egress
* Header tagging, disable VLAN tunneling, and set the port
* state to Forwarding. Additionally, if this is the CPU
* port, enable Ingress and Egress Trailer tagging mode.
*/
- REG_WRITE(addr, PORT_CONTROL,
- dsa_is_cpu_port(priv->ds, p) ?
+ ret = reg_write(priv, addr, PORT_CONTROL,
+ dsa_is_cpu_port(priv->ds, p) ?
PORT_CONTROL_TRAILER |
PORT_CONTROL_INGRESS_MODE |
PORT_CONTROL_STATE_FORWARDING :
PORT_CONTROL_STATE_FORWARDING);
+ if (ret)
+ return ret;
/* Port based VLAN map: give each port its own address
* database, allow the CPU port to talk to each of the 'real'
* ports, and allow each of the 'real' ports to only talk to
* the CPU port.
*/
- REG_WRITE(addr, PORT_VLAN_MAP,
- ((p & 0xf) << PORT_VLAN_MAP_DBNUM_SHIFT) |
- (dsa_is_cpu_port(priv->ds, p) ? dsa_user_ports(priv->ds) :
- BIT(dsa_to_port(priv->ds, p)->cpu_dp->index)));
+ ret = reg_write(priv, addr, PORT_VLAN_MAP,
+ ((p & 0xf) << PORT_VLAN_MAP_DBNUM_SHIFT) |
+ (dsa_is_cpu_port(priv->ds, p) ?
+ dsa_user_ports(priv->ds) :
+ BIT(dsa_to_port(priv->ds, p)->cpu_dp->index)));
+ if (ret)
+ return ret;
/* Port Association Vector: when learning source addresses
* of packets, add the address to the address database using
* a port bitmap that has only the bit for this port set and
* the other bits clear.
*/
- REG_WRITE(addr, PORT_ASSOC_VECTOR, BIT(p));
-
- return 0;
+ return reg_write(priv, addr, PORT_ASSOC_VECTOR, BIT(p));
}
static int mv88e6060_setup_addr(struct mv88e6060_priv *priv)
{
u8 addr[ETH_ALEN];
+ int ret;
u16 val;
eth_random_addr(addr);
@@ -195,11 +198,17 @@ static int mv88e6060_setup_addr(struct mv88e6060_priv *priv)
*/
val &= 0xfeff;
- REG_WRITE(REG_GLOBAL, GLOBAL_MAC_01, val);
- REG_WRITE(REG_GLOBAL, GLOBAL_MAC_23, (addr[2] << 8) | addr[3]);
- REG_WRITE(REG_GLOBAL, GLOBAL_MAC_45, (addr[4] << 8) | addr[5]);
+ ret = reg_write(priv, REG_GLOBAL, GLOBAL_MAC_01, val);
+ if (ret)
+ return ret;
+
+ ret = reg_write(priv, REG_GLOBAL, GLOBAL_MAC_23,
+ (addr[2] << 8) | addr[3]);
+ if (ret)
+ return ret;
- return 0;
+ return reg_write(priv, REG_GLOBAL, GLOBAL_MAC_45,
+ (addr[4] << 8) | addr[5]);
}
static int mv88e6060_setup(struct dsa_switch *ds)
--
2.20.1
^ permalink raw reply related
* [PATCH RFC RFT net-next 06/10] net: dsa: mv88e6060: Remove support for legacy probing
From: Andrew Lunn @ 2019-01-30 0:37 UTC (permalink / raw)
To: netdev; +Cc: Vivien Didelot, Florian Fainelli, Pavel Machek, Andrew Lunn
In-Reply-To: <20190130003758.23852-1-andrew@lunn.ch>
Now that the driver can be probed as an mdio device, remove the legacy
DSA platform device probing.
Signed-off-by: Andrew Lunn <andrew@lunn.ch>
---
drivers/net/dsa/Kconfig | 2 +-
drivers/net/dsa/mv88e6060.c | 42 +------------------------------------
2 files changed, 2 insertions(+), 42 deletions(-)
diff --git a/drivers/net/dsa/Kconfig b/drivers/net/dsa/Kconfig
index 71bb3aebded4..82560b710681 100644
--- a/drivers/net/dsa/Kconfig
+++ b/drivers/net/dsa/Kconfig
@@ -41,7 +41,7 @@ config NET_DSA_MT7530
config NET_DSA_MV88E6060
tristate "Marvell 88E6060 ethernet switch chip support"
- depends on NET_DSA && NET_DSA_LEGACY
+ depends on NET_DSA
select NET_DSA_TAG_TRAILER
---help---
This enables support for the Marvell 88E6060 ethernet switch
diff --git a/drivers/net/dsa/mv88e6060.c b/drivers/net/dsa/mv88e6060.c
index aaa176edafc0..792091a7153b 100644
--- a/drivers/net/dsa/mv88e6060.c
+++ b/drivers/net/dsa/mv88e6060.c
@@ -52,27 +52,6 @@ static enum dsa_tag_protocol mv88e6060_get_tag_protocol(struct dsa_switch *ds,
return DSA_TAG_PROTO_TRAILER;
}
-static const char *mv88e6060_drv_probe(struct device *dsa_dev,
- struct device *host_dev, int sw_addr,
- void **_priv)
-{
- struct mii_bus *bus = dsa_host_dev_to_mii_bus(host_dev);
- struct mv88e6060_priv *priv;
- const char *name;
-
- name = mv88e6060_get_name(bus, sw_addr);
- if (name) {
- priv = devm_kzalloc(dsa_dev, sizeof(*priv), GFP_KERNEL);
- if (!priv)
- return NULL;
- *_priv = priv;
- priv->bus = bus;
- priv->sw_addr = sw_addr;
- }
-
- return name;
-}
-
static int mv88e6060_switch_reset(struct mv88e6060_priv *priv)
{
int i;
@@ -270,16 +249,11 @@ mv88e6060_phy_write(struct dsa_switch *ds, int port, int regnum, u16 val)
static const struct dsa_switch_ops mv88e6060_switch_ops = {
.get_tag_protocol = mv88e6060_get_tag_protocol,
- .probe = mv88e6060_drv_probe,
.setup = mv88e6060_setup,
.phy_read = mv88e6060_phy_read,
.phy_write = mv88e6060_phy_write,
};
-static struct dsa_switch_driver mv88e6060_switch_drv = {
- .ops = &mv88e6060_switch_ops,
-};
-
static int mv88e6060_probe(struct mdio_device *mdiodev)
{
struct device *dev = &mdiodev->dev;
@@ -336,21 +310,7 @@ static struct mdio_driver mv88e6060_driver = {
},
};
-static int __init mv88e6060_init(void)
-{
- register_switch_driver(&mv88e6060_switch_drv);
- return mdio_driver_register(&mv88e6060_driver);
-}
-module_init(mv88e6060_init);
-
-static void __exit mv88e6060_cleanup(void)
-{
- mdio_driver_unregister(&mv88e6060_driver);
- unregister_switch_driver(&mv88e6060_switch_drv);
-}
-module_exit(mv88e6060_cleanup);
-
-
+mdio_module_driver(mv88e6060_driver);
MODULE_AUTHOR("Lennert Buytenhek <buytenh@wantstofly.org>");
MODULE_DESCRIPTION("Driver for Marvell 88E6060 ethernet switch chip");
--
2.20.1
^ permalink raw reply related
* [PATCH RFC RFT net-next 02/10] net: dsa: mv88e6060: Replace ds with priv
From: Andrew Lunn @ 2019-01-30 0:37 UTC (permalink / raw)
To: netdev; +Cc: Vivien Didelot, Florian Fainelli, Pavel Machek, Andrew Lunn
In-Reply-To: <20190130003758.23852-1-andrew@lunn.ch>
Pass around priv, not ds. This will help with changing to an mdio
driver, and makes this driver more like mv88e6xxx.
Signed-off-by: Andrew Lunn <andrew@lunn.ch>
---
drivers/net/dsa/mv88e6060.c | 43 +++++++++++++++++++------------------
drivers/net/dsa/mv88e6060.h | 1 +
2 files changed, 23 insertions(+), 21 deletions(-)
diff --git a/drivers/net/dsa/mv88e6060.c b/drivers/net/dsa/mv88e6060.c
index 0b3e51f248c2..631358bf3d6b 100644
--- a/drivers/net/dsa/mv88e6060.c
+++ b/drivers/net/dsa/mv88e6060.c
@@ -18,10 +18,8 @@
#include <net/dsa.h>
#include "mv88e6060.h"
-static int reg_read(struct dsa_switch *ds, int addr, int reg)
+static int reg_read(struct mv88e6060_priv *priv, int addr, int reg)
{
- struct mv88e6060_priv *priv = ds->priv;
-
return mdiobus_read_nested(priv->bus, priv->sw_addr + addr, reg);
}
@@ -29,17 +27,15 @@ static int reg_read(struct dsa_switch *ds, int addr, int reg)
({ \
int __ret; \
\
- __ret = reg_read(ds, addr, reg); \
+ __ret = reg_read(priv, addr, reg); \
if (__ret < 0) \
return __ret; \
__ret; \
})
-static int reg_write(struct dsa_switch *ds, int addr, int reg, u16 val)
+static int reg_write(struct mv88e6060_priv *priv, int addr, int reg, u16 val)
{
- struct mv88e6060_priv *priv = ds->priv;
-
return mdiobus_write_nested(priv->bus, priv->sw_addr + addr, reg, val);
}
@@ -47,7 +43,7 @@ static int reg_write(struct dsa_switch *ds, int addr, int reg, u16 val)
({ \
int __ret; \
\
- __ret = reg_write(ds, addr, reg, val); \
+ __ret = reg_write(priv, addr, reg, val); \
if (__ret < 0) \
return __ret; \
})
@@ -97,7 +93,7 @@ static const char *mv88e6060_drv_probe(struct device *dsa_dev,
return name;
}
-static int mv88e6060_switch_reset(struct dsa_switch *ds)
+static int mv88e6060_switch_reset(struct mv88e6060_priv *priv)
{
int i;
int ret;
@@ -133,7 +129,7 @@ static int mv88e6060_switch_reset(struct dsa_switch *ds)
return 0;
}
-static int mv88e6060_setup_global(struct dsa_switch *ds)
+static int mv88e6060_setup_global(struct mv88e6060_priv *priv)
{
/* Disable discarding of frames with excessive collisions,
* set the maximum frame size to 1536 bytes, and mask all
@@ -149,7 +145,7 @@ static int mv88e6060_setup_global(struct dsa_switch *ds)
return 0;
}
-static int mv88e6060_setup_port(struct dsa_switch *ds, int p)
+static int mv88e6060_setup_port(struct mv88e6060_priv *priv, int p)
{
int addr = REG_PORT(p);
@@ -159,7 +155,7 @@ static int mv88e6060_setup_port(struct dsa_switch *ds, int p)
* port, enable Ingress and Egress Trailer tagging mode.
*/
REG_WRITE(addr, PORT_CONTROL,
- dsa_is_cpu_port(ds, p) ?
+ dsa_is_cpu_port(priv->ds, p) ?
PORT_CONTROL_TRAILER |
PORT_CONTROL_INGRESS_MODE |
PORT_CONTROL_STATE_FORWARDING :
@@ -172,8 +168,8 @@ static int mv88e6060_setup_port(struct dsa_switch *ds, int p)
*/
REG_WRITE(addr, PORT_VLAN_MAP,
((p & 0xf) << PORT_VLAN_MAP_DBNUM_SHIFT) |
- (dsa_is_cpu_port(ds, p) ? dsa_user_ports(ds) :
- BIT(dsa_to_port(ds, p)->cpu_dp->index)));
+ (dsa_is_cpu_port(priv->ds, p) ? dsa_user_ports(priv->ds) :
+ BIT(dsa_to_port(priv->ds, p)->cpu_dp->index)));
/* Port Association Vector: when learning source addresses
* of packets, add the address to the address database using
@@ -185,7 +181,7 @@ static int mv88e6060_setup_port(struct dsa_switch *ds, int p)
return 0;
}
-static int mv88e6060_setup_addr(struct dsa_switch *ds)
+static int mv88e6060_setup_addr(struct mv88e6060_priv *priv)
{
u8 addr[ETH_ALEN];
u16 val;
@@ -208,25 +204,28 @@ static int mv88e6060_setup_addr(struct dsa_switch *ds)
static int mv88e6060_setup(struct dsa_switch *ds)
{
+ struct mv88e6060_priv *priv = ds->priv;
int ret;
int i;
- ret = mv88e6060_switch_reset(ds);
+ priv->ds = ds;
+
+ ret = mv88e6060_switch_reset(priv);
if (ret < 0)
return ret;
/* @@@ initialise atu */
- ret = mv88e6060_setup_global(ds);
+ ret = mv88e6060_setup_global(priv);
if (ret < 0)
return ret;
- ret = mv88e6060_setup_addr(ds);
+ ret = mv88e6060_setup_addr(priv);
if (ret < 0)
return ret;
for (i = 0; i < MV88E6060_PORTS; i++) {
- ret = mv88e6060_setup_port(ds, i);
+ ret = mv88e6060_setup_port(priv, i);
if (ret < 0)
return ret;
}
@@ -243,25 +242,27 @@ static int mv88e6060_port_to_phy_addr(int port)
static int mv88e6060_phy_read(struct dsa_switch *ds, int port, int regnum)
{
+ struct mv88e6060_priv *priv = ds->priv;
int addr;
addr = mv88e6060_port_to_phy_addr(port);
if (addr == -1)
return 0xffff;
- return reg_read(ds, addr, regnum);
+ return reg_read(priv, addr, regnum);
}
static int
mv88e6060_phy_write(struct dsa_switch *ds, int port, int regnum, u16 val)
{
+ struct mv88e6060_priv *priv = ds->priv;
int addr;
addr = mv88e6060_port_to_phy_addr(port);
if (addr == -1)
return 0xffff;
- return reg_write(ds, addr, regnum, val);
+ return reg_write(priv, addr, regnum, val);
}
static const struct dsa_switch_ops mv88e6060_switch_ops = {
diff --git a/drivers/net/dsa/mv88e6060.h b/drivers/net/dsa/mv88e6060.h
index 10249bd16292..c0e7a0f2fb6a 100644
--- a/drivers/net/dsa/mv88e6060.h
+++ b/drivers/net/dsa/mv88e6060.h
@@ -117,6 +117,7 @@ struct mv88e6060_priv {
*/
struct mii_bus *bus;
int sw_addr;
+ struct dsa_switch *ds;
};
#endif
--
2.20.1
^ permalink raw reply related
* [PATCH RFC RFT net-next 10/10] bt-bindings: net: DSA: Remove legacy binding
From: Andrew Lunn @ 2019-01-30 0:37 UTC (permalink / raw)
To: netdev; +Cc: Vivien Didelot, Florian Fainelli, Pavel Machek, Andrew Lunn
In-Reply-To: <20190130003758.23852-1-andrew@lunn.ch>
Now that the code to support the legacy binding has been removed,
remove the documentation for it.
Signed-off-by: Andrew Lunn <andrew@lunn.ch>
---
.../devicetree/bindings/net/dsa/dsa.txt | 155 ------------------
1 file changed, 155 deletions(-)
diff --git a/Documentation/devicetree/bindings/net/dsa/dsa.txt b/Documentation/devicetree/bindings/net/dsa/dsa.txt
index 35694c0c376b..a6759824b061 100644
--- a/Documentation/devicetree/bindings/net/dsa/dsa.txt
+++ b/Documentation/devicetree/bindings/net/dsa/dsa.txt
@@ -1,12 +1,6 @@
Distributed Switch Architecture Device Tree Bindings
----------------------------------------------------
-Two bindings exist, one of which has been deprecated due to
-limitations.
-
-Current Binding
----------------
-
Switches are true Linux devices and can be probed by any means. Once
probed, they register to the DSA framework, passing a node
pointer. This node is expected to fulfil the following binding, and
@@ -257,152 +251,3 @@ linked into one DSA cluster.
};
};
};
-
-Deprecated Binding
-------------------
-
-The deprecated binding makes use of a platform device to represent the
-switches. The switches themselves are not Linux devices, and make use
-of an MDIO bus for management.
-
-Required properties:
-- compatible : Should be "marvell,dsa"
-- #address-cells : Must be 2, first cell is the address on the MDIO bus
- and second cell is the address in the switch tree.
- Second cell is used only when cascading/chaining.
-- #size-cells : Must be 0
-- dsa,ethernet : Should be a phandle to a valid Ethernet device node
-- dsa,mii-bus : Should be a phandle to a valid MDIO bus device node
-
-Optional properties:
-- interrupts : property with a value describing the switch
- interrupt number (not supported by the driver)
-
-A DSA node can contain multiple switch chips which are therefore child nodes of
-the parent DSA node. The maximum number of allowed child nodes is 4
-(DSA_MAX_SWITCHES).
-Each of these switch child nodes should have the following required properties:
-
-- reg : Contains two fields. The first one describes the
- address on the MII bus. The second is the switch
- number that must be unique in cascaded configurations
-- #address-cells : Must be 1
-- #size-cells : Must be 0
-
-A switch child node has the following optional property:
-
-- eeprom-length : Set to the length of an EEPROM connected to the
- switch. Must be set if the switch can not detect
- the presence and/or size of a connected EEPROM,
- otherwise optional.
-
-A switch may have multiple "port" children nodes
-
-Each port children node must have the following mandatory properties:
-- reg : Describes the port address in the switch
-- label : Describes the label associated with this port, special
- labels are "cpu" to indicate a CPU port and "dsa" to
- indicate an uplink/downlink port.
-
-Note that a port labelled "dsa" will imply checking for the uplink phandle
-described below.
-
-Optional property:
-- link : Should be a list of phandles to another switch's DSA port.
- This property is only used when switches are being
- chained/cascaded together. This port is used as outgoing port
- towards the phandle port, which can be more than one hop away.
-
-- phy-handle : Phandle to a PHY on an external MDIO bus, not the
- switch internal one. See
- Documentation/devicetree/bindings/net/ethernet.txt
- for details.
-
-- phy-mode : String representing the connection to the designated
- PHY node specified by the 'phy-handle' property. See
- Documentation/devicetree/bindings/net/ethernet.txt
- for details.
-
-- mii-bus : Should be a phandle to a valid MDIO bus device node.
- This mii-bus will be used in preference to the
- global dsa,mii-bus defined above, for this switch.
-
-Optional subnodes:
-- fixed-link : Fixed-link subnode describing a link to a non-MDIO
- managed entity. See
- Documentation/devicetree/bindings/net/fixed-link.txt
- for details.
-
-Example:
-
- dsa@0 {
- compatible = "marvell,dsa";
- #address-cells = <2>;
- #size-cells = <0>;
-
- interrupts = <10>;
- dsa,ethernet = <ðernet0>;
- dsa,mii-bus = <&mii_bus0>;
-
- switch@0 {
- #address-cells = <1>;
- #size-cells = <0>;
- reg = <16 0>; /* MDIO address 16, switch 0 in tree */
-
- port@0 {
- reg = <0>;
- label = "lan1";
- phy-handle = <&phy0>;
- };
-
- port@1 {
- reg = <1>;
- label = "lan2";
- };
-
- port@5 {
- reg = <5>;
- label = "cpu";
- };
-
- switch0port6: port@6 {
- reg = <6>;
- label = "dsa";
- link = <&switch1port0
- &switch2port0>;
- };
- };
-
- switch@1 {
- #address-cells = <1>;
- #size-cells = <0>;
- reg = <17 1>; /* MDIO address 17, switch 1 in tree */
- mii-bus = <&mii_bus1>;
- reset-gpios = <&gpio5 1 GPIO_ACTIVE_LOW>;
-
- switch1port0: port@0 {
- reg = <0>;
- label = "dsa";
- link = <&switch0port6>;
- };
- switch1port1: port@1 {
- reg = <1>;
- label = "dsa";
- link = <&switch2port1>;
- };
- };
-
- switch@2 {
- #address-cells = <1>;
- #size-cells = <0>;
- reg = <18 2>; /* MDIO address 18, switch 2 in tree */
- mii-bus = <&mii_bus1>;
-
- switch2port0: port@0 {
- reg = <0>;
- label = "dsa";
- link = <&switch1port1
- &switch0port6>;
- };
- };
- };
--
2.20.1
^ permalink raw reply related
* [PATCH RFC RFT net-next 01/10] net: dsa: mv88e6xxx: Remove legacy probe support
From: Andrew Lunn @ 2019-01-30 0:37 UTC (permalink / raw)
To: netdev; +Cc: Vivien Didelot, Florian Fainelli, Pavel Machek, Andrew Lunn
In-Reply-To: <20190130003758.23852-1-andrew@lunn.ch>
Remove the legacy method of probing the mv88e6xxx driver, now that all
the mainline boards have been converted to use mdio based probing for
a number of cycles.
Signed-off-by: Andrew Lunn <andrew@lunn.ch>
---
drivers/net/dsa/mv88e6xxx/chip.c | 71 +-------------------------------
1 file changed, 1 insertion(+), 70 deletions(-)
diff --git a/drivers/net/dsa/mv88e6xxx/chip.c b/drivers/net/dsa/mv88e6xxx/chip.c
index 8dca2c949e73..df8d54208c3c 100644
--- a/drivers/net/dsa/mv88e6xxx/chip.c
+++ b/drivers/net/dsa/mv88e6xxx/chip.c
@@ -4587,56 +4587,6 @@ static enum dsa_tag_protocol mv88e6xxx_get_tag_protocol(struct dsa_switch *ds,
return chip->info->tag_protocol;
}
-#if IS_ENABLED(CONFIG_NET_DSA_LEGACY)
-static const char *mv88e6xxx_drv_probe(struct device *dsa_dev,
- struct device *host_dev, int sw_addr,
- void **priv)
-{
- struct mv88e6xxx_chip *chip;
- struct mii_bus *bus;
- int err;
-
- bus = dsa_host_dev_to_mii_bus(host_dev);
- if (!bus)
- return NULL;
-
- chip = mv88e6xxx_alloc_chip(dsa_dev);
- if (!chip)
- return NULL;
-
- /* Legacy SMI probing will only support chips similar to 88E6085 */
- chip->info = &mv88e6xxx_table[MV88E6085];
-
- err = mv88e6xxx_smi_init(chip, bus, sw_addr);
- if (err)
- goto free;
-
- err = mv88e6xxx_detect(chip);
- if (err)
- goto free;
-
- mutex_lock(&chip->reg_lock);
- err = mv88e6xxx_switch_reset(chip);
- mutex_unlock(&chip->reg_lock);
- if (err)
- goto free;
-
- mv88e6xxx_phy_init(chip);
-
- err = mv88e6xxx_mdios_register(chip, NULL);
- if (err)
- goto free;
-
- *priv = chip;
-
- return chip->info->name;
-free:
- devm_kfree(dsa_dev, chip);
-
- return NULL;
-}
-#endif
-
static int mv88e6xxx_port_mdb_prepare(struct dsa_switch *ds, int port,
const struct switchdev_obj_port_mdb *mdb)
{
@@ -4675,9 +4625,6 @@ static int mv88e6xxx_port_mdb_del(struct dsa_switch *ds, int port,
}
static const struct dsa_switch_ops mv88e6xxx_switch_ops = {
-#if IS_ENABLED(CONFIG_NET_DSA_LEGACY)
- .probe = mv88e6xxx_drv_probe,
-#endif
.get_tag_protocol = mv88e6xxx_get_tag_protocol,
.setup = mv88e6xxx_setup,
.adjust_link = mv88e6xxx_adjust_link,
@@ -4722,10 +4669,6 @@ static const struct dsa_switch_ops mv88e6xxx_switch_ops = {
.get_ts_info = mv88e6xxx_get_ts_info,
};
-static struct dsa_switch_driver mv88e6xxx_switch_drv = {
- .ops = &mv88e6xxx_switch_ops,
-};
-
static int mv88e6xxx_register_switch(struct mv88e6xxx_chip *chip)
{
struct device *dev = chip->dev;
@@ -4951,19 +4894,7 @@ static struct mdio_driver mv88e6xxx_driver = {
},
};
-static int __init mv88e6xxx_init(void)
-{
- register_switch_driver(&mv88e6xxx_switch_drv);
- return mdio_driver_register(&mv88e6xxx_driver);
-}
-module_init(mv88e6xxx_init);
-
-static void __exit mv88e6xxx_cleanup(void)
-{
- mdio_driver_unregister(&mv88e6xxx_driver);
- unregister_switch_driver(&mv88e6xxx_switch_drv);
-}
-module_exit(mv88e6xxx_cleanup);
+mdio_module_driver(mv88e6xxx_driver);
MODULE_AUTHOR("Lennert Buytenhek <buytenh@wantstofly.org>");
MODULE_DESCRIPTION("Driver for Marvell 88E6XXX ethernet switch chips");
--
2.20.1
^ permalink raw reply related
* [PATCH RFC RFT net-next 09/10] arch: arm: dts: Remove disabled marvell,dsa properties
From: Andrew Lunn @ 2019-01-30 0:37 UTC (permalink / raw)
To: netdev; +Cc: Vivien Didelot, Florian Fainelli, Pavel Machek, Andrew Lunn
In-Reply-To: <20190130003758.23852-1-andrew@lunn.ch>
These have been disable since the change to probe Marvell Ethernet
switches as MDIO devices. Remove the properties now that the code to
suppport them has also been removed.
Signed-off-by: Andrew Lunn <andrew@lunn.ch>
---
arch/arm/boot/dts/armada-370-rd.dts | 42 --------------
arch/arm/boot/dts/armada-388-clearfog.dts | 58 -------------------
arch/arm/boot/dts/armada-xp-linksys-mamba.dts | 47 ---------------
arch/arm/boot/dts/kirkwood-dir665.dts | 47 ---------------
arch/arm/boot/dts/kirkwood-linksys-viper.dts | 47 ---------------
.../arm/boot/dts/kirkwood-mv88f6281gtw-ge.dts | 47 ---------------
arch/arm/boot/dts/kirkwood-rd88f6281.dtsi | 41 -------------
7 files changed, 329 deletions(-)
diff --git a/arch/arm/boot/dts/armada-370-rd.dts b/arch/arm/boot/dts/armada-370-rd.dts
index 2bfb3108b5b2..c910d157a686 100644
--- a/arch/arm/boot/dts/armada-370-rd.dts
+++ b/arch/arm/boot/dts/armada-370-rd.dts
@@ -114,48 +114,6 @@
};
};
};
-
- dsa {
- status = "disabled";
-
- compatible = "marvell,dsa";
- #address-cells = <2>;
- #size-cells = <0>;
-
- dsa,ethernet = <ð1>;
- dsa,mii-bus = <&mdio>;
-
- switch@0 {
- #address-cells = <1>;
- #size-cells = <0>;
- reg = <0x10 0>; /* MDIO address 16, switch 0 in tree */
-
- port@0 {
- reg = <0>;
- label = "lan0";
- };
-
- port@1 {
- reg = <1>;
- label = "lan1";
- };
-
- port@2 {
- reg = <2>;
- label = "lan2";
- };
-
- port@3 {
- reg = <3>;
- label = "lan3";
- };
-
- port@5 {
- reg = <5>;
- label = "cpu";
- };
- };
- };
};
&pciec {
diff --git a/arch/arm/boot/dts/armada-388-clearfog.dts b/arch/arm/boot/dts/armada-388-clearfog.dts
index 89a354b43978..20f8d4667753 100644
--- a/arch/arm/boot/dts/armada-388-clearfog.dts
+++ b/arch/arm/boot/dts/armada-388-clearfog.dts
@@ -30,64 +30,6 @@
};
};
- dsa@0 {
- status = "disabled";
-
- compatible = "marvell,dsa";
- dsa,ethernet = <ð1>;
- dsa,mii-bus = <&mdio>;
- pinctrl-0 = <&clearfog_dsa0_clk_pins &clearfog_dsa0_pins>;
- pinctrl-names = "default";
- #address-cells = <2>;
- #size-cells = <0>;
-
- switch@0 {
- #address-cells = <1>;
- #size-cells = <0>;
- reg = <4 0>;
-
- port@0 {
- reg = <0>;
- label = "lan5";
- };
-
- port@1 {
- reg = <1>;
- label = "lan4";
- };
-
- port@2 {
- reg = <2>;
- label = "lan3";
- };
-
- port@3 {
- reg = <3>;
- label = "lan2";
- };
-
- port@4 {
- reg = <4>;
- label = "lan1";
- };
-
- port@5 {
- reg = <5>;
- label = "cpu";
- };
-
- port@6 {
- /* 88E1512 external phy */
- reg = <6>;
- label = "lan6";
- fixed-link {
- speed = <1000>;
- full-duplex;
- };
- };
- };
- };
-
gpio-keys {
compatible = "gpio-keys";
pinctrl-0 = <&rear_button_pins>;
diff --git a/arch/arm/boot/dts/armada-xp-linksys-mamba.dts b/arch/arm/boot/dts/armada-xp-linksys-mamba.dts
index 7a2606c3b62e..8480a16919a0 100644
--- a/arch/arm/boot/dts/armada-xp-linksys-mamba.dts
+++ b/arch/arm/boot/dts/armada-xp-linksys-mamba.dts
@@ -210,53 +210,6 @@
compatible = "pwm-fan";
pwms = <&gpio0 24 4000>;
};
-
- dsa {
- status = "disabled";
-
- compatible = "marvell,dsa";
- #address-cells = <2>;
- #size-cells = <0>;
-
- dsa,ethernet = <ð0>;
- dsa,mii-bus = <&mdio>;
-
- switch@0 {
- #address-cells = <1>;
- #size-cells = <0>;
- reg = <0x0 0>; /* MDIO address 0, switch 0 in tree */
-
- port@0 {
- reg = <0>;
- label = "lan4";
- };
-
- port@1 {
- reg = <1>;
- label = "lan3";
- };
-
- port@2 {
- reg = <2>;
- label = "lan2";
- };
-
- port@3 {
- reg = <3>;
- label = "lan1";
- };
-
- port@4 {
- reg = <4>;
- label = "internet";
- };
-
- port@5 {
- reg = <5>;
- label = "cpu";
- };
- };
- };
};
&pciec {
diff --git a/arch/arm/boot/dts/kirkwood-dir665.dts b/arch/arm/boot/dts/kirkwood-dir665.dts
index 31ceacd841de..b3ad3f607d31 100644
--- a/arch/arm/boot/dts/kirkwood-dir665.dts
+++ b/arch/arm/boot/dts/kirkwood-dir665.dts
@@ -190,53 +190,6 @@
gpios = <&gpio1 14 GPIO_ACTIVE_LOW>;
};
};
-
- dsa {
- status = "disabled";
-
- compatible = "marvell,dsa";
- #address-cells = <2>;
- #size-cells = <0>;
-
- dsa,ethernet = <ð0port>;
- dsa,mii-bus = <&mdio>;
-
- switch@0 {
- #address-cells = <1>;
- #size-cells = <0>;
- reg = <0 0>; /* MDIO address 0, switch 0 in tree */
-
- port@0 {
- reg = <0>;
- label = "lan4";
- };
-
- port@1 {
- reg = <1>;
- label = "lan3";
- };
-
- port@2 {
- reg = <2>;
- label = "lan2";
- };
-
- port@3 {
- reg = <3>;
- label = "lan1";
- };
-
- port@4 {
- reg = <4>;
- label = "wan";
- };
-
- port@6 {
- reg = <6>;
- label = "cpu";
- };
- };
- };
};
&mdio {
diff --git a/arch/arm/boot/dts/kirkwood-linksys-viper.dts b/arch/arm/boot/dts/kirkwood-linksys-viper.dts
index a7d659b7145a..2f9660f3b457 100644
--- a/arch/arm/boot/dts/kirkwood-linksys-viper.dts
+++ b/arch/arm/boot/dts/kirkwood-linksys-viper.dts
@@ -66,53 +66,6 @@
gpios = <&gpio0 14 GPIO_ACTIVE_HIGH>;
};
};
-
- dsa {
- status = "disabled";
-
- compatible = "marvell,dsa";
- #address-cells = <2>;
- #size-cells = <0>;
-
- dsa,ethernet = <ð0port>;
- dsa,mii-bus = <&mdio>;
-
- switch@16,0 {
- #address-cells = <1>;
- #size-cells = <0>;
- reg = <16 0>; /* MDIO address 16, switch 0 in tree */
-
- port@0 {
- reg = <0>;
- label = "ethernet1";
- };
-
- port@1 {
- reg = <1>;
- label = "ethernet2";
- };
-
- port@2 {
- reg = <2>;
- label = "ethernet3";
- };
-
- port@3 {
- reg = <3>;
- label = "ethernet4";
- };
-
- port@4 {
- reg = <4>;
- label = "internet";
- };
-
- port@5 {
- reg = <5>;
- label = "cpu";
- };
- };
- };
};
&pinctrl {
diff --git a/arch/arm/boot/dts/kirkwood-mv88f6281gtw-ge.dts b/arch/arm/boot/dts/kirkwood-mv88f6281gtw-ge.dts
index 86d532916d56..2e1a75348908 100644
--- a/arch/arm/boot/dts/kirkwood-mv88f6281gtw-ge.dts
+++ b/arch/arm/boot/dts/kirkwood-mv88f6281gtw-ge.dts
@@ -107,53 +107,6 @@
gpios = <&gpio1 14 GPIO_ACTIVE_LOW>;
};
};
-
- dsa {
- status = "disabled";
-
- compatible = "marvell,dsa";
- #address-cells = <1>;
- #size-cells = <0>;
-
- dsa,ethernet = <ð0port>;
- dsa,mii-bus = <&mdio>;
-
- switch@0 {
- #address-cells = <1>;
- #size-cells = <0>;
- reg = <0 0>; /* MDIO address 0, switch 0 in tree */
-
- port@0 {
- reg = <0>;
- label = "lan1";
- };
-
- port@1 {
- reg = <1>;
- label = "lan2";
- };
-
- port@2 {
- reg = <2>;
- label = "lan3";
- };
-
- port@3 {
- reg = <3>;
- label = "lan4";
- };
-
- port@4 {
- reg = <4>;
- label = "wan";
- };
-
- port@5 {
- reg = <5>;
- label = "cpu";
- };
- };
- };
};
&mdio {
diff --git a/arch/arm/boot/dts/kirkwood-rd88f6281.dtsi b/arch/arm/boot/dts/kirkwood-rd88f6281.dtsi
index 0f22f0e6f56b..f1f8eee132e8 100644
--- a/arch/arm/boot/dts/kirkwood-rd88f6281.dtsi
+++ b/arch/arm/boot/dts/kirkwood-rd88f6281.dtsi
@@ -48,47 +48,6 @@
cd-gpios = <&gpio0 28 GPIO_ACTIVE_HIGH>;
/* No WP GPIO */
};
- };
-
- dsa {
- status = "disabled";
-
- compatible = "marvell,dsa";
- #address-cells = <2>;
- #size-cells = <0>;
-
- dsa,ethernet = <ð0port>;
- dsa,mii-bus = <&mdio>;
-
- switch@0 {
- #address-cells = <1>;
- #size-cells = <0>;
-
- port@0 {
- reg = <0>;
- label = "lan1";
- };
-
- port@1 {
- reg = <1>;
- label = "lan2";
- };
-
- port@2 {
- reg = <2>;
- label = "lan3";
- };
-
- port@3 {
- reg = <3>;
- label = "lan4";
- };
-
- port@5 {
- reg = <5>;
- label = "cpu";
- };
- };
};
};
--
2.20.1
^ permalink raw reply related
* [PATCH RFC RFT net-next 00/10] Modernize mv88e6060 and remove legacy probe
From: Andrew Lunn @ 2019-01-30 0:37 UTC (permalink / raw)
To: netdev; +Cc: Vivien Didelot, Florian Fainelli, Pavel Machek, Andrew Lunn
The mv88e6060 is the last device using the legacy method of probing an
DSA Ethernet switch. This patchset applies some cleanups to the
driver, and then adds support for probing the device as an MDIO bus
device. The legacy probe is then removed from the driver, and then
from DSA as a whole.
This is compile tested only. Comment and testing welcome.
It should not be merged yet, and one of the patches should go via
arm-soc.
Andrew Lunn (10):
net: dsa: mv88e6xxx: Remove legacy probe support
net: dsa: mv88e6060: Replace ds with priv
net: dsa: mv88e6060: Replace REG_WRITE macro
net: dsa: mv88e6060: Replace REG_READ macro
net: dsa: mv88e6060: Support probing as an mdio device
net: dsa: mv88e6060: Remove support for legacy probing
net: dsa: mv88e6060: Add SPDX header
net: dsa: Remove legacy probing support
arch: arm: dts: Remove disabled marvell,dsa properties
bt-bindings: net: DSA: Remove legacy binding
.../devicetree/bindings/net/dsa/dsa.txt | 155 ----
arch/arm/boot/dts/armada-370-rd.dts | 42 -
arch/arm/boot/dts/armada-388-clearfog.dts | 58 --
arch/arm/boot/dts/armada-xp-linksys-mamba.dts | 47 --
arch/arm/boot/dts/kirkwood-dir665.dts | 47 --
arch/arm/boot/dts/kirkwood-linksys-viper.dts | 47 --
.../arm/boot/dts/kirkwood-mv88f6281gtw-ge.dts | 47 --
arch/arm/boot/dts/kirkwood-rd88f6281.dtsi | 41 -
drivers/net/dsa/Kconfig | 2 +-
drivers/net/dsa/mv88e6060.c | 217 ++---
drivers/net/dsa/mv88e6060.h | 1 +
drivers/net/dsa/mv88e6xxx/chip.c | 71 +-
include/net/dsa.h | 23 -
net/dsa/Kconfig | 9 -
net/dsa/Makefile | 1 -
net/dsa/dsa.c | 5 -
net/dsa/dsa_priv.h | 12 -
net/dsa/legacy.c | 745 ------------------
18 files changed, 121 insertions(+), 1449 deletions(-)
--
2.20.1
^ permalink raw reply
* [PATCH bpf 0/2] bpf: btf: allow typedef func_proto
From: Yonghong Song @ 2019-01-30 0:38 UTC (permalink / raw)
To: netdev; +Cc: Alexei Starovoitov, Daniel Borkmann, kernel-team, Yonghong Song
The current btf implementation disallows the typedef of
a func_proto type. This actually is allowed per C standard.
This patch fixed btf verification to permit such types.
Patch #1 fixed the kernel side and Patch #2 fixed
the tools test_btf test.
Yonghong Song (2):
bpf: btf: allow typedef func_proto
tools/bpf: fix test_btf for typedef func_proto case
kernel/bpf/btf.c | 3 ++-
tools/testing/selftests/bpf/test_btf.c | 9 +++------
2 files changed, 5 insertions(+), 7 deletions(-)
--
2.17.1
^ permalink raw reply
* [PATCH bpf 2/2] tools/bpf: fix test_btf for typedef func_proto case
From: Yonghong Song @ 2019-01-30 0:38 UTC (permalink / raw)
To: netdev; +Cc: Alexei Starovoitov, Daniel Borkmann, kernel-team, Yonghong Song
In-Reply-To: <20190130003816.1043826-1-yhs@fb.com>
Fixed one test_btf raw test such that typedef func_proto
is permitted now.
Fixes: 78a2540e8945 ("tools/bpf: Add tests for BTF_KIND_FUNC_PROTO and BTF_KIND_FUNC")
Acked-by: Martin KaFai Lau <kafai@fb.com>
Signed-off-by: Yonghong Song <yhs@fb.com>
---
tools/testing/selftests/bpf/test_btf.c | 9 +++------
1 file changed, 3 insertions(+), 6 deletions(-)
diff --git a/tools/testing/selftests/bpf/test_btf.c b/tools/testing/selftests/bpf/test_btf.c
index a0bd04befe87..91420fa83b08 100644
--- a/tools/testing/selftests/bpf/test_btf.c
+++ b/tools/testing/selftests/bpf/test_btf.c
@@ -1881,13 +1881,12 @@ static struct btf_raw_test raw_tests[] = {
},
{
- .descr = "func proto (CONST=>TYPEDEF=>FUNC_PROTO)",
+ .descr = "func proto (TYPEDEF=>FUNC_PROTO)",
.raw_types = {
BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4), /* [1] */
BTF_TYPE_INT_ENC(0, 0, 0, 32, 4), /* [2] */
- BTF_CONST_ENC(4), /* [3] */
- BTF_TYPEDEF_ENC(NAME_TBD, 5), /* [4] */
- BTF_FUNC_PROTO_ENC(0, 2), /* [5] */
+ BTF_TYPEDEF_ENC(NAME_TBD, 4), /* [3] */
+ BTF_FUNC_PROTO_ENC(0, 2), /* [4] */
BTF_FUNC_PROTO_ARG_ENC(0, 1),
BTF_FUNC_PROTO_ARG_ENC(0, 2),
BTF_END_RAW,
@@ -1901,8 +1900,6 @@ static struct btf_raw_test raw_tests[] = {
.key_type_id = 1,
.value_type_id = 1,
.max_entries = 4,
- .btf_load_err = true,
- .err_str = "Invalid type_id",
},
{
--
2.17.1
^ permalink raw reply related
* [PATCH bpf 1/2] bpf: btf: allow typedef func_proto
From: Yonghong Song @ 2019-01-30 0:38 UTC (permalink / raw)
To: netdev; +Cc: Alexei Starovoitov, Daniel Borkmann, kernel-team, Yonghong Song
In-Reply-To: <20190130003816.1043826-1-yhs@fb.com>
Current implementation does not allow typedef func_proto.
But it is actually allowed.
-bash-4.4$ cat t.c
typedef int (f) (int);
f *g;
-bash-4.4$ clang -O2 -g -c -target bpf t.c -Xclang -target-feature -Xclang +dwarfris
-bash-4.4$ pahole -JV t.o
File t.o:
[1] PTR (anon) type_id=2
[2] TYPEDEF f type_id=3
[3] FUNC_PROTO (anon) return=4 args=(4 (anon))
[4] INT int size=4 bit_offset=0 nr_bits=32 encoding=SIGNED
-bash-4.4$
This patch related btf verifier to allow such (typedef func_proto)
patterns.
Fixes: 2667a2626f4d ("bpf: btf: Add BTF_KIND_FUNC and BTF_KIND_FUNC_PROTO")
Acked-by: Martin KaFai Lau <kafai@fb.com>
Signed-off-by: Yonghong Song <yhs@fb.com>
---
kernel/bpf/btf.c | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/kernel/bpf/btf.c b/kernel/bpf/btf.c
index befe570be5ba..c57bd10340ed 100644
--- a/kernel/bpf/btf.c
+++ b/kernel/bpf/btf.c
@@ -1459,7 +1459,8 @@ static int btf_modifier_resolve(struct btf_verifier_env *env,
/* "typedef void new_void", "const void"...etc */
if (!btf_type_is_void(next_type) &&
- !btf_type_is_fwd(next_type)) {
+ !btf_type_is_fwd(next_type) &&
+ !btf_type_is_func_proto(next_type)) {
btf_verifier_log_type(env, v->t, "Invalid type_id");
return -EINVAL;
}
--
2.17.1
^ permalink raw reply related
* Are your photos ready for retouching?
From: Mindy @ 2019-01-29 10:11 UTC (permalink / raw)
To: netdev
Are your photos ready for retouching? We are waiting to start working for
you soon.
No matter making white background or adding path to your pictures, we can
do it quickly for you.
We can do test on your current photos, please send some to start.
Thanks,
Mindy
^ permalink raw reply
* (Basic Greenhorn Q) add ethernet access point 130 feet away
From: Harry Putnam @ 2019-01-29 23:28 UTC (permalink / raw)
To: netdev
Sorry about the greenhorn question.
When I got to thinking about doing this, I realized that I really
wasn't sure I knew how. My googling has failed to turn up a
definitive answer... never clear if what is talked about is the same
as what I want to do. Probably due to my inexperience with the lingo
of and networking in general
My current network:
INTERNET
|
house
|
comcast modem router
|
|
Personal home router (TP-link AC1750) with wifi for the house
|
------- ------- ---=--- ------- -------
( yet to be added)
What I plan to do below is lay a 14 inch deep narrow trench to
garage, then run an 1 1/2 inch pvc pipe to garage for housing the
ethernet line to garage..
------- ------- ---=--- ------- -------
|
130 feet of underground Cat7 or cat6a ethernet wire (underground)
|
Garage
|
router w/ wifi ( used as access point)
|
Hosts on a Different subnet
So, the question is: Can I use most any router (with wifi) at the
garage end by just plugging 130 feet of ethernet into the TP-link 1750
in the house and some (as yet unspecified piece of) equip in the Garage
and thereby establish both ethernet and wifi service in the Garage on
a different subnet?
Or do I need some specific piece of equipment at the garage end? If
not: can anyone suggest what to use.
I'm not averse to buying a new piece of equip for this.
^ permalink raw reply
* Re: [PATCH net] vhost: fix OOB in get_rx_bufs()
From: David Miller @ 2019-01-29 23:38 UTC (permalink / raw)
To: mst; +Cc: jasowang, stefanha, kvm, virtualization, netdev, linux-kernel
In-Reply-To: <20190129.151026.358327408932275252.davem@davemloft.net>
From: David Miller <davem@davemloft.net>
Date: Tue, 29 Jan 2019 15:10:26 -0800 (PST)
> Yeah the CVE pushed my hand a little bit, and I knew I was going to
> send Linus a pull request today because David Watson needs some TLS
> changes in net-next.
I also want to make a general comment.... for the record.
If I let patches slip consistently past 24 hours my backlog is
unmanageable. Even with aggressively applying things quickly I'm
right now at 70-75. If I do not do what I am doing, then it's in the
100-150 range.
So I am at the point where I often must move forward with patches that
I think I personally can verify and vet on my own.
^ permalink raw reply
* Re: [PATCH] ucc_geth: Reset BQL queue when stopping device
From: David Miller @ 2019-01-29 23:33 UTC (permalink / raw)
To: Mathias.Thore
Cc: leoyang.li, christophe.leroy, netdev, linuxppc-dev,
David.Gounaris, Joakim.Tjernlund
In-Reply-To: <DM6PR10MB3721D7BA109A3823D9DACF1984970@DM6PR10MB3721.namprd10.prod.outlook.com>
From: Mathias Thore <Mathias.Thore@infinera.com>
Date: Tue, 29 Jan 2019 08:07:54 +0000
> Is there a scenario where we are clearing the TX ring but don't want to reset the BQL TX queue?
>
> I think it makes sense to keep it in ucc_geth_free_tx since the
> reason it is needed isn't the timeout per se, but rather the
> clearing of the TX ring. This way, it will be performed no matter
> why the driver ends up calling this function.
I absolutely think the BQL reset should remain in ucc_geth_free_tx().
That way if another callsite for ucc_geth_free_tx() emerges that does
need the BQL queue reset, it won't be "forgotten".
^ permalink raw reply
* Re: mv88e6xxx -- DSA support for Marvell 88e6065 switch (and maybe 88e6060?)
From: Vivien Didelot @ 2019-01-29 23:21 UTC (permalink / raw)
To: Pavel Machek; +Cc: Andrew Lunn, netdev, f.fainelli, buytenh, buytenh, nico
In-Reply-To: <20190129225732.GA11686@amd>
Hi Pavel,
On Tue, 29 Jan 2019 23:57:32 +0100, Pavel Machek <pavel@ucw.cz> wrote:
> Ok, so I took a long look at mv88e6xxx... and got it to work.
>
> Good news is that modifications needed are not too heavy. Most are
> inlined below. (tag_daddr is still needed. I can send that too).
>
> Bad news is that only about half of all the registers are present on
> 6065 (6060 is similar), and I'm not sure how to do that
> cleanly. Anything marked "W" is not present or reserved or different
> in 6065. What would be good markup of registers that are common to all
> and that are newer-generations-only be? Mark everything not present on
> 6065 as MV88E6085_*?
>
> Is someone is interested in getting 6060 to work with mv88e6xxx?
I am currently trying to request boards with an 88E6060 so that we can
finally get rid of the legacy code used by the mv88e6060 driver.
I think the 6065 has similar registers layout than the 6060. If so, it would
be simpler for you to add the 6065 support into the mv88e6060 driver.
Merging mv88e6060 into mv88e6xxx is the next step I have on my plate after
removing legacy.
Are you using the legacy binding with mv88e6xxx or the new ones? If you're
using the new ones, Andrew may have a patch to convert the mv88e6060 driver
to use the new bindings, that you could apply and test first. Then you can
add support for 88E6065 in the mv88e6060 driver more easily.
Thanks,
Vivien
^ permalink raw reply
* Re: mv88e6xxx -- DSA support for Marvell 88e6065 switch (and maybe 88e6060?)
From: Andrew Lunn @ 2019-01-29 23:12 UTC (permalink / raw)
To: Pavel Machek; +Cc: netdev, f.fainelli, buytenh, buytenh, nico
In-Reply-To: <20190129225732.GA11686@amd>
> Is someone is interested in getting 6060 to work with mv88e6xxx?
Vivien is.
I also have a set of patches which modernize the driver. That might be
a step towards merging it in.
> @@ -2126,6 +2146,7 @@ static int mv88e6xxx_setup_egress_floods(struct mv88e6xxx_chip *chip, int port)
>
> /* Upstream ports flood frames with unknown unicast or multicast DA */
> flood = dsa_is_cpu_port(ds, port) || dsa_is_dsa_port(ds, port);
> + flood = 1; /* This is strange, but original driver also sets flood everywhere */
This might be because the driver did not support hardware offload.
What happens if you don't have this?
> +static const struct mv88e6xxx_ops mv88e6065_ops = {
> + /* MV88E6XXX_FAMILY_6095 */ /* Here */
> + //.ieee_pri_map = mv88e6085_g1_ieee_pri_map, /* FIXME */
> + // .ip_pri_map = mv88e6085_g1_ip_pri_map, /* FIXME */
> + // .set_switch_mac = mv88e6xxx_g1_set_switch_mac, /* FIXME */
What you should do is see if the hardware supports these functions. If
it does not, simply leave it out of mv88e6065_ops. If it does have the
functionality, but needs a new implementation, add a mv88e6065_
version. In theory, nearly everything is optional. So you can start
simple and then add features.
Andrew
^ permalink raw reply
* Re: [PATCH net] vhost: fix OOB in get_rx_bufs()
From: David Miller @ 2019-01-29 23:10 UTC (permalink / raw)
To: mst; +Cc: jasowang, stefanha, kvm, virtualization, netdev, linux-kernel
In-Reply-To: <20190129175145-mutt-send-email-mst@kernel.org>
From: "Michael S. Tsirkin" <mst@redhat.com>
Date: Tue, 29 Jan 2019 17:54:44 -0500
> On Mon, Jan 28, 2019 at 10:54:44PM -0800, David Miller wrote:
>> From: Jason Wang <jasowang@redhat.com>
>> Date: Mon, 28 Jan 2019 15:05:05 +0800
>>
>> > After batched used ring updating was introduced in commit e2b3b35eb989
>> > ("vhost_net: batch used ring update in rx"). We tend to batch heads in
>> > vq->heads for more than one packet. But the quota passed to
>> > get_rx_bufs() was not correctly limited, which can result a OOB write
>> > in vq->heads.
>> >
>> > headcount = get_rx_bufs(vq, vq->heads + nvq->done_idx,
>> > vhost_len, &in, vq_log, &log,
>> > likely(mergeable) ? UIO_MAXIOV : 1);
>> >
>> > UIO_MAXIOV was still used which is wrong since we could have batched
>> > used in vq->heads, this will cause OOB if the next buffer needs more
>> > than 960 (1024 (UIO_MAXIOV) - 64 (VHOST_NET_BATCH)) heads after we've
>> > batched 64 (VHOST_NET_BATCH) heads:
>> ...
>> > Fixing this by allocating UIO_MAXIOV + VHOST_NET_BATCH iovs for
>> > vhost-net. This is done through set the limitation through
>> > vhost_dev_init(), then set_owner can allocate the number of iov in a
>> > per device manner.
>> >
>> > This fixes CVE-2018-16880.
>> >
>> > Fixes: e2b3b35eb989 ("vhost_net: batch used ring update in rx")
>> > Signed-off-by: Jason Wang <jasowang@redhat.com>
>>
>> Applied and queued up for -stable, thanks!
>
> Wow it seems we are down to hours round time post to queue.
> It would be hard to keep up that rate generally.
> However, I am guessing this was already in downstreams, and it's a CVE,
> so I guess it's a no brainer and review wasn't really necessary - was
> that the idea? Just checking.
Yeah the CVE pushed my hand a little bit, and I knew I was going to send Linus
a pull request today because David Watson needs some TLS changes in net-next.
^ permalink raw reply
* mv88e6xxx -- DSA support for Marvell 88e6065 switch (and maybe 88e6060?)
From: Pavel Machek @ 2019-01-29 22:57 UTC (permalink / raw)
To: Andrew Lunn; +Cc: netdev, f.fainelli, buytenh, buytenh, nico
In-Reply-To: <20181118182053.GE7446@lunn.ch>
[-- Attachment #1.1: Type: text/plain, Size: 8160 bytes --]
Hi!
> > > > I'm trying to create support for Marvell 88e6065 switch... and it
> > > > seems like drivers/net/dsa supports everything, but this model.
> > > >
> > > > Did someone work with this hardware before? Any idea if it would be
> > > > more suitable to support by existing 88e6060 code, or if 88e6xxx code
> > > > should serve as a base?
> > >
> > > Hi Pavel
> > >
> > > The 88e6xxx should be extended to support this. I think you will find
> > > a lot of the building blocks are already in the driver. Compare the
> > > various implementations of the functions in the mv88e6xxx_ops to what
> > > the datasheet says for the registers, and pick those that match.
> >
> > Ok, so I played a bit.
> >
> > It looks like e6065 has different register layout from those supported
> > by 6xxx, and is quite similar to e6060.
>
> However, if you look in the mv88e6xxx, there are quite a few functions
> called mv88e6065_foo. Marvell keeps changing the register layout. When
> writing code, we try to name the functions based on which family of
> devices introduced those registers. But we don't have the whole
> history, so we probably have some names wrong.
Ok, so I took a long look at mv88e6xxx... and got it to work.
Good news is that modifications needed are not too heavy. Most are
inlined below. (tag_daddr is still needed. I can send that too).
Bad news is that only about half of all the registers are present on
6065 (6060 is similar), and I'm not sure how to do that
cleanly. Anything marked "W" is not present or reserved or different
in 6065. What would be good markup of registers that are common to all
and that are newer-generations-only be? Mark everything not present on
6065 as MV88E6085_*?
Is someone is interested in getting 6060 to work with mv88e6xxx?
Best regards,
Pavel
commit b0a8ed2459b8bc1922441edb482d0c7a4217eb1f
Author: Pavel Machek <pavel@denx.de>
Date: Mon Jan 28 15:12:30 2019 +0100
6xxx: Add basic support for 6065.
diff --git a/drivers/net/dsa/mv88e6xxx/chip.c b/drivers/net/dsa/mv88e6xxx/chip.c
index 33e99dfa00a8..0a1fc2432094 100644
--- a/drivers/net/dsa/mv88e6xxx/chip.c
+++ b/drivers/net/dsa/mv88e6xxx/chip.c
@@ -2094,6 +2094,21 @@ static int mv88e6xxx_set_port_mode_edsa(struct mv88e6xxx_chip *chip, int port)
ETH_P_EDSA);
}
+static int mv88e6xxx_set_port_mode_header(struct mv88e6xxx_chip *chip, int port)
+{
+ u16 reg;
+ int err;
+
+ err = mv88e6xxx_port_read(chip, port, MV88E6XXX_PORT_CTL0, ®);
+ if (err)
+ return err;
+
+ reg |= MV88E6XXX_PORT_CTL0_HEADER;
+ printk("port %d -- enabling header, val %lx\n", port, (unsigned long) reg);
+
+ return mv88e6xxx_port_write(chip, port, MV88E6XXX_PORT_CTL0, reg);
+}
+
static int mv88e6xxx_setup_port_mode(struct mv88e6xxx_chip *chip, int port)
{
if (dsa_is_dsa_port(chip->ds, port))
@@ -2109,6 +2124,11 @@ static int mv88e6xxx_setup_port_mode(struct mv88e6xxx_chip *chip, int port)
if (chip->info->tag_protocol == DSA_TAG_PROTO_EDSA)
return mv88e6xxx_set_port_mode_edsa(chip, port);
+ if (chip->info->tag_protocol == DSA_TAG_PROTO_DADDR)
+ return mv88e6xxx_set_port_mode_header(chip, port);
+
+ dev_warn(chip->dev, "set port mode failed");
+
return -EINVAL;
}
@@ -2126,6 +2146,7 @@ static int mv88e6xxx_setup_egress_floods(struct mv88e6xxx_chip *chip, int port)
/* Upstream ports flood frames with unknown unicast or multicast DA */
flood = dsa_is_cpu_port(ds, port) || dsa_is_dsa_port(ds, port);
+ flood = 1; /* This is strange, but original driver also sets flood everywhere */
if (chip->info->ops->port_set_egress_floods)
return chip->info->ops->port_set_egress_floods(chip, port,
flood, flood);
@@ -3777,7 +3798,58 @@ static const struct mv88e6xxx_ops mv88e6390x_ops = {
.phylink_validate = mv88e6390x_phylink_validate,
};
+static const struct mv88e6xxx_ops mv88e6065_ops = {
+ /* MV88E6XXX_FAMILY_6095 */ /* Here */
+ //.ieee_pri_map = mv88e6085_g1_ieee_pri_map, /* FIXME */
+ // .ip_pri_map = mv88e6085_g1_ip_pri_map, /* FIXME */
+ // .set_switch_mac = mv88e6xxx_g1_set_switch_mac, /* FIXME */
+ .phy_read = mv88e6185_phy_ppu_read,
+ .phy_write = mv88e6185_phy_ppu_write,
+ .port_set_link = mv88e6xxx_port_set_link, /* ok */
+ .port_set_duplex = mv88e6xxx_port_set_duplex, /* ok */
+ .port_set_speed = mv88e6065_port_set_speed, /* ok */
+ .port_set_frame_mode = mv88e6065_port_set_frame_mode, // -- definitely not compatible on 6065; neccessary for correct operation? */
+ .port_set_egress_floods = mv88e6352_port_set_egress_floods, /* ok */
+ //.port_set_upstream_port = mv88e6095_port_set_upstream_port, /* FIXME */
+ .port_link_state = mv88e6352_port_link_state, /* FIXME -- this one is wrong, 6065 uses dufferebt bits */
+ //.port_get_cmode = mv88e6185_port_get_cmode, /* FIXME -- wrong bits */
+ //.stats_snapshot = mv88e6xxx_g1_stats_snapshot, /* FIXME */
+ //.stats_set_histogram = mv88e6095_g1_stats_set_histogram, /* FIXME */
+ //.stats_get_sset_count = mv88e6095_stats_get_sset_count, /* FIXME */
+ //.stats_get_strings = mv88e6095_stats_get_strings, /* FIXME */
+ //.stats_get_stats = mv88e6095_stats_get_stats, /* FIXME */
+ //.mgmt_rsvd2cpu = mv88e6185_g2_mgmt_rsvd2cpu, /* FIXME */
+ //.ppu_enable = mv88e6185_g1_ppu_enable, /* FIXME */
+ //.ppu_disable = mv88e6185_g1_ppu_disable, /* FIXME */
+ .reset = NULL, /* No reset bit in global1: register 4, but we have MV88E6065_G1_RESET */
+ .vtu_getnext = mv88e6185_g1_vtu_getnext, /* ok? */
+ .vtu_loadpurge = mv88e6185_g1_vtu_loadpurge, /* FIXME */
+ .phylink_validate = mv88e6065_phylink_validate,
+};
+
static const struct mv88e6xxx_info mv88e6xxx_table[] = {
+ [MV88E6065] = {
+ .prod_num = 0x650,
+ .family = MV88E6XXX_FAMILY_6065,
+ .name = "Marvell 88E6065 not so hacked :-)",
+ .num_databases = 16,
+ .num_ports = 6,
+ .num_internal_phys = 6,
+ .max_vid = 4095,
+ .port_base_addr = 0x18,
+ .phy_base_addr = 0x10,
+ .global1_addr = 0x1f,
+ .global2_addr = 0,
+ .age_time_coeff = 15000,
+ .g1_irqs = 8,
+ .g2_irqs = 0,
+ .atu_move_port_mask = 0xf,
+ .pvt = false,
+ .multi_chip = true,
+ .tag_protocol = DSA_TAG_PROTO_DADDR,
+ .ops = &mv88e6065_ops,
+ },
+
[MV88E6085] = {
.prod_num = MV88E6XXX_PORT_SWITCH_ID_PROD_6085,
.family = MV88E6XXX_FAMILY_6097,
diff --git a/drivers/net/dsa/mv88e6xxx/chip.h b/drivers/net/dsa/mv88e6xxx/chip.h
index fc82085d4296..7d6c746d4b66 100644
--- a/drivers/net/dsa/mv88e6xxx/chip.h
+++ b/drivers/net/dsa/mv88e6xxx/chip.h
@@ -57,10 +57,12 @@ enum mv88e6xxx_frame_mode {
MV88E6XXX_FRAME_MODE_DSA,
MV88E6XXX_FRAME_MODE_PROVIDER,
MV88E6XXX_FRAME_MODE_ETHERTYPE,
+ MV88E6XXX_FRAME_MODE_HEADER,
};
/* List of supported models */
enum mv88e6xxx_model {
+ MV88E6065,
MV88E6085,
MV88E6095,
MV88E6097,
diff --git a/drivers/net/dsa/mv88e6xxx/port.c b/drivers/net/dsa/mv88e6xxx/port.c
index 3f43c231f40b..cfa16b5fd41a 100644
--- a/drivers/net/dsa/mv88e6xxx/port.c
+++ b/drivers/net/dsa/mv88e6xxx/port.c
@@ -631,6 +631,31 @@ int mv88e6xxx_port_set_egress_mode(struct mv88e6xxx_chip *chip, int port,
return mv88e6xxx_port_write(chip, port, MV88E6XXX_PORT_CTL0, reg);
}
+int mv88e6065_port_set_frame_mode(struct mv88e6xxx_chip *chip, int port,
+ enum mv88e6xxx_frame_mode mode)
+{
+ int err;
+ u16 reg;
+
+ err = mv88e6xxx_port_read(chip, port, MV88E6XXX_PORT_CTL0, ®);
+ if (err)
+ return err;
+
+ reg &= ~MV88E6XXX_PORT_CTL0_FRAME_MODE_MASK;
+
+ switch (mode) {
+ case MV88E6XXX_FRAME_MODE_NORMAL:
+ /* FIXME ... ? why is it needed */
+ reg |= MV88E6XXX_PORT_CTL0_FRAME_MODE_NORMAL;
+ break;
+ default:
+ printk("Bad frame mode\n");
+ return -EINVAL;
+ }
+
+ return mv88e6xxx_port_write(chip, port, MV88E6XXX_PORT_CTL0, reg);
+}
+
int mv88e6085_port_set_frame_mode(struct mv88e6xxx_chip *chip, int port,
enum mv88e6xxx_frame_mode mode)
{
--
(english) http://www.livejournal.com/~pavelmachek
(cesky, pictures) http://atrey.karlin.mff.cuni.cz/~pavel/picture/horses/blog.html
[-- Attachment #1.2: delme2 --]
[-- Type: text/plain, Size: 35206 bytes --]
commit 58a8b67092027331b83311e5621e12870fef0845
Author: Pavel Machek <pavel@denx.de>
Date: Mon Jan 28 14:59:36 2019 +0100
6xxx: headers-only: anotate same and different registers on 6065.
diff --git a/drivers/net/dsa/mv88e6xxx/global1.h b/drivers/net/dsa/mv88e6xxx/global1.h
index 5df4fc049733..6d7c7868f7d8 100644
--- a/drivers/net/dsa/mv88e6xxx/global1.h
+++ b/drivers/net/dsa/mv88e6xxx/global1.h
@@ -18,15 +18,15 @@
#include "chip.h"
/* Offset 0x00: Switch Global Status Register */
-#define MV88E6XXX_G1_STS 0x00
-#define MV88E6352_G1_STS_PPU_STATE 0x8000
-#define MV88E6185_G1_STS_PPU_STATE_MASK 0xc000
-#define MV88E6185_G1_STS_PPU_STATE_DISABLED_RST 0x0000
-#define MV88E6185_G1_STS_PPU_STATE_INITIALIZING 0x4000
-#define MV88E6185_G1_STS_PPU_STATE_DISABLED 0x8000
-#define MV88E6185_G1_STS_PPU_STATE_POLLING 0xc000
-#define MV88E6XXX_G1_STS_INIT_READY 0x0800
-#define MV88E6XXX_G1_STS_IRQ_AVB 8
+#define MV88E6XXX_G1_STS 0x00 /* ok */
+#define MV88E6352_G1_STS_PPU_STATE 0x8000
+#define MV88E6185_G1_STS_PPU_STATE_MASK 0xc000 W /* not on 6065 */
+#define MV88E6185_G1_STS_PPU_STATE_DISABLED_RST 0x0000 W
+#define MV88E6185_G1_STS_PPU_STATE_INITIALIZING 0x4000 W
+#define MV88E6185_G1_STS_PPU_STATE_DISABLED 0x8000 W
+#define MV88E6185_G1_STS_PPU_STATE_POLLING 0xc000 W
+#define MV88E6XXX_G1_STS_INIT_READY 0x0800 /* ok */
+#define MV88E6XXX_G1_STS_IRQ_AVB 8 /* ok vv */
#define MV88E6XXX_G1_STS_IRQ_DEVICE 7
#define MV88E6XXX_G1_STS_IRQ_STATS 6
#define MV88E6XXX_G1_STS_IRQ_VTU_PROB 5
@@ -34,13 +34,13 @@
#define MV88E6XXX_G1_STS_IRQ_ATU_PROB 3
#define MV88E6XXX_G1_STS_IRQ_ATU_DONE 2
#define MV88E6XXX_G1_STS_IRQ_TCAM_DONE 1
-#define MV88E6XXX_G1_STS_IRQ_EEPROM_DONE 0
+#define MV88E6XXX_G1_STS_IRQ_EEPROM_DONE 0 /* ok ^^ */
/* Offset 0x01: Switch MAC Address Register Bytes 0 & 1
* Offset 0x02: Switch MAC Address Register Bytes 2 & 3
* Offset 0x03: Switch MAC Address Register Bytes 4 & 5
*/
-#define MV88E6XXX_G1_MAC_01 0x01
+#define MV88E6XXX_G1_MAC_01 0x01 /* ok */
#define MV88E6XXX_G1_MAC_23 0x02
#define MV88E6XXX_G1_MAC_45 0x03
@@ -57,13 +57,13 @@
/* Offset 0x04: Switch Global Control Register */
#define MV88E6XXX_G1_CTL1 0x04
-#define MV88E6XXX_G1_CTL1_SW_RESET 0x8000
-#define MV88E6XXX_G1_CTL1_PPU_ENABLE 0x4000
-#define MV88E6352_G1_CTL1_DISCARD_EXCESS 0x2000
-#define MV88E6185_G1_CTL1_SCHED_PRIO 0x0800
-#define MV88E6185_G1_CTL1_MAX_FRAME_1632 0x0400
-#define MV88E6185_G1_CTL1_RELOAD_EEPROM 0x0200
-#define MV88E6XXX_G1_CTL1_DEVICE_EN 0x0080
+#define MV88E6XXX_G1_CTL1_SW_RESET 0x8000 W /* Not on 6065 */
+#define MV88E6XXX_G1_CTL1_PPU_ENABLE 0x4000 W /* Not on 6065 */
+#define MV88E6352_G1_CTL1_DISCARD_EXCESS 0x2000 /* ok */
+#define MV88E6185_G1_CTL1_SCHED_PRIO 0x0800 /* ok */
+#define MV88E6185_G1_CTL1_MAX_FRAME_1632 0x0400 /* ok */
+#define MV88E6185_G1_CTL1_RELOAD_EEPROM 0x0200 /* ok */
+#define MV88E6XXX_G1_CTL1_DEVICE_EN 0x0080 /* ?? vv */
#define MV88E6XXX_G1_CTL1_STATS_DONE_EN 0x0040
#define MV88E6XXX_G1_CTL1_VTU_PROBLEM_EN 0x0020
#define MV88E6XXX_G1_CTL1_VTU_DONE_EN 0x0010
@@ -74,24 +74,24 @@
/* Offset 0x05: VTU Operation Register */
#define MV88E6XXX_G1_VTU_OP 0x05
-#define MV88E6XXX_G1_VTU_OP_BUSY 0x8000
-#define MV88E6XXX_G1_VTU_OP_MASK 0x7000
-#define MV88E6XXX_G1_VTU_OP_FLUSH_ALL 0x1000
+#define MV88E6XXX_G1_VTU_OP_BUSY 0x8000 /* ok */
+#define MV88E6XXX_G1_VTU_OP_MASK 0x7000 /* ok */
+#define MV88E6XXX_G1_VTU_OP_FLUSH_ALL 0x1000 /* ok vv */
#define MV88E6XXX_G1_VTU_OP_NOOP 0x2000
#define MV88E6XXX_G1_VTU_OP_VTU_LOAD_PURGE 0x3000
-#define MV88E6XXX_G1_VTU_OP_VTU_GET_NEXT 0x4000
-#define MV88E6XXX_G1_VTU_OP_STU_LOAD_PURGE 0x5000
-#define MV88E6XXX_G1_VTU_OP_STU_GET_NEXT 0x6000
-#define MV88E6XXX_G1_VTU_OP_GET_CLR_VIOLATION 0x7000
-#define MV88E6XXX_G1_VTU_OP_MEMBER_VIOLATION BIT(6)
-#define MV88E6XXX_G1_VTU_OP_MISS_VIOLATION BIT(5)
-#define MV88E6XXX_G1_VTU_OP_SPID_MASK 0xf
+#define MV88E6XXX_G1_VTU_OP_VTU_GET_NEXT 0x4000 /* ok ^^ */
+#define MV88E6XXX_G1_VTU_OP_STU_LOAD_PURGE 0x5000 W /* reserved on 6065 */
+#define MV88E6XXX_G1_VTU_OP_STU_GET_NEXT 0x6000 W /* reserved on 6065 */
+#define MV88E6XXX_G1_VTU_OP_GET_CLR_VIOLATION 0x7000 /* ok */
+#define MV88E6XXX_G1_VTU_OP_MEMBER_VIOLATION BIT(6) /* ok */
+#define MV88E6XXX_G1_VTU_OP_MISS_VIOLATION BIT(5) /* ok */
+#define MV88E6XXX_G1_VTU_OP_SPID_MASK 0xf /* ok */
/* Offset 0x06: VTU VID Register */
#define MV88E6XXX_G1_VTU_VID 0x06
#define MV88E6XXX_G1_VTU_VID_MASK 0x0fff
-#define MV88E6390_G1_VTU_VID_PAGE 0x2000
-#define MV88E6XXX_G1_VTU_VID_VALID 0x1000
+#define MV88E6390_G1_VTU_VID_PAGE 0x2000 W /* not on 6065 */
+#define MV88E6XXX_G1_VTU_VID_VALID 0x1000 /* ok */
/* Offset 0x07: VTU/STU Data Register 1
* Offset 0x08: VTU/STU Data Register 2
@@ -99,7 +99,7 @@
*/
#define MV88E6XXX_G1_VTU_DATA1 0x07
#define MV88E6XXX_G1_VTU_DATA2 0x08
-#define MV88E6XXX_G1_VTU_DATA3 0x09
+#define MV88E6XXX_G1_VTU_DATA3 0x09 W /* reserved on 6065 */
#define MV88E6XXX_G1_VTU_STU_DATA_MASK 0x0003
#define MV88E6XXX_G1_VTU_DATA_MEMBER_TAG_UNMODIFIED 0x0000
#define MV88E6XXX_G1_VTU_DATA_MEMBER_TAG_UNTAGGED 0x0001
@@ -113,12 +113,12 @@
/* Offset 0x0A: ATU Control Register */
#define MV88E6XXX_G1_ATU_CTL 0x0a
#define MV88E6065_G1_RESET 0x8000
-#define MV88E6XXX_G1_ATU_CTL_LEARN2ALL 0x0008
+#define MV88E6XXX_G1_ATU_CTL_LEARN2ALL 0x0008 W /* reserved bit */
/* Offset 0x0B: ATU Operation Register */
#define MV88E6XXX_G1_ATU_OP 0x0b
-#define MV88E6XXX_G1_ATU_OP_BUSY 0x8000
-#define MV88E6XXX_G1_ATU_OP_MASK 0x7000
+#define MV88E6XXX_G1_ATU_OP_BUSY 0x8000 /* ok */
+#define MV88E6XXX_G1_ATU_OP_MASK 0x7000 /* ok vv */
#define MV88E6XXX_G1_ATU_OP_NOOP 0x0000
#define MV88E6XXX_G1_ATU_OP_FLUSH_MOVE_ALL 0x1000
#define MV88E6XXX_G1_ATU_OP_FLUSH_MOVE_NON_STATIC 0x2000
@@ -126,18 +126,18 @@
#define MV88E6XXX_G1_ATU_OP_GET_NEXT_DB 0x4000
#define MV88E6XXX_G1_ATU_OP_FLUSH_MOVE_ALL_DB 0x5000
#define MV88E6XXX_G1_ATU_OP_FLUSH_MOVE_NON_STATIC_DB 0x6000
-#define MV88E6XXX_G1_ATU_OP_GET_CLR_VIOLATION 0x7000
+#define MV88E6XXX_G1_ATU_OP_GET_CLR_VIOLATION 0x7000
#define MV88E6XXX_G1_ATU_OP_AGE_OUT_VIOLATION BIT(7)
#define MV88E6XXX_G1_ATU_OP_MEMBER_VIOLATION BIT(6)
#define MV88E6XXX_G1_ATU_OP_MISS_VIOLATION BIT(5)
-#define MV88E6XXX_G1_ATU_OP_FULL_VIOLATION BIT(4)
+#define MV88E6XXX_G1_ATU_OP_FULL_VIOLATION BIT(4) /* ok ^^ */
/* Offset 0x0C: ATU Data Register */
#define MV88E6XXX_G1_ATU_DATA 0x0c
-#define MV88E6XXX_G1_ATU_DATA_TRUNK 0x8000
+#define MV88E6XXX_G1_ATU_DATA_TRUNK 0x8000 /* ??? */
#define MV88E6XXX_G1_ATU_DATA_TRUNK_ID_MASK 0x00f0
#define MV88E6XXX_G1_ATU_DATA_PORT_VECTOR_MASK 0x3ff0
-#define MV88E6XXX_G1_ATU_DATA_STATE_MASK 0x000f
+#define MV88E6XXX_G1_ATU_DATA_STATE_MASK 0x000f /* ok */
#define MV88E6XXX_G1_ATU_DATA_STATE_UNUSED 0x0000
#define MV88E6XXX_G1_ATU_DATA_STATE_UC_MGMT 0x000d
#define MV88E6XXX_G1_ATU_DATA_STATE_UC_STATIC 0x000e
@@ -151,7 +151,7 @@
* Offset 0x0E: ATU MAC Address Register Bytes 2 & 3
* Offset 0x0F: ATU MAC Address Register Bytes 4 & 5
*/
-#define MV88E6XXX_G1_ATU_MAC01 0x0d
+#define MV88E6XXX_G1_ATU_MAC01 0x0d /* ok */
#define MV88E6XXX_G1_ATU_MAC23 0x0e
#define MV88E6XXX_G1_ATU_MAC45 0x0f
@@ -164,7 +164,7 @@
* Offset 0x16: IP-PRI Mapping Register 6
* Offset 0x17: IP-PRI Mapping Register 7
*/
-#define MV88E6XXX_G1_IP_PRI_0 0x10
+#define MV88E6XXX_G1_IP_PRI_0 0x10 /* ok */
#define MV88E6XXX_G1_IP_PRI_1 0x11
#define MV88E6XXX_G1_IP_PRI_2 0x12
#define MV88E6XXX_G1_IP_PRI_3 0x13
@@ -174,10 +174,10 @@
#define MV88E6XXX_G1_IP_PRI_7 0x17
/* Offset 0x18: IEEE-PRI Register */
-#define MV88E6XXX_G1_IEEE_PRI 0x18
+#define MV88E6XXX_G1_IEEE_PRI 0x18 /* ok */
/* Offset 0x19: Core Tag Type */
-#define MV88E6185_G1_CORE_TAG_TYPE 0x19
+#define MV88E6185_G1_CORE_TAG_TYPE 0x19 W /* reserved on 6065 */
/* Offset 0x1A: Monitor Control */
#define MV88E6185_G1_MONITOR_CTL 0x1a
@@ -188,8 +188,8 @@
#define MV88E6352_G1_MONITOR_CTL_MIRROR_DEST_MASK 0x000f
/* Offset 0x1A: Monitor & MGMT Control Register */
-#define MV88E6390_G1_MONITOR_MGMT_CTL 0x1a
-#define MV88E6390_G1_MONITOR_MGMT_CTL_UPDATE 0x8000
+#define MV88E6390_G1_MONITOR_MGMT_CTL 0x1a /* ok */
+#define MV88E6390_G1_MONITOR_MGMT_CTL_UPDATE 0x8000 W /* not on 6065 */
#define MV88E6390_G1_MONITOR_MGMT_CTL_PTR_MASK 0x3f00
#define MV88E6390_G1_MONITOR_MGMT_CTL_PTR_0180C280000000XLO 0x0000
#define MV88E6390_G1_MONITOR_MGMT_CTL_PTR_0180C280000000XHI 0x0100
@@ -198,10 +198,10 @@
#define MV88E6390_G1_MONITOR_MGMT_CTL_PTR_INGRESS_DEST 0x2000
#define MV88E6390_G1_MONITOR_MGMT_CTL_PTR_EGRESS_DEST 0x2100
#define MV88E6390_G1_MONITOR_MGMT_CTL_PTR_CPU_DEST 0x3000
-#define MV88E6390_G1_MONITOR_MGMT_CTL_DATA_MASK 0x00ff
+#define MV88E6390_G1_MONITOR_MGMT_CTL_DATA_MASK 0x00ff W /* different on 6065 ? */
/* Offset 0x1C: Global Control 2 */
-#define MV88E6XXX_G1_CTL2 0x1c
+#define MV88E6XXX_G1_CTL2 0x1c W /* different, mostly reserved on 6065 */
#define MV88E6185_G1_CTL2_CASCADE_PORT_MASK 0xf000
#define MV88E6185_G1_CTL2_CASCADE_PORT_NONE 0xe000
#define MV88E6185_G1_CTL2_CASCADE_PORT_MULTI 0xf000
@@ -230,11 +230,11 @@
#define MV88E6390_G1_CTL2_HIST_MODE_TX 0x0080
#define MV88E6352_G1_CTL2_CTR_MODE_MASK 0x0060
#define MV88E6390_G1_CTL2_CTR_MODE 0x0020
-#define MV88E6XXX_G1_CTL2_DEVICE_NUMBER_MASK 0x001f
+#define MV88E6XXX_G1_CTL2_DEVICE_NUMBER_MASK 0x001f W /* reserved on 6065 */
/* Offset 0x1D: Stats Operation Register */
#define MV88E6XXX_G1_STATS_OP 0x1d
-#define MV88E6XXX_G1_STATS_OP_BUSY 0x8000
+#define MV88E6XXX_G1_STATS_OP_BUSY 0x8000 /* ok */
#define MV88E6XXX_G1_STATS_OP_NOP 0x0000
#define MV88E6XXX_G1_STATS_OP_FLUSH_ALL 0x1000
#define MV88E6XXX_G1_STATS_OP_FLUSH_PORT 0x2000
@@ -242,14 +242,14 @@
#define MV88E6XXX_G1_STATS_OP_CAPTURE_PORT 0x5000
#define MV88E6XXX_G1_STATS_OP_HIST_RX 0x0400
#define MV88E6XXX_G1_STATS_OP_HIST_TX 0x0800
-#define MV88E6XXX_G1_STATS_OP_HIST_RX_TX 0x0c00
+#define MV88E6XXX_G1_STATS_OP_HIST_RX_TX 0x0c00 /* ok */
#define MV88E6XXX_G1_STATS_OP_BANK_1_BIT_9 0x0200
#define MV88E6XXX_G1_STATS_OP_BANK_1_BIT_10 0x0400
/* Offset 0x1E: Stats Counter Register Bytes 3 & 2
* Offset 0x1F: Stats Counter Register Bytes 1 & 0
*/
-#define MV88E6XXX_G1_STATS_COUNTER_32 0x1e
+#define MV88E6XXX_G1_STATS_COUNTER_32 0x1e /* ok */
#define MV88E6XXX_G1_STATS_COUNTER_01 0x1f
int mv88e6xxx_g1_read(struct mv88e6xxx_chip *chip, int reg, u16 *val);
diff --git a/drivers/net/dsa/mv88e6xxx/global2.h b/drivers/net/dsa/mv88e6xxx/global2.h
index 48e501d15e20..f5a52b7bfb12 100644
--- a/drivers/net/dsa/mv88e6xxx/global2.h
+++ b/drivers/net/dsa/mv88e6xxx/global2.h
@@ -18,7 +18,7 @@
#include "chip.h"
/* Offset 0x00: Interrupt Source Register */
-#define MV88E6XXX_G2_INT_SRC 0x00 /* FIXME: reserved */
+#define MV88E6XXX_G2_INT_SRC 0x00 W /* reserved */
#define MV88E6XXX_G2_INT_SRC_WDOG 0x8000
#define MV88E6XXX_G2_INT_SRC_JAM_LIMIT 0x4000
#define MV88E6XXX_G2_INT_SRC_DUPLEX_MISMATCH 0x2000
@@ -30,7 +30,7 @@
#define MV88E6XXX_G2_INT_SOURCE_WATCHDOG 15
/* Offset 0x01: Interrupt Mask Register */
-#define MV88E6XXX_G2_INT_MASK 0x01 /* FIXME: reserved */
+#define MV88E6XXX_G2_INT_MASK 0x01 W /* reserved */
#define MV88E6XXX_G2_INT_MASK_WDOG 0x8000
#define MV88E6XXX_G2_INT_MASK_JAM_LIMIT 0x4000
#define MV88E6XXX_G2_INT_MASK_DUPLEX_MISMATCH 0x2000
@@ -40,16 +40,16 @@
#define MV88E6390_G2_INT_MASK_PHY 0x07fe
/* Offset 0x02: MGMT Enable Register 2x */
-#define MV88E6XXX_G2_MGMT_EN_2X 0x02 /* FIXME: reserved */
+#define MV88E6XXX_G2_MGMT_EN_2X 0x02 W /* reserved */
/* Offset 0x03: MGMT Enable Register 0x */
-#define MV88E6XXX_G2_MGMT_EN_0X 0x03 /* FIXME: reserved */
+#define MV88E6XXX_G2_MGMT_EN_0X 0x03 W /* reserved */
/* Offset 0x04: Flow Control Delay Register */
-#define MV88E6XXX_G2_FLOW_CTL 0x04 /* FIXME: reserved */
+#define MV88E6XXX_G2_FLOW_CTL 0x04 W /* reserved */
/* Offset 0x05: Switch Management Register */
-#define MV88E6XXX_G2_SWITCH_MGMT 0x05 /* FIXME: reserved */
+#define MV88E6XXX_G2_SWITCH_MGMT 0x05 W /* reserved */
#define MV88E6XXX_G2_SWITCH_MGMT_USE_DOUBLE_TAG_DATA 0x8000
#define MV88E6XXX_G2_SWITCH_MGMT_PREVENT_LOOPS 0x4000
#define MV88E6XXX_G2_SWITCH_MGMT_FLOW_CTL_MSG 0x2000
@@ -57,7 +57,7 @@
#define MV88E6XXX_G2_SWITCH_MGMT_RSVD2CPU 0x0008
/* Offset 0x06: Device Mapping Table Register */
-#define MV88E6XXX_G2_DEVICE_MAPPING 0x06 /* FIXME: reserved */
+#define MV88E6XXX_G2_DEVICE_MAPPING 0x06 W /* reserved */
#define MV88E6XXX_G2_DEVICE_MAPPING_UPDATE 0x8000
#define MV88E6XXX_G2_DEVICE_MAPPING_DEV_MASK 0x1f00
#define MV88E6352_G2_DEVICE_MAPPING_PORT_MASK 0x000f
@@ -70,7 +70,7 @@
#define MV88E6XXX_G2_TRUNK_MASK_HASH 0x0800
/* Offset 0x08: Trunk Mapping Table Register */
-#define MV88E6XXX_G2_TRUNK_MAPPING 0x08 /* FIXME: reserved */
+#define MV88E6XXX_G2_TRUNK_MAPPING 0x08 W /* reserved */
#define MV88E6XXX_G2_TRUNK_MAPPING_UPDATE 0x8000
#define MV88E6XXX_G2_TRUNK_MAPPING_ID_MASK 0x7800
@@ -94,11 +94,11 @@
#define MV88E6XXX_G2_IRL_CMD_REG_MASK 0x000f
/* Offset 0x0A: Ingress Rate Data Register */
-#define MV88E6XXX_G2_IRL_DATA 0x0a
+#define MV88E6XXX_G2_IRL_DATA 0x0a /* ok */
#define MV88E6XXX_G2_IRL_DATA_MASK 0xffff
/* Offset 0x0B: Cross-chip Port VLAN Register */
-#define MV88E6XXX_G2_PVT_ADDR 0x0b
+#define MV88E6XXX_G2_PVT_ADDR 0x0b W /* reserved */
#define MV88E6XXX_G2_PVT_ADDR_BUSY 0x8000
#define MV88E6XXX_G2_PVT_ADDR_OP_MASK 0x7000
#define MV88E6XXX_G2_PVT_ADDR_OP_INIT_ONES 0x1000
@@ -107,11 +107,11 @@
#define MV88E6XXX_G2_PVT_ADDR_PTR_MASK 0x01ff
/* Offset 0x0C: Cross-chip Port VLAN Data Register */
-#define MV88E6XXX_G2_PVT_DATA 0x0c
+#define MV88E6XXX_G2_PVT_DATA 0x0c W /* reserved */
#define MV88E6XXX_G2_PVT_DATA_MASK 0x7f
/* Offset 0x0D: Switch MAC/WoL/WoF Register */
-#define MV88E6XXX_G2_SWITCH_MAC 0x0d
+#define MV88E6XXX_G2_SWITCH_MAC 0x0d W /* reserved */
#define MV88E6XXX_G2_SWITCH_MAC_UPDATE 0x8000
#define MV88E6XXX_G2_SWITCH_MAC_PTR_MASK 0x1f00
#define MV88E6XXX_G2_SWITCH_MAC_DATA_MASK 0x00ff
@@ -120,7 +120,7 @@
#define MV88E6XXX_G2_ATU_STATS 0x0e
/* Offset 0x0F: Priority Override Table */
-#define MV88E6XXX_G2_PRIO_OVERRIDE 0x0f
+#define MV88E6XXX_G2_PRIO_OVERRIDE 0x0f W /* reserved */
#define MV88E6XXX_G2_PRIO_OVERRIDE_UPDATE 0x8000
#define MV88E6XXX_G2_PRIO_OVERRIDE_FPRISET 0x1000
#define MV88E6XXX_G2_PRIO_OVERRIDE_PTR_MASK 0x0f00
@@ -130,7 +130,7 @@
#define MV88E6XXX_G2_PRIO_OVERRIDE_DATA_MASK 0x0007
/* Offset 0x14: EEPROM Command */
-#define MV88E6XXX_G2_EEPROM_CMD 0x14
+#define MV88E6XXX_G2_EEPROM_CMD 0x14 W /* reserved */
#define MV88E6XXX_G2_EEPROM_CMD_BUSY 0x8000
#define MV88E6XXX_G2_EEPROM_CMD_OP_MASK 0x7000
#define MV88E6XXX_G2_EEPROM_CMD_OP_WRITE 0x3000
@@ -142,15 +142,15 @@
#define MV88E6390_G2_EEPROM_CMD_DATA_MASK 0x00ff
/* Offset 0x15: EEPROM Data */
-#define MV88E6352_G2_EEPROM_DATA 0x15
+#define MV88E6352_G2_EEPROM_DATA 0x15 W /* reserved */
#define MV88E6352_G2_EEPROM_DATA_MASK 0xffff
/* Offset 0x15: EEPROM Addr */
-#define MV88E6390_G2_EEPROM_ADDR 0x15
+#define MV88E6390_G2_EEPROM_ADDR 0x15 W /* reserved */
#define MV88E6390_G2_EEPROM_ADDR_MASK 0xffff
/* Offset 0x16: AVB Command Register */
-#define MV88E6352_G2_AVB_CMD 0x16
+#define MV88E6352_G2_AVB_CMD 0x16 W /* reserved */
#define MV88E6352_G2_AVB_CMD_BUSY 0x8000
#define MV88E6352_G2_AVB_CMD_OP_READ 0x4000
#define MV88E6352_G2_AVB_CMD_OP_READ_INCR 0x6000
@@ -173,10 +173,10 @@
#define MV88E6352_G2_AVB_CMD_ADDR_MASK 0x001f
/* Offset 0x17: AVB Data Register */
-#define MV88E6352_G2_AVB_DATA 0x17
+#define MV88E6352_G2_AVB_DATA 0x17 W /* reserved */
/* Offset 0x18: SMI PHY Command Register */
-#define MV88E6XXX_G2_SMI_PHY_CMD 0x18
+#define MV88E6XXX_G2_SMI_PHY_CMD 0x18 W /* reserved */
#define MV88E6XXX_G2_SMI_PHY_CMD_BUSY 0x8000
#define MV88E6390_G2_SMI_PHY_CMD_FUNC_MASK 0x6000
#define MV88E6390_G2_SMI_PHY_CMD_FUNC_INTERNAL 0x0000
@@ -197,16 +197,16 @@
#define MV88E6XXX_G2_SMI_PHY_CMD_SETUP_PTR_MASK 0x03ff
/* Offset 0x19: SMI PHY Data Register */
-#define MV88E6XXX_G2_SMI_PHY_DATA 0x19
+#define MV88E6XXX_G2_SMI_PHY_DATA 0x19 W /* reserved */
/* Offset 0x1A: Scratch and Misc. Register */
-#define MV88E6XXX_G2_SCRATCH_MISC_MISC 0x1a
+#define MV88E6XXX_G2_SCRATCH_MISC_MISC 0x1a W /* reserved */
#define MV88E6XXX_G2_SCRATCH_MISC_UPDATE 0x8000
#define MV88E6XXX_G2_SCRATCH_MISC_PTR_MASK 0x7f00
#define MV88E6XXX_G2_SCRATCH_MISC_DATA_MASK 0x00ff
/* Offset 0x1B: Watch Dog Control Register */
-#define MV88E6352_G2_WDOG_CTL 0x1b
+#define MV88E6352_G2_WDOG_CTL 0x1b W /* reserved */
#define MV88E6352_G2_WDOG_CTL_EGRESS_EVENT 0x0080
#define MV88E6352_G2_WDOG_CTL_RMU_TIMEOUT 0x0040
#define MV88E6352_G2_WDOG_CTL_QC_ENABLE 0x0020
@@ -217,7 +217,7 @@
#define MV88E6352_G2_WDOG_CTL_SWRESET 0x0001
/* Offset 0x1B: Watch Dog Control Register */
-#define MV88E6390_G2_WDOG_CTL 0x1b
+#define MV88E6390_G2_WDOG_CTL 0x1b W /* reserved */
#define MV88E6390_G2_WDOG_CTL_UPDATE 0x8000
#define MV88E6390_G2_WDOG_CTL_PTR_MASK 0x7f00
#define MV88E6390_G2_WDOG_CTL_PTR_INT_SOURCE 0x0000
@@ -232,14 +232,14 @@
#define MV88E6390_G2_WDOG_CTL_FORCE_IRQ 0x0001
/* Offset 0x1C: QoS Weights Register */
-#define MV88E6XXX_G2_QOS_WEIGHTS 0x1c
+#define MV88E6XXX_G2_QOS_WEIGHTS 0x1c W /* reserved */
#define MV88E6XXX_G2_QOS_WEIGHTS_UPDATE 0x8000
#define MV88E6352_G2_QOS_WEIGHTS_PTR_MASK 0x3f00
#define MV88E6390_G2_QOS_WEIGHTS_PTR_MASK 0x7f00
#define MV88E6XXX_G2_QOS_WEIGHTS_DATA_MASK 0x00ff
/* Offset 0x1D: Misc Register */
-#define MV88E6XXX_G2_MISC 0x1d
+#define MV88E6XXX_G2_MISC 0x1d W /* reserved */
#define MV88E6XXX_G2_MISC_5_BIT_PORT 0x4000
#define MV88E6352_G2_NOEGR_POLICY 0x2000
#define MV88E6390_G2_LAG_ID_4 0x2000
diff --git a/drivers/net/dsa/mv88e6xxx/port.h b/drivers/net/dsa/mv88e6xxx/port.h
index f32f56af8e35..5b9dde5c3334 100644
--- a/drivers/net/dsa/mv88e6xxx/port.h
+++ b/drivers/net/dsa/mv88e6xxx/port.h
@@ -19,13 +19,13 @@
/* Offset 0x00: Port Status Register */
#define MV88E6XXX_PORT_STS 0x00
-#define MV88E6XXX_PORT_STS_PAUSE_EN 0x8000
+#define MV88E6XXX_PORT_STS_PAUSE_EN 0x8000 /* ok vvv */
#define MV88E6XXX_PORT_STS_MY_PAUSE 0x4000
-#define MV88E6XXX_PORT_STS_HD_FLOW 0x2000
+#define MV88E6XXX_PORT_STS_HD_FLOW 0x2000 W /* "link mode is resolved" on 6065 */
#define MV88E6XXX_PORT_STS_PHY_DETECT 0x1000
-#define MV88E6XXX_PORT_STS_LINK 0x0800
-#define MV88E6XXX_PORT_STS_DUPLEX 0x0400
-#define MV88E6XXX_PORT_STS_SPEED_MASK 0x0300
+#define MV88E6XXX_PORT_STS_LINK 0x0800 W /* -- 0x1000 on 6065? */
+#define MV88E6XXX_PORT_STS_DUPLEX 0x0400 W /* -- 0x200 on 6065*/
+#define MV88E6XXX_PORT_STS_SPEED_MASK 0x0300 W /* -- mask is 0x0f00 on 6065 */
#define MV88E6XXX_PORT_STS_SPEED_10 0x0000
#define MV88E6XXX_PORT_STS_SPEED_100 0x0100
#define MV88E6XXX_PORT_STS_SPEED_1000 0x0200
@@ -33,38 +33,38 @@
#define MV88E6352_PORT_STS_EEE 0x0040
#define MV88E6165_PORT_STS_AM_DIS 0x0040
#define MV88E6185_PORT_STS_MGMII 0x0040
-#define MV88E6XXX_PORT_STS_TX_PAUSED 0x0020
-#define MV88E6XXX_PORT_STS_FLOW_CTL 0x0010
-#define MV88E6XXX_PORT_STS_CMODE_MASK 0x000f
-#define MV88E6XXX_PORT_STS_CMODE_100BASE_X 0x0008
-#define MV88E6XXX_PORT_STS_CMODE_1000BASE_X 0x0009
-#define MV88E6XXX_PORT_STS_CMODE_SGMII 0x000a
-#define MV88E6XXX_PORT_STS_CMODE_2500BASEX 0x000b
-#define MV88E6XXX_PORT_STS_CMODE_XAUI 0x000c
-#define MV88E6XXX_PORT_STS_CMODE_RXAUI 0x000d
-#define MV88E6185_PORT_STS_CDUPLEX 0x0008
-#define MV88E6185_PORT_STS_CMODE_MASK 0x0007
-#define MV88E6185_PORT_STS_CMODE_GMII_FD 0x0000
-#define MV88E6185_PORT_STS_CMODE_MII_100_FD_PS 0x0001
-#define MV88E6185_PORT_STS_CMODE_MII_100 0x0002
-#define MV88E6185_PORT_STS_CMODE_MII_10 0x0003
-#define MV88E6185_PORT_STS_CMODE_SERDES 0x0004
-#define MV88E6185_PORT_STS_CMODE_1000BASE_X 0x0005
-#define MV88E6185_PORT_STS_CMODE_PHY 0x0006
-#define MV88E6185_PORT_STS_CMODE_DISABLED 0x0007
+#define MV88E6XXX_PORT_STS_TX_PAUSED 0x0020 /* ok */
+#define MV88E6XXX_PORT_STS_FLOW_CTL 0x0010 /* ok */
+#define MV88E6XXX_PORT_STS_CMODE_MASK 0x000f W /* vv these are reserved or different */
+#define MV88E6XXX_PORT_STS_CMODE_100BASE_X 0x0008 W
+#define MV88E6XXX_PORT_STS_CMODE_1000BASE_X 0x0009 W
+#define MV88E6XXX_PORT_STS_CMODE_SGMII 0x000a W
+#define MV88E6XXX_PORT_STS_CMODE_2500BASEX 0x000b W
+#define MV88E6XXX_PORT_STS_CMODE_XAUI 0x000c W
+#define MV88E6XXX_PORT_STS_CMODE_RXAUI 0x000d W
+#define MV88E6185_PORT_STS_CDUPLEX 0x0008 W
+#define MV88E6185_PORT_STS_CMODE_MASK 0x0007 W
+#define MV88E6185_PORT_STS_CMODE_GMII_FD 0x0000 W
+#define MV88E6185_PORT_STS_CMODE_MII_100_FD_PS 0x0001 W
+#define MV88E6185_PORT_STS_CMODE_MII_100 0x0002 W
+#define MV88E6185_PORT_STS_CMODE_MII_10 0x0003 W
+#define MV88E6185_PORT_STS_CMODE_SERDES 0x0004 W
+#define MV88E6185_PORT_STS_CMODE_1000BASE_X 0x0005 W
+#define MV88E6185_PORT_STS_CMODE_PHY 0x0006 W
+#define MV88E6185_PORT_STS_CMODE_DISABLED 0x0007 W /* ^^ */
/* Offset 0x01: MAC (or PCS or Physical) Control Register */
#define MV88E6XXX_PORT_MAC_CTL 0x01
-#define MV88E6XXX_PORT_MAC_CTL_RGMII_DELAY_RXCLK 0x8000
-#define MV88E6XXX_PORT_MAC_CTL_RGMII_DELAY_TXCLK 0x4000
-#define MV88E6185_PORT_MAC_CTL_SYNC_OK 0x4000
-#define MV88E6390_PORT_MAC_CTL_FORCE_SPEED 0x2000
-#define MV88E6390_PORT_MAC_CTL_ALTSPEED 0x1000
-#define MV88E6352_PORT_MAC_CTL_200BASE 0x1000
-#define MV88E6185_PORT_MAC_CTL_AN_EN 0x0400
-#define MV88E6185_PORT_MAC_CTL_AN_RESTART 0x0200
-#define MV88E6185_PORT_MAC_CTL_AN_DONE 0x0100
-#define MV88E6XXX_PORT_MAC_CTL_FC 0x0080
+#define MV88E6XXX_PORT_MAC_CTL_RGMII_DELAY_RXCLK 0x8000 W /* vv reserved */
+#define MV88E6XXX_PORT_MAC_CTL_RGMII_DELAY_TXCLK 0x4000 W
+#define MV88E6185_PORT_MAC_CTL_SYNC_OK 0x4000 W
+#define MV88E6390_PORT_MAC_CTL_FORCE_SPEED 0x2000 W
+#define MV88E6390_PORT_MAC_CTL_ALTSPEED 0x1000 W
+#define MV88E6352_PORT_MAC_CTL_200BASE 0x1000 W
+#define MV88E6185_PORT_MAC_CTL_AN_EN 0x0400 W
+#define MV88E6185_PORT_MAC_CTL_AN_RESTART 0x0200 W /* ^^ reserved */
+#define MV88E6185_PORT_MAC_CTL_AN_DONE 0x0100 W /* reserved on 6065 */
+#define MV88E6XXX_PORT_MAC_CTL_FC 0x0080 /* ok vv */
#define MV88E6XXX_PORT_MAC_CTL_FORCE_FC 0x0040
#define MV88E6XXX_PORT_MAC_CTL_LINK_UP 0x0020
#define MV88E6XXX_PORT_MAC_CTL_FORCE_LINK 0x0010
@@ -76,15 +76,15 @@
#define MV88E6065_PORT_MAC_CTL_SPEED_200 0x0002
#define MV88E6XXX_PORT_MAC_CTL_SPEED_1000 0x0002
#define MV88E6390_PORT_MAC_CTL_SPEED_10000 0x0003
-#define MV88E6XXX_PORT_MAC_CTL_SPEED_UNFORCED 0x0003
+#define MV88E6XXX_PORT_MAC_CTL_SPEED_UNFORCED 0x0003 /* ok ^^ */
/* Offset 0x02: Jamming Control Register */
-#define MV88E6097_PORT_JAM_CTL 0x02
+#define MV88E6097_PORT_JAM_CTL 0x02 W /* Not on 6065 */
#define MV88E6097_PORT_JAM_CTL_LIMIT_OUT_MASK 0xff00
#define MV88E6097_PORT_JAM_CTL_LIMIT_IN_MASK 0x00ff
/* Offset 0x02: Flow Control Register */
-#define MV88E6390_PORT_FLOW_CTL 0x02
+#define MV88E6390_PORT_FLOW_CTL 0x02 W
#define MV88E6390_PORT_FLOW_CTL_UPDATE 0x8000
#define MV88E6390_PORT_FLOW_CTL_PTR_MASK 0x7f00
#define MV88E6390_PORT_FLOW_CTL_LIMIT_IN 0x0000
@@ -92,8 +92,10 @@
#define MV88E6390_PORT_FLOW_CTL_DATA_MASK 0x00ff
/* Offset 0x03: Switch Identifier Register */
-#define MV88E6XXX_PORT_SWITCH_ID 0x03
+#define MV88E6XXX_PORT_SWITCH_ID 0x03 /* ok */
#define MV88E6XXX_PORT_SWITCH_ID_PROD_MASK 0xfff0
+#define MV88E6XXX_PORT_SWITCH_ID_PROD_6035 0x0350 /* very similar to 6065 */
+#define MV88E6XXX_PORT_SWITCH_ID_PROD_6065 0x0650
#define MV88E6XXX_PORT_SWITCH_ID_PROD_6085 0x04a0
#define MV88E6XXX_PORT_SWITCH_ID_PROD_6095 0x0950
#define MV88E6XXX_PORT_SWITCH_ID_PROD_6097 0x0990
@@ -124,132 +126,133 @@
/* Offset 0x04: Port Control Register */
#define MV88E6XXX_PORT_CTL0 0x04
-#define MV88E6XXX_PORT_CTL0_USE_CORE_TAG 0x8000
-#define MV88E6XXX_PORT_CTL0_DROP_ON_LOCK 0x4000
-#define MV88E6XXX_PORT_CTL0_EGRESS_MODE_MASK 0x3000
+#define MV88E6XXX_PORT_CTL0_USE_CORE_TAG 0x8000 W /* not on 6065, unused */
+#define MV88E6XXX_PORT_CTL0_DROP_ON_LOCK 0x4000 /* ...but this matches? */
+#define MV88E6XXX_PORT_CTL0_EGRESS_MODE_MASK 0x3000 /* ok, matches 6065 */
#define MV88E6XXX_PORT_CTL0_EGRESS_MODE_UNMODIFIED 0x0000
#define MV88E6XXX_PORT_CTL0_EGRESS_MODE_UNTAGGED 0x1000
#define MV88E6XXX_PORT_CTL0_EGRESS_MODE_TAGGED 0x2000
-#define MV88E6XXX_PORT_CTL0_EGRESS_MODE_ETHER_TYPE_DSA 0x3000
-#define MV88E6XXX_PORT_CTL0_HEADER 0x0800
-#define MV88E6XXX_PORT_CTL0_IGMP_MLD_SNOOP 0x0400
-#define MV88E6XXX_PORT_CTL0_DOUBLE_TAG 0x0200
+#define MV88E6XXX_PORT_CTL0_EGRESS_MODE_ETHER_TYPE_DSA 0x3000 W /* not on 6065, unused */
+#define MV88E6XXX_PORT_CTL0_HEADER 0x0800 /* ok, matches 6065 */
+#define MV88E6XXX_PORT_CTL0_IGMP_MLD_SNOOP 0x0400 /* ok */
+#define MV88E6XXX_PORT_CTL0_DOUBLE_TAG 0x0200 W /* not on 6065, unused */
#define MV88E6XXX_PORT_CTL0_FRAME_MODE_MASK 0x0300
#define MV88E6XXX_PORT_CTL0_FRAME_MODE_NORMAL 0x0000
-#define MV88E6XXX_PORT_CTL0_FRAME_MODE_DSA 0x0100
-#define MV88E6XXX_PORT_CTL0_FRAME_MODE_PROVIDER 0x0200
+#define MV88E6XXX_PORT_CTL0_FRAME_MODE_DSA 0x0100
+#define MV88E6XXX_PORT_CTL0_FRAME_MODE_PROVIDER 0x0200 W /* not on 6065, not used */
#define MV88E6XXX_PORT_CTL0_FRAME_MODE_ETHER_TYPE_DSA 0x0300
-#define MV88E6XXX_PORT_CTL0_DSA_TAG 0x0100
-#define MV88E6XXX_PORT_CTL0_VLAN_TUNNEL 0x0080
-#define MV88E6XXX_PORT_CTL0_TAG_IF_BOTH 0x0040
-#define MV88E6185_PORT_CTL0_USE_IP 0x0020
-#define MV88E6185_PORT_CTL0_USE_TAG 0x0010
+#define MV88E6XXX_PORT_CTL0_DSA_TAG 0x0100 W /* not on 6065, unused */
+#define MV88E6XXX_PORT_CTL0_VLAN_TUNNEL 0x0080 /* ok */
+#define MV88E6XXX_PORT_CTL0_TAG_IF_BOTH 0x0040 /* ok */
+#define MV88E6185_PORT_CTL0_USE_IP 0x0020 /* ok */
+#define MV88E6185_PORT_CTL0_USE_TAG 0x0010 /* ok */
#define MV88E6185_PORT_CTL0_FORWARD_UNKNOWN 0x0004
-#define MV88E6352_PORT_CTL0_EGRESS_FLOODS_MASK 0x000c
+#define MV88E6352_PORT_CTL0_EGRESS_FLOODS_MASK 0x000c /* ok */
#define MV88E6352_PORT_CTL0_EGRESS_FLOODS_NO_UNKNOWN_DA 0x0000
#define MV88E6352_PORT_CTL0_EGRESS_FLOODS_NO_UNKNOWN_MC_DA 0x0004
#define MV88E6352_PORT_CTL0_EGRESS_FLOODS_NO_UNKNOWN_UC_DA 0x0008
#define MV88E6352_PORT_CTL0_EGRESS_FLOODS_ALL_UNKNOWN_DA 0x000c
-#define MV88E6XXX_PORT_CTL0_STATE_MASK 0x0003
+#define MV88E6XXX_PORT_CTL0_STATE_MASK 0x0003 /* ok */
#define MV88E6XXX_PORT_CTL0_STATE_DISABLED 0x0000
#define MV88E6XXX_PORT_CTL0_STATE_BLOCKING 0x0001
#define MV88E6XXX_PORT_CTL0_STATE_LEARNING 0x0002
#define MV88E6XXX_PORT_CTL0_STATE_FORWARDING 0x0003
/* Offset 0x05: Port Control 1 */
-#define MV88E6XXX_PORT_CTL1 0x05
+#define MV88E6XXX_PORT_CTL1 0x05 W /* undocumented / reserved */
#define MV88E6XXX_PORT_CTL1_MESSAGE_PORT 0x8000
#define MV88E6XXX_PORT_CTL1_FID_11_4_MASK 0x00ff
/* Offset 0x06: Port Based VLAN Map */
#define MV88E6XXX_PORT_BASE_VLAN 0x06
-#define MV88E6XXX_PORT_BASE_VLAN_FID_3_0_MASK 0xf000
+#define MV88E6XXX_PORT_BASE_VLAN_FID_3_0_MASK 0xf000 W /* 6065 has dbum there */
+/* ...and more bits below */
/* Offset 0x07: Default Port VLAN ID & Priority */
#define MV88E6XXX_PORT_DEFAULT_VLAN 0x07
-#define MV88E6XXX_PORT_DEFAULT_VLAN_MASK 0x0fff
+#define MV88E6XXX_PORT_DEFAULT_VLAN_MASK 0x0fff /* ok */
/* Offset 0x08: Port Control 2 Register */
#define MV88E6XXX_PORT_CTL2 0x08
-#define MV88E6XXX_PORT_CTL2_IGNORE_FCS 0x8000
+#define MV88E6XXX_PORT_CTL2_IGNORE_FCS 0x8000 /* ok vv */
#define MV88E6XXX_PORT_CTL2_VTU_PRI_OVERRIDE 0x4000
#define MV88E6XXX_PORT_CTL2_SA_PRIO_OVERRIDE 0x2000
-#define MV88E6XXX_PORT_CTL2_DA_PRIO_OVERRIDE 0x1000
-#define MV88E6XXX_PORT_CTL2_JUMBO_MODE_MASK 0x3000
-#define MV88E6XXX_PORT_CTL2_JUMBO_MODE_1522 0x0000
-#define MV88E6XXX_PORT_CTL2_JUMBO_MODE_2048 0x1000
-#define MV88E6XXX_PORT_CTL2_JUMBO_MODE_10240 0x2000
-#define MV88E6XXX_PORT_CTL2_8021Q_MODE_MASK 0x0c00
+#define MV88E6XXX_PORT_CTL2_DA_PRIO_OVERRIDE 0x1000 /* ok ?? */
+#define MV88E6XXX_PORT_CTL2_JUMBO_MODE_MASK 0x3000 W /* vv: incompatible */
+#define MV88E6XXX_PORT_CTL2_JUMBO_MODE_1522 0x0000 W
+#define MV88E6XXX_PORT_CTL2_JUMBO_MODE_2048 0x1000 W
+#define MV88E6XXX_PORT_CTL2_JUMBO_MODE_10240 0x2000 W /* ^^ */
+#define MV88E6XXX_PORT_CTL2_8021Q_MODE_MASK 0x0c00 /* ok vv */
#define MV88E6XXX_PORT_CTL2_8021Q_MODE_DISABLED 0x0000
#define MV88E6XXX_PORT_CTL2_8021Q_MODE_FALLBACK 0x0400
#define MV88E6XXX_PORT_CTL2_8021Q_MODE_CHECK 0x0800
#define MV88E6XXX_PORT_CTL2_8021Q_MODE_SECURE 0x0c00
#define MV88E6XXX_PORT_CTL2_DISCARD_TAGGED 0x0200
#define MV88E6XXX_PORT_CTL2_DISCARD_UNTAGGED 0x0100
-#define MV88E6XXX_PORT_CTL2_MAP_DA 0x0080
-#define MV88E6XXX_PORT_CTL2_DEFAULT_FORWARD 0x0040
-#define MV88E6XXX_PORT_CTL2_EGRESS_MONITOR 0x0020
-#define MV88E6XXX_PORT_CTL2_INGRESS_MONITOR 0x0010
-#define MV88E6095_PORT_CTL2_CPU_PORT_MASK 0x000f
+#define MV88E6XXX_PORT_CTL2_MAP_DA 0x0080 /* ok %% */
+#define MV88E6XXX_PORT_CTL2_DEFAULT_FORWARD 0x0040 W /* reserved on 6065 */
+#define MV88E6XXX_PORT_CTL2_EGRESS_MONITOR 0x0020 W /* reserved on 6065 */
+#define MV88E6XXX_PORT_CTL2_INGRESS_MONITOR 0x0010 W /* reserved on 6065 */
+#define MV88E6095_PORT_CTL2_CPU_PORT_MASK 0x000f W /* 6065 has qpri overrides here */
/* Offset 0x09: Egress Rate Control */
-#define MV88E6XXX_PORT_EGRESS_RATE_CTL1 0x09
+#define MV88E6XXX_PORT_EGRESS_RATE_CTL1 0x09 W /* we have ingress control here */
/* Offset 0x0A: Egress Rate Control 2 */
-#define MV88E6XXX_PORT_EGRESS_RATE_CTL2 0x0a
+#define MV88E6XXX_PORT_EGRESS_RATE_CTL2 0x0a W /* so this may not be compatible */
/* Offset 0x0B: Port Association Vector */
#define MV88E6XXX_PORT_ASSOC_VECTOR 0x0b
-#define MV88E6XXX_PORT_ASSOC_VECTOR_HOLD_AT_1 0x8000
-#define MV88E6XXX_PORT_ASSOC_VECTOR_INT_AGE_OUT 0x4000
-#define MV88E6XXX_PORT_ASSOC_VECTOR_LOCKED_PORT 0x2000
-#define MV88E6XXX_PORT_ASSOC_VECTOR_IGNORE_WRONG 0x1000
-#define MV88E6XXX_PORT_ASSOC_VECTOR_REFRESH_LOCKED 0x0800
+#define MV88E6XXX_PORT_ASSOC_VECTOR_HOLD_AT_1 0x8000 W /* 6065 is different -- Ingress monitor */
+#define MV88E6XXX_PORT_ASSOC_VECTOR_INT_AGE_OUT 0x4000 W /* portsched on 6065 */
+#define MV88E6XXX_PORT_ASSOC_VECTOR_LOCKED_PORT 0x2000 /* ok */
+#define MV88E6XXX_PORT_ASSOC_VECTOR_IGNORE_WRONG 0x1000 /* ok */
+#define MV88E6XXX_PORT_ASSOC_VECTOR_REFRESH_LOCKED 0x0800 W /* 6065 has agenten */
/* Offset 0x0C: Port ATU Control */
-#define MV88E6XXX_PORT_ATU_CTL 0x0c
+#define MV88E6XXX_PORT_ATU_CTL 0x0c W /* not on 6065? */
/* Offset 0x0D: Priority Override Register */
-#define MV88E6XXX_PORT_PRI_OVERRIDE 0x0d
+#define MV88E6XXX_PORT_PRI_OVERRIDE 0x0d W /* not on 6065? */
/* Offset 0x0E: Policy Control Register */
-#define MV88E6XXX_PORT_POLICY_CTL 0x0e
+#define MV88E6XXX_PORT_POLICY_CTL 0x0e W /* not on 6065? */
/* Offset 0x0F: Port Special Ether Type */
-#define MV88E6XXX_PORT_ETH_TYPE 0x0f
+#define MV88E6XXX_PORT_ETH_TYPE 0x0f W /* not on 6065? */
#define MV88E6XXX_PORT_ETH_TYPE_DEFAULT 0x9100
/* Offset 0x10: InDiscards Low Counter */
-#define MV88E6XXX_PORT_IN_DISCARD_LO 0x10
+#define MV88E6XXX_PORT_IN_DISCARD_LO 0x10 W /* different counter on 6065 */
/* Offset 0x11: InDiscards High Counter */
-#define MV88E6XXX_PORT_IN_DISCARD_HI 0x11
+#define MV88E6XXX_PORT_IN_DISCARD_HI 0x11 W /* different counter on 6065 */
/* Offset 0x12: InFiltered Counter */
-#define MV88E6XXX_PORT_IN_FILTERED 0x12
+#define MV88E6XXX_PORT_IN_FILTERED 0x12 W /* ok, depending on other bit? */
/* Offset 0x13: OutFiltered Counter */
-#define MV88E6XXX_PORT_OUT_FILTERED 0x13
+#define MV88E6XXX_PORT_OUT_FILTERED 0x13 W /* not on 6065 */
/* Offset 0x18: IEEE Priority Mapping Table */
#define MV88E6390_PORT_IEEE_PRIO_MAP_TABLE 0x18
-#define MV88E6390_PORT_IEEE_PRIO_MAP_TABLE_UPDATE 0x8000
-#define MV88E6390_PORT_IEEE_PRIO_MAP_TABLE_MASK 0x7000
-#define MV88E6390_PORT_IEEE_PRIO_MAP_TABLE_INGRESS_PCP 0x0000
-#define MV88E6390_PORT_IEEE_PRIO_MAP_TABLE_EGRESS_GREEN_PCP 0x1000
-#define MV88E6390_PORT_IEEE_PRIO_MAP_TABLE_EGRESS_YELLOW_PCP 0x2000
-#define MV88E6390_PORT_IEEE_PRIO_MAP_TABLE_EGRESS_AVB_PCP 0x3000
-#define MV88E6390_PORT_IEEE_PRIO_MAP_TABLE_EGRESS_GREEN_DSCP 0x5000
-#define MV88E6390_PORT_IEEE_PRIO_MAP_TABLE_EGRESS_YELLOW_DSCP 0x6000
-#define MV88E6390_PORT_IEEE_PRIO_MAP_TABLE_EGRESS_AVB_DSCP 0x7000
-#define MV88E6390_PORT_IEEE_PRIO_MAP_TABLE_PTR_MASK 0x0e00
-#define MV88E6390_PORT_IEEE_PRIO_MAP_TABLE_DATA_MASK 0x01ff
+#define MV88E6390_PORT_IEEE_PRIO_MAP_TABLE_UPDATE 0x8000 W /* reserved on 6065 */
+#define MV88E6390_PORT_IEEE_PRIO_MAP_TABLE_MASK 0x7000 W
+#define MV88E6390_PORT_IEEE_PRIO_MAP_TABLE_INGRESS_PCP 0x0000 W
+#define MV88E6390_PORT_IEEE_PRIO_MAP_TABLE_EGRESS_GREEN_PCP 0x1000 W
+#define MV88E6390_PORT_IEEE_PRIO_MAP_TABLE_EGRESS_YELLOW_PCP 0x2000 W
+#define MV88E6390_PORT_IEEE_PRIO_MAP_TABLE_EGRESS_AVB_PCP 0x3000 W
+#define MV88E6390_PORT_IEEE_PRIO_MAP_TABLE_EGRESS_GREEN_DSCP 0x5000 W
+#define MV88E6390_PORT_IEEE_PRIO_MAP_TABLE_EGRESS_YELLOW_DSCP 0x6000 W
+#define MV88E6390_PORT_IEEE_PRIO_MAP_TABLE_EGRESS_AVB_DSCP 0x7000 W
+#define MV88E6390_PORT_IEEE_PRIO_MAP_TABLE_PTR_MASK 0x0e00 W
+#define MV88E6390_PORT_IEEE_PRIO_MAP_TABLE_DATA_MASK 0x01ff W /* ^^ looks different on 6065 */
/* Offset 0x18: Port IEEE Priority Remapping Registers (0-3) */
-#define MV88E6095_PORT_IEEE_PRIO_REMAP_0123 0x18
+#define MV88E6095_PORT_IEEE_PRIO_REMAP_0123 0x18 W
/* Offset 0x19: Port IEEE Priority Remapping Registers (4-7) */
-#define MV88E6095_PORT_IEEE_PRIO_REMAP_4567 0x19
+#define MV88E6095_PORT_IEEE_PRIO_REMAP_4567 0x19 W
int mv88e6xxx_port_read(struct mv88e6xxx_chip *chip, int port, int reg,
u16 *val);
@@ -289,6 +292,8 @@ int mv88e6095_port_tag_remap(struct mv88e6xxx_chip *chip, int port);
int mv88e6390_port_tag_remap(struct mv88e6xxx_chip *chip, int port);
int mv88e6xxx_port_set_egress_mode(struct mv88e6xxx_chip *chip, int port,
enum mv88e6xxx_egress_mode mode);
+int mv88e6065_port_set_frame_mode(struct mv88e6xxx_chip *chip, int port,
+ enum mv88e6xxx_frame_mode mode);
int mv88e6085_port_set_frame_mode(struct mv88e6xxx_chip *chip, int port,
enum mv88e6xxx_frame_mode mode);
int mv88e6351_port_set_frame_mode(struct mv88e6xxx_chip *chip, int port,
[-- Attachment #2: Digital signature --]
[-- Type: application/pgp-signature, Size: 181 bytes --]
^ permalink raw reply related
* Re: [PATCH net] vhost: fix OOB in get_rx_bufs()
From: Michael S. Tsirkin @ 2019-01-29 22:54 UTC (permalink / raw)
To: David Miller
Cc: jasowang, stefanha, kvm, virtualization, netdev, linux-kernel
In-Reply-To: <20190128.225444.1929870241029842289.davem@davemloft.net>
On Mon, Jan 28, 2019 at 10:54:44PM -0800, David Miller wrote:
> From: Jason Wang <jasowang@redhat.com>
> Date: Mon, 28 Jan 2019 15:05:05 +0800
>
> > After batched used ring updating was introduced in commit e2b3b35eb989
> > ("vhost_net: batch used ring update in rx"). We tend to batch heads in
> > vq->heads for more than one packet. But the quota passed to
> > get_rx_bufs() was not correctly limited, which can result a OOB write
> > in vq->heads.
> >
> > headcount = get_rx_bufs(vq, vq->heads + nvq->done_idx,
> > vhost_len, &in, vq_log, &log,
> > likely(mergeable) ? UIO_MAXIOV : 1);
> >
> > UIO_MAXIOV was still used which is wrong since we could have batched
> > used in vq->heads, this will cause OOB if the next buffer needs more
> > than 960 (1024 (UIO_MAXIOV) - 64 (VHOST_NET_BATCH)) heads after we've
> > batched 64 (VHOST_NET_BATCH) heads:
> ...
> > Fixing this by allocating UIO_MAXIOV + VHOST_NET_BATCH iovs for
> > vhost-net. This is done through set the limitation through
> > vhost_dev_init(), then set_owner can allocate the number of iov in a
> > per device manner.
> >
> > This fixes CVE-2018-16880.
> >
> > Fixes: e2b3b35eb989 ("vhost_net: batch used ring update in rx")
> > Signed-off-by: Jason Wang <jasowang@redhat.com>
>
> Applied and queued up for -stable, thanks!
Wow it seems we are down to hours round time post to queue.
It would be hard to keep up that rate generally.
However, I am guessing this was already in downstreams, and it's a CVE,
so I guess it's a no brainer and review wasn't really necessary - was
that the idea? Just checking.
--
MST
^ permalink raw reply
* Re: [PATCH v2 net 7/7] virtio_net: Differentiate sk_buff and xdp_frame on freeing
From: Michael S. Tsirkin @ 2019-01-29 22:51 UTC (permalink / raw)
To: Toshiaki Makita; +Cc: David S. Miller, Jason Wang, netdev, virtualization
In-Reply-To: <1548722759-2470-8-git-send-email-makita.toshiaki@lab.ntt.co.jp>
On Tue, Jan 29, 2019 at 09:45:59AM +0900, Toshiaki Makita wrote:
> We do not reset or free up unused buffers when enabling/disabling XDP,
> so it can happen that xdp_frames are freed after disabling XDP or
> sk_buffs are freed after enabling XDP on xdp tx queues.
> Thus we need to handle both forms (xdp_frames and sk_buffs) regardless
> of XDP setting.
> One way to trigger this problem is to disable XDP when napi_tx is
> enabled. In that case, virtnet_xdp_set() calls virtnet_napi_enable()
> which kicks NAPI. The NAPI handler will call virtnet_poll_cleantx()
> which invokes free_old_xmit_skbs() for queues which have been used by
> XDP.
>
> Note that even with this change we need to keep skipping
> free_old_xmit_skbs() from NAPI handlers when XDP is enabled, because XDP
> tx queues do not aquire queue locks.
>
> - v2: Use napi_consume_skb() instead of dev_consume_skb_any()
>
> Fixes: 4941d472bf95 ("virtio-net: do not reset during XDP set")
> Signed-off-by: Toshiaki Makita <makita.toshiaki@lab.ntt.co.jp>
Acked-by: Michael S. Tsirkin <mst@redhat.com>
> ---
> NOTE: Dropped Acked-by because of the v2 change.
>
> drivers/net/virtio_net.c | 54 +++++++++++++++++++++++++++++++++++++-----------
> 1 file changed, 42 insertions(+), 12 deletions(-)
>
> diff --git a/drivers/net/virtio_net.c b/drivers/net/virtio_net.c
> index 1d454ce..2594481 100644
> --- a/drivers/net/virtio_net.c
> +++ b/drivers/net/virtio_net.c
> @@ -57,6 +57,8 @@
> #define VIRTIO_XDP_TX BIT(0)
> #define VIRTIO_XDP_REDIR BIT(1)
>
> +#define VIRTIO_XDP_FLAG BIT(0)
> +
> /* RX packet size EWMA. The average packet size is used to determine the packet
> * buffer size when refilling RX rings. As the entire RX ring may be refilled
> * at once, the weight is chosen so that the EWMA will be insensitive to short-
> @@ -252,6 +254,21 @@ struct padded_vnet_hdr {
> char padding[4];
> };
>
> +static bool is_xdp_frame(void *ptr)
> +{
> + return (unsigned long)ptr & VIRTIO_XDP_FLAG;
> +}
> +
> +static void *xdp_to_ptr(struct xdp_frame *ptr)
> +{
> + return (void *)((unsigned long)ptr | VIRTIO_XDP_FLAG);
> +}
> +
> +static struct xdp_frame *ptr_to_xdp(void *ptr)
> +{
> + return (struct xdp_frame *)((unsigned long)ptr & ~VIRTIO_XDP_FLAG);
> +}
> +
> /* Converting between virtqueue no. and kernel tx/rx queue no.
> * 0:rx0 1:tx0 2:rx1 3:tx1 ... 2N:rxN 2N+1:txN 2N+2:cvq
> */
> @@ -462,7 +479,8 @@ static int __virtnet_xdp_xmit_one(struct virtnet_info *vi,
>
> sg_init_one(sq->sg, xdpf->data, xdpf->len);
>
> - err = virtqueue_add_outbuf(sq->vq, sq->sg, 1, xdpf, GFP_ATOMIC);
> + err = virtqueue_add_outbuf(sq->vq, sq->sg, 1, xdp_to_ptr(xdpf),
> + GFP_ATOMIC);
> if (unlikely(err))
> return -ENOSPC; /* Caller handle free/refcnt */
>
> @@ -482,13 +500,13 @@ static int virtnet_xdp_xmit(struct net_device *dev,
> {
> struct virtnet_info *vi = netdev_priv(dev);
> struct receive_queue *rq = vi->rq;
> - struct xdp_frame *xdpf_sent;
> struct bpf_prog *xdp_prog;
> struct send_queue *sq;
> unsigned int len;
> int drops = 0;
> int kicks = 0;
> int ret, err;
> + void *ptr;
> int i;
>
> /* Only allow ndo_xdp_xmit if XDP is loaded on dev, as this
> @@ -507,8 +525,12 @@ static int virtnet_xdp_xmit(struct net_device *dev,
> }
>
> /* Free up any pending old buffers before queueing new ones. */
> - while ((xdpf_sent = virtqueue_get_buf(sq->vq, &len)) != NULL)
> - xdp_return_frame(xdpf_sent);
> + while ((ptr = virtqueue_get_buf(sq->vq, &len)) != NULL) {
> + if (likely(is_xdp_frame(ptr)))
> + xdp_return_frame(ptr_to_xdp(ptr));
> + else
> + napi_consume_skb(ptr, false);
> + }
>
> for (i = 0; i < n; i++) {
> struct xdp_frame *xdpf = frames[i];
> @@ -1329,18 +1351,26 @@ static int virtnet_receive(struct receive_queue *rq, int budget,
>
> static void free_old_xmit_skbs(struct send_queue *sq, bool in_napi)
> {
> - struct sk_buff *skb;
> unsigned int len;
> unsigned int packets = 0;
> unsigned int bytes = 0;
> + void *ptr;
>
> - while ((skb = virtqueue_get_buf(sq->vq, &len)) != NULL) {
> - pr_debug("Sent skb %p\n", skb);
> + while ((ptr = virtqueue_get_buf(sq->vq, &len)) != NULL) {
> + if (likely(!is_xdp_frame(ptr))) {
> + struct sk_buff *skb = ptr;
>
> - bytes += skb->len;
> - packets++;
> + pr_debug("Sent skb %p\n", skb);
>
> - napi_consume_skb(skb, in_napi);
> + bytes += skb->len;
> + napi_consume_skb(skb, in_napi);
> + } else {
> + struct xdp_frame *frame = ptr_to_xdp(ptr);
> +
> + bytes += frame->len;
> + xdp_return_frame(frame);
> + }
> + packets++;
> }
>
> /* Avoid overhead when no packets have been processed
> @@ -2666,10 +2696,10 @@ static void free_unused_bufs(struct virtnet_info *vi)
> for (i = 0; i < vi->max_queue_pairs; i++) {
> struct virtqueue *vq = vi->sq[i].vq;
> while ((buf = virtqueue_detach_unused_buf(vq)) != NULL) {
> - if (!is_xdp_raw_buffer_queue(vi, i))
> + if (!is_xdp_frame(buf))
> dev_kfree_skb(buf);
> else
> - xdp_return_frame(buf);
> + xdp_return_frame(ptr_to_xdp(buf));
> }
> }
>
> --
> 1.8.3.1
>
^ permalink raw reply
page: next (older) | prev (newer) | latest
- recent:[subjects (threaded)|topics (new)|topics (active)]
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox