aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/wireless/p54
diff options
context:
space:
mode:
authorChristian Lamparter <chunkeey@web.de>2008-11-29 16:35:43 -0500
committerJohn W. Linville <linville@tuxdriver.com>2008-12-05 09:35:44 -0500
commit64c354ddcd65c98d9a1e2a8f7fb5cc80c7fa488e (patch)
treeccec32736bbb126b0c0e7d07a66821f7d5525ffa /drivers/net/wireless/p54
parent25900ef0191af98bbb24d8088c6887af31c1ba27 (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.c35
-rw-r--r--drivers/net/wireless/p54/p54common.h18
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
248struct p54_eeprom_lm86 { 248struct 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
254enum p54_rx_decrypt_status { 266enum p54_rx_decrypt_status {