Commit 64c354dd authored by Christian Lamparter's avatar Christian Lamparter Committed by John W. Linville
Browse files

p54: include support for 2.13.24.0 USB LM87 Firmwares



Those firmwares are probably capable of reprogramming the device's eeprom.
We better support them officially, before all the accidents happen.

Signed-off-by: default avatarChristian Lamparter <chunkeey@web.de>
Signed-off-by: default avatarJohn W. Linville <linville@tuxdriver.com>
parent 25900ef0
Loading
Loading
Loading
Loading
+27 −8
Original line number Diff line number Diff line
@@ -739,7 +739,13 @@ static void p54_rx_eeprom_readback(struct ieee80211_hw *dev,
	if (!priv->eeprom)
		return ;

	memcpy(priv->eeprom, eeprom->data, le16_to_cpu(eeprom->len));
	if (priv->fw_var >= 0x509) {
		memcpy(priv->eeprom, eeprom->v2.data,
		       le16_to_cpu(eeprom->v2.len));
	} else {
		memcpy(priv->eeprom, eeprom->v1.data,
		       le16_to_cpu(eeprom->v1.len));
	}

	complete(&priv->eeprom_comp);
}
@@ -940,12 +946,18 @@ int p54_read_eeprom(struct ieee80211_hw *dev)
	struct p54_hdr *hdr = NULL;
	struct p54_eeprom_lm86 *eeprom_hdr;
	struct sk_buff *skb;
	size_t eeprom_size = 0x2020, offset = 0, blocksize;
	size_t eeprom_size = 0x2020, offset = 0, blocksize, maxblocksize;
	int ret = -ENOMEM;
	void *eeprom = NULL;

	skb = p54_alloc_skb(dev, 0x8000, sizeof(*hdr) + sizeof(*eeprom_hdr) +
			    EEPROM_READBACK_LEN,
	maxblocksize = EEPROM_READBACK_LEN;
	if (priv->fw_var >= 0x509)
		maxblocksize -= 0xc;
	else
		maxblocksize -= 0x4;

	skb = p54_alloc_skb(dev, P54_HDR_FLAG_CONTROL, sizeof(*hdr) +
			    sizeof(*eeprom_hdr) + maxblocksize,
			    P54_CONTROL_TYPE_EEPROM_READBACK, GFP_KERNEL);
	if (!skb)
		goto free;
@@ -957,12 +969,19 @@ int p54_read_eeprom(struct ieee80211_hw *dev)
		goto free;

	eeprom_hdr = (struct p54_eeprom_lm86 *) skb_put(skb,
		     sizeof(*eeprom_hdr) + EEPROM_READBACK_LEN);
		     sizeof(*eeprom_hdr) + maxblocksize);

	while (eeprom_size) {
		blocksize = min(eeprom_size, (size_t)EEPROM_READBACK_LEN);
		eeprom_hdr->offset = cpu_to_le16(offset);
		eeprom_hdr->len = cpu_to_le16(blocksize);
		blocksize = min(eeprom_size, maxblocksize);
		if (priv->fw_var < 0x509) {
			eeprom_hdr->v1.offset = cpu_to_le16(offset);
			eeprom_hdr->v1.len = cpu_to_le16(blocksize);
		} else {
			eeprom_hdr->v2.offset = cpu_to_le32(offset);
			eeprom_hdr->v2.len = cpu_to_le16(blocksize);
			eeprom_hdr->v2.magic2 = 0xf;
			memcpy(eeprom_hdr->v2.magic, (const char *)"LOCK", 4);
		}
		priv->tx(dev, skb, 0);

		if (!wait_for_completion_interruptible_timeout(&priv->eeprom_comp, HZ)) {
+15 −3
Original line number Diff line number Diff line
@@ -246,9 +246,21 @@ struct memrecord {
};

struct p54_eeprom_lm86 {
	union {
		struct {
			__le16 offset;
			__le16 len;
			u8 data[0];
		} v1;
		struct {
			__le32 offset;
			__le16 len;
			u8 magic2;
			u8 pad;
			u8 magic[4];
			u8 data[0];
		} v2;
	}  __attribute__ ((packed));
} __attribute__ ((packed));

enum p54_rx_decrypt_status {