| b.liu | e958203 | 2025-04-17 19:18:16 +0800 | [diff] [blame] | 1 | From 72a6312eda9b142ac5910e5f4b652fa8ae8d222d Mon Sep 17 00:00:00 2001 |
| 2 | From: Roy Pledge <roy.pledge@nxp.com> |
| 3 | Date: Thu, 25 Oct 2018 16:55:53 -0400 |
| 4 | Subject: [PATCH] soc: fsl: dpio: Fix order restoration API for QBMan 5.0 |
| 5 | |
| 6 | The mechanism for indicating to HW that a frame was dropped |
| 7 | when performing HW order restoration changed in QBMan 5.0 to |
| 8 | use a management command instead of a special enqueue command. |
| 9 | This patch implements that change when running on a QBMan 5.0 |
| 10 | and above device. |
| 11 | |
| 12 | Signed-off-by: Roy Pledge <roy.pledge@nxp.com> |
| 13 | --- |
| 14 | drivers/soc/fsl/dpio/dpio-service.c | 10 +++++++ |
| 15 | drivers/soc/fsl/dpio/qbman-portal.c | 59 ++++++++++++++++++++++++++++++++----- |
| 16 | drivers/soc/fsl/dpio/qbman-portal.h | 9 ++++++ |
| 17 | 3 files changed, 71 insertions(+), 7 deletions(-) |
| 18 | |
| 19 | --- a/drivers/soc/fsl/dpio/dpio-service.c |
| 20 | +++ b/drivers/soc/fsl/dpio/dpio-service.c |
| 21 | @@ -803,10 +803,20 @@ int dpaa2_io_service_orp_seqnum_drop(str |
| 22 | { |
| 23 | struct qbman_eq_desc ed; |
| 24 | struct dpaa2_fd fd; |
| 25 | + unsigned long irqflags; |
| 26 | + int ret; |
| 27 | |
| 28 | d = service_select(d); |
| 29 | if (!d) |
| 30 | return -ENODEV; |
| 31 | + |
| 32 | + if ((d->swp->desc->qman_version & QMAN_REV_MASK) >= QMAN_REV_5000) { |
| 33 | + spin_lock_irqsave(&d->lock_mgmt_cmd, irqflags); |
| 34 | + ret = qbman_orp_drop(d->swp, orpid, seqnum); |
| 35 | + spin_unlock_irqrestore(&d->lock_mgmt_cmd, irqflags); |
| 36 | + return ret; |
| 37 | + } |
| 38 | + |
| 39 | qbman_eq_desc_clear(&ed); |
| 40 | qbman_eq_desc_set_orp_hole(&ed, orpid, seqnum); |
| 41 | return qbman_swp_enqueue(d->swp, &ed, &fd); |
| 42 | --- a/drivers/soc/fsl/dpio/qbman-portal.c |
| 43 | +++ b/drivers/soc/fsl/dpio/qbman-portal.c |
| 44 | @@ -12,19 +12,13 @@ |
| 45 | |
| 46 | #include "qbman-portal.h" |
| 47 | |
| 48 | -#define QMAN_REV_4000 0x04000000 |
| 49 | -#define QMAN_REV_4100 0x04010000 |
| 50 | -#define QMAN_REV_4101 0x04010001 |
| 51 | -#define QMAN_REV_5000 0x05000000 |
| 52 | - |
| 53 | -#define QMAN_REV_MASK 0xffff0000 |
| 54 | - |
| 55 | /* All QBMan command and result structures use this "valid bit" encoding */ |
| 56 | #define QB_VALID_BIT ((u32)0x80) |
| 57 | |
| 58 | /* QBMan portal management command codes */ |
| 59 | #define QBMAN_MC_ACQUIRE 0x30 |
| 60 | #define QBMAN_WQCHAN_CONFIGURE 0x46 |
| 61 | +#define QBMAN_MC_ORP 0x63 |
| 62 | |
| 63 | /* CINH register offsets */ |
| 64 | #define QBMAN_CINH_SWP_EQCR_PI 0x800 |
| 65 | @@ -1246,3 +1240,54 @@ u32 qbman_bp_info_num_free_bufs(struct q |
| 66 | { |
| 67 | return le32_to_cpu(a->fill); |
| 68 | } |
| 69 | + |
| 70 | +struct qbman_orp_cmd_desc { |
| 71 | + u8 verb; |
| 72 | + u8 reserved; |
| 73 | + u8 cid; |
| 74 | + u8 reserved2; |
| 75 | + u16 orpid; |
| 76 | + u16 seqnum; |
| 77 | + u8 reserved3[56]; |
| 78 | +}; |
| 79 | + |
| 80 | +struct qbman_orp_cmd_rslt { |
| 81 | + u8 verb; |
| 82 | + u8 rslt; |
| 83 | + u8 cid; |
| 84 | + u8 reserved1[61]; |
| 85 | +}; |
| 86 | + |
| 87 | +int qbman_orp_drop(struct qbman_swp *s, u16 orpid, u16 seqnum) |
| 88 | +{ |
| 89 | + struct qbman_orp_cmd_desc *p; |
| 90 | + struct qbman_orp_cmd_rslt *r; |
| 91 | + void *resp; |
| 92 | + |
| 93 | + p = (struct qbman_orp_cmd_desc *)qbman_swp_mc_start(s); |
| 94 | + if (!p) |
| 95 | + return -EBUSY; |
| 96 | + |
| 97 | + p->cid = 0x7; |
| 98 | + p->orpid = cpu_to_le16(orpid); |
| 99 | + p->seqnum = cpu_to_le16(seqnum); |
| 100 | + |
| 101 | + resp = qbman_swp_mc_complete(s, p, QBMAN_MC_ORP); |
| 102 | + if (!resp) { |
| 103 | + pr_err("qbman: Drop sequence num %d orpid 0x%x failed, no response\n", |
| 104 | + seqnum, orpid); |
| 105 | + return -EIO; |
| 106 | + } |
| 107 | + r = (struct qbman_orp_cmd_rslt *)resp; |
| 108 | + /* Decode the outcome */ |
| 109 | + WARN_ON((r->verb & QBMAN_RESPONSE_VERB_MASK) != QBMAN_MC_ORP); |
| 110 | + |
| 111 | + /* Determine success or failure */ |
| 112 | + if (r->rslt != QBMAN_MC_RSLT_OK) { |
| 113 | + pr_err("Drop seqnum %d of prpid 0x%x failed, code=0x%02x\n", |
| 114 | + seqnum, orpid, r->rslt); |
| 115 | + return -EIO; |
| 116 | + } |
| 117 | + |
| 118 | + return 0; |
| 119 | +} |
| 120 | --- a/drivers/soc/fsl/dpio/qbman-portal.h |
| 121 | +++ b/drivers/soc/fsl/dpio/qbman-portal.h |
| 122 | @@ -9,6 +9,13 @@ |
| 123 | |
| 124 | #include <soc/fsl/dpaa2-fd.h> |
| 125 | |
| 126 | +#define QMAN_REV_4000 0x04000000 |
| 127 | +#define QMAN_REV_4100 0x04010000 |
| 128 | +#define QMAN_REV_4101 0x04010001 |
| 129 | +#define QMAN_REV_5000 0x05000000 |
| 130 | + |
| 131 | +#define QMAN_REV_MASK 0xffff0000 |
| 132 | + |
| 133 | struct dpaa2_dq; |
| 134 | struct qbman_swp; |
| 135 | |
| 136 | @@ -178,6 +185,8 @@ void qbman_eq_desc_set_qd(struct qbman_e |
| 137 | int qbman_swp_enqueue(struct qbman_swp *p, const struct qbman_eq_desc *d, |
| 138 | const struct dpaa2_fd *fd); |
| 139 | |
| 140 | +int qbman_orp_drop(struct qbman_swp *s, u16 orpid, u16 seqnum); |
| 141 | + |
| 142 | void qbman_release_desc_clear(struct qbman_release_desc *d); |
| 143 | void qbman_release_desc_set_bpid(struct qbman_release_desc *d, u16 bpid); |
| 144 | void qbman_release_desc_set_rcdi(struct qbman_release_desc *d, int enable); |