X-Git-Url: http://git.onelab.eu/?a=blobdiff_plain;f=drivers%2Finfiniband%2Fhw%2Fmthca%2Fmthca_cmd.c;fp=drivers%2Finfiniband%2Fhw%2Fmthca%2Fmthca_cmd.c;h=2825615ce81c3cd440247a500eedc7111e36871a;hb=64ba3f394c830ec48a1c31b53dcae312c56f1604;hp=deabc14b4ea4c3ba2edb1a74dc808184d3171982;hpb=be1e6109ac94a859551f8e1774eb9a8469fe055c;p=linux-2.6.git diff --git a/drivers/infiniband/hw/mthca/mthca_cmd.c b/drivers/infiniband/hw/mthca/mthca_cmd.c index deabc14b4..2825615ce 100644 --- a/drivers/infiniband/hw/mthca/mthca_cmd.c +++ b/drivers/infiniband/hw/mthca/mthca_cmd.c @@ -1,7 +1,7 @@ /* * Copyright (c) 2004, 2005 Topspin Communications. All rights reserved. * Copyright (c) 2005 Mellanox Technologies. All rights reserved. - * Copyright (c) 2005, 2006 Cisco Systems. All rights reserved. + * Copyright (c) 2005 Cisco Systems. All rights reserved. * * This software is available to you under a choice of one of two * licenses. You may choose to be licensed under the terms of the GNU @@ -174,6 +174,7 @@ enum { struct mthca_cmd_context { struct completion done; + struct timer_list timer; int result; int next; u64 out_param; @@ -181,58 +182,25 @@ struct mthca_cmd_context { u8 status; }; -static int fw_cmd_doorbell = 0; -module_param(fw_cmd_doorbell, int, 0644); -MODULE_PARM_DESC(fw_cmd_doorbell, "post FW commands through doorbell page if nonzero " - "(and supported by FW)"); - static inline int go_bit(struct mthca_dev *dev) { return readl(dev->hcr + HCR_STATUS_OFFSET) & swab32(1 << HCR_GO_BIT); } -static void mthca_cmd_post_dbell(struct mthca_dev *dev, - u64 in_param, - u64 out_param, - u32 in_modifier, - u8 op_modifier, - u16 op, - u16 token) +static int mthca_cmd_post(struct mthca_dev *dev, + u64 in_param, + u64 out_param, + u32 in_modifier, + u8 op_modifier, + u16 op, + u16 token, + int event) { - void __iomem *ptr = dev->cmd.dbell_map; - u16 *offs = dev->cmd.dbell_offsets; + int err = 0; - __raw_writel((__force u32) cpu_to_be32(in_param >> 32), ptr + offs[0]); - wmb(); - __raw_writel((__force u32) cpu_to_be32(in_param & 0xfffffffful), ptr + offs[1]); - wmb(); - __raw_writel((__force u32) cpu_to_be32(in_modifier), ptr + offs[2]); - wmb(); - __raw_writel((__force u32) cpu_to_be32(out_param >> 32), ptr + offs[3]); - wmb(); - __raw_writel((__force u32) cpu_to_be32(out_param & 0xfffffffful), ptr + offs[4]); - wmb(); - __raw_writel((__force u32) cpu_to_be32(token << 16), ptr + offs[5]); - wmb(); - __raw_writel((__force u32) cpu_to_be32((1 << HCR_GO_BIT) | - (1 << HCA_E_BIT) | - (op_modifier << HCR_OPMOD_SHIFT) | - op), ptr + offs[6]); - wmb(); - __raw_writel((__force u32) 0, ptr + offs[7]); - wmb(); -} + mutex_lock(&dev->cmd.hcr_mutex); -static int mthca_cmd_post_hcr(struct mthca_dev *dev, - u64 in_param, - u64 out_param, - u32 in_modifier, - u8 op_modifier, - u16 op, - u16 token, - int event) -{ if (event) { unsigned long end = jiffies + GO_BIT_TIMEOUT; @@ -242,8 +210,10 @@ static int mthca_cmd_post_hcr(struct mthca_dev *dev, } } - if (go_bit(dev)) - return -EAGAIN; + if (go_bit(dev)) { + err = -EAGAIN; + goto out; + } /* * We use writel (instead of something like memcpy_toio) @@ -266,29 +236,7 @@ static int mthca_cmd_post_hcr(struct mthca_dev *dev, (op_modifier << HCR_OPMOD_SHIFT) | op), dev->hcr + 6 * 4); - return 0; -} - -static int mthca_cmd_post(struct mthca_dev *dev, - u64 in_param, - u64 out_param, - u32 in_modifier, - u8 op_modifier, - u16 op, - u16 token, - int event) -{ - int err = 0; - - mutex_lock(&dev->cmd.hcr_mutex); - - if (event && dev->cmd.flags & MTHCA_CMD_POST_DOORBELLS && fw_cmd_doorbell) - mthca_cmd_post_dbell(dev, in_param, out_param, in_modifier, - op_modifier, op, token); - else - err = mthca_cmd_post_hcr(dev, in_param, out_param, in_modifier, - op_modifier, op, token, event); - +out: mutex_unlock(&dev->cmd.hcr_mutex); return err; } @@ -327,7 +275,7 @@ static int mthca_cmd_poll(struct mthca_dev *dev, } if (out_is_imm) - *out_param = + *out_param = (u64) be32_to_cpu((__force __be32) __raw_readl(dev->hcr + HCR_OUT_PARAM_OFFSET)) << 32 | (u64) be32_to_cpu((__force __be32) @@ -361,6 +309,15 @@ void mthca_cmd_event(struct mthca_dev *dev, complete(&context->done); } +static void event_timeout(unsigned long context_ptr) +{ + struct mthca_cmd_context *context = + (struct mthca_cmd_context *) context_ptr; + + context->result = -EBUSY; + complete(&context->done); +} + static int mthca_cmd_wait(struct mthca_dev *dev, u64 in_param, u64 *out_param, @@ -391,10 +348,11 @@ static int mthca_cmd_wait(struct mthca_dev *dev, if (err) goto out; - if (!wait_for_completion_timeout(&context->done, timeout)) { - err = -EBUSY; - goto out; - } + context->timer.expires = jiffies + timeout; + add_timer(&context->timer); + + wait_for_completion(&context->done); + del_timer_sync(&context->timer); err = context->result; if (err) @@ -428,7 +386,7 @@ static int mthca_cmd_box(struct mthca_dev *dev, unsigned long timeout, u8 *status) { - if (dev->cmd.flags & MTHCA_CMD_USE_EVENTS) + if (dev->cmd.use_events) return mthca_cmd_wait(dev, in_param, &out_param, 0, in_modifier, op_modifier, op, timeout, status); @@ -465,7 +423,7 @@ static int mthca_cmd_imm(struct mthca_dev *dev, unsigned long timeout, u8 *status) { - if (dev->cmd.flags & MTHCA_CMD_USE_EVENTS) + if (dev->cmd.use_events) return mthca_cmd_wait(dev, in_param, out_param, 1, in_modifier, op_modifier, op, timeout, status); @@ -479,7 +437,7 @@ int mthca_cmd_init(struct mthca_dev *dev) { mutex_init(&dev->cmd.hcr_mutex); sema_init(&dev->cmd.poll_sem, 1); - dev->cmd.flags = 0; + dev->cmd.use_events = 0; dev->hcr = ioremap(pci_resource_start(dev->pdev, 0) + MTHCA_HCR_BASE, MTHCA_HCR_SIZE); @@ -503,8 +461,6 @@ void mthca_cmd_cleanup(struct mthca_dev *dev) { pci_pool_destroy(dev->cmd.pool); iounmap(dev->hcr); - if (dev->cmd.flags & MTHCA_CMD_POST_DOORBELLS) - iounmap(dev->cmd.dbell_map); } /* @@ -524,6 +480,10 @@ int mthca_cmd_use_events(struct mthca_dev *dev) for (i = 0; i < dev->cmd.max_cmds; ++i) { dev->cmd.context[i].token = i; dev->cmd.context[i].next = i + 1; + init_timer(&dev->cmd.context[i].timer); + dev->cmd.context[i].timer.data = + (unsigned long) &dev->cmd.context[i]; + dev->cmd.context[i].timer.function = event_timeout; } dev->cmd.context[dev->cmd.max_cmds - 1].next = -1; @@ -538,8 +498,7 @@ int mthca_cmd_use_events(struct mthca_dev *dev) ; /* nothing */ --dev->cmd.token_mask; - dev->cmd.flags |= MTHCA_CMD_USE_EVENTS; - + dev->cmd.use_events = 1; down(&dev->cmd.poll_sem); return 0; @@ -552,7 +511,7 @@ void mthca_cmd_use_polling(struct mthca_dev *dev) { int i; - dev->cmd.flags &= ~MTHCA_CMD_USE_EVENTS; + dev->cmd.use_events = 0; for (i = 0; i < dev->cmd.max_cmds; ++i) down(&dev->cmd.event_sem); @@ -637,9 +596,8 @@ static int mthca_map_cmd(struct mthca_dev *dev, u16 op, struct mthca_icm *icm, * address or size and use that as our log2 size. */ lg = ffs(mthca_icm_addr(&iter) | mthca_icm_size(&iter)) - 1; - if (lg < MTHCA_ICM_PAGE_SHIFT) { - mthca_warn(dev, "Got FW area not aligned to %d (%llx/%lx).\n", - MTHCA_ICM_PAGE_SIZE, + if (lg < 12) { + mthca_warn(dev, "Got FW area not aligned to 4K (%llx/%lx).\n", (unsigned long long) mthca_icm_addr(&iter), mthca_icm_size(&iter)); err = -EINVAL; @@ -651,9 +609,8 @@ static int mthca_map_cmd(struct mthca_dev *dev, u16 op, struct mthca_icm *icm, virt += 1 << lg; } - pages[nent * 2 + 1] = - cpu_to_be64((mthca_icm_addr(&iter) + (i << lg)) | - (lg - MTHCA_ICM_PAGE_SHIFT)); + pages[nent * 2 + 1] = cpu_to_be64((mthca_icm_addr(&iter) + + (i << lg)) | (lg - 12)); ts += 1 << (lg - 10); ++tc; @@ -704,41 +661,12 @@ int mthca_RUN_FW(struct mthca_dev *dev, u8 *status) return mthca_cmd(dev, 0, 0, 0, CMD_RUN_FW, CMD_TIME_CLASS_A, status); } -static void mthca_setup_cmd_doorbells(struct mthca_dev *dev, u64 base) -{ - unsigned long addr; - u16 max_off = 0; - int i; - - for (i = 0; i < 8; ++i) - max_off = max(max_off, dev->cmd.dbell_offsets[i]); - - if ((base & PAGE_MASK) != ((base + max_off) & PAGE_MASK)) { - mthca_warn(dev, "Firmware doorbell region at 0x%016llx, " - "length 0x%x crosses a page boundary\n", - (unsigned long long) base, max_off); - return; - } - - addr = pci_resource_start(dev->pdev, 2) + - ((pci_resource_len(dev->pdev, 2) - 1) & base); - dev->cmd.dbell_map = ioremap(addr, max_off + sizeof(u32)); - if (!dev->cmd.dbell_map) - return; - - dev->cmd.flags |= MTHCA_CMD_POST_DOORBELLS; - mthca_dbg(dev, "Mapped doorbell page for posting FW commands\n"); -} - int mthca_QUERY_FW(struct mthca_dev *dev, u8 *status) { struct mthca_mailbox *mailbox; u32 *outbox; - u64 base; - u32 tmp; int err = 0; u8 lg; - int i; #define QUERY_FW_OUT_SIZE 0x100 #define QUERY_FW_VER_OFFSET 0x00 @@ -746,10 +674,6 @@ int mthca_QUERY_FW(struct mthca_dev *dev, u8 *status) #define QUERY_FW_ERR_START_OFFSET 0x30 #define QUERY_FW_ERR_SIZE_OFFSET 0x38 -#define QUERY_FW_CMD_DB_EN_OFFSET 0x10 -#define QUERY_FW_CMD_DB_OFFSET 0x50 -#define QUERY_FW_CMD_DB_BASE 0x60 - #define QUERY_FW_START_OFFSET 0x20 #define QUERY_FW_END_OFFSET 0x28 @@ -780,28 +704,14 @@ int mthca_QUERY_FW(struct mthca_dev *dev, u8 *status) MTHCA_GET(lg, outbox, QUERY_FW_MAX_CMD_OFFSET); dev->cmd.max_cmds = 1 << lg; - - mthca_dbg(dev, "FW version %012llx, max commands %d\n", - (unsigned long long) dev->fw_ver, dev->cmd.max_cmds); - MTHCA_GET(dev->catas_err.addr, outbox, QUERY_FW_ERR_START_OFFSET); MTHCA_GET(dev->catas_err.size, outbox, QUERY_FW_ERR_SIZE_OFFSET); + mthca_dbg(dev, "FW version %012llx, max commands %d\n", + (unsigned long long) dev->fw_ver, dev->cmd.max_cmds); mthca_dbg(dev, "Catastrophic error buffer at 0x%llx, size 0x%x\n", (unsigned long long) dev->catas_err.addr, dev->catas_err.size); - MTHCA_GET(tmp, outbox, QUERY_FW_CMD_DB_EN_OFFSET); - if (tmp & 0x1) { - mthca_dbg(dev, "FW supports commands through doorbells\n"); - - MTHCA_GET(base, outbox, QUERY_FW_CMD_DB_BASE); - for (i = 0; i < MTHCA_CMD_NUM_DBELL_DWORDS; ++i) - MTHCA_GET(dev->cmd.dbell_offsets[i], outbox, - QUERY_FW_CMD_DB_OFFSET + (i << 1)); - - mthca_setup_cmd_doorbells(dev, base); - } - if (mthca_is_memfree(dev)) { MTHCA_GET(dev->fw.arbel.fw_pages, outbox, QUERY_FW_SIZE_OFFSET); MTHCA_GET(dev->fw.arbel.clr_int_base, outbox, QUERY_FW_CLR_INT_BASE_OFFSET); @@ -810,12 +720,12 @@ int mthca_QUERY_FW(struct mthca_dev *dev, u8 *status) mthca_dbg(dev, "FW size %d KB\n", dev->fw.arbel.fw_pages << 2); /* - * Round up number of system pages needed in case - * MTHCA_ICM_PAGE_SIZE < PAGE_SIZE. + * Arbel page size is always 4 KB; round up number of + * system pages needed. */ dev->fw.arbel.fw_pages = - ALIGN(dev->fw.arbel.fw_pages, PAGE_SIZE / MTHCA_ICM_PAGE_SIZE) >> - (PAGE_SHIFT - MTHCA_ICM_PAGE_SHIFT); + ALIGN(dev->fw.arbel.fw_pages, PAGE_SIZE >> 12) >> + (PAGE_SHIFT - 12); mthca_dbg(dev, "Clear int @ %llx, EQ arm @ %llx, EQ set CI @ %llx\n", (unsigned long long) dev->fw.arbel.clr_int_base, @@ -951,7 +861,6 @@ int mthca_QUERY_DEV_LIM(struct mthca_dev *dev, u32 *outbox; u8 field; u16 size; - u16 stat_rate; int err; #define QUERY_DEV_LIM_OUT_SIZE 0x100 @@ -982,7 +891,6 @@ int mthca_QUERY_DEV_LIM(struct mthca_dev *dev, #define QUERY_DEV_LIM_MTU_WIDTH_OFFSET 0x36 #define QUERY_DEV_LIM_VL_PORT_OFFSET 0x37 #define QUERY_DEV_LIM_MAX_GID_OFFSET 0x3b -#define QUERY_DEV_LIM_RATE_SUPPORT_OFFSET 0x3c #define QUERY_DEV_LIM_MAX_PKEY_OFFSET 0x3f #define QUERY_DEV_LIM_FLAGS_OFFSET 0x44 #define QUERY_DEV_LIM_RSVD_UAR_OFFSET 0x48 @@ -1074,8 +982,6 @@ int mthca_QUERY_DEV_LIM(struct mthca_dev *dev, dev_lim->num_ports = field & 0xf; MTHCA_GET(field, outbox, QUERY_DEV_LIM_MAX_GID_OFFSET); dev_lim->max_gids = 1 << (field & 0xf); - MTHCA_GET(stat_rate, outbox, QUERY_DEV_LIM_RATE_SUPPORT_OFFSET); - dev_lim->stat_rate_support = stat_rate; MTHCA_GET(field, outbox, QUERY_DEV_LIM_MAX_PKEY_OFFSET); dev_lim->max_pkeys = 1 << (field & 0xf); MTHCA_GET(dev_lim->flags, outbox, QUERY_DEV_LIM_FLAGS_OFFSET); @@ -1267,8 +1173,7 @@ int mthca_INIT_HCA(struct mthca_dev *dev, int err; #define INIT_HCA_IN_SIZE 0x200 -#define INIT_HCA_FLAGS1_OFFSET 0x00c -#define INIT_HCA_FLAGS2_OFFSET 0x014 +#define INIT_HCA_FLAGS_OFFSET 0x014 #define INIT_HCA_QPC_OFFSET 0x020 #define INIT_HCA_QPC_BASE_OFFSET (INIT_HCA_QPC_OFFSET + 0x10) #define INIT_HCA_LOG_QP_OFFSET (INIT_HCA_QPC_OFFSET + 0x17) @@ -1311,18 +1216,15 @@ int mthca_INIT_HCA(struct mthca_dev *dev, memset(inbox, 0, INIT_HCA_IN_SIZE); - if (dev->mthca_flags & MTHCA_FLAG_SINAI_OPT) - MTHCA_PUT(inbox, 0x1, INIT_HCA_FLAGS1_OFFSET); - #if defined(__LITTLE_ENDIAN) - *(inbox + INIT_HCA_FLAGS2_OFFSET / 4) &= ~cpu_to_be32(1 << 1); + *(inbox + INIT_HCA_FLAGS_OFFSET / 4) &= ~cpu_to_be32(1 << 1); #elif defined(__BIG_ENDIAN) - *(inbox + INIT_HCA_FLAGS2_OFFSET / 4) |= cpu_to_be32(1 << 1); + *(inbox + INIT_HCA_FLAGS_OFFSET / 4) |= cpu_to_be32(1 << 1); #else #error Host endianness not defined #endif /* Check port for UD address vector: */ - *(inbox + INIT_HCA_FLAGS2_OFFSET / 4) |= cpu_to_be32(1); + *(inbox + INIT_HCA_FLAGS_OFFSET / 4) |= cpu_to_be32(1); /* We leave wqe_quota, responder_exu, etc as 0 (default) */ @@ -1536,11 +1438,11 @@ int mthca_SET_ICM_SIZE(struct mthca_dev *dev, u64 icm_size, u64 *aux_pages, return ret; /* - * Round up number of system pages needed in case - * MTHCA_ICM_PAGE_SIZE < PAGE_SIZE. + * Arbel page size is always 4 KB; round up number of system + * pages needed. */ - *aux_pages = ALIGN(*aux_pages, PAGE_SIZE / MTHCA_ICM_PAGE_SIZE) >> - (PAGE_SHIFT - MTHCA_ICM_PAGE_SHIFT); + *aux_pages = (*aux_pages + (1 << (PAGE_SHIFT - 12)) - 1) >> (PAGE_SHIFT - 12); + *aux_pages = ALIGN(*aux_pages, PAGE_SIZE >> 12) >> (PAGE_SHIFT - 12); return 0; } @@ -1612,37 +1514,6 @@ int mthca_HW2SW_CQ(struct mthca_dev *dev, struct mthca_mailbox *mailbox, CMD_TIME_CLASS_A, status); } -int mthca_RESIZE_CQ(struct mthca_dev *dev, int cq_num, u32 lkey, u8 log_size, - u8 *status) -{ - struct mthca_mailbox *mailbox; - __be32 *inbox; - int err; - -#define RESIZE_CQ_IN_SIZE 0x40 -#define RESIZE_CQ_LOG_SIZE_OFFSET 0x0c -#define RESIZE_CQ_LKEY_OFFSET 0x1c - - mailbox = mthca_alloc_mailbox(dev, GFP_KERNEL); - if (IS_ERR(mailbox)) - return PTR_ERR(mailbox); - inbox = mailbox->buf; - - memset(inbox, 0, RESIZE_CQ_IN_SIZE); - /* - * Leave start address fields zeroed out -- mthca assumes that - * MRs for CQs always start at virtual address 0. - */ - MTHCA_PUT(inbox, log_size, RESIZE_CQ_LOG_SIZE_OFFSET); - MTHCA_PUT(inbox, lkey, RESIZE_CQ_LKEY_OFFSET); - - err = mthca_cmd(dev, mailbox->dma, cq_num, 1, CMD_RESIZE_CQ, - CMD_TIME_CLASS_B, status); - - mthca_free_mailbox(dev, mailbox); - return err; -} - int mthca_SW2HW_SRQ(struct mthca_dev *dev, struct mthca_mailbox *mailbox, int srq_num, u8 *status) { @@ -1658,69 +1529,37 @@ int mthca_HW2SW_SRQ(struct mthca_dev *dev, struct mthca_mailbox *mailbox, CMD_TIME_CLASS_A, status); } -int mthca_QUERY_SRQ(struct mthca_dev *dev, u32 num, - struct mthca_mailbox *mailbox, u8 *status) -{ - return mthca_cmd_box(dev, 0, mailbox->dma, num, 0, - CMD_QUERY_SRQ, CMD_TIME_CLASS_A, status); -} - int mthca_ARM_SRQ(struct mthca_dev *dev, int srq_num, int limit, u8 *status) { return mthca_cmd(dev, limit, srq_num, 0, CMD_ARM_SRQ, CMD_TIME_CLASS_B, status); } -int mthca_MODIFY_QP(struct mthca_dev *dev, enum ib_qp_state cur, - enum ib_qp_state next, u32 num, int is_ee, - struct mthca_mailbox *mailbox, u32 optmask, +int mthca_MODIFY_QP(struct mthca_dev *dev, int trans, u32 num, + int is_ee, struct mthca_mailbox *mailbox, u32 optmask, u8 *status) { - static const u16 op[IB_QPS_ERR + 1][IB_QPS_ERR + 1] = { - [IB_QPS_RESET] = { - [IB_QPS_RESET] = CMD_ERR2RST_QPEE, - [IB_QPS_ERR] = CMD_2ERR_QPEE, - [IB_QPS_INIT] = CMD_RST2INIT_QPEE, - }, - [IB_QPS_INIT] = { - [IB_QPS_RESET] = CMD_ERR2RST_QPEE, - [IB_QPS_ERR] = CMD_2ERR_QPEE, - [IB_QPS_INIT] = CMD_INIT2INIT_QPEE, - [IB_QPS_RTR] = CMD_INIT2RTR_QPEE, - }, - [IB_QPS_RTR] = { - [IB_QPS_RESET] = CMD_ERR2RST_QPEE, - [IB_QPS_ERR] = CMD_2ERR_QPEE, - [IB_QPS_RTS] = CMD_RTR2RTS_QPEE, - }, - [IB_QPS_RTS] = { - [IB_QPS_RESET] = CMD_ERR2RST_QPEE, - [IB_QPS_ERR] = CMD_2ERR_QPEE, - [IB_QPS_RTS] = CMD_RTS2RTS_QPEE, - [IB_QPS_SQD] = CMD_RTS2SQD_QPEE, - }, - [IB_QPS_SQD] = { - [IB_QPS_RESET] = CMD_ERR2RST_QPEE, - [IB_QPS_ERR] = CMD_2ERR_QPEE, - [IB_QPS_RTS] = CMD_SQD2RTS_QPEE, - [IB_QPS_SQD] = CMD_SQD2SQD_QPEE, - }, - [IB_QPS_SQE] = { - [IB_QPS_RESET] = CMD_ERR2RST_QPEE, - [IB_QPS_ERR] = CMD_2ERR_QPEE, - [IB_QPS_RTS] = CMD_SQERR2RTS_QPEE, - }, - [IB_QPS_ERR] = { - [IB_QPS_RESET] = CMD_ERR2RST_QPEE, - [IB_QPS_ERR] = CMD_2ERR_QPEE, - } + static const u16 op[] = { + [MTHCA_TRANS_RST2INIT] = CMD_RST2INIT_QPEE, + [MTHCA_TRANS_INIT2INIT] = CMD_INIT2INIT_QPEE, + [MTHCA_TRANS_INIT2RTR] = CMD_INIT2RTR_QPEE, + [MTHCA_TRANS_RTR2RTS] = CMD_RTR2RTS_QPEE, + [MTHCA_TRANS_RTS2RTS] = CMD_RTS2RTS_QPEE, + [MTHCA_TRANS_SQERR2RTS] = CMD_SQERR2RTS_QPEE, + [MTHCA_TRANS_ANY2ERR] = CMD_2ERR_QPEE, + [MTHCA_TRANS_RTS2SQD] = CMD_RTS2SQD_QPEE, + [MTHCA_TRANS_SQD2SQD] = CMD_SQD2SQD_QPEE, + [MTHCA_TRANS_SQD2RTS] = CMD_SQD2RTS_QPEE, + [MTHCA_TRANS_ANY2RST] = CMD_ERR2RST_QPEE }; - u8 op_mod = 0; int my_mailbox = 0; int err; - if (op[cur][next] == CMD_ERR2RST_QPEE) { + if (trans < 0 || trans >= ARRAY_SIZE(op)) + return -EINVAL; + + if (trans == MTHCA_TRANS_ANY2RST) { op_mod = 3; /* don't write outbox, any->reset */ /* For debugging */ @@ -1732,35 +1571,34 @@ int mthca_MODIFY_QP(struct mthca_dev *dev, enum ib_qp_state cur, } else mailbox = NULL; } - - err = mthca_cmd_box(dev, 0, mailbox ? mailbox->dma : 0, - (!!is_ee << 24) | num, op_mod, - op[cur][next], CMD_TIME_CLASS_C, status); - - if (0 && mailbox) { + } else { + if (0) { int i; mthca_dbg(dev, "Dumping QP context:\n"); - printk(" %08x\n", be32_to_cpup(mailbox->buf)); + printk(" opt param mask: %08x\n", be32_to_cpup(mailbox->buf)); for (i = 0; i < 0x100 / 4; ++i) { if (i % 8 == 0) - printk("[%02x] ", i * 4); + printk(" [%02x] ", i * 4); printk(" %08x", be32_to_cpu(((__be32 *) mailbox->buf)[i + 2])); if ((i + 1) % 8 == 0) printk("\n"); } } + } - if (my_mailbox) - mthca_free_mailbox(dev, mailbox); - } else { - if (0) { + if (trans == MTHCA_TRANS_ANY2RST) { + err = mthca_cmd_box(dev, 0, mailbox ? mailbox->dma : 0, + (!!is_ee << 24) | num, op_mod, + op[trans], CMD_TIME_CLASS_C, status); + + if (0 && mailbox) { int i; mthca_dbg(dev, "Dumping QP context:\n"); - printk(" opt param mask: %08x\n", be32_to_cpup(mailbox->buf)); + printk(" %08x\n", be32_to_cpup(mailbox->buf)); for (i = 0; i < 0x100 / 4; ++i) { if (i % 8 == 0) - printk(" [%02x] ", i * 4); + printk("[%02x] ", i * 4); printk(" %08x", be32_to_cpu(((__be32 *) mailbox->buf)[i + 2])); if ((i + 1) % 8 == 0) @@ -1768,9 +1606,12 @@ int mthca_MODIFY_QP(struct mthca_dev *dev, enum ib_qp_state cur, } } - err = mthca_cmd(dev, mailbox->dma, optmask | (!!is_ee << 24) | num, - op_mod, op[cur][next], CMD_TIME_CLASS_C, status); - } + } else + err = mthca_cmd(dev, mailbox->dma, (!!is_ee << 24) | num, + op_mod, op[trans], CMD_TIME_CLASS_C, status); + + if (my_mailbox) + mthca_free_mailbox(dev, mailbox); return err; }