diff options
Diffstat (limited to 'drivers/net/tsec.c')
-rw-r--r-- | drivers/net/tsec.c | 249 |
1 files changed, 126 insertions, 123 deletions
diff --git a/drivers/net/tsec.c b/drivers/net/tsec.c index 9a91b9e..a2705e1 100644 --- a/drivers/net/tsec.c +++ b/drivers/net/tsec.c @@ -5,7 +5,7 @@ * terms of the GNU Public License, Version 2, incorporated * herein by reference. * - * Copyright 2004-2010 Freescale Semiconductor, Inc. + * Copyright 2004-2011 Freescale Semiconductor, Inc. * (C) Copyright 2003, Motorola, Inc. * author Andy Fleming * @@ -50,7 +50,7 @@ static int tsec_recv(struct eth_device *dev); static int tsec_init(struct eth_device *dev, bd_t * bd); static int tsec_initialize(bd_t * bis, struct tsec_info_struct *tsec_info); static void tsec_halt(struct eth_device *dev); -static void init_registers(volatile tsec_t * regs); +static void init_registers(tsec_t *regs); static void startup_tsec(struct eth_device *dev); static int init_phy(struct eth_device *dev); void write_phy_reg(struct tsec_private *priv, uint regnum, uint value); @@ -166,9 +166,9 @@ static int tsec_initialize(bd_t * bis, struct tsec_info_struct *tsec_info) eth_register(dev); /* Reset the MAC */ - priv->regs->maccfg1 |= MACCFG1_SOFT_RESET; + setbits_be32(&priv->regs->maccfg1, MACCFG1_SOFT_RESET); udelay(2); /* Soft Reset must be asserted for 3 TX clocks */ - priv->regs->maccfg1 &= ~(MACCFG1_SOFT_RESET); + clrbits_be32(&priv->regs->maccfg1, MACCFG1_SOFT_RESET); #if defined(CONFIG_MII) || defined(CONFIG_CMD_MII) \ && !defined(BITBANGMII) @@ -190,16 +190,16 @@ static int tsec_init(struct eth_device *dev, bd_t * bd) char tmpbuf[MAC_ADDR_LEN]; int i; struct tsec_private *priv = (struct tsec_private *)dev->priv; - volatile tsec_t *regs = priv->regs; + tsec_t *regs = priv->regs; /* Make sure the controller is stopped */ tsec_halt(dev); /* Init MACCFG2. Defaults to GMII */ - regs->maccfg2 = MACCFG2_INIT_SETTINGS; + out_be32(®s->maccfg2, MACCFG2_INIT_SETTINGS); /* Init ECNTRL */ - regs->ecntrl = ECNTRL_INIT_SETTINGS; + out_be32(®s->ecntrl, ECNTRL_INIT_SETTINGS); /* Copy the station address into the address registers. * Backwards, because little endian MACS are dumb */ @@ -209,11 +209,11 @@ static int tsec_init(struct eth_device *dev, bd_t * bd) tempval = (tmpbuf[0] << 24) | (tmpbuf[1] << 16) | (tmpbuf[2] << 8) | tmpbuf[3]; - regs->macstnaddr1 = tempval; + out_be32(®s->macstnaddr1, tempval); tempval = *((uint *) (tmpbuf + 4)); - regs->macstnaddr2 = tempval; + out_be32(®s->macstnaddr2, tempval); /* reset the indices to zero */ rxIdx = 0; @@ -230,17 +230,17 @@ static int tsec_init(struct eth_device *dev, bd_t * bd) } /* Writes the given phy's reg with value, using the specified MDIO regs */ -static void tsec_local_mdio_write(volatile tsec_mdio_t *phyregs, uint addr, +static void tsec_local_mdio_write(tsec_mdio_t *phyregs, uint addr, uint reg, uint value) { int timeout = 1000000; - phyregs->miimadd = (addr << 8) | reg; - phyregs->miimcon = value; - asm("sync"); + out_be32(&phyregs->miimadd, (addr << 8) | reg); + out_be32(&phyregs->miimcon, value); timeout = 1000000; - while ((phyregs->miimind & MIIMIND_BUSY) && timeout--) ; + while ((in_be32(&phyregs->miimind) & MIIMIND_BUSY) && timeout--) + ; } @@ -254,28 +254,26 @@ static void tsec_local_mdio_write(volatile tsec_mdio_t *phyregs, uint addr, * notvalid bit cleared), and the bus to cease activity (miimind * busy bit cleared), and then returns the value */ -static uint tsec_local_mdio_read(volatile tsec_mdio_t *phyregs, - uint phyid, uint regnum) +static uint tsec_local_mdio_read(tsec_mdio_t *phyregs, uint phyid, uint regnum) { uint value; /* Put the address of the phy, and the register * number into MIIMADD */ - phyregs->miimadd = (phyid << 8) | regnum; + out_be32(&phyregs->miimadd, (phyid << 8) | regnum); /* Clear the command register, and wait */ - phyregs->miimcom = 0; - asm("sync"); + out_be32(&phyregs->miimcom, 0); /* Initiate a read command, and wait */ - phyregs->miimcom = MIIM_READ_COMMAND; - asm("sync"); + out_be32(&phyregs->miimcom, MIIM_READ_COMMAND); /* Wait for the the indication that the read is done */ - while ((phyregs->miimind & (MIIMIND_NOTVALID | MIIMIND_BUSY))) ; + while ((in_be32(&phyregs->miimind) & (MIIMIND_NOTVALID | MIIMIND_BUSY))) + ; /* Grab the value read from the PHY */ - value = phyregs->miimstat; + value = in_be32(&phyregs->miimstat); return value; } @@ -321,18 +319,16 @@ static int init_phy(struct eth_device *dev) { struct tsec_private *priv = (struct tsec_private *)dev->priv; struct phy_info *curphy; - volatile tsec_t *regs = priv->regs; + tsec_t *regs = priv->regs; /* Assign a Physical address to the TBI */ - regs->tbipa = CONFIG_SYS_TBIPA_VALUE; - asm("sync"); + out_be32(®s->tbipa, CONFIG_SYS_TBIPA_VALUE); /* Reset MII (due to new addresses) */ - priv->phyregs->miimcfg = MIIMCFG_RESET; - asm("sync"); - priv->phyregs->miimcfg = MIIMCFG_INIT_VALUE; - asm("sync"); - while (priv->phyregs->miimind & MIIMIND_BUSY) ; + out_be32(&priv->phyregs->miimcfg, MIIMCFG_RESET); + out_be32(&priv->phyregs->miimcfg, MIIMCFG_INIT_VALUE); + while (in_be32(&priv->phyregs->miimind) & MIIMIND_BUSY) + ; /* Get the cmd structure corresponding to the attached * PHY */ @@ -345,7 +341,7 @@ static int init_phy(struct eth_device *dev) return 0; } - if (regs->ecntrl & ECNTRL_SGMII_MODE) + if (in_be32(®s->ecntrl) & ECNTRL_SGMII_MODE) tsec_configure_serdes(priv); priv->phyinfo = curphy; @@ -838,16 +834,16 @@ static uint mii_parse_dm9161_scsr(uint mii_reg, struct tsec_private * priv) static uint mii_cis8204_fixled(uint mii_reg, struct tsec_private * priv) { uint phyid; - volatile tsec_mdio_t *regbase = priv->phyregs; + tsec_mdio_t *regbase = priv->phyregs; int timeout = 1000000; for (phyid = 0; phyid < 4; phyid++) { - regbase->miimadd = (phyid << 8) | mii_reg; - regbase->miimcon = MIIM_CIS8204_SLEDCON_INIT; - asm("sync"); + out_be32(®base->miimadd, (phyid << 8) | mii_reg); + out_be32(®base->miimcon, MIIM_CIS8204_SLEDCON_INIT); timeout = 1000000; - while ((regbase->miimind & MIIMIND_BUSY) && timeout--) ; + while ((in_be32(®base->miimind) & MIIMIND_BUSY) && timeout--) + ; } return MIIM_CIS8204_SLEDCON_INIT; @@ -874,45 +870,45 @@ static uint mii_m88e1111s_setmode(uint mii_reg, struct tsec_private *priv) * those we don't care about (unless zero is bad, in which case, * choose a more appropriate value) */ -static void init_registers(volatile tsec_t * regs) +static void init_registers(tsec_t *regs) { /* Clear IEVENT */ - regs->ievent = IEVENT_INIT_CLEAR; - - regs->imask = IMASK_INIT_CLEAR; - - regs->hash.iaddr0 = 0; - regs->hash.iaddr1 = 0; - regs->hash.iaddr2 = 0; - regs->hash.iaddr3 = 0; - regs->hash.iaddr4 = 0; - regs->hash.iaddr5 = 0; - regs->hash.iaddr6 = 0; - regs->hash.iaddr7 = 0; - - regs->hash.gaddr0 = 0; - regs->hash.gaddr1 = 0; - regs->hash.gaddr2 = 0; - regs->hash.gaddr3 = 0; - regs->hash.gaddr4 = 0; - regs->hash.gaddr5 = 0; - regs->hash.gaddr6 = 0; - regs->hash.gaddr7 = 0; - - regs->rctrl = 0x00000000; + out_be32(®s->ievent, IEVENT_INIT_CLEAR); + + out_be32(®s->imask, IMASK_INIT_CLEAR); + + out_be32(®s->hash.iaddr0, 0); + out_be32(®s->hash.iaddr1, 0); + out_be32(®s->hash.iaddr2, 0); + out_be32(®s->hash.iaddr3, 0); + out_be32(®s->hash.iaddr4, 0); + out_be32(®s->hash.iaddr5, 0); + out_be32(®s->hash.iaddr6, 0); + out_be32(®s->hash.iaddr7, 0); + + out_be32(®s->hash.gaddr0, 0); + out_be32(®s->hash.gaddr1, 0); + out_be32(®s->hash.gaddr2, 0); + out_be32(®s->hash.gaddr3, 0); + out_be32(®s->hash.gaddr4, 0); + out_be32(®s->hash.gaddr5, 0); + out_be32(®s->hash.gaddr6, 0); + out_be32(®s->hash.gaddr7, 0); + + out_be32(®s->rctrl, 0x00000000); /* Init RMON mib registers */ memset((void *)&(regs->rmon), 0, sizeof(rmon_mib_t)); - regs->rmon.cam1 = 0xffffffff; - regs->rmon.cam2 = 0xffffffff; + out_be32(®s->rmon.cam1, 0xffffffff); + out_be32(®s->rmon.cam2, 0xffffffff); - regs->mrblr = MRBLR_INIT_SETTINGS; + out_be32(®s->mrblr, MRBLR_INIT_SETTINGS); - regs->minflr = MINFLR_INIT_SETTINGS; + out_be32(®s->minflr, MINFLR_INIT_SETTINGS); - regs->attr = ATTR_INIT_SETTINGS; - regs->attreli = ATTRELI_INIT_SETTINGS; + out_be32(®s->attr, ATTR_INIT_SETTINGS); + out_be32(®s->attreli, ATTRELI_INIT_SETTINGS); } @@ -922,44 +918,49 @@ static void init_registers(volatile tsec_t * regs) static void adjust_link(struct eth_device *dev) { struct tsec_private *priv = (struct tsec_private *)dev->priv; - volatile tsec_t *regs = priv->regs; + tsec_t *regs = priv->regs; + u32 ecntrl, maccfg2; - if (priv->link) { - if (priv->duplexity != 0) - regs->maccfg2 |= MACCFG2_FULL_DUPLEX; - else - regs->maccfg2 &= ~(MACCFG2_FULL_DUPLEX); + if (!priv->link) { + printf("%s: No link.\n", dev->name); + return; + } - switch (priv->speed) { - case 1000: - regs->maccfg2 = ((regs->maccfg2 & ~(MACCFG2_IF)) - | MACCFG2_GMII); - break; - case 100: - case 10: - regs->maccfg2 = ((regs->maccfg2 & ~(MACCFG2_IF)) - | MACCFG2_MII); + /* clear all bits relative with interface mode */ + ecntrl = in_be32(®s->ecntrl); + ecntrl &= ~ECNTRL_R100; - /* Set R100 bit in all modes although - * it is only used in RGMII mode - */ - if (priv->speed == 100) - regs->ecntrl |= ECNTRL_R100; - else - regs->ecntrl &= ~(ECNTRL_R100); - break; - default: - printf("%s: Speed was bad\n", dev->name); - break; - } + maccfg2 = in_be32(®s->maccfg2); + maccfg2 &= ~(MACCFG2_IF | MACCFG2_FULL_DUPLEX); - printf("Speed: %d, %s duplex%s\n", priv->speed, - (priv->duplexity) ? "full" : "half", - (priv->flags & TSEC_FIBER) ? ", fiber mode" : ""); + if (priv->duplexity) + maccfg2 |= MACCFG2_FULL_DUPLEX; - } else { - printf("%s: No link.\n", dev->name); + switch (priv->speed) { + case 1000: + maccfg2 |= MACCFG2_GMII; + break; + case 100: + case 10: + maccfg2 |= MACCFG2_MII; + + /* Set R100 bit in all modes although + * it is only used in RGMII mode + */ + if (priv->speed == 100) + ecntrl |= ECNTRL_R100; + break; + default: + printf("%s: Speed was bad\n", dev->name); + break; } + + out_be32(®s->ecntrl, ecntrl); + out_be32(®s->maccfg2, maccfg2); + + printf("Speed: %d, %s duplex%s\n", priv->speed, + (priv->duplexity) ? "full" : "half", + (priv->flags & TSEC_FIBER) ? ", fiber mode" : ""); } /* Set up the buffers and their descriptors, and bring up the @@ -969,11 +970,11 @@ static void startup_tsec(struct eth_device *dev) { int i; struct tsec_private *priv = (struct tsec_private *)dev->priv; - volatile tsec_t *regs = priv->regs; + tsec_t *regs = priv->regs; /* Point to the buffer descriptors */ - regs->tbase = (unsigned int)(&rtx.txbd[txIdx]); - regs->rbase = (unsigned int)(&rtx.rxbd[rxIdx]); + out_be32(®s->tbase, (unsigned int)(&rtx.txbd[txIdx])); + out_be32(®s->rbase, (unsigned int)(&rtx.rxbd[rxIdx])); /* Initialize the Rx Buffer descriptors */ for (i = 0; i < PKTBUFSRX; i++) { @@ -998,13 +999,13 @@ static void startup_tsec(struct eth_device *dev) adjust_link(dev); /* Enable Transmit and Receive */ - regs->maccfg1 |= (MACCFG1_RX_EN | MACCFG1_TX_EN); + setbits_be32(®s->maccfg1, MACCFG1_RX_EN | MACCFG1_TX_EN); /* Tell the DMA it is clear to go */ - regs->dmactrl |= DMACTRL_INIT_SETTINGS; - regs->tstat = TSTAT_CLEAR_THALT; - regs->rstat = RSTAT_CLEAR_RHALT; - regs->dmactrl &= ~(DMACTRL_GRS | DMACTRL_GTS); + setbits_be32(®s->dmactrl, DMACTRL_INIT_SETTINGS); + out_be32(®s->tstat, TSTAT_CLEAR_THALT); + out_be32(®s->rstat, RSTAT_CLEAR_RHALT); + clrbits_be32(®s->dmactrl, DMACTRL_GRS | DMACTRL_GTS); } /* This returns the status bits of the device. The return value @@ -1017,7 +1018,7 @@ static int tsec_send(struct eth_device *dev, volatile void *packet, int length) int i; int result = 0; struct tsec_private *priv = (struct tsec_private *)dev->priv; - volatile tsec_t *regs = priv->regs; + tsec_t *regs = priv->regs; /* Find an empty buffer descriptor */ for (i = 0; rtx.txbd[txIdx].status & TXBD_READY; i++) { @@ -1033,7 +1034,7 @@ static int tsec_send(struct eth_device *dev, volatile void *packet, int length) (TXBD_READY | TXBD_LAST | TXBD_CRC | TXBD_INTERRUPT); /* Tell the DMA to go */ - regs->tstat = TSTAT_CLEAR_THALT; + out_be32(®s->tstat, TSTAT_CLEAR_THALT); /* Wait for buffer to be transmitted */ for (i = 0; rtx.txbd[txIdx].status & TXBD_READY; i++) { @@ -1053,7 +1054,7 @@ static int tsec_recv(struct eth_device *dev) { int length; struct tsec_private *priv = (struct tsec_private *)dev->priv; - volatile tsec_t *regs = priv->regs; + tsec_t *regs = priv->regs; while (!(rtx.rxbd[rxIdx].status & RXBD_EMPTY)) { @@ -1076,9 +1077,9 @@ static int tsec_recv(struct eth_device *dev) rxIdx = (rxIdx + 1) % PKTBUFSRX; } - if (regs->ievent & IEVENT_BSY) { - regs->ievent = IEVENT_BSY; - regs->rstat = RSTAT_CLEAR_RHALT; + if (in_be32(®s->ievent) & IEVENT_BSY) { + out_be32(®s->ievent, IEVENT_BSY); + out_be32(®s->rstat, RSTAT_CLEAR_RHALT); } return -1; @@ -1089,15 +1090,16 @@ static int tsec_recv(struct eth_device *dev) static void tsec_halt(struct eth_device *dev) { struct tsec_private *priv = (struct tsec_private *)dev->priv; - volatile tsec_t *regs = priv->regs; + tsec_t *regs = priv->regs; - regs->dmactrl &= ~(DMACTRL_GRS | DMACTRL_GTS); - regs->dmactrl |= (DMACTRL_GRS | DMACTRL_GTS); + clrbits_be32(®s->dmactrl, DMACTRL_GRS | DMACTRL_GTS); + setbits_be32(®s->dmactrl, DMACTRL_GRS | DMACTRL_GTS); - while ((regs->ievent & (IEVENT_GRSC | IEVENT_GTSC)) - != (IEVENT_GRSC | IEVENT_GTSC)) ; + while ((in_be32(®s->ievent) & (IEVENT_GRSC | IEVENT_GTSC)) + != (IEVENT_GRSC | IEVENT_GTSC)) + ; - regs->maccfg1 &= ~(MACCFG1_TX_EN | MACCFG1_RX_EN); + clrbits_be32(®s->maccfg1, MACCFG1_TX_EN | MACCFG1_RX_EN); /* Shut down the PHY, as needed */ if(priv->phyinfo) @@ -1904,13 +1906,14 @@ static void phy_run_commands(struct tsec_private *priv, struct phy_cmd *cmd) { int i; uint result; - volatile tsec_mdio_t *phyregs = priv->phyregs; + tsec_mdio_t *phyregs = priv->phyregs; - phyregs->miimcfg = MIIMCFG_RESET; + out_be32(&phyregs->miimcfg, MIIMCFG_RESET); - phyregs->miimcfg = MIIMCFG_INIT_VALUE; + out_be32(&phyregs->miimcfg, MIIMCFG_INIT_VALUE); - while (phyregs->miimind & MIIMIND_BUSY) ; + while (in_be32(&phyregs->miimind) & MIIMIND_BUSY) + ; for (i = 0; cmd->mii_reg != miim_end; i++) { if (cmd->mii_data == miim_read) { |