Beispiel #1
0
static int mdio_read(int base_address, int phy_id, int location)
{
    long mdio_addr = base_address + MIICtrl;
    int mii_cmd = (0xf6 << 10) | (phy_id << 5) | location;
    int i, retval = 0;

    if (mii_preamble_required)
        mdio_sync(mdio_addr);

    
    for (i = 15; i >= 0; i--) {
        int dataval = (mii_cmd & (1 << i)) ? MDIO_WRITE1 : MDIO_WRITE0;

        writel(dataval, mdio_addr);
        mdio_delay(mdio_addr);
        writel(dataval | MDIO_ShiftClk, mdio_addr);
        mdio_delay(mdio_addr);
    }
    
    for (i = 20; i > 0; i--) {
        writel(MDIO_EnbIn, mdio_addr);
        mdio_delay(mdio_addr);
        retval = (retval << 1) | ((readl(mdio_addr) & MDIO_DataIn) ? 1 : 0);
        writel(MDIO_EnbIn | MDIO_ShiftClk, mdio_addr);
        mdio_delay(mdio_addr);
    }
    return (retval>>1) & 0xffff;
}
Beispiel #2
0
static int mdio_read(struct dev *dev, int phy_id, int location) {
  struct nic *np = (struct nic *) dev->privdata;
  long mdio_addr = np->iobase + MII_SMI;
  int mii_cmd = (0xf6 << 10) | (phy_id << 5) | location;
  int retval = 0;
  int i;

  if (phy_id > 31) {
    // Really a 8139.  Use internal registers
    return location < 8 && mii_2_8139_map[location] ? inpw(np->iobase + mii_2_8139_map[location]) : 0;
  }

  mdio_sync(mdio_addr);

  // Shift the read command bits out
  for (i = 15; i >= 0; i--) {
    int dataval = (mii_cmd & (1 << i)) ? MDIO_DATA_OUT : 0;

    outp(mdio_addr, MDIO_DIR | dataval);
    mdio_delay(mdio_addr);
    outp(mdio_addr, MDIO_DIR | dataval | MDIO_CLK);
    mdio_delay(mdio_addr);
  }

  // Read the two transition, 16 data, and wire-idle bits
  for (i = 19; i > 0; i--) {
    outp(mdio_addr, 0);
    mdio_delay(mdio_addr);
    retval = (retval << 1) | ((inp(mdio_addr) & MDIO_DATA_IN) ? 1 : 0);
    outp(mdio_addr, MDIO_CLK);
    mdio_delay(mdio_addr);
  }

  return (retval >> 1) & 0xffff;
}
Beispiel #3
0
static int
mdio_read(struct eth_device *dev, int phy_id, int addr)
{
	int mii_cmd = (0xf6 << 10) | (phy_id << 5) | addr;
	int i, retval = 0;

	/* Shift the read command bits out. */
	for (i = 15; i >= 0; i--) {
		int dataval = (mii_cmd & (1 << i)) ? MDIO_WRITE1 : MDIO_WRITE0;

		OUTL(dev, dataval, EECtrl);
		mdio_delay(EECtrl);
		OUTL(dev, dataval | MDIO_ShiftClk, EECtrl);
		mdio_delay(EECtrl);
	}
	/* Read the two transition, 16 data, and wire-idle bits. */
	for (i = 19; i > 0; i--) {
		OUTL(dev, MDIO_EnbIn, EECtrl);
		mdio_delay(EECtrl);
		retval =
		    (retval << 1) | ((INL(dev, EECtrl) & MDIO_Data) ? 1 : 0);
		OUTL(dev, MDIO_EnbIn | MDIO_ShiftClk, EECtrl);
		mdio_delay(EECtrl);
	}
	return (retval >> 1) & 0xffff;
}
Beispiel #4
0
static void mdio_write(int base_address, int phy_id, int location, int value)
{
    long mdio_addr = base_address + MIICtrl;
    int mii_cmd = (0x5002 << 16) | (phy_id << 23) | (location<<18) | value;
    int i;

    if (location == 4  &&  phy_id == w840private.phys[0])
        w840private.advertising = value;

    if (mii_preamble_required)
        mdio_sync(mdio_addr);

    
    for (i = 31; i >= 0; i--) {
        int dataval = (mii_cmd & (1 << i)) ? MDIO_WRITE1 : MDIO_WRITE0;

        writel(dataval, mdio_addr);
        mdio_delay(mdio_addr);
        writel(dataval | MDIO_ShiftClk, mdio_addr);
        mdio_delay(mdio_addr);
    }
    
    for (i = 2; i > 0; i--) {
        writel(MDIO_EnbIn, mdio_addr);
        mdio_delay(mdio_addr);
        writel(MDIO_EnbIn | MDIO_ShiftClk, mdio_addr);
        mdio_delay(mdio_addr);
    }
    return;
}
Beispiel #5
0
/***********************************************************************************
 * FUNCTION PURPOSE: Perform blind MDIO access
 ***********************************************************************************
 * DESCRIPTION: Pre-configured mdio access is performed.
 ***********************************************************************************/
