1 /* SPDX-License-Identifier: GPL-2.0+ */ 2 /* Microchip Sparx5 Switch driver 3 * 4 * Copyright (c) 2021 Microchip Technology Inc. and its subsidiaries. 5 */ 6 7 #ifndef __SPARX5_MAIN_H__ 8 #define __SPARX5_MAIN_H__ 9 10 #include <linux/types.h> 11 #include <linux/phy/phy.h> 12 #include <linux/netdevice.h> 13 #include <linux/phy.h> 14 #include <linux/if_vlan.h> 15 #include <linux/bitmap.h> 16 #include <linux/phylink.h> 17 #include <linux/hrtimer.h> 18 19 /* Target chip type */ 20 enum spx5_target_chiptype { 21 SPX5_TARGET_CT_7546 = 0x7546, /* SparX-5-64 Enterprise */ 22 SPX5_TARGET_CT_7549 = 0x7549, /* SparX-5-90 Enterprise */ 23 SPX5_TARGET_CT_7552 = 0x7552, /* SparX-5-128 Enterprise */ 24 SPX5_TARGET_CT_7556 = 0x7556, /* SparX-5-160 Enterprise */ 25 SPX5_TARGET_CT_7558 = 0x7558, /* SparX-5-200 Enterprise */ 26 SPX5_TARGET_CT_7546TSN = 0x47546, /* SparX-5-64i Industrial */ 27 SPX5_TARGET_CT_7549TSN = 0x47549, /* SparX-5-90i Industrial */ 28 SPX5_TARGET_CT_7552TSN = 0x47552, /* SparX-5-128i Industrial */ 29 SPX5_TARGET_CT_7556TSN = 0x47556, /* SparX-5-160i Industrial */ 30 SPX5_TARGET_CT_7558TSN = 0x47558, /* SparX-5-200i Industrial */ 31 }; 32 33 enum sparx5_port_max_tags { 34 SPX5_PORT_MAX_TAGS_NONE, /* No extra tags allowed */ 35 SPX5_PORT_MAX_TAGS_ONE, /* Single tag allowed */ 36 SPX5_PORT_MAX_TAGS_TWO /* Single and double tag allowed */ 37 }; 38 39 enum sparx5_vlan_port_type { 40 SPX5_VLAN_PORT_TYPE_UNAWARE, /* VLAN unaware port */ 41 SPX5_VLAN_PORT_TYPE_C, /* C-port */ 42 SPX5_VLAN_PORT_TYPE_S, /* S-port */ 43 SPX5_VLAN_PORT_TYPE_S_CUSTOM /* S-port using custom type */ 44 }; 45 46 #define SPX5_PORTS 65 47 #define SPX5_PORT_CPU (SPX5_PORTS) /* Next port is CPU port */ 48 #define SPX5_PORT_CPU_0 (SPX5_PORT_CPU + 0) /* CPU Port 65 */ 49 #define SPX5_PORT_CPU_1 (SPX5_PORT_CPU + 1) /* CPU Port 66 */ 50 #define SPX5_PORT_VD0 (SPX5_PORT_CPU + 2) /* VD0/Port 67 used for IPMC */ 51 #define SPX5_PORT_VD1 (SPX5_PORT_CPU + 3) /* VD1/Port 68 used for AFI/OAM */ 52 #define SPX5_PORT_VD2 (SPX5_PORT_CPU + 4) /* VD2/Port 69 used for IPinIP*/ 53 #define SPX5_PORTS_ALL (SPX5_PORT_CPU + 5) /* Total number of ports */ 54 55 #define PGID_BASE SPX5_PORTS /* Starts after port PGIDs */ 56 #define PGID_UC_FLOOD (PGID_BASE + 0) 57 #define PGID_MC_FLOOD (PGID_BASE + 1) 58 #define PGID_IPV4_MC_DATA (PGID_BASE + 2) 59 #define PGID_IPV4_MC_CTRL (PGID_BASE + 3) 60 #define PGID_IPV6_MC_DATA (PGID_BASE + 4) 61 #define PGID_IPV6_MC_CTRL (PGID_BASE + 5) 62 #define PGID_BCAST (PGID_BASE + 6) 63 #define PGID_CPU (PGID_BASE + 7) 64 65 #define IFH_LEN 9 /* 36 bytes */ 66 #define NULL_VID 0 67 #define SPX5_MACT_PULL_DELAY (2 * HZ) 68 #define SPX5_STATS_CHECK_DELAY (1 * HZ) 69 #define SPX5_PRIOS 8 /* Number of priority queues */ 70 #define SPX5_BUFFER_CELL_SZ 184 /* Cell size */ 71 #define SPX5_BUFFER_MEMORY 4194280 /* 22795 words * 184 bytes */ 72 73 #define XTR_QUEUE 0 74 #define INJ_QUEUE 0 75 76 struct sparx5; 77 78 struct sparx5_port_config { 79 phy_interface_t portmode; 80 u32 bandwidth; 81 int speed; 82 int duplex; 83 enum phy_media media; 84 bool inband; 85 bool power_down; 86 bool autoneg; 87 bool serdes_reset; 88 u32 pause; 89 u32 pause_adv; 90 phy_interface_t phy_mode; 91 u32 sd_sgpio; 92 }; 93 94 struct sparx5_port { 95 struct net_device *ndev; 96 struct sparx5 *sparx5; 97 struct device_node *of_node; 98 struct phy *serdes; 99 struct sparx5_port_config conf; 100 struct phylink_config phylink_config; 101 struct phylink *phylink; 102 struct phylink_pcs phylink_pcs; 103 u16 portno; 104 /* Ingress default VLAN (pvid) */ 105 u16 pvid; 106 /* Egress default VLAN (vid) */ 107 u16 vid; 108 bool signd_internal; 109 bool signd_active_high; 110 bool signd_enable; 111 bool flow_control; 112 enum sparx5_port_max_tags max_vlan_tags; 113 enum sparx5_vlan_port_type vlan_type; 114 u32 custom_etype; 115 u32 ifh[IFH_LEN]; 116 bool vlan_aware; 117 struct hrtimer inj_timer; 118 }; 119 120 enum sparx5_core_clockfreq { 121 SPX5_CORE_CLOCK_DEFAULT, /* Defaults to the highest supported frequency */ 122 SPX5_CORE_CLOCK_250MHZ, /* 250MHZ core clock frequency */ 123 SPX5_CORE_CLOCK_500MHZ, /* 500MHZ core clock frequency */ 124 SPX5_CORE_CLOCK_625MHZ, /* 625MHZ core clock frequency */ 125 }; 126 127 struct sparx5 { 128 struct platform_device *pdev; 129 struct device *dev; 130 u32 chip_id; 131 enum spx5_target_chiptype target_ct; 132 void __iomem *regs[NUM_TARGETS]; 133 int port_count; 134 struct mutex lock; /* MAC reg lock */ 135 /* port structures are in net device */ 136 struct sparx5_port *ports[SPX5_PORTS]; 137 enum sparx5_core_clockfreq coreclock; 138 /* Statistics */ 139 u32 num_stats; 140 u32 num_ethtool_stats; 141 const char * const *stats_layout; 142 u64 *stats; 143 /* Workqueue for reading stats */ 144 struct mutex queue_stats_lock; 145 struct delayed_work stats_work; 146 struct workqueue_struct *stats_queue; 147 /* Notifiers */ 148 struct notifier_block netdevice_nb; 149 struct notifier_block switchdev_nb; 150 struct notifier_block switchdev_blocking_nb; 151 /* Switch state */ 152 u8 base_mac[ETH_ALEN]; 153 /* Associated bridge device (when bridged) */ 154 struct net_device *hw_bridge_dev; 155 /* Bridged interfaces */ 156 DECLARE_BITMAP(bridge_mask, SPX5_PORTS); 157 DECLARE_BITMAP(bridge_fwd_mask, SPX5_PORTS); 158 DECLARE_BITMAP(bridge_lrn_mask, SPX5_PORTS); 159 DECLARE_BITMAP(vlan_mask[VLAN_N_VID], SPX5_PORTS); 160 /* SW MAC table */ 161 struct list_head mact_entries; 162 /* mac table list (mact_entries) mutex */ 163 struct mutex mact_lock; 164 struct delayed_work mact_work; 165 struct workqueue_struct *mact_queue; 166 /* Board specifics */ 167 bool sd_sgpio_remapping; 168 /* Register based inj/xtr */ 169 int xtr_irq; 170 }; 171 172 /* sparx5_switchdev.c */ 173 int sparx5_register_notifier_blocks(struct sparx5 *sparx5); 174 void sparx5_unregister_notifier_blocks(struct sparx5 *sparx5); 175 176 /* sparx5_packet.c */ 177 irqreturn_t sparx5_xtr_handler(int irq, void *_priv); 178 int sparx5_port_xmit_impl(struct sk_buff *skb, struct net_device *dev); 179 int sparx5_manual_injection_mode(struct sparx5 *sparx5); 180 void sparx5_port_inj_timer_setup(struct sparx5_port *port); 181 182 /* sparx5_mactable.c */ 183 void sparx5_mact_pull_work(struct work_struct *work); 184 int sparx5_mact_learn(struct sparx5 *sparx5, int port, 185 const unsigned char mac[ETH_ALEN], u16 vid); 186 bool sparx5_mact_getnext(struct sparx5 *sparx5, 187 unsigned char mac[ETH_ALEN], u16 *vid, u32 *pcfg2); 188 int sparx5_mact_forget(struct sparx5 *sparx5, 189 const unsigned char mac[ETH_ALEN], u16 vid); 190 int sparx5_add_mact_entry(struct sparx5 *sparx5, 191 struct sparx5_port *port, 192 const unsigned char *addr, u16 vid); 193 int sparx5_del_mact_entry(struct sparx5 *sparx5, 194 const unsigned char *addr, 195 u16 vid); 196 int sparx5_mc_sync(struct net_device *dev, const unsigned char *addr); 197 int sparx5_mc_unsync(struct net_device *dev, const unsigned char *addr); 198 void sparx5_set_ageing(struct sparx5 *sparx5, int msecs); 199 void sparx5_mact_init(struct sparx5 *sparx5); 200 201 /* sparx5_vlan.c */ 202 void sparx5_pgid_update_mask(struct sparx5_port *port, int pgid, bool enable); 203 void sparx5_update_fwd(struct sparx5 *sparx5); 204 void sparx5_vlan_init(struct sparx5 *sparx5); 205 void sparx5_vlan_port_setup(struct sparx5 *sparx5, int portno); 206 int sparx5_vlan_vid_add(struct sparx5_port *port, u16 vid, bool pvid, 207 bool untagged); 208 int sparx5_vlan_vid_del(struct sparx5_port *port, u16 vid); 209 void sparx5_vlan_port_apply(struct sparx5 *sparx5, struct sparx5_port *port); 210 211 /* sparx5_calendar.c */ 212 int sparx5_config_auto_calendar(struct sparx5 *sparx5); 213 int sparx5_config_dsm_calendar(struct sparx5 *sparx5); 214 215 /* sparx5_ethtool.c */ 216 void sparx5_get_stats64(struct net_device *ndev, struct rtnl_link_stats64 *stats); 217 int sparx_stats_init(struct sparx5 *sparx5); 218 219 /* sparx5_netdev.c */ 220 bool sparx5_netdevice_check(const struct net_device *dev); 221 struct net_device *sparx5_create_netdev(struct sparx5 *sparx5, u32 portno); 222 int sparx5_register_netdevs(struct sparx5 *sparx5); 223 void sparx5_destroy_netdevs(struct sparx5 *sparx5); 224 void sparx5_unregister_netdevs(struct sparx5 *sparx5); 225 226 /* Clock period in picoseconds */ 227 static inline u32 sparx5_clk_period(enum sparx5_core_clockfreq cclock) 228 { 229 switch (cclock) { 230 case SPX5_CORE_CLOCK_250MHZ: 231 return 4000; 232 case SPX5_CORE_CLOCK_500MHZ: 233 return 2000; 234 case SPX5_CORE_CLOCK_625MHZ: 235 default: 236 return 1600; 237 } 238 } 239 240 static inline bool sparx5_is_baser(phy_interface_t interface) 241 { 242 return interface == PHY_INTERFACE_MODE_5GBASER || 243 interface == PHY_INTERFACE_MODE_10GBASER || 244 interface == PHY_INTERFACE_MODE_25GBASER; 245 } 246 247 extern const struct phylink_mac_ops sparx5_phylink_mac_ops; 248 extern const struct phylink_pcs_ops sparx5_phylink_pcs_ops; 249 extern const struct ethtool_ops sparx5_ethtool_ops; 250 251 /* Calculate raw offset */ 252 static inline __pure int spx5_offset(int id, int tinst, int tcnt, 253 int gbase, int ginst, 254 int gcnt, int gwidth, 255 int raddr, int rinst, 256 int rcnt, int rwidth) 257 { 258 WARN_ON((tinst) >= tcnt); 259 WARN_ON((ginst) >= gcnt); 260 WARN_ON((rinst) >= rcnt); 261 return gbase + ((ginst) * gwidth) + 262 raddr + ((rinst) * rwidth); 263 } 264 265 /* Read, Write and modify registers content. 266 * The register definition macros start at the id 267 */ 268 static inline void __iomem *spx5_addr(void __iomem *base[], 269 int id, int tinst, int tcnt, 270 int gbase, int ginst, 271 int gcnt, int gwidth, 272 int raddr, int rinst, 273 int rcnt, int rwidth) 274 { 275 WARN_ON((tinst) >= tcnt); 276 WARN_ON((ginst) >= gcnt); 277 WARN_ON((rinst) >= rcnt); 278 return base[id + (tinst)] + 279 gbase + ((ginst) * gwidth) + 280 raddr + ((rinst) * rwidth); 281 } 282 283 static inline void __iomem *spx5_inst_addr(void __iomem *base, 284 int gbase, int ginst, 285 int gcnt, int gwidth, 286 int raddr, int rinst, 287 int rcnt, int rwidth) 288 { 289 WARN_ON((ginst) >= gcnt); 290 WARN_ON((rinst) >= rcnt); 291 return base + 292 gbase + ((ginst) * gwidth) + 293 raddr + ((rinst) * rwidth); 294 } 295 296 static inline u32 spx5_rd(struct sparx5 *sparx5, int id, int tinst, int tcnt, 297 int gbase, int ginst, int gcnt, int gwidth, 298 int raddr, int rinst, int rcnt, int rwidth) 299 { 300 return readl(spx5_addr(sparx5->regs, id, tinst, tcnt, gbase, ginst, 301 gcnt, gwidth, raddr, rinst, rcnt, rwidth)); 302 } 303 304 static inline u32 spx5_inst_rd(void __iomem *iomem, int id, int tinst, int tcnt, 305 int gbase, int ginst, int gcnt, int gwidth, 306 int raddr, int rinst, int rcnt, int rwidth) 307 { 308 return readl(spx5_inst_addr(iomem, gbase, ginst, 309 gcnt, gwidth, raddr, rinst, rcnt, rwidth)); 310 } 311 312 static inline void spx5_wr(u32 val, struct sparx5 *sparx5, 313 int id, int tinst, int tcnt, 314 int gbase, int ginst, int gcnt, int gwidth, 315 int raddr, int rinst, int rcnt, int rwidth) 316 { 317 writel(val, spx5_addr(sparx5->regs, id, tinst, tcnt, 318 gbase, ginst, gcnt, gwidth, 319 raddr, rinst, rcnt, rwidth)); 320 } 321 322 static inline void spx5_inst_wr(u32 val, void __iomem *iomem, 323 int id, int tinst, int tcnt, 324 int gbase, int ginst, int gcnt, int gwidth, 325 int raddr, int rinst, int rcnt, int rwidth) 326 { 327 writel(val, spx5_inst_addr(iomem, 328 gbase, ginst, gcnt, gwidth, 329 raddr, rinst, rcnt, rwidth)); 330 } 331 332 static inline void spx5_rmw(u32 val, u32 mask, struct sparx5 *sparx5, 333 int id, int tinst, int tcnt, 334 int gbase, int ginst, int gcnt, int gwidth, 335 int raddr, int rinst, int rcnt, int rwidth) 336 { 337 u32 nval; 338 339 nval = readl(spx5_addr(sparx5->regs, id, tinst, tcnt, gbase, ginst, 340 gcnt, gwidth, raddr, rinst, rcnt, rwidth)); 341 nval = (nval & ~mask) | (val & mask); 342 writel(nval, spx5_addr(sparx5->regs, id, tinst, tcnt, gbase, ginst, 343 gcnt, gwidth, raddr, rinst, rcnt, rwidth)); 344 } 345 346 static inline void spx5_inst_rmw(u32 val, u32 mask, void __iomem *iomem, 347 int id, int tinst, int tcnt, 348 int gbase, int ginst, int gcnt, int gwidth, 349 int raddr, int rinst, int rcnt, int rwidth) 350 { 351 u32 nval; 352 353 nval = readl(spx5_inst_addr(iomem, gbase, ginst, gcnt, gwidth, raddr, 354 rinst, rcnt, rwidth)); 355 nval = (nval & ~mask) | (val & mask); 356 writel(nval, spx5_inst_addr(iomem, gbase, ginst, gcnt, gwidth, raddr, 357 rinst, rcnt, rwidth)); 358 } 359 360 static inline void __iomem *spx5_inst_get(struct sparx5 *sparx5, int id, int tinst) 361 { 362 return sparx5->regs[id + tinst]; 363 } 364 365 static inline void __iomem *spx5_reg_get(struct sparx5 *sparx5, 366 int id, int tinst, int tcnt, 367 int gbase, int ginst, int gcnt, int gwidth, 368 int raddr, int rinst, int rcnt, int rwidth) 369 { 370 return spx5_addr(sparx5->regs, id, tinst, tcnt, 371 gbase, ginst, gcnt, gwidth, 372 raddr, rinst, rcnt, rwidth); 373 } 374 375 #endif /* __SPARX5_MAIN_H__ */ 376