MV_VOID xorSetSrcBurstLimit(MV_U32 chan, MV_XOR_BURST_LIMIT srcBurstLimit) { MV_U32 temp = MV_REG_READ(XOR_CONFIG_REG(XOR_UNIT(chan), XOR_CHAN(chan))); temp &= ~XEXCR_SRC_BURST_LIMIT_MASK; temp |= srcBurstLimit << XEXCR_SRC_BURST_LIMIT_OFFS; MV_REG_WRITE(XOR_CONFIG_REG(XOR_UNIT(chan),XOR_CHAN(chan)), temp); }
int mv_xor_mem_init(u32 chan, u32 start_ptr, u32 block_size, u32 init_val_high, u32 init_val_low) { u32 temp; /* Parameter checking */ if (chan >= MV_XOR_MAX_CHAN) return MV_BAD_PARAM; if (MV_ACTIVE == mv_xor_state_get(chan)) return MV_BUSY; if ((block_size < XEXBSR_BLOCK_SIZE_MIN_VALUE) || (block_size > XEXBSR_BLOCK_SIZE_MAX_VALUE)) return MV_BAD_PARAM; /* set the operation mode to Memory Init */ temp = reg_read(XOR_CONFIG_REG(XOR_UNIT(chan), XOR_CHAN(chan))); temp &= ~XEXCR_OPERATION_MODE_MASK; temp |= XEXCR_OPERATION_MODE_MEM_INIT; reg_write(XOR_CONFIG_REG(XOR_UNIT(chan), XOR_CHAN(chan)), temp); /* * update the start_ptr field in XOR Engine [0..1] Destination Pointer * Register */ reg_write(XOR_DST_PTR_REG(XOR_UNIT(chan), XOR_CHAN(chan)), start_ptr); /* * update the Block_size field in the XOR Engine[0..1] Block Size * Registers */ reg_write(XOR_BLOCK_SIZE_REG(XOR_UNIT(chan), XOR_CHAN(chan)), block_size); /* * update the field Init_val_l in the XOR Engine Initial Value Register * Low (XEIVRL) */ reg_write(XOR_INIT_VAL_LOW_REG(XOR_UNIT(chan)), init_val_low); /* * update the field Init_val_h in the XOR Engine Initial Value Register * High (XEIVRH) */ reg_write(XOR_INIT_VAL_HIGH_REG(XOR_UNIT(chan)), init_val_high); /* start transfer */ reg_bit_set(XOR_ACTIVATION_REG(XOR_UNIT(chan), XOR_CHAN(chan)), XEXACTR_XESTART_MASK); return MV_OK; }
/******************************************************************************* * mvXorCtrlSet - Set XOR channel control registers * * DESCRIPTION: * * INPUT: * * OUTPUT: * None. * * RETURN: * GT_BAD_PARAM if parameters to function invalid, GT_OK otherwise. * NOTE: * This function does not modify the OperationMode field of control register. * *******************************************************************************/ GT_STATUS mvXorCtrlSet(GT_U32 chan, GT_U32 xorCtrl) { GT_U32 oldValue; /* update the XOR Engine [0..1] Configuration Registers (XExCR) */ oldValue = MV_REG_READ(XOR_CONFIG_REG(XOR_UNIT(chan), XOR_CHAN(chan))) & XEXCR_OPERATION_MODE_MASK; xorCtrl &= ~XEXCR_OPERATION_MODE_MASK; xorCtrl |= oldValue; MV_REG_WRITE(XOR_CONFIG_REG(XOR_UNIT(chan), XOR_CHAN(chan)), xorCtrl); return GT_OK; }
/* * mv_xor_ctrl_set - Set XOR channel control registers * * DESCRIPTION: * * INPUT: * * OUTPUT: * None. * * RETURN: * MV_BAD_PARAM if parameters to function invalid, MV_OK otherwise. * NOTE: * This function does not modify the Operation_mode field of control register. */ int mv_xor_ctrl_set(u32 chan, u32 xor_ctrl) { u32 old_value; /* update the XOR Engine [0..1] Configuration Registers (XEx_c_r) */ old_value = reg_read(XOR_CONFIG_REG(XOR_UNIT(chan), XOR_CHAN(chan))) & XEXCR_OPERATION_MODE_MASK; xor_ctrl &= ~XEXCR_OPERATION_MODE_MASK; xor_ctrl |= old_value; reg_write(XOR_CONFIG_REG(XOR_UNIT(chan), XOR_CHAN(chan)), xor_ctrl); return MV_OK; }
/* * mv_xor_ctrl_set - Set XOR channel control registers * * DESCRIPTION: * * INPUT: * * OUTPUT: * None. * * RETURN: * MV_BAD_PARAM if parameters to function invalid, MV_OK otherwise. * NOTE: * This function does not modify the OperationMode field of control register. * */ static int mv_xor_ctrl_set(u32 chan, u32 xor_ctrl) { u32 val; /* Update the XOR Engine [0..1] Configuration Registers (XExCR) */ val = reg_read(XOR_CONFIG_REG(XOR_UNIT(chan), XOR_CHAN(chan))) & XEXCR_OPERATION_MODE_MASK; xor_ctrl &= ~XEXCR_OPERATION_MODE_MASK; xor_ctrl |= val; reg_write(XOR_CONFIG_REG(XOR_UNIT(chan), XOR_CHAN(chan)), xor_ctrl); return MV_OK; }
/* * mv_xor_command_set - Set command of XOR channel * * DESCRIPTION: * XOR channel can be started, idle, paused and restarted. * Paused can be set only if channel is active. * Start can be set only if channel is idle or paused. * Restart can be set only if channel is paused. * Stop can be set only if channel is active. * * INPUT: * chan - The channel number * command - The command type (start, stop, restart, pause) * * OUTPUT: * None. * * RETURN: * MV_OK on success , MV_BAD_PARAM on erroneous parameter, MV_ERROR on * undefind XOR engine mode */ int mv_xor_command_set(u32 chan, enum mv_command command) { enum mv_state state; /* Parameter checking */ if (chan >= MV_XOR_MAX_CHAN) { DB(printf("%s: ERR. Invalid chan num %d\n", __func__, chan)); return MV_BAD_PARAM; } /* get the current state */ state = mv_xor_state_get(chan); if ((command == MV_START) && (state == MV_IDLE)) { /* command is start and current state is idle */ reg_bit_set(XOR_ACTIVATION_REG (XOR_UNIT(chan), XOR_CHAN(chan)), XEXACTR_XESTART_MASK); return MV_OK; } else if ((command == MV_STOP) && (state == MV_ACTIVE)) { /* command is stop and current state is active */ reg_bit_set(XOR_ACTIVATION_REG (XOR_UNIT(chan), XOR_CHAN(chan)), XEXACTR_XESTOP_MASK); return MV_OK; } else if (((enum mv_state)command == MV_PAUSED) && (state == MV_ACTIVE)) { /* command is paused and current state is active */ reg_bit_set(XOR_ACTIVATION_REG (XOR_UNIT(chan), XOR_CHAN(chan)), XEXACTR_XEPAUSE_MASK); return MV_OK; } else if ((command == MV_RESTART) && (state == MV_PAUSED)) { /* command is restart and current state is paused */ reg_bit_set(XOR_ACTIVATION_REG (XOR_UNIT(chan), XOR_CHAN(chan)), XEXACTR_XERESTART_MASK); return MV_OK; } else if ((command == MV_STOP) && (state == MV_IDLE)) { /* command is stop and current state is active */ return MV_OK; } /* illegal command */ DB(printf("%s: ERR. Illegal command\n", __func__)); return MV_BAD_PARAM; }
void setXorDesc(void) { unsigned int mode; eth_xor_desc = mvOsMalloc(sizeof(MV_XOR_DESC) + XEXDPR_DST_PTR_DMA_MASK + 32); eth_xor_desc = (MV_XOR_DESC *)MV_ALIGN_UP((MV_U32)eth_xor_desc, XEXDPR_DST_PTR_DMA_MASK+1); eth_xor_desc_phys_addr = mvOsIoVirtToPhys(NULL, eth_xor_desc); mvSysXorInit(); mode = MV_REG_READ(XOR_CONFIG_REG(1, XOR_CHAN(0))); mode &= ~XEXCR_OPERATION_MODE_MASK; mode |= XEXCR_OPERATION_MODE_DMA; MV_REG_WRITE(XOR_CONFIG_REG(1, XOR_CHAN(0)), mode); MV_REG_WRITE(XOR_NEXT_DESC_PTR_REG(1, XOR_CHAN(0)), eth_xor_desc_phys_addr); dump_xor(); }
/******************************************************************************* * mvXorStateGet - Get XOR channel state. * * DESCRIPTION: * XOR channel activity state can be active, idle, paused. * This function retrunes the channel activity state. * * INPUT: * chan - the channel number * * OUTPUT: * None. * * RETURN: * XOR_CHANNEL_IDLE - If the engine is idle. * XOR_CHANNEL_ACTIVE - If the engine is busy. * XOR_CHANNEL_PAUSED - If the engine is paused. * MV_UNDEFINED_STATE - If the engine state is undefind or there is no * such engine * *******************************************************************************/ MV_STATE mvXorStateGet(GT_U32 chan) { GT_U32 state; /* Parameter checking */ if (chan >= MV_XOR_MAX_CHAN) { DB(mvPrintf("%s: ERR. Invalid chan num %d\n", __func__, chan)); return MV_UNDEFINED_STATE; } /* read the current state */ state = MV_REG_READ(XOR_ACTIVATION_REG(XOR_UNIT(chan), XOR_CHAN(chan))); state &= XEXACTR_XESTATUS_MASK; /* return the state */ switch (state) { case XEXACTR_XESTATUS_IDLE: return MV_IDLE; case XEXACTR_XESTATUS_ACTIVE: return MV_ACTIVE; case XEXACTR_XESTATUS_PAUSED: return MV_PAUSED; } return MV_UNDEFINED_STATE; }
/* * mv_xor_state_get - Get XOR channel state. * * DESCRIPTION: * XOR channel activity state can be active, idle, paused. * This function retrunes the channel activity state. * * INPUT: * chan - the channel number * * OUTPUT: * None. * * RETURN: * XOR_CHANNEL_IDLE - If the engine is idle. * XOR_CHANNEL_ACTIVE - If the engine is busy. * XOR_CHANNEL_PAUSED - If the engine is paused. * MV_UNDEFINED_STATE - If the engine state is undefind or there is no * such engine */ enum mv_state mv_xor_state_get(u32 chan) { u32 state; /* Parameter checking */ if (chan >= MV_XOR_MAX_CHAN) { DB(printf("%s: ERR. Invalid chan num %d\n", __func__, chan)); return MV_UNDEFINED_STATE; } /* read the current state */ state = reg_read(XOR_ACTIVATION_REG(XOR_UNIT(chan), XOR_CHAN(chan))); state &= XEXACTR_XESTATUS_MASK; /* return the state */ switch (state) { case XEXACTR_XESTATUS_IDLE: return MV_IDLE; case XEXACTR_XESTATUS_ACTIVE: return MV_ACTIVE; case XEXACTR_XESTATUS_PAUSED: return MV_PAUSED; } return MV_UNDEFINED_STATE; }
/* * mv_xor_cmd_set - Set command of XOR channel * * DESCRIPTION: * XOR channel can be started, idle, paused and restarted. * Paused can be set only if channel is active. * Start can be set only if channel is idle or paused. * Restart can be set only if channel is paused. * Stop can be set only if channel is active. * * INPUT: * chan - The channel number * command - The command type (start, stop, restart, pause) * * OUTPUT: * None. * * RETURN: * MV_OK on success , MV_BAD_PARAM on erroneous parameter, MV_ERROR on * undefind XOR engine mode * */ static int mv_xor_cmd_set(u32 chan, int command) { int state; /* Parameter checking */ if (chan >= MV_XOR_MAX_CHAN) { debug("%s: ERR. Invalid chan num %d\n", __func__, chan); return MV_BAD_PARAM; } /* Get the current state */ state = mv_xor_state_get(chan); /* Command is start and current state is idle */ if ((command == MV_START) && (state == MV_IDLE)) { reg_bit_set(XOR_ACTIVATION_REG(XOR_UNIT(chan), XOR_CHAN(chan)), XEXACTR_XESTART_MASK); return MV_OK; } /* Command is stop and current state is active */ else if ((command == MV_STOP) && (state == MV_ACTIVE)) { reg_bit_set(XOR_ACTIVATION_REG(XOR_UNIT(chan), XOR_CHAN(chan)), XEXACTR_XESTOP_MASK); return MV_OK; } /* Command is paused and current state is active */ else if ((command == MV_PAUSED) && (state == MV_ACTIVE)) { reg_bit_set(XOR_ACTIVATION_REG(XOR_UNIT(chan), XOR_CHAN(chan)), XEXACTR_XEPAUSE_MASK); return MV_OK; } /* Command is restart and current state is paused */ else if ((command == MV_RESTART) && (state == MV_PAUSED)) { reg_bit_set(XOR_ACTIVATION_REG(XOR_UNIT(chan), XOR_CHAN(chan)), XEXACTR_XERESTART_MASK); return MV_OK; } /* Command is stop and current state is active */ else if ((command == MV_STOP) && (state == MV_IDLE)) return MV_OK; /* Illegal command */ debug("%s: ERR. Illegal command\n", __func__); return MV_BAD_PARAM; }
static inline int xorReady(void) { int timeout = 0; while (!(MV_REG_READ(XOR_CAUSE_REG(1)) & XOR_CAUSE_DONE_MASK(XOR_CHAN(0)))) { if (timeout > 0x100000) { mvOsPrintf("XOR timeout\n"); return 0; } timeout++; } /* Clear int */ MV_REG_WRITE(XOR_CAUSE_REG(1), ~(XOR_CAUSE_DONE_MASK(XOR_CHAN(0)))); return 1; }
/******************************************************************************* * mvXorMemInit - * * DESCRIPTION: * * * INPUT: * None. * * OUTPUT: * None. * * RETURN: * * *******************************************************************************/ MV_STATUS mvXorMemInit(MV_U32 chan, MV_U32 startPtr, MV_U32 blockSize, MV_U32 initValHigh, MV_U32 initValLow) { MV_U32 temp; /* Parameter checking */ if (chan >= MV_XOR_MAX_CHAN) { mvOsPrintf("%s: ERR. Invalid chan num %d\n", __func__, chan); return MV_BAD_PARAM; } if (MV_ACTIVE == mvXorStateGet(chan)) { mvOsPrintf("%s: ERR. Channel is already active\n", __func__); return MV_BUSY; } if ((blockSize < XEXBSR_BLOCK_SIZE_MIN_VALUE) || (blockSize > XEXBSR_BLOCK_SIZE_MAX_VALUE)) { mvOsPrintf("%s: ERR. Block size must be between %d to %ul\n", __func__, XEXBSR_BLOCK_SIZE_MIN_VALUE, XEXBSR_BLOCK_SIZE_MAX_VALUE); return MV_BAD_PARAM; } /* set the operation mode to Memory Init */ temp = MV_REG_READ(XOR_CONFIG_REG(XOR_UNIT(chan), XOR_CHAN(chan))); temp &= ~XEXCR_OPERATION_MODE_MASK; temp |= XEXCR_OPERATION_MODE_MEM_INIT; MV_REG_WRITE(XOR_CONFIG_REG(XOR_UNIT(chan), XOR_CHAN(chan)), temp); /* update the startPtr field in XOR Engine [0..1] Destination Pointer Register (XExDPR0) */ MV_REG_WRITE(XOR_DST_PTR_REG(XOR_UNIT(chan), XOR_CHAN(chan)), startPtr); /* update the BlockSize field in the XOR Engine[0..1] Block Size Registers (XExBSR) */ MV_REG_WRITE(XOR_BLOCK_SIZE_REG(XOR_UNIT(chan), XOR_CHAN(chan)), blockSize); /* update the field InitValL in the XOR Engine Initial Value Register Low (XEIVRL) */ MV_REG_WRITE(XOR_INIT_VAL_LOW_REG(XOR_UNIT(chan)), initValLow); /* update the field InitValH in the XOR Engine Initial Value Register High (XEIVRH) */ MV_REG_WRITE(XOR_INIT_VAL_HIGH_REG(XOR_UNIT(chan)), initValHigh); /* start transfer */ MV_REG_BIT_SET(XOR_ACTIVATION_REG(XOR_UNIT(chan), XOR_CHAN(chan)), XEXACTR_XESTART_MASK); return MV_OK; }
static void dump_xor(void) { mvOsPrintf(" CHANNEL_ARBITER_REG %08x\n", MV_REG_READ(XOR_CHANNEL_ARBITER_REG(1))); mvOsPrintf(" CONFIG_REG %08x\n", MV_REG_READ(XOR_CONFIG_REG(1, XOR_CHAN(0)))); mvOsPrintf(" ACTIVATION_REG %08x\n", MV_REG_READ(XOR_ACTIVATION_REG(1, XOR_CHAN(0)))); mvOsPrintf(" CAUSE_REG %08x\n", MV_REG_READ(XOR_CAUSE_REG(1))); mvOsPrintf(" MASK_REG %08x\n", MV_REG_READ(XOR_MASK_REG(1))); mvOsPrintf(" ERROR_CAUSE_REG %08x\n", MV_REG_READ(XOR_ERROR_CAUSE_REG(1))); mvOsPrintf(" ERROR_ADDR_REG %08x\n", MV_REG_READ(XOR_ERROR_ADDR_REG(1))); mvOsPrintf(" NEXT_DESC_PTR_REG %08x\n", MV_REG_READ(XOR_NEXT_DESC_PTR_REG(1, XOR_CHAN(0)))); mvOsPrintf(" CURR_DESC_PTR_REG %08x\n", MV_REG_READ(XOR_CURR_DESC_PTR_REG(1, XOR_CHAN(0)))); mvOsPrintf(" BYTE_COUNT_REG %08x\n\n", MV_REG_READ(XOR_BYTE_COUNT_REG(1, XOR_CHAN(0)))); mvOsPrintf(" %08x\n\n", XOR_WINDOW_CTRL_REG(1, XOR_CHAN(0))) ; mvOsPrintf(" XOR_WINDOW_CTRL_REG %08x\n\n", MV_REG_READ(XOR_WINDOW_CTRL_REG(1, XOR_CHAN(0)))) ; }
/******************************************************************************* * mvXorCommandSet - Set command of XOR channel * * DESCRIPTION: * XOR channel can be started, idle, paused and restarted. * Paused can be set only if channel is active. * Start can be set only if channel is idle or paused. * Restart can be set only if channel is paused. * Stop can be set only if channel is active. * * INPUT: * chan - The channel number * command - The command type (start, stop, restart, pause) * * OUTPUT: * None. * * RETURN: * GT_OK on success , GT_BAD_PARAM on erroneous parameter, MV_ERROR on * undefind XOR engine mode * *******************************************************************************/ GT_STATUS mvXorCommandSet(GT_U32 chan, MV_COMMAND command) { MV_STATE state; /* Parameter checking */ if (chan >= MV_XOR_MAX_CHAN) { DB(mvPrintf("%s: ERR. Invalid chan num %d\n", __func__, chan)); return GT_BAD_PARAM; } /* get the current state */ state = mvXorStateGet(chan); /* command is start and current state is idle */ if ((command == MV_START) && (state == MV_IDLE)) { MV_REG_BIT_SET(XOR_ACTIVATION_REG(XOR_UNIT(chan), XOR_CHAN(chan)), XEXACTR_XESTART_MASK); return GT_OK; } /* command is stop and current state is active */ else if ((command == MV_STOP) && (state == MV_ACTIVE)) { MV_REG_BIT_SET(XOR_ACTIVATION_REG(XOR_UNIT(chan), XOR_CHAN(chan)), XEXACTR_XESTOP_MASK); return GT_OK; } /* command is paused and current state is active */ else if (((MV_STATE)command == MV_PAUSED) && (state == MV_ACTIVE)) { MV_REG_BIT_SET(XOR_ACTIVATION_REG(XOR_UNIT(chan), XOR_CHAN(chan)), XEXACTR_XEPAUSE_MASK); return GT_OK; } /* command is restart and current state is paused */ else if ((command == MV_RESTART) && (state == MV_PAUSED)) { MV_REG_BIT_SET(XOR_ACTIVATION_REG(XOR_UNIT(chan), XOR_CHAN(chan)), XEXACTR_XERESTART_MASK); return GT_OK; } /* command is stop and current state is active */ else if ((command == MV_STOP) && (state == MV_IDLE)) return GT_OK; /* illegal command */ DB(mvPrintf("%s: ERR. Illegal command\n", __func__)); return GT_BAD_PARAM; }
/******************************************************************************* * mvXorMemInit - * * DESCRIPTION: * * * INPUT: * None. * * OUTPUT: * None. * * RETURN: * * *******************************************************************************/ GT_STATUS mvXorMemInit(GT_U32 chan, GT_U32 startPtr, GT_U32 blockSize, GT_U32 initValHigh, GT_U32 initValLow) { GT_U32 temp; /* Parameter checking */ if (chan >= MV_XOR_MAX_CHAN) { return GT_BAD_PARAM; } if (MV_ACTIVE == mvXorStateGet(chan)) { return GT_BUSY; } if ((blockSize < XEXBSR_BLOCK_SIZE_MIN_VALUE) || (blockSize > XEXBSR_BLOCK_SIZE_MAX_VALUE)) { return GT_BAD_PARAM; } /* set the operation mode to Memory Init */ temp = MV_REG_READ(XOR_CONFIG_REG(XOR_UNIT(chan), XOR_CHAN(chan))); temp &= ~XEXCR_OPERATION_MODE_MASK; temp |= XEXCR_OPERATION_MODE_MEM_INIT; MV_REG_WRITE(XOR_CONFIG_REG(XOR_UNIT(chan), XOR_CHAN(chan)), temp); /* update the startPtr field in XOR Engine [0..1] Destination Pointer Register (XExDPR0) */ MV_REG_WRITE(XOR_DST_PTR_REG(XOR_UNIT(chan), XOR_CHAN(chan)), startPtr); /* update the BlockSize field in the XOR Engine[0..1] Block Size Registers (XExBSR) */ MV_REG_WRITE(XOR_BLOCK_SIZE_REG(XOR_UNIT(chan), XOR_CHAN(chan)), blockSize); /* update the field InitValL in the XOR Engine Initial Value Register Low (XEIVRL) */ MV_REG_WRITE(XOR_INIT_VAL_LOW_REG(XOR_UNIT(chan)), initValLow); /* update the field InitValH in the XOR Engine Initial Value Register High (XEIVRH) */ MV_REG_WRITE(XOR_INIT_VAL_HIGH_REG(XOR_UNIT(chan)), initValHigh); /* start transfer */ MV_REG_BIT_SET(XOR_ACTIVATION_REG(XOR_UNIT(chan), XOR_CHAN(chan)), XEXACTR_XESTART_MASK); return GT_OK; }
static inline struct eth_pbuf *eth_l2fw_copy_packet_withXor(struct eth_pbuf *pRxPktInfo) { struct bm_pool *pool; struct eth_pbuf *pTxPktInfo; pool = &mv_eth_pool[pRxPktInfo->pool]; pTxPktInfo = mv_eth_pool_get(pool); if (pTxPktInfo == NULL) { mvOsPrintf("pTxPktInfo == NULL in %s\n", __func__); return NULL; } /* sync between giga and XOR to avoid errors (like checksum errors in TX) when working with IOCC */ mvOsCacheIoSync(); eth_xor_desc->srcAdd0 = pRxPktInfo->physAddr + pRxPktInfo->offset + MV_ETH_MH_SIZE + 30; eth_xor_desc->phyDestAdd = pTxPktInfo->physAddr + pTxPktInfo->offset + MV_ETH_MH_SIZE + 30; eth_xor_desc->byteCnt = pRxPktInfo->bytes - 30; eth_xor_desc->phyNextDescPtr = 0; eth_xor_desc->status = BIT31; /* we had changed only the first part of eth_xor_desc, so flush only one line of cache */ mvOsCacheLineFlush(NULL, eth_xor_desc); MV_REG_WRITE(XOR_NEXT_DESC_PTR_REG(1, XOR_CHAN(0)), eth_xor_desc_phys_addr); MV_REG_WRITE(XOR_ACTIVATION_REG(1, XOR_CHAN(0)), XEXACTR_XESTART_MASK); mvOsCacheLineInv(NULL, pRxPktInfo->pBuf + pRxPktInfo->offset); l2fw_copy_mac(pRxPktInfo, pTxPktInfo); mvOsCacheLineFlush(NULL, pTxPktInfo->pBuf + pTxPktInfo->offset); /* Update TxPktInfo */ pTxPktInfo->bytes = pRxPktInfo->bytes; return pTxPktInfo; }
/******************************************************************************* * mvXorEccClean - . * * DESCRIPTION: * * * INPUT: * destPtr - * * OUTPUT: * None. * * RETURN: * *******************************************************************************/ MV_STATUS mvXorEccClean(MV_U32 chan, MV_XOR_ECC *pXorEccConfig) { MV_U32 tClkCycles; MV_U32 temp; /* Parameter checking */ if (chan >= MV_XOR_MAX_CHAN) { DB(mvOsPrintf("%s: ERR. Invalid chan num %d\n", __func__, chan)); return MV_BAD_PARAM; } if (NULL == pXorEccConfig) { DB(mvOsPrintf("%s: ERR. pXorEccConfig is NULL pointer\n", __func__)); return MV_BAD_PTR; } if (MV_ACTIVE == mvXorStateGet(chan)) { DB(mvOsPrintf("%s: ERR. Channel is already active\n", __func__)); return MV_BUSY; } if ((pXorEccConfig->sectorSize < XETMCR_SECTION_SIZE_MIN_VALUE) || (pXorEccConfig->sectorSize > XETMCR_SECTION_SIZE_MAX_VALUE)) { DB(mvOsPrintf("%s: ERR. sectorSize must be between %d to %d\n", __func__, XETMCR_SECTION_SIZE_MIN_VALUE, XETMCR_SECTION_SIZE_MAX_VALUE)); return MV_BAD_PARAM; } if ((pXorEccConfig->blockSize < XEXBSR_BLOCK_SIZE_MIN_VALUE) || (pXorEccConfig->blockSize > XEXBSR_BLOCK_SIZE_MAX_VALUE)) { DB(mvOsPrintf("%s: ERR. Block size must be between %d to %ul\n", __func__, XEXBSR_BLOCK_SIZE_MIN_VALUE, XEXBSR_BLOCK_SIZE_MAX_VALUE)); return MV_BAD_PARAM; } if (0x0 == pXorEccConfig->destPtr) { DB(mvOsPrintf("%s: ERR. destPtr is NULL pointer\n", __func__)); return MV_BAD_PARAM; } /* set the operation mode to ECC */ temp = MV_REG_READ(XOR_CONFIG_REG(XOR_UNIT(chan), XOR_CHAN(chan))); temp &= ~XEXCR_OPERATION_MODE_MASK; temp |= XEXCR_OPERATION_MODE_ECC; MV_REG_WRITE(XOR_CONFIG_REG(XOR_UNIT(chan), XOR_CHAN(chan)), temp); /* update the TimerEn bit in the XOR Engine Timer Mode Control Register (XETMCR) */ if (pXorEccConfig->periodicEnable) MV_REG_BIT_SET(XOR_TIMER_MODE_CTRL_REG(XOR_UNIT(chan)), XETMCR_TIMER_EN_MASK); else MV_REG_BIT_RESET(XOR_TIMER_MODE_CTRL_REG(XOR_UNIT(chan)), XETMCR_TIMER_EN_MASK); /* update the SectionSizeCtrl bit in the XOR Engine Timer Mode Control Register (XETMCR) */ temp = MV_REG_READ(XOR_TIMER_MODE_CTRL_REG(XOR_UNIT(chan))); temp &= ~XETMCR_SECTION_SIZE_CTRL_MASK; temp |= (pXorEccConfig->sectorSize << XETMCR_SECTION_SIZE_CTRL_OFFS); MV_REG_WRITE(XOR_TIMER_MODE_CTRL_REG(XOR_UNIT(chan)), temp); /* update the DstPtr field in the XOR Engine [0..1] Destination Pointer Register (XExDPR0) */ MV_REG_WRITE(XOR_DST_PTR_REG(XOR_UNIT(chan), XOR_CHAN(chan)), pXorEccConfig->destPtr); /* update the BlockSize field in the XOR Engine[0..1] Block Size Registers (XExBSR) */ MV_REG_WRITE(XOR_BLOCK_SIZE_REG(XOR_UNIT(chan), XOR_CHAN(chan)), pXorEccConfig->blockSize); /* update the XOR Engine Timer Mode Initial Value Register (XETMIVR) */ tClkCycles = pXorEccConfig->tClkTicks; MV_REG_WRITE(XOR_TIMER_MODE_INIT_VAL_REG(XOR_UNIT(chan)), tClkCycles); /* start transfer */ MV_REG_BIT_SET(XOR_ACTIVATION_REG(XOR_UNIT(chan), XOR_CHAN(chan)), XEXACTR_XESTART_MASK); return MV_OK; }
/******************************************************************************* * mvXorTransfer - Transfer data from source to destination on one of * three modes (XOR,CRC32,DMA) * * DESCRIPTION: * This function initiates XOR channel, according to function parameters, * in order to perform XOR or CRC32 or DMA transaction. * To gain maximum performance the user is asked to keep the following * restrictions: * 1) Selected engine is available (not busy). * 1) This module does not take into consideration CPU MMU issues. * In order for the XOR engine to access the appropreate source * and destination, address parameters must be given in system * physical mode. * 2) This API does not take care of cache coherency issues. The source, * destination and in case of chain the descriptor list are assumed * to be cache coherent. * 4) Parameters validity. For example, does size parameter exceeds * maximum byte count of descriptor mode (16M or 64K). * * INPUT: * chan - XOR channel number. See MV_XOR_CHANNEL enumerator. * xorType - One of three: XOR, CRC32 and DMA operations. * xorChainPtr - address of chain pointer * * OUTPUT: * None. * * RETURS: * MV_BAD_PARAM if parameters to function invalid, MV_OK otherwise. * *******************************************************************************/ MV_STATUS mvXorTransfer(MV_U32 chan, MV_XOR_TYPE xorType, MV_U32 xorChainPtr) { MV_U32 temp; /* Parameter checking */ if (chan >= MV_XOR_MAX_CHAN) { DB(mvOsPrintf("%s: ERR. Invalid chan num %d\n", __func__, chan)); return MV_BAD_PARAM; } if (MV_ACTIVE == mvXorStateGet(chan)) { DB(mvOsPrintf("%s: ERR. Channel is already active\n", __func__)); return MV_BUSY; } if (0x0 == xorChainPtr) { DB(mvOsPrintf("%s: ERR. xorChainPtr is NULL pointer\n", __func__)); return MV_BAD_PARAM; } /* read configuration register and mask the operation mode field */ temp = MV_REG_READ(XOR_CONFIG_REG(XOR_UNIT(chan), XOR_CHAN(chan))); temp &= ~XEXCR_OPERATION_MODE_MASK; switch (xorType) { case MV_XOR: if (0 != (xorChainPtr & XEXDPR_DST_PTR_XOR_MASK)) { DB(mvOsPrintf("%s: ERR. Invalid chain pointer (bits [5:0] must " "be cleared)\n", __func__)); return MV_BAD_PARAM; } /* set the operation mode to XOR */ temp |= XEXCR_OPERATION_MODE_XOR; break; case MV_DMA: if (0 != (xorChainPtr & XEXDPR_DST_PTR_DMA_MASK)) { DB(mvOsPrintf("%s: ERR. Invalid chain pointer (bits [4:0] must " "be cleared)\n", __func__)); return MV_BAD_PARAM; } /* set the operation mode to DMA */ temp |= XEXCR_OPERATION_MODE_DMA; break; case MV_CRC32: if (0 != (xorChainPtr & XEXDPR_DST_PTR_CRC_MASK)) { DB(mvOsPrintf("%s: ERR. Invalid chain pointer (bits [4:0] must " "be cleared)\n", __func__)); return MV_BAD_PARAM; } /* set the operation mode to CRC32 */ temp |= XEXCR_OPERATION_MODE_CRC; break; default: return MV_BAD_PARAM; } /* write the operation mode to the register */ MV_REG_WRITE(XOR_CONFIG_REG(XOR_UNIT(chan), XOR_CHAN(chan)), temp); /* update the NextDescPtr field in the XOR Engine [0..1] Next Descriptor Pointer Register (XExNDPR) */ MV_REG_WRITE(XOR_NEXT_DESC_PTR_REG(XOR_UNIT(chan), XOR_CHAN(chan)), xorChainPtr); /* start transfer */ MV_REG_BIT_SET(XOR_ACTIVATION_REG(XOR_UNIT(chan), XOR_CHAN(chan)), XEXACTR_XESTART_MASK); return MV_OK; }
/* * mv_xor_transfer - Transfer data from source to destination on one of * three modes (XOR,CRC32,DMA) * * DESCRIPTION: * This function initiates XOR channel, according to function parameters, * in order to perform XOR or CRC32 or DMA transaction. * To gain maximum performance the user is asked to keep the following * restrictions: * 1) Selected engine is available (not busy). * 1) This module does not take into consideration CPU MMU issues. * In order for the XOR engine to access the appropreate source * and destination, address parameters must be given in system * physical mode. * 2) This API does not take care of cache coherency issues. The source, * destination and in case of chain the descriptor list are assumed * to be cache coherent. * 4) Parameters validity. For example, does size parameter exceeds * maximum byte count of descriptor mode (16M or 64K). * * INPUT: * chan - XOR channel number. See MV_XOR_CHANNEL enumerator. * xor_type - One of three: XOR, CRC32 and DMA operations. * xor_chain_ptr - address of chain pointer * * OUTPUT: * None. * * RETURS: * MV_BAD_PARAM if parameters to function invalid, MV_OK otherwise. * */ int mv_xor_transfer(u32 chan, int xor_type, u32 xor_chain_ptr) { u32 tmp; /* Parameter checking */ if (chan >= MV_XOR_MAX_CHAN) { debug("%s: ERR. Invalid chan num %d\n", __func__, chan); return MV_BAD_PARAM; } if (MV_ACTIVE == mv_xor_state_get(chan)) { debug("%s: ERR. Channel is already active\n", __func__); return MV_BUSY; } if (0x0 == xor_chain_ptr) { debug("%s: ERR. xor_chain_ptr is NULL pointer\n", __func__); return MV_BAD_PARAM; } /* Read configuration register and mask the operation mode field */ tmp = reg_read(XOR_CONFIG_REG(XOR_UNIT(chan), XOR_CHAN(chan))); tmp &= ~XEXCR_OPERATION_MODE_MASK; switch (xor_type) { case MV_XOR: if (0 != (xor_chain_ptr & XEXDPR_DST_PTR_XOR_MASK)) { debug("%s: ERR. Invalid chain pointer (bits [5:0] must be cleared)\n", __func__); return MV_BAD_PARAM; } /* Set the operation mode to XOR */ tmp |= XEXCR_OPERATION_MODE_XOR; break; case MV_DMA: if (0 != (xor_chain_ptr & XEXDPR_DST_PTR_DMA_MASK)) { debug("%s: ERR. Invalid chain pointer (bits [4:0] must be cleared)\n", __func__); return MV_BAD_PARAM; } /* Set the operation mode to DMA */ tmp |= XEXCR_OPERATION_MODE_DMA; break; case MV_CRC32: if (0 != (xor_chain_ptr & XEXDPR_DST_PTR_CRC_MASK)) { debug("%s: ERR. Invalid chain pointer (bits [4:0] must be cleared)\n", __func__); return MV_BAD_PARAM; } /* Set the operation mode to CRC32 */ tmp |= XEXCR_OPERATION_MODE_CRC; break; default: return MV_BAD_PARAM; } /* Write the operation mode to the register */ reg_write(XOR_CONFIG_REG(XOR_UNIT(chan), XOR_CHAN(chan)), tmp); /* * Update the NextDescPtr field in the XOR Engine [0..1] Next Descriptor * Pointer Register (XExNDPR) */ reg_write(XOR_NEXT_DESC_PTR_REG(XOR_UNIT(chan), XOR_CHAN(chan)), xor_chain_ptr); /* Start transfer */ reg_bit_set(XOR_ACTIVATION_REG(XOR_UNIT(chan), XOR_CHAN(chan)), XEXACTR_XESTART_MASK); return MV_OK; }