Ticket #9365: clock-ubiquiti-rs.c

File clock-ubiquiti-rs.c, 5.6 KB (added by ciusss89 <ciusss@…>, 5 years ago)

Surce code

Line 
1/*
2 * clock-ubiquiti-rs.c
3 *
4 * Copyright (C) 2009 Sebastian Gottschall <gottschall@dd-wrt.com>
5 *
6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU General Public License
8 * as published by the Free Software Foundation; either version 2
9 * of the License, or (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
19 *
20 * usage:
21 * clock-ubiquiti-rs mhz
22 *
23 * valid values for mhz are 200, 300 ,333, 400, 600, 680, 720, 800
24 */
25#include <unistd.h>
26#include <sys/types.h>
27#include <sys/wait.h>
28#include <stdio.h>
29#include <string.h>
30#include <stdlib.h>
31#include <fcntl.h>
32
33int overclock(FILE * out, char *freq, int value)
34{
35    fseek(out, 0xd3, SEEK_SET);
36    int val = getc(out);
37    if (val == value) {
38        fprintf(stderr, "board already clocked to %sMhz\n", freq);
39        return -1;
40    }
41    fseek(out, 0xd3, SEEK_SET);
42    putc(value, out);
43    return 0;
44}
45
46int overclock_3(FILE * out, char *freq, int value)
47{
48    fseek(out, 0x3f, SEEK_SET);
49    int val = getc(out);
50    if (val == value) {
51        fprintf(stderr, "board already clocked to %sMhz\n", freq);
52        return -1;
53    }
54    fseek(out, 0x3f, SEEK_SET);
55    putc(value, out);
56    return 0;
57}
58
59void start_overclock(int mhz)
60{
61    long len;
62    long i;
63
64    FILE *in = fopen("/dev/mtdblock0", "rb");
65    fseek(in, 0, SEEK_END);
66    len = ftell(in);
67    rewind(in);
68    char check[8];
69    char check2[8];
70    char values[8] = { 0x24, 0x08, 0x00, 0xaa, 0x15, 0x09, 0x00, 0x04 };
71    char values2[8] = { 0x24, 0x0a, 0x00, 0x0f, 0x11, 0x2a, 0x00, 0x04 };
72    fseek(in, 0xc0, SEEK_SET);
73    fread(check, 1, 8, in);
74    fseek(in, 0xc4, SEEK_SET);
75    fread(check2, 1, 8, in);
76    int ret1 = 0xff;
77    int ret2 = 0xff;
78    int ret3 = 0xff;
79    if ((ret1 = memcmp(check, values, 8))
80        && (ret2 = memcmp(check2, values, 8))
81        && (ret3 = memcmp(check2, values2, 8))) {
82        fprintf(stderr,
83            "no compatible routerstation bootloader found\n");
84        fclose(in);
85        return;
86    }
87    if (!ret1)
88        fprintf(stderr, "bootloader rev1 found\n");
89    if (!ret2)
90        fprintf(stderr, "bootloader rev2 found\n");
91    if (!ret3)
92        fprintf(stderr, "bootloader rev3 found\n");
93    FILE *out = fopen("/tmp/boot", "w+b");
94    rewind(in);
95    for (i = 0; i < len; i++)
96        putc(getc(in), out);
97    fclose(in);
98    int ret = 1;
99    if (!ret3) {
100        if (mhz == 200)
101            ret = overclock_3(out, "200", 0x1);
102        if (mhz == 300)
103            ret = overclock_3(out, "300", 0x2);
104        if (mhz == 333)
105            ret = overclock_3(out, "333", 0x3);
106        if (mhz == 400)
107            ret = overclock_3(out, "400", 0x6);
108        if (mhz == 600)
109            ret = overclock_3(out, "600", 0x7);
110        if (mhz == 680)
111            ret = overclock_3(out, "680", 0xc);    //special ubiquiti setting with different ddram clock settings
112        if (mhz == 720)
113            ret = overclock_3(out, "720", 0xe);    //need to be validated
114        if (mhz == 800)
115            ret = overclock_3(out, "800", 0xf);
116    } else {
117        if (mhz == 200)
118            ret = overclock(out, "200", 0x1);
119        if (mhz == 300)
120            ret = overclock(out, "300", 0x2);
121        if (mhz == 333)
122            ret = overclock(out, "333", 0x3);
123        if (mhz == 400)
124            ret = overclock(out, "400", 0x6);
125        if (mhz == 600)
126            ret = overclock(out, "600", 0x7);
127        if (mhz == 680)
128            ret = overclock(out, "680", 0xa);    //special ubiquiti setting with different ddram clock settings
129        if (mhz == 720)
130            ret = overclock(out, "720", 0x1e);    //magic atheros values
131        if (mhz == 800)
132            ret = overclock(out, "800", 0x1f);
133    }
134
135    fclose(out);
136    if (!ret) {
137        fprintf(stderr, "write new bootloader\n");
138
139        pid_t child_pid;
140        int child_status=-1;
141
142        child_pid = fork();
143
144        if (child_pid == -1) {
145            fprintf(stderr,"Fork failed.\n");
146            exit(1);
147        }
148        else if (child_pid > 0){
149            /* This is the parent process. */
150            ret = child_pid;
151        }
152            else {
153                /* child process */
154                execlp("mtd", "mtd", "-f", "write", "/tmp/boot", "RedBoot", NULL);
155                /* The execl function returns only if an error occurs. */
156                fprintf (stderr, "An error occurred writing new Redboot.\n");
157                exit(-1);
158            }
159
160        wait(&child_status);
161        if (WIFEXITED (child_status))
162            fprintf(stderr, "board now clocked to %u Mhz\n", mhz);
163        else
164            fprintf (stderr, "An error occurred writing new Redboot.\n");
165    }
166}
167
168int main (int argc, char *argv[]) 
169{
170    int mhz;
171
172    if (argc == 2) {
173        mhz = atoi(argv[1]);
174        if (mhz != 200 && mhz != 300 && mhz != 333 && mhz != 400 && mhz != 600 && mhz != 680 && mhz != 720 && mhz != 800) {
175            fprintf(stderr, "Allowed values are 200,300,333,400,600,680,720,800\n"); 
176            exit(1);
177        } 
178        else {
179            start_overclock (mhz);
180        }
181    }
182    else {
183        fprintf(stderr, "Usage: %s mhz\nAllowed values for mhz are 200,300,333,400,600,680,720,800\n", argv[0]);
184        exit(1);
185    }
186
187    return 0;
188
189}