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