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

📄 rcpci45.c

📁 powerpc内核mpc8241linux系统下net驱动程序
💻 C
📖 第 1 页 / 共 3 页
字号:
        printk("rc: Waking up adapter...\n");        RCResetLANCard(pDpa->id,0,0,0);    }    else    {        pDpa->nexus = 1;    }    while(post_buffers)    {        if (post_buffers > MAX_NMBR_POST_BUFFERS_PER_MSG)            requested = MAX_NMBR_POST_BUFFERS_PER_MSG;        else            requested = post_buffers;        count = RC_allocate_and_post_buffers(dev, requested);        if ( count < requested )        {            /*             * Check to see if we were able to post any buffers at all.             */            if (post_buffers == MAX_NMBR_RCV_BUFFERS)            {                printk("rc: Error RCopen: not able to allocate any buffers\r\n");                return(-ENOMEM);                                }            printk("rc: Warning RCopen: not able to allocate all requested buffers\r\n");            break;            /* we'll try to post more buffers later */        }        else            post_buffers -= count;    }    pDpa->numOutRcvBuffers = MAX_NMBR_RCV_BUFFERS - post_buffers;    pDpa->shutdown = 0;        /* just in case */#ifdef RCDEBUG    printk("rc: RCopen: posted %d buffers\n", (uint)pDpa->numOutRcvBuffers);#endif    MOD_INC_USE_COUNT;    return 0;}static intRC_xmit_packet(struct sk_buff *skb, struct device *dev){    PDPA pDpa = (PDPA) dev->priv;    singleTCB tcb;    psingleTCB ptcb = &tcb;    RC_RETURN status = 0;            if (dev->tbusy || pDpa->shutdown || pDpa->reboot)        {#ifdef RCDEBUG            printk("rc: RC_xmit_packet: tbusy!\n");#endif            dev->tbusy = 1;            return 1;        }          if ( skb->len <= 0 )     {        printk("RC_xmit_packet: skb->len less than 0!\n");        return 0;    }    /*     * The user is free to reuse the TCB after RCI2OSendPacket() returns, since     * the function copies the necessary info into its own private space.  Thus,     * our TCB can be a local structure.  The skb, on the other hand, will be     * freed up in our interrupt handler.     */    ptcb->bcount = 1;    /*      * we'll get the context when the adapter interrupts us to tell us that     * the transmision is done. At that time, we can free skb.     */    ptcb->b.context = (U32)skb;        ptcb->b.scount = 1;    ptcb->b.size = skb->len;    ptcb->b.addr = virt_to_bus((void *)skb->data);#ifdef RCDEBUG    printk("rc: RC xmit: skb = 0x%x, pDpa = 0x%x, id = %d, ptcb = 0x%x\n",            (uint)skb, (uint)pDpa, (uint)pDpa->id, (uint)ptcb);#endif    if ( (status = RCI2OSendPacket(pDpa->id, (U32)NULL, (PRCTCB)ptcb))         != RC_RTN_NO_ERROR)    {#ifdef RCDEBUG        printk("rc: RC send error 0x%x\n", (uint)status);#endif        dev->tbusy = 1;        return 1;    }    else    {        dev->trans_start = jiffies;        //       dev->tbusy = 0;    }    /*     * That's it!     */    return 0;}/* * RCxmit_callback() * * The transmit callback routine. It's called by RCProcI2OMsgQ() * because the adapter is done with one or more transmit buffers and * it's returning them to us, or we asked the adapter to return the * outstanding transmit buffers by calling RCResetLANCard() with  * RC_RESOURCE_RETURN_PEND_TX_BUFFERS flag.  * All we need to do is free the buffers. */static void RCxmit_callback(U32 Status,                 U16 PcktCount,                 PU32 BufferContext,                 U16 AdapterID){    struct sk_buff *skb;    PDPA pDpa;    struct device *dev;        pDpa = PCIAdapters[AdapterID];        if (!pDpa)        {            printk("rc: Fatal error: xmit callback, !pDpa\n");            return;        }        dev = pDpa->dev;        // printk("xmit_callback: Status = 0x%x\n", (uint)Status);        if (Status != I2O_REPLY_STATUS_SUCCESS)        {            printk("rc: xmit_callback: Status = 0x%x\n", (uint)Status);        }#ifdef RCDEBUG        if (pDpa->shutdown || pDpa->reboot)            printk("rc: xmit callback: shutdown||reboot\n");#endif#ifdef RCDEBUG             printk("rc: xmit_callback: PcktCount = %d, BC = 0x%x\n",                (uint)PcktCount, (uint)BufferContext);#endif        while (PcktCount--)        {            skb = (struct sk_buff *)(BufferContext[0]);#ifdef RCDEBUG            printk("rc: skb = 0x%x\n", (uint)skb);#endif            BufferContext++;#ifdef LINUX_2_1            dev_kfree_skb (skb);#else            dev_kfree_skb (skb, FREE_WRITE);#endif        }        dev->tbusy = 0;}static voidRCreset_callback(U32 Status, U32 p1, U32 p2, U16 AdapterID){    PDPA pDpa;    struct device *dev;         pDpa = PCIAdapters[AdapterID];    dev = pDpa->dev;#ifdef RCDEBUG    printk("rc: RCreset_callback Status 0x%x\n", (uint)Status);#endif    /*     * Check to see why we were called.     */    if (pDpa->shutdown)    {        printk("rc: Shutting down interface\n");        pDpa->shutdown = 0;        pDpa->reboot = 0;        MOD_DEC_USE_COUNT;     }    else if (pDpa->reboot)    {        printk("rc: reboot, shutdown adapter\n");        /*         * We don't set any of the flags in RCShutdownLANCard()         * and we don't pass a callback routine to it.         * The adapter will have already initiated the reboot by         * the time the function returns.         */        RCDisableI2OInterrupts(pDpa->id);        RCShutdownLANCard(pDpa->id,0,0,0);        printk("rc: scheduling timer...\n");        init_timer(&pDpa->timer);        pDpa->timer.expires = RUN_AT((40*HZ)/10); /* 4 sec. */        pDpa->timer.data = (unsigned long)dev;        pDpa->timer.function = &rc_timer;    /* timer handler */        add_timer(&pDpa->timer);    }}static voidRCreboot_callback(U32 Status, U32 p1, U32 p2, U16 AdapterID){    PDPA pDpa;        pDpa = PCIAdapters[AdapterID];#ifdef RCDEBUG    printk("rc: RCreboot: rcv buffers outstanding = %d\n",            (uint)pDpa->numOutRcvBuffers);#endif    if (pDpa->shutdown)    {        printk("rc: skipping reboot sequence -- shutdown already initiated\n");        return;    }    pDpa->reboot = 1;    /*     * OK, we reset the adapter and ask it to return all     * outstanding transmit buffers as well as the posted     * receive buffers.  When the adapter is done returning     * those buffers, it will call our RCreset_callback()      * routine.  In that routine, we'll call RCShutdownLANCard()     * to tell the adapter that it's OK to start the reboot and     * schedule a timer callback routine to execute 3 seconds      * later; this routine will reinitialize the adapter at that time.     */    RCResetLANCard(pDpa->id,                    RC_RESOURCE_RETURN_POSTED_RX_BUCKETS |                    RC_RESOURCE_RETURN_PEND_TX_BUFFERS,0,                   (PFNCALLBACK)RCreset_callback);}int broadcast_packet(unsigned char * address){    int i;    for (i=0; i<6; i++)        if (address[i] != 0xff) return 0;    return 1;}/* * RCrecv_callback() *  * The receive packet callback routine.  This is called by * RCProcI2OMsgQ() after the adapter posts buffers which have been * filled (one ethernet packet per buffer). */static voidRCrecv_callback(U32  Status,                 U8   PktCount,                 U32  BucketsRemain,                 PU32 PacketDescBlock,                 U16  AdapterID){    U32 len, count;    PDPA pDpa;    struct sk_buff *skb;    struct device *dev;    singleTCB tcb;    psingleTCB ptcb = &tcb;        pDpa = PCIAdapters[AdapterID];        dev = pDpa->dev;        ptcb->bcount = 1;#ifdef RCDEBUG        printk("rc: RCrecv_callback: 0x%x, 0x%x, 0x%x\n",               (uint)PktCount, (uint)BucketsRemain, (uint)PacketDescBlock);#endif        #ifdef RCDEBUG        if ((pDpa->shutdown || pDpa->reboot) && !Status)            printk("shutdown||reboot && !Status: PktCount = %d\n",PktCount);#endif        if ( (Status != I2O_REPLY_STATUS_SUCCESS) || pDpa->shutdown)        {            /*             * Free whatever buffers the adapter returned, but don't             * pass them to the kernel.             */                        if (!pDpa->shutdown && !pDpa->reboot)                    printk("rc: RCrecv error: status = 0x%x\n", (uint)Status);#ifdef RCDEBUG                else                    printk("rc: Returning %d buffers, status = 0x%x\n",                            PktCount, (uint)Status);#endif            /*             * TO DO: check the nature of the failure and put the adapter in             * failed mode if it's a hard failure.  Send a reset to the adapter             * and free all outstanding memory.             */            if (Status == I2O_REPLY_STATUS_ABORT_NO_DATA_TRANSFER)            {#ifdef RCDEBUG                printk("RCrecv status ABORT NO DATA TRANSFER\n");#endif            }            /* check for reset status: I2O_REPLY_STATUS_ABORT_NO_DATA_TRANSFER */             if (PacketDescBlock)            {                while(PktCount--)                {                    skb = (struct sk_buff *)PacketDescBlock[0];#ifndef LINUX_2_1                    skb->free = 1;                    skb->lock = 0;    #endif#ifdef RCDEBUG                    printk("free skb 0x%p\n", skb);#endif#ifdef LINUX_2_1                    dev_kfree_skb (skb);#else                    dev_kfree_skb(skb, FREE_READ);#endif                    pDpa->numOutRcvBuffers--;                    PacketDescBlock += BD_SIZE; /* point to next context field */                }            }            return;        }        else        {            while(PktCount--)            {                skb = (struct sk_buff *)PacketDescBlock[0];#ifdef RCDEBUG                if (pDpa->shutdown)                    printk("shutdown: skb=0x%x\n", (uint)skb);                printk("skb = 0x%x: 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x\n", (uint)skb,                       (uint)skb->data[0], (uint)skb->data[1], (uint)skb->data[2],                       (uint)skb->data[3], (uint)skb->data[4], (uint)skb->data[5]);#endif#ifdef PROMISCUOUS_BY_DEFAULT   /* early 2.x firmware */                if ( (memcmp(dev->dev_addr, skb->data, 6)) &&                     (!broadcast_packet(skb->data)))                {                    /*                     * Re-post the buffer to the adapter.  Since the adapter usually                     * return 1 to 2 receive buffers at a time, it's not too inefficient                     * post one buffer at a time but ... may be that should be                      * optimized at some point.                     */                    ptcb->b.context = (U32)skb;                        ptcb->b.scount = 1;                    ptcb->b.size = MAX_ETHER_SIZE;                    ptcb->b.addr = virt_to_bus((void *)skb->data);                    if ( RCPostRecvBuffers(pDpa->id, (PRCTCB)ptcb ) != RC_RTN_NO_ERROR)                    {                        printk("rc: RCrecv_callback: post buffer failed!\n");#ifdef LINUX_2_1                        dev_kfree_skb (skb);#else                        skb->free = 1;                        dev_kfree_skb(skb, FREE_READ);#endif                    }                    else                    {                        pDpa->numOutRcvBuffers++;                    }                }                else#endif /* PROMISCUOUS_BY_DEFAULT */                {                    len = PacketDescBlock[2];                    skb->dev = dev;                    skb_put( skb, len ); /* adjust length and tail */                    skb->protocol = eth_type_trans(skb, dev);                    netif_rx(skb);    /* send the packet to the kernel */                    dev->last_rx = jiffies;                }                pDpa->numOutRcvBuffers--;                PacketDescBlock += BD_SIZE; /* point to next context field */            }        }             /*         * Replenish the posted receive buffers.          * DO NOT replenish buffers if the driver has already         * initiated a reboot or shutdown!         */        if (!pDpa->shutdown && !pDpa->reboot)        {            count = RC_allocate_and_post_buffers(dev,                                                  MAX_NMBR_RCV_BUFFERS-pDpa->numOutRcvBuffers);            pDpa->numOutRcvBuffers += count;        }}/* * RCinterrupt() *  * Interrupt handler.  * This routine sets up a couple of pointers and calls * RCProcI2OMsgQ(), which in turn process the message and * calls one of our callback functions. */static void RCinterrupt(int irq, void *dev_id, struct pt_regs *regs){    PDPA pDpa;    struct device *dev = (struct device *)(dev_id);    pDpa = (PDPA) (dev->priv);     #ifdef RCDEBUG    if (pDpa->shutdown)        printk("rc: shutdown: service irq\n");    printk("RC irq: pDpa = 0x%x, dev = 0x%x, id = %d\n",            (uint)pDpa, (uint)dev, (uint)pDpa->id);    printk("dev = 0x%x\n", (uint)dev);#endif    if (dev->interrupt)        printk("%s: Re-entering the interrupt handler.\n", dev->name);    dev->interrupt = 1;    RCProcI2OMsgQ(pDpa->id);    dev->interrupt = 0;    return;}#define REBOOT_REINIT_RETRY_LIMIT 4static void rc_timer(unsigned long data){    struct device *dev = (struct device *)data;    PDPA pDpa = (PDPA) (dev->priv);    int init_status;    static int retry = 0;    int post_buffers = MAX_NMBR_RCV_BUFFERS;    int count = 0;    int requested = 0;    if (pDpa->reboot)    {        init_status = RCInitI2OMsgLayer(pDpa->id, dev->base_addr,                                     pDpa->PLanApiPA,                                     (PU8)virt_to_bus((void *)pDpa->PLanApiPA),                                    (PFNTXCALLBACK)RCxmit_callback,                                    (PFNRXCALLBACK)RCrecv_callback,                                    (PFNCALLBACK)RCreboot_callback);        switch(init_status)        {        case RC_RTN_NO_ERROR:             pDpa->reboot = 0;            pDpa->shutdown = 0;        /* just in case */            RCReportDriverCapability(pDpa->id, DriverControlWord);            RCEnableI2OInterrupts(pDpa->id);            if (dev->flags & IFF_UP)            {                while(post_buffers)                {                    if (post_buffers > MAX_NMBR_POST_BUFFERS_PER_MSG)                        requested = MAX_NMBR_POST_BUFFERS_PER_MSG;                    else                        requested = post_buffers;                    count = RC_allocate_and_post_buffers(dev, requested);                    post_buffers -= count;

⌨️ 快捷键说明

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