hc
2024-02-20 102a0743326a03cd1a1202ceda21e175b7d3575c
kernel/drivers/net/dsa/bcm_sf2.c
....@@ -1,12 +1,8 @@
1
+// SPDX-License-Identifier: GPL-2.0-or-later
12 /*
23 * Broadcom Starfighter 2 DSA switch driver
34 *
45 * Copyright (C) 2014, Broadcom Corporation
5
- *
6
- * This program is free software; you can redistribute it and/or modify
7
- * it under the terms of the GNU General Public License as published by
8
- * the Free Software Foundation; either version 2 of the License, or
9
- * (at your option) any later version.
106 */
117
128 #include <linux/list.h>
....@@ -18,6 +14,7 @@
1814 #include <linux/phy_fixed.h>
1915 #include <linux/phylink.h>
2016 #include <linux/mii.h>
17
+#include <linux/clk.h>
2118 #include <linux/of.h>
2219 #include <linux/of_irq.h>
2320 #include <linux/of_address.h>
....@@ -34,6 +31,49 @@
3431 #include "bcm_sf2_regs.h"
3532 #include "b53/b53_priv.h"
3633 #include "b53/b53_regs.h"
34
+
35
+/* Return the number of active ports, not counting the IMP (CPU) port */
36
+static unsigned int bcm_sf2_num_active_ports(struct dsa_switch *ds)
37
+{
38
+ struct bcm_sf2_priv *priv = bcm_sf2_to_priv(ds);
39
+ unsigned int port, count = 0;
40
+
41
+ for (port = 0; port < ds->num_ports; port++) {
42
+ if (dsa_is_cpu_port(ds, port))
43
+ continue;
44
+ if (priv->port_sts[port].enabled)
45
+ count++;
46
+ }
47
+
48
+ return count;
49
+}
50
+
51
+static void bcm_sf2_recalc_clock(struct dsa_switch *ds)
52
+{
53
+ struct bcm_sf2_priv *priv = bcm_sf2_to_priv(ds);
54
+ unsigned long new_rate;
55
+ unsigned int ports_active;
56
+ /* Frequenty in Mhz */
57
+ static const unsigned long rate_table[] = {
58
+ 59220000,
59
+ 60820000,
60
+ 62500000,
61
+ 62500000,
62
+ };
63
+
64
+ ports_active = bcm_sf2_num_active_ports(ds);
65
+ if (ports_active == 0 || !priv->clk_mdiv)
66
+ return;
67
+
68
+ /* If we overflow our table, just use the recommended operational
69
+ * frequency
70
+ */
71
+ if (ports_active > ARRAY_SIZE(rate_table))
72
+ new_rate = 90000000;
73
+ else
74
+ new_rate = rate_table[ports_active - 1];
75
+ clk_set_rate(priv->clk_mdiv, new_rate);
76
+}
3777
3878 static void bcm_sf2_imp_setup(struct dsa_switch *ds, int port)
3979 {
....@@ -86,6 +126,8 @@
86126 reg &= ~(RX_DIS | TX_DIS);
87127 core_writel(priv, reg, CORE_G_PCTL_PORT(port));
88128 }
129
+
130
+ priv->port_sts[port].enabled = true;
89131 }
90132
91133 static void bcm_sf2_gphy_enable_set(struct dsa_switch *ds, bool enable)
....@@ -168,6 +210,13 @@
168210 unsigned int i;
169211 u32 reg;
170212
213
+ if (!dsa_is_user_port(ds, port))
214
+ return 0;
215
+
216
+ priv->port_sts[port].enabled = true;
217
+
218
+ bcm_sf2_recalc_clock(ds);
219
+
171220 /* Clear the memory power down */
172221 reg = core_readl(priv, CORE_MEM_PSM_VDD_CTRL);
173222 reg &= ~P_TXQ_PSM_VDD(port);
....@@ -223,8 +272,7 @@
223272 return b53_enable_port(ds, port, phy);
224273 }
225274
226
-static void bcm_sf2_port_disable(struct dsa_switch *ds, int port,
227
- struct phy_device *phy)
275
+static void bcm_sf2_port_disable(struct dsa_switch *ds, int port)
228276 {
229277 struct bcm_sf2_priv *priv = bcm_sf2_to_priv(ds);
230278 u32 reg;
....@@ -243,12 +291,16 @@
243291 if (priv->int_phy_mask & 1 << port && priv->hw_params.num_gphy == 1)
244292 bcm_sf2_gphy_enable_set(ds, false);
245293
246
- b53_disable_port(ds, port, phy);
294
+ b53_disable_port(ds, port);
247295
248296 /* Power down the port memory */
249297 reg = core_readl(priv, CORE_MEM_PSM_VDD_CTRL);
250298 reg |= P_TXQ_PSM_VDD(port);
251299 core_writel(priv, reg, CORE_MEM_PSM_VDD_CTRL);
300
+
301
+ priv->port_sts[port].enabled = false;
302
+
303
+ bcm_sf2_recalc_clock(ds);
252304 }
253305
254306
....@@ -348,6 +400,18 @@
348400 {
349401 unsigned int timeout = 1000;
350402 u32 reg;
403
+ int ret;
404
+
405
+ /* The watchdog reset does not work on 7278, we need to hit the
406
+ * "external" reset line through the reset controller.
407
+ */
408
+ if (priv->type == BCM7278_DEVICE_ID && !IS_ERR(priv->rcdev)) {
409
+ ret = reset_control_assert(priv->rcdev);
410
+ if (ret)
411
+ return ret;
412
+
413
+ return reset_control_deassert(priv->rcdev);
414
+ }
351415
352416 reg = core_readl(priv, CORE_WATCHDOG_CTRL);
353417 reg |= SOFTWARE_RESET | EN_CHIP_RST | EN_SW_RESET;
....@@ -379,8 +443,10 @@
379443 struct device_node *dn)
380444 {
381445 struct device_node *port;
382
- int mode;
383446 unsigned int port_num;
447
+ struct property *prop;
448
+ phy_interface_t mode;
449
+ int err;
384450
385451 priv->moca_port = -1;
386452
....@@ -393,8 +459,8 @@
393459 * has completed, since they might be turned off at that
394460 * time
395461 */
396
- mode = of_get_phy_mode(port);
397
- if (mode < 0)
462
+ err = of_get_phy_mode(port, &mode);
463
+ if (err)
398464 continue;
399465
400466 if (mode == PHY_INTERFACE_MODE_INTERNAL)
....@@ -405,15 +471,27 @@
405471
406472 if (of_property_read_bool(port, "brcm,use-bcm-hdr"))
407473 priv->brcm_tag_mask |= 1 << port_num;
474
+
475
+ /* Ensure that port 5 is not picked up as a DSA CPU port
476
+ * flavour but a regular port instead. We should be using
477
+ * devlink to be able to set the port flavour.
478
+ */
479
+ if (port_num == 5 && priv->type == BCM7278_DEVICE_ID) {
480
+ prop = of_find_property(port, "ethernet", NULL);
481
+ if (prop)
482
+ of_remove_property(port, prop);
483
+ }
408484 }
409485 }
410486
411487 static int bcm_sf2_mdio_register(struct dsa_switch *ds)
412488 {
413489 struct bcm_sf2_priv *priv = bcm_sf2_to_priv(ds);
414
- struct device_node *dn;
490
+ struct device_node *dn, *child;
491
+ struct phy_device *phydev;
492
+ struct property *prop;
415493 static int index;
416
- int err;
494
+ int err, reg;
417495
418496 /* Find our integrated MDIO bus node */
419497 dn = of_find_compatible_node(NULL, NULL, "brcm,unimac-mdio");
....@@ -426,7 +504,7 @@
426504 get_device(&priv->master_mii_bus->dev);
427505 priv->master_mii_dn = dn;
428506
429
- priv->slave_mii_bus = devm_mdiobus_alloc(ds->dev);
507
+ priv->slave_mii_bus = mdiobus_alloc();
430508 if (!priv->slave_mii_bus) {
431509 of_node_put(dn);
432510 return -ENOMEM;
....@@ -451,7 +529,7 @@
451529 * driver.
452530 */
453531 if (of_machine_is_compatible("brcm,bcm7445d0"))
454
- priv->indir_phy_mask |= (1 << BRCM_PSEUDO_PHY_ADDR);
532
+ priv->indir_phy_mask |= (1 << BRCM_PSEUDO_PHY_ADDR) | (1 << 0);
455533 else
456534 priv->indir_phy_mask = 0;
457535
....@@ -460,9 +538,36 @@
460538 priv->slave_mii_bus->parent = ds->dev->parent;
461539 priv->slave_mii_bus->phy_mask = ~priv->indir_phy_mask;
462540
541
+ /* We need to make sure that of_phy_connect() will not work by
542
+ * removing the 'phandle' and 'linux,phandle' properties and
543
+ * unregister the existing PHY device that was already registered.
544
+ */
545
+ for_each_available_child_of_node(dn, child) {
546
+ if (of_property_read_u32(child, "reg", &reg) ||
547
+ reg >= PHY_MAX_ADDR)
548
+ continue;
549
+
550
+ if (!(priv->indir_phy_mask & BIT(reg)))
551
+ continue;
552
+
553
+ prop = of_find_property(child, "phandle", NULL);
554
+ if (prop)
555
+ of_remove_property(child, prop);
556
+
557
+ prop = of_find_property(child, "linux,phandle", NULL);
558
+ if (prop)
559
+ of_remove_property(child, prop);
560
+
561
+ phydev = of_phy_find_device(child);
562
+ if (phydev)
563
+ phy_device_remove(phydev);
564
+ }
565
+
463566 err = mdiobus_register(priv->slave_mii_bus);
464
- if (err && dn)
567
+ if (err && dn) {
568
+ mdiobus_free(priv->slave_mii_bus);
465569 of_node_put(dn);
570
+ }
466571
467572 return err;
468573 }
....@@ -470,8 +575,8 @@
470575 static void bcm_sf2_mdio_unregister(struct bcm_sf2_priv *priv)
471576 {
472577 mdiobus_unregister(priv->slave_mii_bus);
473
- if (priv->master_mii_dn)
474
- of_node_put(priv->master_mii_dn);
578
+ mdiobus_free(priv->slave_mii_bus);
579
+ of_node_put(priv->master_mii_dn);
475580 }
476581
477582 static u32 bcm_sf2_sw_get_phy_flags(struct dsa_switch *ds, int port)
....@@ -492,6 +597,7 @@
492597 unsigned long *supported,
493598 struct phylink_link_state *state)
494599 {
600
+ struct bcm_sf2_priv *priv = bcm_sf2_to_priv(ds);
495601 __ETHTOOL_DECLARE_LINK_MODE_MASK(mask) = { 0, };
496602
497603 if (!phy_interface_mode_is_rgmii(state->interface) &&
....@@ -501,8 +607,10 @@
501607 state->interface != PHY_INTERFACE_MODE_INTERNAL &&
502608 state->interface != PHY_INTERFACE_MODE_MOCA) {
503609 bitmap_zero(supported, __ETHTOOL_LINK_MODE_MASK_NBITS);
504
- dev_err(ds->dev,
505
- "Unsupported interface: %d\n", state->interface);
610
+ if (port != core_readl(priv, CORE_IMP0_PRT_ID))
611
+ dev_err(ds->dev,
612
+ "Unsupported interface: %d for port %d\n",
613
+ state->interface, port);
506614 return;
507615 }
508616
....@@ -538,17 +646,15 @@
538646 {
539647 struct bcm_sf2_priv *priv = bcm_sf2_to_priv(ds);
540648 u32 id_mode_dis = 0, port_mode;
541
- u32 reg, offset;
649
+ u32 reg;
542650
543
- if (priv->type == BCM7445_DEVICE_ID)
544
- offset = CORE_STS_OVERRIDE_GMIIP_PORT(port);
545
- else
546
- offset = CORE_STS_OVERRIDE_GMIIP2_PORT(port);
651
+ if (port == core_readl(priv, CORE_IMP0_PRT_ID))
652
+ return;
547653
548654 switch (state->interface) {
549655 case PHY_INTERFACE_MODE_RGMII:
550656 id_mode_dis = 1;
551
- /* fallthrough */
657
+ fallthrough;
552658 case PHY_INTERFACE_MODE_RGMII_TXID:
553659 port_mode = EXT_GPHY;
554660 break;
....@@ -559,8 +665,8 @@
559665 port_mode = EXT_REVMII;
560666 break;
561667 default:
562
- /* all other PHYs: internal and MoCA */
563
- goto force_link;
668
+ /* Nothing required for all other PHYs: internal and MoCA */
669
+ return;
564670 }
565671
566672 /* Clear id_mode_dis bit, and the existing port mode, let
....@@ -569,38 +675,12 @@
569675 reg = reg_readl(priv, REG_RGMII_CNTRL_P(port));
570676 reg &= ~ID_MODE_DIS;
571677 reg &= ~(PORT_MODE_MASK << PORT_MODE_SHIFT);
572
- reg &= ~(RX_PAUSE_EN | TX_PAUSE_EN);
573678
574679 reg |= port_mode;
575680 if (id_mode_dis)
576681 reg |= ID_MODE_DIS;
577682
578
- if (state->pause & MLO_PAUSE_TXRX_MASK) {
579
- if (state->pause & MLO_PAUSE_TX)
580
- reg |= TX_PAUSE_EN;
581
- reg |= RX_PAUSE_EN;
582
- }
583
-
584683 reg_writel(priv, reg, REG_RGMII_CNTRL_P(port));
585
-
586
-force_link:
587
- /* Force link settings detected from the PHY */
588
- reg = SW_OVERRIDE;
589
- switch (state->speed) {
590
- case SPEED_1000:
591
- reg |= SPDSTS_1000 << SPEED_SHIFT;
592
- break;
593
- case SPEED_100:
594
- reg |= SPDSTS_100 << SPEED_SHIFT;
595
- break;
596
- }
597
-
598
- if (state->link)
599
- reg |= LINK_STS;
600
- if (state->duplex == DUPLEX_FULL)
601
- reg |= DUPLX_MODE;
602
-
603
- core_writel(priv, reg, offset);
604684 }
605685
606686 static void bcm_sf2_sw_mac_link_set(struct dsa_switch *ds, int port,
....@@ -627,18 +707,80 @@
627707 unsigned int mode,
628708 phy_interface_t interface)
629709 {
710
+ struct bcm_sf2_priv *priv = bcm_sf2_to_priv(ds);
711
+ u32 reg, offset;
712
+
713
+ if (priv->wol_ports_mask & BIT(port))
714
+ return;
715
+
716
+ if (port != core_readl(priv, CORE_IMP0_PRT_ID)) {
717
+ if (priv->type == BCM7445_DEVICE_ID)
718
+ offset = CORE_STS_OVERRIDE_GMIIP_PORT(port);
719
+ else
720
+ offset = CORE_STS_OVERRIDE_GMIIP2_PORT(port);
721
+
722
+ reg = core_readl(priv, offset);
723
+ reg &= ~LINK_STS;
724
+ core_writel(priv, reg, offset);
725
+ }
726
+
630727 bcm_sf2_sw_mac_link_set(ds, port, interface, false);
631728 }
632729
633730 static void bcm_sf2_sw_mac_link_up(struct dsa_switch *ds, int port,
634731 unsigned int mode,
635732 phy_interface_t interface,
636
- struct phy_device *phydev)
733
+ struct phy_device *phydev,
734
+ int speed, int duplex,
735
+ bool tx_pause, bool rx_pause)
637736 {
638737 struct bcm_sf2_priv *priv = bcm_sf2_to_priv(ds);
639738 struct ethtool_eee *p = &priv->dev->ports[port].eee;
739
+ u32 reg, offset;
640740
641741 bcm_sf2_sw_mac_link_set(ds, port, interface, true);
742
+
743
+ if (port != core_readl(priv, CORE_IMP0_PRT_ID)) {
744
+ if (priv->type == BCM7445_DEVICE_ID)
745
+ offset = CORE_STS_OVERRIDE_GMIIP_PORT(port);
746
+ else
747
+ offset = CORE_STS_OVERRIDE_GMIIP2_PORT(port);
748
+
749
+ if (interface == PHY_INTERFACE_MODE_RGMII ||
750
+ interface == PHY_INTERFACE_MODE_RGMII_TXID ||
751
+ interface == PHY_INTERFACE_MODE_MII ||
752
+ interface == PHY_INTERFACE_MODE_REVMII) {
753
+ reg = reg_readl(priv, REG_RGMII_CNTRL_P(port));
754
+ reg &= ~(RX_PAUSE_EN | TX_PAUSE_EN);
755
+
756
+ if (tx_pause)
757
+ reg |= TX_PAUSE_EN;
758
+ if (rx_pause)
759
+ reg |= RX_PAUSE_EN;
760
+
761
+ reg_writel(priv, reg, REG_RGMII_CNTRL_P(port));
762
+ }
763
+
764
+ reg = SW_OVERRIDE | LINK_STS;
765
+ switch (speed) {
766
+ case SPEED_1000:
767
+ reg |= SPDSTS_1000 << SPEED_SHIFT;
768
+ break;
769
+ case SPEED_100:
770
+ reg |= SPDSTS_100 << SPEED_SHIFT;
771
+ break;
772
+ }
773
+
774
+ if (duplex == DUPLEX_FULL)
775
+ reg |= DUPLX_MODE;
776
+
777
+ if (tx_pause)
778
+ reg |= TXFLOW_CNTL;
779
+ if (rx_pause)
780
+ reg |= RXFLOW_CNTL;
781
+
782
+ core_writel(priv, reg, offset);
783
+ }
642784
643785 if (mode == MLO_AN_PHY && phydev)
644786 p->eee_enabled = b53_eee_init(ds, port, phydev);
....@@ -667,7 +809,7 @@
667809 * state machine and make it go in PHY_FORCING state instead.
668810 */
669811 if (!status->link)
670
- netif_carrier_off(ds->ports[port].slave);
812
+ netif_carrier_off(dsa_to_port(ds, port)->slave);
671813 status->duplex = DUPLEX_FULL;
672814 } else {
673815 status->link = true;
....@@ -701,8 +843,11 @@
701843 */
702844 for (port = 0; port < ds->num_ports; port++) {
703845 if (dsa_is_user_port(ds, port) || dsa_is_cpu_port(ds, port))
704
- bcm_sf2_port_disable(ds, port, NULL);
846
+ bcm_sf2_port_disable(ds, port);
705847 }
848
+
849
+ if (!priv->wol_ports_mask)
850
+ clk_disable_unprepare(priv->clk);
706851
707852 return 0;
708853 }
....@@ -712,11 +857,18 @@
712857 struct bcm_sf2_priv *priv = bcm_sf2_to_priv(ds);
713858 int ret;
714859
860
+ if (!priv->wol_ports_mask)
861
+ clk_prepare_enable(priv->clk);
862
+
715863 ret = bcm_sf2_sw_rst(priv);
716864 if (ret) {
717865 pr_err("%s: failed to software reset switch\n", __func__);
718866 return ret;
719867 }
868
+
869
+ ret = bcm_sf2_cfp_resume(ds);
870
+ if (ret)
871
+ return ret;
720872
721873 if (priv->hw_params.num_gphy == 1)
722874 bcm_sf2_gphy_enable_set(ds, true);
....@@ -729,7 +881,7 @@
729881 static void bcm_sf2_sw_get_wol(struct dsa_switch *ds, int port,
730882 struct ethtool_wolinfo *wol)
731883 {
732
- struct net_device *p = ds->ports[port].cpu_dp->master;
884
+ struct net_device *p = dsa_to_port(ds, port)->cpu_dp->master;
733885 struct bcm_sf2_priv *priv = bcm_sf2_to_priv(ds);
734886 struct ethtool_wolinfo pwol = { };
735887
....@@ -753,9 +905,9 @@
753905 static int bcm_sf2_sw_set_wol(struct dsa_switch *ds, int port,
754906 struct ethtool_wolinfo *wol)
755907 {
756
- struct net_device *p = ds->ports[port].cpu_dp->master;
908
+ struct net_device *p = dsa_to_port(ds, port)->cpu_dp->master;
757909 struct bcm_sf2_priv *priv = bcm_sf2_to_priv(ds);
758
- s8 cpu_port = ds->ports[port].cpu_dp->index;
910
+ s8 cpu_port = dsa_to_port(ds, port)->cpu_dp->index;
759911 struct ethtool_wolinfo pwol = { };
760912
761913 if (p->ethtool_ops->get_wol)
....@@ -793,13 +945,18 @@
793945 else if (dsa_is_cpu_port(ds, port))
794946 bcm_sf2_imp_setup(ds, port);
795947 else
796
- bcm_sf2_port_disable(ds, port, NULL);
948
+ bcm_sf2_port_disable(ds, port);
797949 }
798950
799951 b53_configure_vlan(ds);
800952 bcm_sf2_enable_acb(ds);
801953
802
- return 0;
954
+ return b53_setup_devlink_resources(ds);
955
+}
956
+
957
+static void bcm_sf2_sw_teardown(struct dsa_switch *ds)
958
+{
959
+ dsa_devlink_resources_unregister(ds);
803960 }
804961
805962 /* The SWITCH_CORE register space is managed by b53 but operates on a page +
....@@ -901,12 +1058,45 @@
9011058 .write64 = bcm_sf2_core_write64,
9021059 };
9031060
1061
+static void bcm_sf2_sw_get_strings(struct dsa_switch *ds, int port,
1062
+ u32 stringset, uint8_t *data)
1063
+{
1064
+ int cnt = b53_get_sset_count(ds, port, stringset);
1065
+
1066
+ b53_get_strings(ds, port, stringset, data);
1067
+ bcm_sf2_cfp_get_strings(ds, port, stringset,
1068
+ data + cnt * ETH_GSTRING_LEN);
1069
+}
1070
+
1071
+static void bcm_sf2_sw_get_ethtool_stats(struct dsa_switch *ds, int port,
1072
+ uint64_t *data)
1073
+{
1074
+ int cnt = b53_get_sset_count(ds, port, ETH_SS_STATS);
1075
+
1076
+ b53_get_ethtool_stats(ds, port, data);
1077
+ bcm_sf2_cfp_get_ethtool_stats(ds, port, data + cnt);
1078
+}
1079
+
1080
+static int bcm_sf2_sw_get_sset_count(struct dsa_switch *ds, int port,
1081
+ int sset)
1082
+{
1083
+ int cnt = b53_get_sset_count(ds, port, sset);
1084
+
1085
+ if (cnt < 0)
1086
+ return cnt;
1087
+
1088
+ cnt += bcm_sf2_cfp_get_sset_count(ds, port, sset);
1089
+
1090
+ return cnt;
1091
+}
1092
+
9041093 static const struct dsa_switch_ops bcm_sf2_ops = {
9051094 .get_tag_protocol = b53_get_tag_protocol,
9061095 .setup = bcm_sf2_sw_setup,
907
- .get_strings = b53_get_strings,
908
- .get_ethtool_stats = b53_get_ethtool_stats,
909
- .get_sset_count = b53_get_sset_count,
1096
+ .teardown = bcm_sf2_sw_teardown,
1097
+ .get_strings = bcm_sf2_sw_get_strings,
1098
+ .get_ethtool_stats = bcm_sf2_sw_get_ethtool_stats,
1099
+ .get_sset_count = bcm_sf2_sw_get_sset_count,
9101100 .get_ethtool_phy_stats = b53_get_ethtool_phy_stats,
9111101 .get_phy_flags = bcm_sf2_sw_get_phy_flags,
9121102 .phylink_validate = bcm_sf2_sw_validate,
....@@ -937,6 +1127,9 @@
9371127 .set_rxnfc = bcm_sf2_set_rxnfc,
9381128 .port_mirror_add = b53_mirror_add,
9391129 .port_mirror_del = b53_mirror_del,
1130
+ .port_mdb_prepare = b53_mdb_prepare,
1131
+ .port_mdb_add = b53_mdb_add,
1132
+ .port_mdb_del = b53_mdb_del,
9401133 };
9411134
9421135 struct bcm_sf2_of_data {
....@@ -1020,7 +1213,6 @@
10201213 struct b53_device *dev;
10211214 struct dsa_switch *ds;
10221215 void __iomem **base;
1023
- struct resource *r;
10241216 unsigned int i;
10251217 u32 reg, rev;
10261218 int ret;
....@@ -1053,6 +1245,11 @@
10531245 priv->core_reg_align = data->core_reg_align;
10541246 priv->num_cfp_rules = data->num_cfp_rules;
10551247
1248
+ priv->rcdev = devm_reset_control_get_optional_exclusive(&pdev->dev,
1249
+ "switch");
1250
+ if (PTR_ERR(priv->rcdev) == -EPROBE_DEFER)
1251
+ return PTR_ERR(priv->rcdev);
1252
+
10561253 /* Auto-detection using standard registers will not work, so
10571254 * provide an indication of what kind of device we are for
10581255 * b53_common to work with
....@@ -1070,8 +1267,8 @@
10701267 dev_set_drvdata(&pdev->dev, priv);
10711268
10721269 spin_lock_init(&priv->indir_lock);
1073
- mutex_init(&priv->stats_mutex);
10741270 mutex_init(&priv->cfp.lock);
1271
+ INIT_LIST_HEAD(&priv->cfp.rules_list);
10751272
10761273 /* CFP rule #0 cannot be used for specific classifications, flag it as
10771274 * permanently used
....@@ -1092,8 +1289,7 @@
10921289
10931290 base = &priv->core;
10941291 for (i = 0; i < BCM_SF2_REGS_NUM; i++) {
1095
- r = platform_get_resource(pdev, IORESOURCE_MEM, i);
1096
- *base = devm_ioremap_resource(&pdev->dev, r);
1292
+ *base = devm_platform_ioremap_resource(pdev, i);
10971293 if (IS_ERR(*base)) {
10981294 pr_err("unable to find register: %s\n", reg_names[i]);
10991295 return PTR_ERR(*base);
....@@ -1101,10 +1297,28 @@
11011297 base++;
11021298 }
11031299
1300
+ priv->clk = devm_clk_get_optional(&pdev->dev, "sw_switch");
1301
+ if (IS_ERR(priv->clk))
1302
+ return PTR_ERR(priv->clk);
1303
+
1304
+ ret = clk_prepare_enable(priv->clk);
1305
+ if (ret)
1306
+ return ret;
1307
+
1308
+ priv->clk_mdiv = devm_clk_get_optional(&pdev->dev, "sw_switch_mdiv");
1309
+ if (IS_ERR(priv->clk_mdiv)) {
1310
+ ret = PTR_ERR(priv->clk_mdiv);
1311
+ goto out_clk;
1312
+ }
1313
+
1314
+ ret = clk_prepare_enable(priv->clk_mdiv);
1315
+ if (ret)
1316
+ goto out_clk;
1317
+
11041318 ret = bcm_sf2_sw_rst(priv);
11051319 if (ret) {
11061320 pr_err("unable to software reset switch: %d\n", ret);
1107
- return ret;
1321
+ goto out_clk_mdiv;
11081322 }
11091323
11101324 bcm_sf2_gphy_enable_set(priv->dev->ds, true);
....@@ -1112,7 +1326,7 @@
11121326 ret = bcm_sf2_mdio_register(ds);
11131327 if (ret) {
11141328 pr_err("failed to register MDIO bus\n");
1115
- return ret;
1329
+ goto out_clk_mdiv;
11161330 }
11171331
11181332 bcm_sf2_gphy_enable_set(priv->dev->ds, false);
....@@ -1169,15 +1383,20 @@
11691383 if (ret)
11701384 goto out_mdio;
11711385
1172
- pr_info("Starfighter 2 top: %x.%02x, core: %x.%02x base: 0x%p, IRQs: %d, %d\n",
1173
- priv->hw_params.top_rev >> 8, priv->hw_params.top_rev & 0xff,
1174
- priv->hw_params.core_rev >> 8, priv->hw_params.core_rev & 0xff,
1175
- priv->core, priv->irq0, priv->irq1);
1386
+ dev_info(&pdev->dev,
1387
+ "Starfighter 2 top: %x.%02x, core: %x.%02x, IRQs: %d, %d\n",
1388
+ priv->hw_params.top_rev >> 8, priv->hw_params.top_rev & 0xff,
1389
+ priv->hw_params.core_rev >> 8, priv->hw_params.core_rev & 0xff,
1390
+ priv->irq0, priv->irq1);
11761391
11771392 return 0;
11781393
11791394 out_mdio:
11801395 bcm_sf2_mdio_unregister(priv);
1396
+out_clk_mdiv:
1397
+ clk_disable_unprepare(priv->clk_mdiv);
1398
+out_clk:
1399
+ clk_disable_unprepare(priv->clk);
11811400 return ret;
11821401 }
11831402
....@@ -1186,10 +1405,15 @@
11861405 struct bcm_sf2_priv *priv = platform_get_drvdata(pdev);
11871406
11881407 priv->wol_ports_mask = 0;
1408
+ /* Disable interrupts */
1409
+ bcm_sf2_intr_disable(priv);
11891410 dsa_unregister_switch(priv->dev->ds);
1190
- /* Disable all ports and interrupts */
1191
- bcm_sf2_sw_suspend(priv->dev->ds);
1411
+ bcm_sf2_cfp_exit(priv->dev->ds);
11921412 bcm_sf2_mdio_unregister(priv);
1413
+ clk_disable_unprepare(priv->clk_mdiv);
1414
+ clk_disable_unprepare(priv->clk);
1415
+ if (priv->type == BCM7278_DEVICE_ID && !IS_ERR(priv->rcdev))
1416
+ reset_control_assert(priv->rcdev);
11931417
11941418 return 0;
11951419 }
....@@ -1211,16 +1435,14 @@
12111435 #ifdef CONFIG_PM_SLEEP
12121436 static int bcm_sf2_suspend(struct device *dev)
12131437 {
1214
- struct platform_device *pdev = to_platform_device(dev);
1215
- struct bcm_sf2_priv *priv = platform_get_drvdata(pdev);
1438
+ struct bcm_sf2_priv *priv = dev_get_drvdata(dev);
12161439
12171440 return dsa_switch_suspend(priv->dev->ds);
12181441 }
12191442
12201443 static int bcm_sf2_resume(struct device *dev)
12211444 {
1222
- struct platform_device *pdev = to_platform_device(dev);
1223
- struct bcm_sf2_priv *priv = platform_get_drvdata(pdev);
1445
+ struct bcm_sf2_priv *priv = dev_get_drvdata(dev);
12241446
12251447 return dsa_switch_resume(priv->dev->ds);
12261448 }