linux/drivers/net/dsa/lan9303-core.c

// SPDX-License-Identifier: GPL-2.0-only
/*
 * Copyright (C) 2017 Pengutronix, Juergen Borleis <[email protected]>
 */
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/gpio/consumer.h>
#include <linux/regmap.h>
#include <linux/iopoll.h>
#include <linux/mutex.h>
#include <linux/mii.h>
#include <linux/of.h>
#include <linux/phy.h>
#include <linux/if_bridge.h>
#include <linux/if_vlan.h>
#include <linux/etherdevice.h>

#include "lan9303.h"

/* For the LAN9303 and LAN9354, only port 0 is an XMII port. */
#define IS_PORT_XMII(port)

#define LAN9303_NUM_PORTS

/* 13.2 System Control and Status Registers
 * Multiply register number by 4 to get address offset.
 */
#define LAN9303_CHIP_REV
#define LAN9303_CHIP_ID
#define LAN9352_CHIP_ID
#define LAN9353_CHIP_ID
#define LAN9354_CHIP_ID
#define LAN9355_CHIP_ID
#define LAN9303_IRQ_CFG
#define LAN9303_IRQ_CFG_IRQ_ENABLE
#define LAN9303_IRQ_CFG_IRQ_POL
#define LAN9303_IRQ_CFG_IRQ_TYPE
#define LAN9303_INT_STS
#define LAN9303_INT_STS_PHY_INT2
#define LAN9303_INT_STS_PHY_INT1
#define LAN9303_INT_EN
#define LAN9303_INT_EN_PHY_INT2_EN
#define LAN9303_INT_EN_PHY_INT1_EN
#define LAN9303_BYTE_ORDER
#define LAN9303_HW_CFG
#define LAN9303_HW_CFG_READY
#define LAN9303_HW_CFG_AMDX_EN_PORT2
#define LAN9303_HW_CFG_AMDX_EN_PORT1
#define LAN9303_PMI_DATA
#define LAN9303_PMI_ACCESS
#define LAN9303_PMI_ACCESS_PHY_ADDR(x)
#define LAN9303_PMI_ACCESS_MIIRINDA(x)
#define LAN9303_PMI_ACCESS_MII_BUSY
#define LAN9303_PMI_ACCESS_MII_WRITE
#define LAN9303_MANUAL_FC_1
#define LAN9303_MANUAL_FC_2
#define LAN9303_MANUAL_FC_0
#define LAN9303_BP_EN
#define LAN9303_RX_FC_EN
#define LAN9303_TX_FC_EN
#define LAN9303_SWITCH_CSR_DATA
#define LAN9303_SWITCH_CSR_CMD
#define LAN9303_SWITCH_CSR_CMD_BUSY
#define LAN9303_SWITCH_CSR_CMD_RW
#define LAN9303_SWITCH_CSR_CMD_LANES
#define LAN9303_VIRT_PHY_BASE
#define LAN9303_VIRT_SPECIAL_CTRL
#define LAN9303_VIRT_SPECIAL_TURBO

/*13.4 Switch Fabric Control and Status Registers
 * Accessed indirectly via SWITCH_CSR_CMD, SWITCH_CSR_DATA.
 */
