From ada516d88927cdb88b43f9c1b8307a9d8a494abc Mon Sep 17 00:00:00 2001 From: mehrabi Date: Sat, 1 Jan 2022 03:22:48 -0500 Subject: [PATCH] merge with abidi --- Plx/Plx.pro | 12 +- .../Exception/HonaAlreadyStartedException.h | 2 +- Plx/include/LowLevel/HonaLowLevelAPI.h | 6 +- Plx/include/LowLevel/HonaPacket.h | 2 +- Plx/src/LowLevel/HonaLowLevelAPI.cpp | 190 +-- Plx/src/LowLevel/HonaPacket.cpp | 13 + Plxlibrary/Aardvark.h | 952 +++++++++++++++ Plxlibrary/ConsFunc.h | 325 +++++ Plxlibrary/Eep_8000.h | 171 +++ Plxlibrary/I2cAaUsb.h | 281 +++++ Plxlibrary/Library/Obj_x86_64_64b/Aardvark.o | Bin 0 -> 23600 bytes Plxlibrary/Library/Obj_x86_64_64b/ConsFunc.o | Bin 0 -> 7032 bytes Plxlibrary/Library/Obj_x86_64_64b/Eep_8000.o | Bin 0 -> 8368 bytes Plxlibrary/Library/Obj_x86_64_64b/I2cAaUsb.o | Bin 0 -> 29104 bytes .../Library/Obj_x86_64_64b/MdioSpliceUsb.o | Bin 0 -> 12336 bytes Plxlibrary/Library/Obj_x86_64_64b/PlxApi.o | Bin 0 -> 50864 bytes .../Library/Obj_x86_64_64b/PlxApiDirect.o | Bin 0 -> 32112 bytes Plxlibrary/Library/Obj_x86_64_64b/PlxInit.o | Bin 0 -> 5176 bytes Plxlibrary/Library/Obj_x86_64_64b/PlxLists.o | Bin 0 -> 2072 bytes .../Library/Obj_x86_64_64b/PlxPci_9054_Func.o | Bin 0 -> 7016 bytes .../Library/Obj_x86_64_64b/SdbComPort.o | Bin 0 -> 8864 bytes Plxlibrary/Library/Obj_x86_64_64b/SpiFlash.o | Bin 0 -> 5792 bytes Plxlibrary/Library/libPlxApi.a | Bin 0 -> 200046 bytes Plxlibrary/Library/libPlxApi.so | Bin 0 -> 146816 bytes Plxlibrary/MdioSpliceUsb.h | 315 +++++ Plxlibrary/PciRegs.h | 345 ++++++ Plxlibrary/PciTypes.h | 388 ++++++ Plxlibrary/PexApi.h | 745 ++++++++++++ Plxlibrary/Plx.h | 122 ++ Plxlibrary/PlxApi.h | 73 ++ Plxlibrary/PlxApiDebug.h | 150 +++ Plxlibrary/PlxApiDirect.h | 346 ++++++ Plxlibrary/PlxDefCk.h | 84 ++ Plxlibrary/PlxInit.h | 103 ++ Plxlibrary/PlxIoctl.h | 293 +++++ Plxlibrary/PlxLists.h | 154 +++ Plxlibrary/PlxPci_9054_Func.h | 99 ++ Plxlibrary/PlxStat.h | 158 +++ Plxlibrary/PlxTypes.h | 1062 +++++++++++++++++ Plxlibrary/Plx_sysdep.h | 490 ++++++++ Plxlibrary/SdbComPort.h | 171 +++ Plxlibrary/SpiFlash.h | 192 +++ Test/MainWindow.cpp | 91 +- Test/MainWindow.h | 3 +- Test/MainWindow.ui | 115 +- Test/Test.pro | 12 +- 46 files changed, 7246 insertions(+), 219 deletions(-) create mode 100755 Plxlibrary/Aardvark.h create mode 100755 Plxlibrary/ConsFunc.h create mode 100755 Plxlibrary/Eep_8000.h create mode 100755 Plxlibrary/I2cAaUsb.h create mode 100755 Plxlibrary/Library/Obj_x86_64_64b/Aardvark.o create mode 100755 Plxlibrary/Library/Obj_x86_64_64b/ConsFunc.o create mode 100755 Plxlibrary/Library/Obj_x86_64_64b/Eep_8000.o create mode 100755 Plxlibrary/Library/Obj_x86_64_64b/I2cAaUsb.o create mode 100755 Plxlibrary/Library/Obj_x86_64_64b/MdioSpliceUsb.o create mode 100755 Plxlibrary/Library/Obj_x86_64_64b/PlxApi.o create mode 100755 Plxlibrary/Library/Obj_x86_64_64b/PlxApiDirect.o create mode 100755 Plxlibrary/Library/Obj_x86_64_64b/PlxInit.o create mode 100755 Plxlibrary/Library/Obj_x86_64_64b/PlxLists.o create mode 100755 Plxlibrary/Library/Obj_x86_64_64b/PlxPci_9054_Func.o create mode 100755 Plxlibrary/Library/Obj_x86_64_64b/SdbComPort.o create mode 100755 Plxlibrary/Library/Obj_x86_64_64b/SpiFlash.o create mode 100755 Plxlibrary/Library/libPlxApi.a create mode 100755 Plxlibrary/Library/libPlxApi.so create mode 100755 Plxlibrary/MdioSpliceUsb.h create mode 100755 Plxlibrary/PciRegs.h create mode 100755 Plxlibrary/PciTypes.h create mode 100755 Plxlibrary/PexApi.h create mode 100755 Plxlibrary/Plx.h create mode 100755 Plxlibrary/PlxApi.h create mode 100755 Plxlibrary/PlxApiDebug.h create mode 100755 Plxlibrary/PlxApiDirect.h create mode 100755 Plxlibrary/PlxDefCk.h create mode 100755 Plxlibrary/PlxInit.h create mode 100755 Plxlibrary/PlxIoctl.h create mode 100755 Plxlibrary/PlxLists.h create mode 100755 Plxlibrary/PlxPci_9054_Func.h create mode 100755 Plxlibrary/PlxStat.h create mode 100755 Plxlibrary/PlxTypes.h create mode 100755 Plxlibrary/Plx_sysdep.h create mode 100755 Plxlibrary/SdbComPort.h create mode 100755 Plxlibrary/SpiFlash.h diff --git a/Plx/Plx.pro b/Plx/Plx.pro index 9aab6b0..4a49cbc 100755 --- a/Plx/Plx.pro +++ b/Plx/Plx.pro @@ -32,12 +32,12 @@ unix { -unix:!macx: LIBS += -L$$PWD/../../Plxlibrary/Library/ -lPlxApi +unix:!macx: LIBS += -L$$PWD/../Plxlibrary/Library/ -lPlxApi -INCLUDEPATH += $$PWD/../../Plxlibrary/Library -DEPENDPATH += $$PWD/../../Plxlibrary/Library +INCLUDEPATH += $$PWD/../Plxlibrary/Library +DEPENDPATH += $$PWD/../Plxlibrary/Library -INCLUDEPATH += $$PWD/../../Plxlibrary -DEPENDPATH += $$PWD/../../Plxlibrary +INCLUDEPATH += $$PWD/../Plxlibrary +DEPENDPATH += $$PWD/../Plxlibrary -unix:!macx: PRE_TARGETDEPS += $$PWD/../../Plxlibrary/Library/libPlxApi.a +unix:!macx: PRE_TARGETDEPS += $$PWD/../Plxlibrary/Library/libPlxApi.a diff --git a/Plx/include/LowLevel/Exception/HonaAlreadyStartedException.h b/Plx/include/LowLevel/Exception/HonaAlreadyStartedException.h index 65ad341..a704414 100755 --- a/Plx/include/LowLevel/Exception/HonaAlreadyStartedException.h +++ b/Plx/include/LowLevel/Exception/HonaAlreadyStartedException.h @@ -15,7 +15,7 @@ public: virtual const char* what() const throw() { - return ""; + return "AlreadyStarted"; } }; diff --git a/Plx/include/LowLevel/HonaLowLevelAPI.h b/Plx/include/LowLevel/HonaLowLevelAPI.h index 43f2523..4af4350 100755 --- a/Plx/include/LowLevel/HonaLowLevelAPI.h +++ b/Plx/include/LowLevel/HonaLowLevelAPI.h @@ -3,7 +3,6 @@ #include #include #include -#include #include "LowLevel/Setting/Setting.h" #include "LowLevel/HonaPacket.h" @@ -74,9 +73,11 @@ private: HonaPacket tempHonaPacketIntS; HonaPacket tempHonaPacketResS; -public: quint64 toaStartBoard = 0; +public: + + HonaLowLevelAPI(QObject* parent = nullptr); ~HonaLowLevelAPI() { @@ -119,7 +120,6 @@ private: public: - signals: void lowLevelHonaData(QList honaPacketList, quint32 hsruLoss, quint32 Doa); diff --git a/Plx/include/LowLevel/HonaPacket.h b/Plx/include/LowLevel/HonaPacket.h index 1d73c3e..3fb0574 100755 --- a/Plx/include/LowLevel/HonaPacket.h +++ b/Plx/include/LowLevel/HonaPacket.h @@ -10,7 +10,7 @@ class HonaPacket { private: - qreal toaClock; + qreal toaClock = 1.0e7; honaPacketType m_PacketType; quint32 m_PacketNumber; quint64 m_Toa; diff --git a/Plx/src/LowLevel/HonaLowLevelAPI.cpp b/Plx/src/LowLevel/HonaLowLevelAPI.cpp index 2f7cdd2..f2f742d 100755 --- a/Plx/src/LowLevel/HonaLowLevelAPI.cpp +++ b/Plx/src/LowLevel/HonaLowLevelAPI.cpp @@ -2,8 +2,9 @@ #include #include "include/LowLevel/HonaLowLevelAPI.h" #include "include/Wrapper/PlxWrapper.h" + #include -#include +#include quint32 HonaLowLevelAPI::packetLenInt4; quint32 HonaLowLevelAPI::packetLenRes4; @@ -25,6 +26,7 @@ quint32 HonaLowLevelAPI::nextIntS; #define PLX_ID 0x9054 + /*************************************************************************************************/ HonaLowLevelAPI::HonaLowLevelAPI(QObject* parent) : QObject(parent) { @@ -35,6 +37,24 @@ HonaLowLevelAPI::HonaLowLevelAPI(QObject* parent) : QObject(parent) packetLenRes123C = 6; packetLenIntS = 7; packetLenResS = 7; + + nextInt4 = 0; + nextRes4 = 0; + nextSinglePulse = 0; + nextResS = 0; + nextInt123C = 0; + nextRes123C = 0; + nextIntS = 0; + + tempHonaPacketInt4 = HonaPacket(); + tempHonaPacketRes4 = HonaPacket(); + tempHonaPacketSinglePulse = HonaPacket(); + tempHonaPacketInt123C = HonaPacket(); + tempHonaPacketRes123C = HonaPacket(); + tempHonaPacketIntS = HonaPacket(); + tempHonaPacketResS = HonaPacket(); + + } /*************************************************************************************************/ @@ -42,6 +62,9 @@ void HonaLowLevelAPI::deviceReset() { if(!plxWrapper.deviceReset()) throw HonaException(); + + static const int64_t TICKS_1970 = 621355968000000000ll; + toaStartBoard = QDateTime::currentMSecsSinceEpoch() * 10000 + TICKS_1970; } /*************************************************************************************************/ @@ -158,7 +181,7 @@ void HonaLowLevelAPI::writeSettingToRegisters(HonaSettings& settings) /************************************************************************/ honaRegisterBuffer.insert(0,(honaRegisterBuffer.at(0) + - (settings.hiruSettings.threshold & 0x00000FFF))); + (settings.hiruSettings.threshold & 0x00000FFF))); honaRegisterBuffer.insert(1, settings.hsruSettings.honaInt123CTHR); honaRegisterBuffer.insert(2, settings.hsruSettings.honaRes123CTHR); @@ -225,16 +248,14 @@ void HonaLowLevelAPI::hsruReadThread() throw HonaException(); } - _hsruLoss += hsruParserInt123C(hsruReadHonaBuffer(honaReceivers::int123C), - honaPacketList); - _hsruLoss += hsruParserRes123C(hsruReadHonaBuffer(honaReceivers::res123C), - honaPacketList); + _hsruLoss += hsruParserInt123C(hsruReadHonaBuffer(honaReceivers::int123C), honaPacketList); + _hsruLoss += hsruParserRes123C(hsruReadHonaBuffer(honaReceivers::res123C), honaPacketList); _hsruLoss += hsruParserIntS(hsruReadHonaBuffer(honaReceivers::intS), honaPacketList); _hsruLoss += hsruParserResS(hsruReadHonaBuffer(honaReceivers::resS), honaPacketList); _hsruLoss += hsruParserInt4(hsruReadHonaBuffer(honaReceivers::int4), honaPacketList); _hsruLoss += hsruParserRes4(hsruReadHonaBuffer(honaReceivers::res4), honaPacketList); - _hsruLoss += hsruParserSinglePulse(hsruReadHonaBuffer(honaReceivers::singlePulse), - honaPacketList); + _hsruLoss += hsruParserSinglePulse(hsruReadHonaBuffer(honaReceivers::singlePulse),honaPacketList); + if(!plxWrapper.deviceClosePCIChannel()) { throw HonaException(); @@ -243,6 +264,7 @@ void HonaLowLevelAPI::hsruReadThread() { throw HonaException(); } + QThread::usleep(200000); _mutex.lock(); _hsruReadDone.wakeAll(); _hsruUpdateAck.wait(&_mutex); @@ -263,9 +285,6 @@ void HonaLowLevelAPI::hsruUpdateThread() quint32 Doa = 0; Doa = hiruGetDOA(); emit lowLevelHonaData(honaPacketList, _hsruLoss, Doa); - QThread::msleep(200); - // QDateTime time = QDateTime :: currentDateTime ();//Get the current time of the system - // QString str = time.toString ("yyyy-MM-dd hh: mm: ss: zzz ddd");//Set the display format _hsruUpdateAck.wakeAll(); } } @@ -314,6 +333,7 @@ quint32 HonaLowLevelAPI::hsruParserInt123C(const QVector& honaData, { if((honaData[Ind] & 0xFF000000) == 0x0F000000) { + tempHonaPacketInt123C = HonaPacket(); tempHonaPacketInt123C.setPacketType(honaPacketType::interrogationMode123C); packetLenInt123C = 6; tempHonaPacketInt123C.setPacketNumber(honaData[Ind] & 0x0000FFFF); @@ -321,7 +341,7 @@ quint32 HonaLowLevelAPI::hsruParserInt123C(const QVector& honaData, (lastPNInt123C + 1)) & (lastPNInt123C > 0)) { lossFound += - ((tempHonaPacketInt123C.getPacketNumber() - lastPNInt123C + 65536) % 65536 - 1); + ((tempHonaPacketInt123C.getPacketNumber() - lastPNInt123C + 65536) % 65536 - 1); } lastPNInt123C = tempHonaPacketInt123C.getPacketNumber(); if(nextInt123C > 0) @@ -336,8 +356,7 @@ quint32 HonaLowLevelAPI::hsruParserInt123C(const QVector& honaData, else if(((honaData[Ind] & 0xF0000000) == 0x20000000) && (nextInt123C == 2)) { tempHonaPacketInt123C.setToa((tempHonaPacketInt123C.getToa()) + - (static_cast(honaData[Ind] & 0x0000FFFF) << - 28)); + (static_cast(honaData[Ind] & 0x0000FFFF) <<28)); tempHonaPacketInt123C.setPa2((honaData[Ind] & 0x0FFF0000) >> 16); nextInt123C = 3; @@ -351,23 +370,16 @@ quint32 HonaLowLevelAPI::hsruParserInt123C(const QVector& honaData, else if(((honaData[Ind] & 0xF0000000) == 0x40000000) && (nextInt123C == 4)) { tempHonaPacketInt123C.setPa1(honaData[Ind] & 0x0000FFFF); - tempHonaPacketInt123C.setPa2(tempHonaPacketInt123C.getPa2() + - ((honaData[Ind] & 0x000F0000) >> 4)); - tempHonaPacketInt123C.setPa3(tempHonaPacketInt123C.getPa3() + - ((honaData[Ind] & 0x00F00000) >> 8)); + tempHonaPacketInt123C.setPa2(tempHonaPacketInt123C.getPa2() + ((honaData[Ind] & 0x000F0000) >> 4)); + tempHonaPacketInt123C.setPa3(tempHonaPacketInt123C.getPa3() + ((honaData[Ind] & 0x00F00000) >> 8)); nextInt123C = 5; } else if(((honaData[Ind] & 0xF0000000) == 0x50000000) && (nextInt123C == 5)) { - tempHonaPacketInt123C.setCodeM( - (static_cast(honaData[Ind] & 0x0000001F)) << 59); + tempHonaPacketInt123C.setCodeM((static_cast(honaData[Ind] & 0x0000001F)) << 59); tempHonaPacketInt123C.setCodeL(0); nextInt123C = 6; } - else if(honaData[Ind] == 0xEEEEEEEE) - { - break; - } if(nextInt123C == packetLenInt123C) { @@ -378,6 +390,9 @@ quint32 HonaLowLevelAPI::hsruParserInt123C(const QVector& honaData, } nextInt123C = 0; } + else if ( (honaData[Ind] & 0xFFFFFFFF) == 0xEEEEEEEE){ + break; + } } return lossFound; @@ -392,6 +407,7 @@ quint32 HonaLowLevelAPI::hsruParserRes123C(const QVector& honaData, { if((honaData[Ind] & 0xFF000000) == 0x0F000000) { + tempHonaPacketRes123C = HonaPacket(); tempHonaPacketRes123C.setPacketType(honaPacketType::responseMode123C); packetLenRes123C = 6; tempHonaPacketRes123C.setPacketNumber(honaData[Ind] & 0x0000FFFF); @@ -399,7 +415,7 @@ quint32 HonaLowLevelAPI::hsruParserRes123C(const QVector& honaData, (lastPNRes123C + 1)) & (lastPNRes123C > 0)) { lossFound += - ((tempHonaPacketRes123C.getPacketNumber() - lastPNRes123C + 65536) % 65536 - 1); + ((tempHonaPacketRes123C.getPacketNumber() - lastPNRes123C + 65536) % 65536 - 1); } lastPNRes123C = tempHonaPacketRes123C.getPacketNumber(); if(nextRes123C > 0) @@ -414,8 +430,7 @@ quint32 HonaLowLevelAPI::hsruParserRes123C(const QVector& honaData, else if(((honaData[Ind] & 0xF0000000) == 0x20000000) && (nextRes123C == 2)) { tempHonaPacketRes123C.setToa(tempHonaPacketRes123C.getToa() + - ((static_cast(honaData[Ind] & 0x0000FFFF)) << - 28)); + ((static_cast(honaData[Ind] & 0x0000FFFF)) << 28)); tempHonaPacketRes123C.setPa2((honaData[Ind] & 0x0FFF0000) >> 16); nextRes123C = 3; } @@ -430,23 +445,19 @@ quint32 HonaLowLevelAPI::hsruParserRes123C(const QVector& honaData, tempHonaPacketRes123C.setPa1(honaData[Ind] & 0x0000FFFF); tempHonaPacketRes123C.setPa2(tempHonaPacketRes123C.getPa2() + - ((honaData[Ind] & 0x000F0000) >> 4)); + ((honaData[Ind] & 0x000F0000) >> 4)); tempHonaPacketRes123C.setPa3(tempHonaPacketRes123C.getPa3() + - ((honaData[Ind] & 0x00F00000) >> 8)); + ((honaData[Ind] & 0x00F00000) >> 8)); nextRes123C = 5; } else if(((honaData[Ind] & 0xF0000000) == 0x50000000) && (nextRes123C == 5)) { tempHonaPacketRes123C.setCodeM( - (static_cast(honaData[Ind] & 0x00001FFF)) << 51); + (static_cast(honaData[Ind] & 0x00001FFF)) << 51); tempHonaPacketRes123C.setCodeL(0); nextRes123C = 6; } - else if(honaData[Ind] == 0xEEEEEEEE) - { - break; - } if(nextRes123C == packetLenRes123C) { @@ -457,6 +468,9 @@ quint32 HonaLowLevelAPI::hsruParserRes123C(const QVector& honaData, } nextRes123C = 0; } + else if ( (honaData[Ind] & 0xFFFFFFFF) == 0xEEEEEEEE){ + break; + } } return lossFound; } @@ -470,6 +484,7 @@ quint32 HonaLowLevelAPI::hsruParserIntS(const QVector& honaData, { if((honaData[Ind] & 0xFF000000) == 0x0F000000) { + tempHonaPacketIntS = HonaPacket(); qint32 TypeVal = (honaData[Ind] & 0x00F00000) >> 20; if(TypeVal == 2) { @@ -485,7 +500,7 @@ quint32 HonaLowLevelAPI::hsruParserIntS(const QVector& honaData, if((tempHonaPacketIntS.getPacketNumber() != (lastPNIntS + 1)) & (lastPNIntS > 0)) { lossFound += - ((tempHonaPacketIntS.getPacketNumber() - lastPNIntS + 65536) % 65536 - 1); + ((tempHonaPacketIntS.getPacketNumber() - lastPNIntS + 65536) % 65536 - 1); } lastPNIntS = tempHonaPacketIntS.getPacketNumber(); if(nextIntS > 0) @@ -500,8 +515,7 @@ quint32 HonaLowLevelAPI::hsruParserIntS(const QVector& honaData, else if(((honaData[Ind] & 0xF0000000) == 0x20000000) && (nextIntS == 2)) { tempHonaPacketIntS.setToa(tempHonaPacketIntS.getToa() + - ((static_cast(honaData[Ind] & 0x0000FFFF)) << - 28)); + ((static_cast(honaData[Ind] & 0x0000FFFF)) << 28)); tempHonaPacketIntS.setPa2((honaData[Ind] & 0x0FFF0000) >> 16); nextIntS = 3; } @@ -516,7 +530,7 @@ quint32 HonaLowLevelAPI::hsruParserIntS(const QVector& honaData, tempHonaPacketIntS.setPa1(honaData[Ind] & 0x0000FFFF); tempHonaPacketIntS.setPa2(tempHonaPacketIntS.getPa2() + ((honaData[Ind] & 0x000F0000))); tempHonaPacketIntS.setPa3(tempHonaPacketIntS.getPa3() + - ((honaData[Ind] & 0x00F00000) >> 4)); + ((honaData[Ind] & 0x00F00000) >> 4)); nextIntS = 5; } else if(((honaData[Ind] & 0xF0000000) == 0x50000000) && (nextIntS == 5)) @@ -528,7 +542,7 @@ quint32 HonaLowLevelAPI::hsruParserIntS(const QVector& honaData, else if(((honaData[Ind] & 0xF0000000) == 0x60000000) && (nextIntS == 6)) { tempHonaPacketIntS.setCodeM(tempHonaPacketIntS.getCodeM() + - ((static_cast(honaData[Ind] & 0x0FFFFFFF)) << 36)); + ((static_cast(honaData[Ind] & 0x0FFFFFFF)) << 36)); tempHonaPacketIntS.setCodeL(0); nextIntS = 7; } @@ -541,13 +555,9 @@ quint32 HonaLowLevelAPI::hsruParserIntS(const QVector& honaData, else if(((honaData[Ind] & 0xF0000000) == 0x80000000) && (nextIntS == 8)) { tempHonaPacketIntS.setCodeM(tempHonaPacketIntS.getCodeM() + - ((static_cast(honaData[Ind] & 0x0FFFFFFF)) << 36)); + ((static_cast(honaData[Ind] & 0x0FFFFFFF)) << 36)); nextIntS = 9; } - else if(honaData[Ind] == 0xEEEEEEEE) - { - break; - } if(nextIntS == packetLenIntS) { @@ -558,6 +568,9 @@ quint32 HonaLowLevelAPI::hsruParserIntS(const QVector& honaData, } nextIntS = 0; } + else if ( (honaData[Ind] & 0xFFFFFFFF) == 0xEEEEEEEE){ + break; + } } return lossFound; @@ -572,6 +585,7 @@ quint32 HonaLowLevelAPI::hsruParserResS(const QVector& honaData, { if((honaData[Ind] & 0xFF000000) == 0x0F000000) { + tempHonaPacketIntS = HonaPacket(); qint32 TypeVal = (honaData[Ind] & 0x00F00000) >> 20; if(TypeVal == 4) { @@ -587,7 +601,7 @@ quint32 HonaLowLevelAPI::hsruParserResS(const QVector& honaData, if((tempHonaPacketResS.getPacketNumber() != (lastPNResS + 1)) & (lastPNResS > 0)) { lossFound += - ((tempHonaPacketResS.getPacketNumber() - lastPNResS + 65536) % 65536 - 1); + ((tempHonaPacketResS.getPacketNumber() - lastPNResS + 65536) % 65536 - 1); } lastPNResS = tempHonaPacketResS.getPacketNumber(); if(nextResS > 0) @@ -602,8 +616,7 @@ quint32 HonaLowLevelAPI::hsruParserResS(const QVector& honaData, else if(((honaData[Ind] & 0xF0000000) == 0x20000000) && (nextResS == 2)) { tempHonaPacketResS.setToa(tempHonaPacketResS.getToa() + - ((static_cast(honaData[Ind] & 0x0000FFFF)) << - 28)); + ((static_cast(honaData[Ind] & 0x0000FFFF)) << 28)); tempHonaPacketResS.setPa2((honaData[Ind] & 0x0FFF0000) >> 16); nextResS = 3; } @@ -617,8 +630,7 @@ quint32 HonaLowLevelAPI::hsruParserResS(const QVector& honaData, { tempHonaPacketResS.setPa1(honaData[Ind] & 0x0000FFFF); tempHonaPacketResS.setPa2(tempHonaPacketResS.getPa2() + ((honaData[Ind] & 0x000F0000))); - tempHonaPacketResS.setPa3(tempHonaPacketResS.getPa3() + - ((honaData[Ind] & 0x00F00000) >> 4)); + tempHonaPacketResS.setPa3(tempHonaPacketResS.getPa3() +((honaData[Ind] & 0x00F00000) >> 4)); nextResS = 5; } else if(((honaData[Ind] & 0xF0000000) == 0x50000000) && (nextResS == 5)) @@ -630,7 +642,7 @@ quint32 HonaLowLevelAPI::hsruParserResS(const QVector& honaData, else if(((honaData[Ind] & 0xF0000000) == 0x60000000) && (nextResS == 6)) { tempHonaPacketResS.setCodeM(tempHonaPacketResS.getCodeM() + - ((static_cast(honaData[Ind] & 0x0FFFFFFF)) << 36)); + ((static_cast(honaData[Ind] & 0x0FFFFFFF)) << 36)); tempHonaPacketResS.setCodeL(0); nextResS = 7; } @@ -643,23 +655,21 @@ quint32 HonaLowLevelAPI::hsruParserResS(const QVector& honaData, else if(((honaData[Ind] & 0xF0000000) == 0x80000000) && (nextResS == 8)) { tempHonaPacketResS.setCodeM(tempHonaPacketResS.getCodeM() + - ((static_cast(honaData[Ind] & 0x0FFFFFFF)) << 36)); + ((static_cast(honaData[Ind] & 0x0FFFFFFF)) << 36)); nextResS = 9; } - else if(honaData[Ind] == 0xEEEEEEEE) - { - break; - } - if(nextResS == packetLenResS) { if(isValid(tempHonaPacketResS)) { - tempHonaPacketResS.setToa((tempHonaPacketResS.getToa() / 8) + toaStartBoard); + tempHonaPacketResS.setToa((tempHonaPacketResS.getToa() / 8) + toaStartBoard);; honaPacketList.append(tempHonaPacketResS); } nextResS = 0; } + else if ( (honaData[Ind] & 0xFFFFFFFF) == 0xEEEEEEEE){ + break; + } } return lossFound; @@ -675,13 +685,14 @@ quint32 HonaLowLevelAPI::hsruParserInt4(const QVector& honaData, { if((honaData[Ind] & 0xFF000000) == 0x0F000000) { + tempHonaPacketInt4 = HonaPacket(); tempHonaPacketInt4.setPacketType(honaPacketType::interrogationMode4); packetLenInt4 = 7; tempHonaPacketInt4.setPacketNumber(honaData[Ind] & 0x0000FFFF); if((tempHonaPacketInt4.getPacketNumber() != (lastPNInt4 + 1)) & (lastPNInt4 > 0)) { lossFound += - ((tempHonaPacketInt4.getPacketNumber() - lastPNInt4 + 65536) % 65536 - 1); + ((tempHonaPacketInt4.getPacketNumber() - lastPNInt4 + 65536) % 65536 - 1); } lastPNInt4 = tempHonaPacketInt4.getPacketNumber(); if(nextInt4 > 0) @@ -696,8 +707,7 @@ quint32 HonaLowLevelAPI::hsruParserInt4(const QVector& honaData, else if(((honaData[Ind] & 0xF0000000) == 0x20000000) && (nextInt4 == 2)) { tempHonaPacketInt4.setToa(tempHonaPacketInt4.getToa() + - ((static_cast(honaData[Ind] & 0x0000FFFF)) << - 28)); + ((static_cast(honaData[Ind] & 0x0000FFFF)) << 28)); tempHonaPacketInt4.setPa2((honaData[Ind] & 0x0FFF0000) >> 16); nextInt4 = 3; } @@ -711,9 +721,9 @@ quint32 HonaLowLevelAPI::hsruParserInt4(const QVector& honaData, { tempHonaPacketInt4.setPa1(honaData[Ind] & 0x0000FFFF); tempHonaPacketInt4.setPa2(tempHonaPacketInt4.getPa2() + - ((honaData[Ind] & 0x000F0000) >> 4)); + ((honaData[Ind] & 0x000F0000) >> 4)); tempHonaPacketInt4.setPa3(tempHonaPacketInt4.getPa3() + - ((honaData[Ind] & 0x00F00000) >> 8)); + ((honaData[Ind] & 0x00F00000) >> 8)); nextInt4 = 5; } else if(((honaData[Ind] & 0xF0000000) == 0x50000000) && (nextInt4 == 5)) @@ -726,14 +736,10 @@ quint32 HonaLowLevelAPI::hsruParserInt4(const QVector& honaData, { tempHonaPacketInt4.setPa4(honaData[Ind] & 0x0000FFFF); tempHonaPacketInt4.setCodeL(tempHonaPacketInt4.getCodeL() + - ((static_cast(honaData[Ind] & 0x000F0000)) << 12)); + (static_cast(honaData[Ind] & 0x000F0000) << 12)); tempHonaPacketInt4.setm4Status(static_cast((honaData[Ind] & 0x0F000000) >> 20)); nextInt4 = 7; } - else if(honaData[Ind] == 0xEEEEEEEE) - { - break; - } if(nextInt4 == packetLenInt4) { @@ -744,6 +750,9 @@ quint32 HonaLowLevelAPI::hsruParserInt4(const QVector& honaData, } nextInt4 = 0; } + else if ( (honaData[Ind] & 0xFFFFFFFF) == 0xEEEEEEEE){ + break; + } } return lossFound; @@ -758,13 +767,14 @@ quint32 HonaLowLevelAPI::hsruParserRes4(const QVector& honaData, { if((honaData[Ind] & 0xFF000000) == 0x0F000000) { + tempHonaPacketInt4 = HonaPacket(); tempHonaPacketRes4.setPacketType(honaPacketType::responseMode4); packetLenRes4 = 5; tempHonaPacketRes4.setPacketNumber(honaData[Ind] & 0x0000FFFF); if((tempHonaPacketRes4.getPacketNumber() != (lastPNRes4 + 1)) & (lastPNRes4 > 0)) { lossFound += - ((tempHonaPacketRes4.getPacketNumber() - lastPNRes4 + 65536) % 65536 - 1); + ((tempHonaPacketRes4.getPacketNumber() - lastPNRes4 + 65536) % 65536 - 1); } lastPNRes4 = tempHonaPacketRes4.getPacketNumber(); if(nextRes4 > 0) @@ -779,8 +789,7 @@ quint32 HonaLowLevelAPI::hsruParserRes4(const QVector& honaData, else if(((honaData[Ind] & 0xF0000000) == 0x20000000) && (nextRes4 == 2)) { tempHonaPacketRes4.setToa(tempHonaPacketRes4.getToa() + - (static_cast(honaData[Ind] & 0x0000FFFF) << - 28)); + (static_cast(honaData[Ind] & 0x0000FFFF) << 28)); tempHonaPacketRes4.setPa2((honaData[Ind] & 0x0FFF0000) >> 16); nextRes4 = 3; } @@ -794,15 +803,11 @@ quint32 HonaLowLevelAPI::hsruParserRes4(const QVector& honaData, { tempHonaPacketRes4.setPa1(honaData[Ind] & 0x0000FFFF); tempHonaPacketRes4.setPa2(tempHonaPacketRes4.getPa2() + - ((honaData[Ind] & 0x000F0000) >> 4)); + ((honaData[Ind] & 0x000F0000) >> 4)); tempHonaPacketRes4.setPa3(tempHonaPacketRes4.getPa3() + - ((honaData[Ind] & 0x00F00000) >> 8)); + ((honaData[Ind] & 0x00F00000) >> 8)); nextRes4 = 5; } - else if(honaData[Ind] == 0xEEEEEEEE) - { - break; - } if(nextRes4 == packetLenRes4) { @@ -813,6 +818,9 @@ quint32 HonaLowLevelAPI::hsruParserRes4(const QVector& honaData, } nextRes4 = 0; } + else if ( (honaData[Ind] & 0xFFFFFFFF) == 0xEEEEEEEE){ + break; + } } return lossFound; @@ -827,6 +835,7 @@ quint32 HonaLowLevelAPI::hsruParserSinglePulse(const QVector& honaData, { if((honaData[Ind] & 0xFF000000) == 0x0F000000) { + tempHonaPacketSinglePulse = HonaPacket(); tempHonaPacketSinglePulse.setPacketType(honaPacketType::singlePulseMode4); packetLenSinglePulse = 5; tempHonaPacketSinglePulse.setPacketNumber(honaData[Ind] & 0x0000FFFF); @@ -834,9 +843,9 @@ quint32 HonaLowLevelAPI::hsruParserSinglePulse(const QVector& honaData, (lastPNSinglePulse + 1)) & (lastPNSinglePulse > 0)) { lossFound += - ((tempHonaPacketSinglePulse.getPacketNumber() - lastPNSinglePulse + 65536) % - 65536 - - 1); + ((tempHonaPacketSinglePulse.getPacketNumber() - lastPNSinglePulse + 65536) % + 65536 - + 1); } lastPNSinglePulse = tempHonaPacketSinglePulse.getPacketNumber(); if(nextSinglePulse > 0) @@ -846,14 +855,14 @@ quint32 HonaLowLevelAPI::hsruParserSinglePulse(const QVector& honaData, else if(((honaData[Ind] & 0xF0000000) == 0x10000000) && (nextSinglePulse == 1)) { tempHonaPacketSinglePulse.setToa(static_cast(honaData[Ind] & - 0x0FFFFFFF)); + 0x0FFFFFFF)); nextSinglePulse = 2; } else if(((honaData[Ind] & 0xF0000000) == 0x20000000) && (nextSinglePulse == 2)) { tempHonaPacketSinglePulse.setToa(tempHonaPacketSinglePulse.getToa() + - ((static_cast(honaData[Ind] & - 0x0000FFFF)) << 28)); + ((static_cast(honaData[Ind] & + 0x0000FFFF)) << 28)); tempHonaPacketSinglePulse.setPa2((honaData[Ind] & 0x0FFF0000) >> 16); nextSinglePulse = 3; } @@ -867,26 +876,25 @@ quint32 HonaLowLevelAPI::hsruParserSinglePulse(const QVector& honaData, { tempHonaPacketSinglePulse.setPa1(honaData[Ind] & 0x0000FFFF); tempHonaPacketSinglePulse.setPa2(tempHonaPacketSinglePulse.getPa2() + - ((honaData[Ind] & 0x000F0000) >> 4)); + ((honaData[Ind] & 0x000F0000) >> 4)); tempHonaPacketSinglePulse.setPa3(tempHonaPacketSinglePulse.getPa3() + - ((honaData[Ind] & 0x00F00000) >> 8)); + ((honaData[Ind] & 0x00F00000) >> 8)); nextSinglePulse = 5; } - else if(honaData[Ind] == 0xEEEEEEEE) - { - break; - } if(nextSinglePulse == packetLenSinglePulse) { if(isValid(tempHonaPacketSinglePulse)) { tempHonaPacketSinglePulse.setToa( - (tempHonaPacketSinglePulse.getToa() / 6) + toaStartBoard); + (tempHonaPacketSinglePulse.getToa() / 6) + toaStartBoard); honaPacketList.append(tempHonaPacketSinglePulse); } nextSinglePulse = 0; } + else if ( (honaData[Ind] & 0xFFFFFFFF) == 0xEEEEEEEE){ + break; + } } return lossFound; @@ -921,10 +929,6 @@ QVector HonaLowLevelAPI::hsruReadHonaBuffer(honaReceivers receiver) throw HonaException(); } - qDebug() << " hsruReadHonaBuffer receiver "<< receiver; - for(auto i = 0 ; i < 10; i++) - qDebug() << "[" << i << "] " << "0x" << QString::number(honaData[i], 16); - qDebug() << "------------------------------------------------------------"; return honaData; } diff --git a/Plx/src/LowLevel/HonaPacket.cpp b/Plx/src/LowLevel/HonaPacket.cpp index 7ef7edf..2b0e1ad 100755 --- a/Plx/src/LowLevel/HonaPacket.cpp +++ b/Plx/src/LowLevel/HonaPacket.cpp @@ -2,6 +2,19 @@ HonaPacket::HonaPacket() { + m_PacketType = honaPacketType::singlePulseMode4; + m_PacketNumber = 0; + m_Toa = 0; + m_Doa = 0; + m_Pa1 = 0; + m_Pa2 = 0; + m_Pa3 = 0; + m_Pa4 = 0; + m_Code = 0; + m_CodeL = 0; + m_CodeM = 0; + m4Status = 0; + } /*************************************************************************************************/ diff --git a/Plxlibrary/Aardvark.h b/Plxlibrary/Aardvark.h new file mode 100755 index 0000000..5399879 --- /dev/null +++ b/Plxlibrary/Aardvark.h @@ -0,0 +1,952 @@ +/*========================================================================= +| Aardvark Interface Library +|-------------------------------------------------------------------------- +| Copyright (c) 2002-2019 Total Phase, Inc. +| All rights reserved. +| www.totalphase.com +| +| Redistribution and use in source and binary forms, with or without +| modification, are permitted provided that the following conditions +| are met: +| +| - Redistributions of source code must retain the above copyright +| notice, this list of conditions and the following disclaimer. +| +| - Redistributions in binary form must reproduce the above copyright +| notice, this list of conditions and the following disclaimer in the +| documentation and/or other materials provided with the distribution. +| +| - Neither the name of Total Phase, Inc. nor the names of its +| contributors may be used to endorse or promote products derived from +| this software without specific prior written permission. +| +| THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +| "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +| LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS +| FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE +| COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, +| INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, +| BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +| LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +| CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +| LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN +| ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +| POSSIBILITY OF SUCH DAMAGE. +|-------------------------------------------------------------------------- +| To access Aardvark devices through the API: +| +| 1) Use one of the following shared objects: +| aardvark.so -- Linux shared object +| aardvark.dll -- Windows dynamic link library +| +| 2) Along with one of the following language modules: +| aardvark.c/h -- C/C++ API header file and interface module +| aardvark_py.py -- Python API +| aardvark.bas -- Visual Basic 6 API +| aardvark.cs -- C# .NET source +| aardvark_net.dll -- Compiled .NET binding + ========================================================================*/ + + +#ifndef __aardvark_h__ +#define __aardvark_h__ + +#ifdef __cplusplus +extern "C" { +#endif + + +/*========================================================================= +| TYPEDEFS + ========================================================================*/ +#ifndef TOTALPHASE_DATA_TYPES +#define TOTALPHASE_DATA_TYPES + +#ifndef _MSC_VER +/* C99-compliant compilers (GCC) */ +#include +typedef uint8_t u08; +typedef uint16_t u16; +typedef uint32_t u32; +typedef uint64_t u64; +typedef int8_t s08; +typedef int16_t s16; +typedef int32_t s32; +typedef int64_t s64; + +#else +/* Microsoft compilers (Visual C++) */ +typedef unsigned __int8 u08; +typedef unsigned __int16 u16; +typedef unsigned __int32 u32; +typedef unsigned __int64 u64; +typedef signed __int8 s08; +typedef signed __int16 s16; +typedef signed __int32 s32; +typedef signed __int64 s64; + +#endif /* __MSC_VER */ + +typedef float f32; +typedef double f64; + +#endif /* TOTALPHASE_DATA_TYPES */ + + +/*========================================================================= +| DEBUG + ========================================================================*/ +/* Set the following macro to '1' for debugging */ +#define AA_DEBUG 0 + + +/*========================================================================= +| VERSION + ========================================================================*/ +#define AA_HEADER_VERSION 0x0528 /* v5.40 */ + + +/*========================================================================= +| STATUS CODES + ========================================================================*/ +/* + * All API functions return an integer which is the result of the + * transaction, or a status code if negative. The status codes are + * defined as follows: + */ +enum AardvarkStatus { + /* General codes (0 to -99) */ + AA_OK = 0, + AA_UNABLE_TO_LOAD_LIBRARY = -1, + AA_UNABLE_TO_LOAD_DRIVER = -2, + AA_UNABLE_TO_LOAD_FUNCTION = -3, + AA_INCOMPATIBLE_LIBRARY = -4, + AA_INCOMPATIBLE_DEVICE = -5, + AA_COMMUNICATION_ERROR = -6, + AA_UNABLE_TO_OPEN = -7, + AA_UNABLE_TO_CLOSE = -8, + AA_INVALID_HANDLE = -9, + AA_CONFIG_ERROR = -10, + + /* I2C codes (-100 to -199) */ + AA_I2C_NOT_AVAILABLE = -100, + AA_I2C_NOT_ENABLED = -101, + AA_I2C_READ_ERROR = -102, + AA_I2C_WRITE_ERROR = -103, + AA_I2C_SLAVE_BAD_CONFIG = -104, + AA_I2C_SLAVE_READ_ERROR = -105, + AA_I2C_SLAVE_TIMEOUT = -106, + AA_I2C_DROPPED_EXCESS_BYTES = -107, + AA_I2C_BUS_ALREADY_FREE = -108, + + /* SPI codes (-200 to -299) */ + AA_SPI_NOT_AVAILABLE = -200, + AA_SPI_NOT_ENABLED = -201, + AA_SPI_WRITE_ERROR = -202, + AA_SPI_SLAVE_READ_ERROR = -203, + AA_SPI_SLAVE_TIMEOUT = -204, + AA_SPI_DROPPED_EXCESS_BYTES = -205, + + /* GPIO codes (-400 to -499) */ + AA_GPIO_NOT_AVAILABLE = -400, + + /* I2C bus monitor codes (-500 to -599) */ + AA_I2C_MONITOR_NOT_AVAILABLE = -500, + AA_I2C_MONITOR_NOT_ENABLED = -501 +}; +#ifndef __cplusplus +typedef enum AardvarkStatus AardvarkStatus; +#endif + + +/*========================================================================= +| GENERAL TYPE DEFINITIONS + ========================================================================*/ +/* Aardvark handle type definition */ +typedef int Aardvark; + +/* + * Deprecated type definitions. + * + * These are only for use with legacy code and + * should not be used for new development. + */ +typedef u08 aa_u08; + +typedef u16 aa_u16; + +typedef u32 aa_u32; + +typedef s08 aa_s08; + +typedef s16 aa_s16; + +typedef s32 aa_s32; + +/* + * Aardvark version matrix. + * + * This matrix describes the various version dependencies + * of Aardvark components. It can be used to determine + * which component caused an incompatibility error. + * + * All version numbers are of the format: + * (major << 8) | minor + * + * ex. v1.20 would be encoded as: 0x0114 + */ +struct AardvarkVersion { + /* Software, firmware, and hardware versions. */ + u16 software; + u16 firmware; + u16 hardware; + + /* Firmware requires that software must be >= this version. */ + u16 sw_req_by_fw; + + /* Software requires that firmware must be >= this version. */ + u16 fw_req_by_sw; + + /* Software requires that the API interface must be >= this version. */ + u16 api_req_by_sw; +}; +#ifndef __cplusplus +typedef struct AardvarkVersion AardvarkVersion; +#endif + + +/*========================================================================= +| GENERAL API + ========================================================================*/ +/* + * Get a list of ports to which Aardvark devices are attached. + * + * nelem = maximum number of elements to return + * devices = array into which the port numbers are returned + * + * Each element of the array is written with the port number. + * Devices that are in-use are ORed with AA_PORT_NOT_FREE (0x8000). + * + * ex. devices are attached to ports 0, 1, 2 + * ports 0 and 2 are available, and port 1 is in-use. + * array => 0x0000, 0x8001, 0x0002 + * + * If the array is NULL, it is not filled with any values. + * If there are more devices than the array size, only the + * first nmemb port numbers will be written into the array. + * + * Returns the number of devices found, regardless of the + * array size. + */ +#define AA_PORT_NOT_FREE 0x8000 +int aa_find_devices ( + int num_devices, + u16 * devices +); + + +/* + * Get a list of ports to which Aardvark devices are attached. + * + * This function is the same as aa_find_devices() except that + * it returns the unique IDs of each Aardvark device. The IDs + * are guaranteed to be non-zero if valid. + * + * The IDs are the unsigned integer representation of the 10-digit + * serial numbers. + */ +int aa_find_devices_ext ( + int num_devices, + u16 * devices, + int num_ids, + u32 * unique_ids +); + + +/* + * Open the Aardvark port. + * + * The port number is a zero-indexed integer. + * + * The port number is the same as that obtained from the + * aa_find_devices() function above. + * + * Returns an Aardvark handle, which is guaranteed to be + * greater than zero if it is valid. + * + * This function is recommended for use in simple applications + * where extended information is not required. For more complex + * applications, the use of aa_open_ext() is recommended. + */ +Aardvark aa_open ( + int port_number +); + + +/* + * Open the Aardvark port, returning extended information + * in the supplied structure. Behavior is otherwise identical + * to aa_open() above. If 0 is passed as the pointer to the + * structure, this function is exactly equivalent to aa_open(). + * + * The structure is zeroed before the open is attempted. + * It is filled with whatever information is available. + * + * For example, if the firmware version is not filled, then + * the device could not be queried for its version number. + * + * This function is recommended for use in complex applications + * where extended information is required. For more simple + * applications, the use of aa_open() is recommended. + */ +struct AardvarkExt { + /* Version matrix */ + AardvarkVersion version; + + /* Features of this device. */ + int features; +}; +#ifndef __cplusplus +typedef struct AardvarkExt AardvarkExt; +#endif + +Aardvark aa_open_ext ( + int port_number, + AardvarkExt * aa_ext +); + + +/* Close the Aardvark port. */ +int aa_close ( + Aardvark aardvark +); + + +/* + * Return the port for this Aardvark handle. + * + * The port number is a zero-indexed integer. + */ +int aa_port ( + Aardvark aardvark +); + + +/* + * Return the device features as a bit-mask of values, or + * an error code if the handle is not valid. + */ +#define AA_FEATURE_SPI 0x00000001 +#define AA_FEATURE_I2C 0x00000002 +#define AA_FEATURE_GPIO 0x00000008 +#define AA_FEATURE_I2C_MONITOR 0x00000010 +int aa_features ( + Aardvark aardvark +); + + +/* + * Return the unique ID for this Aardvark adapter. + * IDs are guaranteed to be non-zero if valid. + * The ID is the unsigned integer representation of the + * 10-digit serial number. + */ +u32 aa_unique_id ( + Aardvark aardvark +); + + +/* + * Return the status string for the given status code. + * If the code is not valid or the library function cannot + * be loaded, return a NULL string. + */ +const char * aa_status_string ( + int status +); + + +/* + * Enable logging to a file. The handle must be standard file + * descriptor. In C, a file descriptor can be obtained by using + * the ANSI C function "open" or by using the function "fileno" + * on a FILE* stream. A FILE* stream can be obtained using "fopen" + * or can correspond to the common "stdout" or "stderr" -- + * available when including stdlib.h + */ +#define AA_LOG_STDOUT 1 +#define AA_LOG_STDERR 2 +int aa_log ( + Aardvark aardvark, + int level, + int handle +); + + +/* + * Return the version matrix for the device attached to the + * given handle. If the handle is 0 or invalid, only the + * software and required api versions are set. + */ +int aa_version ( + Aardvark aardvark, + AardvarkVersion * version +); + + +/* + * Configure the device by enabling/disabling I2C, SPI, and + * GPIO functions. + */ +enum AardvarkConfig { + AA_CONFIG_GPIO_ONLY = 0x00, + AA_CONFIG_SPI_GPIO = 0x01, + AA_CONFIG_GPIO_I2C = 0x02, + AA_CONFIG_SPI_I2C = 0x03, + AA_CONFIG_QUERY = 0x80 +}; +#ifndef __cplusplus +typedef enum AardvarkConfig AardvarkConfig; +#endif + +#define AA_CONFIG_SPI_MASK 0x00000001 +#define AA_CONFIG_I2C_MASK 0x00000002 +int aa_configure ( + Aardvark aardvark, + AardvarkConfig config +); + + +/* + * Configure the target power pins. + * This is only supported on hardware versions >= 2.00 + */ +#define AA_TARGET_POWER_NONE 0x00 +#define AA_TARGET_POWER_BOTH 0x03 +#define AA_TARGET_POWER_QUERY 0x80 +int aa_target_power ( + Aardvark aardvark, + u08 power_mask +); + + +/* + * Sleep for the specified number of milliseconds + * Accuracy depends on the operating system scheduler + * Returns the number of milliseconds slept + */ +u32 aa_sleep_ms ( + u32 milliseconds +); + + + +/*========================================================================= +| ASYNC MESSAGE POLLING + ========================================================================*/ +/* + * Polling function to check if there are any asynchronous + * messages pending for processing. The function takes a timeout + * value in units of milliseconds. If the timeout is < 0, the + * function will block until data is received. If the timeout is 0, + * the function will perform a non-blocking check. + */ +#define AA_ASYNC_NO_DATA 0x00000000 +#define AA_ASYNC_I2C_READ 0x00000001 +#define AA_ASYNC_I2C_WRITE 0x00000002 +#define AA_ASYNC_SPI 0x00000004 +#define AA_ASYNC_I2C_MONITOR 0x00000008 +int aa_async_poll ( + Aardvark aardvark, + int timeout +); + + + +/*========================================================================= +| I2C API + ========================================================================*/ +/* Free the I2C bus. */ +int aa_i2c_free_bus ( + Aardvark aardvark +); + + +/* + * Set the I2C bit rate in kilohertz. If a zero is passed as the + * bitrate, the bitrate is unchanged and the current bitrate is + * returned. + */ +int aa_i2c_bitrate ( + Aardvark aardvark, + int bitrate_khz +); + + +/* + * Set the bus lock timeout. If a zero is passed as the timeout, + * the timeout is unchanged and the current timeout is returned. + */ +int aa_i2c_bus_timeout ( + Aardvark aardvark, + u16 timeout_ms +); + + +enum AardvarkI2cFlags { + AA_I2C_NO_FLAGS = 0x00, + AA_I2C_10_BIT_ADDR = 0x01, + AA_I2C_COMBINED_FMT = 0x02, + AA_I2C_NO_STOP = 0x04, + AA_I2C_SIZED_READ = 0x10, + AA_I2C_SIZED_READ_EXTRA1 = 0x20 +}; +#ifndef __cplusplus +typedef enum AardvarkI2cFlags AardvarkI2cFlags; +#endif + +/* Read a stream of bytes from the I2C slave device. */ +int aa_i2c_read ( + Aardvark aardvark, + u16 slave_addr, + AardvarkI2cFlags flags, + u16 num_bytes, + u08 * data_in +); + + +enum AardvarkI2cStatus { + AA_I2C_STATUS_OK = 0, + AA_I2C_STATUS_BUS_ERROR = 1, + AA_I2C_STATUS_SLA_ACK = 2, + AA_I2C_STATUS_SLA_NACK = 3, + AA_I2C_STATUS_DATA_NACK = 4, + AA_I2C_STATUS_ARB_LOST = 5, + AA_I2C_STATUS_BUS_LOCKED = 6, + AA_I2C_STATUS_LAST_DATA_ACK = 7 +}; +#ifndef __cplusplus +typedef enum AardvarkI2cStatus AardvarkI2cStatus; +#endif + +/* + * Read a stream of bytes from the I2C slave device. + * This API function returns the number of bytes read into + * the num_read variable. The return value of the function + * is a status code. + */ +int aa_i2c_read_ext ( + Aardvark aardvark, + u16 slave_addr, + AardvarkI2cFlags flags, + u16 num_bytes, + u08 * data_in, + u16 * num_read +); + + +/* Write a stream of bytes to the I2C slave device. */ +int aa_i2c_write ( + Aardvark aardvark, + u16 slave_addr, + AardvarkI2cFlags flags, + u16 num_bytes, + const u08 * data_out +); + + +/* + * Write a stream of bytes to the I2C slave device. + * This API function returns the number of bytes written into + * the num_written variable. The return value of the function + * is a status code. + */ +int aa_i2c_write_ext ( + Aardvark aardvark, + u16 slave_addr, + AardvarkI2cFlags flags, + u16 num_bytes, + const u08 * data_out, + u16 * num_written +); + + +/* + * Do an atomic write+read to an I2C slave device by first + * writing a stream of bytes to the I2C slave device and then + * reading a stream of bytes back from the same slave device. + * This API function returns the number of bytes written into + * the num_written variable and the number of bytes read into + * the num_read variable. The return value of the function is + * the status given as (read_status << 8) | (write_status). + */ +int aa_i2c_write_read ( + Aardvark aardvark, + u16 slave_addr, + AardvarkI2cFlags flags, + u16 out_num_bytes, + const u08 * out_data, + u16 * num_written, + u16 in_num_bytes, + u08 * in_data, + u16 * num_read +); + + +/* Enable/Disable the Aardvark as an I2C slave device */ +int aa_i2c_slave_enable ( + Aardvark aardvark, + u08 addr, + u16 maxTxBytes, + u16 maxRxBytes +); + + +int aa_i2c_slave_disable ( + Aardvark aardvark +); + + +/* + * Set the slave response in the event the Aardvark is put + * into slave mode and contacted by a Master. + */ +int aa_i2c_slave_set_response ( + Aardvark aardvark, + u08 num_bytes, + const u08 * data_out +); + + +/* + * Return number of bytes written from a previous + * Aardvark->I2C_master transmission. Since the transmission is + * happening asynchronously with respect to the PC host + * software, there could be responses queued up from many + * previous write transactions. + */ +int aa_i2c_slave_write_stats ( + Aardvark aardvark +); + + +/* Read the bytes from an I2C slave reception */ +int aa_i2c_slave_read ( + Aardvark aardvark, + u08 * addr, + u16 num_bytes, + u08 * data_in +); + + +/* Extended functions that return status code */ +int aa_i2c_slave_write_stats_ext ( + Aardvark aardvark, + u16 * num_written +); + + +int aa_i2c_slave_read_ext ( + Aardvark aardvark, + u08 * addr, + u16 num_bytes, + u08 * data_in, + u16 * num_read +); + + +/* + * Enable the I2C bus monitor + * This disables all other functions on the Aardvark adapter + */ +int aa_i2c_monitor_enable ( + Aardvark aardvark +); + + +/* Disable the I2C bus monitor */ +int aa_i2c_monitor_disable ( + Aardvark aardvark +); + + +/* Read the data collected by the bus monitor */ +#define AA_I2C_MONITOR_DATA 0x00ff +#define AA_I2C_MONITOR_NACK 0x0100 +#define AA_I2C_MONITOR_CMD_START 0xff00 +#define AA_I2C_MONITOR_CMD_STOP 0xff01 +int aa_i2c_monitor_read ( + Aardvark aardvark, + u16 num_bytes, + u16 * data +); + + +/* + * Configure the I2C pullup resistors. + * This is only supported on hardware versions >= 2.00 + */ +#define AA_I2C_PULLUP_NONE 0x00 +#define AA_I2C_PULLUP_BOTH 0x03 +#define AA_I2C_PULLUP_QUERY 0x80 +int aa_i2c_pullup ( + Aardvark aardvark, + u08 pullup_mask +); + + + +/*========================================================================= +| SPI API + ========================================================================*/ +/* + * Set the SPI bit rate in kilohertz. If a zero is passed as the + * bitrate, the bitrate is unchanged and the current bitrate is + * returned. + */ +int aa_spi_bitrate ( + Aardvark aardvark, + int bitrate_khz +); + + +/* + * These configuration parameters specify how to clock the + * bits that are sent and received on the Aardvark SPI + * interface. + * + * The polarity option specifies which transition + * constitutes the leading edge and which transition is the + * falling edge. For example, AA_SPI_POL_RISING_FALLING + * would configure the SPI to idle the SCK clock line low. + * The clock would then transition low-to-high on the + * leading edge and high-to-low on the trailing edge. + * + * The phase option determines whether to sample or setup on + * the leading edge. For example, AA_SPI_PHASE_SAMPLE_SETUP + * would configure the SPI to sample on the leading edge and + * setup on the trailing edge. + * + * The bitorder option is used to indicate whether LSB or + * MSB is shifted first. + * + * See the diagrams in the Aardvark datasheet for + * more details. + */ +enum AardvarkSpiPolarity { + AA_SPI_POL_RISING_FALLING = 0, + AA_SPI_POL_FALLING_RISING = 1 +}; +#ifndef __cplusplus +typedef enum AardvarkSpiPolarity AardvarkSpiPolarity; +#endif + +enum AardvarkSpiPhase { + AA_SPI_PHASE_SAMPLE_SETUP = 0, + AA_SPI_PHASE_SETUP_SAMPLE = 1 +}; +#ifndef __cplusplus +typedef enum AardvarkSpiPhase AardvarkSpiPhase; +#endif + +enum AardvarkSpiBitorder { + AA_SPI_BITORDER_MSB = 0, + AA_SPI_BITORDER_LSB = 1 +}; +#ifndef __cplusplus +typedef enum AardvarkSpiBitorder AardvarkSpiBitorder; +#endif + +/* Configure the SPI master or slave interface */ +int aa_spi_configure ( + Aardvark aardvark, + AardvarkSpiPolarity polarity, + AardvarkSpiPhase phase, + AardvarkSpiBitorder bitorder +); + + +/* Write a stream of bytes to the downstream SPI slave device. */ +int aa_spi_write ( + Aardvark aardvark, + u16 out_num_bytes, + const u08 * data_out, + u16 in_num_bytes, + u08 * data_in +); + + +/* Enable/Disable the Aardvark as an SPI slave device */ +int aa_spi_slave_enable ( + Aardvark aardvark +); + + +int aa_spi_slave_disable ( + Aardvark aardvark +); + + +/* + * Set the slave response in the event the Aardvark is put + * into slave mode and contacted by a Master. + */ +int aa_spi_slave_set_response ( + Aardvark aardvark, + u08 num_bytes, + const u08 * data_out +); + + +/* Read the bytes from an SPI slave reception */ +int aa_spi_slave_read ( + Aardvark aardvark, + u16 num_bytes, + u08 * data_in +); + + +/* + * Change the output polarity on the SS line. + * + * Note: When configured as an SPI slave, the Aardvark will + * always be setup with SS as active low. Hence this function + * only affects the SPI master functions on the Aardvark. + */ +enum AardvarkSpiSSPolarity { + AA_SPI_SS_ACTIVE_LOW = 0, + AA_SPI_SS_ACTIVE_HIGH = 1 +}; +#ifndef __cplusplus +typedef enum AardvarkSpiSSPolarity AardvarkSpiSSPolarity; +#endif + +int aa_spi_master_ss_polarity ( + Aardvark aardvark, + AardvarkSpiSSPolarity polarity +); + + + +/*========================================================================= +| GPIO API + ========================================================================*/ +/* + * The following enumerated type maps the named lines on the + * Aardvark I2C/SPI line to bit positions in the GPIO API. + * All GPIO API functions will index these lines through an + * 8-bit masked value. Thus, each bit position in the mask + * can be referred back its corresponding line through the + * enumerated type. + */ +enum AardvarkGpioBits { + AA_GPIO_SCL = 0x01, + AA_GPIO_SDA = 0x02, + AA_GPIO_MISO = 0x04, + AA_GPIO_SCK = 0x08, + AA_GPIO_MOSI = 0x10, + AA_GPIO_SS = 0x20 +}; +#ifndef __cplusplus +typedef enum AardvarkGpioBits AardvarkGpioBits; +#endif + +/* + * Configure the GPIO, specifying the direction of each bit. + * + * A call to this function will not change the value of the pullup + * mask in the Aardvark. This is illustrated by the following + * example: + * (1) Direction mask is first set to 0x00 + * (2) Pullup is set to 0x01 + * (3) Direction mask is set to 0x01 + * (4) Direction mask is later set back to 0x00. + * + * The pullup will be active after (4). + * + * On Aardvark power-up, the default value of the direction + * mask is 0x00. + */ +#define AA_GPIO_DIR_INPUT 0 +#define AA_GPIO_DIR_OUTPUT 1 +int aa_gpio_direction ( + Aardvark aardvark, + u08 direction_mask +); + + +/* + * Enable an internal pullup on any of the GPIO input lines. + * + * Note: If a line is configured as an output, the pullup bit + * for that line will be ignored, though that pullup bit will + * be cached in case the line is later configured as an input. + * + * By default the pullup mask is 0x00. + */ +#define AA_GPIO_PULLUP_OFF 0 +#define AA_GPIO_PULLUP_ON 1 +int aa_gpio_pullup ( + Aardvark aardvark, + u08 pullup_mask +); + + +/* + * Read the current digital values on the GPIO input lines. + * + * The bits will be ordered as described by AA_GPIO_BITS. If a + * line is configured as an output, its corresponding bit + * position in the mask will be undefined. + */ +int aa_gpio_get ( + Aardvark aardvark +); + + +/* + * Set the outputs on the GPIO lines. + * + * Note: If a line is configured as an input, it will not be + * affected by this call, but the output value for that line + * will be cached in the event that the line is later + * configured as an output. + */ +int aa_gpio_set ( + Aardvark aardvark, + u08 value +); + + +/* + * Block until there is a change on the GPIO input lines. + * Pins configured as outputs will be ignored. + * + * The function will return either when a change has occurred or + * the timeout expires. The timeout, specified in millisecods, has + * a precision of ~16 ms. The maximum allowable timeout is + * approximately 4 seconds. If the timeout expires, this function + * will return the current state of the GPIO lines. + * + * This function will return immediately with the current value + * of the GPIO lines for the first invocation after any of the + * following functions are called: aa_configure, + * aa_gpio_direction, or aa_gpio_pullup. + * + * If the function aa_gpio_get is called before calling + * aa_gpio_change, aa_gpio_change will only register any changes + * from the value last returned by aa_gpio_get. + */ +int aa_gpio_change ( + Aardvark aardvark, + u16 timeout +); + + + + +#ifdef __cplusplus +} +#endif + +#endif /* __aardvark_h__ */ diff --git a/Plxlibrary/ConsFunc.h b/Plxlibrary/ConsFunc.h new file mode 100755 index 0000000..5c431d7 --- /dev/null +++ b/Plxlibrary/ConsFunc.h @@ -0,0 +1,325 @@ +#ifndef _CONSFUNC_H +#define _CONSFUNC_H + +/******************************************************************************* + * Copyright 2013-2016 Avago Technologies + * Copyright (c) 2009 to 2012 PLX Technology Inc. All rights reserved. + * + * This software is available to you under a choice of one of two + * licenses. You may choose to be licensed under the terms of the GNU + * General Public License (GPL) Version 2, available from the file + * COPYING in the main directorY of this source tree, or the + * BSD license below: + * + * Redistribution and use in source and binary forms, with or + * without modification, are permitted provided that the following + * conditions are met: + * + * - Redistributions of source code must retain the above + * copyright notice, this list of conditions and the following + * disclaimer. + * + * - Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + ******************************************************************************/ + +/****************************************************************************** + * + * File Name: + * + * ConsFunc.h + * + * Description: + * + * Header file for the Console functions + * + * Revision History: + * + * 04-01-16 : PLX SDK v7.30 + * + ******************************************************************************/ + + +#if defined(_WIN32) || defined(_WIN64) + #include + #include + #include + #define PLX_MSWINDOWS +#elif defined(PLX_LINUX) + #include + #include + #include + #include + #include + #include + #include +#elif defined(PLX_DOS) + #include + #include + #include + #include + #include +#endif + + + + +/************************************* + * Definitions + ************************************/ +#if defined(PLX_MSWINDOWS) + + #define Plx_sleep Sleep + #define Plx_strcmp strcmp + #define Plx_strcasecmp stricmp + #define Plx_strncasecmp strnicmp + #define Cons_clear Plx_clrscr + #define Cons_fflush fflush + #define Cons_flushinp() FlushConsoleInputBuffer(GetStdHandle(STD_INPUT_HANDLE)) + #define Cons_fputs Plx_fputs + #define Cons_kbhit _kbhit + #define Cons_getch _getch + #define Cons_puts puts + #define Cons_putchar putchar + #define Cons_scanf scanf + #define Cons_printf Plx_printf + +#elif defined(PLX_LINUX) + + #define Plx_sleep(arg) usleep((arg) * 1000) + #define Plx_strcmp strcmp + #define Plx_strcasecmp strcasecmp + #define Plx_strncasecmp strncasecmp + #define Cons_clear Plx_clrscr + #define Cons_fflush fflush + #define Cons_flushinp do {while (Plx_kbhit()) Plx_getch();} while (0) + #define Cons_fputs Plx_fputs + #define Cons_kbhit Plx_kbhit + #define Cons_getch Plx_getch + #define Cons_puts puts + #define Cons_putchar putchar + #define Cons_scanf scanf + #define Cons_printf Plx_printf + +#elif defined(PLX_DOS) + + #define Plx_sleep(arg) usleep((arg) * 1000) + #define Plx_strcmp strcmp + #define Plx_strcasecmp strcasecmp + #define Plx_strncasecmp strncasecmp + #define Cons_clear clrscr + #define Cons_fflush fflush + #define Cons_flushinp() do {while (kbhit()) getch();} while (0) + #define Cons_fputs Plx_fputs + #define Cons_kbhit kbhit + #define Cons_getch getch + #define Cons_puts puts + #define Cons_putchar putchar + #define Cons_scanf scanf + #define Cons_printf Plx_printf + +#endif + + +#if !defined(min) + #define min(a, b) (((a) < (b)) ? (a) : (b)) +#endif + + +/****************************************************************** + * A 64-bit HEX value (0xFFFF FFFF FFFF FFFF) requires 20 decimal + * digits or 22 octal digits. The following constant defines the + * buffer size used to hold an ANSI string converted from a + * 64-bit HEX value. + *****************************************************************/ +#define MAX_DECIMAL_BUFFER_SIZE 30 + +#define DEFAULT_SCREEN_SIZE 25 // Default lines to display before halting, if enabled +#define SCREEN_THROTTLE_OFFSET 2 // Num lines to offset for halting + +#define _Pause \ + do \ + { \ + Cons_printf(" -- Press any key to continue --"); \ + Cons_getch(); \ + Cons_printf("\r \r"); \ + } \ + while(0) + + +#define _PauseWithExit \ + do \ + { \ + Cons_printf(" -- Press any key to continue or ESC to exit --"); \ + if (Cons_getch() == 27) \ + { \ + Cons_printf("\r \n"); \ + ConsoleEnd(); \ + exit(0); \ + } \ + Cons_printf("\r \r"); \ + } \ + while(0) + +// Standard key codes +#define CONS_KEY_NULL '\0' +#define CONS_KEY_ESCAPE 27 +#define CONS_KEY_NEWLINE '\n' +#define CONS_KEY_CARRIAGE_RET '\r' +#define CONS_KEY_TAB '\t' +#define CONS_KEY_BACKSPACE '\b' + +// 1st extended key code +#if defined(PLX_LINUX) + #define CONS_KEY_EXT_CODE 91 + #define CONS_KEY_KEYPAD_CODE 79 +#elif defined(PLX_MSWINDOWS) + #define CONS_KEY_EXT_CODE 224 + #define CONS_KEY_KEYPAD_CODE 1 // For code compatability, not actually used +#elif defined(PLX_DOS) + #define CONS_KEY_EXT_CODE 0 + #define CONS_KEY_KEYPAD_CODE 1 // For code compatability, not actually used +#endif + +// Extended key codes +#if defined(PLX_LINUX) + #define CONS_KEY_EXT_BACKSPACE 127 + #define CONS_KEY_ARROW_UP 65 + #define CONS_KEY_ARROW_DOWN 66 + #define CONS_KEY_ARROW_LEFT 68 + #define CONS_KEY_ARROW_RIGHT 67 + #define CONS_KEY_HOME 49 + #define CONS_KEY_HOME_XTERM 72 // Code different in GUI terminal + #define CONS_KEY_END 70 + #define CONS_KEY_END_XTERM 52 // Code different in GUI terminal + #define CONS_KEY_INSERT 50 + #define CONS_KEY_DELETE 51 + #define CONS_KEY_PAGE_UP 53 + #define CONS_KEY_PAGE_DOWN 54 +#else + #define CONS_KEY_EXT_BACKSPACE 127 + #define CONS_KEY_ARROW_UP 72 + #define CONS_KEY_ARROW_DOWN 80 + #define CONS_KEY_ARROW_LEFT 75 + #define CONS_KEY_ARROW_RIGHT 77 + #define CONS_KEY_HOME 71 + #define CONS_KEY_HOME_XTERM 254 // Added for code compatability + #define CONS_KEY_END 79 + #define CONS_KEY_END_XTERM 253 // Added for code compatability + #define CONS_KEY_INSERT 82 + #define CONS_KEY_DELETE 83 + #define CONS_KEY_PAGE_UP 73 + #define CONS_KEY_PAGE_DOWN 81 +#endif + +// Preset cursor sizes/types +#define CONS_CURSOR_DISABLED 0 +#define CONS_CURSOR_UNDERLINE 20 +#define CONS_CURSOR_INSERT 70 +#define CONS_CURSOR_DEFAULT CONS_CURSOR_UNDERLINE + + + + +/************************************* + * Functions + ************************************/ +void +ConsoleInitialize( + void + ); + +void +ConsoleEnd( + void + ); + +unsigned short +ConsoleScreenHeightSet( + unsigned short NumLines + ); + +unsigned short +ConsoleScreenHeightGet( + void + ); + +void +ConsoleCursorPropertiesSet( + int size + ); + +unsigned char +ConsoleIoThrottleGet( + void + ); + +void +ConsoleIoThrottleSet( + unsigned char bEnable + ); + +void +ConsoleIoThrottleReset( + void + ); + +void +ConsoleIoThrottleLock( + unsigned char bLock + ); + +void +ConsoleIoIncrementLine( + void + ); + +void +ConsoleIoOutputDisable( + unsigned char bEnable + ); + +int +Plx_fputs( + const char *string, + FILE *stream + ); + +int +Plx_printf( + const char *format, + ... + ); + +void +Plx_clrscr( + void + ); + +// Linux-specific functions +#if defined(PLX_LINUX) +int +Plx_kbhit( + void + ); + +int +Plx_getch( + void + ); +#endif + + + +#endif diff --git a/Plxlibrary/Eep_8000.h b/Plxlibrary/Eep_8000.h new file mode 100755 index 0000000..96b0d7d --- /dev/null +++ b/Plxlibrary/Eep_8000.h @@ -0,0 +1,171 @@ +#ifndef __EEP_8000_H +#define __EEP_8000_H + +/******************************************************************************* + * Copyright 2013-2015 Avago Technologies + * Copyright (c) 2009 to 2012 PLX Technology Inc. All rights reserved. + * + * This software is available to you under a choice of one of two + * licenses. You may choose to be licensed under the terms of the GNU + * General Public License (GPL) Version 2, available from the file + * COPYING in the main directorY of this source tree, or the + * BSD license below: + * + * Redistribution and use in source and binary forms, with or + * without modification, are permitted provided that the following + * conditions are met: + * + * - Redistributions of source code must retain the above + * copyright notice, this list of conditions and the following + * disclaimer. + * + * - Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + ******************************************************************************/ + +/****************************************************************************** + * + * File Name: + * + * Eep_8000.h + * + * Description: + * + * The include file for 8000-series EEPROM support functions + * + * Revision History: + * + * 08-01-11 : PLX SDK v6.50 + * + ******************************************************************************/ + + +#include "PlxTypes.h" + + +#ifdef __cplusplus +extern "C" { +#endif + + + + +/********************************************** +* Definitions +**********************************************/ +#define CONST_CRC_XOR_VALUE 0xDB710641 // Constant used in CRC calculations + +// PLX 8000-series EEPROM definitions +#define PLX8000_EE_CMD_READ 3 +#define PLX8000_EE_CMD_READ_STATUS 5 +#define PLX8000_EE_CMD_WRITE_ENABLE 6 +#define PLX8000_EE_CMD_WRITE_DISABLE 4 +#define PLX8000_EE_CMD_WRITE 2 +#define PLX8000_EE_CMD_WRITE_STATUS 1 + + + + +/********************************************** +* Functions +**********************************************/ +PLX_STATUS +Plx8000_EepromPresent( + PLX_DEVICE_OBJECT *pdx, + U8 *pStatus + ); + +PLX_STATUS +Plx8000_EepromGetAddressWidth( + PLX_DEVICE_OBJECT *pdx, + U8 *pWidth + ); + +PLX_STATUS +Plx8000_EepromSetAddressWidth( + PLX_DEVICE_OBJECT *pdx, + U8 width + ); + +PLX_STATUS +Plx8000_EepromCrcGet( + PLX_DEVICE_OBJECT *pdx, + U32 *pCrc, + U8 *pCrcStatus + ); + +PLX_STATUS +Plx8000_EepromCrcUpdate( + PLX_DEVICE_OBJECT *pdx, + U32 *pCrc, + BOOLEAN bUpdateEeprom + ); + +PLX_STATUS +Plx8000_EepromReadByOffset( + PLX_DEVICE_OBJECT *pdx, + U32 offset, + U32 *pValue + ); + +PLX_STATUS +Plx8000_EepromWriteByOffset( + PLX_DEVICE_OBJECT *pdx, + U32 offset, + U32 value + ); + +PLX_STATUS +Plx8000_EepromReadByOffset_16( + PLX_DEVICE_OBJECT *pdx, + U32 offset, + U16 *pValue + ); + +PLX_STATUS +Plx8000_EepromWriteByOffset_16( + PLX_DEVICE_OBJECT *pdx, + U32 offset, + U16 value + ); + +BOOLEAN +Plx8000_EepromWaitIdle( + PLX_DEVICE_OBJECT *pdx + ); + +BOOLEAN +Plx8000_EepromSendCommand( + PLX_DEVICE_OBJECT *pdx, + U32 command + ); + +VOID +Plx8000_EepromComputeNextCrc( + U32 *pCrc, + U32 NextEepromValue + ); + +U16 +Plx8000_EepromGetCtrlOffset( + PLX_DEVICE_OBJECT *pdx + ); + + + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/Plxlibrary/I2cAaUsb.h b/Plxlibrary/I2cAaUsb.h new file mode 100755 index 0000000..a7fc4ef --- /dev/null +++ b/Plxlibrary/I2cAaUsb.h @@ -0,0 +1,281 @@ +#ifndef __I2C_AA_USB_H +#define __I2C_AA_USB_H + +/******************************************************************************* + * Copyright 2013-2018 Avago Technologies + * Copyright (c) 2009 to 2012 PLX Technology Inc. All rights reserved. + * + * This software is available to you under a choice of one of two + * licenses. You may choose to be licensed under the terms of the GNU + * General Public License (GPL) Version 2, available from the file + * COPYING in the main directorY of this source tree, or the + * BSD license below: + * + * Redistribution and use in source and binary forms, with or + * without modification, are permitted provided that the following + * conditions are met: + * + * - Redistributions of source code must retain the above + * copyright notice, this list of conditions and the following + * disclaimer. + * + * - Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + ******************************************************************************/ + +/****************************************************************************** + * + * File Name: + * + * I2cAaUsb.h + * + * Description: + * + * The PLX API support function prototypes for Aardark I2C interface + * + * Revision: + * + * 01-01-18 : PLX SDK v8.00 + * + ******************************************************************************/ + + +#include "PlxIoctl.h" + + +#ifdef __cplusplus +extern "C" { +#endif + + + + +/****************************************** + * Definitions + ******************************************/ +#define I2C_MAX_DEVICES 10 // Max number of I2C USB devices supported +#define I2C_MAX_NT_PORTS 2 // Max number of NT ports in single switch +#define I2C_DEFAULT_CLOCK_RATE 100 // I2C default clock rate in Khz +#define I2C_CMD_REG_READ 0x04 // I2C read command code +#define I2C_CMD_REG_WRITE 0x03 // I2C write command code +#define I2C_CMD_ERROR ((U32)-1) // Reserved command value to denote error +#define I2C_CMD_SKIP ((U32)-2) // Reserved command value to denote skip operation +#define I2C_RETRY_MAX_COUNT 3 // On error, max retry count +#define I2C_RETRY_DELAY_MS 300 // Delay in ms to wait before command retry +#define I2C_HIGH_ADDR_OFFSET 0x2CC // Register to contain high address bits +#define I2C_HIGH_ADDR_INIT 0xFF + +// Various addressing modes, which vary between chips +#define I2C_ADDR_MODE_STD 0 // Standard (ports only) +#define I2C_ADDR_MODE_NON_STD 1 // Non-standard +#define I2C_ADDR_MODE_FULL 2 // Full +#define I2C_ADDR_MODE_NTV 2 // NT-Virtual +#define I2C_ADDR_MODE_NTL 1 // NT-Link +#define I2C_ADDR_MODE_NT_P2P 1 // NT parent P2P +#define I2C_ADDR_MODE_DMA 3 // DMA & DMA RAM +#define I2C_ADDR_MODE_ALUT 3 // ALUT + +#define I2C_PEX_BASE_ADDR_MASK 0xFF800000 // PEX region base address mask +#define I2C_PEX_MAX_OFFSET_MASK 0x007FFFFF // Max I2C addressing (23 bits) + + + + +/****************************************** + * PLX Device Selection Functions + *****************************************/ +PLX_STATUS +PlxI2c_I2cGetPorts( + PLX_API_MODE ApiMode, + U32 *pI2cPorts + ); + +PLX_STATUS +PlxI2c_DeviceOpen( + PLX_DEVICE_OBJECT *pDevice + ); + +PLX_STATUS +PlxI2c_DeviceClose( + PLX_DEVICE_OBJECT *pDevice + ); + +PLX_STATUS +PlxI2c_DeviceFindEx( + PLX_DEVICE_KEY *pKey, + U16 DeviceNumber, + PLX_MODE_PROP *pModeProp + ); + + +/****************************************** + * Query for Information Functions + *****************************************/ +PLX_STATUS +PlxI2c_I2cVersion( + U16 I2cPort, + PLX_VERSION *pVersion + ); + + +/****************************************** + * Device-specific Register Access Functions + *****************************************/ +U32 +PlxI2c_PlxRegisterRead( + PLX_DEVICE_OBJECT *pDevice, + U32 offset, + PLX_STATUS *pStatus, + BOOLEAN bAdjustForPort, + U16 bRetryOnError + ); + +PLX_STATUS +PlxI2c_PlxRegisterWrite( + PLX_DEVICE_OBJECT *pDevice, + U32 offset, + U32 value, + BOOLEAN bAdjustForPort + ); + + +/****************************************** + * Serial EEPROM Access Functions + *****************************************/ +PLX_STATUS +PlxI2c_EepromPresent( + PLX_DEVICE_OBJECT *pDevice, + PLX_EEPROM_STATUS *pStatus + ); + +PLX_STATUS +PlxI2c_EepromProbe( + PLX_DEVICE_OBJECT *pDevice, + BOOLEAN *pFlag + ); + +PLX_STATUS +PlxI2c_EepromGetAddressWidth( + PLX_DEVICE_OBJECT *pDevice, + U8 *pWidth + ); + +PLX_STATUS +PlxI2c_EepromSetAddressWidth( + PLX_DEVICE_OBJECT *pDevice, + U8 width + ); + +PLX_STATUS +PlxI2c_EepromCrcUpdate( + PLX_DEVICE_OBJECT *pDevice, + U32 *pCrc, + BOOLEAN bUpdateEeprom + ); + +PLX_STATUS +PlxI2c_EepromCrcGet( + PLX_DEVICE_OBJECT *pDevice, + U32 *pCrc, + U8 *pCrcStatus + ); + +PLX_STATUS +PlxI2c_EepromReadByOffset( + PLX_DEVICE_OBJECT *pDevice, + U32 offset, + U32 *pValue + ); + +PLX_STATUS +PlxI2c_EepromWriteByOffset( + PLX_DEVICE_OBJECT *pDevice, + U32 offset, + U32 value + ); + +PLX_STATUS +PlxI2c_EepromReadByOffset_16( + PLX_DEVICE_OBJECT *pDevice, + U32 offset, + U16 *pValue + ); + +PLX_STATUS +PlxI2c_EepromWriteByOffset_16( + PLX_DEVICE_OBJECT *pDevice, + U32 offset, + U16 value + ); + + +/****************************************** + * Multi-VS Functions + *****************************************/ +PLX_STATUS +PlxI2c_MH_GetProperties( + PLX_DEVICE_OBJECT *pDevice, + PLX_MULTI_HOST_PROP *pMHProp + ); + +PLX_STATUS +PlxI2c_MH_MigrateDsPorts( + PLX_DEVICE_OBJECT *pDevice, + U16 VS_Source, + U16 VS_Dest, + U32 DsPortMask, + BOOLEAN bResetSrc + ); + + +/****************************************** + * Private Support Functions + *****************************************/ +U32 +PlxI2c_GenerateCommand( + PLX_DEVICE_OBJECT *pDevice, + U8 I2cOperation, + U32 Address, + BOOLEAN bAdjustForPort + ); + +BOOLEAN +PlxI2c_Driver_Connect( + PLX_DEVICE_OBJECT *pDevice, + PLX_MODE_PROP *pModeProp + ); + +S32 +PlxI2c_Dispatch_IoControl( + PLX_DEVICE_OBJECT *pDevice, + U32 IoControlCode, + PLX_PARAMS *pIoBuffer, + U32 Size + ); + +PLX_STATUS +PlxI2c_ProbeSwitch( + PLX_DEVICE_OBJECT *pDevice, + PLX_DEVICE_KEY *pKey, + U16 DeviceNumber, + U16 *pNumMatched + ); + + + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/Plxlibrary/Library/Obj_x86_64_64b/Aardvark.o b/Plxlibrary/Library/Obj_x86_64_64b/Aardvark.o new file mode 100755 index 0000000000000000000000000000000000000000..513caa4d40a4a06be4ebf4be64f51541d6f898c6 GIT binary patch literal 23600 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 literal 0 HcmV?d00001 diff --git a/Plxlibrary/Library/Obj_x86_64_64b/ConsFunc.o b/Plxlibrary/Library/Obj_x86_64_64b/ConsFunc.o new file mode 100755 index 0000000000000000000000000000000000000000..0c7bdba269206f857b54b1a2e91a2664dd01ab76 GIT binary patch literal 7032 zcmb_hZ){sv6~B(t)g-B3*oqoxSzqbvlCZ|uO$FWBfn7Vvi{!RuO<}MM$8nw$tB##L zKdU*BV1Nd!NL16bwaO6f7^7qB%sJ=X zYu~=cpWsNo_uSw8opbIz_m8iWZ}&ud8(c0X#KpeIYAt~>HovN-2T2Vwg?ZUOm3#lQ zkV^TKwbO)RTc3KnEl@dg&j4d1dZ}?k2lVL0h~^2D_2TPSk$0$E*r1$h)MjHJrHY?G zL@z}(&xqdLLiEBt`qa6$h1A?>j645HC>CEOODUGJHc0X3D5V1B?}d4`M@sLlOb>y%T3PL*A$t)y`~bGhx^W%KzkV0iZY^;sGgO$z;o1_BlR z;M*r)cvAkSwc`K;%F)>oO^p`cq>SjLh!zXH7pSC^Ttri$jB0*;c0e1_i__X17y#iB zfCsdo(izc)0DTtFdE7EnBUaKt;|^u$rG%%8!cUjbVN! z!2^WTDL;P9PYlo_fQtMKQhtV%&H-%#lanI`a0N`O#-B zO*vhi9u5Ywq8ArzSC^lDNjVeIl*JR&ruE+w8t5;+yGJkH+6`yXBledOEp?&K)4fof zq0HGkhwt6~(hfU?BWCM`dDZ% z^cZbRIGpzVz}Ir|FUs0U@Xcret9F61ZG(rocAtb`K6`Kp8LYZK)uJ)bkASgWJgNOz z!TP9nh3XmYD%4R}h3iz$Xg8srE?cmBr!}-!I%l+2s*h?a)j!nyR6nl;ss5=Jqxz&a zMD@$s1k|@}or~Z!Q0@u*U0e;zCcnfA_v@u;4ZC1P?ORVd^d}tV!E;BzL!@|>&kpvb zK0B?Q0FX|jUVQ)bF|fl+vK6>QN zi*SqvwRL2ZY5dIMD*HZ!sSoN?3oiYEMP+&r?n&k6;mWqA!dubO2JpkqhbyeVv{@rx zd^XCVZXhChwh1WIW%qAo%JeGe(~Eywe1RZ-eDso^n%Ca{s8U(Qk{KgmqI=fWrS8a? zhT0J`jeK5BWDlrTPEF>rRytcSHmdF6b~TkV1(GY|H>%KV|8hI>9xtS=PPGem?F#k( zA}bi{3x^+6JN670vQ|NTz}M~bcLlyspl0CdO@5z$bEgf{_#2^wWny?q^zGck8W<}h z=7tXnexsnco_v_O_P4rLw=DO}!O=pSHPmCGcqI2HPN?wkyJpaXlbmC%NvGu!~%Wy+(qu|H}2x z@fxw~T&HUqbi^9*Dgi+qMTHOD$55}pzFu$ZOhdo7>}q(f$=kZ!>*;Oo0C*d>BcH?x zdE2JkeMtOCleaBIT)kNb?ilA@03H3!Hf;B{&A208^>Aav+cC8);`KL}P2P?^uL@qa zlj+XpZ+JVx5&$v5{3Q29bcSpvy*fqq0<= zd&w6S?jf;@ZntuSC#PV(T@oMmA<4ajH&!k9)EKU}3sA9d1ddlf;v%xZzs7N>NQD0} zXdz#;1s_T7s&_J}7H)P|RhJbv^T^Gr?q(mW>ayalo`f3u6sclXHT)o{cg8);aoj^r zakJ%4h?M}j8)hs-MEU{8#U4*^!q1=kj4*nY87-hP69h`-8*?eyyoAf1F zyl*%YkEXLmI0s*fI}-bCWO!iA%vn~(h~|=e9nh|VHBqoQ7)uoLM$E{Lq_d+AXPjZv zBk6o%IAbthH0;MBfW;;nNiJjbWJiR$J82q5RyWe4V^*JmVWPXXhobRay}i482I2#u z?a`h%OXreShQ;G~E0NqAPmb-4rxNMRQa*Nr51cPV2^Y+K&WxG43B$C~MqcXb&!(+( zB9ng75aj-xNCA$5d#Hi3ZI$`3kza~SIjnl<&%zAHjjV-PuQ|RwO|i`Wcrs(=lP1d_ z$XmuZLuBvpSlVJ%a@4RAmSutl@kq-X86#;C2|ANwEN_kEV3AU(Od&tUOd~Nuohewk zJWK5})0P40OIimejJTD{d+9(GS|#-Yb$;pgiTj#rAn6B3U35qR2xi+Sy< zgMUZD@qQA1e!+3{y+OiPVq!oLzYjiw|5XW>_rs`!%lz+2c)R51ISH5d$vKXH7Py@f z{}qXkePTS9C0rhVfZxl`@sCUR{gR)jBwQZMP!d?4XIiSNaLAXwp>Q{=f@!tt#k@LmaD zC*iJT&;Swn5$EVz97i*Jn+QKIbKIG?OA>#h#Q$v_|8GeAO%nf_gsT$%p@hrp>%I#} zAkOhLa~#JnkLMJz?Yw;obTKb{FQFiRJ$wYdUdkK3tpu)uj)HmPTbtUOsjT7RjS+L; zle|6Rz~^{-zXLzU+oE5@Epz;NUJLvRZ_hh$@vi)h0~hZ~VJG~EcjdbdzIa!9r27hO z#Jh5h0~hZ{;ZOKKh6+f=$>;l?{s;{HfZ?SbmZn1=1bw^Ry#GGQi{VWfJghdmceNW9ZXq{}pcU82%mhc*kITybENhXOCPIQ3tv1v>)Pu zzmH@|#QcT*F6cwuFL6-4!R_%oNETry>PMhc=rV83oj+-*+sPdR6sgWUtK42Ct6Cw( zFOW%4(5KTr$nCE?0y^!#3ARh^pX2n;pxU{{{nG>=VK4U2Qn7)?{QOS|7x}qe0ockV l?2+c&I{>kpXaKU+F)_z<7=BkTW#561ACT|bRkd{5{}(amD9-=@ literal 0 HcmV?d00001 diff --git a/Plxlibrary/Library/Obj_x86_64_64b/Eep_8000.o b/Plxlibrary/Library/Obj_x86_64_64b/Eep_8000.o new file mode 100755 index 0000000000000000000000000000000000000000..ff7aab2f3b388173c34a0e6e1af1bd15d24a7722 GIT binary patch literal 8368 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 literal 0 HcmV?d00001 diff --git a/Plxlibrary/Library/Obj_x86_64_64b/MdioSpliceUsb.o b/Plxlibrary/Library/Obj_x86_64_64b/MdioSpliceUsb.o new file mode 100755 index 0000000000000000000000000000000000000000..6ea701fde3a377a71fe4ef8f1675af7258392b0b GIT binary patch literal 12336 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 literal 0 HcmV?d00001 diff --git a/Plxlibrary/Library/Obj_x86_64_64b/PlxApiDirect.o b/Plxlibrary/Library/Obj_x86_64_64b/PlxApiDirect.o new file mode 100755 index 0000000000000000000000000000000000000000..57d7d75db0f776a5aa44102024ebfb04d5d5c108 GIT binary patch literal 32112 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 literal 0 HcmV?d00001 diff --git a/Plxlibrary/Library/Obj_x86_64_64b/PlxInit.o b/Plxlibrary/Library/Obj_x86_64_64b/PlxInit.o new file mode 100755 index 0000000000000000000000000000000000000000..cd083a7367b041736074232f3dd1077bd4fdedc7 GIT binary patch literal 5176 zcmbtYZ){sv6~B(%)k!lyr|X|=1@g2yD22tclK@Gjb$RxC$@BVRTlRArZ7pw(V-u^6 zZDPB)lg3≶<%VF=%gv62FJ@@y!=bU@*x!3nz`DH~LYjZdV69+j)9wNpP@{#bcK5AA+Nf+^w4~5Tt zETtqpl~m8)2Tat3P9K5#5=05!3_ehTcV^UOS8pFUsf|Tny$kqOuA%unYU4jzv*7cp zP<&nJIfr3$!kLz^@<3~R5V@g<>mbq%rO(vD5rs%lc<-X&)1-|MVe!xCqg=QnEdBs$ zYV&Dq3$`$>$Fx(M{YVKti>P1-9|T)wgVy-_hPg=yE3(g%lSgj7{C@62OIUmnX24mz z0~QN+9qL83x$m6Xbj8)Hx7yUE?i&42D4leTs>>k}YSUh!>yX+Ai_4)tp)2EUg!?x7 zU$#;(qYhd*5iWcd`#FDo2@)eWZasfWIw_sH#_VO`vh3RrrRF;zT(0^K;$*95rKav% zSDUg=39bt(zf+r?ufvd@{V6UTjOPtGk zLH-SGs{K{y86}H1Yd$jp&9Wocs6rwZKFtWP&V9PRzWQS**mxqsJJ)kUN%MK3)P16~ zaNU8)5LPr_w<4_kfo6;)N9fWZEtny7S@s3gh5K%yE8$feArbIs0}`~N`<@K8CgsK- z&1IN+Znc8T{&QUP)n7y3*6LXM1NWP@ybG67TK1m*_z>)Z>QJy1d~i?1c`URX!pghC z%9`5vm3sBIOIqH?th^)d)o!U*|K^G;%K`Vb;7#@FU$E|WU(5N~{LKBVON~#=PUXgJ zIv?qz+W2L#wTd01w6}{Oy#q6Tu{SVOw+iw3>7%`Yfx1|+RPJbR{Zt3F6$5@ToGxav zg$|&=S{Dz-q{%f?NU4_Do3K@FjL(ai>0C%)|zQjm!Pi@49d`BF$3nRY2=wy^msIOBKnNAZd*#& zKX!3&xQ)Y34!bzKi^Gp_csGaL9B$`u2Z#4?xRb+=a@fORfx})7cX4V}azc~=_2ZoMVwB_Xj z1-BHz6J$J^!b_xuoD)8jeU>7Q7Zb!$_c{)B?smThr)nJd&(O9!j$zE>ZMKCx-LE($ zkN7Q@hBsUTM=kZrZ++!h_#M{;|GYyK~zc9p}tuz1hnNk+u`3nYFDgPV&fB z5*R1hy#wE|1HWenzHWwa3KfJ+rCBToZ^t zxQVrZleBMPj{vjRmVa~a0QY71tg&u((RSd!x&xozfv@ktH-N|SlXBl;>dz3r77k)DfW;sdLs$f`_!3E)*PC_M5o277g(S_0 znfH#N?*!We-^YPg^jQ03cXYr#* zfbjNN8-Ebmnf*5?{{`S4xAE`W?7MCJ9m=D^{mkO5+3f9kW9JxdFZ}f$hYtl~qA)&c zLDEMx<5Lt5bNmYws~lgTc#7lCP&~`=7bvcC{Oc4iar|2pU*!0oP<)Bwe@5{Yj(?Y8 zrrCVoqx_#Z`@0k~&Ft4G{}E^ZZ;IV$2*T{!DDLL?c8dErem}*-9Pgu8<@h0rr#Su? z#j_l*P+aHuD8)-0KS}XLj(>sTOB`RM_zK6rM6qaQ$NHVpEo?GXj%VlR634T1lK3lU z=c?&x(A9ZM&$8NlwvhH$@v!pGq^oJ-pRQDhf4+nO&4d2o%@B@P)5kP`n!ixWqzlBK zDb3Agix8$*s%HK0oar|YM~c5ztoh6HrE+$@dX@&r&KkM-^jww>`u|WO_+rZV8+a5r zlz-Wi2bjO>4grT}(kOg(S))&bb96oM?8B;?8g*0sdCK!Im?55^_B0$tgggZ`jLDn- zum1R6z?cK@*=3jp#Q1h$<7eX-g~sjtXQ=67(MW=J*f{~GYy<lYV>_6`Bc6h43OXVbR+Q*`{_r+!TF{{ID@r^Oxs literal 0 HcmV?d00001 diff --git a/Plxlibrary/Library/Obj_x86_64_64b/PlxLists.o b/Plxlibrary/Library/Obj_x86_64_64b/PlxLists.o new file mode 100755 index 0000000000000000000000000000000000000000..45730555bf1a8f27f827c849d8dc7a0ac8c4493c GIT binary patch literal 2072 zcmbW1K~EDw6vt;N!YU+1Vk`zDB_6~mn<5wj2iSUul{j87uNZqq-A z*TbV4xal)iSXh|Nj;$3Ne%Q#)Sd&(6d}6vG(uw^?IV(4HKgQx5@Y4-r00y?9@NA8B zF?Nb91q1Cy?3l5)%8cCsW4OQ9Jc34|=C+*cmmXP8#(fHdb_u(su$M9(R9HpEv?s3D zk}RXl9n1Kp^#5~s=iTi4@1&Yk;uC@Y9lDTUsZLiePNqcnE;7tgtmkhic<(Hll5Fz?cuxj;c4cgOW zR^6>Qmb{mHiFl3%1JM}4Jy6av)K_l5XR3N(+ks@;RcgmGE@ zL(t-yIT)(Z{tr|LG3`(OvBK2SQ7TYjLTw%xzWwU6h>|g>&tjq&{#VuBK!T;Zo=g2F zwHRVukKbMV%GfYeGv%j;^jBdL&q?|rS)8;tPJNU6x1_%Y4A;>0$n?7d#A*_Lz(g^* UT!&nTC`tcWo`1Vj83(%l4**}l2><{9 literal 0 HcmV?d00001 diff --git a/Plxlibrary/Library/Obj_x86_64_64b/PlxPci_9054_Func.o b/Plxlibrary/Library/Obj_x86_64_64b/PlxPci_9054_Func.o new file mode 100755 index 0000000000000000000000000000000000000000..d57e03b0b4c77c1c54dacdc5342e6a5c1c73ef72 GIT binary patch literal 7016 zcmcIoZ){sv6~9j0)N9jcr`;e^+tq6`WEl10{()>Plb`K4ubpW^ldPj{a2@A)ahKS} ze(st9C7ny@Q&PwWU`S{P!9MH*XhouH*A0l8jZ^}}r11eUq(u{gp%m6X&_Ts0=iGO$ zef{Ex5EECr@6Yf4&hMUk?z#6}`-?q^c$3S;L~*f)SnW-qj0M_j&td);W@}h0yY9W~ zrn*mkL>*EGcfGstUEc4#QhFmX zy%kB|LBjkCrzR}3g!xXw{1->msh_UHXaHo~!I7osGnP*GBi|@Ly>!8%p;MoTb+j67 zl~-L$GwRf_m8|^jKN&DA^#43+NQ1~^g5FIhuy-qdgFT_&4?wg$+Vn;QH7jVE`6id= zu_$+V&qddo7cJB}=BRNy_7pI z#rrkP4^Oo#YdkOnpK88l-lWJJc4_8S^+iZ1_7l9+q%HgQ`C3dcpWmRWoB95F73EV22el)tn2>smK40>0Vwv9qVwL%{*PS=|qQTRNLOl?aD1M zPTzrf?z)sdv*fSGyoNnWc`wIj`S>8yYD=V^T8o9q4=W}9kNoox8Frm77F+{7`N%rJB3d#Jyg*&dZ;*fO;Zv|9iZMbqv}R1B!=s&si+y~Mp0zotjZbzYbVFOf%!U=^ak1uQ z8Sa5)Sle%;`3&8#_vV>rz0v3c{=m>kIcJpp_XoEJJGX{DUgoc%W7|4|ojX2k!O$U2 z4s7@gcmCczLzu>Mh&4mSa=Ue7t|#|0*HNEqed|ikENn@K0N+4uJ8_GOE55HbMU?ih zG)ENwX?H{k%&d4=={(sIRk|uG<4S*1&nl%$RXSBA01RM86kkN~sH>aKDqZnqI7oIv zoq~$xvv`3%W}0G3d!;$1_))Jt#x;6Z?-q|5(0+tmD8Il9*qlbcX3*xOJE{aKE1(LtEW6tOQgEVf>ScV}tTByl6`M9>t$jJdC$(aA@-bwTs$D(XL1FRho8# z%X?NSJ{8Bz<9d)dA3~0%_=Z6k<82UrH{p*GKI4Et>wxo52Wa%5&R)e=B%NOqKT7&f z5`LNR-Gn!RtLTrLrzT_8x>o$-#NR-87xD9i?;v~&;rju1D%ho)UA@()y}98@26Izn zXT4Q3&*pjz-GYiI9H2`J=*r_2@$muPh`-eV?*SbBpQT*n>lga?v;)6D{MT&! zFFEj^A-<1Nk*{;m|Dgl_=MMPqNN0+4_+9`yR~`7R;2)0b4Ds)#xZMSKqxgh~zi8t} z3HP}z0iiQYc$jd$cK~J5K_BDG<4pW0`SSw@{;R}aBtGA3z~(K&JNZu#+G_y6>7cU) z#)JJ9h|l*R;0FM2l!u*wH;PZ3bk2~@7V>|@fjyhYqzNFVf zeFZ(oV#Vwcz1UyO7pjd_L@ydyy(Dn%BDax!j(t)cET(d$j9x_IuAHG4i{*mB_T-Ih zX0mVOu%0%A1jn-Jl#$Kn_UeyiOF)k2i!3&g>Q5C@6V<)|5UN8Zy%;HHNFQS*tL#f< ztLogry?SailH$G~7b?6B6jEs&TZAK=y04fu^u}D?R7XbZ9=#eQcr4~8cxRJ+nM_GH zSTb2MQt8K&>9NO?nN)VX&YTM_v$s4D0&-aQ>L^KwHK%nDA3)ulawL%lFSiv2^YQ*( zRhaXZo?L2VT(3IKJZ@TdRO$nF#{ey(#FCW3b4fb~|=+6hB z3jAKeaaIDCaA*yf`t1eeAYqd>k@yn#DB?wKPT}!B>s{E|BA$y=Y2go4#hq$KjC_ z!5%|m|0Nv;49n}3XV%;Dvo`Lf7{ah1(A|e0KPUmRUj@(DkN6#ldps8WU4%GIKSI2$ zvpYmMO&`56hQA|G^MADufh}s{nv;v@|6Un{XVJg7KOkW;^`ZaL|J`7O|5i{sRVBh? z@2?`(gNUDiN8kZ{vD+Uad(GBhw;u-EM)TK&n;(=Z8Ys>m+6sFye~tP^yXS}~))$`H qZfjtVn0@X5VyAF(gi^6Jinv>?))~u2;Z5i9Z~c`s`+o!d`+yq& literal 0 HcmV?d00001 diff --git a/Plxlibrary/Library/Obj_x86_64_64b/SdbComPort.o b/Plxlibrary/Library/Obj_x86_64_64b/SdbComPort.o new file mode 100755 index 0000000000000000000000000000000000000000..e80938e2e37d3c8117b34d7bc102c27a08f99d90 GIT binary patch literal 8864 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

AuzmrQL%ZY~O z->|Y9v^p?xQ&}Gaw1IN2OuV&8OEz%Q0E|Zfl;0Oyzpdd7=}s;zzUh{M0U4lxJWp|W ze{uL@H+!7Gx=f)_+=lXja>PUqMgW;1)lHb^duS(?Q&0usPit=lR`rKwm#w^>vMuU6 zvyxTgWmHn5l)e$A^p~e3hc1yVe*+y9ITOKfvZ;lz)p2C)L}PG$2P5TWM-mE@0r#JX z+_&-%MXn`0UhLJ^dpV-PYk09cX02=7!rJv0W68BpcJn7mp|Q=MB!{k=(AA6;LBG?r zHszPJI4|#EX{r*$GZ22poXWSX9i^|W|5%3ZMP$A}m~`W9>Bjl2mDgGQ{Keby3f)_K z7pmd+knOuo^C-}LPXNY4N1*vFtg-*`%AKVEJA0EU?++n`p)5+m9*`;co{_Qg8gkD& z;>OHC+f-j5Jk8%WH9I_QT;mk)qfh$O?@=!2HfV}gV#5az$&?Qvx(Lb>c zn@;6AfA&J}?X(Da_%qtQa#r{^WkKwOvhpxhEHGQ_vQgpB2(DdYDibUwPOE^uW$J9K z1{Ra`Y#l6hW1!pCiB#X?l&T#%rQ1|xLdU`I^G=+v%QsB}Y~>J23MbQ&Xk6K)aP#Qj zDR#EP(@UZi($Z{OOihYyY)t0tJl&K!$ILoxZ^JiQEHX8(b&G#7eD^+9<4-Sa-R7^x zMQe-yEBLbBhqsstm}+ZkGfHXoR?ksd*AIa^jjQZ%GW1}=UkF07z0(mtL!8ClBl^WY zmVeDhL-m7Mw2P(HFR61FwP!M{LRrhSoLL&`oj~}V|3w9Ven11lyDA*jsndv{_GNJG z4%X*~R-frcpR}Mc*0+N`TQ?X@qP3ewOVAE0glb8fg{_;6Is;+5W?rl&sW$yFRu!ag zGEY`!?|e}m?r3<{_cA*Ql6qe!3|N}ylLy*A~k?J(B6JbAjD#4@j+$&)nmqjMZm4c zsjbcnmXae!fB2<;_TG;-dM#azt$Ug&#DjWQKy^~?l3n$FjJ7<@JlPjxNcz2Ock}sID!mtEt|88+>G8BNzzZm;&Jim9rWahHuH} z-GB$$JL*Fbslel96}RD6>!q~|!_(3t&+M6&?&+<4~ ze_L$LHf};=2DHtvYAq!g_X3Qq*>s5HA5_`}=zP3_?;A2{N9JT39dzRSrek9IBh)VR zw-t=T7xzoBo@dVxMAT$6+8Ucqa`RhL{4gN&L<`PDUoyqtT5yg@0kh#!v^{0=b8m^{ zF}oKH#XdnZ(Mf^OMR8*JZ5vB^n)dl_FAg6H;N>rwFPPOsM{uDaD zhswp3?+(U!b3eA7r`8zfUhKQ`xZT_kZmot}x!CQL+`4D1dBy{VJLKi+v*SG$DPLFi z`!_bJ&Enx1E#q^W1xZX z)U-gyaoqQMn;yp1Xqz*;r=~!K80#>0x$@m)gm-2CeUMvr$AD-#;j6qKF17egXl(da z8d8rEYGwcZIB%SszkLV>AQ6=7105(HyQn;a&soN2Y!iNl^*ni3d-GeLuIxXF_Gf8jp!ijD3)7IGA==yipB1!)HTjw`H9A{nYeNLzpv~s zrtti@gO-j#aE2PqP>ASNTO>pjn!7zzDZ{@jHd6dT2n=k1&Q~oWQ#1Oc^&y|6=@@Wp zH6Bk1bkIAO;lmxpE(~AOJryE36aml5xBB13s?hyS7m=&iz@^?S{Od@9{@_Tm1n7C{ zox1_L{(5L2|A}NPH`M4cRtS1L2O+;6lDqP^C)pS#TZPlmY{WHDI2gIes*toGH%36| zyB-(y+B@N4xIyk1^=5i@xk`+ve;K*iA)ypElju>eH}Yuy<643oAC#O7R~=1=t9UZ< zXx#fq+(@Y6J&*glItC3kDkf_orDS$#6_X7>EWT0g>JSr_B#O0Sgdgb$tqr!%pKld^ zcZ}kV4pAq2c6HK^B#_`N+!BvILnEY@x_Pdk zI21AULL_ReVoWkNM0L5VQzC8EV$$!U+0lSJDfdlbkP^8i0coUwEWG5^NhW|)SYW>+f;)&>w z`j;nb{O^Z5wjGTAhwWTu$7u>bLJ^Z;e~Evze`#M)P=nvRr9k(xbFgjk(@P1};-~i! z)EbWVZASigwDsF~0kwAV5@IC2O2cK?#0Oi?EDV>Wncg$$0k4njfPZ%Z44&Rlm8I=T z?(Z#x?a+PO54Z|fJ?6HA*Nk7BN^hXCRQJc+cQBnpRMbp6Kfzm;+&53D+ZGuQpmz?5 z`)f9(ysLgjv0nLEzt_9^UYwpNwAe%7Ido1a9Xf|2;Pf^i$E3)>V4HTJ(>}l_#FVLGjeENG&f1At``YFNIRYUW;&HlbdC)`i5<6|+;46xr5x!=d` z8|9$CdMfUnn!Wue!a?SSf@w9nQYSPxHns#N7CzGHMLLk0o!3!k{NdzAcCBM%T>grk zy})+%jIy)sY-c|+c4qW(N}~adON|O`jF*)chyM^AoWaPsTNs=)wiyyzGOuSMWuCFK zo^uYJl6i6cc9Qbk9nSC%%%pb?&>s~wZrDKl=SCs@#rGpGy7+T@@+WhFFU`k@lnGRa*IYR~N^$?08Z(;*=muMYaFz z?-FYt?X**`|86^x$x|?Gg<^v?CUMYA0;nSO5(E-;$v_pw7O4_mR3p=ASPShnw3)aS zk8)^4lC}573(VUJbO8t7J_OAql&@6c_CAbsmhob$Y)~GWc7fC0BYou0=1qX9q11t) z0*ut!NkM_|8vkYh?08NiqnE=C>tmoBr&I?16{Dv4zaYoGtM)=N{}-t^r;vD8lT(GZ zoK?4A?;rFjAAT}4aN1+j}&cFC%P!SGx^ zHXeP7oMHC6w+W{vhj||@8BJnYJeZ!3!A3jnirmWxv`yM; z#@dhmP=?o+1yQ48zbK3^npaI2%`D-8+gX{Nry*qv$-7{<3rQYmEAj{NUb2qHEDI@F zE82=MwFK=moYz=8q_;~22a&|ss)-|HXJa7rCKQDfz~Tki;`i0UwxXN~{YBn~pTUk* zN!W{QzuD0HqXTBQH52#1dI~^l;DS9R3!XNSq~}v@e9Y#Vdnhdy91XOgU6YU9#TI&N zv4b!668j6KQqcu3VsqQ#LAwyg?_h4&j7-SoVq`QWJY#f8_(78>;nDs*Emx*Njo9)t z51MWE>@q-52bp-b2}WlqAV z30=W!H|?VMg)RwTAE!X`u_29zJ17X)oIW)&&5hg3$REK4JyV;uj5YBHoe{w6ZaPd? zv2P#pqf!5iwV8h=931m@xEoWe+GgHY_|fZu1+*P*Qh(rr&w>}&SF@|S8oxcGyQPmp zKu6zCZT)4Y1toadXX6kWPq7@*J%qB>z;a@VQ;{{1%eowO3(?N=V8bV_$)e?F+W}R6 z=JYk0NZWSB|5EtB`ZtCD{J$am&%WY@pWeFXnD=Hj4)Q+aMDwyZ0j@MXK~4puVm%AY zyXtPzd}Q*J$v5HO=%nbpkb-X~u-Q6;E&|w*?7jygkM3rLaMJG+CfVUH`f1Xj*;aM-+G?R!@+?GV* z7L6R&hbQRI+qAPU6frmHC?($togguJ!*|j!NApJQZxBut>N%~+2;#t8d3MCAqvIo{ z_SPheT)jMNCZsD)wA%|r<9Snyt0K-V=T7| z>vN|T-jmG7@^{=Vuj%-z+BO8_i=zBeKUk zo#!AH$f3}7Rbd!EU-)AnTth!8$|Igz$>hFl((S4^JzZ2HinCx@_X(kC}-*Ok|8=6C6hgL~)0!Vvt`G!}#3 z*#z2F(+^`XQ8J@#^*Ee`r`ZWi(6Q9Z@yE+(K4J6W97nx{{%lkrq+6OV%DUx={`f^; z_%Al$XTeW15`@I9l#qoMb4Vm?C=*G494hY^ymTt0@uxr0)Id^_ZQTZCbb^L`vZKFE zLfCfa(9j0OBM=^92QPkW^#!-#P}G&ir}}-%1eeogFi zWI=sAODv6lC{kqaTzfzHgY>bfAaM^+EC<9r8s5-(HXbU@mmnJwx{ zBZXkkdEK^9--1Zl^2W9!HpJ*Vaet9Yw*S5GjU5oayY`$?_z;TosVQ@gRh6;z&|p(u z^*-@5HSQzjm1)00{!%O2c$RI%b__xZ7fQl>`%x$wPLlslSihmavz`*4@*=$#j!nJB z(_Q~A99YyWjMgcpJw2d*N=b?zmE}NJWT;Np^NYVU$}*X=@juiX{JwS8Zf*Lmj!oYa z>7$MHcY^Wz|G&JS84aBzXa_`1e(Y{L))Re~?vC)DqSTQi?$z3_w;@gOK$n^w69Lyesi5LQ|o{uKiB4*e*pg*KiFbQk(FsoD*qKcAVugQ|a^ z(S-0iFxk8Md7Opc>!3zoa4lX>1;fw1c*wl`3qM8U^jXb^yr*G;z*DU_w~6>@!IJ@Te;q>a_B874+<6ucwWnc&9+eM9`9 zzuej1Z-Q-J2~c}3e~0M++flSa4)og+ZWFsNoQ_!Khj)8hE<-o@3+cEr)o`J=@KEnr zk)E?V++)WZW9)}s4?9i4$Wj+%Kda-}&u>UUvG(&3As9;vzKw09MC^y=__6(Lz*)q8 zuoMH*;l)GNbdXZUbUuOUq}r6h>)f0PU1TuOuxR^+jLxfJIF6dpzby1GCmoYbuz8Tx zfNaE9)I92cVRf9t_F%_VgW=Casbmc6jW#CQ+~i&LOSk}IARQHkl`+`ziR>XKu00G4 z=u8#R4aPnO1oY`098flfCImw4VGfejv}=N47(*oJumWQZ-j;C#P2p@Yg-Cz;l*-c+ zmtVOt<=2@Aa$CGEerzduYLDp$ETzSvtu2NrxY^cQI|KNT-ou0i}&OLx(B6WhKp&nM}PjI*6|yc6O7n39K@ z=SQ4~eB8LO1trERAk1IDPb$+eZ7_hkcjuwOfie37YuDXFxpG2R-y~zd#cP+R2E#jx zskp^3Rdd%0`W1a~civ&T#;@s{ch=dT(iczOADWQAa`^}JyY*1FY4HTw^e+hMg|tzZ zyeEpWjrfT8GZ`%LS7t*JquU9ETq_6!r ziB0&%e9W(Trsaju94IXiK4NtC>%h)GKxe-WtWEn?-$;qi+R_z)$$LYWL#HcqjVcba zDt5?^DW}*UQ{Em`MIQ3espOF<&`D&84PI;o#W|WvcGVRrMZ0^(VVW3ndS9#CzU*Bl zMU2shQ@`L1Zu8-6bS+OuL~GHN{%cXopBty**R`oUHio83ceBYoq$abH!l!H7$h2(o zn-MmQ4rDu3G4dH!s~C!rr>EcdX5g0+R1dz?+%xEX?`3<9TPUqDF(<3->%R8`-f?@| z8vTWBjfIpAQUlwc|ETPZ|9D`xuOz&?n0}5P!d#y4`^Daee-)^Hy6In0WN{9_VEa&v=&(2B;e&g)of zAc%E;zyg6m&(I($bU^gL$G^k$EF=e{5Us$@KPA8K9Z^sk9Mla%?hI7#?7=UE0^#9- z?*=|vfn;c&;>RVsdGO9uIFkD6(+5r`Jsx=P;GJ{4E$^cI3*g0#y=T%{Bwioq|NX}Y z-}~LG-qkeTeelkzwprO2yhN%`YAeZY`}&l&#yo^A6-kHWm~YY=vFt}mQ;M5(OO4ee zrCUYZbgPM*Zgp|fEfhE1mM2WN44ZB?!J59FG6E^sh-EXpIR8#SJyfiBw z(_JzK>j6+I9xDm|Hkyjf)LiC-G#U+t@7o9z2sd}pmn5gTXOc73Bxh7sy|xhUQi`kiZR86NTvXfAkHbKbRuOk*@ct~pI%)S{N+y|U zZcp8R8SSx3Z2DWh#Qxs?WcFYZ7xT`ki?qdwJpcA6o;{dfxFoiRJh6vBCf>Nk&J4O9 z@o=M^7maq*Fut=jY8c*CcOn&OJjqPNSW0Og(YKB7mnE5PeSMPk70~AUs}oI5W31ny z-VJ+K9fFvcy&WII!YIb{i^Kb*ABV9$ED_|SEw#?@zTPHtXC9{;njw_J@tPse_x#7h z(fFdhj)`?cXfDbuOiq3?l$uW~f>2Oa9rU)$LR|MGd(4^&c)thH(?~ZtB5kg6^TT+5 zLgJUO?($kk_MU_Dn0C%-qPIwU@KpLU)R>VB68(MJ0Oh^tC=cBXYoF!?E()LUbFgXK z4MuJ_wVyX2R~W+&AF+l)7kM;EdT#z{RHfckG{1_~G_v=m zs2<$M(BsdcpZ)cmWgqRmG%9E9?990O`v0_lq(_pco=SF__7kIvzE=DGQ1y>y6=R*S zm4`FX?g)f!M5VBRt7{9DcU z27j0N-sInJzPI=fneT1>Bj$UDS>GmRlx7ZYpy`aYpL{eJhrSg03oU*h!nB>L2qpvguLQY4gjnf)-6jNSX@bZev+b^%HS$?_a z;)aVGJXp%L?Dhqo&tF`D>v^|dTyb&E6%}-a8@V|-IrDCu896O1$*1$lIalV`?}_}K z%imW{;`>*b@2jpf-?-MX__Al+*0?m(=$kx#;`p4;Pq@0#Tu!*_ik$H|lg3zVeM-Ss z20qm3#5M}_qN$4*tz|=pd8LN$L0`MsGiZ6npiyZ$FTJ5{B&P_dKN^crl%GTC;#T)L&q)l%M-+R4WE$Z?tN9<%L2|}nR=3$PPZ$EkzYPs2Kn9!x@W>;p1;j~ zzK&(SPBJFA<>q-mF4yqA)pTzL#ph1kyJ2`~dg`uHx&$WOZeuxG5uOfWdzp#e3&CDv zHkrP^OmRCn7KKVx{|us!Li!N?ab@K^vJKY5H}7P({6 zZCWJVrc$~gjqVvzAn8U4kXtw)*`^IAx9Zp}qsORQNME)AJjgas3>!#V6W0WajE%{D zOP`~_;UGQiXZNo%#IiS;r7_FF_c3Ol5}THuu_g%yd{1&=y01B9IvK~pVaBGBjK-!( zpW`^w{F?L-eFnzQ&&+V2DHxvgK>B*PxG{MyzVqQI9wQqHu{$B0du|{bT7U$|A5P(t zy>8HLiSNfPt{>Bljqhgn4$?D4l&pwLb23Hau84^j3^)2Y!m>VEGarW!A6jCCj-eDU zJl~9bi9jJXlsAfpQe`^PtUz5j88s@SLjj!1FJP>()Cg1y2n{{8qBbH_<$3%FgNON0O7zO^TZd^Qr7C#OD~h*M)P0A7wk- zTLUXa*PT7u`SG`9HV^F#q44eTAQC= zVs-gR)&Zc{z^wc6-El-0~HgJ$-j*|@hbjsnR{Sh0^ zH+9!?mX$nCx>@5suXIzGUYdjw!iSPwswCrQ7eBK*)=v`ucEn4xn5Yat%(5Fu*4TSA z%~H8O(DzLG^F6oR&1EL`>4TF&X8XwfsLtnFoliIMu8Z?r3$qiImz!Be=N0mIH{Ub) zFzPQNXWMoZhaTlG>H9dd%{Y%|izxA<`bPapI?SO06vt}%XLNYGDKqF^knfqcow-+I z?geqLitm}dw@#t_o=t7vfsLr?KOT9F?|Jz7dy;0P zZ%j#gTk-`&5+3wOiswDk4Anx(#z9S~Psxo-bt@Sz#XFKsuQc`!WyvJRebe^@I~$)t z9xkwPUWX4I6im*;wWwYsHfnURXE0CKQHluG=j&pYra~+}@=GvvN zGC$LCgHCT}evaaI8m?XUc$y3!7~fUQ<5_6(fSm?Co^L{)>JxozOu&Ddfd4!J-=2VX zCE(bQA#QkHOu*kvz&}mE&qjYEUVJBlp8>ly8x=wsrar{?v;^|EB;eHvcoVzd&h1ng z>-aYFt<2|eLi{j+JKGcR7ZUI{*!>JHYRuRP{P;@(`JpIB;_2ty1f0eYNNWiA!Rd%{^sW{d*zH0D5hXs68@amaYYDCS#7S#HK8a5{-OcC0Xm8Hd2xbmp?R zwHbo|zfCwBj_IF*-^JW_zH!DQV-DXJdFC>n@N?!(%%u(dGV`rU{vGD~nZIkj@eD>$ zNb&9RSzyK;aC$EDrVA{8(tdfaVV-xP1zVWUVSa@9ub3|t_b;;GC(Ktduk%|V_2c)L z?`Lkt6(I6c@ObvTJpq4`-D$eiy5D8LJTD}Wr`b=Whdk;q;gEEBhq-5r(Uv0rH%>TgLyhs5P`D4N-TfyBdKLUy(J?v+`fjNyk7<=G?N_ZagjBBl+luPrN z=P?(1TgJSJ`9604UznFpu|VV>V&2YN%9-uV=YPS#h7|`{l_%(~aW0mHBGs7c$Swvq0L<6Pb50m%XiTVD2ff@}{4R(<yotH# z>q6v*%;!(D@=`u`Gxtrm-1Kd6`WExjfaRuNi_^iV?OTAW@29xq>C#_}0A zT6xnq#VNh~B6o6bvRulaFERI(#`2}&&KE5={ZE|U!@QIW0Mo|=zn^(inU$CLZegA` z({cpC98ZGB3;%No_>15pJn#1>u`}}h8|FUd(qH?%;-&2Ge=9zYpL;if`!pSgHg#U$ zDXg!)y|R8@LG99|l?y_|EisdYifcb{kI&^~D1?5W@RMseg!X@Qpm7#gubPh8E6SP_@|85UR(Yr?#$gsi(SjL8!*Fpr*E=lB7cQ(3cUSi}D4F>3rV8 z^6DB7b`P6ZSlv)p9$HW}uecT|9ICIa@yLc`3o7H?MLJ_=vjlf2p{)fJ82^nA#v<&s zJnSIXHwOXUG7@42?P^k5R-ClIgIU z+WL^q8qktLB!x_MOJ#inELdU$A%{?WVu?|z$%Kwr6h;k|le_K?liU(L^JLkAs>+JS zn#!9i8y1vDd@iV}uA6yBT_u7off0lp;3AG#NqNI!!HgX5#YdAG@G0s9LhI(4Y2^(O z*PUA?pCq^!lhq^$&a-qs4vx)wi3B3NX1N>8IM}%7@RIVny2^?K55?Xb_-J*_ZME>w z33$!&5@bx!SYcIkM*KG%zIYZ@hU!oVH&lPE(z9d<04D_$ghF@LQbJ1_%@^M(s;sNW z&VltvrKORy5LkO#q&&B%pq@-yT#c|fFuS@UR2BOStSa$M(!|s| zZd$m|F&yia(MJ4R?nCn?m*vM6Kp4qMN7+XtBH6L!KhDN?zTmwlt7C` ze0OhCQzagcCKIKG`-E-1$TPRpp&W{;9+xpHN2>-&8>h5ZtsQX=@pX!F&$bsSM{ zCa~hEwG=TV3L(JE`tqd>Xvj@Px<={?htF!jy@)yUL+o3mp+LB_vVLK0{Ss=W6)&w0 zRhQSGgc}$KN35h4a<%m;kdA<l)D}srHE8J+_U;UpG|V!DnTaHE7~jR-kWy?xs1Yzd`Skj^mdf zbV%QY_&E;G!#N$qN8%&$w-UsWf)5R~3BQdX4w4^*kMOS$#6j|Ye1w04AP(X*)*}47 z1aT0*1Rvo?3F07rDL%q!g*iGjFJ?~R8I6y~f6&_V@h(o)7C;?wKIKDiMAJU=SS&nhGc>Lo8oW|2c-qrIL9Zq8{ zqKB_KoQD2{uXK2h!w+KohYkuS4PlA=^K78RX^cepy%meO zUVMJ$`SJM^zWBWHg82N}3*+;i1pIMI3>-TA)&BVWOH_E_AbA=Z61{!T;kP*aC(KEo zZu&mvaM!NBL4_a=a(^~H;{GzqoH%qi2T|e0-1YY|hkpt8#hniw?%LIMy1=2`|Mq3^ z`O>lRc`gr3X?G4K;0Gy_G?+ zcI16jc;V3g?oYrUnHXRGJ|36X?ri39dCdp$05Wmc9u_*>P2ZI~E>H5e<0J81?{GK1 zD|4gaY;@$i9lqS*#~kjuvutwI9oOG3hr9AsJif2vn|f{39alcU?{| z1l)fUg=S#+GpaN`AO6Moyx`{eyrC>Uzn0&BkX^ayK5|x6emzblzM~xeU58I`xa$th zFQS9or>aKW`B#Til_>m&4j=3AM;%U8jmZDOX_r#bF8r{=si+qIfy1e&7M_xd3mg>A zEAbJ2@o7XYry^GPl@6yOQ+ScXsc01b-f&#tAor;V6fW~jiBr)fyuoQN&2acGhX)-# z&8hDy9lqS*iyZ!M4zG4Ne*0|>3Qvv08y#Nja3hR=l#l4son;9<-_KxHFqMH)A9GR^~qC&OGLR#TPKoR(uh2vPn85zKfZ& znj^fHIX4p`{2&KB*E$p7%UGVP#|XcZd7hHLn|Yz)gK01T2N%x~civ@x$(HDl@E>Jf zYH@_$%kFcr5#jeSpQGgOXFgZ)2bj-S{6XdwivNIlmEu2QPPR&ig#RJtbrwhX!^}g9 zKf-*u;*T+3q4+4)XOrS7%v%)S#qP8!-pzcC;?FW~SNwVA>lA;H`Fh1)VZK4}gUmN7 z{yOtbiod~pv*K?t-=cUQ^R0@%%Y2*SS**7X#kVovq4=llPM6~S%y%oEoN2*c#fLKA zr}%K@`xW;xe@XF?%nvAj7W3B>AI1ET;^#AeQ}K(K_b7fT^TUddWqw5Q%b9vPt_3?=^ryCa(xhg^ z^E}0CnHMVFz&xP%GUh?W?_@6XQzZO%GoPvCo0-p1JekvRuHp@xj`J1&Ez4IZejmGE zrT9peuTi|2-LF&pZI%xy{sVS@x#B-!zC!Vbm^Uf@F!L70A7S3AxYRFe6n}!{+ZBJ3 z`8vgSF<-BEH}egO|CRNyQSm=8-=w(YyUmJA{jx>zgY55C#b0N>P4PFFcPRcA^Bsyy z{nDkl)GxagKg#axRs197`xO6_`F_RwnZKmC)Gr4V|Csgpn&Rg$Kcx6{=5H!4^-GW9 zQokHlTKEGo$>mbN z&{9|~m-;1Baj9Rj6raxJz-Yy9VD3}=Cg!q61l^`j8S`u%b*sQ8`COBKKSEE}(xic5JrNAcC{&RoUY zn9o=IUgi~w-^aX4@%x$ADEjGk9#Z@V%$F#qx(0AI1EL;^#B}K=F&1A5;8N=EoHu%UpgUOSkEBIr9{Le<*w+^HjyJ zW}c?_wahaVe~;}mQ}F_p&r)3K)6t6G!16xDZ({COyo`Ca;g^^E}0CnHMVFz&xP%GUh?W?_^%8_}$EBD&EX|j^eAC%X|sZPaE_3 zO8#Ev^m{-$ME*YJ@?Ki_g;`dvM#=vd%hxI1%=NFVStRZ(Wxia=``F%AC@%fPCdE@& zzD4mrvHPux-^%UDHHyz;-mdrp=Ia!fe&Tw?rJuM#ap@;+R9yOrn-rIR;%3ErI9^*6 zujO>vs`w1%+Y}$qyhHIbnD0>hL)LSb;=g9TTk)SW->diotj~RlKgfK);?hriNpa~X z9#CBRiLWUx{lr6xOF!{V#igIvqxcgX&clj7$^3}oJ6R7ODE>a{`IzF*vOC8Wf1bH{ zq2c7y7n#%VVd;?kCH=%y#SgN4n&PiB&rn?YiJ6K^KQT*j=_ig>{9Sh6r?~VJ{fbLJ zF>TisD|D&r^IP^FqbXVjfU@6!W0s z=QA%={37Nv6~C1E9L2{npR4%g%;zgUk$HvUS2M3t{95KUieJyXPVoZfA;qUNU#|EK z%vUJBmFt%##cz@Ef5mf|w<>-syT3;9dCc1tU%-5w;)|HCS9~$^4T{$?->7&4^G%8` zW4>AOJDG1${BGu36>ny~P4U&tI}~qYzC-bQnRh9EAM@Rc-_Lxn;tw$2r}%@+_bdJb z<}WG!BjyJbe~9^Oia*T!km8Rpe^c?tnD;3D1oOj+Kgs-v;w@~4A1L0<^2Zc^mickT zpJy&h-bgw2BJ-5NvE|z<%u^LV$UIH)*O}YhhN9)<8_Z=*L-F@5=2^;}KIWqpf0wyW z@uSTBihsmBTk%hsk5jy#d5+@ATy9KKd?@o=#fLMWqPUlNp5h~!7b-6O#DL<`PYfz9 z{lrqmFJkv)O-RxIrOatP2Rek0Wj6^h@)yh(BCC$=aq{lr$qrJuM)ap@Hgud^Ph9#UEvRuvSHDX4$o$vl*oFxA2L4ouN2S z^D}G1(Jhgm&T>Bf7S7YL%$kIBOZaS-%Te<4_&Qf{nsY-(p7|ejhvv}G5wKqo_m}Z? zsp8+@>p6;lldtD1?&a$$#lOwhKK_<`%9ozGiq}!Zan#wbNWPZ$B3+8l=YGPQiu<_! z$YA%xU#XuaDK7b{RB>4o&G z&O(aII%i#q%Q{JV{7}|I(&Kxw9+Dn^lXZ`BRKKkBbQ`|qip%;&dfY(PH`4v$t(<{$ zKT*~%LvS>I@!;UZT^CvRb-69;8|iXY);Bt?+?Vx=3OOH$ zeagB-Rf?O*p745&;$35Gcxe3}I>a4Wm*_RcWnCi4XCg1_5{>5hmcnISqCCZAU81>) z%eq8Oip#o08x)syi6kG3zq0<&ZY3}43>{Eh))P9exU456<$<^_>ju$!KCa$m-JmIo z%lbfb6qogZLW;}!K${hp^?_bfT-FDY9|}r1WqqJ=JWo})tPdpRnedHQ+4!tb@*A(V zyj^iwA85DcG#M7h5yfSFptNE3zW7^rjlIrRT-FDgqPVONRI0eF4-`^d)(2`;T-FEL zqPVONv{!LiALy{+vObW9=lx2&WPPAXip%;yrHbd}Sv}M!-o<=};<7$aTAF<>;%||? z&Q@I32MQ`K>jPCOF6#reC@$**ZB$&=2TJ97Nx~!R0F6^z)&UAA?&Ahgjp7+R4}PQK zvJTL0#bq6!LyAY%0UF_hn9r2Lf|+)R^8&p4csn}6@~G|ipd zwLIGdd?bcaO|l?A4CJF15OHNggiZ>CeX=S6yhONq>|^T7UHO z5At8f|In>~IHVnKuRI=~obY!EzT^4d`luC<_Bi=Zerx~94$1#B@Nth)?pTPt+>>kh zuE&jd&(BHlJU0_fn90q%`S~2WaE|%>{8)$4DfvZ*e78F1<_7<3la7%Ky)(g!d zb48tn970YiH9c1&o~sehY1c|2hIS1RkCTjat`=%DUL!<2?P`2(r+ChIwTS1mE9F7Q zxFgQg|4n`g;yK?cUJ&E;9U+)@)$$vI=SVMq^$_Y*#)|w}s)uq>ZtW`6%XCR;kj;#| zZ-Rnol_X1`5Ps*SVDrwFMEq?+S8{urFE^lcelh_0MhWh13NUxO+N`u1qx_>Frd3cvSy0eF%&mL96=5^QUa1IyPhHI?2*DiM4#NoV05TkJ&Bkt)k7Uwve;|buHgj2W&Wh(Bc z;Y`FyM>4-O`I`ciiZc!844mmW>BzwO5YC4Qh$Bl}vvJMAnTsq^# znUCv2alZ&xkGL-o*TuLl!C545vACAt`lPro#dRsprv-in*JU`L#km~k3Y^d3)Q;zI z^8(J5IA0RvDsj~=ui)lY0baxPb)0YEd>iK)oOHa)FHQcw2lPJ94{&~na~;l)aBjd! z$HzE7!MTwDj?FkLaaQ4^V++o0IJe{6fwLN?eC!lpmrUaRQv?1S_zQ{q5AJJl?!mbi z=T|tt#!1Jw{Gxm(uHWPO1I`0De-s>De!^KxH-_Voz=v@?D(;Wr>c@E;=LwvraMDrF zFUlEl)h=hn&9Atg(@1f>fa`BKFA+xT*SgI>+y~(d#z{vjTtmctTUvyg6pj~ zZ^L;z&S;#*V=%ZoaSp|K7tXtJ%12UM<&)PfUh~GCnJ>J#dd+(a`?n7I^2>i83V-vn z@-1EadLHfkNu(0+!?4>D6IYeq+PTXO3yNpB5A2^5x4a^_;f;zrUVmpVM?i6o*nYxx%B6EJ@vpJ zpMN^_^?0*wbMe0%?{4^H!sV(FPfskocjoi+Mm}r{9r;tcoxzUP{$X80-dTTsamX*Bn@cTWliF0=z)c%iSsXJz@@^sFch%K75D zxi@T%cp_kWVXMfEmw)_E)X3LwxT({ktd8cw&o_=AQPAU_4WrIgJ^PaT#edws_WAdY z@A@G`xw$?v;fq^Be(d|NA+5^0^q!JAdfAt|e%z68Zp%9-U%aX9iH2wM^1isuzaY89 zHsSFf&YT|nQq-55dw>4Gx*PL$f4^+=fSA)VU4c~j)7 zTdmJLaQ2T|kNtGrW91+030n~C3ft8#sbJbm^U~W7TKQ4z3rj!hyxVT=m|ydH(VsMpatY58F0<8~l2=R(;3az1B2gL$-SOE6-=IbW2}$ z$Ch)yHN0K)-u#QNzTPWf((h}tXP!7d<(ss#W0oy`wDp1Ni_T%4;<5+*oYTJ{W8m&S z5B%nR?(skJ8aD6RJLTp#f1J^+Lbz8rg^VC3f=c@xx4|^gcf6+fzj{fegpkrYp7cJaBAk(s}zc=O1 z{-GV){9e~@>hhG>-7m#-&O5uaXP+V4`bO^W#L@PI)>9;)o`@u zo~dIm+;qdv%|%yz-DOg+x^-2BdSJ$l5naoQ{CyXf?5&x+(l!3_w*9^_=WluXgYns? zLzm53V+q*4(2dtXwB4aj~u+~g@sq2-f-W! zHq$r%KI4|xTJ^~_FTH8jXI*ZYcH899^OjRr(d=_5z$OKd)g~Xhi3RA;G2_kehcaUJGlAyX)Vb41bl3B>F>F^dA_^_c}BL7ex%xb zI*VJ7|8NWGk3c%j>HnK{&8Pol3+W$dfnVN&-ojdte^#63^QA7Ux%#bYprBI?fjC`Ii>zaT(HYPM@P&sK;3?@Vi=&^Zpj%mv?DC-~CrLug@JV$p1?Vdg#}J z{wK9iU+FFAe+1I$jq{451w9A1kj|Se@TXglKfZyBgS!JtVk!B$=_b7`I!?aCOh5= zs;6OBXJi_X|y^`}f$8LU6?qhmuuax^ZF^4~<{1f#^ z=_mo5p!%kxtB7Ao18f}i{G#*^;qsL2;Y7aRFED#(uefP2kK=QGQAWcFliu9FbD~J- zA(7R4d!=#!C;kxeKVbHc_)l@-X~BO8@hF|zLQd=z>AWWN79l1FS{wYbGmjrJokv_E z(y79g(y5%w3A^C8iTbMjj1%v-;@56Skm5&(iNmWRemkvRXtILidVW!+3%*S7y#!y+ z{9$_~MpU54UKuOWucZkIj*wJs>Q<`Ta(N;ra$cKL{U+ou7ZX=RW5+Vh z9^T;C%`eKKPCOm+{XCsN1>axDQzOb-C-?}V=cJ!GagE@^L_J3QgQp{w=ak+;4+#mJ ze@Ddc3B8g&6IOCU)5B6to=H4D&8g^k3jU4a*F4OL)vymb0)-vMyv?zNUzCAD&ymYG z;THU>LO;r9oDgQJ92a&~U&Q%Dk#BclKRFL@LetNOLLPSx=fg$(&qcY)R`GP){GzPX z^h1+195m;p;{#L>m8(=td~f5l@}g)*IW!T(q1kP{@IN^lc|<^GOlJKW+UYP(p!n=K z%f>V9l}KT?P!~I%6mr&x3Kwo#c~$7Sk`@wiyf4z<54$7zBbG8+(dZQW6tpSnjfHbW0I#*7)U>nPCHRw zHA2CfoZkvL>*ILDN}il@t0-@hFoX#roySG`<>fr$?Lr`vkU!yZ&f7%%-;i$yrK=Kg zL8LGEouXW2lQ}U%Q>7yP4@Lc!9pn+U z`t2?BkRS|Gh^s6R?W|4G3sf{zvaCgC?CR&l~D_+X*`(nXwz5PZ0(ukt!hSP+kn<075%mpRtP39W_Q zRu*$!8@JSH_WU&GH9J`=>?CF+SIpZY{k6gl&F6XiXns+i7k;3A43Dq1qp3pAkzetM zuZnbfg>(JXyLkM~A|0ESj_B_`5&Y*O-vp8GbivOTRqx1oHg>9dr_ck_!v?w#}>@hB%W z|M@u#kNC1#JRPkbJ;L9{?BMY?AzeC#i}WLeJ~g}DCFH5Oo2PSuM_0B&59B|SgkSB! zgOy9dKbyrkXQGJj6!uwTu+Pn!UA5;4jE7$6ct+?mX9nlBet&`H|HpIwRUTc*5%rZ6 z%lR(^f0wZ5GT~Pt20Ow;zBLy)7Tu>Z9}b_jm*t#y^NSKK+I!7PP6)GB-WT@Z7UNY~ zBd6n0G2e+4epR!>??pNhFY|b!I@voL%C}zF;btDJ+@Q(xPfoZ6|AWRq&j~G^IJ9f3 zmzqGXNTE)pM)>qlz8Ahq2~zE&n^)8t`h#O<{T#m3Em|187U0p zS)qsSA|1CFhx8Hgf6&^?&zyi7*)dw!Nu;nhQ9NY~43hLyn!yvkS)|`u@b$t@4v2Id zqFvXE27OHMK|*g4&v3#i_;&>FevT6>1n(FAs`f2TX!hI#evkC52>aLk&n-fqIS+CH zw~2Hjg`73%oY(629$^nTFY<_P5&ug>qw>})k1)|;Moa6By;1?xW=)Y1ZUX!zvC|8-V^CA)dkk*cJo9gW@ zVGof9dBkWDf0QU!xhR)b-uH!Htr30|&5a#DiF&E|k>gasmkWL7tmZ_9@G}Wo{R;iN zMSPQJzwXvt&W`A}=-4NC^G1#*@Qd<^#tTC@z#mfviTZL2KNBV59~b_ryeE%XA>^@X z_OOgc)a>Cq5x?Hd<9~v5=~yMoRsROZZhldIhP>1s%ZfRn>Fr)&=k;P<{JDsKji~op z5g%%2#}2_q2nVmpa{^*e`blmcPaC%{6?T#R<)?wio)35&G}WqbpQzOrANM(EOEK=-GUk z^KT2o`c%|Q&A&Lmk6)B~MEaE?eNin+gcuLhhuxImrPP{J4 zwM5u+g0N@JFMWV;lHa|6#}~tTC0X;U!jB1aSB{GITX~+xpDyxUBg&i5o@c0~KT*_s z%o98!%!VDcqP&quIIb4F3OT7iN)Y{#W^bKf*Cc28A|A01Fdb8beY)S{So6bvVL$c4 z!E58m^TK}0YI*#7_(l0h^cQ7fT%pN7PUy2%R8$|KPgU5PGLRDyz;tvL@k`(47;0ok zSCM`sExhCShW+JxI;dRcd7LN|{7O;pwPM^pQSgU_eb&VAbT$Znv#77~gPcef{0vcF zk>@yZx8RQmdFn-Z`v`u4;1w}%6>doRNZ4(Ju-jKf{BWWF98q4)KHq{oZ2TtH;d_Yq zCD0S`ZraI(Lo9&rZ%r8o*$TxBYC&Wd`7WP~&{Et>&|IymTQ6B$8t|n!U zR*ypQ1%e+d(#c8Vgf_1^B%Js?5xB* zXL7DHF;Pj38$T*BH7z%7Mn;}9EqDB=;hEW4Y2%ZpXQuJ6=0g%w<|ZdPGP060GagA( z5;EsTM@B{_#-`=uX3rd+Ju}DUOuH{_u5);9iXm`hnsc}_H*>VZk(cH)geByr<)vjY zHX$V=5vh(!&dEtj9V>(zo0gnvcm&B=Q&aI=-lU9FXSyMD+?AotCOj!O!)YwVxU{TP zlw@XdmNCys$r;YLROrW*mzkE9W5|<)95%1n^2tGoQMaKgPzxy!C#Ix7oaji-$TXw` z<)L^6l8M?v`c1+p14F&!rcB65O-4z_rA|+@rOnPrNkeVt37nfTJ1sYHcy?A+T8fio z%gN2iaym#lptRiFtn9?h?383@Ms}9sOmSqo^3rjgk>*TxI&+m2s?dzQoV2u5exJ?n zohjg1jK*9?=cHwkaJCF&n4Xa{eqK(REzL>!QlxS7vQjibC^O;^yNMYzCN?4?D>Zhm zmRv$^_Vl!Ib26MM>Bi@HEwcw9XEI_W#$}_t&fILKdRZEwc%pEdke%y9!Z~TV&WyA? zJ*$+AVad78@M*b@>|7X5N?Kf2hBJe;k^dTPR5s#e=Ne>5XiR4;8isRtwkr!wv@!q2 zaL6c!CN}09k7jKb?ItlUk6`S~9OpbLMB>=Anc1_`VxfU~6d-Z*h=Cdp3)QK(tUM^A z8A^X}W^yL1MRDY&r73yN+^m$Gc}gx)&CJMpn26kz^jrnTlQJh&NzKfgHxqxM;VdPY zIhIs7B{I-FBTj@{Ax?`+SB*mw>T4F{j0W>_PD-Rdg z_zWU4v)KhrAdgHAOiFf^BVz`hCID{B&v52ayA#0(Npxn+Ov`pLAt?rFMhm8UtwapQrDo(^Ny4)5cwSC6s#Ft!N9TEws`QfZ09o2AqRPTGMweOiKVculavDQ4d5D>rOnql!ULILN zGOBAH$u=V=BRerQBNuK>m=t3gg=Y|ErAJ0?`h7}za@GvE=Cn*a&z&{3PwKxoBEQF4 zEces!(HVK!DT4cg?Qx!JknsmWM#G8ka)LkqFN5oRVcXF#rQTu#P_ z%;daua#nCD3UFc*0*T7;Vsn$J_dqOuX9yk(LmuXGIM8G$jsy)6Cy|9qF=cFs3bDqq zw#$-iL?Rk4=q4y9O<9~_gBy*GL!&a%qf#@n$K_C7qH%Dj%MllRP~mlj>Lm zP!Bd1&Wap|=*6TE>f6TgZk$xd^JN8WMnau8h{*ZoWz?S$$?Ib#t+>RKj3Y8KVWp^Y z@&T#Tr!iX~i=trYlDJXHc@JwPgRpvPJR7P<8vlr{Dl;vYa+#+%$e*z)89pH%}h>6&P_%Spb0oLSxa>S`bJ^R&7?x=(;i}qAPr(5p>Yr#Xk1QmN}5)KdRbT{ zG#^(t13fZ5jS;z)E^aY6XPHUEQ$03&{)*^4!{*|%A&HhYubn0oD_WB(WK4WEgt{eX zeD;Whkyh<-781)ktj5|9s?!M`-sBNs%X$4j-MBmdULW1|gf|%w#!Kq-A)piF#mB;t4^+4!H9~W6R6V#5gTg5x3(~Fv7^P zr)A7Ycao?X*(uJ<<^sv{h-Zeoa`UpK;i?qWI9${s$7PRC&&_r^Gt($}kwPOWKdZ;& z)qh3Y`0SL28&inOg6K0b%Zty*N^7J?yPTLaO4XH^l9`*AlB?v+L)SW!>LT&s>FH=W zd8|WZ#0-oc(=nDzrGb=#Pe>@D14-p6jyY`Hl$e;}gbPk|W@pmijixa0NwekI4Wg$g zl5^$O%xfXXnVySwlsFSJ+PN5$V#Js|4@1=yHq?|KYC3;v`dkJEJXhwx?1qwnj;$#e z>*ld}cU)F#+FYe+0+9M)1LewMq$~m(F^l<-%r`sTp)Lj|^47ZoqU6FunIhIiF)kL2 zp-oUE?p~xRd?QK4GfdJO17S)n2R2TD8y^5Crm;ep<{ew(16TO4#vruV>1^WPNXZUT z%%K|tnc$T^bWF{L3Q5Z-{)*vDo7+wyIU76_UXwYi(xa4Jo96|{4uuZ#o^z^5JrzB4x5*g zoR>FxTr1G;tV_-9lyD^Y7p{-k@ zSYT&Y!U4*1U^=wlJ;7^0cGQUX^^<7>0uGHY6?~F`fA4u7FWtaz5PXh--y!(92L4OI zyAAv|f-f@gKMKCoz#kR-3Il&q@MQ-6yx>H}J~^KiR;)EckQ-|E}QY8u$vq7a90!!LKmz zUkQG-fj=bp3Iks+_?-s+lHm6l_%@5V9()GAtKcsh_>{AvTgLhuy^{$;`MH1Oqu z-)G=A3%>Le*C)0SX#;k1Y!NQ7-ZHdl%YKA@O317z?VD z_}iuUJ0-rGmI$sj5`U+}@00j^iLaITe@MJf;_s69dWr8Z@!|DcI4bKTiI0%@*%IGZ z;-z9KkrMy96hB(xb0t1T;!RRQc8Q-R#ZQoUv89NGPL_BY&1grG#9z`#T+=09Y;|R! zITF7|ia%H4wY@78?3Va@r1(V=uYChZ!KD(9Ei3x5LgKMCML)_UUThg;VXGxRSkha$ z#NV!`q9_#--(QMfDe=do_&X(D^Ys*5Bk|u$@%Kr*wg-uVYbD+-#rH}4PKmFV_y9@H zixMxk=JBUa^GIa3?@H-}NW9qU#X`*zUnRv4m-s*_-w25pTc+4keI>rL6hBhpuaWp@ ziML36jKrHI-Y)Ul9x%!{LE^C$NFZ6P)WSDmyd$yN<0R7 z`r(%NO*)I;pOScN71NJWiC1+Nzd0rGt0cZm;;}VOKUPaTwleBRxx{yp%3C4vK@wjn z@l*6v6lJHxzajB85|6EY`ms;q#nxvQRx9z?il!evi9e{b_�Yv9(V>E=qhSoyE-= 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 literal 0 HcmV?d00001 diff --git a/Plxlibrary/MdioSpliceUsb.h b/Plxlibrary/MdioSpliceUsb.h new file mode 100755 index 0000000..ce14e84 --- /dev/null +++ b/Plxlibrary/MdioSpliceUsb.h @@ -0,0 +1,315 @@ +#ifndef __MDIO_SPLICE_USB_H +#define __MDIO_SPLICE_USB_H + +/******************************************************************************* + * Copyright 2013-2019 Broadcom, Inc + * Copyright (c) 2009 to 2012 PLX Technology Inc. All rights reserved. + * + * This software is available to you under a choice of one of two + * licenses. You may choose to be licensed under the terms of the GNU + * General Public License (GPL) Version 2, available from the file + * COPYING in the main directorY of this source tree, or the + * BSD license below: + * + * Redistribution and use in source and binary forms, with or + * without modification, are permitted provided that the following + * conditions are met: + * + * - Redistributions of source code must retain the above + * copyright notice, this list of conditions and the following + * disclaimer. + * + * - Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + ******************************************************************************/ + +/******************************************************************************* + * + * File Name: + * + * MdioSpliceUsb.h + * + * Description: + * + * Header file for Splice MDIO USB interface functions + * + * Revision History: + * + * 03-01-18: PLX SDK v8.00 + * + ******************************************************************************/ + + +#include "PlxIoctl.h" +#if defined(PLX_LINUX) + #include // For dynamic library functions +#endif + + + + +#ifdef __cplusplus +extern "C" { +#endif + + +/****************************************** + * Definitions + ******************************************/ +// Defaults for loading the MDIO USB library +#if defined(PLX_MSWINDOWS) + #define MDIO_SPLICE_LIB_NAME "MdioSpliceUsb.dll" + #define MDIO_SPLICE_ROOT_PATH_DEFAULT "C:\\Plx\\PlxSdk\\MdioSpliceUsb" +#elif defined(PLX_LINUX) + #define MDIO_SPLICE_LIB_NAME "" + #define MDIO_SPLICE_ROOT_PATH_DEFAULT "" + + // Linux dynamic library load functions for portability + #define LoadLibrary( name ) dlopen( (name), RTLD_LAZY ) + #define FreeLibrary dlclose + #define GetProcAddress( hdl, fn ) dlsym( (hdl), (fn) ) + typedef void* HINSTANCE; + #define TEXT( str ) (str) + #define __cdecl +#elif defined(PLX_DOS) + #define __cdecl +#endif + +#define MDIO_MAX_DEVICES 10 // Max MDIO USB devices supported +#define MDIO_DEFAULT_CLOCK_RATE 100 // MDIO default clock rate in Khz + +// Splice API status codes +#define MDIO_SPLICE_STATUS_OK 0 +#define MDIO_SPLICE_STATUS_ERROR 1 +typedef int MDIO_SPLICE_STATUS; + +// Invalid entry when looking up an address for corresponding MDIO command +#define MDIO_ADDR_TABLE_IDX_INVALID (U16)0xFFFF + +// Build a 32-bit ID to identify the last accessed region +#define MDIO_ACCESS_ID( idx, AddrHigh ) (((U32)(idx) << 16) | (U16)(AddrHigh)) + +// MDIO command build ([28:24]=DEV [20:16]=PHY/Port [15:0]=Address/data) +#define MDIO_CMD_BUILD( phy, dev, data ) ( ((U32)(dev) << 24) | \ + ((U32)(phy) << 16) | \ + ((U32)(data) & 0xFFFF) ) + +// Set data field ([15:0]) in MDIO command +#define MDIO_CMD_SET_DATA( cmd, data ) ( (cmd) = ((cmd) & 0xFFFF0000) | \ + ((data) & 0xFFFF) ) + +// Register read value to return on error +#define MDIO_REG_READ_U32_FAIL_VAL ((U32)-1) + + + + +/****************************************** + * Device Selection Functions + *****************************************/ +PLX_STATUS +MdioSplice_DeviceOpen( + PLX_DEVICE_OBJECT *pDevice + ); + +PLX_STATUS +MdioSplice_DeviceClose( + PLX_DEVICE_OBJECT *pDevice + ); + +PLX_STATUS +MdioSplice_DeviceFindEx( + PLX_DEVICE_KEY *pKey, + U16 DeviceNumber, + PLX_MODE_PROP *pModeProp + ); + + +/****************************************** + * MDIO Private Support Functions + *****************************************/ +BOOLEAN +MdioSplice_Driver_Connect( + PLX_DEVICE_OBJECT *pDevice, + PLX_MODE_PROP *pModeProp + ); + +S32 +MdioSplice_Dispatch_IoControl( + PLX_DEVICE_OBJECT *pDevice, + U32 IoControlCode, + PLX_PARAMS *pIoBuffer, + U32 Size + ); + + +/****************************************** + * Device-specific Register Access Functions + *****************************************/ +U32 +MdioSplice_PlxRegisterRead( + PLX_DEVICE_OBJECT *pDevice, + U32 offset, + PLX_STATUS *pStatus, + BOOLEAN bAdjustForPort, + U16 bRetryOnError + ); + +PLX_STATUS +MdioSplice_PlxRegisterWrite( + PLX_DEVICE_OBJECT *pDevice, + U32 offset, + U32 value, + BOOLEAN bAdjustForPort + ); + + +/****************************************** + * Private functions + *****************************************/ +U16 +MdioGetAccessTableIndex( + U32 Address + ); + + +/****************************************** + * Splice MDIO library functions + *****************************************/ + +/************************************************************************************************* + * Function: UsbConnect() + * + * Arguments: port - This port handle will be returned and used in calls to + * Read/Write functions listed below such as + * UsbReadMdio(port), + * UsbWriteMdio(port) + * root - Root directory for all the dll, firmware, etc. + * dev - Target device "D6S" in this case + * index - first Splice board = 0, second = 1 + * + * Description: Opens a communication link between the application and the USB device. + * + * Return: 0 - on success otherwise failure. + * 1 - Failed to find Splice USB Device + * 2 - Failed to connect to Splice Board + * 3 - Failed to Program USB Firmware + * 4 - Failed to Re-Connect to USB after USB Firmware Programming + * 5 - Failed to Program FPGA Firmware + * 6 - Failed to Program FPGA Firmware + * 7 - Failed to verify FPGA version after FPGA Firmware Programming + *************************************************************************************************/ +typedef int (__cdecl *Fn_UsbConnect)(void **port, const char *root, const char *dev, unsigned int index); + + + + +/************************************************************************************************* + * Function: UsbDisConnect() + * Arguments: port - An opaque port handle of type (void *) returned from + * UsbConnect() function call. + * + * Description: Closes the specified port and ends the communication to the USB device. + * + * Return: 0 on success and 1 on failure. + *************************************************************************************************/ +typedef int (__cdecl *Fn_UsbDisConnect)(void *port); + + + + +/************************************************************************************************* + * Function: UsbReadMdio() + * + * Arguments: port - An opaque port handle of type (void *) returned from + * UsbConnect() function call. + * addr - This is addr array of size count to read from. + * data - This is data array of size count to read into. + * count - This is the length of data and addr array pairs. + * b32 - set 1 for 32-bit MDIO, 0 for 16-bit MDIO + * + * Description: Reads data from MDIO registers on a device from addr -> (addr + count) + * + * Return: 0 on success and 1 on failure. + *************************************************************************************************/ +typedef int (__cdecl *Fn_UsbReadMdio)(const void *port, const void *addr, void *data, unsigned int count, unsigned int b32); + + + + +/************************************************************************************************* + * Function: UsbWriteMdio() + * + * Arguments: port - An opaque port handle of type (void *) returned from + * UsbConnect() function call. + * addr - This is addr array of size count to write to. + * - Address Format is as Follows: + * - Bits [28:24] = DEVTYPE + * - Bits [20:16] = PHYADDR + * - Bits [15:00] = MDIO Address + * data - This is data array of size count to write to. + * count - This is the length of data and addr array pairs. + * b32 - set 1 for 32-bit MDIO, 0 for 16-bit MDIO + * + * Description: Writes data to MDIO registers on a device from addr -> (addr + count) + * + * Return: 0 on success and 1 on failure. + *************************************************************************************************/ +typedef int (__cdecl *Fn_UsbWriteMdio)(const void *port, const void *addr, const void *data, unsigned int count, unsigned int b32); + + + +/************************************************************************************************* + * Function: UsbReadCfgReg() + * + * Arguments: port - An opaque port handle of type (void *) returned from + * UsbConnect() function call. + * addr - This is addr array of size count to read from. + * - Address Format is as Follows: + * - Bits [28:24] = DEVTYPE + * - Bits [20:16] = PHYADDR + * - Bits [15:00] = MDIO Address + * data - This is data array of size count to read into. + * count - This is the length of data and addr array pairs. + * + * Description: Reads data from config registers on a device from addr -> (addr + count) + * + * Return: 0 on success and 1 on failure. + *************************************************************************************************/ +typedef int (__cdecl *Fn_UsbReadCfgReg)(const void *port, const void *addr, void *data, unsigned int count); + + + +/************************************************************************************************* + * Function: UsbWriteCfgReg() + * + * Arguments: port - An opaque port handle of type (void *) returned from + * UsbConnect() function call. + * addr - This is addr array of size count to write to. + * data - This is data array of size count to write to. + * count - This is the length of data and addr array pairs. + * + * Description: Wites data to config registers on a device from addr -> (addr + count) + * + * Return: 0 on success and 1 on failure. + *************************************************************************************************/ +typedef int (__cdecl *Fn_UsbWriteCfgReg)(const void *port, const void *addr, void *data, unsigned int count); + + + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/Plxlibrary/PciRegs.h b/Plxlibrary/PciRegs.h new file mode 100755 index 0000000..6a18b6f --- /dev/null +++ b/Plxlibrary/PciRegs.h @@ -0,0 +1,345 @@ +#ifndef __PCI_REGS_H +#define __PCI_REGS_H + +/******************************************************************************* + * Copyright 2013-2020 Broadcom, Inc. + * Copyright (c) 2009 to 2012 PLX Technology Inc. All rights reserved. + * + * This software is available to you under a choice of one of two + * licenses. You may choose to be licensed under the terms of the GNU + * General Public License (GPL) Version 2, available from the file + * COPYING in the main directorY of this source tree, or the + * BSD license below: + * + * Redistribution and use in source and binary forms, with or + * without modification, are permitted provided that the following + * conditions are met: + * + * - Redistributions of source code must retain the above + * copyright notice, this list of conditions and the following + * disclaimer. + * + * - Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + ******************************************************************************/ + +/****************************************************************************** + * + * File Name: + * + * PciRegs.h + * + * Description: + * + * This file defines the generic PCI Configuration Registers + * + * Revision: + * + * 01-01-20 : PCI/PCIe SDK v8.10 + * + ******************************************************************************/ + + + +// PCI location max counts +#define PCI_MAX_BUS 256 // Max PCI Buses +#define PCI_MAX_DEV 32 // Max PCI Slots +#define PCI_MAX_FUNC 8 // Max PCI Functions + +// PCI config space sizes +#define PCI_CONFIG_SPACE_SIZE 0x100 // PCI = 256B +#define PCIE_CONFIG_SPACE_SIZE 0x1000 // PCIe = 4K + +// PCI register read error values return to software +#define PCI_CFG_RD_ERR_VAL_8 ((U8)-1) +#define PCI_CFG_RD_ERR_VAL_16 ((U16)-1) +#define PCI_CFG_RD_ERR_VAL_32 ((U32)-1) +#define PCI_CFG_RD_ERR_VAL PCI_CFG_RD_ERR_VAL_32 + +// Special values returned for ID read if CRS SW visibility enabled +#define PCIE_CFG_RD_CRS_VAL_16 (U16)0x0001 +#define PCIE_CFG_RD_CRS_VAL_32 (U32)0xFFFF0001 + +// PCI Header types +#define PCI_HDR_TYPE_0 0 // Endpoint +#define PCI_HDR_TYPE_1 1 // PCI-to-PCI bridge +#define PCI_HDR_TYPE_2 2 // Cardbus +#define PCI_NUM_BARS_TYPE_00 6 // Type 0 total PCI BARs +#define PCI_NUM_BARS_TYPE_01 2 // Type 1 total PCI BARs + +// Standard PCI registers +#define PCI_REG_DEV_VEN_ID 0x00 +#define PCI_REG_CMD_STAT 0x04 +#define PCI_REG_CLASS_REV 0x08 +#define PCI_REG_HDR_CACHE_LN 0x0C +#define PCI_REG_BAR_0 0x10 +#define PCI_REG_BAR_1 0x14 +#define PCI_REG_CAP_PTR 0x34 +#define PCI_REG_INT_PIN_LN 0x3C + +// Type 0 specific standard registers +#define PCI_REG_T0_BAR_2 0x18 +#define PCI_REG_T0_BAR_3 0x1C +#define PCI_REG_T0_BAR_4 0x20 +#define PCI_REG_T0_BAR_5 0x24 +#define PCI_REG_TO_CARDBUS_PTR 0x28 +#define PCI_REG_TO_SUBSYS_ID 0x2C +#define PCI_REG_TO_EXP_ROM 0x30 +#define PCI_REG_TO_RSVD_38H 0x38 + +// Type 1 specific standard registers +#define PCI_REG_T1_PRIM_SEC_BUS 0x18 +#define PCI_REG_T1_IO_BASE_LIM 0x1C +#define PCI_REG_T1_MEM_BASE_LIM 0x20 +#define PCI_REG_T1_PF_MEM_BASE_LIM 0x24 +#define PCI_REG_T1_PF_MEM_BASE_HIGH 0x28 +#define PCI_REG_T1_PF_MEM_LIM_HIGH 0x2C +#define PCI_REG_T1_IO_BASE_LIM_HIGH 0x30 +#define PCI_REG_T1_EXP_ROM 0x38 + +// PCIe 1st capability pointer +#define PCIE_REG_CAP_PTR 0x100 + + +// PCI Extended Capability IDs +#define PCI_CAP_ID_NULL 0x00 +#define PCI_CAP_ID_POWER_MAN 0x01 +#define PCI_CAP_ID_AGP 0x02 +#define PCI_CAP_ID_VPD 0x03 +#define PCI_CAP_ID_SLOT_ID 0x04 +#define PCI_CAP_ID_MSI 0x05 +#define PCI_CAP_ID_HOT_SWAP 0x06 +#define PCI_CAP_ID_PCIX 0x07 +#define PCI_CAP_ID_HYPER_TRANSPORT 0x08 +#define PCI_CAP_ID_VENDOR_SPECIFIC 0x09 +#define PCI_CAP_ID_DEBUG_PORT 0x0A +#define PCI_CAP_ID_RESOURCE_CTRL 0x0B +#define PCI_CAP_ID_HOT_PLUG 0x0C +#define PCI_CAP_ID_BRIDGE_SUB_ID 0x0D +#define PCI_CAP_ID_AGP_8X 0x0E +#define PCI_CAP_ID_SECURE_DEVICE 0x0F +#define PCI_CAP_ID_PCI_EXPRESS 0x10 +#define PCI_CAP_ID_MSI_X 0x11 +#define PCI_CAP_ID_SATA 0x12 +#define PCI_CAP_ID_ADV_FEATURES 0x13 +#define PCI_CAP_ID_ENHANCED_ALLOCATION 0x14 +#define PCI_CAP_ID_FLATTENING_PORTAL_BRIDGE 0x15 + + +// PCI Express Extended Capability IDs +#define PCIE_CAP_ID_NULL 0x000 // Empty capability +#define PCIE_CAP_ID_ADV_ERROR_REPORTING 0x001 // Advanced Error Reporting (AER) +#define PCIE_CAP_ID_VIRTUAL_CHANNEL 0x002 // Virtual Channel (VC) +#define PCIE_CAP_ID_DEV_SERIAL_NUMBER 0x003 // Device Serial Number +#define PCIE_CAP_ID_POWER_BUDGETING 0x004 // Power Budgeting +#define PCIE_CAP_ID_RC_LINK_DECLARATION 0x005 // Root Complex Link Declaration +#define PCIE_CAP_ID_RC_INT_LINK_CONTROL 0x006 // Root Complex Internal Link Control +#define PCIE_CAP_ID_RC_EVENT_COLLECTOR 0x007 // Root Complex Event Collector Endpoint Association +#define PCIE_CAP_ID_MF_VIRTUAL_CHANNEL 0x008 // Multi-Function Virtual Channel (MFVC) +#define PCIE_CAP_ID_VC_WITH_MULTI_FN 0x009 // Virtual Channel with Multi-Function +#define PCIE_CAP_ID_RC_REG_BLOCK 0x00A // Root Complex Register Block (RCRB) +#define PCIE_CAP_ID_VENDOR_SPECIFIC 0x00B // Vendor-specific (VSEC) +#define PCIE_CAP_ID_CONFIG_ACCESS_CORR 0x00C // Configuration Access Correlation +#define PCIE_CAP_ID_ACCESS_CTRL_SERVICES 0x00D // Access Control Services (ACS) +#define PCIE_CAP_ID_ALT_ROUTE_ID_INTERPRET 0x00E // Alternate Routing-ID Interpretation (ARI) +#define PCIE_CAP_ID_ADDR_TRANS_SERVICES 0x00F // Address Translation Services (ATS) +#define PCIE_CAP_ID_SR_IOV 0x010 // SR-IOV +#define PCIE_CAP_ID_MR_IOV 0x011 // MR-IOV +#define PCIE_CAP_ID_MULTICAST 0x012 // Multicast +#define PCIE_CAP_ID_PAGE_REQUEST 0x013 // Page Request Interface (PRI) +#define PCIE_CAP_ID_AMD_RESERVED 0x014 // Reserved for AMD +#define PCIE_CAP_ID_RESIZABLE_BAR 0x015 // Resizable BAR +#define PCIE_CAP_ID_DYNAMIC_POWER_ALLOC 0x016 // Dynamic Power Allocation (DPA) +#define PCIE_CAP_ID_TLP_PROCESSING_HINT 0x017 // TLP Processing Hints (TPH) +#define PCIE_CAP_ID_LATENCY_TOLERANCE_REPORT 0x018 // Latency Tolerance Reporting (LTR) +#define PCIE_CAP_ID_SECONDARY_PCI_EXPRESS 0x019 // Secondary PCI Express +#define PCIE_CAP_ID_PROTOCOL_MULTIPLEX 0x01A // Protocol Multiplexing (PMUX) +#define PCIE_CAP_ID_PROCESS_ADDR_SPACE_ID 0x01B // Process Address Space ID (PASID) +#define PCIE_CAP_ID_LTWT_NOTIF_REQUESTER 0x01C // Lightweight Notification Requester (LNR) +#define PCIE_CAP_ID_DS_PORT_CONTAINMENT 0x01D // Downstream Port Containment (DPC) +#define PCIE_CAP_ID_L1_PM_SUBSTRATES 0x01E // L1 Power Management Substrates (L1PM) +#define PCIE_CAP_ID_PRECISION_TIME_MEAS 0x01F // Precision Time Measurement (PTM) +#define PCIE_CAP_ID_PCIE_OVER_M_PHY 0x020 // PCIe over M-PHY (M-PCIe) +#define PCIE_CAP_ID_FRS_QUEUEING 0x021 // FRS Queueing +#define PCIE_CAP_ID_READINESS_TIME_REPORTING 0x022 // Readiness Time Reporting +#define PCIE_CAP_ID_DESIGNATED_VEND_SPECIFIC 0x023 // Designated vendor-specific +#define PCIE_CAP_ID_VF_RESIZABLE_BAR 0x024 // VF resizable BAR +#define PCIE_CAP_ID_DATA_LINK_FEATURE 0x025 // Data Link Feature +#define PCIE_CAP_ID_PHYS_LAYER_16GT 0x026 // Physical Layer 16 GT/s +#define PCIE_CAP_ID_PHYS_LAYER_16GT_MARGINING 0x027 // Physical Layer 16 GT/s Margining +#define PCIE_CAP_ID_HIERARCHY_ID 0x028 // Hierarchy ID +#define PCIE_CAP_ID_NATIVE_PCIE_ENCL_MGMT 0x029 // Native PCIe Enclosure Management (NPEM) +#define PCIE_CAP_ID_PHYS_LAYER_32GT 0x02A // Physical Layer 32 GT/s +#define PCIE_CAP_ID_ALTERNATE_PROTOCOL 0x02B // Alternate Protocol +#define PCIE_CAP_ID_SYS_FW_INTERMEDIARY 0x02C // System Firmware Intermediary (SFI) + + +// Convert encoding of MPS/MRR to bytes (128 * (2 ^ encoded_val)) +#define PCIE_MPS_MRR_TO_BYTES(val) ( 128 * (1 << (val)) ) + + +// PCI device Power Management states (PM Cntrl/Stat [1:0]) +#define PCI_CAP_PM_STATE_D0 0x00 +#define PCI_CAP_PM_STATE_D1 0x01 +#define PCI_CAP_PM_STATE_D2 0x02 +#define PCI_CAP_PM_STATE_D3_HOT 0x03 + + +// Function codes for PCI BIOS operations +#define PCI_FUNC_ID 0xb1 +#define PCI_FUNC_BIOS_PRESENT 0x01 +#define PCI_FUNC_FIND_PCI_DEVICE 0x02 +#define PCI_FUNC_FIND_PCI_CLASS_CODE 0x03 +#define PCI_FUNC_GENERATE_SPECIAL_CYC 0x06 +#define PCI_FUNC_READ_CONFIG_BYTE 0x08 +#define PCI_FUNC_READ_CONFIG_WORD 0x09 +#define PCI_FUNC_READ_CONFIG_DWORD 0x0a +#define PCI_FUNC_WRITE_CONFIG_BYTE 0x0b +#define PCI_FUNC_WRITE_CONFIG_WORD 0x0c +#define PCI_FUNC_WRITE_CONFIG_DWORD 0x0d +#define PCI_FUNC_GET_IRQ_ROUTING_OPTS 0x0e +#define PCI_FUNC_SET_PCI_HW_INT 0x0f + + +// PCI SIG Vendor IDs +#define PLX_PCI_VENDOR_ID_LSI 0x1000 +#define PLX_PCI_VENDOR_ID_PLX 0x10B5 +#define PLX_PCI_VENDOR_ID_BROADCOM 0x14E4 +#define PLX_PCI_VENDOR_ID_AMD 0x1022 +#define PLX_PCI_VENDOR_ID_HEWLETT_PACKARD 0x103C +#define PLX_PCI_VENDOR_ID_HP_ENTERPRISE 0x1590 +#define PLX_PCI_VENDOR_ID_HITACHI 0x1054 +#define PLX_PCI_VENDOR_ID_HUAWEI 0x19E5 +#define PLX_PCI_VENDOR_ID_IBM 0x1014 +#define PLX_PCI_VENDOR_ID_INTEL 0x8086 +#define PLX_PCI_VENDOR_ID_LENOVO 0x1D49 +#define PLX_PCI_VENDOR_ID_MARVELL 0x1148 +#define PLX_PCI_VENDOR_ID_MATROX 0x102B +#define PLX_PCI_VENDOR_ID_MELLANOX 0x15B3 +#define PLX_PCI_VENDOR_ID_NETAPP 0x1275 +#define PLX_PCI_VENDOR_ID_NVIDIA 0x10DE +#define PLX_PCI_VENDOR_ID_QUALCOMM 0x5143 +#define PLX_PCI_VENDOR_ID_REALTEK 0x10EC +#define PLX_PCI_VENDOR_ID_SAMSUNG 0x144D +#define PLX_PCI_VENDOR_ID_SEAGATE 0x1BB1 +#define PLX_PCI_VENDOR_ID_TOSHIBA 0x1179 +#define PLX_PCI_VENDOR_ID_WESTERN_DIGITAL 0x1B96 + + +// PCIe ReqID support macros +#define PCIE_REQID_BUILD(bus,dev,fn) (((U16)(bus) << 8) | ((dev) << 3) | ((fn) << 0)) +#define PCIE_REQID_BUS(ReqId) ((U8)((ReqId) >> 8) & 0xFF) +#define PCIE_REQID_DEV(ReqId) ((U8)((ReqId) >> 3) & 0x1F) +#define PCIE_REQID_FN(ReqId) ((U8)((ReqId) >> 0) & 0x7) + + + +// PCIe TLP format +typedef enum _PCIE_TLP_FORMAT +{ + PCIE_TLP_FORMAT_3DW_NO_DATA = 0x0, + PCIE_TLP_FORMAT_4DW_NO_DATA = 0x1, + PCIE_TLP_FORMAT_3DW_DATA = 0x2, + PCIE_TLP_FORMAT_4DW_DATA = 0x3, + PCIE_TLP_FORMAT_TLP_PREFIX = 0x4 +} PCIE_TLP_FORMAT; + + +// PCIe TLP Types +typedef enum _PCIE_TLP_TYPE +{ + TLP_TYPE_MEM_READ_32 = 0x00, + TLP_TYPE_MEM_READ_64 = 0x20, + TLP_TYPE_MEM_READ_LOCK_32 = 0x01, + TLP_TYPE_MEM_READ_LOCK_64 = 0x21, + TLP_TYPE_MEM_WRITE_32 = 0x40, + TLP_TYPE_MEM_WRITE_64 = 0x60, + TLP_TYPE_IO_READ = 0x02, + TLP_TYPE_IO_WRITE = 0x42, + TLP_TYPE_CFG_READ_TYPE_0 = 0x04, + TLP_TYPE_CFG_WRITE_TYPE_0 = 0x44, + TLP_TYPE_CFG_READ_TYPE_1 = 0x05, + TLP_TYPE_CFG_WRITE_TYPE_1 = 0x45, + TLP_TYPE_MSG_TO_RC = 0x30, + TLP_TYPE_MSG_BY_ADDRESS = 0x31, + TLP_TYPE_MSG_BY_ID = 0x32, + TLP_TYPE_MSG_RC_BROADCAST = 0x33, + TLP_TYPE_MSG_TO_RECEIVER = 0x34, + TLP_TYPE_MSG_GATHERED_TO_RC = 0x35, + TLP_TYPE_MSGD_TO_RC = 0x70, + TLP_TYPE_MSGD_BY_ADDRESS = 0x71, + TLP_TYPE_MSGD_BY_ID = 0x72, + TLP_TYPE_MSGD_RC_BROADCAST = 0x73, + TLP_TYPE_MSGD_TO_RECEIVER = 0x74, + TLP_TYPE_MSGD_GATHERED_TO_RC = 0x75, + TLP_TYPE_CPL_NO_DATA = 0x0A, + TLP_TYPE_CPL_WITH_DATA = 0x4A, + TLP_TYPE_CPL_LOCKED_NO_DATA = 0x0B, + TLP_TYPE_CPL_LOCKED_WITH_DATA = 0x4B, + TLP_TYPE_FINAL_ENTRY = 0xFF // Must be last entry +} PCIE_TLP_TYPE; + + +// PCIe Completion TLP status +typedef enum _PCIE_TLP_CPL_STATUS +{ + TLP_CPL_STATUS_SUCCESS = 0x00, + TLP_CPL_STATUS_UNSUPP_REQ = 0x01, + TLP_CPL_STATUS_CONFIG_RETRY = 0x02, + TLP_CPL_STATUS_COMPLETER_ABORT = 0x04 +} PCIE_TLP_CPL_STATUS; + + +// PCIe Message TLP routing +typedef enum _PCIE_TLP_MSG_ROUTE +{ + TLP_MSG_ROUTE_TO_RC = 0x00, + TLP_MSG_ROUTE_BY_ADDR = 0x01, + TLP_MSG_ROUTE_BY_ID = 0x02, + TLP_MSG_ROUTE_RC_BROADCAST = 0x03, + TLP_MSG_ROUTE_LOCAL_TERMINATE = 0x04, + TLP_MSG_ROUTE_GATHERED_TO_RC = 0x05, +} PCIE_TLP_MSG_ROUTE; + + +// PCIe Message TLP types +typedef enum _PCIE_TLP_MSG +{ + TLP_MSG_UNLOCK = 0x00, + TLP_MSG_LATENCY_TOLERANCE_REP = 0x10, + TLP_MSG_OPT_BUFF_FLUSH_FILL = 0x12, + TLP_MSG_PM_ACTIVE_STATE_NAK = 0x14, + TLP_MSG_PM_PME = 0x18, + TLP_MSG_PM_PME_TURN_OFF = 0x19, + TLP_MSG_PM_PME_TO_ACK = 0x1B, + TLP_MSG_ERROR_CORRECTABLE = 0x30, + TLP_MSG_ERROR_NON_FATAL = 0x31, + TLP_MSG_ERROR_FATAL = 0x33, + TLP_MSG_ASSERT_INTA = 0x20, + TLP_MSG_ASSERT_INTB = 0x21, + TLP_MSG_ASSERT_INTC = 0x22, + TLP_MSG_ASSERT_INTD = 0x23, + TLP_MSG_DEASSERT_INTA = 0x24, + TLP_MSG_DEASSERT_INTB = 0x25, + TLP_MSG_DEASSERT_INTC = 0x26, + TLP_MSG_DEASSERT_INTD = 0x27, + TLP_MSG_SET_SLOT_POWER_LIMIT = 0x50, + TLP_MSG_VENDOR_DEFINED_TYPE_0 = 0x7E, + TLP_MSG_VENDOR_DEFINED_TYPE_1 = 0x7F, + TLP_MSG_FINAL_ENTRY = 0xFF // Must be last entry +} PCIE_TLP_MSG; + + + +#endif diff --git a/Plxlibrary/PciTypes.h b/Plxlibrary/PciTypes.h new file mode 100755 index 0000000..b715be7 --- /dev/null +++ b/Plxlibrary/PciTypes.h @@ -0,0 +1,388 @@ +#ifndef __PCI_TYPES_H +#define __PCI_TYPES_H + +/******************************************************************************* + * Copyright 2013-2017 Avago Technologies + * Copyright (c) 2009 to 2012 PLX Technology Inc. All rights reserved. + * + * This software is available to you under a choice of one of two + * licenses. You may choose to be licensed under the terms of the GNU + * General Public License (GPL) Version 2, available from the file + * COPYING in the main directorY of this source tree, or the + * BSD license below: + * + * Redistribution and use in source and binary forms, with or + * without modification, are permitted provided that the following + * conditions are met: + * + * - Redistributions of source code must retain the above + * copyright notice, this list of conditions and the following + * disclaimer. + * + * - Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + ******************************************************************************/ + +/****************************************************************************** + * + * File Name: + * + * PciTypes.h + * + * Description: + * + * This file defines the basic types + * + * Revision: + * + * 06-01-19 : PLX SDK v8.00 + * + ******************************************************************************/ + + +#if defined(PLX_WDM_DRIVER) + #include // WDM Driver types +#endif + +#if defined(PLX_NT_DRIVER) + #include // NT Kernel Mode Driver (ie PLX Service) +#endif + +#if defined(PLX_MSWINDOWS) + #if !defined(PLX_DRIVER) + #include // Windows application level types + #endif +#endif + +// Must be placed before to prevent compile errors +#if defined(PLX_LINUX) && !defined(PLX_LINUX_DRIVER) + #include // To automatically add mem*() set of functions +#endif + +#if defined(PLX_LINUX) || defined(PLX_LINUX_DRIVER) + #include // Linux types +#endif + +#if defined(PLX_LINUX) + #include // For MAX_SCHEDULE_TIMEOUT in Linux applications +#endif + + +#ifdef __cplusplus +extern "C" { +#endif + + + +/******************************************* + * Linux Application Level Definitions + ******************************************/ +#if defined(PLX_LINUX) + typedef __s8 S8; + typedef __u8 U8; + typedef __s16 S16; + typedef __u16 U16; + typedef __s32 S32; + typedef __u32 U32; + typedef __s64 S64; + typedef __u64 U64; + typedef signed long PLX_INT_PTR; // For 32/64-bit code compatability + typedef unsigned long PLX_UINT_PTR; + typedef int HANDLE; + typedef int PLX_DRIVER_HANDLE; // Linux-specific driver handle + + #define INVALID_HANDLE_VALUE (HANDLE)-1 + + #if !defined(MAX_SCHEDULE_TIMEOUT) + #define MAX_SCHEDULE_TIMEOUT LONG_MAX + #endif +#endif + + + +/******************************************* + * Linux Kernel Level Definitions + ******************************************/ +#if defined(PLX_LINUX_DRIVER) + typedef s8 S8; + typedef u8 U8; + typedef s16 S16; + typedef u16 U16; + typedef s32 S32; + typedef u32 U32; + typedef s64 S64; + typedef u64 U64; + typedef signed long PLX_INT_PTR; // For 32/64-bit code compatability + typedef unsigned long PLX_UINT_PTR; + typedef int PLX_DRIVER_HANDLE; // Linux-specific driver handle +#endif + + + +/******************************************* + * Windows Type Definitions + ******************************************/ +#if defined(PLX_MSWINDOWS) + typedef signed char S8; + typedef unsigned char U8; + typedef signed short S16; + typedef unsigned short U16; + typedef signed long S32; + typedef unsigned long U32; + typedef signed __int64 S64; + typedef unsigned __int64 U64; + typedef INT_PTR PLX_INT_PTR; // For 32/64-bit code compatability + typedef UINT_PTR PLX_UINT_PTR; + typedef HANDLE PLX_DRIVER_HANDLE; // Windows-specific driver handle + + #if defined(_DEBUG) + #define PLX_DEBUG + #endif +#endif + + + +/******************************************* + * Windows WDM Driver Compatability + ******************************************/ +#if defined(PLX_WDM_DRIVER) + // RtlIsNtDdiVersionAvailable supported in Windows Vista & higher + #if (WINVER < 0x600) + #define RtlIsNtDdiVersionAvailable(ver) IoIsWdmVersionAvailable( (U8)(ver >> 24), (U8)(ver >> 16) ) + + // Windows versions taken from SdkDdkVer.h + #define NTDDI_WIN2K 0x01100000 // WDM=1.10 Winver=5.00 + #define NTDDI_WINXP 0x01200000 // WDM=1.20 Winver=5.01 + #define NTDDI_WS03 0x01300000 // WDM=1.30 Winver=5.02 + #endif + + #if (WINVER < 0x601) + #define NTDDI_WIN6 0x06000000 + #define NTDDI_WIN6SP1 0x06000100 + #define NTDDI_VISTA NTDDI_WIN6 + #define NTDDI_WS08 NTDDI_WIN6SP1 + #define NTDDI_WIN7 0x06010000 + #endif + + #if (WINVER < 0x602) + #define NTDDI_WIN8 0x06020000 + #define NTDDI_WIN10 0x0A000000 + #endif + + #if (WINVER < 0x603) + #define NTDDI_WINBLUE 0x06030000 // Windows 8.1 + #endif + + #if (WINVER < 0xA00) + #define NTDDI_WIN10 0x0A000000 + #endif + + // Additional Win8+ DDK definitions + #if (NTDDI_VER < NTDDI_WIN8) + // More POOL_TYPEs added, needed for no-execute + typedef enum _PLX_POOL_TYPE + { + NonPagedPoolBase = 0, + NonPagedPoolBaseMustSucceed = NonPagedPoolBase + 2, + NonPagedPoolBaseCacheAligned = NonPagedPoolBase + 4, + NonPagedPoolBaseCacheAlignedMustS = NonPagedPoolBase + 6, + + NonPagedPoolNx = 512, + NonPagedPoolNxCacheAligned = NonPagedPoolNx + 4, + NonPagedPoolSessionNx = NonPagedPoolNx + 32 + } PLX_POOL_TYPE; + + // Additional -OR- flags for MM_PAGE_PRIORITY + #define MdlMappingNoWrite 0x80000000 // Create the mapping as nowrite + #define MdlMappingNoExecute 0x40000000 // Create the mapping as noexecute + #endif + + #if (NTDDI_VER < NTDDI_WIN7) + // Win7 DDK added typedef's for registered functions for declaration + typedef + NTSTATUS + DRIVER_INITIALIZE( + struct _DRIVER_OBJECT *DriverObject, + PUNICODE_STRING RegistryPath + ); + + typedef + VOID + DRIVER_UNLOAD( + struct _DRIVER_OBJECT *DriverObject + ); + + typedef + NTSTATUS + DRIVER_ADD_DEVICE( + struct _DRIVER_OBJECT *DriverObject, + struct _DEVICE_OBJECT *PhysicalDeviceObject + ); + + typedef + NTSTATUS + DRIVER_DISPATCH( + struct _DEVICE_OBJECT *DeviceObject, + struct _IRP *Irp + ); + + typedef + VOID + DRIVER_CANCEL( + struct _DEVICE_OBJECT *DeviceObject, + struct _IRP *Irp + ); + + typedef + BOOLEAN + KSERVICE_ROUTINE( + struct _KINTERRUPT *Interrupt, + PVOID ServiceContext + ); + + typedef + VOID + KDEFERRED_ROUTINE( + struct _KDPC *Dpc, + PVOID DeferredContext, + PVOID SystemArgument1, + PVOID SystemArgument2 + ); + + typedef + BOOLEAN + KSYNCHRONIZE_ROUTINE ( + PVOID SynchronizeContext + ); + + typedef + NTSTATUS + IO_COMPLETION_ROUTINE ( + PDEVICE_OBJECT DeviceObject, + PIRP Irp, + PVOID Context + ); + + typedef + VOID + IO_WORKITEM_ROUTINE ( + PDEVICE_OBJECT DeviceObject, + PVOID Context + ); + + typedef + VOID + REQUEST_POWER_COMPLETE ( + PDEVICE_OBJECT DeviceObject, + UCHAR MinorFunction, + POWER_STATE PowerState, + PVOID Context, + PIO_STATUS_BLOCK IoStatus + ); + + #endif +#endif + + + +/******************************************* + * DOS Type Definitions + ******************************************/ +#if defined(PLX_DOS) + typedef signed char S8; + typedef unsigned char U8; + typedef signed short S16; + typedef unsigned short U16; + typedef signed long S32; + typedef unsigned long U32; + typedef signed long long S64; + typedef unsigned long long U64; + typedef S32 PLX_INT_PTR; // For 32/64-bit code compatability + typedef U32 PLX_UINT_PTR; + typedef unsigned long HANDLE; + typedef HANDLE PLX_DRIVER_HANDLE; + #define INVALID_HANDLE_VALUE 0 + + #if !defined(_far) + #define _far + #endif +#endif + + + +/******************************************* + * Volatile Basic Type Definitions + ******************************************/ +typedef volatile S8 VS8; +typedef volatile U8 VU8; +typedef volatile S16 VS16; +typedef volatile U16 VU16; +typedef volatile S32 VS32; +typedef volatile U32 VU32; +typedef volatile S64 VS64; +typedef volatile U64 VU64; + + + +/******************************************* + * Definitions used for ACPI & ECAM probe + ******************************************/ +// Used to scan ROM for services +#define BIOS_MEM_START 0x000E0000 +#define BIOS_MEM_END 0x00100000 + +// ACPI probe states +#define ACPI_PCIE_NOT_PROBED 0 +#define ACPI_PCIE_BYPASS_OS_OK 1 +#define ACPI_PCIE_DEFAULT_TO_OS 2 +#define ACPI_PCIE_ALWAYS_USE_OS 3 + +// ECAM probe definitions +#define ECAM_PROBE_ADDR_MIN 0x80000000 +#define ECAM_PROBE_ADDR_MAX 0xFC000000 +#define ECAM_PROBE_ADDR_INCR 0x01000000 +#define ECAM_PROBE_ADDR_DEFAULT_START 0xC0000000 +#define ECAM_PROBE_ADDR_DEFAULT_END 0xFC000000 + +// Number of PCI registers to compare +#define ECAM_PROBE_REG_CMP_COUNT 4 + +// ECAM address offset +#define ECAM_DEVICE_REG_OFFSET( bus, dev, fn, off ) \ + (U32)( ( (bus) << 20) | \ + ( (dev) << 15) | \ + ( (fn) << 12) | \ + ( (off) << 0) ) + +// ACPI RSDT v1.0 structure +typedef struct _ACPI_RSDT_v1_0 +{ + U32 Signature; + U32 Length; + U8 Revision; + U8 Oem_Id[6]; + U8 Oem_Table_Id[8]; + U32 Oem_Revision; + U32 Creator_Id; + U32 Creator_Revision; +} ACPI_RSDT_v1_0; + + + + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/Plxlibrary/PexApi.h b/Plxlibrary/PexApi.h new file mode 100755 index 0000000..8fc5fe1 --- /dev/null +++ b/Plxlibrary/PexApi.h @@ -0,0 +1,745 @@ +#ifndef __PEX_API_H +#define __PEX_API_H + +/******************************************************************************* + * Copyright 2013-2019 Avago Technologies + * Copyright (c) 2009 to 2012 PLX Technology Inc. All rights reserved. + * + * This software is available to you under a choice of one of two + * licenses. You may choose to be licensed under the terms of the GNU + * General Public License (GPL) Version 2, available from the file + * COPYING in the main directorY of this source tree, or the + * BSD license below: + * + * Redistribution and use in source and binary forms, with or + * without modification, are permitted provided that the following + * conditions are met: + * + * - Redistributions of source code must retain the above + * copyright notice, this list of conditions and the following + * disclaimer. + * + * - Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + ******************************************************************************/ + +/****************************************************************************** + * + * File Name: + * + * PexApi.h + * + * Description: + * + * This file contains all the PLX API function prototypes + * + * Revision: + * + * 09-01-19 : PCI/PCIe SDK v8.10 + * + ******************************************************************************/ + + +#include "PlxTypes.h" + + +#ifdef __cplusplus +extern "C" { +#endif + + +/****************************************** + * Definitions + ******************************************/ +// DLL support +#ifndef EXPORT + #if defined(PLX_MSWINDOWS) + #define EXPORT __declspec(dllexport) + #else + #define EXPORT + #endif +#endif + + + + +/****************************************** + * Device Selection Functions + *****************************************/ +PLX_STATUS EXPORT +PlxPci_DeviceOpen( + PLX_DEVICE_KEY *pKey, + PLX_DEVICE_OBJECT *pDevice + ); + +PLX_STATUS EXPORT +PlxPci_DeviceClose( + PLX_DEVICE_OBJECT *pDevice + ); + +PLX_STATUS EXPORT +PlxPci_DeviceFind( + PLX_DEVICE_KEY *pKey, + U16 DeviceNumber + ); + +PLX_STATUS EXPORT +PlxPci_DeviceFindEx( + PLX_DEVICE_KEY *pKey, + U16 DeviceNumber, + PLX_API_MODE ApiMode, + PLX_MODE_PROP *pModeProp + ); + +PLX_STATUS EXPORT +PlxPci_I2cGetPorts( + PLX_API_MODE ApiMode, + U32 *pI2cPorts + ); + + +/****************************************** + * Query for Information Functions + *****************************************/ +PLX_STATUS EXPORT +PlxPci_ApiVersion( + U8 *pVersionMajor, + U8 *pVersionMinor, + U8 *pVersionRevision + ); + +PLX_STATUS EXPORT +PlxPci_I2cVersion( + U16 I2cPort, + PLX_VERSION *pVersion + ); + +PLX_STATUS EXPORT +PlxPci_DriverVersion( + PLX_DEVICE_OBJECT *pDevice, + U8 *pVersionMajor, + U8 *pVersionMinor, + U8 *pVersionRevision + ); + +PLX_STATUS EXPORT +PlxPci_DriverProperties( + PLX_DEVICE_OBJECT *pDevice, + PLX_DRIVER_PROP *pDriverProp + ); + +PLX_STATUS EXPORT +PlxPci_DriverScheduleRescan( + PLX_DEVICE_OBJECT *pDevice + ); + +PLX_STATUS EXPORT +PlxPci_ChipTypeGet( + PLX_DEVICE_OBJECT *pDevice, + U16 *pChipType, + U8 *pRevision + ); + +PLX_STATUS EXPORT +PlxPci_ChipTypeSet( + PLX_DEVICE_OBJECT *pDevice, + U16 ChipType, + U8 Revision + ); + +PLX_STATUS EXPORT +PlxPci_ChipGetPortMask( + U32 ChipID, + U8 Revision, + PEX_CHIP_FEAT *PtrFeat + ); + +PLX_STATUS EXPORT +PlxPci_GetPortProperties( + PLX_DEVICE_OBJECT *pDevice, + PLX_PORT_PROP *pPortProp + ); + + +/****************************************** + * Device Control Functions + *****************************************/ +PLX_STATUS EXPORT +PlxPci_DeviceReset( + PLX_DEVICE_OBJECT *pDevice + ); + + +/****************************************** + * Register Access Functions + *****************************************/ +U32 EXPORT +PlxPci_PciRegisterRead( + U8 bus, + U8 slot, + U8 function, + U16 offset, + PLX_STATUS *pStatus + ); + +PLX_STATUS EXPORT +PlxPci_PciRegisterWrite( + U8 bus, + U8 slot, + U8 function, + U16 offset, + U32 value + ); + +U32 EXPORT +PlxPci_PciRegisterReadFast( + PLX_DEVICE_OBJECT *pDevice, + U16 offset, + PLX_STATUS *pStatus + ); + +PLX_STATUS EXPORT +PlxPci_PciRegisterWriteFast( + PLX_DEVICE_OBJECT *pDevice, + U16 offset, + U32 value + ); + +U32 EXPORT +PlxPci_PciRegisterRead_BypassOS( + U8 bus, + U8 slot, + U8 function, + U16 offset, + PLX_STATUS *pStatus + ); + +PLX_STATUS EXPORT +PlxPci_PciRegisterWrite_BypassOS( + U8 bus, + U8 slot, + U8 function, + U16 offset, + U32 value + ); + + +/****************************************** + * Device-specific Register Functions + *****************************************/ +U32 EXPORT +PlxPci_PlxRegisterRead( + PLX_DEVICE_OBJECT *pDevice, + U32 offset, + PLX_STATUS *pStatus + ); + +PLX_STATUS EXPORT +PlxPci_PlxRegisterWrite( + PLX_DEVICE_OBJECT *pDevice, + U32 offset, + U32 value + ); + +U32 EXPORT +PlxPci_PlxMappedRegisterRead( + PLX_DEVICE_OBJECT *pDevice, + U32 offset, + PLX_STATUS *pStatus + ); + +PLX_STATUS EXPORT +PlxPci_PlxMappedRegisterWrite( + PLX_DEVICE_OBJECT *pDevice, + U32 offset, + U32 value + ); + +U32 EXPORT +PlxPci_PlxMailboxRead( + PLX_DEVICE_OBJECT *pDevice, + U16 mailbox, + PLX_STATUS *pStatus + ); + +PLX_STATUS EXPORT +PlxPci_PlxMailboxWrite( + PLX_DEVICE_OBJECT *pDevice, + U16 mailbox, + U32 value + ); + + +/****************************************** + * PCI Mapping Functions + *****************************************/ +PLX_STATUS EXPORT +PlxPci_PciBarProperties( + PLX_DEVICE_OBJECT *pDevice, + U8 BarIndex, + PLX_PCI_BAR_PROP *pBarProperties + ); + +PLX_STATUS EXPORT +PlxPci_PciBarMap( + PLX_DEVICE_OBJECT *pDevice, + U8 BarIndex, + VOID **pVa + ); + +PLX_STATUS EXPORT +PlxPci_PciBarUnmap( + PLX_DEVICE_OBJECT *pDevice, + VOID **pVa + ); + + +/****************************************** + * BAR I/O & Memory Access Functions + *****************************************/ +PLX_STATUS EXPORT +PlxPci_IoPortRead( + PLX_DEVICE_OBJECT *pDevice, + U64 port, + VOID *pBuffer, + U32 ByteCount, + PLX_ACCESS_TYPE AccessType + ); + +PLX_STATUS EXPORT +PlxPci_IoPortWrite( + PLX_DEVICE_OBJECT *pDevice, + U64 port, + VOID *pBuffer, + U32 ByteCount, + PLX_ACCESS_TYPE AccessType + ); + +PLX_STATUS EXPORT +PlxPci_PciBarSpaceRead( + PLX_DEVICE_OBJECT *pDevice, + U8 BarIndex, + U32 offset, + VOID *pBuffer, + U32 ByteCount, + PLX_ACCESS_TYPE AccessType, + BOOLEAN bOffsetAsLocalAddr + ); + +PLX_STATUS EXPORT +PlxPci_PciBarSpaceWrite( + PLX_DEVICE_OBJECT *pDevice, + U8 BarIndex, + U32 offset, + VOID *pBuffer, + U32 ByteCount, + PLX_ACCESS_TYPE AccessType, + BOOLEAN bOffsetAsLocalAddr + ); + + +/****************************************** + * Physical Memory Functions + *****************************************/ +PLX_STATUS EXPORT +PlxPci_PhysicalMemoryAllocate( + PLX_DEVICE_OBJECT *pDevice, + PLX_PHYSICAL_MEM *pMemoryInfo, + BOOLEAN bSmallerOk + ); + +PLX_STATUS EXPORT +PlxPci_PhysicalMemoryFree( + PLX_DEVICE_OBJECT *pDevice, + PLX_PHYSICAL_MEM *pMemoryInfo + ); + +PLX_STATUS EXPORT +PlxPci_PhysicalMemoryMap( + PLX_DEVICE_OBJECT *pDevice, + PLX_PHYSICAL_MEM *pMemoryInfo + ); + +PLX_STATUS EXPORT +PlxPci_PhysicalMemoryUnmap( + PLX_DEVICE_OBJECT *pDevice, + PLX_PHYSICAL_MEM *pMemoryInfo + ); + +PLX_STATUS EXPORT +PlxPci_CommonBufferProperties( + PLX_DEVICE_OBJECT *pDevice, + PLX_PHYSICAL_MEM *pMemoryInfo + ); + +PLX_STATUS EXPORT +PlxPci_CommonBufferMap( + PLX_DEVICE_OBJECT *pDevice, + VOID **pVa + ); + +PLX_STATUS EXPORT +PlxPci_CommonBufferUnmap( + PLX_DEVICE_OBJECT *pDevice, + VOID **pVa + ); + + +/****************************************** + * Interrupt Support Functions + *****************************************/ +PLX_STATUS EXPORT +PlxPci_InterruptEnable( + PLX_DEVICE_OBJECT *pDevice, + PLX_INTERRUPT *pPlxIntr + ); + +PLX_STATUS EXPORT +PlxPci_InterruptDisable( + PLX_DEVICE_OBJECT *pDevice, + PLX_INTERRUPT *pPlxIntr + ); + +PLX_STATUS EXPORT +PlxPci_NotificationRegisterFor( + PLX_DEVICE_OBJECT *pDevice, + PLX_INTERRUPT *pPlxIntr, + PLX_NOTIFY_OBJECT *pEvent + ); + +PLX_STATUS EXPORT +PlxPci_NotificationWait( + PLX_DEVICE_OBJECT *pDevice, + PLX_NOTIFY_OBJECT *pEvent, + U64 Timeout_ms + ); + +PLX_STATUS EXPORT +PlxPci_NotificationStatus( + PLX_DEVICE_OBJECT *pDevice, + PLX_NOTIFY_OBJECT *pEvent, + PLX_INTERRUPT *pPlxIntr + ); + +PLX_STATUS EXPORT +PlxPci_NotificationCancel( + PLX_DEVICE_OBJECT *pDevice, + PLX_NOTIFY_OBJECT *pEvent + ); + + +/****************************************** + * Serial EEPROM Access Functions + *****************************************/ +PLX_EEPROM_STATUS EXPORT +PlxPci_EepromPresent( + PLX_DEVICE_OBJECT *pDevice, + PLX_STATUS *pStatus + ); + +BOOLEAN EXPORT +PlxPci_EepromProbe( + PLX_DEVICE_OBJECT *pDevice, + PLX_STATUS *pStatus + ); + +PLX_STATUS EXPORT +PlxPci_EepromGetAddressWidth( + PLX_DEVICE_OBJECT *pDevice, + U8 *pWidth + ); + +PLX_STATUS EXPORT +PlxPci_EepromSetAddressWidth( + PLX_DEVICE_OBJECT *pDevice, + U8 width + ); + +PLX_STATUS EXPORT +PlxPci_EepromCrcUpdate( + PLX_DEVICE_OBJECT *pDevice, + U32 *pCrc, + BOOLEAN bUpdateEeprom + ); + +PLX_STATUS EXPORT +PlxPci_EepromCrcGet( + PLX_DEVICE_OBJECT *pDevice, + U32 *pCrc, + U8 *pCrcStatus + ); + +PLX_STATUS EXPORT +PlxPci_EepromReadByOffset( + PLX_DEVICE_OBJECT *pDevice, + U32 offset, + U32 *pValue + ); + +PLX_STATUS EXPORT +PlxPci_EepromWriteByOffset( + PLX_DEVICE_OBJECT *pDevice, + U32 offset, + U32 value + ); + +PLX_STATUS EXPORT +PlxPci_EepromReadByOffset_16( + PLX_DEVICE_OBJECT *pDevice, + U32 offset, + U16 *pValue + ); + +PLX_STATUS EXPORT +PlxPci_EepromWriteByOffset_16( + PLX_DEVICE_OBJECT *pDevice, + U32 offset, + U16 value + ); + + +/****************************************** + * SPI Flash Functions + *****************************************/ +PLX_STATUS EXPORT +PlxPci_SpiFlashPropGet( + PLX_DEVICE_OBJECT *PtrDev, + U8 ChipSel, + PEX_SPI_OBJ *PtrSpi + ); + +PLX_STATUS EXPORT +PlxPci_SpiFlashErase( + PLX_DEVICE_OBJECT *PtrDev, + PEX_SPI_OBJ *PtrSpi, + U32 StartOffset, + U8 BoolWaitComplete + ); + +PLX_STATUS EXPORT +PlxPci_SpiFlashReadBuffer( + PLX_DEVICE_OBJECT *PtrDev, + PEX_SPI_OBJ *PtrSpi, + U32 StartOffset, + U8 *PtrRxBuff, + U32 SizeRx + ); + +U32 EXPORT +PlxPci_SpiFlashReadByOffset( + PLX_DEVICE_OBJECT *PtrDev, + PEX_SPI_OBJ *PtrSpi, + U32 Offset, + PLX_STATUS *PtrStatus + ); + +PLX_STATUS EXPORT +PlxPci_SpiFlashWriteBuffer( + PLX_DEVICE_OBJECT *PtrDev, + PEX_SPI_OBJ *PtrSpi, + U32 StartOffset, + U8 *PtrTxBuff, + U32 SizeTx + ); + +PLX_STATUS EXPORT +PlxPci_SpiFlashWriteByOffset( + PLX_DEVICE_OBJECT *PtrDev, + PEX_SPI_OBJ *PtrSpi, + U32 Offset, + U32 Data + ); + +PLX_STATUS EXPORT +PlxPci_SpiFlashGetStatus( + PLX_DEVICE_OBJECT *PtrDev, + PEX_SPI_OBJ *PtrSpi + ); + + +/****************************************** + * PLX VPD Functions + *****************************************/ +U32 EXPORT +PlxPci_VpdRead( + PLX_DEVICE_OBJECT *pDevice, + U16 offset, + PLX_STATUS *pStatus + ); + +PLX_STATUS EXPORT +PlxPci_VpdWrite( + PLX_DEVICE_OBJECT *pDevice, + U16 offset, + U32 value + ); + + +/****************************************** + * DMA Functions + *****************************************/ +PLX_STATUS EXPORT +PlxPci_DmaChannelOpen( + PLX_DEVICE_OBJECT *pDevice, + U8 channel, + PLX_DMA_PROP *pDmaProp + ); + +PLX_STATUS EXPORT +PlxPci_DmaGetProperties( + PLX_DEVICE_OBJECT *pDevice, + U8 channel, + PLX_DMA_PROP *pDmaProp + ); + +PLX_STATUS EXPORT +PlxPci_DmaSetProperties( + PLX_DEVICE_OBJECT *pDevice, + U8 channel, + PLX_DMA_PROP *pDmaProp + ); + +PLX_STATUS EXPORT +PlxPci_DmaControl( + PLX_DEVICE_OBJECT *pDevice, + U8 channel, + PLX_DMA_COMMAND command + ); + +PLX_STATUS EXPORT +PlxPci_DmaStatus( + PLX_DEVICE_OBJECT *pDevice, + U8 channel + ); + +PLX_STATUS EXPORT +PlxPci_DmaTransferBlock( + PLX_DEVICE_OBJECT *pDevice, + U8 channel, + PLX_DMA_PARAMS *pDmaParams, + U64 Timeout_ms + ); + +PLX_STATUS EXPORT +PlxPci_DmaTransferUserBuffer( + PLX_DEVICE_OBJECT *pDevice, + U8 channel, + PLX_DMA_PARAMS *pDmaParams, + U64 Timeout_ms + ); + +PLX_STATUS EXPORT +PlxPci_DmaChannelClose( + PLX_DEVICE_OBJECT *pDevice, + U8 channel + ); + + +/****************************************** + * Performance Monitoring Functions + *****************************************/ +PLX_STATUS EXPORT +PlxPci_PerformanceInitializeProperties( + PLX_DEVICE_OBJECT *pDevice, + PLX_PERF_PROP *pPerfObject + ); + +PLX_STATUS EXPORT +PlxPci_PerformanceMonitorControl( + PLX_DEVICE_OBJECT *pDevice, + PLX_PERF_CMD command + ); + +PLX_STATUS EXPORT +PlxPci_PerformanceResetCounters( + PLX_DEVICE_OBJECT *pDevice, + PLX_PERF_PROP *pPerfProps, + U8 NumOfObjects + ); + +PLX_STATUS EXPORT +PlxPci_PerformanceGetCounters( + PLX_DEVICE_OBJECT *pDevice, + PLX_PERF_PROP *pPerfProps, + U8 NumOfObjects + ); + +PLX_STATUS EXPORT +PlxPci_PerformanceCalcStatistics( + PLX_PERF_PROP *pPerfProp, + PLX_PERF_STATS *pPerfStats, + U32 ElapsedTime_ms + ); + + +/****************************************** + * Multi-Host Switch Functions + *****************************************/ +PLX_STATUS EXPORT +PlxPci_MH_GetProperties( + PLX_DEVICE_OBJECT *pDevice, + PLX_MULTI_HOST_PROP *pMHProp + ); + +PLX_STATUS EXPORT +PlxPci_MH_MigratePorts( + PLX_DEVICE_OBJECT *pDevice, + U16 VS_Source, + U16 VS_Dest, + U32 DsPortMask, + BOOLEAN bResetSrc + ); + + +/****************************************** + * PLX Non-Transparent Port Functions + *****************************************/ +PLX_STATUS EXPORT +PlxPci_Nt_ReqIdProbe( + PLX_DEVICE_OBJECT *pDevice, + BOOLEAN bRead, + U16 *pReqId + ); + +PLX_STATUS EXPORT +PlxPci_Nt_LutProperties( + PLX_DEVICE_OBJECT *pDevice, + U16 LutIndex, + U16 *pReqId, + U32 *pFlags, + BOOLEAN *pbEnabled + ); + +PLX_STATUS EXPORT +PlxPci_Nt_LutAdd( + PLX_DEVICE_OBJECT *pDevice, + U16 *pLutIndex, + U16 ReqId, + U32 flags + ); + +PLX_STATUS EXPORT +PlxPci_Nt_LutDisable( + PLX_DEVICE_OBJECT *pDevice, + U16 LutIndex + ); + + + + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/Plxlibrary/Plx.h b/Plxlibrary/Plx.h new file mode 100755 index 0000000..7701e24 --- /dev/null +++ b/Plxlibrary/Plx.h @@ -0,0 +1,122 @@ +#ifndef __PLX_H +#define __PLX_H + +/******************************************************************************* + * Copyright 2013-2020 Broadcom, Inc. + * Copyright (c) 2009 to 2012 PLX Technology Inc. All rights reserved. + * + * This software is available to you under a choice of one of two + * licenses. You may choose to be licensed under the terms of the GNU + * General Public License (GPL) Version 2, available from the file + * COPYING in the main directorY of this source tree, or the + * BSD license below: + * + * Redistribution and use in source and binary forms, with or + * without modification, are permitted provided that the following + * conditions are met: + * + * - Redistributions of source code must retain the above + * copyright notice, this list of conditions and the following + * disclaimer. + * + * - Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + ******************************************************************************/ + +/****************************************************************************** + * + * File Name: + * + * Plx.h + * + * Description: + * + * This file contains definitions that are common to all PCI SDK code + * + * Revision: + * + * 11-17-20 : PCI/PCIe SDK v8.23 + * + ******************************************************************************/ + + +#ifdef __cplusplus +extern "C" { +#endif + + + + +/********************************************** +* Definitions +**********************************************/ +// SDK Version information +#define PLX_SDK_VERSION_MAJOR 8 +#define PLX_SDK_VERSION_MINOR 23 +#define PLX_SDK_VERSION_STRING "8.23" +#define PLX_SDK_PRODUCT_NAME_STRING "Broadcom PCI/PCIe SDK" +#define PLX_SDK_COMPANY_NAME_STRING "Broadcom Ltd." +#define PLX_SDK_COPYRIGHT_STRING "\251 Broadcom 2020" + +// Device object validity codes +#define PLX_TAG_VALID 0x5F504C58 // "_PLX" in Hex +#define PLX_TAG_INVALID 0x564F4944 // "VOID" in Hex +#define ObjectValidate(pObj) ((pObj)->IsValidTag = PLX_TAG_VALID) +#define ObjectInvalidate(pObj) ((pObj)->IsValidTag = PLX_TAG_INVALID) +#define IsObjectValid(pObj) ((pObj)->IsValidTag == PLX_TAG_VALID) + +// Used for locating PCI devices +#define PCI_FIELD_IGNORE (-1) + +// Used for VPD accesses +#define VPD_COMMAND_MAX_RETRIES 5 // Max number VPD command re-issues +#define VPD_STATUS_MAX_POLL 10 // Max number of times to read VPD status +#define VPD_STATUS_POLL_DELAY 5 // Delay between polling VPD status (Milliseconds) + +// Define a large value for a signal to the driver +#define FIND_AMOUNT_MATCHED 80001 + +// Max ports +#define PEX_MAX_PORT 128 +#define PEX_PORT_REGS_SIZE (4 * 1024) + +// Used for performance counter calculations +#define PERF_MAX_PORTS 96 // Max # ports in a switch +#define PERF_COUNTERS_PER_PORT 14 // Number of counters per port +#define PERF_TLP_OH_DW 2 // Overhead DW per TLP +#define PERF_TLP_DW (3 + PERF_TLP_OH_DW) // DW per TLP +#define PERF_TLP_SIZE (PERF_TLP_DW * sizeof(U32)) // TLP header bytes with overhead +#define PERF_TLP_SIZE_NO_OH (3 * sizeof(U32)) // TLP header bytes w/o overhead +#define PERF_DLLP_SIZE (2 * sizeof(U32)) // Bytes per DLLP +#define PERF_MAX_BPS_GEN_1_0 ((U64)250000000) // 250 MB/s (2.5 Gbps) +#define PERF_MAX_BPS_GEN_2_0 ((U64)500000000) // 500 MB/s (5 Gbps) +#define PERF_MAX_BPS_GEN_3_0 ((U64)1000000000) // 1 GB/s (8 Gbps) +#define PERF_MAX_BPS_GEN_4_0 ((U64)2000000000) // 2 GB/s (16 Gbps) + +// Endian swap macros +#define EndianSwap32(value) ( ((((value) >> 0) & 0xff) << 24) | \ + ((((value) >> 8) & 0xff) << 16) | \ + ((((value) >> 16) & 0xff) << 8) | \ + ((((value) >> 24) & 0xff) << 0) ) + +#define EndianSwap16(value) ( ((((value) >> 0) & 0xffff) << 16) | \ + ((((value) >> 16) & 0xffff) << 0) ) + + + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/Plxlibrary/PlxApi.h b/Plxlibrary/PlxApi.h new file mode 100755 index 0000000..03106d6 --- /dev/null +++ b/Plxlibrary/PlxApi.h @@ -0,0 +1,73 @@ +#ifndef __PLX_API_H +#define __PLX_API_H + +/******************************************************************************* + * Copyright 2013-2015 Avago Technologies + * Copyright (c) 2009 to 2012 PLX Technology Inc. All rights reserved. + * + * This software is available to you under a choice of one of two + * licenses. You may choose to be licensed under the terms of the GNU + * General Public License (GPL) Version 2, available from the file + * COPYING in the main directorY of this source tree, or the + * BSD license below: + * + * Redistribution and use in source and binary forms, with or + * without modification, are permitted provided that the following + * conditions are met: + * + * - Redistributions of source code must retain the above + * copyright notice, this list of conditions and the following + * disclaimer. + * + * - Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + ******************************************************************************/ + +/****************************************************************************** + * + * File Name: + * + * PlxApi.h + * + * Description: + * + * The main PLX API include file + * + * Revision: + * + * 02-01-07 : PLX SDK v5.00 + * + ******************************************************************************/ + + + + +/********************************************** +* Verify Required Definitions +**********************************************/ +#include "PlxDefCk.h" + + + + +/********************************************** +* Include Files +**********************************************/ +#include "Plx.h" +#include "PlxTypes.h" +#include "PexApi.h" + + + +#endif diff --git a/Plxlibrary/PlxApiDebug.h b/Plxlibrary/PlxApiDebug.h new file mode 100755 index 0000000..aef7781 --- /dev/null +++ b/Plxlibrary/PlxApiDebug.h @@ -0,0 +1,150 @@ +#ifndef __PLX_API_DEBUG_H +#define __PLX_API_DEBUG_H + +/******************************************************************************* + * Copyright 2013-2019 Avago Technologies + * Copyright (c) 2009 to 2012 PLX Technology Inc. All rights reserved. + * + * This software is available to you under a choice of one of two + * licenses. You may choose to be licensed under the terms of the GNU + * General Public License (GPL) Version 2, available from the file + * COPYING in the main directorY of this source tree, or the + * BSD license below: + * + * Redistribution and use in source and binary forms, with or + * without modification, are permitted provided that the following + * conditions are met: + * + * - Redistributions of source code must retain the above + * copyright notice, this list of conditions and the following + * disclaimer. + * + * - Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + ******************************************************************************/ + +/****************************************************************************** + * + * File Name: + * + * PlxApiDebug.h + * + * Description: + * + * PLX API debug support functions header + * + * Revision: + * + * 09-01-19: PLX SDK v8.10 + * + ******************************************************************************/ + + +#include + + +#ifdef __cplusplus +extern "C" { +#endif + + + +/****************************************** + * Definitions + *****************************************/ +// Ensure debug is enabled for debug builds +#if defined(DEBUG) || defined(_DEBUG) + #define PLX_DEBUG +#endif + +// Remove any existing definitions of debug macros +#if defined(DebugPrintf) + #undef DebugPrintf + #undef DebugPrintf_Cont + #undef InfoPrintf + #undef InfoPrintf_Cont + #undef ErrorPrintf + #undef ErrorPrintf_Cont + #undef _PlxDbgFunc + #undef _PlxDbgOut + #undef _Debug_Print_Macro +#endif + + +// Set log data destination +#if defined(WIN32) + #define PLX_DBG_DEST_DEBUGGER // Default Win DLL to debugger +#elif defined(PLX_LINUX) + #define PLX_DBG_DEST_CONSOLE // Default Linux API to console +#elif defined(PLX_DOS) + #define PLX_DBG_DEST_FILE // Default DOS API to file +#else + #define PLX_DBG_DEST_CONSOLE // Default to console +#endif + + +// Debug definitions +#if defined(PLX_DBG_DEST_FILE) + #define _PlxDbgFunc PlxApi_DebugPrintf + #define PLX_LOG_FILE "PlxApi.Log" // Log file for debug output +#elif defined(PLX_DBG_DEST_DEBUGGER) + #if defined(WIN32) + #define _PlxDbgFunc PlxApi_DebugPrintf + #define _PlxDbgOut OutputDebugStringA + #endif +#elif defined(PLX_DBG_DEST_CONSOLE) + #define _PlxDbgFunc printf + #define _PlxDbgOut puts +#endif + +#if defined(PLX_DEBUG) + #define DebugPrintf(arg) _Debug_Print_Macro(arg) + #define DebugPrintf_Cont(arg) _PlxDbgFunc arg + #define ErrorPrintf(arg) _Debug_Print_Macro(arg) + #define ErrorPrintf_Cont(arg) _PlxDbgFunc arg +#else + #define DebugPrintf(arg) do { } while(0) + #define DebugPrintf_Cont(arg) do { } while(0) + #define ErrorPrintf(arg) do { } while(0) + #define ErrorPrintf_Cont(arg) do { } while(0) +#endif +#define InfoPrintf(arg) _Debug_Print_Macro(arg) +#define InfoPrintf_Cont(arg) _PlxDbgFunc arg + +#define _Debug_Print_Macro(arg) \ + do \ + { \ + _PlxDbgFunc("PlxApi: "); \ + _PlxDbgFunc arg; \ + } \ + while (0) + + + +/****************************************** + * Functions + *****************************************/ +extern void +PlxApi_DebugPrintf( + const char *format, + ... + ); + + + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/Plxlibrary/PlxApiDirect.h b/Plxlibrary/PlxApiDirect.h new file mode 100755 index 0000000..a3f4a28 --- /dev/null +++ b/Plxlibrary/PlxApiDirect.h @@ -0,0 +1,346 @@ +#ifndef __PLX_API_DIRECT_H +#define __PLX_API_DIRECT_H + +/******************************************************************************* + * Copyright 2013-2019 Broadcom Inc + * Copyright (c) 2009 to 2012 PLX Technology Inc. All rights reserved. + * + * This software is available to you under a choice of one of two + * licenses. You may choose to be licensed under the terms of the GNU + * General Public License (GPL) Version 2, available from the file + * COPYING in the main directorY of this source tree, or the + * BSD license below: + * + * Redistribution and use in source and binary forms, with or + * without modification, are permitted provided that the following + * conditions are met: + * + * - Redistributions of source code must retain the above + * copyright notice, this list of conditions and the following + * disclaimer. + * + * - Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + ******************************************************************************/ + +/****************************************************************************** + * + * File Name: + * + * PlxApiDirect.h + * + * Description: + * + * PLX API function prototypes at API level for direct connect interfaces + * + * Revision: + * + * 09-01-19: PCI/PCIe SDK v8.10 + * + ******************************************************************************/ + + +#include "PlxTypes.h" +#if defined(PLX_LINUX) + #include // For mutex support + #include // For usleep() +#elif defined(PLX_DOS) + #include // For usleep() +#endif + + +#ifdef __cplusplus +extern "C" { +#endif + + + + +/****************************************** + * Definitions + ******************************************/ + +// For displaying connection mode in debug statements +#define DbgGetApiModeStr( pDev ) \ + ( ((pDev)->Key.ApiMode == PLX_API_MODE_PCI) ? "PCI" : \ + ((pDev)->Key.ApiMode == PLX_API_MODE_SDB) ? "SDB" : \ + ((pDev)->Key.ApiMode == PLX_API_MODE_I2C_AARDVARK) ? "I2C" : \ + ((pDev)->Key.ApiMode == PLX_API_MODE_MDIO_SPLICE) ? "MDIO" : \ + "??" ) + +// Addresses used for probe, register, & flash accesses +#define ATLAS_REGS_AXI_CCR_BASE_ADDR 0xFFF00000 +#define ATLAS_REGS_AXI_BASE_ADDR 0x60800000 +#define ATLAS_REGS_AXI_MAVERICK_BASE_ADDR 0x60000000 +#define _REG_CCR(offset) (ATLAS_REGS_AXI_CCR_BASE_ADDR + (offset)) + +// Addresses dependent upon access mode +#define ATLAS_REGS_PCI_PBAM_BASE_ADDR 0x001C0000 +#define ATLAS_REGS_AXI_PBAM_BASE_ADDR 0x2A0C0000 +#define ATLAS_SPI_CS0_AXI_BASE_ADDR 0x10000000 +#define ATLAS_SPI_CS0_PCI_BASE_ADDR 0x00300000 + +// Atlas PEX registers start offset +#if !defined(ATLAS_PEX_REGS_BASE_OFFSET) + #define ATLAS_PEX_REGS_BASE_OFFSET ATLAS_REGS_AXI_BASE_ADDR +#endif + +// CCR registers +#define ATLAS_REG_CCR_DEV_ID _REG_CCR( 0x0 ) +#define ATLAS_REG_CCR_PCIE_SW_MODE _REG_CCR( 0xB0 ) +#define ATLAS_REG_CCR_PORT_TYPE0 _REG_CCR( 0x120 ) +#define ATLAS_REG_CCR_PCIE_CONFIG _REG_CCR( 0x170 ) + +// Chip registers +#define ATLAS_REG_PORT_CLOCK_EN_0 0x30C // Port clock enable for 0-31 +#define ATLAS_REG_PORT_CLOCK_EN_1 0x310 // Port clock enable for 32-63 +#define ATLAS_REG_PORT_CLOCK_EN_2 0x314 // Port clock enable for 64-95 +#define ATLAS_REG_VS0_UPSTREAM 0x360 // Port upstream setting +#define ATLAS_REG_IDX_AXI_ADDR 0x1F0100 // Index access AXI address +#define ATLAS_REG_IDX_AXI_DATA 0x1F0104 // Index access data +#define ATLAS_REG_IDX_AXI_CTRL 0x1F0108 // Index access control + +// Per port registers +#define ATLAS_OFF_PORT_CAP_BUS 0x97C // Port captured bus + +// PEX CSR index method control +#define PEX_IDX_CTRL_CMD_READ (1 << 1) // READ command +#define PEX_IDX_CTRL_CMD_WRITE (1 << 0) // WRITE command +#define PEX_IDX_CTRL_READ_VALID (1 << 3) // Indicates READ completed +#define PEX_IDX_CTRL_BUSY (1 << 2) // Indicates operation pending + +// Maverick +#define ATLAS_REG_MAV_HOST_DIAG 0x08 // Maverick host diag reg +#define ATLAS_MAV_HOST_DIAG_CPU_RESET_MASK (1 << 1) // Hold CPU in reset + + + + +/********************************************** + * Portability Functions + *********************************************/ +#if defined(PLX_MSWINDOWS) + + #define Plx_sleep Sleep + +#elif defined(PLX_LINUX) + + #define Plx_sleep(arg) usleep((arg) * 1000) + + #define CRITICAL_SECTION pthread_mutex_t + #define InitializeCriticalSection(pCS) pthread_mutex_init ( (pCS), NULL ) + #define DeleteCriticalSection(pCS) pthread_mutex_destroy( (pCS) ) + #define EnterCriticalSection(pCS) pthread_mutex_lock ( (pCS) ) + #define LeaveCriticalSection(pCS) pthread_mutex_unlock ( (pCS) ) + + #define InterlockedIncrement( pVal ) ++(*(pVal)) + #define InterlockedDecrement( pVal ) --(*(pVal)) + +#elif defined(PLX_DOS) + + #define Plx_sleep(arg) usleep((arg) * 1000) + +#endif + +#if !defined(PLX_8000_REG_READ) + // Macros for PLX chip register access + #define PLX_PCI_REG_READ(pDevice, offset, pValue) *(pValue) = PlxDir_PlxRegRead( (pDevice), (U16)(offset), NULL ) + #define PLX_PCI_REG_WRITE(pDevice, offset, value) PlxDir_PlxRegWrite( (pDevice), (U16)(offset), (value) ) + #define PLX_8000_REG_READ(pDevice, offset) PlxDir_PlxMappedRegRead( (pDevice), (offset), NULL ) + #define PLX_8000_REG_WRITE(pDevice, offset, value) PlxDir_PlxMappedRegWrite( (pDevice), (offset), (value) ) +#endif + + + + +/****************************************** + * Query for Information Functions + *****************************************/ +PLX_STATUS +PlxDir_ChipTypeGet( + PLX_DEVICE_OBJECT *pDevice, + U16 *pChipType, + U8 *pRevision + ); + +PLX_STATUS +PlxDir_ChipTypeSet( + PLX_DEVICE_OBJECT *pDevice, + U16 ChipType, + U8 Revision + ); + +PLX_STATUS +PlxDir_GetPortProperties( + PLX_DEVICE_OBJECT *pDevice, + PLX_PORT_PROP *pPortProp + ); + + +/****************************************** + * PCI BAR Functions + *****************************************/ +PLX_STATUS +PlxDir_PciBarProperties( + PLX_DEVICE_OBJECT *pDevice, + U8 BarIndex, + PLX_PCI_BAR_PROP *pBarProperties + ); + + +/****************************************** + * SPI Flash Functions + *****************************************/ +PLX_STATUS +PlxDir_SpiFlashPropGet( + PLX_DEVICE_OBJECT *pDevice, + U8 ChipSel, + PEX_SPI_OBJ *PtrSpi + ); + +PLX_STATUS +PlxDir_SpiFlashErase( + PLX_DEVICE_OBJECT *PtrDev, + PEX_SPI_OBJ *PtrSpi, + U32 StartOffset, + U8 BoolWaitComplete + ); + +PLX_STATUS +PlxDir_SpiFlashReadBuffer( + PLX_DEVICE_OBJECT *PtrDev, + PEX_SPI_OBJ *PtrSpi, + U32 StartOffset, + U8 *PtrRxBuff, + U32 SizeRx + ); + +PLX_STATUS +PlxDir_SpiFlashWriteBuffer( + PLX_DEVICE_OBJECT *PtrDevice, + PEX_SPI_OBJ *PtrSpi, + U32 StartOffset, + U8 *PtrTxBuff, + U32 SizeTx + ); + +PLX_STATUS +PlxDir_SpiFlashGetStatus( + PLX_DEVICE_OBJECT *PtrDev, + PEX_SPI_OBJ *PtrSpi + ); + + +/****************************************** + * Performance Monitor Functions + *****************************************/ +PLX_STATUS +PlxDir_PerformanceInitializeProperties( + PLX_DEVICE_OBJECT *pDevice, + PLX_PERF_PROP *pPerfObject + ); + +PLX_STATUS +PlxDir_PerformanceMonitorControl( + PLX_DEVICE_OBJECT *pDevice, + PLX_PERF_CMD command + ); + +PLX_STATUS +PlxDir_PerformanceResetCounters( + PLX_DEVICE_OBJECT *pDevice + ); + +PLX_STATUS +PlxDir_PerformanceGetCounters( + PLX_DEVICE_OBJECT *pDevice, + PLX_PERF_PROP *pPerfProps, + U8 NumOfObjects + ); + + +/****************************************** + * Private Support Functions + *****************************************/ +U16 +PlxDir_PciFindCapability( + PLX_DEVICE_OBJECT *pDevice, + U16 CapID, + U8 bPCIeCap, + U8 InstanceNum + ); + +BOOLEAN +PlxDir_ChipTypeDetect( + PLX_DEVICE_OBJECT *pDevice + ); + +VOID +PlxDir_ChipRevisionDetect( + PLX_DEVICE_OBJECT *pDevice + ); + +PLX_STATUS +PlxDir_ChipFilterDisabledPorts( + PLX_DEVICE_OBJECT *pDevice, + PEX_CHIP_FEAT *PtrFeat + ); + +PLX_STATUS +PlxDir_ProbeSwitch( + PLX_DEVICE_OBJECT *pDevice, + PLX_DEVICE_KEY *pKey, + U16 DeviceNumber, + U16 *pNumMatched + ); + + +/****************************************** + * Private Register Dispatch Functions + *****************************************/ +U32 +PlxDir_PlxRegRead( + PLX_DEVICE_OBJECT *pDevice, + U16 offset, + PLX_STATUS *pStatus + ); + +PLX_STATUS +PlxDir_PlxRegWrite( + PLX_DEVICE_OBJECT *pDevice, + U16 offset, + U32 value + ); + +U32 +PlxDir_PlxMappedRegRead( + PLX_DEVICE_OBJECT *pDevice, + U32 offset, + PLX_STATUS *pStatus + ); + +PLX_STATUS +PlxDir_PlxMappedRegWrite( + PLX_DEVICE_OBJECT *pDevice, + U32 offset, + U32 value + ); + + + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/Plxlibrary/PlxDefCk.h b/Plxlibrary/PlxDefCk.h new file mode 100755 index 0000000..06cd1fc --- /dev/null +++ b/Plxlibrary/PlxDefCk.h @@ -0,0 +1,84 @@ +/******************************************************************************* + * Copyright 2013-2015 Avago Technologies + * Copyright (c) 2009 to 2012 PLX Technology Inc. All rights reserved. + * + * This software is available to you under a choice of one of two + * licenses. You may choose to be licensed under the terms of the GNU + * General Public License (GPL) Version 2, available from the file + * COPYING in the main directorY of this source tree, or the + * BSD license below: + * + * Redistribution and use in source and binary forms, with or + * without modification, are permitted provided that the following + * conditions are met: + * + * - Redistributions of source code must retain the above + * copyright notice, this list of conditions and the following + * disclaimer. + * + * - Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + ******************************************************************************/ + +/****************************************************************************** + * + * File Name: + * + * PlxDefCk.h + * + * Description: + * + * Verifies definitions required by the PLX API + * + * Revision: + * + * 05-01-12 : PLX SDK v7.00 + * + ******************************************************************************/ + + + + +/********************************************** +* Automatic selection for Windows +**********************************************/ +#if defined(_WIN32) || defined(_WIN64) + #if !defined(PLX_LITTLE_ENDIAN) && !defined(PLX_BIG_ENDIAN) + #define PLX_LITTLE_ENDIAN + #endif + + #if defined(_WIN64) + #define PLX_CPU_BITS 64 + #else + #define PLX_CPU_BITS 32 + #endif + + #define PLX_MSWINDOWS +#endif + + +#if defined(PLX_LINUX) + #if !defined(PLX_LITTLE_ENDIAN) && !defined(PLX_BIG_ENDIAN) + #define PLX_LITTLE_ENDIAN + #endif +#endif + + + +/********************************************** +* Error Checks +**********************************************/ +#if !defined(PLX_LITTLE_ENDIAN) && !defined(PLX_BIG_ENDIAN) + #error ERROR: Either PLX_LITTLE_ENDIAN or PLX_BIG_ENDIAN must be defined. +#endif diff --git a/Plxlibrary/PlxInit.h b/Plxlibrary/PlxInit.h new file mode 100755 index 0000000..0b98bc9 --- /dev/null +++ b/Plxlibrary/PlxInit.h @@ -0,0 +1,103 @@ +#ifndef PLXINIT_H +#define PLXINIT_H + +/******************************************************************************* + * Copyright 2013-2015 Avago Technologies + * Copyright (c) 2009 to 2012 PLX Technology Inc. All rights reserved. + * + * This software is available to you under a choice of one of two + * licenses. You may choose to be licensed under the terms of the GNU + * General Public License (GPL) Version 2, available from the file + * COPYING in the main directorY of this source tree, or the + * BSD license below: + * + * Redistribution and use in source and binary forms, with or + * without modification, are permitted provided that the following + * conditions are met: + * + * - Redistributions of source code must retain the above + * copyright notice, this list of conditions and the following + * disclaimer. + * + * - Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + ******************************************************************************/ + +/****************************************************************************** + * + * File Name: + * + * PlxInit.h + * + * Description: + * + * Header file for the PlxInit.c module + * + * Revision History: + * + * 12-01-07 : PLX SDK v5.20 + * + ******************************************************************************/ + + +#ifdef __cplusplus +extern "C" { +#endif + + +#include "PlxTypes.h" + + + + +/****************************** +* Definitions +******************************/ +#define MAX_DEVICES_TO_LIST 100 + +typedef struct _API_ERRORS +{ + PLX_STATUS code; + char *text; +} API_ERRORS; + + + + +/******************************************************************************** +* Functions +*********************************************************************************/ +S16 +SelectDevice( + PLX_DEVICE_KEY *pKey + ); + +char* +PlxSdkErrorText( + PLX_STATUS code + ); + +void +PlxSdkErrorDisplay( + PLX_STATUS code + ); + + + + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/Plxlibrary/PlxIoctl.h b/Plxlibrary/PlxIoctl.h new file mode 100755 index 0000000..a49cded --- /dev/null +++ b/Plxlibrary/PlxIoctl.h @@ -0,0 +1,293 @@ +#ifndef __PLX_IOCTL_H +#define __PLX_IOCTL_H + +/******************************************************************************* + * Copyright 2013-2016 Avago Technologies + * Copyright (c) 2009 to 2012 PLX Technology Inc. All rights reserved. + * + * This software is available to you under a choice of one of two + * licenses. You may choose to be licensed under the terms of the GNU + * General Public License (GPL) Version 2, available from the file + * COPYING in the main directorY of this source tree, or the + * BSD license below: + * + * Redistribution and use in source and binary forms, with or + * without modification, are permitted provided that the following + * conditions are met: + * + * - Redistributions of source code must retain the above + * copyright notice, this list of conditions and the following + * disclaimer. + * + * - Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + ******************************************************************************/ + +/****************************************************************************** + * + * File Name: + * + * PlxIoctl.h + * + * Description: + * + * This file contains the common I/O Control messages shared between + * the driver and the PCI API. + * + * Revision History: + * + * 09-01-19 : PCI/PCIe SDK v8.10 + * + ******************************************************************************/ + + +#include "PlxTypes.h" + +#if defined(PLX_MSWINDOWS) && !defined(PLX_DRIVER) + #include +#elif defined(PLX_LINUX) + #include + #include + #include +#endif + + +#ifdef __cplusplus +extern "C" { +#endif + + +// Set structure packing for consistentcy in kernel/user levels & save current +#pragma pack( push, 4 ) + + + + +// Used to pass IOCTL arguments down to the driver +typedef struct _PLX_PARAMS +{ + PLX_STATUS ReturnCode; // API status code + PLX_DEVICE_KEY Key; // Device key information + U64 value[3]; // Generic storage for parameters + union + { + U64 ExData[5]; + PLX_INTERRUPT PlxIntr; + PLX_PHYSICAL_MEM PciMemory; + PLX_PORT_PROP PortProp; + PLX_PCI_BAR_PROP BarProp; + PLX_DMA_PROP DmaProp; + PLX_DMA_PARAMS TxParams; + PLX_DRIVER_PROP DriverProp; + PLX_MULTI_HOST_PROP MH_Prop; + PEX_SPI_OBJ SpiProp; + } u; +} PLX_PARAMS; + + +#if defined(PLX_MSWINDOWS) + /********************************************************** + * Note: Codes 0-2047 (0-7FFh) are reserved by Microsoft + * Coded 2048-4095 (800h-FFFh) are reserved for OEMs + *********************************************************/ + #define PLX_IOCTL_CODE_BASE 0x800 + #define IOCTL_MSG( code ) CTL_CODE( \ + FILE_DEVICE_UNKNOWN, \ + code, \ + METHOD_BUFFERED, \ + FILE_ANY_ACCESS \ + ) + +#elif defined(PLX_LINUX) || defined(PLX_LINUX_DRIVER) + + #define PLX_IOCTL_CODE_BASE 0x0 + #define PLX_MAGIC 'P' + #define IOCTL_MSG( code ) _IOWR( \ + PLX_MAGIC, \ + code, \ + PLX_PARAMS \ + ) + +#elif defined(PLX_DOS) + + #define PLX_IOCTL_CODE_BASE 0x0 + #define IOCTL_MSG( code ) code + +#endif + + +typedef enum _DRIVER_MSGS +{ + MSG_DRIVER_VERSION = PLX_IOCTL_CODE_BASE, + MSG_DRIVER_PROPERTIES, + MSG_DRIVER_SCHEDULE_RESCAN, + MSG_CHIP_TYPE_GET, + MSG_CHIP_TYPE_SET, + MSG_GET_PORT_PROPERTIES, + MSG_PCI_DEVICE_RESET, + MSG_PCI_DEVICE_FIND, + MSG_PCI_BAR_PROPERTIES, + MSG_PCI_BAR_MAP, + MSG_PCI_BAR_UNMAP, + MSG_PCI_REGISTER_READ, + MSG_PCI_REGISTER_WRITE, + MSG_PCI_REG_READ_BYPASS_OS, + MSG_PCI_REG_WRITE_BYPASS_OS, + MSG_REGISTER_READ, + MSG_REGISTER_WRITE, + MSG_MAPPED_REGISTER_READ, + MSG_MAPPED_REGISTER_WRITE, + MSG_PHYSICAL_MEM_ALLOCATE, + MSG_PHYSICAL_MEM_FREE, + MSG_PHYSICAL_MEM_MAP, + MSG_PHYSICAL_MEM_UNMAP, + MSG_COMMON_BUFFER_PROPERTIES, + MSG_IO_PORT_READ, + MSG_IO_PORT_WRITE, + MSG_PCI_BAR_SPACE_READ, + MSG_PCI_BAR_SPACE_WRITE, + MSG_VPD_READ, + MSG_VPD_WRITE, + MSG_EEPROM_PRESENT, + MSG_EEPROM_PROBE, + MSG_EEPROM_GET_ADDRESS_WIDTH, + MSG_EEPROM_SET_ADDRESS_WIDTH, + MSG_EEPROM_CRC_GET, + MSG_EEPROM_CRC_UPDATE, + MSG_EEPROM_READ_BY_OFFSET, + MSG_EEPROM_WRITE_BY_OFFSET, + MSG_EEPROM_READ_BY_OFFSET_16, + MSG_EEPROM_WRITE_BY_OFFSET_16, + MSG_MAILBOX_READ, + MSG_MAILBOX_WRITE, + MSG_INTR_ENABLE, + MSG_INTR_DISABLE, + MSG_INTR_STATUS_GET, + MSG_NOTIFICATION_REGISTER_FOR, + MSG_NOTIFICATION_CANCEL, + MSG_NOTIFICATION_WAIT, + MSG_NOTIFICATION_STATUS, + MSG_DMA_CHANNEL_OPEN, + MSG_DMA_GET_PROPERTIES, + MSG_DMA_SET_PROPERTIES, + MSG_DMA_CONTROL, + MSG_DMA_STATUS, + MSG_DMA_TRANSFER_BLOCK, + MSG_DMA_TRANSFER_USER_BUFFER, + MSG_DMA_CHANNEL_CLOSE, + MSG_PERFORMANCE_INIT_PROPERTIES, + MSG_PERFORMANCE_MONITOR_CTRL, + MSG_PERFORMANCE_RESET_COUNTERS, + MSG_PERFORMANCE_GET_COUNTERS, + MSG_MH_GET_PROPERTIES, + MSG_MH_MIGRATE_DS_PORTS, + MSG_NT_PROBE_REQ_ID, + MSG_NT_LUT_PROPERTIES, + MSG_NT_LUT_ADD, + MSG_NT_LUT_DISABLE +} DRIVER_MSGS; + + + + +#define PLX_IOCTL_DRIVER_VERSION IOCTL_MSG( MSG_DRIVER_VERSION ) +#define PLX_IOCTL_DRIVER_PROPERTIES IOCTL_MSG( MSG_DRIVER_PROPERTIES ) +#define PLX_IOCTL_DRIVER_SCHEDULE_RESCAN IOCTL_MSG( MSG_DRIVER_SCHEDULE_RESCAN ) +#define PLX_IOCTL_CHIP_TYPE_GET IOCTL_MSG( MSG_CHIP_TYPE_GET ) +#define PLX_IOCTL_CHIP_TYPE_SET IOCTL_MSG( MSG_CHIP_TYPE_SET ) +#define PLX_IOCTL_GET_PORT_PROPERTIES IOCTL_MSG( MSG_GET_PORT_PROPERTIES ) + +#define PLX_IOCTL_PCI_DEVICE_FIND IOCTL_MSG( MSG_PCI_DEVICE_FIND ) +#define PLX_IOCTL_PCI_DEVICE_RESET IOCTL_MSG( MSG_PCI_DEVICE_RESET ) +#define PLX_IOCTL_PCI_BAR_PROPERTIES IOCTL_MSG( MSG_PCI_BAR_PROPERTIES ) +#define PLX_IOCTL_PCI_BAR_MAP IOCTL_MSG( MSG_PCI_BAR_MAP ) +#define PLX_IOCTL_PCI_BAR_UNMAP IOCTL_MSG( MSG_PCI_BAR_UNMAP ) + +#define PLX_IOCTL_PCI_REGISTER_READ IOCTL_MSG( MSG_PCI_REGISTER_READ ) +#define PLX_IOCTL_PCI_REGISTER_WRITE IOCTL_MSG( MSG_PCI_REGISTER_WRITE ) +#define PLX_IOCTL_PCI_REG_READ_BYPASS_OS IOCTL_MSG( MSG_PCI_REG_READ_BYPASS_OS ) +#define PLX_IOCTL_PCI_REG_WRITE_BYPASS_OS IOCTL_MSG( MSG_PCI_REG_WRITE_BYPASS_OS ) + +#define PLX_IOCTL_REGISTER_READ IOCTL_MSG( MSG_REGISTER_READ ) +#define PLX_IOCTL_REGISTER_WRITE IOCTL_MSG( MSG_REGISTER_WRITE ) +#define PLX_IOCTL_MAPPED_REGISTER_READ IOCTL_MSG( MSG_MAPPED_REGISTER_READ ) +#define PLX_IOCTL_MAPPED_REGISTER_WRITE IOCTL_MSG( MSG_MAPPED_REGISTER_WRITE ) +#define PLX_IOCTL_MAILBOX_READ IOCTL_MSG( MSG_MAILBOX_READ ) +#define PLX_IOCTL_MAILBOX_WRITE IOCTL_MSG( MSG_MAILBOX_WRITE ) + +#define PLX_IOCTL_PHYSICAL_MEM_ALLOCATE IOCTL_MSG( MSG_PHYSICAL_MEM_ALLOCATE ) +#define PLX_IOCTL_PHYSICAL_MEM_FREE IOCTL_MSG( MSG_PHYSICAL_MEM_FREE ) +#define PLX_IOCTL_PHYSICAL_MEM_MAP IOCTL_MSG( MSG_PHYSICAL_MEM_MAP ) +#define PLX_IOCTL_PHYSICAL_MEM_UNMAP IOCTL_MSG( MSG_PHYSICAL_MEM_UNMAP ) +#define PLX_IOCTL_COMMON_BUFFER_PROPERTIES IOCTL_MSG( MSG_COMMON_BUFFER_PROPERTIES ) + +#define PLX_IOCTL_IO_PORT_READ IOCTL_MSG( MSG_IO_PORT_READ ) +#define PLX_IOCTL_IO_PORT_WRITE IOCTL_MSG( MSG_IO_PORT_WRITE ) +#define PLX_IOCTL_PCI_BAR_SPACE_READ IOCTL_MSG( MSG_PCI_BAR_SPACE_READ ) +#define PLX_IOCTL_PCI_BAR_SPACE_WRITE IOCTL_MSG( MSG_PCI_BAR_SPACE_WRITE ) + +#define PLX_IOCTL_VPD_READ IOCTL_MSG( MSG_VPD_READ ) +#define PLX_IOCTL_VPD_WRITE IOCTL_MSG( MSG_VPD_WRITE ) + +#define PLX_IOCTL_EEPROM_PRESENT IOCTL_MSG( MSG_EEPROM_PRESENT ) +#define PLX_IOCTL_EEPROM_PROBE IOCTL_MSG( MSG_EEPROM_PROBE ) +#define PLX_IOCTL_EEPROM_GET_ADDRESS_WIDTH IOCTL_MSG( MSG_EEPROM_GET_ADDRESS_WIDTH ) +#define PLX_IOCTL_EEPROM_SET_ADDRESS_WIDTH IOCTL_MSG( MSG_EEPROM_SET_ADDRESS_WIDTH ) +#define PLX_IOCTL_EEPROM_CRC_GET IOCTL_MSG( MSG_EEPROM_CRC_GET ) +#define PLX_IOCTL_EEPROM_CRC_UPDATE IOCTL_MSG( MSG_EEPROM_CRC_UPDATE ) +#define PLX_IOCTL_EEPROM_READ_BY_OFFSET IOCTL_MSG( MSG_EEPROM_READ_BY_OFFSET ) +#define PLX_IOCTL_EEPROM_WRITE_BY_OFFSET IOCTL_MSG( MSG_EEPROM_WRITE_BY_OFFSET ) +#define PLX_IOCTL_EEPROM_READ_BY_OFFSET_16 IOCTL_MSG( MSG_EEPROM_READ_BY_OFFSET_16 ) +#define PLX_IOCTL_EEPROM_WRITE_BY_OFFSET_16 IOCTL_MSG( MSG_EEPROM_WRITE_BY_OFFSET_16 ) + +#define PLX_IOCTL_INTR_ENABLE IOCTL_MSG( MSG_INTR_ENABLE ) +#define PLX_IOCTL_INTR_DISABLE IOCTL_MSG( MSG_INTR_DISABLE ) +#define PLX_IOCTL_INTR_STATUS_GET IOCTL_MSG( MSG_INTR_STATUS_GET ) +#define PLX_IOCTL_NOTIFICATION_REGISTER_FOR IOCTL_MSG( MSG_NOTIFICATION_REGISTER_FOR ) +#define PLX_IOCTL_NOTIFICATION_CANCEL IOCTL_MSG( MSG_NOTIFICATION_CANCEL ) +#define PLX_IOCTL_NOTIFICATION_WAIT IOCTL_MSG( MSG_NOTIFICATION_WAIT ) +#define PLX_IOCTL_NOTIFICATION_STATUS IOCTL_MSG( MSG_NOTIFICATION_STATUS ) + +#define PLX_IOCTL_DMA_CHANNEL_OPEN IOCTL_MSG( MSG_DMA_CHANNEL_OPEN ) +#define PLX_IOCTL_DMA_GET_PROPERTIES IOCTL_MSG( MSG_DMA_GET_PROPERTIES ) +#define PLX_IOCTL_DMA_SET_PROPERTIES IOCTL_MSG( MSG_DMA_SET_PROPERTIES ) +#define PLX_IOCTL_DMA_CONTROL IOCTL_MSG( MSG_DMA_CONTROL ) +#define PLX_IOCTL_DMA_STATUS IOCTL_MSG( MSG_DMA_STATUS ) +#define PLX_IOCTL_DMA_TRANSFER_BLOCK IOCTL_MSG( MSG_DMA_TRANSFER_BLOCK ) +#define PLX_IOCTL_DMA_TRANSFER_USER_BUFFER IOCTL_MSG( MSG_DMA_TRANSFER_USER_BUFFER ) +#define PLX_IOCTL_DMA_CHANNEL_CLOSE IOCTL_MSG( MSG_DMA_CHANNEL_CLOSE ) + +#define PLX_IOCTL_PERFORMANCE_INIT_PROPERTIES IOCTL_MSG( MSG_PERFORMANCE_INIT_PROPERTIES ) +#define PLX_IOCTL_PERFORMANCE_MONITOR_CTRL IOCTL_MSG( MSG_PERFORMANCE_MONITOR_CTRL ) +#define PLX_IOCTL_PERFORMANCE_RESET_COUNTERS IOCTL_MSG( MSG_PERFORMANCE_RESET_COUNTERS ) +#define PLX_IOCTL_PERFORMANCE_GET_COUNTERS IOCTL_MSG( MSG_PERFORMANCE_GET_COUNTERS ) + +#define PLX_IOCTL_MH_GET_PROPERTIES IOCTL_MSG( MSG_MH_GET_PROPERTIES ) +#define PLX_IOCTL_MH_MIGRATE_DS_PORTS IOCTL_MSG( MSG_MH_MIGRATE_DS_PORTS ) + +#define PLX_IOCTL_NT_PROBE_REQ_ID IOCTL_MSG( MSG_NT_PROBE_REQ_ID ) +#define PLX_IOCTL_NT_LUT_PROPERTIES IOCTL_MSG( MSG_NT_LUT_PROPERTIES ) +#define PLX_IOCTL_NT_LUT_ADD IOCTL_MSG( MSG_NT_LUT_ADD ) +#define PLX_IOCTL_NT_LUT_DISABLE IOCTL_MSG( MSG_NT_LUT_DISABLE ) + + +// Restore previous pack value +#pragma pack( pop ) + + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/Plxlibrary/PlxLists.h b/Plxlibrary/PlxLists.h new file mode 100755 index 0000000..2d9733d --- /dev/null +++ b/Plxlibrary/PlxLists.h @@ -0,0 +1,154 @@ +#ifndef __PLX_LISTS_H +#define __PLX_LISTS_H + +/******************************************************************************* + * Copyright 2013-2015 Avago Technologies + * Copyright (c) 2009 to 2012 PLX Technology Inc. All rights reserved. + * + * This software is available to you under a choice of one of two + * licenses. You may choose to be licensed under the terms of the GNU + * General Public License (GPL) Version 2, available from the file + * COPYING in the main directorY of this source tree, or the + * BSD license below: + * + * Redistribution and use in source and binary forms, with or + * without modification, are permitted provided that the following + * conditions are met: + * + * - Redistributions of source code must retain the above + * copyright notice, this list of conditions and the following + * disclaimer. + * + * - Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + ******************************************************************************/ + +/****************************************************************************** + * + * File Name: + * + * PlxLists.h + * + * Description: + * + * Generic double-linked list support + * + * Revision History: + * + * 02-01-10 : PLX SDK v6.40 + * + ******************************************************************************/ + + +#include "PlxTypes.h" + + +#ifdef __cplusplus +extern "C" { +#endif + + + + +/********************************************** + * Definitions + *********************************************/ + +// Define list functions +// Declare and initialize a list +#define PLX_LIST_HEAD_INIT(name) { &(name), &(name) } +#define PLX_LIST_HEAD(name) struct _PLX_LIST_ENTRY = PLX_LIST_HEAD_INIT(name) + +// Calculate the address of the base of the structure given its type, and an +// address of a field within the structure. +#define PLX_CONTAINING_RECORD(address, type, field) ((type *)( \ + (char*)(address) - \ + (PLX_UINT_PTR)(&((type *)0)->field))) + +// Locked list operations +#define Plx_ExInterlockedInsertTailList(List,Entry,Lock) Plx_InsertTailList( (List), (Entry) ) +#define Plx_ExInterlockedInsertHeadList(List,Entry,Lock) Plx_InsertHeadList( (List), (Entry) ) + + +// Doubly linked list structure +typedef struct _PLX_LIST_ENTRY +{ + struct _PLX_LIST_ENTRY *Flink; + struct _PLX_LIST_ENTRY *Blink; +} PLX_LIST_ENTRY; + + +#if defined(PLX_DOS) + #define CONTAINING_RECORD PLX_CONTAINING_RECORD + #define ExInterlockedInsertTailList Plx_ExInterlockedInsertTailList + #define ExInterlockedInsertHeadList Plx_ExInterlockedInsertHeadList + #define InitializeListHead Plx_InitializeListHead + #define IsListEmpty Plx_IsListEmpty + #define RemoveHeadList Plx_RemoveHeadList + #define RemoveEntryList Plx_RemoveEntryList + #define InsertTailList Plx_InsertTailList + #define InsertHeadList Plx_InsertHeadList + typedef PLX_LIST_ENTRY LIST_ENTRY; +#endif + + + + +/********************************************** + * Functions + *********************************************/ +VOID +Plx_InitializeListHead( + PLX_LIST_ENTRY *ListHead + ); + +BOOLEAN +Plx_IsListEmpty( + const PLX_LIST_ENTRY * ListHead + ); + +BOOLEAN +Plx_RemoveEntryList( + PLX_LIST_ENTRY *Entry + ); + +PLX_LIST_ENTRY* +Plx_RemoveHeadList( + PLX_LIST_ENTRY *ListHead + ); + +PLX_LIST_ENTRY* +Plx_RemoveTailList( + PLX_LIST_ENTRY *ListHead + ); + +VOID +Plx_InsertTailList( + PLX_LIST_ENTRY *ListHead, + PLX_LIST_ENTRY *Entry + ); + +VOID +Plx_InsertHeadList( + PLX_LIST_ENTRY *ListHead, + PLX_LIST_ENTRY *Entry + ); + + + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/Plxlibrary/PlxPci_9054_Func.h b/Plxlibrary/PlxPci_9054_Func.h new file mode 100755 index 0000000..7d83a65 --- /dev/null +++ b/Plxlibrary/PlxPci_9054_Func.h @@ -0,0 +1,99 @@ +#ifndef __PLXPCI_9054_FUNC_H +#define __PLXPCI_9054_FUNC_H + +#ifdef __cplusplus +extern "C" { +#endif + +#ifndef PLX_LINUX +#define PLX_LINUX +#endif +/****************************************************************************** + * + * File Name: + * + * PlxPci_9054_Func.h + * + * Description: + * + * + * + ******************************************************************************/ + +#include "PlxTypes.h" +#include "PlxApi.h" +#include "PlxInit.h" + + + +typedef enum __REGISTER_SET{ + Pci9054, + Lcr9054, + Dma9054, + Eep9054 +}REGISTER_SET; +/********************************************** + * Functions + *********************************************/ +BOOLEAN PlxPci_9054_SelDevice(U32 Dkey); + +BOOLEAN PlxPci_9054_Open(void); + + +BOOLEAN +PlxPci_9054_DMATransfer( + U32 LocalAddress, + VOID *pUserBuffer, + U32 BufferByteCount + ); + +BOOLEAN +PlxPci_9054_ReadBar( + U32 PBOffset, + VOID *pUserBuffer, + U32 UserBuffersize + ); + +BOOLEAN +PlxPci_9054_WriteBar( + U32 PBOffset, + VOID *pUserBuffer, + U32 UserBuffersize + ); + +BOOLEAN +PlxPci_9054_ReadEep( + U16 RegOffset, + U32 *RegBuffer + ); + +BOOLEAN +PlxPci_9054_WriteEep( + U16 RegOffset, + U32 RegVal + ); + +BOOLEAN PlxPci_9054_Reset(void); + +BOOLEAN PlxPci_9054_Close(void); + +BOOLEAN PlxPci_9054_LoadE2pToFPGA(void); + +BOOLEAN PlxPci_9054_EnableInterrupt(void); + +BOOLEAN PlxPci_9054_DisableInterrupt(void); + +BOOLEAN PlxPci_9054_WaitForInterrupt(U32 TimeOut); + +BOOLEAN PlxPci_9054_ChipTypeGet(U8 Revision, + U16 ChipType); + +BOOLEAN PlxPci_9054_DMAChannelOpen(void); + +BOOLEAN PlxPci_9054_DMAChannelClose(void); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/Plxlibrary/PlxStat.h b/Plxlibrary/PlxStat.h new file mode 100755 index 0000000..cc642bb --- /dev/null +++ b/Plxlibrary/PlxStat.h @@ -0,0 +1,158 @@ +#ifndef __PLX_STATUS_H +#define __PLX_STATUS_H + +/******************************************************************************* + * Copyright 2013-2015 Avago Technologies + * Copyright (c) 2009 to 2012 PLX Technology Inc. All rights reserved. + * + * This software is available to you under a choice of one of two + * licenses. You may choose to be licensed under the terms of the GNU + * General Public License (GPL) Version 2, available from the file + * COPYING in the main directorY of this source tree, or the + * BSD license below: + * + * Redistribution and use in source and binary forms, with or + * without modification, are permitted provided that the following + * conditions are met: + * + * - Redistributions of source code must retain the above + * copyright notice, this list of conditions and the following + * disclaimer. + * + * - Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + ******************************************************************************/ + +/****************************************************************************** + * + * File Name: + * + * PlxStat.h + * + * Description: + * + * This file defines all the status codes for PLX SDK + * + * Revision: + * + * 08-01-14 : PLX SDK v7.20 + * + ******************************************************************************/ + + +#ifdef __cplusplus +extern "C" { +#endif + + + + +/****************************************** + * Definitions + *****************************************/ +#define PLX_STATUS_START 0x200 // Starting status code + +// Return type +typedef int PLX_STATUS; + + +// API Return Code Values +typedef enum _PLX_STATUS_CODE +{ + PLX_STATUS_OK = PLX_STATUS_START, + PLX_STATUS_FAILED, + PLX_STATUS_NULL_PARAM, + PLX_STATUS_UNSUPPORTED, + PLX_STATUS_NO_DRIVER, + PLX_STATUS_INVALID_OBJECT, + PLX_STATUS_VER_MISMATCH, + PLX_STATUS_INVALID_OFFSET, + PLX_STATUS_INVALID_DATA, + PLX_STATUS_INVALID_SIZE, + PLX_STATUS_INVALID_ADDR, + PLX_STATUS_INVALID_ACCESS, + PLX_STATUS_INSUFFICIENT_RES, + PLX_STATUS_TIMEOUT, + PLX_STATUS_CANCELED, + PLX_STATUS_COMPLETE, + PLX_STATUS_PAUSED, + PLX_STATUS_IN_PROGRESS, + PLX_STATUS_PAGE_GET_ERROR, + PLX_STATUS_PAGE_LOCK_ERROR, + PLX_STATUS_LOW_POWER, + PLX_STATUS_IN_USE, + PLX_STATUS_DISABLED, + PLX_STATUS_PENDING, + PLX_STATUS_NOT_FOUND, + PLX_STATUS_INVALID_STATE, + PLX_STATUS_BUFF_TOO_SMALL, + PLX_STATUS_RSVD_LAST_ERROR // Do not add API errors below this line +} PLX_STATUS_CODE; + + + +// Definitions to support existing applications. Will be removed in future. +#if 1 +#define ApiSuccess PLX_STATUS_OK +#define ApiFailed PLX_STATUS_FAILED +#define ApiNullParam PLX_STATUS_NULL_PARAM +#define ApiUnsupportedFunction PLX_STATUS_UNSUPPORTED +#define ApiNoActiveDriver PLX_STATUS_NO_DRIVER +#define ApiConfigAccessFailed PLX_STATUS_FAILED +#define ApiInvalidDeviceInfo PLX_STATUS_INVALID_OBJECT +#define ApiInvalidDriverVersion PLX_STATUS_VER_MISMATCH +#define ApiInvalidPciSpace PLX_STATUS_INVALID_ADDR +#define ApiInvalidOffset PLX_STATUS_INVALID_OFFSET +#define ApiInvalidData PLX_STATUS_INVALID_DATA +#define ApiInvalidSize PLX_STATUS_INVALID_SIZE +#define ApiInvalidAddress PLX_STATUS_INVALID_ADDR +#define ApiInvalidAccessType PLX_STATUS_INVALID_ACCESS +#define ApiInvalidIndex PLX_STATUS_INVALID_DATA +#define ApiInvalidHandle PLX_STATUS_INVALID_ACCESS +#define ApiInvalidPowerState PLX_STATUS_INVALID_STATE +#define ApiInvalidIopSpace PLX_STATUS_INVALID_ACCESS +#define ApiInvalidBusIndex PLX_STATUS_INVALID_DATA +#define ApiInsufficientResources PLX_STATUS_INSUFFICIENT_RES +#define ApiWaitTimeout PLX_STATUS_TIMEOUT +#define ApiWaitCanceled PLX_STATUS_CANCELED +#define ApiDmaDone PLX_STATUS_COMPLETE +#define ApiDmaPaused PLX_STATUS_PAUSED +#define ApiDmaChannelInvalid PLX_STATUS_INVALID_ADDR +#define ApiDmaInProgress PLX_STATUS_IN_PROGRESS +#define ApiDmaSglPagesGetError PLX_STATUS_PAGE_GET_ERROR +#define ApiDmaSglPagesLockError PLX_STATUS_PAGE_LOCK_ERROR +#define ApiDmaChannelUnavailable PLX_STATUS_INVALID_ACCESS +#define ApiDmaCommandInvalid PLX_STATUS_INVALID_DATA +#define ApiDmaInvalidChannelPriority PLX_STATUS_INVALID_DATA +#define ApiPowerDown PLX_STATUS_LOW_POWER +#define ApiDeviceInUse PLX_STATUS_IN_USE +#define ApiDeviceDisabled PLX_STATUS_DISABLED +#define ApiPending PLX_STATUS_PENDING +#define ApiObjectNotFound PLX_STATUS_NOT_FOUND +#define ApiInvalidState PLX_STATUS_INVALID_STATE +#define ApiBufferTooSmall PLX_STATUS_BUFF_TOO_SMALL +#define ApiMuFifoEmpty PLX_STATUS_NOT_FOUND +#define ApiMuFifoFull PLX_STATUS_INSUFFICIENT_RES +#define ApiHSNotSupported PLX_STATUS_UNSUPPORTED +#define ApiVPDNotSupported PLX_STATUS_UNSUPPORTED +#define ApiLastError PLX_STATUS_RSVD_LAST_ERROR +#endif + + + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/Plxlibrary/PlxTypes.h b/Plxlibrary/PlxTypes.h new file mode 100755 index 0000000..2194af1 --- /dev/null +++ b/Plxlibrary/PlxTypes.h @@ -0,0 +1,1062 @@ +#ifndef __PLX_TYPES_H +#define __PLX_TYPES_H + +/******************************************************************************* + * Copyright 2019-2020 Broadcom Inc. + * Copyright 2013-2018 Avago Technologies + * Copyright (c) 2009 to 2012 PLX Technology Inc. All rights reserved. + * + * This software is available to you under a choice of one of two + * licenses. You may choose to be licensed under the terms of the GNU + * General Public License (GPL) Version 2, available from the file + * COPYING in the main directorY of this source tree, or the + * BSD license below: + * + * Redistribution and use in source and binary forms, with or + * without modification, are permitted provided that the following + * conditions are met: + * + * - Redistributions of source code must retain the above + * copyright notice, this list of conditions and the following + * disclaimer. + * + * - Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + ******************************************************************************/ + +/****************************************************************************** + * + * File Name: + * + * PlxTypes.h + * + * Description: + * + * This file includes SDK types and definitions + * + * Revision: + * + * 01-01-20 : PCI/PCIe SDK v8.10 + * + ******************************************************************************/ + + +#include "Plx.h" +#include "PlxDefCk.h" +#include "PlxStat.h" +#include "PciTypes.h" + + +#ifdef __cplusplus +extern "C" { +#endif + + +// Set structure packing for consistentcy in kernel/user levels & save current +#pragma pack( push, 4 ) + + + + +/****************************************** + * Definitions for Code Portability + ******************************************/ +// Memory set and copy +#if !defined(PLX_MSWINDOWS) + #define RtlZeroMemory(pDest, count) memset((pDest), 0, (count)) + #define RtlCopyMemory(pDest, pSrc, count) memcpy((pDest), (pSrc), (count)) + #define RtlFillMemory(pDest, count, value) memset((pDest), (value), (count)) +#endif + +// Count number of bits of supplied data type +#define PLX_BYTE_TO_BIT_COUNT( bytes ) ((bytes) * 8) + +// Convert pointer to an integer +#define PLX_PTR_TO_INT( ptr ) ((PLX_UINT_PTR)(ptr)) + +// Convert integer to a pointer +#define PLX_INT_TO_PTR( intval ) ((VOID*)(PLX_UINT_PTR)(intval)) + +// Macros that guarantee correct endian format regardless of CPU platform +#if defined(PLX_BIG_ENDIAN) + #define PLX_LE_DATA_32(value) EndianSwap32( (value) ) + #define PLX_BE_DATA_32(value) (value) +#else + #define PLX_LE_DATA_32(value) (value) + #define PLX_BE_DATA_32(value) EndianSwap32( (value) ) +#endif + +// Macros to support portable type casting on BE/LE platforms +#if defined(PLX_BIG_ENDIAN) + #define PLX_64_HIGH_32(value) ((U32)((U64)value)) + #define PLX_64_LOW_32(value) ((U32)(((U64)value) >> 32)) + + #define PLX_CAST_64_TO_8_PTR( ptr64 ) (U8*) ((U8*)PLX_INT_TO_PTR(ptr64) + (7 * sizeof(U8))) + #define PLX_CAST_64_TO_16_PTR( ptr64 ) (U16*)((U8*)PLX_INT_TO_PTR(ptr64) + (6 * sizeof(U8))) + #define PLX_CAST_64_TO_32_PTR( ptr64 ) (U32*)((U8*)PLX_INT_TO_PTR(ptr64) + sizeof(U32)) + + #define PLX_LE_U32_BIT( pos ) ((U32)(1 << (31 - (pos)))) +#else + #define PLX_64_HIGH_32( value ) ((U32)(((U64)value) >> 32)) + #define PLX_64_LOW_32( value ) ((U32)((U64)value)) + + #define PLX_CAST_64_TO_8_PTR( ptr64 ) (U8*) PLX_INT_TO_PTR(ptr64) + #define PLX_CAST_64_TO_16_PTR( ptr64 ) (U16*)PLX_INT_TO_PTR(ptr64) + #define PLX_CAST_64_TO_32_PTR( ptr64 ) (U32*)PLX_INT_TO_PTR(ptr64) + + #define PLX_LE_U32_BIT( pos ) ((U32)(1 << (pos))) +#endif + + + +/****************************************** + * Miscellaneous definitions + ******************************************/ +#if !defined(VOID) + typedef void VOID; +#endif + +// Linux actypes.h contains conflicting definition for BOOLEAN +#if (!defined(PLX_MSWINDOWS)) || defined(PLX_VXD_DRIVER) + #if !defined(BOOLEAN) && !defined(__ACTYPES_H__) + typedef S8 BOOLEAN; + #endif +#endif + +#if !defined(PLX_MSWINDOWS) + #if !defined(BOOL) + typedef S8 BOOL; + #endif +#endif + +#if !defined(NULL) + #define NULL ((VOID *) 0x0) +#endif + +#if !defined(TRUE) + #define TRUE 1 +#endif + +#if !defined(FALSE) + #define FALSE 0 +#endif + +// Min/Max +#define PEX_MIN(v1,v2) ( (v1) < (v2) ? (v1) : (v2) ) +#define PEX_MAX(v1,v2) ( (v1) > (v2) ? (v1) : (v2) ) + +// Round up/down based on power of 2 +#define PEX_P2_ROUND_UP( val, align ) ( ((val) + ((align) - 1)) & ~(align - 1) ) +#define PEX_P2_ROUND_DOWN( val, align ) ( (val) & ~((align) - 1) ) + +// Calculate time difference between 2 timeb structures +#define PLX_DIFF_TIMEB(time1,time0) ( ((double)((time1).time - (time0).time)) + \ + (((double)(time1).millitm - (time0).millitm) / 1000) ) + +#if defined(PLX_MSWINDOWS) + #define PLX_TIMEOUT_INFINITE INFINITE + #define PLX_MEM_POOL_TAG '_XLP' // "PLX_" tag for driver mem alloc +#elif defined(PLX_LINUX) || defined(PLX_LINUX_DRIVER) + #define PLX_TIMEOUT_INFINITE MAX_SCHEDULE_TIMEOUT + + /********************************************************* + * Convert milliseconds to jiffies. The following + * formula is used: + * + * ms * HZ + * jiffies = --------- + * 1,000 + * + * where: HZ = System-defined clock ticks per second + * ms = Timeout in milliseconds + * jiffies = Number of HZ's per second + ********************************************************/ + #define Plx_ms_to_jiffies( ms ) ( ((ms) * HZ) / 1000 ) + #define Plx_jiffies_to_ms( jiff ) ( ((jiff) * 1000) / HZ ) +#endif + + + +/****************************************** + * Definitions for Generic Bitmasks + ******************************************/ +/// Declare a generic bitmask variable with arbitrary size (auto-aligns to 32-bit multiple) +#define PEX_BITMASK_T(Name,Bits) U32 (Name)[ ((Bits) + 31) / 32 ] + +// Set a bit in generic bitmask variable +#define PEX_BITMASK_SET(Mask,Bit) ( (Mask)[ (Bit) / 32 ] |= ((U32)1 << ((Bit) % 32)) ) + +// Set all bits in generic bitmask variable +#define PEX_BITMASK_SET_ALL(Mask) memset( (Mask), 0xFF, sizeof((Mask)) ) + +// Clear a bit in generic bitmask variable +#define PEX_BITMASK_CLEAR(Mask,Bit) ( (Mask)[ (Bit) / 32 ] &= ~((U32)1 << ((Bit) % 32)) ) + +// Clear all bits in generic bitmask variable +#define PEX_BITMASK_CLEAR_ALL(Mask) memset( (Mask), 0, sizeof((Mask)) ) + +// Returns 32-bit DW port mask at provided DW index +#define PEX_BITMASK_GET_DW(Mask,Idx) ((Mask)[Idx]) + +// Sets 32-bit DW port mask at provided DW index +#define PEX_BITMASK_SET_DW(Mask,Idx,Val) ((Mask)[Idx] = (Val)) + +// Copies one mask to another +#define PEX_BITMASK_COPY(Src,Dest) memcpy( (Dest), (Src), sizeof((Dest)) ) + +// Test whether a specific bit is set in generic bitmask variable +#define PEX_BITMASK_TEST(Mask,Bit) ( ((Mask)[ (Bit) / 32 ] & ((U32)1 << ((Bit) % 32))) != 0 ) + +// Test whether any bit is set in generic bitmask variable +#define PEX_BITMASK_TEST_ANY(Mask) __PEX_BITMASK_TEST_ANY( (Mask), sizeof( (Mask) ) ) + +// Helper function for PEX_BITMASK_TEST_ANY macro +static __inline U8 __PEX_BITMASK_TEST_ANY( U32 *PtrBitMask, U32 ByteSize ) +{ + U32 idx = 0; + + while ( idx < (ByteSize / sizeof(U32)) ) + { + if (PtrBitMask[ idx ] != 0) + { + return TRUE; + } + idx++; + } + return FALSE; +} + +// Return the count of set bits in a mask +#define PEX_BITMASK_GET_SET_COUNT(Mask) __PEX_BITMASK_GET_SET_COUNT( (Mask), sizeof( (Mask) ) ) + +// Helper function for PEX_BITMASK_GET_SET_COUNT macro +static __inline U32 __PEX_BITMASK_GET_SET_COUNT( U32 *PtrBitMask, U32 ByteSize ) +{ + U32 bit = 0; + U32 bitCount = 0; + + while (bit < (ByteSize * 8)) + { + bitCount += PEX_BITMASK_TEST( PtrBitMask, bit ); + bit++; + } + return bitCount; +} + + + +/****************************************** + * PLX-specific types & structures + ******************************************/ +// Mode PLX API uses to access device +typedef enum _PLX_API_MODE +{ + PLX_API_MODE_PCI, // Device accessed via PLX driver over PCI/PCIe + PLX_API_MODE_I2C_AARDVARK, // Device accessed via Aardvark I2C USB + PLX_API_MODE_MDIO_SPLICE, // Device accessed via Splice MDIO USB + PLX_API_MODE_SDB, // Device accessed via Serial Debug Port + PLX_API_MODE_TCP // Device accessed via TCP/IP +} PLX_API_MODE; + + +// Supported UART cable connections for SDB +typedef enum _SDB_UART_CABLE +{ + SDB_UART_CABLE_DEFAULT = 0, // Default connection + SDB_UART_CABLE_UART = 1, // Standard COMx connection + SDB_UART_CABLE_USB = 2 // USB-to-serial cable +} SDB_UART_CABLE; + + +// Baud rates supported by SDB +typedef enum _SDB_BAUD_RATE +{ + SDB_BAUD_RATE_DEFAULT = 0, // Default rate + SDB_BAUD_RATE_19200 = 1, // 19,200 BAUD + SDB_BAUD_RATE_115200 = 2 // 115,200 BAUD +} SDB_BAUD_RATE; + + +// Access Size Type +typedef enum _PLX_ACCESS_TYPE +{ + BitSize8, + BitSize16, + BitSize32, + BitSize64 +} PLX_ACCESS_TYPE; + + +// PLX chip families +typedef enum _PLX_CHIP_FAMILY +{ + PLX_FAMILY_NONE = 0, + PLX_FAMILY_UNKNOWN, + PLX_FAMILY_BRIDGE_P2L, // 9000 series & 8311 + PLX_FAMILY_BRIDGE_PCI_P2P, // 6000 series + PLX_FAMILY_BRIDGE_PCIE_P2P, // 8111,8112,8114 + PLX_FAMILY_ALTAIR, // 8525,8533,8547,8548 + PLX_FAMILY_ALTAIR_XL, // 8505,8509 + PLX_FAMILY_VEGA, // 8516,8524,8532 + PLX_FAMILY_VEGA_LITE, // 8508,8512,8517,8518 + PLX_FAMILY_DENEB, // 8612,8616,8624,8632,8647,8648 + PLX_FAMILY_SIRIUS, // 8604,8606,8608,8609,8613,8614,8615 + // 8617,8618,8619 + PLX_FAMILY_CYGNUS, // 8625,8636,8649,8664,8680,8696 + PLX_FAMILY_SCOUT, // 8700 + PLX_FAMILY_DRACO_1, // 8712,8716,8724,8732,8747,8748,8749 + PLX_FAMILY_DRACO_2, // 8713,8717,8725,8733 + [Draco 1 rev BA] + PLX_FAMILY_MIRA, // 2380,3380,3382,8603,8605 + PLX_FAMILY_CAPELLA_1, // 8714,8718,8734,8750,8764,8780,8796 + PLX_FAMILY_CAPELLA_2, // 9712,9716,9733,9749,9750,9765,9781,9797 + PLX_FAMILY_ATLAS, // C010,C011,C012 + PLX_FAMILY_LAST_ENTRY // -- Must be final entry -- +} PLX_CHIP_FAMILY; + + +// PLX chip configured mode +typedef enum _PLX_CHIP_MODE +{ + PLX_CHIP_MODE_UNKNOWN, + PLX_CHIP_MODE_STANDARD, // Standard switch fan-out mode + PLX_CHIP_MODE_STD_LEGACY_NT, // Standard mode with NT but no parent DS P2P + PLX_CHIP_MODE_STD_NT_DS_P2P, // Standard mode with NT & parent DS P2P + PLX_CHIP_MODE_VIRT_SW, // Virtual Switch (VS) mode + PLX_CHIP_MODE_FABRIC, // PCIe fabric mode + PLX_CHIP_MODE_ROOT_COMPLEX, // RC mode + PLX_CHIP_MODE_LEGACY_ADAPTER // MIRA legacy adapter mode +} PLX_CHIP_MODE; + + +// PLX port flags for mask +typedef enum _PLX_FLAG_PORT +{ + // Flags for special port/device types + PLX_FLAG_PORT_NT_LINK_0 = 178, // Bit for NT Link port 0 + PLX_FLAG_PORT_NT_LINK_1 = 179, // Bit for NT Link port 1 + PLX_FLAG_PORT_NT_VIRTUAL_0 = 180, // Bit for NT Virtual port 0 + PLX_FLAG_PORT_NT_VIRTUAL_1 = 181, // Bit for NT Virtual port 1 + PLX_FLAG_PORT_NT_DS_P2P = 182, // Bit for NT DS P2P port (Virtual) + PLX_FLAG_PORT_DMA_RAM = 183, // Bit for DMA RAM + PLX_FLAG_PORT_DMA_0 = 184, // Bit for DMA channel 3 + PLX_FLAG_PORT_DMA_1 = 185, // Bit for DMA channel 2 + PLX_FLAG_PORT_DMA_2 = 186, // Bit for DMA channel 1 + PLX_FLAG_PORT_DMA_3 = 187, // Bit for DMA ch 0 or Func 1 (all 4 ch) + PLX_FLAG_PORT_PCIE_TO_USB = 188, // Bit for PCIe-to-USB P2P or Root Port + PLX_FLAG_PORT_USB = 189, // Bit for USB Host/Bridge + PLX_FLAG_PORT_ALUT_0 = 190, // Bit for ALUT RAM arrays 0 + PLX_FLAG_PORT_ALUT_1 = 191, // Bit for ALUT RAM arrays 1 + PLX_FLAG_PORT_ALUT_2 = 192, // Bit for ALUT RAM arrays 2 + PLX_FLAG_PORT_ALUT_3 = 193, // Bit for ALUT RAM arrays 3 + PLX_FLAG_PORT_STN_REGS_S0 = 194, // Bit for VS or Fabric mode station 0 specific regs + PLX_FLAG_PORT_STN_REGS_S1 = 195, // Bit for VS or Fabric mode station 1 specific regs + PLX_FLAG_PORT_STN_REGS_S2 = 196, // Bit for VS or Fabric mode station 2 specific regs + PLX_FLAG_PORT_STN_REGS_S3 = 197, // Bit for VS or Fabric mode station 3 specific regs + PLX_FLAG_PORT_STN_REGS_S4 = 198, // Bit for VS or Fabric mode station 4 specific regs + PLX_FLAG_PORT_STN_REGS_S5 = 199, // Bit for VS or Fabric mode station 5 specific regs + PLX_FLAG_PORT_MAX = 200, // Bit for highest possible standard port + + // Flags for internal fan out ports & endpoints + PLX_FLAG_PORT_INT_MGMT = 253, // Internal Management port (iSSW) + PLX_FLAG_PORT_INT_DS_0 = 224, // Internal DS 0 + PLX_FLAG_PORT_INT_DS_4 = 225, // Internal DS 4 + PLX_FLAG_PORT_INT_DS_8 = 226, // Internal DS 8 + PLX_FLAG_PORT_INT_DS_12 = 227, // Internal DS 12 + PLX_FLAG_PORT_INT_UP_0 = 232, // Internal UP 0 + PLX_FLAG_PORT_INT_UP_4 = 233, // Internal UP 4 + PLX_FLAG_PORT_INT_UP_8 = 234, // Internal UP 8 + PLX_FLAG_PORT_INT_UP_12 = 235, // Internal UP 12 + PLX_FLAG_PORT_GEP = 251, // GEP + PLX_FLAG_PORT_GEP_DS = 255, // GEP parent DS + PLX_FLAG_PORT_MPT0 = 247, // MPT0 + PLX_FLAG_PORT_MPT1 = 248, // MPT1 + PLX_FLAG_PORT_MPT2 = 249, // MPT2 + PLX_FLAG_PORT_MPT3 = 250 // MPT3 +} PLX_FLAG_PORT; + + +// Generic states used internally by PLX software +typedef enum _PLX_STATE +{ + PLX_STATE_OK, + PLX_STATE_NO_CHANGE, + PLX_STATE_WORKING, + PLX_STATE_ERROR, + PLX_STATE_ENABLED, + PLX_STATE_DISABLED, + PLX_STATE_UNINITIALIZED, + PLX_STATE_INITIALIZING, + PLX_STATE_INITIALIZED, + PLX_STATE_IDLE, + PLX_STATE_BUSY, + PLX_STATE_STARTED, + PLX_STATE_STARTING, + PLX_STATE_STOPPED, + PLX_STATE_STOPPING, + PLX_STATE_CANCELED, + PLX_STATE_DELETED, + PLX_STATE_MARKED_FOR_DELETE, + PLX_STATE_OK_TO_DELETE, + PLX_STATE_TRIGGERED, + PLX_STATE_PENDING, + PLX_STATE_WAITING, + PLX_STATE_TIMEOUT, + PLX_STATE_REQUESTING, + PLX_STATE_REQUESTED, + PLX_STATE_ACCEPTING, + PLX_STATE_ACCEPTED, + PLX_STATE_REJECTED, + PLX_STATE_COMPLETING, + PLX_STATE_COMPLETED, + PLX_STATE_CONNECTING, + PLX_STATE_CONNECTED, + PLX_STATE_DISCONNECTING, + PLX_STATE_DISCONNECTED +} PLX_STATE; + + +// BAR flags +typedef enum _PLX_BAR_FLAG +{ + PLX_BAR_FLAG_MEM = (1 << 0), + PLX_BAR_FLAG_IO = (1 << 1), + PLX_BAR_FLAG_BELOW_1MB = (1 << 2), + PLX_BAR_FLAG_32_BIT = (1 << 3), + PLX_BAR_FLAG_64_BIT = (1 << 4), + PLX_BAR_FLAG_PREFETCHABLE = (1 << 5), + PLX_BAR_FLAG_UPPER_32 = (1 << 6), + PLX_BAR_FLAG_PROBED = (1 << 7) +} PLX_BAR_FLAG; + + +// EEPROM status +typedef enum _PLX_EEPROM_STATUS +{ + PLX_EEPROM_STATUS_NONE = 0, // Not present + PLX_EEPROM_STATUS_VALID = 1, // Present with valid data + PLX_EEPROM_STATUS_INVALID_DATA = 2, // Present w/invalid data or CRC error + PLX_EEPROM_STATUS_BLANK = PLX_EEPROM_STATUS_INVALID_DATA, + PLX_EEPROM_STATUS_CRC_ERROR = PLX_EEPROM_STATUS_INVALID_DATA +} PLX_EEPROM_STATUS; + + +// EEPROM port numbers +typedef enum _PLX_EEPROM_PORT +{ + PLX_EEPROM_PORT_NONE = 0, + PLX_EEPROM_PORT_NT_VIRT_0 = 254, + PLX_EEPROM_PORT_NT_LINK_0 = 253, + PLX_EEPROM_PORT_NT_VIRT_1 = 252, + PLX_EEPROM_PORT_NT_LINK_1 = 251, + PLX_EEPROM_PORT_DMA_0 = 250, + PLX_EEPROM_PORT_DMA_1 = 249, + PLX_EEPROM_PORT_DMA_2 = 248, + PLX_EEPROM_PORT_DMA_3 = 247, + PLX_EEPROM_PORT_SHARED_MEM = 246 +} PLX_EEPROM_PORT; + + +// EEPROM CRC status +typedef enum _PLX_CRC_STATUS +{ + PLX_CRC_INVALID = 0, + PLX_CRC_VALID = 1, + PLX_CRC_UNSUPPORTED = 2, + PLX_CRC_UNKNOWN = 3 +} PLX_CRC_STATUS; + + +// SPI flags +typedef enum _PEX_SPI_FLAGS +{ + PEX_SPI_FLAG_NONE = 0, // No flags + PEX_SPI_FLAG_USE_MM_RD = (1 << 1), // Use mem-mapped read if supp + PEX_SPI_FLAG_DUAL_IO_SUPP = (1 << 2), // Dual I/O supported + PEX_SPI_FLAG_QUAD_IO_SUPP = (1 << 3) // Dual I/O supported +} PEX_SPI_FLAGS; + + +// SPI I/O mode types +typedef enum _PEX_SPI_IO_MODE +{ + PEX_SPI_IO_MODE_SERIAL = 0, // Standard serial mode + PEX_SPI_IO_MODE_DUAL_IO = 1, // Dual I/O mode + PEX_SPI_IO_MODE_QUAD_IO = 2 // Quad I/O mode +} PEX_SPI_IO_MODE; + + +// Special value to indicate erase all of flash +#define SPI_FLASH_ERASE_ALL (U32)-1 + + +// PCI Express Link Speeds +typedef enum _PLX_LINK_SPEED +{ + PLX_LINK_SPEED_2_5_GBPS = 1, + PLX_LINK_SPEED_5_GBPS = 2, + PLX_LINK_SPEED_8_GBPS = 3, + PLX_LINK_SPEED_16_GBPS = 4 +} PLX_LINK_SPEED; + + +// Interrupt generation types +typedef enum _PLX_IRQ_TYPE +{ + PLX_IRQ_TYPE_NONE = 0, // No interrupt + PLX_IRQ_TYPE_UNKNOWN = 1, // Undefined interrupt type + PLX_IRQ_TYPE_INTX = 2, // Legacy INTx interrupt (INTA,INTB,etc) + PLX_IRQ_TYPE_MSI = 3, // MSI interrupt + PLX_IRQ_TYPE_MSIX = 4 // MSI-X interrupt +} PLX_IRQ_TYPE; + + +// Port types +typedef enum _PLX_PORT_TYPE +{ + PLX_PORT_UNKNOWN = 0xFF, + PLX_PORT_ENDPOINT = 0, + PLX_PORT_LEGACY_ENDPOINT = 1, + PLX_PORT_ROOT_PORT = 4, + PLX_PORT_UPSTREAM = 5, + PLX_PORT_DOWNSTREAM = 6, + PLX_PORT_PCIE_TO_PCI_BRIDGE = 7, + PLX_PORT_PCI_TO_PCIE_BRIDGE = 8, + PLX_PORT_ROOT_ENDPOINT = 9, + PLX_PORT_ROOT_EVENT_COLL = 10 +} PLX_PORT_TYPE; + + +// PLX-specific port types +typedef enum _PLX_SPECIFIC_PORT_TYPE +{ + PLX_SPEC_PORT_UNKNOWN = 0, // Unknown port type + PLX_SPEC_PORT_INVALID = 0xFF, // Invalid port type + PLX_SPEC_PORT_NT_VIRTUAL = 1, // NT Virtual-side + PLX_SPEC_PORT_NT_LINK = 2, // NT Link-side + PLX_SPEC_PORT_UPSTREAM = 3, // Upstream port + PLX_SPEC_PORT_DOWNSTREAM = 4, // Downstream port + PLX_SPEC_PORT_P2P_BRIDGE = 5, // P2P bridge + PLX_SPEC_PORT_LEGACY_EP = 6, // Legacy EP + PLX_SPEC_PORT_DMA = 7, // DMA EP + PLX_SPEC_PORT_HOST = 8, // Host port + PLX_SPEC_PORT_FABRIC = 9, // Fabric port + PLX_SPEC_PORT_GEP = 10, // Global EP + PLX_SPEC_PORT_MPT = 11, // MPT SAS controller EP + PLX_SPEC_PORT_MPT_NO_SES = 12, // MPT EP (No SES) + PLX_SPEC_PORT_SYNTH_NIC = 13, // Synthetic NIC VF + PLX_SPEC_PORT_SYNTH_TWC = 14, // Synthetic TWC EP + PLX_SPEC_PORT_SYNTH_EN_EP = 15, // Synthetic Enabler EP + PLX_SPEC_PORT_SYNTH_NT = 16, // Synthetic NT 2.0 EP + PLX_SPEC_PORT_SYNTH_MPT = 17, // Synthetic MPT SAS controller EP + PLX_SPEC_PORT_SYNTH_GDMA = 18, // Synthetic gDMA EP + PLX_SPEC_PORT_INT_MGMT = 19, // iSSW internal management port +} PLX_SPECIFIC_PORT_TYPE; + +// For compatibility +typedef PLX_SPECIFIC_PORT_TYPE PLX_NT_PORT_TYPE; + + +// NT port configuration types +typedef enum _PLX_NT_CONFIG_TYPE +{ + PLX_NT_CONFIG_TYPE_NONE = 0, + PLX_NT_CONFIG_TYPE_LINK_DOWN, + PLX_NT_CONFIG_TYPE_STANDARD, + PLX_NT_CONFIG_TYPE_BACK_TO_BACK +} PLX_NT_CONFIG_TYPE; + + +// Non-transparent LUT flags +typedef enum _PLX_NT_LUT_FLAG +{ + PLX_NT_LUT_FLAG_NONE = 0, + PLX_NT_LUT_FLAG_NO_SNOOP = (1 << 0), + PLX_NT_LUT_FLAG_READ = (1 << 1), + PLX_NT_LUT_FLAG_WRITE = (1 << 2) +} PLX_NT_LUT_FLAG; + + +// DMA control commands +typedef enum _PLX_DMA_COMMAND +{ + DmaPause, + DmaPauseImmediate, + DmaResume, + DmaAbort +} PLX_DMA_COMMAND; + + +// DMA transfer direction +typedef enum _PLX_DMA_DIR +{ + PLX_DMA_PCI_TO_LOC = 0, // DMA PCI --> Local bus (9000 DMA) + PLX_DMA_LOC_TO_PCI = 1, // DMA Local bus --> PCI (9000 DMA) + PLX_DMA_USER_TO_PCI = PLX_DMA_PCI_TO_LOC, // DMA User buffer --> PCI (8000 DMA) + PLX_DMA_PCI_TO_USER = PLX_DMA_LOC_TO_PCI // DMA PCI --> User buffer (8000 DMA) +} PLX_DMA_DIR; + + +// DMA Descriptor Mode +typedef enum _PLX_DMA_DESCR_MODE +{ + PLX_DMA_MODE_BLOCK = 0, // DMA Block transfer mode + PLX_DMA_MODE_SGL = 1, // DMA SGL with descriptors off-chip + PLX_DMA_MODE_SGL_INTERNAL = 2 // DMA SGL with descriptors on-chip +} PLX_DMA_DESCR_MODE; + + +// DMA Ring Delay Period +typedef enum _PLX_DMA_RING_DELAY_TIME +{ + PLX_DMA_RING_DELAY_0 = 0, + PLX_DMA_RING_DELAY_1us = 1, + PLX_DMA_RING_DELAY_2us = 2, + PLX_DMA_RING_DELAY_8us = 3, + PLX_DMA_RING_DELAY_32us = 4, + PLX_DMA_RING_DELAY_128us = 5, + PLX_DMA_RING_DELAY_512us = 6, + PLX_DMA_RING_DELAY_1ms = 7 +} PLX_DMA_RING_DELAY_TIME; + + +// DMA Maximum Source & Destination Transfer Sizes +typedef enum _PLX_DMA_MAX_TSIZE +{ + PLX_DMA_MAX_TSIZE_64B = 0, + PLX_DMA_MAX_TSIZE_128B = 1, + PLX_DMA_MAX_TSIZE_256B = 2, + PLX_DMA_MAX_TSIZE_512B = 3, + PLX_DMA_MAX_TSIZE_1K = 4, + PLX_DMA_MAX_TSIZE_2K = 5, + PLX_DMA_MAX_TSIZE_4B = 7, + + // Legacy definitions may be removed in future + PLX_DMA_MAX_SRC_TSIZE_64B = PLX_DMA_MAX_TSIZE_64B, + PLX_DMA_MAX_SRC_TSIZE_128B = PLX_DMA_MAX_TSIZE_128B, + PLX_DMA_MAX_SRC_TSIZE_256B = PLX_DMA_MAX_TSIZE_256B, + PLX_DMA_MAX_SRC_TSIZE_512B = PLX_DMA_MAX_TSIZE_512B, + PLX_DMA_MAX_SRC_TSIZE_1K = PLX_DMA_MAX_TSIZE_1K, + PLX_DMA_MAX_SRC_TSIZE_2K = PLX_DMA_MAX_TSIZE_2K, + PLX_DMA_MAX_SRC_TSIZE_4B = PLX_DMA_MAX_TSIZE_4B +} PLX_DMA_MAX_TSIZE; + + +// Performance monitor control +typedef enum _PLX_PERF_CMD +{ + PLX_PERF_CMD_START, + PLX_PERF_CMD_STOP, +} PLX_PERF_CMD; + + +// Used for device power state. Added for code compatability with Linux +#if !defined(PLX_MSWINDOWS) + typedef enum _DEVICE_POWER_STATE + { + PowerDeviceUnspecified = 0, + PowerDeviceD0, + PowerDeviceD1, + PowerDeviceD2, + PowerDeviceD3, + PowerDeviceMaximum + } DEVICE_POWER_STATE; +#endif + + +// Properties of API access mode +typedef struct _PLX_MODE_PROP +{ + union + { + struct + { + U16 I2cPort; + U16 SlaveAddr; + U32 ClockRate; + } I2c; + + struct + { + U8 Port; + U32 ClockRate; + char *StrPath; + } Mdio; + + struct + { + U8 Port; + U8 Baud; + U8 Cable; + } Sdb; + + struct + { + U64 IpAddress; + } Tcp; + }; +} PLX_MODE_PROP; + + +// PLX version information +typedef struct _PLX_VERSION +{ + PLX_API_MODE ApiMode; + + union + { + struct + { + U16 ApiLibrary; // API library version + U16 Software; // Software version + U16 Firmware; // Firmware version + U16 Hardware; // Hardware version + U16 SwReqByFw; // Firmware requires software must be >= this version + U16 FwReqBySw; // Software requires firmware must be >= this version + U16 ApiReqBySw; // Software requires API interface must be >= this version + U32 Features; // Bitmask of supported features + } I2c; + }; +} PLX_VERSION; + + +// Chip features & port mask +typedef struct _PEX_CHIP_FEAT +{ + U8 StnCount; // Supported station count + U8 PortsPerStn; // Max number of ports per station + U8 StnMask; // Bitmask of enabled stations + PEX_BITMASK_T( PortMask, 256 ); // Bitmask for ports and special types +} PEX_CHIP_FEAT; + + +// PCI Memory Structure +typedef struct _PLX_PHYSICAL_MEM +{ + U64 UserAddr; // User-mode virtual address + U64 PhysicalAddr; // Bus physical address + U64 CpuPhysical; // CPU physical address + U32 Size; // Size of the buffer +} PLX_PHYSICAL_MEM; + + +// PLX Driver Properties +typedef struct _PLX_DRIVER_PROP +{ + U32 Version; // Driver version + char Name[16]; // Driver name + char FullName[255]; // Full driver name + U8 bIsServiceDriver; // Is service driver or PnP driver? + U64 AcpiPcieEcam; // Base address of PCIe ECAM +} PLX_DRIVER_PROP; + + +// PCI BAR Properties +typedef struct _PLX_PCI_BAR_PROP +{ + U64 BarValue; // Actual value in BAR + U64 Physical; // BAR Physical Address + U64 Size; // Size of BAR space + U32 Flags; // Additional BAR properties +} PLX_PCI_BAR_PROP; + + +// Used for getting the port properties and status +typedef struct _PLX_PORT_PROP +{ + U8 PortType; // Port configuration + U8 PortNumber; // Internal port number + U8 LinkWidth; // Negotiated port link width + U8 MaxLinkWidth; // Max link width device is capable of + U8 LinkSpeed; // Negotiated link speed + U8 MaxLinkSpeed; // Max link speed device is capable of + U16 MaxReadReqSize; // Max read request size allowed + U16 MaxPayloadSize; // Max payload size setting + U16 MaxPayloadSupported; // Max payload size supported by device + U8 bNonPcieDevice; // Flag whether device is a PCIe device +} PLX_PORT_PROP; + + +// Used for getting the multi-host switch properties +typedef struct _PLX_MULTI_HOST_PROP +{ + U8 SwitchMode; // Current switch mode + U16 VS_EnabledMask; // Bit for each enabled Virtual Switch + U8 VS_UpstreamPortNum[8]; // Upstream port number of each Virtual Switch + U32 VS_DownstreamPorts[8]; // Downstream ports associated with a Virtual Switch + U8 bIsMgmtPort; // Is selected device management port + U8 bMgmtPortActiveEn; // Is active management port enabled + U8 MgmtPortNumActive; // Active management port + U8 bMgmtPortRedundantEn; // Is redundant management port enabled + U8 MgmtPortNumRedundant; // Redundant management port +} PLX_MULTI_HOST_PROP; + + +// SPI flash properties +typedef struct _PEX_SPI_OBJ +{ + U32 IsValidTag; // Magic number to determine validity + U8 Flags; // Additional flags + U8 ChipSel; // Chip select to access + U8 IoMode; // I/O moode to use + U8 PageSize; // Page size in power of 2 + U8 SectorsCount; // Sector count in power of 2 + U8 SectorSize; // Sector size in power of 2 + U8 MfgID; // Manufacturer ID + U16 DeviceId; // Device-reported ID + U32 CtrlBaseAddr; // Address/offset of SPI controller registers + U32 MmapAddr; // AXI mem-mapped address to flash (optional) +} PEX_SPI_OBJ; + + +// PCI Device Key Identifier +typedef struct _PLX_DEVICE_KEY +{ + U32 IsValidTag; // Magic number to determine validity + U8 domain; // Physical device location + U8 bus; + U8 slot; + U8 function; + U16 VendorId; // Device Identifier + U16 DeviceId; + U16 SubVendorId; + U16 SubDeviceId; + U8 Revision; + U16 PlxChip; // PLX chip type + U16 ChipID; // Chip ID (if reported) + U8 PlxRevision; // PLX chip revision + U8 PlxFamily; // PLX chip family + U8 ApiIndex; // Used internally by the API + U16 DeviceNumber; // Used internally by device drivers + U8 ApiMode; // Mode API uses to access device + U8 PlxPort; // PLX port number of device + U8 PlxPortType; // PLX-specific port type (NT/DMA/Host/etc) + U8 NTPortNum; // If NT port exists, store NT port number + U8 DeviceMode; // Device mode used internally by API + U32 ApiInternal[2]; // Reserved for internal PLX API use +} PLX_DEVICE_KEY; + + +// PLX Device Object Structure +typedef struct _PLX_DEVICE_OBJECT +{ + U32 IsValidTag; // Magic number to determine validity + PLX_DEVICE_KEY Key; // Device location key identifier + PLX_DRIVER_HANDLE hDevice; // Handle to driver + PLX_PCI_BAR_PROP PciBar[6]; // PCI BAR properties + U64 PciBarVa[6]; // For PCI BAR user-mode BAR mappings + U8 BarMapRef[6]; // BAR map count used by API + PLX_PHYSICAL_MEM CommonBuffer; // Used to store common buffer information + U64 PrivateData[4];// Private storage for user application +} PLX_DEVICE_OBJECT; + + +// PLX Notification Object +typedef struct _PLX_NOTIFY_OBJECT +{ + U32 IsValidTag; // Magic number to determine validity + U64 pWaitObject; // -- INTERNAL -- Wait object used by the driver + U64 hEvent; // User event handle (HANDLE can be 32 or 64 bit) +} PLX_NOTIFY_OBJECT; + + +// PLX Interrupt Structure +typedef struct _PLX_INTERRUPT +{ + U32 Doorbell; // Up to 32 doorbells + U8 PciMain :1; + U8 PciAbort :1; + U8 LocalToPci :2; // Local->PCI interrupts 1 & 2 + U8 DmaDone :4; // DMA channel 0-3 interrupts + U8 DmaPauseDone :4; + U8 DmaAbortDone :4; + U8 DmaImmedStopDone :4; + U8 DmaInvalidDescr :4; + U8 DmaError :4; + U8 MuInboundPost :1; + U8 MuOutboundPost :1; + U8 MuOutboundOverflow :1; + U8 TargetRetryAbort :1; + U8 Message :4; // 6000 NT 0-3 message interrupts + U8 SwInterrupt :1; + U8 ResetDeassert :1; + U8 PmeDeassert :1; + U8 GPIO_4_5 :1; // 6000 NT GPIO 4/5 interrupt + U8 GPIO_14_15 :1; // 6000 NT GPIO 14/15 interrupt + U8 NTV_LE_Correctable :1; // 8000 NT Virtual - Link-side error interrupts + U8 NTV_LE_Uncorrectable :1; + U8 NTV_LE_LinkStateChange :1; + U8 NTV_LE_UncorrErrorMsg :1; +} PLX_INTERRUPT; + + +// DMA Channel Properties Structure +typedef struct _PLX_DMA_PROP +{ + // 8000 DMA properties + U8 CplStatusWriteBack :1; + U8 DescriptorMode :2; + U8 DescriptorPollMode :1; + U8 RingHaltAtEnd :1; + U8 RingWrapDelayTime :3; + U8 RelOrderDescrRead :1; + U8 RelOrderDescrWrite :1; + U8 RelOrderDataReadReq :1; + U8 RelOrderDataWrite :1; + U8 NoSnoopDescrRead :1; + U8 NoSnoopDescrWrite :1; + U8 NoSnoopDataReadReq :1; + U8 NoSnoopDataWrite :1; + U8 MaxSrcXferSize :3; + U8 MaxDestWriteSize :3; + U8 TrafficClass :3; + U8 MaxPendingReadReq :6; + U8 DescriptorPollTime; + U8 MaxDescriptorFetch; + U16 ReadReqDelayClocks; + + // 9000 DMA properties + U8 ReadyInput :1; + U8 Burst :1; + U8 BurstInfinite :1; + U8 SglMode :1; + U8 DoneInterrupt :1; + U8 RouteIntToPci :1; + U8 ConstAddrLocal :1; + U8 WriteInvalidMode :1; + U8 DemandMode :1; + U8 EnableEOT :1; + U8 FastTerminateMode :1; + U8 ClearCountMode :1; + U8 DualAddressMode :1; + U8 EOTEndLink :1; + U8 ValidMode :1; + U8 ValidStopControl :1; + U8 LocalBusWidth :2; + U8 WaitStates :4; +} PLX_DMA_PROP; + + +// DMA Transfer Parameters +typedef struct _PLX_DMA_PARAMS +{ + U64 UserVa; // User buffer virtual address + U64 AddrSource; // Source address (8000 DMA) + U64 AddrDest; // Destination address (8000 DMA) + U64 PciAddr; // PCI address (9000 DMA) + U32 LocalAddr; // Local bus address (9000 DMA) + U32 ByteCount; // Number of bytes to transfer + U8 Direction; // Direction of transfer (Local<->PCI, User<->PCI) (9000 DMA) + U8 bConstAddrSrc :1; // Constant source PCI address? (8000 DMA) + U8 bConstAddrDest :1; // Constant destination PCI address? (8000 DMA) + U8 bForceFlush :1; // Force DMA to flush write on final descriptor (8000 DMA) + U8 bIgnoreBlockInt :1; // For block mode only, do not enable DMA done interrupt +} PLX_DMA_PARAMS; + + +// Performance properties +typedef struct _PLX_PERF_PROP +{ + U32 IsValidTag; // Magic number to determine validity + + // Chip properties + U8 PlxFamily; + + // Port properties + U8 PortNumber; + U8 LinkWidth; + U8 LinkSpeed; + U8 Station; + U8 StationPort; + + // Ingress counters + U32 IngressPostedHeader; + U32 IngressPostedDW; + U32 IngressNonpostedHdr; + U32 IngressNonpostedDW; + U32 IngressCplHeader; + U32 IngressCplDW; + U32 IngressDllp; + + // Egress counters + U32 EgressPostedHeader; + U32 EgressPostedDW; + U32 EgressNonpostedHdr; + U32 EgressNonpostedDW; + U32 EgressCplHeader; + U32 EgressCplDW; + U32 EgressDllp; + + // Storage for previous counter values + + // Previous Ingress counters + U32 Prev_IngressPostedHeader; + U32 Prev_IngressPostedDW; + U32 Prev_IngressNonpostedHdr; + U32 Prev_IngressNonpostedDW; + U32 Prev_IngressCplHeader; + U32 Prev_IngressCplDW; + U32 Prev_IngressDllp; + + // Previous Egress counters + U32 Prev_EgressPostedHeader; + U32 Prev_EgressPostedDW; + U32 Prev_EgressNonpostedHdr; + U32 Prev_EgressNonpostedDW; + U32 Prev_EgressCplHeader; + U32 Prev_EgressCplDW; + U32 Prev_EgressDllp; +} PLX_PERF_PROP; + + +// Performance statistics +typedef struct _PLX_PERF_STATS +{ + S64 IngressTotalBytes; // Total bytes including overhead + long double IngressTotalByteRate; // Total byte rate + S64 IngressCplAvgPerReadReq; // Average number of completion TLPs for read requests + S64 IngressCplAvgBytesPerTlp; // Average number of bytes per completion TLPs + S64 IngressPayloadReadBytes; // Payload bytes read (Completion TLPs) + S64 IngressPayloadReadBytesAvg; // Average payload bytes for reads (Completion TLPs) + S64 IngressPayloadWriteBytes; // Payload bytes written (Posted TLPs) + S64 IngressPayloadWriteBytesAvg; // Average payload bytes for writes (Posted TLPs) + S64 IngressPayloadTotalBytes; // Payload total bytes + double IngressPayloadAvgPerTlp; // Payload average size per TLP + long double IngressPayloadByteRate; // Payload byte rate + long double IngressLinkUtilization; // Total link utilization + + S64 EgressTotalBytes; // Total byte including overhead + long double EgressTotalByteRate; // Total byte rate + S64 EgressCplAvgPerReadReq; // Average number of completion TLPs for read requests + S64 EgressCplAvgBytesPerTlp; // Average number of bytes per completion TLPs + S64 EgressPayloadReadBytes; // Payload bytes read (Completion TLPs) + S64 EgressPayloadReadBytesAvg; // Average payload bytes for reads (Completion TLPs) + S64 EgressPayloadWriteBytes; // Payload bytes written (Posted TLPs) + S64 EgressPayloadWriteBytesAvg; // Average payload bytes for writes (Posted TLPs) + S64 EgressPayloadTotalBytes; // Payload total bytes + double EgressPayloadAvgPerTlp; // Payload average size per TLP + long double EgressPayloadByteRate; // Payload byte rate + long double EgressLinkUtilization; // Total link utilization +} PLX_PERF_STATS; + + + +// Restore previous pack value +#pragma pack( pop ) + + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/Plxlibrary/Plx_sysdep.h b/Plxlibrary/Plx_sysdep.h new file mode 100755 index 0000000..18b027c --- /dev/null +++ b/Plxlibrary/Plx_sysdep.h @@ -0,0 +1,490 @@ +#ifndef _PLX_SYSDEP_H_ +#define _PLX_SYSDEP_H_ + +/******************************************************************************* + * Copyright 2013-2019 Broadcom Inc + * Copyright (c) 2009 to 2012 PLX Technology Inc. All rights reserved. + * + * This software is available to you under a choice of one of two + * licenses. You may choose to be licensed under the terms of the GNU + * General Public License (GPL) Version 2, available from the file + * COPYING in the main directorY of this source tree, or the + * BSD license below: + * + * Redistribution and use in source and binary forms, with or + * without modification, are permitted provided that the following + * conditions are met: + * + * - Redistributions of source code must retain the above + * copyright notice, this list of conditions and the following + * disclaimer. + * + * - Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + ******************************************************************************/ + +/****************************************************************************** + * + * File Name: + * + * Plx_sysdep.h + * + * Description: + * + * This file is provided to support compatible code between different + * Linux kernel versions. + * + * Revision History: + * + * 04-01-19 : PCI/PCIe SDK v8.00 + * + *****************************************************************************/ + + +#ifndef LINUX_VERSION_CODE + #include +#endif + + +// Only allow 2.6.18 and higher kernels +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,18) + #error "ERROR: Linux kernel versions prior to v2.6.18 not supported" +#endif + + + + +/*********************************************************** + * IORESOURCE_MEM_64 + * + * This flag specifies whether a PCI BAR space is 64-bit. The + * definition wasn't added until 2.6.31. + **********************************************************/ +#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,31)) + #define IORESOURCE_MEM_64 0x00100000 +#endif + + + + +/*********************************************************** + * VM_RESERVED + * + * This flag was removed starting with 3.7. The recommended + * replacement is a combination of two flags. + **********************************************************/ +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,7,0)) + #define VM_RESERVED (VM_DONTEXPAND | VM_DONTDUMP) +#endif + + + + +/*********************************************************** + * INIT_WORK & INIT_DELAYED_WORK + * + * This macro initializes a work structure with the function + * to call. In kernel 2.6.20, the 3rd parameter was removed. + * It used to be the parameter to the function, but now, the + * function is called with a pointer to the work_struct itself. + * INIT_DELAYED_WORK was introduced to init the delayed_work struct. + **********************************************************/ +#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,20)) + #define PLX_INIT_WORK INIT_WORK + // Red Hat pre-defines this + #if !defined(RED_HAT_LINUX_KERNEL) + #define INIT_DELAYED_WORK INIT_WORK + #endif +#else + #define PLX_INIT_WORK(work, func, data) INIT_WORK((work), (func)) +#endif + + + + +/*********************************************************** + * ioremap_prot + * + * This function is supported after 2.6.27 only one some + * architectures, like x86 & PowerPC. Other architectures + * added support for it in later kernels. For platforms + * that support it, HAVE_IOREMAP_PROT is expected defined. + * SDK drivers use the function for probing ACPI tables. In + * newer kernels, calls to ioremap() for ACPI locations may + * report errors if default flags conflict with kernel mappings. + **********************************************************/ +#if !defined(CONFIG_HAVE_IOREMAP_PROT) + // Revert to ioremap() for unsupported architectures + #define ioremap_prot(addr,size,flags) ioremap((addr), (size)) +#endif + + + + +/*********************************************************** + * pgprot_writecombine + * + * This function is not supported on all platforms. There is + * a standard definition for it starting with 2.6.29. + **********************************************************/ +#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,29)) + #define pgprot_writecombine pgprot_noncached +#endif + + + + +/*********************************************************** + * access_ok + * + * access_ok() removed type param in 5.0 + **********************************************************/ +#if (LINUX_VERSION_CODE < KERNEL_VERSION(5,0,0)) + #define Plx_access_ok access_ok +#else + #define Plx_access_ok(type,addr,size) access_ok( (addr),(size) ) +#endif + + + + +/*********************************************************** + * sema_init / init_MUTEX + * + * init_MUTEX replaced by sema_init starting with 2.6.26 + **********************************************************/ +#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,26)) + #define Plx_sema_init(sem, n) init_MUTEX( (sem) ) +#else + #define Plx_sema_init sema_init +#endif + + + + +/*********************************************************** + * flush_work + * + * Flush work queue function not added until 2.6.27 + **********************************************************/ +#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,27)) + #define Plx_flush_work(x) +#else + #define Plx_flush_work flush_work +#endif + + + + +/*********************************************************** + * PLX_DPC_PARAM + * + * In kernel 2.6.20, the parameter to a work queue function + * was made to always be a pointer to the work_struct itself. + * In previous kernels, this was always a VOID*. Since + * PLX drivers use work queue functions for the DPC/bottom-half + * processing, the parameter had to be changed. For cleaner + * source code, the definition PLX_DPC_PARAM is used and is + * defined below. + **********************************************************/ +#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,20)) + #define PLX_DPC_PARAM VOID +#else + #define PLX_DPC_PARAM struct work_struct +#endif + + + + +/*********************************************************** + * pci_get_domain_bus_and_slot not added until 2.6.33 + **********************************************************/ +#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,33)) + #define Plx_pci_get_domain_bus_and_slot(d,b,df) pci_get_bus_and_slot( b, df ) +#else + #define Plx_pci_get_domain_bus_and_slot pci_get_domain_bus_and_slot +#endif + + + + +/*********************************************************** + * pci_enable_msi/pci_enable_msix deprecated + * + * The pci_*_msi/msix MSI functions are deprecated as of + * kernel 4.8. A new set of PCI subsystem functions have + * replaced them. + **********************************************************/ +#if (LINUX_VERSION_CODE < KERNEL_VERSION(4,8,0)) + + #define Plx_pci_enable_msi pci_enable_msi + #define Plx_pci_disable_msi pci_disable_msi + #define Plx_pci_enable_msix pci_enable_msix + #define Plx_pci_disable_msix pci_disable_msix + +#else + + #define Plx_pci_enable_msi( pdev ) pci_alloc_irq_vectors( (pdev), 1, 1, PCI_IRQ_MSI ) + #define Plx_pci_disable_msi pci_free_irq_vectors + #define Plx_pci_disable_msix pci_free_irq_vectors + + #define Plx_pci_enable_msix(pdev,entries,nvec) \ + ({ \ + int _rc; \ + int _idx; \ + \ + /* Attempt to allocate MSI-X vectors */ \ + _rc = pci_alloc_irq_vectors( \ + (pdev), (nvec), (nvec), PCI_IRQ_MSIX ); \ + if (_rc == (nvec)) \ + { \ + /* Set successful return value */ \ + _rc = 0; \ + \ + /* Fill in the vector table */ \ + for (_idx = 0; _idx < (nvec); _idx++) \ + { \ + (entries)[_idx].vector = \ + pci_irq_vector( (pdev), (entries)[_idx].entry ); \ + } \ + } \ + \ + _rc; \ + }) + +#endif + + + + +/*********************************************************** + * kmap_atomic/kunmap_atomic - 2nd parameter removed in 2.6.37 + **********************************************************/ +#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,37)) + #define Plx_kmap_atomic kmap_atomic + #define Plx_kunmap_atomic kunmap_atomic +#else + #define Plx_kmap_atomic(page,kmtype) kmap_atomic( (page) ) + #define Plx_kunmap_atomic(page,kmtype) kunmap_atomic( (page) ) +#endif + + + + +/*********************************************************** + * 'secondary' & 'subordinate' fields removed from 'struct pci_bus' + * in 3.6 & replaced with start/end fields in a 'struct resource'. + **********************************************************/ +#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,6,0)) + #define Plx_STRUCT_PCI_BUS_SEC(pbus) (pbus)->secondary + #define Plx_STRUCT_PCI_BUS_SUB(pbus) (pbus)->subordinate +#else + #define Plx_STRUCT_PCI_BUS_SEC(pbus) (pbus)->busn_res.start + #define Plx_STRUCT_PCI_BUS_SUB(pbus) (pbus)->busn_res.end +#endif + + + + +/*********************************************************** + * skb_frag_struct "page" field changed from pointer to + * a page pointer within a structure in 3.2.0 + **********************************************************/ +#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,2,0)) + #define Plx_SKB_FRAG_STRUCT_PAGE(frag) (frag)->page +#else + #define Plx_SKB_FRAG_STRUCT_PAGE(frag) (frag)->page.p +#endif + + + + +/*********************************************************** + * pcie_cap field in pci_dev - Added by 2.6.38 + * + * The pci_dev structure has a pcie_cap field to report the + * device's PCIe capability (10h) starting offset. + * This field is was also added to updated RedHat kernels. + **********************************************************/ +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38)) || \ + ((LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,32)) && defined(RED_HAT_LINUX_KERNEL)) + #define Plx_pcie_cap(pDev) ((pDev)->pcie_cap) +#else + #define Plx_pcie_cap(pDev) pci_find_capability( (pDev), 0x10 ) +#endif + + + + +/*********************************************************** + * is_virtfn field in pci_dev - Added in 2.6.30 + * pci_physfn - Added by 2.6.35 + * + * For SR-IOV devices, there is an 'is_virtfn' field in the + * pci_dev structure to report whether the device is a VF. This + * field is was also added to updated RedHat kernels. + * + * pci_physfn returns the parent PF of a VF; otherwise, returns + * the passed device. + ***********************************************************/ +#if defined(CONFIG_PCI_IOV) && \ + ((LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,30)) || \ + ((LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,18)) && defined(RED_HAT_LINUX_KERNEL))) + #define Plx_pcie_is_virtfn(pDev) ((pDev)->is_virtfn) + + #if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,35)) + #define Plx_pci_physfn(pDev) \ + ({ \ + struct pci_dev *_pDev; \ + \ + if (pDev->is_virtfn) \ + _pDev = (pDev->physfn); \ + else \ + _pDev = pDev; \ + _pDev; \ + }) + #else + #define Plx_pci_physfn pci_physfn + #endif +#else + #define Plx_pcie_is_virtfn(pDev) (FALSE) + #define Plx_pci_physfn(pDev) (pDev) +#endif + + + + +/*********************************************************** + * readq / writeq + * + * These functions are used to perform 64-bit accesses to + * I/O memory. They are not defined for all architectures. + * For x86 32-bit, they were added in 2.6.29. + * + * NOTE: This is still incomplete for non-x86 32-bit architectures + * where readq/writeq are not yet defined. + **********************************************************/ +#if ((LINUX_VERSION_CODE < KERNEL_VERSION(2,6,29)) && defined(CONFIG_X86_32)) + // x86 64-bit I/O access functions + static inline __u64 readq(const volatile void __iomem *addr) + { + const volatile u32 __iomem *p = addr; + u64 value; + + value = readl(p); + value += ((u64)readl(p + 1) << 32); + + return value; + } + + static inline void writeq(__u64 val, volatile void __iomem *addr) + { + writel(val, addr); + writel(val >> 32, addr+4); + } + +#elif !defined(CONFIG_64BIT) && !defined(CONFIG_X86_32) + // Revert to 32-bit accesses for non-x86/x64 platforms + #define readq readl + #define writeq writel +#endif + + + + +/*********************************************************** + * get_user_pages + * + * Parameters to this function changed as follows: + * 4.6: Removed first two params (curr task & task's mem-manage struct) + * 4.9: Replaced write & force params with a single gup_flags param + **********************************************************/ +#if LINUX_VERSION_CODE < KERNEL_VERSION(4,6,0) + #define Plx_get_user_pages(start, nr_pages, gup_flags, pages, vmas) \ + ( \ + get_user_pages( \ + current, \ + current->mm, \ + (start), \ + (nr_pages), \ + ((gup_flags) & FOLL_WRITE) ? 1 : 0, \ + 0, \ + (pages), \ + (vmas) \ + ) \ + ) +#elif LINUX_VERSION_CODE < KERNEL_VERSION(4,9,0) + #define Plx_get_user_pages(start, nr_pages, gup_flags, pages, vmas) \ + ( \ + get_user_pages( \ + (start), \ + (nr_pages), \ + ((gup_flags) & FOLL_WRITE) ? 1 : 0, \ + 0, \ + (pages), \ + (vmas) \ + ) \ + ) +#else + #define Plx_get_user_pages get_user_pages +#endif + + + + +/*********************************************************** + * dma_set_coherent_mask / pci_set_consistent_dma_mask + * + * This function is used to set the mask for coherent/consistent + * DMA buffer allocations. Prior to 2.6.34, the function is + * pci_set_consistent_dma_mask. It is now dma_set_coherent_mask. + * The first parameter has also been changed from pci_dev + * structure to the dev structure found in pci_dev. + **********************************************************/ +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,34) + #define Plx_dma_set_coherent_mask(pdx, mask) \ + ( \ + pci_set_consistent_dma_mask( \ + (pdx)->pPciDevice, \ + (mask) \ + ) \ + ) +#else + #define Plx_dma_set_coherent_mask(pdx, mask) \ + ( \ + dma_set_coherent_mask( \ + &((pdx)->pPciDevice->dev), \ + (mask) \ + ) \ + ) +#endif + + + + +/*********************************************************** + * DMA_BIT_MASK + * + * This macro is used to specify bit masks (e.g dma_set_mask). + * It was introduced in 2.6.24 + **********************************************************/ +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,24) + #define PLX_DMA_BIT_MASK(n) (((n) == 64) ? ~0ULL : ((1ULL<<(n))-1)) +#else + #define PLX_DMA_BIT_MASK DMA_BIT_MASK +#endif + + + +#endif // _PLX_SYSDEP_H_ diff --git a/Plxlibrary/SdbComPort.h b/Plxlibrary/SdbComPort.h new file mode 100755 index 0000000..0b4f468 --- /dev/null +++ b/Plxlibrary/SdbComPort.h @@ -0,0 +1,171 @@ +#ifndef __SDB_COM_PORT_H +#define __SDB_COM_PORT_H + +/******************************************************************************* + * Copyright 2013-2019 Broadcom, Inc + * Copyright (c) 2009 to 2012 PLX Technology Inc. All rights reserved. + * + * This software is available to you under a choice of one of two + * licenses. You may choose to be licensed under the terms of the GNU + * General Public License (GPL) Version 2, available from the file + * COPYING in the main directorY of this source tree, or the + * BSD license below: + * + * Redistribution and use in source and binary forms, with or + * without modification, are permitted provided that the following + * conditions are met: + * + * - Redistributions of source code must retain the above + * copyright notice, this list of conditions and the following + * disclaimer. + * + * - Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + ******************************************************************************/ + +/******************************************************************************* + * + * File Name: + * + * SdbComPort.h + * + * Description: + * + * Header file for SDB COM port interface functions + * + * Revision History: + * + * 09-01-19: PCI/PCIe SDK v8.10 + * + ******************************************************************************/ + + +#include "PlxIoctl.h" + + +#ifdef __cplusplus +extern "C" { +#endif + + +/****************************************** + * Definitions + ******************************************/ +// OS-specific prefix for COM/TTY port name +#if defined(PLX_MSWINDOWS) + #define SDB_OS_COM_PORT_UART "\\\\.\\COM" + #define SDB_OS_COM_PORT_USB SDB_OS_COM_PORT_UART + #define SDB_OS_BAUD_19200 CBR_19200 + #define SDB_OS_BAUD_115200 CBR_115200 +#elif defined(PLX_LINUX) + #define SDB_OS_COM_PORT_UART "/dev/ttyS" + #define SDB_OS_COM_PORT_USB "/dev/ttyUSB" + #define SDB_OS_BAUD_19200 B19200 + #define SDB_OS_BAUD_115200 B115200 +#endif + +#define SDB_MAX_ATTEMPTS 2 // Max num of attempts if failure +#define SDB_NEEDS_INIT_CMD (0xFFFFFFFE) // Needs initial sync command +#define SDB_NEXT_READ_OFFSET_INIT (0xFFFFFFFF) // Init offset to force full read cmd + +// SDB command & reply sizes +#define SDB_READ_CMD_LEN (1 + 1 + 4 + 1) // Cmd + size + addr + end +#define SDB_READ_NEXT_CMD_LEN (1 + 1) // Cmd + end +#define SDB_READ_REPLY_LEN (4 + 1) // 4B data + ACK('%') +#define SDB_WRITE_CMD_LEN (1 + 1 + 4 + 4 + 1) // Cmd + size + addr + data + end +#define SDB_WRITE_REPLY_LEN (1) // 1B ACK('%') + +// SDB binary commands +#define SDB_CMD_READ 'G' +#define SDB_CMD_READ_NEXT 'N' +#define SDB_CMD_WRITE 'P' +#define SDB_CMD_END '\n' +#define SDB_CMD_ACK '%' +#define SDB_CMD_ERROR 'E' +#define SDB_CMD_INIT "%\n" + + + + +/****************************************** + * Device Selection Functions + *****************************************/ +PLX_STATUS +Sdb_DeviceOpen( + PLX_DEVICE_OBJECT *pDevice + ); + +PLX_STATUS +Sdb_DeviceClose( + PLX_DEVICE_OBJECT *pDevice + ); + +PLX_STATUS +Sdb_DeviceFindEx( + PLX_DEVICE_KEY *pKey, + U16 DeviceNumber, + PLX_MODE_PROP *pModeProp + ); + + +/****************************************** + * MDIO Private Support Functions + *****************************************/ +PLX_STATUS +Sdb_Driver_Connect( + PLX_DEVICE_OBJECT *pDevice, + PLX_MODE_PROP *pModeProp + ); + +BOOLEAN +Sdb_Sync_Connection( + PLX_DEVICE_OBJECT *pDevice + ); + +S32 +Sdb_Dispatch_IoControl( + PLX_DEVICE_OBJECT *pDevice, + U32 IoControlCode, + PLX_PARAMS *pIoBuffer, + U32 Size + ); + + +/****************************************** + * Device-specific Register Access Functions + *****************************************/ +U32 +Sdb_PlxRegisterRead( + PLX_DEVICE_OBJECT *pDevice, + U32 offset, + PLX_STATUS *pStatus, + BOOLEAN bAdjustForPort, + U16 bRetryOnError + ); + +PLX_STATUS +Sdb_PlxRegisterWrite( + PLX_DEVICE_OBJECT *pDevice, + U32 offset, + U32 value, + BOOLEAN bAdjustForPort + ); + + + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/Plxlibrary/SpiFlash.h b/Plxlibrary/SpiFlash.h new file mode 100755 index 0000000..9eab2c0 --- /dev/null +++ b/Plxlibrary/SpiFlash.h @@ -0,0 +1,192 @@ +#ifndef __SPI_FLASH_H +#define __SPI_FLASH_H + +/******************************************************************************* + * Copyright 2013-2020 Broadcom Inc + * Copyright (c) 2009 to 2012 PLX Technology Inc. All rights reserved. + * + * This software is available to you under a choice of one of two + * licenses. You may choose to be licensed under the terms of the GNU + * General Public License (GPL) Version 2, available from the file + * COPYING in the main directorY of this source tree, or the + * BSD license below: + * + * Redistribution and use in source and binary forms, with or + * without modification, are permitted provided that the following + * conditions are met: + * + * - Redistributions of source code must retain the above + * copyright notice, this list of conditions and the following + * disclaimer. + * + * - Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + ******************************************************************************/ + +/****************************************************************************** + * + * File Name: + * + * SpiFlash.h + * + * Description: + * + * SPI flash access functions + * + * Revision: + * + * 03-01-20 : PCI/PCIe SDK v8.10 + * + ******************************************************************************/ + + +#include "PlxApiDirect.h" + + +#ifdef __cplusplus +extern "C" { +#endif + + + + +/****************************************** + * Definitions + ******************************************/ + +#define SPI_REG_ADDR( ptrSpi, offset ) ((ptrSpi)->CtrlBaseAddr + (offset)) +#define SPI_MAX_CMD_LEN (1 + 4) // 1B cmd + 4B addr + +// Max time to wait until controller is ready +#define SPI_MAX_WAIT_CTRL_READY_MS (1000) + +// PBAM SPI registers +#define PEX_REG_SPI_MANUAL_IO_MODE 0x7C +#define PEX_REG_SPI_MANUAL_RD_DATA 0x78 +#define PEX_REG_SPI_MANUAL_WR_DATA 0x80 +#define PEX_REG_SPI_MANUAL_CTRL_STAT 0x84 + +// SPI flash command codes +#define SPI_FLASH_CMD_READ_ID_DEPRECATED 0x90 +#define SPI_FLASH_CMD_READ_ID_CFI 0x9F +#define SPI_FLASH_CMD_ERASE_ALL 0x60 +#define SPI_FLASH_CMD_3B_ERASE_SECTOR 0xD8 +#define SPI_FLASH_CMD_4B_ERASE_SECTOR 0xDC +#define SPI_FLASH_CMD_3B_READ 0x03 +#define SPI_FLASH_CMD_3B_READ_DUAL_IO 0xBB +#define SPI_FLASH_CMD_3B_READ_QUAD_IO 0xEB +#define SPI_FLASH_CMD_4B_READ 0x13 +#define SPI_FLASH_CMD_3B_WRITE 0x02 +#define SPI_FLASH_CMD_3B_WRITE_QUAD_IO 0x32 +#define SPI_FLASH_CMD_4B_WRITE 0x12 +#define SPI_FLASH_CMD_WRITE_ENABLE 0x06 +#define SPI_FLASH_CMD_WRITE_DISABLE 0x04 +#define SPI_FLASH_CMD_RD_STATUS_REG_1 0x05 + +// SPI command additional flags +#define SPI_CMD_FLAGS_NONE 0 +#define SPI_CMD_FLAGS_OP_MORE_CMDS (1 << 0) // More commands coming for operation +#define SPI_CMD_FLAGS_OP_MORE_DATA (1 << 1) // More data coming for operation + +// SPI Manual control reg fields +#define SPI_MAN_CTRL_LEN_SHIFT 0 +#define SPI_MAN_CTRL_CS_SHIFT 7 +#define SPI_MAN_CTRL_LAST_MASK ((U32)1 << 11) +#define SPI_MAN_CTRL_WRITE_OP_MASK ((U32)1 << 12) +#define SPI_MAN_CTRL_ATOMIC_OP_MASK ((U32)1 << 14) +#define SPI_MAN_CTRL_VALID_MASK ((U32)1 << 16) + +// Status register 1 +#define SPI_FLASH_REG_SR1_WRITE_IN_PROG (1 << 0) +#define SPI_FLASH_REG_SR1_WRITE_EN_LATCH (1 << 1) +#define SPI_FLASH_REG_SR1_BLOCK_PROT_0 (1 << 2) +#define SPI_FLASH_REG_SR1_BLOCK_PROT_1 (1 << 3) +#define SPI_FLASH_REG_SR1_BLOCK_PROT_2 (1 << 4) +#define SPI_FLASH_REG_SR1_ERASE_ERR (1 << 5) +#define SPI_FLASH_REG_SR1_PROG_ERR (1 << 6) +#define SPI_FLASH_REG_SR1_SR_WRITE_DIS (1 << 7) + + + + +/****************************************** + * SPI Flash Functions + *****************************************/ +PLX_STATUS +Spi_FlashPropGet( + PLX_DEVICE_OBJECT *PtrDev, + U8 ChipSel, + PEX_SPI_OBJ *PtrSpi + ); + +PLX_STATUS +Spi_Erase( + PLX_DEVICE_OBJECT *PtrDev, + PEX_SPI_OBJ *PtrSpi, + U32 StartOffset, + U8 BoolWaitComplete + ); + +PLX_STATUS +Spi_ReadBuffer( + PLX_DEVICE_OBJECT *PtrDev, + PEX_SPI_OBJ *PtrSpi, + U32 StartOffset, + U8 *PtrRxBuff, + U32 SizeRx + ); + +PLX_STATUS +Spi_WriteBuffer( + PLX_DEVICE_OBJECT *PtrDev, + PEX_SPI_OBJ *PtrSpi, + U32 StartOffset, + U8 *PtrTxBuff, + U32 SizeTx + ); + +PLX_STATUS +Spi_GetStatus( + PLX_DEVICE_OBJECT *PtrDev, + PEX_SPI_OBJ *PtrSpi + ); + + +/****************************************** + * Support Functions + *****************************************/ +PLX_STATUS +Spi_CmdSendAndReply( + PLX_DEVICE_OBJECT *PtrDev, + PEX_SPI_OBJ *PtrSpi, + U8 Flags, + U8 *PtrDataTx, + U32 SizeTx, + U8 *PtrDataRx, + U32 SizeRx + ); + +PLX_STATUS +Spi_WaitControllerReady( + PLX_DEVICE_OBJECT *PtrDev, + PEX_SPI_OBJ *PtrSpi + ); + + + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/Test/MainWindow.cpp b/Test/MainWindow.cpp index f32db8d..2b2f2dd 100755 --- a/Test/MainWindow.cpp +++ b/Test/MainWindow.cpp @@ -7,12 +7,11 @@ MainWindow::MainWindow(QWidget* parent) : QMainWindow(parent) , ui(new Ui::MainWindow) { -// system("sudo PlxSdk/Bin/Plx_load 9054 d"); -// system("echo jangal28 | sudo -S gedit"); - - ui->setupUi(this); connect(&_honaAPI, &HonaAPI::honaDataResult, this, &MainWindow::honaDataResultUi); +// ApiResult _resultInit = _honaAPI.init(); +// ApiResult _hsruStartResult = _honaAPI.hsruStart(); + } MainWindow::~MainWindow() @@ -24,56 +23,68 @@ MainWindow::~MainWindow() void MainWindow::honaDataResultUi(QList honaPacketList, quint32 hsruLoss, quint32 Doa) { QString _str; - for(auto i = 0; i < honaPacketList.length(); i++) + _str = QDateTime::currentDateTime().toString("hh:mm:ss.z") + "\nhonaPacketList size " + QString::number(honaPacketList.size()); + for(auto i = 0; i < qMin(10, honaPacketList.length()); i++) { - _str += "\n[hsruLoss] :" + QString::number(hsruLoss, 16); - _str += "\n[getToa] :" + QString::number(honaPacketList[i].getToa(), 16); - _str += "\n[getDoa] :" + QString::number(honaPacketList[i].getDoa(), 16); - _str += "\n[getPa1] :" + QString::number(honaPacketList[i].getPa1(), 16); - _str += "\n[getPa2] :" + QString::number(honaPacketList[i].getPa2(), 16); - _str += "\n[getPa3] :" + QString::number(honaPacketList[i].getPa3(), 16); - _str += "\n[getPa4] :" + QString::number(honaPacketList[i].getPa4(), 16); - _str += "\n[getCode] :" + QString::number(honaPacketList[i].getCode(), 16); - _str += "\n[getCodeL] :" + QString::number(honaPacketList[i].getCodeL(), 16); - _str += "\n[getCodeM] :" + QString::number(honaPacketList[i].getCodeM(), 16); + _str += "\n[PacketType] :" + QString::number(honaPacketList[i].getPacketType()); + _str += "\n[PacketNumber] :" + QString::number(honaPacketList[i].getPacketNumber()); + _str += "\n[Toa] :" + QString::number(honaPacketList[i].getToa()); + _str += "\n[Doa] :" + QString::number(honaPacketList[i].getDoa()); + _str += "\n[Pa1] :" + QString::number(honaPacketList[i].getPa1()); + _str += "\n[Pa2] :" + QString::number(honaPacketList[i].getPa2()); + _str += "\n[Pa3] :" + QString::number(honaPacketList[i].getPa3()); + _str += "\n[Pa4] :" + QString::number(honaPacketList[i].getPa4()); + _str += "\n[Code] :" + QString::number(honaPacketList[i].getCode(), 16); + _str += "\n[CodeL] :" + QString::number(honaPacketList[i].getCodeL(), 16); + _str += "\n[CodeM] :" + QString::number(honaPacketList[i].getCodeM(), 16); + _str += "\n[hsruLoss] :" + QString::number(hsruLoss); + _str += "\n[doa] :" + QString::number(Doa); } ui->dataFromMemory->setText(_str); + + qDebug() << QDateTime::currentDateTime().toString("hh:mm:ss.z") << " honaPacketList size "<< honaPacketList.size(); } -void MainWindow::on_testPLX_clicked() +QString resultString(ApiResult res){ + + switch (res) { + case ApiResult::success: + return "success"; + case ApiResult::alreadyStarted: + return "alreadyStarted"; + case ApiResult::busy: + return "busy"; + case ApiResult::error: + return "error"; + } + return ""; +}; + + +void MainWindow::on_startHsru_clicked() { + //******************************************************** ApiResult _resultInit = _honaAPI.init(); - ApiResult _hsruStartResult = _honaAPI.hsruStart(); + ui->errorMonitoring->setText("_resultInit: " + resultString(_resultInit)); //******************************************************** + ApiResult _hsruStartResult = _honaAPI.hsruStart(); QString temp = ui->errorMonitoring->text(); - if(_resultInit == ApiResult::error) - { - ui->errorMonitoring->setText(temp + "\n" + " Error _resultInit"); - } - else if(_resultInit == ApiResult::success) - { - ui->errorMonitoring->setText(temp + "\n" + "success _resultInit"); - } - //******************************************************** + ui->errorMonitoring->setText(temp + "\n _hsruStartResult: " + resultString(_hsruStartResult)); - if(_hsruStartResult == ApiResult::error) - { - ui->errorMonitoring->setText(temp + "\n" + " Error _hsruStartResult"); - } - else if(_hsruStartResult == ApiResult::success) - { - ui->errorMonitoring->setText(temp + "\n" + " success _hsruStartResult"); - } - //******************************************************** +} + +void MainWindow::on_resetDevice_clicked() +{ + + ApiResult _hsruStop = _honaAPI.deviceReset(); + ui->errorMonitoring->setText("deviceReset: " + resultString(_hsruStop)); } void MainWindow::on_stopHsru_clicked() { - QString temp = ui->errorMonitoring->text(); + ApiResult _hsruStop = _honaAPI.hsruStop(); - if(_hsruStop == ApiResult::error) - { - ui->errorMonitoring->setText(temp + "\n" + " success _hsruStartResult"); - } + ui->errorMonitoring->setText("hsruStop: " + resultString(_hsruStop)); + } diff --git a/Test/MainWindow.h b/Test/MainWindow.h index 363b537..add5b8d 100755 --- a/Test/MainWindow.h +++ b/Test/MainWindow.h @@ -28,7 +28,8 @@ public: //uncrustify off private slots: void honaDataResultUi(QList honaPacketList, quint32 hsruLoss, quint32 Doa); - void on_testPLX_clicked(); + void on_startHsru_clicked(); + void on_resetDevice_clicked(); void on_stopHsru_clicked(); //uncrustify on: diff --git a/Test/MainWindow.ui b/Test/MainWindow.ui index 3c00688..3e25f38 100755 --- a/Test/MainWindow.ui +++ b/Test/MainWindow.ui @@ -14,74 +14,53 @@ MainWindow - - - - 250 - 40 - 89 - 25 - - - - Test PLX - - - - - - 60 - 30 - 171 - 51 - - - - <html><head/><body><p align="center"><span style=" font-size:20pt;">Test PLX</span></p></body></html> - - - - - - 50 - 90 - 411 - 61 - - - - TextLabel - - - - - - 390 - 40 - 89 - 25 - - - - stopHsru - - - - - - 50 - 140 - 451 - 301 - - - - Qt::ScrollBarAlwaysOn - - - QAbstractScrollArea::AdjustToContentsOnFirstShow - - + + + + + resetDevice + + + + + + + Qt::ScrollBarAlwaysOn + + + QAbstractScrollArea::AdjustToContentsOnFirstShow + + + + + + + <html><head/><body><p align="center"><span style=" font-size:20pt;">Test PLX</span></p></body></html> + + + + + + + startHsru + + + + + + + TextLabel + + + + + + + stopHsru + + + + diff --git a/Test/Test.pro b/Test/Test.pro index 432718d..5cc32ed 100755 --- a/Test/Test.pro +++ b/Test/Test.pro @@ -36,13 +36,13 @@ else: unix:!android: target.path = /opt/$${TARGET}/bin !isEmpty(target.path): INSTALLS += target -unix:!macx: LIBS += -L$$PWD/../../Plxlibrary/Library/ -lPlxApi +unix:!macx: LIBS += -L$$PWD/../Plxlibrary/Library/ -lPlxApi -INCLUDEPATH += $$PWD/../../Plxlibrary/Library -DEPENDPATH += $$PWD/../../Plxlibrary/Library +INCLUDEPATH += $$PWD/../Plxlibrary/Library +DEPENDPATH += $$PWD/../Plxlibrary/Library -INCLUDEPATH += $$PWD/../../Plxlibrary -DEPENDPATH += $$PWD/../../Plxlibrary +INCLUDEPATH += $$PWD/../Plxlibrary +DEPENDPATH += $$PWD/../Plxlibrary -unix:!macx: PRE_TARGETDEPS += $$PWD/../../Plxlibrary/Library/libPlxApi.a +unix:!macx: PRE_TARGETDEPS += $$PWD/../Plxlibrary/Library/libPlxApi.a