Skip to content

Commit 2701c3b

Browse files
committed
Merge branch 'mlxsw-IB'
Jiri Pirko says: ==================== mlxsw: Add Infiniband support for Mellanox switches This patchset adds basic Infiniband support for SwitchX-2, Switch-IB and Switch-IB-2 ASIC drivers. SwitchX-2 ASIC is VPI capable, which means each port can be either Ethernet or Infiniband. When the port is configured as Infiniband, the Subnet Management Agent (SMA) is managed by the SwitchX-2 firmware and not by the host. Port configuration, MTU and more are configured remotely by the Subnet Manager (SM). Usage: $ devlink port show pci/0000:03:00.0/1: type eth netdev eth0 pci/0000:03:00.0/3: type eth netdev eth1 pci/0000:03:00.0/5: type eth netdev eth2 pci/0000:03:00.0/6: type eth netdev eth3 pci/0000:03:00.0/8: type eth netdev eth4 $ devlink port set pci/0000:03:00.0/1 type ib $ devlink port show pci/0000:03:00.0/1: type ib Switch-IB (FDR) and Switch-IB-2 (EDR 100Gbs) ASICs are Infiniband-only switches. The support provided in the mlxsw_switchib.ko driver is port initialization only. The firmware running in the Silicon implements the SMA. Please note that this patchset does only very basic port initialization. ib_device or RDMA implementations are not part of this patchset. ==================== Signed-off-by: David S. Miller <davem@davemloft.net>
2 parents 27058af + d1ba526 commit 2701c3b

File tree

13 files changed

+1258
-137
lines changed

13 files changed

+1258
-137
lines changed

drivers/net/ethernet/mellanox/mlxsw/Kconfig

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,17 @@ config MLXSW_PCI
2929
To compile this driver as a module, choose M here: the
3030
module will be called mlxsw_pci.
3131

32+
config MLXSW_SWITCHIB
33+
tristate "Mellanox Technologies SwitchIB and SwitchIB-2 support"
34+
depends on MLXSW_CORE && NET_SWITCHDEV
35+
default m
36+
---help---
37+
This driver supports Mellanox Technologies SwitchIB and SwitchIB-2
38+
Infiniband Switch ASICs.
39+
40+
To compile this driver as a module, choose M here: the
41+
module will be called mlxsw_switchib.
42+
3243
config MLXSW_SWITCHX2
3344
tristate "Mellanox Technologies SwitchX-2 support"
3445
depends on MLXSW_CORE && MLXSW_PCI && NET_SWITCHDEV

drivers/net/ethernet/mellanox/mlxsw/Makefile

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,8 @@ mlxsw_core-objs := core.o
33
mlxsw_core-$(CONFIG_MLXSW_CORE_HWMON) += core_hwmon.o
44
obj-$(CONFIG_MLXSW_PCI) += mlxsw_pci.o
55
mlxsw_pci-objs := pci.o
6+
obj-$(CONFIG_MLXSW_SWITCHIB) += mlxsw_switchib.o
7+
mlxsw_switchib-objs := switchib.o
68
obj-$(CONFIG_MLXSW_SWITCHX2) += mlxsw_switchx2.o
79
mlxsw_switchx2-objs := switchx2.o
810
obj-$(CONFIG_MLXSW_SPECTRUM) += mlxsw_spectrum.o

drivers/net/ethernet/mellanox/mlxsw/core.c

Lines changed: 109 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -90,6 +90,23 @@ struct mlxsw_core_pcpu_stats {
9090
u32 port_rx_invalid;
9191
};
9292