#define LAN9303_SW_DEV_ID
#define LAN9303_SW_RESET
#define LAN9303_SW_RESET_RESET
#define LAN9303_SW_IMR
#define LAN9303_SW_IPR
#define LAN9303_MAC_VER_ID_0
#define LAN9303_MAC_RX_CFG_0
#define LAN9303_MAC_RX_CFG_X_REJECT_MAC_TYPES
#define LAN9303_MAC_RX_CFG_X_RX_ENABLE
#define LAN9303_MAC_RX_UNDSZE_CNT_0
#define LAN9303_MAC_RX_64_CNT_0
#define LAN9303_MAC_RX_127_CNT_0
#define LAN9303_MAC_RX_255_CNT_0
#define LAN9303_MAC_RX_511_CNT_0
#define LAN9303_MAC_RX_1023_CNT_0
#define LAN9303_MAC_RX_MAX_CNT_0
#define LAN9303_MAC_RX_OVRSZE_CNT_0
#define LAN9303_MAC_RX_PKTOK_CNT_0
#define LAN9303_MAC_RX_CRCERR_CNT_0
#define LAN9303_MAC_RX_MULCST_CNT_0
#define LAN9303_MAC_RX_BRDCST_CNT_0
#define LAN9303_MAC_RX_PAUSE_CNT_0
#define LAN9303_MAC_RX_FRAG_CNT_0
#define LAN9303_MAC_RX_JABB_CNT_0
#define LAN9303_MAC_RX_ALIGN_CNT_0
#define LAN9303_MAC_RX_PKTLEN_CNT_0
#define LAN9303_MAC_RX_GOODPKTLEN_CNT_0
#define LAN9303_MAC_RX_SYMBL_CNT_0
#define LAN9303_MAC_RX_CTLFRM_CNT_0

#define LAN9303_MAC_TX_CFG_0
#define LAN9303_MAC_TX_CFG_X_TX_IFG_CONFIG_DEFAULT
#define LAN9303_MAC_TX_CFG_X_TX_PAD_ENABLE
#define LAN9303_MAC_TX_CFG_X_TX_ENABLE
#define LAN9303_MAC_TX_DEFER_CNT_0
#define LAN9303_MAC_TX_PAUSE_CNT_0
#define LAN9303_MAC_TX_PKTOK_CNT_0
#define LAN9303_MAC_TX_64_CNT_0
#define LAN9303_MAC_TX_127_CNT_0
#define LAN9303_MAC_TX_255_CNT_0
#define LAN9303_MAC_TX_511_CNT_0
#define LAN9303_MAC_TX_1023_CNT_0
#define LAN9303_MAC_TX_MAX_CNT_0
#define LAN9303_MAC_TX_UNDSZE_CNT_0
#define LAN9303_MAC_TX_PKTLEN_CNT_0
#define LAN9303_MAC_TX_BRDCST_CNT_0
#define LAN9303_MAC_TX_MULCST_CNT_0
#define LAN9303_MAC_TX_LATECOL_0
#define LAN9303_MAC_TX_EXCOL_CNT_0
#define LAN9303_MAC_TX_SNGLECOL_CNT_0
#define LAN9303_MAC_TX_MULTICOL_CNT_0
#define LAN9303_MAC_TX_TOTALCOL_CNT_0

