Linux Audio

Check our new training course

Loading...
Note: File does not exist in v3.15.
  1/* SPDX-License-Identifier: GPL-2.0-or-later */
  2/*
  3 * Broadcom Starfighter2 private context
  4 *
  5 * Copyright (C) 2014, Broadcom Corporation
  6 */
  7
  8#ifndef __BCM_SF2_H
  9#define __BCM_SF2_H
 10
 11#include <linux/platform_device.h>
 12#include <linux/kernel.h>
 13#include <linux/io.h>
 14#include <linux/spinlock.h>
 15#include <linux/mutex.h>
 16#include <linux/mii.h>
 17#include <linux/ethtool.h>
 18#include <linux/types.h>
 19#include <linux/bitops.h>
 20#include <linux/if_vlan.h>
 21
 22#include <net/dsa.h>
 23
 24#include "bcm_sf2_regs.h"
 25#include "b53/b53_priv.h"
 26
 27struct bcm_sf2_hw_params {
 28	u16	top_rev;
 29	u16	core_rev;
 30	u16	gphy_rev;
 31	u32	num_gphy;
 32	u8	num_acb_queue;
 33	u8	num_rgmii;
 34	u8	num_ports;
 35	u8	fcb_pause_override:1;
 36	u8	acb_packets_inflight:1;
 37};
 38
 39#define BCM_SF2_REGS_NAME {\
 40	"core", "reg", "intrl2_0", "intrl2_1", "fcb", "acb" \
 41}
 42
 43#define BCM_SF2_REGS_NUM	6
 44
 45struct bcm_sf2_port_status {
 46	unsigned int link;
 47};
 48
 49struct bcm_sf2_cfp_priv {
 50	/* Mutex protecting concurrent accesses to the CFP registers */
 51	struct mutex lock;
 52	DECLARE_BITMAP(used, CFP_NUM_RULES);
 53	DECLARE_BITMAP(unique, CFP_NUM_RULES);
 54	unsigned int rules_cnt;
 55	struct list_head rules_list;
 56};
 57
 58struct bcm_sf2_priv {
 59	/* Base registers, keep those in order with BCM_SF2_REGS_NAME */
 60	void __iomem			*core;
 61	void __iomem			*reg;
 62	void __iomem			*intrl2_0;
 63	void __iomem			*intrl2_1;
 64	void __iomem			*fcb;
 65	void __iomem			*acb;
 66
 67	/* Register offsets indirection tables */
 68	u32 				type;
 69	const u16			*reg_offsets;
 70	unsigned int			core_reg_align;
 71	unsigned int			num_cfp_rules;
 72
 73	/* spinlock protecting access to the indirect registers */
 74	spinlock_t			indir_lock;
 75
 76	int				irq0;
 77	int				irq1;
 78	u32				irq0_stat;
 79	u32				irq0_mask;
 80	u32				irq1_stat;
 81	u32				irq1_mask;
 82
 83	/* Backing b53_device */
 84	struct b53_device		*dev;
 85
 86	struct bcm_sf2_hw_params	hw_params;
 87
 88	struct bcm_sf2_port_status	port_sts[DSA_MAX_PORTS];
 89
 90	/* Mask of ports enabled for Wake-on-LAN */
 91	u32				wol_ports_mask;
 92
 93	/* MoCA port location */
 94	int				moca_port;
 95
 96	/* Bitmask of ports having an integrated PHY */
 97	unsigned int			int_phy_mask;
 98
 99	/* Master and slave MDIO bus controller */
100	unsigned int			indir_phy_mask;
101	struct device_node		*master_mii_dn;
102	struct mii_bus			*slave_mii_bus;
103	struct mii_bus			*master_mii_bus;
104
105	/* Bitmask of ports needing BRCM tags */
106	unsigned int			brcm_tag_mask;
107
108	/* CFP rules context */
109	struct bcm_sf2_cfp_priv		cfp;
110};
111
112static inline struct bcm_sf2_priv *bcm_sf2_to_priv(struct dsa_switch *ds)
113{
114	struct b53_device *dev = ds->priv;
115
116	return dev->priv;
117}
118
119static inline u32 bcm_sf2_mangle_addr(struct bcm_sf2_priv *priv, u32 off)
120{
121	return off << priv->core_reg_align;
122}
123
124#define SF2_IO_MACRO(name) \
125static inline u32 name##_readl(struct bcm_sf2_priv *priv, u32 off)	\
126{									\
127	return readl_relaxed(priv->name + off);				\
128}									\
129static inline void name##_writel(struct bcm_sf2_priv *priv,		\
130				  u32 val, u32 off)			\
131{									\
132	writel_relaxed(val, priv->name + off);				\
133}									\
134
135/* Accesses to 64-bits register requires us to latch the hi/lo pairs
136 * using the REG_DIR_DATA_{READ,WRITE} ancillary registers. The 'indir_lock'
137 * spinlock is automatically grabbed and released to provide relative
138 * atomiticy with latched reads/writes.
139 */
140#define SF2_IO64_MACRO(name) \
141static inline u64 name##_readq(struct bcm_sf2_priv *priv, u32 off)	\
142{									\
143	u32 indir, dir;							\
144	spin_lock(&priv->indir_lock);					\
145	dir = name##_readl(priv, off);					\
146	indir = reg_readl(priv, REG_DIR_DATA_READ);			\
147	spin_unlock(&priv->indir_lock);					\
148	return (u64)indir << 32 | dir;					\
149}									\
150static inline void name##_writeq(struct bcm_sf2_priv *priv, u64 val,	\
151							u32 off)	\
152{									\
153	spin_lock(&priv->indir_lock);					\
154	reg_writel(priv, upper_32_bits(val), REG_DIR_DATA_WRITE);	\
155	name##_writel(priv, lower_32_bits(val), off);			\
156	spin_unlock(&priv->indir_lock);					\
157}
158
159#define SWITCH_INTR_L2(which)						\
160static inline void intrl2_##which##_mask_clear(struct bcm_sf2_priv *priv, \
161						u32 mask)		\
162{									\
163	priv->irq##which##_mask &= ~(mask);				\
164	intrl2_##which##_writel(priv, mask, INTRL2_CPU_MASK_CLEAR);	\
165}									\
166static inline void intrl2_##which##_mask_set(struct bcm_sf2_priv *priv, \
167						u32 mask)		\
168{									\
169	intrl2_## which##_writel(priv, mask, INTRL2_CPU_MASK_SET);	\
170	priv->irq##which##_mask |= (mask);				\
171}									\
172
173static inline u32 core_readl(struct bcm_sf2_priv *priv, u32 off)
174{
175	u32 tmp = bcm_sf2_mangle_addr(priv, off);
176	return readl_relaxed(priv->core + tmp);
177}
178
179static inline void core_writel(struct bcm_sf2_priv *priv, u32 val, u32 off)
180{
181	u32 tmp = bcm_sf2_mangle_addr(priv, off);
182	writel_relaxed(val, priv->core + tmp);
183}
184
185static inline u32 reg_readl(struct bcm_sf2_priv *priv, u16 off)
186{
187	return readl_relaxed(priv->reg + priv->reg_offsets[off]);
188}
189
190static inline void reg_writel(struct bcm_sf2_priv *priv, u32 val, u16 off)
191{
192	writel_relaxed(val, priv->reg + priv->reg_offsets[off]);
193}
194
195SF2_IO64_MACRO(core);
196SF2_IO_MACRO(intrl2_0);
197SF2_IO_MACRO(intrl2_1);
198SF2_IO_MACRO(fcb);
199SF2_IO_MACRO(acb);
200
201SWITCH_INTR_L2(0);
202SWITCH_INTR_L2(1);
203
204/* RXNFC */
205int bcm_sf2_get_rxnfc(struct dsa_switch *ds, int port,
206		      struct ethtool_rxnfc *nfc, u32 *rule_locs);
207int bcm_sf2_set_rxnfc(struct dsa_switch *ds, int port,
208		      struct ethtool_rxnfc *nfc);
209int bcm_sf2_cfp_rst(struct bcm_sf2_priv *priv);
210void bcm_sf2_cfp_exit(struct dsa_switch *ds);
211int bcm_sf2_cfp_resume(struct dsa_switch *ds);
212void bcm_sf2_cfp_get_strings(struct dsa_switch *ds, int port,
213			     u32 stringset, uint8_t *data);
214void bcm_sf2_cfp_get_ethtool_stats(struct dsa_switch *ds, int port,
215				   uint64_t *data);
216int bcm_sf2_cfp_get_sset_count(struct dsa_switch *ds, int port, int sset);
217
218#endif /* __BCM_SF2_H */