2018-05-14 22:04:57 +02:00
/* SPDX-License-Identifier: (GPL-2.0 OR MIT) */
/*
* Microsemi Ocelot Switch driver
*
* Copyright ( c ) 2017 Microsemi Corporation
*/
# ifndef _MSCC_OCELOT_H_
# define _MSCC_OCELOT_H_
# include <linux/bitops.h>
# include <linux/etherdevice.h>
# include <linux/if_vlan.h>
2018-10-04 14:22:08 +02:00
# include <linux/phy.h>
# include <linux/phy/phy.h>
2018-05-14 22:04:57 +02:00
# include <linux/platform_device.h>
# include <linux/regmap.h>
# include "ocelot_ana.h"
# include "ocelot_dev.h"
# include "ocelot_qsys.h"
# include "ocelot_rew.h"
# include "ocelot_sys.h"
# include "ocelot_qs.h"
# define PGID_AGGR 64
# define PGID_SRC 80
/* Reserved PGIDs */
# define PGID_CPU (PGID_AGGR - 5)
# define PGID_UC (PGID_AGGR - 4)
# define PGID_MC (PGID_AGGR - 3)
# define PGID_MCIPV4 (PGID_AGGR - 2)
# define PGID_MCIPV6 (PGID_AGGR - 1)
# define OCELOT_BUFFER_CELL_SZ 60
# define OCELOT_STATS_CHECK_DELAY (2 * HZ)
# define IFH_LEN 4
struct frame_info {
u32 len ;
u16 port ;
u16 vid ;
u8 cpuq ;
u8 tag_type ;
} ;
# define IFH_INJ_BYPASS BIT(31)
# define IFH_INJ_POP_CNT_DISABLE (3 << 28)
# define IFH_TAG_TYPE_C 0
# define IFH_TAG_TYPE_S 1
# define OCELOT_SPEED_2500 0
# define OCELOT_SPEED_1000 1
# define OCELOT_SPEED_100 2
# define OCELOT_SPEED_10 3
# define TARGET_OFFSET 24
# define REG_MASK GENMASK(TARGET_OFFSET - 1, 0)
# define REG(reg, offset) [reg & REG_MASK] = offset
enum ocelot_target {
ANA = 1 ,
QS ,
QSYS ,
REW ,
SYS ,
HSIO ,
TARGET_MAX ,
} ;
enum ocelot_reg {
ANA_ADVLEARN = ANA < < TARGET_OFFSET ,
ANA_VLANMASK ,
ANA_PORT_B_DOMAIN ,
ANA_ANAGEFIL ,
ANA_ANEVENTS ,
ANA_STORMLIMIT_BURST ,
ANA_STORMLIMIT_CFG ,
ANA_ISOLATED_PORTS ,
ANA_COMMUNITY_PORTS ,
ANA_AUTOAGE ,
ANA_MACTOPTIONS ,
ANA_LEARNDISC ,
ANA_AGENCTRL ,
ANA_MIRRORPORTS ,
ANA_EMIRRORPORTS ,
ANA_FLOODING ,
ANA_FLOODING_IPMC ,
ANA_SFLOW_CFG ,
ANA_PORT_MODE ,
ANA_CUT_THRU_CFG ,
ANA_PGID_PGID ,
ANA_TABLES_ANMOVED ,
ANA_TABLES_MACHDATA ,
ANA_TABLES_MACLDATA ,
ANA_TABLES_STREAMDATA ,
ANA_TABLES_MACACCESS ,
ANA_TABLES_MACTINDX ,
ANA_TABLES_VLANACCESS ,
ANA_TABLES_VLANTIDX ,
ANA_TABLES_ISDXACCESS ,
ANA_TABLES_ISDXTIDX ,
ANA_TABLES_ENTRYLIM ,
ANA_TABLES_PTP_ID_HIGH ,
ANA_TABLES_PTP_ID_LOW ,
ANA_TABLES_STREAMACCESS ,
ANA_TABLES_STREAMTIDX ,
ANA_TABLES_SEQ_HISTORY ,
ANA_TABLES_SEQ_MASK ,
ANA_TABLES_SFID_MASK ,
ANA_TABLES_SFIDACCESS ,
ANA_TABLES_SFIDTIDX ,
ANA_MSTI_STATE ,
ANA_OAM_UPM_LM_CNT ,
ANA_SG_ACCESS_CTRL ,
ANA_SG_CONFIG_REG_1 ,
ANA_SG_CONFIG_REG_2 ,
ANA_SG_CONFIG_REG_3 ,
ANA_SG_CONFIG_REG_4 ,
ANA_SG_CONFIG_REG_5 ,
ANA_SG_GCL_GS_CONFIG ,
ANA_SG_GCL_TI_CONFIG ,
ANA_SG_STATUS_REG_1 ,
ANA_SG_STATUS_REG_2 ,
ANA_SG_STATUS_REG_3 ,
ANA_PORT_VLAN_CFG ,
ANA_PORT_DROP_CFG ,
ANA_PORT_QOS_CFG ,
ANA_PORT_VCAP_CFG ,
ANA_PORT_VCAP_S1_KEY_CFG ,
ANA_PORT_VCAP_S2_CFG ,
ANA_PORT_PCP_DEI_MAP ,
ANA_PORT_CPU_FWD_CFG ,
ANA_PORT_CPU_FWD_BPDU_CFG ,
ANA_PORT_CPU_FWD_GARP_CFG ,
ANA_PORT_CPU_FWD_CCM_CFG ,
ANA_PORT_PORT_CFG ,
ANA_PORT_POL_CFG ,
ANA_PORT_PTP_CFG ,
ANA_PORT_PTP_DLY1_CFG ,
ANA_PORT_PTP_DLY2_CFG ,
ANA_PORT_SFID_CFG ,
ANA_PFC_PFC_CFG ,
ANA_PFC_PFC_TIMER ,
ANA_IPT_OAM_MEP_CFG ,
ANA_IPT_IPT ,
ANA_PPT_PPT ,
ANA_FID_MAP_FID_MAP ,
ANA_AGGR_CFG ,
ANA_CPUQ_CFG ,
ANA_CPUQ_CFG2 ,
ANA_CPUQ_8021_CFG ,
ANA_DSCP_CFG ,
ANA_DSCP_REWR_CFG ,
ANA_VCAP_RNG_TYPE_CFG ,
ANA_VCAP_RNG_VAL_CFG ,
ANA_VRAP_CFG ,
ANA_VRAP_HDR_DATA ,
ANA_VRAP_HDR_MASK ,
ANA_DISCARD_CFG ,
ANA_FID_CFG ,
ANA_POL_PIR_CFG ,
ANA_POL_CIR_CFG ,
ANA_POL_MODE_CFG ,
ANA_POL_PIR_STATE ,
ANA_POL_CIR_STATE ,
ANA_POL_STATE ,
ANA_POL_FLOWC ,
ANA_POL_HYST ,
ANA_POL_MISC_CFG ,
QS_XTR_GRP_CFG = QS < < TARGET_OFFSET ,
QS_XTR_RD ,
QS_XTR_FRM_PRUNING ,
QS_XTR_FLUSH ,
QS_XTR_DATA_PRESENT ,
QS_XTR_CFG ,
QS_INJ_GRP_CFG ,
QS_INJ_WR ,
QS_INJ_CTRL ,
QS_INJ_STATUS ,
QS_INJ_ERR ,
QS_INH_DBG ,
QSYS_PORT_MODE = QSYS < < TARGET_OFFSET ,
QSYS_SWITCH_PORT_MODE ,
QSYS_STAT_CNT_CFG ,
QSYS_EEE_CFG ,
QSYS_EEE_THRES ,
QSYS_IGR_NO_SHARING ,
QSYS_EGR_NO_SHARING ,
QSYS_SW_STATUS ,
QSYS_EXT_CPU_CFG ,
QSYS_PAD_CFG ,
QSYS_CPU_GROUP_MAP ,
QSYS_QMAP ,
QSYS_ISDX_SGRP ,
QSYS_TIMED_FRAME_ENTRY ,
QSYS_TFRM_MISC ,
QSYS_TFRM_PORT_DLY ,
QSYS_TFRM_TIMER_CFG_1 ,
QSYS_TFRM_TIMER_CFG_2 ,
QSYS_TFRM_TIMER_CFG_3 ,
QSYS_TFRM_TIMER_CFG_4 ,
QSYS_TFRM_TIMER_CFG_5 ,
QSYS_TFRM_TIMER_CFG_6 ,
QSYS_TFRM_TIMER_CFG_7 ,
QSYS_TFRM_TIMER_CFG_8 ,
QSYS_RED_PROFILE ,
QSYS_RES_QOS_MODE ,
QSYS_RES_CFG ,
QSYS_RES_STAT ,
QSYS_EGR_DROP_MODE ,
QSYS_EQ_CTRL ,
QSYS_EVENTS_CORE ,
QSYS_QMAXSDU_CFG_0 ,
QSYS_QMAXSDU_CFG_1 ,
QSYS_QMAXSDU_CFG_2 ,
QSYS_QMAXSDU_CFG_3 ,
QSYS_QMAXSDU_CFG_4 ,
QSYS_QMAXSDU_CFG_5 ,
QSYS_QMAXSDU_CFG_6 ,
QSYS_QMAXSDU_CFG_7 ,
QSYS_PREEMPTION_CFG ,
QSYS_CIR_CFG ,
QSYS_EIR_CFG ,
QSYS_SE_CFG ,
QSYS_SE_DWRR_CFG ,
QSYS_SE_CONNECT ,
QSYS_SE_DLB_SENSE ,
QSYS_CIR_STATE ,
QSYS_EIR_STATE ,
QSYS_SE_STATE ,
QSYS_HSCH_MISC_CFG ,
QSYS_TAG_CONFIG ,
QSYS_TAS_PARAM_CFG_CTRL ,
QSYS_PORT_MAX_SDU ,
QSYS_PARAM_CFG_REG_1 ,
QSYS_PARAM_CFG_REG_2 ,
QSYS_PARAM_CFG_REG_3 ,
QSYS_PARAM_CFG_REG_4 ,
QSYS_PARAM_CFG_REG_5 ,
QSYS_GCL_CFG_REG_1 ,
QSYS_GCL_CFG_REG_2 ,
QSYS_PARAM_STATUS_REG_1 ,
QSYS_PARAM_STATUS_REG_2 ,
QSYS_PARAM_STATUS_REG_3 ,
QSYS_PARAM_STATUS_REG_4 ,
QSYS_PARAM_STATUS_REG_5 ,
QSYS_PARAM_STATUS_REG_6 ,
QSYS_PARAM_STATUS_REG_7 ,
QSYS_PARAM_STATUS_REG_8 ,
QSYS_PARAM_STATUS_REG_9 ,
QSYS_GCL_STATUS_REG_1 ,
QSYS_GCL_STATUS_REG_2 ,
REW_PORT_VLAN_CFG = REW < < TARGET_OFFSET ,
REW_TAG_CFG ,
REW_PORT_CFG ,
REW_DSCP_CFG ,
REW_PCP_DEI_QOS_MAP_CFG ,
REW_PTP_CFG ,
REW_PTP_DLY1_CFG ,
REW_RED_TAG_CFG ,
REW_DSCP_REMAP_DP1_CFG ,
REW_DSCP_REMAP_CFG ,
REW_STAT_CFG ,
REW_REW_STICKY ,
REW_PPT ,
SYS_COUNT_RX_OCTETS = SYS < < TARGET_OFFSET ,
SYS_COUNT_RX_UNICAST ,
SYS_COUNT_RX_MULTICAST ,
SYS_COUNT_RX_BROADCAST ,
SYS_COUNT_RX_SHORTS ,
SYS_COUNT_RX_FRAGMENTS ,
SYS_COUNT_RX_JABBERS ,
SYS_COUNT_RX_CRC_ALIGN_ERRS ,
SYS_COUNT_RX_SYM_ERRS ,
SYS_COUNT_RX_64 ,
SYS_COUNT_RX_65_127 ,
SYS_COUNT_RX_128_255 ,
SYS_COUNT_RX_256_1023 ,
SYS_COUNT_RX_1024_1526 ,
SYS_COUNT_RX_1527_MAX ,
SYS_COUNT_RX_PAUSE ,
SYS_COUNT_RX_CONTROL ,
SYS_COUNT_RX_LONGS ,
SYS_COUNT_RX_CLASSIFIED_DROPS ,
SYS_COUNT_TX_OCTETS ,
SYS_COUNT_TX_UNICAST ,
SYS_COUNT_TX_MULTICAST ,
SYS_COUNT_TX_BROADCAST ,
SYS_COUNT_TX_COLLISION ,
SYS_COUNT_TX_DROPS ,
SYS_COUNT_TX_PAUSE ,
SYS_COUNT_TX_64 ,
SYS_COUNT_TX_65_127 ,
SYS_COUNT_TX_128_511 ,
SYS_COUNT_TX_512_1023 ,
SYS_COUNT_TX_1024_1526 ,
SYS_COUNT_TX_1527_MAX ,
SYS_COUNT_TX_AGING ,
SYS_RESET_CFG ,
SYS_SR_ETYPE_CFG ,
SYS_VLAN_ETYPE_CFG ,
SYS_PORT_MODE ,
SYS_FRONT_PORT_MODE ,
SYS_FRM_AGING ,
SYS_STAT_CFG ,
SYS_SW_STATUS ,
SYS_MISC_CFG ,
SYS_REW_MAC_HIGH_CFG ,
SYS_REW_MAC_LOW_CFG ,
SYS_TIMESTAMP_OFFSET ,
SYS_CMID ,
SYS_PAUSE_CFG ,
SYS_PAUSE_TOT_CFG ,
SYS_ATOP ,
SYS_ATOP_TOT_CFG ,
SYS_MAC_FC_CFG ,
SYS_MMGT ,
SYS_MMGT_FAST ,
SYS_EVENTS_DIF ,
SYS_EVENTS_CORE ,
SYS_CNT ,
SYS_PTP_STATUS ,
SYS_PTP_TXSTAMP ,
SYS_PTP_NXT ,
SYS_PTP_CFG ,
SYS_RAM_INIT ,
SYS_CM_ADDR ,
SYS_CM_DATA_WR ,
SYS_CM_DATA_RD ,
SYS_CM_OP ,
SYS_CM_DATA ,
} ;
enum ocelot_regfield {
ANA_ADVLEARN_VLAN_CHK ,
ANA_ADVLEARN_LEARN_MIRROR ,
ANA_ANEVENTS_FLOOD_DISCARD ,
ANA_ANEVENTS_MSTI_DROP ,
ANA_ANEVENTS_ACLKILL ,
ANA_ANEVENTS_ACLUSED ,
ANA_ANEVENTS_AUTOAGE ,
ANA_ANEVENTS_VS2TTL1 ,
ANA_ANEVENTS_STORM_DROP ,
ANA_ANEVENTS_LEARN_DROP ,
ANA_ANEVENTS_AGED_ENTRY ,
ANA_ANEVENTS_CPU_LEARN_FAILED ,
ANA_ANEVENTS_AUTO_LEARN_FAILED ,
ANA_ANEVENTS_LEARN_REMOVE ,
ANA_ANEVENTS_AUTO_LEARNED ,
ANA_ANEVENTS_AUTO_MOVED ,
ANA_ANEVENTS_DROPPED ,
ANA_ANEVENTS_CLASSIFIED_DROP ,
ANA_ANEVENTS_CLASSIFIED_COPY ,
ANA_ANEVENTS_VLAN_DISCARD ,
ANA_ANEVENTS_FWD_DISCARD ,
ANA_ANEVENTS_MULTICAST_FLOOD ,
ANA_ANEVENTS_UNICAST_FLOOD ,
ANA_ANEVENTS_DEST_KNOWN ,
ANA_ANEVENTS_BUCKET3_MATCH ,
ANA_ANEVENTS_BUCKET2_MATCH ,
ANA_ANEVENTS_BUCKET1_MATCH ,
ANA_ANEVENTS_BUCKET0_MATCH ,
ANA_ANEVENTS_CPU_OPERATION ,
ANA_ANEVENTS_DMAC_LOOKUP ,
ANA_ANEVENTS_SMAC_LOOKUP ,
ANA_ANEVENTS_SEQ_GEN_ERR_0 ,
ANA_ANEVENTS_SEQ_GEN_ERR_1 ,
ANA_TABLES_MACACCESS_B_DOM ,
ANA_TABLES_MACTINDX_BUCKET ,
ANA_TABLES_MACTINDX_M_INDEX ,
QSYS_TIMED_FRAME_ENTRY_TFRM_VLD ,
QSYS_TIMED_FRAME_ENTRY_TFRM_FP ,
QSYS_TIMED_FRAME_ENTRY_TFRM_PORTNO ,
QSYS_TIMED_FRAME_ENTRY_TFRM_TM_SEL ,
QSYS_TIMED_FRAME_ENTRY_TFRM_TM_T ,
SYS_RESET_CFG_CORE_ENA ,
SYS_RESET_CFG_MEM_ENA ,
SYS_RESET_CFG_MEM_INIT ,
REGFIELD_MAX
} ;
struct ocelot_multicast {
struct list_head list ;
unsigned char addr [ ETH_ALEN ] ;
u16 vid ;
u16 ports ;
} ;
struct ocelot_port ;
struct ocelot_stat_layout {
u32 offset ;
char name [ ETH_GSTRING_LEN ] ;
} ;
struct ocelot {
struct device * dev ;
struct regmap * targets [ TARGET_MAX ] ;
struct regmap_field * regfields [ REGFIELD_MAX ] ;
const u32 * const * map ;
const struct ocelot_stat_layout * stats_layout ;
unsigned int num_stats ;
u8 base_mac [ ETH_ALEN ] ;
struct net_device * hw_bridge_dev ;
u16 bridge_mask ;
u16 bridge_fwd_mask ;
struct workqueue_struct * ocelot_owq ;
int shared_queue_sz ;
u8 num_phys_ports ;
u8 num_cpu_ports ;
struct ocelot_port * * ports ;
2018-06-26 14:28:48 +02:00
u32 * lags ;
2018-05-14 22:04:57 +02:00
/* Keep track of the vlan port masks */
u32 vlan_mask [ VLAN_N_VID ] ;
struct list_head multicast ;
/* Workqueue to check statistics for overflow with its lock */
struct mutex stats_lock ;
u64 * stats ;
struct delayed_work stats_work ;
struct workqueue_struct * stats_queue ;
} ;
struct ocelot_port {
struct net_device * dev ;
struct ocelot * ocelot ;
struct phy_device * phy ;
void __iomem * regs ;
u8 chip_port ;
/* Ingress default VLAN (pvid) */
u16 pvid ;
/* Egress default VLAN (vid) */
u16 vid ;
u8 vlan_aware ;
u64 * stats ;
2018-10-04 14:22:08 +02:00
phy_interface_t phy_mode ;
struct phy * serdes ;
2018-05-14 22:04:57 +02:00
} ;
u32 __ocelot_read_ix ( struct ocelot * ocelot , u32 reg , u32 offset ) ;
# define ocelot_read_ix(ocelot, reg, gi, ri) __ocelot_read_ix(ocelot, reg, reg##_GSZ * (gi) + reg##_RSZ * (ri))
# define ocelot_read_gix(ocelot, reg, gi) __ocelot_read_ix(ocelot, reg, reg##_GSZ * (gi))
# define ocelot_read_rix(ocelot, reg, ri) __ocelot_read_ix(ocelot, reg, reg##_RSZ * (ri))
# define ocelot_read(ocelot, reg) __ocelot_read_ix(ocelot, reg, 0)
void __ocelot_write_ix ( struct ocelot * ocelot , u32 val , u32 reg , u32 offset ) ;
# define ocelot_write_ix(ocelot, val, reg, gi, ri) __ocelot_write_ix(ocelot, val, reg, reg##_GSZ * (gi) + reg##_RSZ * (ri))
# define ocelot_write_gix(ocelot, val, reg, gi) __ocelot_write_ix(ocelot, val, reg, reg##_GSZ * (gi))
# define ocelot_write_rix(ocelot, val, reg, ri) __ocelot_write_ix(ocelot, val, reg, reg##_RSZ * (ri))
# define ocelot_write(ocelot, val, reg) __ocelot_write_ix(ocelot, val, reg, 0)
void __ocelot_rmw_ix ( struct ocelot * ocelot , u32 val , u32 reg , u32 mask ,
u32 offset ) ;
# define ocelot_rmw_ix(ocelot, val, m, reg, gi, ri) __ocelot_rmw_ix(ocelot, val, m, reg, reg##_GSZ * (gi) + reg##_RSZ * (ri))
# define ocelot_rmw_gix(ocelot, val, m, reg, gi) __ocelot_rmw_ix(ocelot, val, m, reg, reg##_GSZ * (gi))
# define ocelot_rmw_rix(ocelot, val, m, reg, ri) __ocelot_rmw_ix(ocelot, val, m, reg, reg##_RSZ * (ri))
# define ocelot_rmw(ocelot, val, m, reg) __ocelot_rmw_ix(ocelot, val, m, reg, 0)
u32 ocelot_port_readl ( struct ocelot_port * port , u32 reg ) ;
void ocelot_port_writel ( struct ocelot_port * port , u32 val , u32 reg ) ;
int ocelot_regfields_init ( struct ocelot * ocelot ,
const struct reg_field * const regfields ) ;
struct regmap * ocelot_io_platform_init ( struct ocelot * ocelot ,
struct platform_device * pdev ,
const char * name ) ;
# define ocelot_field_write(ocelot, reg, val) regmap_field_write((ocelot)->regfields[(reg)], (val))
# define ocelot_field_read(ocelot, reg, val) regmap_field_read((ocelot)->regfields[(reg)], (val))
int ocelot_init ( struct ocelot * ocelot ) ;
void ocelot_deinit ( struct ocelot * ocelot ) ;
int ocelot_chip_init ( struct ocelot * ocelot ) ;
int ocelot_probe_port ( struct ocelot * ocelot , u8 port ,
void __iomem * regs ,
struct phy_device * phy ) ;
extern struct notifier_block ocelot_netdevice_nb ;
2019-02-27 11:44:29 -08:00
extern struct notifier_block ocelot_switchdev_nb ;
2018-11-22 23:30:11 +00:00
extern struct notifier_block ocelot_switchdev_blocking_nb ;
2018-05-14 22:04:57 +02:00
# endif