iproc_mbox.h (7956B)
1 /* 2 * 3 * This license is set out in https://raw.githubusercontent.com/Broadcom-Network-Switching-Software/OpenBCM/master/Legal/LICENSE file. 4 * 5 * Copyright 2007-2019 Broadcom Inc. All rights reserved. 6 * 7 * File: iproc_mbox.h 8 * Purpose: iproc M0SSQ communication protocol message format and APIs 9 */ 10 #ifndef __IPROC_MBOX_H__ 11 #define __IPROC_MBOX_H__ 12 #if defined(BCM_CMICX_SUPPORT) || defined(CMICX_FW_BUILD) 13 #include <shared/cmicfw/iproc_m0ssq.h> 14 15 /* Iproc mailbox message flags */ 16 #define IPROC_SYNC_MSG 0x1 17 #define IPROC_RESP_REQUIRED 0x2 18 #define IPROC_RESP_READY 0x4 19 #define IPROC_RESP_SUCCESS 0x8 20 #define IPROC_ASYNC_STATUS 0x10 21 22 #define IPROC_MBOX_READ_RETRY_COUNT 5000 23 #define IPROC_MBOX_SLEEP_DELAY 250 /* in usecs */ 24 25 #define IPROC_MAX_MBOX 16 26 #define IPROC_MAX_TYPE 2 27 28 /* Mbox Types */ 29 #ifndef CMICX_FW_BUILD 30 #define IPROC_MBOX_TYPE_RX 0 31 #define IPROC_MBOX_TYPE_TX 1 32 #else 33 #define IPROC_MBOX_TYPE_RX 1 34 #define IPROC_MBOX_TYPE_TX 0 35 #endif /* CMICX_FW_BUILD */ 36 37 typedef enum soc_iproc_msg_rtncode_e { 38 IPROC_MSG_SUCCESS = 0, 39 IPROC_MBOX_ERR_FULL = -1, 40 IPROC_MBOX_ERR_EMPTY = -2, 41 IPROC_MBOX_ERR_INTERNAL = -3, 42 IPROC_MBOX_ERR_INVCMD = -4, 43 IPROC_MBOX_ERR_INVPARAM = -5, 44 IPROC_MBOX_ERR_ALLOC = -6 45 } soc_iproc_msg_rtncode_t; 46 47 #ifndef CMICX_FW_BUILD 48 typedef sal_mutex_t soc_iproc_mbox_lock_t; 49 #else 50 typedef uint32 soc_iproc_mbox_lock_t; 51 #endif /* CMICX_FW_BUILD */ 52 53 typedef int (*soc_iproc_msg_hndlr_t)(void *); 54 55 typedef struct soc_iproc_mbox_ptr_s { 56 uint32 head; 57 uint32 tail; 58 } soc_iproc_mbox_ptr_t; 59 60 /* Iproc mailbox */ 61 typedef struct soc_iproc_mbox_info_s { 62 uint32 base; 63 uint32 limit; 64 uint32 unit; 65 uint32 mbox; 66 uint32 maxent; 67 uint32 inuse; 68 soc_iproc_mbox_lock_t lock; 69 soc_iproc_mbox_ptr_t *ptr; 70 soc_iproc_msg_hndlr_t msg_handler; 71 void *msg_handler_param; 72 } soc_iproc_mbox_info_t; 73 74 typedef struct soc_iproc_mbox_config_s { 75 int max_ucores; 76 int nucores_enabled; 77 int max_mboxs[MAX_UCORES]; 78 } soc_iproc_mbox_config_t; 79 80 /* Iproc mailbox message format */ 81 typedef struct soc_iproc_mbox_msg_s { 82 uint32 flags; /* Flags to identify the message type */ 83 uint32 id; /* Message identifier */ 84 uint32 size; /* Number of 32 bit words in the message payload */ 85 uint32 tag0; /* Lower 32bit of 64 bit metadata preserved to use it while handling response */ 86 uint32 tag1; /* Upper 32bit of 64 bit metadata preserved to use it while handling response */ 87 uint32 data[1]; /* Variable size message payload */ 88 } __attribute__ ((packed)) soc_iproc_mbox_msg_t; 89 90 #define IPROC_MSG_HDRSZ ((sizeof(soc_iproc_mbox_msg_t) - sizeof(uint32)) / sizeof(uint32)) 91 #define IPROC_MBOX_PTR(chan) chan->ptr 92 #define IPROC_MBOX_MAX_ENT(chan) chan->maxent 93 #define IPROC_MSG_SIZE(msg) (msg->size + IPROC_MSG_HDRSZ) 94 #define IPROC_MBOX_BASE(chan) chan->base 95 #define IPROC_MBOX_START_IDX (sizeof(soc_iproc_mbox_ptr_t) / sizeof(uint32)) 96 97 /* 98 * Each IPROC MBOX is implemented as a circular ring buffer of 2048 bytes total. 99 * Each entry is 4 bytes and hence max entry is 512 (indexed from 0 to 511) 100 * The first 2 entries are store head and tail entry indices, hence total usable indices are 2 - 511. 101 * MBOX is full if the given size (no. of entries) cannot fit in the available free space entries. 102 */ 103 #ifndef CMICX_FW_BUILD 104 105 #define IPROC_MBOX_HEAD(chan, mbox) (soc_m0ssq_sram_read32(chan->unit, ((unsigned long)&mbox->head - soc_iproc_sram_membase_get(chan->unit)))) 106 #define IPROC_MBOX_TAIL(chan, mbox) (soc_m0ssq_sram_read32(chan->unit, ((unsigned long)&mbox->tail - soc_iproc_sram_membase_get(chan->unit)))) 107 108 #define MOVE_IPROC_MBOX_HEAD(chan, mbox, size) \ 109 { \ 110 soc_m0ssq_sram_write32(chan->unit, ((unsigned long)&mbox->head - soc_iproc_sram_membase_get(chan->unit)), \ 111 ((IPROC_MBOX_HEAD(chan, mbox) + size) >= IPROC_MBOX_MAX_ENT(chan)) ? \ 112 ((IPROC_MBOX_HEAD(chan, mbox) + size) % (IPROC_MBOX_MAX_ENT(chan)) + IPROC_MBOX_START_IDX) : \ 113 (IPROC_MBOX_HEAD(chan, mbox) + size)); \ 114 } 115 #define MOVE_IPROC_MBOX_TAIL(chan, mbox, size) \ 116 { \ 117 soc_m0ssq_sram_write32(chan->unit, ((unsigned long)&mbox->tail - soc_iproc_sram_membase_get(chan->unit)), \ 118 ((IPROC_MBOX_TAIL(chan, mbox) + size) >= IPROC_MBOX_MAX_ENT(chan)) ? \ 119 ((IPROC_MBOX_TAIL(chan, mbox) + size) % (IPROC_MBOX_MAX_ENT(chan)) + IPROC_MBOX_START_IDX) : \ 120 (IPROC_MBOX_TAIL(chan, mbox) + size)); \ 121 } 122 123 static inline int 124 _iproc_mbox_full(soc_iproc_mbox_info_t *chan, 125 soc_iproc_mbox_ptr_t *mbox, 126 int size) 127 { 128 uint32 tail, head; 129 tail = IPROC_MBOX_TAIL(chan, mbox); 130 head = IPROC_MBOX_HEAD(chan, mbox); 131 132 if (tail < head) { 133 return (tail + size) >= head; 134 } else { 135 return (tail - head + size) >= (IPROC_MBOX_MAX_ENT(chan) - IPROC_MBOX_START_IDX); 136 } 137 } 138 139 #define IPROC_MBOX_FULL(chan, mbox, size) _iproc_mbox_full(chan, mbox, size) 140 141 #define IPROC_MBOX_EMPTY(chan, mbox) (IPROC_MBOX_HEAD(chan, mbox) == IPROC_MBOX_TAIL(chan, mbox)) 142 143 #else 144 #define IPROC_MBOX_INTERVAL (30) /* msecs */ 145 #define IPROC_MBOX_HEAD(mbox) mbox->head 146 #define IPROC_MBOX_TAIL(mbox) mbox->tail 147 #define IPROC_MBOX_MAX_ENT(chan) chan->maxent 148 #define MOVE_IPROC_MBOX_TAIL(chan, mbox, size) \ 149 { \ 150 mbox->tail = ((mbox->tail + size) >= chan->maxent) ? (((mbox->tail + size) % chan->maxent) + IPROC_MBOX_START_IDX) : (mbox->tail + size); \ 151 } 152 153 #define MOVE_IPROC_MBOX_HEAD(chan, mbox, size) \ 154 { \ 155 mbox->head = ((mbox->head + size) >= chan->maxent) ? (((mbox->head + size) % chan->maxent) + IPROC_MBOX_START_IDX) : (mbox->head + size); \ 156 } 157 158 #define IPROC_MBOX_EMPTY(mbox) (mbox->head == mbox->tail) 159 160 static inline int 161 _iproc_mbox_full(soc_iproc_mbox_info_t *chan, 162 soc_iproc_mbox_ptr_t *mbox, 163 int size) 164 { 165 uint32 tail, head; 166 tail = IPROC_MBOX_TAIL(mbox); 167 head = IPROC_MBOX_HEAD(mbox); 168 169 if (tail < head) { 170 return (tail + size) >= head; 171 } else { 172 return (tail - head + size) >= (IPROC_MBOX_MAX_ENT(chan) - IPROC_MBOX_START_IDX); 173 } 174 } 175 176 #define IPROC_MBOX_FULL(chan, mbox, size) _iproc_mbox_full(chan, mbox, size) 177 178 #endif /* !CMICX_FW_BUILD */ 179 180 #define IS_SYNC_IPROC_MSG(msg) (msg->flags & IPROC_SYNC_MSG) 181 #define IS_IPROC_RESP_REQD(msg) (msg->flags & IPROC_RESP_REQUIRED) 182 #define IS_IPROC_RESP_READY(msg) (msg->flags & IPROC_RESP_READY) 183 #define IS_IPROC_RESP_SUCCESS(msg) (msg->flags & IPROC_RESP_SUCCESS) 184 #define IS_ASYNC_IPROC_STATUS(msg) (msg->flags & IPROC_ASYNC_STATUS) 185 186 #define IPROC_MSG_FLAG_SET(msg, flag) (msg->flags |= flag) 187 #define IPROC_MSG_FLAG_CLEAR(msg, flag) (msg->flags &= ~flag) 188 189 /* Iproc mailbox APIs */ 190 int soc_iproc_mbox_init(int unit); 191 int soc_iproc_mbox_exit(int unit); 192 soc_iproc_mbox_info_t *soc_iproc_tx_mbox_get(int unit, int mboxid); 193 soc_iproc_mbox_info_t *soc_iproc_rx_mbox_get(int unit, int mboxid); 194 int soc_iproc_mbox_alloc(int unit, int app_id); 195 int soc_iproc_mbox_free(int unit, int mbox_id); 196 int soc_iproc_data_send_nowait(soc_iproc_mbox_info_t *chan, soc_iproc_mbox_msg_t *msg); 197 int soc_iproc_data_recv(soc_iproc_mbox_info_t *chan, soc_iproc_mbox_msg_t **msg); 198 int soc_iproc_data_send_wait(soc_iproc_mbox_info_t *chan, soc_iproc_mbox_msg_t *cmd, soc_iproc_mbox_msg_t *resp); 199 int soc_iproc_mbox_handler_register(int unit, int id, soc_iproc_msg_hndlr_t hndlr, void *param); 200 int soc_iproc_resp_send(soc_iproc_mbox_info_t *chan, soc_iproc_mbox_msg_t *resp, int didx); 201 int soc_iproc_msgintr_handler(int unit, void *param); 202 void _soc_iproc_fw_config(int unit); 203 int _soc_iproc_num_mbox_get(int unit, int ucnum); 204 int _soc_iproc_num_ucore_get(int unit); 205 #endif /* defined(BCM_CMICX_SUPPORT) || defined(CMICX_FW_BUILD) */ 206 #endif /* __IPROC_MBOX_H__ */