ax88180.c

来自「最新版的u-boot,2008-10-18发布」· C语言 代码 · 共 728 行 · 第 1/2 页

C
728
字号
			break;		case MEDIA_1000HALF:			debug ("ax88180: 1000Mbps Half-duplex mode.\n");			rxcfg_val = DEFAULT_RXCFG;			maccfg0_val = DEFAULT_MACCFG0;			maccfg1_val = GIGA_MODE_EN | DEFAULT_MACCFG1;			break;		case MEDIA_100FULL:			debug ("ax88180: 100Mbps Full-duplex mode.\n");			rxcfg_val = RXFLOW_ENABLE | DEFAULT_RXCFG;			maccfg0_val = SPEED100 | TXFLOW_ENABLE			    | DEFAULT_MACCFG0;			maccfg1_val = RXFLOW_EN | FULLDUPLEX | DEFAULT_MACCFG1;			break;		case MEDIA_100HALF:			debug ("ax88180: 100Mbps Half-duplex mode.\n");			rxcfg_val = DEFAULT_RXCFG;			maccfg0_val = SPEED100 | DEFAULT_MACCFG0;			maccfg1_val = DEFAULT_MACCFG1;			break;		case MEDIA_10FULL:			debug ("ax88180: 10Mbps Full-duplex mode.\n");			rxcfg_val = RXFLOW_ENABLE | DEFAULT_RXCFG;			maccfg0_val = TXFLOW_ENABLE | DEFAULT_MACCFG0;			maccfg1_val = RXFLOW_EN | FULLDUPLEX | DEFAULT_MACCFG1;			break;		case MEDIA_10HALF:			debug ("ax88180: 10Mbps Half-duplex mode.\n");			rxcfg_val = DEFAULT_RXCFG;			maccfg0_val = DEFAULT_MACCFG0;			maccfg1_val = DEFAULT_MACCFG1;			break;		default:			debug ("ax88180: Unknow media mode.\n");			rxcfg_val = DEFAULT_RXCFG;			maccfg0_val = DEFAULT_MACCFG0;			maccfg1_val = DEFAULT_MACCFG1;			priv->LinkState = INS_LINK_DOWN;			break;		}	} else {		rxcfg_val = DEFAULT_RXCFG;		maccfg0_val = DEFAULT_MACCFG0;		maccfg1_val = DEFAULT_MACCFG1;		priv->LinkState = INS_LINK_DOWN;	}	OUTW (dev, rxcfg_val, RXCFG);	OUTW (dev, maccfg0_val, MACCFG0);	OUTW (dev, maccfg1_val, MACCFG1);	return;}static unsigned long get_MarvellPHY_meida_mode (struct eth_device *dev){	unsigned long m88_ssr;	unsigned long MediaMode;	m88_ssr = ax88180_mdio_read (dev, M88_SSR);	switch (m88_ssr & SSR_MEDIA_MASK) {	case SSR_1000FULL:		MediaMode = MEDIA_1000FULL;		break;	case SSR_1000HALF:		MediaMode = MEDIA_1000HALF;		break;	case SSR_100FULL:		MediaMode = MEDIA_100FULL;		break;	case SSR_100HALF:		MediaMode = MEDIA_100HALF;		break;	case SSR_10FULL:		MediaMode = MEDIA_10FULL;		break;	case SSR_10HALF:		MediaMode = MEDIA_10HALF;		break;	default:		MediaMode = MEDIA_UNKNOWN;		break;	}	return MediaMode;}static unsigned long get_CicadaPHY_meida_mode (struct eth_device *dev){	unsigned long tmp_regval;	unsigned long MediaMode;	tmp_regval = ax88180_mdio_read (dev, CIS_AUX_CTRL_STATUS);	switch (tmp_regval & CIS_MEDIA_MASK) {	case CIS_1000FULL:		MediaMode = MEDIA_1000FULL;		break;	case CIS_1000HALF:		MediaMode = MEDIA_1000HALF;		break;	case CIS_100FULL:		MediaMode = MEDIA_100FULL;		break;	case CIS_100HALF:		MediaMode = MEDIA_100HALF;		break;	case CIS_10FULL:		MediaMode = MEDIA_10FULL;		break;	case CIS_10HALF:		MediaMode = MEDIA_10HALF;		break;	default:		MediaMode = MEDIA_UNKNOWN;		break;	}	return MediaMode;}static void ax88180_halt (struct eth_device *dev){	/* Disable AX88180 TX/RX functions */	OUTW (dev, WAKEMOD, CMD);}static int ax88180_init (struct eth_device *dev, bd_t * bd){	struct ax88180_private *priv = (struct ax88180_private *)dev->priv;	unsigned short tmp_regval;	ax88180_mac_reset (dev);	/* Disable interrupt */	OUTW (dev, CLEAR_IMR, IMR);	/* Disable AX88180 TX/RX functions */	OUTW (dev, WAKEMOD, CMD);	/* Fill the MAC address */	tmp_regval =	    dev->enetaddr[0] | (((unsigned short)dev->enetaddr[1]) << 8);	OUTW (dev, tmp_regval, MACID0);	tmp_regval =	    dev->enetaddr[2] | (((unsigned short)dev->enetaddr[3]) << 8);	OUTW (dev, tmp_regval, MACID1);	tmp_regval =	    dev->enetaddr[4] | (((unsigned short)dev->enetaddr[5]) << 8);	OUTW (dev, tmp_regval, MACID2);	ax88180_meidia_config (dev);	OUTW (dev, DEFAULT_RXFILTER, RXFILTER);	/* Initial variables here */	priv->FirstTxDesc = TXDP0;	priv->NextTxDesc = TXDP0;	/* Check if there is any invalid interrupt status and clear it. */	OUTW (dev, INW (dev, ISR), ISR);	/* Start AX88180 TX/RX functions */	OUTW (dev, (RXEN | TXEN | WAKEMOD), CMD);	return 0;}/* Get a data block via Ethernet */static int ax88180_recv (struct eth_device *dev){	unsigned short ISR_Status;	unsigned short tmp_regval;	/* Read and check interrupt status here. */	ISR_Status = INW (dev, ISR);	while (ISR_Status) {		/* Clear the interrupt status */		OUTW (dev, ISR_Status, ISR);		debug ("\nax88180: The interrupt status = 0x%04x\n",		       ISR_Status);		if (ISR_Status & ISR_PHY) {			/* Read ISR register once to clear PHY interrupt bit */			tmp_regval = ax88180_mdio_read (dev, M88_ISR);			ax88180_meidia_config (dev);		}		if ((ISR_Status & ISR_RX) || (ISR_Status & ISR_RXBUFFOVR)) {			ax88180_rx_handler (dev);		}		/* Read and check interrupt status again */		ISR_Status = INW (dev, ISR);	}	return 0;}/* Send a data block via Ethernet. */static intax88180_send (struct eth_device *dev, volatile void *packet, int length){	struct ax88180_private *priv = (struct ax88180_private *)dev->priv;	unsigned short TXDES_addr;	unsigned short txcmd_txdp, txbs_txdp;	unsigned short tmp_data;	int i;#if defined (CONFIG_DRIVER_AX88180_16BIT)	volatile unsigned short *txdata = (volatile unsigned short *)packet;#else	volatile unsigned long *txdata = (volatile unsigned long *)packet;#endif	unsigned short count;	if (priv->LinkState != INS_LINK_UP) {		return 0;	}	priv->FirstTxDesc = priv->NextTxDesc;	txbs_txdp = 1 << priv->FirstTxDesc;	debug ("ax88180: TXDP%d is available\n", priv->FirstTxDesc);	txcmd_txdp = priv->FirstTxDesc << 13;	TXDES_addr = TXDES0 + (priv->FirstTxDesc << 2);	OUTW (dev, (txcmd_txdp | length | TX_START_WRITE), TXCMD);	/* Comput access times */	count = (length + priv->PadSize) >> priv->BusWidth;	for (i = 0; i < count; i++) {		WRITE_TXBUF (dev, *(txdata + i));	}	OUTW (dev, txcmd_txdp | length, TXCMD);	OUTW (dev, txbs_txdp, TXBS);	OUTW (dev, (TXDPx_ENABLE | length), TXDES_addr);	priv->NextTxDesc = (priv->NextTxDesc + 1) & TXDP_MASK;	/*	 * Check the available transmit descriptor, if we had exhausted all	 * transmit descriptor ,then we have to wait for at least one free	 * descriptor	 */	txbs_txdp = 1 << priv->NextTxDesc;	tmp_data = INW (dev, TXBS);	if (tmp_data & txbs_txdp) {		if (ax88180_poll_tx_complete (dev) < 0) {			ax88180_mac_reset (dev);			priv->FirstTxDesc = TXDP0;			priv->NextTxDesc = TXDP0;			printf ("ax88180: Transmit time out occurred!\n");		}	}	return 0;}static void ax88180_read_mac_addr (struct eth_device *dev){	unsigned short macid0_val, macid1_val, macid2_val;	unsigned short tmp_regval;	unsigned short i;	/* Reload MAC address from EEPROM */	OUTW (dev, RELOAD_EEPROM, PROMCTRL);	/* Waiting for reload eeprom completion */	for (i = 0; i < 500; i++) {		tmp_regval = INW (dev, PROMCTRL);		if ((tmp_regval & RELOAD_EEPROM) == 0)			break;		udelay (1000);	}	/* Get MAC addresses */	macid0_val = INW (dev, MACID0);	macid1_val = INW (dev, MACID1);	macid2_val = INW (dev, MACID2);	if (((macid0_val | macid1_val | macid2_val) != 0) &&	    ((macid0_val & 0x01) == 0)) {		dev->enetaddr[0] = (unsigned char)macid0_val;		dev->enetaddr[1] = (unsigned char)(macid0_val >> 8);		dev->enetaddr[2] = (unsigned char)macid1_val;		dev->enetaddr[3] = (unsigned char)(macid1_val >> 8);		dev->enetaddr[4] = (unsigned char)macid2_val;		dev->enetaddr[5] = (unsigned char)(macid2_val >> 8);	}}/*===========================================================================<<<<<<			Exported SubProgram Bodies		>>>>>>===========================================================================*/int ax88180_initialize (bd_t * bis){	struct eth_device *dev;	struct ax88180_private *priv;	dev = (struct eth_device *)malloc (sizeof *dev);	if (NULL == dev)		return 0;	memset (dev, 0, sizeof *dev);	priv = (struct ax88180_private *)malloc (sizeof (*priv));	if (NULL == priv)		return 0;	memset (priv, 0, sizeof *priv);	sprintf (dev->name, "ax88180");	dev->iobase = AX88180_BASE;	dev->priv = priv;	dev->init = ax88180_init;	dev->halt = ax88180_halt;	dev->send = ax88180_send;	dev->recv = ax88180_recv;	priv->BusWidth = BUS_WIDTH_32;	priv->PadSize = 3;#if defined (CONFIG_DRIVER_AX88180_16BIT)	OUTW (dev, (START_BASE >> 8), BASE);	OUTW (dev, DECODE_EN, DECODE);	priv->BusWidth = BUS_WIDTH_16;	priv->PadSize = 1;#endif	ax88180_mac_reset (dev);	/* Disable interrupt */	OUTW (dev, CLEAR_IMR, IMR);	/* Disable AX88180 TX/RX functions */	OUTW (dev, WAKEMOD, CMD);	ax88180_read_mac_addr (dev);	eth_register (dev);	return ax88180_phy_initial (dev);}

⌨️ 快捷键说明

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