linux/drivers/net/ethernet/mellanox/mlxsw/core.h
<<
>>
Prefs
   1/*
   2 * drivers/net/ethernet/mellanox/mlxsw/core.h
   3 * Copyright (c) 2015 Mellanox Technologies. All rights reserved.
   4 * Copyright (c) 2015 Jiri Pirko <jiri@mellanox.com>
   5 * Copyright (c) 2015 Ido Schimmel <idosch@mellanox.com>
   6 * Copyright (c) 2015 Elad Raz <eladr@mellanox.com>
   7 *
   8 * Redistribution and use in source and binary forms, with or without
   9 * modification, are permitted provided that the following conditions are met:
  10 *
  11 * 1. Redistributions of source code must retain the above copyright
  12 *    notice, this list of conditions and the following disclaimer.
  13 * 2. Redistributions in binary form must reproduce the above copyright
  14 *    notice, this list of conditions and the following disclaimer in the
  15 *    documentation and/or other materials provided with the distribution.
  16 * 3. Neither the names of the copyright holders nor the names of its
  17 *    contributors may be used to endorse or promote products derived from
  18 *    this software without specific prior written permission.
  19 *
  20 * Alternatively, this software may be distributed under the terms of the
  21 * GNU General Public License ("GPL") version 2 as published by the Free
  22 * Software Foundation.
  23 *
  24 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
  25 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  26 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
  27 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
  28 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
  29 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
  30 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
  31 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
  32 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
  33 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
  34 * POSSIBILITY OF SUCH DAMAGE.
  35 */
  36
  37#ifndef _MLXSW_CORE_H
  38#define _MLXSW_CORE_H
  39
  40#include <linux/module.h>
  41#include <linux/device.h>
  42#include <linux/slab.h>
  43#include <linux/gfp.h>
  44#include <linux/types.h>
  45#include <linux/skbuff.h>
  46#include <linux/workqueue.h>
  47#include <net/devlink.h>
  48
  49#include "trap.h"
  50#include "reg.h"
  51#include "cmd.h"
  52#include "resources.h"
  53
  54struct mlxsw_core;
  55struct mlxsw_core_port;
  56struct mlxsw_driver;
  57struct mlxsw_bus;
  58struct mlxsw_bus_info;
  59
  60unsigned int mlxsw_core_max_ports(const struct mlxsw_core *mlxsw_core);
  61
  62void *mlxsw_core_driver_priv(struct mlxsw_core *mlxsw_core);
  63
  64int mlxsw_core_driver_register(struct mlxsw_driver *mlxsw_driver);
  65void mlxsw_core_driver_unregister(struct mlxsw_driver *mlxsw_driver);
  66
  67int mlxsw_core_bus_device_register(const struct mlxsw_bus_info *mlxsw_bus_info,
  68                                   const struct mlxsw_bus *mlxsw_bus,
  69                                   void *bus_priv);
  70void mlxsw_core_bus_device_unregister(struct mlxsw_core *mlxsw_core);
  71
  72struct mlxsw_tx_info {
  73        u8 local_port;
  74        bool is_emad;
  75};
  76
  77bool mlxsw_core_skb_transmit_busy(struct mlxsw_core *mlxsw_core,
  78                                  const struct mlxsw_tx_info *tx_info);
  79int mlxsw_core_skb_transmit(struct mlxsw_core *mlxsw_core, struct sk_buff *skb,
  80                            const struct mlxsw_tx_info *tx_info);
  81
  82struct mlxsw_rx_listener {
  83        void (*func)(struct sk_buff *skb, u8 local_port, void *priv);
  84        u8 local_port;
  85        u16 trap_id;
  86        enum mlxsw_reg_hpkt_action action;
  87};
  88
  89struct mlxsw_event_listener {
  90        void (*func)(const struct mlxsw_reg_info *reg,
  91                     char *payload, void *priv);
  92        enum mlxsw_event_trap_id trap_id;
  93};
  94
  95struct mlxsw_listener {
  96        u16 trap_id;
  97        union {
  98                struct mlxsw_rx_listener rx_listener;
  99                struct mlxsw_event_listener event_listener;
 100        } u;
 101        enum mlxsw_reg_hpkt_action action;
 102        enum mlxsw_reg_hpkt_action unreg_action;
 103        u8 trap_group;
 104        bool is_ctrl; /* should go via control buffer or not */
 105        bool is_event;
 106};
 107
 108#define MLXSW_RXL(_func, _trap_id, _action, _is_ctrl, _trap_group,      \
 109                  _unreg_action)                                        \
 110        {                                                               \
 111                .trap_id = MLXSW_TRAP_ID_##_trap_id,                    \
 112                .u.rx_listener =                                        \
 113                {                                                       \
 114                        .func = _func,                                  \
 115                        .local_port = MLXSW_PORT_DONT_CARE,             \
 116                        .trap_id = MLXSW_TRAP_ID_##_trap_id,            \
 117                },                                                      \
 118                .action = MLXSW_REG_HPKT_ACTION_##_action,              \
 119                .unreg_action = MLXSW_REG_HPKT_ACTION_##_unreg_action,  \
 120                .trap_group = MLXSW_REG_HTGT_TRAP_GROUP_##_trap_group,  \
 121                .is_ctrl = _is_ctrl,                                    \
 122                .is_event = false,                                      \
 123        }
 124
 125#define MLXSW_EVENTL(_func, _trap_id, _trap_group)                      \
 126        {                                                               \
 127                .trap_id = MLXSW_TRAP_ID_##_trap_id,                    \
 128                .u.event_listener =                                     \
 129                {                                                       \
 130                        .func = _func,                                  \
 131                        .trap_id = MLXSW_TRAP_ID_##_trap_id,            \
 132                },                                                      \
 133                .action = MLXSW_REG_HPKT_ACTION_TRAP_TO_CPU,            \
 134                .trap_group = MLXSW_REG_HTGT_TRAP_GROUP_##_trap_group,  \
 135                .is_ctrl = false,                                       \
 136                .is_event = true,                                       \
 137        }
 138
 139int mlxsw_core_rx_listener_register(struct mlxsw_core *mlxsw_core,
 140                                    const struct mlxsw_rx_listener *rxl,
 141                                    void *priv);
 142void mlxsw_core_rx_listener_unregister(struct mlxsw_core *mlxsw_core,
 143                                       const struct mlxsw_rx_listener *rxl,
 144                                       void *priv);
 145
 146int mlxsw_core_event_listener_register(struct mlxsw_core *mlxsw_core,
 147                                       const struct mlxsw_event_listener *el,
 148                                       void *priv);
 149void mlxsw_core_event_listener_unregister(struct mlxsw_core *mlxsw_core,
 150                                          const struct mlxsw_event_listener *el,
 151                                          void *priv);
 152
 153int mlxsw_core_trap_register(struct mlxsw_core *mlxsw_core,
 154                             const struct mlxsw_listener *listener,
 155                             void *priv);
 156void mlxsw_core_trap_unregister(struct mlxsw_core *mlxsw_core,
 157                                const struct mlxsw_listener *listener,
 158                                void *priv);
 159
 160typedef void mlxsw_reg_trans_cb_t(struct mlxsw_core *mlxsw_core, char *payload,
 161                                  size_t payload_len, unsigned long cb_priv);
 162
 163int mlxsw_reg_trans_query(struct mlxsw_core *mlxsw_core,
 164                          const struct mlxsw_reg_info *reg, char *payload,
 165                          struct list_head *bulk_list,
 166                          mlxsw_reg_trans_cb_t *cb, unsigned long cb_priv);
 167int mlxsw_reg_trans_write(struct mlxsw_core *mlxsw_core,
 168                          const struct mlxsw_reg_info *reg, char *payload,
 169                          struct list_head *bulk_list,
 170                          mlxsw_reg_trans_cb_t *cb, unsigned long cb_priv);
 171int mlxsw_reg_trans_bulk_wait(struct list_head *bulk_list);
 172
 173int mlxsw_reg_query(struct mlxsw_core *mlxsw_core,
 174                    const struct mlxsw_reg_info *reg, char *payload);
 175int mlxsw_reg_write(struct mlxsw_core *mlxsw_core,
 176                    const struct mlxsw_reg_info *reg, char *payload);
 177
 178struct mlxsw_rx_info {
 179        bool is_lag;
 180        union {
 181                u16 sys_port;
 182                u16 lag_id;
 183        } u;
 184        u8 lag_port_index;
 185        int trap_id;
 186};
 187
 188void mlxsw_core_skb_receive(struct mlxsw_core *mlxsw_core, struct sk_buff *skb,
 189                            struct mlxsw_rx_info *rx_info);
 190
 191void mlxsw_core_lag_mapping_set(struct mlxsw_core *mlxsw_core,
 192                                u16 lag_id, u8 port_index, u8 local_port);
 193u8 mlxsw_core_lag_mapping_get(struct mlxsw_core *mlxsw_core,
 194                              u16 lag_id, u8 port_index);
 195void mlxsw_core_lag_mapping_clear(struct mlxsw_core *mlxsw_core,
 196                                  u16 lag_id, u8 local_port);
 197
 198void *mlxsw_core_port_driver_priv(struct mlxsw_core_port *mlxsw_core_port);
 199int mlxsw_core_port_init(struct mlxsw_core *mlxsw_core, u8 local_port);
 200void mlxsw_core_port_fini(struct mlxsw_core *mlxsw_core, u8 local_port);
 201void mlxsw_core_port_eth_set(struct mlxsw_core *mlxsw_core, u8 local_port,
 202                             void *port_driver_priv, struct net_device *dev,
 203                             bool split, u32 split_group);
 204void mlxsw_core_port_ib_set(struct mlxsw_core *mlxsw_core, u8 local_port,
 205                            void *port_driver_priv);
 206void mlxsw_core_port_clear(struct mlxsw_core *mlxsw_core, u8 local_port,
 207                           void *port_driver_priv);
 208enum devlink_port_type mlxsw_core_port_type_get(struct mlxsw_core *mlxsw_core,
 209                                                u8 local_port);
 210
 211int mlxsw_core_schedule_dw(struct delayed_work *dwork, unsigned long delay);
 212bool mlxsw_core_schedule_work(struct work_struct *work);
 213void mlxsw_core_flush_owq(void);
 214
 215#define MLXSW_CONFIG_PROFILE_SWID_COUNT 8
 216
 217struct mlxsw_swid_config {
 218        u8      used_type:1,
 219                used_properties:1;
 220        u8      type;
 221        u8      properties;
 222};
 223
 224struct mlxsw_config_profile {
 225        u16     used_max_vepa_channels:1,
 226                used_max_mid:1,
 227                used_max_pgt:1,
 228                used_max_system_port:1,
 229                used_max_vlan_groups:1,
 230                used_max_regions:1,
 231                used_flood_tables:1,
 232                used_flood_mode:1,
 233                used_max_ib_mc:1,
 234                used_max_pkey:1,
 235                used_ar_sec:1,
 236                used_adaptive_routing_group_cap:1,
 237                used_kvd_split_data:1; /* indicate for the kvd's values */
 238
 239        u8      max_vepa_channels;
 240        u16     max_mid;
 241        u16     max_pgt;
 242        u16     max_system_port;
 243        u16     max_vlan_groups;
 244        u16     max_regions;
 245        u8      max_flood_tables;
 246        u8      max_vid_flood_tables;
 247        u8      flood_mode;
 248        u8      max_fid_offset_flood_tables;
 249        u16     fid_offset_flood_table_size;
 250        u8      max_fid_flood_tables;
 251        u16     fid_flood_table_size;
 252        u16     max_ib_mc;
 253        u16     max_pkey;
 254        u8      ar_sec;
 255        u16     adaptive_routing_group_cap;
 256        u8      arn;
 257        u32     kvd_linear_size;
 258        u16     kvd_hash_granularity;
 259        u8      kvd_hash_single_parts;
 260        u8      kvd_hash_double_parts;
 261        u8      resource_query_enable;
 262        struct mlxsw_swid_config swid_config[MLXSW_CONFIG_PROFILE_SWID_COUNT];
 263};
 264
 265struct mlxsw_driver {
 266        struct list_head list;
 267        const char *kind;
 268        size_t priv_size;
 269        int (*init)(struct mlxsw_core *mlxsw_core,
 270                    const struct mlxsw_bus_info *mlxsw_bus_info);
 271        void (*fini)(struct mlxsw_core *mlxsw_core);
 272        int (*basic_trap_groups_set)(struct mlxsw_core *mlxsw_core);
 273        int (*port_type_set)(struct mlxsw_core *mlxsw_core, u8 local_port,
 274                             enum devlink_port_type new_type);
 275        int (*port_split)(struct mlxsw_core *mlxsw_core, u8 local_port,
 276                          unsigned int count);
 277        int (*port_unsplit)(struct mlxsw_core *mlxsw_core, u8 local_port);
 278        int (*sb_pool_get)(struct mlxsw_core *mlxsw_core,
 279                           unsigned int sb_index, u16 pool_index,
 280                           struct devlink_sb_pool_info *pool_info);
 281        int (*sb_pool_set)(struct mlxsw_core *mlxsw_core,
 282                           unsigned int sb_index, u16 pool_index, u32 size,
 283                           enum devlink_sb_threshold_type threshold_type);
 284        int (*sb_port_pool_get)(struct mlxsw_core_port *mlxsw_core_port,
 285                                unsigned int sb_index, u16 pool_index,
 286                                u32 *p_threshold);
 287        int (*sb_port_pool_set)(struct mlxsw_core_port *mlxsw_core_port,
 288                                unsigned int sb_index, u16 pool_index,
 289                                u32 threshold);
 290        int (*sb_tc_pool_bind_get)(struct mlxsw_core_port *mlxsw_core_port,
 291                                   unsigned int sb_index, u16 tc_index,
 292                                   enum devlink_sb_pool_type pool_type,
 293                                   u16 *p_pool_index, u32 *p_threshold);
 294        int (*sb_tc_pool_bind_set)(struct mlxsw_core_port *mlxsw_core_port,
 295                                   unsigned int sb_index, u16 tc_index,
 296                                   enum devlink_sb_pool_type pool_type,
 297                                   u16 pool_index, u32 threshold);
 298        int (*sb_occ_snapshot)(struct mlxsw_core *mlxsw_core,
 299                               unsigned int sb_index);
 300        int (*sb_occ_max_clear)(struct mlxsw_core *mlxsw_core,
 301                                unsigned int sb_index);
 302        int (*sb_occ_port_pool_get)(struct mlxsw_core_port *mlxsw_core_port,
 303                                    unsigned int sb_index, u16 pool_index,
 304                                    u32 *p_cur, u32 *p_max);
 305        int (*sb_occ_tc_port_bind_get)(struct mlxsw_core_port *mlxsw_core_port,
 306                                       unsigned int sb_index, u16 tc_index,
 307                                       enum devlink_sb_pool_type pool_type,
 308                                       u32 *p_cur, u32 *p_max);
 309        void (*txhdr_construct)(struct sk_buff *skb,
 310                                const struct mlxsw_tx_info *tx_info);
 311        u8 txhdr_len;
 312        const struct mlxsw_config_profile *profile;
 313};
 314
 315bool mlxsw_core_res_valid(struct mlxsw_core *mlxsw_core,
 316                          enum mlxsw_res_id res_id);
 317
 318#define MLXSW_CORE_RES_VALID(res, short_res_id)                 \
 319        mlxsw_core_res_valid(res, MLXSW_RES_ID_##short_res_id)
 320
 321u64 mlxsw_core_res_get(struct mlxsw_core *mlxsw_core,
 322                       enum mlxsw_res_id res_id);
 323
 324#define MLXSW_CORE_RES_GET(res, short_res_id)                   \
 325        mlxsw_core_res_get(res, MLXSW_RES_ID_##short_res_id)
 326
 327#define MLXSW_BUS_F_TXRX        BIT(0)
 328
 329struct mlxsw_bus {
 330        const char *kind;
 331        int (*init)(void *bus_priv, struct mlxsw_core *mlxsw_core,
 332                    const struct mlxsw_config_profile *profile,
 333                    struct mlxsw_res *res);
 334        void (*fini)(void *bus_priv);
 335        bool (*skb_transmit_busy)(void *bus_priv,
 336                                  const struct mlxsw_tx_info *tx_info);
 337        int (*skb_transmit)(void *bus_priv, struct sk_buff *skb,
 338                            const struct mlxsw_tx_info *tx_info);
 339        int (*cmd_exec)(void *bus_priv, u16 opcode, u8 opcode_mod,
 340                        u32 in_mod, bool out_mbox_direct,
 341                        char *in_mbox, size_t in_mbox_size,
 342                        char *out_mbox, size_t out_mbox_size,
 343                        u8 *p_status);
 344        u8 features;
 345};
 346
 347struct mlxsw_fw_rev {
 348        u16 major;
 349        u16 minor;
 350        u16 subminor;
 351};
 352
 353struct mlxsw_bus_info {
 354        const char *device_kind;
 355        const char *device_name;
 356        struct device *dev;
 357        struct mlxsw_fw_rev fw_rev;
 358        u8 vsd[MLXSW_CMD_BOARDINFO_VSD_LEN];
 359        u8 psid[MLXSW_CMD_BOARDINFO_PSID_LEN];
 360};
 361
 362struct mlxsw_hwmon;
 363
 364#ifdef CONFIG_MLXSW_CORE_HWMON
 365
 366int mlxsw_hwmon_init(struct mlxsw_core *mlxsw_core,
 367                     const struct mlxsw_bus_info *mlxsw_bus_info,
 368                     struct mlxsw_hwmon **p_hwmon);
 369void mlxsw_hwmon_fini(struct mlxsw_hwmon *mlxsw_hwmon);
 370
 371#else
 372
 373static inline int mlxsw_hwmon_init(struct mlxsw_core *mlxsw_core,
 374                                   const struct mlxsw_bus_info *mlxsw_bus_info,
 375                                   struct mlxsw_hwmon **p_hwmon)
 376{
 377        return 0;
 378}
 379
 380#endif
 381
 382struct mlxsw_thermal;
 383
 384#ifdef CONFIG_MLXSW_CORE_THERMAL
 385
 386int mlxsw_thermal_init(struct mlxsw_core *mlxsw_core,
 387                       const struct mlxsw_bus_info *mlxsw_bus_info,
 388                       struct mlxsw_thermal **p_thermal);
 389void mlxsw_thermal_fini(struct mlxsw_thermal *thermal);
 390
 391#else
 392
 393static inline int mlxsw_thermal_init(struct mlxsw_core *mlxsw_core,
 394                                     const struct mlxsw_bus_info *mlxsw_bus_info,
 395                                     struct mlxsw_thermal **p_thermal)
 396{
 397        return 0;
 398}
 399
 400static inline void mlxsw_thermal_fini(struct mlxsw_thermal *thermal)
 401{
 402}
 403
 404#endif
 405
 406#endif
 407