linux/drivers/net/ethernet/mscc/ocelot.c

// SPDX-License-Identifier: (GPL-2.0 OR MIT)
/*
 * Microsemi Ocelot Switch driver
 *
 * Copyright (c) 2017 Microsemi Corporation
 */
#include <linux/dsa/ocelot.h>
#include <linux/if_bridge.h>
#include <linux/iopoll.h>
#include <linux/phy/phy.h>
#include <net/pkt_sched.h>
#include <soc/mscc/ocelot_hsio.h>
#include <soc/mscc/ocelot_vcap.h>
#include "ocelot.h"
#include "ocelot_vcap.h"

#define TABLE_UPDATE_SLEEP_US
#define TABLE_UPDATE_TIMEOUT_US
#define MEM_INIT_SLEEP_US
#define MEM_INIT_TIMEOUT_US

#define OCELOT_RSV_VLAN_RANGE_START

struct ocelot_mact_entry {};

/* Caller must hold &ocelot->mact_lock */
static inline u32 ocelot_mact_read_macaccess(struct ocelot *ocelot)
{}

/* Caller must hold &ocelot->mact_lock */
static inline int ocelot_mact_wait_for_completion(struct ocelot *ocelot)
{}

/* Caller must hold &ocelot->mact_lock */
static void ocelot_mact_select(struct ocelot *ocelot,
			       const unsigned char mac[ETH_ALEN],
			       unsigned int vid)
{}

static int __ocelot_mact_learn(struct ocelot *ocelot, int port,
			       const unsigned char mac[ETH_ALEN],
			       unsigned int vid, enum macaccess_entry_type type)
{}

int ocelot_mact_learn(struct ocelot *ocelot, int port,
		      const unsigned char mac[ETH_ALEN],
		      unsigned int vid, enum macaccess_entry_type type)
{}
EXPORT_SYMBOL();

int ocelot_mact_forget(struct ocelot *ocelot,
		       const unsigned char mac[ETH_ALEN], unsigned int vid)
{}
EXPORT_SYMBOL();

int ocelot_mact_lookup(struct ocelot *ocelot, int *dst_idx,
		       const unsigned char mac[ETH_ALEN],
		       unsigned int vid, enum macaccess_entry_type *type)
{}
EXPORT_SYMBOL();

int ocelot_mact_learn_streamdata(struct ocelot *ocelot, int dst_idx,
				 const unsigned char mac[ETH_ALEN],
				 unsigned int vid,
				 enum macaccess_entry_type type,
				 int sfid, int ssid)
{}
EXPORT_SYMBOL();

static void ocelot_mact_init(struct ocelot *ocelot)
{}

void ocelot_pll5_init(struct ocelot *ocelot)
{}
EXPORT_SYMBOL();

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

static int ocelot_single_vlan_aware_bridge(struct ocelot *ocelot,
					   struct netlink_ext_ack *extack)
{}

static inline u32 ocelot_vlant_read_vlanaccess(struct ocelot *ocelot)
{}

static inline int ocelot_vlant_wait_for_completion(struct ocelot *ocelot)
{}

static int ocelot_vlant_set_mask(struct ocelot *ocelot, u16 vid, u32 mask)
{}

static int ocelot_port_num_untagged_vlans(struct ocelot *ocelot, int port)
{}

static int ocelot_port_num_tagged_vlans(struct ocelot *ocelot, int port)
{}

/* We use native VLAN when we have to mix egress-tagged VLANs with exactly
 * _one_ egress-untagged VLAN (_the_ native VLAN)
 */
static bool ocelot_port_uses_native_vlan(struct ocelot *ocelot, int port)
{}

static struct ocelot_bridge_vlan *
ocelot_port_find_native_vlan(struct ocelot *ocelot, int port)
{}

/* Keep in sync REW_TAG_CFG_TAG_CFG and, if applicable,
 * REW_PORT_VLAN_CFG_PORT_VID, with the bridge VLAN table and VLAN awareness
 * state of the port.
 */
