2525#include <linux/poll.h>
2626#include <linux/wait.h>
2727#include <linux/io-64-nonatomic-lo-hi.h>
28+ #include <linux/aer.h>
2829
2930#include "version.h"
3031MODULE_DESCRIPTION ("Microsemi Switchtec(tm) PCIe Management Driver" );
@@ -705,6 +706,26 @@ static int flash_part_info_gen4(struct switchtec_dev *stdev,
705706 struct active_partition_info_gen4 __iomem * af = & fi -> active_flag ;
706707
707708 switch (info -> flash_partition ) {
709+ case SWITCHTEC_IOCTL_PART_MAP_0 :
710+ set_fw_info_part (info , & fi -> map0 );
711+ break ;
712+ case SWITCHTEC_IOCTL_PART_MAP_1 :
713+ set_fw_info_part (info , & fi -> map1 );
714+ break ;
715+ case SWITCHTEC_IOCTL_PART_KEY_0 :
716+ set_fw_info_part (info , & fi -> key0 );
717+ if (ioread8 (& af -> key ) == SWITCHTEC_GEN4_KEY0_ACTIVE )
718+ info -> active |= SWITCHTEC_IOCTL_PART_ACTIVE ;
719+ if (ioread16 (& si -> key_running ) == SWITCHTEC_GEN4_KEY0_RUNNING )
720+ info -> active |= SWITCHTEC_IOCTL_PART_RUNNING ;
721+ break ;
722+ case SWITCHTEC_IOCTL_PART_KEY_1 :
723+ set_fw_info_part (info , & fi -> key1 );
724+ if (ioread8 (& af -> key ) == SWITCHTEC_GEN4_KEY1_ACTIVE )
725+ info -> active |= SWITCHTEC_IOCTL_PART_ACTIVE ;
726+ if (ioread16 (& si -> key_running ) == SWITCHTEC_GEN4_KEY1_RUNNING )
727+ info -> active |= SWITCHTEC_IOCTL_PART_RUNNING ;
728+ break ;
708729 case SWITCHTEC_IOCTL_PART_BL2_0 :
709730 set_fw_info_part (info , & fi -> bl2_0 );
710731 if (ioread8 (& af -> bl2 ) == SWITCHTEC_GEN4_BL2_0_ACTIVE )
@@ -947,6 +968,9 @@ static int event_ctl(struct switchtec_dev *stdev,
947968 return PTR_ERR (reg );
948969
949970 hdr = ioread32 (reg );
971+ if (hdr & SWITCHTEC_EVENT_NOT_SUPP )
972+ return - ENOTSUPP ;
973+
950974 for (i = 0 ; i < ARRAY_SIZE (ctl -> data ); i ++ )
951975 ctl -> data [i ] = ioread32 (& reg [i + 1 ]);
952976
@@ -1019,7 +1043,7 @@ static int ioctl_event_ctl(struct switchtec_dev *stdev,
10191043 for (ctl .index = 0 ; ctl .index < nr_idxs ; ctl .index ++ ) {
10201044 ctl .flags = event_flags ;
10211045 ret = event_ctl (stdev , & ctl );
1022- if (ret < 0 )
1046+ if (ret < 0 && ret != - ENOTSUPP )
10231047 return ret ;
10241048 }
10251049 } else {
@@ -1324,6 +1348,9 @@ static int mask_event(struct switchtec_dev *stdev, int eid, int idx)
13241348 hdr_reg = event_regs [eid ].map_reg (stdev , off , idx );
13251349 hdr = ioread32 (hdr_reg );
13261350
1351+ if (hdr & SWITCHTEC_EVENT_NOT_SUPP )
1352+ return 0 ;
1353+
13271354 if (!(hdr & SWITCHTEC_EVENT_OCCURRED && hdr & SWITCHTEC_EVENT_EN_IRQ ))
13281355 return 0 ;
13291356
@@ -1662,6 +1689,8 @@ static int switchtec_pci_probe(struct pci_dev *pdev,
16621689 goto err_devadd ;
16631690
16641691 dev_info (& stdev -> dev , "Management device registered.\n" );
1692+ pci_enable_pcie_error_reporting (pdev );
1693+ pci_save_state (pdev );
16651694
16661695 return 0 ;
16671696
@@ -1688,6 +1717,111 @@ static void switchtec_pci_remove(struct pci_dev *pdev)
16881717 put_device (& stdev -> dev );
16891718}
16901719
1720+ static void switchtec_pci_disable (struct pci_dev * pdev )
1721+ {
1722+ struct switchtec_dev * stdev = pci_get_drvdata (pdev );
1723+
1724+ if (pci_is_enabled (pdev )) {
1725+ pci_disable_pcie_error_reporting (pdev );
1726+ pci_disable_device (pdev );
1727+ }
1728+
1729+ stdev_kill (stdev );
1730+ }
1731+
1732+ static pci_ers_result_t switchtec_pci_error_detected (struct pci_dev * pdev ,
1733+ pci_channel_state_t state )
1734+ {
1735+ struct switchtec_dev * stdev = pci_get_drvdata (pdev );
1736+
1737+ /*
1738+ * A frozen channel requires a reset. When detected, this method
1739+ * will disable the device. The device will be restarted
1740+ * after the slot reset through driver's slot_reset callback.
1741+ */
1742+ switch (state ) {
1743+ case pci_channel_io_normal :
1744+ return PCI_ERS_RESULT_CAN_RECOVER ;
1745+ case pci_channel_io_frozen :
1746+ switchtec_pci_disable (pdev );
1747+ dev_info (& stdev -> dev , "frozen state error detected - reset needed\n" );
1748+ return PCI_ERS_RESULT_NEED_RESET ;
1749+ case pci_channel_io_perm_failure :
1750+ switchtec_pci_disable (pdev );
1751+ dev_info (& stdev -> dev , "failure state error detected - request disconnect\n" );
1752+ return PCI_ERS_RESULT_DISCONNECT ;
1753+ }
1754+ return PCI_ERS_RESULT_NEED_RESET ;
1755+ }
1756+
1757+ static pci_ers_result_t switchtec_pci_slot_reset (struct pci_dev * pdev )
1758+ {
1759+ struct switchtec_dev * stdev = pci_get_drvdata (pdev );
1760+ int rc ;
1761+ unsigned long res_start , res_len ;
1762+
1763+ dev_info (& stdev -> dev , "slot_reset.\n" );
1764+
1765+ pci_restore_state (pdev );
1766+
1767+ /*
1768+ * First, release PCI resources and memory regions
1769+ */
1770+ if (stdev -> dma_mrpc ){
1771+ iowrite32 (0 , & stdev -> mmio_mrpc -> dma_en );
1772+ flush_wc_buf (stdev );
1773+ writeq (0 , & stdev -> mmio_mrpc -> dma_addr );
1774+ dma_free_coherent (& stdev -> pdev -> dev , sizeof (* stdev -> dma_mrpc ),
1775+ stdev -> dma_mrpc , stdev -> dma_mrpc_dma_addr );
1776+ }
1777+
1778+ res_start = pci_resource_start (pdev , 0 );
1779+ res_len = pci_resource_len (pdev , 0 );
1780+
1781+ devm_release_mem_region (& pdev -> dev , res_start , res_len );
1782+
1783+ /*
1784+ * Second, reinitialize PCI resources, remap memory regions and reenable events.
1785+ */
1786+ rc = switchtec_init_pci (stdev , pdev );
1787+ if (rc ) {
1788+ dev_err (& stdev -> dev , "failed to reinitialize pci.\n" );
1789+ goto err_ret ;
1790+ }
1791+
1792+ iowrite32 (SWITCHTEC_EVENT_CLEAR |
1793+ SWITCHTEC_EVENT_EN_IRQ ,
1794+ & stdev -> mmio_part_cfg -> mrpc_comp_hdr );
1795+ enable_link_state_events (stdev );
1796+
1797+ if (stdev -> dma_mrpc )
1798+ enable_dma_mrpc (stdev );
1799+
1800+ stdev -> alive = true;
1801+ stdev -> mrpc_busy = 0 ;
1802+
1803+ pci_enable_pcie_error_reporting (pdev );
1804+ pci_save_state (pdev );
1805+
1806+ return PCI_ERS_RESULT_RECOVERED ;
1807+ err_ret :
1808+ return PCI_ERS_RESULT_DISCONNECT ;
1809+ }
1810+
1811+ static void switchtec_pci_error_resume (struct pci_dev * pdev )
1812+ {
1813+ struct switchtec_dev * stdev = pci_get_drvdata (pdev );
1814+
1815+ dev_info (& stdev -> dev , "resume.\n" );
1816+ pci_cleanup_aer_uncorrect_error_status (pdev );
1817+ }
1818+
1819+ static const struct pci_error_handlers switchtec_pci_err_handler = {
1820+ .error_detected = switchtec_pci_error_detected ,
1821+ .slot_reset = switchtec_pci_slot_reset ,
1822+ .resume = switchtec_pci_error_resume ,
1823+ };
1824+
16911825#define SWITCHTEC_PCI_DEVICE (device_id , gen ) \
16921826 { \
16931827 .vendor = MICROSEMI_VENDOR_ID, \
@@ -1766,6 +1900,7 @@ static struct pci_driver switchtec_pci_driver = {
17661900 .id_table = switchtec_pci_tbl ,
17671901 .probe = switchtec_pci_probe ,
17681902 .remove = switchtec_pci_remove ,
1903+ .err_handler = & switchtec_pci_err_handler ,
17691904};
17701905
17711906static int __init switchtec_init (void )
0 commit comments