⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 csend.c

📁 Crystal Semiconductor CS8900 network interface driver.
💻 C
📖 第 1 页 / 共 5 页
字号:

#ifdef CS_DEBUG_ENABLE
   pCS->TxQueueDepth    = 0;
   pCS->MaxTxQueueDepth = 0;
#endif

   /* Initialize local queues */
   pCS->pTxBuffFreeList = &TxBuffFreeList;
   pCS->pRxBuffProcessList = &RxBuffProcessList;
   pCS->pTxQueue = &TxQueue;
   csInitQueue( pCS->pTxBuffFreeList );
   csInitQueue( pCS->pRxBuffProcessList );
   csInitQueue( pCS->pTxQueue );
   
   /* Allocate the receive frame buffers */
   if ( csInitRxBuff(pCS) == ERROR )
   {
#ifdef CS_DEBUG_ENABLE
      logMsg("csEndLoad: CS_END_DEVICE %d Can not allocate receive buffers\n", 
              pCS->unit,0,0,0,0,0 );
#endif
      return NULL;
   }

   /* Verify that it is the correct chip */
   if ( csVerifyChip(pCS) == ERROR )
   {
#ifdef CS_DEBUG_ENABLE
      logMsg("csEndLoad: CS_END_DEVICE %d, csVerifyChip failed\n", 
              pCS->unit,0,0,0,0,0 );
#endif
      return NULL;
   }

   /* Get any CS8900 parameters not specifed in network interface table */
   if ( sysEnetGetConfig(pCS) == ERROR )
   {
#ifdef CS_DEBUG_ENABLE
      logMsg("csEndLoad: CS_END_DEVICE %d, sysEnetGetConfig failed\n", 
              pCS->unit,0,0,0,0,0 );
#endif
      return NULL;
   }

   /* Get Ethernet addr in BSP-specific manner*/
   if ( sysEnetAddrGet(pCS,pCS->enetAddr) == ERROR )
   {
#ifdef CS_DEBUG_ENABLE
      logMsg("csEndLoad: CS_END_DEVICE %d, sysEnetAddrGet failed\n", 
         pCS->unit,0,0,0,0,0 );
#endif
      return NULL;
   }


   /* initialize the END and MIB2 parts of the structure 
    * The M2 element must come from m2Lib.h 
    * This template is set up for a DIX type ethernet device.
    */

   status1 = END_OBJ_INIT (&pCS->end, (DEV_OBJ *)pCS, (char *)CS_NAME,
                           pCS->unit, &endFuncTable,
                           "MUX-based Cirrus Logic CS8900 Ethernet Driver.");
   status2 = END_MIB_INIT (&pCS->end, M2_ifType_ethernet_csmacd,
                           &pCS->enetAddr[0], 6,
                           ETHERMTU, END_SPEED);
   if ((status1 == ERROR) || (status2 == ERROR))
   {
#ifdef CS_DEBUG_ENABLE
      logMsg("csEndLoad: CS_END_DEVICE %d,  END_OBJ_INIT or END_MIB_INIT failed\n", 
         pCS->unit,0,0,0,0,0 );
#endif
      return( NULL );
   }
      

   /* Reset the chip */
   if ( csResetChip(pCS) == ERROR )
   {
#ifdef CS_DEBUG_ENABLE
      logMsg("csEndLoad: CS_END_DEVICE %d, Can not reset chip\n", 
         pCS->unit,0,0,0,0,0 );
#endif
      return NULL;
   }

    
    /* set the flags to indicate readiness */ 
    END_OBJ_READY (&pCS->end, IFF_NOTRAILERS | IFF_BROADCAST | IFF_MULTICAST );

    /* Set promiscuous mode if user asked for. */
    if ( pCS->ConfigFlags & CFGFLG_PROMISC_MODE )
    {
       END_FLAGS_SET(&pCS->end, IFF_PROMISC);
    }

#ifdef CS_DEBUG_ENABLE
    logMsg("csEndLoad: CS_END_DEVICE %d, csEndLoad has finished successfully!\n", 
            pCS->unit,0,0,0,0,0 );
#endif

    return (&pCS->end);
}


/*******************************************************************************
*
* csParse - parse the init string
*
* Parse the input string.  Fill in values in the driver control structure.
*
* The initialization string format is:
*  "Unit:IOAdr:IntLevel:MemAddr:MediaType:ConfigFlags"
*
* .bS
*
* unit        Device unit number, a small integer, Decimal.
*
* IOAdr       IO address, Hexadecimal.
*
* intLevel    Interrupt level, Hexadecimal. 
*
* memAddr     Memory Address, Hexadecimal.
*
* mediaType   Media Type, Decimal.
*
* cofigFlag   Configuration flags. See definition of flags in csEnd.h, Hexadecimal. 
*
*
*
* .bE
*
* RETURNS: NULL for invalid arguments or Pointer to CS_END_DEVICE for the device.
*/

