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

📄 olympic.c

📁 内核linux2.4.20,可跟rtlinux3.2打补丁 组成实时linux系统,编译内核
💻 C
📖 第 1 页 / 共 5 页
字号:
	pci_unmap_single(olympic_priv->pdev, olympic_priv->tx_ring_dma_addr, 		sizeof(struct olympic_tx_desc) * OLYMPIC_TX_RING_SIZE, PCI_DMA_TODEVICE);	/* reset tx/rx fifo's and busmaster logic */	writel(readl(olympic_mmio+BCTL)|(3<<13),olympic_mmio+BCTL);	udelay(1);	writel(readl(olympic_mmio+BCTL)&~(3<<13),olympic_mmio+BCTL);#if OLYMPIC_DEBUG	printk("srb(%p): ",srb);	for(i=0;i<4;i++)		printk("%x ",readb(srb+i));	printk("\n");#endif	free_irq(dev->irq,dev);	return 0;	}static void olympic_set_rx_mode(struct net_device *dev) {	struct olympic_private *olympic_priv = (struct olympic_private *) dev->priv ;    	u8 *olympic_mmio = olympic_priv->olympic_mmio ; 	u8 options = 0; 	u8 *srb;	struct dev_mc_list *dmi ; 	unsigned char dev_mc_address[4] ; 	int i ; 	writel(olympic_priv->srb,olympic_mmio+LAPA);	srb=olympic_priv->olympic_lap + (olympic_priv->srb & (~0xf800));	options = olympic_priv->olympic_copy_all_options; 	if (dev->flags&IFF_PROMISC)  		options |= 0x61 ;	else		options &= ~0x61 ; 	/* Only issue the srb if there is a change in options */	if ((options ^ olympic_priv->olympic_copy_all_options)) { 			/* Now to issue the srb command to alter the copy.all.options */			writeb(SRB_MODIFY_RECEIVE_OPTIONS,srb);		writeb(0,srb+1);		writeb(OLYMPIC_CLEAR_RET_CODE,srb+2);		writeb(0,srb+3);		writeb(olympic_priv->olympic_receive_options,srb+4);		writeb(options,srb+5);		olympic_priv->srb_queued=2; /* Can't sleep, use srb_bh */		writel(LISR_SRB_CMD,olympic_mmio+LISR_SUM);		olympic_priv->olympic_copy_all_options = options ;				return ;  	} 	/* Set the functional addresses we need for multicast */	dev_mc_address[0] = dev_mc_address[1] = dev_mc_address[2] = dev_mc_address[3] = 0 ; 	for (i=0,dmi=dev->mc_list;i < dev->mc_count; i++,dmi = dmi->next) { 		dev_mc_address[0] |= dmi->dmi_addr[2] ; 		dev_mc_address[1] |= dmi->dmi_addr[3] ; 		dev_mc_address[2] |= dmi->dmi_addr[4] ; 		dev_mc_address[3] |= dmi->dmi_addr[5] ; 	}	writeb(SRB_SET_FUNC_ADDRESS,srb+0);	writeb(0,srb+1);	writeb(OLYMPIC_CLEAR_RET_CODE,srb+2);	writeb(0,srb+3);	writeb(0,srb+4);	writeb(0,srb+5);	writeb(dev_mc_address[0],srb+6);	writeb(dev_mc_address[1],srb+7);	writeb(dev_mc_address[2],srb+8);	writeb(dev_mc_address[3],srb+9);	olympic_priv->srb_queued = 2 ;	writel(LISR_SRB_CMD,olympic_mmio+LISR_SUM);}static void olympic_srb_bh(struct net_device *dev) { 	struct olympic_private *olympic_priv = (struct olympic_private *) dev->priv ;    	u8 *olympic_mmio = olympic_priv->olympic_mmio ; 	u8 *srb;	writel(olympic_priv->srb,olympic_mmio+LAPA);	srb=olympic_priv->olympic_lap + (olympic_priv->srb & (~0xf800));	switch (readb(srb)) { 		/* SRB_MODIFY_RECEIVE_OPTIONS i.e. set_multicast_list options (promiscuous)                  * At some point we should do something if we get an error, such as                 * resetting the IFF_PROMISC flag in dev		 */		case SRB_MODIFY_RECEIVE_OPTIONS:			switch (readb(srb+2)) { 				case 0x01:					printk(KERN_WARNING "%s: Unrecognized srb command\n",dev->name) ; 					break ; 				case 0x04:					printk(KERN_WARNING "%s: Adapter must be open for this operation, doh!!\n",dev->name);					break ; 				default:					if (olympic_priv->olympic_message_level) 						printk(KERN_WARNING "%s: Receive Options Modified to %x,%x\n",dev->name,olympic_priv->olympic_copy_all_options, olympic_priv->olympic_receive_options) ; 					break ; 				} /* switch srb[2] */ 			break ;				/* SRB_SET_GROUP_ADDRESS - Multicast group setting                  */		case SRB_SET_GROUP_ADDRESS:			switch (readb(srb+2)) { 				case 0x00:					break ; 				case 0x01:					printk(KERN_WARNING "%s: Unrecognized srb command \n",dev->name) ; 					break ;				case 0x04:					printk(KERN_WARNING "%s: Adapter must be open for this operation, doh!!\n",dev->name); 					break ;				case 0x3c:					printk(KERN_WARNING "%s: Group/Functional address indicator bits not set correctly\n",dev->name) ; 					break ;				case 0x3e: /* If we ever implement individual multicast addresses, will need to deal with this */					printk(KERN_WARNING "%s: Group address registers full\n",dev->name) ; 					break ;  				case 0x55:					printk(KERN_INFO "%s: Group Address already set.\n",dev->name) ; 					break ;				default:					break ; 			} /* switch srb[2] */ 			break ; 		/* SRB_RESET_GROUP_ADDRESS - Remove a multicast address from group list 		 */		case SRB_RESET_GROUP_ADDRESS:			switch (readb(srb+2)) { 				case 0x00:					break ; 				case 0x01:					printk(KERN_WARNING "%s: Unrecognized srb command \n",dev->name) ; 					break ; 				case 0x04:					printk(KERN_WARNING "%s: Adapter must be open for this operation, doh!!\n",dev->name) ; 					break ; 				case 0x39: /* Must deal with this if individual multicast addresses used */					printk(KERN_INFO "%s: Group address not found \n",dev->name); 					break ;				default:					break ; 			} /* switch srb[2] */			break ; 				/* SRB_SET_FUNC_ADDRESS - Called by the set_rx_mode 		 */		case SRB_SET_FUNC_ADDRESS:			switch (readb(srb+2)) { 				case 0x00:					if (olympic_priv->olympic_message_level)						printk(KERN_INFO "%s: Functional Address Mask Set \n",dev->name) ; 					break ;				case 0x01:					printk(KERN_WARNING "%s: Unrecognized srb command \n",dev->name) ; 					break ; 				case 0x04:					printk(KERN_WARNING "%s: Adapter must be open for this operation, doh!!\n",dev->name) ; 					break ; 				default:					break ; 			} /* switch srb[2] */			break ; 			/* SRB_READ_LOG - Read and reset the adapter error counters 		 */		case SRB_READ_LOG:			switch (readb(srb+2)) { 				case 0x00: 					if (olympic_priv->olympic_message_level) 						printk(KERN_INFO "%s: Read Log issued\n",dev->name) ; 					break ; 				case 0x01:					printk(KERN_WARNING "%s: Unrecognized srb command \n",dev->name) ; 					break ; 				case 0x04:					printk(KERN_WARNING "%s: Adapter must be open for this operation, doh!!\n",dev->name) ; 					break ; 						} /* switch srb[2] */			break ; 				/* SRB_READ_SR_COUNTERS - Read and reset the source routing bridge related counters */		case SRB_READ_SR_COUNTERS:			switch (readb(srb+2)) { 				case 0x00: 					if (olympic_priv->olympic_message_level) 						printk(KERN_INFO "%s: Read Source Routing Counters issued\n",dev->name) ; 					break ; 				case 0x01:					printk(KERN_WARNING "%s: Unrecognized srb command \n",dev->name) ; 					break ; 				case 0x04:					printk(KERN_WARNING "%s: Adapter must be open for this operation, doh!!\n",dev->name) ; 					break ; 				default:					break ; 			} /* switch srb[2] */			break ; 		default:			printk(KERN_WARNING "%s: Unrecognized srb bh return value.\n",dev->name);			break ; 	} /* switch srb[0] */} static struct net_device_stats * olympic_get_stats(struct net_device *dev){	struct olympic_private *olympic_priv ;	olympic_priv=(struct olympic_private *) dev->priv;	return (struct net_device_stats *) &olympic_priv->olympic_stats; }static int olympic_set_mac_address (struct net_device *dev, void *addr) {	struct sockaddr *saddr = addr ; 	struct olympic_private *olympic_priv = (struct olympic_private *)dev->priv ; 	if (netif_running(dev)) { 		printk(KERN_WARNING "%s: Cannot set mac/laa address while card is open\n", dev->name) ; 		return -EIO ; 	}	memcpy(olympic_priv->olympic_laa, saddr->sa_data,dev->addr_len) ; 		if (olympic_priv->olympic_message_level) {  		printk(KERN_INFO "%s: MAC/LAA Set to  = %x.%x.%x.%x.%x.%x\n",dev->name, olympic_priv->olympic_laa[0],		olympic_priv->olympic_laa[1], olympic_priv->olympic_laa[2],		olympic_priv->olympic_laa[3], olympic_priv->olympic_laa[4],		olympic_priv->olympic_laa[5]);	} 	return 0 ; }static void olympic_arb_cmd(struct net_device *dev){	struct olympic_private *olympic_priv = (struct olympic_private *) dev->priv;    	u8 *olympic_mmio=olympic_priv->olympic_mmio;	u8 *arb_block, *asb_block, *srb  ; 	u8 header_len ; 	u16 frame_len, buffer_len ;	struct sk_buff *mac_frame ;  	u8 *buf_ptr ;	u8 *frame_data ;  	u16 buff_off ; 	u16 lan_status = 0, lan_status_diff  ; /* Initialize to stop compiler warning */	u8 fdx_prot_error ; 	u16 next_ptr;	int i ; 	arb_block = (u8 *)(olympic_priv->olympic_lap + olympic_priv->arb) ; 	asb_block = (u8 *)(olympic_priv->olympic_lap + olympic_priv->asb) ; 	srb = (u8 *)(olympic_priv->olympic_lap + olympic_priv->srb) ; 	writel(readl(olympic_mmio+LAPA),olympic_mmio+LAPWWO);	if (readb(arb_block+0) == ARB_RECEIVE_DATA) { /* Receive.data, MAC frames */		header_len = readb(arb_block+8) ; /* 802.5 Token-Ring Header Length */			frame_len = swab16(readw(arb_block + 10)) ; 		buff_off = swab16(readw(arb_block + 6)) ;				buf_ptr = olympic_priv->olympic_lap + buff_off ; #if OLYMPIC_DEBUG{		int i;		frame_data = buf_ptr+offsetof(struct mac_receive_buffer,frame_data) ; 		for (i=0 ;  i < 14 ; i++) { 			printk("Loc %d = %02x\n",i,readb(frame_data + i)); 		}		printk("next %04x, fs %02x, len %04x \n",readw(buf_ptr+offsetof(struct mac_receive_buffer,next)), readb(buf_ptr+offsetof(struct mac_receive_buffer,frame_status)), readw(buf_ptr+offsetof(struct mac_receive_buffer,buffer_length))); }#endif 		mac_frame = dev_alloc_skb(frame_len) ; 		if (!mac_frame) {			printk(KERN_WARNING "%s: Memory squeeze, dropping frame.\n", dev->name);			goto drop_frame;		}		/* Walk the buffer chain, creating the frame */		do {			frame_data = buf_ptr+offsetof(struct mac_receive_buffer,frame_data) ; 			buffer_len = swab16(readw(buf_ptr+offsetof(struct mac_receive_buffer,buffer_length))); 			memcpy_fromio(skb_put(mac_frame, buffer_len), frame_data , buffer_len ) ;			next_ptr=readw(buf_ptr+offsetof(struct mac_receive_buffer,next)); 		} while (next_ptr && (buf_ptr=olympic_priv->olympic_lap + ntohs(next_ptr)));		if (olympic_priv->olympic_network_monitor) { 			struct trh_hdr *mac_hdr ; 			printk(KERN_WARNING "%s: Received MAC Frame, details: \n",dev->name) ;			mac_hdr = (struct trh_hdr *)mac_frame->data ; 			printk(KERN_WARNING "%s: MAC Frame Dest. Addr: %02x:%02x:%02x:%02x:%02x:%02x \n", dev->name , mac_hdr->daddr[0], mac_hdr->daddr[1], mac_hdr->daddr[2], mac_hdr->daddr[3], mac_hdr->daddr[4], mac_hdr->daddr[5]) ; 			printk(KERN_WARNING "%s: MAC Frame Srce. Addr: %02x:%02x:%02x:%02x:%02x:%02x \n", dev->name , mac_hdr->saddr[0], mac_hdr->saddr[1], mac_hdr->saddr[2], mac_hdr->saddr[3], mac_hdr->saddr[4], mac_hdr->saddr[5]) ; 		}		mac_frame->dev = dev ; 		mac_frame->protocol = tr_type_trans(mac_frame,dev);		netif_rx(mac_frame) ; 			dev->last_rx = jiffies;drop_frame:		/* Now tell the card we have dealt with the received frame */		/* Set LISR Bit 1 */		writel(LISR_ARB_FREE,olympic_priv->olympic_lap + LISR_SUM);		/* Is the ASB free ? */ 					if (readb(asb_block + 2) != 0xff) { 			olympic_priv->asb_queued = 1 ; 			writel(LISR_ASB_FREE_REQ,olympic_priv->olympic_mmio+LISR_SUM); 			return ; 				/* Drop out and wait for the bottom half to be run */		}

⌨️ 快捷键说明

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