1 /* 2 * tiwlan driver loader - utility to load firmware and calibration data 3 * 4 * This program is free software; you can redistribute it and/or modify 5 * it under the terms of the GNU General Public License version 2 as 6 * published by the Free Software Foundation. 7 * 8 * Alternatively, this software may be distributed under the terms of BSD 9 * license. 10 * 11 */ 12 13 /* Copyright Texas Instruments Incorporated (Oct 2005) 14 * THIS CODE/PROGRAM IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND, 15 * EITHER EXPRESS OR IMPLIED, INCLUDED BUT NOT LIMITED TO , THE IMPLIED 16 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. 17 * This program has been modified from its original operation by Texas 18 * Instruments Incorporated. These changes are covered under version 2 19 * of the GNU General Public License, dated June 1991. 20 * 21 * Copyright Google Inc (Feb 2008) 22 */ 23 /*-------------------------------------------------------------------*/ 24 #include <stdio.h> 25 #include <stdlib.h> 26 #include <errno.h> 27 #include <unistd.h> 28 #include <string.h> 29 30 #ifdef __LINUX__ 31 #ifdef EEPROM_MEMORY_SUPPORT 32 #include <sys/types.h> 33 #include <sys/stat.h> 34 #include <fcntl.h> 35 #include <sys/mman.h> 36 #endif 37 #endif 38 39 #ifdef ANDROID 40 #include <cutils/properties.h> 41 42 #define LOG_TAG "wlan_loader" 43 44 #include <cutils/log.h> 45 #include <hardware_legacy/power.h> 46 #define PROGRAM_NAME "wlan_loader" 47 #endif 48 49 #include "paramOut.h" 50 #include "linux_ioctl_common.h" 51 #include "osApi.h" 52 #include "tiioctl.h" 53 #include "TI_AdapterApiC.h" 54 #include "TI_IPC_Api.h" 55 #include "osTIType.h" 56 #include "cli_cu_common.h" 57 /*---------------------------------------------------------*/ 58 #ifndef offsetof 59 #define offsetof(type, field) ((unsigned int) (&(((type *)(0))->field))) 60 #endif 61 62 #ifndef IFNAMSIZ 63 #define IFNAMSIZ 16 64 #endif 65 66 #ifdef ANDROID 67 68 #define ENABLE_LOG_ERROR 69 #define ENABLE_LOG_INFO 70 71 #ifdef ENABLE_LOG_ERROR 72 #define print_error(fmt, args...) \ 73 { LOGE(fmt , ## args); } 74 #else 75 #define print_error(fmt, args...) \ 76 do { } while (0) 77 #endif /* ENABLE_LOG_ERROR */ 78 79 #ifdef ENABLE_LOG_DEBUG 80 #define print_debug(fmt, args...) \ 81 { LOGD(fmt , ## args); } 82 #else 83 #define print_debug(fmt, args...) \ 84 do { } while (0) 85 #endif /* ENABLE_LOG_DEBUG */ 86 87 #ifdef ENABLE_LOG_INFO 88 #define print_info(fmt, args...) \ 89 { LOGI(fmt , ## args); } 90 #else 91 #define print_info(fmt, args...) \ 92 do { } while (0) 93 #endif /* ENABLE_LOG_INFO */ 94 95 #else /* !ANDROID */ 96 97 #define print_error printf 98 #define print_debug printf 99 100 #endif /* ifdef ANDROID */ 101 102 103 /*---------------------------------------------------------*/ 104 char g_drv_name[IFNAMSIZ + 1]; 105 TI_HANDLE g_id_adapter = 0; 106 /*---------------------------------------------------------*/ 107 int print_usage(void) 108 { 109 print_info("Usage: ./wlan_loader [driver_name] [options]\n"); 110 #ifdef HOST_PLATFORM_WIPP 111 print_info(" -e <filename> - eeprom image file name. default=/var/run/nvs_map.bin\n"); 112 #else 113 print_info(" -e <filename> - eeprom image file name. default=./nvs_map.bin\n"); 114 #endif 115 print_info(" -i <filename> - init file name. default=tiwlan.ini\n"); 116 print_info(" -f <filename> - firmware image file name. default=firmware.bin\n"); 117 return 1; 118 } 119 120 /* Return '0' if success */ 121 int init_driver( char *adapter_name, char *eeprom_file_name, char *init_file_name, char *firmware_file_name ) 122 { 123 #ifdef __LINUX__ 124 FILE *f1 = NULL, *f2 = NULL, *f3 = NULL; 125 UINT32 eeprom_image_length = 0; 126 UINT32 init_file_length = 0; 127 UINT32 firmware_image_length = 0; 128 UINT32 req_size = 0; 129 tiwlan_dev_init_t *init_info = NULL; 130 #ifdef EEPROM_MEMORY_SUPPORT 131 volatile unsigned long *nvsPtr = NULL; 132 int fd = -1; 133 #endif 134 #endif 135 int rc = -1, count = 0; 136 tiUINT32 tmpData = 1; 137 138 print_debug("adapter %s, eeprom %s, init %s, firmware %s\n", 139 adapter_name, eeprom_file_name, init_file_name, firmware_file_name); 140 141 if( !adapter_name || !*adapter_name ) 142 return rc; 143 144 g_id_adapter = TI_AdapterInit( adapter_name ); 145 146 if( g_id_adapter == 0 ) { 147 print_error("wlan_loader: failed to initialize Utility-Adapter interface...aborting...\n"); 148 goto init_driver_end; 149 } 150 151 #ifdef __LINUX__ 152 /* Send init request to the driver */ 153 if (eeprom_file_name) { 154 if ((f1 = fopen(eeprom_file_name, "r")) == NULL) { 155 print_error("Cannot open eeprom image file <%s>: %s\n", 156 eeprom_file_name, strerror(errno)); 157 goto init_driver_end; 158 } 159 if (fseek(f1, 0, SEEK_END)) { 160 print_error("Cannot seek eeprom image file <%s>: %s\n", 161 eeprom_file_name, strerror(errno)); 162 goto init_driver_end; 163 } 164 eeprom_image_length = ftell(f1); 165 rewind(f1); 166 } 167 #ifdef EEPROM_MEMORY_SUPPORT 168 else { 169 fd = open("/dev/mem", O_RDWR | O_SYNC); 170 if( fd == -1 ) { 171 print_error("Cannot access /dev/mem\n"); 172 goto init_driver_end; 173 } 174 nvsPtr = (volatile unsigned long *)mmap(0,0x1000,PROT_READ|PROT_WRITE,MAP_SHARED,fd,0x13F13000); 175 eeprom_image_length = *(nvsPtr + (0xE0C >> 2)); 176 print_debug("---Eeprom from Memory Size = %u\n", eeprom_image_length); 177 } 178 #endif 179 #ifdef FIRMWARE_DYNAMIC_LOAD 180 if( firmware_file_name) { 181 if ((f2 = fopen(firmware_file_name, "r")) == NULL ) { 182 print_error("Cannot open firmware file <%s>: %s\n", 183 firmware_file_name, strerror(errno)); 184 goto init_driver_end; 185 } 186 if( fseek(f2, 0, SEEK_END) ) { 187 print_error( "Cannot seek firmware file <%s>: %s\n", 188 firmware_file_name, strerror(errno)); 189 goto init_driver_end; 190 } 191 firmware_image_length = ftell(f2); 192 rewind(f2); 193 } 194 #endif 195 if( init_file_name) { 196 if ((f3 = fopen(init_file_name, "r")) == NULL ) { 197 print_error( "Cannot open init file <%s>: %s\n", 198 init_file_name, strerror(errno)); 199 goto init_driver_end; 200 } 201 if( fseek(f3, 0, SEEK_END) ) { 202 print_error("Cannot seek init file <%s>: %s\n", 203 init_file_name, strerror(errno)); 204 goto init_driver_end; 205 } 206 init_file_length = ftell(f3); 207 rewind(f3); 208 } 209 210 /* Now when we can calculate the request length. allocate it and read the files */ 211 req_size = offsetof(tiwlan_dev_init_t, data)+ eeprom_image_length + (init_file_length+1) + firmware_image_length; 212 init_info = (tiwlan_dev_init_t *)malloc(req_size); 213 if( !init_info ) { 214 print_error("No memory to allocate init request (%d bytes)\n", req_size); 215 goto init_driver_end; 216 } 217 init_info->eeprom_image_length = eeprom_image_length; 218 init_info->firmware_image_length = firmware_image_length; 219 init_info->init_file_length = init_file_length; 220 #ifdef EEPROM_MEMORY_SUPPORT 221 if( (nvsPtr != NULL) && eeprom_image_length ) { 222 memcpy(&init_info->data[0], (void *)(nvsPtr + (0xE40 >> 2)), eeprom_image_length); 223 munmap( (void *)nvsPtr, 0x1000 ); 224 close( fd ); 225 } 226 else 227 #endif 228 if( eeprom_image_length && 229 fread(&init_info->data[0], 1, eeprom_image_length, f1) < eeprom_image_length ) { 230 print_error("Error reading eeprom image %s: %s\n", eeprom_file_name, strerror(errno)); 231 goto init_driver_end; 232 } 233 if( firmware_image_length && 234 fread(&init_info->data[eeprom_image_length], 1, firmware_image_length, f2) < firmware_image_length ) { 235 print_error("Error reading firmware image %s: %s\n", firmware_file_name, strerror(errno)); 236 goto init_driver_end; 237 } 238 if( init_file_length && 239 fread(&init_info->data[eeprom_image_length+firmware_image_length], 1, init_file_length, f3) < init_file_length ) { 240 print_error("Error reading init_file %s: %s\n", init_file_name, strerror(errno)); 241 goto init_driver_end; 242 } 243 244 do { /* Need to wait till driver will be created in sdio_probe() */ 245 print_debug("Configuring adapter\n"); 246 rc = IPC_DeviceIoControl(adapter_name, TIWLN_SET_INIT_INFO, init_info, req_size, NULL, 0, NULL); 247 print_debug("Adapter configuration rc = %d\n", rc); 248 if( rc != 0 ) { 249 if( count > 4 ) { 250 break; 251 } 252 count++; 253 sleep(1); 254 } 255 } while( rc != 0 ); 256 257 /* Send configMge start command as the cli is started */ 258 if( rc == 0 ) { 259 print_debug("Starting configMge\n"); 260 rc = IPC_DeviceIoControl(adapter_name, TIWLN_DRIVER_STATUS_SET, &tmpData, sizeof(tiUINT32), NULL, 0, NULL); 261 print_debug("ConfigMge start rc = %d\n", rc); 262 } 263 264 init_driver_end: 265 if( f1 ) 266 fclose(f1); 267 if( f2 ) 268 fclose(f2); 269 if( f3 ) 270 fclose(f3); 271 if( init_info ) 272 free(init_info); 273 #endif 274 if( rc == 0 ) { 275 print_debug("Driver configured\n"); 276 } else { 277 print_debug("Driver configuration failed (%d)\n", rc); 278 } 279 return rc; 280 } 281 282 #ifdef ANDROID 283 int check_and_set_property(char *prop_name, char *prop_val) 284 { 285 char prop_status[PROPERTY_VALUE_MAX]; 286 int count; 287 288 for(count=4;( count != 0 );count--) { 289 property_set(prop_name, prop_val); 290 if( property_get(prop_name, prop_status, NULL) && 291 (strcmp(prop_status, prop_val) == 0) ) 292 break; 293 } 294 return( count ); 295 } 296 #endif 297 298 #ifdef __LINUX__ 299 int main(int argc, char ** argv) 300 { 301 int i; 302 #ifdef HOST_PLATFORM_WIPP 303 char *eeprom_file_name = "/NVS/nvs_map.bin"; 304 char *init_file_name = "/voice/tiwlan.ini"; 305 char *firmware_file_name = "/apps/firmware.bin"; 306 #else 307 char *eeprom_file_name = "./nvs_map.bin"; 308 char *init_file_name = "./tiwlan.ini"; 309 char *firmware_file_name = "./firmware.bin"; 310 #endif 311 312 if( argc > 1 ) { 313 i=1; 314 if( argv[i][0] != '-' ) { 315 strcpy( g_drv_name, argv[i++] ); 316 } 317 for(;( i < argc );i++) { 318 if( !strcmp(argv[i], "-h" ) || !strcmp(argv[i], "--help") ) 319 return print_usage(); 320 else if( !strcmp(argv[i], "-f" ) ) { 321 firmware_file_name = argv[++i]; 322 } 323 else if( !strcmp(argv[i], "-e") && ((i+1) < argc) ) { 324 eeprom_file_name = argv[++i]; 325 } 326 else if( !strcmp(argv[i], "-i") && ((i+1) < argc) ) { 327 init_file_name = argv[++i]; 328 } 329 else if( !strcmp(argv[i], "-n" ) ) { 330 eeprom_file_name = NULL; 331 } 332 else { 333 print_error("ticon: unknown parameter '%s'\n", argv[i] ); 334 #ifdef ANDROID 335 check_and_set_property("wlan.driver.status", "failed"); 336 #endif 337 return -1; 338 } 339 } 340 } 341 #else 342 int start_cli() 343 { 344 char *eeprom_file_name = NULL; 345 char *init_file_name = NULL; 346 char *firmware_file_name = NULL; 347 #endif 348 if( !g_drv_name[0] ) { 349 #if defined(__LINUX__) 350 strcpy(g_drv_name, TIWLAN_DRV_NAME "0" ); 351 #else 352 strcpy(g_drv_name, TIWLAN_DRV_NAME ); 353 #endif 354 } 355 356 #ifdef ANDROID 357 acquire_wake_lock(PARTIAL_WAKE_LOCK, PROGRAM_NAME); 358 #endif 359 360 if( init_driver(g_drv_name, eeprom_file_name, init_file_name, firmware_file_name) != 0 ) { 361 print_error("init_driver() failed\n"); 362 #ifdef ANDROID 363 check_and_set_property("wlan.driver.status", "failed"); 364 release_wake_lock(PROGRAM_NAME); 365 #endif 366 return -1; 367 } 368 369 TI_AdapterDeinit(g_id_adapter); 370 #ifdef ANDROID 371 check_and_set_property("wlan.driver.status", "ok"); 372 release_wake_lock(PROGRAM_NAME); 373 #endif 374 return 0; 375 } 376