add vdsl firmware loader/cutter
authorJohn Crispin <john@openwrt.org>
Thu, 14 Mar 2013 18:43:29 +0000 (18:43 +0000)
committerJohn Crispin <john@openwrt.org>
Thu, 14 Mar 2013 18:43:29 +0000 (18:43 +0000)
Signed-off-by: John Crispin <blogic@openwrt.org>
SVN-Revision: 36025

package/platform/lantiq/ltq-vdsl-fw/Makefile [new file with mode: 0644]
package/platform/lantiq/ltq-vdsl-fw/src/LzmaDecode.c [new file with mode: 0644]
package/platform/lantiq/ltq-vdsl-fw/src/LzmaDecode.h [new file with mode: 0644]
package/platform/lantiq/ltq-vdsl-fw/src/LzmaTypes.h [new file with mode: 0644]
package/platform/lantiq/ltq-vdsl-fw/src/LzmaWrapper.c [new file with mode: 0644]
package/platform/lantiq/ltq-vdsl-fw/src/LzmaWrapper.h [new file with mode: 0644]
package/platform/lantiq/ltq-vdsl-fw/src/Makefile [new file with mode: 0644]
package/platform/lantiq/ltq-vdsl-fw/src/vdsl_fw_install.sh [new file with mode: 0755]
package/platform/lantiq/ltq-vdsl-fw/src/w921v_fw_cutter.c [new file with mode: 0644]

