openbcm

Git mirror of https://github.com/Broadcom-Network-Switching-Software/OpenBCM
git clone git://git.finwo.net/mirror/broadcom/openbcm
Log | Files | Refs | README

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__ */