|
5 | 5 | #define __OTX2_CPTLF_H |
6 | 6 |
|
7 | 7 | #include <linux/soc/marvell/octeontx2/asm.h> |
| 8 | +#include <linux/bitfield.h> |
8 | 9 | #include <mbox.h> |
9 | 10 | #include <rvu.h> |
10 | 11 | #include "otx2_cpt_common.h" |
@@ -119,6 +120,7 @@ struct otx2_cptlfs_info { |
119 | 120 | u8 kvf_limits; /* Kernel crypto limits */ |
120 | 121 | atomic_t state; /* LF's state. started/reset */ |
121 | 122 | int blkaddr; /* CPT blkaddr: BLKADDR_CPT0/BLKADDR_CPT1 */ |
| 123 | + int global_slot; /* Global slot across the blocks */ |
122 | 124 | }; |
123 | 125 |
|
124 | 126 | static inline void otx2_cpt_free_instruction_queues( |
@@ -206,48 +208,71 @@ static inline void otx2_cptlf_set_iqueues_size(struct otx2_cptlfs_info *lfs) |
206 | 208 | otx2_cptlf_do_set_iqueue_size(&lfs->lf[slot]); |
207 | 209 | } |
208 | 210 |
|
| 211 | +#define INFLIGHT GENMASK_ULL(8, 0) |
| 212 | +#define GRB_CNT GENMASK_ULL(39, 32) |
| 213 | +#define GWB_CNT GENMASK_ULL(47, 40) |
| 214 | +#define XQ_XOR GENMASK_ULL(63, 63) |
| 215 | +#define DQPTR GENMASK_ULL(19, 0) |
| 216 | +#define NQPTR GENMASK_ULL(51, 32) |
| 217 | + |
209 | 218 | static inline void otx2_cptlf_do_disable_iqueue(struct otx2_cptlf_info *lf) |
210 | 219 | { |
211 | | - union otx2_cptx_lf_ctl lf_ctl = { .u = 0x0 }; |
212 | | - union otx2_cptx_lf_inprog lf_inprog; |
| 220 | + void __iomem *reg_base = lf->lfs->reg_base; |
| 221 | + struct pci_dev *pdev = lf->lfs->pdev; |
213 | 222 | u8 blkaddr = lf->lfs->blkaddr; |
214 | | - int timeout = 20; |
| 223 | + int timeout = 1000000; |
| 224 | + u64 inprog, inst_ptr; |
| 225 | + u64 slot = lf->slot; |
| 226 | + u64 qsize, pending; |
| 227 | + int i = 0; |
215 | 228 |
|
216 | 229 | /* Disable instructions enqueuing */ |
217 | | - otx2_cpt_write64(lf->lfs->reg_base, blkaddr, lf->slot, |
218 | | - OTX2_CPT_LF_CTL, lf_ctl.u); |
| 230 | + otx2_cpt_write64(reg_base, blkaddr, slot, OTX2_CPT_LF_CTL, 0x0); |
219 | 231 |
|
220 | | - /* Wait for instruction queue to become empty */ |
| 232 | + inprog = otx2_cpt_read64(reg_base, blkaddr, slot, OTX2_CPT_LF_INPROG); |
| 233 | + inprog |= BIT_ULL(16); |
| 234 | + otx2_cpt_write64(reg_base, blkaddr, slot, OTX2_CPT_LF_INPROG, inprog); |
| 235 | + |
| 236 | + qsize = otx2_cpt_read64(reg_base, blkaddr, slot, OTX2_CPT_LF_Q_SIZE) & 0x7FFF; |
| 237 | + do { |
| 238 | + inst_ptr = otx2_cpt_read64(reg_base, blkaddr, slot, OTX2_CPT_LF_Q_INST_PTR); |
| 239 | + pending = (FIELD_GET(XQ_XOR, inst_ptr) * qsize * 40) + |
| 240 | + FIELD_GET(NQPTR, inst_ptr) - FIELD_GET(DQPTR, inst_ptr); |
| 241 | + udelay(1); |
| 242 | + timeout--; |
| 243 | + } while ((pending != 0) && (timeout != 0)); |
| 244 | + |
| 245 | + if (timeout == 0) |
| 246 | + dev_warn(&pdev->dev, "TIMEOUT: CPT poll on pending instructions\n"); |
| 247 | + |
| 248 | + timeout = 1000000; |
| 249 | + /* Wait for CPT queue to become execution-quiescent */ |
221 | 250 | do { |
222 | | - lf_inprog.u = otx2_cpt_read64(lf->lfs->reg_base, blkaddr, |
223 | | - lf->slot, OTX2_CPT_LF_INPROG); |
224 | | - if (!lf_inprog.s.inflight) |
225 | | - break; |
226 | | - |
227 | | - usleep_range(10000, 20000); |
228 | | - if (timeout-- < 0) { |
229 | | - dev_err(&lf->lfs->pdev->dev, |
230 | | - "Error LF %d is still busy.\n", lf->slot); |
231 | | - break; |
| 251 | + inprog = otx2_cpt_read64(reg_base, blkaddr, slot, OTX2_CPT_LF_INPROG); |
| 252 | + |
| 253 | + if ((FIELD_GET(INFLIGHT, inprog) == 0) && |
| 254 | + (FIELD_GET(GRB_CNT, inprog) == 0)) { |
| 255 | + i++; |
| 256 | + } else { |
| 257 | + i = 0; |
| 258 | + timeout--; |
232 | 259 | } |
| 260 | + } while ((timeout != 0) && (i < 10)); |
233 | 261 |
|
234 | | - } while (1); |
235 | | - |
236 | | - /* |
237 | | - * Disable executions in the LF's queue, |
238 | | - * the queue should be empty at this point |
239 | | - */ |
240 | | - lf_inprog.s.eena = 0x0; |
241 | | - otx2_cpt_write64(lf->lfs->reg_base, blkaddr, lf->slot, |
242 | | - OTX2_CPT_LF_INPROG, lf_inprog.u); |
| 262 | + if (timeout == 0) |
| 263 | + dev_warn(&pdev->dev, "TIMEOUT: CPT poll on inflight count\n"); |
| 264 | + /* Wait for 2 us to flush all queue writes to memory */ |
| 265 | + udelay(2); |
243 | 266 | } |
244 | 267 |
|
245 | 268 | static inline void otx2_cptlf_disable_iqueues(struct otx2_cptlfs_info *lfs) |
246 | 269 | { |
247 | 270 | int slot; |
248 | 271 |
|
249 | | - for (slot = 0; slot < lfs->lfs_num; slot++) |
| 272 | + for (slot = 0; slot < lfs->lfs_num; slot++) { |
250 | 273 | otx2_cptlf_do_disable_iqueue(&lfs->lf[slot]); |
| 274 | + otx2_cpt_lf_reset_msg(lfs, lfs->global_slot + slot); |
| 275 | + } |
251 | 276 | } |
252 | 277 |
|
253 | 278 | static inline void otx2_cptlf_set_iqueue_enq(struct otx2_cptlf_info *lf, |
|
0 commit comments