forked from ~ljy/RK356X_SDK_RELEASE

hc
2024-05-11 297b60346df8beafee954a0fd7c2d64f33f3b9bc
kernel/drivers/net/ethernet/qlogic/qed/qed_spq.c
....@@ -1,33 +1,7 @@
1
+// SPDX-License-Identifier: (GPL-2.0-only OR BSD-3-Clause)
12 /* QLogic qed NIC Driver
23 * Copyright (c) 2015-2017 QLogic Corporation
3
- *
4
- * This software is available to you under a choice of one of two
5
- * licenses. You may choose to be licensed under the terms of the GNU
6
- * General Public License (GPL) Version 2, available from the file
7
- * COPYING in the main directory of this source tree, or the
8
- * OpenIB.org BSD license below:
9
- *
10
- * Redistribution and use in source and binary forms, with or
11
- * without modification, are permitted provided that the following
12
- * conditions are met:
13
- *
14
- * - Redistributions of source code must retain the above
15
- * copyright notice, this list of conditions and the following
16
- * disclaimer.
17
- *
18
- * - Redistributions in binary form must reproduce the above
19
- * copyright notice, this list of conditions and the following
20
- * disclaimer in the documentation and /or other materials
21
- * provided with the distribution.
22
- *
23
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
24
- * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
25
- * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
26
- * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
27
- * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
28
- * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
29
- * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
30
- * SOFTWARE.
4
+ * Copyright (c) 2019-2020 Marvell International Ltd.
315 */
326
337 #include <linux/types.h>
....@@ -160,12 +134,16 @@
160134 return 0;
161135 }
162136 err:
163
- DP_NOTICE(p_hwfn,
164
- "Ramrod is stuck [CID %08x cmd %02x protocol %02x echo %04x]\n",
165
- le32_to_cpu(p_ent->elem.hdr.cid),
166
- p_ent->elem.hdr.cmd_id,
167
- p_ent->elem.hdr.protocol_id,
168
- le16_to_cpu(p_ent->elem.hdr.echo));
137
+ p_ptt = qed_ptt_acquire(p_hwfn);
138
+ if (!p_ptt)
139
+ return -EBUSY;
140
+ qed_hw_err_notify(p_hwfn, p_ptt, QED_HW_ERR_RAMROD_FAIL,
141
+ "Ramrod is stuck [CID %08x cmd %02x protocol %02x echo %04x]\n",
142
+ le32_to_cpu(p_ent->elem.hdr.cid),
143
+ p_ent->elem.hdr.cmd_id,
144
+ p_ent->elem.hdr.protocol_id,
145
+ le16_to_cpu(p_ent->elem.hdr.echo));
146
+ qed_ptt_release(p_hwfn, p_ptt);
169147
170148 return -EBUSY;
171149 }
....@@ -252,9 +230,9 @@
252230 struct qed_spq *p_spq, struct qed_spq_entry *p_ent)
253231 {
254232 struct qed_chain *p_chain = &p_hwfn->p_spq->chain;
233
+ struct core_db_data *p_db_data = &p_spq->db_data;
255234 u16 echo = qed_chain_get_prod_idx(p_chain);
256235 struct slow_path_element *elem;
257
- struct core_db_data db;
258236
259237 p_ent->elem.hdr.echo = cpu_to_le16(echo);
260238 elem = qed_chain_produce(p_chain);
....@@ -266,27 +244,22 @@
266244 *elem = p_ent->elem; /* struct assignment */
267245
268246 /* send a doorbell on the slow hwfn session */
269
- memset(&db, 0, sizeof(db));
270
- SET_FIELD(db.params, CORE_DB_DATA_DEST, DB_DEST_XCM);
271
- SET_FIELD(db.params, CORE_DB_DATA_AGG_CMD, DB_AGG_CMD_SET);
272
- SET_FIELD(db.params, CORE_DB_DATA_AGG_VAL_SEL,
273
- DQ_XCM_CORE_SPQ_PROD_CMD);
274
- db.agg_flags = DQ_XCM_CORE_DQ_CF_CMD;
275
- db.spq_prod = cpu_to_le16(qed_chain_get_prod_idx(p_chain));
247
+ p_db_data->spq_prod = cpu_to_le16(qed_chain_get_prod_idx(p_chain));
276248
277249 /* make sure the SPQE is updated before the doorbell */
278250 wmb();
279251
280
- DOORBELL(p_hwfn, qed_db_addr(p_spq->cid, DQ_DEMS_LEGACY), *(u32 *)&db);
252
+ DOORBELL(p_hwfn, p_spq->db_addr_offset, *(u32 *)p_db_data);
281253
282254 /* make sure doorbell is rang */
283255 wmb();
284256
285257 DP_VERBOSE(p_hwfn, QED_MSG_SPQ,
286258 "Doorbelled [0x%08x, CID 0x%08x] with Flags: %02x agg_params: %02x, prod: %04x\n",
287
- qed_db_addr(p_spq->cid, DQ_DEMS_LEGACY),
288
- p_spq->cid, db.params, db.agg_flags,
289
- qed_chain_get_prod_idx(p_chain));
259
+ p_spq->db_addr_offset,
260
+ p_spq->cid,
261
+ p_db_data->params,
262
+ p_db_data->agg_flags, qed_chain_get_prod_idx(p_chain));
290263
291264 return 0;
292265 }
....@@ -346,9 +319,6 @@
346319 USTORM_EQE_CONS_OFFSET(p_hwfn->rel_pf_id);
347320
348321 REG_WR16(p_hwfn, addr, prod);
349
-
350
- /* keep prod updates ordered */
351
- mmiowb();
352322 }
353323
354324 int qed_eq_completion(struct qed_hwfn *p_hwfn, void *cookie)
....@@ -412,22 +382,26 @@
412382
413383 int qed_eq_alloc(struct qed_hwfn *p_hwfn, u16 num_elem)
414384 {
385
+ struct qed_chain_init_params params = {
386
+ .mode = QED_CHAIN_MODE_PBL,
387
+ .intended_use = QED_CHAIN_USE_TO_PRODUCE,
388
+ .cnt_type = QED_CHAIN_CNT_TYPE_U16,
389
+ .num_elems = num_elem,
390
+ .elem_size = sizeof(union event_ring_element),
391
+ };
415392 struct qed_eq *p_eq;
393
+ int ret;
416394
417395 /* Allocate EQ struct */
418396 p_eq = kzalloc(sizeof(*p_eq), GFP_KERNEL);
419397 if (!p_eq)
420398 return -ENOMEM;
421399
422
- /* Allocate and initialize EQ chain*/
423
- if (qed_chain_alloc(p_hwfn->cdev,
424
- QED_CHAIN_USE_TO_PRODUCE,
425
- QED_CHAIN_MODE_PBL,
426
- QED_CHAIN_CNT_TYPE_U16,
427
- num_elem,
428
- sizeof(union event_ring_element),
429
- &p_eq->chain, NULL))
400
+ ret = qed_chain_alloc(p_hwfn->cdev, &p_eq->chain, &params);
401
+ if (ret) {
402
+ DP_NOTICE(p_hwfn, "Failed to allocate EQ chain\n");
430403 goto eq_allocate_fail;
404
+ }
431405
432406 /* register EQ completion on the SP SB */
433407 qed_int_register_cb(p_hwfn, qed_eq_completion,
....@@ -438,7 +412,8 @@
438412
439413 eq_allocate_fail:
440414 kfree(p_eq);
441
- return -ENOMEM;
415
+
416
+ return ret;
442417 }
443418
444419 void qed_eq_setup(struct qed_hwfn *p_hwfn)
....@@ -495,8 +470,11 @@
495470 {
496471 struct qed_spq *p_spq = p_hwfn->p_spq;
497472 struct qed_spq_entry *p_virt = NULL;
473
+ struct core_db_data *p_db_data;
474
+ void __iomem *db_addr;
498475 dma_addr_t p_phys = 0;
499476 u32 i, capacity;
477
+ int rc;
500478
501479 INIT_LIST_HEAD(&p_spq->pending);
502480 INIT_LIST_HEAD(&p_spq->completion_pending);
....@@ -533,37 +511,63 @@
533511
534512 /* reset the chain itself */
535513 qed_chain_reset(&p_spq->chain);
514
+
515
+ /* Initialize the address/data of the SPQ doorbell */
516
+ p_spq->db_addr_offset = qed_db_addr(p_spq->cid, DQ_DEMS_LEGACY);
517
+ p_db_data = &p_spq->db_data;
518
+ memset(p_db_data, 0, sizeof(*p_db_data));
519
+ SET_FIELD(p_db_data->params, CORE_DB_DATA_DEST, DB_DEST_XCM);
520
+ SET_FIELD(p_db_data->params, CORE_DB_DATA_AGG_CMD, DB_AGG_CMD_MAX);
521
+ SET_FIELD(p_db_data->params, CORE_DB_DATA_AGG_VAL_SEL,
522
+ DQ_XCM_CORE_SPQ_PROD_CMD);
523
+ p_db_data->agg_flags = DQ_XCM_CORE_DQ_CF_CMD;
524
+
525
+ /* Register the SPQ doorbell with the doorbell recovery mechanism */
526
+ db_addr = (void __iomem *)((u8 __iomem *)p_hwfn->doorbells +
527
+ p_spq->db_addr_offset);
528
+ rc = qed_db_recovery_add(p_hwfn->cdev, db_addr, &p_spq->db_data,
529
+ DB_REC_WIDTH_32B, DB_REC_KERNEL);
530
+ if (rc)
531
+ DP_INFO(p_hwfn,
532
+ "Failed to register the SPQ doorbell with the doorbell recovery mechanism\n");
536533 }
537534
538535 int qed_spq_alloc(struct qed_hwfn *p_hwfn)
539536 {
537
+ struct qed_chain_init_params params = {
538
+ .mode = QED_CHAIN_MODE_SINGLE,
539
+ .intended_use = QED_CHAIN_USE_TO_PRODUCE,
540
+ .cnt_type = QED_CHAIN_CNT_TYPE_U16,
541
+ .elem_size = sizeof(struct slow_path_element),
542
+ };
543
+ struct qed_dev *cdev = p_hwfn->cdev;
540544 struct qed_spq_entry *p_virt = NULL;
541545 struct qed_spq *p_spq = NULL;
542546 dma_addr_t p_phys = 0;
543547 u32 capacity;
548
+ int ret;
544549
545550 /* SPQ struct */
546551 p_spq = kzalloc(sizeof(struct qed_spq), GFP_KERNEL);
547552 if (!p_spq)
548553 return -ENOMEM;
549554
550
- /* SPQ ring */
551
- if (qed_chain_alloc(p_hwfn->cdev,
552
- QED_CHAIN_USE_TO_PRODUCE,
553
- QED_CHAIN_MODE_SINGLE,
554
- QED_CHAIN_CNT_TYPE_U16,
555
- 0, /* N/A when the mode is SINGLE */
556
- sizeof(struct slow_path_element),
557
- &p_spq->chain, NULL))
558
- goto spq_allocate_fail;
555
+ /* SPQ ring */
556
+ ret = qed_chain_alloc(cdev, &p_spq->chain, &params);
557
+ if (ret) {
558
+ DP_NOTICE(p_hwfn, "Failed to allocate SPQ chain\n");
559
+ goto spq_chain_alloc_fail;
560
+ }
559561
560562 /* allocate and fill the SPQ elements (incl. ramrod data list) */
561563 capacity = qed_chain_get_capacity(&p_spq->chain);
562
- p_virt = dma_alloc_coherent(&p_hwfn->cdev->pdev->dev,
564
+ ret = -ENOMEM;
565
+
566
+ p_virt = dma_alloc_coherent(&cdev->pdev->dev,
563567 capacity * sizeof(struct qed_spq_entry),
564568 &p_phys, GFP_KERNEL);
565569 if (!p_virt)
566
- goto spq_allocate_fail;
570
+ goto spq_alloc_fail;
567571
568572 p_spq->p_virt = p_virt;
569573 p_spq->p_phys = p_phys;
....@@ -571,19 +575,27 @@
571575
572576 return 0;
573577
574
-spq_allocate_fail:
575
- qed_chain_free(p_hwfn->cdev, &p_spq->chain);
578
+spq_alloc_fail:
579
+ qed_chain_free(cdev, &p_spq->chain);
580
+spq_chain_alloc_fail:
576581 kfree(p_spq);
577
- return -ENOMEM;
582
+
583
+ return ret;
578584 }
579585
580586 void qed_spq_free(struct qed_hwfn *p_hwfn)
581587 {
582588 struct qed_spq *p_spq = p_hwfn->p_spq;
589
+ void __iomem *db_addr;
583590 u32 capacity;
584591
585592 if (!p_spq)
586593 return;
594
+
595
+ /* Delete the SPQ doorbell from the doorbell recovery mechanism */
596
+ db_addr = (void __iomem *)((u8 __iomem *)p_hwfn->doorbells +
597
+ p_spq->db_addr_offset);
598
+ qed_db_recovery_del(p_hwfn->cdev, db_addr, &p_spq->db_data);
587599
588600 if (p_spq->p_virt) {
589601 capacity = qed_chain_get_capacity(&p_spq->chain);
....@@ -644,18 +656,18 @@
644656 }
645657
646658 /**
647
- * @brief qed_spq_add_entry - adds a new entry to the pending
648
- * list. Should be used while lock is being held.
659
+ * qed_spq_add_entry() - Add a new entry to the pending list.
660
+ * Should be used while lock is being held.
649661 *
650
- * Addes an entry to the pending list is there is room (en empty
662
+ * @p_hwfn: HW device data.
663
+ * @p_ent: An entry to add.
664
+ * @priority: Desired priority.
665
+ *
666
+ * Adds an entry to the pending list is there is room (an empty
651667 * element is available in the free_pool), or else places the
652668 * entry in the unlimited_pending pool.
653669 *
654
- * @param p_hwfn
655
- * @param p_ent
656
- * @param priority
657
- *
658
- * @return int
670
+ * Return: zero on success, -EINVAL on invalid @priority.
659671 */
660672 static int qed_spq_add_entry(struct qed_hwfn *p_hwfn,
661673 struct qed_spq_entry *p_ent,
....@@ -735,8 +747,7 @@
735747 !list_empty(head)) {
736748 struct qed_spq_entry *p_ent =
737749 list_first_entry(head, struct qed_spq_entry, list);
738
- list_del(&p_ent->list);
739
- list_add_tail(&p_ent->list, &p_spq->completion_pending);
750
+ list_move_tail(&p_ent->list, &p_spq->completion_pending);
740751 p_spq->comp_sent_count++;
741752
742753 rc = qed_spq_hw_post(p_hwfn, p_spq, p_ent);
....@@ -773,6 +784,17 @@
773784 SPQ_HIGH_PRI_RESERVE_DEFAULT);
774785 }
775786
787
+static void qed_spq_recov_set_ret_code(struct qed_spq_entry *p_ent,
788
+ u8 *fw_return_code)
789
+{
790
+ if (!fw_return_code)
791
+ return;
792
+
793
+ if (p_ent->elem.hdr.protocol_id == PROTOCOLID_ROCE ||
794
+ p_ent->elem.hdr.protocol_id == PROTOCOLID_IWARP)
795
+ *fw_return_code = RDMA_RETURN_OK;
796
+}
797
+
776798 /* Avoid overriding of SPQ entries when getting out-of-order completions, by
777799 * marking the completions in a bitmap and increasing the chain consumer only
778800 * for the first successive completed entries.
....@@ -806,6 +828,17 @@
806828 if (!p_ent) {
807829 DP_NOTICE(p_hwfn, "Got a NULL pointer\n");
808830 return -EINVAL;
831
+ }
832
+
833
+ if (p_hwfn->cdev->recov_in_prog) {
834
+ DP_VERBOSE(p_hwfn,
835
+ QED_MSG_SPQ,
836
+ "Recovery is in progress. Skip spq post [cmd %02x protocol %02x]\n",
837
+ p_ent->elem.hdr.cmd_id, p_ent->elem.hdr.protocol_id);
838
+
839
+ /* Let the flow complete w/o any error handling */
840
+ qed_spq_recov_set_ret_code(p_ent, fw_return_code);
841
+ return 0;
809842 }
810843
811844 /* Complete the entry */
....@@ -948,30 +981,40 @@
948981 return 0;
949982 }
950983
984
+#define QED_SPQ_CONSQ_ELEM_SIZE 0x80
985
+
951986 int qed_consq_alloc(struct qed_hwfn *p_hwfn)
952987 {
988
+ struct qed_chain_init_params params = {
989
+ .mode = QED_CHAIN_MODE_PBL,
990
+ .intended_use = QED_CHAIN_USE_TO_PRODUCE,
991
+ .cnt_type = QED_CHAIN_CNT_TYPE_U16,
992
+ .num_elems = QED_CHAIN_PAGE_SIZE / QED_SPQ_CONSQ_ELEM_SIZE,
993
+ .elem_size = QED_SPQ_CONSQ_ELEM_SIZE,
994
+ };
953995 struct qed_consq *p_consq;
996
+ int ret;
954997
955998 /* Allocate ConsQ struct */
956999 p_consq = kzalloc(sizeof(*p_consq), GFP_KERNEL);
9571000 if (!p_consq)
9581001 return -ENOMEM;
9591002
960
- /* Allocate and initialize EQ chain*/
961
- if (qed_chain_alloc(p_hwfn->cdev,
962
- QED_CHAIN_USE_TO_PRODUCE,
963
- QED_CHAIN_MODE_PBL,
964
- QED_CHAIN_CNT_TYPE_U16,
965
- QED_CHAIN_PAGE_SIZE / 0x80,
966
- 0x80, &p_consq->chain, NULL))
967
- goto consq_allocate_fail;
1003
+ /* Allocate and initialize ConsQ chain */
1004
+ ret = qed_chain_alloc(p_hwfn->cdev, &p_consq->chain, &params);
1005
+ if (ret) {
1006
+ DP_NOTICE(p_hwfn, "Failed to allocate ConsQ chain");
1007
+ goto consq_alloc_fail;
1008
+ }
9681009
9691010 p_hwfn->p_consq = p_consq;
1011
+
9701012 return 0;
9711013
972
-consq_allocate_fail:
1014
+consq_alloc_fail:
9731015 kfree(p_consq);
974
- return -ENOMEM;
1016
+
1017
+ return ret;
9751018 }
9761019
9771020 void qed_consq_setup(struct qed_hwfn *p_hwfn)