void hwMdio (int16 nAccess, uint32 *access, uint16 clkdiv, uint32 delayCpuCycles)
{
    int16 i;

    /* Enable MDIO, set the divider. A divider value of 0 is not allowed */
    if (clkdiv == 0)
        clkdiv = 1;

    MDIOR->CONTROL = (0x40000000 | clkdiv);


    for (i = 0; i < nAccess; i++)  {

        /* Set the Go bit */
        MDIOR->USERACCESS0 = (((uint32)1 << 31) | access[i]);
        while (MDIOR->USERACCESS0 & 0x80000000);

        mdio_delay (delayCpuCycles);

    }

    /* A big delay after the last configure */
    mdio_delay (1000000);

}
Beispiel #6
0
static int mdio_read(struct net_device *dev, int phy_id, int location)
{
	long mdio_addr = dev->base_addr + MIICtrl;
	int mii_cmd = (0xf6 << 10) | (phy_id << 5) | location;
	int i, retval = 0;

	if (mii_preamble_required)
		mdio_sync(mdio_addr);

	/* Shift the read command bits out. */
	for (i = 15; i >= 0; i--) {
		int dataval = (mii_cmd & (1 << i)) ? MDIO_WRITE1 : MDIO_WRITE0;

		writeb(dataval, mdio_addr);
		mdio_delay();
		writeb(dataval | MDIO_ShiftClk, mdio_addr);
		mdio_delay();
	}
	/* Read the two transition, 16 data, and wire-idle bits. */
	for (i = 19; i > 0; i--) {
		writeb(MDIO_EnbIn, mdio_addr);
		mdio_delay();
		retval = (retval << 1) | ((readb(mdio_addr) & MDIO_Data) ? 1 : 0);
		writeb(MDIO_EnbIn | MDIO_ShiftClk, mdio_addr);
		mdio_delay();
	}
	return (retval>>1) & 0xffff;
}
Beispiel #7
0
static void mdio_write(struct device *dev, int phy_id, int location, int value)
{
	long mdio_addr = dev->base_addr + MII_SMI;
	int mii_cmd = (0x5002 << 16) | (phy_id << 23) | (location<<18) | value;
	int i;

	if (phy_id > 31) {	/* Really a 8139.  Use internal registers. */
		if (location < 8  &&  mii_2_8139_map[location])
			outw(value, dev->base_addr + mii_2_8139_map[location]);
		return;
	}
	mdio_sync(mdio_addr);

	/* Shift the command bits out. */
	for (i = 31; i >= 0; i--) {
		int dataval = (mii_cmd & (1 << i)) ? MDIO_WRITE1 : MDIO_WRITE0;
		outb(dataval, mdio_addr);
		mdio_delay();
		outb(dataval | MDIO_CLK, mdio_addr);
		mdio_delay();
	}
	/* Clear out extra bits. */
	for (i = 2; i > 0; i--) {
		outb(0, mdio_addr);
		mdio_delay();
		outb(MDIO_CLK, mdio_addr);
		mdio_delay();
	}
	return;
}
Beispiel #8
0
static void mdio_write(struct net_device *dev, int phy_id, int location, int value)
{
	long mdio_addr = dev->base_addr + MIICtrl;
	int mii_cmd = (0x5002 << 16) | (phy_id << 23) | (location<<18) | value;
	int i;

	if (mii_preamble_required)
		mdio_sync(mdio_addr);

	/* Shift the command bits out. */
	for (i = 31; i >= 0; i--) {
		int dataval = (mii_cmd & (1 << i)) ? MDIO_WRITE1 : MDIO_WRITE0;

		writeb(dataval, mdio_addr);
		mdio_delay();
		writeb(dataval | MDIO_ShiftClk, mdio_addr);
		mdio_delay();
	}
	/* Clear out extra bits. */
	for (i = 2; i > 0; i--) {
		writeb(MDIO_EnbIn, mdio_addr);
		mdio_delay();
		writeb(MDIO_EnbIn | MDIO_ShiftClk, mdio_addr);
		mdio_delay();
	}
	return;
}
Beispiel #9
0
static u16 mdio_read(struct device *net_dev, int phy_id, int location)
{
        long mdio_addr = net_dev->base_addr + mear;
        int mii_cmd = MIIread|(phy_id<<MIIpmdShift)|(location<<MIIregShift);
        u16 retval = 0;
        int i;

        mdio_reset(mdio_addr);
        mdio_idle(mdio_addr);

        for (i = 15; i >= 0; i--) {
                int dataval = (mii_cmd & (1 << i)) ? MDDIR | MDIO : MDDIR;
                outl(dataval, mdio_addr);
		mdio_delay();
                outl(dataval | MDC, mdio_addr);
		mdio_delay();
        }

        /* Read the 16 data bits. */
        for (i = 16; i > 0; i--) {
                outl(0, mdio_addr);
                mdio_delay();
                retval = (retval << 1) | ((inl(mdio_addr) & MDIO) ? 1 : 0);
                outl(MDC, mdio_addr);
                mdio_delay();
        }
        return retval;
}
Beispiel #10
0
static int mdio_read(struct device *dev, int phy_id, int location)
{
	long mdio_addr = dev->base_addr + MII_SMI;
	int mii_cmd = (0xf6 << 10) | (phy_id << 5) | location;
	int retval = 0;
	int i;

	if (phy_id > 31) {	/* Really a 8139.  Use internal registers. */
		return location < 8 && mii_2_8139_map[location] ?
			inw(dev->base_addr + mii_2_8139_map[location]) : 0;
	}
	mdio_sync(mdio_addr);
	/* Shift the read command bits out. */
	for (i = 15; i >= 0; i--) {
		int dataval = (mii_cmd & (1 << i)) ? MDIO_DATA_OUT : 0;

		outb(MDIO_DIR | dataval, mdio_addr);
		mdio_delay();
		outb(MDIO_DIR | dataval | MDIO_CLK, mdio_addr);
		mdio_delay();
	}

	/* Read the two transition, 16 data, and wire-idle bits. */
	for (i = 19; i > 0; i--) {
		outb(0, mdio_addr);
		mdio_delay();
		retval = (retval << 1) | ((inb(mdio_addr) & MDIO_DATA_IN) ? 1 : 0);
		outb(MDIO_CLK, mdio_addr);
		mdio_delay();
	}
	return (retval>>1) & 0xffff;
}
Beispiel #11
0
static void mdio_sync(long mdio_addr) {
  int i;

  for (i = 32; i >= 0; i--) {
    outp(mdio_addr, MDIO_WRITE1);
    mdio_delay(mdio_addr);
    outp(mdio_addr, MDIO_WRITE1 | MDIO_CLK);
    mdio_delay(mdio_addr);
  }
}
Beispiel #12
0
/* Generate the preamble required for initial synchronization and
   a few older transceivers. */
