cptvf_reqmanager.c 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575
  1. // SPDX-License-Identifier: GPL-2.0-only
  2. /*
  3. * Copyright (C) 2016 Cavium, Inc.
  4. */
  5. #include "cptvf.h"
  6. #include "cptvf_algs.h"
  7. #include "request_manager.h"
  8. /**
  9. * get_free_pending_entry - get free entry from pending queue
  10. * @q: pending queue
  11. * @qlen: queue length
  12. */
  13. static struct pending_entry *get_free_pending_entry(struct pending_queue *q,
  14. int qlen)
  15. {
  16. struct pending_entry *ent = NULL;
  17. ent = &q->head[q->rear];
  18. if (unlikely(ent->busy)) {
  19. ent = NULL;
  20. goto no_free_entry;
  21. }
  22. q->rear++;
  23. if (unlikely(q->rear == qlen))
  24. q->rear = 0;
  25. no_free_entry:
  26. return ent;
  27. }
  28. static inline void pending_queue_inc_front(struct pending_qinfo *pqinfo,
  29. int qno)
  30. {
  31. struct pending_queue *queue = &pqinfo->queue[qno];
  32. queue->front++;
  33. if (unlikely(queue->front == pqinfo->qlen))
  34. queue->front = 0;
  35. }
  36. static int setup_sgio_components(struct cpt_vf *cptvf, struct buf_ptr *list,
  37. int buf_count, u8 *buffer)
  38. {
  39. int ret = 0, i, j;
  40. int components;
  41. struct sglist_component *sg_ptr = NULL;
  42. struct pci_dev *pdev = cptvf->pdev;
  43. if (unlikely(!list)) {
  44. dev_err(&pdev->dev, "Input List pointer is NULL\n");
  45. return -EFAULT;
  46. }
  47. for (i = 0; i < buf_count; i++) {
  48. if (likely(list[i].vptr)) {
  49. list[i].dma_addr = dma_map_single(&pdev->dev,
  50. list[i].vptr,
  51. list[i].size,
  52. DMA_BIDIRECTIONAL);
  53. if (unlikely(dma_mapping_error(&pdev->dev,
  54. list[i].dma_addr))) {
  55. dev_err(&pdev->dev, "DMA map kernel buffer failed for component: %d\n",
  56. i);
  57. ret = -EIO;
  58. goto sg_cleanup;
  59. }
  60. }
  61. }
  62. components = buf_count / 4;
  63. sg_ptr = (struct sglist_component *)buffer;
  64. for (i = 0; i < components; i++) {
  65. sg_ptr->u.s.len0 = cpu_to_be16(list[i * 4 + 0].size);
  66. sg_ptr->u.s.len1 = cpu_to_be16(list[i * 4 + 1].size);
  67. sg_ptr->u.s.len2 = cpu_to_be16(list[i * 4 + 2].size);
  68. sg_ptr->u.s.len3 = cpu_to_be16(list[i * 4 + 3].size);
  69. sg_ptr->ptr0 = cpu_to_be64(list[i * 4 + 0].dma_addr);
  70. sg_ptr->ptr1 = cpu_to_be64(list[i * 4 + 1].dma_addr);
  71. sg_ptr->ptr2 = cpu_to_be64(list[i * 4 + 2].dma_addr);
  72. sg_ptr->ptr3 = cpu_to_be64(list[i * 4 + 3].dma_addr);
  73. sg_ptr++;
  74. }
  75. components = buf_count % 4;
  76. switch (components) {
  77. case 3:
  78. sg_ptr->u.s.len2 = cpu_to_be16(list[i * 4 + 2].size);
  79. sg_ptr->ptr2 = cpu_to_be64(list[i * 4 + 2].dma_addr);
  80. fallthrough;
  81. case 2:
  82. sg_ptr->u.s.len1 = cpu_to_be16(list[i * 4 + 1].size);
  83. sg_ptr->ptr1 = cpu_to_be64(list[i * 4 + 1].dma_addr);
  84. fallthrough;
  85. case 1:
  86. sg_ptr->u.s.len0 = cpu_to_be16(list[i * 4 + 0].size);
  87. sg_ptr->ptr0 = cpu_to_be64(list[i * 4 + 0].dma_addr);
  88. break;
  89. default:
  90. break;
  91. }
  92. return ret;
  93. sg_cleanup:
  94. for (j = 0; j < i; j++) {
  95. if (list[j].dma_addr) {
  96. dma_unmap_single(&pdev->dev, list[i].dma_addr,
  97. list[i].size, DMA_BIDIRECTIONAL);
  98. }
  99. list[j].dma_addr = 0;
  100. }
  101. return ret;
  102. }
  103. static inline int setup_sgio_list(struct cpt_vf *cptvf,
  104. struct cpt_info_buffer *info,
  105. struct cpt_request_info *req)
  106. {
  107. u16 g_sz_bytes = 0, s_sz_bytes = 0;
  108. int ret = 0;
  109. struct pci_dev *pdev = cptvf->pdev;
  110. if (req->incnt > MAX_SG_IN_CNT || req->outcnt > MAX_SG_OUT_CNT) {
  111. dev_err(&pdev->dev, "Request SG components are higher than supported\n");
  112. ret = -EINVAL;
  113. goto scatter_gather_clean;
  114. }
  115. /* Setup gather (input) components */
  116. g_sz_bytes = ((req->incnt + 3) / 4) * sizeof(struct sglist_component);
  117. info->gather_components = kzalloc(g_sz_bytes, req->may_sleep ? GFP_KERNEL : GFP_ATOMIC);
  118. if (!info->gather_components) {
  119. ret = -ENOMEM;
  120. goto scatter_gather_clean;
  121. }
  122. ret = setup_sgio_components(cptvf, req->in,
  123. req->incnt,
  124. info->gather_components);
  125. if (ret) {
  126. dev_err(&pdev->dev, "Failed to setup gather list\n");
  127. ret = -EFAULT;
  128. goto scatter_gather_clean;
  129. }
  130. /* Setup scatter (output) components */
  131. s_sz_bytes = ((req->outcnt + 3) / 4) * sizeof(struct sglist_component);
  132. info->scatter_components = kzalloc(s_sz_bytes, req->may_sleep ? GFP_KERNEL : GFP_ATOMIC);
  133. if (!info->scatter_components) {
  134. ret = -ENOMEM;
  135. goto scatter_gather_clean;
  136. }
  137. ret = setup_sgio_components(cptvf, req->out,
  138. req->outcnt,
  139. info->scatter_components);
  140. if (ret) {
  141. dev_err(&pdev->dev, "Failed to setup gather list\n");
  142. ret = -EFAULT;
  143. goto scatter_gather_clean;
  144. }
  145. /* Create and initialize DPTR */
  146. info->dlen = g_sz_bytes + s_sz_bytes + SG_LIST_HDR_SIZE;
  147. info->in_buffer = kzalloc(info->dlen, req->may_sleep ? GFP_KERNEL : GFP_ATOMIC);
  148. if (!info->in_buffer) {
  149. ret = -ENOMEM;
  150. goto scatter_gather_clean;
  151. }
  152. ((__be16 *)info->in_buffer)[0] = cpu_to_be16(req->outcnt);
  153. ((__be16 *)info->in_buffer)[1] = cpu_to_be16(req->incnt);
  154. ((__be16 *)info->in_buffer)[2] = 0;
  155. ((__be16 *)info->in_buffer)[3] = 0;
  156. memcpy(&info->in_buffer[8], info->gather_components,
  157. g_sz_bytes);
  158. memcpy(&info->in_buffer[8 + g_sz_bytes],
  159. info->scatter_components, s_sz_bytes);
  160. info->dptr_baddr = dma_map_single(&pdev->dev,
  161. (void *)info->in_buffer,
  162. info->dlen,
  163. DMA_BIDIRECTIONAL);
  164. if (dma_mapping_error(&pdev->dev, info->dptr_baddr)) {
  165. dev_err(&pdev->dev, "Mapping DPTR Failed %d\n", info->dlen);
  166. ret = -EIO;
  167. goto scatter_gather_clean;
  168. }
  169. /* Create and initialize RPTR */
  170. info->out_buffer = kzalloc(COMPLETION_CODE_SIZE, req->may_sleep ? GFP_KERNEL : GFP_ATOMIC);
  171. if (!info->out_buffer) {
  172. ret = -ENOMEM;
  173. goto scatter_gather_clean;
  174. }
  175. *((u64 *)info->out_buffer) = ~((u64)COMPLETION_CODE_INIT);
  176. info->alternate_caddr = (u64 *)info->out_buffer;
  177. info->rptr_baddr = dma_map_single(&pdev->dev,
  178. (void *)info->out_buffer,
  179. COMPLETION_CODE_SIZE,
  180. DMA_BIDIRECTIONAL);
  181. if (dma_mapping_error(&pdev->dev, info->rptr_baddr)) {
  182. dev_err(&pdev->dev, "Mapping RPTR Failed %d\n",
  183. COMPLETION_CODE_SIZE);
  184. ret = -EIO;
  185. goto scatter_gather_clean;
  186. }
  187. return 0;
  188. scatter_gather_clean:
  189. return ret;
  190. }
  191. static int send_cpt_command(struct cpt_vf *cptvf, union cpt_inst_s *cmd,
  192. u32 qno)
  193. {
  194. struct pci_dev *pdev = cptvf->pdev;
  195. struct command_qinfo *qinfo = NULL;
  196. struct command_queue *queue;
  197. struct command_chunk *chunk;
  198. u8 *ent;
  199. int ret = 0;
  200. if (unlikely(qno >= cptvf->nr_queues)) {
  201. dev_err(&pdev->dev, "Invalid queue (qno: %d, nr_queues: %d)\n",
  202. qno, cptvf->nr_queues);
  203. return -EINVAL;
  204. }
  205. qinfo = &cptvf->cqinfo;
  206. queue = &qinfo->queue[qno];
  207. /* lock commad queue */
  208. spin_lock(&queue->lock);
  209. ent = &queue->qhead->head[queue->idx * qinfo->cmd_size];
  210. memcpy(ent, (void *)cmd, qinfo->cmd_size);
  211. if (++queue->idx >= queue->qhead->size / 64) {
  212. hlist_for_each_entry(chunk, &queue->chead, nextchunk) {
  213. if (chunk == queue->qhead) {
  214. continue;
  215. } else {
  216. queue->qhead = chunk;
  217. break;
  218. }
  219. }
  220. queue->idx = 0;
  221. }
  222. /* make sure all memory stores are done before ringing doorbell */
  223. smp_wmb();
  224. cptvf_write_vq_doorbell(cptvf, 1);
  225. /* unlock command queue */
  226. spin_unlock(&queue->lock);
  227. return ret;
  228. }
  229. static void do_request_cleanup(struct cpt_vf *cptvf,
  230. struct cpt_info_buffer *info)
  231. {
  232. int i;
  233. struct pci_dev *pdev = cptvf->pdev;
  234. struct cpt_request_info *req;
  235. if (info->dptr_baddr)
  236. dma_unmap_single(&pdev->dev, info->dptr_baddr,
  237. info->dlen, DMA_BIDIRECTIONAL);
  238. if (info->rptr_baddr)
  239. dma_unmap_single(&pdev->dev, info->rptr_baddr,
  240. COMPLETION_CODE_SIZE, DMA_BIDIRECTIONAL);
  241. if (info->comp_baddr)
  242. dma_unmap_single(&pdev->dev, info->comp_baddr,
  243. sizeof(union cpt_res_s), DMA_BIDIRECTIONAL);
  244. if (info->req) {
  245. req = info->req;
  246. for (i = 0; i < req->outcnt; i++) {
  247. if (req->out[i].dma_addr)
  248. dma_unmap_single(&pdev->dev,
  249. req->out[i].dma_addr,
  250. req->out[i].size,
  251. DMA_BIDIRECTIONAL);
  252. }
  253. for (i = 0; i < req->incnt; i++) {
  254. if (req->in[i].dma_addr)
  255. dma_unmap_single(&pdev->dev,
  256. req->in[i].dma_addr,
  257. req->in[i].size,
  258. DMA_BIDIRECTIONAL);
  259. }
  260. }
  261. kfree_sensitive(info->scatter_components);
  262. kfree_sensitive(info->gather_components);
  263. kfree_sensitive(info->out_buffer);
  264. kfree_sensitive(info->in_buffer);
  265. kfree_sensitive((void *)info->completion_addr);
  266. kfree_sensitive(info);
  267. }
  268. static void do_post_process(struct cpt_vf *cptvf, struct cpt_info_buffer *info)
  269. {
  270. struct pci_dev *pdev = cptvf->pdev;
  271. if (!info) {
  272. dev_err(&pdev->dev, "incorrect cpt_info_buffer for post processing\n");
  273. return;
  274. }
  275. do_request_cleanup(cptvf, info);
  276. }
  277. static inline void process_pending_queue(struct cpt_vf *cptvf,
  278. struct pending_qinfo *pqinfo,
  279. int qno)
  280. {
  281. struct pci_dev *pdev = cptvf->pdev;
  282. struct pending_queue *pqueue = &pqinfo->queue[qno];
  283. struct pending_entry *pentry = NULL;
  284. struct cpt_info_buffer *info = NULL;
  285. union cpt_res_s *status = NULL;
  286. unsigned char ccode;
  287. while (1) {
  288. spin_lock_bh(&pqueue->lock);
  289. pentry = &pqueue->head[pqueue->front];
  290. if (unlikely(!pentry->busy)) {
  291. spin_unlock_bh(&pqueue->lock);
  292. break;
  293. }
  294. info = (struct cpt_info_buffer *)pentry->post_arg;
  295. if (unlikely(!info)) {
  296. dev_err(&pdev->dev, "Pending Entry post arg NULL\n");
  297. pending_queue_inc_front(pqinfo, qno);
  298. spin_unlock_bh(&pqueue->lock);
  299. continue;
  300. }
  301. status = (union cpt_res_s *)pentry->completion_addr;
  302. ccode = status->s.compcode;
  303. if ((status->s.compcode == CPT_COMP_E_FAULT) ||
  304. (status->s.compcode == CPT_COMP_E_SWERR)) {
  305. dev_err(&pdev->dev, "Request failed with %s\n",
  306. (status->s.compcode == CPT_COMP_E_FAULT) ?
  307. "DMA Fault" : "Software error");
  308. pentry->completion_addr = NULL;
  309. pentry->busy = false;
  310. atomic64_dec((&pqueue->pending_count));
  311. pentry->post_arg = NULL;
  312. pending_queue_inc_front(pqinfo, qno);
  313. do_request_cleanup(cptvf, info);
  314. spin_unlock_bh(&pqueue->lock);
  315. break;
  316. } else if (status->s.compcode == COMPLETION_CODE_INIT) {
  317. /* check for timeout */
  318. if (time_after_eq(jiffies,
  319. (info->time_in +
  320. (CPT_COMMAND_TIMEOUT * HZ)))) {
  321. dev_err(&pdev->dev, "Request timed out");
  322. pentry->completion_addr = NULL;
  323. pentry->busy = false;
  324. atomic64_dec((&pqueue->pending_count));
  325. pentry->post_arg = NULL;
  326. pending_queue_inc_front(pqinfo, qno);
  327. do_request_cleanup(cptvf, info);
  328. spin_unlock_bh(&pqueue->lock);
  329. break;
  330. } else if ((*info->alternate_caddr ==
  331. (~COMPLETION_CODE_INIT)) &&
  332. (info->extra_time < TIME_IN_RESET_COUNT)) {
  333. info->time_in = jiffies;
  334. info->extra_time++;
  335. spin_unlock_bh(&pqueue->lock);
  336. break;
  337. }
  338. }
  339. pentry->completion_addr = NULL;
  340. pentry->busy = false;
  341. pentry->post_arg = NULL;
  342. atomic64_dec((&pqueue->pending_count));
  343. pending_queue_inc_front(pqinfo, qno);
  344. spin_unlock_bh(&pqueue->lock);
  345. do_post_process(info->cptvf, info);
  346. /*
  347. * Calling callback after we find
  348. * that the request has been serviced
  349. */
  350. pentry->callback(ccode, pentry->callback_arg);
  351. }
  352. }
  353. int process_request(struct cpt_vf *cptvf, struct cpt_request_info *req)
  354. {
  355. int ret = 0, clear = 0, queue = 0;
  356. struct cpt_info_buffer *info = NULL;
  357. struct cptvf_request *cpt_req = NULL;
  358. union ctrl_info *ctrl = NULL;
  359. union cpt_res_s *result = NULL;
  360. struct pending_entry *pentry = NULL;
  361. struct pending_queue *pqueue = NULL;
  362. struct pci_dev *pdev = cptvf->pdev;
  363. u8 group = 0;
  364. struct cpt_vq_command vq_cmd;
  365. union cpt_inst_s cptinst;
  366. info = kzalloc(sizeof(*info), req->may_sleep ? GFP_KERNEL : GFP_ATOMIC);
  367. if (unlikely(!info)) {
  368. dev_err(&pdev->dev, "Unable to allocate memory for info_buffer\n");
  369. return -ENOMEM;
  370. }
  371. cpt_req = (struct cptvf_request *)&req->req;
  372. ctrl = (union ctrl_info *)&req->ctrl;
  373. info->cptvf = cptvf;
  374. group = ctrl->s.grp;
  375. ret = setup_sgio_list(cptvf, info, req);
  376. if (ret) {
  377. dev_err(&pdev->dev, "Setting up SG list failed");
  378. goto request_cleanup;
  379. }
  380. cpt_req->dlen = info->dlen;
  381. /*
  382. * Get buffer for union cpt_res_s response
  383. * structure and its physical address
  384. */
  385. info->completion_addr = kzalloc(sizeof(union cpt_res_s), req->may_sleep ? GFP_KERNEL : GFP_ATOMIC);
  386. if (unlikely(!info->completion_addr)) {
  387. dev_err(&pdev->dev, "Unable to allocate memory for completion_addr\n");
  388. ret = -ENOMEM;
  389. goto request_cleanup;
  390. }
  391. result = (union cpt_res_s *)info->completion_addr;
  392. result->s.compcode = COMPLETION_CODE_INIT;
  393. info->comp_baddr = dma_map_single(&pdev->dev,
  394. (void *)info->completion_addr,
  395. sizeof(union cpt_res_s),
  396. DMA_BIDIRECTIONAL);
  397. if (dma_mapping_error(&pdev->dev, info->comp_baddr)) {
  398. dev_err(&pdev->dev, "mapping compptr Failed %lu\n",
  399. sizeof(union cpt_res_s));
  400. ret = -EFAULT;
  401. goto request_cleanup;
  402. }
  403. /* Fill the VQ command */
  404. vq_cmd.cmd.u64 = 0;
  405. vq_cmd.cmd.s.opcode = cpu_to_be16(cpt_req->opcode.flags);
  406. vq_cmd.cmd.s.param1 = cpu_to_be16(cpt_req->param1);
  407. vq_cmd.cmd.s.param2 = cpu_to_be16(cpt_req->param2);
  408. vq_cmd.cmd.s.dlen = cpu_to_be16(cpt_req->dlen);
  409. vq_cmd.dptr = info->dptr_baddr;
  410. vq_cmd.rptr = info->rptr_baddr;
  411. vq_cmd.cptr.u64 = 0;
  412. vq_cmd.cptr.s.grp = group;
  413. /* Get Pending Entry to submit command */
  414. /* Always queue 0, because 1 queue per VF */
  415. queue = 0;
  416. pqueue = &cptvf->pqinfo.queue[queue];
  417. if (atomic64_read(&pqueue->pending_count) > PENDING_THOLD) {
  418. dev_err(&pdev->dev, "pending threshold reached\n");
  419. process_pending_queue(cptvf, &cptvf->pqinfo, queue);
  420. }
  421. get_pending_entry:
  422. spin_lock_bh(&pqueue->lock);
  423. pentry = get_free_pending_entry(pqueue, cptvf->pqinfo.qlen);
  424. if (unlikely(!pentry)) {
  425. spin_unlock_bh(&pqueue->lock);
  426. if (clear == 0) {
  427. process_pending_queue(cptvf, &cptvf->pqinfo, queue);
  428. clear = 1;
  429. goto get_pending_entry;
  430. }
  431. dev_err(&pdev->dev, "Get free entry failed\n");
  432. dev_err(&pdev->dev, "queue: %d, rear: %d, front: %d\n",
  433. queue, pqueue->rear, pqueue->front);
  434. ret = -EFAULT;
  435. goto request_cleanup;
  436. }
  437. pentry->completion_addr = info->completion_addr;
  438. pentry->post_arg = (void *)info;
  439. pentry->callback = req->callback;
  440. pentry->callback_arg = req->callback_arg;
  441. info->pentry = pentry;
  442. pentry->busy = true;
  443. atomic64_inc(&pqueue->pending_count);
  444. /* Send CPT command */
  445. info->pentry = pentry;
  446. info->time_in = jiffies;
  447. info->req = req;
  448. /* Create the CPT_INST_S type command for HW intrepretation */
  449. cptinst.s.doneint = true;
  450. cptinst.s.res_addr = (u64)info->comp_baddr;
  451. cptinst.s.tag = 0;
  452. cptinst.s.grp = 0;
  453. cptinst.s.wq_ptr = 0;
  454. cptinst.s.ei0 = vq_cmd.cmd.u64;
  455. cptinst.s.ei1 = vq_cmd.dptr;
  456. cptinst.s.ei2 = vq_cmd.rptr;
  457. cptinst.s.ei3 = vq_cmd.cptr.u64;
  458. ret = send_cpt_command(cptvf, &cptinst, queue);
  459. spin_unlock_bh(&pqueue->lock);
  460. if (unlikely(ret)) {
  461. dev_err(&pdev->dev, "Send command failed for AE\n");
  462. ret = -EFAULT;
  463. goto request_cleanup;
  464. }
  465. return 0;
  466. request_cleanup:
  467. dev_dbg(&pdev->dev, "Failed to submit CPT command\n");
  468. do_request_cleanup(cptvf, info);
  469. return ret;
  470. }
  471. void vq_post_process(struct cpt_vf *cptvf, u32 qno)
  472. {
  473. struct pci_dev *pdev = cptvf->pdev;
  474. if (unlikely(qno > cptvf->nr_queues)) {
  475. dev_err(&pdev->dev, "Request for post processing on invalid pending queue: %u\n",
  476. qno);
  477. return;
  478. }
  479. process_pending_queue(cptvf, &cptvf->pqinfo, qno);
  480. }
  481. int cptvf_do_request(void *vfdev, struct cpt_request_info *req)
  482. {
  483. struct cpt_vf *cptvf = (struct cpt_vf *)vfdev;
  484. struct pci_dev *pdev = cptvf->pdev;
  485. if (!cpt_device_ready(cptvf)) {
  486. dev_err(&pdev->dev, "CPT Device is not ready");
  487. return -ENODEV;
  488. }
  489. if ((cptvf->vftype == SE_TYPES) && (!req->ctrl.s.se_req)) {
  490. dev_err(&pdev->dev, "CPTVF-%d of SE TYPE got AE request",
  491. cptvf->vfid);
  492. return -EINVAL;
  493. } else if ((cptvf->vftype == AE_TYPES) && (req->ctrl.s.se_req)) {
  494. dev_err(&pdev->dev, "CPTVF-%d of AE TYPE got SE request",
  495. cptvf->vfid);
  496. return -EINVAL;
  497. }
  498. return process_request(cptvf, req);
  499. }