#define LAN9303_MAC_VER_ID_1
#define LAN9303_MAC_RX_CFG_1
#define LAN9303_MAC_TX_CFG_1
#define LAN9303_MAC_VER_ID_2
#define LAN9303_MAC_RX_CFG_2
#define LAN9303_MAC_TX_CFG_2
#define LAN9303_SWE_ALR_CMD
#define LAN9303_ALR_CMD_MAKE_ENTRY
#define LAN9303_ALR_CMD_GET_FIRST
#define LAN9303_ALR_CMD_GET_NEXT
#define LAN9303_SWE_ALR_WR_DAT_0
#define LAN9303_SWE_ALR_WR_DAT_1
#define LAN9303_ALR_DAT1_VALID
#define LAN9303_ALR_DAT1_END_OF_TABL
#define LAN9303_ALR_DAT1_AGE_OVERRID
#define LAN9303_ALR_DAT1_STATIC
#define LAN9303_ALR_DAT1_PORT_BITOFFS
#define LAN9303_ALR_DAT1_PORT_MASK
#define LAN9303_SWE_ALR_RD_DAT_0
#define LAN9303_SWE_ALR_RD_DAT_1
#define LAN9303_SWE_ALR_CMD_STS
#define ALR_STS_MAKE_PEND
#define LAN9303_SWE_VLAN_CMD
#define LAN9303_SWE_VLAN_CMD_RNW
#define LAN9303_SWE_VLAN_CMD_PVIDNVLAN
#define LAN9303_SWE_VLAN_WR_DATA
#define LAN9303_SWE_VLAN_RD_DATA
#define LAN9303_SWE_VLAN_MEMBER_PORT2
#define LAN9303_SWE_VLAN_UNTAG_PORT2
#define LAN9303_SWE_VLAN_MEMBER_PORT1
#define LAN9303_SWE_VLAN_UNTAG_PORT1
#define LAN9303_SWE_VLAN_MEMBER_PORT0
#define LAN9303_SWE_VLAN_UNTAG_PORT0
#define LAN9303_SWE_VLAN_CMD_STS
#define LAN9303_SWE_GLB_INGRESS_CFG
#define LAN9303_SWE_GLB_INGR_IGMP_TRAP
#define LAN9303_SWE_GLB_INGR_IGMP_PORT(p)
#define LAN9303_SWE_PORT_STATE
#define LAN9303_SWE_PORT_STATE_FORWARDING_PORT2
#define LAN9303_SWE_PORT_STATE_LEARNING_PORT2
#define LAN9303_SWE_PORT_STATE_BLOCKING_PORT2
#define LAN9303_SWE_PORT_STATE_FORWARDING_PORT1
#define LAN9303_SWE_PORT_STATE_LEARNING_PORT1
#define LAN9303_SWE_PORT_STATE_BLOCKING_PORT1
#define LAN9303_SWE_PORT_STATE_FORWARDING_PORT0
#define LAN9303_SWE_PORT_STATE_LEARNING_PORT0
#define LAN9303_SWE_PORT_STATE_BLOCKING_PORT0
#define LAN9303_SWE_PORT_STATE_DISABLED_PORT0
#define LAN9303_SWE_PORT_MIRROR
#define LAN9303_SWE_PORT_MIRROR_SNIFF_ALL
#define LAN9303_SWE_PORT_MIRROR_SNIFFER_PORT2
#define LAN9303_SWE_PORT_MIRROR_SNIFFER_PORT1
#define LAN9303_SWE_PORT_MIRROR_SNIFFER_PORT0
#define LAN9303_SWE_PORT_MIRROR_MIRRORED_PORT2
#define LAN9303_SWE_PORT_MIRROR_MIRRORED_PORT1
#define LAN9303_SWE_PORT_MIRROR_MIRRORED_PORT0
#define LAN9303_SWE_PORT_MIRROR_ENABLE_RX_MIRRORING
#define LAN9303_SWE_PORT_MIRROR_ENABLE_TX_MIRRORING
#define LAN9303_SWE_PORT_MIRROR_DISABLED
#define LAN9303_SWE_INGRESS_PORT_TYPE
#define LAN9303_SWE_INGRESS_PORT_TYPE_VLAN
#define LAN9303_BM_CFG
#define LAN9303_BM_EGRSS_PORT_TYPE
#define LAN9303_BM_EGRSS_PORT_TYPE_SPECIAL_TAG_PORT2
#define LAN9303_BM_EGRSS_PORT_TYPE_SPECIAL_TAG_PORT1
#define LAN9303_BM_EGRSS_PORT_TYPE_SPECIAL_TAG_PORT0

#define LAN9303_SWITCH_PORT_REG(port, reg0)

/* the built-in PHYs are of type LAN911X */
#define MII_LAN911X_SPECIAL_MODES
#define MII_LAN911X_SPECIAL_CONTROL_STATUS

static const struct regmap_range lan9303_valid_regs[] =;

static const struct regmap_range lan9303_reserved_ranges[] =;

const struct regmap_access_table lan9303_register_set =;
EXPORT_SYMBOL();

/* Flow Control registers indexed by port number */
static unsigned int flow_ctl_reg[] =;

static int lan9303_read(struct regmap *regmap, unsigned int offset, u32 *reg)
{}

static int lan9303_read_wait(struct lan9303 *chip, int offset, u32 mask)
{}

static int lan9303_virt_phy_reg_read(struct lan9303 *chip, int regnum)
{}

static int lan9303_virt_phy_reg_write(struct lan9303 *chip, int regnum, u16 val)
{}