static void mdio_sync(long mdio_addr)
{
	int bits = 32;

	/* Establish sync by sending at least 32 logic ones. */
	while (--bits >= 0) {
		writeb(MDIO_WRITE1, mdio_addr);
		mdio_delay();
		writeb(MDIO_WRITE1 | MDIO_ShiftClk, mdio_addr);
		mdio_delay();
	}
}
Beispiel #13
0
/* Syncronize the MII management interface by shifting 32 one bits out. */
static void mdio_sync(long mdio_addr)
{
	int i;

	for (i = 32; i >= 0; i--) {
		outb(MDIO_WRITE1, mdio_addr);
		mdio_delay();
		outb(MDIO_WRITE1 | MDIO_CLK, mdio_addr);
		mdio_delay();
	}
	return;
}
Beispiel #14
0
/* Syncronize the MII management interface by shifting 32 one bits out. */
static void mdio_reset(long mdio_addr)
{
        int i;

        for (i = 31; i >= 0; i--) {
                outl(MDDIR | MDIO, mdio_addr);
                mdio_delay();
                outl(MDDIR | MDIO | MDC, mdio_addr);
                mdio_delay();
        }
        return;
}
Beispiel #15
0
static void mdio_sync (u16 mdio_address)
{
  int counter;
  
  for (counter = 32; counter >= 0; counter--)
  {
    system_port_out_u8 (mdio_address, MDIO_WRITE1);
    mdio_delay ();
    system_port_out_u8 (mdio_address, MDIO_WRITE1 | MDIO_CLOCK);
    mdio_delay();
  }
}
Beispiel #16
0
static void mdio_sync(long mdio_addr)
{
    int bits = 32;

    
    while (--bits >= 0) {
        writel(MDIO_WRITE1, mdio_addr);
        mdio_delay(mdio_addr);
        writel(MDIO_WRITE1 | MDIO_ShiftClk, mdio_addr);
        mdio_delay(mdio_addr);
    }
}
Beispiel #17
0
/* Generate the preamble required for initial synchronization and
   a few older transceivers. */
