linux/drivers/net/dsa/ocelot/felix.c

// SPDX-License-Identifier: GPL-2.0
/* Copyright 2019-2021 NXP
 *
 * This is an umbrella module for all network switches that are
 * register-compatible with Ocelot and that perform I/O to their host CPU
 * through an NPI (Node Processor Interface) Ethernet port.
 */
#include <uapi/linux/if_bridge.h>
#include <soc/mscc/ocelot_vcap.h>
#include <soc/mscc/ocelot_qsys.h>
#include <soc/mscc/ocelot_sys.h>
#include <soc/mscc/ocelot_dev.h>
#include <soc/mscc/ocelot_ana.h>
#include <soc/mscc/ocelot_ptp.h>
#include <soc/mscc/ocelot.h>
#include <linux/dsa/8021q.h>
#include <linux/dsa/ocelot.h>
#include <linux/platform_device.h>
#include <linux/ptp_classify.h>
#include <linux/module.h>
#include <linux/of_net.h>
#include <linux/pci.h>
#include <linux/of.h>
#include <net/pkt_sched.h>
#include <net/dsa.h>
#include "felix.h"

/* Translate the DSA database API into the ocelot switch library API,
 * which uses VID 0 for all ports that aren't part of a bridge,
 * and expects the bridge_dev to be NULL in that case.
 */
static struct net_device *felix_classify_db(struct dsa_db db)
{}

static int felix_cpu_port_for_conduit(struct dsa_switch *ds,
				      struct net_device *conduit)
{}

/* Set up VCAP ES0 rules for pushing a tag_8021q VLAN towards the CPU such that
 * the tagger can perform RX source port identification.
 */
static int felix_tag_8021q_vlan_add_rx(struct dsa_switch *ds, int port,
				       int upstream, u16 vid)
{}

static int felix_tag_8021q_vlan_del_rx(struct dsa_switch *ds, int port,
				       int upstream, u16 vid)
{}

/* Set up VCAP IS1 rules for stripping the tag_8021q VLAN on TX and VCAP IS2
 * rules for steering those tagged packets towards the correct destination port
 */
static int felix_tag_8021q_vlan_add_tx(struct dsa_switch *ds, int port,
				       u16 vid)
{}

static int felix_tag_8021q_vlan_del_tx(struct dsa_switch *ds, int port, u16 vid)
{}

static int felix_tag_8021q_vlan_add(struct dsa_switch *ds, int port, u16 vid,
				    u16 flags)
{}

static int felix_tag_8021q_vlan_del(struct dsa_switch *ds, int port, u16 vid)
{}

static int felix_trap_get_cpu_port(struct dsa_switch *ds,
				   const struct ocelot_vcap_filter *trap)
{}

/* On switches with no extraction IRQ wired, trapped packets need to be
 * replicated over Ethernet as well, otherwise we'd get no notification of
 * their arrival when using the ocelot-8021q tagging protocol.
 */
static int felix_update_trapping_destinations(struct dsa_switch *ds,
					      bool using_tag_8021q)
{}

/* The CPU port module is connected to the Node Processor Interface (NPI). This
 * is the mode through which frames can be injected from and extracted to an
 * external CPU, over Ethernet. In NXP SoCs, the "external CPU" is the ARM CPU
 * running Linux, and this forms a DSA setup together with the enetc or fman
 * DSA conduit.
 */
static void felix_npi_port_init(struct ocelot *ocelot, int port)
{}

static void felix_npi_port_deinit(struct ocelot *ocelot, int port)
{}

static int felix_tag_npi_setup(struct dsa_switch *ds)
{}

static void felix_tag_npi_teardown(struct dsa_switch *ds)
{}

static unsigned long felix_tag_npi_get_host_fwd_mask(struct dsa_switch *ds)
{}

static int felix_tag_npi_change_conduit(struct dsa_switch *ds, int port,
					struct net_device *conduit,
					struct netlink_ext_ack *extack)
{}

