Exemplo n.º 1
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;
}
Exemplo n.º 2
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;
}
Exemplo n.º 3
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;
}
Exemplo n.º 4
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;
}
Exemplo n.º 5
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;
}
Exemplo n.º 6
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;
}
Exemplo n.º 7
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;
}
Exemplo n.º 8
0
static void mdio_write(unsigned int addr, int phy_id, int loc, int value)
{
    u_int cmd = (0x05<<28)|(phy_id<<23)|(loc<<18)|(1<<17)|value;
    int i, mask = inb(addr) & MDIO_MASK;

    mdio_sync(addr);
    for (i = 31; i >= 0; i--) {
	int dat = (cmd&(1<<i)) ? MDIO_DATA_WRITE1 : MDIO_DATA_WRITE0;
	outb(mask | dat, addr);
	outb(mask | dat | MDIO_SHIFT_CLK, addr);
    }
    for (i = 1; i >= 0; i--) {
	outb(mask, addr);
	outb(mask | MDIO_SHIFT_CLK, addr);
    }
}
Exemplo n.º 9
0
static int mdio_read(unsigned int addr, int phy_id, int loc)
{
    u_int cmd = (0x06<<10)|(phy_id<<5)|loc;
    int i, retval = 0, mask = inb(addr) & MDIO_MASK;

    mdio_sync(addr);
    for (i = 13; i >= 0; i--) {
	int dat = (cmd&(1<<i)) ? MDIO_DATA_WRITE1 : MDIO_DATA_WRITE0;
	outb(mask | dat, addr);
	outb(mask | dat | MDIO_SHIFT_CLK, addr);
    }
    for (i = 19; i > 0; i--) {
	outb(mask, addr);
	retval = (retval << 1) | ((inb(addr) & MDIO_DATA_READ) != 0);
	outb(mask | MDIO_SHIFT_CLK, addr);
    }
    return (retval>>1) & 0xffff;
}
Exemplo n.º 10
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;
}
Exemplo n.º 11
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);
    }
  }
}
Exemplo n.º 12
0
int
ns8382x_initialize(bd_t * bis)
{
	pci_dev_t devno;
	int card_number = 0;
	struct eth_device *dev;
	u32 iobase, status;
	int i, idx = 0;
	u32 phyAddress;
	u32 tmp;
	u32 chip_config;

	while (1) {		/* Find PCI device(s) */
		if ((devno = pci_find_devices(supported, idx++)) < 0)
			break;

		pci_read_config_dword(devno, PCI_BASE_ADDRESS_1, &iobase);
		iobase &= ~0x3;	/* 1: unused and 0:I/O Space Indicator */

#ifdef NS8382X_DEBUG
		printf("ns8382x: NatSemi dp8382x @ 0x%x\n", iobase);
#endif

		pci_write_config_dword(devno, PCI_COMMAND,
				       PCI_COMMAND_MEMORY | PCI_COMMAND_MASTER);

		/* Check if I/O accesses and Bus Mastering are enabled. */
		pci_read_config_dword(devno, PCI_COMMAND, &status);
		if (!(status & PCI_COMMAND_MEMORY)) {
			printf("Error: Can not enable MEM access.\n");
			continue;
		} else if (!(status & PCI_COMMAND_MASTER)) {
			printf("Error: Can not enable Bus Mastering.\n");
			continue;
		}

		dev = (struct eth_device *) malloc(sizeof *dev);
		if (!dev) {
			printf("ns8382x: Can not allocate memory\n");
			break;
		}
		memset(dev, 0, sizeof(*dev));

		sprintf(dev->name, "dp8382x#%d", card_number);
		dev->iobase = bus_to_phys(iobase);
		dev->priv = (void *) devno;
		dev->init = ns8382x_init;
		dev->halt = ns8382x_disable;
		dev->send = ns8382x_send;
		dev->recv = ns8382x_poll;

		/* ns8382x has a non-standard PM control register
		 * in PCI config space.  Some boards apparently need
		 * to be brought to D0 in this manner.  */
		pci_read_config_dword(devno, PCIPM, &tmp);
		if (tmp & (0x03 | 0x100)) {	/* D0 state, disable PME assertion */
			u32 newtmp = tmp & ~(0x03 | 0x100);
			pci_write_config_dword(devno, PCIPM, newtmp);
		}

		/* get MAC address */
		for (i = 0; i < 3; i++) {
			u32 data;
			char *mac = (char *)&dev->enetaddr[i * 2];

			OUTL(dev, i * 2, RxFilterAddr);
			data = INL(dev, RxFilterData);
			*mac++ = data;
			*mac++ = data >> 8;
		}
		/* get PHY address, can't be zero */
		for (phyAddress = 1; phyAddress < 32; phyAddress++) {
			u32 rev, phy1;

			phy1 = mdio_read(dev, phyAddress, PHYIDR1);
			if (phy1 == 0x2000) {	/*check for 83861/91 */
				rev = mdio_read(dev, phyAddress, PHYIDR2);
				if ((rev & ~(0x000f)) == 0x00005c50 ||
				    (rev & ~(0x000f)) == 0x00005c60) {
#ifdef NS8382X_DEBUG
					printf("phy rev is %x\n", rev);
					printf("phy address is %x\n",
					       phyAddress);
#endif
					break;
				}
			}
		}

		/* set phy to autonegotiate && advertise everything */
		mdio_write(dev, phyAddress, KTCR,
			   (ktcr_adv_1000H | ktcr_adv_1000F));
		mdio_write(dev, phyAddress, ANAR,
			   (anar_adv_100F | anar_adv_100H | anar_adv_10H |
			    anar_adv_10F | anar_ieee_8023));
		mdio_write(dev, phyAddress, BMCR, 0x0);	/*restore */
		mdio_write(dev, phyAddress, BMCR,
			   (Bmcr_AutoNegEn | Bmcr_RstAutoNeg));
		/* Reset the chip to erase any previous misconfiguration. */
		OUTL(dev, (ChipReset), ChipCmd);

		chip_config = INL(dev, ChipConfig);
		/* reset the phy */
		OUTL(dev, (chip_config | PhyRst), ChipConfig);
		/* power up and initialize transceiver */
		OUTL(dev, (chip_config & ~(PhyDis)), ChipConfig);

		mdio_sync(dev, EECtrl);
#ifdef NS8382X_DEBUG
		{
			u32 chpcfg =
			    INL(dev, ChipConfig) ^ SpeedStatus_Polarity;

			printf("%s: Transceiver 10%s %s duplex.\n", dev->name,
			       (chpcfg & GigSpeed) ? "00" : (chpcfg & HundSpeed)
			       ? "0" : "",
			       chpcfg & FullDuplex ? "full" : "half");
			printf("%s: %02x:%02x:%02x:%02x:%02x:%02x\n", dev->name,
			       dev->enetaddr[0], dev->enetaddr[1],
			       dev->enetaddr[2], dev->enetaddr[3],
			       dev->enetaddr[4], dev->enetaddr[5]);
		}
#endif
		/* Disable PME:
		 * The PME bit is initialized from the EEPROM contents.
		 * PCI cards probably have PME disabled, but motherboard
		 * implementations may have PME set to enable WakeOnLan.
		 * With PME set the chip will scan incoming packets but
		 * nothing will be written to memory. */
		SavedClkRun = INL(dev, ClkRun);
		OUTL(dev, SavedClkRun & ~0x100, ClkRun);

		eth_register(dev);

		card_number++;

		pci_write_config_byte(devno, PCI_LATENCY_TIMER, 0x60);

		udelay(10 * 1000);
	}
	return card_number;
}