#include "cpswhaleswitchprivate.h"

int cpswHalEswitchTestPdspRam(halDevice_s *HalDev,char *name,bit32u base,bit32u size)
  {
  int sts,LocalDebugFlag=(HalDev->debug&(1<<30));

  dbgprint(1<<30,"cpswHalEswitchTestPdspRam Base: %08x, Size: %d\n",base,size);
  dbgprint(1<<30,"%s Basic Memory Data Test ",name);
  sts=cpswHalUtlMemBasicDataTest(base);
  dbgprint(1<<30,"%s\n",(sts)?"Failed!":"Passed.");
  if (sts)
    {
    if (!LocalDebugFlag) HalDev->OsFunc->Printf("\n%s Basic Memory Data Test Failed\n",name);
    HalDev->OsFunc->Printf("  Bad data bits = %08x\n",sts);
    return(1);
    }

  dbgprint(1<<30,"%s Memory Address Test ",name);
  sts=cpswHalUtlMemAddressTest(base,size);
  dbgprint(1<<30,"%s\n",(sts)?"Failed!":"Passed.");
  if (sts)
    {
    if (!LocalDebugFlag) HalDev->OsFunc->Printf("\n%s Memory Address Test Failed\n",name);
    HalDev->OsFunc->Printf("  Bad data bits = %08x\n",sts);
    return(1);
    }

  dbgprint(1<<30,"%s Memory Data Test ",name);
  sts=cpswHalUtlMemDataTest(base,size,1);
  dbgprint(1<<30,"%s\n",(sts)?"Failed!":"Passed.");
  if (sts)
    {
    if (!LocalDebugFlag) HalDev->OsFunc->Printf("\n%s Memory Data Test Failed\n",name);
    HalDev->OsFunc->Printf("  Bad data bits = %08x\n",sts);
    return(1);
    }
  cpswHalUtlmemset((void*)base,0,size);
  return(0);
  }

#include "cpswhaleswitchpdspcode.h"

int cpswHalEswitchPdspLoad(halDevice_s *HalDev)
  {
  bit32u *PdspMemPtr=(bit32u*)PDSP_IMEM_BASE;
  unsigned long *PdspCodePtr=PDSPcode;
  int LoadSize;
  bit32u LoadVersion;

  dbgprint(1<<29,"PdspLoad\n");

  *PdspMemPtr++=0;  /*Stop PDSP                                              */
  PdspCodePtr++;

  LoadSize=PdspCodePtr[0];
  LoadVersion=PdspCodePtr[1];

  dbgprint(1<<29,"  Size: %0d\n",LoadSize);
  dbgprint(1<<29,"  Version: %0d\n",LoadVersion);

  if (!PDSP_SCRATCHPADRAM)
    {
    HalDev->OsFunc->Printf("ERROR: PDSP ScratchPad Base not set yet!\n");
    return(1);
    }

  PDSP_COMMAND=MIPS_PING_PDSP;  /*Throw a junk command to see if PDSP is alive*/
  PDSP_STATUS =MIPS_PING_PDSP;

  while(LoadSize--) *PdspMemPtr++=*PdspCodePtr++;

  dbgprint(1<<29,"  Start\n");

  PDSP_IMEM_CTL=3;

  dbgprint(1<<29,"  Check\n");

  cpswHalUtlClockWait(HalDev->ResetBase,64);
  if ((PDSP_COMMAND!=0)||(PDSP_STATUS!=0))
    {
    HalDev->OsFunc->Printf("ERROR: PDSP not operational!\n");
    return(1);
    }

  dbgprint(1<<29,"  Complete\n");

  return(0);
  }

int cpswHalEswitchPdspCmdRamTest(halDevice_s *HalDev,bit32u base, bit32u size)
  {

  PDSP_PARAM0=base;
  PDSP_PARAM1=size;
  PDSP_COMMAND=MIPS_RAMTEST;
  dbgprint(1<<31,"cpswHalEswitchPdspCmdRamTest(%08x,%x);\n",PDSP_PARAM0,PDSP_PARAM1);
  return(cpswHalEswitchPdspCmdWait(HalDev));
  }

int cpswHalEswitchPdspCmdSetOverflowQueue(halDevice_s *HalDev,bit32u head, bit32u tail,bit32 count,bit32u overctl)
  {

  PDSP_PARAM0=head;
  PDSP_PARAM1=tail;
  PDSP_PARAM2=count;
  PDSP_PARAM3=overctl;
  PDSP_COMMAND=MIPS_SET_OVERFLOW_Q;
  dbgprint(1<<31,"cpswHalEswitchPdspCmdSetOverflowQueue(%08x,%08x,%08x,%08x);\n",
                      PDSP_PARAM0,PDSP_PARAM1,PDSP_PARAM2,PDSP_PARAM3);
  return(cpswHalEswitchPdspCmdWait(HalDev));
  }

