Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit c22202fa authored by Ben Hutchings's avatar Ben Hutchings Committed by Greg Kroah-Hartman
Browse files

Staging: rt{2860,2870}sta: Use request_firmware() to load firmware



When originally introduced into staging, these drivers had custom
firmware-loading code which checked a version number and CRC at the
end of each blob.  This reintroduces those checks, using crc-ccitt
instead of custom code.

The removed firmware will be added to the linux-firmware.git
repository.

Based on work by Darren Salt <linux@youmustbejoking.demon.co.uk>.

Signed-off-by: default avatarBen Hutchings <ben@decadent.org.uk>
Tested-By: default avatarDarren Salt <linux@youmustbejoking.demon.co.uk>
Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@suse.de>
parent 8838d256
Loading
Loading
Loading
Loading
+2 −0
Original line number Diff line number Diff line
@@ -3,6 +3,8 @@ config RT2860
	depends on PCI && X86 && WLAN
	select WIRELESS_EXT
	select WEXT_PRIV
	select CRC_CCITT
	select FW_LOADER
	---help---
	  This is an experimental driver for the Ralink 2860 and 3090
	  wireless chips.
+0 −558

File deleted.

Preview size limit exceeded, changes collapsed.

+0 −517

File deleted.

Preview size limit exceeded, changes collapsed.

+105 −60
Original line number Diff line number Diff line
@@ -37,35 +37,38 @@

#include	"../rt_config.h"

#if defined(RT2860) || defined(RT3090)
#include "firmware.h"
#include "../../rt3090/firmware.h"
#endif
#ifdef RT2870
#include "../../rt3070/firmware.h"
#include "firmware_3070.h"
#endif

#include <linux/bitrev.h>
#include <linux/crc-ccitt.h>
#include <linux/firmware.h>

#ifdef RTMP_MAC_USB
/* */
/* RT2870 Firmware Spec only used 1 oct for version expression */
/* */
#define FIRMWARE_MINOR_VERSION	7
#endif /* RTMP_MAC_USB // */

/* New 8k byte firmware size for RT3071/RT3072 */
#define FIRMWAREIMAGE_MAX_LENGTH	0x2000
#define FIRMWAREIMAGE_LENGTH			(sizeof (FirmwareImage) / sizeof(u8))
#define FIRMWARE_MAJOR_VERSION		0
#define FIRMWAREIMAGE_LENGTH		0x1000

#define FIRMWAREIMAGEV1_LENGTH		0x1000
#define FIRMWAREIMAGEV2_LENGTH		0x1000
#define FIRMWARE_2870_MIN_VERSION	12
#define FIRMWARE_2870_FILENAME		"rt2870.bin"
MODULE_FIRMWARE(FIRMWARE_2870_FILENAME);

#ifdef RTMP_MAC_PCI
#define FIRMWARE_MINOR_VERSION		2
#endif /* RTMP_MAC_PCI // */
#define FIRMWARE_3070_MIN_VERSION	17
#define FIRMWARE_3070_FILENAME		"rt3070.bin"
MODULE_FIRMWARE(FIRMWARE_3070_FILENAME);

#define FIRMWARE_3071_MIN_VERSION	17
#define FIRMWARE_3071_FILENAME		"rt3071.bin"	/* for RT3071/RT3072 */
MODULE_FIRMWARE(FIRMWARE_3071_FILENAME);

#else /* RTMP_MAC_PCI */

#define FIRMWAREIMAGE_LENGTH		0x2000

#define FIRMWARE_2860_MIN_VERSION	11
#define FIRMWARE_2860_FILENAME		"rt2860.bin"
MODULE_FIRMWARE(FIRMWARE_2860_FILENAME);

#define FIRMWARE_3090_MIN_VERSION	19
#define FIRMWARE_3090_FILENAME		"rt3090.bin"	/* for RT3090/RT3390 */
MODULE_FIRMWARE(FIRMWARE_3090_FILENAME);

#endif

/*
	========================================================================
@@ -90,6 +93,78 @@ int RtmpAsicEraseFirmware(struct rt_rtmp_adapter *pAd)
	return 0;
}

static const struct firmware *rtmp_get_firmware(struct rt_rtmp_adapter *adapter)
{
	const char *name;
	const struct firmware *fw = NULL;
	u8 min_version;
	struct device *dev;
	int err;

	if (adapter->firmware)
		return adapter->firmware;

#ifdef RTMP_MAC_USB
	if (IS_RT3071(adapter)) {
		name = FIRMWARE_3071_FILENAME;
		min_version = FIRMWARE_3071_MIN_VERSION;
	} else if (IS_RT3070(adapter)) {
		name = FIRMWARE_3070_FILENAME;
		min_version = FIRMWARE_3070_MIN_VERSION;
	} else {
		name = FIRMWARE_2870_FILENAME;
		min_version = FIRMWARE_2870_MIN_VERSION;
	}
	dev = &((struct os_cookie *)adapter->OS_Cookie)->pUsb_Dev->dev;
#else /* RTMP_MAC_PCI */
	if (IS_RT3090(adapter) || IS_RT3390(adapter)) {
		name = FIRMWARE_3090_FILENAME;
		min_version = FIRMWARE_3090_MIN_VERSION;
	} else {
		name = FIRMWARE_2860_FILENAME;
		min_version = FIRMWARE_2860_MIN_VERSION;
	}
	dev = &((struct os_cookie *)adapter->OS_Cookie)->pci_dev->dev;