static void
mdio_sync(struct eth_device *dev, u32 offset)
{
	int bits = 32;

	/* Establish sync by sending at least 32 logic ones. */
	while (--bits >= 0) {
		OUTL(dev, MDIO_WRITE1, offset);
		mdio_delay(offset);
		OUTL(dev, MDIO_WRITE1 | MDIO_ShiftClk, offset);
		mdio_delay(offset);
	}
}
Beispiel #18
0
static int mdio_read (u16 base_address, int physical_id, int location)
{
  long mdio_address = base_address + MII_SMI;
  int mii_command = (0xF6 << 10) | (physical_id << 5) | location;
  int return_value = 0;
  int counter;
  
  /* Really a 8139.  Use internal registers. */

  if (physical_id > 31)
  {
    return (location < 8 && mii_2_8139_map[location] ?
            system_port_in_u16 (base_address + mii_2_8139_map[location]) : 0);
  }

  mdio_sync (mdio_address);

  /* Shift the read command bits out. */
  
  for (counter = 15; counter >= 0; counter--) 
  {
    int data_value = (mii_command & (1 << counter)) ? MDIO_DATA_OUT : 0;
    
    system_port_out_u8 (mdio_address, MDIO_DIR | data_value);
    mdio_delay ();
    system_port_out_u8 (mdio_address, MDIO_DIR | data_value | MDIO_CLOCK);
    mdio_delay ();
  }
  
  /* Read the two transition, 16 data, and wire-idle bits. */

  for (counter = 19; counter > 0; counter--) 
  {
    system_port_out_u8 (mdio_address, 0);
    mdio_delay ();
    return_value = (return_value << 1) | ((system_port_in_u8 (mdio_address) & 
                                           MDIO_DATA_IN) ? 1 : 0);
    system_port_out_u8 (mdio_address, MDIO_CLOCK);
    mdio_delay ();
  }

  return (return_value >> 1) & 0xFFFF;
}
Beispiel #19
0
int tulip_mdio_read(struct net_device *dev, int phy_id, int location)
{
	struct tulip_private *tp = (struct tulip_private *)dev->priv;
	int i;
	int read_cmd = (0xf6 << 10) | (phy_id << 5) | location;
	int retval = 0;
	long ioaddr = dev->base_addr;
	long mdio_addr = ioaddr + CSR9;

	if (tp->chip_id == LC82C168) {
		int i = 1000;
		outl(0x60020000 + (phy_id<<23) + (location<<18), ioaddr + 0xA0);
		inl(ioaddr + 0xA0);
		inl(ioaddr + 0xA0);
		while (--i > 0)
			if ( ! ((retval = inl(ioaddr + 0xA0)) & 0x80000000))
				return retval & 0xffff;
		return 0xffff;
	}

	if (tp->chip_id == COMET) {
		if (phy_id == 1) {
			if (location < 7)
				return inl(ioaddr + 0xB4 + (location<<2));
			else if (location == 17)
				return inl(ioaddr + 0xD0);
			else if (location >= 29 && location <= 31)
				return inl(ioaddr + 0xD4 + ((location-29)<<2));
		}
		return 0xffff;
	}

	/* Establish sync by sending at least 32 logic ones. */
	for (i = 32; i >= 0; i--) {
		outl(MDIO_ENB | MDIO_DATA_WRITE1, mdio_addr);
		mdio_delay();
		outl(MDIO_ENB | MDIO_DATA_WRITE1 | MDIO_SHIFT_CLK, mdio_addr);
		mdio_delay();
	}
	/* Shift the read command bits out. */
	for (i = 15; i >= 0; i--) {
		int dataval = (read_cmd & (1 << i)) ? MDIO_DATA_WRITE1 : 0;

		outl(MDIO_ENB | dataval, mdio_addr);
		mdio_delay();
		outl(MDIO_ENB | dataval | MDIO_SHIFT_CLK, mdio_addr);
		mdio_delay();
	}
	/* Read the two transition, 16 data, and wire-idle bits. */
	for (i = 19; i > 0; i--) {
		outl(MDIO_ENB_IN, mdio_addr);
		mdio_delay();
		retval = (retval << 1) | ((inl(mdio_addr) & MDIO_DATA_READ) ? 1 : 0);
		outl(MDIO_ENB_IN | MDIO_SHIFT_CLK, mdio_addr);
		mdio_delay();
	}
	return (retval>>1) & 0xffff;
}
Beispiel #20
0
static void mdio_write(struct dev *dev, int phy_id, int location, int value) {
  struct nic *np = (struct nic *) dev->privdata;
  long mdio_addr = np->iobase + MII_SMI;
  int mii_cmd = (0x5002 << 16) | (phy_id << 23) | (location << 18) | value;
  int i;

  if (phy_id > 31) {
    // Really a 8139.  Use internal registers.
    long ioaddr = np->iobase;
    if (location == 0) {
      outp(ioaddr + Cfg9346, 0xC0);
      outpw(ioaddr + MII_BMCR, value);
      outp(ioaddr + Cfg9346, 0x00);
    } else if (location < 8  &&  mii_2_8139_map[location]) {
      outpw(ioaddr + mii_2_8139_map[location], value);
    }
  } else {
    mdio_sync(mdio_addr);

    // Shift the command bits out
    for (i = 31; i >= 0; i--) {
      int dataval = (mii_cmd & (1 << i)) ? MDIO_WRITE1 : MDIO_WRITE0;
      outp(mdio_addr, dataval);
      mdio_delay(mdio_addr);
      outp(mdio_addr, dataval | MDIO_CLK);
      mdio_delay(mdio_addr);
    }

    // Clear out extra bits
    for (i = 2; i > 0; i--) {
      outp(mdio_addr, 0);
      mdio_delay(mdio_addr);
      outp(mdio_addr, MDIO_CLK);
      mdio_delay(mdio_addr);
    }
  }
}
Beispiel #21
0
void
MDIO_Address(uint16_t phy_addr,uint16_t devType,uint16_t addr)
{
	uint8_t i;
	uint16_t outval;
	/* Preamble */
	SetMDO(1);
	SetDirection(DIR_OUT);
	mdio_delay();
	for(i = 0; i < 32; i++) {
		SetMDC(1);
		mdio_delay();
		SetMDC(0);
		mdio_delay();
	}
	//outval = 0x5002;
	outval = 0x0002;
	outval |= ((phy_addr & 0x1f) << 7);
	outval |= (devType & 0x1f) << 2;	
	for(i = 0; i < 16; i++,  outval <<= 1) {
		uint8_t mdo = (outval & 0x8000) ? 1 : 0; 
		SetMDO(mdo);		
		SetMDC(1);
		mdio_delay();
		SetMDC(0);
		mdio_delay();
	}
	outval = addr; 
	for(i = 0; i < 16; i++,  outval <<= 1) {
		uint8_t mdo = (outval & 0x8000) ? 1 : 0; 
		SetMDO(mdo);
		SetMDC(1);
		mdio_delay();
		SetMDC(0);
		mdio_delay();
	}
	SetDirection(DIR_IN);
	SetMDC(1);
	mdio_delay();
	SetMDC(0);
	mdio_delay();
}
Beispiel #22
0
static void
mdio_write(struct eth_device *dev, int phy_id, int addr, int value)
{
	int mii_cmd = (0x5002 << 16) | (phy_id << 23) | (addr << 18) | value;
	int i;

	/* Shift the command bits out. */
	for (i = 31; i >= 0; i--) {
		int dataval = (mii_cmd & (1 << i)) ? MDIO_WRITE1 : MDIO_WRITE0;

		OUTL(dev, dataval, EECtrl);
		mdio_delay(EECtrl);
		OUTL(dev, dataval | MDIO_ShiftClk, EECtrl);
		mdio_delay(EECtrl);
	}
	/* Clear out extra bits. */
	for (i = 2; i > 0; i--) {
		OUTL(dev, MDIO_EnbIn, EECtrl);
		mdio_delay(EECtrl);
		OUTL(dev, MDIO_EnbIn | MDIO_ShiftClk, EECtrl);
		mdio_delay(EECtrl);
	}
	return;
}
Beispiel #23
0
void tulip_mdio_write(struct net_device *dev, int phy_id, int location, int value)
{
	struct tulip_private *tp = (struct tulip_private *)dev->priv;
	int i;
	int cmd = (0x5002 << 16) | (phy_id << 23) | (location<<18) | value;
	long ioaddr = dev->base_addr;
	long mdio_addr = ioaddr + CSR9;

	if (tp->chip_id == LC82C168) {
		int i = 1000;
		outl(cmd, ioaddr + 0xA0);
		do
			if ( ! (inl(ioaddr + 0xA0) & 0x80000000))
				break;
		while (--i > 0);
		return;
	}

	if (tp->chip_id == COMET) {
		if (phy_id != 1)
			return;
		if (location < 7)
			outl(value, ioaddr + 0xB4 + (location<<2));
		else if (location == 17)
			outl(value, ioaddr + 0xD0);
		else if (location >= 29 && location <= 31)
			outl(value, ioaddr + 0xD4 + ((location-29)<<2));
		return;
	}

	/* Establish sync by sending 32 logic ones. */
	for (i = 32; i >= 0; i--) {
		outl(MDIO_ENB | MDIO_DATA_WRITE1, mdio_addr);
		mdio_delay();
		outl(MDIO_ENB | MDIO_DATA_WRITE1 | MDIO_SHIFT_CLK, mdio_addr);
		mdio_delay();
	}
	/* Shift the command bits out. */
	for (i = 31; i >= 0; i--) {
		int dataval = (cmd & (1 << i)) ? MDIO_DATA_WRITE1 : 0;
		outl(MDIO_ENB | dataval, mdio_addr);
		mdio_delay();
		outl(MDIO_ENB | dataval | MDIO_SHIFT_CLK, mdio_addr);
		mdio_delay();
	}
	/* Clear out extra bits. */
	for (i = 2; i > 0; i--) {
		outl(MDIO_ENB_IN, mdio_addr);
		mdio_delay();
		outl(MDIO_ENB_IN | MDIO_SHIFT_CLK, mdio_addr);
		mdio_delay();
	}
}
Beispiel #24
0
static void mdio_write(struct device *net_dev, int phy_id, int location, int value)
{
        long mdio_addr = net_dev->base_addr + mear;
        int mii_cmd = MIIwrite|(phy_id<<MIIpmdShift)|(location<<MIIregShift);
        int i;

        mdio_reset(mdio_addr);
        mdio_idle(mdio_addr);

        /* Shift the command bits out. */
        for (i = 15; i >= 0; i--) {
                int dataval = (mii_cmd & (1 << i)) ? MDDIR | MDIO : MDDIR;
                outb(dataval, mdio_addr);
                mdio_delay();
                outb(dataval | MDC, mdio_addr);
                mdio_delay();
        }
        mdio_delay();

	/* Shift the value bits out. */
	for (i = 15; i >= 0; i--) {
		int dataval = (value & (1 << i)) ? MDDIR | MDIO : MDDIR;
	        outl(dataval, mdio_addr);
	        mdio_delay();
	        outl(dataval | MDC, mdio_addr);
	       	mdio_delay();
	}
	mdio_delay();
	
        /* Clear out extra bits. */
        for (i = 2; i > 0; i--) {
                outb(0, mdio_addr);
                mdio_delay();
                outb(MDC, mdio_addr);
                mdio_delay();
        }
        return;
}
Beispiel #25
0
static void mdio_idle(long mdio_addr)
{
        outl(MDIO | MDDIR, mdio_addr);
        mdio_delay();
        outl(MDIO | MDDIR | MDC, mdio_addr);
}
Beispiel #26
0
/**
 ****************************************************************************
 * \fn static uint16_t MDIO_Read(uint8_t phy_addr,uint8_t regAddr)
 * Read 16 Bit from MDIO
 * This is not the standard Read command as used for PHY Registers.
 * Use this command after setting the Address with a separate address 
 * command with no other commands between.
 ****************************************************************************
 */
