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

📄 macmace.c

📁 Linux内核源代码 为压缩文件 是<<Linux内核>>一书中的源代码
💻 C
📖 第 1 页 / 共 2 页
字号:
	/* reset the chip */	mace68k_reset(dev);	mp->rx_done = 0;	mace68k_rxdma_reset(dev);	/*	 *	The interrupt is fixed and comes off the PSC.	 */	 	if (request_irq(dev->irq, mace68k_interrupt, 0, "68K MACE", dev))	{		printk(KERN_ERR "MACE: can't get irq %d\n", dev->irq);		return -EAGAIN;	}	/*	 *	Ditto the DMA interrupt.	 */	 	if (request_irq(IRQ_MAC_MACE_DMA, mace68k_dma_intr, 0, "68K MACE DMA",			dev))	{		printk(KERN_ERR "MACE: can't get irq %d\n", IRQ_MAC_MACE_DMA);		return -EAGAIN;	}	/* Activate the Mac DMA engine */	mp->tx_slot = 0;		/* Using register set 0 */	mp->tx_count = 1;		/* 1 Buffer ready for use */	mace68k_txdma_reset(dev);		/* turn it on! */	mb->maccc = mp->maccc;	/* enable all interrupts except receive interrupts */	mb->imr = RCVINT;	return 0;}/* *	Shut down the mace and its interrupt channel */ static int mace68k_close(struct net_device *dev){	struct mace68k_data *mp = (struct mace68k_data *) dev->priv;	volatile struct mace *mb = mp->mace;	/* disable rx and tx */	mb->maccc = 0;	mb->imr = 0xff;		/* disable all intrs */	/* disable rx and tx dma */	mace68k_dma_off(dev);	free_irq(dev->irq, dev);	free_irq(IRQ_MAC_MACE_DMA, dev);	return 0;}static inline void mace68k_set_timeout(struct net_device *dev){	struct mace68k_data *mp = (struct mace68k_data *) dev->priv;	unsigned long flags;	save_flags(flags);	cli();	if (mp->timeout_active)		del_timer(&mp->tx_timeout);	mp->tx_timeout.expires = jiffies + TX_TIMEOUT;	mp->tx_timeout.function = mace68k_tx_timeout;	mp->tx_timeout.data = (unsigned long) dev;	add_timer(&mp->tx_timeout);	mp->timeout_active = 1;	restore_flags(flags);}/* *	Transmit a frame */ static int mace68k_xmit_start(struct sk_buff *skb, struct net_device *dev){	struct mace68k_data *mp = (struct mace68k_data *) dev->priv;	/*	 *	This may need atomic types ???	 */	printk("mace68k_xmit_start: mp->tx_count = %d, dev->tbusy = %d, mp->tx_ring = %p (%p)\n",		mp->tx_count, dev->tbusy,		mp->tx_ring, virt_to_bus(mp->tx_ring));	psc_debug_dump();	if(mp->tx_count == 0)	{		dev->tbusy=1;		mace68k_dma_intr(IRQ_MAC_MACE_DMA, dev, NULL);		return 1;	}	mp->tx_count--;		/*	 *	FIXME:	 *	This is hackish. The memcpy probably isnt needed but	 *	the rules for alignment are not known. Ideally we'd like	 *	to just blast the skb directly to ethernet. We also don't	 *	use the ring properly - just a one frame buffer. That	 *	also requires cache pushes ;).	 */	memcpy((void *)mp->tx_ring, skb, skb->len);	psc_write_long(PSC_ENETWR_ADDR + mp->tx_slot, virt_to_bus(mp->tx_ring));        psc_write_long(PSC_ENETWR_LEN + mp->tx_slot, skb->len);        psc_write_word(PSC_ENETWR_CMD + mp->tx_slot, 0x9800);                       	mp->stats.tx_packets++;	mp->stats.tx_bytes+=skb->len;        dev_kfree_skb(skb);	return 0;}static struct net_device_stats *mace68k_stats(struct net_device *dev){	struct mace68k_data *p = (struct mace68k_data *) dev->priv;	return &p->stats;}/* * CRC polynomial - used in working out multicast filter bits. */#define CRC_POLY	0xedb88320static void mace68k_set_multicast(struct net_device *dev){	struct mace68k_data *mp = (struct mace68k_data *) dev->priv;	volatile struct mace *mb = mp->mace;	int i, j, k, b;	unsigned long crc;	mp->maccc &= ~PROM;	if (dev->flags & IFF_PROMISC)	{		mp->maccc |= PROM;	} else	{		unsigned char multicast_filter[8];		struct dev_mc_list *dmi = dev->mc_list;		if (dev->flags & IFF_ALLMULTI)		{			for (i = 0; i < 8; i++)				multicast_filter[i] = 0xff;		} else		{			for (i = 0; i < 8; i++)				multicast_filter[i] = 0;			for (i = 0; i < dev->mc_count; i++)			{				crc = ~0;				for (j = 0; j < 6; ++j)				{					b = dmi->dmi_addr[j];					for (k = 0; k < 8; ++k)					{						if ((crc ^ b) & 1)							crc = (crc >> 1) ^ CRC_POLY;						else							crc >>= 1;						b >>= 1;					}				}				j = crc >> 26;	/* bit number in multicast_filter */				multicast_filter[j >> 3] |= 1 << (j & 7);				dmi = dmi->next;			}		}#if 0		printk("Multicast filter :");		for (i = 0; i < 8; i++)			printk("%02x ", multicast_filter[i]);		printk("\n");#endif		mb->iac = ADDRCHG | LOGADDR;		while ((mb->iac & ADDRCHG) != 0);				for (i = 0; i < 8; ++i)			mb->ladrf = multicast_filter[i];	}	/* reset maccc */	mb->maccc = mp->maccc;}/* *	Miscellaneous interrupts are handled here. We may end up  *	having to bash the chip on the head for bad errors */ static void mace68k_handle_misc_intrs(struct mace68k_data *mp, int intr){	volatile struct mace *mb = mp->mace;	static int mace68k_babbles, mace68k_jabbers;	if (intr & MPCO)		mp->stats.rx_missed_errors += 256;	mp->stats.rx_missed_errors += mb->mpc;	/* reading clears it */	if (intr & RNTPCO)		mp->stats.rx_length_errors += 256;	mp->stats.rx_length_errors += mb->rntpc;	/* reading clears it */	if (intr & CERR)		++mp->stats.tx_heartbeat_errors;	if (intr & BABBLE)		if (mace68k_babbles++ < 4)			printk(KERN_DEBUG "mace: babbling transmitter\n");	if (intr & JABBER)		if (mace68k_jabbers++ < 4)			printk(KERN_DEBUG "mace: jabbering transceiver\n");}/* *	A transmit error has occured. (We kick the transmit side from *	the DMA completion) */ static void mace68k_xmit_error(struct net_device *dev){	struct mace68k_data *mp = (struct mace68k_data *) dev->priv;	volatile struct mace *mb = mp->mace;	u8 xmtfs, xmtrc;		xmtfs = mb->xmtfs;	xmtrc = mb->xmtrc;		if(xmtfs & XMTSV)	{		if(xmtfs & UFLO)		{			printk("%s: DMA underrun.\n", dev->name);			mp->stats.tx_errors++;			mp->stats.tx_fifo_errors++;			mace68k_reset(dev);		}		if(xmtfs & RTRY)			mp->stats.collisions++;	}				mark_bh(NET_BH);}/* *	A receive interrupt occured. */ static void mace68k_recv_interrupt(struct net_device *dev){//	struct mace68k_data *mp = (struct mace68k_data *) dev->priv;//	volatile struct mace *mb = mp->mace;}/* *	Process the chip interrupt */ static void mace68k_interrupt(int irq, void *dev_id, struct pt_regs *regs){	struct net_device *dev = (struct net_device *) dev_id;	struct mace68k_data *mp = (struct mace68k_data *) dev->priv;	volatile struct mace *mb = mp->mace;	u8 ir;		ir = mb->ir;	mace68k_handle_misc_intrs(mp, ir);		if(ir&XMTINT)		mace68k_xmit_error(dev);	if(ir&RCVINT)		mace68k_recv_interrupt(dev);}static void mace68k_tx_timeout(unsigned long data){//	struct net_device *dev = (struct net_device *) data;//	struct mace68k_data *mp = (struct mace68k_data *) dev->priv;//	volatile struct mace *mb = mp->mace;}/* *	Handle a newly arrived frame */ static void mace_dma_rx_frame(struct net_device *dev, struct mace_frame *mf){	struct mace68k_data *mp = (struct mace68k_data *) dev->priv;	struct sk_buff *skb;	if(mf->status&RS_OFLO)	{		printk("%s: fifo overflow.\n", dev->name);		mp->stats.rx_errors++;		mp->stats.rx_fifo_errors++;	}	if(mf->status&(RS_CLSN|RS_FRAMERR|RS_FCSERR))		mp->stats.rx_errors++;			if(mf->status&RS_CLSN)		mp->stats.collisions++;	if(mf->status&RS_FRAMERR)		mp->stats.rx_frame_errors++;	if(mf->status&RS_FCSERR)		mp->stats.rx_crc_errors++;			skb = dev_alloc_skb(mf->len+2);	if(skb==NULL)	{		mp->stats.rx_dropped++;		return;	}	skb_reserve(skb,2);	memcpy(skb_put(skb, mf->len), mf->data, mf->len);		skb->protocol = eth_type_trans(skb, dev);	netif_rx(skb);	mp->stats.rx_packets++;	mp->stats.rx_bytes+=mf->len;}/* *	The PSC has passed us a DMA interrupt event. */ static void mace68k_dma_intr(int irq, void *dev_id, struct pt_regs *regs){	struct net_device *dev = (struct net_device *) dev_id;	struct mace68k_data *mp = (struct mace68k_data *) dev->priv;#if 0	u32 psc_status;		/* It seems this must be allowed to stabilise ?? */		while((psc_status=psc_read_long(0x0804))!=psc_read_long(0x0804));	/*	 *	Was this an ethernet event ?	 */	 		if(psc_status&0x60000000)	{#endif		/*		 *	Process the read queue		 */		 		u16 psc_status = psc_read_word(PSC_ENETRD_CTL);				printk("mace68k_dma_intr: PSC_ENETRD_CTL = %04X\n", (uint) psc_status);		if (psc_status & 0x2000) {			mace68k_rxdma_reset(dev);			mp->rx_done = 0;		} else if (psc_status & 0x100) {			int left;						psc_write_word(PSC_ENETRD_CMD + mp->rx_slot, 0x1100);			left=psc_read_long(PSC_ENETRD_LEN + mp->rx_slot);			/* read packets */							while(mp->rx_done < left)			{				struct mace_frame *mf=((struct mace_frame *)					mp->rx_ring)+mp->rx_done++;				mace_dma_rx_frame(dev, mf);			}						if(left == 0)	/* Out of DMA room */			{				psc_load_rxdma_base(mp->rx_slot, 					(void *)virt_to_phys(mp->rx_ring));				mp->rx_slot^=16;				mp->rx_done = 0;			}			else			{				psc_write_word(PSC_ENETRD_CMD+mp->rx_slot,					0x9800);			}							}				/*		 *	Process the write queue		 */		 		psc_status = psc_read_word(PSC_ENETWR_CTL);		printk("mace68k_dma_intr: PSC_ENETWR_CTL = %04X\n", (uint) psc_status);		/* apple's driver seems to loop over this until neither */		/* condition is true.    - jmt                          */		if (psc_status & 0x2000) {			mace68k_txdma_reset(dev);		} else if (psc_status & 0x0100) {			psc_write_word(PSC_ENETWR_CMD + mp->tx_slot, 0x0100);			mp->tx_slot ^=16;			mp->tx_count++;			dev->tbusy = 0;			mark_bh(NET_BH);		}#if 0	}#endif}

⌨️ 快捷键说明

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