Skip to content

Commit e6acd2b

Browse files
committed
Merge branch 'qed-aer'
Sudarsana Reddy Kalluru says: ==================== qed*: Add support for pcie advanced error recovery. The patch series adds qed/qede driver changes for PCIe Advanced Error Recovery (AER) support. Patch (1) adds qed changes to enable the device to send error messages to root port when detected. Patch (2) adds qede support for handling the detected errors (AERs). Changes from previous version: ------------------------------- v2: use pci_num_vf() instead of caching the value in edev. ==================== Signed-off-by: David S. Miller <davem@davemloft.net>
2 parents e131a56 + 731815e commit e6acd2b

File tree

3 files changed

+77
-1
lines changed

3 files changed

+77
-1
lines changed

drivers/net/ethernet/qlogic/qed/qed_main.c

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,7 @@
4949
#include <linux/qed/qed_if.h>
5050
#include <linux/qed/qed_ll2_if.h>
5151
#include <net/devlink.h>
52+
#include <linux/aer.h>
5253

5354
#include "qed.h"
5455
#include "qed_sriov.h"
@@ -129,6 +130,8 @@ static void qed_free_pci(struct qed_dev *cdev)
129130
{
130131
struct pci_dev *pdev = cdev->pdev;
131132

133+
pci_disable_pcie_error_reporting(pdev);
134+
132135
if (cdev->doorbells && cdev->db_size)
133136
iounmap(cdev->doorbells);
134137
if (cdev->regview)
@@ -231,6 +234,12 @@ static int qed_init_pci(struct qed_dev *cdev, struct pci_dev *pdev)
231234
return -ENOMEM;
232235
}
233236

237+
/* AER (Advanced Error reporting) configuration */
238+
rc = pci_enable_pcie_error_reporting(pdev);
239+
if (rc)
240+
DP_VERBOSE(cdev, NETIF_MSG_DRV,
241+
"Failed to configure PCIe AER [%d]\n", rc);
242+
234243
return 0;
235244

236245
err2:

drivers/net/ethernet/qlogic/qede/qede.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -485,6 +485,7 @@ struct qede_fastpath {
485485

486486
#define QEDE_SP_RECOVERY 0
487487
#define QEDE_SP_RX_MODE 1
488+
#define QEDE_SP_AER 7
488489

489490
#ifdef CONFIG_RFS_ACCEL
490491
int qede_rx_flow_steer(struct net_device *dev, const struct sk_buff *skb,

drivers/net/ethernet/qlogic/qede/qede_main.c

Lines changed: 67 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,7 @@
6060
#include <net/ip6_checksum.h>
6161
#include <linux/bitops.h>
6262
#include <linux/vmalloc.h>
63+
#include <linux/aer.h>
6364
#include "qede.h"
6465
#include "qede_ptp.h"
6566

@@ -124,6 +125,8 @@ static const struct pci_device_id qede_pci_tbl[] = {
124125
MODULE_DEVICE_TABLE(pci, qede_pci_tbl);
125126

126127
static int qede_probe(struct pci_dev *pdev, const struct pci_device_id *id);
128+
static pci_ers_result_t
129+
qede_io_error_detected(struct pci_dev *pdev, pci_channel_state_t state);
127130

128131
#define TX_TIMEOUT (5 * HZ)
129132

@@ -203,6 +206,10 @@ static int qede_sriov_configure(struct pci_dev *pdev, int num_vfs_param)
203206
}
204207
#endif
205208

209+
static const struct pci_error_handlers qede_err_handler = {
210+
.error_detected = qede_io_error_detected,
211+
};
212+
206213
static struct pci_driver qede_pci_driver = {
207214
.name = "qede",
208215
.id_table = qede_pci_tbl,
@@ -212,6 +219,7 @@ static struct pci_driver qede_pci_driver = {
212219
#ifdef CONFIG_QED_SRIOV
213220
.sriov_configure = qede_sriov_configure,
214221
#endif
222+
.err_handler = &qede_err_handler,
215223
};
216224

217225
static struct qed_eth_cb_ops qede_ll_ops = {
@@ -974,7 +982,8 @@ static void qede_sp_task(struct work_struct *work)
974982
/* SRIOV must be disabled outside the lock to avoid a deadlock.
975983
* The recovery of the active VFs is currently not supported.
976984
*/
977-
qede_sriov_configure(edev->pdev, 0);
985+
if (pci_num_vf(edev->pdev))
986+
qede_sriov_configure(edev->pdev, 0);
978987
#endif
979988
qede_lock(edev);
980989
qede_recovery_handler(edev);
@@ -994,6 +1003,17 @@ static void qede_sp_task(struct work_struct *work)
9941003
}
9951004
#endif
9961005
__qede_unlock(edev);
1006+
1007+
if (test_and_clear_bit(QEDE_SP_AER, &edev->sp_flags)) {
1008+
#ifdef CONFIG_QED_SRIOV
1009+
/* SRIOV must be disabled outside the lock to avoid a deadlock.
1010+
* The recovery of the active VFs is currently not supported.
1011+
*/
1012+
if (pci_num_vf(edev->pdev))
1013+
qede_sriov_configure(edev->pdev, 0);
1014+
#endif
1015+
edev->ops->common->recovery_process(edev->cdev);
1016+
}
9971017
}
9981018

9991019
static void qede_update_pf_params(struct qed_dev *cdev)
@@ -2579,3 +2599,49 @@ static void qede_get_eth_tlv_data(void *dev, void *data)
25792599
etlv->num_txqs_full_set = true;
25802600
etlv->num_rxqs_full_set = true;
25812601
}
2602+
2603+
/**
2604+
* qede_io_error_detected - called when PCI error is detected
2605+
* @pdev: Pointer to PCI device
2606+
* @state: The current pci connection state
2607+
*
2608+
* This function is called after a PCI bus error affecting
2609+
* this device has been detected.
2610+
*/
2611+
static pci_ers_result_t
2612+
qede_io_error_detected(struct pci_dev *pdev, pci_channel_state_t state)
2613+
{
2614+
struct net_device *dev = pci_get_drvdata(pdev);
2615+
struct qede_dev *edev = netdev_priv(dev);
2616+
2617+
if (!edev)
2618+
return PCI_ERS_RESULT_NONE;
2619+
2620+
DP_NOTICE(edev, "IO error detected [%d]\n", state);
2621+
2622+
__qede_lock(edev);
2623+
if (edev->state == QEDE_STATE_RECOVERY) {
2624+
DP_NOTICE(edev, "Device already in the recovery state\n");
2625+
__qede_unlock(edev);
2626+
return PCI_ERS_RESULT_NONE;
2627+
}
2628+
2629+
/* PF handles the recovery of its VFs */
2630+
if (IS_VF(edev)) {
2631+
DP_VERBOSE(edev, QED_MSG_IOV,
2632+
"VF recovery is handled by its PF\n");
2633+
__qede_unlock(edev);
2634+
return PCI_ERS_RESULT_RECOVERED;
2635+
}
2636+
2637+
/* Close OS Tx */
2638+
netif_tx_disable(edev->ndev);
2639+
netif_carrier_off(edev->ndev);
2640+
2641+
set_bit(QEDE_SP_AER, &edev->sp_flags);
2642+
schedule_delayed_work(&edev->sp_task, 0);
2643+
2644+
__qede_unlock(edev);
2645+
2646+
return PCI_ERS_RESULT_CAN_RECOVER;
2647+
}

0 commit comments

Comments
 (0)