Add function for printing command usage
[oweals/u-boot_mod.git] / u-boot / common / cmd_custom.c
1 /*
2  * (C) Copyright 2013
3  * Piotr Dymacz (pepe2k), Real Time Systems, piotr@realtimesystems.pl, pepe2k@gmail.com
4  * Custom commands for U-Boot 1.1.4 modification.
5  *
6  * See file CREDITS for list of people who contributed to U-Boot project.
7  *
8  * This program is free software: you can redistribute it and/or modify
9  * it under the terms of the GNU General Public License as published by
10  * the Free Software Foundation, either version 3 of the License, or
11  * (at your option) any later version.
12  *
13  * This program is distributed in the hope that it will be useful,
14  * but WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16  * GNU General Public License for more details.
17  *
18  * You should have received a copy of the GNU General Public License
19  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
20  */
21
22 #include <common.h>
23 #include <command.h>
24 #include <asm/mipsregs.h>
25 #include <asm/addrspace.h>
26 #include <ar7240_soc.h>
27
28 /* TODO: remove extern and include header file*/
29 extern void qca_sys_clocks(u32 *cpu_clk, u32 *ddr_clk, u32 *ahb_clk,
30                                                    u32 *spi_clk, u32 *ref_clk);
31
32 #if defined(OFFSET_MAC_ADDRESS)
33 /*
34  * Show MAC address(es)
35  */
36 int do_print_mac(cmd_tbl_t * cmdtp, int flag, int argc, char *argv[]){
37         char buffer[6];
38 #if defined(OFFSET_MAC_ADDRESS2)
39         char buffer2[6];
40 #endif
41
42 #if defined(OFFSET_MAC_ADDRESS2)
43         // get MAC1 and MAC2 addresses from flash and print them
44         memcpy(buffer,  (void *)(CFG_FLASH_BASE + OFFSET_MAC_DATA_BLOCK + OFFSET_MAC_ADDRESS),  6);
45         memcpy(buffer2, (void *)(CFG_FLASH_BASE + OFFSET_MAC_DATA_BLOCK + OFFSET_MAC_ADDRESS2), 6);
46
47         puts("Current MAC addresses stored in FLASH:\n");
48         printf("MAC1 at 0x%X: %02X:%02X:%02X:%02X:%02X:%02X\n", CFG_FLASH_BASE + OFFSET_MAC_DATA_BLOCK + OFFSET_MAC_ADDRESS,
49                                                                                                                         buffer[0] & 0xFF, buffer[1] & 0xFF, buffer[2] & 0xFF, buffer[3] & 0xFF, buffer[4] & 0xFF, buffer[5] & 0xFF);
50
51         printf("MAC2 at 0x%X: %02X:%02X:%02X:%02X:%02X:%02X\n\n", CFG_FLASH_BASE + OFFSET_MAC_DATA_BLOCK + OFFSET_MAC_ADDRESS2,
52                                                                                                                           buffer2[0] & 0xFF, buffer2[1] & 0xFF, buffer2[2] & 0xFF, buffer2[3] & 0xFF, buffer2[4] & 0xFF, buffer2[5] & 0xFF);
53 #else
54         // get MAC address from flash and print it
55         memcpy(buffer, (void *)(CFG_FLASH_BASE + OFFSET_MAC_DATA_BLOCK + OFFSET_MAC_ADDRESS), 6);
56
57         printf("Current MAC address stored in FLASH at offset 0x%X: ", CFG_FLASH_BASE + OFFSET_MAC_DATA_BLOCK + OFFSET_MAC_ADDRESS);
58         printf("%02X:%02X:%02X:%02X:%02X:%02X\n\n", buffer[0] & 0xFF, buffer[1] & 0xFF, buffer[2] & 0xFF, buffer[3] & 0xFF, buffer[4] & 0xFF, buffer[5] & 0xFF);
59 #endif
60
61         return(0);
62 }
63
64 #if defined(OFFSET_MAC_ADDRESS2)
65 U_BOOT_CMD(printmac, 1, 1, do_print_mac, "print MAC addresses stored in FLASH\n", NULL);
66 #else
67 U_BOOT_CMD(printmac, 1, 1, do_print_mac, "print MAC address stored in FLASH\n", NULL);
68 #endif
69
70 /*
71  * Change MAC address(es)
72  */
73 int do_set_mac(cmd_tbl_t * cmdtp, int flag, int argc, char *argv[]){
74         unsigned char *data_pointer;
75         char buf[128];
76         int i = 0, j = 0;
77
78         // allow only 2 arg (command name + mac), second argument length should be 17 (xx:xx:xx:xx:xx:xx)
79         if(argc != 2 || strlen(argv[1]) != 17){
80                 print_cmd_help(cmdtp);
81                 return(1);
82         }
83
84         // count ':'
85         for(i = 0; i< 17; i++){
86                 if(argv[1][i] == ':'){
87                         j++;
88                 }
89         }
90
91         if(j != 5){
92                 puts("## Error: given MAC address has wrong format (should be: xx:xx:xx:xx:xx:xx)!\n");
93                 return(1);
94         }
95
96         // backup block with MAC address from flash in RAM
97         data_pointer = (unsigned char *)WEBFAILSAFE_UPLOAD_RAM_ADDRESS;
98
99         if(!data_pointer){
100                 puts("## Error: couldn't allocate RAM for data block backup!\n");
101                 return(1);
102         }
103
104         puts("** Notice:\n   you should always make a backup of your device\n           entire FLASH content before making any changes\n\n");
105
106         memcpy((void *)data_pointer, (void *)(CFG_FLASH_BASE + OFFSET_MAC_DATA_BLOCK), OFFSET_MAC_DATA_BLOCK_LENGTH);
107
108         // store new MAC address in RAM
109         for(i = 0; i < 6; i++){
110                 data_pointer[OFFSET_MAC_ADDRESS + i] = simple_strtoul((char *)(argv[1] + i*3), NULL, 16);
111         }
112
113         // now we can erase flash and write data from RAM
114         sprintf(buf,
115                         "erase 0x%lX +0x%lX; cp.b 0x%lX 0x%lX 0x%lX",
116                         CFG_FLASH_BASE + OFFSET_MAC_DATA_BLOCK,
117                         OFFSET_MAC_DATA_BLOCK_LENGTH,
118                         WEBFAILSAFE_UPLOAD_RAM_ADDRESS,
119                         CFG_FLASH_BASE + OFFSET_MAC_DATA_BLOCK,
120                         OFFSET_MAC_DATA_BLOCK_LENGTH);
121
122         printf("Executing: %s\n\n", buf);
123
124         return(run_command(buf, 0));
125 }
126
127 U_BOOT_CMD(setmac, 2, 0, do_set_mac, "save new MAC address in FLASH\n", "xx:xx:xx:xx:xx:xx\n\t- change MAC address stored in FLASH (xx - value in hex format)\n");
128
129 #endif /* if defined(OFFSET_MAC_ADDRESS) */
130
131 #if defined(OFFSET_ROUTER_MODEL)
132 /*
133  * Show TP-Link router model
134  */
135 int do_print_model(cmd_tbl_t * cmdtp, int flag, int argc, char *argv[]){
136         unsigned char buffer[8];
137
138         // get router model from flash and print it
139         memcpy(buffer, (void *)(CFG_FLASH_BASE + OFFSET_MAC_DATA_BLOCK + OFFSET_ROUTER_MODEL), 8);
140
141         printf("Router model stored in FLASH at offset 0x%X: ", CFG_FLASH_BASE + OFFSET_MAC_DATA_BLOCK + OFFSET_ROUTER_MODEL);
142         printf("%02X%02X%02X%02X%02X%02X%02X%02X\n\n", buffer[0] & 0xFF, buffer[1] & 0xFF, buffer[2] & 0xFF, buffer[3] & 0xFF, buffer[4] & 0xFF, buffer[5] & 0xFF, buffer[6] & 0xFF, buffer[7] & 0xFF);
143
144         return(0);
145 }
146
147 U_BOOT_CMD(printmodel, 1, 1, do_print_model, "print router model stored in FLASH\n", NULL);
148
149 #endif /* if defined(OFFSET_ROUTER_MODEL) */
150
151 #if defined(OFFSET_PIN_NUMBER)
152 /*
153  * Show pin number
154  */
155 int do_print_pin(cmd_tbl_t * cmdtp, int flag, int argc, char *argv[]){
156         unsigned char buffer[9];
157
158         // get pin number from flash and print it
159         memcpy(buffer, (void *)(CFG_FLASH_BASE + OFFSET_MAC_DATA_BLOCK + OFFSET_PIN_NUMBER), 8);
160         buffer[8] = 0;
161
162         printf("Router pin number stored in FLASH at offset 0x%X: ", CFG_FLASH_BASE + OFFSET_MAC_DATA_BLOCK + OFFSET_PIN_NUMBER);
163         printf("%s\n\n", buffer);
164
165         return(0);
166 }
167
168 U_BOOT_CMD(printpin, 1, 1, do_print_pin, "print WPS pin stored in FLASH\n", NULL);
169
170 #endif /* if defined(OFFSET_PIN_NUMBER) */
171
172 #if defined(CONFIG_NETCONSOLE)
173 /*
174  * Start NetConsole
175  */
176 int do_start_nc(cmd_tbl_t * cmdtp, int flag, int argc, char *argv[]){
177         return(run_command("setenv stdin nc;setenv stdout nc;setenv stderr nc;version;", 0));
178 }
179
180 U_BOOT_CMD(startnc, 1, 0, do_start_nc, "start net console\n", NULL);
181
182 /*
183  * Start Serial Console
184  */
185 int do_start_sc(cmd_tbl_t * cmdtp, int flag, int argc, char *argv[]){
186         return(run_command("setenv stdin serial;setenv stdout serial;setenv stderr serial;version;", 0));
187 }
188
189 U_BOOT_CMD(startsc, 1, 0, do_start_sc, "start serial console\n", NULL);
190
191 #endif /* if defined(CONFIG_NETCONSOLE) */
192
193 #if !defined(CONFIG_FOR_DLINK_DIR505_A1)
194 /*
195  * Erase environment sector
196  */
197 int do_default_env(cmd_tbl_t * cmdtp, int flag, int argc, char *argv[]){
198         int     rc, rcode = 0;
199         int len;
200         ulong end_addr, flash_sect_addr;
201 #if defined(CFG_ENV_SECT_SIZE) && (CFG_ENV_SECT_SIZE > CFG_ENV_SIZE)
202         ulong flash_offset;
203         unsigned char env_buffer[CFG_ENV_SECT_SIZE];
204 #endif
205
206 #if defined(CFG_ENV_SECT_SIZE) && (CFG_ENV_SECT_SIZE > CFG_ENV_SIZE)
207         flash_offset    = CFG_ENV_ADDR & (CFG_ENV_SECT_SIZE-1);
208         flash_sect_addr = CFG_ENV_ADDR & ~(CFG_ENV_SECT_SIZE-1);
209
210         /* copy whole env sector to temporary buffer */
211         memcpy(env_buffer, (void *)flash_sect_addr, CFG_ENV_SECT_SIZE);
212
213         /* clear env part */
214         memset((uchar *)((unsigned long)env_buffer + flash_offset), 0xFF, CFG_ENV_SIZE);
215
216         len      = CFG_ENV_SECT_SIZE;
217 #else
218         flash_sect_addr = CFG_ENV_ADDR;
219         len = CFG_ENV_SIZE;
220 #endif
221
222         end_addr = flash_sect_addr + len - 1;
223
224         /* erase whole env sector */
225         if(flash_sect_erase(flash_sect_addr, end_addr)){
226                 rcode = 1;
227         }
228
229 #if defined(CFG_ENV_SECT_SIZE) && (CFG_ENV_SECT_SIZE > CFG_ENV_SIZE)
230         /* restore data from buffer in FLASH */
231         rc = flash_write((char *)env_buffer, flash_sect_addr, len);
232
233         if(rc != 0){
234                 flash_perror(rc);
235                 rcode = 1;
236         }
237 #endif
238
239         return(rcode);
240 }
241
242 U_BOOT_CMD(defenv, 1, 0, do_default_env, "reset environment variables to their default values\n", NULL);
243 #endif /* if !defined(CONFIG_FOR_DLINK_DIR505_A1) */