📄 dc2114x.c
字号:
bis->bi_enetaddr[4], bis->bi_enetaddr[5]); if ((bis->bi_enetaddr[0] != 0) || (bis->bi_enetaddr[1] != 0) || (bis->bi_enetaddr[2] != 0) || (bis->bi_enetaddr[3] != 0) || (bis->bi_enetaddr[4] != 0) || (bis->bi_enetaddr[5] != 0)) { printf("Updating SROM data - please wait...\n"); updateSRom(bis); } goto Done; } } Done:}static void send_setup_frame(bd_t *bis){ int i; char setup_frame[SETUP_FRAME_LEN]; char * pa = &setup_frame[0]; memset(pa, 0xff, SETUP_FRAME_LEN); for (i = 0; i < ETH_ALEN; i++) { *(pa + (i & 1)) = bis->bi_enetaddr[i]; if (i & 0x01) { pa += 4; } } for(i = 0; tx_ring[tx_new].status & cpu_to_le32(T_OWN); i++) { if (i >= TOUT_LOOP) { printf("eth: tx error buffer not ready\n"); goto out; } } tx_ring[tx_new].buf = cpu_to_le32((u_long)&setup_frame[0]); tx_ring[tx_new].des1 = cpu_to_le32(TD_TER | TD_SET| SETUP_FRAME_LEN); tx_ring[tx_new].status = cpu_to_le32(T_OWN); outl(POLL_DEMAND, DE4X5_TPD); for(i = 0; tx_ring[tx_new].status & cpu_to_le32(T_OWN); i++) { if (i >= TOUT_LOOP) { printf("eth: tx buffer not ready\n"); goto out; } } if (le32_to_cpu(tx_ring[tx_new].status) != 0x7FFFFFFF) { printf("TX error status2 = 0x%08X\n", le32_to_cpu(tx_ring[tx_new].status)); } out:}/* SROM Read. */static shortsrom_rd(u_long addr, u_char offset){ sendto_srom(SROM_RD | SROM_SR, addr); srom_latch(SROM_RD | SROM_SR | DT_CS, addr); srom_command(SROM_RD | SROM_SR | DT_IN | DT_CS, addr); srom_address(SROM_RD | SROM_SR | DT_CS, addr, offset); return srom_data(SROM_RD | SROM_SR | DT_CS, addr);}static voidsrom_latch(u_int command, u_long addr){ sendto_srom(command, addr); sendto_srom(command | DT_CLK, addr); sendto_srom(command, addr); return;}static voidsrom_command(u_int command, u_long addr){ srom_latch(command, addr); srom_latch(command, addr); srom_latch((command & 0x0000ff00) | DT_CS, addr); return;}static voidsrom_address(u_int command, u_long addr, u_char offset){ int i; signed char a; a = (char)(offset << 2); for (i=0; i<6; i++, a <<= 1) { srom_latch(command | ((a < 0) ? DT_IN : 0), addr); } udelay(1); i = (getfrom_srom(addr) >> 3) & 0x01; return;}static shortsrom_data(u_int command, u_long addr){ int i; short word = 0; s32 tmp; for (i=0; i<16; i++) { sendto_srom(command | DT_CLK, addr); tmp = getfrom_srom(addr); sendto_srom(command, addr); word = (word << 1) | ((tmp >> 3) & 0x01); } sendto_srom(command & 0x0000ff00, addr); return word;}static voidsendto_srom(u_int command, u_long addr){ outl(command, addr); udelay(1); return;}static intgetfrom_srom(u_long addr){ s32 tmp; tmp = inl(addr); udelay(1); return tmp;}/*************************************************************************** * * Routines for srom write access * */#define DECPCI_REG_OFFSET 0x08 /* quad word aligned */#define LONGSWAP(data) ((unsigned long) \ (((unsigned long)(data) >> 24) | \ ((unsigned long)(data) << 24) | \ (((unsigned long)(data) >> 8) & 0x0000ff00 ) | \ (((unsigned long)(data) << 8) & 0x00ff0000 )))#define PCISWAP(x) LONGSWAP(x) /* processor big endian *//********************************************************************************* dcCsrWrite - select and write a CSR register**/static void dcCsrWrite( unsigned long devAdrs, /* device address base */ int reg, /* register to select */ unsigned long value /* value to write */ ){ unsigned long * csrReg; csrReg = (unsigned long *)(devAdrs + (reg * DECPCI_REG_OFFSET)); /* write val to CSR */ *(csrReg) = PCISWAP(value);}/********************************************************************************* dcCsrRead - select and read a CSR register**/static unsigned long dcCsrRead( unsigned long devAdrs, /* device address base */ int reg /* register to select */ ){ unsigned long * csrReg; /* csr register */ unsigned long csrData; /* data in csr register */ csrReg = (unsigned long *)(devAdrs + (reg * DECPCI_REG_OFFSET)); csrData = *csrReg; /* get contents of CSR */ return (PCISWAP(csrData));}/* define CSRs and descriptors */#define CSR0 0 /* csr 0 */#define CSR1 1 /* csr 1 */#define CSR2 2 /* csr 2 */#define CSR3 3 /* csr 3 */#define CSR4 4 /* csr 4 */#define CSR5 5 /* csr 5 */#define CSR6 6 /* csr 6 */#define CSR7 7 /* csr 7 */#define CSR8 8 /* csr 8 */#define CSR9 9 /* csr 9 */#define CSR10 10 /* csr 10 */#define CSR11 11 /* csr 11 */#define CSR12 12 /* csr 12 */#define CSR13 13 /* csr 13 */#define CSR14 14 /* csr 14 */#define CSR15 15 /* csr 15 *//* CSR9 Ethernet Address ROM Register */#define CSR9_DNV 0x80000000 /* Data not valid */#define CSR9_DAT_MSK 0x000000FF /* data mask */#define ENET_ROM_SIZE 8 /* ethernet rom register size *//* CSR9 Serial Address ROM and MII Management Register for the DEC21140 */#define CSR9_040_DNVAL 0x80000000 /* Data not valid - 21040 */#define CSR9_MDI 0x00080000 /* MII mgmt data in - 21140+ */#define CSR9_MDI_SHF 19#define CSR9_MII_RD 0x00040000 /* MII mgmt read mode - 21140+ */#define CSR9_MII_WR 0x00000000 /* MII mgmt write mode - 21140+ */#define CSR9_MDO 0x00020000 /* MII mgmt write data - 21140+ */#define CSR9_MDO_SHF 17#define CSR9_MDC 0x00010000 /* MII mgmt clock - 21140+ */#define CSR9_RD 0x00004000 /* Read command - 21140+ */#define CSR9_WR 0x00002000 /* Write command - 21140+ */#define CSR9_BR 0x00001000 /* Boot rom select - 21140+ */#define CSR9_SR 0x00000800 /* Serial rom select - 21140+ */#define CSR9_REG 0x00000400 /* External register select - 21140+ */#define CSR9_DATA 0x000000FF /* Data */#define CSR9_DATA_OUT 0x00000008 /* Shift read data from SROM - 21140+ */#define CSR9_DATA_IN 0x00000004 /* Shift write data into SROM - 21140+*/#define CSR9_SROM_CLK 0x00000002 /* SCLK output to SROM - 21140+ */#define CSR9_SROM_CS 0x00000001 /* SerialROM chip select - 21140+ */#define CSR9_MII_DBIT_RD(X) (((X) & CSR9_MDI) >> CSR9_MDI_SHF)#define CSR9_MII_DBIT_WR(X) (((X) & 0x1) << CSR9_MDO_SHF)#define NSDELAY(nsec) { \ volatile int nx = 0; \ volatile int loop = (int)(nsec); \ for (nx = 0; nx < loop; nx++); \ }#ifndef DC_CSR_READ#define DC_CSR_READ(devAdrs, csrNum) \ dcCsrRead ((devAdrs), (csrNum))#endif /* DC_CSR_READ */#ifndef DC_CSR_WRITE#define DC_CSR_WRITE(devAdrs, csrNum, csrVal) \ dcCsrWrite((devAdrs), (csrNum), (csrVal))#endif /* DC_CSR_WRITE */#define DC_CSR_UPDATE(devAdrs, csrNum, csrBits) \ DC_CSR_WRITE((devAdrs), (csrNum), \ DC_CSR_READ((devAdrs), (csrNum)) | (csrBits))#define DC_CSR_RESET(devAdrs, csrNum, csrBits) \ DC_CSR_WRITE((devAdrs), (csrNum), \ DC_CSR_READ((devAdrs), (csrNum)) & ~(csrBits))#define DC_INT_ENABLE(devAdrs, X) \ DC_CSR_UPDATE ((devAdrs), CSR7, (X))#define DC_INT_DISABLE(devAdrs, X) \ DC_CSR_RESET ((devAdrs), CSR7, (X))#define DC_SROM_WRITE(devAdrs, adrs, delay) \ { \ DC_CSR_WRITE ((devAdrs), CSR9, (adrs) | CSR9_SR | CSR9_WR); \ NSDELAY(delay); \ }#define DC_SROM_READ(devAdrs) \ ((DC_CSR_READ ((devAdrs), CSR9) & 0x08) >> 3)/* Reading a serial EEPROM is a "bit" grungy, but we work our way through:->.*//* This code is a "nasty" timing loop, but PC compatible machines are *supposed* to delay an ISA-compatible period for the SLOW_DOWN_IO macro. */#define eeprom_delay() NSDELAY(100)#undef inl#undef outl#define outl(val, addr) DC_SROM_WRITE(addr, val, 0)#define inl(addr) DC_SROM_READ(addr)#undef debug#define debug 0/* EEPROM_Ctrl bits. */#define EE_SHIFT_CLK 0x02 /* EEPROM shift clock. */#define EE_CS 0x01 /* EEPROM chip select. */#define EE_DATA_WRITE 0x04 /* EEPROM chip data in. */#define EE_WRITE_0 0x4801#define EE_WRITE_1 0x4805#define EE_DATA_READ 0x08 /* EEPROM chip data out. */#define EE_ENB (0x4800 | EE_CS)/* The EEPROM commands include the alway-set leading bit. */#define EE_WRITE_CMD (5)#define EE_READ_CMD (6)#define EE_ERASE_CMD (7)/* Note: this routine returns extra data bits for size detection. */static int read_eeprom(long ioaddr, int location, int addr_len){ int i; unsigned retval = 0; long ee_addr = ioaddr; int read_cmd = location | (EE_READ_CMD << addr_len); outl(EE_ENB & ~EE_CS, ee_addr); outl(EE_ENB, ee_addr); if (debug > 2) printf(" EEPROM read at %d ", location); /* Shift the read command bits out. */ for (i = 4 + addr_len; i >= 0; i--) { short dataval = (read_cmd & (1 << i)) ? EE_DATA_WRITE : 0; outl(EE_ENB | dataval, ee_addr); eeprom_delay(); outl(EE_ENB | dataval | EE_SHIFT_CLK, ee_addr); eeprom_delay(); if (debug > 2) printf("%lX", inl(ee_addr) & 15); retval = (retval << 1) | ((inl(ee_addr) & EE_DATA_READ) ? 1 : 0); } outl(EE_ENB, ee_addr); if (debug > 2) printf(" :%lX:", inl(ee_addr) & 15); for (i = 16; i > 0; i--) { outl(EE_ENB | EE_SHIFT_CLK, ee_addr); eeprom_delay(); if (debug > 2) printf("%lX", inl(ee_addr) & 15); retval = (retval << 1) | ((inl(ee_addr) & EE_DATA_READ) ? 1 : 0); outl(EE_ENB, ee_addr); eeprom_delay(); } /* Terminate the EEPROM access. */ outl(EE_ENB & ~EE_CS, ee_addr); if (debug > 2) printf(" EEPROM value at %d is %5.5x.\n", location, retval); return retval;}/* This executes a generic EEPROM command, typically a write or write enable. It returns the data output from the EEPROM, and thus may also be used for reads. */static int do_eeprom_cmd(int ioaddr, int cmd, int cmd_len){ unsigned retval = 0; int ee_addr = ioaddr; if (debug > 1) printf(" EEPROM op 0x%x: ", cmd); outl(EE_ENB | EE_SHIFT_CLK, ee_addr); /* Shift the command bits out. */ do { short dataval = (cmd & (1 << cmd_len)) ? EE_WRITE_1 : EE_WRITE_0; outl(dataval, ee_addr); eeprom_delay(); if (debug > 2) printf("%lX", inl(ee_addr) & 15); outl(dataval | EE_SHIFT_CLK, ee_addr); eeprom_delay(); retval = (retval << 1) | ((inl(ee_addr) & EE_DATA_READ) ? 1 : 0); } while (--cmd_len >= 0); outl(EE_ENB, ee_addr); /* Terminate the EEPROM access. */ outl(EE_ENB & ~EE_CS, ee_addr); if (debug > 1) printf(" EEPROM result is 0x%5.5x.\n", retval); return retval;}static int dcWriteRom(int ioaddr, int index, int new_value){ int ee_addr_size = read_eeprom(ioaddr, 0xff, 8) & 0x40000 ? 8 : 6; int i; unsigned short newval; udelay(10*1000); /* test-only */ if (debug > 1) { printf("ee_addr_size=%d.\n", ee_addr_size); printf("Writing new entry 0x%4.4x to offset %d.\n", new_value, index); } /* Enable programming modes. */ do_eeprom_cmd(ioaddr, (0x4f << (ee_addr_size-4)), 3+ee_addr_size); /* Do the actual write. */ do_eeprom_cmd(ioaddr, (((EE_WRITE_CMD<<ee_addr_size)|index) << 16) | new_value, 3 + ee_addr_size + 16); /* Poll for write finished. */ outl(EE_ENB, ioaddr); for (i = 0; i < 10000; i++) /* Typical 2000 ticks */ if (inl(ioaddr) & EE_DATA_READ) break; if (debug > 1) printf(" Write finished after %d ticks.\n", i); /* Disable programming. */ do_eeprom_cmd(ioaddr, (0x40 << (ee_addr_size-4)), 3 + ee_addr_size); /* And read the result. */ newval = do_eeprom_cmd(ioaddr, (((EE_READ_CMD<<ee_addr_size)|index) << 16) | 0xffff, 3 + ee_addr_size + 16); if (debug > 1) printf(" New value at offset %d is %4.4x.\n", index, newval); return 1;}static void updateSRom(bd_t *bis){ unsigned short addrShort; /* taken from ramix pmc-module */ dcWriteRom(iobase, 0x00, 0x140b); dcWriteRom(iobase, 0x01, 0x6610); dcWriteRom(iobase, 0x02, 0x0); dcWriteRom(iobase, 0x03, 0x0); dcWriteRom(iobase, 0x04, 0x0); dcWriteRom(iobase, 0x05, 0x0); dcWriteRom(iobase, 0x06, 0x0); dcWriteRom(iobase, 0x07, 0x0); dcWriteRom(iobase, 0x08, 0x00a3); dcWriteRom(iobase, 0x09, 0x0103); dcWriteRom(iobase, 0x0a, 0x0200); /* Ethernet Addr... */ dcWriteRom(iobase, 0x0b, 0x0027); addrShort = ((bis->bi_enetaddr[5] & 0xff) << 8) | (bis->bi_enetaddr[4] & 0xff); dcWriteRom(iobase, 0x0c, addrShort); /* ...Ethernet Addr */ dcWriteRom(iobase, 0x0d, 0x1f00); dcWriteRom(iobase, 0x0e, 0x0); dcWriteRom(iobase, 0x0f, 0x0); dcWriteRom(iobase, 0x10, 0x0108); dcWriteRom(iobase, 0x11, 0x038d); /* set extended format bit 0x80 !!! */ dcWriteRom(iobase, 0x12, 0x0); dcWriteRom(iobase, 0x13, 0x0); dcWriteRom(iobase, 0x14, 0xe078); dcWriteRom(iobase, 0x15, 0x0001); dcWriteRom(iobase, 0x16, 0x0040); dcWriteRom(iobase, 0x17, 0x0018); dcWriteRom(iobase, 0x18, 0x0); dcWriteRom(iobase, 0x19, 0x0); dcWriteRom(iobase, 0x1a, 0x0); dcWriteRom(iobase, 0x1b, 0x0); dcWriteRom(iobase, 0x1c, 0x0); dcWriteRom(iobase, 0x1d, 0x0); dcWriteRom(iobase, 0x1e, 0x0); dcWriteRom(iobase, 0x1f, 0x0); dcWriteRom(iobase, 0x20, 0x0); dcWriteRom(iobase, 0x21, 0x0); dcWriteRom(iobase, 0x22, 0x0); dcWriteRom(iobase, 0x23, 0x0); dcWriteRom(iobase, 0x24, 0x0); dcWriteRom(iobase, 0x25, 0x0); dcWriteRom(iobase, 0x26, 0x0); dcWriteRom(iobase, 0x27, 0x0); dcWriteRom(iobase, 0x28, 0x0); dcWriteRom(iobase, 0x29, 0x0); dcWriteRom(iobase, 0x2a, 0x0); dcWriteRom(iobase, 0x2b, 0x0); dcWriteRom(iobase, 0x2c, 0x0); dcWriteRom(iobase, 0x2d, 0x0); dcWriteRom(iobase, 0x2e, 0x0); dcWriteRom(iobase, 0x2f, 0x0); dcWriteRom(iobase, 0x30, 0x0); dcWriteRom(iobase, 0x31, 0x0); dcWriteRom(iobase, 0x32, 0x0); dcWriteRom(iobase, 0x33, 0x0); dcWriteRom(iobase, 0x34, 0x0); dcWriteRom(iobase, 0x35, 0x0); dcWriteRom(iobase, 0x36, 0x0); dcWriteRom(iobase, 0x37, 0x0); dcWriteRom(iobase, 0x38, 0x0); dcWriteRom(iobase, 0x39, 0x0); dcWriteRom(iobase, 0x3a, 0x0); dcWriteRom(iobase, 0x3b, 0x0); dcWriteRom(iobase, 0x3c, 0x0); dcWriteRom(iobase, 0x3d, 0x0); dcWriteRom(iobase, 0x3e, 0x0); dcWriteRom(iobase, 0x3f, 0x4e07);}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -