diff options
author | Luciano Coelho <coelho@ti.com> | 2011-03-10 08:24:57 -0500 |
---|---|---|
committer | Luciano Coelho <coelho@ti.com> | 2011-04-19 09:49:03 -0400 |
commit | e7ddf549f3f2da156f5c12921e6699024e80a3f4 (patch) | |
tree | df8f0e4d2ac9e23ec96117ffca35517a3cd94ac6 /drivers | |
parent | 0830ceedbfde20c9110c59597fdffbf51886565a (diff) |
wl12xx: use 1 spare TX block instead of two
All the new firmware versions (>=6.1.3.50.58 for STA and >=6.2.0.0.47
for AP) use 1 spare TX block. We still want to support older
firmwares that require 2 spare blocks, so added a quirk to handle the
difference.
Also implemented a generic way of setting quirks that depend on the
firmware revision.
Signed-off-by: Luciano Coelho <coelho@ti.com>
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/net/wireless/wl12xx/main.c | 24 | ||||
-rw-r--r-- | drivers/net/wireless/wl12xx/tx.c | 10 | ||||
-rw-r--r-- | drivers/net/wireless/wl12xx/tx.h | 1 | ||||
-rw-r--r-- | drivers/net/wireless/wl12xx/wl12xx.h | 28 |
4 files changed, 57 insertions, 6 deletions
diff --git a/drivers/net/wireless/wl12xx/main.c b/drivers/net/wireless/wl12xx/main.c index 0b9d41f14b28..db7ab856363e 100644 --- a/drivers/net/wireless/wl12xx/main.c +++ b/drivers/net/wireless/wl12xx/main.c | |||
@@ -1040,6 +1040,24 @@ out: | |||
1040 | return ret; | 1040 | return ret; |
1041 | } | 1041 | } |
1042 | 1042 | ||
1043 | static unsigned int wl1271_get_fw_ver_quirks(struct wl1271 *wl) | ||
1044 | { | ||
1045 | unsigned int quirks = 0; | ||
1046 | unsigned int *fw_ver = wl->chip.fw_ver; | ||
1047 | |||
1048 | /* Only for wl127x */ | ||
1049 | if ((fw_ver[FW_VER_CHIP] == FW_VER_CHIP_WL127X) && | ||
1050 | /* Check STA version */ | ||
1051 | (((fw_ver[FW_VER_IF_TYPE] == FW_VER_IF_TYPE_STA) && | ||
1052 | (fw_ver[FW_VER_MINOR] < FW_VER_MINOR_1_SPARE_STA_MIN)) || | ||
1053 | /* Check AP version */ | ||
1054 | ((fw_ver[FW_VER_IF_TYPE] == FW_VER_IF_TYPE_AP) && | ||
1055 | (fw_ver[FW_VER_MINOR] < FW_VER_MINOR_1_SPARE_AP_MIN)))) | ||
1056 | quirks |= WL12XX_QUIRK_USE_2_SPARE_BLOCKS; | ||
1057 | |||
1058 | return quirks; | ||
1059 | } | ||
1060 | |||
1043 | int wl1271_plt_start(struct wl1271 *wl) | 1061 | int wl1271_plt_start(struct wl1271 *wl) |
1044 | { | 1062 | { |
1045 | int retries = WL1271_BOOT_RETRIES; | 1063 | int retries = WL1271_BOOT_RETRIES; |
@@ -1075,6 +1093,9 @@ int wl1271_plt_start(struct wl1271 *wl) | |||
1075 | wl->state = WL1271_STATE_PLT; | 1093 | wl->state = WL1271_STATE_PLT; |
1076 | wl1271_notice("firmware booted in PLT mode (%s)", | 1094 | wl1271_notice("firmware booted in PLT mode (%s)", |
1077 | wl->chip.fw_ver_str); | 1095 | wl->chip.fw_ver_str); |
1096 | |||
1097 | /* Check if any quirks are needed with older fw versions */ | ||
1098 | wl->quirks |= wl1271_get_fw_ver_quirks(wl); | ||
1078 | goto out; | 1099 | goto out; |
1079 | 1100 | ||
1080 | irq_disable: | 1101 | irq_disable: |
@@ -1353,6 +1374,9 @@ power_off: | |||
1353 | strncpy(wiphy->fw_version, wl->chip.fw_ver_str, | 1374 | strncpy(wiphy->fw_version, wl->chip.fw_ver_str, |
1354 | sizeof(wiphy->fw_version)); | 1375 | sizeof(wiphy->fw_version)); |
1355 | 1376 | ||
1377 | /* Check if any quirks are needed with older fw versions */ | ||
1378 | wl->quirks |= wl1271_get_fw_ver_quirks(wl); | ||
1379 | |||
1356 | /* | 1380 | /* |
1357 | * Now we know if 11a is supported (info from the NVS), so disable | 1381 | * Now we know if 11a is supported (info from the NVS), so disable |
1358 | * 11a channels if not supported | 1382 | * 11a channels if not supported |
diff --git a/drivers/net/wireless/wl12xx/tx.c b/drivers/net/wireless/wl12xx/tx.c index 75222a681296..109878c3246e 100644 --- a/drivers/net/wireless/wl12xx/tx.c +++ b/drivers/net/wireless/wl12xx/tx.c | |||
@@ -135,6 +135,12 @@ static int wl1271_tx_allocate(struct wl1271 *wl, struct sk_buff *skb, u32 extra, | |||
135 | u32 len; | 135 | u32 len; |
136 | u32 total_blocks; | 136 | u32 total_blocks; |
137 | int id, ret = -EBUSY; | 137 | int id, ret = -EBUSY; |
138 | u32 spare_blocks; | ||
139 | |||
140 | if (unlikely(wl->quirks & WL12XX_QUIRK_USE_2_SPARE_BLOCKS)) | ||
141 | spare_blocks = 2; | ||
142 | else | ||
143 | spare_blocks = 1; | ||
138 | 144 | ||
139 | if (buf_offset + total_len > WL1271_AGGR_BUFFER_SIZE) | 145 | if (buf_offset + total_len > WL1271_AGGR_BUFFER_SIZE) |
140 | return -EAGAIN; | 146 | return -EAGAIN; |
@@ -152,7 +158,7 @@ static int wl1271_tx_allocate(struct wl1271 *wl, struct sk_buff *skb, u32 extra, | |||
152 | len = total_len; | 158 | len = total_len; |
153 | 159 | ||
154 | total_blocks = (len + TX_HW_BLOCK_SIZE - 1) / TX_HW_BLOCK_SIZE + | 160 | total_blocks = (len + TX_HW_BLOCK_SIZE - 1) / TX_HW_BLOCK_SIZE + |
155 | TX_HW_BLOCK_SPARE; | 161 | spare_blocks; |
156 | 162 | ||
157 | if (total_blocks <= wl->tx_blocks_available) { | 163 | if (total_blocks <= wl->tx_blocks_available) { |
158 | desc = (struct wl1271_tx_hw_descr *)skb_push( | 164 | desc = (struct wl1271_tx_hw_descr *)skb_push( |
@@ -162,7 +168,7 @@ static int wl1271_tx_allocate(struct wl1271 *wl, struct sk_buff *skb, u32 extra, | |||
162 | if (wl->chip.id == CHIP_ID_1283_PG20) { | 168 | if (wl->chip.id == CHIP_ID_1283_PG20) { |
163 | desc->wl128x_mem.total_mem_blocks = total_blocks; | 169 | desc->wl128x_mem.total_mem_blocks = total_blocks; |
164 | } else { | 170 | } else { |
165 | desc->wl127x_mem.extra_blocks = TX_HW_BLOCK_SPARE; | 171 | desc->wl127x_mem.extra_blocks = spare_blocks; |
166 | desc->wl127x_mem.total_mem_blocks = total_blocks; | 172 | desc->wl127x_mem.total_mem_blocks = total_blocks; |
167 | } | 173 | } |
168 | 174 | ||
diff --git a/drivers/net/wireless/wl12xx/tx.h b/drivers/net/wireless/wl12xx/tx.h index 6f45e9108d9a..a3877ba32d37 100644 --- a/drivers/net/wireless/wl12xx/tx.h +++ b/drivers/net/wireless/wl12xx/tx.h | |||
@@ -25,7 +25,6 @@ | |||
25 | #ifndef __TX_H__ | 25 | #ifndef __TX_H__ |
26 | #define __TX_H__ | 26 | #define __TX_H__ |
27 | 27 | ||
28 | #define TX_HW_BLOCK_SPARE 2 | ||
29 | #define TX_HW_BLOCK_SIZE 252 | 28 | #define TX_HW_BLOCK_SIZE 252 |
30 | 29 | ||
31 | #define TX_HW_MGMT_PKT_LIFETIME_TU 2000 | 30 | #define TX_HW_MGMT_PKT_LIFETIME_TU 2000 |
diff --git a/drivers/net/wireless/wl12xx/wl12xx.h b/drivers/net/wireless/wl12xx/wl12xx.h index 890c1a54382d..b04481aadf9c 100644 --- a/drivers/net/wireless/wl12xx/wl12xx.h +++ b/drivers/net/wireless/wl12xx/wl12xx.h | |||
@@ -207,13 +207,29 @@ struct wl1271_partition_set { | |||
207 | 207 | ||
208 | struct wl1271; | 208 | struct wl1271; |
209 | 209 | ||
210 | #define WL12XX_NUM_FW_VER 5 | 210 | enum { |
211 | FW_VER_CHIP, | ||
212 | FW_VER_IF_TYPE, | ||
213 | FW_VER_MAJOR, | ||
214 | FW_VER_SUBTYPE, | ||
215 | FW_VER_MINOR, | ||
216 | |||
217 | NUM_FW_VER | ||
218 | }; | ||
219 | |||
220 | #define FW_VER_CHIP_WL127X 6 | ||
221 | #define FW_VER_CHIP_WL128X 7 | ||
222 | |||
223 | #define FW_VER_IF_TYPE_STA 1 | ||
224 | #define FW_VER_IF_TYPE_AP 2 | ||
225 | |||
226 | #define FW_VER_MINOR_1_SPARE_STA_MIN 58 | ||
227 | #define FW_VER_MINOR_1_SPARE_AP_MIN 47 | ||
211 | 228 | ||
212 | /* FIXME: I'm not sure about this structure name */ | ||
213 | struct wl1271_chip { | 229 | struct wl1271_chip { |
214 | u32 id; | 230 | u32 id; |
215 | char fw_ver_str[ETHTOOL_BUSINFO_LEN]; | 231 | char fw_ver_str[ETHTOOL_BUSINFO_LEN]; |
216 | unsigned int fw_ver[WL12XX_NUM_FW_VER]; | 232 | unsigned int fw_ver[NUM_FW_VER]; |
217 | }; | 233 | }; |
218 | 234 | ||
219 | struct wl1271_stats { | 235 | struct wl1271_stats { |
@@ -594,4 +610,10 @@ int wl1271_plt_stop(struct wl1271 *wl); | |||
594 | /* Each RX/TX transaction requires an end-of-transaction transfer */ | 610 | /* Each RX/TX transaction requires an end-of-transaction transfer */ |
595 | #define WL12XX_QUIRK_END_OF_TRANSACTION BIT(0) | 611 | #define WL12XX_QUIRK_END_OF_TRANSACTION BIT(0) |
596 | 612 | ||
613 | /* | ||
614 | * Older firmwares use 2 spare TX blocks | ||
615 | * (for STA < 6.1.3.50.58 or for AP < 6.2.0.0.47) | ||
616 | */ | ||
617 | #define WL12XX_QUIRK_USE_2_SPARE_BLOCKS BIT(1) | ||
618 | |||
597 | #endif | 619 | #endif |