/* * Stop hardware timer and read time elapsed since last start. * * returns * The elapsed time since last start in units of 16us. * */ SK_U32 SkHwtRead( SK_AC *pAC, /* Adapters context */ SK_IOC Ioc) /* IoContext */ { SK_U32 TRead; SK_U32 IStatus; if (pAC->Hwt.TActive) { SkHwtStop(pAC, Ioc); SK_IN32(Ioc, B2_TI_VAL, &TRead); TRead /= SK_HWT_FAC; SK_IN32(Ioc, B0_ISRC, &IStatus); /* Check if timer expired (or wraped around) */ if ((TRead > pAC->Hwt.TStart) || (IStatus & IS_TIMINT)) { SkHwtStop(pAC, Ioc); pAC->Hwt.TStop = pAC->Hwt.TStart; } else { pAC->Hwt.TStop = pAC->Hwt.TStart - TRead; } } return(pAC->Hwt.TStop); }
/****************************************************************************** * * RamReadAddr() - Reads one quadword from board RAM * * Description: * Read one quadword from board RAM. * For Yukon Extreme, if Addr == 2^29 then the qword * at the current position of the hardware pointer is read. * * Returns: * 0 on success, 1 on error */ static int RamReadAddr( SK_AC *pAC, /* Adapter context */ SK_U32 Addr, /* Address to be read at */ SK_U32 *pLowDword, /* Lower Dword to be read */ SK_U32 *pHighDword, /* Upper Dword to be read */ int SelectedRam) /* Selected RAM buffer 0, 1 or 3 */ { /* Support for Yukon Extreme and Supreme */ if ((pAC->GIni.GIChipId == CHIP_ID_YUKON_EX) || (pAC->FwApp.ChipMode == SK_GEASF_CHIP_SU)) { if (Addr == BIT_29) { Addr = SelectedRam << 30; } else { /* Use given address (lower 8 bits for TX, lower 9 bits for RX). */ Addr = (Addr & 0x7fffL) | BIT_29 | (SelectedRam << 30); } SelectedRam = 0; } else { return(1); } SK_OUT32(pAC->IoBase, SELECT_RAM_BUFFER(SelectedRam, B3_RAM_ADDR), Addr); /* Read Access is initiated by reading the lower dword. */ SK_IN32(pAC->IoBase, SELECT_RAM_BUFFER(SelectedRam, B3_RAM_DATA_LO), pLowDword); SK_IN32(pAC->IoBase, SELECT_RAM_BUFFER(SelectedRam, B3_RAM_DATA_HI), pHighDword); return(0); }
/* * Stop hardware timer and read time elapsed since last start. * * returns * The elapsed time since last start in units of 1 us. * */ SK_U32 SkHwtRead( SK_AC *pAC, /* Adapter Context */ SK_IOC IoC) /* I/O Context */ { SK_U32 TRead; SK_U32 IStatus; SK_U32 TimerInt; TimerInt = CHIP_ID_YUKON_2(pAC) ? Y2_IS_TIMINT : IS_TIMINT; if (pAC->Hwt.TActive) { SkHwtStop(pAC, IoC); SK_IN32(IoC, B2_TI_VAL, &TRead); TRead /= SK_HWT_FAC; SK_IN32(IoC, B0_ISRC, &IStatus); /* Check if timer expired (or wrapped around) */ if ((TRead > pAC->Hwt.TStart) || ((IStatus & TimerInt) != 0)) { SkHwtStop(pAC, IoC); pAC->Hwt.TStop = pAC->Hwt.TStart; } else { pAC->Hwt.TStop = pAC->Hwt.TStart - TRead; } } return(pAC->Hwt.TStop); }
/* * waits for a completion of an I2C transfer * * Returns * Nothing */ void SkI2cWaitIrq( SK_AC *pAC, /* Adapter Context */ SK_IOC IoC) /* I/O Context */ { SK_SENSOR *pSen; SK_U64 StartTime; SK_U32 IrqSrc; pSen = &pAC->I2c.SenTable[pAC->I2c.CurrSens]; if (pSen->SenState == SK_SEN_IDLE) { return; } StartTime = SkOsGetTime(pAC); do { if (SkOsGetTime(pAC) - StartTime > SK_TICKS_PER_SEC / 8) { SK_I2C_STOP(IoC); #ifndef SK_DIAG SK_ERR_LOG(pAC, SK_ERRCL_SW, SKERR_I2C_E016, SKERR_I2C_E016MSG); #endif /* !SK_DIAG */ return; } SK_IN32(IoC, B0_ISRC, &IrqSrc); } while ((IrqSrc & IS_I2C_READY) == 0); pSen->SenState = SK_SEN_IDLE; return; } /* SkI2cWaitIrq */
static SK_BOOL IsIntModEnabled(SK_AC *pAC) { unsigned long CtrCmd; SK_IN32(pAC->IoBase, B2_IRQM_CTRL, &CtrCmd); if ((CtrCmd & TIM_START) == TIM_START) { return SK_TRUE; } else { return SK_FALSE; } }
/* * reads a single byte or 4 bytes from the I2C device * * returns the word read */ SK_U32 SkI2cRead( SK_AC *pAC, /* Adapter Context */ SK_IOC IoC, /* I/O Context */ int I2cDev, /* I2C Device Address */ int I2cReg, /* I2C Device Register Address */ int I2cBurst) /* I2C Burst Flag ( 0 || I2C_BURST ) */ { SK_U32 Data; SK_OUT32(IoC, B2_I2C_DATA, 0); SK_I2C_CTL(IoC, I2C_READ, I2cDev, I2cReg, I2cBurst); if (SkI2cWait(pAC, IoC, I2C_READ)) { w_print("I2C Transfer Timeout!\n"); } SK_IN32(IoC, B2_I2C_DATA, &Data); return(Data); } /* SkI2cRead */
/***************************************************************************** * * SkPflCheck - Determines whether a parallel flash is present * * Description: * This function determines whether a parallel flash is present. * * Returns: * 0 No parallel flash * 1 Parallel flash detected */ int SkPflCheck( SK_AC *pAC, SK_IOC IoC) { #ifdef XXX unsigned long opcodes; #endif /* XXX */ SK_IN8(IoC, B2_CHIP_ID, &pAC->pfl.YkChipId); if (pAC->pfl.YkChipId == CHIP_ID_YUKON_SUPR) { SkPflSetDevPtr(pAC, IoC); if (pAC->pfl.pPflDev == NULL) { /* unknown or no flash */ fl_print("\nFlash device\t: none\n"); return (0); } #ifdef XXX /* * set the opcodes for the SPI flash found */ SK_IN32(IoC, SPI_Y2_OPCODE_REG1, &opcodes); opcodes &= 0x000000ffL; opcodes |= ((((unsigned long)(pAC->pfl.pPflDev->opcodes.op_read)) << 8) | (((unsigned long)(pAC->pfl.pPflDev->opcodes.op_read_id)) << 16) | (((unsigned long)(pAC->pfl.pPflDev->opcodes.op_read_status)) << 24)); SK_OUT32(IoC, SPI_Y2_OPCODE_REG1, opcodes); opcodes = (((unsigned long)(pAC->pfl.pPflDev->opcodes.op_write_enable)) | (((unsigned long)(pAC->pfl.pPflDev->opcodes.op_write)) << 8) | (((unsigned long)(pAC->pfl.pPflDev->opcodes.op_sector_erase)) << 16) | (((unsigned long)(pAC->pfl.pPflDev->opcodes.op_chip_erase)) << 24)); SK_OUT32(IoC, SPI_Y2_OPCODE_REG2, opcodes); #endif /* XXX */ return (1); } return (0); }
/* * reads a single byte or 4 bytes from the I2C device * * returns the word read */ SK_U32 SkI2cRead( SK_AC *pAC, /* Adapter Context */ SK_IOC IoC, /* I/O Context */ int I2cDev, /* I2C Device Address */ int I2cReg, /* I2C Device Register Address */ int I2cBurst) /* I2C Burst Flag */ { SK_U32 Data; SK_OUT32(IoC, B2_I2C_DATA, 0); SK_I2C_CTL(IoC, I2C_READ, I2cDev, I2cReg, I2cBurst); if (SkI2cWait(pAC, IoC, I2C_READ) != 0) { w_print("%s\n", SKERR_I2C_E002MSG); } SK_IN32(IoC, B2_I2C_DATA, &Data); return(Data); } /* SkI2cRead */
/***************************************************************************** * * SkPflReadDword - Reads a dword from the parallel flash * * Description: * The function reads a dword from the specified address in the parallel flash. * * Returns: * The DWord read */ static SK_U32 SkPflReadDword( SK_AC *pAC, SK_IOC IoC, int Part, SK_U32 Addr) /* address in the parallel flash to read from */ { SK_U32 Val; Addr &= (1 << 20) - 1; Addr |= (2 << 24); /* bits 31..29 == 000: read access to information memory. */ /* bits 26..24 == 010: 32-bit access. */ Addr |= (Part << 30); SK_OUT32(IoC, FCU_MEM_CTRL, Addr); SK_PFL_WAIT_FINISH_RD(pAC, IoC); SK_IN32(IoC, FCU_RD_DATA, &Val); return (Val); }
/***************************************************************************** * * SkPflReadChipId - Reads parallel flash IDs * * Description: * This function reads the IDs of the parallel flash. * * Returns: * Nothing (parallel flash manufacturer and device ID in parameters) */ static void SkPflReadChipId( SK_AC *pAC, SK_IOC IoC, SK_U32 *pManId, SK_U16 *pDevId) { /* Put manufacturer and device ID into proper registers. */ SkPflCommand(pAC, IoC, -1, pAC->pfl.pPflDev->opcodes.OpReadManDev, 0); /* bits 31..29 == 001: read access to parallel flash register. */ /* bits 26..24 == 010: 32-bit access. */ /* bits 7..0: register address */ SK_OUT32(IoC, FCU_MEM_CTRL, BIT_29 | (2 << 24) | 0x18); SK_PFL_WAIT_FINISH_RD(pAC, IoC); SK_IN32(IoC, FCU_RD_DATA, pManId); *pManId = FL_SWAP32(*pManId); SK_OUT32(IoC, FCU_MEM_CTRL, BIT_29 | (2 << 24) | 0x1C); SK_PFL_WAIT_FINISH_RD(pAC, IoC); SK_IN16(IoC, FCU_RD_DATA, pDevId); *pDevId = FL_SWAP16(*pDevId); return; }
/***************************************************************************** * * FwCheckLinkMode - Check the firmware link state and link mode * * Description: * * Returns: * Nothing */ void FwCheckLinkMode( SK_AC *pAC, /* Pointer to adapter context */ SK_IOC IoC, /* IO context handle */ int Port) { SK_U16 PhyStat; SK_U32 PhyCtrl; PhyStat = 0x0; PhyCtrl = 0x0; pAC->GIni.GIDontInitPhy = SK_FALSE; if (pAC->UseLinkMaintenance == SK_TRUE) { /* Check if link is up */ SK_IN32(pAC->IoBase, MR_ADDR(Port, GPHY_CTRL), &PhyCtrl); if ((PhyCtrl & GPC_PHY_LINK_UP) == 0) { #ifdef MV_FW_SDK_LINK_MAINTENANCE_DEBUG printk("FwCheckLinkMode: No link on port %d\n", Port); #endif return; } else { #ifdef MV_FW_SDK_LINK_MAINTENANCE_DEBUG printk("FwCheckLinkMode: Link up on port %d\n", Port); #endif /* Check link state */ GM_IN16(IoC, Port, GM_GP_CTRL, &PhyStat); #ifdef MV_FW_SDK_LINK_MAINTENANCE_DEBUG printk("FwCheckLinkMode: GM_GP_CTRL: 0x%x\n", PhyStat); #endif if (pAC->DriverLinkStat != PhyStat) { #ifdef MV_FW_SDK_LINK_MAINTENANCE_DEBUG printk("FwCheckLinkMode: Link status changed\n"); printk("FwCheckLinkMode: pAC->DriverLinkStat: 0x%x\n", pAC->DriverLinkStat); #endif return; } /* Store link state */ pAC->DriverLinkStat = PhyStat; /* Enable link maintenance */ pAC->GIni.GIDontInitPhy = SK_TRUE; #ifdef MV_FW_SDK_LINK_MAINTENANCE_DEBUG printk("FwCheckLinkMode: Link match, GIDontInitPhy: %d\n", pAC->GIni.GIDontInitPhy); #endif } } else { #ifdef MV_FW_SDK_LINK_MAINTENANCE_DEBUG printk("FwCheckLinkMode: UseLinkMaintenance not set!\n"); #endif } return; } /* FwCheckLinkMode */
/* * read a sensors value (LM80 specific) * * This function reads a sensors value from the I2C sensor chip LM80. * The sensor is defined by its index into the sensors database in the struct * pAC points to. * * Returns 1 if the read is completed * 0 if the read must be continued (I2C Bus still allocated) */ int SkLm80ReadSensor( SK_AC *pAC, /* Adapter Context */ SK_IOC IoC, /* I/O Context needed in level 1 and 2 */ SK_SENSOR *pSen) /* Sensor to be read */ { SK_I32 Value; switch (pSen->SenState) { case SK_SEN_IDLE: /* Send address to ADDR register */ SK_I2C_CTL(IoC, I2C_READ, pSen->SenDev, I2C_025K_DEV, pSen->SenReg, 0); pSen->SenState = SK_SEN_VALUE ; BREAK_OR_WAIT(pAC, IoC, I2C_READ); case SK_SEN_VALUE: /* Read value from data register */ SK_IN32(IoC, B2_I2C_DATA, ((SK_U32 *)&Value)); Value &= 0xff; /* only least significant byte is valid */ /* Do NOT check the Value against the thresholds */ /* Checking is done in the calling instance */ if (pSen->SenType == SK_SEN_VOLT) { /* Voltage sensor */ pSen->SenValue = Value * SK_LM80_VT_LSB; pSen->SenState = SK_SEN_IDLE ; return(1); } if (pSen->SenType == SK_SEN_FAN) { if (Value != 0 && Value != 0xff) { /* Fan speed counter */ pSen->SenValue = SK_LM80_FAN_FAKTOR/Value; } else { /* Indicate Fan error */ pSen->SenValue = 0; } pSen->SenState = SK_SEN_IDLE ; return(1); } /* First: correct the value: it might be negative */ if ((Value & 0x80) != 0) { /* Value is negative */ Value = Value - 256; } /* We have a temperature sensor and need to get the signed extension. * For now we get the extension from the last reading, so in the normal * case we won't see flickering temperatures. */ pSen->SenValue = (Value * SK_LM80_TEMP_LSB) + (pSen->SenValue % SK_LM80_TEMP_LSB); /* Send address to ADDR register */ SK_I2C_CTL(IoC, I2C_READ, pSen->SenDev, I2C_025K_DEV, LM80_TEMP_CTRL, 0); pSen->SenState = SK_SEN_VALEXT ; BREAK_OR_WAIT(pAC, IoC, I2C_READ); case SK_SEN_VALEXT: /* Read value from data register */ SK_IN32(IoC, B2_I2C_DATA, ((SK_U32 *)&Value)); Value &= LM80_TEMP_LSB_9; /* only bit 7 is valid */ /* cut the LSB bit */ pSen->SenValue = ((pSen->SenValue / SK_LM80_TEMP_LSB) * SK_LM80_TEMP_LSB); if (pSen->SenValue < 0) { /* Value negative: The bit value must be subtracted */ pSen->SenValue -= ((Value >> 7) * SK_LM80_TEMPEXT_LSB); } else {