diff options
author | Christian Lamparter <chunkeey@web.de> | 2008-11-29 16:35:43 -0500 |
---|---|---|
committer | John W. Linville <linville@tuxdriver.com> | 2008-12-05 09:35:44 -0500 |
commit | 64c354ddcd65c98d9a1e2a8f7fb5cc80c7fa488e (patch) | |
tree | ccec32736bbb126b0c0e7d07a66821f7d5525ffa /drivers/net/wireless/p54 | |
parent | 25900ef0191af98bbb24d8088c6887af31c1ba27 (diff) |
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: Christian Lamparter <chunkeey@web.de>
Signed-off-by: John W. Linville <linville@tuxdriver.com>
Diffstat (limited to 'drivers/net/wireless/p54')
-rw-r--r-- | drivers/net/wireless/p54/p54common.c | 35 | ||||
-rw-r--r-- | drivers/net/wireless/p54/p54common.h | 18 |
2 files changed, 42 insertions, 11 deletions
diff --git a/drivers/net/wireless/p54/p54common.c b/drivers/net/wireless/p54/p54common.c index 6f7e82b56cbe..1b5627d4062e 100644 --- a/drivers/net/wireless/p54/p54common.c +++ b/drivers/net/wireless/p54/p54common.c | |||
@@ -739,7 +739,13 @@ static void p54_rx_eeprom_readback(struct ieee80211_hw *dev, | |||
739 | if (!priv->eeprom) | 739 | if (!priv->eeprom) |
740 | return ; | 740 | return ; |
741 | 741 | ||
742 | memcpy(priv->eeprom, eeprom->data, le16_to_cpu(eeprom->len)); | 742 | if (priv->fw_var >= 0x509) { |
743 | memcpy(priv->eeprom, eeprom->v2.data, | ||
744 | le16_to_cpu(eeprom->v2.len)); | ||
745 | } else { | ||
746 | memcpy(priv->eeprom, eeprom->v1.data, | ||
747 | le16_to_cpu(eeprom->v1.len)); | ||
748 | } | ||
743 | 749 | ||
744 | complete(&priv->eeprom_comp); | 750 | complete(&priv->eeprom_comp); |
745 | } | 751 | } |
@@ -940,12 +946,18 @@ int p54_read_eeprom(struct ieee80211_hw *dev) | |||
940 | struct p54_hdr *hdr = NULL; | 946 | struct p54_hdr *hdr = NULL; |
941 | struct p54_eeprom_lm86 *eeprom_hdr; | 947 | struct p54_eeprom_lm86 *eeprom_hdr; |
942 | struct sk_buff *skb; | 948 | struct sk_buff *skb; |
943 | size_t eeprom_size = 0x2020, offset = 0, blocksize; | 949 | size_t eeprom_size = 0x2020, offset = 0, blocksize, maxblocksize; |
944 | int ret = -ENOMEM; | 950 | int ret = -ENOMEM; |
945 | void *eeprom = NULL; | 951 | void *eeprom = NULL; |
946 | 952 | ||
947 | skb = p54_alloc_skb(dev, 0x8000, sizeof(*hdr) + sizeof(*eeprom_hdr) + | 953 | maxblocksize = EEPROM_READBACK_LEN; |
948 | EEPROM_READBACK_LEN, | 954 | if (priv->fw_var >= 0x509) |
955 | maxblocksize -= 0xc; | ||
956 | else | ||
957 | maxblocksize -= 0x4; | ||
958 | |||
959 | skb = p54_alloc_skb(dev, P54_HDR_FLAG_CONTROL, sizeof(*hdr) + | ||
960 | sizeof(*eeprom_hdr) + maxblocksize, | ||
949 | P54_CONTROL_TYPE_EEPROM_READBACK, GFP_KERNEL); | 961 | P54_CONTROL_TYPE_EEPROM_READBACK, GFP_KERNEL); |
950 | if (!skb) | 962 | if (!skb) |
951 | goto free; | 963 | goto free; |
@@ -957,12 +969,19 @@ int p54_read_eeprom(struct ieee80211_hw *dev) | |||
957 | goto free; | 969 | goto free; |
958 | 970 | ||
959 | eeprom_hdr = (struct p54_eeprom_lm86 *) skb_put(skb, | 971 | eeprom_hdr = (struct p54_eeprom_lm86 *) skb_put(skb, |
960 | sizeof(*eeprom_hdr) + EEPROM_READBACK_LEN); | 972 | sizeof(*eeprom_hdr) + maxblocksize); |
961 | 973 | ||
962 | while (eeprom_size) { | 974 | while (eeprom_size) { |
963 | blocksize = min(eeprom_size, (size_t)EEPROM_READBACK_LEN); | 975 | blocksize = min(eeprom_size, maxblocksize); |
964 | eeprom_hdr->offset = cpu_to_le16(offset); | 976 | if (priv->fw_var < 0x509) { |
965 | eeprom_hdr->len = cpu_to_le16(blocksize); | 977 | eeprom_hdr->v1.offset = cpu_to_le16(offset); |
978 | eeprom_hdr->v1.len = cpu_to_le16(blocksize); | ||
979 | } else { | ||
980 | eeprom_hdr->v2.offset = cpu_to_le32(offset); | ||
981 | eeprom_hdr->v2.len = cpu_to_le16(blocksize); | ||
982 | eeprom_hdr->v2.magic2 = 0xf; | ||
983 | memcpy(eeprom_hdr->v2.magic, (const char *)"LOCK", 4); | ||
984 | } | ||
966 | priv->tx(dev, skb, 0); | 985 | priv->tx(dev, skb, 0); |
967 | 986 | ||
968 | if (!wait_for_completion_interruptible_timeout(&priv->eeprom_comp, HZ)) { | 987 | if (!wait_for_completion_interruptible_timeout(&priv->eeprom_comp, HZ)) { |
diff --git a/drivers/net/wireless/p54/p54common.h b/drivers/net/wireless/p54/p54common.h index d292ffbec08c..5a68fdae7730 100644 --- a/drivers/net/wireless/p54/p54common.h +++ b/drivers/net/wireless/p54/p54common.h | |||
@@ -246,9 +246,21 @@ struct memrecord { | |||
246 | }; | 246 | }; |
247 | 247 | ||
248 | struct p54_eeprom_lm86 { | 248 | struct p54_eeprom_lm86 { |
249 | __le16 offset; | 249 | union { |
250 | __le16 len; | 250 | struct { |
251 | u8 data[0]; | 251 | __le16 offset; |
252 | __le16 len; | ||
253 | u8 data[0]; | ||
254 | } v1; | ||
255 | struct { | ||
256 | __le32 offset; | ||
257 | __le16 len; | ||
258 | u8 magic2; | ||
259 | u8 pad; | ||
260 | u8 magic[4]; | ||
261 | u8 data[0]; | ||
262 | } v2; | ||
263 | } __attribute__ ((packed)); | ||
252 | } __attribute__ ((packed)); | 264 | } __attribute__ ((packed)); |
253 | 265 | ||
254 | enum p54_rx_decrypt_status { | 266 | enum p54_rx_decrypt_status { |