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

📄 xircom_cb.c

📁 linux-2.6.15.6
💻 C
📖 第 1 页 / 共 3 页
字号:
	val = inl(card->io_port + CSR6);	/* Operation mode */	/* If the "active" bit is set and the receiver is already	   active, no need to do the expensive thing */	 	if ((val&(1<<13)) && (transmit_active(card)))		return;	val = val & ~(1 << 13);	/* disable the transmitter */	outl(val, card->io_port + CSR6);	counter = 10;	while (counter > 0) {		if (!transmit_active(card))			break;		/* wait a while */		udelay(50);		counter--;		if (counter <= 0)			printk(KERN_ERR "xircom_cb: Transmitter failed to deactivate\n");	}	/* enable the transmitter */	val = inl(card->io_port + CSR6);	/* Operation mode */	val = val | (1 << 13);	/* enable the transmitter */	outl(val, card->io_port + CSR6);	/* now wait for the card to activate again */	counter = 10;	while (counter > 0) {		if (transmit_active(card))			break;		/* wait a while */		udelay(50);		counter--;		if (counter <= 0)			printk(KERN_ERR "xircom_cb: Transmitter failed to re-activate\n");	}	leave("activate_transmitter");}/*deactivate_transmitter disables the transmitter on the card.To achieve this this code disables the transmitter first; then it waits for the transmitter to become inactive.must be called with the lock held and interrupts disabled.*/static void deactivate_transmitter(struct xircom_private *card){	unsigned int val;	int counter;	enter("deactivate_transmitter");	val = inl(card->io_port + CSR6);	/* Operation mode */	val = val & ~2;		/* disable the transmitter */	outl(val, card->io_port + CSR6);	counter = 20;	while (counter > 0) {		if (!transmit_active(card))			break;		/* wait a while */		udelay(50);		counter--;		if (counter <= 0)			printk(KERN_ERR "xircom_cb: Transmitter failed to deactivate\n");	}	leave("deactivate_transmitter");}/*enable_transmit_interrupt enables the transmit interruptmust be called with the lock held and interrupts disabled.*/static void enable_transmit_interrupt(struct xircom_private *card){	unsigned int val;	enter("enable_transmit_interrupt");	val = inl(card->io_port + CSR7);	/* Interrupt enable register */	val |= 1;				/* enable the transmit interrupt */	outl(val, card->io_port + CSR7);	leave("enable_transmit_interrupt");}/*enable_receive_interrupt enables the receive interruptmust be called with the lock held and interrupts disabled.*/static void enable_receive_interrupt(struct xircom_private *card){	unsigned int val;	enter("enable_receive_interrupt");	val = inl(card->io_port + CSR7);	/* Interrupt enable register */	val = val | (1 << 6);			/* enable the receive interrupt */	outl(val, card->io_port + CSR7);	leave("enable_receive_interrupt");}/*enable_link_interrupt enables the link status change interruptmust be called with the lock held and interrupts disabled.*/static void enable_link_interrupt(struct xircom_private *card){	unsigned int val;	enter("enable_link_interrupt");	val = inl(card->io_port + CSR7);	/* Interrupt enable register */	val = val | (1 << 27);			/* enable the link status chage interrupt */	outl(val, card->io_port + CSR7);	leave("enable_link_interrupt");}/*disable_all_interrupts disables all interruptsmust be called with the lock held and interrupts disabled.*/static void disable_all_interrupts(struct xircom_private *card){	unsigned int val;	enter("enable_all_interrupts");		val = 0;				/* disable all interrupts */	outl(val, card->io_port + CSR7);	leave("disable_all_interrupts");}/*enable_common_interrupts enables several weird interruptsmust be called with the lock held and interrupts disabled.*/static void enable_common_interrupts(struct xircom_private *card){	unsigned int val;	enter("enable_link_interrupt");	val = inl(card->io_port + CSR7);	/* Interrupt enable register */	val |= (1<<16); /* Normal Interrupt Summary */	val |= (1<<15); /* Abnormal Interrupt Summary */	val |= (1<<13); /* Fatal bus error */	val |= (1<<8);  /* Receive Process Stopped */	val |= (1<<7);  /* Receive Buffer Unavailable */	val |= (1<<5);  /* Transmit Underflow */	val |= (1<<2);  /* Transmit Buffer Unavailable */	val |= (1<<1);  /* Transmit Process Stopped */	outl(val, card->io_port + CSR7);	leave("enable_link_interrupt");}/*enable_promisc starts promisc modemust be called with the lock held and interrupts disabled.*/static int enable_promisc(struct xircom_private *card){	unsigned int val;	enter("enable_promisc");	val = inl(card->io_port + CSR6);		val = val | (1 << 6);		outl(val, card->io_port + CSR6);	leave("enable_promisc");	return 1;}/* link_status() checks the the links status and will return 0 for no link, 10 for 10mbit link and 100 for.. guess what.Must be called in locked state with interrupts disabled*/static int link_status(struct xircom_private *card){	unsigned int val;	enter("link_status");		val = inb(card->io_port + CSR12);		if (!(val&(1<<2)))  /* bit 2 is 0 for 10mbit link, 1 for not an 10mbit link */		return 10;	if (!(val&(1<<1)))  /* bit 1 is 0 for 100mbit link, 1 for not an 100mbit link */		return 100;			/* If we get here -> no link at all */		leave("link_status");	return 0;}/*  read_mac_address() reads the MAC address from the NIC and stores it in the "dev" structure.   This function will take the spinlock itself and can, as a result, not be called with the lock helt. */static void read_mac_address(struct xircom_private *card){	unsigned char j, tuple, link, data_id, data_count;	unsigned long flags;	int i;	enter("read_mac_address");			spin_lock_irqsave(&card->lock, flags);	outl(1 << 12, card->io_port + CSR9);	/* enable boot rom access */	for (i = 0x100; i < 0x1f7; i += link + 2) {		outl(i, card->io_port + CSR10);		tuple = inl(card->io_port + CSR9) & 0xff;		outl(i + 1, card->io_port + CSR10);		link = inl(card->io_port + CSR9) & 0xff;		outl(i + 2, card->io_port + CSR10);		data_id = inl(card->io_port + CSR9) & 0xff;		outl(i + 3, card->io_port + CSR10);		data_count = inl(card->io_port + CSR9) & 0xff;		if ((tuple == 0x22) && (data_id == 0x04) && (data_count == 0x06)) {			/* 			 * This is it.  We have the data we want.			 */			for (j = 0; j < 6; j++) {				outl(i + j + 4, card->io_port + CSR10);				card->dev->dev_addr[j] = inl(card->io_port + CSR9) & 0xff;			}			break;		} else if (link == 0) {			break;		}	}	spin_unlock_irqrestore(&card->lock, flags);#ifdef DEBUG	for (i = 0; i < 6; i++)		printk("%c%2.2X", i ? ':' : ' ', card->dev->dev_addr[i]);	printk("\n");#endif	leave("read_mac_address");}/* transceiver_voodoo() enables the external UTP plug thingy. it's called voodoo as I stole this code and cannot cross-reference it with the specification. */static void transceiver_voodoo(struct xircom_private *card){	unsigned long flags;	enter("transceiver_voodoo");	/* disable all powermanagement */	pci_write_config_dword(card->pdev, PCI_POWERMGMT, 0x0000);	setup_descriptors(card);	spin_lock_irqsave(&card->lock, flags);	outl(0x0008, card->io_port + CSR15);        udelay(25);          outl(0xa8050000, card->io_port + CSR15);        udelay(25);        outl(0xa00f0000, card->io_port + CSR15);        udelay(25);                spin_unlock_irqrestore(&card->lock, flags);	netif_start_queue(card->dev);	leave("transceiver_voodoo");}static void xircom_up(struct xircom_private *card){	unsigned long flags;	int i;	enter("xircom_up");	/* disable all powermanagement */	pci_write_config_dword(card->pdev, PCI_POWERMGMT, 0x0000);	setup_descriptors(card);	spin_lock_irqsave(&card->lock, flags);		enable_link_interrupt(card);	enable_transmit_interrupt(card);	enable_receive_interrupt(card);	enable_common_interrupts(card);	enable_promisc(card);		/* The card can have received packets already, read them away now */	for (i=0;i<NUMDESCRIPTORS;i++) 		investigate_read_descriptor(card->dev,card,i,bufferoffsets[i]);	spin_unlock_irqrestore(&card->lock, flags);	trigger_receive(card);	trigger_transmit(card);	netif_start_queue(card->dev);	leave("xircom_up");}/* Bufferoffset is in BYTES */static void investigate_read_descriptor(struct net_device *dev,struct xircom_private *card, int descnr, unsigned int bufferoffset){		int status;						enter("investigate_read_descriptor");		status = card->rx_buffer[4*descnr];				if ((status > 0)) {	/* packet received */					/* TODO: discard error packets */						short pkt_len = ((status >> 16) & 0x7ff) - 4;	/* minus 4, we don't want the CRC */			struct sk_buff *skb;			if (pkt_len > 1518) {				printk(KERN_ERR "xircom_cb: Packet length %i is bogus \n",pkt_len);				pkt_len = 1518;			}			skb = dev_alloc_skb(pkt_len + 2);			if (skb == NULL) {				card->stats.rx_dropped++;				goto out;			}			skb->dev = dev;			skb_reserve(skb, 2);			eth_copy_and_sum(skb, (unsigned char*)&card->rx_buffer[bufferoffset / 4], pkt_len, 0);			skb_put(skb, pkt_len);			skb->protocol = eth_type_trans(skb, dev);			netif_rx(skb);			dev->last_rx = jiffies;			card->stats.rx_packets++;			card->stats.rx_bytes += pkt_len;					      out:			/* give the buffer back to the card */			card->rx_buffer[4*descnr] =  0x80000000;			trigger_receive(card);		}		leave("investigate_read_descriptor");}/* Bufferoffset is in BYTES */static void investigate_write_descriptor(struct net_device *dev, struct xircom_private *card, int descnr, unsigned int bufferoffset){		int status;		enter("investigate_write_descriptor");				status = card->tx_buffer[4*descnr];#if 0				if (status & 0x8000) {	/* Major error */			printk(KERN_ERR "Major transmit error status %x \n", status);			card->tx_buffer[4*descnr] = 0;			netif_wake_queue (dev);		}#endif		if (status > 0) {	/* bit 31 is 0 when done */			if (card->tx_skb[descnr]!=NULL) {				card->stats.tx_bytes += card->tx_skb[descnr]->len;				dev_kfree_skb_irq(card->tx_skb[descnr]);			}			card->tx_skb[descnr] = NULL;			/* Bit 8 in the status field is 1 if there was a collision */			if (status&(1<<8))				card->stats.collisions++;			card->tx_buffer[4*descnr] = 0; /* descriptor is free again */			netif_wake_queue (dev);			card->stats.tx_packets++;		}		leave("investigate_write_descriptor");		}static int __init xircom_init(void){	pci_register_driver(&xircom_ops);	return 0;}static void __exit xircom_exit(void){	pci_unregister_driver(&xircom_ops);} module_init(xircom_init) module_exit(xircom_exit)

⌨️ 快捷键说明

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