Back to home page

OSCL-LXR

 
 

    


0001 /* SPDX-License-Identifier: GPL-2.0-only */
0002 /*
0003  * Copyright (C) 2022 Schneider Electric
0004  *
0005  * Clément Léger <clement.leger@bootlin.com>
0006  */
0007 
0008 #include <linux/clk.h>
0009 #include <linux/debugfs.h>
0010 #include <linux/kernel.h>
0011 #include <linux/module.h>
0012 #include <linux/of.h>
0013 #include <linux/of_mdio.h>
0014 #include <linux/platform_device.h>
0015 #include <linux/pcs-rzn1-miic.h>
0016 #include <net/dsa.h>
0017 
0018 #define A5PSW_REVISION          0x0
0019 #define A5PSW_PORT_OFFSET(port)     (0x400 * (port))
0020 
0021 #define A5PSW_PORT_ENA          0x8
0022 #define A5PSW_PORT_ENA_RX_SHIFT     16
0023 #define A5PSW_PORT_ENA_TX_RX(port)  (BIT((port) + A5PSW_PORT_ENA_RX_SHIFT) | \
0024                      BIT(port))
0025 #define A5PSW_UCAST_DEF_MASK        0xC
0026 
0027 #define A5PSW_VLAN_VERIFY       0x10
0028 #define A5PSW_VLAN_VERI_SHIFT       0
0029 #define A5PSW_VLAN_DISC_SHIFT       16
0030 
0031 #define A5PSW_BCAST_DEF_MASK        0x14
0032 #define A5PSW_MCAST_DEF_MASK        0x18
0033 
0034 #define A5PSW_INPUT_LEARN       0x1C
0035 #define A5PSW_INPUT_LEARN_DIS(p)    BIT((p) + 16)
0036 #define A5PSW_INPUT_LEARN_BLOCK(p)  BIT(p)
0037 
0038 #define A5PSW_MGMT_CFG          0x20
0039 #define A5PSW_MGMT_CFG_DISCARD      BIT(7)
0040 
0041 #define A5PSW_MODE_CFG          0x24
0042 #define A5PSW_MODE_STATS_RESET      BIT(31)
0043 
0044 #define A5PSW_VLAN_IN_MODE      0x28
0045 #define A5PSW_VLAN_IN_MODE_PORT_SHIFT(port) ((port) * 2)
0046 #define A5PSW_VLAN_IN_MODE_PORT(port)       (GENMASK(1, 0) << \
0047                     A5PSW_VLAN_IN_MODE_PORT_SHIFT(port))
0048 #define A5PSW_VLAN_IN_MODE_SINGLE_PASSTHROUGH   0x0
0049 #define A5PSW_VLAN_IN_MODE_SINGLE_REPLACE   0x1
0050 #define A5PSW_VLAN_IN_MODE_TAG_ALWAYS       0x2
0051 
0052 #define A5PSW_VLAN_OUT_MODE     0x2C
0053 #define A5PSW_VLAN_OUT_MODE_PORT(port)  (GENMASK(1, 0) << ((port) * 2))
0054 #define A5PSW_VLAN_OUT_MODE_DIS     0x0
0055 #define A5PSW_VLAN_OUT_MODE_STRIP   0x1
0056 #define A5PSW_VLAN_OUT_MODE_TAG_THROUGH 0x2
0057 #define A5PSW_VLAN_OUT_MODE_TRANSPARENT 0x3
0058 
0059 #define A5PSW_VLAN_IN_MODE_ENA      0x30
0060 #define A5PSW_VLAN_TAG_ID       0x34
0061 
0062 #define A5PSW_SYSTEM_TAGINFO(port)  (0x200 + A5PSW_PORT_OFFSET(port))
0063 
0064 #define A5PSW_AUTH_PORT(port)       (0x240 + 4 * (port))
0065 #define A5PSW_AUTH_PORT_AUTHORIZED  BIT(0)
0066 
0067 #define A5PSW_VLAN_RES(entry)       (0x280 + 4 * (entry))
0068 #define A5PSW_VLAN_RES_WR_PORTMASK  BIT(30)
0069 #define A5PSW_VLAN_RES_WR_TAGMASK   BIT(29)
0070 #define A5PSW_VLAN_RES_RD_TAGMASK   BIT(28)
0071 #define A5PSW_VLAN_RES_ID       GENMASK(16, 5)
0072 #define A5PSW_VLAN_RES_PORTMASK     GENMASK(4, 0)
0073 
0074 #define A5PSW_RXMATCH_CONFIG(port)  (0x3e80 + 4 * (port))
0075 #define A5PSW_RXMATCH_CONFIG_PATTERN(p) BIT(p)
0076 
0077 #define A5PSW_PATTERN_CTRL(p)       (0x3eb0 + 4  * (p))
0078 #define A5PSW_PATTERN_CTRL_MGMTFWD  BIT(1)
0079 
0080 #define A5PSW_LK_CTRL       0x400
0081 #define A5PSW_LK_ADDR_CTRL_BLOCKING BIT(0)
0082 #define A5PSW_LK_ADDR_CTRL_LEARNING BIT(1)
0083 #define A5PSW_LK_ADDR_CTRL_AGEING   BIT(2)
0084 #define A5PSW_LK_ADDR_CTRL_ALLOW_MIGR   BIT(3)
0085 #define A5PSW_LK_ADDR_CTRL_CLEAR_TABLE  BIT(6)
0086 
0087 #define A5PSW_LK_ADDR_CTRL      0x408
0088 #define A5PSW_LK_ADDR_CTRL_BUSY     BIT(31)
0089 #define A5PSW_LK_ADDR_CTRL_DELETE_PORT  BIT(30)
0090 #define A5PSW_LK_ADDR_CTRL_CLEAR    BIT(29)
0091 #define A5PSW_LK_ADDR_CTRL_LOOKUP   BIT(28)
0092 #define A5PSW_LK_ADDR_CTRL_WAIT     BIT(27)
0093 #define A5PSW_LK_ADDR_CTRL_READ     BIT(26)
0094 #define A5PSW_LK_ADDR_CTRL_WRITE    BIT(25)
0095 #define A5PSW_LK_ADDR_CTRL_ADDRESS  GENMASK(12, 0)
0096 
0097 #define A5PSW_LK_DATA_LO        0x40C
0098 #define A5PSW_LK_DATA_HI        0x410
0099 #define A5PSW_LK_DATA_HI_VALID      BIT(16)
0100 #define A5PSW_LK_DATA_HI_PORT       BIT(16)
0101 
0102 #define A5PSW_LK_LEARNCOUNT     0x418
0103 #define A5PSW_LK_LEARNCOUNT_COUNT   GENMASK(13, 0)
0104 #define A5PSW_LK_LEARNCOUNT_MODE    GENMASK(31, 30)
0105 #define A5PSW_LK_LEARNCOUNT_MODE_SET    0x0
0106 #define A5PSW_LK_LEARNCOUNT_MODE_INC    0x1
0107 #define A5PSW_LK_LEARNCOUNT_MODE_DEC    0x2
0108 
0109 #define A5PSW_MGMT_TAG_CFG      0x480
0110 #define A5PSW_MGMT_TAG_CFG_TAGFIELD GENMASK(31, 16)
0111 #define A5PSW_MGMT_TAG_CFG_ALL_FRAMES   BIT(1)
0112 #define A5PSW_MGMT_TAG_CFG_ENABLE   BIT(0)
0113 
0114 #define A5PSW_LK_AGETIME        0x41C
0115 #define A5PSW_LK_AGETIME_MASK       GENMASK(23, 0)
0116 
0117 #define A5PSW_MDIO_CFG_STATUS       0x700
0118 #define A5PSW_MDIO_CFG_STATUS_CLKDIV    GENMASK(15, 7)
0119 #define A5PSW_MDIO_CFG_STATUS_READERR   BIT(1)
0120 #define A5PSW_MDIO_CFG_STATUS_BUSY  BIT(0)
0121 
0122 #define A5PSW_MDIO_COMMAND      0x704
0123 /* Register is named TRAININIT in datasheet and should be set when reading */
0124 #define A5PSW_MDIO_COMMAND_READ     BIT(15)
0125 #define A5PSW_MDIO_COMMAND_PHY_ADDR GENMASK(9, 5)
0126 #define A5PSW_MDIO_COMMAND_REG_ADDR GENMASK(4, 0)
0127 
0128 #define A5PSW_MDIO_DATA         0x708
0129 #define A5PSW_MDIO_DATA_MASK        GENMASK(15, 0)
0130 
0131 #define A5PSW_CMD_CFG(port)     (0x808 + A5PSW_PORT_OFFSET(port))
0132 #define A5PSW_CMD_CFG_CNTL_FRM_ENA  BIT(23)
0133 #define A5PSW_CMD_CFG_SW_RESET      BIT(13)
0134 #define A5PSW_CMD_CFG_TX_CRC_APPEND BIT(11)
0135 #define A5PSW_CMD_CFG_HD_ENA        BIT(10)
0136 #define A5PSW_CMD_CFG_PAUSE_IGNORE  BIT(8)
0137 #define A5PSW_CMD_CFG_CRC_FWD       BIT(6)
0138 #define A5PSW_CMD_CFG_ETH_SPEED     BIT(3)
0139 #define A5PSW_CMD_CFG_RX_ENA        BIT(1)
0140 #define A5PSW_CMD_CFG_TX_ENA        BIT(0)
0141 
0142 #define A5PSW_FRM_LENGTH(port)      (0x814 + A5PSW_PORT_OFFSET(port))
0143 #define A5PSW_FRM_LENGTH_MASK       GENMASK(13, 0)
0144 
0145 #define A5PSW_STATUS(port)      (0x840 + A5PSW_PORT_OFFSET(port))
0146 
0147 #define A5PSW_STATS_HIWORD      0x900
0148 
0149 /* Stats */
0150 #define A5PSW_aFramesTransmittedOK      0x868
0151 #define A5PSW_aFramesReceivedOK         0x86C
0152 #define A5PSW_aFrameCheckSequenceErrors     0x870
0153 #define A5PSW_aAlignmentErrors          0x874
0154 #define A5PSW_aOctetsTransmittedOK      0x878
0155 #define A5PSW_aOctetsReceivedOK         0x87C
0156 #define A5PSW_aTxPAUSEMACCtrlFrames     0x880
0157 #define A5PSW_aRxPAUSEMACCtrlFrames     0x884
0158 /* If */
0159 #define A5PSW_ifInErrors            0x888
0160 #define A5PSW_ifOutErrors           0x88C
0161 #define A5PSW_ifInUcastPkts         0x890
0162 #define A5PSW_ifInMulticastPkts         0x894
0163 #define A5PSW_ifInBroadcastPkts         0x898
0164 #define A5PSW_ifOutDiscards         0x89C
0165 #define A5PSW_ifOutUcastPkts            0x8A0
0166 #define A5PSW_ifOutMulticastPkts        0x8A4
0167 #define A5PSW_ifOutBroadcastPkts        0x8A8
0168 /* Ether */
0169 #define A5PSW_etherStatsDropEvents      0x8AC
0170 #define A5PSW_etherStatsOctets          0x8B0
0171 #define A5PSW_etherStatsPkts            0x8B4
0172 #define A5PSW_etherStatsUndersizePkts       0x8B8
0173 #define A5PSW_etherStatsOversizePkts        0x8BC
0174 #define A5PSW_etherStatsPkts64Octets        0x8C0
0175 #define A5PSW_etherStatsPkts65to127Octets   0x8C4
0176 #define A5PSW_etherStatsPkts128to255Octets  0x8C8
0177 #define A5PSW_etherStatsPkts256to511Octets  0x8CC
0178 #define A5PSW_etherStatsPkts512to1023Octets 0x8D0
0179 #define A5PSW_etherStatsPkts1024to1518Octets    0x8D4
0180 #define A5PSW_etherStatsPkts1519toXOctets   0x8D8
0181 #define A5PSW_etherStatsJabbers         0x8DC
0182 #define A5PSW_etherStatsFragments       0x8E0
0183 
0184 #define A5PSW_VLANReceived          0x8E8
0185 #define A5PSW_VLANTransmitted           0x8EC
0186 
0187 #define A5PSW_aDeferred             0x910
0188 #define A5PSW_aMultipleCollisions       0x914
0189 #define A5PSW_aSingleCollisions         0x918
0190 #define A5PSW_aLateCollisions           0x91C
0191 #define A5PSW_aExcessiveCollisions      0x920
0192 #define A5PSW_aCarrierSenseErrors       0x924
0193 
0194 #define A5PSW_VLAN_TAG(prio, id)    (((prio) << 12) | (id))
0195 #define A5PSW_PORTS_NUM         5
0196 #define A5PSW_CPU_PORT          (A5PSW_PORTS_NUM - 1)
0197 #define A5PSW_MDIO_DEF_FREQ     2500000
0198 #define A5PSW_MDIO_TIMEOUT      100
0199 #define A5PSW_JUMBO_LEN         (10 * SZ_1K)
0200 #define A5PSW_MDIO_CLK_DIV_MIN      5
0201 #define A5PSW_TAG_LEN           8
0202 #define A5PSW_VLAN_COUNT        32
0203 
0204 /* Ensure enough space for 2 VLAN tags */
0205 #define A5PSW_EXTRA_MTU_LEN     (A5PSW_TAG_LEN + 8)
0206 #define A5PSW_MAX_MTU           (A5PSW_JUMBO_LEN - A5PSW_EXTRA_MTU_LEN)
0207 
0208 #define A5PSW_PATTERN_MGMTFWD       0
0209 
0210 #define A5PSW_LK_BUSY_USEC_POLL     10
0211 #define A5PSW_CTRL_TIMEOUT      1000
0212 #define A5PSW_TABLE_ENTRIES     8192
0213 
0214 struct fdb_entry {
0215     u8 mac[ETH_ALEN];
0216     u16 valid:1;
0217     u16 is_static:1;
0218     u16 prio:3;
0219     u16 port_mask:5;
0220     u16 reserved:6;
0221 } __packed;
0222 
0223 union lk_data {
0224     struct {
0225         u32 lo;
0226         u32 hi;
0227     };
0228     struct fdb_entry entry;
0229 };
0230 
0231 /**
0232  * struct a5psw - switch struct
0233  * @base: Base address of the switch
0234  * @hclk: hclk_switch clock
0235  * @clk: clk_switch clock
0236  * @dev: Device associated to the switch
0237  * @mii_bus: MDIO bus struct
0238  * @mdio_freq: MDIO bus frequency requested
0239  * @pcs: Array of PCS connected to the switch ports (not for the CPU)
0240  * @ds: DSA switch struct
0241  * @stats_lock: lock to access statistics (shared HI counter)
0242  * @lk_lock: Lock for the lookup table
0243  * @reg_lock: Lock for register read-modify-write operation
0244  * @bridged_ports: Mask of ports that are bridged and should be flooded
0245  * @br_dev: Bridge net device
0246  */
0247 struct a5psw {
0248     void __iomem *base;
0249     struct clk *hclk;
0250     struct clk *clk;
0251     struct device *dev;
0252     struct mii_bus  *mii_bus;
0253     struct phylink_pcs *pcs[A5PSW_PORTS_NUM - 1];
0254     struct dsa_switch ds;
0255     struct mutex lk_lock;
0256     spinlock_t reg_lock;
0257     u32 bridged_ports;
0258     struct net_device *br_dev;
0259 };