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

📄 am79c973.c

📁 Windows CE 6.0 BSP for VOIP sample phone. Intel PXA270 platform.
💻 C
📖 第 1 页 / 共 2 页
字号:

    // Buffers must be aligned to 32 bytes boundary
    offset = address & 0x1F;
    if (offset != 0) {
        address = address + 0x20 - offset;
        size = size + 0x20 - offset;
    }

    // Check if buffer is big enough to accomodate all
    buffers = TX_BUFFERS + RX_BUFFERS;
    if (size < ((BUFFER_SIZE + DESC_SIZE) * buffers + INIT_SIZE)) {
        OALMSGS(OAL_ERROR, (
            L"ERROR: AM79C973InitDMABuffer: Buffer too small\r\n"
        ));
        goto cleanUp;
    }

    // Store address and size
    g_dmaAddress = (UINT32)OALCAtoUA(address);
    g_dmaSize = size;

    // Done
    rc = TRUE;

cleanUp:    
    OALMSGS(OAL_ETHER&&OAL_FUNC, (L"-AM79C973InitDMABuffer(rc = %d)\r\n", rc));
    return rc;
}

//------------------------------------------------------------------------------

BOOL AM79C973Init(UINT8 *pAddress, UINT32 offset, UINT16 mac[3])
{
    BOOL rc = FALSE;

    OALMSGS(OAL_ETHER&&OAL_FUNC, (
        L"+AM79C973Init(0x%08x, 0x%08x, 0x%08x)\r\n", pAddress, offset, mac
    ));
   
    g_base = (UINT32)pAddress;

    if (!HWInit()) goto cleanUp;
    
    // Set mac parameters 
    mac[0] = g_pInit[1] & 0xFFFF;
    mac[1] = g_pInit[1] >> 16;
    mac[2] = g_pInit[2] & 0xFFFF;

    // Done
    rc = TRUE;

cleanUp:    
    OALMSGS(OAL_ETHER&&OAL_FUNC, (L"-AM79C973Init(rc = %d)\r\n", rc));
    return rc;
}

//------------------------------------------------------------------------------

VOID AM79C973PowerOff()
{
    UINT32 exCtrl;

    // First we must go to suspend mode
    exCtrl = ReadCSR(5);
    exCtrl |= 0x0001;
    WriteCSR(5, exCtrl);
    
    // Wait until we get there
    while ((ReadCSR(5) & 0x0001) == 0) OALStall(10);

    // Res
}

//------------------------------------------------------------------------------

VOID AM79C973PowerOn()
{
    HWInit();
}

//------------------------------------------------------------------------------

UINT16 AM79C973SendFrame(UINT8 *pData, UINT32 length)
{
    UINT32 start;
    volatile UINT32 *pos;

    OALMSGS(OAL_ETHER&&OAL_VERBOSE, (
        L"+AM79C973SendFrame(0x%08x, %d)\r\n", pData, length
    ));

    // Check if packet fit to buffer    
    if (length > BUFFER_SIZE) return 1;

    // Wait until buffer is done
    pos = (volatile UINT32*)&g_pTxRing[g_txPos << 2];

    // Wait for transmit buffer available
    start = OALGetTickCount();
    while ((pos[1] & TMD1_OWN) != 0) {
        if ((OALGetTickCount() - start) > 2000) {
            OALMSGS(OAL_ERROR, (L"ERROR: AM79C973SendFrame: Send timeout\r\n"));
            return 1;
        }
    }

    // Copy data to buffer
    memcpy((VOID*)pos[3], pData, length);
    pos[0] = 0;
    pos[1] = TMD1_OWN|TMD1_STP|TMD1_ENP|TMD1_ONES|(4096 - length);

    // Force controller to read tx descriptor
    WriteCSR(0, (ReadCSR(0) & 0x0040) | 0x0008);

    // Move to next possition
    if (++g_txPos == TX_BUFFERS) g_txPos = 0;

    OALMSGS(OAL_ETHER&&OAL_VERBOSE, (L"-RAM79C973SendFrame(rc = 0)\r\n"));
    return 0;
}

//------------------------------------------------------------------------------

UINT16 AM79C973GetFrame(UINT8 *pData, UINT16 *pLength)
{
    UINT32 rmd1, rmd2, length;
    volatile UINT32 *pos;

    OALMSGS(OAL_ETHER&&OAL_VERBOSE, (
        L"+AM79C973GetFrame(0x%08x, %d)\r\n", pData, *pLength
    ));

    pos = (volatile UINT32 *)&g_pRxRing[g_rxPos << 2];
    length = 0;

    // Check if there is received frame 
    if ((ReadCSR(0) & 0x0400) != 0) {
        
        // When packet is in buffer hardware doesn own descriptor
        while (((rmd1 = pos[1]) & RMD1_OWN) == 0) {
            rmd2 = pos[0];
            // Is packet received ok?
            length = rmd2 & 0x0FFF;
            if (length > 4) length -= 4; 
            if ((rmd1 & RMD1_ERR) == 0 && length < *pLength) {
                // Copy packet if there is no problem
                memcpy(pData, (VOID*)pos[3], length);
            } else {
                OALMSGS(OAL_WARN, (
                    L"AM79C973GetFrame - %X/%X %d\n", rmd1, rmd2, *pLength
                ));
                length = 0;
            }
            // Reinitialize descriptor
            pos[0] = 0;
            pos[1] = RMD1_OWN | RMD1_ONES | (4096 - BUFFER_SIZE);
            // Move to next possition
            if (++g_rxPos == RX_BUFFERS) g_rxPos = 0;
            // Calculate position
            pos = (volatile UINT32 *)&g_pRxRing[g_rxPos << 2];
            // If this descriptor is owned by hardware clear interrupt
            if ((pos[1] & RMD1_OWN) != 0) {
                WriteCSR (0, (ReadCSR(0) & 0x0040) | 0x0400);
            }         
            // If we get a packet break loop
            if (length > 0) break;
        }

    }

    // Return size
    *pLength = (USHORT)length;

    OALMSGS(OAL_ETHER&&OAL_VERBOSE, (
        L"-AM79C973GetFrame(length = %d)\r\n", length
    ));
    return *pLength;
}

