1 // SPDX-License-Identifier: GPL-2.0-only
3 #include <asm/mach-rtl838x/mach-rtl83xx.h>
6 extern struct mutex smi_lock
;
9 static inline void rtl838x_mask_port_reg(u64 clear
, u64 set
, int reg
)
11 sw_w32_mask((u32
)clear
, (u32
)set
, reg
);
14 static inline void rtl838x_set_port_reg(u64 set
, int reg
)
19 static inline u64
rtl838x_get_port_reg(int reg
)
21 return ((u64
) sw_r32(reg
));
24 static inline int rtl838x_stat_port_std_mib(int p
)
26 return RTL838X_STAT_PORT_STD_MIB
+ (p
<< 8);
29 static inline int rtl838x_port_iso_ctrl(int p
)
31 return RTL838X_PORT_ISO_CTRL(p
);
34 static inline void rtl838x_exec_tbl0_cmd(u32 cmd
)
36 sw_w32(cmd
, RTL838X_TBL_ACCESS_CTRL_0
);
37 do { } while (sw_r32(RTL838X_TBL_ACCESS_CTRL_0
) & BIT(15));
40 static inline void rtl838x_exec_tbl1_cmd(u32 cmd
)
42 sw_w32(cmd
, RTL838X_TBL_ACCESS_CTRL_1
);
43 do { } while (sw_r32(RTL838X_TBL_ACCESS_CTRL_1
) & BIT(15));
46 static inline int rtl838x_tbl_access_data_0(int i
)
48 return RTL838X_TBL_ACCESS_DATA_0(i
);
51 static void rtl838x_vlan_tables_read(u32 vlan
, struct rtl838x_vlan_info
*info
)
55 cmd
= BIT(15) /* Execute cmd */
57 | 0 << 12 /* Table type 0b00 */
59 rtl838x_exec_tbl0_cmd(cmd
);
60 info
->tagged_ports
= sw_r32(RTL838X_TBL_ACCESS_DATA_0(0));
61 v
= sw_r32(RTL838X_TBL_ACCESS_DATA_0(1));
62 info
->profile_id
= v
& 0x7;
63 info
->hash_mc_fid
= !!(v
& 0x8);
64 info
->hash_uc_fid
= !!(v
& 0x10);
65 info
->fid
= (v
>> 5) & 0x3f;
68 cmd
= BIT(15) /* Execute cmd */
70 | 0 << 12 /* Table type 0b00 */
72 rtl838x_exec_tbl1_cmd(cmd
);
73 info
->untagged_ports
= sw_r32(RTL838X_TBL_ACCESS_DATA_1(0));
76 static void rtl838x_vlan_set_tagged(u32 vlan
, struct rtl838x_vlan_info
*info
)
78 u32 cmd
= BIT(15) /* Execute cmd */
80 | 0 << 12 /* Table type 0b00 */
84 sw_w32(info
->tagged_ports
, RTL838X_TBL_ACCESS_DATA_0(0));
87 v
|= info
->hash_mc_fid
? 0x8 : 0;
88 v
|= info
->hash_uc_fid
? 0x10 : 0;
89 v
|= ((u32
)info
->fid
) << 5;
91 sw_w32(v
, RTL838X_TBL_ACCESS_DATA_0(1));
92 rtl838x_exec_tbl0_cmd(cmd
);
95 static void rtl838x_vlan_set_untagged(u32 vlan
, u64 portmask
)
97 u32 cmd
= BIT(15) /* Execute cmd */
99 | 0 << 12 /* Table type 0b00 */
101 sw_w32(portmask
& 0x1fffffff, RTL838X_TBL_ACCESS_DATA_1(0));
102 rtl838x_exec_tbl1_cmd(cmd
);
105 static inline int rtl838x_mac_force_mode_ctrl(int p
)
107 return RTL838X_MAC_FORCE_MODE_CTRL
+ (p
<< 2);
110 static inline int rtl838x_mac_port_ctrl(int p
)
112 return RTL838X_MAC_PORT_CTRL(p
);
115 static inline int rtl838x_l2_port_new_salrn(int p
)
117 return RTL838X_L2_PORT_NEW_SALRN(p
);
120 static inline int rtl838x_l2_port_new_sa_fwd(int p
)
122 return RTL838X_L2_PORT_NEW_SA_FWD(p
);
125 static inline int rtl838x_mir_ctrl(int group
)
127 return RTL838X_MIR_CTRL(group
);
130 static inline int rtl838x_mir_dpm(int group
)
132 return RTL838X_MIR_DPM_CTRL(group
);
135 static inline int rtl838x_mir_spm(int group
)
137 return RTL838X_MIR_SPM_CTRL(group
);
140 static inline int rtl838x_mac_link_spd_sts(int p
)
142 return RTL838X_MAC_LINK_SPD_STS(p
);
145 static u64
rtl838x_read_l2_entry_using_hash(u32 hash
, u32 position
, struct rtl838x_l2_entry
*e
)
150 /* Search in SRAM, with hash and at position in hash bucket (0-3) */
151 u32 idx
= (0 << 14) | (hash
<< 2) | position
;
153 u32 cmd
= BIT(16) /* Execute cmd */
155 | 0 << 13 /* Table type 0b00 */
158 sw_w32(cmd
, RTL838X_TBL_ACCESS_L2_CTRL
);
159 do { } while (sw_r32(RTL838X_TBL_ACCESS_L2_CTRL
) & BIT(16));
160 r
[0] = sw_r32(RTL838X_TBL_ACCESS_L2_DATA(0));
161 r
[1] = sw_r32(RTL838X_TBL_ACCESS_L2_DATA(1));
162 r
[2] = sw_r32(RTL838X_TBL_ACCESS_L2_DATA(2));
164 e
->mac
[0] = (r
[1] >> 20);
165 e
->mac
[1] = (r
[1] >> 12);
166 e
->mac
[2] = (r
[1] >> 4);
167 e
->mac
[3] = (r
[1] & 0xf) << 4 | (r
[2] >> 28);
168 e
->mac
[4] = (r
[2] >> 20);
169 e
->mac
[5] = (r
[2] >> 12);
170 e
->is_static
= !!((r
[0] >> 19) & 1);
171 e
->vid
= r
[0] & 0xfff;
172 e
->rvid
= r
[2] & 0xfff;
173 e
->port
= (r
[0] >> 12) & 0x1f;
176 if (!(r
[0] >> 17)) /* Check for invalid entry */
180 pr_debug("Found in Hash: R1 %x R2 %x R3 %x\n", r
[0], r
[1], r
[2]);
182 entry
= (((u64
) r
[1]) << 32) | (r
[2] & 0xfffff000) | (r
[0] & 0xfff);
186 static u64
rtl838x_read_cam(int idx
, struct rtl838x_l2_entry
*e
)
191 u32 cmd
= BIT(16) /* Execute cmd */
193 | BIT(13) /* Table type 0b01 */
195 sw_w32(cmd
, RTL838X_TBL_ACCESS_L2_CTRL
);
196 do { } while (sw_r32(RTL838X_TBL_ACCESS_L2_CTRL
) & BIT(16));
197 r
[0] = sw_r32(RTL838X_TBL_ACCESS_L2_DATA(0));
198 r
[1] = sw_r32(RTL838X_TBL_ACCESS_L2_DATA(1));
199 r
[2] = sw_r32(RTL838X_TBL_ACCESS_L2_DATA(2));
201 e
->mac
[0] = (r
[1] >> 20);
202 e
->mac
[1] = (r
[1] >> 12);
203 e
->mac
[2] = (r
[1] >> 4);
204 e
->mac
[3] = (r
[1] & 0xf) << 4 | (r
[2] >> 28);
205 e
->mac
[4] = (r
[2] >> 20);
206 e
->mac
[5] = (r
[2] >> 12);
207 e
->is_static
= !!((r
[0] >> 19) & 1);
208 e
->vid
= r
[0] & 0xfff;
209 e
->rvid
= r
[2] & 0xfff;
210 e
->port
= (r
[0] >> 12) & 0x1f;
213 if (!(r
[0] >> 17)) /* Check for invalid entry */
217 pr_debug("Found in CAM: R1 %x R2 %x R3 %x\n", r
[0], r
[1], r
[2]);
219 entry
= (((u64
) r
[1]) << 32) | (r
[2] & 0xfffff000) | (r
[0] & 0xfff);
223 static inline int rtl838x_vlan_profile(int profile
)
225 return RTL838X_VLAN_PROFILE(profile
);
228 static inline int rtl838x_vlan_port_egr_filter(int port
)
230 return RTL838X_VLAN_PORT_EGR_FLTR
;
233 static inline int rtl838x_vlan_port_igr_filter(int port
)
235 return RTL838X_VLAN_PORT_IGR_FLTR(port
);
238 static inline int rtl838x_vlan_port_pb(int port
)
240 return RTL838X_VLAN_PORT_PB_VLAN(port
);
243 static inline int rtl838x_vlan_port_tag_sts_ctrl(int port
)
245 return RTL838X_VLAN_PORT_TAG_STS_CTRL(port
);
248 const struct rtl838x_reg rtl838x_reg
= {
249 .mask_port_reg_be
= rtl838x_mask_port_reg
,
250 .set_port_reg_be
= rtl838x_set_port_reg
,
251 .get_port_reg_be
= rtl838x_get_port_reg
,
252 .mask_port_reg_le
= rtl838x_mask_port_reg
,
253 .set_port_reg_le
= rtl838x_set_port_reg
,
254 .get_port_reg_le
= rtl838x_get_port_reg
,
255 .stat_port_rst
= RTL838X_STAT_PORT_RST
,
256 .stat_rst
= RTL838X_STAT_RST
,
257 .stat_port_std_mib
= rtl838x_stat_port_std_mib
,
258 .port_iso_ctrl
= rtl838x_port_iso_ctrl
,
259 .l2_ctrl_0
= RTL838X_L2_CTRL_0
,
260 .l2_ctrl_1
= RTL838X_L2_CTRL_1
,
261 .l2_port_aging_out
= RTL838X_L2_PORT_AGING_OUT
,
262 .smi_poll_ctrl
= RTL838X_SMI_POLL_CTRL
,
263 .l2_tbl_flush_ctrl
= RTL838X_L2_TBL_FLUSH_CTRL
,
264 .exec_tbl0_cmd
= rtl838x_exec_tbl0_cmd
,
265 .exec_tbl1_cmd
= rtl838x_exec_tbl1_cmd
,
266 .tbl_access_data_0
= rtl838x_tbl_access_data_0
,
267 .isr_glb_src
= RTL838X_ISR_GLB_SRC
,
268 .isr_port_link_sts_chg
= RTL838X_ISR_PORT_LINK_STS_CHG
,
269 .imr_port_link_sts_chg
= RTL838X_IMR_PORT_LINK_STS_CHG
,
270 .imr_glb
= RTL838X_IMR_GLB
,
271 .vlan_tables_read
= rtl838x_vlan_tables_read
,
272 .vlan_set_tagged
= rtl838x_vlan_set_tagged
,
273 .vlan_set_untagged
= rtl838x_vlan_set_untagged
,
274 .mac_force_mode_ctrl
= rtl838x_mac_force_mode_ctrl
,
275 .mac_port_ctrl
= rtl838x_mac_port_ctrl
,
276 .l2_port_new_salrn
= rtl838x_l2_port_new_salrn
,
277 .l2_port_new_sa_fwd
= rtl838x_l2_port_new_sa_fwd
,
278 .mir_ctrl
= rtl838x_mir_ctrl
,
279 .mir_dpm
= rtl838x_mir_dpm
,
280 .mir_spm
= rtl838x_mir_spm
,
281 .mac_link_sts
= RTL838X_MAC_LINK_STS
,
282 .mac_link_dup_sts
= RTL838X_MAC_LINK_DUP_STS
,
283 .mac_link_spd_sts
= rtl838x_mac_link_spd_sts
,
284 .mac_rx_pause_sts
= RTL838X_MAC_RX_PAUSE_STS
,
285 .mac_tx_pause_sts
= RTL838X_MAC_TX_PAUSE_STS
,
286 .read_l2_entry_using_hash
= rtl838x_read_l2_entry_using_hash
,
287 .read_cam
= rtl838x_read_cam
,
288 .vlan_profile
= rtl838x_vlan_profile
,
289 .vlan_port_egr_filter
= rtl838x_vlan_port_egr_filter
,
290 .vlan_port_igr_filter
= rtl838x_vlan_port_igr_filter
,
291 .vlan_port_pb
= rtl838x_vlan_port_pb
,
292 .vlan_port_tag_sts_ctrl
= rtl838x_vlan_port_tag_sts_ctrl
,
295 irqreturn_t
rtl838x_switch_irq(int irq
, void *dev_id
)
297 struct dsa_switch
*ds
= dev_id
;
298 u32 status
= sw_r32(RTL838X_ISR_GLB_SRC
);
299 u32 ports
= sw_r32(RTL838X_ISR_PORT_LINK_STS_CHG
);
304 sw_w32(ports
, RTL838X_ISR_PORT_LINK_STS_CHG
);
305 pr_debug("RTL8380 Link change: status: %x, ports %x\n", status
, ports
);
307 for (i
= 0; i
< 28; i
++) {
308 if (ports
& BIT(i
)) {
309 link
= sw_r32(RTL838X_MAC_LINK_STS
);
311 dsa_port_phylink_mac_change(ds
, i
, true);
313 dsa_port_phylink_mac_change(ds
, i
, false);
319 int rtl838x_smi_wait_op(int timeout
)
324 } while ((sw_r32(RTL838X_SMI_ACCESS_PHY_CTRL_1
) & 0x1) && (timeout
>= 0));
331 * Reads a register in a page from the PHY
333 int rtl838x_read_phy(u32 port
, u32 page
, u32 reg
, u32
*val
)
343 if (page
> 4095 || reg
> 31)
346 mutex_lock(&smi_lock
);
348 if (rtl838x_smi_wait_op(10000))
351 sw_w32_mask(0xffff0000, port
<< 16, RTL838X_SMI_ACCESS_PHY_CTRL_2
);
353 park_page
= sw_r32(RTL838X_SMI_ACCESS_PHY_CTRL_1
) & ((0x1f << 15) | 0x2);
354 v
= reg
<< 20 | page
<< 3;
355 sw_w32(v
| park_page
, RTL838X_SMI_ACCESS_PHY_CTRL_1
);
356 sw_w32_mask(0, 1, RTL838X_SMI_ACCESS_PHY_CTRL_1
);
358 if (rtl838x_smi_wait_op(10000))
361 *val
= sw_r32(RTL838X_SMI_ACCESS_PHY_CTRL_2
) & 0xffff;
363 mutex_unlock(&smi_lock
);
367 mutex_unlock(&smi_lock
);
372 * Write to a register in a page of the PHY
374 int rtl838x_write_phy(u32 port
, u32 page
, u32 reg
, u32 val
)
380 if (port
> 31 || page
> 4095 || reg
> 31)
383 mutex_lock(&smi_lock
);
384 if (rtl838x_smi_wait_op(10000))
387 sw_w32(BIT(port
), RTL838X_SMI_ACCESS_PHY_CTRL_0
);
390 sw_w32_mask(0xffff0000, val
<< 16, RTL838X_SMI_ACCESS_PHY_CTRL_2
);
392 park_page
= sw_r32(RTL838X_SMI_ACCESS_PHY_CTRL_1
) & ((0x1f << 15) | 0x2);
393 v
= reg
<< 20 | page
<< 3 | 0x4;
394 sw_w32(v
| park_page
, RTL838X_SMI_ACCESS_PHY_CTRL_1
);
395 sw_w32_mask(0, 1, RTL838X_SMI_ACCESS_PHY_CTRL_1
);
397 if (rtl838x_smi_wait_op(10000))
400 mutex_unlock(&smi_lock
);
404 mutex_unlock(&smi_lock
);
408 void rtl8380_get_version(struct rtl838x_switch_priv
*priv
)
410 u32 rw_save
, info_save
;
413 rw_save
= sw_r32(RTL838X_INT_RW_CTRL
);
414 sw_w32(rw_save
| 0x3, RTL838X_INT_RW_CTRL
);
416 info_save
= sw_r32(RTL838X_CHIP_INFO
);
417 sw_w32(info_save
| 0xA0000000, RTL838X_CHIP_INFO
);
419 info
= sw_r32(RTL838X_CHIP_INFO
);
420 sw_w32(info_save
, RTL838X_CHIP_INFO
);
421 sw_w32(rw_save
, RTL838X_INT_RW_CTRL
);
423 if ((info
& 0xFFFF) == 0x6275) {
424 if (((info
>> 16) & 0x1F) == 0x1)
425 priv
->version
= RTL8380_VERSION_A
;
426 else if (((info
>> 16) & 0x1F) == 0x2)
427 priv
->version
= RTL8380_VERSION_B
;
429 priv
->version
= RTL8380_VERSION_B
;
436 * Applies the same hash algorithm as the one used currently by the ASIC
438 u32
rtl838x_hash(struct rtl838x_switch_priv
*priv
, u64 seed
)
442 if (sw_r32(priv
->r
->l2_ctrl_0
) & 1) {
443 h1
= (seed
>> 11) & 0x7ff;
444 h1
= ((h1
& 0x1f) << 6) | ((h1
>> 5) & 0x3f);
446 h2
= (seed
>> 33) & 0x7ff;
447 h2
= ((h2
& 0x3f) << 5) | ((h2
>> 6) & 0x1f);
449 h3
= (seed
>> 44) & 0x7ff;
450 h3
= ((h3
& 0x7f) << 4) | ((h3
>> 7) & 0xf);
452 h
= h1
^ h2
^ h3
^ ((seed
>> 55) & 0x1ff);
453 h
^= ((seed
>> 22) & 0x7ff) ^ (seed
& 0x7ff);
455 h
= ((seed
>> 55) & 0x1ff) ^ ((seed
>> 44) & 0x7ff)
456 ^ ((seed
>> 33) & 0x7ff) ^ ((seed
>> 22) & 0x7ff)
457 ^ ((seed
>> 11) & 0x7ff) ^ (seed
& 0x7ff);
463 void rtl838x_vlan_profile_dump(int index
)
467 if (index
< 0 || index
> 7)
470 profile
= sw_r32(RTL838X_VLAN_PROFILE(index
));
472 pr_debug("VLAN %d: L2 learning: %d, L2 Unknown MultiCast Field %x, \
473 IPv4 Unknown MultiCast Field %x, IPv6 Unknown MultiCast Field: %x",
474 index
, profile
& 1, (profile
>> 1) & 0x1ff, (profile
>> 10) & 0x1ff,
475 (profile
>> 19) & 0x1ff);