Path: blob/master/drivers/infiniband/hw/ipath/ipath_qp.c
15112 views
/*1* Copyright (c) 2006, 2007, 2008 QLogic Corporation. All rights reserved.2* Copyright (c) 2005, 2006 PathScale, Inc. All rights reserved.3*4* This software is available to you under a choice of one of two5* licenses. You may choose to be licensed under the terms of the GNU6* General Public License (GPL) Version 2, available from the file7* COPYING in the main directory of this source tree, or the8* OpenIB.org BSD license below:9*10* Redistribution and use in source and binary forms, with or11* without modification, are permitted provided that the following12* conditions are met:13*14* - Redistributions of source code must retain the above15* copyright notice, this list of conditions and the following16* disclaimer.17*18* - Redistributions in binary form must reproduce the above19* copyright notice, this list of conditions and the following20* disclaimer in the documentation and/or other materials21* provided with the distribution.22*23* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,24* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF25* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND26* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS27* BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN28* ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN29* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE30* SOFTWARE.31*/3233#include <linux/err.h>34#include <linux/sched.h>35#include <linux/slab.h>36#include <linux/vmalloc.h>3738#include "ipath_verbs.h"39#include "ipath_kernel.h"4041#define BITS_PER_PAGE (PAGE_SIZE*BITS_PER_BYTE)42#define BITS_PER_PAGE_MASK (BITS_PER_PAGE-1)43#define mk_qpn(qpt, map, off) (((map) - (qpt)->map) * BITS_PER_PAGE + \44(off))45#define find_next_offset(map, off) find_next_zero_bit((map)->page, \46BITS_PER_PAGE, off)4748/*49* Convert the AETH credit code into the number of credits.50*/51static u32 credit_table[31] = {520, /* 0 */531, /* 1 */542, /* 2 */553, /* 3 */564, /* 4 */576, /* 5 */588, /* 6 */5912, /* 7 */6016, /* 8 */6124, /* 9 */6232, /* A */6348, /* B */6464, /* C */6596, /* D */66128, /* E */67192, /* F */68256, /* 10 */69384, /* 11 */70512, /* 12 */71768, /* 13 */721024, /* 14 */731536, /* 15 */742048, /* 16 */753072, /* 17 */764096, /* 18 */776144, /* 19 */788192, /* 1A */7912288, /* 1B */8016384, /* 1C */8124576, /* 1D */8232768 /* 1E */83};848586static void get_map_page(struct ipath_qp_table *qpt, struct qpn_map *map)87{88unsigned long page = get_zeroed_page(GFP_KERNEL);89unsigned long flags;9091/*92* Free the page if someone raced with us installing it.93*/9495spin_lock_irqsave(&qpt->lock, flags);96if (map->page)97free_page(page);98else99map->page = (void *)page;100spin_unlock_irqrestore(&qpt->lock, flags);101}102103104static int alloc_qpn(struct ipath_qp_table *qpt, enum ib_qp_type type)105{106u32 i, offset, max_scan, qpn;107struct qpn_map *map;108u32 ret = -1;109110if (type == IB_QPT_SMI)111ret = 0;112else if (type == IB_QPT_GSI)113ret = 1;114115if (ret != -1) {116map = &qpt->map[0];117if (unlikely(!map->page)) {118get_map_page(qpt, map);119if (unlikely(!map->page)) {120ret = -ENOMEM;121goto bail;122}123}124if (!test_and_set_bit(ret, map->page))125atomic_dec(&map->n_free);126else127ret = -EBUSY;128goto bail;129}130131qpn = qpt->last + 1;132if (qpn >= QPN_MAX)133qpn = 2;134offset = qpn & BITS_PER_PAGE_MASK;135map = &qpt->map[qpn / BITS_PER_PAGE];136max_scan = qpt->nmaps - !offset;137for (i = 0;;) {138if (unlikely(!map->page)) {139get_map_page(qpt, map);140if (unlikely(!map->page))141break;142}143if (likely(atomic_read(&map->n_free))) {144do {145if (!test_and_set_bit(offset, map->page)) {146atomic_dec(&map->n_free);147qpt->last = qpn;148ret = qpn;149goto bail;150}151offset = find_next_offset(map, offset);152qpn = mk_qpn(qpt, map, offset);153/*154* This test differs from alloc_pidmap().155* If find_next_offset() does find a zero156* bit, we don't need to check for QPN157* wrapping around past our starting QPN.158* We just need to be sure we don't loop159* forever.160*/161} while (offset < BITS_PER_PAGE && qpn < QPN_MAX);162}163/*164* In order to keep the number of pages allocated to a165* minimum, we scan the all existing pages before increasing166* the size of the bitmap table.167*/168if (++i > max_scan) {169if (qpt->nmaps == QPNMAP_ENTRIES)170break;171map = &qpt->map[qpt->nmaps++];172offset = 0;173} else if (map < &qpt->map[qpt->nmaps]) {174++map;175offset = 0;176} else {177map = &qpt->map[0];178offset = 2;179}180qpn = mk_qpn(qpt, map, offset);181}182183ret = -ENOMEM;184185bail:186return ret;187}188189static void free_qpn(struct ipath_qp_table *qpt, u32 qpn)190{191struct qpn_map *map;192193map = qpt->map + qpn / BITS_PER_PAGE;194if (map->page)195clear_bit(qpn & BITS_PER_PAGE_MASK, map->page);196atomic_inc(&map->n_free);197}198199/**200* ipath_alloc_qpn - allocate a QP number201* @qpt: the QP table202* @qp: the QP203* @type: the QP type (IB_QPT_SMI and IB_QPT_GSI are special)204*205* Allocate the next available QPN and put the QP into the hash table.206* The hash table holds a reference to the QP.207*/208static int ipath_alloc_qpn(struct ipath_qp_table *qpt, struct ipath_qp *qp,209enum ib_qp_type type)210{211unsigned long flags;212int ret;213214ret = alloc_qpn(qpt, type);215if (ret < 0)216goto bail;217qp->ibqp.qp_num = ret;218219/* Add the QP to the hash table. */220spin_lock_irqsave(&qpt->lock, flags);221222ret %= qpt->max;223qp->next = qpt->table[ret];224qpt->table[ret] = qp;225atomic_inc(&qp->refcount);226227spin_unlock_irqrestore(&qpt->lock, flags);228ret = 0;229230bail:231return ret;232}233234/**235* ipath_free_qp - remove a QP from the QP table236* @qpt: the QP table237* @qp: the QP to remove238*239* Remove the QP from the table so it can't be found asynchronously by240* the receive interrupt routine.241*/242static void ipath_free_qp(struct ipath_qp_table *qpt, struct ipath_qp *qp)243{244struct ipath_qp *q, **qpp;245unsigned long flags;246247spin_lock_irqsave(&qpt->lock, flags);248249/* Remove QP from the hash table. */250qpp = &qpt->table[qp->ibqp.qp_num % qpt->max];251for (; (q = *qpp) != NULL; qpp = &q->next) {252if (q == qp) {253*qpp = qp->next;254qp->next = NULL;255atomic_dec(&qp->refcount);256break;257}258}259260spin_unlock_irqrestore(&qpt->lock, flags);261}262263/**264* ipath_free_all_qps - check for QPs still in use265* @qpt: the QP table to empty266*267* There should not be any QPs still in use.268* Free memory for table.269*/270unsigned ipath_free_all_qps(struct ipath_qp_table *qpt)271{272unsigned long flags;273struct ipath_qp *qp;274u32 n, qp_inuse = 0;275276spin_lock_irqsave(&qpt->lock, flags);277for (n = 0; n < qpt->max; n++) {278qp = qpt->table[n];279qpt->table[n] = NULL;280281for (; qp; qp = qp->next)282qp_inuse++;283}284spin_unlock_irqrestore(&qpt->lock, flags);285286for (n = 0; n < ARRAY_SIZE(qpt->map); n++)287if (qpt->map[n].page)288free_page((unsigned long) qpt->map[n].page);289return qp_inuse;290}291292/**293* ipath_lookup_qpn - return the QP with the given QPN294* @qpt: the QP table295* @qpn: the QP number to look up296*297* The caller is responsible for decrementing the QP reference count298* when done.299*/300struct ipath_qp *ipath_lookup_qpn(struct ipath_qp_table *qpt, u32 qpn)301{302unsigned long flags;303struct ipath_qp *qp;304305spin_lock_irqsave(&qpt->lock, flags);306307for (qp = qpt->table[qpn % qpt->max]; qp; qp = qp->next) {308if (qp->ibqp.qp_num == qpn) {309atomic_inc(&qp->refcount);310break;311}312}313314spin_unlock_irqrestore(&qpt->lock, flags);315return qp;316}317318/**319* ipath_reset_qp - initialize the QP state to the reset state320* @qp: the QP to reset321* @type: the QP type322*/323static void ipath_reset_qp(struct ipath_qp *qp, enum ib_qp_type type)324{325qp->remote_qpn = 0;326qp->qkey = 0;327qp->qp_access_flags = 0;328atomic_set(&qp->s_dma_busy, 0);329qp->s_flags &= IPATH_S_SIGNAL_REQ_WR;330qp->s_hdrwords = 0;331qp->s_wqe = NULL;332qp->s_pkt_delay = 0;333qp->s_draining = 0;334qp->s_psn = 0;335qp->r_psn = 0;336qp->r_msn = 0;337if (type == IB_QPT_RC) {338qp->s_state = IB_OPCODE_RC_SEND_LAST;339qp->r_state = IB_OPCODE_RC_SEND_LAST;340} else {341qp->s_state = IB_OPCODE_UC_SEND_LAST;342qp->r_state = IB_OPCODE_UC_SEND_LAST;343}344qp->s_ack_state = IB_OPCODE_RC_ACKNOWLEDGE;345qp->r_nak_state = 0;346qp->r_aflags = 0;347qp->r_flags = 0;348qp->s_rnr_timeout = 0;349qp->s_head = 0;350qp->s_tail = 0;351qp->s_cur = 0;352qp->s_last = 0;353qp->s_ssn = 1;354qp->s_lsn = 0;355memset(qp->s_ack_queue, 0, sizeof(qp->s_ack_queue));356qp->r_head_ack_queue = 0;357qp->s_tail_ack_queue = 0;358qp->s_num_rd_atomic = 0;359if (qp->r_rq.wq) {360qp->r_rq.wq->head = 0;361qp->r_rq.wq->tail = 0;362}363}364365/**366* ipath_error_qp - put a QP into the error state367* @qp: the QP to put into the error state368* @err: the receive completion error to signal if a RWQE is active369*370* Flushes both send and receive work queues.371* Returns true if last WQE event should be generated.372* The QP s_lock should be held and interrupts disabled.373* If we are already in error state, just return.374*/375376int ipath_error_qp(struct ipath_qp *qp, enum ib_wc_status err)377{378struct ipath_ibdev *dev = to_idev(qp->ibqp.device);379struct ib_wc wc;380int ret = 0;381382if (qp->state == IB_QPS_ERR)383goto bail;384385qp->state = IB_QPS_ERR;386387spin_lock(&dev->pending_lock);388if (!list_empty(&qp->timerwait))389list_del_init(&qp->timerwait);390if (!list_empty(&qp->piowait))391list_del_init(&qp->piowait);392spin_unlock(&dev->pending_lock);393394/* Schedule the sending tasklet to drain the send work queue. */395if (qp->s_last != qp->s_head)396ipath_schedule_send(qp);397398memset(&wc, 0, sizeof(wc));399wc.qp = &qp->ibqp;400wc.opcode = IB_WC_RECV;401402if (test_and_clear_bit(IPATH_R_WRID_VALID, &qp->r_aflags)) {403wc.wr_id = qp->r_wr_id;404wc.status = err;405ipath_cq_enter(to_icq(qp->ibqp.recv_cq), &wc, 1);406}407wc.status = IB_WC_WR_FLUSH_ERR;408409if (qp->r_rq.wq) {410struct ipath_rwq *wq;411u32 head;412u32 tail;413414spin_lock(&qp->r_rq.lock);415416/* sanity check pointers before trusting them */417wq = qp->r_rq.wq;418head = wq->head;419if (head >= qp->r_rq.size)420head = 0;421tail = wq->tail;422if (tail >= qp->r_rq.size)423tail = 0;424while (tail != head) {425wc.wr_id = get_rwqe_ptr(&qp->r_rq, tail)->wr_id;426if (++tail >= qp->r_rq.size)427tail = 0;428ipath_cq_enter(to_icq(qp->ibqp.recv_cq), &wc, 1);429}430wq->tail = tail;431432spin_unlock(&qp->r_rq.lock);433} else if (qp->ibqp.event_handler)434ret = 1;435436bail:437return ret;438}439440/**441* ipath_modify_qp - modify the attributes of a queue pair442* @ibqp: the queue pair who's attributes we're modifying443* @attr: the new attributes444* @attr_mask: the mask of attributes to modify445* @udata: user data for ipathverbs.so446*447* Returns 0 on success, otherwise returns an errno.448*/449int ipath_modify_qp(struct ib_qp *ibqp, struct ib_qp_attr *attr,450int attr_mask, struct ib_udata *udata)451{452struct ipath_ibdev *dev = to_idev(ibqp->device);453struct ipath_qp *qp = to_iqp(ibqp);454enum ib_qp_state cur_state, new_state;455int lastwqe = 0;456int ret;457458spin_lock_irq(&qp->s_lock);459460cur_state = attr_mask & IB_QP_CUR_STATE ?461attr->cur_qp_state : qp->state;462new_state = attr_mask & IB_QP_STATE ? attr->qp_state : cur_state;463464if (!ib_modify_qp_is_ok(cur_state, new_state, ibqp->qp_type,465attr_mask))466goto inval;467468if (attr_mask & IB_QP_AV) {469if (attr->ah_attr.dlid == 0 ||470attr->ah_attr.dlid >= IPATH_MULTICAST_LID_BASE)471goto inval;472473if ((attr->ah_attr.ah_flags & IB_AH_GRH) &&474(attr->ah_attr.grh.sgid_index > 1))475goto inval;476}477478if (attr_mask & IB_QP_PKEY_INDEX)479if (attr->pkey_index >= ipath_get_npkeys(dev->dd))480goto inval;481482if (attr_mask & IB_QP_MIN_RNR_TIMER)483if (attr->min_rnr_timer > 31)484goto inval;485486if (attr_mask & IB_QP_PORT)487if (attr->port_num == 0 ||488attr->port_num > ibqp->device->phys_port_cnt)489goto inval;490491/*492* don't allow invalid Path MTU values or greater than 2048493* unless we are configured for a 4KB MTU494*/495if ((attr_mask & IB_QP_PATH_MTU) &&496(ib_mtu_enum_to_int(attr->path_mtu) == -1 ||497(attr->path_mtu > IB_MTU_2048 && !ipath_mtu4096)))498goto inval;499500if (attr_mask & IB_QP_PATH_MIG_STATE)501if (attr->path_mig_state != IB_MIG_MIGRATED &&502attr->path_mig_state != IB_MIG_REARM)503goto inval;504505if (attr_mask & IB_QP_MAX_DEST_RD_ATOMIC)506if (attr->max_dest_rd_atomic > IPATH_MAX_RDMA_ATOMIC)507goto inval;508509switch (new_state) {510case IB_QPS_RESET:511if (qp->state != IB_QPS_RESET) {512qp->state = IB_QPS_RESET;513spin_lock(&dev->pending_lock);514if (!list_empty(&qp->timerwait))515list_del_init(&qp->timerwait);516if (!list_empty(&qp->piowait))517list_del_init(&qp->piowait);518spin_unlock(&dev->pending_lock);519qp->s_flags &= ~IPATH_S_ANY_WAIT;520spin_unlock_irq(&qp->s_lock);521/* Stop the sending tasklet */522tasklet_kill(&qp->s_task);523wait_event(qp->wait_dma, !atomic_read(&qp->s_dma_busy));524spin_lock_irq(&qp->s_lock);525}526ipath_reset_qp(qp, ibqp->qp_type);527break;528529case IB_QPS_SQD:530qp->s_draining = qp->s_last != qp->s_cur;531qp->state = new_state;532break;533534case IB_QPS_SQE:535if (qp->ibqp.qp_type == IB_QPT_RC)536goto inval;537qp->state = new_state;538break;539540case IB_QPS_ERR:541lastwqe = ipath_error_qp(qp, IB_WC_WR_FLUSH_ERR);542break;543544default:545qp->state = new_state;546break;547}548549if (attr_mask & IB_QP_PKEY_INDEX)550qp->s_pkey_index = attr->pkey_index;551552if (attr_mask & IB_QP_DEST_QPN)553qp->remote_qpn = attr->dest_qp_num;554555if (attr_mask & IB_QP_SQ_PSN) {556qp->s_psn = qp->s_next_psn = attr->sq_psn;557qp->s_last_psn = qp->s_next_psn - 1;558}559560if (attr_mask & IB_QP_RQ_PSN)561qp->r_psn = attr->rq_psn;562563if (attr_mask & IB_QP_ACCESS_FLAGS)564qp->qp_access_flags = attr->qp_access_flags;565566if (attr_mask & IB_QP_AV) {567qp->remote_ah_attr = attr->ah_attr;568qp->s_dmult = ipath_ib_rate_to_mult(attr->ah_attr.static_rate);569}570571if (attr_mask & IB_QP_PATH_MTU)572qp->path_mtu = attr->path_mtu;573574if (attr_mask & IB_QP_RETRY_CNT)575qp->s_retry = qp->s_retry_cnt = attr->retry_cnt;576577if (attr_mask & IB_QP_RNR_RETRY) {578qp->s_rnr_retry = attr->rnr_retry;579if (qp->s_rnr_retry > 7)580qp->s_rnr_retry = 7;581qp->s_rnr_retry_cnt = qp->s_rnr_retry;582}583584if (attr_mask & IB_QP_MIN_RNR_TIMER)585qp->r_min_rnr_timer = attr->min_rnr_timer;586587if (attr_mask & IB_QP_TIMEOUT)588qp->timeout = attr->timeout;589590if (attr_mask & IB_QP_QKEY)591qp->qkey = attr->qkey;592593if (attr_mask & IB_QP_MAX_DEST_RD_ATOMIC)594qp->r_max_rd_atomic = attr->max_dest_rd_atomic;595596if (attr_mask & IB_QP_MAX_QP_RD_ATOMIC)597qp->s_max_rd_atomic = attr->max_rd_atomic;598599spin_unlock_irq(&qp->s_lock);600601if (lastwqe) {602struct ib_event ev;603604ev.device = qp->ibqp.device;605ev.element.qp = &qp->ibqp;606ev.event = IB_EVENT_QP_LAST_WQE_REACHED;607qp->ibqp.event_handler(&ev, qp->ibqp.qp_context);608}609ret = 0;610goto bail;611612inval:613spin_unlock_irq(&qp->s_lock);614ret = -EINVAL;615616bail:617return ret;618}619620int ipath_query_qp(struct ib_qp *ibqp, struct ib_qp_attr *attr,621int attr_mask, struct ib_qp_init_attr *init_attr)622{623struct ipath_qp *qp = to_iqp(ibqp);624625attr->qp_state = qp->state;626attr->cur_qp_state = attr->qp_state;627attr->path_mtu = qp->path_mtu;628attr->path_mig_state = 0;629attr->qkey = qp->qkey;630attr->rq_psn = qp->r_psn;631attr->sq_psn = qp->s_next_psn;632attr->dest_qp_num = qp->remote_qpn;633attr->qp_access_flags = qp->qp_access_flags;634attr->cap.max_send_wr = qp->s_size - 1;635attr->cap.max_recv_wr = qp->ibqp.srq ? 0 : qp->r_rq.size - 1;636attr->cap.max_send_sge = qp->s_max_sge;637attr->cap.max_recv_sge = qp->r_rq.max_sge;638attr->cap.max_inline_data = 0;639attr->ah_attr = qp->remote_ah_attr;640memset(&attr->alt_ah_attr, 0, sizeof(attr->alt_ah_attr));641attr->pkey_index = qp->s_pkey_index;642attr->alt_pkey_index = 0;643attr->en_sqd_async_notify = 0;644attr->sq_draining = qp->s_draining;645attr->max_rd_atomic = qp->s_max_rd_atomic;646attr->max_dest_rd_atomic = qp->r_max_rd_atomic;647attr->min_rnr_timer = qp->r_min_rnr_timer;648attr->port_num = 1;649attr->timeout = qp->timeout;650attr->retry_cnt = qp->s_retry_cnt;651attr->rnr_retry = qp->s_rnr_retry_cnt;652attr->alt_port_num = 0;653attr->alt_timeout = 0;654655init_attr->event_handler = qp->ibqp.event_handler;656init_attr->qp_context = qp->ibqp.qp_context;657init_attr->send_cq = qp->ibqp.send_cq;658init_attr->recv_cq = qp->ibqp.recv_cq;659init_attr->srq = qp->ibqp.srq;660init_attr->cap = attr->cap;661if (qp->s_flags & IPATH_S_SIGNAL_REQ_WR)662init_attr->sq_sig_type = IB_SIGNAL_REQ_WR;663else664init_attr->sq_sig_type = IB_SIGNAL_ALL_WR;665init_attr->qp_type = qp->ibqp.qp_type;666init_attr->port_num = 1;667return 0;668}669670/**671* ipath_compute_aeth - compute the AETH (syndrome + MSN)672* @qp: the queue pair to compute the AETH for673*674* Returns the AETH.675*/676__be32 ipath_compute_aeth(struct ipath_qp *qp)677{678u32 aeth = qp->r_msn & IPATH_MSN_MASK;679680if (qp->ibqp.srq) {681/*682* Shared receive queues don't generate credits.683* Set the credit field to the invalid value.684*/685aeth |= IPATH_AETH_CREDIT_INVAL << IPATH_AETH_CREDIT_SHIFT;686} else {687u32 min, max, x;688u32 credits;689struct ipath_rwq *wq = qp->r_rq.wq;690u32 head;691u32 tail;692693/* sanity check pointers before trusting them */694head = wq->head;695if (head >= qp->r_rq.size)696head = 0;697tail = wq->tail;698if (tail >= qp->r_rq.size)699tail = 0;700/*701* Compute the number of credits available (RWQEs).702* XXX Not holding the r_rq.lock here so there is a small703* chance that the pair of reads are not atomic.704*/705credits = head - tail;706if ((int)credits < 0)707credits += qp->r_rq.size;708/*709* Binary search the credit table to find the code to710* use.711*/712min = 0;713max = 31;714for (;;) {715x = (min + max) / 2;716if (credit_table[x] == credits)717break;718if (credit_table[x] > credits)719max = x;720else if (min == x)721break;722else723min = x;724}725aeth |= x << IPATH_AETH_CREDIT_SHIFT;726}727return cpu_to_be32(aeth);728}729730/**731* ipath_create_qp - create a queue pair for a device732* @ibpd: the protection domain who's device we create the queue pair for733* @init_attr: the attributes of the queue pair734* @udata: unused by InfiniPath735*736* Returns the queue pair on success, otherwise returns an errno.737*738* Called by the ib_create_qp() core verbs function.739*/740struct ib_qp *ipath_create_qp(struct ib_pd *ibpd,741struct ib_qp_init_attr *init_attr,742struct ib_udata *udata)743{744struct ipath_qp *qp;745int err;746struct ipath_swqe *swq = NULL;747struct ipath_ibdev *dev;748size_t sz;749size_t sg_list_sz;750struct ib_qp *ret;751752if (init_attr->create_flags) {753ret = ERR_PTR(-EINVAL);754goto bail;755}756757if (init_attr->cap.max_send_sge > ib_ipath_max_sges ||758init_attr->cap.max_send_wr > ib_ipath_max_qp_wrs) {759ret = ERR_PTR(-EINVAL);760goto bail;761}762763/* Check receive queue parameters if no SRQ is specified. */764if (!init_attr->srq) {765if (init_attr->cap.max_recv_sge > ib_ipath_max_sges ||766init_attr->cap.max_recv_wr > ib_ipath_max_qp_wrs) {767ret = ERR_PTR(-EINVAL);768goto bail;769}770if (init_attr->cap.max_send_sge +771init_attr->cap.max_send_wr +772init_attr->cap.max_recv_sge +773init_attr->cap.max_recv_wr == 0) {774ret = ERR_PTR(-EINVAL);775goto bail;776}777}778779switch (init_attr->qp_type) {780case IB_QPT_UC:781case IB_QPT_RC:782case IB_QPT_UD:783case IB_QPT_SMI:784case IB_QPT_GSI:785sz = sizeof(struct ipath_sge) *786init_attr->cap.max_send_sge +787sizeof(struct ipath_swqe);788swq = vmalloc((init_attr->cap.max_send_wr + 1) * sz);789if (swq == NULL) {790ret = ERR_PTR(-ENOMEM);791goto bail;792}793sz = sizeof(*qp);794sg_list_sz = 0;795if (init_attr->srq) {796struct ipath_srq *srq = to_isrq(init_attr->srq);797798if (srq->rq.max_sge > 1)799sg_list_sz = sizeof(*qp->r_sg_list) *800(srq->rq.max_sge - 1);801} else if (init_attr->cap.max_recv_sge > 1)802sg_list_sz = sizeof(*qp->r_sg_list) *803(init_attr->cap.max_recv_sge - 1);804qp = kmalloc(sz + sg_list_sz, GFP_KERNEL);805if (!qp) {806ret = ERR_PTR(-ENOMEM);807goto bail_swq;808}809if (sg_list_sz && (init_attr->qp_type == IB_QPT_UD ||810init_attr->qp_type == IB_QPT_SMI ||811init_attr->qp_type == IB_QPT_GSI)) {812qp->r_ud_sg_list = kmalloc(sg_list_sz, GFP_KERNEL);813if (!qp->r_ud_sg_list) {814ret = ERR_PTR(-ENOMEM);815goto bail_qp;816}817} else818qp->r_ud_sg_list = NULL;819if (init_attr->srq) {820sz = 0;821qp->r_rq.size = 0;822qp->r_rq.max_sge = 0;823qp->r_rq.wq = NULL;824init_attr->cap.max_recv_wr = 0;825init_attr->cap.max_recv_sge = 0;826} else {827qp->r_rq.size = init_attr->cap.max_recv_wr + 1;828qp->r_rq.max_sge = init_attr->cap.max_recv_sge;829sz = (sizeof(struct ib_sge) * qp->r_rq.max_sge) +830sizeof(struct ipath_rwqe);831qp->r_rq.wq = vmalloc_user(sizeof(struct ipath_rwq) +832qp->r_rq.size * sz);833if (!qp->r_rq.wq) {834ret = ERR_PTR(-ENOMEM);835goto bail_sg_list;836}837}838839/*840* ib_create_qp() will initialize qp->ibqp841* except for qp->ibqp.qp_num.842*/843spin_lock_init(&qp->s_lock);844spin_lock_init(&qp->r_rq.lock);845atomic_set(&qp->refcount, 0);846init_waitqueue_head(&qp->wait);847init_waitqueue_head(&qp->wait_dma);848tasklet_init(&qp->s_task, ipath_do_send, (unsigned long)qp);849INIT_LIST_HEAD(&qp->piowait);850INIT_LIST_HEAD(&qp->timerwait);851qp->state = IB_QPS_RESET;852qp->s_wq = swq;853qp->s_size = init_attr->cap.max_send_wr + 1;854qp->s_max_sge = init_attr->cap.max_send_sge;855if (init_attr->sq_sig_type == IB_SIGNAL_REQ_WR)856qp->s_flags = IPATH_S_SIGNAL_REQ_WR;857else858qp->s_flags = 0;859dev = to_idev(ibpd->device);860err = ipath_alloc_qpn(&dev->qp_table, qp,861init_attr->qp_type);862if (err) {863ret = ERR_PTR(err);864vfree(qp->r_rq.wq);865goto bail_sg_list;866}867qp->ip = NULL;868qp->s_tx = NULL;869ipath_reset_qp(qp, init_attr->qp_type);870break;871872default:873/* Don't support raw QPs */874ret = ERR_PTR(-ENOSYS);875goto bail;876}877878init_attr->cap.max_inline_data = 0;879880/*881* Return the address of the RWQ as the offset to mmap.882* See ipath_mmap() for details.883*/884if (udata && udata->outlen >= sizeof(__u64)) {885if (!qp->r_rq.wq) {886__u64 offset = 0;887888err = ib_copy_to_udata(udata, &offset,889sizeof(offset));890if (err) {891ret = ERR_PTR(err);892goto bail_ip;893}894} else {895u32 s = sizeof(struct ipath_rwq) +896qp->r_rq.size * sz;897898qp->ip =899ipath_create_mmap_info(dev, s,900ibpd->uobject->context,901qp->r_rq.wq);902if (!qp->ip) {903ret = ERR_PTR(-ENOMEM);904goto bail_ip;905}906907err = ib_copy_to_udata(udata, &(qp->ip->offset),908sizeof(qp->ip->offset));909if (err) {910ret = ERR_PTR(err);911goto bail_ip;912}913}914}915916spin_lock(&dev->n_qps_lock);917if (dev->n_qps_allocated == ib_ipath_max_qps) {918spin_unlock(&dev->n_qps_lock);919ret = ERR_PTR(-ENOMEM);920goto bail_ip;921}922923dev->n_qps_allocated++;924spin_unlock(&dev->n_qps_lock);925926if (qp->ip) {927spin_lock_irq(&dev->pending_lock);928list_add(&qp->ip->pending_mmaps, &dev->pending_mmaps);929spin_unlock_irq(&dev->pending_lock);930}931932ret = &qp->ibqp;933goto bail;934935bail_ip:936if (qp->ip)937kref_put(&qp->ip->ref, ipath_release_mmap_info);938else939vfree(qp->r_rq.wq);940ipath_free_qp(&dev->qp_table, qp);941free_qpn(&dev->qp_table, qp->ibqp.qp_num);942bail_sg_list:943kfree(qp->r_ud_sg_list);944bail_qp:945kfree(qp);946bail_swq:947vfree(swq);948bail:949return ret;950}951952/**953* ipath_destroy_qp - destroy a queue pair954* @ibqp: the queue pair to destroy955*956* Returns 0 on success.957*958* Note that this can be called while the QP is actively sending or959* receiving!960*/961int ipath_destroy_qp(struct ib_qp *ibqp)962{963struct ipath_qp *qp = to_iqp(ibqp);964struct ipath_ibdev *dev = to_idev(ibqp->device);965966/* Make sure HW and driver activity is stopped. */967spin_lock_irq(&qp->s_lock);968if (qp->state != IB_QPS_RESET) {969qp->state = IB_QPS_RESET;970spin_lock(&dev->pending_lock);971if (!list_empty(&qp->timerwait))972list_del_init(&qp->timerwait);973if (!list_empty(&qp->piowait))974list_del_init(&qp->piowait);975spin_unlock(&dev->pending_lock);976qp->s_flags &= ~IPATH_S_ANY_WAIT;977spin_unlock_irq(&qp->s_lock);978/* Stop the sending tasklet */979tasklet_kill(&qp->s_task);980wait_event(qp->wait_dma, !atomic_read(&qp->s_dma_busy));981} else982spin_unlock_irq(&qp->s_lock);983984ipath_free_qp(&dev->qp_table, qp);985986if (qp->s_tx) {987atomic_dec(&qp->refcount);988if (qp->s_tx->txreq.flags & IPATH_SDMA_TXREQ_F_FREEBUF)989kfree(qp->s_tx->txreq.map_addr);990spin_lock_irq(&dev->pending_lock);991list_add(&qp->s_tx->txreq.list, &dev->txreq_free);992spin_unlock_irq(&dev->pending_lock);993qp->s_tx = NULL;994}995996wait_event(qp->wait, !atomic_read(&qp->refcount));997998/* all user's cleaned up, mark it available */999free_qpn(&dev->qp_table, qp->ibqp.qp_num);1000spin_lock(&dev->n_qps_lock);1001dev->n_qps_allocated--;1002spin_unlock(&dev->n_qps_lock);10031004if (qp->ip)1005kref_put(&qp->ip->ref, ipath_release_mmap_info);1006else1007vfree(qp->r_rq.wq);1008kfree(qp->r_ud_sg_list);1009vfree(qp->s_wq);1010kfree(qp);1011return 0;1012}10131014/**1015* ipath_init_qp_table - initialize the QP table for a device1016* @idev: the device who's QP table we're initializing1017* @size: the size of the QP table1018*1019* Returns 0 on success, otherwise returns an errno.1020*/1021int ipath_init_qp_table(struct ipath_ibdev *idev, int size)1022{1023int i;1024int ret;10251026idev->qp_table.last = 1; /* QPN 0 and 1 are special. */1027idev->qp_table.max = size;1028idev->qp_table.nmaps = 1;1029idev->qp_table.table = kzalloc(size * sizeof(*idev->qp_table.table),1030GFP_KERNEL);1031if (idev->qp_table.table == NULL) {1032ret = -ENOMEM;1033goto bail;1034}10351036for (i = 0; i < ARRAY_SIZE(idev->qp_table.map); i++) {1037atomic_set(&idev->qp_table.map[i].n_free, BITS_PER_PAGE);1038idev->qp_table.map[i].page = NULL;1039}10401041ret = 0;10421043bail:1044return ret;1045}10461047/**1048* ipath_get_credit - flush the send work queue of a QP1049* @qp: the qp who's send work queue to flush1050* @aeth: the Acknowledge Extended Transport Header1051*1052* The QP s_lock should be held.1053*/1054void ipath_get_credit(struct ipath_qp *qp, u32 aeth)1055{1056u32 credit = (aeth >> IPATH_AETH_CREDIT_SHIFT) & IPATH_AETH_CREDIT_MASK;10571058/*1059* If the credit is invalid, we can send1060* as many packets as we like. Otherwise, we have to1061* honor the credit field.1062*/1063if (credit == IPATH_AETH_CREDIT_INVAL)1064qp->s_lsn = (u32) -1;1065else if (qp->s_lsn != (u32) -1) {1066/* Compute new LSN (i.e., MSN + credit) */1067credit = (aeth + credit_table[credit]) & IPATH_MSN_MASK;1068if (ipath_cmp24(credit, qp->s_lsn) > 0)1069qp->s_lsn = credit;1070}10711072/* Restart sending if it was blocked due to lack of credits. */1073if ((qp->s_flags & IPATH_S_WAIT_SSN_CREDIT) &&1074qp->s_cur != qp->s_head &&1075(qp->s_lsn == (u32) -1 ||1076ipath_cmp24(get_swqe_ptr(qp, qp->s_cur)->ssn,1077qp->s_lsn + 1) <= 0))1078ipath_schedule_send(qp);1079}108010811082