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