CS_END_DEVICE *csParse (
    char *initString                /* information string */
    )
{
char*        tok;
char*        pHolder = NULL;
int          unit;
unsigned long  tmp_long;
unsigned short tmp_short;
CS_END_DEVICE *pCS;

   /* Parse the initString */
   /* Unit number. */
   tok = strtok_r (initString, ":", &pHolder);
   if (tok == NULL)
      return NULL;

   unit = atoi(tok);
   if ( unit >= CS_MAX_NUM_UNITS )
   {
#ifdef CS_DEBUG_ENABLE
       logMsg("csEndLoad: Invalid unit number (%d)\n", unit,0,0,0,0,0 );
#endif
      return NULL;
   }
   pCS = &cs_end[unit];
   pCS->unit =unit;

   /* Save the passed-in parameters */

   tok = strtok_r (NULL, ":", &pHolder);
   if (tok == NULL)
   {
      return NULL;
   }
   tmp_long = strtoul (tok, NULL, 16);
   pCS->IOAddr= tmp_long;

   tok = strtok_r (NULL, ":", &pHolder);
   if (tok == NULL) return NULL;
   tmp_short = (USHORT )strtoul(tok, NULL, 16);
   pCS->IntLevel= tmp_short;


/*      The intVector value is used for intConnect() to
*       connect ISR() to the interrupt vector number.
*       In intConnect(), we pass INUM_TO_IVEC((ULONG)pCS->IntVector) as the 1st parameter.
*       If the processor type is Intel x86,  It is automatically calculated by 
*       "pCS->IntVector = sysVectorIRQ0 + pCS->IntLevel;" for x86.
*       For non-x86 processors, just let IntVector = IntLevel.      
*/

#if CPU_FAMILY == I80X86
    pCS->IntVector = sysVectorIRQ0 + pCS->IntLevel;
#else
     pCS->IntVector = pCS->IntLevel;
#endif

   tok = strtok_r (NULL, ":", &pHolder);
   if (tok == NULL) return NULL;
   tmp_long = strtoul (tok, NULL, 16);
   pCS->pPacketPage= (unsigned short *)tmp_long;

   tok = strtok_r (NULL, ":", &pHolder);
   if (tok == NULL) return NULL;
   tmp_short = (USHORT )atoi(tok);
   pCS->MediaType = tmp_short;

   tok = strtok_r (NULL, ":", &pHolder);
   if (tok == NULL) return NULL;
   tmp_long = (USHORT)strtoul (tok, NULL, 16);
   pCS->ConfigFlags = tmp_long;



#ifdef CS_DEBUG_ENABLE
   logMsg("csParser(): IOAddr=0X%X, IntLevel=0X%X, IntVect=0X%X, 
           MemBase=0X%X, MediaType=%d, ConfigFlag=0X%X\n", 
           pCS->IOAddr,pCS->IntLevel,pCS->IntVector,(unsigned int)pCS->pPacketPage,
           pCS->MediaType, pCS->ConfigFlags );
#endif
 
   return pCS;
}

/*******************************************************************************
*
* csInitRxBuff -
*
* This routine initializes the network interface driver's collection of
* receive buffers.  The receive buffers are allocated from system memory
* and linked together in a linked list of free receive buffers.
*
* RETURNS: OK or ERROR.
*/

LOCAL STATUS csInitRxBuff( CS_END_DEVICE *pCS )
{
  M_CL_CONFIG endMclBlkConfig=         /* network mbuf configuration table */
       
 /* no. mBlks  no. clBlks memArea memSize
    ---------  ---------- ------- ------- */
  { 0,           0,         NULL,         0 };
    


  CL_DESC endClDescTbl []= {        /* network cluster pool configuration table */    
/*  clusterSize                    num                    memArea        memSize
    ------------  ----------------        -------        ------- */
    {END_BUFSIZE, CS_NUM_RX_BUFFERS, NULL,            0}
  }; 

  int endClDescTblNumEnt;


   /* Allocate Memory for Clusters used by RX buffers */
    
   if ((pCS->end.pNetPool = malloc(sizeof(NET_POOL))) == NULL)
        return (ERROR);

    endMclBlkConfig.mBlkNum = 2*CS_NUM_RX_BUFFERS;
    endMclBlkConfig.clBlkNum = CS_NUM_RX_BUFFERS;
   
  
    /* Calculate the total memory for all the M-Blks and CL-Blks. */

    endMclBlkConfig.memSize = (endMclBlkConfig.mBlkNum * (MSIZE + sizeof (long))) +
                          (endMclBlkConfig.clBlkNum * (CL_BLK_SZ + sizeof(long)));

    if ((endMclBlkConfig.memArea = (char *) memalign (sizeof(long),
                             endMclBlkConfig.memSize)) == NULL)
    {
#ifdef CS_DEBUG_ENABLE
       logMsg("csInitRxBuff: Unit=%d Memory unavailable. memalign() Failed!\n", 
                        pCS->unit, 0, 0, 0, 0, 0);
#endif
       return (ERROR);
    }
    
    /* Calculate the memory size of all the clusters. */

    endClDescTbl[0].memSize = (endClDescTbl[0].clNum * (END_BUFSIZE + 8))
                              + sizeof(int);

    /* Allocate the memory for the clusters from cache safe memory. */

   endClDescTbl[0].memArea =(char *) cacheDmaMalloc(endClDescTbl[0].memSize);
    

   if ((int)endClDescTbl[0].memArea == NULL)
   {
#ifdef CS_DEBUG_ENABLE
      logMsg("csInitRxBuff: Unit=%d System memory unavailable\n", 
              pCS->unit, 0, 0, 0, 0, 0);
#endif
      return (ERROR);
   }
    

   endClDescTblNumEnt = (NELEMENTS(endClDescTbl));
 
   /* Initialize the memory pool. */

   if (netPoolInit(pCS->end.pNetPool, &endMclBlkConfig,
                    &endClDescTbl[0], endClDescTblNumEnt, NULL) == ERROR)
   {
#ifdef CS_DEBUG_ENABLE
        logMsg("csInitRxBuff: Unit=%d Could not init buffering\n",
                pCS->unit, 0, 0, 0, 0, 0);
#endif
        return (ERROR);
   }

   /* Store the cluster pool id as others need it later. */
   pCS->pClPoolId = netClPoolIdGet(pCS->end.pNetPool, (int)END_BUFSIZE, (BOOL)FALSE);
   if (pCS->pClPoolId == NULL)
   {
#ifdef CS_DEBUG_ENABLE
        logMsg("csInitRxBuff: Unit=%d Could not memory cluster ID\n",
                pCS->unit, 0, 0, 0, 0, 0);
#endif
        return (ERROR);
   }
   
   return OK;
}


