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

📄 saa9730.c

📁 linux和2410结合开发 用他可以生成2410所需的zImage文件
💻 C
📖 第 1 页 / 共 2 页
字号:
	return 0;}static int lan_saa9730_restart(struct lan_saa9730_private *lp){	lan_saa9730_stop(lp);	lan_saa9730_start(lp);	return 0;}static int lan_saa9730_tx(struct net_device *dev){	struct lan_saa9730_private *lp =	    (struct lan_saa9730_private *) dev->priv;	unsigned int *pPacket;	unsigned int tx_status;	if (lan_saa9730_debug > 5)		printk("lan_saa9730_tx interrupt\n");	/* Clear interrupt. */	OUTL(DMA_STATUS_MAC_TX_INT, &lp->lan_saa9730_regs->DmaStatus);	while (1) {		pPacket =		    (unsigned int *) lp->TxmBuffer[lp->						   PendingTxmBufferIndex]		    [lp->PendingTxmPacketIndex];		/* Get status of first packet transmitted. */		tx_status = le32_to_cpu(*pPacket);		/* Check ownership. */		if ((tx_status & TX_STAT_CTL_OWNER_MSK) !=		    (TXSF_HWDONE << TX_STAT_CTL_OWNER_SHF)) break;		/* Check for error. */		if (tx_status & TX_STAT_CTL_ERROR_MSK) {			if (lan_saa9730_debug > 1)				printk("lan_saa9730_tx: tx error = %x\n",				       tx_status);			lp->stats.tx_errors++;			if (tx_status &			    (TX_STATUS_EX_COLL << TX_STAT_CTL_STATUS_SHF))				    lp->stats.tx_aborted_errors++;			if (tx_status &			    (TX_STATUS_LATE_COLL <<			     TX_STAT_CTL_STATUS_SHF)) lp->stats.	     tx_window_errors++;			if (tx_status &			    (TX_STATUS_L_CARR << TX_STAT_CTL_STATUS_SHF))				    lp->stats.tx_carrier_errors++;			if (tx_status &			    (TX_STATUS_UNDER << TX_STAT_CTL_STATUS_SHF))				    lp->stats.tx_fifo_errors++;			if (tx_status &			    (TX_STATUS_SQ_ERR << TX_STAT_CTL_STATUS_SHF))				    lp->stats.tx_heartbeat_errors++;			lp->stats.collisions +=			    tx_status & TX_STATUS_TX_COLL_MSK;		}		/* Free buffer. */		*pPacket =		    cpu_to_le32(TXSF_EMPTY << TX_STAT_CTL_OWNER_SHF);		/* Update pending index pointer. */		lp->PendingTxmPacketIndex++;		if (lp->PendingTxmPacketIndex >= LAN_SAA9730_TXM_Q_SIZE) {			lp->PendingTxmPacketIndex = 0;			lp->PendingTxmBufferIndex ^= 1;		}	}	/* Make sure A and B are available to hardware. */	OUTL(OK2USE_TX_A | OK2USE_TX_B, &lp->lan_saa9730_regs->Ok2Use);	if (netif_queue_stopped(dev)) {		/* The tx buffer is no longer full. */		netif_wake_queue(dev);	}	return 0;}static int lan_saa9730_rx(struct net_device *dev){	struct lan_saa9730_private *lp =	    (struct lan_saa9730_private *) dev->priv;	int len = 0;	struct sk_buff *skb = 0;	unsigned int rx_status;	int BufferIndex;	int PacketIndex;	unsigned int *pPacket;	unsigned char *pData;	if (lan_saa9730_debug > 5)		printk("lan_saa9730_rx interrupt\n");	/* Clear receive interrupts. */	OUTL(DMA_STATUS_MAC_RX_INT | DMA_STATUS_RX_INT |	     DMA_STATUS_RX_TO_INT, &lp->lan_saa9730_regs->DmaStatus);	/* Address next packet */	if (lp->NextRcvToUseIsA)		BufferIndex = 0;	else		BufferIndex = 1;	PacketIndex = lp->NextRcvPacketIndex;	pPacket = (unsigned int *) lp->RcvBuffer[BufferIndex][PacketIndex];	rx_status = le32_to_cpu(*pPacket);	/* Process each packet. */	while ((rx_status & RX_STAT_CTL_OWNER_MSK) ==	       (RXSF_HWDONE << RX_STAT_CTL_OWNER_SHF)) {		/* Check the rx status. */		if (rx_status & (RX_STATUS_GOOD << RX_STAT_CTL_STATUS_SHF)) {			/* Received packet is good. */			len = (rx_status & RX_STAT_CTL_LENGTH_MSK) >>			    RX_STAT_CTL_LENGTH_SHF;			pData = (unsigned char *) pPacket;			pData += 4;			skb = dev_alloc_skb(len + 2);			if (skb == 0) {				printk				    ("%s: Memory squeeze, deferring packet.\n",				     dev->name);				lp->stats.rx_dropped++;			} else {				lp->stats.rx_bytes += len;				lp->stats.rx_packets++;				skb->dev = dev;				skb_reserve(skb, 2);	/* 16 byte align */				skb_put(skb, len);	/* make room */				eth_copy_and_sum(skb,						 (unsigned char *) pData,						 len, 0);				skb->protocol = eth_type_trans(skb, dev);				netif_rx(skb);			}		} else {			/* We got an error packet. */			if (lan_saa9730_debug > 2)				printk				    ("lan_saa9730_rx: We got an error packet = %x\n",				     rx_status);			lp->stats.rx_errors++;			if (rx_status &			    (RX_STATUS_CRC_ERR << RX_STAT_CTL_STATUS_SHF))				    lp->stats.rx_crc_errors++;			if (rx_status &			    (RX_STATUS_ALIGN_ERR <<			     RX_STAT_CTL_STATUS_SHF)) lp->stats.	     rx_frame_errors++;			if (rx_status &			    (RX_STATUS_OVERFLOW << RX_STAT_CTL_STATUS_SHF))				    lp->stats.rx_fifo_errors++;			if (rx_status &			    (RX_STATUS_LONG_ERR << RX_STAT_CTL_STATUS_SHF))				    lp->stats.rx_length_errors++;		}		/* Indicate we have processed the buffer. */		*pPacket =		    cpu_to_le32(RXSF_READY << RX_STAT_CTL_OWNER_SHF);		/* Go to next packet in sequence. */		lp->NextRcvPacketIndex++;		if (lp->NextRcvPacketIndex >= LAN_SAA9730_RCV_Q_SIZE) {			lp->NextRcvPacketIndex = 0;			if (BufferIndex) {				lp->NextRcvToUseIsA = 1;			} else {				lp->NextRcvToUseIsA = 0;			}		}		OUTL(OK2USE_RX_A | OK2USE_RX_B,		     &lp->lan_saa9730_regs->Ok2Use);		/* Address next packet */		if (lp->NextRcvToUseIsA)			BufferIndex = 0;		else			BufferIndex = 1;		PacketIndex = lp->NextRcvPacketIndex;		pPacket =		    (unsigned int *) lp->		    RcvBuffer[BufferIndex][PacketIndex];		rx_status = le32_to_cpu(*pPacket);	}	/* Make sure A and B are available to hardware. */	OUTL(OK2USE_RX_A | OK2USE_RX_B, &lp->lan_saa9730_regs->Ok2Use);	return 0;}static void lan_saa9730_interrupt(const int irq, void *dev_id,				  struct pt_regs *regs){	struct net_device *dev = (struct net_device *) dev_id;	struct lan_saa9730_private *lp =	    (struct lan_saa9730_private *) dev->priv;	if (lan_saa9730_debug > 5)		printk("lan_saa9730_interrupt\n");	/* Disable the EVM LAN interrupt. */	evm_saa9730_block_lan_int(lp);	/* Clear the EVM LAN interrupt. */	evm_saa9730_clear_lan_int(lp);	/* Service pending transmit interrupts. */	if (INL(&lp->lan_saa9730_regs->DmaStatus) & DMA_STATUS_MAC_TX_INT)		lan_saa9730_tx(dev);	/* Service pending receive interrupts. */	if (INL(&lp->lan_saa9730_regs->DmaStatus) &	    (DMA_STATUS_MAC_RX_INT | DMA_STATUS_RX_INT |	     DMA_STATUS_RX_TO_INT)) lan_saa9730_rx(dev);	/* Enable the EVM LAN interrupt. */	evm_saa9730_unblock_lan_int(lp);	return;}static int lan_saa9730_open_fail(struct net_device *dev){	return -ENODEV;}static int lan_saa9730_open(struct net_device *dev){	struct lan_saa9730_private *lp =	    (struct lan_saa9730_private *) dev->priv;	/* Associate IRQ with lan_saa9730_interrupt */	if (request_irq(dev->irq, &lan_saa9730_interrupt, 0, "SAA9730 Eth",			dev)) {		printk("lan_saa9730_open: Can't get irq %d\n", dev->irq);		return -EAGAIN;	}	/* Enable the Lan interrupt in the event manager. */	evm_saa9730_enable_lan_int(lp);	/* Start the LAN controller */	if (lan_saa9730_start(lp))		return -1;	netif_start_queue(dev);	return 0;}static int lan_saa9730_write(struct lan_saa9730_private *lp,			     struct sk_buff *skb, int skblen){	unsigned char *pbData = skb->data;	unsigned int len = skblen;	unsigned char *pbPacketData;	unsigned int tx_status;	int BufferIndex;	int PacketIndex;	if (lan_saa9730_debug > 5)		printk("lan_saa9730_write: skb=%08x\n",		       (unsigned int) skb);	BufferIndex = lp->NextTxmBufferIndex;	PacketIndex = lp->NextTxmPacketIndex;	tx_status =	    le32_to_cpu(*(unsigned int *) lp->			TxmBuffer[BufferIndex][PacketIndex]);	if ((tx_status & TX_STAT_CTL_OWNER_MSK) !=	    (TXSF_EMPTY << TX_STAT_CTL_OWNER_SHF)) {		if (lan_saa9730_debug > 4)			printk			    ("lan_saa9730_write: Tx buffer not available: tx_status = %x\n",			     tx_status);		return -1;	}	lp->NextTxmPacketIndex++;	if (lp->NextTxmPacketIndex >= LAN_SAA9730_TXM_Q_SIZE) {		lp->NextTxmPacketIndex = 0;		lp->NextTxmBufferIndex ^= 1;	}	pbPacketData =	    (unsigned char *) lp->TxmBuffer[BufferIndex][PacketIndex];	pbPacketData += 4;	/* copy the bits */	memcpy(pbPacketData, pbData, len);	/* Set transmit status for hardware */	*(unsigned int *) lp->TxmBuffer[BufferIndex][PacketIndex] =	    cpu_to_le32((TXSF_READY << TX_STAT_CTL_OWNER_SHF) |			(TX_STAT_CTL_INT_AFTER_TX << TX_STAT_CTL_FRAME_SHF)			| (len << TX_STAT_CTL_LENGTH_SHF));	/* Set hardware tx buffer. */	OUTL(OK2USE_TX_A | OK2USE_TX_B, &lp->lan_saa9730_regs->Ok2Use);	return 0;}static void lan_saa9730_tx_timeout(struct net_device *dev){	struct lan_saa9730_private *lp =	    (struct lan_saa9730_private *) dev->priv;	/* Transmitter timeout, serious problems */	lp->stats.tx_errors++;	printk("%s: transmit timed out, reset\n", dev->name);	/*show_saa9730_regs(lp); */	lan_saa9730_restart(lp);	dev->trans_start = jiffies;	netif_start_queue(dev);}static int lan_saa9730_start_xmit(struct sk_buff *skb,				  struct net_device *dev){	struct lan_saa9730_private *lp =	    (struct lan_saa9730_private *) dev->priv;	unsigned long flags;	int skblen;	int len;	if (lan_saa9730_debug > 4)		printk("Send packet: skb=%08x\n", (unsigned int) skb);	skblen = skb->len;	save_and_cli(flags);	len = (skblen <= ETH_ZLEN) ? ETH_ZLEN : skblen;	if (lan_saa9730_write(lp, skb, skblen)) {		restore_flags(flags);		printk		    ("Error when writing packet to controller: skb=%08x\n",		     (unsigned int) skb);		netif_stop_queue(dev);		return -1;	}	lp->stats.tx_bytes += len;	lp->stats.tx_packets++;	dev->trans_start = jiffies;	netif_start_queue(dev);	dev_kfree_skb(skb);	restore_flags(flags);	return 0;}static int lan_saa9730_close(struct net_device *dev){	struct lan_saa9730_private *lp =	    (struct lan_saa9730_private *) dev->priv;	if (lan_saa9730_debug > 1)		printk("lan_saa9730_close:\n");	netif_stop_queue(dev);	/* Disable the Lan interrupt in the event manager. */	evm_saa9730_disable_lan_int(lp);	/* Stop the controller */	if (lan_saa9730_stop(lp))		return -1;	free_irq(dev->irq, (void *) dev);	return 0;}static struct net_device_stats *lan_saa9730_get_stats(struct net_device						      *dev){	struct lan_saa9730_private *lp =	    (struct lan_saa9730_private *) dev->priv;	return &lp->stats;}static void lan_saa9730_set_multicast(struct net_device *dev){	struct lan_saa9730_private *lp =	    (struct lan_saa9730_private *) dev->priv;	/* Stop the controller */	lan_saa9730_stop(lp);	if (dev->flags & IFF_PROMISC) {		/* accept all packets */		OUTL(CAM_CONTROL_COMP_EN | CAM_CONTROL_STATION_ACC |		     CAM_CONTROL_GROUP_ACC | CAM_CONTROL_BROAD_ACC,		     &lp->lan_saa9730_regs->CamCtl);	} else {		if (dev->flags & IFF_ALLMULTI) {			/* accept all multicast packets */			OUTL(CAM_CONTROL_COMP_EN | CAM_CONTROL_GROUP_ACC |			     CAM_CONTROL_BROAD_ACC,			     &lp->lan_saa9730_regs->CamCtl);		} else {			/* 			 * Will handle the multicast stuff later. -carstenl			 */		}	}	lan_saa9730_restart(lp);}static int lan_saa9730_init(struct net_device *dev, int ioaddr, int irq){	struct lan_saa9730_private *lp;	unsigned char ethernet_addr[6];	dev = init_etherdev(dev, 0);	dev->open = lan_saa9730_open_fail;	if (get_ethernet_addr(ethernet_addr))		return -1;	memcpy(dev->dev_addr, ethernet_addr, 6);	dev->base_addr = ioaddr;	dev->irq = irq;	/* 	 * Make certain the data structures used by the controller are aligned 	 * and DMAble. 	 */	lp = (struct lan_saa9730_private *) (((unsigned long)					      kmalloc(sizeof(*lp) + 7,						      GFP_DMA | GFP_KERNEL)					      + 7) & ~7);	dev->priv = lp;	memset(lp, 0, sizeof(*lp));	/* Set SAA9730 LAN base address. */	lp->lan_saa9730_regs = (t_lan_saa9730_regmap *) (ioaddr +							 SAA9730_LAN_REGS_ADDR);	/* Set SAA9730 EVM base address. */	lp->evm_saa9730_regs = (t_evm_saa9730_regmap *) (ioaddr +							 SAA9730_EVM_REGS_ADDR);	/* Allocate LAN RX/TX frame buffer space. */	if (lan_saa9730_allocate_buffers(lp))		return -1;	/* Stop LAN controller. */	if (lan_saa9730_stop(lp))		return -1;	/* Initialize CAM registers. */	if (lan_saa9730_cam_init(dev))		return -1;	/* Initialize MII registers. */	if (lan_saa9730_mii_init(lp))		return -1;	/* Initialize control registers. */	if (lan_saa9730_control_init(lp))		return -1;	/* Load CAM registers. */	if (lan_saa9730_cam_load(lp))		return -1;	/* Initialize DMA context registers. */	if (lan_saa9730_dma_init(lp))		return -1;	dev->open = lan_saa9730_open;	dev->hard_start_xmit = lan_saa9730_start_xmit;	dev->stop = lan_saa9730_close;	dev->get_stats = lan_saa9730_get_stats;	dev->set_multicast_list = lan_saa9730_set_multicast;	dev->tx_timeout = lan_saa9730_tx_timeout;	dev->watchdog_timeo = (HZ >> 1);	dev->dma = 0;	return 0;}static int __init saa9730_probe(void){	struct net_device *dev = NULL;	if (pci_present()) {		struct pci_dev *pdev = NULL;		if (lan_saa9730_debug > 1)			printk			    ("saa9730.c: PCI bios is present, checking for devices...\n");		while ((pdev = pci_find_device(PCI_VENDOR_ID_PHILIPS,					       PCI_DEVICE_ID_PHILIPS_SAA9730,					       pdev))) {			unsigned int pci_ioaddr;			pci_irq_line = pdev->irq;			/* LAN base address in located at BAR 1. */			pci_ioaddr = pci_resource_start(pdev, 1);			pci_set_master(pdev);			printk("Found SAA9730 (PCI) at %#x, irq %d.\n",			       pci_ioaddr, pci_irq_line);			if (!lan_saa9730_init			    (dev, pci_ioaddr, pci_irq_line)) return 0;			else				printk("Lan init failed.\n");		}	}	return -ENODEV;}module_init(saa9730_probe);MODULE_LICENSE("GPL");

⌨️ 快捷键说明

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