linux/drivers/net/dsa/rtl8366rb.c
<<
>>
Prefs
   1// SPDX-License-Identifier: GPL-2.0
   2/* Realtek SMI subdriver for the Realtek RTL8366RB ethernet switch
   3 *
   4 * This is a sparsely documented chip, the only viable documentation seems
   5 * to be a patched up code drop from the vendor that appear in various
   6 * GPL source trees.
   7 *
   8 * Copyright (C) 2017 Linus Walleij <linus.walleij@linaro.org>
   9 * Copyright (C) 2009-2010 Gabor Juhos <juhosg@openwrt.org>
  10 * Copyright (C) 2010 Antti Seppälä <a.seppala@gmail.com>
  11 * Copyright (C) 2010 Roman Yeryomin <roman@advem.lv>
  12 * Copyright (C) 2011 Colin Leitner <colin.leitner@googlemail.com>
  13 */
  14
  15#include <linux/bitops.h>
  16#include <linux/etherdevice.h>
  17#include <linux/interrupt.h>
  18#include <linux/irqdomain.h>
  19#include <linux/irqchip/chained_irq.h>
  20#include <linux/of_irq.h>
  21#include <linux/regmap.h>
  22
  23#include "realtek-smi.h"
  24
  25#define RTL8366RB_PORT_NUM_CPU          5
  26#define RTL8366RB_NUM_PORTS             6
  27#define RTL8366RB_PHY_NO_MAX            4
  28#define RTL8366RB_PHY_ADDR_MAX          31
  29
  30/* Switch Global Configuration register */
  31#define RTL8366RB_SGCR                          0x0000
  32#define RTL8366RB_SGCR_EN_BC_STORM_CTRL         BIT(0)
  33#define RTL8366RB_SGCR_MAX_LENGTH(a)            ((a) << 4)
  34#define RTL8366RB_SGCR_MAX_LENGTH_MASK          RTL8366RB_SGCR_MAX_LENGTH(0x3)
  35#define RTL8366RB_SGCR_MAX_LENGTH_1522          RTL8366RB_SGCR_MAX_LENGTH(0x0)
  36#define RTL8366RB_SGCR_MAX_LENGTH_1536          RTL8366RB_SGCR_MAX_LENGTH(0x1)
  37#define RTL8366RB_SGCR_MAX_LENGTH_1552          RTL8366RB_SGCR_MAX_LENGTH(0x2)
  38#define RTL8366RB_SGCR_MAX_LENGTH_9216          RTL8366RB_SGCR_MAX_LENGTH(0x3)
  39#define RTL8366RB_SGCR_EN_VLAN                  BIT(13)
  40#define RTL8366RB_SGCR_EN_VLAN_4KTB             BIT(14)
  41
  42/* Port Enable Control register */
  43#define RTL8366RB_PECR                          0x0001
  44
  45/* Switch Security Control registers */
  46#define RTL8366RB_SSCR0                         0x0002
  47#define RTL8366RB_SSCR1                         0x0003
  48#define RTL8366RB_SSCR2                         0x0004
  49#define RTL8366RB_SSCR2_DROP_UNKNOWN_DA         BIT(0)
  50
  51/* Port Mode Control registers */
  52#define RTL8366RB_PMC0                          0x0005
  53#define RTL8366RB_PMC0_SPI                      BIT(0)
  54#define RTL8366RB_PMC0_EN_AUTOLOAD              BIT(1)
  55#define RTL8366RB_PMC0_PROBE                    BIT(2)
  56#define RTL8366RB_PMC0_DIS_BISR                 BIT(3)
  57#define RTL8366RB_PMC0_ADCTEST                  BIT(4)
  58#define RTL8366RB_PMC0_SRAM_DIAG                BIT(5)
  59#define RTL8366RB_PMC0_EN_SCAN                  BIT(6)
  60#define RTL8366RB_PMC0_P4_IOMODE_SHIFT          7
  61#define RTL8366RB_PMC0_P4_IOMODE_MASK           GENMASK(9, 7)
  62#define RTL8366RB_PMC0_P5_IOMODE_SHIFT          10
  63#define RTL8366RB_PMC0_P5_IOMODE_MASK           GENMASK(12, 10)
  64#define RTL8366RB_PMC0_SDSMODE_SHIFT            13
  65#define RTL8366RB_PMC0_SDSMODE_MASK             GENMASK(15, 13)
  66#define RTL8366RB_PMC1                          0x0006
  67
  68/* Port Mirror Control Register */
  69#define RTL8366RB_PMCR                          0x0007
  70#define RTL8366RB_PMCR_SOURCE_PORT(a)           (a)
  71#define RTL8366RB_PMCR_SOURCE_PORT_MASK         0x000f
  72#define RTL8366RB_PMCR_MONITOR_PORT(a)          ((a) << 4)
  73#define RTL8366RB_PMCR_MONITOR_PORT_MASK        0x00f0
  74#define RTL8366RB_PMCR_MIRROR_RX                BIT(8)
  75#define RTL8366RB_PMCR_MIRROR_TX                BIT(9)
  76#define RTL8366RB_PMCR_MIRROR_SPC               BIT(10)
  77#define RTL8366RB_PMCR_MIRROR_ISO               BIT(11)
  78
  79/* bits 0..7 = port 0, bits 8..15 = port 1 */
  80#define RTL8366RB_PAACR0                0x0010
  81/* bits 0..7 = port 2, bits 8..15 = port 3 */
  82#define RTL8366RB_PAACR1                0x0011
  83/* bits 0..7 = port 4, bits 8..15 = port 5 */
  84#define RTL8366RB_PAACR2                0x0012
  85#define RTL8366RB_PAACR_SPEED_10M       0
  86#define RTL8366RB_PAACR_SPEED_100M      1
  87#define RTL8366RB_PAACR_SPEED_1000M     2
  88#define RTL8366RB_PAACR_FULL_DUPLEX     BIT(2)
  89#define RTL8366RB_PAACR_LINK_UP         BIT(4)
  90#define RTL8366RB_PAACR_TX_PAUSE        BIT(5)
  91#define RTL8366RB_PAACR_RX_PAUSE        BIT(6)
  92#define RTL8366RB_PAACR_AN              BIT(7)
  93
  94#define RTL8366RB_PAACR_CPU_PORT        (RTL8366RB_PAACR_SPEED_1000M | \
  95                                         RTL8366RB_PAACR_FULL_DUPLEX | \
  96                                         RTL8366RB_PAACR_LINK_UP | \
  97                                         RTL8366RB_PAACR_TX_PAUSE | \
  98                                         RTL8366RB_PAACR_RX_PAUSE)
  99
 100/* bits 0..7 = port 0, bits 8..15 = port 1 */
 101#define RTL8366RB_PSTAT0                0x0014
 102/* bits 0..7 = port 2, bits 8..15 = port 3 */
 103#define RTL8366RB_PSTAT1                0x0015
 104/* bits 0..7 = port 4, bits 8..15 = port 5 */
 105#define RTL8366RB_PSTAT2                0x0016
 106
 107#define RTL8366RB_POWER_SAVING_REG      0x0021
 108
 109/* CPU port control reg */
 110#define RTL8368RB_CPU_CTRL_REG          0x0061
 111#define RTL8368RB_CPU_PORTS_MSK         0x00FF
 112/* Enables inserting custom tag length/type 0x8899 */
 113#define RTL8368RB_CPU_INSTAG            BIT(15)
 114
 115#define RTL8366RB_SMAR0                 0x0070 /* bits 0..15 */
 116#define RTL8366RB_SMAR1                 0x0071 /* bits 16..31 */
 117#define RTL8366RB_SMAR2                 0x0072 /* bits 32..47 */
 118
 119#define RTL8366RB_RESET_CTRL_REG                0x0100
 120#define RTL8366RB_CHIP_CTRL_RESET_HW            BIT(0)
 121#define RTL8366RB_CHIP_CTRL_RESET_SW            BIT(1)
 122
 123#define RTL8366RB_CHIP_ID_REG                   0x0509
 124#define RTL8366RB_CHIP_ID_8366                  0x5937
 125#define RTL8366RB_CHIP_VERSION_CTRL_REG         0x050A
 126#define RTL8366RB_CHIP_VERSION_MASK             0xf
 127
 128/* PHY registers control */
 129#define RTL8366RB_PHY_ACCESS_CTRL_REG           0x8000
 130#define RTL8366RB_PHY_CTRL_READ                 BIT(0)
 131#define RTL8366RB_PHY_CTRL_WRITE                0
 132#define RTL8366RB_PHY_ACCESS_BUSY_REG           0x8001
 133#define RTL8366RB_PHY_INT_BUSY                  BIT(0)
 134#define RTL8366RB_PHY_EXT_BUSY                  BIT(4)
 135#define RTL8366RB_PHY_ACCESS_DATA_REG           0x8002
 136#define RTL8366RB_PHY_EXT_CTRL_REG              0x8010
 137#define RTL8366RB_PHY_EXT_WRDATA_REG            0x8011
 138#define RTL8366RB_PHY_EXT_RDDATA_REG            0x8012
 139
 140#define RTL8366RB_PHY_REG_MASK                  0x1f
 141#define RTL8366RB_PHY_PAGE_OFFSET               5
 142#define RTL8366RB_PHY_PAGE_MASK                 (0xf << 5)
 143#define RTL8366RB_PHY_NO_OFFSET                 9
 144#define RTL8366RB_PHY_NO_MASK                   (0x1f << 9)
 145
 146#define RTL8366RB_VLAN_INGRESS_CTRL2_REG        0x037f
 147
 148/* LED control registers */
 149#define RTL8366RB_LED_BLINKRATE_REG             0x0430
 150#define RTL8366RB_LED_BLINKRATE_MASK            0x0007
 151#define RTL8366RB_LED_BLINKRATE_28MS            0x0000
 152#define RTL8366RB_LED_BLINKRATE_56MS            0x0001
 153#define RTL8366RB_LED_BLINKRATE_84MS            0x0002
 154#define RTL8366RB_LED_BLINKRATE_111MS           0x0003
 155#define RTL8366RB_LED_BLINKRATE_222MS           0x0004
 156#define RTL8366RB_LED_BLINKRATE_446MS           0x0005
 157
 158#define RTL8366RB_LED_CTRL_REG                  0x0431
 159#define RTL8366RB_LED_OFF                       0x0
 160#define RTL8366RB_LED_DUP_COL                   0x1
 161#define RTL8366RB_LED_LINK_ACT                  0x2
 162#define RTL8366RB_LED_SPD1000                   0x3
 163#define RTL8366RB_LED_SPD100                    0x4
 164#define RTL8366RB_LED_SPD10                     0x5
 165#define RTL8366RB_LED_SPD1000_ACT               0x6
 166#define RTL8366RB_LED_SPD100_ACT                0x7
 167#define RTL8366RB_LED_SPD10_ACT                 0x8
 168#define RTL8366RB_LED_SPD100_10_ACT             0x9
 169#define RTL8366RB_LED_FIBER                     0xa
 170#define RTL8366RB_LED_AN_FAULT                  0xb
 171#define RTL8366RB_LED_LINK_RX                   0xc
 172#define RTL8366RB_LED_LINK_TX                   0xd
 173#define RTL8366RB_LED_MASTER                    0xe
 174#define RTL8366RB_LED_FORCE                     0xf
 175#define RTL8366RB_LED_0_1_CTRL_REG              0x0432
 176#define RTL8366RB_LED_1_OFFSET                  6
 177#define RTL8366RB_LED_2_3_CTRL_REG              0x0433
 178#define RTL8366RB_LED_3_OFFSET                  6
 179
 180#define RTL8366RB_MIB_COUNT                     33
 181#define RTL8366RB_GLOBAL_MIB_COUNT              1
 182#define RTL8366RB_MIB_COUNTER_PORT_OFFSET       0x0050
 183#define RTL8366RB_MIB_COUNTER_BASE              0x1000
 184#define RTL8366RB_MIB_CTRL_REG                  0x13F0
 185#define RTL8366RB_MIB_CTRL_USER_MASK            0x0FFC
 186#define RTL8366RB_MIB_CTRL_BUSY_MASK            BIT(0)
 187#define RTL8366RB_MIB_CTRL_RESET_MASK           BIT(1)
 188#define RTL8366RB_MIB_CTRL_PORT_RESET(_p)       BIT(2 + (_p))
 189#define RTL8366RB_MIB_CTRL_GLOBAL_RESET         BIT(11)
 190
 191#define RTL8366RB_PORT_VLAN_CTRL_BASE           0x0063
 192#define RTL8366RB_PORT_VLAN_CTRL_REG(_p)  \
 193                (RTL8366RB_PORT_VLAN_CTRL_BASE + (_p) / 4)
 194#define RTL8366RB_PORT_VLAN_CTRL_MASK           0xf
 195#define RTL8366RB_PORT_VLAN_CTRL_SHIFT(_p)      (4 * ((_p) % 4))
 196
 197#define RTL8366RB_VLAN_TABLE_READ_BASE          0x018C
 198#define RTL8366RB_VLAN_TABLE_WRITE_BASE         0x0185
 199
 200#define RTL8366RB_TABLE_ACCESS_CTRL_REG         0x0180
 201#define RTL8366RB_TABLE_VLAN_READ_CTRL          0x0E01
 202#define RTL8366RB_TABLE_VLAN_WRITE_CTRL         0x0F01
 203
 204#define RTL8366RB_VLAN_MC_BASE(_x)              (0x0020 + (_x) * 3)
 205
 206#define RTL8366RB_PORT_LINK_STATUS_BASE         0x0014
 207#define RTL8366RB_PORT_STATUS_SPEED_MASK        0x0003
 208#define RTL8366RB_PORT_STATUS_DUPLEX_MASK       0x0004
 209#define RTL8366RB_PORT_STATUS_LINK_MASK         0x0010
 210#define RTL8366RB_PORT_STATUS_TXPAUSE_MASK      0x0020
 211#define RTL8366RB_PORT_STATUS_RXPAUSE_MASK      0x0040
 212#define RTL8366RB_PORT_STATUS_AN_MASK           0x0080
 213
 214#define RTL8366RB_NUM_VLANS             16
 215#define RTL8366RB_NUM_LEDGROUPS         4
 216#define RTL8366RB_NUM_VIDS              4096
 217#define RTL8366RB_PRIORITYMAX           7
 218#define RTL8366RB_FIDMAX                7
 219
 220#define RTL8366RB_PORT_1                BIT(0) /* In userspace port 0 */
 221#define RTL8366RB_PORT_2                BIT(1) /* In userspace port 1 */
 222#define RTL8366RB_PORT_3                BIT(2) /* In userspace port 2 */
 223#define RTL8366RB_PORT_4                BIT(3) /* In userspace port 3 */
 224#define RTL8366RB_PORT_5                BIT(4) /* In userspace port 4 */
 225
 226#define RTL8366RB_PORT_CPU              BIT(5) /* CPU port */
 227
 228#define RTL8366RB_PORT_ALL              (RTL8366RB_PORT_1 |     \
 229                                         RTL8366RB_PORT_2 |     \
 230                                         RTL8366RB_PORT_3 |     \
 231                                         RTL8366RB_PORT_4 |     \
 232                                         RTL8366RB_PORT_5 |     \
 233                                         RTL8366RB_PORT_CPU)
 234
 235#define RTL8366RB_PORT_ALL_BUT_CPU      (RTL8366RB_PORT_1 |     \
 236                                         RTL8366RB_PORT_2 |     \
 237                                         RTL8366RB_PORT_3 |     \
 238                                         RTL8366RB_PORT_4 |     \
 239                                         RTL8366RB_PORT_5)
 240
 241#define RTL8366RB_PORT_ALL_EXTERNAL     (RTL8366RB_PORT_1 |     \
 242                                         RTL8366RB_PORT_2 |     \
 243                                         RTL8366RB_PORT_3 |     \
 244                                         RTL8366RB_PORT_4)
 245
 246#define RTL8366RB_PORT_ALL_INTERNAL      RTL8366RB_PORT_CPU
 247
 248/* First configuration word per member config, VID and prio */
 249#define RTL8366RB_VLAN_VID_MASK         0xfff
 250#define RTL8366RB_VLAN_PRIORITY_SHIFT   12
 251#define RTL8366RB_VLAN_PRIORITY_MASK    0x7
 252/* Second configuration word per member config, member and untagged */
 253#define RTL8366RB_VLAN_UNTAG_SHIFT      8
 254#define RTL8366RB_VLAN_UNTAG_MASK       0xff
 255#define RTL8366RB_VLAN_MEMBER_MASK      0xff
 256/* Third config word per member config, STAG currently unused */
 257#define RTL8366RB_VLAN_STAG_MBR_MASK    0xff
 258#define RTL8366RB_VLAN_STAG_MBR_SHIFT   8
 259#define RTL8366RB_VLAN_STAG_IDX_MASK    0x7
 260#define RTL8366RB_VLAN_STAG_IDX_SHIFT   5
 261#define RTL8366RB_VLAN_FID_MASK         0x7
 262
 263/* Port ingress bandwidth control */
 264#define RTL8366RB_IB_BASE               0x0200
 265#define RTL8366RB_IB_REG(pnum)          (RTL8366RB_IB_BASE + (pnum))
 266#define RTL8366RB_IB_BDTH_MASK          0x3fff
 267#define RTL8366RB_IB_PREIFG             BIT(14)
 268
 269/* Port egress bandwidth control */
 270#define RTL8366RB_EB_BASE               0x02d1
 271#define RTL8366RB_EB_REG(pnum)          (RTL8366RB_EB_BASE + (pnum))
 272#define RTL8366RB_EB_BDTH_MASK          0x3fff
 273#define RTL8366RB_EB_PREIFG_REG         0x02f8
 274#define RTL8366RB_EB_PREIFG             BIT(9)
 275
 276#define RTL8366RB_BDTH_SW_MAX           1048512 /* 1048576? */
 277#define RTL8366RB_BDTH_UNIT             64
 278#define RTL8366RB_BDTH_REG_DEFAULT      16383
 279
 280/* QOS */
 281#define RTL8366RB_QOS                   BIT(15)
 282/* Include/Exclude Preamble and IFG (20 bytes). 0:Exclude, 1:Include. */
 283#define RTL8366RB_QOS_DEFAULT_PREIFG    1
 284
 285/* Interrupt handling */
 286#define RTL8366RB_INTERRUPT_CONTROL_REG 0x0440
 287#define RTL8366RB_INTERRUPT_POLARITY    BIT(0)
 288#define RTL8366RB_P4_RGMII_LED          BIT(2)
 289#define RTL8366RB_INTERRUPT_MASK_REG    0x0441
 290#define RTL8366RB_INTERRUPT_LINK_CHGALL GENMASK(11, 0)
 291#define RTL8366RB_INTERRUPT_ACLEXCEED   BIT(8)
 292#define RTL8366RB_INTERRUPT_STORMEXCEED BIT(9)
 293#define RTL8366RB_INTERRUPT_P4_FIBER    BIT(12)
 294#define RTL8366RB_INTERRUPT_P4_UTP      BIT(13)
 295#define RTL8366RB_INTERRUPT_VALID       (RTL8366RB_INTERRUPT_LINK_CHGALL | \
 296                                         RTL8366RB_INTERRUPT_ACLEXCEED | \
 297                                         RTL8366RB_INTERRUPT_STORMEXCEED | \
 298                                         RTL8366RB_INTERRUPT_P4_FIBER | \
 299                                         RTL8366RB_INTERRUPT_P4_UTP)
 300#define RTL8366RB_INTERRUPT_STATUS_REG  0x0442
 301#define RTL8366RB_NUM_INTERRUPT         14 /* 0..13 */
 302
 303/* bits 0..5 enable force when cleared */
 304#define RTL8366RB_MAC_FORCE_CTRL_REG    0x0F11
 305
 306#define RTL8366RB_OAM_PARSER_REG        0x0F14
 307#define RTL8366RB_OAM_MULTIPLEXER_REG   0x0F15
 308
 309#define RTL8366RB_GREEN_FEATURE_REG     0x0F51
 310#define RTL8366RB_GREEN_FEATURE_MSK     0x0007
 311#define RTL8366RB_GREEN_FEATURE_TX      BIT(0)
 312#define RTL8366RB_GREEN_FEATURE_RX      BIT(2)
 313
 314static struct rtl8366_mib_counter rtl8366rb_mib_counters[] = {
 315        { 0,  0, 4, "IfInOctets"                                },
 316        { 0,  4, 4, "EtherStatsOctets"                          },
 317        { 0,  8, 2, "EtherStatsUnderSizePkts"                   },
 318        { 0, 10, 2, "EtherFragments"                            },
 319        { 0, 12, 2, "EtherStatsPkts64Octets"                    },
 320        { 0, 14, 2, "EtherStatsPkts65to127Octets"               },
 321        { 0, 16, 2, "EtherStatsPkts128to255Octets"              },
 322        { 0, 18, 2, "EtherStatsPkts256to511Octets"              },
 323        { 0, 20, 2, "EtherStatsPkts512to1023Octets"             },
 324        { 0, 22, 2, "EtherStatsPkts1024to1518Octets"            },
 325        { 0, 24, 2, "EtherOversizeStats"                        },
 326        { 0, 26, 2, "EtherStatsJabbers"                         },
 327        { 0, 28, 2, "IfInUcastPkts"                             },
 328        { 0, 30, 2, "EtherStatsMulticastPkts"                   },
 329        { 0, 32, 2, "EtherStatsBroadcastPkts"                   },
 330        { 0, 34, 2, "EtherStatsDropEvents"                      },
 331        { 0, 36, 2, "Dot3StatsFCSErrors"                        },
 332        { 0, 38, 2, "Dot3StatsSymbolErrors"                     },
 333        { 0, 40, 2, "Dot3InPauseFrames"                         },
 334        { 0, 42, 2, "Dot3ControlInUnknownOpcodes"               },
 335        { 0, 44, 4, "IfOutOctets"                               },
 336        { 0, 48, 2, "Dot3StatsSingleCollisionFrames"            },
 337        { 0, 50, 2, "Dot3StatMultipleCollisionFrames"           },
 338        { 0, 52, 2, "Dot3sDeferredTransmissions"                },
 339        { 0, 54, 2, "Dot3StatsLateCollisions"                   },
 340        { 0, 56, 2, "EtherStatsCollisions"                      },
 341        { 0, 58, 2, "Dot3StatsExcessiveCollisions"              },
 342        { 0, 60, 2, "Dot3OutPauseFrames"                        },
 343        { 0, 62, 2, "Dot1dBasePortDelayExceededDiscards"        },
 344        { 0, 64, 2, "Dot1dTpPortInDiscards"                     },
 345        { 0, 66, 2, "IfOutUcastPkts"                            },
 346        { 0, 68, 2, "IfOutMulticastPkts"                        },
 347        { 0, 70, 2, "IfOutBroadcastPkts"                        },
 348};
 349
 350static int rtl8366rb_get_mib_counter(struct realtek_smi *smi,
 351                                     int port,
 352                                     struct rtl8366_mib_counter *mib,
 353                                     u64 *mibvalue)
 354{
 355        u32 addr, val;
 356        int ret;
 357        int i;
 358
 359        addr = RTL8366RB_MIB_COUNTER_BASE +
 360                RTL8366RB_MIB_COUNTER_PORT_OFFSET * (port) +
 361                mib->offset;
 362
 363        /* Writing access counter address first
 364         * then ASIC will prepare 64bits counter wait for being retrived
 365         */
 366        ret = regmap_write(smi->map, addr, 0); /* Write whatever */
 367        if (ret)
 368                return ret;
 369
 370        /* Read MIB control register */
 371        ret = regmap_read(smi->map, RTL8366RB_MIB_CTRL_REG, &val);
 372        if (ret)
 373                return -EIO;
 374
 375        if (val & RTL8366RB_MIB_CTRL_BUSY_MASK)
 376                return -EBUSY;
 377
 378        if (val & RTL8366RB_MIB_CTRL_RESET_MASK)
 379                return -EIO;
 380
 381        /* Read each individual MIB 16 bits at the time */
 382        *mibvalue = 0;
 383        for (i = mib->length; i > 0; i--) {
 384                ret = regmap_read(smi->map, addr + (i - 1), &val);
 385                if (ret)
 386                        return ret;
 387                *mibvalue = (*mibvalue << 16) | (val & 0xFFFF);
 388        }
 389        return 0;
 390}
 391
 392static u32 rtl8366rb_get_irqmask(struct irq_data *d)
 393{
 394        int line = irqd_to_hwirq(d);
 395        u32 val;
 396
 397        /* For line interrupts we combine link down in bits
 398         * 6..11 with link up in bits 0..5 into one interrupt.
 399         */
 400        if (line < 12)
 401                val = BIT(line) | BIT(line + 6);
 402        else
 403                val = BIT(line);
 404        return val;
 405}
 406
 407static void rtl8366rb_mask_irq(struct irq_data *d)
 408{
 409        struct realtek_smi *smi = irq_data_get_irq_chip_data(d);
 410        int ret;
 411
 412        ret = regmap_update_bits(smi->map, RTL8366RB_INTERRUPT_MASK_REG,
 413                                 rtl8366rb_get_irqmask(d), 0);
 414        if (ret)
 415                dev_err(smi->dev, "could not mask IRQ\n");
 416}
 417
 418static void rtl8366rb_unmask_irq(struct irq_data *d)
 419{
 420        struct realtek_smi *smi = irq_data_get_irq_chip_data(d);
 421        int ret;
 422
 423        ret = regmap_update_bits(smi->map, RTL8366RB_INTERRUPT_MASK_REG,
 424                                 rtl8366rb_get_irqmask(d),
 425                                 rtl8366rb_get_irqmask(d));
 426        if (ret)
 427                dev_err(smi->dev, "could not unmask IRQ\n");
 428}
 429
 430static irqreturn_t rtl8366rb_irq(int irq, void *data)
 431{
 432        struct realtek_smi *smi = data;
 433        u32 stat;
 434        int ret;
 435
 436        /* This clears the IRQ status register */
 437        ret = regmap_read(smi->map, RTL8366RB_INTERRUPT_STATUS_REG,
 438                          &stat);
 439        if (ret) {
 440                dev_err(smi->dev, "can't read interrupt status\n");
 441                return IRQ_NONE;
 442        }
 443        stat &= RTL8366RB_INTERRUPT_VALID;
 444        if (!stat)
 445                return IRQ_NONE;
 446        while (stat) {
 447                int line = __ffs(stat);
 448                int child_irq;
 449
 450                stat &= ~BIT(line);
 451                /* For line interrupts we combine link down in bits
 452                 * 6..11 with link up in bits 0..5 into one interrupt.
 453                 */
 454                if (line < 12 && line > 5)
 455                        line -= 5;
 456                child_irq = irq_find_mapping(smi->irqdomain, line);
 457                handle_nested_irq(child_irq);
 458        }
 459        return IRQ_HANDLED;
 460}
 461
 462static struct irq_chip rtl8366rb_irq_chip = {
 463        .name = "RTL8366RB",
 464        .irq_mask = rtl8366rb_mask_irq,
 465        .irq_unmask = rtl8366rb_unmask_irq,
 466};
 467
 468static int rtl8366rb_irq_map(struct irq_domain *domain, unsigned int irq,
 469                             irq_hw_number_t hwirq)
 470{
 471        irq_set_chip_data(irq, domain->host_data);
 472        irq_set_chip_and_handler(irq, &rtl8366rb_irq_chip, handle_simple_irq);
 473        irq_set_nested_thread(irq, 1);
 474        irq_set_noprobe(irq);
 475
 476        return 0;
 477}
 478
 479static void rtl8366rb_irq_unmap(struct irq_domain *d, unsigned int irq)
 480{
 481        irq_set_nested_thread(irq, 0);
 482        irq_set_chip_and_handler(irq, NULL, NULL);
 483        irq_set_chip_data(irq, NULL);
 484}
 485
 486static const struct irq_domain_ops rtl8366rb_irqdomain_ops = {
 487        .map = rtl8366rb_irq_map,
 488        .unmap = rtl8366rb_irq_unmap,
 489        .xlate  = irq_domain_xlate_onecell,
 490};
 491
 492static int rtl8366rb_setup_cascaded_irq(struct realtek_smi *smi)
 493{
 494        struct device_node *intc;
 495        unsigned long irq_trig;
 496        int irq;
 497        int ret;
 498        u32 val;
 499        int i;
 500
 501        intc = of_get_child_by_name(smi->dev->of_node, "interrupt-controller");
 502        if (!intc) {
 503                dev_err(smi->dev, "missing child interrupt-controller node\n");
 504                return -EINVAL;
 505        }
 506        /* RB8366RB IRQs cascade off this one */
 507        irq = of_irq_get(intc, 0);
 508        if (irq <= 0) {
 509                dev_err(smi->dev, "failed to get parent IRQ\n");
 510                return irq ? irq : -EINVAL;
 511        }
 512
 513        /* This clears the IRQ status register */
 514        ret = regmap_read(smi->map, RTL8366RB_INTERRUPT_STATUS_REG,
 515                          &val);
 516        if (ret) {
 517                dev_err(smi->dev, "can't read interrupt status\n");
 518                return ret;
 519        }
 520
 521        /* Fetch IRQ edge information from the descriptor */
 522        irq_trig = irqd_get_trigger_type(irq_get_irq_data(irq));
 523        switch (irq_trig) {
 524        case IRQF_TRIGGER_RISING:
 525        case IRQF_TRIGGER_HIGH:
 526                dev_info(smi->dev, "active high/rising IRQ\n");
 527                val = 0;
 528                break;
 529        case IRQF_TRIGGER_FALLING:
 530        case IRQF_TRIGGER_LOW:
 531                dev_info(smi->dev, "active low/falling IRQ\n");
 532                val = RTL8366RB_INTERRUPT_POLARITY;
 533                break;
 534        }
 535        ret = regmap_update_bits(smi->map, RTL8366RB_INTERRUPT_CONTROL_REG,
 536                                 RTL8366RB_INTERRUPT_POLARITY,
 537                                 val);
 538        if (ret) {
 539                dev_err(smi->dev, "could not configure IRQ polarity\n");
 540                return ret;
 541        }
 542
 543        ret = devm_request_threaded_irq(smi->dev, irq, NULL,
 544                                        rtl8366rb_irq, IRQF_ONESHOT,
 545                                        "RTL8366RB", smi);
 546        if (ret) {
 547                dev_err(smi->dev, "unable to request irq: %d\n", ret);
 548                return ret;
 549        }
 550        smi->irqdomain = irq_domain_add_linear(intc,
 551                                               RTL8366RB_NUM_INTERRUPT,
 552                                               &rtl8366rb_irqdomain_ops,
 553                                               smi);
 554        if (!smi->irqdomain) {
 555                dev_err(smi->dev, "failed to create IRQ domain\n");
 556                return -EINVAL;
 557        }
 558        for (i = 0; i < smi->num_ports; i++)
 559                irq_set_parent(irq_create_mapping(smi->irqdomain, i), irq);
 560
 561        return 0;
 562}
 563
 564static int rtl8366rb_set_addr(struct realtek_smi *smi)
 565{
 566        u8 addr[ETH_ALEN];
 567        u16 val;
 568        int ret;
 569
 570        eth_random_addr(addr);
 571
 572        dev_info(smi->dev, "set MAC: %02X:%02X:%02X:%02X:%02X:%02X\n",
 573                 addr[0], addr[1], addr[2], addr[3], addr[4], addr[5]);
 574        val = addr[0] << 8 | addr[1];
 575        ret = regmap_write(smi->map, RTL8366RB_SMAR0, val);
 576        if (ret)
 577                return ret;
 578        val = addr[2] << 8 | addr[3];
 579        ret = regmap_write(smi->map, RTL8366RB_SMAR1, val);
 580        if (ret)
 581                return ret;
 582        val = addr[4] << 8 | addr[5];
 583        ret = regmap_write(smi->map, RTL8366RB_SMAR2, val);
 584        if (ret)
 585                return ret;
 586
 587        return 0;
 588}
 589
 590/* Found in a vendor driver */
 591
 592/* For the "version 0" early silicon, appear in most source releases */
 593static const u16 rtl8366rb_init_jam_ver_0[] = {
 594        0x000B, 0x0001, 0x03A6, 0x0100, 0x03A7, 0x0001, 0x02D1, 0x3FFF,
 595        0x02D2, 0x3FFF, 0x02D3, 0x3FFF, 0x02D4, 0x3FFF, 0x02D5, 0x3FFF,
 596        0x02D6, 0x3FFF, 0x02D7, 0x3FFF, 0x02D8, 0x3FFF, 0x022B, 0x0688,
 597        0x022C, 0x0FAC, 0x03D0, 0x4688, 0x03D1, 0x01F5, 0x0000, 0x0830,
 598        0x02F9, 0x0200, 0x02F7, 0x7FFF, 0x02F8, 0x03FF, 0x0080, 0x03E8,
 599        0x0081, 0x00CE, 0x0082, 0x00DA, 0x0083, 0x0230, 0xBE0F, 0x2000,
 600        0x0231, 0x422A, 0x0232, 0x422A, 0x0233, 0x422A, 0x0234, 0x422A,
 601        0x0235, 0x422A, 0x0236, 0x422A, 0x0237, 0x422A, 0x0238, 0x422A,
 602        0x0239, 0x422A, 0x023A, 0x422A, 0x023B, 0x422A, 0x023C, 0x422A,
 603        0x023D, 0x422A, 0x023E, 0x422A, 0x023F, 0x422A, 0x0240, 0x422A,
 604        0x0241, 0x422A, 0x0242, 0x422A, 0x0243, 0x422A, 0x0244, 0x422A,
 605        0x0245, 0x422A, 0x0246, 0x422A, 0x0247, 0x422A, 0x0248, 0x422A,
 606        0x0249, 0x0146, 0x024A, 0x0146, 0x024B, 0x0146, 0xBE03, 0xC961,
 607        0x024D, 0x0146, 0x024E, 0x0146, 0x024F, 0x0146, 0x0250, 0x0146,
 608        0xBE64, 0x0226, 0x0252, 0x0146, 0x0253, 0x0146, 0x024C, 0x0146,
 609        0x0251, 0x0146, 0x0254, 0x0146, 0xBE62, 0x3FD0, 0x0084, 0x0320,
 610        0x0255, 0x0146, 0x0256, 0x0146, 0x0257, 0x0146, 0x0258, 0x0146,
 611        0x0259, 0x0146, 0x025A, 0x0146, 0x025B, 0x0146, 0x025C, 0x0146,
 612        0x025D, 0x0146, 0x025E, 0x0146, 0x025F, 0x0146, 0x0260, 0x0146,
 613        0x0261, 0xA23F, 0x0262, 0x0294, 0x0263, 0xA23F, 0x0264, 0x0294,
 614        0x0265, 0xA23F, 0x0266, 0x0294, 0x0267, 0xA23F, 0x0268, 0x0294,
 615        0x0269, 0xA23F, 0x026A, 0x0294, 0x026B, 0xA23F, 0x026C, 0x0294,
 616        0x026D, 0xA23F, 0x026E, 0x0294, 0x026F, 0xA23F, 0x0270, 0x0294,
 617        0x02F5, 0x0048, 0xBE09, 0x0E00, 0xBE1E, 0x0FA0, 0xBE14, 0x8448,
 618        0xBE15, 0x1007, 0xBE4A, 0xA284, 0xC454, 0x3F0B, 0xC474, 0x3F0B,
 619        0xBE48, 0x3672, 0xBE4B, 0x17A7, 0xBE4C, 0x0B15, 0xBE52, 0x0EDD,
 620        0xBE49, 0x8C00, 0xBE5B, 0x785C, 0xBE5C, 0x785C, 0xBE5D, 0x785C,
 621        0xBE61, 0x368A, 0xBE63, 0x9B84, 0xC456, 0xCC13, 0xC476, 0xCC13,
 622        0xBE65, 0x307D, 0xBE6D, 0x0005, 0xBE6E, 0xE120, 0xBE2E, 0x7BAF,
 623};
 624
 625/* This v1 init sequence is from Belkin F5D8235 U-Boot release */
 626static const u16 rtl8366rb_init_jam_ver_1[] = {
 627        0x0000, 0x0830, 0x0001, 0x8000, 0x0400, 0x8130, 0xBE78, 0x3C3C,
 628        0x0431, 0x5432, 0xBE37, 0x0CE4, 0x02FA, 0xFFDF, 0x02FB, 0xFFE0,
 629        0xC44C, 0x1585, 0xC44C, 0x1185, 0xC44C, 0x1585, 0xC46C, 0x1585,
 630        0xC46C, 0x1185, 0xC46C, 0x1585, 0xC451, 0x2135, 0xC471, 0x2135,
 631        0xBE10, 0x8140, 0xBE15, 0x0007, 0xBE6E, 0xE120, 0xBE69, 0xD20F,
 632        0xBE6B, 0x0320, 0xBE24, 0xB000, 0xBE23, 0xFF51, 0xBE22, 0xDF20,
 633        0xBE21, 0x0140, 0xBE20, 0x00BB, 0xBE24, 0xB800, 0xBE24, 0x0000,
 634        0xBE24, 0x7000, 0xBE23, 0xFF51, 0xBE22, 0xDF60, 0xBE21, 0x0140,
 635        0xBE20, 0x0077, 0xBE24, 0x7800, 0xBE24, 0x0000, 0xBE2E, 0x7B7A,
 636        0xBE36, 0x0CE4, 0x02F5, 0x0048, 0xBE77, 0x2940, 0x000A, 0x83E0,
 637        0xBE79, 0x3C3C, 0xBE00, 0x1340,
 638};
 639
 640/* This v2 init sequence is from Belkin F5D8235 U-Boot release */
 641static const u16 rtl8366rb_init_jam_ver_2[] = {
 642        0x0450, 0x0000, 0x0400, 0x8130, 0x000A, 0x83ED, 0x0431, 0x5432,
 643        0xC44F, 0x6250, 0xC46F, 0x6250, 0xC456, 0x0C14, 0xC476, 0x0C14,
 644        0xC44C, 0x1C85, 0xC44C, 0x1885, 0xC44C, 0x1C85, 0xC46C, 0x1C85,
 645        0xC46C, 0x1885, 0xC46C, 0x1C85, 0xC44C, 0x0885, 0xC44C, 0x0881,
 646        0xC44C, 0x0885, 0xC46C, 0x0885, 0xC46C, 0x0881, 0xC46C, 0x0885,
 647        0xBE2E, 0x7BA7, 0xBE36, 0x1000, 0xBE37, 0x1000, 0x8000, 0x0001,
 648        0xBE69, 0xD50F, 0x8000, 0x0000, 0xBE69, 0xD50F, 0xBE6E, 0x0320,
 649        0xBE77, 0x2940, 0xBE78, 0x3C3C, 0xBE79, 0x3C3C, 0xBE6E, 0xE120,
 650        0x8000, 0x0001, 0xBE15, 0x1007, 0x8000, 0x0000, 0xBE15, 0x1007,
 651        0xBE14, 0x0448, 0xBE1E, 0x00A0, 0xBE10, 0x8160, 0xBE10, 0x8140,
 652        0xBE00, 0x1340, 0x0F51, 0x0010,
 653};
 654
 655/* Appears in a DDWRT code dump */
 656static const u16 rtl8366rb_init_jam_ver_3[] = {
 657        0x0000, 0x0830, 0x0400, 0x8130, 0x000A, 0x83ED, 0x0431, 0x5432,
 658        0x0F51, 0x0017, 0x02F5, 0x0048, 0x02FA, 0xFFDF, 0x02FB, 0xFFE0,
 659        0xC456, 0x0C14, 0xC476, 0x0C14, 0xC454, 0x3F8B, 0xC474, 0x3F8B,
 660        0xC450, 0x2071, 0xC470, 0x2071, 0xC451, 0x226B, 0xC471, 0x226B,
 661        0xC452, 0xA293, 0xC472, 0xA293, 0xC44C, 0x1585, 0xC44C, 0x1185,
 662        0xC44C, 0x1585, 0xC46C, 0x1585, 0xC46C, 0x1185, 0xC46C, 0x1585,
 663        0xC44C, 0x0185, 0xC44C, 0x0181, 0xC44C, 0x0185, 0xC46C, 0x0185,
 664        0xC46C, 0x0181, 0xC46C, 0x0185, 0xBE24, 0xB000, 0xBE23, 0xFF51,
 665        0xBE22, 0xDF20, 0xBE21, 0x0140, 0xBE20, 0x00BB, 0xBE24, 0xB800,
 666        0xBE24, 0x0000, 0xBE24, 0x7000, 0xBE23, 0xFF51, 0xBE22, 0xDF60,
 667        0xBE21, 0x0140, 0xBE20, 0x0077, 0xBE24, 0x7800, 0xBE24, 0x0000,
 668        0xBE2E, 0x7BA7, 0xBE36, 0x1000, 0xBE37, 0x1000, 0x8000, 0x0001,
 669        0xBE69, 0xD50F, 0x8000, 0x0000, 0xBE69, 0xD50F, 0xBE6B, 0x0320,
 670        0xBE77, 0x2800, 0xBE78, 0x3C3C, 0xBE79, 0x3C3C, 0xBE6E, 0xE120,
 671        0x8000, 0x0001, 0xBE10, 0x8140, 0x8000, 0x0000, 0xBE10, 0x8140,
 672        0xBE15, 0x1007, 0xBE14, 0x0448, 0xBE1E, 0x00A0, 0xBE10, 0x8160,
 673        0xBE10, 0x8140, 0xBE00, 0x1340, 0x0450, 0x0000, 0x0401, 0x0000,
 674};
 675
 676/* Belkin F5D8235 v1, "belkin,f5d8235-v1" */
 677static const u16 rtl8366rb_init_jam_f5d8235[] = {
 678        0x0242, 0x02BF, 0x0245, 0x02BF, 0x0248, 0x02BF, 0x024B, 0x02BF,
 679        0x024E, 0x02BF, 0x0251, 0x02BF, 0x0254, 0x0A3F, 0x0256, 0x0A3F,
 680        0x0258, 0x0A3F, 0x025A, 0x0A3F, 0x025C, 0x0A3F, 0x025E, 0x0A3F,
 681        0x0263, 0x007C, 0x0100, 0x0004, 0xBE5B, 0x3500, 0x800E, 0x200F,
 682        0xBE1D, 0x0F00, 0x8001, 0x5011, 0x800A, 0xA2F4, 0x800B, 0x17A3,
 683        0xBE4B, 0x17A3, 0xBE41, 0x5011, 0xBE17, 0x2100, 0x8000, 0x8304,
 684        0xBE40, 0x8304, 0xBE4A, 0xA2F4, 0x800C, 0xA8D5, 0x8014, 0x5500,
 685        0x8015, 0x0004, 0xBE4C, 0xA8D5, 0xBE59, 0x0008, 0xBE09, 0x0E00,
 686        0xBE36, 0x1036, 0xBE37, 0x1036, 0x800D, 0x00FF, 0xBE4D, 0x00FF,
 687};
 688
 689/* DGN3500, "netgear,dgn3500", "netgear,dgn3500b" */
 690static const u16 rtl8366rb_init_jam_dgn3500[] = {
 691        0x0000, 0x0830, 0x0400, 0x8130, 0x000A, 0x83ED, 0x0F51, 0x0017,
 692        0x02F5, 0x0048, 0x02FA, 0xFFDF, 0x02FB, 0xFFE0, 0x0450, 0x0000,
 693        0x0401, 0x0000, 0x0431, 0x0960,
 694};
 695
 696/* This jam table activates "green ethernet", which means low power mode
 697 * and is claimed to detect the cable length and not use more power than
 698 * necessary, and the ports should enter power saving mode 10 seconds after
 699 * a cable is disconnected. Seems to always be the same.
 700 */
 701static const u16 rtl8366rb_green_jam[][2] = {
 702        {0xBE78, 0x323C}, {0xBE77, 0x5000}, {0xBE2E, 0x7BA7},
 703        {0xBE59, 0x3459}, {0xBE5A, 0x745A}, {0xBE5B, 0x785C},
 704        {0xBE5C, 0x785C}, {0xBE6E, 0xE120}, {0xBE79, 0x323C},
 705};
 706
 707static int rtl8366rb_setup(struct dsa_switch *ds)
 708{
 709        struct realtek_smi *smi = ds->priv;
 710        const u16 *jam_table;
 711        u32 chip_ver = 0;
 712        u32 chip_id = 0;
 713        int jam_size;
 714        u32 val;
 715        int ret;
 716        int i;
 717
 718        ret = regmap_read(smi->map, RTL8366RB_CHIP_ID_REG, &chip_id);
 719        if (ret) {
 720                dev_err(smi->dev, "unable to read chip id\n");
 721                return ret;
 722        }
 723
 724        switch (chip_id) {
 725        case RTL8366RB_CHIP_ID_8366:
 726                break;
 727        default:
 728                dev_err(smi->dev, "unknown chip id (%04x)\n", chip_id);
 729                return -ENODEV;
 730        }
 731
 732        ret = regmap_read(smi->map, RTL8366RB_CHIP_VERSION_CTRL_REG,
 733                          &chip_ver);
 734        if (ret) {
 735                dev_err(smi->dev, "unable to read chip version\n");
 736                return ret;
 737        }
 738
 739        dev_info(smi->dev, "RTL%04x ver %u chip found\n",
 740                 chip_id, chip_ver & RTL8366RB_CHIP_VERSION_MASK);
 741
 742        /* Do the init dance using the right jam table */
 743        switch (chip_ver) {
 744        case 0:
 745                jam_table = rtl8366rb_init_jam_ver_0;
 746                jam_size = ARRAY_SIZE(rtl8366rb_init_jam_ver_0);
 747                break;
 748        case 1:
 749                jam_table = rtl8366rb_init_jam_ver_1;
 750                jam_size = ARRAY_SIZE(rtl8366rb_init_jam_ver_1);
 751                break;
 752        case 2:
 753                jam_table = rtl8366rb_init_jam_ver_2;
 754                jam_size = ARRAY_SIZE(rtl8366rb_init_jam_ver_2);
 755                break;
 756        default:
 757                jam_table = rtl8366rb_init_jam_ver_3;
 758                jam_size = ARRAY_SIZE(rtl8366rb_init_jam_ver_3);
 759                break;
 760        }
 761
 762        /* Special jam tables for special routers
 763         * TODO: are these necessary? Maintainers, please test
 764         * without them, using just the off-the-shelf tables.
 765         */
 766        if (of_machine_is_compatible("belkin,f5d8235-v1")) {
 767                jam_table = rtl8366rb_init_jam_f5d8235;
 768                jam_size = ARRAY_SIZE(rtl8366rb_init_jam_f5d8235);
 769        }
 770        if (of_machine_is_compatible("netgear,dgn3500") ||
 771            of_machine_is_compatible("netgear,dgn3500b")) {
 772                jam_table = rtl8366rb_init_jam_dgn3500;
 773                jam_size = ARRAY_SIZE(rtl8366rb_init_jam_dgn3500);
 774        }
 775
 776        i = 0;
 777        while (i < jam_size) {
 778                if ((jam_table[i] & 0xBE00) == 0xBE00) {
 779                        ret = regmap_read(smi->map,
 780                                          RTL8366RB_PHY_ACCESS_BUSY_REG,
 781                                          &val);
 782                        if (ret)
 783                                return ret;
 784                        if (!(val & RTL8366RB_PHY_INT_BUSY)) {
 785                                ret = regmap_write(smi->map,
 786                                                RTL8366RB_PHY_ACCESS_CTRL_REG,
 787                                                RTL8366RB_PHY_CTRL_WRITE);
 788                                if (ret)
 789                                        return ret;
 790                        }
 791                }
 792                dev_dbg(smi->dev, "jam %04x into register %04x\n",
 793                        jam_table[i + 1],
 794                        jam_table[i]);
 795                ret = regmap_write(smi->map,
 796                                   jam_table[i],
 797                                   jam_table[i + 1]);
 798                if (ret)
 799                        return ret;
 800                i += 2;
 801        }
 802
 803        /* Set up the "green ethernet" feature */
 804        i = 0;
 805        while (i < ARRAY_SIZE(rtl8366rb_green_jam)) {
 806                ret = regmap_read(smi->map, RTL8366RB_PHY_ACCESS_BUSY_REG,
 807                                  &val);
 808                if (ret)
 809                        return ret;
 810                if (!(val & RTL8366RB_PHY_INT_BUSY)) {
 811                        ret = regmap_write(smi->map,
 812                                           RTL8366RB_PHY_ACCESS_CTRL_REG,
 813                                           RTL8366RB_PHY_CTRL_WRITE);
 814                        if (ret)
 815                                return ret;
 816                        ret = regmap_write(smi->map,
 817                                           rtl8366rb_green_jam[i][0],
 818                                           rtl8366rb_green_jam[i][1]);
 819                        if (ret)
 820                                return ret;
 821                        i++;
 822                }
 823        }
 824        ret = regmap_write(smi->map,
 825                           RTL8366RB_GREEN_FEATURE_REG,
 826                           (chip_ver == 1) ? 0x0007 : 0x0003);
 827        if (ret)
 828                return ret;
 829
 830        /* Vendor driver sets 0x240 in registers 0xc and 0xd (undocumented) */
 831        ret = regmap_write(smi->map, 0x0c, 0x240);
 832        if (ret)
 833                return ret;
 834        ret = regmap_write(smi->map, 0x0d, 0x240);
 835        if (ret)
 836                return ret;
 837
 838        /* Set some random MAC address */
 839        ret = rtl8366rb_set_addr(smi);
 840        if (ret)
 841                return ret;
 842
 843        /* Enable CPU port and enable inserting CPU tag
 844         *
 845         * Disabling RTL8368RB_CPU_INSTAG here will change the behaviour
 846         * of the switch totally and it will start talking Realtek RRCP
 847         * internally. It is probably possible to experiment with this,
 848         * but then the kernel needs to understand and handle RRCP first.
 849         */
 850        ret = regmap_update_bits(smi->map, RTL8368RB_CPU_CTRL_REG,
 851                                 0xFFFF,
 852                                 RTL8368RB_CPU_INSTAG | BIT(smi->cpu_port));
 853        if (ret)
 854                return ret;
 855
 856        /* Make sure we default-enable the fixed CPU port */
 857        ret = regmap_update_bits(smi->map, RTL8366RB_PECR,
 858                                 BIT(smi->cpu_port),
 859                                 0);
 860        if (ret)
 861                return ret;
 862
 863        /* Set maximum packet length to 1536 bytes */
 864        ret = regmap_update_bits(smi->map, RTL8366RB_SGCR,
 865                                 RTL8366RB_SGCR_MAX_LENGTH_MASK,
 866                                 RTL8366RB_SGCR_MAX_LENGTH_1536);
 867        if (ret)
 868                return ret;
 869
 870        /* Enable learning for all ports */
 871        ret = regmap_write(smi->map, RTL8366RB_SSCR0, 0);
 872        if (ret)
 873                return ret;
 874
 875        /* Enable auto ageing for all ports */
 876        ret = regmap_write(smi->map, RTL8366RB_SSCR1, 0);
 877        if (ret)
 878                return ret;
 879
 880        /* Port 4 setup: this enables Port 4, usually the WAN port,
 881         * common PHY IO mode is apparently mode 0, and this is not what
 882         * the port is initialized to. There is no explanation of the
 883         * IO modes in the Realtek source code, if your WAN port is
 884         * connected to something exotic such as fiber, then this might
 885         * be worth experimenting with.
 886         */
 887        ret = regmap_update_bits(smi->map, RTL8366RB_PMC0,
 888                                 RTL8366RB_PMC0_P4_IOMODE_MASK,
 889                                 0 << RTL8366RB_PMC0_P4_IOMODE_SHIFT);
 890        if (ret)
 891                return ret;
 892
 893        /* Discard VLAN tagged packets if the port is not a member of
 894         * the VLAN with which the packets is associated.
 895         */
 896        ret = regmap_write(smi->map, RTL8366RB_VLAN_INGRESS_CTRL2_REG,
 897                           RTL8366RB_PORT_ALL);
 898        if (ret)
 899                return ret;
 900
 901        /* Don't drop packets whose DA has not been learned */
 902        ret = regmap_update_bits(smi->map, RTL8366RB_SSCR2,
 903                                 RTL8366RB_SSCR2_DROP_UNKNOWN_DA, 0);
 904        if (ret)
 905                return ret;
 906
 907        /* Set blinking, TODO: make this configurable */
 908        ret = regmap_update_bits(smi->map, RTL8366RB_LED_BLINKRATE_REG,
 909                                 RTL8366RB_LED_BLINKRATE_MASK,
 910                                 RTL8366RB_LED_BLINKRATE_56MS);
 911        if (ret)
 912                return ret;
 913
 914        /* Set up LED activity:
 915         * Each port has 4 LEDs, we configure all ports to the same
 916         * behaviour (no individual config) but we can set up each
 917         * LED separately.
 918         */
 919        if (smi->leds_disabled) {
 920                /* Turn everything off */
 921                regmap_update_bits(smi->map,
 922                                   RTL8366RB_LED_0_1_CTRL_REG,
 923                                   0x0FFF, 0);
 924                regmap_update_bits(smi->map,
 925                                   RTL8366RB_LED_2_3_CTRL_REG,
 926                                   0x0FFF, 0);
 927                regmap_update_bits(smi->map,
 928                                   RTL8366RB_INTERRUPT_CONTROL_REG,
 929                                   RTL8366RB_P4_RGMII_LED,
 930                                   0);
 931                val = RTL8366RB_LED_OFF;
 932        } else {
 933                /* TODO: make this configurable per LED */
 934                val = RTL8366RB_LED_FORCE;
 935        }
 936        for (i = 0; i < 4; i++) {
 937                ret = regmap_update_bits(smi->map,
 938                                         RTL8366RB_LED_CTRL_REG,
 939                                         0xf << (i * 4),
 940                                         val << (i * 4));
 941                if (ret)
 942                        return ret;
 943        }
 944
 945        ret = rtl8366_init_vlan(smi);
 946        if (ret)
 947                return ret;
 948
 949        ret = rtl8366rb_setup_cascaded_irq(smi);
 950        if (ret)
 951                dev_info(smi->dev, "no interrupt support\n");
 952
 953        ret = realtek_smi_setup_mdio(smi);
 954        if (ret) {
 955                dev_info(smi->dev, "could not set up MDIO bus\n");
 956                return -ENODEV;
 957        }
 958
 959        return 0;
 960}
 961
 962static enum dsa_tag_protocol rtl8366_get_tag_protocol(struct dsa_switch *ds,
 963                                                      int port)
 964{
 965        /* For now, the RTL switches are handled without any custom tags.
 966         *
 967         * It is possible to turn on "custom tags" by removing the
 968         * RTL8368RB_CPU_INSTAG flag when enabling the port but what it
 969         * does is unfamiliar to DSA: ethernet frames of type 8899, the Realtek
 970         * Remote Control Protocol (RRCP) start to appear on the CPU port of
 971         * the device. So this is not the ordinary few extra bytes in the
 972         * frame. Instead it appears that the switch starts to talk Realtek
 973         * RRCP internally which means a pretty complex RRCP implementation
 974         * decoding and responding the RRCP protocol is needed to exploit this.
 975         *
 976         * The OpenRRCP project (dormant since 2009) have reverse-egineered
 977         * parts of the protocol.
 978         */
 979        return DSA_TAG_PROTO_NONE;
 980}
 981
 982static void rtl8366rb_adjust_link(struct dsa_switch *ds, int port,
 983                                  struct phy_device *phydev)
 984{
 985        struct realtek_smi *smi = ds->priv;
 986        int ret;
 987
 988        if (port != smi->cpu_port)
 989                return;
 990
 991        dev_info(smi->dev, "adjust link on CPU port (%d)\n", port);
 992
 993        /* Force the fixed CPU port into 1Gbit mode, no autonegotiation */
 994        ret = regmap_update_bits(smi->map, RTL8366RB_MAC_FORCE_CTRL_REG,
 995                                 BIT(port), BIT(port));
 996        if (ret)
 997                return;
 998
 999        ret = regmap_update_bits(smi->map, RTL8366RB_PAACR2,
1000                                 0xFF00U,
1001                                 RTL8366RB_PAACR_CPU_PORT << 8);
1002        if (ret)
1003                return;
1004
1005        /* Enable the CPU port */
1006        ret = regmap_update_bits(smi->map, RTL8366RB_PECR, BIT(port),
1007                                 0);
1008        if (ret)
1009                return;
1010}
1011
1012static void rb8366rb_set_port_led(struct realtek_smi *smi,
1013                                  int port, bool enable)
1014{
1015        u16 val = enable ? 0x3f : 0;
1016        int ret;
1017
1018        if (smi->leds_disabled)
1019                return;
1020
1021        switch (port) {
1022        case 0:
1023                ret = regmap_update_bits(smi->map,
1024                                         RTL8366RB_LED_0_1_CTRL_REG,
1025                                         0x3F, val);
1026                break;
1027        case 1:
1028                ret = regmap_update_bits(smi->map,
1029                                         RTL8366RB_LED_0_1_CTRL_REG,
1030                                         0x3F << RTL8366RB_LED_1_OFFSET,
1031                                         val << RTL8366RB_LED_1_OFFSET);
1032                break;
1033        case 2:
1034                ret = regmap_update_bits(smi->map,
1035                                         RTL8366RB_LED_2_3_CTRL_REG,
1036                                         0x3F, val);
1037                break;
1038        case 3:
1039                ret = regmap_update_bits(smi->map,
1040                                         RTL8366RB_LED_2_3_CTRL_REG,
1041                                         0x3F << RTL8366RB_LED_3_OFFSET,
1042                                         val << RTL8366RB_LED_3_OFFSET);
1043                break;
1044        case 4:
1045                ret = regmap_update_bits(smi->map,
1046                                         RTL8366RB_INTERRUPT_CONTROL_REG,
1047                                         RTL8366RB_P4_RGMII_LED,
1048                                         enable ? RTL8366RB_P4_RGMII_LED : 0);
1049                break;
1050        default:
1051                dev_err(smi->dev, "no LED for port %d\n", port);
1052                return;
1053        }
1054        if (ret)
1055                dev_err(smi->dev, "error updating LED on port %d\n", port);
1056}
1057
1058static int
1059rtl8366rb_port_enable(struct dsa_switch *ds, int port,
1060                      struct phy_device *phy)
1061{
1062        struct realtek_smi *smi = ds->priv;
1063        int ret;
1064
1065        dev_dbg(smi->dev, "enable port %d\n", port);
1066        ret = regmap_update_bits(smi->map, RTL8366RB_PECR, BIT(port),
1067                                 0);
1068        if (ret)
1069                return ret;
1070
1071        rb8366rb_set_port_led(smi, port, true);
1072        return 0;
1073}
1074
1075static void
1076rtl8366rb_port_disable(struct dsa_switch *ds, int port,
1077                       struct phy_device *phy)
1078{
1079        struct realtek_smi *smi = ds->priv;
1080        int ret;
1081
1082        dev_dbg(smi->dev, "disable port %d\n", port);
1083        ret = regmap_update_bits(smi->map, RTL8366RB_PECR, BIT(port),
1084                                 BIT(port));
1085        if (ret)
1086                return;
1087
1088        rb8366rb_set_port_led(smi, port, false);
1089}
1090
1091static int rtl8366rb_get_vlan_4k(struct realtek_smi *smi, u32 vid,
1092                                 struct rtl8366_vlan_4k *vlan4k)
1093{
1094        u32 data[3];
1095        int ret;
1096        int i;
1097
1098        memset(vlan4k, '\0', sizeof(struct rtl8366_vlan_4k));
1099
1100        if (vid >= RTL8366RB_NUM_VIDS)
1101                return -EINVAL;
1102
1103        /* write VID */
1104        ret = regmap_write(smi->map, RTL8366RB_VLAN_TABLE_WRITE_BASE,
1105                           vid & RTL8366RB_VLAN_VID_MASK);
1106        if (ret)
1107                return ret;
1108
1109        /* write table access control word */
1110        ret = regmap_write(smi->map, RTL8366RB_TABLE_ACCESS_CTRL_REG,
1111                           RTL8366RB_TABLE_VLAN_READ_CTRL);
1112        if (ret)
1113                return ret;
1114
1115        for (i = 0; i < 3; i++) {
1116                ret = regmap_read(smi->map,
1117                                  RTL8366RB_VLAN_TABLE_READ_BASE + i,
1118                                  &data[i]);
1119                if (ret)
1120                        return ret;
1121        }
1122
1123        vlan4k->vid = vid;
1124        vlan4k->untag = (data[1] >> RTL8366RB_VLAN_UNTAG_SHIFT) &
1125                        RTL8366RB_VLAN_UNTAG_MASK;
1126        vlan4k->member = data[1] & RTL8366RB_VLAN_MEMBER_MASK;
1127        vlan4k->fid = data[2] & RTL8366RB_VLAN_FID_MASK;
1128
1129        return 0;
1130}
1131
1132static int rtl8366rb_set_vlan_4k(struct realtek_smi *smi,
1133                                 const struct rtl8366_vlan_4k *vlan4k)
1134{
1135        u32 data[3];
1136        int ret;
1137        int i;
1138
1139        if (vlan4k->vid >= RTL8366RB_NUM_VIDS ||
1140            vlan4k->member > RTL8366RB_VLAN_MEMBER_MASK ||
1141            vlan4k->untag > RTL8366RB_VLAN_UNTAG_MASK ||
1142            vlan4k->fid > RTL8366RB_FIDMAX)
1143                return -EINVAL;
1144
1145        data[0] = vlan4k->vid & RTL8366RB_VLAN_VID_MASK;
1146        data[1] = (vlan4k->member & RTL8366RB_VLAN_MEMBER_MASK) |
1147                  ((vlan4k->untag & RTL8366RB_VLAN_UNTAG_MASK) <<
1148                        RTL8366RB_VLAN_UNTAG_SHIFT);
1149        data[2] = vlan4k->fid & RTL8366RB_VLAN_FID_MASK;
1150
1151        for (i = 0; i < 3; i++) {
1152                ret = regmap_write(smi->map,
1153                                   RTL8366RB_VLAN_TABLE_WRITE_BASE + i,
1154                                   data[i]);
1155                if (ret)
1156                        return ret;
1157        }
1158
1159        /* write table access control word */
1160        ret = regmap_write(smi->map, RTL8366RB_TABLE_ACCESS_CTRL_REG,
1161                           RTL8366RB_TABLE_VLAN_WRITE_CTRL);
1162
1163        return ret;
1164}
1165
1166static int rtl8366rb_get_vlan_mc(struct realtek_smi *smi, u32 index,
1167                                 struct rtl8366_vlan_mc *vlanmc)
1168{
1169        u32 data[3];
1170        int ret;
1171        int i;
1172
1173        memset(vlanmc, '\0', sizeof(struct rtl8366_vlan_mc));
1174
1175        if (index >= RTL8366RB_NUM_VLANS)
1176                return -EINVAL;
1177
1178        for (i = 0; i < 3; i++) {
1179                ret = regmap_read(smi->map,
1180                                  RTL8366RB_VLAN_MC_BASE(index) + i,
1181                                  &data[i]);
1182                if (ret)
1183                        return ret;
1184        }
1185
1186        vlanmc->vid = data[0] & RTL8366RB_VLAN_VID_MASK;
1187        vlanmc->priority = (data[0] >> RTL8366RB_VLAN_PRIORITY_SHIFT) &
1188                RTL8366RB_VLAN_PRIORITY_MASK;
1189        vlanmc->untag = (data[1] >> RTL8366RB_VLAN_UNTAG_SHIFT) &
1190                RTL8366RB_VLAN_UNTAG_MASK;
1191        vlanmc->member = data[1] & RTL8366RB_VLAN_MEMBER_MASK;
1192        vlanmc->fid = data[2] & RTL8366RB_VLAN_FID_MASK;
1193
1194        return 0;
1195}
1196
1197static int rtl8366rb_set_vlan_mc(struct realtek_smi *smi, u32 index,
1198                                 const struct rtl8366_vlan_mc *vlanmc)
1199{
1200        u32 data[3];
1201        int ret;
1202        int i;
1203
1204        if (index >= RTL8366RB_NUM_VLANS ||
1205            vlanmc->vid >= RTL8366RB_NUM_VIDS ||
1206            vlanmc->priority > RTL8366RB_PRIORITYMAX ||
1207            vlanmc->member > RTL8366RB_VLAN_MEMBER_MASK ||
1208            vlanmc->untag > RTL8366RB_VLAN_UNTAG_MASK ||
1209            vlanmc->fid > RTL8366RB_FIDMAX)
1210                return -EINVAL;
1211
1212        data[0] = (vlanmc->vid & RTL8366RB_VLAN_VID_MASK) |
1213                  ((vlanmc->priority & RTL8366RB_VLAN_PRIORITY_MASK) <<
1214                        RTL8366RB_VLAN_PRIORITY_SHIFT);
1215        data[1] = (vlanmc->member & RTL8366RB_VLAN_MEMBER_MASK) |
1216                  ((vlanmc->untag & RTL8366RB_VLAN_UNTAG_MASK) <<
1217                        RTL8366RB_VLAN_UNTAG_SHIFT);
1218        data[2] = vlanmc->fid & RTL8366RB_VLAN_FID_MASK;
1219
1220        for (i = 0; i < 3; i++) {
1221                ret = regmap_write(smi->map,
1222                                   RTL8366RB_VLAN_MC_BASE(index) + i,
1223                                   data[i]);
1224                if (ret)
1225                        return ret;
1226        }
1227
1228        return 0;
1229}
1230
1231static int rtl8366rb_get_mc_index(struct realtek_smi *smi, int port, int *val)
1232{
1233        u32 data;
1234        int ret;
1235
1236        if (port >= smi->num_ports)
1237                return -EINVAL;
1238
1239        ret = regmap_read(smi->map, RTL8366RB_PORT_VLAN_CTRL_REG(port),
1240                          &data);
1241        if (ret)
1242                return ret;
1243
1244        *val = (data >> RTL8366RB_PORT_VLAN_CTRL_SHIFT(port)) &
1245                RTL8366RB_PORT_VLAN_CTRL_MASK;
1246
1247        return 0;
1248}
1249
1250static int rtl8366rb_set_mc_index(struct realtek_smi *smi, int port, int index)
1251{
1252        if (port >= smi->num_ports || index >= RTL8366RB_NUM_VLANS)
1253                return -EINVAL;
1254
1255        return regmap_update_bits(smi->map, RTL8366RB_PORT_VLAN_CTRL_REG(port),
1256                                RTL8366RB_PORT_VLAN_CTRL_MASK <<
1257                                        RTL8366RB_PORT_VLAN_CTRL_SHIFT(port),
1258                                (index & RTL8366RB_PORT_VLAN_CTRL_MASK) <<
1259                                        RTL8366RB_PORT_VLAN_CTRL_SHIFT(port));
1260}
1261
1262static bool rtl8366rb_is_vlan_valid(struct realtek_smi *smi, unsigned int vlan)
1263{
1264        unsigned int max = RTL8366RB_NUM_VLANS;
1265
1266        if (smi->vlan4k_enabled)
1267                max = RTL8366RB_NUM_VIDS - 1;
1268
1269        if (vlan == 0 || vlan >= max)
1270                return false;
1271
1272        return true;
1273}
1274
1275static int rtl8366rb_enable_vlan(struct realtek_smi *smi, bool enable)
1276{
1277        dev_dbg(smi->dev, "%s VLAN\n", enable ? "enable" : "disable");
1278        return regmap_update_bits(smi->map,
1279                                  RTL8366RB_SGCR, RTL8366RB_SGCR_EN_VLAN,
1280                                  enable ? RTL8366RB_SGCR_EN_VLAN : 0);
1281}
1282
1283static int rtl8366rb_enable_vlan4k(struct realtek_smi *smi, bool enable)
1284{
1285        dev_dbg(smi->dev, "%s VLAN 4k\n", enable ? "enable" : "disable");
1286        return regmap_update_bits(smi->map, RTL8366RB_SGCR,
1287                                  RTL8366RB_SGCR_EN_VLAN_4KTB,
1288                                  enable ? RTL8366RB_SGCR_EN_VLAN_4KTB : 0);
1289}
1290
1291static int rtl8366rb_phy_read(struct realtek_smi *smi, int phy, int regnum)
1292{
1293        u32 val;
1294        u32 reg;
1295        int ret;
1296
1297        if (phy > RTL8366RB_PHY_NO_MAX)
1298                return -EINVAL;
1299
1300        ret = regmap_write(smi->map, RTL8366RB_PHY_ACCESS_CTRL_REG,
1301                           RTL8366RB_PHY_CTRL_READ);
1302        if (ret)
1303                return ret;
1304
1305        reg = 0x8000 | (1 << (phy + RTL8366RB_PHY_NO_OFFSET)) | regnum;
1306
1307        ret = regmap_write(smi->map, reg, 0);
1308        if (ret) {
1309                dev_err(smi->dev,
1310                        "failed to write PHY%d reg %04x @ %04x, ret %d\n",
1311                        phy, regnum, reg, ret);
1312                return ret;
1313        }
1314
1315        ret = regmap_read(smi->map, RTL8366RB_PHY_ACCESS_DATA_REG, &val);
1316        if (ret)
1317                return ret;
1318
1319        dev_dbg(smi->dev, "read PHY%d register 0x%04x @ %08x, val <- %04x\n",
1320                phy, regnum, reg, val);
1321
1322        return val;
1323}
1324
1325static int rtl8366rb_phy_write(struct realtek_smi *smi, int phy, int regnum,
1326                               u16 val)
1327{
1328        u32 reg;
1329        int ret;
1330
1331        if (phy > RTL8366RB_PHY_NO_MAX)
1332                return -EINVAL;
1333
1334        ret = regmap_write(smi->map, RTL8366RB_PHY_ACCESS_CTRL_REG,
1335                           RTL8366RB_PHY_CTRL_WRITE);
1336        if (ret)
1337                return ret;
1338
1339        reg = 0x8000 | (1 << (phy + RTL8366RB_PHY_NO_OFFSET)) | regnum;
1340
1341        dev_dbg(smi->dev, "write PHY%d register 0x%04x @ %04x, val -> %04x\n",
1342                phy, regnum, reg, val);
1343
1344        ret = regmap_write(smi->map, reg, val);
1345        if (ret)
1346                return ret;
1347
1348        return 0;
1349}
1350
1351static int rtl8366rb_reset_chip(struct realtek_smi *smi)
1352{
1353        int timeout = 10;
1354        u32 val;
1355        int ret;
1356
1357        realtek_smi_write_reg_noack(smi, RTL8366RB_RESET_CTRL_REG,
1358                                    RTL8366RB_CHIP_CTRL_RESET_HW);
1359        do {
1360                usleep_range(20000, 25000);
1361                ret = regmap_read(smi->map, RTL8366RB_RESET_CTRL_REG, &val);
1362                if (ret)
1363                        return ret;
1364
1365                if (!(val & RTL8366RB_CHIP_CTRL_RESET_HW))
1366                        break;
1367        } while (--timeout);
1368
1369        if (!timeout) {
1370                dev_err(smi->dev, "timeout waiting for the switch to reset\n");
1371                return -EIO;
1372        }
1373
1374        return 0;
1375}
1376
1377static int rtl8366rb_detect(struct realtek_smi *smi)
1378{
1379        struct device *dev = smi->dev;
1380        int ret;
1381        u32 val;
1382
1383        /* Detect device */
1384        ret = regmap_read(smi->map, 0x5c, &val);
1385        if (ret) {
1386                dev_err(dev, "can't get chip ID (%d)\n", ret);
1387                return ret;
1388        }
1389
1390        switch (val) {
1391        case 0x6027:
1392                dev_info(dev, "found an RTL8366S switch\n");
1393                dev_err(dev, "this switch is not yet supported, submit patches!\n");
1394                return -ENODEV;
1395        case 0x5937:
1396                dev_info(dev, "found an RTL8366RB switch\n");
1397                smi->cpu_port = RTL8366RB_PORT_NUM_CPU;
1398                smi->num_ports = RTL8366RB_NUM_PORTS;
1399                smi->num_vlan_mc = RTL8366RB_NUM_VLANS;
1400                smi->mib_counters = rtl8366rb_mib_counters;
1401                smi->num_mib_counters = ARRAY_SIZE(rtl8366rb_mib_counters);
1402                break;
1403        default:
1404                dev_info(dev, "found an Unknown Realtek switch (id=0x%04x)\n",
1405                         val);
1406                break;
1407        }
1408
1409        ret = rtl8366rb_reset_chip(smi);
1410        if (ret)
1411                return ret;
1412
1413        return 0;
1414}
1415
1416static const struct dsa_switch_ops rtl8366rb_switch_ops = {
1417        .get_tag_protocol = rtl8366_get_tag_protocol,
1418        .setup = rtl8366rb_setup,
1419        .adjust_link = rtl8366rb_adjust_link,
1420        .get_strings = rtl8366_get_strings,
1421        .get_ethtool_stats = rtl8366_get_ethtool_stats,
1422        .get_sset_count = rtl8366_get_sset_count,
1423        .port_vlan_filtering = rtl8366_vlan_filtering,
1424        .port_vlan_prepare = rtl8366_vlan_prepare,
1425        .port_vlan_add = rtl8366_vlan_add,
1426        .port_vlan_del = rtl8366_vlan_del,
1427        .port_enable = rtl8366rb_port_enable,
1428        .port_disable = rtl8366rb_port_disable,
1429};
1430
1431static const struct realtek_smi_ops rtl8366rb_smi_ops = {
1432        .detect         = rtl8366rb_detect,
1433        .get_vlan_mc    = rtl8366rb_get_vlan_mc,
1434        .set_vlan_mc    = rtl8366rb_set_vlan_mc,
1435        .get_vlan_4k    = rtl8366rb_get_vlan_4k,
1436        .set_vlan_4k    = rtl8366rb_set_vlan_4k,
1437        .get_mc_index   = rtl8366rb_get_mc_index,
1438        .set_mc_index   = rtl8366rb_set_mc_index,
1439        .get_mib_counter = rtl8366rb_get_mib_counter,
1440        .is_vlan_valid  = rtl8366rb_is_vlan_valid,
1441        .enable_vlan    = rtl8366rb_enable_vlan,
1442        .enable_vlan4k  = rtl8366rb_enable_vlan4k,
1443        .phy_read       = rtl8366rb_phy_read,
1444        .phy_write      = rtl8366rb_phy_write,
1445};
1446
1447const struct realtek_smi_variant rtl8366rb_variant = {
1448        .ds_ops = &rtl8366rb_switch_ops,
1449        .ops = &rtl8366rb_smi_ops,
1450        .clk_delay = 10,
1451        .cmd_read = 0xa9,
1452        .cmd_write = 0xa8,
1453};
1454EXPORT_SYMBOL_GPL(rtl8366rb_variant);
1455