162306a36Sopenharmony_ci/* SPDX-License-Identifier: (GPL-2.0 OR MIT) */ 262306a36Sopenharmony_ci/* 362306a36Sopenharmony_ci * Microsemi Ocelot Switch driver 462306a36Sopenharmony_ci * 562306a36Sopenharmony_ci * Copyright (c) 2017 Microsemi Corporation 662306a36Sopenharmony_ci */ 762306a36Sopenharmony_ci 862306a36Sopenharmony_ci#ifndef _MSCC_OCELOT_H_ 962306a36Sopenharmony_ci#define _MSCC_OCELOT_H_ 1062306a36Sopenharmony_ci 1162306a36Sopenharmony_ci#include <linux/bitops.h> 1262306a36Sopenharmony_ci#include <linux/etherdevice.h> 1362306a36Sopenharmony_ci#include <linux/if_vlan.h> 1462306a36Sopenharmony_ci#include <linux/net_tstamp.h> 1562306a36Sopenharmony_ci#include <linux/phylink.h> 1662306a36Sopenharmony_ci#include <linux/platform_device.h> 1762306a36Sopenharmony_ci#include <linux/regmap.h> 1862306a36Sopenharmony_ci 1962306a36Sopenharmony_ci#include <soc/mscc/ocelot_qsys.h> 2062306a36Sopenharmony_ci#include <soc/mscc/ocelot_sys.h> 2162306a36Sopenharmony_ci#include <soc/mscc/ocelot_dev.h> 2262306a36Sopenharmony_ci#include <soc/mscc/ocelot_ana.h> 2362306a36Sopenharmony_ci#include <soc/mscc/ocelot_ptp.h> 2462306a36Sopenharmony_ci#include <soc/mscc/ocelot_vcap.h> 2562306a36Sopenharmony_ci#include <soc/mscc/ocelot.h> 2662306a36Sopenharmony_ci#include "ocelot_rew.h" 2762306a36Sopenharmony_ci#include "ocelot_qs.h" 2862306a36Sopenharmony_ci 2962306a36Sopenharmony_ci#define OCELOT_STANDALONE_PVID 0 3062306a36Sopenharmony_ci#define OCELOT_BUFFER_CELL_SZ 60 3162306a36Sopenharmony_ci 3262306a36Sopenharmony_ci#define OCELOT_STATS_CHECK_DELAY (2 * HZ) 3362306a36Sopenharmony_ci 3462306a36Sopenharmony_ci#define OCELOT_PTP_QUEUE_SZ 128 3562306a36Sopenharmony_ci 3662306a36Sopenharmony_ci#define OCELOT_JUMBO_MTU 9000 3762306a36Sopenharmony_ci 3862306a36Sopenharmony_cistruct ocelot_port_tc { 3962306a36Sopenharmony_ci bool block_shared; 4062306a36Sopenharmony_ci unsigned long offload_cnt; 4162306a36Sopenharmony_ci unsigned long ingress_mirred_id; 4262306a36Sopenharmony_ci unsigned long egress_mirred_id; 4362306a36Sopenharmony_ci unsigned long police_id; 4462306a36Sopenharmony_ci}; 4562306a36Sopenharmony_ci 4662306a36Sopenharmony_cistruct ocelot_port_private { 4762306a36Sopenharmony_ci struct ocelot_port port; 4862306a36Sopenharmony_ci struct net_device *dev; 4962306a36Sopenharmony_ci struct phylink *phylink; 5062306a36Sopenharmony_ci struct phylink_config phylink_config; 5162306a36Sopenharmony_ci struct ocelot_port_tc tc; 5262306a36Sopenharmony_ci}; 5362306a36Sopenharmony_ci 5462306a36Sopenharmony_ci/* A (PGID) port mask structure, encoding the 2^ocelot->num_phys_ports 5562306a36Sopenharmony_ci * possibilities of egress port masks for L2 multicast traffic. 5662306a36Sopenharmony_ci * For a switch with 9 user ports, there are 512 possible port masks, but the 5762306a36Sopenharmony_ci * hardware only has 46 individual PGIDs that it can forward multicast traffic 5862306a36Sopenharmony_ci * to. So we need a structure that maps the limited PGID indices to the port 5962306a36Sopenharmony_ci * destinations requested by the user for L2 multicast. 6062306a36Sopenharmony_ci */ 6162306a36Sopenharmony_cistruct ocelot_pgid { 6262306a36Sopenharmony_ci unsigned long ports; 6362306a36Sopenharmony_ci int index; 6462306a36Sopenharmony_ci refcount_t refcount; 6562306a36Sopenharmony_ci struct list_head list; 6662306a36Sopenharmony_ci}; 6762306a36Sopenharmony_ci 6862306a36Sopenharmony_cistruct ocelot_multicast { 6962306a36Sopenharmony_ci struct list_head list; 7062306a36Sopenharmony_ci enum macaccess_entry_type entry_type; 7162306a36Sopenharmony_ci unsigned char addr[ETH_ALEN]; 7262306a36Sopenharmony_ci u16 vid; 7362306a36Sopenharmony_ci u16 ports; 7462306a36Sopenharmony_ci struct ocelot_pgid *pgid; 7562306a36Sopenharmony_ci}; 7662306a36Sopenharmony_ci 7762306a36Sopenharmony_cistatic inline void ocelot_reg_to_target_addr(struct ocelot *ocelot, 7862306a36Sopenharmony_ci enum ocelot_reg reg, 7962306a36Sopenharmony_ci enum ocelot_target *target, 8062306a36Sopenharmony_ci u32 *addr) 8162306a36Sopenharmony_ci{ 8262306a36Sopenharmony_ci *target = reg >> TARGET_OFFSET; 8362306a36Sopenharmony_ci *addr = ocelot->map[*target][reg & REG_MASK]; 8462306a36Sopenharmony_ci} 8562306a36Sopenharmony_ci 8662306a36Sopenharmony_ciint ocelot_bridge_num_find(struct ocelot *ocelot, 8762306a36Sopenharmony_ci const struct net_device *bridge); 8862306a36Sopenharmony_ci 8962306a36Sopenharmony_ciint ocelot_mact_learn(struct ocelot *ocelot, int port, 9062306a36Sopenharmony_ci const unsigned char mac[ETH_ALEN], 9162306a36Sopenharmony_ci unsigned int vid, enum macaccess_entry_type type); 9262306a36Sopenharmony_ciint ocelot_mact_forget(struct ocelot *ocelot, 9362306a36Sopenharmony_ci const unsigned char mac[ETH_ALEN], unsigned int vid); 9462306a36Sopenharmony_cistruct net_device *ocelot_port_to_netdev(struct ocelot *ocelot, int port); 9562306a36Sopenharmony_ciint ocelot_netdev_to_port(struct net_device *dev); 9662306a36Sopenharmony_ci 9762306a36Sopenharmony_ciint ocelot_probe_port(struct ocelot *ocelot, int port, struct regmap *target, 9862306a36Sopenharmony_ci struct device_node *portnp); 9962306a36Sopenharmony_civoid ocelot_release_port(struct ocelot_port *ocelot_port); 10062306a36Sopenharmony_ciint ocelot_port_devlink_init(struct ocelot *ocelot, int port, 10162306a36Sopenharmony_ci enum devlink_port_flavour flavour); 10262306a36Sopenharmony_civoid ocelot_port_devlink_teardown(struct ocelot *ocelot, int port); 10362306a36Sopenharmony_ci 10462306a36Sopenharmony_ciint ocelot_trap_add(struct ocelot *ocelot, int port, 10562306a36Sopenharmony_ci unsigned long cookie, bool take_ts, 10662306a36Sopenharmony_ci void (*populate)(struct ocelot_vcap_filter *f)); 10762306a36Sopenharmony_ciint ocelot_trap_del(struct ocelot *ocelot, int port, unsigned long cookie); 10862306a36Sopenharmony_ci 10962306a36Sopenharmony_cistruct ocelot_mirror *ocelot_mirror_get(struct ocelot *ocelot, int to, 11062306a36Sopenharmony_ci struct netlink_ext_ack *extack); 11162306a36Sopenharmony_civoid ocelot_mirror_put(struct ocelot *ocelot); 11262306a36Sopenharmony_ci 11362306a36Sopenharmony_ciint ocelot_stats_init(struct ocelot *ocelot); 11462306a36Sopenharmony_civoid ocelot_stats_deinit(struct ocelot *ocelot); 11562306a36Sopenharmony_ci 11662306a36Sopenharmony_ciint ocelot_mm_init(struct ocelot *ocelot); 11762306a36Sopenharmony_civoid ocelot_port_change_fp(struct ocelot *ocelot, int port, 11862306a36Sopenharmony_ci unsigned long preemptible_tcs); 11962306a36Sopenharmony_civoid ocelot_port_update_active_preemptible_tcs(struct ocelot *ocelot, int port); 12062306a36Sopenharmony_ci 12162306a36Sopenharmony_ciextern struct notifier_block ocelot_netdevice_nb; 12262306a36Sopenharmony_ciextern struct notifier_block ocelot_switchdev_nb; 12362306a36Sopenharmony_ciextern struct notifier_block ocelot_switchdev_blocking_nb; 12462306a36Sopenharmony_ciextern const struct devlink_ops ocelot_devlink_ops; 12562306a36Sopenharmony_ci 12662306a36Sopenharmony_ci#endif 127