Path: blob/master/drivers/infiniband/hw/amso1100/c2_mq.c
15112 views
/*1* Copyright (c) 2005 Ammasso, Inc. All rights reserved.2* Copyright (c) 2005 Open Grid Computing, 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*/32#include "c2.h"33#include "c2_mq.h"3435void *c2_mq_alloc(struct c2_mq *q)36{37BUG_ON(q->magic != C2_MQ_MAGIC);38BUG_ON(q->type != C2_MQ_ADAPTER_TARGET);3940if (c2_mq_full(q)) {41return NULL;42} else {43#ifdef DEBUG44struct c2wr_hdr *m =45(struct c2wr_hdr *) (q->msg_pool.host + q->priv * q->msg_size);46#ifdef CCMSGMAGIC47BUG_ON(m->magic != be32_to_cpu(~CCWR_MAGIC));48m->magic = cpu_to_be32(CCWR_MAGIC);49#endif50return m;51#else52return q->msg_pool.host + q->priv * q->msg_size;53#endif54}55}5657void c2_mq_produce(struct c2_mq *q)58{59BUG_ON(q->magic != C2_MQ_MAGIC);60BUG_ON(q->type != C2_MQ_ADAPTER_TARGET);6162if (!c2_mq_full(q)) {63q->priv = (q->priv + 1) % q->q_size;64q->hint_count++;65/* Update peer's offset. */66__raw_writew((__force u16) cpu_to_be16(q->priv), &q->peer->shared);67}68}6970void *c2_mq_consume(struct c2_mq *q)71{72BUG_ON(q->magic != C2_MQ_MAGIC);73BUG_ON(q->type != C2_MQ_HOST_TARGET);7475if (c2_mq_empty(q)) {76return NULL;77} else {78#ifdef DEBUG79struct c2wr_hdr *m = (struct c2wr_hdr *)80(q->msg_pool.host + q->priv * q->msg_size);81#ifdef CCMSGMAGIC82BUG_ON(m->magic != be32_to_cpu(CCWR_MAGIC));83#endif84return m;85#else86return q->msg_pool.host + q->priv * q->msg_size;87#endif88}89}9091void c2_mq_free(struct c2_mq *q)92{93BUG_ON(q->magic != C2_MQ_MAGIC);94BUG_ON(q->type != C2_MQ_HOST_TARGET);9596if (!c2_mq_empty(q)) {9798#ifdef CCMSGMAGIC99{100struct c2wr_hdr __iomem *m = (struct c2wr_hdr __iomem *)101(q->msg_pool.adapter + q->priv * q->msg_size);102__raw_writel(cpu_to_be32(~CCWR_MAGIC), &m->magic);103}104#endif105q->priv = (q->priv + 1) % q->q_size;106/* Update peer's offset. */107__raw_writew((__force u16) cpu_to_be16(q->priv), &q->peer->shared);108}109}110111112void c2_mq_lconsume(struct c2_mq *q, u32 wqe_count)113{114BUG_ON(q->magic != C2_MQ_MAGIC);115BUG_ON(q->type != C2_MQ_ADAPTER_TARGET);116117while (wqe_count--) {118BUG_ON(c2_mq_empty(q));119*q->shared = cpu_to_be16((be16_to_cpu(*q->shared)+1) % q->q_size);120}121}122123#if 0124u32 c2_mq_count(struct c2_mq *q)125{126s32 count;127128if (q->type == C2_MQ_HOST_TARGET)129count = be16_to_cpu(*q->shared) - q->priv;130else131count = q->priv - be16_to_cpu(*q->shared);132133if (count < 0)134count += q->q_size;135136return (u32) count;137}138#endif /* 0 */139140void c2_mq_req_init(struct c2_mq *q, u32 index, u32 q_size, u32 msg_size,141u8 __iomem *pool_start, u16 __iomem *peer, u32 type)142{143BUG_ON(!q->shared);144145/* This code assumes the byte swapping has already been done! */146q->index = index;147q->q_size = q_size;148q->msg_size = msg_size;149q->msg_pool.adapter = pool_start;150q->peer = (struct c2_mq_shared __iomem *) peer;151q->magic = C2_MQ_MAGIC;152q->type = type;153q->priv = 0;154q->hint_count = 0;155return;156}157void c2_mq_rep_init(struct c2_mq *q, u32 index, u32 q_size, u32 msg_size,158u8 *pool_start, u16 __iomem *peer, u32 type)159{160BUG_ON(!q->shared);161162/* This code assumes the byte swapping has already been done! */163q->index = index;164q->q_size = q_size;165q->msg_size = msg_size;166q->msg_pool.host = pool_start;167q->peer = (struct c2_mq_shared __iomem *) peer;168q->magic = C2_MQ_MAGIC;169q->type = type;170q->priv = 0;171q->hint_count = 0;172return;173}174175176