Lines Matching +full:mbox +full:-
1 // SPDX-License-Identifier: GPL-2.0
13 #include "mbox.h"
18 void __otx2_mbox_reset(struct otx2_mbox *mbox, int devid) in __otx2_mbox_reset() argument
20 struct otx2_mbox_dev *mdev = &mbox->dev[devid]; in __otx2_mbox_reset()
22 void *hw_mbase = mdev->hwbase; in __otx2_mbox_reset()
24 tx_hdr = hw_mbase + mbox->tx_start; in __otx2_mbox_reset()
25 rx_hdr = hw_mbase + mbox->rx_start; in __otx2_mbox_reset()
27 mdev->msg_size = 0; in __otx2_mbox_reset()
28 mdev->rsp_size = 0; in __otx2_mbox_reset()
29 tx_hdr->num_msgs = 0; in __otx2_mbox_reset()
30 tx_hdr->msg_size = 0; in __otx2_mbox_reset()
31 rx_hdr->num_msgs = 0; in __otx2_mbox_reset()
32 rx_hdr->msg_size = 0; in __otx2_mbox_reset()
36 void otx2_mbox_reset(struct otx2_mbox *mbox, int devid) in otx2_mbox_reset() argument
38 struct otx2_mbox_dev *mdev = &mbox->dev[devid]; in otx2_mbox_reset()
40 spin_lock(&mdev->mbox_lock); in otx2_mbox_reset()
41 __otx2_mbox_reset(mbox, devid); in otx2_mbox_reset()
42 spin_unlock(&mdev->mbox_lock); in otx2_mbox_reset()
46 void otx2_mbox_destroy(struct otx2_mbox *mbox) in otx2_mbox_destroy() argument
48 mbox->reg_base = NULL; in otx2_mbox_destroy()
49 mbox->hwbase = NULL; in otx2_mbox_destroy()
51 kfree(mbox->dev); in otx2_mbox_destroy()
52 mbox->dev = NULL; in otx2_mbox_destroy()
56 static int otx2_mbox_setup(struct otx2_mbox *mbox, struct pci_dev *pdev, in otx2_mbox_setup() argument
62 mbox->tx_start = MBOX_DOWN_TX_START; in otx2_mbox_setup()
63 mbox->rx_start = MBOX_DOWN_RX_START; in otx2_mbox_setup()
64 mbox->tx_size = MBOX_DOWN_TX_SIZE; in otx2_mbox_setup()
65 mbox->rx_size = MBOX_DOWN_RX_SIZE; in otx2_mbox_setup()
69 mbox->tx_start = MBOX_DOWN_RX_START; in otx2_mbox_setup()
70 mbox->rx_start = MBOX_DOWN_TX_START; in otx2_mbox_setup()
71 mbox->tx_size = MBOX_DOWN_RX_SIZE; in otx2_mbox_setup()
72 mbox->rx_size = MBOX_DOWN_TX_SIZE; in otx2_mbox_setup()
76 mbox->tx_start = MBOX_UP_TX_START; in otx2_mbox_setup()
77 mbox->rx_start = MBOX_UP_RX_START; in otx2_mbox_setup()
78 mbox->tx_size = MBOX_UP_TX_SIZE; in otx2_mbox_setup()
79 mbox->rx_size = MBOX_UP_RX_SIZE; in otx2_mbox_setup()
83 mbox->tx_start = MBOX_UP_RX_START; in otx2_mbox_setup()
84 mbox->rx_start = MBOX_UP_TX_START; in otx2_mbox_setup()
85 mbox->tx_size = MBOX_UP_RX_SIZE; in otx2_mbox_setup()
86 mbox->rx_size = MBOX_UP_TX_SIZE; in otx2_mbox_setup()
89 return -ENODEV; in otx2_mbox_setup()
95 mbox->trigger = RVU_AF_AFPF_MBOX0; in otx2_mbox_setup()
96 mbox->tr_shift = 4; in otx2_mbox_setup()
100 mbox->trigger = RVU_PF_PFAF_MBOX1; in otx2_mbox_setup()
101 mbox->tr_shift = 0; in otx2_mbox_setup()
105 mbox->trigger = RVU_PF_VFX_PFVF_MBOX0; in otx2_mbox_setup()
106 mbox->tr_shift = 12; in otx2_mbox_setup()
110 mbox->trigger = RVU_VF_VFPF_MBOX1; in otx2_mbox_setup()
111 mbox->tr_shift = 0; in otx2_mbox_setup()
114 return -ENODEV; in otx2_mbox_setup()
117 mbox->reg_base = reg_base; in otx2_mbox_setup()
118 mbox->pdev = pdev; in otx2_mbox_setup()
120 mbox->dev = kcalloc(ndevs, sizeof(struct otx2_mbox_dev), GFP_KERNEL); in otx2_mbox_setup()
121 if (!mbox->dev) { in otx2_mbox_setup()
122 otx2_mbox_destroy(mbox); in otx2_mbox_setup()
123 return -ENOMEM; in otx2_mbox_setup()
125 mbox->ndevs = ndevs; in otx2_mbox_setup()
130 int otx2_mbox_init(struct otx2_mbox *mbox, void *hwbase, struct pci_dev *pdev, in otx2_mbox_init() argument
136 err = otx2_mbox_setup(mbox, pdev, reg_base, direction, ndevs); in otx2_mbox_init()
140 mbox->hwbase = hwbase; in otx2_mbox_init()
143 mdev = &mbox->dev[devid]; in otx2_mbox_init()
144 mdev->mbase = mbox->hwbase + (devid * MBOX_SIZE); in otx2_mbox_init()
145 mdev->hwbase = mdev->mbase; in otx2_mbox_init()
146 spin_lock_init(&mdev->mbox_lock); in otx2_mbox_init()
148 otx2_mbox_reset(mbox, devid); in otx2_mbox_init()
158 int otx2_mbox_regions_init(struct otx2_mbox *mbox, void **hwbase, in otx2_mbox_regions_init() argument
165 err = otx2_mbox_setup(mbox, pdev, reg_base, direction, ndevs); in otx2_mbox_regions_init()
169 mbox->hwbase = hwbase[0]; in otx2_mbox_regions_init()
175 mdev = &mbox->dev[devid]; in otx2_mbox_regions_init()
176 mdev->mbase = hwbase[devid]; in otx2_mbox_regions_init()
177 mdev->hwbase = hwbase[devid]; in otx2_mbox_regions_init()
178 spin_lock_init(&mdev->mbox_lock); in otx2_mbox_regions_init()
180 otx2_mbox_reset(mbox, devid); in otx2_mbox_regions_init()
187 int otx2_mbox_wait_for_rsp(struct otx2_mbox *mbox, int devid) in otx2_mbox_wait_for_rsp() argument
190 struct otx2_mbox_dev *mdev = &mbox->dev[devid]; in otx2_mbox_wait_for_rsp()
191 struct device *sender = &mbox->pdev->dev; in otx2_mbox_wait_for_rsp()
194 if (mdev->num_msgs == mdev->msgs_acked) in otx2_mbox_wait_for_rsp()
199 return -EIO; in otx2_mbox_wait_for_rsp()
203 int otx2_mbox_busy_poll_for_rsp(struct otx2_mbox *mbox, int devid) in otx2_mbox_busy_poll_for_rsp() argument
205 struct otx2_mbox_dev *mdev = &mbox->dev[devid]; in otx2_mbox_busy_poll_for_rsp()
209 if (mdev->num_msgs == mdev->msgs_acked) in otx2_mbox_busy_poll_for_rsp()
213 return -EIO; in otx2_mbox_busy_poll_for_rsp()
217 static void otx2_mbox_msg_send_data(struct otx2_mbox *mbox, int devid, u64 data) in otx2_mbox_msg_send_data() argument
219 struct otx2_mbox_dev *mdev = &mbox->dev[devid]; in otx2_mbox_msg_send_data()
221 void *hw_mbase = mdev->hwbase; in otx2_mbox_msg_send_data()
224 tx_hdr = hw_mbase + mbox->tx_start; in otx2_mbox_msg_send_data()
225 rx_hdr = hw_mbase + mbox->rx_start; in otx2_mbox_msg_send_data()
227 /* If bounce buffer is implemented copy mbox messages from in otx2_mbox_msg_send_data()
228 * bounce buffer to hw mbox memory. in otx2_mbox_msg_send_data()
230 if (mdev->mbase != hw_mbase) in otx2_mbox_msg_send_data()
231 memcpy(hw_mbase + mbox->tx_start + msgs_offset, in otx2_mbox_msg_send_data()
232 mdev->mbase + mbox->tx_start + msgs_offset, in otx2_mbox_msg_send_data()
233 mdev->msg_size); in otx2_mbox_msg_send_data()
235 spin_lock(&mdev->mbox_lock); in otx2_mbox_msg_send_data()
237 tx_hdr->msg_size = mdev->msg_size; in otx2_mbox_msg_send_data()
240 mdev->msg_size = 0; in otx2_mbox_msg_send_data()
241 mdev->rsp_size = 0; in otx2_mbox_msg_send_data()
242 mdev->msgs_acked = 0; in otx2_mbox_msg_send_data()
244 /* Sync mbox data into memory */ in otx2_mbox_msg_send_data()
251 tx_hdr->num_msgs = mdev->num_msgs; in otx2_mbox_msg_send_data()
252 rx_hdr->num_msgs = 0; in otx2_mbox_msg_send_data()
254 trace_otx2_msg_send(mbox->pdev, tx_hdr->num_msgs, tx_hdr->msg_size); in otx2_mbox_msg_send_data()
256 spin_unlock(&mdev->mbox_lock); in otx2_mbox_msg_send_data()
259 intr_val = readq((void __iomem *)mbox->reg_base + in otx2_mbox_msg_send_data()
260 (mbox->trigger | (devid << mbox->tr_shift))); in otx2_mbox_msg_send_data()
266 writeq(intr_val, (void __iomem *)mbox->reg_base + in otx2_mbox_msg_send_data()
267 (mbox->trigger | (devid << mbox->tr_shift))); in otx2_mbox_msg_send_data()
270 void otx2_mbox_msg_send(struct otx2_mbox *mbox, int devid) in otx2_mbox_msg_send() argument
272 otx2_mbox_msg_send_data(mbox, devid, MBOX_DOWN_MSG); in otx2_mbox_msg_send()
276 void otx2_mbox_msg_send_up(struct otx2_mbox *mbox, int devid) in otx2_mbox_msg_send_up() argument
278 otx2_mbox_msg_send_data(mbox, devid, MBOX_UP_MSG); in otx2_mbox_msg_send_up()
282 bool otx2_mbox_wait_for_zero(struct otx2_mbox *mbox, int devid) in otx2_mbox_wait_for_zero() argument
286 data = readq((void __iomem *)mbox->reg_base + in otx2_mbox_wait_for_zero()
287 (mbox->trigger | (devid << mbox->tr_shift))); in otx2_mbox_wait_for_zero()
289 /* If data is non-zero wait for ~1ms and return to caller in otx2_mbox_wait_for_zero()
297 data = readq((void __iomem *)mbox->reg_base + in otx2_mbox_wait_for_zero()
298 (mbox->trigger | (devid << mbox->tr_shift))); in otx2_mbox_wait_for_zero()
304 struct mbox_msghdr *otx2_mbox_alloc_msg_rsp(struct otx2_mbox *mbox, int devid, in otx2_mbox_alloc_msg_rsp() argument
307 struct otx2_mbox_dev *mdev = &mbox->dev[devid]; in otx2_mbox_alloc_msg_rsp()
310 spin_lock(&mdev->mbox_lock); in otx2_mbox_alloc_msg_rsp()
314 if ((mdev->msg_size + size) > mbox->tx_size - msgs_offset) in otx2_mbox_alloc_msg_rsp()
316 if ((mdev->rsp_size + size_rsp) > mbox->rx_size - msgs_offset) in otx2_mbox_alloc_msg_rsp()
319 if (mdev->msg_size == 0) in otx2_mbox_alloc_msg_rsp()
320 mdev->num_msgs = 0; in otx2_mbox_alloc_msg_rsp()
321 mdev->num_msgs++; in otx2_mbox_alloc_msg_rsp()
323 msghdr = mdev->mbase + mbox->tx_start + msgs_offset + mdev->msg_size; in otx2_mbox_alloc_msg_rsp()
328 msghdr->ver = OTX2_MBOX_VERSION; in otx2_mbox_alloc_msg_rsp()
329 mdev->msg_size += size; in otx2_mbox_alloc_msg_rsp()
330 mdev->rsp_size += size_rsp; in otx2_mbox_alloc_msg_rsp()
331 msghdr->next_msgoff = mdev->msg_size + msgs_offset; in otx2_mbox_alloc_msg_rsp()
333 spin_unlock(&mdev->mbox_lock); in otx2_mbox_alloc_msg_rsp()
339 struct mbox_msghdr *otx2_mbox_get_rsp(struct otx2_mbox *mbox, int devid, in otx2_mbox_get_rsp() argument
342 unsigned long imsg = mbox->tx_start + msgs_offset; in otx2_mbox_get_rsp()
343 unsigned long irsp = mbox->rx_start + msgs_offset; in otx2_mbox_get_rsp()
344 struct otx2_mbox_dev *mdev = &mbox->dev[devid]; in otx2_mbox_get_rsp()
347 spin_lock(&mdev->mbox_lock); in otx2_mbox_get_rsp()
349 if (mdev->num_msgs != mdev->msgs_acked) in otx2_mbox_get_rsp()
352 for (msgs = 0; msgs < mdev->msgs_acked; msgs++) { in otx2_mbox_get_rsp()
353 struct mbox_msghdr *pmsg = mdev->mbase + imsg; in otx2_mbox_get_rsp()
354 struct mbox_msghdr *prsp = mdev->mbase + irsp; in otx2_mbox_get_rsp()
357 if (pmsg->id != prsp->id) in otx2_mbox_get_rsp()
359 spin_unlock(&mdev->mbox_lock); in otx2_mbox_get_rsp()
363 imsg = mbox->tx_start + pmsg->next_msgoff; in otx2_mbox_get_rsp()
364 irsp = mbox->rx_start + prsp->next_msgoff; in otx2_mbox_get_rsp()
368 spin_unlock(&mdev->mbox_lock); in otx2_mbox_get_rsp()
369 return ERR_PTR(-ENODEV); in otx2_mbox_get_rsp()
373 int otx2_mbox_check_rsp_msgs(struct otx2_mbox *mbox, int devid) in otx2_mbox_check_rsp_msgs() argument
375 unsigned long ireq = mbox->tx_start + msgs_offset; in otx2_mbox_check_rsp_msgs()
376 unsigned long irsp = mbox->rx_start + msgs_offset; in otx2_mbox_check_rsp_msgs()
377 struct otx2_mbox_dev *mdev = &mbox->dev[devid]; in otx2_mbox_check_rsp_msgs()
378 int rc = -ENODEV; in otx2_mbox_check_rsp_msgs()
381 spin_lock(&mdev->mbox_lock); in otx2_mbox_check_rsp_msgs()
383 if (mdev->num_msgs != mdev->msgs_acked) in otx2_mbox_check_rsp_msgs()
386 for (msgs = 0; msgs < mdev->msgs_acked; msgs++) { in otx2_mbox_check_rsp_msgs()
387 struct mbox_msghdr *preq = mdev->mbase + ireq; in otx2_mbox_check_rsp_msgs()
388 struct mbox_msghdr *prsp = mdev->mbase + irsp; in otx2_mbox_check_rsp_msgs()
390 if (preq->id != prsp->id) { in otx2_mbox_check_rsp_msgs()
391 trace_otx2_msg_check(mbox->pdev, preq->id, in otx2_mbox_check_rsp_msgs()
392 prsp->id, prsp->rc); in otx2_mbox_check_rsp_msgs()
395 if (prsp->rc) { in otx2_mbox_check_rsp_msgs()
396 rc = prsp->rc; in otx2_mbox_check_rsp_msgs()
397 trace_otx2_msg_check(mbox->pdev, preq->id, in otx2_mbox_check_rsp_msgs()
398 prsp->id, prsp->rc); in otx2_mbox_check_rsp_msgs()
402 ireq = mbox->tx_start + preq->next_msgoff; in otx2_mbox_check_rsp_msgs()
403 irsp = mbox->rx_start + prsp->next_msgoff; in otx2_mbox_check_rsp_msgs()
407 spin_unlock(&mdev->mbox_lock); in otx2_mbox_check_rsp_msgs()
413 otx2_reply_invalid_msg(struct otx2_mbox *mbox, int devid, u16 pcifunc, u16 id) in otx2_reply_invalid_msg() argument
418 otx2_mbox_alloc_msg(mbox, devid, sizeof(*rsp)); in otx2_reply_invalid_msg()
420 return -ENOMEM; in otx2_reply_invalid_msg()
421 rsp->hdr.id = id; in otx2_reply_invalid_msg()
422 rsp->hdr.sig = OTX2_MBOX_RSP_SIG; in otx2_reply_invalid_msg()
423 rsp->hdr.rc = MBOX_MSG_INVALID; in otx2_reply_invalid_msg()
424 rsp->hdr.pcifunc = pcifunc; in otx2_reply_invalid_msg()
429 bool otx2_mbox_nonempty(struct otx2_mbox *mbox, int devid) in otx2_mbox_nonempty() argument
431 struct otx2_mbox_dev *mdev = &mbox->dev[devid]; in otx2_mbox_nonempty()
434 spin_lock(&mdev->mbox_lock); in otx2_mbox_nonempty()
435 ret = mdev->num_msgs != 0; in otx2_mbox_nonempty()
436 spin_unlock(&mdev->mbox_lock); in otx2_mbox_nonempty()
455 MODULE_DESCRIPTION("Marvell RVU NIC Mbox helpers");