uint16_t 
MDIO_Read(uint8_t phy_addr,uint8_t regAddr)
{
	uint8_t i;
	uint16_t outval,inval;
	SetMDO(1);
	SetDirection(DIR_OUT);
	mdio_delay();
	/* Preamble */
	for(i = 0; i < 32; i++) {
		SetMDC(1);
		mdio_delay();
		SetMDC(0);
		mdio_delay();
	}
	//outval = 0x1800;
	outval = 0x0c00;
	outval |= (phy_addr << 5);
	outval |= (regAddr & 0x1f);
	for(i = 0; i < 14; i++,  outval <<= 1) {
		uint8_t mdo = (outval & 0x2000) ? 1 : 0; 
		SetMDO(mdo);
		SetMDC(1);
		mdio_delay();
		SetMDC(0);
		mdio_delay();
	}
	/* Bus release with one clock cycle */
	SetDirection(DIR_IN);
	SetMDC(1);
	mdio_delay();
	SetMDC(0);
	mdio_delay();

	inval = 0;
	for(i = 0; i < 16; i++) {
		SetMDC(1);
		mdio_delay();
		SetMDC(0);
		mdio_delay();
		/* 
		 ******************************************************
		 * delay of data is up to 300ns from rising edge so 
		 * better sample behind falling edge 
		 ******************************************************
		 */
		inval <<= 1;
		if(GetMDI()) {
			inval |= 1;
		}
	}
	/* Let the device release the bus ? */
	SetMDC(1);
	mdio_delay();
	SetMDC(0);
	mdio_delay();
	return inval;
}