//------------------------------------------------------------------------------

void AM79C973EnableInts()
{
    OALMSGS(OAL_ETHER&&OAL_FUNC, (L"+AM79C973EnableInts\r\n"));
    WriteCSR(3, ReadCSR(3) & 0xFBFF);  // clear RINT mask
    WriteCSR(0, 0x40);
    OALMSGS(OAL_ETHER&&OAL_FUNC, (L"-AM79C973EnableInts\r\n"));
}

//------------------------------------------------------------------------------

void AM79C973DisableInts()
{
    OALMSGS(OAL_ETHER&&OAL_FUNC, (L"+AM79C973DisableInts\r\n"));
    WriteCSR(0, 0);
    OALMSGS(OAL_ETHER&&OAL_FUNC, (L"-AM79C973DisableInts\r\n"));
}

//------------------------------------------------------------------------------

VOID AM79C973CurrentPacketFilter(UINT32 filter)
{
    UINT32 exCtrl, mode;

    OALMSGS(OAL_ETHER&&OAL_FUNC, (
       L"+AM79C973CurrentPacketFilter(0x%08x)\r\n", filter
    ));

    // First we must go to suspend mode
    exCtrl = ReadCSR(5);
    exCtrl |= 0x0001;
    WriteCSR(5, exCtrl);
    
    // Wait until we get there
    while ((ReadCSR(5) & 0x0001) == 0) OALStall(10);

    // Just assume that we always receive direct & broadcast packets
    if ((filter & PACKET_TYPE_ALL_MULTICAST) != 0) {
        WriteCSR(8, 0xFFFF);
        WriteCSR(9, 0xFFFF);
        WriteCSR(10, 0xFFFF);
        WriteCSR(11, 0xFFFF);
    } else if ((filter & PACKET_TYPE_MULTICAST) == 0) {
        WriteCSR(8, 0);
        WriteCSR(9, 0);
        WriteCSR(10, 0);
        WriteCSR(11, 0);
    }

    mode = ReadCSR(15);
    if ((filter & PACKET_TYPE_PROMISCUOUS) != 0) {
        mode |= MODE_PROM;
    } else {
        mode &= ~MODE_PROM;
    }
    WriteCSR(15, mode);
    
    // It is time to leave suspend mode
    exCtrl = ReadCSR(5);
    exCtrl &= ~0x0001;
    WriteCSR(5, exCtrl);

    // Wait until we get there
    while ((ReadCSR(5) & 0x0001) != 0) OALStall(10);

    OALMSGS(OAL_ETHER&&OAL_FUNC, (L"-AM79C973CurrentPacketFilter\r\n"));
}

//------------------------------------------------------------------------------

BOOL AM79C973MulticastList(UINT8 *pAddresses, UINT32 count)
{
   ULONG exCtrl, crc;
   ULONG i, j, bit;
   USHORT h[4];

   OALMSGS(OAL_ETHER&&OAL_FUNC, (
       L"+AM79C973MulticastList(0x%08x, %d)\r\n", pAddresses, count
   ));

   // Calculate hash bits       
   h[0] = h[1] = h[2] = h[3] = 0;
   for (i = 0; i < count; i++) {
      crc = HashAddress(pAddresses);
      bit = 0;
      for (j = 0; j < 6; j++) bit = (bit << 1) + ((crc >> j) & 0x01);
      h[bit >> 4] |= 1 << (bit & 0x0F);
      pAddresses += ADDR_SIZE;
   }

   // Go to suspend mode
   exCtrl = ReadCSR(5);
   exCtrl |= 0x0001;
   WriteCSR(5, exCtrl);

   // Wait until we get there
   while ((ReadCSR(5) & 0x0001) == 0) OALStall(10);

   // And set hardware   
   WriteCSR(8, h[0]);
   WriteCSR(9, h[1]);
   WriteCSR(10, h[2]);
   WriteCSR(11, h[3]);

   // Leave suspend mode
   exCtrl = ReadCSR(5);
   exCtrl &= ~0x0001;
   WriteCSR(5, exCtrl);

   // Wait until we get there
   while ((ReadCSR(5) & 0x0001) != 0) OALStall(10);
   
   OALMSGS(OAL_ETHER&&OAL_FUNC, (L"-AM79C973MulticastList(rc = 1)\r\n"));
   return TRUE;
}

//------------------------------------------------------------------------------

⌨️ 快捷键说明

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