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 thres_cells = 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 delay_cells = 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, ð_proto_cap, 2922 ð_proto_admin, ð_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, ð_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, ð_proto_cap, 3063 ð_proto_admin, ð_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 ð_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 ×tamp); 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); 6333