static int lan9303_indirect_phy_wait_for_completion(struct lan9303 *chip)
{}

static int lan9303_indirect_phy_read(struct lan9303 *chip, int addr, int regnum)
{}

static int lan9303_indirect_phy_write(struct lan9303 *chip, int addr,
				      int regnum, u16 val)
{}

const struct lan9303_phy_ops lan9303_indirect_phy_ops =;
EXPORT_SYMBOL_GPL();

static int lan9303_switch_wait_for_completion(struct lan9303 *chip)
{}

static int lan9303_write_switch_reg(struct lan9303 *chip, u16 regnum, u32 val)
{}

static int lan9303_read_switch_reg(struct lan9303 *chip, u16 regnum, u32 *val)
{}

static int lan9303_write_switch_reg_mask(struct lan9303 *chip, u16 regnum,
					 u32 val, u32 mask)
{}

static int lan9303_write_switch_port(struct lan9303 *chip, int port,
				     u16 regnum, u32 val)
{}

static int lan9303_read_switch_port(struct lan9303 *chip, int port,
				    u16 regnum, u32 *val)
{}

static int lan9303_detect_phy_setup(struct lan9303 *chip)
{}

/* Map ALR-port bits to port bitmap, and back */
static const int alrport_2_portmap[] =;
static const int portmap_2_alrport[] =;

/* Return pointer to first free ALR cache entry, return NULL if none */
static struct lan9303_alr_cache_entry *
lan9303_alr_cache_find_free(struct lan9303 *chip)
{}

/* Return pointer to ALR cache entry matching MAC address */
static struct lan9303_alr_cache_entry *
lan9303_alr_cache_find_mac(struct lan9303 *chip, const u8 *mac_addr)
{}

static int lan9303_csr_reg_wait(struct lan9303 *chip, int regno, u32 mask)
{}

static int lan9303_alr_make_entry_raw(struct lan9303 *chip, u32 dat0, u32 dat1)
{}

alr_loop_cb_t;

static int lan9303_alr_loop(struct lan9303 *chip, alr_loop_cb_t *cb, void *ctx)
{}

static void alr_reg_to_mac(u32 dat0, u32 dat1, u8 mac[6])
{}

struct del_port_learned_ctx {};

/* Clear learned (non-static) entry on given port */
static int alr_loop_cb_del_port_learned(struct lan9303 *chip, u32 dat0,
					u32 dat1, int portmap, void *ctx)
{}

struct port_fdb_dump_ctx {};

static int alr_loop_cb_fdb_port_dump(struct lan9303 *chip, u32 dat0,
				     u32 dat1, int portmap, void *ctx)
{}

/* Set a static ALR entry. Delete entry if port_map is zero */
static void lan9303_alr_set_entry(struct lan9303 *chip, const u8 *mac,
				  u8 port_map, bool stp_override)
{}

/* Add port to static ALR entry, create new static entry if needed */
static int lan9303_alr_add_port(struct lan9303 *chip, const u8 *mac, int port,
				bool stp_override)
{}

/* Delete static port from ALR entry, delete entry if last port */
static int lan9303_alr_del_port(struct lan9303 *chip, const u8 *mac, int port)
{}

static int lan9303_disable_processing_port(struct lan9303 *chip,
					   unsigned int port)
{}

static int lan9303_enable_processing_port(struct lan9303 *chip,
					  unsigned int port)
{}

/* forward special tagged packets from port 0 to port 1 *or* port 2 */
static int lan9303_setup_tagging(struct lan9303 *chip)
{}

/* We want a special working switch:
 * - do not forward packets between port 1 and 2
 * - forward everything from port 1 to port 0
 * - forward everything from port 2 to port 0
 */
static int lan9303_separate_ports(struct lan9303 *chip)
{}

static void lan9303_bridge_ports(struct lan9303 *chip)
{}

static void lan9303_handle_reset(struct lan9303 *chip)
{}

/* stop processing packets for all ports */
static int lan9303_disable_processing(struct lan9303 *chip)
{}

