From patchwork Thu Jun 10 18:59:14 2010 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Yevgeny Petrilin X-Patchwork-Id: 105426 Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by demeter.kernel.org (8.14.3/8.14.3) with ESMTP id o5AIxDup014770 for ; Thu, 10 Jun 2010 18:59:19 GMT Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1759504Ab0FJS7S (ORCPT ); Thu, 10 Jun 2010 14:59:18 -0400 Received: from mail.mellanox.co.il ([194.90.237.43]:51246 "EHLO mellanox.co.il" rhost-flags-OK-OK-OK-FAIL) by vger.kernel.org with ESMTP id S1759500Ab0FJS7S (ORCPT ); Thu, 10 Jun 2010 14:59:18 -0400 Received: from Internal Mail-Server by MTLPINE1 (envelope-from yevgenyp@mellanox.co.il) with SMTP; 10 Jun 2010 22:00:06 +0300 Received: from vnc8.lab.mtl.com ([10.4.45.8]) by mtlexch01.mtl.com with Microsoft SMTPSVC(6.0.3790.3959); Thu, 10 Jun 2010 21:59:14 +0300 Message-ID: <4C113602.4010404@mellanox.co.il> Date: Thu, 10 Jun 2010 21:59:14 +0300 From: Yevgeny Petrilin User-Agent: Mozilla/5.0 (X11; U; Linux i686 (x86_64); en-US; rv:1.9.1.9) Gecko/20100317 Thunderbird/3.0.4 MIME-Version: 1.0 To: Roland Dreier CC: linux-rdma@vger.kernel.org Subject: [PATCH 03/19 V4] mlx4_core: add WRITE_MTT support X-OriginalArrivalTime: 10 Jun 2010 18:59:14.0993 (UTC) FILETIME=[05463210:01CB08CF] X-TM-AS-Product-Ver: SMEX-8.0.0.1181-6.000.1038-17438.001 X-TM-AS-Result: No--8.191700-8.000000-31 X-TM-AS-User-Approved-Sender: No X-TM-AS-User-Blocked-Sender: No Sender: linux-rdma-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-rdma@vger.kernel.org X-Greylist: IP, sender and recipient auto-whitelisted, not delayed by milter-greylist-4.2.3 (demeter.kernel.org [140.211.167.41]); Thu, 10 Jun 2010 18:59:19 +0000 (UTC) diff --git a/drivers/net/mlx4/cmd.c b/drivers/net/mlx4/cmd.c index 672e13b..eac3b21 100644 --- a/drivers/net/mlx4/cmd.c +++ b/drivers/net/mlx4/cmd.c @@ -37,8 +37,6 @@ #include #include -#include - #include #include "mlx4.h" @@ -498,6 +496,14 @@ static struct mlx4_cmd_info { .wrapper = NULL }, { + .opcode = MLX4_CMD_WRITE_MTT, + .has_inbox = true, + .has_outbox = false, + .out_is_imm = false, + .verify = NULL, /* need verifier */ + .wrapper = mlx4_WRITE_MTT_wrapper + }, + { .opcode = MLX4_CMD_SYNC_TPT, .has_inbox = true, .has_outbox = false, diff --git a/drivers/net/mlx4/mlx4.h b/drivers/net/mlx4/mlx4.h index fac5d6e..71b191e 100644 --- a/drivers/net/mlx4/mlx4.h +++ b/drivers/net/mlx4/mlx4.h @@ -46,6 +46,7 @@ #include #include #include +#include #define DRV_NAME "mlx4_core" #define PFX DRV_NAME ": " @@ -420,6 +421,10 @@ void mlx4_cleanup_qp_table(struct mlx4_dev *dev); void mlx4_cleanup_srq_table(struct mlx4_dev *dev); void mlx4_cleanup_mcg_table(struct mlx4_dev *dev); +int mlx4_WRITE_MTT_wrapper(struct mlx4_dev *dev, int slave, struct mlx4_vhcr *vhcr, + struct mlx4_cmd_mailbox *inbox, + struct mlx4_cmd_mailbox *outbox); + void mlx4_start_catas_poll(struct mlx4_dev *dev); void mlx4_stop_catas_poll(struct mlx4_dev *dev); void mlx4_catas_init(void); diff --git a/drivers/net/mlx4/mr.c b/drivers/net/mlx4/mr.c index 3dc69be..67c0539 100644 --- a/drivers/net/mlx4/mr.c +++ b/drivers/net/mlx4/mr.c @@ -263,6 +263,35 @@ static int mlx4_HW2SW_MPT(struct mlx4_dev *dev, struct mlx4_cmd_mailbox *mailbox !mailbox, MLX4_CMD_HW2SW_MPT, MLX4_CMD_TIME_CLASS_B); } +int mlx4_WRITE_MTT_wrapper(struct mlx4_dev *dev, int slave, struct mlx4_vhcr *vhcr, + struct mlx4_cmd_mailbox *inbox, + struct mlx4_cmd_mailbox *outbox) +{ + struct mlx4_mtt mtt; + u64 *page_list = inbox->buf; + int i; + + /* Call the SW implementation of write_mtt: + * - Prepare a dummy mtt struct + * - Translate inbox contents to simple addresses in host endianess */ + mtt.first_seg = 0; + mtt.order = 0; + mtt.page_shift = 0; + for (i = 0; i < vhcr->in_modifier; ++i) + page_list[i + 2] = be64_to_cpu(page_list[i + 2]) & ~1ULL; + vhcr->errno = mlx4_write_mtt(dev, &mtt, be64_to_cpu(page_list[0]), + vhcr->in_modifier, + page_list + 2); + return 0; +} + +static int mlx4_WRITE_MTT(struct mlx4_dev *dev, struct mlx4_cmd_mailbox *mailbox, + int num_entries) +{ + return mlx4_cmd(dev, mailbox->dma, num_entries, 0, MLX4_CMD_WRITE_MTT, + MLX4_CMD_TIME_CLASS_A); +} + int mlx4_mr_alloc(struct mlx4_dev *dev, u32 pd, u64 iova, u64 size, u32 access, int npages, int page_shift, struct mlx4_mr *mr) { @@ -414,24 +443,50 @@ static int mlx4_write_mtt_chunk(struct mlx4_dev *dev, struct mlx4_mtt *mtt, int mlx4_write_mtt(struct mlx4_dev *dev, struct mlx4_mtt *mtt, int start_index, int npages, u64 *page_list) { + struct mlx4_cmd_mailbox *mailbox = NULL; int chunk; - int err; + int err = 0; + __be64 *inbox = NULL; + int i; if (mtt->order < 0) return -EINVAL; + if (mlx4_is_slave(dev)) { + mailbox = mlx4_alloc_cmd_mailbox(dev); + if (IS_ERR(mailbox)) + return PTR_ERR(mailbox); + inbox = mailbox->buf; + } + while (npages > 0) { - chunk = min_t(int, PAGE_SIZE / sizeof(u64), npages); - err = mlx4_write_mtt_chunk(dev, mtt, start_index, chunk, page_list); + if (mlx4_is_slave(dev)) { + int s = mtt->first_seg * dev->caps.mtts_per_seg + start_index; + chunk = min_t(int, MLX4_MAILBOX_SIZE / sizeof(u64) - dev->caps.mtts_per_seg, npages); + if (s / (PAGE_SIZE / sizeof (u64)) != + (s + chunk - 1) / (PAGE_SIZE / sizeof (u64))) + chunk = PAGE_SIZE / sizeof (u64) - (s % (PAGE_SIZE / sizeof (u64))); + + inbox[0] = cpu_to_be64(mtt->first_seg * dev->caps.mtts_per_seg + start_index); + inbox[1] = 0; + for (i = 0; i < chunk; ++i) + inbox[i + 2] = cpu_to_be64(page_list[i] | MLX4_MTT_FLAG_PRESENT); + err = mlx4_WRITE_MTT(dev, mailbox, chunk); + } else { + chunk = min_t(int, PAGE_SIZE / sizeof(u64), npages); + err = mlx4_write_mtt_chunk(dev, mtt, start_index, chunk, page_list); + } if (err) - return err; + goto out; npages -= chunk; start_index += chunk; page_list += chunk; } - - return 0; +out: + if (mlx4_is_slave(dev)) + mlx4_free_cmd_mailbox(dev, mailbox); + return err; } EXPORT_SYMBOL_GPL(mlx4_write_mtt);