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 + -
显示快捷键?