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

📄 lan8xx.c

📁 这是单板上DPRAM的驱动程序
💻 C
📖 第 1 页 / 共 5 页
字号:

    splx(old_level);
    }
}

/***********************************************************************/
/*     ni_init: Initialize the network interface.                      */
/*                                                                     */
/*      INPUTS: ap_addr: pNA+'s announce packet entry point.           */
/*              if_num: interface number                               */
/*              funcs: pointer to pNA memory mgmnt functions           */
/*     RETURNS: Pointer to hardware address of NI, or -1 if failure    */
/*                                                                     */
/***********************************************************************/
static long ni_init(long (*ap_addr)(ULONG, char *, ULONG, ULONG, char *,
    char *), long if_num, struct ni_funcs *funcs)
{
extern long ifadminstatus;
UINT i;

/*---------------------------------------------------------------------*/
/* Assign input parameters to global variables.                        */
/*---------------------------------------------------------------------*/
Announce = ap_addr;
If_Num   = if_num;
Ni_funcs = *funcs;

/*---------------------------------------------------------------------*/
/* Arrest all Ethernet activity and initialize the receive buffers and */
/* transmit headers.                                                   */
/*---------------------------------------------------------------------*/
LanStop();
InitBuffers();

/*---------------------------------------------------------------------*/
/* Allocate Dual Ported RAM for the Receive Buffer Descriptors.        */
/*---------------------------------------------------------------------*/
RxUsedPtr = RxNewPtr = RxFirstBdPtr = (BuffDescType *)
    dpram_alloc(LAN_PORT, BD_SCC_RX_BDS * sizeof(BuffDescType));

RxLastBdPtr = RxFirstBdPtr + BD_SCC_RX_BDS - 1;

if(RxFirstBdPtr == (BuffDescType *)0)
    return -1;

/*---------------------------------------------------------------------*/
/* Clear the Receive Buffer Descriptors.                               */
/*---------------------------------------------------------------------*/
for (i = 0; i < BD_SCC_RX_BDS; i++)
    {
    (RxFirstBdPtr + i)->status = 0;
    (RxFirstBdPtr + i)->length = 0;
    (RxFirstBdPtr + i)->address = NULL;
    }

RxLastBdPtr->status = WRAP;
AssignRxBuffers();

/*---------------------------------------------------------------------*/
/* Allocate Dual Ported RAM for the Transmit Buffer Descriptors.       */
/*---------------------------------------------------------------------*/
TxUsedPtr = TxNewPtr = TxFirstBdPtr = (BuffDescType *)
    dpram_alloc(LAN_PORT, NrTxBds * sizeof(BuffDescType));

if(TxFirstBdPtr == (BuffDescType *)0)
    return -1;

/*---------------------------------------------------------------------*/
/* Clear the Transmit Buffer Descriptors.                              */
/*---------------------------------------------------------------------*/
TxLastBdPtr = TxFirstBdPtr + NrTxBds - 1;

for (i = 0; i < NrTxBds; i++)
    {
    (TxFirstBdPtr + i)->status = 0;
    (TxFirstBdPtr + i)->length = 0;
    (TxFirstBdPtr + i)->address = NULL;
    }

TxLastBdPtr->status = WRAP;
TxFreeBDs = NrTxBds;

/*---------------------------------------------------------------------*/
/* Initialize the interrupt vector, and the pSOS and ISR state flags.  */
/*---------------------------------------------------------------------*/

#if (BD_HAS_SLAVE == 1)

IsrAddHandler(V_SCC1, (void*)ni_isr, (void *)V_SCC1);

#else /* BD_HAS_SLAVE */

IsrAddHandler(V_SCC1, (void *)ni_isr, (void *)V_SCC1);

#endif /* BD_HAS_SLAVE */

pSOS_Is_Up = FALSE;

/*---------------------------------------------------------------------*/
/* Get the Ethernet Address.  This is set in bpdialog.c.               */
/*---------------------------------------------------------------------*/
for (i = 0; i < 6; ++i)
    OurAddress.byte[i] = EthernetAddress[i];

/*---------------------------------------------------------------------*/
/* Initialize MIB variables.                                           */
/*---------------------------------------------------------------------*/
clear(&MG_stat, sizeof(MG_stat));

MG_stat.ifDescr = "Motorola PowerQUICC SCC1";

#if ((BSP_LAN1_FLAGS) & (IFF_MULTICAST))
    /*-----------------------------------------------------------------*/
    /* Clear the multicast address table.                              */
    /*-----------------------------------------------------------------*/
    lan_mcast.num_used = 0;
#endif

ifadminstatus = 1;

/*---------------------------------------------------------------------*/
/* Initialize SCC1 in Ethernet mode.                                   */
/*---------------------------------------------------------------------*/
InitSCC1();

/*---------------------------------------------------------------------*/
/* No errors if we got here, so return pointer to Ethernet address.    */
/*---------------------------------------------------------------------*/
return (long)&OurAddress;
}

/***********************************************************************/
/* ReturnBuffer: Return a receive buffer to the free list              */
/*                                                                     */
/*      INPUTS: buf_ptr: Pointer to the buffer being returned          */
/*                                                                     */
/***********************************************************************/
static void ReturnBuffer(RX_BUFF *buf_ptr)
{
ULONG old_level;

/*---------------------------------------------------------------------*/
/* Link returned envelope to the envelope previously at the top of the */
/* free queue and point "free_head" to the newly returned envelope.    */
/*---------------------------------------------------------------------*/
old_level = splx(MAX_ILEV);
buf_ptr->next = RxbFreeHead;
RxbFreeHead = buf_ptr;
splx(old_level);
AssignRxBuffers();
}

