Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

Merge branch 'dsa-mv88e6xxx-monolithic'

Vivien Didelot says:

====================
net: dsa: mv88e6xxx: turn into monolithic driver

This patchset merges all mv88e6* drivers supported by the shared
mv88e6xxx code into a single mv88e6xxx DSA switch driver.

Some flags are added to describe the capabilities of a switch model,
such as the presence of a PPU, EEPROM, some old or new registers, etc.

First these flags are used to conditionally support the same set of
functions in every driver, then specific driver files are removed in
favor of the common mv88e6xxx driver.

Only the merge of driver specific setup code assumes a few differences.
If these differences such as frames priorities are really needed for
some models, they can easily be brought back in a future patch.

Some inconsistencies might show up, such as the need for
MV88E6XXX_FLAG_PPU and MV88E6XXX_FLAG_PPU_ACTIVE flags. But this
patchset does not aim to fix them yet. A future patch can do that if
they end up being unwanted.

The patchset has been tested on interconnected 88E6352 and 88E6185.

Changes v1 -> v2:
- add missing MV88E6XXX_FLAG_EEPROM flag checks
- remove a few remaining _ prefixes
- remove MV88E6XXX_FLAG_CORE_TAG_TYPE which is a specific default

Changes RFC -> v1:
- introduce flags in a separate patch
- do not refactor anything yet
- do not add new functions prefixed with _
- drop packet discarding and mentioned tested platforms
- factorize family flags
- update text for NET_DSA_MV88E6XXX Kconfig entry
====================

Reviewed-by: Andrew Lunn <andrew@lunn.ch>
Tested-by: Andrew Lunn <andrew@lunn.ch>
Signed-off-by: David S. Miller <davem@davemloft.net>

