From ea0993a97c498925d08bb11f05be51455842adc9 Mon Sep 17 00:00:00 2001 From: Mark Carlin Date: Wed, 10 Jan 2024 10:57:18 -0700 Subject: [PATCH 01/27] The cpu RGMII port is now working. Need to pull out debug code and make sure bridging is working properly. Note tags are disabled in this version, and a lot of register values are hacked in. --- drivers/net/dsa/b53/b53_common.c | 44 ++++++++++++------- drivers/net/dsa/b53/b53_spi.c | 9 ++++ .../net/ethernet/stmicro/stmmac/dwmac-stm32.c | 1 + include/net/dsa.h | 1 + net/dsa/dsa.c | 1 + net/dsa/dsa2.c | 28 ++++++++++-- net/dsa/tag_brcm.c | 9 +++- net/dsa/tag_dsa.c | 2 + 8 files changed, 75 insertions(+), 20 deletions(-) diff --git a/drivers/net/dsa/b53/b53_common.c b/drivers/net/dsa/b53/b53_common.c index 66f6e7d33d6193..9c542f40e938d8 100644 --- a/drivers/net/dsa/b53/b53_common.c +++ b/drivers/net/dsa/b53/b53_common.c @@ -624,7 +624,8 @@ void b53_brcm_hdr_setup(struct dsa_switch *ds, int port) bool tag_en = !(dev->tag_protocol == DSA_TAG_PROTO_NONE); u8 hdr_ctl, val; u16 reg; - + dev->tag_protocol = DSA_TAG_PROTO_NONE; + tag_en = 0; /* Resolve which bit controls the Broadcom tag */ switch (port) { case 8: @@ -640,7 +641,7 @@ void b53_brcm_hdr_setup(struct dsa_switch *ds, int port) val = 0; break; } - + printk("dsi-b53_brcm_hdr_setup: port=%d, tag_en=%d, val=%d\n", port, tag_en, val); /* Enable management mode if tagging is requested */ b53_read8(dev, B53_CTRL_PAGE, B53_SWITCH_MODE, &hdr_ctl); if (tag_en) @@ -694,7 +695,7 @@ EXPORT_SYMBOL(b53_brcm_hdr_setup); static void b53_enable_cpu_port(struct b53_device *dev, int port) { u8 port_ctrl; - + printk("dsi-b53_enable_cpu_port: port=%d\n", port); /* BCM5325 CPU port is at 8 */ if ((is5325(dev) || is5365(dev)) && port == B53_CPU_PORT_25) port = B53_CPU_PORT; @@ -1101,7 +1102,7 @@ static int b53_setup(struct dsa_switch *ds) struct b53_device *dev = ds->priv; unsigned int port; int ret; - + printk("dsi-b53_setup\n"); /* Request bridge PVID untagged when DSA_TAG_PROTO_NONE is set * which forces the CPU port to be tagged in all VLANs. */ @@ -1142,7 +1143,7 @@ static void b53_teardown(struct dsa_switch *ds) static void b53_force_link(struct b53_device *dev, int port, int link) { u8 reg, val, off; - + printk("dsi-b53_force_link: port=%d, link=%d\n", port, link); /* Override the port settings */ if (port == dev->imp_port) { off = B53_PORT_OVERRIDE_CTRL; @@ -1166,7 +1167,7 @@ static void b53_force_port_config(struct b53_device *dev, int port, bool tx_pause, bool rx_pause) { u8 reg, val, off; - + printk("dsi-b53_force_port_config: port=%d, speed=%d, duplex=%d, tx_pause=%d, rx_pause=%d\n", port, speed, duplex, tx_pause, rx_pause); /* Override the port settings */ if (port == dev->imp_port) { off = B53_PORT_OVERRIDE_CTRL; @@ -1264,13 +1265,18 @@ static void b53_adjust_link(struct dsa_switch *ds, int port, */ if (phydev->interface == PHY_INTERFACE_MODE_RGMII_TXID) rgmii_ctrl |= RGMII_CTRL_DLL_TXC; + if (phydev->interface == PHY_INTERFACE_MODE_RGMII_RXID) + rgmii_ctrl |= RGMII_CTRL_DLL_RXC; if (phydev->interface == PHY_INTERFACE_MODE_RGMII) - rgmii_ctrl |= RGMII_CTRL_DLL_TXC | RGMII_CTRL_DLL_RXC; - rgmii_ctrl |= RGMII_CTRL_TIMING_SEL; + rgmii_ctrl |= (RGMII_CTRL_DLL_TXC | RGMII_CTRL_DLL_RXC); + //rgmii_ctrl |= RGMII_CTRL_TIMING_SEL; + rgmii_ctrl = (RGMII_CTRL_DLL_TXC | RGMII_CTRL_DLL_RXC); + //rgmii_ctrl = RGMII_CTRL_DLL_TXC; + //rgmii_ctrl = RGMII_CTRL_DLL_RXC; b53_write8(dev, B53_CTRL_PAGE, off, rgmii_ctrl); - dev_info(ds->dev, "Configured port %d for %s\n", port, - phy_modes(phydev->interface)); + dev_info(ds->dev, "Configured port %d for %s (reg=0x%02x)\n", port, + phy_modes(phydev->interface), rgmii_ctrl); } /* configure MII port if necessary */ @@ -2047,7 +2053,8 @@ static bool b53_can_enable_brcm_tags(struct dsa_switch *ds, int port, case DSA_TAG_PROTO_BRCM_PREPEND: dev_warn(ds->dev, "Port %d is stacked to Broadcom tag switch\n", port); - ret = false; + //ret = false; + ret = true; break; default: ret = true; @@ -2061,14 +2068,16 @@ enum dsa_tag_protocol b53_get_tag_protocol(struct dsa_switch *ds, int port, enum dsa_tag_protocol mprot) { struct b53_device *dev = ds->priv; - + printk("dsi-b53_get_tag_protocol: port=%d, mprot=%d\n", port, mprot); if (!b53_can_enable_brcm_tags(ds, port, mprot)) { + printk("dsi-brcm_notags\n"); dev->tag_protocol = DSA_TAG_PROTO_NONE; goto out; } /* Older models require a different 6 byte tag */ if (is5325(dev) || is5365(dev) || is63xx(dev)) { + printk("dsi-brcm_legacy\n"); dev->tag_protocol = DSA_TAG_PROTO_BRCM_LEGACY; goto out; } @@ -2077,12 +2086,15 @@ enum dsa_tag_protocol b53_get_tag_protocol(struct dsa_switch *ds, int port, * which requires us to use the prepended Broadcom tag type */ if (dev->chip_id == BCM58XX_DEVICE_ID && port == B53_CPU_PORT) { + printk("dsi-brcm_prepend\n"); dev->tag_protocol = DSA_TAG_PROTO_BRCM_PREPEND; goto out; } dev->tag_protocol = DSA_TAG_PROTO_BRCM; + printk("dsi-brcm_enable\n"); out: + dev->tag_protocol = DSA_TAG_PROTO_NONE; return dev->tag_protocol; } EXPORT_SYMBOL(b53_get_tag_protocol); @@ -2579,7 +2591,7 @@ static const struct b53_chip_data b53_switch_chips[] = { .vlans = 4096, .enabled_ports = 0x12f, .imp_port = 8, - .cpu_port = B53_CPU_PORT, + .cpu_port = B53_CPU_PORT_25, /* TODO: auto detect */ .vta_regs = B53_VTA_REGS, .arl_bins = 4, .arl_buckets = 1024, @@ -2692,7 +2704,7 @@ struct b53_device *b53_switch_alloc(struct device *base, { struct dsa_switch *ds; struct b53_device *dev; - + printk("dsi-b53_switch_alloc()\n"); ds = devm_kzalloc(base, sizeof(*ds), GFP_KERNEL); if (!ds) return NULL; @@ -2796,7 +2808,7 @@ EXPORT_SYMBOL(b53_switch_detect); int b53_switch_register(struct b53_device *dev) { int ret; - + printk("dsi-b53_switch_register()\n"); if (dev->pdata) { dev->chip_id = dev->pdata->chip_id; dev->enabled_ports = dev->pdata->enabled_ports; @@ -2804,8 +2816,10 @@ int b53_switch_register(struct b53_device *dev) if (!dev->chip_id && b53_switch_detect(dev)) return -EINVAL; + printk("dsi-b53_switch_detect()\n"); ret = b53_switch_init(dev); + printk("dsi-b53_switch_init() ret=%d\n", ret); if (ret) return ret; diff --git a/drivers/net/dsa/b53/b53_spi.c b/drivers/net/dsa/b53/b53_spi.c index 4626bb6a9bd2e8..3738f7d318accd 100644 --- a/drivers/net/dsa/b53/b53_spi.c +++ b/drivers/net/dsa/b53/b53_spi.c @@ -18,6 +18,8 @@ #include +#include + #include #include #include @@ -297,6 +299,13 @@ static int b53_spi_probe(struct spi_device *spi) { struct b53_device *dev; int ret; + struct net_device *ndev = dev_get_by_name(&init_net, "eth0"); + printk("dsi-b53_spi_probe\n"); + if(!ndev) + { + printk("dsi-b53_spi_probe dev is null\n"); + return -EPROBE_DEFER; + } dev = b53_switch_alloc(&spi->dev, &b53_spi_ops, spi); if (!dev) diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac-stm32.c b/drivers/net/ethernet/stmicro/stmmac/dwmac-stm32.c index f0849cf4266f4a..a1843ac1eabd85 100644 --- a/drivers/net/ethernet/stmicro/stmmac/dwmac-stm32.c +++ b/drivers/net/ethernet/stmicro/stmmac/dwmac-stm32.c @@ -409,6 +409,7 @@ static int stm32_dwmac_probe(struct platform_device *pdev) const struct stm32_ops *data; int ret; + printk("stm32_dwmac_probe()\n"); ret = stmmac_get_platform_resources(pdev, &stmmac_res); if (ret) return ret; diff --git a/include/net/dsa.h b/include/net/dsa.h index d784e76113b8d4..d68eea5bf35a5f 100644 --- a/include/net/dsa.h +++ b/include/net/dsa.h @@ -459,6 +459,7 @@ static inline bool dsa_is_unused_port(struct dsa_switch *ds, int p) static inline bool dsa_is_cpu_port(struct dsa_switch *ds, int p) { + printk("dsi-dsa_is_cpu_port: port=%d\n",p); return dsa_to_port(ds, p)->type == DSA_PORT_TYPE_CPU; } diff --git a/net/dsa/dsa.c b/net/dsa/dsa.c index 41f36ad8b0ec67..88eab5cd56e60d 100644 --- a/net/dsa/dsa.c +++ b/net/dsa/dsa.c @@ -56,6 +56,7 @@ void dsa_tag_drivers_register(struct dsa_tag_driver *dsa_tag_driver_array[], unsigned int count, struct module *owner) { unsigned int i; + printk("dsi-dsa_tag_drivers_register() #=%d\n", count); for (i = 0; i < count; i++) dsa_tag_driver_register(dsa_tag_driver_array[i], owner); diff --git a/net/dsa/dsa2.c b/net/dsa/dsa2.c index 34763f575c308c..31157b4eef909c 100644 --- a/net/dsa/dsa2.c +++ b/net/dsa/dsa2.c @@ -1242,11 +1242,15 @@ static enum dsa_tag_protocol dsa_get_tag_protocol(struct dsa_port *dp, mdp_upstream = dsa_upstream_port(mds, mdp->index); tag_protocol = mds->ops->get_tag_protocol(mds, mdp_upstream, DSA_TAG_PROTO_NONE); + printk("dsi-dsa_get_tag_protocol_slave tag_protocol=%d\n", tag_protocol); } /* If the master device is not itself a DSA slave in a disjoint DSA * tree, then return immediately. */ + tag_protocol = ds->ops->get_tag_protocol(ds, dp->index, tag_protocol); + printk("dsi-dsa_get_tag_protocol tag_protocol=%d\n", tag_protocol); + return ds->ops->get_tag_protocol(ds, dp->index, tag_protocol); } @@ -1369,6 +1373,7 @@ static int dsa_switch_parse_ports_of(struct dsa_switch *ds, struct dsa_port *dp; int err = 0; u32 reg; + int np = 0; ports = of_get_child_by_name(dn, "ports"); if (!ports) { @@ -1382,6 +1387,7 @@ static int dsa_switch_parse_ports_of(struct dsa_switch *ds, for_each_available_child_of_node(ports, port) { err = of_property_read_u32(port, "reg", ®); + printk("dsi-for_each_available_child_of_node-of_property_read_u32 err=%d (%d)\n", err, np); if (err) { of_node_put(port); goto out_put_node; @@ -1398,10 +1404,12 @@ static int dsa_switch_parse_ports_of(struct dsa_switch *ds, dp = dsa_to_port(ds, reg); err = dsa_port_parse_of(dp, port); + printk("dsi-dsa_port_parse_of err=%d (%d)\n", err, np); if (err) { of_node_put(port); goto out_put_node; } + np++; } out_put_node: @@ -1414,9 +1422,10 @@ static int dsa_switch_parse_member_of(struct dsa_switch *ds, { u32 m[2] = { 0, 0 }; int sz; - + printk("dsi-dsa_switch_parse_member_of\n"); /* Don't error out if this optional property isn't found */ sz = of_property_read_variable_u32_array(dn, "dsa,member", m, 2, 2); + printk("dsi-of_property_read_variable_u32_array sz=%d\n", sz); if (sz < 0 && sz != -EINVAL) return sz; @@ -1456,16 +1465,20 @@ static int dsa_switch_touch_ports(struct dsa_switch *ds) static int dsa_switch_parse_of(struct dsa_switch *ds, struct device_node *dn) { int err; - + printk("dsi-dsa_switch_parse_of\n"); err = dsa_switch_parse_member_of(ds, dn); + printk("dsi-dsa_switch_parse_member_of err=%d\n", err); if (err) return err; err = dsa_switch_touch_ports(ds); + printk("dsi-dsa_switch_touch_ports err=%d\n", err); if (err) return err; - return dsa_switch_parse_ports_of(ds, dn); + err = dsa_switch_parse_ports_of(ds, dn); + printk("dsi-dsa_switch_parse_ports_of err=%d\n", err); + return err; } static int dsa_port_parse(struct dsa_port *dp, const char *name, @@ -1560,7 +1573,7 @@ static int dsa_switch_probe(struct dsa_switch *ds) struct dsa_chip_data *pdata; struct device_node *np; int err; - + printk("dsi-dsa_switch_probe\n"); if (!ds->dev) return -ENODEV; @@ -1569,25 +1582,30 @@ static int dsa_switch_probe(struct dsa_switch *ds) if (!ds->num_ports) return -EINVAL; + printk("dsi-dsa_switch_probe ds->num_ports=%d\n", ds->num_ports); if (np) { err = dsa_switch_parse_of(ds, np); + printk("dsi-dsa_switch_parse_of err=%d\n", err); if (err) dsa_switch_release_ports(ds); } else if (pdata) { err = dsa_switch_parse(ds, pdata); + printk("dsi-dsa_switch_parse err=%d\n", err); if (err) dsa_switch_release_ports(ds); } else { err = -ENODEV; } + printk("dsi-dsa_err=%d\n", err); if (err) return err; dst = ds->dst; dsa_tree_get(dst); err = dsa_tree_setup(dst); + printk("dsi-dsa_tree_setup err=%d\n", err); if (err) { dsa_switch_release_ports(ds); dsa_tree_put(dst); @@ -1600,8 +1618,10 @@ int dsa_register_switch(struct dsa_switch *ds) { int err; + printk("dsi-dsa_register_switch\n"); mutex_lock(&dsa2_mutex); err = dsa_switch_probe(ds); + printk("dsi-dsa_switch_probe err=%d\n", err); dsa_tree_put(ds->dst); mutex_unlock(&dsa2_mutex); diff --git a/net/dsa/tag_brcm.c b/net/dsa/tag_brcm.c index ed5f68c4f1dad1..3f3f22549f0bf4 100644 --- a/net/dsa/tag_brcm.c +++ b/net/dsa/tag_brcm.c @@ -5,6 +5,7 @@ * Copyright (C) 2014 Broadcom Corporation */ +#include #include #include #include @@ -85,6 +86,7 @@ static struct sk_buff *brcm_tag_xmit_ll(struct sk_buff *skb, u16 queue = skb_get_queue_mapping(skb); u8 *brcm_tag; + //printk("brcm_tag_xmit_ll()\n"); /* The Ethernet switch we are interfaced with needs packets to be at * least 64 bytes (including FCS) otherwise they will be discarded when * they enter the switch port logic. When Broadcom tags are enabled, we @@ -140,8 +142,9 @@ static struct sk_buff *brcm_tag_rcv_ll(struct sk_buff *skb, unsigned int offset) { int source_port; + int i; u8 *brcm_tag; - + //printk("brcm_tag_rcv_ll()\n"); if (unlikely(!pskb_may_pull(skb, BRCM_TAG_LEN))) return NULL; @@ -151,6 +154,10 @@ static struct sk_buff *brcm_tag_rcv_ll(struct sk_buff *skb, if (unlikely((brcm_tag[0] >> BRCM_OPCODE_SHIFT) & BRCM_OPCODE_MASK)) return NULL; + // for( i = 0; i < 16; i++) + // printk("%02x, ", brcm_tag[i]); + // printk("\n"); + /* We should never see a reserved reason code without knowing how to * handle it */ diff --git a/net/dsa/tag_dsa.c b/net/dsa/tag_dsa.c index b3da4b2ea11cf6..de572ff46819c4 100644 --- a/net/dsa/tag_dsa.c +++ b/net/dsa/tag_dsa.c @@ -130,6 +130,7 @@ static struct sk_buff *dsa_xmit_ll(struct sk_buff *skb, struct net_device *dev, u8 tag_dev, tag_port; enum dsa_cmd cmd; u8 *dsa_header; + printk("dsi-dsa_xmit_ll()\n"); if (skb->offload_fwd_mark) { struct dsa_switch_tree *dst = dp->ds->dst; @@ -193,6 +194,7 @@ static struct sk_buff *dsa_rcv_ll(struct sk_buff *skb, struct net_device *dev, enum dsa_code code; enum dsa_cmd cmd; u8 *dsa_header; + prinkt("dsa_rcv_ll()\n"); /* The ethertype field is part of the DSA header. */ dsa_header = dsa_etype_header_pos_rx(skb); From fc8c491733c53a6f8a71434879748c879aadfb18 Mon Sep 17 00:00:00 2001 From: Mark Carlin Date: Wed, 10 Jan 2024 10:58:47 -0700 Subject: [PATCH 02/27] Update kernel version identifier to datum.3 --- Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Makefile b/Makefile index e25606177cf1f8..e2e6bbb3936185 100644 --- a/Makefile +++ b/Makefile @@ -2,7 +2,7 @@ VERSION = 5 PATCHLEVEL = 15 SUBLEVEL = 107 -EXTRAVERSION = -datum.2 +EXTRAVERSION = -datum.3 NAME = Trick or Treat # *DOCUMENTATION* From 4b784273ca18f72faf7a424c73188f58e98aa47a Mon Sep 17 00:00:00 2001 From: Mark Carlin Date: Sat, 20 Jan 2024 20:54:09 -0700 Subject: [PATCH 03/27] Checkpointing here as the port-based vlans are working on the driver level. Still need to test if they are maintained through port enables/disables. Also need to do lots of cleanup, there's a lot a test code in there. --- drivers/net/dsa/b53/b53_common.c | 70 ++++++++++++++++++++++++++------ drivers/net/dsa/bcm_sf2.c | 4 +- include/net/dsa.h | 6 +++ net/dsa/dsa2.c | 9 ++-- net/dsa/master.c | 61 ++++++++++++++++++++++++++++ 5 files changed, 133 insertions(+), 17 deletions(-) diff --git a/drivers/net/dsa/b53/b53_common.c b/drivers/net/dsa/b53/b53_common.c index 9c542f40e938d8..cf653064fe1abd 100644 --- a/drivers/net/dsa/b53/b53_common.c +++ b/drivers/net/dsa/b53/b53_common.c @@ -500,7 +500,7 @@ void b53_imp_vlan_setup(struct dsa_switch *ds, int cpu_port) struct b53_device *dev = ds->priv; unsigned int i; u16 pvlan; - + printk("dsi-b53_imp_vlan_setup: cpu_port=%d\n", cpu_port); /* Enable the IMP port to be in the same VLAN as the other ports * on a per-port basis such that we only have Port i and IMP in * the same VLAN. @@ -565,7 +565,7 @@ int b53_enable_port(struct dsa_switch *ds, int port, struct phy_device *phy) unsigned int cpu_port; int ret = 0; u16 pvlan; - + printk("dsi-b53_enable_port: port=%d\n", port); if (!dsa_is_user_port(ds, port)) return 0; @@ -593,7 +593,7 @@ int b53_enable_port(struct dsa_switch *ds, int port, struct phy_device *phy) pvlan |= dev->ports[port].vlan_ctl_mask; b53_write16(dev, B53_PVLAN_PAGE, B53_PVLAN_PORT_MASK(port), pvlan); - b53_imp_vlan_setup(ds, cpu_port); + //b53_imp_vlan_setup(ds, cpu_port); /* If EEE was enabled, restore it */ if (dev->ports[port].eee.eee_enabled) @@ -607,7 +607,7 @@ void b53_disable_port(struct dsa_switch *ds, int port) { struct b53_device *dev = ds->priv; u8 reg; - + printk("dsi-b53_disable_port: port=%d\n", port); /* Disable Tx/Rx for the port */ b53_read8(dev, B53_CTRL_PAGE, B53_PORT_CTRL(port), ®); reg |= PORT_CTRL_RX_DISABLE | PORT_CTRL_TX_DISABLE; @@ -1131,6 +1131,11 @@ static int b53_setup(struct dsa_switch *ds) else b53_disable_port(ds, port); } + /* Disable all port based VLANs on powerup. Userspace configuration + * will enable them as needed. + */ + for (port = 0; port < dev->num_ports; port++) + b53_write16(dev, B53_PVLAN_PAGE, B53_PVLAN_PORT_MASK(port), 0x00); return b53_setup_devlink_resources(ds); } @@ -1369,7 +1374,7 @@ int b53_phylink_mac_link_state(struct dsa_switch *ds, int port, { struct b53_device *dev = ds->priv; int ret = -EOPNOTSUPP; - + printk("dsi-b53_phylink_mac_link_state: port=%d\n", port); if ((phy_interface_mode_is_8023z(state->interface) || state->interface == PHY_INTERFACE_MODE_SGMII) && dev->ops->serdes_link_state) @@ -1384,7 +1389,7 @@ void b53_phylink_mac_config(struct dsa_switch *ds, int port, const struct phylink_link_state *state) { struct b53_device *dev = ds->priv; - + printk("dsi-b53_phylink_mac_config: port=%d, mode=%d\n", port, mode); if (mode == MLO_AN_PHY || mode == MLO_AN_FIXED) return; @@ -1398,7 +1403,7 @@ EXPORT_SYMBOL(b53_phylink_mac_config); void b53_phylink_mac_an_restart(struct dsa_switch *ds, int port) { struct b53_device *dev = ds->priv; - + printk("dsi-b53_phylink_mac_an_restart: port=%d\n", port); if (dev->ops->serdes_an_restart) dev->ops->serdes_an_restart(dev, port); } @@ -1409,7 +1414,7 @@ void b53_phylink_mac_link_down(struct dsa_switch *ds, int port, phy_interface_t interface) { struct b53_device *dev = ds->priv; - + printk("dsi-b53_phylink_mac_link_down: port=%d, mode=%d\n", port, mode); if (mode == MLO_AN_PHY) return; @@ -1433,6 +1438,7 @@ void b53_phylink_mac_link_up(struct dsa_switch *ds, int port, { struct b53_device *dev = ds->priv; + printk("dsi-b53_phylink_mac_link_up: port=%d, mode=%d, speed=%d, duplex=%d, tx_pause=%d, rx_pause=%d\n", port, mode, speed, duplex, tx_pause, rx_pause); if (mode == MLO_AN_PHY) return; @@ -1446,6 +1452,8 @@ void b53_phylink_mac_link_up(struct dsa_switch *ds, int port, if (phy_interface_mode_is_8023z(interface) && dev->ops->serdes_link_set) dev->ops->serdes_link_set(dev, port, mode, interface, true); + + } EXPORT_SYMBOL(b53_phylink_mac_link_up); @@ -1859,7 +1867,7 @@ int b53_br_join(struct dsa_switch *ds, int port, struct net_device *br) s8 cpu_port = dsa_to_port(ds, port)->cpu_dp->index; u16 pvlan, reg; unsigned int i; - + printk("dsi-b53_br_join: port=%d\n", port); /* On 7278, port 7 which connects to the ASP should only receive * traffic from matching CFP rules. */ @@ -1900,6 +1908,12 @@ int b53_br_join(struct dsa_switch *ds, int port, struct net_device *br) b53_write16(dev, B53_PVLAN_PAGE, B53_PVLAN_PORT_MASK(port), pvlan); dev->ports[port].vlan_ctl_mask = pvlan; + b53_for_each_port(dev, i) { + b53_read16(dev, B53_PVLAN_PAGE, B53_PVLAN_PORT_MASK(i), ®); + printk("b53_br_join: port=%d, PORT_VLAN_CTL==0x%04x\n", i, reg); + } + + return 0; } EXPORT_SYMBOL(b53_br_join); @@ -1911,7 +1925,7 @@ void b53_br_leave(struct dsa_switch *ds, int port, struct net_device *br) s8 cpu_port = dsa_to_port(ds, port)->cpu_dp->index; unsigned int i; u16 pvlan, reg, pvid; - + printk("dsi-b53_br_leave: port=%d\n", port); b53_read16(dev, B53_PVLAN_PAGE, B53_PVLAN_PORT_MASK(port), &pvlan); b53_for_each_port(dev, i) { @@ -1947,6 +1961,11 @@ void b53_br_leave(struct dsa_switch *ds, int port, struct net_device *br) vl->untag |= BIT(port) | BIT(cpu_port); b53_set_vlan_entry(dev, pvid, vl); } + b53_for_each_port(dev, i) { + b53_read16(dev, B53_PVLAN_PAGE, B53_PVLAN_PORT_MASK(i), ®); + printk("b53_br_leave: port=%d, PORT_VLAN_CTL==0x%04x\n", i, reg); + } + } EXPORT_SYMBOL(b53_br_leave); @@ -1997,6 +2016,7 @@ int b53_br_flags_pre(struct dsa_switch *ds, int port, struct switchdev_brport_flags flags, struct netlink_ext_ack *extack) { + printk("dsi-b53_br_flags_pre: port=%d, flags.val=0x%08lx val.mask=0x%08lx\n", port, flags.val, flags.mask); if (flags.mask & ~(BR_FLOOD | BR_MCAST_FLOOD | BR_LEARNING)) return -EINVAL; @@ -2008,6 +2028,7 @@ int b53_br_flags(struct dsa_switch *ds, int port, struct switchdev_brport_flags flags, struct netlink_ext_ack *extack) { + printk("dsi-b53_br_flags: port=%d, flags.val=0x%08lx val.mask=0x%08lx\n", port, flags.val, flags.mask); if (flags.mask & BR_FLOOD) b53_port_set_ucast_flood(ds->priv, port, !!(flags.val & BR_FLOOD)); @@ -2104,7 +2125,7 @@ int b53_mirror_add(struct dsa_switch *ds, int port, { struct b53_device *dev = ds->priv; u16 reg, loc; - + printk("dsi-b53_mirror_add: port=%d, mirror->to_local_port=%d, mirror->ingress=%d, ingress=%d\n", port, mirror->to_local_port, mirror->ingress, ingress); if (ingress) loc = B53_IG_MIR_CTL; else @@ -2130,7 +2151,7 @@ void b53_mirror_del(struct dsa_switch *ds, int port, struct b53_device *dev = ds->priv; bool loc_disable = false, other_loc_disable = false; u16 reg, loc; - + printk("dsi-b53_mirror_del: port=%d, mirror->to_local_port=%d, mirror->ingress=%d\n", port, mirror->to_local_port, mirror->ingress); if (mirror->ingress) loc = B53_IG_MIR_CTL; else @@ -2234,7 +2255,7 @@ static int b53_change_mtu(struct dsa_switch *ds, int port, int mtu) if (is5325(dev) || is5365(dev)) return -EOPNOTSUPP; - + printk("dsi-b53_change_mtu: port=%d, mtu=%d\n", port, mtu); enable_jumbo = (mtu >= JMS_MIN_SIZE); allow_10_100 = (dev->chip_id == BCM583XX_DEVICE_ID); @@ -2246,6 +2267,27 @@ static int b53_get_max_mtu(struct dsa_switch *ds, int port) return JMS_MAX_SIZE; } +static int b53_port_change_pvlan(struct dsa_switch *ds, int port, u16 mask) +{ + struct b53_device *dev = ds->priv; + + printk("dsi-b53_port_change_pvlan: port=%d, mask=0x%04hx\n", port, mask); + b53_write16(dev, B53_PVLAN_PAGE, B53_PVLAN_PORT_MASK(port), mask); + dev->ports[port].vlan_ctl_mask = mask; + return 0; +} + +static int b53_port_get_pvlan(struct dsa_switch *ds, int port, u16 *mask) +{ + struct b53_device *dev = ds->priv; + u16 reg; + b53_read16(dev, B53_PVLAN_PAGE, B53_PVLAN_PORT_MASK(port), ®); + *mask = reg & 0x1ff; + printk("dsi-b53_port_get_pvlan: port=%d, mask=0x%04hx\n", port, *mask); + + return 0; +} + static const struct dsa_switch_ops b53_switch_ops = { .get_tag_protocol = b53_get_tag_protocol, .setup = b53_setup, @@ -2285,6 +2327,8 @@ static const struct dsa_switch_ops b53_switch_ops = { .port_mdb_del = b53_mdb_del, .port_max_mtu = b53_get_max_mtu, .port_change_mtu = b53_change_mtu, + .port_change_pvlan = b53_port_change_pvlan, + .port_get_pvlan = b53_port_get_pvlan }; struct b53_chip_data { diff --git a/drivers/net/dsa/bcm_sf2.c b/drivers/net/dsa/bcm_sf2.c index d76b2377d66ef1..bb9097a424c1ef 100644 --- a/drivers/net/dsa/bcm_sf2.c +++ b/drivers/net/dsa/bcm_sf2.c @@ -1336,7 +1336,9 @@ static int bcm_sf2_sw_probe(struct platform_device *pdev) unsigned int i; u32 reg, rev; int ret; - + + printk("bcm_sf2_sw_probe\n"); + priv = devm_kzalloc(&pdev->dev, sizeof(*priv), GFP_KERNEL); if (!priv) return -ENOMEM; diff --git a/include/net/dsa.h b/include/net/dsa.h index d68eea5bf35a5f..c4905b1b0d927c 100644 --- a/include/net/dsa.h +++ b/include/net/dsa.h @@ -906,6 +906,12 @@ struct dsa_switch_ops { int (*tag_8021q_vlan_add)(struct dsa_switch *ds, int port, u16 vid, u16 flags); int (*tag_8021q_vlan_del)(struct dsa_switch *ds, int port, u16 vid); + + /* + * Port-based VLAN operations + */ + int (*port_change_pvlan)(struct dsa_switch *ds, int port, u16 mask); + int (*port_get_pvlan)(struct dsa_switch *ds, int port, u16 *mask); }; #define DSA_DEVLINK_PARAM_DRIVER(_id, _name, _type, _cmodes) \ diff --git a/net/dsa/dsa2.c b/net/dsa/dsa2.c index 31157b4eef909c..5249f347750ca4 100644 --- a/net/dsa/dsa2.c +++ b/net/dsa/dsa2.c @@ -858,6 +858,7 @@ static int dsa_switch_setup(struct dsa_switch *ds) * setup() can register regions etc, against the ports */ list_for_each_entry(dp, &ds->dst->ports, list) { + printk("dsi-dsa_switch_setup dp->index=%d\n", dp->index); if (dp->ds == ds) { err = dsa_port_devlink_setup(dp); if (err) @@ -982,6 +983,7 @@ static int dsa_tree_setup_switches(struct dsa_switch_tree *dst) int err; list_for_each_entry(dp, &dst->ports, list) { + printk("dsi-dsa_tree_setup_switches dp->index=%d\n", dp->index); err = dsa_switch_setup(dp->ds); if (err) goto teardown; @@ -1516,6 +1518,7 @@ static int dsa_switch_parse_ports(struct dsa_switch *ds, name = cd->port_names[i]; dev = cd->netdev[i]; dp = dsa_to_port(ds, i); + printk("dsi-dsa_switch_parse_ports i=%d name=%s dev=%p\n", i, name, dev); if (!name) continue; @@ -1582,7 +1585,7 @@ static int dsa_switch_probe(struct dsa_switch *ds) if (!ds->num_ports) return -EINVAL; - printk("dsi-dsa_switch_probe ds->num_ports=%d\n", ds->num_ports); + printk("dsi-dsa_switch_probe entry ds->num_ports=%d\n", ds->num_ports); if (np) { err = dsa_switch_parse_of(ds, np); @@ -1598,7 +1601,7 @@ static int dsa_switch_probe(struct dsa_switch *ds) err = -ENODEV; } - printk("dsi-dsa_err=%d\n", err); + printk("dsi-dsa_switch_probe mid err=%d\n", err); if (err) return err; @@ -1610,7 +1613,7 @@ static int dsa_switch_probe(struct dsa_switch *ds) dsa_switch_release_ports(ds); dsa_tree_put(dst); } - + printk("dsi-dsa_switch_probe exit err=%d\n", err); return err; } diff --git a/net/dsa/master.c b/net/dsa/master.c index 69ec510abe83cb..bcb7326a74dad0 100644 --- a/net/dsa/master.c +++ b/net/dsa/master.c @@ -319,8 +319,68 @@ static ssize_t tagging_store(struct device *d, struct device_attribute *attr, } static DEVICE_ATTR_RW(tagging); +static ssize_t pvlan_show(struct device *d, struct device_attribute *attr, + char *buf) +{ + struct net_device *dev = to_net_dev(d); + struct dsa_port *cpu_dp = dev->dsa_ptr; + struct dsa_switch_tree *dst = cpu_dp->ds->dst; + struct dsa_port *dp; + int i, len = 0; + u16 value; + + list_for_each_entry(dp, &dst->ports, list) { + if (dp->type |= DSA_PORT_TYPE_UNUSED) { + if(!dp->ds->ops->port_change_pvlan) + return -EOPNOTSUPP; + dp->ds->ops->port_get_pvlan(dp->ds, dp->index, &value); + len += sprintf(buf + len, "%d:%02hx ", dp->index, value); + printk("dsi-pvlan_show %d:%02hx\n", dp->index, dp->index); + } + } + + len += sprintf(buf + len, "\n"); + + return len; +} + +static ssize_t pvlan_store(struct device *d, struct device_attribute *attr, + const char *buf, size_t count) +{ + struct net_device *dev = to_net_dev(d); + struct dsa_port *cpu_dp = dev->dsa_ptr; + struct dsa_switch_tree *dst = cpu_dp->ds->dst; + struct dsa_switch *ds = cpu_dp->ds; + struct dsa_port *dp; + int index; + u16 value; + int err; + + // Parse the input + err = sscanf(buf, "%d:%hx", &index, &value); + if (err != 2) + return -EINVAL; // Invalid format + + // Find the port with the given index + list_for_each_entry(dp, &dst->ports, list) { + if (dp->index == index && dp->type != DSA_PORT_TYPE_UNUSED) { + if(!dp->ds->ops->port_get_pvlan) + return -EOPNOTSUPP; + // Apply the new value + dp->ds->ops->port_change_pvlan(ds, index, value); + return count; + } + } + + // No port with the given index was found + return -EINVAL; +} + +static DEVICE_ATTR_RW(pvlan); + static struct attribute *dsa_slave_attrs[] = { &dev_attr_tagging.attr, + &dev_attr_pvlan.attr, NULL }; @@ -329,6 +389,7 @@ static const struct attribute_group dsa_group = { .attrs = dsa_slave_attrs, }; + static void dsa_master_reset_mtu(struct net_device *dev) { int err; From 608bb0f9b013f3a36bab27bad69a954b5a0826b8 Mon Sep 17 00:00:00 2001 From: Mark Carlin Date: Sun, 21 Jan 2024 13:53:46 -0700 Subject: [PATCH 04/27] Add some lower level sysfs functions. --- drivers/net/dsa/b53/b53_common.c | 58 ++++++++++++ drivers/net/dsa/b53/b53_priv.h | 5 + drivers/net/dsa/bcm_sf2.c | 1 + include/net/dsa.h | 7 ++ net/dsa/dsa2.c | 9 +- net/dsa/master.c | 156 +++++++++++++++++++++++++++++-- 6 files changed, 228 insertions(+), 8 deletions(-) diff --git a/drivers/net/dsa/b53/b53_common.c b/drivers/net/dsa/b53/b53_common.c index cf653064fe1abd..58883968e6933a 100644 --- a/drivers/net/dsa/b53/b53_common.c +++ b/drivers/net/dsa/b53/b53_common.c @@ -2288,6 +2288,61 @@ static int b53_port_get_pvlan(struct dsa_switch *ds, int port, u16 *mask) return 0; } +static int b53_switch_setup_get_reg(struct dsa_switch *ds, u8 page, u8 reg, u8 size) +{ + struct b53_device *dev = ds->priv; + + dev->page = page; + dev->reg = reg; + dev->size = size; + + return 0; +} + +static int b53_switch_get_reg(struct dsa_switch *ds, u64 *value) +{ + struct b53_device *dev = ds->priv; + + switch(dev->size) { + case 1: + return b53_read8(dev, dev->page, dev->reg, value); + case 2: + return b53_read16(dev, dev->page, dev->reg, value); + case 4: + return b53_read32(dev, dev->page, dev->reg, value); + case 6: + return b53_read48(dev, dev->page, dev->reg, value); + case 8: + return b53_read64(dev, dev->page, dev->reg, value); + default: + return -EINVAL; + } + + return 0; +} + +static int b53_switch_set_reg(struct dsa_switch *ds, u8 page, u8 reg, u8 size, u64 value) +{ + struct b53_device *dev = ds->priv; + + switch(size) { + case 1: + return b53_write8(dev, page, reg, (u8)value); + case 2: + return b53_write16(dev, page, reg, (u16)value); + case 4: + return b53_write32(dev, page, reg, (u32)value); + case 6: + return b53_write48(dev, page, reg, (u64)value); + case 8: + return b53_write64(dev, page, reg, (u64)value); + default: + return -EINVAL; + } + + return 0; +} + static const struct dsa_switch_ops b53_switch_ops = { .get_tag_protocol = b53_get_tag_protocol, .setup = b53_setup, @@ -2329,6 +2384,9 @@ static const struct dsa_switch_ops b53_switch_ops = { .port_change_mtu = b53_change_mtu, .port_change_pvlan = b53_port_change_pvlan, .port_get_pvlan = b53_port_get_pvlan + .switch_setup_get_reg = b53_switch_setup_get_reg, + .switch_get_reg = b53_switch_get_reg, + .switch_set_reg = b53_switch_set_reg }; struct b53_chip_data { diff --git a/drivers/net/dsa/b53/b53_priv.h b/drivers/net/dsa/b53/b53_priv.h index 57ca977e80ca45..5f805661b4d52e 100644 --- a/drivers/net/dsa/b53/b53_priv.h +++ b/drivers/net/dsa/b53/b53_priv.h @@ -122,6 +122,11 @@ struct b53_device { u16 num_arl_buckets; enum dsa_tag_protocol tag_protocol; + /* raw register read data*/ + u8 page; + u8 reg; + u8 size; + /* used ports mask */ u16 enabled_ports; unsigned int imp_port; diff --git a/drivers/net/dsa/bcm_sf2.c b/drivers/net/dsa/bcm_sf2.c index bb9097a424c1ef..21d6250a70ee36 100644 --- a/drivers/net/dsa/bcm_sf2.c +++ b/drivers/net/dsa/bcm_sf2.c @@ -110,6 +110,7 @@ static void bcm_sf2_imp_setup(struct dsa_switch *ds, int port) struct bcm_sf2_priv *priv = bcm_sf2_to_priv(ds); unsigned int i; u32 reg, offset; + printk("dsi-bcm_sf2_imp_setup(): port=%d\n", port); /* Enable the port memories */ reg = core_readl(priv, CORE_MEM_PSM_VDD_CTRL); diff --git a/include/net/dsa.h b/include/net/dsa.h index c4905b1b0d927c..0aa2420c8d593b 100644 --- a/include/net/dsa.h +++ b/include/net/dsa.h @@ -912,6 +912,13 @@ struct dsa_switch_ops { */ int (*port_change_pvlan)(struct dsa_switch *ds, int port, u16 mask); int (*port_get_pvlan)(struct dsa_switch *ds, int port, u16 *mask); + + /* + * Switch low level register read/write + */ + int (*switch_setup_get_reg)(struct dsa_switch *ds, u8 page, u8 reg, u8 size); + int (*switch_get_reg)(struct dsa_switch *ds, u64 *value); + int (*switch_set_reg)(struct dsa_switch *ds, u8 page, u8 reg, u8 size, u64 value); }; #define DSA_DEVLINK_PARAM_DRIVER(_id, _name, _type, _cmodes) \ diff --git a/net/dsa/dsa2.c b/net/dsa/dsa2.c index 5249f347750ca4..23b31bbc2ea869 100644 --- a/net/dsa/dsa2.c +++ b/net/dsa/dsa2.c @@ -990,11 +990,13 @@ static int dsa_tree_setup_switches(struct dsa_switch_tree *dst) } list_for_each_entry(dp, &dst->ports, list) { + printk("dsi-dsa_tree_setup_ports dp->index=%d\n", dp->index); err = dsa_port_setup(dp); if (err) { err = dsa_port_reinit_as_unused(dp); if (err) goto teardown; + printk("dsi-dsa_port_reinit_as_unused dp->index=%d\n", dp->index); } } @@ -1015,6 +1017,7 @@ static int dsa_tree_setup_master(struct dsa_switch_tree *dst) list_for_each_entry(dp, &dst->ports, list) { if (dsa_port_is_cpu(dp)) { + printk("dsi-dsa_tree_setup_master (is cpu) dp->index=%d\n", dp->index); err = dsa_master_setup(dp->master, dp); if (err) return err; @@ -1264,6 +1267,7 @@ static int dsa_port_parse_cpu(struct dsa_port *dp, struct net_device *master, struct dsa_switch_tree *dst = ds->dst; enum dsa_tag_protocol default_proto; + printk("dsi-dsa_port_parse_cpu: index=%d\n", dp->index); /* Find out which protocol the switch would prefer. */ default_proto = dsa_get_tag_protocol(dp, master); if (dst->default_proto) { @@ -1341,14 +1345,16 @@ static int dsa_port_parse_cpu(struct dsa_port *dp, struct net_device *master, return 0; } + static int dsa_port_parse_of(struct dsa_port *dp, struct device_node *dn) { struct device_node *ethernet = of_parse_phandle(dn, "ethernet", 0); const char *name = of_get_property(dn, "label", NULL); bool link = of_property_read_bool(dn, "link"); + bool port_imp = of_property_read_bool(dn, "port-imp"); dp->dn = dn; - + printk("dsi-dsa_port_parse_of: index=%d, ethernet=%p, name=%s, link=%d\n", dp->index, ethernet, name, link); if (ethernet) { struct net_device *master; const char *user_protocol; @@ -1368,6 +1374,7 @@ static int dsa_port_parse_of(struct dsa_port *dp, struct device_node *dn) return dsa_port_parse_user(dp, name); } + static int dsa_switch_parse_ports_of(struct dsa_switch *ds, struct device_node *dn) { diff --git a/net/dsa/master.c b/net/dsa/master.c index bcb7326a74dad0..f959974612d47f 100644 --- a/net/dsa/master.c +++ b/net/dsa/master.c @@ -271,7 +271,7 @@ static void dsa_master_set_promiscuity(struct net_device *dev, int inc) rtnl_unlock(); } -static ssize_t tagging_show(struct device *d, struct device_attribute *attr, +static ssize_t tagging_cpu_show(struct device *d, struct device_attribute *attr, char *buf) { struct net_device *dev = to_net_dev(d); @@ -281,7 +281,7 @@ static ssize_t tagging_show(struct device *d, struct device_attribute *attr, dsa_tag_protocol_to_str(cpu_dp->tag_ops)); } -static ssize_t tagging_store(struct device *d, struct device_attribute *attr, +static ssize_t tagging_cpu_store(struct device *d, struct device_attribute *attr, const char *buf, size_t count) { const struct dsa_device_ops *new_tag_ops, *old_tag_ops; @@ -317,7 +317,55 @@ static ssize_t tagging_store(struct device *d, struct device_attribute *attr, dsa_tag_driver_put(old_tag_ops); return count; } -static DEVICE_ATTR_RW(tagging); +static DEVICE_ATTR_RW(tagging_cpu); + +static ssize_t tagging_imp_show(struct device *d, struct device_attribute *attr, + char *buf) +{ + struct net_device *dev = to_net_dev(d); + struct dsa_port *cpu_dp = dev->dsa_ptr; + + return sprintf(buf, "%s\n", + dsa_tag_protocol_to_str(cpu_dp->tag_ops)); +} + +static ssize_t tagging_imp_store(struct device *d, struct device_attribute *attr, + const char *buf, size_t count) +{ + const struct dsa_device_ops *new_tag_ops, *old_tag_ops; + struct net_device *dev = to_net_dev(d); + struct dsa_port *cpu_dp = dev->dsa_ptr; + int err; + + old_tag_ops = cpu_dp->tag_ops; + new_tag_ops = dsa_find_tagger_by_name(buf); + /* Bad tagger name, or module is not loaded? */ + if (IS_ERR(new_tag_ops)) + return PTR_ERR(new_tag_ops); + + if (new_tag_ops == old_tag_ops) + /* Drop the temporarily held duplicate reference, since + * the DSA switch tree uses this tagger. + */ + goto out; + + err = dsa_tree_change_tag_proto(cpu_dp->ds->dst, dev, new_tag_ops, + old_tag_ops); + if (err) { + /* On failure the old tagger is restored, so we don't need the + * driver for the new one. + */ + dsa_tag_driver_put(new_tag_ops); + return err; + } + + /* On success we no longer need the module for the old tagging protocol + */ +out: + dsa_tag_driver_put(old_tag_ops); + return count; +} +static DEVICE_ATTR_RW(tagging_imp); static ssize_t pvlan_show(struct device *d, struct device_attribute *attr, char *buf) @@ -326,7 +374,7 @@ static ssize_t pvlan_show(struct device *d, struct device_attribute *attr, struct dsa_port *cpu_dp = dev->dsa_ptr; struct dsa_switch_tree *dst = cpu_dp->ds->dst; struct dsa_port *dp; - int i, len = 0; + int len = 0; u16 value; list_for_each_entry(dp, &dst->ports, list) { @@ -334,8 +382,8 @@ static ssize_t pvlan_show(struct device *d, struct device_attribute *attr, if(!dp->ds->ops->port_change_pvlan) return -EOPNOTSUPP; dp->ds->ops->port_get_pvlan(dp->ds, dp->index, &value); - len += sprintf(buf + len, "%d:%02hx ", dp->index, value); - printk("dsi-pvlan_show %d:%02hx\n", dp->index, dp->index); + len += sprintf(buf + len, "%d:%03hx ", dp->index, value); + printk("dsi-pvlan_show %d:%03hx\n", dp->index, dp->index); } } @@ -378,9 +426,103 @@ static ssize_t pvlan_store(struct device *d, struct device_attribute *attr, static DEVICE_ATTR_RW(pvlan); +static ssize_t rdreg_show(struct device *d, struct device_attribute *attr, + char *buf) +{ + struct net_device *dev = to_net_dev(d); + struct dsa_port *cpu_dp = dev->dsa_ptr; + struct dsa_switch *ds = cpu_dp->ds; + u8 size; + u64 value; + int len = 0; + + if(ds->ops->switch_get_reg(ds, &size, &value)) + return -EIO; + switch(size) { + case 1: + len += sprintf(buf + len, "%hhx\n", (u8)value); + break; + case 2: + len += sprintf(buf + len, "%hx\n", (u16)value); + break; + case 4: + len += sprintf(buf + len, "%x\n", (u32)value); + break; + case 6: + len += sprintf(buf + len, "%llx\n", value); + break; + case 8: + len += sprintf(buf + len, "%llx\n", value); + break; + default: + return -EIO; + } + return len; +} + +static ssize_t rdreg_store(struct device *d, struct device_attribute *attr, + const char *buf, size_t count) +{ + struct net_device *dev = to_net_dev(d); + struct dsa_port *cpu_dp = dev->dsa_ptr; + struct dsa_switch *ds = cpu_dp->ds; + u8 page; + u8 reg; + u8 size; + int err; + + // Parse the input + err = sscanf(buf, "%hhx:%hhx:%hhx" , &page, ®, &size); + if (err != 3) + return -EINVAL; // Invalid format + + // Write the value to the switch + if(ds->ops->switch_setup_get_reg(ds, page, reg, size)) + return -EIO; + + return count; +} + +static DEVICE_ATTR_RW(rdreg); + +static ssize_t wrreg_show(struct device *d, struct device_attribute *attr, + char *buf) +{ + return -EPERM; +} + +static_ wrreg_store(struct device *d, struct device_attribute *attr, + const char *buf, size_t count) +{ + struct net_device *dev = to_net_dev(d); + struct dsa_port *cpu_dp = dev->dsa_ptr; + struct dsa_switch *ds = cpu_dp->ds; + u8 page; + u8 reg; + u8 size; + u64 value; + int err; + + // Parse the input + err = sscanf(buf, %hhx:%hhx:%hhx:%llx , &page, ®, &size, &value); + if (err != 4) + return -EINVAL; // Invalid format + + // Write the value to the switch + if(ds->ops->switch_setup_set_reg(ds, page, reg, size, value)) + return -EIO; + + return count; +} + +static DEVICE_ATTR_RW(wrreg); + static struct attribute *dsa_slave_attrs[] = { - &dev_attr_tagging.attr, + &dev_attr_tagging_cpu.attr, + &dev_attr_tagging_imp.attr, &dev_attr_pvlan.attr, + &dev_attr_rdreg.attr, + &dev_attr_wrreg.attr, NULL }; From 4e2290297c032842200da9d059d619e01f3b142e Mon Sep 17 00:00:00 2001 From: Mark Carlin Date: Mon, 22 Jan 2024 15:57:28 -0700 Subject: [PATCH 05/27] Add register peek/poke functions to b53 driver via sysfs. --- drivers/net/dsa/b53/b53_common.c | 11 ++++++----- include/net/dsa.h | 2 +- net/dsa/master.c | 8 ++++---- 3 files changed, 11 insertions(+), 10 deletions(-) diff --git a/drivers/net/dsa/b53/b53_common.c b/drivers/net/dsa/b53/b53_common.c index 58883968e6933a..c787bd234d81d7 100644 --- a/drivers/net/dsa/b53/b53_common.c +++ b/drivers/net/dsa/b53/b53_common.c @@ -2299,17 +2299,18 @@ static int b53_switch_setup_get_reg(struct dsa_switch *ds, u8 page, u8 reg, u8 s return 0; } -static int b53_switch_get_reg(struct dsa_switch *ds, u64 *value) +static int b53_switch_get_reg(struct dsa_switch *ds, u8 *size, u64 *value) { struct b53_device *dev = ds->priv; + *size = dev->size; switch(dev->size) { case 1: - return b53_read8(dev, dev->page, dev->reg, value); + return b53_read8(dev, dev->page, dev->reg, (u8 *)value); case 2: - return b53_read16(dev, dev->page, dev->reg, value); + return b53_read16(dev, dev->page, dev->reg, (u16 *)value); case 4: - return b53_read32(dev, dev->page, dev->reg, value); + return b53_read32(dev, dev->page, dev->reg, (u32 *)value); case 6: return b53_read48(dev, dev->page, dev->reg, value); case 8: @@ -2383,7 +2384,7 @@ static const struct dsa_switch_ops b53_switch_ops = { .port_max_mtu = b53_get_max_mtu, .port_change_mtu = b53_change_mtu, .port_change_pvlan = b53_port_change_pvlan, - .port_get_pvlan = b53_port_get_pvlan + .port_get_pvlan = b53_port_get_pvlan, .switch_setup_get_reg = b53_switch_setup_get_reg, .switch_get_reg = b53_switch_get_reg, .switch_set_reg = b53_switch_set_reg diff --git a/include/net/dsa.h b/include/net/dsa.h index 0aa2420c8d593b..60606f82f61c4c 100644 --- a/include/net/dsa.h +++ b/include/net/dsa.h @@ -917,7 +917,7 @@ struct dsa_switch_ops { * Switch low level register read/write */ int (*switch_setup_get_reg)(struct dsa_switch *ds, u8 page, u8 reg, u8 size); - int (*switch_get_reg)(struct dsa_switch *ds, u64 *value); + int (*switch_get_reg)(struct dsa_switch *ds, u8 *size, u64 *value); int (*switch_set_reg)(struct dsa_switch *ds, u8 page, u8 reg, u8 size, u64 value); }; diff --git a/net/dsa/master.c b/net/dsa/master.c index f959974612d47f..aac811b4620c46 100644 --- a/net/dsa/master.c +++ b/net/dsa/master.c @@ -476,7 +476,7 @@ static ssize_t rdreg_store(struct device *d, struct device_attribute *attr, if (err != 3) return -EINVAL; // Invalid format - // Write the value to the switch + // Write the value to the private data if(ds->ops->switch_setup_get_reg(ds, page, reg, size)) return -EIO; @@ -491,7 +491,7 @@ static ssize_t wrreg_show(struct device *d, struct device_attribute *attr, return -EPERM; } -static_ wrreg_store(struct device *d, struct device_attribute *attr, +static ssize_t wrreg_store(struct device *d, struct device_attribute *attr, const char *buf, size_t count) { struct net_device *dev = to_net_dev(d); @@ -504,12 +504,12 @@ static_ wrreg_store(struct device *d, struct device_attribute *attr, int err; // Parse the input - err = sscanf(buf, %hhx:%hhx:%hhx:%llx , &page, ®, &size, &value); + err = sscanf(buf, "%hhx:%hhx:%hhx:%llx" , &page, ®, &size, &value); if (err != 4) return -EINVAL; // Invalid format // Write the value to the switch - if(ds->ops->switch_setup_set_reg(ds, page, reg, size, value)) + if(ds->ops->switch_set_reg(ds, page, reg, size, value)) return -EIO; return count; From bb74c155a1b43e5f47c04b01151addab1edaa22c Mon Sep 17 00:00:00 2001 From: Mark Carlin Date: Thu, 25 Jan 2024 14:30:32 -0700 Subject: [PATCH 06/27] Latest br53143 driver. On powerup, cpu has no headers / imp has headers. PVLANs all set to zero (no connections between ports) Port0-Port4 PHY and MACs disabled. --- drivers/net/dsa/b53/b53_common.c | 69 +++++++++++++++++++++++++++++--- drivers/net/dsa/b53/b53_priv.h | 1 + drivers/net/dsa/b53/b53_regs.h | 39 ++++++++++++++++++ drivers/net/dsa/b53/b53_spi.c | 3 +- net/dsa/dsa2.c | 1 + 5 files changed, 107 insertions(+), 6 deletions(-) diff --git a/drivers/net/dsa/b53/b53_common.c b/drivers/net/dsa/b53/b53_common.c index c787bd234d81d7..59c2ef65ed9aff 100644 --- a/drivers/net/dsa/b53/b53_common.c +++ b/drivers/net/dsa/b53/b53_common.c @@ -20,6 +20,7 @@ #include #include #include +#include #include #include #include @@ -607,6 +608,7 @@ void b53_disable_port(struct dsa_switch *ds, int port) { struct b53_device *dev = ds->priv; u8 reg; + printk("dsi-b53_disable_port: port=%d\n", port); /* Disable Tx/Rx for the port */ b53_read8(dev, B53_CTRL_PAGE, B53_PORT_CTRL(port), ®); @@ -806,6 +808,27 @@ static void b53_switch_reset_gpio(struct b53_device *dev) dev->current_page = 0xff; } +static void b53_switch_reset_gpiod(struct b53_device *dev) +{ + struct gpio_desc *gpiod = dev->reset_gpiod; + + if (IS_ERR(gpiod)) + return; + + printk("dsi-b53_switch_reset_gpiod\n"); + + /* Reset sequence: RESET low(5ms)->high(10ms) + */ + gpiod_set_value(gpiod, 1); // Reset Asserted (Voltage Low) + mdelay(5); + + gpiod_set_value(gpiod, 0); // Reset De-Asserted (Voltage High) + mdelay(10); + + dev->current_page = 0xff; +} + + static int b53_switch_reset(struct b53_device *dev) { unsigned int timeout = 1000; @@ -1333,6 +1356,7 @@ void b53_phylink_validate(struct dsa_switch *ds, int port, struct b53_device *dev = ds->priv; __ETHTOOL_DECLARE_LINK_MODE_MASK(mask) = { 0, }; + printk("dsi-b53_phylink_validate: port=%d\n", port); if (dev->ops->serdes_phylink_validate) dev->ops->serdes_phylink_validate(dev, port, mask, state); @@ -2709,6 +2733,7 @@ static int b53_switch_init(struct b53_device *dev) { unsigned int i; int ret; + u16 phyreg; for (i = 0; i < ARRAY_SIZE(b53_switch_chips); i++) { const struct b53_chip_data *chip = &b53_switch_chips[i]; @@ -2777,13 +2802,27 @@ static int b53_switch_init(struct b53_device *dev) dev->ds->phys_mii_mask |= BIT(i); } } - dev->ports = devm_kcalloc(dev->dev, dev->num_ports, sizeof(struct b53_port), GFP_KERNEL); if (!dev->ports) return -ENOMEM; + /* Disable integrated PHY ports */ + for(i = 0; i < dev->num_ports; i++) + { + if((dev->enabled_ports & BIT(i)) && (i != dev->cpu_port) && (i != dev->imp_port)) + { + ret = b53_read16(dev, B53_PORT_MII_PAGE(i), B53_GMII_CTL, &phyreg); + if(ret) + return ret; + phyreg |= GMII_PWR_DOWN; + ret = b53_write16(dev, B53_PORT_MII_PAGE(i), B53_GMII_CTL, phyreg); + if(ret) + return ret; + } + } + dev->vlans = devm_kcalloc(dev->dev, dev->num_vlans, sizeof(struct b53_vlan), GFP_KERNEL); @@ -2827,7 +2866,7 @@ struct b53_device *b53_switch_alloc(struct device *base, ds->ops = &b53_switch_ops; dev->vlan_enabled = true; /* Let DSA handle the case were multiple bridges span the same switch - * device and different VLAN awareness settings are requested, which + * device and different VLAN awareness settings are requested, whichdev * would be breaking filtering semantics for any of the other bridge * devices. (not hardware supported) */ @@ -2910,8 +2949,19 @@ EXPORT_SYMBOL(b53_switch_detect); int b53_switch_register(struct b53_device *dev) { + + int i; int ret; + u16 phyreg; + printk("dsi-b53_switch_register()\n"); + dev->reset_gpiod = devm_gpiod_get(dev->dev, "reset", GPIOD_OUT_HIGH); // Reset Asserted (Voltage Low) + if (IS_ERR(dev->reset_gpiod)) { + dev_err(dev->ds->dev, "Failed to get reset GPIO\n"); + return PTR_ERR(dev->reset_gpiod); + } + b53_switch_reset_gpiod(dev); + if (dev->pdata) { dev->chip_id = dev->pdata->chip_id; dev->enabled_ports = dev->pdata->enabled_ports; @@ -2919,17 +2969,26 @@ int b53_switch_register(struct b53_device *dev) if (!dev->chip_id && b53_switch_detect(dev)) return -EINVAL; - printk("dsi-b53_switch_detect()\n"); ret = b53_switch_init(dev); - printk("dsi-b53_switch_init() ret=%d\n", ret); if (ret) return ret; dev_info(dev->dev, "found switch: %s, rev %i\n", dev->name, dev->core_rev); - return dsa_register_switch(dev->ds); + ret = dsa_register_switch(dev->ds); + /* Disable integrated PHY ports */ + for(i = 0; i < dev->num_ports; i++) + { + if((dev->enabled_ports & BIT(i)) && (i != dev->cpu_port) && (i != dev->imp_port)) + { + b53_read16(dev, B53_PORT_MII_PAGE(i), B53_GMII_CTL, &phyreg); + phyreg |= GMII_PWR_DOWN; + b53_write16(dev, B53_PORT_MII_PAGE(i), B53_GMII_CTL, phyreg); + } + } + return ret; } EXPORT_SYMBOL(b53_switch_register); diff --git a/drivers/net/dsa/b53/b53_priv.h b/drivers/net/dsa/b53/b53_priv.h index 5f805661b4d52e..81f9b7aaa206db 100644 --- a/drivers/net/dsa/b53/b53_priv.h +++ b/drivers/net/dsa/b53/b53_priv.h @@ -109,6 +109,7 @@ struct b53_device { struct mutex reg_mutex; struct mutex stats_mutex; const struct b53_io_ops *ops; + struct gpio_desc *reset_gpiod; /* chip specific data */ u32 chip_id; diff --git a/drivers/net/dsa/b53/b53_regs.h b/drivers/net/dsa/b53/b53_regs.h index b2c539a4215450..c741ad273e633f 100644 --- a/drivers/net/dsa/b53/b53_regs.h +++ b/drivers/net/dsa/b53/b53_regs.h @@ -354,6 +354,45 @@ #define B53_ARL_SRCH_RSTL_MACVID(x) (B53_ARL_SRCH_RSTL_0_MACVID + ((x) * 0x10)) #define B53_ARL_SRCH_RSTL(x) (B53_ARL_SRCH_RSTL_0 + ((x) * 0x10)) +/************************************************************************* + * Port MII Registers + *************************************************************************/ + #define B53_GMII_CTL 0x00 + #define GMII_CTL_RESET BIT(15) + #define GMII_CTL_LOOPBACK BIT(14) + #define GMII_CTL_SPD_SEL_LSB BIT(13) + #define GMII_AN_EN BIT(12) + #define GMII_PWR_DOWN BIT(11) + #define GMII_ISOLATE BIT(10) + #define GMII_RESTART_AN BIT(9) + #define GMII_DUPLEX BIT(8) + #define GMII_COLL_TEST BIT(7) + #define GMII_SPD_SEL_MSB BIT(6) + #define B53_GMII_STS 0x02 + #define B53_PHY_IDH 0x04 + #define B53_PHY_IDL 0x06 + #define B53_AN_ADV 0x08 + #define B53_AN_LPA 0x0a + #define B53_AN_EXP 0x0c + #define B53_AN_NXP 0x0e + #define B53_LP_NXP 0x10 + #define B53_B1000T_CTL 0x12 + #define B53_B1000T_STS 0x14 + #define B53_EXT_STS 0x1e + #define B53_PHY_EXT_CTL 0x20 + #define B53_PHY_EXT_STS 0x22 + #define B53_REC_ERR_CNT 0x24 + #define B53_FALSE_CARR_CNT 0x26 + #define B53_REC_NOTOK_CNT 0x28 + #define B53_DSP_COEFFICIENT 0x2a + #define B53_DSP_COEFFICIENT_ADDR 0x2e + #define B53_AUX_CTL 0x30 + #define B53_AUX_STS 0x32 + #define B53_INTERRUPT_STS 0x34 + #define B53_INTERRUPT_MSK 0x36 + #define B53_MISC_SHADOW 0x38 + #define B53_LED_CTRL 0x3a + /************************************************************************* * Port VLAN Registers *************************************************************************/ diff --git a/drivers/net/dsa/b53/b53_spi.c b/drivers/net/dsa/b53/b53_spi.c index 3738f7d318accd..3180276bdbd496 100644 --- a/drivers/net/dsa/b53/b53_spi.c +++ b/drivers/net/dsa/b53/b53_spi.c @@ -300,6 +300,7 @@ static int b53_spi_probe(struct spi_device *spi) struct b53_device *dev; int ret; struct net_device *ndev = dev_get_by_name(&init_net, "eth0"); + printk("dsi-b53_spi_probe\n"); if(!ndev) { @@ -365,7 +366,7 @@ static const struct spi_device_id b53_spi_ids[] = { { .name = "bcm5395" }, { .name = "bcm5397" }, { .name = "bcm5398" }, -{ .name = "bcm53115" }, + { .name = "bcm53115" }, { .name = "bcm53125" }, { .name = "bcm53128" }, { .name = "bcm53134" }, diff --git a/net/dsa/dsa2.c b/net/dsa/dsa2.c index 23b31bbc2ea869..7242d9302f5844 100644 --- a/net/dsa/dsa2.c +++ b/net/dsa/dsa2.c @@ -1633,6 +1633,7 @@ int dsa_register_switch(struct dsa_switch *ds) err = dsa_switch_probe(ds); printk("dsi-dsa_switch_probe err=%d\n", err); dsa_tree_put(ds->dst); + printk("dsi-dsa_tree_put\n"); mutex_unlock(&dsa2_mutex); return err; From 31ad6293207800b3797ec595ac83ca0588f7eca9 Mon Sep 17 00:00:00 2001 From: Mark Carlin Date: Thu, 25 Jan 2024 15:25:24 -0700 Subject: [PATCH 07/27] Git rid of debugging statements for the K53 driver. --- drivers/net/dsa/b53/b53_common.c | 60 +++++++++++--------------------- drivers/net/dsa/b53/b53_spi.c | 4 --- drivers/net/dsa/bcm_sf2.c | 3 -- include/net/dsa.h | 1 - net/dsa/dsa.c | 1 - net/dsa/dsa2.c | 31 ++--------------- net/dsa/master.c | 1 - net/dsa/tag_dsa.c | 1 - 8 files changed, 23 insertions(+), 79 deletions(-) diff --git a/drivers/net/dsa/b53/b53_common.c b/drivers/net/dsa/b53/b53_common.c index 59c2ef65ed9aff..76f988076af6f3 100644 --- a/drivers/net/dsa/b53/b53_common.c +++ b/drivers/net/dsa/b53/b53_common.c @@ -501,7 +501,7 @@ void b53_imp_vlan_setup(struct dsa_switch *ds, int cpu_port) struct b53_device *dev = ds->priv; unsigned int i; u16 pvlan; - printk("dsi-b53_imp_vlan_setup: cpu_port=%d\n", cpu_port); + /* Enable the IMP port to be in the same VLAN as the other ports * on a per-port basis such that we only have Port i and IMP in * the same VLAN. @@ -566,7 +566,7 @@ int b53_enable_port(struct dsa_switch *ds, int port, struct phy_device *phy) unsigned int cpu_port; int ret = 0; u16 pvlan; - printk("dsi-b53_enable_port: port=%d\n", port); + if (!dsa_is_user_port(ds, port)) return 0; @@ -609,7 +609,6 @@ void b53_disable_port(struct dsa_switch *ds, int port) struct b53_device *dev = ds->priv; u8 reg; - printk("dsi-b53_disable_port: port=%d\n", port); /* Disable Tx/Rx for the port */ b53_read8(dev, B53_CTRL_PAGE, B53_PORT_CTRL(port), ®); reg |= PORT_CTRL_RX_DISABLE | PORT_CTRL_TX_DISABLE; @@ -643,7 +642,7 @@ void b53_brcm_hdr_setup(struct dsa_switch *ds, int port) val = 0; break; } - printk("dsi-b53_brcm_hdr_setup: port=%d, tag_en=%d, val=%d\n", port, tag_en, val); + /* Enable management mode if tagging is requested */ b53_read8(dev, B53_CTRL_PAGE, B53_SWITCH_MODE, &hdr_ctl); if (tag_en) @@ -697,7 +696,7 @@ EXPORT_SYMBOL(b53_brcm_hdr_setup); static void b53_enable_cpu_port(struct b53_device *dev, int port) { u8 port_ctrl; - printk("dsi-b53_enable_cpu_port: port=%d\n", port); + /* BCM5325 CPU port is at 8 */ if ((is5325(dev) || is5365(dev)) && port == B53_CPU_PORT_25) port = B53_CPU_PORT; @@ -815,8 +814,6 @@ static void b53_switch_reset_gpiod(struct b53_device *dev) if (IS_ERR(gpiod)) return; - printk("dsi-b53_switch_reset_gpiod\n"); - /* Reset sequence: RESET low(5ms)->high(10ms) */ gpiod_set_value(gpiod, 1); // Reset Asserted (Voltage Low) @@ -1125,7 +1122,7 @@ static int b53_setup(struct dsa_switch *ds) struct b53_device *dev = ds->priv; unsigned int port; int ret; - printk("dsi-b53_setup\n"); + /* Request bridge PVID untagged when DSA_TAG_PROTO_NONE is set * which forces the CPU port to be tagged in all VLANs. */ @@ -1171,7 +1168,7 @@ static void b53_teardown(struct dsa_switch *ds) static void b53_force_link(struct b53_device *dev, int port, int link) { u8 reg, val, off; - printk("dsi-b53_force_link: port=%d, link=%d\n", port, link); + /* Override the port settings */ if (port == dev->imp_port) { off = B53_PORT_OVERRIDE_CTRL; @@ -1195,7 +1192,7 @@ static void b53_force_port_config(struct b53_device *dev, int port, bool tx_pause, bool rx_pause) { u8 reg, val, off; - printk("dsi-b53_force_port_config: port=%d, speed=%d, duplex=%d, tx_pause=%d, rx_pause=%d\n", port, speed, duplex, tx_pause, rx_pause); + /* Override the port settings */ if (port == dev->imp_port) { off = B53_PORT_OVERRIDE_CTRL; @@ -1356,7 +1353,6 @@ void b53_phylink_validate(struct dsa_switch *ds, int port, struct b53_device *dev = ds->priv; __ETHTOOL_DECLARE_LINK_MODE_MASK(mask) = { 0, }; - printk("dsi-b53_phylink_validate: port=%d\n", port); if (dev->ops->serdes_phylink_validate) dev->ops->serdes_phylink_validate(dev, port, mask, state); @@ -1398,7 +1394,7 @@ int b53_phylink_mac_link_state(struct dsa_switch *ds, int port, { struct b53_device *dev = ds->priv; int ret = -EOPNOTSUPP; - printk("dsi-b53_phylink_mac_link_state: port=%d\n", port); + if ((phy_interface_mode_is_8023z(state->interface) || state->interface == PHY_INTERFACE_MODE_SGMII) && dev->ops->serdes_link_state) @@ -1413,7 +1409,7 @@ void b53_phylink_mac_config(struct dsa_switch *ds, int port, const struct phylink_link_state *state) { struct b53_device *dev = ds->priv; - printk("dsi-b53_phylink_mac_config: port=%d, mode=%d\n", port, mode); + if (mode == MLO_AN_PHY || mode == MLO_AN_FIXED) return; @@ -1427,7 +1423,7 @@ EXPORT_SYMBOL(b53_phylink_mac_config); void b53_phylink_mac_an_restart(struct dsa_switch *ds, int port) { struct b53_device *dev = ds->priv; - printk("dsi-b53_phylink_mac_an_restart: port=%d\n", port); + if (dev->ops->serdes_an_restart) dev->ops->serdes_an_restart(dev, port); } @@ -1438,7 +1434,7 @@ void b53_phylink_mac_link_down(struct dsa_switch *ds, int port, phy_interface_t interface) { struct b53_device *dev = ds->priv; - printk("dsi-b53_phylink_mac_link_down: port=%d, mode=%d\n", port, mode); + if (mode == MLO_AN_PHY) return; @@ -1462,7 +1458,6 @@ void b53_phylink_mac_link_up(struct dsa_switch *ds, int port, { struct b53_device *dev = ds->priv; - printk("dsi-b53_phylink_mac_link_up: port=%d, mode=%d, speed=%d, duplex=%d, tx_pause=%d, rx_pause=%d\n", port, mode, speed, duplex, tx_pause, rx_pause); if (mode == MLO_AN_PHY) return; @@ -1891,7 +1886,7 @@ int b53_br_join(struct dsa_switch *ds, int port, struct net_device *br) s8 cpu_port = dsa_to_port(ds, port)->cpu_dp->index; u16 pvlan, reg; unsigned int i; - printk("dsi-b53_br_join: port=%d\n", port); + /* On 7278, port 7 which connects to the ASP should only receive * traffic from matching CFP rules. */ @@ -1932,11 +1927,8 @@ int b53_br_join(struct dsa_switch *ds, int port, struct net_device *br) b53_write16(dev, B53_PVLAN_PAGE, B53_PVLAN_PORT_MASK(port), pvlan); dev->ports[port].vlan_ctl_mask = pvlan; - b53_for_each_port(dev, i) { + b53_for_each_port(dev, i) b53_read16(dev, B53_PVLAN_PAGE, B53_PVLAN_PORT_MASK(i), ®); - printk("b53_br_join: port=%d, PORT_VLAN_CTL==0x%04x\n", i, reg); - } - return 0; } @@ -1949,7 +1941,7 @@ void b53_br_leave(struct dsa_switch *ds, int port, struct net_device *br) s8 cpu_port = dsa_to_port(ds, port)->cpu_dp->index; unsigned int i; u16 pvlan, reg, pvid; - printk("dsi-b53_br_leave: port=%d\n", port); + b53_read16(dev, B53_PVLAN_PAGE, B53_PVLAN_PORT_MASK(port), &pvlan); b53_for_each_port(dev, i) { @@ -1985,11 +1977,8 @@ void b53_br_leave(struct dsa_switch *ds, int port, struct net_device *br) vl->untag |= BIT(port) | BIT(cpu_port); b53_set_vlan_entry(dev, pvid, vl); } - b53_for_each_port(dev, i) { + b53_for_each_port(dev, i) b53_read16(dev, B53_PVLAN_PAGE, B53_PVLAN_PORT_MASK(i), ®); - printk("b53_br_leave: port=%d, PORT_VLAN_CTL==0x%04x\n", i, reg); - } - } EXPORT_SYMBOL(b53_br_leave); @@ -2040,7 +2029,6 @@ int b53_br_flags_pre(struct dsa_switch *ds, int port, struct switchdev_brport_flags flags, struct netlink_ext_ack *extack) { - printk("dsi-b53_br_flags_pre: port=%d, flags.val=0x%08lx val.mask=0x%08lx\n", port, flags.val, flags.mask); if (flags.mask & ~(BR_FLOOD | BR_MCAST_FLOOD | BR_LEARNING)) return -EINVAL; @@ -2052,7 +2040,6 @@ int b53_br_flags(struct dsa_switch *ds, int port, struct switchdev_brport_flags flags, struct netlink_ext_ack *extack) { - printk("dsi-b53_br_flags: port=%d, flags.val=0x%08lx val.mask=0x%08lx\n", port, flags.val, flags.mask); if (flags.mask & BR_FLOOD) b53_port_set_ucast_flood(ds->priv, port, !!(flags.val & BR_FLOOD)); @@ -2113,16 +2100,13 @@ enum dsa_tag_protocol b53_get_tag_protocol(struct dsa_switch *ds, int port, enum dsa_tag_protocol mprot) { struct b53_device *dev = ds->priv; - printk("dsi-b53_get_tag_protocol: port=%d, mprot=%d\n", port, mprot); if (!b53_can_enable_brcm_tags(ds, port, mprot)) { - printk("dsi-brcm_notags\n"); dev->tag_protocol = DSA_TAG_PROTO_NONE; goto out; } /* Older models require a different 6 byte tag */ if (is5325(dev) || is5365(dev) || is63xx(dev)) { - printk("dsi-brcm_legacy\n"); dev->tag_protocol = DSA_TAG_PROTO_BRCM_LEGACY; goto out; } @@ -2131,13 +2115,12 @@ enum dsa_tag_protocol b53_get_tag_protocol(struct dsa_switch *ds, int port, * which requires us to use the prepended Broadcom tag type */ if (dev->chip_id == BCM58XX_DEVICE_ID && port == B53_CPU_PORT) { - printk("dsi-brcm_prepend\n"); dev->tag_protocol = DSA_TAG_PROTO_BRCM_PREPEND; goto out; } dev->tag_protocol = DSA_TAG_PROTO_BRCM; - printk("dsi-brcm_enable\n"); + out: dev->tag_protocol = DSA_TAG_PROTO_NONE; return dev->tag_protocol; @@ -2149,7 +2132,7 @@ int b53_mirror_add(struct dsa_switch *ds, int port, { struct b53_device *dev = ds->priv; u16 reg, loc; - printk("dsi-b53_mirror_add: port=%d, mirror->to_local_port=%d, mirror->ingress=%d, ingress=%d\n", port, mirror->to_local_port, mirror->ingress, ingress); + if (ingress) loc = B53_IG_MIR_CTL; else @@ -2175,7 +2158,7 @@ void b53_mirror_del(struct dsa_switch *ds, int port, struct b53_device *dev = ds->priv; bool loc_disable = false, other_loc_disable = false; u16 reg, loc; - printk("dsi-b53_mirror_del: port=%d, mirror->to_local_port=%d, mirror->ingress=%d\n", port, mirror->to_local_port, mirror->ingress); + if (mirror->ingress) loc = B53_IG_MIR_CTL; else @@ -2279,7 +2262,7 @@ static int b53_change_mtu(struct dsa_switch *ds, int port, int mtu) if (is5325(dev) || is5365(dev)) return -EOPNOTSUPP; - printk("dsi-b53_change_mtu: port=%d, mtu=%d\n", port, mtu); + enable_jumbo = (mtu >= JMS_MIN_SIZE); allow_10_100 = (dev->chip_id == BCM583XX_DEVICE_ID); @@ -2295,7 +2278,6 @@ static int b53_port_change_pvlan(struct dsa_switch *ds, int port, u16 mask) { struct b53_device *dev = ds->priv; - printk("dsi-b53_port_change_pvlan: port=%d, mask=0x%04hx\n", port, mask); b53_write16(dev, B53_PVLAN_PAGE, B53_PVLAN_PORT_MASK(port), mask); dev->ports[port].vlan_ctl_mask = mask; return 0; @@ -2307,7 +2289,6 @@ static int b53_port_get_pvlan(struct dsa_switch *ds, int port, u16 *mask) u16 reg; b53_read16(dev, B53_PVLAN_PAGE, B53_PVLAN_PORT_MASK(port), ®); *mask = reg & 0x1ff; - printk("dsi-b53_port_get_pvlan: port=%d, mask=0x%04hx\n", port, *mask); return 0; } @@ -2846,7 +2827,7 @@ struct b53_device *b53_switch_alloc(struct device *base, { struct dsa_switch *ds; struct b53_device *dev; - printk("dsi-b53_switch_alloc()\n"); + ds = devm_kzalloc(base, sizeof(*ds), GFP_KERNEL); if (!ds) return NULL; @@ -2954,7 +2935,6 @@ int b53_switch_register(struct b53_device *dev) int ret; u16 phyreg; - printk("dsi-b53_switch_register()\n"); dev->reset_gpiod = devm_gpiod_get(dev->dev, "reset", GPIOD_OUT_HIGH); // Reset Asserted (Voltage Low) if (IS_ERR(dev->reset_gpiod)) { dev_err(dev->ds->dev, "Failed to get reset GPIO\n"); diff --git a/drivers/net/dsa/b53/b53_spi.c b/drivers/net/dsa/b53/b53_spi.c index 3180276bdbd496..abfeea5d47e966 100644 --- a/drivers/net/dsa/b53/b53_spi.c +++ b/drivers/net/dsa/b53/b53_spi.c @@ -301,12 +301,8 @@ static int b53_spi_probe(struct spi_device *spi) int ret; struct net_device *ndev = dev_get_by_name(&init_net, "eth0"); - printk("dsi-b53_spi_probe\n"); if(!ndev) - { - printk("dsi-b53_spi_probe dev is null\n"); return -EPROBE_DEFER; - } dev = b53_switch_alloc(&spi->dev, &b53_spi_ops, spi); if (!dev) diff --git a/drivers/net/dsa/bcm_sf2.c b/drivers/net/dsa/bcm_sf2.c index 21d6250a70ee36..9c3ca5f76a6c92 100644 --- a/drivers/net/dsa/bcm_sf2.c +++ b/drivers/net/dsa/bcm_sf2.c @@ -110,7 +110,6 @@ static void bcm_sf2_imp_setup(struct dsa_switch *ds, int port) struct bcm_sf2_priv *priv = bcm_sf2_to_priv(ds); unsigned int i; u32 reg, offset; - printk("dsi-bcm_sf2_imp_setup(): port=%d\n", port); /* Enable the port memories */ reg = core_readl(priv, CORE_MEM_PSM_VDD_CTRL); @@ -1338,8 +1337,6 @@ static int bcm_sf2_sw_probe(struct platform_device *pdev) u32 reg, rev; int ret; - printk("bcm_sf2_sw_probe\n"); - priv = devm_kzalloc(&pdev->dev, sizeof(*priv), GFP_KERNEL); if (!priv) return -ENOMEM; diff --git a/include/net/dsa.h b/include/net/dsa.h index 60606f82f61c4c..f639092a6b256b 100644 --- a/include/net/dsa.h +++ b/include/net/dsa.h @@ -459,7 +459,6 @@ static inline bool dsa_is_unused_port(struct dsa_switch *ds, int p) static inline bool dsa_is_cpu_port(struct dsa_switch *ds, int p) { - printk("dsi-dsa_is_cpu_port: port=%d\n",p); return dsa_to_port(ds, p)->type == DSA_PORT_TYPE_CPU; } diff --git a/net/dsa/dsa.c b/net/dsa/dsa.c index 88eab5cd56e60d..41f36ad8b0ec67 100644 --- a/net/dsa/dsa.c +++ b/net/dsa/dsa.c @@ -56,7 +56,6 @@ void dsa_tag_drivers_register(struct dsa_tag_driver *dsa_tag_driver_array[], unsigned int count, struct module *owner) { unsigned int i; - printk("dsi-dsa_tag_drivers_register() #=%d\n", count); for (i = 0; i < count; i++) dsa_tag_driver_register(dsa_tag_driver_array[i], owner); diff --git a/net/dsa/dsa2.c b/net/dsa/dsa2.c index 7242d9302f5844..747fb02f62eb8e 100644 --- a/net/dsa/dsa2.c +++ b/net/dsa/dsa2.c @@ -858,7 +858,6 @@ static int dsa_switch_setup(struct dsa_switch *ds) * setup() can register regions etc, against the ports */ list_for_each_entry(dp, &ds->dst->ports, list) { - printk("dsi-dsa_switch_setup dp->index=%d\n", dp->index); if (dp->ds == ds) { err = dsa_port_devlink_setup(dp); if (err) @@ -983,20 +982,17 @@ static int dsa_tree_setup_switches(struct dsa_switch_tree *dst) int err; list_for_each_entry(dp, &dst->ports, list) { - printk("dsi-dsa_tree_setup_switches dp->index=%d\n", dp->index); err = dsa_switch_setup(dp->ds); if (err) goto teardown; } list_for_each_entry(dp, &dst->ports, list) { - printk("dsi-dsa_tree_setup_ports dp->index=%d\n", dp->index); err = dsa_port_setup(dp); if (err) { err = dsa_port_reinit_as_unused(dp); if (err) goto teardown; - printk("dsi-dsa_port_reinit_as_unused dp->index=%d\n", dp->index); } } @@ -1017,7 +1013,6 @@ static int dsa_tree_setup_master(struct dsa_switch_tree *dst) list_for_each_entry(dp, &dst->ports, list) { if (dsa_port_is_cpu(dp)) { - printk("dsi-dsa_tree_setup_master (is cpu) dp->index=%d\n", dp->index); err = dsa_master_setup(dp->master, dp); if (err) return err; @@ -1247,14 +1242,12 @@ static enum dsa_tag_protocol dsa_get_tag_protocol(struct dsa_port *dp, mdp_upstream = dsa_upstream_port(mds, mdp->index); tag_protocol = mds->ops->get_tag_protocol(mds, mdp_upstream, DSA_TAG_PROTO_NONE); - printk("dsi-dsa_get_tag_protocol_slave tag_protocol=%d\n", tag_protocol); } /* If the master device is not itself a DSA slave in a disjoint DSA * tree, then return immediately. */ tag_protocol = ds->ops->get_tag_protocol(ds, dp->index, tag_protocol); - printk("dsi-dsa_get_tag_protocol tag_protocol=%d\n", tag_protocol); return ds->ops->get_tag_protocol(ds, dp->index, tag_protocol); } @@ -1267,7 +1260,6 @@ static int dsa_port_parse_cpu(struct dsa_port *dp, struct net_device *master, struct dsa_switch_tree *dst = ds->dst; enum dsa_tag_protocol default_proto; - printk("dsi-dsa_port_parse_cpu: index=%d\n", dp->index); /* Find out which protocol the switch would prefer. */ default_proto = dsa_get_tag_protocol(dp, master); if (dst->default_proto) { @@ -1354,7 +1346,6 @@ static int dsa_port_parse_of(struct dsa_port *dp, struct device_node *dn) bool port_imp = of_property_read_bool(dn, "port-imp"); dp->dn = dn; - printk("dsi-dsa_port_parse_of: index=%d, ethernet=%p, name=%s, link=%d\n", dp->index, ethernet, name, link); if (ethernet) { struct net_device *master; const char *user_protocol; @@ -1396,7 +1387,6 @@ static int dsa_switch_parse_ports_of(struct dsa_switch *ds, for_each_available_child_of_node(ports, port) { err = of_property_read_u32(port, "reg", ®); - printk("dsi-for_each_available_child_of_node-of_property_read_u32 err=%d (%d)\n", err, np); if (err) { of_node_put(port); goto out_put_node; @@ -1413,7 +1403,6 @@ static int dsa_switch_parse_ports_of(struct dsa_switch *ds, dp = dsa_to_port(ds, reg); err = dsa_port_parse_of(dp, port); - printk("dsi-dsa_port_parse_of err=%d (%d)\n", err, np); if (err) { of_node_put(port); goto out_put_node; @@ -1431,10 +1420,9 @@ static int dsa_switch_parse_member_of(struct dsa_switch *ds, { u32 m[2] = { 0, 0 }; int sz; - printk("dsi-dsa_switch_parse_member_of\n"); + /* Don't error out if this optional property isn't found */ sz = of_property_read_variable_u32_array(dn, "dsa,member", m, 2, 2); - printk("dsi-of_property_read_variable_u32_array sz=%d\n", sz); if (sz < 0 && sz != -EINVAL) return sz; @@ -1474,19 +1462,16 @@ static int dsa_switch_touch_ports(struct dsa_switch *ds) static int dsa_switch_parse_of(struct dsa_switch *ds, struct device_node *dn) { int err; - printk("dsi-dsa_switch_parse_of\n"); + err = dsa_switch_parse_member_of(ds, dn); - printk("dsi-dsa_switch_parse_member_of err=%d\n", err); if (err) return err; err = dsa_switch_touch_ports(ds); - printk("dsi-dsa_switch_touch_ports err=%d\n", err); if (err) return err; err = dsa_switch_parse_ports_of(ds, dn); - printk("dsi-dsa_switch_parse_ports_of err=%d\n", err); return err; } @@ -1525,7 +1510,6 @@ static int dsa_switch_parse_ports(struct dsa_switch *ds, name = cd->port_names[i]; dev = cd->netdev[i]; dp = dsa_to_port(ds, i); - printk("dsi-dsa_switch_parse_ports i=%d name=%s dev=%p\n", i, name, dev); if (!name) continue; @@ -1583,7 +1567,7 @@ static int dsa_switch_probe(struct dsa_switch *ds) struct dsa_chip_data *pdata; struct device_node *np; int err; - printk("dsi-dsa_switch_probe\n"); + if (!ds->dev) return -ENODEV; @@ -1592,35 +1576,29 @@ static int dsa_switch_probe(struct dsa_switch *ds) if (!ds->num_ports) return -EINVAL; - printk("dsi-dsa_switch_probe entry ds->num_ports=%d\n", ds->num_ports); if (np) { err = dsa_switch_parse_of(ds, np); - printk("dsi-dsa_switch_parse_of err=%d\n", err); if (err) dsa_switch_release_ports(ds); } else if (pdata) { err = dsa_switch_parse(ds, pdata); - printk("dsi-dsa_switch_parse err=%d\n", err); if (err) dsa_switch_release_ports(ds); } else { err = -ENODEV; } - printk("dsi-dsa_switch_probe mid err=%d\n", err); if (err) return err; dst = ds->dst; dsa_tree_get(dst); err = dsa_tree_setup(dst); - printk("dsi-dsa_tree_setup err=%d\n", err); if (err) { dsa_switch_release_ports(ds); dsa_tree_put(dst); } - printk("dsi-dsa_switch_probe exit err=%d\n", err); return err; } @@ -1628,12 +1606,9 @@ int dsa_register_switch(struct dsa_switch *ds) { int err; - printk("dsi-dsa_register_switch\n"); mutex_lock(&dsa2_mutex); err = dsa_switch_probe(ds); - printk("dsi-dsa_switch_probe err=%d\n", err); dsa_tree_put(ds->dst); - printk("dsi-dsa_tree_put\n"); mutex_unlock(&dsa2_mutex); return err; diff --git a/net/dsa/master.c b/net/dsa/master.c index aac811b4620c46..e73d71a00198b1 100644 --- a/net/dsa/master.c +++ b/net/dsa/master.c @@ -383,7 +383,6 @@ static ssize_t pvlan_show(struct device *d, struct device_attribute *attr, return -EOPNOTSUPP; dp->ds->ops->port_get_pvlan(dp->ds, dp->index, &value); len += sprintf(buf + len, "%d:%03hx ", dp->index, value); - printk("dsi-pvlan_show %d:%03hx\n", dp->index, dp->index); } } diff --git a/net/dsa/tag_dsa.c b/net/dsa/tag_dsa.c index de572ff46819c4..86b4fd07ca57ae 100644 --- a/net/dsa/tag_dsa.c +++ b/net/dsa/tag_dsa.c @@ -130,7 +130,6 @@ static struct sk_buff *dsa_xmit_ll(struct sk_buff *skb, struct net_device *dev, u8 tag_dev, tag_port; enum dsa_cmd cmd; u8 *dsa_header; - printk("dsi-dsa_xmit_ll()\n"); if (skb->offload_fwd_mark) { struct dsa_switch_tree *dst = dp->ds->dst; From 2ab6c9f12cc502f0f434277cefaa242f764180ac Mon Sep 17 00:00:00 2001 From: mcarlin Date: Thu, 25 Jan 2024 18:45:43 -0700 Subject: [PATCH 08/27] Update version id to 5.15.107-datum.4 --- Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Makefile b/Makefile index e2e6bbb3936185..c28b2a2daa5ce8 100644 --- a/Makefile +++ b/Makefile @@ -2,7 +2,7 @@ VERSION = 5 PATCHLEVEL = 15 SUBLEVEL = 107 -EXTRAVERSION = -datum.3 +EXTRAVERSION = -datum.4 NAME = Trick or Treat # *DOCUMENTATION* From e0c75f123f4eba2548fe698df1fa91b0e5356db8 Mon Sep 17 00:00:00 2001 From: Mark Carlin Date: Fri, 9 Feb 2024 11:56:25 -0700 Subject: [PATCH 09/27] Add brcm header enable/disable for imp port only in sysfs. Enable VLANs for all ports. --- drivers/net/dsa/b53/b53_common.c | 105 ++++++++++++++++++++++++------- drivers/net/dsa/b53/b53_priv.h | 3 + drivers/net/dsa/b53/b53_regs.h | 2 + net/dsa/dsa2.c | 1 - net/dsa/master.c | 35 ++++------- net/dsa/tag_brcm.c | 9 +-- net/dsa/tag_dsa.c | 1 - 7 files changed, 101 insertions(+), 55 deletions(-) diff --git a/drivers/net/dsa/b53/b53_common.c b/drivers/net/dsa/b53/b53_common.c index 76f988076af6f3..526910c9edd9d5 100644 --- a/drivers/net/dsa/b53/b53_common.c +++ b/drivers/net/dsa/b53/b53_common.c @@ -166,6 +166,7 @@ static const struct b53_mib_desc b53_mibs[] = { #define B53_MIBS_SIZE ARRAY_SIZE(b53_mibs) +// Datum: This is the one BCM53134 static const struct b53_mib_desc b53_mibs_58xx[] = { { 8, 0x00, "TxOctets" }, { 4, 0x08, "TxDropPkts" }, @@ -622,44 +623,52 @@ EXPORT_SYMBOL(b53_disable_port); void b53_brcm_hdr_setup(struct dsa_switch *ds, int port) { struct b53_device *dev = ds->priv; - bool tag_en = !(dev->tag_protocol == DSA_TAG_PROTO_NONE); + bool tag_en; u8 hdr_ctl, val; u16 reg; - dev->tag_protocol = DSA_TAG_PROTO_NONE; - tag_en = 0; + /* Resolve which bit controls the Broadcom tag */ switch (port) { case 8: val = BRCM_HDR_P8_EN; + tag_en = !(dev->tag_protocol_imp == DSA_TAG_PROTO_NONE); break; case 7: val = BRCM_HDR_P7_EN; + tag_en = false; break; case 5: val = BRCM_HDR_P5_EN; + tag_en = !(dev->tag_protocol == DSA_TAG_PROTO_NONE); break; default: val = 0; break; } - /* Enable management mode if tagging is requested */ + // /* Enable management mode if tagging is requested */ + // b53_read8(dev, B53_CTRL_PAGE, B53_SWITCH_MODE, &hdr_ctl); + // if (tag_en) + // hdr_ctl |= SM_SW_FWD_MODE; + // else + // hdr_ctl &= ~SM_SW_FWD_MODE; + // b53_write8(dev, B53_CTRL_PAGE, B53_SWITCH_MODE, hdr_ctl); + + // Datum: Always disable management mode b53_read8(dev, B53_CTRL_PAGE, B53_SWITCH_MODE, &hdr_ctl); - if (tag_en) - hdr_ctl |= SM_SW_FWD_MODE; - else - hdr_ctl &= ~SM_SW_FWD_MODE; + hdr_ctl &= ~SM_SW_FWD_MODE; b53_write8(dev, B53_CTRL_PAGE, B53_SWITCH_MODE, hdr_ctl); - /* Configure the appropriate IMP port */ - b53_read8(dev, B53_MGMT_PAGE, B53_GLOBAL_CONFIG, &hdr_ctl); - if (port == 8) - hdr_ctl |= GC_FRM_MGMT_PORT_MII; - else if (port == 5) - hdr_ctl |= GC_FRM_MGMT_PORT_M; - b53_write8(dev, B53_MGMT_PAGE, B53_GLOBAL_CONFIG, hdr_ctl); + // Datum: No in-band management ports, switch is managed via SPI (defaults to no in-band management ports) + // /* Configure the appropriate IMP port */ + // b53_read8(dev, B53_MGMT_PAGE, B53_GLOBAL_CONFIG, &hdr_ctl); + // if (port == 8) + // hdr_ctl |= GC_FRM_MGMT_PORT_MII; + // else if (port == 5) + // hdr_ctl |= GC_FRM_MGMT_PORT_M; + // b53_write8(dev, B53_MGMT_PAGE, B53_GLOBAL_CONFIG, hdr_ctl); - /* Enable Broadcom tags for IMP port */ + /* Configure Broadcom tags for IMP/CPU port */ b53_read8(dev, B53_MGMT_PAGE, B53_BRCM_HDR, &hdr_ctl); if (tag_en) hdr_ctl |= val; @@ -670,6 +679,8 @@ void b53_brcm_hdr_setup(struct dsa_switch *ds, int port) /* Registers below are only accessible on newer devices */ if (!is58xx(dev)) return; + // Datum: BCM53134 does not have the following registers: + // B53_BRCM_HDR_RX_DIS, B53_BRCM_HDR_TX_DIS /* Enable reception Broadcom tag for CPU TX (switch RX) to * allow us to tag outgoing frames @@ -697,9 +708,21 @@ static void b53_enable_cpu_port(struct b53_device *dev, int port) { u8 port_ctrl; - /* BCM5325 CPU port is at 8 */ - if ((is5325(dev) || is5365(dev)) && port == B53_CPU_PORT_25) - port = B53_CPU_PORT; + port_ctrl = PORT_CTRL_RX_BCST_EN | + PORT_CTRL_RX_MCST_EN | + PORT_CTRL_RX_UCST_EN; + b53_write8(dev, B53_CTRL_PAGE, B53_PORT_CTRL(port), port_ctrl); + + b53_brcm_hdr_setup(dev->ds, port); + + b53_port_set_ucast_flood(dev, port, true); + b53_port_set_mcast_flood(dev, port, true); + b53_port_set_learning(dev, port, false); +} + +static void b53_enable_imp_port(struct b53_device *dev, int port) +{ + u8 port_ctrl; port_ctrl = PORT_CTRL_RX_BCST_EN | PORT_CTRL_RX_MCST_EN | @@ -1117,6 +1140,11 @@ int b53_setup_devlink_resources(struct dsa_switch *ds) } EXPORT_SYMBOL(b53_setup_devlink_resources); +static inline bool dsa_is_imp_port(struct dsa_switch *ds, int p) +{ + return p == B53_CPU_PORT; +} + static int b53_setup(struct dsa_switch *ds) { struct b53_device *dev = ds->priv; @@ -1146,8 +1174,11 @@ static int b53_setup(struct dsa_switch *ds) * ports will be configured with .port_enable */ for (port = 0; port < dev->num_ports; port++) { + dsa_is_cpu_port(ds, port); if (dsa_is_cpu_port(ds, port)) b53_enable_cpu_port(dev, port); + else if(dsa_is_imp_port(ds, port)) + b53_enable_imp_port(dev, port); else b53_disable_port(ds, port); } @@ -2059,6 +2090,7 @@ static bool b53_possible_cpu_port(struct dsa_switch *ds, int port) /* Broadcom switches will accept enabling Broadcom tags on the * following ports: 5, 7 and 8, any other port is not supported */ + switch (port) { case B53_CPU_PORT_25: case 7: @@ -2100,6 +2132,10 @@ enum dsa_tag_protocol b53_get_tag_protocol(struct dsa_switch *ds, int port, enum dsa_tag_protocol mprot) { struct b53_device *dev = ds->priv; + + if(port == 8) + return dev->tag_protocol_imp; + if (!b53_can_enable_brcm_tags(ds, port, mprot)) { dev->tag_protocol = DSA_TAG_PROTO_NONE; goto out; @@ -2119,14 +2155,34 @@ enum dsa_tag_protocol b53_get_tag_protocol(struct dsa_switch *ds, int port, goto out; } - dev->tag_protocol = DSA_TAG_PROTO_BRCM; out: + // Datum: Always set tag_protocol to NONE (cpu) dev->tag_protocol = DSA_TAG_PROTO_NONE; - return dev->tag_protocol; + if(port == B53_CPU_PORT) + return dev->tag_protocol_imp; + else + return dev->tag_protocol; } EXPORT_SYMBOL(b53_get_tag_protocol); +int b53_change_imp_tag_protocol(struct dsa_switch *ds, int port, + enum dsa_tag_protocol mprot) +{ + struct b53_device *dev = ds->priv; + + if (!b53_can_enable_brcm_tags(ds, port, mprot)) + return -EOPNOTSUPP; + if(dev->tag_protocol_imp == mprot) + return 0; + dev->tag_protocol_imp = mprot; + b53_brcm_hdr_setup(ds, port); + + return 0; +} +EXPORT_SYMBOL(b53_change_imp_tag_protocol); + + int b53_mirror_add(struct dsa_switch *ds, int port, struct dsa_mall_mirror_tc_entry *mirror, bool ingress) { @@ -2351,6 +2407,7 @@ static int b53_switch_set_reg(struct dsa_switch *ds, u8 page, u8 reg, u8 size, u static const struct dsa_switch_ops b53_switch_ops = { .get_tag_protocol = b53_get_tag_protocol, + .change_tag_protocol = b53_change_imp_tag_protocol, .setup = b53_setup, .teardown = b53_teardown, .get_strings = b53_get_strings, @@ -2782,6 +2839,9 @@ static int b53_switch_init(struct b53_device *dev) !b53_possible_cpu_port(dev->ds, i)) dev->ds->phys_mii_mask |= BIT(i); } + /* Default cpu to no tagging, imp Port to brcm tagging */ + dev->tag_protocol = DSA_TAG_PROTO_NONE; + dev->tag_protocol_imp = DSA_TAG_PROTO_BRCM; } dev->ports = devm_kcalloc(dev->dev, dev->num_ports, sizeof(struct b53_port), @@ -2810,6 +2870,9 @@ static int b53_switch_init(struct b53_device *dev) if (!dev->vlans) return -ENOMEM; + /* Join all VLANs for all ports (promiscuous mode) */ + b53_write16(dev, B53_VLAN_PAGE, B53_JOIN_ALL_VLAN_EN, VJA_ALL_PORTS_MASK); + dev->reset_gpio = b53_switch_get_reset_gpio(dev); if (dev->reset_gpio >= 0) { ret = devm_gpio_request_one(dev->dev, dev->reset_gpio, diff --git a/drivers/net/dsa/b53/b53_priv.h b/drivers/net/dsa/b53/b53_priv.h index 81f9b7aaa206db..6a5f936d9d5bcd 100644 --- a/drivers/net/dsa/b53/b53_priv.h +++ b/drivers/net/dsa/b53/b53_priv.h @@ -122,6 +122,7 @@ struct b53_device { u8 num_arl_bins; u16 num_arl_buckets; enum dsa_tag_protocol tag_protocol; + enum dsa_tag_protocol tag_protocol_imp; /* raw register read data*/ u8 page; @@ -384,6 +385,8 @@ int b53_mirror_add(struct dsa_switch *ds, int port, struct dsa_mall_mirror_tc_entry *mirror, bool ingress); enum dsa_tag_protocol b53_get_tag_protocol(struct dsa_switch *ds, int port, enum dsa_tag_protocol mprot); +int b53_change_imp_tag_protocol(struct dsa_switch *ds, int port, + enum dsa_tag_protocol mprot); void b53_mirror_del(struct dsa_switch *ds, int port, struct dsa_mall_mirror_tc_entry *mirror); int b53_enable_port(struct dsa_switch *ds, int port, struct phy_device *phy); diff --git a/drivers/net/dsa/b53/b53_regs.h b/drivers/net/dsa/b53/b53_regs.h index c741ad273e633f..e78807d5d30ae7 100644 --- a/drivers/net/dsa/b53/b53_regs.h +++ b/drivers/net/dsa/b53/b53_regs.h @@ -402,6 +402,8 @@ /* Join all VLANs register (16 bit) */ #define B53_JOIN_ALL_VLAN_EN 0x50 +#define VJA_ALL_PORTS_MASK 0x12f + /************************************************************************* * 802.1Q Page Registers diff --git a/net/dsa/dsa2.c b/net/dsa/dsa2.c index 747fb02f62eb8e..3a8f6fe3a0405b 100644 --- a/net/dsa/dsa2.c +++ b/net/dsa/dsa2.c @@ -1343,7 +1343,6 @@ static int dsa_port_parse_of(struct dsa_port *dp, struct device_node *dn) struct device_node *ethernet = of_parse_phandle(dn, "ethernet", 0); const char *name = of_get_property(dn, "label", NULL); bool link = of_property_read_bool(dn, "link"); - bool port_imp = of_property_read_bool(dn, "port-imp"); dp->dn = dn; if (ethernet) { diff --git a/net/dsa/master.c b/net/dsa/master.c index e73d71a00198b1..02d7ee8f37f1c8 100644 --- a/net/dsa/master.c +++ b/net/dsa/master.c @@ -324,45 +324,32 @@ static ssize_t tagging_imp_show(struct device *d, struct device_attribute *attr, { struct net_device *dev = to_net_dev(d); struct dsa_port *cpu_dp = dev->dsa_ptr; + struct dsa_switch *ds = cpu_dp->ds; + const struct dsa_device_ops *tag_ops; + enum dsa_tag_protocol proto; - return sprintf(buf, "%s\n", - dsa_tag_protocol_to_str(cpu_dp->tag_ops)); + proto = ds->ops->get_tag_protocol(ds, 8, DSA_TAG_PROTO_NONE); + tag_ops = dsa_tag_driver_get(proto); + return sprintf(buf, "%s\n", dsa_tag_protocol_to_str(tag_ops)); } static ssize_t tagging_imp_store(struct device *d, struct device_attribute *attr, const char *buf, size_t count) { - const struct dsa_device_ops *new_tag_ops, *old_tag_ops; + const struct dsa_device_ops *new_tag_ops; struct net_device *dev = to_net_dev(d); struct dsa_port *cpu_dp = dev->dsa_ptr; - int err; + struct dsa_switch *ds = cpu_dp->ds; - old_tag_ops = cpu_dp->tag_ops; new_tag_ops = dsa_find_tagger_by_name(buf); /* Bad tagger name, or module is not loaded? */ if (IS_ERR(new_tag_ops)) return PTR_ERR(new_tag_ops); - if (new_tag_ops == old_tag_ops) - /* Drop the temporarily held duplicate reference, since - * the DSA switch tree uses this tagger. - */ - goto out; - - err = dsa_tree_change_tag_proto(cpu_dp->ds->dst, dev, new_tag_ops, - old_tag_ops); - if (err) { - /* On failure the old tagger is restored, so we don't need the - * driver for the new one. - */ - dsa_tag_driver_put(new_tag_ops); - return err; - } + if(!ds->ops->change_tag_protocol) + return -EOPNOTSUPP; - /* On success we no longer need the module for the old tagging protocol - */ -out: - dsa_tag_driver_put(old_tag_ops); + ds->ops->change_tag_protocol(ds, 8, new_tag_ops->proto); return count; } static DEVICE_ATTR_RW(tagging_imp); diff --git a/net/dsa/tag_brcm.c b/net/dsa/tag_brcm.c index 3f3f22549f0bf4..ed5f68c4f1dad1 100644 --- a/net/dsa/tag_brcm.c +++ b/net/dsa/tag_brcm.c @@ -5,7 +5,6 @@ * Copyright (C) 2014 Broadcom Corporation */ -#include #include #include #include @@ -86,7 +85,6 @@ static struct sk_buff *brcm_tag_xmit_ll(struct sk_buff *skb, u16 queue = skb_get_queue_mapping(skb); u8 *brcm_tag; - //printk("brcm_tag_xmit_ll()\n"); /* The Ethernet switch we are interfaced with needs packets to be at * least 64 bytes (including FCS) otherwise they will be discarded when * they enter the switch port logic. When Broadcom tags are enabled, we @@ -142,9 +140,8 @@ static struct sk_buff *brcm_tag_rcv_ll(struct sk_buff *skb, unsigned int offset) { int source_port; - int i; u8 *brcm_tag; - //printk("brcm_tag_rcv_ll()\n"); + if (unlikely(!pskb_may_pull(skb, BRCM_TAG_LEN))) return NULL; @@ -154,10 +151,6 @@ static struct sk_buff *brcm_tag_rcv_ll(struct sk_buff *skb, if (unlikely((brcm_tag[0] >> BRCM_OPCODE_SHIFT) & BRCM_OPCODE_MASK)) return NULL; - // for( i = 0; i < 16; i++) - // printk("%02x, ", brcm_tag[i]); - // printk("\n"); - /* We should never see a reserved reason code without knowing how to * handle it */ diff --git a/net/dsa/tag_dsa.c b/net/dsa/tag_dsa.c index 86b4fd07ca57ae..b3da4b2ea11cf6 100644 --- a/net/dsa/tag_dsa.c +++ b/net/dsa/tag_dsa.c @@ -193,7 +193,6 @@ static struct sk_buff *dsa_rcv_ll(struct sk_buff *skb, struct net_device *dev, enum dsa_code code; enum dsa_cmd cmd; u8 *dsa_header; - prinkt("dsa_rcv_ll()\n"); /* The ethertype field is part of the DSA header. */ dsa_header = dsa_etype_header_pos_rx(skb); From 671472957cafba69695796dde9f9fe2430c35565 Mon Sep 17 00:00:00 2001 From: Mark Carlin Date: Fri, 9 Feb 2024 16:17:38 -0700 Subject: [PATCH 10/27] Remove some unneeded code from the BR53514 driver. --- drivers/net/dsa/b53/b53_common.c | 1291 +++++++++++------------------- drivers/net/dsa/b53/b53_priv.h | 114 +-- drivers/net/dsa/b53/b53_regs.h | 6 +- 3 files changed, 545 insertions(+), 866 deletions(-) diff --git a/drivers/net/dsa/b53/b53_common.c b/drivers/net/dsa/b53/b53_common.c index 526910c9edd9d5..437614f5e1ecc5 100644 --- a/drivers/net/dsa/b53/b53_common.c +++ b/drivers/net/dsa/b53/b53_common.c @@ -39,135 +39,8 @@ struct b53_mib_desc { const char *name; }; -/* BCM5365 MIB counters */ -static const struct b53_mib_desc b53_mibs_65[] = { - { 8, 0x00, "TxOctets" }, - { 4, 0x08, "TxDropPkts" }, - { 4, 0x10, "TxBroadcastPkts" }, - { 4, 0x14, "TxMulticastPkts" }, - { 4, 0x18, "TxUnicastPkts" }, - { 4, 0x1c, "TxCollisions" }, - { 4, 0x20, "TxSingleCollision" }, - { 4, 0x24, "TxMultipleCollision" }, - { 4, 0x28, "TxDeferredTransmit" }, - { 4, 0x2c, "TxLateCollision" }, - { 4, 0x30, "TxExcessiveCollision" }, - { 4, 0x38, "TxPausePkts" }, - { 8, 0x44, "RxOctets" }, - { 4, 0x4c, "RxUndersizePkts" }, - { 4, 0x50, "RxPausePkts" }, - { 4, 0x54, "Pkts64Octets" }, - { 4, 0x58, "Pkts65to127Octets" }, - { 4, 0x5c, "Pkts128to255Octets" }, - { 4, 0x60, "Pkts256to511Octets" }, - { 4, 0x64, "Pkts512to1023Octets" }, - { 4, 0x68, "Pkts1024to1522Octets" }, - { 4, 0x6c, "RxOversizePkts" }, - { 4, 0x70, "RxJabbers" }, - { 4, 0x74, "RxAlignmentErrors" }, - { 4, 0x78, "RxFCSErrors" }, - { 8, 0x7c, "RxGoodOctets" }, - { 4, 0x84, "RxDropPkts" }, - { 4, 0x88, "RxUnicastPkts" }, - { 4, 0x8c, "RxMulticastPkts" }, - { 4, 0x90, "RxBroadcastPkts" }, - { 4, 0x94, "RxSAChanges" }, - { 4, 0x98, "RxFragments" }, -}; - -#define B53_MIBS_65_SIZE ARRAY_SIZE(b53_mibs_65) - -/* BCM63xx MIB counters */ -static const struct b53_mib_desc b53_mibs_63xx[] = { - { 8, 0x00, "TxOctets" }, - { 4, 0x08, "TxDropPkts" }, - { 4, 0x0c, "TxQoSPkts" }, - { 4, 0x10, "TxBroadcastPkts" }, - { 4, 0x14, "TxMulticastPkts" }, - { 4, 0x18, "TxUnicastPkts" }, - { 4, 0x1c, "TxCollisions" }, - { 4, 0x20, "TxSingleCollision" }, - { 4, 0x24, "TxMultipleCollision" }, - { 4, 0x28, "TxDeferredTransmit" }, - { 4, 0x2c, "TxLateCollision" }, - { 4, 0x30, "TxExcessiveCollision" }, - { 4, 0x38, "TxPausePkts" }, - { 8, 0x3c, "TxQoSOctets" }, - { 8, 0x44, "RxOctets" }, - { 4, 0x4c, "RxUndersizePkts" }, - { 4, 0x50, "RxPausePkts" }, - { 4, 0x54, "Pkts64Octets" }, - { 4, 0x58, "Pkts65to127Octets" }, - { 4, 0x5c, "Pkts128to255Octets" }, - { 4, 0x60, "Pkts256to511Octets" }, - { 4, 0x64, "Pkts512to1023Octets" }, - { 4, 0x68, "Pkts1024to1522Octets" }, - { 4, 0x6c, "RxOversizePkts" }, - { 4, 0x70, "RxJabbers" }, - { 4, 0x74, "RxAlignmentErrors" }, - { 4, 0x78, "RxFCSErrors" }, - { 8, 0x7c, "RxGoodOctets" }, - { 4, 0x84, "RxDropPkts" }, - { 4, 0x88, "RxUnicastPkts" }, - { 4, 0x8c, "RxMulticastPkts" }, - { 4, 0x90, "RxBroadcastPkts" }, - { 4, 0x94, "RxSAChanges" }, - { 4, 0x98, "RxFragments" }, - { 4, 0xa0, "RxSymbolErrors" }, - { 4, 0xa4, "RxQoSPkts" }, - { 8, 0xa8, "RxQoSOctets" }, - { 4, 0xb0, "Pkts1523to2047Octets" }, - { 4, 0xb4, "Pkts2048to4095Octets" }, - { 4, 0xb8, "Pkts4096to8191Octets" }, - { 4, 0xbc, "Pkts8192to9728Octets" }, - { 4, 0xc0, "RxDiscarded" }, -}; - -#define B53_MIBS_63XX_SIZE ARRAY_SIZE(b53_mibs_63xx) - -/* MIB counters */ -static const struct b53_mib_desc b53_mibs[] = { - { 8, 0x00, "TxOctets" }, - { 4, 0x08, "TxDropPkts" }, - { 4, 0x10, "TxBroadcastPkts" }, - { 4, 0x14, "TxMulticastPkts" }, - { 4, 0x18, "TxUnicastPkts" }, - { 4, 0x1c, "TxCollisions" }, - { 4, 0x20, "TxSingleCollision" }, - { 4, 0x24, "TxMultipleCollision" }, - { 4, 0x28, "TxDeferredTransmit" }, - { 4, 0x2c, "TxLateCollision" }, - { 4, 0x30, "TxExcessiveCollision" }, - { 4, 0x38, "TxPausePkts" }, - { 8, 0x50, "RxOctets" }, - { 4, 0x58, "RxUndersizePkts" }, - { 4, 0x5c, "RxPausePkts" }, - { 4, 0x60, "Pkts64Octets" }, - { 4, 0x64, "Pkts65to127Octets" }, - { 4, 0x68, "Pkts128to255Octets" }, - { 4, 0x6c, "Pkts256to511Octets" }, - { 4, 0x70, "Pkts512to1023Octets" }, - { 4, 0x74, "Pkts1024to1522Octets" }, - { 4, 0x78, "RxOversizePkts" }, - { 4, 0x7c, "RxJabbers" }, - { 4, 0x80, "RxAlignmentErrors" }, - { 4, 0x84, "RxFCSErrors" }, - { 8, 0x88, "RxGoodOctets" }, - { 4, 0x90, "RxDropPkts" }, - { 4, 0x94, "RxUnicastPkts" }, - { 4, 0x98, "RxMulticastPkts" }, - { 4, 0x9c, "RxBroadcastPkts" }, - { 4, 0xa0, "RxSAChanges" }, - { 4, 0xa4, "RxFragments" }, - { 4, 0xa8, "RxJumboPkts" }, - { 4, 0xac, "RxSymbolErrors" }, - { 4, 0xc0, "RxDiscarded" }, -}; - -#define B53_MIBS_SIZE ARRAY_SIZE(b53_mibs) - -// Datum: This is the one BCM53134 -static const struct b53_mib_desc b53_mibs_58xx[] = { +/* BCM53134 MIB counters */ +static const struct b53_mib_desc b53_mibs_134[] = { { 8, 0x00, "TxOctets" }, { 4, 0x08, "TxDropPkts" }, { 4, 0x0c, "TxQPKTQ0" }, @@ -224,105 +97,105 @@ static const struct b53_mib_desc b53_mibs_58xx[] = { { 4, 0xe4, "TxPkts1024toMaxPktOcets" }, }; -#define B53_MIBS_58XX_SIZE ARRAY_SIZE(b53_mibs_58xx) - -static int b53_do_vlan_op(struct b53_device *dev, u8 op) -{ - unsigned int i; - - b53_write8(dev, B53_ARLIO_PAGE, dev->vta_regs[0], VTA_START_CMD | op); - - for (i = 0; i < 10; i++) { - u8 vta; - - b53_read8(dev, B53_ARLIO_PAGE, dev->vta_regs[0], &vta); - if (!(vta & VTA_START_CMD)) - return 0; - - usleep_range(100, 200); - } - - return -EIO; -} - -static void b53_set_vlan_entry(struct b53_device *dev, u16 vid, - struct b53_vlan *vlan) -{ - if (is5325(dev)) { - u32 entry = 0; - - if (vlan->members) { - entry = ((vlan->untag & VA_UNTAG_MASK_25) << - VA_UNTAG_S_25) | vlan->members; - if (dev->core_rev >= 3) - entry |= VA_VALID_25_R4 | vid << VA_VID_HIGH_S; - else - entry |= VA_VALID_25; - } - - b53_write32(dev, B53_VLAN_PAGE, B53_VLAN_WRITE_25, entry); - b53_write16(dev, B53_VLAN_PAGE, B53_VLAN_TABLE_ACCESS_25, vid | - VTA_RW_STATE_WR | VTA_RW_OP_EN); - } else if (is5365(dev)) { - u16 entry = 0; - - if (vlan->members) - entry = ((vlan->untag & VA_UNTAG_MASK_65) << - VA_UNTAG_S_65) | vlan->members | VA_VALID_65; - - b53_write16(dev, B53_VLAN_PAGE, B53_VLAN_WRITE_65, entry); - b53_write16(dev, B53_VLAN_PAGE, B53_VLAN_TABLE_ACCESS_65, vid | - VTA_RW_STATE_WR | VTA_RW_OP_EN); - } else { - b53_write16(dev, B53_ARLIO_PAGE, dev->vta_regs[1], vid); - b53_write32(dev, B53_ARLIO_PAGE, dev->vta_regs[2], - (vlan->untag << VTE_UNTAG_S) | vlan->members); - - b53_do_vlan_op(dev, VTA_CMD_WRITE); - } - - dev_dbg(dev->ds->dev, "VID: %d, members: 0x%04x, untag: 0x%04x\n", - vid, vlan->members, vlan->untag); -} - -static void b53_get_vlan_entry(struct b53_device *dev, u16 vid, - struct b53_vlan *vlan) -{ - if (is5325(dev)) { - u32 entry = 0; - - b53_write16(dev, B53_VLAN_PAGE, B53_VLAN_TABLE_ACCESS_25, vid | - VTA_RW_STATE_RD | VTA_RW_OP_EN); - b53_read32(dev, B53_VLAN_PAGE, B53_VLAN_WRITE_25, &entry); - - if (dev->core_rev >= 3) - vlan->valid = !!(entry & VA_VALID_25_R4); - else - vlan->valid = !!(entry & VA_VALID_25); - vlan->members = entry & VA_MEMBER_MASK; - vlan->untag = (entry >> VA_UNTAG_S_25) & VA_UNTAG_MASK_25; - - } else if (is5365(dev)) { - u16 entry = 0; - - b53_write16(dev, B53_VLAN_PAGE, B53_VLAN_TABLE_ACCESS_65, vid | - VTA_RW_STATE_WR | VTA_RW_OP_EN); - b53_read16(dev, B53_VLAN_PAGE, B53_VLAN_WRITE_65, &entry); - - vlan->valid = !!(entry & VA_VALID_65); - vlan->members = entry & VA_MEMBER_MASK; - vlan->untag = (entry >> VA_UNTAG_S_65) & VA_UNTAG_MASK_65; - } else { - u32 entry = 0; - - b53_write16(dev, B53_ARLIO_PAGE, dev->vta_regs[1], vid); - b53_do_vlan_op(dev, VTA_CMD_READ); - b53_read32(dev, B53_ARLIO_PAGE, dev->vta_regs[2], &entry); - vlan->members = entry & VTE_MEMBERS; - vlan->untag = (entry >> VTE_UNTAG_S) & VTE_MEMBERS; - vlan->valid = true; - } -} +#define B53_MIBS_134_SIZE ARRAY_SIZE(b53_mibs_134) + +// static int b53_do_vlan_op(struct b53_device *dev, u8 op) +// { +// unsigned int i; + +// b53_write8(dev, B53_ARLIO_PAGE, dev->vta_regs[0], VTA_START_CMD | op); + +// for (i = 0; i < 10; i++) { +// u8 vta; + +// b53_read8(dev, B53_ARLIO_PAGE, dev->vta_regs[0], &vta); +// if (!(vta & VTA_START_CMD)) +// return 0; + +// usleep_range(100, 200); +// } + +// return -EIO; +// } + +// static void b53_set_vlan_entry(struct b53_device *dev, u16 vid, +// struct b53_vlan *vlan) +// { +// if (is5325(dev)) { +// u32 entry = 0; + +// if (vlan->members) { +// entry = ((vlan->untag & VA_UNTAG_MASK_25) << +// VA_UNTAG_S_25) | vlan->members; +// if (dev->core_rev >= 3) +// entry |= VA_VALID_25_R4 | vid << VA_VID_HIGH_S; +// else +// entry |= VA_VALID_25; +// } + +// b53_write32(dev, B53_VLAN_PAGE, B53_VLAN_WRITE_25, entry); +// b53_write16(dev, B53_VLAN_PAGE, B53_VLAN_TABLE_ACCESS_25, vid | +// VTA_RW_STATE_WR | VTA_RW_OP_EN); +// } else if (is5365(dev)) { +// u16 entry = 0; + +// if (vlan->members) +// entry = ((vlan->untag & VA_UNTAG_MASK_65) << +// VA_UNTAG_S_65) | vlan->members | VA_VALID_65; + +// b53_write16(dev, B53_VLAN_PAGE, B53_VLAN_WRITE_65, entry); +// b53_write16(dev, B53_VLAN_PAGE, B53_VLAN_TABLE_ACCESS_65, vid | +// VTA_RW_STATE_WR | VTA_RW_OP_EN); +// } else { +// b53_write16(dev, B53_ARLIO_PAGE, dev->vta_regs[1], vid); +// b53_write32(dev, B53_ARLIO_PAGE, dev->vta_regs[2], +// (vlan->untag << VTE_UNTAG_S) | vlan->members); + +// b53_do_vlan_op(dev, VTA_CMD_WRITE); +// } + +// dev_dbg(dev->ds->dev, "VID: %d, members: 0x%04x, untag: 0x%04x\n", +// vid, vlan->members, vlan->untag); +// } + +// static void b53_get_vlan_entry(struct b53_device *dev, u16 vid, +// struct b53_vlan *vlan) +// { +// if (is5325(dev)) { +// u32 entry = 0; + +// b53_write16(dev, B53_VLAN_PAGE, B53_VLAN_TABLE_ACCESS_25, vid | +// VTA_RW_STATE_RD | VTA_RW_OP_EN); +// b53_read32(dev, B53_VLAN_PAGE, B53_VLAN_WRITE_25, &entry); + +// if (dev->core_rev >= 3) +// vlan->valid = !!(entry & VA_VALID_25_R4); +// else +// vlan->valid = !!(entry & VA_VALID_25); +// vlan->members = entry & VA_MEMBER_MASK; +// vlan->untag = (entry >> VA_UNTAG_S_25) & VA_UNTAG_MASK_25; + +// } else if (is5365(dev)) { +// u16 entry = 0; + +// b53_write16(dev, B53_VLAN_PAGE, B53_VLAN_TABLE_ACCESS_65, vid | +// VTA_RW_STATE_WR | VTA_RW_OP_EN); +// b53_read16(dev, B53_VLAN_PAGE, B53_VLAN_WRITE_65, &entry); + +// vlan->valid = !!(entry & VA_VALID_65); +// vlan->members = entry & VA_MEMBER_MASK; +// vlan->untag = (entry >> VA_UNTAG_S_65) & VA_UNTAG_MASK_65; +// } else { +// u32 entry = 0; + +// b53_write16(dev, B53_ARLIO_PAGE, dev->vta_regs[1], vid); +// b53_do_vlan_op(dev, VTA_CMD_READ); +// b53_read32(dev, B53_ARLIO_PAGE, dev->vta_regs[2], &entry); +// vlan->members = entry & VTE_MEMBERS; +// vlan->untag = (entry >> VTE_UNTAG_S) & VTE_MEMBERS; +// vlan->valid = true; +// } +// } static void b53_set_forwarding(struct b53_device *dev, int enable) { @@ -351,101 +224,98 @@ static void b53_set_forwarding(struct b53_device *dev, int enable) b53_write8(dev, B53_CTRL_PAGE, B53_IP_MULTICAST_CTRL, mgmt); } -static void b53_enable_vlan(struct b53_device *dev, int port, bool enable, - bool enable_filtering) -{ - u8 mgmt, vc0, vc1, vc4 = 0, vc5; - - b53_read8(dev, B53_CTRL_PAGE, B53_SWITCH_MODE, &mgmt); - b53_read8(dev, B53_VLAN_PAGE, B53_VLAN_CTRL0, &vc0); - b53_read8(dev, B53_VLAN_PAGE, B53_VLAN_CTRL1, &vc1); - - if (is5325(dev) || is5365(dev)) { - b53_read8(dev, B53_VLAN_PAGE, B53_VLAN_CTRL4_25, &vc4); - b53_read8(dev, B53_VLAN_PAGE, B53_VLAN_CTRL5_25, &vc5); - } else if (is63xx(dev)) { - b53_read8(dev, B53_VLAN_PAGE, B53_VLAN_CTRL4_63XX, &vc4); - b53_read8(dev, B53_VLAN_PAGE, B53_VLAN_CTRL5_63XX, &vc5); - } else { - b53_read8(dev, B53_VLAN_PAGE, B53_VLAN_CTRL4, &vc4); - b53_read8(dev, B53_VLAN_PAGE, B53_VLAN_CTRL5, &vc5); - } - - if (enable) { - vc0 |= VC0_VLAN_EN | VC0_VID_CHK_EN | VC0_VID_HASH_VID; - vc1 |= VC1_RX_MCST_UNTAG_EN | VC1_RX_MCST_FWD_EN; - vc4 &= ~VC4_ING_VID_CHECK_MASK; - if (enable_filtering) { - vc4 |= VC4_ING_VID_VIO_DROP << VC4_ING_VID_CHECK_S; - vc5 |= VC5_DROP_VTABLE_MISS; - } else { - vc4 |= VC4_ING_VID_VIO_FWD << VC4_ING_VID_CHECK_S; - vc5 &= ~VC5_DROP_VTABLE_MISS; - } - - if (is5325(dev)) - vc0 &= ~VC0_RESERVED_1; - - if (is5325(dev) || is5365(dev)) - vc1 |= VC1_RX_MCST_TAG_EN; - - } else { - vc0 &= ~(VC0_VLAN_EN | VC0_VID_CHK_EN | VC0_VID_HASH_VID); - vc1 &= ~(VC1_RX_MCST_UNTAG_EN | VC1_RX_MCST_FWD_EN); - vc4 &= ~VC4_ING_VID_CHECK_MASK; - vc5 &= ~VC5_DROP_VTABLE_MISS; - - if (is5325(dev) || is5365(dev)) - vc4 |= VC4_ING_VID_VIO_FWD << VC4_ING_VID_CHECK_S; - else - vc4 |= VC4_ING_VID_VIO_TO_IMP << VC4_ING_VID_CHECK_S; - - if (is5325(dev) || is5365(dev)) - vc1 &= ~VC1_RX_MCST_TAG_EN; - } - - if (!is5325(dev) && !is5365(dev)) - vc5 &= ~VC5_VID_FFF_EN; - - b53_write8(dev, B53_VLAN_PAGE, B53_VLAN_CTRL0, vc0); - b53_write8(dev, B53_VLAN_PAGE, B53_VLAN_CTRL1, vc1); - - if (is5325(dev) || is5365(dev)) { - /* enable the high 8 bit vid check on 5325 */ - if (is5325(dev) && enable) - b53_write8(dev, B53_VLAN_PAGE, B53_VLAN_CTRL3, - VC3_HIGH_8BIT_EN); - else - b53_write8(dev, B53_VLAN_PAGE, B53_VLAN_CTRL3, 0); - - b53_write8(dev, B53_VLAN_PAGE, B53_VLAN_CTRL4_25, vc4); - b53_write8(dev, B53_VLAN_PAGE, B53_VLAN_CTRL5_25, vc5); - } else if (is63xx(dev)) { - b53_write16(dev, B53_VLAN_PAGE, B53_VLAN_CTRL3_63XX, 0); - b53_write8(dev, B53_VLAN_PAGE, B53_VLAN_CTRL4_63XX, vc4); - b53_write8(dev, B53_VLAN_PAGE, B53_VLAN_CTRL5_63XX, vc5); - } else { - b53_write16(dev, B53_VLAN_PAGE, B53_VLAN_CTRL3, 0); - b53_write8(dev, B53_VLAN_PAGE, B53_VLAN_CTRL4, vc4); - b53_write8(dev, B53_VLAN_PAGE, B53_VLAN_CTRL5, vc5); - } - - b53_write8(dev, B53_CTRL_PAGE, B53_SWITCH_MODE, mgmt); - - dev->vlan_enabled = enable; - - dev_dbg(dev->dev, "Port %d VLAN enabled: %d, filtering: %d\n", - port, enable, enable_filtering); -} +// static void b53_enable_vlan(struct b53_device *dev, int port, bool enable, +// bool enable_filtering) +// { +// u8 mgmt, vc0, vc1, vc4 = 0, vc5; + +// b53_read8(dev, B53_CTRL_PAGE, B53_SWITCH_MODE, &mgmt); +// b53_read8(dev, B53_VLAN_PAGE, B53_VLAN_CTRL0, &vc0); +// b53_read8(dev, B53_VLAN_PAGE, B53_VLAN_CTRL1, &vc1); + +// if (is5325(dev) || is5365(dev)) { +// b53_read8(dev, B53_VLAN_PAGE, B53_VLAN_CTRL4_25, &vc4); +// b53_read8(dev, B53_VLAN_PAGE, B53_VLAN_CTRL5_25, &vc5); +// } else if (is63xx(dev)) { +// b53_read8(dev, B53_VLAN_PAGE, B53_VLAN_CTRL4_63XX, &vc4); +// b53_read8(dev, B53_VLAN_PAGE, B53_VLAN_CTRL5_63XX, &vc5); +// } else { +// b53_read8(dev, B53_VLAN_PAGE, B53_VLAN_CTRL4, &vc4); +// b53_read8(dev, B53_VLAN_PAGE, B53_VLAN_CTRL5, &vc5); +// } + +// if (enable) { +// vc0 |= VC0_VLAN_EN | VC0_VID_CHK_EN | VC0_VID_HASH_VID; +// vc1 |= VC1_RX_MCST_UNTAG_EN | VC1_RX_MCST_FWD_EN; +// vc4 &= ~VC4_ING_VID_CHECK_MASK; +// if (enable_filtering) { +// vc4 |= VC4_ING_VID_VIO_DROP << VC4_ING_VID_CHECK_S; +// vc5 |= VC5_DROP_VTABLE_MISS; +// } else { +// vc4 |= VC4_ING_VID_VIO_FWD << VC4_ING_VID_CHECK_S; +// vc5 &= ~VC5_DROP_VTABLE_MISS; +// } + +// if (is5325(dev)) +// vc0 &= ~VC0_RESERVED_1; + +// if (is5325(dev) || is5365(dev)) +// vc1 |= VC1_RX_MCST_TAG_EN; + +// } else { +// vc0 &= ~(VC0_VLAN_EN | VC0_VID_CHK_EN | VC0_VID_HASH_VID); +// vc1 &= ~(VC1_RX_MCST_UNTAG_EN | VC1_RX_MCST_FWD_EN); +// vc4 &= ~VC4_ING_VID_CHECK_MASK; +// vc5 &= ~VC5_DROP_VTABLE_MISS; + +// if (is5325(dev) || is5365(dev)) +// vc4 |= VC4_ING_VID_VIO_FWD << VC4_ING_VID_CHECK_S; +// else +// vc4 |= VC4_ING_VID_VIO_TO_IMP << VC4_ING_VID_CHECK_S; + +// if (is5325(dev) || is5365(dev)) +// vc1 &= ~VC1_RX_MCST_TAG_EN; +// } + +// if (!is5325(dev) && !is5365(dev)) +// vc5 &= ~VC5_VID_FFF_EN; + +// b53_write8(dev, B53_VLAN_PAGE, B53_VLAN_CTRL0, vc0); +// b53_write8(dev, B53_VLAN_PAGE, B53_VLAN_CTRL1, vc1); + +// if (is5325(dev) || is5365(dev)) { +// /* enable the high 8 bit vid check on 5325 */ +// if (is5325(dev) && enable) +// b53_write8(dev, B53_VLAN_PAGE, B53_VLAN_CTRL3, +// VC3_HIGH_8BIT_EN); +// else +// b53_write8(dev, B53_VLAN_PAGE, B53_VLAN_CTRL3, 0); + +// b53_write8(dev, B53_VLAN_PAGE, B53_VLAN_CTRL4_25, vc4); +// b53_write8(dev, B53_VLAN_PAGE, B53_VLAN_CTRL5_25, vc5); +// } else if (is63xx(dev)) { +// b53_write16(dev, B53_VLAN_PAGE, B53_VLAN_CTRL3_63XX, 0); +// b53_write8(dev, B53_VLAN_PAGE, B53_VLAN_CTRL4_63XX, vc4); +// b53_write8(dev, B53_VLAN_PAGE, B53_VLAN_CTRL5_63XX, vc5); +// } else { +// b53_write16(dev, B53_VLAN_PAGE, B53_VLAN_CTRL3, 0); +// b53_write8(dev, B53_VLAN_PAGE, B53_VLAN_CTRL4, vc4); +// b53_write8(dev, B53_VLAN_PAGE, B53_VLAN_CTRL5, vc5); +// } + +// b53_write8(dev, B53_CTRL_PAGE, B53_SWITCH_MODE, mgmt); + +// dev->vlan_enabled = enable; + +// dev_dbg(dev->dev, "Port %d VLAN enabled: %d, filtering: %d\n", +// port, enable, enable_filtering); +// } static int b53_set_jumbo(struct b53_device *dev, bool enable, bool allow_10_100) { u32 port_mask = 0; u16 max_size = JMS_MIN_SIZE; - if (is5325(dev) || is5365(dev)) - return -EINVAL; - if (enable) { port_mask = dev->enabled_ports; max_size = JMS_MAX_SIZE; @@ -490,12 +360,12 @@ static int b53_fast_age_port(struct b53_device *dev, int port) return b53_flush_arl(dev, FAST_AGE_PORT); } -static int b53_fast_age_vlan(struct b53_device *dev, u16 vid) -{ - b53_write16(dev, B53_CTRL_PAGE, B53_FAST_AGE_VID_CTRL, vid); +// static int b53_fast_age_vlan(struct b53_device *dev, u16 vid) +// { +// b53_write16(dev, B53_CTRL_PAGE, B53_FAST_AGE_VID_CTRL, vid); - return b53_flush_arl(dev, FAST_AGE_VLAN); -} +// return b53_flush_arl(dev, FAST_AGE_VLAN); +// } void b53_imp_vlan_setup(struct dsa_switch *ds, int cpu_port) { @@ -625,7 +495,6 @@ void b53_brcm_hdr_setup(struct dsa_switch *ds, int port) struct b53_device *dev = ds->priv; bool tag_en; u8 hdr_ctl, val; - u16 reg; /* Resolve which bit controls the Broadcom tag */ switch (port) { @@ -646,28 +515,11 @@ void b53_brcm_hdr_setup(struct dsa_switch *ds, int port) break; } - // /* Enable management mode if tagging is requested */ - // b53_read8(dev, B53_CTRL_PAGE, B53_SWITCH_MODE, &hdr_ctl); - // if (tag_en) - // hdr_ctl |= SM_SW_FWD_MODE; - // else - // hdr_ctl &= ~SM_SW_FWD_MODE; - // b53_write8(dev, B53_CTRL_PAGE, B53_SWITCH_MODE, hdr_ctl); - - // Datum: Always disable management mode + /* Always disable management mode */ b53_read8(dev, B53_CTRL_PAGE, B53_SWITCH_MODE, &hdr_ctl); hdr_ctl &= ~SM_SW_FWD_MODE; b53_write8(dev, B53_CTRL_PAGE, B53_SWITCH_MODE, hdr_ctl); - // Datum: No in-band management ports, switch is managed via SPI (defaults to no in-band management ports) - // /* Configure the appropriate IMP port */ - // b53_read8(dev, B53_MGMT_PAGE, B53_GLOBAL_CONFIG, &hdr_ctl); - // if (port == 8) - // hdr_ctl |= GC_FRM_MGMT_PORT_MII; - // else if (port == 5) - // hdr_ctl |= GC_FRM_MGMT_PORT_M; - // b53_write8(dev, B53_MGMT_PAGE, B53_GLOBAL_CONFIG, hdr_ctl); - /* Configure Broadcom tags for IMP/CPU port */ b53_read8(dev, B53_MGMT_PAGE, B53_BRCM_HDR, &hdr_ctl); if (tag_en) @@ -675,32 +527,6 @@ void b53_brcm_hdr_setup(struct dsa_switch *ds, int port) else hdr_ctl &= ~val; b53_write8(dev, B53_MGMT_PAGE, B53_BRCM_HDR, hdr_ctl); - - /* Registers below are only accessible on newer devices */ - if (!is58xx(dev)) - return; - // Datum: BCM53134 does not have the following registers: - // B53_BRCM_HDR_RX_DIS, B53_BRCM_HDR_TX_DIS - - /* Enable reception Broadcom tag for CPU TX (switch RX) to - * allow us to tag outgoing frames - */ - b53_read16(dev, B53_MGMT_PAGE, B53_BRCM_HDR_RX_DIS, ®); - if (tag_en) - reg &= ~BIT(port); - else - reg |= BIT(port); - b53_write16(dev, B53_MGMT_PAGE, B53_BRCM_HDR_RX_DIS, reg); - - /* Enable transmission of Broadcom tags from the switch (CPU RX) to - * allow delivering frames to the per-port net_devices - */ - b53_read16(dev, B53_MGMT_PAGE, B53_BRCM_HDR_TX_DIS, ®); - if (tag_en) - reg &= ~BIT(port); - else - reg |= BIT(port); - b53_write16(dev, B53_MGMT_PAGE, B53_BRCM_HDR_TX_DIS, reg); } EXPORT_SYMBOL(b53_brcm_hdr_setup); @@ -745,68 +571,24 @@ static void b53_enable_mib(struct b53_device *dev) b53_write8(dev, B53_MGMT_PAGE, B53_GLOBAL_CONFIG, gc); } -static u16 b53_default_pvid(struct b53_device *dev) -{ - if (is5325(dev) || is5365(dev)) - return 1; - else - return 0; -} +// static u16 b53_default_pvid(struct b53_device *dev) +// { +// return 0; +// } -static bool b53_vlan_port_needs_forced_tagged(struct dsa_switch *ds, int port) -{ - struct b53_device *dev = ds->priv; +// static bool b53_vlan_port_needs_forced_tagged(struct dsa_switch *ds, int port) +// { +// struct b53_device *dev = ds->priv; - return dev->tag_protocol == DSA_TAG_PROTO_NONE && dsa_is_cpu_port(ds, port); -} +// return dev->tag_protocol == DSA_TAG_PROTO_NONE && dsa_is_cpu_port(ds, port); +// } int b53_configure_vlan(struct dsa_switch *ds) { struct b53_device *dev = ds->priv; - struct b53_vlan vl = { 0 }; - struct b53_vlan *v; - int i, def_vid; - u16 vid; - - def_vid = b53_default_pvid(dev); - - /* clear all vlan entries */ - if (is5325(dev) || is5365(dev)) { - for (i = def_vid; i < dev->num_vlans; i++) - b53_set_vlan_entry(dev, i, &vl); - } else { - b53_do_vlan_op(dev, VTA_CMD_CLEAR); - } - - b53_enable_vlan(dev, -1, dev->vlan_enabled, ds->vlan_filtering); - - /* Create an untagged VLAN entry for the default PVID in case - * CONFIG_VLAN_8021Q is disabled and there are no calls to - * dsa_slave_vlan_rx_add_vid() to create the default VLAN - * entry. Do this only when the tagging protocol is not - * DSA_TAG_PROTO_NONE - */ - b53_for_each_port(dev, i) { - v = &dev->vlans[def_vid]; - v->members |= BIT(i); - if (!b53_vlan_port_needs_forced_tagged(ds, i)) - v->untag = v->members; - b53_write16(dev, B53_VLAN_PAGE, - B53_VLAN_PORT_DEF_TAG(i), def_vid); - } - /* Upon initial call we have not set-up any VLANs, but upon - * system resume, we need to restore all VLAN entries. - */ - for (vid = def_vid; vid < dev->num_vlans; vid++) { - v = &dev->vlans[vid]; - - if (!v->members) - continue; - - b53_set_vlan_entry(dev, vid, v); - b53_fast_age_vlan(dev, vid); - } + /* Join all VLANs for all ports (promiscuous mode) */ + b53_write16(dev, B53_VLAN_PAGE, B53_JOIN_ALL_VLAN_EN, VJA_ALL_PORTS_MASK); return 0; } @@ -856,35 +638,22 @@ static int b53_switch_reset(struct b53_device *dev) b53_switch_reset_gpio(dev); - if (is539x(dev)) { - b53_write8(dev, B53_CTRL_PAGE, B53_SOFTRESET, 0x83); - b53_write8(dev, B53_CTRL_PAGE, B53_SOFTRESET, 0x00); - } + b53_read8(dev, B53_CTRL_PAGE, B53_SOFTRESET, ®); + reg |= SW_RST | EN_SW_RST | EN_CH_RST; + b53_write8(dev, B53_CTRL_PAGE, B53_SOFTRESET, reg); - /* This is specific to 58xx devices here, do not use is58xx() which - * covers the larger Starfigther 2 family, including 7445/7278 which - * still use this driver as a library and need to perform the reset - * earlier. - */ - if (dev->chip_id == BCM58XX_DEVICE_ID || - dev->chip_id == BCM583XX_DEVICE_ID) { + do { b53_read8(dev, B53_CTRL_PAGE, B53_SOFTRESET, ®); - reg |= SW_RST | EN_SW_RST | EN_CH_RST; - b53_write8(dev, B53_CTRL_PAGE, B53_SOFTRESET, reg); - - do { - b53_read8(dev, B53_CTRL_PAGE, B53_SOFTRESET, ®); - if (!(reg & SW_RST)) - break; + if (!(reg & SW_RST)) + break; - usleep_range(1000, 2000); - } while (timeout-- > 0); + usleep_range(1000, 2000); + } while (timeout-- > 0); - if (timeout == 0) { - dev_err(dev->dev, - "Timeout waiting for SW_RST to clear!\n"); - return -ETIMEDOUT; - } + if (timeout == 0) { + dev_err(dev->dev, + "Timeout waiting for SW_RST to clear!\n"); + return -ETIMEDOUT; } b53_read8(dev, B53_CTRL_PAGE, B53_SWITCH_MODE, &mgmt); @@ -970,26 +739,12 @@ static void b53_reset_mib(struct b53_device *priv) static const struct b53_mib_desc *b53_get_mib(struct b53_device *dev) { - if (is5365(dev)) - return b53_mibs_65; - else if (is63xx(dev)) - return b53_mibs_63xx; - else if (is58xx(dev)) - return b53_mibs_58xx; - else - return b53_mibs; + return b53_mibs_134; } static unsigned int b53_get_mib_size(struct b53_device *dev) { - if (is5365(dev)) - return B53_MIBS_65_SIZE; - else if (is63xx(dev)) - return B53_MIBS_63XX_SIZE; - else if (is58xx(dev)) - return B53_MIBS_58XX_SIZE; - else - return B53_MIBS_SIZE; + return B53_MIBS_134_SIZE; } static struct phy_device *b53_get_phy_device(struct dsa_switch *ds, int port) @@ -1037,8 +792,8 @@ void b53_get_ethtool_stats(struct dsa_switch *ds, int port, uint64_t *data) unsigned int i; u64 val = 0; - if (is5365(dev) && port == 5) - port = 8; + // if (is5365(dev) && port == 5) + // port = 8; mutex_lock(&dev->stats_mutex); @@ -1271,16 +1026,16 @@ static void b53_adjust_link(struct dsa_switch *ds, int port, { struct b53_device *dev = ds->priv; struct ethtool_eee *p = &dev->ports[port].eee; - u8 rgmii_ctrl = 0, reg = 0, off; + u8 rgmii_ctrl = 0, off; bool tx_pause = false; bool rx_pause = false; if (!phy_is_pseudo_fixed_link(phydev)) return; - /* Enable flow control on BCM5301x's CPU port */ - if (is5301x(dev) && port == dev->cpu_port) - tx_pause = rx_pause = true; + // /* Enable flow control on BCM5301x's CPU port */ + // if (is5301x(dev) && port == dev->cpu_port) + // tx_pause = rx_pause = true; if (phydev->pause) { if (phydev->asym_pause) @@ -1292,7 +1047,7 @@ static void b53_adjust_link(struct dsa_switch *ds, int port, tx_pause, rx_pause); b53_force_link(dev, port, phydev->link); - if (is531x5(dev) && phy_interface_is_rgmii(phydev)) { + if (phy_interface_is_rgmii(phydev)) { if (port == dev->imp_port) off = B53_RGMII_CTRL_IMP; else @@ -1335,32 +1090,6 @@ static void b53_adjust_link(struct dsa_switch *ds, int port, phy_modes(phydev->interface), rgmii_ctrl); } - /* configure MII port if necessary */ - if (is5325(dev)) { - b53_read8(dev, B53_CTRL_PAGE, B53_PORT_OVERRIDE_CTRL, - ®); - - /* reverse mii needs to be enabled */ - if (!(reg & PORT_OVERRIDE_RV_MII_25)) { - b53_write8(dev, B53_CTRL_PAGE, B53_PORT_OVERRIDE_CTRL, - reg | PORT_OVERRIDE_RV_MII_25); - b53_read8(dev, B53_CTRL_PAGE, B53_PORT_OVERRIDE_CTRL, - ®); - - if (!(reg & PORT_OVERRIDE_RV_MII_25)) { - dev_err(ds->dev, - "Failed to enable reverse MII mode\n"); - return; - } - } - } else if (is5301x(dev)) { - if (port != dev->cpu_port) { - b53_force_port_config(dev, dev->cpu_port, 2000, - DUPLEX_FULL, true, true); - b53_force_link(dev, dev->cpu_port, 1); - } - } - /* Re-negotiate EEE if it was enabled already */ p->eee_enabled = b53_eee_init(ds, port, phydev); } @@ -1398,8 +1127,7 @@ void b53_phylink_validate(struct dsa_switch *ds, int port, */ if (state->interface != PHY_INTERFACE_MODE_MII && state->interface != PHY_INTERFACE_MODE_REVMII && - !phy_interface_mode_is_8023z(state->interface) && - !(is5325(dev) || is5365(dev))) { + !phy_interface_mode_is_8023z(state->interface)) { phylink_set(mask, 1000baseT_Full); phylink_set(mask, 1000baseT_Half); } @@ -1507,112 +1235,112 @@ void b53_phylink_mac_link_up(struct dsa_switch *ds, int port, } EXPORT_SYMBOL(b53_phylink_mac_link_up); -int b53_vlan_filtering(struct dsa_switch *ds, int port, bool vlan_filtering, - struct netlink_ext_ack *extack) -{ - struct b53_device *dev = ds->priv; +// int b53_vlan_filtering(struct dsa_switch *ds, int port, bool vlan_filtering, +// struct netlink_ext_ack *extack) +// { +// struct b53_device *dev = ds->priv; - b53_enable_vlan(dev, port, dev->vlan_enabled, vlan_filtering); +// b53_enable_vlan(dev, port, dev->vlan_enabled, vlan_filtering); - return 0; -} -EXPORT_SYMBOL(b53_vlan_filtering); +// return 0; +// } +// EXPORT_SYMBOL(b53_vlan_filtering); -static int b53_vlan_prepare(struct dsa_switch *ds, int port, - const struct switchdev_obj_port_vlan *vlan) -{ - struct b53_device *dev = ds->priv; +// static int b53_vlan_prepare(struct dsa_switch *ds, int port, +// const struct switchdev_obj_port_vlan *vlan) +// { +// struct b53_device *dev = ds->priv; - if ((is5325(dev) || is5365(dev)) && vlan->vid == 0) - return -EOPNOTSUPP; +// if ((is5325(dev) || is5365(dev)) && vlan->vid == 0) +// return -EOPNOTSUPP; - /* Port 7 on 7278 connects to the ASP's UniMAC which is not capable of - * receiving VLAN tagged frames at all, we can still allow the port to - * be configured for egress untagged. - */ - if (dev->chip_id == BCM7278_DEVICE_ID && port == 7 && - !(vlan->flags & BRIDGE_VLAN_INFO_UNTAGGED)) - return -EINVAL; +// /* Port 7 on 7278 connects to the ASP's UniMAC which is not capable of +// * receiving VLAN tagged frames at all, we can still allow the port to +// * be configured for egress untagged. +// */ +// if (dev->chip_id == BCM7278_DEVICE_ID && port == 7 && +// !(vlan->flags & BRIDGE_VLAN_INFO_UNTAGGED)) +// return -EINVAL; - if (vlan->vid >= dev->num_vlans) - return -ERANGE; +// if (vlan->vid >= dev->num_vlans) +// return -ERANGE; - b53_enable_vlan(dev, port, true, ds->vlan_filtering); +// b53_enable_vlan(dev, port, true, ds->vlan_filtering); - return 0; -} +// return 0; +// } -int b53_vlan_add(struct dsa_switch *ds, int port, - const struct switchdev_obj_port_vlan *vlan, - struct netlink_ext_ack *extack) -{ - struct b53_device *dev = ds->priv; - bool untagged = vlan->flags & BRIDGE_VLAN_INFO_UNTAGGED; - bool pvid = vlan->flags & BRIDGE_VLAN_INFO_PVID; - struct b53_vlan *vl; - int err; +// int b53_vlan_add(struct dsa_switch *ds, int port, +// const struct switchdev_obj_port_vlan *vlan, +// struct netlink_ext_ack *extack) +// { +// struct b53_device *dev = ds->priv; +// bool untagged = vlan->flags & BRIDGE_VLAN_INFO_UNTAGGED; +// bool pvid = vlan->flags & BRIDGE_VLAN_INFO_PVID; +// struct b53_vlan *vl; +// int err; - err = b53_vlan_prepare(ds, port, vlan); - if (err) - return err; +// err = b53_vlan_prepare(ds, port, vlan); +// if (err) +// return err; - vl = &dev->vlans[vlan->vid]; +// vl = &dev->vlans[vlan->vid]; - b53_get_vlan_entry(dev, vlan->vid, vl); +// b53_get_vlan_entry(dev, vlan->vid, vl); - if (vlan->vid == 0 && vlan->vid == b53_default_pvid(dev)) - untagged = true; +// if (vlan->vid == 0 && vlan->vid == b53_default_pvid(dev)) +// untagged = true; - vl->members |= BIT(port); - if (untagged && !b53_vlan_port_needs_forced_tagged(ds, port)) - vl->untag |= BIT(port); - else - vl->untag &= ~BIT(port); +// vl->members |= BIT(port); +// if (untagged && !b53_vlan_port_needs_forced_tagged(ds, port)) +// vl->untag |= BIT(port); +// else +// vl->untag &= ~BIT(port); - b53_set_vlan_entry(dev, vlan->vid, vl); - b53_fast_age_vlan(dev, vlan->vid); +// b53_set_vlan_entry(dev, vlan->vid, vl); +// b53_fast_age_vlan(dev, vlan->vid); - if (pvid && !dsa_is_cpu_port(ds, port)) { - b53_write16(dev, B53_VLAN_PAGE, B53_VLAN_PORT_DEF_TAG(port), - vlan->vid); - b53_fast_age_vlan(dev, vlan->vid); - } +// if (pvid && !dsa_is_cpu_port(ds, port)) { +// b53_write16(dev, B53_VLAN_PAGE, B53_VLAN_PORT_DEF_TAG(port), +// vlan->vid); +// b53_fast_age_vlan(dev, vlan->vid); +// } - return 0; -} -EXPORT_SYMBOL(b53_vlan_add); +// return 0; +// } +// EXPORT_SYMBOL(b53_vlan_add); -int b53_vlan_del(struct dsa_switch *ds, int port, - const struct switchdev_obj_port_vlan *vlan) -{ - struct b53_device *dev = ds->priv; - bool untagged = vlan->flags & BRIDGE_VLAN_INFO_UNTAGGED; - struct b53_vlan *vl; - u16 pvid; +// int b53_vlan_del(struct dsa_switch *ds, int port, +// const struct switchdev_obj_port_vlan *vlan) +// { +// struct b53_device *dev = ds->priv; +// bool untagged = vlan->flags & BRIDGE_VLAN_INFO_UNTAGGED; +// struct b53_vlan *vl; +// u16 pvid; - b53_read16(dev, B53_VLAN_PAGE, B53_VLAN_PORT_DEF_TAG(port), &pvid); +// b53_read16(dev, B53_VLAN_PAGE, B53_VLAN_PORT_DEF_TAG(port), &pvid); - vl = &dev->vlans[vlan->vid]; +// vl = &dev->vlans[vlan->vid]; - b53_get_vlan_entry(dev, vlan->vid, vl); +// b53_get_vlan_entry(dev, vlan->vid, vl); - vl->members &= ~BIT(port); +// vl->members &= ~BIT(port); - if (pvid == vlan->vid) - pvid = b53_default_pvid(dev); +// if (pvid == vlan->vid) +// pvid = b53_default_pvid(dev); - if (untagged && !b53_vlan_port_needs_forced_tagged(ds, port)) - vl->untag &= ~(BIT(port)); +// if (untagged && !b53_vlan_port_needs_forced_tagged(ds, port)) +// vl->untag &= ~(BIT(port)); - b53_set_vlan_entry(dev, vlan->vid, vl); - b53_fast_age_vlan(dev, vlan->vid); +// b53_set_vlan_entry(dev, vlan->vid, vl); +// b53_fast_age_vlan(dev, vlan->vid); - b53_write16(dev, B53_VLAN_PAGE, B53_VLAN_PORT_DEF_TAG(port), pvid); - b53_fast_age_vlan(dev, pvid); +// b53_write16(dev, B53_VLAN_PAGE, B53_VLAN_PORT_DEF_TAG(port), pvid); +// b53_fast_age_vlan(dev, pvid); - return 0; -} -EXPORT_SYMBOL(b53_vlan_del); +// return 0; +// } +// EXPORT_SYMBOL(b53_vlan_del); /* Address Resolution Logic routines */ static int b53_arl_op_wait(struct b53_device *dev) @@ -1780,12 +1508,6 @@ int b53_fdb_add(struct dsa_switch *ds, int port, { struct b53_device *priv = ds->priv; - /* 5325 and 5365 require some more massaging, but could - * be supported eventually - */ - if (is5325(priv) || is5365(priv)) - return -EOPNOTSUPP; - return b53_arl_op(priv, 0, port, addr, vid, true); } EXPORT_SYMBOL(b53_fdb_add); @@ -1887,12 +1609,6 @@ int b53_mdb_add(struct dsa_switch *ds, int port, { struct b53_device *priv = ds->priv; - /* 5325 and 5365 require some more massaging, but could - * be supported eventually - */ - if (is5325(priv) || is5365(priv)) - return -EOPNOTSUPP; - return b53_arl_op(priv, 0, port, mdb->addr, mdb->vid, true); } EXPORT_SYMBOL(b53_mdb_add); @@ -1911,141 +1627,141 @@ int b53_mdb_del(struct dsa_switch *ds, int port, } EXPORT_SYMBOL(b53_mdb_del); -int b53_br_join(struct dsa_switch *ds, int port, struct net_device *br) -{ - struct b53_device *dev = ds->priv; - s8 cpu_port = dsa_to_port(ds, port)->cpu_dp->index; - u16 pvlan, reg; - unsigned int i; - - /* On 7278, port 7 which connects to the ASP should only receive - * traffic from matching CFP rules. - */ - if (dev->chip_id == BCM7278_DEVICE_ID && port == 7) - return -EINVAL; - - /* Make this port leave the all VLANs join since we will have proper - * VLAN entries from now on - */ - if (is58xx(dev)) { - b53_read16(dev, B53_VLAN_PAGE, B53_JOIN_ALL_VLAN_EN, ®); - reg &= ~BIT(port); - if ((reg & BIT(cpu_port)) == BIT(cpu_port)) - reg &= ~BIT(cpu_port); - b53_write16(dev, B53_VLAN_PAGE, B53_JOIN_ALL_VLAN_EN, reg); - } - - b53_read16(dev, B53_PVLAN_PAGE, B53_PVLAN_PORT_MASK(port), &pvlan); - - b53_for_each_port(dev, i) { - if (dsa_to_port(ds, i)->bridge_dev != br) - continue; - - /* Add this local port to the remote port VLAN control - * membership and update the remote port bitmask - */ - b53_read16(dev, B53_PVLAN_PAGE, B53_PVLAN_PORT_MASK(i), ®); - reg |= BIT(port); - b53_write16(dev, B53_PVLAN_PAGE, B53_PVLAN_PORT_MASK(i), reg); - dev->ports[i].vlan_ctl_mask = reg; - - pvlan |= BIT(i); - } - - /* Configure the local port VLAN control membership to include - * remote ports and update the local port bitmask - */ - b53_write16(dev, B53_PVLAN_PAGE, B53_PVLAN_PORT_MASK(port), pvlan); - dev->ports[port].vlan_ctl_mask = pvlan; - - b53_for_each_port(dev, i) - b53_read16(dev, B53_PVLAN_PAGE, B53_PVLAN_PORT_MASK(i), ®); - - return 0; -} -EXPORT_SYMBOL(b53_br_join); - -void b53_br_leave(struct dsa_switch *ds, int port, struct net_device *br) -{ - struct b53_device *dev = ds->priv; - struct b53_vlan *vl = &dev->vlans[0]; - s8 cpu_port = dsa_to_port(ds, port)->cpu_dp->index; - unsigned int i; - u16 pvlan, reg, pvid; - - b53_read16(dev, B53_PVLAN_PAGE, B53_PVLAN_PORT_MASK(port), &pvlan); - - b53_for_each_port(dev, i) { - /* Don't touch the remaining ports */ - if (dsa_to_port(ds, i)->bridge_dev != br) - continue; - - b53_read16(dev, B53_PVLAN_PAGE, B53_PVLAN_PORT_MASK(i), ®); - reg &= ~BIT(port); - b53_write16(dev, B53_PVLAN_PAGE, B53_PVLAN_PORT_MASK(i), reg); - dev->ports[port].vlan_ctl_mask = reg; - - /* Prevent self removal to preserve isolation */ - if (port != i) - pvlan &= ~BIT(i); - } - - b53_write16(dev, B53_PVLAN_PAGE, B53_PVLAN_PORT_MASK(port), pvlan); - dev->ports[port].vlan_ctl_mask = pvlan; - - pvid = b53_default_pvid(dev); - - /* Make this port join all VLANs without VLAN entries */ - if (is58xx(dev)) { - b53_read16(dev, B53_VLAN_PAGE, B53_JOIN_ALL_VLAN_EN, ®); - reg |= BIT(port); - if (!(reg & BIT(cpu_port))) - reg |= BIT(cpu_port); - b53_write16(dev, B53_VLAN_PAGE, B53_JOIN_ALL_VLAN_EN, reg); - } else { - b53_get_vlan_entry(dev, pvid, vl); - vl->members |= BIT(port) | BIT(cpu_port); - vl->untag |= BIT(port) | BIT(cpu_port); - b53_set_vlan_entry(dev, pvid, vl); - } - b53_for_each_port(dev, i) - b53_read16(dev, B53_PVLAN_PAGE, B53_PVLAN_PORT_MASK(i), ®); -} -EXPORT_SYMBOL(b53_br_leave); - -void b53_br_set_stp_state(struct dsa_switch *ds, int port, u8 state) -{ - struct b53_device *dev = ds->priv; - u8 hw_state; - u8 reg; - - switch (state) { - case BR_STATE_DISABLED: - hw_state = PORT_CTRL_DIS_STATE; - break; - case BR_STATE_LISTENING: - hw_state = PORT_CTRL_LISTEN_STATE; - break; - case BR_STATE_LEARNING: - hw_state = PORT_CTRL_LEARN_STATE; - break; - case BR_STATE_FORWARDING: - hw_state = PORT_CTRL_FWD_STATE; - break; - case BR_STATE_BLOCKING: - hw_state = PORT_CTRL_BLOCK_STATE; - break; - default: - dev_err(ds->dev, "invalid STP state: %d\n", state); - return; - } - - b53_read8(dev, B53_CTRL_PAGE, B53_PORT_CTRL(port), ®); - reg &= ~PORT_CTRL_STP_STATE_MASK; - reg |= hw_state; - b53_write8(dev, B53_CTRL_PAGE, B53_PORT_CTRL(port), reg); -} -EXPORT_SYMBOL(b53_br_set_stp_state); +// int b53_br_join(struct dsa_switch *ds, int port, struct net_device *br) +// { +// struct b53_device *dev = ds->priv; +// s8 cpu_port = dsa_to_port(ds, port)->cpu_dp->index; +// u16 pvlan, reg; +// unsigned int i; + +// /* On 7278, port 7 which connects to the ASP should only receive +// * traffic from matching CFP rules. +// */ +// if (dev->chip_id == BCM7278_DEVICE_ID && port == 7) +// return -EINVAL; + +// /* Make this port leave the all VLANs join since we will have proper +// * VLAN entries from now on +// */ +// if (is58xx(dev)) { +// b53_read16(dev, B53_VLAN_PAGE, B53_JOIN_ALL_VLAN_EN, ®); +// reg &= ~BIT(port); +// if ((reg & BIT(cpu_port)) == BIT(cpu_port)) +// reg &= ~BIT(cpu_port); +// b53_write16(dev, B53_VLAN_PAGE, B53_JOIN_ALL_VLAN_EN, reg); +// } + +// b53_read16(dev, B53_PVLAN_PAGE, B53_PVLAN_PORT_MASK(port), &pvlan); + +// b53_for_each_port(dev, i) { +// if (dsa_to_port(ds, i)->bridge_dev != br) +// continue; + +// /* Add this local port to the remote port VLAN control +// * membership and update the remote port bitmask +// */ +// b53_read16(dev, B53_PVLAN_PAGE, B53_PVLAN_PORT_MASK(i), ®); +// reg |= BIT(port); +// b53_write16(dev, B53_PVLAN_PAGE, B53_PVLAN_PORT_MASK(i), reg); +// dev->ports[i].vlan_ctl_mask = reg; + +// pvlan |= BIT(i); +// } + +// /* Configure the local port VLAN control membership to include +// * remote ports and update the local port bitmask +// */ +// b53_write16(dev, B53_PVLAN_PAGE, B53_PVLAN_PORT_MASK(port), pvlan); +// dev->ports[port].vlan_ctl_mask = pvlan; + +// b53_for_each_port(dev, i) +// b53_read16(dev, B53_PVLAN_PAGE, B53_PVLAN_PORT_MASK(i), ®); + +// return 0; +// } +// EXPORT_SYMBOL(b53_br_join); + +// void b53_br_leave(struct dsa_switch *ds, int port, struct net_device *br) +// { +// struct b53_device *dev = ds->priv; +// struct b53_vlan *vl = &dev->vlans[0]; +// s8 cpu_port = dsa_to_port(ds, port)->cpu_dp->index; +// unsigned int i; +// u16 pvlan, reg, pvid; + +// b53_read16(dev, B53_PVLAN_PAGE, B53_PVLAN_PORT_MASK(port), &pvlan); + +// b53_for_each_port(dev, i) { +// /* Don't touch the remaining ports */ +// if (dsa_to_port(ds, i)->bridge_dev != br) +// continue; + +// b53_read16(dev, B53_PVLAN_PAGE, B53_PVLAN_PORT_MASK(i), ®); +// reg &= ~BIT(port); +// b53_write16(dev, B53_PVLAN_PAGE, B53_PVLAN_PORT_MASK(i), reg); +// dev->ports[port].vlan_ctl_mask = reg; + +// /* Prevent self removal to preserve isolation */ +// if (port != i) +// pvlan &= ~BIT(i); +// } + +// b53_write16(dev, B53_PVLAN_PAGE, B53_PVLAN_PORT_MASK(port), pvlan); +// dev->ports[port].vlan_ctl_mask = pvlan; + +// pvid = b53_default_pvid(dev); + +// /* Make this port join all VLANs without VLAN entries */ +// if (is58xx(dev)) { +// b53_read16(dev, B53_VLAN_PAGE, B53_JOIN_ALL_VLAN_EN, ®); +// reg |= BIT(port); +// if (!(reg & BIT(cpu_port))) +// reg |= BIT(cpu_port); +// b53_write16(dev, B53_VLAN_PAGE, B53_JOIN_ALL_VLAN_EN, reg); +// } else { +// b53_get_vlan_entry(dev, pvid, vl); +// vl->members |= BIT(port) | BIT(cpu_port); +// vl->untag |= BIT(port) | BIT(cpu_port); +// b53_set_vlan_entry(dev, pvid, vl); +// } +// b53_for_each_port(dev, i) +// b53_read16(dev, B53_PVLAN_PAGE, B53_PVLAN_PORT_MASK(i), ®); +// } +// EXPORT_SYMBOL(b53_br_leave); + +// void b53_br_set_stp_state(struct dsa_switch *ds, int port, u8 state) +// { +// struct b53_device *dev = ds->priv; +// u8 hw_state; +// u8 reg; + +// switch (state) { +// case BR_STATE_DISABLED: +// hw_state = PORT_CTRL_DIS_STATE; +// break; +// case BR_STATE_LISTENING: +// hw_state = PORT_CTRL_LISTEN_STATE; +// break; +// case BR_STATE_LEARNING: +// hw_state = PORT_CTRL_LEARN_STATE; +// break; +// case BR_STATE_FORWARDING: +// hw_state = PORT_CTRL_FWD_STATE; +// break; +// case BR_STATE_BLOCKING: +// hw_state = PORT_CTRL_BLOCK_STATE; +// break; +// default: +// dev_err(ds->dev, "invalid STP state: %d\n", state); +// return; +// } + +// b53_read8(dev, B53_CTRL_PAGE, B53_PORT_CTRL(port), ®); +// reg &= ~PORT_CTRL_STP_STATE_MASK; +// reg |= hw_state; +// b53_write8(dev, B53_CTRL_PAGE, B53_PORT_CTRL(port), reg); +// } +// EXPORT_SYMBOL(b53_br_set_stp_state); void b53_br_fast_age(struct dsa_switch *ds, int port) { @@ -2133,7 +1849,7 @@ enum dsa_tag_protocol b53_get_tag_protocol(struct dsa_switch *ds, int port, { struct b53_device *dev = ds->priv; - if(port == 8) + if(port == B53_CPU_PORT) return dev->tag_protocol_imp; if (!b53_can_enable_brcm_tags(ds, port, mprot)) { @@ -2141,28 +1857,8 @@ enum dsa_tag_protocol b53_get_tag_protocol(struct dsa_switch *ds, int port, goto out; } - /* Older models require a different 6 byte tag */ - if (is5325(dev) || is5365(dev) || is63xx(dev)) { - dev->tag_protocol = DSA_TAG_PROTO_BRCM_LEGACY; - goto out; - } - - /* Broadcom BCM58xx chips have a flow accelerator on Port 8 - * which requires us to use the prepended Broadcom tag type - */ - if (dev->chip_id == BCM58XX_DEVICE_ID && port == B53_CPU_PORT) { - dev->tag_protocol = DSA_TAG_PROTO_BRCM_PREPEND; - goto out; - } - - out: - // Datum: Always set tag_protocol to NONE (cpu) - dev->tag_protocol = DSA_TAG_PROTO_NONE; - if(port == B53_CPU_PORT) - return dev->tag_protocol_imp; - else - return dev->tag_protocol; + return dev->tag_protocol; } EXPORT_SYMBOL(b53_get_tag_protocol); @@ -2284,9 +1980,6 @@ int b53_get_mac_eee(struct dsa_switch *ds, int port, struct ethtool_eee *e) struct ethtool_eee *p = &dev->ports[port].eee; u16 reg; - if (is5325(dev) || is5365(dev)) - return -EOPNOTSUPP; - b53_read16(dev, B53_EEE_PAGE, B53_EEE_LPI_INDICATE, ®); e->eee_enabled = p->eee_enabled; e->eee_active = !!(reg & BIT(port)); @@ -2300,9 +1993,6 @@ int b53_set_mac_eee(struct dsa_switch *ds, int port, struct ethtool_eee *e) struct b53_device *dev = ds->priv; struct ethtool_eee *p = &dev->ports[port].eee; - if (is5325(dev) || is5365(dev)) - return -EOPNOTSUPP; - p->eee_enabled = e->eee_enabled; b53_eee_enable_set(ds, port, e->eee_enabled); @@ -2316,9 +2006,6 @@ static int b53_change_mtu(struct dsa_switch *ds, int port, int mtu) bool enable_jumbo; bool allow_10_100; - if (is5325(dev) || is5365(dev)) - return -EOPNOTSUPP; - enable_jumbo = (mtu >= JMS_MIN_SIZE); allow_10_100 = (dev->chip_id == BCM583XX_DEVICE_ID); @@ -2427,15 +2114,15 @@ static const struct dsa_switch_ops b53_switch_ops = { .port_disable = b53_disable_port, .get_mac_eee = b53_get_mac_eee, .set_mac_eee = b53_set_mac_eee, - .port_bridge_join = b53_br_join, - .port_bridge_leave = b53_br_leave, + // .port_bridge_join = b53_br_join, + // .port_bridge_leave = b53_br_leave, .port_pre_bridge_flags = b53_br_flags_pre, .port_bridge_flags = b53_br_flags, - .port_stp_state_set = b53_br_set_stp_state, + // .port_stp_state_set = b53_br_set_stp_state, .port_fast_age = b53_br_fast_age, - .port_vlan_filtering = b53_vlan_filtering, - .port_vlan_add = b53_vlan_add, - .port_vlan_del = b53_vlan_del, + // .port_vlan_filtering = b53_vlan_filtering, + // .port_vlan_add = b53_vlan_add, + // .port_vlan_del = b53_vlan_del, .port_fdb_dump = b53_fdb_dump, .port_fdb_add = b53_fdb_add, .port_fdb_del = b53_fdb_del, @@ -2794,38 +2481,38 @@ static int b53_switch_init(struct b53_device *dev) } } - /* check which BCM5325x version we have */ - if (is5325(dev)) { - u8 vc4; - - b53_read8(dev, B53_VLAN_PAGE, B53_VLAN_CTRL4_25, &vc4); - - /* check reserved bits */ - switch (vc4 & 3) { - case 1: - /* BCM5325E */ - break; - case 3: - /* BCM5325F - do not use port 4 */ - dev->enabled_ports &= ~BIT(4); - break; - default: -/* On the BCM47XX SoCs this is the supported internal switch.*/ -#ifndef CONFIG_BCM47XX - /* BCM5325M */ - return -EINVAL; -#else - break; -#endif - } - } else if (dev->chip_id == BCM53115_DEVICE_ID) { - u64 strap_value; - - b53_read48(dev, B53_STAT_PAGE, B53_STRAP_VALUE, &strap_value); - /* use second IMP port if GMII is enabled */ - if (strap_value & SV_GMII_CTRL_115) - dev->cpu_port = 5; - } +// /* check which BCM5325x version we have */ +// if (is5325(dev)) { +// u8 vc4; + +// b53_read8(dev, B53_VLAN_PAGE, B53_VLAN_CTRL4_25, &vc4); + +// /* check reserved bits */ +// switch (vc4 & 3) { +// case 1: +// /* BCM5325E */ +// break; +// case 3: +// /* BCM5325F - do not use port 4 */ +// dev->enabled_ports &= ~BIT(4); +// break; +// default: +// /* On the BCM47XX SoCs this is the supported internal switch.*/ +// #ifndef CONFIG_BCM47XX +// /* BCM5325M */ +// return -EINVAL; +// #else +// break; +// #endif +// } +// } else if (dev->chip_id == BCM53115_DEVICE_ID) { +// u64 strap_value; + +// b53_read48(dev, B53_STAT_PAGE, B53_STRAP_VALUE, &strap_value); +// /* use second IMP port if GMII is enabled */ +// if (strap_value & SV_GMII_CTRL_115) +// dev->cpu_port = 5; +// } dev->enabled_ports |= BIT(dev->cpu_port); dev->num_ports = fls(dev->enabled_ports); @@ -2833,16 +2520,14 @@ static int b53_switch_init(struct b53_device *dev) dev->ds->num_ports = min_t(unsigned int, dev->num_ports, DSA_MAX_PORTS); /* Include non standard CPU port built-in PHYs to be probed */ - if (is539x(dev) || is531x5(dev)) { - for (i = 0; i < dev->num_ports; i++) { - if (!(dev->ds->phys_mii_mask & BIT(i)) && - !b53_possible_cpu_port(dev->ds, i)) - dev->ds->phys_mii_mask |= BIT(i); - } - /* Default cpu to no tagging, imp Port to brcm tagging */ - dev->tag_protocol = DSA_TAG_PROTO_NONE; - dev->tag_protocol_imp = DSA_TAG_PROTO_BRCM; + for (i = 0; i < dev->num_ports; i++) { + if (!(dev->ds->phys_mii_mask & BIT(i)) && + !b53_possible_cpu_port(dev->ds, i)) + dev->ds->phys_mii_mask |= BIT(i); } + /* Default cpu to no tagging, imp Port to brcm tagging */ + dev->tag_protocol = DSA_TAG_PROTO_NONE; + dev->tag_protocol_imp = DSA_TAG_PROTO_BRCM; dev->ports = devm_kcalloc(dev->dev, dev->num_ports, sizeof(struct b53_port), GFP_KERNEL); @@ -2870,8 +2555,6 @@ static int b53_switch_init(struct b53_device *dev) if (!dev->vlans) return -ENOMEM; - /* Join all VLANs for all ports (promiscuous mode) */ - b53_write16(dev, B53_VLAN_PAGE, B53_JOIN_ALL_VLAN_EN, VJA_ALL_PORTS_MASK); dev->reset_gpio = b53_switch_get_reset_gpio(dev); if (dev->reset_gpio >= 0) { diff --git a/drivers/net/dsa/b53/b53_priv.h b/drivers/net/dsa/b53/b53_priv.h index 6a5f936d9d5bcd..a17504932cf838 100644 --- a/drivers/net/dsa/b53/b53_priv.h +++ b/drivers/net/dsa/b53/b53_priv.h @@ -159,63 +159,63 @@ struct b53_device { if (dev->enabled_ports & BIT(i)) -static inline int is5325(struct b53_device *dev) -{ - return dev->chip_id == BCM5325_DEVICE_ID; -} - -static inline int is5365(struct b53_device *dev) -{ -#ifdef CONFIG_BCM47XX - return dev->chip_id == BCM5365_DEVICE_ID; -#else - return 0; -#endif -} - -static inline int is5397_98(struct b53_device *dev) -{ - return dev->chip_id == BCM5397_DEVICE_ID || - dev->chip_id == BCM5398_DEVICE_ID; -} - -static inline int is539x(struct b53_device *dev) -{ - return dev->chip_id == BCM5395_DEVICE_ID || - dev->chip_id == BCM5397_DEVICE_ID || - dev->chip_id == BCM5398_DEVICE_ID; -} - -static inline int is531x5(struct b53_device *dev) -{ - return dev->chip_id == BCM53115_DEVICE_ID || - dev->chip_id == BCM53125_DEVICE_ID || - dev->chip_id == BCM53128_DEVICE_ID || - dev->chip_id == BCM53134_DEVICE_ID; -} - -static inline int is63xx(struct b53_device *dev) -{ - return dev->chip_id == BCM63XX_DEVICE_ID; -} - -static inline int is5301x(struct b53_device *dev) -{ - return dev->chip_id == BCM53010_DEVICE_ID || - dev->chip_id == BCM53011_DEVICE_ID || - dev->chip_id == BCM53012_DEVICE_ID || - dev->chip_id == BCM53018_DEVICE_ID || - dev->chip_id == BCM53019_DEVICE_ID; -} - -static inline int is58xx(struct b53_device *dev) -{ - return dev->chip_id == BCM58XX_DEVICE_ID || - dev->chip_id == BCM583XX_DEVICE_ID || - dev->chip_id == BCM7445_DEVICE_ID || - dev->chip_id == BCM7278_DEVICE_ID || - dev->chip_id == BCM53134_DEVICE_ID; -} +// static inline int is5325(struct b53_device *dev) +// { +// return dev->chip_id == BCM5325_DEVICE_ID; +// } + +// static inline int is5365(struct b53_device *dev) +// { +// #ifdef CONFIG_BCM47XX +// return dev->chip_id == BCM5365_DEVICE_ID; +// #else +// return 0; +// #endif +// } + +// static inline int is5397_98(struct b53_device *dev) +// { +// return dev->chip_id == BCM5397_DEVICE_ID || +// dev->chip_id == BCM5398_DEVICE_ID; +// } + +// static inline int is539x(struct b53_device *dev) +// { +// return dev->chip_id == BCM5395_DEVICE_ID || +// dev->chip_id == BCM5397_DEVICE_ID || +// dev->chip_id == BCM5398_DEVICE_ID; +// } + +// static inline int is531x5(struct b53_device *dev) +// { +// return dev->chip_id == BCM53115_DEVICE_ID || +// dev->chip_id == BCM53125_DEVICE_ID || +// dev->chip_id == BCM53128_DEVICE_ID || +// dev->chip_id == BCM53134_DEVICE_ID; +// } + +// static inline int is63xx(struct b53_device *dev) +// { +// return dev->chip_id == BCM63XX_DEVICE_ID; +// } + +// static inline int is5301x(struct b53_device *dev) +// { +// return dev->chip_id == BCM53010_DEVICE_ID || +// dev->chip_id == BCM53011_DEVICE_ID || +// dev->chip_id == BCM53012_DEVICE_ID || +// dev->chip_id == BCM53018_DEVICE_ID || +// dev->chip_id == BCM53019_DEVICE_ID; +// } + +// static inline int is58xx(struct b53_device *dev) +// { +// return dev->chip_id == BCM58XX_DEVICE_ID || +// dev->chip_id == BCM583XX_DEVICE_ID || +// dev->chip_id == BCM7445_DEVICE_ID || +// dev->chip_id == BCM7278_DEVICE_ID || +// dev->chip_id == BCM53134_DEVICE_ID; +// } #define B53_CPU_PORT_25 5 #define B53_CPU_PORT 8 diff --git a/drivers/net/dsa/b53/b53_regs.h b/drivers/net/dsa/b53/b53_regs.h index e78807d5d30ae7..5ffc54cd0eb289 100644 --- a/drivers/net/dsa/b53/b53_regs.h +++ b/drivers/net/dsa/b53/b53_regs.h @@ -24,16 +24,12 @@ #define B53_CTRL_PAGE 0x00 /* Control */ #define B53_STAT_PAGE 0x01 /* Status */ #define B53_MGMT_PAGE 0x02 /* Management Mode */ -#define B53_MIB_AC_PAGE 0x03 /* MIB Autocast */ +#define B53_ICR PAGE 0x03 /* Interrrupt Control Register */ #define B53_ARLCTRL_PAGE 0x04 /* ARL Control */ #define B53_ARLIO_PAGE 0x05 /* ARL Access */ -#define B53_FRAMEBUF_PAGE 0x06 /* Management frame access */ -#define B53_MEM_ACCESS_PAGE 0x08 /* Memory access */ /* PHY Registers */ #define B53_PORT_MII_PAGE(i) (0x10 + (i)) /* Port i MII Registers */ -#define B53_IM_PORT_PAGE 0x18 /* Inverse MII Port (to EMAC) */ -#define B53_ALL_PORT_PAGE 0x19 /* All ports MII (broadcast) */ /* MIB registers */ #define B53_MIB_PAGE(i) (0x20 + (i)) From efbebbefd286152b85d59928a429f52a464c1d3f Mon Sep 17 00:00:00 2001 From: Mark Carlin Date: Mon, 12 Feb 2024 10:33:05 -0700 Subject: [PATCH 11/27] Additional cleanup for BR53143 driver. Change kernel version to 5.15.107-datum.5 --- Makefile | 2 +- drivers/net/dsa/b53/b53_common.c | 486 ------------------------------- 2 files changed, 1 insertion(+), 487 deletions(-) diff --git a/Makefile b/Makefile index c28b2a2daa5ce8..ebd6f6b41001e8 100644 --- a/Makefile +++ b/Makefile @@ -2,7 +2,7 @@ VERSION = 5 PATCHLEVEL = 15 SUBLEVEL = 107 -EXTRAVERSION = -datum.4 +EXTRAVERSION = -datum.5 NAME = Trick or Treat # *DOCUMENTATION* diff --git a/drivers/net/dsa/b53/b53_common.c b/drivers/net/dsa/b53/b53_common.c index 437614f5e1ecc5..4944a03f22df3c 100644 --- a/drivers/net/dsa/b53/b53_common.c +++ b/drivers/net/dsa/b53/b53_common.c @@ -99,104 +99,6 @@ static const struct b53_mib_desc b53_mibs_134[] = { #define B53_MIBS_134_SIZE ARRAY_SIZE(b53_mibs_134) -// static int b53_do_vlan_op(struct b53_device *dev, u8 op) -// { -// unsigned int i; - -// b53_write8(dev, B53_ARLIO_PAGE, dev->vta_regs[0], VTA_START_CMD | op); - -// for (i = 0; i < 10; i++) { -// u8 vta; - -// b53_read8(dev, B53_ARLIO_PAGE, dev->vta_regs[0], &vta); -// if (!(vta & VTA_START_CMD)) -// return 0; - -// usleep_range(100, 200); -// } - -// return -EIO; -// } - -// static void b53_set_vlan_entry(struct b53_device *dev, u16 vid, -// struct b53_vlan *vlan) -// { -// if (is5325(dev)) { -// u32 entry = 0; - -// if (vlan->members) { -// entry = ((vlan->untag & VA_UNTAG_MASK_25) << -// VA_UNTAG_S_25) | vlan->members; -// if (dev->core_rev >= 3) -// entry |= VA_VALID_25_R4 | vid << VA_VID_HIGH_S; -// else -// entry |= VA_VALID_25; -// } - -// b53_write32(dev, B53_VLAN_PAGE, B53_VLAN_WRITE_25, entry); -// b53_write16(dev, B53_VLAN_PAGE, B53_VLAN_TABLE_ACCESS_25, vid | -// VTA_RW_STATE_WR | VTA_RW_OP_EN); -// } else if (is5365(dev)) { -// u16 entry = 0; - -// if (vlan->members) -// entry = ((vlan->untag & VA_UNTAG_MASK_65) << -// VA_UNTAG_S_65) | vlan->members | VA_VALID_65; - -// b53_write16(dev, B53_VLAN_PAGE, B53_VLAN_WRITE_65, entry); -// b53_write16(dev, B53_VLAN_PAGE, B53_VLAN_TABLE_ACCESS_65, vid | -// VTA_RW_STATE_WR | VTA_RW_OP_EN); -// } else { -// b53_write16(dev, B53_ARLIO_PAGE, dev->vta_regs[1], vid); -// b53_write32(dev, B53_ARLIO_PAGE, dev->vta_regs[2], -// (vlan->untag << VTE_UNTAG_S) | vlan->members); - -// b53_do_vlan_op(dev, VTA_CMD_WRITE); -// } - -// dev_dbg(dev->ds->dev, "VID: %d, members: 0x%04x, untag: 0x%04x\n", -// vid, vlan->members, vlan->untag); -// } - -// static void b53_get_vlan_entry(struct b53_device *dev, u16 vid, -// struct b53_vlan *vlan) -// { -// if (is5325(dev)) { -// u32 entry = 0; - -// b53_write16(dev, B53_VLAN_PAGE, B53_VLAN_TABLE_ACCESS_25, vid | -// VTA_RW_STATE_RD | VTA_RW_OP_EN); -// b53_read32(dev, B53_VLAN_PAGE, B53_VLAN_WRITE_25, &entry); - -// if (dev->core_rev >= 3) -// vlan->valid = !!(entry & VA_VALID_25_R4); -// else -// vlan->valid = !!(entry & VA_VALID_25); -// vlan->members = entry & VA_MEMBER_MASK; -// vlan->untag = (entry >> VA_UNTAG_S_25) & VA_UNTAG_MASK_25; - -// } else if (is5365(dev)) { -// u16 entry = 0; - -// b53_write16(dev, B53_VLAN_PAGE, B53_VLAN_TABLE_ACCESS_65, vid | -// VTA_RW_STATE_WR | VTA_RW_OP_EN); -// b53_read16(dev, B53_VLAN_PAGE, B53_VLAN_WRITE_65, &entry); - -// vlan->valid = !!(entry & VA_VALID_65); -// vlan->members = entry & VA_MEMBER_MASK; -// vlan->untag = (entry >> VA_UNTAG_S_65) & VA_UNTAG_MASK_65; -// } else { -// u32 entry = 0; - -// b53_write16(dev, B53_ARLIO_PAGE, dev->vta_regs[1], vid); -// b53_do_vlan_op(dev, VTA_CMD_READ); -// b53_read32(dev, B53_ARLIO_PAGE, dev->vta_regs[2], &entry); -// vlan->members = entry & VTE_MEMBERS; -// vlan->untag = (entry >> VTE_UNTAG_S) & VTE_MEMBERS; -// vlan->valid = true; -// } -// } - static void b53_set_forwarding(struct b53_device *dev, int enable) { u8 mgmt; @@ -224,93 +126,6 @@ static void b53_set_forwarding(struct b53_device *dev, int enable) b53_write8(dev, B53_CTRL_PAGE, B53_IP_MULTICAST_CTRL, mgmt); } -// static void b53_enable_vlan(struct b53_device *dev, int port, bool enable, -// bool enable_filtering) -// { -// u8 mgmt, vc0, vc1, vc4 = 0, vc5; - -// b53_read8(dev, B53_CTRL_PAGE, B53_SWITCH_MODE, &mgmt); -// b53_read8(dev, B53_VLAN_PAGE, B53_VLAN_CTRL0, &vc0); -// b53_read8(dev, B53_VLAN_PAGE, B53_VLAN_CTRL1, &vc1); - -// if (is5325(dev) || is5365(dev)) { -// b53_read8(dev, B53_VLAN_PAGE, B53_VLAN_CTRL4_25, &vc4); -// b53_read8(dev, B53_VLAN_PAGE, B53_VLAN_CTRL5_25, &vc5); -// } else if (is63xx(dev)) { -// b53_read8(dev, B53_VLAN_PAGE, B53_VLAN_CTRL4_63XX, &vc4); -// b53_read8(dev, B53_VLAN_PAGE, B53_VLAN_CTRL5_63XX, &vc5); -// } else { -// b53_read8(dev, B53_VLAN_PAGE, B53_VLAN_CTRL4, &vc4); -// b53_read8(dev, B53_VLAN_PAGE, B53_VLAN_CTRL5, &vc5); -// } - -// if (enable) { -// vc0 |= VC0_VLAN_EN | VC0_VID_CHK_EN | VC0_VID_HASH_VID; -// vc1 |= VC1_RX_MCST_UNTAG_EN | VC1_RX_MCST_FWD_EN; -// vc4 &= ~VC4_ING_VID_CHECK_MASK; -// if (enable_filtering) { -// vc4 |= VC4_ING_VID_VIO_DROP << VC4_ING_VID_CHECK_S; -// vc5 |= VC5_DROP_VTABLE_MISS; -// } else { -// vc4 |= VC4_ING_VID_VIO_FWD << VC4_ING_VID_CHECK_S; -// vc5 &= ~VC5_DROP_VTABLE_MISS; -// } - -// if (is5325(dev)) -// vc0 &= ~VC0_RESERVED_1; - -// if (is5325(dev) || is5365(dev)) -// vc1 |= VC1_RX_MCST_TAG_EN; - -// } else { -// vc0 &= ~(VC0_VLAN_EN | VC0_VID_CHK_EN | VC0_VID_HASH_VID); -// vc1 &= ~(VC1_RX_MCST_UNTAG_EN | VC1_RX_MCST_FWD_EN); -// vc4 &= ~VC4_ING_VID_CHECK_MASK; -// vc5 &= ~VC5_DROP_VTABLE_MISS; - -// if (is5325(dev) || is5365(dev)) -// vc4 |= VC4_ING_VID_VIO_FWD << VC4_ING_VID_CHECK_S; -// else -// vc4 |= VC4_ING_VID_VIO_TO_IMP << VC4_ING_VID_CHECK_S; - -// if (is5325(dev) || is5365(dev)) -// vc1 &= ~VC1_RX_MCST_TAG_EN; -// } - -// if (!is5325(dev) && !is5365(dev)) -// vc5 &= ~VC5_VID_FFF_EN; - -// b53_write8(dev, B53_VLAN_PAGE, B53_VLAN_CTRL0, vc0); -// b53_write8(dev, B53_VLAN_PAGE, B53_VLAN_CTRL1, vc1); - -// if (is5325(dev) || is5365(dev)) { -// /* enable the high 8 bit vid check on 5325 */ -// if (is5325(dev) && enable) -// b53_write8(dev, B53_VLAN_PAGE, B53_VLAN_CTRL3, -// VC3_HIGH_8BIT_EN); -// else -// b53_write8(dev, B53_VLAN_PAGE, B53_VLAN_CTRL3, 0); - -// b53_write8(dev, B53_VLAN_PAGE, B53_VLAN_CTRL4_25, vc4); -// b53_write8(dev, B53_VLAN_PAGE, B53_VLAN_CTRL5_25, vc5); -// } else if (is63xx(dev)) { -// b53_write16(dev, B53_VLAN_PAGE, B53_VLAN_CTRL3_63XX, 0); -// b53_write8(dev, B53_VLAN_PAGE, B53_VLAN_CTRL4_63XX, vc4); -// b53_write8(dev, B53_VLAN_PAGE, B53_VLAN_CTRL5_63XX, vc5); -// } else { -// b53_write16(dev, B53_VLAN_PAGE, B53_VLAN_CTRL3, 0); -// b53_write8(dev, B53_VLAN_PAGE, B53_VLAN_CTRL4, vc4); -// b53_write8(dev, B53_VLAN_PAGE, B53_VLAN_CTRL5, vc5); -// } - -// b53_write8(dev, B53_CTRL_PAGE, B53_SWITCH_MODE, mgmt); - -// dev->vlan_enabled = enable; - -// dev_dbg(dev->dev, "Port %d VLAN enabled: %d, filtering: %d\n", -// port, enable, enable_filtering); -// } - static int b53_set_jumbo(struct b53_device *dev, bool enable, bool allow_10_100) { u32 port_mask = 0; @@ -360,13 +175,6 @@ static int b53_fast_age_port(struct b53_device *dev, int port) return b53_flush_arl(dev, FAST_AGE_PORT); } -// static int b53_fast_age_vlan(struct b53_device *dev, u16 vid) -// { -// b53_write16(dev, B53_CTRL_PAGE, B53_FAST_AGE_VID_CTRL, vid); - -// return b53_flush_arl(dev, FAST_AGE_VLAN); -// } - void b53_imp_vlan_setup(struct dsa_switch *ds, int cpu_port) { struct b53_device *dev = ds->priv; @@ -571,17 +379,6 @@ static void b53_enable_mib(struct b53_device *dev) b53_write8(dev, B53_MGMT_PAGE, B53_GLOBAL_CONFIG, gc); } -// static u16 b53_default_pvid(struct b53_device *dev) -// { -// return 0; -// } - -// static bool b53_vlan_port_needs_forced_tagged(struct dsa_switch *ds, int port) -// { -// struct b53_device *dev = ds->priv; - -// return dev->tag_protocol == DSA_TAG_PROTO_NONE && dsa_is_cpu_port(ds, port); -// } int b53_configure_vlan(struct dsa_switch *ds) { @@ -630,7 +427,6 @@ static void b53_switch_reset_gpiod(struct b53_device *dev) dev->current_page = 0xff; } - static int b53_switch_reset(struct b53_device *dev) { unsigned int timeout = 1000; @@ -1235,113 +1031,6 @@ void b53_phylink_mac_link_up(struct dsa_switch *ds, int port, } EXPORT_SYMBOL(b53_phylink_mac_link_up); -// int b53_vlan_filtering(struct dsa_switch *ds, int port, bool vlan_filtering, -// struct netlink_ext_ack *extack) -// { -// struct b53_device *dev = ds->priv; - -// b53_enable_vlan(dev, port, dev->vlan_enabled, vlan_filtering); - -// return 0; -// } -// EXPORT_SYMBOL(b53_vlan_filtering); - -// static int b53_vlan_prepare(struct dsa_switch *ds, int port, -// const struct switchdev_obj_port_vlan *vlan) -// { -// struct b53_device *dev = ds->priv; - -// if ((is5325(dev) || is5365(dev)) && vlan->vid == 0) -// return -EOPNOTSUPP; - -// /* Port 7 on 7278 connects to the ASP's UniMAC which is not capable of -// * receiving VLAN tagged frames at all, we can still allow the port to -// * be configured for egress untagged. -// */ -// if (dev->chip_id == BCM7278_DEVICE_ID && port == 7 && -// !(vlan->flags & BRIDGE_VLAN_INFO_UNTAGGED)) -// return -EINVAL; - -// if (vlan->vid >= dev->num_vlans) -// return -ERANGE; - -// b53_enable_vlan(dev, port, true, ds->vlan_filtering); - -// return 0; -// } - -// int b53_vlan_add(struct dsa_switch *ds, int port, -// const struct switchdev_obj_port_vlan *vlan, -// struct netlink_ext_ack *extack) -// { -// struct b53_device *dev = ds->priv; -// bool untagged = vlan->flags & BRIDGE_VLAN_INFO_UNTAGGED; -// bool pvid = vlan->flags & BRIDGE_VLAN_INFO_PVID; -// struct b53_vlan *vl; -// int err; - -// err = b53_vlan_prepare(ds, port, vlan); -// if (err) -// return err; - -// vl = &dev->vlans[vlan->vid]; - -// b53_get_vlan_entry(dev, vlan->vid, vl); - -// if (vlan->vid == 0 && vlan->vid == b53_default_pvid(dev)) -// untagged = true; - -// vl->members |= BIT(port); -// if (untagged && !b53_vlan_port_needs_forced_tagged(ds, port)) -// vl->untag |= BIT(port); -// else -// vl->untag &= ~BIT(port); - -// b53_set_vlan_entry(dev, vlan->vid, vl); -// b53_fast_age_vlan(dev, vlan->vid); - -// if (pvid && !dsa_is_cpu_port(ds, port)) { -// b53_write16(dev, B53_VLAN_PAGE, B53_VLAN_PORT_DEF_TAG(port), -// vlan->vid); -// b53_fast_age_vlan(dev, vlan->vid); -// } - -// return 0; -// } -// EXPORT_SYMBOL(b53_vlan_add); - -// int b53_vlan_del(struct dsa_switch *ds, int port, -// const struct switchdev_obj_port_vlan *vlan) -// { -// struct b53_device *dev = ds->priv; -// bool untagged = vlan->flags & BRIDGE_VLAN_INFO_UNTAGGED; -// struct b53_vlan *vl; -// u16 pvid; - -// b53_read16(dev, B53_VLAN_PAGE, B53_VLAN_PORT_DEF_TAG(port), &pvid); - -// vl = &dev->vlans[vlan->vid]; - -// b53_get_vlan_entry(dev, vlan->vid, vl); - -// vl->members &= ~BIT(port); - -// if (pvid == vlan->vid) -// pvid = b53_default_pvid(dev); - -// if (untagged && !b53_vlan_port_needs_forced_tagged(ds, port)) -// vl->untag &= ~(BIT(port)); - -// b53_set_vlan_entry(dev, vlan->vid, vl); -// b53_fast_age_vlan(dev, vlan->vid); - -// b53_write16(dev, B53_VLAN_PAGE, B53_VLAN_PORT_DEF_TAG(port), pvid); -// b53_fast_age_vlan(dev, pvid); - -// return 0; -// } -// EXPORT_SYMBOL(b53_vlan_del); - /* Address Resolution Logic routines */ static int b53_arl_op_wait(struct b53_device *dev) { @@ -1627,142 +1316,6 @@ int b53_mdb_del(struct dsa_switch *ds, int port, } EXPORT_SYMBOL(b53_mdb_del); -// int b53_br_join(struct dsa_switch *ds, int port, struct net_device *br) -// { -// struct b53_device *dev = ds->priv; -// s8 cpu_port = dsa_to_port(ds, port)->cpu_dp->index; -// u16 pvlan, reg; -// unsigned int i; - -// /* On 7278, port 7 which connects to the ASP should only receive -// * traffic from matching CFP rules. -// */ -// if (dev->chip_id == BCM7278_DEVICE_ID && port == 7) -// return -EINVAL; - -// /* Make this port leave the all VLANs join since we will have proper -// * VLAN entries from now on -// */ -// if (is58xx(dev)) { -// b53_read16(dev, B53_VLAN_PAGE, B53_JOIN_ALL_VLAN_EN, ®); -// reg &= ~BIT(port); -// if ((reg & BIT(cpu_port)) == BIT(cpu_port)) -// reg &= ~BIT(cpu_port); -// b53_write16(dev, B53_VLAN_PAGE, B53_JOIN_ALL_VLAN_EN, reg); -// } - -// b53_read16(dev, B53_PVLAN_PAGE, B53_PVLAN_PORT_MASK(port), &pvlan); - -// b53_for_each_port(dev, i) { -// if (dsa_to_port(ds, i)->bridge_dev != br) -// continue; - -// /* Add this local port to the remote port VLAN control -// * membership and update the remote port bitmask -// */ -// b53_read16(dev, B53_PVLAN_PAGE, B53_PVLAN_PORT_MASK(i), ®); -// reg |= BIT(port); -// b53_write16(dev, B53_PVLAN_PAGE, B53_PVLAN_PORT_MASK(i), reg); -// dev->ports[i].vlan_ctl_mask = reg; - -// pvlan |= BIT(i); -// } - -// /* Configure the local port VLAN control membership to include -// * remote ports and update the local port bitmask -// */ -// b53_write16(dev, B53_PVLAN_PAGE, B53_PVLAN_PORT_MASK(port), pvlan); -// dev->ports[port].vlan_ctl_mask = pvlan; - -// b53_for_each_port(dev, i) -// b53_read16(dev, B53_PVLAN_PAGE, B53_PVLAN_PORT_MASK(i), ®); - -// return 0; -// } -// EXPORT_SYMBOL(b53_br_join); - -// void b53_br_leave(struct dsa_switch *ds, int port, struct net_device *br) -// { -// struct b53_device *dev = ds->priv; -// struct b53_vlan *vl = &dev->vlans[0]; -// s8 cpu_port = dsa_to_port(ds, port)->cpu_dp->index; -// unsigned int i; -// u16 pvlan, reg, pvid; - -// b53_read16(dev, B53_PVLAN_PAGE, B53_PVLAN_PORT_MASK(port), &pvlan); - -// b53_for_each_port(dev, i) { -// /* Don't touch the remaining ports */ -// if (dsa_to_port(ds, i)->bridge_dev != br) -// continue; - -// b53_read16(dev, B53_PVLAN_PAGE, B53_PVLAN_PORT_MASK(i), ®); -// reg &= ~BIT(port); -// b53_write16(dev, B53_PVLAN_PAGE, B53_PVLAN_PORT_MASK(i), reg); -// dev->ports[port].vlan_ctl_mask = reg; - -// /* Prevent self removal to preserve isolation */ -// if (port != i) -// pvlan &= ~BIT(i); -// } - -// b53_write16(dev, B53_PVLAN_PAGE, B53_PVLAN_PORT_MASK(port), pvlan); -// dev->ports[port].vlan_ctl_mask = pvlan; - -// pvid = b53_default_pvid(dev); - -// /* Make this port join all VLANs without VLAN entries */ -// if (is58xx(dev)) { -// b53_read16(dev, B53_VLAN_PAGE, B53_JOIN_ALL_VLAN_EN, ®); -// reg |= BIT(port); -// if (!(reg & BIT(cpu_port))) -// reg |= BIT(cpu_port); -// b53_write16(dev, B53_VLAN_PAGE, B53_JOIN_ALL_VLAN_EN, reg); -// } else { -// b53_get_vlan_entry(dev, pvid, vl); -// vl->members |= BIT(port) | BIT(cpu_port); -// vl->untag |= BIT(port) | BIT(cpu_port); -// b53_set_vlan_entry(dev, pvid, vl); -// } -// b53_for_each_port(dev, i) -// b53_read16(dev, B53_PVLAN_PAGE, B53_PVLAN_PORT_MASK(i), ®); -// } -// EXPORT_SYMBOL(b53_br_leave); - -// void b53_br_set_stp_state(struct dsa_switch *ds, int port, u8 state) -// { -// struct b53_device *dev = ds->priv; -// u8 hw_state; -// u8 reg; - -// switch (state) { -// case BR_STATE_DISABLED: -// hw_state = PORT_CTRL_DIS_STATE; -// break; -// case BR_STATE_LISTENING: -// hw_state = PORT_CTRL_LISTEN_STATE; -// break; -// case BR_STATE_LEARNING: -// hw_state = PORT_CTRL_LEARN_STATE; -// break; -// case BR_STATE_FORWARDING: -// hw_state = PORT_CTRL_FWD_STATE; -// break; -// case BR_STATE_BLOCKING: -// hw_state = PORT_CTRL_BLOCK_STATE; -// break; -// default: -// dev_err(ds->dev, "invalid STP state: %d\n", state); -// return; -// } - -// b53_read8(dev, B53_CTRL_PAGE, B53_PORT_CTRL(port), ®); -// reg &= ~PORT_CTRL_STP_STATE_MASK; -// reg |= hw_state; -// b53_write8(dev, B53_CTRL_PAGE, B53_PORT_CTRL(port), reg); -// } -// EXPORT_SYMBOL(b53_br_set_stp_state); - void b53_br_fast_age(struct dsa_switch *ds, int port) { struct b53_device *dev = ds->priv; @@ -2114,15 +1667,9 @@ static const struct dsa_switch_ops b53_switch_ops = { .port_disable = b53_disable_port, .get_mac_eee = b53_get_mac_eee, .set_mac_eee = b53_set_mac_eee, - // .port_bridge_join = b53_br_join, - // .port_bridge_leave = b53_br_leave, .port_pre_bridge_flags = b53_br_flags_pre, .port_bridge_flags = b53_br_flags, - // .port_stp_state_set = b53_br_set_stp_state, .port_fast_age = b53_br_fast_age, - // .port_vlan_filtering = b53_vlan_filtering, - // .port_vlan_add = b53_vlan_add, - // .port_vlan_del = b53_vlan_del, .port_fdb_dump = b53_fdb_dump, .port_fdb_add = b53_fdb_add, .port_fdb_del = b53_fdb_del, @@ -2481,39 +2028,6 @@ static int b53_switch_init(struct b53_device *dev) } } -// /* check which BCM5325x version we have */ -// if (is5325(dev)) { -// u8 vc4; - -// b53_read8(dev, B53_VLAN_PAGE, B53_VLAN_CTRL4_25, &vc4); - -// /* check reserved bits */ -// switch (vc4 & 3) { -// case 1: -// /* BCM5325E */ -// break; -// case 3: -// /* BCM5325F - do not use port 4 */ -// dev->enabled_ports &= ~BIT(4); -// break; -// default: -// /* On the BCM47XX SoCs this is the supported internal switch.*/ -// #ifndef CONFIG_BCM47XX -// /* BCM5325M */ -// return -EINVAL; -// #else -// break; -// #endif -// } -// } else if (dev->chip_id == BCM53115_DEVICE_ID) { -// u64 strap_value; - -// b53_read48(dev, B53_STAT_PAGE, B53_STRAP_VALUE, &strap_value); -// /* use second IMP port if GMII is enabled */ -// if (strap_value & SV_GMII_CTRL_115) -// dev->cpu_port = 5; -// } - dev->enabled_ports |= BIT(dev->cpu_port); dev->num_ports = fls(dev->enabled_ports); From b0d33954f81b8821f1ed4dced463ffc455b385b2 Mon Sep 17 00:00:00 2001 From: Mark Carlin Date: Tue, 20 Feb 2024 15:55:35 -0700 Subject: [PATCH 12/27] Add code to read BCM53154 device tree and properly set RGMII internal delays. Version 5.15.107-datum.6 --- Makefile | 2 +- drivers/net/dsa/b53/b53_common.c | 15 +++----------- include/net/dsa.h | 1 + net/dsa/dsa2.c | 34 ++++++++++++++++++++++++++++++++ 4 files changed, 39 insertions(+), 13 deletions(-) diff --git a/Makefile b/Makefile index ebd6f6b41001e8..dfd55dc8e2671a 100644 --- a/Makefile +++ b/Makefile @@ -2,7 +2,7 @@ VERSION = 5 PATCHLEVEL = 15 SUBLEVEL = 107 -EXTRAVERSION = -datum.5 +EXTRAVERSION = -datum.6 NAME = Trick or Treat # *DOCUMENTATION* diff --git a/drivers/net/dsa/b53/b53_common.c b/drivers/net/dsa/b53/b53_common.c index 4944a03f22df3c..e485bcea9208d5 100644 --- a/drivers/net/dsa/b53/b53_common.c +++ b/drivers/net/dsa/b53/b53_common.c @@ -829,10 +829,6 @@ static void b53_adjust_link(struct dsa_switch *ds, int port, if (!phy_is_pseudo_fixed_link(phydev)) return; - // /* Enable flow control on BCM5301x's CPU port */ - // if (is5301x(dev) && port == dev->cpu_port) - // tx_pause = rx_pause = true; - if (phydev->pause) { if (phydev->asym_pause) tx_pause = true; @@ -852,9 +848,7 @@ static void b53_adjust_link(struct dsa_switch *ds, int port, /* Configure the port RGMII clock delay by DLL disabled and * tx_clk aligned timing (restoring to reset defaults) */ - b53_read8(dev, B53_CTRL_PAGE, off, &rgmii_ctrl); - rgmii_ctrl &= ~(RGMII_CTRL_DLL_RXC | RGMII_CTRL_DLL_TXC | - RGMII_CTRL_TIMING_SEL); + rgmii_ctrl = 0x00; /* PHY_INTERFACE_MODE_RGMII_TXID means TX internal delay, make * sure that we enable the port TX clock internal delay to @@ -874,12 +868,9 @@ static void b53_adjust_link(struct dsa_switch *ds, int port, rgmii_ctrl |= RGMII_CTRL_DLL_TXC; if (phydev->interface == PHY_INTERFACE_MODE_RGMII_RXID) rgmii_ctrl |= RGMII_CTRL_DLL_RXC; - if (phydev->interface == PHY_INTERFACE_MODE_RGMII) + if (phydev->interface == PHY_INTERFACE_MODE_RGMII_ID) rgmii_ctrl |= (RGMII_CTRL_DLL_TXC | RGMII_CTRL_DLL_RXC); - //rgmii_ctrl |= RGMII_CTRL_TIMING_SEL; - rgmii_ctrl = (RGMII_CTRL_DLL_TXC | RGMII_CTRL_DLL_RXC); - //rgmii_ctrl = RGMII_CTRL_DLL_TXC; - //rgmii_ctrl = RGMII_CTRL_DLL_RXC; + b53_write8(dev, B53_CTRL_PAGE, off, rgmii_ctrl); dev_info(ds->dev, "Configured port %d for %s (reg=0x%02x)\n", port, diff --git a/include/net/dsa.h b/include/net/dsa.h index f639092a6b256b..87b438a286063e 100644 --- a/include/net/dsa.h +++ b/include/net/dsa.h @@ -241,6 +241,7 @@ struct dsa_port { DSA_PORT_TYPE_CPU, DSA_PORT_TYPE_DSA, DSA_PORT_TYPE_USER, + DSA_PORT_TYPE_IMP } type; struct dsa_switch *ds; diff --git a/net/dsa/dsa2.c b/net/dsa/dsa2.c index 3a8f6fe3a0405b..71d8b8e3f0e4fa 100644 --- a/net/dsa/dsa2.c +++ b/net/dsa/dsa2.c @@ -461,6 +461,18 @@ static int dsa_port_setup(struct dsa_port *dp) dsa_port_enabled = true; break; + case DSA_PORT_TYPE_IMP: + err = dsa_port_link_register_of(dp); + if (err) + break; + dsa_port_link_registered = true; + + err = dsa_port_enable(dp, NULL); + if (err) + break; + dsa_port_enabled = true; + + break; case DSA_PORT_TYPE_DSA: err = dsa_port_link_register_of(dp); if (err) @@ -526,6 +538,9 @@ static int dsa_port_devlink_setup(struct dsa_port *dp) case DSA_PORT_TYPE_DSA: attrs.flavour = DEVLINK_PORT_FLAVOUR_DSA; break; + case DSA_PORT_TYPE_IMP: + attrs.flavour = DEVLINK_PORT_FLAVOUR_PHYSICAL; + break; case DSA_PORT_TYPE_USER: attrs.flavour = DEVLINK_PORT_FLAVOUR_PHYSICAL; break; @@ -561,6 +576,10 @@ static void dsa_port_teardown(struct dsa_port *dp) dsa_port_disable(dp); dsa_port_link_unregister_of(dp); break; + case DSA_PORT_TYPE_IMP: + dsa_port_disable(dp); + dsa_port_link_unregister_of(dp); + break; case DSA_PORT_TYPE_DSA: dsa_port_disable(dp); dsa_port_link_unregister_of(dp); @@ -1224,6 +1243,17 @@ static int dsa_port_parse_dsa(struct dsa_port *dp) return 0; } +static int dsa_port_parse_imp(struct dsa_port *dp, const char *name) +{ + if (!name) + name = "imp%d"; + + dp->type = DSA_PORT_TYPE_IMP; + dp->name = name; + + return 0; +} + static enum dsa_tag_protocol dsa_get_tag_protocol(struct dsa_port *dp, struct net_device *master) { @@ -1358,6 +1388,10 @@ static int dsa_port_parse_of(struct dsa_port *dp, struct device_node *dn) return dsa_port_parse_cpu(dp, master, user_protocol); } + if(of_property_read_bool(dn, "port-imp")) { + return dsa_port_parse_imp(dp, name); + } + if (link) return dsa_port_parse_dsa(dp); From 57c45cca7ab406530590a7b9222e85b781912282 Mon Sep 17 00:00:00 2001 From: Mark Carlin Date: Wed, 21 Feb 2024 15:38:52 -0700 Subject: [PATCH 13/27] Add imp port back into netdev. This will allow us to gather statistics, monitor RMGII link status, etc. Version 5.15.107-datum.7 --- Makefile | 2 +- include/net/dsa.h | 4 ++-- net/dsa/dsa.c | 2 +- net/dsa/dsa2.c | 21 ++++++++++++++++++--- net/dsa/dsa_priv.h | 2 +- net/dsa/slave.c | 2 +- 6 files changed, 24 insertions(+), 9 deletions(-) diff --git a/Makefile b/Makefile index dfd55dc8e2671a..1f47a71551c909 100644 --- a/Makefile +++ b/Makefile @@ -2,7 +2,7 @@ VERSION = 5 PATCHLEVEL = 15 SUBLEVEL = 107 -EXTRAVERSION = -datum.6 +EXTRAVERSION = -datum.7 NAME = Trick or Treat # *DOCUMENTATION* diff --git a/include/net/dsa.h b/include/net/dsa.h index 87b438a286063e..b4781a9a8bafcc 100644 --- a/include/net/dsa.h +++ b/include/net/dsa.h @@ -445,7 +445,7 @@ static inline bool dsa_port_is_cpu(struct dsa_port *port) static inline bool dsa_port_is_user(struct dsa_port *dp) { - return dp->type == DSA_PORT_TYPE_USER; + return (dp->type == DSA_PORT_TYPE_USER) || (dp->type == DSA_PORT_TYPE_IMP); } static inline bool dsa_port_is_unused(struct dsa_port *dp) @@ -470,7 +470,7 @@ static inline bool dsa_is_dsa_port(struct dsa_switch *ds, int p) static inline bool dsa_is_user_port(struct dsa_switch *ds, int p) { - return dsa_to_port(ds, p)->type == DSA_PORT_TYPE_USER; + return dsa_to_port(ds, p)->type == DSA_PORT_TYPE_USER || dsa_to_port(ds, p)->type == DSA_PORT_TYPE_IMP; } static inline u32 dsa_user_ports(struct dsa_switch *ds) diff --git a/net/dsa/dsa.c b/net/dsa/dsa.c index 41f36ad8b0ec67..f9a3656681ef0d 100644 --- a/net/dsa/dsa.c +++ b/net/dsa/dsa.c @@ -284,7 +284,7 @@ static bool dsa_is_port_initialized(struct dsa_switch *ds, int p) { const struct dsa_port *dp = dsa_to_port(ds, p); - return dp->type == DSA_PORT_TYPE_USER && dp->slave; + return (dp->type == DSA_PORT_TYPE_USER || dp->type == DSA_PORT_TYPE_IMP) && dp->slave; } int dsa_switch_suspend(struct dsa_switch *ds) diff --git a/net/dsa/dsa2.c b/net/dsa/dsa2.c index 71d8b8e3f0e4fa..a409496c555960 100644 --- a/net/dsa/dsa2.c +++ b/net/dsa/dsa2.c @@ -472,7 +472,13 @@ static int dsa_port_setup(struct dsa_port *dp) break; dsa_port_enabled = true; - break; + of_get_mac_address(dp->dn, dp->mac); + err = dsa_slave_create(dp); + if (err) + break; + + devlink_port_type_eth_set(dlp, dp->slave); + break; case DSA_PORT_TYPE_DSA: err = dsa_port_link_register_of(dp); if (err) @@ -577,9 +583,18 @@ static void dsa_port_teardown(struct dsa_port *dp) dsa_port_link_unregister_of(dp); break; case DSA_PORT_TYPE_IMP: - dsa_port_disable(dp); - dsa_port_link_unregister_of(dp); + if (dp->slave) { + dsa_slave_destroy(dp->slave); + dp->slave = NULL; + } break; + // dsa_port_disable(dp); + // dsa_port_link_unregister_of(dp); + // if (dp->slave) { + // dsa_slave_destroy(dp->slave); + // dp->slave = NULL; + // } + // break; case DSA_PORT_TYPE_DSA: dsa_port_disable(dp); dsa_port_link_unregister_of(dp); diff --git a/net/dsa/dsa_priv.h b/net/dsa/dsa_priv.h index e91265434354e5..f5fa17d5976b96 100644 --- a/net/dsa/dsa_priv.h +++ b/net/dsa/dsa_priv.h @@ -191,7 +191,7 @@ static inline struct net_device *dsa_master_find_slave(struct net_device *dev, list_for_each_entry(dp, &dst->ports, list) if (dp->ds->index == device && dp->index == port && - dp->type == DSA_PORT_TYPE_USER) + (dp->type == DSA_PORT_TYPE_USER || dp->type == DSA_PORT_TYPE_IMP)) return dp->slave; return NULL; diff --git a/net/dsa/slave.c b/net/dsa/slave.c index 11ec9e689589b0..1a6c3044bad5e5 100644 --- a/net/dsa/slave.c +++ b/net/dsa/slave.c @@ -1546,7 +1546,7 @@ static void dsa_bridge_mtu_normalization(struct dsa_port *dp) struct dsa_hw_port *hw_port; struct net_device *slave; - if (other_dp->type != DSA_PORT_TYPE_USER) + if ((other_dp->type != DSA_PORT_TYPE_USER) && (other_dp->type != DSA_PORT_TYPE_IMP)) continue; if (other_dp->bridge_dev != dp->bridge_dev) From 060a108fa8ca20fd82d1d02f368775f868a3c515 Mon Sep 17 00:00:00 2001 From: Mark Carlin Date: Fri, 1 Mar 2024 19:24:10 -0700 Subject: [PATCH 14/27] Allow jumbo frame configuration on a per-port basis. Initialise PVLAN vectors for each port to include self on driver init. --- Makefile | 2 +- drivers/net/dsa/b53/b53_common.c | 34 +++++++------- drivers/net/dsa/b53/b53_regs.h | 1 + net/dsa/slave.c | 76 ++------------------------------ 4 files changed, 22 insertions(+), 91 deletions(-) diff --git a/Makefile b/Makefile index 1f47a71551c909..645f9aa26496ca 100644 --- a/Makefile +++ b/Makefile @@ -2,7 +2,7 @@ VERSION = 5 PATCHLEVEL = 15 SUBLEVEL = 107 -EXTRAVERSION = -datum.7 +EXTRAVERSION = -datum.8 NAME = Trick or Treat # *DOCUMENTATION* diff --git a/drivers/net/dsa/b53/b53_common.c b/drivers/net/dsa/b53/b53_common.c index e485bcea9208d5..f2a23811c6b68c 100644 --- a/drivers/net/dsa/b53/b53_common.c +++ b/drivers/net/dsa/b53/b53_common.c @@ -126,20 +126,18 @@ static void b53_set_forwarding(struct b53_device *dev, int enable) b53_write8(dev, B53_CTRL_PAGE, B53_IP_MULTICAST_CTRL, mgmt); } -static int b53_set_jumbo(struct b53_device *dev, bool enable, bool allow_10_100) +static int b53_set_jumbo(struct b53_device *dev, int port, bool enable, bool allow_10_100) { - u32 port_mask = 0; - u16 max_size = JMS_MIN_SIZE; - - if (enable) { - port_mask = dev->enabled_ports; - max_size = JMS_MAX_SIZE; - if (allow_10_100) - port_mask |= JPM_10_100_JUMBO_EN; - } - - b53_write32(dev, B53_JUMBO_PAGE, dev->jumbo_pm_reg, port_mask); - return b53_write16(dev, B53_JUMBO_PAGE, dev->jumbo_size_reg, max_size); + u32 port_mask; + b53_read32(dev, B53_JUMBO_PAGE, dev->jumbo_pm_reg, &port_mask); + port_mask &= ~JPM_RESERVED_BITS; + if (enable) + port_mask |= BIT(port); + else + port_mask &= ~BIT(port); + if (allow_10_100) + port_mask |= JPM_10_100_JUMBO_EN; + return b53_write32(dev, B53_JUMBO_PAGE, dev->jumbo_pm_reg, port_mask); } static int b53_flush_arl(struct b53_device *dev, u8 mask) @@ -734,10 +732,11 @@ static int b53_setup(struct dsa_switch *ds) b53_disable_port(ds, port); } /* Disable all port based VLANs on powerup. Userspace configuration - * will enable them as needed. + * will enable them as needed. Note, PVLAN bit mask for each port + * must be set to include itself per data sheet. */ for (port = 0; port < dev->num_ports; port++) - b53_write16(dev, B53_PVLAN_PAGE, B53_PVLAN_PORT_MASK(port), 0x00); + b53_write16(dev, B53_PVLAN_PAGE, B53_PVLAN_PORT_MASK(port), BIT(port)); return b53_setup_devlink_resources(ds); } @@ -1549,11 +1548,10 @@ static int b53_change_mtu(struct dsa_switch *ds, int port, int mtu) struct b53_device *dev = ds->priv; bool enable_jumbo; bool allow_10_100; - enable_jumbo = (mtu >= JMS_MIN_SIZE); - allow_10_100 = (dev->chip_id == BCM583XX_DEVICE_ID); + allow_10_100 = true; - return b53_set_jumbo(dev, enable_jumbo, allow_10_100); + return b53_set_jumbo(dev, port, enable_jumbo, allow_10_100); } static int b53_get_max_mtu(struct dsa_switch *ds, int port) diff --git a/drivers/net/dsa/b53/b53_regs.h b/drivers/net/dsa/b53/b53_regs.h index 5ffc54cd0eb289..3d7930684aa3a2 100644 --- a/drivers/net/dsa/b53/b53_regs.h +++ b/drivers/net/dsa/b53/b53_regs.h @@ -509,6 +509,7 @@ #define B53_JUMBO_PORT_MASK 0x01 #define B53_JUMBO_PORT_MASK_63XX 0x04 #define JPM_10_100_JUMBO_EN BIT(24) /* GigE always enabled */ +#define JPM_RESERVED_BITS 0xfefffe00 /* Good Frame Max Size without 802.1Q TAG (16 bit) */ #define B53_JUMBO_MAX_SIZE 0x05 diff --git a/net/dsa/slave.c b/net/dsa/slave.c index 1a6c3044bad5e5..080a9121f6a2bf 100644 --- a/net/dsa/slave.c +++ b/net/dsa/slave.c @@ -1589,98 +1589,30 @@ static void dsa_bridge_mtu_normalization(struct dsa_port *dp) dsa_hw_port_list_free(&hw_port_list); } +/* Datum - rewrite to unlink slave (switch ports) from master (eth0) */ int dsa_slave_change_mtu(struct net_device *dev, int new_mtu) { - struct net_device *master = dsa_slave_to_master(dev); struct dsa_port *dp = dsa_slave_to_port(dev); struct dsa_slave_priv *p = netdev_priv(dev); struct dsa_switch *ds = p->dp->ds; - struct dsa_port *dp_iter; - struct dsa_port *cpu_dp; - int port = p->dp->index; - int largest_mtu = 0; - int new_master_mtu; - int old_master_mtu; int mtu_limit; - int cpu_mtu; int err; if (!ds->ops->port_change_mtu) return -EOPNOTSUPP; - list_for_each_entry(dp_iter, &ds->dst->ports, list) { - int slave_mtu; - - if (!dsa_port_is_user(dp_iter)) - continue; - - /* During probe, this function will be called for each slave - * device, while not all of them have been allocated. That's - * ok, it doesn't change what the maximum is, so ignore it. - */ - if (!dp_iter->slave) - continue; - - /* Pretend that we already applied the setting, which we - * actually haven't (still haven't done all integrity checks) - */ - if (dp_iter == dp) - slave_mtu = new_mtu; - else - slave_mtu = dp_iter->slave->mtu; - - if (largest_mtu < slave_mtu) - largest_mtu = slave_mtu; - } - - cpu_dp = dsa_to_port(ds, port)->cpu_dp; + mtu_limit = dev->max_mtu; - mtu_limit = min_t(int, master->max_mtu, dev->max_mtu); - old_master_mtu = master->mtu; - new_master_mtu = largest_mtu + dsa_tag_protocol_overhead(cpu_dp->tag_ops); - if (new_master_mtu > mtu_limit) + if(new_mtu > mtu_limit) return -ERANGE; - /* If the master MTU isn't over limit, there's no need to check the CPU - * MTU, since that surely isn't either. - */ - cpu_mtu = largest_mtu; - - /* Start applying stuff */ - if (new_master_mtu != old_master_mtu) { - err = dev_set_mtu(master, new_master_mtu); - if (err < 0) - goto out_master_failed; - - /* We only need to propagate the MTU of the CPU port to - * upstream switches, so create a non-targeted notifier which - * updates all switches. - */ - err = dsa_port_mtu_change(cpu_dp, cpu_mtu, false); - if (err) - goto out_cpu_failed; - } - err = dsa_port_mtu_change(dp, new_mtu, true); if (err) - goto out_port_failed; + return err; dev->mtu = new_mtu; - dsa_bridge_mtu_normalization(dp); - return 0; - -out_port_failed: - if (new_master_mtu != old_master_mtu) - dsa_port_mtu_change(cpu_dp, old_master_mtu - - dsa_tag_protocol_overhead(cpu_dp->tag_ops), - false); -out_cpu_failed: - if (new_master_mtu != old_master_mtu) - dev_set_mtu(master, old_master_mtu); -out_master_failed: - return err; } static const struct ethtool_ops dsa_slave_ethtool_ops = { From 7b3affd6563521fc360072037d2b86f4e308175c Mon Sep 17 00:00:00 2001 From: mcarlin Date: Mon, 25 Mar 2024 10:28:24 -0700 Subject: [PATCH 15/27] Change mpc9902 driver timeout to update on i2c bus when 30 ms stale, not 2 seconds. Add mutex between i2c devices and spi Broadcom switch to use a mutex to lock access to the schematic error that links the clock pins on i2c3 and spi2. --- Makefile | 2 +- drivers/hwmon/ina2xx.c | 35 +++++++++++++++++++++-- drivers/hwmon/mcp9902.c | 7 ++++- drivers/net/dsa/b53/b53_spi.c | 53 ++++++++++++++++++++++++++++++----- 4 files changed, 86 insertions(+), 11 deletions(-) diff --git a/Makefile b/Makefile index 645f9aa26496ca..39d42b8139b336 100644 --- a/Makefile +++ b/Makefile @@ -2,7 +2,7 @@ VERSION = 5 PATCHLEVEL = 15 SUBLEVEL = 107 -EXTRAVERSION = -datum.8 +EXTRAVERSION = -datum.9 NAME = Trick or Treat # *DOCUMENTATION* diff --git a/drivers/hwmon/ina2xx.c b/drivers/hwmon/ina2xx.c index 65ec0331de9d72..52eb1f3f2396fc 100644 --- a/drivers/hwmon/ina2xx.c +++ b/drivers/hwmon/ina2xx.c @@ -94,6 +94,8 @@ */ #define INA226_TOTAL_CONV_TIME_DEFAULT 2200 +extern struct mutex datum_b53_spi_mutex; + static struct regmap_config ina2xx_regmap_config = { .reg_bits = 8, .val_bits = 16, @@ -187,8 +189,14 @@ static u16 ina226_interval_to_reg(int interval) */ static int ina2xx_calibrate(struct ina2xx_data *data) { - return regmap_write(data->regmap, INA2XX_CALIBRATION, + int retval; + + mutex_lock(&datum_b53_spi_mutex); + retval = regmap_write(data->regmap, INA2XX_CALIBRATION, data->config->calibration_value); + mutex_unlock(&datum_b53_spi_mutex); + + return retval; } /* @@ -196,8 +204,13 @@ static int ina2xx_calibrate(struct ina2xx_data *data) */ static int ina2xx_init(struct ina2xx_data *data) { - int ret = regmap_write(data->regmap, INA2XX_CONFIG, + int ret; + + mutex_lock(&datum_b53_spi_mutex); + ret = regmap_write(data->regmap, INA2XX_CONFIG, data->config->config_default); + mutex_unlock(&datum_b53_spi_mutex); + if (ret < 0) return ret; @@ -213,7 +226,10 @@ static int ina2xx_read_reg(struct device *dev, int reg, unsigned int *regval) for (retry = 5; retry; retry--) { + mutex_lock(&datum_b53_spi_mutex); ret = regmap_read(data->regmap, reg, regval); + mutex_unlock(&datum_b53_spi_mutex); + if (ret < 0) return ret; @@ -230,8 +246,11 @@ static int ina2xx_read_reg(struct device *dev, int reg, unsigned int *regval) if (*regval == 0) { unsigned int cal; + mutex_lock(&datum_b53_spi_mutex); ret = regmap_read(data->regmap, INA2XX_CALIBRATION, &cal); + mutex_unlock(&datum_b53_spi_mutex); + if (ret < 0) return ret; @@ -375,6 +394,7 @@ static ssize_t ina226_alert_show(struct device *dev, int ret; mutex_lock(&data->config_lock); + mutex_lock(&datum_b53_spi_mutex); ret = regmap_read(data->regmap, INA226_MASK_ENABLE, ®val); if (ret) goto abort; @@ -388,6 +408,7 @@ static ssize_t ina226_alert_show(struct device *dev, ret = sysfs_emit(buf, "%d\n", val); abort: + mutex_unlock(&datum_b53_spi_mutex); mutex_unlock(&data->config_lock); return ret; } @@ -411,13 +432,16 @@ static ssize_t ina226_alert_store(struct device *dev, * if the value is non-zero. */ mutex_lock(&data->config_lock); + mutex_lock(&datum_b53_spi_mutex); ret = regmap_update_bits(data->regmap, INA226_MASK_ENABLE, INA226_ALERT_CONFIG_MASK, 0); if (ret < 0) goto abort; + ret = regmap_write(data->regmap, INA226_ALERT_LIMIT, ina226_alert_to_reg(data, attr->index, val)); + if (ret < 0) goto abort; @@ -431,6 +455,7 @@ static ssize_t ina226_alert_store(struct device *dev, ret = count; abort: + mutex_unlock(&datum_b53_spi_mutex); mutex_unlock(&data->config_lock); return ret; } @@ -444,7 +469,9 @@ static ssize_t ina226_alarm_show(struct device *dev, int alarm = 0; int ret; + mutex_lock(&datum_b53_spi_mutex); ret = regmap_read(data->regmap, INA226_MASK_ENABLE, ®val); + mutex_unlock(&datum_b53_spi_mutex); if (ret) return ret; @@ -517,9 +544,11 @@ static ssize_t ina226_interval_store(struct device *dev, if (val > INT_MAX || val == 0) return -EINVAL; + mutex_lock(&datum_b53_spi_mutex); status = regmap_update_bits(data->regmap, INA2XX_CONFIG, INA226_AVG_RD_MASK, ina226_interval_to_reg(val)); + mutex_unlock(&datum_b53_spi_mutex); if (status < 0) return status; @@ -533,7 +562,9 @@ static ssize_t ina226_interval_show(struct device *dev, int status; unsigned int regval; + mutex_lock(&datum_b53_spi_mutex); status = regmap_read(data->regmap, INA2XX_CONFIG, ®val); + mutex_unlock(&datum_b53_spi_mutex); if (status) return status; diff --git a/drivers/hwmon/mcp9902.c b/drivers/hwmon/mcp9902.c index e1270f4a29386d..8bdf469a8346f7 100644 --- a/drivers/hwmon/mcp9902.c +++ b/drivers/hwmon/mcp9902.c @@ -55,6 +55,8 @@ static const unsigned short normal_i2c[] = { #define MCP9902_REG_R_TCRIT_HYST 0x21 #define MCP9902_REG_W_TCRIT_HYST 0x21 +extern struct mutex datum_b53_spi_mutex; + /* * Conversions */ @@ -131,8 +133,10 @@ static struct mcp9902_data *mcp9902_update_device(struct device *dev) int i; mutex_lock(&data->update_lock); + mutex_lock(&datum_b53_spi_mutex); if (time_after(jiffies, data->last_updated + HZ * 2) || !data->valid) { + // if (time_after(jiffies, data->last_updated + 5) || !data->valid) { dev_dbg(&client->dev, "Updating mcp9902 data.\n"); for (i = 0; i < t_num_regs; i++) data->temp[i] = i2c_smbus_read_byte_data(client, @@ -144,6 +148,7 @@ static struct mcp9902_data *mcp9902_update_device(struct device *dev) data->valid = 1; } + mutex_unlock(&datum_b53_spi_mutex); mutex_unlock(&data->update_lock); return data; @@ -159,7 +164,7 @@ static ssize_t temp_show(struct device *dev, struct device_attribute *devattr, struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); struct mcp9902_data *data = mcp9902_update_device(dev); u8 fraction_reg; - + switch(attr->index) { case t_input1: diff --git a/drivers/net/dsa/b53/b53_spi.c b/drivers/net/dsa/b53/b53_spi.c index abfeea5d47e966..5cf3e07fa01c9d 100644 --- a/drivers/net/dsa/b53/b53_spi.c +++ b/drivers/net/dsa/b53/b53_spi.c @@ -23,6 +23,7 @@ #include #include #include +#include #include #include @@ -41,15 +42,23 @@ #define B53_SPI_PAGE_SELECT 0xff +DEFINE_MUTEX(datum_b53_spi_mutex); +EXPORT_SYMBOL(datum_b53_spi_mutex); + static inline int b53_spi_read_reg(struct spi_device *spi, u8 reg, u8 *val, unsigned int len) { u8 txbuf[2]; + int retval; txbuf[0] = B53_SPI_CMD_NORMAL | B53_SPI_CMD_READ; txbuf[1] = reg; - return spi_write_then_read(spi, txbuf, 2, val, len); + mutex_lock(&datum_b53_spi_mutex); + retval = spi_write_then_read(spi, txbuf, 2, val, len); + mutex_unlock(&datum_b53_spi_mutex); + + return retval; } static inline int b53_spi_clear_status(struct spi_device *spi) @@ -78,12 +87,17 @@ static inline int b53_spi_clear_status(struct spi_device *spi) static inline int b53_spi_set_page(struct spi_device *spi, u8 page) { u8 txbuf[3]; + int retval; txbuf[0] = B53_SPI_CMD_NORMAL | B53_SPI_CMD_WRITE; txbuf[1] = B53_SPI_PAGE_SELECT; txbuf[2] = page; - return spi_write(spi, txbuf, sizeof(txbuf)); + mutex_lock(&datum_b53_spi_mutex); + retval = spi_write(spi, txbuf, sizeof(txbuf)); + mutex_unlock(&datum_b53_spi_mutex); + + return retval; } static inline int b53_prepare_reg_access(struct spi_device *spi, u8 page) @@ -202,6 +216,7 @@ static int b53_spi_write8(struct b53_device *dev, u8 page, u8 reg, u8 value) struct spi_device *spi = dev->priv; int ret; u8 txbuf[3]; + int retval; ret = b53_prepare_reg_access(spi, page); if (ret) @@ -211,7 +226,11 @@ static int b53_spi_write8(struct b53_device *dev, u8 page, u8 reg, u8 value) txbuf[1] = reg; txbuf[2] = value; - return spi_write(spi, txbuf, sizeof(txbuf)); + mutex_lock(&datum_b53_spi_mutex); + retval = spi_write(spi, txbuf, sizeof(txbuf)); + mutex_unlock(&datum_b53_spi_mutex); + + return retval; } static int b53_spi_write16(struct b53_device *dev, u8 page, u8 reg, u16 value) @@ -219,6 +238,7 @@ static int b53_spi_write16(struct b53_device *dev, u8 page, u8 reg, u16 value) struct spi_device *spi = dev->priv; int ret; u8 txbuf[4]; + int retval; ret = b53_prepare_reg_access(spi, page); if (ret) @@ -228,7 +248,11 @@ static int b53_spi_write16(struct b53_device *dev, u8 page, u8 reg, u16 value) txbuf[1] = reg; put_unaligned_le16(value, &txbuf[2]); - return spi_write(spi, txbuf, sizeof(txbuf)); + mutex_lock(&datum_b53_spi_mutex); + retval = spi_write(spi, txbuf, sizeof(txbuf)); + mutex_unlock(&datum_b53_spi_mutex); + + return retval; } static int b53_spi_write32(struct b53_device *dev, u8 page, u8 reg, u32 value) @@ -236,6 +260,7 @@ static int b53_spi_write32(struct b53_device *dev, u8 page, u8 reg, u32 value) struct spi_device *spi = dev->priv; int ret; u8 txbuf[6]; + int retval; ret = b53_prepare_reg_access(spi, page); if (ret) @@ -245,7 +270,11 @@ static int b53_spi_write32(struct b53_device *dev, u8 page, u8 reg, u32 value) txbuf[1] = reg; put_unaligned_le32(value, &txbuf[2]); - return spi_write(spi, txbuf, sizeof(txbuf)); + mutex_lock(&datum_b53_spi_mutex); + retval = spi_write(spi, txbuf, sizeof(txbuf)); + mutex_unlock(&datum_b53_spi_mutex); + + return retval; } static int b53_spi_write48(struct b53_device *dev, u8 page, u8 reg, u64 value) @@ -253,6 +282,7 @@ static int b53_spi_write48(struct b53_device *dev, u8 page, u8 reg, u64 value) struct spi_device *spi = dev->priv; int ret; u8 txbuf[10]; + int retval; ret = b53_prepare_reg_access(spi, page); if (ret) @@ -262,7 +292,11 @@ static int b53_spi_write48(struct b53_device *dev, u8 page, u8 reg, u64 value) txbuf[1] = reg; put_unaligned_le64(value, &txbuf[2]); - return spi_write(spi, txbuf, sizeof(txbuf) - 2); + mutex_lock(&datum_b53_spi_mutex); + retval = spi_write(spi, txbuf, sizeof(txbuf) - 2); + mutex_unlock(&datum_b53_spi_mutex); + + return retval; } static int b53_spi_write64(struct b53_device *dev, u8 page, u8 reg, u64 value) @@ -270,6 +304,7 @@ static int b53_spi_write64(struct b53_device *dev, u8 page, u8 reg, u64 value) struct spi_device *spi = dev->priv; int ret; u8 txbuf[10]; + int retval; ret = b53_prepare_reg_access(spi, page); if (ret) @@ -279,7 +314,11 @@ static int b53_spi_write64(struct b53_device *dev, u8 page, u8 reg, u64 value) txbuf[1] = reg; put_unaligned_le64(value, &txbuf[2]); - return spi_write(spi, txbuf, sizeof(txbuf)); + mutex_lock(&datum_b53_spi_mutex); + retval = spi_write(spi, txbuf, sizeof(txbuf)); + mutex_unlock(&datum_b53_spi_mutex); + + return retval; } static const struct b53_io_ops b53_spi_ops = { From 90c3e26f3017a10c5291c8fe17b17e96ec364b71 Mon Sep 17 00:00:00 2001 From: Mark Carlin Date: Mon, 25 Mar 2024 14:33:19 -0700 Subject: [PATCH 16/27] Remove modified timeout for testing i2c3/spi2 clock pin contention issue. --- drivers/hwmon/mcp9902.c | 1 - 1 file changed, 1 deletion(-) diff --git a/drivers/hwmon/mcp9902.c b/drivers/hwmon/mcp9902.c index 8bdf469a8346f7..f5a7a849a0376c 100644 --- a/drivers/hwmon/mcp9902.c +++ b/drivers/hwmon/mcp9902.c @@ -136,7 +136,6 @@ static struct mcp9902_data *mcp9902_update_device(struct device *dev) mutex_lock(&datum_b53_spi_mutex); if (time_after(jiffies, data->last_updated + HZ * 2) || !data->valid) { - // if (time_after(jiffies, data->last_updated + 5) || !data->valid) { dev_dbg(&client->dev, "Updating mcp9902 data.\n"); for (i = 0; i < t_num_regs; i++) data->temp[i] = i2c_smbus_read_byte_data(client, From eed87eb93b7b300a97e6e8b0eb5cc428ea6ad972 Mon Sep 17 00:00:00 2001 From: Mark Carlin Date: Fri, 12 Apr 2024 19:00:56 -0700 Subject: [PATCH 17/27] Change phy polling interval and temp sensor memory time to increash spi/i2c actrivity in an attempt to get the spi crash to occur more often. --- Makefile | 2 +- drivers/hwmon/mcp9902.c | 19 +++++++++++++------ drivers/net/phy/phy.c | 10 ++++++++-- 3 files changed, 22 insertions(+), 9 deletions(-) diff --git a/Makefile b/Makefile index 39d42b8139b336..ed314d52739395 100644 --- a/Makefile +++ b/Makefile @@ -2,7 +2,7 @@ VERSION = 5 PATCHLEVEL = 15 SUBLEVEL = 107 -EXTRAVERSION = -datum.9 +EXTRAVERSION = -datum.10-eng.0 NAME = Trick or Treat # *DOCUMENTATION* diff --git a/drivers/hwmon/mcp9902.c b/drivers/hwmon/mcp9902.c index f5a7a849a0376c..969f74703c3fa7 100644 --- a/drivers/hwmon/mcp9902.c +++ b/drivers/hwmon/mcp9902.c @@ -131,17 +131,24 @@ static struct mcp9902_data *mcp9902_update_device(struct device *dev) struct mcp9902_data *data = dev_get_drvdata(dev); struct i2c_client *client = data->client; int i; + int j; mutex_lock(&data->update_lock); mutex_lock(&datum_b53_spi_mutex); - if (time_after(jiffies, data->last_updated + HZ * 2) || !data->valid) { + // if (time_after(jiffies, data->last_updated + HZ * 2) || !data->valid) { + if (time_after(jiffies, data->last_updated + 1) || !data->valid) { dev_dbg(&client->dev, "Updating mcp9902 data.\n"); - for (i = 0; i < t_num_regs; i++) - data->temp[i] = i2c_smbus_read_byte_data(client, - regs_read[i]); - data->alarms = i2c_smbus_read_byte_data(client, - MCP9902_REG_R_STATUS); + // printk("Updating mcp9902 data.\n"); + + for (j = 0; j < 100; j++) + { + for (i = 0; i < t_num_regs; i++) + data->temp[i] = i2c_smbus_read_byte_data(client, + regs_read[i]); + data->alarms = i2c_smbus_read_byte_data(client, + MCP9902_REG_R_STATUS); + } data->last_updated = jiffies; data->valid = 1; diff --git a/drivers/net/phy/phy.c b/drivers/net/phy/phy.c index 1135e63a4a76e1..082053ee00c3d0 100644 --- a/drivers/net/phy/phy.c +++ b/drivers/net/phy/phy.c @@ -36,7 +36,8 @@ #include #include -#define PHY_STATE_TIME HZ +// #define PHY_STATE_TIME HZ +#define PHY_STATE_TIME 2 #define PHY_STATE_STR(_state) \ case PHY_##_state: \ @@ -953,7 +954,6 @@ void phy_stop_machine(struct phy_device *phydev) void phy_error(struct phy_device *phydev) { WARN_ON(1); - mutex_lock(&phydev->lock); phydev->state = PHY_HALTED; mutex_unlock(&phydev->lock); @@ -1209,7 +1209,10 @@ void phy_state_machine(struct work_struct *work) return; if (err < 0) + { + printk("dsi-phy_state_machine(): PHY_ERROR error=%d\n", err); phy_error(phydev); + } phy_process_state_change(phydev, old_state); @@ -1223,7 +1226,10 @@ void phy_state_machine(struct work_struct *work) */ mutex_lock(&phydev->lock); if (phy_polling_mode(phydev) && phy_is_started(phydev)) + { + // printk("phydev poll - port=%d\n", phydev->port); phy_queue_state_machine(phydev, PHY_STATE_TIME); + } mutex_unlock(&phydev->lock); } From a49bf762017e9bc5a83a61cb78390e71fbdc0664 Mon Sep 17 00:00:00 2001 From: mcarlin Date: Sun, 14 Apr 2024 20:11:24 -0700 Subject: [PATCH 18/27] Add more debugging to find spi error. Having a hard time reproducing the error. --- Makefile | 2 +- drivers/hwmon/mcp9902.c | 8 +++++--- drivers/net/dsa/b53/b53_spi.c | 6 ++++++ drivers/net/phy/phy.c | 2 +- 4 files changed, 13 insertions(+), 5 deletions(-) diff --git a/Makefile b/Makefile index ed314d52739395..705e80550be2d6 100644 --- a/Makefile +++ b/Makefile @@ -2,7 +2,7 @@ VERSION = 5 PATCHLEVEL = 15 SUBLEVEL = 107 -EXTRAVERSION = -datum.10-eng.0 +EXTRAVERSION = -datum.10-eng.1 NAME = Trick or Treat # *DOCUMENTATION* diff --git a/drivers/hwmon/mcp9902.c b/drivers/hwmon/mcp9902.c index 969f74703c3fa7..e9a0dd96a616bf 100644 --- a/drivers/hwmon/mcp9902.c +++ b/drivers/hwmon/mcp9902.c @@ -134,27 +134,29 @@ static struct mcp9902_data *mcp9902_update_device(struct device *dev) int j; mutex_lock(&data->update_lock); - mutex_lock(&datum_b53_spi_mutex); +// mutex_lock(&datum_b53_spi_mutex); // if (time_after(jiffies, data->last_updated + HZ * 2) || !data->valid) { if (time_after(jiffies, data->last_updated + 1) || !data->valid) { dev_dbg(&client->dev, "Updating mcp9902 data.\n"); // printk("Updating mcp9902 data.\n"); - for (j = 0; j < 100; j++) + for (j = 0; j < 25; j++) { + mutex_lock(&datum_b53_spi_mutex); for (i = 0; i < t_num_regs; i++) data->temp[i] = i2c_smbus_read_byte_data(client, regs_read[i]); data->alarms = i2c_smbus_read_byte_data(client, MCP9902_REG_R_STATUS); + mutex_unlock(&datum_b53_spi_mutex); } data->last_updated = jiffies; data->valid = 1; } - mutex_unlock(&datum_b53_spi_mutex); +// mutex_unlock(&datum_b53_spi_mutex); mutex_unlock(&data->update_lock); return data; diff --git a/drivers/net/dsa/b53/b53_spi.c b/drivers/net/dsa/b53/b53_spi.c index 5cf3e07fa01c9d..f64aca4ac1b1f6 100644 --- a/drivers/net/dsa/b53/b53_spi.c +++ b/drivers/net/dsa/b53/b53_spi.c @@ -79,7 +79,10 @@ static inline int b53_spi_clear_status(struct spi_device *spi) } if (i == 10) + { + printk("dsi-datum: b53_spi_clear_status failed, rxbuf=0x%x02\n", rxbuf); return -EIO; + } return 0; } @@ -132,7 +135,10 @@ static int b53_spi_prepare_reg_read(struct spi_device *spi, u8 reg) } if (retry_count == 10) + { + printk("dsi-datum: b53_spi_prepare_reg_read failed, rxbuf=0x%02x\n", rxbuf); return -EIO; + } return 0; } diff --git a/drivers/net/phy/phy.c b/drivers/net/phy/phy.c index 082053ee00c3d0..927c7f26ae4687 100644 --- a/drivers/net/phy/phy.c +++ b/drivers/net/phy/phy.c @@ -37,7 +37,7 @@ #include // #define PHY_STATE_TIME HZ -#define PHY_STATE_TIME 2 +#define PHY_STATE_TIME 1 #define PHY_STATE_STR(_state) \ case PHY_##_state: \ From aeebc899ac08a5f0c8bfbdbebe81a927e5a334d1 Mon Sep 17 00:00:00 2001 From: Mark Carlin Date: Tue, 16 Apr 2024 19:01:09 -0700 Subject: [PATCH 19/27] Checkpoint commit. less likely, but spi crash still happens. Put in code to insure the device using the bus is asleep before releasing mutex. --- Makefile | 2 +- drivers/hwmon/ina2xx.c | 22 ++++++++++++++++++++++ drivers/hwmon/mcp9902.c | 20 ++++++++++++++++++-- drivers/i2c/busses/i2c-stm32f7.c | 2 +- drivers/net/dsa/b53/b53_spi.c | 22 ++++++++++++++++++++++ drivers/spi/spi-stm32.c | 2 +- 6 files changed, 65 insertions(+), 5 deletions(-) diff --git a/Makefile b/Makefile index 705e80550be2d6..2a4029aa2b191a 100644 --- a/Makefile +++ b/Makefile @@ -2,7 +2,7 @@ VERSION = 5 PATCHLEVEL = 15 SUBLEVEL = 107 -EXTRAVERSION = -datum.10-eng.1 +EXTRAVERSION = -datum.10-eng.2 NAME = Trick or Treat # *DOCUMENTATION* diff --git a/drivers/hwmon/ina2xx.c b/drivers/hwmon/ina2xx.c index 52eb1f3f2396fc..3868f8598cafde 100644 --- a/drivers/hwmon/ina2xx.c +++ b/drivers/hwmon/ina2xx.c @@ -34,6 +34,7 @@ #include #include #include +#include #include #include @@ -189,11 +190,15 @@ static u16 ina226_interval_to_reg(int interval) */ static int ina2xx_calibrate(struct ina2xx_data *data) { + struct device *dev = regmap_get_device(data->regmap); int retval; mutex_lock(&datum_b53_spi_mutex); retval = regmap_write(data->regmap, INA2XX_CALIBRATION, data->config->calibration_value); + + if(pm_runtime_active(dev)) + usleep_range(100, 200); mutex_unlock(&datum_b53_spi_mutex); return retval; @@ -204,11 +209,14 @@ static int ina2xx_calibrate(struct ina2xx_data *data) */ static int ina2xx_init(struct ina2xx_data *data) { + struct device *dev = regmap_get_device(data->regmap); int ret; mutex_lock(&datum_b53_spi_mutex); ret = regmap_write(data->regmap, INA2XX_CONFIG, data->config->config_default); + if(pm_runtime_active(dev)) + usleep_range(100, 200); mutex_unlock(&datum_b53_spi_mutex); if (ret < 0) @@ -228,6 +236,8 @@ static int ina2xx_read_reg(struct device *dev, int reg, unsigned int *regval) mutex_lock(&datum_b53_spi_mutex); ret = regmap_read(data->regmap, reg, regval); + if(pm_runtime_active(dev)) + usleep_range(100, 200); mutex_unlock(&datum_b53_spi_mutex); if (ret < 0) @@ -249,6 +259,8 @@ static int ina2xx_read_reg(struct device *dev, int reg, unsigned int *regval) mutex_lock(&datum_b53_spi_mutex); ret = regmap_read(data->regmap, INA2XX_CALIBRATION, &cal); + if(pm_runtime_active(dev)) + usleep_range(100, 200); mutex_unlock(&datum_b53_spi_mutex); if (ret < 0) @@ -408,6 +420,8 @@ static ssize_t ina226_alert_show(struct device *dev, ret = sysfs_emit(buf, "%d\n", val); abort: + if(pm_runtime_active(dev)) + usleep_range(100, 200); mutex_unlock(&datum_b53_spi_mutex); mutex_unlock(&data->config_lock); return ret; @@ -455,6 +469,8 @@ static ssize_t ina226_alert_store(struct device *dev, ret = count; abort: + if(pm_runtime_active(dev)) + usleep_range(100, 200); mutex_unlock(&datum_b53_spi_mutex); mutex_unlock(&data->config_lock); return ret; @@ -471,6 +487,8 @@ static ssize_t ina226_alarm_show(struct device *dev, mutex_lock(&datum_b53_spi_mutex); ret = regmap_read(data->regmap, INA226_MASK_ENABLE, ®val); + if(pm_runtime_active(dev)) + usleep_range(100, 200); mutex_unlock(&datum_b53_spi_mutex); if (ret) return ret; @@ -548,6 +566,8 @@ static ssize_t ina226_interval_store(struct device *dev, status = regmap_update_bits(data->regmap, INA2XX_CONFIG, INA226_AVG_RD_MASK, ina226_interval_to_reg(val)); + if(pm_runtime_active(dev)) + usleep_range(100, 200); mutex_unlock(&datum_b53_spi_mutex); if (status < 0) return status; @@ -564,6 +584,8 @@ static ssize_t ina226_interval_show(struct device *dev, mutex_lock(&datum_b53_spi_mutex); status = regmap_read(data->regmap, INA2XX_CONFIG, ®val); + if(pm_runtime_active(dev)) + usleep_range(100, 200); mutex_unlock(&datum_b53_spi_mutex); if (status) return status; diff --git a/drivers/hwmon/mcp9902.c b/drivers/hwmon/mcp9902.c index e9a0dd96a616bf..e5c5bea3b82815 100644 --- a/drivers/hwmon/mcp9902.c +++ b/drivers/hwmon/mcp9902.c @@ -10,6 +10,7 @@ * http://ww1.microchip.com/downloads/en/DeviceDoc/20005382C.pdf */ +#include #include #include #include @@ -19,6 +20,7 @@ #include #include #include +#include #include static const unsigned short normal_i2c[] = { @@ -141,14 +143,16 @@ static struct mcp9902_data *mcp9902_update_device(struct device *dev) dev_dbg(&client->dev, "Updating mcp9902 data.\n"); // printk("Updating mcp9902 data.\n"); - for (j = 0; j < 25; j++) + for (j = 0; j < 20; j++) { - mutex_lock(&datum_b53_spi_mutex); + mutex_lock(&datum_b53_spi_mutex); for (i = 0; i < t_num_regs; i++) data->temp[i] = i2c_smbus_read_byte_data(client, regs_read[i]); data->alarms = i2c_smbus_read_byte_data(client, MCP9902_REG_R_STATUS); + if(pm_runtime_active(dev)) + usleep_range(100, 200); mutex_unlock(&datum_b53_spi_mutex); } @@ -202,8 +206,12 @@ static ssize_t temp_store(struct device *dev, mutex_lock(&data->update_lock); data->temp[attr->index] = temp_to_reg(val); + mutex_lock(&datum_b53_spi_mutex); i2c_smbus_write_byte_data(client, regs_write[attr->index], data->temp[attr->index]); + if(pm_runtime_active(dev)) + usleep_range(100, 200); + mutex_unlock(&datum_b53_spi_mutex); mutex_unlock(&data->update_lock); return count; } @@ -276,8 +284,12 @@ static int mcp9902_detect(struct i2c_client *client, return -ENODEV; /* identification */ + mutex_lock(&datum_b53_spi_mutex); man_id = i2c_smbus_read_byte_data(client, MCP9902_REG_R_MAN_ID); chip_id = i2c_smbus_read_byte_data(client, MCP9902_REG_R_CHIP_ID); + if(pm_runtime_active(&adapter->dev)) + usleep_range(100, 200); + mutex_unlock(&datum_b53_spi_mutex); if (man_id != 0x5D || chip_id != 0x04) { dev_info(&adapter->dev, "Unsupported chip (man_id=0x%02X, chip_id=0x%02X).\n", @@ -296,8 +308,12 @@ static void mcp9902_init_client(struct i2c_client *client) /* * Start the conversions. */ + mutex_lock(&datum_b53_spi_mutex); i2c_smbus_write_byte_data(client, MCP9902_REG_W_CONVRATE, 5); /* 2 Hz */ i2c_smbus_write_byte_data(client, MCP9902_REG_W_CONFIG, 0x9F); /* run - extended temp */ + if(pm_runtime_active(&client->adapter->dev)) + usleep_range(100, 200); + mutex_unlock(&datum_b53_spi_mutex); } static int mcp9902_probe(struct i2c_client *new_client, diff --git a/drivers/i2c/busses/i2c-stm32f7.c b/drivers/i2c/busses/i2c-stm32f7.c index 791baea3623bab..70bdd0c46a2227 100644 --- a/drivers/i2c/busses/i2c-stm32f7.c +++ b/drivers/i2c/busses/i2c-stm32f7.c @@ -179,7 +179,7 @@ enum { #define STM32F7_SCLH_MAX BIT(8) #define STM32F7_SCLL_MAX BIT(8) -#define STM32F7_AUTOSUSPEND_DELAY (HZ / 100) +#define STM32F7_AUTOSUSPEND_DELAY 0 /** * struct stm32f7_i2c_regs - i2c f7 registers backup diff --git a/drivers/net/dsa/b53/b53_spi.c b/drivers/net/dsa/b53/b53_spi.c index f64aca4ac1b1f6..affd6a32d35d13 100644 --- a/drivers/net/dsa/b53/b53_spi.c +++ b/drivers/net/dsa/b53/b53_spi.c @@ -24,6 +24,7 @@ #include #include #include +#include #include #include @@ -48,6 +49,7 @@ EXPORT_SYMBOL(datum_b53_spi_mutex); static inline int b53_spi_read_reg(struct spi_device *spi, u8 reg, u8 *val, unsigned int len) { + struct device *dev = &spi->dev; u8 txbuf[2]; int retval; @@ -56,6 +58,8 @@ static inline int b53_spi_read_reg(struct spi_device *spi, u8 reg, u8 *val, mutex_lock(&datum_b53_spi_mutex); retval = spi_write_then_read(spi, txbuf, 2, val, len); + if(pm_runtime_active(dev)) + usleep_range(100, 200); mutex_unlock(&datum_b53_spi_mutex); return retval; @@ -89,6 +93,7 @@ static inline int b53_spi_clear_status(struct spi_device *spi) static inline int b53_spi_set_page(struct spi_device *spi, u8 page) { + struct device *dev = &spi->dev; u8 txbuf[3]; int retval; @@ -98,6 +103,8 @@ static inline int b53_spi_set_page(struct spi_device *spi, u8 page) mutex_lock(&datum_b53_spi_mutex); retval = spi_write(spi, txbuf, sizeof(txbuf)); + if(pm_runtime_active(dev)) + usleep_range(100, 200); mutex_unlock(&datum_b53_spi_mutex); return retval; @@ -220,6 +227,7 @@ static int b53_spi_read64(struct b53_device *dev, u8 page, u8 reg, u64 *val) static int b53_spi_write8(struct b53_device *dev, u8 page, u8 reg, u8 value) { struct spi_device *spi = dev->priv; + struct device *device = &spi->dev; int ret; u8 txbuf[3]; int retval; @@ -234,6 +242,8 @@ static int b53_spi_write8(struct b53_device *dev, u8 page, u8 reg, u8 value) mutex_lock(&datum_b53_spi_mutex); retval = spi_write(spi, txbuf, sizeof(txbuf)); + if(pm_runtime_active(device)) + usleep_range(100, 200); mutex_unlock(&datum_b53_spi_mutex); return retval; @@ -242,6 +252,7 @@ static int b53_spi_write8(struct b53_device *dev, u8 page, u8 reg, u8 value) static int b53_spi_write16(struct b53_device *dev, u8 page, u8 reg, u16 value) { struct spi_device *spi = dev->priv; + struct device *device = &spi->dev; int ret; u8 txbuf[4]; int retval; @@ -256,6 +267,8 @@ static int b53_spi_write16(struct b53_device *dev, u8 page, u8 reg, u16 value) mutex_lock(&datum_b53_spi_mutex); retval = spi_write(spi, txbuf, sizeof(txbuf)); + if(pm_runtime_active(device)) + usleep_range(100, 200); mutex_unlock(&datum_b53_spi_mutex); return retval; @@ -264,6 +277,7 @@ static int b53_spi_write16(struct b53_device *dev, u8 page, u8 reg, u16 value) static int b53_spi_write32(struct b53_device *dev, u8 page, u8 reg, u32 value) { struct spi_device *spi = dev->priv; + struct device *device = &spi->dev; int ret; u8 txbuf[6]; int retval; @@ -278,6 +292,8 @@ static int b53_spi_write32(struct b53_device *dev, u8 page, u8 reg, u32 value) mutex_lock(&datum_b53_spi_mutex); retval = spi_write(spi, txbuf, sizeof(txbuf)); + if(pm_runtime_active(device)) + usleep_range(100, 200); mutex_unlock(&datum_b53_spi_mutex); return retval; @@ -286,6 +302,7 @@ static int b53_spi_write32(struct b53_device *dev, u8 page, u8 reg, u32 value) static int b53_spi_write48(struct b53_device *dev, u8 page, u8 reg, u64 value) { struct spi_device *spi = dev->priv; + struct device *device = &spi->dev; int ret; u8 txbuf[10]; int retval; @@ -300,6 +317,8 @@ static int b53_spi_write48(struct b53_device *dev, u8 page, u8 reg, u64 value) mutex_lock(&datum_b53_spi_mutex); retval = spi_write(spi, txbuf, sizeof(txbuf) - 2); + if(pm_runtime_active(device)) + usleep_range(100, 200); mutex_unlock(&datum_b53_spi_mutex); return retval; @@ -308,6 +327,7 @@ static int b53_spi_write48(struct b53_device *dev, u8 page, u8 reg, u64 value) static int b53_spi_write64(struct b53_device *dev, u8 page, u8 reg, u64 value) { struct spi_device *spi = dev->priv; + struct device *device = &spi->dev; int ret; u8 txbuf[10]; int retval; @@ -322,6 +342,8 @@ static int b53_spi_write64(struct b53_device *dev, u8 page, u8 reg, u64 value) mutex_lock(&datum_b53_spi_mutex); retval = spi_write(spi, txbuf, sizeof(txbuf)); + if(pm_runtime_active(device)) + usleep_range(100, 200); mutex_unlock(&datum_b53_spi_mutex); return retval; diff --git a/drivers/spi/spi-stm32.c b/drivers/spi/spi-stm32.c index e750dd73a9b6cd..3eb8f5bd892ca7 100644 --- a/drivers/spi/spi-stm32.c +++ b/drivers/spi/spi-stm32.c @@ -175,7 +175,7 @@ #define SPI_3WIRE_TX 3 #define SPI_3WIRE_RX 4 -#define STM32_SPI_AUTOSUSPEND_DELAY 1 /* 1 ms */ +#define STM32_SPI_AUTOSUSPEND_DELAY 0 /* 0 ms */ /* * use PIO for small transfers, avoiding DMA setup/teardown overhead for drivers From fc02f3d2146b369ded3c40b24cea8cd384d7df1b Mon Sep 17 00:00:00 2001 From: Mark Carlin Date: Thu, 18 Apr 2024 15:00:38 -0700 Subject: [PATCH 20/27] Fix the i2c bus device pm_runtime devices. Add debugging. Use pm_runtime_suspended() instead of pm_runtime_active to exclude states where device is becoming active or becoming suspended. --- drivers/hwmon/ina2xx.c | 8 ++++++++ drivers/hwmon/mcp9902.c | 12 +++++++----- drivers/i2c/busses/i2c-stm32f7.c | 1 + drivers/net/dsa/b53/b53_spi.c | 14 +++++++------- 4 files changed, 23 insertions(+), 12 deletions(-) diff --git a/drivers/hwmon/ina2xx.c b/drivers/hwmon/ina2xx.c index 3868f8598cafde..2366b319d8f550 100644 --- a/drivers/hwmon/ina2xx.c +++ b/drivers/hwmon/ina2xx.c @@ -197,6 +197,7 @@ static int ina2xx_calibrate(struct ina2xx_data *data) retval = regmap_write(data->regmap, INA2XX_CALIBRATION, data->config->calibration_value); + dev_err(dev, "ina2xx dev\n"); if(pm_runtime_active(dev)) usleep_range(100, 200); mutex_unlock(&datum_b53_spi_mutex); @@ -215,6 +216,7 @@ static int ina2xx_init(struct ina2xx_data *data) mutex_lock(&datum_b53_spi_mutex); ret = regmap_write(data->regmap, INA2XX_CONFIG, data->config->config_default); + dev_err(dev, "ina2xx dev\n"); if(pm_runtime_active(dev)) usleep_range(100, 200); mutex_unlock(&datum_b53_spi_mutex); @@ -236,6 +238,7 @@ static int ina2xx_read_reg(struct device *dev, int reg, unsigned int *regval) mutex_lock(&datum_b53_spi_mutex); ret = regmap_read(data->regmap, reg, regval); + dev_err(dev, "ina2xx dev\n"); if(pm_runtime_active(dev)) usleep_range(100, 200); mutex_unlock(&datum_b53_spi_mutex); @@ -259,6 +262,7 @@ static int ina2xx_read_reg(struct device *dev, int reg, unsigned int *regval) mutex_lock(&datum_b53_spi_mutex); ret = regmap_read(data->regmap, INA2XX_CALIBRATION, &cal); + dev_err(dev, "ina2xx dev\n"); if(pm_runtime_active(dev)) usleep_range(100, 200); mutex_unlock(&datum_b53_spi_mutex); @@ -420,6 +424,7 @@ static ssize_t ina226_alert_show(struct device *dev, ret = sysfs_emit(buf, "%d\n", val); abort: + dev_err(dev, "ina2xx dev\n"); if(pm_runtime_active(dev)) usleep_range(100, 200); mutex_unlock(&datum_b53_spi_mutex); @@ -469,6 +474,7 @@ static ssize_t ina226_alert_store(struct device *dev, ret = count; abort: + dev_err(dev, "ina2xx dev\n"); if(pm_runtime_active(dev)) usleep_range(100, 200); mutex_unlock(&datum_b53_spi_mutex); @@ -487,6 +493,7 @@ static ssize_t ina226_alarm_show(struct device *dev, mutex_lock(&datum_b53_spi_mutex); ret = regmap_read(data->regmap, INA226_MASK_ENABLE, ®val); + dev_err(dev, "ina2xx dev\n"); if(pm_runtime_active(dev)) usleep_range(100, 200); mutex_unlock(&datum_b53_spi_mutex); @@ -584,6 +591,7 @@ static ssize_t ina226_interval_show(struct device *dev, mutex_lock(&datum_b53_spi_mutex); status = regmap_read(data->regmap, INA2XX_CONFIG, ®val); + dev_err(dev, "ina2xx dev\n"); if(pm_runtime_active(dev)) usleep_range(100, 200); mutex_unlock(&datum_b53_spi_mutex); diff --git a/drivers/hwmon/mcp9902.c b/drivers/hwmon/mcp9902.c index e5c5bea3b82815..550694d6357384 100644 --- a/drivers/hwmon/mcp9902.c +++ b/drivers/hwmon/mcp9902.c @@ -132,6 +132,7 @@ static struct mcp9902_data *mcp9902_update_device(struct device *dev) { struct mcp9902_data *data = dev_get_drvdata(dev); struct i2c_client *client = data->client; + struct i2c_adapter *adapter = client->adapter; int i; int j; @@ -151,7 +152,7 @@ static struct mcp9902_data *mcp9902_update_device(struct device *dev) regs_read[i]); data->alarms = i2c_smbus_read_byte_data(client, MCP9902_REG_R_STATUS); - if(pm_runtime_active(dev)) + if(!pm_runtime_suspended(adapter->dev.parent)) usleep_range(100, 200); mutex_unlock(&datum_b53_spi_mutex); } @@ -199,6 +200,7 @@ static ssize_t temp_store(struct device *dev, struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); struct mcp9902_data *data = dev_get_drvdata(dev); struct i2c_client *client = data->client; + struct i2c_adapter *adapter = client->adapter; long val; int err = kstrtol(buf, 10, &val); if (err) @@ -209,7 +211,7 @@ static ssize_t temp_store(struct device *dev, mutex_lock(&datum_b53_spi_mutex); i2c_smbus_write_byte_data(client, regs_write[attr->index], data->temp[attr->index]); - if(pm_runtime_active(dev)) + if(!pm_runtime_suspended(adapter->dev.parent)) usleep_range(100, 200); mutex_unlock(&datum_b53_spi_mutex); mutex_unlock(&data->update_lock); @@ -287,7 +289,7 @@ static int mcp9902_detect(struct i2c_client *client, mutex_lock(&datum_b53_spi_mutex); man_id = i2c_smbus_read_byte_data(client, MCP9902_REG_R_MAN_ID); chip_id = i2c_smbus_read_byte_data(client, MCP9902_REG_R_CHIP_ID); - if(pm_runtime_active(&adapter->dev)) + if(!pm_runtime_suspended(adapter->dev.parent)) usleep_range(100, 200); mutex_unlock(&datum_b53_spi_mutex); if (man_id != 0x5D || chip_id != 0x04) { @@ -304,14 +306,14 @@ static int mcp9902_detect(struct i2c_client *client, static void mcp9902_init_client(struct i2c_client *client) { - + struct i2c_adapter *adapter = client->adapter; /* * Start the conversions. */ mutex_lock(&datum_b53_spi_mutex); i2c_smbus_write_byte_data(client, MCP9902_REG_W_CONVRATE, 5); /* 2 Hz */ i2c_smbus_write_byte_data(client, MCP9902_REG_W_CONFIG, 0x9F); /* run - extended temp */ - if(pm_runtime_active(&client->adapter->dev)) + if(!pm_runtime_suspended(adapter->dev.parent)) usleep_range(100, 200); mutex_unlock(&datum_b53_spi_mutex); } diff --git a/drivers/i2c/busses/i2c-stm32f7.c b/drivers/i2c/busses/i2c-stm32f7.c index 70bdd0c46a2227..8adace8f25ff85 100644 --- a/drivers/i2c/busses/i2c-stm32f7.c +++ b/drivers/i2c/busses/i2c-stm32f7.c @@ -2228,6 +2228,7 @@ static int stm32f7_i2c_probe(struct platform_device *pdev) platform_set_drvdata(pdev, i2c_dev); + dev_err(i2c_dev->dev, "dsi-stm32f7_i2c_probe() dev\n"); pm_runtime_set_autosuspend_delay(i2c_dev->dev, STM32F7_AUTOSUSPEND_DELAY); pm_runtime_use_autosuspend(i2c_dev->dev); diff --git a/drivers/net/dsa/b53/b53_spi.c b/drivers/net/dsa/b53/b53_spi.c index affd6a32d35d13..61d776f78aec36 100644 --- a/drivers/net/dsa/b53/b53_spi.c +++ b/drivers/net/dsa/b53/b53_spi.c @@ -58,7 +58,7 @@ static inline int b53_spi_read_reg(struct spi_device *spi, u8 reg, u8 *val, mutex_lock(&datum_b53_spi_mutex); retval = spi_write_then_read(spi, txbuf, 2, val, len); - if(pm_runtime_active(dev)) + if(!pm_runtime_suspended(dev)) usleep_range(100, 200); mutex_unlock(&datum_b53_spi_mutex); @@ -103,7 +103,7 @@ static inline int b53_spi_set_page(struct spi_device *spi, u8 page) mutex_lock(&datum_b53_spi_mutex); retval = spi_write(spi, txbuf, sizeof(txbuf)); - if(pm_runtime_active(dev)) + if(!pm_runtime_suspended(dev)) usleep_range(100, 200); mutex_unlock(&datum_b53_spi_mutex); @@ -242,7 +242,7 @@ static int b53_spi_write8(struct b53_device *dev, u8 page, u8 reg, u8 value) mutex_lock(&datum_b53_spi_mutex); retval = spi_write(spi, txbuf, sizeof(txbuf)); - if(pm_runtime_active(device)) + if(!pm_runtime_suspended(device)) usleep_range(100, 200); mutex_unlock(&datum_b53_spi_mutex); @@ -267,7 +267,7 @@ static int b53_spi_write16(struct b53_device *dev, u8 page, u8 reg, u16 value) mutex_lock(&datum_b53_spi_mutex); retval = spi_write(spi, txbuf, sizeof(txbuf)); - if(pm_runtime_active(device)) + if(!pm_runtime_suspended(device)) usleep_range(100, 200); mutex_unlock(&datum_b53_spi_mutex); @@ -292,7 +292,7 @@ static int b53_spi_write32(struct b53_device *dev, u8 page, u8 reg, u32 value) mutex_lock(&datum_b53_spi_mutex); retval = spi_write(spi, txbuf, sizeof(txbuf)); - if(pm_runtime_active(device)) + if(!pm_runtime_suspended(device)) usleep_range(100, 200); mutex_unlock(&datum_b53_spi_mutex); @@ -317,7 +317,7 @@ static int b53_spi_write48(struct b53_device *dev, u8 page, u8 reg, u64 value) mutex_lock(&datum_b53_spi_mutex); retval = spi_write(spi, txbuf, sizeof(txbuf) - 2); - if(pm_runtime_active(device)) + if(!pm_runtime_suspended(device)) usleep_range(100, 200); mutex_unlock(&datum_b53_spi_mutex); @@ -342,7 +342,7 @@ static int b53_spi_write64(struct b53_device *dev, u8 page, u8 reg, u64 value) mutex_lock(&datum_b53_spi_mutex); retval = spi_write(spi, txbuf, sizeof(txbuf)); - if(pm_runtime_active(device)) + if(!pm_runtime_suspended(device)) usleep_range(100, 200); mutex_unlock(&datum_b53_spi_mutex); From 09fc103045e95f1fc29bea531dc4f4d330bc8ad2 Mon Sep 17 00:00:00 2001 From: Mark Carlin Date: Fri, 19 Apr 2024 15:34:52 -0700 Subject: [PATCH 21/27] Clean up mutex handling and use correct PM device for B53 driver. Still has the problem. --- drivers/hwmon/mcp9902.c | 44 +++++++++++--------- drivers/i2c/busses/i2c-stm32f7.c | 2 +- drivers/net/dsa/b53/b53_spi.c | 69 +++++++++++++++----------------- drivers/net/phy/phy.c | 2 +- drivers/spi/spi-stm32.c | 1 + 5 files changed, 62 insertions(+), 56 deletions(-) diff --git a/drivers/hwmon/mcp9902.c b/drivers/hwmon/mcp9902.c index 550694d6357384..e17dca04efbe97 100644 --- a/drivers/hwmon/mcp9902.c +++ b/drivers/hwmon/mcp9902.c @@ -57,8 +57,22 @@ static const unsigned short normal_i2c[] = { #define MCP9902_REG_R_TCRIT_HYST 0x21 #define MCP9902_REG_W_TCRIT_HYST 0x21 +/* + * I2C3-SPI2 Clocks Shorted Mutex + */ + extern struct mutex datum_b53_spi_mutex; +static inline void spi_lock(void) { mutex_lock(&datum_b53_spi_mutex); } + +static inline void spi_unlock(struct device *dev) +{ + if(!pm_runtime_suspended(dev)) + usleep_range(100, 200); + msleep(1); + mutex_unlock(&datum_b53_spi_mutex); +} + /* * Conversions */ @@ -137,7 +151,7 @@ static struct mcp9902_data *mcp9902_update_device(struct device *dev) int j; mutex_lock(&data->update_lock); -// mutex_lock(&datum_b53_spi_mutex); +// spi_lock(); // if (time_after(jiffies, data->last_updated + HZ * 2) || !data->valid) { if (time_after(jiffies, data->last_updated + 1) || !data->valid) { @@ -146,22 +160,20 @@ static struct mcp9902_data *mcp9902_update_device(struct device *dev) for (j = 0; j < 20; j++) { - mutex_lock(&datum_b53_spi_mutex); + spi_lock(); for (i = 0; i < t_num_regs; i++) data->temp[i] = i2c_smbus_read_byte_data(client, regs_read[i]); data->alarms = i2c_smbus_read_byte_data(client, MCP9902_REG_R_STATUS); - if(!pm_runtime_suspended(adapter->dev.parent)) - usleep_range(100, 200); - mutex_unlock(&datum_b53_spi_mutex); + spi_unlock(adapter->dev.parent); } data->last_updated = jiffies; data->valid = 1; } -// mutex_unlock(&datum_b53_spi_mutex); +// spi_unlock(adapter->dev.parent); mutex_unlock(&data->update_lock); return data; @@ -208,12 +220,10 @@ static ssize_t temp_store(struct device *dev, mutex_lock(&data->update_lock); data->temp[attr->index] = temp_to_reg(val); - mutex_lock(&datum_b53_spi_mutex); + spi_lock(); i2c_smbus_write_byte_data(client, regs_write[attr->index], data->temp[attr->index]); - if(!pm_runtime_suspended(adapter->dev.parent)) - usleep_range(100, 200); - mutex_unlock(&datum_b53_spi_mutex); + spi_unlock(adapter->dev.parent); mutex_unlock(&data->update_lock); return count; } @@ -286,12 +296,11 @@ static int mcp9902_detect(struct i2c_client *client, return -ENODEV; /* identification */ - mutex_lock(&datum_b53_spi_mutex); + spi_lock(); man_id = i2c_smbus_read_byte_data(client, MCP9902_REG_R_MAN_ID); chip_id = i2c_smbus_read_byte_data(client, MCP9902_REG_R_CHIP_ID); - if(!pm_runtime_suspended(adapter->dev.parent)) - usleep_range(100, 200); - mutex_unlock(&datum_b53_spi_mutex); + dev_err(adapter->dev.parent, "dsi-mcp9902_detect()\n"); + spi_unlock(adapter->dev.parent); if (man_id != 0x5D || chip_id != 0x04) { dev_info(&adapter->dev, "Unsupported chip (man_id=0x%02X, chip_id=0x%02X).\n", @@ -310,12 +319,11 @@ static void mcp9902_init_client(struct i2c_client *client) /* * Start the conversions. */ - mutex_lock(&datum_b53_spi_mutex); + spi_lock(); i2c_smbus_write_byte_data(client, MCP9902_REG_W_CONVRATE, 5); /* 2 Hz */ i2c_smbus_write_byte_data(client, MCP9902_REG_W_CONFIG, 0x9F); /* run - extended temp */ - if(!pm_runtime_suspended(adapter->dev.parent)) - usleep_range(100, 200); - mutex_unlock(&datum_b53_spi_mutex); + dev_err(adapter->dev.parent, "dsi-mcp9902_init_client()\n"); + spi_unlock(adapter->dev.parent); } static int mcp9902_probe(struct i2c_client *new_client, diff --git a/drivers/i2c/busses/i2c-stm32f7.c b/drivers/i2c/busses/i2c-stm32f7.c index 8adace8f25ff85..102afd2623ea6a 100644 --- a/drivers/i2c/busses/i2c-stm32f7.c +++ b/drivers/i2c/busses/i2c-stm32f7.c @@ -2228,7 +2228,7 @@ static int stm32f7_i2c_probe(struct platform_device *pdev) platform_set_drvdata(pdev, i2c_dev); - dev_err(i2c_dev->dev, "dsi-stm32f7_i2c_probe() dev\n"); + dev_err(i2c_dev->dev, "dsi-stm32f7_i2c_probe() [i2c_dev->dev]\n"); pm_runtime_set_autosuspend_delay(i2c_dev->dev, STM32F7_AUTOSUSPEND_DELAY); pm_runtime_use_autosuspend(i2c_dev->dev); diff --git a/drivers/net/dsa/b53/b53_spi.c b/drivers/net/dsa/b53/b53_spi.c index 61d776f78aec36..78b257937037bc 100644 --- a/drivers/net/dsa/b53/b53_spi.c +++ b/drivers/net/dsa/b53/b53_spi.c @@ -46,21 +46,29 @@ DEFINE_MUTEX(datum_b53_spi_mutex); EXPORT_SYMBOL(datum_b53_spi_mutex); +static inline void spi_lock(void) { mutex_lock(&datum_b53_spi_mutex); } + +static inline void spi_unlock(struct device *dev) +{ + if(!pm_runtime_suspended(dev)) + usleep_range(100, 200); + msleep(1); + mutex_unlock(&datum_b53_spi_mutex); +} + static inline int b53_spi_read_reg(struct spi_device *spi, u8 reg, u8 *val, unsigned int len) { - struct device *dev = &spi->dev; + struct device *dev = spi->dev.parent->parent; u8 txbuf[2]; int retval; txbuf[0] = B53_SPI_CMD_NORMAL | B53_SPI_CMD_READ; txbuf[1] = reg; - mutex_lock(&datum_b53_spi_mutex); + spi_lock(); retval = spi_write_then_read(spi, txbuf, 2, val, len); - if(!pm_runtime_suspended(dev)) - usleep_range(100, 200); - mutex_unlock(&datum_b53_spi_mutex); + spi_unlock(dev); return retval; } @@ -84,7 +92,7 @@ static inline int b53_spi_clear_status(struct spi_device *spi) if (i == 10) { - printk("dsi-datum: b53_spi_clear_status failed, rxbuf=0x%x02\n", rxbuf); + printk("dsi-datum: b53_spi_clear_status failed, rxbuf=0x%02x\n", rxbuf); return -EIO; } @@ -93,7 +101,7 @@ static inline int b53_spi_clear_status(struct spi_device *spi) static inline int b53_spi_set_page(struct spi_device *spi, u8 page) { - struct device *dev = &spi->dev; + struct device *dev = spi->dev.parent->parent; u8 txbuf[3]; int retval; @@ -101,11 +109,9 @@ static inline int b53_spi_set_page(struct spi_device *spi, u8 page) txbuf[1] = B53_SPI_PAGE_SELECT; txbuf[2] = page; - mutex_lock(&datum_b53_spi_mutex); + spi_lock(); retval = spi_write(spi, txbuf, sizeof(txbuf)); - if(!pm_runtime_suspended(dev)) - usleep_range(100, 200); - mutex_unlock(&datum_b53_spi_mutex); + spi_unlock(dev); return retval; } @@ -227,7 +233,7 @@ static int b53_spi_read64(struct b53_device *dev, u8 page, u8 reg, u64 *val) static int b53_spi_write8(struct b53_device *dev, u8 page, u8 reg, u8 value) { struct spi_device *spi = dev->priv; - struct device *device = &spi->dev; + struct device *device = spi->dev.parent->parent; int ret; u8 txbuf[3]; int retval; @@ -240,11 +246,10 @@ static int b53_spi_write8(struct b53_device *dev, u8 page, u8 reg, u8 value) txbuf[1] = reg; txbuf[2] = value; - mutex_lock(&datum_b53_spi_mutex); + spi_lock(); + dev_err(device, "dsi-b53_spi_write8(): %02x %02x %02x\n", txbuf[0], txbuf[1], txbuf[2]); retval = spi_write(spi, txbuf, sizeof(txbuf)); - if(!pm_runtime_suspended(device)) - usleep_range(100, 200); - mutex_unlock(&datum_b53_spi_mutex); + spi_unlock(device); return retval; } @@ -252,7 +257,7 @@ static int b53_spi_write8(struct b53_device *dev, u8 page, u8 reg, u8 value) static int b53_spi_write16(struct b53_device *dev, u8 page, u8 reg, u16 value) { struct spi_device *spi = dev->priv; - struct device *device = &spi->dev; + struct device *device = spi->dev.parent->parent; int ret; u8 txbuf[4]; int retval; @@ -265,11 +270,9 @@ static int b53_spi_write16(struct b53_device *dev, u8 page, u8 reg, u16 value) txbuf[1] = reg; put_unaligned_le16(value, &txbuf[2]); - mutex_lock(&datum_b53_spi_mutex); + spi_lock(); retval = spi_write(spi, txbuf, sizeof(txbuf)); - if(!pm_runtime_suspended(device)) - usleep_range(100, 200); - mutex_unlock(&datum_b53_spi_mutex); + spi_unlock(device); return retval; } @@ -277,7 +280,7 @@ static int b53_spi_write16(struct b53_device *dev, u8 page, u8 reg, u16 value) static int b53_spi_write32(struct b53_device *dev, u8 page, u8 reg, u32 value) { struct spi_device *spi = dev->priv; - struct device *device = &spi->dev; + struct device *device = spi->dev.parent->parent; int ret; u8 txbuf[6]; int retval; @@ -290,11 +293,9 @@ static int b53_spi_write32(struct b53_device *dev, u8 page, u8 reg, u32 value) txbuf[1] = reg; put_unaligned_le32(value, &txbuf[2]); - mutex_lock(&datum_b53_spi_mutex); + spi_lock(); retval = spi_write(spi, txbuf, sizeof(txbuf)); - if(!pm_runtime_suspended(device)) - usleep_range(100, 200); - mutex_unlock(&datum_b53_spi_mutex); + spi_unlock(device); return retval; } @@ -302,7 +303,7 @@ static int b53_spi_write32(struct b53_device *dev, u8 page, u8 reg, u32 value) static int b53_spi_write48(struct b53_device *dev, u8 page, u8 reg, u64 value) { struct spi_device *spi = dev->priv; - struct device *device = &spi->dev; + struct device *device = spi->dev.parent->parent; int ret; u8 txbuf[10]; int retval; @@ -315,11 +316,9 @@ static int b53_spi_write48(struct b53_device *dev, u8 page, u8 reg, u64 value) txbuf[1] = reg; put_unaligned_le64(value, &txbuf[2]); - mutex_lock(&datum_b53_spi_mutex); + spi_lock(); retval = spi_write(spi, txbuf, sizeof(txbuf) - 2); - if(!pm_runtime_suspended(device)) - usleep_range(100, 200); - mutex_unlock(&datum_b53_spi_mutex); + spi_unlock(device); return retval; } @@ -327,7 +326,7 @@ static int b53_spi_write48(struct b53_device *dev, u8 page, u8 reg, u64 value) static int b53_spi_write64(struct b53_device *dev, u8 page, u8 reg, u64 value) { struct spi_device *spi = dev->priv; - struct device *device = &spi->dev; + struct device *device = spi->dev.parent->parent; int ret; u8 txbuf[10]; int retval; @@ -340,11 +339,9 @@ static int b53_spi_write64(struct b53_device *dev, u8 page, u8 reg, u64 value) txbuf[1] = reg; put_unaligned_le64(value, &txbuf[2]); - mutex_lock(&datum_b53_spi_mutex); + spi_lock(); retval = spi_write(spi, txbuf, sizeof(txbuf)); - if(!pm_runtime_suspended(device)) - usleep_range(100, 200); - mutex_unlock(&datum_b53_spi_mutex); + spi_unlock(device); return retval; } diff --git a/drivers/net/phy/phy.c b/drivers/net/phy/phy.c index 927c7f26ae4687..082053ee00c3d0 100644 --- a/drivers/net/phy/phy.c +++ b/drivers/net/phy/phy.c @@ -37,7 +37,7 @@ #include // #define PHY_STATE_TIME HZ -#define PHY_STATE_TIME 1 +#define PHY_STATE_TIME 2 #define PHY_STATE_STR(_state) \ case PHY_##_state: \ diff --git a/drivers/spi/spi-stm32.c b/drivers/spi/spi-stm32.c index 3eb8f5bd892ca7..a80c9d7f9f9f9e 100644 --- a/drivers/spi/spi-stm32.c +++ b/drivers/spi/spi-stm32.c @@ -2041,6 +2041,7 @@ static int stm32_spi_probe(struct platform_device *pdev) if (spi->dma_tx || spi->dma_rx) ctrl->can_dma = stm32_spi_can_dma; + dev_err(&pdev->dev, "dsi-stm32_spi_probe() [&pdev->dev]\n"); pm_runtime_set_autosuspend_delay(&pdev->dev, STM32_SPI_AUTOSUSPEND_DELAY); pm_runtime_use_autosuspend(&pdev->dev); From 734aeea9a7296748c5fc87de9d1a8e9ef35c082e Mon Sep 17 00:00:00 2001 From: Mark Carlin Date: Sat, 20 Apr 2024 12:04:13 -0700 Subject: [PATCH 22/27] Change use of datum_b53_spi_mutex in the b53 switch driver to only lock and unlock the mutex during a complete read or write transaction. Each read/write transaction contains multiple SPI bus accesses. --- drivers/hwmon/mcp9902.c | 2 +- drivers/net/dsa/b53/b53_spi.c | 29 ++++++++++++++++++----------- 2 files changed, 19 insertions(+), 12 deletions(-) diff --git a/drivers/hwmon/mcp9902.c b/drivers/hwmon/mcp9902.c index e17dca04efbe97..807bcad716a668 100644 --- a/drivers/hwmon/mcp9902.c +++ b/drivers/hwmon/mcp9902.c @@ -69,7 +69,7 @@ static inline void spi_unlock(struct device *dev) { if(!pm_runtime_suspended(dev)) usleep_range(100, 200); - msleep(1); +// msleep(1); mutex_unlock(&datum_b53_spi_mutex); } diff --git a/drivers/net/dsa/b53/b53_spi.c b/drivers/net/dsa/b53/b53_spi.c index 78b257937037bc..788dbee631cc22 100644 --- a/drivers/net/dsa/b53/b53_spi.c +++ b/drivers/net/dsa/b53/b53_spi.c @@ -52,7 +52,7 @@ static inline void spi_unlock(struct device *dev) { if(!pm_runtime_suspended(dev)) usleep_range(100, 200); - msleep(1); +// msleep(1); mutex_unlock(&datum_b53_spi_mutex); } @@ -66,9 +66,9 @@ static inline int b53_spi_read_reg(struct spi_device *spi, u8 reg, u8 *val, txbuf[0] = B53_SPI_CMD_NORMAL | B53_SPI_CMD_READ; txbuf[1] = reg; - spi_lock(); +// spi_lock(); retval = spi_write_then_read(spi, txbuf, 2, val, len); - spi_unlock(dev); +// spi_unlock(dev); return retval; } @@ -79,6 +79,7 @@ static inline int b53_spi_clear_status(struct spi_device *spi) u8 rxbuf; int ret; +// printk("dsi-b53_spi_clear_status()\n"); for (i = 0; i < 10; i++) { ret = b53_spi_read_reg(spi, B53_SPI_STATUS, &rxbuf, 1); if (ret) @@ -109,9 +110,9 @@ static inline int b53_spi_set_page(struct spi_device *spi, u8 page) txbuf[1] = B53_SPI_PAGE_SELECT; txbuf[2] = page; - spi_lock(); +// spi_lock(); retval = spi_write(spi, txbuf, sizeof(txbuf)); - spi_unlock(dev); +// spi_unlock(dev); return retval; } @@ -120,6 +121,7 @@ static inline int b53_prepare_reg_access(struct spi_device *spi, u8 page) { int ret = b53_spi_clear_status(spi); +// printk("dsi-b53_prepare_reg_access(): page=0x%02x\n", page); if (ret) return ret; @@ -132,6 +134,7 @@ static int b53_spi_prepare_reg_read(struct spi_device *spi, u8 reg) int retry_count; int ret; +// printk("dsi-b53_spi_prepare_reg_read(): reg=0x%02x\n", reg); ret = b53_spi_read_reg(spi, reg, &rxbuf, 1); if (ret) return ret; @@ -162,6 +165,7 @@ static int b53_spi_read(struct b53_device *dev, u8 page, u8 reg, u8 *data, struct spi_device *spi = dev->priv; int ret; + spi_lock(); ret = b53_prepare_reg_access(spi, page); if (ret) return ret; @@ -170,7 +174,10 @@ static int b53_spi_read(struct b53_device *dev, u8 page, u8 reg, u8 *data, if (ret) return ret; - return b53_spi_read_reg(spi, B53_SPI_DATA, data, len); + ret = b53_spi_read_reg(spi, B53_SPI_DATA, data, len); + spi_unlock(spi->dev.parent->parent); + + return ret; } static int b53_spi_read8(struct b53_device *dev, u8 page, u8 reg, u8 *val) @@ -238,6 +245,7 @@ static int b53_spi_write8(struct b53_device *dev, u8 page, u8 reg, u8 value) u8 txbuf[3]; int retval; + spi_lock(); ret = b53_prepare_reg_access(spi, page); if (ret) return ret; @@ -246,7 +254,6 @@ static int b53_spi_write8(struct b53_device *dev, u8 page, u8 reg, u8 value) txbuf[1] = reg; txbuf[2] = value; - spi_lock(); dev_err(device, "dsi-b53_spi_write8(): %02x %02x %02x\n", txbuf[0], txbuf[1], txbuf[2]); retval = spi_write(spi, txbuf, sizeof(txbuf)); spi_unlock(device); @@ -262,6 +269,7 @@ static int b53_spi_write16(struct b53_device *dev, u8 page, u8 reg, u16 value) u8 txbuf[4]; int retval; + spi_lock(); ret = b53_prepare_reg_access(spi, page); if (ret) return ret; @@ -270,7 +278,6 @@ static int b53_spi_write16(struct b53_device *dev, u8 page, u8 reg, u16 value) txbuf[1] = reg; put_unaligned_le16(value, &txbuf[2]); - spi_lock(); retval = spi_write(spi, txbuf, sizeof(txbuf)); spi_unlock(device); @@ -285,6 +292,7 @@ static int b53_spi_write32(struct b53_device *dev, u8 page, u8 reg, u32 value) u8 txbuf[6]; int retval; + spi_lock(); ret = b53_prepare_reg_access(spi, page); if (ret) return ret; @@ -293,7 +301,6 @@ static int b53_spi_write32(struct b53_device *dev, u8 page, u8 reg, u32 value) txbuf[1] = reg; put_unaligned_le32(value, &txbuf[2]); - spi_lock(); retval = spi_write(spi, txbuf, sizeof(txbuf)); spi_unlock(device); @@ -308,6 +315,7 @@ static int b53_spi_write48(struct b53_device *dev, u8 page, u8 reg, u64 value) u8 txbuf[10]; int retval; + spi_lock(); ret = b53_prepare_reg_access(spi, page); if (ret) return ret; @@ -316,7 +324,6 @@ static int b53_spi_write48(struct b53_device *dev, u8 page, u8 reg, u64 value) txbuf[1] = reg; put_unaligned_le64(value, &txbuf[2]); - spi_lock(); retval = spi_write(spi, txbuf, sizeof(txbuf) - 2); spi_unlock(device); @@ -331,6 +338,7 @@ static int b53_spi_write64(struct b53_device *dev, u8 page, u8 reg, u64 value) u8 txbuf[10]; int retval; + spi_lock(); ret = b53_prepare_reg_access(spi, page); if (ret) return ret; @@ -339,7 +347,6 @@ static int b53_spi_write64(struct b53_device *dev, u8 page, u8 reg, u64 value) txbuf[1] = reg; put_unaligned_le64(value, &txbuf[2]); - spi_lock(); retval = spi_write(spi, txbuf, sizeof(txbuf)); spi_unlock(device); From dc26a9207d96bbdc8056805a671c2045f6341b10 Mon Sep 17 00:00:00 2001 From: Mark Carlin Date: Sat, 20 Apr 2024 17:03:05 -0700 Subject: [PATCH 23/27] User correct device in ina2xx driver to wait for powerdown. Remove some debug code. This appears to work, need to setup the pm autodisable for only the spi/i2c busses with the problem, then separate the i2c drivers into unmodified for the m7xc and modified for the t7xc. --- Makefile | 2 +- drivers/hwmon/ina2xx.c | 90 +++++++++++++++++------------------ drivers/hwmon/mcp9902.c | 1 - drivers/net/dsa/b53/b53_spi.c | 7 --- 4 files changed, 46 insertions(+), 54 deletions(-) diff --git a/Makefile b/Makefile index 2a4029aa2b191a..93ecf0cd5aa6cb 100644 --- a/Makefile +++ b/Makefile @@ -2,7 +2,7 @@ VERSION = 5 PATCHLEVEL = 15 SUBLEVEL = 107 -EXTRAVERSION = -datum.10-eng.2 +EXTRAVERSION = -datum.10-eng.3 NAME = Trick or Treat # *DOCUMENTATION* diff --git a/drivers/hwmon/ina2xx.c b/drivers/hwmon/ina2xx.c index 2366b319d8f550..d0fd7954afcd8c 100644 --- a/drivers/hwmon/ina2xx.c +++ b/drivers/hwmon/ina2xx.c @@ -155,6 +155,15 @@ static const struct ina2xx_config ina2xx_config[] = { */ static const int ina226_avg_tab[] = { 1, 4, 16, 64, 128, 256, 512, 1024 }; +static inline void spi_lock(void) { mutex_lock(&datum_b53_spi_mutex); } + +static inline void spi_unlock(struct device *dev) +{ + if(!pm_runtime_suspended(dev)) + usleep_range(100, 200); + mutex_unlock(&datum_b53_spi_mutex); +} + static int ina226_reg_to_interval(u16 config) { int avg = ina226_avg_tab[INA226_READ_AVG(config)]; @@ -191,16 +200,15 @@ static u16 ina226_interval_to_reg(int interval) static int ina2xx_calibrate(struct ina2xx_data *data) { struct device *dev = regmap_get_device(data->regmap); + struct device *device = dev->parent->parent; int retval; - mutex_lock(&datum_b53_spi_mutex); + spi_lock(); retval = regmap_write(data->regmap, INA2XX_CALIBRATION, data->config->calibration_value); - dev_err(dev, "ina2xx dev\n"); - if(pm_runtime_active(dev)) - usleep_range(100, 200); - mutex_unlock(&datum_b53_spi_mutex); + //dev_err(device, "dsi-ina2xx_calibrate()\n"); + spi_unlock(device); return retval; } @@ -211,16 +219,14 @@ static int ina2xx_calibrate(struct ina2xx_data *data) static int ina2xx_init(struct ina2xx_data *data) { struct device *dev = regmap_get_device(data->regmap); + struct device *device = dev->parent->parent; int ret; - mutex_lock(&datum_b53_spi_mutex); + spi_lock(); ret = regmap_write(data->regmap, INA2XX_CONFIG, data->config->config_default); - dev_err(dev, "ina2xx dev\n"); - if(pm_runtime_active(dev)) - usleep_range(100, 200); - mutex_unlock(&datum_b53_spi_mutex); - + //dev_err(device, "dsi-ina2xx_init()\n"); + spi_unlock(device); if (ret < 0) return ret; @@ -229,6 +235,7 @@ static int ina2xx_init(struct ina2xx_data *data) static int ina2xx_read_reg(struct device *dev, int reg, unsigned int *regval) { + struct device *device = dev->parent->parent->parent; struct ina2xx_data *data = dev_get_drvdata(dev); int ret, retry; @@ -236,12 +243,10 @@ static int ina2xx_read_reg(struct device *dev, int reg, unsigned int *regval) for (retry = 5; retry; retry--) { - mutex_lock(&datum_b53_spi_mutex); + spi_lock(); ret = regmap_read(data->regmap, reg, regval); - dev_err(dev, "ina2xx dev\n"); - if(pm_runtime_active(dev)) - usleep_range(100, 200); - mutex_unlock(&datum_b53_spi_mutex); + //dev_err(device, "dsi-ina2xx_read_reg()\n"); + spi_unlock(device); if (ret < 0) return ret; @@ -259,13 +264,11 @@ static int ina2xx_read_reg(struct device *dev, int reg, unsigned int *regval) if (*regval == 0) { unsigned int cal; - mutex_lock(&datum_b53_spi_mutex); + spi_lock(); ret = regmap_read(data->regmap, INA2XX_CALIBRATION, &cal); - dev_err(dev, "ina2xx dev\n"); - if(pm_runtime_active(dev)) - usleep_range(100, 200); - mutex_unlock(&datum_b53_spi_mutex); + //dev_err(device, "dsi-ina2xx_read_reg()\n"); + spi_unlock(device); if (ret < 0) return ret; @@ -403,6 +406,7 @@ static s16 ina226_alert_to_reg(struct ina2xx_data *data, u8 bit, int val) static ssize_t ina226_alert_show(struct device *dev, struct device_attribute *da, char *buf) { + struct device *device = dev->parent->parent->parent; struct sensor_device_attribute *attr = to_sensor_dev_attr(da); struct ina2xx_data *data = dev_get_drvdata(dev); int regval; @@ -410,7 +414,7 @@ static ssize_t ina226_alert_show(struct device *dev, int ret; mutex_lock(&data->config_lock); - mutex_lock(&datum_b53_spi_mutex); + spi_lock(); ret = regmap_read(data->regmap, INA226_MASK_ENABLE, ®val); if (ret) goto abort; @@ -424,10 +428,8 @@ static ssize_t ina226_alert_show(struct device *dev, ret = sysfs_emit(buf, "%d\n", val); abort: - dev_err(dev, "ina2xx dev\n"); - if(pm_runtime_active(dev)) - usleep_range(100, 200); - mutex_unlock(&datum_b53_spi_mutex); + //dev_err(device, "dsi-ina226_alert_show()\n"); + spi_unlock(device); mutex_unlock(&data->config_lock); return ret; } @@ -436,6 +438,7 @@ static ssize_t ina226_alert_store(struct device *dev, struct device_attribute *da, const char *buf, size_t count) { + struct device *device = dev->parent->parent->parent; struct sensor_device_attribute *attr = to_sensor_dev_attr(da); struct ina2xx_data *data = dev_get_drvdata(dev); unsigned long val; @@ -451,7 +454,7 @@ static ssize_t ina226_alert_store(struct device *dev, * if the value is non-zero. */ mutex_lock(&data->config_lock); - mutex_lock(&datum_b53_spi_mutex); + spi_lock(); ret = regmap_update_bits(data->regmap, INA226_MASK_ENABLE, INA226_ALERT_CONFIG_MASK, 0); if (ret < 0) @@ -474,10 +477,8 @@ static ssize_t ina226_alert_store(struct device *dev, ret = count; abort: - dev_err(dev, "ina2xx dev\n"); - if(pm_runtime_active(dev)) - usleep_range(100, 200); - mutex_unlock(&datum_b53_spi_mutex); + //dev_err(device, "dsi-ina226_alert_store()\n"); + spi_unlock(device); mutex_unlock(&data->config_lock); return ret; } @@ -485,18 +486,17 @@ static ssize_t ina226_alert_store(struct device *dev, static ssize_t ina226_alarm_show(struct device *dev, struct device_attribute *da, char *buf) { + struct device *device = dev->parent->parent->parent; struct sensor_device_attribute *attr = to_sensor_dev_attr(da); struct ina2xx_data *data = dev_get_drvdata(dev); int regval; int alarm = 0; int ret; - mutex_lock(&datum_b53_spi_mutex); + spi_lock(); ret = regmap_read(data->regmap, INA226_MASK_ENABLE, ®val); - dev_err(dev, "ina2xx dev\n"); - if(pm_runtime_active(dev)) - usleep_range(100, 200); - mutex_unlock(&datum_b53_spi_mutex); + //dev_err(device, "dsi-ina226_alarm_show()\n"); + spi_unlock(device); if (ret) return ret; @@ -558,6 +558,7 @@ static ssize_t ina226_interval_store(struct device *dev, struct device_attribute *da, const char *buf, size_t count) { + struct device *device = dev->parent->parent->parent; struct ina2xx_data *data = dev_get_drvdata(dev); unsigned long val; int status; @@ -569,13 +570,13 @@ static ssize_t ina226_interval_store(struct device *dev, if (val > INT_MAX || val == 0) return -EINVAL; - mutex_lock(&datum_b53_spi_mutex); + spi_lock(); status = regmap_update_bits(data->regmap, INA2XX_CONFIG, INA226_AVG_RD_MASK, ina226_interval_to_reg(val)); - if(pm_runtime_active(dev)) - usleep_range(100, 200); - mutex_unlock(&datum_b53_spi_mutex); + + //dev_err(device, "dsi-ina226_interval_store()\n"); + spi_unlock(device); if (status < 0) return status; @@ -585,16 +586,15 @@ static ssize_t ina226_interval_store(struct device *dev, static ssize_t ina226_interval_show(struct device *dev, struct device_attribute *da, char *buf) { + struct device *device = dev->parent->parent->parent; struct ina2xx_data *data = dev_get_drvdata(dev); int status; unsigned int regval; - mutex_lock(&datum_b53_spi_mutex); + spi_lock(); status = regmap_read(data->regmap, INA2XX_CONFIG, ®val); - dev_err(dev, "ina2xx dev\n"); - if(pm_runtime_active(dev)) - usleep_range(100, 200); - mutex_unlock(&datum_b53_spi_mutex); + //dev_err(device, "dsi-ina226_interval_show()\n"); + spi_unlock(device); if (status) return status; diff --git a/drivers/hwmon/mcp9902.c b/drivers/hwmon/mcp9902.c index 807bcad716a668..49be18e188c80c 100644 --- a/drivers/hwmon/mcp9902.c +++ b/drivers/hwmon/mcp9902.c @@ -69,7 +69,6 @@ static inline void spi_unlock(struct device *dev) { if(!pm_runtime_suspended(dev)) usleep_range(100, 200); -// msleep(1); mutex_unlock(&datum_b53_spi_mutex); } diff --git a/drivers/net/dsa/b53/b53_spi.c b/drivers/net/dsa/b53/b53_spi.c index 788dbee631cc22..5c81df0c2a41d0 100644 --- a/drivers/net/dsa/b53/b53_spi.c +++ b/drivers/net/dsa/b53/b53_spi.c @@ -52,7 +52,6 @@ static inline void spi_unlock(struct device *dev) { if(!pm_runtime_suspended(dev)) usleep_range(100, 200); -// msleep(1); mutex_unlock(&datum_b53_spi_mutex); } @@ -66,9 +65,7 @@ static inline int b53_spi_read_reg(struct spi_device *spi, u8 reg, u8 *val, txbuf[0] = B53_SPI_CMD_NORMAL | B53_SPI_CMD_READ; txbuf[1] = reg; -// spi_lock(); retval = spi_write_then_read(spi, txbuf, 2, val, len); -// spi_unlock(dev); return retval; } @@ -79,7 +76,6 @@ static inline int b53_spi_clear_status(struct spi_device *spi) u8 rxbuf; int ret; -// printk("dsi-b53_spi_clear_status()\n"); for (i = 0; i < 10; i++) { ret = b53_spi_read_reg(spi, B53_SPI_STATUS, &rxbuf, 1); if (ret) @@ -110,9 +106,7 @@ static inline int b53_spi_set_page(struct spi_device *spi, u8 page) txbuf[1] = B53_SPI_PAGE_SELECT; txbuf[2] = page; -// spi_lock(); retval = spi_write(spi, txbuf, sizeof(txbuf)); -// spi_unlock(dev); return retval; } @@ -254,7 +248,6 @@ static int b53_spi_write8(struct b53_device *dev, u8 page, u8 reg, u8 value) txbuf[1] = reg; txbuf[2] = value; - dev_err(device, "dsi-b53_spi_write8(): %02x %02x %02x\n", txbuf[0], txbuf[1], txbuf[2]); retval = spi_write(spi, txbuf, sizeof(txbuf)); spi_unlock(device); From aa8953c64563f72d5e5c35a863d505bec863f44e Mon Sep 17 00:00:00 2001 From: Mark Carlin Date: Sat, 20 Apr 2024 18:38:21 -0700 Subject: [PATCH 24/27] Remove most debugging output. Still need to retore phy poll interval and i2c device memory (only use i2c if timer expired). --- drivers/hwmon/ina2xx.c | 10 +--------- drivers/hwmon/mcp9902.c | 5 +++-- drivers/i2c/busses/i2c-stm32f7.c | 3 +-- drivers/net/dsa/b53/b53_spi.c | 13 +++---------- drivers/net/phy/phy.c | 3 --- drivers/spi/spi-stm32.c | 3 +-- 6 files changed, 9 insertions(+), 28 deletions(-) diff --git a/drivers/hwmon/ina2xx.c b/drivers/hwmon/ina2xx.c index d0fd7954afcd8c..e5cee83f4b3273 100644 --- a/drivers/hwmon/ina2xx.c +++ b/drivers/hwmon/ina2xx.c @@ -207,7 +207,6 @@ static int ina2xx_calibrate(struct ina2xx_data *data) retval = regmap_write(data->regmap, INA2XX_CALIBRATION, data->config->calibration_value); - //dev_err(device, "dsi-ina2xx_calibrate()\n"); spi_unlock(device); return retval; @@ -225,7 +224,6 @@ static int ina2xx_init(struct ina2xx_data *data) spi_lock(); ret = regmap_write(data->regmap, INA2XX_CONFIG, data->config->config_default); - //dev_err(device, "dsi-ina2xx_init()\n"); spi_unlock(device); if (ret < 0) return ret; @@ -245,7 +243,6 @@ static int ina2xx_read_reg(struct device *dev, int reg, unsigned int *regval) spi_lock(); ret = regmap_read(data->regmap, reg, regval); - //dev_err(device, "dsi-ina2xx_read_reg()\n"); spi_unlock(device); if (ret < 0) @@ -267,7 +264,6 @@ static int ina2xx_read_reg(struct device *dev, int reg, unsigned int *regval) spi_lock(); ret = regmap_read(data->regmap, INA2XX_CALIBRATION, &cal); - //dev_err(device, "dsi-ina2xx_read_reg()\n"); spi_unlock(device); if (ret < 0) @@ -428,7 +424,6 @@ static ssize_t ina226_alert_show(struct device *dev, ret = sysfs_emit(buf, "%d\n", val); abort: - //dev_err(device, "dsi-ina226_alert_show()\n"); spi_unlock(device); mutex_unlock(&data->config_lock); return ret; @@ -477,7 +472,6 @@ static ssize_t ina226_alert_store(struct device *dev, ret = count; abort: - //dev_err(device, "dsi-ina226_alert_store()\n"); spi_unlock(device); mutex_unlock(&data->config_lock); return ret; @@ -495,7 +489,6 @@ static ssize_t ina226_alarm_show(struct device *dev, spi_lock(); ret = regmap_read(data->regmap, INA226_MASK_ENABLE, ®val); - //dev_err(device, "dsi-ina226_alarm_show()\n"); spi_unlock(device); if (ret) return ret; @@ -575,7 +568,6 @@ static ssize_t ina226_interval_store(struct device *dev, INA226_AVG_RD_MASK, ina226_interval_to_reg(val)); - //dev_err(device, "dsi-ina226_interval_store()\n"); spi_unlock(device); if (status < 0) return status; @@ -593,7 +585,6 @@ static ssize_t ina226_interval_show(struct device *dev, spi_lock(); status = regmap_read(data->regmap, INA2XX_CONFIG, ®val); - //dev_err(device, "dsi-ina226_interval_show()\n"); spi_unlock(device); if (status) return status; @@ -708,6 +699,7 @@ static int ina2xx_probe(struct i2c_client *client) val = INA2XX_RSHUNT_DEFAULT; } + pm_runtime_set_autosuspend_delay(dev->parent->parent, 0); ina2xx_set_shunt(data, val); ina2xx_regmap_config.max_register = data->config->registers; diff --git a/drivers/hwmon/mcp9902.c b/drivers/hwmon/mcp9902.c index 49be18e188c80c..55e1c5ac5d85e3 100644 --- a/drivers/hwmon/mcp9902.c +++ b/drivers/hwmon/mcp9902.c @@ -298,7 +298,6 @@ static int mcp9902_detect(struct i2c_client *client, spi_lock(); man_id = i2c_smbus_read_byte_data(client, MCP9902_REG_R_MAN_ID); chip_id = i2c_smbus_read_byte_data(client, MCP9902_REG_R_CHIP_ID); - dev_err(adapter->dev.parent, "dsi-mcp9902_detect()\n"); spi_unlock(adapter->dev.parent); if (man_id != 0x5D || chip_id != 0x04) { dev_info(&adapter->dev, @@ -315,13 +314,15 @@ static int mcp9902_detect(struct i2c_client *client, static void mcp9902_init_client(struct i2c_client *client) { struct i2c_adapter *adapter = client->adapter; + + pm_runtime_set_autosuspend_delay(adapter->dev.parent, 0); + /* * Start the conversions. */ spi_lock(); i2c_smbus_write_byte_data(client, MCP9902_REG_W_CONVRATE, 5); /* 2 Hz */ i2c_smbus_write_byte_data(client, MCP9902_REG_W_CONFIG, 0x9F); /* run - extended temp */ - dev_err(adapter->dev.parent, "dsi-mcp9902_init_client()\n"); spi_unlock(adapter->dev.parent); } diff --git a/drivers/i2c/busses/i2c-stm32f7.c b/drivers/i2c/busses/i2c-stm32f7.c index 102afd2623ea6a..791baea3623bab 100644 --- a/drivers/i2c/busses/i2c-stm32f7.c +++ b/drivers/i2c/busses/i2c-stm32f7.c @@ -179,7 +179,7 @@ enum { #define STM32F7_SCLH_MAX BIT(8) #define STM32F7_SCLL_MAX BIT(8) -#define STM32F7_AUTOSUSPEND_DELAY 0 +#define STM32F7_AUTOSUSPEND_DELAY (HZ / 100) /** * struct stm32f7_i2c_regs - i2c f7 registers backup @@ -2228,7 +2228,6 @@ static int stm32f7_i2c_probe(struct platform_device *pdev) platform_set_drvdata(pdev, i2c_dev); - dev_err(i2c_dev->dev, "dsi-stm32f7_i2c_probe() [i2c_dev->dev]\n"); pm_runtime_set_autosuspend_delay(i2c_dev->dev, STM32F7_AUTOSUSPEND_DELAY); pm_runtime_use_autosuspend(i2c_dev->dev); diff --git a/drivers/net/dsa/b53/b53_spi.c b/drivers/net/dsa/b53/b53_spi.c index 5c81df0c2a41d0..88bc76d201cfd2 100644 --- a/drivers/net/dsa/b53/b53_spi.c +++ b/drivers/net/dsa/b53/b53_spi.c @@ -58,7 +58,6 @@ static inline void spi_unlock(struct device *dev) static inline int b53_spi_read_reg(struct spi_device *spi, u8 reg, u8 *val, unsigned int len) { - struct device *dev = spi->dev.parent->parent; u8 txbuf[2]; int retval; @@ -88,17 +87,13 @@ static inline int b53_spi_clear_status(struct spi_device *spi) } if (i == 10) - { - printk("dsi-datum: b53_spi_clear_status failed, rxbuf=0x%02x\n", rxbuf); return -EIO; - } return 0; } static inline int b53_spi_set_page(struct spi_device *spi, u8 page) { - struct device *dev = spi->dev.parent->parent; u8 txbuf[3]; int retval; @@ -115,7 +110,6 @@ static inline int b53_prepare_reg_access(struct spi_device *spi, u8 page) { int ret = b53_spi_clear_status(spi); -// printk("dsi-b53_prepare_reg_access(): page=0x%02x\n", page); if (ret) return ret; @@ -128,7 +122,6 @@ static int b53_spi_prepare_reg_read(struct spi_device *spi, u8 reg) int retry_count; int ret; -// printk("dsi-b53_spi_prepare_reg_read(): reg=0x%02x\n", reg); ret = b53_spi_read_reg(spi, reg, &rxbuf, 1); if (ret) return ret; @@ -145,10 +138,7 @@ static int b53_spi_prepare_reg_read(struct spi_device *spi, u8 reg) } if (retry_count == 10) - { - printk("dsi-datum: b53_spi_prepare_reg_read failed, rxbuf=0x%02x\n", rxbuf); return -EIO; - } return 0; } @@ -361,6 +351,7 @@ static const struct b53_io_ops b53_spi_ops = { static int b53_spi_probe(struct spi_device *spi) { + struct device *device = spi->dev.parent->parent; struct b53_device *dev; int ret; struct net_device *ndev = dev_get_by_name(&init_net, "eth0"); @@ -375,6 +366,8 @@ static int b53_spi_probe(struct spi_device *spi) if (spi->dev.platform_data) dev->pdata = spi->dev.platform_data; + pm_runtime_set_autosuspend_delay(device, 0); + ret = b53_switch_register(dev); if (ret) return ret; diff --git a/drivers/net/phy/phy.c b/drivers/net/phy/phy.c index 082053ee00c3d0..7c130bcde9b61e 100644 --- a/drivers/net/phy/phy.c +++ b/drivers/net/phy/phy.c @@ -1209,10 +1209,7 @@ void phy_state_machine(struct work_struct *work) return; if (err < 0) - { - printk("dsi-phy_state_machine(): PHY_ERROR error=%d\n", err); phy_error(phydev); - } phy_process_state_change(phydev, old_state); diff --git a/drivers/spi/spi-stm32.c b/drivers/spi/spi-stm32.c index a80c9d7f9f9f9e..e750dd73a9b6cd 100644 --- a/drivers/spi/spi-stm32.c +++ b/drivers/spi/spi-stm32.c @@ -175,7 +175,7 @@ #define SPI_3WIRE_TX 3 #define SPI_3WIRE_RX 4 -#define STM32_SPI_AUTOSUSPEND_DELAY 0 /* 0 ms */ +#define STM32_SPI_AUTOSUSPEND_DELAY 1 /* 1 ms */ /* * use PIO for small transfers, avoiding DMA setup/teardown overhead for drivers @@ -2041,7 +2041,6 @@ static int stm32_spi_probe(struct platform_device *pdev) if (spi->dma_tx || spi->dma_rx) ctrl->can_dma = stm32_spi_can_dma; - dev_err(&pdev->dev, "dsi-stm32_spi_probe() [&pdev->dev]\n"); pm_runtime_set_autosuspend_delay(&pdev->dev, STM32_SPI_AUTOSUSPEND_DELAY); pm_runtime_use_autosuspend(&pdev->dev); From 3c0fe677155554fb6f5d684478410f5b14e9b68a Mon Sep 17 00:00:00 2001 From: mcarlin Date: Sun, 21 Apr 2024 12:03:30 -0700 Subject: [PATCH 25/27] v5.15.107-datum.10-eng.4: Duplicate and separate I2C ina2xx and mcp9902 drivers into those that supports I2C/SPI clock short and those that don't. Needed for one kernel to support both the T7XC and M7XC. This version still has increased BR53134, INA2236 and MCP9902 bus activity for testing. --- Makefile | 2 +- drivers/hwmon/Kconfig | 30 ++ drivers/hwmon/Makefile | 2 + drivers/hwmon/ina2xx.c | 57 +- drivers/hwmon/ina2xx_datum.c | 782 ++++++++++++++++++++++++++++ drivers/hwmon/mcp9902.c | 53 +- drivers/hwmon/mcp9902_datum.c | 384 ++++++++++++++ drivers/net/dsa/b53/Kconfig | 8 + drivers/net/dsa/b53/Makefile | 1 + drivers/net/dsa/b53/b53_spi.c | 73 +-- drivers/net/dsa/b53/b53_spi_datum.c | 423 +++++++++++++++ 11 files changed, 1648 insertions(+), 167 deletions(-) create mode 100644 drivers/hwmon/ina2xx_datum.c create mode 100644 drivers/hwmon/mcp9902_datum.c create mode 100644 drivers/net/dsa/b53/b53_spi_datum.c diff --git a/Makefile b/Makefile index 93ecf0cd5aa6cb..fa0e1899dd1b5c 100644 --- a/Makefile +++ b/Makefile @@ -2,7 +2,7 @@ VERSION = 5 PATCHLEVEL = 15 SUBLEVEL = 107 -EXTRAVERSION = -datum.10-eng.3 +EXTRAVERSION = -datum.10-eng.4 NAME = Trick or Treat # *DOCUMENTATION* diff --git a/drivers/hwmon/Kconfig b/drivers/hwmon/Kconfig index d71ff7fc9d9a36..8a7620cbd12dba 100644 --- a/drivers/hwmon/Kconfig +++ b/drivers/hwmon/Kconfig @@ -1122,6 +1122,20 @@ config SENSORS_MCP9902 This driver can also be built as a module. If so, the module will be called mcp9902. +config SENSORS_MCP9902_DATUM + tristate "Microchip MCP9902 and compatibles with Datum SPI/I2C clocks shorted" + depends on I2C + help + If you say yes here you get support for MCP9902. + The MCP9902 is a single channel temperature sensor + with internal thermal diode. + + This driver can also be built as a module. If so, the module + will be called mcp9902-datum. + + This driver is for use with the Datum Systems Inc. SPI/I2C shorted bus + management system that fixes the I2C and SPI bus clocks shorted together. + config SENSORS_MLXREG_FAN tristate "Mellanox FAN driver" depends on MELLANOX_PLATFORM @@ -1873,6 +1887,22 @@ config SENSORS_INA2XX This driver can also be built as a module. If so, the module will be called ina2xx. +config SENSORS_INA2XX_DATUM + tristate "Texas Instruments INA219 and compatibles with Datum SPI/I2C clocks shorted" + depends on I2C + select REGMAP_I2C + help + If you say yes here you get support for INA219, INA220, INA226, + INA230, and INA231 power monitor chips. + + The INA2xx driver is configured for the default configuration of + the part as described in the datasheet. + Default value for Rshunt is 10 mOhms. + This driver can also be built as a module. If so, the module + will be called ina2xx-datum. + This driver is for use with the Datum Systems Inc. SPI/I2C shorted bus + management system that fixes the I2C and SPI bus clocks shorted together. + config SENSORS_INA3221 tristate "Texas Instruments INA3221 Triple Power Monitor" depends on I2C diff --git a/drivers/hwmon/Makefile b/drivers/hwmon/Makefile index d93128d89485a4..3192f8208ff70e 100644 --- a/drivers/hwmon/Makefile +++ b/drivers/hwmon/Makefile @@ -90,6 +90,7 @@ obj-$(CONFIG_SENSORS_IBMPOWERNV)+= ibmpowernv.o obj-$(CONFIG_SENSORS_IIO_HWMON) += iio_hwmon.o obj-$(CONFIG_SENSORS_INA209) += ina209.o obj-$(CONFIG_SENSORS_INA2XX) += ina2xx.o +obj-$(CONFIG_SENSORS_INA2XX_DATUM) += ina2xx_datum.o obj-$(CONFIG_SENSORS_INA3221) += ina3221.o obj-$(CONFIG_SENSORS_INTEL_M10_BMC_HWMON) += intel-m10-bmc-hwmon.o obj-$(CONFIG_SENSORS_IT87) += it87.o @@ -144,6 +145,7 @@ obj-$(CONFIG_SENSORS_MAX31790) += max31790.o obj-$(CONFIG_SENSORS_MC13783_ADC)+= mc13783-adc.o obj-$(CONFIG_SENSORS_MCP3021) += mcp3021.o obj-$(CONFIG_SENSORS_MCP9902) += mcp9902.o +obj-$(CONFIG_SENSORS_MCP9902_DATUM) += mcp9902_datum.o obj-$(CONFIG_SENSORS_TC654) += tc654.o obj-$(CONFIG_SENSORS_TPS23861) += tps23861.o obj-$(CONFIG_SENSORS_MLXREG_FAN) += mlxreg-fan.o diff --git a/drivers/hwmon/ina2xx.c b/drivers/hwmon/ina2xx.c index e5cee83f4b3273..65ec0331de9d72 100644 --- a/drivers/hwmon/ina2xx.c +++ b/drivers/hwmon/ina2xx.c @@ -34,7 +34,6 @@ #include #include #include -#include #include #include @@ -95,8 +94,6 @@ */ #define INA226_TOTAL_CONV_TIME_DEFAULT 2200 -extern struct mutex datum_b53_spi_mutex; - static struct regmap_config ina2xx_regmap_config = { .reg_bits = 8, .val_bits = 16, @@ -155,15 +152,6 @@ static const struct ina2xx_config ina2xx_config[] = { */ static const int ina226_avg_tab[] = { 1, 4, 16, 64, 128, 256, 512, 1024 }; -static inline void spi_lock(void) { mutex_lock(&datum_b53_spi_mutex); } - -static inline void spi_unlock(struct device *dev) -{ - if(!pm_runtime_suspended(dev)) - usleep_range(100, 200); - mutex_unlock(&datum_b53_spi_mutex); -} - static int ina226_reg_to_interval(u16 config) { int avg = ina226_avg_tab[INA226_READ_AVG(config)]; @@ -199,17 +187,8 @@ static u16 ina226_interval_to_reg(int interval) */ static int ina2xx_calibrate(struct ina2xx_data *data) { - struct device *dev = regmap_get_device(data->regmap); - struct device *device = dev->parent->parent; - int retval; - - spi_lock(); - retval = regmap_write(data->regmap, INA2XX_CALIBRATION, + return regmap_write(data->regmap, INA2XX_CALIBRATION, data->config->calibration_value); - - spi_unlock(device); - - return retval; } /* @@ -217,14 +196,8 @@ static int ina2xx_calibrate(struct ina2xx_data *data) */ static int ina2xx_init(struct ina2xx_data *data) { - struct device *dev = regmap_get_device(data->regmap); - struct device *device = dev->parent->parent; - int ret; - - spi_lock(); - ret = regmap_write(data->regmap, INA2XX_CONFIG, + int ret = regmap_write(data->regmap, INA2XX_CONFIG, data->config->config_default); - spi_unlock(device); if (ret < 0) return ret; @@ -233,7 +206,6 @@ static int ina2xx_init(struct ina2xx_data *data) static int ina2xx_read_reg(struct device *dev, int reg, unsigned int *regval) { - struct device *device = dev->parent->parent->parent; struct ina2xx_data *data = dev_get_drvdata(dev); int ret, retry; @@ -241,10 +213,7 @@ static int ina2xx_read_reg(struct device *dev, int reg, unsigned int *regval) for (retry = 5; retry; retry--) { - spi_lock(); ret = regmap_read(data->regmap, reg, regval); - spi_unlock(device); - if (ret < 0) return ret; @@ -261,11 +230,8 @@ static int ina2xx_read_reg(struct device *dev, int reg, unsigned int *regval) if (*regval == 0) { unsigned int cal; - spi_lock(); ret = regmap_read(data->regmap, INA2XX_CALIBRATION, &cal); - spi_unlock(device); - if (ret < 0) return ret; @@ -402,7 +368,6 @@ static s16 ina226_alert_to_reg(struct ina2xx_data *data, u8 bit, int val) static ssize_t ina226_alert_show(struct device *dev, struct device_attribute *da, char *buf) { - struct device *device = dev->parent->parent->parent; struct sensor_device_attribute *attr = to_sensor_dev_attr(da); struct ina2xx_data *data = dev_get_drvdata(dev); int regval; @@ -410,7 +375,6 @@ static ssize_t ina226_alert_show(struct device *dev, int ret; mutex_lock(&data->config_lock); - spi_lock(); ret = regmap_read(data->regmap, INA226_MASK_ENABLE, ®val); if (ret) goto abort; @@ -424,7 +388,6 @@ static ssize_t ina226_alert_show(struct device *dev, ret = sysfs_emit(buf, "%d\n", val); abort: - spi_unlock(device); mutex_unlock(&data->config_lock); return ret; } @@ -433,7 +396,6 @@ static ssize_t ina226_alert_store(struct device *dev, struct device_attribute *da, const char *buf, size_t count) { - struct device *device = dev->parent->parent->parent; struct sensor_device_attribute *attr = to_sensor_dev_attr(da); struct ina2xx_data *data = dev_get_drvdata(dev); unsigned long val; @@ -449,16 +411,13 @@ static ssize_t ina226_alert_store(struct device *dev, * if the value is non-zero. */ mutex_lock(&data->config_lock); - spi_lock(); ret = regmap_update_bits(data->regmap, INA226_MASK_ENABLE, INA226_ALERT_CONFIG_MASK, 0); if (ret < 0) goto abort; - ret = regmap_write(data->regmap, INA226_ALERT_LIMIT, ina226_alert_to_reg(data, attr->index, val)); - if (ret < 0) goto abort; @@ -472,7 +431,6 @@ static ssize_t ina226_alert_store(struct device *dev, ret = count; abort: - spi_unlock(device); mutex_unlock(&data->config_lock); return ret; } @@ -480,16 +438,13 @@ static ssize_t ina226_alert_store(struct device *dev, static ssize_t ina226_alarm_show(struct device *dev, struct device_attribute *da, char *buf) { - struct device *device = dev->parent->parent->parent; struct sensor_device_attribute *attr = to_sensor_dev_attr(da); struct ina2xx_data *data = dev_get_drvdata(dev); int regval; int alarm = 0; int ret; - spi_lock(); ret = regmap_read(data->regmap, INA226_MASK_ENABLE, ®val); - spi_unlock(device); if (ret) return ret; @@ -551,7 +506,6 @@ static ssize_t ina226_interval_store(struct device *dev, struct device_attribute *da, const char *buf, size_t count) { - struct device *device = dev->parent->parent->parent; struct ina2xx_data *data = dev_get_drvdata(dev); unsigned long val; int status; @@ -563,12 +517,9 @@ static ssize_t ina226_interval_store(struct device *dev, if (val > INT_MAX || val == 0) return -EINVAL; - spi_lock(); status = regmap_update_bits(data->regmap, INA2XX_CONFIG, INA226_AVG_RD_MASK, ina226_interval_to_reg(val)); - - spi_unlock(device); if (status < 0) return status; @@ -578,14 +529,11 @@ static ssize_t ina226_interval_store(struct device *dev, static ssize_t ina226_interval_show(struct device *dev, struct device_attribute *da, char *buf) { - struct device *device = dev->parent->parent->parent; struct ina2xx_data *data = dev_get_drvdata(dev); int status; unsigned int regval; - spi_lock(); status = regmap_read(data->regmap, INA2XX_CONFIG, ®val); - spi_unlock(device); if (status) return status; @@ -699,7 +647,6 @@ static int ina2xx_probe(struct i2c_client *client) val = INA2XX_RSHUNT_DEFAULT; } - pm_runtime_set_autosuspend_delay(dev->parent->parent, 0); ina2xx_set_shunt(data, val); ina2xx_regmap_config.max_register = data->config->registers; diff --git a/drivers/hwmon/ina2xx_datum.c b/drivers/hwmon/ina2xx_datum.c new file mode 100644 index 00000000000000..eb91dc936b1ce2 --- /dev/null +++ b/drivers/hwmon/ina2xx_datum.c @@ -0,0 +1,782 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * Driver for Texas Instruments INA219, INA226 power monitor chips + * + * INA219: + * Zero Drift Bi-Directional Current/Power Monitor with I2C Interface + * Datasheet: https://www.ti.com/product/ina219 + * + * INA220: + * Bi-Directional Current/Power Monitor with I2C Interface + * Datasheet: https://www.ti.com/product/ina220 + * + * INA226: + * Bi-Directional Current/Power Monitor with I2C Interface + * Datasheet: https://www.ti.com/product/ina226 + * + * INA230: + * Bi-directional Current/Power Monitor with I2C Interface + * Datasheet: https://www.ti.com/product/ina230 + * + * Copyright (C) 2012 Lothar Felten + * Thanks to Jan Volkering + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +/* common register definitions */ +#define INA2XX_CONFIG 0x00 +#define INA2XX_SHUNT_VOLTAGE 0x01 /* readonly */ +#define INA2XX_BUS_VOLTAGE 0x02 /* readonly */ +#define INA2XX_POWER 0x03 /* readonly */ +#define INA2XX_CURRENT 0x04 /* readonly */ +#define INA2XX_CALIBRATION 0x05 + +/* INA226 register definitions */ +#define INA226_MASK_ENABLE 0x06 +#define INA226_ALERT_LIMIT 0x07 +#define INA226_DIE_ID 0xFF + +/* register count */ +#define INA219_REGISTERS 6 +#define INA226_REGISTERS 8 + +#define INA2XX_MAX_REGISTERS 8 + +/* settings - depend on use case */ +#define INA219_CONFIG_DEFAULT 0x399F /* PGA=8 */ +#define INA226_CONFIG_DEFAULT 0x4527 /* averages=16 */ + +/* worst case is 68.10 ms (~14.6Hz, ina219) */ +#define INA2XX_CONVERSION_RATE 15 +#define INA2XX_MAX_DELAY 69 /* worst case delay in ms */ + +#define INA2XX_RSHUNT_DEFAULT 10000 + +/* bit mask for reading the averaging setting in the configuration register */ +#define INA226_AVG_RD_MASK 0x0E00 + +#define INA226_READ_AVG(reg) (((reg) & INA226_AVG_RD_MASK) >> 9) +#define INA226_SHIFT_AVG(val) ((val) << 9) + +/* bit number of alert functions in Mask/Enable Register */ +#define INA226_SHUNT_OVER_VOLTAGE_BIT 15 +#define INA226_SHUNT_UNDER_VOLTAGE_BIT 14 +#define INA226_BUS_OVER_VOLTAGE_BIT 13 +#define INA226_BUS_UNDER_VOLTAGE_BIT 12 +#define INA226_POWER_OVER_LIMIT_BIT 11 + +/* bit mask for alert config bits of Mask/Enable Register */ +#define INA226_ALERT_CONFIG_MASK 0xFC00 +#define INA226_ALERT_FUNCTION_FLAG BIT(4) + +/* common attrs, ina226 attrs and NULL */ +#define INA2XX_MAX_ATTRIBUTE_GROUPS 3 + +/* + * Both bus voltage and shunt voltage conversion times for ina226 are set + * to 0b0100 on POR, which translates to 2200 microseconds in total. + */ +#define INA226_TOTAL_CONV_TIME_DEFAULT 2200 + +extern struct mutex datum_b53_spi_mutex; + +static struct regmap_config ina2xx_regmap_config = { + .reg_bits = 8, + .val_bits = 16, +}; + +enum ina2xx_ids { ina219, ina226 }; + +struct ina2xx_config { + u16 config_default; + int calibration_value; + int registers; + int shunt_div; + int bus_voltage_shift; + int bus_voltage_lsb; /* uV */ + int power_lsb_factor; +}; + +struct ina2xx_data { + const struct ina2xx_config *config; + + long rshunt; + long current_lsb_uA; + long power_lsb_uW; + struct mutex config_lock; + struct regmap *regmap; + + const struct attribute_group *groups[INA2XX_MAX_ATTRIBUTE_GROUPS]; +}; + +static const struct ina2xx_config ina2xx_config[] = { + [ina219] = { + .config_default = INA219_CONFIG_DEFAULT, + .calibration_value = 4096, + .registers = INA219_REGISTERS, + .shunt_div = 100, + .bus_voltage_shift = 3, + .bus_voltage_lsb = 4000, + .power_lsb_factor = 20, + }, + [ina226] = { + .config_default = INA226_CONFIG_DEFAULT, + .calibration_value = 2048, + .registers = INA226_REGISTERS, + .shunt_div = 400, + .bus_voltage_shift = 0, + .bus_voltage_lsb = 1250, + .power_lsb_factor = 25, + }, +}; + +/* + * Available averaging rates for ina226. The indices correspond with + * the bit values expected by the chip (according to the ina226 datasheet, + * table 3 AVG bit settings, found at + * https://www.ti.com/lit/ds/symlink/ina226.pdf. + */ +static const int ina226_avg_tab[] = { 1, 4, 16, 64, 128, 256, 512, 1024 }; + +static inline void spi_lock(void) { mutex_lock(&datum_b53_spi_mutex); } + +static inline void spi_unlock(struct device *dev) +{ + if(!pm_runtime_suspended(dev)) + usleep_range(100, 200); + mutex_unlock(&datum_b53_spi_mutex); +} + +static int ina226_reg_to_interval(u16 config) +{ + int avg = ina226_avg_tab[INA226_READ_AVG(config)]; + + /* + * Multiply the total conversion time by the number of averages. + * Return the result in milliseconds. + */ + return DIV_ROUND_CLOSEST(avg * INA226_TOTAL_CONV_TIME_DEFAULT, 1000); +} + +/* + * Return the new, shifted AVG field value of CONFIG register, + * to use with regmap_update_bits + */ +static u16 ina226_interval_to_reg(int interval) +{ + int avg, avg_bits; + + avg = DIV_ROUND_CLOSEST(interval * 1000, + INA226_TOTAL_CONV_TIME_DEFAULT); + avg_bits = find_closest(avg, ina226_avg_tab, + ARRAY_SIZE(ina226_avg_tab)); + + return INA226_SHIFT_AVG(avg_bits); +} + +/* + * Calibration register is set to the best value, which eliminates + * truncation errors on calculating current register in hardware. + * According to datasheet (eq. 3) the best values are 2048 for + * ina226 and 4096 for ina219. They are hardcoded as calibration_value. + */ +static int ina2xx_calibrate(struct ina2xx_data *data) +{ + struct device *dev = regmap_get_device(data->regmap); + struct device *device = dev->parent->parent; + int retval; + + spi_lock(); + retval = regmap_write(data->regmap, INA2XX_CALIBRATION, + data->config->calibration_value); + + spi_unlock(device); + + return retval; +} + +/* + * Initialize the configuration and calibration registers. + */ +static int ina2xx_init(struct ina2xx_data *data) +{ + struct device *dev = regmap_get_device(data->regmap); + struct device *device = dev->parent->parent; + int ret; + + spi_lock(); + ret = regmap_write(data->regmap, INA2XX_CONFIG, + data->config->config_default); + spi_unlock(device); + if (ret < 0) + return ret; + + return ina2xx_calibrate(data); +} + +static int ina2xx_read_reg(struct device *dev, int reg, unsigned int *regval) +{ + struct device *device = dev->parent->parent->parent; + struct ina2xx_data *data = dev_get_drvdata(dev); + int ret, retry; + + dev_dbg(dev, "Starting register %d read\n", reg); + + for (retry = 5; retry; retry--) { + + spi_lock(); + ret = regmap_read(data->regmap, reg, regval); + spi_unlock(device); + + if (ret < 0) + return ret; + + dev_dbg(dev, "read %d, val = 0x%04x\n", reg, *regval); + + /* + * If the current value in the calibration register is 0, the + * power and current registers will also remain at 0. In case + * the chip has been reset let's check the calibration + * register and reinitialize if needed. + * We do that extra read of the calibration register if there + * is some hint of a chip reset. + */ + if (*regval == 0) { + unsigned int cal; + + spi_lock(); + ret = regmap_read(data->regmap, INA2XX_CALIBRATION, + &cal); + spi_unlock(device); + + if (ret < 0) + return ret; + + if (cal == 0) { + dev_warn(dev, "chip not calibrated, reinitializing\n"); + + ret = ina2xx_init(data); + if (ret < 0) + return ret; + /* + * Let's make sure the power and current + * registers have been updated before trying + * again. + */ + msleep(INA2XX_MAX_DELAY); + continue; + } + } + return 0; + } + + /* + * If we're here then although all write operations succeeded, the + * chip still returns 0 in the calibration register. Nothing more we + * can do here. + */ + dev_err(dev, "unable to reinitialize the chip\n"); + return -ENODEV; +} + +static int ina2xx_get_value(struct ina2xx_data *data, u8 reg, + unsigned int regval) +{ + int val; + + switch (reg) { + case INA2XX_SHUNT_VOLTAGE: + /* signed register */ + val = (s16)regval * 1000; + val = DIV_ROUND_CLOSEST(val, data->config->shunt_div); + break; + case INA2XX_BUS_VOLTAGE: + val = (regval >> data->config->bus_voltage_shift) + * data->config->bus_voltage_lsb; + val = DIV_ROUND_CLOSEST(val, 1000); + break; + case INA2XX_POWER: + val = regval * data->power_lsb_uW; + break; + case INA2XX_CURRENT: + /* signed register, result in mA */ + val = (s16)regval * data->current_lsb_uA; + val = DIV_ROUND_CLOSEST(val, 1000); + break; + case INA2XX_CALIBRATION: + val = regval; + break; + default: + /* programmer goofed */ + WARN_ON_ONCE(1); + val = 0; + break; + } + + return val; +} + +static ssize_t ina2xx_value_show(struct device *dev, + struct device_attribute *da, char *buf) +{ + struct sensor_device_attribute *attr = to_sensor_dev_attr(da); + struct ina2xx_data *data = dev_get_drvdata(dev); + unsigned int regval; + + int err = ina2xx_read_reg(dev, attr->index, ®val); + + if (err < 0) + return err; + + return sysfs_emit(buf, "%d\n", ina2xx_get_value(data, attr->index, regval)); +} + +static int ina226_reg_to_alert(struct ina2xx_data *data, u8 bit, u16 regval) +{ + int reg; + + switch (bit) { + case INA226_SHUNT_OVER_VOLTAGE_BIT: + case INA226_SHUNT_UNDER_VOLTAGE_BIT: + reg = INA2XX_SHUNT_VOLTAGE; + break; + case INA226_BUS_OVER_VOLTAGE_BIT: + case INA226_BUS_UNDER_VOLTAGE_BIT: + reg = INA2XX_BUS_VOLTAGE; + break; + case INA226_POWER_OVER_LIMIT_BIT: + reg = INA2XX_POWER; + break; + default: + /* programmer goofed */ + WARN_ON_ONCE(1); + return 0; + } + + return ina2xx_get_value(data, reg, regval); +} + +/* + * Turns alert limit values into register values. + * Opposite of the formula in ina2xx_get_value(). + */ +static s16 ina226_alert_to_reg(struct ina2xx_data *data, u8 bit, int val) +{ + switch (bit) { + case INA226_SHUNT_OVER_VOLTAGE_BIT: + case INA226_SHUNT_UNDER_VOLTAGE_BIT: + val *= data->config->shunt_div; + return clamp_val(val, SHRT_MIN, SHRT_MAX); + case INA226_BUS_OVER_VOLTAGE_BIT: + case INA226_BUS_UNDER_VOLTAGE_BIT: + val = (val * 1000) << data->config->bus_voltage_shift; + val = DIV_ROUND_CLOSEST(val, data->config->bus_voltage_lsb); + return clamp_val(val, 0, SHRT_MAX); + case INA226_POWER_OVER_LIMIT_BIT: + val = DIV_ROUND_CLOSEST(val, data->power_lsb_uW); + return clamp_val(val, 0, USHRT_MAX); + default: + /* programmer goofed */ + WARN_ON_ONCE(1); + return 0; + } +} + +static ssize_t ina226_alert_show(struct device *dev, + struct device_attribute *da, char *buf) +{ + struct device *device = dev->parent->parent->parent; + struct sensor_device_attribute *attr = to_sensor_dev_attr(da); + struct ina2xx_data *data = dev_get_drvdata(dev); + int regval; + int val = 0; + int ret; + + mutex_lock(&data->config_lock); + spi_lock(); + ret = regmap_read(data->regmap, INA226_MASK_ENABLE, ®val); + if (ret) + goto abort; + + if (regval & BIT(attr->index)) { + ret = regmap_read(data->regmap, INA226_ALERT_LIMIT, ®val); + if (ret) + goto abort; + val = ina226_reg_to_alert(data, attr->index, regval); + } + + ret = sysfs_emit(buf, "%d\n", val); +abort: + spi_unlock(device); + mutex_unlock(&data->config_lock); + return ret; +} + +static ssize_t ina226_alert_store(struct device *dev, + struct device_attribute *da, + const char *buf, size_t count) +{ + struct device *device = dev->parent->parent->parent; + struct sensor_device_attribute *attr = to_sensor_dev_attr(da); + struct ina2xx_data *data = dev_get_drvdata(dev); + unsigned long val; + int ret; + + ret = kstrtoul(buf, 10, &val); + if (ret < 0) + return ret; + + /* + * Clear all alerts first to avoid accidentally triggering ALERT pin + * due to register write sequence. Then, only enable the alert + * if the value is non-zero. + */ + mutex_lock(&data->config_lock); + spi_lock(); + ret = regmap_update_bits(data->regmap, INA226_MASK_ENABLE, + INA226_ALERT_CONFIG_MASK, 0); + if (ret < 0) + goto abort; + + + ret = regmap_write(data->regmap, INA226_ALERT_LIMIT, + ina226_alert_to_reg(data, attr->index, val)); + + if (ret < 0) + goto abort; + + if (val != 0) { + ret = regmap_update_bits(data->regmap, INA226_MASK_ENABLE, + INA226_ALERT_CONFIG_MASK, + BIT(attr->index)); + if (ret < 0) + goto abort; + } + + ret = count; +abort: + spi_unlock(device); + mutex_unlock(&data->config_lock); + return ret; +} + +static ssize_t ina226_alarm_show(struct device *dev, + struct device_attribute *da, char *buf) +{ + struct device *device = dev->parent->parent->parent; + struct sensor_device_attribute *attr = to_sensor_dev_attr(da); + struct ina2xx_data *data = dev_get_drvdata(dev); + int regval; + int alarm = 0; + int ret; + + spi_lock(); + ret = regmap_read(data->regmap, INA226_MASK_ENABLE, ®val); + spi_unlock(device); + if (ret) + return ret; + + alarm = (regval & BIT(attr->index)) && + (regval & INA226_ALERT_FUNCTION_FLAG); + return sysfs_emit(buf, "%d\n", alarm); +} + +/* + * In order to keep calibration register value fixed, the product + * of current_lsb and shunt_resistor should also be fixed and equal + * to shunt_voltage_lsb = 1 / shunt_div multiplied by 10^9 in order + * to keep the scale. + */ +static int ina2xx_set_shunt(struct ina2xx_data *data, long val) +{ + unsigned int dividend = DIV_ROUND_CLOSEST(1000000000, + data->config->shunt_div); + if (val <= 0 || val > dividend) + return -EINVAL; + + mutex_lock(&data->config_lock); + data->rshunt = val; + data->current_lsb_uA = DIV_ROUND_CLOSEST(dividend, val); + data->power_lsb_uW = data->config->power_lsb_factor * + data->current_lsb_uA; + mutex_unlock(&data->config_lock); + + return 0; +} + +static ssize_t ina2xx_shunt_show(struct device *dev, + struct device_attribute *da, char *buf) +{ + struct ina2xx_data *data = dev_get_drvdata(dev); + + return sysfs_emit(buf, "%li\n", data->rshunt); +} + +static ssize_t ina2xx_shunt_store(struct device *dev, + struct device_attribute *da, + const char *buf, size_t count) +{ + unsigned long val; + int status; + struct ina2xx_data *data = dev_get_drvdata(dev); + + status = kstrtoul(buf, 10, &val); + if (status < 0) + return status; + + status = ina2xx_set_shunt(data, val); + if (status < 0) + return status; + return count; +} + +static ssize_t ina226_interval_store(struct device *dev, + struct device_attribute *da, + const char *buf, size_t count) +{ + struct device *device = dev->parent->parent->parent; + struct ina2xx_data *data = dev_get_drvdata(dev); + unsigned long val; + int status; + + status = kstrtoul(buf, 10, &val); + if (status < 0) + return status; + + if (val > INT_MAX || val == 0) + return -EINVAL; + + spi_lock(); + status = regmap_update_bits(data->regmap, INA2XX_CONFIG, + INA226_AVG_RD_MASK, + ina226_interval_to_reg(val)); + + spi_unlock(device); + if (status < 0) + return status; + + return count; +} + +static ssize_t ina226_interval_show(struct device *dev, + struct device_attribute *da, char *buf) +{ + struct device *device = dev->parent->parent->parent; + struct ina2xx_data *data = dev_get_drvdata(dev); + int status; + unsigned int regval; + + spi_lock(); + status = regmap_read(data->regmap, INA2XX_CONFIG, ®val); + spi_unlock(device); + if (status) + return status; + + return sysfs_emit(buf, "%d\n", ina226_reg_to_interval(regval)); +} + +/* shunt voltage */ +static SENSOR_DEVICE_ATTR_RO(in0_input, ina2xx_value, INA2XX_SHUNT_VOLTAGE); +/* shunt voltage over/under voltage alert setting and alarm */ +static SENSOR_DEVICE_ATTR_RW(in0_crit, ina226_alert, + INA226_SHUNT_OVER_VOLTAGE_BIT); +static SENSOR_DEVICE_ATTR_RW(in0_lcrit, ina226_alert, + INA226_SHUNT_UNDER_VOLTAGE_BIT); +static SENSOR_DEVICE_ATTR_RO(in0_crit_alarm, ina226_alarm, + INA226_SHUNT_OVER_VOLTAGE_BIT); +static SENSOR_DEVICE_ATTR_RO(in0_lcrit_alarm, ina226_alarm, + INA226_SHUNT_UNDER_VOLTAGE_BIT); + +/* bus voltage */ +static SENSOR_DEVICE_ATTR_RO(in1_input, ina2xx_value, INA2XX_BUS_VOLTAGE); +/* bus voltage over/under voltage alert setting and alarm */ +static SENSOR_DEVICE_ATTR_RW(in1_crit, ina226_alert, + INA226_BUS_OVER_VOLTAGE_BIT); +static SENSOR_DEVICE_ATTR_RW(in1_lcrit, ina226_alert, + INA226_BUS_UNDER_VOLTAGE_BIT); +static SENSOR_DEVICE_ATTR_RO(in1_crit_alarm, ina226_alarm, + INA226_BUS_OVER_VOLTAGE_BIT); +static SENSOR_DEVICE_ATTR_RO(in1_lcrit_alarm, ina226_alarm, + INA226_BUS_UNDER_VOLTAGE_BIT); + +/* calculated current */ +static SENSOR_DEVICE_ATTR_RO(curr1_input, ina2xx_value, INA2XX_CURRENT); + +/* calculated power */ +static SENSOR_DEVICE_ATTR_RO(power1_input, ina2xx_value, INA2XX_POWER); +/* over-limit power alert setting and alarm */ +static SENSOR_DEVICE_ATTR_RW(power1_crit, ina226_alert, + INA226_POWER_OVER_LIMIT_BIT); +static SENSOR_DEVICE_ATTR_RO(power1_crit_alarm, ina226_alarm, + INA226_POWER_OVER_LIMIT_BIT); + +/* shunt resistance */ +static SENSOR_DEVICE_ATTR_RW(shunt_resistor, ina2xx_shunt, INA2XX_CALIBRATION); + +/* update interval (ina226 only) */ +static SENSOR_DEVICE_ATTR_RW(update_interval, ina226_interval, 0); + +/* pointers to created device attributes */ +static struct attribute *ina2xx_attrs[] = { + &sensor_dev_attr_in0_input.dev_attr.attr, + &sensor_dev_attr_in1_input.dev_attr.attr, + &sensor_dev_attr_curr1_input.dev_attr.attr, + &sensor_dev_attr_power1_input.dev_attr.attr, + &sensor_dev_attr_shunt_resistor.dev_attr.attr, + NULL, +}; + +static const struct attribute_group ina2xx_group = { + .attrs = ina2xx_attrs, +}; + +static struct attribute *ina226_attrs[] = { + &sensor_dev_attr_in0_crit.dev_attr.attr, + &sensor_dev_attr_in0_lcrit.dev_attr.attr, + &sensor_dev_attr_in0_crit_alarm.dev_attr.attr, + &sensor_dev_attr_in0_lcrit_alarm.dev_attr.attr, + &sensor_dev_attr_in1_crit.dev_attr.attr, + &sensor_dev_attr_in1_lcrit.dev_attr.attr, + &sensor_dev_attr_in1_crit_alarm.dev_attr.attr, + &sensor_dev_attr_in1_lcrit_alarm.dev_attr.attr, + &sensor_dev_attr_power1_crit.dev_attr.attr, + &sensor_dev_attr_power1_crit_alarm.dev_attr.attr, + &sensor_dev_attr_update_interval.dev_attr.attr, + NULL, +}; + +static const struct attribute_group ina226_group = { + .attrs = ina226_attrs, +}; + +static const struct i2c_device_id ina2xx_id[]; + +static int ina2xx_probe(struct i2c_client *client) +{ + struct device *dev = &client->dev; + struct ina2xx_data *data; + struct device *hwmon_dev; + u32 val; + int ret, group = 0; + enum ina2xx_ids chip; + + if (client->dev.of_node) + chip = (enum ina2xx_ids)of_device_get_match_data(&client->dev); + else + chip = i2c_match_id(ina2xx_id, client)->driver_data; + + data = devm_kzalloc(dev, sizeof(*data), GFP_KERNEL); + if (!data) + return -ENOMEM; + + /* set the device type */ + data->config = &ina2xx_config[chip]; + mutex_init(&data->config_lock); + + if (of_property_read_u32(dev->of_node, "shunt-resistor", &val) < 0) { + struct ina2xx_platform_data *pdata = dev_get_platdata(dev); + + if (pdata) + val = pdata->shunt_uohms; + else + val = INA2XX_RSHUNT_DEFAULT; + } + + pm_runtime_set_autosuspend_delay(dev->parent->parent, 0); + ina2xx_set_shunt(data, val); + + ina2xx_regmap_config.max_register = data->config->registers; + + data->regmap = devm_regmap_init_i2c(client, &ina2xx_regmap_config); + if (IS_ERR(data->regmap)) { + dev_err(dev, "failed to allocate register map\n"); + return PTR_ERR(data->regmap); + } + + ret = ina2xx_init(data); + if (ret < 0) { + dev_err(dev, "error configuring the device: %d\n", ret); + return -ENODEV; + } + + data->groups[group++] = &ina2xx_group; + if (chip == ina226) + data->groups[group++] = &ina226_group; + + hwmon_dev = devm_hwmon_device_register_with_groups(dev, client->name, + data, data->groups); + if (IS_ERR(hwmon_dev)) + return PTR_ERR(hwmon_dev); + + dev_info(dev, "power monitor %s (Rshunt = %li uOhm)\n", + client->name, data->rshunt); + + return 0; +} + +static const struct i2c_device_id ina2xx_id[] = { + { "ina219-datum", ina219 }, + { "ina220-datum", ina219 }, + { "ina226-datum", ina226 }, + { "ina230-datum", ina226 }, + { "ina231-datum", ina226 }, + { } +}; +MODULE_DEVICE_TABLE(i2c, ina2xx_id); + +static const struct of_device_id __maybe_unused ina2xx_of_match[] = { + { + .compatible = "ti,ina219-datum", + .data = (void *)ina219 + }, + { + .compatible = "ti,ina220-datum", + .data = (void *)ina219 + }, + { + .compatible = "ti,ina226-datum", + .data = (void *)ina226 + }, + { + .compatible = "ti,ina230-datum", + .data = (void *)ina226 + }, + { + .compatible = "ti,ina231-datum", + .data = (void *)ina226 + }, + { }, +}; +MODULE_DEVICE_TABLE(of, ina2xx_of_match); + +static struct i2c_driver ina2xx_driver = { + .driver = { + .name = "ina2xx-datum", + .of_match_table = of_match_ptr(ina2xx_of_match), + }, + .probe_new = ina2xx_probe, + .id_table = ina2xx_id, +}; + +module_i2c_driver(ina2xx_driver); + +MODULE_AUTHOR("Lothar Felten "); +MODULE_DESCRIPTION("ina2xx driver"); +MODULE_LICENSE("GPL"); diff --git a/drivers/hwmon/mcp9902.c b/drivers/hwmon/mcp9902.c index 55e1c5ac5d85e3..e1270f4a29386d 100644 --- a/drivers/hwmon/mcp9902.c +++ b/drivers/hwmon/mcp9902.c @@ -10,7 +10,6 @@ * http://ww1.microchip.com/downloads/en/DeviceDoc/20005382C.pdf */ -#include #include #include #include @@ -20,7 +19,6 @@ #include #include #include -#include #include static const unsigned short normal_i2c[] = { @@ -57,21 +55,6 @@ static const unsigned short normal_i2c[] = { #define MCP9902_REG_R_TCRIT_HYST 0x21 #define MCP9902_REG_W_TCRIT_HYST 0x21 -/* - * I2C3-SPI2 Clocks Shorted Mutex - */ - -extern struct mutex datum_b53_spi_mutex; - -static inline void spi_lock(void) { mutex_lock(&datum_b53_spi_mutex); } - -static inline void spi_unlock(struct device *dev) -{ - if(!pm_runtime_suspended(dev)) - usleep_range(100, 200); - mutex_unlock(&datum_b53_spi_mutex); -} - /* * Conversions */ @@ -145,34 +128,22 @@ static struct mcp9902_data *mcp9902_update_device(struct device *dev) { struct mcp9902_data *data = dev_get_drvdata(dev); struct i2c_client *client = data->client; - struct i2c_adapter *adapter = client->adapter; int i; - int j; mutex_lock(&data->update_lock); -// spi_lock(); - // if (time_after(jiffies, data->last_updated + HZ * 2) || !data->valid) { - if (time_after(jiffies, data->last_updated + 1) || !data->valid) { + if (time_after(jiffies, data->last_updated + HZ * 2) || !data->valid) { dev_dbg(&client->dev, "Updating mcp9902 data.\n"); - // printk("Updating mcp9902 data.\n"); - - for (j = 0; j < 20; j++) - { - spi_lock(); - for (i = 0; i < t_num_regs; i++) - data->temp[i] = i2c_smbus_read_byte_data(client, - regs_read[i]); - data->alarms = i2c_smbus_read_byte_data(client, - MCP9902_REG_R_STATUS); - spi_unlock(adapter->dev.parent); - } + for (i = 0; i < t_num_regs; i++) + data->temp[i] = i2c_smbus_read_byte_data(client, + regs_read[i]); + data->alarms = i2c_smbus_read_byte_data(client, + MCP9902_REG_R_STATUS); data->last_updated = jiffies; data->valid = 1; } -// spi_unlock(adapter->dev.parent); mutex_unlock(&data->update_lock); return data; @@ -188,7 +159,7 @@ static ssize_t temp_show(struct device *dev, struct device_attribute *devattr, struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); struct mcp9902_data *data = mcp9902_update_device(dev); u8 fraction_reg; - + switch(attr->index) { case t_input1: @@ -211,7 +182,6 @@ static ssize_t temp_store(struct device *dev, struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); struct mcp9902_data *data = dev_get_drvdata(dev); struct i2c_client *client = data->client; - struct i2c_adapter *adapter = client->adapter; long val; int err = kstrtol(buf, 10, &val); if (err) @@ -219,10 +189,8 @@ static ssize_t temp_store(struct device *dev, mutex_lock(&data->update_lock); data->temp[attr->index] = temp_to_reg(val); - spi_lock(); i2c_smbus_write_byte_data(client, regs_write[attr->index], data->temp[attr->index]); - spi_unlock(adapter->dev.parent); mutex_unlock(&data->update_lock); return count; } @@ -295,10 +263,8 @@ static int mcp9902_detect(struct i2c_client *client, return -ENODEV; /* identification */ - spi_lock(); man_id = i2c_smbus_read_byte_data(client, MCP9902_REG_R_MAN_ID); chip_id = i2c_smbus_read_byte_data(client, MCP9902_REG_R_CHIP_ID); - spi_unlock(adapter->dev.parent); if (man_id != 0x5D || chip_id != 0x04) { dev_info(&adapter->dev, "Unsupported chip (man_id=0x%02X, chip_id=0x%02X).\n", @@ -313,17 +279,12 @@ static int mcp9902_detect(struct i2c_client *client, static void mcp9902_init_client(struct i2c_client *client) { - struct i2c_adapter *adapter = client->adapter; - - pm_runtime_set_autosuspend_delay(adapter->dev.parent, 0); /* * Start the conversions. */ - spi_lock(); i2c_smbus_write_byte_data(client, MCP9902_REG_W_CONVRATE, 5); /* 2 Hz */ i2c_smbus_write_byte_data(client, MCP9902_REG_W_CONFIG, 0x9F); /* run - extended temp */ - spi_unlock(adapter->dev.parent); } static int mcp9902_probe(struct i2c_client *new_client, diff --git a/drivers/hwmon/mcp9902_datum.c b/drivers/hwmon/mcp9902_datum.c new file mode 100644 index 00000000000000..ae284b9859635b --- /dev/null +++ b/drivers/hwmon/mcp9902_datum.c @@ -0,0 +1,384 @@ +// SPDX-License-Identifier: GPL-2.0-or-later +/* + * mcp9902.c - Part of lm_sensors, Linux kernel modules for hardware + * monitoring + * + * Based on the lm90 driver. The MCP9902 is a sensor chip made by Microchip. + * It reports up to two temperatures (its own plus up to + * one external one). Complete datasheet can be + * obtained from Microchips's website at: + * http://ww1.microchip.com/downloads/en/DeviceDoc/20005382C.pdf + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +static const unsigned short normal_i2c[] = { + 0x1C, 0x4C, I2C_CLIENT_END }; + +/* + * The MCP9902 registers + */ + +#define MCP9902_REG_R_CHIP_ID 0xFD +#define MCP9902_REG_R_MAN_ID 0xFE +#define MCP9902_REG_R_REV_ID 0xFF +#define MCP9902_REG_R_CONFIG 0x03 +#define MCP9902_REG_W_CONFIG 0x09 +#define MCP9902_REG_R_CONVRATE 0x04 +#define MCP9902_REG_W_CONVRATE 0x0A +#define MCP9902_REG_R_STATUS 0x02 +#define MCP9902_REG_R_LOCAL_TEMP 0x00 +#define MCP9902_REG_R_LOCAL_TEMP_FRACTION 0x29 +#define MCP9902_REG_R_REMOTE_TEMP 0x01 +#define MCP9902_REG_R_REMOTE_TEMP_FRACTION 0x10 +#define MCP9902_REG_R_LOCAL_HIGH 0x05 +#define MCP9902_REG_W_LOCAL_HIGH 0x0B +#define MCP9902_REG_R_LOCAL_LOW 0x06 +#define MCP9902_REG_W_LOCAL_LOW 0x0C +#define MCP9902_REG_R_REMOTE_HIGH 0x07 +#define MCP9902_REG_W_REMOTE_HIGH 0x0D +#define MCP9902_REG_R_REMOTE_LOW 0x08 +#define MCP9902_REG_W_REMOTE_LOW 0x0E +#define MCP9902_REG_R_REMOTE_CRIT 0x19 +#define MCP9902_REG_W_REMOTE_CRIT 0x19 +#define MCP9902_REG_R_LOCAL_CRIT 0x20 +#define MCP9902_REG_W_LOCAL_CRIT 0x20 +#define MCP9902_REG_R_TCRIT_HYST 0x21 +#define MCP9902_REG_W_TCRIT_HYST 0x21 + +/* + * I2C3-SPI2 Clocks Shorted Mutex + */ + +extern struct mutex datum_b53_spi_mutex; + +static inline void spi_lock(void) { mutex_lock(&datum_b53_spi_mutex); } + +static inline void spi_unlock(struct device *dev) +{ + if(!pm_runtime_suspended(dev)) + usleep_range(100, 200); + mutex_unlock(&datum_b53_spi_mutex); +} + +/* + * Conversions + */ + +static int temp_from_reg(int val, int fraction) +{ + /* milli-degree C */ + return (((val - 64) * 1000) + (((fraction & 0xE0) >> 5) * 125)); +} + +static int temp_to_reg(int val) +{ + return (val + 64) / 1000; +} + +enum temp_index { + t_input1 = 0, + t_input1_fraction, + t_input2, + t_input2_fraction, + t_low1, + t_high1, + t_crit1, + t_low2, + t_high2, + t_crit2, + t_hyst, + t_num_regs +}; + +/* + * Client data (each client gets its own) + */ + +struct mcp9902_data { + struct i2c_client *client; + struct mutex update_lock; + char valid; /* zero until following fields are valid */ + unsigned long last_updated; /* in jiffies */ + + /* registers values */ + u8 temp[t_num_regs]; /* index with enum temp_index */ + u8 alarms; +}; + +static const u8 regs_read[t_num_regs] = { + [t_input1] = MCP9902_REG_R_LOCAL_TEMP, + [t_input1_fraction] = MCP9902_REG_R_LOCAL_TEMP_FRACTION, + [t_input2] = MCP9902_REG_R_REMOTE_TEMP, + [t_input2_fraction] = MCP9902_REG_R_REMOTE_TEMP_FRACTION, + [t_low1] = MCP9902_REG_R_LOCAL_LOW, + [t_high1] = MCP9902_REG_R_LOCAL_HIGH, + [t_crit1] = MCP9902_REG_R_LOCAL_CRIT, + [t_low2] = MCP9902_REG_R_REMOTE_LOW, + [t_high2] = MCP9902_REG_R_REMOTE_HIGH, + [t_crit2] = MCP9902_REG_R_REMOTE_CRIT, + [t_hyst] = MCP9902_REG_R_TCRIT_HYST, +}; + +static const u8 regs_write[t_num_regs] = { + [t_low1] = MCP9902_REG_W_LOCAL_LOW, + [t_high1] = MCP9902_REG_W_LOCAL_HIGH, + [t_crit1] = MCP9902_REG_W_LOCAL_CRIT, + [t_low2] = MCP9902_REG_W_REMOTE_LOW, + [t_high2] = MCP9902_REG_W_REMOTE_HIGH, + [t_crit2] = MCP9902_REG_W_REMOTE_CRIT, + [t_hyst] = MCP9902_REG_W_TCRIT_HYST, +}; + +static struct mcp9902_data *mcp9902_update_device(struct device *dev) +{ + struct mcp9902_data *data = dev_get_drvdata(dev); + struct i2c_client *client = data->client; + struct i2c_adapter *adapter = client->adapter; + int i; + int j; + + mutex_lock(&data->update_lock); +// spi_lock(); + + // if (time_after(jiffies, data->last_updated + HZ * 2) || !data->valid) { + if (time_after(jiffies, data->last_updated + 1) || !data->valid) { + dev_dbg(&client->dev, "Updating mcp9902 data.\n"); + // printk("Updating mcp9902 data.\n"); + + for (j = 0; j < 20; j++) + { + spi_lock(); + for (i = 0; i < t_num_regs; i++) + data->temp[i] = i2c_smbus_read_byte_data(client, + regs_read[i]); + data->alarms = i2c_smbus_read_byte_data(client, + MCP9902_REG_R_STATUS); + spi_unlock(adapter->dev.parent); + } + + data->last_updated = jiffies; + data->valid = 1; + } + +// spi_unlock(adapter->dev.parent); + mutex_unlock(&data->update_lock); + + return data; +} + +/* + * Sysfs stuff + */ + +static ssize_t temp_show(struct device *dev, struct device_attribute *devattr, + char *buf) +{ + struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); + struct mcp9902_data *data = mcp9902_update_device(dev); + u8 fraction_reg; + + switch(attr->index) + { + case t_input1: + fraction_reg = data->temp[t_input1_fraction]; + break; + case t_input2: + fraction_reg = data->temp[t_input2_fraction]; + break; + default: + fraction_reg = 0; + break; + } + return sprintf(buf, "%d\n", temp_from_reg(data->temp[attr->index], fraction_reg)); +} + +static ssize_t temp_store(struct device *dev, + struct device_attribute *devattr, const char *buf, + size_t count) +{ + struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); + struct mcp9902_data *data = dev_get_drvdata(dev); + struct i2c_client *client = data->client; + struct i2c_adapter *adapter = client->adapter; + long val; + int err = kstrtol(buf, 10, &val); + if (err) + return err; + + mutex_lock(&data->update_lock); + data->temp[attr->index] = temp_to_reg(val); + spi_lock(); + i2c_smbus_write_byte_data(client, regs_write[attr->index], + data->temp[attr->index]); + spi_unlock(adapter->dev.parent); + mutex_unlock(&data->update_lock); + return count; +} + +static ssize_t alarms_show(struct device *dev, struct device_attribute *attr, + char *buf) +{ + struct mcp9902_data *data = mcp9902_update_device(dev); + return sprintf(buf, "%d\n", data->alarms); +} + +static ssize_t alarm_show(struct device *dev, struct device_attribute *attr, + char *buf) +{ + int bitnr = to_sensor_dev_attr(attr)->index; + struct mcp9902_data *data = mcp9902_update_device(dev); + return sprintf(buf, "%d\n", (data->alarms >> bitnr) & 1); +} + +static SENSOR_DEVICE_ATTR_RO(temp1_input, temp, t_input1); +static SENSOR_DEVICE_ATTR_RW(temp1_min, temp, t_low1); +static SENSOR_DEVICE_ATTR_RW(temp1_max, temp, t_high1); +static SENSOR_DEVICE_ATTR_RW(temp1_crit, temp, t_crit1); +static SENSOR_DEVICE_ATTR_RO(temp2_input, temp, t_input2); +static SENSOR_DEVICE_ATTR_RW(temp2_min, temp, t_low2); +static SENSOR_DEVICE_ATTR_RW(temp2_max, temp, t_high2); +static SENSOR_DEVICE_ATTR_RW(temp2_crit, temp, t_crit2); +static SENSOR_DEVICE_ATTR_RW(temp_crit_hyst, temp, t_hyst); + +static DEVICE_ATTR_RO(alarms); +static SENSOR_DEVICE_ATTR_RO(temp1_crit_alarm, alarm, 0); +static SENSOR_DEVICE_ATTR_RO(temp2_crit_alarm, alarm, 1); +static SENSOR_DEVICE_ATTR_RO(temp2_fault, alarm, 2); +static SENSOR_DEVICE_ATTR_RO(temp2_min_alarm, alarm, 3); +static SENSOR_DEVICE_ATTR_RO(temp2_max_alarm, alarm, 4); +static SENSOR_DEVICE_ATTR_RO(temp1_min_alarm, alarm, 5); +static SENSOR_DEVICE_ATTR_RO(temp1_max_alarm, alarm, 6); + +static struct attribute *mcp9902_attrs[] = { + &sensor_dev_attr_temp1_input.dev_attr.attr, + &sensor_dev_attr_temp2_input.dev_attr.attr, + &sensor_dev_attr_temp1_min.dev_attr.attr, + &sensor_dev_attr_temp1_max.dev_attr.attr, + &sensor_dev_attr_temp1_crit.dev_attr.attr, + &sensor_dev_attr_temp2_min.dev_attr.attr, + &sensor_dev_attr_temp2_max.dev_attr.attr, + &sensor_dev_attr_temp2_crit.dev_attr.attr, + &sensor_dev_attr_temp_crit_hyst.dev_attr.attr, + + &dev_attr_alarms.attr, + &sensor_dev_attr_temp1_crit_alarm.dev_attr.attr, + &sensor_dev_attr_temp2_crit_alarm.dev_attr.attr, + &sensor_dev_attr_temp2_fault.dev_attr.attr, + &sensor_dev_attr_temp2_min_alarm.dev_attr.attr, + &sensor_dev_attr_temp2_max_alarm.dev_attr.attr, + &sensor_dev_attr_temp1_min_alarm.dev_attr.attr, + &sensor_dev_attr_temp1_max_alarm.dev_attr.attr, + NULL +}; +ATTRIBUTE_GROUPS(mcp9902); + +/* Return 0 if detection is successful, -ENODEV otherwise */ +static int mcp9902_detect(struct i2c_client *client, + struct i2c_board_info *info) +{ + struct i2c_adapter *adapter = client->adapter; + u8 man_id, chip_id; + + if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA)) + return -ENODEV; + + /* identification */ + spi_lock(); + man_id = i2c_smbus_read_byte_data(client, MCP9902_REG_R_MAN_ID); + chip_id = i2c_smbus_read_byte_data(client, MCP9902_REG_R_CHIP_ID); + spi_unlock(adapter->dev.parent); + if (man_id != 0x5D || chip_id != 0x04) { + dev_info(&adapter->dev, + "Unsupported chip (man_id=0x%02X, chip_id=0x%02X).\n", + man_id, chip_id); + return -ENODEV; + } + + strlcpy(info->type, "mcp9902", I2C_NAME_SIZE); + + return 0; +} + +static void mcp9902_init_client(struct i2c_client *client) +{ + struct i2c_adapter *adapter = client->adapter; + + pm_runtime_set_autosuspend_delay(adapter->dev.parent, 0); + + /* + * Start the conversions. + */ + spi_lock(); + i2c_smbus_write_byte_data(client, MCP9902_REG_W_CONVRATE, 5); /* 2 Hz */ + i2c_smbus_write_byte_data(client, MCP9902_REG_W_CONFIG, 0x9F); /* run - extended temp */ + spi_unlock(adapter->dev.parent); +} + +static int mcp9902_probe(struct i2c_client *new_client, + const struct i2c_device_id *id) +{ + struct mcp9902_data *data; + struct device *hwmon_dev; + + data = devm_kzalloc(&new_client->dev, sizeof(struct mcp9902_data), + GFP_KERNEL); + if (!data) + return -ENOMEM; + + data->client = new_client; + mutex_init(&data->update_lock); + + /* Initialize the MCP9902 chip */ + mcp9902_init_client(new_client); + + hwmon_dev = devm_hwmon_device_register_with_groups(&new_client->dev, + new_client->name, + data, + mcp9902_groups); + return PTR_ERR_OR_ZERO(hwmon_dev); +} + +static const struct i2c_device_id mcp9902_id[] = { + { "mcp9902-datum", 0 }, + { } +}; +MODULE_DEVICE_TABLE(i2c, mcp9902_id); + +#ifdef CONFIG_OF +static const struct of_device_id mcp9902_of_match[] = { + { .compatible = "microchip,mcp9902-datum", }, + {}, +}; + +MODULE_DEVICE_TABLE(of, mcp9902_of_match); +#endif + +static struct i2c_driver mcp9902_driver = { + .class = I2C_CLASS_HWMON, + .driver = { + .name = "mcp9902-datum", + .of_match_table = of_match_ptr(mcp9902_of_match), + }, + .probe = mcp9902_probe, + .id_table = mcp9902_id, + .detect = mcp9902_detect, + .address_list = normal_i2c, +}; + +module_i2c_driver(mcp9902_driver); + +MODULE_AUTHOR("Mark Carlin "); +MODULE_DESCRIPTION("MCP9902 temperature sensor driver"); +MODULE_LICENSE("GPL"); diff --git a/drivers/net/dsa/b53/Kconfig b/drivers/net/dsa/b53/Kconfig index 90b525160b7112..47c5ea7ffaf7dc 100644 --- a/drivers/net/dsa/b53/Kconfig +++ b/drivers/net/dsa/b53/Kconfig @@ -16,6 +16,14 @@ config B53_SPI_DRIVER help Select to enable support for registering switches configured through SPI. +config B53_SPI_DATUM_DRIVER + tristate "B53 SPI connected switch driver with Datum SPI/I2C clocks shorted" + depends on B53 && SPI + help + Select to enable support for registering switches configured through SPI. + This driver is for use with the Datum Systems Inc. SPI/I2C shorted bus + management system that fixes the I2C and SPI bus clocks shorted together. + config B53_MDIO_DRIVER tristate "B53 MDIO connected switch driver" depends on B53 diff --git a/drivers/net/dsa/b53/Makefile b/drivers/net/dsa/b53/Makefile index b1be13023ae4c7..9d7d09343209c5 100644 --- a/drivers/net/dsa/b53/Makefile +++ b/drivers/net/dsa/b53/Makefile @@ -2,6 +2,7 @@ obj-$(CONFIG_B53) += b53_common.o obj-$(CONFIG_B53_SPI_DRIVER) += b53_spi.o +obj-$(CONFIG_B53_SPI_DATUM_DRIVER) += b53_spi_datum.o obj-$(CONFIG_B53_MDIO_DRIVER) += b53_mdio.o obj-$(CONFIG_B53_MMAP_DRIVER) += b53_mmap.o obj-$(CONFIG_B53_SRAB_DRIVER) += b53_srab.o diff --git a/drivers/net/dsa/b53/b53_spi.c b/drivers/net/dsa/b53/b53_spi.c index 88bc76d201cfd2..abfeea5d47e966 100644 --- a/drivers/net/dsa/b53/b53_spi.c +++ b/drivers/net/dsa/b53/b53_spi.c @@ -23,8 +23,6 @@ #include #include #include -#include -#include #include #include @@ -43,30 +41,15 @@ #define B53_SPI_PAGE_SELECT 0xff -DEFINE_MUTEX(datum_b53_spi_mutex); -EXPORT_SYMBOL(datum_b53_spi_mutex); - -static inline void spi_lock(void) { mutex_lock(&datum_b53_spi_mutex); } - -static inline void spi_unlock(struct device *dev) -{ - if(!pm_runtime_suspended(dev)) - usleep_range(100, 200); - mutex_unlock(&datum_b53_spi_mutex); -} - static inline int b53_spi_read_reg(struct spi_device *spi, u8 reg, u8 *val, unsigned int len) { u8 txbuf[2]; - int retval; txbuf[0] = B53_SPI_CMD_NORMAL | B53_SPI_CMD_READ; txbuf[1] = reg; - retval = spi_write_then_read(spi, txbuf, 2, val, len); - - return retval; + return spi_write_then_read(spi, txbuf, 2, val, len); } static inline int b53_spi_clear_status(struct spi_device *spi) @@ -95,15 +78,12 @@ static inline int b53_spi_clear_status(struct spi_device *spi) static inline int b53_spi_set_page(struct spi_device *spi, u8 page) { u8 txbuf[3]; - int retval; txbuf[0] = B53_SPI_CMD_NORMAL | B53_SPI_CMD_WRITE; txbuf[1] = B53_SPI_PAGE_SELECT; txbuf[2] = page; - retval = spi_write(spi, txbuf, sizeof(txbuf)); - - return retval; + return spi_write(spi, txbuf, sizeof(txbuf)); } static inline int b53_prepare_reg_access(struct spi_device *spi, u8 page) @@ -149,7 +129,6 @@ static int b53_spi_read(struct b53_device *dev, u8 page, u8 reg, u8 *data, struct spi_device *spi = dev->priv; int ret; - spi_lock(); ret = b53_prepare_reg_access(spi, page); if (ret) return ret; @@ -158,10 +137,7 @@ static int b53_spi_read(struct b53_device *dev, u8 page, u8 reg, u8 *data, if (ret) return ret; - ret = b53_spi_read_reg(spi, B53_SPI_DATA, data, len); - spi_unlock(spi->dev.parent->parent); - - return ret; + return b53_spi_read_reg(spi, B53_SPI_DATA, data, len); } static int b53_spi_read8(struct b53_device *dev, u8 page, u8 reg, u8 *val) @@ -224,12 +200,9 @@ static int b53_spi_read64(struct b53_device *dev, u8 page, u8 reg, u64 *val) static int b53_spi_write8(struct b53_device *dev, u8 page, u8 reg, u8 value) { struct spi_device *spi = dev->priv; - struct device *device = spi->dev.parent->parent; int ret; u8 txbuf[3]; - int retval; - spi_lock(); ret = b53_prepare_reg_access(spi, page); if (ret) return ret; @@ -238,21 +211,15 @@ static int b53_spi_write8(struct b53_device *dev, u8 page, u8 reg, u8 value) txbuf[1] = reg; txbuf[2] = value; - retval = spi_write(spi, txbuf, sizeof(txbuf)); - spi_unlock(device); - - return retval; + return spi_write(spi, txbuf, sizeof(txbuf)); } static int b53_spi_write16(struct b53_device *dev, u8 page, u8 reg, u16 value) { struct spi_device *spi = dev->priv; - struct device *device = spi->dev.parent->parent; int ret; u8 txbuf[4]; - int retval; - spi_lock(); ret = b53_prepare_reg_access(spi, page); if (ret) return ret; @@ -261,21 +228,15 @@ static int b53_spi_write16(struct b53_device *dev, u8 page, u8 reg, u16 value) txbuf[1] = reg; put_unaligned_le16(value, &txbuf[2]); - retval = spi_write(spi, txbuf, sizeof(txbuf)); - spi_unlock(device); - - return retval; + return spi_write(spi, txbuf, sizeof(txbuf)); } static int b53_spi_write32(struct b53_device *dev, u8 page, u8 reg, u32 value) { struct spi_device *spi = dev->priv; - struct device *device = spi->dev.parent->parent; int ret; u8 txbuf[6]; - int retval; - spi_lock(); ret = b53_prepare_reg_access(spi, page); if (ret) return ret; @@ -284,21 +245,15 @@ static int b53_spi_write32(struct b53_device *dev, u8 page, u8 reg, u32 value) txbuf[1] = reg; put_unaligned_le32(value, &txbuf[2]); - retval = spi_write(spi, txbuf, sizeof(txbuf)); - spi_unlock(device); - - return retval; + return spi_write(spi, txbuf, sizeof(txbuf)); } static int b53_spi_write48(struct b53_device *dev, u8 page, u8 reg, u64 value) { struct spi_device *spi = dev->priv; - struct device *device = spi->dev.parent->parent; int ret; u8 txbuf[10]; - int retval; - spi_lock(); ret = b53_prepare_reg_access(spi, page); if (ret) return ret; @@ -307,21 +262,15 @@ static int b53_spi_write48(struct b53_device *dev, u8 page, u8 reg, u64 value) txbuf[1] = reg; put_unaligned_le64(value, &txbuf[2]); - retval = spi_write(spi, txbuf, sizeof(txbuf) - 2); - spi_unlock(device); - - return retval; + return spi_write(spi, txbuf, sizeof(txbuf) - 2); } static int b53_spi_write64(struct b53_device *dev, u8 page, u8 reg, u64 value) { struct spi_device *spi = dev->priv; - struct device *device = spi->dev.parent->parent; int ret; u8 txbuf[10]; - int retval; - spi_lock(); ret = b53_prepare_reg_access(spi, page); if (ret) return ret; @@ -330,10 +279,7 @@ static int b53_spi_write64(struct b53_device *dev, u8 page, u8 reg, u64 value) txbuf[1] = reg; put_unaligned_le64(value, &txbuf[2]); - retval = spi_write(spi, txbuf, sizeof(txbuf)); - spi_unlock(device); - - return retval; + return spi_write(spi, txbuf, sizeof(txbuf)); } static const struct b53_io_ops b53_spi_ops = { @@ -351,7 +297,6 @@ static const struct b53_io_ops b53_spi_ops = { static int b53_spi_probe(struct spi_device *spi) { - struct device *device = spi->dev.parent->parent; struct b53_device *dev; int ret; struct net_device *ndev = dev_get_by_name(&init_net, "eth0"); @@ -366,8 +311,6 @@ static int b53_spi_probe(struct spi_device *spi) if (spi->dev.platform_data) dev->pdata = spi->dev.platform_data; - pm_runtime_set_autosuspend_delay(device, 0); - ret = b53_switch_register(dev); if (ret) return ret; diff --git a/drivers/net/dsa/b53/b53_spi_datum.c b/drivers/net/dsa/b53/b53_spi_datum.c new file mode 100644 index 00000000000000..1141b70c8b6048 --- /dev/null +++ b/drivers/net/dsa/b53/b53_spi_datum.c @@ -0,0 +1,423 @@ +/* + * B53 register access through SPI + * + * Copyright (C) 2011-2013 Jonas Gorski + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#include + +#include + +#include +#include +#include +#include +#include +#include +#include + +#include "b53_priv.h" + +#define B53_SPI_DATA 0xf0 + +#define B53_SPI_STATUS 0xfe +#define B53_SPI_CMD_SPIF BIT(7) +#define B53_SPI_CMD_RACK BIT(5) + +#define B53_SPI_CMD_READ 0x00 +#define B53_SPI_CMD_WRITE 0x01 +#define B53_SPI_CMD_NORMAL 0x60 +#define B53_SPI_CMD_FAST 0x10 + +#define B53_SPI_PAGE_SELECT 0xff + +DEFINE_MUTEX(datum_b53_spi_mutex); +EXPORT_SYMBOL(datum_b53_spi_mutex); + +static inline void spi_lock(void) { mutex_lock(&datum_b53_spi_mutex); } + +static inline void spi_unlock(struct device *dev) +{ + if(!pm_runtime_suspended(dev)) + usleep_range(100, 200); + mutex_unlock(&datum_b53_spi_mutex); +} + +static inline int b53_spi_read_reg(struct spi_device *spi, u8 reg, u8 *val, + unsigned int len) +{ + u8 txbuf[2]; + + txbuf[0] = B53_SPI_CMD_NORMAL | B53_SPI_CMD_READ; + txbuf[1] = reg; + + return spi_write_then_read(spi, txbuf, 2, val, len); +} + +static inline int b53_spi_clear_status(struct spi_device *spi) +{ + unsigned int i; + u8 rxbuf; + int ret; + + for (i = 0; i < 10; i++) { + ret = b53_spi_read_reg(spi, B53_SPI_STATUS, &rxbuf, 1); + if (ret) + return ret; + + if (!(rxbuf & B53_SPI_CMD_SPIF)) + break; + + mdelay(1); + } + + if (i == 10) + return -EIO; + + return 0; +} + +static inline int b53_spi_set_page(struct spi_device *spi, u8 page) +{ + u8 txbuf[3]; + + txbuf[0] = B53_SPI_CMD_NORMAL | B53_SPI_CMD_WRITE; + txbuf[1] = B53_SPI_PAGE_SELECT; + txbuf[2] = page; + + return spi_write(spi, txbuf, sizeof(txbuf)); +} + +static inline int b53_prepare_reg_access(struct spi_device *spi, u8 page) +{ + int ret = b53_spi_clear_status(spi); + + if (ret) + return ret; + + return b53_spi_set_page(spi, page); +} + +static int b53_spi_prepare_reg_read(struct spi_device *spi, u8 reg) +{ + u8 rxbuf; + int retry_count; + int ret; + + ret = b53_spi_read_reg(spi, reg, &rxbuf, 1); + if (ret) + return ret; + + for (retry_count = 0; retry_count < 10; retry_count++) { + ret = b53_spi_read_reg(spi, B53_SPI_STATUS, &rxbuf, 1); + if (ret) + return ret; + + if (rxbuf & B53_SPI_CMD_RACK) + break; + + mdelay(1); + } + + if (retry_count == 10) + return -EIO; + + return 0; +} + +static int b53_spi_read(struct b53_device *dev, u8 page, u8 reg, u8 *data, + unsigned int len) +{ + struct spi_device *spi = dev->priv; + int ret; + + spi_lock(); + ret = b53_prepare_reg_access(spi, page); + if (ret) + return ret; + + ret = b53_spi_prepare_reg_read(spi, reg); + if (ret) + return ret; + + ret = b53_spi_read_reg(spi, B53_SPI_DATA, data, len); + spi_unlock(spi->dev.parent->parent); + + return ret; +} + +static int b53_spi_read8(struct b53_device *dev, u8 page, u8 reg, u8 *val) +{ + return b53_spi_read(dev, page, reg, val, 1); +} + +static int b53_spi_read16(struct b53_device *dev, u8 page, u8 reg, u16 *val) +{ + __le16 value; + int ret; + + ret = b53_spi_read(dev, page, reg, (u8 *)&value, 2); + + if (!ret) + *val = le16_to_cpu(value); + + return ret; +} + +static int b53_spi_read32(struct b53_device *dev, u8 page, u8 reg, u32 *val) +{ + __le32 value; + int ret; + + ret = b53_spi_read(dev, page, reg, (u8 *)&value, 4); + + if (!ret) + *val = le32_to_cpu(value); + + return ret; +} + +static int b53_spi_read48(struct b53_device *dev, u8 page, u8 reg, u64 *val) +{ + __le64 value; + int ret; + + *val = 0; + ret = b53_spi_read(dev, page, reg, (u8 *)&value, 6); + if (!ret) + *val = le64_to_cpu(value); + + return ret; +} + +static int b53_spi_read64(struct b53_device *dev, u8 page, u8 reg, u64 *val) +{ + __le64 value; + int ret; + + ret = b53_spi_read(dev, page, reg, (u8 *)&value, 8); + + if (!ret) + *val = le64_to_cpu(value); + + return ret; +} + +static int b53_spi_write8(struct b53_device *dev, u8 page, u8 reg, u8 value) +{ + struct spi_device *spi = dev->priv; + struct device *device = spi->dev.parent->parent; + int ret; + u8 txbuf[3]; + int retval; + + spi_lock(); + ret = b53_prepare_reg_access(spi, page); + if (ret) + return ret; + + txbuf[0] = B53_SPI_CMD_NORMAL | B53_SPI_CMD_WRITE; + txbuf[1] = reg; + txbuf[2] = value; + + retval = spi_write(spi, txbuf, sizeof(txbuf)); + spi_unlock(device); + + return retval; +} + +static int b53_spi_write16(struct b53_device *dev, u8 page, u8 reg, u16 value) +{ + struct spi_device *spi = dev->priv; + struct device *device = spi->dev.parent->parent; + int ret; + u8 txbuf[4]; + int retval; + + spi_lock(); + ret = b53_prepare_reg_access(spi, page); + if (ret) + return ret; + + txbuf[0] = B53_SPI_CMD_NORMAL | B53_SPI_CMD_WRITE; + txbuf[1] = reg; + put_unaligned_le16(value, &txbuf[2]); + + retval = spi_write(spi, txbuf, sizeof(txbuf)); + spi_unlock(device); + + return retval; +} + +static int b53_spi_write32(struct b53_device *dev, u8 page, u8 reg, u32 value) +{ + struct spi_device *spi = dev->priv; + struct device *device = spi->dev.parent->parent; + int ret; + u8 txbuf[6]; + int retval; + + spi_lock(); + ret = b53_prepare_reg_access(spi, page); + if (ret) + return ret; + + txbuf[0] = B53_SPI_CMD_NORMAL | B53_SPI_CMD_WRITE; + txbuf[1] = reg; + put_unaligned_le32(value, &txbuf[2]); + + retval = spi_write(spi, txbuf, sizeof(txbuf)); + spi_unlock(device); + + return retval; +} + +static int b53_spi_write48(struct b53_device *dev, u8 page, u8 reg, u64 value) +{ + struct spi_device *spi = dev->priv; + struct device *device = spi->dev.parent->parent; + int ret; + u8 txbuf[10]; + int retval; + + spi_lock(); + ret = b53_prepare_reg_access(spi, page); + if (ret) + return ret; + + txbuf[0] = B53_SPI_CMD_NORMAL | B53_SPI_CMD_WRITE; + txbuf[1] = reg; + put_unaligned_le64(value, &txbuf[2]); + + retval = spi_write(spi, txbuf, sizeof(txbuf) - 2); + spi_unlock(device); + + return retval; +} + +static int b53_spi_write64(struct b53_device *dev, u8 page, u8 reg, u64 value) +{ + struct spi_device *spi = dev->priv; + struct device *device = spi->dev.parent->parent; + int ret; + u8 txbuf[10]; + int retval; + + spi_lock(); + ret = b53_prepare_reg_access(spi, page); + if (ret) + return ret; + + txbuf[0] = B53_SPI_CMD_NORMAL | B53_SPI_CMD_WRITE; + txbuf[1] = reg; + put_unaligned_le64(value, &txbuf[2]); + + retval = spi_write(spi, txbuf, sizeof(txbuf)); + spi_unlock(device); + + return retval; +} + +static const struct b53_io_ops b53_spi_ops = { + .read8 = b53_spi_read8, + .read16 = b53_spi_read16, + .read32 = b53_spi_read32, + .read48 = b53_spi_read48, + .read64 = b53_spi_read64, + .write8 = b53_spi_write8, + .write16 = b53_spi_write16, + .write32 = b53_spi_write32, + .write48 = b53_spi_write48, + .write64 = b53_spi_write64, +}; + +static int b53_spi_probe(struct spi_device *spi) +{ + struct device *device = spi->dev.parent->parent; + struct b53_device *dev; + int ret; + struct net_device *ndev = dev_get_by_name(&init_net, "eth0"); + + if(!ndev) + return -EPROBE_DEFER; + + dev = b53_switch_alloc(&spi->dev, &b53_spi_ops, spi); + if (!dev) + return -ENOMEM; + + if (spi->dev.platform_data) + dev->pdata = spi->dev.platform_data; + + pm_runtime_set_autosuspend_delay(device, 0); + + ret = b53_switch_register(dev); + if (ret) + return ret; + + spi_set_drvdata(spi, dev); + + return 0; +} + +static int b53_spi_remove(struct spi_device *spi) +{ + struct b53_device *dev = spi_get_drvdata(spi); + + if (dev) + b53_switch_remove(dev); + + spi_set_drvdata(spi, NULL); + + return 0; +} + +static void b53_spi_shutdown(struct spi_device *spi) +{ + struct b53_device *dev = spi_get_drvdata(spi); + + if (dev) + b53_switch_shutdown(dev); + + spi_set_drvdata(spi, NULL); +} + +static const struct of_device_id b53_spi_of_match[] = { + { .compatible = "brcm,bcm53134-datum" }, + { /* sentinel */ } +}; +MODULE_DEVICE_TABLE(of, b53_spi_of_match); + +static const struct spi_device_id b53_spi_ids[] = { + { .name = "bcm53134-datum" }, + { /* sentinel */ } +}; +MODULE_DEVICE_TABLE(spi, b53_spi_ids); + +static struct spi_driver b53_spi_driver = { + .driver = { + .name = "b53-switch-datum", + .of_match_table = b53_spi_of_match, + }, + .probe = b53_spi_probe, + .remove = b53_spi_remove, + .shutdown = b53_spi_shutdown, + .id_table = b53_spi_ids, +}; + +module_spi_driver(b53_spi_driver); + +MODULE_AUTHOR("Jonas Gorski "); +MODULE_DESCRIPTION("B53 SPI access driver"); +MODULE_LICENSE("Dual BSD/GPL"); From 88b2936ee74faa3e9d1797a4adfa935dcc7c2167 Mon Sep 17 00:00:00 2001 From: mcarlin Date: Sun, 21 Apr 2024 12:36:51 -0700 Subject: [PATCH 26/27] v4.15.107-datum.10-eng.5: Tweak the mcp9902-datum driver reg reads to only grab/release the mutex once during multiple register reads. --- Makefile | 2 +- drivers/hwmon/mcp9902_datum.c | 6 ++---- 2 files changed, 3 insertions(+), 5 deletions(-) diff --git a/Makefile b/Makefile index fa0e1899dd1b5c..41f7832d0c36a7 100644 --- a/Makefile +++ b/Makefile @@ -2,7 +2,7 @@ VERSION = 5 PATCHLEVEL = 15 SUBLEVEL = 107 -EXTRAVERSION = -datum.10-eng.4 +EXTRAVERSION = -datum.10-eng.5 NAME = Trick or Treat # *DOCUMENTATION* diff --git a/drivers/hwmon/mcp9902_datum.c b/drivers/hwmon/mcp9902_datum.c index ae284b9859635b..baf6813e09a748 100644 --- a/drivers/hwmon/mcp9902_datum.c +++ b/drivers/hwmon/mcp9902_datum.c @@ -150,7 +150,7 @@ static struct mcp9902_data *mcp9902_update_device(struct device *dev) int j; mutex_lock(&data->update_lock); -// spi_lock(); + spi_lock(); // if (time_after(jiffies, data->last_updated + HZ * 2) || !data->valid) { if (time_after(jiffies, data->last_updated + 1) || !data->valid) { @@ -159,20 +159,18 @@ static struct mcp9902_data *mcp9902_update_device(struct device *dev) for (j = 0; j < 20; j++) { - spi_lock(); for (i = 0; i < t_num_regs; i++) data->temp[i] = i2c_smbus_read_byte_data(client, regs_read[i]); data->alarms = i2c_smbus_read_byte_data(client, MCP9902_REG_R_STATUS); - spi_unlock(adapter->dev.parent); } data->last_updated = jiffies; data->valid = 1; } -// spi_unlock(adapter->dev.parent); + spi_unlock(adapter->dev.parent); mutex_unlock(&data->update_lock); return data; From 6217f324896c43bbc81b19ca6dc90cc1f7c15fd9 Mon Sep 17 00:00:00 2001 From: mcarlin Date: Sun, 21 Apr 2024 12:53:20 -0700 Subject: [PATCH 27/27] v5.15.107-datum.10: Remove extra bus activity for mcp9902 and spi phy driver. Ready for release. --- Makefile | 2 +- drivers/hwmon/mcp9902_datum.c | 3 +-- drivers/net/phy/phy.c | 3 +-- 3 files changed, 3 insertions(+), 5 deletions(-) diff --git a/Makefile b/Makefile index 41f7832d0c36a7..14e362fece9e11 100644 --- a/Makefile +++ b/Makefile @@ -2,7 +2,7 @@ VERSION = 5 PATCHLEVEL = 15 SUBLEVEL = 107 -EXTRAVERSION = -datum.10-eng.5 +EXTRAVERSION = -datum.10 NAME = Trick or Treat # *DOCUMENTATION* diff --git a/drivers/hwmon/mcp9902_datum.c b/drivers/hwmon/mcp9902_datum.c index baf6813e09a748..0e72ccb6af3296 100644 --- a/drivers/hwmon/mcp9902_datum.c +++ b/drivers/hwmon/mcp9902_datum.c @@ -152,8 +152,7 @@ static struct mcp9902_data *mcp9902_update_device(struct device *dev) mutex_lock(&data->update_lock); spi_lock(); - // if (time_after(jiffies, data->last_updated + HZ * 2) || !data->valid) { - if (time_after(jiffies, data->last_updated + 1) || !data->valid) { + if (time_after(jiffies, data->last_updated + HZ * 2) || !data->valid) { dev_dbg(&client->dev, "Updating mcp9902 data.\n"); // printk("Updating mcp9902 data.\n"); diff --git a/drivers/net/phy/phy.c b/drivers/net/phy/phy.c index 7c130bcde9b61e..42e1c484cea841 100644 --- a/drivers/net/phy/phy.c +++ b/drivers/net/phy/phy.c @@ -36,8 +36,7 @@ #include #include -// #define PHY_STATE_TIME HZ -#define PHY_STATE_TIME 2 +#define PHY_STATE_TIME HZ #define PHY_STATE_STR(_state) \ case PHY_##_state: \