/* Alternatively to using the NPI functionality, that same hardware MAC
 * connected internally to the enetc or fman DSA conduit can be configured to
 * use the software-defined tag_8021q frame format. As far as the hardware is
 * concerned, it thinks it is a "dumb switch" - the queues of the CPU port
 * module are now disconnected from it, but can still be accessed through
 * register-based MMIO.
 */
static const struct felix_tag_proto_ops felix_tag_npi_proto_ops =;

static int felix_tag_8021q_setup(struct dsa_switch *ds)
{}

static void felix_tag_8021q_teardown(struct dsa_switch *ds)
{}

static unsigned long felix_tag_8021q_get_host_fwd_mask(struct dsa_switch *ds)
{}

static int felix_tag_8021q_change_conduit(struct dsa_switch *ds, int port,
					  struct net_device *conduit,
					  struct netlink_ext_ack *extack)
{}

static const struct felix_tag_proto_ops felix_tag_8021q_proto_ops =;

static void felix_set_host_flood(struct dsa_switch *ds, unsigned long mask,
				 bool uc, bool mc, bool bc)
{}

static void
felix_migrate_host_flood(struct dsa_switch *ds,
			 const struct felix_tag_proto_ops *proto_ops,
			 const struct felix_tag_proto_ops *old_proto_ops)
{}

static int felix_migrate_mdbs(struct dsa_switch *ds,
			      const struct felix_tag_proto_ops *proto_ops,
			      const struct felix_tag_proto_ops *old_proto_ops)
{}

/* Configure the shared hardware resources for a transition between
 * @old_proto_ops and @proto_ops.
 * Manual migration is needed because as far as DSA is concerned, no change of
 * the CPU port is taking place here, just of the tagging protocol.
 */
static int
felix_tag_proto_setup_shared(struct dsa_switch *ds,
			     const struct felix_tag_proto_ops *proto_ops,
			     const struct felix_tag_proto_ops *old_proto_ops)
{}

/* This always leaves the switch in a consistent state, because although the
 * tag_8021q setup can fail, the NPI setup can't. So either the change is made,
 * or the restoration is guaranteed to work.
 */
static int felix_change_tag_protocol(struct dsa_switch *ds,
				     enum dsa_tag_protocol proto)
{}

static enum dsa_tag_protocol felix_get_tag_protocol(struct dsa_switch *ds,
						    int port,
						    enum dsa_tag_protocol mp)
{}

static void felix_port_set_host_flood(struct dsa_switch *ds, int port,
				      bool uc, bool mc)
{}

static int felix_port_change_conduit(struct dsa_switch *ds, int port,
				     struct net_device *conduit,
				     struct netlink_ext_ack *extack)
{}

static int felix_set_ageing_time(struct dsa_switch *ds,
				 unsigned int ageing_time)
{}

static void felix_port_fast_age(struct dsa_switch *ds, int port)
{}

static int felix_fdb_dump(struct dsa_switch *ds, int port,
			  dsa_fdb_dump_cb_t *cb, void *data)
{}

static int felix_fdb_add(struct dsa_switch *ds, int port,
			 const unsigned char *addr, u16 vid,
			 struct dsa_db db)
{}

static int felix_fdb_del(struct dsa_switch *ds, int port,
			 const unsigned char *addr, u16 vid,
			 struct dsa_db db)
{}

static int felix_lag_fdb_add(struct dsa_switch *ds, struct dsa_lag lag,
			     const unsigned char *addr, u16 vid,
			     struct dsa_db db)
{}

static int felix_lag_fdb_del(struct dsa_switch *ds, struct dsa_lag lag,
			     const unsigned char *addr, u16 vid,
			     struct dsa_db db)
{}

static int felix_mdb_add(struct dsa_switch *ds, int port,
			 const struct switchdev_obj_port_mdb *mdb,
			 struct dsa_db db)
{}

