1 /* SPDX-License-Identifier: GPL-2.0 */
2 /* Copyright (c) 2018, Sensor-Technik Wiedemann GmbH
3 * Copyright (c) 2018-2019, Vladimir Oltean <olteanv@gmail.com>
8 #include <linux/ptp_clock_kernel.h>
9 #include <linux/timecounter.h>
10 #include <linux/dsa/sja1105.h>
12 #include <linux/mutex.h>
13 #include "sja1105_static_config.h"
15 #define SJA1105_NUM_PORTS 5
16 #define SJA1105_NUM_TC 8
17 #define SJA1105ET_FDB_BIN_SIZE 4
18 /* The hardware value is in multiples of 10 ms.
19 * The passed parameter is in multiples of 1 ms.
21 #define SJA1105_AGEING_TIME_MS(ms) ((ms) / 10)
23 #include "sja1105_tas.h"
25 /* Keeps the different addresses between E/T and P/Q/R/S */
38 u64 ptpegr_ts
[SJA1105_NUM_PORTS
];
39 u64 pad_mii_tx
[SJA1105_NUM_PORTS
];
40 u64 pad_mii_id
[SJA1105_NUM_PORTS
];
41 u64 cgu_idiv
[SJA1105_NUM_PORTS
];
42 u64 mii_tx_clk
[SJA1105_NUM_PORTS
];
43 u64 mii_rx_clk
[SJA1105_NUM_PORTS
];
44 u64 mii_ext_tx_clk
[SJA1105_NUM_PORTS
];
45 u64 mii_ext_rx_clk
[SJA1105_NUM_PORTS
];
46 u64 rgmii_tx_clk
[SJA1105_NUM_PORTS
];
47 u64 rmii_ref_clk
[SJA1105_NUM_PORTS
];
48 u64 rmii_ext_tx_clk
[SJA1105_NUM_PORTS
];
49 u64 mac
[SJA1105_NUM_PORTS
];
50 u64 mac_hl1
[SJA1105_NUM_PORTS
];
51 u64 mac_hl2
[SJA1105_NUM_PORTS
];
52 u64 qlevel
[SJA1105_NUM_PORTS
];
57 /* Needed for distinction between P and R, and between Q and S
58 * (since the parts with/without SGMII share the same
59 * switch core and device_id)
62 /* E/T and P/Q/R/S have partial timestamps of different sizes.
63 * They must be reconstructed on both families anyway to get the full
67 /* Also SPI commands are of different sizes to retrieve
68 * the egress timestamps.
71 const struct sja1105_dynamic_table_ops
*dyn_ops
;
72 const struct sja1105_table_ops
*static_ops
;
73 const struct sja1105_regs
*regs
;
74 int (*ptp_cmd
)(const void *ctx
, const void *data
);
75 int (*reset_cmd
)(const void *ctx
, const void *data
);
76 int (*setup_rgmii_delay
)(const void *ctx
, int port
);
77 /* Prototypes from include/net/dsa.h */
78 int (*fdb_add_cmd
)(struct dsa_switch
*ds
, int port
,
79 const unsigned char *addr
, u16 vid
);
80 int (*fdb_del_cmd
)(struct dsa_switch
*ds
, int port
,
81 const unsigned char *addr
, u16 vid
);
85 struct sja1105_private
{
86 struct sja1105_static_config static_config
;
87 bool rgmii_rx_delay
[SJA1105_NUM_PORTS
];
88 bool rgmii_tx_delay
[SJA1105_NUM_PORTS
];
89 const struct sja1105_info
*info
;
90 struct gpio_desc
*reset_gpio
;
91 struct spi_device
*spidev
;
92 struct dsa_switch
*ds
;
93 struct sja1105_port ports
[SJA1105_NUM_PORTS
];
94 struct ptp_clock_info ptp_caps
;
95 struct ptp_clock
*clock
;
96 /* The cycle counter translates the PTP timestamps (based on
97 * a free-running counter) into a software time domain.
99 struct cyclecounter tstamp_cc
;
100 struct timecounter tstamp_tc
;
101 struct delayed_work refresh_work
;
102 /* Serializes all operations on the cycle counter */
103 struct mutex ptp_lock
;
104 /* Serializes transmission of management frames so that
105 * the switch doesn't confuse them with one another.
107 struct mutex mgmt_lock
;
108 struct sja1105_tagger_data tagger_data
;
109 struct sja1105_tas_data tas_data
;
112 #include "sja1105_dynamic_config.h"
113 #include "sja1105_ptp.h"
115 struct sja1105_spi_message
{
124 } sja1105_spi_rw_mode_t
;
126 /* From sja1105_main.c */
127 int sja1105_static_config_reload(struct sja1105_private
*priv
);
129 /* From sja1105_spi.c */
130 int sja1105_spi_send_packed_buf(const struct sja1105_private
*priv
,
131 sja1105_spi_rw_mode_t rw
, u64 reg_addr
,
132 void *packed_buf
, size_t size_bytes
);
133 int sja1105_spi_send_int(const struct sja1105_private
*priv
,
134 sja1105_spi_rw_mode_t rw
, u64 reg_addr
,
135 u64
*value
, u64 size_bytes
);
136 int sja1105_spi_send_long_packed_buf(const struct sja1105_private
*priv
,
137 sja1105_spi_rw_mode_t rw
, u64 base_addr
,
138 void *packed_buf
, u64 buf_len
);
139 int sja1105_static_config_upload(struct sja1105_private
*priv
);
140 int sja1105_inhibit_tx(const struct sja1105_private
*priv
,
141 unsigned long port_bitmap
, bool tx_inhibited
);
143 extern struct sja1105_info sja1105e_info
;
144 extern struct sja1105_info sja1105t_info
;
145 extern struct sja1105_info sja1105p_info
;
146 extern struct sja1105_info sja1105q_info
;
147 extern struct sja1105_info sja1105r_info
;
148 extern struct sja1105_info sja1105s_info
;
150 /* From sja1105_clocking.c */
155 } sja1105_mii_role_t
;
161 } sja1105_phy_interface_t
;
164 SJA1105_SPEED_10MBPS
= 3,
165 SJA1105_SPEED_100MBPS
= 2,
166 SJA1105_SPEED_1000MBPS
= 1,
167 SJA1105_SPEED_AUTO
= 0,
170 int sja1105pqrs_setup_rgmii_delay(const void *ctx
, int port
);
171 int sja1105_clocking_setup_port(struct sja1105_private
*priv
, int port
);
172 int sja1105_clocking_setup(struct sja1105_private
*priv
);
174 /* From sja1105_ethtool.c */
175 void sja1105_get_ethtool_stats(struct dsa_switch
*ds
, int port
, u64
*data
);
176 void sja1105_get_strings(struct dsa_switch
*ds
, int port
,
177 u32 stringset
, u8
*data
);
178 int sja1105_get_sset_count(struct dsa_switch
*ds
, int port
, int sset
);
180 /* From sja1105_dynamic_config.c */
181 int sja1105_dynamic_config_read(struct sja1105_private
*priv
,
182 enum sja1105_blk_idx blk_idx
,
183 int index
, void *entry
);
184 int sja1105_dynamic_config_write(struct sja1105_private
*priv
,
185 enum sja1105_blk_idx blk_idx
,
186 int index
, void *entry
, bool keep
);
189 SJA1105_C_TAG
= 0, /* Inner VLAN header */
190 SJA1105_S_TAG
= 1, /* Outer VLAN header */
193 u8
sja1105et_fdb_hash(struct sja1105_private
*priv
, const u8
*addr
, u16 vid
);
194 int sja1105et_fdb_add(struct dsa_switch
*ds
, int port
,
195 const unsigned char *addr
, u16 vid
);
196 int sja1105et_fdb_del(struct dsa_switch
*ds
, int port
,
197 const unsigned char *addr
, u16 vid
);
198 int sja1105pqrs_fdb_add(struct dsa_switch
*ds
, int port
,
199 const unsigned char *addr
, u16 vid
);
200 int sja1105pqrs_fdb_del(struct dsa_switch
*ds
, int port
,
201 const unsigned char *addr
, u16 vid
);
203 /* Common implementations for the static and dynamic configs */
204 size_t sja1105_l2_forwarding_entry_packing(void *buf
, void *entry_ptr
,
206 size_t sja1105pqrs_l2_lookup_entry_packing(void *buf
, void *entry_ptr
,
208 size_t sja1105et_l2_lookup_entry_packing(void *buf
, void *entry_ptr
,
210 size_t sja1105_vlan_lookup_entry_packing(void *buf
, void *entry_ptr
,
212 size_t sja1105pqrs_mac_config_entry_packing(void *buf
, void *entry_ptr
,