1 // SPDX-License-Identifier: BSD-3-Clause OR GPL-2.0
2 /* Copyright (c) 2015-2018 Mellanox Technologies. All rights reserved */
3
4 #include <linux/kernel.h>
5 #include <linux/module.h>
6 #include <linux/types.h>
7 #include <linux/pci.h>
8 #include <linux/netdevice.h>
9 #include <linux/etherdevice.h>
10 #include <linux/ethtool.h>
11 #include <linux/slab.h>
12 #include <linux/device.h>
13 #include <linux/skbuff.h>
14 #include <linux/if_vlan.h>
15 #include <linux/if_bridge.h>
16 #include <linux/workqueue.h>
17 #include <linux/jiffies.h>
18 #include <linux/bitops.h>
19 #include <linux/list.h>
20 #include <linux/notifier.h>
21 #include <linux/dcbnl.h>
22 #include <linux/inetdevice.h>
23 #include <linux/netlink.h>
24 #include <linux/jhash.h>
25 #include <linux/log2.h>
26 #include <linux/refcount.h>
27 #include <linux/rhashtable.h>
28 #include <net/switchdev.h>
29 #include <net/pkt_cls.h>
30 #include <net/netevent.h>
31 #include <net/addrconf.h>
32
33 #include "spectrum.h"
34 #include "pci.h"
35 #include "core.h"
36 #include "core_env.h"
37 #include "reg.h"
38 #include "port.h"
39 #include "trap.h"
40 #include "txheader.h"
41 #include "spectrum_cnt.h"
42 #include "spectrum_dpipe.h"
43 #include "spectrum_acl_flex_actions.h"
44 #include "spectrum_span.h"
45 #include "spectrum_ptp.h"
46 #include "spectrum_trap.h"
47
48 #define MLXSW_SP_FWREV_MINOR 2010
49 #define MLXSW_SP_FWREV_SUBMINOR 1006
50
51 #define MLXSW_SP1_FWREV_MAJOR 13
52 #define MLXSW_SP1_FWREV_CAN_RESET_MINOR 1702
53
54 static const struct mlxsw_fw_rev mlxsw_sp1_fw_rev = {
55 .major = MLXSW_SP1_FWREV_MAJOR,
56 .minor = MLXSW_SP_FWREV_MINOR,
57 .subminor = MLXSW_SP_FWREV_SUBMINOR,
58 .can_reset_minor = MLXSW_SP1_FWREV_CAN_RESET_MINOR,
59 };
60
61 #define MLXSW_SP1_FW_FILENAME \
62 "mellanox/mlxsw_spectrum-" __stringify(MLXSW_SP1_FWREV_MAJOR) \
63 "." __stringify(MLXSW_SP_FWREV_MINOR) \
64 "." __stringify(MLXSW_SP_FWREV_SUBMINOR) ".mfa2"
65
66 #define MLXSW_SP2_FWREV_MAJOR 29
67
68 static const struct mlxsw_fw_rev mlxsw_sp2_fw_rev = {
69 .major = MLXSW_SP2_FWREV_MAJOR,
70 .minor = MLXSW_SP_FWREV_MINOR,
71 .subminor = MLXSW_SP_FWREV_SUBMINOR,
72 };
73
74 #define MLXSW_SP2_FW_FILENAME \
75 "mellanox/mlxsw_spectrum2-" __stringify(MLXSW_SP2_FWREV_MAJOR) \
76 "." __stringify(MLXSW_SP_FWREV_MINOR) \
77 "." __stringify(MLXSW_SP_FWREV_SUBMINOR) ".mfa2"
78
79 #define MLXSW_SP3_FWREV_MAJOR 30
80
81 static const struct mlxsw_fw_rev mlxsw_sp3_fw_rev = {
82 .major = MLXSW_SP3_FWREV_MAJOR,
83 .minor = MLXSW_SP_FWREV_MINOR,
84 .subminor = MLXSW_SP_FWREV_SUBMINOR,
85 };
86
87 #define MLXSW_SP3_FW_FILENAME \
88 "mellanox/mlxsw_spectrum3-" __stringify(MLXSW_SP3_FWREV_MAJOR) \
89 "." __stringify(MLXSW_SP_FWREV_MINOR) \
90 "." __stringify(MLXSW_SP_FWREV_SUBMINOR) ".mfa2"
91
92 #define MLXSW_SP_LINECARDS_INI_BUNDLE_FILENAME \
93 "mellanox/lc_ini_bundle_" \
94 __stringify(MLXSW_SP_FWREV_MINOR) "_" \
95 __stringify(MLXSW_SP_FWREV_SUBMINOR) ".bin"
96
97 static const char mlxsw_sp1_driver_name[] = "mlxsw_spectrum";
98 static const char mlxsw_sp2_driver_name[] = "mlxsw_spectrum2";
99 static const char mlxsw_sp3_driver_name[] = "mlxsw_spectrum3";
100 static const char mlxsw_sp4_driver_name[] = "mlxsw_spectrum4";
101
102 static const unsigned char mlxsw_sp1_mac_mask[ETH_ALEN] = {
103 0xff, 0xff, 0xff, 0xff, 0xfc, 0x00
104 };
105 static const unsigned char mlxsw_sp2_mac_mask[ETH_ALEN] = {
106 0xff, 0xff, 0xff, 0xff, 0xf0, 0x00
107 };
108
109 /* tx_hdr_version
110 * Tx header version.
111 * Must be set to 1.
112 */
113 MLXSW_ITEM32(tx, hdr, version, 0x00, 28, 4);
114
115 /* tx_hdr_ctl
116 * Packet control type.
117 * 0 - Ethernet control (e.g. EMADs, LACP)
118 * 1 - Ethernet data
119 */
120 MLXSW_ITEM32(tx, hdr, ctl, 0x00, 26, 2);
121
122 /* tx_hdr_proto
123 * Packet protocol type. Must be set to 1 (Ethernet).
124 */
125 MLXSW_ITEM32(tx, hdr, proto, 0x00, 21, 3);
126
127 /* tx_hdr_rx_is_router
128 * Packet is sent from the router. Valid for data packets only.
129 */
130 MLXSW_ITEM32(tx, hdr, rx_is_router, 0x00, 19, 1);
131
132 /* tx_hdr_fid_valid
133 * Indicates if the 'fid' field is valid and should be used for
134 * forwarding lookup. Valid for data packets only.
135 */
136 MLXSW_ITEM32(tx, hdr, fid_valid, 0x00, 16, 1);
137
138 /* tx_hdr_swid
139 * Switch partition ID. Must be set to 0.
140 */
141 MLXSW_ITEM32(tx, hdr, swid, 0x00, 12, 3);
142
143 /* tx_hdr_control_tclass
144 * Indicates if the packet should use the control TClass and not one
145 * of the data TClasses.
146 */
147 MLXSW_ITEM32(tx, hdr, control_tclass, 0x00, 6, 1);
148
149 /* tx_hdr_etclass
150 * Egress TClass to be used on the egress device on the egress port.
151 */
152 MLXSW_ITEM32(tx, hdr, etclass, 0x00, 0, 4);
153
154 /* tx_hdr_port_mid
155 * Destination local port for unicast packets.
156 * Destination multicast ID for multicast packets.
157 *
158 * Control packets are directed to a specific egress port, while data
159 * packets are transmitted through the CPU port (0) into the switch partition,
160 * where forwarding rules are applied.
161 */
162 MLXSW_ITEM32(tx, hdr, port_mid, 0x04, 16, 16);
163
164 /* tx_hdr_fid
165 * Forwarding ID used for L2 forwarding lookup. Valid only if 'fid_valid' is
166 * set, otherwise calculated based on the packet's VID using VID to FID mapping.
167 * Valid for data packets only.
168 */
169 MLXSW_ITEM32(tx, hdr, fid, 0x08, 0, 16);
170
171 /* tx_hdr_type
172 * 0 - Data packets
173 * 6 - Control packets
174 */
175 MLXSW_ITEM32(tx, hdr, type, 0x0C, 0, 4);
176
mlxsw_sp_flow_counter_get(struct mlxsw_sp * mlxsw_sp,unsigned int counter_index,u64 * packets,u64 * bytes)177 int mlxsw_sp_flow_counter_get(struct mlxsw_sp *mlxsw_sp,
178 unsigned int counter_index, u64 *packets,
179 u64 *bytes)
180 {
181 char mgpc_pl[MLXSW_REG_MGPC_LEN];
182 int err;
183
184 mlxsw_reg_mgpc_pack(mgpc_pl, counter_index, MLXSW_REG_MGPC_OPCODE_NOP,
185 MLXSW_REG_FLOW_COUNTER_SET_TYPE_PACKETS_BYTES);
186 err = mlxsw_reg_query(mlxsw_sp->core, MLXSW_REG(mgpc), mgpc_pl);
187 if (err)
188 return err;
189 if (packets)
190 *packets = mlxsw_reg_mgpc_packet_counter_get(mgpc_pl);
191 if (bytes)
192 *bytes = mlxsw_reg_mgpc_byte_counter_get(mgpc_pl);
193 return 0;
194 }
195
mlxsw_sp_flow_counter_clear(struct mlxsw_sp * mlxsw_sp,unsigned int counter_index)196 static int mlxsw_sp_flow_counter_clear(struct mlxsw_sp *mlxsw_sp,
197 unsigned int counter_index)
198 {
199 char mgpc_pl[MLXSW_REG_MGPC_LEN];
200
201 mlxsw_reg_mgpc_pack(mgpc_pl, counter_index, MLXSW_REG_MGPC_OPCODE_CLEAR,
202 MLXSW_REG_FLOW_COUNTER_SET_TYPE_PACKETS_BYTES);
203 return mlxsw_reg_write(mlxsw_sp->core, MLXSW_REG(mgpc), mgpc_pl);
204 }
205
mlxsw_sp_flow_counter_alloc(struct mlxsw_sp * mlxsw_sp,unsigned int * p_counter_index)206 int mlxsw_sp_flow_counter_alloc(struct mlxsw_sp *mlxsw_sp,
207 unsigned int *p_counter_index)
208 {
209 int err;
210
211 err = mlxsw_sp_counter_alloc(mlxsw_sp, MLXSW_SP_COUNTER_SUB_POOL_FLOW,
212 p_counter_index);
213 if (err)
214 return err;
215 err = mlxsw_sp_flow_counter_clear(mlxsw_sp, *p_counter_index);
216 if (err)
217 goto err_counter_clear;
218 return 0;
219
220 err_counter_clear:
221 mlxsw_sp_counter_free(mlxsw_sp, MLXSW_SP_COUNTER_SUB_POOL_FLOW,
222 *p_counter_index);
223 return err;
224 }
225
mlxsw_sp_flow_counter_free(struct mlxsw_sp * mlxsw_sp,unsigned int counter_index)226 void mlxsw_sp_flow_counter_free(struct mlxsw_sp *mlxsw_sp,
227 unsigned int counter_index)
228 {
229 mlxsw_sp_counter_free(mlxsw_sp, MLXSW_SP_COUNTER_SUB_POOL_FLOW,
230 counter_index);
231 }
232
mlxsw_sp_txhdr_construct(struct sk_buff * skb,const struct mlxsw_tx_info * tx_info)233 static void mlxsw_sp_txhdr_construct(struct sk_buff *skb,
234 const struct mlxsw_tx_info *tx_info)
235 {
236 char *txhdr = skb_push(skb, MLXSW_TXHDR_LEN);
237
238 memset(txhdr, 0, MLXSW_TXHDR_LEN);
239
240 mlxsw_tx_hdr_version_set(txhdr, MLXSW_TXHDR_VERSION_1);
241 mlxsw_tx_hdr_ctl_set(txhdr, MLXSW_TXHDR_ETH_CTL);
242 mlxsw_tx_hdr_proto_set(txhdr, MLXSW_TXHDR_PROTO_ETH);
243 mlxsw_tx_hdr_swid_set(txhdr, 0);
244 mlxsw_tx_hdr_control_tclass_set(txhdr, 1);
245 mlxsw_tx_hdr_port_mid_set(txhdr, tx_info->local_port);
246 mlxsw_tx_hdr_type_set(txhdr, MLXSW_TXHDR_TYPE_CONTROL);
247 }
248
mlxsw_sp_stp_spms_state(u8 state)249 enum mlxsw_reg_spms_state mlxsw_sp_stp_spms_state(u8 state)
250 {
251 switch (state) {
252 case BR_STATE_FORWARDING:
253 return MLXSW_REG_SPMS_STATE_FORWARDING;
254 case BR_STATE_LEARNING:
255 return MLXSW_REG_SPMS_STATE_LEARNING;
256 case BR_STATE_LISTENING:
257 case BR_STATE_DISABLED:
258 case BR_STATE_BLOCKING:
259 return MLXSW_REG_SPMS_STATE_DISCARDING;
260 default:
261 BUG();
262 }
263 }
264
mlxsw_sp_port_vid_stp_set(struct mlxsw_sp_port * mlxsw_sp_port,u16 vid,u8 state)265 int mlxsw_sp_port_vid_stp_set(struct mlxsw_sp_port *mlxsw_sp_port, u16 vid,
266 u8 state)
267 {
268 enum mlxsw_reg_spms_state spms_state = mlxsw_sp_stp_spms_state(state);
269 struct mlxsw_sp *mlxsw_sp = mlxsw_sp_port->mlxsw_sp;
270 char *spms_pl;
271 int err;
272
273 spms_pl = kmalloc(MLXSW_REG_SPMS_LEN, GFP_KERNEL);
274 if (!spms_pl)
275 return -ENOMEM;
276 mlxsw_reg_spms_pack(spms_pl, mlxsw_sp_port->local_port);
277 mlxsw_reg_spms_vid_pack(spms_pl, vid, spms_state);
278
279 err = mlxsw_reg_write(mlxsw_sp->core, MLXSW_REG(spms), spms_pl);
280 kfree(spms_pl);
281 return err;
282 }
283
mlxsw_sp_base_mac_get(struct mlxsw_sp * mlxsw_sp)284 static int mlxsw_sp_base_mac_get(struct mlxsw_sp *mlxsw_sp)
285 {
286 char spad_pl[MLXSW_REG_SPAD_LEN] = {0};
287 int err;
288
289 err = mlxsw_reg_query(mlxsw_sp->core, MLXSW_REG(spad), spad_pl);
290 if (err)
291 return err;
292 mlxsw_reg_spad_base_mac_memcpy_from(spad_pl, mlxsw_sp->base_mac);
293 return 0;
294 }
295
mlxsw_sp_port_admin_status_set(struct mlxsw_sp_port * mlxsw_sp_port,bool is_up)296 int mlxsw_sp_port_admin_status_set(struct mlxsw_sp_port *mlxsw_sp_port,
297 bool is_up)
298 {
299 struct mlxsw_sp *mlxsw_sp = mlxsw_sp_port->mlxsw_sp;
300 char paos_pl[MLXSW_REG_PAOS_LEN];
301
302 mlxsw_reg_paos_pack(paos_pl, mlxsw_sp_port->local_port,
303 is_up ? MLXSW_PORT_ADMIN_STATUS_UP :
304 MLXSW_PORT_ADMIN_STATUS_DOWN);
305 return mlxsw_reg_write(mlxsw_sp->core, MLXSW_REG(paos), paos_pl);
306 }
307
mlxsw_sp_port_dev_addr_set(struct mlxsw_sp_port * mlxsw_sp_port,const unsigned char * addr)308 static int mlxsw_sp_port_dev_addr_set(struct mlxsw_sp_port *mlxsw_sp_port,
309 const unsigned char *addr)
310 {
311 struct mlxsw_sp *mlxsw_sp = mlxsw_sp_port->mlxsw_sp;
312 char ppad_pl[MLXSW_REG_PPAD_LEN];
313
314 mlxsw_reg_ppad_pack(ppad_pl, true, mlxsw_sp_port->local_port);
315 mlxsw_reg_ppad_mac_memcpy_to(ppad_pl, addr);
316 return mlxsw_reg_write(mlxsw_sp->core, MLXSW_REG(ppad), ppad_pl);
317 }
318
mlxsw_sp_port_dev_addr_init(struct mlxsw_sp_port * mlxsw_sp_port)319 static int mlxsw_sp_port_dev_addr_init(struct mlxsw_sp_port *mlxsw_sp_port)
320 {
321 struct mlxsw_sp *mlxsw_sp = mlxsw_sp_port->mlxsw_sp;
322
323 eth_hw_addr_gen(mlxsw_sp_port->dev, mlxsw_sp->base_mac,
324 mlxsw_sp_port->local_port);
325 return mlxsw_sp_port_dev_addr_set(mlxsw_sp_port,
326 mlxsw_sp_port->dev->dev_addr);
327 }
328
mlxsw_sp_port_max_mtu_get(struct mlxsw_sp_port * mlxsw_sp_port,int * p_max_mtu)329 static int mlxsw_sp_port_max_mtu_get(struct mlxsw_sp_port *mlxsw_sp_port, int *p_max_mtu)
330 {
331 struct mlxsw_sp *mlxsw_sp = mlxsw_sp_port->mlxsw_sp;
332 char pmtu_pl[MLXSW_REG_PMTU_LEN];
333 int err;
334
335 mlxsw_reg_pmtu_pack(pmtu_pl, mlxsw_sp_port->local_port, 0);
336 err = mlxsw_reg_query(mlxsw_sp->core, MLXSW_REG(pmtu), pmtu_pl);
337 if (err)
338 return err;
339
340 *p_max_mtu = mlxsw_reg_pmtu_max_mtu_get(pmtu_pl);
341 return 0;
342 }
343
mlxsw_sp_port_mtu_set(struct mlxsw_sp_port * mlxsw_sp_port,u16 mtu)344 static int mlxsw_sp_port_mtu_set(struct mlxsw_sp_port *mlxsw_sp_port, u16 mtu)
345 {
346 struct mlxsw_sp *mlxsw_sp = mlxsw_sp_port->mlxsw_sp;
347 char pmtu_pl[MLXSW_REG_PMTU_LEN];
348
349 mtu += MLXSW_TXHDR_LEN + ETH_HLEN;
350 if (mtu > mlxsw_sp_port->max_mtu)
351 return -EINVAL;
352
353 mlxsw_reg_pmtu_pack(pmtu_pl, mlxsw_sp_port->local_port, mtu);
354 return mlxsw_reg_write(mlxsw_sp->core, MLXSW_REG(pmtu), pmtu_pl);
355 }
356
mlxsw_sp_port_swid_set(struct mlxsw_sp * mlxsw_sp,u16 local_port,u8 swid)357 static int mlxsw_sp_port_swid_set(struct mlxsw_sp *mlxsw_sp,
358 u16 local_port, u8 swid)
359 {
360 char pspa_pl[MLXSW_REG_PSPA_LEN];
361
362 mlxsw_reg_pspa_pack(pspa_pl, swid, local_port);
363 return mlxsw_reg_write(mlxsw_sp->core, MLXSW_REG(pspa), pspa_pl);
364 }
365
mlxsw_sp_port_vp_mode_set(struct mlxsw_sp_port * mlxsw_sp_port,bool enable)366 int mlxsw_sp_port_vp_mode_set(struct mlxsw_sp_port *mlxsw_sp_port, bool enable)
367 {
368 struct mlxsw_sp *mlxsw_sp = mlxsw_sp_port->mlxsw_sp;
369 char svpe_pl[MLXSW_REG_SVPE_LEN];
370
371 mlxsw_reg_svpe_pack(svpe_pl, mlxsw_sp_port->local_port, enable);
372 return mlxsw_reg_write(mlxsw_sp->core, MLXSW_REG(svpe), svpe_pl);
373 }
374
mlxsw_sp_port_vid_learning_set(struct mlxsw_sp_port * mlxsw_sp_port,u16 vid,bool learn_enable)375 int mlxsw_sp_port_vid_learning_set(struct mlxsw_sp_port *mlxsw_sp_port, u16 vid,
376 bool learn_enable)
377 {
378 struct mlxsw_sp *mlxsw_sp = mlxsw_sp_port->mlxsw_sp;
379 char *spvmlr_pl;
380 int err;
381
382 spvmlr_pl = kmalloc(MLXSW_REG_SPVMLR_LEN, GFP_KERNEL);
383 if (!spvmlr_pl)
384 return -ENOMEM;
385 mlxsw_reg_spvmlr_pack(spvmlr_pl, mlxsw_sp_port->local_port, vid, vid,
386 learn_enable);
387 err = mlxsw_reg_write(mlxsw_sp->core, MLXSW_REG(spvmlr), spvmlr_pl);
388 kfree(spvmlr_pl);
389 return err;
390 }
391
mlxsw_sp_ethtype_to_sver_type(u16 ethtype,u8 * p_sver_type)392 int mlxsw_sp_ethtype_to_sver_type(u16 ethtype, u8 *p_sver_type)
393 {
394 switch (ethtype) {
395 case ETH_P_8021Q:
396 *p_sver_type = 0;
397 break;
398 case ETH_P_8021AD:
399 *p_sver_type = 1;
400 break;
401 default:
402 return -EINVAL;
403 }
404
405 return 0;
406 }
407
mlxsw_sp_port_egress_ethtype_set(struct mlxsw_sp_port * mlxsw_sp_port,u16 ethtype)408 int mlxsw_sp_port_egress_ethtype_set(struct mlxsw_sp_port *mlxsw_sp_port,
409 u16 ethtype)
410 {
411 struct mlxsw_sp *mlxsw_sp = mlxsw_sp_port->mlxsw_sp;
412 char spevet_pl[MLXSW_REG_SPEVET_LEN];
413 u8 sver_type;
414 int err;
415
416 err = mlxsw_sp_ethtype_to_sver_type(ethtype, &sver_type);
417 if (err)
418 return err;
419
420 mlxsw_reg_spevet_pack(spevet_pl, mlxsw_sp_port->local_port, sver_type);
421 return mlxsw_reg_write(mlxsw_sp->core, MLXSW_REG(spevet), spevet_pl);
422 }
423
__mlxsw_sp_port_pvid_set(struct mlxsw_sp_port * mlxsw_sp_port,u16 vid,u16 ethtype)424 static int __mlxsw_sp_port_pvid_set(struct mlxsw_sp_port *mlxsw_sp_port,
425 u16 vid, u16 ethtype)
426 {
427 struct mlxsw_sp *mlxsw_sp = mlxsw_sp_port->mlxsw_sp;
428 char spvid_pl[MLXSW_REG_SPVID_LEN];
429 u8 sver_type;
430 int err;
431
432 err = mlxsw_sp_ethtype_to_sver_type(ethtype, &sver_type);
433 if (err)
434 return err;
435
436 mlxsw_reg_spvid_pack(spvid_pl, mlxsw_sp_port->local_port, vid,
437 sver_type);
438
439 return mlxsw_reg_write(mlxsw_sp->core, MLXSW_REG(spvid), spvid_pl);
440 }
441
mlxsw_sp_port_allow_untagged_set(struct mlxsw_sp_port * mlxsw_sp_port,bool allow)442 static int mlxsw_sp_port_allow_untagged_set(struct mlxsw_sp_port *mlxsw_sp_port,
443 bool allow)
444 {
445 struct mlxsw_sp *mlxsw_sp = mlxsw_sp_port->mlxsw_sp;
446 char spaft_pl[MLXSW_REG_SPAFT_LEN];
447
448 mlxsw_reg_spaft_pack(spaft_pl, mlxsw_sp_port->local_port, allow);
449 return mlxsw_reg_write(mlxsw_sp->core, MLXSW_REG(spaft), spaft_pl);
450 }
451
mlxsw_sp_port_pvid_set(struct mlxsw_sp_port * mlxsw_sp_port,u16 vid,u16 ethtype)452 int mlxsw_sp_port_pvid_set(struct mlxsw_sp_port *mlxsw_sp_port, u16 vid,
453 u16 ethtype)
454 {
455 int err;
456
457 if (!vid) {
458 err = mlxsw_sp_port_allow_untagged_set(mlxsw_sp_port, false);
459 if (err)
460 return err;
461 } else {
462 err = __mlxsw_sp_port_pvid_set(mlxsw_sp_port, vid, ethtype);
463 if (err)
464 return err;
465 err = mlxsw_sp_port_allow_untagged_set(mlxsw_sp_port, true);
466 if (err)
467 goto err_port_allow_untagged_set;
468 }
469
470 mlxsw_sp_port->pvid = vid;
471 return 0;
472
473 err_port_allow_untagged_set:
474 __mlxsw_sp_port_pvid_set(mlxsw_sp_port, mlxsw_sp_port->pvid, ethtype);
475 return err;
476 }
477
478 static int
mlxsw_sp_port_system_port_mapping_set(struct mlxsw_sp_port * mlxsw_sp_port)479 mlxsw_sp_port_system_port_mapping_set(struct mlxsw_sp_port *mlxsw_sp_port)
480 {
481 struct mlxsw_sp *mlxsw_sp = mlxsw_sp_port->mlxsw_sp;
482 char sspr_pl[MLXSW_REG_SSPR_LEN];
483
484 mlxsw_reg_sspr_pack(sspr_pl, mlxsw_sp_port->local_port);
485 return mlxsw_reg_write(mlxsw_sp->core, MLXSW_REG(sspr), sspr_pl);
486 }
487
488 static int
mlxsw_sp_port_module_info_parse(struct mlxsw_sp * mlxsw_sp,u16 local_port,char * pmlp_pl,struct mlxsw_sp_port_mapping * port_mapping)489 mlxsw_sp_port_module_info_parse(struct mlxsw_sp *mlxsw_sp,
490 u16 local_port, char *pmlp_pl,
491 struct mlxsw_sp_port_mapping *port_mapping)
492 {
493 bool separate_rxtx;
494 u8 first_lane;
495 u8 slot_index;
496 u8 module;
497 u8 width;
498 int i;
499
500 module = mlxsw_reg_pmlp_module_get(pmlp_pl, 0);
501 slot_index = mlxsw_reg_pmlp_slot_index_get(pmlp_pl, 0);
502 width = mlxsw_reg_pmlp_width_get(pmlp_pl);
503 separate_rxtx = mlxsw_reg_pmlp_rxtx_get(pmlp_pl);
504 first_lane = mlxsw_reg_pmlp_tx_lane_get(pmlp_pl, 0);
505
506 if (width && !is_power_of_2(width)) {
507 dev_err(mlxsw_sp->bus_info->dev, "Port %d: Unsupported module config: width value is not power of 2\n",
508 local_port);
509 return -EINVAL;
510 }
511
512 for (i = 0; i < width; i++) {
513 if (mlxsw_reg_pmlp_module_get(pmlp_pl, i) != module) {
514 dev_err(mlxsw_sp->bus_info->dev, "Port %d: Unsupported module config: contains multiple modules\n",
515 local_port);
516 return -EINVAL;
517 }
518 if (mlxsw_reg_pmlp_slot_index_get(pmlp_pl, i) != slot_index) {
519 dev_err(mlxsw_sp->bus_info->dev, "Port %d: Unsupported module config: contains multiple slot indexes\n",
520 local_port);
521 return -EINVAL;
522 }
523 if (separate_rxtx &&
524 mlxsw_reg_pmlp_tx_lane_get(pmlp_pl, i) !=
525 mlxsw_reg_pmlp_rx_lane_get(pmlp_pl, i)) {
526 dev_err(mlxsw_sp->bus_info->dev, "Port %d: Unsupported module config: TX and RX lane numbers are different\n",
527 local_port);
528 return -EINVAL;
529 }
530 if (mlxsw_reg_pmlp_tx_lane_get(pmlp_pl, i) != i + first_lane) {
531 dev_err(mlxsw_sp->bus_info->dev, "Port %d: Unsupported module config: TX and RX lane numbers are not sequential\n",
532 local_port);
533 return -EINVAL;
534 }
535 }
536
537 port_mapping->module = module;
538 port_mapping->slot_index = slot_index;
539 port_mapping->width = width;
540 port_mapping->module_width = width;
541 port_mapping->lane = mlxsw_reg_pmlp_tx_lane_get(pmlp_pl, 0);
542 return 0;
543 }
544
545 static int
mlxsw_sp_port_module_info_get(struct mlxsw_sp * mlxsw_sp,u16 local_port,struct mlxsw_sp_port_mapping * port_mapping)546 mlxsw_sp_port_module_info_get(struct mlxsw_sp *mlxsw_sp, u16 local_port,
547 struct mlxsw_sp_port_mapping *port_mapping)
548 {
549 char pmlp_pl[MLXSW_REG_PMLP_LEN];
550 int err;
551
552 mlxsw_reg_pmlp_pack(pmlp_pl, local_port);
553 err = mlxsw_reg_query(mlxsw_sp->core, MLXSW_REG(pmlp), pmlp_pl);
554 if (err)
555 return err;
556 return mlxsw_sp_port_module_info_parse(mlxsw_sp, local_port,
557 pmlp_pl, port_mapping);
558 }
559
560 static int
mlxsw_sp_port_module_map(struct mlxsw_sp * mlxsw_sp,u16 local_port,const struct mlxsw_sp_port_mapping * port_mapping)561 mlxsw_sp_port_module_map(struct mlxsw_sp *mlxsw_sp, u16 local_port,
562 const struct mlxsw_sp_port_mapping *port_mapping)
563 {
564 char pmlp_pl[MLXSW_REG_PMLP_LEN];
565 int i, err;
566
567 mlxsw_env_module_port_map(mlxsw_sp->core, port_mapping->slot_index,
568 port_mapping->module);
569
570 mlxsw_reg_pmlp_pack(pmlp_pl, local_port);
571 mlxsw_reg_pmlp_width_set(pmlp_pl, port_mapping->width);
572 for (i = 0; i < port_mapping->width; i++) {
573 mlxsw_reg_pmlp_slot_index_set(pmlp_pl, i,
574 port_mapping->slot_index);
575 mlxsw_reg_pmlp_module_set(pmlp_pl, i, port_mapping->module);
576 mlxsw_reg_pmlp_tx_lane_set(pmlp_pl, i, port_mapping->lane + i); /* Rx & Tx */
577 }
578
579 err = mlxsw_reg_write(mlxsw_sp->core, MLXSW_REG(pmlp), pmlp_pl);
580 if (err)
581 goto err_pmlp_write;
582 return 0;
583
584 err_pmlp_write:
585 mlxsw_env_module_port_unmap(mlxsw_sp->core, port_mapping->slot_index,
586 port_mapping->module);
587 return err;
588 }
589
mlxsw_sp_port_module_unmap(struct mlxsw_sp * mlxsw_sp,u16 local_port,u8 slot_index,u8 module)590 static void mlxsw_sp_port_module_unmap(struct mlxsw_sp *mlxsw_sp, u16 local_port,
591 u8 slot_index, u8 module)
592 {
593 char pmlp_pl[MLXSW_REG_PMLP_LEN];
594
595 mlxsw_reg_pmlp_pack(pmlp_pl, local_port);
596 mlxsw_reg_pmlp_width_set(pmlp_pl, 0);
597 mlxsw_reg_write(mlxsw_sp->core, MLXSW_REG(pmlp), pmlp_pl);
598 mlxsw_env_module_port_unmap(mlxsw_sp->core, slot_index, module);
599 }
600
mlxsw_sp_port_open(struct net_device * dev)601 static int mlxsw_sp_port_open(struct net_device *dev)
602 {
603 struct mlxsw_sp_port *mlxsw_sp_port = netdev_priv(dev);
604 struct mlxsw_sp *mlxsw_sp = mlxsw_sp_port->mlxsw_sp;
605 int err;
606
607 err = mlxsw_env_module_port_up(mlxsw_sp->core,
608 mlxsw_sp_port->mapping.slot_index,
609 mlxsw_sp_port->mapping.module);
610 if (err)
611 return err;
612 err = mlxsw_sp_port_admin_status_set(mlxsw_sp_port, true);
613 if (err)
614 goto err_port_admin_status_set;
615 netif_start_queue(dev);
616 return 0;
617
618 err_port_admin_status_set:
619 mlxsw_env_module_port_down(mlxsw_sp->core,
620 mlxsw_sp_port->mapping.slot_index,
621 mlxsw_sp_port->mapping.module);
622 return err;
623 }
624
mlxsw_sp_port_stop(struct net_device * dev)625 static int mlxsw_sp_port_stop(struct net_device *dev)
626 {
627 struct mlxsw_sp_port *mlxsw_sp_port = netdev_priv(dev);
628 struct mlxsw_sp *mlxsw_sp = mlxsw_sp_port->mlxsw_sp;
629
630 netif_stop_queue(dev);
631 mlxsw_sp_port_admin_status_set(mlxsw_sp_port, false);
632 mlxsw_env_module_port_down(mlxsw_sp->core,
633 mlxsw_sp_port->mapping.slot_index,
634 mlxsw_sp_port->mapping.module);
635 return 0;
636 }
637
mlxsw_sp_port_xmit(struct sk_buff * skb,struct net_device * dev)638 static netdev_tx_t mlxsw_sp_port_xmit(struct sk_buff *skb,
639 struct net_device *dev)
640 {
641 struct mlxsw_sp_port *mlxsw_sp_port = netdev_priv(dev);
642 struct mlxsw_sp *mlxsw_sp = mlxsw_sp_port->mlxsw_sp;
643 struct mlxsw_sp_port_pcpu_stats *pcpu_stats;
644 const struct mlxsw_tx_info tx_info = {
645 .local_port = mlxsw_sp_port->local_port,
646 .is_emad = false,
647 };
648 u64 len;
649 int err;
650
651 if (skb_cow_head(skb, MLXSW_TXHDR_LEN)) {
652 this_cpu_inc(mlxsw_sp_port->pcpu_stats->tx_dropped);
653 dev_kfree_skb_any(skb);
654 return NETDEV_TX_OK;
655 }
656
657 memset(skb->cb, 0, sizeof(struct mlxsw_skb_cb));
658
659 if (mlxsw_core_skb_transmit_busy(mlxsw_sp->core, &tx_info))
660 return NETDEV_TX_BUSY;
661
662 if (eth_skb_pad(skb)) {
663 this_cpu_inc(mlxsw_sp_port->pcpu_stats->tx_dropped);
664 return NETDEV_TX_OK;
665 }
666
667 mlxsw_sp_txhdr_construct(skb, &tx_info);
668 /* TX header is consumed by HW on the way so we shouldn't count its
669 * bytes as being sent.
670 */
671 len = skb->len - MLXSW_TXHDR_LEN;
672
673 /* Due to a race we might fail here because of a full queue. In that
674 * unlikely case we simply drop the packet.
675 */
676 err = mlxsw_core_skb_transmit(mlxsw_sp->core, skb, &tx_info);
677
678 if (!err) {
679 pcpu_stats = this_cpu_ptr(mlxsw_sp_port->pcpu_stats);
680 u64_stats_update_begin(&pcpu_stats->syncp);
681 pcpu_stats->tx_packets++;
682 pcpu_stats->tx_bytes += len;
683 u64_stats_update_end(&pcpu_stats->syncp);
684 } else {
685 this_cpu_inc(mlxsw_sp_port->pcpu_stats->tx_dropped);
686 dev_kfree_skb_any(skb);
687 }
688 return NETDEV_TX_OK;
689 }
690
mlxsw_sp_set_rx_mode(struct net_device * dev)691 static void mlxsw_sp_set_rx_mode(struct net_device *dev)
692 {
693 }
694
mlxsw_sp_port_set_mac_address(struct net_device * dev,void * p)695 static int mlxsw_sp_port_set_mac_address(struct net_device *dev, void *p)
696 {
697 struct mlxsw_sp_port *mlxsw_sp_port = netdev_priv(dev);
698 struct sockaddr *addr = p;
699 int err;
700
701 if (!is_valid_ether_addr(addr->sa_data))
702 return -EADDRNOTAVAIL;
703
704 err = mlxsw_sp_port_dev_addr_set(mlxsw_sp_port, addr->sa_data);
705 if (err)
706 return err;
707 eth_hw_addr_set(dev, addr->sa_data);
708 return 0;
709 }
710
mlxsw_sp_port_change_mtu(struct net_device * dev,int mtu)711 static int mlxsw_sp_port_change_mtu(struct net_device *dev, int mtu)
712 {
713 struct mlxsw_sp_port *mlxsw_sp_port = netdev_priv(dev);
714 struct mlxsw_sp_hdroom orig_hdroom;
715 struct mlxsw_sp_hdroom hdroom;
716 int err;
717
718 orig_hdroom = *mlxsw_sp_port->hdroom;
719
720 hdroom = orig_hdroom;
721 hdroom.mtu = mtu;
722 mlxsw_sp_hdroom_bufs_reset_sizes(mlxsw_sp_port, &hdroom);
723
724 err = mlxsw_sp_hdroom_configure(mlxsw_sp_port, &hdroom);
725 if (err) {
726 netdev_err(dev, "Failed to configure port's headroom\n");
727 return err;
728 }
729
730 err = mlxsw_sp_port_mtu_set(mlxsw_sp_port, mtu);
731 if (err)
732 goto err_port_mtu_set;
733 dev->mtu = mtu;
734 return 0;
735
736 err_port_mtu_set:
737 mlxsw_sp_hdroom_configure(mlxsw_sp_port, &orig_hdroom);
738 return err;
739 }
740
741 static int
mlxsw_sp_port_get_sw_stats64(const struct net_device * dev,struct rtnl_link_stats64 * stats)742 mlxsw_sp_port_get_sw_stats64(const struct net_device *dev,
743 struct rtnl_link_stats64 *stats)
744 {
745 struct mlxsw_sp_port *mlxsw_sp_port = netdev_priv(dev);
746 struct mlxsw_sp_port_pcpu_stats *p;
747 u64 rx_packets, rx_bytes, tx_packets, tx_bytes;
748 u32 tx_dropped = 0;
749 unsigned int start;
750 int i;
751
752 for_each_possible_cpu(i) {
753 p = per_cpu_ptr(mlxsw_sp_port->pcpu_stats, i);
754 do {
755 start = u64_stats_fetch_begin_irq(&p->syncp);
756 rx_packets = p->rx_packets;
757 rx_bytes = p->rx_bytes;
758 tx_packets = p->tx_packets;
759 tx_bytes = p->tx_bytes;
760 } while (u64_stats_fetch_retry_irq(&p->syncp, start));
761
762 stats->rx_packets += rx_packets;
763 stats->rx_bytes += rx_bytes;
764 stats->tx_packets += tx_packets;
765 stats->tx_bytes += tx_bytes;
766 /* tx_dropped is u32, updated without syncp protection. */
767 tx_dropped += p->tx_dropped;
768 }
769 stats->tx_dropped = tx_dropped;
770 return 0;
771 }
772
mlxsw_sp_port_has_offload_stats(const struct net_device * dev,int attr_id)773 static bool mlxsw_sp_port_has_offload_stats(const struct net_device *dev, int attr_id)
774 {
775 switch (attr_id) {
776 case IFLA_OFFLOAD_XSTATS_CPU_HIT:
777 return true;
778 }
779
780 return false;
781 }
782
mlxsw_sp_port_get_offload_stats(int attr_id,const struct net_device * dev,void * sp)783 static int mlxsw_sp_port_get_offload_stats(int attr_id, const struct net_device *dev,
784 void *sp)
785 {
786 switch (attr_id) {
787 case IFLA_OFFLOAD_XSTATS_CPU_HIT:
788 return mlxsw_sp_port_get_sw_stats64(dev, sp);
789 }
790
791 return -EINVAL;
792 }
793
mlxsw_sp_port_get_stats_raw(struct net_device * dev,int grp,int prio,char * ppcnt_pl)794 int mlxsw_sp_port_get_stats_raw(struct net_device *dev, int grp,
795 int prio, char *ppcnt_pl)
796 {
797 struct mlxsw_sp_port *mlxsw_sp_port = netdev_priv(dev);
798 struct mlxsw_sp *mlxsw_sp = mlxsw_sp_port->mlxsw_sp;
799
800 mlxsw_reg_ppcnt_pack(ppcnt_pl, mlxsw_sp_port->local_port, grp, prio);
801 return mlxsw_reg_query(mlxsw_sp->core, MLXSW_REG(ppcnt), ppcnt_pl);
802 }
803
mlxsw_sp_port_get_hw_stats(struct net_device * dev,struct rtnl_link_stats64 * stats)804 static int mlxsw_sp_port_get_hw_stats(struct net_device *dev,
805 struct rtnl_link_stats64 *stats)
806 {
807 char ppcnt_pl[MLXSW_REG_PPCNT_LEN];
808 int err;
809
810 err = mlxsw_sp_port_get_stats_raw(dev, MLXSW_REG_PPCNT_IEEE_8023_CNT,
811 0, ppcnt_pl);
812 if (err)
813 goto out;
814
815 stats->tx_packets =
816 mlxsw_reg_ppcnt_a_frames_transmitted_ok_get(ppcnt_pl);
817 stats->rx_packets =
818 mlxsw_reg_ppcnt_a_frames_received_ok_get(ppcnt_pl);
819 stats->tx_bytes =
820 mlxsw_reg_ppcnt_a_octets_transmitted_ok_get(ppcnt_pl);
821 stats->rx_bytes =
822 mlxsw_reg_ppcnt_a_octets_received_ok_get(ppcnt_pl);
823 stats->multicast =
824 mlxsw_reg_ppcnt_a_multicast_frames_received_ok_get(ppcnt_pl);
825
826 stats->rx_crc_errors =
827 mlxsw_reg_ppcnt_a_frame_check_sequence_errors_get(ppcnt_pl);
828 stats->rx_frame_errors =
829 mlxsw_reg_ppcnt_a_alignment_errors_get(ppcnt_pl);
830
831 stats->rx_length_errors = (
832 mlxsw_reg_ppcnt_a_in_range_length_errors_get(ppcnt_pl) +
833 mlxsw_reg_ppcnt_a_out_of_range_length_field_get(ppcnt_pl) +
834 mlxsw_reg_ppcnt_a_frame_too_long_errors_get(ppcnt_pl));
835
836 stats->rx_errors = (stats->rx_crc_errors +
837 stats->rx_frame_errors + stats->rx_length_errors);
838
839 out:
840 return err;
841 }
842
843 static void
mlxsw_sp_port_get_hw_xstats(struct net_device * dev,struct mlxsw_sp_port_xstats * xstats)844 mlxsw_sp_port_get_hw_xstats(struct net_device *dev,
845 struct mlxsw_sp_port_xstats *xstats)
846 {
847 char ppcnt_pl[MLXSW_REG_PPCNT_LEN];
848 int err, i;
849
850 err = mlxsw_sp_port_get_stats_raw(dev, MLXSW_REG_PPCNT_EXT_CNT, 0,
851 ppcnt_pl);
852 if (!err)
853 xstats->ecn = mlxsw_reg_ppcnt_ecn_marked_get(ppcnt_pl);
854
855 for (i = 0; i < TC_MAX_QUEUE; i++) {
856 err = mlxsw_sp_port_get_stats_raw(dev,
857 MLXSW_REG_PPCNT_TC_CONG_CNT,
858 i, ppcnt_pl);
859 if (err)
860 goto tc_cnt;
861
862 xstats->wred_drop[i] =
863 mlxsw_reg_ppcnt_wred_discard_get(ppcnt_pl);
864 xstats->tc_ecn[i] = mlxsw_reg_ppcnt_ecn_marked_tc_get(ppcnt_pl);
865
866 tc_cnt:
867 err = mlxsw_sp_port_get_stats_raw(dev, MLXSW_REG_PPCNT_TC_CNT,
868 i, ppcnt_pl);
869 if (err)
870 continue;
871
872 xstats->backlog[i] =
873 mlxsw_reg_ppcnt_tc_transmit_queue_get(ppcnt_pl);
874 xstats->tail_drop[i] =
875 mlxsw_reg_ppcnt_tc_no_buffer_discard_uc_get(ppcnt_pl);
876 }
877
878 for (i = 0; i < IEEE_8021QAZ_MAX_TCS; i++) {
879 err = mlxsw_sp_port_get_stats_raw(dev, MLXSW_REG_PPCNT_PRIO_CNT,
880 i, ppcnt_pl);
881 if (err)
882 continue;
883
884 xstats->tx_packets[i] = mlxsw_reg_ppcnt_tx_frames_get(ppcnt_pl);
885 xstats->tx_bytes[i] = mlxsw_reg_ppcnt_tx_octets_get(ppcnt_pl);
886 }
887 }
888
update_stats_cache(struct work_struct * work)889 static void update_stats_cache(struct work_struct *work)
890 {
891 struct mlxsw_sp_port *mlxsw_sp_port =
892 container_of(work, struct mlxsw_sp_port,
893 periodic_hw_stats.update_dw.work);
894
895 if (!netif_carrier_ok(mlxsw_sp_port->dev))
896 /* Note: mlxsw_sp_port_down_wipe_counters() clears the cache as
897 * necessary when port goes down.
898 */
899 goto out;
900
901 mlxsw_sp_port_get_hw_stats(mlxsw_sp_port->dev,
902 &mlxsw_sp_port->periodic_hw_stats.stats);
903 mlxsw_sp_port_get_hw_xstats(mlxsw_sp_port->dev,
904 &mlxsw_sp_port->periodic_hw_stats.xstats);
905
906 out:
907 mlxsw_core_schedule_dw(&mlxsw_sp_port->periodic_hw_stats.update_dw,
908 MLXSW_HW_STATS_UPDATE_TIME);
909 }
910
911 /* Return the stats from a cache that is updated periodically,
912 * as this function might get called in an atomic context.
913 */
914 static void
mlxsw_sp_port_get_stats64(struct net_device * dev,struct rtnl_link_stats64 * stats)915 mlxsw_sp_port_get_stats64(struct net_device *dev,
916 struct rtnl_link_stats64 *stats)
917 {
918 struct mlxsw_sp_port *mlxsw_sp_port = netdev_priv(dev);
919
920 memcpy(stats, &mlxsw_sp_port->periodic_hw_stats.stats, sizeof(*stats));
921 }
922
__mlxsw_sp_port_vlan_set(struct mlxsw_sp_port * mlxsw_sp_port,u16 vid_begin,u16 vid_end,bool is_member,bool untagged)923 static int __mlxsw_sp_port_vlan_set(struct mlxsw_sp_port *mlxsw_sp_port,
924 u16 vid_begin, u16 vid_end,
925 bool is_member, bool untagged)
926 {
927 struct mlxsw_sp *mlxsw_sp = mlxsw_sp_port->mlxsw_sp;
928 char *spvm_pl;
929 int err;
930
931 spvm_pl = kmalloc(MLXSW_REG_SPVM_LEN, GFP_KERNEL);
932 if (!spvm_pl)
933 return -ENOMEM;
934
935 mlxsw_reg_spvm_pack(spvm_pl, mlxsw_sp_port->local_port, vid_begin,
936 vid_end, is_member, untagged);
937 err = mlxsw_reg_write(mlxsw_sp->core, MLXSW_REG(spvm), spvm_pl);
938 kfree(spvm_pl);
939 return err;
940 }
941
mlxsw_sp_port_vlan_set(struct mlxsw_sp_port * mlxsw_sp_port,u16 vid_begin,u16 vid_end,bool is_member,bool untagged)942 int mlxsw_sp_port_vlan_set(struct mlxsw_sp_port *mlxsw_sp_port, u16 vid_begin,
943 u16 vid_end, bool is_member, bool untagged)
944 {
945 u16 vid, vid_e;
946 int err;
947
948 for (vid = vid_begin; vid <= vid_end;
949 vid += MLXSW_REG_SPVM_REC_MAX_COUNT) {
950 vid_e = min((u16) (vid + MLXSW_REG_SPVM_REC_MAX_COUNT - 1),
951 vid_end);
952
953 err = __mlxsw_sp_port_vlan_set(mlxsw_sp_port, vid, vid_e,
954 is_member, untagged);
955 if (err)
956 return err;
957 }
958
959 return 0;
960 }
961
mlxsw_sp_port_vlan_flush(struct mlxsw_sp_port * mlxsw_sp_port,bool flush_default)962 static void mlxsw_sp_port_vlan_flush(struct mlxsw_sp_port *mlxsw_sp_port,
963 bool flush_default)
964 {
965 struct mlxsw_sp_port_vlan *mlxsw_sp_port_vlan, *tmp;
966
967 list_for_each_entry_safe(mlxsw_sp_port_vlan, tmp,
968 &mlxsw_sp_port->vlans_list, list) {
969 if (!flush_default &&
970 mlxsw_sp_port_vlan->vid == MLXSW_SP_DEFAULT_VID)
971 continue;
972 mlxsw_sp_port_vlan_destroy(mlxsw_sp_port_vlan);
973 }
974 }
975
976 static void
mlxsw_sp_port_vlan_cleanup(struct mlxsw_sp_port_vlan * mlxsw_sp_port_vlan)977 mlxsw_sp_port_vlan_cleanup(struct mlxsw_sp_port_vlan *mlxsw_sp_port_vlan)
978 {
979 if (mlxsw_sp_port_vlan->bridge_port)
980 mlxsw_sp_port_vlan_bridge_leave(mlxsw_sp_port_vlan);
981 else if (mlxsw_sp_port_vlan->fid)
982 mlxsw_sp_port_vlan_router_leave(mlxsw_sp_port_vlan);
983 }
984
985 struct mlxsw_sp_port_vlan *
mlxsw_sp_port_vlan_create(struct mlxsw_sp_port * mlxsw_sp_port,u16 vid)986 mlxsw_sp_port_vlan_create(struct mlxsw_sp_port *mlxsw_sp_port, u16 vid)
987 {
988 struct mlxsw_sp_port_vlan *mlxsw_sp_port_vlan;
989 bool untagged = vid == MLXSW_SP_DEFAULT_VID;
990 int err;
991
992 mlxsw_sp_port_vlan = mlxsw_sp_port_vlan_find_by_vid(mlxsw_sp_port, vid);
993 if (mlxsw_sp_port_vlan)
994 return ERR_PTR(-EEXIST);
995
996 err = mlxsw_sp_port_vlan_set(mlxsw_sp_port, vid, vid, true, untagged);
997 if (err)
998 return ERR_PTR(err);
999
1000 mlxsw_sp_port_vlan = kzalloc(sizeof(*mlxsw_sp_port_vlan), GFP_KERNEL);
1001 if (!mlxsw_sp_port_vlan) {
1002 err = -ENOMEM;
1003 goto err_port_vlan_alloc;
1004 }
1005
1006 mlxsw_sp_port_vlan->mlxsw_sp_port = mlxsw_sp_port;
1007 mlxsw_sp_port_vlan->vid = vid;
1008 list_add(&mlxsw_sp_port_vlan->list, &mlxsw_sp_port->vlans_list);
1009
1010 return mlxsw_sp_port_vlan;
1011
1012 err_port_vlan_alloc:
1013 mlxsw_sp_port_vlan_set(mlxsw_sp_port, vid, vid, false, false);
1014 return ERR_PTR(err);
1015 }
1016
mlxsw_sp_port_vlan_destroy(struct mlxsw_sp_port_vlan * mlxsw_sp_port_vlan)1017 void mlxsw_sp_port_vlan_destroy(struct mlxsw_sp_port_vlan *mlxsw_sp_port_vlan)
1018 {
1019 struct mlxsw_sp_port *mlxsw_sp_port = mlxsw_sp_port_vlan->mlxsw_sp_port;
1020 u16 vid = mlxsw_sp_port_vlan->vid;
1021
1022 mlxsw_sp_port_vlan_cleanup(mlxsw_sp_port_vlan);
1023 list_del(&mlxsw_sp_port_vlan->list);
1024 kfree(mlxsw_sp_port_vlan);
1025 mlxsw_sp_port_vlan_set(mlxsw_sp_port, vid, vid, false, false);
1026 }
1027
mlxsw_sp_port_add_vid(struct net_device * dev,__be16 __always_unused proto,u16 vid)1028 static int mlxsw_sp_port_add_vid(struct net_device *dev,
1029 __be16 __always_unused proto, u16 vid)
1030 {
1031 struct mlxsw_sp_port *mlxsw_sp_port = netdev_priv(dev);
1032
1033 /* VLAN 0 is added to HW filter when device goes up, but it is
1034 * reserved in our case, so simply return.
1035 */
1036 if (!vid)
1037 return 0;
1038
1039 return PTR_ERR_OR_ZERO(mlxsw_sp_port_vlan_create(mlxsw_sp_port, vid));
1040 }
1041
mlxsw_sp_port_kill_vid(struct net_device * dev,__be16 __always_unused proto,u16 vid)1042 static int mlxsw_sp_port_kill_vid(struct net_device *dev,
1043 __be16 __always_unused proto, u16 vid)
1044 {
1045 struct mlxsw_sp_port *mlxsw_sp_port = netdev_priv(dev);
1046 struct mlxsw_sp_port_vlan *mlxsw_sp_port_vlan;
1047
1048 /* VLAN 0 is removed from HW filter when device goes down, but
1049 * it is reserved in our case, so simply return.
1050 */
1051 if (!vid)
1052 return 0;
1053
1054 mlxsw_sp_port_vlan = mlxsw_sp_port_vlan_find_by_vid(mlxsw_sp_port, vid);
1055 if (!mlxsw_sp_port_vlan)
1056 return 0;
1057 mlxsw_sp_port_vlan_destroy(mlxsw_sp_port_vlan);
1058
1059 return 0;
1060 }
1061
mlxsw_sp_setup_tc_block(struct mlxsw_sp_port * mlxsw_sp_port,struct flow_block_offload * f)1062 static int mlxsw_sp_setup_tc_block(struct mlxsw_sp_port *mlxsw_sp_port,
1063 struct flow_block_offload *f)
1064 {
1065 switch (f->binder_type) {
1066 case FLOW_BLOCK_BINDER_TYPE_CLSACT_INGRESS:
1067 return mlxsw_sp_setup_tc_block_clsact(mlxsw_sp_port, f, true);
1068 case FLOW_BLOCK_BINDER_TYPE_CLSACT_EGRESS:
1069 return mlxsw_sp_setup_tc_block_clsact(mlxsw_sp_port, f, false);
1070 case FLOW_BLOCK_BINDER_TYPE_RED_EARLY_DROP:
1071 return mlxsw_sp_setup_tc_block_qevent_early_drop(mlxsw_sp_port, f);
1072 case FLOW_BLOCK_BINDER_TYPE_RED_MARK:
1073 return mlxsw_sp_setup_tc_block_qevent_mark(mlxsw_sp_port, f);
1074 default:
1075 return -EOPNOTSUPP;
1076 }
1077 }
1078
mlxsw_sp_setup_tc(struct net_device * dev,enum tc_setup_type type,void * type_data)1079 static int mlxsw_sp_setup_tc(struct net_device *dev, enum tc_setup_type type,
1080 void *type_data)
1081 {
1082 struct mlxsw_sp_port *mlxsw_sp_port = netdev_priv(dev);
1083
1084 switch (type) {
1085 case TC_SETUP_BLOCK:
1086 return mlxsw_sp_setup_tc_block(mlxsw_sp_port, type_data);
1087 case TC_SETUP_QDISC_RED:
1088 return mlxsw_sp_setup_tc_red(mlxsw_sp_port, type_data);
1089 case TC_SETUP_QDISC_PRIO:
1090 return mlxsw_sp_setup_tc_prio(mlxsw_sp_port, type_data);
1091 case TC_SETUP_QDISC_ETS:
1092 return mlxsw_sp_setup_tc_ets(mlxsw_sp_port, type_data);
1093 case TC_SETUP_QDISC_TBF:
1094 return mlxsw_sp_setup_tc_tbf(mlxsw_sp_port, type_data);
1095 case TC_SETUP_QDISC_FIFO:
1096 return mlxsw_sp_setup_tc_fifo(mlxsw_sp_port, type_data);
1097 default:
1098 return -EOPNOTSUPP;
1099 }
1100 }
1101
mlxsw_sp_feature_hw_tc(struct net_device * dev,bool enable)1102 static int mlxsw_sp_feature_hw_tc(struct net_device *dev, bool enable)
1103 {
1104 struct mlxsw_sp_port *mlxsw_sp_port = netdev_priv(dev);
1105
1106 if (!enable) {
1107 if (mlxsw_sp_flow_block_rule_count(mlxsw_sp_port->ing_flow_block) ||
1108 mlxsw_sp_flow_block_rule_count(mlxsw_sp_port->eg_flow_block)) {
1109 netdev_err(dev, "Active offloaded tc filters, can't turn hw_tc_offload off\n");
1110 return -EINVAL;
1111 }
1112 mlxsw_sp_flow_block_disable_inc(mlxsw_sp_port->ing_flow_block);
1113 mlxsw_sp_flow_block_disable_inc(mlxsw_sp_port->eg_flow_block);
1114 } else {
1115 mlxsw_sp_flow_block_disable_dec(mlxsw_sp_port->ing_flow_block);
1116 mlxsw_sp_flow_block_disable_dec(mlxsw_sp_port->eg_flow_block);
1117 }
1118 return 0;
1119 }
1120
mlxsw_sp_feature_loopback(struct net_device * dev,bool enable)1121 static int mlxsw_sp_feature_loopback(struct net_device *dev, bool enable)
1122 {
1123 struct mlxsw_sp_port *mlxsw_sp_port = netdev_priv(dev);
1124 char pplr_pl[MLXSW_REG_PPLR_LEN];
1125 int err;
1126
1127 if (netif_running(dev))
1128 mlxsw_sp_port_admin_status_set(mlxsw_sp_port, false);
1129
1130 mlxsw_reg_pplr_pack(pplr_pl, mlxsw_sp_port->local_port, enable);
1131 err = mlxsw_reg_write(mlxsw_sp_port->mlxsw_sp->core, MLXSW_REG(pplr),
1132 pplr_pl);
1133
1134 if (netif_running(dev))
1135 mlxsw_sp_port_admin_status_set(mlxsw_sp_port, true);
1136
1137 return err;
1138 }
1139
1140 typedef int (*mlxsw_sp_feature_handler)(struct net_device *dev, bool enable);
1141
mlxsw_sp_handle_feature(struct net_device * dev,netdev_features_t wanted_features,netdev_features_t feature,mlxsw_sp_feature_handler feature_handler)1142 static int mlxsw_sp_handle_feature(struct net_device *dev,
1143 netdev_features_t wanted_features,
1144 netdev_features_t feature,
1145 mlxsw_sp_feature_handler feature_handler)
1146 {
1147 netdev_features_t changes = wanted_features ^ dev->features;
1148 bool enable = !!(wanted_features & feature);
1149 int err;
1150
1151 if (!(changes & feature))
1152 return 0;
1153
1154 err = feature_handler(dev, enable);
1155 if (err) {
1156 netdev_err(dev, "%s feature %pNF failed, err %d\n",
1157 enable ? "Enable" : "Disable", &feature, err);
1158 return err;
1159 }
1160
1161 if (enable)
1162 dev->features |= feature;
1163 else
1164 dev->features &= ~feature;
1165
1166 return 0;
1167 }
mlxsw_sp_set_features(struct net_device * dev,netdev_features_t features)1168 static int mlxsw_sp_set_features(struct net_device *dev,
1169 netdev_features_t features)
1170 {
1171 netdev_features_t oper_features = dev->features;
1172 int err = 0;
1173
1174 err |= mlxsw_sp_handle_feature(dev, features, NETIF_F_HW_TC,
1175 mlxsw_sp_feature_hw_tc);
1176 err |= mlxsw_sp_handle_feature(dev, features, NETIF_F_LOOPBACK,
1177 mlxsw_sp_feature_loopback);
1178
1179 if (err) {
1180 dev->features = oper_features;
1181 return -EINVAL;
1182 }
1183
1184 return 0;
1185 }
1186
1187 static struct devlink_port *
mlxsw_sp_port_get_devlink_port(struct net_device * dev)1188 mlxsw_sp_port_get_devlink_port(struct net_device *dev)
1189 {
1190 struct mlxsw_sp_port *mlxsw_sp_port = netdev_priv(dev);
1191 struct mlxsw_sp *mlxsw_sp = mlxsw_sp_port->mlxsw_sp;
1192
1193 return mlxsw_core_port_devlink_port_get(mlxsw_sp->core,
1194 mlxsw_sp_port->local_port);
1195 }
1196
mlxsw_sp_port_hwtstamp_set(struct mlxsw_sp_port * mlxsw_sp_port,struct ifreq * ifr)1197 static int mlxsw_sp_port_hwtstamp_set(struct mlxsw_sp_port *mlxsw_sp_port,
1198 struct ifreq *ifr)
1199 {
1200 struct hwtstamp_config config;
1201 int err;
1202
1203 if (copy_from_user(&config, ifr->ifr_data, sizeof(config)))
1204 return -EFAULT;
1205
1206 err = mlxsw_sp_port->mlxsw_sp->ptp_ops->hwtstamp_set(mlxsw_sp_port,
1207 &config);
1208 if (err)
1209 return err;
1210
1211 if (copy_to_user(ifr->ifr_data, &config, sizeof(config)))
1212 return -EFAULT;
1213
1214 return 0;
1215 }
1216
mlxsw_sp_port_hwtstamp_get(struct mlxsw_sp_port * mlxsw_sp_port,struct ifreq * ifr)1217 static int mlxsw_sp_port_hwtstamp_get(struct mlxsw_sp_port *mlxsw_sp_port,
1218 struct ifreq *ifr)
1219 {
1220 struct hwtstamp_config config;
1221 int err;
1222
1223 err = mlxsw_sp_port->mlxsw_sp->ptp_ops->hwtstamp_get(mlxsw_sp_port,
1224 &config);
1225 if (err)
1226 return err;
1227
1228 if (copy_to_user(ifr->ifr_data, &config, sizeof(config)))
1229 return -EFAULT;
1230
1231 return 0;
1232 }
1233
mlxsw_sp_port_ptp_clear(struct mlxsw_sp_port * mlxsw_sp_port)1234 static inline void mlxsw_sp_port_ptp_clear(struct mlxsw_sp_port *mlxsw_sp_port)
1235 {
1236 struct hwtstamp_config config = {0};
1237
1238 mlxsw_sp_port->mlxsw_sp->ptp_ops->hwtstamp_set(mlxsw_sp_port, &config);
1239 }
1240
1241 static int
mlxsw_sp_port_ioctl(struct net_device * dev,struct ifreq * ifr,int cmd)1242 mlxsw_sp_port_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
1243 {
1244 struct mlxsw_sp_port *mlxsw_sp_port = netdev_priv(dev);
1245
1246 switch (cmd) {
1247 case SIOCSHWTSTAMP:
1248 return mlxsw_sp_port_hwtstamp_set(mlxsw_sp_port, ifr);
1249 case SIOCGHWTSTAMP:
1250 return mlxsw_sp_port_hwtstamp_get(mlxsw_sp_port, ifr);
1251 default:
1252 return -EOPNOTSUPP;
1253 }
1254 }
1255
1256 static const struct net_device_ops mlxsw_sp_port_netdev_ops = {
1257 .ndo_open = mlxsw_sp_port_open,
1258 .ndo_stop = mlxsw_sp_port_stop,
1259 .ndo_start_xmit = mlxsw_sp_port_xmit,
1260 .ndo_setup_tc = mlxsw_sp_setup_tc,
1261 .ndo_set_rx_mode = mlxsw_sp_set_rx_mode,
1262 .ndo_set_mac_address = mlxsw_sp_port_set_mac_address,
1263 .ndo_change_mtu = mlxsw_sp_port_change_mtu,
1264 .ndo_get_stats64 = mlxsw_sp_port_get_stats64,
1265 .ndo_has_offload_stats = mlxsw_sp_port_has_offload_stats,
1266 .ndo_get_offload_stats = mlxsw_sp_port_get_offload_stats,
1267 .ndo_vlan_rx_add_vid = mlxsw_sp_port_add_vid,
1268 .ndo_vlan_rx_kill_vid = mlxsw_sp_port_kill_vid,
1269 .ndo_set_features = mlxsw_sp_set_features,
1270 .ndo_get_devlink_port = mlxsw_sp_port_get_devlink_port,
1271 .ndo_eth_ioctl = mlxsw_sp_port_ioctl,
1272 };
1273
1274 static int
mlxsw_sp_port_speed_by_width_set(struct mlxsw_sp_port * mlxsw_sp_port)1275 mlxsw_sp_port_speed_by_width_set(struct mlxsw_sp_port *mlxsw_sp_port)
1276 {
1277 struct mlxsw_sp *mlxsw_sp = mlxsw_sp_port->mlxsw_sp;
1278 u32 eth_proto_cap, eth_proto_admin, eth_proto_oper;
1279 const struct mlxsw_sp_port_type_speed_ops *ops;
1280 char ptys_pl[MLXSW_REG_PTYS_LEN];
1281 u32 eth_proto_cap_masked;
1282 int err;
1283
1284 ops = mlxsw_sp->port_type_speed_ops;
1285
1286 /* Set advertised speeds to speeds supported by both the driver
1287 * and the device.
1288 */
1289 ops->reg_ptys_eth_pack(mlxsw_sp, ptys_pl, mlxsw_sp_port->local_port,
1290 0, false);
1291 err = mlxsw_reg_query(mlxsw_sp->core, MLXSW_REG(ptys), ptys_pl);
1292 if (err)
1293 return err;
1294
1295 ops->reg_ptys_eth_unpack(mlxsw_sp, ptys_pl, ð_proto_cap,
1296 ð_proto_admin, ð_proto_oper);
1297 eth_proto_cap_masked = ops->ptys_proto_cap_masked_get(eth_proto_cap);
1298 ops->reg_ptys_eth_pack(mlxsw_sp, ptys_pl, mlxsw_sp_port->local_port,
1299 eth_proto_cap_masked,
1300 mlxsw_sp_port->link.autoneg);
1301 return mlxsw_reg_write(mlxsw_sp->core, MLXSW_REG(ptys), ptys_pl);
1302 }
1303
mlxsw_sp_port_speed_get(struct mlxsw_sp_port * mlxsw_sp_port,u32 * speed)1304 int mlxsw_sp_port_speed_get(struct mlxsw_sp_port *mlxsw_sp_port, u32 *speed)
1305 {
1306 const struct mlxsw_sp_port_type_speed_ops *port_type_speed_ops;
1307 struct mlxsw_sp *mlxsw_sp = mlxsw_sp_port->mlxsw_sp;
1308 char ptys_pl[MLXSW_REG_PTYS_LEN];
1309 u32 eth_proto_oper;
1310 int err;
1311
1312 port_type_speed_ops = mlxsw_sp->port_type_speed_ops;
1313 port_type_speed_ops->reg_ptys_eth_pack(mlxsw_sp, ptys_pl,
1314 mlxsw_sp_port->local_port, 0,
1315 false);
1316 err = mlxsw_reg_query(mlxsw_sp->core, MLXSW_REG(ptys), ptys_pl);
1317 if (err)
1318 return err;
1319 port_type_speed_ops->reg_ptys_eth_unpack(mlxsw_sp, ptys_pl, NULL, NULL,
1320 ð_proto_oper);
1321 *speed = port_type_speed_ops->from_ptys_speed(mlxsw_sp, eth_proto_oper);
1322 return 0;
1323 }
1324
mlxsw_sp_port_ets_set(struct mlxsw_sp_port * mlxsw_sp_port,enum mlxsw_reg_qeec_hr hr,u8 index,u8 next_index,bool dwrr,u8 dwrr_weight)1325 int mlxsw_sp_port_ets_set(struct mlxsw_sp_port *mlxsw_sp_port,
1326 enum mlxsw_reg_qeec_hr hr, u8 index, u8 next_index,
1327 bool dwrr, u8 dwrr_weight)
1328 {
1329 struct mlxsw_sp *mlxsw_sp = mlxsw_sp_port->mlxsw_sp;
1330 char qeec_pl[MLXSW_REG_QEEC_LEN];
1331
1332 mlxsw_reg_qeec_pack(qeec_pl, mlxsw_sp_port->local_port, hr, index,
1333 next_index);
1334 mlxsw_reg_qeec_de_set(qeec_pl, true);
1335 mlxsw_reg_qeec_dwrr_set(qeec_pl, dwrr);
1336 mlxsw_reg_qeec_dwrr_weight_set(qeec_pl, dwrr_weight);
1337 return mlxsw_reg_write(mlxsw_sp->core, MLXSW_REG(qeec), qeec_pl);
1338 }
1339
mlxsw_sp_port_ets_maxrate_set(struct mlxsw_sp_port * mlxsw_sp_port,enum mlxsw_reg_qeec_hr hr,u8 index,u8 next_index,u32 maxrate,u8 burst_size)1340 int mlxsw_sp_port_ets_maxrate_set(struct mlxsw_sp_port *mlxsw_sp_port,
1341 enum mlxsw_reg_qeec_hr hr, u8 index,
1342 u8 next_index, u32 maxrate, u8 burst_size)
1343 {
1344 struct mlxsw_sp *mlxsw_sp = mlxsw_sp_port->mlxsw_sp;
1345 char qeec_pl[MLXSW_REG_QEEC_LEN];
1346
1347 mlxsw_reg_qeec_pack(qeec_pl, mlxsw_sp_port->local_port, hr, index,
1348 next_index);
1349 mlxsw_reg_qeec_mase_set(qeec_pl, true);
1350 mlxsw_reg_qeec_max_shaper_rate_set(qeec_pl, maxrate);
1351 mlxsw_reg_qeec_max_shaper_bs_set(qeec_pl, burst_size);
1352 return mlxsw_reg_write(mlxsw_sp->core, MLXSW_REG(qeec), qeec_pl);
1353 }
1354
mlxsw_sp_port_min_bw_set(struct mlxsw_sp_port * mlxsw_sp_port,enum mlxsw_reg_qeec_hr hr,u8 index,u8 next_index,u32 minrate)1355 static int mlxsw_sp_port_min_bw_set(struct mlxsw_sp_port *mlxsw_sp_port,
1356 enum mlxsw_reg_qeec_hr hr, u8 index,
1357 u8 next_index, u32 minrate)
1358 {
1359 struct mlxsw_sp *mlxsw_sp = mlxsw_sp_port->mlxsw_sp;
1360 char qeec_pl[MLXSW_REG_QEEC_LEN];
1361
1362 mlxsw_reg_qeec_pack(qeec_pl, mlxsw_sp_port->local_port, hr, index,
1363 next_index);
1364 mlxsw_reg_qeec_mise_set(qeec_pl, true);
1365 mlxsw_reg_qeec_min_shaper_rate_set(qeec_pl, minrate);
1366
1367 return mlxsw_reg_write(mlxsw_sp->core, MLXSW_REG(qeec), qeec_pl);
1368 }
1369
mlxsw_sp_port_prio_tc_set(struct mlxsw_sp_port * mlxsw_sp_port,u8 switch_prio,u8 tclass)1370 int mlxsw_sp_port_prio_tc_set(struct mlxsw_sp_port *mlxsw_sp_port,
1371 u8 switch_prio, u8 tclass)
1372 {
1373 struct mlxsw_sp *mlxsw_sp = mlxsw_sp_port->mlxsw_sp;
1374 char qtct_pl[MLXSW_REG_QTCT_LEN];
1375
1376 mlxsw_reg_qtct_pack(qtct_pl, mlxsw_sp_port->local_port, switch_prio,
1377 tclass);
1378 return mlxsw_reg_write(mlxsw_sp->core, MLXSW_REG(qtct), qtct_pl);
1379 }
1380
mlxsw_sp_port_ets_init(struct mlxsw_sp_port * mlxsw_sp_port)1381 static int mlxsw_sp_port_ets_init(struct mlxsw_sp_port *mlxsw_sp_port)
1382 {
1383 int err, i;
1384
1385 /* Setup the elements hierarcy, so that each TC is linked to
1386 * one subgroup, which are all member in the same group.
1387 */
1388 err = mlxsw_sp_port_ets_set(mlxsw_sp_port,
1389 MLXSW_REG_QEEC_HR_GROUP, 0, 0, false, 0);
1390 if (err)
1391 return err;
1392 for (i = 0; i < IEEE_8021QAZ_MAX_TCS; i++) {
1393 err = mlxsw_sp_port_ets_set(mlxsw_sp_port,
1394 MLXSW_REG_QEEC_HR_SUBGROUP, i,
1395 0, false, 0);
1396 if (err)
1397 return err;
1398 }
1399 for (i = 0; i < IEEE_8021QAZ_MAX_TCS; i++) {
1400 err = mlxsw_sp_port_ets_set(mlxsw_sp_port,
1401 MLXSW_REG_QEEC_HR_TC, i, i,
1402 false, 0);
1403 if (err)
1404 return err;
1405
1406 err = mlxsw_sp_port_ets_set(mlxsw_sp_port,
1407 MLXSW_REG_QEEC_HR_TC,
1408 i + 8, i,
1409 true, 100);
1410 if (err)
1411 return err;
1412 }
1413
1414 /* Make sure the max shaper is disabled in all hierarchies that support
1415 * it. Note that this disables ptps (PTP shaper), but that is intended
1416 * for the initial configuration.
1417 */
1418 err = mlxsw_sp_port_ets_maxrate_set(mlxsw_sp_port,
1419 MLXSW_REG_QEEC_HR_PORT, 0, 0,
1420 MLXSW_REG_QEEC_MAS_DIS, 0);
1421 if (err)
1422 return err;
1423 for (i = 0; i < IEEE_8021QAZ_MAX_TCS; i++) {
1424 err = mlxsw_sp_port_ets_maxrate_set(mlxsw_sp_port,
1425 MLXSW_REG_QEEC_HR_SUBGROUP,
1426 i, 0,
1427 MLXSW_REG_QEEC_MAS_DIS, 0);
1428 if (err)
1429 return err;
1430 }
1431 for (i = 0; i < IEEE_8021QAZ_MAX_TCS; i++) {
1432 err = mlxsw_sp_port_ets_maxrate_set(mlxsw_sp_port,
1433 MLXSW_REG_QEEC_HR_TC,
1434 i, i,
1435 MLXSW_REG_QEEC_MAS_DIS, 0);
1436 if (err)
1437 return err;
1438
1439 err = mlxsw_sp_port_ets_maxrate_set(mlxsw_sp_port,
1440 MLXSW_REG_QEEC_HR_TC,
1441 i + 8, i,
1442 MLXSW_REG_QEEC_MAS_DIS, 0);
1443 if (err)
1444 return err;
1445 }
1446
1447 /* Configure the min shaper for multicast TCs. */
1448 for (i = 0; i < IEEE_8021QAZ_MAX_TCS; i++) {
1449 err = mlxsw_sp_port_min_bw_set(mlxsw_sp_port,
1450 MLXSW_REG_QEEC_HR_TC,
1451 i + 8, i,
1452 MLXSW_REG_QEEC_MIS_MIN);
1453 if (err)
1454 return err;
1455 }
1456
1457 /* Map all priorities to traffic class 0. */
1458 for (i = 0; i < IEEE_8021QAZ_MAX_TCS; i++) {
1459 err = mlxsw_sp_port_prio_tc_set(mlxsw_sp_port, i, 0);
1460 if (err)
1461 return err;
1462 }
1463
1464 return 0;
1465 }
1466
mlxsw_sp_port_tc_mc_mode_set(struct mlxsw_sp_port * mlxsw_sp_port,bool enable)1467 static int mlxsw_sp_port_tc_mc_mode_set(struct mlxsw_sp_port *mlxsw_sp_port,
1468 bool enable)
1469 {
1470 struct mlxsw_sp *mlxsw_sp = mlxsw_sp_port->mlxsw_sp;
1471 char qtctm_pl[MLXSW_REG_QTCTM_LEN];
1472
1473 mlxsw_reg_qtctm_pack(qtctm_pl, mlxsw_sp_port->local_port, enable);
1474 return mlxsw_reg_write(mlxsw_sp->core, MLXSW_REG(qtctm), qtctm_pl);
1475 }
1476
mlxsw_sp_port_overheat_init_val_set(struct mlxsw_sp_port * mlxsw_sp_port)1477 static int mlxsw_sp_port_overheat_init_val_set(struct mlxsw_sp_port *mlxsw_sp_port)
1478 {
1479 struct mlxsw_sp *mlxsw_sp = mlxsw_sp_port->mlxsw_sp;
1480 u8 slot_index = mlxsw_sp_port->mapping.slot_index;
1481 u8 module = mlxsw_sp_port->mapping.module;
1482 u64 overheat_counter;
1483 int err;
1484
1485 err = mlxsw_env_module_overheat_counter_get(mlxsw_sp->core, slot_index,
1486 module, &overheat_counter);
1487 if (err)
1488 return err;
1489
1490 mlxsw_sp_port->module_overheat_initial_val = overheat_counter;
1491 return 0;
1492 }
1493
1494 int
mlxsw_sp_port_vlan_classification_set(struct mlxsw_sp_port * mlxsw_sp_port,bool is_8021ad_tagged,bool is_8021q_tagged)1495 mlxsw_sp_port_vlan_classification_set(struct mlxsw_sp_port *mlxsw_sp_port,
1496 bool is_8021ad_tagged,
1497 bool is_8021q_tagged)
1498 {
1499 struct mlxsw_sp *mlxsw_sp = mlxsw_sp_port->mlxsw_sp;
1500 char spvc_pl[MLXSW_REG_SPVC_LEN];
1501
1502 mlxsw_reg_spvc_pack(spvc_pl, mlxsw_sp_port->local_port,
1503 is_8021ad_tagged, is_8021q_tagged);
1504 return mlxsw_reg_write(mlxsw_sp->core, MLXSW_REG(spvc), spvc_pl);
1505 }
1506
mlxsw_sp_port_label_info_get(struct mlxsw_sp * mlxsw_sp,u16 local_port,u8 * port_number,u8 * split_port_subnumber,u8 * slot_index)1507 static int mlxsw_sp_port_label_info_get(struct mlxsw_sp *mlxsw_sp,
1508 u16 local_port, u8 *port_number,
1509 u8 *split_port_subnumber,
1510 u8 *slot_index)
1511 {
1512 char pllp_pl[MLXSW_REG_PLLP_LEN];
1513 int err;
1514
1515 mlxsw_reg_pllp_pack(pllp_pl, local_port);
1516 err = mlxsw_reg_query(mlxsw_sp->core, MLXSW_REG(pllp), pllp_pl);
1517 if (err)
1518 return err;
1519 mlxsw_reg_pllp_unpack(pllp_pl, port_number,
1520 split_port_subnumber, slot_index);
1521 return 0;
1522 }
1523
mlxsw_sp_port_create(struct mlxsw_sp * mlxsw_sp,u16 local_port,bool split,struct mlxsw_sp_port_mapping * port_mapping)1524 static int mlxsw_sp_port_create(struct mlxsw_sp *mlxsw_sp, u16 local_port,
1525 bool split,
1526 struct mlxsw_sp_port_mapping *port_mapping)
1527 {
1528 struct mlxsw_sp_port_vlan *mlxsw_sp_port_vlan;
1529 struct mlxsw_sp_port *mlxsw_sp_port;
1530 u32 lanes = port_mapping->width;
1531 u8 split_port_subnumber;
1532 struct net_device *dev;
1533 u8 port_number;
1534 u8 slot_index;
1535 bool splittable;
1536 int err;
1537
1538 err = mlxsw_sp_port_module_map(mlxsw_sp, local_port, port_mapping);
1539 if (err) {
1540 dev_err(mlxsw_sp->bus_info->dev, "Port %d: Failed to map module\n",
1541 local_port);
1542 return err;
1543 }
1544
1545 err = mlxsw_sp_port_swid_set(mlxsw_sp, local_port, 0);
1546 if (err) {
1547 dev_err(mlxsw_sp->bus_info->dev, "Port %d: Failed to set SWID\n",
1548 local_port);
1549 goto err_port_swid_set;
1550 }
1551
1552 err = mlxsw_sp_port_label_info_get(mlxsw_sp, local_port, &port_number,
1553 &split_port_subnumber, &slot_index);
1554 if (err) {
1555 dev_err(mlxsw_sp->bus_info->dev, "Port %d: Failed to get port label information\n",
1556 local_port);
1557 goto err_port_label_info_get;
1558 }
1559
1560 splittable = lanes > 1 && !split;
1561 err = mlxsw_core_port_init(mlxsw_sp->core, local_port, slot_index,
1562 port_number, split, split_port_subnumber,
1563 splittable, lanes, mlxsw_sp->base_mac,
1564 sizeof(mlxsw_sp->base_mac));
1565 if (err) {
1566 dev_err(mlxsw_sp->bus_info->dev, "Port %d: Failed to init core port\n",
1567 local_port);
1568 goto err_core_port_init;
1569 }
1570
1571 dev = alloc_etherdev(sizeof(struct mlxsw_sp_port));
1572 if (!dev) {
1573 err = -ENOMEM;
1574 goto err_alloc_etherdev;
1575 }
1576 SET_NETDEV_DEV(dev, mlxsw_sp->bus_info->dev);
1577 dev_net_set(dev, mlxsw_sp_net(mlxsw_sp));
1578 mlxsw_sp_port = netdev_priv(dev);
1579 mlxsw_sp_port->dev = dev;
1580 mlxsw_sp_port->mlxsw_sp = mlxsw_sp;
1581 mlxsw_sp_port->local_port = local_port;
1582 mlxsw_sp_port->pvid = MLXSW_SP_DEFAULT_VID;
1583 mlxsw_sp_port->split = split;
1584 mlxsw_sp_port->mapping = *port_mapping;
1585 mlxsw_sp_port->link.autoneg = 1;
1586 INIT_LIST_HEAD(&mlxsw_sp_port->vlans_list);
1587
1588 mlxsw_sp_port->pcpu_stats =
1589 netdev_alloc_pcpu_stats(struct mlxsw_sp_port_pcpu_stats);
1590 if (!mlxsw_sp_port->pcpu_stats) {
1591 err = -ENOMEM;
1592 goto err_alloc_stats;
1593 }
1594
1595 INIT_DELAYED_WORK(&mlxsw_sp_port->periodic_hw_stats.update_dw,
1596 &update_stats_cache);
1597
1598 dev->netdev_ops = &mlxsw_sp_port_netdev_ops;
1599 dev->ethtool_ops = &mlxsw_sp_port_ethtool_ops;
1600
1601 err = mlxsw_sp_port_dev_addr_init(mlxsw_sp_port);
1602 if (err) {
1603 dev_err(mlxsw_sp->bus_info->dev, "Port %d: Unable to init port mac address\n",
1604 mlxsw_sp_port->local_port);
1605 goto err_dev_addr_init;
1606 }
1607
1608 netif_carrier_off(dev);
1609
1610 dev->features |= NETIF_F_NETNS_LOCAL | NETIF_F_LLTX | NETIF_F_SG |
1611 NETIF_F_HW_VLAN_CTAG_FILTER | NETIF_F_HW_TC;
1612 dev->hw_features |= NETIF_F_HW_TC | NETIF_F_LOOPBACK;
1613
1614 dev->min_mtu = 0;
1615 dev->max_mtu = ETH_MAX_MTU;
1616
1617 /* Each packet needs to have a Tx header (metadata) on top all other
1618 * headers.
1619 */
1620 dev->needed_headroom = MLXSW_TXHDR_LEN;
1621
1622 err = mlxsw_sp_port_system_port_mapping_set(mlxsw_sp_port);
1623 if (err) {
1624 dev_err(mlxsw_sp->bus_info->dev, "Port %d: Failed to set system port mapping\n",
1625 mlxsw_sp_port->local_port);
1626 goto err_port_system_port_mapping_set;
1627 }
1628
1629 err = mlxsw_sp_port_speed_by_width_set(mlxsw_sp_port);
1630 if (err) {
1631 dev_err(mlxsw_sp->bus_info->dev, "Port %d: Failed to enable speeds\n",
1632 mlxsw_sp_port->local_port);
1633 goto err_port_speed_by_width_set;
1634 }
1635
1636 err = mlxsw_sp->port_type_speed_ops->ptys_max_speed(mlxsw_sp_port,
1637 &mlxsw_sp_port->max_speed);
1638 if (err) {
1639 dev_err(mlxsw_sp->bus_info->dev, "Port %d: Failed to get maximum speed\n",
1640 mlxsw_sp_port->local_port);
1641 goto err_max_speed_get;
1642 }
1643
1644 err = mlxsw_sp_port_max_mtu_get(mlxsw_sp_port, &mlxsw_sp_port->max_mtu);
1645 if (err) {
1646 dev_err(mlxsw_sp->bus_info->dev, "Port %d: Failed to get maximum MTU\n",
1647 mlxsw_sp_port->local_port);
1648 goto err_port_max_mtu_get;
1649 }
1650
1651 err = mlxsw_sp_port_mtu_set(mlxsw_sp_port, ETH_DATA_LEN);
1652 if (err) {
1653 dev_err(mlxsw_sp->bus_info->dev, "Port %d: Failed to set MTU\n",
1654 mlxsw_sp_port->local_port);
1655 goto err_port_mtu_set;
1656 }
1657
1658 err = mlxsw_sp_port_admin_status_set(mlxsw_sp_port, false);
1659 if (err)
1660 goto err_port_admin_status_set;
1661
1662 err = mlxsw_sp_port_buffers_init(mlxsw_sp_port);
1663 if (err) {
1664 dev_err(mlxsw_sp->bus_info->dev, "Port %d: Failed to initialize buffers\n",
1665 mlxsw_sp_port->local_port);
1666 goto err_port_buffers_init;
1667 }
1668
1669 err = mlxsw_sp_port_ets_init(mlxsw_sp_port);
1670 if (err) {
1671 dev_err(mlxsw_sp->bus_info->dev, "Port %d: Failed to initialize ETS\n",
1672 mlxsw_sp_port->local_port);
1673 goto err_port_ets_init;
1674 }
1675
1676 err = mlxsw_sp_port_tc_mc_mode_set(mlxsw_sp_port, true);
1677 if (err) {
1678 dev_err(mlxsw_sp->bus_info->dev, "Port %d: Failed to initialize TC MC mode\n",
1679 mlxsw_sp_port->local_port);
1680 goto err_port_tc_mc_mode;
1681 }
1682
1683 /* ETS and buffers must be initialized before DCB. */
1684 err = mlxsw_sp_port_dcb_init(mlxsw_sp_port);
1685 if (err) {
1686 dev_err(mlxsw_sp->bus_info->dev, "Port %d: Failed to initialize DCB\n",
1687 mlxsw_sp_port->local_port);
1688 goto err_port_dcb_init;
1689 }
1690
1691 err = mlxsw_sp_port_fids_init(mlxsw_sp_port);
1692 if (err) {
1693 dev_err(mlxsw_sp->bus_info->dev, "Port %d: Failed to initialize FIDs\n",
1694 mlxsw_sp_port->local_port);
1695 goto err_port_fids_init;
1696 }
1697
1698 err = mlxsw_sp_tc_qdisc_init(mlxsw_sp_port);
1699 if (err) {
1700 dev_err(mlxsw_sp->bus_info->dev, "Port %d: Failed to initialize TC qdiscs\n",
1701 mlxsw_sp_port->local_port);
1702 goto err_port_qdiscs_init;
1703 }
1704
1705 err = mlxsw_sp_port_vlan_set(mlxsw_sp_port, 0, VLAN_N_VID - 1, false,
1706 false);
1707 if (err) {
1708 dev_err(mlxsw_sp->bus_info->dev, "Port %d: Failed to clear VLAN filter\n",
1709 mlxsw_sp_port->local_port);
1710 goto err_port_vlan_clear;
1711 }
1712
1713 err = mlxsw_sp_port_nve_init(mlxsw_sp_port);
1714 if (err) {
1715 dev_err(mlxsw_sp->bus_info->dev, "Port %d: Failed to initialize NVE\n",
1716 mlxsw_sp_port->local_port);
1717 goto err_port_nve_init;
1718 }
1719
1720 err = mlxsw_sp_port_pvid_set(mlxsw_sp_port, MLXSW_SP_DEFAULT_VID,
1721 ETH_P_8021Q);
1722 if (err) {
1723 dev_err(mlxsw_sp->bus_info->dev, "Port %d: Failed to set PVID\n",
1724 mlxsw_sp_port->local_port);
1725 goto err_port_pvid_set;
1726 }
1727
1728 mlxsw_sp_port_vlan = mlxsw_sp_port_vlan_create(mlxsw_sp_port,
1729 MLXSW_SP_DEFAULT_VID);
1730 if (IS_ERR(mlxsw_sp_port_vlan)) {
1731 dev_err(mlxsw_sp->bus_info->dev, "Port %d: Failed to create VID 1\n",
1732 mlxsw_sp_port->local_port);
1733 err = PTR_ERR(mlxsw_sp_port_vlan);
1734 goto err_port_vlan_create;
1735 }
1736 mlxsw_sp_port->default_vlan = mlxsw_sp_port_vlan;
1737
1738 /* Set SPVC.et0=true and SPVC.et1=false to make the local port to treat
1739 * only packets with 802.1q header as tagged packets.
1740 */
1741 err = mlxsw_sp_port_vlan_classification_set(mlxsw_sp_port, false, true);
1742 if (err) {
1743 dev_err(mlxsw_sp->bus_info->dev, "Port %d: Failed to set default VLAN classification\n",
1744 local_port);
1745 goto err_port_vlan_classification_set;
1746 }
1747
1748 INIT_DELAYED_WORK(&mlxsw_sp_port->ptp.shaper_dw,
1749 mlxsw_sp->ptp_ops->shaper_work);
1750
1751 mlxsw_sp->ports[local_port] = mlxsw_sp_port;
1752
1753 err = mlxsw_sp_port_overheat_init_val_set(mlxsw_sp_port);
1754 if (err) {
1755 dev_err(mlxsw_sp->bus_info->dev, "Port %d: Failed to set overheat initial value\n",
1756 mlxsw_sp_port->local_port);
1757 goto err_port_overheat_init_val_set;
1758 }
1759
1760 err = register_netdev(dev);
1761 if (err) {
1762 dev_err(mlxsw_sp->bus_info->dev, "Port %d: Failed to register netdev\n",
1763 mlxsw_sp_port->local_port);
1764 goto err_register_netdev;
1765 }
1766
1767 mlxsw_core_port_eth_set(mlxsw_sp->core, mlxsw_sp_port->local_port,
1768 mlxsw_sp_port, dev);
1769 mlxsw_core_schedule_dw(&mlxsw_sp_port->periodic_hw_stats.update_dw, 0);
1770 return 0;
1771
1772 err_register_netdev:
1773 err_port_overheat_init_val_set:
1774 mlxsw_sp_port_vlan_classification_set(mlxsw_sp_port, true, true);
1775 err_port_vlan_classification_set:
1776 mlxsw_sp->ports[local_port] = NULL;
1777 mlxsw_sp_port_vlan_destroy(mlxsw_sp_port_vlan);
1778 err_port_vlan_create:
1779 err_port_pvid_set:
1780 mlxsw_sp_port_nve_fini(mlxsw_sp_port);
1781 err_port_nve_init:
1782 err_port_vlan_clear:
1783 mlxsw_sp_tc_qdisc_fini(mlxsw_sp_port);
1784 err_port_qdiscs_init:
1785 mlxsw_sp_port_fids_fini(mlxsw_sp_port);
1786 err_port_fids_init:
1787 mlxsw_sp_port_dcb_fini(mlxsw_sp_port);
1788 err_port_dcb_init:
1789 mlxsw_sp_port_tc_mc_mode_set(mlxsw_sp_port, false);
1790 err_port_tc_mc_mode:
1791 err_port_ets_init:
1792 mlxsw_sp_port_buffers_fini(mlxsw_sp_port);
1793 err_port_buffers_init:
1794 err_port_admin_status_set:
1795 err_port_mtu_set:
1796 err_port_max_mtu_get:
1797 err_max_speed_get:
1798 err_port_speed_by_width_set:
1799 err_port_system_port_mapping_set:
1800 err_dev_addr_init:
1801 free_percpu(mlxsw_sp_port->pcpu_stats);
1802 err_alloc_stats:
1803 free_netdev(dev);
1804 err_alloc_etherdev:
1805 mlxsw_core_port_fini(mlxsw_sp->core, local_port);
1806 err_core_port_init:
1807 err_port_label_info_get:
1808 mlxsw_sp_port_swid_set(mlxsw_sp, local_port,
1809 MLXSW_PORT_SWID_DISABLED_PORT);
1810 err_port_swid_set:
1811 mlxsw_sp_port_module_unmap(mlxsw_sp, local_port,
1812 port_mapping->slot_index,
1813 port_mapping->module);
1814 return err;
1815 }
1816
mlxsw_sp_port_remove(struct mlxsw_sp * mlxsw_sp,u16 local_port)1817 static void mlxsw_sp_port_remove(struct mlxsw_sp *mlxsw_sp, u16 local_port)
1818 {
1819 struct mlxsw_sp_port *mlxsw_sp_port = mlxsw_sp->ports[local_port];
1820 u8 slot_index = mlxsw_sp_port->mapping.slot_index;
1821 u8 module = mlxsw_sp_port->mapping.module;
1822
1823 cancel_delayed_work_sync(&mlxsw_sp_port->periodic_hw_stats.update_dw);
1824 cancel_delayed_work_sync(&mlxsw_sp_port->ptp.shaper_dw);
1825 mlxsw_core_port_clear(mlxsw_sp->core, local_port, mlxsw_sp);
1826 unregister_netdev(mlxsw_sp_port->dev); /* This calls ndo_stop */
1827 mlxsw_sp_port_ptp_clear(mlxsw_sp_port);
1828 mlxsw_sp_port_vlan_classification_set(mlxsw_sp_port, true, true);
1829 mlxsw_sp->ports[local_port] = NULL;
1830 mlxsw_sp_port_vlan_flush(mlxsw_sp_port, true);
1831 mlxsw_sp_port_nve_fini(mlxsw_sp_port);
1832 mlxsw_sp_tc_qdisc_fini(mlxsw_sp_port);
1833 mlxsw_sp_port_fids_fini(mlxsw_sp_port);
1834 mlxsw_sp_port_dcb_fini(mlxsw_sp_port);
1835 mlxsw_sp_port_tc_mc_mode_set(mlxsw_sp_port, false);
1836 mlxsw_sp_port_buffers_fini(mlxsw_sp_port);
1837 free_percpu(mlxsw_sp_port->pcpu_stats);
1838 WARN_ON_ONCE(!list_empty(&mlxsw_sp_port->vlans_list));
1839 free_netdev(mlxsw_sp_port->dev);
1840 mlxsw_core_port_fini(mlxsw_sp->core, local_port);
1841 mlxsw_sp_port_swid_set(mlxsw_sp, local_port,
1842 MLXSW_PORT_SWID_DISABLED_PORT);
1843 mlxsw_sp_port_module_unmap(mlxsw_sp, local_port, slot_index, module);
1844 }
1845
mlxsw_sp_cpu_port_create(struct mlxsw_sp * mlxsw_sp)1846 static int mlxsw_sp_cpu_port_create(struct mlxsw_sp *mlxsw_sp)
1847 {
1848 struct mlxsw_sp_port *mlxsw_sp_port;
1849 int err;
1850
1851 mlxsw_sp_port = kzalloc(sizeof(*mlxsw_sp_port), GFP_KERNEL);
1852 if (!mlxsw_sp_port)
1853 return -ENOMEM;
1854
1855 mlxsw_sp_port->mlxsw_sp = mlxsw_sp;
1856 mlxsw_sp_port->local_port = MLXSW_PORT_CPU_PORT;
1857
1858 err = mlxsw_core_cpu_port_init(mlxsw_sp->core,
1859 mlxsw_sp_port,
1860 mlxsw_sp->base_mac,
1861 sizeof(mlxsw_sp->base_mac));
1862 if (err) {
1863 dev_err(mlxsw_sp->bus_info->dev, "Failed to initialize core CPU port\n");
1864 goto err_core_cpu_port_init;
1865 }
1866
1867 mlxsw_sp->ports[MLXSW_PORT_CPU_PORT] = mlxsw_sp_port;
1868 return 0;
1869
1870 err_core_cpu_port_init:
1871 kfree(mlxsw_sp_port);
1872 return err;
1873 }
1874
mlxsw_sp_cpu_port_remove(struct mlxsw_sp * mlxsw_sp)1875 static void mlxsw_sp_cpu_port_remove(struct mlxsw_sp *mlxsw_sp)
1876 {
1877 struct mlxsw_sp_port *mlxsw_sp_port =
1878 mlxsw_sp->ports[MLXSW_PORT_CPU_PORT];
1879
1880 mlxsw_core_cpu_port_fini(mlxsw_sp->core);
1881 mlxsw_sp->ports[MLXSW_PORT_CPU_PORT] = NULL;
1882 kfree(mlxsw_sp_port);
1883 }
1884
mlxsw_sp_local_port_valid(u16 local_port)1885 static bool mlxsw_sp_local_port_valid(u16 local_port)
1886 {
1887 return local_port != MLXSW_PORT_CPU_PORT;
1888 }
1889
mlxsw_sp_port_created(struct mlxsw_sp * mlxsw_sp,u16 local_port)1890 static bool mlxsw_sp_port_created(struct mlxsw_sp *mlxsw_sp, u16 local_port)
1891 {
1892 if (!mlxsw_sp_local_port_valid(local_port))
1893 return false;
1894 return mlxsw_sp->ports[local_port] != NULL;
1895 }
1896
mlxsw_sp_port_mapping_event_set(struct mlxsw_sp * mlxsw_sp,u16 local_port,bool enable)1897 static int mlxsw_sp_port_mapping_event_set(struct mlxsw_sp *mlxsw_sp,
1898 u16 local_port, bool enable)
1899 {
1900 char pmecr_pl[MLXSW_REG_PMECR_LEN];
1901
1902 mlxsw_reg_pmecr_pack(pmecr_pl, local_port,
1903 enable ? MLXSW_REG_PMECR_E_GENERATE_EVENT :
1904 MLXSW_REG_PMECR_E_DO_NOT_GENERATE_EVENT);
1905 return mlxsw_reg_write(mlxsw_sp->core, MLXSW_REG(pmecr), pmecr_pl);
1906 }
1907
1908 struct mlxsw_sp_port_mapping_event {
1909 struct list_head list;
1910 char pmlp_pl[MLXSW_REG_PMLP_LEN];
1911 };
1912
mlxsw_sp_port_mapping_events_work(struct work_struct * work)1913 static void mlxsw_sp_port_mapping_events_work(struct work_struct *work)
1914 {
1915 struct mlxsw_sp_port_mapping_event *event, *next_event;
1916 struct mlxsw_sp_port_mapping_events *events;
1917 struct mlxsw_sp_port_mapping port_mapping;
1918 struct mlxsw_sp *mlxsw_sp;
1919 struct devlink *devlink;
1920 LIST_HEAD(event_queue);
1921 u16 local_port;
1922 int err;
1923
1924 events = container_of(work, struct mlxsw_sp_port_mapping_events, work);
1925 mlxsw_sp = container_of(events, struct mlxsw_sp, port_mapping_events);
1926 devlink = priv_to_devlink(mlxsw_sp->core);
1927
1928 spin_lock_bh(&events->queue_lock);
1929 list_splice_init(&events->queue, &event_queue);
1930 spin_unlock_bh(&events->queue_lock);
1931
1932 list_for_each_entry_safe(event, next_event, &event_queue, list) {
1933 local_port = mlxsw_reg_pmlp_local_port_get(event->pmlp_pl);
1934 err = mlxsw_sp_port_module_info_parse(mlxsw_sp, local_port,
1935 event->pmlp_pl, &port_mapping);
1936 if (err)
1937 goto out;
1938
1939 if (WARN_ON_ONCE(!port_mapping.width))
1940 goto out;
1941
1942 devl_lock(devlink);
1943
1944 if (!mlxsw_sp_port_created(mlxsw_sp, local_port))
1945 mlxsw_sp_port_create(mlxsw_sp, local_port,
1946 false, &port_mapping);
1947 else
1948 WARN_ON_ONCE(1);
1949
1950 devl_unlock(devlink);
1951
1952 mlxsw_sp->port_mapping[local_port] = port_mapping;
1953
1954 out:
1955 kfree(event);
1956 }
1957 }
1958
1959 static void
mlxsw_sp_port_mapping_listener_func(const struct mlxsw_reg_info * reg,char * pmlp_pl,void * priv)1960 mlxsw_sp_port_mapping_listener_func(const struct mlxsw_reg_info *reg,
1961 char *pmlp_pl, void *priv)
1962 {
1963 struct mlxsw_sp_port_mapping_events *events;
1964 struct mlxsw_sp_port_mapping_event *event;
1965 struct mlxsw_sp *mlxsw_sp = priv;
1966 u16 local_port;
1967
1968 local_port = mlxsw_reg_pmlp_local_port_get(pmlp_pl);
1969 if (WARN_ON_ONCE(!mlxsw_sp_local_port_is_valid(mlxsw_sp, local_port)))
1970 return;
1971
1972 events = &mlxsw_sp->port_mapping_events;
1973 event = kmalloc(sizeof(*event), GFP_ATOMIC);
1974 if (!event)
1975 return;
1976 memcpy(event->pmlp_pl, pmlp_pl, sizeof(event->pmlp_pl));
1977 spin_lock(&events->queue_lock);
1978 list_add_tail(&event->list, &events->queue);
1979 spin_unlock(&events->queue_lock);
1980 mlxsw_core_schedule_work(&events->work);
1981 }
1982
1983 static void
__mlxsw_sp_port_mapping_events_cancel(struct mlxsw_sp * mlxsw_sp)1984 __mlxsw_sp_port_mapping_events_cancel(struct mlxsw_sp *mlxsw_sp)
1985 {
1986 struct mlxsw_sp_port_mapping_event *event, *next_event;
1987 struct mlxsw_sp_port_mapping_events *events;
1988
1989 events = &mlxsw_sp->port_mapping_events;
1990
1991 /* Caller needs to make sure that no new event is going to appear. */
1992 cancel_work_sync(&events->work);
1993 list_for_each_entry_safe(event, next_event, &events->queue, list) {
1994 list_del(&event->list);
1995 kfree(event);
1996 }
1997 }
1998
mlxsw_sp_ports_remove(struct mlxsw_sp * mlxsw_sp)1999 static void mlxsw_sp_ports_remove(struct mlxsw_sp *mlxsw_sp)
2000 {
2001 unsigned int max_ports = mlxsw_core_max_ports(mlxsw_sp->core);
2002 struct devlink *devlink = priv_to_devlink(mlxsw_sp->core);
2003 int i;
2004
2005 for (i = 1; i < max_ports; i++)
2006 mlxsw_sp_port_mapping_event_set(mlxsw_sp, i, false);
2007 /* Make sure all scheduled events are processed */
2008 __mlxsw_sp_port_mapping_events_cancel(mlxsw_sp);
2009
2010 devl_lock(devlink);
2011 for (i = 1; i < max_ports; i++)
2012 if (mlxsw_sp_port_created(mlxsw_sp, i))
2013 mlxsw_sp_port_remove(mlxsw_sp, i);
2014 mlxsw_sp_cpu_port_remove(mlxsw_sp);
2015 devl_unlock(devlink);
2016 kfree(mlxsw_sp->ports);
2017 mlxsw_sp->ports = NULL;
2018 }
2019
2020 static void
mlxsw_sp_ports_remove_selected(struct mlxsw_core * mlxsw_core,bool (* selector)(void * priv,u16 local_port),void * priv)2021 mlxsw_sp_ports_remove_selected(struct mlxsw_core *mlxsw_core,
2022 bool (*selector)(void *priv, u16 local_port),
2023 void *priv)
2024 {
2025 struct mlxsw_sp *mlxsw_sp = mlxsw_core_driver_priv(mlxsw_core);
2026 unsigned int max_ports = mlxsw_core_max_ports(mlxsw_core);
2027 int i;
2028
2029 for (i = 1; i < max_ports; i++)
2030 if (mlxsw_sp_port_created(mlxsw_sp, i) && selector(priv, i))
2031 mlxsw_sp_port_remove(mlxsw_sp, i);
2032 }
2033
mlxsw_sp_ports_create(struct mlxsw_sp * mlxsw_sp)2034 static int mlxsw_sp_ports_create(struct mlxsw_sp *mlxsw_sp)
2035 {
2036 unsigned int max_ports = mlxsw_core_max_ports(mlxsw_sp->core);
2037 struct devlink *devlink = priv_to_devlink(mlxsw_sp->core);
2038 struct mlxsw_sp_port_mapping_events *events;
2039 struct mlxsw_sp_port_mapping *port_mapping;
2040 size_t alloc_size;
2041 int i;
2042 int err;
2043
2044 alloc_size = sizeof(struct mlxsw_sp_port *) * max_ports;
2045 mlxsw_sp->ports = kzalloc(alloc_size, GFP_KERNEL);
2046 if (!mlxsw_sp->ports)
2047 return -ENOMEM;
2048
2049 events = &mlxsw_sp->port_mapping_events;
2050 INIT_LIST_HEAD(&events->queue);
2051 spin_lock_init(&events->queue_lock);
2052 INIT_WORK(&events->work, mlxsw_sp_port_mapping_events_work);
2053
2054 for (i = 1; i < max_ports; i++) {
2055 err = mlxsw_sp_port_mapping_event_set(mlxsw_sp, i, true);
2056 if (err)
2057 goto err_event_enable;
2058 }
2059
2060 devl_lock(devlink);
2061 err = mlxsw_sp_cpu_port_create(mlxsw_sp);
2062 if (err)
2063 goto err_cpu_port_create;
2064
2065 for (i = 1; i < max_ports; i++) {
2066 port_mapping = &mlxsw_sp->port_mapping[i];
2067 if (!port_mapping->width)
2068 continue;
2069 err = mlxsw_sp_port_create(mlxsw_sp, i, false, port_mapping);
2070 if (err)
2071 goto err_port_create;
2072 }
2073 devl_unlock(devlink);
2074 return 0;
2075
2076 err_port_create:
2077 for (i--; i >= 1; i--)
2078 if (mlxsw_sp_port_created(mlxsw_sp, i))
2079 mlxsw_sp_port_remove(mlxsw_sp, i);
2080 i = max_ports;
2081 mlxsw_sp_cpu_port_remove(mlxsw_sp);
2082 err_cpu_port_create:
2083 devl_unlock(devlink);
2084 err_event_enable:
2085 for (i--; i >= 1; i--)
2086 mlxsw_sp_port_mapping_event_set(mlxsw_sp, i, false);
2087 /* Make sure all scheduled events are processed */
2088 __mlxsw_sp_port_mapping_events_cancel(mlxsw_sp);
2089 kfree(mlxsw_sp->ports);
2090 mlxsw_sp->ports = NULL;
2091 return err;
2092 }
2093
mlxsw_sp_port_module_info_init(struct mlxsw_sp * mlxsw_sp)2094 static int mlxsw_sp_port_module_info_init(struct mlxsw_sp *mlxsw_sp)
2095 {
2096 unsigned int max_ports = mlxsw_core_max_ports(mlxsw_sp->core);
2097 struct mlxsw_sp_port_mapping *port_mapping;
2098 int i;
2099 int err;
2100
2101 mlxsw_sp->port_mapping = kcalloc(max_ports,
2102 sizeof(struct mlxsw_sp_port_mapping),
2103 GFP_KERNEL);
2104 if (!mlxsw_sp->port_mapping)
2105 return -ENOMEM;
2106
2107 for (i = 1; i < max_ports; i++) {
2108 if (mlxsw_core_port_is_xm(mlxsw_sp->core, i))
2109 continue;
2110
2111 port_mapping = &mlxsw_sp->port_mapping[i];
2112 err = mlxsw_sp_port_module_info_get(mlxsw_sp, i, port_mapping);
2113 if (err)
2114 goto err_port_module_info_get;
2115 }
2116 return 0;
2117
2118 err_port_module_info_get:
2119 kfree(mlxsw_sp->port_mapping);
2120 return err;
2121 }
2122
mlxsw_sp_port_module_info_fini(struct mlxsw_sp * mlxsw_sp)2123 static void mlxsw_sp_port_module_info_fini(struct mlxsw_sp *mlxsw_sp)
2124 {
2125 kfree(mlxsw_sp->port_mapping);
2126 }
2127
2128 static int
mlxsw_sp_port_split_create(struct mlxsw_sp * mlxsw_sp,struct mlxsw_sp_port_mapping * port_mapping,unsigned int count,const char * pmtdb_pl)2129 mlxsw_sp_port_split_create(struct mlxsw_sp *mlxsw_sp,
2130 struct mlxsw_sp_port_mapping *port_mapping,
2131 unsigned int count, const char *pmtdb_pl)
2132 {
2133 struct mlxsw_sp_port_mapping split_port_mapping;
2134 int err, i;
2135
2136 split_port_mapping = *port_mapping;
2137 split_port_mapping.width /= count;
2138 for (i = 0; i < count; i++) {
2139 u16 s_local_port = mlxsw_reg_pmtdb_port_num_get(pmtdb_pl, i);
2140
2141 if (!mlxsw_sp_local_port_valid(s_local_port))
2142 continue;
2143
2144 err = mlxsw_sp_port_create(mlxsw_sp, s_local_port,
2145 true, &split_port_mapping);
2146 if (err)
2147 goto err_port_create;
2148 split_port_mapping.lane += split_port_mapping.width;
2149 }
2150
2151 return 0;
2152
2153 err_port_create:
2154 for (i--; i >= 0; i--) {
2155 u16 s_local_port = mlxsw_reg_pmtdb_port_num_get(pmtdb_pl, i);
2156
2157 if (mlxsw_sp_port_created(mlxsw_sp, s_local_port))
2158 mlxsw_sp_port_remove(mlxsw_sp, s_local_port);
2159 }
2160 return err;
2161 }
2162
mlxsw_sp_port_unsplit_create(struct mlxsw_sp * mlxsw_sp,unsigned int count,const char * pmtdb_pl)2163 static void mlxsw_sp_port_unsplit_create(struct mlxsw_sp *mlxsw_sp,
2164 unsigned int count,
2165 const char *pmtdb_pl)
2166 {
2167 struct mlxsw_sp_port_mapping *port_mapping;
2168 int i;
2169
2170 /* Go over original unsplit ports in the gap and recreate them. */
2171 for (i = 0; i < count; i++) {
2172 u16 local_port = mlxsw_reg_pmtdb_port_num_get(pmtdb_pl, i);
2173
2174 port_mapping = &mlxsw_sp->port_mapping[local_port];
2175 if (!port_mapping->width || !mlxsw_sp_local_port_valid(local_port))
2176 continue;
2177 mlxsw_sp_port_create(mlxsw_sp, local_port,
2178 false, port_mapping);
2179 }
2180 }
2181
2182 static struct mlxsw_sp_port *
mlxsw_sp_port_get_by_local_port(struct mlxsw_sp * mlxsw_sp,u16 local_port)2183 mlxsw_sp_port_get_by_local_port(struct mlxsw_sp *mlxsw_sp, u16 local_port)
2184 {
2185 if (mlxsw_sp->ports && mlxsw_sp->ports[local_port])
2186 return mlxsw_sp->ports[local_port];
2187 return NULL;
2188 }
2189
mlxsw_sp_port_split(struct mlxsw_core * mlxsw_core,u16 local_port,unsigned int count,struct netlink_ext_ack * extack)2190 static int mlxsw_sp_port_split(struct mlxsw_core *mlxsw_core, u16 local_port,
2191 unsigned int count,
2192 struct netlink_ext_ack *extack)
2193 {
2194 struct mlxsw_sp *mlxsw_sp = mlxsw_core_driver_priv(mlxsw_core);
2195 struct mlxsw_sp_port_mapping port_mapping;
2196 struct mlxsw_sp_port *mlxsw_sp_port;
2197 enum mlxsw_reg_pmtdb_status status;
2198 char pmtdb_pl[MLXSW_REG_PMTDB_LEN];
2199 int i;
2200 int err;
2201
2202 mlxsw_sp_port = mlxsw_sp_port_get_by_local_port(mlxsw_sp, local_port);
2203 if (!mlxsw_sp_port) {
2204 dev_err(mlxsw_sp->bus_info->dev, "Port number \"%d\" does not exist\n",
2205 local_port);
2206 NL_SET_ERR_MSG_MOD(extack, "Port number does not exist");
2207 return -EINVAL;
2208 }
2209
2210 if (mlxsw_sp_port->split) {
2211 NL_SET_ERR_MSG_MOD(extack, "Port is already split");
2212 return -EINVAL;
2213 }
2214
2215 mlxsw_reg_pmtdb_pack(pmtdb_pl, mlxsw_sp_port->mapping.slot_index,
2216 mlxsw_sp_port->mapping.module,
2217 mlxsw_sp_port->mapping.module_width / count,
2218 count);
2219 err = mlxsw_reg_query(mlxsw_core, MLXSW_REG(pmtdb), pmtdb_pl);
2220 if (err) {
2221 NL_SET_ERR_MSG_MOD(extack, "Failed to query split info");
2222 return err;
2223 }
2224
2225 status = mlxsw_reg_pmtdb_status_get(pmtdb_pl);
2226 if (status != MLXSW_REG_PMTDB_STATUS_SUCCESS) {
2227 NL_SET_ERR_MSG_MOD(extack, "Unsupported split configuration");
2228 return -EINVAL;
2229 }
2230
2231 port_mapping = mlxsw_sp_port->mapping;
2232
2233 for (i = 0; i < count; i++) {
2234 u16 s_local_port = mlxsw_reg_pmtdb_port_num_get(pmtdb_pl, i);
2235
2236 if (mlxsw_sp_port_created(mlxsw_sp, s_local_port))
2237 mlxsw_sp_port_remove(mlxsw_sp, s_local_port);
2238 }
2239
2240 err = mlxsw_sp_port_split_create(mlxsw_sp, &port_mapping,
2241 count, pmtdb_pl);
2242 if (err) {
2243 dev_err(mlxsw_sp->bus_info->dev, "Failed to create split ports\n");
2244 goto err_port_split_create;
2245 }
2246
2247 return 0;
2248
2249 err_port_split_create:
2250 mlxsw_sp_port_unsplit_create(mlxsw_sp, count, pmtdb_pl);
2251
2252 return err;
2253 }
2254
mlxsw_sp_port_unsplit(struct mlxsw_core * mlxsw_core,u16 local_port,struct netlink_ext_ack * extack)2255 static int mlxsw_sp_port_unsplit(struct mlxsw_core *mlxsw_core, u16 local_port,
2256 struct netlink_ext_ack *extack)
2257 {
2258 struct mlxsw_sp *mlxsw_sp = mlxsw_core_driver_priv(mlxsw_core);
2259 struct mlxsw_sp_port *mlxsw_sp_port;
2260 char pmtdb_pl[MLXSW_REG_PMTDB_LEN];
2261 unsigned int count;
2262 int i;
2263 int err;
2264
2265 mlxsw_sp_port = mlxsw_sp_port_get_by_local_port(mlxsw_sp, local_port);
2266 if (!mlxsw_sp_port) {
2267 dev_err(mlxsw_sp->bus_info->dev, "Port number \"%d\" does not exist\n",
2268 local_port);
2269 NL_SET_ERR_MSG_MOD(extack, "Port number does not exist");
2270 return -EINVAL;
2271 }
2272
2273 if (!mlxsw_sp_port->split) {
2274 NL_SET_ERR_MSG_MOD(extack, "Port was not split");
2275 return -EINVAL;
2276 }
2277
2278 count = mlxsw_sp_port->mapping.module_width /
2279 mlxsw_sp_port->mapping.width;
2280
2281 mlxsw_reg_pmtdb_pack(pmtdb_pl, mlxsw_sp_port->mapping.slot_index,
2282 mlxsw_sp_port->mapping.module,
2283 mlxsw_sp_port->mapping.module_width / count,
2284 count);
2285 err = mlxsw_reg_query(mlxsw_core, MLXSW_REG(pmtdb), pmtdb_pl);
2286 if (err) {
2287 NL_SET_ERR_MSG_MOD(extack, "Failed to query split info");
2288 return err;
2289 }
2290
2291 for (i = 0; i < count; i++) {
2292 u16 s_local_port = mlxsw_reg_pmtdb_port_num_get(pmtdb_pl, i);
2293
2294 if (mlxsw_sp_port_created(mlxsw_sp, s_local_port))
2295 mlxsw_sp_port_remove(mlxsw_sp, s_local_port);
2296 }
2297
2298 mlxsw_sp_port_unsplit_create(mlxsw_sp, count, pmtdb_pl);
2299
2300 return 0;
2301 }
2302
2303 static void
mlxsw_sp_port_down_wipe_counters(struct mlxsw_sp_port * mlxsw_sp_port)2304 mlxsw_sp_port_down_wipe_counters(struct mlxsw_sp_port *mlxsw_sp_port)
2305 {
2306 int i;
2307
2308 for (i = 0; i < TC_MAX_QUEUE; i++)
2309 mlxsw_sp_port->periodic_hw_stats.xstats.backlog[i] = 0;
2310 }
2311
mlxsw_sp_pude_event_func(const struct mlxsw_reg_info * reg,char * pude_pl,void * priv)2312 static void mlxsw_sp_pude_event_func(const struct mlxsw_reg_info *reg,
2313 char *pude_pl, void *priv)
2314 {
2315 struct mlxsw_sp *mlxsw_sp = priv;
2316 struct mlxsw_sp_port *mlxsw_sp_port;
2317 enum mlxsw_reg_pude_oper_status status;
2318 u16 local_port;
2319
2320 local_port = mlxsw_reg_pude_local_port_get(pude_pl);
2321
2322 if (WARN_ON_ONCE(!mlxsw_sp_local_port_is_valid(mlxsw_sp, local_port)))
2323 return;
2324 mlxsw_sp_port = mlxsw_sp->ports[local_port];
2325 if (!mlxsw_sp_port)
2326 return;
2327
2328 status = mlxsw_reg_pude_oper_status_get(pude_pl);
2329 if (status == MLXSW_PORT_OPER_STATUS_UP) {
2330 netdev_info(mlxsw_sp_port->dev, "link up\n");
2331 netif_carrier_on(mlxsw_sp_port->dev);
2332 mlxsw_core_schedule_dw(&mlxsw_sp_port->ptp.shaper_dw, 0);
2333 } else {
2334 netdev_info(mlxsw_sp_port->dev, "link down\n");
2335 netif_carrier_off(mlxsw_sp_port->dev);
2336 mlxsw_sp_port_down_wipe_counters(mlxsw_sp_port);
2337 }
2338 }
2339
mlxsw_sp1_ptp_fifo_event_func(struct mlxsw_sp * mlxsw_sp,char * mtpptr_pl,bool ingress)2340 static void mlxsw_sp1_ptp_fifo_event_func(struct mlxsw_sp *mlxsw_sp,
2341 char *mtpptr_pl, bool ingress)
2342 {
2343 u16 local_port;
2344 u8 num_rec;
2345 int i;
2346
2347 local_port = mlxsw_reg_mtpptr_local_port_get(mtpptr_pl);
2348 num_rec = mlxsw_reg_mtpptr_num_rec_get(mtpptr_pl);
2349 for (i = 0; i < num_rec; i++) {
2350 u8 domain_number;
2351 u8 message_type;
2352 u16 sequence_id;
2353 u64 timestamp;
2354
2355 mlxsw_reg_mtpptr_unpack(mtpptr_pl, i, &message_type,
2356 &domain_number, &sequence_id,
2357 ×tamp);
2358 mlxsw_sp1_ptp_got_timestamp(mlxsw_sp, ingress, local_port,
2359 message_type, domain_number,
2360 sequence_id, timestamp);
2361 }
2362 }
2363
mlxsw_sp1_ptp_ing_fifo_event_func(const struct mlxsw_reg_info * reg,char * mtpptr_pl,void * priv)2364 static void mlxsw_sp1_ptp_ing_fifo_event_func(const struct mlxsw_reg_info *reg,
2365 char *mtpptr_pl, void *priv)
2366 {
2367 struct mlxsw_sp *mlxsw_sp = priv;
2368
2369 mlxsw_sp1_ptp_fifo_event_func(mlxsw_sp, mtpptr_pl, true);
2370 }
2371
mlxsw_sp1_ptp_egr_fifo_event_func(const struct mlxsw_reg_info * reg,char * mtpptr_pl,void * priv)2372 static void mlxsw_sp1_ptp_egr_fifo_event_func(const struct mlxsw_reg_info *reg,
2373 char *mtpptr_pl, void *priv)
2374 {
2375 struct mlxsw_sp *mlxsw_sp = priv;
2376
2377 mlxsw_sp1_ptp_fifo_event_func(mlxsw_sp, mtpptr_pl, false);
2378 }
2379
mlxsw_sp_rx_listener_no_mark_func(struct sk_buff * skb,u16 local_port,void * priv)2380 void mlxsw_sp_rx_listener_no_mark_func(struct sk_buff *skb,
2381 u16 local_port, void *priv)
2382 {
2383 struct mlxsw_sp *mlxsw_sp = priv;
2384 struct mlxsw_sp_port *mlxsw_sp_port = mlxsw_sp->ports[local_port];
2385 struct mlxsw_sp_port_pcpu_stats *pcpu_stats;
2386
2387 if (unlikely(!mlxsw_sp_port)) {
2388 dev_warn_ratelimited(mlxsw_sp->bus_info->dev, "Port %d: skb received for non-existent port\n",
2389 local_port);
2390 return;
2391 }
2392
2393 skb->dev = mlxsw_sp_port->dev;
2394
2395 pcpu_stats = this_cpu_ptr(mlxsw_sp_port->pcpu_stats);
2396 u64_stats_update_begin(&pcpu_stats->syncp);
2397 pcpu_stats->rx_packets++;
2398 pcpu_stats->rx_bytes += skb->len;
2399 u64_stats_update_end(&pcpu_stats->syncp);
2400
2401 skb->protocol = eth_type_trans(skb, skb->dev);
2402 netif_receive_skb(skb);
2403 }
2404
mlxsw_sp_rx_listener_mark_func(struct sk_buff * skb,u16 local_port,void * priv)2405 static void mlxsw_sp_rx_listener_mark_func(struct sk_buff *skb, u16 local_port,
2406 void *priv)
2407 {
2408 skb->offload_fwd_mark = 1;
2409 return mlxsw_sp_rx_listener_no_mark_func(skb, local_port, priv);
2410 }
2411
mlxsw_sp_rx_listener_l3_mark_func(struct sk_buff * skb,u16 local_port,void * priv)2412 static void mlxsw_sp_rx_listener_l3_mark_func(struct sk_buff *skb,
2413 u16 local_port, void *priv)
2414 {
2415 skb->offload_l3_fwd_mark = 1;
2416 skb->offload_fwd_mark = 1;
2417 return mlxsw_sp_rx_listener_no_mark_func(skb, local_port, priv);
2418 }
2419
mlxsw_sp_ptp_receive(struct mlxsw_sp * mlxsw_sp,struct sk_buff * skb,u16 local_port)2420 void mlxsw_sp_ptp_receive(struct mlxsw_sp *mlxsw_sp, struct sk_buff *skb,
2421 u16 local_port)
2422 {
2423 mlxsw_sp->ptp_ops->receive(mlxsw_sp, skb, local_port);
2424 }
2425
2426 #define MLXSW_SP_RXL_NO_MARK(_trap_id, _action, _trap_group, _is_ctrl) \
2427 MLXSW_RXL(mlxsw_sp_rx_listener_no_mark_func, _trap_id, _action, \
2428 _is_ctrl, SP_##_trap_group, DISCARD)
2429
2430 #define MLXSW_SP_RXL_MARK(_trap_id, _action, _trap_group, _is_ctrl) \
2431 MLXSW_RXL(mlxsw_sp_rx_listener_mark_func, _trap_id, _action, \
2432 _is_ctrl, SP_##_trap_group, DISCARD)
2433
2434 #define MLXSW_SP_RXL_L3_MARK(_trap_id, _action, _trap_group, _is_ctrl) \
2435 MLXSW_RXL(mlxsw_sp_rx_listener_l3_mark_func, _trap_id, _action, \
2436 _is_ctrl, SP_##_trap_group, DISCARD)
2437
2438 #define MLXSW_SP_EVENTL(_func, _trap_id) \
2439 MLXSW_EVENTL(_func, _trap_id, SP_EVENT)
2440
2441 static const struct mlxsw_listener mlxsw_sp_listener[] = {
2442 /* Events */
2443 MLXSW_SP_EVENTL(mlxsw_sp_pude_event_func, PUDE),
2444 /* L2 traps */
2445 MLXSW_SP_RXL_NO_MARK(FID_MISS, TRAP_TO_CPU, FID_MISS, false),
2446 /* L3 traps */
2447 MLXSW_SP_RXL_MARK(IPV6_UNSPECIFIED_ADDRESS, TRAP_TO_CPU, ROUTER_EXP,
2448 false),
2449 MLXSW_SP_RXL_MARK(IPV6_LINK_LOCAL_SRC, TRAP_TO_CPU, ROUTER_EXP, false),
2450 MLXSW_SP_RXL_MARK(IPV6_MC_LINK_LOCAL_DEST, TRAP_TO_CPU, ROUTER_EXP,
2451 false),
2452 MLXSW_SP_RXL_NO_MARK(DISCARD_ING_ROUTER_SIP_CLASS_E, FORWARD,
2453 ROUTER_EXP, false),
2454 MLXSW_SP_RXL_NO_MARK(DISCARD_ING_ROUTER_MC_DMAC, FORWARD,
2455 ROUTER_EXP, false),
2456 MLXSW_SP_RXL_NO_MARK(DISCARD_ING_ROUTER_SIP_DIP, FORWARD,
2457 ROUTER_EXP, false),
2458 MLXSW_SP_RXL_NO_MARK(DISCARD_ING_ROUTER_DIP_LINK_LOCAL, FORWARD,
2459 ROUTER_EXP, false),
2460 /* Multicast Router Traps */
2461 MLXSW_SP_RXL_MARK(ACL1, TRAP_TO_CPU, MULTICAST, false),
2462 MLXSW_SP_RXL_L3_MARK(ACL2, TRAP_TO_CPU, MULTICAST, false),
2463 /* NVE traps */
2464 MLXSW_SP_RXL_MARK(NVE_ENCAP_ARP, TRAP_TO_CPU, NEIGH_DISCOVERY, false),
2465 };
2466
2467 static const struct mlxsw_listener mlxsw_sp1_listener[] = {
2468 /* Events */
2469 MLXSW_EVENTL(mlxsw_sp1_ptp_egr_fifo_event_func, PTP_EGR_FIFO, SP_PTP0),
2470 MLXSW_EVENTL(mlxsw_sp1_ptp_ing_fifo_event_func, PTP_ING_FIFO, SP_PTP0),
2471 };
2472
2473 static const struct mlxsw_listener mlxsw_sp2_listener[] = {
2474 /* Events */
2475 MLXSW_SP_EVENTL(mlxsw_sp_port_mapping_listener_func, PMLPE),
2476 };
2477
mlxsw_sp_cpu_policers_set(struct mlxsw_core * mlxsw_core)2478 static int mlxsw_sp_cpu_policers_set(struct mlxsw_core *mlxsw_core)
2479 {
2480 struct mlxsw_sp *mlxsw_sp = mlxsw_core_driver_priv(mlxsw_core);
2481 char qpcr_pl[MLXSW_REG_QPCR_LEN];
2482 enum mlxsw_reg_qpcr_ir_units ir_units;
2483 int max_cpu_policers;
2484 bool is_bytes;
2485 u8 burst_size;
2486 u32 rate;
2487 int i, err;
2488
2489 if (!MLXSW_CORE_RES_VALID(mlxsw_core, MAX_CPU_POLICERS))
2490 return -EIO;
2491
2492 max_cpu_policers = MLXSW_CORE_RES_GET(mlxsw_core, MAX_CPU_POLICERS);
2493
2494 ir_units = MLXSW_REG_QPCR_IR_UNITS_M;
2495 for (i = 0; i < max_cpu_policers; i++) {
2496 is_bytes = false;
2497 switch (i) {
2498 case MLXSW_REG_HTGT_TRAP_GROUP_SP_ROUTER_EXP:
2499 case MLXSW_REG_HTGT_TRAP_GROUP_SP_MULTICAST:
2500 case MLXSW_REG_HTGT_TRAP_GROUP_SP_FID_MISS:
2501 rate = 1024;
2502 burst_size = 7;
2503 break;
2504 default:
2505 continue;
2506 }
2507
2508 __set_bit(i, mlxsw_sp->trap->policers_usage);
2509 mlxsw_reg_qpcr_pack(qpcr_pl, i, ir_units, is_bytes, rate,
2510 burst_size);
2511 err = mlxsw_reg_write(mlxsw_core, MLXSW_REG(qpcr), qpcr_pl);
2512 if (err)
2513 return err;
2514 }
2515
2516 return 0;
2517 }
2518
mlxsw_sp_trap_groups_set(struct mlxsw_core * mlxsw_core)2519 static int mlxsw_sp_trap_groups_set(struct mlxsw_core *mlxsw_core)
2520 {
2521 char htgt_pl[MLXSW_REG_HTGT_LEN];
2522 enum mlxsw_reg_htgt_trap_group i;
2523 int max_cpu_policers;
2524 int max_trap_groups;
2525 u8 priority, tc;
2526 u16 policer_id;
2527 int err;
2528
2529 if (!MLXSW_CORE_RES_VALID(mlxsw_core, MAX_TRAP_GROUPS))
2530 return -EIO;
2531
2532 max_trap_groups = MLXSW_CORE_RES_GET(mlxsw_core, MAX_TRAP_GROUPS);
2533 max_cpu_policers = MLXSW_CORE_RES_GET(mlxsw_core, MAX_CPU_POLICERS);
2534
2535 for (i = 0; i < max_trap_groups; i++) {
2536 policer_id = i;
2537 switch (i) {
2538 case MLXSW_REG_HTGT_TRAP_GROUP_SP_ROUTER_EXP:
2539 case MLXSW_REG_HTGT_TRAP_GROUP_SP_MULTICAST:
2540 case MLXSW_REG_HTGT_TRAP_GROUP_SP_FID_MISS:
2541 priority = 1;
2542 tc = 1;
2543 break;
2544 case MLXSW_REG_HTGT_TRAP_GROUP_SP_EVENT:
2545 priority = MLXSW_REG_HTGT_DEFAULT_PRIORITY;
2546 tc = MLXSW_REG_HTGT_DEFAULT_TC;
2547 policer_id = MLXSW_REG_HTGT_INVALID_POLICER;
2548 break;
2549 default:
2550 continue;
2551 }
2552
2553 if (max_cpu_policers <= policer_id &&
2554 policer_id != MLXSW_REG_HTGT_INVALID_POLICER)
2555 return -EIO;
2556
2557 mlxsw_reg_htgt_pack(htgt_pl, i, policer_id, priority, tc);
2558 err = mlxsw_reg_write(mlxsw_core, MLXSW_REG(htgt), htgt_pl);
2559 if (err)
2560 return err;
2561 }
2562
2563 return 0;
2564 }
2565
mlxsw_sp_traps_init(struct mlxsw_sp * mlxsw_sp)2566 static int mlxsw_sp_traps_init(struct mlxsw_sp *mlxsw_sp)
2567 {
2568 struct mlxsw_sp_trap *trap;
2569 u64 max_policers;
2570 int err;
2571
2572 if (!MLXSW_CORE_RES_VALID(mlxsw_sp->core, MAX_CPU_POLICERS))
2573 return -EIO;
2574 max_policers = MLXSW_CORE_RES_GET(mlxsw_sp->core, MAX_CPU_POLICERS);
2575 trap = kzalloc(struct_size(trap, policers_usage,
2576 BITS_TO_LONGS(max_policers)), GFP_KERNEL);
2577 if (!trap)
2578 return -ENOMEM;
2579 trap->max_policers = max_policers;
2580 mlxsw_sp->trap = trap;
2581
2582 err = mlxsw_sp_cpu_policers_set(mlxsw_sp->core);
2583 if (err)
2584 goto err_cpu_policers_set;
2585
2586 err = mlxsw_sp_trap_groups_set(mlxsw_sp->core);
2587 if (err)
2588 goto err_trap_groups_set;
2589
2590 err = mlxsw_core_traps_register(mlxsw_sp->core, mlxsw_sp_listener,
2591 ARRAY_SIZE(mlxsw_sp_listener),
2592 mlxsw_sp);
2593 if (err)
2594 goto err_traps_register;
2595
2596 err = mlxsw_core_traps_register(mlxsw_sp->core, mlxsw_sp->listeners,
2597 mlxsw_sp->listeners_count, mlxsw_sp);
2598 if (err)
2599 goto err_extra_traps_init;
2600
2601 return 0;
2602
2603 err_extra_traps_init:
2604 mlxsw_core_traps_unregister(mlxsw_sp->core, mlxsw_sp_listener,
2605 ARRAY_SIZE(mlxsw_sp_listener),
2606 mlxsw_sp);
2607 err_traps_register:
2608 err_trap_groups_set:
2609 err_cpu_policers_set:
2610 kfree(trap);
2611 return err;
2612 }
2613
mlxsw_sp_traps_fini(struct mlxsw_sp * mlxsw_sp)2614 static void mlxsw_sp_traps_fini(struct mlxsw_sp *mlxsw_sp)
2615 {
2616 mlxsw_core_traps_unregister(mlxsw_sp->core, mlxsw_sp->listeners,
2617 mlxsw_sp->listeners_count,
2618 mlxsw_sp);
2619 mlxsw_core_traps_unregister(mlxsw_sp->core, mlxsw_sp_listener,
2620 ARRAY_SIZE(mlxsw_sp_listener), mlxsw_sp);
2621 kfree(mlxsw_sp->trap);
2622 }
2623
2624 #define MLXSW_SP_LAG_SEED_INIT 0xcafecafe
2625
mlxsw_sp_lag_init(struct mlxsw_sp * mlxsw_sp)2626 static int mlxsw_sp_lag_init(struct mlxsw_sp *mlxsw_sp)
2627 {
2628 char slcr_pl[MLXSW_REG_SLCR_LEN];
2629 u32 seed;
2630 int err;
2631
2632 seed = jhash(mlxsw_sp->base_mac, sizeof(mlxsw_sp->base_mac),
2633 MLXSW_SP_LAG_SEED_INIT);
2634 mlxsw_reg_slcr_pack(slcr_pl, MLXSW_REG_SLCR_LAG_HASH_SMAC |
2635 MLXSW_REG_SLCR_LAG_HASH_DMAC |
2636 MLXSW_REG_SLCR_LAG_HASH_ETHERTYPE |
2637 MLXSW_REG_SLCR_LAG_HASH_VLANID |
2638 MLXSW_REG_SLCR_LAG_HASH_SIP |
2639 MLXSW_REG_SLCR_LAG_HASH_DIP |
2640 MLXSW_REG_SLCR_LAG_HASH_SPORT |
2641 MLXSW_REG_SLCR_LAG_HASH_DPORT |
2642 MLXSW_REG_SLCR_LAG_HASH_IPPROTO, seed);
2643 err = mlxsw_reg_write(mlxsw_sp->core, MLXSW_REG(slcr), slcr_pl);
2644 if (err)
2645 return err;
2646
2647 if (!MLXSW_CORE_RES_VALID(mlxsw_sp->core, MAX_LAG) ||
2648 !MLXSW_CORE_RES_VALID(mlxsw_sp->core, MAX_LAG_MEMBERS))
2649 return -EIO;
2650
2651 mlxsw_sp->lags = kcalloc(MLXSW_CORE_RES_GET(mlxsw_sp->core, MAX_LAG),
2652 sizeof(struct mlxsw_sp_upper),
2653 GFP_KERNEL);
2654 if (!mlxsw_sp->lags)
2655 return -ENOMEM;
2656
2657 return 0;
2658 }
2659
mlxsw_sp_lag_fini(struct mlxsw_sp * mlxsw_sp)2660 static void mlxsw_sp_lag_fini(struct mlxsw_sp *mlxsw_sp)
2661 {
2662 kfree(mlxsw_sp->lags);
2663 }
2664
2665 static const struct mlxsw_sp_ptp_ops mlxsw_sp1_ptp_ops = {
2666 .clock_init = mlxsw_sp1_ptp_clock_init,
2667 .clock_fini = mlxsw_sp1_ptp_clock_fini,
2668 .init = mlxsw_sp1_ptp_init,
2669 .fini = mlxsw_sp1_ptp_fini,
2670 .receive = mlxsw_sp1_ptp_receive,
2671 .transmitted = mlxsw_sp1_ptp_transmitted,
2672 .hwtstamp_get = mlxsw_sp1_ptp_hwtstamp_get,
2673 .hwtstamp_set = mlxsw_sp1_ptp_hwtstamp_set,
2674 .shaper_work = mlxsw_sp1_ptp_shaper_work,
2675 .get_ts_info = mlxsw_sp1_ptp_get_ts_info,
2676 .get_stats_count = mlxsw_sp1_get_stats_count,
2677 .get_stats_strings = mlxsw_sp1_get_stats_strings,
2678 .get_stats = mlxsw_sp1_get_stats,
2679 };
2680
2681 static const struct mlxsw_sp_ptp_ops mlxsw_sp2_ptp_ops = {
2682 .clock_init = mlxsw_sp2_ptp_clock_init,
2683 .clock_fini = mlxsw_sp2_ptp_clock_fini,
2684 .init = mlxsw_sp2_ptp_init,
2685 .fini = mlxsw_sp2_ptp_fini,
2686 .receive = mlxsw_sp2_ptp_receive,
2687 .transmitted = mlxsw_sp2_ptp_transmitted,
2688 .hwtstamp_get = mlxsw_sp2_ptp_hwtstamp_get,
2689 .hwtstamp_set = mlxsw_sp2_ptp_hwtstamp_set,
2690 .shaper_work = mlxsw_sp2_ptp_shaper_work,
2691 .get_ts_info = mlxsw_sp2_ptp_get_ts_info,
2692 .get_stats_count = mlxsw_sp2_get_stats_count,
2693 .get_stats_strings = mlxsw_sp2_get_stats_strings,
2694 .get_stats = mlxsw_sp2_get_stats,
2695 };
2696
2697 struct mlxsw_sp_sample_trigger_node {
2698 struct mlxsw_sp_sample_trigger trigger;
2699 struct mlxsw_sp_sample_params params;
2700 struct rhash_head ht_node;
2701 struct rcu_head rcu;
2702 refcount_t refcount;
2703 };
2704
2705 static const struct rhashtable_params mlxsw_sp_sample_trigger_ht_params = {
2706 .key_offset = offsetof(struct mlxsw_sp_sample_trigger_node, trigger),
2707 .head_offset = offsetof(struct mlxsw_sp_sample_trigger_node, ht_node),
2708 .key_len = sizeof(struct mlxsw_sp_sample_trigger),
2709 .automatic_shrinking = true,
2710 };
2711
2712 static void
mlxsw_sp_sample_trigger_key_init(struct mlxsw_sp_sample_trigger * key,const struct mlxsw_sp_sample_trigger * trigger)2713 mlxsw_sp_sample_trigger_key_init(struct mlxsw_sp_sample_trigger *key,
2714 const struct mlxsw_sp_sample_trigger *trigger)
2715 {
2716 memset(key, 0, sizeof(*key));
2717 key->type = trigger->type;
2718 key->local_port = trigger->local_port;
2719 }
2720
2721 /* RCU read lock must be held */
2722 struct mlxsw_sp_sample_params *
mlxsw_sp_sample_trigger_params_lookup(struct mlxsw_sp * mlxsw_sp,const struct mlxsw_sp_sample_trigger * trigger)2723 mlxsw_sp_sample_trigger_params_lookup(struct mlxsw_sp *mlxsw_sp,
2724 const struct mlxsw_sp_sample_trigger *trigger)
2725 {
2726 struct mlxsw_sp_sample_trigger_node *trigger_node;
2727 struct mlxsw_sp_sample_trigger key;
2728
2729 mlxsw_sp_sample_trigger_key_init(&key, trigger);
2730 trigger_node = rhashtable_lookup(&mlxsw_sp->sample_trigger_ht, &key,
2731 mlxsw_sp_sample_trigger_ht_params);
2732 if (!trigger_node)
2733 return NULL;
2734
2735 return &trigger_node->params;
2736 }
2737
2738 static int
mlxsw_sp_sample_trigger_node_init(struct mlxsw_sp * mlxsw_sp,const struct mlxsw_sp_sample_trigger * trigger,const struct mlxsw_sp_sample_params * params)2739 mlxsw_sp_sample_trigger_node_init(struct mlxsw_sp *mlxsw_sp,
2740 const struct mlxsw_sp_sample_trigger *trigger,
2741 const struct mlxsw_sp_sample_params *params)
2742 {
2743 struct mlxsw_sp_sample_trigger_node *trigger_node;
2744 int err;
2745
2746 trigger_node = kzalloc(sizeof(*trigger_node), GFP_KERNEL);
2747 if (!trigger_node)
2748 return -ENOMEM;
2749
2750 trigger_node->trigger = *trigger;
2751 trigger_node->params = *params;
2752 refcount_set(&trigger_node->refcount, 1);
2753
2754 err = rhashtable_insert_fast(&mlxsw_sp->sample_trigger_ht,
2755 &trigger_node->ht_node,
2756 mlxsw_sp_sample_trigger_ht_params);
2757 if (err)
2758 goto err_rhashtable_insert;
2759
2760 return 0;
2761
2762 err_rhashtable_insert:
2763 kfree(trigger_node);
2764 return err;
2765 }
2766
2767 static void
mlxsw_sp_sample_trigger_node_fini(struct mlxsw_sp * mlxsw_sp,struct mlxsw_sp_sample_trigger_node * trigger_node)2768 mlxsw_sp_sample_trigger_node_fini(struct mlxsw_sp *mlxsw_sp,
2769 struct mlxsw_sp_sample_trigger_node *trigger_node)
2770 {
2771 rhashtable_remove_fast(&mlxsw_sp->sample_trigger_ht,
2772 &trigger_node->ht_node,
2773 mlxsw_sp_sample_trigger_ht_params);
2774 kfree_rcu(trigger_node, rcu);
2775 }
2776
2777 int
mlxsw_sp_sample_trigger_params_set(struct mlxsw_sp * mlxsw_sp,const struct mlxsw_sp_sample_trigger * trigger,const struct mlxsw_sp_sample_params * params,struct netlink_ext_ack * extack)2778 mlxsw_sp_sample_trigger_params_set(struct mlxsw_sp *mlxsw_sp,
2779 const struct mlxsw_sp_sample_trigger *trigger,
2780 const struct mlxsw_sp_sample_params *params,
2781 struct netlink_ext_ack *extack)
2782 {
2783 struct mlxsw_sp_sample_trigger_node *trigger_node;
2784 struct mlxsw_sp_sample_trigger key;
2785
2786 ASSERT_RTNL();
2787
2788 mlxsw_sp_sample_trigger_key_init(&key, trigger);
2789
2790 trigger_node = rhashtable_lookup_fast(&mlxsw_sp->sample_trigger_ht,
2791 &key,
2792 mlxsw_sp_sample_trigger_ht_params);
2793 if (!trigger_node)
2794 return mlxsw_sp_sample_trigger_node_init(mlxsw_sp, &key,
2795 params);
2796
2797 if (trigger_node->trigger.local_port) {
2798 NL_SET_ERR_MSG_MOD(extack, "Sampling already enabled on port");
2799 return -EINVAL;
2800 }
2801
2802 if (trigger_node->params.psample_group != params->psample_group ||
2803 trigger_node->params.truncate != params->truncate ||
2804 trigger_node->params.rate != params->rate ||
2805 trigger_node->params.trunc_size != params->trunc_size) {
2806 NL_SET_ERR_MSG_MOD(extack, "Sampling parameters do not match for an existing sampling trigger");
2807 return -EINVAL;
2808 }
2809
2810 refcount_inc(&trigger_node->refcount);
2811
2812 return 0;
2813 }
2814
2815 void
mlxsw_sp_sample_trigger_params_unset(struct mlxsw_sp * mlxsw_sp,const struct mlxsw_sp_sample_trigger * trigger)2816 mlxsw_sp_sample_trigger_params_unset(struct mlxsw_sp *mlxsw_sp,
2817 const struct mlxsw_sp_sample_trigger *trigger)
2818 {
2819 struct mlxsw_sp_sample_trigger_node *trigger_node;
2820 struct mlxsw_sp_sample_trigger key;
2821
2822 ASSERT_RTNL();
2823
2824 mlxsw_sp_sample_trigger_key_init(&key, trigger);
2825
2826 trigger_node = rhashtable_lookup_fast(&mlxsw_sp->sample_trigger_ht,
2827 &key,
2828 mlxsw_sp_sample_trigger_ht_params);
2829 if (!trigger_node)
2830 return;
2831
2832 if (!refcount_dec_and_test(&trigger_node->refcount))
2833 return;
2834
2835 mlxsw_sp_sample_trigger_node_fini(mlxsw_sp, trigger_node);
2836 }
2837
2838 static int mlxsw_sp_netdevice_event(struct notifier_block *unused,
2839 unsigned long event, void *ptr);
2840
2841 #define MLXSW_SP_DEFAULT_PARSING_DEPTH 96
2842 #define MLXSW_SP_INCREASED_PARSING_DEPTH 128
2843 #define MLXSW_SP_DEFAULT_VXLAN_UDP_DPORT 4789
2844
mlxsw_sp_parsing_init(struct mlxsw_sp * mlxsw_sp)2845 static void mlxsw_sp_parsing_init(struct mlxsw_sp *mlxsw_sp)
2846 {
2847 mlxsw_sp->parsing.parsing_depth = MLXSW_SP_DEFAULT_PARSING_DEPTH;
2848 mlxsw_sp->parsing.vxlan_udp_dport = MLXSW_SP_DEFAULT_VXLAN_UDP_DPORT;
2849 mutex_init(&mlxsw_sp->parsing.lock);
2850 }
2851
mlxsw_sp_parsing_fini(struct mlxsw_sp * mlxsw_sp)2852 static void mlxsw_sp_parsing_fini(struct mlxsw_sp *mlxsw_sp)
2853 {
2854 mutex_destroy(&mlxsw_sp->parsing.lock);
2855 }
2856
2857 struct mlxsw_sp_ipv6_addr_node {
2858 struct in6_addr key;
2859 struct rhash_head ht_node;
2860 u32 kvdl_index;
2861 refcount_t refcount;
2862 };
2863
2864 static const struct rhashtable_params mlxsw_sp_ipv6_addr_ht_params = {
2865 .key_offset = offsetof(struct mlxsw_sp_ipv6_addr_node, key),
2866 .head_offset = offsetof(struct mlxsw_sp_ipv6_addr_node, ht_node),
2867 .key_len = sizeof(struct in6_addr),
2868 .automatic_shrinking = true,
2869 };
2870
2871 static int
mlxsw_sp_ipv6_addr_init(struct mlxsw_sp * mlxsw_sp,const struct in6_addr * addr6,u32 * p_kvdl_index)2872 mlxsw_sp_ipv6_addr_init(struct mlxsw_sp *mlxsw_sp, const struct in6_addr *addr6,
2873 u32 *p_kvdl_index)
2874 {
2875 struct mlxsw_sp_ipv6_addr_node *node;
2876 char rips_pl[MLXSW_REG_RIPS_LEN];
2877 int err;
2878
2879 err = mlxsw_sp_kvdl_alloc(mlxsw_sp,
2880 MLXSW_SP_KVDL_ENTRY_TYPE_IPV6_ADDRESS, 1,
2881 p_kvdl_index);
2882 if (err)
2883 return err;
2884
2885 mlxsw_reg_rips_pack(rips_pl, *p_kvdl_index, addr6);
2886 err = mlxsw_reg_write(mlxsw_sp->core, MLXSW_REG(rips), rips_pl);
2887 if (err)
2888 goto err_rips_write;
2889
2890 node = kzalloc(sizeof(*node), GFP_KERNEL);
2891 if (!node) {
2892 err = -ENOMEM;
2893 goto err_node_alloc;
2894 }
2895
2896 node->key = *addr6;
2897 node->kvdl_index = *p_kvdl_index;
2898 refcount_set(&node->refcount, 1);
2899
2900 err = rhashtable_insert_fast(&mlxsw_sp->ipv6_addr_ht,
2901 &node->ht_node,
2902 mlxsw_sp_ipv6_addr_ht_params);
2903 if (err)
2904 goto err_rhashtable_insert;
2905
2906 return 0;
2907
2908 err_rhashtable_insert:
2909 kfree(node);
2910 err_node_alloc:
2911 err_rips_write:
2912 mlxsw_sp_kvdl_free(mlxsw_sp, MLXSW_SP_KVDL_ENTRY_TYPE_IPV6_ADDRESS, 1,
2913 *p_kvdl_index);
2914 return err;
2915 }
2916
mlxsw_sp_ipv6_addr_fini(struct mlxsw_sp * mlxsw_sp,struct mlxsw_sp_ipv6_addr_node * node)2917 static void mlxsw_sp_ipv6_addr_fini(struct mlxsw_sp *mlxsw_sp,
2918 struct mlxsw_sp_ipv6_addr_node *node)
2919 {
2920 u32 kvdl_index = node->kvdl_index;
2921
2922 rhashtable_remove_fast(&mlxsw_sp->ipv6_addr_ht, &node->ht_node,
2923 mlxsw_sp_ipv6_addr_ht_params);
2924 kfree(node);
2925 mlxsw_sp_kvdl_free(mlxsw_sp, MLXSW_SP_KVDL_ENTRY_TYPE_IPV6_ADDRESS, 1,
2926 kvdl_index);
2927 }
2928
mlxsw_sp_ipv6_addr_kvdl_index_get(struct mlxsw_sp * mlxsw_sp,const struct in6_addr * addr6,u32 * p_kvdl_index)2929 int mlxsw_sp_ipv6_addr_kvdl_index_get(struct mlxsw_sp *mlxsw_sp,
2930 const struct in6_addr *addr6,
2931 u32 *p_kvdl_index)
2932 {
2933 struct mlxsw_sp_ipv6_addr_node *node;
2934 int err = 0;
2935
2936 mutex_lock(&mlxsw_sp->ipv6_addr_ht_lock);
2937 node = rhashtable_lookup_fast(&mlxsw_sp->ipv6_addr_ht, addr6,
2938 mlxsw_sp_ipv6_addr_ht_params);
2939 if (node) {
2940 refcount_inc(&node->refcount);
2941 *p_kvdl_index = node->kvdl_index;
2942 goto out_unlock;
2943 }
2944
2945 err = mlxsw_sp_ipv6_addr_init(mlxsw_sp, addr6, p_kvdl_index);
2946
2947 out_unlock:
2948 mutex_unlock(&mlxsw_sp->ipv6_addr_ht_lock);
2949 return err;
2950 }
2951
2952 void
mlxsw_sp_ipv6_addr_put(struct mlxsw_sp * mlxsw_sp,const struct in6_addr * addr6)2953 mlxsw_sp_ipv6_addr_put(struct mlxsw_sp *mlxsw_sp, const struct in6_addr *addr6)
2954 {
2955 struct mlxsw_sp_ipv6_addr_node *node;
2956
2957 mutex_lock(&mlxsw_sp->ipv6_addr_ht_lock);
2958 node = rhashtable_lookup_fast(&mlxsw_sp->ipv6_addr_ht, addr6,
2959 mlxsw_sp_ipv6_addr_ht_params);
2960 if (WARN_ON(!node))
2961 goto out_unlock;
2962
2963 if (!refcount_dec_and_test(&node->refcount))
2964 goto out_unlock;
2965
2966 mlxsw_sp_ipv6_addr_fini(mlxsw_sp, node);
2967
2968 out_unlock:
2969 mutex_unlock(&mlxsw_sp->ipv6_addr_ht_lock);
2970 }
2971
mlxsw_sp_ipv6_addr_ht_init(struct mlxsw_sp * mlxsw_sp)2972 static int mlxsw_sp_ipv6_addr_ht_init(struct mlxsw_sp *mlxsw_sp)
2973 {
2974 int err;
2975
2976 err = rhashtable_init(&mlxsw_sp->ipv6_addr_ht,
2977 &mlxsw_sp_ipv6_addr_ht_params);
2978 if (err)
2979 return err;
2980
2981 mutex_init(&mlxsw_sp->ipv6_addr_ht_lock);
2982 return 0;
2983 }
2984
mlxsw_sp_ipv6_addr_ht_fini(struct mlxsw_sp * mlxsw_sp)2985 static void mlxsw_sp_ipv6_addr_ht_fini(struct mlxsw_sp *mlxsw_sp)
2986 {
2987 mutex_destroy(&mlxsw_sp->ipv6_addr_ht_lock);
2988 rhashtable_destroy(&mlxsw_sp->ipv6_addr_ht);
2989 }
2990
mlxsw_sp_init(struct mlxsw_core * mlxsw_core,const struct mlxsw_bus_info * mlxsw_bus_info,struct netlink_ext_ack * extack)2991 static int mlxsw_sp_init(struct mlxsw_core *mlxsw_core,
2992 const struct mlxsw_bus_info *mlxsw_bus_info,
2993 struct netlink_ext_ack *extack)
2994 {
2995 struct mlxsw_sp *mlxsw_sp = mlxsw_core_driver_priv(mlxsw_core);
2996 int err;
2997
2998 mlxsw_sp->core = mlxsw_core;
2999 mlxsw_sp->bus_info = mlxsw_bus_info;
3000
3001 mlxsw_sp_parsing_init(mlxsw_sp);
3002 mlxsw_core_emad_string_tlv_enable(mlxsw_core);
3003
3004 err = mlxsw_sp_base_mac_get(mlxsw_sp);
3005 if (err) {
3006 dev_err(mlxsw_sp->bus_info->dev, "Failed to get base mac\n");
3007 return err;
3008 }
3009
3010 err = mlxsw_sp_kvdl_init(mlxsw_sp);
3011 if (err) {
3012 dev_err(mlxsw_sp->bus_info->dev, "Failed to initialize KVDL\n");
3013 return err;
3014 }
3015
3016 err = mlxsw_sp_fids_init(mlxsw_sp);
3017 if (err) {
3018 dev_err(mlxsw_sp->bus_info->dev, "Failed to initialize FIDs\n");
3019 goto err_fids_init;
3020 }
3021
3022 err = mlxsw_sp_policers_init(mlxsw_sp);
3023 if (err) {
3024 dev_err(mlxsw_sp->bus_info->dev, "Failed to initialize policers\n");
3025 goto err_policers_init;
3026 }
3027
3028 err = mlxsw_sp_traps_init(mlxsw_sp);
3029 if (err) {
3030 dev_err(mlxsw_sp->bus_info->dev, "Failed to set traps\n");
3031 goto err_traps_init;
3032 }
3033
3034 err = mlxsw_sp_devlink_traps_init(mlxsw_sp);
3035 if (err) {
3036 dev_err(mlxsw_sp->bus_info->dev, "Failed to initialize devlink traps\n");
3037 goto err_devlink_traps_init;
3038 }
3039
3040 err = mlxsw_sp_buffers_init(mlxsw_sp);
3041 if (err) {
3042 dev_err(mlxsw_sp->bus_info->dev, "Failed to initialize buffers\n");
3043 goto err_buffers_init;
3044 }
3045
3046 err = mlxsw_sp_lag_init(mlxsw_sp);
3047 if (err) {
3048 dev_err(mlxsw_sp->bus_info->dev, "Failed to initialize LAG\n");
3049 goto err_lag_init;
3050 }
3051
3052 /* Initialize SPAN before router and switchdev, so that those components
3053 * can call mlxsw_sp_span_respin().
3054 */
3055 err = mlxsw_sp_span_init(mlxsw_sp);
3056 if (err) {
3057 dev_err(mlxsw_sp->bus_info->dev, "Failed to init span system\n");
3058 goto err_span_init;
3059 }
3060
3061 err = mlxsw_sp_switchdev_init(mlxsw_sp);
3062 if (err) {
3063 dev_err(mlxsw_sp->bus_info->dev, "Failed to initialize switchdev\n");
3064 goto err_switchdev_init;
3065 }
3066
3067 err = mlxsw_sp_counter_pool_init(mlxsw_sp);
3068 if (err) {
3069 dev_err(mlxsw_sp->bus_info->dev, "Failed to init counter pool\n");
3070 goto err_counter_pool_init;
3071 }
3072
3073 err = mlxsw_sp_afa_init(mlxsw_sp);
3074 if (err) {
3075 dev_err(mlxsw_sp->bus_info->dev, "Failed to initialize ACL actions\n");
3076 goto err_afa_init;
3077 }
3078
3079 err = mlxsw_sp_ipv6_addr_ht_init(mlxsw_sp);
3080 if (err) {
3081 dev_err(mlxsw_sp->bus_info->dev, "Failed to initialize hash table for IPv6 addresses\n");
3082 goto err_ipv6_addr_ht_init;
3083 }
3084
3085 err = mlxsw_sp_nve_init(mlxsw_sp);
3086 if (err) {
3087 dev_err(mlxsw_sp->bus_info->dev, "Failed to initialize NVE\n");
3088 goto err_nve_init;
3089 }
3090
3091 err = mlxsw_sp_acl_init(mlxsw_sp);
3092 if (err) {
3093 dev_err(mlxsw_sp->bus_info->dev, "Failed to initialize ACL\n");
3094 goto err_acl_init;
3095 }
3096
3097 err = mlxsw_sp_router_init(mlxsw_sp, extack);
3098 if (err) {
3099 dev_err(mlxsw_sp->bus_info->dev, "Failed to initialize router\n");
3100 goto err_router_init;
3101 }
3102
3103 if (mlxsw_sp->bus_info->read_frc_capable) {
3104 /* NULL is a valid return value from clock_init */
3105 mlxsw_sp->clock =
3106 mlxsw_sp->ptp_ops->clock_init(mlxsw_sp,
3107 mlxsw_sp->bus_info->dev);
3108 if (IS_ERR(mlxsw_sp->clock)) {
3109 err = PTR_ERR(mlxsw_sp->clock);
3110 dev_err(mlxsw_sp->bus_info->dev, "Failed to init ptp clock\n");
3111 goto err_ptp_clock_init;
3112 }
3113 }
3114
3115 if (mlxsw_sp->clock) {
3116 /* NULL is a valid return value from ptp_ops->init */
3117 mlxsw_sp->ptp_state = mlxsw_sp->ptp_ops->init(mlxsw_sp);
3118 if (IS_ERR(mlxsw_sp->ptp_state)) {
3119 err = PTR_ERR(mlxsw_sp->ptp_state);
3120 dev_err(mlxsw_sp->bus_info->dev, "Failed to initialize PTP\n");
3121 goto err_ptp_init;
3122 }
3123 }
3124
3125 /* Initialize netdevice notifier after SPAN is initialized, so that the
3126 * event handler can call SPAN respin.
3127 */
3128 mlxsw_sp->netdevice_nb.notifier_call = mlxsw_sp_netdevice_event;
3129 err = register_netdevice_notifier_net(mlxsw_sp_net(mlxsw_sp),
3130 &mlxsw_sp->netdevice_nb);
3131 if (err) {
3132 dev_err(mlxsw_sp->bus_info->dev, "Failed to register netdev notifier\n");
3133 goto err_netdev_notifier;
3134 }
3135
3136 err = mlxsw_sp_dpipe_init(mlxsw_sp);
3137 if (err) {
3138 dev_err(mlxsw_sp->bus_info->dev, "Failed to init pipeline debug\n");
3139 goto err_dpipe_init;
3140 }
3141
3142 err = mlxsw_sp_port_module_info_init(mlxsw_sp);
3143 if (err) {
3144 dev_err(mlxsw_sp->bus_info->dev, "Failed to init port module info\n");
3145 goto err_port_module_info_init;
3146 }
3147
3148 err = rhashtable_init(&mlxsw_sp->sample_trigger_ht,
3149 &mlxsw_sp_sample_trigger_ht_params);
3150 if (err) {
3151 dev_err(mlxsw_sp->bus_info->dev, "Failed to init sampling trigger hashtable\n");
3152 goto err_sample_trigger_init;
3153 }
3154
3155 err = mlxsw_sp_ports_create(mlxsw_sp);
3156 if (err) {
3157 dev_err(mlxsw_sp->bus_info->dev, "Failed to create ports\n");
3158 goto err_ports_create;
3159 }
3160
3161 return 0;
3162
3163 err_ports_create:
3164 rhashtable_destroy(&mlxsw_sp->sample_trigger_ht);
3165 err_sample_trigger_init:
3166 mlxsw_sp_port_module_info_fini(mlxsw_sp);
3167 err_port_module_info_init:
3168 mlxsw_sp_dpipe_fini(mlxsw_sp);
3169 err_dpipe_init:
3170 unregister_netdevice_notifier_net(mlxsw_sp_net(mlxsw_sp),
3171 &mlxsw_sp->netdevice_nb);
3172 err_netdev_notifier:
3173 if (mlxsw_sp->clock)
3174 mlxsw_sp->ptp_ops->fini(mlxsw_sp->ptp_state);
3175 err_ptp_init:
3176 if (mlxsw_sp->clock)
3177 mlxsw_sp->ptp_ops->clock_fini(mlxsw_sp->clock);
3178 err_ptp_clock_init:
3179 mlxsw_sp_router_fini(mlxsw_sp);
3180 err_router_init:
3181 mlxsw_sp_acl_fini(mlxsw_sp);
3182 err_acl_init:
3183 mlxsw_sp_nve_fini(mlxsw_sp);
3184 err_nve_init:
3185 mlxsw_sp_ipv6_addr_ht_fini(mlxsw_sp);
3186 err_ipv6_addr_ht_init:
3187 mlxsw_sp_afa_fini(mlxsw_sp);
3188 err_afa_init:
3189 mlxsw_sp_counter_pool_fini(mlxsw_sp);
3190 err_counter_pool_init:
3191 mlxsw_sp_switchdev_fini(mlxsw_sp);
3192 err_switchdev_init:
3193 mlxsw_sp_span_fini(mlxsw_sp);
3194 err_span_init:
3195 mlxsw_sp_lag_fini(mlxsw_sp);
3196 err_lag_init:
3197 mlxsw_sp_buffers_fini(mlxsw_sp);
3198 err_buffers_init:
3199 mlxsw_sp_devlink_traps_fini(mlxsw_sp);
3200 err_devlink_traps_init:
3201 mlxsw_sp_traps_fini(mlxsw_sp);
3202 err_traps_init:
3203 mlxsw_sp_policers_fini(mlxsw_sp);
3204 err_policers_init:
3205 mlxsw_sp_fids_fini(mlxsw_sp);
3206 err_fids_init:
3207 mlxsw_sp_kvdl_fini(mlxsw_sp);
3208 mlxsw_sp_parsing_fini(mlxsw_sp);
3209 return err;
3210 }
3211
mlxsw_sp1_init(struct mlxsw_core * mlxsw_core,const struct mlxsw_bus_info * mlxsw_bus_info,struct netlink_ext_ack * extack)3212 static int mlxsw_sp1_init(struct mlxsw_core *mlxsw_core,
3213 const struct mlxsw_bus_info *mlxsw_bus_info,
3214 struct netlink_ext_ack *extack)
3215 {
3216 struct mlxsw_sp *mlxsw_sp = mlxsw_core_driver_priv(mlxsw_core);
3217
3218 mlxsw_sp->switchdev_ops = &mlxsw_sp1_switchdev_ops;
3219 mlxsw_sp->kvdl_ops = &mlxsw_sp1_kvdl_ops;
3220 mlxsw_sp->afa_ops = &mlxsw_sp1_act_afa_ops;
3221 mlxsw_sp->afk_ops = &mlxsw_sp1_afk_ops;
3222 mlxsw_sp->mr_tcam_ops = &mlxsw_sp1_mr_tcam_ops;
3223 mlxsw_sp->acl_rulei_ops = &mlxsw_sp1_acl_rulei_ops;
3224 mlxsw_sp->acl_tcam_ops = &mlxsw_sp1_acl_tcam_ops;
3225 mlxsw_sp->nve_ops_arr = mlxsw_sp1_nve_ops_arr;
3226 mlxsw_sp->mac_mask = mlxsw_sp1_mac_mask;
3227 mlxsw_sp->sb_vals = &mlxsw_sp1_sb_vals;
3228 mlxsw_sp->sb_ops = &mlxsw_sp1_sb_ops;
3229 mlxsw_sp->port_type_speed_ops = &mlxsw_sp1_port_type_speed_ops;
3230 mlxsw_sp->ptp_ops = &mlxsw_sp1_ptp_ops;
3231 mlxsw_sp->span_ops = &mlxsw_sp1_span_ops;
3232 mlxsw_sp->policer_core_ops = &mlxsw_sp1_policer_core_ops;
3233 mlxsw_sp->trap_ops = &mlxsw_sp1_trap_ops;
3234 mlxsw_sp->mall_ops = &mlxsw_sp1_mall_ops;
3235 mlxsw_sp->router_ops = &mlxsw_sp1_router_ops;
3236 mlxsw_sp->listeners = mlxsw_sp1_listener;
3237 mlxsw_sp->listeners_count = ARRAY_SIZE(mlxsw_sp1_listener);
3238 mlxsw_sp->lowest_shaper_bs = MLXSW_REG_QEEC_LOWEST_SHAPER_BS_SP1;
3239
3240 return mlxsw_sp_init(mlxsw_core, mlxsw_bus_info, extack);
3241 }
3242
mlxsw_sp2_init(struct mlxsw_core * mlxsw_core,const struct mlxsw_bus_info * mlxsw_bus_info,struct netlink_ext_ack * extack)3243 static int mlxsw_sp2_init(struct mlxsw_core *mlxsw_core,
3244 const struct mlxsw_bus_info *mlxsw_bus_info,
3245 struct netlink_ext_ack *extack)
3246 {
3247 struct mlxsw_sp *mlxsw_sp = mlxsw_core_driver_priv(mlxsw_core);
3248
3249 mlxsw_sp->switchdev_ops = &mlxsw_sp2_switchdev_ops;
3250 mlxsw_sp->kvdl_ops = &mlxsw_sp2_kvdl_ops;
3251 mlxsw_sp->afa_ops = &mlxsw_sp2_act_afa_ops;
3252 mlxsw_sp->afk_ops = &mlxsw_sp2_afk_ops;
3253 mlxsw_sp->mr_tcam_ops = &mlxsw_sp2_mr_tcam_ops;
3254 mlxsw_sp->acl_rulei_ops = &mlxsw_sp2_acl_rulei_ops;
3255 mlxsw_sp->acl_tcam_ops = &mlxsw_sp2_acl_tcam_ops;
3256 mlxsw_sp->acl_bf_ops = &mlxsw_sp2_acl_bf_ops;
3257 mlxsw_sp->nve_ops_arr = mlxsw_sp2_nve_ops_arr;
3258 mlxsw_sp->mac_mask = mlxsw_sp2_mac_mask;
3259 mlxsw_sp->sb_vals = &mlxsw_sp2_sb_vals;
3260 mlxsw_sp->sb_ops = &mlxsw_sp2_sb_ops;
3261 mlxsw_sp->port_type_speed_ops = &mlxsw_sp2_port_type_speed_ops;
3262 mlxsw_sp->ptp_ops = &mlxsw_sp2_ptp_ops;
3263 mlxsw_sp->span_ops = &mlxsw_sp2_span_ops;
3264 mlxsw_sp->policer_core_ops = &mlxsw_sp2_policer_core_ops;
3265 mlxsw_sp->trap_ops = &mlxsw_sp2_trap_ops;
3266 mlxsw_sp->mall_ops = &mlxsw_sp2_mall_ops;
3267 mlxsw_sp->router_ops = &mlxsw_sp2_router_ops;
3268 mlxsw_sp->listeners = mlxsw_sp2_listener;
3269 mlxsw_sp->listeners_count = ARRAY_SIZE(mlxsw_sp2_listener);
3270 mlxsw_sp->lowest_shaper_bs = MLXSW_REG_QEEC_LOWEST_SHAPER_BS_SP2;
3271
3272 return mlxsw_sp_init(mlxsw_core, mlxsw_bus_info, extack);
3273 }
3274
mlxsw_sp3_init(struct mlxsw_core * mlxsw_core,const struct mlxsw_bus_info * mlxsw_bus_info,struct netlink_ext_ack * extack)3275 static int mlxsw_sp3_init(struct mlxsw_core *mlxsw_core,
3276 const struct mlxsw_bus_info *mlxsw_bus_info,
3277 struct netlink_ext_ack *extack)
3278 {
3279 struct mlxsw_sp *mlxsw_sp = mlxsw_core_driver_priv(mlxsw_core);
3280
3281 mlxsw_sp->switchdev_ops = &mlxsw_sp2_switchdev_ops;
3282 mlxsw_sp->kvdl_ops = &mlxsw_sp2_kvdl_ops;
3283 mlxsw_sp->afa_ops = &mlxsw_sp2_act_afa_ops;
3284 mlxsw_sp->afk_ops = &mlxsw_sp2_afk_ops;
3285 mlxsw_sp->mr_tcam_ops = &mlxsw_sp2_mr_tcam_ops;
3286 mlxsw_sp->acl_rulei_ops = &mlxsw_sp2_acl_rulei_ops;
3287 mlxsw_sp->acl_tcam_ops = &mlxsw_sp2_acl_tcam_ops;
3288 mlxsw_sp->acl_bf_ops = &mlxsw_sp2_acl_bf_ops;
3289 mlxsw_sp->nve_ops_arr = mlxsw_sp2_nve_ops_arr;
3290 mlxsw_sp->mac_mask = mlxsw_sp2_mac_mask;
3291 mlxsw_sp->sb_vals = &mlxsw_sp2_sb_vals;
3292 mlxsw_sp->sb_ops = &mlxsw_sp3_sb_ops;
3293 mlxsw_sp->port_type_speed_ops = &mlxsw_sp2_port_type_speed_ops;
3294 mlxsw_sp->ptp_ops = &mlxsw_sp2_ptp_ops;
3295 mlxsw_sp->span_ops = &mlxsw_sp3_span_ops;
3296 mlxsw_sp->policer_core_ops = &mlxsw_sp2_policer_core_ops;
3297 mlxsw_sp->trap_ops = &mlxsw_sp2_trap_ops;
3298 mlxsw_sp->mall_ops = &mlxsw_sp2_mall_ops;
3299 mlxsw_sp->router_ops = &mlxsw_sp2_router_ops;
3300 mlxsw_sp->listeners = mlxsw_sp2_listener;
3301 mlxsw_sp->listeners_count = ARRAY_SIZE(mlxsw_sp2_listener);
3302 mlxsw_sp->lowest_shaper_bs = MLXSW_REG_QEEC_LOWEST_SHAPER_BS_SP3;
3303
3304 return mlxsw_sp_init(mlxsw_core, mlxsw_bus_info, extack);
3305 }
3306
mlxsw_sp4_init(struct mlxsw_core * mlxsw_core,const struct mlxsw_bus_info * mlxsw_bus_info,struct netlink_ext_ack * extack)3307 static int mlxsw_sp4_init(struct mlxsw_core *mlxsw_core,
3308 const struct mlxsw_bus_info *mlxsw_bus_info,
3309 struct netlink_ext_ack *extack)
3310 {
3311 struct mlxsw_sp *mlxsw_sp = mlxsw_core_driver_priv(mlxsw_core);
3312
3313 mlxsw_sp->switchdev_ops = &mlxsw_sp2_switchdev_ops;
3314 mlxsw_sp->kvdl_ops = &mlxsw_sp2_kvdl_ops;
3315 mlxsw_sp->afa_ops = &mlxsw_sp2_act_afa_ops;
3316 mlxsw_sp->afk_ops = &mlxsw_sp4_afk_ops;
3317 mlxsw_sp->mr_tcam_ops = &mlxsw_sp2_mr_tcam_ops;
3318 mlxsw_sp->acl_rulei_ops = &mlxsw_sp2_acl_rulei_ops;
3319 mlxsw_sp->acl_tcam_ops = &mlxsw_sp2_acl_tcam_ops;
3320 mlxsw_sp->acl_bf_ops = &mlxsw_sp4_acl_bf_ops;
3321 mlxsw_sp->nve_ops_arr = mlxsw_sp2_nve_ops_arr;
3322 mlxsw_sp->mac_mask = mlxsw_sp2_mac_mask;
3323 mlxsw_sp->sb_vals = &mlxsw_sp2_sb_vals;
3324 mlxsw_sp->sb_ops = &mlxsw_sp3_sb_ops;
3325 mlxsw_sp->port_type_speed_ops = &mlxsw_sp2_port_type_speed_ops;
3326 mlxsw_sp->ptp_ops = &mlxsw_sp2_ptp_ops;
3327 mlxsw_sp->span_ops = &mlxsw_sp3_span_ops;
3328 mlxsw_sp->policer_core_ops = &mlxsw_sp2_policer_core_ops;
3329 mlxsw_sp->trap_ops = &mlxsw_sp2_trap_ops;
3330 mlxsw_sp->mall_ops = &mlxsw_sp2_mall_ops;
3331 mlxsw_sp->router_ops = &mlxsw_sp2_router_ops;
3332 mlxsw_sp->listeners = mlxsw_sp2_listener;
3333 mlxsw_sp->listeners_count = ARRAY_SIZE(mlxsw_sp2_listener);
3334 mlxsw_sp->lowest_shaper_bs = MLXSW_REG_QEEC_LOWEST_SHAPER_BS_SP4;
3335
3336 return mlxsw_sp_init(mlxsw_core, mlxsw_bus_info, extack);
3337 }
3338
mlxsw_sp_fini(struct mlxsw_core * mlxsw_core)3339 static void mlxsw_sp_fini(struct mlxsw_core *mlxsw_core)
3340 {
3341 struct mlxsw_sp *mlxsw_sp = mlxsw_core_driver_priv(mlxsw_core);
3342
3343 mlxsw_sp_ports_remove(mlxsw_sp);
3344 rhashtable_destroy(&mlxsw_sp->sample_trigger_ht);
3345 mlxsw_sp_port_module_info_fini(mlxsw_sp);
3346 mlxsw_sp_dpipe_fini(mlxsw_sp);
3347 unregister_netdevice_notifier_net(mlxsw_sp_net(mlxsw_sp),
3348 &mlxsw_sp->netdevice_nb);
3349 if (mlxsw_sp->clock) {
3350 mlxsw_sp->ptp_ops->fini(mlxsw_sp->ptp_state);
3351 mlxsw_sp->ptp_ops->clock_fini(mlxsw_sp->clock);
3352 }
3353 mlxsw_sp_router_fini(mlxsw_sp);
3354 mlxsw_sp_acl_fini(mlxsw_sp);
3355 mlxsw_sp_nve_fini(mlxsw_sp);
3356 mlxsw_sp_ipv6_addr_ht_fini(mlxsw_sp);
3357 mlxsw_sp_afa_fini(mlxsw_sp);
3358 mlxsw_sp_counter_pool_fini(mlxsw_sp);
3359 mlxsw_sp_switchdev_fini(mlxsw_sp);
3360 mlxsw_sp_span_fini(mlxsw_sp);
3361 mlxsw_sp_lag_fini(mlxsw_sp);
3362 mlxsw_sp_buffers_fini(mlxsw_sp);
3363 mlxsw_sp_devlink_traps_fini(mlxsw_sp);
3364 mlxsw_sp_traps_fini(mlxsw_sp);
3365 mlxsw_sp_policers_fini(mlxsw_sp);
3366 mlxsw_sp_fids_fini(mlxsw_sp);
3367 mlxsw_sp_kvdl_fini(mlxsw_sp);
3368 mlxsw_sp_parsing_fini(mlxsw_sp);
3369 }
3370
3371 /* Per-FID flood tables are used for both "true" 802.1D FIDs and emulated
3372 * 802.1Q FIDs
3373 */
3374 #define MLXSW_SP_FID_FLOOD_TABLE_SIZE (MLXSW_SP_FID_8021D_MAX + \
3375 VLAN_VID_MASK - 1)
3376
3377 static const struct mlxsw_config_profile mlxsw_sp1_config_profile = {
3378 .used_max_mid = 1,
3379 .max_mid = MLXSW_SP_MID_MAX,
3380 .used_flood_tables = 1,
3381 .used_flood_mode = 1,
3382 .flood_mode = 3,
3383 .max_fid_flood_tables = 3,
3384 .fid_flood_table_size = MLXSW_SP_FID_FLOOD_TABLE_SIZE,
3385 .used_max_ib_mc = 1,
3386 .max_ib_mc = 0,
3387 .used_max_pkey = 1,
3388 .max_pkey = 0,
3389 .used_kvd_sizes = 1,
3390 .kvd_hash_single_parts = 59,
3391 .kvd_hash_double_parts = 41,
3392 .kvd_linear_size = MLXSW_SP_KVD_LINEAR_SIZE,
3393 .swid_config = {
3394 {
3395 .used_type = 1,
3396 .type = MLXSW_PORT_SWID_TYPE_ETH,
3397 }
3398 },
3399 };
3400
3401 static const struct mlxsw_config_profile mlxsw_sp2_config_profile = {
3402 .used_max_mid = 1,
3403 .max_mid = MLXSW_SP_MID_MAX,
3404 .used_flood_tables = 1,
3405 .used_flood_mode = 1,
3406 .flood_mode = 3,
3407 .max_fid_flood_tables = 3,
3408 .fid_flood_table_size = MLXSW_SP_FID_FLOOD_TABLE_SIZE,
3409 .used_max_ib_mc = 1,
3410 .max_ib_mc = 0,
3411 .used_max_pkey = 1,
3412 .max_pkey = 0,
3413 .used_kvh_xlt_cache_mode = 1,
3414 .kvh_xlt_cache_mode = 1,
3415 .swid_config = {
3416 {
3417 .used_type = 1,
3418 .type = MLXSW_PORT_SWID_TYPE_ETH,
3419 }
3420 },
3421 };
3422
3423 static void
mlxsw_sp_resource_size_params_prepare(struct mlxsw_core * mlxsw_core,struct devlink_resource_size_params * kvd_size_params,struct devlink_resource_size_params * linear_size_params,struct devlink_resource_size_params * hash_double_size_params,struct devlink_resource_size_params * hash_single_size_params)3424 mlxsw_sp_resource_size_params_prepare(struct mlxsw_core *mlxsw_core,
3425 struct devlink_resource_size_params *kvd_size_params,
3426 struct devlink_resource_size_params *linear_size_params,
3427 struct devlink_resource_size_params *hash_double_size_params,
3428 struct devlink_resource_size_params *hash_single_size_params)
3429 {
3430 u32 single_size_min = MLXSW_CORE_RES_GET(mlxsw_core,
3431 KVD_SINGLE_MIN_SIZE);
3432 u32 double_size_min = MLXSW_CORE_RES_GET(mlxsw_core,
3433 KVD_DOUBLE_MIN_SIZE);
3434 u32 kvd_size = MLXSW_CORE_RES_GET(mlxsw_core, KVD_SIZE);
3435 u32 linear_size_min = 0;
3436
3437 devlink_resource_size_params_init(kvd_size_params, kvd_size, kvd_size,
3438 MLXSW_SP_KVD_GRANULARITY,
3439 DEVLINK_RESOURCE_UNIT_ENTRY);
3440 devlink_resource_size_params_init(linear_size_params, linear_size_min,
3441 kvd_size - single_size_min -
3442 double_size_min,
3443 MLXSW_SP_KVD_GRANULARITY,
3444 DEVLINK_RESOURCE_UNIT_ENTRY);
3445 devlink_resource_size_params_init(hash_double_size_params,
3446 double_size_min,
3447 kvd_size - single_size_min -
3448 linear_size_min,
3449 MLXSW_SP_KVD_GRANULARITY,
3450 DEVLINK_RESOURCE_UNIT_ENTRY);
3451 devlink_resource_size_params_init(hash_single_size_params,
3452 single_size_min,
3453 kvd_size - double_size_min -
3454 linear_size_min,
3455 MLXSW_SP_KVD_GRANULARITY,
3456 DEVLINK_RESOURCE_UNIT_ENTRY);
3457 }
3458
mlxsw_sp1_resources_kvd_register(struct mlxsw_core * mlxsw_core)3459 static int mlxsw_sp1_resources_kvd_register(struct mlxsw_core *mlxsw_core)
3460 {
3461 struct devlink *devlink = priv_to_devlink(mlxsw_core);
3462 struct devlink_resource_size_params hash_single_size_params;
3463 struct devlink_resource_size_params hash_double_size_params;
3464 struct devlink_resource_size_params linear_size_params;
3465 struct devlink_resource_size_params kvd_size_params;
3466 u32 kvd_size, single_size, double_size, linear_size;
3467 const struct mlxsw_config_profile *profile;
3468 int err;
3469
3470 profile = &mlxsw_sp1_config_profile;
3471 if (!MLXSW_CORE_RES_VALID(mlxsw_core, KVD_SIZE))
3472 return -EIO;
3473
3474 mlxsw_sp_resource_size_params_prepare(mlxsw_core, &kvd_size_params,
3475 &linear_size_params,
3476 &hash_double_size_params,
3477 &hash_single_size_params);
3478
3479 kvd_size = MLXSW_CORE_RES_GET(mlxsw_core, KVD_SIZE);
3480 err = devlink_resource_register(devlink, MLXSW_SP_RESOURCE_NAME_KVD,
3481 kvd_size, MLXSW_SP_RESOURCE_KVD,
3482 DEVLINK_RESOURCE_ID_PARENT_TOP,
3483 &kvd_size_params);
3484 if (err)
3485 return err;
3486
3487 linear_size = profile->kvd_linear_size;
3488 err = devlink_resource_register(devlink, MLXSW_SP_RESOURCE_NAME_KVD_LINEAR,
3489 linear_size,
3490 MLXSW_SP_RESOURCE_KVD_LINEAR,
3491 MLXSW_SP_RESOURCE_KVD,
3492 &linear_size_params);
3493 if (err)
3494 return err;
3495
3496 err = mlxsw_sp1_kvdl_resources_register(mlxsw_core);
3497 if (err)
3498 return err;
3499
3500 double_size = kvd_size - linear_size;
3501 double_size *= profile->kvd_hash_double_parts;
3502 double_size /= profile->kvd_hash_double_parts +
3503 profile->kvd_hash_single_parts;
3504 double_size = rounddown(double_size, MLXSW_SP_KVD_GRANULARITY);
3505 err = devlink_resource_register(devlink, MLXSW_SP_RESOURCE_NAME_KVD_HASH_DOUBLE,
3506 double_size,
3507 MLXSW_SP_RESOURCE_KVD_HASH_DOUBLE,
3508 MLXSW_SP_RESOURCE_KVD,
3509 &hash_double_size_params);
3510 if (err)
3511 return err;
3512
3513 single_size = kvd_size - double_size - linear_size;
3514 err = devlink_resource_register(devlink, MLXSW_SP_RESOURCE_NAME_KVD_HASH_SINGLE,
3515 single_size,
3516 MLXSW_SP_RESOURCE_KVD_HASH_SINGLE,
3517 MLXSW_SP_RESOURCE_KVD,
3518 &hash_single_size_params);
3519 if (err)
3520 return err;
3521
3522 return 0;
3523 }
3524
mlxsw_sp2_resources_kvd_register(struct mlxsw_core * mlxsw_core)3525 static int mlxsw_sp2_resources_kvd_register(struct mlxsw_core *mlxsw_core)
3526 {
3527 struct devlink *devlink = priv_to_devlink(mlxsw_core);
3528 struct devlink_resource_size_params kvd_size_params;
3529 u32 kvd_size;
3530
3531 if (!MLXSW_CORE_RES_VALID(mlxsw_core, KVD_SIZE))
3532 return -EIO;
3533
3534 kvd_size = MLXSW_CORE_RES_GET(mlxsw_core, KVD_SIZE);
3535 devlink_resource_size_params_init(&kvd_size_params, kvd_size, kvd_size,
3536 MLXSW_SP_KVD_GRANULARITY,
3537 DEVLINK_RESOURCE_UNIT_ENTRY);
3538
3539 return devlink_resource_register(devlink, MLXSW_SP_RESOURCE_NAME_KVD,
3540 kvd_size, MLXSW_SP_RESOURCE_KVD,
3541 DEVLINK_RESOURCE_ID_PARENT_TOP,
3542 &kvd_size_params);
3543 }
3544
mlxsw_sp_resources_span_register(struct mlxsw_core * mlxsw_core)3545 static int mlxsw_sp_resources_span_register(struct mlxsw_core *mlxsw_core)
3546 {
3547 struct devlink *devlink = priv_to_devlink(mlxsw_core);
3548 struct devlink_resource_size_params span_size_params;
3549 u32 max_span;
3550
3551 if (!MLXSW_CORE_RES_VALID(mlxsw_core, MAX_SPAN))
3552 return -EIO;
3553
3554 max_span = MLXSW_CORE_RES_GET(mlxsw_core, MAX_SPAN);
3555 devlink_resource_size_params_init(&span_size_params, max_span, max_span,
3556 1, DEVLINK_RESOURCE_UNIT_ENTRY);
3557
3558 return devlink_resource_register(devlink, MLXSW_SP_RESOURCE_NAME_SPAN,
3559 max_span, MLXSW_SP_RESOURCE_SPAN,
3560 DEVLINK_RESOURCE_ID_PARENT_TOP,
3561 &span_size_params);
3562 }
3563
3564 static int
mlxsw_sp_resources_rif_mac_profile_register(struct mlxsw_core * mlxsw_core)3565 mlxsw_sp_resources_rif_mac_profile_register(struct mlxsw_core *mlxsw_core)
3566 {
3567 struct devlink *devlink = priv_to_devlink(mlxsw_core);
3568 struct devlink_resource_size_params size_params;
3569 u8 max_rif_mac_profiles;
3570
3571 if (!MLXSW_CORE_RES_VALID(mlxsw_core, MAX_RIF_MAC_PROFILES))
3572 max_rif_mac_profiles = 1;
3573 else
3574 max_rif_mac_profiles = MLXSW_CORE_RES_GET(mlxsw_core,
3575 MAX_RIF_MAC_PROFILES);
3576 devlink_resource_size_params_init(&size_params, max_rif_mac_profiles,
3577 max_rif_mac_profiles, 1,
3578 DEVLINK_RESOURCE_UNIT_ENTRY);
3579
3580 return devlink_resource_register(devlink,
3581 "rif_mac_profiles",
3582 max_rif_mac_profiles,
3583 MLXSW_SP_RESOURCE_RIF_MAC_PROFILES,
3584 DEVLINK_RESOURCE_ID_PARENT_TOP,
3585 &size_params);
3586 }
3587
mlxsw_sp1_resources_register(struct mlxsw_core * mlxsw_core)3588 static int mlxsw_sp1_resources_register(struct mlxsw_core *mlxsw_core)
3589 {
3590 int err;
3591
3592 err = mlxsw_sp1_resources_kvd_register(mlxsw_core);
3593 if (err)
3594 return err;
3595
3596 err = mlxsw_sp_resources_span_register(mlxsw_core);
3597 if (err)
3598 goto err_resources_span_register;
3599
3600 err = mlxsw_sp_counter_resources_register(mlxsw_core);
3601 if (err)
3602 goto err_resources_counter_register;
3603
3604 err = mlxsw_sp_policer_resources_register(mlxsw_core);
3605 if (err)
3606 goto err_policer_resources_register;
3607
3608 err = mlxsw_sp_resources_rif_mac_profile_register(mlxsw_core);
3609 if (err)
3610 goto err_resources_rif_mac_profile_register;
3611
3612 return 0;
3613
3614 err_resources_rif_mac_profile_register:
3615 err_policer_resources_register:
3616 err_resources_counter_register:
3617 err_resources_span_register:
3618 devlink_resources_unregister(priv_to_devlink(mlxsw_core));
3619 return err;
3620 }
3621
mlxsw_sp2_resources_register(struct mlxsw_core * mlxsw_core)3622 static int mlxsw_sp2_resources_register(struct mlxsw_core *mlxsw_core)
3623 {
3624 int err;
3625
3626 err = mlxsw_sp2_resources_kvd_register(mlxsw_core);
3627 if (err)
3628 return err;
3629
3630 err = mlxsw_sp_resources_span_register(mlxsw_core);
3631 if (err)
3632 goto err_resources_span_register;
3633
3634 err = mlxsw_sp_counter_resources_register(mlxsw_core);
3635 if (err)
3636 goto err_resources_counter_register;
3637
3638 err = mlxsw_sp_policer_resources_register(mlxsw_core);
3639 if (err)
3640 goto err_policer_resources_register;
3641
3642 err = mlxsw_sp_resources_rif_mac_profile_register(mlxsw_core);
3643 if (err)
3644 goto err_resources_rif_mac_profile_register;
3645
3646 return 0;
3647
3648 err_resources_rif_mac_profile_register:
3649 err_policer_resources_register:
3650 err_resources_counter_register:
3651 err_resources_span_register:
3652 devlink_resources_unregister(priv_to_devlink(mlxsw_core));
3653 return err;
3654 }
3655
mlxsw_sp_kvd_sizes_get(struct mlxsw_core * mlxsw_core,const struct mlxsw_config_profile * profile,u64 * p_single_size,u64 * p_double_size,u64 * p_linear_size)3656 static int mlxsw_sp_kvd_sizes_get(struct mlxsw_core *mlxsw_core,
3657 const struct mlxsw_config_profile *profile,
3658 u64 *p_single_size, u64 *p_double_size,
3659 u64 *p_linear_size)
3660 {
3661 struct devlink *devlink = priv_to_devlink(mlxsw_core);
3662 u32 double_size;
3663 int err;
3664
3665 if (!MLXSW_CORE_RES_VALID(mlxsw_core, KVD_SINGLE_MIN_SIZE) ||
3666 !MLXSW_CORE_RES_VALID(mlxsw_core, KVD_DOUBLE_MIN_SIZE))
3667 return -EIO;
3668
3669 /* The hash part is what left of the kvd without the
3670 * linear part. It is split to the single size and
3671 * double size by the parts ratio from the profile.
3672 * Both sizes must be a multiplications of the
3673 * granularity from the profile. In case the user
3674 * provided the sizes they are obtained via devlink.
3675 */
3676 err = devlink_resource_size_get(devlink,
3677 MLXSW_SP_RESOURCE_KVD_LINEAR,
3678 p_linear_size);
3679 if (err)
3680 *p_linear_size = profile->kvd_linear_size;
3681
3682 err = devlink_resource_size_get(devlink,
3683 MLXSW_SP_RESOURCE_KVD_HASH_DOUBLE,
3684 p_double_size);
3685 if (err) {
3686 double_size = MLXSW_CORE_RES_GET(mlxsw_core, KVD_SIZE) -
3687 *p_linear_size;
3688 double_size *= profile->kvd_hash_double_parts;
3689 double_size /= profile->kvd_hash_double_parts +
3690 profile->kvd_hash_single_parts;
3691 *p_double_size = rounddown(double_size,
3692 MLXSW_SP_KVD_GRANULARITY);
3693 }
3694
3695 err = devlink_resource_size_get(devlink,
3696 MLXSW_SP_RESOURCE_KVD_HASH_SINGLE,
3697 p_single_size);
3698 if (err)
3699 *p_single_size = MLXSW_CORE_RES_GET(mlxsw_core, KVD_SIZE) -
3700 *p_double_size - *p_linear_size;
3701
3702 /* Check results are legal. */
3703 if (*p_single_size < MLXSW_CORE_RES_GET(mlxsw_core, KVD_SINGLE_MIN_SIZE) ||
3704 *p_double_size < MLXSW_CORE_RES_GET(mlxsw_core, KVD_DOUBLE_MIN_SIZE) ||
3705 MLXSW_CORE_RES_GET(mlxsw_core, KVD_SIZE) < *p_linear_size)
3706 return -EIO;
3707
3708 return 0;
3709 }
3710
3711 static int
mlxsw_sp_params_acl_region_rehash_intrvl_get(struct devlink * devlink,u32 id,struct devlink_param_gset_ctx * ctx)3712 mlxsw_sp_params_acl_region_rehash_intrvl_get(struct devlink *devlink, u32 id,
3713 struct devlink_param_gset_ctx *ctx)
3714 {
3715 struct mlxsw_core *mlxsw_core = devlink_priv(devlink);
3716 struct mlxsw_sp *mlxsw_sp = mlxsw_core_driver_priv(mlxsw_core);
3717
3718 ctx->val.vu32 = mlxsw_sp_acl_region_rehash_intrvl_get(mlxsw_sp);
3719 return 0;
3720 }
3721
3722 static int
mlxsw_sp_params_acl_region_rehash_intrvl_set(struct devlink * devlink,u32 id,struct devlink_param_gset_ctx * ctx)3723 mlxsw_sp_params_acl_region_rehash_intrvl_set(struct devlink *devlink, u32 id,
3724 struct devlink_param_gset_ctx *ctx)
3725 {
3726 struct mlxsw_core *mlxsw_core = devlink_priv(devlink);
3727 struct mlxsw_sp *mlxsw_sp = mlxsw_core_driver_priv(mlxsw_core);
3728
3729 return mlxsw_sp_acl_region_rehash_intrvl_set(mlxsw_sp, ctx->val.vu32);
3730 }
3731
3732 static const struct devlink_param mlxsw_sp2_devlink_params[] = {
3733 DEVLINK_PARAM_DRIVER(MLXSW_DEVLINK_PARAM_ID_ACL_REGION_REHASH_INTERVAL,
3734 "acl_region_rehash_interval",
3735 DEVLINK_PARAM_TYPE_U32,
3736 BIT(DEVLINK_PARAM_CMODE_RUNTIME),
3737 mlxsw_sp_params_acl_region_rehash_intrvl_get,
3738 mlxsw_sp_params_acl_region_rehash_intrvl_set,
3739 NULL),
3740 };
3741
mlxsw_sp2_params_register(struct mlxsw_core * mlxsw_core)3742 static int mlxsw_sp2_params_register(struct mlxsw_core *mlxsw_core)
3743 {
3744 struct devlink *devlink = priv_to_devlink(mlxsw_core);
3745 union devlink_param_value value;
3746 int err;
3747
3748 err = devlink_params_register(devlink, mlxsw_sp2_devlink_params,
3749 ARRAY_SIZE(mlxsw_sp2_devlink_params));
3750 if (err)
3751 return err;
3752
3753 value.vu32 = 0;
3754 devlink_param_driverinit_value_set(devlink,
3755 MLXSW_DEVLINK_PARAM_ID_ACL_REGION_REHASH_INTERVAL,
3756 value);
3757 return 0;
3758 }
3759
mlxsw_sp2_params_unregister(struct mlxsw_core * mlxsw_core)3760 static void mlxsw_sp2_params_unregister(struct mlxsw_core *mlxsw_core)
3761 {
3762 devlink_params_unregister(priv_to_devlink(mlxsw_core),
3763 mlxsw_sp2_devlink_params,
3764 ARRAY_SIZE(mlxsw_sp2_devlink_params));
3765 }
3766
mlxsw_sp_ptp_transmitted(struct mlxsw_core * mlxsw_core,struct sk_buff * skb,u16 local_port)3767 static void mlxsw_sp_ptp_transmitted(struct mlxsw_core *mlxsw_core,
3768 struct sk_buff *skb, u16 local_port)
3769 {
3770 struct mlxsw_sp *mlxsw_sp = mlxsw_core_driver_priv(mlxsw_core);
3771
3772 skb_pull(skb, MLXSW_TXHDR_LEN);
3773 mlxsw_sp->ptp_ops->transmitted(mlxsw_sp, skb, local_port);
3774 }
3775
3776 static struct mlxsw_driver mlxsw_sp1_driver = {
3777 .kind = mlxsw_sp1_driver_name,
3778 .priv_size = sizeof(struct mlxsw_sp),
3779 .fw_req_rev = &mlxsw_sp1_fw_rev,
3780 .fw_filename = MLXSW_SP1_FW_FILENAME,
3781 .init = mlxsw_sp1_init,
3782 .fini = mlxsw_sp_fini,
3783 .port_split = mlxsw_sp_port_split,
3784 .port_unsplit = mlxsw_sp_port_unsplit,
3785 .sb_pool_get = mlxsw_sp_sb_pool_get,
3786 .sb_pool_set = mlxsw_sp_sb_pool_set,
3787 .sb_port_pool_get = mlxsw_sp_sb_port_pool_get,
3788 .sb_port_pool_set = mlxsw_sp_sb_port_pool_set,
3789 .sb_tc_pool_bind_get = mlxsw_sp_sb_tc_pool_bind_get,
3790 .sb_tc_pool_bind_set = mlxsw_sp_sb_tc_pool_bind_set,
3791 .sb_occ_snapshot = mlxsw_sp_sb_occ_snapshot,
3792 .sb_occ_max_clear = mlxsw_sp_sb_occ_max_clear,
3793 .sb_occ_port_pool_get = mlxsw_sp_sb_occ_port_pool_get,
3794 .sb_occ_tc_port_bind_get = mlxsw_sp_sb_occ_tc_port_bind_get,
3795 .trap_init = mlxsw_sp_trap_init,
3796 .trap_fini = mlxsw_sp_trap_fini,
3797 .trap_action_set = mlxsw_sp_trap_action_set,
3798 .trap_group_init = mlxsw_sp_trap_group_init,
3799 .trap_group_set = mlxsw_sp_trap_group_set,
3800 .trap_policer_init = mlxsw_sp_trap_policer_init,
3801 .trap_policer_fini = mlxsw_sp_trap_policer_fini,
3802 .trap_policer_set = mlxsw_sp_trap_policer_set,
3803 .trap_policer_counter_get = mlxsw_sp_trap_policer_counter_get,
3804 .txhdr_construct = mlxsw_sp_txhdr_construct,
3805 .resources_register = mlxsw_sp1_resources_register,
3806 .kvd_sizes_get = mlxsw_sp_kvd_sizes_get,
3807 .ptp_transmitted = mlxsw_sp_ptp_transmitted,
3808 .txhdr_len = MLXSW_TXHDR_LEN,
3809 .profile = &mlxsw_sp1_config_profile,
3810 };
3811
3812 static struct mlxsw_driver mlxsw_sp2_driver = {
3813 .kind = mlxsw_sp2_driver_name,
3814 .priv_size = sizeof(struct mlxsw_sp),
3815 .fw_req_rev = &mlxsw_sp2_fw_rev,
3816 .fw_filename = MLXSW_SP2_FW_FILENAME,
3817 .init = mlxsw_sp2_init,
3818 .fini = mlxsw_sp_fini,
3819 .port_split = mlxsw_sp_port_split,
3820 .port_unsplit = mlxsw_sp_port_unsplit,
3821 .ports_remove_selected = mlxsw_sp_ports_remove_selected,
3822 .sb_pool_get = mlxsw_sp_sb_pool_get,
3823 .sb_pool_set = mlxsw_sp_sb_pool_set,
3824 .sb_port_pool_get = mlxsw_sp_sb_port_pool_get,
3825 .sb_port_pool_set = mlxsw_sp_sb_port_pool_set,
3826 .sb_tc_pool_bind_get = mlxsw_sp_sb_tc_pool_bind_get,
3827 .sb_tc_pool_bind_set = mlxsw_sp_sb_tc_pool_bind_set,
3828 .sb_occ_snapshot = mlxsw_sp_sb_occ_snapshot,
3829 .sb_occ_max_clear = mlxsw_sp_sb_occ_max_clear,
3830 .sb_occ_port_pool_get = mlxsw_sp_sb_occ_port_pool_get,
3831 .sb_occ_tc_port_bind_get = mlxsw_sp_sb_occ_tc_port_bind_get,
3832 .trap_init = mlxsw_sp_trap_init,
3833 .trap_fini = mlxsw_sp_trap_fini,
3834 .trap_action_set = mlxsw_sp_trap_action_set,
3835 .trap_group_init = mlxsw_sp_trap_group_init,
3836 .trap_group_set = mlxsw_sp_trap_group_set,
3837 .trap_policer_init = mlxsw_sp_trap_policer_init,
3838 .trap_policer_fini = mlxsw_sp_trap_policer_fini,
3839 .trap_policer_set = mlxsw_sp_trap_policer_set,
3840 .trap_policer_counter_get = mlxsw_sp_trap_policer_counter_get,
3841 .txhdr_construct = mlxsw_sp_txhdr_construct,
3842 .resources_register = mlxsw_sp2_resources_register,
3843 .params_register = mlxsw_sp2_params_register,
3844 .params_unregister = mlxsw_sp2_params_unregister,
3845 .ptp_transmitted = mlxsw_sp_ptp_transmitted,
3846 .txhdr_len = MLXSW_TXHDR_LEN,
3847 .profile = &mlxsw_sp2_config_profile,
3848 };
3849
3850 static struct mlxsw_driver mlxsw_sp3_driver = {
3851 .kind = mlxsw_sp3_driver_name,
3852 .priv_size = sizeof(struct mlxsw_sp),
3853 .fw_req_rev = &mlxsw_sp3_fw_rev,
3854 .fw_filename = MLXSW_SP3_FW_FILENAME,
3855 .init = mlxsw_sp3_init,
3856 .fini = mlxsw_sp_fini,
3857 .port_split = mlxsw_sp_port_split,
3858 .port_unsplit = mlxsw_sp_port_unsplit,
3859 .ports_remove_selected = mlxsw_sp_ports_remove_selected,
3860 .sb_pool_get = mlxsw_sp_sb_pool_get,
3861 .sb_pool_set = mlxsw_sp_sb_pool_set,
3862 .sb_port_pool_get = mlxsw_sp_sb_port_pool_get,
3863 .sb_port_pool_set = mlxsw_sp_sb_port_pool_set,
3864 .sb_tc_pool_bind_get = mlxsw_sp_sb_tc_pool_bind_get,
3865 .sb_tc_pool_bind_set = mlxsw_sp_sb_tc_pool_bind_set,
3866 .sb_occ_snapshot = mlxsw_sp_sb_occ_snapshot,
3867 .sb_occ_max_clear = mlxsw_sp_sb_occ_max_clear,
3868 .sb_occ_port_pool_get = mlxsw_sp_sb_occ_port_pool_get,
3869 .sb_occ_tc_port_bind_get = mlxsw_sp_sb_occ_tc_port_bind_get,
3870 .trap_init = mlxsw_sp_trap_init,
3871 .trap_fini = mlxsw_sp_trap_fini,
3872 .trap_action_set = mlxsw_sp_trap_action_set,
3873 .trap_group_init = mlxsw_sp_trap_group_init,
3874 .trap_group_set = mlxsw_sp_trap_group_set,
3875 .trap_policer_init = mlxsw_sp_trap_policer_init,
3876 .trap_policer_fini = mlxsw_sp_trap_policer_fini,
3877 .trap_policer_set = mlxsw_sp_trap_policer_set,
3878 .trap_policer_counter_get = mlxsw_sp_trap_policer_counter_get,
3879 .txhdr_construct = mlxsw_sp_txhdr_construct,
3880 .resources_register = mlxsw_sp2_resources_register,
3881 .params_register = mlxsw_sp2_params_register,
3882 .params_unregister = mlxsw_sp2_params_unregister,
3883 .ptp_transmitted = mlxsw_sp_ptp_transmitted,
3884 .txhdr_len = MLXSW_TXHDR_LEN,
3885 .profile = &mlxsw_sp2_config_profile,
3886 };
3887
3888 static struct mlxsw_driver mlxsw_sp4_driver = {
3889 .kind = mlxsw_sp4_driver_name,
3890 .priv_size = sizeof(struct mlxsw_sp),
3891 .init = mlxsw_sp4_init,
3892 .fini = mlxsw_sp_fini,
3893 .port_split = mlxsw_sp_port_split,
3894 .port_unsplit = mlxsw_sp_port_unsplit,
3895 .ports_remove_selected = mlxsw_sp_ports_remove_selected,
3896 .sb_pool_get = mlxsw_sp_sb_pool_get,
3897 .sb_pool_set = mlxsw_sp_sb_pool_set,
3898 .sb_port_pool_get = mlxsw_sp_sb_port_pool_get,
3899 .sb_port_pool_set = mlxsw_sp_sb_port_pool_set,
3900 .sb_tc_pool_bind_get = mlxsw_sp_sb_tc_pool_bind_get,
3901 .sb_tc_pool_bind_set = mlxsw_sp_sb_tc_pool_bind_set,
3902 .sb_occ_snapshot = mlxsw_sp_sb_occ_snapshot,
3903 .sb_occ_max_clear = mlxsw_sp_sb_occ_max_clear,
3904 .sb_occ_port_pool_get = mlxsw_sp_sb_occ_port_pool_get,
3905 .sb_occ_tc_port_bind_get = mlxsw_sp_sb_occ_tc_port_bind_get,
3906 .trap_init = mlxsw_sp_trap_init,
3907 .trap_fini = mlxsw_sp_trap_fini,
3908 .trap_action_set = mlxsw_sp_trap_action_set,
3909 .trap_group_init = mlxsw_sp_trap_group_init,
3910 .trap_group_set = mlxsw_sp_trap_group_set,
3911 .trap_policer_init = mlxsw_sp_trap_policer_init,
3912 .trap_policer_fini = mlxsw_sp_trap_policer_fini,
3913 .trap_policer_set = mlxsw_sp_trap_policer_set,
3914 .trap_policer_counter_get = mlxsw_sp_trap_policer_counter_get,
3915 .txhdr_construct = mlxsw_sp_txhdr_construct,
3916 .resources_register = mlxsw_sp2_resources_register,
3917 .params_register = mlxsw_sp2_params_register,
3918 .params_unregister = mlxsw_sp2_params_unregister,
3919 .ptp_transmitted = mlxsw_sp_ptp_transmitted,
3920 .txhdr_len = MLXSW_TXHDR_LEN,
3921 .profile = &mlxsw_sp2_config_profile,
3922 };
3923
mlxsw_sp_port_dev_check(const struct net_device * dev)3924 bool mlxsw_sp_port_dev_check(const struct net_device *dev)
3925 {
3926 return dev->netdev_ops == &mlxsw_sp_port_netdev_ops;
3927 }
3928
mlxsw_sp_lower_dev_walk(struct net_device * lower_dev,struct netdev_nested_priv * priv)3929 static int mlxsw_sp_lower_dev_walk(struct net_device *lower_dev,
3930 struct netdev_nested_priv *priv)
3931 {
3932 int ret = 0;
3933
3934 if (mlxsw_sp_port_dev_check(lower_dev)) {
3935 priv->data = (void *)netdev_priv(lower_dev);
3936 ret = 1;
3937 }
3938
3939 return ret;
3940 }
3941
mlxsw_sp_port_dev_lower_find(struct net_device * dev)3942 struct mlxsw_sp_port *mlxsw_sp_port_dev_lower_find(struct net_device *dev)
3943 {
3944 struct netdev_nested_priv priv = {
3945 .data = NULL,
3946 };
3947
3948 if (mlxsw_sp_port_dev_check(dev))
3949 return netdev_priv(dev);
3950
3951 netdev_walk_all_lower_dev(dev, mlxsw_sp_lower_dev_walk, &priv);
3952
3953 return (struct mlxsw_sp_port *)priv.data;
3954 }
3955
mlxsw_sp_lower_get(struct net_device * dev)3956 struct mlxsw_sp *mlxsw_sp_lower_get(struct net_device *dev)
3957 {
3958 struct mlxsw_sp_port *mlxsw_sp_port;
3959
3960 mlxsw_sp_port = mlxsw_sp_port_dev_lower_find(dev);
3961 return mlxsw_sp_port ? mlxsw_sp_port->mlxsw_sp : NULL;
3962 }
3963
mlxsw_sp_port_dev_lower_find_rcu(struct net_device * dev)3964 struct mlxsw_sp_port *mlxsw_sp_port_dev_lower_find_rcu(struct net_device *dev)
3965 {
3966 struct netdev_nested_priv priv = {
3967 .data = NULL,
3968 };
3969
3970 if (mlxsw_sp_port_dev_check(dev))
3971 return netdev_priv(dev);
3972
3973 netdev_walk_all_lower_dev_rcu(dev, mlxsw_sp_lower_dev_walk,
3974 &priv);
3975
3976 return (struct mlxsw_sp_port *)priv.data;
3977 }
3978
mlxsw_sp_port_lower_dev_hold(struct net_device * dev)3979 struct mlxsw_sp_port *mlxsw_sp_port_lower_dev_hold(struct net_device *dev)
3980 {
3981 struct mlxsw_sp_port *mlxsw_sp_port;
3982
3983 rcu_read_lock();
3984 mlxsw_sp_port = mlxsw_sp_port_dev_lower_find_rcu(dev);
3985 if (mlxsw_sp_port)
3986 dev_hold(mlxsw_sp_port->dev);
3987 rcu_read_unlock();
3988 return mlxsw_sp_port;
3989 }
3990
mlxsw_sp_port_dev_put(struct mlxsw_sp_port * mlxsw_sp_port)3991 void mlxsw_sp_port_dev_put(struct mlxsw_sp_port *mlxsw_sp_port)
3992 {
3993 dev_put(mlxsw_sp_port->dev);
3994 }
3995
mlxsw_sp_parsing_depth_inc(struct mlxsw_sp * mlxsw_sp)3996 int mlxsw_sp_parsing_depth_inc(struct mlxsw_sp *mlxsw_sp)
3997 {
3998 char mprs_pl[MLXSW_REG_MPRS_LEN];
3999 int err = 0;
4000
4001 mutex_lock(&mlxsw_sp->parsing.lock);
4002
4003 if (refcount_inc_not_zero(&mlxsw_sp->parsing.parsing_depth_ref))
4004 goto out_unlock;
4005
4006 mlxsw_reg_mprs_pack(mprs_pl, MLXSW_SP_INCREASED_PARSING_DEPTH,
4007 mlxsw_sp->parsing.vxlan_udp_dport);
4008 err = mlxsw_reg_write(mlxsw_sp->core, MLXSW_REG(mprs), mprs_pl);
4009 if (err)
4010 goto out_unlock;
4011
4012 mlxsw_sp->parsing.parsing_depth = MLXSW_SP_INCREASED_PARSING_DEPTH;
4013 refcount_set(&mlxsw_sp->parsing.parsing_depth_ref, 1);
4014
4015 out_unlock:
4016 mutex_unlock(&mlxsw_sp->parsing.lock);
4017 return err;
4018 }
4019
mlxsw_sp_parsing_depth_dec(struct mlxsw_sp * mlxsw_sp)4020 void mlxsw_sp_parsing_depth_dec(struct mlxsw_sp *mlxsw_sp)
4021 {
4022 char mprs_pl[MLXSW_REG_MPRS_LEN];
4023
4024 mutex_lock(&mlxsw_sp->parsing.lock);
4025
4026 if (!refcount_dec_and_test(&mlxsw_sp->parsing.parsing_depth_ref))
4027 goto out_unlock;
4028
4029 mlxsw_reg_mprs_pack(mprs_pl, MLXSW_SP_DEFAULT_PARSING_DEPTH,
4030 mlxsw_sp->parsing.vxlan_udp_dport);
4031 mlxsw_reg_write(mlxsw_sp->core, MLXSW_REG(mprs), mprs_pl);
4032 mlxsw_sp->parsing.parsing_depth = MLXSW_SP_DEFAULT_PARSING_DEPTH;
4033
4034 out_unlock:
4035 mutex_unlock(&mlxsw_sp->parsing.lock);
4036 }
4037
mlxsw_sp_parsing_vxlan_udp_dport_set(struct mlxsw_sp * mlxsw_sp,__be16 udp_dport)4038 int mlxsw_sp_parsing_vxlan_udp_dport_set(struct mlxsw_sp *mlxsw_sp,
4039 __be16 udp_dport)
4040 {
4041 char mprs_pl[MLXSW_REG_MPRS_LEN];
4042 int err;
4043
4044 mutex_lock(&mlxsw_sp->parsing.lock);
4045
4046 mlxsw_reg_mprs_pack(mprs_pl, mlxsw_sp->parsing.parsing_depth,
4047 be16_to_cpu(udp_dport));
4048 err = mlxsw_reg_write(mlxsw_sp->core, MLXSW_REG(mprs), mprs_pl);
4049 if (err)
4050 goto out_unlock;
4051
4052 mlxsw_sp->parsing.vxlan_udp_dport = be16_to_cpu(udp_dport);
4053
4054 out_unlock:
4055 mutex_unlock(&mlxsw_sp->parsing.lock);
4056 return err;
4057 }
4058
4059 static void
mlxsw_sp_port_lag_uppers_cleanup(struct mlxsw_sp_port * mlxsw_sp_port,struct net_device * lag_dev)4060 mlxsw_sp_port_lag_uppers_cleanup(struct mlxsw_sp_port *mlxsw_sp_port,
4061 struct net_device *lag_dev)
4062 {
4063 struct net_device *br_dev = netdev_master_upper_dev_get(lag_dev);
4064 struct net_device *upper_dev;
4065 struct list_head *iter;
4066
4067 if (netif_is_bridge_port(lag_dev))
4068 mlxsw_sp_port_bridge_leave(mlxsw_sp_port, lag_dev, br_dev);
4069
4070 netdev_for_each_upper_dev_rcu(lag_dev, upper_dev, iter) {
4071 if (!netif_is_bridge_port(upper_dev))
4072 continue;
4073 br_dev = netdev_master_upper_dev_get(upper_dev);
4074 mlxsw_sp_port_bridge_leave(mlxsw_sp_port, upper_dev, br_dev);
4075 }
4076 }
4077
mlxsw_sp_lag_create(struct mlxsw_sp * mlxsw_sp,u16 lag_id)4078 static int mlxsw_sp_lag_create(struct mlxsw_sp *mlxsw_sp, u16 lag_id)
4079 {
4080 char sldr_pl[MLXSW_REG_SLDR_LEN];
4081
4082 mlxsw_reg_sldr_lag_create_pack(sldr_pl, lag_id);
4083 return mlxsw_reg_write(mlxsw_sp->core, MLXSW_REG(sldr), sldr_pl);
4084 }
4085
mlxsw_sp_lag_destroy(struct mlxsw_sp * mlxsw_sp,u16 lag_id)4086 static int mlxsw_sp_lag_destroy(struct mlxsw_sp *mlxsw_sp, u16 lag_id)
4087 {
4088 char sldr_pl[MLXSW_REG_SLDR_LEN];
4089
4090 mlxsw_reg_sldr_lag_destroy_pack(sldr_pl, lag_id);
4091 return mlxsw_reg_write(mlxsw_sp->core, MLXSW_REG(sldr), sldr_pl);
4092 }
4093
mlxsw_sp_lag_col_port_add(struct mlxsw_sp_port * mlxsw_sp_port,u16 lag_id,u8 port_index)4094 static int mlxsw_sp_lag_col_port_add(struct mlxsw_sp_port *mlxsw_sp_port,
4095 u16 lag_id, u8 port_index)
4096 {
4097 struct mlxsw_sp *mlxsw_sp = mlxsw_sp_port->mlxsw_sp;
4098 char slcor_pl[MLXSW_REG_SLCOR_LEN];
4099
4100 mlxsw_reg_slcor_port_add_pack(slcor_pl, mlxsw_sp_port->local_port,
4101 lag_id, port_index);
4102 return mlxsw_reg_write(mlxsw_sp->core, MLXSW_REG(slcor), slcor_pl);
4103 }
4104
mlxsw_sp_lag_col_port_remove(struct mlxsw_sp_port * mlxsw_sp_port,u16 lag_id)4105 static int mlxsw_sp_lag_col_port_remove(struct mlxsw_sp_port *mlxsw_sp_port,
4106 u16 lag_id)
4107 {
4108 struct mlxsw_sp *mlxsw_sp = mlxsw_sp_port->mlxsw_sp;
4109 char slcor_pl[MLXSW_REG_SLCOR_LEN];
4110
4111 mlxsw_reg_slcor_port_remove_pack(slcor_pl, mlxsw_sp_port->local_port,
4112 lag_id);
4113 return mlxsw_reg_write(mlxsw_sp->core, MLXSW_REG(slcor), slcor_pl);
4114 }
4115
mlxsw_sp_lag_col_port_enable(struct mlxsw_sp_port * mlxsw_sp_port,u16 lag_id)4116 static int mlxsw_sp_lag_col_port_enable(struct mlxsw_sp_port *mlxsw_sp_port,
4117 u16 lag_id)
4118 {
4119 struct mlxsw_sp *mlxsw_sp = mlxsw_sp_port->mlxsw_sp;
4120 char slcor_pl[MLXSW_REG_SLCOR_LEN];
4121
4122 mlxsw_reg_slcor_col_enable_pack(slcor_pl, mlxsw_sp_port->local_port,
4123 lag_id);
4124 return mlxsw_reg_write(mlxsw_sp->core, MLXSW_REG(slcor), slcor_pl);
4125 }
4126
mlxsw_sp_lag_col_port_disable(struct mlxsw_sp_port * mlxsw_sp_port,u16 lag_id)4127 static int mlxsw_sp_lag_col_port_disable(struct mlxsw_sp_port *mlxsw_sp_port,
4128 u16 lag_id)
4129 {
4130 struct mlxsw_sp *mlxsw_sp = mlxsw_sp_port->mlxsw_sp;
4131 char slcor_pl[MLXSW_REG_SLCOR_LEN];
4132
4133 mlxsw_reg_slcor_col_disable_pack(slcor_pl, mlxsw_sp_port->local_port,
4134 lag_id);
4135 return mlxsw_reg_write(mlxsw_sp->core, MLXSW_REG(slcor), slcor_pl);
4136 }
4137
mlxsw_sp_lag_index_get(struct mlxsw_sp * mlxsw_sp,struct net_device * lag_dev,u16 * p_lag_id)4138 static int mlxsw_sp_lag_index_get(struct mlxsw_sp *mlxsw_sp,
4139 struct net_device *lag_dev,
4140 u16 *p_lag_id)
4141 {
4142 struct mlxsw_sp_upper *lag;
4143 int free_lag_id = -1;
4144 u64 max_lag;
4145 int i;
4146
4147 max_lag = MLXSW_CORE_RES_GET(mlxsw_sp->core, MAX_LAG);
4148 for (i = 0; i < max_lag; i++) {
4149 lag = mlxsw_sp_lag_get(mlxsw_sp, i);
4150 if (lag->ref_count) {
4151 if (lag->dev == lag_dev) {
4152 *p_lag_id = i;
4153 return 0;
4154 }
4155 } else if (free_lag_id < 0) {
4156 free_lag_id = i;
4157 }
4158 }
4159 if (free_lag_id < 0)
4160 return -EBUSY;
4161 *p_lag_id = free_lag_id;
4162 return 0;
4163 }
4164
4165 static bool
mlxsw_sp_master_lag_check(struct mlxsw_sp * mlxsw_sp,struct net_device * lag_dev,struct netdev_lag_upper_info * lag_upper_info,struct netlink_ext_ack * extack)4166 mlxsw_sp_master_lag_check(struct mlxsw_sp *mlxsw_sp,
4167 struct net_device *lag_dev,
4168 struct netdev_lag_upper_info *lag_upper_info,
4169 struct netlink_ext_ack *extack)
4170 {
4171 u16 lag_id;
4172
4173 if (mlxsw_sp_lag_index_get(mlxsw_sp, lag_dev, &lag_id) != 0) {
4174 NL_SET_ERR_MSG_MOD(extack, "Exceeded number of supported LAG devices");
4175 return false;
4176 }
4177 if (lag_upper_info->tx_type != NETDEV_LAG_TX_TYPE_HASH) {
4178 NL_SET_ERR_MSG_MOD(extack, "LAG device using unsupported Tx type");
4179 return false;
4180 }
4181 return true;
4182 }
4183
mlxsw_sp_port_lag_index_get(struct mlxsw_sp * mlxsw_sp,u16 lag_id,u8 * p_port_index)4184 static int mlxsw_sp_port_lag_index_get(struct mlxsw_sp *mlxsw_sp,
4185 u16 lag_id, u8 *p_port_index)
4186 {
4187 u64 max_lag_members;
4188 int i;
4189
4190 max_lag_members = MLXSW_CORE_RES_GET(mlxsw_sp->core,
4191 MAX_LAG_MEMBERS);
4192 for (i = 0; i < max_lag_members; i++) {
4193 if (!mlxsw_sp_port_lagged_get(mlxsw_sp, lag_id, i)) {
4194 *p_port_index = i;
4195 return 0;
4196 }
4197 }
4198 return -EBUSY;
4199 }
4200
mlxsw_sp_port_lag_join(struct mlxsw_sp_port * mlxsw_sp_port,struct net_device * lag_dev,struct netlink_ext_ack * extack)4201 static int mlxsw_sp_port_lag_join(struct mlxsw_sp_port *mlxsw_sp_port,
4202 struct net_device *lag_dev,
4203 struct netlink_ext_ack *extack)
4204 {
4205 struct mlxsw_sp *mlxsw_sp = mlxsw_sp_port->mlxsw_sp;
4206 struct mlxsw_sp_upper *lag;
4207 u16 lag_id;
4208 u8 port_index;
4209 int err;
4210
4211 err = mlxsw_sp_lag_index_get(mlxsw_sp, lag_dev, &lag_id);
4212 if (err)
4213 return err;
4214 lag = mlxsw_sp_lag_get(mlxsw_sp, lag_id);
4215 if (!lag->ref_count) {
4216 err = mlxsw_sp_lag_create(mlxsw_sp, lag_id);
4217 if (err)
4218 return err;
4219 lag->dev = lag_dev;
4220 }
4221
4222 err = mlxsw_sp_port_lag_index_get(mlxsw_sp, lag_id, &port_index);
4223 if (err)
4224 return err;
4225 err = mlxsw_sp_lag_col_port_add(mlxsw_sp_port, lag_id, port_index);
4226 if (err)
4227 goto err_col_port_add;
4228
4229 mlxsw_core_lag_mapping_set(mlxsw_sp->core, lag_id, port_index,
4230 mlxsw_sp_port->local_port);
4231 mlxsw_sp_port->lag_id = lag_id;
4232 mlxsw_sp_port->lagged = 1;
4233 lag->ref_count++;
4234
4235 /* Port is no longer usable as a router interface */
4236 if (mlxsw_sp_port->default_vlan->fid)
4237 mlxsw_sp_port_vlan_router_leave(mlxsw_sp_port->default_vlan);
4238
4239 /* Join a router interface configured on the LAG, if exists */
4240 err = mlxsw_sp_port_vlan_router_join(mlxsw_sp_port->default_vlan,
4241 lag_dev, extack);
4242 if (err)
4243 goto err_router_join;
4244
4245 return 0;
4246
4247 err_router_join:
4248 lag->ref_count--;
4249 mlxsw_sp_port->lagged = 0;
4250 mlxsw_core_lag_mapping_clear(mlxsw_sp->core, lag_id,
4251 mlxsw_sp_port->local_port);
4252 mlxsw_sp_lag_col_port_remove(mlxsw_sp_port, lag_id);
4253 err_col_port_add:
4254 if (!lag->ref_count)
4255 mlxsw_sp_lag_destroy(mlxsw_sp, lag_id);
4256 return err;
4257 }
4258
mlxsw_sp_port_lag_leave(struct mlxsw_sp_port * mlxsw_sp_port,struct net_device * lag_dev)4259 static void mlxsw_sp_port_lag_leave(struct mlxsw_sp_port *mlxsw_sp_port,
4260 struct net_device *lag_dev)
4261 {
4262 struct mlxsw_sp *mlxsw_sp = mlxsw_sp_port->mlxsw_sp;
4263 u16 lag_id = mlxsw_sp_port->lag_id;
4264 struct mlxsw_sp_upper *lag;
4265
4266 if (!mlxsw_sp_port->lagged)
4267 return;
4268 lag = mlxsw_sp_lag_get(mlxsw_sp, lag_id);
4269 WARN_ON(lag->ref_count == 0);
4270
4271 mlxsw_sp_lag_col_port_remove(mlxsw_sp_port, lag_id);
4272
4273 /* Any VLANs configured on the port are no longer valid */
4274 mlxsw_sp_port_vlan_flush(mlxsw_sp_port, false);
4275 mlxsw_sp_port_vlan_cleanup(mlxsw_sp_port->default_vlan);
4276 /* Make the LAG and its directly linked uppers leave bridges they
4277 * are memeber in
4278 */
4279 mlxsw_sp_port_lag_uppers_cleanup(mlxsw_sp_port, lag_dev);
4280
4281 if (lag->ref_count == 1)
4282 mlxsw_sp_lag_destroy(mlxsw_sp, lag_id);
4283
4284 mlxsw_core_lag_mapping_clear(mlxsw_sp->core, lag_id,
4285 mlxsw_sp_port->local_port);
4286 mlxsw_sp_port->lagged = 0;
4287 lag->ref_count--;
4288
4289 /* Make sure untagged frames are allowed to ingress */
4290 mlxsw_sp_port_pvid_set(mlxsw_sp_port, MLXSW_SP_DEFAULT_VID,
4291 ETH_P_8021Q);
4292 }
4293
mlxsw_sp_lag_dist_port_add(struct mlxsw_sp_port * mlxsw_sp_port,u16 lag_id)4294 static int mlxsw_sp_lag_dist_port_add(struct mlxsw_sp_port *mlxsw_sp_port,
4295 u16 lag_id)
4296 {
4297 struct mlxsw_sp *mlxsw_sp = mlxsw_sp_port->mlxsw_sp;
4298 char sldr_pl[MLXSW_REG_SLDR_LEN];
4299
4300 mlxsw_reg_sldr_lag_add_port_pack(sldr_pl, lag_id,
4301 mlxsw_sp_port->local_port);
4302 return mlxsw_reg_write(mlxsw_sp->core, MLXSW_REG(sldr), sldr_pl);
4303 }
4304
mlxsw_sp_lag_dist_port_remove(struct mlxsw_sp_port * mlxsw_sp_port,u16 lag_id)4305 static int mlxsw_sp_lag_dist_port_remove(struct mlxsw_sp_port *mlxsw_sp_port,
4306 u16 lag_id)
4307 {
4308 struct mlxsw_sp *mlxsw_sp = mlxsw_sp_port->mlxsw_sp;
4309 char sldr_pl[MLXSW_REG_SLDR_LEN];
4310
4311 mlxsw_reg_sldr_lag_remove_port_pack(sldr_pl, lag_id,
4312 mlxsw_sp_port->local_port);
4313 return mlxsw_reg_write(mlxsw_sp->core, MLXSW_REG(sldr), sldr_pl);
4314 }
4315
4316 static int
mlxsw_sp_port_lag_col_dist_enable(struct mlxsw_sp_port * mlxsw_sp_port)4317 mlxsw_sp_port_lag_col_dist_enable(struct mlxsw_sp_port *mlxsw_sp_port)
4318 {
4319 int err;
4320
4321 err = mlxsw_sp_lag_col_port_enable(mlxsw_sp_port,
4322 mlxsw_sp_port->lag_id);
4323 if (err)
4324 return err;
4325
4326 err = mlxsw_sp_lag_dist_port_add(mlxsw_sp_port, mlxsw_sp_port->lag_id);
4327 if (err)
4328 goto err_dist_port_add;
4329
4330 return 0;
4331
4332 err_dist_port_add:
4333 mlxsw_sp_lag_col_port_disable(mlxsw_sp_port, mlxsw_sp_port->lag_id);
4334 return err;
4335 }
4336
4337 static int
mlxsw_sp_port_lag_col_dist_disable(struct mlxsw_sp_port * mlxsw_sp_port)4338 mlxsw_sp_port_lag_col_dist_disable(struct mlxsw_sp_port *mlxsw_sp_port)
4339 {
4340 int err;
4341
4342 err = mlxsw_sp_lag_dist_port_remove(mlxsw_sp_port,
4343 mlxsw_sp_port->lag_id);
4344 if (err)
4345 return err;
4346
4347 err = mlxsw_sp_lag_col_port_disable(mlxsw_sp_port,
4348 mlxsw_sp_port->lag_id);
4349 if (err)
4350 goto err_col_port_disable;
4351
4352 return 0;
4353
4354 err_col_port_disable:
4355 mlxsw_sp_lag_dist_port_add(mlxsw_sp_port, mlxsw_sp_port->lag_id);
4356 return err;
4357 }
4358
mlxsw_sp_port_lag_changed(struct mlxsw_sp_port * mlxsw_sp_port,struct netdev_lag_lower_state_info * info)4359 static int mlxsw_sp_port_lag_changed(struct mlxsw_sp_port *mlxsw_sp_port,
4360 struct netdev_lag_lower_state_info *info)
4361 {
4362 if (info->tx_enabled)
4363 return mlxsw_sp_port_lag_col_dist_enable(mlxsw_sp_port);
4364 else
4365 return mlxsw_sp_port_lag_col_dist_disable(mlxsw_sp_port);
4366 }
4367
mlxsw_sp_port_stp_set(struct mlxsw_sp_port * mlxsw_sp_port,bool enable)4368 static int mlxsw_sp_port_stp_set(struct mlxsw_sp_port *mlxsw_sp_port,
4369 bool enable)
4370 {
4371 struct mlxsw_sp *mlxsw_sp = mlxsw_sp_port->mlxsw_sp;
4372 enum mlxsw_reg_spms_state spms_state;
4373 char *spms_pl;
4374 u16 vid;
4375 int err;
4376
4377 spms_state = enable ? MLXSW_REG_SPMS_STATE_FORWARDING :
4378 MLXSW_REG_SPMS_STATE_DISCARDING;
4379
4380 spms_pl = kmalloc(MLXSW_REG_SPMS_LEN, GFP_KERNEL);
4381 if (!spms_pl)
4382 return -ENOMEM;
4383 mlxsw_reg_spms_pack(spms_pl, mlxsw_sp_port->local_port);
4384
4385 for (vid = 0; vid < VLAN_N_VID; vid++)
4386 mlxsw_reg_spms_vid_pack(spms_pl, vid, spms_state);
4387
4388 err = mlxsw_reg_write(mlxsw_sp->core, MLXSW_REG(spms), spms_pl);
4389 kfree(spms_pl);
4390 return err;
4391 }
4392
mlxsw_sp_port_ovs_join(struct mlxsw_sp_port * mlxsw_sp_port)4393 static int mlxsw_sp_port_ovs_join(struct mlxsw_sp_port *mlxsw_sp_port)
4394 {
4395 u16 vid = 1;
4396 int err;
4397
4398 err = mlxsw_sp_port_vp_mode_set(mlxsw_sp_port, true);
4399 if (err)
4400 return err;
4401 err = mlxsw_sp_port_stp_set(mlxsw_sp_port, true);
4402 if (err)
4403 goto err_port_stp_set;
4404 err = mlxsw_sp_port_vlan_set(mlxsw_sp_port, 1, VLAN_N_VID - 2,
4405 true, false);
4406 if (err)
4407 goto err_port_vlan_set;
4408
4409 for (; vid <= VLAN_N_VID - 1; vid++) {
4410 err = mlxsw_sp_port_vid_learning_set(mlxsw_sp_port,
4411 vid, false);
4412 if (err)
4413 goto err_vid_learning_set;
4414 }
4415
4416 return 0;
4417
4418 err_vid_learning_set:
4419 for (vid--; vid >= 1; vid--)
4420 mlxsw_sp_port_vid_learning_set(mlxsw_sp_port, vid, true);
4421 err_port_vlan_set:
4422 mlxsw_sp_port_stp_set(mlxsw_sp_port, false);
4423 err_port_stp_set:
4424 mlxsw_sp_port_vp_mode_set(mlxsw_sp_port, false);
4425 return err;
4426 }
4427
mlxsw_sp_port_ovs_leave(struct mlxsw_sp_port * mlxsw_sp_port)4428 static void mlxsw_sp_port_ovs_leave(struct mlxsw_sp_port *mlxsw_sp_port)
4429 {
4430 u16 vid;
4431
4432 for (vid = VLAN_N_VID - 1; vid >= 1; vid--)
4433 mlxsw_sp_port_vid_learning_set(mlxsw_sp_port,
4434 vid, true);
4435
4436 mlxsw_sp_port_vlan_set(mlxsw_sp_port, 1, VLAN_N_VID - 2,
4437 false, false);
4438 mlxsw_sp_port_stp_set(mlxsw_sp_port, false);
4439 mlxsw_sp_port_vp_mode_set(mlxsw_sp_port, false);
4440 }
4441
mlxsw_sp_bridge_has_multiple_vxlans(struct net_device * br_dev)4442 static bool mlxsw_sp_bridge_has_multiple_vxlans(struct net_device *br_dev)
4443 {
4444 unsigned int num_vxlans = 0;
4445 struct net_device *dev;
4446 struct list_head *iter;
4447
4448 netdev_for_each_lower_dev(br_dev, dev, iter) {
4449 if (netif_is_vxlan(dev))
4450 num_vxlans++;
4451 }
4452
4453 return num_vxlans > 1;
4454 }
4455
mlxsw_sp_bridge_vxlan_vlan_is_valid(struct net_device * br_dev)4456 static bool mlxsw_sp_bridge_vxlan_vlan_is_valid(struct net_device *br_dev)
4457 {
4458 DECLARE_BITMAP(vlans, VLAN_N_VID) = {0};
4459 struct net_device *dev;
4460 struct list_head *iter;
4461
4462 netdev_for_each_lower_dev(br_dev, dev, iter) {
4463 u16 pvid;
4464 int err;
4465
4466 if (!netif_is_vxlan(dev))
4467 continue;
4468
4469 err = mlxsw_sp_vxlan_mapped_vid(dev, &pvid);
4470 if (err || !pvid)
4471 continue;
4472
4473 if (test_and_set_bit(pvid, vlans))
4474 return false;
4475 }
4476
4477 return true;
4478 }
4479
mlxsw_sp_bridge_vxlan_is_valid(struct net_device * br_dev,struct netlink_ext_ack * extack)4480 static bool mlxsw_sp_bridge_vxlan_is_valid(struct net_device *br_dev,
4481 struct netlink_ext_ack *extack)
4482 {
4483 if (br_multicast_enabled(br_dev)) {
4484 NL_SET_ERR_MSG_MOD(extack, "Multicast can not be enabled on a bridge with a VxLAN device");
4485 return false;
4486 }
4487
4488 if (!br_vlan_enabled(br_dev) &&
4489 mlxsw_sp_bridge_has_multiple_vxlans(br_dev)) {
4490 NL_SET_ERR_MSG_MOD(extack, "Multiple VxLAN devices are not supported in a VLAN-unaware bridge");
4491 return false;
4492 }
4493
4494 if (br_vlan_enabled(br_dev) &&
4495 !mlxsw_sp_bridge_vxlan_vlan_is_valid(br_dev)) {
4496 NL_SET_ERR_MSG_MOD(extack, "Multiple VxLAN devices cannot have the same VLAN as PVID and egress untagged");
4497 return false;
4498 }
4499
4500 return true;
4501 }
4502
mlxsw_sp_netdevice_port_upper_event(struct net_device * lower_dev,struct net_device * dev,unsigned long event,void * ptr)4503 static int mlxsw_sp_netdevice_port_upper_event(struct net_device *lower_dev,
4504 struct net_device *dev,
4505 unsigned long event, void *ptr)
4506 {
4507 struct netdev_notifier_changeupper_info *info;
4508 struct mlxsw_sp_port *mlxsw_sp_port;
4509 struct netlink_ext_ack *extack;
4510 struct net_device *upper_dev;
4511 struct mlxsw_sp *mlxsw_sp;
4512 int err = 0;
4513 u16 proto;
4514
4515 mlxsw_sp_port = netdev_priv(dev);
4516 mlxsw_sp = mlxsw_sp_port->mlxsw_sp;
4517 info = ptr;
4518 extack = netdev_notifier_info_to_extack(&info->info);
4519
4520 switch (event) {
4521 case NETDEV_PRECHANGEUPPER:
4522 upper_dev = info->upper_dev;
4523 if (!is_vlan_dev(upper_dev) &&
4524 !netif_is_lag_master(upper_dev) &&
4525 !netif_is_bridge_master(upper_dev) &&
4526 !netif_is_ovs_master(upper_dev) &&
4527 !netif_is_macvlan(upper_dev) &&
4528 !netif_is_l3_master(upper_dev)) {
4529 NL_SET_ERR_MSG_MOD(extack, "Unknown upper device type");
4530 return -EINVAL;
4531 }
4532 if (!info->linking)
4533 break;
4534 if (netif_is_bridge_master(upper_dev) &&
4535 !mlxsw_sp_bridge_device_is_offloaded(mlxsw_sp, upper_dev) &&
4536 mlxsw_sp_bridge_has_vxlan(upper_dev) &&
4537 !mlxsw_sp_bridge_vxlan_is_valid(upper_dev, extack))
4538 return -EOPNOTSUPP;
4539 if (netdev_has_any_upper_dev(upper_dev) &&
4540 (!netif_is_bridge_master(upper_dev) ||
4541 !mlxsw_sp_bridge_device_is_offloaded(mlxsw_sp,
4542 upper_dev))) {
4543 NL_SET_ERR_MSG_MOD(extack, "Enslaving a port to a device that already has an upper device is not supported");
4544 return -EINVAL;
4545 }
4546 if (netif_is_lag_master(upper_dev) &&
4547 !mlxsw_sp_master_lag_check(mlxsw_sp, upper_dev,
4548 info->upper_info, extack))
4549 return -EINVAL;
4550 if (netif_is_lag_master(upper_dev) && vlan_uses_dev(dev)) {
4551 NL_SET_ERR_MSG_MOD(extack, "Master device is a LAG master and this device has a VLAN");
4552 return -EINVAL;
4553 }
4554 if (netif_is_lag_port(dev) && is_vlan_dev(upper_dev) &&
4555 !netif_is_lag_master(vlan_dev_real_dev(upper_dev))) {
4556 NL_SET_ERR_MSG_MOD(extack, "Can not put a VLAN on a LAG port");
4557 return -EINVAL;
4558 }
4559 if (netif_is_macvlan(upper_dev) &&
4560 !mlxsw_sp_rif_exists(mlxsw_sp, lower_dev)) {
4561 NL_SET_ERR_MSG_MOD(extack, "macvlan is only supported on top of router interfaces");
4562 return -EOPNOTSUPP;
4563 }
4564 if (netif_is_ovs_master(upper_dev) && vlan_uses_dev(dev)) {
4565 NL_SET_ERR_MSG_MOD(extack, "Master device is an OVS master and this device has a VLAN");
4566 return -EINVAL;
4567 }
4568 if (netif_is_ovs_port(dev) && is_vlan_dev(upper_dev)) {
4569 NL_SET_ERR_MSG_MOD(extack, "Can not put a VLAN on an OVS port");
4570 return -EINVAL;
4571 }
4572 if (netif_is_bridge_master(upper_dev)) {
4573 br_vlan_get_proto(upper_dev, &proto);
4574 if (br_vlan_enabled(upper_dev) &&
4575 proto != ETH_P_8021Q && proto != ETH_P_8021AD) {
4576 NL_SET_ERR_MSG_MOD(extack, "Enslaving a port to a bridge with unknown VLAN protocol is not supported");
4577 return -EOPNOTSUPP;
4578 }
4579 if (vlan_uses_dev(lower_dev) &&
4580 br_vlan_enabled(upper_dev) &&
4581 proto == ETH_P_8021AD) {
4582 NL_SET_ERR_MSG_MOD(extack, "Enslaving a port that already has a VLAN upper to an 802.1ad bridge is not supported");
4583 return -EOPNOTSUPP;
4584 }
4585 }
4586 if (netif_is_bridge_port(lower_dev) && is_vlan_dev(upper_dev)) {
4587 struct net_device *br_dev = netdev_master_upper_dev_get(lower_dev);
4588
4589 if (br_vlan_enabled(br_dev)) {
4590 br_vlan_get_proto(br_dev, &proto);
4591 if (proto == ETH_P_8021AD) {
4592 NL_SET_ERR_MSG_MOD(extack, "VLAN uppers are not supported on a port enslaved to an 802.1ad bridge");
4593 return -EOPNOTSUPP;
4594 }
4595 }
4596 }
4597 if (is_vlan_dev(upper_dev) &&
4598 ntohs(vlan_dev_vlan_proto(upper_dev)) != ETH_P_8021Q) {
4599 NL_SET_ERR_MSG_MOD(extack, "VLAN uppers are only supported with 802.1q VLAN protocol");
4600 return -EOPNOTSUPP;
4601 }
4602 break;
4603 case NETDEV_CHANGEUPPER:
4604 upper_dev = info->upper_dev;
4605 if (netif_is_bridge_master(upper_dev)) {
4606 if (info->linking)
4607 err = mlxsw_sp_port_bridge_join(mlxsw_sp_port,
4608 lower_dev,
4609 upper_dev,
4610 extack);
4611 else
4612 mlxsw_sp_port_bridge_leave(mlxsw_sp_port,
4613 lower_dev,
4614 upper_dev);
4615 } else if (netif_is_lag_master(upper_dev)) {
4616 if (info->linking) {
4617 err = mlxsw_sp_port_lag_join(mlxsw_sp_port,
4618 upper_dev, extack);
4619 } else {
4620 mlxsw_sp_port_lag_col_dist_disable(mlxsw_sp_port);
4621 mlxsw_sp_port_lag_leave(mlxsw_sp_port,
4622 upper_dev);
4623 }
4624 } else if (netif_is_ovs_master(upper_dev)) {
4625 if (info->linking)
4626 err = mlxsw_sp_port_ovs_join(mlxsw_sp_port);
4627 else
4628 mlxsw_sp_port_ovs_leave(mlxsw_sp_port);
4629 } else if (netif_is_macvlan(upper_dev)) {
4630 if (!info->linking)
4631 mlxsw_sp_rif_macvlan_del(mlxsw_sp, upper_dev);
4632 } else if (is_vlan_dev(upper_dev)) {
4633 struct net_device *br_dev;
4634
4635 if (!netif_is_bridge_port(upper_dev))
4636 break;
4637 if (info->linking)
4638 break;
4639 br_dev = netdev_master_upper_dev_get(upper_dev);
4640 mlxsw_sp_port_bridge_leave(mlxsw_sp_port, upper_dev,
4641 br_dev);
4642 }
4643 break;
4644 }
4645
4646 return err;
4647 }
4648
mlxsw_sp_netdevice_port_lower_event(struct net_device * dev,unsigned long event,void * ptr)4649 static int mlxsw_sp_netdevice_port_lower_event(struct net_device *dev,
4650 unsigned long event, void *ptr)
4651 {
4652 struct netdev_notifier_changelowerstate_info *info;
4653 struct mlxsw_sp_port *mlxsw_sp_port;
4654 int err;
4655
4656 mlxsw_sp_port = netdev_priv(dev);
4657 info = ptr;
4658
4659 switch (event) {
4660 case NETDEV_CHANGELOWERSTATE:
4661 if (netif_is_lag_port(dev) && mlxsw_sp_port->lagged) {
4662 err = mlxsw_sp_port_lag_changed(mlxsw_sp_port,
4663 info->lower_state_info);
4664 if (err)
4665 netdev_err(dev, "Failed to reflect link aggregation lower state change\n");
4666 }
4667 break;
4668 }
4669
4670 return 0;
4671 }
4672
mlxsw_sp_netdevice_port_event(struct net_device * lower_dev,struct net_device * port_dev,unsigned long event,void * ptr)4673 static int mlxsw_sp_netdevice_port_event(struct net_device *lower_dev,
4674 struct net_device *port_dev,
4675 unsigned long event, void *ptr)
4676 {
4677 switch (event) {
4678 case NETDEV_PRECHANGEUPPER:
4679 case NETDEV_CHANGEUPPER:
4680 return mlxsw_sp_netdevice_port_upper_event(lower_dev, port_dev,
4681 event, ptr);
4682 case NETDEV_CHANGELOWERSTATE:
4683 return mlxsw_sp_netdevice_port_lower_event(port_dev, event,
4684 ptr);
4685 }
4686
4687 return 0;
4688 }
4689
mlxsw_sp_netdevice_lag_event(struct net_device * lag_dev,unsigned long event,void * ptr)4690 static int mlxsw_sp_netdevice_lag_event(struct net_device *lag_dev,
4691 unsigned long event, void *ptr)
4692 {
4693 struct net_device *dev;
4694 struct list_head *iter;
4695 int ret;
4696
4697 netdev_for_each_lower_dev(lag_dev, dev, iter) {
4698 if (mlxsw_sp_port_dev_check(dev)) {
4699 ret = mlxsw_sp_netdevice_port_event(lag_dev, dev, event,
4700 ptr);
4701 if (ret)
4702 return ret;
4703 }
4704 }
4705
4706 return 0;
4707 }
4708
mlxsw_sp_netdevice_port_vlan_event(struct net_device * vlan_dev,struct net_device * dev,unsigned long event,void * ptr,u16 vid)4709 static int mlxsw_sp_netdevice_port_vlan_event(struct net_device *vlan_dev,
4710 struct net_device *dev,
4711 unsigned long event, void *ptr,
4712 u16 vid)
4713 {
4714 struct mlxsw_sp_port *mlxsw_sp_port = netdev_priv(dev);
4715 struct mlxsw_sp *mlxsw_sp = mlxsw_sp_port->mlxsw_sp;
4716 struct netdev_notifier_changeupper_info *info = ptr;
4717 struct netlink_ext_ack *extack;
4718 struct net_device *upper_dev;
4719 int err = 0;
4720
4721 extack = netdev_notifier_info_to_extack(&info->info);
4722
4723 switch (event) {
4724 case NETDEV_PRECHANGEUPPER:
4725 upper_dev = info->upper_dev;
4726 if (!netif_is_bridge_master(upper_dev) &&
4727 !netif_is_macvlan(upper_dev) &&
4728 !netif_is_l3_master(upper_dev)) {
4729 NL_SET_ERR_MSG_MOD(extack, "Unknown upper device type");
4730 return -EINVAL;
4731 }
4732 if (!info->linking)
4733 break;
4734 if (netif_is_bridge_master(upper_dev) &&
4735 !mlxsw_sp_bridge_device_is_offloaded(mlxsw_sp, upper_dev) &&
4736 mlxsw_sp_bridge_has_vxlan(upper_dev) &&
4737 !mlxsw_sp_bridge_vxlan_is_valid(upper_dev, extack))
4738 return -EOPNOTSUPP;
4739 if (netdev_has_any_upper_dev(upper_dev) &&
4740 (!netif_is_bridge_master(upper_dev) ||
4741 !mlxsw_sp_bridge_device_is_offloaded(mlxsw_sp,
4742 upper_dev))) {
4743 NL_SET_ERR_MSG_MOD(extack, "Enslaving a port to a device that already has an upper device is not supported");
4744 return -EINVAL;
4745 }
4746 if (netif_is_macvlan(upper_dev) &&
4747 !mlxsw_sp_rif_exists(mlxsw_sp, vlan_dev)) {
4748 NL_SET_ERR_MSG_MOD(extack, "macvlan is only supported on top of router interfaces");
4749 return -EOPNOTSUPP;
4750 }
4751 break;
4752 case NETDEV_CHANGEUPPER:
4753 upper_dev = info->upper_dev;
4754 if (netif_is_bridge_master(upper_dev)) {
4755 if (info->linking)
4756 err = mlxsw_sp_port_bridge_join(mlxsw_sp_port,
4757 vlan_dev,
4758 upper_dev,
4759 extack);
4760 else
4761 mlxsw_sp_port_bridge_leave(mlxsw_sp_port,
4762 vlan_dev,
4763 upper_dev);
4764 } else if (netif_is_macvlan(upper_dev)) {
4765 if (!info->linking)
4766 mlxsw_sp_rif_macvlan_del(mlxsw_sp, upper_dev);
4767 }
4768 break;
4769 }
4770
4771 return err;
4772 }
4773
mlxsw_sp_netdevice_lag_port_vlan_event(struct net_device * vlan_dev,struct net_device * lag_dev,unsigned long event,void * ptr,u16 vid)4774 static int mlxsw_sp_netdevice_lag_port_vlan_event(struct net_device *vlan_dev,
4775 struct net_device *lag_dev,
4776 unsigned long event,
4777 void *ptr, u16 vid)
4778 {
4779 struct net_device *dev;
4780 struct list_head *iter;
4781 int ret;
4782
4783 netdev_for_each_lower_dev(lag_dev, dev, iter) {
4784 if (mlxsw_sp_port_dev_check(dev)) {
4785 ret = mlxsw_sp_netdevice_port_vlan_event(vlan_dev, dev,
4786 event, ptr,
4787 vid);
4788 if (ret)
4789 return ret;
4790 }
4791 }
4792
4793 return 0;
4794 }
4795
mlxsw_sp_netdevice_bridge_vlan_event(struct net_device * vlan_dev,struct net_device * br_dev,unsigned long event,void * ptr,u16 vid)4796 static int mlxsw_sp_netdevice_bridge_vlan_event(struct net_device *vlan_dev,
4797 struct net_device *br_dev,
4798 unsigned long event, void *ptr,
4799 u16 vid)
4800 {
4801 struct mlxsw_sp *mlxsw_sp = mlxsw_sp_lower_get(vlan_dev);
4802 struct netdev_notifier_changeupper_info *info = ptr;
4803 struct netlink_ext_ack *extack;
4804 struct net_device *upper_dev;
4805
4806 if (!mlxsw_sp)
4807 return 0;
4808
4809 extack = netdev_notifier_info_to_extack(&info->info);
4810
4811 switch (event) {
4812 case NETDEV_PRECHANGEUPPER:
4813 upper_dev = info->upper_dev;
4814 if (!netif_is_macvlan(upper_dev) &&
4815 !netif_is_l3_master(upper_dev)) {
4816 NL_SET_ERR_MSG_MOD(extack, "Unknown upper device type");
4817 return -EOPNOTSUPP;
4818 }
4819 if (!info->linking)
4820 break;
4821 if (netif_is_macvlan(upper_dev) &&
4822 !mlxsw_sp_rif_exists(mlxsw_sp, vlan_dev)) {
4823 NL_SET_ERR_MSG_MOD(extack, "macvlan is only supported on top of router interfaces");
4824 return -EOPNOTSUPP;
4825 }
4826 break;
4827 case NETDEV_CHANGEUPPER:
4828 upper_dev = info->upper_dev;
4829 if (info->linking)
4830 break;
4831 if (netif_is_macvlan(upper_dev))
4832 mlxsw_sp_rif_macvlan_del(mlxsw_sp, upper_dev);
4833 break;
4834 }
4835
4836 return 0;
4837 }
4838
mlxsw_sp_netdevice_vlan_event(struct net_device * vlan_dev,unsigned long event,void * ptr)4839 static int mlxsw_sp_netdevice_vlan_event(struct net_device *vlan_dev,
4840 unsigned long event, void *ptr)
4841 {
4842 struct net_device *real_dev = vlan_dev_real_dev(vlan_dev);
4843 u16 vid = vlan_dev_vlan_id(vlan_dev);
4844
4845 if (mlxsw_sp_port_dev_check(real_dev))
4846 return mlxsw_sp_netdevice_port_vlan_event(vlan_dev, real_dev,
4847 event, ptr, vid);
4848 else if (netif_is_lag_master(real_dev))
4849 return mlxsw_sp_netdevice_lag_port_vlan_event(vlan_dev,
4850 real_dev, event,
4851 ptr, vid);
4852 else if (netif_is_bridge_master(real_dev))
4853 return mlxsw_sp_netdevice_bridge_vlan_event(vlan_dev, real_dev,
4854 event, ptr, vid);
4855
4856 return 0;
4857 }
4858
mlxsw_sp_netdevice_bridge_event(struct net_device * br_dev,unsigned long event,void * ptr)4859 static int mlxsw_sp_netdevice_bridge_event(struct net_device *br_dev,
4860 unsigned long event, void *ptr)
4861 {
4862 struct mlxsw_sp *mlxsw_sp = mlxsw_sp_lower_get(br_dev);
4863 struct netdev_notifier_changeupper_info *info = ptr;
4864 struct netlink_ext_ack *extack;
4865 struct net_device *upper_dev;
4866 u16 proto;
4867
4868 if (!mlxsw_sp)
4869 return 0;
4870
4871 extack = netdev_notifier_info_to_extack(&info->info);
4872
4873 switch (event) {
4874 case NETDEV_PRECHANGEUPPER:
4875 upper_dev = info->upper_dev;
4876 if (!is_vlan_dev(upper_dev) &&
4877 !netif_is_macvlan(upper_dev) &&
4878 !netif_is_l3_master(upper_dev)) {
4879 NL_SET_ERR_MSG_MOD(extack, "Unknown upper device type");
4880 return -EOPNOTSUPP;
4881 }
4882 if (!info->linking)
4883 break;
4884 if (br_vlan_enabled(br_dev)) {
4885 br_vlan_get_proto(br_dev, &proto);
4886 if (proto == ETH_P_8021AD) {
4887 NL_SET_ERR_MSG_MOD(extack, "Upper devices are not supported on top of an 802.1ad bridge");
4888 return -EOPNOTSUPP;
4889 }
4890 }
4891 if (is_vlan_dev(upper_dev) &&
4892 ntohs(vlan_dev_vlan_proto(upper_dev)) != ETH_P_8021Q) {
4893 NL_SET_ERR_MSG_MOD(extack, "VLAN uppers are only supported with 802.1q VLAN protocol");
4894 return -EOPNOTSUPP;
4895 }
4896 if (netif_is_macvlan(upper_dev) &&
4897 !mlxsw_sp_rif_exists(mlxsw_sp, br_dev)) {
4898 NL_SET_ERR_MSG_MOD(extack, "macvlan is only supported on top of router interfaces");
4899 return -EOPNOTSUPP;
4900 }
4901 break;
4902 case NETDEV_CHANGEUPPER:
4903 upper_dev = info->upper_dev;
4904 if (info->linking)
4905 break;
4906 if (is_vlan_dev(upper_dev))
4907 mlxsw_sp_rif_destroy_by_dev(mlxsw_sp, upper_dev);
4908 if (netif_is_macvlan(upper_dev))
4909 mlxsw_sp_rif_macvlan_del(mlxsw_sp, upper_dev);
4910 break;
4911 }
4912
4913 return 0;
4914 }
4915
mlxsw_sp_netdevice_macvlan_event(struct net_device * macvlan_dev,unsigned long event,void * ptr)4916 static int mlxsw_sp_netdevice_macvlan_event(struct net_device *macvlan_dev,
4917 unsigned long event, void *ptr)
4918 {
4919 struct mlxsw_sp *mlxsw_sp = mlxsw_sp_lower_get(macvlan_dev);
4920 struct netdev_notifier_changeupper_info *info = ptr;
4921 struct netlink_ext_ack *extack;
4922 struct net_device *upper_dev;
4923
4924 if (!mlxsw_sp || event != NETDEV_PRECHANGEUPPER)
4925 return 0;
4926
4927 extack = netdev_notifier_info_to_extack(&info->info);
4928 upper_dev = info->upper_dev;
4929
4930 if (!netif_is_l3_master(upper_dev)) {
4931 NL_SET_ERR_MSG_MOD(extack, "Unknown upper device type");
4932 return -EOPNOTSUPP;
4933 }
4934
4935 return 0;
4936 }
4937
mlxsw_sp_netdevice_vxlan_event(struct mlxsw_sp * mlxsw_sp,struct net_device * dev,unsigned long event,void * ptr)4938 static int mlxsw_sp_netdevice_vxlan_event(struct mlxsw_sp *mlxsw_sp,
4939 struct net_device *dev,
4940 unsigned long event, void *ptr)
4941 {
4942 struct netdev_notifier_changeupper_info *cu_info;
4943 struct netdev_notifier_info *info = ptr;
4944 struct netlink_ext_ack *extack;
4945 struct net_device *upper_dev;
4946
4947 extack = netdev_notifier_info_to_extack(info);
4948
4949 switch (event) {
4950 case NETDEV_CHANGEUPPER:
4951 cu_info = container_of(info,
4952 struct netdev_notifier_changeupper_info,
4953 info);
4954 upper_dev = cu_info->upper_dev;
4955 if (!netif_is_bridge_master(upper_dev))
4956 return 0;
4957 if (!mlxsw_sp_lower_get(upper_dev))
4958 return 0;
4959 if (!mlxsw_sp_bridge_vxlan_is_valid(upper_dev, extack))
4960 return -EOPNOTSUPP;
4961 if (cu_info->linking) {
4962 if (!netif_running(dev))
4963 return 0;
4964 /* When the bridge is VLAN-aware, the VNI of the VxLAN
4965 * device needs to be mapped to a VLAN, but at this
4966 * point no VLANs are configured on the VxLAN device
4967 */
4968 if (br_vlan_enabled(upper_dev))
4969 return 0;
4970 return mlxsw_sp_bridge_vxlan_join(mlxsw_sp, upper_dev,
4971 dev, 0, extack);
4972 } else {
4973 /* VLANs were already flushed, which triggered the
4974 * necessary cleanup
4975 */
4976 if (br_vlan_enabled(upper_dev))
4977 return 0;
4978 mlxsw_sp_bridge_vxlan_leave(mlxsw_sp, dev);
4979 }
4980 break;
4981 case NETDEV_PRE_UP:
4982 upper_dev = netdev_master_upper_dev_get(dev);
4983 if (!upper_dev)
4984 return 0;
4985 if (!netif_is_bridge_master(upper_dev))
4986 return 0;
4987 if (!mlxsw_sp_lower_get(upper_dev))
4988 return 0;
4989 return mlxsw_sp_bridge_vxlan_join(mlxsw_sp, upper_dev, dev, 0,
4990 extack);
4991 case NETDEV_DOWN:
4992 upper_dev = netdev_master_upper_dev_get(dev);
4993 if (!upper_dev)
4994 return 0;
4995 if (!netif_is_bridge_master(upper_dev))
4996 return 0;
4997 if (!mlxsw_sp_lower_get(upper_dev))
4998 return 0;
4999 mlxsw_sp_bridge_vxlan_leave(mlxsw_sp, dev);
5000 break;
5001 }
5002
5003 return 0;
5004 }
5005
mlxsw_sp_netdevice_event(struct notifier_block * nb,unsigned long event,void * ptr)5006 static int mlxsw_sp_netdevice_event(struct notifier_block *nb,
5007 unsigned long event, void *ptr)
5008 {
5009 struct net_device *dev = netdev_notifier_info_to_dev(ptr);
5010 struct mlxsw_sp_span_entry *span_entry;
5011 struct mlxsw_sp *mlxsw_sp;
5012 int err = 0;
5013
5014 mlxsw_sp = container_of(nb, struct mlxsw_sp, netdevice_nb);
5015 if (event == NETDEV_UNREGISTER) {
5016 span_entry = mlxsw_sp_span_entry_find_by_port(mlxsw_sp, dev);
5017 if (span_entry)
5018 mlxsw_sp_span_entry_invalidate(mlxsw_sp, span_entry);
5019 }
5020 mlxsw_sp_span_respin(mlxsw_sp);
5021
5022 if (netif_is_vxlan(dev))
5023 err = mlxsw_sp_netdevice_vxlan_event(mlxsw_sp, dev, event, ptr);
5024 else if (mlxsw_sp_port_dev_check(dev))
5025 err = mlxsw_sp_netdevice_port_event(dev, dev, event, ptr);
5026 else if (netif_is_lag_master(dev))
5027 err = mlxsw_sp_netdevice_lag_event(dev, event, ptr);
5028 else if (is_vlan_dev(dev))
5029 err = mlxsw_sp_netdevice_vlan_event(dev, event, ptr);
5030 else if (netif_is_bridge_master(dev))
5031 err = mlxsw_sp_netdevice_bridge_event(dev, event, ptr);
5032 else if (netif_is_macvlan(dev))
5033 err = mlxsw_sp_netdevice_macvlan_event(dev, event, ptr);
5034
5035 return notifier_from_errno(err);
5036 }
5037
5038 static struct notifier_block mlxsw_sp_inetaddr_valid_nb __read_mostly = {
5039 .notifier_call = mlxsw_sp_inetaddr_valid_event,
5040 };
5041
5042 static struct notifier_block mlxsw_sp_inet6addr_valid_nb __read_mostly = {
5043 .notifier_call = mlxsw_sp_inet6addr_valid_event,
5044 };
5045
5046 static const struct pci_device_id mlxsw_sp1_pci_id_table[] = {
5047 {PCI_VDEVICE(MELLANOX, PCI_DEVICE_ID_MELLANOX_SPECTRUM), 0},
5048 {0, },
5049 };
5050
5051 static struct pci_driver mlxsw_sp1_pci_driver = {
5052 .name = mlxsw_sp1_driver_name,
5053 .id_table = mlxsw_sp1_pci_id_table,
5054 };
5055
5056 static const struct pci_device_id mlxsw_sp2_pci_id_table[] = {
5057 {PCI_VDEVICE(MELLANOX, PCI_DEVICE_ID_MELLANOX_SPECTRUM2), 0},
5058 {0, },
5059 };
5060
5061 static struct pci_driver mlxsw_sp2_pci_driver = {
5062 .name = mlxsw_sp2_driver_name,
5063 .id_table = mlxsw_sp2_pci_id_table,
5064 };
5065
5066 static const struct pci_device_id mlxsw_sp3_pci_id_table[] = {
5067 {PCI_VDEVICE(MELLANOX, PCI_DEVICE_ID_MELLANOX_SPECTRUM3), 0},
5068 {0, },
5069 };
5070
5071 static struct pci_driver mlxsw_sp3_pci_driver = {
5072 .name = mlxsw_sp3_driver_name,
5073 .id_table = mlxsw_sp3_pci_id_table,
5074 };
5075
5076 static const struct pci_device_id mlxsw_sp4_pci_id_table[] = {
5077 {PCI_VDEVICE(MELLANOX, PCI_DEVICE_ID_MELLANOX_SPECTRUM4), 0},
5078 {0, },
5079 };
5080
5081 static struct pci_driver mlxsw_sp4_pci_driver = {
5082 .name = mlxsw_sp4_driver_name,
5083 .id_table = mlxsw_sp4_pci_id_table,
5084 };
5085
mlxsw_sp_module_init(void)5086 static int __init mlxsw_sp_module_init(void)
5087 {
5088 int err;
5089
5090 register_inetaddr_validator_notifier(&mlxsw_sp_inetaddr_valid_nb);
5091 register_inet6addr_validator_notifier(&mlxsw_sp_inet6addr_valid_nb);
5092
5093 err = mlxsw_core_driver_register(&mlxsw_sp1_driver);
5094 if (err)
5095 goto err_sp1_core_driver_register;
5096
5097 err = mlxsw_core_driver_register(&mlxsw_sp2_driver);
5098 if (err)
5099 goto err_sp2_core_driver_register;
5100
5101 err = mlxsw_core_driver_register(&mlxsw_sp3_driver);
5102 if (err)
5103 goto err_sp3_core_driver_register;
5104
5105 err = mlxsw_core_driver_register(&mlxsw_sp4_driver);
5106 if (err)
5107 goto err_sp4_core_driver_register;
5108
5109 err = mlxsw_pci_driver_register(&mlxsw_sp1_pci_driver);
5110 if (err)
5111 goto err_sp1_pci_driver_register;
5112
5113 err = mlxsw_pci_driver_register(&mlxsw_sp2_pci_driver);
5114 if (err)
5115 goto err_sp2_pci_driver_register;
5116
5117 err = mlxsw_pci_driver_register(&mlxsw_sp3_pci_driver);
5118 if (err)
5119 goto err_sp3_pci_driver_register;
5120
5121 err = mlxsw_pci_driver_register(&mlxsw_sp4_pci_driver);
5122 if (err)
5123 goto err_sp4_pci_driver_register;
5124
5125 return 0;
5126
5127 err_sp4_pci_driver_register:
5128 mlxsw_pci_driver_unregister(&mlxsw_sp3_pci_driver);
5129 err_sp3_pci_driver_register:
5130 mlxsw_pci_driver_unregister(&mlxsw_sp2_pci_driver);
5131 err_sp2_pci_driver_register:
5132 mlxsw_pci_driver_unregister(&mlxsw_sp1_pci_driver);
5133 err_sp1_pci_driver_register:
5134 mlxsw_core_driver_unregister(&mlxsw_sp4_driver);
5135 err_sp4_core_driver_register:
5136 mlxsw_core_driver_unregister(&mlxsw_sp3_driver);
5137 err_sp3_core_driver_register:
5138 mlxsw_core_driver_unregister(&mlxsw_sp2_driver);
5139 err_sp2_core_driver_register:
5140 mlxsw_core_driver_unregister(&mlxsw_sp1_driver);
5141 err_sp1_core_driver_register:
5142 unregister_inet6addr_validator_notifier(&mlxsw_sp_inet6addr_valid_nb);
5143 unregister_inetaddr_validator_notifier(&mlxsw_sp_inetaddr_valid_nb);
5144 return err;
5145 }
5146
mlxsw_sp_module_exit(void)5147 static void __exit mlxsw_sp_module_exit(void)
5148 {
5149 mlxsw_pci_driver_unregister(&mlxsw_sp4_pci_driver);
5150 mlxsw_pci_driver_unregister(&mlxsw_sp3_pci_driver);
5151 mlxsw_pci_driver_unregister(&mlxsw_sp2_pci_driver);
5152 mlxsw_pci_driver_unregister(&mlxsw_sp1_pci_driver);
5153 mlxsw_core_driver_unregister(&mlxsw_sp4_driver);
5154 mlxsw_core_driver_unregister(&mlxsw_sp3_driver);
5155 mlxsw_core_driver_unregister(&mlxsw_sp2_driver);
5156 mlxsw_core_driver_unregister(&mlxsw_sp1_driver);
5157 unregister_inet6addr_validator_notifier(&mlxsw_sp_inet6addr_valid_nb);
5158 unregister_inetaddr_validator_notifier(&mlxsw_sp_inetaddr_valid_nb);
5159 }
5160
5161 module_init(mlxsw_sp_module_init);
5162 module_exit(mlxsw_sp_module_exit);
5163
5164 MODULE_LICENSE("Dual BSD/GPL");
5165 MODULE_AUTHOR("Jiri Pirko <jiri@mellanox.com>");
5166 MODULE_DESCRIPTION("Mellanox Spectrum driver");
5167 MODULE_DEVICE_TABLE(pci, mlxsw_sp1_pci_id_table);
5168 MODULE_DEVICE_TABLE(pci, mlxsw_sp2_pci_id_table);
5169 MODULE_DEVICE_TABLE(pci, mlxsw_sp3_pci_id_table);
5170 MODULE_DEVICE_TABLE(pci, mlxsw_sp4_pci_id_table);
5171 MODULE_FIRMWARE(MLXSW_SP1_FW_FILENAME);
5172 MODULE_FIRMWARE(MLXSW_SP2_FW_FILENAME);
5173 MODULE_FIRMWARE(MLXSW_SP3_FW_FILENAME);
5174 MODULE_FIRMWARE(MLXSW_SP_LINECARDS_INI_BUNDLE_FILENAME);
5175