Commit 6a02f5eb authored by David S. Miller's avatar David S. Miller

Merge branch 'mlxsw-i2c'

Jiri Pirko says:

====================
mlxsw: Introduce support for I2C bus

Vadim says:

This patchset adds I2C access support for SwitchX, SwitchX2, SwitchIB,
SwitchIB2 and Spectrum silicones.

It contains:
 - Small changes in mlxsw core code, needed for I2C bus support;
 - I2C driver, which obtains I2C input/output mailboxes setting and
   provides command interface implementation.
 - Minimal driver, which works on top of I2C driver and allows running
   of mlxsw command interface over I2C bus;

Use case:
On system, which does not have PCI to ASIC (BMC), hwmon functionality
(sensors, pwm, tacho) will be available through I2C.

Usage (manual probing):
echo mlxsw_minimal 0x48 > /sys/bus/i2c/devices/i2c-2/new_device

Sysfs interface:
/sys/bus/i2c/devices/2-0048/hwmon/hwmon5/pwm1
/sys/bus/i2c/devices/2-0048/hwmon/hwmon5/temp1_input
====================
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parents d01eb808 d556e929
...@@ -29,6 +29,16 @@ config MLXSW_PCI ...@@ -29,6 +29,16 @@ config MLXSW_PCI
To compile this driver as a module, choose M here: the To compile this driver as a module, choose M here: the
module will be called mlxsw_pci. module will be called mlxsw_pci.
config MLXSW_I2C
tristate "I2C bus implementation for Mellanox Technologies Switch ASICs"
depends on I2C && MLXSW_CORE
default m
---help---
This is I2C bus implementation for Mellanox Technologies Switch ASICs.
To compile this driver as a module, choose M here: the
module will be called mlxsw_i2c.
config MLXSW_SWITCHIB config MLXSW_SWITCHIB
tristate "Mellanox Technologies SwitchIB and SwitchIB-2 support" tristate "Mellanox Technologies SwitchIB and SwitchIB-2 support"
depends on MLXSW_CORE && NET_SWITCHDEV depends on MLXSW_CORE && NET_SWITCHDEV
...@@ -69,3 +79,14 @@ config MLXSW_SPECTRUM_DCB ...@@ -69,3 +79,14 @@ config MLXSW_SPECTRUM_DCB
---help--- ---help---
Say Y here if you want to use Data Center Bridging (DCB) in the Say Y here if you want to use Data Center Bridging (DCB) in the
driver. driver.
config MLXSW_MINIMAL
tristate "Mellanox Technologies minimal I2C support"
depends on MLXSW_CORE && MLXSW_I2C
default m
---help---
This driver supports I2C access for Mellanox Technologies Switch
ASICs.
To compile this driver as a module, choose M here: the
module will be called mlxsw_minimal.
...@@ -3,6 +3,8 @@ mlxsw_core-objs := core.o ...@@ -3,6 +3,8 @@ mlxsw_core-objs := core.o
mlxsw_core-$(CONFIG_MLXSW_CORE_HWMON) += core_hwmon.o mlxsw_core-$(CONFIG_MLXSW_CORE_HWMON) += core_hwmon.o
obj-$(CONFIG_MLXSW_PCI) += mlxsw_pci.o obj-$(CONFIG_MLXSW_PCI) += mlxsw_pci.o
mlxsw_pci-objs := pci.o mlxsw_pci-objs := pci.o
obj-$(CONFIG_MLXSW_I2C) += mlxsw_i2c.o
mlxsw_i2c-objs := i2c.o
obj-$(CONFIG_MLXSW_SWITCHIB) += mlxsw_switchib.o obj-$(CONFIG_MLXSW_SWITCHIB) += mlxsw_switchib.o
mlxsw_switchib-objs := switchib.o mlxsw_switchib-objs := switchib.o
obj-$(CONFIG_MLXSW_SWITCHX2) += mlxsw_switchx2.o obj-$(CONFIG_MLXSW_SWITCHX2) += mlxsw_switchx2.o
...@@ -12,3 +14,5 @@ mlxsw_spectrum-objs := spectrum.o spectrum_buffers.o \ ...@@ -12,3 +14,5 @@ mlxsw_spectrum-objs := spectrum.o spectrum_buffers.o \
spectrum_switchdev.o spectrum_router.o \ spectrum_switchdev.o spectrum_router.o \
spectrum_kvdl.o spectrum_kvdl.o
mlxsw_spectrum-$(CONFIG_MLXSW_SPECTRUM_DCB) += spectrum_dcb.o mlxsw_spectrum-$(CONFIG_MLXSW_SPECTRUM_DCB) += spectrum_dcb.o
obj-$(CONFIG_MLXSW_MINIMAL) += mlxsw_minimal.o
mlxsw_minimal-objs := minimal.o
...@@ -598,6 +598,9 @@ static int mlxsw_emad_init(struct mlxsw_core *mlxsw_core) ...@@ -598,6 +598,9 @@ static int mlxsw_emad_init(struct mlxsw_core *mlxsw_core)
u64 tid; u64 tid;
int err; int err;
if (!(mlxsw_core->bus->features & MLXSW_BUS_F_TXRX))
return 0;
/* Set the upper 32 bits of the transaction ID field to a random /* Set the upper 32 bits of the transaction ID field to a random
* number. This allows us to discard EMADs addressed to other * number. This allows us to discard EMADs addressed to other
* devices. * devices.
...@@ -634,6 +637,9 @@ static void mlxsw_emad_fini(struct mlxsw_core *mlxsw_core) ...@@ -634,6 +637,9 @@ static void mlxsw_emad_fini(struct mlxsw_core *mlxsw_core)
{ {
char hpkt_pl[MLXSW_REG_HPKT_LEN]; char hpkt_pl[MLXSW_REG_HPKT_LEN];
if (!(mlxsw_core->bus->features & MLXSW_BUS_F_TXRX))
return;
mlxsw_core->emad.use_emad = false; mlxsw_core->emad.use_emad = false;
mlxsw_reg_hpkt_pack(hpkt_pl, MLXSW_REG_HPKT_ACTION_DISCARD, mlxsw_reg_hpkt_pack(hpkt_pl, MLXSW_REG_HPKT_ACTION_DISCARD,
MLXSW_TRAP_ID_ETHEMAD); MLXSW_TRAP_ID_ETHEMAD);
...@@ -1156,9 +1162,11 @@ int mlxsw_core_bus_device_register(const struct mlxsw_bus_info *mlxsw_bus_info, ...@@ -1156,9 +1162,11 @@ int mlxsw_core_bus_device_register(const struct mlxsw_bus_info *mlxsw_bus_info,
if (err) if (err)
goto err_hwmon_init; goto err_hwmon_init;
if (mlxsw_driver->init) {
err = mlxsw_driver->init(mlxsw_core, mlxsw_bus_info); err = mlxsw_driver->init(mlxsw_core, mlxsw_bus_info);
if (err) if (err)
goto err_driver_init; goto err_driver_init;
}
err = mlxsw_core_debugfs_init(mlxsw_core); err = mlxsw_core_debugfs_init(mlxsw_core);
if (err) if (err)
...@@ -1167,6 +1175,7 @@ int mlxsw_core_bus_device_register(const struct mlxsw_bus_info *mlxsw_bus_info, ...@@ -1167,6 +1175,7 @@ int mlxsw_core_bus_device_register(const struct mlxsw_bus_info *mlxsw_bus_info,
return 0; return 0;
err_debugfs_init: err_debugfs_init:
if (mlxsw_core->driver->fini)
mlxsw_core->driver->fini(mlxsw_core); mlxsw_core->driver->fini(mlxsw_core);
err_driver_init: err_driver_init:
err_hwmon_init: err_hwmon_init:
...@@ -1193,6 +1202,7 @@ void mlxsw_core_bus_device_unregister(struct mlxsw_core *mlxsw_core) ...@@ -1193,6 +1202,7 @@ void mlxsw_core_bus_device_unregister(struct mlxsw_core *mlxsw_core)
struct devlink *devlink = priv_to_devlink(mlxsw_core); struct devlink *devlink = priv_to_devlink(mlxsw_core);
mlxsw_core_debugfs_fini(mlxsw_core); mlxsw_core_debugfs_fini(mlxsw_core);
if (mlxsw_core->driver->fini)
mlxsw_core->driver->fini(mlxsw_core); mlxsw_core->driver->fini(mlxsw_core);
devlink_unregister(devlink); devlink_unregister(devlink);
mlxsw_emad_fini(mlxsw_core); mlxsw_emad_fini(mlxsw_core);
......
...@@ -268,6 +268,8 @@ u64 mlxsw_core_res_get(struct mlxsw_core *mlxsw_core, ...@@ -268,6 +268,8 @@ u64 mlxsw_core_res_get(struct mlxsw_core *mlxsw_core,
#define MLXSW_CORE_RES_GET(res, short_res_id) \ #define MLXSW_CORE_RES_GET(res, short_res_id) \
mlxsw_core_res_get(res, MLXSW_RES_ID_##short_res_id) mlxsw_core_res_get(res, MLXSW_RES_ID_##short_res_id)
#define MLXSW_BUS_F_TXRX BIT(0)
struct mlxsw_bus { struct mlxsw_bus {
const char *kind; const char *kind;
int (*init)(void *bus_priv, struct mlxsw_core *mlxsw_core, int (*init)(void *bus_priv, struct mlxsw_core *mlxsw_core,
...@@ -283,6 +285,7 @@ struct mlxsw_bus { ...@@ -283,6 +285,7 @@ struct mlxsw_bus {
char *in_mbox, size_t in_mbox_size, char *in_mbox, size_t in_mbox_size,
char *out_mbox, size_t out_mbox_size, char *out_mbox, size_t out_mbox_size,
u8 *p_status); u8 *p_status);
u8 features;
}; };
struct mlxsw_bus_info { struct mlxsw_bus_info {
......
This diff is collapsed.
/*
* drivers/net/ethernet/mellanox/mlxsw/i2c.h
* Copyright (c) 2016 Mellanox Technologies. All rights reserved.
* Copyright (c) 2016 Vadim Pasternak <vadimp@mellanox.com>
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the names of the copyright holders nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* Alternatively, this software may be distributed under the terms of the
* GNU General Public License ("GPL") version 2 as published by the Free
* Software Foundation.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef _MLXSW_I2C_H
#define _MLXSW_I2C_H
#include <linux/i2c.h>
#if IS_ENABLED(CONFIG_MLXSW_I2C)
int mlxsw_i2c_driver_register(struct i2c_driver *i2c_driver);
void mlxsw_i2c_driver_unregister(struct i2c_driver *i2c_driver);
#else
static inline int
mlxsw_i2c_driver_register(struct i2c_driver *i2c_driver)
{
return -ENODEV;
}
static inline void
mlxsw_i2c_driver_unregister(struct i2c_driver *i2c_driver)
{
}
#endif
#endif
/*
* drivers/net/ethernet/mellanox/mlxsw/minimal.c
* Copyright (c) 2016 Mellanox Technologies. All rights reserved.
* Copyright (c) 2016 Vadim Pasternak <vadimp@mellanox.com>
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the names of the copyright holders nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* Alternatively, this software may be distributed under the terms of the
* GNU General Public License ("GPL") version 2 as published by the Free
* Software Foundation.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
#include <linux/i2c.h>
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/mod_devicetable.h>
#include <linux/types.h>
#include "core.h"
#include "i2c.h"
static const char mlxsw_minimal_driver_name[] = "mlxsw_minimal";
static const struct mlxsw_config_profile mlxsw_minimal_config_profile;
static struct mlxsw_driver mlxsw_minimal_driver = {
.kind = mlxsw_minimal_driver_name,
.priv_size = 1,
.profile = &mlxsw_minimal_config_profile,
};
static const struct i2c_device_id mlxsw_minimal_i2c_id[] = {
{ "mlxsw_minimal", 0},
{ },
};
static struct i2c_driver mlxsw_minimal_i2c_driver = {
.driver.name = "mlxsw_minimal",
.class = I2C_CLASS_HWMON,
.id_table = mlxsw_minimal_i2c_id,
};
static int __init mlxsw_minimal_module_init(void)
{
int err;
err = mlxsw_core_driver_register(&mlxsw_minimal_driver);
if (err)
return err;
err = mlxsw_i2c_driver_register(&mlxsw_minimal_i2c_driver);
if (err)
goto err_i2c_driver_register;
return 0;
err_i2c_driver_register:
mlxsw_core_driver_unregister(&mlxsw_minimal_driver);
return err;
}
static void __exit mlxsw_minimal_module_exit(void)
{
mlxsw_i2c_driver_unregister(&mlxsw_minimal_i2c_driver);
mlxsw_core_driver_unregister(&mlxsw_minimal_driver);
}
module_init(mlxsw_minimal_module_init);
module_exit(mlxsw_minimal_module_exit);
MODULE_LICENSE("Dual BSD/GPL");
MODULE_AUTHOR("Vadim Pasternak <vadimp@mellanox.com>");
MODULE_DESCRIPTION("Mellanox minimal driver");
MODULE_DEVICE_TABLE(i2c, mlxsw_minimal_i2c_id);
...@@ -1755,6 +1755,7 @@ static const struct mlxsw_bus mlxsw_pci_bus = { ...@@ -1755,6 +1755,7 @@ static const struct mlxsw_bus mlxsw_pci_bus = {
.skb_transmit_busy = mlxsw_pci_skb_transmit_busy, .skb_transmit_busy = mlxsw_pci_skb_transmit_busy,
.skb_transmit = mlxsw_pci_skb_transmit, .skb_transmit = mlxsw_pci_skb_transmit,
.cmd_exec = mlxsw_pci_cmd_exec, .cmd_exec = mlxsw_pci_cmd_exec,
.features = MLXSW_BUS_F_TXRX,
}; };
static int mlxsw_pci_sw_reset(struct mlxsw_pci *mlxsw_pci, static int mlxsw_pci_sw_reset(struct mlxsw_pci *mlxsw_pci,
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment