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

📄 mv_eth.c

📁 AMCC POWERPC 44X系列的U-BOOT文件
💻 C
📖 第 1 页 / 共 5 页
字号:
			s = "eth1addr";			break;		case 2:			s = "eth2addr";			break;		default:	/* this should never happen */			printf ("%s: Invalid device number %d\n",				__FUNCTION__, devnum);			return;		}		temp = getenv_r (s, buf, sizeof (buf));		s = (temp > 0) ? buf : NULL;#ifdef DEBUG		printf ("Setting MAC %d to %s\n", devnum, s);#endif		for (x = 0; x < 6; ++x) {			dev->enetaddr[x] = s ? simple_strtoul (s, &e, 16) : 0;			if (s)				s = (*e) ? e + 1 : e;		}		DP (printf ("Allocating descriptor and buffer rings\n"));		ethernet_private->p_rx_desc_area_base[0] =			(ETH_RX_DESC *) memalign (16,						  RX_DESC_ALIGNED_SIZE *						  MV64460_RX_QUEUE_SIZE + 1);		ethernet_private->p_tx_desc_area_base[0] =			(ETH_TX_DESC *) memalign (16,						  TX_DESC_ALIGNED_SIZE *						  MV64460_TX_QUEUE_SIZE + 1);		ethernet_private->p_rx_buffer_base[0] =			(char *) memalign (16,					   MV64460_RX_QUEUE_SIZE *					   MV64460_TX_BUFFER_SIZE + 1);		ethernet_private->p_tx_buffer_base[0] =			(char *) memalign (16,					   MV64460_RX_QUEUE_SIZE *					   MV64460_TX_BUFFER_SIZE + 1);#ifdef DEBUG_MV_ETH		/* DEBUG OUTPUT prints adresses of globals */		print_globals (dev);#endif		eth_register (dev);		miiphy_register(dev->name, mv_miiphy_read, mv_miiphy_write);	}	DP (printf ("%s: exit\n", __FUNCTION__));}/********************************************************************** * mv64460_eth_open * * This function is called when openning the network device. The function * should initialize all the hardware, initialize cyclic Rx/Tx * descriptors chain and buffers and allocate an IRQ to the network * device. * * Input : a pointer to the network device structure * / / ronen - changed the output to match  net/eth.c needs * Output : nonzero of success , zero if fails. * under construction **********************************************************************/int mv64460_eth_open (struct eth_device *dev){	return (mv64460_eth_real_open (dev));}/* Helper function for mv64460_eth_open */static int mv64460_eth_real_open (struct eth_device *dev){	unsigned int queue;	ETH_PORT_INFO *ethernet_private;	struct mv64460_eth_priv *port_private;	unsigned int port_num;	u32 port_status;	ushort reg_short;	int speed;	int duplex;	int i;	int reg;	ethernet_private = (ETH_PORT_INFO *) dev->priv;	/* ronen - when we update the MAC env params we only update dev->enetaddr	   see ./net/eth.c eth_set_enetaddr() */	memcpy (ethernet_private->port_mac_addr, dev->enetaddr, 6);	port_private = (struct mv64460_eth_priv *) ethernet_private->port_private;	port_num = port_private->port_num;	/* Stop RX Queues */	MV_REG_WRITE (MV64460_ETH_RECEIVE_QUEUE_COMMAND_REG (port_num), 0x0000ff00);	/* Clear the ethernet port interrupts */	MV_REG_WRITE (MV64460_ETH_INTERRUPT_CAUSE_REG (port_num), 0);	MV_REG_WRITE (MV64460_ETH_INTERRUPT_CAUSE_EXTEND_REG (port_num), 0);	/* Unmask RX buffer and TX end interrupt */	MV_REG_WRITE (MV64460_ETH_INTERRUPT_MASK_REG (port_num),		      INT_CAUSE_UNMASK_ALL);	/* Unmask phy and link status changes interrupts */	MV_REG_WRITE (MV64460_ETH_INTERRUPT_EXTEND_MASK_REG (port_num),		      INT_CAUSE_UNMASK_ALL_EXT);	/* Set phy address of the port */	ethernet_private->port_phy_addr = 0x1 + (port_num << 1);	reg = ethernet_private->port_phy_addr;	/* Activate the DMA channels etc */	eth_port_init (ethernet_private);	/* "Allocate" setup TX rings */	for (queue = 0; queue < MV64460_TX_QUEUE_NUM; queue++) {		unsigned int size;		port_private->tx_ring_size[queue] = MV64460_TX_QUEUE_SIZE;		size = (port_private->tx_ring_size[queue] * TX_DESC_ALIGNED_SIZE);	/*size = no of DESCs times DESC-size */		ethernet_private->tx_desc_area_size[queue] = size;		/* first clear desc area completely */		memset ((void *) ethernet_private->p_tx_desc_area_base[queue],			0, ethernet_private->tx_desc_area_size[queue]);		/* initialize tx desc ring with low level driver */		if (ether_init_tx_desc_ring		    (ethernet_private, ETH_Q0,		     port_private->tx_ring_size[queue],		     MV64460_TX_BUFFER_SIZE /* Each Buffer is 1600 Byte */ ,		     (unsigned int) ethernet_private->		     p_tx_desc_area_base[queue],		     (unsigned int) ethernet_private->		     p_tx_buffer_base[queue]) == false)			printf ("### Error initializing TX Ring\n");	}	/* "Allocate" setup RX rings */	for (queue = 0; queue < MV64460_RX_QUEUE_NUM; queue++) {		unsigned int size;		/* Meantime RX Ring are fixed - but must be configurable by user */		port_private->rx_ring_size[queue] = MV64460_RX_QUEUE_SIZE;		size = (port_private->rx_ring_size[queue] *			RX_DESC_ALIGNED_SIZE);		ethernet_private->rx_desc_area_size[queue] = size;		/* first clear desc area completely */		memset ((void *) ethernet_private->p_rx_desc_area_base[queue],			0, ethernet_private->rx_desc_area_size[queue]);		if ((ether_init_rx_desc_ring		     (ethernet_private, ETH_Q0,		      port_private->rx_ring_size[queue],		      MV64460_RX_BUFFER_SIZE /* Each Buffer is 1600 Byte */ ,		      (unsigned int) ethernet_private->		      p_rx_desc_area_base[queue],		      (unsigned int) ethernet_private->		      p_rx_buffer_base[queue])) == false)			printf ("### Error initializing RX Ring\n");	}	eth_port_start (ethernet_private);	/* Set maximum receive buffer to 9700 bytes */	MV_REG_WRITE (MV64460_ETH_PORT_SERIAL_CONTROL_REG (port_num),		      (0x5 << 17) |		      (MV_REG_READ		       (MV64460_ETH_PORT_SERIAL_CONTROL_REG (port_num))		       & 0xfff1ffff));	/*	 * Set ethernet MTU for leaky bucket mechanism to 0 - this will	 * disable the leaky bucket mechanism .	 */	MV_REG_WRITE (MV64460_ETH_MAXIMUM_TRANSMIT_UNIT (port_num), 0);	port_status = MV_REG_READ (MV64460_ETH_PORT_STATUS_REG (port_num));#if defined(CONFIG_PHY_RESET)	/*	 * Reset the phy, only if its the first time through	 * otherwise, just check the speeds & feeds	 */	if (port_private->first_init == 0) {		port_private->first_init = 1;		ethernet_phy_reset (port_num);		/* Start/Restart autonegotiation */		phy_setup_aneg (dev->name, reg);		udelay (1000);	}#endif /* defined(CONFIG_PHY_RESET) */	miiphy_read (dev->name, reg, PHY_BMSR, &reg_short);	/*	 * Wait if PHY is capable of autonegotiation and autonegotiation is not complete	 */	if ((reg_short & PHY_BMSR_AUTN_ABLE)	    && !(reg_short & PHY_BMSR_AUTN_COMP)) {		puts ("Waiting for PHY auto negotiation to complete");		i = 0;		while (!(reg_short & PHY_BMSR_AUTN_COMP)) {			/*			 * Timeout reached ?			 */			if (i > PHY_AUTONEGOTIATE_TIMEOUT) {				puts (" TIMEOUT !\n");				break;			}			if ((i++ % 1000) == 0) {				putc ('.');			}			udelay (1000);	/* 1 ms */			miiphy_read (dev->name, reg, PHY_BMSR, &reg_short);		}		puts (" done\n");		udelay (500000);	/* another 500 ms (results in faster booting) */	}	speed = miiphy_speed (dev->name, reg);	duplex = miiphy_duplex (dev->name, reg);	printf ("ENET Speed is %d Mbps - %s duplex connection\n",		(int) speed, (duplex == HALF) ? "HALF" : "FULL");	port_private->eth_running = MAGIC_ETH_RUNNING;	return 1;}static int mv64460_eth_free_tx_rings (struct eth_device *dev){	unsigned int queue;	ETH_PORT_INFO *ethernet_private;	struct mv64460_eth_priv *port_private;	unsigned int port_num;	volatile ETH_TX_DESC *p_tx_curr_desc;	ethernet_private = (ETH_PORT_INFO *) dev->priv;	port_private =		(struct mv64460_eth_priv *) ethernet_private->port_private;	port_num = port_private->port_num;	/* Stop Tx Queues */	MV_REG_WRITE (MV64460_ETH_TRANSMIT_QUEUE_COMMAND_REG (port_num),		      0x0000ff00);	/* Free TX rings */	DP (printf ("Clearing previously allocated TX queues... "));	for (queue = 0; queue < MV64460_TX_QUEUE_NUM; queue++) {		/* Free on TX rings */		for (p_tx_curr_desc =		     ethernet_private->p_tx_desc_area_base[queue];		     ((unsigned int) p_tx_curr_desc <= (unsigned int)		      ethernet_private->p_tx_desc_area_base[queue] +		      ethernet_private->tx_desc_area_size[queue]);		     p_tx_curr_desc =		     (ETH_TX_DESC *) ((unsigned int) p_tx_curr_desc +				      TX_DESC_ALIGNED_SIZE)) {			/* this is inside for loop */			if (p_tx_curr_desc->return_info != 0) {				p_tx_curr_desc->return_info = 0;				DP (printf ("freed\n"));			}		}		DP (printf ("Done\n"));	}	return 0;}static int mv64460_eth_free_rx_rings (struct eth_device *dev){	unsigned int queue;	ETH_PORT_INFO *ethernet_private;	struct mv64460_eth_priv *port_private;	unsigned int port_num;	volatile ETH_RX_DESC *p_rx_curr_desc;	ethernet_private = (ETH_PORT_INFO *) dev->priv;	port_private =		(struct mv64460_eth_priv *) ethernet_private->port_private;	port_num = port_private->port_num;	/* Stop RX Queues */	MV_REG_WRITE (MV64460_ETH_RECEIVE_QUEUE_COMMAND_REG (port_num),		      0x0000ff00);	/* Free RX rings */	DP (printf ("Clearing previously allocated RX queues... "));	for (queue = 0; queue < MV64460_RX_QUEUE_NUM; queue++) {		/* Free preallocated skb's on RX rings */		for (p_rx_curr_desc =		     ethernet_private->p_rx_desc_area_base[queue];		     (((unsigned int) p_rx_curr_desc <		       ((unsigned int) ethernet_private->			p_rx_desc_area_base[queue] +			ethernet_private->rx_desc_area_size[queue])));		     p_rx_curr_desc =		     (ETH_RX_DESC *) ((unsigned int) p_rx_curr_desc +				      RX_DESC_ALIGNED_SIZE)) {			if (p_rx_curr_desc->return_info != 0) {				p_rx_curr_desc->return_info = 0;				DP (printf ("freed\n"));			}		}		DP (printf ("Done\n"));	}	return 0;}/********************************************************************** * mv64460_eth_stop * * This function is used when closing the network device. * It updates the hardware, * release all memory that holds buffers and descriptors and release the IRQ. * Input : a pointer to the device structure * Output : zero if success , nonzero if fails *********************************************************************/int mv64460_eth_stop (struct eth_device *dev){	ETH_PORT_INFO *ethernet_private;	struct mv64460_eth_priv *port_private;	unsigned int port_num;	ethernet_private = (ETH_PORT_INFO *) dev->priv;	port_private =		(struct mv64460_eth_priv *) ethernet_private->port_private;	port_num = port_private->port_num;	/* Disable all gigE address decoder */	MV_REG_WRITE (MV64460_ETH_BASE_ADDR_ENABLE_REG, 0x3f);	DP (printf ("%s Ethernet stop called ... \n", __FUNCTION__));	mv64460_eth_real_stop (dev);	return 0;};/* Helper function for mv64460_eth_stop */static int mv64460_eth_real_stop (struct eth_device *dev){	ETH_PORT_INFO *ethernet_private;	struct mv64460_eth_priv *port_private;	unsigned int port_num;	ethernet_private = (ETH_PORT_INFO *) dev->priv;	port_private =		(struct mv64460_eth_priv *) ethernet_private->port_private;	port_num = port_private->port_num;	mv64460_eth_free_tx_rings (dev);	mv64460_eth_free_rx_rings (dev);	eth_port_reset (ethernet_private->port_num);	/* Disable ethernet port interrupts */	MV_REG_WRITE (MV64460_ETH_INTERRUPT_CAUSE_REG (port_num), 0);	MV_REG_WRITE (MV64460_ETH_INTERRUPT_CAUSE_EXTEND_REG (port_num), 0);	/* Mask RX buffer and TX end interrupt */	MV_REG_WRITE (MV64460_ETH_INTERRUPT_MASK_REG (port_num), 0);	/* Mask phy and link status changes interrupts */	MV_REG_WRITE (MV64460_ETH_INTERRUPT_EXTEND_MASK_REG (port_num), 0);	MV_RESET_REG_BITS (MV64460_CPU_INTERRUPT0_MASK_HIGH,			   BIT0 << port_num);	/* Print Network statistics */#ifndef	 UPDATE_STATS_BY_SOFTWARE	/*	 * Print statistics (only if ethernet is running),	 * then zero all the stats fields in memory	 */	if (port_private->eth_running == MAGIC_ETH_RUNNING) {		port_private->eth_running = 0;		mv64460_eth_print_stat (dev);	}	memset (port_private->stats, 0, sizeof (struct net_device_stats));#endif	DP (printf ("\nEthernet stopped ... \n"));	return 0;

⌨️ 快捷键说明

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