int cpswHalEswitchPdspCmdSetOverflowBufLen(halDevice_s *HalDev,bit32u size)
  {

  PDSP_PARAM0=size;
  PDSP_COMMAND=MIPS_SET_OVER_BUFLEN;
  dbgprint(1<<31,"cpswHalEswitchPdspCmdSetOverflowBufLen(%08x);\n",PDSP_PARAM0);
  return(cpswHalEswitchPdspCmdWait(HalDev));
  }

int cpswHalEswitchPdspCmdSetTenthCount(halDevice_s *HalDev,bit32u ClocksPerTic)
  {

  PDSP_PARAM0=ClocksPerTic;
  PDSP_COMMAND=MIPS_SET_TENTH_COUNT;
  dbgprint(1<<31,"cpswHalEswitchPdspCmdSetTenthCount(%08x);\n",PDSP_PARAM0);
  return(cpswHalEswitchPdspCmdWait(HalDev));
  }

int cpswHalEswitchPdspCmdSetAgeInterval(halDevice_s *HalDev,bit32u TicsPerInterval)
  {

  PDSP_PARAM0=TicsPerInterval;
  PDSP_COMMAND=MIPS_SET_AGE_INTERVAL;
  dbgprint(1<<31,"cpswHalEswitchPdspCmdSetAgeInterval(%08x);\n",PDSP_PARAM0);
  return(cpswHalEswitchPdspCmdWait(HalDev));
  }

int cpswHalEswitchPdspCmdSetPhyInterval(halDevice_s *HalDev,bit32u TicsPerInterval)
  {

  PDSP_PARAM0=TicsPerInterval;
  PDSP_COMMAND=MIPS_SET_PHY_INTERVAL;
  dbgprint(1<<31,"cpswHalEswitchPdspCmdSetPhyInterval(%08x);\n",PDSP_PARAM0);
  return(cpswHalEswitchPdspCmdWait(HalDev));
  }

int cpswHalEswitchPdspCmdRestartCam(halDevice_s *HalDev)
  {

  PDSP_COMMAND=MIPS_RESTART_CAM;
  dbgprint(1<<31,"cpswHalEswitchPdspCmdRestartCam();\n");
  return(cpswHalEswitchPdspCmdWait(HalDev));
  }

int cpswHalEswitchPdspCmdSetCamSize(halDevice_s *HalDev,bit32u size)
  {

  PDSP_PARAM0=size-1;
  PDSP_COMMAND=MIPS_SET_CAM_SIZE;
  dbgprint(1<<31,"cpswHalEswitchPdspCmdSetCamSize(%08x);\n",PDSP_PARAM0);
  return(cpswHalEswitchPdspCmdWait(HalDev));
  }

int cpswHalEswitchPdspCmdSetMode(halDevice_s *HalDev,bit32u mode)  /*Export  */
  {

  PDSP_PARAM0=mode;
  PDSP_COMMAND=MIPS_SET_MODE;
  dbgprint(1<<31,"cpswHalEswitchPdspCmdSetMode(%08x);\n",PDSP_PARAM0);
  return(cpswHalEswitchPdspCmdWait(HalDev));
  }

int cpswHalEswitchPdspCmdStpPortMask(halDevice_s *HalDev,bit32u mask)  /*Export*/
  {

  PDSP_PARAM0=mask;
  PDSP_COMMAND=MIPS_STP_PORT_MASK;
  dbgprint(1<<31,"cpswHalEswitchPdspCmdStpPortMask(%08x);\n",PDSP_PARAM0);
  return(cpswHalEswitchPdspCmdWait(HalDev));
  }

int cpswHalEswitchPdspCmdSetRxQueue(halDevice_s *HalDev,bit32u ChanPort, bit32u head,bit32 tail,bit32u count)
  {

  PDSP_PARAM0=ChanPort;
  PDSP_PARAM1=head;
  PDSP_PARAM2=tail;
  PDSP_PARAM3=count;
  PDSP_COMMAND=MIPS_SET_RX_Q;
  dbgprint(1<<31,"cpswHalEswitchPdspCmdSetRxQueue(%08x,%08x,%08x,%08x);\n",
                      PDSP_PARAM0,PDSP_PARAM1,PDSP_PARAM2,PDSP_PARAM3);
  return(cpswHalEswitchPdspCmdWait(HalDev));
  }

