root/drivers/net/dsa/realtek/rtl8366rb.h
/* SPDX-License-Identifier: GPL-2.0+ */

#ifndef _RTL8366RB_H
#define _RTL8366RB_H

#include "realtek.h"

#define RTL8366RB_PORT_NUM_CPU          5
#define RTL8366RB_NUM_PORTS             6
#define RTL8366RB_PHY_NO_MAX            4
#define RTL8366RB_NUM_LEDGROUPS         4
#define RTL8366RB_PHY_ADDR_MAX          31

/* LED control registers */
/* The LED blink rate is global; it is used by all triggers in all groups. */
#define RTL8366RB_LED_BLINKRATE_REG             0x0430
#define RTL8366RB_LED_BLINKRATE_MASK            0x0007
#define RTL8366RB_LED_BLINKRATE_28MS            0x0000
#define RTL8366RB_LED_BLINKRATE_56MS            0x0001
#define RTL8366RB_LED_BLINKRATE_84MS            0x0002
#define RTL8366RB_LED_BLINKRATE_111MS           0x0003
#define RTL8366RB_LED_BLINKRATE_222MS           0x0004
#define RTL8366RB_LED_BLINKRATE_446MS           0x0005

/* LED trigger event for each group */
#define RTL8366RB_LED_CTRL_REG                  0x0431
#define RTL8366RB_LED_CTRL_OFFSET(led_group)    \
        (4 * (led_group))
#define RTL8366RB_LED_CTRL_MASK(led_group)      \
        (0xf << RTL8366RB_LED_CTRL_OFFSET(led_group))

/* The RTL8366RB_LED_X_X registers are used to manually set the LED state only
 * when the corresponding LED group in RTL8366RB_LED_CTRL_REG is
 * RTL8366RB_LEDGROUP_FORCE. Otherwise, it is ignored.
 */
#define RTL8366RB_LED_0_1_CTRL_REG              0x0432
#define RTL8366RB_LED_2_3_CTRL_REG              0x0433
#define RTL8366RB_LED_X_X_CTRL_REG(led_group)   \
        ((led_group) <= 1 ? \
                RTL8366RB_LED_0_1_CTRL_REG : \
                RTL8366RB_LED_2_3_CTRL_REG)
#define RTL8366RB_LED_0_X_CTRL_MASK             GENMASK(5, 0)
#define RTL8366RB_LED_X_1_CTRL_MASK             GENMASK(11, 6)
#define RTL8366RB_LED_2_X_CTRL_MASK             GENMASK(5, 0)
#define RTL8366RB_LED_X_3_CTRL_MASK             GENMASK(11, 6)

enum rtl8366_ledgroup_mode {
        RTL8366RB_LEDGROUP_OFF                  = 0x0,
        RTL8366RB_LEDGROUP_DUP_COL              = 0x1,
        RTL8366RB_LEDGROUP_LINK_ACT             = 0x2,
        RTL8366RB_LEDGROUP_SPD1000              = 0x3,
        RTL8366RB_LEDGROUP_SPD100               = 0x4,
        RTL8366RB_LEDGROUP_SPD10                = 0x5,
        RTL8366RB_LEDGROUP_SPD1000_ACT          = 0x6,
        RTL8366RB_LEDGROUP_SPD100_ACT           = 0x7,
        RTL8366RB_LEDGROUP_SPD10_ACT            = 0x8,
        RTL8366RB_LEDGROUP_SPD100_10_ACT        = 0x9,
        RTL8366RB_LEDGROUP_FIBER                = 0xa,
        RTL8366RB_LEDGROUP_AN_FAULT             = 0xb,
        RTL8366RB_LEDGROUP_LINK_RX              = 0xc,
        RTL8366RB_LEDGROUP_LINK_TX              = 0xd,
        RTL8366RB_LEDGROUP_MASTER               = 0xe,
        RTL8366RB_LEDGROUP_FORCE                = 0xf,

        __RTL8366RB_LEDGROUP_MODE_MAX
};

#if IS_ENABLED(CONFIG_NET_DSA_REALTEK_RTL8366RB_LEDS)

struct rtl8366rb_led {
        u8 port_num;
        u8 led_group;
        struct realtek_priv *priv;
        struct led_classdev cdev;
};

int rtl8366rb_setup_leds(struct realtek_priv *priv);

#else

static inline int rtl8366rb_setup_leds(struct realtek_priv *priv)
{
        return 0;
}

#endif /* IS_ENABLED(CONFIG_LEDS_CLASS) */

/**
 * struct rtl8366rb - RTL8366RB-specific data
 * @max_mtu: per-port max MTU setting
 * @pvid_enabled: if PVID is set for respective port
 * @leds: per-port and per-ledgroup led info
 */
struct rtl8366rb {
        unsigned int max_mtu[RTL8366RB_NUM_PORTS];
        bool pvid_enabled[RTL8366RB_NUM_PORTS];
#if IS_ENABLED(CONFIG_NET_DSA_REALTEK_RTL8366RB_LEDS)
        struct rtl8366rb_led leds[RTL8366RB_NUM_PORTS][RTL8366RB_NUM_LEDGROUPS];
#endif
};

/* This code is used also with LEDs disabled */
int rb8366rb_set_ledgroup_mode(struct realtek_priv *priv,
                               u8 led_group,
                               enum rtl8366_ledgroup_mode mode);

#endif /* _RTL8366RB_H */