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