+905 -1270
+1 -4
arch/arm/configs/multi_v5_defconfig
··· 91 91 CONFIG_SATA_MV=y 92 92 CONFIG_NETDEVICES=y 93 93 CONFIG_NET_DSA_MV88E6060=y 94 - CONFIG_NET_DSA_MV88E6131=y 95 - CONFIG_NET_DSA_MV88E6123=y 96 - CONFIG_NET_DSA_MV88E6171=y 97 - CONFIG_NET_DSA_MV88E6352=y 94 + CONFIG_NET_DSA_MV88E6XXX=y 98 95 CONFIG_MV643XX_ETH=y 99 96 CONFIG_R8169=y 100 97 CONFIG_MARVELL_PHY=y
+1 -1
arch/arm/configs/mvebu_v7_defconfig
··· 66 66 CONFIG_AHCI_MVEBU=y 67 67 CONFIG_SATA_MV=y 68 68 CONFIG_NETDEVICES=y 69 - CONFIG_NET_DSA_MV88E6171=y 69 + CONFIG_NET_DSA_MV88E6XXX=y 70 70 CONFIG_MV643XX_ETH=y 71 71 CONFIG_MVNETA=y 72 72 CONFIG_MVPP2=y
+1 -2
arch/arm/configs/orion5x_defconfig
··· 85 85 CONFIG_SATA_MV=y 86 86 CONFIG_NETDEVICES=y 87 87 CONFIG_MII=y 88 - CONFIG_NET_DSA_MV88E6131=y 89 - CONFIG_NET_DSA_MV88E6123=y 88 + CONFIG_NET_DSA_MV88E6XXX=y 90 89 CONFIG_MV643XX_ETH=y 91 90 CONFIG_MARVELL_PHY=y 92 91 # CONFIG_INPUT_MOUSEDEV is not set
+1 -2
arch/tile/configs/tilegx_defconfig
··· 221 221 CONFIG_TUN=y 222 222 CONFIG_VETH=m 223 223 CONFIG_NET_DSA_MV88E6060=y 224 - CONFIG_NET_DSA_MV88E6131=y 225 - CONFIG_NET_DSA_MV88E6123=y 224 + CONFIG_NET_DSA_MV88E6XXX=y 226 225 CONFIG_SKY2=y 227 226 CONFIG_PTP_1588_CLOCK_TILEGX=y 228 227 # CONFIG_WLAN is not set
+1 -2
arch/tile/configs/tilepro_defconfig
··· 340 340 CONFIG_TUN=y 341 341 CONFIG_VETH=m 342 342 CONFIG_NET_DSA_MV88E6060=y 343 - CONFIG_NET_DSA_MV88E6131=y 344 - CONFIG_NET_DSA_MV88E6123=y 343 + CONFIG_NET_DSA_MV88E6XXX=y 345 344 # CONFIG_NET_VENDOR_3COM is not set 346 345 CONFIG_E1000E=y 347 346 # CONFIG_WLAN is not set
+4 -41
drivers/net/dsa/Kconfig
··· 1 1 menu "Distributed Switch Architecture drivers" 2 2 depends on HAVE_NET_DSA 3 3 4 - config NET_DSA_MV88E6XXX 5 - tristate 6 - default n 7 - 8 4 config NET_DSA_MV88E6060 9 5 tristate "Marvell 88E6060 ethernet switch chip support" 10 6 depends on NET_DSA ··· 9 13 This enables support for the Marvell 88E6060 ethernet switch 10 14 chip. 11 15 12 - config NET_DSA_MV88E6XXX_NEED_PPU 13 - bool 14 - default n 15 - 16 - config NET_DSA_MV88E6131 17 - tristate "Marvell 88E6085/6095/6095F/6131 ethernet switch chip support" 16 + config NET_DSA_MV88E6XXX 17 + tristate "Marvell 88E6xxx Ethernet switch chip support" 18 18 depends on NET_DSA 19 - select NET_DSA_MV88E6XXX 20 - select NET_DSA_MV88E6XXX_NEED_PPU 21 - select NET_DSA_TAG_DSA 22 - ---help--- 23 - This enables support for the Marvell 88E6085/6095/6095F/6131 24 - ethernet switch chips. 25 - 26 - config NET_DSA_MV88E6123 27 - tristate "Marvell 88E6123/6161/6165 ethernet switch chip support" 28 - depends on NET_DSA 29 - select NET_DSA_MV88E6XXX 30 19 select NET_DSA_TAG_EDSA 31 20 ---help--- 32 - This enables support for the Marvell 88E6123/6161/6165 33 - ethernet switch chips. 34 - 35 - config NET_DSA_MV88E6171 36 - tristate "Marvell 88E6171/6175/6350/6351 ethernet switch chip support" 37 - depends on NET_DSA 38 - select NET_DSA_MV88E6XXX 39 - select NET_DSA_TAG_EDSA 40 - ---help--- 41 - This enables support for the Marvell 88E6171/6175/6350/6351 42 - ethernet switches chips. 43 - 44 - config NET_DSA_MV88E6352 45 - tristate "Marvell 88E6172/6176/6320/6321/6352 ethernet switch chip support" 46 - depends on NET_DSA 47 - select NET_DSA_MV88E6XXX 48 - select NET_DSA_TAG_EDSA 49 - ---help--- 50 - This enables support for the Marvell 88E6172, 88E6176, 88E6320, 51 - 88E6321 and 88E6352 ethernet switch chips. 21 + This enables support for most of the Marvell 88E6xxx models of 22 + Ethernet switch chips, except 88E6060. 52 23 53 24 config NET_DSA_BCM_SF2 54 25 tristate "Broadcom Starfighter 2 Ethernet switch support"
+1 -14
drivers/net/dsa/Makefile
··· 1 1 obj-$(CONFIG_NET_DSA_MV88E6060) += mv88e6060.o 2 - obj-$(CONFIG_NET_DSA_MV88E6XXX) += mv88e6xxx_drv.o 3 - mv88e6xxx_drv-y += mv88e6xxx.o 4 - ifdef CONFIG_NET_DSA_MV88E6123 5 - mv88e6xxx_drv-y += mv88e6123.o 6 - endif 7 - ifdef CONFIG_NET_DSA_MV88E6131 8 - mv88e6xxx_drv-y += mv88e6131.o 9 - endif 10 - ifdef CONFIG_NET_DSA_MV88E6352 11 - mv88e6xxx_drv-y += mv88e6352.o 12 - endif 13 - ifdef CONFIG_NET_DSA_MV88E6171 14 - mv88e6xxx_drv-y += mv88e6171.o 15 - endif 2 + obj-$(CONFIG_NET_DSA_MV88E6XXX) += mv88e6xxx.o 16 3 obj-$(CONFIG_NET_DSA_BCM_SF2) += bcm_sf2.o
-130
drivers/net/dsa/mv88e6123.c
··· 1 - /* 2 - * net/dsa/mv88e6123_61_65.c - Marvell 88e6123/6161/6165 switch chip support 3 - * Copyright (c) 2008-2009 Marvell Semiconductor 4 - * 5 - * This program is free software; you can redistribute it and/or modify 6 - * it under the terms of the GNU General Public License as published by 7 - * the Free Software Foundation; either version 2 of the License, or 8 - * (at your option) any later version. 9 - */ 10 - 11 - #include <linux/delay.h> 12 - #include <linux/jiffies.h> 13 - #include <linux/list.h> 14 - #include <linux/module.h> 15 - #include <linux/netdevice.h> 16 - #include <linux/phy.h> 17 - #include <net/dsa.h> 18 - #include "mv88e6xxx.h" 19 - 20 - static const struct mv88e6xxx_info mv88e6123_table[] = { 21 - { 22 - .prod_num = PORT_SWITCH_ID_PROD_NUM_6123, 23 - .family = MV88E6XXX_FAMILY_6165, 24 - .name = "Marvell 88E6123", 25 - .num_databases = 4096, 26 - .num_ports = 3, 27 - }, { 28 - .prod_num = PORT_SWITCH_ID_PROD_NUM_6161, 29 - .family = MV88E6XXX_FAMILY_6165, 30 - .name = "Marvell 88E6161", 31 - .num_databases = 4096, 32 - .num_ports = 6, 33 - }, { 34 - .prod_num = PORT_SWITCH_ID_PROD_NUM_6165, 35 - .family = MV88E6XXX_FAMILY_6165, 36 - .name = "Marvell 88E6165", 37 - .num_databases = 4096, 38 - .num_ports = 6, 39 - } 40 - }; 41 - 42 - static const char *mv88e6123_drv_probe(struct device *dsa_dev, 43 - struct device *host_dev, int sw_addr, 44 - void **priv) 45 - { 46 - return mv88e6xxx_drv_probe(dsa_dev, host_dev, sw_addr, priv, 47 - mv88e6123_table, 48 - ARRAY_SIZE(mv88e6123_table)); 49 - } 50 - 51 - static int mv88e6123_setup_global(struct dsa_switch *ds) 52 - { 53 - struct mv88e6xxx_priv_state *ps = ds_to_priv(ds); 54 - u32 upstream_port = dsa_upstream_port(ds); 55 - int ret; 56 - u32 reg; 57 - 58 - ret = mv88e6xxx_setup_global(ds); 59 - if (ret) 60 - return ret; 61 - 62 - /* Disable the PHY polling unit (since there won't be any 63 - * external PHYs to poll), don't discard packets with 64 - * excessive collisions, and mask all interrupt sources. 65 - */ 66 - ret = mv88e6xxx_reg_write(ps, REG_GLOBAL, GLOBAL_CONTROL, 0x0000); 67 - if (ret) 68 - return ret; 69 - 70 - /* Configure the upstream port, and configure the upstream 71 - * port as the port to which ingress and egress monitor frames 72 - * are to be sent. 73 - */ 74 - reg = upstream_port << GLOBAL_MONITOR_CONTROL_INGRESS_SHIFT | 75 - upstream_port << GLOBAL_MONITOR_CONTROL_EGRESS_SHIFT | 76 - upstream_port << GLOBAL_MONITOR_CONTROL_ARP_SHIFT; 77 - ret = mv88e6xxx_reg_write(ps, REG_GLOBAL, GLOBAL_MONITOR_CONTROL, reg); 78 - if (ret) 79 - return ret; 80 - 81 - /* Disable remote management for now, and set the switch's 82 - * DSA device number. 83 - */ 84 - return mv88e6xxx_reg_write(ps, REG_GLOBAL, GLOBAL_CONTROL_2, 85 - ds->index & 0x1f); 86 - } 87 - 88 - static int mv88e6123_setup(struct dsa_switch *ds) 89 - { 90 - struct mv88e6xxx_priv_state *ps = ds_to_priv(ds); 91 - int ret; 92 - 93 - ps->ds = ds; 94 - 95 - ret = mv88e6xxx_setup_common(ps); 96 - if (ret < 0) 97 - return ret; 98 - 99 - ret = mv88e6xxx_switch_reset(ps, false); 100 - if (ret < 0) 101 - return ret; 102 - 103 - ret = mv88e6123_setup_global(ds); 104 - if (ret < 0) 105 - return ret; 106 - 107 - return mv88e6xxx_setup_ports(ds); 108 - } 109 - 110 - struct dsa_switch_driver mv88e6123_switch_driver = { 111 - .tag_protocol = DSA_TAG_PROTO_EDSA, 112 - .probe = mv88e6123_drv_probe, 113 - .setup = mv88e6123_setup, 114 - .set_addr = mv88e6xxx_set_addr_indirect, 115 - .phy_read = mv88e6xxx_phy_read, 116 - .phy_write = mv88e6xxx_phy_write, 117 - .get_strings = mv88e6xxx_get_strings, 118 - .get_ethtool_stats = mv88e6xxx_get_ethtool_stats, 119 - .get_sset_count = mv88e6xxx_get_sset_count, 120 - .adjust_link = mv88e6xxx_adjust_link, 121 - #ifdef CONFIG_NET_DSA_HWMON 122 - .get_temp = mv88e6xxx_get_temp, 123 - #endif 124 - .get_regs_len = mv88e6xxx_get_regs_len, 125 - .get_regs = mv88e6xxx_get_regs, 126 - }; 127 - 128 - MODULE_ALIAS("platform:mv88e6123"); 129 - MODULE_ALIAS("platform:mv88e6161"); 130 - MODULE_ALIAS("platform:mv88e6165");
-204
drivers/net/dsa/mv88e6131.c
··· 1 - /* 2 - * net/dsa/mv88e6131.c - Marvell 88e6095/6095f/6131 switch chip support 3 - * Copyright (c) 2008-2009 Marvell Semiconductor 4 - * 5 - * This program is free software; you can redistribute it and/or modify 6 - * it under the terms of the GNU General Public License as published by 7 - * the Free Software Foundation; either version 2 of the License, or 8 - * (at your option) any later version. 9 - */ 10 - 11 - #include <linux/delay.h> 12 - #include <linux/jiffies.h> 13 - #include <linux/list.h> 14 - #include <linux/module.h> 15 - #include <linux/netdevice.h> 16 - #include <linux/phy.h> 17 - #include <net/dsa.h> 18 - #include "mv88e6xxx.h" 19 - 20 - static const struct mv88e6xxx_info mv88e6131_table[] = { 21 - { 22 - .prod_num = PORT_SWITCH_ID_PROD_NUM_6095, 23 - .family = MV88E6XXX_FAMILY_6095, 24 - .name = "Marvell 88E6095/88E6095F", 25 - .num_databases = 256, 26 - .num_ports = 11, 27 - }, { 28 - .prod_num = PORT_SWITCH_ID_PROD_NUM_6085, 29 - .family = MV88E6XXX_FAMILY_6097, 30 - .name = "Marvell 88E6085", 31 - .num_databases = 4096, 32 - .num_ports = 10, 33 - }, { 34 - .prod_num = PORT_SWITCH_ID_PROD_NUM_6131, 35 - .family = MV88E6XXX_FAMILY_6185, 36 - .name = "Marvell 88E6131", 37 - .num_databases = 256, 38 - .num_ports = 8, 39 - }, { 40 - .prod_num = PORT_SWITCH_ID_PROD_NUM_6185, 41 - .family = MV88E6XXX_FAMILY_6185, 42 - .name = "Marvell 88E6185", 43 - .num_databases = 256, 44 - .num_ports = 10, 45 - } 46 - }; 47 - 48 - static const char *mv88e6131_drv_probe(struct device *dsa_dev, 49 - struct device *host_dev, int sw_addr, 50 - void **priv) 51 - { 52 - return mv88e6xxx_drv_probe(dsa_dev, host_dev, sw_addr, priv, 53 - mv88e6131_table, 54 - ARRAY_SIZE(mv88e6131_table)); 55 - } 56 - 57 - static int mv88e6131_setup_global(struct dsa_switch *ds) 58 - { 59 - struct mv88e6xxx_priv_state *ps = ds_to_priv(ds); 60 - u32 upstream_port = dsa_upstream_port(ds); 61 - int ret; 62 - u32 reg; 63 - 64 - ret = mv88e6xxx_setup_global(ds); 65 - if (ret) 66 - return ret; 67 - 68 - /* Enable the PHY polling unit, don't discard packets with 69 - * excessive collisions, use a weighted fair queueing scheme 70 - * to arbitrate between packet queues, set the maximum frame 71 - * size to 1632, and mask all interrupt sources. 72 - */ 73 - ret = mv88e6xxx_reg_write(ps, REG_GLOBAL, GLOBAL_CONTROL, 74 - GLOBAL_CONTROL_PPU_ENABLE | 75 - GLOBAL_CONTROL_MAX_FRAME_1632); 76 - if (ret) 77 - return ret; 78 - 79 - /* Set the VLAN ethertype to 0x8100. */ 80 - ret = mv88e6xxx_reg_write(ps, REG_GLOBAL, GLOBAL_CORE_TAG_TYPE, 0x8100); 81 - if (ret) 82 - return ret; 83 - 84 - /* Disable ARP mirroring, and configure the upstream port as 85 - * the port to which ingress and egress monitor frames are to 86 - * be sent. 87 - */ 88 - reg = upstream_port << GLOBAL_MONITOR_CONTROL_INGRESS_SHIFT | 89 - upstream_port << GLOBAL_MONITOR_CONTROL_EGRESS_SHIFT | 90 - GLOBAL_MONITOR_CONTROL_ARP_DISABLED; 91 - ret = mv88e6xxx_reg_write(ps, REG_GLOBAL, GLOBAL_MONITOR_CONTROL, reg); 92 - if (ret) 93 - return ret; 94 - 95 - /* Disable cascade port functionality unless this device 96 - * is used in a cascade configuration, and set the switch's 97 - * DSA device number. 98 - */ 99 - if (ds->dst->pd->nr_chips > 1) 100 - ret = mv88e6xxx_reg_write(ps, REG_GLOBAL, GLOBAL_CONTROL_2, 101 - GLOBAL_CONTROL_2_MULTIPLE_CASCADE | 102 - (ds->index & 0x1f)); 103 - else 104 - ret = mv88e6xxx_reg_write(ps, REG_GLOBAL, GLOBAL_CONTROL_2, 105 - GLOBAL_CONTROL_2_NO_CASCADE | 106 - (ds->index & 0x1f)); 107 - if (ret) 108 - return ret; 109 - 110 - /* Force the priority of IGMP/MLD snoop frames and ARP frames 111 - * to the highest setting. 112 - */ 113 - return mv88e6xxx_reg_write(ps, REG_GLOBAL2, GLOBAL2_PRIO_OVERRIDE, 114 - GLOBAL2_PRIO_OVERRIDE_FORCE_SNOOP | 115 - 7 << GLOBAL2_PRIO_OVERRIDE_SNOOP_SHIFT | 116 - GLOBAL2_PRIO_OVERRIDE_FORCE_ARP | 117 - 7 << GLOBAL2_PRIO_OVERRIDE_ARP_SHIFT); 118 - } 119 - 120 - static int mv88e6131_setup(struct dsa_switch *ds) 121 - { 122 - struct mv88e6xxx_priv_state *ps = ds_to_priv(ds); 123 - int ret; 124 - 125 - ps->ds = ds; 126 - 127 - ret = mv88e6xxx_setup_common(ps); 128 - if (ret < 0) 129 - return ret; 130 - 131 - mv88e6xxx_ppu_state_init(ps); 132 - 133 - ret = mv88e6xxx_switch_reset(ps, false); 134 - if (ret < 0) 135 - return ret; 136 - 137 - ret = mv88e6131_setup_global(ds); 138 - if (ret < 0) 139 - return ret; 140 - 141 - return mv88e6xxx_setup_ports(ds); 142 - } 143 - 144 - static int mv88e6131_port_to_phy_addr(struct dsa_switch *ds, int port) 145 - { 146 - struct mv88e6xxx_priv_state *ps = ds_to_priv(ds); 147 - 148 - if (port >= 0 && port < ps->info->num_ports) 149 - return port; 150 - 151 - return -EINVAL; 152 - } 153 - 154 - static int 155 - mv88e6131_phy_read(struct dsa_switch *ds, int port, int regnum) 156 - { 157 - int addr = mv88e6131_port_to_phy_addr(ds, port); 158 - 159 - if (addr < 0) 160 - return addr; 161 - 162 - return mv88e6xxx_phy_read_ppu(ds, addr, regnum); 163 - } 164 - 165 - static int 166 - mv88e6131_phy_write(struct dsa_switch *ds, 167 - int port, int regnum, u16 val) 168 - { 169 - int addr = mv88e6131_port_to_phy_addr(ds, port); 170 - 171 - if (addr < 0) 172 - return addr; 173 - 174 - return mv88e6xxx_phy_write_ppu(ds, addr, regnum, val); 175 - } 176 - 177 - struct dsa_switch_driver mv88e6131_switch_driver = { 178 - .tag_protocol = DSA_TAG_PROTO_DSA, 179 - .probe = mv88e6131_drv_probe, 180 - .setup = mv88e6131_setup, 181 - .set_addr = mv88e6xxx_set_addr_direct, 182 - .phy_read = mv88e6131_phy_read, 183 - .phy_write = mv88e6131_phy_write, 184 - .get_strings = mv88e6xxx_get_strings, 185 - .get_ethtool_stats = mv88e6xxx_get_ethtool_stats, 186 - .get_sset_count = mv88e6xxx_get_sset_count, 187 - .adjust_link = mv88e6xxx_adjust_link, 188 - .port_bridge_join = mv88e6xxx_port_bridge_join, 189 - .port_bridge_leave = mv88e6xxx_port_bridge_leave, 190 - .port_vlan_filtering = mv88e6xxx_port_vlan_filtering, 191 - .port_vlan_prepare = mv88e6xxx_port_vlan_prepare, 192 - .port_vlan_add = mv88e6xxx_port_vlan_add, 193 - .port_vlan_del = mv88e6xxx_port_vlan_del, 194 - .port_vlan_dump = mv88e6xxx_port_vlan_dump, 195 - .port_fdb_prepare = mv88e6xxx_port_fdb_prepare, 196 - .port_fdb_add = mv88e6xxx_port_fdb_add, 197 - .port_fdb_del = mv88e6xxx_port_fdb_del, 198 - .port_fdb_dump = mv88e6xxx_port_fdb_dump, 199 - }; 200 - 201 - MODULE_ALIAS("platform:mv88e6085"); 202 - MODULE_ALIAS("platform:mv88e6095"); 203 - MODULE_ALIAS("platform:mv88e6095f"); 204 - MODULE_ALIAS("platform:mv88e6131");
-151
drivers/net/dsa/mv88e6171.c
··· 1 - /* net/dsa/mv88e6171.c - Marvell 88e6171 switch chip support 2 - * Copyright (c) 2008-2009 Marvell Semiconductor 3 - * Copyright (c) 2014 Claudio Leite <leitec@staticky.com> 4 - * 5 - * This program is free software; you can redistribute it and/or modify 6 - * it under the terms of the GNU General Public License as published by 7 - * the Free Software Foundation; either version 2 of the License, or 8 - * (at your option) any later version. 9 - */ 10 - 11 - #include <linux/delay.h> 12 - #include <linux/jiffies.h> 13 - #include <linux/list.h> 14 - #include <linux/module.h> 15 - #include <linux/netdevice.h> 16 - #include <linux/phy.h> 17 - #include <net/dsa.h> 18 - #include "mv88e6xxx.h" 19 - 20 - static const struct mv88e6xxx_info mv88e6171_table[] = { 21 - { 22 - .prod_num = PORT_SWITCH_ID_PROD_NUM_6171, 23 - .family = MV88E6XXX_FAMILY_6351, 24 - .name = "Marvell 88E6171", 25 - .num_databases = 4096, 26 - .num_ports = 7, 27 - }, { 28 - .prod_num = PORT_SWITCH_ID_PROD_NUM_6175, 29 - .family = MV88E6XXX_FAMILY_6351, 30 - .name = "Marvell 88E6175", 31 - .num_databases = 4096, 32 - .num_ports = 7, 33 - }, { 34 - .prod_num = PORT_SWITCH_ID_PROD_NUM_6350, 35 - .family = MV88E6XXX_FAMILY_6351, 36 - .name = "Marvell 88E6350", 37 - .num_databases = 4096, 38 - .num_ports = 7, 39 - }, { 40 - .prod_num = PORT_SWITCH_ID_PROD_NUM_6351, 41 - .family = MV88E6XXX_FAMILY_6351, 42 - .name = "Marvell 88E6351", 43 - .num_databases = 4096, 44 - .num_ports = 7, 45 - } 46 - }; 47 - 48 - static const char *mv88e6171_drv_probe(struct device *dsa_dev, 49 - struct device *host_dev, int sw_addr, 50 - void **priv) 51 - { 52 - return mv88e6xxx_drv_probe(dsa_dev, host_dev, sw_addr, priv, 53 - mv88e6171_table, 54 - ARRAY_SIZE(mv88e6171_table)); 55 - } 56 - 57 - static int mv88e6171_setup_global(struct dsa_switch *ds) 58 - { 59 - struct mv88e6xxx_priv_state *ps = ds_to_priv(ds); 60 - u32 upstream_port = dsa_upstream_port(ds); 61 - int ret; 62 - u32 reg; 63 - 64 - ret = mv88e6xxx_setup_global(ds); 65 - if (ret) 66 - return ret; 67 - 68 - /* Discard packets with excessive collisions, mask all 69 - * interrupt sources, enable PPU. 70 - */ 71 - ret = mv88e6xxx_reg_write(ps, REG_GLOBAL, GLOBAL_CONTROL, 72 - GLOBAL_CONTROL_PPU_ENABLE | 73 - GLOBAL_CONTROL_DISCARD_EXCESS); 74 - if (ret) 75 - return ret; 76 - 77 - /* Configure the upstream port, and configure the upstream 78 - * port as the port to which ingress and egress monitor frames 79 - * are to be sent. 80 - */ 81 - reg = upstream_port << GLOBAL_MONITOR_CONTROL_INGRESS_SHIFT | 82 - upstream_port << GLOBAL_MONITOR_CONTROL_EGRESS_SHIFT | 83 - upstream_port << GLOBAL_MONITOR_CONTROL_ARP_SHIFT | 84 - upstream_port << GLOBAL_MONITOR_CONTROL_MIRROR_SHIFT; 85 - ret = mv88e6xxx_reg_write(ps, REG_GLOBAL, GLOBAL_MONITOR_CONTROL, reg); 86 - if (ret) 87 - return ret; 88 - 89 - /* Disable remote management for now, and set the switch's 90 - * DSA device number. 91 - */ 92 - return mv88e6xxx_reg_write(ps, REG_GLOBAL, GLOBAL_CONTROL_2, 93 - ds->index & 0x1f); 94 - } 95 - 96 - static int mv88e6171_setup(struct dsa_switch *ds) 97 - { 98 - struct mv88e6xxx_priv_state *ps = ds_to_priv(ds); 99 - int ret; 100 - 101 - ps->ds = ds; 102 - 103 - ret = mv88e6xxx_setup_common(ps); 104 - if (ret < 0) 105 - return ret; 106 - 107 - ret = mv88e6xxx_switch_reset(ps, true); 108 - if (ret < 0) 109 - return ret; 110 - 111 - ret = mv88e6171_setup_global(ds); 112 - if (ret < 0) 113 - return ret; 114 - 115 - return mv88e6xxx_setup_ports(ds); 116 - } 117 - 118 - struct dsa_switch_driver mv88e6171_switch_driver = { 119 - .tag_protocol = DSA_TAG_PROTO_EDSA, 120 - .probe = mv88e6171_drv_probe, 121 - .setup = mv88e6171_setup, 122 - .set_addr = mv88e6xxx_set_addr_indirect, 123 - .phy_read = mv88e6xxx_phy_read_indirect, 124 - .phy_write = mv88e6xxx_phy_write_indirect, 125 - .get_strings = mv88e6xxx_get_strings, 126 - .get_ethtool_stats = mv88e6xxx_get_ethtool_stats, 127 - .get_sset_count = mv88e6xxx_get_sset_count, 128 - .adjust_link = mv88e6xxx_adjust_link, 129 - #ifdef CONFIG_NET_DSA_HWMON 130 - .get_temp = mv88e6xxx_get_temp, 131 - #endif 132 - .get_regs_len = mv88e6xxx_get_regs_len, 133 - .get_regs = mv88e6xxx_get_regs, 134 - .port_bridge_join = mv88e6xxx_port_bridge_join, 135 - .port_bridge_leave = mv88e6xxx_port_bridge_leave, 136 - .port_stp_state_set = mv88e6xxx_port_stp_state_set, 137 - .port_vlan_filtering = mv88e6xxx_port_vlan_filtering, 138 - .port_vlan_prepare = mv88e6xxx_port_vlan_prepare, 139 - .port_vlan_add = mv88e6xxx_port_vlan_add, 140 - .port_vlan_del = mv88e6xxx_port_vlan_del, 141 - .port_vlan_dump = mv88e6xxx_port_vlan_dump, 142 - .port_fdb_prepare = mv88e6xxx_port_fdb_prepare, 143 - .port_fdb_add = mv88e6xxx_port_fdb_add, 144 - .port_fdb_del = mv88e6xxx_port_fdb_del, 145 - .port_fdb_dump = mv88e6xxx_port_fdb_dump, 146 - }; 147 - 148 - MODULE_ALIAS("platform:mv88e6171"); 149 - MODULE_ALIAS("platform:mv88e6175"); 150 - MODULE_ALIAS("platform:mv88e6350"); 151 - MODULE_ALIAS("platform:mv88e6351");
-377
drivers/net/dsa/mv88e6352.c
··· 1 - /* 2 - * net/dsa/mv88e6352.c - Marvell 88e6352 switch chip support 3 - * 4 - * Copyright (c) 2014 Guenter Roeck 5 - * 6 - * Derived from mv88e6123_61_65.c 7 - * Copyright (c) 2008-2009 Marvell Semiconductor 8 - * 9 - * This program is free software; you can redistribute it and/or modify 10 - * it under the terms of the GNU General Public License as published by 11 - * the Free Software Foundation; either version 2 of the License, or 12 - * (at your option) any later version. 13 - */ 14 - 15 - #include <linux/delay.h> 16 - #include <linux/jiffies.h> 17 - #include <linux/list.h> 18 - #include <linux/module.h> 19 - #include <linux/netdevice.h> 20 - #include <linux/platform_device.h> 21 - #include <linux/phy.h> 22 - #include <net/dsa.h> 23 - #include "mv88e6xxx.h" 24 - 25 - static const struct mv88e6xxx_info mv88e6352_table[] = { 26 - { 27 - .prod_num = PORT_SWITCH_ID_PROD_NUM_6320, 28 - .family = MV88E6XXX_FAMILY_6320, 29 - .name = "Marvell 88E6320", 30 - .num_databases = 4096, 31 - .num_ports = 7, 32 - }, { 33 - .prod_num = PORT_SWITCH_ID_PROD_NUM_6321, 34 - .family = MV88E6XXX_FAMILY_6320, 35 - .name = "Marvell 88E6321", 36 - .num_databases = 4096, 37 - .num_ports = 7, 38 - }, { 39 - .prod_num = PORT_SWITCH_ID_PROD_NUM_6172, 40 - .family = MV88E6XXX_FAMILY_6352, 41 - .name = "Marvell 88E6172", 42 - .num_databases = 4096, 43 - .num_ports = 7, 44 - }, { 45 - .prod_num = PORT_SWITCH_ID_PROD_NUM_6176, 46 - .family = MV88E6XXX_FAMILY_6352, 47 - .name = "Marvell 88E6176", 48 - .num_databases = 4096, 49 - .num_ports = 7, 50 - }, { 51 - .prod_num = PORT_SWITCH_ID_PROD_NUM_6240, 52 - .family = MV88E6XXX_FAMILY_6352, 53 - .name = "Marvell 88E6240", 54 - .num_databases = 4096, 55 - .num_ports = 7, 56 - }, { 57 - .prod_num = PORT_SWITCH_ID_PROD_NUM_6352, 58 - .family = MV88E6XXX_FAMILY_6352, 59 - .name = "Marvell 88E6352", 60 - .num_databases = 4096, 61 - .num_ports = 7, 62 - } 63 - }; 64 - 65 - static const char *mv88e6352_drv_probe(struct device *dsa_dev, 66 - struct device *host_dev, int sw_addr, 67 - void **priv) 68 - { 69 - return mv88e6xxx_drv_probe(dsa_dev, host_dev, sw_addr, priv, 70 - mv88e6352_table, 71 - ARRAY_SIZE(mv88e6352_table)); 72 - } 73 - 74 - static int mv88e6352_setup_global(struct dsa_switch *ds) 75 - { 76 - struct mv88e6xxx_priv_state *ps = ds_to_priv(ds); 77 - u32 upstream_port = dsa_upstream_port(ds); 78 - int ret; 79 - u32 reg; 80 - 81 - ret = mv88e6xxx_setup_global(ds); 82 - if (ret) 83 - return ret; 84 - 85 - /* Discard packets with excessive collisions, 86 - * mask all interrupt sources, enable PPU (bit 14, undocumented). 87 - */ 88 - ret = mv88e6xxx_reg_write(ps, REG_GLOBAL, GLOBAL_CONTROL, 89 - GLOBAL_CONTROL_PPU_ENABLE | 90 - GLOBAL_CONTROL_DISCARD_EXCESS); 91 - if (ret) 92 - return ret; 93 - 94 - /* Configure the upstream port, and configure the upstream 95 - * port as the port to which ingress and egress monitor frames 96 - * are to be sent. 97 - */ 98 - reg = upstream_port << GLOBAL_MONITOR_CONTROL_INGRESS_SHIFT | 99 - upstream_port << GLOBAL_MONITOR_CONTROL_EGRESS_SHIFT | 100 - upstream_port << GLOBAL_MONITOR_CONTROL_ARP_SHIFT; 101 - ret = mv88e6xxx_reg_write(ps, REG_GLOBAL, GLOBAL_MONITOR_CONTROL, reg); 102 - if (ret) 103 - return ret; 104 - 105 - /* Disable remote management for now, and set the switch's 106 - * DSA device number. 107 - */ 108 - return mv88e6xxx_reg_write(ps, REG_GLOBAL, 0x1c, ds->index & 0x1f); 109 - } 110 - 111 - static int mv88e6352_setup(struct dsa_switch *ds) 112 - { 113 - struct mv88e6xxx_priv_state *ps = ds_to_priv(ds); 114 - int ret; 115 - 116 - ps->ds = ds; 117 - 118 - ret = mv88e6xxx_setup_common(ps); 119 - if (ret < 0) 120 - return ret; 121 - 122 - mutex_init(&ps->eeprom_mutex); 123 - 124 - ret = mv88e6xxx_switch_reset(ps, true); 125 - if (ret < 0) 126 - return ret; 127 - 128 - ret = mv88e6352_setup_global(ds); 129 - if (ret < 0) 130 - return ret; 131 - 132 - return mv88e6xxx_setup_ports(ds); 133 - } 134 - 135 - static int mv88e6352_read_eeprom_word(struct dsa_switch *ds, int addr) 136 - { 137 - struct mv88e6xxx_priv_state *ps = ds_to_priv(ds); 138 - int ret; 139 - 140 - mutex_lock(&ps->eeprom_mutex); 141 - 142 - ret = mv88e6xxx_reg_write(ps, REG_GLOBAL2, GLOBAL2_EEPROM_OP, 143 - GLOBAL2_EEPROM_OP_READ | 144 - (addr & GLOBAL2_EEPROM_OP_ADDR_MASK)); 145 - if (ret < 0) 146 - goto error; 147 - 148 - ret = mv88e6xxx_eeprom_busy_wait(ds); 149 - if (ret < 0) 150 - goto error; 151 - 152 - ret = mv88e6xxx_reg_read(ps, REG_GLOBAL2, GLOBAL2_EEPROM_DATA); 153 - error: 154 - mutex_unlock(&ps->eeprom_mutex); 155 - return ret; 156 - } 157 - 158 - static int mv88e6352_get_eeprom(struct dsa_switch *ds, 159 - struct ethtool_eeprom *eeprom, u8 *data) 160 - { 161 - int offset; 162 - int len; 163 - int ret; 164 - 165 - offset = eeprom->offset; 166 - len = eeprom->len; 167 - eeprom->len = 0; 168 - 169 - eeprom->magic = 0xc3ec4951; 170 - 171 - ret = mv88e6xxx_eeprom_load_wait(ds); 172 - if (ret < 0) 173 - return ret; 174 - 175 - if (offset & 1) { 176 - int word; 177 - 178 - word = mv88e6352_read_eeprom_word(ds, offset >> 1); 179 - if (word < 0) 180 - return word; 181 - 182 - *data++ = (word >> 8) & 0xff; 183 - 184 - offset++; 185 - len--; 186 - eeprom->len++; 187 - } 188 - 189 - while (len >= 2) { 190 - int word; 191 - 192 - word = mv88e6352_read_eeprom_word(ds, offset >> 1); 193 - if (word < 0) 194 - return word; 195 - 196 - *data++ = word & 0xff; 197 - *data++ = (word >> 8) & 0xff; 198 - 199 - offset += 2; 200 - len -= 2; 201 - eeprom->len += 2; 202 - } 203 - 204 - if (len) { 205 - int word; 206 - 207 - word = mv88e6352_read_eeprom_word(ds, offset >> 1); 208 - if (word < 0) 209 - return word; 210 - 211 - *data++ = word & 0xff; 212 - 213 - offset++; 214 - len--; 215 - eeprom->len++; 216 - } 217 - 218 - return 0; 219 - } 220 - 221 - static int mv88e6352_eeprom_is_readonly(struct dsa_switch *ds) 222 - { 223 - struct mv88e6xxx_priv_state *ps = ds_to_priv(ds); 224 - int ret; 225 - 226 - ret = mv88e6xxx_reg_read(ps, REG_GLOBAL2, GLOBAL2_EEPROM_OP); 227 - if (ret < 0) 228 - return ret; 229 - 230 - if (!(ret & GLOBAL2_EEPROM_OP_WRITE_EN)) 231 - return -EROFS; 232 - 233 - return 0; 234 - } 235 - 236 - static int mv88e6352_write_eeprom_word(struct dsa_switch *ds, int addr, 237 - u16 data) 238 - { 239 - struct mv88e6xxx_priv_state *ps = ds_to_priv(ds); 240 - int ret; 241 - 242 - mutex_lock(&ps->eeprom_mutex); 243 - 244 - ret = mv88e6xxx_reg_write(ps, REG_GLOBAL2, GLOBAL2_EEPROM_DATA, data); 245 - if (ret < 0) 246 - goto error; 247 - 248 - ret = mv88e6xxx_reg_write(ps, REG_GLOBAL2, GLOBAL2_EEPROM_OP, 249 - GLOBAL2_EEPROM_OP_WRITE | 250 - (addr & GLOBAL2_EEPROM_OP_ADDR_MASK)); 251 - if (ret < 0) 252 - goto error; 253 - 254 - ret = mv88e6xxx_eeprom_busy_wait(ds); 255 - error: 256 - mutex_unlock(&ps->eeprom_mutex); 257 - return ret; 258 - } 259 - 260 - static int mv88e6352_set_eeprom(struct dsa_switch *ds, 261 - struct ethtool_eeprom *eeprom, u8 *data) 262 - { 263 - int offset; 264 - int ret; 265 - int len; 266 - 267 - if (eeprom->magic != 0xc3ec4951) 268 - return -EINVAL; 269 - 270 - ret = mv88e6352_eeprom_is_readonly(ds); 271 - if (ret) 272 - return ret; 273 - 274 - offset = eeprom->offset; 275 - len = eeprom->len; 276 - eeprom->len = 0; 277 - 278 - ret = mv88e6xxx_eeprom_load_wait(ds); 279 - if (ret < 0) 280 - return ret; 281 - 282 - if (offset & 1) { 283 - int word; 284 - 285 - word = mv88e6352_read_eeprom_word(ds, offset >> 1); 286 - if (word < 0) 287 - return word; 288 - 289 - word = (*data++ << 8) | (word & 0xff); 290 - 291 - ret = mv88e6352_write_eeprom_word(ds, offset >> 1, word); 292 - if (ret < 0) 293 - return ret; 294 - 295 - offset++; 296 - len--; 297 - eeprom->len++; 298 - } 299 - 300 - while (len >= 2) { 301 - int word; 302 - 303 - word = *data++; 304 - word |= *data++ << 8; 305 - 306 - ret = mv88e6352_write_eeprom_word(ds, offset >> 1, word); 307 - if (ret < 0) 308 - return ret; 309 - 310 - offset += 2; 311 - len -= 2; 312 - eeprom->len += 2; 313 - } 314 - 315 - if (len) { 316 - int word; 317 - 318 - word = mv88e6352_read_eeprom_word(ds, offset >> 1); 319 - if (word < 0) 320 - return word; 321 - 322 - word = (word & 0xff00) | *data++; 323 - 324 - ret = mv88e6352_write_eeprom_word(ds, offset >> 1, word); 325 - if (ret < 0) 326 - return ret; 327 - 328 - offset++; 329 - len--; 330 - eeprom->len++; 331 - } 332 - 333 - return 0; 334 - } 335 - 336 - struct dsa_switch_driver mv88e6352_switch_driver = { 337 - .tag_protocol = DSA_TAG_PROTO_EDSA, 338 - .probe = mv88e6352_drv_probe, 339 - .setup = mv88e6352_setup, 340 - .set_addr = mv88e6xxx_set_addr_indirect, 341 - .phy_read = mv88e6xxx_phy_read_indirect, 342 - .phy_write = mv88e6xxx_phy_write_indirect, 343 - .get_strings = mv88e6xxx_get_strings, 344 - .get_ethtool_stats = mv88e6xxx_get_ethtool_stats, 345 - .get_sset_count = mv88e6xxx_get_sset_count, 346 - .adjust_link = mv88e6xxx_adjust_link, 347 - .set_eee = mv88e6xxx_set_eee, 348 - .get_eee = mv88e6xxx_get_eee, 349 - #ifdef CONFIG_NET_DSA_HWMON 350 - .get_temp = mv88e6xxx_get_temp, 351 - .get_temp_limit = mv88e6xxx_get_temp_limit, 352 - .set_temp_limit = mv88e6xxx_set_temp_limit, 353 - .get_temp_alarm = mv88e6xxx_get_temp_alarm, 354 - #endif 355 - .get_eeprom = mv88e6352_get_eeprom, 356 - .set_eeprom = mv88e6352_set_eeprom, 357 - .get_regs_len = mv88e6xxx_get_regs_len, 358 - .get_regs = mv88e6xxx_get_regs, 359 - .port_bridge_join = mv88e6xxx_port_bridge_join, 360 - .port_bridge_leave = mv88e6xxx_port_bridge_leave, 361 - .port_stp_state_set = mv88e6xxx_port_stp_state_set, 362 - .port_vlan_filtering = mv88e6xxx_port_vlan_filtering, 363 - .port_vlan_prepare = mv88e6xxx_port_vlan_prepare, 364 - .port_vlan_add = mv88e6xxx_port_vlan_add, 365 - .port_vlan_del = mv88e6xxx_port_vlan_del, 366 - .port_vlan_dump = mv88e6xxx_port_vlan_dump, 367 - .port_fdb_prepare = mv88e6xxx_port_fdb_prepare, 368 - .port_fdb_add = mv88e6xxx_port_fdb_add, 369 - .port_fdb_del = mv88e6xxx_port_fdb_del, 370 - .port_fdb_dump = mv88e6xxx_port_fdb_dump, 371 - }; 372 - 373 - MODULE_ALIAS("platform:mv88e6172"); 374 - MODULE_ALIAS("platform:mv88e6176"); 375 - MODULE_ALIAS("platform:mv88e6320"); 376 - MODULE_ALIAS("platform:mv88e6321"); 377 - MODULE_ALIAS("platform:mv88e6352");
+739 -259
drivers/net/dsa/mv88e6xxx.c
··· 173 173 return ret; 174 174 } 175 175 176 - int mv88e6xxx_set_addr_direct(struct dsa_switch *ds, u8 *addr) 176 + static int mv88e6xxx_set_addr_direct(struct dsa_switch *ds, u8 *addr) 177 177 { 178 178 struct mv88e6xxx_priv_state *ps = ds_to_priv(ds); 179 179 int err; ··· 192 192 (addr[4] << 8) | addr[5]); 193 193 } 194 194 195 - int mv88e6xxx_set_addr_indirect(struct dsa_switch *ds, u8 *addr) 195 + static int mv88e6xxx_set_addr_indirect(struct dsa_switch *ds, u8 *addr) 196 196 { 197 197 struct mv88e6xxx_priv_state *ps = ds_to_priv(ds); 198 198 int ret; ··· 225 225 return 0; 226 226 } 227 227 228 + int mv88e6xxx_set_addr(struct dsa_switch *ds, u8 *addr) 229 + { 230 + struct mv88e6xxx_priv_state *ps = ds_to_priv(ds); 231 + 232 + if (mv88e6xxx_has(ps, MV88E6XXX_FLAG_SWITCH_MAC)) 233 + return mv88e6xxx_set_addr_indirect(ds, addr); 234 + else 235 + return mv88e6xxx_set_addr_direct(ds, addr); 236 + } 237 + 228 238 static int _mv88e6xxx_phy_read(struct mv88e6xxx_priv_state *ps, int addr, 229 239 int regnum) 230 240 { ··· 251 241 return 0; 252 242 } 253 243 254 - #ifdef CONFIG_NET_DSA_MV88E6XXX_NEED_PPU 255 244 static int mv88e6xxx_ppu_disable(struct mv88e6xxx_priv_state *ps) 256 245 { 257 246 int ret; 258 247 unsigned long timeout; 259 248 260 - ret = mv88e6xxx_reg_read(ps, REG_GLOBAL, GLOBAL_CONTROL); 249 + ret = _mv88e6xxx_reg_read(ps, REG_GLOBAL, GLOBAL_CONTROL); 261 250 if (ret < 0) 262 251 return ret; 263 252 264 - ret = mv88e6xxx_reg_write(ps, REG_GLOBAL, GLOBAL_CONTROL, 265 - ret & ~GLOBAL_CONTROL_PPU_ENABLE); 253 + ret = _mv88e6xxx_reg_write(ps, REG_GLOBAL, GLOBAL_CONTROL, 254 + ret & ~GLOBAL_CONTROL_PPU_ENABLE); 266 255 if (ret) 267 256 return ret; 268 257 269 258 timeout = jiffies + 1 * HZ; 270 259 while (time_before(jiffies, timeout)) { 271 - ret = mv88e6xxx_reg_read(ps, REG_GLOBAL, GLOBAL_STATUS); 260 + ret = _mv88e6xxx_reg_read(ps, REG_GLOBAL, GLOBAL_STATUS); 272 261 if (ret < 0) 273 262 return ret; 274 263 ··· 370 361 ps->ppu_timer.function = mv88e6xxx_ppu_reenable_timer; 371 362 } 372 363 373 - int mv88e6xxx_phy_read_ppu(struct dsa_switch *ds, int addr, int regnum) 364 + static int mv88e6xxx_phy_read_ppu(struct mv88e6xxx_priv_state *ps, int addr, 365 + int regnum) 374 366 { 375 - struct mv88e6xxx_priv_state *ps = ds_to_priv(ds); 376 367 int ret; 377 368 378 369 ret = mv88e6xxx_ppu_access_get(ps); 379 370 if (ret >= 0) { 380 - ret = mv88e6xxx_reg_read(ps, addr, regnum); 371 + ret = _mv88e6xxx_reg_read(ps, addr, regnum); 381 372 mv88e6xxx_ppu_access_put(ps); 382 373 } 383 374 384 375 return ret; 385 376 } 386 377 387 - int mv88e6xxx_phy_write_ppu(struct dsa_switch *ds, int addr, 388 - int regnum, u16 val) 378 + static int mv88e6xxx_phy_write_ppu(struct mv88e6xxx_priv_state *ps, int addr, 379 + int regnum, u16 val) 389 380 { 390 - struct mv88e6xxx_priv_state *ps = ds_to_priv(ds); 391 381 int ret; 392 382 393 383 ret = mv88e6xxx_ppu_access_get(ps); 394 384 if (ret >= 0) { 395 - ret = mv88e6xxx_reg_write(ps, addr, regnum, val); 385 + ret = _mv88e6xxx_reg_write(ps, addr, regnum, val); 396 386 mv88e6xxx_ppu_access_put(ps); 397 387 } 398 388 399 389 return ret; 400 390 } 401 - #endif 402 391 403 392 static bool mv88e6xxx_6065_family(struct mv88e6xxx_priv_state *ps) 404 393 { ··· 467 460 * phy. However, in the case of a fixed link phy, we force the port 468 461 * settings from the fixed link settings. 469 462 */ 470 - void mv88e6xxx_adjust_link(struct dsa_switch *ds, int port, 471 - struct phy_device *phydev) 463 + static void mv88e6xxx_adjust_link(struct dsa_switch *ds, int port, 464 + struct phy_device *phydev) 472 465 { 473 466 struct mv88e6xxx_priv_state *ps = ds_to_priv(ds); 474 467 u32 reg; ··· 714 707 return value; 715 708 } 716 709 717 - void mv88e6xxx_get_strings(struct dsa_switch *ds, int port, uint8_t *data) 710 + static void mv88e6xxx_get_strings(struct dsa_switch *ds, int port, 711 + uint8_t *data) 718 712 { 719 713 struct mv88e6xxx_priv_state *ps = ds_to_priv(ds); 720 714 struct mv88e6xxx_hw_stat *stat; ··· 731 723 } 732 724 } 733 725 734 - int mv88e6xxx_get_sset_count(struct dsa_switch *ds) 726 + static int mv88e6xxx_get_sset_count(struct dsa_switch *ds) 735 727 { 736 728 struct mv88e6xxx_priv_state *ps = ds_to_priv(ds); 737 729 struct mv88e6xxx_hw_stat *stat; ··· 745 737 return j; 746 738 } 747 739 748 - void 749 - mv88e6xxx_get_ethtool_stats(struct dsa_switch *ds, 750 - int port, uint64_t *data) 740 + static void mv88e6xxx_get_ethtool_stats(struct dsa_switch *ds, int port, 741 + uint64_t *data) 751 742 { 752 743 struct mv88e6xxx_priv_state *ps = ds_to_priv(ds); 753 744 struct mv88e6xxx_hw_stat *stat; ··· 771 764 mutex_unlock(&ps->smi_mutex); 772 765 } 773 766 774 - int mv88e6xxx_get_regs_len(struct dsa_switch *ds, int port) 767 + static int mv88e6xxx_get_regs_len(struct dsa_switch *ds, int port) 775 768 { 776 769 return 32 * sizeof(u16); 777 770 } 778 771 779 - void mv88e6xxx_get_regs(struct dsa_switch *ds, int port, 780 - struct ethtool_regs *regs, void *_p) 772 + static void mv88e6xxx_get_regs(struct dsa_switch *ds, int port, 773 + struct ethtool_regs *regs, void *_p) 781 774 { 782 775 struct mv88e6xxx_priv_state *ps = ds_to_priv(ds); 783 776 u16 *p = _p; ··· 787 780 788 781 memset(p, 0xff, 32 * sizeof(u16)); 789 782 783 + mutex_lock(&ps->smi_mutex); 784 + 790 785 for (i = 0; i < 32; i++) { 791 786 int ret; 792 787 793 - ret = mv88e6xxx_reg_read(ps, REG_PORT(port), i); 788 + ret = _mv88e6xxx_reg_read(ps, REG_PORT(port), i); 794 789 if (ret >= 0) 795 790 p[i] = ret; 796 791 } 792 + 793 + mutex_unlock(&ps->smi_mutex); 797 794 } 798 795 799 796 static int _mv88e6xxx_wait(struct mv88e6xxx_priv_state *ps, int reg, int offset, ··· 837 826 GLOBAL2_SMI_OP_BUSY); 838 827 } 839 828 840 - int mv88e6xxx_eeprom_load_wait(struct dsa_switch *ds) 829 + static int mv88e6xxx_eeprom_load_wait(struct dsa_switch *ds) 841 830 { 842 831 struct mv88e6xxx_priv_state *ps = ds_to_priv(ds); 843 832 ··· 845 834 GLOBAL2_EEPROM_OP_LOAD); 846 835 } 847 836 848 - int mv88e6xxx_eeprom_busy_wait(struct dsa_switch *ds) 837 + static int mv88e6xxx_eeprom_busy_wait(struct dsa_switch *ds) 849 838 { 850 839 struct mv88e6xxx_priv_state *ps = ds_to_priv(ds); 851 840 852 841 return mv88e6xxx_wait(ps, REG_GLOBAL2, GLOBAL2_EEPROM_OP, 853 842 GLOBAL2_EEPROM_OP_BUSY); 843 + } 844 + 845 + static int mv88e6xxx_read_eeprom_word(struct dsa_switch *ds, int addr) 846 + { 847 + struct mv88e6xxx_priv_state *ps = ds_to_priv(ds); 848 + int ret; 849 + 850 + mutex_lock(&ps->eeprom_mutex); 851 + 852 + ret = mv88e6xxx_reg_write(ps, REG_GLOBAL2, GLOBAL2_EEPROM_OP, 853 + GLOBAL2_EEPROM_OP_READ | 854 + (addr & GLOBAL2_EEPROM_OP_ADDR_MASK)); 855 + if (ret < 0) 856 + goto error; 857 + 858 + ret = mv88e6xxx_eeprom_busy_wait(ds); 859 + if (ret < 0) 860 + goto error; 861 + 862 + ret = mv88e6xxx_reg_read(ps, REG_GLOBAL2, GLOBAL2_EEPROM_DATA); 863 + error: 864 + mutex_unlock(&ps->eeprom_mutex); 865 + return ret; 866 + } 867 + 868 + static int mv88e6xxx_get_eeprom(struct dsa_switch *ds, 869 + struct ethtool_eeprom *eeprom, u8 *data) 870 + { 871 + struct mv88e6xxx_priv_state *ps = ds_to_priv(ds); 872 + int offset; 873 + int len; 874 + int ret; 875 + 876 + if (!mv88e6xxx_has(ps, MV88E6XXX_FLAG_EEPROM)) 877 + return -EOPNOTSUPP; 878 + 879 + offset = eeprom->offset; 880 + len = eeprom->len; 881 + eeprom->len = 0; 882 + 883 + eeprom->magic = 0xc3ec4951; 884 + 885 + ret = mv88e6xxx_eeprom_load_wait(ds); 886 + if (ret < 0) 887 + return ret; 888 + 889 + if (offset & 1) { 890 + int word; 891 + 892 + word = mv88e6xxx_read_eeprom_word(ds, offset >> 1); 893 + if (word < 0) 894 + return word; 895 + 896 + *data++ = (word >> 8) & 0xff; 897 + 898 + offset++; 899 + len--; 900 + eeprom->len++; 901 + } 902 + 903 + while (len >= 2) { 904 + int word; 905 + 906 + word = mv88e6xxx_read_eeprom_word(ds, offset >> 1); 907 + if (word < 0) 908 + return word; 909 + 910 + *data++ = word & 0xff; 911 + *data++ = (word >> 8) & 0xff; 912 + 913 + offset += 2; 914 + len -= 2; 915 + eeprom->len += 2; 916 + } 917 + 918 + if (len) { 919 + int word; 920 + 921 + word = mv88e6xxx_read_eeprom_word(ds, offset >> 1); 922 + if (word < 0) 923 + return word; 924 + 925 + *data++ = word & 0xff; 926 + 927 + offset++; 928 + len--; 929 + eeprom->len++; 930 + } 931 + 932 + return 0; 933 + } 934 + 935 + static int mv88e6xxx_eeprom_is_readonly(struct dsa_switch *ds) 936 + { 937 + struct mv88e6xxx_priv_state *ps = ds_to_priv(ds); 938 + int ret; 939 + 940 + ret = mv88e6xxx_reg_read(ps, REG_GLOBAL2, GLOBAL2_EEPROM_OP); 941 + if (ret < 0) 942 + return ret; 943 + 944 + if (!(ret & GLOBAL2_EEPROM_OP_WRITE_EN)) 945 + return -EROFS; 946 + 947 + return 0; 948 + } 949 + 950 + static int mv88e6xxx_write_eeprom_word(struct dsa_switch *ds, int addr, 951 + u16 data) 952 + { 953 + struct mv88e6xxx_priv_state *ps = ds_to_priv(ds); 954 + int ret; 955 + 956 + mutex_lock(&ps->eeprom_mutex); 957 + 958 + ret = mv88e6xxx_reg_write(ps, REG_GLOBAL2, GLOBAL2_EEPROM_DATA, data); 959 + if (ret < 0) 960 + goto error; 961 + 962 + ret = mv88e6xxx_reg_write(ps, REG_GLOBAL2, GLOBAL2_EEPROM_OP, 963 + GLOBAL2_EEPROM_OP_WRITE | 964 + (addr & GLOBAL2_EEPROM_OP_ADDR_MASK)); 965 + if (ret < 0) 966 + goto error; 967 + 968 + ret = mv88e6xxx_eeprom_busy_wait(ds); 969 + error: 970 + mutex_unlock(&ps->eeprom_mutex); 971 + return ret; 972 + } 973 + 974 + static int mv88e6xxx_set_eeprom(struct dsa_switch *ds, 975 + struct ethtool_eeprom *eeprom, u8 *data) 976 + { 977 + struct mv88e6xxx_priv_state *ps = ds_to_priv(ds); 978 + int offset; 979 + int ret; 980 + int len; 981 + 982 + if (!mv88e6xxx_has(ps, MV88E6XXX_FLAG_EEPROM)) 983 + return -EOPNOTSUPP; 984 + 985 + if (eeprom->magic != 0xc3ec4951) 986 + return -EINVAL; 987 + 988 + ret = mv88e6xxx_eeprom_is_readonly(ds); 989 + if (ret) 990 + return ret; 991 + 992 + offset = eeprom->offset; 993 + len = eeprom->len; 994 + eeprom->len = 0; 995 + 996 + ret = mv88e6xxx_eeprom_load_wait(ds); 997 + if (ret < 0) 998 + return ret; 999 + 1000 + if (offset & 1) { 1001 + int word; 1002 + 1003 + word = mv88e6xxx_read_eeprom_word(ds, offset >> 1); 1004 + if (word < 0) 1005 + return word; 1006 + 1007 + word = (*data++ << 8) | (word & 0xff); 1008 + 1009 + ret = mv88e6xxx_write_eeprom_word(ds, offset >> 1, word); 1010 + if (ret < 0) 1011 + return ret; 1012 + 1013 + offset++; 1014 + len--; 1015 + eeprom->len++; 1016 + } 1017 + 1018 + while (len >= 2) { 1019 + int word; 1020 + 1021 + word = *data++; 1022 + word |= *data++ << 8; 1023 + 1024 + ret = mv88e6xxx_write_eeprom_word(ds, offset >> 1, word); 1025 + if (ret < 0) 1026 + return ret; 1027 + 1028 + offset += 2; 1029 + len -= 2; 1030 + eeprom->len += 2; 1031 + } 1032 + 1033 + if (len) { 1034 + int word; 1035 + 1036 + word = mv88e6xxx_read_eeprom_word(ds, offset >> 1); 1037 + if (word < 0) 1038 + return word; 1039 + 1040 + word = (word & 0xff00) | *data++; 1041 + 1042 + ret = mv88e6xxx_write_eeprom_word(ds, offset >> 1, word); 1043 + if (ret < 0) 1044 + return ret; 1045 + 1046 + offset++; 1047 + len--; 1048 + eeprom->len++; 1049 + } 1050 + 1051 + return 0; 854 1052 } 855 1053 856 1054 static int _mv88e6xxx_atu_wait(struct mv88e6xxx_priv_state *ps) ··· 1104 884 return _mv88e6xxx_phy_wait(ps); 1105 885 } 1106 886 1107 - int mv88e6xxx_get_eee(struct dsa_switch *ds, int port, struct ethtool_eee *e) 887 + static int mv88e6xxx_get_eee(struct dsa_switch *ds, int port, 888 + struct ethtool_eee *e) 1108 889 { 1109 890 struct mv88e6xxx_priv_state *ps = ds_to_priv(ds); 1110 891 int reg; 892 + 893 + if (!mv88e6xxx_has(ps, MV88E6XXX_FLAG_EEE)) 894 + return -EOPNOTSUPP; 1111 895 1112 896 mutex_lock(&ps->smi_mutex); 1113 897 ··· 1134 910 return reg; 1135 911 } 1136 912 1137 - int mv88e6xxx_set_eee(struct dsa_switch *ds, int port, 1138 - struct phy_device *phydev, struct ethtool_eee *e) 913 + static int mv88e6xxx_set_eee(struct dsa_switch *ds, int port, 914 + struct phy_device *phydev, struct ethtool_eee *e) 1139 915 { 1140 916 struct mv88e6xxx_priv_state *ps = ds_to_priv(ds); 1141 917 int reg; 1142 918 int ret; 919 + 920 + if (!mv88e6xxx_has(ps, MV88E6XXX_FLAG_EEE)) 921 + return -EOPNOTSUPP; 1143 922 1144 923 mutex_lock(&ps->smi_mutex); 1145 924 ··· 1365 1138 return _mv88e6xxx_reg_write(ps, REG_PORT(port), PORT_BASE_VLAN, reg); 1366 1139 } 1367 1140 1368 - void mv88e6xxx_port_stp_state_set(struct dsa_switch *ds, int port, u8 state) 1141 + static void mv88e6xxx_port_stp_state_set(struct dsa_switch *ds, int port, 1142 + u8 state) 1369 1143 { 1370 1144 struct mv88e6xxx_priv_state *ps = ds_to_priv(ds); 1371 1145 int stp_state; 1146 + 1147 + if (!mv88e6xxx_has(ps, MV88E6XXX_FLAG_PORTSTATE)) 1148 + return; 1372 1149 1373 1150 switch (state) { 1374 1151 case BR_STATE_DISABLED: ··· 1589 1358 return 0; 1590 1359 } 1591 1360 1592 - int mv88e6xxx_port_vlan_dump(struct dsa_switch *ds, int port, 1593 - struct switchdev_obj_port_vlan *vlan, 1594 - int (*cb)(struct switchdev_obj *obj)) 1361 + static int mv88e6xxx_port_vlan_dump(struct dsa_switch *ds, int port, 1362 + struct switchdev_obj_port_vlan *vlan, 1363 + int (*cb)(struct switchdev_obj *obj)) 1595 1364 { 1596 1365 struct mv88e6xxx_priv_state *ps = ds_to_priv(ds); 1597 1366 struct mv88e6xxx_vtu_stu_entry next; 1598 1367 u16 pvid; 1599 1368 int err; 1369 + 1370 + if (!mv88e6xxx_has(ps, MV88E6XXX_FLAG_VTU)) 1371 + return -EOPNOTSUPP; 1600 1372 1601 1373 mutex_lock(&ps->smi_mutex); 1602 1374 ··· 2016 1782 [PORT_CONTROL_2_8021Q_SECURE] = "Secure", 2017 1783 }; 2018 1784 2019 - int mv88e6xxx_port_vlan_filtering(struct dsa_switch *ds, int port, 2020 - bool vlan_filtering) 1785 + static int mv88e6xxx_port_vlan_filtering(struct dsa_switch *ds, int port, 1786 + bool vlan_filtering) 2021 1787 { 2022 1788 struct mv88e6xxx_priv_state *ps = ds_to_priv(ds); 2023 1789 u16 old, new = vlan_filtering ? PORT_CONTROL_2_8021Q_SECURE : 2024 1790 PORT_CONTROL_2_8021Q_DISABLED; 2025 1791 int ret; 1792 + 1793 + if (!mv88e6xxx_has(ps, MV88E6XXX_FLAG_VTU)) 1794 + return -EOPNOTSUPP; 2026 1795 2027 1796 mutex_lock(&ps->smi_mutex); 2028 1797 ··· 2056 1819 return ret; 2057 1820 } 2058 1821 2059 - int mv88e6xxx_port_vlan_prepare(struct dsa_switch *ds, int port, 2060 - const struct switchdev_obj_port_vlan *vlan, 2061 - struct switchdev_trans *trans) 1822 + static int mv88e6xxx_port_vlan_prepare(struct dsa_switch *ds, int port, 1823 + const struct switchdev_obj_port_vlan *vlan, 1824 + struct switchdev_trans *trans) 2062 1825 { 1826 + struct mv88e6xxx_priv_state *ps = ds_to_priv(ds); 2063 1827 int err; 1828 + 1829 + if (!mv88e6xxx_has(ps, MV88E6XXX_FLAG_VTU)) 1830 + return -EOPNOTSUPP; 2064 1831 2065 1832 /* If the requested port doesn't belong to the same bridge as the VLAN 2066 1833 * members, do not support it (yet) and fallback to software VLAN. ··· 2097 1856 return _mv88e6xxx_vtu_loadpurge(ps, &vlan); 2098 1857 } 2099 1858 2100 - void mv88e6xxx_port_vlan_add(struct dsa_switch *ds, int port, 2101 - const struct switchdev_obj_port_vlan *vlan, 2102 - struct switchdev_trans *trans) 1859 + static void mv88e6xxx_port_vlan_add(struct dsa_switch *ds, int port, 1860 + const struct switchdev_obj_port_vlan *vlan, 1861 + struct switchdev_trans *trans) 2103 1862 { 2104 1863 struct mv88e6xxx_priv_state *ps = ds_to_priv(ds); 2105 1864 bool untagged = vlan->flags & BRIDGE_VLAN_INFO_UNTAGGED; 2106 1865 bool pvid = vlan->flags & BRIDGE_VLAN_INFO_PVID; 2107 1866 u16 vid; 1867 + 1868 + if (!mv88e6xxx_has(ps, MV88E6XXX_FLAG_VTU)) 1869 + return; 2108 1870 2109 1871 mutex_lock(&ps->smi_mutex); 2110 1872 ··· 2159 1915 return _mv88e6xxx_atu_remove(ps, vlan.fid, port, false); 2160 1916 } 2161 1917 2162 - int mv88e6xxx_port_vlan_del(struct dsa_switch *ds, int port, 2163 - const struct switchdev_obj_port_vlan *vlan) 1918 + static int mv88e6xxx_port_vlan_del(struct dsa_switch *ds, int port, 1919 + const struct switchdev_obj_port_vlan *vlan) 2164 1920 { 2165 1921 struct mv88e6xxx_priv_state *ps = ds_to_priv(ds); 2166 1922 u16 pvid, vid; 2167 1923 int err = 0; 1924 + 1925 + if (!mv88e6xxx_has(ps, MV88E6XXX_FLAG_VTU)) 1926 + return -EOPNOTSUPP; 2168 1927 2169 1928 mutex_lock(&ps->smi_mutex); 2170 1929 ··· 2273 2026 return _mv88e6xxx_atu_load(ps, &entry); 2274 2027 } 2275 2028 2276 - int mv88e6xxx_port_fdb_prepare(struct dsa_switch *ds, int port, 2277 - const struct switchdev_obj_port_fdb *fdb, 2278 - struct switchdev_trans *trans) 2029 + static int mv88e6xxx_port_fdb_prepare(struct dsa_switch *ds, int port, 2030 + const struct switchdev_obj_port_fdb *fdb, 2031 + struct switchdev_trans *trans) 2279 2032 { 2033 + struct mv88e6xxx_priv_state *ps = ds_to_priv(ds); 2034 + 2035 + if (!mv88e6xxx_has(ps, MV88E6XXX_FLAG_ATU)) 2036 + return -EOPNOTSUPP; 2037 + 2280 2038 /* We don't need any dynamic resource from the kernel (yet), 2281 2039 * so skip the prepare phase. 2282 2040 */ 2283 2041 return 0; 2284 2042 } 2285 2043 2286 - void mv88e6xxx_port_fdb_add(struct dsa_switch *ds, int port, 2287 - const struct switchdev_obj_port_fdb *fdb, 2288 - struct switchdev_trans *trans) 2044 + static void mv88e6xxx_port_fdb_add(struct dsa_switch *ds, int port, 2045 + const struct switchdev_obj_port_fdb *fdb, 2046 + struct switchdev_trans *trans) 2289 2047 { 2290 2048 int state = is_multicast_ether_addr(fdb->addr) ? 2291 2049 GLOBAL_ATU_DATA_STATE_MC_STATIC : 2292 2050 GLOBAL_ATU_DATA_STATE_UC_STATIC; 2293 2051 struct mv88e6xxx_priv_state *ps = ds_to_priv(ds); 2052 + 2053 + if (!mv88e6xxx_has(ps, MV88E6XXX_FLAG_ATU)) 2054 + return; 2294 2055 2295 2056 mutex_lock(&ps->smi_mutex); 2296 2057 if (_mv88e6xxx_port_fdb_load(ps, port, fdb->addr, fdb->vid, state)) ··· 2306 2051 mutex_unlock(&ps->smi_mutex); 2307 2052 } 2308 2053 2309 - int mv88e6xxx_port_fdb_del(struct dsa_switch *ds, int port, 2310 - const struct switchdev_obj_port_fdb *fdb) 2054 + static int mv88e6xxx_port_fdb_del(struct dsa_switch *ds, int port, 2055 + const struct switchdev_obj_port_fdb *fdb) 2311 2056 { 2312 2057 struct mv88e6xxx_priv_state *ps = ds_to_priv(ds); 2313 2058 int ret; 2059 + 2060 + if (!mv88e6xxx_has(ps, MV88E6XXX_FLAG_ATU)) 2061 + return -EOPNOTSUPP; 2314 2062 2315 2063 mutex_lock(&ps->smi_mutex); 2316 2064 ret = _mv88e6xxx_port_fdb_load(ps, port, fdb->addr, fdb->vid, ··· 2409 2151 return err; 2410 2152 } 2411 2153 2412 - int mv88e6xxx_port_fdb_dump(struct dsa_switch *ds, int port, 2413 - struct switchdev_obj_port_fdb *fdb, 2414 - int (*cb)(struct switchdev_obj *obj)) 2154 + static int mv88e6xxx_port_fdb_dump(struct dsa_switch *ds, int port, 2155 + struct switchdev_obj_port_fdb *fdb, 2156 + int (*cb)(struct switchdev_obj *obj)) 2415 2157 { 2416 2158 struct mv88e6xxx_priv_state *ps = ds_to_priv(ds); 2417 2159 struct mv88e6xxx_vtu_stu_entry vlan = { ··· 2419 2161 }; 2420 2162 u16 fid; 2421 2163 int err; 2164 + 2165 + if (!mv88e6xxx_has(ps, MV88E6XXX_FLAG_ATU)) 2166 + return -EOPNOTSUPP; 2422 2167 2423 2168 mutex_lock(&ps->smi_mutex); 2424 2169 ··· 2459 2198 return err; 2460 2199 } 2461 2200 2462 - int mv88e6xxx_port_bridge_join(struct dsa_switch *ds, int port, 2463 - struct net_device *bridge) 2201 + static int mv88e6xxx_port_bridge_join(struct dsa_switch *ds, int port, 2202 + struct net_device *bridge) 2464 2203 { 2465 2204 struct mv88e6xxx_priv_state *ps = ds_to_priv(ds); 2466 2205 int i, err = 0; 2206 + 2207 + if (!mv88e6xxx_has(ps, MV88E6XXX_FLAG_VLANTABLE)) 2208 + return -EOPNOTSUPP; 2467 2209 2468 2210 mutex_lock(&ps->smi_mutex); 2469 2211 ··· 2486 2222 return err; 2487 2223 } 2488 2224 2489 - void mv88e6xxx_port_bridge_leave(struct dsa_switch *ds, int port) 2225 + static void mv88e6xxx_port_bridge_leave(struct dsa_switch *ds, int port) 2490 2226 { 2491 2227 struct mv88e6xxx_priv_state *ps = ds_to_priv(ds); 2492 2228 struct net_device *bridge = ps->ports[port].bridge_dev; 2493 2229 int i; 2230 + 2231 + if (!mv88e6xxx_has(ps, MV88E6XXX_FLAG_VLANTABLE)) 2232 + return; 2494 2233 2495 2234 mutex_lock(&ps->smi_mutex); 2496 2235 ··· 2561 2294 return ret; 2562 2295 } 2563 2296 2297 + static int mv88e6xxx_switch_reset(struct mv88e6xxx_priv_state *ps) 2298 + { 2299 + bool ppu_active = mv88e6xxx_has(ps, MV88E6XXX_FLAG_PPU_ACTIVE); 2300 + u16 is_reset = (ppu_active ? 0x8800 : 0xc800); 2301 + struct gpio_desc *gpiod = ps->ds->pd->reset; 2302 + unsigned long timeout; 2303 + int ret; 2304 + int i; 2305 + 2306 + /* Set all ports to the disabled state. */ 2307 + for (i = 0; i < ps->info->num_ports; i++) { 2308 + ret = _mv88e6xxx_reg_read(ps, REG_PORT(i), PORT_CONTROL); 2309 + if (ret < 0) 2310 + return ret; 2311 + 2312 + ret = _mv88e6xxx_reg_write(ps, REG_PORT(i), PORT_CONTROL, 2313 + ret & 0xfffc); 2314 + if (ret) 2315 + return ret; 2316 + } 2317 + 2318 + /* Wait for transmit queues to drain. */ 2319 + usleep_range(2000, 4000); 2320 + 2321 + /* If there is a gpio connected to the reset pin, toggle it */ 2322 + if (gpiod) { 2323 + gpiod_set_value_cansleep(gpiod, 1); 2324 + usleep_range(10000, 20000); 2325 + gpiod_set_value_cansleep(gpiod, 0); 2326 + usleep_range(10000, 20000); 2327 + } 2328 + 2329 + /* Reset the switch. Keep the PPU active if requested. The PPU 2330 + * needs to be active to support indirect phy register access 2331 + * through global registers 0x18 and 0x19. 2332 + */ 2333 + if (ppu_active) 2334 + ret = _mv88e6xxx_reg_write(ps, REG_GLOBAL, 0x04, 0xc000); 2335 + else 2336 + ret = _mv88e6xxx_reg_write(ps, REG_GLOBAL, 0x04, 0xc400); 2337 + if (ret) 2338 + return ret; 2339 + 2340 + /* Wait up to one second for reset to complete. */ 2341 + timeout = jiffies + 1 * HZ; 2342 + while (time_before(jiffies, timeout)) { 2343 + ret = _mv88e6xxx_reg_read(ps, REG_GLOBAL, 0x00); 2344 + if (ret < 0) 2345 + return ret; 2346 + 2347 + if ((ret & is_reset) == is_reset) 2348 + break; 2349 + usleep_range(1000, 2000); 2350 + } 2351 + if (time_after(jiffies, timeout)) 2352 + ret = -ETIMEDOUT; 2353 + else 2354 + ret = 0; 2355 + 2356 + return ret; 2357 + } 2358 + 2564 2359 static int mv88e6xxx_power_on_serdes(struct mv88e6xxx_priv_state *ps) 2565 2360 { 2566 2361 int ret; ··· 2642 2313 return ret; 2643 2314 } 2644 2315 2645 - static int mv88e6xxx_setup_port(struct dsa_switch *ds, int port) 2316 + static int mv88e6xxx_setup_port(struct mv88e6xxx_priv_state *ps, int port) 2646 2317 { 2647 - struct mv88e6xxx_priv_state *ps = ds_to_priv(ds); 2318 + struct dsa_switch *ds = ps->ds; 2648 2319 int ret; 2649 2320 u16 reg; 2650 - 2651 - mutex_lock(&ps->smi_mutex); 2652 2321 2653 2322 if (mv88e6xxx_6352_family(ps) || mv88e6xxx_6351_family(ps) || 2654 2323 mv88e6xxx_6165_family(ps) || mv88e6xxx_6097_family(ps) || ··· 2676 2349 ret = _mv88e6xxx_reg_write(ps, REG_PORT(port), 2677 2350 PORT_PCS_CTRL, reg); 2678 2351 if (ret) 2679 - goto abort; 2352 + return ret; 2680 2353 } 2681 2354 2682 2355 /* Port Control: disable Drop-on-Unlock, disable Drop-on-Lock, ··· 2740 2413 ret = _mv88e6xxx_reg_write(ps, REG_PORT(port), 2741 2414 PORT_CONTROL, reg); 2742 2415 if (ret) 2743 - goto abort; 2416 + return ret; 2744 2417 } 2745 2418 2746 2419 /* If this port is connected to a SerDes, make sure the SerDes is not ··· 2749 2422 if (mv88e6xxx_6352_family(ps)) { 2750 2423 ret = _mv88e6xxx_reg_read(ps, REG_PORT(port), PORT_STATUS); 2751 2424 if (ret < 0) 2752 - goto abort; 2425 + return ret; 2753 2426 ret &= PORT_STATUS_CMODE_MASK; 2754 2427 if ((ret == PORT_STATUS_CMODE_100BASE_X) || 2755 2428 (ret == PORT_STATUS_CMODE_1000BASE_X) || 2756 2429 (ret == PORT_STATUS_CMODE_SGMII)) { 2757 2430 ret = mv88e6xxx_power_on_serdes(ps); 2758 2431 if (ret < 0) 2759 - goto abort; 2432 + return ret; 2760 2433 } 2761 2434 } 2762 2435 ··· 2793 2466 ret = _mv88e6xxx_reg_write(ps, REG_PORT(port), 2794 2467 PORT_CONTROL_2, reg); 2795 2468 if (ret) 2796 - goto abort; 2469 + return ret; 2797 2470 } 2798 2471 2799 2472 /* Port Association Vector: when learning source addresses ··· 2808 2481 2809 2482 ret = _mv88e6xxx_reg_write(ps, REG_PORT(port), PORT_ASSOC_VECTOR, reg); 2810 2483 if (ret) 2811 - goto abort; 2484 + return ret; 2812 2485 2813 2486 /* Egress rate control 2: disable egress rate control. */ 2814 2487 ret = _mv88e6xxx_reg_write(ps, REG_PORT(port), PORT_RATE_CONTROL_2, 2815 2488 0x0000); 2816 2489 if (ret) 2817 - goto abort; 2490 + return ret; 2818 2491 2819 2492 if (mv88e6xxx_6352_family(ps) || mv88e6xxx_6351_family(ps) || 2820 2493 mv88e6xxx_6165_family(ps) || mv88e6xxx_6097_family(ps) || ··· 2826 2499 ret = _mv88e6xxx_reg_write(ps, REG_PORT(port), 2827 2500 PORT_PAUSE_CTRL, 0x0000); 2828 2501 if (ret) 2829 - goto abort; 2502 + return ret; 2830 2503 2831 2504 /* Port ATU control: disable limiting the number of 2832 2505 * address database entries that this port is allowed ··· 2840 2513 ret = _mv88e6xxx_reg_write(ps, REG_PORT(port), 2841 2514 PORT_PRI_OVERRIDE, 0x0000); 2842 2515 if (ret) 2843 - goto abort; 2516 + return ret; 2844 2517 2845 2518 /* Port Ethertype: use the Ethertype DSA Ethertype 2846 2519 * value. ··· 2848 2521 ret = _mv88e6xxx_reg_write(ps, REG_PORT(port), 2849 2522 PORT_ETH_TYPE, ETH_P_EDSA); 2850 2523 if (ret) 2851 - goto abort; 2524 + return ret; 2852 2525 /* Tag Remap: use an identity 802.1p prio -> switch 2853 2526 * prio mapping. 2854 2527 */ 2855 2528 ret = _mv88e6xxx_reg_write(ps, REG_PORT(port), 2856 2529 PORT_TAG_REGMAP_0123, 0x3210); 2857 2530 if (ret) 2858 - goto abort; 2531 + return ret; 2859 2532 2860 2533 /* Tag Remap 2: use an identity 802.1p prio -> switch 2861 2534 * prio mapping. ··· 2863 2536 ret = _mv88e6xxx_reg_write(ps, REG_PORT(port), 2864 2537 PORT_TAG_REGMAP_4567, 0x7654); 2865 2538 if (ret) 2866 - goto abort; 2539 + return ret; 2867 2540 } 2868 2541 2869 2542 if (mv88e6xxx_6352_family(ps) || mv88e6xxx_6351_family(ps) || ··· 2874 2547 ret = _mv88e6xxx_reg_write(ps, REG_PORT(port), 2875 2548 PORT_RATE_CONTROL, 0x0001); 2876 2549 if (ret) 2877 - goto abort; 2550 + return ret; 2878 2551 } 2879 2552 2880 2553 /* Port Control 1: disable trunking, disable sending ··· 2882 2555 */ 2883 2556 ret = _mv88e6xxx_reg_write(ps, REG_PORT(port), PORT_CONTROL_1, 0x0000); 2884 2557 if (ret) 2885 - goto abort; 2558 + return ret; 2886 2559 2887 2560 /* Port based VLAN map: give each port the same default address 2888 2561 * database, and allow bidirectional communication between the ··· 2890 2563 */ 2891 2564 ret = _mv88e6xxx_port_fid_set(ps, port, 0); 2892 2565 if (ret) 2893 - goto abort; 2566 + return ret; 2894 2567 2895 2568 ret = _mv88e6xxx_port_based_vlan_map(ps, port); 2896 2569 if (ret) 2897 - goto abort; 2570 + return ret; 2898 2571 2899 2572 /* Default VLAN ID and priority: don't set a default VLAN 2900 2573 * ID, and set the default packet priority to zero. 2901 2574 */ 2902 2575 ret = _mv88e6xxx_reg_write(ps, REG_PORT(port), PORT_DEFAULT_VLAN, 2903 2576 0x0000); 2904 - abort: 2905 - mutex_unlock(&ps->smi_mutex); 2906 - return ret; 2907 - } 2908 - 2909 - int mv88e6xxx_setup_ports(struct dsa_switch *ds) 2910 - { 2911 - struct mv88e6xxx_priv_state *ps = ds_to_priv(ds); 2912 - int ret; 2913 - int i; 2914 - 2915 - for (i = 0; i < ps->info->num_ports; i++) { 2916 - ret = mv88e6xxx_setup_port(ds, i); 2917 - if (ret < 0) 2918 - return ret; 2919 - } 2920 - return 0; 2921 - } 2922 - 2923 - int mv88e6xxx_setup_common(struct mv88e6xxx_priv_state *ps) 2924 - { 2925 - mutex_init(&ps->smi_mutex); 2926 - 2927 - INIT_WORK(&ps->bridge_work, mv88e6xxx_bridge_work); 2577 + if (ret) 2578 + return ret; 2928 2579 2929 2580 return 0; 2930 2581 } 2931 2582 2932 - int mv88e6xxx_setup_global(struct dsa_switch *ds) 2583 + static int mv88e6xxx_setup_global(struct mv88e6xxx_priv_state *ps) 2933 2584 { 2934 - struct mv88e6xxx_priv_state *ps = ds_to_priv(ds); 2585 + struct dsa_switch *ds = ps->ds; 2586 + u32 upstream_port = dsa_upstream_port(ds); 2587 + u16 reg; 2935 2588 int err; 2936 2589 int i; 2937 2590 2938 - mutex_lock(&ps->smi_mutex); 2591 + /* Enable the PHY Polling Unit if present, don't discard any packets, 2592 + * and mask all interrupt sources. 2593 + */ 2594 + reg = 0; 2595 + if (mv88e6xxx_has(ps, MV88E6XXX_FLAG_PPU) || 2596 + mv88e6xxx_has(ps, MV88E6XXX_FLAG_PPU_ACTIVE)) 2597 + reg |= GLOBAL_CONTROL_PPU_ENABLE; 2598 + 2599 + err = _mv88e6xxx_reg_write(ps, REG_GLOBAL, GLOBAL_CONTROL, reg); 2600 + if (err) 2601 + return err; 2602 + 2603 + /* Configure the upstream port, and configure it as the port to which 2604 + * ingress and egress and ARP monitor frames are to be sent. 2605 + */ 2606 + reg = upstream_port << GLOBAL_MONITOR_CONTROL_INGRESS_SHIFT | 2607 + upstream_port << GLOBAL_MONITOR_CONTROL_EGRESS_SHIFT | 2608 + upstream_port << GLOBAL_MONITOR_CONTROL_ARP_SHIFT; 2609 + err = _mv88e6xxx_reg_write(ps, REG_GLOBAL, GLOBAL_MONITOR_CONTROL, reg); 2610 + if (err) 2611 + return err; 2612 + 2613 + /* Disable remote management, and set the switch's DSA device number. */ 2614 + err = _mv88e6xxx_reg_write(ps, REG_GLOBAL, GLOBAL_CONTROL_2, 2615 + GLOBAL_CONTROL_2_MULTIPLE_CASCADE | 2616 + (ds->index & 0x1f)); 2617 + if (err) 2618 + return err; 2619 + 2939 2620 /* Set the default address aging time to 5 minutes, and 2940 2621 * enable address learn messages to be sent to all message 2941 2622 * ports. ··· 2951 2616 err = _mv88e6xxx_reg_write(ps, REG_GLOBAL, GLOBAL_ATU_CONTROL, 2952 2617 0x0140 | GLOBAL_ATU_CONTROL_LEARN2ALL); 2953 2618 if (err) 2954 - goto unlock; 2619 + return err; 2955 2620 2956 2621 /* Configure the IP ToS mapping registers. */ 2957 2622 err = _mv88e6xxx_reg_write(ps, REG_GLOBAL, GLOBAL_IP_PRI_0, 0x0000); 2958 2623 if (err) 2959 - goto unlock; 2624 + return err; 2960 2625 err = _mv88e6xxx_reg_write(ps, REG_GLOBAL, GLOBAL_IP_PRI_1, 0x0000); 2961 2626 if (err) 2962 - goto unlock; 2627 + return err; 2963 2628 err = _mv88e6xxx_reg_write(ps, REG_GLOBAL, GLOBAL_IP_PRI_2, 0x5555); 2964 2629 if (err) 2965 - goto unlock; 2630 + return err; 2966 2631 err = _mv88e6xxx_reg_write(ps, REG_GLOBAL, GLOBAL_IP_PRI_3, 0x5555); 2967 2632 if (err) 2968 - goto unlock; 2633 + return err; 2969 2634 err = _mv88e6xxx_reg_write(ps, REG_GLOBAL, GLOBAL_IP_PRI_4, 0xaaaa); 2970 2635 if (err) 2971 - goto unlock; 2636 + return err; 2972 2637 err = _mv88e6xxx_reg_write(ps, REG_GLOBAL, GLOBAL_IP_PRI_5, 0xaaaa); 2973 2638 if (err) 2974 - goto unlock; 2639 + return err; 2975 2640 err = _mv88e6xxx_reg_write(ps, REG_GLOBAL, GLOBAL_IP_PRI_6, 0xffff); 2976 2641 if (err) 2977 - goto unlock; 2642 + return err; 2978 2643 err = _mv88e6xxx_reg_write(ps, REG_GLOBAL, GLOBAL_IP_PRI_7, 0xffff); 2979 2644 if (err) 2980 - goto unlock; 2645 + return err; 2981 2646 2982 2647 /* Configure the IEEE 802.1p priority mapping register. */ 2983 2648 err = _mv88e6xxx_reg_write(ps, REG_GLOBAL, GLOBAL_IEEE_PRI, 0xfa41); 2984 2649 if (err) 2985 - goto unlock; 2650 + return err; 2986 2651 2987 2652 /* Send all frames with destination addresses matching 2988 2653 * 01:80:c2:00:00:0x to the CPU port. 2989 2654 */ 2990 2655 err = _mv88e6xxx_reg_write(ps, REG_GLOBAL2, GLOBAL2_MGMT_EN_0X, 0xffff); 2991 2656 if (err) 2992 - goto unlock; 2657 + return err; 2993 2658 2994 2659 /* Ignore removed tag data on doubly tagged packets, disable 2995 2660 * flow control messages, force flow control priority to the ··· 3000 2665 0x7 | GLOBAL2_SWITCH_MGMT_RSVD2CPU | 0x70 | 3001 2666 GLOBAL2_SWITCH_MGMT_FORCE_FLOW_CTRL_PRI); 3002 2667 if (err) 3003 - goto unlock; 2668 + return err; 3004 2669 3005 2670 /* Program the DSA routing table. */ 3006 2671 for (i = 0; i < 32; i++) { 3007 2672 int nexthop = 0x1f; 3008 2673 3009 - if (ds->pd->rtable && 3010 - i != ds->index && i < ds->dst->pd->nr_chips) 3011 - nexthop = ds->pd->rtable[i] & 0x1f; 2674 + if (ps->ds->pd->rtable && 2675 + i != ps->ds->index && i < ps->ds->dst->pd->nr_chips) 2676 + nexthop = ps->ds->pd->rtable[i] & 0x1f; 3012 2677 3013 2678 err = _mv88e6xxx_reg_write( 3014 2679 ps, REG_GLOBAL2, ··· 3016 2681 GLOBAL2_DEVICE_MAPPING_UPDATE | 3017 2682 (i << GLOBAL2_DEVICE_MAPPING_TARGET_SHIFT) | nexthop); 3018 2683 if (err) 3019 - goto unlock; 2684 + return err; 3020 2685 } 3021 2686 3022 2687 /* Clear all trunk masks. */ ··· 3026 2691 (i << GLOBAL2_TRUNK_MASK_NUM_SHIFT) | 3027 2692 ((1 << ps->info->num_ports) - 1)); 3028 2693 if (err) 3029 - goto unlock; 2694 + return err; 3030 2695 } 3031 2696 3032 2697 /* Clear all trunk mappings. */ ··· 3037 2702 GLOBAL2_TRUNK_MAPPING_UPDATE | 3038 2703 (i << GLOBAL2_TRUNK_MAPPING_ID_SHIFT)); 3039 2704 if (err) 3040 - goto unlock; 2705 + return err; 3041 2706 } 3042 2707 3043 2708 if (mv88e6xxx_6352_family(ps) || mv88e6xxx_6351_family(ps) || ··· 3049 2714 err = _mv88e6xxx_reg_write(ps, REG_GLOBAL2, 3050 2715 GLOBAL2_MGMT_EN_2X, 0xffff); 3051 2716 if (err) 3052 - goto unlock; 2717 + return err; 3053 2718 3054 2719 /* Initialise cross-chip port VLAN table to reset 3055 2720 * defaults. ··· 3057 2722 err = _mv88e6xxx_reg_write(ps, REG_GLOBAL2, 3058 2723 GLOBAL2_PVT_ADDR, 0x9000); 3059 2724 if (err) 3060 - goto unlock; 2725 + return err; 3061 2726 3062 2727 /* Clear the priority override table. */ 3063 2728 for (i = 0; i < 16; i++) { ··· 3065 2730 GLOBAL2_PRIO_OVERRIDE, 3066 2731 0x8000 | (i << 8)); 3067 2732 if (err) 3068 - goto unlock; 2733 + return err; 3069 2734 } 3070 2735 } 3071 2736 ··· 3082 2747 GLOBAL2_INGRESS_OP, 3083 2748 0x9000 | (i << 8)); 3084 2749 if (err) 3085 - goto unlock; 2750 + return err; 3086 2751 } 3087 2752 } 3088 2753 ··· 3090 2755 err = _mv88e6xxx_reg_write(ps, REG_GLOBAL, GLOBAL_STATS_OP, 3091 2756 GLOBAL_STATS_OP_FLUSH_ALL); 3092 2757 if (err) 3093 - goto unlock; 2758 + return err; 3094 2759 3095 2760 /* Wait for the flush to complete. */ 3096 2761 err = _mv88e6xxx_stats_wait(ps); 3097 - if (err < 0) 3098 - goto unlock; 2762 + if (err) 2763 + return err; 3099 2764 3100 2765 /* Clear all ATU entries */ 3101 2766 err = _mv88e6xxx_atu_flush(ps, 0, true); 3102 - if (err < 0) 3103 - goto unlock; 2767 + if (err) 2768 + return err; 3104 2769 3105 2770 /* Clear all the VTU and STU entries */ 3106 2771 err = _mv88e6xxx_vtu_stu_flush(ps); 3107 - unlock: 3108 - mutex_unlock(&ps->smi_mutex); 2772 + if (err < 0) 2773 + return err; 3109 2774 3110 2775 return err; 3111 2776 } 3112 2777 3113 - int mv88e6xxx_switch_reset(struct mv88e6xxx_priv_state *ps, bool ppu_active) 2778 + static int mv88e6xxx_setup(struct dsa_switch *ds) 3114 2779 { 3115 - u16 is_reset = (ppu_active ? 0x8800 : 0xc800); 3116 - struct gpio_desc *gpiod = ps->ds->pd->reset; 3117 - unsigned long timeout; 3118 - int ret; 2780 + struct mv88e6xxx_priv_state *ps = ds_to_priv(ds); 2781 + int err; 3119 2782 int i; 2783 + 2784 + ps->ds = ds; 2785 + 2786 + mutex_init(&ps->smi_mutex); 2787 + 2788 + INIT_WORK(&ps->bridge_work, mv88e6xxx_bridge_work); 2789 + 2790 + if (mv88e6xxx_has(ps, MV88E6XXX_FLAG_EEPROM)) 2791 + mutex_init(&ps->eeprom_mutex); 2792 + 2793 + if (mv88e6xxx_has(ps, MV88E6XXX_FLAG_PPU)) 2794 + mv88e6xxx_ppu_state_init(ps); 3120 2795 3121 2796 mutex_lock(&ps->smi_mutex); 3122 2797 3123 - /* Set all ports to the disabled state. */ 3124 - for (i = 0; i < ps->info->num_ports; i++) { 3125 - ret = _mv88e6xxx_reg_read(ps, REG_PORT(i), PORT_CONTROL); 3126 - if (ret < 0) 3127 - goto unlock; 3128 - 3129 - ret = _mv88e6xxx_reg_write(ps, REG_PORT(i), PORT_CONTROL, 3130 - ret & 0xfffc); 3131 - if (ret) 3132 - goto unlock; 3133 - } 3134 - 3135 - /* Wait for transmit queues to drain. */ 3136 - usleep_range(2000, 4000); 3137 - 3138 - /* If there is a gpio connected to the reset pin, toggle it */ 3139 - if (gpiod) { 3140 - gpiod_set_value_cansleep(gpiod, 1); 3141 - usleep_range(10000, 20000); 3142 - gpiod_set_value_cansleep(gpiod, 0); 3143 - usleep_range(10000, 20000); 3144 - } 3145 - 3146 - /* Reset the switch. Keep the PPU active if requested. The PPU 3147 - * needs to be active to support indirect phy register access 3148 - * through global registers 0x18 and 0x19. 3149 - */ 3150 - if (ppu_active) 3151 - ret = _mv88e6xxx_reg_write(ps, REG_GLOBAL, 0x04, 0xc000); 3152 - else 3153 - ret = _mv88e6xxx_reg_write(ps, REG_GLOBAL, 0x04, 0xc400); 3154 - if (ret) 2798 + err = mv88e6xxx_switch_reset(ps); 2799 + if (err) 3155 2800 goto unlock; 3156 2801 3157 - /* Wait up to one second for reset to complete. */ 3158 - timeout = jiffies + 1 * HZ; 3159 - while (time_before(jiffies, timeout)) { 3160 - ret = _mv88e6xxx_reg_read(ps, REG_GLOBAL, 0x00); 3161 - if (ret < 0) 3162 - goto unlock; 2802 + err = mv88e6xxx_setup_global(ps); 2803 + if (err) 2804 + goto unlock; 3163 2805 3164 - if ((ret & is_reset) == is_reset) 3165 - break; 3166 - usleep_range(1000, 2000); 2806 + for (i = 0; i < ps->info->num_ports; i++) { 2807 + err = mv88e6xxx_setup_port(ps, i); 2808 + if (err) 2809 + goto unlock; 3167 2810 } 3168 - if (time_after(jiffies, timeout)) 3169 - ret = -ETIMEDOUT; 3170 - else 3171 - ret = 0; 2811 + 3172 2812 unlock: 3173 2813 mutex_unlock(&ps->smi_mutex); 3174 2814 3175 - return ret; 2815 + return err; 3176 2816 } 3177 2817 3178 2818 int mv88e6xxx_phy_page_read(struct dsa_switch *ds, int port, int page, int reg) ··· 3183 2873 return -EINVAL; 3184 2874 } 3185 2875 3186 - int 3187 - mv88e6xxx_phy_read(struct dsa_switch *ds, int port, int regnum) 2876 + static int mv88e6xxx_phy_read(struct dsa_switch *ds, int port, int regnum) 3188 2877 { 3189 2878 struct mv88e6xxx_priv_state *ps = ds_to_priv(ds); 3190 2879 int addr = mv88e6xxx_port_to_phy_addr(ps, port); ··· 3193 2884 return 0xffff; 3194 2885 3195 2886 mutex_lock(&ps->smi_mutex); 3196 - ret = _mv88e6xxx_phy_read(ps, addr, regnum); 2887 + 2888 + if (mv88e6xxx_has(ps, MV88E6XXX_FLAG_PPU)) 2889 + ret = mv88e6xxx_phy_read_ppu(ps, addr, regnum); 2890 + else if (mv88e6xxx_has(ps, MV88E6XXX_FLAG_SMI_PHY)) 2891 + ret = _mv88e6xxx_phy_read_indirect(ps, addr, regnum); 2892 + else 2893 + ret = _mv88e6xxx_phy_read(ps, addr, regnum); 2894 + 3197 2895 mutex_unlock(&ps->smi_mutex); 3198 2896 return ret; 3199 2897 } 3200 2898 3201 - int 3202 - mv88e6xxx_phy_write(struct dsa_switch *ds, int port, int regnum, u16 val) 2899 + static int mv88e6xxx_phy_write(struct dsa_switch *ds, int port, int regnum, 2900 + u16 val) 3203 2901 { 3204 2902 struct mv88e6xxx_priv_state *ps = ds_to_priv(ds); 3205 2903 int addr = mv88e6xxx_port_to_phy_addr(ps, port); ··· 3216 2900 return 0xffff; 3217 2901 3218 2902 mutex_lock(&ps->smi_mutex); 3219 - ret = _mv88e6xxx_phy_write(ps, addr, regnum, val); 3220 - mutex_unlock(&ps->smi_mutex); 3221 - return ret; 3222 - } 3223 2903 3224 - int 3225 - mv88e6xxx_phy_read_indirect(struct dsa_switch *ds, int port, int regnum) 3226 - { 3227 - struct mv88e6xxx_priv_state *ps = ds_to_priv(ds); 3228 - int addr = mv88e6xxx_port_to_phy_addr(ps, port); 3229 - int ret; 2904 + if (mv88e6xxx_has(ps, MV88E6XXX_FLAG_PPU)) 2905 + ret = mv88e6xxx_phy_write_ppu(ps, addr, regnum, val); 2906 + else if (mv88e6xxx_has(ps, MV88E6XXX_FLAG_SMI_PHY)) 2907 + ret = _mv88e6xxx_phy_write_indirect(ps, addr, regnum, val); 2908 + else 2909 + ret = _mv88e6xxx_phy_write(ps, addr, regnum, val); 3230 2910 3231 - if (addr < 0) 3232 - return 0xffff; 3233 - 3234 - mutex_lock(&ps->smi_mutex); 3235 - ret = _mv88e6xxx_phy_read_indirect(ps, addr, regnum); 3236 - mutex_unlock(&ps->smi_mutex); 3237 - return ret; 3238 - } 3239 - 3240 - int 3241 - mv88e6xxx_phy_write_indirect(struct dsa_switch *ds, int port, int regnum, 3242 - u16 val) 3243 - { 3244 - struct mv88e6xxx_priv_state *ps = ds_to_priv(ds); 3245 - int addr = mv88e6xxx_port_to_phy_addr(ps, port); 3246 - int ret; 3247 - 3248 - if (addr < 0) 3249 - return addr; 3250 - 3251 - mutex_lock(&ps->smi_mutex); 3252 - ret = _mv88e6xxx_phy_write_indirect(ps, addr, regnum, val); 3253 2911 mutex_unlock(&ps->smi_mutex); 3254 2912 return ret; 3255 2913 } ··· 3292 3002 return 0; 3293 3003 } 3294 3004 3295 - int mv88e6xxx_get_temp(struct dsa_switch *ds, int *temp) 3005 + static int mv88e6xxx_get_temp(struct dsa_switch *ds, int *temp) 3296 3006 { 3297 3007 struct mv88e6xxx_priv_state *ps = ds_to_priv(ds); 3008 + 3009 + if (!mv88e6xxx_has(ps, MV88E6XXX_FLAG_TEMP)) 3010 + return -EOPNOTSUPP; 3298 3011 3299 3012 if (mv88e6xxx_6320_family(ps) || mv88e6xxx_6352_family(ps)) 3300 3013 return mv88e63xx_get_temp(ds, temp); ··· 3305 3012 return mv88e61xx_get_temp(ds, temp); 3306 3013 } 3307 3014 3308 - int mv88e6xxx_get_temp_limit(struct dsa_switch *ds, int *temp) 3015 + static int mv88e6xxx_get_temp_limit(struct dsa_switch *ds, int *temp) 3309 3016 { 3310 3017 struct mv88e6xxx_priv_state *ps = ds_to_priv(ds); 3311 3018 int phy = mv88e6xxx_6320_family(ps) ? 3 : 0; 3312 3019 int ret; 3313 3020 3314 - if (!mv88e6xxx_6320_family(ps) && !mv88e6xxx_6352_family(ps)) 3021 + if (!mv88e6xxx_has(ps, MV88E6XXX_FLAG_TEMP_LIMIT)) 3315 3022 return -EOPNOTSUPP; 3316 3023 3317 3024 *temp = 0; ··· 3325 3032 return 0; 3326 3033 } 3327 3034 3328 - int mv88e6xxx_set_temp_limit(struct dsa_switch *ds, int temp) 3035 + static int mv88e6xxx_set_temp_limit(struct dsa_switch *ds, int temp) 3329 3036 { 3330 3037 struct mv88e6xxx_priv_state *ps = ds_to_priv(ds); 3331 3038 int phy = mv88e6xxx_6320_family(ps) ? 3 : 0; 3332 3039 int ret; 3333 3040 3334 - if (!mv88e6xxx_6320_family(ps) && !mv88e6xxx_6352_family(ps)) 3041 + if (!mv88e6xxx_has(ps, MV88E6XXX_FLAG_TEMP_LIMIT)) 3335 3042 return -EOPNOTSUPP; 3336 3043 3337 3044 ret = mv88e6xxx_phy_page_read(ds, phy, 6, 26); ··· 3342 3049 (ret & 0xe0ff) | (temp << 8)); 3343 3050 } 3344 3051 3345 - int mv88e6xxx_get_temp_alarm(struct dsa_switch *ds, bool *alarm) 3052 + static int mv88e6xxx_get_temp_alarm(struct dsa_switch *ds, bool *alarm) 3346 3053 { 3347 3054 struct mv88e6xxx_priv_state *ps = ds_to_priv(ds); 3348 3055 int phy = mv88e6xxx_6320_family(ps) ? 3 : 0; 3349 3056 int ret; 3350 3057 3351 - if (!mv88e6xxx_6320_family(ps) && !mv88e6xxx_6352_family(ps)) 3058 + if (!mv88e6xxx_has(ps, MV88E6XXX_FLAG_TEMP_LIMIT)) 3352 3059 return -EOPNOTSUPP; 3353 3060 3354 3061 *alarm = false; ··· 3363 3070 } 3364 3071 #endif /* CONFIG_NET_DSA_HWMON */ 3365 3072 3073 + static const struct mv88e6xxx_info mv88e6xxx_table[] = { 3074 + [MV88E6085] = { 3075 + .prod_num = PORT_SWITCH_ID_PROD_NUM_6085, 3076 + .family = MV88E6XXX_FAMILY_6097, 3077 + .name = "Marvell 88E6085", 3078 + .num_databases = 4096, 3079 + .num_ports = 10, 3080 + .flags = MV88E6XXX_FLAGS_FAMILY_6097, 3081 + }, 3082 + 3083 + [MV88E6095] = { 3084 + .prod_num = PORT_SWITCH_ID_PROD_NUM_6095, 3085 + .family = MV88E6XXX_FAMILY_6095, 3086 + .name = "Marvell 88E6095/88E6095F", 3087 + .num_databases = 256, 3088 + .num_ports = 11, 3089 + .flags = MV88E6XXX_FLAGS_FAMILY_6095, 3090 + }, 3091 + 3092 + [MV88E6123] = { 3093 + .prod_num = PORT_SWITCH_ID_PROD_NUM_6123, 3094 + .family = MV88E6XXX_FAMILY_6165, 3095 + .name = "Marvell 88E6123", 3096 + .num_databases = 4096, 3097 + .num_ports = 3, 3098 + .flags = MV88E6XXX_FLAGS_FAMILY_6165, 3099 + }, 3100 + 3101 + [MV88E6131] = { 3102 + .prod_num = PORT_SWITCH_ID_PROD_NUM_6131, 3103 + .family = MV88E6XXX_FAMILY_6185, 3104 + .name = "Marvell 88E6131", 3105 + .num_databases = 256, 3106 + .num_ports = 8, 3107 + .flags = MV88E6XXX_FLAGS_FAMILY_6185, 3108 + }, 3109 + 3110 + [MV88E6161] = { 3111 + .prod_num = PORT_SWITCH_ID_PROD_NUM_6161, 3112 + .family = MV88E6XXX_FAMILY_6165, 3113 + .name = "Marvell 88E6161", 3114 + .num_databases = 4096, 3115 + .num_ports = 6, 3116 + .flags = MV88E6XXX_FLAGS_FAMILY_6165, 3117 + }, 3118 + 3119 + [MV88E6165] = { 3120 + .prod_num = PORT_SWITCH_ID_PROD_NUM_6165, 3121 + .family = MV88E6XXX_FAMILY_6165, 3122 + .name = "Marvell 88E6165", 3123 + .num_databases = 4096, 3124 + .num_ports = 6, 3125 + .flags = MV88E6XXX_FLAGS_FAMILY_6165, 3126 + }, 3127 + 3128 + [MV88E6171] = { 3129 + .prod_num = PORT_SWITCH_ID_PROD_NUM_6171, 3130 + .family = MV88E6XXX_FAMILY_6351, 3131 + .name = "Marvell 88E6171", 3132 + .num_databases = 4096, 3133 + .num_ports = 7, 3134 + .flags = MV88E6XXX_FLAGS_FAMILY_6351, 3135 + }, 3136 + 3137 + [MV88E6172] = { 3138 + .prod_num = PORT_SWITCH_ID_PROD_NUM_6172, 3139 + .family = MV88E6XXX_FAMILY_6352, 3140 + .name = "Marvell 88E6172", 3141 + .num_databases = 4096, 3142 + .num_ports = 7, 3143 + .flags = MV88E6XXX_FLAGS_FAMILY_6352, 3144 + }, 3145 + 3146 + [MV88E6175] = { 3147 + .prod_num = PORT_SWITCH_ID_PROD_NUM_6175, 3148 + .family = MV88E6XXX_FAMILY_6351, 3149 + .name = "Marvell 88E6175", 3150 + .num_databases = 4096, 3151 + .num_ports = 7, 3152 + .flags = MV88E6XXX_FLAGS_FAMILY_6351, 3153 + }, 3154 + 3155 + [MV88E6176] = { 3156 + .prod_num = PORT_SWITCH_ID_PROD_NUM_6176, 3157 + .family = MV88E6XXX_FAMILY_6352, 3158 + .name = "Marvell 88E6176", 3159 + .num_databases = 4096, 3160 + .num_ports = 7, 3161 + .flags = MV88E6XXX_FLAGS_FAMILY_6352, 3162 + }, 3163 + 3164 + [MV88E6185] = { 3165 + .prod_num = PORT_SWITCH_ID_PROD_NUM_6185, 3166 + .family = MV88E6XXX_FAMILY_6185, 3167 + .name = "Marvell 88E6185", 3168 + .num_databases = 256, 3169 + .num_ports = 10, 3170 + .flags = MV88E6XXX_FLAGS_FAMILY_6185, 3171 + }, 3172 + 3173 + [MV88E6240] = { 3174 + .prod_num = PORT_SWITCH_ID_PROD_NUM_6240, 3175 + .family = MV88E6XXX_FAMILY_6352, 3176 + .name = "Marvell 88E6240", 3177 + .num_databases = 4096, 3178 + .num_ports = 7, 3179 + .flags = MV88E6XXX_FLAGS_FAMILY_6352, 3180 + }, 3181 + 3182 + [MV88E6320] = { 3183 + .prod_num = PORT_SWITCH_ID_PROD_NUM_6320, 3184 + .family = MV88E6XXX_FAMILY_6320, 3185 + .name = "Marvell 88E6320", 3186 + .num_databases = 4096, 3187 + .num_ports = 7, 3188 + .flags = MV88E6XXX_FLAGS_FAMILY_6320, 3189 + }, 3190 + 3191 + [MV88E6321] = { 3192 + .prod_num = PORT_SWITCH_ID_PROD_NUM_6321, 3193 + .family = MV88E6XXX_FAMILY_6320, 3194 + .name = "Marvell 88E6321", 3195 + .num_databases = 4096, 3196 + .num_ports = 7, 3197 + .flags = MV88E6XXX_FLAGS_FAMILY_6320, 3198 + }, 3199 + 3200 + [MV88E6350] = { 3201 + .prod_num = PORT_SWITCH_ID_PROD_NUM_6350, 3202 + .family = MV88E6XXX_FAMILY_6351, 3203 + .name = "Marvell 88E6350", 3204 + .num_databases = 4096, 3205 + .num_ports = 7, 3206 + .flags = MV88E6XXX_FLAGS_FAMILY_6351, 3207 + }, 3208 + 3209 + [MV88E6351] = { 3210 + .prod_num = PORT_SWITCH_ID_PROD_NUM_6351, 3211 + .family = MV88E6XXX_FAMILY_6351, 3212 + .name = "Marvell 88E6351", 3213 + .num_databases = 4096, 3214 + .num_ports = 7, 3215 + .flags = MV88E6XXX_FLAGS_FAMILY_6351, 3216 + }, 3217 + 3218 + [MV88E6352] = { 3219 + .prod_num = PORT_SWITCH_ID_PROD_NUM_6352, 3220 + .family = MV88E6XXX_FAMILY_6352, 3221 + .name = "Marvell 88E6352", 3222 + .num_databases = 4096, 3223 + .num_ports = 7, 3224 + .flags = MV88E6XXX_FLAGS_FAMILY_6352, 3225 + }, 3226 + }; 3227 + 3366 3228 static const struct mv88e6xxx_info * 3367 3229 mv88e6xxx_lookup_info(unsigned int prod_num, const struct mv88e6xxx_info *table, 3368 3230 unsigned int num) ··· 3531 3083 return NULL; 3532 3084 } 3533 3085 3534 - const char *mv88e6xxx_drv_probe(struct device *dsa_dev, struct device *host_dev, 3535 - int sw_addr, void **priv, 3536 - const struct mv88e6xxx_info *table, 3537 - unsigned int num) 3086 + static const char *mv88e6xxx_probe(struct device *dsa_dev, 3087 + struct device *host_dev, int sw_addr, 3088 + void **priv) 3538 3089 { 3539 3090 const struct mv88e6xxx_info *info; 3540 3091 struct mv88e6xxx_priv_state *ps; ··· 3552 3105 prod_num = (id & 0xfff0) >> 4; 3553 3106 rev = id & 0x000f; 3554 3107 3555 - info = mv88e6xxx_lookup_info(prod_num, table, num); 3108 + info = mv88e6xxx_lookup_info(prod_num, mv88e6xxx_table, 3109 + ARRAY_SIZE(mv88e6xxx_table)); 3556 3110 if (!info) 3557 3111 return NULL; 3558 3112 ··· 3575 3127 return name; 3576 3128 } 3577 3129 3130 + struct dsa_switch_driver mv88e6xxx_switch_driver = { 3131 + .tag_protocol = DSA_TAG_PROTO_EDSA, 3132 + .probe = mv88e6xxx_probe, 3133 + .setup = mv88e6xxx_setup, 3134 + .set_addr = mv88e6xxx_set_addr, 3135 + .phy_read = mv88e6xxx_phy_read, 3136 + .phy_write = mv88e6xxx_phy_write, 3137 + .adjust_link = mv88e6xxx_adjust_link, 3138 + .get_strings = mv88e6xxx_get_strings, 3139 + .get_ethtool_stats = mv88e6xxx_get_ethtool_stats, 3140 + .get_sset_count = mv88e6xxx_get_sset_count, 3141 + .set_eee = mv88e6xxx_set_eee, 3142 + .get_eee = mv88e6xxx_get_eee, 3143 + #ifdef CONFIG_NET_DSA_HWMON 3144 + .get_temp = mv88e6xxx_get_temp, 3145 + .get_temp_limit = mv88e6xxx_get_temp_limit, 3146 + .set_temp_limit = mv88e6xxx_set_temp_limit, 3147 + .get_temp_alarm = mv88e6xxx_get_temp_alarm, 3148 + #endif 3149 + .get_eeprom = mv88e6xxx_get_eeprom, 3150 + .set_eeprom = mv88e6xxx_set_eeprom, 3151 + .get_regs_len = mv88e6xxx_get_regs_len, 3152 + .get_regs = mv88e6xxx_get_regs, 3153 + .port_bridge_join = mv88e6xxx_port_bridge_join, 3154 + .port_bridge_leave = mv88e6xxx_port_bridge_leave, 3155 + .port_stp_state_set = mv88e6xxx_port_stp_state_set, 3156 + .port_vlan_filtering = mv88e6xxx_port_vlan_filtering, 3157 + .port_vlan_prepare = mv88e6xxx_port_vlan_prepare, 3158 + .port_vlan_add = mv88e6xxx_port_vlan_add, 3159 + .port_vlan_del = mv88e6xxx_port_vlan_del, 3160 + .port_vlan_dump = mv88e6xxx_port_vlan_dump, 3161 + .port_fdb_prepare = mv88e6xxx_port_fdb_prepare, 3162 + .port_fdb_add = mv88e6xxx_port_fdb_add, 3163 + .port_fdb_del = mv88e6xxx_port_fdb_del, 3164 + .port_fdb_dump = mv88e6xxx_port_fdb_dump, 3165 + }; 3166 + 3578 3167 static int __init mv88e6xxx_init(void) 3579 3168 { 3580 - #if IS_ENABLED(CONFIG_NET_DSA_MV88E6131) 3581 - register_switch_driver(&mv88e6131_switch_driver); 3582 - #endif 3583 - #if IS_ENABLED(CONFIG_NET_DSA_MV88E6123) 3584 - register_switch_driver(&mv88e6123_switch_driver); 3585 - #endif 3586 - #if IS_ENABLED(CONFIG_NET_DSA_MV88E6352) 3587 - register_switch_driver(&mv88e6352_switch_driver); 3588 - #endif 3589 - #if IS_ENABLED(CONFIG_NET_DSA_MV88E6171) 3590 - register_switch_driver(&mv88e6171_switch_driver); 3591 - #endif 3169 + register_switch_driver(&mv88e6xxx_switch_driver); 3170 + 3592 3171 return 0; 3593 3172 } 3594 3173 module_init(mv88e6xxx_init); 3595 3174 3596 3175 static void __exit mv88e6xxx_cleanup(void) 3597 3176 { 3598 - #if IS_ENABLED(CONFIG_NET_DSA_MV88E6171) 3599 - unregister_switch_driver(&mv88e6171_switch_driver); 3600 - #endif 3601 - #if IS_ENABLED(CONFIG_NET_DSA_MV88E6352) 3602 - unregister_switch_driver(&mv88e6352_switch_driver); 3603 - #endif 3604 - #if IS_ENABLED(CONFIG_NET_DSA_MV88E6123) 3605 - unregister_switch_driver(&mv88e6123_switch_driver); 3606 - #endif 3607 - #if IS_ENABLED(CONFIG_NET_DSA_MV88E6131) 3608 - unregister_switch_driver(&mv88e6131_switch_driver); 3609 - #endif 3177 + unregister_switch_driver(&mv88e6xxx_switch_driver); 3610 3178 } 3611 3179 module_exit(mv88e6xxx_cleanup); 3612 3180 3181 + MODULE_ALIAS("platform:mv88e6085"); 3182 + MODULE_ALIAS("platform:mv88e6095"); 3183 + MODULE_ALIAS("platform:mv88e6095f"); 3184 + MODULE_ALIAS("platform:mv88e6123"); 3185 + MODULE_ALIAS("platform:mv88e6131"); 3186 + MODULE_ALIAS("platform:mv88e6161"); 3187 + MODULE_ALIAS("platform:mv88e6165"); 3188 + MODULE_ALIAS("platform:mv88e6171"); 3189 + MODULE_ALIAS("platform:mv88e6172"); 3190 + MODULE_ALIAS("platform:mv88e6175"); 3191 + MODULE_ALIAS("platform:mv88e6176"); 3192 + MODULE_ALIAS("platform:mv88e6320"); 3193 + MODULE_ALIAS("platform:mv88e6321"); 3194 + MODULE_ALIAS("platform:mv88e6350"); 3195 + MODULE_ALIAS("platform:mv88e6351"); 3196 + MODULE_ALIAS("platform:mv88e6352"); 3613 3197 MODULE_AUTHOR("Lennert Buytenhek <buytenh@wantstofly.org>"); 3614 3198 MODULE_DESCRIPTION("Driver for Marvell 88E6XXX ethernet switch chips"); 3615 3199 MODULE_LICENSE("GPL");
+156 -83
drivers/net/dsa/mv88e6xxx.h
··· 338 338 339 339 #define MV88E6XXX_N_FID 4096 340 340 341 + /* List of supported models */ 342 + enum mv88e6xxx_model { 343 + MV88E6085, 344 + MV88E6095, 345 + MV88E6123, 346 + MV88E6131, 347 + MV88E6161, 348 + MV88E6165, 349 + MV88E6171, 350 + MV88E6172, 351 + MV88E6175, 352 + MV88E6176, 353 + MV88E6185, 354 + MV88E6240, 355 + MV88E6320, 356 + MV88E6321, 357 + MV88E6350, 358 + MV88E6351, 359 + MV88E6352, 360 + }; 361 + 341 362 enum mv88e6xxx_family { 342 363 MV88E6XXX_FAMILY_NONE, 343 364 MV88E6XXX_FAMILY_6065, /* 6031 6035 6061 6065 */ ··· 371 350 MV88E6XXX_FAMILY_6352, /* 6172 6176 6240 6352 */ 372 351 }; 373 352 353 + enum mv88e6xxx_cap { 354 + /* Address Translation Unit. 355 + * The ATU is used to lookup and learn MAC addresses. See GLOBAL_ATU_OP. 356 + */ 357 + MV88E6XXX_CAP_ATU, 358 + 359 + /* Energy Efficient Ethernet. 360 + */ 361 + MV88E6XXX_CAP_EEE, 362 + 363 + /* EEPROM Command and Data registers. 364 + * See GLOBAL2_EEPROM_OP and GLOBAL2_EEPROM_DATA. 365 + */ 366 + MV88E6XXX_CAP_EEPROM, 367 + 368 + /* Port State Filtering for 802.1D Spanning Tree. 369 + * See PORT_CONTROL_STATE_* values in the PORT_CONTROL register. 370 + */ 371 + MV88E6XXX_CAP_PORTSTATE, 372 + 373 + /* PHY Polling Unit. 374 + * See GLOBAL_CONTROL_PPU_ENABLE and GLOBAL_STATUS_PPU_POLLING. 375 + */ 376 + MV88E6XXX_CAP_PPU, 377 + MV88E6XXX_CAP_PPU_ACTIVE, 378 + 379 + /* SMI PHY Command and Data registers. 380 + * This requires an indirect access to PHY registers through 381 + * GLOBAL2_SMI_OP, otherwise direct access to PHY registers is done. 382 + */ 383 + MV88E6XXX_CAP_SMI_PHY, 384 + 385 + /* Switch MAC/WoL/WoF register. 386 + * This requires an indirect access to set the switch MAC address 387 + * through GLOBAL2_SWITCH_MAC, otherwise GLOBAL_MAC_01, GLOBAL_MAC_23, 388 + * and GLOBAL_MAC_45 are used with a direct access. 389 + */ 390 + MV88E6XXX_CAP_SWITCH_MAC_WOL_WOF, 391 + 392 + /* Internal temperature sensor. 393 + * Available from any enabled port's PHY register 26, page 6. 394 + */ 395 + MV88E6XXX_CAP_TEMP, 396 + MV88E6XXX_CAP_TEMP_LIMIT, 397 + 398 + /* In-chip Port Based VLANs. 399 + * Each port VLANTable register (see PORT_BASE_VLAN) is used to restrict 400 + * the output (or egress) ports to which it is allowed to send frames. 401 + */ 402 + MV88E6XXX_CAP_VLANTABLE, 403 + 404 + /* VLAN Table Unit. 405 + * The VTU is used to program 802.1Q VLANs. See GLOBAL_VTU_OP. 406 + */ 407 + MV88E6XXX_CAP_VTU, 408 + }; 409 + 410 + /* Bitmask of capabilities */ 411 + #define MV88E6XXX_FLAG_ATU BIT(MV88E6XXX_CAP_ATU) 412 + #define MV88E6XXX_FLAG_EEE BIT(MV88E6XXX_CAP_EEE) 413 + #define MV88E6XXX_FLAG_EEPROM BIT(MV88E6XXX_CAP_EEPROM) 414 + #define MV88E6XXX_FLAG_PORTSTATE BIT(MV88E6XXX_CAP_PORTSTATE) 415 + #define MV88E6XXX_FLAG_PPU BIT(MV88E6XXX_CAP_PPU) 416 + #define MV88E6XXX_FLAG_PPU_ACTIVE BIT(MV88E6XXX_CAP_PPU_ACTIVE) 417 + #define MV88E6XXX_FLAG_SMI_PHY BIT(MV88E6XXX_CAP_SMI_PHY) 418 + #define MV88E6XXX_FLAG_SWITCH_MAC BIT(MV88E6XXX_CAP_SWITCH_MAC_WOL_WOF) 419 + #define MV88E6XXX_FLAG_TEMP BIT(MV88E6XXX_CAP_TEMP) 420 + #define MV88E6XXX_FLAG_TEMP_LIMIT BIT(MV88E6XXX_CAP_TEMP_LIMIT) 421 + #define MV88E6XXX_FLAG_VLANTABLE BIT(MV88E6XXX_CAP_VLANTABLE) 422 + #define MV88E6XXX_FLAG_VTU BIT(MV88E6XXX_CAP_VTU) 423 + 424 + #define MV88E6XXX_FLAGS_FAMILY_6095 \ 425 + (MV88E6XXX_FLAG_ATU | \ 426 + MV88E6XXX_FLAG_PPU | \ 427 + MV88E6XXX_FLAG_VLANTABLE | \ 428 + MV88E6XXX_FLAG_VTU) 429 + 430 + #define MV88E6XXX_FLAGS_FAMILY_6097 \ 431 + (MV88E6XXX_FLAG_ATU | \ 432 + MV88E6XXX_FLAG_PPU | \ 433 + MV88E6XXX_FLAG_VLANTABLE | \ 434 + MV88E6XXX_FLAG_VTU) 435 + 436 + #define MV88E6XXX_FLAGS_FAMILY_6165 \ 437 + (MV88E6XXX_FLAG_SWITCH_MAC | \ 438 + MV88E6XXX_FLAG_TEMP) 439 + 440 + #define MV88E6XXX_FLAGS_FAMILY_6185 \ 441 + (MV88E6XXX_FLAG_ATU | \ 442 + MV88E6XXX_FLAG_PPU | \ 443 + MV88E6XXX_FLAG_VLANTABLE | \ 444 + MV88E6XXX_FLAG_VTU) 445 + 446 + #define MV88E6XXX_FLAGS_FAMILY_6320 \ 447 + (MV88E6XXX_FLAG_ATU | \ 448 + MV88E6XXX_FLAG_EEE | \ 449 + MV88E6XXX_FLAG_EEPROM | \ 450 + MV88E6XXX_FLAG_PORTSTATE | \ 451 + MV88E6XXX_FLAG_PPU_ACTIVE | \ 452 + MV88E6XXX_FLAG_SMI_PHY | \ 453 + MV88E6XXX_FLAG_SWITCH_MAC | \ 454 + MV88E6XXX_FLAG_TEMP | \ 455 + MV88E6XXX_FLAG_TEMP_LIMIT | \ 456 + MV88E6XXX_FLAG_VLANTABLE | \ 457 + MV88E6XXX_FLAG_VTU) 458 + 459 + #define MV88E6XXX_FLAGS_FAMILY_6351 \ 460 + (MV88E6XXX_FLAG_ATU | \ 461 + MV88E6XXX_FLAG_PORTSTATE | \ 462 + MV88E6XXX_FLAG_PPU_ACTIVE | \ 463 + MV88E6XXX_FLAG_SMI_PHY | \ 464 + MV88E6XXX_FLAG_SWITCH_MAC | \ 465 + MV88E6XXX_FLAG_TEMP | \ 466 + MV88E6XXX_FLAG_VLANTABLE | \ 467 + MV88E6XXX_FLAG_VTU) 468 + 469 + #define MV88E6XXX_FLAGS_FAMILY_6352 \ 470 + (MV88E6XXX_FLAG_ATU | \ 471 + MV88E6XXX_FLAG_EEE | \ 472 + MV88E6XXX_FLAG_EEPROM | \ 473 + MV88E6XXX_FLAG_PORTSTATE | \ 474 + MV88E6XXX_FLAG_PPU_ACTIVE | \ 475 + MV88E6XXX_FLAG_SMI_PHY | \ 476 + MV88E6XXX_FLAG_SWITCH_MAC | \ 477 + MV88E6XXX_FLAG_TEMP | \ 478 + MV88E6XXX_FLAG_TEMP_LIMIT | \ 479 + MV88E6XXX_FLAG_VLANTABLE | \ 480 + MV88E6XXX_FLAG_VTU) 481 + 374 482 struct mv88e6xxx_info { 375 483 enum mv88e6xxx_family family; 376 484 u16 prod_num; 377 485 const char *name; 378 486 unsigned int num_databases; 379 487 unsigned int num_ports; 488 + unsigned long flags; 380 489 }; 381 490 382 491 struct mv88e6xxx_atu_entry { ··· 554 403 struct mii_bus *bus; 555 404 int sw_addr; 556 405 557 - #ifdef CONFIG_NET_DSA_MV88E6XXX_NEED_PPU 558 406 /* Handles automatic disabling and re-enabling of the PHY 559 407 * polling unit. 560 408 */ ··· 561 411 int ppu_disabled; 562 412 struct work_struct ppu_work; 563 413 struct timer_list ppu_timer; 564 - #endif 565 414 566 415 /* This mutex serialises access to the statistics unit. 567 416 * Hold this mutex over snapshot + dump sequences. ··· 598 449 enum stat_type type; 599 450 }; 600 451 601 - int mv88e6xxx_switch_reset(struct mv88e6xxx_priv_state *ps, bool ppu_active); 602 - const char *mv88e6xxx_drv_probe(struct device *dsa_dev, struct device *host_dev, 603 - int sw_addr, void **priv, 604 - const struct mv88e6xxx_info *table, 605 - unsigned int num); 606 - 607 - int mv88e6xxx_setup_ports(struct dsa_switch *ds); 608 - int mv88e6xxx_setup_common(struct mv88e6xxx_priv_state *ps); 609 - int mv88e6xxx_setup_global(struct dsa_switch *ds); 610 - int mv88e6xxx_reg_read(struct mv88e6xxx_priv_state *ps, int addr, int reg); 611 - int mv88e6xxx_reg_write(struct mv88e6xxx_priv_state *ps, int addr, 612 - int reg, u16 val); 613 - int mv88e6xxx_set_addr_direct(struct dsa_switch *ds, u8 *addr); 614 - int mv88e6xxx_set_addr_indirect(struct dsa_switch *ds, u8 *addr); 615 - int mv88e6xxx_phy_read(struct dsa_switch *ds, int port, int regnum); 616 - int mv88e6xxx_phy_write(struct dsa_switch *ds, int port, int regnum, u16 val); 617 - int mv88e6xxx_phy_read_indirect(struct dsa_switch *ds, int port, int regnum); 618 - int mv88e6xxx_phy_write_indirect(struct dsa_switch *ds, int port, int regnum, 619 - u16 val); 620 - void mv88e6xxx_ppu_state_init(struct mv88e6xxx_priv_state *ps); 621 - int mv88e6xxx_phy_read_ppu(struct dsa_switch *ds, int addr, int regnum); 622 - int mv88e6xxx_phy_write_ppu(struct dsa_switch *ds, int addr, 623 - int regnum, u16 val); 624 - void mv88e6xxx_get_strings(struct dsa_switch *ds, int port, uint8_t *data); 625 - void mv88e6xxx_get_ethtool_stats(struct dsa_switch *ds, int port, 626 - uint64_t *data); 627 - int mv88e6xxx_get_sset_count(struct dsa_switch *ds); 628 - int mv88e6xxx_get_sset_count_basic(struct dsa_switch *ds); 629 - void mv88e6xxx_adjust_link(struct dsa_switch *ds, int port, 630 - struct phy_device *phydev); 631 - int mv88e6xxx_get_regs_len(struct dsa_switch *ds, int port); 632 - void mv88e6xxx_get_regs(struct dsa_switch *ds, int port, 633 - struct ethtool_regs *regs, void *_p); 634 - int mv88e6xxx_get_temp(struct dsa_switch *ds, int *temp); 635 - int mv88e6xxx_get_temp_limit(struct dsa_switch *ds, int *temp); 636 - int mv88e6xxx_set_temp_limit(struct dsa_switch *ds, int temp); 637 - int mv88e6xxx_get_temp_alarm(struct dsa_switch *ds, bool *alarm); 638 - int mv88e6xxx_eeprom_load_wait(struct dsa_switch *ds); 639 - int mv88e6xxx_eeprom_busy_wait(struct dsa_switch *ds); 640 - int mv88e6xxx_phy_read_indirect(struct dsa_switch *ds, int addr, int regnum); 641 - int mv88e6xxx_phy_write_indirect(struct dsa_switch *ds, int addr, int regnum, 642 - u16 val); 643 - int mv88e6xxx_get_eee(struct dsa_switch *ds, int port, struct ethtool_eee *e); 644 - int mv88e6xxx_set_eee(struct dsa_switch *ds, int port, 645 - struct phy_device *phydev, struct ethtool_eee *e); 646 - int mv88e6xxx_port_bridge_join(struct dsa_switch *ds, int port, 647 - struct net_device *bridge); 648 - void mv88e6xxx_port_bridge_leave(struct dsa_switch *ds, int port); 649 - void mv88e6xxx_port_stp_state_set(struct dsa_switch *ds, int port, u8 state); 650 - int mv88e6xxx_port_vlan_filtering(struct dsa_switch *ds, int port, 651 - bool vlan_filtering); 652 - int mv88e6xxx_port_vlan_prepare(struct dsa_switch *ds, int port, 653 - const struct switchdev_obj_port_vlan *vlan, 654 - struct switchdev_trans *trans); 655 - void mv88e6xxx_port_vlan_add(struct dsa_switch *ds, int port, 656 - const struct switchdev_obj_port_vlan *vlan, 657 - struct switchdev_trans *trans); 658 - int mv88e6xxx_port_vlan_del(struct dsa_switch *ds, int port, 659 - const struct switchdev_obj_port_vlan *vlan); 660 - int mv88e6xxx_port_vlan_dump(struct dsa_switch *ds, int port, 661 - struct switchdev_obj_port_vlan *vlan, 662 - int (*cb)(struct switchdev_obj *obj)); 663 - int mv88e6xxx_port_fdb_prepare(struct dsa_switch *ds, int port, 664 - const struct switchdev_obj_port_fdb *fdb, 665 - struct switchdev_trans *trans); 666 - void mv88e6xxx_port_fdb_add(struct dsa_switch *ds, int port, 667 - const struct switchdev_obj_port_fdb *fdb, 668 - struct switchdev_trans *trans); 669 - int mv88e6xxx_port_fdb_del(struct dsa_switch *ds, int port, 670 - const struct switchdev_obj_port_fdb *fdb); 671 - int mv88e6xxx_port_fdb_dump(struct dsa_switch *ds, int port, 672 - struct switchdev_obj_port_fdb *fdb, 673 - int (*cb)(struct switchdev_obj *obj)); 674 - int mv88e6xxx_phy_page_read(struct dsa_switch *ds, int port, int page, int reg); 675 - int mv88e6xxx_phy_page_write(struct dsa_switch *ds, int port, int page, 676 - int reg, int val); 677 - 678 - extern struct dsa_switch_driver mv88e6131_switch_driver; 679 - extern struct dsa_switch_driver mv88e6123_switch_driver; 680 - extern struct dsa_switch_driver mv88e6352_switch_driver; 681 - extern struct dsa_switch_driver mv88e6171_switch_driver; 452 + static inline bool mv88e6xxx_has(struct mv88e6xxx_priv_state *ps, 453 + unsigned long flags) 454 + { 455 + return (ps->info->flags & flags) == flags; 456 + } 682 457 683 458 #endif