static int felix_mdb_del(struct dsa_switch *ds, int port,
			 const struct switchdev_obj_port_mdb *mdb,
			 struct dsa_db db)
{}

static void felix_bridge_stp_state_set(struct dsa_switch *ds, int port,
				       u8 state)
{}

static int felix_pre_bridge_flags(struct dsa_switch *ds, int port,
				  struct switchdev_brport_flags val,
				  struct netlink_ext_ack *extack)
{}

static int felix_bridge_flags(struct dsa_switch *ds, int port,
			      struct switchdev_brport_flags val,
			      struct netlink_ext_ack *extack)
{}

static int felix_bridge_join(struct dsa_switch *ds, int port,
			     struct dsa_bridge bridge, bool *tx_fwd_offload,
			     struct netlink_ext_ack *extack)
{}

static void felix_bridge_leave(struct dsa_switch *ds, int port,
			       struct dsa_bridge bridge)
{}

static int felix_lag_join(struct dsa_switch *ds, int port,
			  struct dsa_lag lag,
			  struct netdev_lag_upper_info *info,
			  struct netlink_ext_ack *extack)
{}

static int felix_lag_leave(struct dsa_switch *ds, int port,
			   struct dsa_lag lag)
{}

static int felix_lag_change(struct dsa_switch *ds, int port)
{}

static int felix_vlan_prepare(struct dsa_switch *ds, int port,
			      const struct switchdev_obj_port_vlan *vlan,
			      struct netlink_ext_ack *extack)
{}

static int felix_vlan_filtering(struct dsa_switch *ds, int port, bool enabled,
				struct netlink_ext_ack *extack)
{}

static int felix_vlan_add(struct dsa_switch *ds, int port,
			  const struct switchdev_obj_port_vlan *vlan,
			  struct netlink_ext_ack *extack)
{}

static int felix_vlan_del(struct dsa_switch *ds, int port,
			  const struct switchdev_obj_port_vlan *vlan)
{}

static void felix_phylink_get_caps(struct dsa_switch *ds, int port,
				   struct phylink_config *config)
{}

static void felix_phylink_mac_config(struct phylink_config *config,
				     unsigned int mode,
				     const struct phylink_link_state *state)
{}

static struct phylink_pcs *
felix_phylink_mac_select_pcs(struct phylink_config *config,
			     phy_interface_t iface)
{}

static void felix_phylink_mac_link_down(struct phylink_config *config,
					unsigned int link_an_mode,
					phy_interface_t interface)
{}

static void felix_phylink_mac_link_up(struct phylink_config *config,
				      struct phy_device *phydev,
				      unsigned int link_an_mode,
				      phy_interface_t interface,
				      int speed, int duplex,
				      bool tx_pause, bool rx_pause)
{}

static int felix_port_enable(struct dsa_switch *ds, int port,
			     struct phy_device *phydev)
{}

static void felix_port_qos_map_init(struct ocelot *ocelot, int port)
{}

static void felix_get_stats64(struct dsa_switch *ds, int port,
			      struct rtnl_link_stats64 *stats)
{}

static void felix_get_pause_stats(struct dsa_switch *ds, int port,
				  struct ethtool_pause_stats *pause_stats)
{}

static void felix_get_rmon_stats(struct dsa_switch *ds, int port,
				 struct ethtool_rmon_stats *rmon_stats,
				 const struct ethtool_rmon_hist_range **ranges)
{}

static void felix_get_eth_ctrl_stats(struct dsa_switch *ds, int port,
				     struct ethtool_eth_ctrl_stats *ctrl_stats)
{}

static void felix_get_eth_mac_stats(struct dsa_switch *ds, int port,
				    struct ethtool_eth_mac_stats *mac_stats)
{}

static void felix_get_eth_phy_stats(struct dsa_switch *ds, int port,
				    struct ethtool_eth_phy_stats *phy_stats)
{}

static void felix_get_strings(struct dsa_switch *ds, int port,
			      u32 stringset, u8 *data)
{}

