aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net
diff options
context:
space:
mode:
authorChristian Lamparter <chunkeey@web.de>2008-09-04 06:29:38 -0400
committerJohn W. Linville <linville@tuxdriver.com>2008-09-05 16:19:52 -0400
commit2b80848e3818fb1c8ccddc105b065a86c68afa9d (patch)
tree02a8d14e9af88e79668d2b0b5414cf8438997a84 /drivers/net
parentd203b8ef8e5acf9dad5a53d7067ef146e6b2e837 (diff)
p54usb: support LM87 firmwares
This patch adds the necessary changes to support LM87 firmwares. Signed-off-by: Christian Lamparter <chunkeey@web.de> Signed-off-by: John W. Linville <linville@tuxdriver.com>
Diffstat (limited to 'drivers/net')
-rw-r--r--drivers/net/wireless/p54/p54.h6
-rw-r--r--drivers/net/wireless/p54/p54common.c5
-rw-r--r--drivers/net/wireless/p54/p54common.h5
-rw-r--r--drivers/net/wireless/p54/p54usb.c72
-rw-r--r--drivers/net/wireless/p54/p54usb.h5
5 files changed, 73 insertions, 20 deletions
diff --git a/drivers/net/wireless/p54/p54.h b/drivers/net/wireless/p54/p54.h
index 3d44ab34ee69..cd2a39f544b1 100644
--- a/drivers/net/wireless/p54/p54.h
+++ b/drivers/net/wireless/p54/p54.h
@@ -42,6 +42,11 @@ struct p54_control_hdr {
42 42
43#define ISL38XX_DEV_FIRMWARE_ADDR 0x20000 43#define ISL38XX_DEV_FIRMWARE_ADDR 0x20000
44 44
45#define FW_FMAC 0x464d4143
46#define FW_LM86 0x4c4d3836
47#define FW_LM87 0x4c4d3837
48#define FW_LM20 0x4c4d3230
49
45struct p54_common { 50struct p54_common {
46 u32 rx_start; 51 u32 rx_start;
47 u32 rx_end; 52 u32 rx_end;
@@ -68,6 +73,7 @@ struct p54_common {
68 unsigned int tx_hdr_len; 73 unsigned int tx_hdr_len;
69 void *cached_vdcf; 74 void *cached_vdcf;
70 unsigned int fw_var; 75 unsigned int fw_var;
76 unsigned int fw_interface;
71 struct ieee80211_tx_queue_stats tx_stats[8]; 77 struct ieee80211_tx_queue_stats tx_stats[8];
72 void *eeprom; 78 void *eeprom;
73 struct completion eeprom_comp; 79 struct completion eeprom_comp;
diff --git a/drivers/net/wireless/p54/p54common.c b/drivers/net/wireless/p54/p54common.c
index 6d8248eac6e8..e96bf1a8f84c 100644
--- a/drivers/net/wireless/p54/p54common.c
+++ b/drivers/net/wireless/p54/p54common.c
@@ -93,7 +93,8 @@ int p54_parse_firmware(struct ieee80211_hw *dev, const struct firmware *fw)
93 u32 code = le32_to_cpu(bootrec->code); 93 u32 code = le32_to_cpu(bootrec->code);
94 switch (code) { 94 switch (code) {
95 case BR_CODE_COMPONENT_ID: 95 case BR_CODE_COMPONENT_ID:
96 switch (be32_to_cpu(*(__be32 *)bootrec->data)) { 96 priv->fw_interface = be32_to_cpup(bootrec->data);
97 switch (priv->fw_interface) {
97 case FW_FMAC: 98 case FW_FMAC:
98 printk(KERN_INFO "p54: FreeMAC firmware\n"); 99 printk(KERN_INFO "p54: FreeMAC firmware\n");
99 break; 100 break;
@@ -104,7 +105,7 @@ int p54_parse_firmware(struct ieee80211_hw *dev, const struct firmware *fw)
104 printk(KERN_INFO "p54: LM86 firmware\n"); 105 printk(KERN_INFO "p54: LM86 firmware\n");
105 break; 106 break;
106 case FW_LM87: 107 case FW_LM87:
107 printk(KERN_INFO "p54: LM87 firmware - not supported yet!\n"); 108 printk(KERN_INFO "p54: LM87 firmware\n");
108 break; 109 break;
109 default: 110 default:
110 printk(KERN_INFO "p54: unknown firmware\n"); 111 printk(KERN_INFO "p54: unknown firmware\n");
diff --git a/drivers/net/wireless/p54/p54common.h b/drivers/net/wireless/p54/p54common.h
index 5f2af5152505..c24b5cddf46b 100644
--- a/drivers/net/wireless/p54/p54common.h
+++ b/drivers/net/wireless/p54/p54common.h
@@ -50,11 +50,6 @@ struct bootrec_desc {
50#define BR_CODE_END_OF_BRA 0xFF0000FF 50#define BR_CODE_END_OF_BRA 0xFF0000FF
51#define LEGACY_BR_CODE_END_OF_BRA 0xFFFFFFFF 51#define LEGACY_BR_CODE_END_OF_BRA 0xFFFFFFFF
52 52
53#define FW_FMAC 0x464d4143
54#define FW_LM86 0x4c4d3836
55#define FW_LM87 0x4c4d3837
56#define FW_LM20 0x4c4d3230
57
58/* PDA defines are Copyright (C) 2005 Nokia Corporation (taken from islsm_pda.h) */ 53/* PDA defines are Copyright (C) 2005 Nokia Corporation (taken from islsm_pda.h) */
59 54
60struct pda_entry { 55struct pda_entry {
diff --git a/drivers/net/wireless/p54/p54usb.c b/drivers/net/wireless/p54/p54usb.c
index eca858c40b1f..7444f3729779 100644
--- a/drivers/net/wireless/p54/p54usb.c
+++ b/drivers/net/wireless/p54/p54usb.c
@@ -91,8 +91,13 @@ static void p54u_rx_cb(struct urb *urb)
91 91
92 skb_unlink(skb, &priv->rx_queue); 92 skb_unlink(skb, &priv->rx_queue);
93 skb_put(skb, urb->actual_length); 93 skb_put(skb, urb->actual_length);
94 if (!priv->hw_type) 94
95 skb_pull(skb, sizeof(struct net2280_tx_hdr)); 95 if (priv->hw_type == P54U_NET2280)
96 skb_pull(skb, priv->common.tx_hdr_len);
97 if (priv->common.fw_interface == FW_LM87) {
98 skb_pull(skb, 4);
99 skb_put(skb, 4);
100 }
96 101
97 if (p54_rx(dev, skb)) { 102 if (p54_rx(dev, skb)) {
98 skb = dev_alloc_skb(priv->common.rx_mtu + 32); 103 skb = dev_alloc_skb(priv->common.rx_mtu + 32);
@@ -109,9 +114,12 @@ static void p54u_rx_cb(struct urb *urb)
109 urb->context = skb; 114 urb->context = skb;
110 skb_queue_tail(&priv->rx_queue, skb); 115 skb_queue_tail(&priv->rx_queue, skb);
111 } else { 116 } else {
112 if (!priv->hw_type) 117 if (priv->hw_type == P54U_NET2280)
113 skb_push(skb, sizeof(struct net2280_tx_hdr)); 118 skb_push(skb, priv->common.tx_hdr_len);
114 119 if (priv->common.fw_interface == FW_LM87) {
120 skb_push(skb, 4);
121 skb_put(skb, 4);
122 }
115 skb_reset_tail_pointer(skb); 123 skb_reset_tail_pointer(skb);
116 skb_trim(skb, 0); 124 skb_trim(skb, 0);
117 if (urb->transfer_buffer != skb_tail_pointer(skb)) { 125 if (urb->transfer_buffer != skb_tail_pointer(skb)) {
@@ -210,6 +218,42 @@ static void p54u_tx_3887(struct ieee80211_hw *dev, struct p54_control_hdr *data,
210 usb_submit_urb(data_urb, GFP_ATOMIC); 218 usb_submit_urb(data_urb, GFP_ATOMIC);
211} 219}
212 220
221__le32 p54u_lm87_chksum(const u32 *data, size_t length)
222{
223 __le32 chk = 0;
224
225 length >>= 2;
226 while (length--) {
227 chk ^= cpu_to_le32(*data++);
228 chk = (chk >> 5) ^ (chk << 3);
229 }
230
231 return chk;
232}
233
234static void p54u_tx_lm87(struct ieee80211_hw *dev,
235 struct p54_control_hdr *data,
236 size_t len, int free_on_tx)
237{
238 struct p54u_priv *priv = dev->priv;
239 struct urb *data_urb;
240 struct lm87_tx_hdr *hdr = (void *)data - sizeof(*hdr);
241
242 data_urb = usb_alloc_urb(0, GFP_ATOMIC);
243 if (!data_urb)
244 return;
245
246 hdr->chksum = p54u_lm87_chksum((u32 *)data, len);
247 hdr->device_addr = data->req_id;
248
249 usb_fill_bulk_urb(data_urb, priv->udev,
250 usb_sndbulkpipe(priv->udev, P54U_PIPE_DATA), hdr,
251 len + sizeof(*hdr), free_on_tx ? p54u_tx_free_cb : p54u_tx_cb,
252 dev);
253
254 usb_submit_urb(data_urb, GFP_ATOMIC);
255}
256
213static void p54u_tx_net2280(struct ieee80211_hw *dev, struct p54_control_hdr *data, 257static void p54u_tx_net2280(struct ieee80211_hw *dev, struct p54_control_hdr *data,
214 size_t len, int free_on_tx) 258 size_t len, int free_on_tx)
215{ 259{
@@ -776,21 +820,23 @@ static int __devinit p54u_probe(struct usb_interface *intf,
776 } 820 }
777 } 821 }
778 priv->common.open = p54u_open; 822 priv->common.open = p54u_open;
779 823 priv->common.stop = p54u_stop;
780 if (recognized_pipes < P54U_PIPE_NUMBER) { 824 if (recognized_pipes < P54U_PIPE_NUMBER) {
781 priv->hw_type = P54U_3887; 825 priv->hw_type = P54U_3887;
782 priv->common.tx = p54u_tx_3887; 826 err = p54u_upload_firmware_3887(dev);
827 if (priv->common.fw_interface == FW_LM87) {
828 dev->extra_tx_headroom += sizeof(struct lm87_tx_hdr);
829 priv->common.tx_hdr_len = sizeof(struct lm87_tx_hdr);
830 priv->common.tx = p54u_tx_lm87;
831 } else
832 priv->common.tx = p54u_tx_3887;
783 } else { 833 } else {
834 priv->hw_type = P54U_NET2280;
784 dev->extra_tx_headroom += sizeof(struct net2280_tx_hdr); 835 dev->extra_tx_headroom += sizeof(struct net2280_tx_hdr);
785 priv->common.tx_hdr_len = sizeof(struct net2280_tx_hdr); 836 priv->common.tx_hdr_len = sizeof(struct net2280_tx_hdr);
786 priv->common.tx = p54u_tx_net2280; 837 priv->common.tx = p54u_tx_net2280;
787 }
788 priv->common.stop = p54u_stop;
789
790 if (priv->hw_type)
791 err = p54u_upload_firmware_3887(dev);
792 else
793 err = p54u_upload_firmware_net2280(dev); 838 err = p54u_upload_firmware_net2280(dev);
839 }
794 if (err) 840 if (err)
795 goto err_free_dev; 841 goto err_free_dev;
796 842
diff --git a/drivers/net/wireless/p54/p54usb.h b/drivers/net/wireless/p54/p54usb.h
index 1baaff058c5a..5b8fe91379c3 100644
--- a/drivers/net/wireless/p54/p54usb.h
+++ b/drivers/net/wireless/p54/p54usb.h
@@ -72,6 +72,11 @@ struct net2280_tx_hdr {
72 u8 padding[8]; 72 u8 padding[8];
73} __attribute__((packed)); 73} __attribute__((packed));
74 74
75struct lm87_tx_hdr {
76 __le32 device_addr;
77 __le32 chksum;
78} __attribute__((packed));
79
75/* Some flags for the isl hardware registers controlling DMA inside the 80/* Some flags for the isl hardware registers controlling DMA inside the
76 * chip */ 81 * chip */
77#define ISL38XX_DMA_STATUS_DONE 0x00000001 82#define ISL38XX_DMA_STATUS_DONE 0x00000001