/***********************************************************************/
/*     ni_send: Send a packet to another node.                         */
/*                                                                     */
/*      INPUTS: hwa_ptr = pointer to the destination hardware address  */
/*              pkb_ptr = pointer to packet (msg block triplet)        */
/*              size    = number of bytes in packet buffer             */
/*              type    = flag indicating either IP, ARP, or RARP      */
/*                                                                     */
/***********************************************************************/
/* static */
void ni_send(char *hwa_ptr, char *pkb_ptr, USHORT size,
  USHORT type)
{
mblk_t *m, *tmp, *m_prev;
ULONG old_level;
UINT NrBDs, FrameLength;
TX_HDR *TxhPtr;
int i, length;
int copy_size;
UCHAR *src;
BuffDescType *FirstBdPtr;
BuffDescType *PrevBdPtr=NULL; /* 必须检查pkt_ptr不为NULL,否则有可能出错*/

ReclaimTxFrames();
m = (mblk_t *)pkb_ptr;
if(m==NULL){ 
    return; /* An error or bug */
    }

/*---------------------------------------------------------------------*/
/* Obtain a transmit header from the free list.  If there are none     */
/* available, we can't send the packet.  Just return the triplet.      */
/*---------------------------------------------------------------------*/
old_level = splx(MAX_ILEV);
if ((TxhPtr = TxhFreeHead) == NULL)
    {
    outdiscards++;
    splx(old_level);
    Ni_funcs.freemsg(m);
    return;
    }
else
    TxhFreeHead = TxhPtr->next;
splx(old_level);

/*---------------------------------------------------------------------*/
/* Write destination and source address, type, and size to the header. */
/*---------------------------------------------------------------------*/
for (i = 0; i < 6; i++)
    TxhPtr->daddr.byte[i] = *hwa_ptr++;
TxhPtr->saddr.word1 = OurAddress.word1;
TxhPtr->saddr.word2 = OurAddress.word2;
TxhPtr->saddr.word3 = OurAddress.word3;
TxhPtr->type = type;

TxhPtr->msg_ptr = m;
TxhPtr->size = size;

/*---------------------------------------------------------------------*/
/* If there are not at least three BDs queue the frame for later       */
/* transmission.                                                       */
/*---------------------------------------------------------------------*/
old_level = splx(MAX_ILEV);
if (TxFreeBDs < 3)
    {
    Postponed++;
    TxhPtr->next = NULL;
    if (TxhOutHead == NULL)
        TxhOutHead = TxhOutTail = TxhPtr;
    else
        {
        TxhOutTail->next = TxhPtr;
        TxhOutTail = TxhPtr;
        }
    splx(old_level);
    return;
    }

/*---------------------------------------------------------------------*/
/* If there is one or more elements on the transmit queue, and the new */
/* frame to the end of the queue. Then remove the head of the queue    */
/* and try to transmit it.                                             */
/*---------------------------------------------------------------------*/
if (TxhOutHead != NULL)
    {
    TxhPtr->next = NULL;
    TxhOutTail->next = TxhPtr;
    TxhOutTail = TxhPtr;
    TxhPtr = TxhOutHead;
    TxhOutHead = TxhPtr->next;
    /*-----------------------------------------------------------------*/
    /* There was at least one element on the queue and we added        */
    /* another. So, there are at least two queue elements. Which means */
    /* we can skip the normal check of the head becoming null.         */
    /*-----------------------------------------------------------------*/
    }
TxhPtr->next = NULL;
FirstBdPtr = TxNewPtr;

/*---------------------------------------------------------------------*/
/* Add the transmit header to the BD list. Don't set the READY bit     */
/* until all BDs for this frame have been added.                       */
/*---------------------------------------------------------------------*/
TxNewPtr->address = TxhPtr;
TxNewPtr->length = 14;
if (TxNewPtr == TxLastBdPtr)
    TxNewPtr->status = (USHORT)WRAP | PAD | TX_CRC;
else
    TxNewPtr->status = PAD | TX_CRC;
IncTxBDptr(TxNewPtr);
#if (BRD_DCACHE == YES) && (BRD_DCACHE_WRITE_THRU == NO)
FlushDcache();
#endif

TxFreeBDs--;

FrameLength = 14;
NrBDs = 1;

/*---------------------------------------------------------------------*/
/* Now put the buffers pointed to by the message block triplet in. If  */
/* the packet is less than 64 bytes long we pad it up to 64. This is a */
/* workaround for a bug in the 68360.                                  */
/*---------------------------------------------------------------------*/
m = TxhPtr->msg_ptr;
m_prev = m;
while (m)
    {
    /*-----------------------------------------------------------------*/
    /* Skip all zero length elements in the mblk list, since adding a  */
    /* buffer of length zero to the BD pool is bad. Free the zero      */
    /* length element and "close" the hole in the chain.               */
    /*-----------------------------------------------------------------*/
    length = m->b_wptr - m->b_rptr;
    if (length == 0)
        {
        m_prev->b_cont = m->b_cont;
        m->b_cont = NULL;
        Ni_funcs.freemsg(m);
        m = m_prev->b_cont;
        continue;
        }

⌨️ 快捷键说明

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