aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/wireless
diff options
context:
space:
mode:
authorArik Nemtsov <arik@wizery.com>2012-05-18 00:46:37 -0400
committerLuciano Coelho <coelho@ti.com>2012-06-06 12:28:05 -0400
commit32bb2c03f990d015c0fec67e9134ea8625aaf784 (patch)
tree625379f953c7b11754f6d5ee09023fc1ad04d939 /drivers/net/wireless
parent2c0133a437905591cdaa39cf65a3f7188d20a094 (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/net/wireless')
-rw-r--r--drivers/net/wireless/ti/wl12xx/main.c11
-rw-r--r--drivers/net/wireless/ti/wl18xx/main.c11
-rw-r--r--drivers/net/wireless/ti/wl18xx/tx.h3
-rw-r--r--drivers/net/wireless/ti/wlcore/debugfs.c1
-rw-r--r--drivers/net/wireless/ti/wlcore/hw_ops.h9
-rw-r--r--drivers/net/wireless/ti/wlcore/main.c11
-rw-r--r--drivers/net/wireless/ti/wlcore/tx.c20
-rw-r--r--drivers/net/wireless/ti/wlcore/wlcore.h5
-rw-r--r--drivers/net/wireless/ti/wlcore/wlcore_i.h3
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
1364static 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
1364static struct wlcore_ops wl12xx_ops = { 1372static 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
1389static struct ieee80211_sta_ht_cap wl12xx_ht_cap = { 1398static 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
1037static 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
1037static struct wlcore_ops wl18xx_ops = { 1043static 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
170static inline int
171wlcore_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
188static int wl1271_tx_allocate(struct wl1271 *wl, struct wl12xx_vif *wlvif, 188static 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
80enum wlcore_partitions { 81enum 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)