int pci_enable_pcie_error_reporting(struct pci_dev *dev) { if (pcie_aer_get_firmware_first(dev)) return -EIO; if (!dev->aer_cap) return -EIO; return pcie_capability_set_word(dev, PCI_EXP_DEVCTL, PCI_EXP_AER_FLAGS); }
int pci_enable_pcie_error_reporting(struct pci_dev *dev) { if (pcie_aer_get_firmware_first(dev)) return -EIO; if (!pci_find_ext_capability(dev, PCI_EXT_CAP_ID_ERR)) return -EIO; return pcie_capability_set_word(dev, PCI_EXP_DEVCTL, PCI_EXP_AER_FLAGS); }
/** * octeon_mbox_process_cmd: * @mbox: Pointer mailbox * @mbox_cmd: Pointer to command received * * Process the cmd received in mbox */ static int octeon_mbox_process_cmd(struct octeon_mbox *mbox, struct octeon_mbox_cmd *mbox_cmd) { struct octeon_device *oct = mbox->oct_dev; switch (mbox_cmd->msg.s.cmd) { case OCTEON_VF_ACTIVE: dev_dbg(&oct->pci_dev->dev, "got vfactive sending data back\n"); mbox_cmd->msg.s.type = OCTEON_MBOX_RESPONSE; mbox_cmd->msg.s.resp_needed = 1; mbox_cmd->msg.s.len = 2; mbox_cmd->data[0] = 0; /* VF version is in mbox_cmd->data[0] */ ((struct lio_version *)&mbox_cmd->data[0])->major = LIQUIDIO_BASE_MAJOR_VERSION; ((struct lio_version *)&mbox_cmd->data[0])->minor = LIQUIDIO_BASE_MINOR_VERSION; ((struct lio_version *)&mbox_cmd->data[0])->micro = LIQUIDIO_BASE_MICRO_VERSION; memcpy(mbox_cmd->msg.s.params, (uint8_t *)&oct->pfvf_hsword, 6); /* Sending core cofig info to the corresponding active VF.*/ octeon_mbox_write(oct, mbox_cmd); break; case OCTEON_VF_FLR_REQUEST: dev_info(&oct->pci_dev->dev, "got a request for FLR from VF that owns DPI ring %u\n", mbox->q_no); pcie_capability_set_word( oct->sriov_info.dpiring_to_vfpcidev_lut[mbox->q_no], PCI_EXP_DEVCTL, PCI_EXP_DEVCTL_BCR_FLR); break; case OCTEON_PF_CHANGED_VF_MACADDR: if (OCTEON_CN23XX_VF(oct)) octeon_pf_changed_vf_macaddr(oct, mbox_cmd->msg.s.params); break; case OCTEON_GET_VF_STATS: dev_dbg(&oct->pci_dev->dev, "Got VF stats request. Sending data back\n"); mbox_cmd->msg.s.type = OCTEON_MBOX_RESPONSE; mbox_cmd->msg.s.resp_needed = 1; mbox_cmd->msg.s.len = 1 + sizeof(struct oct_vf_stats) / sizeof(u64); get_vf_stats(oct, (struct oct_vf_stats *)mbox_cmd->data); octeon_mbox_write(oct, mbox_cmd); break; default: break; } return 0; }
/* * Called to perform platform specific PCI setup */ int pcibios_plat_dev_init(struct pci_dev *dev) { uint16_t config; uint32_t dconfig; int pos; /* * Force the Cache line setting to 64 bytes. The standard * Linux bus scan doesn't seem to set it. Octeon really has * 128 byte lines, but Intel bridges get really upset if you * try and set values above 64 bytes. Value is specified in * 32bit words. */ pci_write_config_byte(dev, PCI_CACHE_LINE_SIZE, 64 / 4); /* Set latency timers for all devices */ pci_write_config_byte(dev, PCI_LATENCY_TIMER, 64); /* Enable reporting System errors and parity errors on all devices */ /* Enable parity checking and error reporting */ pci_read_config_word(dev, PCI_COMMAND, &config); config |= PCI_COMMAND_PARITY | PCI_COMMAND_SERR; pci_write_config_word(dev, PCI_COMMAND, config); if (dev->subordinate) { /* Set latency timers on sub bridges */ pci_write_config_byte(dev, PCI_SEC_LATENCY_TIMER, 64); /* More bridge error detection */ pci_read_config_word(dev, PCI_BRIDGE_CONTROL, &config); config |= PCI_BRIDGE_CTL_PARITY | PCI_BRIDGE_CTL_SERR; pci_write_config_word(dev, PCI_BRIDGE_CONTROL, config); } /* Enable the PCIe normal error reporting */ config = PCI_EXP_DEVCTL_CERE; /* Correctable Error Reporting */ config |= PCI_EXP_DEVCTL_NFERE; /* Non-Fatal Error Reporting */ config |= PCI_EXP_DEVCTL_FERE; /* Fatal Error Reporting */ config |= PCI_EXP_DEVCTL_URRE; /* Unsupported Request */ pcie_capability_set_word(dev, PCI_EXP_DEVCTL, config); /* Find the Advanced Error Reporting capability */ pos = pci_find_ext_capability(dev, PCI_EXT_CAP_ID_ERR); if (pos) { /* Clear Uncorrectable Error Status */ pci_read_config_dword(dev, pos + PCI_ERR_UNCOR_STATUS, &dconfig); pci_write_config_dword(dev, pos + PCI_ERR_UNCOR_STATUS, dconfig); /* Enable reporting of all uncorrectable errors */ /* Uncorrectable Error Mask - turned on bits disable errors */ pci_write_config_dword(dev, pos + PCI_ERR_UNCOR_MASK, 0); /* * Leave severity at HW default. This only controls if * errors are reported as uncorrectable or * correctable, not if the error is reported. */ /* PCI_ERR_UNCOR_SEVER - Uncorrectable Error Severity */ /* Clear Correctable Error Status */ pci_read_config_dword(dev, pos + PCI_ERR_COR_STATUS, &dconfig); pci_write_config_dword(dev, pos + PCI_ERR_COR_STATUS, dconfig); /* Enable reporting of all correctable errors */ /* Correctable Error Mask - turned on bits disable errors */ pci_write_config_dword(dev, pos + PCI_ERR_COR_MASK, 0); /* Advanced Error Capabilities */ pci_read_config_dword(dev, pos + PCI_ERR_CAP, &dconfig); /* ECRC Generation Enable */ if (config & PCI_ERR_CAP_ECRC_GENC) config |= PCI_ERR_CAP_ECRC_GENE; /* ECRC Check Enable */ if (config & PCI_ERR_CAP_ECRC_CHKC) config |= PCI_ERR_CAP_ECRC_CHKE; pci_write_config_dword(dev, pos + PCI_ERR_CAP, dconfig); /* PCI_ERR_HEADER_LOG - Header Log Register (16 bytes) */ /* Report all errors to the root complex */ pci_write_config_dword(dev, pos + PCI_ERR_ROOT_COMMAND, PCI_ERR_ROOT_CMD_COR_EN | PCI_ERR_ROOT_CMD_NONFATAL_EN | PCI_ERR_ROOT_CMD_FATAL_EN); /* Clear the Root status register */ pci_read_config_dword(dev, pos + PCI_ERR_ROOT_STATUS, &dconfig); pci_write_config_dword(dev, pos + PCI_ERR_ROOT_STATUS, dconfig); } dev->dev.archdata.dma_ops = octeon_pci_dma_map_ops; return 0; }