IX_STATUS ixParityENAccPbcPEUnload(void) { UINT32 lockKey; UINT32 status = IX_SUCCESS; IxParityENAccPEConfigOption ixPbcPDCfg; ixPbcPDCfg = IXP400_PARITYENACC_PE_DISABLE; ixParityENAccPbcPEDetectionConfigure(ixPbcPDCfg); /* Unbind the IRQ */ lockKey = ixOsalIrqLock(); if (IX_SUCCESS != ixOsalIrqUnbind ((UINT32) IRQ_IXP400_INTC_PARITYENACC_PBC)) { IXP400_PARITYENACC_MSGLOG(IX_OSAL_LOG_LVL_WARNING, IX_OSAL_LOG_DEV_STDERR, "ixParityENAccPbcPEUnload(): "\ "Can't unbind the PBC ISR to IRQ_IXP400_INTC_PARITYENACC_PBC!!!\n",0,0,0,0,0,0); status = IX_FAIL; } ixOsalIrqUnlock(lockKey); /* Unmap the memory */ IX_OSAL_MEM_UNMAP(ixPbcVirtualBaseAddr); return status; } /* end of ixParityENAccPbcPEUnload() function */
IX_STATUS ixParityENAccPbcPEParityInterruptClear ( IxParityENAccPbcPEParityErrorContext ixPbcPECMsg) { IXP400_PARITYENACC_MSGLOG(IX_OSAL_LOG_LVL_USER, IX_OSAL_LOG_DEV_STDOUT, "\nixParityENAccPbcPEParityInterruptClear():" "\n\tpbcParitySource:%x\tpbcAccessType:%x\n", ixPbcPECMsg.pbcParitySource,ixPbcPECMsg.pbcAccessType,0,0,0,0); IXP400_PARITYENACC_MSGLOG(IX_OSAL_LOG_LVL_DEBUG2, IX_OSAL_LOG_DEV_STDOUT, "ixParityENAccPbcPEParityInterruptClear(): " "\nIXP400_PARITYENACC_PE_PBC_INITIATOR:%x" "\tIXP400_PARITYENACC_PE_READ:%x\n", (IXP400_PARITYENACC_PE_PBC_INITIATOR),(IXP400_PARITYENACC_PE_READ),0,0,0,0); /* Clear off Parity Error Status due to PCI Initiator Read? */ if (IXP400_PARITYENACC_PE_PBC_INITIATOR == ixPbcPECMsg.pbcParitySource) { /* Write '1' to clear off the srcr.MDPE and srcr.DPE */ IXP400_PARITYENACC_VAL_BIT_SET( ixParityENAccPbcPEConfig.pbcParityErrorStatus.pciSrcrValue, (IXP400_PARITYENACC_PBC_PCICFG_SRCR_MDPE | IXP400_PARITYENACC_PBC_PCICFG_SRCR_DPE) ); } /* end of if */ /* Clear off Parity Error Status due to PCI Target Write? */ if (IXP400_PARITYENACC_PE_PBC_TARGET == ixPbcPECMsg.pbcParitySource) { /* Write '1' to clear off the srcr.DPE */ IXP400_PARITYENACC_VAL_BIT_SET( ixParityENAccPbcPEConfig.pbcParityErrorStatus.pciSrcrValue, IXP400_PARITYENACC_PBC_PCICFG_SRCR_DPE); } /* end of if */ /* Clear parity error interrupt status */ ixParityENAccPbcPEParityErrorStatusClear(); return IX_SUCCESS; } /* end of ixParityENAccPbcPEParityInterruptClear() function */
IX_STATUS ixParityENAccEbcPEParityErrorContextFetch( IxParityENAccEbcPEParityErrorContext *ixEbcPECMsg) { if ((IxParityENAccEbcPEParityErrorContext *)NULL == ixEbcPECMsg) { return IX_FAIL; } /* end of if */ /* Fetch EBC Parity Error Status */ ixParityENAccEbcPEParityErrorStatusGet(); ixEbcPECMsg->ebcParityAddress = IXP400_PARITYENACC_VAL_READ( ixParityENAccEbcPEConfig.ebcParityErrorStatus.expParityStatusValue, IXP400_PARITYENACC_EBC_PARITY_STATUS_ERRADDR); /* Detected Parity Error on Inbound Write by an External Master? */ if (IXP400_PARITYENACC_VAL_BIT_CHECK( ixParityENAccEbcPEConfig.ebcParityErrorStatus.expParityStatusValue, IXP400_PARITYENACC_EBC_PARITY_STATUS_INERRSTS)) { ixEbcPECMsg->ebcParitySource = IXP400_PARITYENACC_PE_EBC_EXTMST; ixEbcPECMsg->ebcAccessType = IXP400_PARITYENACC_PE_WRITE; return IX_SUCCESS; } /* end of if */ /* Detected Parity Error on Outbound Read by the Expansion Bus Controller? */ if (IXP400_PARITYENACC_VAL_BIT_CHECK( ixParityENAccEbcPEConfig.ebcParityErrorStatus.expParityStatusValue, IXP400_PARITYENACC_EBC_PARITY_STATUS_OUTERRSTS)) { ixEbcPECMsg->ebcParitySource = IXP400_PARITYENACC_PE_EBC_CS; ixEbcPECMsg->ebcAccessType = IXP400_PARITYENACC_PE_READ; return IX_SUCCESS; } /* end of if */ #ifndef NDEBUG IXP400_PARITYENACC_MSGLOG(IX_OSAL_LOG_LVL_ERROR, IX_OSAL_LOG_DEV_STDERR, "ixParityENAccEbcPEParityErrorContextFetch(): " "Can't fetch parity context of EBC #%u!!!\n", 0,0,0,0,0,0); #endif /* end of #ifndef NDEBUG */ return IX_FAIL; } /* end of ixParityENAccEbcPEParityErrorContextFetch() function */
IX_STATUS ixParityENAccSwcpPEUnload(void) { UINT32 lockKey; UINT32 status = IX_SUCCESS; IxParityENAccSwcpPEConfigOption ixSwcpPDCfg; ixSwcpPDCfg = IXP400_PARITYENACC_PE_DISABLE; ixParityENAccSwcpPEDetectionConfigure(ixSwcpPDCfg); /* Unbind the IRQ */ lockKey = ixOsalIrqLock(); if (IX_SUCCESS != ixOsalIrqUnbind ((UINT32) IRQ_IXP400_INTC_PARITYENACC_SWCP)) { IXP400_PARITYENACC_MSGLOG(IX_OSAL_LOG_LVL_WARNING, IX_OSAL_LOG_DEV_STDERR, "ixParityENAccSwcpPEUnload(): "\ "Can't unbind the SWCP ISR to IRQ_IXP400_INTC_PARITYENACC_SWCP!!!\n",0,0,0,0,0,0); status = IX_FAIL; } ixOsalIrqUnlock(lockKey); return status; } /* end of ixParityENAccSwcpPEUnload() function */
IX_STATUS ixParityENAccEbcPEDetectionConfigure(IxParityENAccEbcPEConfigOption ixEbcPDCfg) { UINT32 ebcPDCfgFlags = 0; UINT32 ebcPDCfgStatus = 0; UINT32 ebcTmpPDCfgStatus = 0; register IxParityENAccEbcPERegisters *ebcPERegisters = &ixParityENAccEbcPEConfig.ebcPERegisters; int loopIdx = 100; if (IXP400_PARITYENACC_PE_EBC_CS == ixEbcPDCfg.ebcCsExtSource) { if (ixEbcPDCfg.ebcCsId >= IXP400_PARITYENACC_PE_EBC_CHIPSEL_MAX) { return IX_FAIL; } /* end of if */ /* Get current parity detection configuration of Chip Select */ IXP400_PARITYENACC_REG_READ( ebcPERegisters->expTimingCs[ixEbcPDCfg.ebcCsId], &ebcPDCfgStatus); /* Enable parity error detection */ ebcPDCfgFlags = IXP400_PARITYENACC_EBC_TIMING_CSX_PAR_EN; if (IXP400_PARITYENACC_PE_ENABLE == ixEbcPDCfg.ebcInOrOutbound.ebcCsEnabled) { IXP400_PARITYENACC_VAL_BIT_SET(ebcPDCfgStatus, ebcPDCfgFlags); } else /* Disable parity error detection */ { IXP400_PARITYENACC_VAL_BIT_CLEAR(ebcPDCfgStatus, ebcPDCfgFlags); } /* end of if */ while (loopIdx-- && (ebcTmpPDCfgStatus != ebcPDCfgStatus)) { /* Set the new configuration */ IXP400_PARITYENACC_REG_WRITE( ebcPERegisters->expTimingCs[ixEbcPDCfg.ebcCsId], ebcPDCfgStatus); /* Configuration successful? */ IXP400_PARITYENACC_REG_READ( ebcPERegisters->expTimingCs[ixEbcPDCfg.ebcCsId],&ebcTmpPDCfgStatus); } if (ebcTmpPDCfgStatus != ebcPDCfgStatus) { return IX_FAIL; } /* end of if */ /* * This step required for Even/Odd Parity Type detection from the * EBC Master Control Register if the chip select configuration is * specified along with the parity type which is part of the Master * Control Register only */ /* Get current parity detection configuration of External Master */ IXP400_PARITYENACC_REG_READ(ebcPERegisters->expMstControl,&ebcPDCfgStatus); } /* else of if */ else /* EBC Master Control */ { ebcPDCfgFlags = IXP400_PARITYENACC_EBC_MST_CONTROL_INPAR_EN; /* Get current parity detection configuration */ IXP400_PARITYENACC_REG_READ(ebcPERegisters->expMstControl, &ebcPDCfgStatus); /* Enable parity error detection */ if (IXP400_PARITYENACC_PE_ENABLE == ixEbcPDCfg.ebcInOrOutbound.ebcExtMstEnabled) { IXP400_PARITYENACC_VAL_BIT_SET(ebcPDCfgStatus,ebcPDCfgFlags); } else /* Disable parity error detection */ { IXP400_PARITYENACC_VAL_BIT_CLEAR(ebcPDCfgStatus,ebcPDCfgFlags); } /* end of if */ } /* end of if */ /* Set Even/Odd parity type */ ebcPDCfgFlags = IXP400_PARITYENACC_EBC_MST_CONTROL_ODDPARITY; if (IXP400_PARITYENACC_PE_ODD_PARITY == ixEbcPDCfg.parityOddEven) { IXP400_PARITYENACC_VAL_BIT_SET(ebcPDCfgStatus,ebcPDCfgFlags); } else /* Set even parity */ { IXP400_PARITYENACC_VAL_BIT_CLEAR(ebcPDCfgStatus,ebcPDCfgFlags); } /* end of if */ loopIdx = 10; while (loopIdx-- && (ebcTmpPDCfgStatus != ebcPDCfgStatus)) { /* Set the new configuration */ IXP400_PARITYENACC_REG_WRITE(ebcPERegisters->expMstControl, ebcPDCfgStatus); /* Configuration successful? */ IXP400_PARITYENACC_REG_READ(ebcPERegisters->expMstControl,&ebcTmpPDCfgStatus); } if (ebcTmpPDCfgStatus == ebcPDCfgStatus) { /* Enable/Disable the corresponding interrupt at Interrupt Controller */ return ((IXP400_PARITYENACC_PE_ENABLE == ixEbcPDCfg.ebcInOrOutbound.ebcCsEnabled) || (IXP400_PARITYENACC_PE_ENABLE == ixEbcPDCfg.ebcInOrOutbound.ebcExtMstEnabled)) ? ixParityENAccIcInterruptEnable( IXP400_PARITYENACC_INTC_EBC_PARITY_INTERRUPT) : ixParityENAccIcInterruptDisable( IXP400_PARITYENACC_INTC_EBC_PARITY_INTERRUPT); } else { IXP400_PARITYENACC_MSGLOG(IX_OSAL_LOG_LVL_ERROR, IX_OSAL_LOG_DEV_STDERR, "ixParityENAccEbcPEDetectionConfigure(): returned IX_FAIL\n", 0,0,0,0,0,0); return IX_FAIL; } /* end of if */ } /* end of ixParityENAccEbcPEDetectionConfigure() function */
IX_STATUS ixParityENAccMcuPEParityInterruptClear ( IxParityENAccMcuPEParityErrorSource ixMcuParityErrSrc, IxParityENAccPEParityErrorAddress ixMcuParityErrAddress) { BOOL mcuParityError0 = FALSE; BOOL mcuParityError1 = FALSE; BOOL mcuParityErrorN = FALSE; UINT32 mcuParitySource0 = IXP400_PARITYENACC_MCU_ERR_SMBIT_SGL; UINT32 mcuParitySource1 = IXP400_PARITYENACC_MCU_ERR_SMBIT_SGL; register IxParityENAccMcuPERegisters *mcuPERegisters = &ixParityENAccMcuPEConfig.mcuPERegisters; IxParityENAccPEParityErrorAddress mcuParityErrorAddr = IXP400_PARITYENACC_VAL_READ(ixParityENAccMcuPEConfig.\ mcuParityErrorStatus.mcuEcar0Value, IXP400_PARITYENACC_MCU_ERR_ADDRESS_MASK); /* Identify the Multi & Single bit parity errors */ ixParityENAccMcuPEParityErrorStatusInterpret ( &mcuParityError0, &mcuParityError1, &mcuParityErrorN, &mcuParitySource0, &mcuParitySource1); switch (ixMcuParityErrSrc) { case IXP400_PARITYENACC_PE_MCU_SBIT: { /* Parity error number #0 is of single bit type */ if ((TRUE == mcuParityError0) && (IXP400_PARITYENACC_MCU_ERR_SMBIT_SGL == mcuParitySource0) && (mcuParityErrorAddr == ixMcuParityErrAddress)) { /* Write '1' to clear the single bit parity interrupt */ IXP400_PARITYENACC_REG_WRITE(mcuPERegisters->mcuMcisr, IXP400_PARITYENACC_MCU_ERROR0_MASK); break; } /* end of if */ /* Parity error number #1 is of single bit type */ /* Write '1' to clear the single bit parity interrupt */ IXP400_PARITYENACC_REG_WRITE(mcuPERegisters->mcuMcisr, IXP400_PARITYENACC_MCU_ERROR1_MASK); break; } /* end of case IXP400_PARITYENACC_PE_MCU_SBIT */ case IXP400_PARITYENACC_PE_MCU_MBIT: { /* Parity error number #0 is of multi bit type */ if ((TRUE == mcuParityError0) && (IXP400_PARITYENACC_MCU_ERR_SMBIT_MLT == mcuParitySource0) && (mcuParityErrorAddr == ixMcuParityErrAddress)) { /* Write '1' to clear the multi bit parity interrupt */ IXP400_PARITYENACC_REG_WRITE(mcuPERegisters->mcuMcisr, IXP400_PARITYENACC_MCU_ERROR0_MASK); break; } /* end of if */ /* Parity error number #1 is of multi bit type */ /* Write '1' to clear the multi bit parity interrupt */ IXP400_PARITYENACC_REG_WRITE(mcuPERegisters->mcuMcisr, IXP400_PARITYENACC_MCU_ERROR1_MASK); break; } /* end of case IXP400_PARITYENACC_PE_MCU_MBIT */ case IXP400_PARITYENACC_PE_MCU_OVERFLOW: { /* Write '1' to clear the Parity Overflow Interrupt */ IXP400_PARITYENACC_REG_WRITE(mcuPERegisters->mcuMcisr, IXP400_PARITYENACC_MCU_ERRORN_MASK); break; } /* end of case IXP400_PARITYENACC_PE_MCU_OVERFLOW */ default: { /* This part of the code should never be reached */ IXP400_PARITYENACC_MSGLOG(IX_OSAL_LOG_LVL_ERROR, IX_OSAL_LOG_DEV_STDERR, "ixParityENAccMcuPEParityInterruptClear(): " "Invalid MCU interrupt source to clear\n", 0,0,0,0,0,0); return IX_FAIL; } /* end of case default */ } /* end of switch */ return IX_SUCCESS; } /* end of ixParityENAccMcuPEParityInterruptClear() function */
IX_STATUS ixParityENAccPbcPEParityErrorContextFetch( IxParityENAccPbcPEParityErrorContext *ixPbcPECMsg) { BOOL isrPPE = FALSE; BOOL srcrDPE = FALSE; BOOL srcrMDPE = FALSE; if ((IxParityENAccPbcPEParityErrorContext *)NULL == ixPbcPECMsg) { return IX_FAIL; } /* end of if */ /* Fetch PBC Parity Error Status into local data structures*/ ixParityENAccPbcPEParityErrorStatusGet(); /* * PCI Controller Initiator/Target Interface and Parity Errors detection * during Read / Write Transactions show in the following decision table * * +--------------------+--------------------+ * | PCI Initiator | PCI Target | * +----------+---------+----------+---------+ * | Read | Write | Read | Write | * +----------+---------+----------+---------+ * isr.PPE | 1 | 1 | - | 1 | * +----------+---------+----------+---------+ * srcr.DPE | 1 | 0 | - | 1 | * +----------+---------+----------+---------+ * srcr.MDPE | 1 | 1 | - | 0 | * +----------+---------+----------+---------+ * * While: * - Error handling is left to initiator of transaction * 1 Bit in the register (row heading-reg.BIT) is SET * 0 Bit in the register is CLEAR * x Don't Care */ isrPPE = IXP400_PARITYENACC_VAL_BIT_CHECK( ixParityENAccPbcPEConfig.pbcParityErrorStatus.pciIsrValue, (UINT32) IXP400_PARITYENACC_PBC_ISR_PPE); srcrDPE = IXP400_PARITYENACC_VAL_BIT_CHECK( ixParityENAccPbcPEConfig.pbcParityErrorStatus.pciSrcrValue, (UINT32) IXP400_PARITYENACC_PBC_PCICFG_SRCR_DPE); srcrMDPE = IXP400_PARITYENACC_VAL_BIT_CHECK( ixParityENAccPbcPEConfig.pbcParityErrorStatus.pciSrcrValue, (UINT32) IXP400_PARITYENACC_PBC_PCICFG_SRCR_MDPE); /* Is Parity Error Detected ? */ if (TRUE == isrPPE) { /* Is due to PCI Initiator Transaction ? */ if (TRUE == srcrMDPE) { /* Is due to PCI Initiator Read Transaction ? */ if (TRUE == srcrDPE) { ixPbcPECMsg->pbcParitySource = IXP400_PARITYENACC_PE_PBC_INITIATOR; ixPbcPECMsg->pbcAccessType = IXP400_PARITYENACC_PE_READ; return IX_SUCCESS; } /* else of if */ /* Is due to PCI Initiator Write Transaction ? */ else { ixPbcPECMsg->pbcParitySource = IXP400_PARITYENACC_PE_PBC_INITIATOR; ixPbcPECMsg->pbcAccessType = IXP400_PARITYENACC_PE_WRITE; return IX_SUCCESS; } /* end of if */ } /* end of if */ /* Is due to PCI Target Write Transaction ? */ if (TRUE == srcrDPE) { ixPbcPECMsg->pbcParitySource = IXP400_PARITYENACC_PE_PBC_TARGET; ixPbcPECMsg->pbcAccessType = IXP400_PARITYENACC_PE_WRITE; return IX_SUCCESS; } /* end of if */ /* Is due to PCI Target Read Transaction? Possibly */ ixPbcPECMsg->pbcParitySource = IXP400_PARITYENACC_PE_PBC_TARGET; ixPbcPECMsg->pbcAccessType = IXP400_PARITYENACC_PE_READ; return IX_SUCCESS; } /* end of if */ #ifndef NDEBUG IXP400_PARITYENACC_MSGLOG(IX_OSAL_LOG_LVL_ERROR, IX_OSAL_LOG_DEV_STDERR, "ixParityENAccPbcPEParityErrorContextFetch(): " "Can't fetch parity context of PBC !!!\n", 0,0,0,0,0,0); #endif /* end of #ifndef NDEBUG */ return IX_FAIL; } /* end of function */