/*******************************************************************************
*
* csVerifyChip -
*
* This routine verifies that the Ethernet chip is present and correct.
*
*/

LOCAL STATUS csVerifyChip( CS_END_DEVICE *pCS )
{
USHORT wrVal, rdVal;
USHORT errorCount = 0;
USHORT x=0xFFFF;

   /* Verify that we can read from the chip */
   x = csReadPacketPage( pCS, PKTPG_EISA_NUM );
   if ( x == 0xFFFF )
   {
#ifdef CS_DEBUG_ENABLE
      logMsg("csVerifyChip: CS_END_DEVICE %d, can't read from chip (I/O address correct?)\n",
              pCS->unit, 0,0,0,0,0 );
#endif
      return ERROR;
   }

   /* Verify that the chip is a Crystal Semiconductor chip */
   if ( x != EISA_NUM_CRYSTAL )
   {
#ifdef CS_DEBUG_ENABLE
      logMsg("csVerifyChip: CS_END_DEVICE %d, Chip is not a Crystal Semiconductor chip\n",
              pCS->unit, 0,0,0,0,0 );
#endif
      return ERROR;
   }

   /* Verify that the chip is a CS8900 */
   x = csReadPacketPage(pCS,PKTPG_PRODUCT_ID);
   x &= PROD_ID_MASK;
   if ( x != PROD_ID_CS8900)
   {
#ifdef CS_DEBUG_ENABLE
      logMsg("csVerifyChip: CS_END_DEVICE %d, Chip is not a CS8900p\n",
              pCS->unit, 0,0,0,0,0 );
#endif
      return ERROR;
   }

    /* walk a one in the memory of the enet controller */
    for( wrVal = 0x0001; wrVal != 0; wrVal <<= 1 )
    {
 
      for( x=0x150; x<= 0x15d; x+=2 )
      {
        /* write out value - don't swap bytes */
        csWritePacketPage( pCS, x, wrVal );
   
        /* read back value - don't swap bytes */
        rdVal = csReadPacketPage( pCS, x );
  
        if( wrVal != rdVal )
        {
          if( errorCount <=10 )
          {
#ifdef CS_DEBUG_ENABLE
            logMsg("csVerifyChip:  ERROR reg %04X, wrVal %04X, rdVal %04X\n",
                    x, (unsigned int) BYTE_SWAP(wrVal),
                    (unsigned int) BYTE_SWAP(rdVal),0,0,0 );
#endif
          }
          errorCount++;
        }
      }
    } /* end walking one test */

    /* write incrementing value test */
    for( x=0x150, wrVal=0x0101; x<= 0x15d; x+=2, wrVal+=0x0101 )
    {
      /* write out value - don't worry about swapping bytes */
      csWritePacketPage( pCS, x, wrVal );
    } 

    /* read incrementing value test */
    for( x=0x150, wrVal=0x0101; x<= 0x15d; x+=2, wrVal+=0x0101 )
    {
       /* read back value - don't worry about swapping bytes */
       rdVal = csReadPacketPage( pCS, x );
 
       if( wrVal != rdVal )
       {
#ifdef CS_DEBUG_ENABLE
          logMsg("\ncsVerifyChip:  ERROR reg %04X, wrVal %04X, rdVal %04X\n",
                  x, (unsigned int) BYTE_SWAP(wrVal), 
                  (unsigned int) BYTE_SWAP(rdVal),0,0,0 );
#endif
          errorCount++;
       }
    } /* end walking one test */

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -