Commit bb62f791 authored by David S. Miller's avatar David S. Miller

Merge branch 'mlx5-next'

Or Gerlitz says:

====================
mlx5: Add Interface Step Sequence ID support

ISSI (Interface Step Sequence ID) defines the step sequence ID of the
interface between the driver to the firmware and is incremented by
steps of one. ISSI is used to enable deprecating/modifying features,
command interfaces and such, while maintaining compatibility.

As the driver serves both ConnectIB (CIB) and ConnectX4, we carefully
made sure that the IB functionality keeps running also on older CIB
firmware releases that don't support ISSI.

The Ethernet functionailty is available only on ConnectX4 where all
firmware releases support the feature since the very basic ISSI level.
So at this point no need for compatility code there.

As done prior to this series, when the Ethernet functionlity is enabled,
during the initialization flow, the core driver performs a query of the
supported ISSIs using the QUERY_ISSI command, and then, if ISSI is supported,
sets the actual issi value informing the firmware on which ISSI level to run,
using SET_ISSI command.

Previously, the IB driver wasn't ready to work on that mode, and hence
building both the IB driver and the Ethernet functionality in the core
driver were disallowed by Kconfigs, with this series, we allow users to
enable them both.
====================
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parents 6a0d7a05 4aa17b28
......@@ -137,3 +137,300 @@ int mlx5_query_ext_port_caps(struct mlx5_ib_dev *dev, u8 port)
kfree(out_mad);
return err;
}
int mlx5_query_mad_ifc_smp_attr_node_info(struct ib_device *ibdev,
struct ib_smp *out_mad)
{
struct ib_smp *in_mad = NULL;
int err = -ENOMEM;
in_mad = kzalloc(sizeof(*in_mad), GFP_KERNEL);
if (!in_mad)
return -ENOMEM;
init_query_mad(in_mad);
in_mad->attr_id = IB_SMP_ATTR_NODE_INFO;
err = mlx5_MAD_IFC(to_mdev(ibdev), 1, 1, 1, NULL, NULL, in_mad,
out_mad);
kfree(in_mad);
return err;
}
int mlx5_query_mad_ifc_system_image_guid(struct ib_device *ibdev,
__be64 *sys_image_guid)
{
struct ib_smp *out_mad = NULL;
int err = -ENOMEM;
out_mad = kmalloc(sizeof(*out_mad), GFP_KERNEL);
if (!out_mad)
return -ENOMEM;
err = mlx5_query_mad_ifc_smp_attr_node_info(ibdev, out_mad);
if (err)
goto out;
memcpy(sys_image_guid, out_mad->data + 4, 8);
out:
kfree(out_mad);
return err;
}
int mlx5_query_mad_ifc_max_pkeys(struct ib_device *ibdev,
u16 *max_pkeys)
{
struct ib_smp *out_mad = NULL;
int err = -ENOMEM;
out_mad = kmalloc(sizeof(*out_mad), GFP_KERNEL);
if (!out_mad)
return -ENOMEM;
err = mlx5_query_mad_ifc_smp_attr_node_info(ibdev, out_mad);
if (err)
goto out;
*max_pkeys = be16_to_cpup((__be16 *)(out_mad->data + 28));
out:
kfree(out_mad);
return err;
}
int mlx5_query_mad_ifc_vendor_id(struct ib_device *ibdev,
u32 *vendor_id)
{
struct ib_smp *out_mad = NULL;
int err = -ENOMEM;
out_mad = kmalloc(sizeof(*out_mad), GFP_KERNEL);
if (!out_mad)
return -ENOMEM;
err = mlx5_query_mad_ifc_smp_attr_node_info(ibdev, out_mad);
if (err)
goto out;
*vendor_id = be32_to_cpup((__be32 *)(out_mad->data + 36)) & 0xffff;
out:
kfree(out_mad);
return err;
}
int mlx5_query_mad_ifc_node_desc(struct mlx5_ib_dev *dev, char *node_desc)
{
struct ib_smp *in_mad = NULL;
struct ib_smp *out_mad = NULL;
int err = -ENOMEM;
in_mad = kzalloc(sizeof(*in_mad), GFP_KERNEL);
out_mad = kmalloc(sizeof(*out_mad), GFP_KERNEL);
if (!in_mad || !out_mad)
goto out;
init_query_mad(in_mad);
in_mad->attr_id = IB_SMP_ATTR_NODE_DESC;
err = mlx5_MAD_IFC(dev, 1, 1, 1, NULL, NULL, in_mad, out_mad);
if (err)
goto out;
memcpy(node_desc, out_mad->data, 64);
out:
kfree(in_mad);
kfree(out_mad);
return err;
}
int mlx5_query_mad_ifc_node_guid(struct mlx5_ib_dev *dev, __be64 *node_guid)
{
struct ib_smp *in_mad = NULL;
struct ib_smp *out_mad = NULL;
int err = -ENOMEM;
in_mad = kzalloc(sizeof(*in_mad), GFP_KERNEL);
out_mad = kmalloc(sizeof(*out_mad), GFP_KERNEL);
if (!in_mad || !out_mad)
goto out;
init_query_mad(in_mad);
in_mad->attr_id = IB_SMP_ATTR_NODE_INFO;
err = mlx5_MAD_IFC(dev, 1, 1, 1, NULL, NULL, in_mad, out_mad);
if (err)
goto out;
memcpy(node_guid, out_mad->data + 12, 8);
out:
kfree(in_mad);
kfree(out_mad);
return err;
}
int mlx5_query_mad_ifc_pkey(struct ib_device *ibdev, u8 port, u16 index,
u16 *pkey)
{
struct ib_smp *in_mad = NULL;
struct ib_smp *out_mad = NULL;
int err = -ENOMEM;
in_mad = kzalloc(sizeof(*in_mad), GFP_KERNEL);
out_mad = kmalloc(sizeof(*out_mad), GFP_KERNEL);
if (!in_mad || !out_mad)
goto out;
init_query_mad(in_mad);
in_mad->attr_id = IB_SMP_ATTR_PKEY_TABLE;
in_mad->attr_mod = cpu_to_be32(index / 32);
err = mlx5_MAD_IFC(to_mdev(ibdev), 1, 1, port, NULL, NULL, in_mad,
out_mad);
if (err)
goto out;
*pkey = be16_to_cpu(((__be16 *)out_mad->data)[index % 32]);
out:
kfree(in_mad);
kfree(out_mad);
return err;
}
int mlx5_query_mad_ifc_gids(struct ib_device *ibdev, u8 port, int index,
union ib_gid *gid)
{
struct ib_smp *in_mad = NULL;
struct ib_smp *out_mad = NULL;
int err = -ENOMEM;
in_mad = kzalloc(sizeof(*in_mad), GFP_KERNEL);
out_mad = kmalloc(sizeof(*out_mad), GFP_KERNEL);
if (!in_mad || !out_mad)
goto out;
init_query_mad(in_mad);
in_mad->attr_id = IB_SMP_ATTR_PORT_INFO;
in_mad->attr_mod = cpu_to_be32(port);
err = mlx5_MAD_IFC(to_mdev(ibdev), 1, 1, port, NULL, NULL, in_mad,
out_mad);
if (err)
goto out;
memcpy(gid->raw, out_mad->data + 8, 8);
init_query_mad(in_mad);
in_mad->attr_id = IB_SMP_ATTR_GUID_INFO;
in_mad->attr_mod = cpu_to_be32(index / 8);
err = mlx5_MAD_IFC(to_mdev(ibdev), 1, 1, port, NULL, NULL, in_mad,
out_mad);
if (err)
goto out;
memcpy(gid->raw + 8, out_mad->data + (index % 8) * 8, 8);
out:
kfree(in_mad);
kfree(out_mad);
return err;
}
int mlx5_query_mad_ifc_port(struct ib_device *ibdev, u8 port,
struct ib_port_attr *props)
{
struct mlx5_ib_dev *dev = to_mdev(ibdev);
struct mlx5_core_dev *mdev = dev->mdev;
struct ib_smp *in_mad = NULL;
struct ib_smp *out_mad = NULL;
int ext_active_speed;
int err = -ENOMEM;
if (port < 1 || port > MLX5_CAP_GEN(mdev, num_ports)) {
mlx5_ib_warn(dev, "invalid port number %d\n", port);
return -EINVAL;
}
in_mad = kzalloc(sizeof(*in_mad), GFP_KERNEL);
out_mad = kmalloc(sizeof(*out_mad), GFP_KERNEL);
if (!in_mad || !out_mad)
goto out;
memset(props, 0, sizeof(*props));
init_query_mad(in_mad);
in_mad->attr_id = IB_SMP_ATTR_PORT_INFO;
in_mad->attr_mod = cpu_to_be32(port);
err = mlx5_MAD_IFC(dev, 1, 1, port, NULL, NULL, in_mad, out_mad);
if (err) {
mlx5_ib_warn(dev, "err %d\n", err);
goto out;
}
props->lid = be16_to_cpup((__be16 *)(out_mad->data + 16));
props->lmc = out_mad->data[34] & 0x7;
props->sm_lid = be16_to_cpup((__be16 *)(out_mad->data + 18));
props->sm_sl = out_mad->data[36] & 0xf;
props->state = out_mad->data[32] & 0xf;
props->phys_state = out_mad->data[33] >> 4;
props->port_cap_flags = be32_to_cpup((__be32 *)(out_mad->data + 20));
props->gid_tbl_len = out_mad->data[50];
props->max_msg_sz = 1 << MLX5_CAP_GEN(mdev, log_max_msg);
props->pkey_tbl_len = mdev->port_caps[port - 1].pkey_table_len;
props->bad_pkey_cntr = be16_to_cpup((__be16 *)(out_mad->data + 46));
props->qkey_viol_cntr = be16_to_cpup((__be16 *)(out_mad->data + 48));
props->active_width = out_mad->data[31] & 0xf;
props->active_speed = out_mad->data[35] >> 4;
props->max_mtu = out_mad->data[41] & 0xf;
props->active_mtu = out_mad->data[36] >> 4;
props->subnet_timeout = out_mad->data[51] & 0x1f;
props->max_vl_num = out_mad->data[37] >> 4;
props->init_type_reply = out_mad->data[41] >> 4;
/* Check if extended speeds (EDR/FDR/...) are supported */
if (props->port_cap_flags & IB_PORT_EXTENDED_SPEEDS_SUP) {
ext_active_speed = out_mad->data[62] >> 4;
switch (ext_active_speed) {
case 1:
props->active_speed = 16; /* FDR */
break;
case 2:
props->active_speed = 32; /* EDR */
break;
}
}
/* If reported active speed is QDR, check if is FDR-10 */
if (props->active_speed == 4) {
if (mdev->port_caps[port - 1].ext_port_cap &
MLX_EXT_PORT_CAP_FLAG_EXTENDED_PORT_INFO) {
init_query_mad(in_mad);
in_mad->attr_id = MLX5_ATTR_EXTENDED_PORT_INFO;
in_mad->attr_mod = cpu_to_be32(port);
err = mlx5_MAD_IFC(dev, 1, 1, port,
NULL, NULL, in_mad, out_mad);
if (err)
goto out;
/* Checking LinkSpeedActive for FDR-10 */
if (out_mad->data[15] & 0x1)
props->active_speed = 8;
}
}
out:
kfree(in_mad);
kfree(out_mad);
return err;
}
This diff is collapsed.
......@@ -415,6 +415,7 @@ struct mlx5_ib_resources {
struct ib_xrcd *x1;
struct ib_pd *p0;
struct ib_srq *s0;
struct ib_srq *s1;
};
struct mlx5_ib_dev {
......@@ -594,6 +595,22 @@ struct ib_xrcd *mlx5_ib_alloc_xrcd(struct ib_device *ibdev,
int mlx5_ib_dealloc_xrcd(struct ib_xrcd *xrcd);
int mlx5_ib_get_buf_offset(u64 addr, int page_shift, u32 *offset);
int mlx5_query_ext_port_caps(struct mlx5_ib_dev *dev, u8 port);
int mlx5_query_mad_ifc_smp_attr_node_info(struct ib_device *ibdev,
struct ib_smp *out_mad);
int mlx5_query_mad_ifc_system_image_guid(struct ib_device *ibdev,
__be64 *sys_image_guid);
int mlx5_query_mad_ifc_max_pkeys(struct ib_device *ibdev,
u16 *max_pkeys);
int mlx5_query_mad_ifc_vendor_id(struct ib_device *ibdev,
u32 *vendor_id);
int mlx5_query_mad_ifc_node_desc(struct mlx5_ib_dev *dev, char *node_desc);
int mlx5_query_mad_ifc_node_guid(struct mlx5_ib_dev *dev, __be64 *node_guid);
int mlx5_query_mad_ifc_pkey(struct ib_device *ibdev, u8 port, u16 index,
u16 *pkey);
int mlx5_query_mad_ifc_gids(struct ib_device *ibdev, u8 port, int index,
union ib_gid *gid);
int mlx5_query_mad_ifc_port(struct ib_device *ibdev, u8 port,
struct ib_port_attr *props);
int mlx5_ib_query_port(struct ib_device *ibdev, u8 port,
struct ib_port_attr *props);
int mlx5_ib_init_fmr(struct mlx5_ib_dev *dev);
......
......@@ -1012,7 +1012,8 @@ static int create_qp_common(struct mlx5_ib_dev *dev, struct ib_pd *pd,
in->ctx.rq_type_srqn |= cpu_to_be32(to_msrq(init_attr->srq)->msrq.srqn);
} else {
in->ctx.xrcd = cpu_to_be32(to_mxrcd(devr->x1)->xrcdn);
in->ctx.rq_type_srqn |= cpu_to_be32(to_msrq(devr->s0)->msrq.srqn);
in->ctx.rq_type_srqn |=
cpu_to_be32(to_msrq(devr->s1)->msrq.srqn);
}
}
......
......@@ -302,7 +302,7 @@ struct ib_srq *mlx5_ib_create_srq(struct ib_pd *pd,
in->ctx.pd = cpu_to_be32(to_mpd(pd)->pdn);
in->ctx.db_record = cpu_to_be64(srq->db.dma);
err = mlx5_core_create_srq(dev->mdev, &srq->msrq, in, inlen);
err = mlx5_core_create_srq(dev->mdev, &srq->msrq, in, inlen, is_xrc);
kvfree(in);
if (err) {
mlx5_ib_dbg(dev, "create SRQ failed, err %d\n", err);
......
......@@ -12,7 +12,7 @@ config MLX5_CORE
config MLX5_CORE_EN
bool "Mellanox Technologies ConnectX-4 Ethernet support"
depends on MLX5_INFINIBAND=n && NETDEVICES && ETHERNET && PCI && MLX5_CORE
depends on NETDEVICES && ETHERNET && PCI && MLX5_CORE
default n
---help---
Ethernet support in Mellanox Technologies ConnectX-4 NIC.
......
......@@ -2,7 +2,7 @@ obj-$(CONFIG_MLX5_CORE) += mlx5_core.o
mlx5_core-y := main.o cmd.o debugfs.o fw.o eq.o uar.o pagealloc.o \
health.o mcg.o cq.o srq.o alloc.o qp.o port.o mr.o pd.o \
mad.o
mlx5_core-$(CONFIG_MLX5_CORE_EN) += wq.o flow_table.o vport.o transobj.o \
mad.o transobj.o vport.o
mlx5_core-$(CONFIG_MLX5_CORE_EN) += wq.o flow_table.o \
en_main.o en_flow_table.o en_ethtool.o en_tx.o en_rx.o \
en_txrx.o
......@@ -35,7 +35,7 @@
#include <linux/mlx5/driver.h>
#include <linux/mlx5/qp.h>
#include <linux/mlx5/cq.h>
#include "vport.h"
#include <linux/mlx5/vport.h>
#include "wq.h"
#include "transobj.h"
#include "mlx5_core.h"
......
......@@ -543,7 +543,7 @@ static int mlx5e_get_settings(struct net_device *netdev,
u32 eth_proto_oper;
int err;
err = mlx5_query_port_ptys(mdev, out, sizeof(out), MLX5_PTYS_EN);
err = mlx5_query_port_ptys(mdev, out, sizeof(out), MLX5_PTYS_EN, 1);
if (err) {
netdev_err(netdev, "%s: query port ptys failed: %d\n",
......
......@@ -722,6 +722,8 @@ static int mlx5e_create_main_flow_table(struct mlx5e_priv *priv)
u8 *dmac;
g = kcalloc(9, sizeof(*g), GFP_KERNEL);
if (!g)
return -ENOMEM;
g[0].log_sz = 2;
g[0].match_criteria_enable = MLX5_MATCH_OUTER_HEADERS;
......
......@@ -367,7 +367,7 @@ static int mlx5e_enable_rq(struct mlx5e_rq *rq, struct mlx5e_rq_param *param)
mlx5_fill_page_array(&rq->wq_ctrl.buf,
(__be64 *)MLX5_ADDR_OF(wq, wq, pas));
err = mlx5_create_rq(mdev, in, inlen, &rq->rqn);
err = mlx5_core_create_rq(mdev, in, inlen, &rq->rqn);
kvfree(in);
......@@ -395,7 +395,7 @@ static int mlx5e_modify_rq(struct mlx5e_rq *rq, int curr_state, int next_state)
MLX5_SET(modify_rq_in, in, rq_state, curr_state);
MLX5_SET(rqc, rqc, state, next_state);
err = mlx5_modify_rq(mdev, rq->rqn, in, inlen);
err = mlx5_core_modify_rq(mdev, rq->rqn, in, inlen);
kvfree(in);
......@@ -408,7 +408,7 @@ static void mlx5e_disable_rq(struct mlx5e_rq *rq)
struct mlx5e_priv *priv = c->priv;
struct mlx5_core_dev *mdev = priv->mdev;
mlx5_destroy_rq(mdev, rq->rqn);
mlx5_core_destroy_rq(mdev, rq->rqn);
}
static int mlx5e_wait_for_min_rx_wqes(struct mlx5e_rq *rq)
......@@ -596,7 +596,7 @@ static int mlx5e_enable_sq(struct mlx5e_sq *sq, struct mlx5e_sq_param *param)
mlx5_fill_page_array(&sq->wq_ctrl.buf,
(__be64 *)MLX5_ADDR_OF(wq, wq, pas));
err = mlx5_create_sq(mdev, in, inlen, &sq->sqn);
err = mlx5_core_create_sq(mdev, in, inlen, &sq->sqn);
kvfree(in);
......@@ -624,7 +624,7 @@ static int mlx5e_modify_sq(struct mlx5e_sq *sq, int curr_state, int next_state)
MLX5_SET(modify_sq_in, in, sq_state, curr_state);
MLX5_SET(sqc, sqc, state, next_state);
err = mlx5_modify_sq(mdev, sq->sqn, in, inlen);
err = mlx5_core_modify_sq(mdev, sq->sqn, in, inlen);
kvfree(in);
......@@ -637,7 +637,7 @@ static void mlx5e_disable_sq(struct mlx5e_sq *sq)
struct mlx5e_priv *priv = c->priv;
struct mlx5_core_dev *mdev = priv->mdev;
mlx5_destroy_sq(mdev, sq->sqn);
mlx5_core_destroy_sq(mdev, sq->sqn);
}
static int mlx5e_open_sq(struct mlx5e_channel *c,
......@@ -1115,12 +1115,12 @@ static int mlx5e_open_tis(struct mlx5e_priv *priv, int tc)
MLX5_SET(tisc, tisc, prio, tc);
return mlx5_create_tis(mdev, in, sizeof(in), &priv->tisn[tc]);
return mlx5_core_create_tis(mdev, in, sizeof(in), &priv->tisn[tc]);
}
static void mlx5e_close_tis(struct mlx5e_priv *priv, int tc)
{
mlx5_destroy_tis(priv->mdev, priv->tisn[tc]);
mlx5_core_destroy_tis(priv->mdev, priv->tisn[tc]);
}
static int mlx5e_open_tises(struct mlx5e_priv *priv)
......@@ -1326,7 +1326,7 @@ static int mlx5e_open_tir(struct mlx5e_priv *priv, int tt)
mlx5e_build_tir_ctx(priv, tirc, tt);
err = mlx5_create_tir(mdev, in, inlen, &priv->tirn[tt]);
err = mlx5_core_create_tir(mdev, in, inlen, &priv->tirn[tt]);
kvfree(in);
......@@ -1335,7 +1335,7 @@ static int mlx5e_open_tir(struct mlx5e_priv *priv, int tt)
static void mlx5e_close_tir(struct mlx5e_priv *priv, int tt)
{
mlx5_destroy_tir(priv->mdev, priv->tirn[tt]);
mlx5_core_destroy_tir(priv->mdev, priv->tirn[tt]);
}
static int mlx5e_open_tirs(struct mlx5e_priv *priv)
......@@ -1386,7 +1386,7 @@ int mlx5e_open_locked(struct net_device *netdev)
return err;
}
err = mlx5_query_port_oper_mtu(mdev, &actual_mtu);
err = mlx5_query_port_oper_mtu(mdev, &actual_mtu, 1);
if (err) {
netdev_err(netdev, "%s: mlx5_query_port_oper_mtu failed %d\n",
__func__, err);
......@@ -1614,7 +1614,7 @@ static int mlx5e_change_mtu(struct net_device *netdev, int new_mtu)
int max_mtu;
int err = 0;
err = mlx5_query_port_max_mtu(mdev, &max_mtu);
err = mlx5_query_port_max_mtu(mdev, &max_mtu, 1);
if (err)
return err;
......@@ -1715,7 +1715,7 @@ static void mlx5e_set_netdev_dev_addr(struct net_device *netdev)
{
struct mlx5e_priv *priv = netdev_priv(netdev);
mlx5_query_vport_mac_address(priv->mdev, netdev->dev_addr);
mlx5_query_nic_vport_mac_address(priv->mdev, netdev->dev_addr);
}
static void mlx5e_build_netdev(struct net_device *netdev)
......
......@@ -35,34 +35,63 @@
#include <linux/module.h>
#include "mlx5_core.h"
int mlx5_cmd_query_adapter(struct mlx5_core_dev *dev)
int mlx5_cmd_query_adapter(struct mlx5_core_dev *dev, u32 *out, int outlen)
{
struct mlx5_cmd_query_adapter_mbox_out *out;
struct mlx5_cmd_query_adapter_mbox_in in;
u32 in[MLX5_ST_SZ_DW(query_adapter_in)];
memset(in, 0, sizeof(in));
MLX5_SET(query_adapter_in, in, opcode, MLX5_CMD_OP_QUERY_ADAPTER);
return mlx5_cmd_exec_check_status(dev, in, sizeof(in), out, outlen);
}
int mlx5_query_board_id(struct mlx5_core_dev *dev)
{
u32 *out;
int outlen = MLX5_ST_SZ_BYTES(query_adapter_out);
int err;
out = kzalloc(sizeof(*out), GFP_KERNEL);
out = kzalloc(outlen, GFP_KERNEL);
if (!out)
return -ENOMEM;
memset(&in, 0, sizeof(in));
in.hdr.opcode = cpu_to_be16(MLX5_CMD_OP_QUERY_ADAPTER);
err = mlx5_cmd_exec(dev, &in, sizeof(in), out, sizeof(*out));
err = mlx5_cmd_query_adapter(dev, out, outlen);
if (err)
goto out_out;
goto out;
if (out->hdr.status) {
err = mlx5_cmd_status_to_err(&out->hdr);
goto out_out;
}
memcpy(dev->board_id,
MLX5_ADDR_OF(query_adapter_out, out,
query_adapter_struct.vsd_contd_psid),
MLX5_FLD_SZ_BYTES(query_adapter_out,
query_adapter_struct.vsd_contd_psid));
memcpy(dev->board_id, out->vsd_psid, sizeof(out->vsd_psid));
out_out:
out:
kfree(out);
return err;
}
int mlx5_core_query_vendor_id(struct mlx5_core_dev *mdev, u32 *vendor_id)
{
u32 *out;
int outlen = MLX5_ST_SZ_BYTES(query_adapter_out);
int err;
out = kzalloc(outlen, GFP_KERNEL);
if (!out)
return -ENOMEM;
err = mlx5_cmd_query_adapter(mdev, out, outlen);
if (err)
goto out;
*vendor_id = MLX5_GET(query_adapter_out, out,
query_adapter_struct.ieee_vendor_id);
out:
kfree(out);
return err;
}
EXPORT_SYMBOL(mlx5_core_query_vendor_id);
int mlx5_query_hca_caps(struct mlx5_core_dev *dev)
{
......
......@@ -284,14 +284,6 @@ static u16 to_fw_pkey_sz(u32 size)
}
}
static u16 to_sw_pkey_sz(int pkey_sz)
{
if (pkey_sz > MLX5_MAX_LOG_PKEY_TABLE)
return 0;
return MLX5_MIN_PKEY_TABLE_SIZE << pkey_sz;
}
int mlx5_core_get_caps(struct mlx5_core_dev *dev, enum mlx5_cap_type cap_type,
enum mlx5_cap_mode cap_mode)
{
......@@ -386,7 +378,7 @@ static int handle_hca_cap(struct mlx5_core_dev *dev)
MLX5_ST_SZ_BYTES(cmd_hca_cap));
mlx5_core_dbg(dev, "Current Pkey table size %d Setting new size %d\n",
to_sw_pkey_sz(MLX5_CAP_GEN(dev, pkey_table_size)),
mlx5_to_sw_pkey_sz(MLX5_CAP_GEN(dev, pkey_table_size)),
128);
/* we limit the size of the pkey table to 128 entries for now */
MLX5_SET(cmd_hca_cap, set_hca_cap, pkey_table_size,
......@@ -654,7 +646,7 @@ static int mlx5_core_set_issi(struct mlx5_core_dev *dev)
dev->issi = 1;
return 0;
} else if (sup_issi & (1 << 0)) {
} else if (sup_issi & (1 << 0) || !sup_issi) {
return 0;
}
......@@ -776,9 +768,9 @@ static int mlx5_dev_init(struct mlx5_core_dev *dev, struct pci_dev *pdev)
goto err_stop_poll;
}
err = mlx5_cmd_query_adapter(dev);
err = mlx5_query_board_id(dev);
if (err) {
dev_err(&pdev->dev, "query adapter failed\n");
dev_err(&pdev->dev, "query board id failed\n");
goto err_stop_poll;
}
......
......@@ -78,7 +78,7 @@ static inline int mlx5_cmd_exec_check_status(struct mlx5_core_dev *dev, u32 *in,
}
int mlx5_query_hca_caps(struct mlx5_core_dev *dev);
int mlx5_cmd_query_adapter(struct mlx5_core_dev *dev);
int mlx5_query_board_id(struct mlx5_core_dev *dev);
int mlx5_cmd_init_hca(struct mlx5_core_dev *dev);
int mlx5_cmd_teardown_hca(struct mlx5_core_dev *dev);
......
......@@ -104,13 +104,13 @@ int mlx5_set_port_caps(struct mlx5_core_dev *dev, u8 port_num, u32 caps)
EXPORT_SYMBOL_GPL(mlx5_set_port_caps);
int mlx5_query_port_ptys(struct mlx5_core_dev *dev, u32 *ptys,
int ptys_size, int proto_mask)
int ptys_size, int proto_mask, u8 local_port)
{
u32 in[MLX5_ST_SZ_DW(ptys_reg)];
int err;
memset(in, 0, sizeof(in));
MLX5_SET(ptys_reg, in, local_port, 1);
MLX5_SET(ptys_reg, in, local_port, local_port);
MLX5_SET(ptys_reg, in, proto_mask, proto_mask);
err = mlx5_core_access_reg(dev, in, sizeof(in), ptys,
......@@ -126,7 +126,7 @@ int mlx5_query_port_proto_cap(struct mlx5_core_dev *dev,
u32 out[MLX5_ST_SZ_DW(ptys_reg)];
int err;
err = mlx5_query_port_ptys(dev, out, sizeof(out), proto_mask);
err = mlx5_query_port_ptys(dev, out, sizeof(out), proto_mask, 1);
if (err)
return err;
......@@ -145,7 +145,7 @@ int mlx5_query_port_proto_admin(struct mlx5_core_dev *dev,
u32 out[MLX5_ST_SZ_DW(ptys_reg)];
int err;
err = mlx5_query_port_ptys(dev, out, sizeof(out), proto_mask);
err = mlx5_query_port_ptys(dev, out, sizeof(out), proto_mask, 1);
if (err)
return err;
......@@ -158,6 +158,42 @@ int mlx5_query_port_proto_admin(struct mlx5_core_dev *dev,
}
EXPORT_SYMBOL_GPL(mlx5_query_port_proto_admin);
int mlx5_query_port_link_width_oper(struct mlx5_core_dev *dev,
u8 *link_width_oper, u8 local_port)
{
u32 out[MLX5_ST_SZ_DW(ptys_reg)];
int err;
err = mlx5_query_port_ptys(dev, out, sizeof(out), MLX5_PTYS_IB, local_port);
if (err)
return err;
*link_width_oper = MLX5_GET(ptys_reg, out, ib_link_width_oper);
return 0;
}
EXPORT_SYMBOL_GPL(mlx5_query_port_link_width_oper);
int mlx5_query_port_proto_oper(struct mlx5_core_dev *dev,
u8 *proto_oper, int proto_mask,
u8 local_port)
{
u32 out[MLX5_ST_SZ_DW(ptys_reg)];
int err;
err = mlx5_query_port_ptys(dev, out, sizeof(out), proto_mask, local_port);
if (err)
return err;
if (proto_mask == MLX5_PTYS_EN)
*proto_oper = MLX5_GET(ptys_reg, out, eth_proto_oper);
else
*proto_oper = MLX5_GET(ptys_reg, out, ib_proto_oper);
return 0;
}
EXPORT_SYMBOL_GPL(mlx5_query_port_proto_oper);
int mlx5_set_port_proto(struct mlx5_core_dev *dev, u32 proto_admin,
int proto_mask)
{
......@@ -213,7 +249,8 @@ int mlx5_query_port_status(struct mlx5_core_dev *dev, u8 *status)
}
static int mlx5_query_port_mtu(struct mlx5_core_dev *dev,
int *admin_mtu, int *max_mtu, int *oper_mtu)
int *admin_mtu, int *max_mtu, int *oper_mtu,
u8 local_port)
{
u32 in[MLX5_ST_SZ_DW(pmtu_reg)];
u32 out[MLX5_ST_SZ_DW(pmtu_reg)];
......@@ -221,7 +258,7 @@ static int mlx5_query_port_mtu(struct mlx5_core_dev *dev,
memset(in, 0, sizeof(in));
MLX5_SET(pmtu_reg, in, local_port, 1);
MLX5_SET(pmtu_reg, in, local_port, local_port);
err = mlx5_core_access_reg(dev, in, sizeof(in), out,
sizeof(out), MLX5_REG_PMTU, 0, 0);
......@@ -253,14 +290,47 @@ int mlx5_set_port_mtu(struct mlx5_core_dev *dev, int mtu)
}
EXPORT_SYMBOL_GPL(mlx5_set_port_mtu);
int mlx5_query_port_max_mtu(struct mlx5_core_dev *dev, int *max_mtu)
int mlx5_query_port_max_mtu(struct mlx5_core_dev *dev, int *max_mtu,
u8 local_port)
{
return mlx5_query_port_mtu(dev, NULL, max_mtu, NULL);
return mlx5_query_port_mtu(dev, NULL, max_mtu, NULL, local_port);
}
EXPORT_SYMBOL_GPL(mlx5_query_port_max_mtu);
int mlx5_query_port_oper_mtu(struct mlx5_core_dev *dev, int *oper_mtu)
int mlx5_query_port_oper_mtu(struct mlx5_core_dev *dev, int *oper_mtu,
u8 local_port)
{
return mlx5_query_port_mtu(dev, NULL, NULL, oper_mtu);
return mlx5_query_port_mtu(dev, NULL, NULL, oper_mtu, local_port);
}
EXPORT_SYMBOL_GPL(mlx5_query_port_oper_mtu);
static int mlx5_query_port_pvlc(struct mlx5_core_dev *dev, u32 *pvlc,
int pvlc_size, u8 local_port)
{
u32 in[MLX5_ST_SZ_DW(pvlc_reg)];
int err;
memset(in, 0, sizeof(in));
MLX5_SET(ptys_reg, in, local_port, local_port);
err = mlx5_core_access_reg(dev, in, sizeof(in), pvlc,
pvlc_size, MLX5_REG_PVLC, 0, 0);
return err;
}
int mlx5_query_port_vl_hw_cap(struct mlx5_core_dev *dev,
u8 *vl_hw_cap, u8 local_port)
{
u32 out[MLX5_ST_SZ_DW(pvlc_reg)];
int err;
err = mlx5_query_port_pvlc(dev, out, sizeof(out), local_port);
if (err)
return err;
*vl_hw_cap = MLX5_GET(pvlc_reg, out, vl_hw_cap);
return 0;
}
EXPORT_SYMBOL_GPL(mlx5_query_port_vl_hw_cap);
......@@ -187,10 +187,17 @@ int mlx5_core_create_qp(struct mlx5_core_dev *dev,
struct mlx5_destroy_qp_mbox_in din;
struct mlx5_destroy_qp_mbox_out dout;
int err;
void *qpc;
memset(&out, 0, sizeof(out));
in->hdr.opcode = cpu_to_be16(MLX5_CMD_OP_CREATE_QP);
if (dev->issi) {
qpc = MLX5_ADDR_OF(create_qp_in, in, qpc);
/* 0xffffff means we ask to work with cqe version 0 */
MLX5_SET(qpc, qpc, user_index, 0xffffff);
}
err = mlx5_cmd_exec(dev, in, inlen, &out, sizeof(out));
if (err) {
mlx5_core_warn(dev, "ret %d\n", err);
......
......@@ -34,7 +34,7 @@
#include "mlx5_core.h"
#include "transobj.h"
int mlx5_create_rq(struct mlx5_core_dev *dev, u32 *in, int inlen, u32 *rqn)
int mlx5_core_create_rq(struct mlx5_core_dev *dev, u32 *in, int inlen, u32 *rqn)
{
u32 out[MLX5_ST_SZ_DW(create_rq_out)];
int err;
......@@ -49,7 +49,7 @@ int mlx5_create_rq(struct mlx5_core_dev *dev, u32 *in, int inlen, u32 *rqn)
return err;
}
int mlx5_modify_rq(struct mlx5_core_dev *dev, u32 rqn, u32 *in, int inlen)
int mlx5_core_modify_rq(struct mlx5_core_dev *dev, u32 rqn, u32 *in, int inlen)
{
u32 out[MLX5_ST_SZ_DW(modify_rq_out)];
......@@ -60,7 +60,7 @@ int mlx5_modify_rq(struct mlx5_core_dev *dev, u32 rqn, u32 *in, int inlen)
return mlx5_cmd_exec_check_status(dev, in, inlen, out, sizeof(out));
}
void mlx5_destroy_rq(struct mlx5_core_dev *dev, u32 rqn)
void mlx5_core_destroy_rq(struct mlx5_core_dev *dev, u32 rqn)
{
u32 in[MLX5_ST_SZ_DW(destroy_rq_in)];
u32 out[MLX5_ST_SZ_DW(destroy_rq_out)];
......@@ -73,7 +73,7 @@ void mlx5_destroy_rq(struct mlx5_core_dev *dev, u32 rqn)
mlx5_cmd_exec_check_status(dev, in, sizeof(in), out, sizeof(out));
}
int mlx5_create_sq(struct mlx5_core_dev *dev, u32 *in, int inlen, u32 *sqn)
int mlx5_core_create_sq(struct mlx5_core_dev *dev, u32 *in, int inlen, u32 *sqn)
{
u32 out[MLX5_ST_SZ_DW(create_sq_out)];
int err;
......@@ -88,7 +88,7 @@ int mlx5_create_sq(struct mlx5_core_dev *dev, u32 *in, int inlen, u32 *sqn)
return err;
}
int mlx5_modify_sq(struct mlx5_core_dev *dev, u32 sqn, u32 *in, int inlen)
int mlx5_core_modify_sq(struct mlx5_core_dev *dev, u32 sqn, u32 *in, int inlen)
{
u32 out[MLX5_ST_SZ_DW(modify_sq_out)];
......@@ -99,7 +99,7 @@ int mlx5_modify_sq(struct mlx5_core_dev *dev, u32 sqn, u32 *in, int inlen)
return mlx5_cmd_exec_check_status(dev, in, inlen, out, sizeof(out));
}
void mlx5_destroy_sq(struct mlx5_core_dev *dev, u32 sqn)
void mlx5_core_destroy_sq(struct mlx5_core_dev *dev, u32 sqn)
{
u32 in[MLX5_ST_SZ_DW(destroy_sq_in)];
u32 out[MLX5_ST_SZ_DW(destroy_sq_out)];
......@@ -112,7 +112,8 @@ void mlx5_destroy_sq(struct mlx5_core_dev *dev, u32 sqn)
mlx5_cmd_exec_check_status(dev, in, sizeof(in), out, sizeof(out));
}
int mlx5_create_tir(struct mlx5_core_dev *dev, u32 *in, int inlen, u32 *tirn)
int mlx5_core_create_tir(struct mlx5_core_dev *dev, u32 *in, int inlen,
u32 *tirn)
{
u32 out[MLX5_ST_SZ_DW(create_tir_out)];
int err;
......@@ -127,7 +128,7 @@ int mlx5_create_tir(struct mlx5_core_dev *dev, u32 *in, int inlen, u32 *tirn)
return err;
}
void mlx5_destroy_tir(struct mlx5_core_dev *dev, u32 tirn)
void mlx5_core_destroy_tir(struct mlx5_core_dev *dev, u32 tirn)
{
u32 in[MLX5_ST_SZ_DW(destroy_tir_out)];
u32 out[MLX5_ST_SZ_DW(destroy_tir_out)];
......@@ -140,7 +141,8 @@ void mlx5_destroy_tir(struct mlx5_core_dev *dev, u32 tirn)
mlx5_cmd_exec_check_status(dev, in, sizeof(in), out, sizeof(out));
}
int mlx5_create_tis(struct mlx5_core_dev *dev, u32 *in, int inlen, u32 *tisn)
int mlx5_core_create_tis(struct mlx5_core_dev *dev, u32 *in, int inlen,
u32 *tisn)
{
u32 out[MLX5_ST_SZ_DW(create_tis_out)];
int err;
......@@ -155,7 +157,7 @@ int mlx5_create_tis(struct mlx5_core_dev *dev, u32 *in, int inlen, u32 *tisn)
return err;
}
void mlx5_destroy_tis(struct mlx5_core_dev *dev, u32 tisn)
void mlx5_core_destroy_tis(struct mlx5_core_dev *dev, u32 tisn)
{
u32 in[MLX5_ST_SZ_DW(destroy_tis_out)];
u32 out[MLX5_ST_SZ_DW(destroy_tis_out)];
......@@ -167,3 +169,157 @@ void mlx5_destroy_tis(struct mlx5_core_dev *dev, u32 tisn)
mlx5_cmd_exec_check_status(dev, in, sizeof(in), out, sizeof(out));
}
int mlx5_core_create_rmp(struct mlx5_core_dev *dev, u32 *in, int inlen,
u32 *rmpn)
{
u32 out[MLX5_ST_SZ_DW(create_rmp_out)];
int err;
MLX5_SET(create_rmp_in, in, opcode, MLX5_CMD_OP_CREATE_RMP);
memset(out, 0, sizeof(out));
err = mlx5_cmd_exec_check_status(dev, in, inlen, out, sizeof(out));
if (!err)
*rmpn = MLX5_GET(create_rmp_out, out, rmpn);
return err;
}
int mlx5_core_modify_rmp(struct mlx5_core_dev *dev, u32 *in, int inlen)
{
u32 out[MLX5_ST_SZ_DW(modify_rmp_out)];
MLX5_SET(modify_rmp_in, in, opcode, MLX5_CMD_OP_MODIFY_RMP);
memset(out, 0, sizeof(out));
return mlx5_cmd_exec_check_status(dev, in, inlen, out, sizeof(out));
}
int mlx5_core_destroy_rmp(struct mlx5_core_dev *dev, u32 rmpn)
{
u32 in[MLX5_ST_SZ_DW(destroy_rmp_in)];
u32 out[MLX5_ST_SZ_DW(destroy_rmp_out)];
memset(in, 0, sizeof(in));
MLX5_SET(destroy_rmp_in, in, opcode, MLX5_CMD_OP_DESTROY_RMP);
MLX5_SET(destroy_rmp_in, in, rmpn, rmpn);
return mlx5_cmd_exec_check_status(dev, in, sizeof(in), out,
sizeof(out));
}
int mlx5_core_query_rmp(struct mlx5_core_dev *dev, u32 rmpn, u32 *out)
{
u32 in[MLX5_ST_SZ_DW(query_rmp_in)];
int outlen = MLX5_ST_SZ_BYTES(query_rmp_out);
memset(in, 0, sizeof(in));
MLX5_SET(query_rmp_in, in, opcode, MLX5_CMD_OP_QUERY_RMP);
MLX5_SET(query_rmp_in, in, rmpn, rmpn);
return mlx5_cmd_exec_check_status(dev, in, sizeof(in), out, outlen);
}
int mlx5_core_arm_rmp(struct mlx5_core_dev *dev, u32 rmpn, u16 lwm)
{
void *in;
void *rmpc;
void *wq;
void *bitmask;
int err;
in = mlx5_vzalloc(MLX5_ST_SZ_BYTES(modify_rmp_in));
if (!in)
return -ENOMEM;
rmpc = MLX5_ADDR_OF(modify_rmp_in, in, ctx);
bitmask = MLX5_ADDR_OF(modify_rmp_in, in, bitmask);
wq = MLX5_ADDR_OF(rmpc, rmpc, wq);
MLX5_SET(modify_rmp_in, in, rmp_state, MLX5_RMPC_STATE_RDY);
MLX5_SET(modify_rmp_in, in, rmpn, rmpn);
MLX5_SET(wq, wq, lwm, lwm);
MLX5_SET(rmp_bitmask, bitmask, lwm, 1);
MLX5_SET(rmpc, rmpc, state, MLX5_RMPC_STATE_RDY);
err = mlx5_core_modify_rmp(dev, in, MLX5_ST_SZ_BYTES(modify_rmp_in));
kvfree(in);
return err;
}
int mlx5_core_create_xsrq(struct mlx5_core_dev *dev, u32 *in, int inlen,
u32 *xsrqn)
{
u32 out[MLX5_ST_SZ_DW(create_xrc_srq_out)];
int err;
MLX5_SET(create_xrc_srq_in, in, opcode, MLX5_CMD_OP_CREATE_XRC_SRQ);
memset(out, 0, sizeof(out));
err = mlx5_cmd_exec_check_status(dev, in, inlen, out, sizeof(out));
if (!err)
*xsrqn = MLX5_GET(create_xrc_srq_out, out, xrc_srqn);
return err;
}
int mlx5_core_destroy_xsrq(struct mlx5_core_dev *dev, u32 xsrqn)
{
u32 in[MLX5_ST_SZ_DW(destroy_xrc_srq_in)];
u32 out[MLX5_ST_SZ_DW(destroy_xrc_srq_out)];
memset(in, 0, sizeof(in));
memset(out, 0, sizeof(out));
MLX5_SET(destroy_xrc_srq_in, in, opcode, MLX5_CMD_OP_DESTROY_XRC_SRQ);
MLX5_SET(destroy_xrc_srq_in, in, xrc_srqn, xsrqn);
return mlx5_cmd_exec_check_status(dev, in, sizeof(in), out,
sizeof(out));
}
int mlx5_core_query_xsrq(struct mlx5_core_dev *dev, u32 xsrqn, u32 *out)
{
u32 in[MLX5_ST_SZ_DW(query_xrc_srq_in)];
void *srqc;
void *xrc_srqc;
int err;
memset(in, 0, sizeof(in));
MLX5_SET(query_xrc_srq_in, in, opcode, MLX5_CMD_OP_QUERY_XRC_SRQ);
MLX5_SET(query_xrc_srq_in, in, xrc_srqn, xsrqn);
err = mlx5_cmd_exec_check_status(dev, in, sizeof(in),
out,
MLX5_ST_SZ_BYTES(query_xrc_srq_out));
if (!err) {
xrc_srqc = MLX5_ADDR_OF(query_xrc_srq_out, out,
xrc_srq_context_entry);
srqc = MLX5_ADDR_OF(query_srq_out, out, srq_context_entry);
memcpy(srqc, xrc_srqc, MLX5_ST_SZ_BYTES(srqc));
}
return err;
}
int mlx5_core_arm_xsrq(struct mlx5_core_dev *dev, u32 xsrqn, u16 lwm)
{
u32 in[MLX5_ST_SZ_DW(arm_xrc_srq_in)];
u32 out[MLX5_ST_SZ_DW(arm_xrc_srq_out)];
memset(in, 0, sizeof(in));
memset(out, 0, sizeof(out));
MLX5_SET(arm_xrc_srq_in, in, opcode, MLX5_CMD_OP_ARM_XRC_SRQ);
MLX5_SET(arm_xrc_srq_in, in, xrc_srqn, xsrqn);
MLX5_SET(arm_xrc_srq_in, in, lwm, lwm);
MLX5_SET(arm_xrc_srq_in, in, op_mod,
MLX5_ARM_XRC_SRQ_IN_OP_MOD_XRC_SRQ);
return mlx5_cmd_exec_check_status(dev, in, sizeof(in), out,
sizeof(out));
}
......@@ -33,15 +33,30 @@
#ifndef __TRANSOBJ_H__
#define __TRANSOBJ_H__
int mlx5_create_rq(struct mlx5_core_dev *dev, u32 *in, int inlen, u32 *rqn);
int mlx5_modify_rq(struct mlx5_core_dev *dev, u32 rqn, u32 *in, int inlen);
void mlx5_destroy_rq(struct mlx5_core_dev *dev, u32 rqn);
int mlx5_create_sq(struct mlx5_core_dev *dev, u32 *in, int inlen, u32 *sqn);
int mlx5_modify_sq(struct mlx5_core_dev *dev, u32 sqn, u32 *in, int inlen);
void mlx5_destroy_sq(struct mlx5_core_dev *dev, u32 sqn);
int mlx5_create_tir(struct mlx5_core_dev *dev, u32 *in, int inlen, u32 *tirn);
void mlx5_destroy_tir(struct mlx5_core_dev *dev, u32 tirn);
int mlx5_create_tis(struct mlx5_core_dev *dev, u32 *in, int inlen, u32 *tisn);
void mlx5_destroy_tis(struct mlx5_core_dev *dev, u32 tisn);
int mlx5_core_create_rq(struct mlx5_core_dev *dev, u32 *in, int inlen,
u32 *rqn);
int mlx5_core_modify_rq(struct mlx5_core_dev *dev, u32 rqn, u32 *in, int inlen);
void mlx5_core_destroy_rq(struct mlx5_core_dev *dev, u32 rqn);
int mlx5_core_create_sq(struct mlx5_core_dev *dev, u32 *in, int inlen,
u32 *sqn);
int mlx5_core_modify_sq(struct mlx5_core_dev *dev, u32 sqn, u32 *in, int inlen);
void mlx5_core_destroy_sq(struct mlx5_core_dev *dev, u32 sqn);
int mlx5_core_create_tir(struct mlx5_core_dev *dev, u32 *in, int inlen,
u32 *tirn);
void mlx5_core_destroy_tir(struct mlx5_core_dev *dev, u32 tirn);
int mlx5_core_create_tis(struct mlx5_core_dev *dev, u32 *in, int inlen,
u32 *tisn);
void mlx5_core_destroy_tis(struct mlx5_core_dev *dev, u32 tisn);
int mlx5_core_create_rmp(struct mlx5_core_dev *dev, u32 *in, int inlen,
u32 *rmpn);
int mlx5_core_modify_rmp(struct mlx5_core_dev *dev, u32 *in, int inlen);
int mlx5_core_destroy_rmp(struct mlx5_core_dev *dev, u32 rmpn);
int mlx5_core_query_rmp(struct mlx5_core_dev *dev, u32 rmpn, u32 *out);
int mlx5_core_arm_rmp(struct mlx5_core_dev *dev, u32 rmpn, u16 lwm);
int mlx5_core_create_xsrq(struct mlx5_core_dev *dev, u32 *in, int inlen,
u32 *rmpn);
int mlx5_core_destroy_xsrq(struct mlx5_core_dev *dev, u32 rmpn);
int mlx5_core_query_xsrq(struct mlx5_core_dev *dev, u32 rmpn, u32 *out);
int mlx5_core_arm_xsrq(struct mlx5_core_dev *dev, u32 rmpn, u16 lwm);
#endif /* __TRANSOBJ_H__ */
......@@ -33,7 +33,7 @@
#include <linux/export.h>
#include <linux/etherdevice.h>
#include <linux/mlx5/driver.h>
#include "vport.h"
#include <linux/mlx5/vport.h>
#include "mlx5_core.h"
u8 mlx5_query_vport_state(struct mlx5_core_dev *mdev, u8 opmod)
......@@ -55,8 +55,9 @@ u8 mlx5_query_vport_state(struct mlx5_core_dev *mdev, u8 opmod)
return MLX5_GET(query_vport_state_out, out, state);
}
EXPORT_SYMBOL(mlx5_query_vport_state);
void mlx5_query_vport_mac_address(struct mlx5_core_dev *mdev, u8 *addr)
void mlx5_query_nic_vport_mac_address(struct mlx5_core_dev *mdev, u8 *addr)
{
u32 in[MLX5_ST_SZ_DW(query_nic_vport_context_in)];
u32 *out;
......@@ -82,3 +83,263 @@ void mlx5_query_vport_mac_address(struct mlx5_core_dev *mdev, u8 *addr)
kvfree(out);
}
EXPORT_SYMBOL(mlx5_query_nic_vport_mac_address);
int mlx5_query_hca_vport_gid(struct mlx5_core_dev *dev, u8 other_vport,
u8 port_num, u16 vf_num, u16 gid_index,
union ib_gid *gid)
{
int in_sz = MLX5_ST_SZ_BYTES(query_hca_vport_gid_in);
int out_sz = MLX5_ST_SZ_BYTES(query_hca_vport_gid_out);
int is_group_manager;
void *out = NULL;
void *in = NULL;
union ib_gid *tmp;
int tbsz;
int nout;
int err;
is_group_manager = MLX5_CAP_GEN(dev, vport_group_manager);
tbsz = mlx5_get_gid_table_len(MLX5_CAP_GEN(dev, gid_table_size));
mlx5_core_dbg(dev, "vf_num %d, index %d, gid_table_size %d\n",
vf_num, gid_index, tbsz);
if (gid_index > tbsz && gid_index != 0xffff)
return -EINVAL;
if (gid_index == 0xffff)
nout = tbsz;
else
nout = 1;
out_sz += nout * sizeof(*gid);
in = kzalloc(in_sz, GFP_KERNEL);
out = kzalloc(out_sz, GFP_KERNEL);
if (!in || !out) {
err = -ENOMEM;
goto out;
}
MLX5_SET(query_hca_vport_gid_in, in, opcode, MLX5_CMD_OP_QUERY_HCA_VPORT_GID);
if (other_vport) {
if (is_group_manager) {
MLX5_SET(query_hca_vport_gid_in, in, vport_number, vf_num);
MLX5_SET(query_hca_vport_gid_in, in, other_vport, 1);
} else {
err = -EPERM;
goto out;
}
}
MLX5_SET(query_hca_vport_gid_in, in, gid_index, gid_index);
if (MLX5_CAP_GEN(dev, num_ports) == 2)
MLX5_SET(query_hca_vport_gid_in, in, port_num, port_num);
err = mlx5_cmd_exec(dev, in, in_sz, out, out_sz);
if (err)
goto out;
err = mlx5_cmd_status_to_err_v2(out);
if (err)
goto out;
tmp = out + MLX5_ST_SZ_BYTES(query_hca_vport_gid_out);
gid->global.subnet_prefix = tmp->global.subnet_prefix;
gid->global.interface_id = tmp->global.interface_id;
out:
kfree(in);
kfree(out);
return err;
}
EXPORT_SYMBOL_GPL(mlx5_query_hca_vport_gid);
int mlx5_query_hca_vport_pkey(struct mlx5_core_dev *dev, u8 other_vport,
u8 port_num, u16 vf_num, u16 pkey_index,
u16 *pkey)
{
int in_sz = MLX5_ST_SZ_BYTES(query_hca_vport_pkey_in);
int out_sz = MLX5_ST_SZ_BYTES(query_hca_vport_pkey_out);
int is_group_manager;
void *out = NULL;
void *in = NULL;
void *pkarr;
int nout;
int tbsz;
int err;
int i;
is_group_manager = MLX5_CAP_GEN(dev, vport_group_manager);
tbsz = mlx5_to_sw_pkey_sz(MLX5_CAP_GEN(dev, pkey_table_size));
if (pkey_index > tbsz && pkey_index != 0xffff)
return -EINVAL;
if (pkey_index == 0xffff)
nout = tbsz;
else
nout = 1;
out_sz += nout * MLX5_ST_SZ_BYTES(pkey);
in = kzalloc(in_sz, GFP_KERNEL);
out = kzalloc(out_sz, GFP_KERNEL);
if (!in || !out) {
err = -ENOMEM;
goto out;
}
MLX5_SET(query_hca_vport_pkey_in, in, opcode, MLX5_CMD_OP_QUERY_HCA_VPORT_PKEY);
if (other_vport) {
if (is_group_manager) {
MLX5_SET(query_hca_vport_pkey_in, in, vport_number, vf_num);
MLX5_SET(query_hca_vport_pkey_in, in, other_vport, 1);
} else {
err = -EPERM;
goto out;
}
}
MLX5_SET(query_hca_vport_pkey_in, in, pkey_index, pkey_index);
if (MLX5_CAP_GEN(dev, num_ports) == 2)
MLX5_SET(query_hca_vport_pkey_in, in, port_num, port_num);
err = mlx5_cmd_exec(dev, in, in_sz, out, out_sz);
if (err)
goto out;
err = mlx5_cmd_status_to_err_v2(out);
if (err)
goto out;
pkarr = MLX5_ADDR_OF(query_hca_vport_pkey_out, out, pkey);
for (i = 0; i < nout; i++, pkey++, pkarr += MLX5_ST_SZ_BYTES(pkey))
*pkey = MLX5_GET_PR(pkey, pkarr, pkey);
out:
kfree(in);
kfree(out);
return err;
}
EXPORT_SYMBOL_GPL(mlx5_query_hca_vport_pkey);
int mlx5_query_hca_vport_context(struct mlx5_core_dev *dev,
u8 other_vport, u8 port_num,
u16 vf_num,
struct mlx5_hca_vport_context *rep)
{
int out_sz = MLX5_ST_SZ_BYTES(query_hca_vport_context_out);
int in[MLX5_ST_SZ_DW(query_hca_vport_context_in)];
int is_group_manager;
void *out;
void *ctx;
int err;
is_group_manager = MLX5_CAP_GEN(dev, vport_group_manager);
memset(in, 0, sizeof(in));
out = kzalloc(out_sz, GFP_KERNEL);
if (!out)
return -ENOMEM;
MLX5_SET(query_hca_vport_context_in, in, opcode, MLX5_CMD_OP_QUERY_HCA_VPORT_CONTEXT);
if (other_vport) {
if (is_group_manager) {
MLX5_SET(query_hca_vport_context_in, in, other_vport, 1);
MLX5_SET(query_hca_vport_context_in, in, vport_number, vf_num);
} else {
err = -EPERM;
goto ex;
}
}
if (MLX5_CAP_GEN(dev, num_ports) == 2)
MLX5_SET(query_hca_vport_context_in, in, port_num, port_num);
err = mlx5_cmd_exec(dev, in, sizeof(in), out, out_sz);
if (err)
goto ex;
err = mlx5_cmd_status_to_err_v2(out);
if (err)
goto ex;
ctx = MLX5_ADDR_OF(query_hca_vport_context_out, out, hca_vport_context);
rep->field_select = MLX5_GET_PR(hca_vport_context, ctx, field_select);
rep->sm_virt_aware = MLX5_GET_PR(hca_vport_context, ctx, sm_virt_aware);
rep->has_smi = MLX5_GET_PR(hca_vport_context, ctx, has_smi);
rep->has_raw = MLX5_GET_PR(hca_vport_context, ctx, has_raw);
rep->policy = MLX5_GET_PR(hca_vport_context, ctx, vport_state_policy);
rep->phys_state = MLX5_GET_PR(hca_vport_context, ctx,
port_physical_state);
rep->vport_state = MLX5_GET_PR(hca_vport_context, ctx, vport_state);
rep->port_physical_state = MLX5_GET_PR(hca_vport_context, ctx,
port_physical_state);
rep->port_guid = MLX5_GET64_PR(hca_vport_context, ctx, port_guid);
rep->node_guid = MLX5_GET64_PR(hca_vport_context, ctx, node_guid);
rep->cap_mask1 = MLX5_GET_PR(hca_vport_context, ctx, cap_mask1);
rep->cap_mask1_perm = MLX5_GET_PR(hca_vport_context, ctx,
cap_mask1_field_select);
rep->cap_mask2 = MLX5_GET_PR(hca_vport_context, ctx, cap_mask2);
rep->cap_mask2_perm = MLX5_GET_PR(hca_vport_context, ctx,
cap_mask2_field_select);
rep->lid = MLX5_GET_PR(hca_vport_context, ctx, lid);
rep->init_type_reply = MLX5_GET_PR(hca_vport_context, ctx,
init_type_reply);
rep->lmc = MLX5_GET_PR(hca_vport_context, ctx, lmc);
rep->subnet_timeout = MLX5_GET_PR(hca_vport_context, ctx,
subnet_timeout);
rep->sm_lid = MLX5_GET_PR(hca_vport_context, ctx, sm_lid);
rep->sm_sl = MLX5_GET_PR(hca_vport_context, ctx, sm_sl);
rep->qkey_violation_counter = MLX5_GET_PR(hca_vport_context, ctx,
qkey_violation_counter);
rep->pkey_violation_counter = MLX5_GET_PR(hca_vport_context, ctx,
pkey_violation_counter);
rep->grh_required = MLX5_GET_PR(hca_vport_context, ctx, grh_required);
rep->sys_image_guid = MLX5_GET64_PR(hca_vport_context, ctx,
system_image_guid);
ex:
kfree(out);
return err;
}
EXPORT_SYMBOL_GPL(mlx5_query_hca_vport_context);
int mlx5_query_hca_vport_system_image_guid(struct mlx5_core_dev *dev,
__be64 *sys_image_guid)
{
struct mlx5_hca_vport_context *rep;
int err;
rep = kzalloc(sizeof(*rep), GFP_KERNEL);
if (!rep)
return -ENOMEM;
err = mlx5_query_hca_vport_context(dev, 0, 1, 0, rep);
if (!err)
*sys_image_guid = rep->sys_image_guid;
kfree(rep);
return err;
}
EXPORT_SYMBOL_GPL(mlx5_query_hca_vport_system_image_guid);
int mlx5_query_hca_vport_node_guid(struct mlx5_core_dev *dev,
u64 *node_guid)
{
struct mlx5_hca_vport_context *rep;
int err;
rep = kzalloc(sizeof(*rep), GFP_KERNEL);
if (!rep)
return -ENOMEM;
err = mlx5_query_hca_vport_context(dev, 0, 1, 0, rep);
if (!err)
*node_guid = rep->node_guid;
kfree(rep);
return err;
}
EXPORT_SYMBOL_GPL(mlx5_query_hca_vport_node_guid);
......@@ -99,6 +99,12 @@ __mlx5_mask(typ, fld))
#define MLX5_GET64(typ, p, fld) be64_to_cpu(*((__be64 *)(p) + __mlx5_64_off(typ, fld)))
#define MLX5_GET64_PR(typ, p, fld) ({ \
u64 ___t = MLX5_GET64(typ, p, fld); \
pr_debug(#fld " = 0x%llx\n", ___t); \
___t; \
})
enum {
MLX5_MAX_COMMANDS = 32,
MLX5_CMD_DATA_BLOCK_SIZE = 512,
......@@ -1172,4 +1178,11 @@ enum {
MLX5_CMD_STAT_BAD_SIZE_OUTS_CQES_ERR = 0x40,
};
static inline u16 mlx5_to_sw_pkey_sz(int pkey_sz)
{
if (pkey_sz > MLX5_MAX_LOG_PKEY_TABLE)
return 0;
return MLX5_MIN_PKEY_TABLE_SIZE << pkey_sz;
}
#endif /* MLX5_DEVICE_H */
......@@ -107,6 +107,7 @@ enum {
MLX5_REG_PUDE = 0x5009,
MLX5_REG_PMPE = 0x5010,
MLX5_REG_PELC = 0x500e,
MLX5_REG_PVLC = 0x500f,
MLX5_REG_PMLP = 0, /* TBD */
MLX5_REG_NODE_DESC = 0x6001,
MLX5_REG_HOST_ENDIANNESS = 0x7004,
......@@ -339,6 +340,8 @@ struct mlx5_core_mr {
enum mlx5_res_type {
MLX5_RES_QP,
MLX5_RES_SRQ,
MLX5_RES_XSRQ,
};
struct mlx5_core_rsc_common {
......@@ -348,6 +351,7 @@ struct mlx5_core_rsc_common {
};
struct mlx5_core_srq {
struct mlx5_core_rsc_common common; /* must be first */
u32 srqn;
int max;
int max_gs;
......@@ -550,6 +554,41 @@ struct mlx5_pas {
u8 log_sz;
};
enum port_state_policy {
MLX5_AAA_000
};
enum phy_port_state {
MLX5_AAA_111
};
struct mlx5_hca_vport_context {
u32 field_select;
bool sm_virt_aware;
bool has_smi;
bool has_raw;
enum port_state_policy policy;
enum phy_port_state phys_state;
enum ib_port_state vport_state;
u8 port_physical_state;
u64 sys_image_guid;
u64 port_guid;
u64 node_guid;
u32 cap_mask1;
u32 cap_mask1_perm;
u32 cap_mask2;
u32 cap_mask2_perm;
u16 lid;
u8 init_type_reply; /* bitmask: see ib spec 14.2.5.6 InitTypeReply */
u8 lmc;
u8 subnet_timeout;
u16 sm_lid;
u8 sm_sl;
u16 qkey_violation_counter;
u16 pkey_violation_counter;
bool grh_required;
};
static inline void *mlx5_buf_offset(struct mlx5_buf *buf, int offset)
{
return buf->direct.buf + offset;
......@@ -640,7 +679,8 @@ struct mlx5_cmd_mailbox *mlx5_alloc_cmd_mailbox_chain(struct mlx5_core_dev *dev,
void mlx5_free_cmd_mailbox_chain(struct mlx5_core_dev *dev,
struct mlx5_cmd_mailbox *head);
int mlx5_core_create_srq(struct mlx5_core_dev *dev, struct mlx5_core_srq *srq,
struct mlx5_create_srq_mbox_in *in, int inlen);
struct mlx5_create_srq_mbox_in *in, int inlen,
int is_xrc);
int mlx5_core_destroy_srq(struct mlx5_core_dev *dev, struct mlx5_core_srq *srq);
int mlx5_core_query_srq(struct mlx5_core_dev *dev, struct mlx5_core_srq *srq,
struct mlx5_query_srq_mbox_out *out);
......@@ -700,11 +740,16 @@ int mlx5_core_access_reg(struct mlx5_core_dev *dev, void *data_in,
int mlx5_set_port_caps(struct mlx5_core_dev *dev, u8 port_num, u32 caps);
int mlx5_query_port_ptys(struct mlx5_core_dev *dev, u32 *ptys,
int ptys_size, int proto_mask);
int ptys_size, int proto_mask, u8 local_port);
int mlx5_query_port_proto_cap(struct mlx5_core_dev *dev,
u32 *proto_cap, int proto_mask);
int mlx5_query_port_proto_admin(struct mlx5_core_dev *dev,
u32 *proto_admin, int proto_mask);
int mlx5_query_port_link_width_oper(struct mlx5_core_dev *dev,
u8 *link_width_oper, u8 local_port);
int mlx5_query_port_proto_oper(struct mlx5_core_dev *dev,
u8 *proto_oper, int proto_mask,
u8 local_port);
int mlx5_set_port_proto(struct mlx5_core_dev *dev, u32 proto_admin,
int proto_mask);
int mlx5_set_port_status(struct mlx5_core_dev *dev,
......@@ -712,8 +757,12 @@ int mlx5_set_port_status(struct mlx5_core_dev *dev,
int mlx5_query_port_status(struct mlx5_core_dev *dev, u8 *status);
int mlx5_set_port_mtu(struct mlx5_core_dev *dev, int mtu);
int mlx5_query_port_max_mtu(struct mlx5_core_dev *dev, int *max_mtu);
int mlx5_query_port_oper_mtu(struct mlx5_core_dev *dev, int *oper_mtu);
int mlx5_query_port_max_mtu(struct mlx5_core_dev *dev, int *max_mtu,
u8 local_port);
int mlx5_query_port_oper_mtu(struct mlx5_core_dev *dev, int *oper_mtu,
u8 local_port);
int mlx5_query_port_vl_hw_cap(struct mlx5_core_dev *dev,
u8 *vl_hw_cap, u8 local_port);
int mlx5_debug_eq_add(struct mlx5_core_dev *dev, struct mlx5_eq *eq);
void mlx5_debug_eq_remove(struct mlx5_core_dev *dev, struct mlx5_eq *eq);
......@@ -778,6 +827,7 @@ struct mlx5_interface {
void *mlx5_get_protocol_dev(struct mlx5_core_dev *mdev, int protocol);
int mlx5_register_interface(struct mlx5_interface *intf);
void mlx5_unregister_interface(struct mlx5_interface *intf);
int mlx5_core_query_vendor_id(struct mlx5_core_dev *mdev, u32 *vendor_id);
struct mlx5_profile {
u64 mask;
......@@ -788,4 +838,14 @@ struct mlx5_profile {
} mr_cache[MAX_MR_CACHE_ENTRIES];
};
static inline int mlx5_get_gid_table_len(u16 param)
{
if (param > 4) {
pr_warn("gid table length is zero\n");
return 0;
}
return 8 * (1 << param);
}
#endif /* MLX5_DRIVER_H */
......@@ -2022,12 +2022,9 @@ struct mlx5_ifc_srqc_bits {
u8 reserved_9[0x40];
u8 db_record_addr_h[0x20];
u8 db_record_addr_l[0x1e];
u8 reserved_10[0x2];
u8 dbr_addr[0x40];
u8 reserved_11[0x80];
u8 reserved_10[0x80];
};
enum {
......@@ -2224,12 +2221,15 @@ struct mlx5_ifc_hca_vport_context_bits {
u8 has_smi[0x1];
u8 has_raw[0x1];
u8 grh_required[0x1];
u8 reserved_1[0x10];
u8 port_state_policy[0x4];
u8 phy_port_state[0x4];
u8 reserved_1[0xc];
u8 port_physical_state[0x4];
u8 vport_state_policy[0x4];
u8 port_state[0x4];
u8 vport_state[0x4];
u8 reserved_2[0x60];
u8 reserved_2[0x20];
u8 system_image_guid[0x40];
u8 port_guid[0x40];
......@@ -2470,9 +2470,12 @@ union mlx5_ifc_cong_control_roce_ecn_auto_bits {
};
struct mlx5_ifc_query_adapter_param_block_bits {
u8 reserved_0[0xe0];
u8 reserved_0[0xc0];
u8 reserved_1[0x10];
u8 reserved_1[0x8];
u8 ieee_vendor_id[0x18];
u8 reserved_2[0x10];
u8 vsd_vendor_id[0x10];
u8 vsd[208][0x8];
......@@ -3493,7 +3496,8 @@ struct mlx5_ifc_query_hca_vport_pkey_in_bits {
u8 op_mod[0x10];
u8 other_vport[0x1];
u8 reserved_2[0xf];
u8 reserved_2[0xb];
u8 port_num[0x4];
u8 vport_number[0x10];
u8 reserved_3[0x10];
......@@ -3522,7 +3526,8 @@ struct mlx5_ifc_query_hca_vport_gid_in_bits {
u8 op_mod[0x10];
u8 other_vport[0x1];
u8 reserved_2[0xf];
u8 reserved_2[0xb];
u8 port_num[0x4];
u8 vport_number[0x10];
u8 reserved_3[0x10];
......@@ -3548,7 +3553,8 @@ struct mlx5_ifc_query_hca_vport_context_in_bits {
u8 op_mod[0x10];
u8 other_vport[0x1];
u8 reserved_2[0xf];
u8 reserved_2[0xb];
u8 port_num[0x4];
u8 vport_number[0x10];
u8 reserved_3[0x20];
......@@ -4167,6 +4173,13 @@ struct mlx5_ifc_modify_rmp_out_bits {
u8 reserved_1[0x40];
};
struct mlx5_ifc_rmp_bitmask_bits {
u8 reserved[0x20];
u8 reserved1[0x1f];
u8 lwm[0x1];
};
struct mlx5_ifc_modify_rmp_in_bits {
u8 opcode[0x10];
u8 reserved_0[0x10];
......@@ -4180,7 +4193,7 @@ struct mlx5_ifc_modify_rmp_in_bits {
u8 reserved_3[0x20];
u8 modify_bitmask[0x40];
struct mlx5_ifc_rmp_bitmask_bits bitmask;
u8 reserved_4[0x40];
......@@ -4239,7 +4252,8 @@ struct mlx5_ifc_modify_hca_vport_context_in_bits {
u8 op_mod[0x10];
u8 other_vport[0x1];
u8 reserved_2[0xf];
u8 reserved_2[0xb];
u8 port_num[0x4];
u8 vport_number[0x10];
u8 reserved_3[0x20];
......
......@@ -36,6 +36,20 @@
#include <linux/mlx5/driver.h>
u8 mlx5_query_vport_state(struct mlx5_core_dev *mdev, u8 opmod);
void mlx5_query_vport_mac_address(struct mlx5_core_dev *mdev, u8 *addr);
void mlx5_query_nic_vport_mac_address(struct mlx5_core_dev *mdev, u8 *addr);
int mlx5_query_hca_vport_gid(struct mlx5_core_dev *dev, u8 other_vport,
u8 port_num, u16 vf_num, u16 gid_index,
union ib_gid *gid);
int mlx5_query_hca_vport_pkey(struct mlx5_core_dev *dev, u8 other_vport,
u8 port_num, u16 vf_num, u16 pkey_index,
u16 *pkey);
int mlx5_query_hca_vport_context(struct mlx5_core_dev *dev,
u8 other_vport, u8 port_num,
u16 vf_num,
struct mlx5_hca_vport_context *rep);
int mlx5_query_hca_vport_system_image_guid(struct mlx5_core_dev *dev,
__be64 *sys_image_guid);
int mlx5_query_hca_vport_node_guid(struct mlx5_core_dev *dev,
u64 *node_guid);
#endif /* __MLX5_VPORT_H__ */
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