Home | History | Annotate | Download | only in tiwlan_loader
      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