root/drivers/net/ethernet/mellanox/mlxsw/switchib.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. mlxsw_sib_tx_v1_hdr_construct
  2. mlxsw_sib_hw_id_get
  3. mlxsw_sib_port_admin_status_set
  4. mlxsw_sib_port_mtu_set
  5. mlxsw_sib_port_set
  6. mlxsw_sib_port_swid_set
  7. mlxsw_sib_port_module_info_get
  8. mlxsw_sib_port_speed_set
  9. mlxsw_sib_port_created
  10. __mlxsw_sib_port_create
  11. mlxsw_sib_port_create
  12. __mlxsw_sib_port_remove
  13. mlxsw_sib_port_remove
  14. mlxsw_sib_ports_remove
  15. mlxsw_sib_ports_create
  16. mlxsw_sib_pude_ib_event_func
  17. mlxsw_sib_pude_event_func
  18. mlxsw_sib_taps_init
  19. mlxsw_sib_traps_fini
  20. mlxsw_sib_basic_trap_groups_set
  21. mlxsw_sib_init
  22. mlxsw_sib_fini
  23. mlxsw_sib_module_init
  24. mlxsw_sib_module_exit

   1 // SPDX-License-Identifier: BSD-3-Clause OR GPL-2.0
   2 /* Copyright (c) 2016-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/slab.h>
  11 #include <linux/device.h>
  12 #include <linux/skbuff.h>
  13 #include <linux/if_vlan.h>
  14 #include <net/switchdev.h>
  15 
  16 #include "pci.h"
  17 #include "core.h"
  18 #include "reg.h"
  19 #include "port.h"
  20 #include "trap.h"
  21 #include "txheader.h"
  22 #include "ib.h"
  23 
  24 static const char mlxsw_sib_driver_name[] = "mlxsw_switchib";
  25 static const char mlxsw_sib2_driver_name[] = "mlxsw_switchib2";
  26 
  27 struct mlxsw_sib_port;
  28 
  29 struct mlxsw_sib {
  30         struct mlxsw_sib_port **ports;
  31         struct mlxsw_core *core;
  32         const struct mlxsw_bus_info *bus_info;
  33         u8 hw_id[ETH_ALEN];
  34 };
  35 
  36 struct mlxsw_sib_port {
  37         struct mlxsw_sib *mlxsw_sib;
  38         u8 local_port;
  39         struct {
  40                 u8 module;
  41         } mapping;
  42 };
  43 
  44 /* tx_v1_hdr_version
  45  * Tx header version.
  46  * Must be set to 1.
  47  */
  48 MLXSW_ITEM32(tx_v1, hdr, version, 0x00, 28, 4);
  49 
  50 /* tx_v1_hdr_ctl
  51  * Packet control type.
  52  * 0 - Ethernet control (e.g. EMADs, LACP)
  53  * 1 - Ethernet data
  54  */
  55 MLXSW_ITEM32(tx_v1, hdr, ctl, 0x00, 26, 2);
  56 
  57 /* tx_v1_hdr_proto
  58  * Packet protocol type. Must be set to 1 (Ethernet).
  59  */
  60 MLXSW_ITEM32(tx_v1, hdr, proto, 0x00, 21, 3);
  61 
  62 /* tx_v1_hdr_swid
  63  * Switch partition ID. Must be set to 0.
  64  */
  65 MLXSW_ITEM32(tx_v1, hdr, swid, 0x00, 12, 3);
  66 
  67 /* tx_v1_hdr_control_tclass
  68  * Indicates if the packet should use the control TClass and not one
  69  * of the data TClasses.
  70  */
  71 MLXSW_ITEM32(tx_v1, hdr, control_tclass, 0x00, 6, 1);
  72 
  73 /* tx_v1_hdr_port_mid
  74  * Destination local port for unicast packets.
  75  * Destination multicast ID for multicast packets.
  76  *
  77  * Control packets are directed to a specific egress port, while data
  78  * packets are transmitted through the CPU port (0) into the switch partition,
  79  * where forwarding rules are applied.
  80  */
  81 MLXSW_ITEM32(tx_v1, hdr, port_mid, 0x04, 16, 16);
  82 
  83 /* tx_v1_hdr_type
  84  * 0 - Data packets
  85  * 6 - Control packets
  86  */
  87 MLXSW_ITEM32(tx_v1, hdr, type, 0x0C, 0, 4);
  88 
  89 static void
  90 mlxsw_sib_tx_v1_hdr_construct(struct sk_buff *skb,
  91                               const struct mlxsw_tx_info *tx_info)
  92 {
  93         char *txhdr = skb_push(skb, MLXSW_TXHDR_LEN);
  94 
  95         memset(txhdr, 0, MLXSW_TXHDR_LEN);
  96 
  97         mlxsw_tx_v1_hdr_version_set(txhdr, MLXSW_TXHDR_VERSION_1);
  98         mlxsw_tx_v1_hdr_ctl_set(txhdr, MLXSW_TXHDR_ETH_CTL);
  99         mlxsw_tx_v1_hdr_proto_set(txhdr, MLXSW_TXHDR_PROTO_ETH);
 100         mlxsw_tx_v1_hdr_swid_set(txhdr, 0);
 101         mlxsw_tx_v1_hdr_control_tclass_set(txhdr, 1);
 102         mlxsw_tx_v1_hdr_port_mid_set(txhdr, tx_info->local_port);
 103         mlxsw_tx_v1_hdr_type_set(txhdr, MLXSW_TXHDR_TYPE_CONTROL);
 104 }
 105 
 106 static int mlxsw_sib_hw_id_get(struct mlxsw_sib *mlxsw_sib)
 107 {
 108         char spad_pl[MLXSW_REG_SPAD_LEN] = {0};
 109         int err;
 110 
 111         err = mlxsw_reg_query(mlxsw_sib->core, MLXSW_REG(spad), spad_pl);
 112         if (err)
 113                 return err;
 114         mlxsw_reg_spad_base_mac_memcpy_from(spad_pl, mlxsw_sib->hw_id);
 115         return 0;
 116 }
 117 
 118 static int
 119 mlxsw_sib_port_admin_status_set(struct mlxsw_sib_port *mlxsw_sib_port,
 120                                 bool is_up)
 121 {
 122         struct mlxsw_sib *mlxsw_sib = mlxsw_sib_port->mlxsw_sib;
 123         char paos_pl[MLXSW_REG_PAOS_LEN];
 124 
 125         mlxsw_reg_paos_pack(paos_pl, mlxsw_sib_port->local_port,
 126                             is_up ? MLXSW_PORT_ADMIN_STATUS_UP :
 127                             MLXSW_PORT_ADMIN_STATUS_DOWN);
 128         return mlxsw_reg_write(mlxsw_sib->core, MLXSW_REG(paos), paos_pl);
 129 }
 130 
 131 static int mlxsw_sib_port_mtu_set(struct mlxsw_sib_port *mlxsw_sib_port,
 132                                   u16 mtu)
 133 {
 134         struct mlxsw_sib *mlxsw_sib = mlxsw_sib_port->mlxsw_sib;
 135         char pmtu_pl[MLXSW_REG_PMTU_LEN];
 136         int max_mtu;
 137         int err;
 138 
 139         mlxsw_reg_pmtu_pack(pmtu_pl, mlxsw_sib_port->local_port, 0);
 140         err = mlxsw_reg_query(mlxsw_sib->core, MLXSW_REG(pmtu), pmtu_pl);
 141         if (err)
 142                 return err;
 143         max_mtu = mlxsw_reg_pmtu_max_mtu_get(pmtu_pl);
 144 
 145         if (mtu > max_mtu)
 146                 return -EINVAL;
 147 
 148         mlxsw_reg_pmtu_pack(pmtu_pl, mlxsw_sib_port->local_port, mtu);
 149         return mlxsw_reg_write(mlxsw_sib->core, MLXSW_REG(pmtu), pmtu_pl);
 150 }
 151 
 152 static int mlxsw_sib_port_set(struct mlxsw_sib_port *mlxsw_sib_port, u8 port)
 153 {
 154         struct mlxsw_sib *mlxsw_sib = mlxsw_sib_port->mlxsw_sib;
 155         char plib_pl[MLXSW_REG_PLIB_LEN] = {0};
 156         int err;
 157 
 158         mlxsw_reg_plib_local_port_set(plib_pl, mlxsw_sib_port->local_port);
 159         mlxsw_reg_plib_ib_port_set(plib_pl, port);
 160         err = mlxsw_reg_write(mlxsw_sib->core, MLXSW_REG(plib), plib_pl);
 161         return err;
 162 }
 163 
 164 static int mlxsw_sib_port_swid_set(struct mlxsw_sib_port *mlxsw_sib_port,
 165                                    u8 swid)
 166 {
 167         struct mlxsw_sib *mlxsw_sib = mlxsw_sib_port->mlxsw_sib;
 168         char pspa_pl[MLXSW_REG_PSPA_LEN];
 169 
 170         mlxsw_reg_pspa_pack(pspa_pl, swid, mlxsw_sib_port->local_port);
 171         return mlxsw_reg_write(mlxsw_sib->core, MLXSW_REG(pspa), pspa_pl);
 172 }
 173 
 174 static int mlxsw_sib_port_module_info_get(struct mlxsw_sib *mlxsw_sib,
 175                                           u8 local_port, u8 *p_module,
 176                                           u8 *p_width)
 177 {
 178         char pmlp_pl[MLXSW_REG_PMLP_LEN];
 179         int err;
 180 
 181         mlxsw_reg_pmlp_pack(pmlp_pl, local_port);
 182         err = mlxsw_reg_query(mlxsw_sib->core, MLXSW_REG(pmlp), pmlp_pl);
 183         if (err)
 184                 return err;
 185         *p_module = mlxsw_reg_pmlp_module_get(pmlp_pl, 0);
 186         *p_width = mlxsw_reg_pmlp_width_get(pmlp_pl);
 187         return 0;
 188 }
 189 
 190 static int mlxsw_sib_port_speed_set(struct mlxsw_sib_port *mlxsw_sib_port,
 191                                     u16 speed, u16 width)
 192 {
 193         struct mlxsw_sib *mlxsw_sib = mlxsw_sib_port->mlxsw_sib;
 194         char ptys_pl[MLXSW_REG_PTYS_LEN];
 195 
 196         mlxsw_reg_ptys_ib_pack(ptys_pl, mlxsw_sib_port->local_port, speed,
 197                                width);
 198         return mlxsw_reg_write(mlxsw_sib->core, MLXSW_REG(ptys), ptys_pl);
 199 }
 200 
 201 static bool mlxsw_sib_port_created(struct mlxsw_sib *mlxsw_sib, u8 local_port)
 202 {
 203         return mlxsw_sib->ports[local_port] != NULL;
 204 }
 205 
 206 static int __mlxsw_sib_port_create(struct mlxsw_sib *mlxsw_sib, u8 local_port,
 207                                    u8 module, u8 width)
 208 {
 209         struct mlxsw_sib_port *mlxsw_sib_port;
 210         int err;
 211 
 212         mlxsw_sib_port = kzalloc(sizeof(*mlxsw_sib_port), GFP_KERNEL);
 213         if (!mlxsw_sib_port)
 214                 return -ENOMEM;
 215         mlxsw_sib_port->mlxsw_sib = mlxsw_sib;
 216         mlxsw_sib_port->local_port = local_port;
 217         mlxsw_sib_port->mapping.module = module;
 218 
 219         err = mlxsw_sib_port_swid_set(mlxsw_sib_port, 0);
 220         if (err) {
 221                 dev_err(mlxsw_sib->bus_info->dev, "Port %d: Failed to set SWID\n",
 222                         mlxsw_sib_port->local_port);
 223                 goto err_port_swid_set;
 224         }
 225 
 226         /* Expose the IB port number as it's front panel name */
 227         err = mlxsw_sib_port_set(mlxsw_sib_port, module + 1);
 228         if (err) {
 229                 dev_err(mlxsw_sib->bus_info->dev, "Port %d: Failed to set IB port\n",
 230                         mlxsw_sib_port->local_port);
 231                 goto err_port_ib_set;
 232         }
 233 
 234         /* Supports all speeds from SDR to FDR (bitmask) and support bus width
 235          * of 1x, 2x and 4x (3 bits bitmask)
 236          */
 237         err = mlxsw_sib_port_speed_set(mlxsw_sib_port,
 238                                        MLXSW_REG_PTYS_IB_SPEED_EDR - 1,
 239                                        BIT(3) - 1);
 240         if (err) {
 241                 dev_err(mlxsw_sib->bus_info->dev, "Port %d: Failed to set speed\n",
 242                         mlxsw_sib_port->local_port);
 243                 goto err_port_speed_set;
 244         }
 245 
 246         /* Change to the maximum MTU the device supports, the SMA will take
 247          * care of the active MTU
 248          */
 249         err = mlxsw_sib_port_mtu_set(mlxsw_sib_port, MLXSW_IB_DEFAULT_MTU);
 250         if (err) {
 251                 dev_err(mlxsw_sib->bus_info->dev, "Port %d: Failed to set MTU\n",
 252                         mlxsw_sib_port->local_port);
 253                 goto err_port_mtu_set;
 254         }
 255 
 256         err = mlxsw_sib_port_admin_status_set(mlxsw_sib_port, true);
 257         if (err) {
 258                 dev_err(mlxsw_sib->bus_info->dev, "Port %d: Failed to change admin state to UP\n",
 259                         mlxsw_sib_port->local_port);
 260                 goto err_port_admin_set;
 261         }
 262 
 263         mlxsw_core_port_ib_set(mlxsw_sib->core, mlxsw_sib_port->local_port,
 264                                mlxsw_sib_port);
 265         mlxsw_sib->ports[local_port] = mlxsw_sib_port;
 266         return 0;
 267 
 268 err_port_admin_set:
 269 err_port_mtu_set:
 270 err_port_speed_set:
 271 err_port_ib_set:
 272         mlxsw_sib_port_swid_set(mlxsw_sib_port, MLXSW_PORT_SWID_DISABLED_PORT);
 273 err_port_swid_set:
 274         kfree(mlxsw_sib_port);
 275         return err;
 276 }
 277 
 278 static int mlxsw_sib_port_create(struct mlxsw_sib *mlxsw_sib, u8 local_port,
 279                                  u8 module, u8 width)
 280 {
 281         int err;
 282 
 283         err = mlxsw_core_port_init(mlxsw_sib->core, local_port,
 284                                    module + 1, false, 0,
 285                                    mlxsw_sib->hw_id, sizeof(mlxsw_sib->hw_id));
 286         if (err) {
 287                 dev_err(mlxsw_sib->bus_info->dev, "Port %d: Failed to init core port\n",
 288                         local_port);
 289                 return err;
 290         }
 291         err = __mlxsw_sib_port_create(mlxsw_sib, local_port, module, width);
 292         if (err)
 293                 goto err_port_create;
 294 
 295         return 0;
 296 
 297 err_port_create:
 298         mlxsw_core_port_fini(mlxsw_sib->core, local_port);
 299         return err;
 300 }
 301 
 302 static void __mlxsw_sib_port_remove(struct mlxsw_sib *mlxsw_sib, u8 local_port)
 303 {
 304         struct mlxsw_sib_port *mlxsw_sib_port = mlxsw_sib->ports[local_port];
 305 
 306         mlxsw_core_port_clear(mlxsw_sib->core, local_port, mlxsw_sib);
 307         mlxsw_sib->ports[local_port] = NULL;
 308         mlxsw_sib_port_admin_status_set(mlxsw_sib_port, false);
 309         mlxsw_sib_port_swid_set(mlxsw_sib_port, MLXSW_PORT_SWID_DISABLED_PORT);
 310         kfree(mlxsw_sib_port);
 311 }
 312 
 313 static void mlxsw_sib_port_remove(struct mlxsw_sib *mlxsw_sib, u8 local_port)
 314 {
 315         __mlxsw_sib_port_remove(mlxsw_sib, local_port);
 316         mlxsw_core_port_fini(mlxsw_sib->core, local_port);
 317 }
 318 
 319 static void mlxsw_sib_ports_remove(struct mlxsw_sib *mlxsw_sib)
 320 {
 321         int i;
 322 
 323         for (i = 1; i < MLXSW_PORT_MAX_IB_PORTS; i++)
 324                 if (mlxsw_sib_port_created(mlxsw_sib, i))
 325                         mlxsw_sib_port_remove(mlxsw_sib, i);
 326         kfree(mlxsw_sib->ports);
 327 }
 328 
 329 static int mlxsw_sib_ports_create(struct mlxsw_sib *mlxsw_sib)
 330 {
 331         size_t alloc_size;
 332         u8 module, width;
 333         int i;
 334         int err;
 335 
 336         alloc_size = sizeof(struct mlxsw_sib_port *) * MLXSW_PORT_MAX_IB_PORTS;
 337         mlxsw_sib->ports = kzalloc(alloc_size, GFP_KERNEL);
 338         if (!mlxsw_sib->ports)
 339                 return -ENOMEM;
 340 
 341         for (i = 1; i < MLXSW_PORT_MAX_IB_PORTS; i++) {
 342                 err = mlxsw_sib_port_module_info_get(mlxsw_sib, i, &module,
 343                                                      &width);
 344                 if (err)
 345                         goto err_port_module_info_get;
 346                 if (!width)
 347                         continue;
 348                 err = mlxsw_sib_port_create(mlxsw_sib, i, module, width);
 349                 if (err)
 350                         goto err_port_create;
 351         }
 352         return 0;
 353 
 354 err_port_create:
 355 err_port_module_info_get:
 356         for (i--; i >= 1; i--)
 357                 if (mlxsw_sib_port_created(mlxsw_sib, i))
 358                         mlxsw_sib_port_remove(mlxsw_sib, i);
 359         kfree(mlxsw_sib->ports);
 360         return err;
 361 }
 362 
 363 static void
 364 mlxsw_sib_pude_ib_event_func(struct mlxsw_sib_port *mlxsw_sib_port,
 365                              enum mlxsw_reg_pude_oper_status status)
 366 {
 367         if (status == MLXSW_PORT_OPER_STATUS_UP)
 368                 pr_info("ib link for port %d - up\n",
 369                         mlxsw_sib_port->mapping.module + 1);
 370         else
 371                 pr_info("ib link for port %d - down\n",
 372                         mlxsw_sib_port->mapping.module + 1);
 373 }
 374 
 375 static void mlxsw_sib_pude_event_func(const struct mlxsw_reg_info *reg,
 376                                       char *pude_pl, void *priv)
 377 {
 378         struct mlxsw_sib *mlxsw_sib = priv;
 379         struct mlxsw_sib_port *mlxsw_sib_port;
 380         enum mlxsw_reg_pude_oper_status status;
 381         u8 local_port;
 382 
 383         local_port = mlxsw_reg_pude_local_port_get(pude_pl);
 384         mlxsw_sib_port = mlxsw_sib->ports[local_port];
 385         if (!mlxsw_sib_port) {
 386                 dev_warn(mlxsw_sib->bus_info->dev, "Port %d: Link event received for non-existent port\n",
 387                          local_port);
 388                 return;
 389         }
 390 
 391         status = mlxsw_reg_pude_oper_status_get(pude_pl);
 392         mlxsw_sib_pude_ib_event_func(mlxsw_sib_port, status);
 393 }
 394 
 395 static const struct mlxsw_listener mlxsw_sib_listener[] = {
 396         MLXSW_EVENTL(mlxsw_sib_pude_event_func, PUDE, EMAD),
 397 };
 398 
 399 static int mlxsw_sib_taps_init(struct mlxsw_sib *mlxsw_sib)
 400 {
 401         int i;
 402         int err;
 403 
 404         for (i = 0; i < ARRAY_SIZE(mlxsw_sib_listener); i++) {
 405                 err = mlxsw_core_trap_register(mlxsw_sib->core,
 406                                                &mlxsw_sib_listener[i],
 407                                                mlxsw_sib);
 408                 if (err)
 409                         goto err_rx_listener_register;
 410         }
 411 
 412         return 0;
 413 
 414 err_rx_listener_register:
 415         for (i--; i >= 0; i--) {
 416                 mlxsw_core_trap_unregister(mlxsw_sib->core,
 417                                            &mlxsw_sib_listener[i],
 418                                            mlxsw_sib);
 419         }
 420 
 421         return err;
 422 }
 423 
 424 static void mlxsw_sib_traps_fini(struct mlxsw_sib *mlxsw_sib)
 425 {
 426         int i;
 427 
 428         for (i = 0; i < ARRAY_SIZE(mlxsw_sib_listener); i++) {
 429                 mlxsw_core_trap_unregister(mlxsw_sib->core,
 430                                            &mlxsw_sib_listener[i], mlxsw_sib);
 431         }
 432 }
 433 
 434 static int mlxsw_sib_basic_trap_groups_set(struct mlxsw_core *mlxsw_core)
 435 {
 436         char htgt_pl[MLXSW_REG_HTGT_LEN];
 437 
 438         mlxsw_reg_htgt_pack(htgt_pl, MLXSW_REG_HTGT_TRAP_GROUP_EMAD,
 439                             MLXSW_REG_HTGT_INVALID_POLICER,
 440                             MLXSW_REG_HTGT_DEFAULT_PRIORITY,
 441                             MLXSW_REG_HTGT_DEFAULT_TC);
 442         mlxsw_reg_htgt_swid_set(htgt_pl, MLXSW_PORT_SWID_ALL_SWIDS);
 443         mlxsw_reg_htgt_local_path_rdq_set(htgt_pl,
 444                                         MLXSW_REG_HTGT_LOCAL_PATH_RDQ_SIB_EMAD);
 445         return mlxsw_reg_write(mlxsw_core, MLXSW_REG(htgt), htgt_pl);
 446 }
 447 
 448 static int mlxsw_sib_init(struct mlxsw_core *mlxsw_core,
 449                           const struct mlxsw_bus_info *mlxsw_bus_info)
 450 {
 451         struct mlxsw_sib *mlxsw_sib = mlxsw_core_driver_priv(mlxsw_core);
 452         int err;
 453 
 454         mlxsw_sib->core = mlxsw_core;
 455         mlxsw_sib->bus_info = mlxsw_bus_info;
 456 
 457         err = mlxsw_sib_hw_id_get(mlxsw_sib);
 458         if (err) {
 459                 dev_err(mlxsw_sib->bus_info->dev, "Failed to get switch HW ID\n");
 460                 return err;
 461         }
 462 
 463         err = mlxsw_sib_ports_create(mlxsw_sib);
 464         if (err) {
 465                 dev_err(mlxsw_sib->bus_info->dev, "Failed to create ports\n");
 466                 return err;
 467         }
 468 
 469         err = mlxsw_sib_taps_init(mlxsw_sib);
 470         if (err) {
 471                 dev_err(mlxsw_sib->bus_info->dev, "Failed to set traps\n");
 472                 goto err_traps_init_err;
 473         }
 474 
 475         return 0;
 476 
 477 err_traps_init_err:
 478         mlxsw_sib_ports_remove(mlxsw_sib);
 479         return err;
 480 }
 481 
 482 static void mlxsw_sib_fini(struct mlxsw_core *mlxsw_core)
 483 {
 484         struct mlxsw_sib *mlxsw_sib = mlxsw_core_driver_priv(mlxsw_core);
 485 
 486         mlxsw_sib_traps_fini(mlxsw_sib);
 487         mlxsw_sib_ports_remove(mlxsw_sib);
 488 }
 489 
 490 static const struct mlxsw_config_profile mlxsw_sib_config_profile = {
 491         .used_max_system_port           = 1,
 492         .max_system_port                = 48000,
 493         .used_max_ib_mc                 = 1,
 494         .max_ib_mc                      = 27,
 495         .used_max_pkey                  = 1,
 496         .max_pkey                       = 32,
 497         .swid_config                    = {
 498                 {
 499                         .used_type      = 1,
 500                         .type           = MLXSW_PORT_SWID_TYPE_IB,
 501                 }
 502         },
 503 };
 504 
 505 static struct mlxsw_driver mlxsw_sib_driver = {
 506         .kind                   = mlxsw_sib_driver_name,
 507         .priv_size              = sizeof(struct mlxsw_sib),
 508         .init                   = mlxsw_sib_init,
 509         .fini                   = mlxsw_sib_fini,
 510         .basic_trap_groups_set  = mlxsw_sib_basic_trap_groups_set,
 511         .txhdr_construct        = mlxsw_sib_tx_v1_hdr_construct,
 512         .txhdr_len              = MLXSW_TXHDR_LEN,
 513         .profile                = &mlxsw_sib_config_profile,
 514 };
 515 
 516 static struct mlxsw_driver mlxsw_sib2_driver = {
 517         .kind                   = mlxsw_sib2_driver_name,
 518         .priv_size              = sizeof(struct mlxsw_sib),
 519         .init                   = mlxsw_sib_init,
 520         .fini                   = mlxsw_sib_fini,
 521         .basic_trap_groups_set  = mlxsw_sib_basic_trap_groups_set,
 522         .txhdr_construct        = mlxsw_sib_tx_v1_hdr_construct,
 523         .txhdr_len              = MLXSW_TXHDR_LEN,
 524         .profile                = &mlxsw_sib_config_profile,
 525 };
 526 
 527 static const struct pci_device_id mlxsw_sib_pci_id_table[] = {
 528         {PCI_VDEVICE(MELLANOX, PCI_DEVICE_ID_MELLANOX_SWITCHIB), 0},
 529         {0, },
 530 };
 531 
 532 static struct pci_driver mlxsw_sib_pci_driver = {
 533         .name = mlxsw_sib_driver_name,
 534         .id_table = mlxsw_sib_pci_id_table,
 535 };
 536 
 537 static const struct pci_device_id mlxsw_sib2_pci_id_table[] = {
 538         {PCI_VDEVICE(MELLANOX, PCI_DEVICE_ID_MELLANOX_SWITCHIB2), 0},
 539         {0, },
 540 };
 541 
 542 static struct pci_driver mlxsw_sib2_pci_driver = {
 543         .name = mlxsw_sib2_driver_name,
 544         .id_table = mlxsw_sib2_pci_id_table,
 545 };
 546 
 547 static int __init mlxsw_sib_module_init(void)
 548 {
 549         int err;
 550 
 551         err = mlxsw_core_driver_register(&mlxsw_sib_driver);
 552         if (err)
 553                 return err;
 554 
 555         err = mlxsw_core_driver_register(&mlxsw_sib2_driver);
 556         if (err)
 557                 goto err_sib2_driver_register;
 558 
 559         err = mlxsw_pci_driver_register(&mlxsw_sib_pci_driver);
 560         if (err)
 561                 goto err_sib_pci_driver_register;
 562 
 563         err = mlxsw_pci_driver_register(&mlxsw_sib2_pci_driver);
 564         if (err)
 565                 goto err_sib2_pci_driver_register;
 566 
 567         return 0;
 568 
 569 err_sib2_pci_driver_register:
 570         mlxsw_pci_driver_unregister(&mlxsw_sib_pci_driver);
 571 err_sib_pci_driver_register:
 572         mlxsw_core_driver_unregister(&mlxsw_sib2_driver);
 573 err_sib2_driver_register:
 574         mlxsw_core_driver_unregister(&mlxsw_sib_driver);
 575         return err;
 576 }
 577 
 578 static void __exit mlxsw_sib_module_exit(void)
 579 {
 580         mlxsw_pci_driver_unregister(&mlxsw_sib2_pci_driver);
 581         mlxsw_pci_driver_unregister(&mlxsw_sib_pci_driver);
 582         mlxsw_core_driver_unregister(&mlxsw_sib2_driver);
 583         mlxsw_core_driver_unregister(&mlxsw_sib_driver);
 584 }
 585 
 586 module_init(mlxsw_sib_module_init);
 587 module_exit(mlxsw_sib_module_exit);
 588 
 589 MODULE_LICENSE("Dual BSD/GPL");
 590 MODULE_AUTHOR("Elad Raz <eladr@@mellanox.com>");
 591 MODULE_DESCRIPTION("Mellanox SwitchIB and SwitchIB-2 driver");
 592 MODULE_ALIAS("mlxsw_switchib2");
 593 MODULE_DEVICE_TABLE(pci, mlxsw_sib_pci_id_table);
 594 MODULE_DEVICE_TABLE(pci, mlxsw_sib2_pci_id_table);

/* [<][>][^][v][top][bottom][index][help] */