@@ -33,6 +33,7 @@ config MLX4_EN_VXLAN
config MLX4_CORE
tristate
depends on PCI
+ select DEVCONF
default n
config MLX4_DEBUG
@@ -42,6 +42,7 @@
#include <linux/io-mapping.h>
#include <linux/delay.h>
#include <linux/kmod.h>
+#include <linux/devconf.h>
#include <linux/mlx4/device.h>
#include <linux/mlx4/doorbell.h>
@@ -55,6 +56,7 @@ MODULE_DESCRIPTION("Mellanox ConnectX HCA low-level driver");
MODULE_LICENSE("Dual BSD/GPL");
MODULE_VERSION(DRV_VERSION);
+static struct devconf_config_driver *mlx4_conf;
struct workqueue_struct *mlx4_wq;
#ifdef CONFIG_MLX4_DEBUG
@@ -255,6 +257,36 @@ static void mlx4_enable_cqe_eqe_stride(struct mlx4_dev *dev)
}
}
+static int config_port_type(struct mlx4_priv *priv,
+ int port_num,
+ int *port_type)
+{
+ struct devconf_config_object *port, *ports;
+ int err;
+ char port_n[sizeof(int)];
+
+ if (!priv->config_obj)
+ return -ENOENT;
+
+ ports = devconf_get_config_object(&priv->config_obj->group, "ports");
+ if (!ports) {
+ pr_err("Fail to get ports configuration\n");
+ return -ENOENT;
+ }
+
+ sprintf(port_n, "%d", port_num);
+ port = devconf_get_config_object(&ports->group, port_n);
+ if (!port)
+ return -ENOENT;
+ err = devconf_get_int_attr(mlx4_conf, port, "type", port_type);
+ if (err < 0) {
+ pr_err("Fail to get port %d type from dev_c_mlx4 configuration module\n",
+ port_num);
+ return err;
+ }
+ return 0;
+}
+
static int _mlx4_dev_port(struct mlx4_dev *dev, int port,
struct mlx4_port_cap *port_cap)
{
@@ -297,6 +329,8 @@ static int mlx4_dev_port(struct mlx4_dev *dev, int port,
#define MLX4_A0_STEERING_TABLE_SIZE 256
static int mlx4_dev_cap(struct mlx4_dev *dev, struct mlx4_dev_cap *dev_cap)
{
+ struct mlx4_priv *priv = mlx4_priv(dev);
+ int port_type;
int err;
int i;
@@ -411,7 +445,11 @@ static int mlx4_dev_cap(struct mlx4_dev *dev, struct mlx4_dev_cap *dev_cap)
/* if IB and ETH are supported, we set the port
* type according to user selection of port type;
* if user selected none, take the FW hint */
- if (port_type_array[i - 1] == MLX4_PORT_TYPE_NONE)
+ err = config_port_type(priv, i, &port_type);
+ if (!err)
+ dev->caps.port_type[i] = port_type;
+ else if (port_type_array[i - 1] ==
+ MLX4_PORT_TYPE_NONE)
dev->caps.port_type[i] = dev->caps.suggested_type[i] ?
MLX4_PORT_TYPE_ETH : MLX4_PORT_TYPE_IB;
else
@@ -3072,6 +3110,7 @@ static int mlx4_init_one(struct pci_dev *pdev, const struct pci_device_id *id)
{
struct mlx4_priv *priv;
struct mlx4_dev *dev;
+ struct devconf_config_object *pdevs;
int ret;
printk_once(KERN_INFO "%s", mlx4_version);
@@ -3085,6 +3124,20 @@ static int mlx4_init_one(struct pci_dev *pdev, const struct pci_device_id *id)
pci_set_drvdata(pdev, dev);
priv->pci_dev_data = id->driver_data;
+ mlx4_conf = devconf_get_config_driver(DRV_NAME);
+ if (IS_ERR(mlx4_conf)) {
+ pr_warn("Configuration driver is missing for "
+ DRV_NAME ", using default vlaues.\n");
+ } else {
+ pdevs = devconf_get_config_object(&mlx4_conf->cobj.group,
+ "pdevs");
+ if (!pdevs)
+ pr_err("Couldn't find 'pdevs' config object\n");
+ else
+ priv->config_obj =
+ devconf_get_config_object(&pdevs->group,
+ pci_name(pdev));
+ }
ret = __mlx4_init_one(pdev, id->driver_data, priv);
if (ret)
kfree(priv);
@@ -881,6 +881,7 @@ struct mlx4_priv {
atomic_t opreq_count;
struct work_struct opreq_task;
+ struct devconf_config_object *config_obj;
};
static inline struct mlx4_priv *mlx4_priv(struct mlx4_dev *dev)