diff options
author | Arik Nemtsov <arik@wizery.com> | 2012-05-18 00:46:37 -0400 |
---|---|---|
committer | Luciano Coelho <coelho@ti.com> | 2012-06-06 12:28:05 -0400 |
commit | 32bb2c03f990d015c0fec67e9134ea8625aaf784 (patch) | |
tree | 625379f953c7b11754f6d5ee09023fc1ad04d939 /drivers | |
parent | 2c0133a437905591cdaa39cf65a3f7188d20a094 (diff) |
wlcore/wl12xx/wl18xx: handle spare blocks spacial cases per arch
Add a HW op for getting spare blocks.
12xx cards require 2 spare blocks for GEM encrypted SKBs, regardless
of VIFs or keys programmed into the FW.
18xx cards require 2 spare blocks when there are any connected TKIP or
GEM VIFs. For now always return 2 spare blocks, as this works with all
networks. The special case TKIP/GEM functionality is added at a later
patch.
Signed-off-by: Arik Nemtsov <arik@wizery.com>
Signed-off-by: Luciano Coelho <coelho@ti.com>
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/net/wireless/ti/wl12xx/main.c | 11 | ||||
-rw-r--r-- | drivers/net/wireless/ti/wl18xx/main.c | 11 | ||||
-rw-r--r-- | drivers/net/wireless/ti/wl18xx/tx.h | 3 | ||||
-rw-r--r-- | drivers/net/wireless/ti/wlcore/debugfs.c | 1 | ||||
-rw-r--r-- | drivers/net/wireless/ti/wlcore/hw_ops.h | 9 | ||||
-rw-r--r-- | drivers/net/wireless/ti/wlcore/main.c | 11 | ||||
-rw-r--r-- | drivers/net/wireless/ti/wlcore/tx.c | 20 | ||||
-rw-r--r-- | drivers/net/wireless/ti/wlcore/wlcore.h | 5 | ||||
-rw-r--r-- | drivers/net/wireless/ti/wlcore/wlcore_i.h | 3 |
9 files changed, 39 insertions, 35 deletions
diff --git a/drivers/net/wireless/ti/wl12xx/main.c b/drivers/net/wireless/ti/wl12xx/main.c index d33117efec79..03ff1ce56bb4 100644 --- a/drivers/net/wireless/ti/wl12xx/main.c +++ b/drivers/net/wireless/ti/wl12xx/main.c | |||
@@ -1361,6 +1361,14 @@ out: | |||
1361 | return ret; | 1361 | return ret; |
1362 | } | 1362 | } |
1363 | 1363 | ||
1364 | static int wl12xx_get_spare_blocks(struct wl1271 *wl, bool is_gem) | ||
1365 | { | ||
1366 | if (is_gem) | ||
1367 | return WL12XX_TX_HW_BLOCK_GEM_SPARE; | ||
1368 | |||
1369 | return WL12XX_TX_HW_BLOCK_SPARE_DEFAULT; | ||
1370 | } | ||
1371 | |||
1364 | static struct wlcore_ops wl12xx_ops = { | 1372 | static struct wlcore_ops wl12xx_ops = { |
1365 | .identify_chip = wl12xx_identify_chip, | 1373 | .identify_chip = wl12xx_identify_chip, |
1366 | .identify_fw = wl12xx_identify_fw, | 1374 | .identify_fw = wl12xx_identify_fw, |
@@ -1384,6 +1392,7 @@ static struct wlcore_ops wl12xx_ops = { | |||
1384 | .set_rx_csum = NULL, | 1392 | .set_rx_csum = NULL, |
1385 | .ap_get_mimo_wide_rate_mask = NULL, | 1393 | .ap_get_mimo_wide_rate_mask = NULL, |
1386 | .debugfs_init = wl12xx_debugfs_add_files, | 1394 | .debugfs_init = wl12xx_debugfs_add_files, |
1395 | .get_spare_blocks = wl12xx_get_spare_blocks, | ||
1387 | }; | 1396 | }; |
1388 | 1397 | ||
1389 | static struct ieee80211_sta_ht_cap wl12xx_ht_cap = { | 1398 | static struct ieee80211_sta_ht_cap wl12xx_ht_cap = { |
@@ -1419,8 +1428,6 @@ static int __devinit wl12xx_probe(struct platform_device *pdev) | |||
1419 | wl->rtable = wl12xx_rtable; | 1428 | wl->rtable = wl12xx_rtable; |
1420 | wl->num_tx_desc = 16; | 1429 | wl->num_tx_desc = 16; |
1421 | wl->num_rx_desc = 8; | 1430 | wl->num_rx_desc = 8; |
1422 | wl->normal_tx_spare = WL12XX_TX_HW_BLOCK_SPARE_DEFAULT; | ||
1423 | wl->gem_tx_spare = WL12XX_TX_HW_BLOCK_GEM_SPARE; | ||
1424 | wl->band_rate_to_idx = wl12xx_band_rate_to_idx; | 1431 | wl->band_rate_to_idx = wl12xx_band_rate_to_idx; |
1425 | wl->hw_tx_rate_tbl_size = WL12XX_CONF_HW_RXTX_RATE_MAX; | 1432 | wl->hw_tx_rate_tbl_size = WL12XX_CONF_HW_RXTX_RATE_MAX; |
1426 | wl->hw_min_ht_rate = WL12XX_CONF_HW_RXTX_RATE_MCS0; | 1433 | wl->hw_min_ht_rate = WL12XX_CONF_HW_RXTX_RATE_MCS0; |
diff --git a/drivers/net/wireless/ti/wl18xx/main.c b/drivers/net/wireless/ti/wl18xx/main.c index d67be3eae3d9..c651f872d7d5 100644 --- a/drivers/net/wireless/ti/wl18xx/main.c +++ b/drivers/net/wireless/ti/wl18xx/main.c | |||
@@ -874,7 +874,7 @@ static int wl18xx_hw_init(struct wl1271 *wl) | |||
874 | 874 | ||
875 | ret = wl18xx_acx_host_if_cfg_bitmap(wl, host_cfg_bitmap, | 875 | ret = wl18xx_acx_host_if_cfg_bitmap(wl, host_cfg_bitmap, |
876 | sdio_align_size, | 876 | sdio_align_size, |
877 | WL18XX_TX_HW_BLOCK_SPARE, | 877 | WL18XX_TX_HW_EXTRA_BLOCK_SPARE, |
878 | WL18XX_HOST_IF_LEN_SIZE_FIELD); | 878 | WL18XX_HOST_IF_LEN_SIZE_FIELD); |
879 | if (ret < 0) | 879 | if (ret < 0) |
880 | return ret; | 880 | return ret; |
@@ -1034,6 +1034,12 @@ static int wl18xx_handle_static_data(struct wl1271 *wl, | |||
1034 | return 0; | 1034 | return 0; |
1035 | } | 1035 | } |
1036 | 1036 | ||
1037 | static int wl18xx_get_spare_blocks(struct wl1271 *wl, bool is_gem) | ||
1038 | { | ||
1039 | /* TODO: dynamically change to extra only when we have GEM or TKIP */ | ||
1040 | return WL18XX_TX_HW_EXTRA_BLOCK_SPARE; | ||
1041 | } | ||
1042 | |||
1037 | static struct wlcore_ops wl18xx_ops = { | 1043 | static struct wlcore_ops wl18xx_ops = { |
1038 | .identify_chip = wl18xx_identify_chip, | 1044 | .identify_chip = wl18xx_identify_chip, |
1039 | .boot = wl18xx_boot, | 1045 | .boot = wl18xx_boot, |
@@ -1056,6 +1062,7 @@ static struct wlcore_ops wl18xx_ops = { | |||
1056 | .get_mac = wl18xx_get_mac, | 1062 | .get_mac = wl18xx_get_mac, |
1057 | .debugfs_init = wl18xx_debugfs_add_files, | 1063 | .debugfs_init = wl18xx_debugfs_add_files, |
1058 | .handle_static_data = wl18xx_handle_static_data, | 1064 | .handle_static_data = wl18xx_handle_static_data, |
1065 | .get_spare_blocks = wl18xx_get_spare_blocks, | ||
1059 | }; | 1066 | }; |
1060 | 1067 | ||
1061 | /* HT cap appropriate for wide channels */ | 1068 | /* HT cap appropriate for wide channels */ |
@@ -1129,8 +1136,6 @@ static int __devinit wl18xx_probe(struct platform_device *pdev) | |||
1129 | wl->rtable = wl18xx_rtable; | 1136 | wl->rtable = wl18xx_rtable; |
1130 | wl->num_tx_desc = 32; | 1137 | wl->num_tx_desc = 32; |
1131 | wl->num_rx_desc = 16; | 1138 | wl->num_rx_desc = 16; |
1132 | wl->normal_tx_spare = WL18XX_TX_HW_BLOCK_SPARE; | ||
1133 | wl->gem_tx_spare = WL18XX_TX_HW_GEM_BLOCK_SPARE; | ||
1134 | wl->band_rate_to_idx = wl18xx_band_rate_to_idx; | 1139 | wl->band_rate_to_idx = wl18xx_band_rate_to_idx; |
1135 | wl->hw_tx_rate_tbl_size = WL18XX_CONF_HW_RXTX_RATE_MAX; | 1140 | wl->hw_tx_rate_tbl_size = WL18XX_CONF_HW_RXTX_RATE_MAX; |
1136 | wl->hw_min_ht_rate = WL18XX_CONF_HW_RXTX_RATE_MCS0; | 1141 | wl->hw_min_ht_rate = WL18XX_CONF_HW_RXTX_RATE_MCS0; |
diff --git a/drivers/net/wireless/ti/wl18xx/tx.h b/drivers/net/wireless/ti/wl18xx/tx.h index 2417262de207..8aecaf09da9c 100644 --- a/drivers/net/wireless/ti/wl18xx/tx.h +++ b/drivers/net/wireless/ti/wl18xx/tx.h | |||
@@ -25,7 +25,8 @@ | |||
25 | #include "../wlcore/wlcore.h" | 25 | #include "../wlcore/wlcore.h" |
26 | 26 | ||
27 | #define WL18XX_TX_HW_BLOCK_SPARE 1 | 27 | #define WL18XX_TX_HW_BLOCK_SPARE 1 |
28 | #define WL18XX_TX_HW_GEM_BLOCK_SPARE 2 | 28 | /* for special cases - namely, TKIP and GEM */ |
29 | #define WL18XX_TX_HW_EXTRA_BLOCK_SPARE 2 | ||
29 | #define WL18XX_TX_HW_BLOCK_SIZE 268 | 30 | #define WL18XX_TX_HW_BLOCK_SIZE 268 |
30 | 31 | ||
31 | #define WL18XX_TX_STATUS_DESC_ID_MASK 0x7F | 32 | #define WL18XX_TX_STATUS_DESC_ID_MASK 0x7F |
diff --git a/drivers/net/wireless/ti/wlcore/debugfs.c b/drivers/net/wireless/ti/wlcore/debugfs.c index fc44262e4cf0..fcd60636e9d1 100644 --- a/drivers/net/wireless/ti/wlcore/debugfs.c +++ b/drivers/net/wireless/ti/wlcore/debugfs.c | |||
@@ -507,7 +507,6 @@ static ssize_t vifs_state_read(struct file *file, char __user *user_buf, | |||
507 | VIF_STATE_PRINT_INT(last_rssi_event); | 507 | VIF_STATE_PRINT_INT(last_rssi_event); |
508 | VIF_STATE_PRINT_INT(ba_support); | 508 | VIF_STATE_PRINT_INT(ba_support); |
509 | VIF_STATE_PRINT_INT(ba_allowed); | 509 | VIF_STATE_PRINT_INT(ba_allowed); |
510 | VIF_STATE_PRINT_INT(is_gem); | ||
511 | VIF_STATE_PRINT_LLHEX(tx_security_seq); | 510 | VIF_STATE_PRINT_LLHEX(tx_security_seq); |
512 | VIF_STATE_PRINT_INT(tx_security_last_seq_lsb); | 511 | VIF_STATE_PRINT_INT(tx_security_last_seq_lsb); |
513 | } | 512 | } |
diff --git a/drivers/net/wireless/ti/wlcore/hw_ops.h b/drivers/net/wireless/ti/wlcore/hw_ops.h index c590b6f529d1..2cb35218ba47 100644 --- a/drivers/net/wireless/ti/wlcore/hw_ops.h +++ b/drivers/net/wireless/ti/wlcore/hw_ops.h | |||
@@ -167,4 +167,13 @@ wlcore_handle_static_data(struct wl1271 *wl, void *static_data) | |||
167 | return 0; | 167 | return 0; |
168 | } | 168 | } |
169 | 169 | ||
170 | static inline int | ||
171 | wlcore_hw_get_spare_blocks(struct wl1271 *wl, bool is_gem) | ||
172 | { | ||
173 | if (!wl->ops->get_spare_blocks) | ||
174 | BUG_ON(1); | ||
175 | |||
176 | return wl->ops->get_spare_blocks(wl, is_gem); | ||
177 | } | ||
178 | |||
170 | #endif | 179 | #endif |
diff --git a/drivers/net/wireless/ti/wlcore/main.c b/drivers/net/wireless/ti/wlcore/main.c index 5ac062831666..0f25d4eea037 100644 --- a/drivers/net/wireless/ti/wlcore/main.c +++ b/drivers/net/wireless/ti/wlcore/main.c | |||
@@ -2799,17 +2799,6 @@ static int wl1271_set_key(struct wl1271 *wl, struct wl12xx_vif *wlvif, | |||
2799 | int ret; | 2799 | int ret; |
2800 | bool is_ap = (wlvif->bss_type == BSS_TYPE_AP_BSS); | 2800 | bool is_ap = (wlvif->bss_type == BSS_TYPE_AP_BSS); |
2801 | 2801 | ||
2802 | /* | ||
2803 | * A role set to GEM cipher requires different Tx settings (namely | ||
2804 | * spare blocks). Note when we are in this mode so the HW can adjust. | ||
2805 | */ | ||
2806 | if (key_type == KEY_GEM) { | ||
2807 | if (action == KEY_ADD_OR_REPLACE) | ||
2808 | wlvif->is_gem = true; | ||
2809 | else if (action == KEY_REMOVE) | ||
2810 | wlvif->is_gem = false; | ||
2811 | } | ||
2812 | |||
2813 | if (is_ap) { | 2802 | if (is_ap) { |
2814 | struct wl1271_station *wl_sta; | 2803 | struct wl1271_station *wl_sta; |
2815 | u8 hlid; | 2804 | u8 hlid; |
diff --git a/drivers/net/wireless/ti/wlcore/tx.c b/drivers/net/wireless/ti/wlcore/tx.c index 6b68e29a1e92..0949ab1f5972 100644 --- a/drivers/net/wireless/ti/wlcore/tx.c +++ b/drivers/net/wireless/ti/wlcore/tx.c | |||
@@ -187,28 +187,24 @@ EXPORT_SYMBOL(wlcore_calc_packet_alignment); | |||
187 | 187 | ||
188 | static int wl1271_tx_allocate(struct wl1271 *wl, struct wl12xx_vif *wlvif, | 188 | static int wl1271_tx_allocate(struct wl1271 *wl, struct wl12xx_vif *wlvif, |
189 | struct sk_buff *skb, u32 extra, u32 buf_offset, | 189 | struct sk_buff *skb, u32 extra, u32 buf_offset, |
190 | u8 hlid) | 190 | u8 hlid, bool is_gem) |
191 | { | 191 | { |
192 | struct wl1271_tx_hw_descr *desc; | 192 | struct wl1271_tx_hw_descr *desc; |
193 | u32 total_len = skb->len + sizeof(struct wl1271_tx_hw_descr) + extra; | 193 | u32 total_len = skb->len + sizeof(struct wl1271_tx_hw_descr) + extra; |
194 | u32 total_blocks; | 194 | u32 total_blocks; |
195 | int id, ret = -EBUSY, ac; | 195 | int id, ret = -EBUSY, ac; |
196 | u32 spare_blocks = wl->normal_tx_spare; | 196 | u32 spare_blocks; |
197 | bool is_dummy = false; | ||
198 | 197 | ||
199 | if (buf_offset + total_len > WL1271_AGGR_BUFFER_SIZE) | 198 | if (buf_offset + total_len > WL1271_AGGR_BUFFER_SIZE) |
200 | return -EAGAIN; | 199 | return -EAGAIN; |
201 | 200 | ||
201 | spare_blocks = wlcore_hw_get_spare_blocks(wl, is_gem); | ||
202 | |||
202 | /* allocate free identifier for the packet */ | 203 | /* allocate free identifier for the packet */ |
203 | id = wl1271_alloc_tx_id(wl, skb); | 204 | id = wl1271_alloc_tx_id(wl, skb); |
204 | if (id < 0) | 205 | if (id < 0) |
205 | return id; | 206 | return id; |
206 | 207 | ||
207 | if (unlikely(wl12xx_is_dummy_packet(wl, skb))) | ||
208 | is_dummy = true; | ||
209 | else if (wlvif->is_gem) | ||
210 | spare_blocks = wl->gem_tx_spare; | ||
211 | |||
212 | total_blocks = wlcore_hw_calc_tx_blocks(wl, total_len, spare_blocks); | 208 | total_blocks = wlcore_hw_calc_tx_blocks(wl, total_len, spare_blocks); |
213 | 209 | ||
214 | if (total_blocks <= wl->tx_blocks_available) { | 210 | if (total_blocks <= wl->tx_blocks_available) { |
@@ -230,7 +226,7 @@ static int wl1271_tx_allocate(struct wl1271 *wl, struct wl12xx_vif *wlvif, | |||
230 | ac = wl1271_tx_get_queue(skb_get_queue_mapping(skb)); | 226 | ac = wl1271_tx_get_queue(skb_get_queue_mapping(skb)); |
231 | wl->tx_allocated_pkts[ac]++; | 227 | wl->tx_allocated_pkts[ac]++; |
232 | 228 | ||
233 | if (!is_dummy && wlvif && | 229 | if (!wl12xx_is_dummy_packet(wl, skb) && wlvif && |
234 | wlvif->bss_type == BSS_TYPE_AP_BSS && | 230 | wlvif->bss_type == BSS_TYPE_AP_BSS && |
235 | test_bit(hlid, wlvif->ap.sta_hlid_map)) | 231 | test_bit(hlid, wlvif->ap.sta_hlid_map)) |
236 | wl->links[hlid].allocated_pkts++; | 232 | wl->links[hlid].allocated_pkts++; |
@@ -349,6 +345,7 @@ static int wl1271_prepare_tx_frame(struct wl1271 *wl, struct wl12xx_vif *wlvif, | |||
349 | u32 total_len; | 345 | u32 total_len; |
350 | u8 hlid; | 346 | u8 hlid; |
351 | bool is_dummy; | 347 | bool is_dummy; |
348 | bool is_gem = false; | ||
352 | 349 | ||
353 | if (!skb) | 350 | if (!skb) |
354 | return -EINVAL; | 351 | return -EINVAL; |
@@ -377,6 +374,8 @@ static int wl1271_prepare_tx_frame(struct wl1271 *wl, struct wl12xx_vif *wlvif, | |||
377 | return ret; | 374 | return ret; |
378 | wlvif->default_key = idx; | 375 | wlvif->default_key = idx; |
379 | } | 376 | } |
377 | |||
378 | is_gem = (cipher == WL1271_CIPHER_SUITE_GEM); | ||
380 | } | 379 | } |
381 | hlid = wl12xx_tx_get_hlid(wl, wlvif, skb); | 380 | hlid = wl12xx_tx_get_hlid(wl, wlvif, skb); |
382 | if (hlid == WL12XX_INVALID_LINK_ID) { | 381 | if (hlid == WL12XX_INVALID_LINK_ID) { |
@@ -384,7 +383,8 @@ static int wl1271_prepare_tx_frame(struct wl1271 *wl, struct wl12xx_vif *wlvif, | |||
384 | return -EINVAL; | 383 | return -EINVAL; |
385 | } | 384 | } |
386 | 385 | ||
387 | ret = wl1271_tx_allocate(wl, wlvif, skb, extra, buf_offset, hlid); | 386 | ret = wl1271_tx_allocate(wl, wlvif, skb, extra, buf_offset, hlid, |
387 | is_gem); | ||
388 | if (ret < 0) | 388 | if (ret < 0) |
389 | return ret; | 389 | return ret; |
390 | 390 | ||
diff --git a/drivers/net/wireless/ti/wlcore/wlcore.h b/drivers/net/wireless/ti/wlcore/wlcore.h index 16c28bbd1b20..5274ace6c8e4 100644 --- a/drivers/net/wireless/ti/wlcore/wlcore.h +++ b/drivers/net/wireless/ti/wlcore/wlcore.h | |||
@@ -75,6 +75,7 @@ struct wlcore_ops { | |||
75 | int (*debugfs_init)(struct wl1271 *wl, struct dentry *rootdir); | 75 | int (*debugfs_init)(struct wl1271 *wl, struct dentry *rootdir); |
76 | int (*handle_static_data)(struct wl1271 *wl, | 76 | int (*handle_static_data)(struct wl1271 *wl, |
77 | struct wl1271_static_data *static_data); | 77 | struct wl1271_static_data *static_data); |
78 | int (*get_spare_blocks)(struct wl1271 *wl, bool is_gem); | ||
78 | }; | 79 | }; |
79 | 80 | ||
80 | enum wlcore_partitions { | 81 | enum wlcore_partitions { |
@@ -354,10 +355,6 @@ struct wl1271 { | |||
354 | /* number of RX descriptors the HW supports. */ | 355 | /* number of RX descriptors the HW supports. */ |
355 | u32 num_rx_desc; | 356 | u32 num_rx_desc; |
356 | 357 | ||
357 | /* spare Tx blocks for normal/GEM operating modes */ | ||
358 | u32 normal_tx_spare; | ||
359 | u32 gem_tx_spare; | ||
360 | |||
361 | /* translate HW Tx rates to standard rate-indices */ | 358 | /* translate HW Tx rates to standard rate-indices */ |
362 | const u8 **band_rate_to_idx; | 359 | const u8 **band_rate_to_idx; |
363 | 360 | ||
diff --git a/drivers/net/wireless/ti/wlcore/wlcore_i.h b/drivers/net/wireless/ti/wlcore/wlcore_i.h index 83c9869105c3..8260b1e9288a 100644 --- a/drivers/net/wireless/ti/wlcore/wlcore_i.h +++ b/drivers/net/wireless/ti/wlcore/wlcore_i.h | |||
@@ -417,9 +417,6 @@ struct wl12xx_vif { | |||
417 | struct work_struct rx_streaming_disable_work; | 417 | struct work_struct rx_streaming_disable_work; |
418 | struct timer_list rx_streaming_timer; | 418 | struct timer_list rx_streaming_timer; |
419 | 419 | ||
420 | /* does the current role use GEM for encryption (AP or STA) */ | ||
421 | bool is_gem; | ||
422 | |||
423 | /* | 420 | /* |
424 | * This struct must be last! | 421 | * This struct must be last! |
425 | * data that has to be saved acrossed reconfigs (e.g. recovery) | 422 | * data that has to be saved acrossed reconfigs (e.g. recovery) |