linux/drivers/staging/bcm/InterfaceDld.c
<<
>>
Prefs
   1#include "headers.h"
   2
   3int InterfaceFileDownload(PVOID arg, struct file *flp, unsigned int on_chip_loc)
   4{
   5        /* unsigned int reg = 0; */
   6        mm_segment_t oldfs = {0};
   7        int errno = 0, len = 0; /* ,is_config_file = 0 */
   8        loff_t pos = 0;
   9        struct bcm_interface_adapter *psIntfAdapter = (struct bcm_interface_adapter *)arg;
  10        /* struct bcm_mini_adapter *Adapter = psIntfAdapter->psAdapter; */
  11        char *buff = kmalloc(MAX_TRANSFER_CTRL_BYTE_USB, GFP_KERNEL);
  12
  13        if (!buff)
  14                return -ENOMEM;
  15
  16        while (1) {
  17                oldfs = get_fs();
  18                set_fs(get_ds());
  19                len = vfs_read(flp, (void __force __user *)buff,
  20                        MAX_TRANSFER_CTRL_BYTE_USB, &pos);
  21                set_fs(oldfs);
  22                if (len <= 0) {
  23                        if (len < 0) {
  24                                BCM_DEBUG_PRINT(psIntfAdapter->psAdapter,
  25                                                DBG_TYPE_INITEXIT, MP_INIT,
  26                                                DBG_LVL_ALL, "len < 0");
  27                                errno = len;
  28                        } else {
  29                                errno = 0;
  30                                BCM_DEBUG_PRINT(psIntfAdapter->psAdapter,
  31                                                DBG_TYPE_INITEXIT, MP_INIT,
  32                                                DBG_LVL_ALL,
  33                                                "Got end of file!");
  34                        }
  35                        break;
  36                }
  37                /* BCM_DEBUG_PRINT_BUFFER(Adapter,DBG_TYPE_INITEXIT, MP_INIT,
  38                 *                        DBG_LVL_ALL, buff,
  39                 *                        MAX_TRANSFER_CTRL_BYTE_USB);
  40                 */
  41                errno = InterfaceWRM(psIntfAdapter, on_chip_loc, buff, len);
  42                if (errno) {
  43                        BCM_DEBUG_PRINT(psIntfAdapter->psAdapter,
  44                                        DBG_TYPE_PRINTK, 0, 0,
  45                                        "WRM Failed! status: %d", errno);
  46                        break;
  47                }
  48                on_chip_loc += MAX_TRANSFER_CTRL_BYTE_USB;
  49        }
  50
  51        kfree(buff);
  52        return errno;
  53}
  54
  55int InterfaceFileReadbackFromChip(PVOID arg, struct file *flp, unsigned int on_chip_loc)
  56{
  57        char *buff, *buff_readback;
  58        unsigned int reg = 0;
  59        mm_segment_t oldfs = {0};
  60        int errno = 0, len = 0, is_config_file = 0;
  61        loff_t pos = 0;
  62        static int fw_down;
  63        INT Status = STATUS_SUCCESS;
  64        struct bcm_interface_adapter *psIntfAdapter = (struct bcm_interface_adapter *)arg;
  65        int bytes;
  66
  67        buff = kmalloc(MAX_TRANSFER_CTRL_BYTE_USB, GFP_DMA);
  68        buff_readback = kmalloc(MAX_TRANSFER_CTRL_BYTE_USB , GFP_DMA);
  69        if (!buff || !buff_readback) {
  70                kfree(buff);
  71                kfree(buff_readback);
  72
  73                return -ENOMEM;
  74        }
  75
  76        is_config_file = (on_chip_loc == CONFIG_BEGIN_ADDR) ? 1 : 0;
  77
  78        memset(buff_readback, 0, MAX_TRANSFER_CTRL_BYTE_USB);
  79        memset(buff, 0, MAX_TRANSFER_CTRL_BYTE_USB);
  80        while (1) {
  81                oldfs = get_fs();
  82                set_fs(get_ds());
  83                len = vfs_read(flp, (void __force __user *)buff, MAX_TRANSFER_CTRL_BYTE_USB, &pos);
  84                set_fs(oldfs);
  85                fw_down++;
  86
  87                if (len <= 0) {
  88                        if (len < 0) {
  89                                BCM_DEBUG_PRINT(psIntfAdapter->psAdapter, DBG_TYPE_INITEXIT, MP_INIT, DBG_LVL_ALL, "len < 0");
  90                                errno = len;
  91                        } else {
  92                                errno = 0;
  93                                BCM_DEBUG_PRINT(psIntfAdapter->psAdapter, DBG_TYPE_INITEXIT, MP_INIT, DBG_LVL_ALL, "Got end of file!");
  94                        }
  95                        break;
  96                }
  97
  98                bytes = InterfaceRDM(psIntfAdapter, on_chip_loc, buff_readback, len);
  99                if (bytes < 0) {
 100                        Status = bytes;
 101                        BCM_DEBUG_PRINT(psIntfAdapter->psAdapter, DBG_TYPE_INITEXIT, MP_INIT, DBG_LVL_ALL, "RDM of len %d Failed! %d", len, reg);
 102                        goto exit;
 103                }
 104                reg++;
 105                if ((len-sizeof(unsigned int)) < 4) {
 106                        if (memcmp(buff_readback, buff, len)) {
 107                                BCM_DEBUG_PRINT(psIntfAdapter->psAdapter, DBG_TYPE_INITEXIT, MP_INIT, DBG_LVL_ALL, "Firmware Download is not proper %d", fw_down);
 108                                BCM_DEBUG_PRINT(psIntfAdapter->psAdapter, DBG_TYPE_INITEXIT, MP_INIT, DBG_LVL_ALL, "Length is: %d", len);
 109                                Status = -EIO;
 110                                goto exit;
 111                        }
 112                } else {
 113                        len -= 4;
 114
 115                        while (len) {
 116                                if (*(unsigned int *)&buff_readback[len] != *(unsigned int *)&buff[len]) {
 117                                        BCM_DEBUG_PRINT(psIntfAdapter->psAdapter, DBG_TYPE_INITEXIT, MP_INIT, DBG_LVL_ALL, "Firmware Download is not proper %d", fw_down);
 118                                        BCM_DEBUG_PRINT(psIntfAdapter->psAdapter, DBG_TYPE_INITEXIT, MP_INIT, DBG_LVL_ALL, "Val from Binary %x, Val From Read Back %x ", *(unsigned int *)&buff[len], *(unsigned int*)&buff_readback[len]);
 119                                        BCM_DEBUG_PRINT(psIntfAdapter->psAdapter, DBG_TYPE_INITEXIT, MP_INIT, DBG_LVL_ALL, "len =%x!!!", len);
 120                                        Status = -EIO;
 121                                        goto exit;
 122                                }
 123                                len -= 4;
 124                        }
 125                }
 126                on_chip_loc += MAX_TRANSFER_CTRL_BYTE_USB;
 127        } /* End of while(1) */
 128
 129exit:
 130        kfree(buff);
 131        kfree(buff_readback);
 132        return Status;
 133}
 134
 135static int bcm_download_config_file(struct bcm_mini_adapter *Adapter, struct bcm_firmware_info *psFwInfo)
 136{
 137        int retval = STATUS_SUCCESS;
 138        B_UINT32 value = 0;
 139
 140        if (Adapter->pstargetparams == NULL) {
 141                Adapter->pstargetparams = kmalloc(sizeof(struct bcm_target_params), GFP_KERNEL);
 142                if (Adapter->pstargetparams == NULL)
 143                        return -ENOMEM;
 144        }
 145
 146        if (psFwInfo->u32FirmwareLength != sizeof(struct bcm_target_params))
 147                return -EIO;
 148
 149        retval = copy_from_user(Adapter->pstargetparams, psFwInfo->pvMappedFirmwareAddress, psFwInfo->u32FirmwareLength);
 150        if (retval) {
 151                kfree(Adapter->pstargetparams);
 152                Adapter->pstargetparams = NULL;
 153                return -EFAULT;
 154        }
 155
 156        /* Parse the structure and then Download the Firmware */
 157        beceem_parse_target_struct(Adapter);
 158
 159        /* Initializing the NVM. */
 160        BcmInitNVM(Adapter);
 161        retval = InitLedSettings(Adapter);
 162
 163        if (retval) {
 164                BCM_DEBUG_PRINT(Adapter, DBG_TYPE_INITEXIT, MP_INIT, DBG_LVL_ALL, "INIT LED Failed\n");
 165                return retval;
 166        }
 167
 168        if (Adapter->LEDInfo.led_thread_running & BCM_LED_THREAD_RUNNING_ACTIVELY) {
 169                Adapter->LEDInfo.bLedInitDone = FALSE;
 170                Adapter->DriverState = DRIVER_INIT;
 171                wake_up(&Adapter->LEDInfo.notify_led_event);
 172        }
 173
 174        if (Adapter->LEDInfo.led_thread_running & BCM_LED_THREAD_RUNNING_ACTIVELY) {
 175                Adapter->DriverState = FW_DOWNLOAD;
 176                wake_up(&Adapter->LEDInfo.notify_led_event);
 177        }
 178
 179        /* Initialize the DDR Controller */
 180        retval = ddr_init(Adapter);
 181        if (retval) {
 182                BCM_DEBUG_PRINT (Adapter, DBG_TYPE_INITEXIT, MP_INIT, DBG_LVL_ALL, "DDR Init Failed\n");
 183                return retval;
 184        }
 185
 186        value = 0;
 187        wrmalt(Adapter, EEPROM_CAL_DATA_INTERNAL_LOC - 4, &value, sizeof(value));
 188        wrmalt(Adapter, EEPROM_CAL_DATA_INTERNAL_LOC - 8, &value, sizeof(value));
 189
 190        if (Adapter->eNVMType == NVM_FLASH) {
 191                retval = PropagateCalParamsFromFlashToMemory(Adapter);
 192                if (retval) {
 193                        BCM_DEBUG_PRINT(Adapter, DBG_TYPE_INITEXIT, MP_INIT, DBG_LVL_ALL, "propagaion of cal param failed with status :%d", retval);
 194                        return retval;
 195                }
 196        }
 197
 198        retval = buffDnldVerify(Adapter, (PUCHAR)Adapter->pstargetparams, sizeof(struct bcm_target_params), CONFIG_BEGIN_ADDR);
 199
 200        if (retval)
 201                BCM_DEBUG_PRINT(Adapter, DBG_TYPE_INITEXIT, MP_INIT, DBG_LVL_ALL, "configuration file not downloaded properly");
 202        else
 203                Adapter->bCfgDownloaded = TRUE;
 204
 205        return retval;
 206}
 207
 208int bcm_ioctl_fw_download(struct bcm_mini_adapter *Adapter, struct bcm_firmware_info *psFwInfo)
 209{
 210        int retval = STATUS_SUCCESS;
 211        PUCHAR buff = NULL;
 212
 213        /* Config File is needed for the Driver to download the Config file and
 214         * Firmware. Check for the Config file to be first to be sent from the
 215         * Application
 216         */
 217        atomic_set(&Adapter->uiMBupdate, FALSE);
 218        if (!Adapter->bCfgDownloaded && psFwInfo->u32StartingAddress != CONFIG_BEGIN_ADDR) {
 219                /* Can't Download Firmware. */
 220                BCM_DEBUG_PRINT(Adapter, DBG_TYPE_INITEXIT, MP_INIT, DBG_LVL_ALL, "Download the config File first\n");
 221                return -EINVAL;
 222        }
 223
 224        /* If Config File, Finish the DDR Settings and then Download CFG File */
 225        if (psFwInfo->u32StartingAddress == CONFIG_BEGIN_ADDR) {
 226                retval = bcm_download_config_file(Adapter, psFwInfo);
 227        } else {
 228                buff = kzalloc(psFwInfo->u32FirmwareLength, GFP_KERNEL);
 229                if (buff == NULL) {
 230                        BCM_DEBUG_PRINT(Adapter, DBG_TYPE_INITEXIT, MP_INIT, DBG_LVL_ALL, "Failed in allocation memory");
 231                        return -ENOMEM;
 232                }
 233
 234                retval = copy_from_user(buff, psFwInfo->pvMappedFirmwareAddress, psFwInfo->u32FirmwareLength);
 235                if (retval != STATUS_SUCCESS) {
 236                        BCM_DEBUG_PRINT(Adapter, DBG_TYPE_INITEXIT, MP_INIT, DBG_LVL_ALL, "copying buffer from user space failed");
 237                        retval = -EFAULT;
 238                        goto error;
 239                }
 240
 241                retval = buffDnldVerify(Adapter,
 242                                        buff,
 243                                        psFwInfo->u32FirmwareLength,
 244                                        psFwInfo->u32StartingAddress);
 245
 246                if (retval != STATUS_SUCCESS) {
 247                        BCM_DEBUG_PRINT(Adapter, DBG_TYPE_INITEXIT, MP_INIT, DBG_LVL_ALL, "f/w download failed status :%d", retval);
 248                        goto error;
 249                }
 250        }
 251
 252error:
 253        kfree(buff);
 254        return retval;
 255}
 256
 257static INT buffDnld(struct bcm_mini_adapter *Adapter, PUCHAR mappedbuffer, UINT u32FirmwareLength, ULONG u32StartingAddress)
 258{
 259        unsigned int len = 0;
 260        int retval = STATUS_SUCCESS;
 261        len = u32FirmwareLength;
 262
 263        while (u32FirmwareLength) {
 264                len = MIN_VAL(u32FirmwareLength, MAX_TRANSFER_CTRL_BYTE_USB);
 265                retval = wrm(Adapter, u32StartingAddress, mappedbuffer, len);
 266
 267                if (retval) {
 268                        BCM_DEBUG_PRINT(Adapter, DBG_TYPE_INITEXIT, MP_INIT, DBG_LVL_ALL, "wrm failed with status :%d", retval);
 269                        break;
 270                }
 271                u32StartingAddress += len;
 272                u32FirmwareLength -= len;
 273                mappedbuffer += len;
 274        }
 275        return retval;
 276}
 277
 278static INT buffRdbkVerify(struct bcm_mini_adapter *Adapter, PUCHAR mappedbuffer, UINT u32FirmwareLength, ULONG u32StartingAddress)
 279{
 280        UINT len = u32FirmwareLength;
 281        INT retval = STATUS_SUCCESS;
 282        PUCHAR readbackbuff = kzalloc(MAX_TRANSFER_CTRL_BYTE_USB, GFP_KERNEL);
 283        int bytes;
 284
 285        if (NULL == readbackbuff) {
 286                BCM_DEBUG_PRINT(Adapter, DBG_TYPE_INITEXIT, MP_INIT, DBG_LVL_ALL, "MEMORY ALLOCATION FAILED");
 287                return -ENOMEM;
 288        }
 289
 290        while (u32FirmwareLength && !retval) {
 291                len = MIN_VAL(u32FirmwareLength, MAX_TRANSFER_CTRL_BYTE_USB);
 292                bytes = rdm(Adapter, u32StartingAddress, readbackbuff, len);
 293
 294                if (bytes < 0) {
 295                        retval = bytes;
 296                        BCM_DEBUG_PRINT(Adapter, DBG_TYPE_INITEXIT, MP_INIT, DBG_LVL_ALL, "rdm failed with status %d", retval);
 297                        break;
 298                }
 299
 300                if (memcmp(readbackbuff, mappedbuffer, len) != 0) {
 301                        pr_err("%s() failed.  The firmware doesn't match what was written",
 302                               __func__);
 303                        retval = -EIO;
 304                }
 305
 306                u32StartingAddress += len;
 307                u32FirmwareLength -= len;
 308                mappedbuffer += len;
 309
 310        } /* end of while (u32FirmwareLength && !retval) */
 311        kfree(readbackbuff);
 312        return retval;
 313}
 314
 315INT buffDnldVerify(struct bcm_mini_adapter *Adapter, unsigned char *mappedbuffer, unsigned int u32FirmwareLength, unsigned long u32StartingAddress)
 316{
 317        INT status = STATUS_SUCCESS;
 318
 319        status = buffDnld(Adapter, mappedbuffer, u32FirmwareLength, u32StartingAddress);
 320        if (status != STATUS_SUCCESS) {
 321                BCM_DEBUG_PRINT(Adapter, DBG_TYPE_INITEXIT, MP_INIT, DBG_LVL_ALL, "Buffer download failed");
 322                goto error;
 323        }
 324
 325        status = buffRdbkVerify(Adapter, mappedbuffer, u32FirmwareLength, u32StartingAddress);
 326        if (status != STATUS_SUCCESS) {
 327                BCM_DEBUG_PRINT(Adapter, DBG_TYPE_INITEXIT, MP_INIT, DBG_LVL_ALL, "Buffer readback verifier failed");
 328                goto error;
 329        }
 330error:
 331        return status;
 332}
 333