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; }
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; }
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; }
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; }
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; }
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; }
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; }
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); } }
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; }
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; }
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); } } }
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; }