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

📄 lanstreamer.c

📁 h内核
💻 C
📖 第 1 页 / 共 5 页
字号:
	return IRQ_HANDLED;}static int streamer_xmit(struct sk_buff *skb, struct net_device *dev){	struct streamer_private *streamer_priv =	    (struct streamer_private *) dev->priv;	__u8 __iomem *streamer_mmio = streamer_priv->streamer_mmio;	unsigned long flags ;	spin_lock_irqsave(&streamer_priv->streamer_lock, flags);	if (streamer_priv->free_tx_ring_entries) {		streamer_priv->streamer_tx_ring[streamer_priv->tx_ring_free].status = 0;		streamer_priv->streamer_tx_ring[streamer_priv->tx_ring_free].bufcnt_framelen = 0x00020000 | skb->len;		streamer_priv->streamer_tx_ring[streamer_priv->tx_ring_free].buffer = 			cpu_to_le32(pci_map_single(streamer_priv->pci_dev, skb->data, skb->len, PCI_DMA_TODEVICE));		streamer_priv->streamer_tx_ring[streamer_priv->tx_ring_free].rsvd1 = skb->len;		streamer_priv->streamer_tx_ring[streamer_priv->tx_ring_free].rsvd2 = 0;		streamer_priv->streamer_tx_ring[streamer_priv->tx_ring_free].rsvd3 = 0;		streamer_priv->streamer_tx_ring[streamer_priv->tx_ring_free].buflen = skb->len;		streamer_priv->tx_ring_skb[streamer_priv->tx_ring_free] = skb;		streamer_priv->free_tx_ring_entries--;#if STREAMER_DEBUG_PACKETS		{			int i;			printk("streamer_xmit packet print:\n");			for (i = 0; i < skb->len; i++) {				printk("%x:", skb->data[i]);				if (((i + 1) % 16) == 0)					printk("\n");			}			printk("\n");		}#endif		writel(cpu_to_le32(pci_map_single(streamer_priv->pci_dev, 					&streamer_priv->streamer_tx_ring[streamer_priv->tx_ring_free],					sizeof(struct streamer_tx_desc), PCI_DMA_TODEVICE)),			streamer_mmio + TX2LFDA);		(void)readl(streamer_mmio + TX2LFDA);		streamer_priv->tx_ring_free = (streamer_priv->tx_ring_free + 1) & (STREAMER_TX_RING_SIZE - 1);		spin_unlock_irqrestore(&streamer_priv->streamer_lock,flags);		return 0;	} else {	        netif_stop_queue(dev);	        spin_unlock_irqrestore(&streamer_priv->streamer_lock,flags);		return 1;	}}static int streamer_close(struct net_device *dev){	struct streamer_private *streamer_priv =	    (struct streamer_private *) dev->priv;	__u8 __iomem *streamer_mmio = streamer_priv->streamer_mmio;	unsigned long flags;	int i;	netif_stop_queue(dev);	netif_carrier_off(dev);	writew(streamer_priv->srb, streamer_mmio + LAPA);	writew(htons(SRB_CLOSE_ADAPTER << 8),streamer_mmio+LAPDINC);	writew(htons(STREAMER_CLEAR_RET_CODE << 8), streamer_mmio+LAPDINC);	spin_lock_irqsave(&streamer_priv->streamer_lock, flags);	streamer_priv->srb_queued = 1;	writew(LISR_SRB_CMD, streamer_mmio + LISR_SUM);	spin_unlock_irqrestore(&streamer_priv->streamer_lock, flags);	while (streamer_priv->srb_queued) 	{		interruptible_sleep_on_timeout(&streamer_priv->srb_wait,					       jiffies + 60 * HZ);		if (signal_pending(current)) 		{			printk(KERN_WARNING "%s: SRB timed out.\n", dev->name);			printk(KERN_WARNING "SISR=%x MISR=%x LISR=%x\n",			       readw(streamer_mmio + SISR),			       readw(streamer_mmio + MISR_RUM),			       readw(streamer_mmio + LISR));			streamer_priv->srb_queued = 0;			break;		}	}	streamer_priv->rx_ring_last_received = (streamer_priv->rx_ring_last_received + 1) & (STREAMER_RX_RING_SIZE - 1);	for (i = 0; i < STREAMER_RX_RING_SIZE; i++) {	        if (streamer_priv->rx_ring_skb[streamer_priv->rx_ring_last_received]) {		        dev_kfree_skb(streamer_priv->rx_ring_skb[streamer_priv->rx_ring_last_received]);		} 		streamer_priv->rx_ring_last_received = (streamer_priv->rx_ring_last_received + 1) & (STREAMER_RX_RING_SIZE - 1);	}	/* reset tx/rx fifo's and busmaster logic */	/* TBD. Add graceful way to reset the LLC channel without doing a soft reset. 	   writel(readl(streamer_mmio+BCTL)|(3<<13),streamer_mmio+BCTL);	   udelay(1);	   writel(readl(streamer_mmio+BCTL)&~(3<<13),streamer_mmio+BCTL);	 */#if STREAMER_DEBUG	writew(streamer_priv->srb, streamer_mmio + LAPA);	printk("srb): ");	for (i = 0; i < 2; i++) {		printk("%x ", ntohs(readw(streamer_mmio + LAPDINC)));	}	printk("\n");#endif	free_irq(dev->irq, dev);	return 0;}static void streamer_set_rx_mode(struct net_device *dev){	struct streamer_private *streamer_priv =	    (struct streamer_private *) dev->priv;	__u8 __iomem *streamer_mmio = streamer_priv->streamer_mmio;	__u8 options = 0;	struct dev_mc_list *dmi;	unsigned char dev_mc_address[5];	int i;	writel(streamer_priv->srb, streamer_mmio + LAPA);	options = streamer_priv->streamer_copy_all_options;	if (dev->flags & IFF_PROMISC)		options |= (3 << 5);	/* All LLC and MAC frames, all through the main rx channel */	else		options &= ~(3 << 5);	/* Only issue the srb if there is a change in options */	if ((options ^ streamer_priv->streamer_copy_all_options)) 	{		/* Now to issue the srb command to alter the copy.all.options */		writew(htons(SRB_MODIFY_RECEIVE_OPTIONS << 8), streamer_mmio+LAPDINC);		writew(htons(STREAMER_CLEAR_RET_CODE << 8), streamer_mmio+LAPDINC);		writew(htons((streamer_priv->streamer_receive_options << 8) | options),streamer_mmio+LAPDINC);		writew(htons(0x4a41),streamer_mmio+LAPDINC);		writew(htons(0x4d45),streamer_mmio+LAPDINC);		writew(htons(0x5320),streamer_mmio+LAPDINC);		writew(0x2020, streamer_mmio + LAPDINC);		streamer_priv->srb_queued = 2;	/* Can't sleep, use srb_bh */		writel(LISR_SRB_CMD, streamer_mmio + LISR_SUM);		streamer_priv->streamer_copy_all_options = options;		return;	}	/* Set the functional addresses we need for multicast */	writel(streamer_priv->srb,streamer_mmio+LAPA);	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] ; 	}  	writew(htons(SRB_SET_FUNC_ADDRESS << 8),streamer_mmio+LAPDINC);	writew(htons(STREAMER_CLEAR_RET_CODE << 8), streamer_mmio+LAPDINC);	writew(0,streamer_mmio+LAPDINC);	writew(htons( (dev_mc_address[0] << 8) | dev_mc_address[1]),streamer_mmio+LAPDINC);	writew(htons( (dev_mc_address[2] << 8) | dev_mc_address[3]),streamer_mmio+LAPDINC);	streamer_priv->srb_queued = 2 ; 	writel(LISR_SRB_CMD,streamer_mmio+LISR_SUM);}static void streamer_srb_bh(struct net_device *dev){	struct streamer_private *streamer_priv = (struct streamer_private *) dev->priv;	__u8 __iomem *streamer_mmio = streamer_priv->streamer_mmio;	__u16 srb_word;	writew(streamer_priv->srb, streamer_mmio + LAPA);	srb_word=ntohs(readw(streamer_mmio+LAPDINC)) >> 8;	switch (srb_word) {		/* 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:	        srb_word=ntohs(readw(streamer_mmio+LAPDINC)) >> 8;		switch (srb_word) {		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 (streamer_priv->streamer_message_level)				printk(KERN_WARNING "%s: Receive Options Modified to %x,%x\n",				       dev->name,				       streamer_priv->streamer_copy_all_options,				       streamer_priv->streamer_receive_options);			break;		}		/* switch srb[2] */		break;		/* SRB_SET_GROUP_ADDRESS - Multicast group setting 		 */	case SRB_SET_GROUP_ADDRESS:	        srb_word=ntohs(readw(streamer_mmio+LAPDINC)) >> 8;		switch (srb_word) {		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:	        srb_word=ntohs(readw(streamer_mmio+LAPDINC)) >> 8;		switch (srb_word) {		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:	        srb_word=ntohs(readw(streamer_mmio+LAPDINC)) >> 8;		switch (srb_word) {		case 0x00:			if (streamer_priv->streamer_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:	        srb_word=ntohs(readw(streamer_mmio+LAPDINC)) >> 8;		switch (srb_word) {		case 0x00:			{				int i;				if (streamer_priv->streamer_message_level)					printk(KERN_INFO "%s: Read Log command complete\n", dev->name);				printk("Read Log statistics: ");				writew(streamer_priv->srb + 6,				       streamer_mmio + LAPA);				for (i = 0; i < 5; i++) {					printk("%x:", ntohs(readw(streamer_mmio + LAPDINC)));				}				printk("\n");			}			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:	        srb_word=ntohs(readw(streamer_mmio+LAPDINC)) >> 8;		switch (srb_word) {		case 0x00:			if (streamer_priv->streamer_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 *streamer_get_stats(struct net_device *dev){	struct streamer_private *streamer_priv;	streamer_priv = (struct streamer_private *) dev->priv;	return (struct net_device_stats *) &streamer_priv->streamer_stats;}static int streamer_set_mac_address(struct net_device *dev, void *addr){	struct sockaddr *saddr = addr;	struct streamer_private *streamer_priv = (struct streamer_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(streamer_priv->streamer_laa, saddr->sa_data, dev->addr_len);	if (streamer_priv->streamer_message_level) {		printk(KERN_INFO "%s: MAC/LAA Set to  = %x.%x.%x.%x.%x.%x\n",		       dev->name, streamer_priv->streamer_laa[0],		       streamer_priv->streamer_laa[1],		       streamer_priv->streamer_laa[2],		       streamer_priv->streamer_laa[3],		       streamer_priv->streamer_laa[4],		       streamer_priv->streamer_laa[5]);	}	return 0;}static void streamer_arb_cmd(struct net_device *dev){	struct streamer_private *streamer_priv =	    (struct streamer_private *) dev->priv;	__u8 __iomem *streamer_mmio = streamer_priv->streamer_mmio;	__u8 header_len;	__u16 frame_len, buffer_len;	struct sk_buff *mac_frame;

⌨️ 快捷键说明

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