#endif

	err = request_firmware(&fw, name, dev);
	if (err) {
		dev_err(dev, "firmware file %s request failed (%d)\n",
			name, err);
		return NULL;
	}

	if (fw->size < FIRMWAREIMAGE_LENGTH) {
		dev_err(dev, "firmware file %s size is invalid\n", name);
		goto invalid;
	}

	/* is it new enough? */
	adapter->FirmwareVersion = fw->data[FIRMWAREIMAGE_LENGTH - 3];
	if (adapter->FirmwareVersion < min_version) {
		dev_err(dev,
			"firmware file %s is too old;"
			" driver requires v%d or later\n",
			name, min_version);
		goto invalid;
	}

	/* is the internal CRC correct? */
	if (crc_ccitt(0xffff, fw->data, FIRMWAREIMAGE_LENGTH - 2) !=
	    (fw->data[FIRMWAREIMAGE_LENGTH - 2] |
	     (fw->data[FIRMWAREIMAGE_LENGTH - 1] << 8))) {
		dev_err(dev, "firmware file %s failed internal CRC\n", name);
		goto invalid;
	}

	adapter->firmware = fw;
	return fw;

invalid:
	release_firmware(fw);
	return NULL;
}

/*
	========================================================================

@@ -109,46 +184,16 @@ int RtmpAsicEraseFirmware(struct rt_rtmp_adapter *pAd)
*/
int RtmpAsicLoadFirmware(struct rt_rtmp_adapter *pAd)
{

	const struct firmware *fw;
	int Status = NDIS_STATUS_SUCCESS;
	u8 *pFirmwareImage = NULL;
	unsigned long FileLength, Index;
	unsigned long Index;
	u32 MacReg = 0;
#ifdef RTMP_MAC_USB
	u32 Version = (pAd->MACVersion >> 16);
#endif

	/* New 8k byte firmware size for RT3071/RT3072 */
	{
#ifdef RTMP_MAC_PCI
		if (IS_RT3090(pAd) || IS_RT3390(pAd)) {
			pFirmwareImage = FirmwareImage_3090;
			FileLength = FIRMWAREIMAGE_MAX_LENGTH;
		} else {
			pFirmwareImage = FirmwareImage_2860;
			FileLength = FIRMWAREIMAGE_MAX_LENGTH;
		}
#endif /* RTMP_MAC_PCI // */
#ifdef RTMP_MAC_USB
		/* the firmware image consists of two parts */
		if ((Version != 0x2860) && (Version != 0x2872) && (Version != 0x3070)) {	/* use the second part */
			/*printk("KH:Use New Version,part2\n"); */
			pFirmwareImage =
			    (u8 *)&
			    FirmwareImage_3070[FIRMWAREIMAGEV1_LENGTH];
			FileLength = FIRMWAREIMAGEV2_LENGTH;
		} else {
			/*printk("KH:Use New Version,part1\n"); */
			if (Version == 0x3070)
				pFirmwareImage = FirmwareImage_3070;
			else
				pFirmwareImage = FirmwareImage_2870;
			FileLength = FIRMWAREIMAGEV1_LENGTH;
		}
#endif /* RTMP_MAC_USB // */
	}
	fw = rtmp_get_firmware(pAd);
	if (!fw)
		return NDIS_STATUS_FAILURE;

	RTMP_WRITE_FIRMWARE(pAd, pFirmwareImage, FileLength);
	RTMP_WRITE_FIRMWARE(pAd, fw->data, FIRMWAREIMAGE_LENGTH);

	/* check if MCU is ready */
	Index = 0;
+3 −0
Original line number Diff line number Diff line
@@ -25,6 +25,7 @@
 *************************************************************************
 */

#include <linux/firmware.h>
#include <linux/sched.h>
#include "rt_config.h"

@@ -260,6 +261,8 @@ void RTMPFreeAdapter(struct rt_rtmp_adapter *pAd)

	NdisFreeSpinLock(&pAd->irq_lock);

	release_firmware(pAd->firmware);

	vfree(pAd);		/* pci_free_consistent(os_cookie->pci_dev,sizeof(struct rt_rtmp_adapter),pAd,os_cookie->pAd_pa); */
	if (os_cookie)
		kfree(os_cookie);
Loading