1 /* SPDX-License-Identifier: BSD-3-Clause OR GPL-2.0 */ 2 /* Copyright (c) 2015-2018 Mellanox Technologies. All rights reserved */ 3 4 #ifndef _MLXSW_CORE_H 5 #define _MLXSW_CORE_H 6 7 #include <linux/module.h> 8 #include <linux/device.h> 9 #include <linux/slab.h> 10 #include <linux/gfp.h> 11 #include <linux/types.h> 12 #include <linux/skbuff.h> 13 #include <linux/workqueue.h> 14 #include <linux/net_namespace.h> 15 #include <net/devlink.h> 16 17 #include "trap.h" 18 #include "reg.h" 19 #include "cmd.h" 20 #include "resources.h" 21 22 struct mlxsw_core; 23 struct mlxsw_core_port; 24 struct mlxsw_driver; 25 struct mlxsw_bus; 26 struct mlxsw_bus_info; 27 struct mlxsw_fw_rev; 28 29 unsigned int mlxsw_core_max_ports(const struct mlxsw_core *mlxsw_core); 30 31 void *mlxsw_core_driver_priv(struct mlxsw_core *mlxsw_core); 32 33 bool mlxsw_core_res_query_enabled(const struct mlxsw_core *mlxsw_core); 34 35 bool 36 mlxsw_core_fw_rev_minor_subminor_validate(const struct mlxsw_fw_rev *rev, 37 const struct mlxsw_fw_rev *req_rev); 38 39 int mlxsw_core_driver_register(struct mlxsw_driver *mlxsw_driver); 40 void mlxsw_core_driver_unregister(struct mlxsw_driver *mlxsw_driver); 41 42 int mlxsw_core_bus_device_register(const struct mlxsw_bus_info *mlxsw_bus_info, 43 const struct mlxsw_bus *mlxsw_bus, 44 void *bus_priv, bool reload, 45 struct devlink *devlink, 46 struct netlink_ext_ack *extack); 47 void mlxsw_core_bus_device_unregister(struct mlxsw_core *mlxsw_core, bool reload); 48 49 struct mlxsw_tx_info { 50 u8 local_port; 51 bool is_emad; 52 }; 53 54 bool mlxsw_core_skb_transmit_busy(struct mlxsw_core *mlxsw_core, 55 const struct mlxsw_tx_info *tx_info); 56 int mlxsw_core_skb_transmit(struct mlxsw_core *mlxsw_core, struct sk_buff *skb, 57 const struct mlxsw_tx_info *tx_info); 58 void mlxsw_core_ptp_transmitted(struct mlxsw_core *mlxsw_core, 59 struct sk_buff *skb, u8 local_port); 60 61 struct mlxsw_rx_listener { 62 void (*func)(struct sk_buff *skb, u8 local_port, void *priv); 63 u8 local_port; 64 u8 mirror_reason; 65 u16 trap_id; 66 }; 67 68 struct mlxsw_event_listener { 69 void (*func)(const struct mlxsw_reg_info *reg, 70 char *payload, void *priv); 71 enum mlxsw_event_trap_id trap_id; 72 }; 73 74 struct mlxsw_listener { 75 u16 trap_id; 76 union { 77 struct mlxsw_rx_listener rx_listener; 78 struct mlxsw_event_listener event_listener; 79 }; 80 enum mlxsw_reg_hpkt_action en_action; /* Action when enabled */ 81 enum mlxsw_reg_hpkt_action dis_action; /* Action when disabled */ 82 u8 en_trap_group; /* Trap group when enabled */ 83 u8 dis_trap_group; /* Trap group when disabled */ 84 u8 is_ctrl:1, /* should go via control buffer or not */ 85 is_event:1, 86 enabled_on_register:1; /* Trap should be enabled when listener 87 * is registered. 88 */ 89 }; 90 91 #define __MLXSW_RXL(_func, _trap_id, _en_action, _is_ctrl, _en_trap_group, \ 92 _dis_action, _enabled_on_register, _dis_trap_group, \ 93 _mirror_reason) \ 94 { \ 95 .trap_id = MLXSW_TRAP_ID_##_trap_id, \ 96 .rx_listener = \ 97 { \ 98 .func = _func, \ 99 .local_port = MLXSW_PORT_DONT_CARE, \ 100 .mirror_reason = _mirror_reason, \ 101 .trap_id = MLXSW_TRAP_ID_##_trap_id, \ 102 }, \ 103 .en_action = MLXSW_REG_HPKT_ACTION_##_en_action, \ 104 .dis_action = MLXSW_REG_HPKT_ACTION_##_dis_action, \ 105 .en_trap_group = MLXSW_REG_HTGT_TRAP_GROUP_##_en_trap_group, \ 106 .dis_trap_group = MLXSW_REG_HTGT_TRAP_GROUP_##_dis_trap_group, \ 107 .is_ctrl = _is_ctrl, \ 108 .enabled_on_register = _enabled_on_register, \ 109 } 110 111 #define MLXSW_RXL(_func, _trap_id, _en_action, _is_ctrl, _trap_group, \ 112 _dis_action) \ 113 __MLXSW_RXL(_func, _trap_id, _en_action, _is_ctrl, _trap_group, \ 114 _dis_action, true, _trap_group, 0) 115 116 #define MLXSW_RXL_DIS(_func, _trap_id, _en_action, _is_ctrl, _en_trap_group, \ 117 _dis_action, _dis_trap_group) \ 118 __MLXSW_RXL(_func, _trap_id, _en_action, _is_ctrl, _en_trap_group, \ 119 _dis_action, false, _dis_trap_group, 0) 120 121 #define MLXSW_RXL_MIRROR(_func, _session_id, _trap_group, _mirror_reason) \ 122 __MLXSW_RXL(_func, MIRROR_SESSION##_session_id, TRAP_TO_CPU, false, \ 123 _trap_group, TRAP_TO_CPU, true, _trap_group, \ 124 _mirror_reason) 125 126 #define MLXSW_EVENTL(_func, _trap_id, _trap_group) \ 127 { \ 128 .trap_id = MLXSW_TRAP_ID_##_trap_id, \ 129 .event_listener = \ 130 { \ 131 .func = _func, \ 132 .trap_id = MLXSW_TRAP_ID_##_trap_id, \ 133 }, \ 134 .en_action = MLXSW_REG_HPKT_ACTION_TRAP_TO_CPU, \ 135 .en_trap_group = MLXSW_REG_HTGT_TRAP_GROUP_##_trap_group, \ 136 .is_event = true, \ 137 .enabled_on_register = true, \ 138 } 139 140 int mlxsw_core_rx_listener_register(struct mlxsw_core *mlxsw_core, 141 const struct mlxsw_rx_listener *rxl, 142 void *priv, bool enabled); 143 void mlxsw_core_rx_listener_unregister(struct mlxsw_core *mlxsw_core, 144 const struct mlxsw_rx_listener *rxl); 145 146 int mlxsw_core_event_listener_register(struct mlxsw_core *mlxsw_core, 147 const struct mlxsw_event_listener *el, 148 void *priv); 149 void mlxsw_core_event_listener_unregister(struct mlxsw_core *mlxsw_core, 150 const struct mlxsw_event_listener *el); 151 152 int mlxsw_core_trap_register(struct mlxsw_core *mlxsw_core, 153 const struct mlxsw_listener *listener, 154 void *priv); 155 void mlxsw_core_trap_unregister(struct mlxsw_core *mlxsw_core, 156 const struct mlxsw_listener *listener, 157 void *priv); 158 int mlxsw_core_trap_state_set(struct mlxsw_core *mlxsw_core, 159 const struct mlxsw_listener *listener, 160 bool enabled); 161 162 typedef void mlxsw_reg_trans_cb_t(struct mlxsw_core *mlxsw_core, char *payload, 163 size_t payload_len, unsigned long cb_priv); 164 165 int mlxsw_reg_trans_query(struct mlxsw_core *mlxsw_core, 166 const struct mlxsw_reg_info *reg, char *payload, 167 struct list_head *bulk_list, 168 mlxsw_reg_trans_cb_t *cb, unsigned long cb_priv); 169 int mlxsw_reg_trans_write(struct mlxsw_core *mlxsw_core, 170 const struct mlxsw_reg_info *reg, char *payload, 171 struct list_head *bulk_list, 172 mlxsw_reg_trans_cb_t *cb, unsigned long cb_priv); 173 int mlxsw_reg_trans_bulk_wait(struct list_head *bulk_list); 174 175 int mlxsw_reg_query(struct mlxsw_core *mlxsw_core, 176 const struct mlxsw_reg_info *reg, char *payload); 177 int mlxsw_reg_write(struct mlxsw_core *mlxsw_core, 178 const struct mlxsw_reg_info *reg, char *payload); 179 180 struct mlxsw_rx_info { 181 bool is_lag; 182 union { 183 u16 sys_port; 184 u16 lag_id; 185 } u; 186 u8 lag_port_index; 187 u8 mirror_reason; 188 int trap_id; 189 }; 190 191 void mlxsw_core_skb_receive(struct mlxsw_core *mlxsw_core, struct sk_buff *skb, 192 struct mlxsw_rx_info *rx_info); 193 194 void mlxsw_core_lag_mapping_set(struct mlxsw_core *mlxsw_core, 195 u16 lag_id, u8 port_index, u8 local_port); 196 u8 mlxsw_core_lag_mapping_get(struct mlxsw_core *mlxsw_core, 197 u16 lag_id, u8 port_index); 198 void mlxsw_core_lag_mapping_clear(struct mlxsw_core *mlxsw_core, 199 u16 lag_id, u8 local_port); 200 201 void *mlxsw_core_port_driver_priv(struct mlxsw_core_port *mlxsw_core_port); 202 int mlxsw_core_port_init(struct mlxsw_core *mlxsw_core, u8 local_port, 203 u32 port_number, bool split, u32 split_port_subnumber, 204 bool splittable, u32 lanes, 205 const unsigned char *switch_id, 206 unsigned char switch_id_len); 207 void mlxsw_core_port_fini(struct mlxsw_core *mlxsw_core, u8 local_port); 208 int mlxsw_core_cpu_port_init(struct mlxsw_core *mlxsw_core, 209 void *port_driver_priv, 210 const unsigned char *switch_id, 211 unsigned char switch_id_len); 212 void mlxsw_core_cpu_port_fini(struct mlxsw_core *mlxsw_core); 213 void mlxsw_core_port_eth_set(struct mlxsw_core *mlxsw_core, u8 local_port, 214 void *port_driver_priv, struct net_device *dev); 215 void mlxsw_core_port_ib_set(struct mlxsw_core *mlxsw_core, u8 local_port, 216 void *port_driver_priv); 217 void mlxsw_core_port_clear(struct mlxsw_core *mlxsw_core, u8 local_port, 218 void *port_driver_priv); 219 enum devlink_port_type mlxsw_core_port_type_get(struct mlxsw_core *mlxsw_core, 220 u8 local_port); 221 struct devlink_port * 222 mlxsw_core_port_devlink_port_get(struct mlxsw_core *mlxsw_core, 223 u8 local_port); 224 int mlxsw_core_module_max_width(struct mlxsw_core *mlxsw_core, u8 module); 225 226 int mlxsw_core_schedule_dw(struct delayed_work *dwork, unsigned long delay); 227 bool mlxsw_core_schedule_work(struct work_struct *work); 228 void mlxsw_core_flush_owq(void); 229 int mlxsw_core_resources_query(struct mlxsw_core *mlxsw_core, char *mbox, 230 struct mlxsw_res *res); 231 232 #define MLXSW_CONFIG_PROFILE_SWID_COUNT 8 233 234 struct mlxsw_swid_config { 235 u8 used_type:1, 236 used_properties:1; 237 u8 type; 238 u8 properties; 239 }; 240 241 struct mlxsw_config_profile { 242 u16 used_max_vepa_channels:1, 243 used_max_mid:1, 244 used_max_pgt:1, 245 used_max_system_port:1, 246 used_max_vlan_groups:1, 247 used_max_regions:1, 248 used_flood_tables:1, 249 used_flood_mode:1, 250 used_max_ib_mc:1, 251 used_max_pkey:1, 252 used_ar_sec:1, 253 used_adaptive_routing_group_cap:1, 254 used_kvd_sizes:1; 255 u8 max_vepa_channels; 256 u16 max_mid; 257 u16 max_pgt; 258 u16 max_system_port; 259 u16 max_vlan_groups; 260 u16 max_regions; 261 u8 max_flood_tables; 262 u8 max_vid_flood_tables; 263 u8 flood_mode; 264 u8 max_fid_offset_flood_tables; 265 u16 fid_offset_flood_table_size; 266 u8 max_fid_flood_tables; 267 u16 fid_flood_table_size; 268 u16 max_ib_mc; 269 u16 max_pkey; 270 u8 ar_sec; 271 u16 adaptive_routing_group_cap; 272 u8 arn; 273 u32 kvd_linear_size; 274 u8 kvd_hash_single_parts; 275 u8 kvd_hash_double_parts; 276 struct mlxsw_swid_config swid_config[MLXSW_CONFIG_PROFILE_SWID_COUNT]; 277 }; 278 279 struct mlxsw_driver { 280 struct list_head list; 281 const char *kind; 282 size_t priv_size; 283 int (*init)(struct mlxsw_core *mlxsw_core, 284 const struct mlxsw_bus_info *mlxsw_bus_info, 285 struct netlink_ext_ack *extack); 286 void (*fini)(struct mlxsw_core *mlxsw_core); 287 int (*basic_trap_groups_set)(struct mlxsw_core *mlxsw_core); 288 int (*port_type_set)(struct mlxsw_core *mlxsw_core, u8 local_port, 289 enum devlink_port_type new_type); 290 int (*port_split)(struct mlxsw_core *mlxsw_core, u8 local_port, 291 unsigned int count, struct netlink_ext_ack *extack); 292 int (*port_unsplit)(struct mlxsw_core *mlxsw_core, u8 local_port, 293 struct netlink_ext_ack *extack); 294 int (*sb_pool_get)(struct mlxsw_core *mlxsw_core, 295 unsigned int sb_index, u16 pool_index, 296 struct devlink_sb_pool_info *pool_info); 297 int (*sb_pool_set)(struct mlxsw_core *mlxsw_core, 298 unsigned int sb_index, u16 pool_index, u32 size, 299 enum devlink_sb_threshold_type threshold_type, 300 struct netlink_ext_ack *extack); 301 int (*sb_port_pool_get)(struct mlxsw_core_port *mlxsw_core_port, 302 unsigned int sb_index, u16 pool_index, 303 u32 *p_threshold); 304 int (*sb_port_pool_set)(struct mlxsw_core_port *mlxsw_core_port, 305 unsigned int sb_index, u16 pool_index, 306 u32 threshold, struct netlink_ext_ack *extack); 307 int (*sb_tc_pool_bind_get)(struct mlxsw_core_port *mlxsw_core_port, 308 unsigned int sb_index, u16 tc_index, 309 enum devlink_sb_pool_type pool_type, 310 u16 *p_pool_index, u32 *p_threshold); 311 int (*sb_tc_pool_bind_set)(struct mlxsw_core_port *mlxsw_core_port, 312 unsigned int sb_index, u16 tc_index, 313 enum devlink_sb_pool_type pool_type, 314 u16 pool_index, u32 threshold, 315 struct netlink_ext_ack *extack); 316 int (*sb_occ_snapshot)(struct mlxsw_core *mlxsw_core, 317 unsigned int sb_index); 318 int (*sb_occ_max_clear)(struct mlxsw_core *mlxsw_core, 319 unsigned int sb_index); 320 int (*sb_occ_port_pool_get)(struct mlxsw_core_port *mlxsw_core_port, 321 unsigned int sb_index, u16 pool_index, 322 u32 *p_cur, u32 *p_max); 323 int (*sb_occ_tc_port_bind_get)(struct mlxsw_core_port *mlxsw_core_port, 324 unsigned int sb_index, u16 tc_index, 325 enum devlink_sb_pool_type pool_type, 326 u32 *p_cur, u32 *p_max); 327 int (*flash_update)(struct mlxsw_core *mlxsw_core, 328 const char *file_name, const char *component, 329 struct netlink_ext_ack *extack); 330 int (*trap_init)(struct mlxsw_core *mlxsw_core, 331 const struct devlink_trap *trap, void *trap_ctx); 332 void (*trap_fini)(struct mlxsw_core *mlxsw_core, 333 const struct devlink_trap *trap, void *trap_ctx); 334 int (*trap_action_set)(struct mlxsw_core *mlxsw_core, 335 const struct devlink_trap *trap, 336 enum devlink_trap_action action, 337 struct netlink_ext_ack *extack); 338 int (*trap_group_init)(struct mlxsw_core *mlxsw_core, 339 const struct devlink_trap_group *group); 340 int (*trap_group_set)(struct mlxsw_core *mlxsw_core, 341 const struct devlink_trap_group *group, 342 const struct devlink_trap_policer *policer, 343 struct netlink_ext_ack *extack); 344 int (*trap_policer_init)(struct mlxsw_core *mlxsw_core, 345 const struct devlink_trap_policer *policer); 346 void (*trap_policer_fini)(struct mlxsw_core *mlxsw_core, 347 const struct devlink_trap_policer *policer); 348 int (*trap_policer_set)(struct mlxsw_core *mlxsw_core, 349 const struct devlink_trap_policer *policer, 350 u64 rate, u64 burst, 351 struct netlink_ext_ack *extack); 352 int (*trap_policer_counter_get)(struct mlxsw_core *mlxsw_core, 353 const struct devlink_trap_policer *policer, 354 u64 *p_drops); 355 void (*txhdr_construct)(struct sk_buff *skb, 356 const struct mlxsw_tx_info *tx_info); 357 int (*resources_register)(struct mlxsw_core *mlxsw_core); 358 int (*kvd_sizes_get)(struct mlxsw_core *mlxsw_core, 359 const struct mlxsw_config_profile *profile, 360 u64 *p_single_size, u64 *p_double_size, 361 u64 *p_linear_size); 362 int (*params_register)(struct mlxsw_core *mlxsw_core); 363 void (*params_unregister)(struct mlxsw_core *mlxsw_core); 364 365 /* Notify a driver that a timestamped packet was transmitted. Driver 366 * is responsible for freeing the passed-in SKB. 367 */ 368 void (*ptp_transmitted)(struct mlxsw_core *mlxsw_core, 369 struct sk_buff *skb, u8 local_port); 370 371 u8 txhdr_len; 372 const struct mlxsw_config_profile *profile; 373 bool res_query_enabled; 374 }; 375 376 int mlxsw_core_kvd_sizes_get(struct mlxsw_core *mlxsw_core, 377 const struct mlxsw_config_profile *profile, 378 u64 *p_single_size, u64 *p_double_size, 379 u64 *p_linear_size); 380 381 void mlxsw_core_fw_flash_start(struct mlxsw_core *mlxsw_core); 382 void mlxsw_core_fw_flash_end(struct mlxsw_core *mlxsw_core); 383 384 u32 mlxsw_core_read_frc_h(struct mlxsw_core *mlxsw_core); 385 u32 mlxsw_core_read_frc_l(struct mlxsw_core *mlxsw_core); 386 387 void mlxsw_core_emad_string_tlv_enable(struct mlxsw_core *mlxsw_core); 388 389 bool mlxsw_core_res_valid(struct mlxsw_core *mlxsw_core, 390 enum mlxsw_res_id res_id); 391 392 #define MLXSW_CORE_RES_VALID(mlxsw_core, short_res_id) \ 393 mlxsw_core_res_valid(mlxsw_core, MLXSW_RES_ID_##short_res_id) 394 395 u64 mlxsw_core_res_get(struct mlxsw_core *mlxsw_core, 396 enum mlxsw_res_id res_id); 397 398 #define MLXSW_CORE_RES_GET(mlxsw_core, short_res_id) \ 399 mlxsw_core_res_get(mlxsw_core, MLXSW_RES_ID_##short_res_id) 400 401 static inline struct net *mlxsw_core_net(struct mlxsw_core *mlxsw_core) 402 { 403 return devlink_net(priv_to_devlink(mlxsw_core)); 404 } 405 406 #define MLXSW_BUS_F_TXRX BIT(0) 407 #define MLXSW_BUS_F_RESET BIT(1) 408 409 struct mlxsw_bus { 410 const char *kind; 411 int (*init)(void *bus_priv, struct mlxsw_core *mlxsw_core, 412 const struct mlxsw_config_profile *profile, 413 struct mlxsw_res *res); 414 void (*fini)(void *bus_priv); 415 bool (*skb_transmit_busy)(void *bus_priv, 416 const struct mlxsw_tx_info *tx_info); 417 int (*skb_transmit)(void *bus_priv, struct sk_buff *skb, 418 const struct mlxsw_tx_info *tx_info); 419 int (*cmd_exec)(void *bus_priv, u16 opcode, u8 opcode_mod, 420 u32 in_mod, bool out_mbox_direct, 421 char *in_mbox, size_t in_mbox_size, 422 char *out_mbox, size_t out_mbox_size, 423 u8 *p_status); 424 u32 (*read_frc_h)(void *bus_priv); 425 u32 (*read_frc_l)(void *bus_priv); 426 u8 features; 427 }; 428 429 struct mlxsw_fw_rev { 430 u16 major; 431 u16 minor; 432 u16 subminor; 433 u16 can_reset_minor; 434 }; 435 436 struct mlxsw_bus_info { 437 const char *device_kind; 438 const char *device_name; 439 struct device *dev; 440 struct mlxsw_fw_rev fw_rev; 441 u8 vsd[MLXSW_CMD_BOARDINFO_VSD_LEN]; 442 u8 psid[MLXSW_CMD_BOARDINFO_PSID_LEN]; 443 u8 low_frequency:1, 444 read_frc_capable:1; 445 }; 446 447 struct mlxsw_hwmon; 448 449 #ifdef CONFIG_MLXSW_CORE_HWMON 450 451 int mlxsw_hwmon_init(struct mlxsw_core *mlxsw_core, 452 const struct mlxsw_bus_info *mlxsw_bus_info, 453 struct mlxsw_hwmon **p_hwmon); 454 void mlxsw_hwmon_fini(struct mlxsw_hwmon *mlxsw_hwmon); 455 456 #else 457 458 static inline int mlxsw_hwmon_init(struct mlxsw_core *mlxsw_core, 459 const struct mlxsw_bus_info *mlxsw_bus_info, 460 struct mlxsw_hwmon **p_hwmon) 461 { 462 return 0; 463 } 464 465 static inline void mlxsw_hwmon_fini(struct mlxsw_hwmon *mlxsw_hwmon) 466 { 467 } 468 469 #endif 470 471 struct mlxsw_thermal; 472 473 #ifdef CONFIG_MLXSW_CORE_THERMAL 474 475 int mlxsw_thermal_init(struct mlxsw_core *mlxsw_core, 476 const struct mlxsw_bus_info *mlxsw_bus_info, 477 struct mlxsw_thermal **p_thermal); 478 void mlxsw_thermal_fini(struct mlxsw_thermal *thermal); 479 480 #else 481 482 static inline int mlxsw_thermal_init(struct mlxsw_core *mlxsw_core, 483 const struct mlxsw_bus_info *mlxsw_bus_info, 484 struct mlxsw_thermal **p_thermal) 485 { 486 return 0; 487 } 488 489 static inline void mlxsw_thermal_fini(struct mlxsw_thermal *thermal) 490 { 491 } 492 493 #endif 494 495 enum mlxsw_devlink_param_id { 496 MLXSW_DEVLINK_PARAM_ID_BASE = DEVLINK_PARAM_GENERIC_ID_MAX, 497 MLXSW_DEVLINK_PARAM_ID_ACL_REGION_REHASH_INTERVAL, 498 }; 499 500 struct mlxsw_skb_cb { 501 union { 502 struct mlxsw_tx_info tx_info; 503 u32 cookie_index; /* Only used during receive */ 504 }; 505 }; 506 507 static inline struct mlxsw_skb_cb *mlxsw_skb_cb(struct sk_buff *skb) 508 { 509 BUILD_BUG_ON(sizeof(mlxsw_skb_cb) > sizeof(skb->cb)); 510 return (struct mlxsw_skb_cb *) skb->cb; 511 } 512 513 #endif 514