diff options
Diffstat (limited to 'drivers/net')
-rw-r--r-- | drivers/net/wireless/p54/p54.h | 6 | ||||
-rw-r--r-- | drivers/net/wireless/p54/p54common.c | 36 | ||||
-rw-r--r-- | drivers/net/wireless/p54/p54common.h | 11 | ||||
-rw-r--r-- | drivers/net/wireless/p54/p54pci.c | 23 | ||||
-rw-r--r-- | drivers/net/wireless/p54/p54usb.c | 20 |
5 files changed, 69 insertions, 27 deletions
diff --git a/drivers/net/wireless/p54/p54.h b/drivers/net/wireless/p54/p54.h index fca8762fa069..b03d13edc61f 100644 --- a/drivers/net/wireless/p54/p54.h +++ b/drivers/net/wireless/p54/p54.h | |||
@@ -39,7 +39,6 @@ struct p54_control_hdr { | |||
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 (sizeof(struct p54_control_hdr) + 4 /* p54_eeprom_lm86 */) |
42 | #define MAX_RX_SIZE (IEEE80211_MAX_RTS_THRESHOLD + sizeof(struct p54_control_hdr) + 20 /* length of struct p54_rx_hdr */ + 16 ) | ||
43 | 42 | ||
44 | #define ISL38XX_DEV_FIRMWARE_ADDR 0x20000 | 43 | #define ISL38XX_DEV_FIRMWARE_ADDR 0x20000 |
45 | 44 | ||
@@ -53,6 +52,9 @@ struct p54_common { | |||
53 | void (*stop)(struct ieee80211_hw *dev); | 52 | void (*stop)(struct ieee80211_hw *dev); |
54 | int mode; | 53 | int mode; |
55 | u16 seqno; | 54 | u16 seqno; |
55 | u16 rx_mtu; | ||
56 | u8 headroom; | ||
57 | u8 tailroom; | ||
56 | struct mutex conf_mutex; | 58 | struct mutex conf_mutex; |
57 | u8 mac_addr[ETH_ALEN]; | 59 | u8 mac_addr[ETH_ALEN]; |
58 | u8 bssid[ETH_ALEN]; | 60 | u8 bssid[ETH_ALEN]; |
@@ -70,7 +72,7 @@ struct p54_common { | |||
70 | }; | 72 | }; |
71 | 73 | ||
72 | int p54_rx(struct ieee80211_hw *dev, struct sk_buff *skb); | 74 | int p54_rx(struct ieee80211_hw *dev, struct sk_buff *skb); |
73 | void p54_parse_firmware(struct ieee80211_hw *dev, const struct firmware *fw); | 75 | int p54_parse_firmware(struct ieee80211_hw *dev, const struct firmware *fw); |
74 | int p54_parse_eeprom(struct ieee80211_hw *dev, void *eeprom, int len); | 76 | int p54_parse_eeprom(struct ieee80211_hw *dev, void *eeprom, int len); |
75 | void p54_fill_eeprom_readback(struct p54_control_hdr *hdr); | 77 | void p54_fill_eeprom_readback(struct p54_control_hdr *hdr); |
76 | struct ieee80211_hw *p54_init_common(size_t priv_data_len); | 78 | struct ieee80211_hw *p54_init_common(size_t priv_data_len); |
diff --git a/drivers/net/wireless/p54/p54common.c b/drivers/net/wireless/p54/p54common.c index 6da98e6e6a9a..fa61749b467b 100644 --- a/drivers/net/wireless/p54/p54common.c +++ b/drivers/net/wireless/p54/p54common.c | |||
@@ -66,8 +66,7 @@ static struct ieee80211_supported_band band_2GHz = { | |||
66 | .n_bitrates = ARRAY_SIZE(p54_rates), | 66 | .n_bitrates = ARRAY_SIZE(p54_rates), |
67 | }; | 67 | }; |
68 | 68 | ||
69 | 69 | int p54_parse_firmware(struct ieee80211_hw *dev, const struct firmware *fw) | |
70 | void p54_parse_firmware(struct ieee80211_hw *dev, const struct firmware *fw) | ||
71 | { | 70 | { |
72 | struct p54_common *priv = dev->priv; | 71 | struct p54_common *priv = dev->priv; |
73 | struct bootrec_exp_if *exp_if; | 72 | struct bootrec_exp_if *exp_if; |
@@ -79,7 +78,7 @@ void p54_parse_firmware(struct ieee80211_hw *dev, const struct firmware *fw) | |||
79 | int i; | 78 | int i; |
80 | 79 | ||
81 | if (priv->rx_start) | 80 | if (priv->rx_start) |
82 | return; | 81 | return 0; |
83 | 82 | ||
84 | while (data < end_data && *data) | 83 | while (data < end_data && *data) |
85 | data++; | 84 | data++; |
@@ -117,11 +116,22 @@ void p54_parse_firmware(struct ieee80211_hw *dev, const struct firmware *fw) | |||
117 | if (strnlen((unsigned char*)bootrec->data, 24) < 24) | 116 | if (strnlen((unsigned char*)bootrec->data, 24) < 24) |
118 | fw_version = (unsigned char*)bootrec->data; | 117 | fw_version = (unsigned char*)bootrec->data; |
119 | break; | 118 | break; |
120 | case BR_CODE_DESCR: | 119 | case BR_CODE_DESCR: { |
121 | priv->rx_start = le32_to_cpu(((__le32 *)bootrec->data)[1]); | 120 | struct bootrec_desc *desc = |
121 | (struct bootrec_desc *)bootrec->data; | ||
122 | priv->rx_start = le32_to_cpu(desc->rx_start); | ||
122 | /* FIXME add sanity checking */ | 123 | /* FIXME add sanity checking */ |
123 | priv->rx_end = le32_to_cpu(((__le32 *)bootrec->data)[2]) - 0x3500; | 124 | priv->rx_end = le32_to_cpu(desc->rx_end) - 0x3500; |
125 | priv->headroom = desc->headroom; | ||
126 | priv->tailroom = desc->tailroom; | ||
127 | if (bootrec->len == 11) | ||
128 | priv->rx_mtu = (size_t) le16_to_cpu( | ||
129 | (__le16)bootrec->data[10]); | ||
130 | else | ||
131 | priv->rx_mtu = (size_t) | ||
132 | 0x620 - priv->tx_hdr_len; | ||
124 | break; | 133 | break; |
134 | } | ||
125 | case BR_CODE_EXPOSED_IF: | 135 | case BR_CODE_EXPOSED_IF: |
126 | exp_if = (struct bootrec_exp_if *) bootrec->data; | 136 | exp_if = (struct bootrec_exp_if *) bootrec->data; |
127 | for (i = 0; i < (len * sizeof(*exp_if) / 4); i++) | 137 | for (i = 0; i < (len * sizeof(*exp_if) / 4); i++) |
@@ -152,6 +162,8 @@ void p54_parse_firmware(struct ieee80211_hw *dev, const struct firmware *fw) | |||
152 | priv->tx_stats[7].limit = 1; | 162 | priv->tx_stats[7].limit = 1; |
153 | dev->queues = 4; | 163 | dev->queues = 4; |
154 | } | 164 | } |
165 | |||
166 | return 0; | ||
155 | } | 167 | } |
156 | EXPORT_SYMBOL_GPL(p54_parse_firmware); | 168 | EXPORT_SYMBOL_GPL(p54_parse_firmware); |
157 | 169 | ||
@@ -428,7 +440,7 @@ static void p54_rx_frame_sent(struct ieee80211_hw *dev, struct sk_buff *skb) | |||
428 | struct p54_control_hdr *hdr = (struct p54_control_hdr *) skb->data; | 440 | struct p54_control_hdr *hdr = (struct p54_control_hdr *) skb->data; |
429 | struct p54_frame_sent_hdr *payload = (struct p54_frame_sent_hdr *) hdr->data; | 441 | struct p54_frame_sent_hdr *payload = (struct p54_frame_sent_hdr *) hdr->data; |
430 | struct sk_buff *entry = (struct sk_buff *) priv->tx_queue.next; | 442 | struct sk_buff *entry = (struct sk_buff *) priv->tx_queue.next; |
431 | u32 addr = le32_to_cpu(hdr->req_id) - 0x70; | 443 | u32 addr = le32_to_cpu(hdr->req_id) - priv->headroom; |
432 | struct memrecord *range = NULL; | 444 | struct memrecord *range = NULL; |
433 | u32 freed = 0; | 445 | u32 freed = 0; |
434 | u32 last_addr = priv->rx_start; | 446 | u32 last_addr = priv->rx_start; |
@@ -550,7 +562,7 @@ static void p54_assign_address(struct ieee80211_hw *dev, struct sk_buff *skb, | |||
550 | u32 target_addr = priv->rx_start; | 562 | u32 target_addr = priv->rx_start; |
551 | unsigned long flags; | 563 | unsigned long flags; |
552 | unsigned int left; | 564 | unsigned int left; |
553 | len = (len + 0x170 + 3) & ~0x3; /* 0x70 headroom, 0x100 tailroom */ | 565 | len = (len + priv->headroom + priv->tailroom + 3) & ~0x3; |
554 | 566 | ||
555 | spin_lock_irqsave(&priv->tx_queue.lock, flags); | 567 | spin_lock_irqsave(&priv->tx_queue.lock, flags); |
556 | left = skb_queue_len(&priv->tx_queue); | 568 | left = skb_queue_len(&priv->tx_queue); |
@@ -585,13 +597,14 @@ static void p54_assign_address(struct ieee80211_hw *dev, struct sk_buff *skb, | |||
585 | range->start_addr = target_addr; | 597 | range->start_addr = target_addr; |
586 | range->end_addr = target_addr + len; | 598 | range->end_addr = target_addr + len; |
587 | __skb_queue_after(&priv->tx_queue, target_skb, skb); | 599 | __skb_queue_after(&priv->tx_queue, target_skb, skb); |
588 | if (largest_hole < IEEE80211_MAX_RTS_THRESHOLD + 0x170 + | 600 | if (largest_hole < priv->rx_mtu + priv->headroom + |
601 | priv->tailroom + | ||
589 | sizeof(struct p54_control_hdr)) | 602 | sizeof(struct p54_control_hdr)) |
590 | ieee80211_stop_queues(dev); | 603 | ieee80211_stop_queues(dev); |
591 | } | 604 | } |
592 | spin_unlock_irqrestore(&priv->tx_queue.lock, flags); | 605 | spin_unlock_irqrestore(&priv->tx_queue.lock, flags); |
593 | 606 | ||
594 | data->req_id = cpu_to_le32(target_addr + 0x70); | 607 | data->req_id = cpu_to_le32(target_addr + priv->headroom); |
595 | } | 608 | } |
596 | 609 | ||
597 | static int p54_tx(struct ieee80211_hw *dev, struct sk_buff *skb) | 610 | static int p54_tx(struct ieee80211_hw *dev, struct sk_buff *skb) |
@@ -704,7 +717,7 @@ static int p54_set_filter(struct ieee80211_hw *dev, u16 filter_type, | |||
704 | filter->antenna = antenna; | 717 | filter->antenna = antenna; |
705 | filter->magic3 = cpu_to_le32(magic3); | 718 | filter->magic3 = cpu_to_le32(magic3); |
706 | filter->rx_addr = cpu_to_le32(priv->rx_end); | 719 | filter->rx_addr = cpu_to_le32(priv->rx_end); |
707 | filter->max_rx = cpu_to_le16(0x0620); /* FIXME: for usb ver 1.. maybe */ | 720 | filter->max_rx = cpu_to_le16(priv->rx_mtu); |
708 | filter->rxhw = priv->rxhw; | 721 | filter->rxhw = priv->rxhw; |
709 | filter->magic8 = cpu_to_le16(magic8); | 722 | filter->magic8 = cpu_to_le16(magic8); |
710 | filter->magic9 = cpu_to_le16(magic9); | 723 | filter->magic9 = cpu_to_le16(magic9); |
@@ -1084,7 +1097,6 @@ struct ieee80211_hw *p54_init_common(size_t priv_data_len) | |||
1084 | priv->tx_stats[3].limit = 1; | 1097 | priv->tx_stats[3].limit = 1; |
1085 | priv->tx_stats[4].limit = 5; | 1098 | priv->tx_stats[4].limit = 5; |
1086 | dev->queues = 1; | 1099 | dev->queues = 1; |
1087 | |||
1088 | dev->extra_tx_headroom = sizeof(struct p54_control_hdr) + 4 + | 1100 | dev->extra_tx_headroom = sizeof(struct p54_control_hdr) + 4 + |
1089 | sizeof(struct p54_tx_control_allocdata); | 1101 | sizeof(struct p54_tx_control_allocdata); |
1090 | 1102 | ||
diff --git a/drivers/net/wireless/p54/p54common.h b/drivers/net/wireless/p54/p54common.h index a79c1a146917..5f2af5152505 100644 --- a/drivers/net/wireless/p54/p54common.h +++ b/drivers/net/wireless/p54/p54common.h | |||
@@ -29,6 +29,17 @@ struct bootrec_exp_if { | |||
29 | __le16 top_compat; | 29 | __le16 top_compat; |
30 | } __attribute__((packed)); | 30 | } __attribute__((packed)); |
31 | 31 | ||
32 | struct bootrec_desc { | ||
33 | __le16 modes; | ||
34 | __le16 flags; | ||
35 | __le32 rx_start; | ||
36 | __le32 rx_end; | ||
37 | u8 headroom; | ||
38 | u8 tailroom; | ||
39 | u8 unimportant[6]; | ||
40 | u8 rates[16]; | ||
41 | } __attribute__((packed)); | ||
42 | |||
32 | #define BR_CODE_MIN 0x80000000 | 43 | #define BR_CODE_MIN 0x80000000 |
33 | #define BR_CODE_COMPONENT_ID 0x80000001 | 44 | #define BR_CODE_COMPONENT_ID 0x80000001 |
34 | #define BR_CODE_COMPONENT_VERSION 0x80000002 | 45 | #define BR_CODE_COMPONENT_VERSION 0x80000002 |
diff --git a/drivers/net/wireless/p54/p54pci.c b/drivers/net/wireless/p54/p54pci.c index a0395af74c2d..fdfc7189f0ff 100644 --- a/drivers/net/wireless/p54/p54pci.c +++ b/drivers/net/wireless/p54/p54pci.c | |||
@@ -81,7 +81,11 @@ static int p54p_upload_firmware(struct ieee80211_hw *dev) | |||
81 | return err; | 81 | return err; |
82 | } | 82 | } |
83 | 83 | ||
84 | p54_parse_firmware(dev, fw_entry); | 84 | err = p54_parse_firmware(dev, fw_entry); |
85 | if (err) { | ||
86 | release_firmware(fw_entry); | ||
87 | return err; | ||
88 | } | ||
85 | 89 | ||
86 | data = (__le32 *) fw_entry->data; | 90 | data = (__le32 *) fw_entry->data; |
87 | remains = fw_entry->size; | 91 | remains = fw_entry->size; |
@@ -258,17 +262,17 @@ static void p54p_refill_rx_ring(struct ieee80211_hw *dev, | |||
258 | if (!desc->host_addr) { | 262 | if (!desc->host_addr) { |
259 | struct sk_buff *skb; | 263 | struct sk_buff *skb; |
260 | dma_addr_t mapping; | 264 | dma_addr_t mapping; |
261 | skb = dev_alloc_skb(MAX_RX_SIZE); | 265 | skb = dev_alloc_skb(priv->common.rx_mtu + 32); |
262 | if (!skb) | 266 | if (!skb) |
263 | break; | 267 | break; |
264 | 268 | ||
265 | mapping = pci_map_single(priv->pdev, | 269 | mapping = pci_map_single(priv->pdev, |
266 | skb_tail_pointer(skb), | 270 | skb_tail_pointer(skb), |
267 | MAX_RX_SIZE, | 271 | priv->common.rx_mtu + 32, |
268 | PCI_DMA_FROMDEVICE); | 272 | PCI_DMA_FROMDEVICE); |
269 | desc->host_addr = cpu_to_le32(mapping); | 273 | desc->host_addr = cpu_to_le32(mapping); |
270 | desc->device_addr = 0; // FIXME: necessary? | 274 | desc->device_addr = 0; // FIXME: necessary? |
271 | desc->len = cpu_to_le16(MAX_RX_SIZE); | 275 | desc->len = cpu_to_le16(priv->common.rx_mtu + 32); |
272 | desc->flags = 0; | 276 | desc->flags = 0; |
273 | rx_buf[i] = skb; | 277 | rx_buf[i] = skb; |
274 | } | 278 | } |
@@ -311,12 +315,13 @@ static void p54p_check_rx_ring(struct ieee80211_hw *dev, u32 *index, | |||
311 | if (p54_rx(dev, skb)) { | 315 | if (p54_rx(dev, skb)) { |
312 | pci_unmap_single(priv->pdev, | 316 | pci_unmap_single(priv->pdev, |
313 | le32_to_cpu(desc->host_addr), | 317 | le32_to_cpu(desc->host_addr), |
314 | MAX_RX_SIZE, PCI_DMA_FROMDEVICE); | 318 | priv->common.rx_mtu + 32, |
319 | PCI_DMA_FROMDEVICE); | ||
315 | rx_buf[i] = NULL; | 320 | rx_buf[i] = NULL; |
316 | desc->host_addr = 0; | 321 | desc->host_addr = 0; |
317 | } else { | 322 | } else { |
318 | skb_trim(skb, 0); | 323 | skb_trim(skb, 0); |
319 | desc->len = cpu_to_le16(MAX_RX_SIZE); | 324 | desc->len = cpu_to_le16(priv->common.rx_mtu + 32); |
320 | } | 325 | } |
321 | 326 | ||
322 | i++; | 327 | i++; |
@@ -534,7 +539,8 @@ static void p54p_stop(struct ieee80211_hw *dev) | |||
534 | if (desc->host_addr) | 539 | if (desc->host_addr) |
535 | pci_unmap_single(priv->pdev, | 540 | pci_unmap_single(priv->pdev, |
536 | le32_to_cpu(desc->host_addr), | 541 | le32_to_cpu(desc->host_addr), |
537 | MAX_RX_SIZE, PCI_DMA_FROMDEVICE); | 542 | priv->common.rx_mtu + 32, |
543 | PCI_DMA_FROMDEVICE); | ||
538 | kfree_skb(priv->rx_buf_data[i]); | 544 | kfree_skb(priv->rx_buf_data[i]); |
539 | priv->rx_buf_data[i] = NULL; | 545 | priv->rx_buf_data[i] = NULL; |
540 | } | 546 | } |
@@ -544,7 +550,8 @@ static void p54p_stop(struct ieee80211_hw *dev) | |||
544 | if (desc->host_addr) | 550 | if (desc->host_addr) |
545 | pci_unmap_single(priv->pdev, | 551 | pci_unmap_single(priv->pdev, |
546 | le32_to_cpu(desc->host_addr), | 552 | le32_to_cpu(desc->host_addr), |
547 | MAX_RX_SIZE, PCI_DMA_FROMDEVICE); | 553 | priv->common.rx_mtu + 32, |
554 | PCI_DMA_FROMDEVICE); | ||
548 | kfree_skb(priv->rx_buf_mgmt[i]); | 555 | kfree_skb(priv->rx_buf_mgmt[i]); |
549 | priv->rx_buf_mgmt[i] = NULL; | 556 | priv->rx_buf_mgmt[i] = NULL; |
550 | } | 557 | } |
diff --git a/drivers/net/wireless/p54/p54usb.c b/drivers/net/wireless/p54/p54usb.c index 8a420df605af..4dca209a6e07 100644 --- a/drivers/net/wireless/p54/p54usb.c +++ b/drivers/net/wireless/p54/p54usb.c | |||
@@ -95,7 +95,7 @@ static void p54u_rx_cb(struct urb *urb) | |||
95 | skb_pull(skb, sizeof(struct net2280_tx_hdr)); | 95 | skb_pull(skb, sizeof(struct net2280_tx_hdr)); |
96 | 96 | ||
97 | if (p54_rx(dev, skb)) { | 97 | if (p54_rx(dev, skb)) { |
98 | skb = dev_alloc_skb(MAX_RX_SIZE); | 98 | skb = dev_alloc_skb(priv->common.rx_mtu + 32); |
99 | if (unlikely(!skb)) { | 99 | if (unlikely(!skb)) { |
100 | usb_free_urb(urb); | 100 | usb_free_urb(urb); |
101 | /* TODO check rx queue length and refill *somewhere* */ | 101 | /* TODO check rx queue length and refill *somewhere* */ |
@@ -145,7 +145,7 @@ static int p54u_init_urbs(struct ieee80211_hw *dev) | |||
145 | struct p54u_rx_info *info; | 145 | struct p54u_rx_info *info; |
146 | 146 | ||
147 | while (skb_queue_len(&priv->rx_queue) < 32) { | 147 | while (skb_queue_len(&priv->rx_queue) < 32) { |
148 | skb = __dev_alloc_skb(MAX_RX_SIZE, GFP_KERNEL); | 148 | skb = __dev_alloc_skb(priv->common.rx_mtu + 32, GFP_KERNEL); |
149 | if (!skb) | 149 | if (!skb) |
150 | break; | 150 | break; |
151 | entry = usb_alloc_urb(0, GFP_KERNEL); | 151 | entry = usb_alloc_urb(0, GFP_KERNEL); |
@@ -153,7 +153,10 @@ static int p54u_init_urbs(struct ieee80211_hw *dev) | |||
153 | kfree_skb(skb); | 153 | kfree_skb(skb); |
154 | break; | 154 | break; |
155 | } | 155 | } |
156 | usb_fill_bulk_urb(entry, priv->udev, usb_rcvbulkpipe(priv->udev, P54U_PIPE_DATA), skb_tail_pointer(skb), MAX_RX_SIZE, p54u_rx_cb, skb); | 156 | usb_fill_bulk_urb(entry, priv->udev, |
157 | usb_rcvbulkpipe(priv->udev, P54U_PIPE_DATA), | ||
158 | skb_tail_pointer(skb), | ||
159 | priv->common.rx_mtu + 32, p54u_rx_cb, skb); | ||
157 | info = (struct p54u_rx_info *) skb->cb; | 160 | info = (struct p54u_rx_info *) skb->cb; |
158 | info->urb = entry; | 161 | info->urb = entry; |
159 | info->dev = dev; | 162 | info->dev = dev; |
@@ -412,7 +415,9 @@ static int p54u_upload_firmware_3887(struct ieee80211_hw *dev) | |||
412 | goto err_req_fw_failed; | 415 | goto err_req_fw_failed; |
413 | } | 416 | } |
414 | 417 | ||
415 | p54_parse_firmware(dev, fw_entry); | 418 | err = p54_parse_firmware(dev, fw_entry); |
419 | if (err) | ||
420 | goto err_upload_failed; | ||
416 | 421 | ||
417 | left = block_size = min((size_t)P54U_FW_BLOCK, fw_entry->size); | 422 | left = block_size = min((size_t)P54U_FW_BLOCK, fw_entry->size); |
418 | strcpy(buf, start_string); | 423 | strcpy(buf, start_string); |
@@ -549,7 +554,12 @@ static int p54u_upload_firmware_net2280(struct ieee80211_hw *dev) | |||
549 | return err; | 554 | return err; |
550 | } | 555 | } |
551 | 556 | ||
552 | p54_parse_firmware(dev, fw_entry); | 557 | err = p54_parse_firmware(dev, fw_entry); |
558 | if (err) { | ||
559 | kfree(buf); | ||
560 | release_firmware(fw_entry); | ||
561 | return err; | ||
562 | } | ||
553 | 563 | ||
554 | #define P54U_WRITE(type, addr, data) \ | 564 | #define P54U_WRITE(type, addr, data) \ |
555 | do {\ | 565 | do {\ |