1 /* SPDX-License-Identifier: GPL-2.0 or BSD-3-Clause */ 2 3 #ifndef __QPLIB_TLV_H__ 4 #define __QPLIB_TLV_H__ 5 6 struct roce_tlv { 7 struct tlv tlv; 8 u8 total_size; // in units of 16 byte chunks 9 u8 unused[7]; // for 16 byte alignment 10 }; 11 12 #define CHUNK_SIZE 16 13 #define CHUNKS(x) (((x) + CHUNK_SIZE - 1) / CHUNK_SIZE) 14 15 static inline void __roce_1st_tlv_prep(struct roce_tlv *rtlv, u8 tot_chunks, 16 u16 content_bytes, u8 flags) 17 { 18 rtlv->tlv.cmd_discr = cpu_to_le16(CMD_DISCR_TLV_ENCAP); 19 rtlv->tlv.tlv_type = cpu_to_le16(TLV_TYPE_ROCE_SP_COMMAND); 20 rtlv->tlv.length = cpu_to_le16(content_bytes); 21 rtlv->tlv.flags = TLV_FLAGS_REQUIRED; 22 rtlv->tlv.flags |= flags ? TLV_FLAGS_MORE : 0; 23 rtlv->total_size = (tot_chunks); 24 } 25 26 static inline void __roce_ext_tlv_prep(struct roce_tlv *rtlv, u16 tlv_type, 27 u16 content_bytes, u8 more, u8 flags) 28 { 29 rtlv->tlv.cmd_discr = cpu_to_le16(CMD_DISCR_TLV_ENCAP); 30 rtlv->tlv.tlv_type = cpu_to_le16(tlv_type); 31 rtlv->tlv.length = cpu_to_le16(content_bytes); 32 rtlv->tlv.flags |= more ? TLV_FLAGS_MORE : 0; 33 rtlv->tlv.flags |= flags ? TLV_FLAGS_REQUIRED : 0; 34 } 35 36 /* 37 * TLV size in units of 16 byte chunks 38 */ 39 #define TLV_SIZE ((sizeof(struct roce_tlv) + 15) / 16) 40 /* 41 * TLV length in bytes 42 */ 43 #define TLV_BYTES (TLV_SIZE * 16) 44 45 #define HAS_TLV_HEADER(msg) (le16_to_cpu(((struct tlv *)(msg))->cmd_discr) == CMD_DISCR_TLV_ENCAP) 46 #define GET_TLV_DATA(tlv) ((void *)&((uint8_t *)(tlv))[TLV_BYTES]) 47 48 static inline u8 __get_cmdq_base_opcode(struct cmdq_base *req, u32 size) 49 { 50 if (HAS_TLV_HEADER(req) && size > TLV_BYTES) 51 return ((struct cmdq_base *)GET_TLV_DATA(req))->opcode; 52 else 53 return req->opcode; 54 } 55 56 static inline void __set_cmdq_base_opcode(struct cmdq_base *req, 57 u32 size, u8 val) 58 { 59 if (HAS_TLV_HEADER(req) && size > TLV_BYTES) 60 ((struct cmdq_base *)GET_TLV_DATA(req))->opcode = val; 61 else 62 req->opcode = val; 63 } 64 65 static inline __le16 __get_cmdq_base_cookie(struct cmdq_base *req, u32 size) 66 { 67 if (HAS_TLV_HEADER(req) && size > TLV_BYTES) 68 return ((struct cmdq_base *)GET_TLV_DATA(req))->cookie; 69 else 70 return req->cookie; 71 } 72 73 static inline void __set_cmdq_base_cookie(struct cmdq_base *req, 74 u32 size, __le16 val) 75 { 76 if (HAS_TLV_HEADER(req) && size > TLV_BYTES) 77 ((struct cmdq_base *)GET_TLV_DATA(req))->cookie = val; 78 else 79 req->cookie = val; 80 } 81 82 static inline __le64 __get_cmdq_base_resp_addr(struct cmdq_base *req, u32 size) 83 { 84 if (HAS_TLV_HEADER(req) && size > TLV_BYTES) 85 return ((struct cmdq_base *)GET_TLV_DATA(req))->resp_addr; 86 else 87 return req->resp_addr; 88 } 89 90 static inline void __set_cmdq_base_resp_addr(struct cmdq_base *req, 91 u32 size, __le64 val) 92 { 93 if (HAS_TLV_HEADER(req) && size > TLV_BYTES) 94 ((struct cmdq_base *)GET_TLV_DATA(req))->resp_addr = val; 95 else 96 req->resp_addr = val; 97 } 98 99 static inline u8 __get_cmdq_base_resp_size(struct cmdq_base *req, u32 size) 100 { 101 if (HAS_TLV_HEADER(req) && size > TLV_BYTES) 102 return ((struct cmdq_base *)GET_TLV_DATA(req))->resp_size; 103 else 104 return req->resp_size; 105 } 106 107 static inline void __set_cmdq_base_resp_size(struct cmdq_base *req, 108 u32 size, u8 val) 109 { 110 if (HAS_TLV_HEADER(req) && size > TLV_BYTES) 111 ((struct cmdq_base *)GET_TLV_DATA(req))->resp_size = val; 112 else 113 req->resp_size = val; 114 } 115 116 static inline u8 __get_cmdq_base_cmd_size(struct cmdq_base *req, u32 size) 117 { 118 if (HAS_TLV_HEADER(req) && size > TLV_BYTES) 119 return ((struct roce_tlv *)(req))->total_size; 120 else 121 return req->cmd_size; 122 } 123 124 static inline void __set_cmdq_base_cmd_size(struct cmdq_base *req, 125 u32 size, u8 val) 126 { 127 if (HAS_TLV_HEADER(req) && size > TLV_BYTES) 128 ((struct cmdq_base *)GET_TLV_DATA(req))->cmd_size = val; 129 else 130 req->cmd_size = val; 131 } 132 133 static inline __le16 __get_cmdq_base_flags(struct cmdq_base *req, u32 size) 134 { 135 if (HAS_TLV_HEADER(req) && size > TLV_BYTES) 136 return ((struct cmdq_base *)GET_TLV_DATA(req))->flags; 137 else 138 return req->flags; 139 } 140 141 static inline void __set_cmdq_base_flags(struct cmdq_base *req, 142 u32 size, __le16 val) 143 { 144 if (HAS_TLV_HEADER(req) && size > TLV_BYTES) 145 ((struct cmdq_base *)GET_TLV_DATA(req))->flags = val; 146 else 147 req->flags = val; 148 } 149 150 struct bnxt_qplib_tlv_modify_cc_req { 151 struct roce_tlv tlv_hdr; 152 struct cmdq_modify_roce_cc base_req; 153 __le64 tlvpad; 154 struct cmdq_modify_roce_cc_gen1_tlv ext_req; 155 }; 156 157 struct bnxt_qplib_tlv_query_rcc_sb { 158 struct roce_tlv tlv_hdr; 159 struct creq_query_roce_cc_resp_sb base_sb; 160 struct creq_query_roce_cc_gen1_resp_sb_tlv gen1_sb; 161 }; 162 #endif /* __QPLIB_TLV_H__ */ 163