diff options
author | Christian Lamparter <chunkeey@web.de> | 2008-09-01 16:48:41 -0400 |
---|---|---|
committer | John W. Linville <linville@tuxdriver.com> | 2008-09-05 16:17:47 -0400 |
commit | 4e416a6f49b710bfe162f0cb24bc68c74493d2a0 (patch) | |
tree | 76e4a5e4a7e1cd65b142d841e5134404f970a99d /drivers/net/wireless/p54/p54common.c | |
parent | 0c25970dc1b0d46f2357e7c4b267ab7b93eb7cdd (diff) |
p54: enhance firmware parser to reduce memory waste
This patch greatly reduces one of biggest memory waste in the driver.
The firmware headers provides the right values for extra head-/tailroom
and mtu size which are usually much lower than the old hardcoded ones.
Signed-off-by: Christian Lamparter <chunkeey@web.de>
Signed-off-by: John W. Linville <linville@tuxdriver.com>
Diffstat (limited to 'drivers/net/wireless/p54/p54common.c')
-rw-r--r-- | drivers/net/wireless/p54/p54common.c | 36 |
1 files changed, 24 insertions, 12 deletions
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 | ||