int cpswHalEswitchPdspCmdSetDescPool(halDevice_s *HalDev,bit32u RxPort0Desc, bit32u RxPort1Desc,bit32 RxPort2Desc,bit32u RxPort3Desc)
  {

  PDSP_PARAM0=RxPort0Desc;
  PDSP_PARAM1=RxPort1Desc;
  PDSP_PARAM2=RxPort2Desc;
  PDSP_PARAM3=RxPort3Desc;
  PDSP_COMMAND=MIPS_SET_RX_DESCPOOL;
  dbgprint(1<<31,"cpswHalEswitchPdspCmdSetDescPool(%08x,%08x,%08x,%08x);\n",
                      PDSP_PARAM0,PDSP_PARAM1,PDSP_PARAM2,PDSP_PARAM3);
  return(cpswHalEswitchPdspCmdWait(HalDev));
  }

int cpswHalEswitchPDSPCommand(halDevice_s *HalDev,bit32u command,bit32u p1, bit32u p2,bit32 p3,bit32u p4)
  {

  PDSP_PARAM0=p1;
  PDSP_PARAM1=p2;
  PDSP_PARAM2=p3;
  PDSP_PARAM3=p4;
  PDSP_COMMAND=command;
  dbgprint(1<<31,"PdcpCmd%d(%08x,%08x,%08x,%08x);\n",command,
                      PDSP_PARAM0,PDSP_PARAM1,PDSP_PARAM2,PDSP_PARAM3);
  return(cpswHalEswitchPdspCmdWait(HalDev));
  }

int cpswHalEswitchPdspCmdSetTxQueue(halDevice_s *HalDev,bit32u ChanPort, bit32u head,bit32 tail,bit32u count)
  {

  PDSP_PARAM0=ChanPort;
  PDSP_PARAM1=head;
  PDSP_PARAM2=tail;
  PDSP_PARAM3=count;
  PDSP_COMMAND=MIPS_SET_TX_Q;
  dbgprint(1<<31,"cpswHalEswitchPdspCmdSetTxQueue(%08x,%08x,%08x,%08x);\n",
                      PDSP_PARAM0,PDSP_PARAM1,PDSP_PARAM2,PDSP_PARAM3);
  return(cpswHalEswitchPdspCmdWait(HalDev));
  }

int cpswHalEswitchPdspCmdSetBufLen(halDevice_s *HalDev,bit32u mask)
  {

  PDSP_PARAM0=mask;
  PDSP_COMMAND=MIPS_SET_CPMAC_BUFLEN;
  dbgprint(1<<31,"cpswHalEswitchPdspCmdSetBufLen(%08x);\n",PDSP_PARAM0);
  return(cpswHalEswitchPdspCmdWait(HalDev));
  }

int cpswHalEswitchPdspCmdSetPriorityMapping(halDevice_s *HalDev,bit32u Port, bit32u InputPriority,bit32 Mapping) /*Export*/
  {

  PDSP_PARAM0=Port;
  PDSP_PARAM1=InputPriority;
  PDSP_PARAM2=Mapping;
  PDSP_COMMAND=MIPS_SET_PRIMAP;
  dbgprint(1<<31,"cpswHalEswitchPdspCmdSetPriorityMapping(%08x,%08x,%08x);\n",
                      PDSP_PARAM0,PDSP_PARAM1,PDSP_PARAM2);
  return(cpswHalEswitchPdspCmdWait(HalDev));
  }

int cpswHalEswitchPdspCmdInitPort(halDevice_s *HalDev,bit32u port)
  {

  PDSP_PARAM0=port;
  PDSP_COMMAND=MIPS_INIT_PORT;
  dbgprint(1<<31,"cpswHalEswitchPdspCmdInitPort(%08x);\n",PDSP_PARAM0);
  return(cpswHalEswitchPdspCmdWait(HalDev));
  }

int cpswHalEswitchPdspCmdSetDuplex(halDevice_s *HalDev,bit32u port, bit32u duplex)
  {

  PDSP_PARAM0=port;
  PDSP_PARAM1=duplex;
  PDSP_COMMAND=MIPS_SET_DUPLEX;
  dbgprint(1<<31,"cpswHalEswitchPdspCmdSetDuplex(%08x,%x);\n",PDSP_PARAM0,PDSP_PARAM1);
  return(cpswHalEswitchPdspCmdWait(HalDev));
  }