static void ocelot_port_manage_port_tag(struct ocelot *ocelot, int port)
{}

int ocelot_bridge_num_find(struct ocelot *ocelot,
			   const struct net_device *bridge)
{}
EXPORT_SYMBOL_GPL();

static u16 ocelot_vlan_unaware_pvid(struct ocelot *ocelot,
				    const struct net_device *bridge)
{}

/* Default vlan to clasify for untagged frames (may be zero) */
static void ocelot_port_set_pvid(struct ocelot *ocelot, int port,
				 const struct ocelot_bridge_vlan *pvid_vlan)
{}

static struct ocelot_bridge_vlan *ocelot_bridge_vlan_find(struct ocelot *ocelot,
							  u16 vid)
{}

static int ocelot_vlan_member_add(struct ocelot *ocelot, int port, u16 vid,
				  bool untagged)
{}

static int ocelot_vlan_member_del(struct ocelot *ocelot, int port, u16 vid)
{}

static int ocelot_add_vlan_unaware_pvid(struct ocelot *ocelot, int port,
					const struct net_device *bridge)
{}

static int ocelot_del_vlan_unaware_pvid(struct ocelot *ocelot, int port,
					const struct net_device *bridge)
{}

int ocelot_port_vlan_filtering(struct ocelot *ocelot, int port,
			       bool vlan_aware, struct netlink_ext_ack *extack)
{}
EXPORT_SYMBOL();

int ocelot_vlan_prepare(struct ocelot *ocelot, int port, u16 vid, bool pvid,
			bool untagged, struct netlink_ext_ack *extack)
{}
EXPORT_SYMBOL();

int ocelot_vlan_add(struct ocelot *ocelot, int port, u16 vid, bool pvid,
		    bool untagged)
{}
EXPORT_SYMBOL();

int ocelot_vlan_del(struct ocelot *ocelot, int port, u16 vid)
{}
EXPORT_SYMBOL();

static void ocelot_vlan_init(struct ocelot *ocelot)
{}

static u32 ocelot_read_eq_avail(struct ocelot *ocelot, int port)
{}

static int ocelot_port_flush(struct ocelot *ocelot, int port)
{}

int ocelot_port_configure_serdes(struct ocelot *ocelot, int port,
				 struct device_node *portnp)
{}
EXPORT_SYMBOL_GPL();

void ocelot_phylink_mac_config(struct ocelot *ocelot, int port,
			       unsigned int link_an_mode,
			       const struct phylink_link_state *state)
{}
EXPORT_SYMBOL_GPL();

void ocelot_phylink_mac_link_down(struct ocelot *ocelot, int port,
				  unsigned int link_an_mode,
				  phy_interface_t interface,
				  unsigned long quirks)
{}
EXPORT_SYMBOL_GPL();

void ocelot_phylink_mac_link_up(struct ocelot *ocelot, int port,
				struct phy_device *phydev,
				unsigned int link_an_mode,
				phy_interface_t interface,
				int speed, int duplex,
				bool tx_pause, bool rx_pause,
				unsigned long quirks)
{}
EXPORT_SYMBOL_GPL();

static int ocelot_rx_frame_word(struct ocelot *ocelot, u8 grp, bool ifh,
				u32 *rval)
{}

static int ocelot_xtr_poll_xfh(struct ocelot *ocelot, int grp, u32 *xfh)
{}

void ocelot_ptp_rx_timestamp(struct ocelot *ocelot, struct sk_buff *skb,
			     u64 timestamp)
{}
EXPORT_SYMBOL();

int ocelot_xtr_poll_frame(struct ocelot *ocelot, int grp, struct sk_buff **nskb)
{}
EXPORT_SYMBOL();

bool ocelot_can_inject(struct ocelot *ocelot, int grp)
{}
EXPORT_SYMBOL();

void ocelot_ifh_port_set(void *ifh, int port, u32 rew_op, u32 vlan_tag)
{}
EXPORT_SYMBOL();

