diff options
Diffstat (limited to 'drivers/net/tsec.c')
| -rw-r--r-- | drivers/net/tsec.c | 241 | 
1 files changed, 122 insertions, 119 deletions
| diff --git a/drivers/net/tsec.c b/drivers/net/tsec.c index 9a91b9e0b..a2705e1ca 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; +	out_be32(®s->ievent, IEVENT_INIT_CLEAR); -	regs->imask = IMASK_INIT_CLEAR; +	out_be32(®s->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; +	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); -	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; +	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); -	regs->rctrl = 0x00000000; +	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) { |