diff options
author | markster <markster@5390a7c7-147a-4af0-8ec9-7488f05a26cb> | 2002-01-28 19:45:35 +0000 |
---|---|---|
committer | markster <markster@5390a7c7-147a-4af0-8ec9-7488f05a26cb> | 2002-01-28 19:45:35 +0000 |
commit | 5093a31d2a974b6340983e17d8fb8a9cea06a559 (patch) | |
tree | 2b4f4f4ff974bf68415a348b415ed6a665824121 /tor2ee.c | |
parent | 5401b056582c8f9747fa1d48e8ab0fca98e1be5d (diff) |
Version 0.1.6 from FTP
git-svn-id: http://svn.digium.com/svn/zaptel/trunk@50 5390a7c7-147a-4af0-8ec9-7488f05a26cb
Diffstat (limited to 'tor2ee.c')
-rwxr-xr-x | tor2ee.c | 401 |
1 files changed, 385 insertions, 16 deletions
@@ -102,6 +102,8 @@ static size_t memlen; struct pci_access *pci = NULL; struct pci_dev *dev = NULL; +static int manual = 0; + #define EEPROM_MAGIC 0xD00dF00d /* PCI 9030 *EEPROM* offsets */ @@ -255,6 +257,248 @@ struct pci_eeprom { u_int16_t crc16; }; +#define BIT_EE_CLK 0x0100 +#define BIT_EE_CS 0x0200 +#define BIT_EE_WR 0x0400 +#define BIT_EE_RD 0x0800 + +static unsigned short cntrl; + +static void write_cntrl(void) +{ + ((word *)memw)[0x52/2] = cntrl; +} + +static void read_cntrl(void) +{ + cntrl = ((word *)memw)[0x52/2]; +} + +static void plx_clock(void) +{ + cntrl |= BIT_EE_CLK; + write_cntrl(); + cntrl &= ~BIT_EE_CLK; + write_cntrl(); +} + +static void plx_write_bit(int bit) +{ + if (bit) + cntrl |= BIT_EE_WR; + else + cntrl &= ~BIT_EE_WR; + write_cntrl(); + plx_clock(); +} + +static int plx_read_bit(void) +{ + int res; + read_cntrl(); + if (cntrl & BIT_EE_RD) + res= 1; + else + res= 0; + plx_clock(); + return res; +} + +static int plx_read_reg(int reg) +{ + int x; + unsigned short res; + + cntrl &= ~BIT_EE_CS; + write_cntrl(); + cntrl |= BIT_EE_CS; + write_cntrl(); + + /* Send command 110 to read */ + plx_write_bit(1); + plx_write_bit(1); + plx_write_bit(0); + + /* Send address */ + for (x=7;x>=0;x--) { + if (reg & (1 << x)) + plx_write_bit(1); + else + plx_write_bit(0); + } + /* Read back start bit */ + if (plx_read_bit()) { + fprintf(stderr, "Did not get expected start bit 0\n"); + return -1; + } + + /* Read back result */ + res = 0; + for (x=0;x<16;x++) { + res <<= 1; + if (plx_read_bit()) + res |= 1; + } + + /* Clear the CS again */ + cntrl &= ~BIT_EE_CS; + + write_cntrl(); + + /* Return result */ + return res; +} + +static int plx_write_reg(int reg, int value) +{ + int x; + + int tries; + cntrl &= ~BIT_EE_CS; + write_cntrl(); + cntrl |= BIT_EE_CS; + write_cntrl(); + + /* Send command 101 to write */ + plx_write_bit(1); + plx_write_bit(0); + plx_write_bit(1); + + /* Send address */ + for (x=7;x>=0;x--) { + if (reg & (1 << x)) + plx_write_bit(1); + else + plx_write_bit(0); + } + + /* Send data */ + for (x=15;x>=0;x--) { + if (value & (1 << x)) + plx_write_bit(1); + else + plx_write_bit(0); + } + + /* Clear the CS again */ + cntrl &= ~BIT_EE_CS; + + write_cntrl(); + + /* Raise the CS again and wait for DOUT to drop */ + cntrl |= BIT_EE_CS; + write_cntrl(); + + tries = 0; + for(;;) { + read_cntrl(); + if (cntrl & BIT_EE_RD) + break; + usleep(1); + tries++; + if (tries > 5) { + fprintf(stderr, "Maximum retries exceeded on write\n"); + return -1; + } + } + /* Drop CS finally */ + cntrl &= ~BIT_EE_CS; + write_cntrl(); + usleep(1); + /* Return result */ + return 0; +} + +static int plx_write_all(int value) +{ + int x; + + int tries; + + cntrl &= ~BIT_EE_CS; + write_cntrl(); + cntrl |= BIT_EE_CS; + write_cntrl(); + + /* Send command 100 to write all */ + plx_write_bit(1); + plx_write_bit(0); + plx_write_bit(0); + + /* Send address */ + plx_write_bit(0); + plx_write_bit(1); + plx_write_bit(0); + plx_write_bit(0); + plx_write_bit(0); + plx_write_bit(0); + plx_write_bit(0); + plx_write_bit(0); + + /* Send data */ + for (x=15;x>=0;x--) { + if (value & (1 << x)) + plx_write_bit(1); + else + plx_write_bit(0); + } + + /* Clear the CS again */ + cntrl &= ~BIT_EE_CS; + + write_cntrl(); + + /* Raise the CS again and wait for DOUT to drop */ + cntrl |= BIT_EE_CS; + write_cntrl(); + tries = 0; + for(;;) { + read_cntrl(); + if (cntrl & BIT_EE_RD) + break; + usleep(1); + tries++; + if (tries > 5) { + fprintf(stderr, "Maximum retries exceeded on write\n"); + return -1; + } + } + /* Drop CS finally */ + cntrl &= ~BIT_EE_CS; + write_cntrl(); + + /* Return result */ + return 0; +} + +static int plx_write_en(void) +{ + cntrl &= ~BIT_EE_CS; + write_cntrl(); + cntrl |= BIT_EE_CS; + write_cntrl(); + + /* Send command 100 and address 11000000 to enable writing */ + plx_write_bit(1); + plx_write_bit(0); + plx_write_bit(0); + plx_write_bit(1); + plx_write_bit(1); + plx_write_bit(0); + plx_write_bit(0); + plx_write_bit(0); + plx_write_bit(0); + plx_write_bit(0); + plx_write_bit(0); + + /* Clear the CS again */ + cntrl &= ~BIT_EE_CS; + + write_cntrl(); + + return 0; +} + static inline u_int32_t read_eeprom_value(struct pci_dev *dev, int addr) { /* First write the address where we want to read */ @@ -333,12 +577,20 @@ static int read_pci_eeprom(struct pci_dev *dev, struct pci_eeprom *ee) printf("Reading from EEPROM.."); fflush(stdout); tmp = (u_int32_t *)(ee->data); - for (x=0;x<sizeof(ee->data)/4;x++) { - v = read_eeprom_value(dev, x << 2); - ee->data[x * 2] = (v & 0xFFFF0000) >> 16; - ee->data[x * 2 + 1] = v & 0xFFFF; - printf("."); - fflush(stdout); + if (manual) { + for (x=0;x<sizeof(ee->data)/2;x++) { + ee->data[x] = plx_read_reg(x); + printf("."); + fflush(stdout); + } + } else { + for (x=0;x<sizeof(ee->data)/4;x++) { + v = read_eeprom_value(dev, x << 2); + ee->data[x * 2] = (v & 0xFFFF0000) >> 16; + ee->data[x * 2 + 1] = v & 0xFFFF; + printf("."); + fflush(stdout); + } } printf("Done\n"); return 0; @@ -357,12 +609,24 @@ static int write_pci_eeprom(struct pci_dev *dev, struct pci_eeprom *ee) ((word *)memw)[PLX_LOC_WP_BOUNDARY/2] = 0; printf("Writing to EEPROM.."); fflush(stdout); - tmp = (u_int32_t *)(ee->data); - for (x=0;x<sizeof(ee->data)/4;x++) { - v = (ee->data[x * 2] << 16) | ee->data[x * 2 + 1]; - write_eeprom_value(dev, x << 2, v); - printf("."); - fflush(stdout); + if (manual) { + /* Enable writing */ + plx_write_en(); + + /* Write values */ + for (x=sizeof(ee->data)/2-1;x>=0;x--) { + plx_write_reg(x, (int)ee->data[x]); + printf("."); + fflush(stdout); + } + } else { + tmp = (u_int32_t *)(ee->data); + for (x=sizeof(ee->data)/4-1;x>=0;x--) { + v = (ee->data[x * 2] << 16) | ee->data[x * 2 + 1]; + write_eeprom_value(dev, x << 2, v); + printf("."); + fflush(stdout); + } } printf("Done\n"); /* Restore write protect */ @@ -370,6 +634,89 @@ static int write_pci_eeprom(struct pci_dev *dev, struct pci_eeprom *ee) return 0; } +static int reset_pci_eeprom(struct pci_dev *dev) +{ + int writeboundary; + + writeboundary = ((word *)memw)[PLX_LOC_WP_BOUNDARY/2]; + + printf("Original Writeprotect boundary: %04x\n", writeboundary); + /* Turn off write protect */ + ((word *)memw)[PLX_LOC_WP_BOUNDARY/2] = 0; + printf("Resetting EEPROM.."); + fflush(stdout); + /* Enable writing */ + plx_write_en(); + plx_write_all(0xffff); + printf("Done\n"); + /* Restore write protect */ + ((word *)memw)[PLX_LOC_WP_BOUNDARY/2] = writeboundary; + return 0; +} + +#if 0 +static void plx_reset(void) +{ + unsigned short tmp; + tmp = ((word *)memw)[0x50/2]; + printf("CNTRL: %04x\n", tmp); + + tmp |= 0x4000; + printf("Writing: %04x\n", tmp); + tmp = ((word *)memw)[0x50/2]; + printf("Readback: %04x\n", tmp); + + sleep(1); + + tmp = ((word *)memw)[0x50/2]; + printf("CNTRL: %04x\n", tmp); + + tmp &= ~0x4000; + ((word *)memw)[0x50/2] = tmp; + tmp = ((word *)memw)[0x50/2]; + printf("CNTRL: %04x\n", tmp); + +} +#endif + +static void plx_manread(void) +{ + int x; + unsigned short reg; + +#if 0 + read_cntrl(); + printf("Cntrl is %02x\n", cntrl); + cntrl &= ~0xf0ff; + printf("Clearing all signals\n"); + write_cntrl(); + fgetc(stdin); + printf("Setting CS\n"); + cntrl |= BIT_EE_CS; + write_cntrl(); + read_cntrl(); + printf("New read: %04x\n", cntrl); + fgetc(stdin); + printf("Setting CLK\n"); + cntrl &= ~BIT_EE_CS; + cntrl |= BIT_EE_CLK; + write_cntrl(); + fgetc(stdin); + printf("Setting WR\n"); + cntrl &= ~BIT_EE_CLK; + cntrl |= BIT_EE_WR; + write_cntrl(); + fgetc(stdin); + cntrl &= ~BIT_EE_WR; + write_cntrl(); +#endif + + for (x=0;x<NUM_REGS;x++) { + reg = plx_read_reg(x); + printf("0x%02x: %04x\n", x, reg); + } +} + static void dump_pci_eeprom(struct pci_eeprom *ee) { int x; @@ -560,9 +907,13 @@ void usage(int exitstatus) "Usage: tor2ee command [args...]\n" " tor2ee detect\n" " -- Detect presense of Tormenta 2 card\n" -" tor2ee save <filename> [revision]\n" +" tor2ee [man]save <filename> [revision]\n" " -- Read contents of eeprom and write to file\n" -" tor2ee load <filename>\n" +" tor2ee reset\n" +" -- Reset the PLX EEPROM\n" +" tor2ee manread\n" +" -- Manually read registers\n" +" tor2ee [man]load <filename>\n" " -- Write EEPROM from contents of file\n" " tor2ee modify <filename> [hex offset] [hex value]\n" " -- Change a specific offset and value in a given filename\n" @@ -580,6 +931,8 @@ void usage(int exitstatus) #define MODE_SAVE 2 #define MODE_MODIFY 3 #define MODE_LOAD 4 +#define MODE_RESET 5 +#define MODE_MANREAD 6 static void modify(struct pci_eeprom *ee, int reg, int val) { @@ -609,7 +962,8 @@ int main(int argc, char *argv[]) mode = MODE_DUMP; if (argc > 2) readfile = argv[2]; - } else if (!strcasecmp(argv[1], "save")) { + } else if (!strcasecmp(argv[1], "save") || + !strcasecmp(argv[1], "mansave")) { if (argc < 3) usage(1); writefile = argv[2]; @@ -618,13 +972,22 @@ int main(int argc, char *argv[]) else revision = makerev(); mode = MODE_SAVE; + if (!strcasecmp(argv[1], "mansave")) + manual = 1; } else if (!strcasecmp(argv[1], "detect")) { mode = MODE_DETECT; - } else if (!strcasecmp(argv[1], "load")) { + } else if (!strcasecmp(argv[1], "load") || + !strcasecmp(argv[1], "manload")) { if (argc < 3) usage(1); readfile = argv[2]; + if (!strcasecmp(argv[1], "manload")) + manual = 1; mode = MODE_LOAD; + } else if (!strcasecmp(argv[1], "reset")) { + mode = MODE_RESET; + } else if (!strcasecmp(argv[1], "manread")) { + mode = MODE_MANREAD; } else if (!strcasecmp(argv[1], "modify")) { if (argc < 5) usage(1); @@ -647,6 +1010,12 @@ int main(int argc, char *argv[]) closemem(); exit(1); } + if (mode == MODE_RESET) { + reset_pci_eeprom(dev); + } + if (mode == MODE_MANREAD) { + plx_manread(); + } if ((mode == MODE_DUMP)) { if (readfile) { if (read_eeprom_file(readfile, &ee)) { |