void ocelot_port_inject_frame(struct ocelot *ocelot, int port, int grp,
			      u32 rew_op, struct sk_buff *skb)
{}
EXPORT_SYMBOL();

void ocelot_drain_cpu_queue(struct ocelot *ocelot, int grp)
{}
EXPORT_SYMBOL();

int ocelot_fdb_add(struct ocelot *ocelot, int port, const unsigned char *addr,
		   u16 vid, const struct net_device *bridge)
{}
EXPORT_SYMBOL();

int ocelot_fdb_del(struct ocelot *ocelot, int port, const unsigned char *addr,
		   u16 vid, const struct net_device *bridge)
{}
EXPORT_SYMBOL();

/* Caller must hold &ocelot->mact_lock */
static int ocelot_mact_read(struct ocelot *ocelot, int port, int row, int col,
			    struct ocelot_mact_entry *entry)
{}

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

int ocelot_fdb_dump(struct ocelot *ocelot, int port,
		    dsa_fdb_dump_cb_t *cb, void *data)
{}
EXPORT_SYMBOL();

int ocelot_trap_add(struct ocelot *ocelot, int port,
		    unsigned long cookie, bool take_ts,
		    void (*populate)(struct ocelot_vcap_filter *f))
{}

int ocelot_trap_del(struct ocelot *ocelot, int port, unsigned long cookie)
{}

static u32 ocelot_get_bond_mask(struct ocelot *ocelot, struct net_device *bond)
{}

/* The logical port number of a LAG is equal to the lowest numbered physical
 * port ID present in that LAG. It may change if that port ever leaves the LAG.
 */
int ocelot_bond_get_id(struct ocelot *ocelot, struct net_device *bond)
{}
EXPORT_SYMBOL_GPL();

/* Returns the mask of user ports assigned to this DSA tag_8021q CPU port.
 * Note that when CPU ports are in a LAG, the user ports are assigned to the
 * 'primary' CPU port, the one whose physical port number gives the logical
 * port number of the LAG.
 *
 * We leave PGID_SRC poorly configured for the 'secondary' CPU port in the LAG
 * (to which no user port is assigned), but it appears that forwarding from
 * this secondary CPU port looks at the PGID_SRC associated with the logical
 * port ID that it's assigned to, which *is* configured properly.
 */
static u32 ocelot_dsa_8021q_cpu_assigned_ports(struct ocelot *ocelot,
					       struct ocelot_port *cpu)
{}

/* Returns the DSA tag_8021q CPU port that the given port is assigned to,
 * or the bit mask of CPU ports if said CPU port is in a LAG.
 */
u32 ocelot_port_assigned_dsa_8021q_cpu_mask(struct ocelot *ocelot, int port)
{}
EXPORT_SYMBOL_GPL();

u32 ocelot_get_bridge_fwd_mask(struct ocelot *ocelot, int src_port)
{}
EXPORT_SYMBOL_GPL();

static void ocelot_apply_bridge_fwd_mask(struct ocelot *ocelot, bool joining)
{}

/* Update PGID_CPU which is the destination port mask used for whitelisting
 * unicast addresses filtered towards the host. In the normal and NPI modes,
 * this points to the analyzer entry for the CPU port module, while in DSA
 * tag_8021q mode, it is a bit mask of all active CPU ports.
 * PGID_SRC will take care of forwarding a packet from one user port to
 * no more than a single CPU port.
 */
static void ocelot_update_pgid_cpu(struct ocelot *ocelot)
{}

void ocelot_port_setup_dsa_8021q_cpu(struct ocelot *ocelot, int cpu)
{}
EXPORT_SYMBOL_GPL();

void ocelot_port_teardown_dsa_8021q_cpu(struct ocelot *ocelot, int cpu)
{}
EXPORT_SYMBOL_GPL();

void ocelot_port_assign_dsa_8021q_cpu(struct ocelot *ocelot, int port,
				      int cpu)
{}
EXPORT_SYMBOL_GPL();

void ocelot_port_unassign_dsa_8021q_cpu(struct ocelot *ocelot, int port)
{}
EXPORT_SYMBOL_GPL();

