1/* 2 * Copyright (c) 2005 Ammasso, Inc. All rights reserved. 3 * Copyright (c) 2005 Open Grid Computing, Inc. All rights reserved. 4 * 5 * This software is available to you under a choice of one of two 6 * licenses. You may choose to be licensed under the terms of the GNU 7 * General Public License (GPL) Version 2, available from the file 8 * COPYING in the main directory of this source tree, or the 9 * OpenIB.org BSD license below: 10 * 11 * Redistribution and use in source and binary forms, with or 12 * without modification, are permitted provided that the following 13 * conditions are met: 14 * 15 * - Redistributions of source code must retain the above 16 * copyright notice, this list of conditions and the following 17 * disclaimer. 18 * 19 * - Redistributions in binary form must reproduce the above 20 * copyright notice, this list of conditions and the following 21 * disclaimer in the documentation and/or other materials 22 * provided with the distribution. 23 * 24 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 25 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 26 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 27 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS 28 * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN 29 * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 30 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 31 * SOFTWARE. 32 */ 33#include "c2.h" 34#include "c2_mq.h" 35 36void *c2_mq_alloc(struct c2_mq *q) 37{ 38 BUG_ON(q->magic != C2_MQ_MAGIC); 39 BUG_ON(q->type != C2_MQ_ADAPTER_TARGET); 40 41 if (c2_mq_full(q)) { 42 return NULL; 43 } else { 44#ifdef DEBUG 45 struct c2wr_hdr *m = 46 (struct c2wr_hdr *) (q->msg_pool.host + q->priv * q->msg_size); 47#ifdef CCMSGMAGIC 48 BUG_ON(m->magic != be32_to_cpu(~CCWR_MAGIC)); 49 m->magic = cpu_to_be32(CCWR_MAGIC); 50#endif 51 return m; 52#else 53 return q->msg_pool.host + q->priv * q->msg_size; 54#endif 55 } 56} 57 58void c2_mq_produce(struct c2_mq *q) 59{ 60 BUG_ON(q->magic != C2_MQ_MAGIC); 61 BUG_ON(q->type != C2_MQ_ADAPTER_TARGET); 62 63 if (!c2_mq_full(q)) { 64 q->priv = (q->priv + 1) % q->q_size; 65 q->hint_count++; 66 /* Update peer's offset. */ 67 __raw_writew((__force u16) cpu_to_be16(q->priv), &q->peer->shared); 68 } 69} 70 71void *c2_mq_consume(struct c2_mq *q) 72{ 73 BUG_ON(q->magic != C2_MQ_MAGIC); 74 BUG_ON(q->type != C2_MQ_HOST_TARGET); 75 76 if (c2_mq_empty(q)) { 77 return NULL; 78 } else { 79#ifdef DEBUG 80 struct c2wr_hdr *m = (struct c2wr_hdr *) 81 (q->msg_pool.host + q->priv * q->msg_size); 82#ifdef CCMSGMAGIC 83 BUG_ON(m->magic != be32_to_cpu(CCWR_MAGIC)); 84#endif 85 return m; 86#else 87 return q->msg_pool.host + q->priv * q->msg_size; 88#endif 89 } 90} 91 92void c2_mq_free(struct c2_mq *q) 93{ 94 BUG_ON(q->magic != C2_MQ_MAGIC); 95 BUG_ON(q->type != C2_MQ_HOST_TARGET); 96 97 if (!c2_mq_empty(q)) { 98 99#ifdef CCMSGMAGIC 100 { 101 struct c2wr_hdr __iomem *m = (struct c2wr_hdr __iomem *) 102 (q->msg_pool.adapter + q->priv * q->msg_size); 103 __raw_writel(cpu_to_be32(~CCWR_MAGIC), &m->magic); 104 } 105#endif 106 q->priv = (q->priv + 1) % q->q_size; 107 /* Update peer's offset. */ 108 __raw_writew((__force u16) cpu_to_be16(q->priv), &q->peer->shared); 109 } 110} 111 112 113void c2_mq_lconsume(struct c2_mq *q, u32 wqe_count) 114{ 115 BUG_ON(q->magic != C2_MQ_MAGIC); 116 BUG_ON(q->type != C2_MQ_ADAPTER_TARGET); 117 118 while (wqe_count--) { 119 BUG_ON(c2_mq_empty(q)); 120 *q->shared = cpu_to_be16((be16_to_cpu(*q->shared)+1) % q->q_size); 121 } 122} 123 124#if 0 125u32 c2_mq_count(struct c2_mq *q) 126{ 127 s32 count; 128 129 if (q->type == C2_MQ_HOST_TARGET) 130 count = be16_to_cpu(*q->shared) - q->priv; 131 else 132 count = q->priv - be16_to_cpu(*q->shared); 133 134 if (count < 0) 135 count += q->q_size; 136 137 return (u32) count; 138} 139#endif /* 0 */ 140 141void c2_mq_req_init(struct c2_mq *q, u32 index, u32 q_size, u32 msg_size, 142 u8 __iomem *pool_start, u16 __iomem *peer, u32 type) 143{ 144 BUG_ON(!q->shared); 145 146 /* This code assumes the byte swapping has already been done! */ 147 q->index = index; 148 q->q_size = q_size; 149 q->msg_size = msg_size; 150 q->msg_pool.adapter = pool_start; 151 q->peer = (struct c2_mq_shared __iomem *) peer; 152 q->magic = C2_MQ_MAGIC; 153 q->type = type; 154 q->priv = 0; 155 q->hint_count = 0; 156 return; 157} 158void c2_mq_rep_init(struct c2_mq *q, u32 index, u32 q_size, u32 msg_size, 159 u8 *pool_start, u16 __iomem *peer, u32 type) 160{ 161 BUG_ON(!q->shared); 162 163 /* This code assumes the byte swapping has already been done! */ 164 q->index = index; 165 q->q_size = q_size; 166 q->msg_size = msg_size; 167 q->msg_pool.host = pool_start; 168 q->peer = (struct c2_mq_shared __iomem *) peer; 169 q->magic = C2_MQ_MAGIC; 170 q->type = type; 171 q->priv = 0; 172 q->hint_count = 0; 173 return; 174} 175