93+
struct mlxsw_core_port {
94+
struct devlink_port devlink_port;
95+
void *port_driver_priv;
96+
u8 local_port;
97+
};
98+
99+
void *mlxsw_core_port_driver_priv(struct mlxsw_core_port *mlxsw_core_port)
100+
{
101+
return mlxsw_core_port->port_driver_priv;
102+
}
103+
EXPORT_SYMBOL(mlxsw_core_port_driver_priv);
104+
105+
static bool mlxsw_core_port_check(struct mlxsw_core_port *mlxsw_core_port)
106+
{
107+
return mlxsw_core_port->port_driver_priv != NULL;
108+
}
109+
93110
struct mlxsw_core {
94111
struct mlxsw_driver *driver;
95112
const struct mlxsw_bus *bus;
@@ -114,6 +131,7 @@ struct mlxsw_core {
114131
} lag;
115132
struct mlxsw_res res;
116133
struct mlxsw_hwmon *hwmon;
134+
struct mlxsw_core_port ports[MLXSW_PORT_MAX_PORTS];
117135
unsigned long driver_priv[0];
118136
/* driver_priv has to be always the last item */
119137
};
@@ -920,6 +938,21 @@ static void *__dl_port(struct devlink_port *devlink_port)
920938
return container_of(devlink_port, struct mlxsw_core_port, devlink_port);
921939
}
922940

