root/drivers/net/wireless/ralink/rt2x00/rt2x00firmware.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. rt2x00lib_request_firmware
  2. rt2x00lib_load_firmware
  3. rt2x00lib_free_firmware

   1 // SPDX-License-Identifier: GPL-2.0-or-later
   2 /*
   3         Copyright (C) 2004 - 2009 Ivo van Doorn <IvDoorn@gmail.com>
   4         Copyright (C) 2004 - 2009 Gertjan van Wingerde <gwingerde@gmail.com>
   5         <http://rt2x00.serialmonkey.com>
   6 
   7  */
   8 
   9 /*
  10         Module: rt2x00lib
  11         Abstract: rt2x00 firmware loading routines.
  12  */
  13 
  14 #include <linux/kernel.h>
  15 #include <linux/module.h>
  16 
  17 #include "rt2x00.h"
  18 #include "rt2x00lib.h"
  19 
  20 static int rt2x00lib_request_firmware(struct rt2x00_dev *rt2x00dev)
  21 {
  22         struct device *device = wiphy_dev(rt2x00dev->hw->wiphy);
  23         const struct firmware *fw;
  24         char *fw_name;
  25         int retval;
  26 
  27         /*
  28          * Read correct firmware from harddisk.
  29          */
  30         fw_name = rt2x00dev->ops->lib->get_firmware_name(rt2x00dev);
  31         if (!fw_name) {
  32                 rt2x00_err(rt2x00dev,
  33                            "Invalid firmware filename\n"
  34                            "Please file bug report to %s\n", DRV_PROJECT);
  35                 return -EINVAL;
  36         }
  37 
  38         rt2x00_info(rt2x00dev, "Loading firmware file '%s'\n", fw_name);
  39 
  40         retval = request_firmware(&fw, fw_name, device);
  41         if (retval) {
  42                 rt2x00_err(rt2x00dev, "Failed to request Firmware\n");
  43                 return retval;
  44         }
  45 
  46         if (!fw || !fw->size || !fw->data) {
  47                 rt2x00_err(rt2x00dev, "Failed to read Firmware\n");
  48                 release_firmware(fw);
  49                 return -ENOENT;
  50         }
  51 
  52         rt2x00_info(rt2x00dev, "Firmware detected - version: %d.%d\n",
  53                     fw->data[fw->size - 4], fw->data[fw->size - 3]);
  54         snprintf(rt2x00dev->hw->wiphy->fw_version,
  55                         sizeof(rt2x00dev->hw->wiphy->fw_version), "%d.%d",
  56                         fw->data[fw->size - 4], fw->data[fw->size - 3]);
  57 
  58         retval = rt2x00dev->ops->lib->check_firmware(rt2x00dev, fw->data, fw->size);
  59         switch (retval) {
  60         case FW_OK:
  61                 break;
  62         case FW_BAD_CRC:
  63                 rt2x00_err(rt2x00dev, "Firmware checksum error\n");
  64                 goto exit;
  65         case FW_BAD_LENGTH:
  66                 rt2x00_err(rt2x00dev, "Invalid firmware file length (len=%zu)\n",
  67                            fw->size);
  68                 goto exit;
  69         case FW_BAD_VERSION:
  70                 rt2x00_err(rt2x00dev, "Current firmware does not support detected chipset\n");
  71                 goto exit;
  72         }
  73 
  74         rt2x00dev->fw = fw;
  75 
  76         return 0;
  77 
  78 exit:
  79         release_firmware(fw);
  80 
  81         return -ENOENT;
  82 }
  83 
  84 int rt2x00lib_load_firmware(struct rt2x00_dev *rt2x00dev)
  85 {
  86         int retval;
  87 
  88         if (!rt2x00_has_cap_flag(rt2x00dev, REQUIRE_FIRMWARE))
  89                 return 0;
  90 
  91         if (!rt2x00dev->fw) {
  92                 retval = rt2x00lib_request_firmware(rt2x00dev);
  93                 if (retval)
  94                         return retval;
  95         }
  96 
  97         /*
  98          * Send firmware to the device.
  99          */
 100         retval = rt2x00dev->ops->lib->load_firmware(rt2x00dev,
 101                                                     rt2x00dev->fw->data,
 102                                                     rt2x00dev->fw->size);
 103 
 104         /*
 105          * When the firmware is uploaded to the hardware the LED
 106          * association status might have been triggered, for correct
 107          * LED handling it should now be reset.
 108          */
 109         rt2x00leds_led_assoc(rt2x00dev, false);
 110 
 111         return retval;
 112 }
 113 
 114 void rt2x00lib_free_firmware(struct rt2x00_dev *rt2x00dev)
 115 {
 116         release_firmware(rt2x00dev->fw);
 117         rt2x00dev->fw = NULL;
 118 }

/* [<][>][^][v][top][bottom][index][help] */