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