diff options
Diffstat (limited to 'drivers/net')
-rw-r--r-- | drivers/net/wireless/p54/p54.h | 9 | ||||
-rw-r--r-- | drivers/net/wireless/p54/p54common.c | 131 | ||||
-rw-r--r-- | drivers/net/wireless/p54/p54pci.c | 144 | ||||
-rw-r--r-- | drivers/net/wireless/p54/p54usb.c | 88 |
4 files changed, 137 insertions, 235 deletions
diff --git a/drivers/net/wireless/p54/p54.h b/drivers/net/wireless/p54/p54.h index b03d13edc61..3d44ab34ee6 100644 --- a/drivers/net/wireless/p54/p54.h +++ b/drivers/net/wireless/p54/p54.h | |||
@@ -38,7 +38,7 @@ struct p54_control_hdr { | |||
38 | u8 data[0]; | 38 | u8 data[0]; |
39 | } __attribute__ ((packed)); | 39 | } __attribute__ ((packed)); |
40 | 40 | ||
41 | #define EEPROM_READBACK_LEN (sizeof(struct p54_control_hdr) + 4 /* p54_eeprom_lm86 */) | 41 | #define EEPROM_READBACK_LEN 0x3fc |
42 | 42 | ||
43 | #define ISL38XX_DEV_FIRMWARE_ADDR 0x20000 | 43 | #define ISL38XX_DEV_FIRMWARE_ADDR 0x20000 |
44 | 44 | ||
@@ -63,18 +63,19 @@ struct p54_common { | |||
63 | struct pda_channel_output_limit *output_limit; | 63 | struct pda_channel_output_limit *output_limit; |
64 | unsigned int output_limit_len; | 64 | unsigned int output_limit_len; |
65 | struct pda_pa_curve_data *curve_data; | 65 | struct pda_pa_curve_data *curve_data; |
66 | __le16 rxhw; | 66 | u16 rxhw; |
67 | u8 version; | 67 | u8 version; |
68 | unsigned int tx_hdr_len; | 68 | unsigned int tx_hdr_len; |
69 | void *cached_vdcf; | 69 | void *cached_vdcf; |
70 | unsigned int fw_var; | 70 | unsigned int fw_var; |
71 | struct ieee80211_tx_queue_stats tx_stats[8]; | 71 | struct ieee80211_tx_queue_stats tx_stats[8]; |
72 | void *eeprom; | ||
73 | struct completion eeprom_comp; | ||
72 | }; | 74 | }; |
73 | 75 | ||
74 | int p54_rx(struct ieee80211_hw *dev, struct sk_buff *skb); | 76 | int p54_rx(struct ieee80211_hw *dev, struct sk_buff *skb); |
75 | int p54_parse_firmware(struct ieee80211_hw *dev, const struct firmware *fw); | 77 | int p54_parse_firmware(struct ieee80211_hw *dev, const struct firmware *fw); |
76 | int p54_parse_eeprom(struct ieee80211_hw *dev, void *eeprom, int len); | 78 | int p54_read_eeprom(struct ieee80211_hw *dev); |
77 | void p54_fill_eeprom_readback(struct p54_control_hdr *hdr); | ||
78 | struct ieee80211_hw *p54_init_common(size_t priv_data_len); | 79 | struct ieee80211_hw *p54_init_common(size_t priv_data_len); |
79 | void p54_free_common(struct ieee80211_hw *dev); | 80 | void p54_free_common(struct ieee80211_hw *dev); |
80 | 81 | ||
diff --git a/drivers/net/wireless/p54/p54common.c b/drivers/net/wireless/p54/p54common.c index fa61749b467..6d8248eac6e 100644 --- a/drivers/net/wireless/p54/p54common.c +++ b/drivers/net/wireless/p54/p54common.c | |||
@@ -249,6 +249,9 @@ static int p54_convert_rev1(struct ieee80211_hw *dev, | |||
249 | return 0; | 249 | return 0; |
250 | } | 250 | } |
251 | 251 | ||
252 | const char* p54_rf_chips[] = { "NULL", "Indigo?", "Duette", | ||
253 | "Frisbee", "Xbow", "Longbow" }; | ||
254 | |||
252 | int p54_parse_eeprom(struct ieee80211_hw *dev, void *eeprom, int len) | 255 | int p54_parse_eeprom(struct ieee80211_hw *dev, void *eeprom, int len) |
253 | { | 256 | { |
254 | struct p54_common *priv = dev->priv; | 257 | struct p54_common *priv = dev->priv; |
@@ -258,6 +261,7 @@ int p54_parse_eeprom(struct ieee80211_hw *dev, void *eeprom, int len) | |||
258 | void *tmp; | 261 | void *tmp; |
259 | int err; | 262 | int err; |
260 | u8 *end = (u8 *)eeprom + len; | 263 | u8 *end = (u8 *)eeprom + len; |
264 | DECLARE_MAC_BUF(mac); | ||
261 | 265 | ||
262 | wrap = (struct eeprom_pda_wrap *) eeprom; | 266 | wrap = (struct eeprom_pda_wrap *) eeprom; |
263 | entry = (void *)wrap->data + le16_to_cpu(wrap->len); | 267 | entry = (void *)wrap->data + le16_to_cpu(wrap->len); |
@@ -339,7 +343,7 @@ int p54_parse_eeprom(struct ieee80211_hw *dev, void *eeprom, int len) | |||
339 | while ((u8 *)tmp < entry->data + data_len) { | 343 | while ((u8 *)tmp < entry->data + data_len) { |
340 | struct bootrec_exp_if *exp_if = tmp; | 344 | struct bootrec_exp_if *exp_if = tmp; |
341 | if (le16_to_cpu(exp_if->if_id) == 0xF) | 345 | if (le16_to_cpu(exp_if->if_id) == 0xF) |
342 | priv->rxhw = exp_if->variant & cpu_to_le16(0x07); | 346 | priv->rxhw = le16_to_cpu(exp_if->variant) & 0x07; |
343 | tmp += sizeof(struct bootrec_exp_if); | 347 | tmp += sizeof(struct bootrec_exp_if); |
344 | } | 348 | } |
345 | break; | 349 | break; |
@@ -365,6 +369,37 @@ int p54_parse_eeprom(struct ieee80211_hw *dev, void *eeprom, int len) | |||
365 | goto err; | 369 | goto err; |
366 | } | 370 | } |
367 | 371 | ||
372 | switch (priv->rxhw) { | ||
373 | case 4: /* XBow */ | ||
374 | case 1: /* Indigo? */ | ||
375 | case 2: /* Duette */ | ||
376 | /* TODO: 5GHz initialization goes here */ | ||
377 | |||
378 | case 3: /* Frisbee */ | ||
379 | case 5: /* Longbow */ | ||
380 | dev->wiphy->bands[IEEE80211_BAND_2GHZ] = &band_2GHz; | ||
381 | break; | ||
382 | default: | ||
383 | printk(KERN_ERR "%s: unsupported RF-Chip\n", | ||
384 | wiphy_name(dev->wiphy)); | ||
385 | err = -EINVAL; | ||
386 | goto err; | ||
387 | } | ||
388 | |||
389 | if (!is_valid_ether_addr(dev->wiphy->perm_addr)) { | ||
390 | u8 perm_addr[ETH_ALEN]; | ||
391 | |||
392 | printk(KERN_WARNING "%s: Invalid hwaddr! Using randomly generated MAC addr\n", | ||
393 | wiphy_name(dev->wiphy)); | ||
394 | random_ether_addr(perm_addr); | ||
395 | SET_IEEE80211_PERM_ADDR(dev, perm_addr); | ||
396 | } | ||
397 | |||
398 | printk(KERN_INFO "%s: hwaddr %s, MAC:isl38%02x RF:%s\n", | ||
399 | wiphy_name(dev->wiphy), | ||
400 | print_mac(mac, dev->wiphy->perm_addr), | ||
401 | priv->version, p54_rf_chips[priv->rxhw]); | ||
402 | |||
368 | return 0; | 403 | return 0; |
369 | 404 | ||
370 | err: | 405 | err: |
@@ -388,20 +423,6 @@ int p54_parse_eeprom(struct ieee80211_hw *dev, void *eeprom, int len) | |||
388 | } | 423 | } |
389 | EXPORT_SYMBOL_GPL(p54_parse_eeprom); | 424 | EXPORT_SYMBOL_GPL(p54_parse_eeprom); |
390 | 425 | ||
391 | void p54_fill_eeprom_readback(struct p54_control_hdr *hdr) | ||
392 | { | ||
393 | struct p54_eeprom_lm86 *eeprom_hdr; | ||
394 | |||
395 | hdr->magic1 = cpu_to_le16(0x8000); | ||
396 | hdr->len = cpu_to_le16(sizeof(*eeprom_hdr) + 0x2000); | ||
397 | hdr->type = cpu_to_le16(P54_CONTROL_TYPE_EEPROM_READBACK); | ||
398 | hdr->retry1 = hdr->retry2 = 0; | ||
399 | eeprom_hdr = (struct p54_eeprom_lm86 *) hdr->data; | ||
400 | eeprom_hdr->offset = 0x0; | ||
401 | eeprom_hdr->len = cpu_to_le16(0x2000); | ||
402 | } | ||
403 | EXPORT_SYMBOL_GPL(p54_fill_eeprom_readback); | ||
404 | |||
405 | static void p54_rx_data(struct ieee80211_hw *dev, struct sk_buff *skb) | 426 | static void p54_rx_data(struct ieee80211_hw *dev, struct sk_buff *skb) |
406 | { | 427 | { |
407 | struct p54_rx_hdr *hdr = (struct p54_rx_hdr *) skb->data; | 428 | struct p54_rx_hdr *hdr = (struct p54_rx_hdr *) skb->data; |
@@ -499,6 +520,21 @@ out: | |||
499 | p54_wake_free_queues(dev); | 520 | p54_wake_free_queues(dev); |
500 | } | 521 | } |
501 | 522 | ||
523 | static void p54_rx_eeprom_readback(struct ieee80211_hw *dev, | ||
524 | struct sk_buff *skb) | ||
525 | { | ||
526 | struct p54_control_hdr *hdr = (struct p54_control_hdr *) skb->data; | ||
527 | struct p54_eeprom_lm86 *eeprom = (struct p54_eeprom_lm86 *) hdr->data; | ||
528 | struct p54_common *priv = dev->priv; | ||
529 | |||
530 | if (!priv->eeprom) | ||
531 | return ; | ||
532 | |||
533 | memcpy(priv->eeprom, eeprom->data, eeprom->len); | ||
534 | |||
535 | complete(&priv->eeprom_comp); | ||
536 | } | ||
537 | |||
502 | static void p54_rx_control(struct ieee80211_hw *dev, struct sk_buff *skb) | 538 | static void p54_rx_control(struct ieee80211_hw *dev, struct sk_buff *skb) |
503 | { | 539 | { |
504 | struct p54_control_hdr *hdr = (struct p54_control_hdr *) skb->data; | 540 | struct p54_control_hdr *hdr = (struct p54_control_hdr *) skb->data; |
@@ -509,6 +545,9 @@ static void p54_rx_control(struct ieee80211_hw *dev, struct sk_buff *skb) | |||
509 | break; | 545 | break; |
510 | case P54_CONTROL_TYPE_BBP: | 546 | case P54_CONTROL_TYPE_BBP: |
511 | break; | 547 | break; |
548 | case P54_CONTROL_TYPE_EEPROM_READBACK: | ||
549 | p54_rx_eeprom_readback(dev, skb); | ||
550 | break; | ||
512 | default: | 551 | default: |
513 | printk(KERN_DEBUG "%s: not handling 0x%02x type control frame\n", | 552 | printk(KERN_DEBUG "%s: not handling 0x%02x type control frame\n", |
514 | wiphy_name(dev->wiphy), le16_to_cpu(hdr->type)); | 553 | wiphy_name(dev->wiphy), le16_to_cpu(hdr->type)); |
@@ -607,6 +646,64 @@ static void p54_assign_address(struct ieee80211_hw *dev, struct sk_buff *skb, | |||
607 | data->req_id = cpu_to_le32(target_addr + priv->headroom); | 646 | data->req_id = cpu_to_le32(target_addr + priv->headroom); |
608 | } | 647 | } |
609 | 648 | ||
649 | int p54_read_eeprom(struct ieee80211_hw *dev) | ||
650 | { | ||
651 | struct p54_common *priv = dev->priv; | ||
652 | struct p54_control_hdr *hdr = NULL; | ||
653 | struct p54_eeprom_lm86 *eeprom_hdr; | ||
654 | size_t eeprom_size = 0x2020, offset = 0, blocksize; | ||
655 | int ret = -ENOMEM; | ||
656 | void *eeprom = NULL; | ||
657 | |||
658 | hdr = (struct p54_control_hdr *)kzalloc(sizeof(*hdr) + | ||
659 | sizeof(*eeprom_hdr) + EEPROM_READBACK_LEN, GFP_KERNEL); | ||
660 | if (!hdr) | ||
661 | goto free; | ||
662 | |||
663 | priv->eeprom = kzalloc(EEPROM_READBACK_LEN, GFP_KERNEL); | ||
664 | if (!priv->eeprom) | ||
665 | goto free; | ||
666 | |||
667 | eeprom = kzalloc(eeprom_size, GFP_KERNEL); | ||
668 | if (!eeprom) | ||
669 | goto free; | ||
670 | |||
671 | hdr->magic1 = cpu_to_le16(0x8000); | ||
672 | hdr->type = cpu_to_le16(P54_CONTROL_TYPE_EEPROM_READBACK); | ||
673 | hdr->retry1 = hdr->retry2 = 0; | ||
674 | eeprom_hdr = (struct p54_eeprom_lm86 *) hdr->data; | ||
675 | |||
676 | while (eeprom_size) { | ||
677 | blocksize = min(eeprom_size, (size_t)EEPROM_READBACK_LEN); | ||
678 | hdr->len = cpu_to_le16(blocksize + sizeof(*eeprom_hdr)); | ||
679 | eeprom_hdr->offset = cpu_to_le16(offset); | ||
680 | eeprom_hdr->len = cpu_to_le16(blocksize); | ||
681 | p54_assign_address(dev, NULL, hdr, hdr->len + sizeof(*hdr)); | ||
682 | priv->tx(dev, hdr, hdr->len + sizeof(*hdr), 0); | ||
683 | |||
684 | if (!wait_for_completion_interruptible_timeout(&priv->eeprom_comp, HZ)) { | ||
685 | printk(KERN_ERR "%s: device does not respond!\n", | ||
686 | wiphy_name(dev->wiphy)); | ||
687 | ret = -EBUSY; | ||
688 | goto free; | ||
689 | } | ||
690 | |||
691 | memcpy(eeprom + offset, priv->eeprom, blocksize); | ||
692 | offset += blocksize; | ||
693 | eeprom_size -= blocksize; | ||
694 | } | ||
695 | |||
696 | ret = p54_parse_eeprom(dev, eeprom, offset); | ||
697 | free: | ||
698 | kfree(priv->eeprom); | ||
699 | priv->eeprom = NULL; | ||
700 | kfree(hdr); | ||
701 | kfree(eeprom); | ||
702 | |||
703 | return ret; | ||
704 | } | ||
705 | EXPORT_SYMBOL_GPL(p54_read_eeprom); | ||
706 | |||
610 | static int p54_tx(struct ieee80211_hw *dev, struct sk_buff *skb) | 707 | static int p54_tx(struct ieee80211_hw *dev, struct sk_buff *skb) |
611 | { | 708 | { |
612 | struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); | 709 | struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); |
@@ -718,7 +815,7 @@ static int p54_set_filter(struct ieee80211_hw *dev, u16 filter_type, | |||
718 | filter->magic3 = cpu_to_le32(magic3); | 815 | filter->magic3 = cpu_to_le32(magic3); |
719 | filter->rx_addr = cpu_to_le32(priv->rx_end); | 816 | filter->rx_addr = cpu_to_le32(priv->rx_end); |
720 | filter->max_rx = cpu_to_le16(priv->rx_mtu); | 817 | filter->max_rx = cpu_to_le16(priv->rx_mtu); |
721 | filter->rxhw = priv->rxhw; | 818 | filter->rxhw = cpu_to_le16(priv->rxhw); |
722 | filter->magic8 = cpu_to_le16(magic8); | 819 | filter->magic8 = cpu_to_le16(magic8); |
723 | filter->magic9 = cpu_to_le16(magic9); | 820 | filter->magic9 = cpu_to_le16(magic9); |
724 | 821 | ||
@@ -1081,7 +1178,6 @@ struct ieee80211_hw *p54_init_common(size_t priv_data_len) | |||
1081 | priv = dev->priv; | 1178 | priv = dev->priv; |
1082 | priv->mode = IEEE80211_IF_TYPE_INVALID; | 1179 | priv->mode = IEEE80211_IF_TYPE_INVALID; |
1083 | skb_queue_head_init(&priv->tx_queue); | 1180 | skb_queue_head_init(&priv->tx_queue); |
1084 | dev->wiphy->bands[IEEE80211_BAND_2GHZ] = &band_2GHz; | ||
1085 | dev->flags = IEEE80211_HW_HOST_BROADCAST_PS_BUFFERING | /* not sure */ | 1181 | dev->flags = IEEE80211_HW_HOST_BROADCAST_PS_BUFFERING | /* not sure */ |
1086 | IEEE80211_HW_RX_INCLUDES_FCS | | 1182 | IEEE80211_HW_RX_INCLUDES_FCS | |
1087 | IEEE80211_HW_SIGNAL_UNSPEC; | 1183 | IEEE80211_HW_SIGNAL_UNSPEC; |
@@ -1101,6 +1197,7 @@ struct ieee80211_hw *p54_init_common(size_t priv_data_len) | |||
1101 | sizeof(struct p54_tx_control_allocdata); | 1197 | sizeof(struct p54_tx_control_allocdata); |
1102 | 1198 | ||
1103 | mutex_init(&priv->conf_mutex); | 1199 | mutex_init(&priv->conf_mutex); |
1200 | init_completion(&priv->eeprom_comp); | ||
1104 | 1201 | ||
1105 | return dev; | 1202 | return dev; |
1106 | } | 1203 | } |
diff --git a/drivers/net/wireless/p54/p54pci.c b/drivers/net/wireless/p54/p54pci.c index fdfc7189f0f..1594786205f 100644 --- a/drivers/net/wireless/p54/p54pci.c +++ b/drivers/net/wireless/p54/p54pci.c | |||
@@ -72,8 +72,6 @@ static int p54p_upload_firmware(struct ieee80211_hw *dev) | |||
72 | P54P_WRITE(ctrl_stat, reg); | 72 | P54P_WRITE(ctrl_stat, reg); |
73 | wmb(); | 73 | wmb(); |
74 | 74 | ||
75 | mdelay(50); | ||
76 | |||
77 | err = request_firmware(&fw_entry, "isl3886", &priv->pdev->dev); | 75 | err = request_firmware(&fw_entry, "isl3886", &priv->pdev->dev); |
78 | if (err) { | 76 | if (err) { |
79 | printk(KERN_ERR "%s (p54pci): cannot find firmware " | 77 | printk(KERN_ERR "%s (p54pci): cannot find firmware " |
@@ -126,120 +124,10 @@ static int p54p_upload_firmware(struct ieee80211_hw *dev) | |||
126 | wmb(); | 124 | wmb(); |
127 | udelay(10); | 125 | udelay(10); |
128 | 126 | ||
129 | return 0; | 127 | /* wait for the firmware to boot properly */ |
130 | } | ||
131 | |||
132 | static irqreturn_t p54p_simple_interrupt(int irq, void *dev_id) | ||
133 | { | ||
134 | struct p54p_priv *priv = (struct p54p_priv *) dev_id; | ||
135 | __le32 reg; | ||
136 | |||
137 | reg = P54P_READ(int_ident); | ||
138 | P54P_WRITE(int_ack, reg); | ||
139 | |||
140 | if (reg & P54P_READ(int_enable)) | ||
141 | complete(&priv->boot_comp); | ||
142 | |||
143 | return IRQ_HANDLED; | ||
144 | } | ||
145 | |||
146 | static int p54p_read_eeprom(struct ieee80211_hw *dev) | ||
147 | { | ||
148 | struct p54p_priv *priv = dev->priv; | ||
149 | struct p54p_ring_control *ring_control = priv->ring_control; | ||
150 | int err; | ||
151 | struct p54_control_hdr *hdr; | ||
152 | void *eeprom; | ||
153 | dma_addr_t rx_mapping, tx_mapping; | ||
154 | u16 alen; | ||
155 | |||
156 | init_completion(&priv->boot_comp); | ||
157 | err = request_irq(priv->pdev->irq, &p54p_simple_interrupt, | ||
158 | IRQF_SHARED, "p54pci", priv); | ||
159 | if (err) { | ||
160 | printk(KERN_ERR "%s (p54pci): failed to register IRQ handler\n", | ||
161 | pci_name(priv->pdev)); | ||
162 | return err; | ||
163 | } | ||
164 | |||
165 | eeprom = kmalloc(0x2010 + EEPROM_READBACK_LEN, GFP_KERNEL); | ||
166 | if (!eeprom) { | ||
167 | printk(KERN_ERR "%s (p54pci): no memory for eeprom!\n", | ||
168 | pci_name(priv->pdev)); | ||
169 | err = -ENOMEM; | ||
170 | goto out; | ||
171 | } | ||
172 | |||
173 | memset(ring_control, 0, sizeof(*ring_control)); | ||
174 | P54P_WRITE(ring_control_base, cpu_to_le32(priv->ring_control_dma)); | ||
175 | P54P_READ(ring_control_base); | ||
176 | udelay(10); | ||
177 | |||
178 | P54P_WRITE(int_enable, cpu_to_le32(ISL38XX_INT_IDENT_INIT)); | ||
179 | P54P_READ(int_enable); | ||
180 | udelay(10); | ||
181 | |||
182 | P54P_WRITE(dev_int, cpu_to_le32(ISL38XX_DEV_INT_RESET)); | ||
183 | |||
184 | if (!wait_for_completion_interruptible_timeout(&priv->boot_comp, HZ)) { | ||
185 | printk(KERN_ERR "%s (p54pci): Cannot boot firmware!\n", | ||
186 | pci_name(priv->pdev)); | ||
187 | err = -EINVAL; | ||
188 | goto out; | ||
189 | } | ||
190 | |||
191 | P54P_WRITE(int_enable, cpu_to_le32(ISL38XX_INT_IDENT_UPDATE)); | ||
192 | P54P_READ(int_enable); | ||
193 | |||
194 | hdr = eeprom + 0x2010; | ||
195 | p54_fill_eeprom_readback(hdr); | ||
196 | hdr->req_id = cpu_to_le32(priv->common.rx_start); | ||
197 | |||
198 | rx_mapping = pci_map_single(priv->pdev, eeprom, | ||
199 | 0x2010, PCI_DMA_FROMDEVICE); | ||
200 | tx_mapping = pci_map_single(priv->pdev, (void *)hdr, | ||
201 | EEPROM_READBACK_LEN, PCI_DMA_TODEVICE); | ||
202 | |||
203 | ring_control->rx_mgmt[0].host_addr = cpu_to_le32(rx_mapping); | ||
204 | ring_control->rx_mgmt[0].len = cpu_to_le16(0x2010); | ||
205 | ring_control->tx_data[0].host_addr = cpu_to_le32(tx_mapping); | ||
206 | ring_control->tx_data[0].device_addr = hdr->req_id; | ||
207 | ring_control->tx_data[0].len = cpu_to_le16(EEPROM_READBACK_LEN); | ||
208 | |||
209 | ring_control->host_idx[2] = cpu_to_le32(1); | ||
210 | ring_control->host_idx[1] = cpu_to_le32(1); | ||
211 | |||
212 | wmb(); | ||
213 | mdelay(100); | 128 | mdelay(100); |
214 | P54P_WRITE(dev_int, cpu_to_le32(ISL38XX_DEV_INT_UPDATE)); | ||
215 | |||
216 | wait_for_completion_interruptible_timeout(&priv->boot_comp, HZ); | ||
217 | wait_for_completion_interruptible_timeout(&priv->boot_comp, HZ); | ||
218 | |||
219 | pci_unmap_single(priv->pdev, tx_mapping, | ||
220 | EEPROM_READBACK_LEN, PCI_DMA_TODEVICE); | ||
221 | pci_unmap_single(priv->pdev, rx_mapping, | ||
222 | 0x2010, PCI_DMA_FROMDEVICE); | ||
223 | |||
224 | alen = le16_to_cpu(ring_control->rx_mgmt[0].len); | ||
225 | if (le32_to_cpu(ring_control->device_idx[2]) != 1 || | ||
226 | alen < 0x10) { | ||
227 | printk(KERN_ERR "%s (p54pci): Cannot read eeprom!\n", | ||
228 | pci_name(priv->pdev)); | ||
229 | err = -EINVAL; | ||
230 | goto out; | ||
231 | } | ||
232 | 129 | ||
233 | p54_parse_eeprom(dev, (u8 *)eeprom + 0x10, alen - 0x10); | 130 | return 0; |
234 | |||
235 | out: | ||
236 | kfree(eeprom); | ||
237 | P54P_WRITE(int_enable, cpu_to_le32(0)); | ||
238 | P54P_READ(int_enable); | ||
239 | udelay(10); | ||
240 | free_irq(priv->pdev->irq, priv); | ||
241 | P54P_WRITE(dev_int, cpu_to_le32(ISL38XX_DEV_INT_RESET)); | ||
242 | return err; | ||
243 | } | 131 | } |
244 | 132 | ||
245 | static void p54p_refill_rx_ring(struct ieee80211_hw *dev, | 133 | static void p54p_refill_rx_ring(struct ieee80211_hw *dev, |
@@ -473,6 +361,11 @@ static int p54p_open(struct ieee80211_hw *dev) | |||
473 | } | 361 | } |
474 | 362 | ||
475 | memset(priv->ring_control, 0, sizeof(*priv->ring_control)); | 363 | memset(priv->ring_control, 0, sizeof(*priv->ring_control)); |
364 | err = p54p_upload_firmware(dev); | ||
365 | if (err) { | ||
366 | free_irq(priv->pdev->irq, dev); | ||
367 | return err; | ||
368 | } | ||
476 | priv->rx_idx_data = priv->tx_idx_data = 0; | 369 | priv->rx_idx_data = priv->tx_idx_data = 0; |
477 | priv->rx_idx_mgmt = priv->tx_idx_mgmt = 0; | 370 | priv->rx_idx_mgmt = priv->tx_idx_mgmt = 0; |
478 | 371 | ||
@@ -482,8 +375,6 @@ static int p54p_open(struct ieee80211_hw *dev) | |||
482 | p54p_refill_rx_ring(dev, 2, priv->ring_control->rx_mgmt, | 375 | p54p_refill_rx_ring(dev, 2, priv->ring_control->rx_mgmt, |
483 | ARRAY_SIZE(priv->ring_control->rx_mgmt), priv->rx_buf_mgmt); | 376 | ARRAY_SIZE(priv->ring_control->rx_mgmt), priv->rx_buf_mgmt); |
484 | 377 | ||
485 | p54p_upload_firmware(dev); | ||
486 | |||
487 | P54P_WRITE(ring_control_base, cpu_to_le32(priv->ring_control_dma)); | 378 | P54P_WRITE(ring_control_base, cpu_to_le32(priv->ring_control_dma)); |
488 | P54P_READ(ring_control_base); | 379 | P54P_READ(ring_control_base); |
489 | wmb(); | 380 | wmb(); |
@@ -658,16 +549,6 @@ static int __devinit p54p_probe(struct pci_dev *pdev, | |||
658 | err = -ENOMEM; | 549 | err = -ENOMEM; |
659 | goto err_iounmap; | 550 | goto err_iounmap; |
660 | } | 551 | } |
661 | memset(priv->ring_control, 0, sizeof(*priv->ring_control)); | ||
662 | |||
663 | err = p54p_upload_firmware(dev); | ||
664 | if (err) | ||
665 | goto err_free_desc; | ||
666 | |||
667 | err = p54p_read_eeprom(dev); | ||
668 | if (err) | ||
669 | goto err_free_desc; | ||
670 | |||
671 | priv->common.open = p54p_open; | 552 | priv->common.open = p54p_open; |
672 | priv->common.stop = p54p_stop; | 553 | priv->common.stop = p54p_stop; |
673 | priv->common.tx = p54p_tx; | 554 | priv->common.tx = p54p_tx; |
@@ -675,6 +556,12 @@ static int __devinit p54p_probe(struct pci_dev *pdev, | |||
675 | spin_lock_init(&priv->lock); | 556 | spin_lock_init(&priv->lock); |
676 | tasklet_init(&priv->rx_tasklet, p54p_rx_tasklet, (unsigned long)dev); | 557 | tasklet_init(&priv->rx_tasklet, p54p_rx_tasklet, (unsigned long)dev); |
677 | 558 | ||
559 | p54p_open(dev); | ||
560 | err = p54_read_eeprom(dev); | ||
561 | p54p_stop(dev); | ||
562 | if (err) | ||
563 | goto err_free_desc; | ||
564 | |||
678 | err = ieee80211_register_hw(dev); | 565 | err = ieee80211_register_hw(dev); |
679 | if (err) { | 566 | if (err) { |
680 | printk(KERN_ERR "%s (p54pci): Cannot register netdevice\n", | 567 | printk(KERN_ERR "%s (p54pci): Cannot register netdevice\n", |
@@ -682,11 +569,6 @@ static int __devinit p54p_probe(struct pci_dev *pdev, | |||
682 | goto err_free_common; | 569 | goto err_free_common; |
683 | } | 570 | } |
684 | 571 | ||
685 | printk(KERN_INFO "%s: hwaddr %s, isl38%02x\n", | ||
686 | wiphy_name(dev->wiphy), | ||
687 | print_mac(mac, dev->wiphy->perm_addr), | ||
688 | priv->common.version); | ||
689 | |||
690 | return 0; | 572 | return 0; |
691 | 573 | ||
692 | err_free_common: | 574 | err_free_common: |
diff --git a/drivers/net/wireless/p54/p54usb.c b/drivers/net/wireless/p54/p54usb.c index 4dca209a6e0..eca858c40b1 100644 --- a/drivers/net/wireless/p54/p54usb.c +++ b/drivers/net/wireless/p54/p54usb.c | |||
@@ -315,73 +315,6 @@ static int p54u_bulk_msg(struct p54u_priv *priv, unsigned int ep, | |||
315 | data, len, &alen, 2000); | 315 | data, len, &alen, 2000); |
316 | } | 316 | } |
317 | 317 | ||
318 | static int p54u_read_eeprom(struct ieee80211_hw *dev) | ||
319 | { | ||
320 | struct p54u_priv *priv = dev->priv; | ||
321 | void *buf; | ||
322 | struct p54_control_hdr *hdr; | ||
323 | int err, alen; | ||
324 | size_t offset = priv->hw_type ? 0x10 : 0x20; | ||
325 | |||
326 | buf = kmalloc(0x2020, GFP_KERNEL); | ||
327 | if (!buf) { | ||
328 | printk(KERN_ERR "p54usb: cannot allocate memory for " | ||
329 | "eeprom readback!\n"); | ||
330 | return -ENOMEM; | ||
331 | } | ||
332 | |||
333 | if (priv->hw_type) { | ||
334 | *((u32 *) buf) = priv->common.rx_start; | ||
335 | err = p54u_bulk_msg(priv, P54U_PIPE_DATA, buf, sizeof(u32)); | ||
336 | if (err) { | ||
337 | printk(KERN_ERR "p54usb: addr send failed\n"); | ||
338 | goto fail; | ||
339 | } | ||
340 | } else { | ||
341 | struct net2280_reg_write *reg = buf; | ||
342 | reg->port = cpu_to_le16(NET2280_DEV_U32); | ||
343 | reg->addr = cpu_to_le32(P54U_DEV_BASE); | ||
344 | reg->val = cpu_to_le32(ISL38XX_DEV_INT_DATA); | ||
345 | err = p54u_bulk_msg(priv, P54U_PIPE_DEV, buf, sizeof(*reg)); | ||
346 | if (err) { | ||
347 | printk(KERN_ERR "p54usb: dev_int send failed\n"); | ||
348 | goto fail; | ||
349 | } | ||
350 | } | ||
351 | |||
352 | hdr = buf + priv->common.tx_hdr_len; | ||
353 | p54_fill_eeprom_readback(hdr); | ||
354 | hdr->req_id = cpu_to_le32(priv->common.rx_start); | ||
355 | if (priv->common.tx_hdr_len) { | ||
356 | struct net2280_tx_hdr *tx_hdr = buf; | ||
357 | tx_hdr->device_addr = hdr->req_id; | ||
358 | tx_hdr->len = cpu_to_le16(EEPROM_READBACK_LEN); | ||
359 | } | ||
360 | |||
361 | /* we can just pretend to send 0x2000 bytes of nothing in the headers */ | ||
362 | err = p54u_bulk_msg(priv, P54U_PIPE_DATA, buf, | ||
363 | EEPROM_READBACK_LEN + priv->common.tx_hdr_len); | ||
364 | if (err) { | ||
365 | printk(KERN_ERR "p54usb: eeprom req send failed\n"); | ||
366 | goto fail; | ||
367 | } | ||
368 | |||
369 | err = usb_bulk_msg(priv->udev, | ||
370 | usb_rcvbulkpipe(priv->udev, P54U_PIPE_DATA), | ||
371 | buf, 0x2020, &alen, 1000); | ||
372 | if (!err && alen > offset) { | ||
373 | p54_parse_eeprom(dev, (u8 *)buf + offset, alen - offset); | ||
374 | } else { | ||
375 | printk(KERN_ERR "p54usb: eeprom read failed!\n"); | ||
376 | err = -EINVAL; | ||
377 | goto fail; | ||
378 | } | ||
379 | |||
380 | fail: | ||
381 | kfree(buf); | ||
382 | return err; | ||
383 | } | ||
384 | |||
385 | static int p54u_upload_firmware_3887(struct ieee80211_hw *dev) | 318 | static int p54u_upload_firmware_3887(struct ieee80211_hw *dev) |
386 | { | 319 | { |
387 | static char start_string[] = "~~~~<\r"; | 320 | static char start_string[] = "~~~~<\r"; |
@@ -861,31 +794,20 @@ static int __devinit p54u_probe(struct usb_interface *intf, | |||
861 | if (err) | 794 | if (err) |
862 | goto err_free_dev; | 795 | goto err_free_dev; |
863 | 796 | ||
864 | err = p54u_read_eeprom(dev); | 797 | skb_queue_head_init(&priv->rx_queue); |
798 | |||
799 | p54u_open(dev); | ||
800 | err = p54_read_eeprom(dev); | ||
801 | p54u_stop(dev); | ||
865 | if (err) | 802 | if (err) |
866 | goto err_free_dev; | 803 | goto err_free_dev; |
867 | 804 | ||
868 | if (!is_valid_ether_addr(dev->wiphy->perm_addr)) { | ||
869 | u8 perm_addr[ETH_ALEN]; | ||
870 | |||
871 | printk(KERN_WARNING "p54usb: Invalid hwaddr! Using randomly generated MAC addr\n"); | ||
872 | random_ether_addr(perm_addr); | ||
873 | SET_IEEE80211_PERM_ADDR(dev, perm_addr); | ||
874 | } | ||
875 | |||
876 | skb_queue_head_init(&priv->rx_queue); | ||
877 | |||
878 | err = ieee80211_register_hw(dev); | 805 | err = ieee80211_register_hw(dev); |
879 | if (err) { | 806 | if (err) { |
880 | printk(KERN_ERR "p54usb: Cannot register netdevice\n"); | 807 | printk(KERN_ERR "p54usb: Cannot register netdevice\n"); |
881 | goto err_free_dev; | 808 | goto err_free_dev; |
882 | } | 809 | } |
883 | 810 | ||
884 | printk(KERN_INFO "%s: hwaddr %s, isl38%02x\n", | ||
885 | wiphy_name(dev->wiphy), | ||
886 | print_mac(mac, dev->wiphy->perm_addr), | ||
887 | priv->common.version); | ||
888 | |||
889 | return 0; | 811 | return 0; |
890 | 812 | ||
891 | err_free_dev: | 813 | err_free_dev: |