void ocelot_bridge_stp_state_set(struct ocelot *ocelot, int port, u8 state)
{}
EXPORT_SYMBOL();

void ocelot_set_ageing_time(struct ocelot *ocelot, unsigned int msecs)
{}
EXPORT_SYMBOL();

static struct ocelot_multicast *ocelot_multicast_get(struct ocelot *ocelot,
						     const unsigned char *addr,
						     u16 vid)
{}

static enum macaccess_entry_type ocelot_classify_mdb(const unsigned char *addr)
{}

static struct ocelot_pgid *ocelot_pgid_alloc(struct ocelot *ocelot, int index,
					     unsigned long ports)
{}

static void ocelot_pgid_free(struct ocelot *ocelot, struct ocelot_pgid *pgid)
{}

static struct ocelot_pgid *ocelot_mdb_get_pgid(struct ocelot *ocelot,
					       const struct ocelot_multicast *mc)
{}

static void ocelot_encode_ports_to_mdb(unsigned char *addr,
				       struct ocelot_multicast *mc)
{}

int ocelot_port_mdb_add(struct ocelot *ocelot, int port,
			const struct switchdev_obj_port_mdb *mdb,
			const struct net_device *bridge)
{}
EXPORT_SYMBOL();

int ocelot_port_mdb_del(struct ocelot *ocelot, int port,
			const struct switchdev_obj_port_mdb *mdb,
			const struct net_device *bridge)
{}
EXPORT_SYMBOL();

int ocelot_port_bridge_join(struct ocelot *ocelot, int port,
			    struct net_device *bridge, int bridge_num,
			    struct netlink_ext_ack *extack)
{}
EXPORT_SYMBOL();

void ocelot_port_bridge_leave(struct ocelot *ocelot, int port,
			      struct net_device *bridge)
{}
EXPORT_SYMBOL();

static void ocelot_set_aggr_pgids(struct ocelot *ocelot)
{}

/* When offloading a bonding interface, the switch ports configured under the
 * same bond must have the same logical port ID, equal to the physical port ID
 * of the lowest numbered physical port in that bond. Otherwise, in standalone/
 * bridged mode, each port has a logical port ID equal to its physical port ID.
 */
static void ocelot_setup_logical_port_ids(struct ocelot *ocelot)
{}

static int ocelot_migrate_mc(struct ocelot *ocelot, struct ocelot_multicast *mc,
			     unsigned long from_mask, unsigned long to_mask)
{}

int ocelot_migrate_mdbs(struct ocelot *ocelot, unsigned long from_mask,
			unsigned long to_mask)
{}
EXPORT_SYMBOL_GPL();

/* Documentation for PORTID_VAL says:
 *     Logical port number for front port. If port is not a member of a LLAG,
 *     then PORTID must be set to the physical port number.
 *     If port is a member of a LLAG, then PORTID must be set to the common
 *     PORTID_VAL used for all member ports of the LLAG.
 *     The value must not exceed the number of physical ports on the device.
 *
 * This means we have little choice but to migrate FDB entries pointing towards
 * a logical port when that changes.
 */
static void ocelot_migrate_lag_fdbs(struct ocelot *ocelot,
				    struct net_device *bond,
				    int lag)
{}

int ocelot_port_lag_join(struct ocelot *ocelot, int port,
			 struct net_device *bond,
			 struct netdev_lag_upper_info *info,
			 struct netlink_ext_ack *extack)
{}
EXPORT_SYMBOL();

void ocelot_port_lag_leave(struct ocelot *ocelot, int port,
			   struct net_device *bond)
{}
EXPORT_SYMBOL();

void ocelot_port_lag_change(struct ocelot *ocelot, int port, bool lag_tx_active)
{}
EXPORT_SYMBOL();

int ocelot_lag_fdb_add(struct ocelot *ocelot, struct net_device *bond,
		       const unsigned char *addr, u16 vid,
		       const struct net_device *bridge)
{}
EXPORT_SYMBOL_GPL();

int ocelot_lag_fdb_del(struct ocelot *ocelot, struct net_device *bond,
		       const unsigned char *addr, u16 vid,
		       const struct net_device *bridge)
{}
EXPORT_SYMBOL_GPL();

/* Configure the maximum SDU (L2 payload) on RX to the value specified in @sdu.
 * The length of VLAN tags is accounted for automatically via DEV_MAC_TAGS_CFG.
 * In the special case that it's the NPI port that we're configuring, the
 * length of the tag and optional prefix needs to be accounted for privately,
 * in order to be able to sustain communication at the requested @sdu.
 */
void ocelot_port_set_maxlen(struct ocelot *ocelot, int port, size_t sdu)
{}
EXPORT_SYMBOL();

int ocelot_get_max_mtu(struct ocelot *ocelot, int port)
{}
EXPORT_SYMBOL();

static void ocelot_port_set_learning(struct ocelot *ocelot, int port,
				     bool enabled)
{}

static void ocelot_port_set_ucast_flood(struct ocelot *ocelot, int port,
					bool enabled)
{}

static void ocelot_port_set_mcast_flood(struct ocelot *ocelot, int port,
					bool enabled)
{}

static void ocelot_port_set_bcast_flood(struct ocelot *ocelot, int port,
					bool enabled)
{}

int ocelot_port_pre_bridge_flags(struct ocelot *ocelot, int port,
				 struct switchdev_brport_flags flags)
{}
EXPORT_SYMBOL();

void ocelot_port_bridge_flags(struct ocelot *ocelot, int port,
			      struct switchdev_brport_flags flags)
{}
EXPORT_SYMBOL();

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

int ocelot_port_set_default_prio(struct ocelot *ocelot, int port, u8 prio)
{}
EXPORT_SYMBOL_GPL();

int ocelot_port_get_dscp_prio(struct ocelot *ocelot, int port, u8 dscp)
{}
EXPORT_SYMBOL_GPL();

int ocelot_port_add_dscp_prio(struct ocelot *ocelot, int port, u8 dscp, u8 prio)
{}
EXPORT_SYMBOL_GPL();

int ocelot_port_del_dscp_prio(struct ocelot *ocelot, int port, u8 dscp, u8 prio)
{}
EXPORT_SYMBOL_GPL();

struct ocelot_mirror *ocelot_mirror_get(struct ocelot *ocelot, int to,
					struct netlink_ext_ack *extack)
{}

void ocelot_mirror_put(struct ocelot *ocelot)
{}

int ocelot_port_mirror_add(struct ocelot *ocelot, int from, int to,
			   bool ingress, struct netlink_ext_ack *extack)
{}
EXPORT_SYMBOL_GPL();

void ocelot_port_mirror_del(struct ocelot *ocelot, int from, bool ingress)
{}
EXPORT_SYMBOL_GPL();

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

int ocelot_port_mqprio(struct ocelot *ocelot, int port,
		       struct tc_mqprio_qopt_offload *mqprio)
{}
EXPORT_SYMBOL_GPL();

void ocelot_init_port(struct ocelot *ocelot, int port)
{}
EXPORT_SYMBOL();

/* Configure and enable the CPU port module, which is a set of queues
 * accessible through register MMIO, frame DMA or Ethernet (in case
 * NPI mode is used).
 */
static void ocelot_cpu_port_init(struct ocelot *ocelot)
{}

static void ocelot_detect_features(struct ocelot *ocelot)
{}

static int ocelot_mem_init_status(struct ocelot *ocelot)
{}

int ocelot_reset(struct ocelot *ocelot)
{}
EXPORT_SYMBOL();

int ocelot_init(struct ocelot *ocelot)
{}
EXPORT_SYMBOL();

void ocelot_deinit(struct ocelot *ocelot)
{}
EXPORT_SYMBOL();

void ocelot_deinit_port(struct ocelot *ocelot, int port)
{}
EXPORT_SYMBOL();

MODULE_DESCRIPTION();
MODULE_LICENSE();