static void felix_get_ethtool_stats(struct dsa_switch *ds, int port, u64 *data)
{}

static int felix_get_sset_count(struct dsa_switch *ds, int port, int sset)
{}

static int felix_get_ts_info(struct dsa_switch *ds, int port,
			     struct kernel_ethtool_ts_info *info)
{}

static const u32 felix_phy_match_table[PHY_INTERFACE_MODE_MAX] =;

static int felix_validate_phy_mode(struct felix *felix, int port,
				   phy_interface_t phy_mode)
{}

static int felix_parse_ports_node(struct felix *felix,
				  struct device_node *ports_node,
				  phy_interface_t *port_phy_modes)
{}

static int felix_parse_dt(struct felix *felix, phy_interface_t *port_phy_modes)
{}

static struct regmap *felix_request_regmap_by_name(struct felix *felix,
						   const char *resource_name)
{}

static struct regmap *felix_request_regmap(struct felix *felix,
					   enum ocelot_target target)
{}

static struct regmap *felix_request_port_regmap(struct felix *felix, int port)
{}

static int felix_init_structs(struct felix *felix, int num_phys_ports)
{}

static void ocelot_port_purge_txtstamp_skb(struct ocelot *ocelot, int port,
					   struct sk_buff *skb)
{}

#define work_to_xmit_work(w)

static void felix_port_deferred_xmit(struct kthread_work *work)
{}

static int felix_connect_tag_protocol(struct dsa_switch *ds,
				      enum dsa_tag_protocol proto)
{}

static int felix_setup(struct dsa_switch *ds)
{}

static void felix_teardown(struct dsa_switch *ds)
{}

static int felix_hwtstamp_get(struct dsa_switch *ds, int port,
			      struct ifreq *ifr)
{}

static int felix_hwtstamp_set(struct dsa_switch *ds, int port,
			      struct ifreq *ifr)
{}

static bool felix_check_xtr_pkt(struct ocelot *ocelot)
{}

static bool felix_rxtstamp(struct dsa_switch *ds, int port,
			   struct sk_buff *skb, unsigned int type)
{}

static void felix_txtstamp(struct dsa_switch *ds, int port,
			   struct sk_buff *skb)
{}

static int felix_change_mtu(struct dsa_switch *ds, int port, int new_mtu)
{}

static int felix_get_max_mtu(struct dsa_switch *ds, int port)
{}

static int felix_cls_flower_add(struct dsa_switch *ds, int port,
				struct flow_cls_offload *cls, bool ingress)
{}

static int felix_cls_flower_del(struct dsa_switch *ds, int port,
				struct flow_cls_offload *cls, bool ingress)
{}

static int felix_cls_flower_stats(struct dsa_switch *ds, int port,
				  struct flow_cls_offload *cls, bool ingress)
{}

static int felix_port_policer_add(struct dsa_switch *ds, int port,
				  struct dsa_mall_policer_tc_entry *policer)
{}

static void felix_port_policer_del(struct dsa_switch *ds, int port)
{}

static int felix_port_mirror_add(struct dsa_switch *ds, int port,
				 struct dsa_mall_mirror_tc_entry *mirror,
				 bool ingress, struct netlink_ext_ack *extack)
{}

static void felix_port_mirror_del(struct dsa_switch *ds, int port,
				  struct dsa_mall_mirror_tc_entry *mirror)
{}

static int felix_port_setup_tc(struct dsa_switch *ds, int port,
			       enum tc_setup_type type,
			       void *type_data)
{}

static int felix_sb_pool_get(struct dsa_switch *ds, unsigned int sb_index,
			     u16 pool_index,
			     struct devlink_sb_pool_info *pool_info)
{}

static int felix_sb_pool_set(struct dsa_switch *ds, unsigned int sb_index,
			     u16 pool_index, u32 size,
			     enum devlink_sb_threshold_type threshold_type,
			     struct netlink_ext_ack *extack)
{}