int cpswHalEswitchPdspCmdSetPortVlanId(halDevice_s *HalDev,bit32u port, bit32u vlanid)  /*Export*/
  {

  PDSP_PARAM0=port;
  PDSP_PARAM1=vlanid;
  PDSP_COMMAND=MIPS_SET_PVID;
  dbgprint(1<<31,"cpswHalEswitchPdspCmdSetPortVlanId(%08x,%x);\n",PDSP_PARAM0,PDSP_PARAM1);
  return(cpswHalEswitchPdspCmdWait(HalDev));
  }

int cpswHalEswitchPdspCmdEnablePort(halDevice_s *HalDev,bit32u port)  /*Export*/
  {

  PDSP_PARAM0=port;
  PDSP_COMMAND=MIPS_ENABLE_PORT;
  dbgprint(1<<31,"cpswHalEswitchPdspCmdEnablePort(%08x);\n",PDSP_PARAM0);
  return(cpswHalEswitchPdspCmdWait(HalDev));
  }

int cpswHalEswitchPdspCmdDisablePort(halDevice_s *HalDev,bit32u port)  /*Export*/
  {

  PDSP_PARAM0=port;
  PDSP_COMMAND=MIPS_DISABLE_PORT;
  dbgprint(1<<31,"cpswHalEswitchPdspCmdDisablePort(%08x);\n",PDSP_PARAM0);
  return(cpswHalEswitchPdspCmdWait(HalDev));
  }

int cpswHalEswitchPdspCmdCamOp(halDevice_s *HalDev,bit32u Mode,bit32u DatLo,bit32 DatHi,bit32u *Status)
  {
  int sts;

  PDSP_PARAM0=Mode;
  PDSP_PARAM1=DatLo;
  PDSP_PARAM2=DatHi;
  PDSP_COMMAND=PDSPCMD_CAM_OP;
  dbgprint(1<<31,"cpswHalEswitchPdspCmdCamOp(%0x8,%08x,%08x,",PDSP_PARAM0,PDSP_PARAM1,PDSP_PARAM2);
  sts=cpswHalEswitchPdspCmdWait(HalDev);
  if (!sts)
    {
    *Status=PDSP_PARAM3;
    }
  dbgprint(1<<31,"*%08x);\n",PDSP_PARAM3);
  return(sts);
  }

int cpswHalEswitchPdspCmdWriteCam(halDevice_s *HalDev,bit32u Adr, bit32u DatLo,bit32 DatHi,bit32u *Status)
  {
  int sts;

  PDSP_PARAM0=Adr;
  PDSP_PARAM1=DatLo;
  PDSP_PARAM2=DatHi;
  PDSP_COMMAND=MIPS_WRITE_CAM;
  dbgprint(1<<31,"cpswHalEswitchPdspCmdWriteCam(%08x,%08x,%08x,",PDSP_PARAM0,PDSP_PARAM1,PDSP_PARAM2);
  sts=cpswHalEswitchPdspCmdWait(HalDev);
  if (!sts)
    {
    *Status=PDSP_PARAM3;
    }
  dbgprint(1<<31,"*%08x);\n",PDSP_PARAM3);
  return(sts);
  }

int cpswHalEswitchPdspCmdReadCam(halDevice_s *HalDev,bit32u Adr, bit32u *DatLo,bit32 *DatHi,bit32u *Status)
  {
  int sts;

  PDSP_PARAM0=Adr;
  PDSP_COMMAND=MIPS_READ_CAM;
  dbgprint(1<<31,"cpswHalEswitchPdspCmdReadCam(%08x,",PDSP_PARAM0);
  sts=cpswHalEswitchPdspCmdWait(HalDev);
  if (!sts)
    {
    *DatLo=PDSP_PARAM1;
    *DatHi=PDSP_PARAM2;
    *Status=PDSP_PARAM3;
    }
  dbgprint(1<<31,"*%08x,*%08x,*%08x);\n",PDSP_PARAM1,PDSP_PARAM2,PDSP_PARAM3);
  return(sts);
  }

int cpswHalEswitchInitHdmaPort(halDevice_s *HalDev)
  {
  bit32u *StatePtr;
  int i;

  StatePtr=(bit32u*)(HalDev->HdmaBase+0x0800);
  for(i=0;i<128;i++) 
    *StatePtr++=0;

  if (HalDev->BigEndian)
    {
    HDMA_TXENDIAN=0x01;
    HDMA_RXENDIAN=0x82;
    }
   else
    {
    HDMA_TXENDIAN=0;
    HDMA_RXENDIAN=0;
    }
  return(0);
  }

int cpswHalEswitchError(halDevice_s *HalDev,char *str)
  {
  HalDev->OsFunc->Printf("ERROR: %s\n",str);
  return(1);
  }

