| /* |
| <:copyright-BRCM:2016:DUAL/GPL:standard |
| |
| Broadcom Proprietary and Confidential.(c) 2016 Broadcom |
| All Rights Reserved |
| |
| Unless you and Broadcom execute a separate written software license |
| agreement governing use of this software, this software is licensed |
| to you under the terms of the GNU General Public License version 2 |
| (the "GPL"), available at http://www.broadcom.com/licenses/GPLv2.php, |
| with the following added to such license: |
| |
| As a special exception, the copyright holders of this software give |
| you permission to link this software with independent modules, and |
| to copy and distribute the resulting executable under terms of your |
| choice, provided that you also meet, for each linked independent |
| module, the terms and conditions of the license of that module. |
| An independent module is a module which is not derived from this |
| software. The special exception does not apply to any modifications |
| of the software. |
| |
| Not withstanding the above, under no circumstances may you combine |
| this software in any way with any other Broadcom software provided |
| under a license other than the GPL, without Broadcom's express prior |
| written consent. |
| |
| :> |
| */ |
| |
| #ifndef BCMTR_HEADER_H_ |
| #define BCMTR_HEADER_H_ |
| |
| #include <bcmolt_buf.h> |
| #include <bcmolt_msg_pack.h> |
| |
| /** Endianess of numbers written to the transport buffer. |
| * Currently bcmolt_buf service doesn't support setting |
| * endianness dynamically. Transport buffer direction must be the same |
| * as selected at compile time in bcmolt_buf.h |
| */ |
| #define BCMTR_BUF_ENDIAN BCMOLT_BUF_ENDIAN_FIXED |
| |
| #define BCMTR_ENDIAN_CPU_TO_BUF_U32(n) BCMOLT_BUF_ENDIAN_CPU_TO_BUF(U32, n) |
| #define BCMTR_ENDIAN_BUF_TO_CPU_U32(n) BCMOLT_BUF_ENDIAN_BUF_TO_CPU(U32, n) |
| |
| /** Transport header. |
| * Inserted in each packet transmitted on the line |
| */ |
| typedef struct bcmtr_hdr |
| { |
| bcmolt_msg_dir dir; /**< Message direction: request/response */ |
| bcmos_bool more_fragments; /**< TRUE=more fragments to follow */ |
| bcmos_bool auto_proxy_reg; /**< TRUE=message is auto / proxy registration */ |
| bcmos_bool auto_proxy_unreg;/**< TRUE=message is auto / proxy un-registration */ |
| uint8_t instance; /**< Message instance */ |
| bcmolt_group_id msg_id; /**< Message id: object+group+subgroup */ |
| uint16_t corr_tag; /**< correlation tag */ |
| uint16_t frag_number; /**< fragment number */ |
| } bcmtr_hdr; |
| |
| #define BCMTR_HDR_SIZE 8 |
| |
| /* Shifts and widths of transport header fields */ |
| #define BCMTR_HDR_DIR_S 31 |
| #define BCMTR_HDR_DIR_W 1 |
| #define BCMTR_HDR_REG_S 26 |
| #define BCMTR_HDR_REG_W 1 |
| #define BCMTR_HDR_UNREG_S 25 |
| #define BCMTR_HDR_UNREG_W 1 |
| #define BCMTR_HDR_MORE_FRAGS_S 24 |
| #define BCMTR_HDR_MORE_FRAGS_W 1 |
| #define BCMTR_HDR_INSTANCE_S 16 |
| #define BCMTR_HDR_INSTANCE_W 8 |
| #define BCMTR_HDR_MSG_ID_S 0 |
| #define BCMTR_HDR_MSG_ID_W 16 |
| #define BCMTR_HDR_CORR_TAG_S 16 |
| #define BCMTR_HDR_CORR_TAG_W 16 |
| #define BCMTR_HDR_FRAG_S 0 |
| #define BCMTR_HDR_FRAG_W 16 |
| |
| /* Pack transport header |
| * |
| * \param[in] hdr Unpacked transport header |
| * \param[out] packed_hdr Packed header |
| */ |
| static inline void bcmtr_header_pack(const bcmtr_hdr *hdr, uint8_t *packed_hdr) |
| { |
| uint32_t w[2]; |
| |
| w[0] = (hdr->dir << BCMTR_HDR_DIR_S) | |
| (hdr->more_fragments << BCMTR_HDR_MORE_FRAGS_S) | |
| (hdr->instance << BCMTR_HDR_INSTANCE_S) | |
| (hdr->auto_proxy_reg << BCMTR_HDR_REG_S) | |
| (hdr->auto_proxy_unreg << BCMTR_HDR_UNREG_S) | |
| hdr->msg_id; |
| w[1] = (hdr->corr_tag << BCMTR_HDR_CORR_TAG_S) | hdr->frag_number; |
| w[0] = BCMTR_ENDIAN_CPU_TO_BUF_U32(w[0]); |
| w[1] = BCMTR_ENDIAN_CPU_TO_BUF_U32(w[1]); |
| memcpy(packed_hdr, w, BCMTR_HDR_SIZE); |
| } |
| |
| /* Unpack transport header |
| * |
| * \param[in] packed_hdr Packed header |
| * \param[out] hdr Unpacked transport header |
| * Buffer current pointer is incremented by the header side. |
| */ |
| static inline void bcmtr_header_unpack(const uint8_t *packed_hdr, bcmtr_hdr *hdr) |
| { |
| uint32_t w[2]; |
| memcpy(w, packed_hdr, BCMTR_HDR_SIZE); |
| w[0] = BCMTR_ENDIAN_BUF_TO_CPU_U32(w[0]); |
| w[1] = BCMTR_ENDIAN_BUF_TO_CPU_U32(w[1]); |
| hdr->dir = BCM_FIELD_GET(w[0], BCMTR_HDR_DIR); |
| hdr->more_fragments = BCM_FIELD_GET(w[0], BCMTR_HDR_MORE_FRAGS); |
| hdr->instance = BCM_FIELD_GET(w[0], BCMTR_HDR_INSTANCE); |
| hdr->msg_id = BCM_FIELD_GET(w[0], BCMTR_HDR_MSG_ID); |
| hdr->auto_proxy_reg = BCM_FIELD_GET(w[0], BCMTR_HDR_REG); |
| hdr->auto_proxy_unreg = BCM_FIELD_GET(w[0], BCMTR_HDR_UNREG); |
| hdr->corr_tag = BCM_FIELD_GET(w[1], BCMTR_HDR_CORR_TAG); |
| hdr->frag_number = BCM_FIELD_GET(w[1], BCMTR_HDR_FRAG); |
| } |
| |
| /* Fill transport header |
| */ |
| static inline bcmos_errno bcmtr_header_fill(const bcmolt_msg *msg, bcmtr_hdr *hdr) |
| { |
| bcmos_errno err; |
| |
| hdr->dir = msg->dir; |
| hdr->more_fragments = BCMOS_FALSE; |
| err = bcmolt_group_id_combine(msg->obj_type, msg->group, msg->subgroup, &hdr->msg_id); |
| if (err) |
| return err; |
| hdr->instance = bcmolt_msg_instance(msg); |
| hdr->corr_tag = msg->corr_tag; |
| hdr->frag_number = 0; |
| return BCM_ERR_OK; |
| } |
| |
| |
| #endif /* BCMTR_HEADER_H_ */ |