forked from ~ljy/RK356X_SDK_RELEASE

hc
2023-12-09 95099d4622f8cb224d94e314c7a8e0df60b13f87
kernel/drivers/scsi/qedi/qedi_main.c
....@@ -1,10 +1,7 @@
1
+// SPDX-License-Identifier: GPL-2.0-only
12 /*
23 * QLogic iSCSI Offload Driver
34 * Copyright (c) 2016 Cavium Inc.
4
- *
5
- * This software is available under the terms of the GNU General Public License
6
- * (GPL) Version 2, available from the file COPYING in the main directory of
7
- * this source tree.
85 */
96
107 #include <linux/module.h>
....@@ -31,6 +28,10 @@
3128 #include "qedi_gbl.h"
3229 #include "qedi_iscsi.h"
3330
31
+static uint qedi_qed_debug;
32
+module_param(qedi_qed_debug, uint, 0644);
33
+MODULE_PARM_DESC(qedi_qed_debug, " QED debug level 0 (default)");
34
+
3435 static uint qedi_fw_debug;
3536 module_param(qedi_fw_debug, uint, 0644);
3637 MODULE_PARM_DESC(qedi_fw_debug, " Firmware debug level 0(default) to 3");
....@@ -44,6 +45,15 @@
4445 MODULE_PARM_DESC(qedi_io_tracing,
4546 " Enable logging of SCSI requests/completions into trace buffer. (default off).");
4647
48
+static uint qedi_ll2_buf_size = 0x400;
49
+module_param(qedi_ll2_buf_size, uint, 0644);
50
+MODULE_PARM_DESC(qedi_ll2_buf_size,
51
+ "parameter to set ping packet size, default - 0x400, Jumbo packets - 0x2400.");
52
+
53
+static uint qedi_flags_override;
54
+module_param(qedi_flags_override, uint, 0644);
55
+MODULE_PARM_DESC(qedi_flags_override, "Disable/Enable MFW error flags bits action.");
56
+
4757 const struct qed_iscsi_ops *qedi_ops;
4858 static struct scsi_transport_template *qedi_scsi_transport;
4959 static struct pci_driver qedi_pci_driver;
....@@ -56,6 +66,9 @@
5666 static void qedi_reset_uio_rings(struct qedi_uio_dev *udev);
5767 static void qedi_ll2_free_skbs(struct qedi_ctx *qedi);
5868 static struct nvm_iscsi_block *qedi_get_nvram_block(struct qedi_ctx *qedi);
69
+static void qedi_recovery_handler(struct work_struct *work);
70
+static void qedi_schedule_hw_err_handler(void *dev,
71
+ enum qed_hw_err_type err_type);
5972
6073 static int qedi_iscsi_event_cb(void *context, u8 fw_event_code, void *fw_handle)
6174 {
....@@ -228,7 +241,7 @@
228241 }
229242
230243 /* Allocating memory for Tx/Rx pkt buffer */
231
- udev->ll2_buf_size = TX_RX_RING * LL2_SINGLE_BUF_SIZE;
244
+ udev->ll2_buf_size = TX_RX_RING * qedi_ll2_buf_size;
232245 udev->ll2_buf_size = QEDI_PAGE_ALIGN(udev->ll2_buf_size);
233246 udev->ll2_buf = (void *)__get_free_pages(GFP_KERNEL | __GFP_COMP |
234247 __GFP_ZERO, 2);
....@@ -283,7 +296,7 @@
283296 qedi->udev = udev;
284297
285298 udev->tx_pkt = udev->ll2_buf;
286
- udev->rx_pkt = udev->ll2_buf + LL2_SINGLE_BUF_SIZE;
299
+ udev->rx_pkt = udev->ll2_buf + qedi_ll2_buf_size;
287300 return 0;
288301
289302 err_uctrl:
....@@ -644,8 +657,7 @@
644657 qedi->max_active_conns = ISCSI_MAX_SESS_PER_HBA;
645658 qedi->max_sqes = QEDI_SQ_SIZE;
646659
647
- if (shost_use_blk_mq(shost))
648
- shost->nr_hw_queues = MIN_NUM_CPUS_MSIX(qedi);
660
+ shost->nr_hw_queues = MIN_NUM_CPUS_MSIX(qedi);
649661
650662 pci_set_drvdata(pdev, qedi);
651663
....@@ -656,10 +668,8 @@
656668 static int qedi_ll2_rx(void *cookie, struct sk_buff *skb, u32 arg1, u32 arg2)
657669 {
658670 struct qedi_ctx *qedi = (struct qedi_ctx *)cookie;
659
- struct qedi_uio_dev *udev;
660
- struct qedi_uio_ctrl *uctrl;
661671 struct skb_work_list *work;
662
- u32 prod;
672
+ struct ethhdr *eh;
663673
664674 if (!qedi) {
665675 QEDI_ERR(NULL, "qedi is NULL\n");
....@@ -673,8 +683,28 @@
673683 return 0;
674684 }
675685
676
- udev = qedi->udev;
677
- uctrl = udev->uctrl;
686
+ eh = (struct ethhdr *)skb->data;
687
+ /* Undo VLAN encapsulation */
688
+ if (eh->h_proto == htons(ETH_P_8021Q)) {
689
+ memmove((u8 *)eh + VLAN_HLEN, eh, ETH_ALEN * 2);
690
+ eh = (struct ethhdr *)skb_pull(skb, VLAN_HLEN);
691
+ skb_reset_mac_header(skb);
692
+ }
693
+
694
+ /* Filter out non FIP/FCoE frames here to free them faster */
695
+ if (eh->h_proto != htons(ETH_P_ARP) &&
696
+ eh->h_proto != htons(ETH_P_IP) &&
697
+ eh->h_proto != htons(ETH_P_IPV6)) {
698
+ QEDI_INFO(&qedi->dbg_ctx, QEDI_LOG_LL2,
699
+ "Dropping frame ethertype [0x%x] len [0x%x].\n",
700
+ eh->h_proto, skb->len);
701
+ kfree_skb(skb);
702
+ return 0;
703
+ }
704
+
705
+ QEDI_INFO(&qedi->dbg_ctx, QEDI_LOG_LL2,
706
+ "Allowed frame ethertype [0x%x] len [0x%x].\n",
707
+ eh->h_proto, skb->len);
678708
679709 work = kzalloc(sizeof(*work), GFP_ATOMIC);
680710 if (!work) {
....@@ -695,17 +725,10 @@
695725
696726 spin_lock_bh(&qedi->ll2_lock);
697727 list_add_tail(&work->list, &qedi->ll2_skb_list);
698
-
699
- ++uctrl->hw_rx_prod_cnt;
700
- prod = (uctrl->hw_rx_prod + 1) % RX_RING;
701
- if (prod != uctrl->host_rx_cons) {
702
- uctrl->hw_rx_prod = prod;
703
- spin_unlock_bh(&qedi->ll2_lock);
704
- wake_up_process(qedi->ll2_recv_thread);
705
- return 0;
706
- }
707
-
708728 spin_unlock_bh(&qedi->ll2_lock);
729
+
730
+ wake_up_process(qedi->ll2_recv_thread);
731
+
709732 return 0;
710733 }
711734
....@@ -720,6 +743,7 @@
720743 u32 rx_bd_prod;
721744 void *pkt;
722745 int len = 0;
746
+ u32 prod;
723747
724748 if (!qedi) {
725749 QEDI_ERR(NULL, "qedi is NULL\n");
....@@ -728,12 +752,16 @@
728752
729753 udev = qedi->udev;
730754 uctrl = udev->uctrl;
731
- pkt = udev->rx_pkt + (uctrl->hw_rx_prod * LL2_SINGLE_BUF_SIZE);
732
- len = min_t(u32, skb->len, (u32)LL2_SINGLE_BUF_SIZE);
755
+
756
+ ++uctrl->hw_rx_prod_cnt;
757
+ prod = (uctrl->hw_rx_prod + 1) % RX_RING;
758
+
759
+ pkt = udev->rx_pkt + (prod * qedi_ll2_buf_size);
760
+ len = min_t(u32, skb->len, (u32)qedi_ll2_buf_size);
733761 memcpy(pkt, skb->data, len);
734762
735763 memset(&rxbd, 0, sizeof(rxbd));
736
- rxbd.rx_pkt_index = uctrl->hw_rx_prod;
764
+ rxbd.rx_pkt_index = prod;
737765 rxbd.rx_pkt_len = len;
738766 rxbd.vlan_id = vlan_id;
739767
....@@ -743,6 +771,16 @@
743771 p_rxbd += rx_bd_prod;
744772
745773 memcpy(p_rxbd, &rxbd, sizeof(rxbd));
774
+
775
+ QEDI_INFO(&qedi->dbg_ctx, QEDI_LOG_LL2,
776
+ "hw_rx_prod [%d] prod [%d] hw_rx_bd_prod [%d] rx_pkt_idx [%d] rx_len [%d].\n",
777
+ uctrl->hw_rx_prod, prod, uctrl->hw_rx_bd_prod,
778
+ rxbd.rx_pkt_index, rxbd.rx_pkt_len);
779
+ QEDI_INFO(&qedi->dbg_ctx, QEDI_LOG_LL2,
780
+ "host_rx_cons [%d] hw_rx_bd_cons [%d].\n",
781
+ uctrl->host_rx_cons, uctrl->host_rx_bd_cons);
782
+
783
+ uctrl->hw_rx_prod = prod;
746784
747785 /* notify the iscsiuio about new packet */
748786 uio_event_notify(&udev->qedi_uinfo);
....@@ -757,8 +795,7 @@
757795 spin_lock_bh(&qedi->ll2_lock);
758796 list_for_each_entry_safe(work, work_tmp, &qedi->ll2_skb_list, list) {
759797 list_del(&work->list);
760
- if (work->skb)
761
- kfree_skb(work->skb);
798
+ kfree_skb(work->skb);
762799 kfree(work);
763800 }
764801 spin_unlock_bh(&qedi->ll2_lock);
....@@ -796,7 +833,7 @@
796833 int rval = 0;
797834
798835
799
- num_sq_pages = (MAX_OUSTANDING_TASKS_PER_CON * 8) / PAGE_SIZE;
836
+ num_sq_pages = (MAX_OUTSTANDING_TASKS_PER_CON * 8) / QEDI_PAGE_SIZE;
800837
801838 qedi->num_queues = MIN_NUM_CPUS_MSIX(qedi);
802839
....@@ -806,11 +843,11 @@
806843 memset(&qedi->pf_params.iscsi_pf_params, 0,
807844 sizeof(qedi->pf_params.iscsi_pf_params));
808845
809
- qedi->p_cpuq = pci_alloc_consistent(qedi->pdev,
846
+ qedi->p_cpuq = dma_alloc_coherent(&qedi->pdev->dev,
810847 qedi->num_queues * sizeof(struct qedi_glbl_q_params),
811
- &qedi->hw_p_cpuq);
848
+ &qedi->hw_p_cpuq, GFP_KERNEL);
812849 if (!qedi->p_cpuq) {
813
- QEDI_ERR(&qedi->dbg_ctx, "pci_alloc_consistent fail\n");
850
+ QEDI_ERR(&qedi->dbg_ctx, "dma_alloc_coherent fail\n");
814851 rval = -1;
815852 goto err_alloc_mem;
816853 }
....@@ -834,7 +871,7 @@
834871 qedi->pf_params.iscsi_pf_params.max_fin_rt = 2;
835872
836873 for (log_page_size = 0 ; log_page_size < 32 ; log_page_size++) {
837
- if ((1 << log_page_size) == PAGE_SIZE)
874
+ if ((1 << log_page_size) == QEDI_PAGE_SIZE)
838875 break;
839876 }
840877 qedi->pf_params.iscsi_pf_params.log_page_size = log_page_size;
....@@ -871,7 +908,7 @@
871908
872909 if (qedi->p_cpuq) {
873910 size = qedi->num_queues * sizeof(struct qedi_glbl_q_params);
874
- pci_free_consistent(qedi->pdev, size, qedi->p_cpuq,
911
+ dma_free_coherent(&qedi->pdev->dev, size, qedi->p_cpuq,
875912 qedi->hw_p_cpuq);
876913 }
877914
....@@ -888,7 +925,7 @@
888925 ipv6_en = !!(block->generic.ctrl_flags &
889926 NVM_ISCSI_CFG_GEN_IPV6_ENABLED);
890927
891
- snprintf(tgt->iscsi_name, sizeof(tgt->iscsi_name), "%s\n",
928
+ snprintf(tgt->iscsi_name, sizeof(tgt->iscsi_name), "%s",
892929 block->target[index].target_name.byte);
893930
894931 tgt->ipv6_en = ipv6_en;
....@@ -1081,6 +1118,65 @@
10811118 return;
10821119 }
10831120
1121
+void qedi_schedule_hw_err_handler(void *dev,
1122
+ enum qed_hw_err_type err_type)
1123
+{
1124
+ struct qedi_ctx *qedi = (struct qedi_ctx *)dev;
1125
+ unsigned long override_flags = qedi_flags_override;
1126
+
1127
+ if (override_flags && test_bit(QEDI_ERR_OVERRIDE_EN, &override_flags))
1128
+ qedi->qedi_err_flags = qedi_flags_override;
1129
+
1130
+ QEDI_INFO(&qedi->dbg_ctx, QEDI_LOG_INFO,
1131
+ "HW error handler scheduled, err=%d err_flags=0x%x\n",
1132
+ err_type, qedi->qedi_err_flags);
1133
+
1134
+ switch (err_type) {
1135
+ case QED_HW_ERR_FAN_FAIL:
1136
+ schedule_delayed_work(&qedi->board_disable_work, 0);
1137
+ break;
1138
+ case QED_HW_ERR_MFW_RESP_FAIL:
1139
+ case QED_HW_ERR_HW_ATTN:
1140
+ case QED_HW_ERR_DMAE_FAIL:
1141
+ case QED_HW_ERR_RAMROD_FAIL:
1142
+ case QED_HW_ERR_FW_ASSERT:
1143
+ /* Prevent HW attentions from being reasserted */
1144
+ if (test_bit(QEDI_ERR_ATTN_CLR_EN, &qedi->qedi_err_flags))
1145
+ qedi_ops->common->attn_clr_enable(qedi->cdev, true);
1146
+
1147
+ if (err_type == QED_HW_ERR_RAMROD_FAIL &&
1148
+ test_bit(QEDI_ERR_IS_RECOVERABLE, &qedi->qedi_err_flags))
1149
+ qedi_ops->common->recovery_process(qedi->cdev);
1150
+
1151
+ break;
1152
+ default:
1153
+ break;
1154
+ }
1155
+}
1156
+
1157
+static void qedi_schedule_recovery_handler(void *dev)
1158
+{
1159
+ struct qedi_ctx *qedi = dev;
1160
+
1161
+ QEDI_ERR(&qedi->dbg_ctx, "Recovery handler scheduled.\n");
1162
+
1163
+ if (test_and_set_bit(QEDI_IN_RECOVERY, &qedi->flags))
1164
+ return;
1165
+
1166
+ atomic_set(&qedi->link_state, QEDI_LINK_DOWN);
1167
+
1168
+ schedule_delayed_work(&qedi->recovery_work, 0);
1169
+}
1170
+
1171
+static void qedi_set_conn_recovery(struct iscsi_cls_session *cls_session)
1172
+{
1173
+ struct iscsi_session *session = cls_session->dd_data;
1174
+ struct iscsi_conn *conn = session->leadconn;
1175
+ struct qedi_conn *qedi_conn = conn->dd_data;
1176
+
1177
+ qedi_start_conn_recovery(qedi_conn->qedi, qedi_conn);
1178
+}
1179
+
10841180 static void qedi_link_update(void *dev, struct qed_link_output *link)
10851181 {
10861182 struct qedi_ctx *qedi = (struct qedi_ctx *)dev;
....@@ -1092,12 +1188,15 @@
10921188 QEDI_INFO(&qedi->dbg_ctx, QEDI_LOG_INFO,
10931189 "Link Down event.\n");
10941190 atomic_set(&qedi->link_state, QEDI_LINK_DOWN);
1191
+ iscsi_host_for_each_session(qedi->shost, qedi_set_conn_recovery);
10951192 }
10961193 }
10971194
10981195 static struct qed_iscsi_cb_ops qedi_cb_ops = {
10991196 {
11001197 .link_update = qedi_link_update,
1198
+ .schedule_recovery_handler = qedi_schedule_recovery_handler,
1199
+ .schedule_hw_err_handler = qedi_schedule_hw_err_handler,
11011200 .get_protocol_tlv_data = qedi_get_protocol_tlv_data,
11021201 .get_generic_tlv_data = qedi_get_generic_tlv_data,
11031202 }
....@@ -1108,7 +1207,6 @@
11081207 {
11091208 struct qedi_work *qedi_work;
11101209 struct qedi_conn *q_conn;
1111
- struct iscsi_conn *conn;
11121210 struct qedi_cmd *qedi_cmd;
11131211 u32 iscsi_cid;
11141212 int rc = 0;
....@@ -1121,7 +1219,6 @@
11211219 iscsi_cid);
11221220 return -1;
11231221 }
1124
- conn = q_conn->cls_conn->dd_data;
11251222
11261223 switch (cqe->cqe_common.cqe_type) {
11271224 case ISCSI_CQE_TYPE_SOLICITED:
....@@ -1254,13 +1351,13 @@
12541351 "process already running\n");
12551352 }
12561353
1257
- if (qedi_fp_has_work(fp) == 0)
1354
+ if (!qedi_fp_has_work(fp))
12581355 qed_sb_update_sb_idx(fp->sb_info);
12591356
12601357 /* Check for more work */
12611358 rmb();
12621359
1263
- if (qedi_fp_has_work(fp) == 0)
1360
+ if (!qedi_fp_has_work(fp))
12641361 qed_sb_ack(fp->sb_info, IGU_INT_ENABLE, 1);
12651362 else
12661363 goto process_again;
....@@ -1281,13 +1378,20 @@
12811378 static void qedi_sync_free_irqs(struct qedi_ctx *qedi)
12821379 {
12831380 int i;
1381
+ u16 idx;
12841382
12851383 if (qedi->int_info.msix_cnt) {
12861384 for (i = 0; i < qedi->int_info.used_cnt; i++) {
1287
- synchronize_irq(qedi->int_info.msix[i].vector);
1288
- irq_set_affinity_hint(qedi->int_info.msix[i].vector,
1385
+ idx = i * qedi->dev_info.common.num_hwfns +
1386
+ qedi_ops->common->get_affin_hwfn_idx(qedi->cdev);
1387
+
1388
+ QEDI_INFO(&qedi->dbg_ctx, QEDI_LOG_INFO,
1389
+ "Freeing IRQ #%d vector_idx=%d.\n", i, idx);
1390
+
1391
+ synchronize_irq(qedi->int_info.msix[idx].vector);
1392
+ irq_set_affinity_hint(qedi->int_info.msix[idx].vector,
12891393 NULL);
1290
- free_irq(qedi->int_info.msix[i].vector,
1394
+ free_irq(qedi->int_info.msix[idx].vector,
12911395 &qedi->fp_array[i]);
12921396 }
12931397 } else {
....@@ -1302,20 +1406,28 @@
13021406 static int qedi_request_msix_irq(struct qedi_ctx *qedi)
13031407 {
13041408 int i, rc, cpu;
1409
+ u16 idx;
13051410
13061411 cpu = cpumask_first(cpu_online_mask);
1307
- for (i = 0; i < MIN_NUM_CPUS_MSIX(qedi); i++) {
1308
- rc = request_irq(qedi->int_info.msix[i].vector,
1412
+ for (i = 0; i < qedi->msix_count; i++) {
1413
+ idx = i * qedi->dev_info.common.num_hwfns +
1414
+ qedi_ops->common->get_affin_hwfn_idx(qedi->cdev);
1415
+
1416
+ QEDI_INFO(&qedi->dbg_ctx, QEDI_LOG_INFO,
1417
+ "dev_info: num_hwfns=%d affin_hwfn_idx=%d.\n",
1418
+ qedi->dev_info.common.num_hwfns,
1419
+ qedi_ops->common->get_affin_hwfn_idx(qedi->cdev));
1420
+
1421
+ rc = request_irq(qedi->int_info.msix[idx].vector,
13091422 qedi_msix_handler, 0, "qedi",
13101423 &qedi->fp_array[i]);
1311
-
13121424 if (rc) {
13131425 QEDI_WARN(&qedi->dbg_ctx, "request_irq failed.\n");
13141426 qedi_sync_free_irqs(qedi);
13151427 return rc;
13161428 }
13171429 qedi->int_info.used_cnt++;
1318
- rc = irq_set_affinity_hint(qedi->int_info.msix[i].vector,
1430
+ rc = irq_set_affinity_hint(qedi->int_info.msix[idx].vector,
13191431 get_cpu_mask(cpu));
13201432 cpu = cpumask_next(cpu, cpu_online_mask);
13211433 }
....@@ -1327,7 +1439,12 @@
13271439 {
13281440 int rc = 0;
13291441
1330
- rc = qedi_ops->common->set_fp_int(qedi->cdev, num_online_cpus());
1442
+ rc = qedi_ops->common->set_fp_int(qedi->cdev, qedi->num_queues);
1443
+ if (rc < 0)
1444
+ goto exit_setup_int;
1445
+
1446
+ qedi->msix_count = rc;
1447
+
13311448 rc = qedi_ops->common->get_fp_int(qedi->cdev, &qedi->int_info);
13321449 if (rc)
13331450 goto exit_setup_int;
....@@ -1360,12 +1477,9 @@
13601477
13611478 static int qedi_alloc_nvm_iscsi_cfg(struct qedi_ctx *qedi)
13621479 {
1363
- struct qedi_nvm_iscsi_image nvm_image;
1364
-
1365
- qedi->iscsi_image = dma_zalloc_coherent(&qedi->pdev->dev,
1366
- sizeof(nvm_image),
1367
- &qedi->nvm_buf_dma,
1368
- GFP_KERNEL);
1480
+ qedi->iscsi_image = dma_alloc_coherent(&qedi->pdev->dev,
1481
+ sizeof(struct qedi_nvm_iscsi_image),
1482
+ &qedi->nvm_buf_dma, GFP_KERNEL);
13691483 if (!qedi->iscsi_image) {
13701484 QEDI_ERR(&qedi->dbg_ctx, "Could not allocate NVM BUF.\n");
13711485 return -ENOMEM;
....@@ -1382,7 +1496,7 @@
13821496 int i;
13831497
13841498 if (qedi->bdq_pbl_list)
1385
- dma_free_coherent(&qedi->pdev->dev, PAGE_SIZE,
1499
+ dma_free_coherent(&qedi->pdev->dev, QEDI_PAGE_SIZE,
13861500 qedi->bdq_pbl_list, qedi->bdq_pbl_list_dma);
13871501
13881502 if (qedi->bdq_pbl)
....@@ -1443,7 +1557,7 @@
14431557
14441558 /* Alloc dma memory for BDQ page buffer list */
14451559 qedi->bdq_pbl_mem_size = QEDI_BDQ_NUM * sizeof(struct scsi_bd);
1446
- qedi->bdq_pbl_mem_size = ALIGN(qedi->bdq_pbl_mem_size, PAGE_SIZE);
1560
+ qedi->bdq_pbl_mem_size = ALIGN(qedi->bdq_pbl_mem_size, QEDI_PAGE_SIZE);
14471561 qedi->rq_num_entries = qedi->bdq_pbl_mem_size / sizeof(struct scsi_bd);
14481562
14491563 QEDI_INFO(&qedi->dbg_ctx, QEDI_LOG_CONN, "rq_num_entries = %d.\n",
....@@ -1478,9 +1592,10 @@
14781592 }
14791593
14801594 /* Allocate list of PBL pages */
1481
- qedi->bdq_pbl_list = dma_zalloc_coherent(&qedi->pdev->dev, PAGE_SIZE,
1482
- &qedi->bdq_pbl_list_dma,
1483
- GFP_KERNEL);
1595
+ qedi->bdq_pbl_list = dma_alloc_coherent(&qedi->pdev->dev,
1596
+ QEDI_PAGE_SIZE,
1597
+ &qedi->bdq_pbl_list_dma,
1598
+ GFP_KERNEL);
14841599 if (!qedi->bdq_pbl_list) {
14851600 QEDI_ERR(&qedi->dbg_ctx,
14861601 "Could not allocate list of PBL pages.\n");
....@@ -1491,13 +1606,14 @@
14911606 * Now populate PBL list with pages that contain pointers to the
14921607 * individual buffers.
14931608 */
1494
- qedi->bdq_pbl_list_num_entries = qedi->bdq_pbl_mem_size / PAGE_SIZE;
1609
+ qedi->bdq_pbl_list_num_entries = qedi->bdq_pbl_mem_size /
1610
+ QEDI_PAGE_SIZE;
14951611 list = (u64 *)qedi->bdq_pbl_list;
14961612 page = qedi->bdq_pbl_list_dma;
14971613 for (i = 0; i < qedi->bdq_pbl_list_num_entries; i++) {
14981614 *list = qedi->bdq_pbl_dma;
14991615 list++;
1500
- page += PAGE_SIZE;
1616
+ page += QEDI_PAGE_SIZE;
15011617 }
15021618
15031619 return 0;
....@@ -1576,10 +1692,10 @@
15761692 (qedi->global_queues[i]->cq_pbl_size +
15771693 (QEDI_PAGE_SIZE - 1));
15781694
1579
- qedi->global_queues[i]->cq = dma_zalloc_coherent(&qedi->pdev->dev,
1580
- qedi->global_queues[i]->cq_mem_size,
1581
- &qedi->global_queues[i]->cq_dma,
1582
- GFP_KERNEL);
1695
+ qedi->global_queues[i]->cq = dma_alloc_coherent(&qedi->pdev->dev,
1696
+ qedi->global_queues[i]->cq_mem_size,
1697
+ &qedi->global_queues[i]->cq_dma,
1698
+ GFP_KERNEL);
15831699
15841700 if (!qedi->global_queues[i]->cq) {
15851701 QEDI_WARN(&qedi->dbg_ctx,
....@@ -1587,10 +1703,10 @@
15871703 status = -ENOMEM;
15881704 goto mem_alloc_failure;
15891705 }
1590
- qedi->global_queues[i]->cq_pbl = dma_zalloc_coherent(&qedi->pdev->dev,
1591
- qedi->global_queues[i]->cq_pbl_size,
1592
- &qedi->global_queues[i]->cq_pbl_dma,
1593
- GFP_KERNEL);
1706
+ qedi->global_queues[i]->cq_pbl = dma_alloc_coherent(&qedi->pdev->dev,
1707
+ qedi->global_queues[i]->cq_pbl_size,
1708
+ &qedi->global_queues[i]->cq_pbl_dma,
1709
+ GFP_KERNEL);
15941710
15951711 if (!qedi->global_queues[i]->cq_pbl) {
15961712 QEDI_WARN(&qedi->dbg_ctx,
....@@ -1658,16 +1774,16 @@
16581774 ep->sq_pbl_size = (ep->sq_mem_size / QEDI_PAGE_SIZE) * sizeof(void *);
16591775 ep->sq_pbl_size = ep->sq_pbl_size + QEDI_PAGE_SIZE;
16601776
1661
- ep->sq = dma_zalloc_coherent(&qedi->pdev->dev, ep->sq_mem_size,
1662
- &ep->sq_dma, GFP_KERNEL);
1777
+ ep->sq = dma_alloc_coherent(&qedi->pdev->dev, ep->sq_mem_size,
1778
+ &ep->sq_dma, GFP_KERNEL);
16631779 if (!ep->sq) {
16641780 QEDI_WARN(&qedi->dbg_ctx,
16651781 "Could not allocate send queue.\n");
16661782 rval = -ENOMEM;
16671783 goto out;
16681784 }
1669
- ep->sq_pbl = dma_zalloc_coherent(&qedi->pdev->dev, ep->sq_pbl_size,
1670
- &ep->sq_pbl_dma, GFP_KERNEL);
1785
+ ep->sq_pbl = dma_alloc_coherent(&qedi->pdev->dev, ep->sq_pbl_size,
1786
+ &ep->sq_pbl_dma, GFP_KERNEL);
16711787 if (!ep->sq_pbl) {
16721788 QEDI_WARN(&qedi->dbg_ctx,
16731789 "Could not allocate send queue PBL.\n");
....@@ -1902,7 +2018,7 @@
19022018 qedi_ops->ll2->start(qedi->cdev, &params);
19032019 }
19042020
1905
-/**
2021
+/*
19062022 * qedi_get_nvram_block: - Scan through the iSCSI NVRAM block (while accounting
19072023 * for gaps) for the matching absolute-pf-id of the QEDI device.
19082024 */
....@@ -2204,14 +2320,13 @@
22042320 static int qedi_get_boot_info(struct qedi_ctx *qedi)
22052321 {
22062322 int ret = 1;
2207
- struct qedi_nvm_iscsi_image nvm_image;
22082323
22092324 QEDI_INFO(&qedi->dbg_ctx, QEDI_LOG_INFO,
22102325 "Get NVM iSCSI CFG image\n");
22112326 ret = qedi_ops->common->nvm_get_image(qedi->cdev,
22122327 QED_NVM_IMAGE_ISCSI_CFG,
22132328 (char *)qedi->iscsi_image,
2214
- sizeof(nvm_image));
2329
+ sizeof(struct qedi_nvm_iscsi_image));
22152330 if (ret)
22162331 QEDI_ERR(&qedi->dbg_ctx,
22172332 "Could not get NVM image. ret = %d\n", ret);
....@@ -2279,21 +2394,47 @@
22792394 return -ENOMEM;
22802395 }
22812396
2397
+static pci_ers_result_t qedi_io_error_detected(struct pci_dev *pdev,
2398
+ pci_channel_state_t state)
2399
+{
2400
+ struct qedi_ctx *qedi = pci_get_drvdata(pdev);
2401
+
2402
+ QEDI_ERR(&qedi->dbg_ctx, "%s: PCI error detected [%d]\n",
2403
+ __func__, state);
2404
+
2405
+ if (test_and_set_bit(QEDI_IN_RECOVERY, &qedi->flags)) {
2406
+ QEDI_INFO(&qedi->dbg_ctx, QEDI_LOG_INFO,
2407
+ "Recovery already in progress.\n");
2408
+ return PCI_ERS_RESULT_NONE;
2409
+ }
2410
+
2411
+ qedi_ops->common->recovery_process(qedi->cdev);
2412
+
2413
+ return PCI_ERS_RESULT_CAN_RECOVER;
2414
+}
2415
+
22822416 static void __qedi_remove(struct pci_dev *pdev, int mode)
22832417 {
22842418 struct qedi_ctx *qedi = pci_get_drvdata(pdev);
22852419 int rval;
2420
+ u16 retry = 10;
22862421
2287
- if (qedi->tmf_thread) {
2288
- flush_workqueue(qedi->tmf_thread);
2289
- destroy_workqueue(qedi->tmf_thread);
2290
- qedi->tmf_thread = NULL;
2291
- }
2422
+ if (mode == QEDI_MODE_SHUTDOWN)
2423
+ iscsi_host_for_each_session(qedi->shost,
2424
+ qedi_clear_session_ctx);
22922425
2293
- if (qedi->offload_thread) {
2294
- flush_workqueue(qedi->offload_thread);
2295
- destroy_workqueue(qedi->offload_thread);
2296
- qedi->offload_thread = NULL;
2426
+ if (mode == QEDI_MODE_NORMAL || mode == QEDI_MODE_SHUTDOWN) {
2427
+ if (qedi->tmf_thread) {
2428
+ flush_workqueue(qedi->tmf_thread);
2429
+ destroy_workqueue(qedi->tmf_thread);
2430
+ qedi->tmf_thread = NULL;
2431
+ }
2432
+
2433
+ if (qedi->offload_thread) {
2434
+ flush_workqueue(qedi->offload_thread);
2435
+ destroy_workqueue(qedi->offload_thread);
2436
+ qedi->offload_thread = NULL;
2437
+ }
22972438 }
22982439
22992440 #ifdef CONFIG_DEBUG_FS
....@@ -2305,12 +2446,17 @@
23052446 qedi_sync_free_irqs(qedi);
23062447
23072448 if (!test_bit(QEDI_IN_OFFLINE, &qedi->flags)) {
2308
- qedi_ops->stop(qedi->cdev);
2449
+ while (retry--) {
2450
+ rval = qedi_ops->stop(qedi->cdev);
2451
+ if (rval < 0)
2452
+ msleep(1000);
2453
+ else
2454
+ break;
2455
+ }
23092456 qedi_ops->ll2->stop(qedi->cdev);
23102457 }
23112458
2312
- if (mode == QEDI_MODE_NORMAL)
2313
- qedi_free_iscsi_pf_param(qedi);
2459
+ qedi_free_iscsi_pf_param(qedi);
23142460
23152461 rval = qedi_ops->common->update_drv_state(qedi->cdev, false);
23162462 if (rval)
....@@ -2323,14 +2469,11 @@
23232469
23242470 qedi_destroy_fp(qedi);
23252471
2326
- if (mode == QEDI_MODE_NORMAL) {
2472
+ if (mode == QEDI_MODE_NORMAL || mode == QEDI_MODE_SHUTDOWN) {
23272473 qedi_release_cid_que(qedi);
23282474 qedi_cm_free_mem(qedi);
23292475 qedi_free_uio(qedi->udev);
23302476 qedi_free_itt(qedi);
2331
-
2332
- iscsi_host_remove(qedi->shost);
2333
- iscsi_host_free(qedi->shost);
23342477
23352478 if (qedi->ll2_recv_thread) {
23362479 kthread_stop(qedi->ll2_recv_thread);
....@@ -2340,14 +2483,41 @@
23402483
23412484 if (qedi->boot_kset)
23422485 iscsi_boot_destroy_kset(qedi->boot_kset);
2486
+
2487
+ iscsi_host_remove(qedi->shost);
2488
+ iscsi_host_free(qedi->shost);
23432489 }
2490
+}
2491
+
2492
+static void qedi_board_disable_work(struct work_struct *work)
2493
+{
2494
+ struct qedi_ctx *qedi =
2495
+ container_of(work, struct qedi_ctx,
2496
+ board_disable_work.work);
2497
+
2498
+ QEDI_INFO(&qedi->dbg_ctx, QEDI_LOG_INFO,
2499
+ "Fan failure, Unloading firmware context.\n");
2500
+
2501
+ if (test_and_set_bit(QEDI_IN_SHUTDOWN, &qedi->flags))
2502
+ return;
2503
+
2504
+ __qedi_remove(qedi->pdev, QEDI_MODE_SHUTDOWN);
2505
+}
2506
+
2507
+static void qedi_shutdown(struct pci_dev *pdev)
2508
+{
2509
+ struct qedi_ctx *qedi = pci_get_drvdata(pdev);
2510
+
2511
+ QEDI_ERR(&qedi->dbg_ctx, "%s: Shutdown qedi\n", __func__);
2512
+ if (test_and_set_bit(QEDI_IN_SHUTDOWN, &qedi->flags))
2513
+ return;
2514
+ __qedi_remove(pdev, QEDI_MODE_SHUTDOWN);
23442515 }
23452516
23462517 static int __qedi_probe(struct pci_dev *pdev, int mode)
23472518 {
23482519 struct qedi_ctx *qedi;
23492520 struct qed_ll2_params params;
2350
- u32 dp_module = 0;
23512521 u8 dp_level = 0;
23522522 bool is_vf = false;
23532523 char host_buf[16];
....@@ -2356,7 +2526,7 @@
23562526 struct qed_probe_params qed_params;
23572527 void *task_start, *task_end;
23582528 int rc;
2359
- u16 tmp;
2529
+ u16 retry = 10;
23602530
23612531 if (mode != QEDI_MODE_RECOVERY) {
23622532 qedi = qedi_host_alloc(pdev);
....@@ -2368,32 +2538,48 @@
23682538 qedi = pci_get_drvdata(pdev);
23692539 }
23702540
2541
+retry_probe:
2542
+ if (mode == QEDI_MODE_RECOVERY)
2543
+ msleep(2000);
2544
+
23712545 memset(&qed_params, 0, sizeof(qed_params));
23722546 qed_params.protocol = QED_PROTOCOL_ISCSI;
2373
- qed_params.dp_module = dp_module;
2547
+ qed_params.dp_module = qedi_qed_debug;
23742548 qed_params.dp_level = dp_level;
23752549 qed_params.is_vf = is_vf;
23762550 qedi->cdev = qedi_ops->common->probe(pdev, &qed_params);
23772551 if (!qedi->cdev) {
2552
+ if (mode == QEDI_MODE_RECOVERY && retry) {
2553
+ QEDI_INFO(&qedi->dbg_ctx, QEDI_LOG_INFO,
2554
+ "Retry %d initialize hardware\n", retry);
2555
+ retry--;
2556
+ goto retry_probe;
2557
+ }
2558
+
23782559 rc = -ENODEV;
23792560 QEDI_ERR(&qedi->dbg_ctx, "Cannot initialize hardware\n");
23802561 goto free_host;
23812562 }
23822563
2564
+ set_bit(QEDI_ERR_ATTN_CLR_EN, &qedi->qedi_err_flags);
2565
+ set_bit(QEDI_ERR_IS_RECOVERABLE, &qedi->qedi_err_flags);
23832566 atomic_set(&qedi->link_state, QEDI_LINK_DOWN);
23842567
23852568 rc = qedi_ops->fill_dev_info(qedi->cdev, &qedi->dev_info);
23862569 if (rc)
23872570 goto free_host;
23882571
2389
- if (mode != QEDI_MODE_RECOVERY) {
2390
- rc = qedi_set_iscsi_pf_param(qedi);
2391
- if (rc) {
2392
- rc = -ENOMEM;
2393
- QEDI_ERR(&qedi->dbg_ctx,
2394
- "Set iSCSI pf param fail\n");
2395
- goto free_host;
2396
- }
2572
+ QEDI_INFO(&qedi->dbg_ctx, QEDI_LOG_INFO,
2573
+ "dev_info: num_hwfns=%d affin_hwfn_idx=%d.\n",
2574
+ qedi->dev_info.common.num_hwfns,
2575
+ qedi_ops->common->get_affin_hwfn_idx(qedi->cdev));
2576
+
2577
+ rc = qedi_set_iscsi_pf_param(qedi);
2578
+ if (rc) {
2579
+ rc = -ENOMEM;
2580
+ QEDI_ERR(&qedi->dbg_ctx,
2581
+ "Set iSCSI pf param fail\n");
2582
+ goto free_host;
23972583 }
23982584
23992585 qedi_ops->common->update_pf_params(qedi->cdev, &qedi->pf_params);
....@@ -2452,15 +2638,15 @@
24522638 "Writing %d to primary and secondary BDQ doorbell registers.\n",
24532639 qedi->bdq_prod_idx);
24542640 writew(qedi->bdq_prod_idx, qedi->bdq_primary_prod);
2455
- tmp = readw(qedi->bdq_primary_prod);
2641
+ readw(qedi->bdq_primary_prod);
24562642 writew(qedi->bdq_prod_idx, qedi->bdq_secondary_prod);
2457
- tmp = readw(qedi->bdq_secondary_prod);
2643
+ readw(qedi->bdq_secondary_prod);
24582644
24592645 ether_addr_copy(qedi->mac, qedi->dev_info.common.hw_mac);
24602646 QEDI_INFO(&qedi->dbg_ctx, QEDI_LOG_DISC, "MAC address is %pM.\n",
24612647 qedi->mac);
24622648
2463
- sprintf(host_buf, "host_%d", qedi->shost->host_no);
2649
+ snprintf(host_buf, sizeof(host_buf), "host_%d", qedi->shost->host_no);
24642650 qedi_ops->common->set_name(qedi->cdev, host_buf);
24652651
24662652 qedi_ops->register_ops(qedi->cdev, &qedi_cb_ops, qedi);
....@@ -2584,6 +2770,10 @@
25842770 goto free_tmf_thread;
25852771 }
25862772
2773
+ INIT_DELAYED_WORK(&qedi->recovery_work, qedi_recovery_handler);
2774
+ INIT_DELAYED_WORK(&qedi->board_disable_work,
2775
+ qedi_board_disable_work);
2776
+
25872777 /* F/w needs 1st task context memory entry for performance */
25882778 set_bit(QEDI_RESERVE_TASK_ID, qedi->task_idx_map);
25892779 atomic_set(&qedi->num_offloads, 0);
....@@ -2626,6 +2816,32 @@
26262816 return rc;
26272817 }
26282818
2819
+static void qedi_mark_conn_recovery(struct iscsi_cls_session *cls_session)
2820
+{
2821
+ struct iscsi_session *session = cls_session->dd_data;
2822
+ struct iscsi_conn *conn = session->leadconn;
2823
+ struct qedi_conn *qedi_conn = conn->dd_data;
2824
+
2825
+ iscsi_conn_failure(qedi_conn->cls_conn->dd_data, ISCSI_ERR_CONN_FAILED);
2826
+}
2827
+
2828
+static void qedi_recovery_handler(struct work_struct *work)
2829
+{
2830
+ struct qedi_ctx *qedi =
2831
+ container_of(work, struct qedi_ctx, recovery_work.work);
2832
+
2833
+ iscsi_host_for_each_session(qedi->shost, qedi_mark_conn_recovery);
2834
+
2835
+ /* Call common_ops->recovery_prolog to allow the MFW to quiesce
2836
+ * any PCI transactions.
2837
+ */
2838
+ qedi_ops->common->recovery_prolog(qedi->cdev);
2839
+
2840
+ __qedi_remove(qedi->pdev, QEDI_MODE_RECOVERY);
2841
+ __qedi_probe(qedi->pdev, QEDI_MODE_RECOVERY);
2842
+ clear_bit(QEDI_IN_RECOVERY, &qedi->flags);
2843
+}
2844
+
26292845 static int qedi_probe(struct pci_dev *pdev, const struct pci_device_id *id)
26302846 {
26312847 return __qedi_probe(pdev, QEDI_MODE_NORMAL);
....@@ -2645,11 +2861,17 @@
26452861
26462862 static enum cpuhp_state qedi_cpuhp_state;
26472863
2864
+static struct pci_error_handlers qedi_err_handler = {
2865
+ .error_detected = qedi_io_error_detected,
2866
+};
2867
+
26482868 static struct pci_driver qedi_pci_driver = {
26492869 .name = QEDI_MODULE_NAME,
26502870 .id_table = qedi_pci_tbl,
26512871 .probe = qedi_probe,
26522872 .remove = qedi_remove,
2873
+ .shutdown = qedi_shutdown,
2874
+ .err_handler = &qedi_err_handler,
26532875 };
26542876
26552877 static int __init qedi_init(void)