hc
2024-01-03 2f7c68cb55ecb7331f2381deb497c27155f32faf
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,10 @@
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);
72
+static int qedi_suspend(struct pci_dev *pdev, pm_message_t state);
5973
6074 static int qedi_iscsi_event_cb(void *context, u8 fw_event_code, void *fw_handle)
6175 {
....@@ -228,7 +242,7 @@
228242 }
229243
230244 /* Allocating memory for Tx/Rx pkt buffer */
231
- udev->ll2_buf_size = TX_RX_RING * LL2_SINGLE_BUF_SIZE;
245
+ udev->ll2_buf_size = TX_RX_RING * qedi_ll2_buf_size;
232246 udev->ll2_buf_size = QEDI_PAGE_ALIGN(udev->ll2_buf_size);
233247 udev->ll2_buf = (void *)__get_free_pages(GFP_KERNEL | __GFP_COMP |
234248 __GFP_ZERO, 2);
....@@ -283,7 +297,7 @@
283297 qedi->udev = udev;
284298
285299 udev->tx_pkt = udev->ll2_buf;
286
- udev->rx_pkt = udev->ll2_buf + LL2_SINGLE_BUF_SIZE;
300
+ udev->rx_pkt = udev->ll2_buf + qedi_ll2_buf_size;
287301 return 0;
288302
289303 err_uctrl:
....@@ -644,8 +658,7 @@
644658 qedi->max_active_conns = ISCSI_MAX_SESS_PER_HBA;
645659 qedi->max_sqes = QEDI_SQ_SIZE;
646660
647
- if (shost_use_blk_mq(shost))
648
- shost->nr_hw_queues = MIN_NUM_CPUS_MSIX(qedi);
661
+ shost->nr_hw_queues = MIN_NUM_CPUS_MSIX(qedi);
649662
650663 pci_set_drvdata(pdev, qedi);
651664
....@@ -656,10 +669,8 @@
656669 static int qedi_ll2_rx(void *cookie, struct sk_buff *skb, u32 arg1, u32 arg2)
657670 {
658671 struct qedi_ctx *qedi = (struct qedi_ctx *)cookie;
659
- struct qedi_uio_dev *udev;
660
- struct qedi_uio_ctrl *uctrl;
661672 struct skb_work_list *work;
662
- u32 prod;
673
+ struct ethhdr *eh;
663674
664675 if (!qedi) {
665676 QEDI_ERR(NULL, "qedi is NULL\n");
....@@ -673,8 +684,28 @@
673684 return 0;
674685 }
675686
676
- udev = qedi->udev;
677
- uctrl = udev->uctrl;
687
+ eh = (struct ethhdr *)skb->data;
688
+ /* Undo VLAN encapsulation */
689
+ if (eh->h_proto == htons(ETH_P_8021Q)) {
690
+ memmove((u8 *)eh + VLAN_HLEN, eh, ETH_ALEN * 2);
691
+ eh = (struct ethhdr *)skb_pull(skb, VLAN_HLEN);
692
+ skb_reset_mac_header(skb);
693
+ }
694
+
695
+ /* Filter out non FIP/FCoE frames here to free them faster */
696
+ if (eh->h_proto != htons(ETH_P_ARP) &&
697
+ eh->h_proto != htons(ETH_P_IP) &&
698
+ eh->h_proto != htons(ETH_P_IPV6)) {
699
+ QEDI_INFO(&qedi->dbg_ctx, QEDI_LOG_LL2,
700
+ "Dropping frame ethertype [0x%x] len [0x%x].\n",
701
+ eh->h_proto, skb->len);
702
+ kfree_skb(skb);
703
+ return 0;
704
+ }
705
+
706
+ QEDI_INFO(&qedi->dbg_ctx, QEDI_LOG_LL2,
707
+ "Allowed frame ethertype [0x%x] len [0x%x].\n",
708
+ eh->h_proto, skb->len);
678709
679710 work = kzalloc(sizeof(*work), GFP_ATOMIC);
680711 if (!work) {
....@@ -695,17 +726,10 @@
695726
696727 spin_lock_bh(&qedi->ll2_lock);
697728 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
-
708729 spin_unlock_bh(&qedi->ll2_lock);
730
+
731
+ wake_up_process(qedi->ll2_recv_thread);
732
+
709733 return 0;
710734 }
711735
....@@ -720,6 +744,7 @@
720744 u32 rx_bd_prod;
721745 void *pkt;
722746 int len = 0;
747
+ u32 prod;
723748
724749 if (!qedi) {
725750 QEDI_ERR(NULL, "qedi is NULL\n");
....@@ -728,12 +753,16 @@
728753
729754 udev = qedi->udev;
730755 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);
756
+
757
+ ++uctrl->hw_rx_prod_cnt;
758
+ prod = (uctrl->hw_rx_prod + 1) % RX_RING;
759
+
760
+ pkt = udev->rx_pkt + (prod * qedi_ll2_buf_size);
761
+ len = min_t(u32, skb->len, (u32)qedi_ll2_buf_size);
733762 memcpy(pkt, skb->data, len);
734763
735764 memset(&rxbd, 0, sizeof(rxbd));
736
- rxbd.rx_pkt_index = uctrl->hw_rx_prod;
765
+ rxbd.rx_pkt_index = prod;
737766 rxbd.rx_pkt_len = len;
738767 rxbd.vlan_id = vlan_id;
739768
....@@ -743,6 +772,16 @@
743772 p_rxbd += rx_bd_prod;
744773
745774 memcpy(p_rxbd, &rxbd, sizeof(rxbd));
775
+
776
+ QEDI_INFO(&qedi->dbg_ctx, QEDI_LOG_LL2,
777
+ "hw_rx_prod [%d] prod [%d] hw_rx_bd_prod [%d] rx_pkt_idx [%d] rx_len [%d].\n",
778
+ uctrl->hw_rx_prod, prod, uctrl->hw_rx_bd_prod,
779
+ rxbd.rx_pkt_index, rxbd.rx_pkt_len);
780
+ QEDI_INFO(&qedi->dbg_ctx, QEDI_LOG_LL2,
781
+ "host_rx_cons [%d] hw_rx_bd_cons [%d].\n",
782
+ uctrl->host_rx_cons, uctrl->host_rx_bd_cons);
783
+
784
+ uctrl->hw_rx_prod = prod;
746785
747786 /* notify the iscsiuio about new packet */
748787 uio_event_notify(&udev->qedi_uinfo);
....@@ -757,8 +796,7 @@
757796 spin_lock_bh(&qedi->ll2_lock);
758797 list_for_each_entry_safe(work, work_tmp, &qedi->ll2_skb_list, list) {
759798 list_del(&work->list);
760
- if (work->skb)
761
- kfree_skb(work->skb);
799
+ kfree_skb(work->skb);
762800 kfree(work);
763801 }
764802 spin_unlock_bh(&qedi->ll2_lock);
....@@ -796,7 +834,7 @@
796834 int rval = 0;
797835
798836
799
- num_sq_pages = (MAX_OUSTANDING_TASKS_PER_CON * 8) / PAGE_SIZE;
837
+ num_sq_pages = (MAX_OUTSTANDING_TASKS_PER_CON * 8) / QEDI_PAGE_SIZE;
800838
801839 qedi->num_queues = MIN_NUM_CPUS_MSIX(qedi);
802840
....@@ -806,11 +844,11 @@
806844 memset(&qedi->pf_params.iscsi_pf_params, 0,
807845 sizeof(qedi->pf_params.iscsi_pf_params));
808846
809
- qedi->p_cpuq = pci_alloc_consistent(qedi->pdev,
847
+ qedi->p_cpuq = dma_alloc_coherent(&qedi->pdev->dev,
810848 qedi->num_queues * sizeof(struct qedi_glbl_q_params),
811
- &qedi->hw_p_cpuq);
849
+ &qedi->hw_p_cpuq, GFP_KERNEL);
812850 if (!qedi->p_cpuq) {
813
- QEDI_ERR(&qedi->dbg_ctx, "pci_alloc_consistent fail\n");
851
+ QEDI_ERR(&qedi->dbg_ctx, "dma_alloc_coherent fail\n");
814852 rval = -1;
815853 goto err_alloc_mem;
816854 }
....@@ -834,7 +872,7 @@
834872 qedi->pf_params.iscsi_pf_params.max_fin_rt = 2;
835873
836874 for (log_page_size = 0 ; log_page_size < 32 ; log_page_size++) {
837
- if ((1 << log_page_size) == PAGE_SIZE)
875
+ if ((1 << log_page_size) == QEDI_PAGE_SIZE)
838876 break;
839877 }
840878 qedi->pf_params.iscsi_pf_params.log_page_size = log_page_size;
....@@ -871,7 +909,7 @@
871909
872910 if (qedi->p_cpuq) {
873911 size = qedi->num_queues * sizeof(struct qedi_glbl_q_params);
874
- pci_free_consistent(qedi->pdev, size, qedi->p_cpuq,
912
+ dma_free_coherent(&qedi->pdev->dev, size, qedi->p_cpuq,
875913 qedi->hw_p_cpuq);
876914 }
877915
....@@ -888,7 +926,7 @@
888926 ipv6_en = !!(block->generic.ctrl_flags &
889927 NVM_ISCSI_CFG_GEN_IPV6_ENABLED);
890928
891
- snprintf(tgt->iscsi_name, sizeof(tgt->iscsi_name), "%s\n",
929
+ snprintf(tgt->iscsi_name, sizeof(tgt->iscsi_name), "%s",
892930 block->target[index].target_name.byte);
893931
894932 tgt->ipv6_en = ipv6_en;
....@@ -1081,6 +1119,65 @@
10811119 return;
10821120 }
10831121
1122
+void qedi_schedule_hw_err_handler(void *dev,
1123
+ enum qed_hw_err_type err_type)
1124
+{
1125
+ struct qedi_ctx *qedi = (struct qedi_ctx *)dev;
1126
+ unsigned long override_flags = qedi_flags_override;
1127
+
1128
+ if (override_flags && test_bit(QEDI_ERR_OVERRIDE_EN, &override_flags))
1129
+ qedi->qedi_err_flags = qedi_flags_override;
1130
+
1131
+ QEDI_INFO(&qedi->dbg_ctx, QEDI_LOG_INFO,
1132
+ "HW error handler scheduled, err=%d err_flags=0x%x\n",
1133
+ err_type, qedi->qedi_err_flags);
1134
+
1135
+ switch (err_type) {
1136
+ case QED_HW_ERR_FAN_FAIL:
1137
+ schedule_delayed_work(&qedi->board_disable_work, 0);
1138
+ break;
1139
+ case QED_HW_ERR_MFW_RESP_FAIL:
1140
+ case QED_HW_ERR_HW_ATTN:
1141
+ case QED_HW_ERR_DMAE_FAIL:
1142
+ case QED_HW_ERR_RAMROD_FAIL:
1143
+ case QED_HW_ERR_FW_ASSERT:
1144
+ /* Prevent HW attentions from being reasserted */
1145
+ if (test_bit(QEDI_ERR_ATTN_CLR_EN, &qedi->qedi_err_flags))
1146
+ qedi_ops->common->attn_clr_enable(qedi->cdev, true);
1147
+
1148
+ if (err_type == QED_HW_ERR_RAMROD_FAIL &&
1149
+ test_bit(QEDI_ERR_IS_RECOVERABLE, &qedi->qedi_err_flags))
1150
+ qedi_ops->common->recovery_process(qedi->cdev);
1151
+
1152
+ break;
1153
+ default:
1154
+ break;
1155
+ }
1156
+}
1157
+
1158
+static void qedi_schedule_recovery_handler(void *dev)
1159
+{
1160
+ struct qedi_ctx *qedi = dev;
1161
+
1162
+ QEDI_ERR(&qedi->dbg_ctx, "Recovery handler scheduled.\n");
1163
+
1164
+ if (test_and_set_bit(QEDI_IN_RECOVERY, &qedi->flags))
1165
+ return;
1166
+
1167
+ atomic_set(&qedi->link_state, QEDI_LINK_DOWN);
1168
+
1169
+ schedule_delayed_work(&qedi->recovery_work, 0);
1170
+}
1171
+
1172
+static void qedi_set_conn_recovery(struct iscsi_cls_session *cls_session)
1173
+{
1174
+ struct iscsi_session *session = cls_session->dd_data;
1175
+ struct iscsi_conn *conn = session->leadconn;
1176
+ struct qedi_conn *qedi_conn = conn->dd_data;
1177
+
1178
+ qedi_start_conn_recovery(qedi_conn->qedi, qedi_conn);
1179
+}
1180
+
10841181 static void qedi_link_update(void *dev, struct qed_link_output *link)
10851182 {
10861183 struct qedi_ctx *qedi = (struct qedi_ctx *)dev;
....@@ -1092,12 +1189,15 @@
10921189 QEDI_INFO(&qedi->dbg_ctx, QEDI_LOG_INFO,
10931190 "Link Down event.\n");
10941191 atomic_set(&qedi->link_state, QEDI_LINK_DOWN);
1192
+ iscsi_host_for_each_session(qedi->shost, qedi_set_conn_recovery);
10951193 }
10961194 }
10971195
10981196 static struct qed_iscsi_cb_ops qedi_cb_ops = {
10991197 {
11001198 .link_update = qedi_link_update,
1199
+ .schedule_recovery_handler = qedi_schedule_recovery_handler,
1200
+ .schedule_hw_err_handler = qedi_schedule_hw_err_handler,
11011201 .get_protocol_tlv_data = qedi_get_protocol_tlv_data,
11021202 .get_generic_tlv_data = qedi_get_generic_tlv_data,
11031203 }
....@@ -1108,7 +1208,6 @@
11081208 {
11091209 struct qedi_work *qedi_work;
11101210 struct qedi_conn *q_conn;
1111
- struct iscsi_conn *conn;
11121211 struct qedi_cmd *qedi_cmd;
11131212 u32 iscsi_cid;
11141213 int rc = 0;
....@@ -1121,7 +1220,6 @@
11211220 iscsi_cid);
11221221 return -1;
11231222 }
1124
- conn = q_conn->cls_conn->dd_data;
11251223
11261224 switch (cqe->cqe_common.cqe_type) {
11271225 case ISCSI_CQE_TYPE_SOLICITED:
....@@ -1254,13 +1352,13 @@
12541352 "process already running\n");
12551353 }
12561354
1257
- if (qedi_fp_has_work(fp) == 0)
1355
+ if (!qedi_fp_has_work(fp))
12581356 qed_sb_update_sb_idx(fp->sb_info);
12591357
12601358 /* Check for more work */
12611359 rmb();
12621360
1263
- if (qedi_fp_has_work(fp) == 0)
1361
+ if (!qedi_fp_has_work(fp))
12641362 qed_sb_ack(fp->sb_info, IGU_INT_ENABLE, 1);
12651363 else
12661364 goto process_again;
....@@ -1281,13 +1379,20 @@
12811379 static void qedi_sync_free_irqs(struct qedi_ctx *qedi)
12821380 {
12831381 int i;
1382
+ u16 idx;
12841383
12851384 if (qedi->int_info.msix_cnt) {
12861385 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,
1386
+ idx = i * qedi->dev_info.common.num_hwfns +
1387
+ qedi_ops->common->get_affin_hwfn_idx(qedi->cdev);
1388
+
1389
+ QEDI_INFO(&qedi->dbg_ctx, QEDI_LOG_INFO,
1390
+ "Freeing IRQ #%d vector_idx=%d.\n", i, idx);
1391
+
1392
+ synchronize_irq(qedi->int_info.msix[idx].vector);
1393
+ irq_set_affinity_hint(qedi->int_info.msix[idx].vector,
12891394 NULL);
1290
- free_irq(qedi->int_info.msix[i].vector,
1395
+ free_irq(qedi->int_info.msix[idx].vector,
12911396 &qedi->fp_array[i]);
12921397 }
12931398 } else {
....@@ -1302,20 +1407,28 @@
13021407 static int qedi_request_msix_irq(struct qedi_ctx *qedi)
13031408 {
13041409 int i, rc, cpu;
1410
+ u16 idx;
13051411
13061412 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,
1413
+ for (i = 0; i < qedi->msix_count; i++) {
1414
+ idx = i * qedi->dev_info.common.num_hwfns +
1415
+ qedi_ops->common->get_affin_hwfn_idx(qedi->cdev);
1416
+
1417
+ QEDI_INFO(&qedi->dbg_ctx, QEDI_LOG_INFO,
1418
+ "dev_info: num_hwfns=%d affin_hwfn_idx=%d.\n",
1419
+ qedi->dev_info.common.num_hwfns,
1420
+ qedi_ops->common->get_affin_hwfn_idx(qedi->cdev));
1421
+
1422
+ rc = request_irq(qedi->int_info.msix[idx].vector,
13091423 qedi_msix_handler, 0, "qedi",
13101424 &qedi->fp_array[i]);
1311
-
13121425 if (rc) {
13131426 QEDI_WARN(&qedi->dbg_ctx, "request_irq failed.\n");
13141427 qedi_sync_free_irqs(qedi);
13151428 return rc;
13161429 }
13171430 qedi->int_info.used_cnt++;
1318
- rc = irq_set_affinity_hint(qedi->int_info.msix[i].vector,
1431
+ rc = irq_set_affinity_hint(qedi->int_info.msix[idx].vector,
13191432 get_cpu_mask(cpu));
13201433 cpu = cpumask_next(cpu, cpu_online_mask);
13211434 }
....@@ -1327,7 +1440,12 @@
13271440 {
13281441 int rc = 0;
13291442
1330
- rc = qedi_ops->common->set_fp_int(qedi->cdev, num_online_cpus());
1443
+ rc = qedi_ops->common->set_fp_int(qedi->cdev, qedi->num_queues);
1444
+ if (rc < 0)
1445
+ goto exit_setup_int;
1446
+
1447
+ qedi->msix_count = rc;
1448
+
13311449 rc = qedi_ops->common->get_fp_int(qedi->cdev, &qedi->int_info);
13321450 if (rc)
13331451 goto exit_setup_int;
....@@ -1360,12 +1478,9 @@
13601478
13611479 static int qedi_alloc_nvm_iscsi_cfg(struct qedi_ctx *qedi)
13621480 {
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);
1481
+ qedi->iscsi_image = dma_alloc_coherent(&qedi->pdev->dev,
1482
+ sizeof(struct qedi_nvm_iscsi_image),
1483
+ &qedi->nvm_buf_dma, GFP_KERNEL);
13691484 if (!qedi->iscsi_image) {
13701485 QEDI_ERR(&qedi->dbg_ctx, "Could not allocate NVM BUF.\n");
13711486 return -ENOMEM;
....@@ -1382,7 +1497,7 @@
13821497 int i;
13831498
13841499 if (qedi->bdq_pbl_list)
1385
- dma_free_coherent(&qedi->pdev->dev, PAGE_SIZE,
1500
+ dma_free_coherent(&qedi->pdev->dev, QEDI_PAGE_SIZE,
13861501 qedi->bdq_pbl_list, qedi->bdq_pbl_list_dma);
13871502
13881503 if (qedi->bdq_pbl)
....@@ -1443,7 +1558,7 @@
14431558
14441559 /* Alloc dma memory for BDQ page buffer list */
14451560 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);
1561
+ qedi->bdq_pbl_mem_size = ALIGN(qedi->bdq_pbl_mem_size, QEDI_PAGE_SIZE);
14471562 qedi->rq_num_entries = qedi->bdq_pbl_mem_size / sizeof(struct scsi_bd);
14481563
14491564 QEDI_INFO(&qedi->dbg_ctx, QEDI_LOG_CONN, "rq_num_entries = %d.\n",
....@@ -1478,9 +1593,10 @@
14781593 }
14791594
14801595 /* 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);
1596
+ qedi->bdq_pbl_list = dma_alloc_coherent(&qedi->pdev->dev,
1597
+ QEDI_PAGE_SIZE,
1598
+ &qedi->bdq_pbl_list_dma,
1599
+ GFP_KERNEL);
14841600 if (!qedi->bdq_pbl_list) {
14851601 QEDI_ERR(&qedi->dbg_ctx,
14861602 "Could not allocate list of PBL pages.\n");
....@@ -1491,13 +1607,14 @@
14911607 * Now populate PBL list with pages that contain pointers to the
14921608 * individual buffers.
14931609 */
1494
- qedi->bdq_pbl_list_num_entries = qedi->bdq_pbl_mem_size / PAGE_SIZE;
1610
+ qedi->bdq_pbl_list_num_entries = qedi->bdq_pbl_mem_size /
1611
+ QEDI_PAGE_SIZE;
14951612 list = (u64 *)qedi->bdq_pbl_list;
14961613 page = qedi->bdq_pbl_list_dma;
14971614 for (i = 0; i < qedi->bdq_pbl_list_num_entries; i++) {
14981615 *list = qedi->bdq_pbl_dma;
14991616 list++;
1500
- page += PAGE_SIZE;
1617
+ page += QEDI_PAGE_SIZE;
15011618 }
15021619
15031620 return 0;
....@@ -1576,10 +1693,10 @@
15761693 (qedi->global_queues[i]->cq_pbl_size +
15771694 (QEDI_PAGE_SIZE - 1));
15781695
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);
1696
+ qedi->global_queues[i]->cq = dma_alloc_coherent(&qedi->pdev->dev,
1697
+ qedi->global_queues[i]->cq_mem_size,
1698
+ &qedi->global_queues[i]->cq_dma,
1699
+ GFP_KERNEL);
15831700
15841701 if (!qedi->global_queues[i]->cq) {
15851702 QEDI_WARN(&qedi->dbg_ctx,
....@@ -1587,10 +1704,10 @@
15871704 status = -ENOMEM;
15881705 goto mem_alloc_failure;
15891706 }
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);
1707
+ qedi->global_queues[i]->cq_pbl = dma_alloc_coherent(&qedi->pdev->dev,
1708
+ qedi->global_queues[i]->cq_pbl_size,
1709
+ &qedi->global_queues[i]->cq_pbl_dma,
1710
+ GFP_KERNEL);
15941711
15951712 if (!qedi->global_queues[i]->cq_pbl) {
15961713 QEDI_WARN(&qedi->dbg_ctx,
....@@ -1658,16 +1775,16 @@
16581775 ep->sq_pbl_size = (ep->sq_mem_size / QEDI_PAGE_SIZE) * sizeof(void *);
16591776 ep->sq_pbl_size = ep->sq_pbl_size + QEDI_PAGE_SIZE;
16601777
1661
- ep->sq = dma_zalloc_coherent(&qedi->pdev->dev, ep->sq_mem_size,
1662
- &ep->sq_dma, GFP_KERNEL);
1778
+ ep->sq = dma_alloc_coherent(&qedi->pdev->dev, ep->sq_mem_size,
1779
+ &ep->sq_dma, GFP_KERNEL);
16631780 if (!ep->sq) {
16641781 QEDI_WARN(&qedi->dbg_ctx,
16651782 "Could not allocate send queue.\n");
16661783 rval = -ENOMEM;
16671784 goto out;
16681785 }
1669
- ep->sq_pbl = dma_zalloc_coherent(&qedi->pdev->dev, ep->sq_pbl_size,
1670
- &ep->sq_pbl_dma, GFP_KERNEL);
1786
+ ep->sq_pbl = dma_alloc_coherent(&qedi->pdev->dev, ep->sq_pbl_size,
1787
+ &ep->sq_pbl_dma, GFP_KERNEL);
16711788 if (!ep->sq_pbl) {
16721789 QEDI_WARN(&qedi->dbg_ctx,
16731790 "Could not allocate send queue PBL.\n");
....@@ -1864,8 +1981,9 @@
18641981 struct qedi_percpu_s *p = this_cpu_ptr(&qedi_percpu);
18651982 struct qedi_work *work, *tmp;
18661983 struct task_struct *thread;
1984
+ unsigned long flags;
18671985
1868
- spin_lock_bh(&p->p_work_lock);
1986
+ spin_lock_irqsave(&p->p_work_lock, flags);
18691987 thread = p->iothread;
18701988 p->iothread = NULL;
18711989
....@@ -1876,7 +1994,7 @@
18761994 kfree(work);
18771995 }
18781996
1879
- spin_unlock_bh(&p->p_work_lock);
1997
+ spin_unlock_irqrestore(&p->p_work_lock, flags);
18801998 if (thread)
18811999 kthread_stop(thread);
18822000 return 0;
....@@ -1902,7 +2020,7 @@
19022020 qedi_ops->ll2->start(qedi->cdev, &params);
19032021 }
19042022
1905
-/**
2023
+/*
19062024 * qedi_get_nvram_block: - Scan through the iSCSI NVRAM block (while accounting
19072025 * for gaps) for the matching absolute-pf-id of the QEDI device.
19082026 */
....@@ -2204,14 +2322,13 @@
22042322 static int qedi_get_boot_info(struct qedi_ctx *qedi)
22052323 {
22062324 int ret = 1;
2207
- struct qedi_nvm_iscsi_image nvm_image;
22082325
22092326 QEDI_INFO(&qedi->dbg_ctx, QEDI_LOG_INFO,
22102327 "Get NVM iSCSI CFG image\n");
22112328 ret = qedi_ops->common->nvm_get_image(qedi->cdev,
22122329 QED_NVM_IMAGE_ISCSI_CFG,
22132330 (char *)qedi->iscsi_image,
2214
- sizeof(nvm_image));
2331
+ sizeof(struct qedi_nvm_iscsi_image));
22152332 if (ret)
22162333 QEDI_ERR(&qedi->dbg_ctx,
22172334 "Could not get NVM image. ret = %d\n", ret);
....@@ -2279,21 +2396,47 @@
22792396 return -ENOMEM;
22802397 }
22812398
2399
+static pci_ers_result_t qedi_io_error_detected(struct pci_dev *pdev,
2400
+ pci_channel_state_t state)
2401
+{
2402
+ struct qedi_ctx *qedi = pci_get_drvdata(pdev);
2403
+
2404
+ QEDI_ERR(&qedi->dbg_ctx, "%s: PCI error detected [%d]\n",
2405
+ __func__, state);
2406
+
2407
+ if (test_and_set_bit(QEDI_IN_RECOVERY, &qedi->flags)) {
2408
+ QEDI_INFO(&qedi->dbg_ctx, QEDI_LOG_INFO,
2409
+ "Recovery already in progress.\n");
2410
+ return PCI_ERS_RESULT_NONE;
2411
+ }
2412
+
2413
+ qedi_ops->common->recovery_process(qedi->cdev);
2414
+
2415
+ return PCI_ERS_RESULT_CAN_RECOVER;
2416
+}
2417
+
22822418 static void __qedi_remove(struct pci_dev *pdev, int mode)
22832419 {
22842420 struct qedi_ctx *qedi = pci_get_drvdata(pdev);
22852421 int rval;
2422
+ u16 retry = 10;
22862423
2287
- if (qedi->tmf_thread) {
2288
- flush_workqueue(qedi->tmf_thread);
2289
- destroy_workqueue(qedi->tmf_thread);
2290
- qedi->tmf_thread = NULL;
2291
- }
2424
+ if (mode == QEDI_MODE_SHUTDOWN)
2425
+ iscsi_host_for_each_session(qedi->shost,
2426
+ qedi_clear_session_ctx);
22922427
2293
- if (qedi->offload_thread) {
2294
- flush_workqueue(qedi->offload_thread);
2295
- destroy_workqueue(qedi->offload_thread);
2296
- qedi->offload_thread = NULL;
2428
+ if (mode == QEDI_MODE_NORMAL || mode == QEDI_MODE_SHUTDOWN) {
2429
+ if (qedi->tmf_thread) {
2430
+ flush_workqueue(qedi->tmf_thread);
2431
+ destroy_workqueue(qedi->tmf_thread);
2432
+ qedi->tmf_thread = NULL;
2433
+ }
2434
+
2435
+ if (qedi->offload_thread) {
2436
+ flush_workqueue(qedi->offload_thread);
2437
+ destroy_workqueue(qedi->offload_thread);
2438
+ qedi->offload_thread = NULL;
2439
+ }
22972440 }
22982441
22992442 #ifdef CONFIG_DEBUG_FS
....@@ -2305,12 +2448,20 @@
23052448 qedi_sync_free_irqs(qedi);
23062449
23072450 if (!test_bit(QEDI_IN_OFFLINE, &qedi->flags)) {
2308
- qedi_ops->stop(qedi->cdev);
2451
+ while (retry--) {
2452
+ rval = qedi_ops->stop(qedi->cdev);
2453
+ if (rval < 0)
2454
+ msleep(1000);
2455
+ else
2456
+ break;
2457
+ }
23092458 qedi_ops->ll2->stop(qedi->cdev);
23102459 }
23112460
2312
- if (mode == QEDI_MODE_NORMAL)
2313
- qedi_free_iscsi_pf_param(qedi);
2461
+ cancel_delayed_work_sync(&qedi->recovery_work);
2462
+ cancel_delayed_work_sync(&qedi->board_disable_work);
2463
+
2464
+ qedi_free_iscsi_pf_param(qedi);
23142465
23152466 rval = qedi_ops->common->update_drv_state(qedi->cdev, false);
23162467 if (rval)
....@@ -2323,14 +2474,11 @@
23232474
23242475 qedi_destroy_fp(qedi);
23252476
2326
- if (mode == QEDI_MODE_NORMAL) {
2477
+ if (mode == QEDI_MODE_NORMAL || mode == QEDI_MODE_SHUTDOWN) {
23272478 qedi_release_cid_que(qedi);
23282479 qedi_cm_free_mem(qedi);
23292480 qedi_free_uio(qedi->udev);
23302481 qedi_free_itt(qedi);
2331
-
2332
- iscsi_host_remove(qedi->shost);
2333
- iscsi_host_free(qedi->shost);
23342482
23352483 if (qedi->ll2_recv_thread) {
23362484 kthread_stop(qedi->ll2_recv_thread);
....@@ -2340,14 +2488,57 @@
23402488
23412489 if (qedi->boot_kset)
23422490 iscsi_boot_destroy_kset(qedi->boot_kset);
2491
+
2492
+ iscsi_host_remove(qedi->shost);
2493
+ iscsi_host_free(qedi->shost);
23432494 }
2495
+}
2496
+
2497
+static void qedi_board_disable_work(struct work_struct *work)
2498
+{
2499
+ struct qedi_ctx *qedi =
2500
+ container_of(work, struct qedi_ctx,
2501
+ board_disable_work.work);
2502
+
2503
+ QEDI_INFO(&qedi->dbg_ctx, QEDI_LOG_INFO,
2504
+ "Fan failure, Unloading firmware context.\n");
2505
+
2506
+ if (test_and_set_bit(QEDI_IN_SHUTDOWN, &qedi->flags))
2507
+ return;
2508
+
2509
+ __qedi_remove(qedi->pdev, QEDI_MODE_SHUTDOWN);
2510
+}
2511
+
2512
+static void qedi_shutdown(struct pci_dev *pdev)
2513
+{
2514
+ struct qedi_ctx *qedi = pci_get_drvdata(pdev);
2515
+
2516
+ QEDI_ERR(&qedi->dbg_ctx, "%s: Shutdown qedi\n", __func__);
2517
+ if (test_and_set_bit(QEDI_IN_SHUTDOWN, &qedi->flags))
2518
+ return;
2519
+ __qedi_remove(pdev, QEDI_MODE_SHUTDOWN);
2520
+}
2521
+
2522
+static int qedi_suspend(struct pci_dev *pdev, pm_message_t state)
2523
+{
2524
+ struct qedi_ctx *qedi;
2525
+
2526
+ if (!pdev) {
2527
+ QEDI_ERR(NULL, "pdev is NULL.\n");
2528
+ return -ENODEV;
2529
+ }
2530
+
2531
+ qedi = pci_get_drvdata(pdev);
2532
+
2533
+ QEDI_ERR(&qedi->dbg_ctx, "%s: Device does not support suspend operation\n", __func__);
2534
+
2535
+ return -EPERM;
23442536 }
23452537
23462538 static int __qedi_probe(struct pci_dev *pdev, int mode)
23472539 {
23482540 struct qedi_ctx *qedi;
23492541 struct qed_ll2_params params;
2350
- u32 dp_module = 0;
23512542 u8 dp_level = 0;
23522543 bool is_vf = false;
23532544 char host_buf[16];
....@@ -2356,7 +2547,7 @@
23562547 struct qed_probe_params qed_params;
23572548 void *task_start, *task_end;
23582549 int rc;
2359
- u16 tmp;
2550
+ u16 retry = 10;
23602551
23612552 if (mode != QEDI_MODE_RECOVERY) {
23622553 qedi = qedi_host_alloc(pdev);
....@@ -2368,32 +2559,48 @@
23682559 qedi = pci_get_drvdata(pdev);
23692560 }
23702561
2562
+retry_probe:
2563
+ if (mode == QEDI_MODE_RECOVERY)
2564
+ msleep(2000);
2565
+
23712566 memset(&qed_params, 0, sizeof(qed_params));
23722567 qed_params.protocol = QED_PROTOCOL_ISCSI;
2373
- qed_params.dp_module = dp_module;
2568
+ qed_params.dp_module = qedi_qed_debug;
23742569 qed_params.dp_level = dp_level;
23752570 qed_params.is_vf = is_vf;
23762571 qedi->cdev = qedi_ops->common->probe(pdev, &qed_params);
23772572 if (!qedi->cdev) {
2573
+ if (mode == QEDI_MODE_RECOVERY && retry) {
2574
+ QEDI_INFO(&qedi->dbg_ctx, QEDI_LOG_INFO,
2575
+ "Retry %d initialize hardware\n", retry);
2576
+ retry--;
2577
+ goto retry_probe;
2578
+ }
2579
+
23782580 rc = -ENODEV;
23792581 QEDI_ERR(&qedi->dbg_ctx, "Cannot initialize hardware\n");
23802582 goto free_host;
23812583 }
23822584
2585
+ set_bit(QEDI_ERR_ATTN_CLR_EN, &qedi->qedi_err_flags);
2586
+ set_bit(QEDI_ERR_IS_RECOVERABLE, &qedi->qedi_err_flags);
23832587 atomic_set(&qedi->link_state, QEDI_LINK_DOWN);
23842588
23852589 rc = qedi_ops->fill_dev_info(qedi->cdev, &qedi->dev_info);
23862590 if (rc)
23872591 goto free_host;
23882592
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
- }
2593
+ QEDI_INFO(&qedi->dbg_ctx, QEDI_LOG_INFO,
2594
+ "dev_info: num_hwfns=%d affin_hwfn_idx=%d.\n",
2595
+ qedi->dev_info.common.num_hwfns,
2596
+ qedi_ops->common->get_affin_hwfn_idx(qedi->cdev));
2597
+
2598
+ rc = qedi_set_iscsi_pf_param(qedi);
2599
+ if (rc) {
2600
+ rc = -ENOMEM;
2601
+ QEDI_ERR(&qedi->dbg_ctx,
2602
+ "Set iSCSI pf param fail\n");
2603
+ goto free_host;
23972604 }
23982605
23992606 qedi_ops->common->update_pf_params(qedi->cdev, &qedi->pf_params);
....@@ -2452,15 +2659,15 @@
24522659 "Writing %d to primary and secondary BDQ doorbell registers.\n",
24532660 qedi->bdq_prod_idx);
24542661 writew(qedi->bdq_prod_idx, qedi->bdq_primary_prod);
2455
- tmp = readw(qedi->bdq_primary_prod);
2662
+ readw(qedi->bdq_primary_prod);
24562663 writew(qedi->bdq_prod_idx, qedi->bdq_secondary_prod);
2457
- tmp = readw(qedi->bdq_secondary_prod);
2664
+ readw(qedi->bdq_secondary_prod);
24582665
24592666 ether_addr_copy(qedi->mac, qedi->dev_info.common.hw_mac);
24602667 QEDI_INFO(&qedi->dbg_ctx, QEDI_LOG_DISC, "MAC address is %pM.\n",
24612668 qedi->mac);
24622669
2463
- sprintf(host_buf, "host_%d", qedi->shost->host_no);
2670
+ snprintf(host_buf, sizeof(host_buf), "host_%d", qedi->shost->host_no);
24642671 qedi_ops->common->set_name(qedi->cdev, host_buf);
24652672
24662673 qedi_ops->register_ops(qedi->cdev, &qedi_cb_ops, qedi);
....@@ -2584,6 +2791,10 @@
25842791 goto free_tmf_thread;
25852792 }
25862793
2794
+ INIT_DELAYED_WORK(&qedi->recovery_work, qedi_recovery_handler);
2795
+ INIT_DELAYED_WORK(&qedi->board_disable_work,
2796
+ qedi_board_disable_work);
2797
+
25872798 /* F/w needs 1st task context memory entry for performance */
25882799 set_bit(QEDI_RESERVE_TASK_ID, qedi->task_idx_map);
25892800 atomic_set(&qedi->num_offloads, 0);
....@@ -2626,6 +2837,32 @@
26262837 return rc;
26272838 }
26282839
2840
+static void qedi_mark_conn_recovery(struct iscsi_cls_session *cls_session)
2841
+{
2842
+ struct iscsi_session *session = cls_session->dd_data;
2843
+ struct iscsi_conn *conn = session->leadconn;
2844
+ struct qedi_conn *qedi_conn = conn->dd_data;
2845
+
2846
+ iscsi_conn_failure(qedi_conn->cls_conn->dd_data, ISCSI_ERR_CONN_FAILED);
2847
+}
2848
+
2849
+static void qedi_recovery_handler(struct work_struct *work)
2850
+{
2851
+ struct qedi_ctx *qedi =
2852
+ container_of(work, struct qedi_ctx, recovery_work.work);
2853
+
2854
+ iscsi_host_for_each_session(qedi->shost, qedi_mark_conn_recovery);
2855
+
2856
+ /* Call common_ops->recovery_prolog to allow the MFW to quiesce
2857
+ * any PCI transactions.
2858
+ */
2859
+ qedi_ops->common->recovery_prolog(qedi->cdev);
2860
+
2861
+ __qedi_remove(qedi->pdev, QEDI_MODE_RECOVERY);
2862
+ __qedi_probe(qedi->pdev, QEDI_MODE_RECOVERY);
2863
+ clear_bit(QEDI_IN_RECOVERY, &qedi->flags);
2864
+}
2865
+
26292866 static int qedi_probe(struct pci_dev *pdev, const struct pci_device_id *id)
26302867 {
26312868 return __qedi_probe(pdev, QEDI_MODE_NORMAL);
....@@ -2645,11 +2882,18 @@
26452882
26462883 static enum cpuhp_state qedi_cpuhp_state;
26472884
2885
+static struct pci_error_handlers qedi_err_handler = {
2886
+ .error_detected = qedi_io_error_detected,
2887
+};
2888
+
26482889 static struct pci_driver qedi_pci_driver = {
26492890 .name = QEDI_MODULE_NAME,
26502891 .id_table = qedi_pci_tbl,
26512892 .probe = qedi_probe,
26522893 .remove = qedi_remove,
2894
+ .shutdown = qedi_shutdown,
2895
+ .err_handler = &qedi_err_handler,
2896
+ .suspend = qedi_suspend,
26532897 };
26542898
26552899 static int __init qedi_init(void)