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

📄 mac8390.c

📁 linux 内核源代码
💻 C
📖 第 1 页 / 共 2 页
字号:
	if (!ndev)		goto out;	err = register_netdev(dev);	if (err)		goto out;	return dev;out:	free_netdev(dev);	return ERR_PTR(err);}#ifdef MODULEMODULE_AUTHOR("David Huggins-Daines <dhd@debian.org> and others");MODULE_DESCRIPTION("Macintosh NS8390-based Nubus Ethernet driver");MODULE_LICENSE("GPL");/* overkill, of course */static struct net_device *dev_mac8390[15];int init_module(void){	int i;	for (i = 0; i < 15; i++) {		struct net_device *dev = mac8390_probe(-1);		if (IS_ERR(dev))			break;		dev_mac890[i] = dev;	}	if (!i) {		printk(KERN_NOTICE "mac8390.c: No useable cards found, driver NOT installed.\n");		return -ENODEV;	}	return 0;}void cleanup_module(void){	int i;	for (i = 0; i < 15; i++) {		struct net_device *dev = dev_mac890[i];		if (dev) {			unregister_netdev(dev);			free_netdev(dev);		}	}}#endif /* MODULE */static int __init mac8390_initdev(struct net_device * dev, struct nubus_dev * ndev,			    enum mac8390_type type){	static u32 fwrd4_offsets[16]={		0,      4,      8,      12,		16,     20,     24,     28,		32,     36,     40,     44,		48,     52,     56,     60	};	static u32 back4_offsets[16]={		60,     56,     52,     48,		44,     40,     36,     32,		28,     24,     20,     16,		12,     8,      4,      0	};	static u32 fwrd2_offsets[16]={		0,      2,      4,      6,		8,     10,     12,     14,		16,    18,     20,     22,		24,    26,     28,     30	};	int access_bitmode = 0;	/* Now fill in our stuff */	dev->open = &mac8390_open;	dev->stop = &mac8390_close;#ifdef CONFIG_NET_POLL_CONTROLLER	dev->poll_controller = __ei_poll;#endif	/* GAR, ei_status is actually a macro even though it looks global */	ei_status.name = cardname[type];	ei_status.word16 = word16[type];	/* Cabletron's TX/RX buffers are backwards */	if (type == MAC8390_CABLETRON) {               ei_status.tx_start_page = CABLETRON_TX_START_PG;               ei_status.rx_start_page = CABLETRON_RX_START_PG;               ei_status.stop_page = CABLETRON_RX_STOP_PG;               ei_status.rmem_start = dev->mem_start;               ei_status.rmem_end = dev->mem_start + CABLETRON_RX_STOP_PG*256;	} else {               ei_status.tx_start_page = WD_START_PG;               ei_status.rx_start_page = WD_START_PG + TX_PAGES;               ei_status.stop_page = (dev->mem_end - dev->mem_start)/256;               ei_status.rmem_start = dev->mem_start + TX_PAGES*256;               ei_status.rmem_end = dev->mem_end;	}	/* Fill in model-specific information and functions */	switch(type) {	case MAC8390_FARALLON:	case MAC8390_APPLE:		switch(mac8390_testio(dev->mem_start)) {			case ACCESS_UNKNOWN:				printk("Don't know how to access card memory!\n");				return -ENODEV;				break;			case ACCESS_16:				/* 16 bit card, register map is reversed */				ei_status.reset_8390 = &mac8390_no_reset;				ei_status.block_input = &slow_sane_block_input;				ei_status.block_output = &slow_sane_block_output;				ei_status.get_8390_hdr = &slow_sane_get_8390_hdr;				ei_status.reg_offset = back4_offsets;				break;			case ACCESS_32:				/* 32 bit card, register map is reversed */				ei_status.reset_8390 = &mac8390_no_reset;				ei_status.block_input = &sane_block_input;				ei_status.block_output = &sane_block_output;				ei_status.get_8390_hdr = &sane_get_8390_hdr;				ei_status.reg_offset = back4_offsets;				access_bitmode = 1;				break;		}		break;	case MAC8390_ASANTE:		/* Some Asante cards pass the 32 bit test		 * but overwrite system memory when run at 32 bit.		 * so we run them all at 16 bit.		 */		ei_status.reset_8390 = &mac8390_no_reset;		ei_status.block_input = &slow_sane_block_input;		ei_status.block_output = &slow_sane_block_output;		ei_status.get_8390_hdr = &slow_sane_get_8390_hdr;		ei_status.reg_offset = back4_offsets;		break;	case MAC8390_CABLETRON:		/* 16 bit card, register map is short forward */		ei_status.reset_8390 = &mac8390_no_reset;		ei_status.block_input = &slow_sane_block_input;		ei_status.block_output = &slow_sane_block_output;		ei_status.get_8390_hdr = &slow_sane_get_8390_hdr;		ei_status.reg_offset = fwrd2_offsets;		break;	case MAC8390_DAYNA:	case MAC8390_KINETICS:		/* 16 bit memory, register map is forward */		/* dayna and similar */		ei_status.reset_8390 = &mac8390_no_reset;		ei_status.block_input = &dayna_block_input;		ei_status.block_output = &dayna_block_output;		ei_status.get_8390_hdr = &dayna_get_8390_hdr;		ei_status.reg_offset = fwrd4_offsets;		break;	case MAC8390_INTERLAN:		/* 16 bit memory, register map is forward */		ei_status.reset_8390 = &interlan_reset;		ei_status.block_input = &slow_sane_block_input;		ei_status.block_output = &slow_sane_block_output;		ei_status.get_8390_hdr = &slow_sane_get_8390_hdr;	        ei_status.reg_offset = fwrd4_offsets;	        break;	default:		printk(KERN_ERR "Card type %s is unsupported, sorry\n", ndev->board->name);		return -ENODEV;	}	__NS8390_init(dev, 0);	/* Good, done, now spit out some messages */	printk(KERN_INFO "%s: %s in slot %X (type %s)\n",		   dev->name, ndev->board->name, ndev->board->slot, cardname[type]);	printk(KERN_INFO "MAC ");	{		int i;		for (i = 0; i < 6; i++) {			printk("%2.2x", dev->dev_addr[i]);			if (i < 5)				printk(":");		}	}	printk(" IRQ %d, %d KB shared memory at %#lx,  %d-bit access.\n",		   dev->irq, (int)((dev->mem_end - dev->mem_start)/0x1000) * 4,		   dev->mem_start, access_bitmode?32:16);	return 0;}static int mac8390_open(struct net_device *dev){	__ei_open(dev);	if (request_irq(dev->irq, __ei_interrupt, 0, "8390 Ethernet", dev)) {		printk ("%s: unable to get IRQ %d.\n", dev->name, dev->irq);		return -EAGAIN;	}	return 0;}static int mac8390_close(struct net_device *dev){	free_irq(dev->irq, dev);	__ei_close(dev);	return 0;}static void mac8390_no_reset(struct net_device *dev){	ei_status.txing = 0;	if (ei_debug > 1)		printk("reset not supported\n");	return;}static void interlan_reset(struct net_device *dev){	unsigned char *target=nubus_slot_addr(IRQ2SLOT(dev->irq));	if (ei_debug > 1)		printk("Need to reset the NS8390 t=%lu...", jiffies);	ei_status.txing = 0;	target[0xC0000] = 0;	if (ei_debug > 1)		printk("reset complete\n");	return;}/* dayna_memcpy_fromio/dayna_memcpy_toio *//* directly from daynaport.c by Alan Cox */static void dayna_memcpy_fromcard(struct net_device *dev, void *to, int from, int count){	volatile unsigned char *ptr;	unsigned char *target=to;	from<<=1;	/* word, skip overhead */	ptr=(unsigned char *)(dev->mem_start+from);	/* Leading byte? */	if (from&2) {		*target++ = ptr[-1];		ptr += 2;		count--;	}	while(count>=2)	{		*(unsigned short *)target = *(unsigned short volatile *)ptr;		ptr += 4;			/* skip cruft */		target += 2;		count-=2;	}	/* Trailing byte? */	if(count)		*target = *ptr;}static void dayna_memcpy_tocard(struct net_device *dev, int to, const void *from, int count){	volatile unsigned short *ptr;	const unsigned char *src=from;	to<<=1;	/* word, skip overhead */	ptr=(unsigned short *)(dev->mem_start+to);	/* Leading byte? */	if (to&2) { /* avoid a byte write (stomps on other data) */		ptr[-1] = (ptr[-1]&0xFF00)|*src++;		ptr++;		count--;	}	while(count>=2)	{		*ptr++=*(unsigned short *)src;		/* Copy and */		ptr++;			/* skip cruft */		src += 2;		count-=2;	}	/* Trailing byte? */	if(count)	{		/* card doesn't like byte writes */		*ptr=(*ptr&0x00FF)|(*src << 8);	}}/* sane block input/output */static void sane_get_8390_hdr(struct net_device *dev,			      struct e8390_pkt_hdr *hdr, int ring_page){	unsigned long hdr_start = (ring_page - WD_START_PG)<<8;	memcpy_fromio((void *)hdr, (char *)dev->mem_start + hdr_start, 4);	/* Fix endianness */	hdr->count = swab16(hdr->count);}static void sane_block_input(struct net_device *dev, int count,			     struct sk_buff *skb, int ring_offset){	unsigned long xfer_base = ring_offset - (WD_START_PG<<8);	unsigned long xfer_start = xfer_base + dev->mem_start;	if (xfer_start + count > ei_status.rmem_end) {		/* We must wrap the input move. */		int semi_count = ei_status.rmem_end - xfer_start;		memcpy_fromio(skb->data, (char *)dev->mem_start + xfer_base, semi_count);		count -= semi_count;		memcpy_toio(skb->data + semi_count, (char *)ei_status.rmem_start, count);	} else {		memcpy_fromio(skb->data, (char *)dev->mem_start + xfer_base, count);	}}static void sane_block_output(struct net_device *dev, int count,			      const unsigned char *buf, int start_page){	long shmem = (start_page - WD_START_PG)<<8;	memcpy_toio((char *)dev->mem_start + shmem, buf, count);}/* dayna block input/output */static void dayna_get_8390_hdr(struct net_device *dev, struct e8390_pkt_hdr *hdr, int ring_page){	unsigned long hdr_start = (ring_page - WD_START_PG)<<8;	dayna_memcpy_fromcard(dev, (void *)hdr, hdr_start, 4);	/* Fix endianness */	hdr->count=(hdr->count&0xFF)<<8|(hdr->count>>8);}static void dayna_block_input(struct net_device *dev, int count, struct sk_buff *skb, int ring_offset){	unsigned long xfer_base = ring_offset - (WD_START_PG<<8);	unsigned long xfer_start = xfer_base+dev->mem_start;	/* Note the offset math is done in card memory space which is word	   per long onto our space. */	if (xfer_start + count > ei_status.rmem_end)	{		/* We must wrap the input move. */		int semi_count = ei_status.rmem_end - xfer_start;		dayna_memcpy_fromcard(dev, skb->data, xfer_base, semi_count);		count -= semi_count;		dayna_memcpy_fromcard(dev, skb->data + semi_count,				      ei_status.rmem_start - dev->mem_start,				      count);	}	else	{		dayna_memcpy_fromcard(dev, skb->data, xfer_base, count);	}}static void dayna_block_output(struct net_device *dev, int count, const unsigned char *buf,				int start_page){	long shmem = (start_page - WD_START_PG)<<8;	dayna_memcpy_tocard(dev, shmem, buf, count);}/* Cabletron block I/O */static void slow_sane_get_8390_hdr(struct net_device *dev, struct e8390_pkt_hdr *hdr,	int ring_page){	unsigned long hdr_start = (ring_page - WD_START_PG)<<8;	word_memcpy_fromcard((void *)hdr, (char *)dev->mem_start+hdr_start, 4);	/* Register endianism - fix here rather than 8390.c */	hdr->count = (hdr->count&0xFF)<<8|(hdr->count>>8);}static void slow_sane_block_input(struct net_device *dev, int count, struct sk_buff *skb,	int ring_offset){	unsigned long xfer_base = ring_offset - (WD_START_PG<<8);	unsigned long xfer_start = xfer_base+dev->mem_start;	if (xfer_start + count > ei_status.rmem_end)	{		/* We must wrap the input move. */		int semi_count = ei_status.rmem_end - xfer_start;		word_memcpy_fromcard(skb->data, (char *)dev->mem_start +			xfer_base, semi_count);		count -= semi_count;		word_memcpy_fromcard(skb->data + semi_count,				     (char *)ei_status.rmem_start, count);	}	else	{		word_memcpy_fromcard(skb->data, (char *)dev->mem_start +			xfer_base, count);	}}static void slow_sane_block_output(struct net_device *dev, int count, const unsigned char *buf,	int start_page){	long shmem = (start_page - WD_START_PG)<<8;	word_memcpy_tocard((char *)dev->mem_start + shmem, buf, count);}static void word_memcpy_tocard(void *tp, const void *fp, int count){	volatile unsigned short *to = tp;	const unsigned short *from = fp;	count++;	count/=2;	while(count--)		*to++=*from++;}static void word_memcpy_fromcard(void *tp, const void *fp, int count){	unsigned short *to = tp;	const volatile unsigned short *from = fp;	count++;	count/=2;	while(count--)		*to++=*from++;}

⌨️ 快捷键说明

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