1 // SPDX-License-Identifier: GPL-2.0-only
3 #include <asm/mach-rtl838x/mach-rtl83xx.h>
6 extern struct mutex smi_lock
;
7 extern struct rtl83xx_soc_info soc_info
;
9 inline void rtl931x_exec_tbl0_cmd(u32 cmd
)
11 sw_w32(cmd
, RTL931X_TBL_ACCESS_CTRL_0
);
12 do { } while (sw_r32(RTL931X_TBL_ACCESS_CTRL_0
) & (1 << 20));
15 inline void rtl931x_exec_tbl1_cmd(u32 cmd
)
17 sw_w32(cmd
, RTL931X_TBL_ACCESS_CTRL_1
);
18 do { } while (sw_r32(RTL931X_TBL_ACCESS_CTRL_1
) & (1 << 17));
21 inline int rtl931x_tbl_access_data_0(int i
)
23 return RTL931X_TBL_ACCESS_DATA_0(i
);
26 void rtl931x_vlan_profile_dump(int index
)
30 if (index
< 0 || index
> 15)
33 profile
[0] = sw_r32(RTL931X_VLAN_PROFILE_SET(index
));
34 profile
[1] = (sw_r32(RTL931X_VLAN_PROFILE_SET(index
) + 4) & 0x1FFFFFFFULL
) << 32
35 | (sw_r32(RTL931X_VLAN_PROFILE_SET(index
) + 8) & 0xFFFFFFFF);
36 profile
[2] = (sw_r32(RTL931X_VLAN_PROFILE_SET(index
) + 16) & 0xFFFFFFFFULL
) << 32
37 | (sw_r32(RTL931X_VLAN_PROFILE_SET(index
) + 12) & 0x1FFFFFFULL
);
38 profile
[3] = (sw_r32(RTL931X_VLAN_PROFILE_SET(index
) + 20) & 0x1FFFFFFFULL
) << 32
39 | (sw_r32(RTL931X_VLAN_PROFILE_SET(index
) + 24) & 0xFFFFFFFF);
41 pr_info("VLAN %d: L2 learning: %d, L2 Unknown MultiCast Field %llx, \
42 IPv4 Unknown MultiCast Field %llx, IPv6 Unknown MultiCast Field: %llx",
43 index
, (u32
) (profile
[0] & (3 << 14)), profile
[1], profile
[2], profile
[3]);
46 static void rtl931x_stp_get(struct rtl838x_switch_priv
*priv
, u16 msti
, u32 port_state
[])
49 u32 cmd
= 1 << 20 /* Execute cmd */
51 | 2 << 15 /* Table type 0b10 */
53 priv
->r
->exec_tbl0_cmd(cmd
);
55 for (i
= 0; i
< 4; i
++)
56 port_state
[i
] = sw_r32(priv
->r
->tbl_access_data_0(i
));
59 static void rtl931x_stp_set(struct rtl838x_switch_priv
*priv
, u16 msti
, u32 port_state
[])
62 u32 cmd
= 1 << 20 /* Execute cmd */
64 | 5 << 15 /* Table type 0b101 */
66 for (i
= 0; i
< 4; i
++)
67 sw_w32(port_state
[i
], priv
->r
->tbl_access_data_0(i
));
68 priv
->r
->exec_tbl0_cmd(cmd
);
71 inline static int rtl931x_trk_mbr_ctr(int group
)
73 return RTL931X_TRK_MBR_CTRL
+ (group
<< 2);
76 static void rtl931x_vlan_tables_read(u32 vlan
, struct rtl838x_vlan_info
*info
)
79 // Read VLAN table (3) via register 0
80 struct table_reg
*r
= rtl_table_get(RTL9310_TBL_0
, 3);
82 rtl_table_read(r
, vlan
);
83 v
= sw_r32(rtl_table_data(r
, 0));
84 w
= sw_r32(rtl_table_data(r
, 1));
85 x
= sw_r32(rtl_table_data(r
, 2));
86 y
= sw_r32(rtl_table_data(r
, 3));
87 pr_debug("VLAN_READ %d: %08x %08x\n", vlan
, v
, w
);
90 info
->tagged_ports
= ((u64
) v
) << 25 | (w
>> 7);
91 info
->profile_id
= (x
>> 16) & 0xf;
92 info
->hash_mc_fid
= !!(x
& BIT(30));
93 info
->hash_uc_fid
= !!(x
& BIT(31));
95 // TODO: use also info in 4th register
97 // Read UNTAG table via table register 3
98 r
= rtl_table_get(RTL9310_TBL_3
, 0);
99 rtl_table_read(r
, vlan
);
100 v
= ((u64
)sw_r32(rtl_table_data(r
, 0))) << 25;
101 v
|= sw_r32(rtl_table_data(r
, 1)) >> 7;
102 rtl_table_release(r
);
104 info
->untagged_ports
= v
;
107 static void rtl931x_vlan_set_tagged(u32 vlan
, struct rtl838x_vlan_info
*info
)
110 // Access VLAN table (1) via register 0
111 struct table_reg
*r
= rtl_table_get(RTL9310_TBL_0
, 3);
113 v
= info
->tagged_ports
<< 7;
114 w
= (info
->tagged_ports
& 0x7f000000) << 25;
116 x
= info
->profile_id
<< 16;
117 w
|= info
->hash_mc_fid
? BIT(30) : 0;
118 w
|= info
->hash_uc_fid
? BIT(31) : 0;
119 // TODO: use also info in 4th register
121 sw_w32(v
, rtl_table_data(r
, 0));
122 sw_w32(w
, rtl_table_data(r
, 1));
123 sw_w32(x
, rtl_table_data(r
, 2));
125 rtl_table_write(r
, vlan
);
126 rtl_table_release(r
);
129 static void rtl931x_vlan_set_untagged(u32 vlan
, u64 portmask
)
131 struct table_reg
*r
= rtl_table_get(RTL9310_TBL_3
, 0);
133 rtl839x_set_port_reg_be(portmask
<< 7, rtl_table_data(r
, 0));
134 rtl_table_write(r
, vlan
);
135 rtl_table_release(r
);
138 static inline int rtl931x_mac_force_mode_ctrl(int p
)
140 return RTL931X_MAC_FORCE_MODE_CTRL
+ (p
<< 2);
143 static inline int rtl931x_mac_link_spd_sts(int p
)
145 return RTL931X_MAC_LINK_SPD_STS(p
);
148 static inline int rtl931x_mac_port_ctrl(int p
)
150 return RTL931X_MAC_PORT_CTRL(p
);
153 static inline int rtl931x_l2_port_new_salrn(int p
)
155 return RTL931X_L2_PORT_NEW_SALRN(p
);
158 static inline int rtl931x_l2_port_new_sa_fwd(int p
)
160 return RTL931X_L2_PORT_NEW_SA_FWD(p
);
163 static u64
rtl931x_read_l2_entry_using_hash(u32 hash
, u32 position
, struct rtl838x_l2_entry
*e
)
171 static u64
rtl931x_read_cam(int idx
, struct rtl838x_l2_entry
*e
)
178 irqreturn_t
rtl931x_switch_irq(int irq
, void *dev_id
)
180 struct dsa_switch
*ds
= dev_id
;
181 u32 status
= sw_r32(RTL931X_ISR_GLB_SRC
);
182 u64 ports
= rtl839x_get_port_reg_le(RTL931X_ISR_PORT_LINK_STS_CHG
);
187 rtl839x_set_port_reg_le(ports
, RTL931X_ISR_PORT_LINK_STS_CHG
);
188 pr_info("RTL9310 Link change: status: %x, ports %llx\n", status
, ports
);
190 for (i
= 0; i
< 56; i
++) {
191 if (ports
& BIT_ULL(i
)) {
192 link
= rtl839x_get_port_reg_le(RTL931X_MAC_LINK_STS
);
193 if (link
& BIT_ULL(i
))
194 dsa_port_phylink_mac_change(ds
, i
, true);
196 dsa_port_phylink_mac_change(ds
, i
, false);
203 int rtl931x_write_phy(u32 port
, u32 page
, u32 reg
, u32 val
)
209 if (port
> 63 || page
> 4095 || reg
> 31)
212 mutex_lock(&smi_lock
);
213 /* Clear both port registers */
214 sw_w32(0, RTL931X_SMI_INDRT_ACCESS_CTRL_2
);
215 sw_w32(0, RTL931X_SMI_INDRT_ACCESS_CTRL_2
+ 4);
216 sw_w32_mask(0, BIT(port
), RTL931X_SMI_INDRT_ACCESS_CTRL_2
+ (port
% 32) * 4);
218 sw_w32_mask(0xffff0000, val
<< 16, RTL931X_SMI_INDRT_ACCESS_CTRL_3
);
220 v
= reg
<< 6 | page
<< 11 ;
221 sw_w32(v
, RTL931X_SMI_INDRT_ACCESS_CTRL_0
);
223 sw_w32(0x1ff, RTL931X_SMI_INDRT_ACCESS_CTRL_1
);
225 v
|= 1 << 3 | 1; /* Write operation and execute */
226 sw_w32(v
, RTL931X_SMI_INDRT_ACCESS_CTRL_0
);
229 } while (sw_r32(RTL931X_SMI_INDRT_ACCESS_CTRL_0
) & 0x1);
231 if (sw_r32(RTL931X_SMI_INDRT_ACCESS_CTRL_0
) & 0x2)
234 mutex_unlock(&smi_lock
);
238 int rtl931x_read_phy(u32 port
, u32 page
, u32 reg
, u32
*val
)
242 if (port
> 63 || page
> 4095 || reg
> 31)
245 mutex_lock(&smi_lock
);
247 sw_w32_mask(0xffff, port
, RTL931X_SMI_INDRT_ACCESS_CTRL_3
);
248 v
= reg
<< 6 | page
<< 11; // TODO: ACCESS Offset? Park page
249 sw_w32(v
, RTL931X_SMI_INDRT_ACCESS_CTRL_0
);
251 sw_w32(0x1ff, RTL931X_SMI_INDRT_ACCESS_CTRL_1
);
254 sw_w32(v
, RTL931X_SMI_INDRT_ACCESS_CTRL_0
);
257 } while (sw_r32(RTL931X_SMI_INDRT_ACCESS_CTRL_0
) & 0x1);
259 *val
= (sw_r32(RTL931X_SMI_INDRT_ACCESS_CTRL_3
) & 0xffff0000) >> 16;
261 pr_info("%s: port %d, page: %d, reg: %x, val: %x\n", __func__
, port
, page
, reg
, *val
);
263 mutex_unlock(&smi_lock
);
267 void rtl931x_print_matrix(void)
269 volatile u64
*ptr
= RTL838X_SW_BASE
+ RTL839X_PORT_ISO_CTRL(0);
272 for (i
= 0; i
< 52; i
+= 4)
273 pr_info("> %16llx %16llx %16llx %16llx\n",
274 ptr
[i
+ 0], ptr
[i
+ 1], ptr
[i
+ 2], ptr
[i
+ 3]);
275 pr_info("CPU_PORT> %16llx\n", ptr
[52]);
278 const struct rtl838x_reg rtl931x_reg
= {
279 .mask_port_reg_be
= rtl839x_mask_port_reg_be
,
280 .set_port_reg_be
= rtl839x_set_port_reg_be
,
281 .get_port_reg_be
= rtl839x_get_port_reg_be
,
282 .mask_port_reg_le
= rtl839x_mask_port_reg_le
,
283 .set_port_reg_le
= rtl839x_set_port_reg_le
,
284 .get_port_reg_le
= rtl839x_get_port_reg_le
,
285 .stat_port_rst
= RTL931X_STAT_PORT_RST
,
286 .stat_rst
= RTL931X_STAT_RST
,
287 .stat_port_std_mib
= 0, // Not defined
288 .l2_ctrl_0
= RTL931X_L2_CTRL
,
289 .l2_ctrl_1
= RTL931X_L2_AGE_CTRL
,
290 .l2_port_aging_out
= RTL931X_L2_PORT_AGE_CTRL
,
291 // .smi_poll_ctrl does not exist
292 .l2_tbl_flush_ctrl
= RTL931X_L2_TBL_FLUSH_CTRL
,
293 .exec_tbl0_cmd
= rtl931x_exec_tbl0_cmd
,
294 .exec_tbl1_cmd
= rtl931x_exec_tbl1_cmd
,
295 .tbl_access_data_0
= rtl931x_tbl_access_data_0
,
296 .isr_glb_src
= RTL931X_ISR_GLB_SRC
,
297 .isr_port_link_sts_chg
= RTL931X_ISR_PORT_LINK_STS_CHG
,
298 .imr_port_link_sts_chg
= RTL931X_IMR_PORT_LINK_STS_CHG
,
299 // imr_glb does not exist on RTL931X
300 .vlan_tables_read
= rtl931x_vlan_tables_read
,
301 .vlan_set_tagged
= rtl931x_vlan_set_tagged
,
302 .vlan_set_untagged
= rtl931x_vlan_set_untagged
,
303 .vlan_profile_dump
= rtl931x_vlan_profile_dump
,
304 .stp_get
= rtl931x_stp_get
,
305 .stp_set
= rtl931x_stp_set
,
306 .mac_force_mode_ctrl
= rtl931x_mac_force_mode_ctrl
,
307 .mac_port_ctrl
= rtl931x_mac_port_ctrl
,
308 .l2_port_new_salrn
= rtl931x_l2_port_new_salrn
,
309 .l2_port_new_sa_fwd
= rtl931x_l2_port_new_sa_fwd
,
310 .mir_ctrl
= RTL931X_MIR_CTRL
,
311 .mir_dpm
= RTL931X_MIR_DPM_CTRL
,
312 .mir_spm
= RTL931X_MIR_SPM_CTRL
,
313 .mac_link_sts
= RTL931X_MAC_LINK_STS
,
314 .mac_link_dup_sts
= RTL931X_MAC_LINK_DUP_STS
,
315 .mac_link_spd_sts
= rtl931x_mac_link_spd_sts
,
316 .mac_rx_pause_sts
= RTL931X_MAC_RX_PAUSE_STS
,
317 .mac_tx_pause_sts
= RTL931X_MAC_TX_PAUSE_STS
,
318 .read_l2_entry_using_hash
= rtl931x_read_l2_entry_using_hash
,
319 .read_cam
= rtl931x_read_cam
,
320 .vlan_port_egr_filter
= RTL931X_VLAN_PORT_EGR_FLTR(0),
321 .vlan_port_igr_filter
= RTL931X_VLAN_PORT_IGR_FLTR(0),
322 // .vlan_port_pb = does not exist
323 .vlan_port_tag_sts_ctrl
= RTL931X_VLAN_PORT_TAG_CTRL
,
324 .trk_mbr_ctr
= rtl931x_trk_mbr_ctr
,