summaryrefslogtreecommitdiff
path: root/tor2ee.c
diff options
context:
space:
mode:
authormarkster <markster@5390a7c7-147a-4af0-8ec9-7488f05a26cb>2002-01-28 19:45:35 +0000
committermarkster <markster@5390a7c7-147a-4af0-8ec9-7488f05a26cb>2002-01-28 19:45:35 +0000
commit5093a31d2a974b6340983e17d8fb8a9cea06a559 (patch)
tree2b4f4f4ff974bf68415a348b415ed6a665824121 /tor2ee.c
parent5401b056582c8f9747fa1d48e8ab0fca98e1be5d (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-xtor2ee.c401
1 files changed, 385 insertions, 16 deletions
diff --git a/tor2ee.c b/tor2ee.c
index 60ecc7c..dc671cb 100755
--- a/tor2ee.c
+++ b/tor2ee.c
@@ -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)) {