linux/drivers/staging/vt6656/firmware.c
<<
>>
Prefs
   1// SPDX-License-Identifier: GPL-2.0+
   2/*
   3 * Copyright (c) 1996, 2003 VIA Networking Technologies, Inc.
   4 * All rights reserved.
   5 *
   6 * File: baseband.c
   7 *
   8 * Purpose: Implement functions to access baseband
   9 *
  10 * Author: Yiching Chen
  11 *
  12 * Date: May 20, 2004
  13 *
  14 * Functions:
  15 *
  16 * Revision History:
  17 *
  18 */
  19
  20#include <linux/compiler.h>
  21#include "firmware.h"
  22#include "usbpipe.h"
  23
  24#define FIRMWARE_VERSION        0x133           /* version 1.51 */
  25#define FIRMWARE_NAME           "vntwusb.fw"
  26
  27#define FIRMWARE_CHUNK_SIZE     0x400
  28
  29int vnt_download_firmware(struct vnt_private *priv)
  30{
  31        struct device *dev = &priv->usb->dev;
  32        const struct firmware *fw;
  33        int status;
  34        void *buffer = NULL;
  35        bool result = false;
  36        u16 length;
  37        int ii, rc;
  38
  39        dev_dbg(dev, "---->Download firmware\n");
  40
  41        rc = request_firmware(&fw, FIRMWARE_NAME, dev);
  42        if (rc) {
  43                dev_err(dev, "firmware file %s request failed (%d)\n",
  44                        FIRMWARE_NAME, rc);
  45                        goto out;
  46        }
  47
  48        buffer = kmalloc(FIRMWARE_CHUNK_SIZE, GFP_KERNEL);
  49        if (!buffer)
  50                goto free_fw;
  51
  52        for (ii = 0; ii < fw->size; ii += FIRMWARE_CHUNK_SIZE) {
  53                length = min_t(int, fw->size - ii, FIRMWARE_CHUNK_SIZE);
  54                memcpy(buffer, fw->data + ii, length);
  55
  56                status = vnt_control_out(priv,
  57                                         0,
  58                                         0x1200 + ii,
  59                                         0x0000,
  60                                         length,
  61                                         buffer);
  62
  63                dev_dbg(dev, "Download firmware...%d %zu\n", ii, fw->size);
  64
  65                if (status != STATUS_SUCCESS)
  66                        goto free_fw;
  67        }
  68
  69        result = true;
  70free_fw:
  71        release_firmware(fw);
  72
  73out:
  74        kfree(buffer);
  75
  76        return result;
  77}
  78MODULE_FIRMWARE(FIRMWARE_NAME);
  79
  80int vnt_firmware_branch_to_sram(struct vnt_private *priv)
  81{
  82        int status;
  83
  84        dev_dbg(&priv->usb->dev, "---->Branch to Sram\n");
  85
  86        status = vnt_control_out(priv,
  87                                 1,
  88                                 0x1200,
  89                                 0x0000,
  90                                 0,
  91                                 NULL);
  92        return status == STATUS_SUCCESS;
  93}
  94
  95int vnt_check_firmware_version(struct vnt_private *priv)
  96{
  97        int status;
  98
  99        status = vnt_control_in(priv,
 100                                MESSAGE_TYPE_READ,
 101                                0,
 102                                MESSAGE_REQUEST_VERSION,
 103                                2,
 104                                (u8 *)&priv->firmware_version);
 105
 106        dev_dbg(&priv->usb->dev, "Firmware Version [%04x]\n",
 107                priv->firmware_version);
 108
 109        if (status != STATUS_SUCCESS) {
 110                dev_dbg(&priv->usb->dev, "Firmware Invalid.\n");
 111                return false;
 112        }
 113        if (priv->firmware_version == 0xFFFF) {
 114                dev_dbg(&priv->usb->dev, "In Loader.\n");
 115                return false;
 116        }
 117
 118        dev_dbg(&priv->usb->dev, "Firmware Version [%04x]\n",
 119                priv->firmware_version);
 120
 121        if (priv->firmware_version < FIRMWARE_VERSION) {
 122                /* branch to loader for download new firmware */
 123                vnt_firmware_branch_to_sram(priv);
 124                return false;
 125        }
 126        return true;
 127}
 128