cachepc-linux

Fork of AMDESE/linux with modifications for CachePC side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-linux
Log | Files | Refs | README | LICENSE | sfeed.txt

rt2x00firmware.c (2749B)


      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
     20static 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
     78exit:
     79	release_firmware(fw);
     80
     81	return -ENOENT;
     82}
     83
     84int 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
    114void rt2x00lib_free_firmware(struct rt2x00_dev *rt2x00dev)
    115{
    116	release_firmware(rt2x00dev->fw);
    117	rt2x00dev->fw = NULL;
    118}