Linux-libre 5.3.12-gnu
[librecmc/linux-libre.git] / drivers / net / ethernet / mellanox / mlxsw / spectrum.c
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 <net/switchdev.h>
26 #include <net/pkt_cls.h>
27 #include <net/tc_act/tc_mirred.h>
28 #include <net/netevent.h>
29 #include <net/tc_act/tc_sample.h>
30 #include <net/addrconf.h>
31
32 #include "spectrum.h"
33 #include "pci.h"
34 #include "core.h"
35 #include "core_env.h"
36 #include "reg.h"
37 #include "port.h"
38 #include "trap.h"
39 #include "txheader.h"
40 #include "spectrum_cnt.h"
41 #include "spectrum_dpipe.h"
42 #include "spectrum_acl_flex_actions.h"
43 #include "spectrum_span.h"
44 #include "spectrum_ptp.h"
45 #include "../mlxfw/mlxfw.h"
46
47 #define MLXSW_SP_FWREV_MINOR_TO_BRANCH(minor) ((minor) / 100)
48
49 #define MLXSW_SP1_FWREV_MAJOR 13
50 #define MLXSW_SP1_FWREV_MINOR 2000
51 #define MLXSW_SP1_FWREV_SUBMINOR 1122
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_SP1_FWREV_MINOR,
57         .subminor = MLXSW_SP1_FWREV_SUBMINOR,
58         .can_reset_minor = MLXSW_SP1_FWREV_CAN_RESET_MINOR,
59 };
60
61 #define MLXSW_SP1_FW_FILENAME \
62         "/*(DEBLOBBED)*/"
63
64 static const char mlxsw_sp1_driver_name[] = "mlxsw_spectrum";
65 static const char mlxsw_sp2_driver_name[] = "mlxsw_spectrum2";
66 static const char mlxsw_sp_driver_version[] = "1.0";
67
68 static const unsigned char mlxsw_sp1_mac_mask[ETH_ALEN] = {
69         0xff, 0xff, 0xff, 0xff, 0xfc, 0x00
70 };
71 static const unsigned char mlxsw_sp2_mac_mask[ETH_ALEN] = {
72         0xff, 0xff, 0xff, 0xff, 0xf0, 0x00
73 };
74
75 /* tx_hdr_version
76  * Tx header version.
77  * Must be set to 1.
78  */
79 MLXSW_ITEM32(tx, hdr, version, 0x00, 28, 4);
80
81 /* tx_hdr_ctl
82  * Packet control type.
83  * 0 - Ethernet control (e.g. EMADs, LACP)
84  * 1 - Ethernet data
85  */
86 MLXSW_ITEM32(tx, hdr, ctl, 0x00, 26, 2);
87
88 /* tx_hdr_proto
89  * Packet protocol type. Must be set to 1 (Ethernet).
90  */
91 MLXSW_ITEM32(tx, hdr, proto, 0x00, 21, 3);
92
93 /* tx_hdr_rx_is_router
94  * Packet is sent from the router. Valid for data packets only.
95  */
96 MLXSW_ITEM32(tx, hdr, rx_is_router, 0x00, 19, 1);
97
98 /* tx_hdr_fid_valid
99  * Indicates if the 'fid' field is valid and should be used for
100  * forwarding lookup. Valid for data packets only.
101  */
102 MLXSW_ITEM32(tx, hdr, fid_valid, 0x00, 16, 1);
103
104 /* tx_hdr_swid
105  * Switch partition ID. Must be set to 0.
106  */
107 MLXSW_ITEM32(tx, hdr, swid, 0x00, 12, 3);
108
109 /* tx_hdr_control_tclass
110  * Indicates if the packet should use the control TClass and not one
111  * of the data TClasses.
112  */
113 MLXSW_ITEM32(tx, hdr, control_tclass, 0x00, 6, 1);
114
115 /* tx_hdr_etclass
116  * Egress TClass to be used on the egress device on the egress port.
117  */
118 MLXSW_ITEM32(tx, hdr, etclass, 0x00, 0, 4);
119
120 /* tx_hdr_port_mid
121  * Destination local port for unicast packets.
122  * Destination multicast ID for multicast packets.
123  *
124  * Control packets are directed to a specific egress port, while data
125  * packets are transmitted through the CPU port (0) into the switch partition,
126  * where forwarding rules are applied.
127  */
128 MLXSW_ITEM32(tx, hdr, port_mid, 0x04, 16, 16);
129
130 /* tx_hdr_fid
131  * Forwarding ID used for L2 forwarding lookup. Valid only if 'fid_valid' is
132  * set, otherwise calculated based on the packet's VID using VID to FID mapping.
133  * Valid for data packets only.
134  */
135 MLXSW_ITEM32(tx, hdr, fid, 0x08, 0, 16);
136
137 /* tx_hdr_type
138  * 0 - Data packets
139  * 6 - Control packets
140  */
141 MLXSW_ITEM32(tx, hdr, type, 0x0C, 0, 4);
142
143 struct mlxsw_sp_mlxfw_dev {
144         struct mlxfw_dev mlxfw_dev;
145         struct mlxsw_sp *mlxsw_sp;
146 };
147
148 struct mlxsw_sp_ptp_ops {
149         struct mlxsw_sp_ptp_clock *
150                 (*clock_init)(struct mlxsw_sp *mlxsw_sp, struct device *dev);
151         void (*clock_fini)(struct mlxsw_sp_ptp_clock *clock);
152
153         struct mlxsw_sp_ptp_state *(*init)(struct mlxsw_sp *mlxsw_sp);
154         void (*fini)(struct mlxsw_sp_ptp_state *ptp_state);
155
156         /* Notify a driver that a packet that might be PTP was received. Driver
157          * is responsible for freeing the passed-in SKB.
158          */
159         void (*receive)(struct mlxsw_sp *mlxsw_sp, struct sk_buff *skb,
160                         u8 local_port);
161
162         /* Notify a driver that a timestamped packet was transmitted. Driver
163          * is responsible for freeing the passed-in SKB.
164          */
165         void (*transmitted)(struct mlxsw_sp *mlxsw_sp, struct sk_buff *skb,
166                             u8 local_port);
167
168         int (*hwtstamp_get)(struct mlxsw_sp_port *mlxsw_sp_port,
169                             struct hwtstamp_config *config);
170         int (*hwtstamp_set)(struct mlxsw_sp_port *mlxsw_sp_port,
171                             struct hwtstamp_config *config);
172         void (*shaper_work)(struct work_struct *work);
173         int (*get_ts_info)(struct mlxsw_sp *mlxsw_sp,
174                            struct ethtool_ts_info *info);
175 };
176
177 static int mlxsw_sp_component_query(struct mlxfw_dev *mlxfw_dev,
178                                     u16 component_index, u32 *p_max_size,
179                                     u8 *p_align_bits, u16 *p_max_write_size)
180 {
181         struct mlxsw_sp_mlxfw_dev *mlxsw_sp_mlxfw_dev =
182                 container_of(mlxfw_dev, struct mlxsw_sp_mlxfw_dev, mlxfw_dev);
183         struct mlxsw_sp *mlxsw_sp = mlxsw_sp_mlxfw_dev->mlxsw_sp;
184         char mcqi_pl[MLXSW_REG_MCQI_LEN];
185         int err;
186
187         mlxsw_reg_mcqi_pack(mcqi_pl, component_index);
188         err = mlxsw_reg_query(mlxsw_sp->core, MLXSW_REG(mcqi), mcqi_pl);
189         if (err)
190                 return err;
191         mlxsw_reg_mcqi_unpack(mcqi_pl, p_max_size, p_align_bits,
192                               p_max_write_size);
193
194         *p_align_bits = max_t(u8, *p_align_bits, 2);
195         *p_max_write_size = min_t(u16, *p_max_write_size,
196                                   MLXSW_REG_MCDA_MAX_DATA_LEN);
197         return 0;
198 }
199
200 static int mlxsw_sp_fsm_lock(struct mlxfw_dev *mlxfw_dev, u32 *fwhandle)
201 {
202         struct mlxsw_sp_mlxfw_dev *mlxsw_sp_mlxfw_dev =
203                 container_of(mlxfw_dev, struct mlxsw_sp_mlxfw_dev, mlxfw_dev);
204         struct mlxsw_sp *mlxsw_sp = mlxsw_sp_mlxfw_dev->mlxsw_sp;
205         char mcc_pl[MLXSW_REG_MCC_LEN];
206         u8 control_state;
207         int err;
208
209         mlxsw_reg_mcc_pack(mcc_pl, 0, 0, 0, 0);
210         err = mlxsw_reg_query(mlxsw_sp->core, MLXSW_REG(mcc), mcc_pl);
211         if (err)
212                 return err;
213
214         mlxsw_reg_mcc_unpack(mcc_pl, fwhandle, NULL, &control_state);
215         if (control_state != MLXFW_FSM_STATE_IDLE)
216                 return -EBUSY;
217
218         mlxsw_reg_mcc_pack(mcc_pl,
219                            MLXSW_REG_MCC_INSTRUCTION_LOCK_UPDATE_HANDLE,
220                            0, *fwhandle, 0);
221         return mlxsw_reg_write(mlxsw_sp->core, MLXSW_REG(mcc), mcc_pl);
222 }
223
224 static int mlxsw_sp_fsm_component_update(struct mlxfw_dev *mlxfw_dev,
225                                          u32 fwhandle, u16 component_index,
226                                          u32 component_size)
227 {
228         struct mlxsw_sp_mlxfw_dev *mlxsw_sp_mlxfw_dev =
229                 container_of(mlxfw_dev, struct mlxsw_sp_mlxfw_dev, mlxfw_dev);
230         struct mlxsw_sp *mlxsw_sp = mlxsw_sp_mlxfw_dev->mlxsw_sp;
231         char mcc_pl[MLXSW_REG_MCC_LEN];
232
233         mlxsw_reg_mcc_pack(mcc_pl, MLXSW_REG_MCC_INSTRUCTION_UPDATE_COMPONENT,
234                            component_index, fwhandle, component_size);
235         return mlxsw_reg_write(mlxsw_sp->core, MLXSW_REG(mcc), mcc_pl);
236 }
237
238 static int mlxsw_sp_fsm_block_download(struct mlxfw_dev *mlxfw_dev,
239                                        u32 fwhandle, u8 *data, u16 size,
240                                        u32 offset)
241 {
242         struct mlxsw_sp_mlxfw_dev *mlxsw_sp_mlxfw_dev =
243                 container_of(mlxfw_dev, struct mlxsw_sp_mlxfw_dev, mlxfw_dev);
244         struct mlxsw_sp *mlxsw_sp = mlxsw_sp_mlxfw_dev->mlxsw_sp;
245         char mcda_pl[MLXSW_REG_MCDA_LEN];
246
247         mlxsw_reg_mcda_pack(mcda_pl, fwhandle, offset, size, data);
248         return mlxsw_reg_write(mlxsw_sp->core, MLXSW_REG(mcda), mcda_pl);
249 }
250
251 static int mlxsw_sp_fsm_component_verify(struct mlxfw_dev *mlxfw_dev,
252                                          u32 fwhandle, u16 component_index)
253 {
254         struct mlxsw_sp_mlxfw_dev *mlxsw_sp_mlxfw_dev =
255                 container_of(mlxfw_dev, struct mlxsw_sp_mlxfw_dev, mlxfw_dev);
256         struct mlxsw_sp *mlxsw_sp = mlxsw_sp_mlxfw_dev->mlxsw_sp;
257         char mcc_pl[MLXSW_REG_MCC_LEN];
258
259         mlxsw_reg_mcc_pack(mcc_pl, MLXSW_REG_MCC_INSTRUCTION_VERIFY_COMPONENT,
260                            component_index, fwhandle, 0);
261         return mlxsw_reg_write(mlxsw_sp->core, MLXSW_REG(mcc), mcc_pl);
262 }
263
264 static int mlxsw_sp_fsm_activate(struct mlxfw_dev *mlxfw_dev, u32 fwhandle)
265 {
266         struct mlxsw_sp_mlxfw_dev *mlxsw_sp_mlxfw_dev =
267                 container_of(mlxfw_dev, struct mlxsw_sp_mlxfw_dev, mlxfw_dev);
268         struct mlxsw_sp *mlxsw_sp = mlxsw_sp_mlxfw_dev->mlxsw_sp;
269         char mcc_pl[MLXSW_REG_MCC_LEN];
270
271         mlxsw_reg_mcc_pack(mcc_pl, MLXSW_REG_MCC_INSTRUCTION_ACTIVATE, 0,
272                            fwhandle, 0);
273         return mlxsw_reg_write(mlxsw_sp->core, MLXSW_REG(mcc), mcc_pl);
274 }
275
276 static int mlxsw_sp_fsm_query_state(struct mlxfw_dev *mlxfw_dev, u32 fwhandle,
277                                     enum mlxfw_fsm_state *fsm_state,
278                                     enum mlxfw_fsm_state_err *fsm_state_err)
279 {
280         struct mlxsw_sp_mlxfw_dev *mlxsw_sp_mlxfw_dev =
281                 container_of(mlxfw_dev, struct mlxsw_sp_mlxfw_dev, mlxfw_dev);
282         struct mlxsw_sp *mlxsw_sp = mlxsw_sp_mlxfw_dev->mlxsw_sp;
283         char mcc_pl[MLXSW_REG_MCC_LEN];
284         u8 control_state;
285         u8 error_code;
286         int err;
287
288         mlxsw_reg_mcc_pack(mcc_pl, 0, 0, fwhandle, 0);
289         err = mlxsw_reg_query(mlxsw_sp->core, MLXSW_REG(mcc), mcc_pl);
290         if (err)
291                 return err;
292
293         mlxsw_reg_mcc_unpack(mcc_pl, NULL, &error_code, &control_state);
294         *fsm_state = control_state;
295         *fsm_state_err = min_t(enum mlxfw_fsm_state_err, error_code,
296                                MLXFW_FSM_STATE_ERR_MAX);
297         return 0;
298 }
299
300 static void mlxsw_sp_fsm_cancel(struct mlxfw_dev *mlxfw_dev, u32 fwhandle)
301 {
302         struct mlxsw_sp_mlxfw_dev *mlxsw_sp_mlxfw_dev =
303                 container_of(mlxfw_dev, struct mlxsw_sp_mlxfw_dev, mlxfw_dev);
304         struct mlxsw_sp *mlxsw_sp = mlxsw_sp_mlxfw_dev->mlxsw_sp;
305         char mcc_pl[MLXSW_REG_MCC_LEN];
306
307         mlxsw_reg_mcc_pack(mcc_pl, MLXSW_REG_MCC_INSTRUCTION_CANCEL, 0,
308                            fwhandle, 0);
309         mlxsw_reg_write(mlxsw_sp->core, MLXSW_REG(mcc), mcc_pl);
310 }
311
312 static void mlxsw_sp_fsm_release(struct mlxfw_dev *mlxfw_dev, u32 fwhandle)
313 {
314         struct mlxsw_sp_mlxfw_dev *mlxsw_sp_mlxfw_dev =
315                 container_of(mlxfw_dev, struct mlxsw_sp_mlxfw_dev, mlxfw_dev);
316         struct mlxsw_sp *mlxsw_sp = mlxsw_sp_mlxfw_dev->mlxsw_sp;
317         char mcc_pl[MLXSW_REG_MCC_LEN];
318
319         mlxsw_reg_mcc_pack(mcc_pl,
320                            MLXSW_REG_MCC_INSTRUCTION_RELEASE_UPDATE_HANDLE, 0,
321                            fwhandle, 0);
322         mlxsw_reg_write(mlxsw_sp->core, MLXSW_REG(mcc), mcc_pl);
323 }
324
325 static void mlxsw_sp_status_notify(struct mlxfw_dev *mlxfw_dev,
326                                    const char *msg, const char *comp_name,
327                                    u32 done_bytes, u32 total_bytes)
328 {
329         struct mlxsw_sp_mlxfw_dev *mlxsw_sp_mlxfw_dev =
330                 container_of(mlxfw_dev, struct mlxsw_sp_mlxfw_dev, mlxfw_dev);
331         struct mlxsw_sp *mlxsw_sp = mlxsw_sp_mlxfw_dev->mlxsw_sp;
332
333         devlink_flash_update_status_notify(priv_to_devlink(mlxsw_sp->core),
334                                            msg, comp_name,
335                                            done_bytes, total_bytes);
336 }
337
338 static const struct mlxfw_dev_ops mlxsw_sp_mlxfw_dev_ops = {
339         .component_query        = mlxsw_sp_component_query,
340         .fsm_lock               = mlxsw_sp_fsm_lock,
341         .fsm_component_update   = mlxsw_sp_fsm_component_update,
342         .fsm_block_download     = mlxsw_sp_fsm_block_download,
343         .fsm_component_verify   = mlxsw_sp_fsm_component_verify,
344         .fsm_activate           = mlxsw_sp_fsm_activate,
345         .fsm_query_state        = mlxsw_sp_fsm_query_state,
346         .fsm_cancel             = mlxsw_sp_fsm_cancel,
347         .fsm_release            = mlxsw_sp_fsm_release,
348         .status_notify          = mlxsw_sp_status_notify,
349 };
350
351 static int mlxsw_sp_firmware_flash(struct mlxsw_sp *mlxsw_sp,
352                                    const struct firmware *firmware,
353                                    struct netlink_ext_ack *extack)
354 {
355         struct mlxsw_sp_mlxfw_dev mlxsw_sp_mlxfw_dev = {
356                 .mlxfw_dev = {
357                         .ops = &mlxsw_sp_mlxfw_dev_ops,
358                         .psid = mlxsw_sp->bus_info->psid,
359                         .psid_size = strlen(mlxsw_sp->bus_info->psid),
360                 },
361                 .mlxsw_sp = mlxsw_sp
362         };
363         int err;
364
365         mlxsw_core_fw_flash_start(mlxsw_sp->core);
366         devlink_flash_update_begin_notify(priv_to_devlink(mlxsw_sp->core));
367         err = mlxfw_firmware_flash(&mlxsw_sp_mlxfw_dev.mlxfw_dev,
368                                    firmware, extack);
369         devlink_flash_update_end_notify(priv_to_devlink(mlxsw_sp->core));
370         mlxsw_core_fw_flash_end(mlxsw_sp->core);
371
372         return err;
373 }
374
375 static int mlxsw_sp_fw_rev_validate(struct mlxsw_sp *mlxsw_sp)
376 {
377         const struct mlxsw_fw_rev *rev = &mlxsw_sp->bus_info->fw_rev;
378         const struct mlxsw_fw_rev *req_rev = mlxsw_sp->req_rev;
379         const char *fw_filename = mlxsw_sp->fw_filename;
380         union devlink_param_value value;
381         const struct firmware *firmware;
382         int err;
383
384         /* Don't check if driver does not require it */
385         if (!req_rev || !fw_filename)
386                 return 0;
387
388         /* Don't check if devlink 'fw_load_policy' param is 'flash' */
389         err = devlink_param_driverinit_value_get(priv_to_devlink(mlxsw_sp->core),
390                                                  DEVLINK_PARAM_GENERIC_ID_FW_LOAD_POLICY,
391                                                  &value);
392         if (err)
393                 return err;
394         if (value.vu8 == DEVLINK_PARAM_FW_LOAD_POLICY_VALUE_FLASH)
395                 return 0;
396
397         /* Validate driver & FW are compatible */
398         if (rev->major != req_rev->major) {
399                 WARN(1, "Mismatch in major FW version [%d:%d] is never expected; Please contact support\n",
400                      rev->major, req_rev->major);
401                 return -EINVAL;
402         }
403         if (MLXSW_SP_FWREV_MINOR_TO_BRANCH(rev->minor) ==
404             MLXSW_SP_FWREV_MINOR_TO_BRANCH(req_rev->minor) &&
405             (rev->minor > req_rev->minor ||
406              (rev->minor == req_rev->minor &&
407               rev->subminor >= req_rev->subminor)))
408                 return 0;
409
410         dev_info(mlxsw_sp->bus_info->dev, "The firmware version %d.%d.%d is incompatible with the driver\n",
411                  rev->major, rev->minor, rev->subminor);
412         dev_info(mlxsw_sp->bus_info->dev, "Flashing firmware using file %s\n",
413                  fw_filename);
414
415         err = reject_firmware_direct(&firmware, fw_filename,
416                                       mlxsw_sp->bus_info->dev);
417         if (err) {
418                 dev_err(mlxsw_sp->bus_info->dev, "Could not request firmware file %s\n",
419                         fw_filename);
420                 return err;
421         }
422
423         err = mlxsw_sp_firmware_flash(mlxsw_sp, firmware, NULL);
424         release_firmware(firmware);
425         if (err)
426                 dev_err(mlxsw_sp->bus_info->dev, "Could not upgrade firmware\n");
427
428         /* On FW flash success, tell the caller FW reset is needed
429          * if current FW supports it.
430          */
431         if (rev->minor >= req_rev->can_reset_minor)
432                 return err ? err : -EAGAIN;
433         else
434                 return 0;
435 }
436
437 static int mlxsw_sp_flash_update(struct mlxsw_core *mlxsw_core,
438                                  const char *file_name, const char *component,
439                                  struct netlink_ext_ack *extack)
440 {
441         struct mlxsw_sp *mlxsw_sp = mlxsw_core_driver_priv(mlxsw_core);
442         const struct firmware *firmware;
443         int err;
444
445         if (component)
446                 return -EOPNOTSUPP;
447
448         err = request_firmware_direct(&firmware, file_name,
449                                       mlxsw_sp->bus_info->dev);
450         if (err)
451                 return err;
452         err = mlxsw_sp_firmware_flash(mlxsw_sp, firmware, extack);
453         release_firmware(firmware);
454
455         return err;
456 }
457
458 int mlxsw_sp_flow_counter_get(struct mlxsw_sp *mlxsw_sp,
459                               unsigned int counter_index, u64 *packets,
460                               u64 *bytes)
461 {
462         char mgpc_pl[MLXSW_REG_MGPC_LEN];
463         int err;
464
465         mlxsw_reg_mgpc_pack(mgpc_pl, counter_index, MLXSW_REG_MGPC_OPCODE_NOP,
466                             MLXSW_REG_FLOW_COUNTER_SET_TYPE_PACKETS_BYTES);
467         err = mlxsw_reg_query(mlxsw_sp->core, MLXSW_REG(mgpc), mgpc_pl);
468         if (err)
469                 return err;
470         if (packets)
471                 *packets = mlxsw_reg_mgpc_packet_counter_get(mgpc_pl);
472         if (bytes)
473                 *bytes = mlxsw_reg_mgpc_byte_counter_get(mgpc_pl);
474         return 0;
475 }
476
477 static int mlxsw_sp_flow_counter_clear(struct mlxsw_sp *mlxsw_sp,
478                                        unsigned int counter_index)
479 {
480         char mgpc_pl[MLXSW_REG_MGPC_LEN];
481
482         mlxsw_reg_mgpc_pack(mgpc_pl, counter_index, MLXSW_REG_MGPC_OPCODE_CLEAR,
483                             MLXSW_REG_FLOW_COUNTER_SET_TYPE_PACKETS_BYTES);
484         return mlxsw_reg_write(mlxsw_sp->core, MLXSW_REG(mgpc), mgpc_pl);
485 }
486
487 int mlxsw_sp_flow_counter_alloc(struct mlxsw_sp *mlxsw_sp,
488                                 unsigned int *p_counter_index)
489 {
490         int err;
491
492         err = mlxsw_sp_counter_alloc(mlxsw_sp, MLXSW_SP_COUNTER_SUB_POOL_FLOW,
493                                      p_counter_index);
494         if (err)
495                 return err;
496         err = mlxsw_sp_flow_counter_clear(mlxsw_sp, *p_counter_index);
497         if (err)
498                 goto err_counter_clear;
499         return 0;
500
501 err_counter_clear:
502         mlxsw_sp_counter_free(mlxsw_sp, MLXSW_SP_COUNTER_SUB_POOL_FLOW,
503                               *p_counter_index);
504         return err;
505 }
506
507 void mlxsw_sp_flow_counter_free(struct mlxsw_sp *mlxsw_sp,
508                                 unsigned int counter_index)
509 {
510          mlxsw_sp_counter_free(mlxsw_sp, MLXSW_SP_COUNTER_SUB_POOL_FLOW,
511                                counter_index);
512 }
513
514 static void mlxsw_sp_txhdr_construct(struct sk_buff *skb,
515                                      const struct mlxsw_tx_info *tx_info)
516 {
517         char *txhdr = skb_push(skb, MLXSW_TXHDR_LEN);
518
519         memset(txhdr, 0, MLXSW_TXHDR_LEN);
520
521         mlxsw_tx_hdr_version_set(txhdr, MLXSW_TXHDR_VERSION_1);
522         mlxsw_tx_hdr_ctl_set(txhdr, MLXSW_TXHDR_ETH_CTL);
523         mlxsw_tx_hdr_proto_set(txhdr, MLXSW_TXHDR_PROTO_ETH);
524         mlxsw_tx_hdr_swid_set(txhdr, 0);
525         mlxsw_tx_hdr_control_tclass_set(txhdr, 1);
526         mlxsw_tx_hdr_port_mid_set(txhdr, tx_info->local_port);
527         mlxsw_tx_hdr_type_set(txhdr, MLXSW_TXHDR_TYPE_CONTROL);
528 }
529
530 enum mlxsw_reg_spms_state mlxsw_sp_stp_spms_state(u8 state)
531 {
532         switch (state) {
533         case BR_STATE_FORWARDING:
534                 return MLXSW_REG_SPMS_STATE_FORWARDING;
535         case BR_STATE_LEARNING:
536                 return MLXSW_REG_SPMS_STATE_LEARNING;
537         case BR_STATE_LISTENING: /* fall-through */
538         case BR_STATE_DISABLED: /* fall-through */
539         case BR_STATE_BLOCKING:
540                 return MLXSW_REG_SPMS_STATE_DISCARDING;
541         default:
542                 BUG();
543         }
544 }
545
546 int mlxsw_sp_port_vid_stp_set(struct mlxsw_sp_port *mlxsw_sp_port, u16 vid,
547                               u8 state)
548 {
549         enum mlxsw_reg_spms_state spms_state = mlxsw_sp_stp_spms_state(state);
550         struct mlxsw_sp *mlxsw_sp = mlxsw_sp_port->mlxsw_sp;
551         char *spms_pl;
552         int err;
553
554         spms_pl = kmalloc(MLXSW_REG_SPMS_LEN, GFP_KERNEL);
555         if (!spms_pl)
556                 return -ENOMEM;
557         mlxsw_reg_spms_pack(spms_pl, mlxsw_sp_port->local_port);
558         mlxsw_reg_spms_vid_pack(spms_pl, vid, spms_state);
559
560         err = mlxsw_reg_write(mlxsw_sp->core, MLXSW_REG(spms), spms_pl);
561         kfree(spms_pl);
562         return err;
563 }
564
565 static int mlxsw_sp_base_mac_get(struct mlxsw_sp *mlxsw_sp)
566 {
567         char spad_pl[MLXSW_REG_SPAD_LEN] = {0};
568         int err;
569
570         err = mlxsw_reg_query(mlxsw_sp->core, MLXSW_REG(spad), spad_pl);
571         if (err)
572                 return err;
573         mlxsw_reg_spad_base_mac_memcpy_from(spad_pl, mlxsw_sp->base_mac);
574         return 0;
575 }
576
577 static int mlxsw_sp_port_sample_set(struct mlxsw_sp_port *mlxsw_sp_port,
578                                     bool enable, u32 rate)
579 {
580         struct mlxsw_sp *mlxsw_sp = mlxsw_sp_port->mlxsw_sp;
581         char mpsc_pl[MLXSW_REG_MPSC_LEN];
582
583         mlxsw_reg_mpsc_pack(mpsc_pl, mlxsw_sp_port->local_port, enable, rate);
584         return mlxsw_reg_write(mlxsw_sp->core, MLXSW_REG(mpsc), mpsc_pl);
585 }
586
587 static int mlxsw_sp_port_admin_status_set(struct mlxsw_sp_port *mlxsw_sp_port,
588                                           bool is_up)
589 {
590         struct mlxsw_sp *mlxsw_sp = mlxsw_sp_port->mlxsw_sp;
591         char paos_pl[MLXSW_REG_PAOS_LEN];
592
593         mlxsw_reg_paos_pack(paos_pl, mlxsw_sp_port->local_port,
594                             is_up ? MLXSW_PORT_ADMIN_STATUS_UP :
595                             MLXSW_PORT_ADMIN_STATUS_DOWN);
596         return mlxsw_reg_write(mlxsw_sp->core, MLXSW_REG(paos), paos_pl);
597 }
598
599 static int mlxsw_sp_port_dev_addr_set(struct mlxsw_sp_port *mlxsw_sp_port,
600                                       unsigned char *addr)
601 {
602         struct mlxsw_sp *mlxsw_sp = mlxsw_sp_port->mlxsw_sp;
603         char ppad_pl[MLXSW_REG_PPAD_LEN];
604
605         mlxsw_reg_ppad_pack(ppad_pl, true, mlxsw_sp_port->local_port);
606         mlxsw_reg_ppad_mac_memcpy_to(ppad_pl, addr);
607         return mlxsw_reg_write(mlxsw_sp->core, MLXSW_REG(ppad), ppad_pl);
608 }
609
610 static int mlxsw_sp_port_dev_addr_init(struct mlxsw_sp_port *mlxsw_sp_port)
611 {
612         struct mlxsw_sp *mlxsw_sp = mlxsw_sp_port->mlxsw_sp;
613         unsigned char *addr = mlxsw_sp_port->dev->dev_addr;
614
615         ether_addr_copy(addr, mlxsw_sp->base_mac);
616         addr[ETH_ALEN - 1] += mlxsw_sp_port->local_port;
617         return mlxsw_sp_port_dev_addr_set(mlxsw_sp_port, addr);
618 }
619
620 static int mlxsw_sp_port_mtu_set(struct mlxsw_sp_port *mlxsw_sp_port, u16 mtu)
621 {
622         struct mlxsw_sp *mlxsw_sp = mlxsw_sp_port->mlxsw_sp;
623         char pmtu_pl[MLXSW_REG_PMTU_LEN];
624         int max_mtu;
625         int err;
626
627         mtu += MLXSW_TXHDR_LEN + ETH_HLEN;
628         mlxsw_reg_pmtu_pack(pmtu_pl, mlxsw_sp_port->local_port, 0);
629         err = mlxsw_reg_query(mlxsw_sp->core, MLXSW_REG(pmtu), pmtu_pl);
630         if (err)
631                 return err;
632         max_mtu = mlxsw_reg_pmtu_max_mtu_get(pmtu_pl);
633
634         if (mtu > max_mtu)
635                 return -EINVAL;
636
637         mlxsw_reg_pmtu_pack(pmtu_pl, mlxsw_sp_port->local_port, mtu);
638         return mlxsw_reg_write(mlxsw_sp->core, MLXSW_REG(pmtu), pmtu_pl);
639 }
640
641 static int mlxsw_sp_port_swid_set(struct mlxsw_sp_port *mlxsw_sp_port, u8 swid)
642 {
643         struct mlxsw_sp *mlxsw_sp = mlxsw_sp_port->mlxsw_sp;
644         char pspa_pl[MLXSW_REG_PSPA_LEN];
645
646         mlxsw_reg_pspa_pack(pspa_pl, swid, mlxsw_sp_port->local_port);
647         return mlxsw_reg_write(mlxsw_sp->core, MLXSW_REG(pspa), pspa_pl);
648 }
649
650 int mlxsw_sp_port_vp_mode_set(struct mlxsw_sp_port *mlxsw_sp_port, bool enable)
651 {
652         struct mlxsw_sp *mlxsw_sp = mlxsw_sp_port->mlxsw_sp;
653         char svpe_pl[MLXSW_REG_SVPE_LEN];
654
655         mlxsw_reg_svpe_pack(svpe_pl, mlxsw_sp_port->local_port, enable);
656         return mlxsw_reg_write(mlxsw_sp->core, MLXSW_REG(svpe), svpe_pl);
657 }
658
659 int mlxsw_sp_port_vid_learning_set(struct mlxsw_sp_port *mlxsw_sp_port, u16 vid,
660                                    bool learn_enable)
661 {
662         struct mlxsw_sp *mlxsw_sp = mlxsw_sp_port->mlxsw_sp;
663         char *spvmlr_pl;
664         int err;
665
666         spvmlr_pl = kmalloc(MLXSW_REG_SPVMLR_LEN, GFP_KERNEL);
667         if (!spvmlr_pl)
668                 return -ENOMEM;
669         mlxsw_reg_spvmlr_pack(spvmlr_pl, mlxsw_sp_port->local_port, vid, vid,
670                               learn_enable);
671         err = mlxsw_reg_write(mlxsw_sp->core, MLXSW_REG(spvmlr), spvmlr_pl);
672         kfree(spvmlr_pl);
673         return err;
674 }
675
676 static int __mlxsw_sp_port_pvid_set(struct mlxsw_sp_port *mlxsw_sp_port,
677                                     u16 vid)
678 {
679         struct mlxsw_sp *mlxsw_sp = mlxsw_sp_port->mlxsw_sp;
680         char spvid_pl[MLXSW_REG_SPVID_LEN];
681
682         mlxsw_reg_spvid_pack(spvid_pl, mlxsw_sp_port->local_port, vid);
683         return mlxsw_reg_write(mlxsw_sp->core, MLXSW_REG(spvid), spvid_pl);
684 }
685
686 static int mlxsw_sp_port_allow_untagged_set(struct mlxsw_sp_port *mlxsw_sp_port,
687                                             bool allow)
688 {
689         struct mlxsw_sp *mlxsw_sp = mlxsw_sp_port->mlxsw_sp;
690         char spaft_pl[MLXSW_REG_SPAFT_LEN];
691
692         mlxsw_reg_spaft_pack(spaft_pl, mlxsw_sp_port->local_port, allow);
693         return mlxsw_reg_write(mlxsw_sp->core, MLXSW_REG(spaft), spaft_pl);
694 }
695
696 int mlxsw_sp_port_pvid_set(struct mlxsw_sp_port *mlxsw_sp_port, u16 vid)
697 {
698         int err;
699
700         if (!vid) {
701                 err = mlxsw_sp_port_allow_untagged_set(mlxsw_sp_port, false);
702                 if (err)
703                         return err;
704         } else {
705                 err = __mlxsw_sp_port_pvid_set(mlxsw_sp_port, vid);
706                 if (err)
707                         return err;
708                 err = mlxsw_sp_port_allow_untagged_set(mlxsw_sp_port, true);
709                 if (err)
710                         goto err_port_allow_untagged_set;
711         }
712
713         mlxsw_sp_port->pvid = vid;
714         return 0;
715
716 err_port_allow_untagged_set:
717         __mlxsw_sp_port_pvid_set(mlxsw_sp_port, mlxsw_sp_port->pvid);
718         return err;
719 }
720
721 static int
722 mlxsw_sp_port_system_port_mapping_set(struct mlxsw_sp_port *mlxsw_sp_port)
723 {
724         struct mlxsw_sp *mlxsw_sp = mlxsw_sp_port->mlxsw_sp;
725         char sspr_pl[MLXSW_REG_SSPR_LEN];
726
727         mlxsw_reg_sspr_pack(sspr_pl, mlxsw_sp_port->local_port);
728         return mlxsw_reg_write(mlxsw_sp->core, MLXSW_REG(sspr), sspr_pl);
729 }
730
731 static int mlxsw_sp_port_module_info_get(struct mlxsw_sp *mlxsw_sp,
732                                          u8 local_port, u8 *p_module,
733                                          u8 *p_width, u8 *p_lane)
734 {
735         char pmlp_pl[MLXSW_REG_PMLP_LEN];
736         int err;
737
738         mlxsw_reg_pmlp_pack(pmlp_pl, local_port);
739         err = mlxsw_reg_query(mlxsw_sp->core, MLXSW_REG(pmlp), pmlp_pl);
740         if (err)
741                 return err;
742         *p_module = mlxsw_reg_pmlp_module_get(pmlp_pl, 0);
743         *p_width = mlxsw_reg_pmlp_width_get(pmlp_pl);
744         *p_lane = mlxsw_reg_pmlp_tx_lane_get(pmlp_pl, 0);
745         return 0;
746 }
747
748 static int mlxsw_sp_port_module_map(struct mlxsw_sp_port *mlxsw_sp_port,
749                                     u8 module, u8 width, u8 lane)
750 {
751         struct mlxsw_sp *mlxsw_sp = mlxsw_sp_port->mlxsw_sp;
752         char pmlp_pl[MLXSW_REG_PMLP_LEN];
753         int i;
754
755         mlxsw_reg_pmlp_pack(pmlp_pl, mlxsw_sp_port->local_port);
756         mlxsw_reg_pmlp_width_set(pmlp_pl, width);
757         for (i = 0; i < width; i++) {
758                 mlxsw_reg_pmlp_module_set(pmlp_pl, i, module);
759                 mlxsw_reg_pmlp_tx_lane_set(pmlp_pl, i, lane + i);  /* Rx & Tx */
760         }
761
762         return mlxsw_reg_write(mlxsw_sp->core, MLXSW_REG(pmlp), pmlp_pl);
763 }
764
765 static int mlxsw_sp_port_module_unmap(struct mlxsw_sp_port *mlxsw_sp_port)
766 {
767         struct mlxsw_sp *mlxsw_sp = mlxsw_sp_port->mlxsw_sp;
768         char pmlp_pl[MLXSW_REG_PMLP_LEN];
769
770         mlxsw_reg_pmlp_pack(pmlp_pl, mlxsw_sp_port->local_port);
771         mlxsw_reg_pmlp_width_set(pmlp_pl, 0);
772         return mlxsw_reg_write(mlxsw_sp->core, MLXSW_REG(pmlp), pmlp_pl);
773 }
774
775 static int mlxsw_sp_port_open(struct net_device *dev)
776 {
777         struct mlxsw_sp_port *mlxsw_sp_port = netdev_priv(dev);
778         int err;
779
780         err = mlxsw_sp_port_admin_status_set(mlxsw_sp_port, true);
781         if (err)
782                 return err;
783         netif_start_queue(dev);
784         return 0;
785 }
786
787 static int mlxsw_sp_port_stop(struct net_device *dev)
788 {
789         struct mlxsw_sp_port *mlxsw_sp_port = netdev_priv(dev);
790
791         netif_stop_queue(dev);
792         return mlxsw_sp_port_admin_status_set(mlxsw_sp_port, false);
793 }
794
795 static netdev_tx_t mlxsw_sp_port_xmit(struct sk_buff *skb,
796                                       struct net_device *dev)
797 {
798         struct mlxsw_sp_port *mlxsw_sp_port = netdev_priv(dev);
799         struct mlxsw_sp *mlxsw_sp = mlxsw_sp_port->mlxsw_sp;
800         struct mlxsw_sp_port_pcpu_stats *pcpu_stats;
801         const struct mlxsw_tx_info tx_info = {
802                 .local_port = mlxsw_sp_port->local_port,
803                 .is_emad = false,
804         };
805         u64 len;
806         int err;
807
808         memset(skb->cb, 0, sizeof(struct mlxsw_skb_cb));
809
810         if (mlxsw_core_skb_transmit_busy(mlxsw_sp->core, &tx_info))
811                 return NETDEV_TX_BUSY;
812
813         if (unlikely(skb_headroom(skb) < MLXSW_TXHDR_LEN)) {
814                 struct sk_buff *skb_orig = skb;
815
816                 skb = skb_realloc_headroom(skb, MLXSW_TXHDR_LEN);
817                 if (!skb) {
818                         this_cpu_inc(mlxsw_sp_port->pcpu_stats->tx_dropped);
819                         dev_kfree_skb_any(skb_orig);
820                         return NETDEV_TX_OK;
821                 }
822                 dev_consume_skb_any(skb_orig);
823         }
824
825         if (eth_skb_pad(skb)) {
826                 this_cpu_inc(mlxsw_sp_port->pcpu_stats->tx_dropped);
827                 return NETDEV_TX_OK;
828         }
829
830         mlxsw_sp_txhdr_construct(skb, &tx_info);
831         /* TX header is consumed by HW on the way so we shouldn't count its
832          * bytes as being sent.
833          */
834         len = skb->len - MLXSW_TXHDR_LEN;
835
836         /* Due to a race we might fail here because of a full queue. In that
837          * unlikely case we simply drop the packet.
838          */
839         err = mlxsw_core_skb_transmit(mlxsw_sp->core, skb, &tx_info);
840
841         if (!err) {
842                 pcpu_stats = this_cpu_ptr(mlxsw_sp_port->pcpu_stats);
843                 u64_stats_update_begin(&pcpu_stats->syncp);
844                 pcpu_stats->tx_packets++;
845                 pcpu_stats->tx_bytes += len;
846                 u64_stats_update_end(&pcpu_stats->syncp);
847         } else {
848                 this_cpu_inc(mlxsw_sp_port->pcpu_stats->tx_dropped);
849                 dev_kfree_skb_any(skb);
850         }
851         return NETDEV_TX_OK;
852 }
853
854 static void mlxsw_sp_set_rx_mode(struct net_device *dev)
855 {
856 }
857
858 static int mlxsw_sp_port_set_mac_address(struct net_device *dev, void *p)
859 {
860         struct mlxsw_sp_port *mlxsw_sp_port = netdev_priv(dev);
861         struct sockaddr *addr = p;
862         int err;
863
864         if (!is_valid_ether_addr(addr->sa_data))
865                 return -EADDRNOTAVAIL;
866
867         err = mlxsw_sp_port_dev_addr_set(mlxsw_sp_port, addr->sa_data);
868         if (err)
869                 return err;
870         memcpy(dev->dev_addr, addr->sa_data, dev->addr_len);
871         return 0;
872 }
873
874 static u16 mlxsw_sp_pg_buf_threshold_get(const struct mlxsw_sp *mlxsw_sp,
875                                          int mtu)
876 {
877         return 2 * mlxsw_sp_bytes_cells(mlxsw_sp, mtu);
878 }
879
880 #define MLXSW_SP_CELL_FACTOR 2  /* 2 * cell_size / (IPG + cell_size + 1) */
881
882 static u16 mlxsw_sp_pfc_delay_get(const struct mlxsw_sp *mlxsw_sp, int mtu,
883                                   u16 delay)
884 {
885         delay = mlxsw_sp_bytes_cells(mlxsw_sp, DIV_ROUND_UP(delay,
886                                                             BITS_PER_BYTE));
887         return MLXSW_SP_CELL_FACTOR * delay + mlxsw_sp_bytes_cells(mlxsw_sp,
888                                                                    mtu);
889 }
890
891 /* Maximum delay buffer needed in case of PAUSE frames, in bytes.
892  * Assumes 100m cable and maximum MTU.
893  */
894 #define MLXSW_SP_PAUSE_DELAY 58752
895
896 static u16 mlxsw_sp_pg_buf_delay_get(const struct mlxsw_sp *mlxsw_sp, int mtu,
897                                      u16 delay, bool pfc, bool pause)
898 {
899         if (pfc)
900                 return mlxsw_sp_pfc_delay_get(mlxsw_sp, mtu, delay);
901         else if (pause)
902                 return mlxsw_sp_bytes_cells(mlxsw_sp, MLXSW_SP_PAUSE_DELAY);
903         else
904                 return 0;
905 }
906
907 static void mlxsw_sp_pg_buf_pack(char *pbmc_pl, int index, u16 size, u16 thres,
908                                  bool lossy)
909 {
910         if (lossy)
911                 mlxsw_reg_pbmc_lossy_buffer_pack(pbmc_pl, index, size);
912         else
913                 mlxsw_reg_pbmc_lossless_buffer_pack(pbmc_pl, index, size,
914                                                     thres);
915 }
916
917 int __mlxsw_sp_port_headroom_set(struct mlxsw_sp_port *mlxsw_sp_port, int mtu,
918                                  u8 *prio_tc, bool pause_en,
919                                  struct ieee_pfc *my_pfc)
920 {
921         struct mlxsw_sp *mlxsw_sp = mlxsw_sp_port->mlxsw_sp;
922         u8 pfc_en = !!my_pfc ? my_pfc->pfc_en : 0;
923         u16 delay = !!my_pfc ? my_pfc->delay : 0;
924         char pbmc_pl[MLXSW_REG_PBMC_LEN];
925         u32 taken_headroom_cells = 0;
926         u32 max_headroom_cells;
927         int i, j, err;
928
929         max_headroom_cells = mlxsw_sp_sb_max_headroom_cells(mlxsw_sp);
930
931         mlxsw_reg_pbmc_pack(pbmc_pl, mlxsw_sp_port->local_port, 0, 0);
932         err = mlxsw_reg_query(mlxsw_sp->core, MLXSW_REG(pbmc), pbmc_pl);
933         if (err)
934                 return err;
935
936         for (i = 0; i < IEEE_8021QAZ_MAX_TCS; i++) {
937                 bool configure = false;
938                 bool pfc = false;
939                 u16 thres_cells;
940                 u16 delay_cells;
941                 u16 total_cells;
942                 bool lossy;
943
944                 for (j = 0; j < IEEE_8021QAZ_MAX_TCS; j++) {
945                         if (prio_tc[j] == i) {
946                                 pfc = pfc_en & BIT(j);
947                                 configure = true;
948                                 break;
949                         }
950                 }
951
952                 if (!configure)
953                         continue;
954
955                 lossy = !(pfc || pause_en);
956                 thres_cells = mlxsw_sp_pg_buf_threshold_get(mlxsw_sp, mtu);
957                 delay_cells = mlxsw_sp_pg_buf_delay_get(mlxsw_sp, mtu, delay,
958                                                         pfc, pause_en);
959                 total_cells = thres_cells + delay_cells;
960
961                 taken_headroom_cells += total_cells;
962                 if (taken_headroom_cells > max_headroom_cells)
963                         return -ENOBUFS;
964
965                 mlxsw_sp_pg_buf_pack(pbmc_pl, i, total_cells,
966                                      thres_cells, lossy);
967         }
968
969         return mlxsw_reg_write(mlxsw_sp->core, MLXSW_REG(pbmc), pbmc_pl);
970 }
971
972 static int mlxsw_sp_port_headroom_set(struct mlxsw_sp_port *mlxsw_sp_port,
973                                       int mtu, bool pause_en)
974 {
975         u8 def_prio_tc[IEEE_8021QAZ_MAX_TCS] = {0};
976         bool dcb_en = !!mlxsw_sp_port->dcb.ets;
977         struct ieee_pfc *my_pfc;
978         u8 *prio_tc;
979
980         prio_tc = dcb_en ? mlxsw_sp_port->dcb.ets->prio_tc : def_prio_tc;
981         my_pfc = dcb_en ? mlxsw_sp_port->dcb.pfc : NULL;
982
983         return __mlxsw_sp_port_headroom_set(mlxsw_sp_port, mtu, prio_tc,
984                                             pause_en, my_pfc);
985 }
986
987 static int mlxsw_sp_port_change_mtu(struct net_device *dev, int mtu)
988 {
989         struct mlxsw_sp_port *mlxsw_sp_port = netdev_priv(dev);
990         bool pause_en = mlxsw_sp_port_is_pause_en(mlxsw_sp_port);
991         int err;
992
993         err = mlxsw_sp_port_headroom_set(mlxsw_sp_port, mtu, pause_en);
994         if (err)
995                 return err;
996         err = mlxsw_sp_span_port_mtu_update(mlxsw_sp_port, mtu);
997         if (err)
998                 goto err_span_port_mtu_update;
999         err = mlxsw_sp_port_mtu_set(mlxsw_sp_port, mtu);
1000         if (err)
1001                 goto err_port_mtu_set;
1002         dev->mtu = mtu;
1003         return 0;
1004
1005 err_port_mtu_set:
1006         mlxsw_sp_span_port_mtu_update(mlxsw_sp_port, dev->mtu);
1007 err_span_port_mtu_update:
1008         mlxsw_sp_port_headroom_set(mlxsw_sp_port, dev->mtu, pause_en);
1009         return err;
1010 }
1011
1012 static int
1013 mlxsw_sp_port_get_sw_stats64(const struct net_device *dev,
1014                              struct rtnl_link_stats64 *stats)
1015 {
1016         struct mlxsw_sp_port *mlxsw_sp_port = netdev_priv(dev);
1017         struct mlxsw_sp_port_pcpu_stats *p;
1018         u64 rx_packets, rx_bytes, tx_packets, tx_bytes;
1019         u32 tx_dropped = 0;
1020         unsigned int start;
1021         int i;
1022
1023         for_each_possible_cpu(i) {
1024                 p = per_cpu_ptr(mlxsw_sp_port->pcpu_stats, i);
1025                 do {
1026                         start = u64_stats_fetch_begin_irq(&p->syncp);
1027                         rx_packets      = p->rx_packets;
1028                         rx_bytes        = p->rx_bytes;
1029                         tx_packets      = p->tx_packets;
1030                         tx_bytes        = p->tx_bytes;
1031                 } while (u64_stats_fetch_retry_irq(&p->syncp, start));
1032
1033                 stats->rx_packets       += rx_packets;
1034                 stats->rx_bytes         += rx_bytes;
1035                 stats->tx_packets       += tx_packets;
1036                 stats->tx_bytes         += tx_bytes;
1037                 /* tx_dropped is u32, updated without syncp protection. */
1038                 tx_dropped      += p->tx_dropped;
1039         }
1040         stats->tx_dropped       = tx_dropped;
1041         return 0;
1042 }
1043
1044 static bool mlxsw_sp_port_has_offload_stats(const struct net_device *dev, int attr_id)
1045 {
1046         switch (attr_id) {
1047         case IFLA_OFFLOAD_XSTATS_CPU_HIT:
1048                 return true;
1049         }
1050
1051         return false;
1052 }
1053
1054 static int mlxsw_sp_port_get_offload_stats(int attr_id, const struct net_device *dev,
1055                                            void *sp)
1056 {
1057         switch (attr_id) {
1058         case IFLA_OFFLOAD_XSTATS_CPU_HIT:
1059                 return mlxsw_sp_port_get_sw_stats64(dev, sp);
1060         }
1061
1062         return -EINVAL;
1063 }
1064
1065 static int mlxsw_sp_port_get_stats_raw(struct net_device *dev, int grp,
1066                                        int prio, char *ppcnt_pl)
1067 {
1068         struct mlxsw_sp_port *mlxsw_sp_port = netdev_priv(dev);
1069         struct mlxsw_sp *mlxsw_sp = mlxsw_sp_port->mlxsw_sp;
1070
1071         mlxsw_reg_ppcnt_pack(ppcnt_pl, mlxsw_sp_port->local_port, grp, prio);
1072         return mlxsw_reg_query(mlxsw_sp->core, MLXSW_REG(ppcnt), ppcnt_pl);
1073 }
1074
1075 static int mlxsw_sp_port_get_hw_stats(struct net_device *dev,
1076                                       struct rtnl_link_stats64 *stats)
1077 {
1078         char ppcnt_pl[MLXSW_REG_PPCNT_LEN];
1079         int err;
1080
1081         err = mlxsw_sp_port_get_stats_raw(dev, MLXSW_REG_PPCNT_IEEE_8023_CNT,
1082                                           0, ppcnt_pl);
1083         if (err)
1084                 goto out;
1085
1086         stats->tx_packets =
1087                 mlxsw_reg_ppcnt_a_frames_transmitted_ok_get(ppcnt_pl);
1088         stats->rx_packets =
1089                 mlxsw_reg_ppcnt_a_frames_received_ok_get(ppcnt_pl);
1090         stats->tx_bytes =
1091                 mlxsw_reg_ppcnt_a_octets_transmitted_ok_get(ppcnt_pl);
1092         stats->rx_bytes =
1093                 mlxsw_reg_ppcnt_a_octets_received_ok_get(ppcnt_pl);
1094         stats->multicast =
1095                 mlxsw_reg_ppcnt_a_multicast_frames_received_ok_get(ppcnt_pl);
1096
1097         stats->rx_crc_errors =
1098                 mlxsw_reg_ppcnt_a_frame_check_sequence_errors_get(ppcnt_pl);
1099         stats->rx_frame_errors =
1100                 mlxsw_reg_ppcnt_a_alignment_errors_get(ppcnt_pl);
1101
1102         stats->rx_length_errors = (
1103                 mlxsw_reg_ppcnt_a_in_range_length_errors_get(ppcnt_pl) +
1104                 mlxsw_reg_ppcnt_a_out_of_range_length_field_get(ppcnt_pl) +
1105                 mlxsw_reg_ppcnt_a_frame_too_long_errors_get(ppcnt_pl));
1106
1107         stats->rx_errors = (stats->rx_crc_errors +
1108                 stats->rx_frame_errors + stats->rx_length_errors);
1109
1110 out:
1111         return err;
1112 }
1113
1114 static void
1115 mlxsw_sp_port_get_hw_xstats(struct net_device *dev,
1116                             struct mlxsw_sp_port_xstats *xstats)
1117 {
1118         char ppcnt_pl[MLXSW_REG_PPCNT_LEN];
1119         int err, i;
1120
1121         err = mlxsw_sp_port_get_stats_raw(dev, MLXSW_REG_PPCNT_EXT_CNT, 0,
1122                                           ppcnt_pl);
1123         if (!err)
1124                 xstats->ecn = mlxsw_reg_ppcnt_ecn_marked_get(ppcnt_pl);
1125
1126         for (i = 0; i < TC_MAX_QUEUE; i++) {
1127                 err = mlxsw_sp_port_get_stats_raw(dev,
1128                                                   MLXSW_REG_PPCNT_TC_CONG_TC,
1129                                                   i, ppcnt_pl);
1130                 if (!err)
1131                         xstats->wred_drop[i] =
1132                                 mlxsw_reg_ppcnt_wred_discard_get(ppcnt_pl);
1133
1134                 err = mlxsw_sp_port_get_stats_raw(dev, MLXSW_REG_PPCNT_TC_CNT,
1135                                                   i, ppcnt_pl);
1136                 if (err)
1137                         continue;
1138
1139                 xstats->backlog[i] =
1140                         mlxsw_reg_ppcnt_tc_transmit_queue_get(ppcnt_pl);
1141                 xstats->tail_drop[i] =
1142                         mlxsw_reg_ppcnt_tc_no_buffer_discard_uc_get(ppcnt_pl);
1143         }
1144
1145         for (i = 0; i < IEEE_8021QAZ_MAX_TCS; i++) {
1146                 err = mlxsw_sp_port_get_stats_raw(dev, MLXSW_REG_PPCNT_PRIO_CNT,
1147                                                   i, ppcnt_pl);
1148                 if (err)
1149                         continue;
1150
1151                 xstats->tx_packets[i] = mlxsw_reg_ppcnt_tx_frames_get(ppcnt_pl);
1152                 xstats->tx_bytes[i] = mlxsw_reg_ppcnt_tx_octets_get(ppcnt_pl);
1153         }
1154 }
1155
1156 static void update_stats_cache(struct work_struct *work)
1157 {
1158         struct mlxsw_sp_port *mlxsw_sp_port =
1159                 container_of(work, struct mlxsw_sp_port,
1160                              periodic_hw_stats.update_dw.work);
1161
1162         if (!netif_carrier_ok(mlxsw_sp_port->dev))
1163                 goto out;
1164
1165         mlxsw_sp_port_get_hw_stats(mlxsw_sp_port->dev,
1166                                    &mlxsw_sp_port->periodic_hw_stats.stats);
1167         mlxsw_sp_port_get_hw_xstats(mlxsw_sp_port->dev,
1168                                     &mlxsw_sp_port->periodic_hw_stats.xstats);
1169
1170 out:
1171         mlxsw_core_schedule_dw(&mlxsw_sp_port->periodic_hw_stats.update_dw,
1172                                MLXSW_HW_STATS_UPDATE_TIME);
1173 }
1174
1175 /* Return the stats from a cache that is updated periodically,
1176  * as this function might get called in an atomic context.
1177  */
1178 static void
1179 mlxsw_sp_port_get_stats64(struct net_device *dev,
1180                           struct rtnl_link_stats64 *stats)
1181 {
1182         struct mlxsw_sp_port *mlxsw_sp_port = netdev_priv(dev);
1183
1184         memcpy(stats, &mlxsw_sp_port->periodic_hw_stats.stats, sizeof(*stats));
1185 }
1186
1187 static int __mlxsw_sp_port_vlan_set(struct mlxsw_sp_port *mlxsw_sp_port,
1188                                     u16 vid_begin, u16 vid_end,
1189                                     bool is_member, bool untagged)
1190 {
1191         struct mlxsw_sp *mlxsw_sp = mlxsw_sp_port->mlxsw_sp;
1192         char *spvm_pl;
1193         int err;
1194
1195         spvm_pl = kmalloc(MLXSW_REG_SPVM_LEN, GFP_KERNEL);
1196         if (!spvm_pl)
1197                 return -ENOMEM;
1198
1199         mlxsw_reg_spvm_pack(spvm_pl, mlxsw_sp_port->local_port, vid_begin,
1200                             vid_end, is_member, untagged);
1201         err = mlxsw_reg_write(mlxsw_sp->core, MLXSW_REG(spvm), spvm_pl);
1202         kfree(spvm_pl);
1203         return err;
1204 }
1205
1206 int mlxsw_sp_port_vlan_set(struct mlxsw_sp_port *mlxsw_sp_port, u16 vid_begin,
1207                            u16 vid_end, bool is_member, bool untagged)
1208 {
1209         u16 vid, vid_e;
1210         int err;
1211
1212         for (vid = vid_begin; vid <= vid_end;
1213              vid += MLXSW_REG_SPVM_REC_MAX_COUNT) {
1214                 vid_e = min((u16) (vid + MLXSW_REG_SPVM_REC_MAX_COUNT - 1),
1215                             vid_end);
1216
1217                 err = __mlxsw_sp_port_vlan_set(mlxsw_sp_port, vid, vid_e,
1218                                                is_member, untagged);
1219                 if (err)
1220                         return err;
1221         }
1222
1223         return 0;
1224 }
1225
1226 static void mlxsw_sp_port_vlan_flush(struct mlxsw_sp_port *mlxsw_sp_port,
1227                                      bool flush_default)
1228 {
1229         struct mlxsw_sp_port_vlan *mlxsw_sp_port_vlan, *tmp;
1230
1231         list_for_each_entry_safe(mlxsw_sp_port_vlan, tmp,
1232                                  &mlxsw_sp_port->vlans_list, list) {
1233                 if (!flush_default &&
1234                     mlxsw_sp_port_vlan->vid == MLXSW_SP_DEFAULT_VID)
1235                         continue;
1236                 mlxsw_sp_port_vlan_destroy(mlxsw_sp_port_vlan);
1237         }
1238 }
1239
1240 static void
1241 mlxsw_sp_port_vlan_cleanup(struct mlxsw_sp_port_vlan *mlxsw_sp_port_vlan)
1242 {
1243         if (mlxsw_sp_port_vlan->bridge_port)
1244                 mlxsw_sp_port_vlan_bridge_leave(mlxsw_sp_port_vlan);
1245         else if (mlxsw_sp_port_vlan->fid)
1246                 mlxsw_sp_port_vlan_router_leave(mlxsw_sp_port_vlan);
1247 }
1248
1249 struct mlxsw_sp_port_vlan *
1250 mlxsw_sp_port_vlan_create(struct mlxsw_sp_port *mlxsw_sp_port, u16 vid)
1251 {
1252         struct mlxsw_sp_port_vlan *mlxsw_sp_port_vlan;
1253         bool untagged = vid == MLXSW_SP_DEFAULT_VID;
1254         int err;
1255
1256         mlxsw_sp_port_vlan = mlxsw_sp_port_vlan_find_by_vid(mlxsw_sp_port, vid);
1257         if (mlxsw_sp_port_vlan)
1258                 return ERR_PTR(-EEXIST);
1259
1260         err = mlxsw_sp_port_vlan_set(mlxsw_sp_port, vid, vid, true, untagged);
1261         if (err)
1262                 return ERR_PTR(err);
1263
1264         mlxsw_sp_port_vlan = kzalloc(sizeof(*mlxsw_sp_port_vlan), GFP_KERNEL);
1265         if (!mlxsw_sp_port_vlan) {
1266                 err = -ENOMEM;
1267                 goto err_port_vlan_alloc;
1268         }
1269
1270         mlxsw_sp_port_vlan->mlxsw_sp_port = mlxsw_sp_port;
1271         mlxsw_sp_port_vlan->vid = vid;
1272         list_add(&mlxsw_sp_port_vlan->list, &mlxsw_sp_port->vlans_list);
1273
1274         return mlxsw_sp_port_vlan;
1275
1276 err_port_vlan_alloc:
1277         mlxsw_sp_port_vlan_set(mlxsw_sp_port, vid, vid, false, false);
1278         return ERR_PTR(err);
1279 }
1280
1281 void mlxsw_sp_port_vlan_destroy(struct mlxsw_sp_port_vlan *mlxsw_sp_port_vlan)
1282 {
1283         struct mlxsw_sp_port *mlxsw_sp_port = mlxsw_sp_port_vlan->mlxsw_sp_port;
1284         u16 vid = mlxsw_sp_port_vlan->vid;
1285
1286         mlxsw_sp_port_vlan_cleanup(mlxsw_sp_port_vlan);
1287         list_del(&mlxsw_sp_port_vlan->list);
1288         kfree(mlxsw_sp_port_vlan);
1289         mlxsw_sp_port_vlan_set(mlxsw_sp_port, vid, vid, false, false);
1290 }
1291
1292 static int mlxsw_sp_port_add_vid(struct net_device *dev,
1293                                  __be16 __always_unused proto, u16 vid)
1294 {
1295         struct mlxsw_sp_port *mlxsw_sp_port = netdev_priv(dev);
1296
1297         /* VLAN 0 is added to HW filter when device goes up, but it is
1298          * reserved in our case, so simply return.
1299          */
1300         if (!vid)
1301                 return 0;
1302
1303         return PTR_ERR_OR_ZERO(mlxsw_sp_port_vlan_create(mlxsw_sp_port, vid));
1304 }
1305
1306 static int mlxsw_sp_port_kill_vid(struct net_device *dev,
1307                                   __be16 __always_unused proto, u16 vid)
1308 {
1309         struct mlxsw_sp_port *mlxsw_sp_port = netdev_priv(dev);
1310         struct mlxsw_sp_port_vlan *mlxsw_sp_port_vlan;
1311
1312         /* VLAN 0 is removed from HW filter when device goes down, but
1313          * it is reserved in our case, so simply return.
1314          */
1315         if (!vid)
1316                 return 0;
1317
1318         mlxsw_sp_port_vlan = mlxsw_sp_port_vlan_find_by_vid(mlxsw_sp_port, vid);
1319         if (!mlxsw_sp_port_vlan)
1320                 return 0;
1321         mlxsw_sp_port_vlan_destroy(mlxsw_sp_port_vlan);
1322
1323         return 0;
1324 }
1325
1326 static struct mlxsw_sp_port_mall_tc_entry *
1327 mlxsw_sp_port_mall_tc_entry_find(struct mlxsw_sp_port *port,
1328                                  unsigned long cookie) {
1329         struct mlxsw_sp_port_mall_tc_entry *mall_tc_entry;
1330
1331         list_for_each_entry(mall_tc_entry, &port->mall_tc_list, list)
1332                 if (mall_tc_entry->cookie == cookie)
1333                         return mall_tc_entry;
1334
1335         return NULL;
1336 }
1337
1338 static int
1339 mlxsw_sp_port_add_cls_matchall_mirror(struct mlxsw_sp_port *mlxsw_sp_port,
1340                                       struct mlxsw_sp_port_mall_mirror_tc_entry *mirror,
1341                                       const struct flow_action_entry *act,
1342                                       bool ingress)
1343 {
1344         enum mlxsw_sp_span_type span_type;
1345
1346         if (!act->dev) {
1347                 netdev_err(mlxsw_sp_port->dev, "Could not find requested device\n");
1348                 return -EINVAL;
1349         }
1350
1351         mirror->ingress = ingress;
1352         span_type = ingress ? MLXSW_SP_SPAN_INGRESS : MLXSW_SP_SPAN_EGRESS;
1353         return mlxsw_sp_span_mirror_add(mlxsw_sp_port, act->dev, span_type,
1354                                         true, &mirror->span_id);
1355 }
1356
1357 static void
1358 mlxsw_sp_port_del_cls_matchall_mirror(struct mlxsw_sp_port *mlxsw_sp_port,
1359                                       struct mlxsw_sp_port_mall_mirror_tc_entry *mirror)
1360 {
1361         enum mlxsw_sp_span_type span_type;
1362
1363         span_type = mirror->ingress ?
1364                         MLXSW_SP_SPAN_INGRESS : MLXSW_SP_SPAN_EGRESS;
1365         mlxsw_sp_span_mirror_del(mlxsw_sp_port, mirror->span_id,
1366                                  span_type, true);
1367 }
1368
1369 static int
1370 mlxsw_sp_port_add_cls_matchall_sample(struct mlxsw_sp_port *mlxsw_sp_port,
1371                                       struct tc_cls_matchall_offload *cls,
1372                                       const struct flow_action_entry *act,
1373                                       bool ingress)
1374 {
1375         int err;
1376
1377         if (!mlxsw_sp_port->sample)
1378                 return -EOPNOTSUPP;
1379         if (rtnl_dereference(mlxsw_sp_port->sample->psample_group)) {
1380                 netdev_err(mlxsw_sp_port->dev, "sample already active\n");
1381                 return -EEXIST;
1382         }
1383         if (act->sample.rate > MLXSW_REG_MPSC_RATE_MAX) {
1384                 netdev_err(mlxsw_sp_port->dev, "sample rate not supported\n");
1385                 return -EOPNOTSUPP;
1386         }
1387
1388         rcu_assign_pointer(mlxsw_sp_port->sample->psample_group,
1389                            act->sample.psample_group);
1390         mlxsw_sp_port->sample->truncate = act->sample.truncate;
1391         mlxsw_sp_port->sample->trunc_size = act->sample.trunc_size;
1392         mlxsw_sp_port->sample->rate = act->sample.rate;
1393
1394         err = mlxsw_sp_port_sample_set(mlxsw_sp_port, true, act->sample.rate);
1395         if (err)
1396                 goto err_port_sample_set;
1397         return 0;
1398
1399 err_port_sample_set:
1400         RCU_INIT_POINTER(mlxsw_sp_port->sample->psample_group, NULL);
1401         return err;
1402 }
1403
1404 static void
1405 mlxsw_sp_port_del_cls_matchall_sample(struct mlxsw_sp_port *mlxsw_sp_port)
1406 {
1407         if (!mlxsw_sp_port->sample)
1408                 return;
1409
1410         mlxsw_sp_port_sample_set(mlxsw_sp_port, false, 1);
1411         RCU_INIT_POINTER(mlxsw_sp_port->sample->psample_group, NULL);
1412 }
1413
1414 static int mlxsw_sp_port_add_cls_matchall(struct mlxsw_sp_port *mlxsw_sp_port,
1415                                           struct tc_cls_matchall_offload *f,
1416                                           bool ingress)
1417 {
1418         struct mlxsw_sp_port_mall_tc_entry *mall_tc_entry;
1419         __be16 protocol = f->common.protocol;
1420         struct flow_action_entry *act;
1421         int err;
1422
1423         if (!flow_offload_has_one_action(&f->rule->action)) {
1424                 netdev_err(mlxsw_sp_port->dev, "only singular actions are supported\n");
1425                 return -EOPNOTSUPP;
1426         }
1427
1428         mall_tc_entry = kzalloc(sizeof(*mall_tc_entry), GFP_KERNEL);
1429         if (!mall_tc_entry)
1430                 return -ENOMEM;
1431         mall_tc_entry->cookie = f->cookie;
1432
1433         act = &f->rule->action.entries[0];
1434
1435         if (act->id == FLOW_ACTION_MIRRED && protocol == htons(ETH_P_ALL)) {
1436                 struct mlxsw_sp_port_mall_mirror_tc_entry *mirror;
1437
1438                 mall_tc_entry->type = MLXSW_SP_PORT_MALL_MIRROR;
1439                 mirror = &mall_tc_entry->mirror;
1440                 err = mlxsw_sp_port_add_cls_matchall_mirror(mlxsw_sp_port,
1441                                                             mirror, act,
1442                                                             ingress);
1443         } else if (act->id == FLOW_ACTION_SAMPLE &&
1444                    protocol == htons(ETH_P_ALL)) {
1445                 mall_tc_entry->type = MLXSW_SP_PORT_MALL_SAMPLE;
1446                 err = mlxsw_sp_port_add_cls_matchall_sample(mlxsw_sp_port, f,
1447                                                             act, ingress);
1448         } else {
1449                 err = -EOPNOTSUPP;
1450         }
1451
1452         if (err)
1453                 goto err_add_action;
1454
1455         list_add_tail(&mall_tc_entry->list, &mlxsw_sp_port->mall_tc_list);
1456         return 0;
1457
1458 err_add_action:
1459         kfree(mall_tc_entry);
1460         return err;
1461 }
1462
1463 static void mlxsw_sp_port_del_cls_matchall(struct mlxsw_sp_port *mlxsw_sp_port,
1464                                            struct tc_cls_matchall_offload *f)
1465 {
1466         struct mlxsw_sp_port_mall_tc_entry *mall_tc_entry;
1467
1468         mall_tc_entry = mlxsw_sp_port_mall_tc_entry_find(mlxsw_sp_port,
1469                                                          f->cookie);
1470         if (!mall_tc_entry) {
1471                 netdev_dbg(mlxsw_sp_port->dev, "tc entry not found on port\n");
1472                 return;
1473         }
1474         list_del(&mall_tc_entry->list);
1475
1476         switch (mall_tc_entry->type) {
1477         case MLXSW_SP_PORT_MALL_MIRROR:
1478                 mlxsw_sp_port_del_cls_matchall_mirror(mlxsw_sp_port,
1479                                                       &mall_tc_entry->mirror);
1480                 break;
1481         case MLXSW_SP_PORT_MALL_SAMPLE:
1482                 mlxsw_sp_port_del_cls_matchall_sample(mlxsw_sp_port);
1483                 break;
1484         default:
1485                 WARN_ON(1);
1486         }
1487
1488         kfree(mall_tc_entry);
1489 }
1490
1491 static int mlxsw_sp_setup_tc_cls_matchall(struct mlxsw_sp_port *mlxsw_sp_port,
1492                                           struct tc_cls_matchall_offload *f,
1493                                           bool ingress)
1494 {
1495         switch (f->command) {
1496         case TC_CLSMATCHALL_REPLACE:
1497                 return mlxsw_sp_port_add_cls_matchall(mlxsw_sp_port, f,
1498                                                       ingress);
1499         case TC_CLSMATCHALL_DESTROY:
1500                 mlxsw_sp_port_del_cls_matchall(mlxsw_sp_port, f);
1501                 return 0;
1502         default:
1503                 return -EOPNOTSUPP;
1504         }
1505 }
1506
1507 static int
1508 mlxsw_sp_setup_tc_cls_flower(struct mlxsw_sp_acl_block *acl_block,
1509                              struct flow_cls_offload *f)
1510 {
1511         struct mlxsw_sp *mlxsw_sp = mlxsw_sp_acl_block_mlxsw_sp(acl_block);
1512
1513         switch (f->command) {
1514         case FLOW_CLS_REPLACE:
1515                 return mlxsw_sp_flower_replace(mlxsw_sp, acl_block, f);
1516         case FLOW_CLS_DESTROY:
1517                 mlxsw_sp_flower_destroy(mlxsw_sp, acl_block, f);
1518                 return 0;
1519         case FLOW_CLS_STATS:
1520                 return mlxsw_sp_flower_stats(mlxsw_sp, acl_block, f);
1521         case FLOW_CLS_TMPLT_CREATE:
1522                 return mlxsw_sp_flower_tmplt_create(mlxsw_sp, acl_block, f);
1523         case FLOW_CLS_TMPLT_DESTROY:
1524                 mlxsw_sp_flower_tmplt_destroy(mlxsw_sp, acl_block, f);
1525                 return 0;
1526         default:
1527                 return -EOPNOTSUPP;
1528         }
1529 }
1530
1531 static int mlxsw_sp_setup_tc_block_cb_matchall(enum tc_setup_type type,
1532                                                void *type_data,
1533                                                void *cb_priv, bool ingress)
1534 {
1535         struct mlxsw_sp_port *mlxsw_sp_port = cb_priv;
1536
1537         switch (type) {
1538         case TC_SETUP_CLSMATCHALL:
1539                 if (!tc_cls_can_offload_and_chain0(mlxsw_sp_port->dev,
1540                                                    type_data))
1541                         return -EOPNOTSUPP;
1542
1543                 return mlxsw_sp_setup_tc_cls_matchall(mlxsw_sp_port, type_data,
1544                                                       ingress);
1545         case TC_SETUP_CLSFLOWER:
1546                 return 0;
1547         default:
1548                 return -EOPNOTSUPP;
1549         }
1550 }
1551
1552 static int mlxsw_sp_setup_tc_block_cb_matchall_ig(enum tc_setup_type type,
1553                                                   void *type_data,
1554                                                   void *cb_priv)
1555 {
1556         return mlxsw_sp_setup_tc_block_cb_matchall(type, type_data,
1557                                                    cb_priv, true);
1558 }
1559
1560 static int mlxsw_sp_setup_tc_block_cb_matchall_eg(enum tc_setup_type type,
1561                                                   void *type_data,
1562                                                   void *cb_priv)
1563 {
1564         return mlxsw_sp_setup_tc_block_cb_matchall(type, type_data,
1565                                                    cb_priv, false);
1566 }
1567
1568 static int mlxsw_sp_setup_tc_block_cb_flower(enum tc_setup_type type,
1569                                              void *type_data, void *cb_priv)
1570 {
1571         struct mlxsw_sp_acl_block *acl_block = cb_priv;
1572
1573         switch (type) {
1574         case TC_SETUP_CLSMATCHALL:
1575                 return 0;
1576         case TC_SETUP_CLSFLOWER:
1577                 if (mlxsw_sp_acl_block_disabled(acl_block))
1578                         return -EOPNOTSUPP;
1579
1580                 return mlxsw_sp_setup_tc_cls_flower(acl_block, type_data);
1581         default:
1582                 return -EOPNOTSUPP;
1583         }
1584 }
1585
1586 static void mlxsw_sp_tc_block_flower_release(void *cb_priv)
1587 {
1588         struct mlxsw_sp_acl_block *acl_block = cb_priv;
1589
1590         mlxsw_sp_acl_block_destroy(acl_block);
1591 }
1592
1593 static LIST_HEAD(mlxsw_sp_block_cb_list);
1594
1595 static int
1596 mlxsw_sp_setup_tc_block_flower_bind(struct mlxsw_sp_port *mlxsw_sp_port,
1597                                     struct flow_block_offload *f, bool ingress)
1598 {
1599         struct mlxsw_sp *mlxsw_sp = mlxsw_sp_port->mlxsw_sp;
1600         struct mlxsw_sp_acl_block *acl_block;
1601         struct flow_block_cb *block_cb;
1602         bool register_block = false;
1603         int err;
1604
1605         block_cb = flow_block_cb_lookup(f->block,
1606                                         mlxsw_sp_setup_tc_block_cb_flower,
1607                                         mlxsw_sp);
1608         if (!block_cb) {
1609                 acl_block = mlxsw_sp_acl_block_create(mlxsw_sp, f->net);
1610                 if (!acl_block)
1611                         return -ENOMEM;
1612                 block_cb = flow_block_cb_alloc(mlxsw_sp_setup_tc_block_cb_flower,
1613                                                mlxsw_sp, acl_block,
1614                                                mlxsw_sp_tc_block_flower_release);
1615                 if (IS_ERR(block_cb)) {
1616                         mlxsw_sp_acl_block_destroy(acl_block);
1617                         err = PTR_ERR(block_cb);
1618                         goto err_cb_register;
1619                 }
1620                 register_block = true;
1621         } else {
1622                 acl_block = flow_block_cb_priv(block_cb);
1623         }
1624         flow_block_cb_incref(block_cb);
1625         err = mlxsw_sp_acl_block_bind(mlxsw_sp, acl_block,
1626                                       mlxsw_sp_port, ingress);
1627         if (err)
1628                 goto err_block_bind;
1629
1630         if (ingress)
1631                 mlxsw_sp_port->ing_acl_block = acl_block;
1632         else
1633                 mlxsw_sp_port->eg_acl_block = acl_block;
1634
1635         if (register_block) {
1636                 flow_block_cb_add(block_cb, f);
1637                 list_add_tail(&block_cb->driver_list, &mlxsw_sp_block_cb_list);
1638         }
1639
1640         return 0;
1641
1642 err_block_bind:
1643         if (!flow_block_cb_decref(block_cb))
1644                 flow_block_cb_free(block_cb);
1645 err_cb_register:
1646         return err;
1647 }
1648
1649 static void
1650 mlxsw_sp_setup_tc_block_flower_unbind(struct mlxsw_sp_port *mlxsw_sp_port,
1651                                       struct flow_block_offload *f, bool ingress)
1652 {
1653         struct mlxsw_sp *mlxsw_sp = mlxsw_sp_port->mlxsw_sp;
1654         struct mlxsw_sp_acl_block *acl_block;
1655         struct flow_block_cb *block_cb;
1656         int err;
1657
1658         block_cb = flow_block_cb_lookup(f->block,
1659                                         mlxsw_sp_setup_tc_block_cb_flower,
1660                                         mlxsw_sp);
1661         if (!block_cb)
1662                 return;
1663
1664         if (ingress)
1665                 mlxsw_sp_port->ing_acl_block = NULL;
1666         else
1667                 mlxsw_sp_port->eg_acl_block = NULL;
1668
1669         acl_block = flow_block_cb_priv(block_cb);
1670         err = mlxsw_sp_acl_block_unbind(mlxsw_sp, acl_block,
1671                                         mlxsw_sp_port, ingress);
1672         if (!err && !flow_block_cb_decref(block_cb)) {
1673                 flow_block_cb_remove(block_cb, f);
1674                 list_del(&block_cb->driver_list);
1675         }
1676 }
1677
1678 static int mlxsw_sp_setup_tc_block(struct mlxsw_sp_port *mlxsw_sp_port,
1679                                    struct flow_block_offload *f)
1680 {
1681         struct flow_block_cb *block_cb;
1682         flow_setup_cb_t *cb;
1683         bool ingress;
1684         int err;
1685
1686         if (f->binder_type == FLOW_BLOCK_BINDER_TYPE_CLSACT_INGRESS) {
1687                 cb = mlxsw_sp_setup_tc_block_cb_matchall_ig;
1688                 ingress = true;
1689         } else if (f->binder_type == FLOW_BLOCK_BINDER_TYPE_CLSACT_EGRESS) {
1690                 cb = mlxsw_sp_setup_tc_block_cb_matchall_eg;
1691                 ingress = false;
1692         } else {
1693                 return -EOPNOTSUPP;
1694         }
1695
1696         f->driver_block_list = &mlxsw_sp_block_cb_list;
1697
1698         switch (f->command) {
1699         case FLOW_BLOCK_BIND:
1700                 if (flow_block_cb_is_busy(cb, mlxsw_sp_port,
1701                                           &mlxsw_sp_block_cb_list))
1702                         return -EBUSY;
1703
1704                 block_cb = flow_block_cb_alloc(cb, mlxsw_sp_port,
1705                                                mlxsw_sp_port, NULL);
1706                 if (IS_ERR(block_cb))
1707                         return PTR_ERR(block_cb);
1708                 err = mlxsw_sp_setup_tc_block_flower_bind(mlxsw_sp_port, f,
1709                                                           ingress);
1710                 if (err) {
1711                         flow_block_cb_free(block_cb);
1712                         return err;
1713                 }
1714                 flow_block_cb_add(block_cb, f);
1715                 list_add_tail(&block_cb->driver_list, &mlxsw_sp_block_cb_list);
1716                 return 0;
1717         case FLOW_BLOCK_UNBIND:
1718                 mlxsw_sp_setup_tc_block_flower_unbind(mlxsw_sp_port,
1719                                                       f, ingress);
1720                 block_cb = flow_block_cb_lookup(f->block, cb, mlxsw_sp_port);
1721                 if (!block_cb)
1722                         return -ENOENT;
1723
1724                 flow_block_cb_remove(block_cb, f);
1725                 list_del(&block_cb->driver_list);
1726                 return 0;
1727         default:
1728                 return -EOPNOTSUPP;
1729         }
1730 }
1731
1732 static int mlxsw_sp_setup_tc(struct net_device *dev, enum tc_setup_type type,
1733                              void *type_data)
1734 {
1735         struct mlxsw_sp_port *mlxsw_sp_port = netdev_priv(dev);
1736
1737         switch (type) {
1738         case TC_SETUP_BLOCK:
1739                 return mlxsw_sp_setup_tc_block(mlxsw_sp_port, type_data);
1740         case TC_SETUP_QDISC_RED:
1741                 return mlxsw_sp_setup_tc_red(mlxsw_sp_port, type_data);
1742         case TC_SETUP_QDISC_PRIO:
1743                 return mlxsw_sp_setup_tc_prio(mlxsw_sp_port, type_data);
1744         default:
1745                 return -EOPNOTSUPP;
1746         }
1747 }
1748
1749
1750 static int mlxsw_sp_feature_hw_tc(struct net_device *dev, bool enable)
1751 {
1752         struct mlxsw_sp_port *mlxsw_sp_port = netdev_priv(dev);
1753
1754         if (!enable) {
1755                 if (mlxsw_sp_acl_block_rule_count(mlxsw_sp_port->ing_acl_block) ||
1756                     mlxsw_sp_acl_block_rule_count(mlxsw_sp_port->eg_acl_block) ||
1757                     !list_empty(&mlxsw_sp_port->mall_tc_list)) {
1758                         netdev_err(dev, "Active offloaded tc filters, can't turn hw_tc_offload off\n");
1759                         return -EINVAL;
1760                 }
1761                 mlxsw_sp_acl_block_disable_inc(mlxsw_sp_port->ing_acl_block);
1762                 mlxsw_sp_acl_block_disable_inc(mlxsw_sp_port->eg_acl_block);
1763         } else {
1764                 mlxsw_sp_acl_block_disable_dec(mlxsw_sp_port->ing_acl_block);
1765                 mlxsw_sp_acl_block_disable_dec(mlxsw_sp_port->eg_acl_block);
1766         }
1767         return 0;
1768 }
1769
1770 static int mlxsw_sp_feature_loopback(struct net_device *dev, bool enable)
1771 {
1772         struct mlxsw_sp_port *mlxsw_sp_port = netdev_priv(dev);
1773         char pplr_pl[MLXSW_REG_PPLR_LEN];
1774         int err;
1775
1776         if (netif_running(dev))
1777                 mlxsw_sp_port_admin_status_set(mlxsw_sp_port, false);
1778
1779         mlxsw_reg_pplr_pack(pplr_pl, mlxsw_sp_port->local_port, enable);
1780         err = mlxsw_reg_write(mlxsw_sp_port->mlxsw_sp->core, MLXSW_REG(pplr),
1781                               pplr_pl);
1782
1783         if (netif_running(dev))
1784                 mlxsw_sp_port_admin_status_set(mlxsw_sp_port, true);
1785
1786         return err;
1787 }
1788
1789 typedef int (*mlxsw_sp_feature_handler)(struct net_device *dev, bool enable);
1790
1791 static int mlxsw_sp_handle_feature(struct net_device *dev,
1792                                    netdev_features_t wanted_features,
1793                                    netdev_features_t feature,
1794                                    mlxsw_sp_feature_handler feature_handler)
1795 {
1796         netdev_features_t changes = wanted_features ^ dev->features;
1797         bool enable = !!(wanted_features & feature);
1798         int err;
1799
1800         if (!(changes & feature))
1801                 return 0;
1802
1803         err = feature_handler(dev, enable);
1804         if (err) {
1805                 netdev_err(dev, "%s feature %pNF failed, err %d\n",
1806                            enable ? "Enable" : "Disable", &feature, err);
1807                 return err;
1808         }
1809
1810         if (enable)
1811                 dev->features |= feature;
1812         else
1813                 dev->features &= ~feature;
1814
1815         return 0;
1816 }
1817 static int mlxsw_sp_set_features(struct net_device *dev,
1818                                  netdev_features_t features)
1819 {
1820         netdev_features_t oper_features = dev->features;
1821         int err = 0;
1822
1823         err |= mlxsw_sp_handle_feature(dev, features, NETIF_F_HW_TC,
1824                                        mlxsw_sp_feature_hw_tc);
1825         err |= mlxsw_sp_handle_feature(dev, features, NETIF_F_LOOPBACK,
1826                                        mlxsw_sp_feature_loopback);
1827
1828         if (err) {
1829                 dev->features = oper_features;
1830                 return -EINVAL;
1831         }
1832
1833         return 0;
1834 }
1835
1836 static struct devlink_port *
1837 mlxsw_sp_port_get_devlink_port(struct net_device *dev)
1838 {
1839         struct mlxsw_sp_port *mlxsw_sp_port = netdev_priv(dev);
1840         struct mlxsw_sp *mlxsw_sp = mlxsw_sp_port->mlxsw_sp;
1841
1842         return mlxsw_core_port_devlink_port_get(mlxsw_sp->core,
1843                                                 mlxsw_sp_port->local_port);
1844 }
1845
1846 static int mlxsw_sp_port_hwtstamp_set(struct mlxsw_sp_port *mlxsw_sp_port,
1847                                       struct ifreq *ifr)
1848 {
1849         struct hwtstamp_config config;
1850         int err;
1851
1852         if (copy_from_user(&config, ifr->ifr_data, sizeof(config)))
1853                 return -EFAULT;
1854
1855         err = mlxsw_sp_port->mlxsw_sp->ptp_ops->hwtstamp_set(mlxsw_sp_port,
1856                                                              &config);
1857         if (err)
1858                 return err;
1859
1860         if (copy_to_user(ifr->ifr_data, &config, sizeof(config)))
1861                 return -EFAULT;
1862
1863         return 0;
1864 }
1865
1866 static int mlxsw_sp_port_hwtstamp_get(struct mlxsw_sp_port *mlxsw_sp_port,
1867                                       struct ifreq *ifr)
1868 {
1869         struct hwtstamp_config config;
1870         int err;
1871
1872         err = mlxsw_sp_port->mlxsw_sp->ptp_ops->hwtstamp_get(mlxsw_sp_port,
1873                                                              &config);
1874         if (err)
1875                 return err;
1876
1877         if (copy_to_user(ifr->ifr_data, &config, sizeof(config)))
1878                 return -EFAULT;
1879
1880         return 0;
1881 }
1882
1883 static inline void mlxsw_sp_port_ptp_clear(struct mlxsw_sp_port *mlxsw_sp_port)
1884 {
1885         struct hwtstamp_config config = {0};
1886
1887         mlxsw_sp_port->mlxsw_sp->ptp_ops->hwtstamp_set(mlxsw_sp_port, &config);
1888 }
1889
1890 static int
1891 mlxsw_sp_port_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
1892 {
1893         struct mlxsw_sp_port *mlxsw_sp_port = netdev_priv(dev);
1894
1895         switch (cmd) {
1896         case SIOCSHWTSTAMP:
1897                 return mlxsw_sp_port_hwtstamp_set(mlxsw_sp_port, ifr);
1898         case SIOCGHWTSTAMP:
1899                 return mlxsw_sp_port_hwtstamp_get(mlxsw_sp_port, ifr);
1900         default:
1901                 return -EOPNOTSUPP;
1902         }
1903 }
1904
1905 static const struct net_device_ops mlxsw_sp_port_netdev_ops = {
1906         .ndo_open               = mlxsw_sp_port_open,
1907         .ndo_stop               = mlxsw_sp_port_stop,
1908         .ndo_start_xmit         = mlxsw_sp_port_xmit,
1909         .ndo_setup_tc           = mlxsw_sp_setup_tc,
1910         .ndo_set_rx_mode        = mlxsw_sp_set_rx_mode,
1911         .ndo_set_mac_address    = mlxsw_sp_port_set_mac_address,
1912         .ndo_change_mtu         = mlxsw_sp_port_change_mtu,
1913         .ndo_get_stats64        = mlxsw_sp_port_get_stats64,
1914         .ndo_has_offload_stats  = mlxsw_sp_port_has_offload_stats,
1915         .ndo_get_offload_stats  = mlxsw_sp_port_get_offload_stats,
1916         .ndo_vlan_rx_add_vid    = mlxsw_sp_port_add_vid,
1917         .ndo_vlan_rx_kill_vid   = mlxsw_sp_port_kill_vid,
1918         .ndo_set_features       = mlxsw_sp_set_features,
1919         .ndo_get_devlink_port   = mlxsw_sp_port_get_devlink_port,
1920         .ndo_do_ioctl           = mlxsw_sp_port_ioctl,
1921 };
1922
1923 static void mlxsw_sp_port_get_drvinfo(struct net_device *dev,
1924                                       struct ethtool_drvinfo *drvinfo)
1925 {
1926         struct mlxsw_sp_port *mlxsw_sp_port = netdev_priv(dev);
1927         struct mlxsw_sp *mlxsw_sp = mlxsw_sp_port->mlxsw_sp;
1928
1929         strlcpy(drvinfo->driver, mlxsw_sp->bus_info->device_kind,
1930                 sizeof(drvinfo->driver));
1931         strlcpy(drvinfo->version, mlxsw_sp_driver_version,
1932                 sizeof(drvinfo->version));
1933         snprintf(drvinfo->fw_version, sizeof(drvinfo->fw_version),
1934                  "%d.%d.%d",
1935                  mlxsw_sp->bus_info->fw_rev.major,
1936                  mlxsw_sp->bus_info->fw_rev.minor,
1937                  mlxsw_sp->bus_info->fw_rev.subminor);
1938         strlcpy(drvinfo->bus_info, mlxsw_sp->bus_info->device_name,
1939                 sizeof(drvinfo->bus_info));
1940 }
1941
1942 static void mlxsw_sp_port_get_pauseparam(struct net_device *dev,
1943                                          struct ethtool_pauseparam *pause)
1944 {
1945         struct mlxsw_sp_port *mlxsw_sp_port = netdev_priv(dev);
1946
1947         pause->rx_pause = mlxsw_sp_port->link.rx_pause;
1948         pause->tx_pause = mlxsw_sp_port->link.tx_pause;
1949 }
1950
1951 static int mlxsw_sp_port_pause_set(struct mlxsw_sp_port *mlxsw_sp_port,
1952                                    struct ethtool_pauseparam *pause)
1953 {
1954         char pfcc_pl[MLXSW_REG_PFCC_LEN];
1955
1956         mlxsw_reg_pfcc_pack(pfcc_pl, mlxsw_sp_port->local_port);
1957         mlxsw_reg_pfcc_pprx_set(pfcc_pl, pause->rx_pause);
1958         mlxsw_reg_pfcc_pptx_set(pfcc_pl, pause->tx_pause);
1959
1960         return mlxsw_reg_write(mlxsw_sp_port->mlxsw_sp->core, MLXSW_REG(pfcc),
1961                                pfcc_pl);
1962 }
1963
1964 static int mlxsw_sp_port_set_pauseparam(struct net_device *dev,
1965                                         struct ethtool_pauseparam *pause)
1966 {
1967         struct mlxsw_sp_port *mlxsw_sp_port = netdev_priv(dev);
1968         bool pause_en = pause->tx_pause || pause->rx_pause;
1969         int err;
1970
1971         if (mlxsw_sp_port->dcb.pfc && mlxsw_sp_port->dcb.pfc->pfc_en) {
1972                 netdev_err(dev, "PFC already enabled on port\n");
1973                 return -EINVAL;
1974         }
1975
1976         if (pause->autoneg) {
1977                 netdev_err(dev, "PAUSE frames autonegotiation isn't supported\n");
1978                 return -EINVAL;
1979         }
1980
1981         err = mlxsw_sp_port_headroom_set(mlxsw_sp_port, dev->mtu, pause_en);
1982         if (err) {
1983                 netdev_err(dev, "Failed to configure port's headroom\n");
1984                 return err;
1985         }
1986
1987         err = mlxsw_sp_port_pause_set(mlxsw_sp_port, pause);
1988         if (err) {
1989                 netdev_err(dev, "Failed to set PAUSE parameters\n");
1990                 goto err_port_pause_configure;
1991         }
1992
1993         mlxsw_sp_port->link.rx_pause = pause->rx_pause;
1994         mlxsw_sp_port->link.tx_pause = pause->tx_pause;
1995
1996         return 0;
1997
1998 err_port_pause_configure:
1999         pause_en = mlxsw_sp_port_is_pause_en(mlxsw_sp_port);
2000         mlxsw_sp_port_headroom_set(mlxsw_sp_port, dev->mtu, pause_en);
2001         return err;
2002 }
2003
2004 struct mlxsw_sp_port_hw_stats {
2005         char str[ETH_GSTRING_LEN];
2006         u64 (*getter)(const char *payload);
2007         bool cells_bytes;
2008 };
2009
2010 static struct mlxsw_sp_port_hw_stats mlxsw_sp_port_hw_stats[] = {
2011         {
2012                 .str = "a_frames_transmitted_ok",
2013                 .getter = mlxsw_reg_ppcnt_a_frames_transmitted_ok_get,
2014         },
2015         {
2016                 .str = "a_frames_received_ok",
2017                 .getter = mlxsw_reg_ppcnt_a_frames_received_ok_get,
2018         },
2019         {
2020                 .str = "a_frame_check_sequence_errors",
2021                 .getter = mlxsw_reg_ppcnt_a_frame_check_sequence_errors_get,
2022         },
2023         {
2024                 .str = "a_alignment_errors",
2025                 .getter = mlxsw_reg_ppcnt_a_alignment_errors_get,
2026         },
2027         {
2028                 .str = "a_octets_transmitted_ok",
2029                 .getter = mlxsw_reg_ppcnt_a_octets_transmitted_ok_get,
2030         },
2031         {
2032                 .str = "a_octets_received_ok",
2033                 .getter = mlxsw_reg_ppcnt_a_octets_received_ok_get,
2034         },
2035         {
2036                 .str = "a_multicast_frames_xmitted_ok",
2037                 .getter = mlxsw_reg_ppcnt_a_multicast_frames_xmitted_ok_get,
2038         },
2039         {
2040                 .str = "a_broadcast_frames_xmitted_ok",
2041                 .getter = mlxsw_reg_ppcnt_a_broadcast_frames_xmitted_ok_get,
2042         },
2043         {
2044                 .str = "a_multicast_frames_received_ok",
2045                 .getter = mlxsw_reg_ppcnt_a_multicast_frames_received_ok_get,
2046         },
2047         {
2048                 .str = "a_broadcast_frames_received_ok",
2049                 .getter = mlxsw_reg_ppcnt_a_broadcast_frames_received_ok_get,
2050         },
2051         {
2052                 .str = "a_in_range_length_errors",
2053                 .getter = mlxsw_reg_ppcnt_a_in_range_length_errors_get,
2054         },
2055         {
2056                 .str = "a_out_of_range_length_field",
2057                 .getter = mlxsw_reg_ppcnt_a_out_of_range_length_field_get,
2058         },
2059         {
2060                 .str = "a_frame_too_long_errors",
2061                 .getter = mlxsw_reg_ppcnt_a_frame_too_long_errors_get,
2062         },
2063         {
2064                 .str = "a_symbol_error_during_carrier",
2065                 .getter = mlxsw_reg_ppcnt_a_symbol_error_during_carrier_get,
2066         },
2067         {
2068                 .str = "a_mac_control_frames_transmitted",
2069                 .getter = mlxsw_reg_ppcnt_a_mac_control_frames_transmitted_get,
2070         },
2071         {
2072                 .str = "a_mac_control_frames_received",
2073                 .getter = mlxsw_reg_ppcnt_a_mac_control_frames_received_get,
2074         },
2075         {
2076                 .str = "a_unsupported_opcodes_received",
2077                 .getter = mlxsw_reg_ppcnt_a_unsupported_opcodes_received_get,
2078         },
2079         {
2080                 .str = "a_pause_mac_ctrl_frames_received",
2081                 .getter = mlxsw_reg_ppcnt_a_pause_mac_ctrl_frames_received_get,
2082         },
2083         {
2084                 .str = "a_pause_mac_ctrl_frames_xmitted",
2085                 .getter = mlxsw_reg_ppcnt_a_pause_mac_ctrl_frames_transmitted_get,
2086         },
2087 };
2088
2089 #define MLXSW_SP_PORT_HW_STATS_LEN ARRAY_SIZE(mlxsw_sp_port_hw_stats)
2090
2091 static struct mlxsw_sp_port_hw_stats mlxsw_sp_port_hw_rfc_2863_stats[] = {
2092         {
2093                 .str = "if_in_discards",
2094                 .getter = mlxsw_reg_ppcnt_if_in_discards_get,
2095         },
2096         {
2097                 .str = "if_out_discards",
2098                 .getter = mlxsw_reg_ppcnt_if_out_discards_get,
2099         },
2100         {
2101                 .str = "if_out_errors",
2102                 .getter = mlxsw_reg_ppcnt_if_out_errors_get,
2103         },
2104 };
2105
2106 #define MLXSW_SP_PORT_HW_RFC_2863_STATS_LEN \
2107         ARRAY_SIZE(mlxsw_sp_port_hw_rfc_2863_stats)
2108
2109 static struct mlxsw_sp_port_hw_stats mlxsw_sp_port_hw_rfc_2819_stats[] = {
2110         {
2111                 .str = "ether_stats_undersize_pkts",
2112                 .getter = mlxsw_reg_ppcnt_ether_stats_undersize_pkts_get,
2113         },
2114         {
2115                 .str = "ether_stats_oversize_pkts",
2116                 .getter = mlxsw_reg_ppcnt_ether_stats_oversize_pkts_get,
2117         },
2118         {
2119                 .str = "ether_stats_fragments",
2120                 .getter = mlxsw_reg_ppcnt_ether_stats_fragments_get,
2121         },
2122         {
2123                 .str = "ether_pkts64octets",
2124                 .getter = mlxsw_reg_ppcnt_ether_stats_pkts64octets_get,
2125         },
2126         {
2127                 .str = "ether_pkts65to127octets",
2128                 .getter = mlxsw_reg_ppcnt_ether_stats_pkts65to127octets_get,
2129         },
2130         {
2131                 .str = "ether_pkts128to255octets",
2132                 .getter = mlxsw_reg_ppcnt_ether_stats_pkts128to255octets_get,
2133         },
2134         {
2135                 .str = "ether_pkts256to511octets",
2136                 .getter = mlxsw_reg_ppcnt_ether_stats_pkts256to511octets_get,
2137         },
2138         {
2139                 .str = "ether_pkts512to1023octets",
2140                 .getter = mlxsw_reg_ppcnt_ether_stats_pkts512to1023octets_get,
2141         },
2142         {
2143                 .str = "ether_pkts1024to1518octets",
2144                 .getter = mlxsw_reg_ppcnt_ether_stats_pkts1024to1518octets_get,
2145         },
2146         {
2147                 .str = "ether_pkts1519to2047octets",
2148                 .getter = mlxsw_reg_ppcnt_ether_stats_pkts1519to2047octets_get,
2149         },
2150         {
2151                 .str = "ether_pkts2048to4095octets",
2152                 .getter = mlxsw_reg_ppcnt_ether_stats_pkts2048to4095octets_get,
2153         },
2154         {
2155                 .str = "ether_pkts4096to8191octets",
2156                 .getter = mlxsw_reg_ppcnt_ether_stats_pkts4096to8191octets_get,
2157         },
2158         {
2159                 .str = "ether_pkts8192to10239octets",
2160                 .getter = mlxsw_reg_ppcnt_ether_stats_pkts8192to10239octets_get,
2161         },
2162 };
2163
2164 #define MLXSW_SP_PORT_HW_RFC_2819_STATS_LEN \
2165         ARRAY_SIZE(mlxsw_sp_port_hw_rfc_2819_stats)
2166
2167 static struct mlxsw_sp_port_hw_stats mlxsw_sp_port_hw_rfc_3635_stats[] = {
2168         {
2169                 .str = "dot3stats_fcs_errors",
2170                 .getter = mlxsw_reg_ppcnt_dot3stats_fcs_errors_get,
2171         },
2172         {
2173                 .str = "dot3stats_symbol_errors",
2174                 .getter = mlxsw_reg_ppcnt_dot3stats_symbol_errors_get,
2175         },
2176         {
2177                 .str = "dot3control_in_unknown_opcodes",
2178                 .getter = mlxsw_reg_ppcnt_dot3control_in_unknown_opcodes_get,
2179         },
2180         {
2181                 .str = "dot3in_pause_frames",
2182                 .getter = mlxsw_reg_ppcnt_dot3in_pause_frames_get,
2183         },
2184 };
2185
2186 #define MLXSW_SP_PORT_HW_RFC_3635_STATS_LEN \
2187         ARRAY_SIZE(mlxsw_sp_port_hw_rfc_3635_stats)
2188
2189 static struct mlxsw_sp_port_hw_stats mlxsw_sp_port_hw_discard_stats[] = {
2190         {
2191                 .str = "discard_ingress_general",
2192                 .getter = mlxsw_reg_ppcnt_ingress_general_get,
2193         },
2194         {
2195                 .str = "discard_ingress_policy_engine",
2196                 .getter = mlxsw_reg_ppcnt_ingress_policy_engine_get,
2197         },
2198         {
2199                 .str = "discard_ingress_vlan_membership",
2200                 .getter = mlxsw_reg_ppcnt_ingress_vlan_membership_get,
2201         },
2202         {
2203                 .str = "discard_ingress_tag_frame_type",
2204                 .getter = mlxsw_reg_ppcnt_ingress_tag_frame_type_get,
2205         },
2206         {
2207                 .str = "discard_egress_vlan_membership",
2208                 .getter = mlxsw_reg_ppcnt_egress_vlan_membership_get,
2209         },
2210         {
2211                 .str = "discard_loopback_filter",
2212                 .getter = mlxsw_reg_ppcnt_loopback_filter_get,
2213         },
2214         {
2215                 .str = "discard_egress_general",
2216                 .getter = mlxsw_reg_ppcnt_egress_general_get,
2217         },
2218         {
2219                 .str = "discard_egress_hoq",
2220                 .getter = mlxsw_reg_ppcnt_egress_hoq_get,
2221         },
2222         {
2223                 .str = "discard_egress_policy_engine",
2224                 .getter = mlxsw_reg_ppcnt_egress_policy_engine_get,
2225         },
2226         {
2227                 .str = "discard_ingress_tx_link_down",
2228                 .getter = mlxsw_reg_ppcnt_ingress_tx_link_down_get,
2229         },
2230         {
2231                 .str = "discard_egress_stp_filter",
2232                 .getter = mlxsw_reg_ppcnt_egress_stp_filter_get,
2233         },
2234         {
2235                 .str = "discard_egress_sll",
2236                 .getter = mlxsw_reg_ppcnt_egress_sll_get,
2237         },
2238 };
2239
2240 #define MLXSW_SP_PORT_HW_DISCARD_STATS_LEN \
2241         ARRAY_SIZE(mlxsw_sp_port_hw_discard_stats)
2242
2243 static struct mlxsw_sp_port_hw_stats mlxsw_sp_port_hw_prio_stats[] = {
2244         {
2245                 .str = "rx_octets_prio",
2246                 .getter = mlxsw_reg_ppcnt_rx_octets_get,
2247         },
2248         {
2249                 .str = "rx_frames_prio",
2250                 .getter = mlxsw_reg_ppcnt_rx_frames_get,
2251         },
2252         {
2253                 .str = "tx_octets_prio",
2254                 .getter = mlxsw_reg_ppcnt_tx_octets_get,
2255         },
2256         {
2257                 .str = "tx_frames_prio",
2258                 .getter = mlxsw_reg_ppcnt_tx_frames_get,
2259         },
2260         {
2261                 .str = "rx_pause_prio",
2262                 .getter = mlxsw_reg_ppcnt_rx_pause_get,
2263         },
2264         {
2265                 .str = "rx_pause_duration_prio",
2266                 .getter = mlxsw_reg_ppcnt_rx_pause_duration_get,
2267         },
2268         {
2269                 .str = "tx_pause_prio",
2270                 .getter = mlxsw_reg_ppcnt_tx_pause_get,
2271         },
2272         {
2273                 .str = "tx_pause_duration_prio",
2274                 .getter = mlxsw_reg_ppcnt_tx_pause_duration_get,
2275         },
2276 };
2277
2278 #define MLXSW_SP_PORT_HW_PRIO_STATS_LEN ARRAY_SIZE(mlxsw_sp_port_hw_prio_stats)
2279
2280 static struct mlxsw_sp_port_hw_stats mlxsw_sp_port_hw_tc_stats[] = {
2281         {
2282                 .str = "tc_transmit_queue_tc",
2283                 .getter = mlxsw_reg_ppcnt_tc_transmit_queue_get,
2284                 .cells_bytes = true,
2285         },
2286         {
2287                 .str = "tc_no_buffer_discard_uc_tc",
2288                 .getter = mlxsw_reg_ppcnt_tc_no_buffer_discard_uc_get,
2289         },
2290 };
2291
2292 #define MLXSW_SP_PORT_HW_TC_STATS_LEN ARRAY_SIZE(mlxsw_sp_port_hw_tc_stats)
2293
2294 #define MLXSW_SP_PORT_ETHTOOL_STATS_LEN (MLXSW_SP_PORT_HW_STATS_LEN + \
2295                                          MLXSW_SP_PORT_HW_RFC_2863_STATS_LEN + \
2296                                          MLXSW_SP_PORT_HW_RFC_2819_STATS_LEN + \
2297                                          MLXSW_SP_PORT_HW_RFC_3635_STATS_LEN + \
2298                                          MLXSW_SP_PORT_HW_DISCARD_STATS_LEN + \
2299                                          (MLXSW_SP_PORT_HW_PRIO_STATS_LEN * \
2300                                           IEEE_8021QAZ_MAX_TCS) + \
2301                                          (MLXSW_SP_PORT_HW_TC_STATS_LEN * \
2302                                           TC_MAX_QUEUE))
2303
2304 static void mlxsw_sp_port_get_prio_strings(u8 **p, int prio)
2305 {
2306         int i;
2307
2308         for (i = 0; i < MLXSW_SP_PORT_HW_PRIO_STATS_LEN; i++) {
2309                 snprintf(*p, ETH_GSTRING_LEN, "%.29s_%.1d",
2310                          mlxsw_sp_port_hw_prio_stats[i].str, prio);
2311                 *p += ETH_GSTRING_LEN;
2312         }
2313 }
2314
2315 static void mlxsw_sp_port_get_tc_strings(u8 **p, int tc)
2316 {
2317         int i;
2318
2319         for (i = 0; i < MLXSW_SP_PORT_HW_TC_STATS_LEN; i++) {
2320                 snprintf(*p, ETH_GSTRING_LEN, "%.29s_%.1d",
2321                          mlxsw_sp_port_hw_tc_stats[i].str, tc);
2322                 *p += ETH_GSTRING_LEN;
2323         }
2324 }
2325
2326 static void mlxsw_sp_port_get_strings(struct net_device *dev,
2327                                       u32 stringset, u8 *data)
2328 {
2329         u8 *p = data;
2330         int i;
2331
2332         switch (stringset) {
2333         case ETH_SS_STATS:
2334                 for (i = 0; i < MLXSW_SP_PORT_HW_STATS_LEN; i++) {
2335                         memcpy(p, mlxsw_sp_port_hw_stats[i].str,
2336                                ETH_GSTRING_LEN);
2337                         p += ETH_GSTRING_LEN;
2338                 }
2339
2340                 for (i = 0; i < MLXSW_SP_PORT_HW_RFC_2863_STATS_LEN; i++) {
2341                         memcpy(p, mlxsw_sp_port_hw_rfc_2863_stats[i].str,
2342                                ETH_GSTRING_LEN);
2343                         p += ETH_GSTRING_LEN;
2344                 }
2345
2346                 for (i = 0; i < MLXSW_SP_PORT_HW_RFC_2819_STATS_LEN; i++) {
2347                         memcpy(p, mlxsw_sp_port_hw_rfc_2819_stats[i].str,
2348                                ETH_GSTRING_LEN);
2349                         p += ETH_GSTRING_LEN;
2350                 }
2351
2352                 for (i = 0; i < MLXSW_SP_PORT_HW_RFC_3635_STATS_LEN; i++) {
2353                         memcpy(p, mlxsw_sp_port_hw_rfc_3635_stats[i].str,
2354                                ETH_GSTRING_LEN);
2355                         p += ETH_GSTRING_LEN;
2356                 }
2357
2358                 for (i = 0; i < MLXSW_SP_PORT_HW_DISCARD_STATS_LEN; i++) {
2359                         memcpy(p, mlxsw_sp_port_hw_discard_stats[i].str,
2360                                ETH_GSTRING_LEN);
2361                         p += ETH_GSTRING_LEN;
2362                 }
2363
2364                 for (i = 0; i < IEEE_8021QAZ_MAX_TCS; i++)
2365                         mlxsw_sp_port_get_prio_strings(&p, i);
2366
2367                 for (i = 0; i < TC_MAX_QUEUE; i++)
2368                         mlxsw_sp_port_get_tc_strings(&p, i);
2369
2370                 break;
2371         }
2372 }
2373
2374 static int mlxsw_sp_port_set_phys_id(struct net_device *dev,
2375                                      enum ethtool_phys_id_state state)
2376 {
2377         struct mlxsw_sp_port *mlxsw_sp_port = netdev_priv(dev);
2378         struct mlxsw_sp *mlxsw_sp = mlxsw_sp_port->mlxsw_sp;
2379         char mlcr_pl[MLXSW_REG_MLCR_LEN];
2380         bool active;
2381
2382         switch (state) {
2383         case ETHTOOL_ID_ACTIVE:
2384                 active = true;
2385                 break;
2386         case ETHTOOL_ID_INACTIVE:
2387                 active = false;
2388                 break;
2389         default:
2390                 return -EOPNOTSUPP;
2391         }
2392
2393         mlxsw_reg_mlcr_pack(mlcr_pl, mlxsw_sp_port->local_port, active);
2394         return mlxsw_reg_write(mlxsw_sp->core, MLXSW_REG(mlcr), mlcr_pl);
2395 }
2396
2397 static int
2398 mlxsw_sp_get_hw_stats_by_group(struct mlxsw_sp_port_hw_stats **p_hw_stats,
2399                                int *p_len, enum mlxsw_reg_ppcnt_grp grp)
2400 {
2401         switch (grp) {
2402         case MLXSW_REG_PPCNT_IEEE_8023_CNT:
2403                 *p_hw_stats = mlxsw_sp_port_hw_stats;
2404                 *p_len = MLXSW_SP_PORT_HW_STATS_LEN;
2405                 break;
2406         case MLXSW_REG_PPCNT_RFC_2863_CNT:
2407                 *p_hw_stats = mlxsw_sp_port_hw_rfc_2863_stats;
2408                 *p_len = MLXSW_SP_PORT_HW_RFC_2863_STATS_LEN;
2409                 break;
2410         case MLXSW_REG_PPCNT_RFC_2819_CNT:
2411                 *p_hw_stats = mlxsw_sp_port_hw_rfc_2819_stats;
2412                 *p_len = MLXSW_SP_PORT_HW_RFC_2819_STATS_LEN;
2413                 break;
2414         case MLXSW_REG_PPCNT_RFC_3635_CNT:
2415                 *p_hw_stats = mlxsw_sp_port_hw_rfc_3635_stats;
2416                 *p_len = MLXSW_SP_PORT_HW_RFC_3635_STATS_LEN;
2417                 break;
2418         case MLXSW_REG_PPCNT_DISCARD_CNT:
2419                 *p_hw_stats = mlxsw_sp_port_hw_discard_stats;
2420                 *p_len = MLXSW_SP_PORT_HW_DISCARD_STATS_LEN;
2421                 break;
2422         case MLXSW_REG_PPCNT_PRIO_CNT:
2423                 *p_hw_stats = mlxsw_sp_port_hw_prio_stats;
2424                 *p_len = MLXSW_SP_PORT_HW_PRIO_STATS_LEN;
2425                 break;
2426         case MLXSW_REG_PPCNT_TC_CNT:
2427                 *p_hw_stats = mlxsw_sp_port_hw_tc_stats;
2428                 *p_len = MLXSW_SP_PORT_HW_TC_STATS_LEN;
2429                 break;
2430         default:
2431                 WARN_ON(1);
2432                 return -EOPNOTSUPP;
2433         }
2434         return 0;
2435 }
2436
2437 static void __mlxsw_sp_port_get_stats(struct net_device *dev,
2438                                       enum mlxsw_reg_ppcnt_grp grp, int prio,
2439                                       u64 *data, int data_index)
2440 {
2441         struct mlxsw_sp_port *mlxsw_sp_port = netdev_priv(dev);
2442         struct mlxsw_sp *mlxsw_sp = mlxsw_sp_port->mlxsw_sp;
2443         struct mlxsw_sp_port_hw_stats *hw_stats;
2444         char ppcnt_pl[MLXSW_REG_PPCNT_LEN];
2445         int i, len;
2446         int err;
2447
2448         err = mlxsw_sp_get_hw_stats_by_group(&hw_stats, &len, grp);
2449         if (err)
2450                 return;
2451         mlxsw_sp_port_get_stats_raw(dev, grp, prio, ppcnt_pl);
2452         for (i = 0; i < len; i++) {
2453                 data[data_index + i] = hw_stats[i].getter(ppcnt_pl);
2454                 if (!hw_stats[i].cells_bytes)
2455                         continue;
2456                 data[data_index + i] = mlxsw_sp_cells_bytes(mlxsw_sp,
2457                                                             data[data_index + i]);
2458         }
2459 }
2460
2461 static void mlxsw_sp_port_get_stats(struct net_device *dev,
2462                                     struct ethtool_stats *stats, u64 *data)
2463 {
2464         int i, data_index = 0;
2465
2466         /* IEEE 802.3 Counters */
2467         __mlxsw_sp_port_get_stats(dev, MLXSW_REG_PPCNT_IEEE_8023_CNT, 0,
2468                                   data, data_index);
2469         data_index = MLXSW_SP_PORT_HW_STATS_LEN;
2470
2471         /* RFC 2863 Counters */
2472         __mlxsw_sp_port_get_stats(dev, MLXSW_REG_PPCNT_RFC_2863_CNT, 0,
2473                                   data, data_index);
2474         data_index += MLXSW_SP_PORT_HW_RFC_2863_STATS_LEN;
2475
2476         /* RFC 2819 Counters */
2477         __mlxsw_sp_port_get_stats(dev, MLXSW_REG_PPCNT_RFC_2819_CNT, 0,
2478                                   data, data_index);
2479         data_index += MLXSW_SP_PORT_HW_RFC_2819_STATS_LEN;
2480
2481         /* RFC 3635 Counters */
2482         __mlxsw_sp_port_get_stats(dev, MLXSW_REG_PPCNT_RFC_3635_CNT, 0,
2483                                   data, data_index);
2484         data_index += MLXSW_SP_PORT_HW_RFC_3635_STATS_LEN;
2485
2486         /* Discard Counters */
2487         __mlxsw_sp_port_get_stats(dev, MLXSW_REG_PPCNT_DISCARD_CNT, 0,
2488                                   data, data_index);
2489         data_index += MLXSW_SP_PORT_HW_DISCARD_STATS_LEN;
2490
2491         /* Per-Priority Counters */
2492         for (i = 0; i < IEEE_8021QAZ_MAX_TCS; i++) {
2493                 __mlxsw_sp_port_get_stats(dev, MLXSW_REG_PPCNT_PRIO_CNT, i,
2494                                           data, data_index);
2495                 data_index += MLXSW_SP_PORT_HW_PRIO_STATS_LEN;
2496         }
2497
2498         /* Per-TC Counters */
2499         for (i = 0; i < TC_MAX_QUEUE; i++) {
2500                 __mlxsw_sp_port_get_stats(dev, MLXSW_REG_PPCNT_TC_CNT, i,
2501                                           data, data_index);
2502                 data_index += MLXSW_SP_PORT_HW_TC_STATS_LEN;
2503         }
2504 }
2505
2506 static int mlxsw_sp_port_get_sset_count(struct net_device *dev, int sset)
2507 {
2508         switch (sset) {
2509         case ETH_SS_STATS:
2510                 return MLXSW_SP_PORT_ETHTOOL_STATS_LEN;
2511         default:
2512                 return -EOPNOTSUPP;
2513         }
2514 }
2515
2516 struct mlxsw_sp1_port_link_mode {
2517         enum ethtool_link_mode_bit_indices mask_ethtool;
2518         u32 mask;
2519         u32 speed;
2520 };
2521
2522 static const struct mlxsw_sp1_port_link_mode mlxsw_sp1_port_link_mode[] = {
2523         {
2524                 .mask           = MLXSW_REG_PTYS_ETH_SPEED_100BASE_T,
2525                 .mask_ethtool   = ETHTOOL_LINK_MODE_100baseT_Full_BIT,
2526                 .speed          = SPEED_100,
2527         },
2528         {
2529                 .mask           = MLXSW_REG_PTYS_ETH_SPEED_SGMII |
2530                                   MLXSW_REG_PTYS_ETH_SPEED_1000BASE_KX,
2531                 .mask_ethtool   = ETHTOOL_LINK_MODE_1000baseKX_Full_BIT,
2532                 .speed          = SPEED_1000,
2533         },
2534         {
2535                 .mask           = MLXSW_REG_PTYS_ETH_SPEED_10GBASE_T,
2536                 .mask_ethtool   = ETHTOOL_LINK_MODE_10000baseT_Full_BIT,
2537                 .speed          = SPEED_10000,
2538         },
2539         {
2540                 .mask           = MLXSW_REG_PTYS_ETH_SPEED_10GBASE_CX4 |
2541                                   MLXSW_REG_PTYS_ETH_SPEED_10GBASE_KX4,
2542                 .mask_ethtool   = ETHTOOL_LINK_MODE_10000baseKX4_Full_BIT,
2543                 .speed          = SPEED_10000,
2544         },
2545         {
2546                 .mask           = MLXSW_REG_PTYS_ETH_SPEED_10GBASE_KR |
2547                                   MLXSW_REG_PTYS_ETH_SPEED_10GBASE_CR |
2548                                   MLXSW_REG_PTYS_ETH_SPEED_10GBASE_SR |
2549                                   MLXSW_REG_PTYS_ETH_SPEED_10GBASE_ER_LR,
2550                 .mask_ethtool   = ETHTOOL_LINK_MODE_10000baseKR_Full_BIT,
2551                 .speed          = SPEED_10000,
2552         },
2553         {
2554                 .mask           = MLXSW_REG_PTYS_ETH_SPEED_20GBASE_KR2,
2555                 .mask_ethtool   = ETHTOOL_LINK_MODE_20000baseKR2_Full_BIT,
2556                 .speed          = SPEED_20000,
2557         },
2558         {
2559                 .mask           = MLXSW_REG_PTYS_ETH_SPEED_40GBASE_CR4,
2560                 .mask_ethtool   = ETHTOOL_LINK_MODE_40000baseCR4_Full_BIT,
2561                 .speed          = SPEED_40000,
2562         },
2563         {
2564                 .mask           = MLXSW_REG_PTYS_ETH_SPEED_40GBASE_KR4,
2565                 .mask_ethtool   = ETHTOOL_LINK_MODE_40000baseKR4_Full_BIT,
2566                 .speed          = SPEED_40000,
2567         },
2568         {
2569                 .mask           = MLXSW_REG_PTYS_ETH_SPEED_40GBASE_SR4,
2570                 .mask_ethtool   = ETHTOOL_LINK_MODE_40000baseSR4_Full_BIT,
2571                 .speed          = SPEED_40000,
2572         },
2573         {
2574                 .mask           = MLXSW_REG_PTYS_ETH_SPEED_40GBASE_LR4_ER4,
2575                 .mask_ethtool   = ETHTOOL_LINK_MODE_40000baseLR4_Full_BIT,
2576                 .speed          = SPEED_40000,
2577         },
2578         {
2579                 .mask           = MLXSW_REG_PTYS_ETH_SPEED_25GBASE_CR,
2580                 .mask_ethtool   = ETHTOOL_LINK_MODE_25000baseCR_Full_BIT,
2581                 .speed          = SPEED_25000,
2582         },
2583         {
2584                 .mask           = MLXSW_REG_PTYS_ETH_SPEED_25GBASE_KR,
2585                 .mask_ethtool   = ETHTOOL_LINK_MODE_25000baseKR_Full_BIT,
2586                 .speed          = SPEED_25000,
2587         },
2588         {
2589                 .mask           = MLXSW_REG_PTYS_ETH_SPEED_25GBASE_SR,
2590                 .mask_ethtool   = ETHTOOL_LINK_MODE_25000baseSR_Full_BIT,
2591                 .speed          = SPEED_25000,
2592         },
2593         {
2594                 .mask           = MLXSW_REG_PTYS_ETH_SPEED_50GBASE_CR2,
2595                 .mask_ethtool   = ETHTOOL_LINK_MODE_50000baseCR2_Full_BIT,
2596                 .speed          = SPEED_50000,
2597         },
2598         {
2599                 .mask           = MLXSW_REG_PTYS_ETH_SPEED_50GBASE_KR2,
2600                 .mask_ethtool   = ETHTOOL_LINK_MODE_50000baseKR2_Full_BIT,
2601                 .speed          = SPEED_50000,
2602         },
2603         {
2604                 .mask           = MLXSW_REG_PTYS_ETH_SPEED_50GBASE_SR2,
2605                 .mask_ethtool   = ETHTOOL_LINK_MODE_50000baseSR2_Full_BIT,
2606                 .speed          = SPEED_50000,
2607         },
2608         {
2609                 .mask           = MLXSW_REG_PTYS_ETH_SPEED_56GBASE_R4,
2610                 .mask_ethtool   = ETHTOOL_LINK_MODE_56000baseKR4_Full_BIT,
2611                 .speed          = SPEED_56000,
2612         },
2613         {
2614                 .mask           = MLXSW_REG_PTYS_ETH_SPEED_56GBASE_R4,
2615                 .mask_ethtool   = ETHTOOL_LINK_MODE_56000baseCR4_Full_BIT,
2616                 .speed          = SPEED_56000,
2617         },
2618         {
2619                 .mask           = MLXSW_REG_PTYS_ETH_SPEED_56GBASE_R4,
2620                 .mask_ethtool   = ETHTOOL_LINK_MODE_56000baseSR4_Full_BIT,
2621                 .speed          = SPEED_56000,
2622         },
2623         {
2624                 .mask           = MLXSW_REG_PTYS_ETH_SPEED_56GBASE_R4,
2625                 .mask_ethtool   = ETHTOOL_LINK_MODE_56000baseLR4_Full_BIT,
2626                 .speed          = SPEED_56000,
2627         },
2628         {
2629                 .mask           = MLXSW_REG_PTYS_ETH_SPEED_100GBASE_CR4,
2630                 .mask_ethtool   = ETHTOOL_LINK_MODE_100000baseCR4_Full_BIT,
2631                 .speed          = SPEED_100000,
2632         },
2633         {
2634                 .mask           = MLXSW_REG_PTYS_ETH_SPEED_100GBASE_SR4,
2635                 .mask_ethtool   = ETHTOOL_LINK_MODE_100000baseSR4_Full_BIT,
2636                 .speed          = SPEED_100000,
2637         },
2638         {
2639                 .mask           = MLXSW_REG_PTYS_ETH_SPEED_100GBASE_KR4,
2640                 .mask_ethtool   = ETHTOOL_LINK_MODE_100000baseKR4_Full_BIT,
2641                 .speed          = SPEED_100000,
2642         },
2643         {
2644                 .mask           = MLXSW_REG_PTYS_ETH_SPEED_100GBASE_LR4_ER4,
2645                 .mask_ethtool   = ETHTOOL_LINK_MODE_100000baseLR4_ER4_Full_BIT,
2646                 .speed          = SPEED_100000,
2647         },
2648 };
2649
2650 #define MLXSW_SP1_PORT_LINK_MODE_LEN ARRAY_SIZE(mlxsw_sp1_port_link_mode)
2651
2652 static void
2653 mlxsw_sp1_from_ptys_supported_port(struct mlxsw_sp *mlxsw_sp,
2654                                    u32 ptys_eth_proto,
2655                                    struct ethtool_link_ksettings *cmd)
2656 {
2657         if (ptys_eth_proto & (MLXSW_REG_PTYS_ETH_SPEED_10GBASE_CR |
2658                               MLXSW_REG_PTYS_ETH_SPEED_10GBASE_SR |
2659                               MLXSW_REG_PTYS_ETH_SPEED_40GBASE_CR4 |
2660                               MLXSW_REG_PTYS_ETH_SPEED_40GBASE_SR4 |
2661                               MLXSW_REG_PTYS_ETH_SPEED_100GBASE_SR4 |
2662                               MLXSW_REG_PTYS_ETH_SPEED_SGMII))
2663                 ethtool_link_ksettings_add_link_mode(cmd, supported, FIBRE);
2664
2665         if (ptys_eth_proto & (MLXSW_REG_PTYS_ETH_SPEED_10GBASE_KR |
2666                               MLXSW_REG_PTYS_ETH_SPEED_10GBASE_KX4 |
2667                               MLXSW_REG_PTYS_ETH_SPEED_40GBASE_KR4 |
2668                               MLXSW_REG_PTYS_ETH_SPEED_100GBASE_KR4 |
2669                               MLXSW_REG_PTYS_ETH_SPEED_1000BASE_KX))
2670                 ethtool_link_ksettings_add_link_mode(cmd, supported, Backplane);
2671 }
2672
2673 static void
2674 mlxsw_sp1_from_ptys_link(struct mlxsw_sp *mlxsw_sp, u32 ptys_eth_proto,
2675                          unsigned long *mode)
2676 {
2677         int i;
2678
2679         for (i = 0; i < MLXSW_SP1_PORT_LINK_MODE_LEN; i++) {
2680                 if (ptys_eth_proto & mlxsw_sp1_port_link_mode[i].mask)
2681                         __set_bit(mlxsw_sp1_port_link_mode[i].mask_ethtool,
2682                                   mode);
2683         }
2684 }
2685
2686 static u32
2687 mlxsw_sp1_from_ptys_speed(struct mlxsw_sp *mlxsw_sp, u32 ptys_eth_proto)
2688 {
2689         int i;
2690
2691         for (i = 0; i < MLXSW_SP1_PORT_LINK_MODE_LEN; i++) {
2692                 if (ptys_eth_proto & mlxsw_sp1_port_link_mode[i].mask)
2693                         return mlxsw_sp1_port_link_mode[i].speed;
2694         }
2695
2696         return SPEED_UNKNOWN;
2697 }
2698
2699 static void
2700 mlxsw_sp1_from_ptys_speed_duplex(struct mlxsw_sp *mlxsw_sp, bool carrier_ok,
2701                                  u32 ptys_eth_proto,
2702                                  struct ethtool_link_ksettings *cmd)
2703 {
2704         cmd->base.speed = SPEED_UNKNOWN;
2705         cmd->base.duplex = DUPLEX_UNKNOWN;
2706
2707         if (!carrier_ok)
2708                 return;
2709
2710         cmd->base.speed = mlxsw_sp1_from_ptys_speed(mlxsw_sp, ptys_eth_proto);
2711         if (cmd->base.speed != SPEED_UNKNOWN)
2712                 cmd->base.duplex = DUPLEX_FULL;
2713 }
2714
2715 static u32
2716 mlxsw_sp1_to_ptys_advert_link(struct mlxsw_sp *mlxsw_sp,
2717                               const struct ethtool_link_ksettings *cmd)
2718 {
2719         u32 ptys_proto = 0;
2720         int i;
2721
2722         for (i = 0; i < MLXSW_SP1_PORT_LINK_MODE_LEN; i++) {
2723                 if (test_bit(mlxsw_sp1_port_link_mode[i].mask_ethtool,
2724                              cmd->link_modes.advertising))
2725                         ptys_proto |= mlxsw_sp1_port_link_mode[i].mask;
2726         }
2727         return ptys_proto;
2728 }
2729
2730 static u32 mlxsw_sp1_to_ptys_speed(struct mlxsw_sp *mlxsw_sp, u32 speed)
2731 {
2732         u32 ptys_proto = 0;
2733         int i;
2734
2735         for (i = 0; i < MLXSW_SP1_PORT_LINK_MODE_LEN; i++) {
2736                 if (speed == mlxsw_sp1_port_link_mode[i].speed)
2737                         ptys_proto |= mlxsw_sp1_port_link_mode[i].mask;
2738         }
2739         return ptys_proto;
2740 }
2741
2742 static u32
2743 mlxsw_sp1_to_ptys_upper_speed(struct mlxsw_sp *mlxsw_sp, u32 upper_speed)
2744 {
2745         u32 ptys_proto = 0;
2746         int i;
2747
2748         for (i = 0; i < MLXSW_SP1_PORT_LINK_MODE_LEN; i++) {
2749                 if (mlxsw_sp1_port_link_mode[i].speed <= upper_speed)
2750                         ptys_proto |= mlxsw_sp1_port_link_mode[i].mask;
2751         }
2752         return ptys_proto;
2753 }
2754
2755 static int
2756 mlxsw_sp1_port_speed_base(struct mlxsw_sp *mlxsw_sp, u8 local_port,
2757                           u32 *base_speed)
2758 {
2759         *base_speed = MLXSW_SP_PORT_BASE_SPEED_25G;
2760         return 0;
2761 }
2762
2763 static void
2764 mlxsw_sp1_reg_ptys_eth_pack(struct mlxsw_sp *mlxsw_sp, char *payload,
2765                             u8 local_port, u32 proto_admin, bool autoneg)
2766 {
2767         mlxsw_reg_ptys_eth_pack(payload, local_port, proto_admin, autoneg);
2768 }
2769
2770 static void
2771 mlxsw_sp1_reg_ptys_eth_unpack(struct mlxsw_sp *mlxsw_sp, char *payload,
2772                               u32 *p_eth_proto_cap, u32 *p_eth_proto_admin,
2773                               u32 *p_eth_proto_oper)
2774 {
2775         mlxsw_reg_ptys_eth_unpack(payload, p_eth_proto_cap, p_eth_proto_admin,
2776                                   p_eth_proto_oper);
2777 }
2778
2779 static const struct mlxsw_sp_port_type_speed_ops
2780 mlxsw_sp1_port_type_speed_ops = {
2781         .from_ptys_supported_port       = mlxsw_sp1_from_ptys_supported_port,
2782         .from_ptys_link                 = mlxsw_sp1_from_ptys_link,
2783         .from_ptys_speed                = mlxsw_sp1_from_ptys_speed,
2784         .from_ptys_speed_duplex         = mlxsw_sp1_from_ptys_speed_duplex,
2785         .to_ptys_advert_link            = mlxsw_sp1_to_ptys_advert_link,
2786         .to_ptys_speed                  = mlxsw_sp1_to_ptys_speed,
2787         .to_ptys_upper_speed            = mlxsw_sp1_to_ptys_upper_speed,
2788         .port_speed_base                = mlxsw_sp1_port_speed_base,
2789         .reg_ptys_eth_pack              = mlxsw_sp1_reg_ptys_eth_pack,
2790         .reg_ptys_eth_unpack            = mlxsw_sp1_reg_ptys_eth_unpack,
2791 };
2792
2793 static const enum ethtool_link_mode_bit_indices
2794 mlxsw_sp2_mask_ethtool_sgmii_100m[] = {
2795         ETHTOOL_LINK_MODE_100baseT_Full_BIT,
2796 };
2797
2798 #define MLXSW_SP2_MASK_ETHTOOL_SGMII_100M_LEN \
2799         ARRAY_SIZE(mlxsw_sp2_mask_ethtool_sgmii_100m)
2800
2801 static const enum ethtool_link_mode_bit_indices
2802 mlxsw_sp2_mask_ethtool_1000base_x_sgmii[] = {
2803         ETHTOOL_LINK_MODE_1000baseT_Full_BIT,
2804         ETHTOOL_LINK_MODE_1000baseKX_Full_BIT,
2805 };
2806
2807 #define MLXSW_SP2_MASK_ETHTOOL_1000BASE_X_SGMII_LEN \
2808         ARRAY_SIZE(mlxsw_sp2_mask_ethtool_1000base_x_sgmii)
2809
2810 static const enum ethtool_link_mode_bit_indices
2811 mlxsw_sp2_mask_ethtool_2_5gbase_x_2_5gmii[] = {
2812         ETHTOOL_LINK_MODE_2500baseX_Full_BIT,
2813 };
2814
2815 #define MLXSW_SP2_MASK_ETHTOOL_2_5GBASE_X_2_5GMII_LEN \
2816         ARRAY_SIZE(mlxsw_sp2_mask_ethtool_2_5gbase_x_2_5gmii)
2817
2818 static const enum ethtool_link_mode_bit_indices
2819 mlxsw_sp2_mask_ethtool_5gbase_r[] = {
2820         ETHTOOL_LINK_MODE_5000baseT_Full_BIT,
2821 };
2822
2823 #define MLXSW_SP2_MASK_ETHTOOL_5GBASE_R_LEN \
2824         ARRAY_SIZE(mlxsw_sp2_mask_ethtool_5gbase_r)
2825
2826 static const enum ethtool_link_mode_bit_indices
2827 mlxsw_sp2_mask_ethtool_xfi_xaui_1_10g[] = {
2828         ETHTOOL_LINK_MODE_10000baseT_Full_BIT,
2829         ETHTOOL_LINK_MODE_10000baseKR_Full_BIT,
2830         ETHTOOL_LINK_MODE_10000baseR_FEC_BIT,
2831         ETHTOOL_LINK_MODE_10000baseCR_Full_BIT,
2832         ETHTOOL_LINK_MODE_10000baseSR_Full_BIT,
2833         ETHTOOL_LINK_MODE_10000baseLR_Full_BIT,
2834         ETHTOOL_LINK_MODE_10000baseER_Full_BIT,
2835 };
2836
2837 #define MLXSW_SP2_MASK_ETHTOOL_XFI_XAUI_1_10G_LEN \
2838         ARRAY_SIZE(mlxsw_sp2_mask_ethtool_xfi_xaui_1_10g)
2839
2840 static const enum ethtool_link_mode_bit_indices
2841 mlxsw_sp2_mask_ethtool_xlaui_4_xlppi_4_40g[] = {
2842         ETHTOOL_LINK_MODE_40000baseKR4_Full_BIT,
2843         ETHTOOL_LINK_MODE_40000baseCR4_Full_BIT,
2844         ETHTOOL_LINK_MODE_40000baseSR4_Full_BIT,
2845         ETHTOOL_LINK_MODE_40000baseLR4_Full_BIT,
2846 };
2847
2848 #define MLXSW_SP2_MASK_ETHTOOL_XLAUI_4_XLPPI_4_40G_LEN \
2849         ARRAY_SIZE(mlxsw_sp2_mask_ethtool_xlaui_4_xlppi_4_40g)
2850
2851 static const enum ethtool_link_mode_bit_indices
2852 mlxsw_sp2_mask_ethtool_25gaui_1_25gbase_cr_kr[] = {
2853         ETHTOOL_LINK_MODE_25000baseCR_Full_BIT,
2854         ETHTOOL_LINK_MODE_25000baseKR_Full_BIT,
2855         ETHTOOL_LINK_MODE_25000baseSR_Full_BIT,
2856 };
2857
2858 #define MLXSW_SP2_MASK_ETHTOOL_25GAUI_1_25GBASE_CR_KR_LEN \
2859         ARRAY_SIZE(mlxsw_sp2_mask_ethtool_25gaui_1_25gbase_cr_kr)
2860
2861 static const enum ethtool_link_mode_bit_indices
2862 mlxsw_sp2_mask_ethtool_50gaui_2_laui_2_50gbase_cr2_kr2[] = {
2863         ETHTOOL_LINK_MODE_50000baseCR2_Full_BIT,
2864         ETHTOOL_LINK_MODE_50000baseKR2_Full_BIT,
2865         ETHTOOL_LINK_MODE_50000baseSR2_Full_BIT,
2866 };
2867
2868 #define MLXSW_SP2_MASK_ETHTOOL_50GAUI_2_LAUI_2_50GBASE_CR2_KR2_LEN \
2869         ARRAY_SIZE(mlxsw_sp2_mask_ethtool_50gaui_2_laui_2_50gbase_cr2_kr2)
2870
2871 static const enum ethtool_link_mode_bit_indices
2872 mlxsw_sp2_mask_ethtool_50gaui_1_laui_1_50gbase_cr_kr[] = {
2873         ETHTOOL_LINK_MODE_50000baseKR_Full_BIT,
2874         ETHTOOL_LINK_MODE_50000baseSR_Full_BIT,
2875         ETHTOOL_LINK_MODE_50000baseCR_Full_BIT,
2876         ETHTOOL_LINK_MODE_50000baseLR_ER_FR_Full_BIT,
2877         ETHTOOL_LINK_MODE_50000baseDR_Full_BIT,
2878 };
2879
2880 #define MLXSW_SP2_MASK_ETHTOOL_50GAUI_1_LAUI_1_50GBASE_CR_KR_LEN \
2881         ARRAY_SIZE(mlxsw_sp2_mask_ethtool_50gaui_1_laui_1_50gbase_cr_kr)
2882
2883 static const enum ethtool_link_mode_bit_indices
2884 mlxsw_sp2_mask_ethtool_caui_4_100gbase_cr4_kr4[] = {
2885         ETHTOOL_LINK_MODE_100000baseKR4_Full_BIT,
2886         ETHTOOL_LINK_MODE_100000baseSR4_Full_BIT,
2887         ETHTOOL_LINK_MODE_100000baseCR4_Full_BIT,
2888         ETHTOOL_LINK_MODE_100000baseLR4_ER4_Full_BIT,
2889 };
2890
2891 #define MLXSW_SP2_MASK_ETHTOOL_CAUI_4_100GBASE_CR4_KR4_LEN \
2892         ARRAY_SIZE(mlxsw_sp2_mask_ethtool_caui_4_100gbase_cr4_kr4)
2893
2894 static const enum ethtool_link_mode_bit_indices
2895 mlxsw_sp2_mask_ethtool_100gaui_2_100gbase_cr2_kr2[] = {
2896         ETHTOOL_LINK_MODE_100000baseKR2_Full_BIT,
2897         ETHTOOL_LINK_MODE_100000baseSR2_Full_BIT,
2898         ETHTOOL_LINK_MODE_100000baseCR2_Full_BIT,
2899         ETHTOOL_LINK_MODE_100000baseLR2_ER2_FR2_Full_BIT,
2900         ETHTOOL_LINK_MODE_100000baseDR2_Full_BIT,
2901 };
2902
2903 #define MLXSW_SP2_MASK_ETHTOOL_100GAUI_2_100GBASE_CR2_KR2_LEN \
2904         ARRAY_SIZE(mlxsw_sp2_mask_ethtool_100gaui_2_100gbase_cr2_kr2)
2905
2906 static const enum ethtool_link_mode_bit_indices
2907 mlxsw_sp2_mask_ethtool_200gaui_4_200gbase_cr4_kr4[] = {
2908         ETHTOOL_LINK_MODE_200000baseKR4_Full_BIT,
2909         ETHTOOL_LINK_MODE_200000baseSR4_Full_BIT,
2910         ETHTOOL_LINK_MODE_200000baseLR4_ER4_FR4_Full_BIT,
2911         ETHTOOL_LINK_MODE_200000baseDR4_Full_BIT,
2912         ETHTOOL_LINK_MODE_200000baseCR4_Full_BIT,
2913 };
2914
2915 #define MLXSW_SP2_MASK_ETHTOOL_200GAUI_4_200GBASE_CR4_KR4_LEN \
2916         ARRAY_SIZE(mlxsw_sp2_mask_ethtool_200gaui_4_200gbase_cr4_kr4)
2917
2918 struct mlxsw_sp2_port_link_mode {
2919         const enum ethtool_link_mode_bit_indices *mask_ethtool;
2920         int m_ethtool_len;
2921         u32 mask;
2922         u32 speed;
2923 };
2924
2925 static const struct mlxsw_sp2_port_link_mode mlxsw_sp2_port_link_mode[] = {
2926         {
2927                 .mask           = MLXSW_REG_PTYS_EXT_ETH_SPEED_SGMII_100M,
2928                 .mask_ethtool   = mlxsw_sp2_mask_ethtool_sgmii_100m,
2929                 .m_ethtool_len  = MLXSW_SP2_MASK_ETHTOOL_SGMII_100M_LEN,
2930                 .speed          = SPEED_100,
2931         },
2932         {
2933                 .mask           = MLXSW_REG_PTYS_EXT_ETH_SPEED_1000BASE_X_SGMII,
2934                 .mask_ethtool   = mlxsw_sp2_mask_ethtool_1000base_x_sgmii,
2935                 .m_ethtool_len  = MLXSW_SP2_MASK_ETHTOOL_1000BASE_X_SGMII_LEN,
2936                 .speed          = SPEED_1000,
2937         },
2938         {
2939                 .mask           = MLXSW_REG_PTYS_EXT_ETH_SPEED_2_5GBASE_X_2_5GMII,
2940                 .mask_ethtool   = mlxsw_sp2_mask_ethtool_2_5gbase_x_2_5gmii,
2941                 .m_ethtool_len  = MLXSW_SP2_MASK_ETHTOOL_2_5GBASE_X_2_5GMII_LEN,
2942                 .speed          = SPEED_2500,
2943         },
2944         {
2945                 .mask           = MLXSW_REG_PTYS_EXT_ETH_SPEED_5GBASE_R,
2946                 .mask_ethtool   = mlxsw_sp2_mask_ethtool_5gbase_r,
2947                 .m_ethtool_len  = MLXSW_SP2_MASK_ETHTOOL_5GBASE_R_LEN,
2948                 .speed          = SPEED_5000,
2949         },
2950         {
2951                 .mask           = MLXSW_REG_PTYS_EXT_ETH_SPEED_XFI_XAUI_1_10G,
2952                 .mask_ethtool   = mlxsw_sp2_mask_ethtool_xfi_xaui_1_10g,
2953                 .m_ethtool_len  = MLXSW_SP2_MASK_ETHTOOL_XFI_XAUI_1_10G_LEN,
2954                 .speed          = SPEED_10000,
2955         },
2956         {
2957                 .mask           = MLXSW_REG_PTYS_EXT_ETH_SPEED_XLAUI_4_XLPPI_4_40G,
2958                 .mask_ethtool   = mlxsw_sp2_mask_ethtool_xlaui_4_xlppi_4_40g,
2959                 .m_ethtool_len  = MLXSW_SP2_MASK_ETHTOOL_XLAUI_4_XLPPI_4_40G_LEN,
2960                 .speed          = SPEED_40000,
2961         },
2962         {
2963                 .mask           = MLXSW_REG_PTYS_EXT_ETH_SPEED_25GAUI_1_25GBASE_CR_KR,
2964                 .mask_ethtool   = mlxsw_sp2_mask_ethtool_25gaui_1_25gbase_cr_kr,
2965                 .m_ethtool_len  = MLXSW_SP2_MASK_ETHTOOL_25GAUI_1_25GBASE_CR_KR_LEN,
2966                 .speed          = SPEED_25000,
2967         },
2968         {
2969                 .mask           = MLXSW_REG_PTYS_EXT_ETH_SPEED_50GAUI_2_LAUI_2_50GBASE_CR2_KR2,
2970                 .mask_ethtool   = mlxsw_sp2_mask_ethtool_50gaui_2_laui_2_50gbase_cr2_kr2,
2971                 .m_ethtool_len  = MLXSW_SP2_MASK_ETHTOOL_50GAUI_2_LAUI_2_50GBASE_CR2_KR2_LEN,
2972                 .speed          = SPEED_50000,
2973         },
2974         {
2975                 .mask           = MLXSW_REG_PTYS_EXT_ETH_SPEED_50GAUI_1_LAUI_1_50GBASE_CR_KR,
2976                 .mask_ethtool   = mlxsw_sp2_mask_ethtool_50gaui_1_laui_1_50gbase_cr_kr,
2977                 .m_ethtool_len  = MLXSW_SP2_MASK_ETHTOOL_50GAUI_1_LAUI_1_50GBASE_CR_KR_LEN,
2978                 .speed          = SPEED_50000,
2979         },
2980         {
2981                 .mask           = MLXSW_REG_PTYS_EXT_ETH_SPEED_CAUI_4_100GBASE_CR4_KR4,
2982                 .mask_ethtool   = mlxsw_sp2_mask_ethtool_caui_4_100gbase_cr4_kr4,
2983                 .m_ethtool_len  = MLXSW_SP2_MASK_ETHTOOL_CAUI_4_100GBASE_CR4_KR4_LEN,
2984                 .speed          = SPEED_100000,
2985         },
2986         {
2987                 .mask           = MLXSW_REG_PTYS_EXT_ETH_SPEED_100GAUI_2_100GBASE_CR2_KR2,
2988                 .mask_ethtool   = mlxsw_sp2_mask_ethtool_100gaui_2_100gbase_cr2_kr2,
2989                 .m_ethtool_len  = MLXSW_SP2_MASK_ETHTOOL_100GAUI_2_100GBASE_CR2_KR2_LEN,
2990                 .speed          = SPEED_100000,
2991         },
2992         {
2993                 .mask           = MLXSW_REG_PTYS_EXT_ETH_SPEED_200GAUI_4_200GBASE_CR4_KR4,
2994                 .mask_ethtool   = mlxsw_sp2_mask_ethtool_200gaui_4_200gbase_cr4_kr4,
2995                 .m_ethtool_len  = MLXSW_SP2_MASK_ETHTOOL_200GAUI_4_200GBASE_CR4_KR4_LEN,
2996                 .speed          = SPEED_200000,
2997         },
2998 };
2999
3000 #define MLXSW_SP2_PORT_LINK_MODE_LEN ARRAY_SIZE(mlxsw_sp2_port_link_mode)
3001
3002 static void
3003 mlxsw_sp2_from_ptys_supported_port(struct mlxsw_sp *mlxsw_sp,
3004                                    u32 ptys_eth_proto,
3005                                    struct ethtool_link_ksettings *cmd)
3006 {
3007         ethtool_link_ksettings_add_link_mode(cmd, supported, FIBRE);
3008         ethtool_link_ksettings_add_link_mode(cmd, supported, Backplane);
3009 }
3010
3011 static void
3012 mlxsw_sp2_set_bit_ethtool(const struct mlxsw_sp2_port_link_mode *link_mode,
3013                           unsigned long *mode)
3014 {
3015         int i;
3016
3017         for (i = 0; i < link_mode->m_ethtool_len; i++)
3018                 __set_bit(link_mode->mask_ethtool[i], mode);
3019 }
3020
3021 static void
3022 mlxsw_sp2_from_ptys_link(struct mlxsw_sp *mlxsw_sp, u32 ptys_eth_proto,
3023                          unsigned long *mode)
3024 {
3025         int i;
3026
3027         for (i = 0; i < MLXSW_SP2_PORT_LINK_MODE_LEN; i++) {
3028                 if (ptys_eth_proto & mlxsw_sp2_port_link_mode[i].mask)
3029                         mlxsw_sp2_set_bit_ethtool(&mlxsw_sp2_port_link_mode[i],
3030                                                   mode);
3031         }
3032 }
3033
3034 static u32
3035 mlxsw_sp2_from_ptys_speed(struct mlxsw_sp *mlxsw_sp, u32 ptys_eth_proto)
3036 {
3037         int i;
3038
3039         for (i = 0; i < MLXSW_SP2_PORT_LINK_MODE_LEN; i++) {
3040                 if (ptys_eth_proto & mlxsw_sp2_port_link_mode[i].mask)
3041                         return mlxsw_sp2_port_link_mode[i].speed;
3042         }
3043
3044         return SPEED_UNKNOWN;
3045 }
3046
3047 static void
3048 mlxsw_sp2_from_ptys_speed_duplex(struct mlxsw_sp *mlxsw_sp, bool carrier_ok,
3049                                  u32 ptys_eth_proto,
3050                                  struct ethtool_link_ksettings *cmd)
3051 {
3052         cmd->base.speed = SPEED_UNKNOWN;
3053         cmd->base.duplex = DUPLEX_UNKNOWN;
3054
3055         if (!carrier_ok)
3056                 return;
3057
3058         cmd->base.speed = mlxsw_sp2_from_ptys_speed(mlxsw_sp, ptys_eth_proto);
3059         if (cmd->base.speed != SPEED_UNKNOWN)
3060                 cmd->base.duplex = DUPLEX_FULL;
3061 }
3062
3063 static bool
3064 mlxsw_sp2_test_bit_ethtool(const struct mlxsw_sp2_port_link_mode *link_mode,
3065                            const unsigned long *mode)
3066 {
3067         int cnt = 0;
3068         int i;
3069
3070         for (i = 0; i < link_mode->m_ethtool_len; i++) {
3071                 if (test_bit(link_mode->mask_ethtool[i], mode))
3072                         cnt++;
3073         }
3074
3075         return cnt == link_mode->m_ethtool_len;
3076 }
3077
3078 static u32
3079 mlxsw_sp2_to_ptys_advert_link(struct mlxsw_sp *mlxsw_sp,
3080                               const struct ethtool_link_ksettings *cmd)
3081 {
3082         u32 ptys_proto = 0;
3083         int i;
3084
3085         for (i = 0; i < MLXSW_SP2_PORT_LINK_MODE_LEN; i++) {
3086                 if (mlxsw_sp2_test_bit_ethtool(&mlxsw_sp2_port_link_mode[i],
3087                                                cmd->link_modes.advertising))
3088                         ptys_proto |= mlxsw_sp2_port_link_mode[i].mask;
3089         }
3090         return ptys_proto;
3091 }
3092
3093 static u32 mlxsw_sp2_to_ptys_speed(struct mlxsw_sp *mlxsw_sp, u32 speed)
3094 {
3095         u32 ptys_proto = 0;
3096         int i;
3097
3098         for (i = 0; i < MLXSW_SP2_PORT_LINK_MODE_LEN; i++) {
3099                 if (speed == mlxsw_sp2_port_link_mode[i].speed)
3100                         ptys_proto |= mlxsw_sp2_port_link_mode[i].mask;
3101         }
3102         return ptys_proto;
3103 }
3104
3105 static u32
3106 mlxsw_sp2_to_ptys_upper_speed(struct mlxsw_sp *mlxsw_sp, u32 upper_speed)
3107 {
3108         u32 ptys_proto = 0;
3109         int i;
3110
3111         for (i = 0; i < MLXSW_SP2_PORT_LINK_MODE_LEN; i++) {
3112                 if (mlxsw_sp2_port_link_mode[i].speed <= upper_speed)
3113                         ptys_proto |= mlxsw_sp2_port_link_mode[i].mask;
3114         }
3115         return ptys_proto;
3116 }
3117
3118 static int
3119 mlxsw_sp2_port_speed_base(struct mlxsw_sp *mlxsw_sp, u8 local_port,
3120                           u32 *base_speed)
3121 {
3122         char ptys_pl[MLXSW_REG_PTYS_LEN];
3123         u32 eth_proto_cap;
3124         int err;
3125
3126         /* In Spectrum-2, the speed of 1x can change from port to port, so query
3127          * it from firmware.
3128          */
3129         mlxsw_reg_ptys_ext_eth_pack(ptys_pl, local_port, 0, false);
3130         err = mlxsw_reg_query(mlxsw_sp->core, MLXSW_REG(ptys), ptys_pl);
3131         if (err)
3132                 return err;
3133         mlxsw_reg_ptys_ext_eth_unpack(ptys_pl, &eth_proto_cap, NULL, NULL);
3134
3135         if (eth_proto_cap &
3136             MLXSW_REG_PTYS_EXT_ETH_SPEED_50GAUI_1_LAUI_1_50GBASE_CR_KR) {
3137                 *base_speed = MLXSW_SP_PORT_BASE_SPEED_50G;
3138                 return 0;
3139         }
3140
3141         if (eth_proto_cap &
3142             MLXSW_REG_PTYS_EXT_ETH_SPEED_25GAUI_1_25GBASE_CR_KR) {
3143                 *base_speed = MLXSW_SP_PORT_BASE_SPEED_25G;
3144                 return 0;
3145         }
3146
3147         return -EIO;
3148 }
3149
3150 static void
3151 mlxsw_sp2_reg_ptys_eth_pack(struct mlxsw_sp *mlxsw_sp, char *payload,
3152                             u8 local_port, u32 proto_admin,
3153                             bool autoneg)
3154 {
3155         mlxsw_reg_ptys_ext_eth_pack(payload, local_port, proto_admin, autoneg);
3156 }
3157
3158 static void
3159 mlxsw_sp2_reg_ptys_eth_unpack(struct mlxsw_sp *mlxsw_sp, char *payload,
3160                               u32 *p_eth_proto_cap, u32 *p_eth_proto_admin,
3161                               u32 *p_eth_proto_oper)
3162 {
3163         mlxsw_reg_ptys_ext_eth_unpack(payload, p_eth_proto_cap,
3164                                       p_eth_proto_admin, p_eth_proto_oper);
3165 }
3166
3167 static const struct mlxsw_sp_port_type_speed_ops
3168 mlxsw_sp2_port_type_speed_ops = {
3169         .from_ptys_supported_port       = mlxsw_sp2_from_ptys_supported_port,
3170         .from_ptys_link                 = mlxsw_sp2_from_ptys_link,
3171         .from_ptys_speed                = mlxsw_sp2_from_ptys_speed,
3172         .from_ptys_speed_duplex         = mlxsw_sp2_from_ptys_speed_duplex,
3173         .to_ptys_advert_link            = mlxsw_sp2_to_ptys_advert_link,
3174         .to_ptys_speed                  = mlxsw_sp2_to_ptys_speed,
3175         .to_ptys_upper_speed            = mlxsw_sp2_to_ptys_upper_speed,
3176         .port_speed_base                = mlxsw_sp2_port_speed_base,
3177         .reg_ptys_eth_pack              = mlxsw_sp2_reg_ptys_eth_pack,
3178         .reg_ptys_eth_unpack            = mlxsw_sp2_reg_ptys_eth_unpack,
3179 };
3180
3181 static void
3182 mlxsw_sp_port_get_link_supported(struct mlxsw_sp *mlxsw_sp, u32 eth_proto_cap,
3183                                  struct ethtool_link_ksettings *cmd)
3184 {
3185         const struct mlxsw_sp_port_type_speed_ops *ops;
3186
3187         ops = mlxsw_sp->port_type_speed_ops;
3188
3189         ethtool_link_ksettings_add_link_mode(cmd, supported, Asym_Pause);
3190         ethtool_link_ksettings_add_link_mode(cmd, supported, Autoneg);
3191         ethtool_link_ksettings_add_link_mode(cmd, supported, Pause);
3192
3193         ops->from_ptys_supported_port(mlxsw_sp, eth_proto_cap, cmd);
3194         ops->from_ptys_link(mlxsw_sp, eth_proto_cap, cmd->link_modes.supported);
3195 }
3196
3197 static void
3198 mlxsw_sp_port_get_link_advertise(struct mlxsw_sp *mlxsw_sp,
3199                                  u32 eth_proto_admin, bool autoneg,
3200                                  struct ethtool_link_ksettings *cmd)
3201 {
3202         const struct mlxsw_sp_port_type_speed_ops *ops;
3203
3204         ops = mlxsw_sp->port_type_speed_ops;
3205
3206         if (!autoneg)
3207                 return;
3208
3209         ethtool_link_ksettings_add_link_mode(cmd, advertising, Autoneg);
3210         ops->from_ptys_link(mlxsw_sp, eth_proto_admin,
3211                             cmd->link_modes.advertising);
3212 }
3213
3214 static u8
3215 mlxsw_sp_port_connector_port(enum mlxsw_reg_ptys_connector_type connector_type)
3216 {
3217         switch (connector_type) {
3218         case MLXSW_REG_PTYS_CONNECTOR_TYPE_UNKNOWN_OR_NO_CONNECTOR:
3219                 return PORT_OTHER;
3220         case MLXSW_REG_PTYS_CONNECTOR_TYPE_PORT_NONE:
3221                 return PORT_NONE;
3222         case MLXSW_REG_PTYS_CONNECTOR_TYPE_PORT_TP:
3223                 return PORT_TP;
3224         case MLXSW_REG_PTYS_CONNECTOR_TYPE_PORT_AUI:
3225                 return PORT_AUI;
3226         case MLXSW_REG_PTYS_CONNECTOR_TYPE_PORT_BNC:
3227                 return PORT_BNC;
3228         case MLXSW_REG_PTYS_CONNECTOR_TYPE_PORT_MII:
3229                 return PORT_MII;
3230         case MLXSW_REG_PTYS_CONNECTOR_TYPE_PORT_FIBRE:
3231                 return PORT_FIBRE;
3232         case MLXSW_REG_PTYS_CONNECTOR_TYPE_PORT_DA:
3233                 return PORT_DA;
3234         case MLXSW_REG_PTYS_CONNECTOR_TYPE_PORT_OTHER:
3235                 return PORT_OTHER;
3236         default:
3237                 WARN_ON_ONCE(1);
3238                 return PORT_OTHER;
3239         }
3240 }
3241
3242 static int mlxsw_sp_port_get_link_ksettings(struct net_device *dev,
3243                                             struct ethtool_link_ksettings *cmd)
3244 {
3245         u32 eth_proto_cap, eth_proto_admin, eth_proto_oper;
3246         struct mlxsw_sp_port *mlxsw_sp_port = netdev_priv(dev);
3247         struct mlxsw_sp *mlxsw_sp = mlxsw_sp_port->mlxsw_sp;
3248         const struct mlxsw_sp_port_type_speed_ops *ops;
3249         char ptys_pl[MLXSW_REG_PTYS_LEN];
3250         u8 connector_type;
3251         bool autoneg;
3252         int err;
3253
3254         ops = mlxsw_sp->port_type_speed_ops;
3255
3256         autoneg = mlxsw_sp_port->link.autoneg;
3257         ops->reg_ptys_eth_pack(mlxsw_sp, ptys_pl, mlxsw_sp_port->local_port,
3258                                0, false);
3259         err = mlxsw_reg_query(mlxsw_sp->core, MLXSW_REG(ptys), ptys_pl);
3260         if (err)
3261                 return err;
3262         ops->reg_ptys_eth_unpack(mlxsw_sp, ptys_pl, &eth_proto_cap,
3263                                  &eth_proto_admin, &eth_proto_oper);
3264
3265         mlxsw_sp_port_get_link_supported(mlxsw_sp, eth_proto_cap, cmd);
3266
3267         mlxsw_sp_port_get_link_advertise(mlxsw_sp, eth_proto_admin, autoneg,
3268                                          cmd);
3269
3270         cmd->base.autoneg = autoneg ? AUTONEG_ENABLE : AUTONEG_DISABLE;
3271         connector_type = mlxsw_reg_ptys_connector_type_get(ptys_pl);
3272         cmd->base.port = mlxsw_sp_port_connector_port(connector_type);
3273         ops->from_ptys_speed_duplex(mlxsw_sp, netif_carrier_ok(dev),
3274                                     eth_proto_oper, cmd);
3275
3276         return 0;
3277 }
3278
3279 static int
3280 mlxsw_sp_port_set_link_ksettings(struct net_device *dev,
3281                                  const struct ethtool_link_ksettings *cmd)
3282 {
3283         struct mlxsw_sp_port *mlxsw_sp_port = netdev_priv(dev);
3284         struct mlxsw_sp *mlxsw_sp = mlxsw_sp_port->mlxsw_sp;
3285         const struct mlxsw_sp_port_type_speed_ops *ops;
3286         char ptys_pl[MLXSW_REG_PTYS_LEN];
3287         u32 eth_proto_cap, eth_proto_new;
3288         bool autoneg;
3289         int err;
3290
3291         ops = mlxsw_sp->port_type_speed_ops;
3292
3293         ops->reg_ptys_eth_pack(mlxsw_sp, ptys_pl, mlxsw_sp_port->local_port,
3294                                0, false);
3295         err = mlxsw_reg_query(mlxsw_sp->core, MLXSW_REG(ptys), ptys_pl);
3296         if (err)
3297                 return err;
3298         ops->reg_ptys_eth_unpack(mlxsw_sp, ptys_pl, &eth_proto_cap, NULL, NULL);
3299
3300         autoneg = cmd->base.autoneg == AUTONEG_ENABLE;
3301         if (!autoneg && cmd->base.speed == SPEED_56000) {
3302                 netdev_err(dev, "56G not supported with autoneg off\n");
3303                 return -EINVAL;
3304         }
3305         eth_proto_new = autoneg ?
3306                 ops->to_ptys_advert_link(mlxsw_sp, cmd) :
3307                 ops->to_ptys_speed(mlxsw_sp, cmd->base.speed);
3308
3309         eth_proto_new = eth_proto_new & eth_proto_cap;
3310         if (!eth_proto_new) {
3311                 netdev_err(dev, "No supported speed requested\n");
3312                 return -EINVAL;
3313         }
3314
3315         ops->reg_ptys_eth_pack(mlxsw_sp, ptys_pl, mlxsw_sp_port->local_port,
3316                                eth_proto_new, autoneg);
3317         err = mlxsw_reg_write(mlxsw_sp->core, MLXSW_REG(ptys), ptys_pl);
3318         if (err)
3319                 return err;
3320
3321         mlxsw_sp_port->link.autoneg = autoneg;
3322
3323         if (!netif_running(dev))
3324                 return 0;
3325
3326         mlxsw_sp_port_admin_status_set(mlxsw_sp_port, false);
3327         mlxsw_sp_port_admin_status_set(mlxsw_sp_port, true);
3328
3329         return 0;
3330 }
3331
3332 static int mlxsw_sp_get_module_info(struct net_device *netdev,
3333                                     struct ethtool_modinfo *modinfo)
3334 {
3335         struct mlxsw_sp_port *mlxsw_sp_port = netdev_priv(netdev);
3336         struct mlxsw_sp *mlxsw_sp = mlxsw_sp_port->mlxsw_sp;
3337         int err;
3338
3339         err = mlxsw_env_get_module_info(mlxsw_sp->core,
3340                                         mlxsw_sp_port->mapping.module,
3341                                         modinfo);
3342
3343         return err;
3344 }
3345
3346 static int mlxsw_sp_get_module_eeprom(struct net_device *netdev,
3347                                       struct ethtool_eeprom *ee,
3348                                       u8 *data)
3349 {
3350         struct mlxsw_sp_port *mlxsw_sp_port = netdev_priv(netdev);
3351         struct mlxsw_sp *mlxsw_sp = mlxsw_sp_port->mlxsw_sp;
3352         int err;
3353
3354         err = mlxsw_env_get_module_eeprom(netdev, mlxsw_sp->core,
3355                                           mlxsw_sp_port->mapping.module, ee,
3356                                           data);
3357
3358         return err;
3359 }
3360
3361 static int
3362 mlxsw_sp_get_ts_info(struct net_device *netdev, struct ethtool_ts_info *info)
3363 {
3364         struct mlxsw_sp_port *mlxsw_sp_port = netdev_priv(netdev);
3365         struct mlxsw_sp *mlxsw_sp = mlxsw_sp_port->mlxsw_sp;
3366
3367         return mlxsw_sp->ptp_ops->get_ts_info(mlxsw_sp, info);
3368 }
3369
3370 static const struct ethtool_ops mlxsw_sp_port_ethtool_ops = {
3371         .get_drvinfo            = mlxsw_sp_port_get_drvinfo,
3372         .get_link               = ethtool_op_get_link,
3373         .get_pauseparam         = mlxsw_sp_port_get_pauseparam,
3374         .set_pauseparam         = mlxsw_sp_port_set_pauseparam,
3375         .get_strings            = mlxsw_sp_port_get_strings,
3376         .set_phys_id            = mlxsw_sp_port_set_phys_id,
3377         .get_ethtool_stats      = mlxsw_sp_port_get_stats,
3378         .get_sset_count         = mlxsw_sp_port_get_sset_count,
3379         .get_link_ksettings     = mlxsw_sp_port_get_link_ksettings,
3380         .set_link_ksettings     = mlxsw_sp_port_set_link_ksettings,
3381         .get_module_info        = mlxsw_sp_get_module_info,
3382         .get_module_eeprom      = mlxsw_sp_get_module_eeprom,
3383         .get_ts_info            = mlxsw_sp_get_ts_info,
3384 };
3385
3386 static int
3387 mlxsw_sp_port_speed_by_width_set(struct mlxsw_sp_port *mlxsw_sp_port, u8 width)
3388 {
3389         struct mlxsw_sp *mlxsw_sp = mlxsw_sp_port->mlxsw_sp;
3390         const struct mlxsw_sp_port_type_speed_ops *ops;
3391         char ptys_pl[MLXSW_REG_PTYS_LEN];
3392         u32 eth_proto_admin;
3393         u32 upper_speed;
3394         u32 base_speed;
3395         int err;
3396
3397         ops = mlxsw_sp->port_type_speed_ops;
3398
3399         err = ops->port_speed_base(mlxsw_sp, mlxsw_sp_port->local_port,
3400                                    &base_speed);
3401         if (err)
3402                 return err;
3403         upper_speed = base_speed * width;
3404
3405         eth_proto_admin = ops->to_ptys_upper_speed(mlxsw_sp, upper_speed);
3406         ops->reg_ptys_eth_pack(mlxsw_sp, ptys_pl, mlxsw_sp_port->local_port,
3407                                eth_proto_admin, mlxsw_sp_port->link.autoneg);
3408         return mlxsw_reg_write(mlxsw_sp->core, MLXSW_REG(ptys), ptys_pl);
3409 }
3410
3411 int mlxsw_sp_port_ets_set(struct mlxsw_sp_port *mlxsw_sp_port,
3412                           enum mlxsw_reg_qeec_hr hr, u8 index, u8 next_index,
3413                           bool dwrr, u8 dwrr_weight)
3414 {
3415         struct mlxsw_sp *mlxsw_sp = mlxsw_sp_port->mlxsw_sp;
3416         char qeec_pl[MLXSW_REG_QEEC_LEN];
3417
3418         mlxsw_reg_qeec_pack(qeec_pl, mlxsw_sp_port->local_port, hr, index,
3419                             next_index);
3420         mlxsw_reg_qeec_de_set(qeec_pl, true);
3421         mlxsw_reg_qeec_dwrr_set(qeec_pl, dwrr);
3422         mlxsw_reg_qeec_dwrr_weight_set(qeec_pl, dwrr_weight);
3423         return mlxsw_reg_write(mlxsw_sp->core, MLXSW_REG(qeec), qeec_pl);
3424 }
3425
3426 int mlxsw_sp_port_ets_maxrate_set(struct mlxsw_sp_port *mlxsw_sp_port,
3427                                   enum mlxsw_reg_qeec_hr hr, u8 index,
3428                                   u8 next_index, u32 maxrate)
3429 {
3430         struct mlxsw_sp *mlxsw_sp = mlxsw_sp_port->mlxsw_sp;
3431         char qeec_pl[MLXSW_REG_QEEC_LEN];
3432
3433         mlxsw_reg_qeec_pack(qeec_pl, mlxsw_sp_port->local_port, hr, index,
3434                             next_index);
3435         mlxsw_reg_qeec_mase_set(qeec_pl, true);
3436         mlxsw_reg_qeec_max_shaper_rate_set(qeec_pl, maxrate);
3437         return mlxsw_reg_write(mlxsw_sp->core, MLXSW_REG(qeec), qeec_pl);
3438 }
3439
3440 static int mlxsw_sp_port_min_bw_set(struct mlxsw_sp_port *mlxsw_sp_port,
3441                                     enum mlxsw_reg_qeec_hr hr, u8 index,
3442                                     u8 next_index, u32 minrate)
3443 {
3444         struct mlxsw_sp *mlxsw_sp = mlxsw_sp_port->mlxsw_sp;
3445         char qeec_pl[MLXSW_REG_QEEC_LEN];
3446
3447         mlxsw_reg_qeec_pack(qeec_pl, mlxsw_sp_port->local_port, hr, index,
3448                             next_index);
3449         mlxsw_reg_qeec_mise_set(qeec_pl, true);
3450         mlxsw_reg_qeec_min_shaper_rate_set(qeec_pl, minrate);
3451
3452         return mlxsw_reg_write(mlxsw_sp->core, MLXSW_REG(qeec), qeec_pl);
3453 }
3454
3455 int mlxsw_sp_port_prio_tc_set(struct mlxsw_sp_port *mlxsw_sp_port,
3456                               u8 switch_prio, u8 tclass)
3457 {
3458         struct mlxsw_sp *mlxsw_sp = mlxsw_sp_port->mlxsw_sp;
3459         char qtct_pl[MLXSW_REG_QTCT_LEN];
3460
3461         mlxsw_reg_qtct_pack(qtct_pl, mlxsw_sp_port->local_port, switch_prio,
3462                             tclass);
3463         return mlxsw_reg_write(mlxsw_sp->core, MLXSW_REG(qtct), qtct_pl);
3464 }
3465
3466 static int mlxsw_sp_port_ets_init(struct mlxsw_sp_port *mlxsw_sp_port)
3467 {
3468         int err, i;
3469
3470         /* Setup the elements hierarcy, so that each TC is linked to
3471          * one subgroup, which are all member in the same group.
3472          */
3473         err = mlxsw_sp_port_ets_set(mlxsw_sp_port,
3474                                     MLXSW_REG_QEEC_HIERARCY_GROUP, 0, 0, false,
3475                                     0);
3476         if (err)
3477                 return err;
3478         for (i = 0; i < IEEE_8021QAZ_MAX_TCS; i++) {
3479                 err = mlxsw_sp_port_ets_set(mlxsw_sp_port,
3480                                             MLXSW_REG_QEEC_HIERARCY_SUBGROUP, i,
3481                                             0, false, 0);
3482                 if (err)
3483                         return err;
3484         }
3485         for (i = 0; i < IEEE_8021QAZ_MAX_TCS; i++) {
3486                 err = mlxsw_sp_port_ets_set(mlxsw_sp_port,
3487                                             MLXSW_REG_QEEC_HIERARCY_TC, i, i,
3488                                             false, 0);
3489                 if (err)
3490                         return err;
3491
3492                 err = mlxsw_sp_port_ets_set(mlxsw_sp_port,
3493                                             MLXSW_REG_QEEC_HIERARCY_TC,
3494                                             i + 8, i,
3495                                             true, 100);
3496                 if (err)
3497                         return err;
3498         }
3499
3500         /* Make sure the max shaper is disabled in all hierarchies that support
3501          * it. Note that this disables ptps (PTP shaper), but that is intended
3502          * for the initial configuration.
3503          */
3504         err = mlxsw_sp_port_ets_maxrate_set(mlxsw_sp_port,
3505                                             MLXSW_REG_QEEC_HIERARCY_PORT, 0, 0,
3506                                             MLXSW_REG_QEEC_MAS_DIS);
3507         if (err)
3508                 return err;
3509         for (i = 0; i < IEEE_8021QAZ_MAX_TCS; i++) {
3510                 err = mlxsw_sp_port_ets_maxrate_set(mlxsw_sp_port,
3511                                                     MLXSW_REG_QEEC_HIERARCY_SUBGROUP,
3512                                                     i, 0,
3513                                                     MLXSW_REG_QEEC_MAS_DIS);
3514                 if (err)
3515                         return err;
3516         }
3517         for (i = 0; i < IEEE_8021QAZ_MAX_TCS; i++) {
3518                 err = mlxsw_sp_port_ets_maxrate_set(mlxsw_sp_port,
3519                                                     MLXSW_REG_QEEC_HIERARCY_TC,
3520                                                     i, i,
3521                                                     MLXSW_REG_QEEC_MAS_DIS);
3522                 if (err)
3523                         return err;
3524
3525                 err = mlxsw_sp_port_ets_maxrate_set(mlxsw_sp_port,
3526                                                     MLXSW_REG_QEEC_HIERARCY_TC,
3527                                                     i + 8, i,
3528                                                     MLXSW_REG_QEEC_MAS_DIS);
3529                 if (err)
3530                         return err;
3531         }
3532
3533         /* Configure the min shaper for multicast TCs. */
3534         for (i = 0; i < IEEE_8021QAZ_MAX_TCS; i++) {
3535                 err = mlxsw_sp_port_min_bw_set(mlxsw_sp_port,
3536                                                MLXSW_REG_QEEC_HIERARCY_TC,
3537                                                i + 8, i,
3538                                                MLXSW_REG_QEEC_MIS_MIN);
3539                 if (err)
3540                         return err;
3541         }
3542
3543         /* Map all priorities to traffic class 0. */
3544         for (i = 0; i < IEEE_8021QAZ_MAX_TCS; i++) {
3545                 err = mlxsw_sp_port_prio_tc_set(mlxsw_sp_port, i, 0);
3546                 if (err)
3547                         return err;
3548         }
3549
3550         return 0;
3551 }
3552
3553 static int mlxsw_sp_port_tc_mc_mode_set(struct mlxsw_sp_port *mlxsw_sp_port,
3554                                         bool enable)
3555 {
3556         struct mlxsw_sp *mlxsw_sp = mlxsw_sp_port->mlxsw_sp;
3557         char qtctm_pl[MLXSW_REG_QTCTM_LEN];
3558
3559         mlxsw_reg_qtctm_pack(qtctm_pl, mlxsw_sp_port->local_port, enable);
3560         return mlxsw_reg_write(mlxsw_sp->core, MLXSW_REG(qtctm), qtctm_pl);
3561 }
3562
3563 static int mlxsw_sp_port_create(struct mlxsw_sp *mlxsw_sp, u8 local_port,
3564                                 bool split, u8 module, u8 width, u8 lane)
3565 {
3566         struct mlxsw_sp_port_vlan *mlxsw_sp_port_vlan;
3567         struct mlxsw_sp_port *mlxsw_sp_port;
3568         struct net_device *dev;
3569         int err;
3570
3571         err = mlxsw_core_port_init(mlxsw_sp->core, local_port,
3572                                    module + 1, split, lane / width,
3573                                    mlxsw_sp->base_mac,
3574                                    sizeof(mlxsw_sp->base_mac));
3575         if (err) {
3576                 dev_err(mlxsw_sp->bus_info->dev, "Port %d: Failed to init core port\n",
3577                         local_port);
3578                 return err;
3579         }
3580
3581         dev = alloc_etherdev(sizeof(struct mlxsw_sp_port));
3582         if (!dev) {
3583                 err = -ENOMEM;
3584                 goto err_alloc_etherdev;
3585         }
3586         SET_NETDEV_DEV(dev, mlxsw_sp->bus_info->dev);
3587         mlxsw_sp_port = netdev_priv(dev);
3588         mlxsw_sp_port->dev = dev;
3589         mlxsw_sp_port->mlxsw_sp = mlxsw_sp;
3590         mlxsw_sp_port->local_port = local_port;
3591         mlxsw_sp_port->pvid = MLXSW_SP_DEFAULT_VID;
3592         mlxsw_sp_port->split = split;
3593         mlxsw_sp_port->mapping.module = module;
3594         mlxsw_sp_port->mapping.width = width;
3595         mlxsw_sp_port->mapping.lane = lane;
3596         mlxsw_sp_port->link.autoneg = 1;
3597         INIT_LIST_HEAD(&mlxsw_sp_port->vlans_list);
3598         INIT_LIST_HEAD(&mlxsw_sp_port->mall_tc_list);
3599
3600         mlxsw_sp_port->pcpu_stats =
3601                 netdev_alloc_pcpu_stats(struct mlxsw_sp_port_pcpu_stats);
3602         if (!mlxsw_sp_port->pcpu_stats) {
3603                 err = -ENOMEM;
3604                 goto err_alloc_stats;
3605         }
3606
3607         mlxsw_sp_port->sample = kzalloc(sizeof(*mlxsw_sp_port->sample),
3608                                         GFP_KERNEL);
3609         if (!mlxsw_sp_port->sample) {
3610                 err = -ENOMEM;
3611                 goto err_alloc_sample;
3612         }
3613
3614         INIT_DELAYED_WORK(&mlxsw_sp_port->periodic_hw_stats.update_dw,
3615                           &update_stats_cache);
3616
3617         dev->netdev_ops = &mlxsw_sp_port_netdev_ops;
3618         dev->ethtool_ops = &mlxsw_sp_port_ethtool_ops;
3619
3620         err = mlxsw_sp_port_module_map(mlxsw_sp_port, module, width, lane);
3621         if (err) {
3622                 dev_err(mlxsw_sp->bus_info->dev, "Port %d: Failed to map module\n",
3623                         mlxsw_sp_port->local_port);
3624                 goto err_port_module_map;
3625         }
3626
3627         err = mlxsw_sp_port_swid_set(mlxsw_sp_port, 0);
3628         if (err) {
3629                 dev_err(mlxsw_sp->bus_info->dev, "Port %d: Failed to set SWID\n",
3630                         mlxsw_sp_port->local_port);
3631                 goto err_port_swid_set;
3632         }
3633
3634         err = mlxsw_sp_port_dev_addr_init(mlxsw_sp_port);
3635         if (err) {
3636                 dev_err(mlxsw_sp->bus_info->dev, "Port %d: Unable to init port mac address\n",
3637                         mlxsw_sp_port->local_port);
3638                 goto err_dev_addr_init;
3639         }
3640
3641         netif_carrier_off(dev);
3642
3643         dev->features |= NETIF_F_NETNS_LOCAL | NETIF_F_LLTX | NETIF_F_SG |
3644                          NETIF_F_HW_VLAN_CTAG_FILTER | NETIF_F_HW_TC;
3645         dev->hw_features |= NETIF_F_HW_TC | NETIF_F_LOOPBACK;
3646
3647         dev->min_mtu = 0;
3648         dev->max_mtu = ETH_MAX_MTU;
3649
3650         /* Each packet needs to have a Tx header (metadata) on top all other
3651          * headers.
3652          */
3653         dev->needed_headroom = MLXSW_TXHDR_LEN;
3654
3655         err = mlxsw_sp_port_system_port_mapping_set(mlxsw_sp_port);
3656         if (err) {
3657                 dev_err(mlxsw_sp->bus_info->dev, "Port %d: Failed to set system port mapping\n",
3658                         mlxsw_sp_port->local_port);
3659                 goto err_port_system_port_mapping_set;
3660         }
3661
3662         err = mlxsw_sp_port_speed_by_width_set(mlxsw_sp_port, width);
3663         if (err) {
3664                 dev_err(mlxsw_sp->bus_info->dev, "Port %d: Failed to enable speeds\n",
3665                         mlxsw_sp_port->local_port);
3666                 goto err_port_speed_by_width_set;
3667         }
3668
3669         err = mlxsw_sp_port_mtu_set(mlxsw_sp_port, ETH_DATA_LEN);
3670         if (err) {
3671                 dev_err(mlxsw_sp->bus_info->dev, "Port %d: Failed to set MTU\n",
3672                         mlxsw_sp_port->local_port);
3673                 goto err_port_mtu_set;
3674         }
3675
3676         err = mlxsw_sp_port_admin_status_set(mlxsw_sp_port, false);
3677         if (err)
3678                 goto err_port_admin_status_set;
3679
3680         err = mlxsw_sp_port_buffers_init(mlxsw_sp_port);
3681         if (err) {
3682                 dev_err(mlxsw_sp->bus_info->dev, "Port %d: Failed to initialize buffers\n",
3683                         mlxsw_sp_port->local_port);
3684                 goto err_port_buffers_init;
3685         }
3686
3687         err = mlxsw_sp_port_ets_init(mlxsw_sp_port);
3688         if (err) {
3689                 dev_err(mlxsw_sp->bus_info->dev, "Port %d: Failed to initialize ETS\n",
3690                         mlxsw_sp_port->local_port);
3691                 goto err_port_ets_init;
3692         }
3693
3694         err = mlxsw_sp_port_tc_mc_mode_set(mlxsw_sp_port, true);
3695         if (err) {
3696                 dev_err(mlxsw_sp->bus_info->dev, "Port %d: Failed to initialize TC MC mode\n",
3697                         mlxsw_sp_port->local_port);
3698                 goto err_port_tc_mc_mode;
3699         }
3700
3701         /* ETS and buffers must be initialized before DCB. */
3702         err = mlxsw_sp_port_dcb_init(mlxsw_sp_port);
3703         if (err) {
3704                 dev_err(mlxsw_sp->bus_info->dev, "Port %d: Failed to initialize DCB\n",
3705                         mlxsw_sp_port->local_port);
3706                 goto err_port_dcb_init;
3707         }
3708
3709         err = mlxsw_sp_port_fids_init(mlxsw_sp_port);
3710         if (err) {
3711                 dev_err(mlxsw_sp->bus_info->dev, "Port %d: Failed to initialize FIDs\n",
3712                         mlxsw_sp_port->local_port);
3713                 goto err_port_fids_init;
3714         }
3715
3716         err = mlxsw_sp_tc_qdisc_init(mlxsw_sp_port);
3717         if (err) {
3718                 dev_err(mlxsw_sp->bus_info->dev, "Port %d: Failed to initialize TC qdiscs\n",
3719                         mlxsw_sp_port->local_port);
3720                 goto err_port_qdiscs_init;
3721         }
3722
3723         err = mlxsw_sp_port_nve_init(mlxsw_sp_port);
3724         if (err) {
3725                 dev_err(mlxsw_sp->bus_info->dev, "Port %d: Failed to initialize NVE\n",
3726                         mlxsw_sp_port->local_port);
3727                 goto err_port_nve_init;
3728         }
3729
3730         err = mlxsw_sp_port_pvid_set(mlxsw_sp_port, MLXSW_SP_DEFAULT_VID);
3731         if (err) {
3732                 dev_err(mlxsw_sp->bus_info->dev, "Port %d: Failed to set PVID\n",
3733                         mlxsw_sp_port->local_port);
3734                 goto err_port_pvid_set;
3735         }
3736
3737         mlxsw_sp_port_vlan = mlxsw_sp_port_vlan_create(mlxsw_sp_port,
3738                                                        MLXSW_SP_DEFAULT_VID);
3739         if (IS_ERR(mlxsw_sp_port_vlan)) {
3740                 dev_err(mlxsw_sp->bus_info->dev, "Port %d: Failed to create VID 1\n",
3741                         mlxsw_sp_port->local_port);
3742                 err = PTR_ERR(mlxsw_sp_port_vlan);
3743                 goto err_port_vlan_create;
3744         }
3745         mlxsw_sp_port->default_vlan = mlxsw_sp_port_vlan;
3746
3747         INIT_DELAYED_WORK(&mlxsw_sp_port->ptp.shaper_dw,
3748                           mlxsw_sp->ptp_ops->shaper_work);
3749
3750         mlxsw_sp->ports[local_port] = mlxsw_sp_port;
3751         err = register_netdev(dev);
3752         if (err) {
3753                 dev_err(mlxsw_sp->bus_info->dev, "Port %d: Failed to register netdev\n",
3754                         mlxsw_sp_port->local_port);
3755                 goto err_register_netdev;
3756         }
3757
3758         mlxsw_core_port_eth_set(mlxsw_sp->core, mlxsw_sp_port->local_port,
3759                                 mlxsw_sp_port, dev);
3760         mlxsw_core_schedule_dw(&mlxsw_sp_port->periodic_hw_stats.update_dw, 0);
3761         return 0;
3762
3763 err_register_netdev:
3764         mlxsw_sp->ports[local_port] = NULL;
3765         mlxsw_sp_port_vlan_destroy(mlxsw_sp_port_vlan);
3766 err_port_vlan_create:
3767 err_port_pvid_set:
3768         mlxsw_sp_port_nve_fini(mlxsw_sp_port);
3769 err_port_nve_init:
3770         mlxsw_sp_tc_qdisc_fini(mlxsw_sp_port);
3771 err_port_qdiscs_init:
3772         mlxsw_sp_port_fids_fini(mlxsw_sp_port);
3773 err_port_fids_init:
3774         mlxsw_sp_port_dcb_fini(mlxsw_sp_port);
3775 err_port_dcb_init:
3776         mlxsw_sp_port_tc_mc_mode_set(mlxsw_sp_port, false);
3777 err_port_tc_mc_mode:
3778 err_port_ets_init:
3779 err_port_buffers_init:
3780 err_port_admin_status_set:
3781 err_port_mtu_set:
3782 err_port_speed_by_width_set:
3783 err_port_system_port_mapping_set:
3784 err_dev_addr_init:
3785         mlxsw_sp_port_swid_set(mlxsw_sp_port, MLXSW_PORT_SWID_DISABLED_PORT);
3786 err_port_swid_set:
3787         mlxsw_sp_port_module_unmap(mlxsw_sp_port);
3788 err_port_module_map:
3789         kfree(mlxsw_sp_port->sample);
3790 err_alloc_sample:
3791         free_percpu(mlxsw_sp_port->pcpu_stats);
3792 err_alloc_stats:
3793         free_netdev(dev);
3794 err_alloc_etherdev:
3795         mlxsw_core_port_fini(mlxsw_sp->core, local_port);
3796         return err;
3797 }
3798
3799 static void mlxsw_sp_port_remove(struct mlxsw_sp *mlxsw_sp, u8 local_port)
3800 {
3801         struct mlxsw_sp_port *mlxsw_sp_port = mlxsw_sp->ports[local_port];
3802
3803         cancel_delayed_work_sync(&mlxsw_sp_port->periodic_hw_stats.update_dw);
3804         cancel_delayed_work_sync(&mlxsw_sp_port->ptp.shaper_dw);
3805         mlxsw_sp_port_ptp_clear(mlxsw_sp_port);
3806         mlxsw_core_port_clear(mlxsw_sp->core, local_port, mlxsw_sp);
3807         unregister_netdev(mlxsw_sp_port->dev); /* This calls ndo_stop */
3808         mlxsw_sp->ports[local_port] = NULL;
3809         mlxsw_sp_port_vlan_flush(mlxsw_sp_port, true);
3810         mlxsw_sp_port_nve_fini(mlxsw_sp_port);
3811         mlxsw_sp_tc_qdisc_fini(mlxsw_sp_port);
3812         mlxsw_sp_port_fids_fini(mlxsw_sp_port);
3813         mlxsw_sp_port_dcb_fini(mlxsw_sp_port);
3814         mlxsw_sp_port_tc_mc_mode_set(mlxsw_sp_port, false);
3815         mlxsw_sp_port_swid_set(mlxsw_sp_port, MLXSW_PORT_SWID_DISABLED_PORT);
3816         mlxsw_sp_port_module_unmap(mlxsw_sp_port);
3817         kfree(mlxsw_sp_port->sample);
3818         free_percpu(mlxsw_sp_port->pcpu_stats);
3819         WARN_ON_ONCE(!list_empty(&mlxsw_sp_port->vlans_list));
3820         free_netdev(mlxsw_sp_port->dev);
3821         mlxsw_core_port_fini(mlxsw_sp->core, local_port);
3822 }
3823
3824 static bool mlxsw_sp_port_created(struct mlxsw_sp *mlxsw_sp, u8 local_port)
3825 {
3826         return mlxsw_sp->ports[local_port] != NULL;
3827 }
3828
3829 static void mlxsw_sp_ports_remove(struct mlxsw_sp *mlxsw_sp)
3830 {
3831         int i;
3832
3833         for (i = 1; i < mlxsw_core_max_ports(mlxsw_sp->core); i++)
3834                 if (mlxsw_sp_port_created(mlxsw_sp, i))
3835                         mlxsw_sp_port_remove(mlxsw_sp, i);
3836         kfree(mlxsw_sp->port_to_module);
3837         kfree(mlxsw_sp->ports);
3838 }
3839
3840 static int mlxsw_sp_ports_create(struct mlxsw_sp *mlxsw_sp)
3841 {
3842         unsigned int max_ports = mlxsw_core_max_ports(mlxsw_sp->core);
3843         u8 module, width, lane;
3844         size_t alloc_size;
3845         int i;
3846         int err;
3847
3848         alloc_size = sizeof(struct mlxsw_sp_port *) * max_ports;
3849         mlxsw_sp->ports = kzalloc(alloc_size, GFP_KERNEL);
3850         if (!mlxsw_sp->ports)
3851                 return -ENOMEM;
3852
3853         mlxsw_sp->port_to_module = kmalloc_array(max_ports, sizeof(int),
3854                                                  GFP_KERNEL);
3855         if (!mlxsw_sp->port_to_module) {
3856                 err = -ENOMEM;
3857                 goto err_port_to_module_alloc;
3858         }
3859
3860         for (i = 1; i < max_ports; i++) {
3861                 /* Mark as invalid */
3862                 mlxsw_sp->port_to_module[i] = -1;
3863
3864                 err = mlxsw_sp_port_module_info_get(mlxsw_sp, i, &module,
3865                                                     &width, &lane);
3866                 if (err)
3867                         goto err_port_module_info_get;
3868                 if (!width)
3869                         continue;
3870                 mlxsw_sp->port_to_module[i] = module;
3871                 err = mlxsw_sp_port_create(mlxsw_sp, i, false,
3872                                            module, width, lane);
3873                 if (err)
3874                         goto err_port_create;
3875         }
3876         return 0;
3877
3878 err_port_create:
3879 err_port_module_info_get:
3880         for (i--; i >= 1; i--)
3881                 if (mlxsw_sp_port_created(mlxsw_sp, i))
3882                         mlxsw_sp_port_remove(mlxsw_sp, i);
3883         kfree(mlxsw_sp->port_to_module);
3884 err_port_to_module_alloc:
3885         kfree(mlxsw_sp->ports);
3886         return err;
3887 }
3888
3889 static u8 mlxsw_sp_cluster_base_port_get(u8 local_port)
3890 {
3891         u8 offset = (local_port - 1) % MLXSW_SP_PORTS_PER_CLUSTER_MAX;
3892
3893         return local_port - offset;
3894 }
3895
3896 static int mlxsw_sp_port_split_create(struct mlxsw_sp *mlxsw_sp, u8 base_port,
3897                                       u8 module, unsigned int count, u8 offset)
3898 {
3899         u8 width = MLXSW_PORT_MODULE_MAX_WIDTH / count;
3900         int err, i;
3901
3902         for (i = 0; i < count; i++) {
3903                 err = mlxsw_sp_port_create(mlxsw_sp, base_port + i * offset,
3904                                            true, module, width, i * width);
3905                 if (err)
3906                         goto err_port_create;
3907         }
3908
3909         return 0;
3910
3911 err_port_create:
3912         for (i--; i >= 0; i--)
3913                 if (mlxsw_sp_port_created(mlxsw_sp, base_port + i * offset))
3914                         mlxsw_sp_port_remove(mlxsw_sp, base_port + i * offset);
3915         return err;
3916 }
3917
3918 static void mlxsw_sp_port_unsplit_create(struct mlxsw_sp *mlxsw_sp,
3919                                          u8 base_port, unsigned int count)
3920 {
3921         u8 local_port, module, width = MLXSW_PORT_MODULE_MAX_WIDTH;
3922         int i;
3923
3924         /* Split by four means we need to re-create two ports, otherwise
3925          * only one.
3926          */
3927         count = count / 2;
3928
3929         for (i = 0; i < count; i++) {
3930                 local_port = base_port + i * 2;
3931                 if (mlxsw_sp->port_to_module[local_port] < 0)
3932                         continue;
3933                 module = mlxsw_sp->port_to_module[local_port];
3934
3935                 mlxsw_sp_port_create(mlxsw_sp, local_port, false, module,
3936                                      width, 0);
3937         }
3938 }
3939
3940 static int mlxsw_sp_port_split(struct mlxsw_core *mlxsw_core, u8 local_port,
3941                                unsigned int count,
3942                                struct netlink_ext_ack *extack)
3943 {
3944         struct mlxsw_sp *mlxsw_sp = mlxsw_core_driver_priv(mlxsw_core);
3945         u8 local_ports_in_1x, local_ports_in_2x, offset;
3946         struct mlxsw_sp_port *mlxsw_sp_port;
3947         u8 module, cur_width, base_port;
3948         int i;
3949         int err;
3950
3951         if (!MLXSW_CORE_RES_VALID(mlxsw_core, LOCAL_PORTS_IN_1X) ||
3952             !MLXSW_CORE_RES_VALID(mlxsw_core, LOCAL_PORTS_IN_2X))
3953                 return -EIO;
3954
3955         local_ports_in_1x = MLXSW_CORE_RES_GET(mlxsw_core, LOCAL_PORTS_IN_1X);
3956         local_ports_in_2x = MLXSW_CORE_RES_GET(mlxsw_core, LOCAL_PORTS_IN_2X);
3957
3958         mlxsw_sp_port = mlxsw_sp->ports[local_port];
3959         if (!mlxsw_sp_port) {
3960                 dev_err(mlxsw_sp->bus_info->dev, "Port number \"%d\" does not exist\n",
3961                         local_port);
3962                 NL_SET_ERR_MSG_MOD(extack, "Port number does not exist");
3963                 return -EINVAL;
3964         }
3965
3966         module = mlxsw_sp_port->mapping.module;
3967         cur_width = mlxsw_sp_port->mapping.width;
3968
3969         if (count != 2 && count != 4) {
3970                 netdev_err(mlxsw_sp_port->dev, "Port can only be split into 2 or 4 ports\n");
3971                 NL_SET_ERR_MSG_MOD(extack, "Port can only be split into 2 or 4 ports");
3972                 return -EINVAL;
3973         }
3974
3975         if (cur_width != MLXSW_PORT_MODULE_MAX_WIDTH) {
3976                 netdev_err(mlxsw_sp_port->dev, "Port cannot be split further\n");
3977                 NL_SET_ERR_MSG_MOD(extack, "Port cannot be split further");
3978                 return -EINVAL;
3979         }
3980
3981         /* Make sure we have enough slave (even) ports for the split. */
3982         if (count == 2) {
3983                 offset = local_ports_in_2x;
3984                 base_port = local_port;
3985                 if (mlxsw_sp->ports[base_port + local_ports_in_2x]) {
3986                         netdev_err(mlxsw_sp_port->dev, "Invalid split configuration\n");
3987                         NL_SET_ERR_MSG_MOD(extack, "Invalid split configuration");
3988                         return -EINVAL;
3989                 }
3990         } else {
3991                 offset = local_ports_in_1x;
3992                 base_port = mlxsw_sp_cluster_base_port_get(local_port);
3993                 if (mlxsw_sp->ports[base_port + 1] ||
3994                     mlxsw_sp->ports[base_port + 3]) {
3995                         netdev_err(mlxsw_sp_port->dev, "Invalid split configuration\n");
3996                         NL_SET_ERR_MSG_MOD(extack, "Invalid split configuration");
3997                         return -EINVAL;
3998                 }
3999         }
4000
4001         for (i = 0; i < count; i++)
4002                 if (mlxsw_sp_port_created(mlxsw_sp, base_port + i * offset))
4003                         mlxsw_sp_port_remove(mlxsw_sp, base_port + i * offset);
4004
4005         err = mlxsw_sp_port_split_create(mlxsw_sp, base_port, module, count,
4006                                          offset);
4007         if (err) {
4008                 dev_err(mlxsw_sp->bus_info->dev, "Failed to create split ports\n");
4009                 goto err_port_split_create;
4010         }
4011
4012         return 0;
4013
4014 err_port_split_create:
4015         mlxsw_sp_port_unsplit_create(mlxsw_sp, base_port, count);
4016         return err;
4017 }
4018
4019 static int mlxsw_sp_port_unsplit(struct mlxsw_core *mlxsw_core, u8 local_port,
4020                                  struct netlink_ext_ack *extack)
4021 {
4022         struct mlxsw_sp *mlxsw_sp = mlxsw_core_driver_priv(mlxsw_core);
4023         u8 local_ports_in_1x, local_ports_in_2x, offset;
4024         struct mlxsw_sp_port *mlxsw_sp_port;
4025         u8 cur_width, base_port;
4026         unsigned int count;
4027         int i;
4028
4029         if (!MLXSW_CORE_RES_VALID(mlxsw_core, LOCAL_PORTS_IN_1X) ||
4030             !MLXSW_CORE_RES_VALID(mlxsw_core, LOCAL_PORTS_IN_2X))
4031                 return -EIO;
4032
4033         local_ports_in_1x = MLXSW_CORE_RES_GET(mlxsw_core, LOCAL_PORTS_IN_1X);
4034         local_ports_in_2x = MLXSW_CORE_RES_GET(mlxsw_core, LOCAL_PORTS_IN_2X);
4035
4036         mlxsw_sp_port = mlxsw_sp->ports[local_port];
4037         if (!mlxsw_sp_port) {
4038                 dev_err(mlxsw_sp->bus_info->dev, "Port number \"%d\" does not exist\n",
4039                         local_port);
4040                 NL_SET_ERR_MSG_MOD(extack, "Port number does not exist");
4041                 return -EINVAL;
4042         }
4043
4044         if (!mlxsw_sp_port->split) {
4045                 netdev_err(mlxsw_sp_port->dev, "Port was not split\n");
4046                 NL_SET_ERR_MSG_MOD(extack, "Port was not split");
4047                 return -EINVAL;
4048         }
4049
4050         cur_width = mlxsw_sp_port->mapping.width;
4051         count = cur_width == 1 ? 4 : 2;
4052
4053         if (count == 2)
4054                 offset = local_ports_in_2x;
4055         else
4056                 offset = local_ports_in_1x;
4057
4058         base_port = mlxsw_sp_cluster_base_port_get(local_port);
4059
4060         /* Determine which ports to remove. */
4061         if (count == 2 && local_port >= base_port + 2)
4062                 base_port = base_port + 2;
4063
4064         for (i = 0; i < count; i++)
4065                 if (mlxsw_sp_port_created(mlxsw_sp, base_port + i * offset))
4066                         mlxsw_sp_port_remove(mlxsw_sp, base_port + i * offset);
4067
4068         mlxsw_sp_port_unsplit_create(mlxsw_sp, base_port, count);
4069
4070         return 0;
4071 }
4072
4073 static void mlxsw_sp_pude_event_func(const struct mlxsw_reg_info *reg,
4074                                      char *pude_pl, void *priv)
4075 {
4076         struct mlxsw_sp *mlxsw_sp = priv;
4077         struct mlxsw_sp_port *mlxsw_sp_port;
4078         enum mlxsw_reg_pude_oper_status status;
4079         u8 local_port;
4080
4081         local_port = mlxsw_reg_pude_local_port_get(pude_pl);
4082         mlxsw_sp_port = mlxsw_sp->ports[local_port];
4083         if (!mlxsw_sp_port)
4084                 return;
4085
4086         status = mlxsw_reg_pude_oper_status_get(pude_pl);
4087         if (status == MLXSW_PORT_OPER_STATUS_UP) {
4088                 netdev_info(mlxsw_sp_port->dev, "link up\n");
4089                 netif_carrier_on(mlxsw_sp_port->dev);
4090                 mlxsw_core_schedule_dw(&mlxsw_sp_port->ptp.shaper_dw, 0);
4091         } else {
4092                 netdev_info(mlxsw_sp_port->dev, "link down\n");
4093                 netif_carrier_off(mlxsw_sp_port->dev);
4094         }
4095 }
4096
4097 static void mlxsw_sp1_ptp_fifo_event_func(struct mlxsw_sp *mlxsw_sp,
4098                                           char *mtpptr_pl, bool ingress)
4099 {
4100         u8 local_port;
4101         u8 num_rec;
4102         int i;
4103
4104         local_port = mlxsw_reg_mtpptr_local_port_get(mtpptr_pl);
4105         num_rec = mlxsw_reg_mtpptr_num_rec_get(mtpptr_pl);
4106         for (i = 0; i < num_rec; i++) {
4107                 u8 domain_number;
4108                 u8 message_type;
4109                 u16 sequence_id;
4110                 u64 timestamp;
4111
4112                 mlxsw_reg_mtpptr_unpack(mtpptr_pl, i, &message_type,
4113                                         &domain_number, &sequence_id,
4114                                         &timestamp);
4115                 mlxsw_sp1_ptp_got_timestamp(mlxsw_sp, ingress, local_port,
4116                                             message_type, domain_number,
4117                                             sequence_id, timestamp);
4118         }
4119 }
4120
4121 static void mlxsw_sp1_ptp_ing_fifo_event_func(const struct mlxsw_reg_info *reg,
4122                                               char *mtpptr_pl, void *priv)
4123 {
4124         struct mlxsw_sp *mlxsw_sp = priv;
4125
4126         mlxsw_sp1_ptp_fifo_event_func(mlxsw_sp, mtpptr_pl, true);
4127 }
4128
4129 static void mlxsw_sp1_ptp_egr_fifo_event_func(const struct mlxsw_reg_info *reg,
4130                                               char *mtpptr_pl, void *priv)
4131 {
4132         struct mlxsw_sp *mlxsw_sp = priv;
4133
4134         mlxsw_sp1_ptp_fifo_event_func(mlxsw_sp, mtpptr_pl, false);
4135 }
4136
4137 void mlxsw_sp_rx_listener_no_mark_func(struct sk_buff *skb,
4138                                        u8 local_port, void *priv)
4139 {
4140         struct mlxsw_sp *mlxsw_sp = priv;
4141         struct mlxsw_sp_port *mlxsw_sp_port = mlxsw_sp->ports[local_port];
4142         struct mlxsw_sp_port_pcpu_stats *pcpu_stats;
4143
4144         if (unlikely(!mlxsw_sp_port)) {
4145                 dev_warn_ratelimited(mlxsw_sp->bus_info->dev, "Port %d: skb received for non-existent port\n",
4146                                      local_port);
4147                 return;
4148         }
4149
4150         skb->dev = mlxsw_sp_port->dev;
4151
4152         pcpu_stats = this_cpu_ptr(mlxsw_sp_port->pcpu_stats);
4153         u64_stats_update_begin(&pcpu_stats->syncp);
4154         pcpu_stats->rx_packets++;
4155         pcpu_stats->rx_bytes += skb->len;
4156         u64_stats_update_end(&pcpu_stats->syncp);
4157
4158         skb->protocol = eth_type_trans(skb, skb->dev);
4159         netif_receive_skb(skb);
4160 }
4161
4162 static void mlxsw_sp_rx_listener_mark_func(struct sk_buff *skb, u8 local_port,
4163                                            void *priv)
4164 {
4165         skb->offload_fwd_mark = 1;
4166         return mlxsw_sp_rx_listener_no_mark_func(skb, local_port, priv);
4167 }
4168
4169 static void mlxsw_sp_rx_listener_l3_mark_func(struct sk_buff *skb,
4170                                               u8 local_port, void *priv)
4171 {
4172         skb->offload_l3_fwd_mark = 1;
4173         skb->offload_fwd_mark = 1;
4174         return mlxsw_sp_rx_listener_no_mark_func(skb, local_port, priv);
4175 }
4176
4177 static void mlxsw_sp_rx_listener_sample_func(struct sk_buff *skb, u8 local_port,
4178                                              void *priv)
4179 {
4180         struct mlxsw_sp *mlxsw_sp = priv;
4181         struct mlxsw_sp_port *mlxsw_sp_port = mlxsw_sp->ports[local_port];
4182         struct psample_group *psample_group;
4183         u32 size;
4184
4185         if (unlikely(!mlxsw_sp_port)) {
4186                 dev_warn_ratelimited(mlxsw_sp->bus_info->dev, "Port %d: sample skb received for non-existent port\n",
4187                                      local_port);
4188                 goto out;
4189         }
4190         if (unlikely(!mlxsw_sp_port->sample)) {
4191                 dev_warn_ratelimited(mlxsw_sp->bus_info->dev, "Port %d: sample skb received on unsupported port\n",
4192                                      local_port);
4193                 goto out;
4194         }
4195
4196         size = mlxsw_sp_port->sample->truncate ?
4197                   mlxsw_sp_port->sample->trunc_size : skb->len;
4198
4199         rcu_read_lock();
4200         psample_group = rcu_dereference(mlxsw_sp_port->sample->psample_group);
4201         if (!psample_group)
4202                 goto out_unlock;
4203         psample_sample_packet(psample_group, skb, size,
4204                               mlxsw_sp_port->dev->ifindex, 0,
4205                               mlxsw_sp_port->sample->rate);
4206 out_unlock:
4207         rcu_read_unlock();
4208 out:
4209         consume_skb(skb);
4210 }
4211
4212 static void mlxsw_sp_rx_listener_ptp(struct sk_buff *skb, u8 local_port,
4213                                      void *priv)
4214 {
4215         struct mlxsw_sp *mlxsw_sp = priv;
4216
4217         mlxsw_sp->ptp_ops->receive(mlxsw_sp, skb, local_port);
4218 }
4219
4220 #define MLXSW_SP_RXL_NO_MARK(_trap_id, _action, _trap_group, _is_ctrl)  \
4221         MLXSW_RXL(mlxsw_sp_rx_listener_no_mark_func, _trap_id, _action, \
4222                   _is_ctrl, SP_##_trap_group, DISCARD)
4223
4224 #define MLXSW_SP_RXL_MARK(_trap_id, _action, _trap_group, _is_ctrl)     \
4225         MLXSW_RXL(mlxsw_sp_rx_listener_mark_func, _trap_id, _action,    \
4226                 _is_ctrl, SP_##_trap_group, DISCARD)
4227
4228 #define MLXSW_SP_RXL_L3_MARK(_trap_id, _action, _trap_group, _is_ctrl)  \
4229         MLXSW_RXL(mlxsw_sp_rx_listener_l3_mark_func, _trap_id, _action, \
4230                 _is_ctrl, SP_##_trap_group, DISCARD)
4231
4232 #define MLXSW_SP_EVENTL(_func, _trap_id)                \
4233         MLXSW_EVENTL(_func, _trap_id, SP_EVENT)
4234
4235 static const struct mlxsw_listener mlxsw_sp_listener[] = {
4236         /* Events */
4237         MLXSW_SP_EVENTL(mlxsw_sp_pude_event_func, PUDE),
4238         /* L2 traps */
4239         MLXSW_SP_RXL_NO_MARK(STP, TRAP_TO_CPU, STP, true),
4240         MLXSW_SP_RXL_NO_MARK(LACP, TRAP_TO_CPU, LACP, true),
4241         MLXSW_RXL(mlxsw_sp_rx_listener_ptp, LLDP, TRAP_TO_CPU,
4242                   false, SP_LLDP, DISCARD),
4243         MLXSW_SP_RXL_MARK(DHCP, MIRROR_TO_CPU, DHCP, false),
4244         MLXSW_SP_RXL_MARK(IGMP_QUERY, MIRROR_TO_CPU, IGMP, false),
4245         MLXSW_SP_RXL_NO_MARK(IGMP_V1_REPORT, TRAP_TO_CPU, IGMP, false),
4246         MLXSW_SP_RXL_NO_MARK(IGMP_V2_REPORT, TRAP_TO_CPU, IGMP, false),
4247         MLXSW_SP_RXL_NO_MARK(IGMP_V2_LEAVE, TRAP_TO_CPU, IGMP, false),
4248         MLXSW_SP_RXL_NO_MARK(IGMP_V3_REPORT, TRAP_TO_CPU, IGMP, false),
4249         MLXSW_SP_RXL_MARK(ARPBC, MIRROR_TO_CPU, ARP, false),
4250         MLXSW_SP_RXL_MARK(ARPUC, MIRROR_TO_CPU, ARP, false),
4251         MLXSW_SP_RXL_NO_MARK(FID_MISS, TRAP_TO_CPU, IP2ME, false),
4252         MLXSW_SP_RXL_MARK(IPV6_MLDV12_LISTENER_QUERY, MIRROR_TO_CPU, IPV6_MLD,
4253                           false),
4254         MLXSW_SP_RXL_NO_MARK(IPV6_MLDV1_LISTENER_REPORT, TRAP_TO_CPU, IPV6_MLD,
4255                              false),
4256         MLXSW_SP_RXL_NO_MARK(IPV6_MLDV1_LISTENER_DONE, TRAP_TO_CPU, IPV6_MLD,
4257                              false),
4258         MLXSW_SP_RXL_NO_MARK(IPV6_MLDV2_LISTENER_REPORT, TRAP_TO_CPU, IPV6_MLD,
4259                              false),
4260         /* L3 traps */
4261         MLXSW_SP_RXL_MARK(MTUERROR, TRAP_TO_CPU, ROUTER_EXP, false),
4262         MLXSW_SP_RXL_MARK(TTLERROR, TRAP_TO_CPU, ROUTER_EXP, false),
4263         MLXSW_SP_RXL_L3_MARK(LBERROR, MIRROR_TO_CPU, LBERROR, false),
4264         MLXSW_SP_RXL_MARK(IP2ME, TRAP_TO_CPU, IP2ME, false),
4265         MLXSW_SP_RXL_MARK(IPV6_UNSPECIFIED_ADDRESS, TRAP_TO_CPU, ROUTER_EXP,
4266                           false),
4267         MLXSW_SP_RXL_MARK(IPV6_LINK_LOCAL_DEST, TRAP_TO_CPU, ROUTER_EXP, false),
4268         MLXSW_SP_RXL_MARK(IPV6_LINK_LOCAL_SRC, TRAP_TO_CPU, ROUTER_EXP, false),
4269         MLXSW_SP_RXL_MARK(IPV6_ALL_NODES_LINK, TRAP_TO_CPU, ROUTER_EXP, false),
4270         MLXSW_SP_RXL_MARK(IPV6_ALL_ROUTERS_LINK, TRAP_TO_CPU, ROUTER_EXP,
4271                           false),
4272         MLXSW_SP_RXL_MARK(IPV4_OSPF, TRAP_TO_CPU, OSPF, false),
4273         MLXSW_SP_RXL_MARK(IPV6_OSPF, TRAP_TO_CPU, OSPF, false),
4274         MLXSW_SP_RXL_MARK(IPV6_DHCP, TRAP_TO_CPU, DHCP, false),
4275         MLXSW_SP_RXL_MARK(RTR_INGRESS0, TRAP_TO_CPU, REMOTE_ROUTE, false),
4276         MLXSW_SP_RXL_MARK(IPV4_BGP, TRAP_TO_CPU, BGP, false),
4277         MLXSW_SP_RXL_MARK(IPV6_BGP, TRAP_TO_CPU, BGP, false),
4278         MLXSW_SP_RXL_MARK(L3_IPV6_ROUTER_SOLICITATION, TRAP_TO_CPU, IPV6_ND,
4279                           false),
4280         MLXSW_SP_RXL_MARK(L3_IPV6_ROUTER_ADVERTISMENT, TRAP_TO_CPU, IPV6_ND,
4281                           false),
4282         MLXSW_SP_RXL_MARK(L3_IPV6_NEIGHBOR_SOLICITATION, TRAP_TO_CPU, IPV6_ND,
4283                           false),
4284         MLXSW_SP_RXL_MARK(L3_IPV6_NEIGHBOR_ADVERTISMENT, TRAP_TO_CPU, IPV6_ND,
4285                           false),
4286         MLXSW_SP_RXL_MARK(L3_IPV6_REDIRECTION, TRAP_TO_CPU, IPV6_ND, false),
4287         MLXSW_SP_RXL_MARK(IPV6_MC_LINK_LOCAL_DEST, TRAP_TO_CPU, ROUTER_EXP,
4288                           false),
4289         MLXSW_SP_RXL_MARK(HOST_MISS_IPV4, TRAP_TO_CPU, HOST_MISS, false),
4290         MLXSW_SP_RXL_MARK(HOST_MISS_IPV6, TRAP_TO_CPU, HOST_MISS, false),
4291         MLXSW_SP_RXL_MARK(ROUTER_ALERT_IPV4, TRAP_TO_CPU, ROUTER_EXP, false),
4292         MLXSW_SP_RXL_MARK(ROUTER_ALERT_IPV6, TRAP_TO_CPU, ROUTER_EXP, false),
4293         MLXSW_SP_RXL_MARK(IPIP_DECAP_ERROR, TRAP_TO_CPU, ROUTER_EXP, false),
4294         MLXSW_SP_RXL_MARK(DECAP_ECN0, TRAP_TO_CPU, ROUTER_EXP, false),
4295         MLXSW_SP_RXL_MARK(IPV4_VRRP, TRAP_TO_CPU, ROUTER_EXP, false),
4296         MLXSW_SP_RXL_MARK(IPV6_VRRP, TRAP_TO_CPU, ROUTER_EXP, false),
4297         /* PKT Sample trap */
4298         MLXSW_RXL(mlxsw_sp_rx_listener_sample_func, PKT_SAMPLE, MIRROR_TO_CPU,
4299                   false, SP_IP2ME, DISCARD),
4300         /* ACL trap */
4301         MLXSW_SP_RXL_NO_MARK(ACL0, TRAP_TO_CPU, IP2ME, false),
4302         /* Multicast Router Traps */
4303         MLXSW_SP_RXL_MARK(IPV4_PIM, TRAP_TO_CPU, PIM, false),
4304         MLXSW_SP_RXL_MARK(IPV6_PIM, TRAP_TO_CPU, PIM, false),
4305         MLXSW_SP_RXL_MARK(RPF, TRAP_TO_CPU, RPF, false),
4306         MLXSW_SP_RXL_MARK(ACL1, TRAP_TO_CPU, MULTICAST, false),
4307         MLXSW_SP_RXL_L3_MARK(ACL2, TRAP_TO_CPU, MULTICAST, false),
4308         /* NVE traps */
4309         MLXSW_SP_RXL_MARK(NVE_ENCAP_ARP, TRAP_TO_CPU, ARP, false),
4310         MLXSW_SP_RXL_NO_MARK(NVE_DECAP_ARP, TRAP_TO_CPU, ARP, false),
4311         /* PTP traps */
4312         MLXSW_RXL(mlxsw_sp_rx_listener_ptp, PTP0, TRAP_TO_CPU,
4313                   false, SP_PTP0, DISCARD),
4314         MLXSW_SP_RXL_NO_MARK(PTP1, TRAP_TO_CPU, PTP1, false),
4315 };
4316
4317 static const struct mlxsw_listener mlxsw_sp1_listener[] = {
4318         /* Events */
4319         MLXSW_EVENTL(mlxsw_sp1_ptp_egr_fifo_event_func, PTP_EGR_FIFO, SP_PTP0),
4320         MLXSW_EVENTL(mlxsw_sp1_ptp_ing_fifo_event_func, PTP_ING_FIFO, SP_PTP0),
4321 };
4322
4323 static int mlxsw_sp_cpu_policers_set(struct mlxsw_core *mlxsw_core)
4324 {
4325         char qpcr_pl[MLXSW_REG_QPCR_LEN];
4326         enum mlxsw_reg_qpcr_ir_units ir_units;
4327         int max_cpu_policers;
4328         bool is_bytes;
4329         u8 burst_size;
4330         u32 rate;
4331         int i, err;
4332
4333         if (!MLXSW_CORE_RES_VALID(mlxsw_core, MAX_CPU_POLICERS))
4334                 return -EIO;
4335
4336         max_cpu_policers = MLXSW_CORE_RES_GET(mlxsw_core, MAX_CPU_POLICERS);
4337
4338         ir_units = MLXSW_REG_QPCR_IR_UNITS_M;
4339         for (i = 0; i < max_cpu_policers; i++) {
4340                 is_bytes = false;
4341                 switch (i) {
4342                 case MLXSW_REG_HTGT_TRAP_GROUP_SP_STP:
4343                 case MLXSW_REG_HTGT_TRAP_GROUP_SP_LACP:
4344                 case MLXSW_REG_HTGT_TRAP_GROUP_SP_LLDP:
4345                 case MLXSW_REG_HTGT_TRAP_GROUP_SP_OSPF:
4346                 case MLXSW_REG_HTGT_TRAP_GROUP_SP_PIM:
4347                 case MLXSW_REG_HTGT_TRAP_GROUP_SP_RPF:
4348                 case MLXSW_REG_HTGT_TRAP_GROUP_SP_LBERROR:
4349                         rate = 128;
4350                         burst_size = 7;
4351                         break;
4352                 case MLXSW_REG_HTGT_TRAP_GROUP_SP_IGMP:
4353                 case MLXSW_REG_HTGT_TRAP_GROUP_SP_IPV6_MLD:
4354                         rate = 16 * 1024;
4355                         burst_size = 10;
4356                         break;
4357                 case MLXSW_REG_HTGT_TRAP_GROUP_SP_BGP:
4358                 case MLXSW_REG_HTGT_TRAP_GROUP_SP_ARP:
4359                 case MLXSW_REG_HTGT_TRAP_GROUP_SP_DHCP:
4360                 case MLXSW_REG_HTGT_TRAP_GROUP_SP_HOST_MISS:
4361                 case MLXSW_REG_HTGT_TRAP_GROUP_SP_ROUTER_EXP:
4362                 case MLXSW_REG_HTGT_TRAP_GROUP_SP_REMOTE_ROUTE:
4363                 case MLXSW_REG_HTGT_TRAP_GROUP_SP_IPV6_ND:
4364                 case MLXSW_REG_HTGT_TRAP_GROUP_SP_MULTICAST:
4365                         rate = 1024;
4366                         burst_size = 7;
4367                         break;
4368                 case MLXSW_REG_HTGT_TRAP_GROUP_SP_IP2ME:
4369                         rate = 1024;
4370                         burst_size = 7;
4371                         break;
4372                 case MLXSW_REG_HTGT_TRAP_GROUP_SP_PTP0:
4373                         rate = 24 * 1024;
4374                         burst_size = 12;
4375                         break;
4376                 case MLXSW_REG_HTGT_TRAP_GROUP_SP_PTP1:
4377                         rate = 19 * 1024;
4378                         burst_size = 12;
4379                         break;
4380                 default:
4381                         continue;
4382                 }
4383
4384                 mlxsw_reg_qpcr_pack(qpcr_pl, i, ir_units, is_bytes, rate,
4385                                     burst_size);
4386                 err = mlxsw_reg_write(mlxsw_core, MLXSW_REG(qpcr), qpcr_pl);
4387                 if (err)
4388                         return err;
4389         }
4390
4391         return 0;
4392 }
4393
4394 static int mlxsw_sp_trap_groups_set(struct mlxsw_core *mlxsw_core)
4395 {
4396         char htgt_pl[MLXSW_REG_HTGT_LEN];
4397         enum mlxsw_reg_htgt_trap_group i;
4398         int max_cpu_policers;
4399         int max_trap_groups;
4400         u8 priority, tc;
4401         u16 policer_id;
4402         int err;
4403
4404         if (!MLXSW_CORE_RES_VALID(mlxsw_core, MAX_TRAP_GROUPS))
4405                 return -EIO;
4406
4407         max_trap_groups = MLXSW_CORE_RES_GET(mlxsw_core, MAX_TRAP_GROUPS);
4408         max_cpu_policers = MLXSW_CORE_RES_GET(mlxsw_core, MAX_CPU_POLICERS);
4409
4410         for (i = 0; i < max_trap_groups; i++) {
4411                 policer_id = i;
4412                 switch (i) {
4413                 case MLXSW_REG_HTGT_TRAP_GROUP_SP_STP:
4414                 case MLXSW_REG_HTGT_TRAP_GROUP_SP_LACP:
4415                 case MLXSW_REG_HTGT_TRAP_GROUP_SP_LLDP:
4416                 case MLXSW_REG_HTGT_TRAP_GROUP_SP_OSPF:
4417                 case MLXSW_REG_HTGT_TRAP_GROUP_SP_PIM:
4418                 case MLXSW_REG_HTGT_TRAP_GROUP_SP_PTP0:
4419                         priority = 5;
4420                         tc = 5;
4421                         break;
4422                 case MLXSW_REG_HTGT_TRAP_GROUP_SP_BGP:
4423                 case MLXSW_REG_HTGT_TRAP_GROUP_SP_DHCP:
4424                         priority = 4;
4425                         tc = 4;
4426                         break;
4427                 case MLXSW_REG_HTGT_TRAP_GROUP_SP_IGMP:
4428                 case MLXSW_REG_HTGT_TRAP_GROUP_SP_IP2ME:
4429                 case MLXSW_REG_HTGT_TRAP_GROUP_SP_IPV6_MLD:
4430                         priority = 3;
4431                         tc = 3;
4432                         break;
4433                 case MLXSW_REG_HTGT_TRAP_GROUP_SP_ARP:
4434                 case MLXSW_REG_HTGT_TRAP_GROUP_SP_IPV6_ND:
4435                 case MLXSW_REG_HTGT_TRAP_GROUP_SP_RPF:
4436                 case MLXSW_REG_HTGT_TRAP_GROUP_SP_PTP1:
4437                         priority = 2;
4438                         tc = 2;
4439                         break;
4440                 case MLXSW_REG_HTGT_TRAP_GROUP_SP_HOST_MISS:
4441                 case MLXSW_REG_HTGT_TRAP_GROUP_SP_ROUTER_EXP:
4442                 case MLXSW_REG_HTGT_TRAP_GROUP_SP_REMOTE_ROUTE:
4443                 case MLXSW_REG_HTGT_TRAP_GROUP_SP_MULTICAST:
4444                 case MLXSW_REG_HTGT_TRAP_GROUP_SP_LBERROR:
4445                         priority = 1;
4446                         tc = 1;
4447                         break;
4448                 case MLXSW_REG_HTGT_TRAP_GROUP_SP_EVENT:
4449                         priority = MLXSW_REG_HTGT_DEFAULT_PRIORITY;
4450                         tc = MLXSW_REG_HTGT_DEFAULT_TC;
4451                         policer_id = MLXSW_REG_HTGT_INVALID_POLICER;
4452                         break;
4453                 default:
4454                         continue;
4455                 }
4456
4457                 if (max_cpu_policers <= policer_id &&
4458                     policer_id != MLXSW_REG_HTGT_INVALID_POLICER)
4459                         return -EIO;
4460
4461                 mlxsw_reg_htgt_pack(htgt_pl, i, policer_id, priority, tc);
4462                 err = mlxsw_reg_write(mlxsw_core, MLXSW_REG(htgt), htgt_pl);
4463                 if (err)
4464                         return err;
4465         }
4466
4467         return 0;
4468 }
4469
4470 static int mlxsw_sp_traps_register(struct mlxsw_sp *mlxsw_sp,
4471                                    const struct mlxsw_listener listeners[],
4472                                    size_t listeners_count)
4473 {
4474         int i;
4475         int err;
4476
4477         for (i = 0; i < listeners_count; i++) {
4478                 err = mlxsw_core_trap_register(mlxsw_sp->core,
4479                                                &listeners[i],
4480                                                mlxsw_sp);
4481                 if (err)
4482                         goto err_listener_register;
4483
4484         }
4485         return 0;
4486
4487 err_listener_register:
4488         for (i--; i >= 0; i--) {
4489                 mlxsw_core_trap_unregister(mlxsw_sp->core,
4490                                            &listeners[i],
4491                                            mlxsw_sp);
4492         }
4493         return err;
4494 }
4495
4496 static void mlxsw_sp_traps_unregister(struct mlxsw_sp *mlxsw_sp,
4497                                       const struct mlxsw_listener listeners[],
4498                                       size_t listeners_count)
4499 {
4500         int i;
4501
4502         for (i = 0; i < listeners_count; i++) {
4503                 mlxsw_core_trap_unregister(mlxsw_sp->core,
4504                                            &listeners[i],
4505                                            mlxsw_sp);
4506         }
4507 }
4508
4509 static int mlxsw_sp_traps_init(struct mlxsw_sp *mlxsw_sp)
4510 {
4511         int err;
4512
4513         err = mlxsw_sp_cpu_policers_set(mlxsw_sp->core);
4514         if (err)
4515                 return err;
4516
4517         err = mlxsw_sp_trap_groups_set(mlxsw_sp->core);
4518         if (err)
4519                 return err;
4520
4521         err = mlxsw_sp_traps_register(mlxsw_sp, mlxsw_sp_listener,
4522                                       ARRAY_SIZE(mlxsw_sp_listener));
4523         if (err)
4524                 return err;
4525
4526         err = mlxsw_sp_traps_register(mlxsw_sp, mlxsw_sp->listeners,
4527                                       mlxsw_sp->listeners_count);
4528         if (err)
4529                 goto err_extra_traps_init;
4530
4531         return 0;
4532
4533 err_extra_traps_init:
4534         mlxsw_sp_traps_unregister(mlxsw_sp, mlxsw_sp_listener,
4535                                   ARRAY_SIZE(mlxsw_sp_listener));
4536         return err;
4537 }
4538
4539 static void mlxsw_sp_traps_fini(struct mlxsw_sp *mlxsw_sp)
4540 {
4541         mlxsw_sp_traps_unregister(mlxsw_sp, mlxsw_sp->listeners,
4542                                   mlxsw_sp->listeners_count);
4543         mlxsw_sp_traps_unregister(mlxsw_sp, mlxsw_sp_listener,
4544                                   ARRAY_SIZE(mlxsw_sp_listener));
4545 }
4546
4547 #define MLXSW_SP_LAG_SEED_INIT 0xcafecafe
4548
4549 static int mlxsw_sp_lag_init(struct mlxsw_sp *mlxsw_sp)
4550 {
4551         char slcr_pl[MLXSW_REG_SLCR_LEN];
4552         u32 seed;
4553         int err;
4554
4555         seed = jhash(mlxsw_sp->base_mac, sizeof(mlxsw_sp->base_mac),
4556                      MLXSW_SP_LAG_SEED_INIT);
4557         mlxsw_reg_slcr_pack(slcr_pl, MLXSW_REG_SLCR_LAG_HASH_SMAC |
4558                                      MLXSW_REG_SLCR_LAG_HASH_DMAC |
4559                                      MLXSW_REG_SLCR_LAG_HASH_ETHERTYPE |
4560                                      MLXSW_REG_SLCR_LAG_HASH_VLANID |
4561                                      MLXSW_REG_SLCR_LAG_HASH_SIP |
4562                                      MLXSW_REG_SLCR_LAG_HASH_DIP |
4563                                      MLXSW_REG_SLCR_LAG_HASH_SPORT |
4564                                      MLXSW_REG_SLCR_LAG_HASH_DPORT |
4565                                      MLXSW_REG_SLCR_LAG_HASH_IPPROTO, seed);
4566         err = mlxsw_reg_write(mlxsw_sp->core, MLXSW_REG(slcr), slcr_pl);
4567         if (err)
4568                 return err;
4569
4570         if (!MLXSW_CORE_RES_VALID(mlxsw_sp->core, MAX_LAG) ||
4571             !MLXSW_CORE_RES_VALID(mlxsw_sp->core, MAX_LAG_MEMBERS))
4572                 return -EIO;
4573
4574         mlxsw_sp->lags = kcalloc(MLXSW_CORE_RES_GET(mlxsw_sp->core, MAX_LAG),
4575                                  sizeof(struct mlxsw_sp_upper),
4576                                  GFP_KERNEL);
4577         if (!mlxsw_sp->lags)
4578                 return -ENOMEM;
4579
4580         return 0;
4581 }
4582
4583 static void mlxsw_sp_lag_fini(struct mlxsw_sp *mlxsw_sp)
4584 {
4585         kfree(mlxsw_sp->lags);
4586 }
4587
4588 static int mlxsw_sp_basic_trap_groups_set(struct mlxsw_core *mlxsw_core)
4589 {
4590         char htgt_pl[MLXSW_REG_HTGT_LEN];
4591
4592         mlxsw_reg_htgt_pack(htgt_pl, MLXSW_REG_HTGT_TRAP_GROUP_EMAD,
4593                             MLXSW_REG_HTGT_INVALID_POLICER,
4594                             MLXSW_REG_HTGT_DEFAULT_PRIORITY,
4595                             MLXSW_REG_HTGT_DEFAULT_TC);
4596         return mlxsw_reg_write(mlxsw_core, MLXSW_REG(htgt), htgt_pl);
4597 }
4598
4599 static const struct mlxsw_sp_ptp_ops mlxsw_sp1_ptp_ops = {
4600         .clock_init     = mlxsw_sp1_ptp_clock_init,
4601         .clock_fini     = mlxsw_sp1_ptp_clock_fini,
4602         .init           = mlxsw_sp1_ptp_init,
4603         .fini           = mlxsw_sp1_ptp_fini,
4604         .receive        = mlxsw_sp1_ptp_receive,
4605         .transmitted    = mlxsw_sp1_ptp_transmitted,
4606         .hwtstamp_get   = mlxsw_sp1_ptp_hwtstamp_get,
4607         .hwtstamp_set   = mlxsw_sp1_ptp_hwtstamp_set,
4608         .shaper_work    = mlxsw_sp1_ptp_shaper_work,
4609         .get_ts_info    = mlxsw_sp1_ptp_get_ts_info,
4610 };
4611
4612 static const struct mlxsw_sp_ptp_ops mlxsw_sp2_ptp_ops = {
4613         .clock_init     = mlxsw_sp2_ptp_clock_init,
4614         .clock_fini     = mlxsw_sp2_ptp_clock_fini,
4615         .init           = mlxsw_sp2_ptp_init,
4616         .fini           = mlxsw_sp2_ptp_fini,
4617         .receive        = mlxsw_sp2_ptp_receive,
4618         .transmitted    = mlxsw_sp2_ptp_transmitted,
4619         .hwtstamp_get   = mlxsw_sp2_ptp_hwtstamp_get,
4620         .hwtstamp_set   = mlxsw_sp2_ptp_hwtstamp_set,
4621         .shaper_work    = mlxsw_sp2_ptp_shaper_work,
4622         .get_ts_info    = mlxsw_sp2_ptp_get_ts_info,
4623 };
4624
4625 static int mlxsw_sp_netdevice_event(struct notifier_block *unused,
4626                                     unsigned long event, void *ptr);
4627
4628 static int mlxsw_sp_init(struct mlxsw_core *mlxsw_core,
4629                          const struct mlxsw_bus_info *mlxsw_bus_info)
4630 {
4631         struct mlxsw_sp *mlxsw_sp = mlxsw_core_driver_priv(mlxsw_core);
4632         int err;
4633
4634         mlxsw_sp->core = mlxsw_core;
4635         mlxsw_sp->bus_info = mlxsw_bus_info;
4636
4637         err = mlxsw_sp_fw_rev_validate(mlxsw_sp);
4638         if (err)
4639                 return err;
4640
4641         err = mlxsw_sp_base_mac_get(mlxsw_sp);
4642         if (err) {
4643                 dev_err(mlxsw_sp->bus_info->dev, "Failed to get base mac\n");
4644                 return err;
4645         }
4646
4647         err = mlxsw_sp_kvdl_init(mlxsw_sp);
4648         if (err) {
4649                 dev_err(mlxsw_sp->bus_info->dev, "Failed to initialize KVDL\n");
4650                 return err;
4651         }
4652
4653         err = mlxsw_sp_fids_init(mlxsw_sp);
4654         if (err) {
4655                 dev_err(mlxsw_sp->bus_info->dev, "Failed to initialize FIDs\n");
4656                 goto err_fids_init;
4657         }
4658
4659         err = mlxsw_sp_traps_init(mlxsw_sp);
4660         if (err) {
4661                 dev_err(mlxsw_sp->bus_info->dev, "Failed to set traps\n");
4662                 goto err_traps_init;
4663         }
4664
4665         err = mlxsw_sp_buffers_init(mlxsw_sp);
4666         if (err) {
4667                 dev_err(mlxsw_sp->bus_info->dev, "Failed to initialize buffers\n");
4668                 goto err_buffers_init;
4669         }
4670
4671         err = mlxsw_sp_lag_init(mlxsw_sp);
4672         if (err) {
4673                 dev_err(mlxsw_sp->bus_info->dev, "Failed to initialize LAG\n");
4674                 goto err_lag_init;
4675         }
4676
4677         /* Initialize SPAN before router and switchdev, so that those components
4678          * can call mlxsw_sp_span_respin().
4679          */
4680         err = mlxsw_sp_span_init(mlxsw_sp);
4681         if (err) {
4682                 dev_err(mlxsw_sp->bus_info->dev, "Failed to init span system\n");
4683                 goto err_span_init;
4684         }
4685
4686         err = mlxsw_sp_switchdev_init(mlxsw_sp);
4687         if (err) {
4688                 dev_err(mlxsw_sp->bus_info->dev, "Failed to initialize switchdev\n");
4689                 goto err_switchdev_init;
4690         }
4691
4692         err = mlxsw_sp_counter_pool_init(mlxsw_sp);
4693         if (err) {
4694                 dev_err(mlxsw_sp->bus_info->dev, "Failed to init counter pool\n");
4695                 goto err_counter_pool_init;
4696         }
4697
4698         err = mlxsw_sp_afa_init(mlxsw_sp);
4699         if (err) {
4700                 dev_err(mlxsw_sp->bus_info->dev, "Failed to initialize ACL actions\n");
4701                 goto err_afa_init;
4702         }
4703
4704         err = mlxsw_sp_nve_init(mlxsw_sp);
4705         if (err) {
4706                 dev_err(mlxsw_sp->bus_info->dev, "Failed to initialize NVE\n");
4707                 goto err_nve_init;
4708         }
4709
4710         err = mlxsw_sp_acl_init(mlxsw_sp);
4711         if (err) {
4712                 dev_err(mlxsw_sp->bus_info->dev, "Failed to initialize ACL\n");
4713                 goto err_acl_init;
4714         }
4715
4716         err = mlxsw_sp_router_init(mlxsw_sp);
4717         if (err) {
4718                 dev_err(mlxsw_sp->bus_info->dev, "Failed to initialize router\n");
4719                 goto err_router_init;
4720         }
4721
4722         if (mlxsw_sp->bus_info->read_frc_capable) {
4723                 /* NULL is a valid return value from clock_init */
4724                 mlxsw_sp->clock =
4725                         mlxsw_sp->ptp_ops->clock_init(mlxsw_sp,
4726                                                       mlxsw_sp->bus_info->dev);
4727                 if (IS_ERR(mlxsw_sp->clock)) {
4728                         err = PTR_ERR(mlxsw_sp->clock);
4729                         dev_err(mlxsw_sp->bus_info->dev, "Failed to init ptp clock\n");
4730                         goto err_ptp_clock_init;
4731                 }
4732         }
4733
4734         if (mlxsw_sp->clock) {
4735                 /* NULL is a valid return value from ptp_ops->init */
4736                 mlxsw_sp->ptp_state = mlxsw_sp->ptp_ops->init(mlxsw_sp);
4737                 if (IS_ERR(mlxsw_sp->ptp_state)) {
4738                         err = PTR_ERR(mlxsw_sp->ptp_state);
4739                         dev_err(mlxsw_sp->bus_info->dev, "Failed to initialize PTP\n");
4740                         goto err_ptp_init;
4741                 }
4742         }
4743
4744         /* Initialize netdevice notifier after router and SPAN is initialized,
4745          * so that the event handler can use router structures and call SPAN
4746          * respin.
4747          */
4748         mlxsw_sp->netdevice_nb.notifier_call = mlxsw_sp_netdevice_event;
4749         err = register_netdevice_notifier(&mlxsw_sp->netdevice_nb);
4750         if (err) {
4751                 dev_err(mlxsw_sp->bus_info->dev, "Failed to register netdev notifier\n");
4752                 goto err_netdev_notifier;
4753         }
4754
4755         err = mlxsw_sp_dpipe_init(mlxsw_sp);
4756         if (err) {
4757                 dev_err(mlxsw_sp->bus_info->dev, "Failed to init pipeline debug\n");
4758                 goto err_dpipe_init;
4759         }
4760
4761         err = mlxsw_sp_ports_create(mlxsw_sp);
4762         if (err) {
4763                 dev_err(mlxsw_sp->bus_info->dev, "Failed to create ports\n");
4764                 goto err_ports_create;
4765         }
4766
4767         return 0;
4768
4769 err_ports_create:
4770         mlxsw_sp_dpipe_fini(mlxsw_sp);
4771 err_dpipe_init:
4772         unregister_netdevice_notifier(&mlxsw_sp->netdevice_nb);
4773 err_netdev_notifier:
4774         if (mlxsw_sp->clock)
4775                 mlxsw_sp->ptp_ops->fini(mlxsw_sp->ptp_state);
4776 err_ptp_init:
4777         if (mlxsw_sp->clock)
4778                 mlxsw_sp->ptp_ops->clock_fini(mlxsw_sp->clock);
4779 err_ptp_clock_init:
4780         mlxsw_sp_router_fini(mlxsw_sp);
4781 err_router_init:
4782         mlxsw_sp_acl_fini(mlxsw_sp);
4783 err_acl_init:
4784         mlxsw_sp_nve_fini(mlxsw_sp);
4785 err_nve_init:
4786         mlxsw_sp_afa_fini(mlxsw_sp);
4787 err_afa_init:
4788         mlxsw_sp_counter_pool_fini(mlxsw_sp);
4789 err_counter_pool_init:
4790         mlxsw_sp_switchdev_fini(mlxsw_sp);
4791 err_switchdev_init:
4792         mlxsw_sp_span_fini(mlxsw_sp);
4793 err_span_init:
4794         mlxsw_sp_lag_fini(mlxsw_sp);
4795 err_lag_init:
4796         mlxsw_sp_buffers_fini(mlxsw_sp);
4797 err_buffers_init:
4798         mlxsw_sp_traps_fini(mlxsw_sp);
4799 err_traps_init:
4800         mlxsw_sp_fids_fini(mlxsw_sp);
4801 err_fids_init:
4802         mlxsw_sp_kvdl_fini(mlxsw_sp);
4803         return err;
4804 }
4805
4806 static int mlxsw_sp1_init(struct mlxsw_core *mlxsw_core,
4807                           const struct mlxsw_bus_info *mlxsw_bus_info)
4808 {
4809         struct mlxsw_sp *mlxsw_sp = mlxsw_core_driver_priv(mlxsw_core);
4810
4811         mlxsw_sp->req_rev = &mlxsw_sp1_fw_rev;
4812         mlxsw_sp->fw_filename = MLXSW_SP1_FW_FILENAME;
4813         mlxsw_sp->kvdl_ops = &mlxsw_sp1_kvdl_ops;
4814         mlxsw_sp->afa_ops = &mlxsw_sp1_act_afa_ops;
4815         mlxsw_sp->afk_ops = &mlxsw_sp1_afk_ops;
4816         mlxsw_sp->mr_tcam_ops = &mlxsw_sp1_mr_tcam_ops;
4817         mlxsw_sp->acl_tcam_ops = &mlxsw_sp1_acl_tcam_ops;
4818         mlxsw_sp->nve_ops_arr = mlxsw_sp1_nve_ops_arr;
4819         mlxsw_sp->mac_mask = mlxsw_sp1_mac_mask;
4820         mlxsw_sp->rif_ops_arr = mlxsw_sp1_rif_ops_arr;
4821         mlxsw_sp->sb_vals = &mlxsw_sp1_sb_vals;
4822         mlxsw_sp->port_type_speed_ops = &mlxsw_sp1_port_type_speed_ops;
4823         mlxsw_sp->ptp_ops = &mlxsw_sp1_ptp_ops;
4824         mlxsw_sp->listeners = mlxsw_sp1_listener;
4825         mlxsw_sp->listeners_count = ARRAY_SIZE(mlxsw_sp1_listener);
4826
4827         return mlxsw_sp_init(mlxsw_core, mlxsw_bus_info);
4828 }
4829
4830 static int mlxsw_sp2_init(struct mlxsw_core *mlxsw_core,
4831                           const struct mlxsw_bus_info *mlxsw_bus_info)
4832 {
4833         struct mlxsw_sp *mlxsw_sp = mlxsw_core_driver_priv(mlxsw_core);
4834
4835         mlxsw_sp->kvdl_ops = &mlxsw_sp2_kvdl_ops;
4836         mlxsw_sp->afa_ops = &mlxsw_sp2_act_afa_ops;
4837         mlxsw_sp->afk_ops = &mlxsw_sp2_afk_ops;
4838         mlxsw_sp->mr_tcam_ops = &mlxsw_sp2_mr_tcam_ops;
4839         mlxsw_sp->acl_tcam_ops = &mlxsw_sp2_acl_tcam_ops;
4840         mlxsw_sp->nve_ops_arr = mlxsw_sp2_nve_ops_arr;
4841         mlxsw_sp->mac_mask = mlxsw_sp2_mac_mask;
4842         mlxsw_sp->rif_ops_arr = mlxsw_sp2_rif_ops_arr;
4843         mlxsw_sp->sb_vals = &mlxsw_sp2_sb_vals;
4844         mlxsw_sp->port_type_speed_ops = &mlxsw_sp2_port_type_speed_ops;
4845         mlxsw_sp->ptp_ops = &mlxsw_sp2_ptp_ops;
4846
4847         return mlxsw_sp_init(mlxsw_core, mlxsw_bus_info);
4848 }
4849
4850 static void mlxsw_sp_fini(struct mlxsw_core *mlxsw_core)
4851 {
4852         struct mlxsw_sp *mlxsw_sp = mlxsw_core_driver_priv(mlxsw_core);
4853
4854         mlxsw_sp_ports_remove(mlxsw_sp);
4855         mlxsw_sp_dpipe_fini(mlxsw_sp);
4856         unregister_netdevice_notifier(&mlxsw_sp->netdevice_nb);
4857         if (mlxsw_sp->clock) {
4858                 mlxsw_sp->ptp_ops->fini(mlxsw_sp->ptp_state);
4859                 mlxsw_sp->ptp_ops->clock_fini(mlxsw_sp->clock);
4860         }
4861         mlxsw_sp_router_fini(mlxsw_sp);
4862         mlxsw_sp_acl_fini(mlxsw_sp);
4863         mlxsw_sp_nve_fini(mlxsw_sp);
4864         mlxsw_sp_afa_fini(mlxsw_sp);
4865         mlxsw_sp_counter_pool_fini(mlxsw_sp);
4866         mlxsw_sp_switchdev_fini(mlxsw_sp);
4867         mlxsw_sp_span_fini(mlxsw_sp);
4868         mlxsw_sp_lag_fini(mlxsw_sp);
4869         mlxsw_sp_buffers_fini(mlxsw_sp);
4870         mlxsw_sp_traps_fini(mlxsw_sp);
4871         mlxsw_sp_fids_fini(mlxsw_sp);
4872         mlxsw_sp_kvdl_fini(mlxsw_sp);
4873 }
4874
4875 /* Per-FID flood tables are used for both "true" 802.1D FIDs and emulated
4876  * 802.1Q FIDs
4877  */
4878 #define MLXSW_SP_FID_FLOOD_TABLE_SIZE   (MLXSW_SP_FID_8021D_MAX + \
4879                                          VLAN_VID_MASK - 1)
4880
4881 static const struct mlxsw_config_profile mlxsw_sp1_config_profile = {
4882         .used_max_mid                   = 1,
4883         .max_mid                        = MLXSW_SP_MID_MAX,
4884         .used_flood_tables              = 1,
4885         .used_flood_mode                = 1,
4886         .flood_mode                     = 3,
4887         .max_fid_flood_tables           = 3,
4888         .fid_flood_table_size           = MLXSW_SP_FID_FLOOD_TABLE_SIZE,
4889         .used_max_ib_mc                 = 1,
4890         .max_ib_mc                      = 0,
4891         .used_max_pkey                  = 1,
4892         .max_pkey                       = 0,
4893         .used_kvd_sizes                 = 1,
4894         .kvd_hash_single_parts          = 59,
4895         .kvd_hash_double_parts          = 41,
4896         .kvd_linear_size                = MLXSW_SP_KVD_LINEAR_SIZE,
4897         .swid_config                    = {
4898                 {
4899                         .used_type      = 1,
4900                         .type           = MLXSW_PORT_SWID_TYPE_ETH,
4901                 }
4902         },
4903 };
4904
4905 static const struct mlxsw_config_profile mlxsw_sp2_config_profile = {
4906         .used_max_mid                   = 1,
4907         .max_mid                        = MLXSW_SP_MID_MAX,
4908         .used_flood_tables              = 1,
4909         .used_flood_mode                = 1,
4910         .flood_mode                     = 3,
4911         .max_fid_flood_tables           = 3,
4912         .fid_flood_table_size           = MLXSW_SP_FID_FLOOD_TABLE_SIZE,
4913         .used_max_ib_mc                 = 1,
4914         .max_ib_mc                      = 0,
4915         .used_max_pkey                  = 1,
4916         .max_pkey                       = 0,
4917         .swid_config                    = {
4918                 {
4919                         .used_type      = 1,
4920                         .type           = MLXSW_PORT_SWID_TYPE_ETH,
4921                 }
4922         },
4923 };
4924
4925 static void
4926 mlxsw_sp_resource_size_params_prepare(struct mlxsw_core *mlxsw_core,
4927                                       struct devlink_resource_size_params *kvd_size_params,
4928                                       struct devlink_resource_size_params *linear_size_params,
4929                                       struct devlink_resource_size_params *hash_double_size_params,
4930                                       struct devlink_resource_size_params *hash_single_size_params)
4931 {
4932         u32 single_size_min = MLXSW_CORE_RES_GET(mlxsw_core,
4933                                                  KVD_SINGLE_MIN_SIZE);
4934         u32 double_size_min = MLXSW_CORE_RES_GET(mlxsw_core,
4935                                                  KVD_DOUBLE_MIN_SIZE);
4936         u32 kvd_size = MLXSW_CORE_RES_GET(mlxsw_core, KVD_SIZE);
4937         u32 linear_size_min = 0;
4938
4939         devlink_resource_size_params_init(kvd_size_params, kvd_size, kvd_size,
4940                                           MLXSW_SP_KVD_GRANULARITY,
4941                                           DEVLINK_RESOURCE_UNIT_ENTRY);
4942         devlink_resource_size_params_init(linear_size_params, linear_size_min,
4943                                           kvd_size - single_size_min -
4944                                           double_size_min,
4945                                           MLXSW_SP_KVD_GRANULARITY,
4946                                           DEVLINK_RESOURCE_UNIT_ENTRY);
4947         devlink_resource_size_params_init(hash_double_size_params,
4948                                           double_size_min,
4949                                           kvd_size - single_size_min -
4950                                           linear_size_min,
4951                                           MLXSW_SP_KVD_GRANULARITY,
4952                                           DEVLINK_RESOURCE_UNIT_ENTRY);
4953         devlink_resource_size_params_init(hash_single_size_params,
4954                                           single_size_min,
4955                                           kvd_size - double_size_min -
4956                                           linear_size_min,
4957                                           MLXSW_SP_KVD_GRANULARITY,
4958                                           DEVLINK_RESOURCE_UNIT_ENTRY);
4959 }
4960
4961 static int mlxsw_sp1_resources_kvd_register(struct mlxsw_core *mlxsw_core)
4962 {
4963         struct devlink *devlink = priv_to_devlink(mlxsw_core);
4964         struct devlink_resource_size_params hash_single_size_params;
4965         struct devlink_resource_size_params hash_double_size_params;
4966         struct devlink_resource_size_params linear_size_params;
4967         struct devlink_resource_size_params kvd_size_params;
4968         u32 kvd_size, single_size, double_size, linear_size;
4969         const struct mlxsw_config_profile *profile;
4970         int err;
4971
4972         profile = &mlxsw_sp1_config_profile;
4973         if (!MLXSW_CORE_RES_VALID(mlxsw_core, KVD_SIZE))
4974                 return -EIO;
4975
4976         mlxsw_sp_resource_size_params_prepare(mlxsw_core, &kvd_size_params,
4977                                               &linear_size_params,
4978                                               &hash_double_size_params,
4979                                               &hash_single_size_params);
4980
4981         kvd_size = MLXSW_CORE_RES_GET(mlxsw_core, KVD_SIZE);
4982         err = devlink_resource_register(devlink, MLXSW_SP_RESOURCE_NAME_KVD,
4983                                         kvd_size, MLXSW_SP_RESOURCE_KVD,
4984                                         DEVLINK_RESOURCE_ID_PARENT_TOP,
4985                                         &kvd_size_params);
4986         if (err)
4987                 return err;
4988
4989         linear_size = profile->kvd_linear_size;
4990         err = devlink_resource_register(devlink, MLXSW_SP_RESOURCE_NAME_KVD_LINEAR,
4991                                         linear_size,
4992                                         MLXSW_SP_RESOURCE_KVD_LINEAR,
4993                                         MLXSW_SP_RESOURCE_KVD,
4994                                         &linear_size_params);
4995         if (err)
4996                 return err;
4997
4998         err = mlxsw_sp1_kvdl_resources_register(mlxsw_core);
4999         if  (err)
5000                 return err;
5001
5002         double_size = kvd_size - linear_size;
5003         double_size *= profile->kvd_hash_double_parts;
5004         double_size /= profile->kvd_hash_double_parts +
5005                        profile->kvd_hash_single_parts;
5006         double_size = rounddown(double_size, MLXSW_SP_KVD_GRANULARITY);
5007         err = devlink_resource_register(devlink, MLXSW_SP_RESOURCE_NAME_KVD_HASH_DOUBLE,
5008                                         double_size,
5009                                         MLXSW_SP_RESOURCE_KVD_HASH_DOUBLE,
5010                                         MLXSW_SP_RESOURCE_KVD,
5011                                         &hash_double_size_params);
5012         if (err)
5013                 return err;
5014
5015         single_size = kvd_size - double_size - linear_size;
5016         err = devlink_resource_register(devlink, MLXSW_SP_RESOURCE_NAME_KVD_HASH_SINGLE,
5017                                         single_size,
5018                                         MLXSW_SP_RESOURCE_KVD_HASH_SINGLE,
5019                                         MLXSW_SP_RESOURCE_KVD,
5020                                         &hash_single_size_params);
5021         if (err)
5022                 return err;
5023
5024         return 0;
5025 }
5026
5027 static int mlxsw_sp1_resources_register(struct mlxsw_core *mlxsw_core)
5028 {
5029         return mlxsw_sp1_resources_kvd_register(mlxsw_core);
5030 }
5031
5032 static int mlxsw_sp2_resources_register(struct mlxsw_core *mlxsw_core)
5033 {
5034         return 0;
5035 }
5036
5037 static int mlxsw_sp_kvd_sizes_get(struct mlxsw_core *mlxsw_core,
5038                                   const struct mlxsw_config_profile *profile,
5039                                   u64 *p_single_size, u64 *p_double_size,
5040                                   u64 *p_linear_size)
5041 {
5042         struct devlink *devlink = priv_to_devlink(mlxsw_core);
5043         u32 double_size;
5044         int err;
5045
5046         if (!MLXSW_CORE_RES_VALID(mlxsw_core, KVD_SINGLE_MIN_SIZE) ||
5047             !MLXSW_CORE_RES_VALID(mlxsw_core, KVD_DOUBLE_MIN_SIZE))
5048                 return -EIO;
5049
5050         /* The hash part is what left of the kvd without the
5051          * linear part. It is split to the single size and
5052          * double size by the parts ratio from the profile.
5053          * Both sizes must be a multiplications of the
5054          * granularity from the profile. In case the user
5055          * provided the sizes they are obtained via devlink.
5056          */
5057         err = devlink_resource_size_get(devlink,
5058                                         MLXSW_SP_RESOURCE_KVD_LINEAR,
5059                                         p_linear_size);
5060         if (err)
5061                 *p_linear_size = profile->kvd_linear_size;
5062
5063         err = devlink_resource_size_get(devlink,
5064                                         MLXSW_SP_RESOURCE_KVD_HASH_DOUBLE,
5065                                         p_double_size);
5066         if (err) {
5067                 double_size = MLXSW_CORE_RES_GET(mlxsw_core, KVD_SIZE) -
5068                               *p_linear_size;
5069                 double_size *= profile->kvd_hash_double_parts;
5070                 double_size /= profile->kvd_hash_double_parts +
5071                                profile->kvd_hash_single_parts;
5072                 *p_double_size = rounddown(double_size,
5073                                            MLXSW_SP_KVD_GRANULARITY);
5074         }
5075
5076         err = devlink_resource_size_get(devlink,
5077                                         MLXSW_SP_RESOURCE_KVD_HASH_SINGLE,
5078                                         p_single_size);
5079         if (err)
5080                 *p_single_size = MLXSW_CORE_RES_GET(mlxsw_core, KVD_SIZE) -
5081                                  *p_double_size - *p_linear_size;
5082
5083         /* Check results are legal. */
5084         if (*p_single_size < MLXSW_CORE_RES_GET(mlxsw_core, KVD_SINGLE_MIN_SIZE) ||
5085             *p_double_size < MLXSW_CORE_RES_GET(mlxsw_core, KVD_DOUBLE_MIN_SIZE) ||
5086             MLXSW_CORE_RES_GET(mlxsw_core, KVD_SIZE) < *p_linear_size)
5087                 return -EIO;
5088
5089         return 0;
5090 }
5091
5092 static int
5093 mlxsw_sp_devlink_param_fw_load_policy_validate(struct devlink *devlink, u32 id,
5094                                                union devlink_param_value val,
5095                                                struct netlink_ext_ack *extack)
5096 {
5097         if ((val.vu8 != DEVLINK_PARAM_FW_LOAD_POLICY_VALUE_DRIVER) &&
5098             (val.vu8 != DEVLINK_PARAM_FW_LOAD_POLICY_VALUE_FLASH)) {
5099                 NL_SET_ERR_MSG_MOD(extack, "'fw_load_policy' must be 'driver' or 'flash'");
5100                 return -EINVAL;
5101         }
5102
5103         return 0;
5104 }
5105
5106 static const struct devlink_param mlxsw_sp_devlink_params[] = {
5107         DEVLINK_PARAM_GENERIC(FW_LOAD_POLICY,
5108                               BIT(DEVLINK_PARAM_CMODE_DRIVERINIT),
5109                               NULL, NULL,
5110                               mlxsw_sp_devlink_param_fw_load_policy_validate),
5111 };
5112
5113 static int mlxsw_sp_params_register(struct mlxsw_core *mlxsw_core)
5114 {
5115         struct devlink *devlink = priv_to_devlink(mlxsw_core);
5116         union devlink_param_value value;
5117         int err;
5118
5119         err = devlink_params_register(devlink, mlxsw_sp_devlink_params,
5120                                       ARRAY_SIZE(mlxsw_sp_devlink_params));
5121         if (err)
5122                 return err;
5123
5124         value.vu8 = DEVLINK_PARAM_FW_LOAD_POLICY_VALUE_DRIVER;
5125         devlink_param_driverinit_value_set(devlink,
5126                                            DEVLINK_PARAM_GENERIC_ID_FW_LOAD_POLICY,
5127                                            value);
5128         return 0;
5129 }
5130
5131 static void mlxsw_sp_params_unregister(struct mlxsw_core *mlxsw_core)
5132 {
5133         devlink_params_unregister(priv_to_devlink(mlxsw_core),
5134                                   mlxsw_sp_devlink_params,
5135                                   ARRAY_SIZE(mlxsw_sp_devlink_params));
5136 }
5137
5138 static int
5139 mlxsw_sp_params_acl_region_rehash_intrvl_get(struct devlink *devlink, u32 id,
5140                                              struct devlink_param_gset_ctx *ctx)
5141 {
5142         struct mlxsw_core *mlxsw_core = devlink_priv(devlink);
5143         struct mlxsw_sp *mlxsw_sp = mlxsw_core_driver_priv(mlxsw_core);
5144
5145         ctx->val.vu32 = mlxsw_sp_acl_region_rehash_intrvl_get(mlxsw_sp);
5146         return 0;
5147 }
5148
5149 static int
5150 mlxsw_sp_params_acl_region_rehash_intrvl_set(struct devlink *devlink, u32 id,
5151                                              struct devlink_param_gset_ctx *ctx)
5152 {
5153         struct mlxsw_core *mlxsw_core = devlink_priv(devlink);
5154         struct mlxsw_sp *mlxsw_sp = mlxsw_core_driver_priv(mlxsw_core);
5155
5156         return mlxsw_sp_acl_region_rehash_intrvl_set(mlxsw_sp, ctx->val.vu32);
5157 }
5158
5159 static const struct devlink_param mlxsw_sp2_devlink_params[] = {
5160         DEVLINK_PARAM_DRIVER(MLXSW_DEVLINK_PARAM_ID_ACL_REGION_REHASH_INTERVAL,
5161                              "acl_region_rehash_interval",
5162                              DEVLINK_PARAM_TYPE_U32,
5163                              BIT(DEVLINK_PARAM_CMODE_RUNTIME),
5164                              mlxsw_sp_params_acl_region_rehash_intrvl_get,
5165                              mlxsw_sp_params_acl_region_rehash_intrvl_set,
5166                              NULL),
5167 };
5168
5169 static int mlxsw_sp2_params_register(struct mlxsw_core *mlxsw_core)
5170 {
5171         struct devlink *devlink = priv_to_devlink(mlxsw_core);
5172         union devlink_param_value value;
5173         int err;
5174
5175         err = mlxsw_sp_params_register(mlxsw_core);
5176         if (err)
5177                 return err;
5178
5179         err = devlink_params_register(devlink, mlxsw_sp2_devlink_params,
5180                                       ARRAY_SIZE(mlxsw_sp2_devlink_params));
5181         if (err)
5182                 goto err_devlink_params_register;
5183
5184         value.vu32 = 0;
5185         devlink_param_driverinit_value_set(devlink,
5186                                            MLXSW_DEVLINK_PARAM_ID_ACL_REGION_REHASH_INTERVAL,
5187                                            value);
5188         return 0;
5189
5190 err_devlink_params_register:
5191         mlxsw_sp_params_unregister(mlxsw_core);
5192         return err;
5193 }
5194
5195 static void mlxsw_sp2_params_unregister(struct mlxsw_core *mlxsw_core)
5196 {
5197         devlink_params_unregister(priv_to_devlink(mlxsw_core),
5198                                   mlxsw_sp2_devlink_params,
5199                                   ARRAY_SIZE(mlxsw_sp2_devlink_params));
5200         mlxsw_sp_params_unregister(mlxsw_core);
5201 }
5202
5203 static void mlxsw_sp_ptp_transmitted(struct mlxsw_core *mlxsw_core,
5204                                      struct sk_buff *skb, u8 local_port)
5205 {
5206         struct mlxsw_sp *mlxsw_sp = mlxsw_core_driver_priv(mlxsw_core);
5207
5208         skb_pull(skb, MLXSW_TXHDR_LEN);
5209         mlxsw_sp->ptp_ops->transmitted(mlxsw_sp, skb, local_port);
5210 }
5211
5212 static struct mlxsw_driver mlxsw_sp1_driver = {
5213         .kind                           = mlxsw_sp1_driver_name,
5214         .priv_size                      = sizeof(struct mlxsw_sp),
5215         .init                           = mlxsw_sp1_init,
5216         .fini                           = mlxsw_sp_fini,
5217         .basic_trap_groups_set          = mlxsw_sp_basic_trap_groups_set,
5218         .port_split                     = mlxsw_sp_port_split,
5219         .port_unsplit                   = mlxsw_sp_port_unsplit,
5220         .sb_pool_get                    = mlxsw_sp_sb_pool_get,
5221         .sb_pool_set                    = mlxsw_sp_sb_pool_set,
5222         .sb_port_pool_get               = mlxsw_sp_sb_port_pool_get,
5223         .sb_port_pool_set               = mlxsw_sp_sb_port_pool_set,
5224         .sb_tc_pool_bind_get            = mlxsw_sp_sb_tc_pool_bind_get,
5225         .sb_tc_pool_bind_set            = mlxsw_sp_sb_tc_pool_bind_set,
5226         .sb_occ_snapshot                = mlxsw_sp_sb_occ_snapshot,
5227         .sb_occ_max_clear               = mlxsw_sp_sb_occ_max_clear,
5228         .sb_occ_port_pool_get           = mlxsw_sp_sb_occ_port_pool_get,
5229         .sb_occ_tc_port_bind_get        = mlxsw_sp_sb_occ_tc_port_bind_get,
5230         .flash_update                   = mlxsw_sp_flash_update,
5231         .txhdr_construct                = mlxsw_sp_txhdr_construct,
5232         .resources_register             = mlxsw_sp1_resources_register,
5233         .kvd_sizes_get                  = mlxsw_sp_kvd_sizes_get,
5234         .params_register                = mlxsw_sp_params_register,
5235         .params_unregister              = mlxsw_sp_params_unregister,
5236         .ptp_transmitted                = mlxsw_sp_ptp_transmitted,
5237         .txhdr_len                      = MLXSW_TXHDR_LEN,
5238         .profile                        = &mlxsw_sp1_config_profile,
5239         .res_query_enabled              = true,
5240 };
5241
5242 static struct mlxsw_driver mlxsw_sp2_driver = {
5243         .kind                           = mlxsw_sp2_driver_name,
5244         .priv_size                      = sizeof(struct mlxsw_sp),
5245         .init                           = mlxsw_sp2_init,
5246         .fini                           = mlxsw_sp_fini,
5247         .basic_trap_groups_set          = mlxsw_sp_basic_trap_groups_set,
5248         .port_split                     = mlxsw_sp_port_split,
5249         .port_unsplit                   = mlxsw_sp_port_unsplit,
5250         .sb_pool_get                    = mlxsw_sp_sb_pool_get,
5251         .sb_pool_set                    = mlxsw_sp_sb_pool_set,
5252         .sb_port_pool_get               = mlxsw_sp_sb_port_pool_get,
5253         .sb_port_pool_set               = mlxsw_sp_sb_port_pool_set,
5254         .sb_tc_pool_bind_get            = mlxsw_sp_sb_tc_pool_bind_get,
5255         .sb_tc_pool_bind_set            = mlxsw_sp_sb_tc_pool_bind_set,
5256         .sb_occ_snapshot                = mlxsw_sp_sb_occ_snapshot,
5257         .sb_occ_max_clear               = mlxsw_sp_sb_occ_max_clear,
5258         .sb_occ_port_pool_get           = mlxsw_sp_sb_occ_port_pool_get,
5259         .sb_occ_tc_port_bind_get        = mlxsw_sp_sb_occ_tc_port_bind_get,
5260         .flash_update                   = mlxsw_sp_flash_update,
5261         .txhdr_construct                = mlxsw_sp_txhdr_construct,
5262         .resources_register             = mlxsw_sp2_resources_register,
5263         .params_register                = mlxsw_sp2_params_register,
5264         .params_unregister              = mlxsw_sp2_params_unregister,
5265         .ptp_transmitted                = mlxsw_sp_ptp_transmitted,
5266         .txhdr_len                      = MLXSW_TXHDR_LEN,
5267         .profile                        = &mlxsw_sp2_config_profile,
5268         .res_query_enabled              = true,
5269 };
5270
5271 bool mlxsw_sp_port_dev_check(const struct net_device *dev)
5272 {
5273         return dev->netdev_ops == &mlxsw_sp_port_netdev_ops;
5274 }
5275
5276 static int mlxsw_sp_lower_dev_walk(struct net_device *lower_dev, void *data)
5277 {
5278         struct mlxsw_sp_port **p_mlxsw_sp_port = data;
5279         int ret = 0;
5280
5281         if (mlxsw_sp_port_dev_check(lower_dev)) {
5282                 *p_mlxsw_sp_port = netdev_priv(lower_dev);
5283                 ret = 1;
5284         }
5285
5286         return ret;
5287 }
5288
5289 struct mlxsw_sp_port *mlxsw_sp_port_dev_lower_find(struct net_device *dev)
5290 {
5291         struct mlxsw_sp_port *mlxsw_sp_port;
5292
5293         if (mlxsw_sp_port_dev_check(dev))
5294                 return netdev_priv(dev);
5295
5296         mlxsw_sp_port = NULL;
5297         netdev_walk_all_lower_dev(dev, mlxsw_sp_lower_dev_walk, &mlxsw_sp_port);
5298
5299         return mlxsw_sp_port;
5300 }
5301
5302 struct mlxsw_sp *mlxsw_sp_lower_get(struct net_device *dev)
5303 {
5304         struct mlxsw_sp_port *mlxsw_sp_port;
5305
5306         mlxsw_sp_port = mlxsw_sp_port_dev_lower_find(dev);
5307         return mlxsw_sp_port ? mlxsw_sp_port->mlxsw_sp : NULL;
5308 }
5309
5310 struct mlxsw_sp_port *mlxsw_sp_port_dev_lower_find_rcu(struct net_device *dev)
5311 {
5312         struct mlxsw_sp_port *mlxsw_sp_port;
5313
5314         if (mlxsw_sp_port_dev_check(dev))
5315                 return netdev_priv(dev);
5316
5317         mlxsw_sp_port = NULL;
5318         netdev_walk_all_lower_dev_rcu(dev, mlxsw_sp_lower_dev_walk,
5319                                       &mlxsw_sp_port);
5320
5321         return mlxsw_sp_port;
5322 }
5323
5324 struct mlxsw_sp_port *mlxsw_sp_port_lower_dev_hold(struct net_device *dev)
5325 {
5326         struct mlxsw_sp_port *mlxsw_sp_port;
5327
5328         rcu_read_lock();
5329         mlxsw_sp_port = mlxsw_sp_port_dev_lower_find_rcu(dev);
5330         if (mlxsw_sp_port)
5331                 dev_hold(mlxsw_sp_port->dev);
5332         rcu_read_unlock();
5333         return mlxsw_sp_port;
5334 }
5335
5336 void mlxsw_sp_port_dev_put(struct mlxsw_sp_port *mlxsw_sp_port)
5337 {
5338         dev_put(mlxsw_sp_port->dev);
5339 }
5340
5341 static void
5342 mlxsw_sp_port_lag_uppers_cleanup(struct mlxsw_sp_port *mlxsw_sp_port,
5343                                  struct net_device *lag_dev)
5344 {
5345         struct net_device *br_dev = netdev_master_upper_dev_get(lag_dev);
5346         struct net_device *upper_dev;
5347         struct list_head *iter;
5348
5349         if (netif_is_bridge_port(lag_dev))
5350                 mlxsw_sp_port_bridge_leave(mlxsw_sp_port, lag_dev, br_dev);
5351
5352         netdev_for_each_upper_dev_rcu(lag_dev, upper_dev, iter) {
5353                 if (!netif_is_bridge_port(upper_dev))
5354                         continue;
5355                 br_dev = netdev_master_upper_dev_get(upper_dev);
5356                 mlxsw_sp_port_bridge_leave(mlxsw_sp_port, upper_dev, br_dev);
5357         }
5358 }
5359
5360 static int mlxsw_sp_lag_create(struct mlxsw_sp *mlxsw_sp, u16 lag_id)
5361 {
5362         char sldr_pl[MLXSW_REG_SLDR_LEN];
5363
5364         mlxsw_reg_sldr_lag_create_pack(sldr_pl, lag_id);
5365         return mlxsw_reg_write(mlxsw_sp->core, MLXSW_REG(sldr), sldr_pl);
5366 }
5367
5368 static int mlxsw_sp_lag_destroy(struct mlxsw_sp *mlxsw_sp, u16 lag_id)
5369 {
5370         char sldr_pl[MLXSW_REG_SLDR_LEN];
5371
5372         mlxsw_reg_sldr_lag_destroy_pack(sldr_pl, lag_id);
5373         return mlxsw_reg_write(mlxsw_sp->core, MLXSW_REG(sldr), sldr_pl);
5374 }
5375
5376 static int mlxsw_sp_lag_col_port_add(struct mlxsw_sp_port *mlxsw_sp_port,
5377                                      u16 lag_id, u8 port_index)
5378 {
5379         struct mlxsw_sp *mlxsw_sp = mlxsw_sp_port->mlxsw_sp;
5380         char slcor_pl[MLXSW_REG_SLCOR_LEN];
5381
5382         mlxsw_reg_slcor_port_add_pack(slcor_pl, mlxsw_sp_port->local_port,
5383                                       lag_id, port_index);
5384         return mlxsw_reg_write(mlxsw_sp->core, MLXSW_REG(slcor), slcor_pl);
5385 }
5386
5387 static int mlxsw_sp_lag_col_port_remove(struct mlxsw_sp_port *mlxsw_sp_port,
5388                                         u16 lag_id)
5389 {
5390         struct mlxsw_sp *mlxsw_sp = mlxsw_sp_port->mlxsw_sp;
5391         char slcor_pl[MLXSW_REG_SLCOR_LEN];
5392
5393         mlxsw_reg_slcor_port_remove_pack(slcor_pl, mlxsw_sp_port->local_port,
5394                                          lag_id);
5395         return mlxsw_reg_write(mlxsw_sp->core, MLXSW_REG(slcor), slcor_pl);
5396 }
5397
5398 static int mlxsw_sp_lag_col_port_enable(struct mlxsw_sp_port *mlxsw_sp_port,
5399                                         u16 lag_id)
5400 {
5401         struct mlxsw_sp *mlxsw_sp = mlxsw_sp_port->mlxsw_sp;
5402         char slcor_pl[MLXSW_REG_SLCOR_LEN];
5403
5404         mlxsw_reg_slcor_col_enable_pack(slcor_pl, mlxsw_sp_port->local_port,
5405                                         lag_id);
5406         return mlxsw_reg_write(mlxsw_sp->core, MLXSW_REG(slcor), slcor_pl);
5407 }
5408
5409 static int mlxsw_sp_lag_col_port_disable(struct mlxsw_sp_port *mlxsw_sp_port,
5410                                          u16 lag_id)
5411 {
5412         struct mlxsw_sp *mlxsw_sp = mlxsw_sp_port->mlxsw_sp;
5413         char slcor_pl[MLXSW_REG_SLCOR_LEN];
5414
5415         mlxsw_reg_slcor_col_disable_pack(slcor_pl, mlxsw_sp_port->local_port,
5416                                          lag_id);
5417         return mlxsw_reg_write(mlxsw_sp->core, MLXSW_REG(slcor), slcor_pl);
5418 }
5419
5420 static int mlxsw_sp_lag_index_get(struct mlxsw_sp *mlxsw_sp,
5421                                   struct net_device *lag_dev,
5422                                   u16 *p_lag_id)
5423 {
5424         struct mlxsw_sp_upper *lag;
5425         int free_lag_id = -1;
5426         u64 max_lag;
5427         int i;
5428
5429         max_lag = MLXSW_CORE_RES_GET(mlxsw_sp->core, MAX_LAG);
5430         for (i = 0; i < max_lag; i++) {
5431                 lag = mlxsw_sp_lag_get(mlxsw_sp, i);
5432                 if (lag->ref_count) {
5433                         if (lag->dev == lag_dev) {
5434                                 *p_lag_id = i;
5435                                 return 0;
5436                         }
5437                 } else if (free_lag_id < 0) {
5438                         free_lag_id = i;
5439                 }
5440         }
5441         if (free_lag_id < 0)
5442                 return -EBUSY;
5443         *p_lag_id = free_lag_id;
5444         return 0;
5445 }
5446
5447 static bool
5448 mlxsw_sp_master_lag_check(struct mlxsw_sp *mlxsw_sp,
5449                           struct net_device *lag_dev,
5450                           struct netdev_lag_upper_info *lag_upper_info,
5451                           struct netlink_ext_ack *extack)
5452 {
5453         u16 lag_id;
5454
5455         if (mlxsw_sp_lag_index_get(mlxsw_sp, lag_dev, &lag_id) != 0) {
5456                 NL_SET_ERR_MSG_MOD(extack, "Exceeded number of supported LAG devices");
5457                 return false;
5458         }
5459         if (lag_upper_info->tx_type != NETDEV_LAG_TX_TYPE_HASH) {
5460                 NL_SET_ERR_MSG_MOD(extack, "LAG device using unsupported Tx type");
5461                 return false;
5462         }
5463         return true;
5464 }
5465
5466 static int mlxsw_sp_port_lag_index_get(struct mlxsw_sp *mlxsw_sp,
5467                                        u16 lag_id, u8 *p_port_index)
5468 {
5469         u64 max_lag_members;
5470         int i;
5471
5472         max_lag_members = MLXSW_CORE_RES_GET(mlxsw_sp->core,
5473                                              MAX_LAG_MEMBERS);
5474         for (i = 0; i < max_lag_members; i++) {
5475                 if (!mlxsw_sp_port_lagged_get(mlxsw_sp, lag_id, i)) {
5476                         *p_port_index = i;
5477                         return 0;
5478                 }
5479         }
5480         return -EBUSY;
5481 }
5482
5483 static int mlxsw_sp_port_lag_join(struct mlxsw_sp_port *mlxsw_sp_port,
5484                                   struct net_device *lag_dev)
5485 {
5486         struct mlxsw_sp *mlxsw_sp = mlxsw_sp_port->mlxsw_sp;
5487         struct mlxsw_sp_upper *lag;
5488         u16 lag_id;
5489         u8 port_index;
5490         int err;
5491
5492         err = mlxsw_sp_lag_index_get(mlxsw_sp, lag_dev, &lag_id);
5493         if (err)
5494                 return err;
5495         lag = mlxsw_sp_lag_get(mlxsw_sp, lag_id);
5496         if (!lag->ref_count) {
5497                 err = mlxsw_sp_lag_create(mlxsw_sp, lag_id);
5498                 if (err)
5499                         return err;
5500                 lag->dev = lag_dev;
5501         }
5502
5503         err = mlxsw_sp_port_lag_index_get(mlxsw_sp, lag_id, &port_index);
5504         if (err)
5505                 return err;
5506         err = mlxsw_sp_lag_col_port_add(mlxsw_sp_port, lag_id, port_index);
5507         if (err)
5508                 goto err_col_port_add;
5509
5510         mlxsw_core_lag_mapping_set(mlxsw_sp->core, lag_id, port_index,
5511                                    mlxsw_sp_port->local_port);
5512         mlxsw_sp_port->lag_id = lag_id;
5513         mlxsw_sp_port->lagged = 1;
5514         lag->ref_count++;
5515
5516         /* Port is no longer usable as a router interface */
5517         if (mlxsw_sp_port->default_vlan->fid)
5518                 mlxsw_sp_port_vlan_router_leave(mlxsw_sp_port->default_vlan);
5519
5520         return 0;
5521
5522 err_col_port_add:
5523         if (!lag->ref_count)
5524                 mlxsw_sp_lag_destroy(mlxsw_sp, lag_id);
5525         return err;
5526 }
5527
5528 static void mlxsw_sp_port_lag_leave(struct mlxsw_sp_port *mlxsw_sp_port,
5529                                     struct net_device *lag_dev)
5530 {
5531         struct mlxsw_sp *mlxsw_sp = mlxsw_sp_port->mlxsw_sp;
5532         u16 lag_id = mlxsw_sp_port->lag_id;
5533         struct mlxsw_sp_upper *lag;
5534
5535         if (!mlxsw_sp_port->lagged)
5536                 return;
5537         lag = mlxsw_sp_lag_get(mlxsw_sp, lag_id);
5538         WARN_ON(lag->ref_count == 0);
5539
5540         mlxsw_sp_lag_col_port_remove(mlxsw_sp_port, lag_id);
5541
5542         /* Any VLANs configured on the port are no longer valid */
5543         mlxsw_sp_port_vlan_flush(mlxsw_sp_port, false);
5544         mlxsw_sp_port_vlan_cleanup(mlxsw_sp_port->default_vlan);
5545         /* Make the LAG and its directly linked uppers leave bridges they
5546          * are memeber in
5547          */
5548         mlxsw_sp_port_lag_uppers_cleanup(mlxsw_sp_port, lag_dev);
5549
5550         if (lag->ref_count == 1)
5551                 mlxsw_sp_lag_destroy(mlxsw_sp, lag_id);
5552
5553         mlxsw_core_lag_mapping_clear(mlxsw_sp->core, lag_id,
5554                                      mlxsw_sp_port->local_port);
5555         mlxsw_sp_port->lagged = 0;
5556         lag->ref_count--;
5557
5558         /* Make sure untagged frames are allowed to ingress */
5559         mlxsw_sp_port_pvid_set(mlxsw_sp_port, MLXSW_SP_DEFAULT_VID);
5560 }
5561
5562 static int mlxsw_sp_lag_dist_port_add(struct mlxsw_sp_port *mlxsw_sp_port,
5563                                       u16 lag_id)
5564 {
5565         struct mlxsw_sp *mlxsw_sp = mlxsw_sp_port->mlxsw_sp;
5566         char sldr_pl[MLXSW_REG_SLDR_LEN];
5567
5568         mlxsw_reg_sldr_lag_add_port_pack(sldr_pl, lag_id,
5569                                          mlxsw_sp_port->local_port);
5570         return mlxsw_reg_write(mlxsw_sp->core, MLXSW_REG(sldr), sldr_pl);
5571 }
5572
5573 static int mlxsw_sp_lag_dist_port_remove(struct mlxsw_sp_port *mlxsw_sp_port,
5574                                          u16 lag_id)
5575 {
5576         struct mlxsw_sp *mlxsw_sp = mlxsw_sp_port->mlxsw_sp;
5577         char sldr_pl[MLXSW_REG_SLDR_LEN];
5578
5579         mlxsw_reg_sldr_lag_remove_port_pack(sldr_pl, lag_id,
5580                                             mlxsw_sp_port->local_port);
5581         return mlxsw_reg_write(mlxsw_sp->core, MLXSW_REG(sldr), sldr_pl);
5582 }
5583
5584 static int
5585 mlxsw_sp_port_lag_col_dist_enable(struct mlxsw_sp_port *mlxsw_sp_port)
5586 {
5587         int err;
5588
5589         err = mlxsw_sp_lag_col_port_enable(mlxsw_sp_port,
5590                                            mlxsw_sp_port->lag_id);
5591         if (err)
5592                 return err;
5593
5594         err = mlxsw_sp_lag_dist_port_add(mlxsw_sp_port, mlxsw_sp_port->lag_id);
5595         if (err)
5596                 goto err_dist_port_add;
5597
5598         return 0;
5599
5600 err_dist_port_add:
5601         mlxsw_sp_lag_col_port_disable(mlxsw_sp_port, mlxsw_sp_port->lag_id);
5602         return err;
5603 }
5604
5605 static int
5606 mlxsw_sp_port_lag_col_dist_disable(struct mlxsw_sp_port *mlxsw_sp_port)
5607 {
5608         int err;
5609
5610         err = mlxsw_sp_lag_dist_port_remove(mlxsw_sp_port,
5611                                             mlxsw_sp_port->lag_id);
5612         if (err)
5613                 return err;
5614
5615         err = mlxsw_sp_lag_col_port_disable(mlxsw_sp_port,
5616                                             mlxsw_sp_port->lag_id);
5617         if (err)
5618                 goto err_col_port_disable;
5619
5620         return 0;
5621
5622 err_col_port_disable:
5623         mlxsw_sp_lag_dist_port_add(mlxsw_sp_port, mlxsw_sp_port->lag_id);
5624         return err;
5625 }
5626
5627 static int mlxsw_sp_port_lag_changed(struct mlxsw_sp_port *mlxsw_sp_port,
5628                                      struct netdev_lag_lower_state_info *info)
5629 {
5630         if (info->tx_enabled)
5631                 return mlxsw_sp_port_lag_col_dist_enable(mlxsw_sp_port);
5632         else
5633                 return mlxsw_sp_port_lag_col_dist_disable(mlxsw_sp_port);
5634 }
5635
5636 static int mlxsw_sp_port_stp_set(struct mlxsw_sp_port *mlxsw_sp_port,
5637                                  bool enable)
5638 {
5639         struct mlxsw_sp *mlxsw_sp = mlxsw_sp_port->mlxsw_sp;
5640         enum mlxsw_reg_spms_state spms_state;
5641         char *spms_pl;
5642         u16 vid;
5643         int err;
5644
5645         spms_state = enable ? MLXSW_REG_SPMS_STATE_FORWARDING :
5646                               MLXSW_REG_SPMS_STATE_DISCARDING;
5647
5648         spms_pl = kmalloc(MLXSW_REG_SPMS_LEN, GFP_KERNEL);
5649         if (!spms_pl)
5650                 return -ENOMEM;
5651         mlxsw_reg_spms_pack(spms_pl, mlxsw_sp_port->local_port);
5652
5653         for (vid = 0; vid < VLAN_N_VID; vid++)
5654                 mlxsw_reg_spms_vid_pack(spms_pl, vid, spms_state);
5655
5656         err = mlxsw_reg_write(mlxsw_sp->core, MLXSW_REG(spms), spms_pl);
5657         kfree(spms_pl);
5658         return err;
5659 }
5660
5661 static int mlxsw_sp_port_ovs_join(struct mlxsw_sp_port *mlxsw_sp_port)
5662 {
5663         u16 vid = 1;
5664         int err;
5665
5666         err = mlxsw_sp_port_vp_mode_set(mlxsw_sp_port, true);
5667         if (err)
5668                 return err;
5669         err = mlxsw_sp_port_stp_set(mlxsw_sp_port, true);
5670         if (err)
5671                 goto err_port_stp_set;
5672         err = mlxsw_sp_port_vlan_set(mlxsw_sp_port, 1, VLAN_N_VID - 2,
5673                                      true, false);
5674         if (err)
5675                 goto err_port_vlan_set;
5676
5677         for (; vid <= VLAN_N_VID - 1; vid++) {
5678                 err = mlxsw_sp_port_vid_learning_set(mlxsw_sp_port,
5679                                                      vid, false);
5680                 if (err)
5681                         goto err_vid_learning_set;
5682         }
5683
5684         return 0;
5685
5686 err_vid_learning_set:
5687         for (vid--; vid >= 1; vid--)
5688                 mlxsw_sp_port_vid_learning_set(mlxsw_sp_port, vid, true);
5689 err_port_vlan_set:
5690         mlxsw_sp_port_stp_set(mlxsw_sp_port, false);
5691 err_port_stp_set:
5692         mlxsw_sp_port_vp_mode_set(mlxsw_sp_port, false);
5693         return err;
5694 }
5695
5696 static void mlxsw_sp_port_ovs_leave(struct mlxsw_sp_port *mlxsw_sp_port)
5697 {
5698         u16 vid;
5699
5700         for (vid = VLAN_N_VID - 1; vid >= 1; vid--)
5701                 mlxsw_sp_port_vid_learning_set(mlxsw_sp_port,
5702                                                vid, true);
5703
5704         mlxsw_sp_port_vlan_set(mlxsw_sp_port, 1, VLAN_N_VID - 2,
5705                                false, false);
5706         mlxsw_sp_port_stp_set(mlxsw_sp_port, false);
5707         mlxsw_sp_port_vp_mode_set(mlxsw_sp_port, false);
5708 }
5709
5710 static bool mlxsw_sp_bridge_has_multiple_vxlans(struct net_device *br_dev)
5711 {
5712         unsigned int num_vxlans = 0;
5713         struct net_device *dev;
5714         struct list_head *iter;
5715
5716         netdev_for_each_lower_dev(br_dev, dev, iter) {
5717                 if (netif_is_vxlan(dev))
5718                         num_vxlans++;
5719         }
5720
5721         return num_vxlans > 1;
5722 }
5723
5724 static bool mlxsw_sp_bridge_vxlan_vlan_is_valid(struct net_device *br_dev)
5725 {
5726         DECLARE_BITMAP(vlans, VLAN_N_VID) = {0};
5727         struct net_device *dev;
5728         struct list_head *iter;
5729
5730         netdev_for_each_lower_dev(br_dev, dev, iter) {
5731                 u16 pvid;
5732                 int err;
5733
5734                 if (!netif_is_vxlan(dev))
5735                         continue;
5736
5737                 err = mlxsw_sp_vxlan_mapped_vid(dev, &pvid);
5738                 if (err || !pvid)
5739                         continue;
5740
5741                 if (test_and_set_bit(pvid, vlans))
5742                         return false;
5743         }
5744
5745         return true;
5746 }
5747
5748 static bool mlxsw_sp_bridge_vxlan_is_valid(struct net_device *br_dev,
5749                                            struct netlink_ext_ack *extack)
5750 {
5751         if (br_multicast_enabled(br_dev)) {
5752                 NL_SET_ERR_MSG_MOD(extack, "Multicast can not be enabled on a bridge with a VxLAN device");
5753                 return false;
5754         }
5755
5756         if (!br_vlan_enabled(br_dev) &&
5757             mlxsw_sp_bridge_has_multiple_vxlans(br_dev)) {
5758                 NL_SET_ERR_MSG_MOD(extack, "Multiple VxLAN devices are not supported in a VLAN-unaware bridge");
5759                 return false;
5760         }
5761
5762         if (br_vlan_enabled(br_dev) &&
5763             !mlxsw_sp_bridge_vxlan_vlan_is_valid(br_dev)) {
5764                 NL_SET_ERR_MSG_MOD(extack, "Multiple VxLAN devices cannot have the same VLAN as PVID and egress untagged");
5765                 return false;
5766         }
5767
5768         return true;
5769 }
5770
5771 static int mlxsw_sp_netdevice_port_upper_event(struct net_device *lower_dev,
5772                                                struct net_device *dev,
5773                                                unsigned long event, void *ptr)
5774 {
5775         struct netdev_notifier_changeupper_info *info;
5776         struct mlxsw_sp_port *mlxsw_sp_port;
5777         struct netlink_ext_ack *extack;
5778         struct net_device *upper_dev;
5779         struct mlxsw_sp *mlxsw_sp;
5780         int err = 0;
5781
5782         mlxsw_sp_port = netdev_priv(dev);
5783         mlxsw_sp = mlxsw_sp_port->mlxsw_sp;
5784         info = ptr;
5785         extack = netdev_notifier_info_to_extack(&info->info);
5786
5787         switch (event) {
5788         case NETDEV_PRECHANGEUPPER:
5789                 upper_dev = info->upper_dev;
5790                 if (!is_vlan_dev(upper_dev) &&
5791                     !netif_is_lag_master(upper_dev) &&
5792                     !netif_is_bridge_master(upper_dev) &&
5793                     !netif_is_ovs_master(upper_dev) &&
5794                     !netif_is_macvlan(upper_dev)) {
5795                         NL_SET_ERR_MSG_MOD(extack, "Unknown upper device type");
5796                         return -EINVAL;
5797                 }
5798                 if (!info->linking)
5799                         break;
5800                 if (netif_is_bridge_master(upper_dev) &&
5801                     !mlxsw_sp_bridge_device_is_offloaded(mlxsw_sp, upper_dev) &&
5802                     mlxsw_sp_bridge_has_vxlan(upper_dev) &&
5803                     !mlxsw_sp_bridge_vxlan_is_valid(upper_dev, extack))
5804                         return -EOPNOTSUPP;
5805                 if (netdev_has_any_upper_dev(upper_dev) &&
5806                     (!netif_is_bridge_master(upper_dev) ||
5807                      !mlxsw_sp_bridge_device_is_offloaded(mlxsw_sp,
5808                                                           upper_dev))) {
5809                         NL_SET_ERR_MSG_MOD(extack, "Enslaving a port to a device that already has an upper device is not supported");
5810                         return -EINVAL;
5811                 }
5812                 if (netif_is_lag_master(upper_dev) &&
5813                     !mlxsw_sp_master_lag_check(mlxsw_sp, upper_dev,
5814                                                info->upper_info, extack))
5815                         return -EINVAL;
5816                 if (netif_is_lag_master(upper_dev) && vlan_uses_dev(dev)) {
5817                         NL_SET_ERR_MSG_MOD(extack, "Master device is a LAG master and this device has a VLAN");
5818                         return -EINVAL;
5819                 }
5820                 if (netif_is_lag_port(dev) && is_vlan_dev(upper_dev) &&
5821                     !netif_is_lag_master(vlan_dev_real_dev(upper_dev))) {
5822                         NL_SET_ERR_MSG_MOD(extack, "Can not put a VLAN on a LAG port");
5823                         return -EINVAL;
5824                 }
5825                 if (netif_is_macvlan(upper_dev) &&
5826                     !mlxsw_sp_rif_find_by_dev(mlxsw_sp, lower_dev)) {
5827                         NL_SET_ERR_MSG_MOD(extack, "macvlan is only supported on top of router interfaces");
5828                         return -EOPNOTSUPP;
5829                 }
5830                 if (netif_is_ovs_master(upper_dev) && vlan_uses_dev(dev)) {
5831                         NL_SET_ERR_MSG_MOD(extack, "Master device is an OVS master and this device has a VLAN");
5832                         return -EINVAL;
5833                 }
5834                 if (netif_is_ovs_port(dev) && is_vlan_dev(upper_dev)) {
5835                         NL_SET_ERR_MSG_MOD(extack, "Can not put a VLAN on an OVS port");
5836                         return -EINVAL;
5837                 }
5838                 break;
5839         case NETDEV_CHANGEUPPER:
5840                 upper_dev = info->upper_dev;
5841                 if (netif_is_bridge_master(upper_dev)) {
5842                         if (info->linking)
5843                                 err = mlxsw_sp_port_bridge_join(mlxsw_sp_port,
5844                                                                 lower_dev,
5845                                                                 upper_dev,
5846                                                                 extack);
5847                         else
5848                                 mlxsw_sp_port_bridge_leave(mlxsw_sp_port,
5849                                                            lower_dev,
5850                                                            upper_dev);
5851                 } else if (netif_is_lag_master(upper_dev)) {
5852                         if (info->linking) {
5853                                 err = mlxsw_sp_port_lag_join(mlxsw_sp_port,
5854                                                              upper_dev);
5855                         } else {
5856                                 mlxsw_sp_port_lag_col_dist_disable(mlxsw_sp_port);
5857                                 mlxsw_sp_port_lag_leave(mlxsw_sp_port,
5858                                                         upper_dev);
5859                         }
5860                 } else if (netif_is_ovs_master(upper_dev)) {
5861                         if (info->linking)
5862                                 err = mlxsw_sp_port_ovs_join(mlxsw_sp_port);
5863                         else
5864                                 mlxsw_sp_port_ovs_leave(mlxsw_sp_port);
5865                 } else if (netif_is_macvlan(upper_dev)) {
5866                         if (!info->linking)
5867                                 mlxsw_sp_rif_macvlan_del(mlxsw_sp, upper_dev);
5868                 } else if (is_vlan_dev(upper_dev)) {
5869                         struct net_device *br_dev;
5870
5871                         if (!netif_is_bridge_port(upper_dev))
5872                                 break;
5873                         if (info->linking)
5874                                 break;
5875                         br_dev = netdev_master_upper_dev_get(upper_dev);
5876                         mlxsw_sp_port_bridge_leave(mlxsw_sp_port, upper_dev,
5877                                                    br_dev);
5878                 }
5879                 break;
5880         }
5881
5882         return err;
5883 }
5884
5885 static int mlxsw_sp_netdevice_port_lower_event(struct net_device *dev,
5886                                                unsigned long event, void *ptr)
5887 {
5888         struct netdev_notifier_changelowerstate_info *info;
5889         struct mlxsw_sp_port *mlxsw_sp_port;
5890         int err;
5891
5892         mlxsw_sp_port = netdev_priv(dev);
5893         info = ptr;
5894
5895         switch (event) {
5896         case NETDEV_CHANGELOWERSTATE:
5897                 if (netif_is_lag_port(dev) && mlxsw_sp_port->lagged) {
5898                         err = mlxsw_sp_port_lag_changed(mlxsw_sp_port,
5899                                                         info->lower_state_info);
5900                         if (err)
5901                                 netdev_err(dev, "Failed to reflect link aggregation lower state change\n");
5902                 }
5903                 break;
5904         }
5905
5906         return 0;
5907 }
5908
5909 static int mlxsw_sp_netdevice_port_event(struct net_device *lower_dev,
5910                                          struct net_device *port_dev,
5911                                          unsigned long event, void *ptr)
5912 {
5913         switch (event) {
5914         case NETDEV_PRECHANGEUPPER:
5915         case NETDEV_CHANGEUPPER:
5916                 return mlxsw_sp_netdevice_port_upper_event(lower_dev, port_dev,
5917                                                            event, ptr);
5918         case NETDEV_CHANGELOWERSTATE:
5919                 return mlxsw_sp_netdevice_port_lower_event(port_dev, event,
5920                                                            ptr);
5921         }
5922
5923         return 0;
5924 }
5925
5926 static int mlxsw_sp_netdevice_lag_event(struct net_device *lag_dev,
5927                                         unsigned long event, void *ptr)
5928 {
5929         struct net_device *dev;
5930         struct list_head *iter;
5931         int ret;
5932
5933         netdev_for_each_lower_dev(lag_dev, dev, iter) {
5934                 if (mlxsw_sp_port_dev_check(dev)) {
5935                         ret = mlxsw_sp_netdevice_port_event(lag_dev, dev, event,
5936                                                             ptr);
5937                         if (ret)
5938                                 return ret;
5939                 }
5940         }
5941
5942         return 0;
5943 }
5944
5945 static int mlxsw_sp_netdevice_port_vlan_event(struct net_device *vlan_dev,
5946                                               struct net_device *dev,
5947                                               unsigned long event, void *ptr,
5948                                               u16 vid)
5949 {
5950         struct mlxsw_sp_port *mlxsw_sp_port = netdev_priv(dev);
5951         struct mlxsw_sp *mlxsw_sp = mlxsw_sp_port->mlxsw_sp;
5952         struct netdev_notifier_changeupper_info *info = ptr;
5953         struct netlink_ext_ack *extack;
5954         struct net_device *upper_dev;
5955         int err = 0;
5956
5957         extack = netdev_notifier_info_to_extack(&info->info);
5958
5959         switch (event) {
5960         case NETDEV_PRECHANGEUPPER:
5961                 upper_dev = info->upper_dev;
5962                 if (!netif_is_bridge_master(upper_dev) &&
5963                     !netif_is_macvlan(upper_dev)) {
5964                         NL_SET_ERR_MSG_MOD(extack, "Unknown upper device type");
5965                         return -EINVAL;
5966                 }
5967                 if (!info->linking)
5968                         break;
5969                 if (netif_is_bridge_master(upper_dev) &&
5970                     !mlxsw_sp_bridge_device_is_offloaded(mlxsw_sp, upper_dev) &&
5971                     mlxsw_sp_bridge_has_vxlan(upper_dev) &&
5972                     !mlxsw_sp_bridge_vxlan_is_valid(upper_dev, extack))
5973                         return -EOPNOTSUPP;
5974                 if (netdev_has_any_upper_dev(upper_dev) &&
5975                     (!netif_is_bridge_master(upper_dev) ||
5976                      !mlxsw_sp_bridge_device_is_offloaded(mlxsw_sp,
5977                                                           upper_dev))) {
5978                         NL_SET_ERR_MSG_MOD(extack, "Enslaving a port to a device that already has an upper device is not supported");
5979                         return -EINVAL;
5980                 }
5981                 if (netif_is_macvlan(upper_dev) &&
5982                     !mlxsw_sp_rif_find_by_dev(mlxsw_sp, vlan_dev)) {
5983                         NL_SET_ERR_MSG_MOD(extack, "macvlan is only supported on top of router interfaces");
5984                         return -EOPNOTSUPP;
5985                 }
5986                 break;
5987         case NETDEV_CHANGEUPPER:
5988                 upper_dev = info->upper_dev;
5989                 if (netif_is_bridge_master(upper_dev)) {
5990                         if (info->linking)
5991                                 err = mlxsw_sp_port_bridge_join(mlxsw_sp_port,
5992                                                                 vlan_dev,
5993                                                                 upper_dev,
5994                                                                 extack);
5995                         else
5996                                 mlxsw_sp_port_bridge_leave(mlxsw_sp_port,
5997                                                            vlan_dev,
5998                                                            upper_dev);
5999                 } else if (netif_is_macvlan(upper_dev)) {
6000                         if (!info->linking)
6001                                 mlxsw_sp_rif_macvlan_del(mlxsw_sp, upper_dev);
6002                 } else {
6003                         err = -EINVAL;
6004                         WARN_ON(1);
6005                 }
6006                 break;
6007         }
6008
6009         return err;
6010 }
6011
6012 static int mlxsw_sp_netdevice_lag_port_vlan_event(struct net_device *vlan_dev,
6013                                                   struct net_device *lag_dev,
6014                                                   unsigned long event,
6015                                                   void *ptr, u16 vid)
6016 {
6017         struct net_device *dev;
6018         struct list_head *iter;
6019         int ret;
6020
6021         netdev_for_each_lower_dev(lag_dev, dev, iter) {
6022                 if (mlxsw_sp_port_dev_check(dev)) {
6023                         ret = mlxsw_sp_netdevice_port_vlan_event(vlan_dev, dev,
6024                                                                  event, ptr,
6025                                                                  vid);
6026                         if (ret)
6027                                 return ret;
6028                 }
6029         }
6030
6031         return 0;
6032 }
6033
6034 static int mlxsw_sp_netdevice_bridge_vlan_event(struct net_device *vlan_dev,
6035                                                 struct net_device *br_dev,
6036                                                 unsigned long event, void *ptr,
6037                                                 u16 vid)
6038 {
6039         struct mlxsw_sp *mlxsw_sp = mlxsw_sp_lower_get(vlan_dev);
6040         struct netdev_notifier_changeupper_info *info = ptr;
6041         struct netlink_ext_ack *extack;
6042         struct net_device *upper_dev;
6043
6044         if (!mlxsw_sp)
6045                 return 0;
6046
6047         extack = netdev_notifier_info_to_extack(&info->info);
6048
6049         switch (event) {
6050         case NETDEV_PRECHANGEUPPER:
6051                 upper_dev = info->upper_dev;
6052                 if (!netif_is_macvlan(upper_dev)) {
6053                         NL_SET_ERR_MSG_MOD(extack, "Unknown upper device type");
6054                         return -EOPNOTSUPP;
6055                 }
6056                 if (!info->linking)
6057                         break;
6058                 if (netif_is_macvlan(upper_dev) &&
6059                     !mlxsw_sp_rif_find_by_dev(mlxsw_sp, vlan_dev)) {
6060                         NL_SET_ERR_MSG_MOD(extack, "macvlan is only supported on top of router interfaces");
6061                         return -EOPNOTSUPP;
6062                 }
6063                 break;
6064         case NETDEV_CHANGEUPPER:
6065                 upper_dev = info->upper_dev;
6066                 if (info->linking)
6067                         break;
6068                 if (netif_is_macvlan(upper_dev))
6069                         mlxsw_sp_rif_macvlan_del(mlxsw_sp, upper_dev);
6070                 break;
6071         }
6072
6073         return 0;
6074 }
6075
6076 static int mlxsw_sp_netdevice_vlan_event(struct net_device *vlan_dev,
6077                                          unsigned long event, void *ptr)
6078 {
6079         struct net_device *real_dev = vlan_dev_real_dev(vlan_dev);
6080         u16 vid = vlan_dev_vlan_id(vlan_dev);
6081
6082         if (mlxsw_sp_port_dev_check(real_dev))
6083                 return mlxsw_sp_netdevice_port_vlan_event(vlan_dev, real_dev,
6084                                                           event, ptr, vid);
6085         else if (netif_is_lag_master(real_dev))
6086                 return mlxsw_sp_netdevice_lag_port_vlan_event(vlan_dev,
6087                                                               real_dev, event,
6088                                                               ptr, vid);
6089         else if (netif_is_bridge_master(real_dev))
6090                 return mlxsw_sp_netdevice_bridge_vlan_event(vlan_dev, real_dev,
6091                                                             event, ptr, vid);
6092
6093         return 0;
6094 }
6095
6096 static int mlxsw_sp_netdevice_bridge_event(struct net_device *br_dev,
6097                                            unsigned long event, void *ptr)
6098 {
6099         struct mlxsw_sp *mlxsw_sp = mlxsw_sp_lower_get(br_dev);
6100         struct netdev_notifier_changeupper_info *info = ptr;
6101         struct netlink_ext_ack *extack;
6102         struct net_device *upper_dev;
6103
6104         if (!mlxsw_sp)
6105                 return 0;
6106
6107         extack = netdev_notifier_info_to_extack(&info->info);
6108
6109         switch (event) {
6110         case NETDEV_PRECHANGEUPPER:
6111                 upper_dev = info->upper_dev;
6112                 if (!is_vlan_dev(upper_dev) && !netif_is_macvlan(upper_dev)) {
6113                         NL_SET_ERR_MSG_MOD(extack, "Unknown upper device type");
6114                         return -EOPNOTSUPP;
6115                 }
6116                 if (!info->linking)
6117                         break;
6118                 if (netif_is_macvlan(upper_dev) &&
6119                     !mlxsw_sp_rif_find_by_dev(mlxsw_sp, br_dev)) {
6120                         NL_SET_ERR_MSG_MOD(extack, "macvlan is only supported on top of router interfaces");
6121                         return -EOPNOTSUPP;
6122                 }
6123                 break;
6124         case NETDEV_CHANGEUPPER:
6125                 upper_dev = info->upper_dev;
6126                 if (info->linking)
6127                         break;
6128                 if (is_vlan_dev(upper_dev))
6129                         mlxsw_sp_rif_destroy_by_dev(mlxsw_sp, upper_dev);
6130                 if (netif_is_macvlan(upper_dev))
6131                         mlxsw_sp_rif_macvlan_del(mlxsw_sp, upper_dev);
6132                 break;
6133         }
6134
6135         return 0;
6136 }
6137
6138 static int mlxsw_sp_netdevice_macvlan_event(struct net_device *macvlan_dev,
6139                                             unsigned long event, void *ptr)
6140 {
6141         struct mlxsw_sp *mlxsw_sp = mlxsw_sp_lower_get(macvlan_dev);
6142         struct netdev_notifier_changeupper_info *info = ptr;
6143         struct netlink_ext_ack *extack;
6144
6145         if (!mlxsw_sp || event != NETDEV_PRECHANGEUPPER)
6146                 return 0;
6147
6148         extack = netdev_notifier_info_to_extack(&info->info);
6149
6150         /* VRF enslavement is handled in mlxsw_sp_netdevice_vrf_event() */
6151         NL_SET_ERR_MSG_MOD(extack, "Unknown upper device type");
6152
6153         return -EOPNOTSUPP;
6154 }
6155
6156 static bool mlxsw_sp_is_vrf_event(unsigned long event, void *ptr)
6157 {
6158         struct netdev_notifier_changeupper_info *info = ptr;
6159
6160         if (event != NETDEV_PRECHANGEUPPER && event != NETDEV_CHANGEUPPER)
6161                 return false;
6162         return netif_is_l3_master(info->upper_dev);
6163 }
6164
6165 static int mlxsw_sp_netdevice_vxlan_event(struct mlxsw_sp *mlxsw_sp,
6166                                           struct net_device *dev,
6167                                           unsigned long event, void *ptr)
6168 {
6169         struct netdev_notifier_changeupper_info *cu_info;
6170         struct netdev_notifier_info *info = ptr;
6171         struct netlink_ext_ack *extack;
6172         struct net_device *upper_dev;
6173
6174         extack = netdev_notifier_info_to_extack(info);
6175
6176         switch (event) {
6177         case NETDEV_CHANGEUPPER:
6178                 cu_info = container_of(info,
6179                                        struct netdev_notifier_changeupper_info,
6180                                        info);
6181                 upper_dev = cu_info->upper_dev;
6182                 if (!netif_is_bridge_master(upper_dev))
6183                         return 0;
6184                 if (!mlxsw_sp_lower_get(upper_dev))
6185                         return 0;
6186                 if (!mlxsw_sp_bridge_vxlan_is_valid(upper_dev, extack))
6187                         return -EOPNOTSUPP;
6188                 if (cu_info->linking) {
6189                         if (!netif_running(dev))
6190                                 return 0;
6191                         /* When the bridge is VLAN-aware, the VNI of the VxLAN
6192                          * device needs to be mapped to a VLAN, but at this
6193                          * point no VLANs are configured on the VxLAN device
6194                          */
6195                         if (br_vlan_enabled(upper_dev))
6196                                 return 0;
6197                         return mlxsw_sp_bridge_vxlan_join(mlxsw_sp, upper_dev,
6198                                                           dev, 0, extack);
6199                 } else {
6200                         /* VLANs were already flushed, which triggered the
6201                          * necessary cleanup
6202                          */
6203                         if (br_vlan_enabled(upper_dev))
6204                                 return 0;
6205                         mlxsw_sp_bridge_vxlan_leave(mlxsw_sp, dev);
6206                 }
6207                 break;
6208         case NETDEV_PRE_UP:
6209                 upper_dev = netdev_master_upper_dev_get(dev);
6210                 if (!upper_dev)
6211                         return 0;
6212                 if (!netif_is_bridge_master(upper_dev))
6213                         return 0;
6214                 if (!mlxsw_sp_lower_get(upper_dev))
6215                         return 0;
6216                 return mlxsw_sp_bridge_vxlan_join(mlxsw_sp, upper_dev, dev, 0,
6217                                                   extack);
6218         case NETDEV_DOWN:
6219                 upper_dev = netdev_master_upper_dev_get(dev);
6220                 if (!upper_dev)
6221                         return 0;
6222                 if (!netif_is_bridge_master(upper_dev))
6223                         return 0;
6224                 if (!mlxsw_sp_lower_get(upper_dev))
6225                         return 0;
6226                 mlxsw_sp_bridge_vxlan_leave(mlxsw_sp, dev);
6227                 break;
6228         }
6229
6230         return 0;
6231 }
6232
6233 static int mlxsw_sp_netdevice_event(struct notifier_block *nb,
6234                                     unsigned long event, void *ptr)
6235 {
6236         struct net_device *dev = netdev_notifier_info_to_dev(ptr);
6237         struct mlxsw_sp_span_entry *span_entry;
6238         struct mlxsw_sp *mlxsw_sp;
6239         int err = 0;
6240
6241         mlxsw_sp = container_of(nb, struct mlxsw_sp, netdevice_nb);
6242         if (event == NETDEV_UNREGISTER) {
6243                 span_entry = mlxsw_sp_span_entry_find_by_port(mlxsw_sp, dev);
6244                 if (span_entry)
6245                         mlxsw_sp_span_entry_invalidate(mlxsw_sp, span_entry);
6246         }
6247         mlxsw_sp_span_respin(mlxsw_sp);
6248
6249         if (netif_is_vxlan(dev))
6250                 err = mlxsw_sp_netdevice_vxlan_event(mlxsw_sp, dev, event, ptr);
6251         if (mlxsw_sp_netdev_is_ipip_ol(mlxsw_sp, dev))
6252                 err = mlxsw_sp_netdevice_ipip_ol_event(mlxsw_sp, dev,
6253                                                        event, ptr);
6254         else if (mlxsw_sp_netdev_is_ipip_ul(mlxsw_sp, dev))
6255                 err = mlxsw_sp_netdevice_ipip_ul_event(mlxsw_sp, dev,
6256                                                        event, ptr);
6257         else if (event == NETDEV_PRE_CHANGEADDR ||
6258                  event == NETDEV_CHANGEADDR ||
6259                  event == NETDEV_CHANGEMTU)
6260                 err = mlxsw_sp_netdevice_router_port_event(dev, event, ptr);
6261         else if (mlxsw_sp_is_vrf_event(event, ptr))
6262                 err = mlxsw_sp_netdevice_vrf_event(dev, event, ptr);
6263         else if (mlxsw_sp_port_dev_check(dev))
6264                 err = mlxsw_sp_netdevice_port_event(dev, dev, event, ptr);
6265         else if (netif_is_lag_master(dev))
6266                 err = mlxsw_sp_netdevice_lag_event(dev, event, ptr);
6267         else if (is_vlan_dev(dev))
6268                 err = mlxsw_sp_netdevice_vlan_event(dev, event, ptr);
6269         else if (netif_is_bridge_master(dev))
6270                 err = mlxsw_sp_netdevice_bridge_event(dev, event, ptr);
6271         else if (netif_is_macvlan(dev))
6272                 err = mlxsw_sp_netdevice_macvlan_event(dev, event, ptr);
6273
6274         return notifier_from_errno(err);
6275 }
6276
6277 static struct notifier_block mlxsw_sp_inetaddr_valid_nb __read_mostly = {
6278         .notifier_call = mlxsw_sp_inetaddr_valid_event,
6279 };
6280
6281 static struct notifier_block mlxsw_sp_inet6addr_valid_nb __read_mostly = {
6282         .notifier_call = mlxsw_sp_inet6addr_valid_event,
6283 };
6284
6285 static const struct pci_device_id mlxsw_sp1_pci_id_table[] = {
6286         {PCI_VDEVICE(MELLANOX, PCI_DEVICE_ID_MELLANOX_SPECTRUM), 0},
6287         {0, },
6288 };
6289
6290 static struct pci_driver mlxsw_sp1_pci_driver = {
6291         .name = mlxsw_sp1_driver_name,
6292         .id_table = mlxsw_sp1_pci_id_table,
6293 };
6294
6295 static const struct pci_device_id mlxsw_sp2_pci_id_table[] = {
6296         {PCI_VDEVICE(MELLANOX, PCI_DEVICE_ID_MELLANOX_SPECTRUM2), 0},
6297         {0, },
6298 };
6299
6300 static struct pci_driver mlxsw_sp2_pci_driver = {
6301         .name = mlxsw_sp2_driver_name,
6302         .id_table = mlxsw_sp2_pci_id_table,
6303 };
6304
6305 static int __init mlxsw_sp_module_init(void)
6306 {
6307         int err;
6308
6309         register_inetaddr_validator_notifier(&mlxsw_sp_inetaddr_valid_nb);
6310         register_inet6addr_validator_notifier(&mlxsw_sp_inet6addr_valid_nb);
6311
6312         err = mlxsw_core_driver_register(&mlxsw_sp1_driver);
6313         if (err)
6314                 goto err_sp1_core_driver_register;
6315
6316         err = mlxsw_core_driver_register(&mlxsw_sp2_driver);
6317         if (err)
6318                 goto err_sp2_core_driver_register;
6319
6320         err = mlxsw_pci_driver_register(&mlxsw_sp1_pci_driver);
6321         if (err)
6322                 goto err_sp1_pci_driver_register;
6323
6324         err = mlxsw_pci_driver_register(&mlxsw_sp2_pci_driver);
6325         if (err)
6326                 goto err_sp2_pci_driver_register;
6327
6328         return 0;
6329
6330 err_sp2_pci_driver_register:
6331         mlxsw_pci_driver_unregister(&mlxsw_sp1_pci_driver);
6332 err_sp1_pci_driver_register:
6333         mlxsw_core_driver_unregister(&mlxsw_sp2_driver);
6334 err_sp2_core_driver_register:
6335         mlxsw_core_driver_unregister(&mlxsw_sp1_driver);
6336 err_sp1_core_driver_register:
6337         unregister_inet6addr_validator_notifier(&mlxsw_sp_inet6addr_valid_nb);
6338         unregister_inetaddr_validator_notifier(&mlxsw_sp_inetaddr_valid_nb);
6339         return err;
6340 }
6341
6342 static void __exit mlxsw_sp_module_exit(void)
6343 {
6344         mlxsw_pci_driver_unregister(&mlxsw_sp2_pci_driver);
6345         mlxsw_pci_driver_unregister(&mlxsw_sp1_pci_driver);
6346         mlxsw_core_driver_unregister(&mlxsw_sp2_driver);
6347         mlxsw_core_driver_unregister(&mlxsw_sp1_driver);
6348         unregister_inet6addr_validator_notifier(&mlxsw_sp_inet6addr_valid_nb);
6349         unregister_inetaddr_validator_notifier(&mlxsw_sp_inetaddr_valid_nb);
6350 }
6351
6352 module_init(mlxsw_sp_module_init);
6353 module_exit(mlxsw_sp_module_exit);
6354
6355 MODULE_LICENSE("Dual BSD/GPL");
6356 MODULE_AUTHOR("Jiri Pirko <jiri@mellanox.com>");
6357 MODULE_DESCRIPTION("Mellanox Spectrum driver");
6358 MODULE_DEVICE_TABLE(pci, mlxsw_sp1_pci_id_table);
6359 MODULE_DEVICE_TABLE(pci, mlxsw_sp2_pci_id_table);
6360 /*(DEBLOBBED)*/