941+
static int mlxsw_devlink_port_type_set(struct devlink_port *devlink_port,
942+
enum devlink_port_type port_type)
943+
{
944+
struct mlxsw_core *mlxsw_core = devlink_priv(devlink_port->devlink);
945+
struct mlxsw_driver *mlxsw_driver = mlxsw_core->driver;
946+
struct mlxsw_core_port *mlxsw_core_port = __dl_port(devlink_port);
947+
948+
if (!mlxsw_driver->port_type_set)
949+
return -EOPNOTSUPP;
950+
951+
return mlxsw_driver->port_type_set(mlxsw_core,
952+
mlxsw_core_port->local_port,
953+
port_type);
954+
}
955+
923956
static int mlxsw_devlink_sb_port_pool_get(struct devlink_port *devlink_port,
924957
unsigned int sb_index, u16 pool_index,
925958
u32 *p_threshold)
@@ -928,7 +961,8 @@ static int mlxsw_devlink_sb_port_pool_get(struct devlink_port *devlink_port,
928961
struct mlxsw_driver *mlxsw_driver = mlxsw_core->driver;
929962
struct mlxsw_core_port *mlxsw_core_port = __dl_port(devlink_port);
930963

931-
if (!mlxsw_driver->sb_port_pool_get)
964+
if (!mlxsw_driver->sb_port_pool_get ||
965+
!mlxsw_core_port_check(mlxsw_core_port))
932966
return -EOPNOTSUPP;
933967
return mlxsw_driver->sb_port_pool_get(mlxsw_core_port, sb_index,
934968
pool_index, p_threshold);
@@ -942,7 +976,8 @@ static int mlxsw_devlink_sb_port_pool_set(struct devlink_port *devlink_port,
942976
struct mlxsw_driver *mlxsw_driver = mlxsw_core->driver;
943977
struct mlxsw_core_port *mlxsw_core_port = __dl_port(devlink_port);
944978

945-
if (!mlxsw_driver->sb_port_pool_set)
979+
if (!mlxsw_driver->sb_port_pool_set ||
980+
!mlxsw_core_port_check(mlxsw_core_port))
946981
return -EOPNOTSUPP;
947982
return mlxsw_driver->sb_port_pool_set(mlxsw_core_port, sb_index,
948983
pool_index, threshold);
@@ -958,7 +993,8 @@ mlxsw_devlink_sb_tc_pool_bind_get(struct devlink_port *devlink_port,
958993
struct mlxsw_driver *mlxsw_driver = mlxsw_core->driver;
959994
struct mlxsw_core_port *mlxsw_core_port = __dl_port(devlink_port);
960995

961-
if (!mlxsw_driver->sb_tc_pool_bind_get)
996+
if (!mlxsw_driver->sb_tc_pool_bind_get ||
997+
!mlxsw_core_port_check(mlxsw_core_port))
962998
return -EOPNOTSUPP;
963999
return mlxsw_driver->sb_tc_pool_bind_get(mlxsw_core_port, sb_index,
9641000
tc_index, pool_type,
@@ -975,7 +1011,8 @@ mlxsw_devlink_sb_tc_pool_bind_set(struct devlink_port *devlink_port,
9751011
struct mlxsw_driver *mlxsw_driver = mlxsw_core->driver;
9761012
struct mlxsw_core_port *mlxsw_core_port = __dl_port(devlink_port);
9771013

978-
if (!mlxsw_driver->sb_tc_pool_bind_set)
1014+
if (!mlxsw_driver->sb_tc_pool_bind_set ||
1015+
!mlxsw_core_port_check(mlxsw_core_port))
9791016
return -EOPNOTSUPP;
9801017
return mlxsw_driver->sb_tc_pool_bind_set(mlxsw_core_port, sb_index,
9811018
tc_index, pool_type,
@@ -1013,7 +1050,8 @@ mlxsw_devlink_sb_occ_port_pool_get(struct devlink_port *devlink_port,
10131050
struct mlxsw_driver *mlxsw_driver = mlxsw_core->driver;
10141051
struct mlxsw_core_port *mlxsw_core_port = __dl_port(devlink_port);
10151052

1016-
if (!mlxsw_driver->sb_occ_port_pool_get)
1053+
if (!mlxsw_driver->sb_occ_port_pool_get ||
1054+
!mlxsw_core_port_check(mlxsw_core_port))
10171055
return -EOPNOTSUPP;
10181056
return mlxsw_driver->sb_occ_port_pool_get(mlxsw_core_port, sb_index,
10191057
pool_index, p_cur, p_max);
@@ -1029,14 +1067,16 @@ mlxsw_devlink_sb_occ_tc_port_bind_get(struct devlink_port *devlink_port,
10291067
struct mlxsw_driver *mlxsw_driver = mlxsw_core->driver;
10301068
struct mlxsw_core_port *mlxsw_core_port = __dl_port(devlink_port);
10311069

1032-
if (!mlxsw_driver->sb_occ_tc_port_bind_get)
1070+
if (!mlxsw_driver->sb_occ_tc_port_bind_get ||
1071+
!mlxsw_core_port_check(mlxsw_core_port))
10331072
return -EOPNOTSUPP;
10341073
return mlxsw_driver->sb_occ_tc_port_bind_get(mlxsw_core_port,
10351074
sb_index, tc_index,
10361075
pool_type, p_cur, p_max);
10371076
}
10381077

10391078
static const struct devlink_ops mlxsw_devlink_ops = {
1079+
.port_type_set = mlxsw_devlink_port_type_set,
10401080
.port_split = mlxsw_devlink_port_split,
10411081
.port_unsplit = mlxsw_devlink_port_unsplit,
10421082
.sb_pool_get = mlxsw_devlink_sb_pool_get,
@@ -1656,28 +1696,83 @@ u64 mlxsw_core_res_get(struct mlxsw_core *mlxsw_core,
16561696
}
16571697
EXPORT_SYMBOL(mlxsw_core_res_get);
16581698

1659-
int mlxsw_core_port_init(struct mlxsw_core *mlxsw_core,
1660-
struct mlxsw_core_port *mlxsw_core_port, u8 local_port,
1661-
struct net_device *dev, bool split, u32 split_group)
1699+
int mlxsw_core_port_init(struct mlxsw_core *mlxsw_core, u8 local_port)
16621700
{
16631701
struct devlink *devlink = priv_to_devlink(mlxsw_core);
1702+
struct mlxsw_core_port *mlxsw_core_port =
1703+
&mlxsw_core->ports[local_port];
16641704
struct devlink_port *devlink_port = &mlxsw_core_port->devlink_port;
1705+
int err;
16651706

1666-
if (split)
1667-
devlink_port_split_set(devlink_port, split_group);
1668-
devlink_port_type_eth_set(devlink_port, dev);
1669-
return devlink_port_register(devlink, devlink_port, local_port);
1707+
mlxsw_core_port->local_port = local_port;
1708+
err = devlink_port_register(devlink, devlink_port, local_port);
1709+
if (err)
1710+
memset(mlxsw_core_port, 0, sizeof(*mlxsw_core_port));
1711+
return err;
16701712
}
16711713
EXPORT_SYMBOL(mlxsw_core_port_init);
16721714

1673-
void mlxsw_core_port_fini(struct mlxsw_core_port *mlxsw_core_port)
1715+
void mlxsw_core_port_fini(struct mlxsw_core *mlxsw_core, u8 local_port)
16741716
{
1717+
struct mlxsw_core_port *mlxsw_core_port =
1718+
&mlxsw_core->ports[local_port];
16751719
struct devlink_port *devlink_port = &mlxsw_core_port->devlink_port;
16761720

16771721
devlink_port_unregister(devlink_port);
1722+
memset(mlxsw_core_port, 0, sizeof(*mlxsw_core_port));
16781723
}
16791724
EXPORT_SYMBOL(mlxsw_core_port_fini);
16801725

1726+
void mlxsw_core_port_eth_set(struct mlxsw_core *mlxsw_core, u8 local_port,
1727+
void *port_driver_priv, struct net_device *dev,
1728+
bool split, u32 split_group)
1729+
{
1730+
struct mlxsw_core_port *mlxsw_core_port =
1731+
&mlxsw_core->ports[local_port];
1732+
struct devlink_port *devlink_port = &mlxsw_core_port->devlink_port;
1733+
1734+
mlxsw_core_port->port_driver_priv = port_driver_priv;
1735+
if (split)
1736+
devlink_port_split_set(devlink_port, split_group);
1737+
devlink_port_type_eth_set(devlink_port, dev);
1738+
}
1739+
EXPORT_SYMBOL(mlxsw_core_port_eth_set);
1740+
1741+
void mlxsw_core_port_ib_set(struct mlxsw_core *mlxsw_core, u8 local_port,
1742+
void *port_driver_priv)
1743+
{
1744+
struct mlxsw_core_port *mlxsw_core_port =
1745+
&mlxsw_core->ports[local_port];
1746+
struct devlink_port *devlink_port = &mlxsw_core_port->devlink_port;
1747+
1748+
mlxsw_core_port->port_driver_priv = port_driver_priv;
1749+
devlink_port_type_ib_set(devlink_port, NULL);
1750+
}
1751+
EXPORT_SYMBOL(mlxsw_core_port_ib_set);
1752+
1753+
void mlxsw_core_port_clear(struct mlxsw_core *mlxsw_core, u8 local_port,
1754+
void *port_driver_priv)
1755+
{
1756+
struct mlxsw_core_port *mlxsw_core_port =
1757+
&mlxsw_core->ports[local_port];
1758+
struct devlink_port *devlink_port = &mlxsw_core_port->devlink_port;
1759+
1760+
mlxsw_core_port->port_driver_priv = port_driver_priv;
1761+
devlink_port_type_clear(devlink_port);
1762+
}
1763+
EXPORT_SYMBOL(mlxsw_core_port_clear);
1764+
1765+
enum devlink_port_type mlxsw_core_port_type_get(struct mlxsw_core *mlxsw_core,
1766+
u8 local_port)
1767+
{
1768+
struct mlxsw_core_port *mlxsw_core_port =
1769+
&mlxsw_core->ports[local_port];
1770+
struct devlink_port *devlink_port = &mlxsw_core_port->devlink_port;
1771+
1772+
return devlink_port->type;
1773+
}
1774+
EXPORT_SYMBOL(mlxsw_core_port_type_get);
1775+
16811776
static void mlxsw_core_buf_dump_dbg(struct mlxsw_core *mlxsw_core,
16821777
const char *buf, size_t size)
16831778
{

drivers/net/ethernet/mellanox/mlxsw/core.h

Lines changed: 15 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,7 @@
5252
#include "resources.h"
5353

5454
struct mlxsw_core;
55+
struct mlxsw_core_port;
5556
struct mlxsw_driver;
5657
struct mlxsw_bus;
5758
struct mlxsw_bus_info;
@@ -141,23 +142,18 @@ u8 mlxsw_core_lag_mapping_get(struct mlxsw_core *mlxsw_core,
141142
void mlxsw_core_lag_mapping_clear(struct mlxsw_core *mlxsw_core,
142143
u16 lag_id, u8 local_port);
143144

144-
struct mlxsw_core_port {
145-
struct devlink_port devlink_port;
146-
};
147-
148-
static inline void *
149-
mlxsw_core_port_driver_priv(struct mlxsw_core_port *mlxsw_core_port)
150-
{
151-
/* mlxsw_core_port is ensured to always be the first field in driver
152-
* port structure.
153-
*/
154-
return mlxsw_core_port;
155-
}
156-
157-
int mlxsw_core_port_init(struct mlxsw_core *mlxsw_core,
158-
struct mlxsw_core_port *mlxsw_core_port, u8 local_port,
159-
struct net_device *dev, bool split, u32 split_group);
160-
void mlxsw_core_port_fini(struct mlxsw_core_port *mlxsw_core_port);
145+
void *mlxsw_core_port_driver_priv(struct mlxsw_core_port *mlxsw_core_port);
146+
int mlxsw_core_port_init(struct mlxsw_core *mlxsw_core, u8 local_port);
147+
void mlxsw_core_port_fini(struct mlxsw_core *mlxsw_core, u8 local_port);
148+
void mlxsw_core_port_eth_set(struct mlxsw_core *mlxsw_core, u8 local_port,
149+
void *port_driver_priv, struct net_device *dev,
150+
bool split, u32 split_group);
151+
void mlxsw_core_port_ib_set(struct mlxsw_core *mlxsw_core, u8 local_port,
152+
void *port_driver_priv);
153+
void mlxsw_core_port_clear(struct mlxsw_core *mlxsw_core, u8 local_port,
154+
void *port_driver_priv);
155+
enum devlink_port_type mlxsw_core_port_type_get(struct mlxsw_core *mlxsw_core,
156+
u8 local_port);
161157

162158
int mlxsw_core_schedule_dw(struct delayed_work *dwork, unsigned long delay);
163159

@@ -218,6 +214,8 @@ struct mlxsw_driver {
218214
int (*init)(struct mlxsw_core *mlxsw_core,
219215
const struct mlxsw_bus_info *mlxsw_bus_info);
220216
void (*fini)(struct mlxsw_core *mlxsw_core);
217+
int (*port_type_set)(struct mlxsw_core *mlxsw_core, u8 local_port,
218+
enum devlink_port_type new_type);
221219
int (*port_split)(struct mlxsw_core *mlxsw_core, u8 local_port,
222220
unsigned int count);
223221
int (*port_unsplit)(struct mlxsw_core *mlxsw_core, u8 local_port);

drivers/net/ethernet/mellanox/mlxsw/core_hwmon.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -262,7 +262,7 @@ static void mlxsw_hwmon_attr_add(struct mlxsw_hwmon *mlxsw_hwmon,
262262

263263
static int mlxsw_hwmon_temp_init(struct mlxsw_hwmon *mlxsw_hwmon)
264264
{
265-
char mtcap_pl[MLXSW_REG_MTCAP_LEN];
265+
char mtcap_pl[MLXSW_REG_MTCAP_LEN] = {0};
266266
char mtmp_pl[MLXSW_REG_MTMP_LEN];
267267
u8 sensor_count;
268268
int i;
@@ -295,7 +295,7 @@ static int mlxsw_hwmon_temp_init(struct mlxsw_hwmon *mlxsw_hwmon)
295295

296296
static int mlxsw_hwmon_fans_init(struct mlxsw_hwmon *mlxsw_hwmon)
297297
{
298-
char mfcr_pl[MLXSW_REG_MFCR_LEN];
298+
char mfcr_pl[MLXSW_REG_MFCR_LEN] = {0};
299299
enum mlxsw_reg_mfcr_pwm_frequency freq;
300300
unsigned int type_index;
301301
unsigned int num;
Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
/*
2+
* drivers/net/ethernet/mellanox/mlxsw/ib.h
3+
* Copyright (c) 2016 Mellanox Technologies. All rights reserved.
4+
* Copyright (c) 2016 Elad Raz <eladr@mellanox.com>
5+
*
6+
* Redistribution and use in source and binary forms, with or without
7+
* modification, are permitted provided that the following conditions are met:
8+
*
9+
* 1. Redistributions of source code must retain the above copyright
10+
* notice, this list of conditions and the following disclaimer.
11+
* 2. Redistributions in binary form must reproduce the above copyright
12+
* notice, this list of conditions and the following disclaimer in the
13+
* documentation and/or other materials provided with the distribution.
14+
* 3. Neither the names of the copyright holders nor the names of its
15+
* contributors may be used to endorse or promote products derived from
16+
* this software without specific prior written permission.
17+
*
18+
* Alternatively, this software may be distributed under the terms of the
19+
* GNU General Public License ("GPL") version 2 as published by the Free
20+
* Software Foundation.
21+
*
22+
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
23+
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
24+
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
25+
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
26+
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
27+
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
28+
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
29+
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
30+
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
31+
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
32+
* POSSIBILITY OF SUCH DAMAGE.
33+
*/
34+
#ifndef _MLXSW_IB_H
35+
#define _MLXSW_IB_H
36+
37+
#define MLXSW_IB_DEFAULT_MTU 4096
38+
39+
#endif /* _MLXSW_IB_H */

drivers/net/ethernet/mellanox/mlxsw/pci.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,8 @@
3939

4040
#define PCI_DEVICE_ID_MELLANOX_SWITCHX2 0xc738
4141
#define PCI_DEVICE_ID_MELLANOX_SPECTRUM 0xcb84
42+
#define PCI_DEVICE_ID_MELLANOX_SWITCHIB 0xcb20
43+
#define PCI_DEVICE_ID_MELLANOX_SWITCHIB2 0xcf08
4244

4345
#if IS_ENABLED(CONFIG_MLXSW_PCI)
4446

drivers/net/ethernet/mellanox/mlxsw/port.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,13 +44,17 @@
4444

4545
#define MLXSW_PORT_SWID_DISABLED_PORT 255
4646
#define MLXSW_PORT_SWID_ALL_SWIDS 254
47+
#define MLXSW_PORT_SWID_TYPE_IB 1
4748
#define MLXSW_PORT_SWID_TYPE_ETH 2
4849

4950
#define MLXSW_PORT_MID 0xd000
5051

5152
#define MLXSW_PORT_MAX_PHY_PORTS 0x40
5253
#define MLXSW_PORT_MAX_PORTS (MLXSW_PORT_MAX_PHY_PORTS + 1)
5354

55+
#define MLXSW_PORT_MAX_IB_PHY_PORTS 36
56+
#define MLXSW_PORT_MAX_IB_PORTS (MLXSW_PORT_MAX_IB_PHY_PORTS + 1)
57+
5458
#define MLXSW_PORT_DEVID_BITS_OFFSET 10
5559
#define MLXSW_PORT_PHY_BITS_OFFSET 4
5660
#define MLXSW_PORT_PHY_BITS_MASK (MLXSW_PORT_MAX_PHY_PORTS - 1)

0 commit comments

Comments
 (0)