162306a36Sopenharmony_ci/* SPDX-License-Identifier: GPL-2.0-only */
262306a36Sopenharmony_ci/*
362306a36Sopenharmony_ci * Copyright 2008 Cisco Systems, Inc.  All rights reserved.
462306a36Sopenharmony_ci * Copyright 2007 Nuova Systems, Inc.  All rights reserved.
562306a36Sopenharmony_ci */
662306a36Sopenharmony_ci#ifndef _CQ_DESC_H_
762306a36Sopenharmony_ci#define _CQ_DESC_H_
862306a36Sopenharmony_ci
962306a36Sopenharmony_ci/*
1062306a36Sopenharmony_ci * Completion queue descriptor types
1162306a36Sopenharmony_ci */
1262306a36Sopenharmony_cienum cq_desc_types {
1362306a36Sopenharmony_ci	CQ_DESC_TYPE_WQ_ENET = 0,
1462306a36Sopenharmony_ci	CQ_DESC_TYPE_DESC_COPY = 1,
1562306a36Sopenharmony_ci	CQ_DESC_TYPE_WQ_EXCH = 2,
1662306a36Sopenharmony_ci	CQ_DESC_TYPE_RQ_ENET = 3,
1762306a36Sopenharmony_ci	CQ_DESC_TYPE_RQ_FCP = 4,
1862306a36Sopenharmony_ci};
1962306a36Sopenharmony_ci
2062306a36Sopenharmony_ci/* Completion queue descriptor: 16B
2162306a36Sopenharmony_ci *
2262306a36Sopenharmony_ci * All completion queues have this basic layout.  The
2362306a36Sopenharmony_ci * type_specfic area is unique for each completion
2462306a36Sopenharmony_ci * queue type.
2562306a36Sopenharmony_ci */
2662306a36Sopenharmony_cistruct cq_desc {
2762306a36Sopenharmony_ci	__le16 completed_index;
2862306a36Sopenharmony_ci	__le16 q_number;
2962306a36Sopenharmony_ci	u8 type_specfic[11];
3062306a36Sopenharmony_ci	u8 type_color;
3162306a36Sopenharmony_ci};
3262306a36Sopenharmony_ci
3362306a36Sopenharmony_ci#define CQ_DESC_TYPE_BITS        4
3462306a36Sopenharmony_ci#define CQ_DESC_TYPE_MASK        ((1 << CQ_DESC_TYPE_BITS) - 1)
3562306a36Sopenharmony_ci#define CQ_DESC_COLOR_MASK       1
3662306a36Sopenharmony_ci#define CQ_DESC_COLOR_SHIFT      7
3762306a36Sopenharmony_ci#define CQ_DESC_Q_NUM_BITS       10
3862306a36Sopenharmony_ci#define CQ_DESC_Q_NUM_MASK       ((1 << CQ_DESC_Q_NUM_BITS) - 1)
3962306a36Sopenharmony_ci#define CQ_DESC_COMP_NDX_BITS    12
4062306a36Sopenharmony_ci#define CQ_DESC_COMP_NDX_MASK    ((1 << CQ_DESC_COMP_NDX_BITS) - 1)
4162306a36Sopenharmony_ci
4262306a36Sopenharmony_cistatic inline void cq_desc_dec(const struct cq_desc *desc_arg,
4362306a36Sopenharmony_ci	u8 *type, u8 *color, u16 *q_number, u16 *completed_index)
4462306a36Sopenharmony_ci{
4562306a36Sopenharmony_ci	const struct cq_desc *desc = desc_arg;
4662306a36Sopenharmony_ci	const u8 type_color = desc->type_color;
4762306a36Sopenharmony_ci
4862306a36Sopenharmony_ci	*color = (type_color >> CQ_DESC_COLOR_SHIFT) & CQ_DESC_COLOR_MASK;
4962306a36Sopenharmony_ci
5062306a36Sopenharmony_ci	/*
5162306a36Sopenharmony_ci	 * Make sure color bit is read from desc *before* other fields
5262306a36Sopenharmony_ci	 * are read from desc.  Hardware guarantees color bit is last
5362306a36Sopenharmony_ci	 * bit (byte) written.  Adding the rmb() prevents the compiler
5462306a36Sopenharmony_ci	 * and/or CPU from reordering the reads which would potentially
5562306a36Sopenharmony_ci	 * result in reading stale values.
5662306a36Sopenharmony_ci	 */
5762306a36Sopenharmony_ci
5862306a36Sopenharmony_ci	rmb();
5962306a36Sopenharmony_ci
6062306a36Sopenharmony_ci	*type = type_color & CQ_DESC_TYPE_MASK;
6162306a36Sopenharmony_ci	*q_number = le16_to_cpu(desc->q_number) & CQ_DESC_Q_NUM_MASK;
6262306a36Sopenharmony_ci	*completed_index = le16_to_cpu(desc->completed_index) &
6362306a36Sopenharmony_ci		CQ_DESC_COMP_NDX_MASK;
6462306a36Sopenharmony_ci}
6562306a36Sopenharmony_ci
6662306a36Sopenharmony_ci#endif /* _CQ_DESC_H_ */
67