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

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
...@@ -739,7 +739,13 @@ static void p54_rx_eeprom_readback(struct ieee80211_hw *dev, ...@@ -739,7 +739,13 @@ static void p54_rx_eeprom_readback(struct ieee80211_hw *dev,
if (!priv->eeprom) if (!priv->eeprom)
return ; 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); complete(&priv->eeprom_comp);
} }
...@@ -940,12 +946,18 @@ int p54_read_eeprom(struct ieee80211_hw *dev) ...@@ -940,12 +946,18 @@ int p54_read_eeprom(struct ieee80211_hw *dev)
struct p54_hdr *hdr = NULL; struct p54_hdr *hdr = NULL;
struct p54_eeprom_lm86 *eeprom_hdr; struct p54_eeprom_lm86 *eeprom_hdr;
struct sk_buff *skb; struct sk_buff *skb;
size_t eeprom_size = 0x2020, offset = 0, blocksize; size_t eeprom_size = 0x2020, offset = 0, blocksize, maxblocksize;
int ret = -ENOMEM; int ret = -ENOMEM;
void *eeprom = NULL; void *eeprom = NULL;
skb = p54_alloc_skb(dev, 0x8000, sizeof(*hdr) + sizeof(*eeprom_hdr) + maxblocksize = EEPROM_READBACK_LEN;
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); P54_CONTROL_TYPE_EEPROM_READBACK, GFP_KERNEL);
if (!skb) if (!skb)
goto free; goto free;
...@@ -957,12 +969,19 @@ int p54_read_eeprom(struct ieee80211_hw *dev) ...@@ -957,12 +969,19 @@ int p54_read_eeprom(struct ieee80211_hw *dev)
goto free; goto free;
eeprom_hdr = (struct p54_eeprom_lm86 *) skb_put(skb, eeprom_hdr = (struct p54_eeprom_lm86 *) skb_put(skb,
sizeof(*eeprom_hdr) + EEPROM_READBACK_LEN); sizeof(*eeprom_hdr) + maxblocksize);
while (eeprom_size) { while (eeprom_size) {
blocksize = min(eeprom_size, (size_t)EEPROM_READBACK_LEN); blocksize = min(eeprom_size, maxblocksize);
eeprom_hdr->offset = cpu_to_le16(offset); if (priv->fw_var < 0x509) {
eeprom_hdr->len = cpu_to_le16(blocksize); 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); priv->tx(dev, skb, 0);
if (!wait_for_completion_interruptible_timeout(&priv->eeprom_comp, HZ)) { if (!wait_for_completion_interruptible_timeout(&priv->eeprom_comp, HZ)) {
......
...@@ -246,9 +246,21 @@ struct memrecord { ...@@ -246,9 +246,21 @@ struct memrecord {
}; };
struct p54_eeprom_lm86 { struct p54_eeprom_lm86 {
union {
struct {
__le16 offset; __le16 offset;
__le16 len; __le16 len;
u8 data[0]; u8 data[0];
} v1;
struct {
__le32 offset;
__le16 len;
u8 magic2;
u8 pad;
u8 magic[4];
u8 data[0];
} v2;
} __attribute__ ((packed));
} __attribute__ ((packed)); } __attribute__ ((packed));
enum p54_rx_decrypt_status { enum p54_rx_decrypt_status {
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment