]>
git.proxmox.com Git - ceph.git/blob - ceph/src/seastar/dpdk/drivers/common/octeontx/octeontx_mbox.c
1 /* SPDX-License-Identifier: BSD-3-Clause
2 * Copyright(c) 2017 Cavium, Inc
7 #include <rte_atomic.h>
8 #include <rte_common.h>
9 #include <rte_cycles.h>
11 #include <rte_spinlock.h>
13 #include "octeontx_mbox.h"
15 /* Mbox operation timeout in seconds */
16 #define MBOX_WAIT_TIME_SEC 3
17 #define MAX_RAM_MBOX_LEN ((SSOW_BAR4_LEN >> 1) - 8 /* Mbox header */)
19 /* Mbox channel state */
21 MBOX_CHAN_STATE_REQ
= 1,
22 MBOX_CHAN_STATE_RES
= 0,
25 /* Response messages */
29 MBOX_RET_INTERNAL_ERR
,
34 uint8_t *ram_mbox_base
; /* Base address of mbox message stored in ram */
35 uint8_t *reg
; /* Store to this register triggers PF mbox interrupt */
36 uint16_t tag_own
; /* Last tag which was written to own channel */
40 static struct mbox octeontx_mbox
;
43 * Structure used for mbox synchronization
44 * This structure sits at the begin of Mbox RAM and used as main
45 * synchronization point for channel communication
51 uint8_t chan_state
: 1;
62 int octeontx_logtype_mbox
;
64 RTE_INIT(otx_init_log
)
66 octeontx_logtype_mbox
= rte_log_register("pmd.octeontx.mbox");
67 if (octeontx_logtype_mbox
>= 0)
68 rte_log_set_level(octeontx_logtype_mbox
, RTE_LOG_NOTICE
);
72 mbox_msgcpy(volatile uint8_t *d
, volatile const uint8_t *s
, uint16_t size
)
76 for (i
= 0; i
< size
; i
++)
81 mbox_send_request(struct mbox
*m
, struct octeontx_mbox_hdr
*hdr
,
82 const void *txmsg
, uint16_t txsize
)
84 struct mbox_ram_hdr old_hdr
;
85 struct mbox_ram_hdr new_hdr
= { {0} };
86 uint64_t *ram_mbox_hdr
= (uint64_t *)m
->ram_mbox_base
;
87 uint8_t *ram_mbox_msg
= m
->ram_mbox_base
+ sizeof(struct mbox_ram_hdr
);
90 * Initialize the channel with the tag left by last send.
91 * On success full mbox send complete, PF increments the tag by one.
92 * The sender can validate integrity of PF message with this scheme
94 old_hdr
.u64
= rte_read64(ram_mbox_hdr
);
95 m
->tag_own
= (old_hdr
.tag
+ 2) & (~0x1ul
); /* next even number */
99 mbox_msgcpy(ram_mbox_msg
, txmsg
, txsize
);
101 /* Prepare new hdr */
102 new_hdr
.chan_state
= MBOX_CHAN_STATE_REQ
;
103 new_hdr
.coproc
= hdr
->coproc
;
104 new_hdr
.msg
= hdr
->msg
;
105 new_hdr
.vfid
= hdr
->vfid
;
106 new_hdr
.tag
= m
->tag_own
;
107 new_hdr
.len
= txsize
;
109 /* Write the msg header */
110 rte_write64(new_hdr
.u64
, ram_mbox_hdr
);
112 /* Notify PF about the new msg - write to MBOX reg generates PF IRQ */
113 rte_write64(0, m
->reg
);
117 mbox_wait_response(struct mbox
*m
, struct octeontx_mbox_hdr
*hdr
,
118 void *rxmsg
, uint16_t rxsize
)
122 struct mbox_ram_hdr rx_hdr
;
123 uint64_t *ram_mbox_hdr
= (uint64_t *)m
->ram_mbox_base
;
124 uint8_t *ram_mbox_msg
= m
->ram_mbox_base
+ sizeof(struct mbox_ram_hdr
);
126 /* Wait for response */
127 wait
= MBOX_WAIT_TIME_SEC
* 1000 * 10;
130 rx_hdr
.u64
= rte_read64(ram_mbox_hdr
);
131 if (rx_hdr
.chan_state
== MBOX_CHAN_STATE_RES
)
136 hdr
->res_code
= rx_hdr
.res_code
;
146 if (m
->tag_own
!= rx_hdr
.tag
) {
151 /* PF nacked the msg */
152 if (rx_hdr
.res_code
!= MBOX_RET_SUCCESS
) {
157 len
= RTE_MIN(rx_hdr
.len
, rxsize
);
159 mbox_msgcpy(rxmsg
, ram_mbox_msg
, len
);
164 mbox_log_err("Failed to send mbox(%d/%d) coproc=%d msg=%d ret=(%d,%d)",
165 m
->tag_own
, rx_hdr
.tag
, hdr
->coproc
, hdr
->msg
, res
,
171 mbox_send(struct mbox
*m
, struct octeontx_mbox_hdr
*hdr
, const void *txmsg
,
172 uint16_t txsize
, void *rxmsg
, uint16_t rxsize
)
176 if (m
->init_once
== 0 || hdr
== NULL
||
177 txsize
> MAX_RAM_MBOX_LEN
|| rxsize
> MAX_RAM_MBOX_LEN
) {
178 mbox_log_err("Invalid init_once=%d hdr=%p txsz=%d rxsz=%d",
179 m
->init_once
, hdr
, txsize
, rxsize
);
183 rte_spinlock_lock(&m
->lock
);
185 mbox_send_request(m
, hdr
, txmsg
, txsize
);
186 res
= mbox_wait_response(m
, hdr
, rxmsg
, rxsize
);
188 rte_spinlock_unlock(&m
->lock
);
193 octeontx_mbox_set_ram_mbox_base(uint8_t *ram_mbox_base
)
195 struct mbox
*m
= &octeontx_mbox
;
200 if (ram_mbox_base
== NULL
) {
201 mbox_log_err("Invalid ram_mbox_base=%p", ram_mbox_base
);
205 m
->ram_mbox_base
= ram_mbox_base
;
207 if (m
->reg
!= NULL
) {
208 rte_spinlock_init(&m
->lock
);
216 octeontx_mbox_set_reg(uint8_t *reg
)
218 struct mbox
*m
= &octeontx_mbox
;
224 mbox_log_err("Invalid reg=%p", reg
);
230 if (m
->ram_mbox_base
!= NULL
) {
231 rte_spinlock_init(&m
->lock
);
239 octeontx_mbox_send(struct octeontx_mbox_hdr
*hdr
, void *txdata
,
240 uint16_t txlen
, void *rxdata
, uint16_t rxlen
)
242 struct mbox
*m
= &octeontx_mbox
;
244 RTE_BUILD_BUG_ON(sizeof(struct mbox_ram_hdr
) != 8);
245 if (rte_eal_process_type() != RTE_PROC_PRIMARY
)
248 return mbox_send(m
, hdr
, txdata
, txlen
, rxdata
, rxlen
);