1187fbae0SWei Fang /* SPDX-License-Identifier: (GPL-2.0+ OR BSD-3-Clause) */ 2187fbae0SWei Fang /* 3187fbae0SWei Fang * Copyright 2025-2026 NXP 4187fbae0SWei Fang */ 5187fbae0SWei Fang 6187fbae0SWei Fang #ifndef _NETC_SWITCH_H 7187fbae0SWei Fang #define _NETC_SWITCH_H 8187fbae0SWei Fang 9187fbae0SWei Fang #include <linux/dsa/tag_netc.h> 10187fbae0SWei Fang #include <linux/fsl/netc_global.h> 11187fbae0SWei Fang #include <linux/fsl/ntmp.h> 12187fbae0SWei Fang #include <linux/of_device.h> 13187fbae0SWei Fang #include <linux/of_net.h> 14187fbae0SWei Fang #include <linux/pci.h> 15187fbae0SWei Fang 16187fbae0SWei Fang #include "netc_switch_hw.h" 17187fbae0SWei Fang 18187fbae0SWei Fang #define NETC_REGS_BAR 0 19187fbae0SWei Fang #define NETC_REGS_SIZE 0x80000 20187fbae0SWei Fang #define NETC_MSIX_TBL_BAR 2 21187fbae0SWei Fang #define NETC_REGS_PORT_BASE 0x4000 22187fbae0SWei Fang /* register block size per port */ 23187fbae0SWei Fang #define NETC_REGS_PORT_SIZE 0x4000 24187fbae0SWei Fang #define PORT_IOBASE(p) (NETC_REGS_PORT_SIZE * (p)) 25187fbae0SWei Fang #define NETC_REGS_GLOBAL_BASE 0x70000 26187fbae0SWei Fang 27187fbae0SWei Fang #define NETC_SWITCH_REV_4_3 0x0403 28187fbae0SWei Fang 29187fbae0SWei Fang #define NETC_TC_NUM 8 30187fbae0SWei Fang #define NETC_CBDR_NUM 2 31a5ccb7f5SWei Fang #define NETC_IPV_NUM 8 32187fbae0SWei Fang 33187fbae0SWei Fang #define NETC_MAX_FRAME_LEN 9600 34187fbae0SWei Fang 3546d64076SWei Fang #define NETC_STANDALONE_PVID 0 36751aa5a5SWei Fang #define NETC_VLAN_UNAWARE_PVID(br_id) (4096 - (br_id)) 3746d64076SWei Fang 38a5ccb7f5SWei Fang /* Threshold format: MANT (bits 11:4) * 2^EXP (bits 3:0) 39a5ccb7f5SWei Fang * Unit: Memory words (average of 20 bytes each) 40a5ccb7f5SWei Fang * NETC_BP_THRESH = 0x8c3, MANT = 0x8c, EXP = 3. Threshold: 1120 words 41a5ccb7f5SWei Fang * NETC_FC_THRESH_ON = 0x733, MANT = 0x73, EXP = 3. Threshold: 920 words 42a5ccb7f5SWei Fang * NETC_FC_THRESH_OFF = 0x263, MANT = 0x26, EXP = 3. Threshold: 304 words 43a5ccb7f5SWei Fang */ 44a5ccb7f5SWei Fang #define NETC_BP_THRESH 0x8c3 45a5ccb7f5SWei Fang #define NETC_FC_THRESH_ON 0x733 46a5ccb7f5SWei Fang #define NETC_FC_THRESH_OFF 0x263 47a5ccb7f5SWei Fang 48a5ccb7f5SWei Fang /* PAUSE quanta: 0xFFFF = 65535 quanta (each quanta = 512 bit times) */ 49a5ccb7f5SWei Fang #define NETC_PAUSE_QUANTA 0xFFFF 50a5ccb7f5SWei Fang /* PAUSE refresh threshold: send refresh when timer reaches this value */ 51a5ccb7f5SWei Fang #define NETC_PAUSE_THRESH 0x7FFF 52a5ccb7f5SWei Fang 53*05b5ee61SWei Fang #define NETC_FDBT_AGEING_DELAY (3 * HZ) 54*05b5ee61SWei Fang #define NETC_FDBT_AGEING_THRESH 100 55*05b5ee61SWei Fang 56187fbae0SWei Fang struct netc_switch; 57187fbae0SWei Fang 58187fbae0SWei Fang struct netc_switch_info { 59187fbae0SWei Fang u32 num_ports; 60bbe97e34SWei Fang void (*phylink_get_caps)(int port, struct phylink_config *config); 61187fbae0SWei Fang }; 62187fbae0SWei Fang 63187fbae0SWei Fang struct netc_port_caps { 64187fbae0SWei Fang u32 half_duplex:1; /* indicates whether the port support half-duplex */ 65187fbae0SWei Fang u32 pmac:1; /* indicates whether the port has preemption MAC */ 66187fbae0SWei Fang u32 pseudo_link:1; 67187fbae0SWei Fang }; 68187fbae0SWei Fang 6946d64076SWei Fang enum netc_host_reason { 7046d64076SWei Fang /* Software defined host reasons */ 7146d64076SWei Fang NETC_HR_HOST_FLOOD = 8, 7246d64076SWei Fang }; 7346d64076SWei Fang 74187fbae0SWei Fang struct netc_port { 75187fbae0SWei Fang void __iomem *iobase; 76187fbae0SWei Fang struct netc_switch *switch_priv; 77187fbae0SWei Fang struct netc_port_caps caps; 78187fbae0SWei Fang struct dsa_port *dp; 7946d64076SWei Fang struct clk *ref_clk; /* RGMII/RMII reference clock */ 80187fbae0SWei Fang struct mii_bus *emdio; 8184b4a3b3SWei Fang int ett_offset; 8246d64076SWei Fang 8346d64076SWei Fang u16 enable:1; 8446d64076SWei Fang u16 uc:1; 8546d64076SWei Fang u16 mc:1; 86751aa5a5SWei Fang u16 pvid; 8746d64076SWei Fang struct ipft_entry_data *host_flood; 88187fbae0SWei Fang }; 89187fbae0SWei Fang 90187fbae0SWei Fang struct netc_switch_regs { 91187fbae0SWei Fang void __iomem *base; 92187fbae0SWei Fang void __iomem *port; 93187fbae0SWei Fang void __iomem *global; 94187fbae0SWei Fang }; 95187fbae0SWei Fang 9646d64076SWei Fang struct netc_fdb_entry { 9746d64076SWei Fang u32 entry_id; 9846d64076SWei Fang struct fdbt_cfge_data cfge; 9946d64076SWei Fang struct fdbt_keye_data keye; 10046d64076SWei Fang struct hlist_node node; 10146d64076SWei Fang }; 10246d64076SWei Fang 10384b4a3b3SWei Fang struct netc_vlan_entry { 10484b4a3b3SWei Fang u16 vid; 10584b4a3b3SWei Fang u32 ect_gid; 10684b4a3b3SWei Fang u32 untagged_port_bitmap; 10784b4a3b3SWei Fang struct vft_cfge_data cfge; 10884b4a3b3SWei Fang struct hlist_node node; 10984b4a3b3SWei Fang }; 11084b4a3b3SWei Fang 111beb0e54fSWei Fang struct netc_port_stat { 112beb0e54fSWei Fang int reg; 113beb0e54fSWei Fang char name[ETH_GSTRING_LEN] __nonstring; 114beb0e54fSWei Fang }; 115beb0e54fSWei Fang 116187fbae0SWei Fang struct netc_switch { 117187fbae0SWei Fang struct pci_dev *pdev; 118187fbae0SWei Fang struct device *dev; 119187fbae0SWei Fang struct dsa_switch *ds; 120187fbae0SWei Fang u16 revision; 121187fbae0SWei Fang 122187fbae0SWei Fang const struct netc_switch_info *info; 123187fbae0SWei Fang struct netc_switch_regs regs; 124187fbae0SWei Fang struct netc_port **ports; 12584b4a3b3SWei Fang u32 port_bitmap; /* bitmap of available ports */ 126187fbae0SWei Fang 127187fbae0SWei Fang struct ntmp_user ntmp; 12846d64076SWei Fang struct hlist_head fdb_list; 12946d64076SWei Fang struct mutex fdbt_lock; /* FDB table lock */ 130*05b5ee61SWei Fang struct delayed_work fdbt_ageing_work; 131*05b5ee61SWei Fang /* (fdbt_ageing_delay * NETC_FDBT_AGEING_THRESH) is ageing time */ 132*05b5ee61SWei Fang unsigned long fdbt_ageing_delay; 133*05b5ee61SWei Fang atomic_t br_cnt; 13484b4a3b3SWei Fang struct hlist_head vlan_list; 13584b4a3b3SWei Fang struct mutex vft_lock; /* VLAN filter table lock */ 13646d64076SWei Fang 13746d64076SWei Fang /* Switch hardware capabilities */ 13846d64076SWei Fang u32 htmcapr_num_words; 139a5ccb7f5SWei Fang u32 num_bp; 140a5ccb7f5SWei Fang 141a5ccb7f5SWei Fang struct bpt_cfge_data *bpt_list; 142187fbae0SWei Fang }; 143187fbae0SWei Fang 144bbe97e34SWei Fang #define NETC_PRIV(ds) ((struct netc_switch *)((ds)->priv)) 145bbe97e34SWei Fang #define NETC_PORT(ds, port_id) (NETC_PRIV(ds)->ports[(port_id)]) 146bbe97e34SWei Fang 147187fbae0SWei Fang /* Write/Read Switch base registers */ 148187fbae0SWei Fang #define netc_base_rd(r, o) netc_read((r)->base + (o)) 149187fbae0SWei Fang #define netc_base_wr(r, o, v) netc_write((r)->base + (o), v) 150187fbae0SWei Fang 151187fbae0SWei Fang /* Write/Read registers of Switch Port (including pseudo MAC port) */ 152187fbae0SWei Fang #define netc_port_rd(p, o) netc_read((p)->iobase + (o)) 15325049d8bSWei Fang #define netc_port_rd64(p, o) netc_read64((p)->iobase + (o)) 154187fbae0SWei Fang #define netc_port_wr(p, o, v) netc_write((p)->iobase + (o), v) 155187fbae0SWei Fang 156187fbae0SWei Fang /* Write/Read Switch global registers */ 157187fbae0SWei Fang #define netc_glb_rd(r, o) netc_read((r)->global + (o)) 158187fbae0SWei Fang #define netc_glb_wr(r, o, v) netc_write((r)->global + (o), v) 159187fbae0SWei Fang 160187fbae0SWei Fang static inline bool is_netc_pseudo_port(struct netc_port *np) 161187fbae0SWei Fang { 162187fbae0SWei Fang return np->caps.pseudo_link; 163187fbae0SWei Fang } 164187fbae0SWei Fang 16546d64076SWei Fang static inline void netc_add_fdb_entry(struct netc_switch *priv, 16646d64076SWei Fang struct netc_fdb_entry *entry) 16746d64076SWei Fang { 16846d64076SWei Fang hlist_add_head(&entry->node, &priv->fdb_list); 16946d64076SWei Fang } 17046d64076SWei Fang 17146d64076SWei Fang static inline void netc_del_fdb_entry(struct netc_fdb_entry *entry) 17246d64076SWei Fang { 17346d64076SWei Fang hlist_del(&entry->node); 17446d64076SWei Fang kfree(entry); 17546d64076SWei Fang } 17646d64076SWei Fang 17784b4a3b3SWei Fang static inline void netc_add_vlan_entry(struct netc_switch *priv, 17884b4a3b3SWei Fang struct netc_vlan_entry *entry) 17984b4a3b3SWei Fang { 18084b4a3b3SWei Fang hlist_add_head(&entry->node, &priv->vlan_list); 18184b4a3b3SWei Fang } 18284b4a3b3SWei Fang 18384b4a3b3SWei Fang static inline void netc_del_vlan_entry(struct netc_vlan_entry *entry) 18484b4a3b3SWei Fang { 18584b4a3b3SWei Fang hlist_del(&entry->node); 18684b4a3b3SWei Fang kfree(entry); 18784b4a3b3SWei Fang } 18884b4a3b3SWei Fang 189187fbae0SWei Fang int netc_switch_platform_probe(struct netc_switch *priv); 190187fbae0SWei Fang 19125049d8bSWei Fang /* ethtool APIs */ 19225049d8bSWei Fang void netc_port_get_pause_stats(struct dsa_switch *ds, int port, 19325049d8bSWei Fang struct ethtool_pause_stats *pause_stats); 19425049d8bSWei Fang void netc_port_get_rmon_stats(struct dsa_switch *ds, int port, 19525049d8bSWei Fang struct ethtool_rmon_stats *rmon_stats, 19625049d8bSWei Fang const struct ethtool_rmon_hist_range **ranges); 19725049d8bSWei Fang void netc_port_get_eth_ctrl_stats(struct dsa_switch *ds, int port, 19825049d8bSWei Fang struct ethtool_eth_ctrl_stats *ctrl_stats); 19925049d8bSWei Fang void netc_port_get_eth_mac_stats(struct dsa_switch *ds, int port, 20025049d8bSWei Fang struct ethtool_eth_mac_stats *mac_stats); 201beb0e54fSWei Fang int netc_port_get_sset_count(struct dsa_switch *ds, int port, int sset); 202beb0e54fSWei Fang void netc_port_get_strings(struct dsa_switch *ds, int port, 203beb0e54fSWei Fang u32 sset, u8 *data); 204beb0e54fSWei Fang void netc_port_get_ethtool_stats(struct dsa_switch *ds, int port, u64 *data); 20525049d8bSWei Fang 206187fbae0SWei Fang #endif 207