static int felix_sb_port_pool_get(struct dsa_switch *ds, int port,
				  unsigned int sb_index, u16 pool_index,
				  u32 *p_threshold)
{}

static int felix_sb_port_pool_set(struct dsa_switch *ds, int port,
				  unsigned int sb_index, u16 pool_index,
				  u32 threshold, struct netlink_ext_ack *extack)
{}

static int felix_sb_tc_pool_bind_get(struct dsa_switch *ds, int port,
				     unsigned int sb_index, u16 tc_index,
				     enum devlink_sb_pool_type pool_type,
				     u16 *p_pool_index, u32 *p_threshold)
{}

static int felix_sb_tc_pool_bind_set(struct dsa_switch *ds, int port,
				     unsigned int sb_index, u16 tc_index,
				     enum devlink_sb_pool_type pool_type,
				     u16 pool_index, u32 threshold,
				     struct netlink_ext_ack *extack)
{}

static int felix_sb_occ_snapshot(struct dsa_switch *ds,
				 unsigned int sb_index)
{}

static int felix_sb_occ_max_clear(struct dsa_switch *ds,
				  unsigned int sb_index)
{}

static int felix_sb_occ_port_pool_get(struct dsa_switch *ds, int port,
				      unsigned int sb_index, u16 pool_index,
				      u32 *p_cur, u32 *p_max)
{}

static int felix_sb_occ_tc_port_bind_get(struct dsa_switch *ds, int port,
					 unsigned int sb_index, u16 tc_index,
					 enum devlink_sb_pool_type pool_type,
					 u32 *p_cur, u32 *p_max)
{}

static int felix_mrp_add(struct dsa_switch *ds, int port,
			 const struct switchdev_obj_mrp *mrp)
{}

static int felix_mrp_del(struct dsa_switch *ds, int port,
			 const struct switchdev_obj_mrp *mrp)
{}

static int
felix_mrp_add_ring_role(struct dsa_switch *ds, int port,
			const struct switchdev_obj_ring_role_mrp *mrp)
{}

static int
felix_mrp_del_ring_role(struct dsa_switch *ds, int port,
			const struct switchdev_obj_ring_role_mrp *mrp)
{}

static int felix_port_get_default_prio(struct dsa_switch *ds, int port)
{}

static int felix_port_set_default_prio(struct dsa_switch *ds, int port,
				       u8 prio)
{}

static int felix_port_get_dscp_prio(struct dsa_switch *ds, int port, u8 dscp)
{}

static int felix_port_add_dscp_prio(struct dsa_switch *ds, int port, u8 dscp,
				    u8 prio)
{}

static int felix_port_del_dscp_prio(struct dsa_switch *ds, int port, u8 dscp,
				    u8 prio)
{}

static int felix_get_mm(struct dsa_switch *ds, int port,
			struct ethtool_mm_state *state)
{}

static int felix_set_mm(struct dsa_switch *ds, int port,
			struct ethtool_mm_cfg *cfg,
			struct netlink_ext_ack *extack)
{}

static void felix_get_mm_stats(struct dsa_switch *ds, int port,
			       struct ethtool_mm_stats *stats)
{}

static const struct phylink_mac_ops felix_phylink_mac_ops =;

static const struct dsa_switch_ops felix_switch_ops =;

int felix_register_switch(struct device *dev, resource_size_t switch_base,
			  int num_flooding_pgids, bool ptp,
			  bool mm_supported,
			  enum dsa_tag_protocol init_tag_proto,
			  const struct felix_info *info)
{}
EXPORT_SYMBOL_GPL();

struct net_device *felix_port_to_netdev(struct ocelot *ocelot, int port)
{}
EXPORT_SYMBOL_GPL();

int felix_netdev_to_port(struct net_device *dev)
{}
EXPORT_SYMBOL_GPL();

MODULE_DESCRIPTION();
MODULE_LICENSE();