1 | // SPDX-License-Identifier: GPL-2.0+ |
2 | |
3 | #include "lan966x_main.h" |
4 | #include "lan966x_vcap_ag_api.h" |
5 | #include "vcap_api.h" |
6 | #include "vcap_api_client.h" |
7 | |
8 | static void lan966x_vcap_is1_port_keys(struct lan966x_port *port, |
9 | struct vcap_admin *admin, |
10 | struct vcap_output_print *out) |
11 | { |
12 | struct lan966x *lan966x = port->lan966x; |
13 | u32 val; |
14 | |
15 | out->prf(out->dst, " port[%d] (%s): " , port->chip_port, |
16 | netdev_name(dev: port->dev)); |
17 | |
18 | val = lan_rd(lan966x, ANA_VCAP_CFG(port->chip_port)); |
19 | out->prf(out->dst, "\n state: " ); |
20 | if (ANA_VCAP_CFG_S1_ENA_GET(val)) |
21 | out->prf(out->dst, "on" ); |
22 | else |
23 | out->prf(out->dst, "off" ); |
24 | |
25 | for (int l = 0; l < admin->lookups; ++l) { |
26 | out->prf(out->dst, "\n Lookup %d: " , l); |
27 | |
28 | val = lan_rd(lan966x, ANA_VCAP_S1_CFG(port->chip_port, l)); |
29 | |
30 | out->prf(out->dst, "\n other: " ); |
31 | switch (ANA_VCAP_S1_CFG_KEY_OTHER_CFG_GET(val)) { |
32 | case VCAP_IS1_PS_OTHER_NORMAL: |
33 | out->prf(out->dst, "normal" ); |
34 | break; |
35 | case VCAP_IS1_PS_OTHER_7TUPLE: |
36 | out->prf(out->dst, "7tuple" ); |
37 | break; |
38 | case VCAP_IS1_PS_OTHER_DBL_VID: |
39 | out->prf(out->dst, "dbl_vid" ); |
40 | break; |
41 | case VCAP_IS1_PS_OTHER_DMAC_VID: |
42 | out->prf(out->dst, "dmac_vid" ); |
43 | break; |
44 | default: |
45 | out->prf(out->dst, "-" ); |
46 | break; |
47 | } |
48 | |
49 | out->prf(out->dst, "\n ipv4: " ); |
50 | switch (ANA_VCAP_S1_CFG_KEY_IP4_CFG_GET(val)) { |
51 | case VCAP_IS1_PS_IPV4_NORMAL: |
52 | out->prf(out->dst, "normal" ); |
53 | break; |
54 | case VCAP_IS1_PS_IPV4_7TUPLE: |
55 | out->prf(out->dst, "7tuple" ); |
56 | break; |
57 | case VCAP_IS1_PS_IPV4_5TUPLE_IP4: |
58 | out->prf(out->dst, "5tuple_ipv4" ); |
59 | break; |
60 | case VCAP_IS1_PS_IPV4_DBL_VID: |
61 | out->prf(out->dst, "dbl_vid" ); |
62 | break; |
63 | case VCAP_IS1_PS_IPV4_DMAC_VID: |
64 | out->prf(out->dst, "dmac_vid" ); |
65 | break; |
66 | default: |
67 | out->prf(out->dst, "-" ); |
68 | break; |
69 | } |
70 | |
71 | out->prf(out->dst, "\n ipv6: " ); |
72 | switch (ANA_VCAP_S1_CFG_KEY_IP6_CFG_GET(val)) { |
73 | case VCAP_IS1_PS_IPV6_NORMAL: |
74 | out->prf(out->dst, "normal" ); |
75 | break; |
76 | case VCAP_IS1_PS_IPV6_7TUPLE: |
77 | out->prf(out->dst, "7tuple" ); |
78 | break; |
79 | case VCAP_IS1_PS_IPV6_5TUPLE_IP4: |
80 | out->prf(out->dst, "5tuple_ip4" ); |
81 | break; |
82 | case VCAP_IS1_PS_IPV6_NORMAL_IP6: |
83 | out->prf(out->dst, "normal_ip6" ); |
84 | break; |
85 | case VCAP_IS1_PS_IPV6_5TUPLE_IP6: |
86 | out->prf(out->dst, "5tuple_ip6" ); |
87 | break; |
88 | case VCAP_IS1_PS_IPV6_DBL_VID: |
89 | out->prf(out->dst, "dbl_vid" ); |
90 | break; |
91 | case VCAP_IS1_PS_IPV6_DMAC_VID: |
92 | out->prf(out->dst, "dmac_vid" ); |
93 | break; |
94 | default: |
95 | out->prf(out->dst, "-" ); |
96 | break; |
97 | } |
98 | |
99 | out->prf(out->dst, "\n rt: " ); |
100 | switch (ANA_VCAP_S1_CFG_KEY_RT_CFG_GET(val)) { |
101 | case VCAP_IS1_PS_RT_NORMAL: |
102 | out->prf(out->dst, "normal" ); |
103 | break; |
104 | case VCAP_IS1_PS_RT_7TUPLE: |
105 | out->prf(out->dst, "7tuple" ); |
106 | break; |
107 | case VCAP_IS1_PS_RT_DBL_VID: |
108 | out->prf(out->dst, "dbl_vid" ); |
109 | break; |
110 | case VCAP_IS1_PS_RT_DMAC_VID: |
111 | out->prf(out->dst, "dmac_vid" ); |
112 | break; |
113 | case VCAP_IS1_PS_RT_FOLLOW_OTHER: |
114 | out->prf(out->dst, "follow_other" ); |
115 | break; |
116 | default: |
117 | out->prf(out->dst, "-" ); |
118 | break; |
119 | } |
120 | } |
121 | |
122 | out->prf(out->dst, "\n" ); |
123 | } |
124 | |
125 | static void lan966x_vcap_is2_port_keys(struct lan966x_port *port, |
126 | struct vcap_admin *admin, |
127 | struct vcap_output_print *out) |
128 | { |
129 | struct lan966x *lan966x = port->lan966x; |
130 | u32 val; |
131 | |
132 | out->prf(out->dst, " port[%d] (%s): " , port->chip_port, |
133 | netdev_name(dev: port->dev)); |
134 | |
135 | val = lan_rd(lan966x, ANA_VCAP_S2_CFG(port->chip_port)); |
136 | out->prf(out->dst, "\n state: " ); |
137 | if (ANA_VCAP_S2_CFG_ENA_GET(val)) |
138 | out->prf(out->dst, "on" ); |
139 | else |
140 | out->prf(out->dst, "off" ); |
141 | |
142 | for (int l = 0; l < admin->lookups; ++l) { |
143 | out->prf(out->dst, "\n Lookup %d: " , l); |
144 | |
145 | out->prf(out->dst, "\n snap: " ); |
146 | if (ANA_VCAP_S2_CFG_SNAP_DIS_GET(val) & (BIT(0) << l)) |
147 | out->prf(out->dst, "mac_llc" ); |
148 | else |
149 | out->prf(out->dst, "mac_snap" ); |
150 | |
151 | out->prf(out->dst, "\n oam: " ); |
152 | if (ANA_VCAP_S2_CFG_OAM_DIS_GET(val) & (BIT(0) << l)) |
153 | out->prf(out->dst, "mac_etype" ); |
154 | else |
155 | out->prf(out->dst, "mac_oam" ); |
156 | |
157 | out->prf(out->dst, "\n arp: " ); |
158 | if (ANA_VCAP_S2_CFG_ARP_DIS_GET(val) & (BIT(0) << l)) |
159 | out->prf(out->dst, "mac_etype" ); |
160 | else |
161 | out->prf(out->dst, "mac_arp" ); |
162 | |
163 | out->prf(out->dst, "\n ipv4_other: " ); |
164 | if (ANA_VCAP_S2_CFG_IP_OTHER_DIS_GET(val) & (BIT(0) << l)) |
165 | out->prf(out->dst, "mac_etype" ); |
166 | else |
167 | out->prf(out->dst, "ip4_other" ); |
168 | |
169 | out->prf(out->dst, "\n ipv4_tcp_udp: " ); |
170 | if (ANA_VCAP_S2_CFG_IP_TCPUDP_DIS_GET(val) & (BIT(0) << l)) |
171 | out->prf(out->dst, "mac_etype" ); |
172 | else |
173 | out->prf(out->dst, "ipv4_tcp_udp" ); |
174 | |
175 | out->prf(out->dst, "\n ipv6: " ); |
176 | switch (ANA_VCAP_S2_CFG_IP6_CFG_GET(val) & (0x3 << l)) { |
177 | case VCAP_IS2_PS_IPV6_TCPUDP_OTHER: |
178 | out->prf(out->dst, "ipv6_tcp_udp ipv6_tcp_udp" ); |
179 | break; |
180 | case VCAP_IS2_PS_IPV6_STD: |
181 | out->prf(out->dst, "ipv6_std" ); |
182 | break; |
183 | case VCAP_IS2_PS_IPV6_IP4_TCPUDP_IP4_OTHER: |
184 | out->prf(out->dst, "ipv4_tcp_udp ipv4_tcp_udp" ); |
185 | break; |
186 | case VCAP_IS2_PS_IPV6_MAC_ETYPE: |
187 | out->prf(out->dst, "mac_etype" ); |
188 | break; |
189 | } |
190 | } |
191 | |
192 | out->prf(out->dst, "\n" ); |
193 | } |
194 | |
195 | static void lan966x_vcap_es0_port_keys(struct lan966x_port *port, |
196 | struct vcap_admin *admin, |
197 | struct vcap_output_print *out) |
198 | { |
199 | struct lan966x *lan966x = port->lan966x; |
200 | u32 val; |
201 | |
202 | out->prf(out->dst, " port[%d] (%s): " , port->chip_port, |
203 | netdev_name(dev: port->dev)); |
204 | |
205 | val = lan_rd(lan966x, REW_PORT_CFG(port->chip_port)); |
206 | out->prf(out->dst, "\n state: " ); |
207 | if (REW_PORT_CFG_ES0_EN_GET(val)) |
208 | out->prf(out->dst, "on" ); |
209 | else |
210 | out->prf(out->dst, "off" ); |
211 | |
212 | out->prf(out->dst, "\n" ); |
213 | } |
214 | |
215 | int lan966x_vcap_port_info(struct net_device *dev, |
216 | struct vcap_admin *admin, |
217 | struct vcap_output_print *out) |
218 | { |
219 | struct lan966x_port *port = netdev_priv(dev); |
220 | struct lan966x *lan966x = port->lan966x; |
221 | const struct vcap_info *vcap; |
222 | struct vcap_control *vctrl; |
223 | |
224 | vctrl = lan966x->vcap_ctrl; |
225 | vcap = &vctrl->vcaps[admin->vtype]; |
226 | |
227 | out->prf(out->dst, "%s:\n" , vcap->name); |
228 | switch (admin->vtype) { |
229 | case VCAP_TYPE_IS2: |
230 | lan966x_vcap_is2_port_keys(port, admin, out); |
231 | break; |
232 | case VCAP_TYPE_IS1: |
233 | lan966x_vcap_is1_port_keys(port, admin, out); |
234 | break; |
235 | case VCAP_TYPE_ES0: |
236 | lan966x_vcap_es0_port_keys(port, admin, out); |
237 | break; |
238 | default: |
239 | out->prf(out->dst, " no info\n" ); |
240 | break; |
241 | } |
242 | |
243 | return 0; |
244 | } |
245 | |