From patchwork Fri Nov 6 03:08:56 2009 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Yevgeny Petrilin X-Patchwork-Id: 57955 Received: from vger.kernel.org (vger.kernel.org [209.132.176.167]) by demeter.kernel.org (8.14.2/8.14.2) with ESMTP id nA60BSbR027464 for ; Fri, 6 Nov 2009 00:11:28 GMT Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1759156AbZKFALV (ORCPT ); Thu, 5 Nov 2009 19:11:21 -0500 Received: (majordomo@vger.kernel.org) by vger.kernel.org id S1759161AbZKFALV (ORCPT ); Thu, 5 Nov 2009 19:11:21 -0500 Received: from mail.mellanox.co.il ([194.90.237.43]:43138 "EHLO mellanox.co.il" rhost-flags-OK-OK-OK-FAIL) by vger.kernel.org with ESMTP id S1759156AbZKFALU (ORCPT ); Thu, 5 Nov 2009 19:11:20 -0500 Received: from Internal Mail-Server by MTLPINE1 (envelope-from yevgenyp@mellanox.co.il) with SMTP; 6 Nov 2009 02:17:12 +0200 Received: from [10.4.12.75] ([10.4.12.75]) by mtlexch01.mtl.com with Microsoft SMTPSVC(6.0.3790.3959); Fri, 6 Nov 2009 02:11:24 +0200 Message-ID: <4AF39348.3020208@mellanox.co.il> Date: Fri, 06 Nov 2009 05:08:56 +0200 From: Yevgeny Petrilin User-Agent: Thunderbird 2.0.0.23 (X11/20090812) MIME-Version: 1.0 To: rdreier@cisco.com CC: linux-rdma@vger.kernel.org, netdev@vger.kernel.org, liranl@mellanox.co.il, tziporet@mellanox.co.il, yevgenyp@mellanox.co.il Subject: [PATCH 10/25 v2] mlx4_core: track slave special qps X-OriginalArrivalTime: 06 Nov 2009 00:11:24.0673 (UTC) FILETIME=[AD64CF10:01CA5E75] Sender: linux-rdma-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-rdma@vger.kernel.org diff --git a/drivers/net/mlx4/cmd.c b/drivers/net/mlx4/cmd.c index 634e5c9..485e976 100644 --- a/drivers/net/mlx4/cmd.c +++ b/drivers/net/mlx4/cmd.c @@ -539,6 +539,14 @@ static struct mlx4_cmd_info { .verify = NULL, .wrapper = NULL }, + { + .opcode = MLX4_CMD_GET_SLAVE_SQP, + .has_inbox = false, + .has_outbox = true, + .out_is_imm = false, + .verify = NULL, + .wrapper = mlx4_GET_SLAVE_SQP_wrapper + }, { .opcode = MLX4_CMD_INIT_PORT, @@ -855,6 +863,14 @@ static struct mlx4_cmd_info { .wrapper = NULL }, { + .opcode = MLX4_CMD_CONF_SPECIAL_QP, + .has_inbox = false, + .has_outbox = false, + .out_is_imm = false, + .verify = NULL, + .wrapper = mlx4_CONF_SPECIAL_QP_wrapper + }, + { .opcode = MLX4_CMD_MAD_IFC, .has_inbox = true, .has_outbox = true, diff --git a/drivers/net/mlx4/eq.c b/drivers/net/mlx4/eq.c index 1e8b62d..a27e1c4 100644 --- a/drivers/net/mlx4/eq.c +++ b/drivers/net/mlx4/eq.c @@ -358,6 +358,17 @@ static int mlx4_eq_int(struct mlx4_dev *dev, struct mlx4_eq *eq) return eqes_found; } +static void mlx4_update_sqp(struct mlx4_dev *dev) +{ + if (!dev->caps.sqp_demux) { + mlx4_warn(dev, "unexpected update_sqp event\n"); + return; + } + if (mlx4_GET_SLAVE_SQP(dev, mlx4_priv(dev)->mfunc.demux_sqp, + dev->caps.sqp_demux)) + mlx4_warn(dev, "couldn't update sqp\n"); +} + void mlx4_slave_async_eq_poll(struct work_struct *work) { struct delayed_work *delay = container_of(work, struct delayed_work, work); @@ -402,6 +413,10 @@ void mlx4_slave_async_eq_poll(struct work_struct *work) mlx4_warn(dev, "slave async EQ overrun\n"); break; + case MLX4_EVENT_TYPE_SQP_UPDATE: + mlx4_update_sqp(dev); + break; + default: mlx4_warn(dev, "Unhandled event:%02x\n", eqe.type); } diff --git a/drivers/net/mlx4/mlx4.h b/drivers/net/mlx4/mlx4.h index f680940..e2d80c6 100644 --- a/drivers/net/mlx4/mlx4.h +++ b/drivers/net/mlx4/mlx4.h @@ -111,6 +111,7 @@ enum mlx4_alloc_mode { }; enum { + MLX4_MFUNC_MAX = 64, MLX4_MFUNC_MAX_EQES = 8, MLX4_MFUNC_EQE_MASK = (MLX4_MFUNC_MAX_EQES - 1) }; @@ -219,6 +220,7 @@ struct mlx4_slave_state { struct mlx4_slave_eqe eq[MLX4_MFUNC_MAX_EQES]; u16 eq_pi; u16 eq_ci; + int sqp_start; spinlock_t lock; }; @@ -246,6 +248,7 @@ struct mlx4_mfunc { dma_addr_t vhcr_dma; struct mlx4_mfunc_master_ctx master; + u32 demux_sqp[MLX4_MFUNC_MAX]; }; struct mlx4_cmd { @@ -531,6 +534,14 @@ int mlx4_QUERY_PORT_wrapper(struct mlx4_dev *dev, int slave, struct mlx4_vhcr *v struct mlx4_cmd_mailbox *outbox); int mlx4_get_port_ib_caps(struct mlx4_dev *dev, u8 port, __be32 *caps); +int mlx4_CONF_SPECIAL_QP_wrapper(struct mlx4_dev *dev, int slave, struct mlx4_vhcr *vhcr, + struct mlx4_cmd_mailbox *inbox, + struct mlx4_cmd_mailbox *outbox); +int mlx4_GET_SLAVE_SQP(struct mlx4_dev *dev, u32 *sqp, int num); +int mlx4_GET_SLAVE_SQP_wrapper(struct mlx4_dev *dev, int slave, struct mlx4_vhcr *vhcr, + struct mlx4_cmd_mailbox *inbox, + struct mlx4_cmd_mailbox *outbox); + int mlx4_MCAST_wrapper(struct mlx4_dev *dev, int slave, struct mlx4_vhcr *vhcr, struct mlx4_cmd_mailbox *inbox, struct mlx4_cmd_mailbox *outbox); diff --git a/drivers/net/mlx4/qp.c b/drivers/net/mlx4/qp.c index 065c7fc..99b9ded 100644 --- a/drivers/net/mlx4/qp.c +++ b/drivers/net/mlx4/qp.c @@ -145,6 +145,54 @@ int mlx4_qp_modify(struct mlx4_dev *dev, struct mlx4_mtt *mtt, } EXPORT_SYMBOL_GPL(mlx4_qp_modify); +u32 mlx4_get_slave_sqp(struct mlx4_dev *dev, int slave) +{ + if (mlx4_is_master(dev) && slave < dev->num_slaves) { + return mlx4_priv(dev)->mfunc.master.slave_state[slave].sqp_start; + } + if (mlx4_is_slave(dev) && slave < dev->caps.sqp_demux) { + return mlx4_priv(dev)->mfunc.demux_sqp[slave]; + } + return 0; +} +EXPORT_SYMBOL_GPL(mlx4_get_slave_sqp); + +int mlx4_GET_SLAVE_SQP_wrapper(struct mlx4_dev *dev, int slave, struct mlx4_vhcr *vhcr, + struct mlx4_cmd_mailbox *inbox, + struct mlx4_cmd_mailbox *outbox) +{ + u32 *slave_sqp = outbox->buf; + int i; + + /* CX1: special qp demultiplexing is done by slave0 */ + if (slave) { + mlx4_warn(dev, "Denying slave_sqp request from slave:%d\n", slave); + return -EINVAL; + } + for (i = 0; i < 64; i++) + slave_sqp[i] = mlx4_get_slave_sqp(dev, i); + return 0; +} + +int mlx4_GET_SLAVE_SQP(struct mlx4_dev *dev, u32 *sqp, int num) +{ + struct mlx4_cmd_mailbox *mailbox; + int err; + + mailbox = mlx4_alloc_cmd_mailbox(dev); + if (IS_ERR(mailbox)) + return PTR_ERR(mailbox); + + err = mlx4_cmd_box(dev, 0, mailbox->dma, 0, 0, MLX4_CMD_GET_SLAVE_SQP, + MLX4_CMD_TIME_CLASS_A); + if (!err) + memcpy(sqp, mailbox->buf, sizeof (u32) * num); + + mlx4_free_cmd_mailbox(dev, mailbox); + return err; +} +EXPORT_SYMBOL_GPL(mlx4_GET_SLAVE_SQP); + int mlx4_qp_reserve_range(struct mlx4_dev *dev, int cnt, int align, int *base) { struct mlx4_priv *priv = mlx4_priv(dev); @@ -331,6 +379,25 @@ static int mlx4_CONF_SPECIAL_QP(struct mlx4_dev *dev, u32 base_qpn) MLX4_CMD_TIME_CLASS_B); } +int mlx4_CONF_SPECIAL_QP_wrapper(struct mlx4_dev *dev, int slave, struct mlx4_vhcr *vhcr, + struct mlx4_cmd_mailbox *inbox, + struct mlx4_cmd_mailbox *outbox) +{ + struct mlx4_priv *priv = mlx4_priv(dev); + int ret; + + priv->mfunc.master.slave_state[slave].sqp_start = vhcr->in_modifier & 0xffffff; + if (!slave) { + /* CX1: slave0 owns real special QPs */ + ret = mlx4_CONF_SPECIAL_QP(dev, priv->mfunc.master.slave_state[slave].sqp_start); + if (ret) + return ret; + } + /* Notify slave0 that an SQP change occured */ + mlx4_slave_event(dev, 0, MLX4_EVENT_TYPE_SQP_UPDATE, 0, 0); + return 0; +} + int mlx4_init_qp_table(struct mlx4_dev *dev) { struct mlx4_qp_table *qp_table = &mlx4_priv(dev)->qp_table; diff --git a/include/linux/mlx4/cmd.h b/include/linux/mlx4/cmd.h index 04255cd..8444b89 100644 --- a/include/linux/mlx4/cmd.h +++ b/include/linux/mlx4/cmd.h @@ -129,6 +129,7 @@ enum { MLX4_CMD_FREE_RES = 0x51, MLX4_CMD_GET_EVENT = 0x52, MLX4_CMD_MCAST_ATTACH = 0x54, + MLX4_CMD_GET_SLAVE_SQP = 0x55, /* debug commands */ MLX4_CMD_QUERY_DEBUG_MSG = 0x2a, diff --git a/include/linux/mlx4/device.h b/include/linux/mlx4/device.h index 9735f40..b20c8d8 100644 --- a/include/linux/mlx4/device.h +++ b/include/linux/mlx4/device.h @@ -99,6 +99,7 @@ enum mlx4_event { MLX4_EVENT_TYPE_EQ_OVERFLOW = 0x0f, MLX4_EVENT_TYPE_ECC_DETECT = 0x0e, MLX4_EVENT_TYPE_CMD = 0x0a, + MLX4_EVENT_TYPE_SQP_UPDATE = 0xfe, MLX4_EVENT_TYPE_NONE = 0xff, }; @@ -242,6 +243,7 @@ struct mlx4_caps { int log_num_prios; enum mlx4_port_type port_type[MLX4_MAX_PORTS + 1]; u8 supported_type[MLX4_MAX_PORTS + 1]; + u8 sqp_demux; u32 port_mask; enum mlx4_port_type possible_type[MLX4_MAX_PORTS + 1]; }; @@ -470,6 +472,7 @@ void mlx4_qp_release_range(struct mlx4_dev *dev, int base_qpn, int cnt); int mlx4_qp_alloc(struct mlx4_dev *dev, int qpn, struct mlx4_qp *qp); void mlx4_qp_free(struct mlx4_dev *dev, struct mlx4_qp *qp); +u32 mlx4_get_slave_sqp(struct mlx4_dev *dev, int vf); int mlx4_srq_alloc(struct mlx4_dev *dev, u32 pdn, struct mlx4_mtt *mtt, u64 db_rec, struct mlx4_srq *srq);