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

📄 com90xx.c

📁 powerpc内核mpc8241linux系统下net驱动程序
💻 C
📖 第 1 页 / 共 3 页
字号:
					lp->stats.tx_errors++;					lp->stats.tx_carrier_errors++;				} else {					BUGMSG(D_DURING, "broadcast was not acknowledged; that's normal (status=%Xh, dest=%02Xh)\n",					       status,					       lp->lasttrans_dest);				}			}			/* send packet if there is one */			arcnet_go_tx(dev, 0);			didsomething++;			if (lp->intx) {				BUGMSG(D_DURING, "TXDONE while intx! (status=%Xh, intx=%d)\n",				       ARCSTATUS, lp->intx);				lp->in_txhandler--;				continue;			}			if (!lp->outgoing.skb) {				BUGMSG(D_DURING, "TX IRQ done: no split to continue.\n");				/* inform upper layers */				if (!lp->txready)					arcnet_tx_done(dev, lp);				lp->in_txhandler--;				continue;			}			/* if more than one segment, and not all segments			 * are done, then continue xmit.			 */			if (out->segnum < out->numsegs)				arcnetA_continue_tx(dev);			arcnet_go_tx(dev, 0);			/* if segnum==numsegs, the transmission is finished;			 * free the skb.			 */			if (out->segnum >= out->numsegs) {				/* transmit completed */				out->segnum++;				if (out->skb) {					lp->stats.tx_bytes += out->skb->len;					dev_kfree_skb(out->skb);				}				out->skb = NULL;				/* inform upper layers */				if (!lp->txready)					arcnet_tx_done(dev, lp);			}			didsomething++;			lp->in_txhandler--;		} else if (lp->txready && !lp->sending && !lp->intx) {			BUGMSG(D_NORMAL, "recovery from silent TX (status=%Xh)\n",			       status);			arcnet_go_tx(dev, 0);			didsomething++;		}#ifdef DETECT_RECONFIGS		if (status & (lp->intmask) & RECONflag) {			ACOMMAND(CFLAGScmd | CONFIGclear);			lp->stats.tx_carrier_errors++;#ifdef SHOW_RECONFIGS			BUGMSG(D_NORMAL, "Network reconfiguration detected (status=%Xh)\n",			       status);#endif				/* SHOW_RECONFIGS */#ifdef RECON_THRESHOLD			/* is the RECON info empty or old? */			if (!lp->first_recon || !lp->last_recon ||			    jiffies - lp->last_recon > HZ * 10) {				if (lp->network_down)					BUGMSG(D_NORMAL, "reconfiguration detected: cabling restored?\n");				lp->first_recon = lp->last_recon = jiffies;				lp->num_recons = lp->network_down = 0;				BUGMSG(D_DURING, "recon: clearing counters.\n");			} else {	/* add to current RECON counter */				lp->last_recon = jiffies;				lp->num_recons++;				BUGMSG(D_DURING, "recon: counter=%d, time=%lds, net=%d\n",				       lp->num_recons,				 (lp->last_recon - lp->first_recon) / HZ,				       lp->network_down);				/* if network is marked up;				 * and first_recon and last_recon are 60+ sec				 *   apart;				 * and the average no. of recons counted is				 *   > RECON_THRESHOLD/min;				 * then print a warning message.				 */				if (!lp->network_down				    && (lp->last_recon - lp->first_recon) <= HZ * 60				  && lp->num_recons >= RECON_THRESHOLD) {					lp->network_down = 1;					BUGMSG(D_NORMAL, "many reconfigurations detected: cabling problem?\n");				} else if (!lp->network_down					   && lp->last_recon - lp->first_recon > HZ * 60) {					/* reset counters if we've gone for					 * over a minute.					 */					lp->first_recon = lp->last_recon;					lp->num_recons = 1;				}			}		} else if (lp->network_down && jiffies - lp->last_recon > HZ * 10) {			if (lp->network_down)				BUGMSG(D_NORMAL, "cabling restored?\n");			lp->first_recon = lp->last_recon = 0;			lp->num_recons = lp->network_down = 0;			BUGMSG(D_DURING, "not recon: clearing counters anyway.\n");#endif		}#endif				/* DETECT_RECONFIGS */	} while (--boguscount && didsomething);	BUGMSG(D_DURING, "net_interrupt complete (status=%Xh, count=%d)\n",	       ARCSTATUS, boguscount);	BUGMSG(D_DURING, "\n");	SETMASK;		/* put back interrupt mask */}/* A packet has arrived; grab it from the buffers and pass it to the generic * arcnet_rx routing to deal with it. */static void arc90xx_rx(struct device *dev, int recbuf){	struct arcnet_local *lp = (struct arcnet_local *) dev->priv;	int ioaddr = dev->base_addr;	union ArcPacket *arcpacket =	(union ArcPacket *) phys_to_virt(dev->mem_start + recbuf * 512);	u_char *arcsoft;	short length, offset;	u_char daddr, saddr;	lp->stats.rx_packets++;	saddr = arcpacket->hardheader.source;	/* if source is 0, it's a "used" packet! */	if (saddr == 0) {		BUGMSG(D_NORMAL, "discarding old packet. (status=%Xh)\n",		       ARCSTATUS);		lp->stats.rx_errors++;		return;	}	/* Set source address to zero to mark it as old */	arcpacket->hardheader.source = 0;	daddr = arcpacket->hardheader.destination;	if (arcpacket->hardheader.offset1) {	/* Normal Packet */		offset = arcpacket->hardheader.offset1;		arcsoft = &arcpacket->raw[offset];		length = 256 - offset;	} else {		/* ExtendedPacket or ExceptionPacket */		offset = arcpacket->hardheader.offset2;		arcsoft = &arcpacket->raw[offset];		length = 512 - offset;	}	arcnet_rx(lp, arcsoft, length, saddr, daddr);	BUGLVL(D_RX) arcnet_dump_packet(lp->adev, arcpacket->raw, length > 240, "rx");#ifndef SLOW_XMIT_COPY	/* clean out the page to make debugging make more sense :) */	BUGLVL(D_DURING)	    memset((void *) arcpacket->raw, 0x42, 512);#endif}/* Given an skb, copy a packet into the ARCnet buffers for later transmission * by arcnet_go_tx. */static void arc90xx_prepare_tx(struct device *dev, u_char * hdr, int hdrlen,	      char *data, int length, int daddr, int exceptA, int offset){	struct arcnet_local *lp = (struct arcnet_local *) dev->priv;	union ArcPacket *arcpacket =	(union ArcPacket *) phys_to_virt(dev->mem_start + 512 * (lp->txbuf ^ 1));#ifdef SLOW_XMIT_COPY	char *iptr, *iend, *optr;#endif	lp->txbuf = lp->txbuf ^ 1;	/* XOR with 1 to alternate between 2 and 3 */	length += hdrlen;	BUGMSG(D_TX, "arcnetAS_prep_tx: hdr:%ph, length:%d, data:%ph\n",	       hdr, length, data);#ifndef SLOW_XMIT_COPY	/* clean out the page to make debugging make more sense :) */	BUGLVL(D_DURING)	    memset_io(dev->mem_start + lp->txbuf * 512, 0x42, 512);#endif	arcpacket->hardheader.destination = daddr;	/* load packet into shared memory */	if (length <= MTU)	/* Normal (256-byte) Packet */		arcpacket->hardheader.offset1 = offset = offset ? offset : 256 - length;	else if (length >= MinTU || offset) {	/* Extended (512-byte) Packet */		arcpacket->hardheader.offset1 = 0;		arcpacket->hardheader.offset2 = offset = offset ? offset : 512 - length;	} else if (exceptA) {	/* RFC1201 Exception Packet */		arcpacket->hardheader.offset1 = 0;		arcpacket->hardheader.offset2 = offset = 512 - length - 4;		/* exception-specific stuff - these four bytes		 * make the packet long enough to fit in a 512-byte		 * frame.		 */		arcpacket->raw[offset + 0] = hdr[0];		arcpacket->raw[offset + 1] = 0xFF;	/* FF flag */		arcpacket->raw[offset + 2] = 0xFF;	/* FF padding */		arcpacket->raw[offset + 3] = 0xFF;	/* FF padding */		offset += 4;	} else {		/* "other" Exception packet */		/* RFC1051 - set 4 trailing bytes to 0 */		memset(&arcpacket->raw[508], 0, 4);		/* now round up to MinTU */		arcpacket->hardheader.offset1 = 0;		arcpacket->hardheader.offset2 = offset = 512 - MinTU;	}	/* copy the packet into ARCnet shmem	 *  - the first bytes of ClientData header are skipped	 */	memcpy((u_char *) arcpacket + offset, (u_char *) hdr, hdrlen);#ifdef SLOW_XMIT_COPY	for (iptr = data, iend = iptr + length - hdrlen, optr = (char *) arcpacket + offset + hdrlen;	     iptr < iend; iptr++, optr++) {		*optr = *iptr;		/*udelay(5); */	}#else	memcpy((u_char *) arcpacket + offset + hdrlen, data, length - hdrlen);#endif	BUGMSG(D_DURING, "transmitting packet to station %02Xh (%d bytes)\n",	       daddr, length);	BUGLVL(D_TX) arcnet_dump_packet(dev, arcpacket->raw, length > MTU, "tx");	lp->lastload_dest = daddr;	lp->txready = lp->txbuf;	/* packet is ready for sending */}/**************************************************************************** *                                                                          * * Kernel Loadable Module Support                                           * *                                                                          * ****************************************************************************/#ifdef MODULEstatic char devicename[9] = "";static struct device thiscard ={	devicename,		/* device name is inserted by linux/drivers/net/net_init.c */	0, 0, 0, 0,	0, 0,			/* I/O address, IRQ */	0, 0, 0, NULL, arc90xx_probe};int init_module(void){	struct device *dev = &thiscard;	if (device)		strcpy(dev->name, device);	else		arcnet_makename(dev->name);	dev->base_addr = io;	dev->irq = irq;	if (dev->irq == 2)		dev->irq = 9;	if (shmem) {		dev->mem_start = shmem;		dev->mem_end = thiscard.mem_start + 512 * 4 - 1;		dev->rmem_start = thiscard.mem_start + 512 * 0;		dev->rmem_end = thiscard.mem_start + 512 * 2 - 1;	}	if (register_netdev(dev) != 0)		return -EIO;	arcnet_use_count(1);	return 0;}void cleanup_module(void){	struct device *dev = &thiscard;	int ioaddr = dev->mem_start;	if (dev->start)		(*dev->stop) (dev);	/* Flush TX and disable RX */	if (ioaddr) {		AINTMASK(0);	/* disable IRQ's */		ACOMMAND(NOTXcmd);	/* stop transmit */		ACOMMAND(NORXcmd);	/* disable receive */#if defined(IO_MAPPED_BUFFERS) && !defined(COM20020)		/* Set the thing back to MMAP mode, in case the old		   driver is loaded later */		outb((inb(_CONFIG) & ~IOMAPflag), _CONFIG);#endif	}	if (dev->irq) {		free_irq(dev->irq, dev);	}	if (dev->base_addr)		release_region(dev->base_addr, ARCNET_TOTAL_SIZE);	unregister_netdev(dev);	kfree(dev->priv);	dev->priv = NULL;	arcnet_use_count(0);}#else__initfunc(void com90xx_setup(char *str, int *ints)){	struct device *dev;	if (arcnet_num_devs == MAX_ARCNET_DEVS) {		printk("com90xx: Too many ARCnet devices registered (max %d).\n",		       MAX_ARCNET_DEVS);		return;	}	if (!ints[0] && (!str || !*str)) {		printk("com90xx: Disabled.\n");		com90xx_explicit++;		return;	}	dev = &arcnet_devs[arcnet_num_devs];	dev->dev_addr[3] = 3;	dev->init = arc90xx_probe;	switch (ints[0]) {	case 4:		/* ERROR */		printk("com20020: Too many arguments.\n");	case 3:		/* Mem address */		dev->mem_start = ints[3];	case 2:		/* IRQ */		dev->irq = ints[2];	case 1:		/* IO address */		dev->base_addr = ints[1];	}	dev->name = (char *) &arcnet_dev_names[arcnet_num_devs];	if (str)		strncpy(dev->name, str, 9);	arcnet_num_devs++;}#endif				/* MODULE */

⌨️ 快捷键说明

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