112eb4683SFrank Haverkamp /** 212eb4683SFrank Haverkamp * IBM Accelerator Family 'GenWQE' 312eb4683SFrank Haverkamp * 412eb4683SFrank Haverkamp * (C) Copyright IBM Corp. 2013 512eb4683SFrank Haverkamp * 612eb4683SFrank Haverkamp * Author: Frank Haverkamp <haver@linux.vnet.ibm.com> 712eb4683SFrank Haverkamp * Author: Joerg-Stephan Vogt <jsvogt@de.ibm.com> 826d8f6f1SFrank Haverkamp * Author: Michael Jung <mijung@gmx.net> 912eb4683SFrank Haverkamp * Author: Michael Ruettger <michael@ibmra.de> 1012eb4683SFrank Haverkamp * 1112eb4683SFrank Haverkamp * This program is free software; you can redistribute it and/or modify 1212eb4683SFrank Haverkamp * it under the terms of the GNU General Public License (version 2 only) 1312eb4683SFrank Haverkamp * as published by the Free Software Foundation. 1412eb4683SFrank Haverkamp * 1512eb4683SFrank Haverkamp * This program is distributed in the hope that it will be useful, 1612eb4683SFrank Haverkamp * but WITHOUT ANY WARRANTY; without even the implied warranty of 1712eb4683SFrank Haverkamp * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 1812eb4683SFrank Haverkamp * GNU General Public License for more details. 1912eb4683SFrank Haverkamp */ 2012eb4683SFrank Haverkamp 2112eb4683SFrank Haverkamp /* 2212eb4683SFrank Haverkamp * Module initialization and PCIe setup. Card health monitoring and 2312eb4683SFrank Haverkamp * recovery functionality. Character device creation and deletion are 2412eb4683SFrank Haverkamp * controlled from here. 2512eb4683SFrank Haverkamp */ 2612eb4683SFrank Haverkamp 2712eb4683SFrank Haverkamp #include <linux/module.h> 2812eb4683SFrank Haverkamp #include <linux/types.h> 2912eb4683SFrank Haverkamp #include <linux/pci.h> 3012eb4683SFrank Haverkamp #include <linux/err.h> 3112eb4683SFrank Haverkamp #include <linux/aer.h> 3212eb4683SFrank Haverkamp #include <linux/string.h> 3312eb4683SFrank Haverkamp #include <linux/sched.h> 3412eb4683SFrank Haverkamp #include <linux/wait.h> 3512eb4683SFrank Haverkamp #include <linux/delay.h> 3612eb4683SFrank Haverkamp #include <linux/dma-mapping.h> 3712eb4683SFrank Haverkamp #include <linux/module.h> 3812eb4683SFrank Haverkamp #include <linux/notifier.h> 3912eb4683SFrank Haverkamp #include <linux/device.h> 4012eb4683SFrank Haverkamp #include <linux/log2.h> 4112eb4683SFrank Haverkamp 4212eb4683SFrank Haverkamp #include "card_base.h" 4312eb4683SFrank Haverkamp #include "card_ddcb.h" 4412eb4683SFrank Haverkamp 4512eb4683SFrank Haverkamp MODULE_AUTHOR("Frank Haverkamp <haver@linux.vnet.ibm.com>"); 4612eb4683SFrank Haverkamp MODULE_AUTHOR("Michael Ruettger <michael@ibmra.de>"); 4712eb4683SFrank Haverkamp MODULE_AUTHOR("Joerg-Stephan Vogt <jsvogt@de.ibm.com>"); 4826d8f6f1SFrank Haverkamp MODULE_AUTHOR("Michael Jung <mijung@gmx.net>"); 4912eb4683SFrank Haverkamp 5012eb4683SFrank Haverkamp MODULE_DESCRIPTION("GenWQE Card"); 5164df2ec5SFrank Haverkamp MODULE_VERSION(DRV_VERSION); 5212eb4683SFrank Haverkamp MODULE_LICENSE("GPL"); 5312eb4683SFrank Haverkamp 5412eb4683SFrank Haverkamp static char genwqe_driver_name[] = GENWQE_DEVNAME; 5512eb4683SFrank Haverkamp static struct class *class_genwqe; 5612eb4683SFrank Haverkamp static struct dentry *debugfs_genwqe; 5712eb4683SFrank Haverkamp static struct genwqe_dev *genwqe_devices[GENWQE_CARD_NO_MAX]; 5812eb4683SFrank Haverkamp 5912eb4683SFrank Haverkamp /* PCI structure for identifying device by PCI vendor and device ID */ 6032182cd3SGreg Kroah-Hartman static const struct pci_device_id genwqe_device_table[] = { 6112eb4683SFrank Haverkamp { .vendor = PCI_VENDOR_ID_IBM, 6212eb4683SFrank Haverkamp .device = PCI_DEVICE_GENWQE, 6312eb4683SFrank Haverkamp .subvendor = PCI_SUBVENDOR_ID_IBM, 6412eb4683SFrank Haverkamp .subdevice = PCI_SUBSYSTEM_ID_GENWQE5, 6512eb4683SFrank Haverkamp .class = (PCI_CLASSCODE_GENWQE5 << 8), 6612eb4683SFrank Haverkamp .class_mask = ~0, 6712eb4683SFrank Haverkamp .driver_data = 0 }, 6812eb4683SFrank Haverkamp 6912eb4683SFrank Haverkamp /* Initial SR-IOV bring-up image */ 7012eb4683SFrank Haverkamp { .vendor = PCI_VENDOR_ID_IBM, 7112eb4683SFrank Haverkamp .device = PCI_DEVICE_GENWQE, 7212eb4683SFrank Haverkamp .subvendor = PCI_SUBVENDOR_ID_IBM_SRIOV, 7312eb4683SFrank Haverkamp .subdevice = PCI_SUBSYSTEM_ID_GENWQE5_SRIOV, 7412eb4683SFrank Haverkamp .class = (PCI_CLASSCODE_GENWQE5_SRIOV << 8), 7512eb4683SFrank Haverkamp .class_mask = ~0, 7612eb4683SFrank Haverkamp .driver_data = 0 }, 7712eb4683SFrank Haverkamp 7812eb4683SFrank Haverkamp { .vendor = PCI_VENDOR_ID_IBM, /* VF Vendor ID */ 7912eb4683SFrank Haverkamp .device = 0x0000, /* VF Device ID */ 8012eb4683SFrank Haverkamp .subvendor = PCI_SUBVENDOR_ID_IBM_SRIOV, 8112eb4683SFrank Haverkamp .subdevice = PCI_SUBSYSTEM_ID_GENWQE5_SRIOV, 8212eb4683SFrank Haverkamp .class = (PCI_CLASSCODE_GENWQE5_SRIOV << 8), 8312eb4683SFrank Haverkamp .class_mask = ~0, 8412eb4683SFrank Haverkamp .driver_data = 0 }, 8512eb4683SFrank Haverkamp 8612eb4683SFrank Haverkamp /* Fixed up image */ 8712eb4683SFrank Haverkamp { .vendor = PCI_VENDOR_ID_IBM, 8812eb4683SFrank Haverkamp .device = PCI_DEVICE_GENWQE, 8912eb4683SFrank Haverkamp .subvendor = PCI_SUBVENDOR_ID_IBM_SRIOV, 9012eb4683SFrank Haverkamp .subdevice = PCI_SUBSYSTEM_ID_GENWQE5, 9112eb4683SFrank Haverkamp .class = (PCI_CLASSCODE_GENWQE5_SRIOV << 8), 9212eb4683SFrank Haverkamp .class_mask = ~0, 9312eb4683SFrank Haverkamp .driver_data = 0 }, 9412eb4683SFrank Haverkamp 9512eb4683SFrank Haverkamp { .vendor = PCI_VENDOR_ID_IBM, /* VF Vendor ID */ 9612eb4683SFrank Haverkamp .device = 0x0000, /* VF Device ID */ 9712eb4683SFrank Haverkamp .subvendor = PCI_SUBVENDOR_ID_IBM_SRIOV, 9812eb4683SFrank Haverkamp .subdevice = PCI_SUBSYSTEM_ID_GENWQE5, 9912eb4683SFrank Haverkamp .class = (PCI_CLASSCODE_GENWQE5_SRIOV << 8), 10012eb4683SFrank Haverkamp .class_mask = ~0, 10112eb4683SFrank Haverkamp .driver_data = 0 }, 10212eb4683SFrank Haverkamp 10312eb4683SFrank Haverkamp /* Even one more ... */ 10412eb4683SFrank Haverkamp { .vendor = PCI_VENDOR_ID_IBM, 10512eb4683SFrank Haverkamp .device = PCI_DEVICE_GENWQE, 10612eb4683SFrank Haverkamp .subvendor = PCI_SUBVENDOR_ID_IBM, 10712eb4683SFrank Haverkamp .subdevice = PCI_SUBSYSTEM_ID_GENWQE5_NEW, 10812eb4683SFrank Haverkamp .class = (PCI_CLASSCODE_GENWQE5 << 8), 10912eb4683SFrank Haverkamp .class_mask = ~0, 11012eb4683SFrank Haverkamp .driver_data = 0 }, 11112eb4683SFrank Haverkamp 11212eb4683SFrank Haverkamp { 0, } /* 0 terminated list. */ 11312eb4683SFrank Haverkamp }; 11412eb4683SFrank Haverkamp 11512eb4683SFrank Haverkamp MODULE_DEVICE_TABLE(pci, genwqe_device_table); 11612eb4683SFrank Haverkamp 11712eb4683SFrank Haverkamp /** 11812eb4683SFrank Haverkamp * genwqe_dev_alloc() - Create and prepare a new card descriptor 11912eb4683SFrank Haverkamp * 12012eb4683SFrank Haverkamp * Return: Pointer to card descriptor, or ERR_PTR(err) on error 12112eb4683SFrank Haverkamp */ 12212eb4683SFrank Haverkamp static struct genwqe_dev *genwqe_dev_alloc(void) 12312eb4683SFrank Haverkamp { 12412eb4683SFrank Haverkamp unsigned int i = 0, j; 12512eb4683SFrank Haverkamp struct genwqe_dev *cd; 12612eb4683SFrank Haverkamp 12712eb4683SFrank Haverkamp for (i = 0; i < GENWQE_CARD_NO_MAX; i++) { 12812eb4683SFrank Haverkamp if (genwqe_devices[i] == NULL) 12912eb4683SFrank Haverkamp break; 13012eb4683SFrank Haverkamp } 13112eb4683SFrank Haverkamp if (i >= GENWQE_CARD_NO_MAX) 13212eb4683SFrank Haverkamp return ERR_PTR(-ENODEV); 13312eb4683SFrank Haverkamp 13412eb4683SFrank Haverkamp cd = kzalloc(sizeof(struct genwqe_dev), GFP_KERNEL); 13512eb4683SFrank Haverkamp if (!cd) 13612eb4683SFrank Haverkamp return ERR_PTR(-ENOMEM); 13712eb4683SFrank Haverkamp 13812eb4683SFrank Haverkamp cd->card_idx = i; 13912eb4683SFrank Haverkamp cd->class_genwqe = class_genwqe; 14012eb4683SFrank Haverkamp cd->debugfs_genwqe = debugfs_genwqe; 14112eb4683SFrank Haverkamp 142fb145456SKleber Sacilotto de Souza /* 143fb145456SKleber Sacilotto de Souza * This comes from kernel config option and can be overritten via 144fb145456SKleber Sacilotto de Souza * debugfs. 145fb145456SKleber Sacilotto de Souza */ 146fb145456SKleber Sacilotto de Souza cd->use_platform_recovery = CONFIG_GENWQE_PLATFORM_ERROR_RECOVERY; 147fb145456SKleber Sacilotto de Souza 14812eb4683SFrank Haverkamp init_waitqueue_head(&cd->queue_waitq); 14912eb4683SFrank Haverkamp 15012eb4683SFrank Haverkamp spin_lock_init(&cd->file_lock); 15112eb4683SFrank Haverkamp INIT_LIST_HEAD(&cd->file_list); 15212eb4683SFrank Haverkamp 15312eb4683SFrank Haverkamp cd->card_state = GENWQE_CARD_UNUSED; 15412eb4683SFrank Haverkamp spin_lock_init(&cd->print_lock); 15512eb4683SFrank Haverkamp 15612eb4683SFrank Haverkamp cd->ddcb_software_timeout = genwqe_ddcb_software_timeout; 15712eb4683SFrank Haverkamp cd->kill_timeout = genwqe_kill_timeout; 15812eb4683SFrank Haverkamp 15912eb4683SFrank Haverkamp for (j = 0; j < GENWQE_MAX_VFS; j++) 16012eb4683SFrank Haverkamp cd->vf_jobtimeout_msec[j] = genwqe_vf_jobtimeout_msec; 16112eb4683SFrank Haverkamp 16212eb4683SFrank Haverkamp genwqe_devices[i] = cd; 16312eb4683SFrank Haverkamp return cd; 16412eb4683SFrank Haverkamp } 16512eb4683SFrank Haverkamp 16612eb4683SFrank Haverkamp static void genwqe_dev_free(struct genwqe_dev *cd) 16712eb4683SFrank Haverkamp { 16812eb4683SFrank Haverkamp if (!cd) 16912eb4683SFrank Haverkamp return; 17012eb4683SFrank Haverkamp 17112eb4683SFrank Haverkamp genwqe_devices[cd->card_idx] = NULL; 17212eb4683SFrank Haverkamp kfree(cd); 17312eb4683SFrank Haverkamp } 17412eb4683SFrank Haverkamp 17512eb4683SFrank Haverkamp /** 17612eb4683SFrank Haverkamp * genwqe_bus_reset() - Card recovery 17712eb4683SFrank Haverkamp * 17812eb4683SFrank Haverkamp * pci_reset_function() will recover the device and ensure that the 17912eb4683SFrank Haverkamp * registers are accessible again when it completes with success. If 18012eb4683SFrank Haverkamp * not, the card will stay dead and registers will be unaccessible 18112eb4683SFrank Haverkamp * still. 18212eb4683SFrank Haverkamp */ 18312eb4683SFrank Haverkamp static int genwqe_bus_reset(struct genwqe_dev *cd) 18412eb4683SFrank Haverkamp { 185f03774bdSJohannes Thumshirn int rc = 0; 18612eb4683SFrank Haverkamp struct pci_dev *pci_dev = cd->pci_dev; 18712eb4683SFrank Haverkamp void __iomem *mmio; 18812eb4683SFrank Haverkamp 18912eb4683SFrank Haverkamp if (cd->err_inject & GENWQE_INJECT_BUS_RESET_FAILURE) 19012eb4683SFrank Haverkamp return -EIO; 19112eb4683SFrank Haverkamp 19212eb4683SFrank Haverkamp mmio = cd->mmio; 19312eb4683SFrank Haverkamp cd->mmio = NULL; 19412eb4683SFrank Haverkamp pci_iounmap(pci_dev, mmio); 19512eb4683SFrank Haverkamp 196f03774bdSJohannes Thumshirn pci_release_mem_regions(pci_dev); 19712eb4683SFrank Haverkamp 19812eb4683SFrank Haverkamp /* 19912eb4683SFrank Haverkamp * Firmware/BIOS might change memory mapping during bus reset. 20012eb4683SFrank Haverkamp * Settings like enable bus-mastering, ... are backuped and 20112eb4683SFrank Haverkamp * restored by the pci_reset_function(). 20212eb4683SFrank Haverkamp */ 20312eb4683SFrank Haverkamp dev_dbg(&pci_dev->dev, "[%s] pci_reset function ...\n", __func__); 20412eb4683SFrank Haverkamp rc = pci_reset_function(pci_dev); 20512eb4683SFrank Haverkamp if (rc) { 20612eb4683SFrank Haverkamp dev_err(&pci_dev->dev, 20712eb4683SFrank Haverkamp "[%s] err: failed reset func (rc %d)\n", __func__, rc); 20812eb4683SFrank Haverkamp return rc; 20912eb4683SFrank Haverkamp } 21012eb4683SFrank Haverkamp dev_dbg(&pci_dev->dev, "[%s] done with rc=%d\n", __func__, rc); 21112eb4683SFrank Haverkamp 21212eb4683SFrank Haverkamp /* 21312eb4683SFrank Haverkamp * Here is the right spot to clear the register read 21412eb4683SFrank Haverkamp * failure. pci_bus_reset() does this job in real systems. 21512eb4683SFrank Haverkamp */ 21612eb4683SFrank Haverkamp cd->err_inject &= ~(GENWQE_INJECT_HARDWARE_FAILURE | 21712eb4683SFrank Haverkamp GENWQE_INJECT_GFIR_FATAL | 21812eb4683SFrank Haverkamp GENWQE_INJECT_GFIR_INFO); 21912eb4683SFrank Haverkamp 220f03774bdSJohannes Thumshirn rc = pci_request_mem_regions(pci_dev, genwqe_driver_name); 22112eb4683SFrank Haverkamp if (rc) { 22212eb4683SFrank Haverkamp dev_err(&pci_dev->dev, 22312eb4683SFrank Haverkamp "[%s] err: request bars failed (%d)\n", __func__, rc); 22412eb4683SFrank Haverkamp return -EIO; 22512eb4683SFrank Haverkamp } 22612eb4683SFrank Haverkamp 22712eb4683SFrank Haverkamp cd->mmio = pci_iomap(pci_dev, 0, 0); 22812eb4683SFrank Haverkamp if (cd->mmio == NULL) { 22912eb4683SFrank Haverkamp dev_err(&pci_dev->dev, 23012eb4683SFrank Haverkamp "[%s] err: mapping BAR0 failed\n", __func__); 23112eb4683SFrank Haverkamp return -ENOMEM; 23212eb4683SFrank Haverkamp } 23312eb4683SFrank Haverkamp return 0; 23412eb4683SFrank Haverkamp } 23512eb4683SFrank Haverkamp 23612eb4683SFrank Haverkamp /* 23712eb4683SFrank Haverkamp * Hardware circumvention section. Certain bitstreams in our test-lab 23812eb4683SFrank Haverkamp * had different kinds of problems. Here is where we adjust those 23912eb4683SFrank Haverkamp * bitstreams to function will with this version of our device driver. 24012eb4683SFrank Haverkamp * 24112eb4683SFrank Haverkamp * Thise circumventions are applied to the physical function only. 24212eb4683SFrank Haverkamp * The magical numbers below are identifying development/manufacturing 24312eb4683SFrank Haverkamp * versions of the bitstream used on the card. 24412eb4683SFrank Haverkamp * 24512eb4683SFrank Haverkamp * Turn off error reporting for old/manufacturing images. 24612eb4683SFrank Haverkamp */ 24712eb4683SFrank Haverkamp 24812eb4683SFrank Haverkamp bool genwqe_need_err_masking(struct genwqe_dev *cd) 24912eb4683SFrank Haverkamp { 25012eb4683SFrank Haverkamp return (cd->slu_unitcfg & 0xFFFF0ull) < 0x32170ull; 25112eb4683SFrank Haverkamp } 25212eb4683SFrank Haverkamp 25312eb4683SFrank Haverkamp static void genwqe_tweak_hardware(struct genwqe_dev *cd) 25412eb4683SFrank Haverkamp { 25512eb4683SFrank Haverkamp struct pci_dev *pci_dev = cd->pci_dev; 25612eb4683SFrank Haverkamp 25712eb4683SFrank Haverkamp /* Mask FIRs for development images */ 25812eb4683SFrank Haverkamp if (((cd->slu_unitcfg & 0xFFFF0ull) >= 0x32000ull) && 25912eb4683SFrank Haverkamp ((cd->slu_unitcfg & 0xFFFF0ull) <= 0x33250ull)) { 26012eb4683SFrank Haverkamp dev_warn(&pci_dev->dev, 26112eb4683SFrank Haverkamp "FIRs masked due to bitstream %016llx.%016llx\n", 26212eb4683SFrank Haverkamp cd->slu_unitcfg, cd->app_unitcfg); 26312eb4683SFrank Haverkamp 26412eb4683SFrank Haverkamp __genwqe_writeq(cd, IO_APP_SEC_LEM_DEBUG_OVR, 26512eb4683SFrank Haverkamp 0xFFFFFFFFFFFFFFFFull); 26612eb4683SFrank Haverkamp 26712eb4683SFrank Haverkamp __genwqe_writeq(cd, IO_APP_ERR_ACT_MASK, 26812eb4683SFrank Haverkamp 0x0000000000000000ull); 26912eb4683SFrank Haverkamp } 27012eb4683SFrank Haverkamp } 27112eb4683SFrank Haverkamp 27212eb4683SFrank Haverkamp /** 27312eb4683SFrank Haverkamp * genwqe_recovery_on_fatal_gfir_required() - Version depended actions 27412eb4683SFrank Haverkamp * 27512eb4683SFrank Haverkamp * Bitstreams older than 2013-02-17 have a bug where fatal GFIRs must 27612eb4683SFrank Haverkamp * be ignored. This is e.g. true for the bitstream we gave to the card 27712eb4683SFrank Haverkamp * manufacturer, but also for some old bitstreams we released to our 27812eb4683SFrank Haverkamp * test-lab. 27912eb4683SFrank Haverkamp */ 28012eb4683SFrank Haverkamp int genwqe_recovery_on_fatal_gfir_required(struct genwqe_dev *cd) 28112eb4683SFrank Haverkamp { 28212eb4683SFrank Haverkamp return (cd->slu_unitcfg & 0xFFFF0ull) >= 0x32170ull; 28312eb4683SFrank Haverkamp } 28412eb4683SFrank Haverkamp 28512eb4683SFrank Haverkamp int genwqe_flash_readback_fails(struct genwqe_dev *cd) 28612eb4683SFrank Haverkamp { 28712eb4683SFrank Haverkamp return (cd->slu_unitcfg & 0xFFFF0ull) < 0x32170ull; 28812eb4683SFrank Haverkamp } 28912eb4683SFrank Haverkamp 29012eb4683SFrank Haverkamp /** 29112eb4683SFrank Haverkamp * genwqe_T_psec() - Calculate PF/VF timeout register content 29212eb4683SFrank Haverkamp * 29312eb4683SFrank Haverkamp * Note: From a design perspective it turned out to be a bad idea to 29412eb4683SFrank Haverkamp * use codes here to specifiy the frequency/speed values. An old 29512eb4683SFrank Haverkamp * driver cannot understand new codes and is therefore always a 29612eb4683SFrank Haverkamp * problem. Better is to measure out the value or put the 29712eb4683SFrank Haverkamp * speed/frequency directly into a register which is always a valid 29812eb4683SFrank Haverkamp * value for old as well as for new software. 29912eb4683SFrank Haverkamp */ 30012eb4683SFrank Haverkamp /* T = 1/f */ 30112eb4683SFrank Haverkamp static int genwqe_T_psec(struct genwqe_dev *cd) 30212eb4683SFrank Haverkamp { 30312eb4683SFrank Haverkamp u16 speed; /* 1/f -> 250, 200, 166, 175 */ 30412eb4683SFrank Haverkamp static const int T[] = { 4000, 5000, 6000, 5714 }; 30512eb4683SFrank Haverkamp 30612eb4683SFrank Haverkamp speed = (u16)((cd->slu_unitcfg >> 28) & 0x0full); 30712eb4683SFrank Haverkamp if (speed >= ARRAY_SIZE(T)) 30812eb4683SFrank Haverkamp return -1; /* illegal value */ 30912eb4683SFrank Haverkamp 31012eb4683SFrank Haverkamp return T[speed]; 31112eb4683SFrank Haverkamp } 31212eb4683SFrank Haverkamp 31312eb4683SFrank Haverkamp /** 31412eb4683SFrank Haverkamp * genwqe_setup_pf_jtimer() - Setup PF hardware timeouts for DDCB execution 31512eb4683SFrank Haverkamp * 31612eb4683SFrank Haverkamp * Do this _after_ card_reset() is called. Otherwise the values will 31712eb4683SFrank Haverkamp * vanish. The settings need to be done when the queues are inactive. 31812eb4683SFrank Haverkamp * 31912eb4683SFrank Haverkamp * The max. timeout value is 2^(10+x) * T (6ns for 166MHz) * 15/16. 32012eb4683SFrank Haverkamp * The min. timeout value is 2^(10+x) * T (6ns for 166MHz) * 14/16. 32112eb4683SFrank Haverkamp */ 32212eb4683SFrank Haverkamp static bool genwqe_setup_pf_jtimer(struct genwqe_dev *cd) 32312eb4683SFrank Haverkamp { 32412eb4683SFrank Haverkamp u32 T = genwqe_T_psec(cd); 32512eb4683SFrank Haverkamp u64 x; 32612eb4683SFrank Haverkamp 32712eb4683SFrank Haverkamp if (genwqe_pf_jobtimeout_msec == 0) 32812eb4683SFrank Haverkamp return false; 32912eb4683SFrank Haverkamp 33012eb4683SFrank Haverkamp /* PF: large value needed, flash update 2sec per block */ 33112eb4683SFrank Haverkamp x = ilog2(genwqe_pf_jobtimeout_msec * 33212eb4683SFrank Haverkamp 16000000000uL/(T * 15)) - 10; 33312eb4683SFrank Haverkamp 33412eb4683SFrank Haverkamp genwqe_write_vreg(cd, IO_SLC_VF_APPJOB_TIMEOUT, 33512eb4683SFrank Haverkamp 0xff00 | (x & 0xff), 0); 33612eb4683SFrank Haverkamp return true; 33712eb4683SFrank Haverkamp } 33812eb4683SFrank Haverkamp 33912eb4683SFrank Haverkamp /** 34012eb4683SFrank Haverkamp * genwqe_setup_vf_jtimer() - Setup VF hardware timeouts for DDCB execution 34112eb4683SFrank Haverkamp */ 34212eb4683SFrank Haverkamp static bool genwqe_setup_vf_jtimer(struct genwqe_dev *cd) 34312eb4683SFrank Haverkamp { 34412eb4683SFrank Haverkamp struct pci_dev *pci_dev = cd->pci_dev; 34512eb4683SFrank Haverkamp unsigned int vf; 34612eb4683SFrank Haverkamp u32 T = genwqe_T_psec(cd); 34712eb4683SFrank Haverkamp u64 x; 34895a8825cSFrank Haverkamp int totalvfs; 34912eb4683SFrank Haverkamp 35095a8825cSFrank Haverkamp totalvfs = pci_sriov_get_totalvfs(pci_dev); 35195a8825cSFrank Haverkamp if (totalvfs <= 0) 35295a8825cSFrank Haverkamp return false; 35395a8825cSFrank Haverkamp 35495a8825cSFrank Haverkamp for (vf = 0; vf < totalvfs; vf++) { 35512eb4683SFrank Haverkamp 35612eb4683SFrank Haverkamp if (cd->vf_jobtimeout_msec[vf] == 0) 35712eb4683SFrank Haverkamp continue; 35812eb4683SFrank Haverkamp 35912eb4683SFrank Haverkamp x = ilog2(cd->vf_jobtimeout_msec[vf] * 36012eb4683SFrank Haverkamp 16000000000uL/(T * 15)) - 10; 36112eb4683SFrank Haverkamp 36212eb4683SFrank Haverkamp genwqe_write_vreg(cd, IO_SLC_VF_APPJOB_TIMEOUT, 36312eb4683SFrank Haverkamp 0xff00 | (x & 0xff), vf + 1); 36412eb4683SFrank Haverkamp } 36512eb4683SFrank Haverkamp return true; 36612eb4683SFrank Haverkamp } 36712eb4683SFrank Haverkamp 36812eb4683SFrank Haverkamp static int genwqe_ffdc_buffs_alloc(struct genwqe_dev *cd) 36912eb4683SFrank Haverkamp { 37012eb4683SFrank Haverkamp unsigned int type, e = 0; 37112eb4683SFrank Haverkamp 37212eb4683SFrank Haverkamp for (type = 0; type < GENWQE_DBG_UNITS; type++) { 37312eb4683SFrank Haverkamp switch (type) { 37412eb4683SFrank Haverkamp case GENWQE_DBG_UNIT0: 37512eb4683SFrank Haverkamp e = genwqe_ffdc_buff_size(cd, 0); 37612eb4683SFrank Haverkamp break; 37712eb4683SFrank Haverkamp case GENWQE_DBG_UNIT1: 37812eb4683SFrank Haverkamp e = genwqe_ffdc_buff_size(cd, 1); 37912eb4683SFrank Haverkamp break; 38012eb4683SFrank Haverkamp case GENWQE_DBG_UNIT2: 38112eb4683SFrank Haverkamp e = genwqe_ffdc_buff_size(cd, 2); 38212eb4683SFrank Haverkamp break; 38312eb4683SFrank Haverkamp case GENWQE_DBG_REGS: 38412eb4683SFrank Haverkamp e = GENWQE_FFDC_REGS; 38512eb4683SFrank Haverkamp break; 38612eb4683SFrank Haverkamp } 38712eb4683SFrank Haverkamp 38812eb4683SFrank Haverkamp /* currently support only the debug units mentioned here */ 38912eb4683SFrank Haverkamp cd->ffdc[type].entries = e; 390d9c11d45SFrank Haverkamp cd->ffdc[type].regs = 391d9c11d45SFrank Haverkamp kmalloc_array(e, sizeof(struct genwqe_reg), 39212eb4683SFrank Haverkamp GFP_KERNEL); 39312eb4683SFrank Haverkamp /* 39412eb4683SFrank Haverkamp * regs == NULL is ok, the using code treats this as no regs, 39512eb4683SFrank Haverkamp * Printing warning is ok in this case. 39612eb4683SFrank Haverkamp */ 39712eb4683SFrank Haverkamp } 39812eb4683SFrank Haverkamp return 0; 39912eb4683SFrank Haverkamp } 40012eb4683SFrank Haverkamp 40112eb4683SFrank Haverkamp static void genwqe_ffdc_buffs_free(struct genwqe_dev *cd) 40212eb4683SFrank Haverkamp { 40312eb4683SFrank Haverkamp unsigned int type; 40412eb4683SFrank Haverkamp 40512eb4683SFrank Haverkamp for (type = 0; type < GENWQE_DBG_UNITS; type++) { 40612eb4683SFrank Haverkamp kfree(cd->ffdc[type].regs); 40712eb4683SFrank Haverkamp cd->ffdc[type].regs = NULL; 40812eb4683SFrank Haverkamp } 40912eb4683SFrank Haverkamp } 41012eb4683SFrank Haverkamp 41112eb4683SFrank Haverkamp static int genwqe_read_ids(struct genwqe_dev *cd) 41212eb4683SFrank Haverkamp { 41312eb4683SFrank Haverkamp int err = 0; 41412eb4683SFrank Haverkamp int slu_id; 41512eb4683SFrank Haverkamp struct pci_dev *pci_dev = cd->pci_dev; 41612eb4683SFrank Haverkamp 41712eb4683SFrank Haverkamp cd->slu_unitcfg = __genwqe_readq(cd, IO_SLU_UNITCFG); 41812eb4683SFrank Haverkamp if (cd->slu_unitcfg == IO_ILLEGAL_VALUE) { 41912eb4683SFrank Haverkamp dev_err(&pci_dev->dev, 42012eb4683SFrank Haverkamp "err: SLUID=%016llx\n", cd->slu_unitcfg); 42112eb4683SFrank Haverkamp err = -EIO; 42212eb4683SFrank Haverkamp goto out_err; 42312eb4683SFrank Haverkamp } 42412eb4683SFrank Haverkamp 42512eb4683SFrank Haverkamp slu_id = genwqe_get_slu_id(cd); 42612eb4683SFrank Haverkamp if (slu_id < GENWQE_SLU_ARCH_REQ || slu_id == 0xff) { 42712eb4683SFrank Haverkamp dev_err(&pci_dev->dev, 42812eb4683SFrank Haverkamp "err: incompatible SLU Architecture %u\n", slu_id); 42912eb4683SFrank Haverkamp err = -ENOENT; 43012eb4683SFrank Haverkamp goto out_err; 43112eb4683SFrank Haverkamp } 43212eb4683SFrank Haverkamp 43312eb4683SFrank Haverkamp cd->app_unitcfg = __genwqe_readq(cd, IO_APP_UNITCFG); 43412eb4683SFrank Haverkamp if (cd->app_unitcfg == IO_ILLEGAL_VALUE) { 43512eb4683SFrank Haverkamp dev_err(&pci_dev->dev, 43612eb4683SFrank Haverkamp "err: APPID=%016llx\n", cd->app_unitcfg); 43712eb4683SFrank Haverkamp err = -EIO; 43812eb4683SFrank Haverkamp goto out_err; 43912eb4683SFrank Haverkamp } 44012eb4683SFrank Haverkamp genwqe_read_app_id(cd, cd->app_name, sizeof(cd->app_name)); 44112eb4683SFrank Haverkamp 44212eb4683SFrank Haverkamp /* 44312eb4683SFrank Haverkamp * Is access to all registers possible? If we are a VF the 44412eb4683SFrank Haverkamp * answer is obvious. If we run fully virtualized, we need to 44512eb4683SFrank Haverkamp * check if we can access all registers. If we do not have 44612eb4683SFrank Haverkamp * full access we will cause an UR and some informational FIRs 44712eb4683SFrank Haverkamp * in the PF, but that should not harm. 44812eb4683SFrank Haverkamp */ 44912eb4683SFrank Haverkamp if (pci_dev->is_virtfn) 45012eb4683SFrank Haverkamp cd->is_privileged = 0; 45112eb4683SFrank Haverkamp else 45212eb4683SFrank Haverkamp cd->is_privileged = (__genwqe_readq(cd, IO_SLU_BITSTREAM) 45312eb4683SFrank Haverkamp != IO_ILLEGAL_VALUE); 45412eb4683SFrank Haverkamp 45512eb4683SFrank Haverkamp out_err: 45612eb4683SFrank Haverkamp return err; 45712eb4683SFrank Haverkamp } 45812eb4683SFrank Haverkamp 45912eb4683SFrank Haverkamp static int genwqe_start(struct genwqe_dev *cd) 46012eb4683SFrank Haverkamp { 46112eb4683SFrank Haverkamp int err; 46212eb4683SFrank Haverkamp struct pci_dev *pci_dev = cd->pci_dev; 46312eb4683SFrank Haverkamp 46412eb4683SFrank Haverkamp err = genwqe_read_ids(cd); 46512eb4683SFrank Haverkamp if (err) 46612eb4683SFrank Haverkamp return err; 46712eb4683SFrank Haverkamp 46812eb4683SFrank Haverkamp if (genwqe_is_privileged(cd)) { 46912eb4683SFrank Haverkamp /* do this after the tweaks. alloc fail is acceptable */ 47012eb4683SFrank Haverkamp genwqe_ffdc_buffs_alloc(cd); 47112eb4683SFrank Haverkamp genwqe_stop_traps(cd); 47212eb4683SFrank Haverkamp 47312eb4683SFrank Haverkamp /* Collect registers e.g. FIRs, UNITIDs, traces ... */ 47412eb4683SFrank Haverkamp genwqe_read_ffdc_regs(cd, cd->ffdc[GENWQE_DBG_REGS].regs, 47512eb4683SFrank Haverkamp cd->ffdc[GENWQE_DBG_REGS].entries, 0); 47612eb4683SFrank Haverkamp 47712eb4683SFrank Haverkamp genwqe_ffdc_buff_read(cd, GENWQE_DBG_UNIT0, 47812eb4683SFrank Haverkamp cd->ffdc[GENWQE_DBG_UNIT0].regs, 47912eb4683SFrank Haverkamp cd->ffdc[GENWQE_DBG_UNIT0].entries); 48012eb4683SFrank Haverkamp 48112eb4683SFrank Haverkamp genwqe_ffdc_buff_read(cd, GENWQE_DBG_UNIT1, 48212eb4683SFrank Haverkamp cd->ffdc[GENWQE_DBG_UNIT1].regs, 48312eb4683SFrank Haverkamp cd->ffdc[GENWQE_DBG_UNIT1].entries); 48412eb4683SFrank Haverkamp 48512eb4683SFrank Haverkamp genwqe_ffdc_buff_read(cd, GENWQE_DBG_UNIT2, 48612eb4683SFrank Haverkamp cd->ffdc[GENWQE_DBG_UNIT2].regs, 48712eb4683SFrank Haverkamp cd->ffdc[GENWQE_DBG_UNIT2].entries); 48812eb4683SFrank Haverkamp 48912eb4683SFrank Haverkamp genwqe_start_traps(cd); 49012eb4683SFrank Haverkamp 49112eb4683SFrank Haverkamp if (cd->card_state == GENWQE_CARD_FATAL_ERROR) { 49212eb4683SFrank Haverkamp dev_warn(&pci_dev->dev, 49312eb4683SFrank Haverkamp "[%s] chip reload/recovery!\n", __func__); 49412eb4683SFrank Haverkamp 49512eb4683SFrank Haverkamp /* 49612eb4683SFrank Haverkamp * Stealth Mode: Reload chip on either hot 49712eb4683SFrank Haverkamp * reset or PERST. 49812eb4683SFrank Haverkamp */ 49912eb4683SFrank Haverkamp cd->softreset = 0x7Cull; 50012eb4683SFrank Haverkamp __genwqe_writeq(cd, IO_SLC_CFGREG_SOFTRESET, 50112eb4683SFrank Haverkamp cd->softreset); 50212eb4683SFrank Haverkamp 50312eb4683SFrank Haverkamp err = genwqe_bus_reset(cd); 50412eb4683SFrank Haverkamp if (err != 0) { 50512eb4683SFrank Haverkamp dev_err(&pci_dev->dev, 50612eb4683SFrank Haverkamp "[%s] err: bus reset failed!\n", 50712eb4683SFrank Haverkamp __func__); 50812eb4683SFrank Haverkamp goto out; 50912eb4683SFrank Haverkamp } 51012eb4683SFrank Haverkamp 51112eb4683SFrank Haverkamp /* 51212eb4683SFrank Haverkamp * Re-read the IDs because 51312eb4683SFrank Haverkamp * it could happen that the bitstream load 51412eb4683SFrank Haverkamp * failed! 51512eb4683SFrank Haverkamp */ 51612eb4683SFrank Haverkamp err = genwqe_read_ids(cd); 51712eb4683SFrank Haverkamp if (err) 51812eb4683SFrank Haverkamp goto out; 51912eb4683SFrank Haverkamp } 52012eb4683SFrank Haverkamp } 52112eb4683SFrank Haverkamp 52212eb4683SFrank Haverkamp err = genwqe_setup_service_layer(cd); /* does a reset to the card */ 52312eb4683SFrank Haverkamp if (err != 0) { 52412eb4683SFrank Haverkamp dev_err(&pci_dev->dev, 52512eb4683SFrank Haverkamp "[%s] err: could not setup servicelayer!\n", __func__); 52612eb4683SFrank Haverkamp err = -ENODEV; 52712eb4683SFrank Haverkamp goto out; 52812eb4683SFrank Haverkamp } 52912eb4683SFrank Haverkamp 53012eb4683SFrank Haverkamp if (genwqe_is_privileged(cd)) { /* code is running _after_ reset */ 53112eb4683SFrank Haverkamp genwqe_tweak_hardware(cd); 53212eb4683SFrank Haverkamp 53312eb4683SFrank Haverkamp genwqe_setup_pf_jtimer(cd); 53412eb4683SFrank Haverkamp genwqe_setup_vf_jtimer(cd); 53512eb4683SFrank Haverkamp } 53612eb4683SFrank Haverkamp 53712eb4683SFrank Haverkamp err = genwqe_device_create(cd); 53812eb4683SFrank Haverkamp if (err < 0) { 53912eb4683SFrank Haverkamp dev_err(&pci_dev->dev, 54012eb4683SFrank Haverkamp "err: chdev init failed! (err=%d)\n", err); 54112eb4683SFrank Haverkamp goto out_release_service_layer; 54212eb4683SFrank Haverkamp } 54312eb4683SFrank Haverkamp return 0; 54412eb4683SFrank Haverkamp 54512eb4683SFrank Haverkamp out_release_service_layer: 54612eb4683SFrank Haverkamp genwqe_release_service_layer(cd); 54712eb4683SFrank Haverkamp out: 54812eb4683SFrank Haverkamp if (genwqe_is_privileged(cd)) 54912eb4683SFrank Haverkamp genwqe_ffdc_buffs_free(cd); 55012eb4683SFrank Haverkamp return -EIO; 55112eb4683SFrank Haverkamp } 55212eb4683SFrank Haverkamp 55312eb4683SFrank Haverkamp /** 55412eb4683SFrank Haverkamp * genwqe_stop() - Stop card operation 55512eb4683SFrank Haverkamp * 55612eb4683SFrank Haverkamp * Recovery notes: 55712eb4683SFrank Haverkamp * As long as genwqe_thread runs we might access registers during 55812eb4683SFrank Haverkamp * error data capture. Same is with the genwqe_health_thread. 55912eb4683SFrank Haverkamp * When genwqe_bus_reset() fails this function might called two times: 56012eb4683SFrank Haverkamp * first by the genwqe_health_thread() and later by genwqe_remove() to 56112eb4683SFrank Haverkamp * unbind the device. We must be able to survive that. 56212eb4683SFrank Haverkamp * 56312eb4683SFrank Haverkamp * This function must be robust enough to be called twice. 56412eb4683SFrank Haverkamp */ 56512eb4683SFrank Haverkamp static int genwqe_stop(struct genwqe_dev *cd) 56612eb4683SFrank Haverkamp { 56712eb4683SFrank Haverkamp genwqe_finish_queue(cd); /* no register access */ 56812eb4683SFrank Haverkamp genwqe_device_remove(cd); /* device removed, procs killed */ 56912eb4683SFrank Haverkamp genwqe_release_service_layer(cd); /* here genwqe_thread is stopped */ 57012eb4683SFrank Haverkamp 57112eb4683SFrank Haverkamp if (genwqe_is_privileged(cd)) { 57212eb4683SFrank Haverkamp pci_disable_sriov(cd->pci_dev); /* access pci config space */ 57312eb4683SFrank Haverkamp genwqe_ffdc_buffs_free(cd); 57412eb4683SFrank Haverkamp } 57512eb4683SFrank Haverkamp 57612eb4683SFrank Haverkamp return 0; 57712eb4683SFrank Haverkamp } 57812eb4683SFrank Haverkamp 57912eb4683SFrank Haverkamp /** 58012eb4683SFrank Haverkamp * genwqe_recover_card() - Try to recover the card if it is possible 58112eb4683SFrank Haverkamp * 58212eb4683SFrank Haverkamp * If fatal_err is set no register access is possible anymore. It is 58312eb4683SFrank Haverkamp * likely that genwqe_start fails in that situation. Proper error 58412eb4683SFrank Haverkamp * handling is required in this case. 58512eb4683SFrank Haverkamp * 58612eb4683SFrank Haverkamp * genwqe_bus_reset() will cause the pci code to call genwqe_remove() 58712eb4683SFrank Haverkamp * and later genwqe_probe() for all virtual functions. 58812eb4683SFrank Haverkamp */ 58912eb4683SFrank Haverkamp static int genwqe_recover_card(struct genwqe_dev *cd, int fatal_err) 59012eb4683SFrank Haverkamp { 59112eb4683SFrank Haverkamp int rc; 59212eb4683SFrank Haverkamp struct pci_dev *pci_dev = cd->pci_dev; 59312eb4683SFrank Haverkamp 59412eb4683SFrank Haverkamp genwqe_stop(cd); 59512eb4683SFrank Haverkamp 59612eb4683SFrank Haverkamp /* 59712eb4683SFrank Haverkamp * Make sure chip is not reloaded to maintain FFDC. Write SLU 59812eb4683SFrank Haverkamp * Reset Register, CPLDReset field to 0. 59912eb4683SFrank Haverkamp */ 60012eb4683SFrank Haverkamp if (!fatal_err) { 60112eb4683SFrank Haverkamp cd->softreset = 0x70ull; 60212eb4683SFrank Haverkamp __genwqe_writeq(cd, IO_SLC_CFGREG_SOFTRESET, cd->softreset); 60312eb4683SFrank Haverkamp } 60412eb4683SFrank Haverkamp 60512eb4683SFrank Haverkamp rc = genwqe_bus_reset(cd); 60612eb4683SFrank Haverkamp if (rc != 0) { 60712eb4683SFrank Haverkamp dev_err(&pci_dev->dev, 60812eb4683SFrank Haverkamp "[%s] err: card recovery impossible!\n", __func__); 60912eb4683SFrank Haverkamp return rc; 61012eb4683SFrank Haverkamp } 61112eb4683SFrank Haverkamp 61212eb4683SFrank Haverkamp rc = genwqe_start(cd); 61312eb4683SFrank Haverkamp if (rc < 0) { 61412eb4683SFrank Haverkamp dev_err(&pci_dev->dev, 61512eb4683SFrank Haverkamp "[%s] err: failed to launch device!\n", __func__); 61612eb4683SFrank Haverkamp return rc; 61712eb4683SFrank Haverkamp } 61812eb4683SFrank Haverkamp return 0; 61912eb4683SFrank Haverkamp } 62012eb4683SFrank Haverkamp 62112eb4683SFrank Haverkamp static int genwqe_health_check_cond(struct genwqe_dev *cd, u64 *gfir) 62212eb4683SFrank Haverkamp { 62312eb4683SFrank Haverkamp *gfir = __genwqe_readq(cd, IO_SLC_CFGREG_GFIR); 62412eb4683SFrank Haverkamp return (*gfir & GFIR_ERR_TRIGGER) && 62512eb4683SFrank Haverkamp genwqe_recovery_on_fatal_gfir_required(cd); 62612eb4683SFrank Haverkamp } 62712eb4683SFrank Haverkamp 62812eb4683SFrank Haverkamp /** 62912eb4683SFrank Haverkamp * genwqe_fir_checking() - Check the fault isolation registers of the card 63012eb4683SFrank Haverkamp * 63112eb4683SFrank Haverkamp * If this code works ok, can be tried out with help of the genwqe_poke tool: 63212eb4683SFrank Haverkamp * sudo ./tools/genwqe_poke 0x8 0xfefefefefef 63312eb4683SFrank Haverkamp * 63412eb4683SFrank Haverkamp * Now the relevant FIRs/sFIRs should be printed out and the driver should 63512eb4683SFrank Haverkamp * invoke recovery (devices are removed and readded). 63612eb4683SFrank Haverkamp */ 63712eb4683SFrank Haverkamp static u64 genwqe_fir_checking(struct genwqe_dev *cd) 63812eb4683SFrank Haverkamp { 63912eb4683SFrank Haverkamp int j, iterations = 0; 64012eb4683SFrank Haverkamp u64 mask, fir, fec, uid, gfir, gfir_masked, sfir, sfec; 64112eb4683SFrank Haverkamp u32 fir_addr, fir_clr_addr, fec_addr, sfir_addr, sfec_addr; 64212eb4683SFrank Haverkamp struct pci_dev *pci_dev = cd->pci_dev; 64312eb4683SFrank Haverkamp 64412eb4683SFrank Haverkamp healthMonitor: 64512eb4683SFrank Haverkamp iterations++; 64612eb4683SFrank Haverkamp if (iterations > 16) { 64712eb4683SFrank Haverkamp dev_err(&pci_dev->dev, "* exit looping after %d times\n", 64812eb4683SFrank Haverkamp iterations); 64912eb4683SFrank Haverkamp goto fatal_error; 65012eb4683SFrank Haverkamp } 65112eb4683SFrank Haverkamp 65212eb4683SFrank Haverkamp gfir = __genwqe_readq(cd, IO_SLC_CFGREG_GFIR); 65312eb4683SFrank Haverkamp if (gfir != 0x0) 65412eb4683SFrank Haverkamp dev_err(&pci_dev->dev, "* 0x%08x 0x%016llx\n", 65512eb4683SFrank Haverkamp IO_SLC_CFGREG_GFIR, gfir); 65612eb4683SFrank Haverkamp if (gfir == IO_ILLEGAL_VALUE) 65712eb4683SFrank Haverkamp goto fatal_error; 65812eb4683SFrank Haverkamp 65912eb4683SFrank Haverkamp /* 66012eb4683SFrank Haverkamp * Avoid printing when to GFIR bit is on prevents contignous 66112eb4683SFrank Haverkamp * printout e.g. for the following bug: 66212eb4683SFrank Haverkamp * FIR set without a 2ndary FIR/FIR cannot be cleared 66312eb4683SFrank Haverkamp * Comment out the following if to get the prints: 66412eb4683SFrank Haverkamp */ 66512eb4683SFrank Haverkamp if (gfir == 0) 66612eb4683SFrank Haverkamp return 0; 66712eb4683SFrank Haverkamp 66812eb4683SFrank Haverkamp gfir_masked = gfir & GFIR_ERR_TRIGGER; /* fatal errors */ 66912eb4683SFrank Haverkamp 67012eb4683SFrank Haverkamp for (uid = 0; uid < GENWQE_MAX_UNITS; uid++) { /* 0..2 in zEDC */ 67112eb4683SFrank Haverkamp 67212eb4683SFrank Haverkamp /* read the primary FIR (pfir) */ 67312eb4683SFrank Haverkamp fir_addr = (uid << 24) + 0x08; 67412eb4683SFrank Haverkamp fir = __genwqe_readq(cd, fir_addr); 67512eb4683SFrank Haverkamp if (fir == 0x0) 67612eb4683SFrank Haverkamp continue; /* no error in this unit */ 67712eb4683SFrank Haverkamp 67812eb4683SFrank Haverkamp dev_err(&pci_dev->dev, "* 0x%08x 0x%016llx\n", fir_addr, fir); 67912eb4683SFrank Haverkamp if (fir == IO_ILLEGAL_VALUE) 68012eb4683SFrank Haverkamp goto fatal_error; 68112eb4683SFrank Haverkamp 68212eb4683SFrank Haverkamp /* read primary FEC */ 68312eb4683SFrank Haverkamp fec_addr = (uid << 24) + 0x18; 68412eb4683SFrank Haverkamp fec = __genwqe_readq(cd, fec_addr); 68512eb4683SFrank Haverkamp 68612eb4683SFrank Haverkamp dev_err(&pci_dev->dev, "* 0x%08x 0x%016llx\n", fec_addr, fec); 68712eb4683SFrank Haverkamp if (fec == IO_ILLEGAL_VALUE) 68812eb4683SFrank Haverkamp goto fatal_error; 68912eb4683SFrank Haverkamp 69012eb4683SFrank Haverkamp for (j = 0, mask = 1ULL; j < 64; j++, mask <<= 1) { 69112eb4683SFrank Haverkamp 69212eb4683SFrank Haverkamp /* secondary fir empty, skip it */ 69312eb4683SFrank Haverkamp if ((fir & mask) == 0x0) 69412eb4683SFrank Haverkamp continue; 69512eb4683SFrank Haverkamp 69612eb4683SFrank Haverkamp sfir_addr = (uid << 24) + 0x100 + 0x08 * j; 69712eb4683SFrank Haverkamp sfir = __genwqe_readq(cd, sfir_addr); 69812eb4683SFrank Haverkamp 69912eb4683SFrank Haverkamp if (sfir == IO_ILLEGAL_VALUE) 70012eb4683SFrank Haverkamp goto fatal_error; 70112eb4683SFrank Haverkamp dev_err(&pci_dev->dev, 70212eb4683SFrank Haverkamp "* 0x%08x 0x%016llx\n", sfir_addr, sfir); 70312eb4683SFrank Haverkamp 70412eb4683SFrank Haverkamp sfec_addr = (uid << 24) + 0x300 + 0x08 * j; 70512eb4683SFrank Haverkamp sfec = __genwqe_readq(cd, sfec_addr); 70612eb4683SFrank Haverkamp 70712eb4683SFrank Haverkamp if (sfec == IO_ILLEGAL_VALUE) 70812eb4683SFrank Haverkamp goto fatal_error; 70912eb4683SFrank Haverkamp dev_err(&pci_dev->dev, 71012eb4683SFrank Haverkamp "* 0x%08x 0x%016llx\n", sfec_addr, sfec); 71112eb4683SFrank Haverkamp 71212eb4683SFrank Haverkamp gfir = __genwqe_readq(cd, IO_SLC_CFGREG_GFIR); 71312eb4683SFrank Haverkamp if (gfir == IO_ILLEGAL_VALUE) 71412eb4683SFrank Haverkamp goto fatal_error; 71512eb4683SFrank Haverkamp 71612eb4683SFrank Haverkamp /* gfir turned on during routine! get out and 71712eb4683SFrank Haverkamp start over. */ 71812eb4683SFrank Haverkamp if ((gfir_masked == 0x0) && 71912eb4683SFrank Haverkamp (gfir & GFIR_ERR_TRIGGER)) { 72012eb4683SFrank Haverkamp goto healthMonitor; 72112eb4683SFrank Haverkamp } 72212eb4683SFrank Haverkamp 72312eb4683SFrank Haverkamp /* do not clear if we entered with a fatal gfir */ 72412eb4683SFrank Haverkamp if (gfir_masked == 0x0) { 72512eb4683SFrank Haverkamp 72612eb4683SFrank Haverkamp /* NEW clear by mask the logged bits */ 72712eb4683SFrank Haverkamp sfir_addr = (uid << 24) + 0x100 + 0x08 * j; 72812eb4683SFrank Haverkamp __genwqe_writeq(cd, sfir_addr, sfir); 72912eb4683SFrank Haverkamp 73012eb4683SFrank Haverkamp dev_dbg(&pci_dev->dev, 731d9c11d45SFrank Haverkamp "[HM] Clearing 2ndary FIR 0x%08x with 0x%016llx\n", 732d9c11d45SFrank Haverkamp sfir_addr, sfir); 73312eb4683SFrank Haverkamp 73412eb4683SFrank Haverkamp /* 73512eb4683SFrank Haverkamp * note, these cannot be error-Firs 73612eb4683SFrank Haverkamp * since gfir_masked is 0 after sfir 73712eb4683SFrank Haverkamp * was read. Also, it is safe to do 73812eb4683SFrank Haverkamp * this write if sfir=0. Still need to 73912eb4683SFrank Haverkamp * clear the primary. This just means 74012eb4683SFrank Haverkamp * there is no secondary FIR. 74112eb4683SFrank Haverkamp */ 74212eb4683SFrank Haverkamp 74312eb4683SFrank Haverkamp /* clear by mask the logged bit. */ 74412eb4683SFrank Haverkamp fir_clr_addr = (uid << 24) + 0x10; 74512eb4683SFrank Haverkamp __genwqe_writeq(cd, fir_clr_addr, mask); 74612eb4683SFrank Haverkamp 74712eb4683SFrank Haverkamp dev_dbg(&pci_dev->dev, 748d9c11d45SFrank Haverkamp "[HM] Clearing primary FIR 0x%08x with 0x%016llx\n", 749d9c11d45SFrank Haverkamp fir_clr_addr, mask); 75012eb4683SFrank Haverkamp } 75112eb4683SFrank Haverkamp } 75212eb4683SFrank Haverkamp } 75312eb4683SFrank Haverkamp gfir = __genwqe_readq(cd, IO_SLC_CFGREG_GFIR); 75412eb4683SFrank Haverkamp if (gfir == IO_ILLEGAL_VALUE) 75512eb4683SFrank Haverkamp goto fatal_error; 75612eb4683SFrank Haverkamp 75712eb4683SFrank Haverkamp if ((gfir_masked == 0x0) && (gfir & GFIR_ERR_TRIGGER)) { 75812eb4683SFrank Haverkamp /* 75912eb4683SFrank Haverkamp * Check once more that it didn't go on after all the 76012eb4683SFrank Haverkamp * FIRS were cleared. 76112eb4683SFrank Haverkamp */ 76212eb4683SFrank Haverkamp dev_dbg(&pci_dev->dev, "ACK! Another FIR! Recursing %d!\n", 76312eb4683SFrank Haverkamp iterations); 76412eb4683SFrank Haverkamp goto healthMonitor; 76512eb4683SFrank Haverkamp } 76612eb4683SFrank Haverkamp return gfir_masked; 76712eb4683SFrank Haverkamp 76812eb4683SFrank Haverkamp fatal_error: 76912eb4683SFrank Haverkamp return IO_ILLEGAL_VALUE; 77012eb4683SFrank Haverkamp } 77112eb4683SFrank Haverkamp 77212eb4683SFrank Haverkamp /** 773c1f732adSKleber Sacilotto de Souza * genwqe_pci_fundamental_reset() - trigger a PCIe fundamental reset on the slot 774c1f732adSKleber Sacilotto de Souza * 775c1f732adSKleber Sacilotto de Souza * Note: pci_set_pcie_reset_state() is not implemented on all archs, so this 776c1f732adSKleber Sacilotto de Souza * reset method will not work in all cases. 777c1f732adSKleber Sacilotto de Souza * 778c1f732adSKleber Sacilotto de Souza * Return: 0 on success or error code from pci_set_pcie_reset_state() 779c1f732adSKleber Sacilotto de Souza */ 780c1f732adSKleber Sacilotto de Souza static int genwqe_pci_fundamental_reset(struct pci_dev *pci_dev) 781c1f732adSKleber Sacilotto de Souza { 782c1f732adSKleber Sacilotto de Souza int rc; 783c1f732adSKleber Sacilotto de Souza 784c1f732adSKleber Sacilotto de Souza /* 785c1f732adSKleber Sacilotto de Souza * lock pci config space access from userspace, 786c1f732adSKleber Sacilotto de Souza * save state and issue PCIe fundamental reset 787c1f732adSKleber Sacilotto de Souza */ 788c1f732adSKleber Sacilotto de Souza pci_cfg_access_lock(pci_dev); 789c1f732adSKleber Sacilotto de Souza pci_save_state(pci_dev); 790c1f732adSKleber Sacilotto de Souza rc = pci_set_pcie_reset_state(pci_dev, pcie_warm_reset); 791c1f732adSKleber Sacilotto de Souza if (!rc) { 792c1f732adSKleber Sacilotto de Souza /* keep PCIe reset asserted for 250ms */ 793c1f732adSKleber Sacilotto de Souza msleep(250); 794c1f732adSKleber Sacilotto de Souza pci_set_pcie_reset_state(pci_dev, pcie_deassert_reset); 795c1f732adSKleber Sacilotto de Souza /* Wait for 2s to reload flash and train the link */ 796c1f732adSKleber Sacilotto de Souza msleep(2000); 797c1f732adSKleber Sacilotto de Souza } 798c1f732adSKleber Sacilotto de Souza pci_restore_state(pci_dev); 799c1f732adSKleber Sacilotto de Souza pci_cfg_access_unlock(pci_dev); 800c1f732adSKleber Sacilotto de Souza return rc; 801c1f732adSKleber Sacilotto de Souza } 802c1f732adSKleber Sacilotto de Souza 80393b772b2SKleber Sacilotto de Souza 80493b772b2SKleber Sacilotto de Souza static int genwqe_platform_recovery(struct genwqe_dev *cd) 80593b772b2SKleber Sacilotto de Souza { 80693b772b2SKleber Sacilotto de Souza struct pci_dev *pci_dev = cd->pci_dev; 80793b772b2SKleber Sacilotto de Souza int rc; 80893b772b2SKleber Sacilotto de Souza 80993b772b2SKleber Sacilotto de Souza dev_info(&pci_dev->dev, 81093b772b2SKleber Sacilotto de Souza "[%s] resetting card for error recovery\n", __func__); 81193b772b2SKleber Sacilotto de Souza 81293b772b2SKleber Sacilotto de Souza /* Clear out error injection flags */ 81393b772b2SKleber Sacilotto de Souza cd->err_inject &= ~(GENWQE_INJECT_HARDWARE_FAILURE | 81493b772b2SKleber Sacilotto de Souza GENWQE_INJECT_GFIR_FATAL | 81593b772b2SKleber Sacilotto de Souza GENWQE_INJECT_GFIR_INFO); 81693b772b2SKleber Sacilotto de Souza 81793b772b2SKleber Sacilotto de Souza genwqe_stop(cd); 81893b772b2SKleber Sacilotto de Souza 81993b772b2SKleber Sacilotto de Souza /* Try recoverying the card with fundamental reset */ 82093b772b2SKleber Sacilotto de Souza rc = genwqe_pci_fundamental_reset(pci_dev); 82193b772b2SKleber Sacilotto de Souza if (!rc) { 82293b772b2SKleber Sacilotto de Souza rc = genwqe_start(cd); 82393b772b2SKleber Sacilotto de Souza if (!rc) 82493b772b2SKleber Sacilotto de Souza dev_info(&pci_dev->dev, 82593b772b2SKleber Sacilotto de Souza "[%s] card recovered\n", __func__); 82693b772b2SKleber Sacilotto de Souza else 82793b772b2SKleber Sacilotto de Souza dev_err(&pci_dev->dev, 82893b772b2SKleber Sacilotto de Souza "[%s] err: cannot start card services! (err=%d)\n", 82993b772b2SKleber Sacilotto de Souza __func__, rc); 83093b772b2SKleber Sacilotto de Souza } else { 83193b772b2SKleber Sacilotto de Souza dev_err(&pci_dev->dev, 83293b772b2SKleber Sacilotto de Souza "[%s] card reset failed\n", __func__); 83393b772b2SKleber Sacilotto de Souza } 83493b772b2SKleber Sacilotto de Souza 83593b772b2SKleber Sacilotto de Souza return rc; 83693b772b2SKleber Sacilotto de Souza } 83793b772b2SKleber Sacilotto de Souza 838c1f732adSKleber Sacilotto de Souza /* 839c1f732adSKleber Sacilotto de Souza * genwqe_reload_bistream() - reload card bitstream 840c1f732adSKleber Sacilotto de Souza * 841c1f732adSKleber Sacilotto de Souza * Set the appropriate register and call fundamental reset to reaload the card 842c1f732adSKleber Sacilotto de Souza * bitstream. 843c1f732adSKleber Sacilotto de Souza * 844c1f732adSKleber Sacilotto de Souza * Return: 0 on success, error code otherwise 845c1f732adSKleber Sacilotto de Souza */ 846c1f732adSKleber Sacilotto de Souza static int genwqe_reload_bistream(struct genwqe_dev *cd) 847c1f732adSKleber Sacilotto de Souza { 848c1f732adSKleber Sacilotto de Souza struct pci_dev *pci_dev = cd->pci_dev; 849c1f732adSKleber Sacilotto de Souza int rc; 850c1f732adSKleber Sacilotto de Souza 851c1f732adSKleber Sacilotto de Souza dev_info(&pci_dev->dev, 852c1f732adSKleber Sacilotto de Souza "[%s] resetting card for bitstream reload\n", 853c1f732adSKleber Sacilotto de Souza __func__); 854c1f732adSKleber Sacilotto de Souza 855c1f732adSKleber Sacilotto de Souza genwqe_stop(cd); 856c1f732adSKleber Sacilotto de Souza 857c1f732adSKleber Sacilotto de Souza /* 858c1f732adSKleber Sacilotto de Souza * Cause a CPLD reprogram with the 'next_bitstream' 859c1f732adSKleber Sacilotto de Souza * partition on PCIe hot or fundamental reset 860c1f732adSKleber Sacilotto de Souza */ 861c1f732adSKleber Sacilotto de Souza __genwqe_writeq(cd, IO_SLC_CFGREG_SOFTRESET, 862c1f732adSKleber Sacilotto de Souza (cd->softreset & 0xcull) | 0x70ull); 863c1f732adSKleber Sacilotto de Souza 864c1f732adSKleber Sacilotto de Souza rc = genwqe_pci_fundamental_reset(pci_dev); 865c1f732adSKleber Sacilotto de Souza if (rc) { 866c1f732adSKleber Sacilotto de Souza /* 867c1f732adSKleber Sacilotto de Souza * A fundamental reset failure can be caused 868c1f732adSKleber Sacilotto de Souza * by lack of support on the arch, so we just 869c1f732adSKleber Sacilotto de Souza * log the error and try to start the card 870c1f732adSKleber Sacilotto de Souza * again. 871c1f732adSKleber Sacilotto de Souza */ 872c1f732adSKleber Sacilotto de Souza dev_err(&pci_dev->dev, 873c1f732adSKleber Sacilotto de Souza "[%s] err: failed to reset card for bitstream reload\n", 874c1f732adSKleber Sacilotto de Souza __func__); 875c1f732adSKleber Sacilotto de Souza } 876c1f732adSKleber Sacilotto de Souza 877c1f732adSKleber Sacilotto de Souza rc = genwqe_start(cd); 878c1f732adSKleber Sacilotto de Souza if (rc) { 879c1f732adSKleber Sacilotto de Souza dev_err(&pci_dev->dev, 880c1f732adSKleber Sacilotto de Souza "[%s] err: cannot start card services! (err=%d)\n", 881c1f732adSKleber Sacilotto de Souza __func__, rc); 882c1f732adSKleber Sacilotto de Souza return rc; 883c1f732adSKleber Sacilotto de Souza } 884c1f732adSKleber Sacilotto de Souza dev_info(&pci_dev->dev, 885c1f732adSKleber Sacilotto de Souza "[%s] card reloaded\n", __func__); 886c1f732adSKleber Sacilotto de Souza return 0; 887c1f732adSKleber Sacilotto de Souza } 888c1f732adSKleber Sacilotto de Souza 889c1f732adSKleber Sacilotto de Souza 890c1f732adSKleber Sacilotto de Souza /** 89112eb4683SFrank Haverkamp * genwqe_health_thread() - Health checking thread 89212eb4683SFrank Haverkamp * 89312eb4683SFrank Haverkamp * This thread is only started for the PF of the card. 89412eb4683SFrank Haverkamp * 89512eb4683SFrank Haverkamp * This thread monitors the health of the card. A critical situation 89612eb4683SFrank Haverkamp * is when we read registers which contain -1 (IO_ILLEGAL_VALUE). In 89712eb4683SFrank Haverkamp * this case we need to be recovered from outside. Writing to 89812eb4683SFrank Haverkamp * registers will very likely not work either. 89912eb4683SFrank Haverkamp * 90012eb4683SFrank Haverkamp * This thread must only exit if kthread_should_stop() becomes true. 90112eb4683SFrank Haverkamp * 90212eb4683SFrank Haverkamp * Condition for the health-thread to trigger: 90312eb4683SFrank Haverkamp * a) when a kthread_stop() request comes in or 90412eb4683SFrank Haverkamp * b) a critical GFIR occured 90512eb4683SFrank Haverkamp * 90612eb4683SFrank Haverkamp * Informational GFIRs are checked and potentially printed in 90712eb4683SFrank Haverkamp * health_check_interval seconds. 90812eb4683SFrank Haverkamp */ 90912eb4683SFrank Haverkamp static int genwqe_health_thread(void *data) 91012eb4683SFrank Haverkamp { 91112eb4683SFrank Haverkamp int rc, should_stop = 0; 91212eb4683SFrank Haverkamp struct genwqe_dev *cd = data; 91312eb4683SFrank Haverkamp struct pci_dev *pci_dev = cd->pci_dev; 91412eb4683SFrank Haverkamp u64 gfir, gfir_masked, slu_unitcfg, app_unitcfg; 91512eb4683SFrank Haverkamp 91693b772b2SKleber Sacilotto de Souza health_thread_begin: 91712eb4683SFrank Haverkamp while (!kthread_should_stop()) { 91812eb4683SFrank Haverkamp rc = wait_event_interruptible_timeout(cd->health_waitq, 91912eb4683SFrank Haverkamp (genwqe_health_check_cond(cd, &gfir) || 92012eb4683SFrank Haverkamp (should_stop = kthread_should_stop())), 92112eb4683SFrank Haverkamp genwqe_health_check_interval * HZ); 92212eb4683SFrank Haverkamp 92312eb4683SFrank Haverkamp if (should_stop) 92412eb4683SFrank Haverkamp break; 92512eb4683SFrank Haverkamp 92612eb4683SFrank Haverkamp if (gfir == IO_ILLEGAL_VALUE) { 92712eb4683SFrank Haverkamp dev_err(&pci_dev->dev, 92812eb4683SFrank Haverkamp "[%s] GFIR=%016llx\n", __func__, gfir); 92912eb4683SFrank Haverkamp goto fatal_error; 93012eb4683SFrank Haverkamp } 93112eb4683SFrank Haverkamp 93212eb4683SFrank Haverkamp slu_unitcfg = __genwqe_readq(cd, IO_SLU_UNITCFG); 93312eb4683SFrank Haverkamp if (slu_unitcfg == IO_ILLEGAL_VALUE) { 93412eb4683SFrank Haverkamp dev_err(&pci_dev->dev, 93512eb4683SFrank Haverkamp "[%s] SLU_UNITCFG=%016llx\n", 93612eb4683SFrank Haverkamp __func__, slu_unitcfg); 93712eb4683SFrank Haverkamp goto fatal_error; 93812eb4683SFrank Haverkamp } 93912eb4683SFrank Haverkamp 94012eb4683SFrank Haverkamp app_unitcfg = __genwqe_readq(cd, IO_APP_UNITCFG); 94112eb4683SFrank Haverkamp if (app_unitcfg == IO_ILLEGAL_VALUE) { 94212eb4683SFrank Haverkamp dev_err(&pci_dev->dev, 94312eb4683SFrank Haverkamp "[%s] APP_UNITCFG=%016llx\n", 94412eb4683SFrank Haverkamp __func__, app_unitcfg); 94512eb4683SFrank Haverkamp goto fatal_error; 94612eb4683SFrank Haverkamp } 94712eb4683SFrank Haverkamp 94812eb4683SFrank Haverkamp gfir = __genwqe_readq(cd, IO_SLC_CFGREG_GFIR); 94912eb4683SFrank Haverkamp if (gfir == IO_ILLEGAL_VALUE) { 95012eb4683SFrank Haverkamp dev_err(&pci_dev->dev, 95112eb4683SFrank Haverkamp "[%s] %s: GFIR=%016llx\n", __func__, 95212eb4683SFrank Haverkamp (gfir & GFIR_ERR_TRIGGER) ? "err" : "info", 95312eb4683SFrank Haverkamp gfir); 95412eb4683SFrank Haverkamp goto fatal_error; 95512eb4683SFrank Haverkamp } 95612eb4683SFrank Haverkamp 95712eb4683SFrank Haverkamp gfir_masked = genwqe_fir_checking(cd); 95812eb4683SFrank Haverkamp if (gfir_masked == IO_ILLEGAL_VALUE) 95912eb4683SFrank Haverkamp goto fatal_error; 96012eb4683SFrank Haverkamp 96112eb4683SFrank Haverkamp /* 96212eb4683SFrank Haverkamp * GFIR ErrorTrigger bits set => reset the card! 96312eb4683SFrank Haverkamp * Never do this for old/manufacturing images! 96412eb4683SFrank Haverkamp */ 96512eb4683SFrank Haverkamp if ((gfir_masked) && !cd->skip_recovery && 96612eb4683SFrank Haverkamp genwqe_recovery_on_fatal_gfir_required(cd)) { 96712eb4683SFrank Haverkamp 96812eb4683SFrank Haverkamp cd->card_state = GENWQE_CARD_FATAL_ERROR; 96912eb4683SFrank Haverkamp 97012eb4683SFrank Haverkamp rc = genwqe_recover_card(cd, 0); 97112eb4683SFrank Haverkamp if (rc < 0) { 97212eb4683SFrank Haverkamp /* FIXME Card is unusable and needs unbind! */ 97312eb4683SFrank Haverkamp goto fatal_error; 97412eb4683SFrank Haverkamp } 97512eb4683SFrank Haverkamp } 97612eb4683SFrank Haverkamp 977c1f732adSKleber Sacilotto de Souza if (cd->card_state == GENWQE_CARD_RELOAD_BITSTREAM) { 978c1f732adSKleber Sacilotto de Souza /* Userspace requested card bitstream reload */ 979c1f732adSKleber Sacilotto de Souza rc = genwqe_reload_bistream(cd); 980c1f732adSKleber Sacilotto de Souza if (rc) 981c1f732adSKleber Sacilotto de Souza goto fatal_error; 982c1f732adSKleber Sacilotto de Souza } 983c1f732adSKleber Sacilotto de Souza 98412eb4683SFrank Haverkamp cd->last_gfir = gfir; 98512eb4683SFrank Haverkamp cond_resched(); 98612eb4683SFrank Haverkamp } 98712eb4683SFrank Haverkamp 98812eb4683SFrank Haverkamp return 0; 98912eb4683SFrank Haverkamp 99012eb4683SFrank Haverkamp fatal_error: 991fb145456SKleber Sacilotto de Souza if (cd->use_platform_recovery) { 992fb145456SKleber Sacilotto de Souza /* 993fb145456SKleber Sacilotto de Souza * Since we use raw accessors, EEH errors won't be detected 994fb145456SKleber Sacilotto de Souza * by the platform until we do a non-raw MMIO or config space 995fb145456SKleber Sacilotto de Souza * read 996fb145456SKleber Sacilotto de Souza */ 997fb145456SKleber Sacilotto de Souza readq(cd->mmio + IO_SLC_CFGREG_GFIR); 998fb145456SKleber Sacilotto de Souza 999fb145456SKleber Sacilotto de Souza /* We do nothing if the card is going over PCI recovery */ 1000fb145456SKleber Sacilotto de Souza if (pci_channel_offline(pci_dev)) 1001fb145456SKleber Sacilotto de Souza return -EIO; 100293b772b2SKleber Sacilotto de Souza 100393b772b2SKleber Sacilotto de Souza /* 100493b772b2SKleber Sacilotto de Souza * If it's supported by the platform, we try a fundamental reset 100593b772b2SKleber Sacilotto de Souza * to recover from a fatal error. Otherwise, we continue to wait 100693b772b2SKleber Sacilotto de Souza * for an external recovery procedure to take care of it. 100793b772b2SKleber Sacilotto de Souza */ 100893b772b2SKleber Sacilotto de Souza rc = genwqe_platform_recovery(cd); 100993b772b2SKleber Sacilotto de Souza if (!rc) 101093b772b2SKleber Sacilotto de Souza goto health_thread_begin; 1011fb145456SKleber Sacilotto de Souza } 1012fb145456SKleber Sacilotto de Souza 101312eb4683SFrank Haverkamp dev_err(&pci_dev->dev, 101412eb4683SFrank Haverkamp "[%s] card unusable. Please trigger unbind!\n", __func__); 101512eb4683SFrank Haverkamp 101612eb4683SFrank Haverkamp /* Bring down logical devices to inform user space via udev remove. */ 101712eb4683SFrank Haverkamp cd->card_state = GENWQE_CARD_FATAL_ERROR; 101812eb4683SFrank Haverkamp genwqe_stop(cd); 101912eb4683SFrank Haverkamp 102012eb4683SFrank Haverkamp /* genwqe_bus_reset failed(). Now wait for genwqe_remove(). */ 102112eb4683SFrank Haverkamp while (!kthread_should_stop()) 102212eb4683SFrank Haverkamp cond_resched(); 102312eb4683SFrank Haverkamp 102412eb4683SFrank Haverkamp return -EIO; 102512eb4683SFrank Haverkamp } 102612eb4683SFrank Haverkamp 102712eb4683SFrank Haverkamp static int genwqe_health_check_start(struct genwqe_dev *cd) 102812eb4683SFrank Haverkamp { 102912eb4683SFrank Haverkamp int rc; 103012eb4683SFrank Haverkamp 103112eb4683SFrank Haverkamp if (genwqe_health_check_interval <= 0) 103212eb4683SFrank Haverkamp return 0; /* valid for disabling the service */ 103312eb4683SFrank Haverkamp 103412eb4683SFrank Haverkamp /* moved before request_irq() */ 103512eb4683SFrank Haverkamp /* init_waitqueue_head(&cd->health_waitq); */ 103612eb4683SFrank Haverkamp 103712eb4683SFrank Haverkamp cd->health_thread = kthread_run(genwqe_health_thread, cd, 103812eb4683SFrank Haverkamp GENWQE_DEVNAME "%d_health", 103912eb4683SFrank Haverkamp cd->card_idx); 104012eb4683SFrank Haverkamp if (IS_ERR(cd->health_thread)) { 104112eb4683SFrank Haverkamp rc = PTR_ERR(cd->health_thread); 104212eb4683SFrank Haverkamp cd->health_thread = NULL; 104312eb4683SFrank Haverkamp return rc; 104412eb4683SFrank Haverkamp } 104512eb4683SFrank Haverkamp return 0; 104612eb4683SFrank Haverkamp } 104712eb4683SFrank Haverkamp 104812eb4683SFrank Haverkamp static int genwqe_health_thread_running(struct genwqe_dev *cd) 104912eb4683SFrank Haverkamp { 105012eb4683SFrank Haverkamp return cd->health_thread != NULL; 105112eb4683SFrank Haverkamp } 105212eb4683SFrank Haverkamp 105312eb4683SFrank Haverkamp static int genwqe_health_check_stop(struct genwqe_dev *cd) 105412eb4683SFrank Haverkamp { 105512eb4683SFrank Haverkamp int rc; 105612eb4683SFrank Haverkamp 105712eb4683SFrank Haverkamp if (!genwqe_health_thread_running(cd)) 105812eb4683SFrank Haverkamp return -EIO; 105912eb4683SFrank Haverkamp 106012eb4683SFrank Haverkamp rc = kthread_stop(cd->health_thread); 106112eb4683SFrank Haverkamp cd->health_thread = NULL; 106212eb4683SFrank Haverkamp return 0; 106312eb4683SFrank Haverkamp } 106412eb4683SFrank Haverkamp 106512eb4683SFrank Haverkamp /** 106612eb4683SFrank Haverkamp * genwqe_pci_setup() - Allocate PCIe related resources for our card 106712eb4683SFrank Haverkamp */ 106812eb4683SFrank Haverkamp static int genwqe_pci_setup(struct genwqe_dev *cd) 106912eb4683SFrank Haverkamp { 1070f03774bdSJohannes Thumshirn int err; 107112eb4683SFrank Haverkamp struct pci_dev *pci_dev = cd->pci_dev; 107212eb4683SFrank Haverkamp 107312eb4683SFrank Haverkamp err = pci_enable_device_mem(pci_dev); 107412eb4683SFrank Haverkamp if (err) { 107512eb4683SFrank Haverkamp dev_err(&pci_dev->dev, 107612eb4683SFrank Haverkamp "err: failed to enable pci memory (err=%d)\n", err); 107712eb4683SFrank Haverkamp goto err_out; 107812eb4683SFrank Haverkamp } 107912eb4683SFrank Haverkamp 108012eb4683SFrank Haverkamp /* Reserve PCI I/O and memory resources */ 1081f03774bdSJohannes Thumshirn err = pci_request_mem_regions(pci_dev, genwqe_driver_name); 108212eb4683SFrank Haverkamp if (err) { 108312eb4683SFrank Haverkamp dev_err(&pci_dev->dev, 108412eb4683SFrank Haverkamp "[%s] err: request bars failed (%d)\n", __func__, err); 108512eb4683SFrank Haverkamp err = -EIO; 108612eb4683SFrank Haverkamp goto err_disable_device; 108712eb4683SFrank Haverkamp } 108812eb4683SFrank Haverkamp 108912eb4683SFrank Haverkamp /* check for 64-bit DMA address supported (DAC) */ 109012eb4683SFrank Haverkamp if (!pci_set_dma_mask(pci_dev, DMA_BIT_MASK(64))) { 109112eb4683SFrank Haverkamp err = pci_set_consistent_dma_mask(pci_dev, DMA_BIT_MASK(64)); 109212eb4683SFrank Haverkamp if (err) { 109312eb4683SFrank Haverkamp dev_err(&pci_dev->dev, 109412eb4683SFrank Haverkamp "err: DMA64 consistent mask error\n"); 109512eb4683SFrank Haverkamp err = -EIO; 109612eb4683SFrank Haverkamp goto out_release_resources; 109712eb4683SFrank Haverkamp } 109812eb4683SFrank Haverkamp /* check for 32-bit DMA address supported (SAC) */ 109912eb4683SFrank Haverkamp } else if (!pci_set_dma_mask(pci_dev, DMA_BIT_MASK(32))) { 110012eb4683SFrank Haverkamp err = pci_set_consistent_dma_mask(pci_dev, DMA_BIT_MASK(32)); 110112eb4683SFrank Haverkamp if (err) { 110212eb4683SFrank Haverkamp dev_err(&pci_dev->dev, 110312eb4683SFrank Haverkamp "err: DMA32 consistent mask error\n"); 110412eb4683SFrank Haverkamp err = -EIO; 110512eb4683SFrank Haverkamp goto out_release_resources; 110612eb4683SFrank Haverkamp } 110712eb4683SFrank Haverkamp } else { 110812eb4683SFrank Haverkamp dev_err(&pci_dev->dev, 110912eb4683SFrank Haverkamp "err: neither DMA32 nor DMA64 supported\n"); 111012eb4683SFrank Haverkamp err = -EIO; 111112eb4683SFrank Haverkamp goto out_release_resources; 111212eb4683SFrank Haverkamp } 111312eb4683SFrank Haverkamp 111412eb4683SFrank Haverkamp pci_set_master(pci_dev); 111512eb4683SFrank Haverkamp pci_enable_pcie_error_reporting(pci_dev); 111612eb4683SFrank Haverkamp 1117fb145456SKleber Sacilotto de Souza /* EEH recovery requires PCIe fundamental reset */ 1118fb145456SKleber Sacilotto de Souza pci_dev->needs_freset = 1; 1119fb145456SKleber Sacilotto de Souza 112012eb4683SFrank Haverkamp /* request complete BAR-0 space (length = 0) */ 112112eb4683SFrank Haverkamp cd->mmio_len = pci_resource_len(pci_dev, 0); 112212eb4683SFrank Haverkamp cd->mmio = pci_iomap(pci_dev, 0, 0); 112312eb4683SFrank Haverkamp if (cd->mmio == NULL) { 112412eb4683SFrank Haverkamp dev_err(&pci_dev->dev, 112512eb4683SFrank Haverkamp "[%s] err: mapping BAR0 failed\n", __func__); 112612eb4683SFrank Haverkamp err = -ENOMEM; 112712eb4683SFrank Haverkamp goto out_release_resources; 112812eb4683SFrank Haverkamp } 112912eb4683SFrank Haverkamp 113012eb4683SFrank Haverkamp cd->num_vfs = pci_sriov_get_totalvfs(pci_dev); 113195a8825cSFrank Haverkamp if (cd->num_vfs < 0) 113295a8825cSFrank Haverkamp cd->num_vfs = 0; 113312eb4683SFrank Haverkamp 113412eb4683SFrank Haverkamp err = genwqe_read_ids(cd); 113512eb4683SFrank Haverkamp if (err) 113612eb4683SFrank Haverkamp goto out_iounmap; 113712eb4683SFrank Haverkamp 113812eb4683SFrank Haverkamp return 0; 113912eb4683SFrank Haverkamp 114012eb4683SFrank Haverkamp out_iounmap: 114112eb4683SFrank Haverkamp pci_iounmap(pci_dev, cd->mmio); 114212eb4683SFrank Haverkamp out_release_resources: 1143f03774bdSJohannes Thumshirn pci_release_mem_regions(pci_dev); 114412eb4683SFrank Haverkamp err_disable_device: 114512eb4683SFrank Haverkamp pci_disable_device(pci_dev); 114612eb4683SFrank Haverkamp err_out: 114712eb4683SFrank Haverkamp return err; 114812eb4683SFrank Haverkamp } 114912eb4683SFrank Haverkamp 115012eb4683SFrank Haverkamp /** 115112eb4683SFrank Haverkamp * genwqe_pci_remove() - Free PCIe related resources for our card 115212eb4683SFrank Haverkamp */ 115312eb4683SFrank Haverkamp static void genwqe_pci_remove(struct genwqe_dev *cd) 115412eb4683SFrank Haverkamp { 115512eb4683SFrank Haverkamp struct pci_dev *pci_dev = cd->pci_dev; 115612eb4683SFrank Haverkamp 115712eb4683SFrank Haverkamp if (cd->mmio) 115812eb4683SFrank Haverkamp pci_iounmap(pci_dev, cd->mmio); 115912eb4683SFrank Haverkamp 1160f03774bdSJohannes Thumshirn pci_release_mem_regions(pci_dev); 116112eb4683SFrank Haverkamp pci_disable_device(pci_dev); 116212eb4683SFrank Haverkamp } 116312eb4683SFrank Haverkamp 116412eb4683SFrank Haverkamp /** 116512eb4683SFrank Haverkamp * genwqe_probe() - Device initialization 116612eb4683SFrank Haverkamp * @pdev: PCI device information struct 116712eb4683SFrank Haverkamp * 116812eb4683SFrank Haverkamp * Callable for multiple cards. This function is called on bind. 116912eb4683SFrank Haverkamp * 117012eb4683SFrank Haverkamp * Return: 0 if succeeded, < 0 when failed 117112eb4683SFrank Haverkamp */ 117212eb4683SFrank Haverkamp static int genwqe_probe(struct pci_dev *pci_dev, 117312eb4683SFrank Haverkamp const struct pci_device_id *id) 117412eb4683SFrank Haverkamp { 117512eb4683SFrank Haverkamp int err; 117612eb4683SFrank Haverkamp struct genwqe_dev *cd; 117712eb4683SFrank Haverkamp 117812eb4683SFrank Haverkamp genwqe_init_crc32(); 117912eb4683SFrank Haverkamp 118012eb4683SFrank Haverkamp cd = genwqe_dev_alloc(); 118112eb4683SFrank Haverkamp if (IS_ERR(cd)) { 118212eb4683SFrank Haverkamp dev_err(&pci_dev->dev, "err: could not alloc mem (err=%d)!\n", 118312eb4683SFrank Haverkamp (int)PTR_ERR(cd)); 118412eb4683SFrank Haverkamp return PTR_ERR(cd); 118512eb4683SFrank Haverkamp } 118612eb4683SFrank Haverkamp 118712eb4683SFrank Haverkamp dev_set_drvdata(&pci_dev->dev, cd); 118812eb4683SFrank Haverkamp cd->pci_dev = pci_dev; 118912eb4683SFrank Haverkamp 119012eb4683SFrank Haverkamp err = genwqe_pci_setup(cd); 119112eb4683SFrank Haverkamp if (err < 0) { 119212eb4683SFrank Haverkamp dev_err(&pci_dev->dev, 119312eb4683SFrank Haverkamp "err: problems with PCI setup (err=%d)\n", err); 119412eb4683SFrank Haverkamp goto out_free_dev; 119512eb4683SFrank Haverkamp } 119612eb4683SFrank Haverkamp 119712eb4683SFrank Haverkamp err = genwqe_start(cd); 119812eb4683SFrank Haverkamp if (err < 0) { 119912eb4683SFrank Haverkamp dev_err(&pci_dev->dev, 120012eb4683SFrank Haverkamp "err: cannot start card services! (err=%d)\n", err); 120112eb4683SFrank Haverkamp goto out_pci_remove; 120212eb4683SFrank Haverkamp } 120312eb4683SFrank Haverkamp 120412eb4683SFrank Haverkamp if (genwqe_is_privileged(cd)) { 120512eb4683SFrank Haverkamp err = genwqe_health_check_start(cd); 120612eb4683SFrank Haverkamp if (err < 0) { 120712eb4683SFrank Haverkamp dev_err(&pci_dev->dev, 1208d9c11d45SFrank Haverkamp "err: cannot start health checking! (err=%d)\n", 1209d9c11d45SFrank Haverkamp err); 121012eb4683SFrank Haverkamp goto out_stop_services; 121112eb4683SFrank Haverkamp } 121212eb4683SFrank Haverkamp } 121312eb4683SFrank Haverkamp return 0; 121412eb4683SFrank Haverkamp 121512eb4683SFrank Haverkamp out_stop_services: 121612eb4683SFrank Haverkamp genwqe_stop(cd); 121712eb4683SFrank Haverkamp out_pci_remove: 121812eb4683SFrank Haverkamp genwqe_pci_remove(cd); 121912eb4683SFrank Haverkamp out_free_dev: 122012eb4683SFrank Haverkamp genwqe_dev_free(cd); 122112eb4683SFrank Haverkamp return err; 122212eb4683SFrank Haverkamp } 122312eb4683SFrank Haverkamp 122412eb4683SFrank Haverkamp /** 122512eb4683SFrank Haverkamp * genwqe_remove() - Called when device is removed (hot-plugable) 122612eb4683SFrank Haverkamp * 122712eb4683SFrank Haverkamp * Or when driver is unloaded respecitively when unbind is done. 122812eb4683SFrank Haverkamp */ 122912eb4683SFrank Haverkamp static void genwqe_remove(struct pci_dev *pci_dev) 123012eb4683SFrank Haverkamp { 123112eb4683SFrank Haverkamp struct genwqe_dev *cd = dev_get_drvdata(&pci_dev->dev); 123212eb4683SFrank Haverkamp 123312eb4683SFrank Haverkamp genwqe_health_check_stop(cd); 123412eb4683SFrank Haverkamp 123512eb4683SFrank Haverkamp /* 123612eb4683SFrank Haverkamp * genwqe_stop() must survive if it is called twice 123712eb4683SFrank Haverkamp * sequentially. This happens when the health thread calls it 123812eb4683SFrank Haverkamp * and fails on genwqe_bus_reset(). 123912eb4683SFrank Haverkamp */ 124012eb4683SFrank Haverkamp genwqe_stop(cd); 124112eb4683SFrank Haverkamp genwqe_pci_remove(cd); 124212eb4683SFrank Haverkamp genwqe_dev_free(cd); 124312eb4683SFrank Haverkamp } 124412eb4683SFrank Haverkamp 124512eb4683SFrank Haverkamp /* 124612eb4683SFrank Haverkamp * genwqe_err_error_detected() - Error detection callback 124712eb4683SFrank Haverkamp * 124812eb4683SFrank Haverkamp * This callback is called by the PCI subsystem whenever a PCI bus 124912eb4683SFrank Haverkamp * error is detected. 125012eb4683SFrank Haverkamp */ 125112eb4683SFrank Haverkamp static pci_ers_result_t genwqe_err_error_detected(struct pci_dev *pci_dev, 125212eb4683SFrank Haverkamp enum pci_channel_state state) 125312eb4683SFrank Haverkamp { 125412eb4683SFrank Haverkamp struct genwqe_dev *cd; 125512eb4683SFrank Haverkamp 125612eb4683SFrank Haverkamp dev_err(&pci_dev->dev, "[%s] state=%d\n", __func__, state); 125712eb4683SFrank Haverkamp 125812eb4683SFrank Haverkamp cd = dev_get_drvdata(&pci_dev->dev); 125912eb4683SFrank Haverkamp if (cd == NULL) 126012eb4683SFrank Haverkamp return PCI_ERS_RESULT_DISCONNECT; 1261fb145456SKleber Sacilotto de Souza 1262fb145456SKleber Sacilotto de Souza /* Stop the card */ 1263fb145456SKleber Sacilotto de Souza genwqe_health_check_stop(cd); 1264fb145456SKleber Sacilotto de Souza genwqe_stop(cd); 1265fb145456SKleber Sacilotto de Souza 1266fb145456SKleber Sacilotto de Souza /* 1267fb145456SKleber Sacilotto de Souza * On permanent failure, the PCI code will call device remove 1268fb145456SKleber Sacilotto de Souza * after the return of this function. 1269fb145456SKleber Sacilotto de Souza * genwqe_stop() can be called twice. 1270fb145456SKleber Sacilotto de Souza */ 1271fb145456SKleber Sacilotto de Souza if (state == pci_channel_io_perm_failure) { 1272fb145456SKleber Sacilotto de Souza return PCI_ERS_RESULT_DISCONNECT; 1273fb145456SKleber Sacilotto de Souza } else { 1274fb145456SKleber Sacilotto de Souza genwqe_pci_remove(cd); 1275fb145456SKleber Sacilotto de Souza return PCI_ERS_RESULT_NEED_RESET; 1276fb145456SKleber Sacilotto de Souza } 127712eb4683SFrank Haverkamp } 127812eb4683SFrank Haverkamp 1279fb145456SKleber Sacilotto de Souza static pci_ers_result_t genwqe_err_slot_reset(struct pci_dev *pci_dev) 1280fb145456SKleber Sacilotto de Souza { 1281fb145456SKleber Sacilotto de Souza int rc; 1282fb145456SKleber Sacilotto de Souza struct genwqe_dev *cd = dev_get_drvdata(&pci_dev->dev); 1283fb145456SKleber Sacilotto de Souza 1284fb145456SKleber Sacilotto de Souza rc = genwqe_pci_setup(cd); 1285fb145456SKleber Sacilotto de Souza if (!rc) { 1286fb145456SKleber Sacilotto de Souza return PCI_ERS_RESULT_RECOVERED; 1287fb145456SKleber Sacilotto de Souza } else { 1288fb145456SKleber Sacilotto de Souza dev_err(&pci_dev->dev, 1289fb145456SKleber Sacilotto de Souza "err: problems with PCI setup (err=%d)\n", rc); 1290fb145456SKleber Sacilotto de Souza return PCI_ERS_RESULT_DISCONNECT; 1291fb145456SKleber Sacilotto de Souza } 129212eb4683SFrank Haverkamp } 129312eb4683SFrank Haverkamp 129412eb4683SFrank Haverkamp static pci_ers_result_t genwqe_err_result_none(struct pci_dev *dev) 129512eb4683SFrank Haverkamp { 129612eb4683SFrank Haverkamp return PCI_ERS_RESULT_NONE; 129712eb4683SFrank Haverkamp } 129812eb4683SFrank Haverkamp 1299fb145456SKleber Sacilotto de Souza static void genwqe_err_resume(struct pci_dev *pci_dev) 130012eb4683SFrank Haverkamp { 1301fb145456SKleber Sacilotto de Souza int rc; 1302fb145456SKleber Sacilotto de Souza struct genwqe_dev *cd = dev_get_drvdata(&pci_dev->dev); 1303fb145456SKleber Sacilotto de Souza 1304fb145456SKleber Sacilotto de Souza rc = genwqe_start(cd); 1305fb145456SKleber Sacilotto de Souza if (!rc) { 1306fb145456SKleber Sacilotto de Souza rc = genwqe_health_check_start(cd); 1307fb145456SKleber Sacilotto de Souza if (rc) 1308fb145456SKleber Sacilotto de Souza dev_err(&pci_dev->dev, 1309fb145456SKleber Sacilotto de Souza "err: cannot start health checking! (err=%d)\n", 1310fb145456SKleber Sacilotto de Souza rc); 1311fb145456SKleber Sacilotto de Souza } else { 1312fb145456SKleber Sacilotto de Souza dev_err(&pci_dev->dev, 1313fb145456SKleber Sacilotto de Souza "err: cannot start card services! (err=%d)\n", rc); 1314fb145456SKleber Sacilotto de Souza } 131512eb4683SFrank Haverkamp } 131612eb4683SFrank Haverkamp 131712eb4683SFrank Haverkamp static int genwqe_sriov_configure(struct pci_dev *dev, int numvfs) 131812eb4683SFrank Haverkamp { 1319bc407dd3SFrank Haverkamp int rc; 132012eb4683SFrank Haverkamp struct genwqe_dev *cd = dev_get_drvdata(&dev->dev); 132112eb4683SFrank Haverkamp 132212eb4683SFrank Haverkamp if (numvfs > 0) { 132312eb4683SFrank Haverkamp genwqe_setup_vf_jtimer(cd); 1324bc407dd3SFrank Haverkamp rc = pci_enable_sriov(dev, numvfs); 1325bc407dd3SFrank Haverkamp if (rc < 0) 1326bc407dd3SFrank Haverkamp return rc; 132712eb4683SFrank Haverkamp return numvfs; 132812eb4683SFrank Haverkamp } 132912eb4683SFrank Haverkamp if (numvfs == 0) { 133012eb4683SFrank Haverkamp pci_disable_sriov(dev); 133112eb4683SFrank Haverkamp return 0; 133212eb4683SFrank Haverkamp } 133312eb4683SFrank Haverkamp return 0; 133412eb4683SFrank Haverkamp } 133512eb4683SFrank Haverkamp 133612eb4683SFrank Haverkamp static struct pci_error_handlers genwqe_err_handler = { 133712eb4683SFrank Haverkamp .error_detected = genwqe_err_error_detected, 133812eb4683SFrank Haverkamp .mmio_enabled = genwqe_err_result_none, 133912eb4683SFrank Haverkamp .link_reset = genwqe_err_result_none, 1340fb145456SKleber Sacilotto de Souza .slot_reset = genwqe_err_slot_reset, 134112eb4683SFrank Haverkamp .resume = genwqe_err_resume, 134212eb4683SFrank Haverkamp }; 134312eb4683SFrank Haverkamp 134412eb4683SFrank Haverkamp static struct pci_driver genwqe_driver = { 134512eb4683SFrank Haverkamp .name = genwqe_driver_name, 134612eb4683SFrank Haverkamp .id_table = genwqe_device_table, 134712eb4683SFrank Haverkamp .probe = genwqe_probe, 134812eb4683SFrank Haverkamp .remove = genwqe_remove, 134912eb4683SFrank Haverkamp .sriov_configure = genwqe_sriov_configure, 135012eb4683SFrank Haverkamp .err_handler = &genwqe_err_handler, 135112eb4683SFrank Haverkamp }; 135212eb4683SFrank Haverkamp 135312eb4683SFrank Haverkamp /** 1354*5ed22cebSFrank Haverkamp * genwqe_devnode() - Set default access mode for genwqe devices. 1355*5ed22cebSFrank Haverkamp * 1356*5ed22cebSFrank Haverkamp * Default mode should be rw for everybody. Do not change default 1357*5ed22cebSFrank Haverkamp * device name. 1358*5ed22cebSFrank Haverkamp */ 1359*5ed22cebSFrank Haverkamp static char *genwqe_devnode(struct device *dev, umode_t *mode) 1360*5ed22cebSFrank Haverkamp { 1361*5ed22cebSFrank Haverkamp if (mode) 1362*5ed22cebSFrank Haverkamp *mode = 0666; 1363*5ed22cebSFrank Haverkamp return NULL; 1364*5ed22cebSFrank Haverkamp } 1365*5ed22cebSFrank Haverkamp 1366*5ed22cebSFrank Haverkamp /** 136712eb4683SFrank Haverkamp * genwqe_init_module() - Driver registration and initialization 136812eb4683SFrank Haverkamp */ 136912eb4683SFrank Haverkamp static int __init genwqe_init_module(void) 137012eb4683SFrank Haverkamp { 137112eb4683SFrank Haverkamp int rc; 137212eb4683SFrank Haverkamp 137312eb4683SFrank Haverkamp class_genwqe = class_create(THIS_MODULE, GENWQE_DEVNAME); 137412eb4683SFrank Haverkamp if (IS_ERR(class_genwqe)) { 137512eb4683SFrank Haverkamp pr_err("[%s] create class failed\n", __func__); 137612eb4683SFrank Haverkamp return -ENOMEM; 137712eb4683SFrank Haverkamp } 137812eb4683SFrank Haverkamp 1379*5ed22cebSFrank Haverkamp class_genwqe->devnode = genwqe_devnode; 1380*5ed22cebSFrank Haverkamp 138112eb4683SFrank Haverkamp debugfs_genwqe = debugfs_create_dir(GENWQE_DEVNAME, NULL); 138212eb4683SFrank Haverkamp if (!debugfs_genwqe) { 138312eb4683SFrank Haverkamp rc = -ENOMEM; 138412eb4683SFrank Haverkamp goto err_out; 138512eb4683SFrank Haverkamp } 138612eb4683SFrank Haverkamp 138712eb4683SFrank Haverkamp rc = pci_register_driver(&genwqe_driver); 138812eb4683SFrank Haverkamp if (rc != 0) { 138912eb4683SFrank Haverkamp pr_err("[%s] pci_reg_driver (rc=%d)\n", __func__, rc); 139012eb4683SFrank Haverkamp goto err_out0; 139112eb4683SFrank Haverkamp } 139212eb4683SFrank Haverkamp 139312eb4683SFrank Haverkamp return rc; 139412eb4683SFrank Haverkamp 139512eb4683SFrank Haverkamp err_out0: 139612eb4683SFrank Haverkamp debugfs_remove(debugfs_genwqe); 139712eb4683SFrank Haverkamp err_out: 139812eb4683SFrank Haverkamp class_destroy(class_genwqe); 139912eb4683SFrank Haverkamp return rc; 140012eb4683SFrank Haverkamp } 140112eb4683SFrank Haverkamp 140212eb4683SFrank Haverkamp /** 140312eb4683SFrank Haverkamp * genwqe_exit_module() - Driver exit 140412eb4683SFrank Haverkamp */ 140512eb4683SFrank Haverkamp static void __exit genwqe_exit_module(void) 140612eb4683SFrank Haverkamp { 140712eb4683SFrank Haverkamp pci_unregister_driver(&genwqe_driver); 140812eb4683SFrank Haverkamp debugfs_remove(debugfs_genwqe); 140912eb4683SFrank Haverkamp class_destroy(class_genwqe); 141012eb4683SFrank Haverkamp } 141112eb4683SFrank Haverkamp 141212eb4683SFrank Haverkamp module_init(genwqe_init_module); 141312eb4683SFrank Haverkamp module_exit(genwqe_exit_module); 1414