/* Need to be called after we discover btcoex capabilities */ static void ath_pci_aspm_init(struct ath_common *common) { struct ath_softc *sc = (struct ath_softc *) common->priv; struct ath_hw *ah = sc->sc_ah; struct pci_dev *pdev = to_pci_dev(sc->dev); struct pci_dev *parent; int pos; u8 aspm; if (!ah->is_pciexpress) return; pos = pci_pcie_cap(pdev); if (!pos) return; parent = pdev->bus->self; if (!parent) return; if ((ath9k_hw_get_btcoex_scheme(ah) != ATH_BTCOEX_CFG_NONE) && (AR_SREV_9285(ah))) { /* Bluetooth coexistance requires disabling ASPM for AR9285. */ pci_read_config_byte(pdev, pos + PCI_EXP_LNKCTL, &aspm); aspm &= ~(PCIE_LINK_STATE_L0S | PCIE_LINK_STATE_L1); pci_write_config_byte(pdev, pos + PCI_EXP_LNKCTL, aspm); /* * Both upstream and downstream PCIe components should * have the same ASPM settings. */ pos = pci_pcie_cap(parent); pci_read_config_byte(parent, pos + PCI_EXP_LNKCTL, &aspm); aspm &= ~(PCIE_LINK_STATE_L0S | PCIE_LINK_STATE_L1); pci_write_config_byte(parent, pos + PCI_EXP_LNKCTL, aspm); ath_info(common, "Disabling ASPM since BTCOEX is enabled\n"); return; } pos = pci_pcie_cap(parent); pci_read_config_byte(parent, pos + PCI_EXP_LNKCTL, &aspm); if (aspm & (PCIE_LINK_STATE_L0S | PCIE_LINK_STATE_L1)) { ah->aspm_enabled = true; /* Initialize PCIe PM and SERDES registers. */ ath9k_hw_configpcipowersave(ah, false); ath_info(common, "ASPM enabled: 0x%x\n", aspm); } }
void pciehp_set_attention_status(struct slot *slot, u8 value) { struct controller *ctrl = slot->ctrl; u16 slot_cmd; if (!ATTN_LED(ctrl)) return; switch (value) { case 0: /* turn off */ slot_cmd = PCI_EXP_SLTCTL_ATTN_IND_OFF; break; case 1: /* turn on */ slot_cmd = PCI_EXP_SLTCTL_ATTN_IND_ON; break; case 2: /* turn blink */ slot_cmd = PCI_EXP_SLTCTL_ATTN_IND_BLINK; break; default: return; } ctrl_dbg(ctrl, "%s: SLOTCTRL %x write cmd %x\n", __func__, pci_pcie_cap(ctrl->pcie->port) + PCI_EXP_SLTCTL, slot_cmd); pcie_write_cmd(ctrl, slot_cmd, PCI_EXP_SLTCTL_AIC); }
int pciehp_power_on_slot(struct slot *slot) { struct controller *ctrl = slot->ctrl; struct pci_dev *pdev = ctrl_dev(ctrl); u16 slot_status; int retval; /* Clear sticky power-fault bit from previous power failures */ pcie_capability_read_word(pdev, PCI_EXP_SLTSTA, &slot_status); if (slot_status & PCI_EXP_SLTSTA_PFD) pcie_capability_write_word(pdev, PCI_EXP_SLTSTA, PCI_EXP_SLTSTA_PFD); ctrl->power_fault_detected = 0; pcie_write_cmd(ctrl, PCI_EXP_SLTCTL_PWR_ON, PCI_EXP_SLTCTL_PCC); ctrl_dbg(ctrl, "%s: SLOTCTRL %x write cmd %x\n", __func__, pci_pcie_cap(ctrl->pcie->port) + PCI_EXP_SLTCTL, PCI_EXP_SLTCTL_PWR_ON); retval = pciehp_link_enable(ctrl); if (retval) ctrl_err(ctrl, "%s: Can not enable the link!\n", __func__); return retval; }
void pciehp_get_attention_status(struct slot *slot, u8 *status) { struct controller *ctrl = slot->ctrl; struct pci_dev *pdev = ctrl_dev(ctrl); u16 slot_ctrl; pcie_capability_read_word(pdev, PCI_EXP_SLTCTL, &slot_ctrl); ctrl_dbg(ctrl, "%s: SLOTCTRL %x, value read %x\n", __func__, pci_pcie_cap(ctrl->pcie->port) + PCI_EXP_SLTCTL, slot_ctrl); switch (slot_ctrl & PCI_EXP_SLTCTL_AIC) { case PCI_EXP_SLTCTL_ATTN_IND_ON: *status = 1; /* On */ break; case PCI_EXP_SLTCTL_ATTN_IND_BLINK: *status = 2; /* Blink */ break; case PCI_EXP_SLTCTL_ATTN_IND_OFF: *status = 0; /* Off */ break; default: *status = 0xFF; break; } }
int pci_enable_pcie_error_reporting(struct pci_dev *dev) { u16 reg16 = 0; int pos; if (pcie_aer_get_firmware_first(dev)) return -EIO; pos = pci_find_ext_capability(dev, PCI_EXT_CAP_ID_ERR); if (!pos) return -EIO; pos = pci_pcie_cap(dev); if (!pos) return -EIO; pci_read_config_word(dev, pos + PCI_EXP_DEVCTL, ®16); reg16 |= (PCI_EXP_DEVCTL_CERE | PCI_EXP_DEVCTL_NFERE | PCI_EXP_DEVCTL_FERE | PCI_EXP_DEVCTL_URRE); pci_write_config_word(dev, pos + PCI_EXP_DEVCTL, reg16); return 0; }
/* * test_read_pci_exp_config * make call to pci_config_read and determine if * the PCI-Express enhanced config space of this * device can be read successfully. */ static int test_read_pci_exp_config(void) { int pos; u32 header; struct pci_dev *dev = ltp_pci.dev; /* skip the test if device doesn't have PCIe capability */ pos = pci_pcie_cap(dev); if (!pos) { prk_info("device doesn't have PCI-EXP capability"); return TSKIP; } prk_info("read the PCI Express configuration registers at 0x%x", pos); if (pci_read_config_dword(dev, pos, &header)) { prk_err("failed to read config dword"); return TFAIL; } /* comparing the value read with PCI_CAP_ID_EXP macro */ if ((header & 0x000000ff) == PCI_CAP_ID_EXP) { prk_info("correct val read using PCIE driver installed: 0x%x", header); return TPASS; } prk_err("incorrect val read. PCIE driver/device not installed: 0x%x", header); return TFAIL; }
int pcie_capability_read_word(struct pci_dev *dev, int pos, u16 *val) { int ret; *val = 0; if (pos & 1) return -EINVAL; if (pcie_capability_reg_implemented(dev, pos)) { ret = pci_read_config_word(dev, pci_pcie_cap(dev) + pos, val); /* * Reset *val to 0 if pci_read_config_word() fails, it may * have been written as 0xFFFF if hardware error happens * during pci_read_config_word(). */ if (ret) *val = 0; return ret; } /* * For Functions that do not implement the Slot Capabilities, * Slot Status, and Slot Control registers, these spaces must * be hardwired to 0b, with the exception of the Presence Detect * State bit in the Slot Status register of Downstream Ports, * which must be hardwired to 1b. (PCIe Base Spec 3.0, sec 7.8) */ if (pci_is_pcie(dev) && pos == PCI_EXP_SLTSTA && pci_pcie_type(dev) == PCI_EXP_TYPE_DOWNSTREAM) { *val = PCI_EXP_SLTSTA_PDS; } return 0; }
int pcie_capability_read_dword(struct pci_dev *dev, int pos, u32 *val) { int ret; *val = 0; if (pos & 3) return -EINVAL; if (pcie_capability_reg_implemented(dev, pos)) { ret = pci_read_config_dword(dev, pci_pcie_cap(dev) + pos, val); /* * Reset *val to 0 if pci_read_config_dword() fails, it may * have been written as 0xFFFFFFFF if hardware error happens * during pci_read_config_dword(). */ if (ret) *val = 0; return ret; } if (pci_is_pcie(dev) && pos == PCI_EXP_SLTCTL && pci_pcie_type(dev) == PCI_EXP_TYPE_DOWNSTREAM) { *val = PCI_EXP_SLTSTA_PDS; } return 0; }
int pciehp_get_power_status(struct slot *slot, u8 *status) { struct controller *ctrl = slot->ctrl; u16 slot_ctrl; u8 pwr_state; int retval = 0; retval = pciehp_readw(ctrl, PCI_EXP_SLTCTL, &slot_ctrl); if (retval) { ctrl_err(ctrl, "%s: Cannot read SLOTCTRL register\n", __func__); return retval; } ctrl_dbg(ctrl, "%s: SLOTCTRL %x value read %x\n", __func__, pci_pcie_cap(ctrl->pcie->port) + PCI_EXP_SLTCTL, slot_ctrl); pwr_state = (slot_ctrl & PCI_EXP_SLTCTL_PCC) >> 10; switch (pwr_state) { case 0: *status = 1; break; case 1: *status = 0; break; default: *status = 0xFF; break; } return retval; }
static void aer_enable_rootport(struct aer_rpc *rpc) { struct pci_dev *pdev = rpc->rpd->port; int pos, aer_pos; u16 reg16; u32 reg32; pos = pci_pcie_cap(pdev); pci_read_config_word(pdev, pos+PCI_EXP_DEVSTA, ®16); pci_write_config_word(pdev, pos+PCI_EXP_DEVSTA, reg16); pci_read_config_word(pdev, pos + PCI_EXP_RTCTL, ®16); reg16 &= ~(SYSTEM_ERROR_INTR_ON_MESG_MASK); pci_write_config_word(pdev, pos + PCI_EXP_RTCTL, reg16); aer_pos = pci_find_ext_capability(pdev, PCI_EXT_CAP_ID_ERR); pci_read_config_dword(pdev, aer_pos + PCI_ERR_ROOT_STATUS, ®32); pci_write_config_dword(pdev, aer_pos + PCI_ERR_ROOT_STATUS, reg32); pci_read_config_dword(pdev, aer_pos + PCI_ERR_COR_STATUS, ®32); pci_write_config_dword(pdev, aer_pos + PCI_ERR_COR_STATUS, reg32); pci_read_config_dword(pdev, aer_pos + PCI_ERR_UNCOR_STATUS, ®32); pci_write_config_dword(pdev, aer_pos + PCI_ERR_UNCOR_STATUS, reg32); set_downstream_devices_error_reporting(pdev, true); pci_read_config_dword(pdev, aer_pos + PCI_ERR_ROOT_COMMAND, ®32); reg32 |= ROOT_PORT_INTR_ON_MESG_MASK; pci_write_config_dword(pdev, aer_pos + PCI_ERR_ROOT_COMMAND, reg32); }
int pciehp_power_off_slot(struct slot * slot) { struct controller *ctrl = slot->ctrl; u16 slot_cmd; u16 cmd_mask; int retval; /* Disable the link at first */ pciehp_link_disable(ctrl); /* wait the link is down */ if (ctrl->link_active_reporting) pcie_wait_link_not_active(ctrl); else msleep(1000); slot_cmd = POWER_OFF; cmd_mask = PCI_EXP_SLTCTL_PCC; retval = pcie_write_cmd(ctrl, slot_cmd, cmd_mask); if (retval) { ctrl_err(ctrl, "Write command failed!\n"); return retval; } ctrl_dbg(ctrl, "%s: SLOTCTRL %x write cmd %x\n", __func__, pci_pcie_cap(ctrl->pcie->port) + PCI_EXP_SLTCTL, slot_cmd); return 0; }
/** * is_error_source - check whether the device is source of reported error * @dev: pointer to pci_dev to be checked * @e_info: pointer to reported error info */ static bool is_error_source(struct pci_dev *dev, struct aer_err_info *e_info) { int pos; u32 status, mask; u16 reg16; /* * When bus id is equal to 0, it might be a bad id * reported by root port. */ if (!nosourceid && (PCI_BUS(e_info->id) != 0)) { /* Device ID match? */ if (e_info->id == ((dev->bus->number << 8) | dev->devfn)) return true; /* Continue id comparing if there is no multiple error */ if (!e_info->multi_error_valid) return false; } /* * When either * 1) nosourceid==y; * 2) bus id is equal to 0. Some ports might lose the bus * id of error source id; * 3) There are multiple errors and prior id comparing fails; * We check AER status registers to find possible reporter. */ if (atomic_read(&dev->enable_cnt) == 0) return false; pos = pci_pcie_cap(dev); if (!pos) return false; /* Check if AER is enabled */ pci_read_config_word(dev, pos + PCI_EXP_DEVCTL, ®16); if (!(reg16 & ( PCI_EXP_DEVCTL_CERE | PCI_EXP_DEVCTL_NFERE | PCI_EXP_DEVCTL_FERE | PCI_EXP_DEVCTL_URRE))) return false; pos = pci_find_ext_capability(dev, PCI_EXT_CAP_ID_ERR); if (!pos) return false; /* Check if error is recorded */ if (e_info->severity == AER_CORRECTABLE) { pci_read_config_dword(dev, pos + PCI_ERR_COR_STATUS, &status); pci_read_config_dword(dev, pos + PCI_ERR_COR_MASK, &mask); } else { pci_read_config_dword(dev, pos + PCI_ERR_UNCOR_STATUS, &status); pci_read_config_dword(dev, pos + PCI_ERR_UNCOR_MASK, &mask); } if (status & ~mask) return true; return false; }
void pciehp_power_off_slot(struct slot *slot) { struct controller *ctrl = slot->ctrl; pcie_write_cmd(ctrl, PCI_EXP_SLTCTL_PWR_OFF, PCI_EXP_SLTCTL_PCC); ctrl_dbg(ctrl, "%s: SLOTCTRL %x write cmd %x\n", __func__, pci_pcie_cap(ctrl->pcie->port) + PCI_EXP_SLTCTL, PCI_EXP_SLTCTL_PWR_OFF); }
static u16 iwl_pciexp_link_ctrl(struct iwl_bus *bus) { int pos; u16 pci_lnk_ctl; struct pci_dev *pci_dev = IWL_BUS_GET_PCI_DEV(bus); pos = pci_pcie_cap(pci_dev); pci_read_config_word(pci_dev, pos + PCI_EXP_LNKCTL, &pci_lnk_ctl); return pci_lnk_ctl; }
int pcie_capability_write_dword(struct pci_dev *dev, int pos, u32 val) { if (pos & 3) return -EINVAL; if (!pcie_capability_reg_implemented(dev, pos)) return 0; return pci_write_config_dword(dev, pci_pcie_cap(dev) + pos, val); }
/** * pcie_clear_root_pme_status - Clear root port PME interrupt status. * @dev: PCIe root port or event collector. */ void pcie_clear_root_pme_status(struct pci_dev *dev) { int rtsta_pos; u32 rtsta; rtsta_pos = pci_pcie_cap(dev) + PCI_EXP_RTSTA; pci_read_config_dword(dev, rtsta_pos, &rtsta); rtsta |= PCI_EXP_RTSTA_PME; pci_write_config_dword(dev, rtsta_pos, rtsta); }
void pciehp_green_led_blink(struct slot *slot) { struct controller *ctrl = slot->ctrl; u16 slot_cmd; u16 cmd_mask; slot_cmd = 0x0200; cmd_mask = PCI_EXP_SLTCTL_PIC; pcie_write_cmd(ctrl, slot_cmd, cmd_mask); ctrl_dbg(ctrl, "%s: SLOTCTRL %x write cmd %x\n", __func__, pci_pcie_cap(ctrl->pcie->port) + PCI_EXP_SLTCTL, slot_cmd); }
void pciehp_green_led_blink(struct slot *slot) { struct controller *ctrl = slot->ctrl; if (!PWR_LED(ctrl)) return; pcie_write_cmd(ctrl, PCI_EXP_SLTCTL_PWR_IND_BLINK, PCI_EXP_SLTCTL_PIC); ctrl_dbg(ctrl, "%s: SLOTCTRL %x write cmd %x\n", __func__, pci_pcie_cap(ctrl->pcie->port) + PCI_EXP_SLTCTL, PCI_EXP_SLTCTL_PWR_IND_BLINK); }
static inline void dbg_ctrl(struct controller *ctrl) { int i; u16 reg16; struct pci_dev *pdev = ctrl->pcie->port; if (!pciehp_debug) return; ctrl_info(ctrl, "Hotplug Controller:\n"); ctrl_info(ctrl, " Seg/Bus/Dev/Func/IRQ : %s IRQ %d\n", pci_name(pdev), pdev->irq); ctrl_info(ctrl, " Vendor ID : 0x%04x\n", pdev->vendor); ctrl_info(ctrl, " Device ID : 0x%04x\n", pdev->device); ctrl_info(ctrl, " Subsystem ID : 0x%04x\n", pdev->subsystem_device); ctrl_info(ctrl, " Subsystem Vendor ID : 0x%04x\n", pdev->subsystem_vendor); ctrl_info(ctrl, " PCIe Cap offset : 0x%02x\n", pci_pcie_cap(pdev)); for (i = 0; i < DEVICE_COUNT_RESOURCE; i++) { if (!pci_resource_len(pdev, i)) continue; ctrl_info(ctrl, " PCI resource [%d] : %pR\n", i, &pdev->resource[i]); } ctrl_info(ctrl, "Slot Capabilities : 0x%08x\n", ctrl->slot_cap); ctrl_info(ctrl, " Physical Slot Number : %d\n", PSN(ctrl)); ctrl_info(ctrl, " Attention Button : %3s\n", ATTN_BUTTN(ctrl) ? "yes" : "no"); ctrl_info(ctrl, " Power Controller : %3s\n", POWER_CTRL(ctrl) ? "yes" : "no"); ctrl_info(ctrl, " MRL Sensor : %3s\n", MRL_SENS(ctrl) ? "yes" : "no"); ctrl_info(ctrl, " Attention Indicator : %3s\n", ATTN_LED(ctrl) ? "yes" : "no"); ctrl_info(ctrl, " Power Indicator : %3s\n", PWR_LED(ctrl) ? "yes" : "no"); ctrl_info(ctrl, " Hot-Plug Surprise : %3s\n", HP_SUPR_RM(ctrl) ? "yes" : "no"); ctrl_info(ctrl, " EMI Present : %3s\n", EMI(ctrl) ? "yes" : "no"); ctrl_info(ctrl, " Command Completed : %3s\n", NO_CMD_CMPL(ctrl) ? "no" : "yes"); pciehp_readw(ctrl, PCI_EXP_SLTSTA, ®16); ctrl_info(ctrl, "Slot Status : 0x%04x\n", reg16); pciehp_readw(ctrl, PCI_EXP_SLTCTL, ®16); ctrl_info(ctrl, "Slot Control : 0x%04x\n", reg16); }
int pciehp_power_on_slot(struct slot * slot) { struct controller *ctrl = slot->ctrl; u16 slot_cmd; u16 cmd_mask; u16 slot_status; u16 lnk_status; int retval = 0; /* Clear sticky power-fault bit from previous power failures */ retval = pciehp_readw(ctrl, PCI_EXP_SLTSTA, &slot_status); if (retval) { ctrl_err(ctrl, "%s: Cannot read SLOTSTATUS register\n", __func__); return retval; } slot_status &= PCI_EXP_SLTSTA_PFD; if (slot_status) { retval = pciehp_writew(ctrl, PCI_EXP_SLTSTA, slot_status); if (retval) { ctrl_err(ctrl, "%s: Cannot write to SLOTSTATUS register\n", __func__); return retval; } } ctrl->power_fault_detected = 0; slot_cmd = POWER_ON; cmd_mask = PCI_EXP_SLTCTL_PCC; retval = pcie_write_cmd(ctrl, slot_cmd, cmd_mask); if (retval) { ctrl_err(ctrl, "Write %x command failed!\n", slot_cmd); return retval; } ctrl_dbg(ctrl, "%s: SLOTCTRL %x write cmd %x\n", __func__, pci_pcie_cap(ctrl->pcie->port) + PCI_EXP_SLTCTL, slot_cmd); retval = pciehp_readw(ctrl, PCI_EXP_LNKSTA, &lnk_status); if (retval) { ctrl_err(ctrl, "%s: Cannot read LNKSTA register\n", __func__); return retval; } pcie_update_link_speed(ctrl->pcie->port->subordinate, lnk_status); return retval; }
int pciehp_power_off_slot(struct slot * slot) { struct controller *ctrl = slot->ctrl; u16 slot_cmd; u16 cmd_mask; int retval; slot_cmd = POWER_OFF; cmd_mask = PCI_EXP_SLTCTL_PCC; retval = pcie_write_cmd(ctrl, slot_cmd, cmd_mask); if (retval) { ctrl_err(ctrl, "Write command failed!\n"); return retval; } ctrl_dbg(ctrl, "%s: SLOTCTRL %x write cmd %x\n", __func__, pci_pcie_cap(ctrl->pcie->port) + PCI_EXP_SLTCTL, slot_cmd); return 0; }
static void aer_error_resume(struct pci_dev *dev) { int pos; u32 status, mask; u16 reg16; pos = pci_pcie_cap(dev); pci_read_config_word(dev, pos + PCI_EXP_DEVSTA, ®16); pci_write_config_word(dev, pos + PCI_EXP_DEVSTA, reg16); pos = pci_find_ext_capability(dev, PCI_EXT_CAP_ID_ERR); pci_read_config_dword(dev, pos + PCI_ERR_UNCOR_STATUS, &status); pci_read_config_dword(dev, pos + PCI_ERR_UNCOR_SEVER, &mask); if (dev->error_state == pci_channel_io_normal) status &= ~mask; else status &= mask; pci_write_config_dword(dev, pos + PCI_ERR_UNCOR_STATUS, status); }
/** * aer_error_resume - clean up corresponding error status bits * @dev: pointer to Root Port's pci_dev data structure * * Invoked by Port Bus driver during nonfatal recovery. **/ static void aer_error_resume(struct pci_dev *dev) { int pos; u32 status, mask; u16 reg16; /* Clean up Root device status */ pos = pci_pcie_cap(dev); pci_read_config_word(dev, pos + PCI_EXP_DEVSTA, ®16); pci_write_config_word(dev, pos + PCI_EXP_DEVSTA, reg16); /* Clean AER Root Error Status */ pos = pci_find_ext_capability(dev, PCI_EXT_CAP_ID_ERR); pci_read_config_dword(dev, pos + PCI_ERR_UNCOR_STATUS, &status); pci_read_config_dword(dev, pos + PCI_ERR_UNCOR_SEVER, &mask); if (dev->error_state == pci_channel_io_normal) status &= ~mask; /* Clear corresponding nonfatal bits */ else status &= mask; /* Clear corresponding fatal bits */ pci_write_config_dword(dev, pos + PCI_ERR_UNCOR_STATUS, status); }
int pci_disable_pcie_error_reporting(struct pci_dev *dev) { u16 reg16 = 0; int pos; if (pcie_aer_get_firmware_first(dev)) return -EIO; pos = pci_pcie_cap(dev); if (!pos) return -EIO; pci_read_config_word(dev, pos + PCI_EXP_DEVCTL, ®16); reg16 &= ~(PCI_EXP_DEVCTL_CERE | PCI_EXP_DEVCTL_NFERE | PCI_EXP_DEVCTL_FERE | PCI_EXP_DEVCTL_URRE); pci_write_config_word(dev, pos + PCI_EXP_DEVCTL, reg16); return 0; }
int pciehp_get_attention_status(struct slot *slot, u8 *status) { struct controller *ctrl = slot->ctrl; u16 slot_ctrl; u8 atten_led_state; int retval = 0; retval = pciehp_readw(ctrl, PCI_EXP_SLTCTL, &slot_ctrl); if (retval) { ctrl_err(ctrl, "%s: Cannot read SLOTCTRL register\n", __func__); return retval; } ctrl_dbg(ctrl, "%s: SLOTCTRL %x, value read %x\n", __func__, pci_pcie_cap(ctrl->pcie->port) + PCI_EXP_SLTCTL, slot_ctrl); atten_led_state = (slot_ctrl & PCI_EXP_SLTCTL_AIC) >> 6; switch (atten_led_state) { case 0: *status = 0xFF; /* Reserved */ break; case 1: *status = 1; /* On */ break; case 2: *status = 2; /* Blink */ break; case 3: *status = 0; /* Off */ break; default: *status = 0xFF; break; } return 0; }
static void aer_enable_rootport(struct aer_rpc *rpc) { struct pci_dev *pdev = rpc->rpd->port; int pos, aer_pos; u16 reg16; u32 reg32; pos = pci_pcie_cap(pdev); /* Clear PCIe Capability's Device Status */ pci_read_config_word(pdev, pos+PCI_EXP_DEVSTA, ®16); pci_write_config_word(pdev, pos+PCI_EXP_DEVSTA, reg16); /* Disable system error generation in response to error messages */ pci_read_config_word(pdev, pos + PCI_EXP_RTCTL, ®16); reg16 &= ~(SYSTEM_ERROR_INTR_ON_MESG_MASK); pci_write_config_word(pdev, pos + PCI_EXP_RTCTL, reg16); aer_pos = pci_find_ext_capability(pdev, PCI_EXT_CAP_ID_ERR); /* Clear error status */ pci_read_config_dword(pdev, aer_pos + PCI_ERR_ROOT_STATUS, ®32); pci_write_config_dword(pdev, aer_pos + PCI_ERR_ROOT_STATUS, reg32); pci_read_config_dword(pdev, aer_pos + PCI_ERR_COR_STATUS, ®32); pci_write_config_dword(pdev, aer_pos + PCI_ERR_COR_STATUS, reg32); pci_read_config_dword(pdev, aer_pos + PCI_ERR_UNCOR_STATUS, ®32); pci_write_config_dword(pdev, aer_pos + PCI_ERR_UNCOR_STATUS, reg32); /* * Enable error reporting for the root port device and downstream port * devices. */ set_downstream_devices_error_reporting(pdev, true); /* Enable Root Port's interrupt in response to error messages */ pci_read_config_dword(pdev, aer_pos + PCI_ERR_ROOT_COMMAND, ®32); reg32 |= ROOT_PORT_INTR_ON_MESG_MASK; pci_write_config_dword(pdev, aer_pos + PCI_ERR_ROOT_COMMAND, reg32); }
int pciehp_set_attention_status(struct slot *slot, u8 value) { struct controller *ctrl = slot->ctrl; u16 slot_cmd; u16 cmd_mask; cmd_mask = PCI_EXP_SLTCTL_AIC; switch (value) { case 0 : /* turn off */ slot_cmd = 0x00C0; break; case 1: /* turn on */ slot_cmd = 0x0040; break; case 2: /* turn blink */ slot_cmd = 0x0080; break; default: return -EINVAL; } ctrl_dbg(ctrl, "%s: SLOTCTRL %x write cmd %x\n", __func__, pci_pcie_cap(ctrl->pcie->port) + PCI_EXP_SLTCTL, slot_cmd); return pcie_write_cmd(ctrl, slot_cmd, cmd_mask); }
static void ath_pci_aspm_init(struct ath_common *common) { struct ath_softc *sc = (struct ath_softc *) common->priv; struct ath_hw *ah = sc->sc_ah; struct pci_dev *pdev = to_pci_dev(sc->dev); struct pci_dev *parent; int pos; u8 aspm; if (!pci_is_pcie(pdev)) return; parent = pdev->bus->self; if (WARN_ON(!parent)) return; pos = pci_pcie_cap(parent); pci_read_config_byte(parent, pos + PCI_EXP_LNKCTL, &aspm); if (aspm & (PCIE_LINK_STATE_L0S | PCIE_LINK_STATE_L1)) { ah->aspm_enabled = true; /* Initialize PCIe PM and SERDES registers. */ ath9k_hw_configpcipowersave(ah, 0, 0); } }
static bool _rtl_pci_find_adapter(struct pci_dev *pdev, struct ieee80211_hw *hw) { struct rtl_priv *rtlpriv = rtl_priv(hw); struct rtl_pci_priv *pcipriv = rtl_pcipriv(hw); struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); struct pci_dev *bridge_pdev = pdev->bus->self; u16 venderid; u16 deviceid; u16 irqline; u8 tmp; venderid = pdev->vendor; deviceid = pdev->device; pci_read_config_word(pdev, 0x3C, &irqline); if (deviceid == RTL_PCI_8192_DID || deviceid == RTL_PCI_0044_DID || deviceid == RTL_PCI_0047_DID || deviceid == RTL_PCI_8192SE_DID || deviceid == RTL_PCI_8174_DID || deviceid == RTL_PCI_8173_DID || deviceid == RTL_PCI_8172_DID || deviceid == RTL_PCI_8171_DID) { switch (pdev->revision) { case RTL_PCI_REVISION_ID_8192PCIE: RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, ("8192 PCI-E is found - " "vid/did=%x/%x\n", venderid, deviceid)); rtlhal->hw_type = HARDWARE_TYPE_RTL8192E; break; case RTL_PCI_REVISION_ID_8192SE: RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, ("8192SE is found - " "vid/did=%x/%x\n", venderid, deviceid)); rtlhal->hw_type = HARDWARE_TYPE_RTL8192SE; break; default: RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING, ("Err: Unknown device - " "vid/did=%x/%x\n", venderid, deviceid)); rtlhal->hw_type = HARDWARE_TYPE_RTL8192SE; break; } } else if (deviceid == RTL_PCI_8192CET_DID || deviceid == RTL_PCI_8192CE_DID || deviceid == RTL_PCI_8191CE_DID || deviceid == RTL_PCI_8188CE_DID) { rtlhal->hw_type = HARDWARE_TYPE_RTL8192CE; RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, ("8192C PCI-E is found - " "vid/did=%x/%x\n", venderid, deviceid)); } else { RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING, ("Err: Unknown device -" " vid/did=%x/%x\n", venderid, deviceid)); rtlhal->hw_type = RTL_DEFAULT_HARDWARE_TYPE; } /*find bus info */ pcipriv->ndis_adapter.busnumber = pdev->bus->number; pcipriv->ndis_adapter.devnumber = PCI_SLOT(pdev->devfn); pcipriv->ndis_adapter.funcnumber = PCI_FUNC(pdev->devfn); /*find bridge info */ pcipriv->ndis_adapter.pcibridge_vendorid = bridge_pdev->vendor; for (tmp = 0; tmp < PCI_BRIDGE_VENDOR_MAX; tmp++) { if (bridge_pdev->vendor == pcibridge_vendors[tmp]) { pcipriv->ndis_adapter.pcibridge_vendor = tmp; RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, ("Pci Bridge Vendor is found index: %d\n", tmp)); break; } } if (pcipriv->ndis_adapter.pcibridge_vendor != PCI_BRIDGE_VENDOR_UNKNOWN) { pcipriv->ndis_adapter.pcibridge_busnum = bridge_pdev->bus->number; pcipriv->ndis_adapter.pcibridge_devnum = PCI_SLOT(bridge_pdev->devfn); pcipriv->ndis_adapter.pcibridge_funcnum = PCI_FUNC(bridge_pdev->devfn); pcipriv->ndis_adapter.pcibridge_pciehdr_offset = pci_pcie_cap(bridge_pdev); pcipriv->ndis_adapter.pcicfg_addrport = (pcipriv->ndis_adapter.pcibridge_busnum << 16) | (pcipriv->ndis_adapter.pcibridge_devnum << 11) | (pcipriv->ndis_adapter.pcibridge_funcnum << 8) | (1 << 31); pcipriv->ndis_adapter.num4bytes = (pcipriv->ndis_adapter.pcibridge_pciehdr_offset + 0x10) / 4; rtl_pci_get_linkcontrol_field(hw); if (pcipriv->ndis_adapter.pcibridge_vendor == PCI_BRIDGE_VENDOR_AMD) { pcipriv->ndis_adapter.amd_l1_patch = rtl_pci_get_amd_l1_patch(hw); } } RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, ("pcidev busnumber:devnumber:funcnumber:" "vendor:link_ctl %d:%d:%d:%x:%x\n", pcipriv->ndis_adapter.busnumber, pcipriv->ndis_adapter.devnumber, pcipriv->ndis_adapter.funcnumber, pdev->vendor, pcipriv->ndis_adapter.linkctrl_reg)); RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, ("pci_bridge busnumber:devnumber:funcnumber:vendor:" "pcie_cap:link_ctl_reg:amd %d:%d:%d:%x:%x:%x:%x\n", pcipriv->ndis_adapter.pcibridge_busnum, pcipriv->ndis_adapter.pcibridge_devnum, pcipriv->ndis_adapter.pcibridge_funcnum, pcibridge_vendors[pcipriv->ndis_adapter.pcibridge_vendor], pcipriv->ndis_adapter.pcibridge_pciehdr_offset, pcipriv->ndis_adapter.pcibridge_linkctrlreg, pcipriv->ndis_adapter.amd_l1_patch)); rtl_pci_parse_configuration(pdev, hw); return true; }
struct controller *pcie_init(struct pcie_device *dev) { struct controller *ctrl; u32 slot_cap, link_cap; struct pci_dev *pdev = dev->port; ctrl = kzalloc(sizeof(*ctrl), GFP_KERNEL); if (!ctrl) { dev_err(&dev->device, "%s: Out of memory\n", __func__); goto abort; } ctrl->pcie = dev; if (!pci_pcie_cap(pdev)) { ctrl_err(ctrl, "Cannot find PCI Express capability\n"); goto abort_ctrl; } if (pciehp_readl(ctrl, PCI_EXP_SLTCAP, &slot_cap)) { ctrl_err(ctrl, "Cannot read SLOTCAP register\n"); goto abort_ctrl; } ctrl->slot_cap = slot_cap; mutex_init(&ctrl->ctrl_lock); init_waitqueue_head(&ctrl->queue); dbg_ctrl(ctrl); /* * Controller doesn't notify of command completion if the "No * Command Completed Support" bit is set in Slot Capability * register or the controller supports none of power * controller, attention led, power led and EMI. */ if (NO_CMD_CMPL(ctrl) || !(POWER_CTRL(ctrl) | ATTN_LED(ctrl) | PWR_LED(ctrl) | EMI(ctrl))) ctrl->no_cmd_complete = 1; /* Check if Data Link Layer Link Active Reporting is implemented */ if (pciehp_readl(ctrl, PCI_EXP_LNKCAP, &link_cap)) { ctrl_err(ctrl, "%s: Cannot read LNKCAP register\n", __func__); goto abort_ctrl; } if (link_cap & PCI_EXP_LNKCAP_DLLLARC) { ctrl_dbg(ctrl, "Link Active Reporting supported\n"); ctrl->link_active_reporting = 1; } /* Clear all remaining event bits in Slot Status register */ if (pciehp_writew(ctrl, PCI_EXP_SLTSTA, 0x1f)) goto abort_ctrl; /* Disable sotfware notification */ pcie_disable_notification(ctrl); /* * If this is the first controller to be initialized, * initialize the pciehp work queue */ if (atomic_add_return(1, &pciehp_num_controllers) == 1) { pciehp_wq = create_singlethread_workqueue("pciehpd"); if (!pciehp_wq) goto abort_ctrl; } ctrl_info(ctrl, "HPC vendor_id %x device_id %x ss_vid %x ss_did %x\n", pdev->vendor, pdev->device, pdev->subsystem_vendor, pdev->subsystem_device); if (pcie_init_slot(ctrl)) goto abort_ctrl; return ctrl; abort_ctrl: kfree(ctrl); abort: return NULL; }