static int lan9303_check_device(struct lan9303 *chip)
{}

/* ---------------------------- DSA -----------------------------------*/

static enum dsa_tag_protocol lan9303_get_tag_protocol(struct dsa_switch *ds,
						      int port,
						      enum dsa_tag_protocol mp)
{}

static int lan9303_setup(struct dsa_switch *ds)
{}

struct lan9303_mib_desc {};

static const struct lan9303_mib_desc lan9303_mib[] =;

static void lan9303_get_strings(struct dsa_switch *ds, int port,
				u32 stringset, uint8_t *data)
{}

static void lan9303_get_ethtool_stats(struct dsa_switch *ds, int port,
				      uint64_t *data)
{}

static int lan9303_get_sset_count(struct dsa_switch *ds, int port, int sset)
{}

static int lan9303_phy_read(struct dsa_switch *ds, int port, int regnum)
{}

static int lan9303_phy_write(struct dsa_switch *ds, int port, int regnum,
			     u16 val)
{}

static int lan9303_port_enable(struct dsa_switch *ds, int port,
			       struct phy_device *phy)
{}

static void lan9303_port_disable(struct dsa_switch *ds, int port)
{}

static int lan9303_port_bridge_join(struct dsa_switch *ds, int port,
				    struct dsa_bridge bridge,
				    bool *tx_fwd_offload,
				    struct netlink_ext_ack *extack)
{}

static void lan9303_port_bridge_leave(struct dsa_switch *ds, int port,
				      struct dsa_bridge bridge)
{}

static void lan9303_port_stp_state_set(struct dsa_switch *ds, int port,
				       u8 state)
{}

static void lan9303_port_fast_age(struct dsa_switch *ds, int port)
{}

static int lan9303_port_fdb_add(struct dsa_switch *ds, int port,
				const unsigned char *addr, u16 vid,
				struct dsa_db db)
{}

static int lan9303_port_fdb_del(struct dsa_switch *ds, int port,
				const unsigned char *addr, u16 vid,
				struct dsa_db db)
{}

static int lan9303_port_fdb_dump(struct dsa_switch *ds, int port,
				 dsa_fdb_dump_cb_t *cb, void *data)
{}

static int lan9303_port_mdb_prepare(struct dsa_switch *ds, int port,
				    const struct switchdev_obj_port_mdb *mdb)
{}

static int lan9303_port_mdb_add(struct dsa_switch *ds, int port,
				const struct switchdev_obj_port_mdb *mdb,
				struct dsa_db db)
{}

static int lan9303_port_mdb_del(struct dsa_switch *ds, int port,
				const struct switchdev_obj_port_mdb *mdb,
				struct dsa_db db)
{}

static void lan9303_phylink_get_caps(struct dsa_switch *ds, int port,
				     struct phylink_config *config)
{}

static void lan9303_phylink_mac_config(struct phylink_config *config,
				       unsigned int mode,
				       const struct phylink_link_state *state)
{}

static void lan9303_phylink_mac_link_down(struct phylink_config *config,
					  unsigned int mode,
					  phy_interface_t interface)
{}

static void lan9303_phylink_mac_link_up(struct phylink_config *config,
					struct phy_device *phydev,
					unsigned int mode,
					phy_interface_t interface,
					int speed, int duplex, bool tx_pause,
					bool rx_pause)
{}

static const struct phylink_mac_ops lan9303_phylink_mac_ops =;

static const struct dsa_switch_ops lan9303_switch_ops =;

static int lan9303_register_switch(struct lan9303 *chip)
{}

static int lan9303_probe_reset_gpio(struct lan9303 *chip,
				     struct device_node *np)
{}

int lan9303_probe(struct lan9303 *chip, struct device_node *np)
{}
EXPORT_SYMBOL();

int lan9303_remove(struct lan9303 *chip)
{}
EXPORT_SYMBOL();

void lan9303_shutdown(struct lan9303 *chip)
{}
EXPORT_SYMBOL();

MODULE_AUTHOR();
MODULE_DESCRIPTION();
MODULE_LICENSE();