diff --git a/package/platform/lantiq/ltq-vdsl-fw/Makefile b/package/platform/lantiq/ltq-vdsl-fw/Makefile
new file mode 100644 (file)
index 0000000..d4e0023
--- /dev/null
@@ -0,0 +1,40 @@
+# Copyright (C) 2012 OpenWrt.org
+#
+# This is free software, licensed under the GNU General Public License v2.
+# See /LICENSE for more information.
+
+include $(TOPDIR)/rules.mk
+
+PKG_NAME:=ltq-vdsl-fw
+PKG_VERSION:=1
+PKG_RELEASE:=1
+
+PKG_MAINTAINER:=John Crispin <blogic@openwrt.org>
+
+include $(INCLUDE_DIR)/package.mk
+
+define Package/ltq-vdsl-vr9-fw-installer
+  TITLE:=Firmware installer
+  SECTION:=net
+  CATEGORY:=Network
+  DEPENDS:=@TARGET_lantiq_xway +kmod-ltq-vdsl-vr9
+endef
+
+define Build/Prepare
+       $(INSTALL_DIR) $(PKG_BUILD_DIR)
+       $(CP) ./src/* $(PKG_BUILD_DIR)
+endef
+
+define Build/Compile
+       $(TARGET_CONFIGURE_OPTS) \
+               CFLAGS="$(TARGET_CFLAGS)" \
+               LDFLAGS="$(TARGET_LDFLAGS)" \
+               $(MAKE) -C $(PKG_BUILD_DIR)
+endef
+
+define Package/ltq-vdsl-vr9-fw-installer/install
+       $(INSTALL_DIR) $(1)/sbin
+       $(CP) $(PKG_BUILD_DIR)/w921v_fw_cutter $(PKG_BUILD_DIR)/vdsl_fw_install.sh $(1)/sbin/
+endef
+
+$(eval $(call BuildPackage,ltq-vdsl-vr9-fw-installer))
diff --git a/package/platform/lantiq/ltq-vdsl-fw/src/LzmaDecode.c b/package/platform/lantiq/ltq-vdsl-fw/src/LzmaDecode.c
new file mode 100644 (file)
index 0000000..cb83453
--- /dev/null
@@ -0,0 +1,584 @@
+/*
+  LzmaDecode.c
+  LZMA Decoder (optimized for Speed version)
+  
+  LZMA SDK 4.40 Copyright (c) 1999-2006 Igor Pavlov (2006-05-01)
+  http://www.7-zip.org/
+
+  LZMA SDK is licensed under two licenses:
+  1) GNU Lesser General Public License (GNU LGPL)
+  2) Common Public License (CPL)
+  It means that you can select one of these two licenses and 
+  follow rules of that license.
+
+  SPECIAL EXCEPTION:
+  Igor Pavlov, as the author of this Code, expressly permits you to 
+  statically or dynamically link your Code (or bind by name) to the 
+  interfaces of this file without subjecting your linked Code to the 
+  terms of the CPL or GNU LGPL. Any modifications or additions 
+  to this file, however, are subject to the LGPL or CPL terms.
+*/
+
+#include "LzmaDecode.h"
+
+#define kNumTopBits 24
+#define kTopValue ((UInt32)1 << kNumTopBits)
+
+#define kNumBitModelTotalBits 11
+#define kBitModelTotal (1 << kNumBitModelTotalBits)
+#define kNumMoveBits 5
+
+#define RC_READ_BYTE (*Buffer++)
+
+#define RC_INIT2 Code = 0; Range = 0xFFFFFFFF; \
+  { int i; for(i = 0; i < 5; i++) { RC_TEST; Code = (Code << 8) | RC_READ_BYTE; }}
+
+#ifdef _LZMA_IN_CB
+
+#define RC_TEST { if (Buffer == BufferLim) \
+  { SizeT size; int result = InCallback->Read(InCallback, &Buffer, &size); if (result != LZMA_RESULT_OK) return result; \
+  BufferLim = Buffer + size; if (size == 0) return LZMA_RESULT_DATA_ERROR; }}
+
+#define RC_INIT Buffer = BufferLim = 0; RC_INIT2
+
+#else
+
+#define RC_TEST { if (Buffer == BufferLim) return LZMA_RESULT_DATA_ERROR; }
+
+#define RC_INIT(buffer, bufferSize) Buffer = buffer; BufferLim = buffer + bufferSize; RC_INIT2
+#endif
+
+#define RC_NORMALIZE if (Range < kTopValue) { RC_TEST; Range <<= 8; Code = (Code << 8) | RC_READ_BYTE; }
+
+#define IfBit0(p) RC_NORMALIZE; bound = (Range >> kNumBitModelTotalBits) * *(p); if (Code < bound)
+#define UpdateBit0(p) Range = bound; *(p) += (kBitModelTotal - *(p)) >> kNumMoveBits;
+#define UpdateBit1(p) Range -= bound; Code -= bound; *(p) -= (*(p)) >> kNumMoveBits;
+
+#define RC_GET_BIT2(p, mi, A0, A1) IfBit0(p) \
+  { UpdateBit0(p); mi <<= 1; A0; } else \
+  { UpdateBit1(p); mi = (mi + mi) + 1; A1; } 
+  
+#define RC_GET_BIT(p, mi) RC_GET_BIT2(p, mi, ; , ;)               
+
+#define RangeDecoderBitTreeDecode(probs, numLevels, res) \
+  { int i = numLevels; res = 1; \
+  do { CProb *p = probs + res; RC_GET_BIT(p, res) } while(--i != 0); \
+  res -= (1 << numLevels); }
+
+
+#define kNumPosBitsMax 4
+#define kNumPosStatesMax (1 << kNumPosBitsMax)
+
+#define kLenNumLowBits 3
+#define kLenNumLowSymbols (1 << kLenNumLowBits)
+#define kLenNumMidBits 3
+#define kLenNumMidSymbols (1 << kLenNumMidBits)
+#define kLenNumHighBits 8
+#define kLenNumHighSymbols (1 << kLenNumHighBits)
+
+#define LenChoice 0
+#define LenChoice2 (LenChoice + 1)
+#define LenLow (LenChoice2 + 1)
+#define LenMid (LenLow + (kNumPosStatesMax << kLenNumLowBits))
+#define LenHigh (LenMid + (kNumPosStatesMax << kLenNumMidBits))
+#define kNumLenProbs (LenHigh + kLenNumHighSymbols) 
+
+
+#define kNumStates 12
+#define kNumLitStates 7
+
+#define kStartPosModelIndex 4
+#define kEndPosModelIndex 14
+#define kNumFullDistances (1 << (kEndPosModelIndex >> 1))
+
+#define kNumPosSlotBits 6
+#define kNumLenToPosStates 4
+
+#define kNumAlignBits 4
+#define kAlignTableSize (1 << kNumAlignBits)
+
+#define kMatchMinLen 2
+
+#define IsMatch 0
+#define IsRep (IsMatch + (kNumStates << kNumPosBitsMax))
+#define IsRepG0 (IsRep + kNumStates)
+#define IsRepG1 (IsRepG0 + kNumStates)
+#define IsRepG2 (IsRepG1 + kNumStates)
+#define IsRep0Long (IsRepG2 + kNumStates)
+#define PosSlot (IsRep0Long + (kNumStates << kNumPosBitsMax))
+#define SpecPos (PosSlot + (kNumLenToPosStates << kNumPosSlotBits))
+#define Align (SpecPos + kNumFullDistances - kEndPosModelIndex)
+#define LenCoder (Align + kAlignTableSize)
+#define RepLenCoder (LenCoder + kNumLenProbs)
+#define Literal (RepLenCoder + kNumLenProbs)
+
+#if Literal != LZMA_BASE_SIZE
+StopCompilingDueBUG
+#endif
+
+int LzmaDecodeProperties(CLzmaProperties *propsRes, const unsigned char *propsData, int size)
+{
+  unsigned char prop0;
+  if (size < LZMA_PROPERTIES_SIZE)
+    return LZMA_RESULT_DATA_ERROR;
+  prop0 = propsData[0];
+  if (prop0 >= (9 * 5 * 5))
+    return LZMA_RESULT_DATA_ERROR;
+  {
+    for (propsRes->pb = 0; prop0 >= (9 * 5); propsRes->pb++, prop0 -= (9 * 5));
+    for (propsRes->lp = 0; prop0 >= 9; propsRes->lp++, prop0 -= 9);
+    propsRes->lc = prop0;
+    /*
+    unsigned char remainder = (unsigned char)(prop0 / 9);
+    propsRes->lc = prop0 % 9;
+    propsRes->pb = remainder / 5;
+    propsRes->lp = remainder % 5;
+    */
+  }
+
+  #ifdef _LZMA_OUT_READ
+  {
+    int i;
+    propsRes->DictionarySize = 0;
+    for (i = 0; i < 4; i++)
+      propsRes->DictionarySize += (UInt32)(propsData[1 + i]) << (i * 8);
+    if (propsRes->DictionarySize == 0)
+      propsRes->DictionarySize = 1;
+  }
+  #endif
+  return LZMA_RESULT_OK;
+}
+
+#define kLzmaStreamWasFinishedId (-1)
+
+int LzmaDecode(CLzmaDecoderState *vs,
+    #ifdef _LZMA_IN_CB
+    ILzmaInCallback *InCallback,
+    #else
+    const unsigned char *inStream, SizeT inSize, SizeT *inSizeProcessed,
+    #endif
+    unsigned char *outStream, SizeT outSize, SizeT *outSizeProcessed)
+{
+  CProb *p = vs->Probs;
+  SizeT nowPos = 0;
+  Byte previousByte = 0;
+  UInt32 posStateMask = (1 << (vs->Properties.pb)) - 1;
+  UInt32 literalPosMask = (1 << (vs->Properties.lp)) - 1;
+  int lc = vs->Properties.lc;
+
+  #ifdef _LZMA_OUT_READ
+  
+  UInt32 Range = vs->Range;
+  UInt32 Code = vs->Code;
+  #ifdef _LZMA_IN_CB
+  const Byte *Buffer = vs->Buffer;
+  const Byte *BufferLim = vs->BufferLim;
+  #else
+  const Byte *Buffer = inStream;
+  const Byte *BufferLim = inStream + inSize;
+  #endif
+  int state = vs->State;
+  UInt32 rep0 = vs->Reps[0], rep1 = vs->Reps[1], rep2 = vs->Reps[2], rep3 = vs->Reps[3];
+  int len = vs->RemainLen;
+  UInt32 globalPos = vs->GlobalPos;
+  UInt32 distanceLimit = vs->DistanceLimit;
+
+  Byte *dictionary = vs->Dictionary;
+  UInt32 dictionarySize = vs->Properties.DictionarySize;
+  UInt32 dictionaryPos = vs->DictionaryPos;
+
+  Byte tempDictionary[4];
+
+  #ifndef _LZMA_IN_CB
+  *inSizeProcessed = 0;
+  #endif
+  *outSizeProcessed = 0;
+  if (len == kLzmaStreamWasFinishedId)
+    return LZMA_RESULT_OK;
+
+  if (dictionarySize == 0)
+  {
+    dictionary = tempDictionary;
+    dictionarySize = 1;
+    tempDictionary[0] = vs->TempDictionary[0];
+  }
+
+  if (len == kLzmaNeedInitId)
+  {
+    {
+      UInt32 numProbs = Literal + ((UInt32)LZMA_LIT_SIZE << (lc + vs->Properties.lp));
+      UInt32 i;
+      for (i = 0; i < numProbs; i++)
+        p[i] = kBitModelTotal >> 1; 
+      rep0 = rep1 = rep2 = rep3 = 1;
+      state = 0;
+      globalPos = 0;
+      distanceLimit = 0;
+      dictionaryPos = 0;
+      dictionary[dictionarySize - 1] = 0;
+      #ifdef _LZMA_IN_CB
+      RC_INIT;
+      #else
+      RC_INIT(inStream, inSize);
+      #endif
+    }
+    len = 0;
+  }
+  while(len != 0 && nowPos < outSize)
+  {
+    UInt32 pos = dictionaryPos - rep0;
+    if (pos >= dictionarySize)
+      pos += dictionarySize;
+    outStream[nowPos++] = dictionary[dictionaryPos] = dictionary[pos];
+    if (++dictionaryPos == dictionarySize)
+      dictionaryPos = 0;
+    len--;
+  }
+  if (dictionaryPos == 0)
+    previousByte = dictionary[dictionarySize - 1];
+  else
+    previousByte = dictionary[dictionaryPos - 1];
+
+  #else /* if !_LZMA_OUT_READ */
+
+  int state = 0;
+  UInt32 rep0 = 1, rep1 = 1, rep2 = 1, rep3 = 1;
+  int len = 0;
+  const Byte *Buffer;
+  const Byte *BufferLim;
+  UInt32 Range;
+  UInt32 Code;
+
+  #ifndef _LZMA_IN_CB
+  *inSizeProcessed = 0;
+  #endif
+  *outSizeProcessed = 0;
+
+  {
+    UInt32 i;
+    UInt32 numProbs = Literal + ((UInt32)LZMA_LIT_SIZE << (lc + vs->Properties.lp));
+    for (i = 0; i < numProbs; i++)
+      p[i] = kBitModelTotal >> 1;
+  }
+  
+  #ifdef _LZMA_IN_CB
+  RC_INIT;
+  #else
+  RC_INIT(inStream, inSize);
+  #endif
+
+  #endif /* _LZMA_OUT_READ */
+
+  while(nowPos < outSize)
+  {
+    CProb *prob;
+    UInt32 bound;
+    int posState = (int)(
+        (nowPos 
+        #ifdef _LZMA_OUT_READ
+        + globalPos
+        #endif
+        )
+        & posStateMask);
+
+    prob = p + IsMatch + (state << kNumPosBitsMax) + posState;
+    IfBit0(prob)
+    {
+      int symbol = 1;
+      UpdateBit0(prob)
+      prob = p + Literal + (LZMA_LIT_SIZE * 
+        (((
+        (nowPos 
+        #ifdef _LZMA_OUT_READ
+        + globalPos
+        #endif
+        )
+        & literalPosMask) << lc) + (previousByte >> (8 - lc))));
+
+      if (state >= kNumLitStates)
+      {
+        int matchByte;
+        #ifdef _LZMA_OUT_READ
+        UInt32 pos = dictionaryPos - rep0;
+        if (pos >= dictionarySize)
+          pos += dictionarySize;
+        matchByte = dictionary[pos];
+        #else
+        matchByte = outStream[nowPos - rep0];
+        #endif
+        do
+        {
+          int bit;
+          CProb *probLit;
+          matchByte <<= 1;
+          bit = (matchByte & 0x100);
+          probLit = prob + 0x100 + bit + symbol;
+          RC_GET_BIT2(probLit, symbol, if (bit != 0) break, if (bit == 0) break)
+        }
+        while (symbol < 0x100);
+      }
+      while (symbol < 0x100)
+      {
+        CProb *probLit = prob + symbol;
+        RC_GET_BIT(probLit, symbol)
+      }
+      previousByte = (Byte)symbol;
+
+      outStream[nowPos++] = previousByte;
+      #ifdef _LZMA_OUT_READ
+      if (distanceLimit < dictionarySize)
+        distanceLimit++;
+
+      dictionary[dictionaryPos] = previousByte;
+      if (++dictionaryPos == dictionarySize)
+        dictionaryPos = 0;
+      #endif
+      if (state < 4) state = 0;
+      else if (state < 10) state -= 3;
+      else state -= 6;
+    }
+    else             
+    {
+      UpdateBit1(prob);
+      prob = p + IsRep + state;
+      IfBit0(prob)
+      {
+        UpdateBit0(prob);
+        rep3 = rep2;
+        rep2 = rep1;
+        rep1 = rep0;
+        state = state < kNumLitStates ? 0 : 3;
+        prob = p + LenCoder;
+      }
+      else
+      {
+        UpdateBit1(prob);
+        prob = p + IsRepG0 + state;
+        IfBit0(prob)
+        {
+          UpdateBit0(prob);
+          prob = p + IsRep0Long + (state << kNumPosBitsMax) + posState;
+          IfBit0(prob)
+          {
+            #ifdef _LZMA_OUT_READ
+            UInt32 pos;
+            #endif
+            UpdateBit0(prob);
+            
+            #ifdef _LZMA_OUT_READ
+            if (distanceLimit == 0)
+            #else
+            if (nowPos == 0)
+            #endif
+              return LZMA_RESULT_DATA_ERROR;
+            
+            state = state < kNumLitStates ? 9 : 11;
+            #ifdef _LZMA_OUT_READ
+            pos = dictionaryPos - rep0;
+            if (pos >= dictionarySize)
+              pos += dictionarySize;
+            previousByte = dictionary[pos];
+            dictionary[dictionaryPos] = previousByte;
+            if (++dictionaryPos == dictionarySize)
+              dictionaryPos = 0;
+            #else
+            previousByte = outStream[nowPos - rep0];
+            #endif
+            outStream[nowPos++] = previousByte;
+            #ifdef _LZMA_OUT_READ
+            if (distanceLimit < dictionarySize)
+              distanceLimit++;
+            #endif
+
+            continue;
+          }
+          else
+          {
+            UpdateBit1(prob);
+          }
+        }
+        else
+        {
+          UInt32 distance;
+          UpdateBit1(prob);
+          prob = p + IsRepG1 + state;
+          IfBit0(prob)
+          {
+            UpdateBit0(prob);
+            distance = rep1;
+          }
+          else 
+          {
+            UpdateBit1(prob);
+            prob = p + IsRepG2 + state;
+            IfBit0(prob)
+            {
+              UpdateBit0(prob);
+              distance = rep2;
+            }
+            else
+            {
+              UpdateBit1(prob);
+              distance = rep3;
+              rep3 = rep2;
+            }
+            rep2 = rep1;
+          }
+          rep1 = rep0;
+          rep0 = distance;
+        }
+        state = state < kNumLitStates ? 8 : 11;
+        prob = p + RepLenCoder;
+      }
+      {
+        int numBits, offset;
+        CProb *probLen = prob + LenChoice;
+        IfBit0(probLen)
+        {
+          UpdateBit0(probLen);
+          probLen = prob + LenLow + (posState << kLenNumLowBits);
+          offset = 0;
+          numBits = kLenNumLowBits;
+        }
+        else
+        {
+          UpdateBit1(probLen);
+          probLen = prob + LenChoice2;
+          IfBit0(probLen)
+          {
+            UpdateBit0(probLen);
+            probLen = prob + LenMid + (posState << kLenNumMidBits);
+            offset = kLenNumLowSymbols;
+            numBits = kLenNumMidBits;
+          }
+          else
+          {
+            UpdateBit1(probLen);
+            probLen = prob + LenHigh;
+            offset = kLenNumLowSymbols + kLenNumMidSymbols;
+            numBits = kLenNumHighBits;
+          }
+        }
+        RangeDecoderBitTreeDecode(probLen, numBits, len);
+        len += offset;
+      }
+
+      if (state < 4)
+      {
+        int posSlot;
+        state += kNumLitStates;
+        prob = p + PosSlot +
+            ((len < kNumLenToPosStates ? len : kNumLenToPosStates - 1) << 
+            kNumPosSlotBits);
+        RangeDecoderBitTreeDecode(prob, kNumPosSlotBits, posSlot);
+        if (posSlot >= kStartPosModelIndex)
+        {
+          int numDirectBits = ((posSlot >> 1) - 1);
+          rep0 = (2 | ((UInt32)posSlot & 1));
+          if (posSlot < kEndPosModelIndex)
+          {
+            rep0 <<= numDirectBits;
+            prob = p + SpecPos + rep0 - posSlot - 1;
+          }
+          else
+          {
+            numDirectBits -= kNumAlignBits;
+            do
+            {
+              RC_NORMALIZE
+              Range >>= 1;
+              rep0 <<= 1;
+              if (Code >= Range)
+              {
+                Code -= Range;
+                rep0 |= 1;
+              }
+            }
+            while (--numDirectBits != 0);
+            prob = p + Align;
+            rep0 <<= kNumAlignBits;
+            numDirectBits = kNumAlignBits;
+          }
+          {
+            int i = 1;
+            int mi = 1;
+            do
+            {
+              CProb *prob3 = prob + mi;
+              RC_GET_BIT2(prob3, mi, ; , rep0 |= i);
+              i <<= 1;
+            }
+            while(--numDirectBits != 0);
+          }
+        }
+        else
+          rep0 = posSlot;
+        if (++rep0 == (UInt32)(0))
+        {
+          /* it's for stream version */
+          len = kLzmaStreamWasFinishedId;
+          break;
+        }
+      }
+
+      len += kMatchMinLen;
+      #ifdef _LZMA_OUT_READ
+      if (rep0 > distanceLimit) 
+      #else
+      if (rep0 > nowPos)
+      #endif
+        return LZMA_RESULT_DATA_ERROR;
+
+      #ifdef _LZMA_OUT_READ
+      if (dictionarySize - distanceLimit > (UInt32)len)
+        distanceLimit += len;
+      else
+        distanceLimit = dictionarySize;
+      #endif
+
+      do
+      {
+        #ifdef _LZMA_OUT_READ
+        UInt32 pos = dictionaryPos - rep0;
+        if (pos >= dictionarySize)
+          pos += dictionarySize;
+        previousByte = dictionary[pos];
+        dictionary[dictionaryPos] = previousByte;
+        if (++dictionaryPos == dictionarySize)
+          dictionaryPos = 0;
+        #else
+        previousByte = outStream[nowPos - rep0];
+        #endif
+        len--;
+        outStream[nowPos++] = previousByte;
+      }
+      while(len != 0 && nowPos < outSize);
+    }
+  }
+  RC_NORMALIZE;
+
+  #ifdef _LZMA_OUT_READ
+  vs->Range = Range;
+  vs->Code = Code;
+  vs->DictionaryPos = dictionaryPos;
+  vs->GlobalPos = globalPos + (UInt32)nowPos;
+  vs->DistanceLimit = distanceLimit;
+  vs->Reps[0] = rep0;
+  vs->Reps[1] = rep1;
+  vs->Reps[2] = rep2;
+  vs->Reps[3] = rep3;
+  vs->State = state;
+  vs->RemainLen = len;
+  vs->TempDictionary[0] = tempDictionary[0];
+  #endif
+
+  #ifdef _LZMA_IN_CB
+  vs->Buffer = Buffer;
+  vs->BufferLim = BufferLim;
+  #else
+  *inSizeProcessed = (SizeT)(Buffer - inStream);
+  #endif
+  *outSizeProcessed = nowPos;
+  return LZMA_RESULT_OK;
+}
diff --git a/package/platform/lantiq/ltq-vdsl-fw/src/LzmaDecode.h b/package/platform/lantiq/ltq-vdsl-fw/src/LzmaDecode.h
new file mode 100644 (file)
index 0000000..2870eeb
--- /dev/null
@@ -0,0 +1,113 @@
+/* 
+  LzmaDecode.h
+  LZMA Decoder interface
+
+  LZMA SDK 4.40 Copyright (c) 1999-2006 Igor Pavlov (2006-05-01)
+  http://www.7-zip.org/
+
+  LZMA SDK is licensed under two licenses:
+  1) GNU Lesser General Public License (GNU LGPL)
+  2) Common Public License (CPL)
+  It means that you can select one of these two licenses and 
+  follow rules of that license.
+
+  SPECIAL EXCEPTION:
+  Igor Pavlov, as the author of this code, expressly permits you to 
+  statically or dynamically link your code (or bind by name) to the 
+  interfaces of this file without subjecting your linked code to the 
+  terms of the CPL or GNU LGPL. Any modifications or additions 
+  to this file, however, are subject to the LGPL or CPL terms.
+*/
+
+#ifndef __LZMADECODE_H
+#define __LZMADECODE_H
+
+#include "LzmaTypes.h"
+
+/* #define _LZMA_IN_CB */
+/* Use callback for input data */
+
+/* #define _LZMA_OUT_READ */
+/* Use read function for output data */
+
+/* #define _LZMA_PROB32 */
+/* It can increase speed on some 32-bit CPUs, 
+   but memory usage will be doubled in that case */
+
+/* #define _LZMA_LOC_OPT */
+/* Enable local speed optimizations inside code */
+
+#ifdef _LZMA_PROB32
+#define CProb UInt32
+#else
+#define CProb UInt16
+#endif
+
+#define LZMA_RESULT_OK 0
+#define LZMA_RESULT_DATA_ERROR 1
+
+#ifdef _LZMA_IN_CB
+typedef struct _ILzmaInCallback
+{
+  int (*Read)(void *object, const unsigned char **buffer, SizeT *bufferSize);
+} ILzmaInCallback;
+#endif
+
+#define LZMA_BASE_SIZE 1846
+#define LZMA_LIT_SIZE 768
+
+#define LZMA_PROPERTIES_SIZE 5
+
+typedef struct _CLzmaProperties
+{
+  int lc;
+  int lp;
+  int pb;
+  #ifdef _LZMA_OUT_READ
+  UInt32 DictionarySize;
+  #endif
+}CLzmaProperties;
+
+int LzmaDecodeProperties(CLzmaProperties *propsRes, const unsigned char *propsData, int size);
+
+#define LzmaGetNumProbs(Properties) (LZMA_BASE_SIZE + (LZMA_LIT_SIZE << ((Properties)->lc + (Properties)->lp)))
+
+#define kLzmaNeedInitId (-2)
+
+typedef struct _CLzmaDecoderState
+{
+  CLzmaProperties Properties;
+  CProb *Probs;
+
+  #ifdef _LZMA_IN_CB
+  const unsigned char *Buffer;
+  const unsigned char *BufferLim;
+  #endif
+
+  #ifdef _LZMA_OUT_READ
+  unsigned char *Dictionary;
+  UInt32 Range;
+  UInt32 Code;
+  UInt32 DictionaryPos;
+  UInt32 GlobalPos;
+  UInt32 DistanceLimit;
+  UInt32 Reps[4];
+  int State;
+  int RemainLen;
+  unsigned char TempDictionary[4];
+  #endif
+} CLzmaDecoderState;
+
+#ifdef _LZMA_OUT_READ
+#define LzmaDecoderInit(vs) { (vs)->RemainLen = kLzmaNeedInitId; }
+#endif
+
+int LzmaDecode(CLzmaDecoderState *vs,
+    #ifdef _LZMA_IN_CB
+    ILzmaInCallback *inCallback,
+    #else
+    const unsigned char *inStream, SizeT inSize, SizeT *inSizeProcessed,
+    #endif
+    unsigned char *outStream, SizeT outSize, SizeT *outSizeProcessed);
+
+#endif
diff --git a/package/platform/lantiq/ltq-vdsl-fw/src/LzmaTypes.h b/package/platform/lantiq/ltq-vdsl-fw/src/LzmaTypes.h
new file mode 100644 (file)
index 0000000..9c27290
--- /dev/null
@@ -0,0 +1,45 @@
+/* 
+LzmaTypes.h 
+
+Types for LZMA Decoder
+
+This file written and distributed to public domain by Igor Pavlov.
+This file is part of LZMA SDK 4.40 (2006-05-01)
+*/
+
+#ifndef __LZMATYPES_H
+#define __LZMATYPES_H
+
+#ifndef _7ZIP_BYTE_DEFINED
+#define _7ZIP_BYTE_DEFINED
+typedef unsigned char Byte;
+#endif 
+
+#ifndef _7ZIP_UINT16_DEFINED
+#define _7ZIP_UINT16_DEFINED
+typedef unsigned short UInt16;
+#endif 
+
+#ifndef _7ZIP_UINT32_DEFINED
+#define _7ZIP_UINT32_DEFINED
+#ifdef _LZMA_UINT32_IS_ULONG
+typedef unsigned long UInt32;
+#else
+typedef unsigned int UInt32;
+#endif
+#endif 
+
+/* #define _LZMA_NO_SYSTEM_SIZE_T */
+/* You can use it, if you don't want <stddef.h> */
+
+#ifndef _7ZIP_SIZET_DEFINED
+#define _7ZIP_SIZET_DEFINED
+#ifdef _LZMA_NO_SYSTEM_SIZE_T
+typedef UInt32 SizeT;
+#else
+#include <stddef.h>
+typedef size_t SizeT;
+#endif
+#endif
+
+#endif
diff --git a/package/platform/lantiq/ltq-vdsl-fw/src/LzmaWrapper.c b/package/platform/lantiq/ltq-vdsl-fw/src/LzmaWrapper.c
new file mode 100644 (file)
index 0000000..7dce056
--- /dev/null
@@ -0,0 +1,206 @@
+/******************************************************************************
+**
+** FILE NAME    : LzmaWrapper.c
+** PROJECT      : bootloader
+** MODULES      : U-boot
+**
+** DATE         : 2 Nov 2006
+** AUTHOR       : Lin Mars
+** DESCRIPTION  : LZMA decoder support for U-boot 1.1.5
+** COPYRIGHT    :       Copyright (c) 2006
+**                      Infineon Technologies AG
+**                      Am Campeon 1-12, 85579 Neubiberg, Germany
+**
+**    This program is free software; you can redistribute it and/or modify
+**    it under the terms of the GNU General Public License as published by
+**    the Free Software Foundation; either version 2 of the License, or
+**    (at your option) any later version.
+**
+** HISTORY
+** $Date        $Author         $Comment
+** 2 Nov 2006   Lin Mars        init version which derived from LzmaTest.c from
+**                              LZMA v4.43 SDK
+** 24 May 2007 Lin Mars        Fix issue for multiple lzma_inflate involved
+*******************************************************************************/
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "LzmaDecode.h"
+#include "LzmaWrapper.h"
+
+#if defined(DEBUG_ENABLE_BOOTSTRAP_PRINTF) || !defined(CFG_BOOTSTRAP_CODE)
+static const char *kCantReadMessage = "Can not read from source buffer";
+static const char *kCantAllocateMessage = "Not enough buffer for decompression";
+#endif
+
+static size_t rpos=0, dpos=0;
+
+static int MyReadFileAndCheck(unsigned char *src, void *dest, size_t size)
+{
+  if (size == 0)
+    return 0;
+  memcpy(dest, src + rpos, size);
+  rpos += size;
+  return 1;
+}
+
+int lzma_inflate(unsigned char *source, int s_len, unsigned char *dest, int *d_len)
+{
+  /* We use two 32-bit integers to construct 64-bit integer for file size.
+     You can remove outSizeHigh, if you don't need >= 4GB supporting,
+     or you can use UInt64 outSize, if your compiler supports 64-bit integers*/
+  UInt32 outSize = 0;
+  UInt32 outSizeHigh = 0;
+  SizeT outSizeFull;
+  unsigned char *outStream;
+  
+  int waitEOS = 1; 
+  /* waitEOS = 1, if there is no uncompressed size in headers, 
+   so decoder will wait EOS (End of Stream Marker) in compressed stream */
+
+  SizeT compressedSize;
+  unsigned char *inStream;
+
+  CLzmaDecoderState state;  /* it's about 24-80 bytes structure, if int is 32-bit */
+  unsigned char properties[LZMA_PROPERTIES_SIZE];
+
+  int res;
+
+  rpos=0; dpos=0;
+
+  if (sizeof(UInt32) < 4)
+  {
+#if defined(DEBUG_ENABLE_BOOTSTRAP_PRINTF) || !defined(CFG_BOOTSTRAP_CODE)
+    printf("LZMA decoder needs correct UInt32\n");
+#endif
+    return LZMA_RESULT_DATA_ERROR;
+  }
+
+  {
+    long length=s_len;
+    if ((long)(SizeT)length != length)
+    {
+#if defined(DEBUG_ENABLE_BOOTSTRAP_PRINTF) || !defined(CFG_BOOTSTRAP_CODE)
+      printf("Too big compressed stream\n");
+#endif
+      return LZMA_RESULT_DATA_ERROR;
+    }
+    compressedSize = (SizeT)(length - (LZMA_PROPERTIES_SIZE + 8));
+  }
+
+  /* Read LZMA properties for compressed stream */
+
+  if (!MyReadFileAndCheck(source, properties, sizeof(properties)))
+  {
+#if defined(DEBUG_ENABLE_BOOTSTRAP_PRINTF) || !defined(CFG_BOOTSTRAP_CODE)
+    printf("%s\n", kCantReadMessage);
+#endif
+    return LZMA_RESULT_DATA_ERROR;
+  }
+
+  /* Read uncompressed size */
+  {
+    int i;
+    for (i = 0; i < 8; i++)
+    {
+      unsigned char b;
+      if (!MyReadFileAndCheck(source, &b, 1))
+      {
+#if defined(DEBUG_ENABLE_BOOTSTRAP_PRINTF) || !defined(CFG_BOOTSTRAP_CODE)
+        printf("%s\n", kCantReadMessage);
+#endif
+        return LZMA_RESULT_DATA_ERROR;
+      }
+      if (b != 0xFF)
+        waitEOS = 0;
+      if (i < 4)
+        outSize += (UInt32)(b) << (i * 8);
+      else
+        outSizeHigh += (UInt32)(b) << ((i - 4) * 8);
+    }
+    
+    if (waitEOS)
+    {
+#if defined(DEBUG_ENABLE_BOOTSTRAP_PRINTF) || !defined(CFG_BOOTSTRAP_CODE)
+      printf("Stream with EOS marker is not supported");
+#endif
+      return LZMA_RESULT_DATA_ERROR;
+    }
+    outSizeFull = (SizeT)outSize;
+    if (sizeof(SizeT) >= 8)
+      outSizeFull |= (((SizeT)outSizeHigh << 16) << 16);
+    else if (outSizeHigh != 0 || (UInt32)(SizeT)outSize != outSize)
+    {
+#if defined(DEBUG_ENABLE_BOOTSTRAP_PRINTF) || !defined(CFG_BOOTSTRAP_CODE)
+      printf("Too big uncompressed stream");
+#endif
+      return LZMA_RESULT_DATA_ERROR;
+    }
+  }
+
+  /* Decode LZMA properties and allocate memory */
+  if (LzmaDecodeProperties(&state.Properties, properties, LZMA_PROPERTIES_SIZE) != LZMA_RESULT_OK)
+  {
+#if defined(DEBUG_ENABLE_BOOTSTRAP_PRINTF) || !defined(CFG_BOOTSTRAP_CODE)
+    printf("Incorrect stream properties");
+#endif
+    return LZMA_RESULT_DATA_ERROR;
+  }
+  state.Probs = (CProb *)malloc(LzmaGetNumProbs(&state.Properties) * sizeof(CProb));
+
+  if (outSizeFull == 0)
+    outStream = 0;
+  else
+  {
+    if (outSizeFull > d_len)
+      outStream = 0;
+    else
+      outStream = dest;
+  }
+
+  if (compressedSize == 0)
+    inStream = 0;
+  else
+  {
+    if ((compressedSize+rpos) > s_len )
+      inStream = 0;
+    else
+      inStream = source + rpos;
+  }
+
+  if (state.Probs == 0 
+    || (outStream == 0 && outSizeFull != 0)
+    || (inStream == 0 && compressedSize != 0)
+    )
+  {
+    free(state.Probs);
+#if defined(DEBUG_ENABLE_BOOTSTRAP_PRINTF) || !defined(CFG_BOOTSTRAP_CODE)
+    printf("%s\n", kCantAllocateMessage);
+#endif
+    return LZMA_RESULT_DATA_ERROR;
+  }
+
+  /* Decompress */
+  {
+    SizeT inProcessed;
+    SizeT outProcessed;
+    res = LzmaDecode(&state,
+      inStream, compressedSize, &inProcessed,
+      outStream, outSizeFull, &outProcessed);
+    if (res != 0)
+    {
+#if defined(DEBUG_ENABLE_BOOTSTRAP_PRINTF) || !defined(CFG_BOOTSTRAP_CODE)
+      printf("\nDecoding error = %d\n", res);
+#endif
+      res = 1;
+    }
+    else
+    {
+      *d_len = outProcessed;
+    }
+  }
+
+  free(state.Probs);
+  return res;
+}
diff --git a/package/platform/lantiq/ltq-vdsl-fw/src/LzmaWrapper.h b/package/platform/lantiq/ltq-vdsl-fw/src/LzmaWrapper.h
new file mode 100644 (file)
index 0000000..2f9a3ff
--- /dev/null
@@ -0,0 +1,36 @@
+/******************************************************************************
+**
+** FILE NAME    : LzmaWrapper.h
+** PROJECT      : bootloader
+** MODULES      : U-boot
+**
+** DATE         : 2 Nov 2006
+** AUTHOR       : Lin Mars
+** DESCRIPTION  : LZMA decoder support for U-boot 1.1.5
+** COPYRIGHT    :       Copyright (c) 2006
+**                      Infineon Technologies AG
+**                      Am Campeon 1-12, 85579 Neubiberg, Germany
+**
+**    This program is free software; you can redistribute it and/or modify
+**    it under the terms of the GNU General Public License as published by
+**    the Free Software Foundation; either version 2 of the License, or
+**    (at your option) any later version.
+**
+** HISTORY
+** $Date        $Author         $Comment
+** 2 Nov 2006   Lin Mars        init version which derived from LzmaTest.c from
+**                              LZMA v4.43 SDK
+*******************************************************************************/
+#ifndef  __LZMA_WRAPPER_H__
+#define  __LZMA_WRAPPER_H__
+
+#ifndef LZMA_RESULT_OK
+#define LZMA_RESULT_OK 0
+#endif
+#ifndef LZMA_RESULT_DATA_ERROR
+#define LZMA_RESULT_DATA_ERROR 1
+#endif
+
+extern int lzma_inflate(unsigned char *source, int s_len, unsigned char *dest, int *d_len);
+
+#endif /*__LZMA_WRAPPER_H__*/
diff --git a/package/platform/lantiq/ltq-vdsl-fw/src/Makefile b/package/platform/lantiq/ltq-vdsl-fw/src/Makefile
new file mode 100644 (file)
index 0000000..2d50aaf
--- /dev/null
@@ -0,0 +1,13 @@
+PROG=w921v_fw_cutter
+OBJS=w921v_fw_cutter.c LzmaDecode.c LzmaWrapper.c
+
+all: $(PROG) 
+
+$(PROG): $(OBJS)
+       $(CC) $(CFLAGS) $(LDFLAGS) $^ -o $@
+
+clean:
+       rm *.o $(PROG)
+
+%.o: %.c
+       $(CC) $(CFLAGS) -c $^ -o $@
diff --git a/package/platform/lantiq/ltq-vdsl-fw/src/vdsl_fw_install.sh b/package/platform/lantiq/ltq-vdsl-fw/src/vdsl_fw_install.sh
new file mode 100755 (executable)
index 0000000..4d40756
--- /dev/null
@@ -0,0 +1,48 @@
+#!/bin/sh
+
+FW="/tmp/Firmware_Speedport_W921V_1.20.000.bin"
+URL="http://hilfe.telekom.de/dlp/eki/downloads/Speedport/Speedport%20W%20921V/Firmware_Speedport_W921V_1.20.000.bin"
+FW_TAPI="/tmp/vr9_tapi_fw.bin"
+FW_DSL="/tmp/vr9_dsl_fw_annex_b.bin"
+FW_TGZ="/tmp/vr9_fw.tgz"
+MD5_FW="4d812f2c3476dadd738b022c4767c491"
+MD5_TAPI="06b6ab3481b8d3eb7e8bf6131f7f6b7f"
+MD5_DSL="59dd9dc81195c6854433c691b163f757"
+
+[ -f /lib/firmware/vdsl.bin] && exit 0
+
+[ -z "$1" ] || URL=$1
+
+[ -f "${FW}" ] || {
+       echo "${FW} does not exist. Try to Download it ? (y/N)"
+       read -n 1 R
+       echo ""
+       [ "$R" = "y" ] || {
+               echo "Please manually download the firmware from ${URL} and copy the file to ${FW}"
+               exit 1
+       }
+       echo "Download w921v Firmware"
+       wget "${URL}" -O "${FW}"
+       [ $? -eq 0 -a -f "${FW}" ] || exit 1
+}
+
+F=`md5sum -b ${FW} | cut -d" " -f1`
+[ "$F" = "${MD5_FW}" ] || {
+       echo "Failed to verify Firmware MD5"
+       exit 1
+}
+
+echo "Unpack and decompress w921v Firmware"
+w921v_fw_cutter
+[ $? -eq 0 ] || exit 1
+
+T=`md5sum -b ${FW_TAPI} | cut -d" " -f1`
+D=`md5sum -b ${FW_DSL} | cut -d" " -f1`
+
+[ "$T" = "${MD5_TAPI}" -a "$D" = "${MD5_DSL}" ] || {
+       echo "Failed to verify MD5"
+       exit 1
+}
+
+cp ${FW_TAPI} ${FW_DSL} /lib/firmware/
+ln -s /lib/firmware/vr9_dsl_fw_annex_b.bin /lib/firmware/vdsl.bin
diff --git a/package/platform/lantiq/ltq-vdsl-fw/src/w921v_fw_cutter.c b/package/platform/lantiq/ltq-vdsl-fw/src/w921v_fw_cutter.c
new file mode 100644 (file)
index 0000000..b26c91e
--- /dev/null
@@ -0,0 +1,164 @@
+/*
+ *   This program is free software; you can redistribute it and/or modify
+ *   it under the terms of the GNU General Public License as published by
+ *   the Free Software Foundation; version 2 of the License
+ *
+ *   This program is distributed in the hope that it will be useful,
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *   GNU General Public License for more details.
+ *
+ *   You should have received a copy of the GNU General Public License
+ *   along with this program; if not, write to the Free Software
+ *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
+ *
+ *   Copyright (C) 2012 John Crispin <blogic@openwrt.org>
+ */
+
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <unistd.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include <errno.h>
+#include <fcntl.h>
+
+#include "LzmaWrapper.h"
+
+#define FW_NAME                "/tmp/Firmware_Speedport_W921V_1.20.000.bin"
+
+#define MAGIC          0x50
+#define MAGIC_SZ       0x3FFC00
+#if __BYTE_ORDER == __LITTLE_ENDIAN
+#define MAGIC_PART     0x12345678
+#define MAGIC_LZMA     0x8000005D
+#define MAGIC_ANNEX_B  0x3C
+#define MAGIC_TAPI     0x5A
+#else
+#define MAGIC_PART     0x78563412
+#define MAGIC_LZMA     0x5D000080
+#define MAGIC_ANNEX_B  0x3C000000
+#define MAGIC_TAPI     0x5A000000
+#endif
+
+
+const char* part_type(u_int32_t id)
+{
+       switch(id) {
+       case MAGIC_ANNEX_B:
+               return "/tmp/vr9_dsl_fw_annex_b.bin";
+       case MAGIC_TAPI:
+               return "/tmp/vr9_tapi_fw.bin";
+       }
+       printf("\tUnknown lzma type 0x%02X\n", id);
+       return "/tmp/unknown.lzma";
+}
+
+int main(int argc, char **argv)
+{
+       struct stat s;
+       u_int8_t *buf_orig;
+       u_int32_t *buf;
+       int buflen;
+       int fd;
+       int i;
+       int err;
+       int start = 0, end = 0;
+
+       printf("Arcadyan Firmware cutter v0.1\n");
+       printf("-----------------------------\n");
+       printf("This tool extracts the different parts of an arcadyan firmware update file\n");
+       printf("This tool is for private use only. The Firmware that gets extracted has a license that forbids redistribution\n");
+       printf("Please only run this if you understand the risks\n\n");
+       printf("I understand the risks ? (y/N)\n");
+
+       if (getchar() != 'y')
+               return -1;
+
+       if (stat(FW_NAME, &s) != 0) {
+               printf("Failed to find %s\n", FW_NAME);
+               printf("Ask Google or try http://hilfe.telekom.de/dlp/eki/downloads/Speedport/Speedport%20W%20921V/Firmware_Speedport_W921V_1.20.000.bin\n");
+               return -1;
+       }
+
+       buf_orig = malloc(s.st_size);
+       if (!buf_orig) {
+               printf("Failed to alloc %d bytes\n", s.st_size);
+               return -1;
+       }
+
+       fd = open(FW_NAME, O_RDONLY);
+       if (fd < 0) {
+               printf("Unable to open %s\n", FW_NAME);
+               return -1;
+       }
+
+       buflen = read(fd, buf_orig, s.st_size);
+       close(fd);
+       if (buflen != s.st_size) {
+               printf("Loaded %d instead of %d bytes inside %s\n", buflen, s.st_size, FW_NAME);
+               return -1;
+       }
+
+       /* <magic> */
+       buf_orig++;
+       buflen -= 1;
+       for (i = 0; i < MAGIC_SZ; i++) {
+               if ((i % 16) < 3)
+                       buf_orig[i] = buf_orig[i + 16] ^ MAGIC;
+               else
+                       buf_orig[i] = buf_orig[i] ^ MAGIC;
+       }
+       buflen -= 3;
+       memmove(&buf_orig[MAGIC_SZ], &buf_orig[MAGIC_SZ + 3], buflen - MAGIC_SZ);
+       /* </magic> */
+
+       buf = (u_int32_t*) buf_orig;
+
+       do {
+               if (buf[end] == MAGIC_PART) {
+                       end += 2;
+                       printf("Found partition at 0x%08X with size %d\n",
+                               start * sizeof(u_int32_t),
+                               (end - start) * sizeof(u_int32_t));
+                       if (buf[start] == MAGIC_LZMA) {
+                               int dest_len = 1024 * 1024;
+                               int len = buf[end - 3];
+                               u_int32_t id = buf[end - 6];
+                               const char *type = part_type(id);
+                               u_int8_t *dest;
+
+                               dest = malloc(dest_len);
+                               if (!dest) {
+                                       printf("Failed to alloc dest buffer\n");
+                                       return -1;
+                               }
+
+                               if (lzma_inflate((u_int8_t*)&buf[start], len, dest, &dest_len)) {
+                                       printf("Failed to decompress data\n");
+                                       return -1;
+                               }
+
+                               fd = creat(type, S_IRUSR | S_IWUSR);
+                               if (fd != -1) {
+                                       if (write(fd, dest, dest_len) != dest_len)
+                                               printf("\tFailed to write %d bytes\n", dest_len);
+                                       else
+                                               printf("\tWrote %d bytes to %s\n", dest_len, type);
+                                       close(fd);
+                               } else {
+                                       printf("\tFailed to open %s\n", type);
+                               }
+                               free(dest);
+                       } else {
+                               printf("\tThis is not lzma\n");
+                       }
+                       start = end;
+               } else {
+                       end++;
+               }
+       } while(end < buflen / sizeof(u_int32_t));
+
+       return 0;
+}