📄 rcpci45.c
字号:
if ( count < requested ) break; } pDpa->numOutRcvBuffers = MAX_NMBR_RCV_BUFFERS - post_buffers; printk("rc: posted %d buffers \r\n", (uint)pDpa->numOutRcvBuffers); } printk("rc: Initialization done.\n"); dev->tbusy=0; retry=0; return; case RC_RTN_FREE_Q_EMPTY: retry++; printk("rc: inbound free q empty\n"); break; default: retry++; printk("rc: bad status after reboot: %d\n", init_status); break; } if (retry > REBOOT_REINIT_RETRY_LIMIT) { printk("rc: unable to reinitialize adapter after reboot\n"); printk("rc: decrementing driver and closing interface\n"); RCDisableI2OInterrupts(pDpa->id); dev->flags &= ~IFF_UP; MOD_DEC_USE_COUNT; } else { printk("rc: rescheduling timer...\n"); init_timer(&pDpa->timer); pDpa->timer.expires = RUN_AT((40*HZ)/10); /* 3 sec. */ pDpa->timer.data = (unsigned long)dev; pDpa->timer.function = &rc_timer; /* timer handler */ add_timer(&pDpa->timer); } } else { printk("rc: timer??\n"); }}static intRCclose(struct device *dev){ PDPA pDpa = (PDPA) dev->priv;#ifdef RCDEBUG printk("rc: RCclose\r\n");#endif if (pDpa->reboot) { printk("rc: skipping reset -- adapter already in reboot mode\n"); dev->flags &= ~IFF_UP; pDpa->shutdown = 1; return 0; }#ifdef RCDEBUG printk("rc: receive buffers outstanding: %d\n", (uint)pDpa->numOutRcvBuffers);#endif pDpa->shutdown = 1; /* * We can't allow the driver to be unloaded until the adapter returns * all posted receive buffers. It doesn't hurt to tell the adapter * to return all posted receive buffers and outstanding xmit buffers, * even if there are none. */ RCShutdownLANCard(pDpa->id, RC_RESOURCE_RETURN_POSTED_RX_BUCKETS | RC_RESOURCE_RETURN_PEND_TX_BUFFERS,0, (PFNCALLBACK)RCreset_callback); dev->flags &= ~IFF_UP; return 0;}static struct enet_statistics *RCget_stats(struct device *dev){ RCLINKSTATS RCstats; PDPA pDpa = dev->priv; if (!pDpa) { printk("rc: RCget_stats: !pDpa\n"); return 0; } else if (!(dev->flags & IFF_UP)) {#ifdef RCDEBUG printk("rc: RCget_stats: device down\n");#endif return 0; } memset(&RCstats, 0, sizeof(RCLINKSTATS)); if ( (RCGetLinkStatistics(pDpa->id, &RCstats, (void *)0)) == RC_RTN_NO_ERROR ) {#ifdef RCDEBUG printk("rc: TX_good 0x%x\n", (uint)RCstats.TX_good); printk("rc: TX_maxcol 0x%x\n", (uint)RCstats.TX_maxcol); printk("rc: TX_latecol 0x%x\n", (uint)RCstats.TX_latecol); printk("rc: TX_urun 0x%x\n", (uint)RCstats.TX_urun); printk("rc: TX_crs 0x%x\n", (uint)RCstats.TX_crs); printk("rc: TX_def 0x%x\n", (uint)RCstats.TX_def); printk("rc: TX_singlecol 0x%x\n", (uint)RCstats.TX_singlecol); printk("rc: TX_multcol 0x%x\n", (uint)RCstats.TX_multcol); printk("rc: TX_totcol 0x%x\n", (uint)RCstats.TX_totcol); printk("rc: Rcv_good 0x%x\n", (uint)RCstats.Rcv_good); printk("rc: Rcv_CRCerr 0x%x\n", (uint)RCstats.Rcv_CRCerr); printk("rc: Rcv_alignerr 0x%x\n", (uint)RCstats.Rcv_alignerr); printk("rc: Rcv_reserr 0x%x\n", (uint)RCstats.Rcv_reserr); printk("rc: Rcv_orun 0x%x\n", (uint)RCstats.Rcv_orun); printk("rc: Rcv_cdt 0x%x\n", (uint)RCstats.Rcv_cdt); printk("rc: Rcv_runt 0x%x\n", (uint)RCstats.Rcv_runt);#endif pDpa->stats.rx_packets = RCstats.Rcv_good; /* total packets received */ pDpa->stats.tx_packets = RCstats.TX_good; /* total packets transmitted */ pDpa->stats.rx_errors = RCstats.Rcv_CRCerr + RCstats.Rcv_alignerr + RCstats.Rcv_reserr + RCstats.Rcv_orun + RCstats.Rcv_cdt + RCstats.Rcv_runt; /* bad packets received */ pDpa->stats.tx_errors = RCstats.TX_urun + RCstats.TX_crs + RCstats.TX_def + RCstats.TX_totcol; /* packet transmit problems */ /* * This needs improvement. */ pDpa->stats.rx_dropped = 0; /* no space in linux buffers */ pDpa->stats.tx_dropped = 0; /* no space available in linux */ pDpa->stats.multicast = 0; /* multicast packets received */ pDpa->stats.collisions = RCstats.TX_totcol; /* detailed rx_errors: */ pDpa->stats.rx_length_errors = 0; pDpa->stats.rx_over_errors = RCstats.Rcv_orun; /* receiver ring buff overflow */ pDpa->stats.rx_crc_errors = RCstats.Rcv_CRCerr; /* recved pkt with crc error */ pDpa->stats.rx_frame_errors = 0; /* recv'd frame alignment error */ pDpa->stats.rx_fifo_errors = 0; /* recv'r fifo overrun */ pDpa->stats.rx_missed_errors = 0; /* receiver missed packet */ /* detailed tx_errors */ pDpa->stats.tx_aborted_errors = 0; pDpa->stats.tx_carrier_errors = 0; pDpa->stats.tx_fifo_errors = 0; pDpa->stats.tx_heartbeat_errors = 0; pDpa->stats.tx_window_errors = 0; return ((struct enet_statistics *)&(pDpa->stats)); } return 0;}static int RCioctl(struct device *dev, struct ifreq *rq, int cmd){ RCuser_struct RCuser; PDPA pDpa = dev->priv;#if RCDEBUG printk("RCioctl: cmd = 0x%x\n", cmd);#endif switch (cmd) { case RCU_PROTOCOL_REV: /* * Assign user protocol revision, to tell user-level * controller program whether or not it's in sync. */ rq->ifr_ifru.ifru_data = (caddr_t) USER_PROTOCOL_REV; break; case RCU_COMMAND: {#ifdef LINUX_2_1 if(copy_from_user(&RCuser, rq->ifr_data, sizeof(RCuser))) return -EFAULT;#else int error; error=verify_area(VERIFY_WRITE, rq->ifr_data, sizeof(RCuser)); if (error) { return error; } memcpy_fromfs(&RCuser, rq->ifr_data, sizeof(RCuser));#endif #ifdef RCDEBUG printk("RCioctl: RCuser_cmd = 0x%x\n", RCuser.cmd);#endif switch(RCuser.cmd) { case RCUC_GETFWVER: printk("RC GETFWVER\n"); RCUD_GETFWVER = &RCuser.RCUS_GETFWVER; RCGetFirmwareVer(pDpa->id, (PU8) &RCUD_GETFWVER->FirmString, NULL); break; case RCUC_GETINFO: printk("RC GETINFO\n"); RCUD_GETINFO = &RCuser.RCUS_GETINFO; RCUD_GETINFO -> mem_start = dev->base_addr; RCUD_GETINFO -> mem_end = dev->base_addr + 2*32768; RCUD_GETINFO -> base_addr = pDpa->pci_addr; RCUD_GETINFO -> irq = dev->irq; break; case RCUC_GETIPANDMASK: printk("RC GETIPANDMASK\n"); RCUD_GETIPANDMASK = &RCuser.RCUS_GETIPANDMASK; RCGetRavlinIPandMask(pDpa->id, (PU32) &RCUD_GETIPANDMASK->IpAddr, (PU32) &RCUD_GETIPANDMASK->NetMask, NULL); break; case RCUC_GETLINKSTATISTICS: printk("RC GETLINKSTATISTICS\n"); RCUD_GETLINKSTATISTICS = &RCuser.RCUS_GETLINKSTATISTICS; RCGetLinkStatistics(pDpa->id, (P_RCLINKSTATS) &RCUD_GETLINKSTATISTICS->StatsReturn, NULL); break; case RCUC_GETLINKSTATUS: printk("RC GETLINKSTATUS\n"); RCUD_GETLINKSTATUS = &RCuser.RCUS_GETLINKSTATUS; RCGetLinkStatus(pDpa->id, (PU32) &RCUD_GETLINKSTATUS->ReturnStatus, NULL); break; case RCUC_GETMAC: printk("RC GETMAC\n"); RCUD_GETMAC = &RCuser.RCUS_GETMAC; RCGetMAC(pDpa->id, (PU8) &RCUD_GETMAC->mac, NULL); break; case RCUC_GETPROM: printk("RC GETPROM\n"); RCUD_GETPROM = &RCuser.RCUS_GETPROM; RCGetPromiscuousMode(pDpa->id, (PU32) &RCUD_GETPROM->PromMode, NULL); break; case RCUC_GETBROADCAST: printk("RC GETBROADCAST\n"); RCUD_GETBROADCAST = &RCuser.RCUS_GETBROADCAST; RCGetBroadcastMode(pDpa->id, (PU32) &RCUD_GETBROADCAST->BroadcastMode, NULL); break; case RCUC_GETSPEED: printk("RC GETSPEED\n"); if (!(dev->flags & IFF_UP)) { printk("RCioctl, GETSPEED error: interface down\n"); return -ENODATA; } RCUD_GETSPEED = &RCuser.RCUS_GETSPEED; RCGetLinkSpeed(pDpa->id, (PU32) &RCUD_GETSPEED->LinkSpeedCode, NULL); printk("RC speed = 0x%ld\n", RCUD_GETSPEED->LinkSpeedCode); break; case RCUC_SETIPANDMASK: printk("RC SETIPANDMASK\n"); RCUD_SETIPANDMASK = &RCuser.RCUS_SETIPANDMASK; printk ("RC New IP Addr = %d.%d.%d.%d, ", (U8) ((RCUD_SETIPANDMASK->IpAddr) & 0xff), (U8) ((RCUD_SETIPANDMASK->IpAddr >> 8) & 0xff), (U8) ((RCUD_SETIPANDMASK->IpAddr >> 16) & 0xff), (U8) ((RCUD_SETIPANDMASK->IpAddr >> 24) & 0xff)); printk ("RC New Mask = %d.%d.%d.%d\n", (U8) ((RCUD_SETIPANDMASK->NetMask) & 0xff), (U8) ((RCUD_SETIPANDMASK->NetMask >> 8) & 0xff), (U8) ((RCUD_SETIPANDMASK->NetMask >> 16) & 0xff), (U8) ((RCUD_SETIPANDMASK->NetMask >> 24) & 0xff)); RCSetRavlinIPandMask(pDpa->id, (U32) RCUD_SETIPANDMASK->IpAddr, (U32) RCUD_SETIPANDMASK->NetMask); break; case RCUC_SETMAC: printk("RC SETMAC\n"); RCUD_SETMAC = &RCuser.RCUS_SETMAC; printk ("RC New MAC addr = %02X:%02X:%02X:%02X:%02X:%02X\n", (U8) (RCUD_SETMAC->mac[0]), (U8) (RCUD_SETMAC->mac[1]), (U8) (RCUD_SETMAC->mac[2]), (U8) (RCUD_SETMAC->mac[3]), (U8) (RCUD_SETMAC->mac[4]), (U8) (RCUD_SETMAC->mac[5])); RCSetMAC(pDpa->id, (PU8) &RCUD_SETMAC->mac); break; case RCUC_SETSPEED: printk("RC SETSPEED\n"); RCUD_SETSPEED = &RCuser.RCUS_SETSPEED; RCSetLinkSpeed(pDpa->id, (U16) RCUD_SETSPEED->LinkSpeedCode); printk("RC New speed = 0x%d\n", RCUD_SETSPEED->LinkSpeedCode); break; case RCUC_SETPROM: printk("RC SETPROM\n"); RCUD_SETPROM = &RCuser.RCUS_SETPROM; RCSetPromiscuousMode(pDpa->id,(U16)RCUD_SETPROM->PromMode); printk("RC New prom mode = 0x%d\n", RCUD_SETPROM->PromMode); break; case RCUC_SETBROADCAST: printk("RC SETBROADCAST\n"); RCUD_SETBROADCAST = &RCuser.RCUS_SETBROADCAST; RCSetBroadcastMode(pDpa->id,(U16)RCUD_SETBROADCAST->BroadcastMode); printk("RC New broadcast mode = 0x%d\n", RCUD_SETBROADCAST->BroadcastMode); break; default: printk("RC command default\n"); RCUD_DEFAULT = &RCuser.RCUS_DEFAULT; RCUD_DEFAULT -> rc = 0x11223344; break; }#ifdef LINUX_2_1 copy_to_user(rq->ifr_data, &RCuser, sizeof(RCuser));#else memcpy_tofs(rq->ifr_data, &RCuser, sizeof(RCuser));#endif break; } /* RCU_COMMAND */ default: printk("RC default\n"); rq->ifr_ifru.ifru_data = (caddr_t) 0x12345678; break; } return 0;}static int RCconfig(struct device *dev, struct ifmap *map){ /* * To be completed ... */ printk("rc: RCconfig\n"); return 0; if (dev->flags & IFF_UP) /* can't act on a running interface */ return -EBUSY; /* Don't allow changing the I/O address */ if (map->base_addr != dev->base_addr) { printk(KERN_WARNING "RC pci45: Change I/O address not implemented\n"); return -EOPNOTSUPP; } return 0;}#ifdef MODULEvoidcleanup_module(void){ PDPA pDpa; struct device *next;#ifdef RCDEBUG printk("rc: RC cleanup_module\n"); printk("rc: root_RCdev = 0x%x\n", (uint)root_RCdev);#endif while (root_RCdev) { pDpa = (PDPA) root_RCdev->priv;#ifdef RCDEBUG printk("rc: cleanup 0x%08X\n", (uint)root_RCdev);#endif printk("IOP reset: 0x%x\n", RCResetIOP(pDpa->id)); unregister_netdev(root_RCdev); next = pDpa->next; iounmap((unsigned long *)root_RCdev->base_addr); free_irq( root_RCdev->irq, root_RCdev ); kfree(root_RCdev); root_RCdev = next; }}#endifstatic intRC_allocate_and_post_buffers(struct device *dev, int numBuffers){ int i; PDPA pDpa = (PDPA)dev->priv; PU32 p; psingleB pB; struct sk_buff *skb; RC_RETURN status; if (!numBuffers) return 0; else if (numBuffers > MAX_NMBR_POST_BUFFERS_PER_MSG) {#ifdef RCDEBUG printk("rc: Too many buffers requested!\n"); printk("rc: attempting to allocate only 32 buffers\n");#endif numBuffers = 32; } p = (PU32) kmalloc(sizeof(U32) + numBuffers*sizeof(singleB), GFP_ATOMIC);#ifdef RCDEBUG printk("rc: TCB = 0x%x\n", (uint)p);#endif if (!p) { printk("rc: RCopen: unable to allocate TCB\n"); return 0; } p[0] = 0; /* Buffer Count */ pB = (psingleB)((U32)p + sizeof(U32)); /* point to the first buffer */#ifdef RCDEBUG printk("rc: p[0] = 0x%x, p = 0x%x, pB = 0x%x\n", (uint)p[0], (uint)p, (uint)pB); printk("rc: pB = 0x%x\n", (uint)pB);#endif for (i=0; i<numBuffers; i++) { skb = dev_alloc_skb(MAX_ETHER_SIZE+2); if (!skb) { printk("rc: Doh! RCopen: unable to allocate enough skbs!\n"); if (*p != 0) /* did we allocate any buffers at all? */ {#ifdef RCDEBUG printk("rc: will post only %d buffers \n", (uint)(*p));#endif break; } else { kfree(p); /* Free the TCB */ return 0; } }#ifdef RCDEBUG printk("post 0x%x\n", (uint)skb);#endif skb_reserve(skb, 2); /* Align IP on 16 byte boundaries */ pB->context = (U32)skb; pB->scount = 1; /* segment count */ pB->size = MAX_ETHER_SIZE; pB->addr = virt_to_bus((void *)skb->data); p[0]++; pB++; } if ( (status = RCPostRecvBuffers(pDpa->id, (PRCTCB)p )) != RC_RTN_NO_ERROR) { printk("rc: Post buffer failed with error code 0x%x!\n", status); pB = (psingleB)((U32)p + sizeof(U32)); /* point to the first buffer */ while(p[0]) { skb = (struct sk_buff *)pB->context;#ifndef LINUX_2_1 skb->free = 1; #endif#ifdef RCDEBUG printk("rc: freeing 0x%x\n", (uint)skb);#endif#ifdef LINUX_2_1 dev_kfree_skb (skb);#else dev_kfree_skb(skb, FREE_READ);#endif p[0]--; pB++; }#ifdef RCDEBUG printk("rc: freed all buffers, p[0] = %ld\n", p[0]);#endif } kfree(p); return(p[0]); /* return the number of posted buffers */}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -